Skip to content

Commit 8ad59b7

Browse files
committed
Complete proof that regular languages are closed under Kleene star
1 parent 4a7b922 commit 8ad59b7

1 file changed

Lines changed: 223 additions & 25 deletions

File tree

TraceTheory/TraceTheory/Computability.lean

Lines changed: 223 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ lemma IsPath.concat_lift_inl {εM₁ : εNFA α σ₁} {εM₂ : εNFA α σ₂}
3030
(h : εM₁.IsPath s t x) : (concat εM₁ εM₂).IsPath (Sum.inl s) (Sum.inl t) x := by
3131
induction h with
3232
| nil _ =>
33-
exact (εNFA.isPath_nil (concat εM₁ εM₂)).mpr rfl
33+
exact (isPath_nil (concat εM₁ εM₂)).mpr rfl
3434
| cons t' s' u oa x' h_step h_path ih =>
35-
apply εNFA.IsPath.cons (Sum.inl t') (Sum.inl s') (Sum.inl u)
35+
apply IsPath.cons (Sum.inl t') (Sum.inl s') (Sum.inl u)
3636
· simp [concat]
3737
cases oa with
3838
| some a =>
@@ -45,9 +45,9 @@ lemma IsPath.concat_lift_inr {εM₁ : εNFA α σ₁} {εM₂ : εNFA α σ₂}
4545
(h : εM₂.IsPath s t x) : (concat εM₁ εM₂).IsPath (Sum.inr s) (Sum.inr t) x := by
4646
induction h with
4747
| nil _ =>
48-
exact (εNFA.isPath_nil (concat εM₁ εM₂)).mpr rfl
48+
exact (isPath_nil (concat εM₁ εM₂)).mpr rfl
4949
| cons t' s' u _ _ h_step _ ih =>
50-
apply εNFA.IsPath.cons (Sum.inr t') (Sum.inr s') (Sum.inr u)
50+
apply IsPath.cons (Sum.inr t') (Sum.inr s') (Sum.inr u)
5151
· simp [concat]
5252
exact h_step
5353
· exact ih
@@ -66,7 +66,7 @@ lemma IsPath.concat_proj_inr {εM₁ : εNFA α σ₁} {εM₂ : εNFA α σ₂}
6666
subst hs' ht'
6767
simp [concat] at h_step
6868
rcases h_step with ⟨q, hq, rfl⟩
69-
apply εNFA.IsPath.cons q s t
69+
apply IsPath.cons q s t
7070
· exact hq
7171
· simp [ih]
7272

