fix: replace bad simp lemmas for Id (#7352)
This PR reworks the `simp` set around the `Id` monad, to not elide or unfold `pure` and `Id.run` In particular, it stops encoding the "defeq abuse" of `Id X = X` in the statements of theorems, instead using `Id.run` and `pure` to pass back and forth between these two spellings. Often when writing these with `pure`, they generalize to other lawful monads; though such changes were split off to other PRs. This fixes the problem with the current simp set where `Id.run (pure x)` is simplified to `Id.run x`, instead of the desirable `x`. This is particularly bad because the` x` is sometimes inferred with type `Id X` instead of `X`, which prevents other `simp` lemmas about `X` from firing. Making `Id` reducible instead is not an option, as then the `Monad` instances would have nothing to key on. --------- Co-authored-by: Sebastian Graf <sg@lean-fro.org> Co-authored-by: Kim Morrison <kim@tqft.net> Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
This commit is contained in:
parent
5e40f4af52
commit
ae1ab94992
61 changed files with 324 additions and 244 deletions
|
|
@ -6,6 +6,7 @@ Authors: Sebastian Ullrich, Leonardo de Moura, Mario Carneiro
|
|||
module
|
||||
|
||||
prelude
|
||||
import Init.Ext
|
||||
import Init.SimpLemmas
|
||||
import Init.Meta
|
||||
|
||||
|
|
@ -241,13 +242,23 @@ theorem LawfulMonad.mk' (m : Type u → Type v) [Monad m]
|
|||
|
||||
namespace Id
|
||||
|
||||
@[simp] theorem map_eq (x : Id α) (f : α → β) : f <$> x = f x := rfl
|
||||
@[simp] theorem bind_eq (x : Id α) (f : α → id β) : x >>= f = f x := rfl
|
||||
@[simp] theorem pure_eq (a : α) : (pure a : Id α) = a := rfl
|
||||
@[ext] theorem ext {x y : Id α} (h : x.run = y.run) : x = y := h
|
||||
|
||||
instance : LawfulMonad Id := by
|
||||
refine LawfulMonad.mk' _ ?_ ?_ ?_ <;> intros <;> rfl
|
||||
|
||||
@[simp] theorem run_map (x : Id α) (f : α → β) : (f <$> x).run = f x.run := rfl
|
||||
@[simp] theorem run_bind (x : Id α) (f : α → Id β) : (x >>= f).run = (f x.run).run := rfl
|
||||
@[simp] theorem run_pure (a : α) : (pure a : Id α).run = a := rfl
|
||||
@[simp] theorem run_seqRight (x y : Id α) : (x *> y).run = y.run := rfl
|
||||
@[simp] theorem run_seqLeft (x y : Id α) : (x <* y).run = x.run := rfl
|
||||
@[simp] theorem run_seq (f : Id (α → β)) (x : Id α) : (f <*> x).run = f.run x.run := rfl
|
||||
|
||||
-- These lemmas are bad as they abuse the defeq of `Id α` and `α`
|
||||
@[deprecated run_map (since := "2025-03-05")] theorem map_eq (x : Id α) (f : α → β) : f <$> x = f x := rfl
|
||||
@[deprecated run_bind (since := "2025-03-05")] theorem bind_eq (x : Id α) (f : α → id β) : x >>= f = f x := rfl
|
||||
@[deprecated run_pure (since := "2025-03-05")] theorem pure_eq (a : α) : (pure a : Id α) = a := rfl
|
||||
|
||||
end Id
|
||||
|
||||
/-! # Option -/
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def modify (xs : Array α) (i : Nat) (f : α → α) : Array α :=
|
||||
Id.run <| modifyM xs i f
|
||||
Id.run <| modifyM xs i (pure <| f ·)
|
||||
|
||||
set_option linter.indexVariables false in -- Changing `idx` causes bootstrapping issues, haven't investigated.
|
||||
/--
|
||||
|
|
@ -1059,7 +1059,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def foldl {α : Type u} {β : Type v} (f : β → α → β) (init : β) (as : Array α) (start := 0) (stop := as.size) : β :=
|
||||
Id.run <| as.foldlM f init start stop
|
||||
Id.run <| as.foldlM (pure <| f · ·) init start stop
|
||||
|
||||
/--
|
||||
Folds a function over an array from the right, accumulating a value starting with `init`. The
|
||||
|
|
@ -1076,7 +1076,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def foldr {α : Type u} {β : Type v} (f : α → β → β) (init : β) (as : Array α) (start := as.size) (stop := 0) : β :=
|
||||
Id.run <| as.foldrM f init start stop
|
||||
Id.run <| as.foldrM (pure <| f · ·) init start stop
|
||||
|
||||
/--
|
||||
Computes the sum of the elements of an array.
|
||||
|
|
@ -1124,7 +1124,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def map {α : Type u} {β : Type v} (f : α → β) (as : Array α) : Array β :=
|
||||
Id.run <| as.mapM f
|
||||
Id.run <| as.mapM (pure <| f ·)
|
||||
|
||||
instance : Functor Array where
|
||||
map := map
|
||||
|
|
@ -1139,7 +1139,7 @@ valid.
|
|||
-/
|
||||
@[inline]
|
||||
def mapFinIdx {α : Type u} {β : Type v} (as : Array α) (f : (i : Nat) → α → (h : i < as.size) → β) : Array β :=
|
||||
Id.run <| as.mapFinIdxM f
|
||||
Id.run <| as.mapFinIdxM (pure <| f · · ·)
|
||||
|
||||
/--
|
||||
Applies a function to each element of the array along with the index at which that element is found,
|
||||
|
|
@ -1150,7 +1150,7 @@ is valid.
|
|||
-/
|
||||
@[inline]
|
||||
def mapIdx {α : Type u} {β : Type v} (f : Nat → α → β) (as : Array α) : Array β :=
|
||||
Id.run <| as.mapIdxM f
|
||||
Id.run <| as.mapIdxM (pure <| f · ·)
|
||||
|
||||
/--
|
||||
Pairs each element of an array with its index, optionally starting from an index other than `0`.
|
||||
|
|
@ -1198,7 +1198,7 @@ some 10
|
|||
-/
|
||||
@[inline]
|
||||
def findSome? {α : Type u} {β : Type v} (f : α → Option β) (as : Array α) : Option β :=
|
||||
Id.run <| as.findSomeM? f
|
||||
Id.run <| as.findSomeM? (pure <| f ·)
|
||||
|
||||
/--
|
||||
Returns the first non-`none` result of applying the function `f` to each element of the
|
||||
|
|
@ -1232,7 +1232,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def findSomeRev? {α : Type u} {β : Type v} (f : α → Option β) (as : Array α) : Option β :=
|
||||
Id.run <| as.findSomeRevM? f
|
||||
Id.run <| as.findSomeRevM? (pure <| f ·)
|
||||
|
||||
/--
|
||||
Returns the last element of the array for which the predicate `p` returns `true`, or `none` if no
|
||||
|
|
@ -1244,7 +1244,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def findRev? {α : Type} (p : α → Bool) (as : Array α) : Option α :=
|
||||
Id.run <| as.findRevM? p
|
||||
Id.run <| as.findRevM? (pure <| p ·)
|
||||
|
||||
/--
|
||||
Returns the index of the first element for which `p` returns `true`, or `none` if there is no such
|
||||
|
|
@ -1383,7 +1383,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def any (as : Array α) (p : α → Bool) (start := 0) (stop := as.size) : Bool :=
|
||||
Id.run <| as.anyM p start stop
|
||||
Id.run <| as.anyM (pure <| p ·) start stop
|
||||
|
||||
/--
|
||||
Returns `true` if `p` returns `true` for every element of `as`.
|
||||
|
|
@ -1401,7 +1401,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def all (as : Array α) (p : α → Bool) (start := 0) (stop := as.size) : Bool :=
|
||||
Id.run <| as.allM p start stop
|
||||
Id.run <| as.allM (pure <| p ·) start stop
|
||||
|
||||
/--
|
||||
Checks whether `a` is an element of `as`, using `==` to compare elements.
|
||||
|
|
@ -1670,7 +1670,7 @@ Example:
|
|||
-/
|
||||
@[inline]
|
||||
def filterMap (f : α → Option β) (as : Array α) (start := 0) (stop := as.size) : Array β :=
|
||||
Id.run <| as.filterMapM f (start := start) (stop := stop)
|
||||
Id.run <| as.filterMapM (pure <| f ·) (start := start) (stop := stop)
|
||||
|
||||
/--
|
||||
Returns the largest element of the array, as determined by the comparison `lt`, or `none` if
|
||||
|
|
|
|||
|
|
@ -88,4 +88,4 @@ pointer equality, and does not allocate a new array if the result of each functi
|
|||
pointer-equal to its argument.
|
||||
-/
|
||||
@[inline] def Array.mapMono (as : Array α) (f : α → α) : Array α :=
|
||||
Id.run <| as.mapMonoM f
|
||||
Id.run <| as.mapMonoM (pure <| f ·)
|
||||
|
|
|
|||
|
|
@ -129,6 +129,6 @@ Examples:
|
|||
* `#[].binInsert (· < ·) 1 = #[1]`
|
||||
-/
|
||||
@[inline] def binInsert {α : Type u} (lt : α → α → Bool) (as : Array α) (k : α) : Array α :=
|
||||
Id.run <| binInsertM lt (fun _ => k) (fun _ => k) as k
|
||||
Id.run <| binInsertM lt (fun _ => pure k) (fun _ => pure k) as k
|
||||
|
||||
end Array
|
||||
|
|
|
|||
|
|
@ -613,13 +613,13 @@ theorem anyM_loop_cons [Monad m] {p : α → m Bool} {a : α} {as : List α} {st
|
|||
|
||||
-- Auxiliary for `any_iff_exists`.
|
||||
theorem anyM_loop_iff_exists {p : α → Bool} {as : Array α} {start stop} (h : stop ≤ as.size) :
|
||||
anyM.loop (m := Id) p as stop h start = true ↔
|
||||
(anyM.loop (m := Id) (pure <| p ·) as stop h start).run = true ↔
|
||||
∃ (i : Nat) (_ : i < as.size), start ≤ i ∧ i < stop ∧ p as[i] = true := by
|
||||
unfold anyM.loop
|
||||
split <;> rename_i h₁
|
||||
· dsimp
|
||||
split <;> rename_i h₂
|
||||
· simp only [true_iff]
|
||||
· simp only [true_iff, Id.run_pure]
|
||||
refine ⟨start, by omega, by omega, by omega, h₂⟩
|
||||
· rw [anyM_loop_iff_exists]
|
||||
constructor
|
||||
|
|
@ -636,9 +636,9 @@ termination_by stop - start
|
|||
-- This could also be proved from `SatisfiesM_anyM_iff_exists` in `Batteries.Data.Array.Init.Monadic`
|
||||
theorem any_iff_exists {p : α → Bool} {as : Array α} {start stop} :
|
||||
as.any p start stop ↔ ∃ (i : Nat) (_ : i < as.size), start ≤ i ∧ i < stop ∧ p as[i] := by
|
||||
dsimp [any, anyM, Id.run]
|
||||
dsimp [any, anyM]
|
||||
split
|
||||
· rw [anyM_loop_iff_exists]
|
||||
· rw [anyM_loop_iff_exists (p := p)]
|
||||
· rw [anyM_loop_iff_exists]
|
||||
constructor
|
||||
· rintro ⟨i, hi, ge, _, h⟩
|
||||
|
|
@ -1370,17 +1370,17 @@ theorem mapM_eq_mapM_toList [Monad m] [LawfulMonad m] {f : α → m β} {xs : Ar
|
|||
|
||||
@[deprecated "Use `mapM_eq_foldlM` instead" (since := "2025-01-08")]
|
||||
theorem mapM_map_eq_foldl {as : Array α} {f : α → β} {i : Nat} :
|
||||
mapM.map (m := Id) f as i b = as.foldl (start := i) (fun acc a => acc.push (f a)) b := by
|
||||
mapM.map (m := Id) (pure <| f ·) as i b = pure (as.foldl (start := i) (fun acc a => acc.push (f a)) b) := by
|
||||
unfold mapM.map
|
||||
split <;> rename_i h
|
||||
· simp only [Id.bind_eq]
|
||||
dsimp [foldl, Id.run, foldlM]
|
||||
· ext : 1
|
||||
dsimp [foldl, foldlM]
|
||||
rw [mapM_map_eq_foldl, dif_pos (by omega), foldlM.loop, dif_pos h]
|
||||
-- Calling `split` here gives a bad goal.
|
||||
have : size as - i = Nat.succ (size as - i - 1) := by omega
|
||||
rw [this]
|
||||
simp [foldl, foldlM, Id.run, Nat.sub_add_eq]
|
||||
· dsimp [foldl, Id.run, foldlM]
|
||||
simp [foldl, foldlM, Nat.sub_add_eq]
|
||||
· dsimp [foldl, foldlM]
|
||||
rw [dif_pos (by omega), foldlM.loop, dif_neg h]
|
||||
rfl
|
||||
termination_by as.size - i
|
||||
|
|
@ -1602,8 +1602,8 @@ theorem filterMap_congr {as bs : Array α} (h : as = bs)
|
|||
as.toList ++ List.filterMap f xs := ?_
|
||||
exact this #[]
|
||||
induction xs
|
||||
· simp_all [Id.run]
|
||||
· simp_all [Id.run, List.filterMap_cons]
|
||||
· simp_all
|
||||
· simp_all [List.filterMap_cons]
|
||||
split <;> simp_all
|
||||
|
||||
@[grind] theorem toList_filterMap {f : α → Option β} {xs : Array α} :
|
||||
|
|
@ -3215,18 +3215,16 @@ theorem foldlM_push [Monad m] [LawfulMonad m] {xs : Array α} {a : α} {f : β
|
|||
rw [foldr, foldrM_start_stop, ← foldrM_toList, List.foldrM_pure, foldr_toList, foldr, ← foldrM_start_stop]
|
||||
|
||||
theorem foldl_eq_foldlM {f : β → α → β} {b} {xs : Array α} {start stop : Nat} :
|
||||
xs.foldl f b start stop = xs.foldlM (m := Id) f b start stop := by
|
||||
simp [foldl, Id.run]
|
||||
xs.foldl f b start stop = (xs.foldlM (m := Id) (pure <| f · ·) b start stop).run := rfl
|
||||
|
||||
theorem foldr_eq_foldrM {f : α → β → β} {b} {xs : Array α} {start stop : Nat} :
|
||||
xs.foldr f b start stop = xs.foldrM (m := Id) f b start stop := by
|
||||
simp [foldr, Id.run]
|
||||
xs.foldr f b start stop = (xs.foldrM (m := Id) (pure <| f · ·) b start stop).run := rfl
|
||||
|
||||
@[simp] theorem id_run_foldlM {f : β → α → Id β} {b} {xs : Array α} {start stop : Nat} :
|
||||
Id.run (xs.foldlM f b start stop) = xs.foldl f b start stop := foldl_eq_foldlM.symm
|
||||
Id.run (xs.foldlM f b start stop) = xs.foldl (f · · |>.run) b start stop := rfl
|
||||
|
||||
@[simp] theorem id_run_foldrM {f : α → β → Id β} {b} {xs : Array α} {start stop : Nat} :
|
||||
Id.run (xs.foldrM f b start stop) = xs.foldr f b start stop := foldr_eq_foldrM.symm
|
||||
Id.run (xs.foldrM f b start stop) = xs.foldr (f · · |>.run) b start stop := rfl
|
||||
|
||||
/-- Variant of `foldlM_reverse` with a side condition for the `stop` argument. -/
|
||||
@[simp] theorem foldlM_reverse' [Monad m] {xs : Array α} {f : β → α → m β} {b} {stop : Nat}
|
||||
|
|
@ -3526,17 +3524,16 @@ theorem foldrM_append [Monad m] [LawfulMonad m] {f : α → β → m β} {b} {xs
|
|||
|
||||
@[simp] theorem foldr_append' {f : α → β → β} {b} {xs ys : Array α} {start : Nat}
|
||||
(w : start = xs.size + ys.size) :
|
||||
(xs ++ ys).foldr f b start 0 = xs.foldr f (ys.foldr f b) := by
|
||||
subst w
|
||||
simp [foldr_eq_foldrM]
|
||||
(xs ++ ys).foldr f b start 0 = xs.foldr f (ys.foldr f b) :=
|
||||
foldrM_append' w
|
||||
|
||||
@[grind _=_]theorem foldl_append {β : Type _} {f : β → α → β} {b} {xs ys : Array α} :
|
||||
(xs ++ ys).foldl f b = ys.foldl f (xs.foldl f b) := by
|
||||
simp [foldl_eq_foldlM]
|
||||
(xs ++ ys).foldl f b = ys.foldl f (xs.foldl f b) :=
|
||||
foldlM_append
|
||||
|
||||
@[grind _=_] theorem foldr_append {f : α → β → β} {b} {xs ys : Array α} :
|
||||
(xs ++ ys).foldr f b = xs.foldr f (ys.foldr f b) := by
|
||||
simp [foldr_eq_foldrM]
|
||||
(xs ++ ys).foldr f b = xs.foldr f (ys.foldr f b) :=
|
||||
foldrM_append
|
||||
|
||||
@[simp] theorem foldl_flatten' {f : β → α → β} {b} {xss : Array (Array α)} {stop : Nat}
|
||||
(w : stop = xss.flatten.size) :
|
||||
|
|
@ -3565,21 +3562,22 @@ theorem foldrM_append [Monad m] [LawfulMonad m] {f : α → β → m β} {b} {xs
|
|||
/-- Variant of `foldl_reverse` with a side condition for the `stop` argument. -/
|
||||
@[simp] theorem foldl_reverse' {xs : Array α} {f : β → α → β} {b} {stop : Nat}
|
||||
(w : stop = xs.size) :
|
||||
xs.reverse.foldl f b 0 stop = xs.foldr (fun x y => f y x) b := by
|
||||
simp [w, foldl_eq_foldlM, foldr_eq_foldrM]
|
||||
xs.reverse.foldl f b 0 stop = xs.foldr (fun x y => f y x) b :=
|
||||
foldlM_reverse' w
|
||||
|
||||
/-- Variant of `foldr_reverse` with a side condition for the `start` argument. -/
|
||||
@[simp] theorem foldr_reverse' {xs : Array α} {f : α → β → β} {b} {start : Nat}
|
||||
(w : start = xs.size) :
|
||||
xs.reverse.foldr f b start 0 = xs.foldl (fun x y => f y x) b := by
|
||||
simp [w, foldl_eq_foldlM, foldr_eq_foldrM]
|
||||
xs.reverse.foldr f b start 0 = xs.foldl (fun x y => f y x) b :=
|
||||
foldrM_reverse' w
|
||||
|
||||
@[grind] theorem foldl_reverse {xs : Array α} {f : β → α → β} {b} :
|
||||
xs.reverse.foldl f b = xs.foldr (fun x y => f y x) b := by simp [foldl_eq_foldlM, foldr_eq_foldrM]
|
||||
xs.reverse.foldl f b = xs.foldr (fun x y => f y x) b :=
|
||||
foldlM_reverse
|
||||
|
||||
@[grind] theorem foldr_reverse {xs : Array α} {f : α → β → β} {b} :
|
||||
xs.reverse.foldr f b = xs.foldl (fun x y => f y x) b :=
|
||||
(foldl_reverse ..).symm.trans <| by simp
|
||||
foldrM_reverse
|
||||
|
||||
theorem foldl_eq_foldr_reverse {xs : Array α} {f : β → α → β} {b} :
|
||||
xs.foldl f b = xs.reverse.foldr (fun x y => f y x) b := by simp
|
||||
|
|
@ -4094,15 +4092,16 @@ abbrev all_mkArray := @all_replicate
|
|||
/-! ### modify -/
|
||||
|
||||
@[simp] theorem size_modify {xs : Array α} {i : Nat} {f : α → α} : (xs.modify i f).size = xs.size := by
|
||||
unfold modify modifyM Id.run
|
||||
unfold modify modifyM
|
||||
split <;> simp
|
||||
|
||||
theorem getElem_modify {xs : Array α} {j i} (h : i < (xs.modify j f).size) :
|
||||
(xs.modify j f)[i] = if j = i then f (xs[i]'(by simpa using h)) else xs[i]'(by simpa using h) := by
|
||||
simp only [modify, modifyM, Id.run, Id.pure_eq]
|
||||
simp only [modify, modifyM]
|
||||
split
|
||||
· simp only [Id.bind_eq, getElem_set]; split <;> simp [*]
|
||||
· rw [if_neg (mt (by rintro rfl; exact h) (by simp_all))]
|
||||
· simp only [getElem_set, Id.run_pure, Id.run_bind]; split <;> simp [*]
|
||||
· simp only [Id.run_pure]
|
||||
rw [if_neg (mt (by rintro rfl; exact h) (by simp_all))]
|
||||
|
||||
@[simp] theorem toList_modify {xs : Array α} {f : α → α} {i : Nat} :
|
||||
(xs.modify i f).toList = xs.toList.modify i f := by
|
||||
|
|
@ -4643,12 +4642,12 @@ namespace Array
|
|||
@[simp] theorem findSomeRev?_eq_findSome?_reverse {f : α → Option β} {xs : Array α} :
|
||||
xs.findSomeRev? f = xs.reverse.findSome? f := by
|
||||
cases xs
|
||||
simp [findSomeRev?, Id.run]
|
||||
simp [findSomeRev?]
|
||||
|
||||
@[simp] theorem findRev?_eq_find?_reverse {f : α → Bool} {xs : Array α} :
|
||||
xs.findRev? f = xs.reverse.find? f := by
|
||||
cases xs
|
||||
simp [findRev?, Id.run]
|
||||
simp [findRev?]
|
||||
|
||||
/-! ### unzip -/
|
||||
|
||||
|
|
|
|||
|
|
@ -29,16 +29,16 @@ protected theorem not_le_iff_gt [DecidableEq α] [LT α] [DecidableLT α] {xs ys
|
|||
Decidable.not_not
|
||||
|
||||
@[simp] theorem lex_empty [BEq α] {lt : α → α → Bool} {xs : Array α} : xs.lex #[] lt = false := by
|
||||
simp [lex, Id.run]
|
||||
simp [lex]
|
||||
|
||||
@[simp] theorem singleton_lex_singleton [BEq α] {lt : α → α → Bool} : #[a].lex #[b] lt = lt a b := by
|
||||
simp only [lex, List.getElem_toArray, List.getElem_singleton]
|
||||
cases lt a b <;> cases a != b <;> simp [Id.run]
|
||||
cases lt a b <;> cases a != b <;> simp
|
||||
|
||||
private theorem cons_lex_cons [BEq α] {lt : α → α → Bool} {a b : α} {xs ys : Array α} :
|
||||
(#[a] ++ xs).lex (#[b] ++ ys) lt =
|
||||
(lt a b || a == b && xs.lex ys lt) := by
|
||||
simp only [lex, Id.run]
|
||||
simp only [lex]
|
||||
simp only [Std.Range.forIn'_eq_forIn'_range', size_append, List.size_toArray, List.length_singleton,
|
||||
Nat.add_comm 1]
|
||||
simp [Nat.add_min_add_right, List.range'_succ, getElem_append_left, List.range'_succ_left,
|
||||
|
|
@ -51,10 +51,10 @@ private theorem cons_lex_cons [BEq α] {lt : α → α → Bool} {a b : α} {xs
|
|||
@[simp, grind =] theorem _root_.List.lex_toArray [BEq α] {lt : α → α → Bool} {l₁ l₂ : List α} :
|
||||
l₁.toArray.lex l₂.toArray lt = l₁.lex l₂ lt := by
|
||||
induction l₁ generalizing l₂ with
|
||||
| nil => cases l₂ <;> simp [lex, Id.run]
|
||||
| nil => cases l₂ <;> simp [lex]
|
||||
| cons x l₁ ih =>
|
||||
cases l₂ with
|
||||
| nil => simp [lex, Id.run]
|
||||
| nil => simp [lex]
|
||||
| cons y l₂ =>
|
||||
rw [List.toArray_cons, List.toArray_cons y, cons_lex_cons, List.lex, ih]
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ theorem mapFinIdx_induction (xs : Array α) (f : (i : Nat) → α → (h : i < x
|
|||
motive xs.size ∧ ∃ eq : (Array.mapFinIdx xs f).size = xs.size,
|
||||
∀ i h, p i ((Array.mapFinIdx xs f)[i]) h := by
|
||||
let rec go {bs i j h} (h₁ : j = bs.size) (h₂ : ∀ i h h', p i bs[i] h) (hm : motive j) :
|
||||
let as : Array β := Array.mapFinIdxM.map (m := Id) xs f i j h bs
|
||||
let as : Array β := Id.run <| Array.mapFinIdxM.map xs (pure <| f · · ·) i j h bs
|
||||
motive xs.size ∧ ∃ eq : as.size = xs.size, ∀ i h, p i as[i] h := by
|
||||
induction i generalizing j bs with simp [mapFinIdxM.map]
|
||||
| zero =>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,11 @@ open Nat
|
|||
xs.mapM (m := m) (pure <| f ·) = pure (xs.map f) := by
|
||||
induction xs; simp_all
|
||||
|
||||
@[simp] theorem mapM_id {xs : Array α} {f : α → Id β} : xs.mapM f = xs.map f :=
|
||||
@[simp] theorem idRun_mapM {xs : Array α} {f : α → Id β} : (xs.mapM f).run = xs.map (f · |>.run) :=
|
||||
mapM_pure
|
||||
|
||||
@[deprecated idRun_mapM (since := "2025-05-21")]
|
||||
theorem mapM_id {xs : Array α} {f : α → Id β} : xs.mapM f = xs.map f :=
|
||||
mapM_pure
|
||||
|
||||
@[simp] theorem mapM_map [Monad m] [LawfulMonad m] {f : α → β} {g : β → m γ} {xs : Array α} :
|
||||
|
|
@ -191,12 +195,18 @@ theorem forIn'_eq_foldlM [Monad m] [LawfulMonad m]
|
|||
rcases xs with ⟨xs⟩
|
||||
simp [List.forIn'_pure_yield_eq_foldl, List.foldl_map]
|
||||
|
||||
@[simp] theorem forIn'_yield_eq_foldl
|
||||
@[simp] theorem idRun_forIn'_yield_eq_foldl
|
||||
{xs : Array α} (f : (a : α) → a ∈ xs → β → Id β) (init : β) :
|
||||
(forIn' xs init (fun a m b => .yield <$> f a m b)).run =
|
||||
xs.attach.foldl (fun b ⟨a, h⟩ => f a h b |>.run) init :=
|
||||
forIn'_pure_yield_eq_foldl _ _
|
||||
|
||||
@[deprecated idRun_forIn'_yield_eq_foldl (since := "2025-05-21")]
|
||||
theorem forIn'_yield_eq_foldl
|
||||
{xs : Array α} (f : (a : α) → a ∈ xs → β → β) (init : β) :
|
||||
forIn' (m := Id) xs init (fun a m b => .yield (f a m b)) =
|
||||
xs.attach.foldl (fun b ⟨a, h⟩ => f a h b) init := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.foldl_map]
|
||||
xs.attach.foldl (fun b ⟨a, h⟩ => f a h b) init :=
|
||||
forIn'_pure_yield_eq_foldl _ _
|
||||
|
||||
@[simp] theorem forIn'_map [Monad m] [LawfulMonad m]
|
||||
{xs : Array α} (g : α → β) (f : (b : β) → b ∈ xs.map g → γ → m (ForInStep γ)) :
|
||||
|
|
@ -233,12 +243,18 @@ theorem forIn_eq_foldlM [Monad m] [LawfulMonad m]
|
|||
rcases xs with ⟨xs⟩
|
||||
simp [List.forIn_pure_yield_eq_foldl, List.foldl_map]
|
||||
|
||||
@[simp] theorem forIn_yield_eq_foldl
|
||||
@[simp] theorem idRun_forIn_yield_eq_foldl
|
||||
{xs : Array α} (f : α → β → Id β) (init : β) :
|
||||
(forIn xs init (fun a b => .yield <$> f a b)).run =
|
||||
xs.foldl (fun b a => f a b |>.run) init :=
|
||||
forIn_pure_yield_eq_foldl _ _
|
||||
|
||||
@[deprecated idRun_forIn_yield_eq_foldl (since := "2025-05-21")]
|
||||
theorem forIn_yield_eq_foldl
|
||||
{xs : Array α} (f : α → β → β) (init : β) :
|
||||
forIn (m := Id) xs init (fun a b => .yield (f a b)) =
|
||||
xs.foldl (fun b a => f a b) init := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.foldl_map]
|
||||
xs.foldl (fun b a => f a b) init :=
|
||||
forIn_pure_yield_eq_foldl _ _
|
||||
|
||||
@[simp] theorem forIn_map [Monad m] [LawfulMonad m]
|
||||
{xs : Array α} {g : α → β} {f : β → γ → m (ForInStep γ)} :
|
||||
|
|
|
|||
|
|
@ -129,7 +129,6 @@ theorem ofFnM_pure [Monad m] [LawfulMonad m] {n} {f : Fin n → α} :
|
|||
|
||||
@[simp, grind =] theorem idRun_ofFnM {f : Fin n → Id α} :
|
||||
Id.run (ofFnM f) = ofFn (fun i => Id.run (f i)) := by
|
||||
unfold Id.run
|
||||
induction n with
|
||||
| zero => simp
|
||||
| succ n ih => simp [ofFnM_succ', ofFn_succ', ih]
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def foldl {α : Type u} {β : Type v} (f : β → α → β) (init : β) (as : Subarray α) : β :=
|
||||
Id.run <| as.foldlM f (init := init)
|
||||
Id.run <| as.foldlM (pure <| f · ·) (init := init)
|
||||
|
||||
/--
|
||||
Folds an operation from right to left over the elements in a subarray.
|
||||
|
|
@ -304,7 +304,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def foldr {α : Type u} {β : Type v} (f : α → β → β) (init : β) (as : Subarray α) : β :=
|
||||
Id.run <| as.foldrM f (init := init)
|
||||
Id.run <| as.foldrM (pure <| f · ·) (init := init)
|
||||
|
||||
/--
|
||||
Checks whether any of the elements in a subarray satisfy a Boolean predicate.
|
||||
|
|
@ -314,7 +314,7 @@ an element that satisfies the predicate is found.
|
|||
-/
|
||||
@[inline]
|
||||
def any {α : Type u} (p : α → Bool) (as : Subarray α) : Bool :=
|
||||
Id.run <| as.anyM p
|
||||
Id.run <| as.anyM (pure <| p ·)
|
||||
|
||||
/--
|
||||
Checks whether all of the elements in a subarray satisfy a Boolean predicate.
|
||||
|
|
@ -324,7 +324,7 @@ an element that does not satisfy the predicate is found.
|
|||
-/
|
||||
@[inline]
|
||||
def all {α : Type u} (p : α → Bool) (as : Subarray α) : Bool :=
|
||||
Id.run <| as.allM p
|
||||
Id.run <| as.allM (pure <| p ·)
|
||||
|
||||
/--
|
||||
Applies a monadic function to each element in a subarray in reverse order, stopping at the first
|
||||
|
|
@ -394,7 +394,7 @@ Examples:
|
|||
-/
|
||||
@[inline]
|
||||
def findRev? {α : Type} (as : Subarray α) (p : α → Bool) : Option α :=
|
||||
Id.run <| as.findRevM? p
|
||||
Id.run <| as.findRevM? (pure <| p ·)
|
||||
|
||||
end Subarray
|
||||
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ def foldlM {β : Type v} {m : Type v → Type w} [Monad m] (f : β → UInt8 →
|
|||
|
||||
@[inline]
|
||||
def foldl {β : Type v} (f : β → UInt8 → β) (init : β) (as : ByteArray) (start := 0) (stop := as.size) : β :=
|
||||
Id.run <| as.foldlM f init start stop
|
||||
Id.run <| as.foldlM (pure <| f · ·) init start stop
|
||||
|
||||
/-- Iterator over the bytes (`UInt8`) of a `ByteArray`.
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ theorem foldl_add (f : α → Fin (n + m) → α) (x) :
|
|||
| succ m ih => simp [foldl_succ_last, ih, ← Nat.add_assoc]
|
||||
|
||||
theorem foldl_eq_foldlM (f : α → Fin n → α) (x) :
|
||||
foldl n f x = foldlM (m:=Id) n f x := by
|
||||
foldl n f x = (foldlM (m := Id) n (pure <| f · ·) x).run := by
|
||||
induction n generalizing x <;> simp [foldl_succ, foldlM_succ, *]
|
||||
|
||||
-- This is not marked `@[simp]` as it would match on every occurrence of `foldlM`.
|
||||
|
|
@ -319,7 +319,7 @@ theorem foldr_add (f : Fin (n + m) → α → α) (x) :
|
|||
| succ m ih => simp [foldr_succ_last, ih, ← Nat.add_assoc]
|
||||
|
||||
theorem foldr_eq_foldrM (f : Fin n → α → α) (x) :
|
||||
foldr n f x = foldrM (m:=Id) n f x := by
|
||||
foldr n f x = (foldrM (m := Id) n (pure <| f · ·) x).run := by
|
||||
induction n <;> simp [foldr_succ, foldrM_succ, *]
|
||||
|
||||
theorem foldl_rev (f : Fin n → α → α) (x) :
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ def foldlM {β : Type v} {m : Type v → Type w} [Monad m] (f : β → Float →
|
|||
|
||||
@[inline]
|
||||
def foldl {β : Type v} (f : β → Float → β) (init : β) (as : FloatArray) (start := 0) (stop := as.size) : β :=
|
||||
Id.run <| as.foldlM f init start stop
|
||||
Id.run <| as.foldlM (pure <| f · ·) init start stop
|
||||
|
||||
end FloatArray
|
||||
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ pointer-equal to its argument.
|
|||
For verification purposes, `List.mapMono = List.map`.
|
||||
-/
|
||||
def mapMono (as : List α) (f : α → α) : List α :=
|
||||
Id.run <| as.mapMonoM f
|
||||
Id.run <| as.mapMonoM (pure <| f ·)
|
||||
|
||||
/-! ## Additional lemmas required for bootstrapping `Array`. -/
|
||||
|
||||
|
|
|
|||
|
|
@ -348,9 +348,16 @@ theorem findM?_pure {m} [Monad m] [LawfulMonad m] (p : α → Bool) (as : List
|
|||
| false => simp [ih]
|
||||
|
||||
@[simp]
|
||||
theorem findM?_id (p : α → Bool) (as : List α) : findM? (m := Id) p as = as.find? p :=
|
||||
theorem idRun_findM? (p : α → Id Bool) (as : List α) :
|
||||
(findM? p as).run = as.find? (p · |>.run) :=
|
||||
findM?_pure _ _
|
||||
|
||||
@[deprecated idRun_findM? (since := "2025-05-21")]
|
||||
theorem findM?_id (p : α → Id Bool) (as : List α) :
|
||||
findM? (m := Id) p as = as.find? p :=
|
||||
findM?_pure _ _
|
||||
|
||||
|
||||
/--
|
||||
Returns the first non-`none` result of applying the monadic function `f` to each element of the
|
||||
list, in order. Returns `none` if `f` returns `none` for all elements.
|
||||
|
|
@ -394,7 +401,13 @@ theorem findSomeM?_pure [Monad m] [LawfulMonad m] {f : α → Option β} {as : L
|
|||
| none => simp [ih]
|
||||
|
||||
@[simp]
|
||||
theorem findSomeM?_id {f : α → Option β} {as : List α} : findSomeM? (m := Id) f as = as.findSome? f :=
|
||||
theorem idRun_findSomeM? (f : α → Id (Option β)) (as : List α) :
|
||||
(findSomeM? f as).run = as.findSome? (f · |>.run) :=
|
||||
findSomeM?_pure
|
||||
|
||||
@[deprecated idRun_findSomeM? (since := "2025-05-21")]
|
||||
theorem findSomeM?_id (f : α → Id (Option β)) (as : List α) :
|
||||
findSomeM? (m := Id) f as = as.findSome? f :=
|
||||
findSomeM?_pure
|
||||
|
||||
theorem findM?_eq_findSomeM? [Monad m] [LawfulMonad m] {p : α → m Bool} {as : List α} :
|
||||
|
|
|
|||
|
|
@ -2541,17 +2541,25 @@ theorem flatten_reverse {L : List (List α)} :
|
|||
induction l generalizing b <;> simp [*]
|
||||
|
||||
theorem foldl_eq_foldlM {f : β → α → β} {b : β} {l : List α} :
|
||||
l.foldl f b = l.foldlM (m := Id) f b := by
|
||||
induction l generalizing b <;> simp [*, foldl]
|
||||
l.foldl f b = (l.foldlM (m := Id) (pure <| f · ·) b).run := by
|
||||
simp
|
||||
|
||||
theorem foldr_eq_foldrM {f : α → β → β} {b : β} {l : List α} :
|
||||
l.foldr f b = l.foldrM (m := Id) f b := by
|
||||
induction l <;> simp [*, foldr]
|
||||
l.foldr f b = (l.foldrM (m := Id) (pure <| f · ·) b).run := by
|
||||
simp
|
||||
|
||||
@[simp] theorem id_run_foldlM {f : β → α → Id β} {b : β} {l : List α} :
|
||||
theorem idRun_foldlM {f : β → α → Id β} {b : β} {l : List α} :
|
||||
Id.run (l.foldlM f b) = l.foldl (f · · |>.run) b := foldl_eq_foldlM.symm
|
||||
|
||||
@[deprecated idRun_foldlM (since := "2025-05-21")]
|
||||
theorem id_run_foldlM {f : β → α → Id β} {b : β} {l : List α} :
|
||||
Id.run (l.foldlM f b) = l.foldl f b := foldl_eq_foldlM.symm
|
||||
|
||||
@[simp] theorem id_run_foldrM {f : α → β → Id β} {b : β} {l : List α} :
|
||||
theorem idRun_foldrM {f : α → β → Id β} {b : β} {l : List α} :
|
||||
Id.run (l.foldrM f b) = l.foldr (f · · |>.run) b := foldr_eq_foldrM.symm
|
||||
|
||||
@[deprecated idRun_foldrM (since := "2025-05-21")]
|
||||
theorem id_run_foldrM {f : α → β → Id β} {b : β} {l : List α} :
|
||||
Id.run (l.foldrM f b) = l.foldr f b := foldr_eq_foldrM.symm
|
||||
|
||||
@[simp] theorem foldlM_reverse [Monad m] {l : List α} {f : β → α → m β} {b : β} :
|
||||
|
|
@ -2646,10 +2654,10 @@ theorem foldr_map_hom {g : α → β} {f : α → α → α} {f' : β → β →
|
|||
induction l <;> simp [*]
|
||||
|
||||
@[simp, grind _=_] theorem foldl_append {β : Type _} {f : β → α → β} {b : β} {l l' : List α} :
|
||||
(l ++ l').foldl f b = l'.foldl f (l.foldl f b) := by simp [foldl_eq_foldlM]
|
||||
(l ++ l').foldl f b = l'.foldl f (l.foldl f b) := by simp [foldl_eq_foldlM, -foldlM_pure]
|
||||
|
||||
@[simp, grind _=_] theorem foldr_append {f : α → β → β} {b : β} {l l' : List α} :
|
||||
(l ++ l').foldr f b = l.foldr f (l'.foldr f b) := by simp [foldr_eq_foldrM]
|
||||
(l ++ l').foldr f b = l.foldr f (l'.foldr f b) := by simp [foldr_eq_foldrM, -foldrM_pure]
|
||||
|
||||
@[grind] theorem foldl_flatten {f : β → α → β} {b : β} {L : List (List α)} :
|
||||
(flatten L).foldl f b = L.foldl (fun b l => l.foldl f b) b := by
|
||||
|
|
@ -2660,7 +2668,8 @@ theorem foldr_map_hom {g : α → β} {f : α → α → α} {f' : β → β →
|
|||
induction L <;> simp_all
|
||||
|
||||
@[simp, grind] theorem foldl_reverse {l : List α} {f : β → α → β} {b : β} :
|
||||
l.reverse.foldl f b = l.foldr (fun x y => f y x) b := by simp [foldl_eq_foldlM, foldr_eq_foldrM]
|
||||
l.reverse.foldl f b = l.foldr (fun x y => f y x) b := by
|
||||
simp [foldl_eq_foldlM, foldr_eq_foldrM, -foldrM_pure]
|
||||
|
||||
@[simp, grind] theorem foldr_reverse {l : List α} {f : α → β → β} {b : β} :
|
||||
l.reverse.foldr f b = l.foldl (fun x y => f y x) b :=
|
||||
|
|
|
|||
|
|
@ -68,7 +68,11 @@ theorem mapM'_eq_mapM [Monad m] [LawfulMonad m] {f : α → m β} {l : List α}
|
|||
l.mapM (m := m) (pure <| f ·) = pure (l.map f) := by
|
||||
induction l <;> simp_all
|
||||
|
||||
@[simp] theorem mapM_id {l : List α} {f : α → Id β} : l.mapM f = l.map f :=
|
||||
@[simp] theorem idRun_mapM {l : List α} {f : α → Id β} : (l.mapM f).run = l.map (f · |>.run) :=
|
||||
mapM_pure
|
||||
|
||||
@[deprecated idRun_mapM (since := "2025-05-21")]
|
||||
theorem mapM_id {l : List α} {f : α → Id β} : (l.mapM f).run = l.map (f · |>.run) :=
|
||||
mapM_pure
|
||||
|
||||
@[simp] theorem mapM_map [Monad m] [LawfulMonad m] {f : α → β} {g : β → m γ} {l : List α} :
|
||||
|
|
@ -345,12 +349,18 @@ theorem forIn'_eq_foldlM [Monad m] [LawfulMonad m]
|
|||
simp only [forIn'_eq_foldlM]
|
||||
induction l.attach generalizing init <;> simp_all
|
||||
|
||||
@[simp] theorem forIn'_yield_eq_foldl
|
||||
@[simp] theorem idRun_forIn'_yield_eq_foldl
|
||||
(l : List α) (f : (a : α) → a ∈ l → β → Id β) (init : β) :
|
||||
(forIn' l init (fun a m b => .yield <$> f a m b)).run =
|
||||
l.attach.foldl (fun b ⟨a, h⟩ => f a h b |>.run) init :=
|
||||
forIn'_pure_yield_eq_foldl _ _
|
||||
|
||||
@[deprecated idRun_forIn'_yield_eq_foldl (since := "2025-05-21")]
|
||||
theorem forIn'_yield_eq_foldl
|
||||
{l : List α} (f : (a : α) → a ∈ l → β → β) (init : β) :
|
||||
forIn' (m := Id) l init (fun a m b => .yield (f a m b)) =
|
||||
l.attach.foldl (fun b ⟨a, h⟩ => f a h b) init := by
|
||||
simp only [forIn'_eq_foldlM]
|
||||
induction l.attach generalizing init <;> simp_all
|
||||
l.attach.foldl (fun b ⟨a, h⟩ => f a h b) init :=
|
||||
forIn'_pure_yield_eq_foldl _ _
|
||||
|
||||
@[simp] theorem forIn'_map [Monad m] [LawfulMonad m]
|
||||
{l : List α} (g : α → β) (f : (b : β) → b ∈ l.map g → γ → m (ForInStep γ)) :
|
||||
|
|
@ -398,12 +408,18 @@ theorem forIn_eq_foldlM [Monad m] [LawfulMonad m]
|
|||
simp only [forIn_eq_foldlM]
|
||||
induction l generalizing init <;> simp_all
|
||||
|
||||
@[simp] theorem forIn_yield_eq_foldl
|
||||
@[simp] theorem idRun_forIn_yield_eq_foldl
|
||||
(l : List α) (f : α → β → Id β) (init : β) :
|
||||
(forIn l init (fun a b => .yield <$> f a b)).run =
|
||||
l.foldl (fun b a => f a b |>.run) init :=
|
||||
forIn_pure_yield_eq_foldl _ _
|
||||
|
||||
@[deprecated idRun_forIn_yield_eq_foldl (since := "2025-05-21")]
|
||||
theorem forIn_yield_eq_foldl
|
||||
{l : List α} (f : α → β → β) (init : β) :
|
||||
forIn (m := Id) l init (fun a b => .yield (f a b)) =
|
||||
l.foldl (fun b a => f a b) init := by
|
||||
simp only [forIn_eq_foldlM]
|
||||
induction l generalizing init <;> simp_all
|
||||
l.foldl (fun b a => f a b) init :=
|
||||
forIn_pure_yield_eq_foldl _ _
|
||||
|
||||
@[simp] theorem forIn_map [Monad m] [LawfulMonad m]
|
||||
{l : List α} {g : α → β} {f : β → γ → m (ForInStep γ)} :
|
||||
|
|
|
|||
|
|
@ -173,7 +173,6 @@ theorem ofFnM_pure [Monad m] [LawfulMonad m] {n} {f : Fin n → α} :
|
|||
|
||||
@[simp, grind =] theorem idRun_ofFnM {f : Fin n → Id α} :
|
||||
Id.run (ofFnM f) = ofFn (fun i => Id.run (f i)) := by
|
||||
unfold Id.run
|
||||
induction n with
|
||||
| zero => simp
|
||||
| succ n ih => simp [-ofFn_succ, ofFnM_succ_last, ofFn_succ_last, ih]
|
||||
|
|
|
|||
|
|
@ -256,16 +256,16 @@ theorem findRevM?_toArray [Monad m] [LawfulMonad m] (f : α → m Bool) (l : Lis
|
|||
|
||||
@[simp, grind =] theorem findSome?_toArray (f : α → Option β) (l : List α) :
|
||||
l.toArray.findSome? f = l.findSome? f := by
|
||||
rw [Array.findSome?, ← findSomeM?_id, findSomeM?_toArray, Id.run]
|
||||
rw [Array.findSome?, findSomeM?_toArray, findSomeM?_pure, Id.run_pure]
|
||||
|
||||
@[simp, grind =] theorem find?_toArray (f : α → Bool) (l : List α) :
|
||||
l.toArray.find? f = l.find? f := by
|
||||
rw [Array.find?]
|
||||
simp only [Id.run, Id, Id.pure_eq, Id.bind_eq, forIn_toArray]
|
||||
simp only [forIn_toArray]
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons a l ih =>
|
||||
simp only [forIn_cons, Id.pure_eq, Id.bind_eq, find?]
|
||||
simp only [forIn_cons, find?]
|
||||
by_cases f a <;> simp_all
|
||||
|
||||
private theorem findFinIdx?_loop_toArray (w : l' = l.drop j) :
|
||||
|
|
|
|||
|
|
@ -90,11 +90,18 @@ theorem forIn'_eq_pelim [Monad m] [LawfulMonad m]
|
|||
pure (f := m) (o.pelim b (fun a h => f a h b)) := by
|
||||
cases o <;> simp
|
||||
|
||||
@[simp] theorem forIn'_id_yield_eq_pelim
|
||||
@[simp] theorem idRun_forIn'_yield_eq_pelim
|
||||
(o : Option α) (f : (a : α) → a ∈ o → β → Id β) (b : β) :
|
||||
(forIn' o b (fun a m b => .yield <$> f a m b)).run =
|
||||
o.pelim b (fun a h => f a h b |>.run) :=
|
||||
forIn'_pure_yield_eq_pelim _ _ _
|
||||
|
||||
@[deprecated idRun_forIn'_yield_eq_pelim (since := "2025-05-21")]
|
||||
theorem forIn'_id_yield_eq_pelim
|
||||
(o : Option α) (f : (a : α) → a ∈ o → β → β) (b : β) :
|
||||
forIn' (m := Id) o b (fun a m b => .yield (f a m b)) =
|
||||
o.pelim b (fun a h => f a h b) := by
|
||||
cases o <;> simp
|
||||
o.pelim b (fun a h => f a h b) :=
|
||||
forIn'_pure_yield_eq_pelim _ _ _
|
||||
|
||||
@[simp, grind] theorem forIn'_map [Monad m] [LawfulMonad m]
|
||||
(o : Option α) (g : α → β) (f : (b : β) → b ∈ o.map g → γ → m (ForInStep γ)) :
|
||||
|
|
@ -126,11 +133,18 @@ theorem forIn_eq_elim [Monad m] [LawfulMonad m]
|
|||
pure (f := m) (o.elim b (fun a => f a b)) := by
|
||||
cases o <;> simp
|
||||
|
||||
@[simp] theorem forIn_id_yield_eq_elim
|
||||
@[simp] theorem idRun_forIn_yield_eq_elim
|
||||
(o : Option α) (f : (a : α) → β → Id β) (b : β) :
|
||||
(forIn o b (fun a b => .yield <$> f a b)).run =
|
||||
o.elim b (fun a => f a b |>.run) :=
|
||||
forIn_pure_yield_eq_elim _ _ _
|
||||
|
||||
@[deprecated idRun_forIn_yield_eq_elim (since := "2025-05-21")]
|
||||
theorem forIn_id_yield_eq_elim
|
||||
(o : Option α) (f : (a : α) → β → β) (b : β) :
|
||||
forIn (m := Id) o b (fun a b => .yield (f a b)) =
|
||||
o.elim b (fun a => f a b) := by
|
||||
cases o <;> simp
|
||||
o.elim b (fun a => f a b) :=
|
||||
forIn_pure_yield_eq_elim _ _ _
|
||||
|
||||
@[simp, grind] theorem forIn_map [Monad m] [LawfulMonad m]
|
||||
(o : Option α) (g : α → β) (f : β → γ → m (ForInStep γ)) :
|
||||
|
|
|
|||
|
|
@ -2385,19 +2385,23 @@ theorem foldrM_pure [Monad m] [LawfulMonad m] {f : α → β → β} {b} {xs : V
|
|||
Array.foldrM_pure
|
||||
|
||||
theorem foldl_eq_foldlM {f : β → α → β} {b} {xs : Vector α n} :
|
||||
xs.foldl f b = xs.foldlM (m := Id) f b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldl_eq_foldlM]
|
||||
xs.foldl f b = (xs.foldlM (m := Id) (pure <| f · ·) b).run := rfl
|
||||
|
||||
theorem foldr_eq_foldrM {f : α → β → β} {b} {xs : Vector α n} :
|
||||
xs.foldr f b = xs.foldrM (m := Id) f b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldr_eq_foldrM]
|
||||
xs.foldr f b = (xs.foldrM (m := Id) (pure <| f · ·) b).run := rfl
|
||||
|
||||
@[simp] theorem id_run_foldlM {f : β → α → Id β} {b} {xs : Vector α n} :
|
||||
@[simp] theorem idRun_foldlM {f : β → α → Id β} {b} {xs : Vector α n} :
|
||||
Id.run (xs.foldlM f b) = xs.foldl (f · · |>.run) b := foldl_eq_foldlM.symm
|
||||
|
||||
@[deprecated idRun_foldlM (since := "2025-05-21")]
|
||||
theorem id_run_foldlM {f : β → α → Id β} {b} {xs : Vector α n} :
|
||||
Id.run (xs.foldlM f b) = xs.foldl f b := foldl_eq_foldlM.symm
|
||||
|
||||
@[simp] theorem id_run_foldrM {f : α → β → Id β} {b} {xs : Vector α n} :
|
||||
@[simp] theorem idRun_foldrM {f : α → β → Id β} {b} {xs : Vector α n} :
|
||||
Id.run (xs.foldrM f b) = xs.foldr (f · · |>.run) b := foldr_eq_foldrM.symm
|
||||
|
||||
@[deprecated idRun_foldrM (since := "2025-05-21")]
|
||||
theorem id_run_foldrM {f : α → β → Id β} {b} {xs : Vector α n} :
|
||||
Id.run (xs.foldrM f b) = xs.foldr f b := foldr_eq_foldrM.symm
|
||||
|
||||
@[simp] theorem foldlM_reverse [Monad m] {xs : Vector α n} {f : β → α → m β} {b} :
|
||||
|
|
@ -2485,10 +2489,10 @@ theorem foldr_map_hom {g : α → β} {f : α → α → α} {f' : β → β →
|
|||
simp
|
||||
|
||||
@[simp, grind _=_] theorem foldl_append {β : Type _} {f : β → α → β} {b} {xs : Vector α n} {ys : Vector α k} :
|
||||
(xs ++ ys).foldl f b = ys.foldl f (xs.foldl f b) := by simp [foldl_eq_foldlM]
|
||||
(xs ++ ys).foldl f b = ys.foldl f (xs.foldl f b) := foldlM_append
|
||||
|
||||
@[simp, grind _=_] theorem foldr_append {f : α → β → β} {b} {xs : Vector α n} {ys : Vector α k} :
|
||||
(xs ++ ys).foldr f b = xs.foldr f (ys.foldr f b) := by simp [foldr_eq_foldrM]
|
||||
(xs ++ ys).foldr f b = xs.foldr f (ys.foldr f b) := foldrM_append
|
||||
|
||||
@[simp, grind] theorem foldl_flatten {f : β → α → β} {b} {xss : Vector (Vector α m) n} :
|
||||
(flatten xss).foldl f b = xss.foldl (fun b xs => xs.foldl f b) b := by
|
||||
|
|
@ -2501,7 +2505,8 @@ theorem foldr_map_hom {g : α → β} {f : α → α → α} {f' : β → β →
|
|||
simp [Array.foldr_flatten', Array.foldr_map']
|
||||
|
||||
@[simp, grind] theorem foldl_reverse {xs : Vector α n} {f : β → α → β} {b} :
|
||||
xs.reverse.foldl f b = xs.foldr (fun x y => f y x) b := by simp [foldl_eq_foldlM, foldr_eq_foldrM]
|
||||
xs.reverse.foldl f b = xs.foldr (fun x y => f y x) b :=
|
||||
foldlM_reverse
|
||||
|
||||
@[simp, grind] theorem foldr_reverse {xs : Vector α n} {f : α → β → β} {b} :
|
||||
xs.reverse.foldr f b = xs.foldl (fun x y => f y x) b :=
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ protected theorem not_le_iff_gt [DecidableEq α] [LT α] [DecidableLT α] {xs ys
|
|||
|
||||
@[simp] theorem singleton_lex_singleton [BEq α] {lt : α → α → Bool} : #v[a].lex #v[b] lt = lt a b := by
|
||||
simp only [lex, getElem_mk, List.getElem_toArray, List.getElem_singleton]
|
||||
cases lt a b <;> cases a != b <;> simp [Id.run]
|
||||
cases lt a b <;> cases a != b <;> simp
|
||||
|
||||
protected theorem lt_irrefl [LT α] [Std.Irrefl (· < · : α → α → Prop)] (xs : Vector α n) : ¬ xs < xs :=
|
||||
Array.lt_irrefl xs.toArray
|
||||
|
|
|
|||
|
|
@ -148,12 +148,18 @@ theorem forIn'_eq_foldlM [Monad m] [LawfulMonad m]
|
|||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.forIn'_pure_yield_eq_foldl, Array.foldl_map]
|
||||
|
||||
@[simp] theorem forIn'_yield_eq_foldl
|
||||
@[simp] theorem idRun_forIn'_yield_eq_foldl
|
||||
{xs : Vector α n} (f : (a : α) → a ∈ xs → β → Id β) (init : β) :
|
||||
(forIn' xs init (fun a m b => .yield <$> f a m b)).run =
|
||||
xs.attach.foldl (fun b ⟨a, h⟩ => f a h b |>.run) init :=
|
||||
forIn'_pure_yield_eq_foldl _ _
|
||||
|
||||
@[deprecated forIn'_yield_eq_foldl (since := "2025-05-21")]
|
||||
theorem forIn'_yield_eq_foldl
|
||||
{xs : Vector α n} (f : (a : α) → a ∈ xs → β → β) (init : β) :
|
||||
forIn' (m := Id) xs init (fun a m b => .yield (f a m b)) =
|
||||
xs.attach.foldl (fun b ⟨a, h⟩ => f a h b) init := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [List.foldl_map]
|
||||
xs.attach.foldl (fun b ⟨a, h⟩ => f a h b) init :=
|
||||
forIn'_pure_yield_eq_foldl _ _
|
||||
|
||||
@[simp] theorem forIn'_map [Monad m] [LawfulMonad m]
|
||||
{xs : Vector α n} (g : α → β) (f : (b : β) → b ∈ xs.map g → γ → m (ForInStep γ)) :
|
||||
|
|
@ -190,12 +196,18 @@ theorem forIn_eq_foldlM [Monad m] [LawfulMonad m]
|
|||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.forIn_pure_yield_eq_foldl, Array.foldl_map]
|
||||
|
||||
@[simp] theorem forIn_yield_eq_foldl
|
||||
@[simp] theorem idRun_forIn_yield_eq_foldl
|
||||
{xs : Vector α n} (f : α → β → Id β) (init : β) :
|
||||
(forIn xs init (fun a b => .yield <$> f a b)).run =
|
||||
xs.foldl (fun b a => f a b |>.run) init :=
|
||||
forIn_pure_yield_eq_foldl _ _
|
||||
|
||||
@[deprecated idRun_forIn_yield_eq_foldl (since := "2025-05-21")]
|
||||
theorem forIn_yield_eq_foldl
|
||||
{xs : Vector α n} (f : α → β → β) (init : β) :
|
||||
forIn (m := Id) xs init (fun a b => .yield (f a b)) =
|
||||
xs.foldl (fun b a => f a b) init := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp
|
||||
xs.foldl (fun b a => f a b) init :=
|
||||
forIn_pure_yield_eq_foldl _ _
|
||||
|
||||
@[simp] theorem forIn_map [Monad m] [LawfulMonad m]
|
||||
{xs : Vector α n} (g : α → β) (f : β → γ → m (ForInStep γ)) :
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ theorem ofFnM_pure [Monad m] [LawfulMonad m] {n} {f : Fin n → α} :
|
|||
|
||||
@[simp, grind =] theorem idRun_ofFnM {f : Fin n → Id α} :
|
||||
Id.run (ofFnM f) = ofFn (fun i => Id.run (f i)) := by
|
||||
unfold Id.run
|
||||
induction n with
|
||||
| zero => simp
|
||||
| succ n ih => simp [ofFnM_succ', ofFn_succ', ih]
|
||||
|
|
|
|||
|
|
@ -1317,7 +1317,7 @@ test with the predicate `p`. The resulting array contains the tested elements fo
|
|||
`true`, separated by the corresponding separator elements.
|
||||
-/
|
||||
def filterSepElems (a : Array Syntax) (p : Syntax → Bool) : Array Syntax :=
|
||||
Id.run <| a.filterSepElemsM p
|
||||
Id.run <| a.filterSepElemsM (pure <| p ·)
|
||||
|
||||
private partial def mapSepElemsMAux {m : Type → Type} [Monad m] (a : Array Syntax) (f : Syntax → m Syntax) (i : Nat) (acc : Array Syntax) : m (Array Syntax) := do
|
||||
if h : i < a.size then
|
||||
|
|
@ -1334,7 +1334,7 @@ def mapSepElemsM {m : Type → Type} [Monad m] (a : Array Syntax) (f : Syntax
|
|||
mapSepElemsMAux a f 0 #[]
|
||||
|
||||
def mapSepElems (a : Array Syntax) (f : Syntax → Syntax) : Array Syntax :=
|
||||
Id.run <| a.mapSepElemsM f
|
||||
Id.run <| a.mapSepElemsM (pure <| f ·)
|
||||
|
||||
end Array
|
||||
|
||||
|
|
|
|||
|
|
@ -205,9 +205,9 @@ where
|
|||
if !(← f fvar) then failure
|
||||
|
||||
def anyFVar [TraverseFVar α] (f : FVarId → Bool) (x : α) : Bool :=
|
||||
Id.run <| anyFVarM f x
|
||||
Id.run <| anyFVarM (pure <| f ·) x
|
||||
|
||||
def allFVar [TraverseFVar α] (f : FVarId → Bool) (x : α) : Bool :=
|
||||
Id.run <| allFVarM f x
|
||||
Id.run <| allFVarM (pure <| f ·) x
|
||||
|
||||
end Lean.Compiler.LCNF
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ def isEmpty : AssocList α β → Bool
|
|||
foldlM f d es
|
||||
|
||||
@[inline] def foldl (f : δ → α → β → δ) (init : δ) (as : AssocList α β) : δ :=
|
||||
Id.run (foldlM f init as)
|
||||
Id.run (foldlM (pure <| f · · ·) init as)
|
||||
|
||||
def toList (as : AssocList α β) : List (α × β) :=
|
||||
as.foldl (init := []) (fun r a b => (a, b)::r) |>.reverse
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ def NameTrie.forM [Monad m] (t : NameTrie β) (f : β → m Unit) : m Unit :=
|
|||
t.forMatchingM Name.anonymous f
|
||||
|
||||
def NameTrie.matchingToArray (t : NameTrie β) (k : Name) : Array β :=
|
||||
Id.run <| t.foldMatchingM k #[] fun v acc => acc.push v
|
||||
Id.run <| t.foldMatchingM k #[] fun v acc => return acc.push v
|
||||
|
||||
def NameTrie.toArray (t : NameTrie β) : Array β :=
|
||||
Id.run <| t.foldM #[] fun v acc => acc.push v
|
||||
Id.run <| t.foldM #[] fun v acc => return acc.push v
|
||||
|
||||
end Lean
|
||||
|
|
|
|||
|
|
@ -281,10 +281,10 @@ instance : ForIn m (PersistentArray α) α where
|
|||
end
|
||||
|
||||
@[inline] def foldl (t : PersistentArray α) (f : β → α → β) (init : β) (start : Nat := 0) : β :=
|
||||
Id.run <| t.foldlM f init start
|
||||
Id.run <| t.foldlM (pure <| f · ·) init start
|
||||
|
||||
@[inline] def foldr (t : PersistentArray α) (f : α → β → β) (init : β) : β :=
|
||||
Id.run <| t.foldrM f init
|
||||
Id.run <| t.foldrM (pure <| f · ·) init
|
||||
|
||||
@[inline] def filter (as : PersistentArray α) (p : α → Bool) : PersistentArray α :=
|
||||
as.foldl (init := {}) fun asNew a => if p a then asNew.push a else asNew
|
||||
|
|
@ -301,10 +301,10 @@ def append (t₁ t₂ : PersistentArray α) : PersistentArray α :=
|
|||
instance : Append (PersistentArray α) := ⟨append⟩
|
||||
|
||||
@[inline] def findSome? {β} (t : PersistentArray α) (f : α → (Option β)) : Option β :=
|
||||
Id.run $ t.findSomeM? f
|
||||
Id.run $ t.findSomeM? (pure <| f ·)
|
||||
|
||||
@[inline] def findSomeRev? {β} (t : PersistentArray α) (f : α → (Option β)) : Option β :=
|
||||
Id.run $ t.findSomeRevM? f
|
||||
Id.run $ t.findSomeRevM? (pure <| f ·)
|
||||
|
||||
def toList (t : PersistentArray α) : List α :=
|
||||
(t.foldl (init := []) fun xs x => x :: xs).reverse
|
||||
|
|
@ -325,7 +325,7 @@ variable {m : Type → Type w} [Monad m]
|
|||
end
|
||||
|
||||
@[inline] def any (a : PersistentArray α) (p : α → Bool) : Bool :=
|
||||
Id.run $ anyM a p
|
||||
Id.run $ anyM a (pure <| p ·)
|
||||
|
||||
@[inline] def all (a : PersistentArray α) (p : α → Bool) : Bool :=
|
||||
!any a fun v => !p v
|
||||
|
|
@ -346,7 +346,7 @@ variable {β : Type u}
|
|||
end
|
||||
|
||||
@[inline] def map {β} (f : α → β) (t : PersistentArray α) : PersistentArray β :=
|
||||
Id.run $ t.mapM f
|
||||
Id.run $ t.mapM (pure <| f ·)
|
||||
|
||||
structure Stats where
|
||||
numNodes : Nat
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ def forM {_ : BEq α} {_ : Hashable α} (map : PersistentHashMap α β) (f : α
|
|||
map.foldlM (fun _ => f) ⟨⟩
|
||||
|
||||
def foldl {_ : BEq α} {_ : Hashable α} (map : PersistentHashMap α β) (f : σ → α → β → σ) (init : σ) : σ :=
|
||||
Id.run <| map.foldlM f init
|
||||
Id.run <| map.foldlM (pure <| f · · ·) init
|
||||
|
||||
protected def forIn {_ : BEq α} {_ : Hashable α} [Monad m]
|
||||
(map : PersistentHashMap α β) (init : σ) (f : α × β → σ → m (ForInStep σ)) : m σ := do
|
||||
|
|
@ -322,7 +322,7 @@ def mapM {α : Type u} {β : Type v} {σ : Type u} {m : Type u → Type w} [Mona
|
|||
return { root }
|
||||
|
||||
def map {α : Type u} {β : Type v} {σ : Type u} {_ : BEq α} {_ : Hashable α} (pm : PersistentHashMap α β) (f : β → σ) : PersistentHashMap α σ :=
|
||||
Id.run <| pm.mapM f
|
||||
Id.run <| pm.mapM (pure <| f ·)
|
||||
|
||||
def toList {_ : BEq α} {_ : Hashable α} (m : PersistentHashMap α β) : List (α × β) :=
|
||||
m.foldl (init := []) fun ps k v => (k, v) :: ps
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ variable {_ : BEq α} {_ : Hashable α}
|
|||
s.set.foldlM (init := init) fun d a _ => f d a
|
||||
|
||||
@[inline] def fold {β : Type v} (f : β → α → β) (init : β) (s : PersistentHashSet α) : β :=
|
||||
Id.run $ s.foldM f init
|
||||
Id.run $ s.foldM (pure <| f · ·) init
|
||||
|
||||
def toList (s : PersistentHashSet α) : List α :=
|
||||
s.set.toList.map (·.1)
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ def SnapshotTree.runAndReport (s : SnapshotTree) (opts : Options)
|
|||
|
||||
/-- Waits on and returns all snapshots in the tree. -/
|
||||
def SnapshotTree.getAll (s : SnapshotTree) : Array Snapshot :=
|
||||
Id.run <| s.foldM (·.push ·) #[]
|
||||
Id.run <| s.foldM (pure <| ·.push ·) #[]
|
||||
|
||||
/-- Returns a task that waits on all snapshots in the tree. -/
|
||||
def SnapshotTree.waitAll : SnapshotTree → BaseIO (Task Unit)
|
||||
|
|
|
|||
|
|
@ -397,19 +397,19 @@ instance : ForIn m LocalContext LocalDecl where
|
|||
| some d => f d b
|
||||
|
||||
@[inline] def foldl (lctx : LocalContext) (f : β → LocalDecl → β) (init : β) (start : Nat := 0) : β :=
|
||||
Id.run <| lctx.foldlM f init start
|
||||
Id.run <| lctx.foldlM (pure <| f · ·) init start
|
||||
|
||||
@[inline] def foldr (lctx : LocalContext) (f : LocalDecl → β → β) (init : β) : β :=
|
||||
Id.run <| lctx.foldrM f init
|
||||
Id.run <| lctx.foldrM (pure <| f · ·) init
|
||||
|
||||
def size (lctx : LocalContext) : Nat :=
|
||||
lctx.foldl (fun n _ => n+1) 0
|
||||
|
||||
@[inline] def findDecl? (lctx : LocalContext) (f : LocalDecl → Option β) : Option β :=
|
||||
Id.run <| lctx.findDeclM? f
|
||||
Id.run <| lctx.findDeclM? (pure <| f ·)
|
||||
|
||||
@[inline] def findDeclRev? (lctx : LocalContext) (f : LocalDecl → Option β) : Option β :=
|
||||
Id.run <| lctx.findDeclRevM? f
|
||||
Id.run <| lctx.findDeclRevM? (pure <| f ·)
|
||||
|
||||
partial def isSubPrefixOfAux (a₁ a₂ : PArray (Option LocalDecl)) (exceptFVars : Array Expr) (i j : Nat) : Bool :=
|
||||
if h : i < a₁.size then
|
||||
|
|
@ -473,11 +473,11 @@ def mkForall (lctx : LocalContext) (xs : Array Expr) (b : Expr) : Expr :=
|
|||
|
||||
/-- Return `true` if `lctx` contains a local declaration satisfying `p`. -/
|
||||
@[inline] def any (lctx : LocalContext) (p : LocalDecl → Bool) : Bool :=
|
||||
Id.run <| lctx.anyM p
|
||||
Id.run <| lctx.anyM (pure <| p ·)
|
||||
|
||||
/-- Return `true` if all declarations in `lctx` satisfy `p`. -/
|
||||
@[inline] def all (lctx : LocalContext) (p : LocalDecl → Bool) : Bool :=
|
||||
Id.run <| lctx.allM p
|
||||
Id.run <| lctx.allM (pure <| p ·)
|
||||
|
||||
/-- If option `pp.sanitizeNames` is set to `true`, add tombstone to shadowed local declaration names and ones contains macroscopes. -/
|
||||
def sanitizeNames (lctx : LocalContext) : StateM NameSanitizerState LocalContext := do
|
||||
|
|
|
|||
|
|
@ -795,7 +795,7 @@ Fold the values stored in a `Trie`.
|
|||
-/
|
||||
@[inline]
|
||||
def foldValues (f : σ → α → σ) (init : σ) (t : Trie α) : σ :=
|
||||
Id.run <| t.foldValuesM (init := init) f
|
||||
Id.run <| t.foldValuesM (init := init) (pure <| f · ·)
|
||||
|
||||
/--
|
||||
The number of values stored in a `Trie`.
|
||||
|
|
@ -835,7 +835,7 @@ Fold over the values stored in a `DiscrTree`.
|
|||
-/
|
||||
@[inline]
|
||||
def foldValues (f : σ → α → σ) (init : σ) (t : DiscrTree α) : σ :=
|
||||
Id.run <| t.foldValuesM (init := init) f
|
||||
Id.run <| t.foldValuesM (init := init) (pure <| f · ·)
|
||||
|
||||
/--
|
||||
Check for the presence of a value satisfying a predicate.
|
||||
|
|
|
|||
|
|
@ -1975,7 +1975,7 @@ def foldArgsM (s : Syntax) (f : Syntax → β → m β) (b : β) : m β :=
|
|||
s.getArgs.foldlM (flip f) b
|
||||
|
||||
def foldArgs (s : Syntax) (f : Syntax → β → β) (b : β) : β :=
|
||||
Id.run (s.foldArgsM f b)
|
||||
Id.run (s.foldArgsM (pure <| f · ·) b)
|
||||
|
||||
def forArgsM (s : Syntax) (f : Syntax → m Unit) : m Unit :=
|
||||
s.foldArgsM (fun s _ => f s) ()
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ private partial def mkErrorMessage (c : InputContext) (pos : String.Pos) (stk :
|
|||
where
|
||||
-- Error recovery might lead to there being some "junk" on the stack
|
||||
lastTrailing (s : SyntaxStack) : Option Substring :=
|
||||
s.toSubarray.findSomeRevM? (m := Id) fun stx =>
|
||||
Id.run <| s.toSubarray.findSomeRevM? fun stx =>
|
||||
if let .original (trailing := trailing) .. := stx.getTailInfo then pure (some trailing)
|
||||
else none
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ def getEligibleHeaderDecls (env : Environment) : IO EligibleHeaderDecls := do
|
|||
eligibleHeaderDeclsRef.modifyGet fun
|
||||
| some eligibleHeaderDecls => (eligibleHeaderDecls, some eligibleHeaderDecls)
|
||||
| none =>
|
||||
let (_, eligibleHeaderDecls) :=
|
||||
StateT.run (m := Id) (s := {}) do
|
||||
let (_, eligibleHeaderDecls) := Id.run <|
|
||||
StateT.run (s := {}) do
|
||||
-- `map₁` are the header decls
|
||||
env.constants.map₁.forM fun declName c => do
|
||||
modify fun eligibleHeaderDecls =>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ private def findBest?
|
|||
(gt : α → α → Bool)
|
||||
(f : ContextInfo → Info → PersistentArray InfoTree → Option α)
|
||||
: Option α :=
|
||||
infoTree.visitM (m := Id) (postNode := choose) |>.join
|
||||
(Id.run <| infoTree.visitM (postNode := choose)).join
|
||||
where
|
||||
choose
|
||||
(ctx : ContextInfo)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ def InfoTree.collectNodesBottomUpM [Monad m] (p : ContextInfo → Info → Persi
|
|||
/--
|
||||
Visit nodes bottom-up, passing in a surrounding context (the innermost one) and the union of nested results (empty at leaves). -/
|
||||
def InfoTree.collectNodesBottomUp (p : ContextInfo → Info → PersistentArray InfoTree → List α → List α) (i : InfoTree) : List α :=
|
||||
i.collectNodesBottomUpM (m := Id) p
|
||||
Id.run <| i.collectNodesBottomUpM (pure <| p · · · ·)
|
||||
|
||||
/--
|
||||
For every branch of the `InfoTree`, find the deepest node in that branch for which `p` returns
|
||||
|
|
@ -97,7 +97,7 @@ partial def InfoTree.deepestNodesM [Monad m] (p : ContextInfo → Info → Persi
|
|||
`some _` and return the union of all such nodes. The visitor `p` is given a node together with
|
||||
its innermost surrounding `ContextInfo`. -/
|
||||
partial def InfoTree.deepestNodes (p : ContextInfo → Info → PersistentArray InfoTree → Option α) (infoTree : InfoTree) : List α :=
|
||||
infoTree.deepestNodesM (m := Id) p
|
||||
Id.run <| infoTree.deepestNodesM (pure <| p · · ·)
|
||||
|
||||
partial def InfoTree.foldInfo (f : ContextInfo → Info → α → α) (init : α) : InfoTree → α :=
|
||||
go none init
|
||||
|
|
@ -237,7 +237,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`. -/
|
||||
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 (postNode := fun ctx info children results => do
|
||||
let mut results := results.flatMap (·.getD [])
|
||||
if omitAppFns && info.stx.isOfKind ``Parser.Term.app && info.stx[0].isIdent then
|
||||
results := results.filter (·.2.info.stx != info.stx[0])
|
||||
|
|
@ -267,7 +267,7 @@ partial def InfoTree.hoverableInfoAt? (t : InfoTree) (hoverPos : String.Pos) (in
|
|||
Int.negOfNat (r.stop - r.start).byteIdx,
|
||||
-- prefer results for constants over variables (which overlap at declaration names)
|
||||
if info matches .ofTermInfo { expr := .fvar .., .. } then 0 else 1)
|
||||
[(priority, {ctx, info, children})]) |>.getD []
|
||||
[(priority, {ctx, info, children})])) |>.getD []
|
||||
-- sort results by lexicographical priority
|
||||
let maxPrio? :=
|
||||
let _ := @lexOrd
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ def depth (p : Pos) :=
|
|||
|
||||
/-- Returns true if `pred` is true for each coordinate in `p`.-/
|
||||
def all (pred : Nat → Bool) (p : Pos) : Bool :=
|
||||
OptionT.run (m := Id) (foldrM (fun n a => if pred n then pure a else failure) p ()) |>.isSome
|
||||
(Id.run <| OptionT.run (foldrM (fun n a => if pred n then pure a else failure) p ())) |>.isSome
|
||||
|
||||
def append : Pos → Pos → Pos := foldl push
|
||||
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ partial def hasIdent (id : Name) : Syntax → Bool
|
|||
| stx => fn stx
|
||||
|
||||
@[inline] def rewriteBottomUp (fn : Syntax → Syntax) (stx : Syntax) : Syntax :=
|
||||
Id.run <| stx.rewriteBottomUpM fn
|
||||
Id.run <| stx.rewriteBottomUpM (pure <| fn ·)
|
||||
|
||||
private def updateInfo : SourceInfo → String.Pos → String.Pos → SourceInfo
|
||||
| SourceInfo.original lead pos trail endPos, leadStart, trailStop =>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace AssocList
|
|||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
@[inline] def foldl (f : δ → (α : α) → β α → δ) (init : δ) (as : AssocList α β) : δ :=
|
||||
Id.run (foldlM f init as)
|
||||
Id.run (foldlM (pure <| f · · ·) init as)
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
@[specialize] def foldrM (f : (a : α) → β a → δ → m δ) : (init : δ) → AssocList α β → m δ
|
||||
|
|
@ -60,7 +60,7 @@ namespace AssocList
|
|||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
@[inline] def foldr (f : (a : α) → β a → δ → δ) (init : δ) (as : AssocList α β) : δ :=
|
||||
Id.run (foldrM f init as)
|
||||
Id.run (foldrM (pure <| f · · ·) init as)
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
@[inline] def forM (f : (a : α) → β a → m PUnit) (as : AssocList α β) : m PUnit :=
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ open Std.Internal
|
|||
@[simp]
|
||||
theorem foldl_eq {f : δ → (a : α) → β a → δ} {init : δ} {l : AssocList α β} :
|
||||
l.foldl f init = l.toList.foldl (fun d p => f d p.1 p.2) init := by
|
||||
induction l generalizing init <;> simp_all [foldl, Id.run, foldlM]
|
||||
induction l generalizing init <;> simp_all [foldl, foldlM]
|
||||
|
||||
@[simp]
|
||||
theorem length_eq {l : AssocList α β} : l.length = l.toList.length := by
|
||||
|
|
@ -260,11 +260,11 @@ end Const
|
|||
theorem foldl_apply {l : AssocList α β} {acc : List δ} (f : (a : α) → β a → δ) :
|
||||
l.foldl (fun acc k v => f k v :: acc) acc =
|
||||
(l.toList.map (fun p => f p.1 p.2)).reverse ++ acc := by
|
||||
induction l generalizing acc <;> simp_all [AssocList.foldl, AssocList.foldlM, Id.run]
|
||||
induction l generalizing acc <;> simp_all [AssocList.foldl, AssocList.foldlM]
|
||||
|
||||
theorem foldr_apply {l : AssocList α β} {acc : List δ} (f : (a : α) → β a → δ) :
|
||||
l.foldr (fun k v acc => f k v :: acc) acc =
|
||||
(l.toList.map (fun p => f p.1 p.2)) ++ acc := by
|
||||
induction l generalizing acc <;> simp_all [AssocList.foldr, AssocList.foldrM, Id.run]
|
||||
induction l generalizing acc <;> simp_all [AssocList.foldr, AssocList.foldrM]
|
||||
|
||||
end Std.DHashMap.Internal.AssocList
|
||||
|
|
|
|||
|
|
@ -596,7 +596,7 @@ theorem filter_eq_filterₘ (m : Raw₀ α β) (f : (a : α) → β a → Bool)
|
|||
m.filter f = m.filterₘ f := rfl
|
||||
|
||||
theorem insertMany_eq_insertListₘ [BEq α] [Hashable α] (m : Raw₀ α β) (l : List ((a : α) × β a)) : insertMany m l = insertListₘ m l := by
|
||||
simp only [insertMany, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
simp only [insertMany, Id.run_pure, Id.run_bind, pure_bind, List.forIn_pure_yield_eq_foldl]
|
||||
suffices ∀ (t : { m' // ∀ (P : Raw₀ α β → Prop),
|
||||
(∀ {m'' : Raw₀ α β} {a : α} {b : β a}, P m'' → P (m''.insert a b)) → P m → P m' }),
|
||||
(List.foldl (fun m' p => ⟨m'.val.insert p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
|
||||
|
|
@ -639,9 +639,9 @@ theorem Const.getThenInsertIfNew?_eq_get?ₘ [BEq α] [Hashable α] (m : Raw₀
|
|||
split <;> simp_all [-getValue?_eq_none]
|
||||
|
||||
theorem Const.insertMany_eq_insertListₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => β))
|
||||
(l: List (α × β)):
|
||||
(l : List (α × β)) :
|
||||
(Const.insertMany m l).1 = Const.insertListₘ m l := by
|
||||
simp only [insertMany, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
simp only [insertMany, Id.run_pure, pure_bind, List.forIn_pure_yield_eq_foldl]
|
||||
suffices ∀ (t : { m' // ∀ (P : Raw₀ α (fun _ => β) → Prop),
|
||||
(∀ {m'' : Raw₀ α (fun _ => β)} {a : α} {b : β}, P m'' → P (m''.insert a b)) → P m → P m' }),
|
||||
(List.foldl (fun m' p => ⟨m'.val.insert p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
|
||||
|
|
@ -656,7 +656,7 @@ theorem Const.insertMany_eq_insertListₘ [BEq α] [Hashable α] (m : Raw₀ α
|
|||
theorem Const.insertManyIfNewUnit_eq_insertListIfNewUnitₘ [BEq α] [Hashable α]
|
||||
(m : Raw₀ α (fun _ => Unit)) (l: List α):
|
||||
(Const.insertManyIfNewUnit m l).1 = Const.insertListIfNewUnitₘ m l := by
|
||||
simp only [insertManyIfNewUnit, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
simp only [insertManyIfNewUnit, Id.run_pure, Id.run_bind, pure_bind, List.forIn_pure_yield_eq_foldl]
|
||||
suffices ∀ (t : { m' // ∀ (P : Raw₀ α (fun _ => Unit) → Prop),
|
||||
(∀ {m'' a b}, P m'' → P (m''.insertIfNew a b)) → P m → P m'}),
|
||||
(List.foldl (fun m' p => ⟨m'.val.insertIfNew p (), fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
|
||||
|
|
|
|||
|
|
@ -1210,12 +1210,12 @@ theorem insertMany_ind {motive : Raw₀ α β → Prop} (m : Raw₀ α β) (l :
|
|||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
m.insertMany [] = m := by
|
||||
simp [insertMany, Id.run]
|
||||
simp [insertMany]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β k} :
|
||||
m.insertMany [⟨k, v⟩] = m.insert k v := by
|
||||
simp [insertMany, Id.run]
|
||||
simp [insertMany]
|
||||
|
||||
theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} :
|
||||
(m.insertMany (⟨k, v⟩ :: l)).1 = ((m.insert k v).insertMany l).1 := by
|
||||
|
|
@ -1412,12 +1412,12 @@ theorem insertMany_ind {motive : Raw₀ α (fun _ => β) → Prop} (m : Raw₀
|
|||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
insertMany m [] = m := by
|
||||
simp [insertMany, Id.run]
|
||||
simp [insertMany]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β} :
|
||||
insertMany m [⟨k, v⟩] = m.insert k v := by
|
||||
simp [insertMany, Id.run]
|
||||
simp [insertMany]
|
||||
|
||||
theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} :
|
||||
(insertMany m (⟨k, v⟩ :: l)).1 = (insertMany (m.insert k v) l).1 := by
|
||||
|
|
@ -1613,12 +1613,12 @@ theorem insertManyIfNewUnit_ind {motive : Raw₀ α (fun _ => Unit) → Prop}
|
|||
@[simp]
|
||||
theorem insertManyIfNewUnit_nil :
|
||||
insertManyIfNewUnit m [] = m := by
|
||||
simp [insertManyIfNewUnit, Id.run]
|
||||
simp [insertManyIfNewUnit]
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_list_singleton {k : α} :
|
||||
insertManyIfNewUnit m [k] = m.insertIfNew k () := by
|
||||
simp [insertManyIfNewUnit, Id.run]
|
||||
simp [insertManyIfNewUnit]
|
||||
|
||||
theorem insertManyIfNewUnit_cons {l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m (k :: l)).1 = (insertManyIfNewUnit (m.insertIfNew k ()) l).1 := by
|
||||
|
|
|
|||
|
|
@ -69,9 +69,7 @@ theorem isEmpty_eq_isEmpty [BEq α] [Hashable α] {m : Raw α β} (h : Raw.WFImp
|
|||
Nat.beq_eq_true_eq]
|
||||
|
||||
theorem fold_eq {l : Raw α β} {f : γ → (a : α) → β a → γ} {init : γ} :
|
||||
l.fold f init = l.buckets.foldl (fun acc l => l.foldl f acc) init := by
|
||||
simp only [Raw.fold, Raw.foldM, ← Array.foldlM_toList, Array.foldl_toList,
|
||||
← List.foldl_eq_foldlM, Id.run, AssocList.foldl]
|
||||
l.fold f init = l.buckets.foldl (fun acc l => l.foldl f acc) init := rfl
|
||||
|
||||
theorem fold_cons_apply {l : Raw α β} {acc : List γ} (f : (a : α) → β a → γ) :
|
||||
l.fold (fun acc k v => f k v :: acc) acc =
|
||||
|
|
@ -94,8 +92,7 @@ theorem fold_cons_key {l : Raw α β} {acc : List α} :
|
|||
theorem foldRev_eq {l : Raw α β} {f : γ → (a : α) → β a → γ} {init : γ} :
|
||||
Raw.Internal.foldRev f init l =
|
||||
l.buckets.foldr (fun l acc => l.foldr (fun a b g => f g a b) acc) init := by
|
||||
simp only [Raw.Internal.foldRev, Raw.Internal.foldRevM, ← Array.foldrM_toList, Array.foldr_toList,
|
||||
← List.foldr_eq_foldrM, Id.run, AssocList.foldr]
|
||||
simp only [Raw.Internal.foldRev, Raw.Internal.foldRevM, Array.id_run_foldrM, AssocList.foldr]
|
||||
|
||||
theorem foldRev_cons_apply {l : Raw α β} {acc : List γ} (f : (a : α) → β a → γ) :
|
||||
Raw.Internal.foldRev (fun acc k v => f k v :: acc) acc l =
|
||||
|
|
@ -261,7 +258,7 @@ theorem isHashSelf_foldl_reinsertAux [BEq α] [Hashable α] [EquivBEq α] [Lawfu
|
|||
IsHashSelf target.1 →
|
||||
IsHashSelf (l.foldl (fun acc p => reinsertAux hash acc p.1 p.2) target).1 := by
|
||||
induction l generalizing target
|
||||
· simp [Id.run]
|
||||
· simp
|
||||
· next k v _ ih => exact fun h => ih _ (isHashSelf_reinsertAux _ _ _ h)
|
||||
|
||||
theorem toListModel_foldl_reinsertAux [BEq α] [Hashable α] [PartialEquivBEq α]
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ map in some order.
|
|||
|
||||
/-- Folds the given function over the mappings in the hash map in some order. -/
|
||||
@[inline] def fold (f : δ → (a : α) → β a → δ) (init : δ) (b : Raw α β) : δ :=
|
||||
Id.run (b.foldM f init)
|
||||
Id.run (b.foldM (pure <| f · · ·) init)
|
||||
|
||||
namespace Internal
|
||||
|
||||
|
|
@ -376,7 +376,7 @@ Internal implementation detail of the hash map.
|
|||
Folds the given function over the mappings in the hash map in the reverse order used
|
||||
by `foldM`. -/
|
||||
@[inline] def foldRev (f : δ → (a : α) → β a → δ) (init : δ) (b : Raw α β) : δ :=
|
||||
Id.run (foldRevM f init b)
|
||||
Id.run (foldRevM (pure <| f · · ·) init b)
|
||||
|
||||
end Internal
|
||||
|
||||
|
|
@ -395,7 +395,7 @@ by `foldM`. -/
|
|||
@[inline, deprecated "Deprecated without replacement. If the order does not matter, use fold."
|
||||
(since := "2025-03-07")]
|
||||
def foldRev (f : δ → (a : α) → β a → δ) (init : δ) (b : Raw α β) : δ :=
|
||||
Id.run (Internal.foldRevM f init b)
|
||||
Id.run (Internal.foldRevM (pure <| f · · ·) init b)
|
||||
|
||||
/-- Carries out a monadic action on each mapping in the hash map in some order. -/
|
||||
@[inline] def forM (f : (a : α) → β a → m PUnit) (b : Raw α β) : m PUnit :=
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ def foldlM {m} [Monad m] (f : δ → (a : α) → β a → m δ) (init : δ) : I
|
|||
/-- Folds the given function over the mappings in the tree in ascending order. -/
|
||||
@[specialize]
|
||||
def foldl (f : δ → (a : α) → β a → δ) (init : δ) (t : Impl α β) : δ :=
|
||||
Id.run (t.foldlM f init)
|
||||
Id.run (t.foldlM (pure <| f · · ·) init)
|
||||
|
||||
/-- Folds the given function over the mappings in the tree in descending order. -/
|
||||
@[specialize]
|
||||
|
|
@ -214,7 +214,7 @@ def foldrM {m} [Monad m] (f : (a : α) → β a → δ → m δ) (init : δ) : I
|
|||
/-- Folds the given function over the mappings in the tree in descending order. -/
|
||||
@[inline]
|
||||
def foldr (f : (a : α) → β a → δ → δ) (init : δ) (t : Impl α β) : δ :=
|
||||
Id.run (t.foldrM f init)
|
||||
Id.run (t.foldrM (pure <| f · · ·) init)
|
||||
|
||||
/-- Applies the given function to the mappings in the tree in ascending order. -/
|
||||
@[inline]
|
||||
|
|
|
|||
|
|
@ -1189,7 +1189,7 @@ theorem foldlM_toListModel_eq_foldlM {t : Impl α β} {m δ} [Monad m] [LawfulMo
|
|||
|
||||
theorem foldl_eq_foldl {t : Impl α β} {δ} {f : δ → (a : α) → β a → δ} {init} :
|
||||
t.foldl (init := init) f = t.toListModel.foldl (init := init) fun acc p => f acc p.1 p.2 := by
|
||||
rw [foldl, foldlM_eq_foldlM_toListModel, List.foldl_eq_foldlM, Id.run]
|
||||
rw [foldl, foldlM_eq_foldlM_toListModel, List.foldl_eq_foldlM]
|
||||
|
||||
/-!
|
||||
### foldrM
|
||||
|
|
@ -1210,7 +1210,7 @@ theorem foldrM_eq_foldrM {t : Impl α β} {m δ} [Monad m] [LawfulMonad m]
|
|||
|
||||
theorem foldr_eq_foldr {t : Impl α β} {δ} {f : (a : α) → β a → δ → δ} {init} :
|
||||
t.foldr (init := init) f = t.toListModel.foldr (init := init) fun p acc => f p.1 p.2 acc := by
|
||||
rw [foldr, foldrM_eq_foldrM, List.foldr_eq_foldrM, Id.run]
|
||||
rw [foldr, foldrM_eq_foldrM, List.foldr_eq_foldrM]
|
||||
|
||||
/-!
|
||||
### toList
|
||||
|
|
@ -1542,11 +1542,11 @@ theorem WF.eraseMany! {_ : Ord α} [TransOrd α] {ρ} [ForIn Id ρ α] {l : ρ}
|
|||
|
||||
theorem insertMany!_eq_foldl {_ : Ord α} {l : List ((a : α) × β a)} {t : Impl α β} :
|
||||
(t.insertMany! l).val = l.foldl (init := t) fun acc ⟨k, v⟩ => acc.insert! k v := by
|
||||
simp [insertMany!, Id.run, ← List.foldl_hom Subtype.val]
|
||||
simp [insertMany!, ← List.foldl_hom Subtype.val, List.forIn_pure_yield_eq_foldl]
|
||||
|
||||
theorem insertMany_eq_foldl {_ : Ord α} {l : List ((a : α) × β a)} {t : Impl α β} (h : t.Balanced) :
|
||||
(t.insertMany l h).val = l.foldl (init := t) fun acc ⟨k, v⟩ => acc.insert! k v := by
|
||||
simp [insertMany, Id.run, insert_eq_insert!, ← List.foldl_hom Subtype.val]
|
||||
simp [insertMany, insert_eq_insert!, ← List.foldl_hom Subtype.val, List.forIn_pure_yield_eq_foldl]
|
||||
|
||||
theorem insertMany_eq_insertMany! {_ : Ord α} {l : List ((a : α) × β a)}
|
||||
{t : Impl α β} (h : t.Balanced) :
|
||||
|
|
@ -1592,15 +1592,14 @@ variable {β : Type v}
|
|||
|
||||
theorem insertMany!_eq_foldl {_ : Ord α} {l : List (α × β)} {t : Impl α β} :
|
||||
(insertMany! t l).val = l.foldl (init := t) fun acc ⟨k, v⟩ => acc.insert! k v := by
|
||||
simp only [insertMany!, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
simp only [insertMany!, Id.run_pure, pure_bind, List.forIn_pure_yield_eq_foldl]
|
||||
rw [← List.foldl_hom Subtype.val]
|
||||
simp only [implies_true]
|
||||
|
||||
theorem insertMany_eq_foldl {_ : Ord α} {l : List (α × β)}
|
||||
{t : Impl α β} (h : t.Balanced) :
|
||||
(Const.insertMany t l h).val = l.foldl (init := t) fun acc ⟨k, v⟩ => acc.insert! k v := by
|
||||
simp only [insertMany, Id.run, Id.pure_eq, insert_eq_insert!, Id.bind_eq,
|
||||
List.forIn_yield_eq_foldl]
|
||||
simp only [insertMany, Id.run_pure, insert_eq_insert!, pure_bind, List.forIn_pure_yield_eq_foldl]
|
||||
rw [← List.foldl_hom Subtype.val]
|
||||
simp only [implies_true]
|
||||
|
||||
|
|
@ -1627,13 +1626,13 @@ theorem toListModel_insertMany!_list {_ : Ord α} [BEq α] [LawfulBEqOrd α] [Tr
|
|||
|
||||
theorem insertManyIfNewUnit_eq_foldl {_ : Ord α} {l : List α} {t : Impl α Unit} (h : t.Balanced) :
|
||||
(Const.insertManyIfNewUnit t l h).val = l.foldl (init := t) fun acc k => acc.insertIfNew! k () := by
|
||||
simp only [insertManyIfNewUnit, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
simp only [insertManyIfNewUnit, Id.run_pure, pure_bind, List.forIn_pure_yield_eq_foldl]
|
||||
rw [← List.foldl_hom Subtype.val]
|
||||
simp only [insertIfNew_eq_insertIfNew!, implies_true]
|
||||
|
||||
theorem insertManyIfNewUnit!_eq_foldl {_ : Ord α} {l : List α} {t : Impl α Unit} :
|
||||
(Const.insertManyIfNewUnit! t l).val = l.foldl (init := t) fun acc k => acc.insertIfNew! k () := by
|
||||
simp only [insertManyIfNewUnit!, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
simp only [insertManyIfNewUnit!, Id.run_pure, pure_bind, List.forIn_pure_yield_eq_foldl]
|
||||
rw [← List.foldl_hom Subtype.val]
|
||||
simp only [implies_true]
|
||||
|
||||
|
|
@ -1687,8 +1686,8 @@ theorem mergeWith_eq_mergeWith! {_ : Ord α} [LawfulEqOrd α] {mergeFn} {t₁ t
|
|||
induction t₂ generalizing t₁ with
|
||||
| leaf => rfl
|
||||
| inner sz k v l r ihl ihr =>
|
||||
simp only [foldl, foldlM, Id.run, bind]
|
||||
simp only [foldl, Id.run, bind] at ihl ihr
|
||||
simp only [foldl, foldlM, pure_bind, Id.run_bind]
|
||||
simp only [foldl] at ihl ihr
|
||||
rw [ihr]
|
||||
congr
|
||||
simp only [SizedBalancedTree.toBalancedTree]
|
||||
|
|
@ -1708,8 +1707,8 @@ theorem Const.mergeWith_eq_mergeWith! {β : Type v} {_ : Ord α} {mergeFn} {t₁
|
|||
induction t₂ generalizing t₁ with
|
||||
| leaf => rfl
|
||||
| inner sz k v l r ihl ihr =>
|
||||
simp only [foldl, foldlM, Id.run, bind]
|
||||
simp only [foldl, Id.run, bind] at ihl ihr
|
||||
simp only [foldl, foldlM, Id.run_bind, pure_bind]
|
||||
simp only [foldl] at ihl ihr
|
||||
rw [ihr]
|
||||
congr
|
||||
simp only [SizedBalancedTree.toBalancedTree]
|
||||
|
|
|
|||
|
|
@ -965,7 +965,7 @@ theorem insertMany_cons [EquivBEq α] [LawfulHashable α]
|
|||
m.insertMany (p :: l) = (m.insert p.1 p.2).insertMany l := by
|
||||
rcases p with ⟨k, v⟩
|
||||
unfold insertMany
|
||||
simp only [Id.pure_eq, Id.bind_eq, Id.run, List.forIn_yield_eq_foldl, List.foldl_cons]
|
||||
simp only [bind_pure_comp, map_pure, List.forIn_pure_yield_eq_foldl, List.foldl_cons, Id.run_pure]
|
||||
refine Eq.trans ?_ (Eq.symm ?_ : l.foldl (fun b a => b.insert a.1 a.2) (m.insert k v) = _)
|
||||
exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm
|
||||
exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm
|
||||
|
|
@ -1228,7 +1228,7 @@ theorem insertMany_cons [EquivBEq α] [LawfulHashable α] {l : List (α × β)}
|
|||
insertMany m (p :: l) = insertMany (m.insert p.1 p.2) l := by
|
||||
rcases p with ⟨k, v⟩
|
||||
unfold insertMany
|
||||
simp only [Id.pure_eq, Id.bind_eq, Id.run, List.forIn_yield_eq_foldl, List.foldl_cons]
|
||||
simp only [bind_pure_comp, map_pure, List.forIn_pure_yield_eq_foldl, List.foldl_cons, Id.run_pure]
|
||||
refine Eq.trans ?_ (Eq.symm ?_ : l.foldl (fun b a => b.insert a.1 a.2) (m.insert k v) = _)
|
||||
exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm
|
||||
exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm
|
||||
|
|
@ -1492,7 +1492,7 @@ theorem insertManyIfNewUnit_list_singleton [EquivBEq α] [LawfulHashable α] {k
|
|||
theorem insertManyIfNewUnit_cons [EquivBEq α] [LawfulHashable α] {l : List α} {k : α} :
|
||||
insertManyIfNewUnit m (k :: l) = insertManyIfNewUnit (m.insertIfNew k ()) l := by
|
||||
unfold insertManyIfNewUnit
|
||||
simp only [Id.pure_eq, Id.bind_eq, Id.run, List.forIn_yield_eq_foldl, List.foldl_cons]
|
||||
simp only [bind_pure_comp, map_pure, List.forIn_pure_yield_eq_foldl, List.foldl_cons, Id.run_pure]
|
||||
refine Eq.trans ?_ (Eq.symm ?_ : l.foldl (fun b a => b.insertIfNew a ()) (m.insertIfNew k ()) = _)
|
||||
exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm
|
||||
exact (List.foldl_hom (f := Subtype.val) fun x y => rfl).symm
|
||||
|
|
|
|||
|
|
@ -27,31 +27,31 @@ namespace Std.Iterators
|
|||
@[always_inline, inline, inherit_doc IterM.toArray]
|
||||
def Iter.toArray {α : Type w} {β : Type w}
|
||||
[Iterator α Id β] [Finite α Id] [IteratorCollect α Id] (it : Iter (α := α) β) : Array β :=
|
||||
it.toIterM.toArray
|
||||
it.toIterM.toArray.run
|
||||
|
||||
@[always_inline, inline, inherit_doc IterM.Partial.toArray]
|
||||
def Iter.Partial.toArray {α : Type w} {β : Type w}
|
||||
[Iterator α Id β] [IteratorCollectPartial α Id] (it : Iter.Partial (α := α) β) : Array β :=
|
||||
it.it.toIterM.allowNontermination.toArray
|
||||
it.it.toIterM.allowNontermination.toArray.run
|
||||
|
||||
@[always_inline, inline, inherit_doc IterM.toListRev]
|
||||
def Iter.toListRev {α : Type w} {β : Type w}
|
||||
[Iterator α Id β] [Finite α Id] (it : Iter (α := α) β) : List β :=
|
||||
it.toIterM.toListRev
|
||||
it.toIterM.toListRev.run
|
||||
|
||||
@[always_inline, inline, inherit_doc IterM.Partial.toListRev]
|
||||
def Iter.Partial.toListRev {α : Type w} {β : Type w}
|
||||
[Iterator α Id β] (it : Iter.Partial (α := α) β) : List β :=
|
||||
it.it.toIterM.allowNontermination.toListRev
|
||||
it.it.toIterM.allowNontermination.toListRev.run
|
||||
|
||||
@[always_inline, inline, inherit_doc IterM.toList]
|
||||
def Iter.toList {α : Type w} {β : Type w}
|
||||
[Iterator α Id β] [Finite α Id] [IteratorCollect α Id] (it : Iter (α := α) β) : List β :=
|
||||
it.toIterM.toList
|
||||
it.toIterM.toList.run
|
||||
|
||||
@[always_inline, inline, inherit_doc IterM.Partial.toList]
|
||||
def Iter.Partial.toList {α : Type w} {β : Type w}
|
||||
[Iterator α Id β] [IteratorCollectPartial α Id] (it : Iter.Partial (α := α) β) : List β :=
|
||||
it.it.toIterM.allowNontermination.toList
|
||||
it.it.toIterM.allowNontermination.toList.run
|
||||
|
||||
end Std.Iterators
|
||||
|
|
|
|||
|
|
@ -13,42 +13,40 @@ namespace Std.Iterators
|
|||
|
||||
theorem Iter.toArray_eq_toArray_toIterM {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
|
||||
[LawfulIteratorCollect α Id] {it : Iter (α := α) β} :
|
||||
it.toArray = it.toIterM.toArray :=
|
||||
it.toArray = it.toIterM.toArray.run :=
|
||||
rfl
|
||||
|
||||
theorem Iter.toList_eq_toList_toIterM {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
|
||||
[LawfulIteratorCollect α Id] {it : Iter (α := α) β} :
|
||||
it.toList = it.toIterM.toList :=
|
||||
it.toList = it.toIterM.toList.run :=
|
||||
rfl
|
||||
|
||||
theorem Iter.toListRev_eq_toListRev_toIterM {α β} [Iterator α Id β] [Finite α Id]
|
||||
{it : Iter (α := α) β} :
|
||||
it.toListRev = it.toIterM.toListRev :=
|
||||
it.toListRev = it.toIterM.toListRev.run :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem IterM.toList_toIter {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
|
||||
{it : IterM (α := α) Id β} :
|
||||
it.toIter.toList = it.toList :=
|
||||
it.toIter.toList = it.toList.run :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem IterM.toListRev_toIter {α β} [Iterator α Id β] [Finite α Id]
|
||||
{it : IterM (α := α) Id β} :
|
||||
it.toIter.toListRev = it.toListRev :=
|
||||
it.toIter.toListRev = it.toListRev.run :=
|
||||
rfl
|
||||
|
||||
theorem Iter.toList_toArray {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
|
||||
[LawfulIteratorCollect α Id] {it : Iter (α := α) β} :
|
||||
it.toArray.toList = it.toList := by
|
||||
simp only [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toList_toArray,
|
||||
Id.map_eq]
|
||||
simp [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toList_toArray]
|
||||
|
||||
theorem Iter.toArray_toList {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
|
||||
[LawfulIteratorCollect α Id] {it : Iter (α := α) β} :
|
||||
it.toList.toArray = it.toArray := by
|
||||
simp only [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toArray_toList,
|
||||
Id.map_eq]
|
||||
simp [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toArray_toList]
|
||||
|
||||
theorem Iter.toListRev_eq {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
|
||||
[LawfulIteratorCollect α Id] {it : Iter (α := α) β} :
|
||||
|
|
@ -62,9 +60,8 @@ theorem Iter.toArray_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [I
|
|||
| .skip it' _ => it'.toArray
|
||||
| .done _ => #[] := by
|
||||
simp only [Iter.toArray_eq_toArray_toIterM, Iter.step]
|
||||
rw [IterM.toArray_eq_match_step]
|
||||
simp only [Id.map_eq, Id.pure_eq, Id.bind_eq, Id.run]
|
||||
generalize it.toIterM.step = step
|
||||
rw [IterM.toArray_eq_match_step, Id.run_bind]
|
||||
generalize it.toIterM.step.run = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.toList_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
|
||||
|
|
@ -81,9 +78,8 @@ theorem Iter.toListRev_eq_match_step {α β} [Iterator α Id β] [Finite α Id]
|
|||
| .yield it' out _ => it'.toListRev ++ [out]
|
||||
| .skip it' _ => it'.toListRev
|
||||
| .done _ => [] := by
|
||||
rw [Iter.toListRev_eq_toListRev_toIterM, IterM.toListRev_eq_match_step, Iter.step]
|
||||
simp only [Id.map_eq, Id.pure_eq, Id.bind_eq, Id.run]
|
||||
generalize it.toIterM.step = step
|
||||
rw [Iter.toListRev_eq_toListRev_toIterM, IterM.toListRev_eq_match_step, Iter.step, Id.run_bind]
|
||||
generalize it.toIterM.step.run = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.getElem?_toList_eq_atIdxSlow? {α β}
|
||||
|
|
|
|||
|
|
@ -145,10 +145,10 @@ def uriEscapeByte (b : UInt8) (s := "") : String :=
|
|||
return s
|
||||
|
||||
abbrev foldlUtf8 (c : Char) (f : σ → UInt8 → σ) (init : σ) : σ :=
|
||||
Id.run <| foldlUtf8M c f init
|
||||
Id.run <| foldlUtf8M c (pure <| f · ·) init
|
||||
|
||||
example : foldlUtf8 c (fun l b => b::l) List.nil = (String.utf8EncodeChar c).reverse := by
|
||||
simp only [foldlUtf8M, String.utf8EncodeChar, Id.run]
|
||||
simp only [foldlUtf8, foldlUtf8M, String.utf8EncodeChar]
|
||||
if h1 : c.val ≤ 0x7f then simp [h1]
|
||||
else if h2 : c.val ≤ 0x7ff then simp [h1, h2]
|
||||
else if h3 : c.val ≤ 0xffff then simp [h1, h2, h3]
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ def findSomeRevM? [Monad m] (as : Array α) (f : α → m (Option β)) : m (Opti
|
|||
pure none
|
||||
|
||||
def findSomeRev? (as : Array α) (f : α → Option β) : Option β :=
|
||||
Id.run <| findSomeRevM? as f
|
||||
Id.run <| findSomeRevM? as (pure <| f ·)
|
||||
|
||||
end Ex1
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
theorem modifySize {A : Type u} (as : Array A) (f : A → A) (n : Nat) : (as.modify n f).size = as.size := by
|
||||
simp [Array.modify, Array.modifyM, Id.run]; split <;> simp [Id.run]
|
||||
simp [Array.modify, Array.modifyM]; split <;> simp
|
||||
|
||||
structure Idx (p : Array String) where
|
||||
n : Fin p.size
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ attribute [-simp] Nat.default_eq_zero -- undo changes to simp set after this tes
|
|||
variable {xs : Array α} in
|
||||
#check_simp xs.size = 0 ~> xs = #[]
|
||||
|
||||
attribute [local simp] Id.run in
|
||||
#check_simp
|
||||
(Id.run do
|
||||
let mut s := 0
|
||||
|
|
@ -19,7 +18,6 @@ attribute [local simp] Id.run in
|
|||
s := s + i
|
||||
pure s) ~> 10
|
||||
|
||||
attribute [local simp] Id.run in
|
||||
#check_simp
|
||||
(Id.run do
|
||||
let mut s := 0
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ def fib_impl (n : Nat) := Id.run do
|
|||
theorem fib_correct {n} : fib_impl n = fib_spec n := by
|
||||
-- The default simp set eliminates the binds generated by `do` notation,
|
||||
-- and converts the `for` loop into a `List.foldl` over `List.range'`.
|
||||
simp [fib_impl, Id.run]
|
||||
simp [fib_impl]
|
||||
match n with
|
||||
| 0 => simp [fib_spec]
|
||||
| n+1 =>
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ example (f : Fin 3 → Nat) : List.ofFn f = [f 0, f 1, f 2] := rfl
|
|||
example (f : Fin 3 → Nat) : Fin.foldl 3 (fun acc i => f i :: acc) [] = [f 2, f 1, f 0] := rfl
|
||||
|
||||
/-! ## Monadic operations -/
|
||||
attribute [local simp] Id.run in
|
||||
|
||||
#check_simp
|
||||
(Id.run do
|
||||
let mut s := 0
|
||||
|
|
@ -475,7 +475,6 @@ attribute [local simp] Id.run in
|
|||
s := s + i
|
||||
pure s) ~> 10
|
||||
|
||||
attribute [local simp] Id.run in
|
||||
#check_simp
|
||||
(Id.run do
|
||||
let mut s := 0
|
||||
|
|
@ -483,7 +482,6 @@ attribute [local simp] Id.run in
|
|||
s := s + i
|
||||
pure s) ~> 10
|
||||
|
||||
attribute [local simp] Id.run in
|
||||
variable (l : List α) (k m : Nat) in
|
||||
#check_simp
|
||||
(Id.run do
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ def treeToList (t : TreeNode) : List String :=
|
|||
return r
|
||||
|
||||
@[simp] theorem treeToList_eq (name : String) (children : List TreeNode) : treeToList (.mkNode name children) = name :: List.flatten (children.map treeToList) := by
|
||||
simp [treeToList, Id.run]
|
||||
simp [treeToList]
|
||||
|
||||
mutual
|
||||
def numNames : TreeNode → Nat
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ example [TransOrd α] [LawfulEqOrd α] (a : α) (b : β) : Option β :=
|
|||
(mkTreeMapSingleton a b)[a]?
|
||||
|
||||
example [TransOrd α] (a : α) (b : β) : (mkTreeMapSingleton a b).contains a := by
|
||||
simp [mkTreeMapSingleton, Id.run]
|
||||
simp [mkTreeMapSingleton]
|
||||
|
||||
example [TransOrd α] (a : α) (b : β) : (mkDTreeMapSingleton a b).contains a := by
|
||||
simp [mkDTreeMapSingleton, Id.run]
|
||||
simp [mkDTreeMapSingleton]
|
||||
|
||||
example [TransOrd α] (a : α) : (mkTreeSetSingleton a).contains a := by
|
||||
simp [mkTreeSetSingleton, Id.run]
|
||||
simp [mkTreeSetSingleton]
|
||||
|
||||
namespace DTreeMap.Raw
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
theorem Array.sizeOf_lt_of_mem' [DecidableEq α] [SizeOf α] {as : Array α} (h : as.contains a) : sizeOf a < sizeOf as := by
|
||||
simp [Membership.mem, contains, any, Id.run, BEq.beq, anyM] at h
|
||||
let rec aux (j : Nat) : anyM.loop (m := Id) (fun b => decide (a = b)) as as.size (Nat.le_refl ..) j = true → sizeOf a < sizeOf as := by
|
||||
let rec aux (j : Nat) : anyM.loop (m := Id) (fun b => pure <| decide (a = b)) as as.size (Nat.le_refl ..) j = true → sizeOf a < sizeOf as := by
|
||||
unfold anyM.loop
|
||||
intro h
|
||||
split at h
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue