Minimal deterministic automaton
TheoremLeft quotients of continuation languages#✓fully proved
Let \(M\) be a DFA, write \(\delta^*(q, x)\) for the state \(M\) reaches from the state \(q\) by reading the word \(x\), and let \(L_M(q)\) be the language of words accepted by \(M\) when started in \(q\). For every state \(q\) and every word \(x\), the left quotient \(\{z : xz \in L_M(q)\}\) of \(L_M(q)\) by \(x\) equals \(L_M(\delta^*(q, x))\).
DefinitionResidual reached by a word#✓fully proved
For a DFA \(M\) and a word \(x\), the minimized state of \(x\) is the language accepted by \(M\) starting from the state that \(M\) reaches on reading \(x\) from its start state, viewed as an element of the reachable residuals of \(M\).
def minimizedState (M : DFA Symbol State) (x : List Symbol) : reachableResiduals M :=
⟨M.acceptsFrom (M.eval x), ⟨x, rfl⟩⟩
def reachableResiduals (M : DFA Symbol State) : Set (Language Symbol) :=
Set.range (M.acceptsFrom ∘ M.eval)
CSLibExt/Computability/Languages/Congruences/Minimality.lean:96
Uses 1 · Used by 6
DefinitionLeft quotients as reachable residuals#✓fully proved
Let \(M\) be a DFA accepting the language \(L\). The set of left quotients \(\{z : xz \in L\}\) of \(L\) by words \(x\) equals the set of reachable residuals of \(M\) (the languages accepted by \(M\) from the states it reaches from its start state). The bijection from the first set to the second sends each language to itself.
noncomputable def leftQuotientEquivReachableResiduals (M : DFA Symbol State) :
Set.range M.accepts.leftQuotient ≃ reachableResiduals M where
toFun q := ⟨q.val, by
rw [reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
invFun q := ⟨q.val, by
rw [← reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
left_inv _ := Subtype.ext rfl
right_inv _ := Subtype.ext rfl
def reachableResiduals (M : DFA Symbol State) : Set (Language Symbol) :=
Set.range (M.acceptsFrom ∘ M.eval)
CSLibExt/Computability/Languages/Congruences/Minimality.lean:96
Uses 1 · Used by 8
DefinitionMinimized DFA#✓fully proved
Let \(M\) be a DFA accepting the language \(L\). The minimized DFA of \(M\) has as states the reachable residuals of \(M\), that is, the languages accepted by \(M\) from the states it reaches from its start state. Its start state is \(L\); on a letter \(a\) it moves from a state \(K\) to the left quotient \(\{z : az \in K\}\); and its accepting states are those that contain the empty word.
It is the canonical automaton of \(L\), whose states are the left quotients of \(L\), with each state renamed to the same language viewed as a reachable residual of \(M\).
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
def reachableResiduals (M : DFA Symbol State) : Set (Language Symbol) :=
Set.range (M.acceptsFrom ∘ M.eval)
CSLibExt/Computability/Languages/Congruences/Minimality.lean:96
noncomputable def leftQuotientEquivReachableResiduals (M : DFA Symbol State) :
Set.range M.accepts.leftQuotient ≃ reachableResiduals M where
toFun q := ⟨q.val, by
rw [reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
invFun q := ⟨q.val, by
rw [← reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
left_inv _ := Subtype.ext rfl
right_inv _ := Subtype.ext rfl
CSLibExt/Computability/Languages/Congruences/Minimization.lean:73
Uses 2 · Used by 10
TheoremStates reached in the residual-language DFA#✓fully proved
For every language \(L\) and every word \(x\), the state that the residual-language DFA of \(L\) reaches on reading \(x\) is the left quotient \(x^{-1}L = \{z : xz \in L\}\). This automaton has the left quotients of \(L\) as states, start state \(L\), transition from \(K\) on a letter \(a\) to \(a^{-1}K\), and accepts \(K\) when \(K\) contains the empty word.
@[simp]
theorem toDFA_eval_val (L : Language Symbol) (x : List Symbol) :
(L.toDFA.eval x).val = L.leftQuotient x
Used by 2
TheoremEvaluation in the minimized DFA agrees with the left-quotient automaton#✓fully proved
Let \(M\) be a DFA accepting the language \(L\), and consider the automaton whose states are the left quotients of \(L\), with start state \(L\), moving from \(K\) on a letter \(a\) to \(\{z : az \in K\}\). For every word \(x\), the state that the minimized DFA of \(M\) reaches on \(x\), carried to the left quotients of \(L\) by the bijection that sends each language to itself, is the state that this automaton reaches on \(x\).
@[simp]
theorem minimizedDFA_eval_equiv (M : DFA Symbol State) (x : List Symbol) :
(leftQuotientEquivReachableResiduals M).symm ((minimizedDFA M).eval x) =
M.accepts.toDFA.eval x
noncomputable def leftQuotientEquivReachableResiduals (M : DFA Symbol State) :
Set.range M.accepts.leftQuotient ≃ reachableResiduals M where
toFun q := ⟨q.val, by
rw [reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
invFun q := ⟨q.val, by
rw [← reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
left_inv _ := Subtype.ext rfl
right_inv _ := Subtype.ext rfl
CSLibExt/Computability/Languages/Congruences/Minimization.lean:73
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
Uses 3 · Used by 1
TheoremStates reached in the minimized DFA#✓fully proved
For every DFA \(M\) and every word \(x\), the state that the minimized DFA of \(M\) reaches on \(x\) is the language accepted by \(M\) from the state that \(M\) reaches on \(x\).
@[simp]
theorem minimizedDFA_eval (M : DFA Symbol State) (x : List Symbol) :
(minimizedDFA M).eval x = minimizedState M x
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
def minimizedState (M : DFA Symbol State) (x : List Symbol) : reachableResiduals M :=
⟨M.acceptsFrom (M.eval x), ⟨x, rfl⟩⟩
CSLibExt/Computability/Languages/Congruences/Minimization.lean:49
TheoremTransitions of the minimized DFA#✓fully proved
Let \(M\) be a DFA. For every reachable residual \(K\) of \(M\) (a state of the minimized DFA of \(M\)) and every letter \(a\), the minimized DFA of \(M\) moves from \(K\) on input \(a\) to the left quotient \(\{z : az \in K\}\) of \(K\) by \(a\).
@[simp]
theorem minimizedDFA_step_val (M : DFA Symbol State) (q : reachableResiduals M) (a : Symbol) :
((minimizedDFA M).step q a).val = q.val.leftQuotient [a]
def reachableResiduals (M : DFA Symbol State) : Set (Language Symbol) :=
Set.range (M.acceptsFrom ∘ M.eval)
CSLibExt/Computability/Languages/Congruences/Minimality.lean:96
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
Uses 3 · Used by 2
TheoremTransitions of the minimized DFA on reached states#✓fully proved
Let \(M\) be a DFA, and for a word \(x\) let \([x]\) be the language accepted by \(M\) from the state that \(M\) reaches on \(x\). For every word \(x\) and every letter \(a\), the minimized DFA of \(M\) moves from the state \([x]\) on input \(a\) to the state \([xa]\).
@[simp]
theorem minimizedDFA_step_minimizedState (M : DFA Symbol State) (x : List Symbol) (a : Symbol) :
(minimizedDFA M).step (minimizedState M x) a = minimizedState M (x ++ [a])
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
def minimizedState (M : DFA Symbol State) (x : List Symbol) : reachableResiduals M :=
⟨M.acceptsFrom (M.eval x), ⟨x, rfl⟩⟩
CSLibExt/Computability/Languages/Congruences/Minimization.lean:49
Uses 5 · Used by 1
TheoremThe minimized DFA accepts the same language#✓fully proved
For every DFA \(M\), the minimized DFA of \(M\) accepts exactly the language accepted by \(M\).
@[simp]
theorem minimizedDFA_accepts (M : DFA Symbol State) :
(minimizedDFA M).accepts = M.accepts
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
Uses 3 · Used by 2
TheoremThe residual-language DFA is accessible#✓fully proved
For every language \(L\), the residual-language DFA of \(L\) is accessible. This automaton has as states the left quotients \(x^{-1}L = \{z : xz \in L\}\) for words \(x\), start state \(L\), transition from \(K\) on a letter \(a\) to \(a^{-1}K\), and accepts \(K\) when \(K\) contains the empty word.
theorem toDFA_accessible (L : Language Symbol) : Accessible L.toDFA
def Accessible (M : DFA Symbol State) : Prop :=
∀ q, ReachableState M q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:191
Uses 3 · Used by 1
TheoremThe minimized DFA is accessible#✓fully proved
For every DFA \(M\), every state of the minimized DFA of \(M\) is reached from its start state by reading some word.
theorem minimizedDFA_accessible (M : DFA Symbol State) : Accessible (minimizedDFA M)
def Accessible (M : DFA Symbol State) : Prop :=
∀ q, ReachableState M q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:191
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
Uses 6
DefinitionNerode classes and reachable residuals#✓fully proved
For a DFA \(M\) accepting the language \(L\), there is a bijection from the Nerode classes of \(L\) to the reachable residuals of \(M\); it sends the class of a word \(x\) to the left quotient \(x^{-1}L = \{z : xz \in L\}\).
noncomputable def nerodeClassEquivMinimizedState (M : DFA Symbol State) :
NerodeClass M.accepts ≃ reachableResiduals M :=
nerodeClassEquivReachableResiduals M rfl
abbrev NerodeClass (L : Language Symbol) := Quotient (nerodeSetoid L)
CSLibExt/Computability/Languages/Congruences/Nerode.lean:78
def reachableResiduals (M : DFA Symbol State) : Set (Language Symbol) :=
Set.range (M.acceptsFrom ∘ M.eval)
CSLibExt/Computability/Languages/Congruences/Minimality.lean:96
noncomputable def nerodeClassEquivReachableResiduals (M : DFA Symbol State)
(hM : M.accepts = L) : NerodeClass L ≃ reachableResiduals M :=
(nerodeClassEquivResidual L).trans
(Equiv.cast
(congrArg (fun s : Set (Language Symbol) ↦ ↥s) (reachableResiduals_eq M hM).symm))
CSLibExt/Computability/Languages/Congruences/Minimality.lean:109
Uses 3 · Used by 3
DefinitionReachable residuals of the minimized DFA#✓fully proved
Let \(M\) be a DFA accepting the language \(L\). The reachable residuals of the minimized DFA of \(M\) and the reachable residuals of \(M\) both form the set of left quotients \(x^{-1}L = \{z : xz \in L\}\) of \(L\) by words \(x\), and this is the bijection from the first set to the second that sends each language to itself.
It is built as the composite of the bijections from the Nerode classes of \(L\) to both sets, each sending the class of a word \(x\) to \(x^{-1}L\); so minimizing the minimized DFA again gives the same state space.
noncomputable def minimizedStateEquivIterated (M : DFA Symbol State) :
reachableResiduals (minimizedDFA M) ≃ reachableResiduals M :=
(nerodeClassEquivReachableResiduals (minimizedDFA M) (minimizedDFA_accepts M)).symm.trans
(nerodeClassEquivMinimizedState M)
def reachableResiduals (M : DFA Symbol State) : Set (Language Symbol) :=
Set.range (M.acceptsFrom ∘ M.eval)
CSLibExt/Computability/Languages/Congruences/Minimality.lean:96
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
noncomputable def nerodeClassEquivReachableResiduals (M : DFA Symbol State)
(hM : M.accepts = L) : NerodeClass L ≃ reachableResiduals M :=
(nerodeClassEquivResidual L).trans
(Equiv.cast
(congrArg (fun s : Set (Language Symbol) ↦ ↥s) (reachableResiduals_eq M hM).symm))
CSLibExt/Computability/Languages/Congruences/Minimality.lean:109
@[simp]
theorem minimizedDFA_accepts (M : DFA Symbol State) :
(minimizedDFA M).accepts = M.accepts
CSLibExt/Computability/Languages/Congruences/Minimization.lean:148
noncomputable def nerodeClassEquivMinimizedState (M : DFA Symbol State) :
NerodeClass M.accepts ≃ reachableResiduals M :=
nerodeClassEquivReachableResiduals M rfl
CSLibExt/Computability/Languages/Congruences/Minimization.lean:170
TheoremWhen finite, the minimized DFA has as many states as there are Nerode classes#✓fully proved
Let \(M\) be a DFA accepting the language \(L\). If the set of reachable residuals of \(M\) (the states of the minimized DFA of \(M\)) and the set of Nerode classes of \(L\) are both finite, then they have the same number of elements.
theorem minimizedDFA_card_eq_nerode (M : DFA Symbol State) [Fintype (reachableResiduals M)]
[Fintype (NerodeClass M.accepts)] :
Fintype.card (reachableResiduals M) = Fintype.card (NerodeClass M.accepts)
def reachableResiduals (M : DFA Symbol State) : Set (Language Symbol) :=
Set.range (M.acceptsFrom ∘ M.eval)
CSLibExt/Computability/Languages/Congruences/Minimality.lean:96
abbrev NerodeClass (L : Language Symbol) := Quotient (nerodeSetoid L)
CSLibExt/Computability/Languages/Congruences/Nerode.lean:78
Uses 3
DefinitionCSLib automata as Mathlib DFAs#✓fully proved
A CSLib deterministic automaton \(M\) on finite words is viewed as a Mathlib DFA with the same states, the same transition function, the same start state and the same set of accepting states as \(M\).
def toDFA (M : DA.FinAcc State Symbol) : DFA Symbol State where
step := M.tr
start := M.start
accept := M.accept
DefinitionMathlib DFAs as CSLib automata#✓fully proved
A Mathlib DFA \(M\) is viewed as a CSLib deterministic automaton on finite words with the same states, the same transition function, the same start state and the same set of accepting states as \(M\).
def ofDFA (M : DFA Symbol State) : DA.FinAcc State Symbol where
tr := M.step
start := M.start
accept := M.accept
TheoremConverting a CSLib automaton to a Mathlib DFA preserves its language#✓fully proved
For every deterministic automaton \(M\) on finite words, the DFA with the same states, transition function, start state and accepting states as \(M\) accepts exactly the language of \(M\).
@[simp]
theorem language_toDFA (M : DA.FinAcc State Symbol) :
M.toDFA.accepts = Acceptor.language M
Uses 1
TheoremThe Nerode congruence relates words with equal left quotients#✓fully proved
Let \(L\) be a language over an alphabet \(\Sigma\) and let \(x, y \in \Sigma^*\). Then \(x\) and \(y\) are related by the Nerode congruence of \(L\), that is, \(xz \in L \iff yz \in L\) for every word \(z\), if and only if they are Nerode equivalent for \(L\), that is, their left quotients \(x^{-1}L = \{z : xz \in L\}\) and \(y^{-1}L\) are equal.
theorem nerodeCongruence_r_iff {x y : List Symbol} :
l.NerodeCongruence.r x y ↔ nerodeRel l x y
def nerodeRel (L : Language Symbol) (x y : List Symbol) : Prop :=
L.leftQuotient x = L.leftQuotient y
CSLibExt/Computability/Languages/Congruences/Nerode.lean:56
Uses 1 · Used by 2
DefinitionThe residual language of a Nerode class#✓fully proved
Let \(L\) be a language over an alphabet \(\Sigma\), and write \(x^{-1}L = \{z : xz \in L\}\) for the left quotient of \(L\) by a word \(x\). This is the map from the classes of the Nerode congruence of \(L\) to the set \(\{w^{-1}L : w \in \Sigma^*\}\) of residual languages of \(L\) that sends the class of each word \(x\) to \(x^{-1}L\); it is well defined because Nerode-congruent words have the same left quotient.
def nerodeResidual (l : Language Symbol) : l.NerodeQuotient → Set.range l.leftQuotient :=
Quotient.lift (fun x => ⟨l.leftQuotient x, x, rfl⟩)
(fun _ _ h => Subtype.ext (nerodeCongruence_r_iff.1 h))
theorem nerodeCongruence_r_iff {x y : List Symbol} :
l.NerodeCongruence.r x y ↔ nerodeRel l x y
CSLibExt/Computability/Automata/DA/MathlibDFA.lean:93
Uses 2 · Used by 1
DefinitionNerode classes are the residual languages#✓fully proved
Let \(L\) be a language over an alphabet \(\Sigma\), and write \(x^{-1}L = \{z : xz \in L\}\) for the left quotient of \(L\) by a word \(x\). This is the bijection from the classes of the Nerode congruence of \(L\) onto the set \(\{x^{-1}L : x \in \Sigma^*\}\) of residual languages of \(L\) that sends the class of each word \(x\) to \(x^{-1}L\).
The residual languages are the states of Mathlib's residual-language DFA of \(L\).
noncomputable def nerodeQuotientEquivResidual (l : Language Symbol) :
l.NerodeQuotient ≃ Set.range l.leftQuotient :=
Equiv.ofBijective _ nerodeResidual_bijective
theorem nerodeResidual_bijective : Function.Bijective (nerodeResidual l)
CSLibExt/Computability/Automata/DA/MathlibDFA.lean:113
TheoremThe Nerode automaton is the residual-language automaton#✓fully proved
Let \(L\) be a language over an alphabet \(\Sigma\), and write \(x^{-1}L = \{z : xz \in L\}\) for the left quotient of \(L\) by a word \(x\). Consider the canonical automaton of \(L\) as a DFA: its states are the classes \([x]\) of the Nerode congruence of \(L\), its start state is the class of the empty word, on a letter \(a\) it goes from \([x]\) to \([xa]\), and its accepting states are the classes of words of \(L\). Renaming each class \([x]\) to \(x^{-1}L\) gives exactly Mathlib's residual-language DFA of \(L\): its states are the residual languages \(x^{-1}L\) for \(x \in \Sigma^*\), its start state is \(L\), on a letter \(a\) it goes from \(K\) to \(a^{-1}K\), and its accepting states are the residual languages that contain the empty word.
theorem reindex_nerodeCongruenceDA (l : Language Symbol) :
DFA.reindex (nerodeQuotientEquivResidual l) (toDFA l.NerodeCongruenceDA) = l.toDFA
noncomputable def nerodeQuotientEquivResidual (l : Language Symbol) :
l.NerodeQuotient ≃ Set.range l.leftQuotient :=
Equiv.ofBijective _ nerodeResidual_bijective
CSLibExt/Computability/Automata/DA/MathlibDFA.lean:124
def toDFA (M : DA.FinAcc State Symbol) : DFA Symbol State where
step := M.tr
start := M.start
accept := M.accept
CSLibExt/Computability/Automata/DA/MathlibDFA.lean:50
Uses 2 · Used by 1
TheoremThe canonical automaton of a DFA's language is its minimized DFA#✓fully proved
Let \(M\) be a DFA over an alphabet \(\Sigma\) accepting the language \(L\), and write \(x^{-1}L = \{z : xz \in L\}\) for the left quotient of \(L\) by a word \(x\). Consider the canonical automaton of \(L\) as a DFA: its states are the classes \([x]\) of the Nerode congruence of \(L\), its start state is the class of the empty word, on a letter \(a\) it goes from \([x]\) to \([xa]\), and its accepting states are the classes of words of \(L\). Renaming each class \([x]\) to \(x^{-1}L\), regarded as one of the languages accepted from the states of \(M\) reachable from its start state, gives exactly the minimized DFA of \(M\).
theorem reindex_nerodeCongruenceDA_eq_minimizedDFA {State : Type*} (M : DFA Symbol State) :
DFA.reindex ((nerodeQuotientEquivResidual M.accepts).trans
(leftQuotientEquivReachableResiduals M)) (toDFA M.accepts.NerodeCongruenceDA) =
minimizedDFA M
noncomputable def nerodeQuotientEquivResidual (l : Language Symbol) :
l.NerodeQuotient ≃ Set.range l.leftQuotient :=
Equiv.ofBijective _ nerodeResidual_bijective
CSLibExt/Computability/Automata/DA/MathlibDFA.lean:124
noncomputable def leftQuotientEquivReachableResiduals (M : DFA Symbol State) :
Set.range M.accepts.leftQuotient ≃ reachableResiduals M where
toFun q := ⟨q.val, by
rw [reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
invFun q := ⟨q.val, by
rw [← reachableResiduals_eq_range_leftQuotient]
exact q.property⟩
left_inv _ := Subtype.ext rfl
right_inv _ := Subtype.ext rfl
CSLibExt/Computability/Languages/Congruences/Minimization.lean:73
def toDFA (M : DA.FinAcc State Symbol) : DFA Symbol State where
step := M.tr
start := M.start
accept := M.accept
CSLibExt/Computability/Automata/DA/MathlibDFA.lean:50
noncomputable def minimizedDFA (M : DFA Symbol State) : DFA Symbol (reachableResiduals M) :=
DFA.reindex (leftQuotientEquivReachableResiduals M) M.accepts.toDFA
CSLibExt/Computability/Languages/Congruences/Minimization.lean:98
StructureMorphisms of DFAs#✓fully proved
Let \(M\) and \(N\) be DFAs over the same alphabet with transition functions \(\delta_M\) and \(\delta_N\). A morphism from \(M\) to \(N\) is a map \(f\) from the states of \(M\) to the states of \(N\) that sends the start state of \(M\) to the start state of \(N\), satisfies \(f(\delta_M(q, a)) = \delta_N(f(q), a)\) for every state \(q\) of \(M\) and every symbol \(a\), and such that each state \(q\) of \(M\) is accepting if and only if \(f(q)\) is accepting in \(N\).
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
toFun : State → State'
CSLibExt/Computability/Languages/Congruences/Universal.lean:41
Used by 10
TheoremDFA morphisms commute with evaluation from a state#✓fully proved
If \(f\) is a morphism from a DFA \(M\) to a DFA \(N\), then for every state \(q\) of \(M\) and every word \(x\), running \(N\) on \(x\) from \(f(q)\) ends in the image under \(f\) of the state reached by running \(M\) on \(x\) from \(q\).
theorem DFAHom.map_evalFrom {M : DFA Symbol State} {N : DFA Symbol State'}
(f : DFAHom M N) (q : State) (x : List Symbol) :
f (M.evalFrom q x) = N.evalFrom (f q) x
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
CSLibExt/Computability/Languages/Congruences/Universal.lean:40
Uses 1 · Used by 1
TheoremDFA morphisms commute with evaluation#✓fully proved
If \(f\) is a morphism from a DFA \(M\) to a DFA \(N\), then for every word \(x\), the state that \(N\) reaches on input \(x\) from its start state is the image under \(f\) of the state that \(M\) reaches on input \(x\) from its start state.
theorem DFAHom.map_eval {M : DFA Symbol State} {N : DFA Symbol State'}
(f : DFAHom M N) (x : List Symbol) : f (M.eval x) = N.eval x
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
CSLibExt/Computability/Languages/Congruences/Universal.lean:40
Uses 2 · Used by 2
TheoremDFA morphisms preserve the accepted language#✓fully proved
If \(f\) is a morphism from a DFA \(M\) to a DFA \(N\) over the same alphabet, then \(M\) and \(N\) accept the same language.
theorem DFAHom.accepts_eq {M : DFA Symbol State} {N : DFA Symbol State'}
(f : DFAHom M N) : M.accepts = N.accepts
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
CSLibExt/Computability/Languages/Congruences/Universal.lean:40
Uses 2
DefinitionIdentity DFA morphism#✓fully proved
For every DFA \(M\), the identity map on the states of \(M\) is a DFA morphism from \(M\) to itself.
def DFAHom.refl (M : DFA Symbol State) : DFAHom M M where
toFun := id
map_start := rfl
map_step := fun _ _ ↦ rfl
mem_accept_iff := fun _ ↦ Iff.rfl
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
CSLibExt/Computability/Languages/Congruences/Universal.lean:40
Uses 1
DefinitionComposition of DFA morphisms#✓fully proved
If \(f\) is a DFA morphism from \(M\) to \(N\) and \(g\) is a DFA morphism from \(N\) to \(P\), where \(M\), \(N\), \(P\) are DFAs over the same alphabet, then the composite of \(g\) and \(f\) is the DFA morphism from \(M\) to \(P\) whose state map is \(g \circ f\).
def DFAHom.comp {State'' : Type*} {M : DFA Symbol State} {N : DFA Symbol State'}
{P : DFA Symbol State''} (g : DFAHom N P) (f : DFAHom M N) : DFAHom M P where
toFun := g ∘ f
map_start := by rw [Function.comp_apply, f.map_start, g.map_start]
map_step := by intro q a; rw [Function.comp_apply, f.map_step, g.map_step, Function.comp_apply]
mem_accept_iff := fun q ↦ (f.mem_accept_iff q).trans (g.mem_accept_iff (f q))
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
CSLibExt/Computability/Languages/Congruences/Universal.lean:40
Uses 1
DefinitionState-separated DFA#✓fully proved
A DFA \(M\) is state-separated when any two equivalent states of \(M\) are equal: if \(p \ne q\), then the languages of words accepted by \(M\) starting from \(p\) and from \(q\) are different.
def StateSeparated (M : DFA Symbol State) : Prop :=
∀ ⦃p q⦄, StateEquivalent M p q → p = q
def StateEquivalent (M : DFA Symbol State) (p q : State) : Prop :=
M.acceptsFrom p = M.acceptsFrom q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:76
Uses 1 · Used by 7
DefinitionThe canonical residual map#✓fully proved
Let \(M\) be an accessible DFA accepting the language \(L\). The residual-language DFA of \(L\) has as states the left quotients \(x^{-1}L = \{y \mid xy \in L\}\) for words \(x\), start state \(L\), transitions \(K \mapsto a^{-1}K\) on a symbol \(a\), and a state \(K\) is accepting when it contains the empty word. The canonical residual map is the DFA morphism from \(M\) to this DFA that sends each state \(q\) of \(M\) to its continuation language, the set of words \(z\) such that running \(M\) from \(q\) on \(z\) ends in an accepting state.
Cslib.Language.canonicalResidualHom · 18 lines
noncomputable def canonicalResidualHom (M : DFA Symbol State) (hacc : Accessible M) :
DFAHom M M.accepts.toDFA where
toFun q := by
refine ⟨M.acceptsFrom q, ?_⟩
obtain ⟨x, hx⟩ := hacc q
refine ⟨x, ?_⟩
rw [Language.leftQuotient_accepts_apply, hx]
map_start := by
apply Subtype.ext
rfl
map_step q a := by
apply Subtype.ext
change M.acceptsFrom (M.step q a) = (M.acceptsFrom q).leftQuotient [a]
rw [← DFA.evalFrom_singleton]
exact (leftQuotient_acceptsFrom M q [a]).symm
mem_accept_iff q := by
change q ∈ M.accept ↔ [] ∈ M.acceptsFrom q
rfl
def Accessible (M : DFA Symbol State) : Prop :=
∀ q, ReachableState M q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:191
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
CSLibExt/Computability/Languages/Congruences/Universal.lean:40
toFun : State → State'
CSLibExt/Computability/Languages/Congruences/Universal.lean:41
Uses 4 · Used by 4
TheoremThe canonical residual map is surjective#✓fully proved
For an accessible DFA \(M\), every state of the residual-language DFA of the language accepted by \(M\) is the image of some state of \(M\) under the canonical residual map.
theorem canonicalResidualHom_surjective (M : DFA Symbol State) (hacc : Accessible M) :
Function.Surjective (canonicalResidualHom M hacc)
def Accessible (M : DFA Symbol State) : Prop :=
∀ q, ReachableState M q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:191
noncomputable def canonicalResidualHom (M : DFA Symbol State) (hacc : Accessible M) :
DFAHom M M.accepts.toDFA where
toFun q := by
refine ⟨M.acceptsFrom q, ?_⟩
obtain ⟨x, hx⟩ := hacc q
refine ⟨x, ?_⟩
rw [Language.leftQuotient_accepts_apply, hx]
map_start := by
apply Subtype.ext
rfl
map_step q a := by
apply Subtype.ext
⋯
CSLibExt/Computability/Languages/Congruences/Universal.lean:100
Uses 3 · Used by 1
TheoremInjectivity of the canonical residual map#✓fully proved
For an accessible DFA \(M\), the canonical residual map from \(M\) to the residual-language DFA of its accepted language is injective if and only if \(M\) is state-separated, that is, any two states of \(M\) with the same continuation language are equal.
theorem canonicalResidualHom_injective_iff (M : DFA Symbol State) (hacc : Accessible M) :
Function.Injective (canonicalResidualHom M hacc) ↔ StateSeparated M
def Accessible (M : DFA Symbol State) : Prop :=
∀ q, ReachableState M q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:191
noncomputable def canonicalResidualHom (M : DFA Symbol State) (hacc : Accessible M) :
DFAHom M M.accepts.toDFA where
toFun q := by
refine ⟨M.acceptsFrom q, ?_⟩
obtain ⟨x, hx⟩ := hacc q
refine ⟨x, ?_⟩
rw [Language.leftQuotient_accepts_apply, hx]
map_start := by
apply Subtype.ext
rfl
map_step q a := by
apply Subtype.ext
⋯
CSLibExt/Computability/Languages/Congruences/Universal.lean:100
def StateSeparated (M : DFA Symbol State) : Prop :=
∀ ⦃p q⦄, StateEquivalent M p q → p = q
CSLibExt/Computability/Languages/Congruences/Universal.lean:95
Uses 5 · Used by 1
DefinitionStates of an accessible, state-separated DFA correspond to residuals#✓fully proved
Let \(M\) be a DFA that is accessible and state-separated, and let \(L\) be the language it accepts. The map sending each state \(q\) of \(M\) to the language of words accepted by \(M\) starting from \(q\) is a bijection from the states of \(M\) onto the set of left quotients \(\{z : xz \in L\}\) of \(L\) by words \(x\).
noncomputable def stateEquivResidualsOfSeparated (M : DFA Symbol State) (hacc : Accessible M)
(hsep : StateSeparated M) : State ≃ Set.range M.accepts.leftQuotient :=
Equiv.ofBijective (canonicalResidualHom M hacc)
⟨(canonicalResidualHom_injective_iff M hacc).mpr hsep,
canonicalResidualHom_surjective M hacc⟩
def Accessible (M : DFA Symbol State) : Prop :=
∀ q, ReachableState M q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:191
def StateSeparated (M : DFA Symbol State) : Prop :=
∀ ⦃p q⦄, StateEquivalent M p q → p = q
CSLibExt/Computability/Languages/Congruences/Universal.lean:95
noncomputable def canonicalResidualHom (M : DFA Symbol State) (hacc : Accessible M) :
DFAHom M M.accepts.toDFA where
toFun q := by
refine ⟨M.acceptsFrom q, ?_⟩
obtain ⟨x, hx⟩ := hacc q
refine ⟨x, ?_⟩
rw [Language.leftQuotient_accepts_apply, hx]
map_start := by
apply Subtype.ext
rfl
map_step q a := by
apply Subtype.ext
⋯
CSLibExt/Computability/Languages/Congruences/Universal.lean:100
theorem canonicalResidualHom_injective_iff (M : DFA Symbol State) (hacc : Accessible M) :
Function.Injective (canonicalResidualHom M hacc) ↔ StateSeparated M
CSLibExt/Computability/Languages/Congruences/Universal.lean:136
theorem canonicalResidualHom_surjective (M : DFA Symbol State) (hacc : Accessible M) :
Function.Surjective (canonicalResidualHom M hacc)
CSLibExt/Computability/Languages/Congruences/Universal.lean:126
TheoremUniqueness of the canonical residual map#✓fully proved
For an accessible DFA \(M\) accepting the language \(L\), every DFA morphism from \(M\) to the residual-language DFA of \(L\) equals the canonical residual map.
theorem canonicalResidualHom_unique (M : DFA Symbol State) (hacc : Accessible M)
(f : DFAHom M M.accepts.toDFA) : f = canonicalResidualHom M hacc
def Accessible (M : DFA Symbol State) : Prop :=
∀ q, ReachableState M q
CSLibExt/Computability/Languages/Congruences/Minimality.lean:191
structure DFAHom (M : DFA Symbol State) (N : DFA Symbol State') where
toFun : State → State'
map_start : toFun M.start = N.start
map_step : ∀ q a, toFun (M.step q a) = N.step (toFun q) a
mem_accept_iff : ∀ q, q ∈ M.accept ↔ toFun q ∈ N.accept
CSLibExt/Computability/Languages/Congruences/Universal.lean:40
noncomputable def canonicalResidualHom (M : DFA Symbol State) (hacc : Accessible M) :
DFAHom M M.accepts.toDFA where
toFun q := by
refine ⟨M.acceptsFrom q, ?_⟩
obtain ⟨x, hx⟩ := hacc q
refine ⟨x, ?_⟩
rw [Language.leftQuotient_accepts_apply, hx]
map_start := by
apply Subtype.ext
rfl
map_step q a := by
apply Subtype.ext
⋯
CSLibExt/Computability/Languages/Congruences/Universal.lean:100
Uses 5
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.