feat: List.replicate lemmas (#5350)

This commit is contained in:
Kim Morrison 2024-09-16 09:57:04 +10:00 committed by GitHub
parent 4c439c73a7
commit 3ef67c468a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 3 deletions

View file

@ -2323,6 +2323,47 @@ theorem bind_replicate {β} (f : α → List β) : (replicate n a).bind f = (rep
@[simp] theorem isEmpty_replicate : (replicate n a).isEmpty = decide (n = 0) := by
cases n <;> simp [replicate_succ]
/-- Every list is either empty, a non-empty `replicate`, or begins with a non-empty `replicate`
followed by a different element. -/
theorem eq_replicate_or_eq_replicate_append_cons {α : Type _} (l : List α) :
(l = []) (∃ n a, l = replicate n a ∧ 0 < n)
(∃ n a b l', l = replicate n a ++ b :: l' ∧ 0 < n ∧ a ≠ b) := by
induction l with
| nil => simp
| cons x l ih =>
right
rcases ih with rfl | ⟨n, a, rfl, h⟩ | ⟨n, a, b, l', rfl, h⟩
· left
exact ⟨1, x, rfl, by decide⟩
· by_cases h' : x = a
· subst h'
left
exact ⟨n + 1, x, rfl, by simp⟩
· right
refine ⟨1, x, a, replicate (n - 1) a, ?_, by decide, h'⟩
match n with | n + 1 => simp [replicate_succ]
· right
by_cases h' : x = a
· subst h'
refine ⟨n + 1, x, b, l', by simp [replicate_succ], by simp, h.2⟩
· refine ⟨1, x, a, replicate (n - 1) a ++ b :: l', ?_, by decide, h'⟩
match n with | n + 1 => simp [replicate_succ]
/-- An induction principle for lists based on contiguous runs of identical elements. -/
-- A `Sort _` valued version would require a different design. (And associated `@[simp]` lemmas.)
theorem replicateRecOn {α : Type _} {p : List α → Prop} (m : List α)
(h0 : p []) (hr : ∀ a n, 0 < n → p (replicate n a))
(hi : ∀ a b n l, a ≠ b → 0 < n → p (b :: l) → p (replicate n a ++ b :: l)) : p m := by
rcases eq_replicate_or_eq_replicate_append_cons m with
rfl | ⟨n, a, rfl, hn⟩ | ⟨n, a, b, l', w, hn, h⟩
· exact h0
· exact hr _ _ hn
· have : (b :: l').length < m.length := by
simpa [w] using Nat.lt_add_of_pos_left hn
subst w
exact hi _ _ _ _ h hn (replicateRecOn (b :: l') h0 hr hi)
termination_by m.length
/-! ### reverse -/
@[simp] theorem length_reverse (as : List α) : (as.reverse).length = as.length := by

View file

@ -514,6 +514,10 @@ protected theorem add_lt_add_left {n m : Nat} (h : n < m) (k : Nat) : k + n < k
protected theorem add_lt_add_right {n m : Nat} (h : n < m) (k : Nat) : n + k < m + k :=
Nat.add_comm k m ▸ Nat.add_comm k n ▸ Nat.add_lt_add_left h k
protected theorem lt_add_of_pos_left (h : 0 < k) : n < k + n := by
rw [Nat.add_comm]
exact Nat.add_lt_add_left h n
protected theorem lt_add_of_pos_right (h : 0 < k) : n < n + k :=
Nat.add_lt_add_left h n

View file

@ -84,9 +84,6 @@ protected theorem add_lt_add_of_lt_of_le {a b c d : Nat} (hlt : a < b) (hle : c
a + c < b + d :=
Nat.lt_of_le_of_lt (Nat.add_le_add_left hle _) (Nat.add_lt_add_right hlt _)
protected theorem lt_add_of_pos_left : 0 < k → n < k + n := by
rw [Nat.add_comm]; exact Nat.lt_add_of_pos_right
protected theorem pos_of_lt_add_right (h : n < n + k) : 0 < k :=
Nat.lt_of_add_lt_add_left h