|
1 | 1 | import Mathlib.Computability.EpsilonNFA |
2 | 2 | import Mathlib.Computability.Language |
3 | 3 | import Mathlib.Computability.RegularExpressions |
| 4 | +import Mathlib.Data.Fintype.Option |
4 | 5 |
|
5 | 6 | open Classical Computability |
6 | 7 |
|
7 | 8 | variable {α : Type} |
8 | 9 |
|
| 10 | +namespace DFA |
| 11 | + |
| 12 | +section epsilon |
| 13 | + |
| 14 | +def epsilon : DFA α (Option Unit) where |
| 15 | + step := fun _ _ => none |
| 16 | + start := some () |
| 17 | + accept := { some () } |
| 18 | + |
| 19 | +theorem accepts_epsilon : epsilon.accepts = (1 : Language α) := by |
| 20 | + ext x |
| 21 | + simp [DFA.accepts, DFA.acceptsFrom, DFA.evalFrom] |
| 22 | + rw [Set.mem_setOf_eq] |
| 23 | + cases x with |
| 24 | + | nil => |
| 25 | + simp [epsilon] |
| 26 | + | cons a x' => |
| 27 | + simp [epsilon] |
| 28 | + have h_dead : ∀ w : List α, List.foldl (fun _ _ => none) (none : Option Unit) w = none := by |
| 29 | + intro w; induction w <;> simp [*] |
| 30 | + intro h_absurd |
| 31 | + rw [h_dead] at h_absurd |
| 32 | + contradiction |
| 33 | + |
| 34 | +end epsilon |
| 35 | + |
| 36 | +section singleton |
| 37 | + |
| 38 | +def char (a : α) [DecidableEq α] : DFA α (Option Bool) where |
| 39 | + step (ob : Option Bool) (x : α) := match ob with |
| 40 | + | some true => none |
| 41 | + | some false => if x = a then some true else none |
| 42 | + | none => none |
| 43 | + start := some false |
| 44 | + accept := { some true } |
| 45 | + |
| 46 | +@[simp] |
| 47 | +theorem char_step_start (a : α) [DecidableEq α] (x : α) : |
| 48 | + (char a).step (some false) x = if x = a then some true else none := rfl |
| 49 | + |
| 50 | +@[simp] |
| 51 | +theorem char_step_accept (a : α) [DecidableEq α] (x : α) : |
| 52 | + (char a).step (some true) x = none := rfl |
| 53 | + |
| 54 | +@[simp] |
| 55 | +theorem char_step_dead (a : α) [DecidableEq α] (x : α) : |
| 56 | + (char a).step none x = none := rfl |
| 57 | + |
| 58 | +theorem accepts_char {a : α} : (char a).accepts = { [a] } := by |
| 59 | + ext x |
| 60 | + simp [DFA.accepts, DFA.acceptsFrom, DFA.evalFrom] |
| 61 | + rw [Set.mem_setOf_eq, Set.mem_singleton_iff] |
| 62 | + cases x with |
| 63 | + | nil => |
| 64 | + simp [char] |
| 65 | + | cons b x' => |
| 66 | + cases x' with |
| 67 | + | nil => |
| 68 | + simp [char] |
| 69 | + | cons c x'' => |
| 70 | + have h_dead : ∀ w, List.foldl (char a).step none w = none := by |
| 71 | + intro w; induction w <;> simp [*] |
| 72 | + simp [char] at * |
| 73 | + split_ifs |
| 74 | + all_goals( |
| 75 | + intro h_absurd |
| 76 | + rw [h_dead] at h_absurd |
| 77 | + contradiction |
| 78 | + ) |
| 79 | + |
| 80 | +end singleton |
| 81 | + |
| 82 | +end DFA |
| 83 | + |
9 | 84 | namespace εNFA |
10 | 85 |
|
11 | 86 | section concat |
@@ -481,96 +556,27 @@ end kstar |
481 | 556 |
|
482 | 557 | end εNFA |
483 | 558 |
|
484 | | -namespace DFA |
485 | | - |
486 | | -section singleton |
487 | | - |
488 | | -def char (a : α) [DecidableEq α] : DFA α (Fin 3) where |
489 | | - step (n : Fin 3) (x : α) := |
490 | | - match n.val with |
491 | | - | Nat.zero => |
492 | | - if x = a then 1 else 2 |
493 | | - | Nat.succ _ => |
494 | | - 2 |
495 | | - start := 0 |
496 | | - accept := {1} |
497 | | - |
498 | | -theorem accepts_char {a : α} : (char a).accepts = { [a] } := by |
499 | | - ext x |
500 | | - simp [DFA.accepts, DFA.acceptsFrom, DFA.evalFrom] |
501 | | - constructor |
502 | | - · intro h |
503 | | - rw [Set.mem_setOf_eq] at h |
504 | | - cases x with |
505 | | - | nil => |
506 | | - simp [char] at h |
507 | | - | cons b x' => |
508 | | - have h_dead_state : ∀ w, List.foldl (char a).step 2 w = 2 := by |
509 | | - intro w |
510 | | - induction w with |
511 | | - | nil => |
512 | | - simp |
513 | | - | cons b w' ih => |
514 | | - simp [char] at * |
515 | | - simp [ih] |
516 | | - by_cases heq : b = a |
517 | | - · subst heq |
518 | | - simp [char] at h h_dead_state |
519 | | - cases x' with |
520 | | - | nil => |
521 | | - rfl |
522 | | - | cons c x'' => |
523 | | - by_cases heq' : c = b |
524 | | - all_goals( |
525 | | - simp [heq'] at h |
526 | | - rw [h_dead_state] at h |
527 | | - contradiction |
528 | | - ) |
529 | | - · simp [char, heq] at h h_dead_state |
530 | | - rw [h_dead_state] at h |
531 | | - contradiction |
532 | | - · rintro rfl |
533 | | - rw [Set.mem_setOf_eq] |
534 | | - simp [char] |
535 | | - |
536 | | -end singleton |
537 | | - |
538 | | -end DFA |
539 | | - |
540 | 559 | namespace Language |
541 | 560 |
|
542 | 561 | theorem IsRegular.zero : IsRegular (0 : Language α) := by |
543 | 562 | apply isRegular_iff.mpr |
544 | 563 | use Unit, inferInstance, ⟨fun _ _ => (), (), {}⟩ |
545 | 564 | rfl |
546 | 565 |
|
| 566 | +theorem IsRegular.one : IsRegular (1 : Language α) := by |
| 567 | + apply isRegular_iff.mpr |
| 568 | + use Option Unit, inferInstance, DFA.epsilon |
| 569 | + exact DFA.accepts_epsilon |
| 570 | + |
547 | 571 | theorem IsRegular.top : IsRegular (⊤ : Language α) := by |
548 | 572 | rw [← compl_bot, bot_eq_zero] |
549 | 573 | apply IsRegular.compl |
550 | 574 | exact IsRegular.zero |
551 | 575 |
|
552 | | -theorem IsRegular.one : IsRegular (1 : Language α) := by |
| 576 | +theorem IsRegular.singleton {a : α} : IsRegular ({ [a] }) := by |
553 | 577 | apply isRegular_iff.mpr |
554 | | - use Fin 2, inferInstance, ⟨fun _ _ => 1, 0, { 0 }⟩ |
555 | | - simp [DFA.accepts, DFA.acceptsFrom, DFA.evalFrom] |
556 | | - ext x |
557 | | - rw [Set.mem_setOf_eq] |
558 | | - cases x with |
559 | | - | nil => |
560 | | - simp |
561 | | - | cons _ x' => |
562 | | - simp |
563 | | - intro h |
564 | | - have h_dead_state : ∀ w : List α, List.foldl (fun (_ : Fin 2) _ => 1) 1 w = 1 := by |
565 | | - intro w |
566 | | - induction w with |
567 | | - | nil => |
568 | | - simp |
569 | | - | cons b w' ih => |
570 | | - simp [ih] |
571 | | - have h_absurd := h_dead_state x' |
572 | | - rw [h] at h_absurd |
573 | | - contradiction |
| 578 | + use Option Bool, inferInstance, DFA.char a |
| 579 | + exact DFA.accepts_char |
574 | 580 |
|
575 | 581 | theorem IsRegular.mul {L₁ L₂ : Language α} [DecidableEq α] |
576 | 582 | (h₁ : IsRegular L₁) (h₂ : IsRegular L₂) : |
@@ -599,12 +605,6 @@ theorem IsRegular.kstar {L : Language α} (h : IsRegular L) : IsRegular (L∗) : |
599 | 605 | rw [← DFA.toNFA_correct, ← NFA.toεNFA_correct] |
600 | 606 | exact εNFA.accepts_kstar |
601 | 607 |
|
602 | | -theorem IsRegular.singleton {a : α} : IsRegular ({ [a] }) := by |
603 | | - apply isRegular_iff.mpr |
604 | | - let M := DFA.char a |
605 | | - use Fin 3, inferInstance, M |
606 | | - exact DFA.accepts_char |
607 | | - |
608 | 608 | end Language |
609 | 609 |
|
610 | 610 | namespace RegularExpressions |
|
0 commit comments