|
| 1 | +import Mathlib.Data.Finset.Basic |
| 2 | +import Mathlib.Data.List.Lex |
| 3 | + |
| 4 | +open List |
| 5 | + |
| 6 | +variable {α : Type} [DecidableEq α] |
| 7 | + |
| 8 | +namespace TraceTheory |
| 9 | + |
| 10 | +/-- The projection of a string onto an alpabet. Removes all symbols not in the Finset.-/ |
| 11 | +def proj (S : Finset α) (w : List α) : List α := w.filter (· ∈ S) |
| 12 | + |
| 13 | +@[simp] |
| 14 | +theorem proj_append {S : Finset α} {u v : List α} : |
| 15 | + proj S (u ++ v) = proj S u ++ proj S v := by |
| 16 | + simp [proj] |
| 17 | + |
| 18 | +@[simp] |
| 19 | +theorem proj_reverse {S : Finset α} {w : List α} : |
| 20 | + reverse (proj S w) = proj S (reverse w) := by |
| 21 | + simp [proj] |
| 22 | + |
| 23 | +/-- Cancel the first occurrence of a symbol (if any) from the right of a word. -/ |
| 24 | +def cancelRight (w : List α) (a : α) : List α := reverse (List.erase (reverse w) a) |
| 25 | + |
| 26 | +/-- Notation for right cancellation. -/ |
| 27 | +infixl:65 " ÷ " => cancelRight |
| 28 | + |
| 29 | +@[simp] |
| 30 | +theorem cancelRight_nil {a : α} : [] ÷ a = [] := |
| 31 | + rfl |
| 32 | + |
| 33 | +lemma append_singleton_cancelRight {w : List α} {a b : α} : |
| 34 | + (w ++ [b]) ÷ a = if b = a then w else w ÷ a ++ [b] := by |
| 35 | + split_ifs with heq <;> simp [cancelRight, heq] |
| 36 | + |
| 37 | +@[simp] |
| 38 | +theorem append_cancelRight {u v : List α} {a : α} : |
| 39 | + (u ++ v) ÷ a = if a ∈ v then u ++ (v ÷ a) else (u ÷ a) ++ v := by |
| 40 | + induction v using List.reverseRecOn with |
| 41 | + | nil => |
| 42 | + simp |
| 43 | + | append_singleton v' b ih => |
| 44 | + rw [← append_assoc, append_singleton_cancelRight] |
| 45 | + by_cases heq : b = a <;> by_cases h_mem : a ∈ v' |
| 46 | + · simp [heq, append_singleton_cancelRight] |
| 47 | + · simp [heq, append_singleton_cancelRight] |
| 48 | + · simp [heq, h_mem, ih, append_singleton_cancelRight] |
| 49 | + · simp [heq, h_mem, ih, Ne.symm] |
| 50 | + |
| 51 | +@[simp] |
| 52 | +theorem singleton_cancelRight {a : α} : [a] ÷ a = [] := by |
| 53 | + simp [cancelRight] |
| 54 | + |
| 55 | +theorem proj_cancelRight {S : Finset α} {w : List α} {a : α} : |
| 56 | + proj S (w ÷ a) = if a ∈ S then proj S w ÷ a else proj S w := by |
| 57 | + induction w using List.reverseRecOn with |
| 58 | + | nil => |
| 59 | + simp [proj] |
| 60 | + | append_singleton w' b ih => |
| 61 | + split_ifs with ha <;> by_cases heq : b = a |
| 62 | + · simp [heq, ha, proj] |
| 63 | + · simp [heq, ha, ih, Ne.symm] |
| 64 | + by_cases hb : b ∈ S |
| 65 | + · simp [heq, hb, proj, Ne.symm] |
| 66 | + · simp [hb, proj] |
| 67 | + · simp [heq, ha, proj] |
| 68 | + · simp [heq, ha, ih, Ne.symm] |
| 69 | + |
| 70 | +theorem rightmost_occurrence {w : List α} {a : α} (h : a ∈ w) : |
| 71 | + ∃ w' w'', w = w' ++ [a] ++ w'' ∧ a ∉ w'' := by |
| 72 | + induction w using List.reverseRecOn with |
| 73 | + | nil => |
| 74 | + contradiction |
| 75 | + | append_singleton v b ih => |
| 76 | + by_cases hab : a = b |
| 77 | + · use v, [] |
| 78 | + simp [hab] |
| 79 | + · simp [hab] at h |
| 80 | + have ⟨w', w'', h_concat, h_in⟩ := ih h |
| 81 | + use w', w'' ++ [b] |
| 82 | + simp [h_concat, h_in, hab] |
| 83 | + |
| 84 | +theorem leftmost_occurrence {w : List α} {a : α} (h : a ∈ w) : |
| 85 | + ∃ w' w'', w = w' ++ [a] ++ w'' ∧ a ∉ w' := by |
| 86 | + induction w with |
| 87 | + | nil => |
| 88 | + contradiction |
| 89 | + | cons b v ih => |
| 90 | + by_cases hab : a = b |
| 91 | + · use [], v |
| 92 | + simp [hab] |
| 93 | + · simp [hab] at h |
| 94 | + have ⟨w', w'', h_concat, h_in⟩ := ih h |
| 95 | + use [b] ++ w', w'' |
| 96 | + simp [h_concat, h_in, hab] |
| 97 | + |
| 98 | +omit [DecidableEq α] in |
| 99 | +theorem exists_decomp_of_lt_of_len_eq {w x : List α} [LinearOrder α] |
| 100 | + (hlt : w < x) (h_len : w.length = x.length): |
| 101 | + ∃ p a b w' x', |
| 102 | + w = p ++ [a] ++ w' ∧ |
| 103 | + x = p ++ [b] ++ x' ∧ |
| 104 | + a < b := by |
| 105 | + induction w generalizing x with |
| 106 | + | nil => |
| 107 | + cases x <;> contradiction |
| 108 | + | cons a w' ih => |
| 109 | + cases x with |
| 110 | + | nil => |
| 111 | + contradiction |
| 112 | + | cons b x' => |
| 113 | + cases hlt with |
| 114 | + | rel hab => |
| 115 | + use [], a, b, w', x' |
| 116 | + exact ⟨rfl, rfl, hab⟩ |
| 117 | + | cons h_lex => |
| 118 | + simp at h_len |
| 119 | + have ⟨p', a', b', w'', x'', hw', hx', hlt'⟩ := ih (List.lex_lt.mp h_lex) h_len |
| 120 | + use a :: p', a', b', w'', x'' |
| 121 | + simp [hw', hx', hlt'] |
| 122 | + |
| 123 | +end TraceTheory |
0 commit comments