feat: add another List.find?_eq_some lemma (#5974)

Inspired by https://github.com/leanprover-community/mathlib4/pull/18593
This commit is contained in:
Kim Morrison 2024-11-06 21:02:25 +11:00 committed by GitHub
parent 76d32cbd2a
commit 1e98fd7f2d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 4 deletions

View file

@ -206,7 +206,8 @@ theorem IsInfix.findSome?_eq_none {l₁ l₂ : List α} {f : α → Option β} (
@[simp] theorem find?_eq_none : find? p l = none ↔ ∀ x ∈ l, ¬ p x := by
induction l <;> simp [find?_cons]; split <;> simp [*]
theorem find?_eq_some : xs.find? p = some b ↔ p b ∧ ∃ as bs, xs = as ++ b :: bs ∧ ∀ a ∈ as, !p a := by
theorem find?_eq_some_iff_append :
xs.find? p = some b ↔ p b ∧ ∃ as bs, xs = as ++ b :: bs ∧ ∀ a ∈ as, !p a := by
induction xs with
| nil => simp
| cons x xs ih =>
@ -242,6 +243,9 @@ theorem find?_eq_some : xs.find? p = some b ↔ p b ∧ ∃ as bs, xs = as ++ b
cases h₁
simp
@[deprecated find?_eq_some_iff_append (since := "2024-11-06")]
abbrev find?_eq_some := @find?_eq_some_iff_append
@[simp]
theorem find?_cons_eq_some : (a :: xs).find? p = some b ↔ (p a ∧ a = b) (!p a ∧ xs.find? p = some b) := by
rw [find?_cons]
@ -347,7 +351,7 @@ theorem find?_flatten_eq_some {xs : List (List α)} {p : α → Bool} {a : α} :
xs.flatten.find? p = some a ↔
p a ∧ ∃ as ys zs bs, xs = as ++ (ys ++ a :: zs) :: bs ∧
(∀ a ∈ as, ∀ x ∈ a, !p x) ∧ (∀ x ∈ ys, !p x) := by
rw [find?_eq_some]
rw [find?_eq_some_iff_append]
constructor
· rintro ⟨h, ⟨ys, zs, h₁, h₂⟩⟩
refine ⟨h, ?_⟩

View file

@ -9,6 +9,32 @@ import Init.Data.List.Find
namespace List
open Nat
theorem find?_eq_some_iff_getElem {xs : List α} {p : α → Bool} {b : α} :
xs.find? p = some b ↔ p b ∧ ∃ i h, xs[i] = b ∧ ∀ j : Nat, (hj : j < i) → !p xs[j] := by
rw [find?_eq_some_iff_append]
simp only [Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, and_congr_right_iff]
intro w
constructor
· rintro ⟨as, ⟨bs, rfl⟩, h⟩
refine ⟨as.length, ⟨?_, ?_, ?_⟩⟩
· simp only [length_append, length_cons]
refine Nat.lt_add_of_pos_right (zero_lt_succ bs.length)
· rw [getElem_append_right (Nat.le_refl as.length)]
simp
· intro j h'
rw [getElem_append_left h']
exact h _ (getElem_mem h')
· rintro ⟨i, h, rfl, h'⟩
refine ⟨xs.take i, ⟨xs.drop (i+1), ?_⟩, ?_⟩
· rw [getElem_cons_drop, take_append_drop]
· intro a m
rw [mem_take_iff_getElem] at m
obtain ⟨j, h, rfl⟩ := m
apply h'
omega
theorem findIdx?_eq_some_le_of_findIdx?_eq_some {xs : List α} {p q : α → Bool} (w : ∀ x ∈ xs, p x → q x) {i : Nat}
(h : xs.findIdx? p = some i) : ∃ j, j ≤ i ∧ xs.findIdx? q = some j := by
simp only [findIdx?_eq_findSome?_enum] at h

View file

@ -108,7 +108,7 @@ theorem range'_eq_append_iff : range' s n = xs ++ ys ↔ ∃ k, k ≤ n ∧ xs =
@[simp] theorem find?_range'_eq_some {s n : Nat} {i : Nat} {p : Nat → Bool} :
(range' s n).find? p = some i ↔ p i ∧ i ∈ range' s n ∧ ∀ j, s ≤ j → j < i → !p j := by
rw [find?_eq_some]
rw [find?_eq_some_iff_append]
simp only [Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, mem_range'_1,
and_congr_right_iff]
simp only [range'_eq_append_iff, eq_comm (a := i :: _), range'_eq_cons_iff]
@ -282,7 +282,7 @@ theorem find?_iota_eq_none {n : Nat} {p : Nat → Bool} :
@[simp] theorem find?_iota_eq_some {n : Nat} {i : Nat} {p : Nat → Bool} :
(iota n).find? p = some i ↔ p i ∧ i ∈ iota n ∧ ∀ j, i < j → j ≤ n → !p j := by
rw [find?_eq_some]
rw [find?_eq_some_iff_append]
simp only [iota_eq_reverse_range', reverse_eq_append_iff, reverse_cons, append_assoc, cons_append,
nil_append, Bool.not_eq_eq_eq_not, Bool.not_true, exists_and_right, mem_reverse, mem_range'_1,
and_congr_right_iff]