Skip to content

Commit

Permalink
feat: lemmas about Array.filter and Array.filterMap (#387)
Browse files Browse the repository at this point in the history
Co-authored-by: François G. Dorais <fgdorais@gmail.com>
  • Loading branch information
kim-em and fgdorais authored Dec 9, 2023
1 parent b197bd2 commit d62205c
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Std/Data/Array/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ attribute [simp] isEmpty uget
@[simp] theorem toArray_data : (a : Array α) → a.data.toArray = a
| ⟨l⟩ => ext' (data_toArray l)

@[simp] theorem data_length {l : Array α} : l.data.length = l.size := rfl

theorem mem_data {a : α} {l : Array α} : a ∈ l.data ↔ a ∈ l := (mem_def _ _).symm

theorem not_mem_nil (a : α) : ¬ a ∈ #[] := fun.
Expand Down Expand Up @@ -359,6 +361,59 @@ theorem forIn_eq_data_forIn [Monad m]
rw [loop (i := i)]; rw [← ij, Nat.succ_add]; rfl
simp [forIn, Array.forIn]; rw [loop (Nat.zero_add _)]; rfl

/-! ### map -/

@[simp] theorem mem_map {f : α → β} {l : Array α} : b ∈ l.map f ↔ ∃ a, a ∈ l ∧ f a = b := by
simp only [mem_def, map_data, List.mem_map]

/-! ### filter -/

@[simp] theorem filter_data (p : α → Bool) (l : Array α) :
(l.filter p).data = l.data.filter p := by
dsimp only [filter]
rw [foldl_eq_foldl_data]
generalize l.data = l
suffices ∀ a, (List.foldl (fun r a => if p a = true then push r a else r) a l).data =
a.data ++ List.filter p l by
simpa using this #[]
induction l with simp
| cons => split <;> simp [*]

@[simp] theorem filter_filter (q) (l : Array α) :
filter p (filter q l) = filter (fun a => p a ∧ q a) l := by
apply ext'
simp only [filter_data, List.filter_filter]

theorem size_filter_le (p : α → Bool) (l : Array α) :
(l.filter p).size ≤ l.size := by
simp only [← data_length, filter_data]
apply List.length_filter_le

@[simp] theorem mem_filter : x ∈ filter p as ↔ x ∈ as ∧ p x := by
simp only [mem_def, filter_data, List.mem_filter]

theorem mem_of_mem_filter {a : α} {l} (h : a ∈ filter p l) : a ∈ l :=
(mem_filter.mp h).1

/-! ### filterMap -/

@[simp] theorem filterMap_data (f : α → Option β) (l : Array α) :
(l.filterMap f).data = l.data.filterMap f := by
dsimp only [filterMap, filterMapM]
rw [foldlM_eq_foldlM_data]
generalize l.data = l
have this : ∀ a : Array β, (Id.run (List.foldlM (m := Id) ?_ a l)).data =
a.data ++ List.filterMap f l := ?_
exact this #[]
induction l
· simp_all [Id.run]
· simp_all [Id.run]
split <;> simp_all

@[simp] theorem mem_filterMap (f : α → Option β) (l : Array α) {b : β} :
b ∈ filterMap f l ↔ ∃ a, a ∈ l ∧ f a = some b := by
simp only [mem_def, filterMap_data, List.mem_filterMap]

/-! ### join -/

@[simp] theorem join_data {l : Array (Array α)} : l.join.data = (l.data.map data).join := by
Expand Down
4 changes: 4 additions & 0 deletions Std/Data/List/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,10 @@ end erase
@[simp] theorem filter_cons_of_neg {p : α → Bool} {a : α} (l) (pa : ¬ p a) :
filter p (a :: l) = filter p l := by rw [filter, eq_false_of_ne_true pa]

theorem filter_cons :
(x :: xs : List α).filter p = if p x then x :: (xs.filter p) else xs.filter p := by
split <;> simp [*]

@[simp] theorem filter_append {p : α → Bool} :
∀ (l₁ l₂ : List α), filter p (l₁ ++ l₂) = filter p l₁ ++ filter p l₂
| [], l₂ => rfl
Expand Down

0 comments on commit d62205c

Please sign in to comment.