@@ -93,38 +93,36 @@ lemma IsPath.concat_split_inl_inr
9393
use some a :: u, v, s_acc, s_start
9494
and_intros
9595
· simp [hx']
96-
· exact εNFA.IsPath.cons q s s_acc (some a) u hq h_path_rest
96+
· exact IsPath.cons q s s_acc (some a) u hq h_path_rest
9797
· exact h_acc
9898
· exact h_bridge
9999
· exact h_path_M₂
100100
| none =>
101101
by_cases h_mem : s ∈ εM₁.accept
102102
· simp [concat, h_mem] at h_step
103103
rcases h_step with ⟨q, hq, rfl⟩ | ⟨q, hq, rfl⟩
104-
· have ⟨u, v, s_acc, s_start, hx', h_path_rest, h_acc, h_bridge, h_path_M₂⟩ :=
105-
ih (Eq.refl _) (Eq.refl _)
104+
· have ⟨u, v, s_acc, s_start, hx', h_path_rest, h_acc, h_bridge, h_path_M₂⟩ := ih rfl rfl
106105
use none :: u, v, s_acc, s_start
107106
and_intros
108107
· simp [hx']
109-
· exact εNFA.IsPath.cons q s s_acc none u hq h_path_rest
108+
· exact IsPath.cons q s s_acc none u hq h_path_rest
110109
· exact h_acc
111110
· exact h_bridge
112111
· exact h_path_M₂
113112
· use [], x', s, q
114113
and_intros
115114
· simp
116-
· exact (εNFA.isPath_nil εM₁).mpr rfl
115+
· exact (isPath_nil εM₁).mpr rfl
117116
· exact h_mem
118117
· exact hq
119118
· exact IsPath.concat_proj_inr h_path
120119
· simp [concat, h_mem] at h_step
121120
rcases h_step with ⟨q, hq, rfl⟩
122-
have ⟨u, v, s_acc, s_start, hx', h_path_rest, h_acc, h_bridge, h_path_M₂⟩ :=
123-
ih (Eq.refl _) (Eq.refl _)
121+
have ⟨u, v, s_acc, s_start, hx', h_path_rest, h_acc, h_bridge, h_path_M₂⟩ := ih rfl rfl
124122
use none :: u, v, s_acc, s_start
125123
and_intros
126124
· simp [hx']
127-
· exact εNFA.IsPath.cons q s s_acc none u hq h_path_rest
125+
· exact IsPath.cons q s s_acc none u hq h_path_rest
128126
· exact h_acc
129127
· exact h_bridge
130128
· exact h_path_M₂
@@ -135,7 +133,7 @@ theorem accepts_concat {εM₁ : εNFA α σ₁} {εM₂ : εNFA α σ₂} :
135133
constructor
136134
· intro h
137135
have ⟨q₁, q₂, x', hq₁, hq₂, hx', hεM⟩ :=
138-
(εNFA.mem_accepts_iff_exists_path (concat εM₁ εM₂)).mp h
136+
(mem_accepts_iff_exists_path (concat εM₁ εM₂)).mp h
139137
simp [concat] at hq₁ hq₂
140138
rcases hq₁ with ⟨s, hs, rfl⟩
141139
rcases hq₂ with ⟨t, ht, rfl⟩
@@ -144,28 +142,28 @@ theorem accepts_concat {εM₁ : εNFA α σ₁} {εM₂ : εNFA α σ₂} :
144142
apply Language.mem_mul.mpr
145143
use u'.reduceOption
146144
constructor
147-
· apply (εNFA.mem_accepts_iff_exists_path εM₁).mpr
145+
· apply (mem_accepts_iff_exists_path εM₁).mpr
148146
use s, s_acc, u'
149147
· use v'.reduceOption
150148
constructor
151-
· apply (εNFA.mem_accepts_iff_exists_path εM₂).mpr
149+
· apply (mem_accepts_iff_exists_path εM₂).mpr
152150
use s_start, t, v'
153151
· rw [← hx', ← List.reduceOption_append, hx]
154152
simp [List.reduceOption_append, List.reduceOption_cons_of_none]
155153
· simp [Language.mul_def, Set.image2]
156154
rw [Set.mem_setOf_eq]
157155
intro ⟨u, hu, v, hv, hx⟩
158-
have ⟨uq₁, uq₂, u', huq₁, huq₂, hu', hεM₁⟩ := (εNFA.mem_accepts_iff_exists_path εM₁).mp hu
159-
have ⟨vq₁, vq₂, v', hvq₁, hvq₂, hv', hεM₂⟩ := (εNFA.mem_accepts_iff_exists_path εM₂).mp hv
160-
apply (εNFA.mem_accepts_iff_exists_path (concat εM₁ εM₂)).mpr
156+
have ⟨uq₁, uq₂, u', huq₁, huq₂, hu', hεM₁⟩ := (mem_accepts_iff_exists_path εM₁).mp hu
157+
have ⟨vq₁, vq₂, v', hvq₁, hvq₂, hv', hεM₂⟩ := (mem_accepts_iff_exists_path εM₂).mp hv
158+
apply (mem_accepts_iff_exists_path (concat εM₁ εM₂)).mpr
161159
use Sum.inl uq₁, Sum.inr vq₂, u' ++ [none] ++ v'
162160
and_intros
163161
· simp [concat]
164162
exact huq₁
165163
· simp [concat]
166164
exact hvq₂
167165
· simp [List.reduceOption_append, hx, hu', hv']
168-
· simp only [εNFA.isPath_append]
166+
· simp only [isPath_append]
169167
use (Sum.inr vq₁)
170168
constructor
171169
· use (Sum.inl uq₂)
@@ -204,7 +202,7 @@ lemma IsPath.kstar_lift_inr {εM : εNFA α σ} {s t : σ} {x : List (Option α)
204202
| nil _ =>
205203
exact (isPath_nil εM.kstar).mpr rfl
206204
| cons t' s' u oa x' h_step h_path ih =>
207-
apply εNFA.IsPath.cons (Sum.inr t') (Sum.inr s') (Sum.inr u)
205+
apply IsPath.cons (Sum.inr t') (Sum.inr s') (Sum.inr u)
208206
· simp [kstar]
209207
cases oa with
210208
| some a =>
@@ -213,7 +211,7 @@ lemma IsPath.kstar_lift_inr {εM : εNFA α σ} {s t : σ} {x : List (Option α)
213211
by_cases h_mem : s' ∈ εM.accept <;> simp [h_mem, h_step]
214212
· exact ih
215213

216-
lemma exists_kstar_path_inr {εM : εNFA α σ}
214+
lemma kstar_exists_path_inr {εM : εNFA α σ}
217215
(L : List (List α)) (h_nonempty : L ≠ []) (h_all : ∀ y ∈ L, y ∈ εM.accepts) :
218216
∃ (s : σ) (q : Unit ⊕ σ) (x : List (Option α)),
219217
s ∈ εM.start ∧
@@ -225,7 +223,7 @@ lemma exists_kstar_path_inr {εM : εNFA α σ}
225223
contradiction
226224
| cons y L' ih =>
227225
have hy := h_all y List.mem_cons_self
228-
have ⟨s, t, x, hs, ht, hy', hx⟩ := (εNFA.mem_accepts_iff_exists_path εM).mp hy
226+
have ⟨s, t, x, hs, ht, hy', hx⟩ := (mem_accepts_iff_exists_path εM).mp hy
229227
subst hy'
230228
cases L' with
231229
| nil =>
@@ -255,10 +253,210 @@ lemma exists_kstar_path_inr {εM : εNFA α σ}
255253
· simp [kstar, ht, hs']
256254
· simp [hx']
257255

256+
lemma kstar_no_return {εM : εNFA α σ} {s : σ} {t : Unit ⊕ σ} {x : List (Option α)}
257+
(h : (kstar εM).IsPath (Sum.inr s) t x) : t ≠ Sum.inl () := by
258+
generalize hs' : Sum.inr s = s' at h
259+
induction h generalizing s with
260+
| nil u =>
261+
subst hs'
262+
simp
263+
| cons t' s'' u oa x' h_step h_path ih =>
264+
subst hs'
265+
have h_next_is_inr : ∃ y, Sum.inr y = t' := by
266+
simp [kstar] at h_step
267+
cases oa with
268+
| some a =>
269+
simp at h_step
270+
rcases h_step with ⟨y, _, rfl⟩
271+
use y
272+
| none =>
273+
simp at h_step
274+
split_ifs at h_step with h_mem
275+
· rcases h_step with ⟨y, _, rfl⟩ | ⟨y, _, rfl⟩
276+
· use y
277+
· use y
278+
· rcases h_step with ⟨y, _, rfl⟩
279+
use y
280+
rcases h_next_is_inr with ⟨y, rfl⟩
281+
exact ih rfl
282+
283+
lemma IsPath.kstar_split_inr {s t : σ} {x : List (Option α)}
284+
(h : (kstar εM).IsPath (Sum.inr s) (Sum.inr t) x) :
285+
(∃ x', x'.reduceOption = x.reduceOption ∧ εM.IsPath s t x') ∨
286+
(∃ (u v : List (Option α)) (q_acc : σ) (s_next : σ),
287+
x.reduceOption = u.reduceOption ++ v.reduceOption ∧
288+
εM.IsPath s q_acc u ∧
289+
q_acc ∈ εM.accept ∧
290+
s_next ∈ εM.start ∧
291+
(kstar εM).IsPath (Sum.inr s_next) (Sum.inr t) v ∧
292+
v.length < x.length) := by
293+
generalize hs' : Sum.inr s = s' at h
294+
generalize ht' : Sum.inr t = t' at h
295+
induction h generalizing s with
296+
| nil q =>
297+
left
298+
use []
299+
simp
300+
cases hs'
301+
cases ht'
302+
rfl
303+
| cons u' s'' t'' oa x'' h_step h_path ih =>
304+
subst hs' ht'
305+
cases oa with
306+
| some a =>
307+
simp [kstar] at h_step
308+
have ⟨s_next, hs_next, hu'⟩ := h_step
309+
rcases ih hu' rfl with
310+
⟨y, hx'', hy⟩ |
311+
⟨u, v, q_acc, s_next', huv, hu, hq_acc, hs_next', hv, hlt⟩
312+
· left
313+
use some a :: y
314+
constructor
315+
· simp [hx'']
316+
· exact IsPath.cons s_next s t (some a) y hs_next hy
317+
· right
318+
use some a :: u, v, q_acc, s_next'
319+
and_intros
320+
· simp [huv]
321+
· exact IsPath.cons s_next s q_acc (some a) u hs_next hu
322+
· exact hq_acc
323+
· exact hs_next'
324+
· exact hv
325+
· simp
326+
exact Nat.lt_add_right 1 hlt
327+
| none =>
328+
simp [kstar] at h_step
329+
split_ifs at h_step with h_mem
330+
· simp at h_step
331+
rcases h_step with ⟨s_next, hs_next, hu'⟩ | ⟨s_start, hs_start, hu'⟩
332+
· rcases ih hu' rfl with
333+
⟨y, hx'', hy⟩ |
334+
⟨u, v, q_acc, s_next', huv, hu, hq_acc, hs_next', hv, hlt⟩
335+
· left
336+
use none :: y
337+
constructor
338+
· simp [hx'']
339+
· exact cons s_next s t none y hs_next hy
340+
· right
341+
use none :: u, v, q_acc, s_next'
342+
and_intros
343+
· simp [huv]
344+
· exact IsPath.cons s_next s q_acc none u hs_next hu
345+
· exact hq_acc
346+
· exact hs_next'
347+
· exact hv
348+
· simp
349+
exact Nat.lt_add_right 1 hlt
350+
· right
351+
use [], x'', s, s_start
352+
and_intros
353+
· simp
354+
· exact (isPath_nil εM).mpr rfl
355+
· exact h_mem
356+
· exact hs_start
357+
· simp [hu', h_path]
358+
· simp
359+
· simp at h_step
360+
rcases h_step with ⟨s_next, hs_next, hu'⟩
361+
rcases ih hu' rfl with
362+
⟨y, hx'', hy⟩ |
363+
⟨u, v, q_acc, s_next', huv, hu, hq_acc, hs_next', hv, hlt⟩
364+
· left
365+
use none :: y
366+
constructor
367+
· simp [hx'']
368+
· exact IsPath.cons s_next s t none y hs_next hy
369+
· right
370+
use none :: u, v, q_acc, s_next'
371+
and_intros
372+
· simp [huv]
373+
· exact IsPath.cons s_next s q_acc none u hs_next hu
374+
· exact hq_acc
375+
· exact hs_next'
376+
· exact hv
377+
· simp
378+
exact Nat.lt_add_right 1 hlt
379+
380+
lemma IsPath.kstar_exists_decomp {εM : εNFA α σ} {s t : σ} {x : List (Option α)}
381+
(h : (kstar εM).IsPath (Sum.inr s) (Sum.inr t) x)
382+
(hs : s ∈ εM.start) (ht : t ∈ εM.accept) :
383+
∃ (L : List (List α)), L.flatten = x.reduceOption ∧ ∀ y ∈ L, y ∈ εM.accepts := by
384+
generalize h_len : x.length = n
385+
induction n using Nat.strong_induction_on generalizing s x with
386+
| h n ih =>
387+
rcases IsPath.kstar_split_inr h with
388+
⟨x', hx, hx'⟩ |
389+
⟨u, v, q_acc, s_next, hx, hu, h_acc, h_next, hv, hlt⟩
390+
· use [x'.reduceOption]
391+
constructor
392+
· simp [hx]
393+
· intro y hy
394+
simp at hy
395+
subst hy
396+
apply (mem_accepts_iff_exists_path εM).mpr
397+
use s, t, x'
398+
· have hu_acc : u.reduceOption ∈ εM.accepts := by
399+
apply (mem_accepts_iff_exists_path εM).mpr
400+
use s, q_acc, u
401+
subst h_len
402+
have ⟨L', hv', hL'⟩ := ih v.length hlt hv h_next rfl
403+
use u.reduceOption :: L'
404+
constructor
405+
· simp [hv', hx]
406+
· intro y hy
407+
simp at hy
408+
rcases hy with hy | hy
409+
· simp [hu_acc, hy]
410+
· exact hL' y hy
411+
258412
theorem accepts_kstar {εM : εNFA α σ} : (kstar εM).accepts = (εM.accepts)∗ := by
259413
ext x
260414
constructor
261-
· sorry
415+
· intro h
416+
rw [Language.kstar_def, Set.mem_setOf_eq]
417+
have ⟨s, t, x', hs, ht, hx, h_path⟩ := (mem_accepts_iff_exists_path εM.kstar).mp h
418+
match t with
419+
| Sum.inl _ =>
420+
use []
421+
simp [kstar] at hs
422+
simp [hs] at h_path
423+
cases h_path with
424+
| nil _ =>
425+
simpa using hx
426+
| cons t' s' u oa x'' h_step h_path =>
427+
simp [kstar] at h_step
428+
cases oa with
429+
| some a =>
430+
simp at h_step
431+
| none =>
432+
simp at h_step
433+
rcases h_step with ⟨y, _, rfl⟩
434+
have h_absurd := kstar_no_return h_path
435+
contradiction
436+
| Sum.inr t' =>
437+
cases x' with
438+
| nil =>
439+
simp [kstar] at hs h_path
440+
subst hs
441+
contradiction
442+
| cons oa x'' =>
443+
rw [← List.singleton_append, isPath_append] at h_path
444+
have ⟨u, hsu, hut⟩ := h_path
445+
simp [kstar] at hs
446+
subst hs
447+
cases oa with
448+
| some a =>
449+
simp [kstar] at hsu
450+
| none =>
451+
simp [kstar] at hsu ht
452+
rcases hsu with ⟨u', hu', hu⟩
453+
subst hu
454+
have ⟨L, hx', hL⟩ := IsPath.kstar_exists_decomp hut hu' ht
455+
use L
456+
constructor
457+
· simp at hx
458+
simp [hx, hx']
459+
· exact hL
262460
· intro h
263461
rw [Language.kstar_def, Set.mem_setOf_eq] at h
264462
rcases h with ⟨L, hx, hL⟩
@@ -270,7 +468,7 @@ theorem accepts_kstar {εM : εNFA α σ} : (kstar εM).accepts = (εM.accepts)
270468
| cons l L' =>
271469
expose_names
272470
have h_nonempty : l :: L' ≠ [] := by simp
273-
have ⟨s, q, x', hs, hq, hL', hx'⟩ := exists_kstar_path_inr (l :: L') h_nonempty hL
471+
have ⟨s, q, x', hs, hq, hL', hx'⟩ := kstar_exists_path_inr (l :: L') h_nonempty hL
274472
use Sum.inl (), q, none :: x'
275473
and_intros
276474
· simp [kstar]

0 commit comments

Comments
 (0)