mirror of
https://github.com/leanprover/lean4.git
synced 2026-04-11 22:54:17 +00:00
Compare commits
1 Commits
array_repl
...
flatMap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6639a043f1 |
@@ -607,13 +607,17 @@ protected def appendList (as : Array α) (bs : List α) : Array α :=
|
|||||||
instance : HAppend (Array α) (List α) (Array α) := ⟨Array.appendList⟩
|
instance : HAppend (Array α) (List α) (Array α) := ⟨Array.appendList⟩
|
||||||
|
|
||||||
@[inline]
|
@[inline]
|
||||||
def concatMapM [Monad m] (f : α → m (Array β)) (as : Array α) : m (Array β) :=
|
def flatMapM [Monad m] (f : α → m (Array β)) (as : Array α) : m (Array β) :=
|
||||||
as.foldlM (init := empty) fun bs a => do return bs ++ (← f a)
|
as.foldlM (init := empty) fun bs a => do return bs ++ (← f a)
|
||||||
|
|
||||||
|
@[deprecated concatMapM (since := "2024-10-16")] abbrev concatMapM := @flatMapM
|
||||||
|
|
||||||
@[inline]
|
@[inline]
|
||||||
def concatMap (f : α → Array β) (as : Array α) : Array β :=
|
def flatMap (f : α → Array β) (as : Array α) : Array β :=
|
||||||
as.foldl (init := empty) fun bs a => bs ++ f a
|
as.foldl (init := empty) fun bs a => bs ++ f a
|
||||||
|
|
||||||
|
@[deprecated flatMap (since := "2024-10-16")] abbrev concatMap := @flatMap
|
||||||
|
|
||||||
/-- Joins array of array into a single array.
|
/-- Joins array of array into a single array.
|
||||||
|
|
||||||
`flatten #[#[a₁, a₂, ⋯], #[b₁, b₂, ⋯], ⋯]` = `#[a₁, a₂, ⋯, b₁, b₂, ⋯]`
|
`flatten #[#[a₁, a₂, ⋯], #[b₁, b₂, ⋯], ⋯]` = `#[a₁, a₂, ⋯, b₁, b₂, ⋯]`
|
||||||
|
|||||||
@@ -242,14 +242,17 @@ abbrev map_data := @toList_map
|
|||||||
cases arr
|
cases arr
|
||||||
simp
|
simp
|
||||||
|
|
||||||
theorem foldl_toList_eq_bind (l : List α) (acc : Array β)
|
theorem foldl_toList_eq_flatMap (l : List α) (acc : Array β)
|
||||||
(F : Array β → α → Array β) (G : α → List β)
|
(F : Array β → α → Array β) (G : α → List β)
|
||||||
(H : ∀ acc a, (F acc a).toList = acc.toList ++ G a) :
|
(H : ∀ acc a, (F acc a).toList = acc.toList ++ G a) :
|
||||||
(l.foldl F acc).toList = acc.toList ++ l.bind G := by
|
(l.foldl F acc).toList = acc.toList ++ l.flatMap G := by
|
||||||
induction l generalizing acc <;> simp [*, List.bind]
|
induction l generalizing acc <;> simp [*, List.flatMap]
|
||||||
|
|
||||||
@[deprecated foldl_toList_eq_bind (since := "2024-09-09")]
|
@[deprecated foldl_toList_eq_flatMap (since := "2024-10-16")]
|
||||||
abbrev foldl_data_eq_bind := @foldl_toList_eq_bind
|
abbrev foldl_toList_eq_bind := @foldl_toList_eq_flatMap
|
||||||
|
|
||||||
|
@[deprecated foldl_toList_eq_flatMap (since := "2024-10-16")]
|
||||||
|
abbrev foldl_data_eq_bind := @foldl_toList_eq_flatMap
|
||||||
|
|
||||||
theorem foldl_toList_eq_map (l : List α) (acc : Array β) (G : α → β) :
|
theorem foldl_toList_eq_map (l : List α) (acc : Array β) (G : α → β) :
|
||||||
(l.foldl (fun acc a => acc.push (G a)) acc).toList = acc.toList ++ l.map G := by
|
(l.foldl (fun acc a => acc.push (G a)) acc).toList = acc.toList ++ l.map G := by
|
||||||
|
|||||||
@@ -639,14 +639,16 @@ and simplifies these to the function directly taking the value.
|
|||||||
| nil => simp
|
| nil => simp
|
||||||
| cons a l ih => simp [ih, hf, filterMap_cons]
|
| cons a l ih => simp [ih, hf, filterMap_cons]
|
||||||
|
|
||||||
@[simp] theorem bind_subtype {p : α → Prop} {l : List { x // p x }}
|
@[simp] theorem flatMap_subtype {p : α → Prop} {l : List { x // p x }}
|
||||||
{f : { x // p x } → List β} {g : α → List β} {hf : ∀ x h, f ⟨x, h⟩ = g x} :
|
{f : { x // p x } → List β} {g : α → List β} {hf : ∀ x h, f ⟨x, h⟩ = g x} :
|
||||||
(l.bind f) = l.unattach.bind g := by
|
(l.flatMap f) = l.unattach.flatMap g := by
|
||||||
unfold unattach
|
unfold unattach
|
||||||
induction l with
|
induction l with
|
||||||
| nil => simp
|
| nil => simp
|
||||||
| cons a l ih => simp [ih, hf]
|
| cons a l ih => simp [ih, hf]
|
||||||
|
|
||||||
|
@[deprecated flatMap_subtype (since := "2024-10-16")] abbrev bind_subtype := @flatMap_subtype
|
||||||
|
|
||||||
@[simp] theorem unattach_filter {p : α → Prop} {l : List { x // p x }}
|
@[simp] theorem unattach_filter {p : α → Prop} {l : List { x // p x }}
|
||||||
{f : { x // p x } → Bool} {g : α → Bool} {hf : ∀ x h, f ⟨x, h⟩ = g x} :
|
{f : { x // p x } → Bool} {g : α → Bool} {hf : ∀ x h, f ⟨x, h⟩ = g x} :
|
||||||
(l.filter f).unattach = l.unattach.filter g := by
|
(l.filter f).unattach = l.unattach.filter g := by
|
||||||
|
|||||||
@@ -563,23 +563,30 @@ def flatten : List (List α) → List α
|
|||||||
/-- `pure x = [x]` is the `pure` operation of the list monad. -/
|
/-- `pure x = [x]` is the `pure` operation of the list monad. -/
|
||||||
@[inline] protected def pure {α : Type u} (a : α) : List α := [a]
|
@[inline] protected def pure {α : Type u} (a : α) : List α := [a]
|
||||||
|
|
||||||
/-! ### bind -/
|
/-! ### flatMap -/
|
||||||
|
|
||||||
/--
|
/--
|
||||||
`bind xs f` is the bind operation of the list monad. It applies `f` to each element of `xs`
|
`flatMap xs f` applies `f` to each element of `xs`
|
||||||
to get a list of lists, and then concatenates them all together.
|
to get a list of lists, and then concatenates them all together.
|
||||||
* `[2, 3, 2].bind range = [0, 1, 0, 1, 2, 0, 1]`
|
* `[2, 3, 2].bind range = [0, 1, 0, 1, 2, 0, 1]`
|
||||||
-/
|
-/
|
||||||
@[inline] protected def bind {α : Type u} {β : Type v} (a : List α) (b : α → List β) : List β := flatten (map b a)
|
@[inline] def flatMap {α : Type u} {β : Type v} (a : List α) (b : α → List β) : List β := flatten (map b a)
|
||||||
|
|
||||||
@[simp] theorem bind_nil (f : α → List β) : List.bind [] f = [] := by simp [flatten, List.bind]
|
@[simp] theorem flatMap_nil (f : α → List β) : List.flatMap [] f = [] := by simp [flatten, List.flatMap]
|
||||||
@[simp] theorem bind_cons x xs (f : α → List β) :
|
@[simp] theorem flatMap_cons x xs (f : α → List β) :
|
||||||
List.bind (x :: xs) f = f x ++ List.bind xs f := by simp [flatten, List.bind]
|
List.flatMap (x :: xs) f = f x ++ List.flatMap xs f := by simp [flatten, List.flatMap]
|
||||||
|
|
||||||
set_option linter.missingDocs false in
|
set_option linter.missingDocs false in
|
||||||
@[deprecated bind_nil (since := "2024-06-15")] abbrev nil_bind := @bind_nil
|
@[deprecated flatMap (since := "2024-10-16")] abbrev bind := @flatMap
|
||||||
set_option linter.missingDocs false in
|
set_option linter.missingDocs false in
|
||||||
@[deprecated bind_cons (since := "2024-06-15")] abbrev cons_bind := @bind_cons
|
@[deprecated flatMap_nil (since := "2024-10-16")] abbrev nil_flatMap := @flatMap_nil
|
||||||
|
set_option linter.missingDocs false in
|
||||||
|
@[deprecated flatMap_cons (since := "2024-10-16")] abbrev cons_flatMap := @flatMap_cons
|
||||||
|
|
||||||
|
set_option linter.missingDocs false in
|
||||||
|
@[deprecated flatMap_nil (since := "2024-06-15")] abbrev nil_bind := @flatMap_nil
|
||||||
|
set_option linter.missingDocs false in
|
||||||
|
@[deprecated flatMap_cons (since := "2024-06-15")] abbrev cons_bind := @flatMap_cons
|
||||||
|
|
||||||
/-! ### replicate -/
|
/-! ### replicate -/
|
||||||
|
|
||||||
|
|||||||
@@ -378,14 +378,18 @@ theorem find?_flatten_eq_some {xs : List (List α)} {p : α → Bool} {a : α} :
|
|||||||
· exact h₁ l ml a m
|
· exact h₁ l ml a m
|
||||||
· exact h₂ a m
|
· exact h₂ a m
|
||||||
|
|
||||||
@[simp] theorem find?_bind (xs : List α) (f : α → List β) (p : β → Bool) :
|
@[simp] theorem find?_flatMap (xs : List α) (f : α → List β) (p : β → Bool) :
|
||||||
(xs.bind f).find? p = xs.findSome? (fun x => (f x).find? p) := by
|
(xs.flatMap f).find? p = xs.findSome? (fun x => (f x).find? p) := by
|
||||||
simp [bind_def, findSome?_map]; rfl
|
simp [flatMap_def, findSome?_map]; rfl
|
||||||
|
|
||||||
theorem find?_bind_eq_none {xs : List α} {f : α → List β} {p : β → Bool} :
|
@[deprecated find?_flatMap (since := "2024-10-16")] abbrev find?_bind := @find?_flatMap
|
||||||
(xs.bind f).find? p = none ↔ ∀ x ∈ xs, ∀ y ∈ f x, !p y := by
|
|
||||||
|
theorem find?_flatMap_eq_none {xs : List α} {f : α → List β} {p : β → Bool} :
|
||||||
|
(xs.flatMap f).find? p = none ↔ ∀ x ∈ xs, ∀ y ∈ f x, !p y := by
|
||||||
simp
|
simp
|
||||||
|
|
||||||
|
@[deprecated find?_flatMap_eq_none (since := "2024-10-16")] abbrev find?_bind_eq_none := @find?_flatMap_eq_none
|
||||||
|
|
||||||
theorem find?_replicate : find? p (replicate n a) = if n = 0 then none else if p a then some a else none := by
|
theorem find?_replicate : find? p (replicate n a) = if n = 0 then none else if p a then some a else none := by
|
||||||
cases n
|
cases n
|
||||||
· simp
|
· simp
|
||||||
|
|||||||
@@ -93,29 +93,29 @@ The following operations are given `@[csimp]` replacements below:
|
|||||||
@[csimp] theorem foldr_eq_foldrTR : @foldr = @foldrTR := by
|
@[csimp] theorem foldr_eq_foldrTR : @foldr = @foldrTR := by
|
||||||
funext α β f init l; simp [foldrTR, Array.foldr_eq_foldr_toList, -Array.size_toArray]
|
funext α β f init l; simp [foldrTR, Array.foldr_eq_foldr_toList, -Array.size_toArray]
|
||||||
|
|
||||||
/-! ### bind -/
|
/-! ### flatMap -/
|
||||||
|
|
||||||
/-- Tail recursive version of `List.bind`. -/
|
/-- Tail recursive version of `List.flatMap`. -/
|
||||||
@[inline] def bindTR (as : List α) (f : α → List β) : List β := go as #[] where
|
@[inline] def flatMapTR (as : List α) (f : α → List β) : List β := go as #[] where
|
||||||
/-- Auxiliary for `bind`: `bind.go f as = acc.toList ++ bind f as` -/
|
/-- Auxiliary for `flatMap`: `flatMap.go f as = acc.toList ++ bind f as` -/
|
||||||
@[specialize] go : List α → Array β → List β
|
@[specialize] go : List α → Array β → List β
|
||||||
| [], acc => acc.toList
|
| [], acc => acc.toList
|
||||||
| x::xs, acc => go xs (acc ++ f x)
|
| x::xs, acc => go xs (acc ++ f x)
|
||||||
|
|
||||||
@[csimp] theorem bind_eq_bindTR : @List.bind = @bindTR := by
|
@[csimp] theorem flatMap_eq_flatMapTR : @List.flatMap = @flatMapTR := by
|
||||||
funext α β as f
|
funext α β as f
|
||||||
let rec go : ∀ as acc, bindTR.go f as acc = acc.toList ++ as.bind f
|
let rec go : ∀ as acc, flatMapTR.go f as acc = acc.toList ++ as.flatMap f
|
||||||
| [], acc => by simp [bindTR.go, bind]
|
| [], acc => by simp [flatMapTR.go, flatMap]
|
||||||
| x::xs, acc => by simp [bindTR.go, bind, go xs]
|
| x::xs, acc => by simp [flatMapTR.go, flatMap, go xs]
|
||||||
exact (go as #[]).symm
|
exact (go as #[]).symm
|
||||||
|
|
||||||
/-! ### flatten -/
|
/-! ### flatten -/
|
||||||
|
|
||||||
/-- Tail recursive version of `List.flatten`. -/
|
/-- Tail recursive version of `List.flatten`. -/
|
||||||
@[inline] def flattenTR (l : List (List α)) : List α := bindTR l id
|
@[inline] def flattenTR (l : List (List α)) : List α := flatMapTR l id
|
||||||
|
|
||||||
@[csimp] theorem flatten_eq_flattenTR : @flatten = @flattenTR := by
|
@[csimp] theorem flatten_eq_flattenTR : @flatten = @flattenTR := by
|
||||||
funext α l; rw [← List.bind_id, List.bind_eq_bindTR]; rfl
|
funext α l; rw [← List.flatMap_id, List.flatMap_eq_flatMapTR]; rfl
|
||||||
|
|
||||||
/-! ## Sublists -/
|
/-! ## Sublists -/
|
||||||
|
|
||||||
|
|||||||
@@ -2098,8 +2098,8 @@ theorem forall_mem_flatten {p : α → Prop} {L : List (List α)} :
|
|||||||
simp only [mem_flatten, forall_exists_index, and_imp]
|
simp only [mem_flatten, forall_exists_index, and_imp]
|
||||||
constructor <;> (intros; solve_by_elim)
|
constructor <;> (intros; solve_by_elim)
|
||||||
|
|
||||||
theorem flatten_eq_bind {L : List (List α)} : flatten L = L.bind id := by
|
theorem flatten_eq_flatMap {L : List (List α)} : flatten L = L.flatMap id := by
|
||||||
induction L <;> simp [List.bind]
|
induction L <;> simp [List.flatMap]
|
||||||
|
|
||||||
theorem head?_flatten {L : List (List α)} : (flatten L).head? = L.findSome? fun l => l.head? := by
|
theorem head?_flatten {L : List (List α)} : (flatten L).head? = L.findSome? fun l => l.head? := by
|
||||||
induction L with
|
induction L with
|
||||||
@@ -2216,86 +2216,86 @@ theorem eq_iff_flatten_eq : ∀ {L L' : List (List α)},
|
|||||||
obtain ⟨rfl, h⟩ := append_inj h₁ h₂
|
obtain ⟨rfl, h⟩ := append_inj h₁ h₂
|
||||||
exact ⟨rfl, h, h₃⟩
|
exact ⟨rfl, h, h₃⟩
|
||||||
|
|
||||||
/-! ### bind -/
|
/-! ### flatMap -/
|
||||||
|
|
||||||
theorem bind_def (l : List α) (f : α → List β) : l.bind f = flatten (map f l) := by rfl
|
theorem flatMap_def (l : List α) (f : α → List β) : l.flatMap f = flatten (map f l) := by rfl
|
||||||
|
|
||||||
@[simp] theorem bind_id (l : List (List α)) : List.bind l id = l.flatten := by simp [bind_def]
|
@[simp] theorem flatMap_id (l : List (List α)) : List.flatMap l id = l.flatten := by simp [flatMap_def]
|
||||||
|
|
||||||
@[simp] theorem mem_bind {f : α → List β} {b} {l : List α} : b ∈ l.bind f ↔ ∃ a, a ∈ l ∧ b ∈ f a := by
|
@[simp] theorem mem_flatMap {f : α → List β} {b} {l : List α} : b ∈ l.flatMap f ↔ ∃ a, a ∈ l ∧ b ∈ f a := by
|
||||||
simp [bind_def, mem_flatten]
|
simp [flatMap_def, mem_flatten]
|
||||||
exact ⟨fun ⟨_, ⟨a, h₁, rfl⟩, h₂⟩ => ⟨a, h₁, h₂⟩, fun ⟨a, h₁, h₂⟩ => ⟨_, ⟨a, h₁, rfl⟩, h₂⟩⟩
|
exact ⟨fun ⟨_, ⟨a, h₁, rfl⟩, h₂⟩ => ⟨a, h₁, h₂⟩, fun ⟨a, h₁, h₂⟩ => ⟨_, ⟨a, h₁, rfl⟩, h₂⟩⟩
|
||||||
|
|
||||||
theorem exists_of_mem_bind {b : β} {l : List α} {f : α → List β} :
|
theorem exists_of_mem_flatMap {b : β} {l : List α} {f : α → List β} :
|
||||||
b ∈ l.bind f → ∃ a, a ∈ l ∧ b ∈ f a := mem_bind.1
|
b ∈ l.flatMap f → ∃ a, a ∈ l ∧ b ∈ f a := mem_flatMap.1
|
||||||
|
|
||||||
theorem mem_bind_of_mem {b : β} {l : List α} {f : α → List β} {a} (al : a ∈ l) (h : b ∈ f a) :
|
theorem mem_flatMap_of_mem {b : β} {l : List α} {f : α → List β} {a} (al : a ∈ l) (h : b ∈ f a) :
|
||||||
b ∈ l.bind f := mem_bind.2 ⟨a, al, h⟩
|
b ∈ l.flatMap f := mem_flatMap.2 ⟨a, al, h⟩
|
||||||
|
|
||||||
@[simp]
|
@[simp]
|
||||||
theorem bind_eq_nil_iff {l : List α} {f : α → List β} : List.bind l f = [] ↔ ∀ x ∈ l, f x = [] :=
|
theorem flatMap_eq_nil_iff {l : List α} {f : α → List β} : List.flatMap l f = [] ↔ ∀ x ∈ l, f x = [] :=
|
||||||
flatten_eq_nil_iff.trans <| by
|
flatten_eq_nil_iff.trans <| by
|
||||||
simp only [mem_map, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂]
|
simp only [mem_map, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂]
|
||||||
|
|
||||||
@[deprecated bind_eq_nil_iff (since := "2024-09-05")] abbrev bind_eq_nil := @bind_eq_nil_iff
|
@[deprecated flatMap_eq_nil_iff (since := "2024-09-05")] abbrev bind_eq_nil := @flatMap_eq_nil_iff
|
||||||
|
|
||||||
theorem forall_mem_bind {p : β → Prop} {l : List α} {f : α → List β} :
|
theorem forall_mem_flatMap {p : β → Prop} {l : List α} {f : α → List β} :
|
||||||
(∀ (x) (_ : x ∈ l.bind f), p x) ↔ ∀ (a) (_ : a ∈ l) (b) (_ : b ∈ f a), p b := by
|
(∀ (x) (_ : x ∈ l.flatMap f), p x) ↔ ∀ (a) (_ : a ∈ l) (b) (_ : b ∈ f a), p b := by
|
||||||
simp only [mem_bind, forall_exists_index, and_imp]
|
simp only [mem_flatMap, forall_exists_index, and_imp]
|
||||||
constructor <;> (intros; solve_by_elim)
|
constructor <;> (intros; solve_by_elim)
|
||||||
|
|
||||||
theorem bind_singleton (f : α → List β) (x : α) : [x].bind f = f x :=
|
theorem flatMap_singleton (f : α → List β) (x : α) : [x].flatMap f = f x :=
|
||||||
append_nil (f x)
|
append_nil (f x)
|
||||||
|
|
||||||
@[simp] theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l := by
|
@[simp] theorem flatMap_singleton' (l : List α) : (l.flatMap fun x => [x]) = l := by
|
||||||
induction l <;> simp [*]
|
induction l <;> simp [*]
|
||||||
|
|
||||||
theorem head?_bind {l : List α} {f : α → List β} :
|
theorem head?_flatMap {l : List α} {f : α → List β} :
|
||||||
(l.bind f).head? = l.findSome? fun a => (f a).head? := by
|
(l.flatMap f).head? = l.findSome? fun a => (f a).head? := by
|
||||||
induction l with
|
induction l with
|
||||||
| nil => rfl
|
| nil => rfl
|
||||||
| cons =>
|
| cons =>
|
||||||
simp only [findSome?_cons]
|
simp only [findSome?_cons]
|
||||||
split <;> simp_all
|
split <;> simp_all
|
||||||
|
|
||||||
@[simp] theorem bind_append (xs ys : List α) (f : α → List β) :
|
@[simp] theorem flatMap_append (xs ys : List α) (f : α → List β) :
|
||||||
(xs ++ ys).bind f = xs.bind f ++ ys.bind f := by
|
(xs ++ ys).flatMap f = xs.flatMap f ++ ys.flatMap f := by
|
||||||
induction xs; {rfl}; simp_all [bind_cons, append_assoc]
|
induction xs; {rfl}; simp_all [flatMap_cons, append_assoc]
|
||||||
|
|
||||||
@[deprecated bind_append (since := "2024-07-24")] abbrev append_bind := @bind_append
|
@[deprecated flatMap_append (since := "2024-07-24")] abbrev append_bind := @flatMap_append
|
||||||
|
|
||||||
theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
|
theorem flatMap_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
|
||||||
(l.bind f).bind g = l.bind fun x => (f x).bind g := by
|
(l.flatMap f).flatMap g = l.flatMap fun x => (f x).flatMap g := by
|
||||||
induction l <;> simp [*]
|
induction l <;> simp [*]
|
||||||
|
|
||||||
theorem map_bind (f : β → γ) (g : α → List β) :
|
theorem map_flatMap (f : β → γ) (g : α → List β) :
|
||||||
∀ l : List α, (l.bind g).map f = l.bind fun a => (g a).map f
|
∀ l : List α, (l.flatMap g).map f = l.flatMap fun a => (g a).map f
|
||||||
| [] => rfl
|
| [] => rfl
|
||||||
| a::l => by simp only [bind_cons, map_append, map_bind _ _ l]
|
| a::l => by simp only [flatMap_cons, map_append, map_flatMap _ _ l]
|
||||||
|
|
||||||
theorem bind_map (f : α → β) (g : β → List γ) (l : List α) :
|
theorem flatMap_map (f : α → β) (g : β → List γ) (l : List α) :
|
||||||
(map f l).bind g = l.bind (fun a => g (f a)) := by
|
(map f l).flatMap g = l.flatMap (fun a => g (f a)) := by
|
||||||
induction l <;> simp [bind_cons, *]
|
induction l <;> simp [flatMap_cons, *]
|
||||||
|
|
||||||
theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by
|
theorem map_eq_flatMap {α β} (f : α → β) (l : List α) : map f l = l.flatMap fun x => [f x] := by
|
||||||
simp only [← map_singleton]
|
simp only [← map_singleton]
|
||||||
rw [← bind_singleton' l, map_bind, bind_singleton']
|
rw [← flatMap_singleton' l, map_flatMap, flatMap_singleton']
|
||||||
|
|
||||||
theorem filterMap_bind {β γ} (l : List α) (g : α → List β) (f : β → Option γ) :
|
theorem filterMap_flatMap {β γ} (l : List α) (g : α → List β) (f : β → Option γ) :
|
||||||
(l.bind g).filterMap f = l.bind fun a => (g a).filterMap f := by
|
(l.flatMap g).filterMap f = l.flatMap fun a => (g a).filterMap f := by
|
||||||
induction l <;> simp [*]
|
induction l <;> simp [*]
|
||||||
|
|
||||||
theorem filter_bind (l : List α) (g : α → List β) (f : β → Bool) :
|
theorem filter_flatMap (l : List α) (g : α → List β) (f : β → Bool) :
|
||||||
(l.bind g).filter f = l.bind fun a => (g a).filter f := by
|
(l.flatMap g).filter f = l.flatMap fun a => (g a).filter f := by
|
||||||
induction l <;> simp [*]
|
induction l <;> simp [*]
|
||||||
|
|
||||||
theorem bind_eq_foldl (f : α → List β) (l : List α) :
|
theorem flatMap_eq_foldl (f : α → List β) (l : List α) :
|
||||||
l.bind f = l.foldl (fun acc a => acc ++ f a) [] := by
|
l.flatMap f = l.foldl (fun acc a => acc ++ f a) [] := by
|
||||||
suffices ∀ l', l' ++ l.bind f = l.foldl (fun acc a => acc ++ f a) l' by simpa using this []
|
suffices ∀ l', l' ++ l.flatMap f = l.foldl (fun acc a => acc ++ f a) l' by simpa using this []
|
||||||
intro l'
|
intro l'
|
||||||
induction l generalizing l'
|
induction l generalizing l'
|
||||||
· simp
|
· simp
|
||||||
· next ih => rw [bind_cons, ← append_assoc, ih, foldl_cons]
|
· next ih => rw [flatMap_cons, ← append_assoc, ih, foldl_cons]
|
||||||
|
|
||||||
/-! ### replicate -/
|
/-! ### replicate -/
|
||||||
|
|
||||||
@@ -2485,10 +2485,10 @@ theorem filterMap_replicate_of_some {f : α → Option β} (h : f a = some b) :
|
|||||||
simp only [replicate_succ, flatten_cons, ih, append_replicate_replicate, replicate_inj, or_true,
|
simp only [replicate_succ, flatten_cons, ih, append_replicate_replicate, replicate_inj, or_true,
|
||||||
and_true, add_one_mul, Nat.add_comm]
|
and_true, add_one_mul, Nat.add_comm]
|
||||||
|
|
||||||
theorem bind_replicate {β} (f : α → List β) : (replicate n a).bind f = (replicate n (f a)).flatten := by
|
theorem flatMap_replicate {β} (f : α → List β) : (replicate n a).flatMap f = (replicate n (f a)).flatten := by
|
||||||
induction n with
|
induction n with
|
||||||
| zero => simp
|
| zero => simp
|
||||||
| succ n ih => simp only [replicate_succ, bind_cons, ih, flatten_cons]
|
| succ n ih => simp only [replicate_succ, flatMap_cons, ih, flatten_cons]
|
||||||
|
|
||||||
@[simp] theorem isEmpty_replicate : (replicate n a).isEmpty = decide (n = 0) := by
|
@[simp] theorem isEmpty_replicate : (replicate n a).isEmpty = decide (n = 0) := by
|
||||||
cases n <;> simp [replicate_succ]
|
cases n <;> simp [replicate_succ]
|
||||||
@@ -2673,10 +2673,10 @@ theorem flatten_reverse (L : List (List α)) :
|
|||||||
L.reverse.flatten = (L.map reverse).flatten.reverse := by
|
L.reverse.flatten = (L.map reverse).flatten.reverse := by
|
||||||
induction L <;> simp_all
|
induction L <;> simp_all
|
||||||
|
|
||||||
theorem reverse_bind {β} (l : List α) (f : α → List β) : (l.bind f).reverse = l.reverse.bind (reverse ∘ f) := by
|
theorem reverse_flatMap {β} (l : List α) (f : α → List β) : (l.flatMap f).reverse = l.reverse.flatMap (reverse ∘ f) := by
|
||||||
induction l <;> simp_all
|
induction l <;> simp_all
|
||||||
|
|
||||||
theorem bind_reverse {β} (l : List α) (f : α → List β) : (l.reverse.bind f) = (l.bind (reverse ∘ f)).reverse := by
|
theorem flatMap_reverse {β} (l : List α) (f : α → List β) : (l.reverse.flatMap f) = (l.flatMap (reverse ∘ f)).reverse := by
|
||||||
induction l <;> simp_all
|
induction l <;> simp_all
|
||||||
|
|
||||||
@[simp] theorem reverseAux_eq (as bs : List α) : reverseAux as bs = reverse as ++ bs :=
|
@[simp] theorem reverseAux_eq (as bs : List α) : reverseAux as bs = reverse as ++ bs :=
|
||||||
@@ -2784,15 +2784,15 @@ theorem getLast_filterMap_of_eq_some {f : α → Option β} {l : List α} {w : l
|
|||||||
rw [head_filterMap_of_eq_some (by simp_all)]
|
rw [head_filterMap_of_eq_some (by simp_all)]
|
||||||
simp_all
|
simp_all
|
||||||
|
|
||||||
theorem getLast?_bind {L : List α} {f : α → List β} :
|
theorem getLast?_flatMap {L : List α} {f : α → List β} :
|
||||||
(L.bind f).getLast? = L.reverse.findSome? fun a => (f a).getLast? := by
|
(L.flatMap f).getLast? = L.reverse.findSome? fun a => (f a).getLast? := by
|
||||||
simp only [← head?_reverse, reverse_bind]
|
simp only [← head?_reverse, reverse_flatMap]
|
||||||
rw [head?_bind]
|
rw [head?_flatMap]
|
||||||
rfl
|
rfl
|
||||||
|
|
||||||
theorem getLast?_flatten {L : List (List α)} :
|
theorem getLast?_flatten {L : List (List α)} :
|
||||||
(flatten L).getLast? = L.reverse.findSome? fun l => l.getLast? := by
|
(flatten L).getLast? = L.reverse.findSome? fun l => l.getLast? := by
|
||||||
simp [← bind_id, getLast?_bind]
|
simp [← flatMap_id, getLast?_flatMap]
|
||||||
|
|
||||||
theorem getLast?_replicate (a : α) (n : Nat) : (replicate n a).getLast? = if n = 0 then none else some a := by
|
theorem getLast?_replicate (a : α) (n : Nat) : (replicate n a).getLast? = if n = 0 then none else some a := by
|
||||||
simp only [← head?_reverse, reverse_replicate, head?_replicate]
|
simp only [← head?_reverse, reverse_replicate, head?_replicate]
|
||||||
@@ -3301,12 +3301,12 @@ theorem all_eq_not_any_not (l : List α) (p : α → Bool) : l.all p = !l.any (!
|
|||||||
|
|
||||||
@[deprecated all_flatten (since := "2024-10-14")] abbrev all_join := @all_flatten
|
@[deprecated all_flatten (since := "2024-10-14")] abbrev all_join := @all_flatten
|
||||||
|
|
||||||
@[simp] theorem any_bind {l : List α} {f : α → List β} :
|
@[simp] theorem any_flatMap {l : List α} {f : α → List β} :
|
||||||
(l.bind f).any p = l.any fun a => (f a).any p := by
|
(l.flatMap f).any p = l.any fun a => (f a).any p := by
|
||||||
induction l <;> simp_all
|
induction l <;> simp_all
|
||||||
|
|
||||||
@[simp] theorem all_bind {l : List α} {f : α → List β} :
|
@[simp] theorem all_flatMap {l : List α} {f : α → List β} :
|
||||||
(l.bind f).all p = l.all fun a => (f a).all p := by
|
(l.flatMap f).all p = l.all fun a => (f a).all p := by
|
||||||
induction l <;> simp_all
|
induction l <;> simp_all
|
||||||
|
|
||||||
@[simp] theorem any_reverse {l : List α} : l.reverse.any f = l.any f := by
|
@[simp] theorem any_reverse {l : List α} : l.reverse.any f = l.any f := by
|
||||||
@@ -3346,7 +3346,7 @@ theorem all_eq_not_any_not (l : List α) (p : α → Bool) : l.all p = !l.any (!
|
|||||||
@[deprecated exists_of_mem_flatten (since := "2024-10-14")] abbrev exists_of_mem_join := @exists_of_mem_flatten
|
@[deprecated exists_of_mem_flatten (since := "2024-10-14")] abbrev exists_of_mem_join := @exists_of_mem_flatten
|
||||||
@[deprecated mem_flatten_of_mem (since := "2024-10-14")] abbrev mem_join_of_mem := @mem_flatten_of_mem
|
@[deprecated mem_flatten_of_mem (since := "2024-10-14")] abbrev mem_join_of_mem := @mem_flatten_of_mem
|
||||||
@[deprecated forall_mem_flatten (since := "2024-10-14")] abbrev forall_mem_join := @forall_mem_flatten
|
@[deprecated forall_mem_flatten (since := "2024-10-14")] abbrev forall_mem_join := @forall_mem_flatten
|
||||||
@[deprecated flatten_eq_bind (since := "2024-10-14")] abbrev join_eq_bind := @flatten_eq_bind
|
@[deprecated flatten_eq_flatMap (since := "2024-10-14")] abbrev join_eq_bind := @flatten_eq_flatMap
|
||||||
@[deprecated head?_flatten (since := "2024-10-14")] abbrev head?_join := @head?_flatten
|
@[deprecated head?_flatten (since := "2024-10-14")] abbrev head?_join := @head?_flatten
|
||||||
@[deprecated foldl_flatten (since := "2024-10-14")] abbrev foldl_join := @foldl_flatten
|
@[deprecated foldl_flatten (since := "2024-10-14")] abbrev foldl_join := @foldl_flatten
|
||||||
@[deprecated foldr_flatten (since := "2024-10-14")] abbrev foldr_join := @foldr_flatten
|
@[deprecated foldr_flatten (since := "2024-10-14")] abbrev foldr_join := @foldr_flatten
|
||||||
@@ -3373,5 +3373,30 @@ theorem join_map_filter (p : α → Bool) (l : List (List α)) :
|
|||||||
@[deprecated reverse_flatten (since := "2024-10-14")] abbrev reverse_join := @reverse_flatten
|
@[deprecated reverse_flatten (since := "2024-10-14")] abbrev reverse_join := @reverse_flatten
|
||||||
@[deprecated flatten_reverse (since := "2024-10-14")] abbrev join_reverse := @flatten_reverse
|
@[deprecated flatten_reverse (since := "2024-10-14")] abbrev join_reverse := @flatten_reverse
|
||||||
@[deprecated getLast?_flatten (since := "2024-10-14")] abbrev getLast?_join := @getLast?_flatten
|
@[deprecated getLast?_flatten (since := "2024-10-14")] abbrev getLast?_join := @getLast?_flatten
|
||||||
|
@[deprecated flatten_eq_flatMap (since := "2024-10-16")] abbrev flatten_eq_bind := @flatten_eq_flatMap
|
||||||
|
@[deprecated flatMap_def (since := "2024-10-16")] abbrev bind_def := @flatMap_def
|
||||||
|
@[deprecated flatMap_id (since := "2024-10-16")] abbrev bind_id := @flatMap_id
|
||||||
|
@[deprecated mem_flatMap (since := "2024-10-16")] abbrev mem_bind := @mem_flatMap
|
||||||
|
@[deprecated exists_of_mem_flatMap (since := "2024-10-16")] abbrev exists_of_mem_bind := @exists_of_mem_flatMap
|
||||||
|
@[deprecated mem_flatMap_of_mem (since := "2024-10-16")] abbrev mem_bind_of_mem := @mem_flatMap_of_mem
|
||||||
|
@[deprecated flatMap_eq_nil_iff (since := "2024-10-16")] abbrev bind_eq_nil_iff := @flatMap_eq_nil_iff
|
||||||
|
@[deprecated forall_mem_flatMap (since := "2024-10-16")] abbrev forall_mem_bind := @forall_mem_flatMap
|
||||||
|
@[deprecated flatMap_singleton (since := "2024-10-16")] abbrev bind_singleton := @flatMap_singleton
|
||||||
|
@[deprecated flatMap_singleton' (since := "2024-10-16")] abbrev bind_singleton' := @flatMap_singleton'
|
||||||
|
@[deprecated head?_flatMap (since := "2024-10-16")] abbrev head_bind := @head?_flatMap
|
||||||
|
@[deprecated flatMap_append (since := "2024-10-16")] abbrev bind_append := @flatMap_append
|
||||||
|
@[deprecated flatMap_assoc (since := "2024-10-16")] abbrev bind_assoc := @flatMap_assoc
|
||||||
|
@[deprecated map_flatMap (since := "2024-10-16")] abbrev map_bind := @map_flatMap
|
||||||
|
@[deprecated flatMap_map (since := "2024-10-16")] abbrev bind_map := @flatMap_map
|
||||||
|
@[deprecated map_eq_flatMap (since := "2024-10-16")] abbrev map_eq_bind := @map_eq_flatMap
|
||||||
|
@[deprecated filterMap_flatMap (since := "2024-10-16")] abbrev filterMap_bind := @filterMap_flatMap
|
||||||
|
@[deprecated filter_flatMap (since := "2024-10-16")] abbrev filter_bind := @filter_flatMap
|
||||||
|
@[deprecated flatMap_eq_foldl (since := "2024-10-16")] abbrev bind_eq_foldl := @flatMap_eq_foldl
|
||||||
|
@[deprecated flatMap_replicate (since := "2024-10-16")] abbrev bind_replicate := @flatMap_replicate
|
||||||
|
@[deprecated reverse_flatMap (since := "2024-10-16")] abbrev reverse_bind := @reverse_flatMap
|
||||||
|
@[deprecated flatMap_reverse (since := "2024-10-16")] abbrev bind_reverse := @flatMap_reverse
|
||||||
|
@[deprecated getLast?_flatMap (since := "2024-10-16")] abbrev getLast?_bind := @getLast?_flatMap
|
||||||
|
@[deprecated any_flatMap (since := "2024-10-16")] abbrev any_bind := @any_flatMap
|
||||||
|
@[deprecated all_flatMap (since := "2024-10-16")] abbrev all_bind := @all_flatMap
|
||||||
|
|
||||||
end List
|
end List
|
||||||
|
|||||||
@@ -173,10 +173,12 @@ theorem pairwise_flatten {L : List (List α)} :
|
|||||||
|
|
||||||
@[deprecated pairwise_flatten (since := "2024-10-14")] abbrev pairwise_join := @pairwise_flatten
|
@[deprecated pairwise_flatten (since := "2024-10-14")] abbrev pairwise_join := @pairwise_flatten
|
||||||
|
|
||||||
theorem pairwise_bind {R : β → β → Prop} {l : List α} {f : α → List β} :
|
theorem pairwise_flatMap {R : β → β → Prop} {l : List α} {f : α → List β} :
|
||||||
List.Pairwise R (l.bind f) ↔
|
List.Pairwise R (l.flatMap f) ↔
|
||||||
(∀ a ∈ l, Pairwise R (f a)) ∧ Pairwise (fun a₁ a₂ => ∀ x ∈ f a₁, ∀ y ∈ f a₂, R x y) l := by
|
(∀ a ∈ l, Pairwise R (f a)) ∧ Pairwise (fun a₁ a₂ => ∀ x ∈ f a₁, ∀ y ∈ f a₂, R x y) l := by
|
||||||
simp [List.bind, pairwise_flatten, pairwise_map]
|
simp [List.flatMap, pairwise_flatten, pairwise_map]
|
||||||
|
|
||||||
|
@[deprecated pairwise_flatMap (since := "2024-10-14")] abbrev pairwise_bind := @pairwise_flatMap
|
||||||
|
|
||||||
theorem pairwise_reverse {l : List α} :
|
theorem pairwise_reverse {l : List α} :
|
||||||
l.reverse.Pairwise R ↔ l.Pairwise (fun a b => R b a) := by
|
l.reverse.Pairwise R ↔ l.Pairwise (fun a b => R b a) := by
|
||||||
|
|||||||
@@ -470,9 +470,11 @@ theorem Perm.flatten {l₁ l₂ : List (List α)} (h : l₁ ~ l₂) : l₁.flatt
|
|||||||
|
|
||||||
@[deprecated Perm.flatten (since := "2024-10-14")] abbrev Perm.join := @Perm.flatten
|
@[deprecated Perm.flatten (since := "2024-10-14")] abbrev Perm.join := @Perm.flatten
|
||||||
|
|
||||||
theorem Perm.bind_right {l₁ l₂ : List α} (f : α → List β) (p : l₁ ~ l₂) : l₁.bind f ~ l₂.bind f :=
|
theorem Perm.flatMap_right {l₁ l₂ : List α} (f : α → List β) (p : l₁ ~ l₂) : l₁.flatMap f ~ l₂.flatMap f :=
|
||||||
(p.map _).flatten
|
(p.map _).flatten
|
||||||
|
|
||||||
|
@[deprecated Perm.flatMap_right (since := "2024-10-16")] abbrev Perm.bind_right := @Perm.flatMap_right
|
||||||
|
|
||||||
theorem Perm.eraseP (f : α → Bool) {l₁ l₂ : List α}
|
theorem Perm.eraseP (f : α → Bool) {l₁ l₂ : List α}
|
||||||
(H : Pairwise (fun a b => f a → f b → False) l₁) (p : l₁ ~ l₂) : eraseP f l₁ ~ eraseP f l₂ := by
|
(H : Pairwise (fun a b => f a → f b → False) l₁) (p : l₁ ~ l₂) : eraseP f l₁ ~ eraseP f l₂ := by
|
||||||
induction p with
|
induction p with
|
||||||
|
|||||||
@@ -117,10 +117,10 @@ def utf8EncodeChar (c : Char) : List UInt8 :=
|
|||||||
/-- Converts the given `String` to a [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoded byte array. -/
|
/-- Converts the given `String` to a [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoded byte array. -/
|
||||||
@[extern "lean_string_to_utf8"]
|
@[extern "lean_string_to_utf8"]
|
||||||
def toUTF8 (a : @& String) : ByteArray :=
|
def toUTF8 (a : @& String) : ByteArray :=
|
||||||
⟨⟨a.data.bind utf8EncodeChar⟩⟩
|
⟨⟨a.data.flatMap utf8EncodeChar⟩⟩
|
||||||
|
|
||||||
@[simp] theorem size_toUTF8 (s : String) : s.toUTF8.size = s.utf8ByteSize := by
|
@[simp] theorem size_toUTF8 (s : String) : s.toUTF8.size = s.utf8ByteSize := by
|
||||||
simp [toUTF8, ByteArray.size, Array.size, utf8ByteSize, List.bind]
|
simp [toUTF8, ByteArray.size, Array.size, utf8ByteSize, List.flatMap]
|
||||||
induction s.data <;> simp [List.map, List.flatten, utf8ByteSize.go, Nat.add_comm, *]
|
induction s.data <;> simp [List.map, List.flatten, utf8ByteSize.go, Nat.add_comm, *]
|
||||||
|
|
||||||
/-- Accesses a byte in the UTF-8 encoding of the `String`. O(1) -/
|
/-- Accesses a byte in the UTF-8 encoding of the `String`. O(1) -/
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ mutual
|
|||||||
|
|
||||||
let z ← optional (Content.Character <$> CharData)
|
let z ← optional (Content.Character <$> CharData)
|
||||||
pure #[y, z]
|
pure #[y, z]
|
||||||
let xs := #[x] ++ xs.concatMap id |>.filterMap id
|
let xs := #[x] ++ xs.flatMap id |>.filterMap id
|
||||||
let mut res := #[]
|
let mut res := #[]
|
||||||
for x in xs do
|
for x in xs do
|
||||||
if res.size > 0 then
|
if res.size > 0 then
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ private def replaceBinderAnnotation (binder : TSyntax ``Parser.Term.bracketedBin
|
|||||||
|
|
||||||
@[builtin_command_elab «variable»] def elabVariable : CommandElab
|
@[builtin_command_elab «variable»] def elabVariable : CommandElab
|
||||||
| `(variable $binders*) => do
|
| `(variable $binders*) => do
|
||||||
let binders ← binders.concatMapM replaceBinderAnnotation
|
let binders ← binders.flatMapM replaceBinderAnnotation
|
||||||
-- Try to elaborate `binders` for sanity checking
|
-- Try to elaborate `binders` for sanity checking
|
||||||
runTermElabM fun _ => Term.withSynthesize <| Term.withAutoBoundImplicit <|
|
runTermElabM fun _ => Term.withSynthesize <| Term.withAutoBoundImplicit <|
|
||||||
Term.elabBinders binders fun _ => pure ()
|
Term.elabBinders binders fun _ => pure ()
|
||||||
@@ -348,7 +348,7 @@ def failIfSucceeds (x : CommandElabM Unit) : CommandElabM Unit := do
|
|||||||
@[builtin_command_elab Lean.Parser.Command.include] def elabInclude : CommandElab
|
@[builtin_command_elab Lean.Parser.Command.include] def elabInclude : CommandElab
|
||||||
| `(Lean.Parser.Command.include| include $ids*) => do
|
| `(Lean.Parser.Command.include| include $ids*) => do
|
||||||
let sc ← getScope
|
let sc ← getScope
|
||||||
let vars ← sc.varDecls.concatMapM getBracketedBinderIds
|
let vars ← sc.varDecls.flatMapM getBracketedBinderIds
|
||||||
let mut uids := #[]
|
let mut uids := #[]
|
||||||
for id in ids do
|
for id in ids do
|
||||||
if let some idx := vars.findIdx? (· == id.getId) then
|
if let some idx := vars.findIdx? (· == id.getId) then
|
||||||
|
|||||||
@@ -571,7 +571,7 @@ def getBracketedBinderIds : Syntax → CommandElabM (Array Name)
|
|||||||
private def mkTermContext (ctx : Context) (s : State) : CommandElabM Term.Context := do
|
private def mkTermContext (ctx : Context) (s : State) : CommandElabM Term.Context := do
|
||||||
let scope := s.scopes.head!
|
let scope := s.scopes.head!
|
||||||
let mut sectionVars := {}
|
let mut sectionVars := {}
|
||||||
for id in (← scope.varDecls.concatMapM getBracketedBinderIds), uid in scope.varUIds do
|
for id in (← scope.varDecls.flatMapM getBracketedBinderIds), uid in scope.varUIds do
|
||||||
sectionVars := sectionVars.insert id uid
|
sectionVars := sectionVars.insert id uid
|
||||||
return {
|
return {
|
||||||
macroStack := ctx.macroStack
|
macroStack := ctx.macroStack
|
||||||
@@ -714,7 +714,7 @@ def expandDeclId (declId : Syntax) (modifiers : Modifiers) : CommandElabM Expand
|
|||||||
let currNamespace ← getCurrNamespace
|
let currNamespace ← getCurrNamespace
|
||||||
let currLevelNames ← getLevelNames
|
let currLevelNames ← getLevelNames
|
||||||
let r ← Elab.expandDeclId currNamespace currLevelNames declId modifiers
|
let r ← Elab.expandDeclId currNamespace currLevelNames declId modifiers
|
||||||
for id in (← (← getScope).varDecls.concatMapM getBracketedBinderIds) do
|
for id in (← (← getScope).varDecls.flatMapM getBracketedBinderIds) do
|
||||||
if id == r.shortName then
|
if id == r.shortName then
|
||||||
throwError "invalid declaration name '{r.shortName}', there is a section variable with the same name"
|
throwError "invalid declaration name '{r.shortName}', there is a section variable with the same name"
|
||||||
return r
|
return r
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ def runFrontend
|
|||||||
snaps.runAndReport opts jsonOutput
|
snaps.runAndReport opts jsonOutput
|
||||||
|
|
||||||
if let some ileanFileName := ileanFileName? then
|
if let some ileanFileName := ileanFileName? then
|
||||||
let trees := snaps.getAll.concatMap (match ·.infoTree? with | some t => #[t] | _ => #[])
|
let trees := snaps.getAll.flatMap (match ·.infoTree? with | some t => #[t] | _ => #[])
|
||||||
let references := Lean.Server.findModuleRefs inputCtx.fileMap trees (localVars := false)
|
let references := Lean.Server.findModuleRefs inputCtx.fileMap trees (localVars := false)
|
||||||
let ilean := { module := mainModuleName, references := ← references.toLspModuleRefs : Lean.Server.Ilean }
|
let ilean := { module := mainModuleName, references := ← references.toLspModuleRefs : Lean.Server.Ilean }
|
||||||
IO.FS.writeFile ileanFileName $ Json.compress $ toJson ilean
|
IO.FS.writeFile ileanFileName $ Json.compress $ toJson ilean
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ def allCombinations (xss : Array (Array α)) : Option (Array (Array α)) :=
|
|||||||
else
|
else
|
||||||
let rec go i acc : Array (Array α):=
|
let rec go i acc : Array (Array α):=
|
||||||
if h : i < xss.size then
|
if h : i < xss.size then
|
||||||
xss[i].concatMap fun x => go (i + 1) (acc.push x)
|
xss[i].flatMap fun x => go (i + 1) (acc.push x)
|
||||||
else
|
else
|
||||||
#[acc]
|
#[acc]
|
||||||
some (go 0 #[])
|
some (go 0 #[])
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ def handleCodeAction (params : CodeActionParams) : RequestM (RequestTask (Array
|
|||||||
let names := codeActionProviderExt.getState env |>.toArray
|
let names := codeActionProviderExt.getState env |>.toArray
|
||||||
let caps ← names.mapM evalCodeActionProvider
|
let caps ← names.mapM evalCodeActionProvider
|
||||||
return (← builtinCodeActionProviders.get).toList.toArray ++ Array.zip names caps
|
return (← builtinCodeActionProviders.get).toList.toArray ++ Array.zip names caps
|
||||||
caps.concatMapM fun (providerName, cap) => do
|
caps.flatMapM fun (providerName, cap) => do
|
||||||
let cas ← cap params snap
|
let cas ← cap params snap
|
||||||
cas.mapIdxM fun i lca => do
|
cas.mapIdxM fun i lca => do
|
||||||
if lca.lazy?.isNone then return lca.eager
|
if lca.lazy?.isNone then return lca.eager
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ A code action which calls all `@[hole_code_action]` code actions on each hole
|
|||||||
unless head ≤ endPos && startPos ≤ tail do return result
|
unless head ≤ endPos && startPos ≤ tail do return result
|
||||||
result.push (ctx, info)
|
result.push (ctx, info)
|
||||||
let #[(ctx, info)] := holes | return #[]
|
let #[(ctx, info)] := holes | return #[]
|
||||||
(holeCodeActionExt.getState snap.env).2.concatMapM (· params snap ctx info)
|
(holeCodeActionExt.getState snap.env).2.flatMapM (· params snap ctx info)
|
||||||
|
|
||||||
/--
|
/--
|
||||||
The return value of `findTactic?`.
|
The return value of `findTactic?`.
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ def InfoTree.smallestInfo? (p : Info → Bool) (t : InfoTree) : Option (ContextI
|
|||||||
/-- Find an info node, if any, which should be shown on hover/cursor at position `hoverPos`. -/
|
/-- Find an info node, if any, which should be shown on hover/cursor at position `hoverPos`. -/
|
||||||
partial def InfoTree.hoverableInfoAt? (t : InfoTree) (hoverPos : String.Pos) (includeStop := false) (omitAppFns := false) (omitIdentApps := false) : Option InfoWithCtx := Id.run do
|
partial def InfoTree.hoverableInfoAt? (t : InfoTree) (hoverPos : String.Pos) (includeStop := false) (omitAppFns := false) (omitIdentApps := false) : Option InfoWithCtx := Id.run do
|
||||||
let results := t.visitM (m := Id) (postNode := fun ctx info children results => do
|
let results := t.visitM (m := Id) (postNode := fun ctx info children results => do
|
||||||
let mut results := results.bind (·.getD [])
|
let mut results := results.flatMap (·.getD [])
|
||||||
if omitAppFns && info.stx.isOfKind ``Parser.Term.app && info.stx[0].isIdent then
|
if omitAppFns && info.stx.isOfKind ``Parser.Term.app && info.stx[0].isIdent then
|
||||||
results := results.filter (·.2.info.stx != info.stx[0])
|
results := results.filter (·.2.info.stx != info.stx[0])
|
||||||
if omitIdentApps && info.stx.isIdent then
|
if omitIdentApps && info.stx.isIdent then
|
||||||
|
|||||||
@@ -669,7 +669,7 @@ where
|
|||||||
let grouped := incomingCalls.groupByKey (·.«from»)
|
let grouped := incomingCalls.groupByKey (·.«from»)
|
||||||
let collapsed := grouped.toArray.map fun ⟨_, group⟩ => {
|
let collapsed := grouped.toArray.map fun ⟨_, group⟩ => {
|
||||||
«from» := group[0]!.«from»
|
«from» := group[0]!.«from»
|
||||||
fromRanges := group.concatMap (·.fromRanges)
|
fromRanges := group.flatMap (·.fromRanges)
|
||||||
}
|
}
|
||||||
collapsed
|
collapsed
|
||||||
|
|
||||||
@@ -716,7 +716,7 @@ where
|
|||||||
let grouped := outgoingCalls.groupByKey (·.to)
|
let grouped := outgoingCalls.groupByKey (·.to)
|
||||||
let collapsed := grouped.toArray.map fun ⟨_, group⟩ => {
|
let collapsed := grouped.toArray.map fun ⟨_, group⟩ => {
|
||||||
to := group[0]!.to
|
to := group[0]!.to
|
||||||
fromRanges := group.concatMap (·.fromRanges)
|
fromRanges := group.flatMap (·.fromRanges)
|
||||||
}
|
}
|
||||||
collapsed
|
collapsed
|
||||||
|
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ namespace DHashMap.Internal
|
|||||||
|
|
||||||
/-- Internal implementation detail of the hash map -/
|
/-- Internal implementation detail of the hash map -/
|
||||||
def toListModel (buckets : Array (AssocList α β)) : List ((a : α) × β a) :=
|
def toListModel (buckets : Array (AssocList α β)) : List ((a : α) × β a) :=
|
||||||
buckets.toList.bind AssocList.toList
|
buckets.toList.flatMap AssocList.toList
|
||||||
|
|
||||||
/-- Internal implementation detail of the hash map -/
|
/-- Internal implementation detail of the hash map -/
|
||||||
@[inline] def computeSize (buckets : Array (AssocList α β)) : Nat :=
|
@[inline] def computeSize (buckets : Array (AssocList α β)) : Nat :=
|
||||||
|
|||||||
@@ -1720,13 +1720,13 @@ theorem containsKey_append [BEq α] {l l' : List ((a : α) × β a)} {a : α} :
|
|||||||
containsKey a (l ++ l') = (containsKey a l || containsKey a l') := by
|
containsKey a (l ++ l') = (containsKey a l || containsKey a l') := by
|
||||||
simp [containsKey_eq_isSome_getEntry?]
|
simp [containsKey_eq_isSome_getEntry?]
|
||||||
|
|
||||||
theorem containsKey_bind_eq_false [BEq α] {γ : Type w} {l : List γ} {f : γ → List ((a : α) × β a)}
|
theorem containsKey_flatMap_eq_false [BEq α] {γ : Type w} {l : List γ} {f : γ → List ((a : α) × β a)}
|
||||||
{a : α} (h : ∀ (i : Nat) (h : i < l.length), containsKey a (f l[i]) = false) :
|
{a : α} (h : ∀ (i : Nat) (h : i < l.length), containsKey a (f l[i]) = false) :
|
||||||
containsKey a (l.bind f) = false := by
|
containsKey a (l.flatMap f) = false := by
|
||||||
induction l
|
induction l
|
||||||
· simp
|
· simp
|
||||||
· next g t ih =>
|
· next g t ih =>
|
||||||
simp only [List.bind_cons, containsKey_append, Bool.or_eq_false_iff]
|
simp only [List.flatMap_cons, containsKey_append, Bool.or_eq_false_iff]
|
||||||
refine ⟨?_, ?_⟩
|
refine ⟨?_, ?_⟩
|
||||||
· simpa using h 0 (by simp)
|
· simpa using h 0 (by simp)
|
||||||
· refine ih ?_
|
· refine ih ?_
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ theorem exists_bucket_of_uset [BEq α] [Hashable α]
|
|||||||
containsKey k l = false) := by
|
containsKey k l = false) := by
|
||||||
have h₀ : 0 < self.size := by omega
|
have h₀ : 0 < self.size := by omega
|
||||||
obtain ⟨l₁, l₂, h₁, h₂, h₃⟩ := Array.exists_of_uset self i d hi
|
obtain ⟨l₁, l₂, h₁, h₂, h₃⟩ := Array.exists_of_uset self i d hi
|
||||||
refine ⟨l₁.bind AssocList.toList ++ l₂.bind AssocList.toList, ?_, ?_, ?_⟩
|
refine ⟨l₁.flatMap AssocList.toList ++ l₂.flatMap AssocList.toList, ?_, ?_, ?_⟩
|
||||||
· rw [toListModel, h₁]
|
· rw [toListModel, h₁]
|
||||||
simpa using perm_append_comm_assoc _ _ _
|
simpa using perm_append_comm_assoc _ _ _
|
||||||
· rw [toListModel, h₃]
|
· rw [toListModel, h₃]
|
||||||
@@ -96,12 +96,12 @@ theorem exists_bucket_of_uset [BEq α] [Hashable α]
|
|||||||
· intro _ h k hki
|
· intro _ h k hki
|
||||||
simp only [containsKey_append, Bool.or_eq_false_iff]
|
simp only [containsKey_append, Bool.or_eq_false_iff]
|
||||||
refine ⟨?_, ?_⟩
|
refine ⟨?_, ?_⟩
|
||||||
· apply List.containsKey_bind_eq_false
|
· apply List.containsKey_flatMap_eq_false
|
||||||
intro j hj
|
intro j hj
|
||||||
rw [List.getElem_append_left' (l₂ := self[i] :: l₂), getElem_congr_coll h₁.symm]
|
rw [List.getElem_append_left' (l₂ := self[i] :: l₂), getElem_congr_coll h₁.symm]
|
||||||
apply (h.hashes_to j _).containsKey_eq_false h₀ k
|
apply (h.hashes_to j _).containsKey_eq_false h₀ k
|
||||||
omega
|
omega
|
||||||
· apply List.containsKey_bind_eq_false
|
· apply List.containsKey_flatMap_eq_false
|
||||||
intro j hj
|
intro j hj
|
||||||
rw [← List.getElem_cons_succ self[i] _ _
|
rw [← List.getElem_cons_succ self[i] _ _
|
||||||
(by simp only [Array.ugetElem_eq_getElem, List.length_cons]; omega)]
|
(by simp only [Array.ugetElem_eq_getElem, List.length_cons]; omega)]
|
||||||
@@ -121,7 +121,7 @@ theorem exists_bucket_of_update [BEq α] [Hashable α] (m : Array (AssocList α
|
|||||||
|
|
||||||
theorem exists_bucket' [BEq α] [Hashable α]
|
theorem exists_bucket' [BEq α] [Hashable α]
|
||||||
(self : Array (AssocList α β)) (i : USize) (hi : i.toNat < self.size) :
|
(self : Array (AssocList α β)) (i : USize) (hi : i.toNat < self.size) :
|
||||||
∃ l, Perm (self.toList.bind AssocList.toList) (self[i.toNat].toList ++ l) ∧
|
∃ l, Perm (self.toList.flatMap AssocList.toList) (self[i.toNat].toList ++ l) ∧
|
||||||
(∀ [LawfulHashable α], IsHashSelf self → ∀ k,
|
(∀ [LawfulHashable α], IsHashSelf self → ∀ k,
|
||||||
(mkIdx self.size (by omega) (hash k)).1.toNat = i.toNat → containsKey k l = false) := by
|
(mkIdx self.size (by omega) (hash k)).1.toNat = i.toNat → containsKey k l = false) := by
|
||||||
obtain ⟨l, h₁, -, h₂⟩ := exists_bucket_of_uset self i hi .nil
|
obtain ⟨l, h₁, -, h₂⟩ := exists_bucket_of_uset self i hi .nil
|
||||||
@@ -186,8 +186,8 @@ theorem toListModel_updateAllBuckets {m : Raw₀ α β} {f : AssocList α β →
|
|||||||
have := (hg (l := []) (l' := [])).length_eq
|
have := (hg (l := []) (l' := [])).length_eq
|
||||||
rw [List.length_append, List.append_nil] at this
|
rw [List.length_append, List.append_nil] at this
|
||||||
omega
|
omega
|
||||||
rw [updateAllBuckets, toListModel, Array.toList_map, List.bind_eq_foldl, List.foldl_map,
|
rw [updateAllBuckets, toListModel, Array.toList_map, List.flatMap_eq_foldl, List.foldl_map,
|
||||||
toListModel, List.bind_eq_foldl]
|
toListModel, List.flatMap_eq_foldl]
|
||||||
suffices ∀ (l : List (AssocList α β)) (l' : List ((a: α) × δ a)) (l'' : List ((a : α) × β a)),
|
suffices ∀ (l : List (AssocList α β)) (l' : List ((a: α) × δ a)) (l'' : List ((a : α) × β a)),
|
||||||
Perm (g l'') l' →
|
Perm (g l'') l' →
|
||||||
Perm (l.foldl (fun acc a => acc ++ (f a).toList) l')
|
Perm (l.foldl (fun acc a => acc ++ (f a).toList) l')
|
||||||
|
|||||||
@@ -31,14 +31,14 @@ namespace Std.DHashMap.Internal
|
|||||||
@[simp]
|
@[simp]
|
||||||
theorem toListModel_mkArray_nil {c} :
|
theorem toListModel_mkArray_nil {c} :
|
||||||
toListModel (mkArray c (AssocList.nil : AssocList α β)) = [] := by
|
toListModel (mkArray c (AssocList.nil : AssocList α β)) = [] := by
|
||||||
suffices ∀ d, (List.replicate d AssocList.nil).bind AssocList.toList = [] from this _
|
suffices ∀ d, (List.replicate d AssocList.nil).flatMap AssocList.toList = [] from this _
|
||||||
intro d
|
intro d
|
||||||
induction d <;> simp_all [List.replicate]
|
induction d <;> simp_all [List.replicate]
|
||||||
|
|
||||||
@[simp]
|
@[simp]
|
||||||
theorem computeSize_eq {buckets : Array (AssocList α β)} :
|
theorem computeSize_eq {buckets : Array (AssocList α β)} :
|
||||||
computeSize buckets = (toListModel buckets).length := by
|
computeSize buckets = (toListModel buckets).length := by
|
||||||
rw [computeSize, toListModel, List.bind_eq_foldl, Array.foldl_eq_foldl_toList]
|
rw [computeSize, toListModel, List.flatMap_eq_foldl, Array.foldl_eq_foldl_toList]
|
||||||
suffices ∀ (l : List (AssocList α β)) (l' : List ((a : α) × β a)),
|
suffices ∀ (l : List (AssocList α β)) (l' : List ((a : α) × β a)),
|
||||||
l.foldl (fun d b => d + b.toList.length) l'.length =
|
l.foldl (fun d b => d + b.toList.length) l'.length =
|
||||||
(l.foldl (fun acc a => acc ++ a.toList) l').length
|
(l.foldl (fun acc a => acc ++ a.toList) l').length
|
||||||
@@ -129,7 +129,7 @@ theorem expand.go_eq [BEq α] [Hashable α] [PartialEquivBEq α] (source : Array
|
|||||||
(target : {d : Array (AssocList α β) // 0 < d.size}) : expand.go 0 source target =
|
(target : {d : Array (AssocList α β) // 0 < d.size}) : expand.go 0 source target =
|
||||||
(toListModel source).foldl (fun acc p => reinsertAux hash acc p.1 p.2) target := by
|
(toListModel source).foldl (fun acc p => reinsertAux hash acc p.1 p.2) target := by
|
||||||
suffices ∀ i, expand.go i source target =
|
suffices ∀ i, expand.go i source target =
|
||||||
((source.toList.drop i).bind AssocList.toList).foldl
|
((source.toList.drop i).flatMap AssocList.toList).foldl
|
||||||
(fun acc p => reinsertAux hash acc p.1 p.2) target by
|
(fun acc p => reinsertAux hash acc p.1 p.2) target by
|
||||||
simpa using this 0
|
simpa using this 0
|
||||||
intro i
|
intro i
|
||||||
@@ -139,10 +139,10 @@ theorem expand.go_eq [BEq α] [Hashable α] [PartialEquivBEq α] (source : Array
|
|||||||
rw [expand.go_pos hi]
|
rw [expand.go_pos hi]
|
||||||
refine ih.trans ?_
|
refine ih.trans ?_
|
||||||
simp only [Array.get_eq_getElem, AssocList.foldl_eq, Array.toList_set]
|
simp only [Array.get_eq_getElem, AssocList.foldl_eq, Array.toList_set]
|
||||||
rw [List.drop_eq_getElem_cons hi, List.bind_cons, List.foldl_append,
|
rw [List.drop_eq_getElem_cons hi, List.flatMap_cons, List.foldl_append,
|
||||||
List.drop_set_of_lt _ _ (by omega), Array.getElem_eq_getElem_toList]
|
List.drop_set_of_lt _ _ (by omega), Array.getElem_eq_getElem_toList]
|
||||||
· next i source target hi =>
|
· next i source target hi =>
|
||||||
rw [expand.go_neg hi, List.drop_eq_nil_of_le, bind_nil, foldl_nil]
|
rw [expand.go_neg hi, List.drop_eq_nil_of_le, flatMap_nil, foldl_nil]
|
||||||
rwa [Array.size_eq_length_toList, Nat.not_lt] at hi
|
rwa [Array.size_eq_length_toList, Nat.not_lt] at hi
|
||||||
|
|
||||||
theorem isHashSelf_expand [BEq α] [Hashable α] [LawfulHashable α] [EquivBEq α]
|
theorem isHashSelf_expand [BEq α] [Hashable α] [LawfulHashable α] [EquivBEq α]
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ def buildImportsAndDeps (leanFile : FilePath) (imports : Array Module) : FetchM
|
|||||||
let precompileImports ← computePrecompileImportsAux leanFile imports
|
let precompileImports ← computePrecompileImportsAux leanFile imports
|
||||||
let pkgs := precompileImports.foldl (·.insert ·.pkg) OrdPackageSet.empty |>.toArray
|
let pkgs := precompileImports.foldl (·.insert ·.pkg) OrdPackageSet.empty |>.toArray
|
||||||
let externLibJob ← BuildJob.collectArray <| ←
|
let externLibJob ← BuildJob.collectArray <| ←
|
||||||
pkgs.concatMapM (·.externLibs.mapM (·.dynlib.fetch))
|
pkgs.flatMapM (·.externLibs.mapM (·.dynlib.fetch))
|
||||||
let precompileJob ← BuildJob.collectArray <| ←
|
let precompileJob ← BuildJob.collectArray <| ←
|
||||||
precompileImports.mapM (·.dynlib.fetch)
|
precompileImports.mapM (·.dynlib.fetch)
|
||||||
let job ←
|
let job ←
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ def LeanLib.leanArtsFacetConfig : LibraryFacetConfig leanArtsFacet :=
|
|||||||
""
|
""
|
||||||
withRegisterJob s!"{self.name}:static{suffix}" do
|
withRegisterJob s!"{self.name}:static{suffix}" do
|
||||||
let mods ← self.modules.fetch
|
let mods ← self.modules.fetch
|
||||||
let oJobs ← mods.concatMapM fun mod =>
|
let oJobs ← mods.flatMapM fun mod =>
|
||||||
mod.nativeFacets shouldExport |>.mapM fun facet => fetch <| mod.facet facet.name
|
mod.nativeFacets shouldExport |>.mapM fun facet => fetch <| mod.facet facet.name
|
||||||
let libFile := if shouldExport then self.staticExportLibFile else self.staticLibFile
|
let libFile := if shouldExport then self.staticExportLibFile else self.staticLibFile
|
||||||
buildStaticLib libFile oJobs
|
buildStaticLib libFile oJobs
|
||||||
@@ -80,10 +80,10 @@ protected def LeanLib.recBuildShared
|
|||||||
(self : LeanLib) : FetchM (BuildJob FilePath) := do
|
(self : LeanLib) : FetchM (BuildJob FilePath) := do
|
||||||
withRegisterJob s!"{self.name}:shared" do
|
withRegisterJob s!"{self.name}:shared" do
|
||||||
let mods ← self.modules.fetch
|
let mods ← self.modules.fetch
|
||||||
let oJobs ← mods.concatMapM fun mod =>
|
let oJobs ← mods.flatMapM fun mod =>
|
||||||
mod.nativeFacets true |>.mapM fun facet => fetch <| mod.facet facet.name
|
mod.nativeFacets true |>.mapM fun facet => fetch <| mod.facet facet.name
|
||||||
let pkgs := mods.foldl (·.insert ·.pkg) OrdPackageSet.empty |>.toArray
|
let pkgs := mods.foldl (·.insert ·.pkg) OrdPackageSet.empty |>.toArray
|
||||||
let externJobs ← pkgs.concatMapM (·.externLibs.mapM (·.shared.fetch))
|
let externJobs ← pkgs.flatMapM (·.externLibs.mapM (·.shared.fetch))
|
||||||
buildLeanSharedLib self.sharedLibFile (oJobs ++ externJobs) self.weakLinkArgs self.linkArgs
|
buildLeanSharedLib self.sharedLibFile (oJobs ++ externJobs) self.weakLinkArgs self.linkArgs
|
||||||
|
|
||||||
/-- The `LibraryFacetConfig` for the builtin `sharedFacet`. -/
|
/-- The `LibraryFacetConfig` for the builtin `sharedFacet`. -/
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ def resolveTargetInPackage (ws : Workspace)
|
|||||||
throw <| CliError.missingTarget pkg.name (target.toString false)
|
throw <| CliError.missingTarget pkg.name (target.toString false)
|
||||||
|
|
||||||
def resolveDefaultPackageTarget (ws : Workspace) (pkg : Package) : Except CliError (Array BuildSpec) :=
|
def resolveDefaultPackageTarget (ws : Workspace) (pkg : Package) : Except CliError (Array BuildSpec) :=
|
||||||
pkg.defaultTargets.concatMapM (resolveTargetInPackage ws pkg · .anonymous)
|
pkg.defaultTargets.flatMapM (resolveTargetInPackage ws pkg · .anonymous)
|
||||||
|
|
||||||
def resolvePackageTarget (ws : Workspace) (pkg : Package) (facet : Name) : Except CliError (Array BuildSpec) :=
|
def resolvePackageTarget (ws : Workspace) (pkg : Package) (facet : Name) : Except CliError (Array BuildSpec) :=
|
||||||
if facet.isAnonymous then
|
if facet.isAnonymous then
|
||||||
|
|||||||
@@ -47,4 +47,4 @@ def OrderedTagAttribute.hasTag (attr : OrderedTagAttribute) (env : Environment)
|
|||||||
/-- Get all tagged declaration names, both those imported and those in the current module. -/
|
/-- Get all tagged declaration names, both those imported and those in the current module. -/
|
||||||
def OrderedTagAttribute.getAllEntries (attr : OrderedTagAttribute) (env : Environment) : Array Name :=
|
def OrderedTagAttribute.getAllEntries (attr : OrderedTagAttribute) (env : Environment) : Array Name :=
|
||||||
let s := attr.ext.toEnvExtension.getState env
|
let s := attr.ext.toEnvExtension.getState env
|
||||||
s.importedEntries.concatMap id ++ s.state
|
s.importedEntries.flatMap id ++ s.state
|
||||||
|
|||||||
Reference in New Issue
Block a user