mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-18 10:54:09 +00:00
Compare commits
53 Commits
document_g
...
IntModule_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26268136dc | ||
|
|
98c220ea8d | ||
|
|
b277f3a402 | ||
|
|
7563199ccc | ||
|
|
42882ce465 | ||
|
|
f20d0e4532 | ||
|
|
9ece4e463a | ||
|
|
c38c0898a3 | ||
|
|
070e622f05 | ||
|
|
12a8f1b5f8 | ||
|
|
7050dc6d38 | ||
|
|
376ae32c7c | ||
|
|
0c44aab811 | ||
|
|
a5eeed4f2c | ||
|
|
be80a23281 | ||
|
|
92ac564f3c | ||
|
|
0fcb6495d6 | ||
|
|
e7c8baaef5 | ||
|
|
8d8c73416a | ||
|
|
cf527e05bd | ||
|
|
61ee83f73b | ||
|
|
26b7e49c05 | ||
|
|
466c9b56ba | ||
|
|
00474e17ff | ||
|
|
891a2c6590 | ||
|
|
d489c6196c | ||
|
|
6703af1ea0 | ||
|
|
7f8ccd8425 | ||
|
|
a8d5982fce | ||
|
|
50cfe354be | ||
|
|
a750da5a7f | ||
|
|
588df4612a | ||
|
|
4ce18249d3 | ||
|
|
dd78012ddd | ||
|
|
1e69d88d6f | ||
|
|
db499e96aa | ||
|
|
c5ca9aa87c | ||
|
|
f416143fbc | ||
|
|
e6b5c45e04 | ||
|
|
3710e4f176 | ||
|
|
ec9865dbd5 | ||
|
|
a2b03b3efd | ||
|
|
42eb3bb4b5 | ||
|
|
f3f932ae8c | ||
|
|
6c6a058beb | ||
|
|
04113f2be5 | ||
|
|
2b393a3b88 | ||
|
|
e1ecc150e3 | ||
|
|
76fcd276c6 | ||
|
|
705769f466 | ||
|
|
cd346a360e | ||
|
|
cfa38b055b | ||
|
|
e9086533ed |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,7 +6,6 @@
|
||||
lake-manifest.json
|
||||
/build
|
||||
/src/lakefile.toml
|
||||
/tests/lakefile.toml
|
||||
/lakefile.toml
|
||||
GPATH
|
||||
GRTAGS
|
||||
|
||||
@@ -50,5 +50,4 @@ echo -n " -DLEANC_INTERNAL_LINKER_FLAGS='--sysroot ROOT -L ROOT/lib -Wl,-Bstatic
|
||||
# when not using the above flags, link GMP dynamically/as usual. Always link ICU dynamically.
|
||||
echo -n " -DLEAN_EXTRA_LINKER_FLAGS='-lgmp $(pkg-config --libs libuv) -lucrtbase'"
|
||||
# do not set `LEAN_CC` for tests
|
||||
echo -n " -DAUTO_THREAD_FINALIZATION=OFF -DSTAGE0_AUTO_THREAD_FINALIZATION=OFF"
|
||||
echo -n " -DLEAN_TEST_VARS=''"
|
||||
|
||||
@@ -58,9 +58,6 @@ option(USE_GITHASH "GIT_HASH" ON)
|
||||
option(INSTALL_LICENSE "INSTALL_LICENSE" ON)
|
||||
# When ON we install a copy of cadical
|
||||
option(INSTALL_CADICAL "Install a copy of cadical" ON)
|
||||
# When ON thread storage is automatically finalized, it assumes platform support pthreads.
|
||||
# This option is important when using Lean as library that is invoked from a different programming language (e.g., Haskell).
|
||||
option(AUTO_THREAD_FINALIZATION "AUTO_THREAD_FINALIZATION" ON)
|
||||
|
||||
# FLAGS for disabling optimizations and debugging
|
||||
option(FREE_VAR_RANGE_OPT "FREE_VAR_RANGE_OPT" ON)
|
||||
@@ -182,10 +179,6 @@ else()
|
||||
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_MULTI_THREAD")
|
||||
endif()
|
||||
|
||||
if(AUTO_THREAD_FINALIZATION AND NOT MSVC)
|
||||
string(APPEND LEAN_EXTRA_CXX_FLAGS " -D LEAN_AUTO_THREAD_FINALIZATION")
|
||||
endif()
|
||||
|
||||
# Set Module Path
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ theorem em (p : Prop) : p ∨ ¬p :=
|
||||
| Or.inr h, _ => Or.inr h
|
||||
| _, Or.inr h => Or.inr h
|
||||
| Or.inl hut, Or.inl hvf =>
|
||||
have hne : u ≠ v := by simp [hvf, hut, true_ne_false]
|
||||
have hne : u ≠ v := by simp [hvf, hut]
|
||||
Or.inl hne
|
||||
have p_implies_uv : p → u = v :=
|
||||
fun hp =>
|
||||
|
||||
@@ -50,7 +50,7 @@ attribute [simp] id_map
|
||||
(comp_map _ _ _).symm
|
||||
|
||||
theorem Functor.map_unit [Functor f] [LawfulFunctor f] {a : f PUnit} : (fun _ => PUnit.unit) <$> a = a := by
|
||||
simp [map]
|
||||
simp
|
||||
|
||||
/--
|
||||
An applicative functor satisfies the laws of an applicative functor.
|
||||
|
||||
@@ -67,7 +67,7 @@ protected theorem seqLeft_eq {α β ε : Type u} {m : Type u → Type v} [Monad
|
||||
| Except.error _ => simp
|
||||
| Except.ok _ =>
|
||||
simp [←bind_pure_comp]; apply bind_congr; intro b;
|
||||
cases b <;> simp [comp, Except.map, const]
|
||||
cases b <;> simp [Except.map, const]
|
||||
|
||||
protected theorem seqRight_eq [Monad m] [LawfulMonad m] (x : ExceptT ε m α) (y : ExceptT ε m β) : x *> y = const α id <$> x <*> y := by
|
||||
change (x >>= fun _ => y) = (const α id <$> x) >>= fun f => f <$> y
|
||||
|
||||
@@ -209,7 +209,7 @@ theorem Context.evalList_sort_congr
|
||||
induction c generalizing a b with
|
||||
| nil => simp [sort.loop, h₂]
|
||||
| cons c _ ih =>
|
||||
simp [sort.loop]; apply ih; simp [evalList_insert ctx h, evalList]
|
||||
simp [sort.loop]; apply ih; simp [evalList_insert ctx h]
|
||||
cases a with
|
||||
| nil => apply absurd h₃; simp
|
||||
| cons a as =>
|
||||
@@ -282,7 +282,7 @@ theorem Context.toList_nonEmpty (e : Expr) : e.toList ≠ [] := by
|
||||
simp [Expr.toList]
|
||||
cases h : l.toList with
|
||||
| nil => contradiction
|
||||
| cons => simp [List.append]
|
||||
| cons => simp
|
||||
|
||||
theorem Context.unwrap_isNeutral
|
||||
{ctx : Context α}
|
||||
@@ -328,13 +328,13 @@ theorem Context.eval_toList (ctx : Context α) (e : Expr) : evalList α ctx e.to
|
||||
induction e with
|
||||
| var x => rfl
|
||||
| op l r ih₁ ih₂ =>
|
||||
simp [evalList, Expr.toList, eval, ←ih₁, ←ih₂]
|
||||
simp [Expr.toList, eval, ←ih₁, ←ih₂]
|
||||
apply evalList_append <;> apply toList_nonEmpty
|
||||
|
||||
theorem Context.eval_norm (ctx : Context α) (e : Expr) : evalList α ctx (norm ctx e) = eval α ctx e := by
|
||||
simp [norm]
|
||||
cases h₁ : ContextInformation.isIdem ctx <;> cases h₂ : ContextInformation.isComm ctx <;>
|
||||
simp_all [evalList_removeNeutrals, eval_toList, toList_nonEmpty, evalList_mergeIdem, evalList_sort]
|
||||
simp_all [evalList_removeNeutrals, eval_toList, evalList_mergeIdem, evalList_sort]
|
||||
|
||||
theorem Context.eq_of_norm (ctx : Context α) (a b : Expr) (h : norm ctx a == norm ctx b) : eval α ctx a = eval α ctx b := by
|
||||
have h := congrArg (evalList α ctx) (eq_of_beq h)
|
||||
|
||||
@@ -155,7 +155,7 @@ theorem attachWith_congr {xs ys : Array α} (w : xs = ys) {P : α → Prop} {H :
|
||||
(xs.push a).attachWith P H =
|
||||
(xs.attachWith P (fun x h => by simp at H; exact H x (.inl h))).push ⟨a, H a (by simp)⟩ := by
|
||||
cases xs
|
||||
simp [attachWith_congr (List.push_toArray _ _)]
|
||||
simp
|
||||
|
||||
theorem pmap_eq_map_attach {p : α → Prop} {f : ∀ a, p a → β} {xs : Array α} (H) :
|
||||
pmap f xs H = xs.attach.map fun x => f x.1 (H _ x.2) := by
|
||||
@@ -342,7 +342,7 @@ theorem foldl_attach {xs : Array α} {f : β → α → β} {b : β} :
|
||||
xs.attach.foldl (fun acc t => f acc t.1) b = xs.foldl f b := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp only [List.attach_toArray, List.attachWith_mem_toArray, List.size_toArray,
|
||||
List.length_pmap, List.foldl_toArray', mem_toArray, List.foldl_subtype]
|
||||
List.foldl_toArray', mem_toArray, List.foldl_subtype]
|
||||
congr
|
||||
ext
|
||||
simpa using fun a => List.mem_of_getElem? a
|
||||
@@ -361,7 +361,7 @@ theorem foldr_attach {xs : Array α} {f : α → β → β} {b : β} :
|
||||
xs.attach.foldr (fun t acc => f t.1 acc) b = xs.foldr f b := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp only [List.attach_toArray, List.attachWith_mem_toArray, List.size_toArray,
|
||||
List.length_pmap, List.foldr_toArray', mem_toArray, List.foldr_subtype]
|
||||
List.foldr_toArray', mem_toArray, List.foldr_subtype]
|
||||
congr
|
||||
ext
|
||||
simpa using fun a => List.mem_of_getElem? a
|
||||
@@ -470,7 +470,7 @@ theorem pmap_append' {p : α → Prop} {f : ∀ a : α, p a → β} {xs ys : Arr
|
||||
{H : ∀ (a : α), a ∈ xs ++ ys → P a} :
|
||||
(xs ++ ys).attachWith P H = xs.attachWith P (fun a h => H a (mem_append_left ys h)) ++
|
||||
ys.attachWith P (fun a h => H a (mem_append_right xs h)) := by
|
||||
simp [attachWith, attach_append, map_pmap, pmap_append]
|
||||
simp [attachWith]
|
||||
|
||||
@[simp, grind =] theorem pmap_reverse {P : α → Prop} {f : (a : α) → P a → β} {xs : Array α}
|
||||
(H : ∀ (a : α), a ∈ xs.reverse → P a) :
|
||||
@@ -703,7 +703,7 @@ and simplifies these to the function directly taking the value.
|
||||
{f : { x // p x } → Array β} {g : α → Array β} (hf : ∀ x h, f ⟨x, h⟩ = g x) :
|
||||
(xs.flatMap f) = xs.unattach.flatMap g := by
|
||||
cases xs
|
||||
simp only [List.size_toArray, List.flatMap_toArray, List.unattach_toArray, List.length_unattach,
|
||||
simp only [List.flatMap_toArray, List.unattach_toArray,
|
||||
mk.injEq]
|
||||
rw [List.flatMap_subtype]
|
||||
simp [hf]
|
||||
|
||||
@@ -1788,7 +1788,7 @@ decreasing_by simp_wf; exact Nat.sub_succ_lt_self _ _ h
|
||||
induction xs, i, h using Array.eraseIdx.induct with
|
||||
| @case1 xs i h h' xs' ih =>
|
||||
unfold eraseIdx
|
||||
simp +zetaDelta [h', xs', ih]
|
||||
simp +zetaDelta [h', ih]
|
||||
| case2 xs i h h' =>
|
||||
unfold eraseIdx
|
||||
simp [h']
|
||||
|
||||
@@ -119,13 +119,13 @@ abbrev pop_toList := @Array.toList_pop
|
||||
@[simp] theorem toList_empty : (#[] : Array α).toList = [] := rfl
|
||||
|
||||
@[simp, grind =] theorem append_empty {xs : Array α} : xs ++ #[] = xs := by
|
||||
apply ext'; simp only [toList_append, toList_empty, List.append_nil]
|
||||
apply ext'; simp only [toList_append, List.append_nil]
|
||||
|
||||
@[deprecated append_empty (since := "2025-01-13")]
|
||||
abbrev append_nil := @append_empty
|
||||
|
||||
@[simp, grind =] theorem empty_append {xs : Array α} : #[] ++ xs = xs := by
|
||||
apply ext'; simp only [toList_append, toList_empty, List.nil_append]
|
||||
apply ext'; simp only [toList_append, List.nil_append]
|
||||
|
||||
@[deprecated empty_append (since := "2025-01-13")]
|
||||
abbrev nil_append := @empty_append
|
||||
|
||||
@@ -223,7 +223,7 @@ theorem boole_getElem_le_count {xs : Array α} {i : Nat} {a : α} (h : i < xs.si
|
||||
@[grind =]
|
||||
theorem count_set {xs : Array α} {i : Nat} {a b : α} (h : i < xs.size) :
|
||||
(xs.set i a).count b = xs.count b - (if xs[i] == b then 1 else 0) + (if a == b then 1 else 0) := by
|
||||
simp [count_eq_countP, countP_set, h]
|
||||
simp [count_eq_countP, countP_set]
|
||||
|
||||
variable [LawfulBEq α]
|
||||
|
||||
@@ -231,7 +231,7 @@ variable [LawfulBEq α]
|
||||
simp [count_push]
|
||||
|
||||
@[simp] theorem count_push_of_ne {xs : Array α} (h : b ≠ a) : count a (xs.push b) = count a xs := by
|
||||
simp_all [count_push, h]
|
||||
simp_all [count_push]
|
||||
|
||||
theorem count_singleton_self {a : α} : count a #[a] = 1 := by simp
|
||||
|
||||
@@ -292,17 +292,17 @@ abbrev mkArray_count_eq_of_count_eq_size := @replicate_count_eq_of_count_eq_size
|
||||
theorem count_le_count_map [BEq β] [LawfulBEq β] {xs : Array α} {f : α → β} {x : α} :
|
||||
count x xs ≤ count (f x) (map f xs) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.count_le_count_map, countP_map]
|
||||
simp [List.count_le_count_map]
|
||||
|
||||
theorem count_filterMap {α} [BEq β] {b : β} {f : α → Option β} {xs : Array α} :
|
||||
count b (filterMap f xs) = countP (fun a => f a == some b) xs := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.count_filterMap, countP_filterMap]
|
||||
simp [List.count_filterMap]
|
||||
|
||||
theorem count_flatMap {α} [BEq β] {xs : Array α} {f : α → Array β} {x : β} :
|
||||
count x (xs.flatMap f) = sum (map (count x ∘ f) xs) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.count_flatMap, countP_flatMap, Function.comp_def]
|
||||
simp [List.count_flatMap, Function.comp_def]
|
||||
|
||||
theorem countP_replace {a b : α} {xs : Array α} {p : α → Bool} :
|
||||
(xs.replace a b).countP p =
|
||||
|
||||
@@ -23,7 +23,7 @@ private theorem rel_of_isEqvAux
|
||||
induction i with
|
||||
| zero => contradiction
|
||||
| succ i ih =>
|
||||
simp only [Array.isEqvAux, Bool.and_eq_true, decide_eq_true_eq] at heqv
|
||||
simp only [Array.isEqvAux, Bool.and_eq_true] at heqv
|
||||
by_cases hj' : j < i
|
||||
next =>
|
||||
exact ih _ heqv.right hj'
|
||||
|
||||
@@ -206,7 +206,7 @@ theorem erase_eq_eraseP [LawfulBEq α] (a : α) (xs : Array α) : xs.erase a = x
|
||||
theorem erase_ne_empty_iff [LawfulBEq α] {xs : Array α} {a : α} :
|
||||
xs.erase a ≠ #[] ↔ xs ≠ #[] ∧ xs ≠ #[a] := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.erase_ne_nil_iff]
|
||||
simp
|
||||
|
||||
theorem exists_erase_eq [LawfulBEq α] {a : α} {xs : Array α} (h : a ∈ xs) :
|
||||
∃ ys zs, a ∉ ys ∧ xs = ys.push a ++ zs ∧ xs.erase a = ys ++ zs := by
|
||||
@@ -306,7 +306,7 @@ theorem erase_eq_iff [LawfulBEq α] {a : α} {xs : Array α} :
|
||||
@[simp] theorem erase_replicate_self [LawfulBEq α] {a : α} :
|
||||
(replicate n a).erase a = replicate (n - 1) a := by
|
||||
simp only [← List.toArray_replicate, List.erase_toArray]
|
||||
simp [List.erase_replicate]
|
||||
simp
|
||||
|
||||
@[deprecated erase_replicate_self (since := "2025-03-18")]
|
||||
abbrev erase_mkArray_self := @erase_replicate_self
|
||||
@@ -352,7 +352,7 @@ theorem getElem?_eraseIdx_of_lt {xs : Array α} {i : Nat} (h : i < xs.size) {j :
|
||||
theorem getElem?_eraseIdx_of_ge {xs : Array α} {i : Nat} (h : i < xs.size) {j : Nat} (h' : i ≤ j) :
|
||||
(xs.eraseIdx i)[j]? = xs[j + 1]? := by
|
||||
rw [getElem?_eraseIdx]
|
||||
simp only [dite_eq_ite, ite_eq_right_iff]
|
||||
simp only [ite_eq_right_iff]
|
||||
intro h'
|
||||
omega
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Array
|
||||
· simp
|
||||
omega
|
||||
· simp only [size_extract] at h₁ h₂
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
theorem size_extract_le {as : Array α} {i j : Nat} :
|
||||
(as.extract i j).size ≤ j - i := by
|
||||
@@ -162,7 +162,7 @@ theorem extract_sub_one {as : Array α} {i j : Nat} (h : j < as.size) :
|
||||
@[simp]
|
||||
theorem getElem?_extract_of_lt {as : Array α} {i j k : Nat} (h : k < min j as.size - i) :
|
||||
(as.extract i j)[k]? = some (as[i + k]'(by omega)) := by
|
||||
simp [getElem?_extract, h]
|
||||
simp [h]
|
||||
|
||||
theorem getElem?_extract_of_succ {as : Array α} {j : Nat} :
|
||||
(as.extract 0 (j + 1))[j]? = as[j]? := by
|
||||
|
||||
@@ -81,7 +81,7 @@ theorem find?_eq_findSome?_guard {xs : Array α} : find? p xs = findSome? (Optio
|
||||
|
||||
@[simp, grind =] theorem getElem_zero_filterMap {f : α → Option β} {xs : Array α} (h) :
|
||||
(xs.filterMap f)[0] = (xs.findSome? f).get (by cases xs; simpa [List.length_filterMap_eq_countP] using h) := by
|
||||
cases xs; simp [← List.head_eq_getElem, ← getElem?_zero_filterMap]
|
||||
cases xs; simp [← getElem?_zero_filterMap]
|
||||
|
||||
@[simp, grind =] theorem back?_filterMap {f : α → Option β} {xs : Array α} : (xs.filterMap f).back? = xs.findSomeRev? f := by
|
||||
cases xs; simp
|
||||
@@ -122,7 +122,7 @@ theorem getElem_zero_flatten.proof {xss : Array (Array α)} (h : 0 < xss.flatten
|
||||
theorem getElem_zero_flatten {xss : Array (Array α)} (h) :
|
||||
(flatten xss)[0] = (xss.findSome? fun xs => xs[0]?).get (getElem_zero_flatten.proof h) := by
|
||||
have t := getElem?_zero_flatten xss
|
||||
simp [getElem?_eq_getElem, h] at t
|
||||
simp at t
|
||||
simp [← t]
|
||||
|
||||
@[grind =]
|
||||
@@ -308,7 +308,7 @@ abbrev find?_flatten_eq_some := @find?_flatten_eq_some_iff
|
||||
@[simp, grind =] theorem find?_flatMap {xs : Array α} {f : α → Array β} {p : β → Bool} :
|
||||
(xs.flatMap f).find? p = xs.findSome? (fun x => (f x).find? p) := by
|
||||
cases xs
|
||||
simp [List.find?_flatMap, Array.flatMap_toArray]
|
||||
simp [List.find?_flatMap]
|
||||
|
||||
theorem find?_flatMap_eq_none_iff {xs : Array α} {f : α → Array β} {p : β → Bool} :
|
||||
(xs.flatMap f).find? p = none ↔ ∀ x ∈ xs, ∀ y ∈ f x, !p y := by
|
||||
@@ -348,7 +348,7 @@ abbrev find?_mkArray_of_neg := @find?_replicate_of_neg
|
||||
-- This isn't a `@[simp]` lemma since there is already a lemma for `l.find? p = none` for any `l`.
|
||||
theorem find?_replicate_eq_none_iff {n : Nat} {a : α} {p : α → Bool} :
|
||||
(replicate n a).find? p = none ↔ n = 0 ∨ !p a := by
|
||||
simp [← List.toArray_replicate, List.find?_replicate_eq_none_iff, Classical.or_iff_not_imp_left]
|
||||
simp [← List.toArray_replicate, Classical.or_iff_not_imp_left]
|
||||
|
||||
@[deprecated find?_replicate_eq_none_iff (since := "2025-03-18")]
|
||||
abbrev find?_mkArray_eq_none_iff := @find?_replicate_eq_none_iff
|
||||
@@ -488,7 +488,7 @@ theorem findIdx_push {xs : Array α} {a : α} {p : α → Bool} :
|
||||
simp only [push_eq_append, findIdx_append]
|
||||
split <;> rename_i h
|
||||
· rfl
|
||||
· simp [findIdx_singleton, Nat.add_comm]
|
||||
· simp [Nat.add_comm]
|
||||
|
||||
theorem findIdx_le_findIdx {xs : Array α} {p q : α → Bool} (h : ∀ x ∈ xs, p x → q x) : xs.findIdx q ≤ xs.findIdx p := by
|
||||
rcases xs with ⟨xs⟩
|
||||
@@ -553,7 +553,7 @@ theorem findIdx?_eq_some_of_exists {xs : Array α} {p : α → Bool} (h : ∃ x,
|
||||
theorem findIdx?_eq_none_iff_findIdx_eq {xs : Array α} {p : α → Bool} :
|
||||
xs.findIdx? p = none ↔ xs.findIdx p = xs.size := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.findIdx?_eq_none_iff_findIdx_eq]
|
||||
simp
|
||||
|
||||
theorem findIdx?_eq_guard_findIdx_lt {xs : Array α} {p : α → Bool} :
|
||||
xs.findIdx? p = Option.guard (fun i => i < xs.size) (xs.findIdx p) := by
|
||||
@@ -798,7 +798,7 @@ The lemmas below should be made consistent with those for `findFinIdx?` (and pro
|
||||
|
||||
theorem idxOf?_eq_map_finIdxOf?_val [BEq α] {xs : Array α} {a : α} :
|
||||
xs.idxOf? a = (xs.finIdxOf? a).map (·.val) := by
|
||||
simp [idxOf?, finIdxOf?, findIdx?_eq_map_findFinIdx?_val]
|
||||
simp [idxOf?, finIdxOf?]
|
||||
|
||||
@[grind =] theorem finIdxOf?_empty [BEq α] : (#[] : Array α).finIdxOf? a = none := by simp
|
||||
|
||||
|
||||
@@ -109,19 +109,19 @@ theorem getElem_insertIdx {xs : Array α} {x : α} {i k : Nat} (w : i ≤ xs.siz
|
||||
else
|
||||
xs[k-1]'(by simp [size_insertIdx] at h; omega) := by
|
||||
cases xs
|
||||
simp [List.getElem_insertIdx, w]
|
||||
simp [List.getElem_insertIdx]
|
||||
|
||||
theorem getElem_insertIdx_of_lt {xs : Array α} {x : α} {i k : Nat} (w : i ≤ xs.size) (h : k < i) :
|
||||
(xs.insertIdx i x)[k]'(by simp; omega) = xs[k] := by
|
||||
simp [getElem_insertIdx, w, h]
|
||||
simp [getElem_insertIdx, h]
|
||||
|
||||
theorem getElem_insertIdx_self {xs : Array α} {x : α} {i : Nat} (w : i ≤ xs.size) :
|
||||
(xs.insertIdx i x)[i]'(by simp; omega) = x := by
|
||||
simp [getElem_insertIdx, w]
|
||||
simp [getElem_insertIdx]
|
||||
|
||||
theorem getElem_insertIdx_of_gt {xs : Array α} {x : α} {i k : Nat} (w : k ≤ xs.size) (h : k > i) :
|
||||
(xs.insertIdx i x)[k]'(by simp; omega) = xs[k - 1]'(by omega) := by
|
||||
simp [getElem_insertIdx, w, h]
|
||||
simp [getElem_insertIdx]
|
||||
rw [dif_neg (by omega), dif_neg (by omega)]
|
||||
|
||||
@[grind =]
|
||||
@@ -135,7 +135,7 @@ theorem getElem?_insertIdx {xs : Array α} {x : α} {i k : Nat} (h : i ≤ xs.si
|
||||
else
|
||||
xs[k-1]? := by
|
||||
cases xs
|
||||
simp [List.getElem?_insertIdx, h]
|
||||
simp [List.getElem?_insertIdx]
|
||||
|
||||
theorem getElem?_insertIdx_of_lt {xs : Array α} {x : α} {i k : Nat} (w : i ≤ xs.size) (h : k < i) :
|
||||
(xs.insertIdx i x)[k]? = xs[k]? := by
|
||||
|
||||
@@ -125,7 +125,7 @@ theorem none_eq_getElem?_iff {xs : Array α} {i : Nat} : none = xs[i]? ↔ xs.si
|
||||
simp
|
||||
|
||||
theorem getElem?_eq_none {xs : Array α} (h : xs.size ≤ i) : xs[i]? = none := by
|
||||
simp [getElem?_eq_none_iff, h]
|
||||
simp [h]
|
||||
|
||||
grind_pattern Array.getElem?_eq_none => xs.size ≤ i, xs[i]?
|
||||
|
||||
@@ -154,16 +154,16 @@ theorem getElem_eq_iff {xs : Array α} {i : Nat} {h : i < xs.size} : xs[i] = x
|
||||
exact ⟨fun w => ⟨h, w⟩, fun h => h.2⟩
|
||||
|
||||
theorem getElem_eq_getElem?_get {xs : Array α} {i : Nat} (h : i < xs.size) :
|
||||
xs[i] = xs[i]?.get (by simp [getElem?_eq_getElem, h]) := by
|
||||
simp [getElem_eq_iff]
|
||||
xs[i] = xs[i]?.get (by simp [h]) := by
|
||||
simp
|
||||
|
||||
theorem getD_getElem? {xs : Array α} {i : Nat} {d : α} :
|
||||
xs[i]?.getD d = if p : i < xs.size then xs[i]'p else d := by
|
||||
if h : i < xs.size then
|
||||
simp [h, getElem?_def]
|
||||
simp [h]
|
||||
else
|
||||
have p : i ≥ xs.size := Nat.le_of_not_gt h
|
||||
simp [getElem?_eq_none p, h]
|
||||
simp [h]
|
||||
|
||||
@[simp] theorem getElem?_empty {i : Nat} : (#[] : Array α)[i]? = none := rfl
|
||||
|
||||
@@ -175,14 +175,14 @@ theorem getElem_push_lt {xs : Array α} {x : α} {i : Nat} (h : i < xs.size) :
|
||||
|
||||
@[simp] theorem getElem_push_eq {xs : Array α} {x : α} : (xs.push x)[xs.size] = x := by
|
||||
simp only [push, ← getElem_toList, List.concat_eq_append]
|
||||
rw [List.getElem_append_right] <;> simp [← getElem_toList, Nat.zero_lt_one]
|
||||
rw [List.getElem_append_right] <;> simp
|
||||
|
||||
@[grind =] theorem getElem_push {xs : Array α} {x : α} {i : Nat} (h : i < (xs.push x).size) :
|
||||
(xs.push x)[i] = if h : i < xs.size then xs[i] else x := by
|
||||
by_cases h' : i < xs.size
|
||||
· simp [getElem_push_lt, h']
|
||||
· simp at h
|
||||
simp [getElem_push_lt, Nat.le_antisymm (Nat.le_of_lt_succ h) (Nat.ge_of_not_lt h')]
|
||||
simp [Nat.le_antisymm (Nat.le_of_lt_succ h) (Nat.ge_of_not_lt h')]
|
||||
|
||||
@[grind =] theorem getElem?_push {xs : Array α} {x} : (xs.push x)[i]? = if i = xs.size then some x else xs[i]? := by
|
||||
simp [getElem?_def, getElem_push]
|
||||
@@ -906,7 +906,7 @@ theorem all_push [BEq α] {xs : Array α} {a : α} {p : α → Bool} :
|
||||
abbrev getElem_set_eq := @getElem_set_self
|
||||
|
||||
@[simp] theorem getElem?_set_self {xs : Array α} {i : Nat} (h : i < xs.size) {v : α} :
|
||||
(xs.set i v)[i]? = some v := by simp [getElem?_eq_getElem, h]
|
||||
(xs.set i v)[i]? = some v := by simp [h]
|
||||
|
||||
@[deprecated getElem?_set_self (since := "2024-12-11")]
|
||||
abbrev getElem?_set_eq := @getElem?_set_self
|
||||
@@ -918,7 +918,7 @@ abbrev getElem?_set_eq := @getElem?_set_self
|
||||
|
||||
@[simp] theorem getElem?_set_ne {xs : Array α} {i : Nat} (h : i < xs.size) {v : α} {j : Nat}
|
||||
(ne : i ≠ j) : (xs.set i v)[j]? = xs[j]? := by
|
||||
by_cases h : j < xs.size <;> simp [getElem?_eq_getElem, getElem?_eq_none, Nat.ge_of_not_lt, ne, h]
|
||||
by_cases h : j < xs.size <;> simp [ne, h]
|
||||
|
||||
@[grind] theorem getElem_set {xs : Array α} {i : Nat} (h' : i < xs.size) {v : α} {j : Nat}
|
||||
(h : j < (xs.set i v).size) :
|
||||
@@ -1044,7 +1044,7 @@ theorem getElem?_setIfInBounds_self {xs : Array α} {i : Nat} {a : α} :
|
||||
@[simp]
|
||||
theorem getElem?_setIfInBounds_self_of_lt {xs : Array α} {i : Nat} {a : α} (h : i < xs.size) :
|
||||
(xs.setIfInBounds i a)[i]? = some a := by
|
||||
simp [getElem?_setIfInBounds, h]
|
||||
simp [h]
|
||||
|
||||
@[deprecated getElem?_setIfInBounds_self (since := "2024-12-11")]
|
||||
abbrev getElem?_setIfInBounds_eq := @getElem?_setIfInBounds_self
|
||||
@@ -1088,7 +1088,7 @@ theorem mem_or_eq_of_mem_setIfInBounds
|
||||
@[simp] theorem getD_getElem?_setIfInBounds {xs : Array α} {i : Nat} {v d : α} :
|
||||
(xs.setIfInBounds i v)[i]?.getD d = if i < xs.size then v else d := by
|
||||
by_cases h : i < xs.size <;>
|
||||
simp [setIfInBounds, Nat.not_lt_of_le, h, getD_getElem?]
|
||||
simp [setIfInBounds, h, ]
|
||||
|
||||
@[simp, grind =] theorem toList_setIfInBounds {xs : Array α} {i : Nat} {x : α} :
|
||||
(xs.setIfInBounds i x).toList = xs.toList.set i x := by
|
||||
@@ -1200,7 +1200,7 @@ where
|
||||
mapM.map f xs i bs = (xs.toList.drop i).foldlM (fun bs a => bs.push <$> f a) bs := by
|
||||
unfold mapM.map; split
|
||||
· rw [← List.getElem_cons_drop_succ_eq_drop ‹_›]
|
||||
simp only [aux (i + 1), map_eq_pure_bind, length_toList, List.foldlM_cons, bind_assoc,
|
||||
simp only [aux (i + 1), map_eq_pure_bind, List.foldlM_cons, bind_assoc,
|
||||
pure_bind]
|
||||
rfl
|
||||
· rw [List.drop_of_length_le (Nat.ge_of_not_lt ‹_›)]; rfl
|
||||
@@ -1755,7 +1755,7 @@ theorem forall_mem_filterMap {f : α → Option β} {xs : Array α} {P : β →
|
||||
|
||||
theorem map_filterMap_of_inv {f : α → Option β} {g : β → α} (H : ∀ x : α, (f x).map g = some x) {xs : Array α} :
|
||||
map g (filterMap f xs) = xs := by
|
||||
simp only [map_filterMap, H, filterMap_some, id]
|
||||
simp only [map_filterMap, H, filterMap_some]
|
||||
|
||||
@[grind →]
|
||||
theorem forall_none_of_filterMap_eq_empty (h : filterMap f xs = #[]) : ∀ x ∈ xs, f x = none := by
|
||||
@@ -1894,7 +1894,7 @@ theorem getElem?_append_left {xs ys : Array α} {i : Nat} (hn : i < xs.size) :
|
||||
(xs ++ ys)[i]? = xs[i]? := by
|
||||
have hn' : i < (xs ++ ys).size := Nat.lt_of_lt_of_le hn <|
|
||||
size_append .. ▸ Nat.le_add_right ..
|
||||
simp_all [getElem?_eq_getElem, getElem_append]
|
||||
simp_all
|
||||
|
||||
theorem getElem?_append_right {xs ys : Array α} {i : Nat} (h : xs.size ≤ i) :
|
||||
(xs ++ ys)[i]? = ys[i - xs.size]? := by
|
||||
@@ -2025,7 +2025,7 @@ theorem append_eq_singleton_iff {xs ys : Array α} {x : α} :
|
||||
xs ++ ys = #[x] ↔ (xs = #[] ∧ ys = #[x]) ∨ (xs = #[x] ∧ ys = #[]) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
rcases ys with ⟨ys⟩
|
||||
simp only [List.append_toArray, mk.injEq, List.append_eq_singleton_iff, toArray_eq_append_iff]
|
||||
simp only [List.append_toArray, mk.injEq, List.append_eq_singleton_iff]
|
||||
|
||||
theorem singleton_eq_append_iff {xs ys : Array α} {x : α} :
|
||||
#[x] = xs ++ ys ↔ (xs = #[] ∧ ys = #[x]) ∨ (xs = #[x] ∧ ys = #[]) := by
|
||||
@@ -2351,7 +2351,7 @@ theorem flatMap_toArray {β} {f : α → Array β} {as : List α} :
|
||||
theorem size_flatMap {xs : Array α} {f : α → Array β} :
|
||||
(xs.flatMap f).size = sum (map (fun a => (f a).size) xs) := by
|
||||
rcases xs with ⟨l⟩
|
||||
simp [Function.comp_def]
|
||||
simp
|
||||
|
||||
@[simp, grind] theorem mem_flatMap {f : α → Array β} {b} {xs : Array α} : b ∈ xs.flatMap f ↔ ∃ a, a ∈ xs ∧ b ∈ f a := by
|
||||
simp [flatMap_def, mem_flatten]
|
||||
@@ -2569,7 +2569,7 @@ abbrev map_mkArray := @map_replicate
|
||||
@[grind] theorem filter_replicate (w : stop = n) :
|
||||
(replicate n a).filter p 0 stop = if p a then replicate n a else #[] := by
|
||||
apply Array.ext'
|
||||
simp only [w, toList_filter', toList_replicate, List.filter_replicate]
|
||||
simp only [w]
|
||||
split <;> simp_all
|
||||
|
||||
@[deprecated filter_replicate (since := "2025-03-18")]
|
||||
@@ -2609,7 +2609,7 @@ abbrev filterMap_mkArray_of_some := @filterMap_replicate_of_some
|
||||
@[simp] theorem filterMap_replicate_of_isSome {f : α → Option β} (h : (f a).isSome) :
|
||||
(replicate n a).filterMap f = replicate n (Option.get _ h) := by
|
||||
match w : f a, h with
|
||||
| some b, _ => simp [filterMap_replicate, h, w]
|
||||
| some b, _ => simp [filterMap_replicate, w]
|
||||
|
||||
@[deprecated filterMap_replicate_of_isSome (since := "2025-03-18")]
|
||||
abbrev filterMap_mkArray_of_isSome := @filterMap_replicate_of_isSome
|
||||
@@ -2644,7 +2644,7 @@ abbrev flatten_mkArray_replicate := @flatten_replicate_replicate
|
||||
|
||||
theorem flatMap_replicate {f : α → Array β} : (replicate n a).flatMap f = (replicate n (f a)).flatten := by
|
||||
rw [← toList_inj]
|
||||
simp [flatMap_toList, List.flatMap_replicate]
|
||||
simp [List.flatMap_replicate]
|
||||
|
||||
@[deprecated flatMap_replicate (since := "2025-03-18")]
|
||||
abbrev flatMap_mkArray := @flatMap_replicate
|
||||
@@ -4142,7 +4142,7 @@ theorem getElem_modify_of_ne {xs : Array α} {i : Nat} (h : i ≠ j)
|
||||
|
||||
@[simp] theorem getElem_swap_right {xs : Array α} {i j : Nat} {hi hj} :
|
||||
(xs.swap i j hi hj)[j]'(by simpa using hj) = xs[i] := by
|
||||
simp [swap_def, getElem_set]
|
||||
simp [swap_def]
|
||||
|
||||
@[simp] theorem getElem_swap_left {xs : Array α} {i j : Nat} {hi hj} :
|
||||
(xs.swap i j hi hj)[i]'(by simpa using hi) = xs[j] := by
|
||||
@@ -4439,7 +4439,7 @@ theorem size_uset {xs : Array α} {v : α} {i : USize} (h : i.toNat < xs.size) :
|
||||
|
||||
@[simp] theorem getD_eq_getD_getElem? {xs : Array α} {i : Nat} {d : α} :
|
||||
xs.getD i d = xs[i]?.getD d := by
|
||||
simp only [getD]; split <;> simp [getD_getElem?, *]
|
||||
simp only [getD]; split <;> simp [*]
|
||||
|
||||
theorem getElem!_eq_getD [Inhabited α] {xs : Array α} {i} : xs[i]! = xs.getD i default := by
|
||||
rfl
|
||||
@@ -4467,13 +4467,13 @@ theorem getElem?_size_le {xs : Array α} {i : Nat} (h : xs.size ≤ i) : xs[i]?
|
||||
simp [getElem?_neg, h]
|
||||
|
||||
theorem getElem_mem_toList {xs : Array α} {i : Nat} (h : i < xs.size) : xs[i] ∈ xs.toList := by
|
||||
simp only [← getElem_toList, List.getElem_mem, ugetElem_eq_getElem]
|
||||
simp only [← getElem_toList, List.getElem_mem]
|
||||
|
||||
theorem back!_eq_back? [Inhabited α] {xs : Array α} : xs.back! = xs.back?.getD default := by
|
||||
simp [back!, back?, getElem!_def, Option.getD]; rfl
|
||||
|
||||
@[simp, grind] theorem back?_push {xs : Array α} {x : α} : (xs.push x).back? = some x := by
|
||||
simp [back?, ← getElem?_toList]
|
||||
simp [back?]
|
||||
|
||||
@[simp] theorem back!_push [Inhabited α] {xs : Array α} {x : α} : (xs.push x).back! = x := by
|
||||
simp [back!_eq_back?]
|
||||
@@ -4622,7 +4622,7 @@ theorem uset_toArray {l : List α} {i : USize} {a : α} {h : i.toNat < l.toArray
|
||||
@[simp, grind =] theorem flatten_toArray {L : List (List α)} :
|
||||
(L.toArray.map List.toArray).flatten = L.flatten.toArray := by
|
||||
apply ext'
|
||||
simp [Function.comp_def]
|
||||
simp
|
||||
|
||||
end List
|
||||
|
||||
@@ -4714,7 +4714,7 @@ namespace List
|
||||
intro h'
|
||||
specialize ih (by omega)
|
||||
have : as.length - (i + 1) + 1 = as.length - i := by omega
|
||||
simp_all [ih]
|
||||
simp_all
|
||||
· simp only [size_toArray, Nat.not_lt] at h
|
||||
have : as.length = 0 := by omega
|
||||
simp_all
|
||||
@@ -4725,7 +4725,7 @@ end List
|
||||
namespace Array
|
||||
|
||||
@[deprecated size_toArray (since := "2024-12-11")]
|
||||
theorem size_mk (as : List α) : (Array.mk as).size = as.length := by simp [size]
|
||||
theorem size_mk (as : List α) : (Array.mk as).size = as.length := by simp
|
||||
|
||||
@[deprecated getElem?_eq_getElem (since := "2024-12-11")]
|
||||
theorem getElem?_lt
|
||||
@@ -4741,7 +4741,7 @@ theorem get?_eq_getElem? (xs : Array α) (i : Nat) : xs.get? i = xs[i]? := rfl
|
||||
|
||||
@[deprecated getElem?_eq_none (since := "2024-12-11")]
|
||||
theorem getElem?_len_le (xs : Array α) {i : Nat} (h : xs.size ≤ i) : xs[i]? = none := by
|
||||
simp [getElem?_eq_none, h]
|
||||
simp [h]
|
||||
|
||||
@[deprecated getD_getElem? (since := "2024-12-11")] abbrev getD_get? := @getD_getElem?
|
||||
|
||||
@@ -4756,7 +4756,7 @@ set_option linter.deprecated false in
|
||||
theorem get!_eq_getD_getElem? [Inhabited α] (xs : Array α) (i : Nat) :
|
||||
xs.get! i = xs[i]?.getD default := by
|
||||
by_cases p : i < xs.size <;>
|
||||
simp [get!, getElem!_eq_getD, getD_eq_getD_getElem?, getD_getElem?, p]
|
||||
simp [get!, getD_eq_getD_getElem?, p]
|
||||
|
||||
set_option linter.deprecated false in
|
||||
@[deprecated get!_eq_getD_getElem? (since := "2025-02-12")] abbrev get!_eq_getElem? := @get!_eq_getD_getElem?
|
||||
|
||||
@@ -162,7 +162,7 @@ instance [DecidableEq α] [LT α] [DecidableLT α]
|
||||
{xs ys : Array α} : lex xs ys = false ↔ ys ≤ xs := by
|
||||
cases xs
|
||||
cases ys
|
||||
simp [List.not_lt_iff_ge]
|
||||
simp
|
||||
|
||||
instance [DecidableEq α] [LT α] [DecidableLT α] : DecidableLT (Array α) :=
|
||||
fun xs ys => decidable_of_iff (lex xs ys = true) lex_eq_true_iff_lt
|
||||
|
||||
@@ -135,7 +135,7 @@ abbrev getElem_zipWithIndex := @getElem_zipIdx
|
||||
|
||||
@[simp, grind =] theorem zipIdx_toArray {l : List α} {k : Nat} :
|
||||
l.toArray.zipIdx k = (l.zipIdx k).toArray := by
|
||||
ext i hi₁ hi₂ <;> simp [Nat.add_comm]
|
||||
ext i hi₁ hi₂ <;> simp
|
||||
|
||||
@[deprecated zipIdx_toArray (since := "2025-01-21")]
|
||||
abbrev zipWithIndex_toArray := @zipIdx_toArray
|
||||
|
||||
@@ -59,7 +59,7 @@ theorem mapM_eq_foldlM_push [Monad m] [LawfulMonad m] {f : α → m β} {xs : Ar
|
||||
rcases xs with ⟨xs⟩
|
||||
simp only [List.mapM_toArray, bind_pure_comp, List.size_toArray, List.foldlM_toArray']
|
||||
rw [List.mapM_eq_reverse_foldlM_cons]
|
||||
simp only [bind_pure_comp, Functor.map_map]
|
||||
simp only [Functor.map_map]
|
||||
suffices ∀ (l), (fun l' => l'.reverse.toArray) <$> List.foldlM (fun acc a => (fun a => a :: acc) <$> f a) l xs =
|
||||
List.foldlM (fun acc a => acc.push <$> f a) l.reverse.toArray xs by
|
||||
exact this []
|
||||
@@ -234,14 +234,14 @@ theorem forIn_eq_foldlM [Monad m] [LawfulMonad m]
|
||||
forIn xs init (fun a b => (fun c => .yield (g a b c)) <$> f a b) =
|
||||
xs.foldlM (fun b a => g a b <$> f a b) init := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.foldlM_map]
|
||||
simp
|
||||
|
||||
@[simp] theorem forIn_pure_yield_eq_foldl [Monad m] [LawfulMonad m]
|
||||
{xs : Array α} (f : α → β → β) (init : β) :
|
||||
forIn xs init (fun a b => pure (.yield (f a b))) =
|
||||
pure (f := m) (xs.foldl (fun b a => f a b) init) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
simp [List.forIn_pure_yield_eq_foldl, List.foldl_map]
|
||||
simp [List.forIn_pure_yield_eq_foldl]
|
||||
|
||||
theorem idRun_forIn_yield_eq_foldl
|
||||
{xs : Array α} (f : α → β → Id β) (init : β) :
|
||||
|
||||
@@ -219,7 +219,7 @@ theorem getElem?_zipIdx {xs : Array α} {i j} : (zipIdx xs i)[j]? = xs[j]?.map f
|
||||
|
||||
theorem map_snd_add_zipIdx_eq_zipIdx {xs : Array α} {n k : Nat} :
|
||||
map (Prod.map id (· + n)) (zipIdx xs k) = zipIdx xs (n + k) :=
|
||||
ext_getElem? fun i ↦ by simp [(· ∘ ·), Nat.add_comm, Nat.add_left_comm]; rfl
|
||||
ext_getElem? fun i ↦ by simp [Nat.add_comm, Nat.add_left_comm]; rfl
|
||||
|
||||
-- Arguments are explicit for parity with `zipIdx_map_fst`.
|
||||
@[simp]
|
||||
|
||||
@@ -240,7 +240,7 @@ theorem toNat_add_of_and_eq_zero {x y : BitVec w} (h : x &&& y = 0#w) :
|
||||
simp only [decide_eq_true_eq] at this
|
||||
omega
|
||||
rw [← carry_width]
|
||||
simp [not_eq_true, carry_of_and_eq_zero h]
|
||||
simp [carry_of_and_eq_zero h]
|
||||
|
||||
/-- Carry function for bitwise addition. -/
|
||||
def adcb (x y c : Bool) : Bool × Bool := (atLeastTwo x y c, x ^^ (y ^^ c))
|
||||
@@ -254,7 +254,7 @@ theorem getLsbD_add_add_bool {i : Nat} (i_lt : i < w) (x y : BitVec w) (c : Bool
|
||||
(getLsbD x i ^^ (getLsbD y i ^^ carry i x y c)) := by
|
||||
let ⟨x, x_lt⟩ := x
|
||||
let ⟨y, y_lt⟩ := y
|
||||
simp only [getLsbD, toNat_add, toNat_setWidth, i_lt, toNat_ofFin, toNat_ofBool,
|
||||
simp only [getLsbD, toNat_add, toNat_setWidth, toNat_ofFin, toNat_ofBool,
|
||||
Nat.mod_add_mod, Nat.add_mod_mod]
|
||||
apply Eq.trans
|
||||
rw [← Nat.div_add_mod x (2^i), ← Nat.div_add_mod y (2^i)]
|
||||
@@ -297,7 +297,7 @@ theorem adc_spec (x y : BitVec w) (c : Bool) :
|
||||
simp [carry, Nat.mod_one]
|
||||
cases c <;> rfl
|
||||
case step =>
|
||||
simp [adcb, Prod.mk.injEq, carry_succ, getElem_add_add_bool]
|
||||
simp [adcb, carry_succ, getElem_add_add_bool]
|
||||
|
||||
theorem add_eq_adc (w : Nat) (x y : BitVec w) : x + y = (adc x y false).snd := by
|
||||
simp [adc_spec]
|
||||
@@ -314,7 +314,7 @@ theorem msb_add {w : Nat} {x y: BitVec w} :
|
||||
Bool.xor x.msb (Bool.xor y.msb (carry (w - 1) x y false)) := by
|
||||
simp only [BitVec.msb, BitVec.getMsbD]
|
||||
by_cases h : w ≤ 0
|
||||
· simp [h, show w = 0 by omega]
|
||||
· simp [show w = 0 by omega]
|
||||
· rw [getLsbD_add (x := x)]
|
||||
simp [show w > 0 by omega]
|
||||
omega
|
||||
@@ -334,15 +334,15 @@ theorem add_eq_or_of_and_eq_zero {w : Nat} (x y : BitVec w)
|
||||
(h : x &&& y = 0#w) : x + y = x ||| y := by
|
||||
rw [add_eq_adc, adc, iunfoldr_replace (fun _ => false) (x ||| y)]
|
||||
· rfl
|
||||
· simp only [adcb, atLeastTwo, Bool.and_false, Bool.or_false, bne_false, getLsbD_or,
|
||||
· simp only [adcb, atLeastTwo, Bool.and_false, Bool.or_false, bne_false,
|
||||
Prod.mk.injEq, and_eq_false_imp]
|
||||
intros i
|
||||
replace h : (x &&& y).getLsbD i = (0#w).getLsbD i := by rw [h]
|
||||
simp only [getLsbD_and, getLsbD_zero, and_eq_false_imp] at h
|
||||
constructor
|
||||
· intros hx
|
||||
simp_all [hx]
|
||||
· by_cases hx : x.getLsbD i <;> simp_all [hx]
|
||||
simp_all
|
||||
· by_cases hx : x.getLsbD i <;> simp_all
|
||||
|
||||
/-! ### Sub-/
|
||||
|
||||
@@ -379,7 +379,7 @@ theorem bit_not_add_self (x : BitVec w) :
|
||||
simp only [add_eq_adc]
|
||||
apply iunfoldr_replace_snd (fun _ => false) (-1) false rfl
|
||||
intro i; simp only [adcb, Fin.is_lt, getLsbD_eq_getElem, atLeastTwo_false_right, bne_false,
|
||||
ofNat_eq_ofNat, Fin.getElem_fin, Prod.mk.injEq, and_eq_false_imp]
|
||||
ofNat_eq_ofNat, Prod.mk.injEq, and_eq_false_imp]
|
||||
rw [iunfoldr_replace_snd (fun _ => ()) (((iunfoldr (fun i c => (c, !(x[i.val])))) ()).snd)]
|
||||
<;> simp [bit_not_testBit, neg_one_eq_allOnes, getElem_allOnes]
|
||||
|
||||
@@ -411,7 +411,7 @@ theorem getLsbD_neg {i : Nat} {x : BitVec w} :
|
||||
· rw [getLsbD_add hi]
|
||||
have : 0 < w := by omega
|
||||
simp only [getLsbD_not, hi, decide_true, Bool.true_and, getLsbD_one, this, not_bne,
|
||||
_root_.true_and, not_eq_eq_eq_not]
|
||||
not_eq_eq_eq_not]
|
||||
cases i with
|
||||
| zero =>
|
||||
have carry_zero : carry 0 ?x ?y false = false := by
|
||||
@@ -426,7 +426,7 @@ theorem getLsbD_neg {i : Nat} {x : BitVec w} :
|
||||
· rintro h j hj; exact And.right <| h j (by omega)
|
||||
· rintro h j hj; exact ⟨by omega, h j (by omega)⟩
|
||||
· have h_ge : w ≤ i := by omega
|
||||
simp [getLsbD_of_ge _ _ h_ge, h_ge, hi]
|
||||
simp [h_ge, hi]
|
||||
|
||||
theorem getElem_neg {i : Nat} {x : BitVec w} (h : i < w) :
|
||||
(-x)[i] = (x[i] ^^ decide (∃ j < i, x.getLsbD j = true)) := by
|
||||
@@ -435,7 +435,7 @@ theorem getElem_neg {i : Nat} {x : BitVec w} (h : i < w) :
|
||||
theorem getMsbD_neg {i : Nat} {x : BitVec w} :
|
||||
getMsbD (-x) i =
|
||||
(getMsbD x i ^^ decide (∃ j < w, i < j ∧ getMsbD x j = true)) := by
|
||||
simp only [getMsbD, getLsbD_neg, Bool.decide_and, Bool.and_eq_true, decide_eq_true_eq]
|
||||
simp only [getMsbD, getLsbD_neg, Bool.and_eq_true, decide_eq_true_eq]
|
||||
by_cases hi : i < w
|
||||
case neg =>
|
||||
simp [hi]; omega
|
||||
@@ -524,7 +524,7 @@ theorem msb_neg {w : Nat} {x : BitVec w} :
|
||||
|
||||
theorem msb_abs {w : Nat} {x : BitVec w} :
|
||||
x.abs.msb = (decide (x = intMin w) && decide (0 < w)) := by
|
||||
simp only [BitVec.abs, getMsbD_neg, ne_eq, decide_not, Bool.not_bne]
|
||||
simp only [BitVec.abs]
|
||||
by_cases h₀ : 0 < w
|
||||
· by_cases h₁ : x = intMin w
|
||||
· simp [h₁, msb_intMin]
|
||||
@@ -611,7 +611,7 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_add_twoPow (x : BitVec w) (i
|
||||
getElem_twoPow]
|
||||
by_cases hik : i = k
|
||||
· subst hik
|
||||
simp [h]
|
||||
simp
|
||||
· by_cases hik' : k < (i + 1)
|
||||
· have hik'' : k < i := by omega
|
||||
simp [hik', hik'']
|
||||
@@ -620,8 +620,8 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_add_twoPow (x : BitVec w) (i
|
||||
simp [hik', hik'']
|
||||
omega
|
||||
· ext k
|
||||
simp only [and_twoPow, getLsbD_and, getLsbD_setWidth, Fin.is_lt, decide_true, Bool.true_and,
|
||||
getLsbD_zero, and_eq_false_imp, and_eq_true, decide_eq_true_eq, and_imp]
|
||||
simp only [and_twoPow,
|
||||
]
|
||||
by_cases hi : x.getLsbD i <;> simp [hi] <;> omega
|
||||
|
||||
/--
|
||||
@@ -778,7 +778,7 @@ private theorem Nat.div_add_eq_left_of_lt {x y z : Nat} (hx : z ∣ x) (hy : y <
|
||||
· apply Nat.le_trans
|
||||
· exact div_mul_le_self x z
|
||||
· omega
|
||||
· simp only [succ_eq_add_one, Nat.add_mul, Nat.one_mul]
|
||||
· simp only [Nat.add_mul, Nat.one_mul]
|
||||
apply Nat.add_lt_add_of_le_of_lt
|
||||
· apply Nat.le_of_eq
|
||||
exact (Nat.div_eq_iff_eq_mul_left hz hx).mp rfl
|
||||
@@ -891,10 +891,10 @@ def DivModState.lawful_init {w : Nat} (args : DivModArgs w) (hd : 0#w < args.d)
|
||||
hwrn := by simp only; omega,
|
||||
hdPos := by assumption
|
||||
hrLtDivisor := by simp [BitVec.lt_def] at hd ⊢; assumption
|
||||
hrWidth := by simp [DivModState.init],
|
||||
hqWidth := by simp [DivModState.init],
|
||||
hrWidth := by simp,
|
||||
hqWidth := by simp,
|
||||
hdiv := by
|
||||
simp only [DivModState.init, toNat_ofNat, zero_mod, Nat.mul_zero, Nat.add_zero];
|
||||
simp only [toNat_ofNat, zero_mod, Nat.mul_zero, Nat.add_zero];
|
||||
rw [Nat.shiftRight_eq_div_pow]
|
||||
apply Nat.div_eq_of_lt args.n.isLt
|
||||
}
|
||||
@@ -922,7 +922,7 @@ theorem DivModState.umod_eq_of_lawful {qr : DivModState w}
|
||||
n % d = qr.r := by
|
||||
apply umod_eq_of_mul_add_toNat h.hrLtDivisor
|
||||
have hdiv := h.hdiv
|
||||
simp only [shiftRight_zero] at hdiv
|
||||
simp only at hdiv
|
||||
simp only [h_final] at *
|
||||
exact hdiv.symm
|
||||
|
||||
@@ -1000,7 +1000,7 @@ obeys the division equation. -/
|
||||
theorem lawful_divSubtractShift (qr : DivModState w) (h : qr.Poised args) :
|
||||
DivModState.Lawful args (divSubtractShift args qr) := by
|
||||
rcases args with ⟨n, d⟩
|
||||
simp only [divSubtractShift, decide_eq_true_eq]
|
||||
simp only [divSubtractShift]
|
||||
-- We add these hypotheses for `omega` to find them later.
|
||||
have ⟨⟨hrwn, hd, hrd, hr, hn, hrnd⟩, hwn_lt⟩ := h
|
||||
have : d.toNat * (qr.q.toNat * 2) = d.toNat * qr.q.toNat * 2 := by rw [Nat.mul_assoc]
|
||||
@@ -1137,7 +1137,7 @@ theorem getLsbD_udiv (n d : BitVec w) (hy : 0#w < d) (i : Nat) :
|
||||
|
||||
theorem getMsbD_udiv (n d : BitVec w) (hd : 0#w < d) (i : Nat) :
|
||||
(n / d).getMsbD i = (decide (i < w) && (divRec w {n, d} (DivModState.init w)).q.getMsbD i) := by
|
||||
simp [getMsbD_eq_getLsbD, getLsbD_udiv, udiv_eq_divRec (by assumption)]
|
||||
simp [getMsbD_eq_getLsbD, udiv_eq_divRec (by assumption)]
|
||||
|
||||
/- ### Arithmetic shift right (sshiftRight) recurrence -/
|
||||
|
||||
@@ -1304,7 +1304,7 @@ theorem negOverflow_eq {w : Nat} (x : BitVec w) :
|
||||
(negOverflow x) = (decide (0 < w) && (x == intMin w)) := by
|
||||
simp only [negOverflow]
|
||||
rcases w with _|w
|
||||
· simp [toInt_of_zero_length, Int.min_eq_right]
|
||||
· simp [toInt_of_zero_length]
|
||||
· suffices - 2 ^ w = (intMin (w + 1)).toInt by simp [beq_eq_decide_eq, ← toInt_inj, this]
|
||||
simp only [toInt_intMin, Nat.add_one_sub_one, Int.natCast_emod, Int.neg_inj]
|
||||
rw_mod_cast [Nat.mod_eq_of_lt (by simp [Nat.pow_lt_pow_succ])]
|
||||
@@ -1346,7 +1346,7 @@ theorem umulOverflow_eq {w : Nat} (x y : BitVec w) :
|
||||
(0 < w && BitVec.twoPow (w * 2) w ≤ x.zeroExtend (w * 2) * y.zeroExtend (w * 2)) := by
|
||||
simp only [umulOverflow, toNat_twoPow, le_def, toNat_mul, toNat_setWidth, mod_mul_mod]
|
||||
rcases w with _|w
|
||||
· simp [of_length_zero, toInt_zero, mul_mod_mod]
|
||||
· simp [of_length_zero]
|
||||
· simp only [ge_iff_le, show 0 < w + 1 by omega, decide_true, mul_mod_mod, Bool.true_and,
|
||||
decide_eq_decide]
|
||||
rw [Nat.mod_eq_of_lt BitVec.toNat_mul_toNat_lt, Nat.mod_eq_of_lt]
|
||||
@@ -1582,11 +1582,11 @@ theorem toInt_sdiv_of_ne_or_ne (a b : BitVec w) (h : a ≠ intMin w ∨ b ≠ -1
|
||||
have := Nat.two_pow_pos (w - 1)
|
||||
|
||||
by_cases hbintMin : b = intMin w
|
||||
· simp only [ne_eq, Decidable.not_not] at hbintMin
|
||||
· simp only at hbintMin
|
||||
subst hbintMin
|
||||
have toIntA_lt := @BitVec.toInt_lt w a; norm_cast at toIntA_lt
|
||||
have le_toIntA := @BitVec.le_toInt w a; norm_cast at le_toIntA
|
||||
simp only [sdiv_intMin, h, ↓reduceIte, toInt_zero, toInt_intMin, wpos,
|
||||
simp only [sdiv_intMin, toInt_intMin, wpos,
|
||||
Nat.two_pow_pred_mod_two_pow, Int.tdiv_neg]
|
||||
· by_cases ha_intMin : a = intMin w
|
||||
· simp only [ha_intMin, ↓reduceIte, show 1 < w by omega, toInt_one, toInt_intMin, wpos,
|
||||
@@ -1763,7 +1763,7 @@ theorem msb_umod_of_le_of_ne_zero_of_le {x y : BitVec w}
|
||||
theorem toInt_srem (x y : BitVec w) : (x.srem y).toInt = x.toInt.tmod y.toInt := by
|
||||
rw [srem_eq]
|
||||
by_cases hyz : y = 0#w
|
||||
· simp only [hyz, ofNat_eq_ofNat, msb_zero, umod_zero, neg_zero, neg_neg, toInt_zero, Int.tmod_zero]
|
||||
· simp only [hyz, msb_zero, umod_zero, neg_zero, neg_neg, toInt_zero, Int.tmod_zero]
|
||||
cases x.msb <;> rfl
|
||||
cases h : x.msb
|
||||
· cases h' : y.msb
|
||||
@@ -1842,7 +1842,7 @@ theorem toInt_umod_neg_add {x y : BitVec w} (hymsb : y.msb = true) (hxmsb : x.ms
|
||||
have hylt : (-y).toNat ≤ 2 ^ (w) := toNat_neg_lt_of_msb y hymsb
|
||||
have hmodlt := Nat.mod_lt x.toNat (y := (-y).toNat)
|
||||
(by rw [toNat_neg, Nat.mod_eq_of_lt (by omega)]; omega)
|
||||
simp only [hdvd, reduceIte, toInt_add, hxnonneg, show ¬0 ≤ y.toInt by omega]
|
||||
simp only [toInt_add]
|
||||
rw [toInt_umod, toInt_eq_neg_toNat_neg_of_msb_true hymsb, Int.bmod_add_bmod,
|
||||
Int.bmod_eq_of_le (by omega) (by omega),
|
||||
toInt_eq_toNat_of_msb hxmsb, Int.emod_neg]
|
||||
@@ -1857,7 +1857,7 @@ theorem toInt_sub_neg_umod {x y : BitVec w} (hxmsb : x.msb = true) (hymsb : y.ms
|
||||
· subst hyzero; simp
|
||||
· simp only [toNat_eq, toNat_ofNat, zero_mod] at hyzero
|
||||
have hypos : 0 < y.toNat := by omega
|
||||
simp only [reduceIte, toInt_sub, toInt_eq_toNat_of_msb hymsb, toInt_umod,
|
||||
simp only [toInt_sub, toInt_eq_toNat_of_msb hymsb, toInt_umod,
|
||||
Int.sub_bmod_bmod, toInt_eq_neg_toNat_neg_of_msb_true hxmsb, Int.neg_emod]
|
||||
have hmodlt := Nat.mod_lt (x := (-x).toNat) (y := y.toNat) hypos
|
||||
rw [Int.bmod_eq_of_le (by omega) (by omega)]
|
||||
@@ -1895,7 +1895,7 @@ theorem toInt_smod {x y : BitVec w} :
|
||||
· simp [show ¬-x % y = 0#(w + 1) by simp_all, toInt_sub_neg_umod hxmsb hymsb hx_dvd_y]
|
||||
· rw [←Int.neg_inj, neg_toInt_neg_umod_eq_of_msb_true_msb_true hxmsb hymsb]
|
||||
simp [BitVec.toInt_eq_neg_toNat_neg_of_msb_true, hxmsb, hymsb,
|
||||
Int.fmod_eq_emod_of_nonneg _, show 0 ≤ (-y).toNat by omega]
|
||||
Int.fmod_eq_emod_of_nonneg _]
|
||||
|
||||
/-! ### Lemmas that use bit blasting circuits -/
|
||||
|
||||
@@ -1929,7 +1929,7 @@ theorem carry_extractLsb'_eq_carry {w i len : Nat} (hi : i < len)
|
||||
{x y : BitVec w} {b : Bool}:
|
||||
(carry i (extractLsb' 0 len x) (extractLsb' 0 len y) b)
|
||||
= (carry i x y b) := by
|
||||
simp only [carry, extractLsb'_toNat, shiftRight_zero, toNat_false, Nat.add_zero, ge_iff_le,
|
||||
simp only [carry, extractLsb'_toNat, shiftRight_zero, ge_iff_le,
|
||||
decide_eq_decide]
|
||||
have : 2 ^ i ∣ 2^len := by
|
||||
apply Nat.pow_dvd_pow
|
||||
|
||||
@@ -64,14 +64,14 @@ theorem eq_of_getLsbD_eq {x y : BitVec w}
|
||||
|
||||
theorem getElem_cons {b : Bool} {n} {x : BitVec n} {i : Nat} (h : i < n + 1) :
|
||||
(cons b x)[i] = if h : i = n then b else x[i] := by
|
||||
simp only [getElem_eq_testBit_toNat, toNat_cons, Nat.testBit_or, getLsbD]
|
||||
simp only [getElem_eq_testBit_toNat, toNat_cons, Nat.testBit_or]
|
||||
rw [Nat.testBit_shiftLeft]
|
||||
rcases Nat.lt_trichotomy i n with i_lt_n | i_eq_n | n_lt_i
|
||||
· have p1 : ¬(n ≤ i) := by omega
|
||||
have p2 : i ≠ n := by omega
|
||||
simp [p1, p2]
|
||||
· simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_true, Nat.sub_self, Nat.testBit_zero,
|
||||
Bool.true_and, testBit_toNat, getLsbD_of_ge, Bool.or_false, ↓reduceIte]
|
||||
Bool.true_and, testBit_toNat, getLsbD_of_ge, Bool.or_false]
|
||||
cases b <;> trivial
|
||||
· have p1 : i ≠ n := by omega
|
||||
have p2 : i - n ≠ 0 := by omega
|
||||
|
||||
@@ -82,9 +82,9 @@ theorem iunfoldr_getLsbD' {f : Fin w → α → α × Bool} (state : Nat → α)
|
||||
simp only [getLsbD_cons]
|
||||
have hj2 : j.val ≤ w := by simp
|
||||
cases (Nat.lt_or_eq_of_le (Nat.lt_succ.mp i.isLt)) with
|
||||
| inl h3 => simp [if_neg, (Nat.ne_of_lt h3)]
|
||||
| inl h3 => simp [(Nat.ne_of_lt h3)]
|
||||
exact (ih hj2).1 ⟨i.val, h3⟩
|
||||
| inr h3 => simp [h3, if_pos]
|
||||
| inr h3 => simp [h3]
|
||||
cases (Nat.eq_zero_or_pos j.val) with
|
||||
| inl hj3 => congr
|
||||
rw [← (ih hj2).2]
|
||||
|
||||
@@ -96,8 +96,8 @@ theorem getElem_eq_iff {l : BitVec w} {n : Nat} {h : n < w} : l[n] = x ↔ l[n]?
|
||||
exact ⟨fun w => ⟨h, w⟩, fun h => h.2⟩
|
||||
|
||||
theorem getElem_eq_getElem? (l : BitVec w) (i : Nat) (h : i < w) :
|
||||
l[i] = l[i]?.get (by simp [getElem?_eq_getElem, h]) := by
|
||||
simp [getElem_eq_iff]
|
||||
l[i] = l[i]?.get (by simp [h]) := by
|
||||
simp
|
||||
|
||||
theorem getLsbD_eq_getElem?_getD {x : BitVec w} {i : Nat} :
|
||||
x.getLsbD i = x[i]?.getD false := by
|
||||
@@ -164,7 +164,7 @@ theorem getMsb'_eq_getLsb' (x : BitVec w) (i : Nat) : x.getMsbD i = (decide (i <
|
||||
theorem getLsbD_eq_getMsbD (x : BitVec w) (i : Nat) : x.getLsbD i = (decide (i < w) && x.getMsbD (w - 1 - i)) := by
|
||||
rw [getMsbD]
|
||||
by_cases h₁ : i < w <;> by_cases h₂ : w - 1 - i < w <;>
|
||||
simp only [h₁, h₂] <;> simp only [decide_true, decide_false, Bool.false_and, Bool.and_false, Bool.true_and, Bool.and_true]
|
||||
simp only [h₁, h₂] <;> simp only [decide_true, decide_false, Bool.false_and, Bool.and_false, Bool.true_and]
|
||||
· congr
|
||||
omega
|
||||
all_goals
|
||||
@@ -274,9 +274,9 @@ theorem toNat_of_zero_length (h : w = 0) (x : BitVec w) : x.toNat = 0 := by
|
||||
theorem toInt_of_zero_length (h : w = 0) (x : BitVec w) : x.toInt = 0 := by
|
||||
subst h; simp [toInt_zero_length]
|
||||
theorem getLsbD_of_zero_length (h : w = 0) (x : BitVec w) : x.getLsbD i = false := by
|
||||
subst h; simp [getLsbD_zero_length]
|
||||
subst h; simp
|
||||
theorem getMsbD_of_zero_length (h : w = 0) (x : BitVec w) : x.getMsbD i = false := by
|
||||
subst h; simp [getMsbD_zero_length]
|
||||
subst h; simp
|
||||
theorem msb_of_zero_length (h : w = 0) (x : BitVec w) : x.msb = false := by
|
||||
subst h; simp [msb_zero_length]
|
||||
theorem eq_of_zero_length (h : w = 0) {x y : BitVec w} : x = y := by
|
||||
@@ -287,7 +287,7 @@ theorem length_pos_of_ne {x y : BitVec w} (h : x ≠ y) : 0 < w :=
|
||||
|
||||
theorem ofFin_ofNat (n : Nat) :
|
||||
ofFin (no_index (OfNat.ofNat n : Fin (2^w))) = OfNat.ofNat n := by
|
||||
simp only [OfNat.ofNat, Fin.ofNat, BitVec.ofNat, Nat.and_two_pow_sub_one_eq_mod]
|
||||
simp only [OfNat.ofNat, Fin.ofNat, BitVec.ofNat]
|
||||
|
||||
@[simp] theorem ofFin_neg {x : Fin (2 ^ w)} : ofFin (-x) = -(ofFin x) := by
|
||||
rfl
|
||||
@@ -305,7 +305,7 @@ theorem toFin_inj {x y : BitVec w} : x.toFin = y.toFin ↔ x = y := by
|
||||
exact @eq_of_toFin_eq w x y
|
||||
case mpr =>
|
||||
intro h
|
||||
simp [toFin, h]
|
||||
simp [h]
|
||||
|
||||
theorem toFin_zero : toFin (0 : BitVec w) = 0 := rfl
|
||||
theorem toFin_one : toFin (1 : BitVec w) = 1 := by
|
||||
@@ -394,7 +394,7 @@ theorem getLsbD_ofNat (n : Nat) (x : Nat) (i : Nat) :
|
||||
<;> simp [h, Nat.testBit_eq_decide_div_mod_eq, Nat.div_eq_of_lt]
|
||||
|
||||
@[simp] theorem getElem_one (h : i < w) : (1#w)[i] = decide (i = 0) := by
|
||||
simp [← getLsbD_eq_getElem, getLsbD_one, h, show 0 < w by omega]
|
||||
simp [← getLsbD_eq_getElem, getLsbD_one, show 0 < w by omega]
|
||||
|
||||
/-- The msb at index `w-1` is the least significant bit, and is true when the width is nonzero. -/
|
||||
@[simp] theorem getMsbD_one : (1#w).getMsbD i = (decide (i = w - 1) && decide (0 < w)) := by
|
||||
@@ -428,7 +428,7 @@ theorem getLsbD_ofNat (n : Nat) (x : Nat) (i : Nat) :
|
||||
|
||||
@[simp] theorem sub_sub_toNat_cancel {x : BitVec w} :
|
||||
2 ^ w - (2 ^ w - x.toNat) = x.toNat := by
|
||||
simp [Nat.sub_sub_eq_min, Nat.min_eq_right]
|
||||
simp [Nat.sub_sub_eq_min]
|
||||
omega
|
||||
|
||||
@[simp] theorem sub_add_bmod_cancel {x y : BitVec w} :
|
||||
@@ -703,18 +703,18 @@ theorem toInt_one (h : 1 < w) : (1#w : BitVec w).toInt = 1 := by
|
||||
|
||||
@[simp] theorem sub_toNat_mod_cancel_of_msb_true {x : BitVec w} (h : x.msb = true) :
|
||||
(2 ^ w - x.toNat) % 2 ^ w = 2 ^ w - x.toNat := by
|
||||
simp only [msb_eq_decide, ge_iff_le, decide_eq_true_eq] at h
|
||||
simp only [msb_eq_decide, decide_eq_true_eq] at h
|
||||
have := Nat.two_pow_pos (w-1)
|
||||
exact sub_toNat_mod_cancel_of_toNat (by omega)
|
||||
|
||||
theorem toNat_lt_of_msb_false {w : Nat} {x : BitVec w} (h : x.msb = false) : x.toNat < 2 ^ (w - 1) := by
|
||||
have rt := @msb_eq_decide w x
|
||||
simp only [ge_iff_le, false_eq_decide_iff, Nat.not_le, h] at rt
|
||||
simp only [false_eq_decide_iff, Nat.not_le, h] at rt
|
||||
omega
|
||||
|
||||
theorem le_toNat_of_msb_true {w : Nat} {x : BitVec w} (h : x.msb = true) : 2 ^ (w - 1) ≤ x.toNat := by
|
||||
have rt := @msb_eq_decide w x
|
||||
simp only [h, ge_iff_le, true_eq_decide_iff] at rt
|
||||
simp only [h, true_eq_decide_iff] at rt
|
||||
omega
|
||||
|
||||
/--
|
||||
@@ -913,7 +913,7 @@ theorem getElem?_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
|
||||
|
||||
@[simp] theorem getMsbD_setWidth' (ge : m ≥ n) (x : BitVec n) (i : Nat) :
|
||||
getMsbD (setWidth' ge x) i = (decide (m - n ≤ i) && getMsbD x (i + n - m)) := by
|
||||
simp only [getMsbD, getLsbD_setWidth', gt_iff_lt]
|
||||
simp only [getMsbD, getLsbD_setWidth']
|
||||
by_cases h₁ : decide (i < m) <;> by_cases h₂ : decide (m - n ≤ i) <;> by_cases h₃ : decide (i + n - m < n) <;>
|
||||
by_cases h₄ : n - 1 - (i + n - m) = m - 1 - i
|
||||
all_goals
|
||||
@@ -933,8 +933,8 @@ theorem getElem?_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
|
||||
unfold setWidth
|
||||
by_cases h : n ≤ m <;> simp only [h]
|
||||
· by_cases h' : m - n ≤ i
|
||||
<;> simp [h', show i - (m - n) = i + n - m by omega]
|
||||
· simp only [show m - n = 0 by omega, getMsbD, getLsbD_setWidth]
|
||||
<;> simp [h']
|
||||
· simp only [show m - n = 0 by omega, getMsbD]
|
||||
by_cases h' : i < m
|
||||
· simp [show m - 1 - i < m by omega, show i + n - m < n by omega,
|
||||
show n - 1 - (i + n - m) = m - 1 - i by omega]
|
||||
@@ -972,7 +972,7 @@ theorem setWidth'_eq {x : BitVec w} (h : w ≤ v) : x.setWidth' h = x.setWidth v
|
||||
@[simp] theorem setWidth_setWidth_of_le (x : BitVec w) (h : k ≤ l) :
|
||||
(x.setWidth l).setWidth k = x.setWidth k := by
|
||||
ext i
|
||||
simp [getElem_setWidth, Fin.is_lt, decide_true, Bool.true_and]
|
||||
simp [getElem_setWidth]
|
||||
omega
|
||||
|
||||
@[simp] theorem setWidth_cast {x : BitVec w} {h : w = v} : (x.cast h).setWidth k = x.setWidth k := by
|
||||
@@ -995,14 +995,14 @@ theorem setWidth_one_eq_ofBool_getLsb_zero (x : BitVec w) :
|
||||
x.setWidth 1 = BitVec.ofBool (x.getLsbD 0) := by
|
||||
ext i h
|
||||
simp at h
|
||||
simp [getLsbD_setWidth, h]
|
||||
simp [h]
|
||||
|
||||
/-- Zero extending `1#v` to `1#w` equals `1#w` when `v > 0`. -/
|
||||
theorem setWidth_ofNat_one_eq_ofNat_one_of_lt {v w : Nat} (hv : 0 < v) :
|
||||
(BitVec.ofNat v 1).setWidth w = BitVec.ofNat w 1 := by
|
||||
ext i h
|
||||
simp only [getElem_setWidth, h, decide_true, getLsbD_ofNat, Bool.true_and,
|
||||
Bool.and_eq_right_iff_imp, decide_eq_true_eq]
|
||||
simp only [getElem_setWidth, getLsbD_ofNat,
|
||||
]
|
||||
have hv := (@Nat.testBit_one_eq_true_iff_self_eq_zero i)
|
||||
by_cases h : Nat.testBit 1 i = true <;> simp_all
|
||||
|
||||
@@ -1078,15 +1078,15 @@ protected theorem extractLsb_ofNat (x n : Nat) (hi lo : Nat) :
|
||||
|
||||
@[simp] theorem toInt_extractLsb {hi lo : Nat} {x : BitVec n} :
|
||||
(extractLsb hi lo x).toInt = ((x.toNat >>> lo) : Int).bmod (2 ^ (hi - lo + 1)) := by
|
||||
simp [extractLsb, toInt_ofNat]
|
||||
simp [extractLsb]
|
||||
|
||||
@[simp] theorem toFin_extractLsb' {s m : Nat} {x : BitVec n} :
|
||||
(extractLsb' s m x).toFin = Fin.ofNat (2 ^ m) (x.toNat >>> s) := by
|
||||
simp [extractLsb', toInt_ofNat]
|
||||
simp [extractLsb']
|
||||
|
||||
@[simp] theorem toFin_extractLsb {hi lo : Nat} {x : BitVec n} :
|
||||
(extractLsb hi lo x).toFin = Fin.ofNat (2 ^ (hi - lo + 1)) (x.toNat >>> lo) := by
|
||||
simp [extractLsb, toInt_ofNat]
|
||||
simp [extractLsb]
|
||||
|
||||
@[simp] theorem getElem_extractLsb' {start len : Nat} {x : BitVec n} {i : Nat} (h : i < len) :
|
||||
(extractLsb' start len x)[i] = x.getLsbD (start+i) := by
|
||||
@@ -1094,7 +1094,7 @@ protected theorem extractLsb_ofNat (x n : Nat) (hi lo : Nat) :
|
||||
|
||||
@[simp] theorem getLsbD_extractLsb' (start len : Nat) (x : BitVec n) (i : Nat) :
|
||||
(extractLsb' start len x).getLsbD i = (i < len && x.getLsbD (start+i)) := by
|
||||
simp [getLsbD, Nat.lt_succ]
|
||||
simp [getLsbD]
|
||||
|
||||
/--
|
||||
Get the most significant bit after `extractLsb'`. With `extractLsb'`, we extract
|
||||
@@ -1272,9 +1272,9 @@ theorem extractLsb'_eq_zero {x : BitVec w} {start : Nat} :
|
||||
|
||||
@[simp] theorem ofFin_add_rev (x : Fin (2^n)) : ofFin (x + x.rev) = allOnes n := by
|
||||
ext
|
||||
simp only [Fin.rev, getElem_ofFin, getElem_allOnes, Fin.is_lt, decide_true]
|
||||
simp only [Fin.rev, getElem_ofFin, getElem_allOnes]
|
||||
rw [Fin.add_def]
|
||||
simp only [Nat.testBit_mod_two_pow, Fin.is_lt, decide_true, Bool.true_and]
|
||||
simp only [Nat.testBit_mod_two_pow]
|
||||
have h : (x : Nat) + (2 ^ n - (x + 1)) = 2 ^ n - 1 := by omega
|
||||
rw [h, Nat.testBit_two_pow_sub_one]
|
||||
simp
|
||||
@@ -1318,7 +1318,7 @@ theorem msb_allOnes (hw : 0 < w) : (allOnes w).msb = true := by
|
||||
@[simp] theorem setWidth_or {x y : BitVec w} :
|
||||
(x ||| y).setWidth k = x.setWidth k ||| y.setWidth k := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
theorem or_assoc (x y z : BitVec w) :
|
||||
x ||| y ||| z = x ||| (y ||| z) := by
|
||||
@@ -1352,11 +1352,11 @@ instance : Std.LawfulCommIdentity (α := BitVec n) (· ||| · ) (0#n) where
|
||||
|
||||
@[simp] theorem or_allOnes {x : BitVec w} : x ||| allOnes w = allOnes w := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[simp] theorem allOnes_or {x : BitVec w} : allOnes w ||| x = allOnes w := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem or_eq_zero_iff {x y : BitVec w} : (x ||| y) = 0#w ↔ x = 0#w ∧ y = 0#w := by
|
||||
@@ -1374,12 +1374,12 @@ theorem or_eq_zero_iff {x y : BitVec w} : (x ||| y) = 0#w ↔ x = 0#w ∧ y = 0#
|
||||
theorem extractLsb'_or {x y : BitVec w} {start len : Nat} :
|
||||
(x ||| y).extractLsb' start len = (x.extractLsb' start len) ||| (y.extractLsb' start len) := by
|
||||
ext i hi
|
||||
simp [hi]
|
||||
simp
|
||||
|
||||
theorem extractLsb_or {x : BitVec w} {hi lo : Nat} :
|
||||
(x ||| y).extractLsb lo hi = (x.extractLsb lo hi) ||| (y.extractLsb lo hi) := by
|
||||
ext k hk
|
||||
simp [hk, show k ≤ lo - hi by omega]
|
||||
simp
|
||||
|
||||
@[simp] theorem ofNat_or {x y : Nat} : BitVec.ofNat w (x ||| y) = BitVec.ofNat w x ||| BitVec.ofNat w y :=
|
||||
eq_of_toNat_eq (by simp [Nat.or_mod_two_pow])
|
||||
@@ -1417,7 +1417,7 @@ theorem extractLsb_or {x : BitVec w} {hi lo : Nat} :
|
||||
@[simp] theorem setWidth_and {x y : BitVec w} :
|
||||
(x &&& y).setWidth k = x.setWidth k &&& y.setWidth k := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
theorem and_assoc (x y z : BitVec w) :
|
||||
x &&& y &&& z = x &&& (y &&& z) := by
|
||||
@@ -1448,14 +1448,14 @@ instance : Std.IdempotentOp (α := BitVec n) (· &&& · ) where
|
||||
|
||||
@[simp] theorem and_allOnes {x : BitVec w} : x &&& allOnes w = x := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
instance : Std.LawfulCommIdentity (α := BitVec n) (· &&& · ) (allOnes n) where
|
||||
right_id _ := BitVec.and_allOnes
|
||||
|
||||
@[simp] theorem allOnes_and {x : BitVec w} : allOnes w &&& x = x := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem and_eq_allOnes_iff {x y : BitVec w} :
|
||||
@@ -1467,19 +1467,19 @@ theorem and_eq_allOnes_iff {x y : BitVec w} :
|
||||
· ext i ih
|
||||
have := BitVec.eq_of_getElem_eq_iff.mp h i ih
|
||||
simp only [getElem_and, getElem_allOnes, Bool.and_eq_true] at this
|
||||
simp [this, ih]
|
||||
simp [this]
|
||||
· intro h
|
||||
simp [h]
|
||||
|
||||
theorem extractLsb'_and {x y : BitVec w} {start len : Nat} :
|
||||
(x &&& y).extractLsb' start len = (x.extractLsb' start len) &&& (y.extractLsb' start len) := by
|
||||
ext i hi
|
||||
simp [hi]
|
||||
simp
|
||||
|
||||
theorem extractLsb_and {x : BitVec w} {hi lo : Nat} :
|
||||
(x &&& y).extractLsb lo hi = (x.extractLsb lo hi) &&& (y.extractLsb lo hi) := by
|
||||
ext k hk
|
||||
simp [hk, show k ≤ lo - hi by omega]
|
||||
simp
|
||||
|
||||
@[simp] theorem ofNat_and {x y : Nat} : BitVec.ofNat w (x &&& y) = BitVec.ofNat w x &&& BitVec.ofNat w y :=
|
||||
eq_of_toNat_eq (by simp [Nat.and_mod_two_pow])
|
||||
@@ -1520,12 +1520,12 @@ theorem extractLsb_and {x : BitVec w} {hi lo : Nat} :
|
||||
@[simp] theorem setWidth_xor {x y : BitVec w} :
|
||||
(x ^^^ y).setWidth k = x.setWidth k ^^^ y.setWidth k := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
theorem xor_assoc (x y z : BitVec w) :
|
||||
x ^^^ y ^^^ z = x ^^^ (y ^^^ z) := by
|
||||
ext i
|
||||
simp [Bool.xor_assoc]
|
||||
simp
|
||||
instance : Std.Associative (fun (x y : BitVec w) => x ^^^ y) := ⟨BitVec.xor_assoc⟩
|
||||
|
||||
theorem xor_comm (x y : BitVec w) :
|
||||
@@ -1577,12 +1577,12 @@ theorem xor_eq_zero_iff {x y : BitVec w} : (x ^^^ y = 0#w) ↔ x = y := by
|
||||
theorem extractLsb'_xor {x y : BitVec w} {start len : Nat} :
|
||||
(x ^^^ y).extractLsb' start len = (x.extractLsb' start len) ^^^ (y.extractLsb' start len) := by
|
||||
ext i hi
|
||||
simp [hi]
|
||||
simp
|
||||
|
||||
theorem extractLsb_xor {x : BitVec w} {hi lo : Nat} :
|
||||
(x ^^^ y).extractLsb lo hi = (x.extractLsb lo hi) ^^^ (y.extractLsb lo hi) := by
|
||||
ext k hk
|
||||
simp [hk, show k ≤ lo - hi by omega]
|
||||
simp
|
||||
|
||||
@[simp] theorem ofNat_xor {x y : Nat} : BitVec.ofNat w (x ^^^ y) = BitVec.ofNat w x ^^^ BitVec.ofNat w y :=
|
||||
eq_of_toNat_eq (by simp [Nat.xor_mod_two_pow])
|
||||
@@ -1655,7 +1655,7 @@ theorem not_def {x : BitVec v} : ~~~x = allOnes v ^^^ x := rfl
|
||||
@[simp] theorem setWidth_not {x : BitVec w} (_ : k ≤ w) :
|
||||
(~~~x).setWidth k = ~~~(x.setWidth k) := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
omega
|
||||
|
||||
@[simp] theorem not_zero : ~~~(0#n) = allOnes n := by
|
||||
@@ -1668,16 +1668,16 @@ theorem not_def {x : BitVec v} : ~~~x = allOnes v ^^^ x := rfl
|
||||
|
||||
@[simp] theorem xor_allOnes {x : BitVec w} : x ^^^ allOnes w = ~~~ x := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[simp] theorem allOnes_xor {x : BitVec w} : allOnes w ^^^ x = ~~~ x := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem not_not {b : BitVec w} : ~~~(~~~b) = b := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
protected theorem not_inj {x y : BitVec w} : ~~~x = ~~~y ↔ x = y :=
|
||||
@@ -1721,7 +1721,7 @@ which makes the operation not commute.
|
||||
theorem extractLsb'_not_of_lt {x : BitVec w} {start len : Nat} (h : start + len < w) :
|
||||
(~~~ x).extractLsb' start len = ~~~ (x.extractLsb' start len) := by
|
||||
ext i hi
|
||||
simp [hi]
|
||||
simp
|
||||
omega
|
||||
|
||||
/--
|
||||
@@ -1734,7 +1734,7 @@ we need the range [lo:hi] to be a valid closed interval inside the bitvector:
|
||||
theorem extractLsb_not_of_lt {x : BitVec w} {hi lo : Nat} (hlo : lo ≤ hi) (hhi : hi < w) :
|
||||
(~~~ x).extractLsb hi lo = ~~~ (x.extractLsb hi lo) := by
|
||||
ext k hk
|
||||
simp [hk, show k ≤ hi - lo by omega]
|
||||
simp
|
||||
omega
|
||||
|
||||
@[simp]
|
||||
@@ -1767,19 +1767,19 @@ theorem not_xor_right {x y : BitVec w} : ~~~ (x ^^^ y) = x ^^^ ~~~ y := by
|
||||
|
||||
@[simp] theorem not_cast {x : BitVec w} (h : w = w') : ~~~(x.cast h) = (~~~x).cast h := by
|
||||
ext
|
||||
simp_all [lt_of_getLsbD]
|
||||
simp_all
|
||||
|
||||
@[simp] theorem and_cast {x y : BitVec w} (h : w = w') : x.cast h &&& y.cast h = (x &&& y).cast h := by
|
||||
ext
|
||||
simp_all [lt_of_getLsbD]
|
||||
simp_all
|
||||
|
||||
@[simp] theorem or_cast {x y : BitVec w} (h : w = w') : x.cast h ||| y.cast h = (x ||| y).cast h := by
|
||||
ext
|
||||
simp_all [lt_of_getLsbD]
|
||||
simp_all
|
||||
|
||||
@[simp] theorem xor_cast {x y : BitVec w} (h : w = w') : x.cast h ^^^ y.cast h = (x ^^^ y).cast h := by
|
||||
ext
|
||||
simp_all [lt_of_getLsbD]
|
||||
simp_all
|
||||
|
||||
/-! ### shiftLeft -/
|
||||
|
||||
@@ -1823,19 +1823,19 @@ theorem zero_shiftLeft (n : Nat) : 0#w <<< n = 0#w := by
|
||||
theorem shiftLeft_xor_distrib (x y : BitVec w) (n : Nat) :
|
||||
(x ^^^ y) <<< n = (x <<< n) ^^^ (y <<< n) := by
|
||||
ext i h
|
||||
simp only [getElem_shiftLeft, h, decide_true, Bool.true_and, getLsbD_xor]
|
||||
simp only [getElem_shiftLeft]
|
||||
by_cases h' : i < n <;> simp [h']
|
||||
|
||||
theorem shiftLeft_and_distrib (x y : BitVec w) (n : Nat) :
|
||||
(x &&& y) <<< n = (x <<< n) &&& (y <<< n) := by
|
||||
ext i h
|
||||
simp only [getElem_shiftLeft, h, decide_true, Bool.true_and, getLsbD_and]
|
||||
simp only [getElem_shiftLeft]
|
||||
by_cases h' : i < n <;> simp [h']
|
||||
|
||||
theorem shiftLeft_or_distrib (x y : BitVec w) (n : Nat) :
|
||||
(x ||| y) <<< n = (x <<< n) ||| (y <<< n) := by
|
||||
ext i h
|
||||
simp only [getElem_shiftLeft, h, decide_true, Bool.true_and, getLsbD_or]
|
||||
simp only [getElem_shiftLeft]
|
||||
by_cases h' : i < n <;> simp [h']
|
||||
|
||||
@[simp] theorem getMsbD_shiftLeft (x : BitVec w) (i) :
|
||||
@@ -1847,7 +1847,7 @@ theorem shiftLeft_or_distrib (x y : BitVec w) (n : Nat) :
|
||||
simp only [t]
|
||||
simp only [decide_true, Nat.sub_sub, Bool.true_and, Nat.add_assoc]
|
||||
by_cases h₁ : k < w <;> by_cases h₂ : w - (1 + k) < i <;> by_cases h₃ : k + i < w
|
||||
<;> simp only [h₁, h₂, h₃, decide_false, h₂, decide_true, Bool.not_true, Bool.false_and, Bool.and_self,
|
||||
<;> simp only [h₁, h₃, decide_false, h₂, decide_true, Bool.not_true, Bool.false_and, Bool.and_self,
|
||||
Bool.true_and, Bool.false_eq, Bool.false_and, Bool.not_false]
|
||||
<;> (first | apply getLsbD_of_ge | apply Eq.symm; apply getLsbD_of_ge)
|
||||
<;> omega
|
||||
@@ -1923,9 +1923,9 @@ theorem toFin_shiftLeftZeroExtend {x : BitVec w} :
|
||||
@[simp] theorem getElem_shiftLeftZeroExtend {x : BitVec m} {n : Nat} (h : i < m + n) :
|
||||
(shiftLeftZeroExtend x n)[i] = if h' : i < n then false else x[i - n] := by
|
||||
rw [shiftLeftZeroExtend_eq]
|
||||
simp only [getElem_eq_testBit_toNat, getLsbD_shiftLeft, getLsbD_setWidth]
|
||||
simp only [getElem_eq_testBit_toNat]
|
||||
cases h₁ : decide (i < n) <;> cases h₂ : decide (i - n < m + n)
|
||||
<;> simp_all [h]
|
||||
<;> simp_all
|
||||
<;> omega
|
||||
|
||||
@[simp] theorem getLsbD_shiftLeftZeroExtend (x : BitVec m) (n : Nat) :
|
||||
@@ -1994,7 +1994,7 @@ theorem getElem_shiftLeft' {x : BitVec w₁} {y : BitVec w₂} {i : Nat} (h : i
|
||||
|
||||
@[simp] theorem shiftLeft_eq_zero {x : BitVec w} {n : Nat} (hn : w ≤ n) : x <<< n = 0#w := by
|
||||
ext i hi
|
||||
simp [hn, hi]
|
||||
simp
|
||||
omega
|
||||
|
||||
theorem shiftLeft_ofNat_eq {x : BitVec w} {k : Nat} : x <<< (BitVec.ofNat w k) = x <<< (k % 2^w) := rfl
|
||||
@@ -2121,7 +2121,7 @@ theorem msb_ushiftRight {x : BitVec w} {n : Nat} :
|
||||
case zero =>
|
||||
simp
|
||||
case succ nn ih =>
|
||||
simp [BitVec.ushiftRight_eq, getMsbD_ushiftRight, BitVec.msb, ih, show nn + 1 > 0 by omega]
|
||||
simp [getMsbD_ushiftRight, BitVec.msb, show nn + 1 > 0 by omega]
|
||||
|
||||
@[simp] theorem setWidth_ushiftRight {x : BitVec w} {y : Nat} (hi : w ≤ i) :
|
||||
(x >>> y).setWidth i = x.setWidth i >>> y := by
|
||||
@@ -2157,7 +2157,7 @@ theorem sshiftRight_eq_of_msb_false {x : BitVec w} {s : Nat} (h : x.msb = false)
|
||||
apply BitVec.eq_of_toNat_eq
|
||||
rw [BitVec.sshiftRight_eq, BitVec.toInt_eq_toNat_cond]
|
||||
have hxbound : 2 * x.toNat < 2 ^ w := BitVec.msb_eq_false_iff_two_mul_lt.mp h
|
||||
simp only [hxbound, ↓reduceIte, Int.natCast_shiftRight, Int.ofNat_eq_coe, ofInt_natCast,
|
||||
simp only [hxbound, ↓reduceIte, Int.natCast_shiftRight, ofInt_natCast,
|
||||
toNat_ofNat, toNat_ushiftRight]
|
||||
replace hxbound : x.toNat >>> s < 2 ^ w := by
|
||||
rw [Nat.shiftRight_eq_div_pow]
|
||||
@@ -2259,7 +2259,7 @@ theorem msb_sshiftRight {n : Nat} {x : BitVec w} :
|
||||
|
||||
@[simp] theorem zero_sshiftRight {n : Nat} : (0#w).sshiftRight n = 0#w := by
|
||||
ext i h
|
||||
simp [getElem_sshiftRight, h]
|
||||
simp [getElem_sshiftRight]
|
||||
|
||||
theorem sshiftRight_add {x : BitVec w} {m n : Nat} :
|
||||
x.sshiftRight (m + n) = (x.sshiftRight m).sshiftRight n := by
|
||||
@@ -2271,17 +2271,17 @@ theorem sshiftRight_add {x : BitVec w} {m n : Nat} :
|
||||
by_cases h₃ : m + (n + ↑i) < w
|
||||
· simp [h₃]
|
||||
omega
|
||||
· simp [h₃, msb_sshiftRight]
|
||||
· simp [h₃]
|
||||
|
||||
theorem not_sshiftRight {b : BitVec w} :
|
||||
~~~b.sshiftRight n = (~~~b).sshiftRight n := by
|
||||
ext i
|
||||
simp only [getElem_not, Fin.is_lt, decide_true, getElem_sshiftRight, Bool.not_and, Bool.not_not,
|
||||
Bool.true_and, msb_not]
|
||||
simp only [getElem_not, getElem_sshiftRight,
|
||||
msb_not]
|
||||
by_cases h : w ≤ i
|
||||
<;> by_cases h' : n + i < w
|
||||
<;> by_cases h'' : 0 < w
|
||||
<;> simp [h, h', h'']
|
||||
<;> simp [h', h'']
|
||||
<;> omega
|
||||
|
||||
@[simp]
|
||||
@@ -2427,7 +2427,7 @@ theorem getLsbD_sshiftRight' {x y : BitVec w} {i : Nat} :
|
||||
-- This should not be a `@[simp]` lemma as the left hand side is not in simp normal form.
|
||||
theorem getElem_sshiftRight' {x y : BitVec w} {i : Nat} (h : i < w) :
|
||||
(x.sshiftRight' y)[i] = (if h : y.toNat + i < w then x[y.toNat + i] else x.msb) := by
|
||||
simp [show ¬ w ≤ i by omega, getElem_sshiftRight]
|
||||
simp [getElem_sshiftRight]
|
||||
|
||||
theorem getMsbD_sshiftRight' {x y: BitVec w} {i : Nat} :
|
||||
(x.sshiftRight y.toNat).getMsbD i =
|
||||
@@ -2453,10 +2453,10 @@ theorem signExtend_eq_setWidth_of_msb_false {x : BitVec w} {v : Nat} (hmsb : x.m
|
||||
x.signExtend v = x.setWidth v := by
|
||||
ext i
|
||||
by_cases hv : i < v
|
||||
· simp only [signExtend, getLsbD, getElem_setWidth, hv, decide_true, Bool.true_and, toNat_ofInt,
|
||||
· simp only [signExtend, getLsbD, getElem_setWidth,
|
||||
BitVec.toInt_eq_msb_cond, hmsb, ↓reduceIte, reduceCtorEq]
|
||||
simp [BitVec.testBit_toNat]
|
||||
· simp only [getElem_setWidth, hv, decide_false, Bool.false_and]
|
||||
· simp only [getElem_setWidth]
|
||||
omega
|
||||
|
||||
/--
|
||||
@@ -2470,7 +2470,7 @@ theorem signExtend_eq_not_setWidth_not_of_msb_true {x : BitVec w} {v : Nat} (hms
|
||||
toNat_setWidth, hmsb, ↓reduceIte]
|
||||
norm_cast
|
||||
rw [Int.ofNat_sub_ofNat_of_lt, Int.negSucc_emod]
|
||||
simp only [Int.natAbs_natCast, Nat.succ_eq_add_one]
|
||||
simp only [Int.natAbs_natCast]
|
||||
rw [Int.subNatNat_of_le]
|
||||
· rw [Int.toNat_natCast, Nat.add_comm, Nat.sub_add_eq]
|
||||
· apply Nat.le_trans
|
||||
@@ -2539,7 +2539,7 @@ private theorem toNat_signExtend_of_le (x : BitVec w) {v : Nat} (hv : w ≤ v) :
|
||||
rcases hi with hi | hi | hi
|
||||
· simp [hi]; omega
|
||||
· simp [hi]; omega
|
||||
· simp [hi, show ¬ (i < w + k) by omega, show ¬ (i < w) by omega]
|
||||
· simp [show ¬ (i < w + k) by omega, show ¬ (i < w) by omega]
|
||||
omega
|
||||
· simp only [hx, Bool.if_false_right,
|
||||
Bool.false_eq_true, ↓reduceIte, Nat.zero_add, testBit_toNat]
|
||||
@@ -2547,7 +2547,7 @@ private theorem toNat_signExtend_of_le (x : BitVec w) {v : Nat} (hv : w ≤ v) :
|
||||
rcases hi with hi | hi | hi
|
||||
· simp [hi]; omega
|
||||
· simp [hi]
|
||||
· simp [hi, show ¬ (i < w + k) by omega, show ¬ (i < w) by omega, getLsbD_of_ge x i (by omega)]
|
||||
· simp [show ¬ (i < w + k) by omega, show ¬ (i < w) by omega, getLsbD_of_ge x i (by omega)]
|
||||
|
||||
/-- Sign extending to a larger bitwidth depends on the msb.
|
||||
If the msb is false, then the result equals the original value.
|
||||
@@ -2576,10 +2576,10 @@ where
|
||||
simp only [toInt_eq_msb_cond, toNat_signExtend]
|
||||
have : (x.signExtend v).msb = x.msb := by
|
||||
rw [msb_eq_getLsbD_last, getLsbD_eq_getElem (Nat.sub_one_lt_of_lt hv)]
|
||||
simp [getElem_signExtend, Nat.le_sub_one_of_lt hv]
|
||||
simp [getElem_signExtend]
|
||||
omega
|
||||
have H : 2^w ≤ 2^v := Nat.pow_le_pow_right (by omega) (by omega)
|
||||
simp only [this, toNat_setWidth, Int.natCast_add, Int.natCast_emod, Int.natCast_mul]
|
||||
simp only [this, toNat_setWidth, Int.natCast_add, Int.natCast_emod]
|
||||
by_cases h : x.msb
|
||||
<;> norm_cast
|
||||
<;> simp [h, Nat.mod_eq_of_lt (Nat.lt_of_lt_of_le x.isLt H), -Int.natCast_pow]
|
||||
@@ -2666,14 +2666,14 @@ theorem getLsbD_append {x : BitVec n} {y : BitVec m} :
|
||||
simp only [append_def, getLsbD_or, getLsbD_shiftLeftZeroExtend, getLsbD_setWidth']
|
||||
by_cases h : i < m
|
||||
· simp [h]
|
||||
· simp_all [h]
|
||||
· simp_all
|
||||
|
||||
theorem getElem_append {x : BitVec n} {y : BitVec m} (h : i < n + m) :
|
||||
(x ++ y)[i] = if h : i < m then y[i] else x[i - m] := by
|
||||
simp only [append_def]
|
||||
by_cases h' : i < m
|
||||
· simp [h']
|
||||
· simp [h', show m ≤ i by omega, show i - m < n by omega]
|
||||
· simp [h', show m ≤ i by omega]
|
||||
|
||||
@[simp] theorem getMsbD_append {x : BitVec n} {y : BitVec m} :
|
||||
getMsbD (x ++ y) i = if n ≤ i then getMsbD y (i - n) else getMsbD x i := by
|
||||
@@ -2697,7 +2697,7 @@ theorem msb_append {x : BitVec w} {y : BitVec v} :
|
||||
@[simp] theorem append_zero_width (x : BitVec w) (y : BitVec 0) : x ++ y = x := by
|
||||
ext i ih
|
||||
rw [getElem_append] -- Why does this not work with `simp [getElem_append]`?
|
||||
simp [show i < w by omega]
|
||||
simp
|
||||
|
||||
theorem toInt_append {x : BitVec n} {y : BitVec m} :
|
||||
(x ++ y).toInt = if n == 0 then y.toInt else (2 ^ m) * x.toInt + y.toNat := by
|
||||
@@ -2783,9 +2783,9 @@ theorem toNat_shiftLeft_or_toNat_lt_two_pow_add {m n : Nat} (x : BitVec m) (y :
|
||||
theorem setWidth_append {x : BitVec w} {y : BitVec v} :
|
||||
(x ++ y).setWidth k = if h : k ≤ v then y.setWidth k else (x.setWidth (k - v) ++ y).cast (by omega) := by
|
||||
ext i h
|
||||
simp only [getElem_setWidth, h, getLsbD_append, getElem_append]
|
||||
simp only [getElem_setWidth, getLsbD_append]
|
||||
split <;> rename_i h₁ <;> split <;> rename_i h₂
|
||||
· simp [h]
|
||||
· simp
|
||||
· simp [getElem_append, h₁]
|
||||
· omega
|
||||
· simp [getElem_append, h₁]
|
||||
@@ -2804,7 +2804,7 @@ theorem setWidth_append {x : BitVec w} {y : BitVec v} :
|
||||
|
||||
@[simp] theorem not_append {x : BitVec w} {y : BitVec v} : ~~~ (x ++ y) = (~~~ x) ++ (~~~ y) := by
|
||||
ext i
|
||||
simp only [getElem_not, getElem_append, cond_eq_if]
|
||||
simp only [getElem_not, getElem_append]
|
||||
split
|
||||
· simp_all
|
||||
· simp_all
|
||||
@@ -2861,7 +2861,7 @@ theorem setWidth_eq_append_extractLsb' {v : Nat} {x : BitVec v} {w : Nat} :
|
||||
ext i hi
|
||||
simp only [getElem_cast, getElem_append]
|
||||
by_cases hiv : i < v
|
||||
· simp [hi]
|
||||
· simp
|
||||
omega
|
||||
· simp [getLsbD_of_ge x i (by omega)]
|
||||
|
||||
@@ -2884,7 +2884,7 @@ theorem setWidth_eq_extractLsb' {v : Nat} {x : BitVec v} {w : Nat} (h : w ≤ v)
|
||||
ext i hi
|
||||
simp only [getElem_cast, getElem_append]
|
||||
by_cases hiv : i < v
|
||||
· simp [hi]
|
||||
· simp
|
||||
omega
|
||||
· simp [getLsbD_of_ge x i (by omega)]
|
||||
|
||||
@@ -2900,7 +2900,7 @@ theorem shiftLeft_eq_concat_of_lt {x : BitVec w} {n : Nat} (hn : n < w) :
|
||||
x <<< n = (x.extractLsb' 0 (w - n) ++ 0#n).cast (by omega) := by
|
||||
ext i hi
|
||||
simp only [getElem_shiftLeft, getElem_cast, getElem_append, getElem_zero, getElem_extractLsb',
|
||||
Nat.zero_add, Bool.if_false_left]
|
||||
Nat.zero_add]
|
||||
by_cases hi' : i < n
|
||||
· simp [hi']
|
||||
· simp [hi', show i - n < w by omega]
|
||||
@@ -2993,7 +2993,7 @@ theorem extractLsb'_append_eq_ite {v w} {xhi : BitVec v} {xlo : BitVec w} {start
|
||||
simp only [getElem_extractLsb', getLsbD_append, getElem_cast,
|
||||
getElem_append, dite_eq_ite]
|
||||
by_cases hi₂ : start + i < w
|
||||
· simp [hi₂, show i < min len w by omega, show i < w - start by omega]
|
||||
· simp [hi₂, show i < w - start by omega]
|
||||
· simp [hi₂, ↓reduceIte, show ¬i < w - start by omega,
|
||||
show start + i - w = start - w + (i - (w - start)) by omega]
|
||||
· simp only [hstart, ↓reduceDIte]
|
||||
@@ -3020,7 +3020,7 @@ the bits from `xhi` when `start` is outside `xlo`.
|
||||
theorem extractLsb'_append_eq_of_le {v w} {xhi : BitVec v} {xlo : BitVec w}
|
||||
{start len : Nat} (h : w ≤ start) :
|
||||
extractLsb' start len (xhi ++ xlo) = extractLsb' (start - w) len xhi := by
|
||||
simp [extractLsb'_append_eq_ite, h, show ¬ start < w by omega]
|
||||
simp [extractLsb'_append_eq_ite, show ¬ start < w by omega]
|
||||
|
||||
/-! ### rev -/
|
||||
|
||||
@@ -3057,7 +3057,7 @@ theorem getLsbD_cons (b : Bool) {n} (x : BitVec n) (i : Nat) :
|
||||
· have p1 : ¬(n ≤ i) := by omega
|
||||
have p2 : i ≠ n := by omega
|
||||
simp [p1, p2]
|
||||
· simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_true, Nat.sub_self, Nat.testBit_zero,
|
||||
· simp only [i_eq_n, Nat.le_refl, decide_true, Nat.sub_self, Nat.testBit_zero,
|
||||
Bool.true_and, testBit_toNat, getLsbD_of_ge, Bool.or_false, ↓reduceIte]
|
||||
cases b <;> trivial
|
||||
· have p1 : i ≠ n := by omega
|
||||
@@ -3081,7 +3081,7 @@ theorem setWidth_succ (x : BitVec w) :
|
||||
simp [j_eq]
|
||||
else
|
||||
have j_lt : j < i := Nat.lt_of_le_of_ne (Nat.le_of_succ_le_succ h) j_eq
|
||||
simp [j_eq, j_lt]
|
||||
simp [j_eq]
|
||||
|
||||
@[simp] theorem not_cons (x : BitVec w) (b : Bool) : ~~~(cons b x) = cons (!b) (~~~x) := by
|
||||
simp [cons]
|
||||
@@ -3111,17 +3111,17 @@ theorem cons_append (x : BitVec w₁) (y : BitVec w₂) (a : Bool) :
|
||||
theorem cons_append_append (x : BitVec w₁) (y : BitVec w₂) (z : BitVec w₃) (a : Bool) :
|
||||
(cons a x) ++ y ++ z = (cons a (x ++ y ++ z)).cast (by omega) := by
|
||||
ext i h
|
||||
simp only [cons, getElem_append, getElem_cast, getElem_ofBool, cast_cast, getLsbD_append, getLsbD_cast, getLsbD_ofBool]
|
||||
simp only [cons, getElem_append, getElem_cast, getElem_ofBool, cast_cast]
|
||||
by_cases h₀ : i < w₁ + w₂ + w₃
|
||||
· simp only [h₀, ↓reduceIte]
|
||||
· simp only [h₀]
|
||||
by_cases h₁ : i < w₃
|
||||
· simp [h₁]
|
||||
· simp only [h₁, ↓reduceIte]
|
||||
· simp only [h₁]
|
||||
by_cases h₂ : i - w₃ < w₂
|
||||
· simp [h₂]
|
||||
· simp [h₂, show i - w₃ - w₂ < w₁ by omega]
|
||||
· simp only [show ¬i - w₃ - w₂ < w₁ by omega, ↓reduceIte, show i - w₃ - w₂ - w₁ = 0 by omega,
|
||||
decide_true, Bool.true_and, h₀, show i - (w₁ + w₂ + w₃) = 0 by omega]
|
||||
· simp only [show ¬i - w₃ - w₂ < w₁ by omega,
|
||||
h₀]
|
||||
by_cases h₂ : i < w₃
|
||||
· simp [h₂]; omega
|
||||
· simp [h₂]; omega
|
||||
@@ -3135,7 +3135,7 @@ theorem cons_append_append (x : BitVec w₁) (y : BitVec w₂) (z : BitVec w₃)
|
||||
cases b
|
||||
· simp
|
||||
· rintro (_ | i)
|
||||
<;> simp [Nat.add_mod, Nat.add_comm, Nat.add_mul_div_right, Nat.testBit_add_one]
|
||||
<;> simp [Nat.add_comm, Nat.add_mul_div_right, Nat.testBit_add_one]
|
||||
|
||||
theorem getLsbD_concat (x : BitVec w) (b : Bool) (i : Nat) :
|
||||
(concat x b).getLsbD i = if i = 0 then b else x.getLsbD (i - 1) := by
|
||||
@@ -3146,7 +3146,7 @@ theorem getLsbD_concat (x : BitVec w) (b : Bool) (i : Nat) :
|
||||
|
||||
theorem getElem_concat (x : BitVec w) (b : Bool) (i : Nat) (h : i < w + 1) :
|
||||
(concat x b)[i] = if h : i = 0 then b else x[i - 1] := by
|
||||
simp only [concat, getElem_eq_testBit_toNat, getLsbD, toNat_append,
|
||||
simp only [concat, getElem_eq_testBit_toNat, toNat_append,
|
||||
toNat_ofBool, Nat.testBit_or, Nat.shiftLeft_eq]
|
||||
cases i
|
||||
· simp [Nat.mod_eq_of_lt b.toNat_lt]
|
||||
@@ -3164,7 +3164,7 @@ theorem getLsbD_concat_zero : (concat x b).getLsbD 0 = b := by
|
||||
@[simp] theorem getElem_concat_succ {x : BitVec w} {i : Nat} (h : i + 1 < w + 1) :
|
||||
(concat x b)[i + 1] = x[i] := by
|
||||
simp only [Nat.add_lt_add_iff_right] at h
|
||||
simp [getElem_concat, h, getLsbD_eq_getElem]
|
||||
simp [getElem_concat]
|
||||
|
||||
@[simp]
|
||||
theorem getMsbD_concat {i w : Nat} {b : Bool} {x : BitVec w} :
|
||||
@@ -3173,7 +3173,7 @@ theorem getMsbD_concat {i w : Nat} {b : Bool} {x : BitVec w} :
|
||||
by_cases h₀ : i = w
|
||||
· simp [h₀]
|
||||
· by_cases h₁ : i < w
|
||||
· simp [h₀, h₁, show ¬ w - i = 0 by omega, show i < w + 1 by omega, Nat.sub_sub, Nat.add_comm]
|
||||
· simp [h₁, show ¬ w - i = 0 by omega, show i < w + 1 by omega, Nat.sub_sub, Nat.add_comm]
|
||||
· simp only [show w - i = 0 by omega, ↓reduceIte, h₁, h₀, decide_false, Bool.false_and,
|
||||
Bool.and_eq_false_imp, decide_eq_true_eq]
|
||||
intro
|
||||
@@ -3186,7 +3186,7 @@ theorem msb_concat {w : Nat} {b : Bool} {x : BitVec w} :
|
||||
Nat.sub_zero, Bool.true_and]
|
||||
by_cases h₀ : 0 < w
|
||||
· simp [getElem_concat, h₀, show ¬ w = 0 by omega, show w - 1 < w by omega]
|
||||
· simp [h₀, show w = 0 by omega]
|
||||
· simp [show w = 0 by omega]
|
||||
|
||||
@[simp] theorem toInt_concat (x : BitVec w) (b : Bool) :
|
||||
(concat x b).toInt = if w = 0 then -b.toInt else x.toInt * 2 + b.toInt := by
|
||||
@@ -3198,25 +3198,25 @@ theorem msb_concat {w : Nat} {b : Bool} {x : BitVec w} :
|
||||
@[simp] theorem toFin_concat (x : BitVec w) (b : Bool) :
|
||||
(concat x b).toFin = Fin.mk (x.toNat * 2 + b.toNat) (by
|
||||
have := Bool.toNat_lt b
|
||||
simp [← Nat.two_pow_pred_add_two_pow_pred, Bool.toNat_lt b]
|
||||
simp [← Nat.two_pow_pred_add_two_pow_pred]
|
||||
omega
|
||||
) := by
|
||||
simp [← Fin.val_inj]
|
||||
|
||||
@[simp] theorem not_concat (x : BitVec w) (b : Bool) : ~~~(concat x b) = concat (~~~x) !b := by
|
||||
ext (_ | i) h <;> simp [getLsbD_concat]
|
||||
ext (_ | i) h <;> simp
|
||||
|
||||
@[simp] theorem concat_or_concat (x y : BitVec w) (a b : Bool) :
|
||||
(concat x a) ||| (concat y b) = concat (x ||| y) (a || b) := by
|
||||
ext (_ | i) h <;> simp [getLsbD_concat]
|
||||
ext (_ | i) h <;> simp
|
||||
|
||||
@[simp] theorem concat_and_concat (x y : BitVec w) (a b : Bool) :
|
||||
(concat x a) &&& (concat y b) = concat (x &&& y) (a && b) := by
|
||||
ext (_ | i) h <;> simp [getLsbD_concat]
|
||||
ext (_ | i) h <;> simp
|
||||
|
||||
@[simp] theorem concat_xor_concat (x y : BitVec w) (a b : Bool) :
|
||||
(concat x a) ^^^ (concat y b) = concat (x ^^^ y) (a ^^ b) := by
|
||||
ext (_ | i) h <;> simp [getLsbD_concat]
|
||||
ext (_ | i) h <;> simp
|
||||
|
||||
@[simp] theorem zero_concat_false : concat 0#w false = 0#(w + 1) := by
|
||||
ext
|
||||
@@ -3252,7 +3252,7 @@ theorem getLsbD_shiftConcat_eq_decide (x : BitVec w) (b : Bool) (i : Nat) :
|
||||
theorem shiftRight_sub_one_eq_shiftConcat (n : BitVec w) (hwn : 0 < wn) :
|
||||
n >>> (wn - 1) = (n >>> wn).shiftConcat (n.getLsbD (wn - 1)) := by
|
||||
ext i h
|
||||
simp only [getElem_ushiftRight, getElem_shiftConcat, h, decide_true, Bool.true_and]
|
||||
simp only [getElem_ushiftRight, getElem_shiftConcat]
|
||||
split
|
||||
· simp [*]
|
||||
· congr 1; omega
|
||||
@@ -3338,7 +3338,7 @@ instance : Std.LawfulIdentity (α := BitVec n) (· + ·) 0#n where
|
||||
theorem setWidth_add (x y : BitVec w) (h : i ≤ w) :
|
||||
(x + y).setWidth i = x.setWidth i + y.setWidth i := by
|
||||
have dvd : 2^i ∣ 2^w := Nat.pow_dvd_pow _ h
|
||||
simp [bitvec_to_nat, h, Nat.mod_mod_of_dvd _ dvd]
|
||||
simp [bitvec_to_nat, Nat.mod_mod_of_dvd _ dvd]
|
||||
|
||||
@[simp, bitvec_to_nat] theorem toInt_add (x y : BitVec w) :
|
||||
(x + y).toInt = (x.toInt + y.toInt).bmod (2^w) := by
|
||||
@@ -3379,7 +3379,7 @@ theorem shiftLeft_add_distrib {x y : BitVec w} {n : Nat} :
|
||||
case zero =>
|
||||
simp
|
||||
case succ n ih =>
|
||||
simp [ih, toNat_eq, Nat.shiftLeft_eq, ← Nat.add_mul]
|
||||
simp [toNat_eq, Nat.shiftLeft_eq, ← Nat.add_mul]
|
||||
|
||||
theorem add_eq_xor {a b : BitVec 1} : a + b = a ^^^ b := by
|
||||
have ha : a = 0 ∨ a = 1 := eq_zero_or_eq_one _
|
||||
@@ -3466,7 +3466,7 @@ theorem sub_ofFin (x : BitVec n) (y : Fin (2^n)) : x - .ofFin y = .ofFin (x.toFi
|
||||
-- If `x` and `n` are not literals, applying this theorem eagerly may not be a good idea.
|
||||
theorem ofNat_sub_ofNat {n} (x y : Nat) : BitVec.ofNat n x - BitVec.ofNat n y = .ofNat n ((2^n - y % 2^n) + x) := by
|
||||
apply eq_of_toNat_eq
|
||||
simp [BitVec.ofNat, Fin.ofNat_sub]
|
||||
simp [BitVec.ofNat]
|
||||
|
||||
theorem ofNat_sub_ofNat_of_le (x y : Nat) (hy : y < 2 ^ w) (hlt : y ≤ x):
|
||||
BitVec.ofNat w x - BitVec.ofNat w y = BitVec.ofNat w (x - y) := by
|
||||
@@ -3565,7 +3565,7 @@ abbrev negOne_eq_allOnes := @neg_one_eq_allOnes
|
||||
|
||||
theorem neg_eq_not_add (x : BitVec w) : -x = ~~~x + 1#w := by
|
||||
apply eq_of_toNat_eq
|
||||
simp only [toNat_neg, ofNat_eq_ofNat, toNat_add, toNat_not, toNat_ofNat, Nat.add_mod_mod]
|
||||
simp only [toNat_neg, toNat_add, toNat_not, toNat_ofNat, Nat.add_mod_mod]
|
||||
congr
|
||||
have hx : x.toNat < 2^w := x.isLt
|
||||
rw [Nat.sub_sub, Nat.add_comm 1 x.toNat, ← Nat.sub_sub, Nat.sub_add_cancel (by omega)]
|
||||
@@ -3631,7 +3631,7 @@ theorem add_neg_eq_sub {x y : BitVec w} : x + - y = (x - y) := by
|
||||
@[simp]
|
||||
theorem sub_neg {x y : BitVec w} : x - - y = x + y := by
|
||||
apply eq_of_toInt_eq
|
||||
simp [toInt_neg, Int.bmod_neg]
|
||||
simp [toInt_neg]
|
||||
|
||||
theorem neg_sub {x y : BitVec w} : - (x - y) = - x + y := by
|
||||
rw [sub_eq_add_neg, neg_add, sub_neg]
|
||||
@@ -3736,7 +3736,7 @@ theorem mul_def {n} {x y : BitVec n} : x * y = (ofFin <| x.toFin * y.toFin) := r
|
||||
|
||||
theorem ofNat_mul {n} (x y : Nat) : BitVec.ofNat n (x * y) = BitVec.ofNat n x * BitVec.ofNat n y := by
|
||||
apply eq_of_toNat_eq
|
||||
simp [BitVec.ofNat, Fin.ofNat_mul]
|
||||
simp [BitVec.ofNat]
|
||||
|
||||
theorem ofNat_mul_ofNat {n} (x y : Nat) : BitVec.ofNat n x * BitVec.ofNat n y = BitVec.ofNat n (x * y) :=
|
||||
(ofNat_mul x y).symm
|
||||
@@ -3879,7 +3879,7 @@ theorem neg_eq_neg_one_mul (b : BitVec w) : -b = -1#w * b :=
|
||||
theorem setWidth_mul (x y : BitVec w) (h : i ≤ w) :
|
||||
(x * y).setWidth i = x.setWidth i * y.setWidth i := by
|
||||
have dvd : 2^i ∣ 2^w := Nat.pow_dvd_pow _ h
|
||||
simp [bitvec_to_nat, h, Nat.mod_mod_of_dvd _ dvd]
|
||||
simp [bitvec_to_nat, Nat.mod_mod_of_dvd _ dvd]
|
||||
|
||||
/-! ### pow -/
|
||||
|
||||
@@ -3960,7 +3960,7 @@ protected theorem ne_of_lt {x y : BitVec n} : x < y → x ≠ y := by
|
||||
apply Nat.ne_of_lt
|
||||
|
||||
protected theorem umod_lt (x : BitVec n) {y : BitVec n} : 0 < y → x % y < y := by
|
||||
simp only [ofNat_eq_ofNat, lt_def, toNat_ofNat, Nat.zero_mod, umod, toNat_ofNatLT]
|
||||
simp only [ofNat_eq_ofNat, lt_def, toNat_ofNat, Nat.zero_mod]
|
||||
apply Nat.mod_lt
|
||||
|
||||
theorem not_lt_iff_le {x y : BitVec w} : (¬ x < y) ↔ y ≤ x := by
|
||||
@@ -4055,7 +4055,7 @@ theorem udiv_zero {x : BitVec n} : x / 0#n = 0#n := by
|
||||
|
||||
@[simp]
|
||||
theorem udiv_one {x : BitVec w} : x / 1#w = x := by
|
||||
simp only [udiv_eq, toNat_eq, toNat_udiv, toNat_ofNat]
|
||||
simp only [toNat_eq, toNat_udiv, toNat_ofNat]
|
||||
cases w
|
||||
· simp [eq_nil x]
|
||||
· simp
|
||||
@@ -4075,7 +4075,7 @@ theorem udiv_self {x : BitVec w} :
|
||||
by_cases h : x = 0#w
|
||||
· simp [h]
|
||||
· simp only [toNat_eq, toNat_ofNat, Nat.zero_mod] at h
|
||||
simp only [udiv_eq, beq_iff_eq, toNat_eq, toNat_ofNat, Nat.zero_mod, h,
|
||||
simp only [beq_iff_eq, toNat_eq, toNat_ofNat, Nat.zero_mod, h,
|
||||
↓reduceIte, toNat_udiv]
|
||||
rw [Nat.div_self (by omega), Nat.mod_eq_of_lt (by omega)]
|
||||
|
||||
@@ -4100,7 +4100,7 @@ theorem msb_udiv (x y : BitVec w) :
|
||||
simpa using msb_x
|
||||
| y + 2 =>
|
||||
suffices x.toNat / (y + 2) < 2 ^ w by
|
||||
simp_all [msb_eq_decide, hy]
|
||||
simp_all [msb_eq_decide]
|
||||
calc
|
||||
x.toNat / (y + 2)
|
||||
≤ x.toNat / 2 := by apply Nat.div_add_le_right (by omega)
|
||||
@@ -4256,7 +4256,7 @@ theorem toNat_sdiv {x y : BitVec w} : (x.sdiv y).toNat =
|
||||
| false, true => (- (x.udiv (- y))).toNat
|
||||
| true, false => (- ((- x).udiv y)).toNat
|
||||
| true, true => ((- x).udiv (- y)).toNat := by
|
||||
simp only [sdiv_eq, toNat_udiv]
|
||||
simp only [sdiv_eq]
|
||||
by_cases h : x.msb <;> by_cases h' : y.msb <;> simp [h, h']
|
||||
|
||||
@[simp]
|
||||
@@ -4291,7 +4291,7 @@ theorem sdiv_self {x : BitVec w} :
|
||||
· by_cases h : w = 1
|
||||
· subst h
|
||||
rcases x.msb with msb | msb <;> simp
|
||||
· rcases x.msb with msb | msb <;> simp [h]
|
||||
· rcases x.msb with msb | msb <;> simp
|
||||
|
||||
/-- Unsigned division never overflows. -/
|
||||
theorem toNat_div_toNat_lt {w : Nat} {x y : BitVec w} :
|
||||
@@ -4369,14 +4369,14 @@ theorem toInt_ediv_toInt_lt_of_nonpos_of_lt_neg_one {w : Nat} {x y : BitVec w} (
|
||||
rcases w with _|_|w
|
||||
· simp [of_length_zero]
|
||||
· have hy := eq_zero_or_eq_one (a := y)
|
||||
simp [← toInt_inj, toInt_zero, toInt_one] at hy
|
||||
simp [← toInt_inj, toInt_zero] at hy
|
||||
omega
|
||||
· have xle := le_two_mul_toInt (x := x); have xlt := two_mul_toInt_lt (x := x)
|
||||
have hx' : x.toInt = 0 ∨ x.toInt = - 1 ∨ x.toInt < - 1 := by omega
|
||||
rcases hx' with hx'|hx'|hx'
|
||||
· simp [hx']; omega
|
||||
· have := BitVec.neg_one_ediv_toInt_eq (y := y)
|
||||
simp only [toInt_allOnes, Nat.lt_add_left_iff_pos, Nat.zero_lt_succ, ↓reduceIte,
|
||||
simp only [
|
||||
Int.reduceNeg] at this
|
||||
simp [hx', this]
|
||||
omega
|
||||
@@ -4462,12 +4462,12 @@ theorem toNat_smod {x y : BitVec w} : (x.smod y).toNat =
|
||||
let u := (-x).umod y
|
||||
(if u = 0#w then u.toNat else (y - u).toNat)
|
||||
| true, true => (- ((- x).umod (- y))).toNat := by
|
||||
simp only [smod_eq, toNat_umod]
|
||||
simp only [smod_eq]
|
||||
by_cases h : x.msb <;> by_cases h' : y.msb
|
||||
<;> by_cases h'' : (-x).umod y = 0#w <;> by_cases h''' : x.umod (-y) = 0#w
|
||||
<;> simp only [h, h', h'', h''']
|
||||
<;> simp only [umod, toNat_eq, toNat_ofNatLT, toNat_ofNat, Nat.zero_mod] at h'' h'''
|
||||
<;> simp [h'', h''']
|
||||
<;> simp
|
||||
|
||||
@[simp]
|
||||
theorem smod_zero {x : BitVec w} : x.smod 0#w = x := by
|
||||
@@ -4567,7 +4567,7 @@ theorem getLsbD_rotateLeftAux_of_ge {x : BitVec w} {r : Nat} {i : Nat} (hi : i
|
||||
suffices (x >>> (w - r)).getLsbD i = false by
|
||||
have hiltr : decide (i < r) = false := by
|
||||
simp [hi]
|
||||
simp [getLsbD_shiftLeft, Bool.or_false, hi, hiltr, this]
|
||||
simp [getLsbD_shiftLeft, Bool.or_false, hiltr, this]
|
||||
simp only [getLsbD_ushiftRight]
|
||||
apply getLsbD_of_ge
|
||||
omega
|
||||
@@ -4673,7 +4673,7 @@ theorem toNat_rotateLeft {x : BitVec w} {r : Nat} :
|
||||
theorem toInt_rotateLeft {x : BitVec w} {r : Nat} :
|
||||
(x.rotateLeft r).toInt =
|
||||
((x <<< (r % w)).toNat ||| (x >>> (w - r % w)).toNat : Int).bmod (2 ^ w) := by
|
||||
simp [rotateLeft_def, toInt_shiftLeft, toInt_ushiftRight, toInt_or]
|
||||
simp [rotateLeft_def, toInt_or]
|
||||
|
||||
theorem toFin_rotateLeft {x : BitVec w} {r : Nat} :
|
||||
(x.rotateLeft r).toFin =
|
||||
@@ -4802,7 +4802,7 @@ theorem getMsbD_rotateRight_of_lt {w n m : Nat} {x : BitVec w} (hr : m < w) :
|
||||
show (w + 1 + n - m) < (w + 1) by omega, Nat.mod_eq_of_lt, Bool.true_and]
|
||||
congr 1
|
||||
omega
|
||||
· simp [h, getMsbD_rotateRightAux_of_ge <| Nat.ge_of_not_lt h]
|
||||
· simp [getMsbD_rotateRightAux_of_ge <| Nat.ge_of_not_lt h]
|
||||
by_cases h₁ : n < w + 1
|
||||
· simp [h, h₁, decide_true, Bool.true_and, Nat.mod_eq_of_lt hr]
|
||||
· simp [h₁]
|
||||
@@ -4836,7 +4836,7 @@ theorem toNat_rotateRight {x : BitVec w} {r : Nat} :
|
||||
|
||||
theorem toInt_rotateRight {x : BitVec w} {r : Nat} :
|
||||
(x.rotateRight r).toInt = ((x >>> (r % w)).toNat ||| (x <<< (w - r % w)).toNat : Int).bmod (2 ^ w) := by
|
||||
simp [rotateRight_def, toInt_shiftLeft, toInt_ushiftRight, toInt_or]
|
||||
simp [rotateRight_def, toInt_or]
|
||||
|
||||
theorem toFin_rotateRight {x : BitVec w} {r : Nat} :
|
||||
(x.rotateRight r).toFin = x.toFin / Fin.ofNat (2 ^ w) (2 ^ (r % w)) ||| Fin.ofNat (2 ^ w) (x.toNat <<< (w - r % w)) := by
|
||||
@@ -4913,8 +4913,8 @@ theorem toInt_twoPow {w i : Nat} :
|
||||
theorem toFin_twoPow {w i : Nat} :
|
||||
(BitVec.twoPow w i).toFin = Fin.ofNat (2^w) (2^i) := by
|
||||
rcases w with rfl | w
|
||||
· simp [BitVec.twoPow, BitVec.toFin, toFin_shiftLeft, Fin.fin_one_eq_zero]
|
||||
· simp [BitVec.twoPow, BitVec.toFin, toFin_shiftLeft, Nat.shiftLeft_eq]
|
||||
· simp [BitVec.twoPow, Fin.fin_one_eq_zero]
|
||||
· simp [BitVec.twoPow, toFin_shiftLeft, Nat.shiftLeft_eq]
|
||||
|
||||
@[simp]
|
||||
theorem getElem_twoPow {i j : Nat} (h : j < w) : (twoPow w i)[j] = decide (j = i) := by
|
||||
@@ -4932,7 +4932,7 @@ theorem getMsbD_twoPow {i j w: Nat} :
|
||||
theorem and_twoPow (x : BitVec w) (i : Nat) :
|
||||
x &&& (twoPow w i) = if x.getLsbD i then twoPow w i else 0#w := by
|
||||
ext j h
|
||||
simp only [getElem_and, getLsbD_twoPow]
|
||||
simp only [getElem_and]
|
||||
by_cases hj : i = j <;> by_cases hx : x.getLsbD i <;> simp_all <;> omega
|
||||
|
||||
theorem twoPow_and (x : BitVec w) (i : Nat) :
|
||||
@@ -4943,14 +4943,7 @@ theorem twoPow_and (x : BitVec w) (i : Nat) :
|
||||
theorem mul_twoPow_eq_shiftLeft (x : BitVec w) (i : Nat) :
|
||||
x * (twoPow w i) = x <<< i := by
|
||||
apply eq_of_toNat_eq
|
||||
simp only [toNat_mul, toNat_twoPow, toNat_shiftLeft, Nat.shiftLeft_eq]
|
||||
by_cases hi : i < w
|
||||
· have hpow : 2^i < 2^w := Nat.pow_lt_pow_of_lt (by omega) (by omega)
|
||||
rw [Nat.mod_eq_of_lt hpow]
|
||||
· have hpow : 2 ^ i % 2 ^ w = 0 := by
|
||||
rw [Nat.mod_eq_zero_of_dvd]
|
||||
apply Nat.pow_dvd_pow 2 (by omega)
|
||||
simp [Nat.mul_mod, hpow]
|
||||
simp only [toNat_mul, toNat_twoPow, Nat.mul_mod_mod, Nat.shiftLeft_eq, toNat_shiftLeft]
|
||||
|
||||
theorem twoPow_mul_eq_shiftLeft (x : BitVec w) (i : Nat) :
|
||||
(twoPow w i) * x = x <<< i := by
|
||||
@@ -4964,7 +4957,7 @@ theorem twoPow_zero {w : Nat} : twoPow w 0 = 1#w := by
|
||||
theorem shiftLeft_eq_mul_twoPow (x : BitVec w) (n : Nat) :
|
||||
x <<< n = x * (BitVec.twoPow w n) := by
|
||||
ext i
|
||||
simp [getLsbD_shiftLeft, Fin.is_lt, decide_true, Bool.true_and, mul_twoPow_eq_shiftLeft]
|
||||
simp [mul_twoPow_eq_shiftLeft]
|
||||
|
||||
/-- 2^i * 2^j = 2^(i + j) with bitvectors as well -/
|
||||
theorem twoPow_mul_twoPow_eq {w : Nat} (i j : Nat) : twoPow w i * twoPow w j = twoPow w (i + j) := by
|
||||
@@ -5048,12 +5041,12 @@ theorem setWidth_setWidth_succ_eq_setWidth_setWidth_or_twoPow_of_getLsbD_true
|
||||
setWidth w (x.setWidth (i + 1)) =
|
||||
setWidth w (x.setWidth i) ||| (twoPow w i) := by
|
||||
ext k h
|
||||
simp only [getElem_setWidth, h, getElem_or, getElem_twoPow]
|
||||
simp only [getElem_setWidth, getElem_or, getElem_twoPow]
|
||||
by_cases hik : i = k
|
||||
· subst hik
|
||||
simp [hx]
|
||||
· by_cases hik' : k < i + 1
|
||||
<;> simp [hik, hik', show ¬ (k = i) by omega]
|
||||
<;> simp [hik', show ¬ (k = i) by omega]
|
||||
<;> omega
|
||||
|
||||
/-- Bitwise and of `(x : BitVec w)` with `1#w` equals zero extending `x.lsb` to `w`. -/
|
||||
@@ -5092,7 +5085,7 @@ theorem getLsbD_replicate {n w : Nat} {x : BitVec w} :
|
||||
· simp only [hi', ↓reduceIte]
|
||||
rw [Nat.sub_mul_eq_mod_of_lt_of_le (by omega) (by omega)]
|
||||
· rw [Nat.mul_succ] at hi ⊢
|
||||
simp only [show ¬i < w * n by omega, decide_false, cond_false, hi, Bool.false_and]
|
||||
simp only [show ¬i < w * n by omega, decide_false, hi, Bool.false_and]
|
||||
apply BitVec.getLsbD_of_ge (x := x) (i := i - w * n) (ge := by omega)
|
||||
|
||||
@[simp]
|
||||
@@ -5392,14 +5385,14 @@ theorem sdiv_neg_one {w : Nat} {x : BitVec w} :
|
||||
x.toInt / -1 = -x.toInt := by
|
||||
rcases w with _|w
|
||||
· simp [of_length_zero]
|
||||
· simp [toInt_allOnes]
|
||||
· simp
|
||||
|
||||
theorem sdivOverflow_eq_negOverflow_of_eq_allOnes {w : Nat} {x y : BitVec w} (hy : y = allOnes w) :
|
||||
sdivOverflow x y = negOverflow x := by
|
||||
rcases w with _|w
|
||||
· simp [sdivOverflow, negOverflow, of_length_zero]
|
||||
· have xle := le_two_mul_toInt (x := x); have xlt := two_mul_toInt_lt (x := x)
|
||||
simp only [sdivOverflow, hy, show ¬2 ^ w < x.toInt by omega, negOverflow]
|
||||
simp only [sdivOverflow, hy, negOverflow]
|
||||
by_cases hx : x.toInt = - 2 ^ w
|
||||
· simp [hx]
|
||||
· simp [show ¬x.toInt == -2 ^ w by simp only [beq_iff_eq, hx, not_false_eq_true]]; omega
|
||||
@@ -5610,11 +5603,11 @@ theorem reverse_append {x : BitVec w} {y : BitVec v} :
|
||||
simp only [getElem_reverse, getElem_cast, getElem_append]
|
||||
by_cases hi : i < v
|
||||
· by_cases hw : w ≤ i
|
||||
· simp [getLsbD_reverse, hw]
|
||||
· simp [getElem_reverse, hw, show i < w by omega]
|
||||
· simp [hw]
|
||||
· simp [hw, show i < w by omega]
|
||||
· by_cases hw : w ≤ i
|
||||
· simp [hw, show ¬ i < w by omega, getLsbD_reverse]
|
||||
· simp [hw, show i < w by omega, getElem_reverse]
|
||||
· simp [hw, show ¬ i < w by omega]
|
||||
· simp [hw, show i < w by omega]
|
||||
|
||||
@[simp]
|
||||
theorem reverse_cast {w v : Nat} (h : w = v) (x : BitVec w) :
|
||||
|
||||
@@ -488,7 +488,7 @@ Converts `true` to `1` and `false` to `0`.
|
||||
|
||||
@[simp] theorem ite_eq_true_else_eq_false {q : Prop} :
|
||||
(if b = true then q else b = false) ↔ (b = true → q) := by
|
||||
cases b <;> simp [not_eq_self]
|
||||
cases b <;> simp
|
||||
|
||||
/-
|
||||
`not_ite_eq_true_eq_true` and related theorems below are added for
|
||||
|
||||
@@ -252,7 +252,7 @@ theorem foldl_succ_last (f : α → Fin (n+1) → α) (x) :
|
||||
foldl (n+1) f x = f (foldl n (f · ·.castSucc) x) (last n) := by
|
||||
rw [foldl_succ]
|
||||
induction n generalizing x with
|
||||
| zero => simp [foldl_succ, Fin.last]
|
||||
| zero => simp [Fin.last]
|
||||
| succ n ih => rw [foldl_succ, ih (f · ·.succ), foldl_succ]; simp
|
||||
|
||||
theorem foldl_add (f : α → Fin (n + m) → α) (x) :
|
||||
|
||||
@@ -381,7 +381,7 @@ theorem zero_ne_one : (0 : Fin (n + 2)) ≠ 1 := Fin.ne_of_lt one_pos
|
||||
@[simp] theorem val_succ (j : Fin n) : (j.succ : Nat) = j + 1 := rfl
|
||||
|
||||
@[simp] theorem succ_pos (a : Fin n) : (0 : Fin (n + 1)) < a.succ := by
|
||||
simp [Fin.lt_def, Nat.succ_pos]
|
||||
simp [Fin.lt_def]
|
||||
|
||||
@[simp] theorem succ_le_succ_iff {a b : Fin n} : a.succ ≤ b.succ ↔ a ≤ b := Nat.succ_le_succ_iff
|
||||
|
||||
@@ -414,7 +414,7 @@ theorem one_lt_succ_succ (a : Fin n) : (1 : Fin (n + 2)) < a.succ.succ := by
|
||||
simp only [lt_def, val_add, val_last, Fin.ext_iff]
|
||||
let ⟨k, hk⟩ := k
|
||||
match Nat.eq_or_lt_of_le (Nat.le_of_lt_succ hk) with
|
||||
| .inl h => cases h; simp [Nat.succ_pos]
|
||||
| .inl h => cases h; simp
|
||||
| .inr hk' => simp [Nat.ne_of_lt hk', Nat.mod_eq_of_lt (Nat.succ_lt_succ hk'), Nat.le_succ]
|
||||
|
||||
@[simp] theorem add_one_le_iff {n : Nat} : ∀ {k : Fin (n + 1)}, k + 1 ≤ k ↔ k = last _ := by
|
||||
@@ -426,7 +426,7 @@ theorem one_lt_succ_succ (a : Fin n) : (1 : Fin (n + 2)) < a.succ.succ := by
|
||||
intro (k : Fin (n+2))
|
||||
rw [← add_one_lt_iff, lt_def, le_def, Nat.lt_iff_le_and_ne, and_iff_left]
|
||||
rw [val_add_one]
|
||||
split <;> simp [*, (Nat.succ_ne_zero _).symm, Nat.ne_of_gt (Nat.lt_succ_self _)]
|
||||
split <;> simp [*, Nat.ne_of_gt (Nat.lt_succ_self _)]
|
||||
|
||||
@[simp] theorem last_le_iff {n : Nat} {k : Fin (n + 1)} : last n ≤ k ↔ k = last n := by
|
||||
rw [Fin.ext_iff, Nat.le_antisymm_iff, le_def, and_iff_right (by apply le_last)]
|
||||
@@ -738,7 +738,7 @@ theorem pred_mk {n : Nat} (i : Nat) (h : i < n + 1) (w) : Fin.pred ⟨i, h⟩ w
|
||||
∀ {a b : Fin (n + 1)} {ha : a ≠ 0} {hb : b ≠ 0}, a.pred ha = b.pred hb ↔ a = b
|
||||
| ⟨0, _⟩, _, ha, _ => by simp only [mk_zero, ne_eq, not_true] at ha
|
||||
| ⟨i + 1, _⟩, ⟨0, _⟩, _, hb => by simp only [mk_zero, ne_eq, not_true] at hb
|
||||
| ⟨i + 1, hi⟩, ⟨j + 1, hj⟩, ha, hb => by simp [Fin.ext_iff, Nat.succ.injEq]
|
||||
| ⟨i + 1, hi⟩, ⟨j + 1, hj⟩, ha, hb => by simp [Fin.ext_iff]
|
||||
|
||||
@[simp] theorem pred_one {n : Nat} :
|
||||
Fin.pred (1 : Fin (n + 2)) (Ne.symm (Fin.ne_of_lt one_pos)) = 0 := rfl
|
||||
@@ -1117,7 +1117,7 @@ protected theorem mul_one [i : NeZero n] (k : Fin n) : k * 1 = k := by
|
||||
| n + 1, _ =>
|
||||
match n with
|
||||
| 0 => exact Subsingleton.elim (α := Fin 1) ..
|
||||
| n+1 => simp [Fin.ext_iff, mul_def, Nat.mod_eq_of_lt (is_lt k)]
|
||||
| n+1 => simp [mul_def, Nat.mod_eq_of_lt (is_lt k)]
|
||||
|
||||
protected theorem mul_comm (a b : Fin n) : a * b = b * a :=
|
||||
Fin.ext <| by rw [mul_def, mul_def, Nat.mul_comm]
|
||||
|
||||
@@ -37,7 +37,7 @@ theorem compare_eq_ite_le (a b : Int) :
|
||||
· next hlt => simp [Int.le_of_lt hlt, Int.not_le.2 hlt]
|
||||
· next hge =>
|
||||
split
|
||||
· next hgt => simp [Int.le_of_lt hgt, Int.not_le.2 hgt]
|
||||
· next hgt => simp [Int.not_le.2 hgt]
|
||||
· next hle => simp [Int.not_lt.1 hge, Int.not_lt.1 hle]
|
||||
|
||||
protected theorem compare_swap (a b : Int) : (compare a b).swap = compare b a := by
|
||||
|
||||
@@ -56,7 +56,7 @@ protected theorem dvd_trans : ∀ {a b c : Int}, a ∣ b → b ∣ c → a ∣ c
|
||||
|
||||
@[simp] protected theorem dvd_neg {a b : Int} : a ∣ -b ↔ a ∣ b := by
|
||||
constructor <;> exact fun ⟨k, e⟩ =>
|
||||
⟨-k, by simp [← e, Int.neg_mul, Int.mul_neg, Int.neg_neg]⟩
|
||||
⟨-k, by simp [← e, Int.mul_neg, Int.neg_neg]⟩
|
||||
|
||||
@[simp] theorem natAbs_dvd_natAbs {a b : Int} : natAbs a ∣ natAbs b ↔ a ∣ b := by
|
||||
refine ⟨fun ⟨k, hk⟩ => ?_, fun ⟨k, hk⟩ => ⟨natAbs k, hk.symm ▸ natAbs_mul a k⟩⟩
|
||||
|
||||
@@ -217,7 +217,7 @@ theorem tdiv_eq_ediv {a b : Int} :
|
||||
negSucc_not_nonneg, sign_of_add_one]
|
||||
simp only [negSucc_emod_ofNat_succ_eq_zero_iff]
|
||||
norm_cast
|
||||
simp only [subNat_eq_zero_iff, Nat.succ_eq_add_one, sign_negSucc, Int.sub_neg, false_or]
|
||||
simp only [Nat.succ_eq_add_one, false_or]
|
||||
split <;> rename_i h
|
||||
· rw [Int.add_zero, neg_ofNat_eq_negSucc_iff]
|
||||
exact Nat.succ_div_of_mod_eq_zero h
|
||||
@@ -1317,7 +1317,7 @@ protected theorem eq_tdiv_of_mul_eq_left {a b c : Int}
|
||||
| 0, n => by simp [Int.neg_zero]
|
||||
| succ _, (n:Nat) => by simp [tdiv, ← Int.negSucc_eq]
|
||||
| -[_+1], 0 | -[_+1], -[_+1] => by
|
||||
simp only [tdiv, neg_negSucc, ← Int.natCast_succ, Int.neg_neg]
|
||||
simp only [tdiv, neg_negSucc, Int.neg_neg]
|
||||
| succ _, -[_+1] | -[_+1], succ _ => (Int.neg_neg _).symm
|
||||
|
||||
protected theorem neg_tdiv_neg (a b : Int) : (-a).tdiv (-b) = a.tdiv b := by
|
||||
@@ -1408,7 +1408,7 @@ theorem mul_tmod (a b n : Int) : (a * b).tmod n = (a.tmod n * b.tmod n).tmod n :
|
||||
case inv => simp [Int.dvd_neg]
|
||||
induction m using wlog_sign
|
||||
case inv => simp
|
||||
simp only [← Int.natCast_mul, ← ofNat_tmod]
|
||||
simp only [← ofNat_tmod]
|
||||
norm_cast at h
|
||||
rw [Nat.mod_mod_of_dvd _ h]
|
||||
|
||||
@@ -1576,7 +1576,7 @@ theorem neg_mul_tmod_left (a b : Int) : (-(a * b)).tmod b = 0 := by
|
||||
|
||||
@[simp] protected theorem tdiv_one : ∀ a : Int, a.tdiv 1 = a
|
||||
| (n:Nat) => congrArg ofNat (Nat.div_one _)
|
||||
| -[n+1] => by simp [Int.tdiv, neg_ofNat_succ]; rfl
|
||||
| -[n+1] => by simp [Int.tdiv]; rfl
|
||||
|
||||
@[simp] theorem tmod_one (a : Int) : tmod a 1 = 0 := by
|
||||
simp [tmod_def, Int.tdiv_one, Int.one_mul, Int.sub_self]
|
||||
@@ -1698,7 +1698,7 @@ theorem lt_ediv_iff_of_dvd_of_neg {a b c : Int} (hc : c < 0) (hcb : c ∣ b) :
|
||||
theorem ediv_le_ediv_iff_of_dvd_of_pos_of_pos {a b c d : Int} (hb : 0 < b) (hd : 0 < d)
|
||||
(hba : b ∣ a) (hdc : d ∣ c) : a / b ≤ c / d ↔ d * a ≤ c * b := by
|
||||
obtain ⟨⟨x, rfl⟩, y, rfl⟩ := hba, hdc
|
||||
simp [*, Int.ne_of_lt, Int.ne_of_gt, d.mul_assoc, b.mul_comm]
|
||||
simp [*, Int.ne_of_gt, d.mul_assoc, b.mul_comm]
|
||||
|
||||
theorem ediv_le_ediv_iff_of_dvd_of_pos_of_neg {a b c d : Int} (hb : 0 < b) (hd : d < 0)
|
||||
(hba : b ∣ a) (hdc : d ∣ c) : a / b ≤ c / d ↔ c * b ≤ d * a := by
|
||||
@@ -1713,12 +1713,12 @@ theorem ediv_le_ediv_iff_of_dvd_of_neg_of_pos {a b c d : Int} (hb : b < 0) (hd :
|
||||
theorem ediv_le_ediv_iff_of_dvd_of_neg_of_neg {a b c d : Int} (hb : b < 0) (hd : d < 0)
|
||||
(hba : b ∣ a) (hdc : d ∣ c) : a / b ≤ c / d ↔ d * a ≤ c * b := by
|
||||
obtain ⟨⟨x, rfl⟩, y, rfl⟩ := hba, hdc
|
||||
simp [*, Int.ne_of_lt, Int.ne_of_gt, d.mul_assoc, b.mul_comm]
|
||||
simp [*, Int.ne_of_lt, d.mul_assoc, b.mul_comm]
|
||||
|
||||
theorem ediv_lt_ediv_iff_of_dvd_of_pos {a b c d : Int} (hb : 0 < b) (hd : 0 < d) (hba : b ∣ a)
|
||||
(hdc : d ∣ c) : a / b < c / d ↔ d * a < c * b := by
|
||||
obtain ⟨⟨x, rfl⟩, y, rfl⟩ := hba, hdc
|
||||
simp [*, Int.ne_of_lt, Int.ne_of_gt, d.mul_assoc, b.mul_comm]
|
||||
simp [*, Int.ne_of_gt, d.mul_assoc, b.mul_comm]
|
||||
|
||||
theorem ediv_lt_ediv_iff_of_dvd_of_pos_of_neg {a b c d : Int} (hb : 0 < b) (hd : d < 0)
|
||||
(hba : b ∣ a) (hdc : d ∣ c) : a / b < c / d ↔ c * b < d * a := by
|
||||
@@ -1733,7 +1733,7 @@ theorem ediv_lt_ediv_iff_of_dvd_of_neg_of_pos {a b c d : Int} (hb : b < 0) (hd :
|
||||
theorem ediv_lt_ediv_iff_of_dvd_of_neg_of_neg {a b c d : Int} (hb : b < 0) (hd : d < 0)
|
||||
(hba : b ∣ a) (hdc : d ∣ c) : a / b < c / d ↔ d * a < c * b := by
|
||||
obtain ⟨⟨x, rfl⟩, y, rfl⟩ := hba, hdc
|
||||
simp [*, Int.ne_of_lt, Int.ne_of_gt, d.mul_assoc, b.mul_comm]
|
||||
simp [*, Int.ne_of_lt, d.mul_assoc, b.mul_comm]
|
||||
|
||||
/-! ### `tdiv` and ordering -/
|
||||
|
||||
@@ -2446,7 +2446,7 @@ theorem lt_mul_fdiv_self_add {x k : Int} (h : 0 < k) : x < k * (x.fdiv k) + k :=
|
||||
|
||||
@[simp]
|
||||
theorem emod_bmod (x : Int) (n : Nat) : Int.bmod (x%n) n = Int.bmod x n := by
|
||||
simp [bmod, Int.emod_emod]
|
||||
simp [bmod]
|
||||
|
||||
@[deprecated emod_bmod (since := "2025-04-11")]
|
||||
theorem emod_bmod_congr (x : Int) (n : Nat) : Int.bmod (x%n) n = Int.bmod x n :=
|
||||
@@ -2987,7 +2987,7 @@ theorem self_le_ediv_of_nonpos_of_nonneg {x y : Int} (hx : x ≤ 0) (hy : 0 ≤
|
||||
· simp [hx', zero_ediv]
|
||||
· by_cases hy : y = 0
|
||||
· simp [hy]; omega
|
||||
· simp only [ge_iff_le, Int.le_ediv_iff_mul_le (c := y) (a := x) (b := x) (by omega),
|
||||
· simp only [Int.le_ediv_iff_mul_le (c := y) (a := x) (b := x) (by omega),
|
||||
show (x * y ≤ x) = (x * y ≤ x * 1) by rw [Int.mul_one], Int.mul_one]
|
||||
apply Int.mul_le_mul_of_nonpos_left (a := x) (b := y) (c := (1 : Int)) (by omega) (by omega)
|
||||
|
||||
|
||||
@@ -631,7 +631,7 @@ theorem lcm_mul_left_dvd_mul_lcm (k m n : Nat) : lcm (m * n) k ∣ lcm m k * lcm
|
||||
simpa [lcm_comm, Nat.mul_comm] using lcm_mul_right_dvd_mul_lcm _ _ _
|
||||
|
||||
theorem lcm_dvd_mul_self_left_iff_dvd_mul {k n m : Nat} : lcm k n ∣ k * m ↔ n ∣ k * m := by
|
||||
simp [← natAbs_dvd_natAbs, natAbs_mul, Nat.lcm_dvd_mul_self_left_iff_dvd_mul,
|
||||
simp [Nat.lcm_dvd_mul_self_left_iff_dvd_mul,
|
||||
lcm_eq_natAbs_lcm_natAbs]
|
||||
|
||||
theorem lcm_dvd_mul_self_right_iff_dvd_mul {k m n : Nat} : lcm n k ∣ m * k ↔ n ∣ m * k := by
|
||||
|
||||
@@ -454,7 +454,7 @@ theorem negOfNat_eq_subNatNat_zero (n) : negOfNat n = subNatNat 0 n := by cases
|
||||
theorem ofNat_mul_subNatNat (m n k : Nat) :
|
||||
m * subNatNat n k = subNatNat (m * n) (m * k) := by
|
||||
cases m with
|
||||
| zero => simp [ofNat_zero, Int.zero_mul, Nat.zero_mul, subNatNat_self]
|
||||
| zero => simp [Int.zero_mul, Nat.zero_mul, subNatNat_self]
|
||||
| succ m => cases n.lt_or_ge k with
|
||||
| inl h =>
|
||||
have h' : succ m * n < succ m * k := Nat.mul_lt_mul_of_pos_left h (Nat.succ_pos m)
|
||||
|
||||
@@ -79,8 +79,8 @@ where
|
||||
theorem Poly.denote'_go_eq_denote (ctx : Context) (p : Poly) (r : Int) : denote'.go ctx r p = p.denote ctx + r := by
|
||||
induction r, p using denote'.go.induct ctx <;> simp [denote'.go, denote]
|
||||
next => rw [Int.add_comm]
|
||||
next ih => simp [denote'.go] at ih; rw [ih]; ac_rfl
|
||||
next ih => simp [denote'.go] at ih; rw [ih]; ac_rfl
|
||||
next ih => simp at ih; rw [ih]; ac_rfl
|
||||
next ih => simp at ih; rw [ih]; ac_rfl
|
||||
|
||||
theorem Poly.denote'_eq_denote (ctx : Context) (p : Poly) : p.denote' ctx = p.denote ctx := by
|
||||
unfold denote' <;> split <;> simp [denote, denote'_go_eq_denote] <;> ac_rfl
|
||||
@@ -363,7 +363,7 @@ theorem Expr.denote_toPoly'_go (ctx : Context) (e : Expr) :
|
||||
simp [eq_of_beq h]
|
||||
| case2 k k' h =>
|
||||
simp only [toPoly'.go, h, cond_false]
|
||||
simp [Var.denote]
|
||||
simp
|
||||
| case3 k i => simp [toPoly'.go]
|
||||
| case4 k a b iha ihb => simp [toPoly'.go, iha, ihb]
|
||||
| case5 k a b iha ihb =>
|
||||
@@ -371,7 +371,7 @@ theorem Expr.denote_toPoly'_go (ctx : Context) (e : Expr) :
|
||||
rw [Int.sub_eq_add_neg, ←Int.neg_mul, Int.add_assoc]
|
||||
| case6 k k' a h
|
||||
| case8 k a k' h =>
|
||||
simp only [toPoly'.go, h, cond_false]
|
||||
simp only [toPoly'.go, h]
|
||||
simp [eq_of_beq h]
|
||||
| case7 k a k' h ih =>
|
||||
simp only [toPoly'.go, h, cond_false]
|
||||
@@ -403,7 +403,7 @@ attribute [local simp] Poly.denote'_eq_denote
|
||||
|
||||
theorem Expr.eq_of_norm_eq (ctx : Context) (e : Expr) (p : Poly) (h : e.norm == p) : e.denote ctx = p.denote' ctx := by
|
||||
have h := congrArg (Poly.denote ctx) (eq_of_beq h)
|
||||
simp [Poly.norm] at h
|
||||
simp at h
|
||||
simp [*]
|
||||
|
||||
@[expose]
|
||||
@@ -472,7 +472,7 @@ private theorem mul_le_zero_iff (a k : Int) (h₁ : k > 0) : k * a ≤ 0 ↔ a
|
||||
simp at h; assumption
|
||||
|
||||
private theorem norm_le_coeff' (ctx : Context) (p p' : Poly) (k : Int) : p = p'.mul k → k > 0 → (p.denote ctx ≤ 0 ↔ p'.denote ctx ≤ 0) := by
|
||||
simp [norm_eq_coeff_cert]
|
||||
simp
|
||||
intro; subst p; intro h; simp [mul_le_zero_iff, *]
|
||||
|
||||
theorem norm_le_coeff (ctx : Context) (lhs rhs : Expr) (p : Poly) (k : Int)
|
||||
@@ -815,7 +815,7 @@ theorem dvd_solve_combine (ctx : Context) (d₁ : Int) (p₁ : Poly) (d₂ : Int
|
||||
split <;> simp
|
||||
next a₁ x₁ p₁ a₂ x₂ p₂ =>
|
||||
intro _ hg hd hp; subst x₁ p
|
||||
simp [Poly.denote'_add]
|
||||
simp
|
||||
intro h₁ h₂
|
||||
rw [Int.add_comm] at h₁ h₂
|
||||
rw [Int.add_comm _ (g * x₂.denote ctx), Int.add_left_comm, ← Int.add_assoc, hd]
|
||||
@@ -1100,7 +1100,7 @@ theorem diseq_coeff (ctx : Context) (p p' : Poly) (k : Int) : eq_coeff_cert p p'
|
||||
intro _ _; simp [mul_eq_zero_iff, *]
|
||||
|
||||
theorem diseq_neg (ctx : Context) (p p' : Poly) : p' == p.mul (-1) → p.denote' ctx ≠ 0 → p'.denote' ctx ≠ 0 := by
|
||||
simp; intro _ _; simp [mul_eq_zero_iff, *]
|
||||
simp; intro _ _; simp [*]
|
||||
|
||||
theorem diseq_unsat (ctx : Context) (p : Poly) : p.isUnsatDiseq → p.denote' ctx ≠ 0 → False := by
|
||||
simp [Poly.isUnsatDiseq] <;> split <;> simp
|
||||
@@ -1311,7 +1311,7 @@ def cooper_dvd_left_split_ineq_cert (p₁ p₂ : Poly) (k : Int) (b : Int) (p' :
|
||||
theorem cooper_dvd_left_split_ineq (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (k : Nat) (b : Int) (p' : Poly)
|
||||
: cooper_dvd_left_split ctx p₁ p₂ p₃ d k → cooper_dvd_left_split_ineq_cert p₁ p₂ k b p' → p'.denote' ctx ≤ 0 := by
|
||||
simp [cooper_dvd_left_split_ineq_cert, cooper_dvd_left_split]
|
||||
intros; subst p' b; simp [denote'_mul_combine_mul_addConst_eq]; assumption
|
||||
intros; subst p' b; simp; assumption
|
||||
|
||||
@[expose]
|
||||
def cooper_dvd_left_split_dvd1_cert (p₁ p' : Poly) (a : Int) (k : Int) : Bool :=
|
||||
@@ -1348,7 +1348,7 @@ private theorem cooper_left_core
|
||||
have h := cooper_dvd_left_core a_neg b_pos d_pos h₁ h₂ h₃
|
||||
simp only [Int.mul_one, gcd_zero, ofNat_natAbs_of_nonpos (Int.le_of_lt a_neg), Int.ediv_neg,
|
||||
Int.ediv_self (Int.ne_of_lt a_neg), Int.reduceNeg, lcm_neg_right, lcm_one,
|
||||
Int.add_left_comm, Int.zero_mul, Int.mul_zero, Int.add_zero, Int.dvd_zero,
|
||||
Int.zero_mul, Int.mul_zero, Int.add_zero, Int.dvd_zero,
|
||||
and_true] at h
|
||||
assumption
|
||||
|
||||
@@ -1398,7 +1398,7 @@ def cooper_left_split_ineq_cert (p₁ p₂ : Poly) (k : Int) (b : Int) (p' : Pol
|
||||
theorem cooper_left_split_ineq (ctx : Context) (p₁ p₂ : Poly) (k : Nat) (b : Int) (p' : Poly)
|
||||
: cooper_left_split ctx p₁ p₂ k → cooper_left_split_ineq_cert p₁ p₂ k b p' → p'.denote' ctx ≤ 0 := by
|
||||
simp [cooper_left_split_ineq_cert, cooper_left_split]
|
||||
intros; subst p' b; simp [denote'_mul_combine_mul_addConst_eq]; assumption
|
||||
intros; subst p' b; simp; assumption
|
||||
|
||||
@[expose]
|
||||
def cooper_left_split_dvd_cert (p₁ p' : Poly) (a : Int) (k : Int) : Bool :=
|
||||
@@ -1422,7 +1422,7 @@ private theorem cooper_dvd_right_core
|
||||
have h₁' : p ≤ (-a)*x := by rw [Int.neg_mul, ← Lean.Omega.Int.add_le_zero_iff_le_neg']; assumption
|
||||
have h₂' : b * x ≤ -q := by rw [← Lean.Omega.Int.add_le_zero_iff_le_neg', Int.add_comm]; assumption
|
||||
have ⟨k, h₁, h₂, h₃, h₄, h₅⟩ := Int.cooper_resolution_dvd_right a_pos' b_pos d_pos |>.mp ⟨x, h₁', h₂', h₃⟩
|
||||
simp only [Int.neg_mul, neg_gcd, lcm_neg_left, Int.mul_neg, Int.neg_neg, Int.neg_dvd] at *
|
||||
simp only [Int.neg_mul, Int.mul_neg, Int.neg_neg] at *
|
||||
apply orOver_of_exists
|
||||
have hlt := ofNat_lt h₁ h₂
|
||||
replace h₃ := Int.add_le_add_right h₃ (-(a*q)); rw [Int.add_right_neg] at h₃
|
||||
@@ -1432,7 +1432,7 @@ private theorem cooper_dvd_right_core
|
||||
have : -(c * k) + -(c * q) + b * s = -(c * q) + b * s + -(c * k) := by ac_rfl
|
||||
rw [this] at h₅; clear this
|
||||
exists k.toNat
|
||||
simp only [hlt, true_and, and_true, cast_toNat h₁, h₃, h₄, h₅]
|
||||
simp only [hlt, and_true, cast_toNat h₁, h₃, h₄, h₅]
|
||||
|
||||
@[expose]
|
||||
def cooper_dvd_right_cert (p₁ p₂ p₃ : Poly) (d : Int) (n : Nat) : Bool :=
|
||||
@@ -1473,7 +1473,7 @@ theorem cooper_dvd_right (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (n :
|
||||
intro h₁ h₂ h₃
|
||||
have := cooper_dvd_right_core ha hb hd h₁ h₂ h₃
|
||||
simp only [denote'_mul_combine_mul_addConst_eq]
|
||||
simp only [denote'_addConst_eq, ←Int.neg_mul]
|
||||
simp only [denote'_addConst_eq]
|
||||
exact cooper_dvd_right_core ha hb hd h₁ h₂ h₃
|
||||
|
||||
@[expose]
|
||||
@@ -1487,7 +1487,7 @@ def cooper_dvd_right_split_ineq_cert (p₁ p₂ : Poly) (k : Int) (a : Int) (p'
|
||||
theorem cooper_dvd_right_split_ineq (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (k : Nat) (a : Int) (p' : Poly)
|
||||
: cooper_dvd_right_split ctx p₁ p₂ p₃ d k → cooper_dvd_right_split_ineq_cert p₁ p₂ k a p' → p'.denote' ctx ≤ 0 := by
|
||||
simp [cooper_dvd_right_split_ineq_cert, cooper_dvd_right_split]
|
||||
intros; subst a p'; simp [denote'_mul_combine_mul_addConst_eq]; assumption
|
||||
intros; subst a p'; simp; assumption
|
||||
|
||||
@[expose]
|
||||
def cooper_dvd_right_split_dvd1_cert (p₂ p' : Poly) (b : Int) (k : Int) : Bool :=
|
||||
@@ -1522,9 +1522,9 @@ private theorem cooper_right_core
|
||||
have d_pos : (0 : Int) < 1 := by decide
|
||||
have h₃ : 1 ∣ 0*x + 0 := Int.one_dvd _
|
||||
have h := cooper_dvd_right_core a_neg b_pos d_pos h₁ h₂ h₃
|
||||
simp only [Int.mul_one, gcd_zero, Int.natAbs_of_nonneg (Int.le_of_lt b_pos), Int.ediv_neg,
|
||||
Int.ediv_self (Int.ne_of_gt b_pos), Int.reduceNeg, lcm_neg_right, lcm_one,
|
||||
Int.add_left_comm, Int.zero_mul, Int.mul_zero, Int.add_zero, Int.dvd_zero,
|
||||
simp only [Int.mul_one, gcd_zero, Int.natAbs_of_nonneg (Int.le_of_lt b_pos),
|
||||
Int.ediv_self (Int.ne_of_gt b_pos), lcm_one,
|
||||
Int.zero_mul, Int.mul_zero, Int.add_zero, Int.dvd_zero,
|
||||
and_true, Int.neg_zero] at h
|
||||
assumption
|
||||
|
||||
@@ -1559,7 +1559,7 @@ theorem cooper_right (ctx : Context) (p₁ p₂ : Poly) (n : Nat)
|
||||
intro h₁ h₂
|
||||
have := cooper_right_core ha hb h₁ h₂
|
||||
simp only [denote'_mul_combine_mul_addConst_eq]
|
||||
simp only [denote'_addConst_eq, ←Int.neg_mul]
|
||||
simp only [denote'_addConst_eq]
|
||||
assumption
|
||||
|
||||
@[expose]
|
||||
@@ -1573,7 +1573,7 @@ def cooper_right_split_ineq_cert (p₁ p₂ : Poly) (k : Int) (a : Int) (p' : Po
|
||||
theorem cooper_right_split_ineq (ctx : Context) (p₁ p₂ : Poly) (k : Nat) (a : Int) (p' : Poly)
|
||||
: cooper_right_split ctx p₁ p₂ k → cooper_right_split_ineq_cert p₁ p₂ k a p' → p'.denote' ctx ≤ 0 := by
|
||||
simp [cooper_right_split_ineq_cert, cooper_right_split]
|
||||
intros; subst a p'; simp [denote'_mul_combine_mul_addConst_eq]; assumption
|
||||
intros; subst a p'; simp; assumption
|
||||
|
||||
@[expose]
|
||||
def cooper_right_split_dvd_cert (p₂ p' : Poly) (b : Int) (k : Int) : Bool :=
|
||||
@@ -1682,7 +1682,7 @@ theorem cooper_unsat (ctx : Context) (p₁ p₂ p₃ : Poly) (d : Int) (α β :
|
||||
: cooper_unsat_cert p₁ p₂ p₃ d α β →
|
||||
p₁.denote' ctx ≤ 0 → p₂.denote' ctx ≤ 0 → d ∣ p₃.denote' ctx → False := by
|
||||
unfold cooper_unsat_cert <;> cases p₁ <;> cases p₂ <;> cases p₃ <;> simp only [Poly.casesOnAdd,
|
||||
Bool.false_eq_true, Poly.denote'_add, mul_def, add_def, false_implies]
|
||||
Bool.false_eq_true, Poly.denote'_add, false_implies]
|
||||
next k₁ x p₁ k₂ y p₂ c z p₃ =>
|
||||
cases p₁ <;> cases p₂ <;> cases p₃ <;> simp only [Poly.casesOnNum, Int.reduceNeg,
|
||||
Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq, and_imp, Bool.false_eq_true,
|
||||
@@ -1819,7 +1819,7 @@ def dvd_neg_le_tight_cert (d : Int) (p₁ p₂ p₃ : Poly) : Bool :=
|
||||
d > 0 && (p₂ == p.addConst b₂ && p₃ == p.addConst (b₁ - d*((b₁ - b₂)/d)))
|
||||
|
||||
theorem Poly.mul_minus_one_getConst_eq (p : Poly) : (p.mul (-1)).getConst = -p.getConst := by
|
||||
simp [Poly.mul, Poly.getConst]
|
||||
simp [Poly.mul]
|
||||
induction p <;> simp [Poly.mul', Poly.getConst, *]
|
||||
|
||||
theorem dvd_neg_le_tight (ctx : Context) (d : Int) (p₁ p₂ p₃ : Poly)
|
||||
@@ -1900,7 +1900,7 @@ theorem not_le_of_le (ctx : Context) (p q : Poly) (k : Nat)
|
||||
intro h
|
||||
apply Int.pos_of_neg_neg
|
||||
apply Int.lt_of_add_one_le
|
||||
simp [Int.neg_add, Int.neg_sub]
|
||||
simp [Int.neg_add]
|
||||
rw [← Int.add_assoc, ← Int.add_assoc, Int.add_neg_cancel_right, Lean.Omega.Int.add_le_zero_iff_le_neg']
|
||||
simp; exact Int.le_trans h (Int.ofNat_zero_le _)
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ def Expr.denoteAsInt (ctx : Context) : Expr → Int
|
||||
| .mod a b => Int.emod (denoteAsInt ctx a) (denoteAsInt ctx b)
|
||||
|
||||
theorem Expr.denoteAsInt_eq (ctx : Context) (e : Expr) : e.denoteAsInt ctx = e.denote ctx := by
|
||||
induction e <;> simp [denote, denoteAsInt, Int.natCast_ediv, *] <;> rfl
|
||||
induction e <;> simp [denote, denoteAsInt, *] <;> rfl
|
||||
|
||||
theorem Expr.eq_denoteAsInt (ctx : Context) (e : Expr) : e.denote ctx = e.denoteAsInt ctx := by
|
||||
apply Eq.symm; apply denoteAsInt_eq
|
||||
|
||||
@@ -448,7 +448,7 @@ protected theorem le_max_left (a b : Int) : a ≤ max a b := by rw [Int.max_def]
|
||||
protected theorem le_max_right (a b : Int) : b ≤ max a b := Int.max_comm .. ▸ Int.le_max_left ..
|
||||
|
||||
protected theorem max_eq_right {a b : Int} (h : a ≤ b) : max a b = b := by
|
||||
simp [Int.max_def, h, Int.not_lt.2 h]
|
||||
simp [Int.max_def, h]
|
||||
|
||||
protected theorem max_eq_left {a b : Int} (h : b ≤ a) : max a b = a := by
|
||||
rw [← Int.max_comm b a]; exact Int.max_eq_right h
|
||||
|
||||
@@ -188,10 +188,10 @@ protected theorem PostconditionT.bind_assoc {m : Type w → Type w'} [Monad m] [
|
||||
protected theorem PostconditionT.map_pure {m : Type w → Type w'} [Monad m] [LawfulMonad m]
|
||||
{α : Type w} {β : Type w} {f : α → β} {a : α} :
|
||||
(pure a : PostconditionT m α).map f = pure (f a) := by
|
||||
apply PostconditionT.ext <;> simp [pure, Functor.map, PostconditionT.map, PostconditionT.pure]
|
||||
apply PostconditionT.ext <;> simp [pure, PostconditionT.map, PostconditionT.pure]
|
||||
|
||||
instance [Monad m] [LawfulMonad m] : LawfulMonad (PostconditionT m) where
|
||||
map_const {α β} := by ext a x; simp [Functor.mapConst, Function.const_apply, Functor.map]
|
||||
map_const {α β} := by ext a x; simp [Functor.mapConst, Functor.map]
|
||||
id_map {α} x := by simp [Functor.map]
|
||||
comp_map {α β γ} g h := by intro x; simp [Functor.map]; rfl
|
||||
seqLeft_eq {α β} x y := by simp [SeqLeft.seqLeft, Functor.map, Seq.seq]; rfl
|
||||
|
||||
@@ -255,7 +255,7 @@ set_option linter.deprecated false in
|
||||
theorem get?_pmap {p : α → Prop} (f : ∀ a, p a → β) {l : List α} (h : ∀ a ∈ l, p a) (n : Nat) :
|
||||
get? (pmap f l h) n = Option.pmap f (get? l n) fun x H => h x (mem_of_get? H) := by
|
||||
simp only [get?_eq_getElem?]
|
||||
simp [getElem?_pmap, h]
|
||||
simp [getElem?_pmap]
|
||||
|
||||
-- The argument `f` is explicit to allow rewriting from right to left.
|
||||
@[simp, grind =]
|
||||
@@ -322,14 +322,14 @@ theorem getElem_attach {xs : List α} {i : Nat} (h : i < xs.attach.length) :
|
||||
| nil => simp
|
||||
| cons x xs ih =>
|
||||
simp at ih
|
||||
simp [head?_pmap, ih]
|
||||
simp
|
||||
|
||||
@[simp, grind =] theorem head_pmap {P : α → Prop} {f : (a : α) → P a → β} {xs : List α}
|
||||
(H : ∀ (a : α), a ∈ xs → P a) (h : xs.pmap f H ≠ []) :
|
||||
(xs.pmap f H).head h = f (xs.head (by simpa using h)) (H _ (head_mem _)) := by
|
||||
induction xs with
|
||||
| nil => simp at h
|
||||
| cons x xs ih => simp [head_pmap, ih]
|
||||
| cons x xs ih => simp
|
||||
|
||||
@[simp, grind =] theorem head?_attachWith {P : α → Prop} {xs : List α}
|
||||
(H : ∀ (a : α), a ∈ xs → P a) :
|
||||
@@ -341,7 +341,7 @@ theorem getElem_attach {xs : List α} {i : Nat} (h : i < xs.attach.length) :
|
||||
(xs.attachWith P H).head h = ⟨xs.head (by simpa using h), H _ (head_mem _)⟩ := by
|
||||
cases xs with
|
||||
| nil => simp at h
|
||||
| cons x xs => simp [head_attachWith, h]
|
||||
| cons x xs => simp
|
||||
|
||||
@[simp, grind =] theorem head?_attach {xs : List α} :
|
||||
xs.attach.head? = xs.head?.pbind (fun a h => some ⟨a, mem_of_head? h⟩) := by
|
||||
@@ -351,7 +351,7 @@ theorem getElem_attach {xs : List α} {i : Nat} (h : i < xs.attach.length) :
|
||||
xs.attach.head h = ⟨xs.head (by simpa using h), head_mem (by simpa using h)⟩ := by
|
||||
cases xs with
|
||||
| nil => simp at h
|
||||
| cons x xs => simp [head_attach, h]
|
||||
| cons x xs => simp
|
||||
|
||||
@[simp, grind =] theorem tail_pmap {P : α → Prop} {f : (a : α) → P a → β} {xs : List α}
|
||||
(H : ∀ (a : α), a ∈ xs → P a) :
|
||||
@@ -472,7 +472,7 @@ theorem attach_filterMap {l : List α} {f : α → Option β} :
|
||||
induction l with
|
||||
| nil => rfl
|
||||
| cons x xs ih =>
|
||||
simp only [filterMap_cons, attach_cons, ih, filterMap_map]
|
||||
simp only [filterMap_cons, attach_cons, filterMap_map]
|
||||
split <;> rename_i h
|
||||
· simp only [Option.pbind_eq_none_iff, reduceCtorEq, exists_false,
|
||||
or_false] at h
|
||||
@@ -554,7 +554,7 @@ theorem pmap_append' {p : α → Prop} {f : ∀ a : α, p a → β} {l₁ l₂ :
|
||||
@[simp, grind =] theorem attach_append {xs ys : List α} :
|
||||
(xs ++ ys).attach = xs.attach.map (fun ⟨x, h⟩ => ⟨x, mem_append_left ys h⟩) ++
|
||||
ys.attach.map fun ⟨x, h⟩ => ⟨x, mem_append_right xs h⟩ := by
|
||||
simp only [attach, attachWith, pmap, map_pmap, pmap_append]
|
||||
simp only [attach, attachWith, map_pmap, pmap_append]
|
||||
congr 1 <;>
|
||||
exact pmap_congr_left _ fun _ _ _ _ => rfl
|
||||
|
||||
@@ -562,7 +562,7 @@ theorem pmap_append' {p : α → Prop} {f : ∀ a : α, p a → β} {l₁ l₂ :
|
||||
{H : ∀ (a : α), a ∈ xs ++ ys → P a} :
|
||||
(xs ++ ys).attachWith P H = xs.attachWith P (fun a h => H a (mem_append_left ys h)) ++
|
||||
ys.attachWith P (fun a h => H a (mem_append_right xs h)) := by
|
||||
simp only [attachWith, attach_append, map_pmap, pmap_append]
|
||||
simp only [attachWith, pmap_append]
|
||||
|
||||
@[simp, grind =] theorem pmap_reverse {P : α → Prop} {f : (a : α) → P a → β} {xs : List α}
|
||||
(H : ∀ (a : α), a ∈ xs.reverse → P a) :
|
||||
@@ -625,7 +625,7 @@ theorem reverse_attach {xs : List α} :
|
||||
@[simp, grind =] theorem getLast_attachWith {P : α → Prop} {xs : List α}
|
||||
{H : ∀ (a : α), a ∈ xs → P a} (h : xs.attachWith P H ≠ []) :
|
||||
(xs.attachWith P H).getLast h = ⟨xs.getLast (by simpa using h), H _ (getLast_mem _)⟩ := by
|
||||
simp only [getLast_eq_head_reverse, reverse_attachWith, head_attachWith, head_map]
|
||||
simp only [getLast_eq_head_reverse, reverse_attachWith, head_attachWith]
|
||||
|
||||
@[simp, grind =]
|
||||
theorem getLast?_attach {xs : List α} :
|
||||
@@ -651,12 +651,12 @@ theorem countP_attachWith {p : α → Prop} {q : α → Bool} {l : List α} (H :
|
||||
@[simp]
|
||||
theorem count_attach [BEq α] {l : List α} {a : {x // x ∈ l}} :
|
||||
l.attach.count a = l.count ↑a :=
|
||||
Eq.trans (countP_congr fun _ _ => by simp [Subtype.ext_iff]) <| countP_attach
|
||||
Eq.trans (countP_congr fun _ _ => by simp) <| countP_attach
|
||||
|
||||
@[simp, grind =]
|
||||
theorem count_attachWith [BEq α] {p : α → Prop} {l : List α} (H : ∀ a ∈ l, p a) {a : {x // p x}} :
|
||||
(l.attachWith p H).count a = l.count ↑a :=
|
||||
Eq.trans (countP_congr fun _ _ => by simp [Subtype.ext_iff]) <| countP_attachWith _
|
||||
Eq.trans (countP_congr fun _ _ => by simp) <| countP_attachWith _
|
||||
|
||||
@[simp, grind =] theorem countP_pmap {p : α → Prop} {g : ∀ a, p a → β} {f : β → Bool} {l : List α} (H₁) :
|
||||
(l.pmap g H₁).countP f =
|
||||
@@ -717,7 +717,7 @@ def unattach {α : Type _} {p : α → Prop} (l : List { x // p x }) : List α :
|
||||
unfold unattach
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons a l ih => simp [ih, Function.comp_def]
|
||||
| cons a l ih => simp [ih]
|
||||
|
||||
@[simp] theorem getElem?_unattach {p : α → Prop} {l : List { x // p x }} (i : Nat) :
|
||||
l.unattach[i]? = l[i]?.map Subtype.val := by
|
||||
|
||||
@@ -730,9 +730,9 @@ Examples:
|
||||
-/
|
||||
@[inline] def flatMap {α : Type u} {β : Type v} (b : α → List β) (as : List α) : List β := flatten (map b as)
|
||||
|
||||
@[simp, grind] theorem flatMap_nil {f : α → List β} : List.flatMap f [] = [] := by simp [flatten, List.flatMap]
|
||||
@[simp, grind] theorem flatMap_nil {f : α → List β} : List.flatMap f [] = [] := by simp [List.flatMap]
|
||||
@[simp, grind] theorem flatMap_cons {x : α} {xs : List α} {f : α → List β} :
|
||||
List.flatMap f (x :: xs) = f x ++ List.flatMap f xs := by simp [flatten, List.flatMap]
|
||||
List.flatMap f (x :: xs) = f x ++ List.flatMap f xs := by simp [List.flatMap]
|
||||
|
||||
/-! ### replicate -/
|
||||
|
||||
@@ -753,7 +753,7 @@ def replicate : (n : Nat) → (a : α) → List α
|
||||
@[simp, grind] theorem length_replicate {n : Nat} {a : α} : (replicate n a).length = n := by
|
||||
induction n with
|
||||
| zero => simp
|
||||
| succ n ih => simp only [ih, replicate_succ, length_cons, Nat.succ_eq_add_one]
|
||||
| succ n ih => simp only [ih, replicate_succ, length_cons]
|
||||
|
||||
/-! ## Additional functions -/
|
||||
|
||||
@@ -892,7 +892,7 @@ theorem mem_of_elem_eq_true [BEq α] [LawfulBEq α] {a : α} {as : List α} : el
|
||||
| a'::as =>
|
||||
simp [elem]
|
||||
split
|
||||
next h => intros; simp [BEq.beq] at h; subst h; apply Mem.head
|
||||
next h => intros; simp at h; subst h; apply Mem.head
|
||||
next _ => intro h; exact Mem.tail _ (mem_of_elem_eq_true h)
|
||||
|
||||
theorem elem_eq_true_of_mem [BEq α] [ReflBEq α] {a : α} {as : List α} (h : a ∈ as) : elem a as = true := by
|
||||
@@ -1780,7 +1780,7 @@ where
|
||||
| a :: l, i, h =>
|
||||
if p a then
|
||||
some ⟨i, by
|
||||
simp only [Nat.add_comm _ i, ← Nat.add_assoc] at h
|
||||
simp only [Nat.add_comm _ i] at h
|
||||
exact Nat.lt_of_add_right_lt (Nat.lt_of_succ_le (Nat.le_of_eq h))⟩
|
||||
else
|
||||
go l (i + 1) (by simp at h; simpa [← Nat.add_assoc, Nat.add_right_comm] using h)
|
||||
@@ -2015,7 +2015,7 @@ def zip : List α → List β → List (Prod α β) :=
|
||||
zipWith Prod.mk
|
||||
|
||||
@[simp] theorem zip_nil_left : zip ([] : List α) (l : List β) = [] := rfl
|
||||
@[simp] theorem zip_nil_right : zip (l : List α) ([] : List β) = [] := by simp [zip, zipWith]
|
||||
@[simp] theorem zip_nil_right : zip (l : List α) ([] : List β) = [] := by simp [zip]
|
||||
@[simp] theorem zip_cons_cons : zip (a :: as) (b :: bs) = (a, b) :: zip as bs := rfl
|
||||
|
||||
/-! ### zipWithAll -/
|
||||
|
||||
@@ -276,7 +276,7 @@ theorem getElem_append_right {as bs : List α} {i : Nat} (h₁ : as.length ≤ i
|
||||
induction as generalizing i with
|
||||
| nil => trivial
|
||||
| cons a as ih =>
|
||||
cases i with simp [Nat.succ_sub_succ] <;> simp [Nat.succ_sub_succ] at h₁
|
||||
cases i with simp [Nat.succ_sub_succ] <;> simp at h₁
|
||||
| succ i => apply ih; simp [h₁]
|
||||
|
||||
@[deprecated "Deprecated without replacement." (since := "2025-02-13")]
|
||||
|
||||
@@ -86,7 +86,7 @@ theorem countP_le_length : countP p l ≤ l.length := by
|
||||
simp only [countP_eq_length_filter, filter_append, length_append]
|
||||
|
||||
@[simp] theorem countP_pos_iff {p} : 0 < countP p l ↔ ∃ a ∈ l, p a := by
|
||||
simp only [countP_eq_length_filter, length_pos_iff_exists_mem, mem_filter, exists_prop]
|
||||
simp only [countP_eq_length_filter, length_pos_iff_exists_mem, mem_filter]
|
||||
|
||||
@[simp] theorem one_le_countP_iff {p} : 1 ≤ countP p l ↔ ∃ a ∈ l, p a :=
|
||||
countP_pos_iff
|
||||
@@ -169,7 +169,7 @@ theorem length_filterMap_eq_countP {f : α → Option β} {l : List α} :
|
||||
| nil => rfl
|
||||
| cons x l ih =>
|
||||
simp only [filterMap_cons, countP_cons]
|
||||
split <;> simp [ih, *]
|
||||
split <;> simp [*]
|
||||
|
||||
theorem countP_filterMap {p : β → Bool} {f : α → Option β} {l : List α} :
|
||||
countP p (filterMap f l) = countP (fun a => ((f a).map p).getD false) l := by
|
||||
|
||||
@@ -146,7 +146,7 @@ theorem mem_of_mem_eraseP {l : List α} : a ∈ l.eraseP p → a ∈ l := (erase
|
||||
@[simp] theorem eraseP_eq_self_iff {p} {l : List α} : l.eraseP p = l ↔ ∀ a ∈ l, ¬ p a := by
|
||||
rw [← Sublist.length_eq eraseP_sublist, length_eraseP]
|
||||
split <;> rename_i h
|
||||
· simp only [any_eq_true, length_eq_zero_iff] at h
|
||||
· simp only [any_eq_true] at h
|
||||
constructor
|
||||
· intro; simp_all [Nat.sub_one_eq_self]
|
||||
· intro; obtain ⟨x, m, h⟩ := h; simp_all
|
||||
@@ -287,9 +287,9 @@ theorem eraseP_comm {l : List α} (h : ∀ a ∈ l, ¬ p a ∨ ¬ q a) :
|
||||
by_cases h₁ : p a
|
||||
· by_cases h₂ : q a
|
||||
· simp_all
|
||||
· simp [h₁, h₂, ih (fun b m => h b (mem_cons_of_mem _ m))]
|
||||
· simp [h₁, h₂]
|
||||
· by_cases h₂ : q a
|
||||
· simp [h₁, h₂, ih (fun b m => h b (mem_cons_of_mem _ m))]
|
||||
· simp [h₁, h₂]
|
||||
· simp [h₁, h₂, ih (fun b m => h b (mem_cons_of_mem _ m))]
|
||||
|
||||
theorem head_eraseP_mem {xs : List α} {p : α → Bool} (h) : (xs.eraseP p).head h ∈ xs :=
|
||||
@@ -578,7 +578,7 @@ theorem eraseIdx_eq_take_drop_succ :
|
||||
match l, i with
|
||||
| [], _
|
||||
| a::l, 0
|
||||
| a::l, i + 1 => simp [Nat.succ_inj]
|
||||
| a::l, i + 1 => simp
|
||||
|
||||
@[deprecated eraseIdx_eq_nil_iff (since := "2025-01-30")]
|
||||
abbrev eraseIdx_eq_nil := @eraseIdx_eq_nil_iff
|
||||
@@ -587,7 +587,7 @@ theorem eraseIdx_ne_nil_iff {l : List α} {i : Nat} : eraseIdx l i ≠ [] ↔ 2
|
||||
match l with
|
||||
| []
|
||||
| [a]
|
||||
| a::b::l => simp [Nat.succ_inj]
|
||||
| a::b::l => simp
|
||||
|
||||
@[deprecated eraseIdx_ne_nil_iff (since := "2025-01-30")]
|
||||
abbrev eraseIdx_ne_nil := @eraseIdx_ne_nil_iff
|
||||
|
||||
@@ -183,7 +183,7 @@ grind_pattern Sublist.findSome?_isSome => l₁ <+ l₂, l₂.findSome? f
|
||||
|
||||
theorem Sublist.findSome?_eq_none {l₁ l₂ : List α} (h : l₁ <+ l₂) :
|
||||
l₂.findSome? f = none → l₁.findSome? f = none := by
|
||||
simp only [List.findSome?_eq_none_iff, Bool.not_eq_true]
|
||||
simp only [List.findSome?_eq_none_iff]
|
||||
exact fun w x m => w x (Sublist.mem m h)
|
||||
|
||||
theorem IsPrefix.findSome?_eq_some {l₁ l₂ : List α} {f : α → Option β} (h : l₁ <+: l₂) :
|
||||
@@ -383,7 +383,7 @@ theorem find?_flatten_eq_some_iff {xs : List (List α)} {p : α → Bool} {a :
|
||||
· simpa using h₂ x (by simpa using ⟨l, ma, m⟩)
|
||||
· specialize h₁ _ mb
|
||||
simp_all
|
||||
· simp [h₁]
|
||||
· simp
|
||||
refine ⟨as, bs, ?_⟩
|
||||
refine ⟨?_, ?_, ?_⟩
|
||||
· simp_all
|
||||
@@ -592,7 +592,7 @@ theorem findIdx_eq_length {p : α → Bool} {xs : List α} :
|
||||
| cons x xs ih =>
|
||||
rw [findIdx_cons, length_cons]
|
||||
simp only [cond_eq_if]
|
||||
split <;> simp_all [Nat.succ.injEq]
|
||||
split <;> simp_all
|
||||
|
||||
theorem findIdx_eq_length_of_false {p : α → Bool} {xs : List α} (h : ∀ x ∈ xs, p x = false) :
|
||||
xs.findIdx p = xs.length := by
|
||||
@@ -737,7 +737,7 @@ theorem findIdx?_eq_none_iff {xs : List α} {p : α → Bool} :
|
||||
| nil => simp_all
|
||||
| cons x xs ih =>
|
||||
simp only [findIdx?_cons]
|
||||
split <;> simp_all [cond_eq_if]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp, grind =]
|
||||
theorem findIdx?_isSome {xs : List α} {p : α → Bool} :
|
||||
@@ -799,13 +799,13 @@ theorem findIdx?_eq_some_iff_getElem {xs : List α} {p : α → Bool} {i : Nat}
|
||||
induction xs generalizing i with
|
||||
| nil => simp
|
||||
| cons x xs ih =>
|
||||
simp only [findIdx?_cons, Nat.zero_add]
|
||||
simp only [findIdx?_cons]
|
||||
split
|
||||
· simp only [Option.some.injEq, Bool.not_eq_true, length_cons]
|
||||
cases i with
|
||||
| zero => simp_all
|
||||
| succ i =>
|
||||
simp only [Bool.not_eq_true, zero_ne_add_one, getElem_cons_succ, false_iff, not_exists,
|
||||
simp only [zero_ne_add_one, getElem_cons_succ, false_iff, not_exists,
|
||||
not_and, Classical.not_forall, Bool.not_eq_false]
|
||||
intros
|
||||
refine ⟨0, zero_lt_succ i, ‹_›⟩
|
||||
@@ -830,8 +830,8 @@ theorem of_findIdx?_eq_some {xs : List α} {p : α → Bool} (w : xs.findIdx? p
|
||||
induction xs generalizing i with
|
||||
| nil => simp_all
|
||||
| cons x xs ih =>
|
||||
simp_all only [findIdx?_cons, Nat.zero_add]
|
||||
split at w <;> cases i <;> simp_all [succ_inj]
|
||||
simp_all only [findIdx?_cons]
|
||||
split at w <;> cases i <;> simp_all
|
||||
|
||||
@[deprecated of_findIdx?_eq_some (since := "2025-02-02")]
|
||||
abbrev findIdx?_of_eq_some := @of_findIdx?_eq_some
|
||||
@@ -842,7 +842,7 @@ theorem of_findIdx?_eq_none {xs : List α} {p : α → Bool} (w : xs.findIdx? p
|
||||
induction xs generalizing i with
|
||||
| nil => simp_all
|
||||
| cons x xs ih =>
|
||||
simp_all only [Bool.not_eq_true, findIdx?_cons, Nat.zero_add]
|
||||
simp_all only [Bool.not_eq_true, findIdx?_cons]
|
||||
cases i with
|
||||
| zero =>
|
||||
split at w <;> simp_all
|
||||
@@ -888,7 +888,7 @@ theorem findIdx?_flatten {l : List (List α)} {p : α → Bool} :
|
||||
cases n with
|
||||
| zero => simp
|
||||
| succ n =>
|
||||
simp only [replicate, findIdx?_cons, Nat.zero_add, zero_lt_succ, true_and]
|
||||
simp only [replicate, findIdx?_cons, zero_lt_succ, true_and]
|
||||
split <;> simp_all
|
||||
|
||||
theorem findIdx?_eq_findSome?_zipIdx {xs : List α} {p : α → Bool} :
|
||||
@@ -899,7 +899,7 @@ theorem findIdx?_eq_findSome?_zipIdx {xs : List α} {p : α → Bool} :
|
||||
simp only [findIdx?_cons, Nat.zero_add, zipIdx]
|
||||
split
|
||||
· simp_all
|
||||
· simp_all only [zipIdx_cons, ite_false, Option.isNone_none, findSome?_cons_of_isNone, reduceCtorEq]
|
||||
· simp_all only [ite_false, Option.isNone_none, findSome?_cons_of_isNone, reduceCtorEq]
|
||||
rw [← map_snd_add_zipIdx_eq_zipIdx (n := 1) (k := 0)]
|
||||
simp [Function.comp_def, findSome?_map]
|
||||
|
||||
@@ -975,7 +975,7 @@ theorem findIdx_eq_getD_findIdx? {xs : List α} {p : α → Bool} :
|
||||
| nil => simp
|
||||
| cons x xs ih =>
|
||||
simp only [findIdx_cons, findIdx?_cons]
|
||||
split <;> simp_all [ih]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp] theorem findIdx?_subtype {p : α → Prop} {l : List { x // p x }}
|
||||
{f : { x // p x } → Bool} {g : α → Bool} (hf : ∀ x h, f ⟨x, h⟩ = g x) :
|
||||
@@ -985,7 +985,7 @@ theorem findIdx_eq_getD_findIdx? {xs : List α} {p : α → Bool} :
|
||||
| nil => simp
|
||||
| cons a l ih =>
|
||||
simp [hf, findIdx?_cons]
|
||||
split <;> simp [ih, Function.comp_def]
|
||||
split <;> simp [ih]
|
||||
|
||||
/-! ### findFinIdx? -/
|
||||
|
||||
@@ -1078,7 +1078,7 @@ theorem isNone_findFinIdx? {l : List α} {p : α → Bool} :
|
||||
{f : { x // p x } → Bool} {g : α → Bool} (hf : ∀ x h, f ⟨x, h⟩ = g x) :
|
||||
l.findFinIdx? f = (l.unattach.findFinIdx? g).map (fun i => i.cast (by simp)) := by
|
||||
induction l with
|
||||
| nil => simp [unattach]
|
||||
| nil => simp
|
||||
| cons a l ih =>
|
||||
simp [hf, findFinIdx?_cons]
|
||||
split <;> simp [ih, Function.comp_def]
|
||||
@@ -1136,7 +1136,7 @@ theorem idxOf_lt_length_of_mem [BEq α] [EquivBEq α] {l : List α} (h : a ∈ l
|
||||
simp only [mem_cons] at h
|
||||
obtain rfl | h := h
|
||||
· simp
|
||||
· simp only [idxOf_cons, cond_eq_if, beq_iff_eq, length_cons]
|
||||
· simp only [idxOf_cons, cond_eq_if, length_cons]
|
||||
specialize ih h
|
||||
split
|
||||
· exact zero_lt_succ xs.length
|
||||
|
||||
@@ -234,7 +234,7 @@ Examples:
|
||||
intro xs; induction xs with intro acc
|
||||
| nil => simp [takeWhile, takeWhileTR.go]
|
||||
| cons x xs IH =>
|
||||
simp only [takeWhileTR.go, Array.toListImpl_eq, takeWhile]
|
||||
simp only [takeWhileTR.go, takeWhile]
|
||||
split
|
||||
· intro h; rw [IH] <;> simp_all
|
||||
· simp [*]
|
||||
|
||||
@@ -255,7 +255,7 @@ theorem getElem?_cons_zero {l : List α} : (a::l)[0]? = some a := rfl
|
||||
|
||||
@[grind =]
|
||||
theorem getElem?_cons : (a :: l)[i]? = if i = 0 then some a else l[i-1]? := by
|
||||
cases i <;> simp [getElem?_cons_zero]
|
||||
cases i <;> simp
|
||||
|
||||
theorem getElem?_eq_some_iff {l : List α} : l[i]? = some a ↔ ∃ h : i < l.length, l[i] = a :=
|
||||
match l with
|
||||
@@ -287,16 +287,16 @@ theorem getElem_eq_iff {l : List α} {i : Nat} (h : i < l.length) : l[i] = x ↔
|
||||
exact ⟨fun w => ⟨h, w⟩, fun h => h.2⟩
|
||||
|
||||
theorem getElem_eq_getElem?_get {l : List α} {i : Nat} (h : i < l.length) :
|
||||
l[i] = l[i]?.get (by simp [getElem?_eq_getElem, h]) := by
|
||||
simp [getElem_eq_iff]
|
||||
l[i] = l[i]?.get (by simp [h]) := by
|
||||
simp
|
||||
|
||||
theorem getD_getElem? {l : List α} {i : Nat} {d : α} :
|
||||
l[i]?.getD d = if p : i < l.length then l[i]'p else d := by
|
||||
if h : i < l.length then
|
||||
simp [h, getElem?_def]
|
||||
simp [h]
|
||||
else
|
||||
have p : i ≥ l.length := Nat.le_of_not_gt h
|
||||
simp [getElem?_eq_none p, h]
|
||||
simp [h]
|
||||
|
||||
@[simp] theorem getElem_singleton {a : α} {i : Nat} (h : i < 1) : [a][i] = a := by
|
||||
match i, h with
|
||||
@@ -332,7 +332,7 @@ theorem ext_getElem {l₁ l₂ : List α} (hl : length l₁ = length l₂)
|
||||
(h : ∀ (i : Nat) (h₁ : i < l₁.length) (h₂ : i < l₂.length), l₁[i]'h₁ = l₂[i]'h₂) : l₁ = l₂ :=
|
||||
ext_getElem? fun n =>
|
||||
if h₁ : n < length l₁ then by
|
||||
simp_all [getElem?_eq_getElem]
|
||||
simp_all
|
||||
else by
|
||||
have h₁ := Nat.le_of_not_lt h₁
|
||||
rw [getElem?_eq_none h₁, getElem?_eq_none]; rwa [← hl]
|
||||
@@ -636,7 +636,7 @@ theorem all_bne' [BEq α] [PartialEquivBEq α] {l : List α} :
|
||||
|
||||
@[simp] theorem getElem?_set_self {l : List α} {i : Nat} {a : α} (h : i < l.length) :
|
||||
(l.set i a)[i]? = some a := by
|
||||
simp_all [getElem?_eq_some_iff]
|
||||
simp_all
|
||||
|
||||
/-- This differs from `getElem?_set_self` by monadically mapping `Function.const _ a` over the `Option`
|
||||
returned by `l[i]?`. -/
|
||||
@@ -679,7 +679,7 @@ theorem getElem?_set_self' {l : List α} {i : Nat} {a : α} :
|
||||
subst h
|
||||
rw [if_pos rfl]
|
||||
split <;> rename_i h
|
||||
· simp only [getElem?_set_self (by simpa), h]
|
||||
· simp only [getElem?_set_self (by simpa)]
|
||||
· simp_all
|
||||
else
|
||||
simp [h]
|
||||
@@ -1276,9 +1276,9 @@ theorem length_filter_le (p : α → Bool) (l : List α) :
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons a l ih =>
|
||||
simp only [filter_cons, length_cons, succ_eq_add_one]
|
||||
simp only [filter_cons, length_cons]
|
||||
split
|
||||
· simp only [length_cons, succ_eq_add_one]
|
||||
· simp only [length_cons]
|
||||
exact Nat.succ_le_succ ih
|
||||
· exact Nat.le_trans ih (Nat.le_add_right _ _)
|
||||
|
||||
@@ -1296,7 +1296,7 @@ theorem length_filter_eq_length_iff {l} : (filter p l).length = l.length ↔ ∀
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons a l ih =>
|
||||
simp only [filter_cons, length_cons, succ_eq_add_one, mem_cons, forall_eq_or_imp]
|
||||
simp only [filter_cons, length_cons, mem_cons, forall_eq_or_imp]
|
||||
split <;> rename_i h
|
||||
· simp_all [Nat.add_one_inj] -- Why does the simproc not fire here?
|
||||
· have := Nat.ne_of_lt (Nat.lt_succ.mpr (length_filter_le p l))
|
||||
@@ -1388,7 +1388,7 @@ theorem filter_eq_cons_iff {l} {a} {as} :
|
||||
· obtain ⟨l₁, l₂, rfl, w₁, w₂, w₃⟩ := ih h
|
||||
exact ⟨x :: l₁, l₂, by simp_all⟩
|
||||
· rintro ⟨l₁, l₂, rfl, h₁, h, h₂⟩
|
||||
simp [h₂, filter_cons, filter_eq_nil_iff.mpr h₁, h]
|
||||
simp [h₂, filter_eq_nil_iff.mpr h₁, h]
|
||||
|
||||
theorem filter_congr {p q : α → Bool} :
|
||||
∀ {l : List α}, (∀ x ∈ l, p x = q x) → filter p l = filter q l
|
||||
@@ -1404,7 +1404,7 @@ theorem head_filter_of_pos {p : α → Bool} {l : List α} (w : l ≠ []) (h : p
|
||||
| nil => simp
|
||||
| cons =>
|
||||
simp only [head_cons] at h
|
||||
simp [filter_cons, h]
|
||||
simp [h]
|
||||
|
||||
@[simp] theorem filter_sublist {p : α → Bool} : ∀ {l : List α}, filter p l <+ l
|
||||
| [] => .slnil
|
||||
@@ -1420,7 +1420,7 @@ theorem head_filter_of_pos {p : α → Bool} {l : List α} (w : l ≠ []) (h : p
|
||||
|
||||
@[simp]
|
||||
theorem filterMap_eq_map {f : α → β} : filterMap (some ∘ f) = map f := by
|
||||
funext l; induction l <;> simp [*, filterMap_cons]
|
||||
funext l; induction l <;> simp [*]
|
||||
|
||||
/-- Variant of `filterMap_eq_map` with `some ∘ f` expanded out to a lambda. -/
|
||||
@[simp]
|
||||
@@ -1453,7 +1453,7 @@ theorem filterMap_length_eq_length {l} :
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons a l ih =>
|
||||
simp only [filterMap_cons, length_cons, succ_eq_add_one, mem_cons, forall_eq_or_imp]
|
||||
simp only [filterMap_cons, length_cons, mem_cons, forall_eq_or_imp]
|
||||
split <;> rename_i h
|
||||
· have := Nat.ne_of_lt (Nat.lt_succ.mpr (length_filterMap_le f l))
|
||||
simp_all
|
||||
@@ -1465,7 +1465,7 @@ theorem filterMap_eq_filter {p : α → Bool} :
|
||||
funext l
|
||||
induction l with
|
||||
| nil => rfl
|
||||
| cons a l IH => by_cases pa : p a <;> simp [filterMap_cons, Option.guard, pa, ← IH]
|
||||
| cons a l IH => by_cases pa : p a <;> simp [Option.guard, pa, ← IH]
|
||||
|
||||
@[grind]
|
||||
theorem filterMap_filterMap {f : α → Option β} {g : β → Option γ} {l : List α} :
|
||||
@@ -1512,7 +1512,7 @@ theorem forall_mem_filterMap {f : α → Option β} {l : List α} {P : β → Pr
|
||||
|
||||
theorem map_filterMap_of_inv
|
||||
{f : α → Option β} {g : β → α} (H : ∀ x : α, (f x).map g = some x) {l : List α} :
|
||||
map g (filterMap f l) = l := by simp only [map_filterMap, H, filterMap_some, id]
|
||||
map g (filterMap f l) = l := by simp only [map_filterMap, H, filterMap_some]
|
||||
|
||||
theorem head_filterMap_of_eq_some {f : α → Option β} {l : List α} (w : l ≠ []) {b : β} (h : f (l.head w) = some b) :
|
||||
(filterMap f l).head ((ne_nil_of_mem (mem_filterMap.2 ⟨_, head_mem w, h⟩))) =
|
||||
@@ -1521,7 +1521,7 @@ theorem head_filterMap_of_eq_some {f : α → Option β} {l : List α} (w : l
|
||||
| nil => simp at w
|
||||
| cons a l =>
|
||||
simp only [head_cons] at h
|
||||
simp [filterMap_cons, h]
|
||||
simp [h]
|
||||
|
||||
@[grind →]
|
||||
theorem forall_none_of_filterMap_eq_nil (h : filterMap f xs = []) : ∀ x ∈ xs, f x = none := by
|
||||
@@ -1613,7 +1613,7 @@ theorem getElem?_append_left {l₁ l₂ : List α} {i : Nat} (hn : i < l₁.leng
|
||||
(l₁ ++ l₂)[i]? = l₁[i]? := by
|
||||
have hn' : i < (l₁ ++ l₂).length := Nat.lt_of_lt_of_le hn <|
|
||||
length_append .. ▸ Nat.le_add_right ..
|
||||
simp_all [getElem?_eq_getElem, getElem_append]
|
||||
simp_all
|
||||
|
||||
theorem getElem?_append_right : ∀ {l₁ l₂ : List α} {i : Nat}, l₁.length ≤ i →
|
||||
(l₁ ++ l₂)[i]? = l₂[i - l₁.length]?
|
||||
@@ -1817,10 +1817,10 @@ theorem filterMap_eq_append_iff {f : α → Option β} :
|
||||
intro h
|
||||
rcases cons_eq_append_iff.mp h with (⟨rfl, rfl⟩ | ⟨_, ⟨rfl, h⟩⟩)
|
||||
· refine ⟨[], x :: l, ?_⟩
|
||||
simp [filterMap_cons, w]
|
||||
simp [w]
|
||||
· obtain ⟨l₁, l₂, rfl, rfl, rfl⟩ := ih ‹_›
|
||||
refine ⟨x :: l₁, l₂, ?_⟩
|
||||
simp [filterMap_cons, w]
|
||||
simp [w]
|
||||
· rintro ⟨l₁, l₂, rfl, rfl, rfl⟩
|
||||
simp
|
||||
|
||||
@@ -1885,7 +1885,7 @@ theorem append_concat {a : α} {l₁ l₂ : List α} : l₁ ++ concat l₂ a = c
|
||||
theorem map_concat {f : α → β} {a : α} {l : List α} : map f (concat l a) = concat (map f l) (f a) := by
|
||||
induction l with
|
||||
| nil => rfl
|
||||
| cons x xs ih => simp [ih]
|
||||
| cons x xs ih => simp
|
||||
|
||||
theorem eq_nil_or_concat : ∀ l : List α, l = [] ∨ ∃ l' b, l = concat l' b
|
||||
| [] => .inl rfl
|
||||
@@ -2191,7 +2191,7 @@ theorem forall_mem_replicate {p : α → Prop} {a : α} {n} :
|
||||
· rw [getElem?_eq_none (by simpa using h), if_neg h]
|
||||
|
||||
@[simp] theorem getElem?_replicate_of_lt {n : Nat} {i : Nat} (h : i < n) : (replicate n a)[i]? = some a := by
|
||||
simp [getElem?_replicate, h]
|
||||
simp [h]
|
||||
|
||||
@[grind] theorem head?_replicate {a : α} {n : Nat} : (replicate n a).head? = if n = 0 then none else some a := by
|
||||
cases n <;> simp [replicate_succ]
|
||||
@@ -2329,8 +2329,8 @@ theorem filterMap_replicate_of_some {f : α → Option β} (h : f a = some b) :
|
||||
induction n with
|
||||
| zero => simp
|
||||
| succ n ih =>
|
||||
simp only [replicate_succ, flatten_cons, ih, replicate_append_replicate, replicate_inj, or_true,
|
||||
and_true, add_one_mul, Nat.add_comm]
|
||||
simp only [replicate_succ, flatten_cons, ih, replicate_append_replicate,
|
||||
add_one_mul, Nat.add_comm]
|
||||
|
||||
theorem flatMap_replicate {β} {f : α → List β} : (replicate n a).flatMap f = (replicate n (f a)).flatten := by
|
||||
induction n with
|
||||
@@ -2413,7 +2413,7 @@ theorem reverse_ne_nil_iff {xs : List α} : xs.reverse ≠ [] ↔ xs ≠ [] :=
|
||||
theorem getElem?_reverse' : ∀ {l : List α} {i j}, i + j + 1 = length l →
|
||||
l.reverse[i]? = l[j]?
|
||||
| [], _, _, _ => rfl
|
||||
| a::l, i, 0, h => by simp [Nat.succ.injEq] at h; simp [h, getElem?_append_right, Nat.succ.injEq]
|
||||
| a::l, i, 0, h => by simp [Nat.succ.injEq] at h; simp [h]
|
||||
| a::l, i, j+1, h => by
|
||||
have := Nat.succ.inj h; simp at this ⊢
|
||||
rw [getElem?_append_left, getElem?_reverse' this]
|
||||
@@ -2649,7 +2649,7 @@ theorem foldl_map_hom {g : α → β} {f : α → α → α} {f' : β → β →
|
||||
(l.map g).foldl f' (g a) = g (l.foldl f a) := by
|
||||
induction l generalizing a
|
||||
· simp
|
||||
· simp [*, h]
|
||||
· simp [*]
|
||||
|
||||
@[deprecated foldl_map_hom (since := "2025-01-20")] abbrev foldl_map' := @foldl_map_hom
|
||||
|
||||
@@ -2658,7 +2658,7 @@ theorem foldr_map_hom {g : α → β} {f : α → α → α} {f' : β → β →
|
||||
(l.map g).foldr f' (g a) = g (l.foldr f a) := by
|
||||
induction l generalizing a
|
||||
· simp
|
||||
· simp [*, h]
|
||||
· simp [*]
|
||||
|
||||
@[deprecated foldr_map_hom (since := "2025-01-20")] abbrev foldr_map' := @foldr_map_hom
|
||||
|
||||
@@ -2847,7 +2847,7 @@ theorem foldr_rel {l : List α} {f : α → β → β} {g : α → γ → γ} {a
|
||||
by_cases h' : l = []
|
||||
· simp_all
|
||||
· simp only [head_eq_iff_head?_eq_some, head?_reverse] at ih
|
||||
simp [ih, h, h', getLast_cons, head_eq_iff_head?_eq_some]
|
||||
simp [ih, h', getLast_cons, head_eq_iff_head?_eq_some]
|
||||
|
||||
theorem getLast_eq_head_reverse {l : List α} (h : l ≠ []) :
|
||||
l.getLast h = l.reverse.head (by simp_all) := by
|
||||
@@ -3398,14 +3398,14 @@ theorem replace_take {l : List α} {i : Nat} :
|
||||
| nil => simp
|
||||
| cons x xs ih =>
|
||||
cases i with
|
||||
| zero => simp [ih]
|
||||
| zero => simp
|
||||
| succ i =>
|
||||
simp only [replace_cons, take_succ_cons]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp] theorem replace_replicate_self [LawfulBEq α] {a : α} (h : 0 < n) :
|
||||
(replicate n a).replace a b = b :: replicate (n - 1) a := by
|
||||
cases n <;> simp_all [replicate_succ, replace_cons]
|
||||
cases n <;> simp_all [replicate_succ]
|
||||
|
||||
@[simp] theorem replace_replicate_ne [LawfulBEq α] {a b c : α} (h : !b == a) :
|
||||
(replicate n a).replace b c = replicate n a := by
|
||||
@@ -3507,11 +3507,11 @@ theorem getElem?_insert_succ {l : List α} {a : α} {i : Nat} :
|
||||
apply Option.some.inj
|
||||
rw [← getElem?_eq_getElem, getElem?_insert]
|
||||
split
|
||||
· simp [getElem?_eq_getElem, h]
|
||||
· simp [h]
|
||||
· split
|
||||
· rfl
|
||||
· have h' : i - 1 < l.length := Nat.lt_of_le_of_lt (Nat.pred_le _) h
|
||||
simp [getElem?_eq_getElem, h']
|
||||
simp [h']
|
||||
|
||||
theorem head?_insert {l : List α} {a : α} :
|
||||
(l.insert a).head? = some (if h : a ∈ l then l.head (ne_nil_of_mem h) else a) := by
|
||||
@@ -3532,7 +3532,7 @@ theorem head_insert {l : List α} {a : α} (w) :
|
||||
|
||||
theorem insert_append_of_mem_left {l₁ l₂ : List α} (h : a ∈ l₂) :
|
||||
(l₁ ++ l₂).insert a = l₁ ++ l₂ := by
|
||||
simp [insert_append, h]
|
||||
simp [h]
|
||||
|
||||
theorem insert_append_of_not_mem_left {l₁ l₂ : List α} (h : ¬ a ∈ l₂) :
|
||||
(l₁ ++ l₂).insert a = l₁.insert a ++ l₂ := by
|
||||
@@ -3693,7 +3693,7 @@ theorem getElem!_of_getElem? [Inhabited α] : ∀ {l : List α} {i : Nat}, l[i]?
|
||||
rw [getElem!_pos] <;> simp_all
|
||||
| _::l, _+1, e => by
|
||||
simp at e
|
||||
simp_all [getElem!_of_getElem? (l := l) e]
|
||||
simp_all
|
||||
|
||||
theorem ext_get {l₁ l₂ : List α} (hl : length l₁ = length l₂)
|
||||
(h : ∀ n h₁ h₂, get l₁ ⟨n, h₁⟩ = get l₂ ⟨n, h₂⟩) : l₁ = l₂ :=
|
||||
|
||||
@@ -218,8 +218,8 @@ theorem mapFinIdx_eq_cons_iff {l : List α} {b : β} {f : (i : Nat) → α → (
|
||||
cases l with
|
||||
| nil => simp
|
||||
| cons x l' =>
|
||||
simp only [mapFinIdx_cons, cons.injEq, length_cons, Fin.zero_eta, Fin.cast_succ_eq,
|
||||
exists_and_left]
|
||||
simp only [mapFinIdx_cons, cons.injEq,
|
||||
]
|
||||
constructor
|
||||
· rintro ⟨rfl, rfl⟩
|
||||
refine ⟨x, l', ⟨rfl, rfl⟩, by simp⟩
|
||||
@@ -267,7 +267,7 @@ theorem mapFinIdx_eq_append_iff {l : List α} {f : (i : Nat) → α → (h : i <
|
||||
· simp
|
||||
omega
|
||||
· intro i hi₁ hi₂
|
||||
simp only [getElem_mapFinIdx, getElem_take]
|
||||
simp only [getElem_mapFinIdx]
|
||||
simp only [length_take, getElem_drop]
|
||||
have : l₁.length ≤ l.length := by omega
|
||||
simp only [Nat.min_eq_left this, Nat.add_comm]
|
||||
@@ -286,7 +286,7 @@ theorem mapFinIdx_eq_append_iff {l : List α} {f : (i : Nat) → α → (h : i <
|
||||
theorem mapFinIdx_eq_mapFinIdx_iff {l : List α} {f g : (i : Nat) → α → (h : i < l.length) → β} :
|
||||
l.mapFinIdx f = l.mapFinIdx g ↔ ∀ (i : Nat) (h : i < l.length), f i l[i] h = g i l[i] h := by
|
||||
rw [eq_comm, mapFinIdx_eq_iff]
|
||||
simp [Fin.forall_iff]
|
||||
simp
|
||||
|
||||
@[simp, grind =] theorem mapFinIdx_mapFinIdx {l : List α}
|
||||
{f : (i : Nat) → α → (h : i < l.length) → β}
|
||||
@@ -341,7 +341,7 @@ theorem getElem?_mapIdx_go : ∀ {l : List α} {acc : Array β} {i : Nat},
|
||||
(mapIdx.go f l acc)[i]? =
|
||||
if h : i < acc.size then some acc[i] else Option.map (f i) l[i - acc.size]?
|
||||
| [], acc, i => by
|
||||
simp only [mapIdx.go, Array.toListImpl_eq, getElem?_def, Array.length_toList,
|
||||
simp only [mapIdx.go, getElem?_def, Array.length_toList,
|
||||
← Array.getElem_toList, length_nil, Nat.not_lt_zero, ↓reduceDIte, Option.map_none]
|
||||
| a :: l, acc, i => by
|
||||
rw [mapIdx.go, getElem?_mapIdx_go]
|
||||
@@ -524,7 +524,7 @@ theorem mapIdx_eq_replicate_iff {l : List α} {f : Nat → α → β} {b : β} :
|
||||
simp [mapIdx_eq_iff]
|
||||
intro i
|
||||
by_cases h : i < l.length
|
||||
· simp [getElem?_reverse, h]
|
||||
· simp [h]
|
||||
congr
|
||||
omega
|
||||
· simp at h
|
||||
|
||||
@@ -90,8 +90,8 @@ theorem foldlM_cons_eq_append [Monad m] [LawfulMonad m] {f : α → m β} {as :
|
||||
induction as generalizing b bs with
|
||||
| nil => simp
|
||||
| cons a as ih =>
|
||||
simp only [bind_pure_comp] at ih
|
||||
simp [ih, _root_.map_bind, Functor.map_map, Function.comp_def]
|
||||
simp only at ih
|
||||
simp [ih, _root_.map_bind, Functor.map_map]
|
||||
|
||||
theorem mapM_eq_reverse_foldlM_cons [Monad m] [LawfulMonad m] {f : α → m β} {l : List α} :
|
||||
mapM f l = reverse <$> (l.foldlM (fun acc a => (· :: acc) <$> f a) []) := by
|
||||
@@ -99,8 +99,8 @@ theorem mapM_eq_reverse_foldlM_cons [Monad m] [LawfulMonad m] {f : α → m β}
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons a as ih =>
|
||||
simp only [mapM'_cons, ih, bind_map_left, foldlM_cons, LawfulMonad.bind_assoc, pure_bind,
|
||||
foldlM_cons_eq_append, _root_.map_bind, Functor.map_map, Function.comp_def, reverse_append,
|
||||
simp only [mapM'_cons, ih, bind_map_left, foldlM_cons,
|
||||
foldlM_cons_eq_append, _root_.map_bind, Functor.map_map, reverse_append,
|
||||
reverse_cons, reverse_nil, nil_append, singleton_append]
|
||||
simp [bind_pure_comp]
|
||||
|
||||
@@ -144,7 +144,7 @@ theorem flatMapM_loop_eq [Monad m] [LawfulMonad m] {f : α → m (List β)} {l :
|
||||
induction l generalizing acc with
|
||||
| nil => simp [flatMapM.loop]
|
||||
| cons a l ih =>
|
||||
simp only [flatMapM.loop, append_nil, _root_.map_bind]
|
||||
simp only [flatMapM.loop, _root_.map_bind]
|
||||
congr
|
||||
funext bs
|
||||
rw [ih, ih (acc := [bs])]
|
||||
@@ -381,7 +381,7 @@ theorem forIn_eq_foldlM [Monad m] [LawfulMonad m]
|
||||
induction l generalizing init with
|
||||
| nil => simp
|
||||
| cons a as ih =>
|
||||
simp only [foldlM_cons, bind_pure_comp, forIn_cons, _root_.map_bind]
|
||||
simp only [foldlM_cons, forIn_cons, _root_.map_bind]
|
||||
congr 1
|
||||
funext x
|
||||
match x with
|
||||
@@ -444,7 +444,7 @@ theorem allM_eq_not_anyM_not [Monad m] [LawfulMonad m] {p : α → m Bool} {as :
|
||||
induction as with
|
||||
| nil => simp
|
||||
| cons a as ih =>
|
||||
simp only [anyM, ih, pure_bind, all_cons]
|
||||
simp only [anyM, ih, pure_bind]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp] theorem allM_pure [Monad m] [LawfulMonad m] {p : α → Bool} {as : List α} :
|
||||
@@ -486,7 +486,7 @@ and simplifies these to the function directly taking the value.
|
||||
induction l generalizing x with
|
||||
| nil => simp
|
||||
| cons a l ih =>
|
||||
simp [ih, hf, foldrM_cons]
|
||||
simp [ih, foldrM_cons]
|
||||
congr
|
||||
funext b
|
||||
simp [hf]
|
||||
|
||||
@@ -68,7 +68,7 @@ theorem length_filterMap_pos_iff {xs : List α} {f : α → Option β} :
|
||||
| cons x xs ih =>
|
||||
simp only [filterMap, mem_cons, exists_prop, exists_eq_or_imp]
|
||||
split
|
||||
· simp_all [ih]
|
||||
· simp_all
|
||||
· simp_all
|
||||
|
||||
@[simp]
|
||||
@@ -116,7 +116,7 @@ section intersperse
|
||||
variable {l : List α} {sep : α} {i : Nat}
|
||||
|
||||
@[simp, grind =] theorem length_intersperse : (l.intersperse sep).length = 2 * l.length - 1 := by
|
||||
fun_induction intersperse <;> simp only [intersperse, length_cons, length_nil] at *
|
||||
fun_induction intersperse <;> simp only [length_cons, length_nil] at *
|
||||
rename_i h _
|
||||
have := length_pos_iff.mpr h
|
||||
omega
|
||||
@@ -194,7 +194,7 @@ theorem mem_eraseIdx_iff_getElem {x : α} :
|
||||
| a::l, 0 => by simp [mem_iff_getElem, Nat.succ_lt_succ_iff]
|
||||
| a::l, k+1 => by
|
||||
rw [← Nat.or_exists_add_one]
|
||||
simp [mem_eraseIdx_iff_getElem, @eq_comm _ a, succ_inj, Nat.succ_lt_succ_iff]
|
||||
simp [mem_eraseIdx_iff_getElem, @eq_comm _ a, Nat.succ_lt_succ_iff]
|
||||
|
||||
theorem mem_eraseIdx_iff_getElem? {x : α} {l} {k} : x ∈ eraseIdx l k ↔ ∃ i ≠ k, l[i]? = some x := by
|
||||
simp only [mem_eraseIdx_iff_getElem, getElem_eq_iff, exists_and_left]
|
||||
|
||||
@@ -45,7 +45,7 @@ theorem countP_replace [BEq α] [LawfulBEq α] {a b : α} {l : List α} {p : α
|
||||
simp [replace_cons]
|
||||
split <;> rename_i h
|
||||
· simp at h
|
||||
simp [h, ih, countP_cons]
|
||||
simp [h, countP_cons]
|
||||
omega
|
||||
· simp only [beq_eq_false_iff_ne, ne_eq] at h
|
||||
simp only [countP_cons, ih, contains_eq_mem, decide_eq_true_eq, mem_cons, h, false_or]
|
||||
@@ -75,12 +75,12 @@ theorem count_replace [BEq α] [LawfulBEq α] {a b c : α} {l : List α} :
|
||||
· have := List.count_pos_iff.mpr (h' ▸ h)
|
||||
omega
|
||||
· rfl
|
||||
· simp [h']
|
||||
· simp
|
||||
· rw [count_cons]
|
||||
split <;> rename_i h'
|
||||
· simp only [beq_iff_eq] at h'
|
||||
rw [count_eq_zero.mpr (h' ▸ h)]
|
||||
simp [h']
|
||||
simp
|
||||
· simp
|
||||
|
||||
/--
|
||||
|
||||
@@ -29,7 +29,7 @@ theorem getElem?_eraseIdx {l : List α} {i : Nat} {j : Nat} :
|
||||
· simp only [length_take, Nat.min_def, Nat.not_lt] at h
|
||||
split at h
|
||||
· omega
|
||||
· simp_all [getElem?_eq_none]
|
||||
· simp_all
|
||||
omega
|
||||
· simp only [length_take]
|
||||
simp only [length_take, Nat.min_def, Nat.not_lt] at h
|
||||
@@ -46,7 +46,7 @@ theorem getElem?_eraseIdx_of_lt {l : List α} {i : Nat} {j : Nat} (h : j < i) :
|
||||
theorem getElem?_eraseIdx_of_ge {l : List α} {i : Nat} {j : Nat} (h : i ≤ j) :
|
||||
(l.eraseIdx i)[j]? = l[j + 1]? := by
|
||||
rw [getElem?_eraseIdx]
|
||||
simp only [dite_eq_ite, ite_eq_right_iff]
|
||||
simp only [ite_eq_right_iff]
|
||||
intro h'
|
||||
omega
|
||||
|
||||
|
||||
@@ -172,12 +172,12 @@ theorem modifyHead_eq_modify_zero (f : α → α) (l : List α) :
|
||||
∀ i (l : List α) j, (l.modify i f)[j]? = (fun a => if i = j then f a else a) <$> l[j]?
|
||||
| n, l, 0 => by cases l <;> cases n <;> simp
|
||||
| n, [], _+1 => by cases n <;> rfl
|
||||
| 0, _ :: l, j+1 => by cases h : l[j]? <;> simp [h, modify, j.succ_ne_zero.symm]
|
||||
| 0, _ :: l, j+1 => by cases h : l[j]? <;> simp [h, modify]
|
||||
| i+1, a :: l, j+1 => by
|
||||
simp only [modify_succ_cons, getElem?_cons_succ, Nat.reduceEqDiff, Option.map_eq_map]
|
||||
refine (getElem?_modify f i l j).trans ?_
|
||||
cases h' : l[j]? <;> by_cases h : i = j <;>
|
||||
simp [h, if_pos, if_neg, Option.map, mt Nat.succ.inj, not_false_iff, h']
|
||||
simp [h, Option.map]
|
||||
|
||||
@[simp, grind =] theorem length_modify (f : α → α) : ∀ (l : List α) i, (l.modify i f).length = l.length :=
|
||||
length_modifyTailIdx _ fun l => by cases l <;> rfl
|
||||
@@ -226,7 +226,7 @@ theorem modify_modify_ne (f g : α → α) {i j} (l : List α) (h : i ≠ j) :
|
||||
apply ext_getElem
|
||||
· simp
|
||||
· intro m' h₁ h₂
|
||||
simp only [getElem_modify, getElem_modify_ne, h₂]
|
||||
simp only [getElem_modify]
|
||||
split <;> split <;> first | rfl | omega
|
||||
|
||||
theorem modify_eq_set [Inhabited α] (f : α → α) (i) (l : List α) :
|
||||
@@ -234,7 +234,7 @@ theorem modify_eq_set [Inhabited α] (f : α → α) (i) (l : List α) :
|
||||
apply ext_getElem
|
||||
· simp
|
||||
· intro m h₁ h₂
|
||||
simp [getElem_modify, getElem_set, h₂]
|
||||
simp [getElem_modify, getElem_set]
|
||||
split <;> rename_i h
|
||||
· subst h
|
||||
simp only [length_modify] at h₁
|
||||
@@ -287,7 +287,7 @@ theorem drop_modify_of_ge (f : α → α) (i j) (l : List α) (h : i ≥ j) :
|
||||
apply ext_getElem
|
||||
· simp
|
||||
· intro m' h₁ h₂
|
||||
simp [getElem_drop, getElem_modify, ite_eq_right_iff]
|
||||
simp [getElem_drop, getElem_modify]
|
||||
split <;> split <;> first | rfl | omega
|
||||
|
||||
theorem eraseIdx_modify_of_eq (f : α → α) (i) (l : List α) :
|
||||
|
||||
@@ -508,7 +508,7 @@ theorem zipIdx_eq_append_iff {l : List α} {k : Nat} :
|
||||
· rintro ⟨l₁', l₂', rfl, rfl, rfl⟩
|
||||
simp only [zipIdx_eq_zip_range']
|
||||
refine ⟨l₁', l₂', range' k l₁'.length, range' (k + l₁'.length) l₂'.length, ?_⟩
|
||||
simp [Nat.add_comm]
|
||||
simp
|
||||
|
||||
/-! ### enumFrom -/
|
||||
|
||||
@@ -635,7 +635,7 @@ theorem enumFrom_eq_append_iff {l : List α} {n : Nat} :
|
||||
· rintro ⟨l₁', l₂', rfl, rfl, rfl⟩
|
||||
simp only [enumFrom_eq_zip_range']
|
||||
refine ⟨range' n l₁'.length, range' (n + l₁'.length) l₂'.length, l₁', l₂', ?_⟩
|
||||
simp [Nat.add_comm]
|
||||
simp
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ theorem suffix_iff_eq_drop : l₁ <:+ l₂ ↔ l₁ = drop (length l₂ - length
|
||||
xs.take i <+: xs.take j ↔ i ≤ j := by
|
||||
simp only [prefix_iff_eq_take, length_take]
|
||||
induction i generalizing xs j with
|
||||
| zero => simp [Nat.min_eq_left, eq_self_iff_true, Nat.zero_le, take]
|
||||
| zero => simp [Nat.min_eq_left, Nat.zero_le, take]
|
||||
| succ i IH =>
|
||||
cases xs with
|
||||
| nil => simp_all
|
||||
@@ -150,7 +150,7 @@ theorem suffix_iff_eq_drop : l₁ <:+ l₂ ↔ l₁ = drop (length l₂ - length
|
||||
| zero =>
|
||||
simp
|
||||
| succ j =>
|
||||
simp only [length_cons, Nat.succ_eq_add_one, Nat.add_lt_add_iff_right] at hm
|
||||
simp only [length_cons, Nat.add_lt_add_iff_right] at hm
|
||||
simp [← @IH j xs hm, Nat.min_eq_left, Nat.le_of_lt hm]
|
||||
|
||||
@[simp] theorem append_left_sublist_self {xs : List α} (ys : List α) : xs ++ ys <+ ys ↔ xs = [] := by
|
||||
@@ -193,7 +193,7 @@ theorem append_sublist_of_sublist_right {xs ys zs : List α} (h : zs <+ ys) :
|
||||
have hl' := h'.length_le
|
||||
simp only [length_append] at hl'
|
||||
have : xs.length = 0 := by omega
|
||||
simp_all only [Nat.zero_add, length_eq_zero_iff, true_and, append_nil]
|
||||
simp_all only [Nat.zero_add, length_eq_zero_iff, true_and]
|
||||
exact Sublist.eq_of_length_le h' hl
|
||||
· rintro ⟨rfl, rfl⟩
|
||||
simp
|
||||
|
||||
@@ -28,8 +28,8 @@ open Nat
|
||||
/-! ### take -/
|
||||
|
||||
@[simp, grind =] theorem length_take : ∀ {i : Nat} {l : List α}, (take i l).length = min i l.length
|
||||
| 0, l => by simp [Nat.zero_min]
|
||||
| succ n, [] => by simp [Nat.min_zero]
|
||||
| 0, l => by simp
|
||||
| succ n, [] => by simp
|
||||
| succ n, _ :: l => by simp [Nat.succ_min_succ, length_take]
|
||||
|
||||
theorem length_take_le (i) (l : List α) : length (take i l) ≤ i := by simp [Nat.min_le_left]
|
||||
@@ -119,8 +119,8 @@ theorem take_set_of_le {a : α} {i j : Nat} {l : List α} (h : j ≤ i) :
|
||||
abbrev take_set_of_lt := @take_set_of_le
|
||||
|
||||
@[simp, grind =] theorem take_replicate {a : α} : ∀ {i n : Nat}, take i (replicate n a) = replicate (min i n) a
|
||||
| n, 0 => by simp [Nat.min_zero]
|
||||
| 0, m => by simp [Nat.zero_min]
|
||||
| n, 0 => by simp
|
||||
| 0, m => by simp
|
||||
| succ n, succ m => by simp [replicate_succ, succ_min_succ, take_replicate]
|
||||
|
||||
@[simp, grind =] theorem drop_replicate {a : α} : ∀ {i n : Nat}, drop i (replicate n a) = replicate (n - i) a
|
||||
@@ -136,7 +136,7 @@ theorem take_append {l₁ l₂ : List α} {i : Nat} :
|
||||
· simp
|
||||
· cases i
|
||||
· simp [*]
|
||||
· simp only [cons_append, take_succ_cons, length_cons, succ_eq_add_one, cons.injEq,
|
||||
· simp only [cons_append, take_succ_cons, length_cons, cons.injEq,
|
||||
append_cancel_left_eq, true_and, *]
|
||||
congr 1
|
||||
omega
|
||||
@@ -157,10 +157,10 @@ theorem take_length_add_append {l₁ l₂ : List α} (i : Nat) :
|
||||
@[simp]
|
||||
theorem take_eq_take_iff :
|
||||
∀ {l : List α} {i j : Nat}, l.take i = l.take j ↔ min i l.length = min j l.length
|
||||
| [], i, j => by simp [Nat.min_zero]
|
||||
| [], i, j => by simp
|
||||
| _ :: xs, 0, 0 => by simp
|
||||
| x :: xs, i + 1, 0 => by simp [Nat.zero_min, succ_min_succ]
|
||||
| x :: xs, 0, j + 1 => by simp [Nat.zero_min, succ_min_succ]
|
||||
| x :: xs, i + 1, 0 => by simp [succ_min_succ]
|
||||
| x :: xs, 0, j + 1 => by simp [succ_min_succ]
|
||||
| x :: xs, i + 1, j + 1 => by simp [succ_min_succ, take_eq_take_iff]
|
||||
|
||||
@[deprecated take_eq_take_iff (since := "2025-02-16")]
|
||||
@@ -279,7 +279,7 @@ theorem mem_drop_iff_getElem {l : List α} {a : α} :
|
||||
@[simp] theorem head_drop {l : List α} {i : Nat} (h : l.drop i ≠ []) :
|
||||
(l.drop i).head h = l[i]'(by simp_all) := by
|
||||
have w : i < l.length := length_lt_of_drop_ne_nil h
|
||||
simp [getElem?_eq_getElem, h, w, head_eq_iff_head?_eq_some]
|
||||
simp [w, head_eq_iff_head?_eq_some]
|
||||
|
||||
theorem getLast?_drop {l : List α} : (l.drop i).getLast? = if l.length ≤ i then none else l.getLast? := by
|
||||
rw [getLast?_eq_getElem?, getElem?_drop]
|
||||
@@ -318,7 +318,7 @@ theorem drop_append {l₁ l₂ : List α} {i : Nat} :
|
||||
· simp
|
||||
· cases i
|
||||
· simp [*]
|
||||
· simp only [cons_append, drop_succ_cons, length_cons, succ_eq_add_one, append_cancel_left_eq, *]
|
||||
· simp only [cons_append, drop_succ_cons, length_cons, append_cancel_left_eq, *]
|
||||
congr 1
|
||||
omega
|
||||
|
||||
@@ -463,7 +463,7 @@ theorem drop_sub_one {l : List α} {i : Nat} (h : 0 < i) :
|
||||
|
||||
theorem false_of_mem_take_findIdx {xs : List α} {p : α → Bool} (h : x ∈ xs.take (xs.findIdx p)) :
|
||||
p x = false := by
|
||||
simp only [mem_take_iff_getElem, forall_exists_index] at h
|
||||
simp only [mem_take_iff_getElem] at h
|
||||
obtain ⟨i, h, rfl⟩ := h
|
||||
exact not_of_lt_findIdx (by omega)
|
||||
|
||||
@@ -484,7 +484,7 @@ theorem false_of_mem_take_findIdx {xs : List α} {p : α → Bool} (h : x ∈ xs
|
||||
induction xs with
|
||||
| nil => simp
|
||||
| cons x xs ih =>
|
||||
simp [findIdx_cons, cond_eq_if, Bool.not_eq_eq_eq_not, Bool.not_true]
|
||||
simp [findIdx_cons, cond_eq_if]
|
||||
split <;> split <;> simp_all [Nat.add_min_add_right]
|
||||
|
||||
/-! ### findIdx? -/
|
||||
@@ -550,7 +550,7 @@ theorem dropWhile_eq_drop_findIdx_not {xs : List α} {p : α → Bool} :
|
||||
@[simp, grind =] theorem length_zipWith {f : α → β → γ} {l₁ : List α} {l₂ : List β} :
|
||||
length (zipWith f l₁ l₂) = min (length l₁) (length l₂) := by
|
||||
induction l₁ generalizing l₂ <;> cases l₂ <;>
|
||||
simp_all [succ_min_succ, Nat.zero_min, Nat.min_zero]
|
||||
simp_all [succ_min_succ]
|
||||
|
||||
theorem lt_length_left_of_zipWith {f : α → β → γ} {i : Nat} {l : List α} {l' : List β}
|
||||
(h : i < (zipWith f l l').length) : i < l.length := by rw [length_zipWith] at h; omega
|
||||
|
||||
@@ -96,7 +96,7 @@ theorem ofFn_add {n m} {f : Fin (n + m) → α} :
|
||||
|
||||
@[simp]
|
||||
theorem ofFn_eq_nil_iff {f : Fin n → α} : ofFn f = [] ↔ n = 0 := by
|
||||
cases n <;> simp only [ofFn_zero, ofFn_succ, eq_self_iff_true, Nat.succ_ne_zero, reduceCtorEq]
|
||||
cases n <;> simp only [ofFn_zero, ofFn_succ, Nat.succ_ne_zero, reduceCtorEq]
|
||||
|
||||
@[simp 500, grind =]
|
||||
theorem mem_ofFn {n} {f : Fin n → α} {a : α} : a ∈ ofFn f ↔ ∃ i, f i = a := by
|
||||
|
||||
@@ -59,7 +59,7 @@ theorem Pairwise.and (hR : Pairwise R l) (hS : Pairwise S l) :
|
||||
induction hR with
|
||||
| nil => simp only [Pairwise.nil]
|
||||
| cons R1 _ IH =>
|
||||
simp only [Pairwise.nil, pairwise_cons] at hS ⊢
|
||||
simp only [pairwise_cons] at hS ⊢
|
||||
exact ⟨fun b bl => ⟨R1 b bl, hS.1 b bl⟩, IH hS.2⟩
|
||||
|
||||
theorem pairwise_and_iff : l.Pairwise (fun a b => R a b ∧ S a b) ↔ Pairwise R l ∧ Pairwise S l :=
|
||||
|
||||
@@ -198,8 +198,8 @@ theorem Perm.filterMap (f : α → Option β) {l₁ l₂ : List α} (p : l₁ ~
|
||||
filterMap f l₁ ~ filterMap f l₂ := by
|
||||
induction p with
|
||||
| nil => simp
|
||||
| cons x _p IH => cases h : f x <;> simp [h, filterMap_cons, IH, Perm.cons]
|
||||
| swap x y l₂ => cases hx : f x <;> cases hy : f y <;> simp [hx, hy, filterMap_cons, swap]
|
||||
| cons x _p IH => cases h : f x <;> simp [h, IH, Perm.cons]
|
||||
| swap x y l₂ => cases hx : f x <;> cases hy : f y <;> simp [hx, hy, swap]
|
||||
| trans _p₁ _p₂ IH₁ IH₂ => exact IH₁.trans IH₂
|
||||
|
||||
grind_pattern Perm.filterMap => l₁ ~ l₂, filterMap f l₁
|
||||
@@ -341,9 +341,9 @@ theorem Perm.foldr_eq' {f : α → β → β} {l₁ l₂ : List α} (p : l₁ ~
|
||||
intros; apply comm <;> apply p₁.symm.subset <;> assumption
|
||||
|
||||
theorem Perm.rec_heq {β : List α → Sort _} {f : ∀ a l, β l → β (a :: l)} {b : β []} {l l' : List α}
|
||||
(hl : l ~ l') (f_congr : ∀ {a l l' b b'}, l ~ l' → HEq b b' → HEq (f a l b) (f a l' b'))
|
||||
(f_swap : ∀ {a a' l b}, HEq (f a (a' :: l) (f a' l b)) (f a' (a :: l) (f a l b))) :
|
||||
HEq (@List.rec α β b f l) (@List.rec α β b f l') := by
|
||||
(hl : l ~ l') (f_congr : ∀ {a l l' b b'}, l ~ l' → b ≍ b' → f a l b ≍ f a l' b')
|
||||
(f_swap : ∀ {a a' l b}, f a (a' :: l) (f a' l b) ≍ f a' (a :: l) (f a l b)) :
|
||||
@List.rec α β b f l ≍ @List.rec α β b f l' := by
|
||||
induction hl with
|
||||
| nil => rfl
|
||||
| cons a h ih => exact f_congr h ih
|
||||
@@ -442,7 +442,7 @@ grind_pattern Perm.count => l₁ ~ l₂, count a l₂
|
||||
|
||||
theorem isPerm_iff : ∀ {l₁ l₂ : List α}, l₁.isPerm l₂ ↔ l₁ ~ l₂
|
||||
| [], [] => by simp [isPerm, isEmpty]
|
||||
| [], _ :: _ => by simp [isPerm, isEmpty, Perm.nil_eq]
|
||||
| [], _ :: _ => by simp [isPerm, isEmpty]
|
||||
| a :: l₁, l₂ => by simp [isPerm, isPerm_iff, cons_perm_iff_perm_erase]
|
||||
|
||||
instance decidablePerm {α} [DecidableEq α] (l₁ l₂ : List α) : Decidable (l₁ ~ l₂) := decidable_of_iff _ isPerm_iff
|
||||
|
||||
@@ -28,7 +28,7 @@ open Nat
|
||||
/-! ### range' -/
|
||||
|
||||
theorem range'_succ {s n step} : range' s (n + 1) step = s :: range' (s + step) n step := by
|
||||
simp [range', Nat.add_succ, Nat.mul_succ]
|
||||
simp [range']
|
||||
|
||||
@[simp] theorem length_range' {s step} : ∀ {n : Nat}, length (range' s n step) = n
|
||||
| 0 => rfl
|
||||
@@ -88,7 +88,7 @@ theorem getElem?_range' {s step} :
|
||||
(getElem?_eq_some_iff.1 <| getElem?_range' (by simpa using H)).2
|
||||
|
||||
theorem head?_range' : (range' s n).head? = if n = 0 then none else some s := by
|
||||
induction n <;> simp_all [range'_succ, head?_append]
|
||||
induction n <;> simp_all [range'_succ]
|
||||
|
||||
@[simp] theorem head_range' (h) : (range' s n).head h = s := by
|
||||
repeat simp_all [head?_range', head_eq_iff_head?_eq_some]
|
||||
@@ -246,11 +246,11 @@ theorem getElem_zipIdx {l : List α} (h : i < (l.zipIdx j).length) :
|
||||
theorem tail_zipIdx {l : List α} {i : Nat} : (zipIdx l i).tail = zipIdx l.tail (i + 1) := by
|
||||
induction l generalizing i with
|
||||
| nil => simp
|
||||
| cons _ l ih => simp [ih, zipIdx_cons]
|
||||
| cons _ l ih => simp [zipIdx_cons]
|
||||
|
||||
theorem map_snd_add_zipIdx_eq_zipIdx {l : List α} {n k : Nat} :
|
||||
map (Prod.map id (· + n)) (zipIdx l k) = zipIdx l (n + k) :=
|
||||
ext_getElem? fun i ↦ by simp [(· ∘ ·), Nat.add_comm, Nat.add_left_comm]; rfl
|
||||
ext_getElem? fun i ↦ by simp [Nat.add_comm, Nat.add_left_comm]; rfl
|
||||
|
||||
theorem zipIdx_cons' {i : Nat} {x : α} {xs : List α} :
|
||||
zipIdx (x :: xs) i = (x, i) :: (zipIdx xs i).map (Prod.map id (· + 1)) := by
|
||||
@@ -328,12 +328,12 @@ theorem getElem_enumFrom (l : List α) (n) (i : Nat) (h : i < (l.enumFrom n).len
|
||||
theorem tail_enumFrom (l : List α) (n : Nat) : (enumFrom n l).tail = enumFrom (n + 1) l.tail := by
|
||||
induction l generalizing n with
|
||||
| nil => simp
|
||||
| cons _ l ih => simp [ih, enumFrom_cons]
|
||||
| cons _ l ih => simp [enumFrom_cons]
|
||||
|
||||
@[deprecated map_snd_add_zipIdx_eq_zipIdx (since := "2025-01-21"), simp]
|
||||
theorem map_fst_add_enumFrom_eq_enumFrom (l : List α) (n k : Nat) :
|
||||
map (Prod.map (· + n) id) (enumFrom k l) = enumFrom (n + k) l :=
|
||||
ext_getElem? fun i ↦ by simp [(· ∘ ·), Nat.add_comm, Nat.add_left_comm]; rfl
|
||||
ext_getElem? fun i ↦ by simp [Nat.add_comm, Nat.add_left_comm]; rfl
|
||||
|
||||
@[deprecated map_snd_add_zipIdx_eq_zipIdx (since := "2025-01-21"), simp]
|
||||
theorem map_fst_add_enum_eq_enumFrom (l : List α) (n : Nat) :
|
||||
|
||||
@@ -44,8 +44,8 @@ def merge (xs ys : List α) (le : α → α → Bool := by exact fun a b => a
|
||||
@[simp] theorem nil_merge (ys : List α) : merge [] ys le = ys := by simp [merge]
|
||||
@[simp] theorem merge_right (xs : List α) : merge xs [] le = xs := by
|
||||
induction xs with
|
||||
| nil => simp [merge]
|
||||
| cons x xs ih => simp [merge, ih]
|
||||
| nil => simp
|
||||
| cons x xs ih => simp [merge]
|
||||
|
||||
/--
|
||||
Split a list in two equal parts. If the length is odd, the first part will be one element longer.
|
||||
|
||||
@@ -57,10 +57,10 @@ where go : List α → List α → List α → List α
|
||||
|
||||
theorem mergeTR_go_eq : mergeTR.go le l₁ l₂ acc = acc.reverse ++ merge l₁ l₂ le := by
|
||||
induction l₁ generalizing l₂ acc with
|
||||
| nil => simp [mergeTR.go, merge, reverseAux_eq]
|
||||
| nil => simp [mergeTR.go, reverseAux_eq]
|
||||
| cons x l₁ ih₁ =>
|
||||
induction l₂ generalizing acc with
|
||||
| nil => simp [mergeTR.go, merge, reverseAux_eq]
|
||||
| nil => simp [mergeTR.go, reverseAux_eq]
|
||||
| cons y l₂ ih₂ =>
|
||||
simp [mergeTR.go, merge]
|
||||
split <;> simp [ih₁, ih₂]
|
||||
@@ -172,7 +172,7 @@ theorem splitRevInTwo_snd (l : { l : List α // l.length = n }) :
|
||||
|
||||
theorem mergeSortTR_run_eq_mergeSort : {n : Nat} → (l : { l : List α // l.length = n }) → mergeSortTR.run le l = mergeSort l.1 le
|
||||
| 0, ⟨[], _⟩
|
||||
| 1, ⟨[a], _⟩ => by simp [mergeSortTR.run, mergeSort]
|
||||
| 1, ⟨[a], _⟩ => by simp [mergeSortTR.run]
|
||||
| n+2, ⟨a :: b :: l, h⟩ => by
|
||||
cases h
|
||||
simp only [mergeSortTR.run, mergeSortTR.run, mergeSort]
|
||||
@@ -189,7 +189,7 @@ set_option maxHeartbeats 400000 in
|
||||
mutual
|
||||
theorem mergeSortTR₂_run_eq_mergeSort : {n : Nat} → (l : { l : List α // l.length = n }) → mergeSortTR₂.run le l = mergeSort l.1 le
|
||||
| 0, ⟨[], _⟩
|
||||
| 1, ⟨[a], _⟩ => by simp [mergeSortTR₂.run, mergeSort]
|
||||
| 1, ⟨[a], _⟩ => by simp [mergeSortTR₂.run]
|
||||
| n+2, ⟨a :: b :: l, h⟩ => by
|
||||
cases h
|
||||
simp only [mergeSortTR₂.run, mergeSort]
|
||||
@@ -201,10 +201,10 @@ termination_by n => n
|
||||
|
||||
theorem mergeSortTR₂_run'_eq_mergeSort : {n : Nat} → (l : { l : List α // l.length = n }) → (w : l' = l.1.reverse) → mergeSortTR₂.run' le l = mergeSort l' le
|
||||
| 0, ⟨[], _⟩, w
|
||||
| 1, ⟨[a], _⟩, w => by simp_all [mergeSortTR₂.run', mergeSort]
|
||||
| 1, ⟨[a], _⟩, w => by simp_all [mergeSortTR₂.run']
|
||||
| n+2, ⟨a :: b :: l, h⟩, w => by
|
||||
cases h
|
||||
simp only [mergeSortTR₂.run', mergeSort]
|
||||
simp only [mergeSortTR₂.run']
|
||||
rw [splitRevInTwo'_fst, splitRevInTwo'_snd]
|
||||
rw [mergeSortTR₂_run_eq_mergeSort, mergeSortTR₂_run'_eq_mergeSort _ rfl]
|
||||
rw [← merge_eq_mergeTR]
|
||||
@@ -220,7 +220,7 @@ theorem mergeSortTR₂_run'_eq_mergeSort : {n : Nat} → (l : { l : List α // l
|
||||
congr 2
|
||||
· dsimp at w
|
||||
simp only [w]
|
||||
simp only [splitInTwo_fst, splitInTwo_snd, reverse_take, take_reverse]
|
||||
simp only [splitInTwo_fst, take_reverse]
|
||||
congr 1
|
||||
rw [w, length_reverse]
|
||||
simp
|
||||
|
||||
@@ -33,11 +33,11 @@ namespace List
|
||||
namespace MergeSort.Internal
|
||||
|
||||
@[simp] theorem splitInTwo_fst (l : { l : List α // l.length = n }) :
|
||||
(splitInTwo l).1 = ⟨l.1.take ((n+1)/2), by simp [splitInTwo, splitAt_eq, l.2]; omega⟩ := by
|
||||
(splitInTwo l).1 = ⟨l.1.take ((n+1)/2), by simp [l.2]; omega⟩ := by
|
||||
simp [splitInTwo, splitAt_eq]
|
||||
|
||||
@[simp] theorem splitInTwo_snd (l : { l : List α // l.length = n }) :
|
||||
(splitInTwo l).2 = ⟨l.1.drop ((n+1)/2), by simp [splitInTwo, splitAt_eq, l.2]; omega⟩ := by
|
||||
(splitInTwo l).2 = ⟨l.1.drop ((n+1)/2), by simp [l.2]; omega⟩ := by
|
||||
simp [splitInTwo, splitAt_eq]
|
||||
|
||||
theorem splitInTwo_fst_append_splitInTwo_snd (l : { l : List α // l.length = n }) : (splitInTwo l).1.1 ++ (splitInTwo l).2.1 = l.1 := by
|
||||
@@ -166,15 +166,15 @@ The elements of `merge le xs ys` are exactly the elements of `xs` and `ys`.
|
||||
-- We subsequently prove that `mergeSort_perm : merge le xs ys ~ xs ++ ys`.
|
||||
theorem mem_merge {a : α} {xs ys : List α} : a ∈ merge xs ys le ↔ a ∈ xs ∨ a ∈ ys := by
|
||||
induction xs generalizing ys with
|
||||
| nil => simp [merge]
|
||||
| nil => simp
|
||||
| cons x xs ih =>
|
||||
induction ys with
|
||||
| nil => simp [merge]
|
||||
| nil => simp
|
||||
| cons y ys ih =>
|
||||
simp only [merge]
|
||||
split <;> rename_i h
|
||||
· simp_all [or_assoc]
|
||||
· simp only [mem_cons, or_assoc, Bool.not_eq_true, ih, ← or_assoc]
|
||||
· simp only [mem_cons, ih, ← or_assoc]
|
||||
apply or_congr_left
|
||||
simp only [or_comm (a := a = y), or_assoc]
|
||||
|
||||
@@ -186,8 +186,8 @@ theorem mem_merge_right (s : α → α → Bool) (h : x ∈ r) : x ∈ merge l r
|
||||
|
||||
theorem merge_stable : ∀ (xs ys) (_ : ∀ x y, x ∈ xs → y ∈ ys → x.2 ≤ y.2),
|
||||
(merge xs ys (zipIdxLE le)).map (·.1) = merge (xs.map (·.1)) (ys.map (·.1)) le
|
||||
| [], ys, _ => by simp [merge]
|
||||
| xs, [], _ => by simp [merge]
|
||||
| [], ys, _ => by simp
|
||||
| xs, [], _ => by simp
|
||||
| (i, x) :: xs, (j, y) :: ys, h => by
|
||||
simp only [merge, zipIdxLE, map_cons]
|
||||
split <;> rename_i w
|
||||
@@ -239,7 +239,7 @@ theorem sorted_merge
|
||||
theorem merge_of_le : ∀ {xs ys : List α} (_ : ∀ a b, a ∈ xs → b ∈ ys → le a b),
|
||||
merge xs ys le = xs ++ ys
|
||||
| [], ys, _
|
||||
| xs, [], _ => by simp [merge]
|
||||
| xs, [], _ => by simp
|
||||
| x :: xs, y :: ys, h => by
|
||||
simp only [merge, cons_append]
|
||||
rw [if_pos, merge_of_le]
|
||||
@@ -249,8 +249,8 @@ theorem merge_of_le : ∀ {xs ys : List α} (_ : ∀ a b, a ∈ xs → b ∈ ys
|
||||
|
||||
variable (le) in
|
||||
theorem merge_perm_append : ∀ {xs ys : List α}, merge xs ys le ~ xs ++ ys
|
||||
| [], ys => by simp [merge]
|
||||
| xs, [] => by simp [merge]
|
||||
| [], ys => by simp
|
||||
| xs, [] => by simp
|
||||
| x :: xs, y :: ys => by
|
||||
simp only [merge]
|
||||
split
|
||||
@@ -269,8 +269,8 @@ theorem Perm.merge (s₁ s₂ : α → α → Bool) (hl : l₁ ~ l₂) (hr : r
|
||||
@[simp] theorem mergeSort_singleton (a : α) : [a].mergeSort r = [a] := by rw [List.mergeSort]
|
||||
|
||||
theorem mergeSort_perm : ∀ (l : List α) (le), mergeSort l le ~ l
|
||||
| [], _ => by simp [mergeSort]
|
||||
| [a], _ => by simp [mergeSort]
|
||||
| [], _ => by simp
|
||||
| [a], _ => by simp
|
||||
| a :: b :: xs, le => by
|
||||
simp only [mergeSort]
|
||||
have : (splitInTwo ⟨a :: b :: xs, rfl⟩).1.1.length < xs.length + 1 + 1 := by simp [splitInTwo_fst]; omega
|
||||
@@ -297,8 +297,8 @@ theorem sorted_mergeSort
|
||||
(trans : ∀ (a b c : α), le a b → le b c → le a c)
|
||||
(total : ∀ (a b : α), le a b || le b a) :
|
||||
(l : List α) → (mergeSort l le).Pairwise le
|
||||
| [] => by simp [mergeSort]
|
||||
| [a] => by simp [mergeSort]
|
||||
| [] => by simp
|
||||
| [a] => by simp
|
||||
| a :: b :: xs => by
|
||||
rw [mergeSort]
|
||||
apply sorted_merge @trans @total
|
||||
@@ -310,8 +310,8 @@ termination_by l => l.length
|
||||
If the input list is already sorted, then `mergeSort` does not change the list.
|
||||
-/
|
||||
theorem mergeSort_of_sorted : ∀ {l : List α} (_ : Pairwise le l), mergeSort l le = l
|
||||
| [], _ => by simp [mergeSort]
|
||||
| [a], _ => by simp [mergeSort]
|
||||
| [], _ => by simp
|
||||
| [a], _ => by simp
|
||||
| a :: b :: xs, h => by
|
||||
have : (splitInTwo ⟨a :: b :: xs, rfl⟩).1.1.length < xs.length + 1 + 1 := by simp [splitInTwo_fst]; omega
|
||||
have : (splitInTwo ⟨a :: b :: xs, rfl⟩).2.1.length < xs.length + 1 + 1 := by simp [splitInTwo_snd]; omega
|
||||
@@ -340,7 +340,7 @@ theorem mergeSort_zipIdx {l : List α} :
|
||||
where go : ∀ (i : Nat) (l : List α),
|
||||
(mergeSort (l.zipIdx i) (zipIdxLE le)).map (·.1) = mergeSort l le
|
||||
| _, []
|
||||
| _, [a] => by simp [mergeSort]
|
||||
| _, [a] => by simp
|
||||
| _, a :: b :: xs => by
|
||||
have : (splitInTwo ⟨a :: b :: xs, rfl⟩).1.1.length < xs.length + 1 + 1 := by simp [splitInTwo_fst]; omega
|
||||
have : (splitInTwo ⟨a :: b :: xs, rfl⟩).2.1.length < xs.length + 1 + 1 := by simp [splitInTwo_snd]; omega
|
||||
|
||||
@@ -276,7 +276,7 @@ grind_pattern Sublist.map => l₁ <+ l₂, map f l₂
|
||||
@[grind]
|
||||
protected theorem Sublist.filterMap (f : α → Option β) (s : l₁ <+ l₂) :
|
||||
filterMap f l₁ <+ filterMap f l₂ := by
|
||||
induction s <;> simp [filterMap_cons] <;> split <;> simp [*, cons, cons₂]
|
||||
induction s <;> simp [filterMap_cons] <;> split <;> simp [*, cons]
|
||||
|
||||
grind_pattern Sublist.filterMap => l₁ <+ l₂, filterMap f l₁
|
||||
grind_pattern Sublist.filterMap => l₁ <+ l₂, filterMap f l₂
|
||||
@@ -542,7 +542,7 @@ theorem sublist_flatten_of_mem {L : List (List α)} {l} (h : l ∈ L) : l <+ L.f
|
||||
| nil => cases h
|
||||
| cons l' L ih =>
|
||||
rcases mem_cons.1 h with (rfl | h)
|
||||
· simp [h]
|
||||
· simp
|
||||
· simp [ih h, flatten_cons, sublist_append_of_sublist_right]
|
||||
|
||||
theorem sublist_flatten_iff {L : List (List α)} {l} :
|
||||
@@ -914,7 +914,7 @@ theorem infix_cons_iff : l₁ <:+: a :: l₂ ↔ l₁ <+: a :: l₂ ∨ l₁ <:+
|
||||
theorem prefix_concat_iff {l₁ l₂ : List α} {a : α} :
|
||||
l₁ <+: l₂ ++ [a] ↔ l₁ = l₂ ++ [a] ∨ l₁ <+: l₂ := by
|
||||
simp only [← reverse_suffix, reverse_concat, suffix_cons_iff]
|
||||
simp only [concat_eq_append, ← reverse_concat, reverse_eq_iff, reverse_reverse]
|
||||
simp only [← reverse_concat, reverse_eq_iff, reverse_reverse]
|
||||
|
||||
theorem suffix_concat_iff {l₁ l₂ : List α} {a : α} :
|
||||
l₁ <:+ l₂ ++ [a] ↔ l₁ = [] ∨ ∃ t, l₁ = t ++ [a] ∧ t <:+ l₂ := by
|
||||
@@ -941,7 +941,7 @@ theorem prefix_iff_getElem? {l₁ l₂ : List α} :
|
||||
| nil =>
|
||||
simpa using ⟨0, by simp⟩
|
||||
| cons b l₂ =>
|
||||
simp only [cons_append, cons_prefix_cons, ih]
|
||||
simp only [cons_prefix_cons, ih]
|
||||
rw (occs := [2]) [← Nat.and_forall_add_one]
|
||||
simp [Nat.succ_lt_succ_iff, eq_comm]
|
||||
|
||||
@@ -964,7 +964,7 @@ theorem prefix_iff_getElem {l₁ l₂ : List α} :
|
||||
| nil =>
|
||||
exact nil_prefix
|
||||
| cons _ _ =>
|
||||
simp only [length_cons, Nat.add_le_add_iff_right, Fin.getElem_fin] at hl h
|
||||
simp only [length_cons, Nat.add_le_add_iff_right] at hl h
|
||||
simp only [cons_prefix_cons]
|
||||
exact ⟨h 0 (zero_lt_succ _), tail_ih hl fun a ha ↦ h a.succ (succ_lt_succ ha)⟩
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ theorem takeWhile_filterMap {f : α → Option β} {p : β → Bool} {l : List
|
||||
· simp only [takeWhile_cons, h]
|
||||
split <;> simp_all
|
||||
· simp [takeWhile_cons, h, ih]
|
||||
split <;> simp_all [filterMap_cons]
|
||||
split <;> simp_all
|
||||
|
||||
theorem dropWhile_filterMap {f : α → Option β} {p : β → Bool} {l : List α} :
|
||||
(l.filterMap f).dropWhile p = (l.dropWhile fun a => (f a).all p).filterMap f := by
|
||||
@@ -362,7 +362,7 @@ theorem dropWhile_filterMap {f : α → Option β} {p : β → Bool} {l : List
|
||||
· simp only [dropWhile_cons, h]
|
||||
split <;> simp_all
|
||||
· simp [dropWhile_cons, h, ih]
|
||||
split <;> simp_all [filterMap_cons]
|
||||
split <;> simp_all
|
||||
|
||||
theorem takeWhile_filter {p q : α → Bool} {l : List α} :
|
||||
(l.filter p).takeWhile q = (l.takeWhile fun a => !p a || q a).filter p := by
|
||||
@@ -393,7 +393,7 @@ theorem takeWhile_append {xs ys : List α} :
|
||||
(l₁ ++ l₂).takeWhile p = l₁ ++ l₂.takeWhile p := by
|
||||
induction l₁ with
|
||||
| nil => simp
|
||||
| cons x xs ih => simp_all [takeWhile_cons]
|
||||
| cons x xs ih => simp_all
|
||||
|
||||
theorem dropWhile_append {xs ys : List α} :
|
||||
(xs ++ ys).dropWhile p =
|
||||
@@ -408,7 +408,7 @@ theorem dropWhile_append {xs ys : List α} :
|
||||
(l₁ ++ l₂).dropWhile p = l₂.dropWhile p := by
|
||||
induction l₁ with
|
||||
| nil => simp
|
||||
| cons x xs ih => simp_all [dropWhile_cons]
|
||||
| cons x xs ih => simp_all
|
||||
|
||||
@[simp] theorem takeWhile_replicate_eq_filter {p : α → Bool} :
|
||||
(replicate n a).takeWhile p = (replicate n a).filter p := by
|
||||
@@ -440,7 +440,7 @@ theorem take_takeWhile {l : List α} {p : α → Bool} :
|
||||
induction l generalizing i with
|
||||
| nil => simp
|
||||
| cons x xs ih =>
|
||||
by_cases h : p x <;> cases i <;> simp [takeWhile_cons, h, ih, take_succ_cons]
|
||||
by_cases h : p x <;> cases i <;> simp [h, ih, take_succ_cons]
|
||||
|
||||
@[simp] theorem all_takeWhile {l : List α} : (l.takeWhile p).all p = true := by
|
||||
induction l with
|
||||
@@ -461,7 +461,7 @@ theorem replace_takeWhile [BEq α] [LawfulBEq α] {l : List α} {p : α → Bool
|
||||
simp only [takeWhile_cons, replace_cons]
|
||||
split <;> rename_i h₁ <;> split <;> rename_i h₂
|
||||
· simp_all
|
||||
· simp [replace_cons, h₂, takeWhile_cons, h₁, ih]
|
||||
· simp [replace_cons, h₂, h₁, ih]
|
||||
· simp_all
|
||||
· simp_all
|
||||
|
||||
|
||||
@@ -576,7 +576,7 @@ theorem flatMap_toArray_cons {β} (f : α → Array β) (a : α) (as : List α)
|
||||
rw [Array.eraseIdx]
|
||||
split <;> rename_i h'
|
||||
· rw [eraseIdx_toArray]
|
||||
simp only [swap_toArray, Fin.getElem_fin, toList_toArray, mk.injEq]
|
||||
simp only [swap_toArray, toList_toArray, mk.injEq]
|
||||
rw [eraseIdx_set_gt (by simp), eraseIdx_set_eq]
|
||||
simp
|
||||
· simp at h h'
|
||||
@@ -667,7 +667,7 @@ theorem replace_toArray [BEq α] [LawfulBEq α] (l : List α) (a b : α) :
|
||||
l.toArray.replace a b = (l.replace a b).toArray := by
|
||||
rw [Array.replace]
|
||||
split <;> rename_i i h
|
||||
· simp only [finIdxOf?_toArray, finIdxOf?_eq_none_iff] at h
|
||||
· simp only [finIdxOf?_toArray] at h
|
||||
rw [replace_of_not_mem]
|
||||
exact finIdxOf?_eq_none_iff.mp h
|
||||
· simp_all only [finIdxOf?_toArray, finIdxOf?_eq_some_iff, Fin.getElem_fin, set_toArray,
|
||||
|
||||
@@ -184,7 +184,7 @@ theorem zipWith_eq_cons_iff {f : α → β → γ} {l₁ : List α} {l₂ : List
|
||||
| [], b :: l₂ => simp
|
||||
| a :: l₁, [] => simp
|
||||
| a' :: l₁, b' :: l₂ =>
|
||||
simp only [zip_cons_cons, cons.injEq, Prod.mk.injEq]
|
||||
simp only [cons.injEq]
|
||||
constructor
|
||||
· rintro ⟨⟨rfl, rfl⟩, rfl⟩
|
||||
refine ⟨a', l₁, b', l₂, by simp⟩
|
||||
|
||||
@@ -937,7 +937,7 @@ protected theorem pred_succ (n : Nat) : pred n.succ = n := rfl
|
||||
@[simp] protected theorem add_one_sub_one (n : Nat) : n + 1 - 1 = n := rfl
|
||||
|
||||
theorem sub_one_eq_self {n : Nat} : n - 1 = n ↔ n = 0 := by cases n <;> simp [ne_add_one]
|
||||
theorem eq_self_sub_one {n : Nat} : n = n - 1 ↔ n = 0 := by cases n <;> simp [add_one_ne]
|
||||
theorem eq_self_sub_one {n : Nat} : n = n - 1 ↔ n = 0 := by cases n <;> simp
|
||||
|
||||
theorem succ_pred {a : Nat} (h : a ≠ 0) : a.pred.succ = a := by
|
||||
induction a with
|
||||
@@ -1098,13 +1098,13 @@ theorem add_le_of_le_sub {a b c : Nat} (hle : b ≤ c) (h : a ≤ c - b) : a + b
|
||||
| ⟨d, hd⟩ =>
|
||||
apply @le.intro _ _ d
|
||||
rw [Nat.eq_add_of_sub_eq hle hd.symm]
|
||||
simp [Nat.add_comm, Nat.add_assoc, Nat.add_left_comm]
|
||||
simp [Nat.add_comm, Nat.add_left_comm]
|
||||
|
||||
theorem le_sub_of_add_le {a b c : Nat} (h : a + b ≤ c) : a ≤ c - b := by
|
||||
match le.dest h with
|
||||
| ⟨d, hd⟩ =>
|
||||
apply @le.intro _ _ d
|
||||
have hd : a + d + b = c := by simp [← hd, Nat.add_comm, Nat.add_assoc, Nat.add_left_comm]
|
||||
have hd : a + d + b = c := by simp [← hd, Nat.add_comm, Nat.add_left_comm]
|
||||
have hd := Nat.sub_eq_of_eq_add hd.symm
|
||||
exact hd.symm
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ theorem shiftLeft_eq (a b : Nat) : a <<< b = a * 2 ^ b :=
|
||||
match b with
|
||||
| 0 => (Nat.mul_one _).symm
|
||||
| b+1 => (shiftLeft_eq _ b).trans <| by
|
||||
simp [Nat.pow_succ, Nat.mul_assoc, Nat.mul_left_comm, Nat.mul_comm]
|
||||
simp [Nat.pow_succ, Nat.mul_assoc, Nat.mul_comm]
|
||||
|
||||
@[simp] theorem shiftRight_zero : n >>> 0 = n := rfl
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ noncomputable def div2Induction {motive : Nat → Sort u}
|
||||
simp only [HAnd.hAnd, AndOp.and, land]
|
||||
unfold bitwise
|
||||
cases mod_two_eq_zero_or_one x with | _ p =>
|
||||
simp [xz, p, andz, mod_eq_of_lt]
|
||||
simp [xz, p, andz]
|
||||
|
||||
/-! ### testBit -/
|
||||
|
||||
@@ -163,7 +163,7 @@ theorem exists_testBit_ne_of_ne {x y : Nat} (p : x ≠ y) : ∃ i, testBit x i
|
||||
| ind y hyp =>
|
||||
cases Nat.eq_zero_or_pos y with
|
||||
| inl yz =>
|
||||
simp only [yz, Nat.zero_testBit, Bool.eq_false_iff]
|
||||
simp only [yz, Nat.zero_testBit]
|
||||
simp only [yz] at p
|
||||
have ⟨i,ip⟩ := exists_testBit_of_ne_zero p
|
||||
apply Exists.intro i
|
||||
@@ -283,14 +283,14 @@ theorem testBit_two_pow_add_gt {i j : Nat} (j_lt_i : j < i) (x : Nat) :
|
||||
have i_def : i = j + (i-j) := (Nat.add_sub_cancel' (Nat.le_of_lt j_lt_i)).symm
|
||||
rw [i_def]
|
||||
simp only [testBit_eq_decide_div_mod_eq, Nat.pow_add,
|
||||
Nat.add_comm x, Nat.mul_add_div (Nat.two_pow_pos _)]
|
||||
Nat.mul_add_div (Nat.two_pow_pos _)]
|
||||
match i_sub_j_eq : i - j with
|
||||
| 0 =>
|
||||
exfalso
|
||||
rw [Nat.sub_eq_zero_iff_le] at i_sub_j_eq
|
||||
exact Nat.not_le_of_gt j_lt_i i_sub_j_eq
|
||||
| d+1 =>
|
||||
simp [Nat.pow_succ, Nat.mul_comm _ 2, Nat.mul_add_mod]
|
||||
simp [Nat.pow_succ, Nat.mul_comm _ 2]
|
||||
|
||||
@[simp, grind =] theorem testBit_mod_two_pow (x j i : Nat) :
|
||||
testBit (x % 2^j) i = (decide (i < j) && testBit x i) := by
|
||||
@@ -330,7 +330,7 @@ theorem testBit_two_pow_sub_succ (h₂ : x < 2 ^ n) (i : Nat) :
|
||||
induction i generalizing n x with
|
||||
| zero =>
|
||||
match n with
|
||||
| 0 => simp [succ_sub_succ_eq_sub]
|
||||
| 0 => simp
|
||||
| n+1 =>
|
||||
simp [not_decide_mod_two_eq_one]
|
||||
omega
|
||||
@@ -338,7 +338,7 @@ theorem testBit_two_pow_sub_succ (h₂ : x < 2 ^ n) (i : Nat) :
|
||||
simp only [testBit_succ]
|
||||
match n with
|
||||
| 0 =>
|
||||
simp [decide_eq_false, succ_sub_succ_eq_sub]
|
||||
simp [decide_eq_false]
|
||||
| n+1 =>
|
||||
rw [Nat.two_pow_succ_sub_succ_div_two, ih]
|
||||
· simp [Nat.succ_lt_succ_iff]
|
||||
@@ -352,8 +352,8 @@ theorem testBit_two_pow_sub_succ (h₂ : x < 2 ^ n) (i : Nat) :
|
||||
theorem testBit_bool_to_nat (b : Bool) (i : Nat) :
|
||||
testBit (Bool.toNat b) i = (decide (i = 0) && b) := by
|
||||
cases b <;> cases i <;>
|
||||
simp [testBit_eq_decide_div_mod_eq, Nat.pow_succ, Nat.mul_comm _ 2,
|
||||
←Nat.div_div_eq_div_mul _ 2, Nat.mod_eq_of_lt]
|
||||
simp [testBit_eq_decide_div_mod_eq,
|
||||
Nat.mod_eq_of_lt]
|
||||
|
||||
/-- `testBit 1 i` is true iff the index `i` equals 0. -/
|
||||
theorem testBit_one_eq_true_iff_self_eq_zero {i : Nat} :
|
||||
@@ -371,7 +371,7 @@ theorem testBit_two_pow {n m : Nat} : testBit (2 ^ n) m = decide (n = m) := by
|
||||
simp
|
||||
· rw [Nat.pow_div _ Nat.two_pos,
|
||||
← Nat.sub_add_cancel (succ_le_of_lt <| Nat.sub_pos_of_lt (by omega))]
|
||||
simp [Nat.pow_succ, and_one_is_mod, mul_mod_left]
|
||||
simp [Nat.pow_succ, mul_mod_left]
|
||||
omega
|
||||
|
||||
@[simp]
|
||||
@@ -415,11 +415,11 @@ theorem testBit_bitwise (of_false_false : f false false = false) (x y i : Nat) :
|
||||
cases i with
|
||||
| zero =>
|
||||
cases p : f (decide (x % 2 = 1)) (decide (y % 2 = 1)) <;>
|
||||
simp [p, Nat.mul_add_mod, mod_eq_of_lt]
|
||||
simp [p]
|
||||
| succ i =>
|
||||
have hyp_i := hyp i (Nat.le_refl (i+1))
|
||||
cases p : f (decide (x % 2 = 1)) (decide (y % 2 = 1)) <;>
|
||||
simp [p, hyp_i, Nat.mul_add_div]
|
||||
simp [hyp_i, Nat.mul_add_div]
|
||||
|
||||
/-! ### bitwise -/
|
||||
|
||||
@@ -437,7 +437,7 @@ private theorem eq_0_of_lt (x : Nat) : x < 2^ 0 ↔ x = 0 := eq_0_of_lt_one x
|
||||
@[local simp]
|
||||
private theorem zero_lt_pow (n : Nat) : 0 < 2^n := by
|
||||
induction n
|
||||
case zero => simp [eq_0_of_lt]
|
||||
case zero => simp
|
||||
case succ n hyp => simpa [Nat.pow_succ]
|
||||
|
||||
private theorem div_two_le_of_lt_two {m n : Nat} (p : m < 2 ^ succ n) : m / 2 < 2^n := by
|
||||
@@ -457,10 +457,10 @@ theorem bitwise_lt_two_pow (left : x < 2^n) (right : y < 2^n) : (Nat.bitwise f x
|
||||
simp only [x_zero, if_pos]
|
||||
by_cases p : f false true = true <;> simp [p, right]
|
||||
else if y_zero : y = 0 then
|
||||
simp only [x_zero, y_zero, if_neg, if_pos]
|
||||
simp only [x_zero, y_zero, if_pos]
|
||||
by_cases p : f true false = true <;> simp [p, left]
|
||||
else
|
||||
simp only [x_zero, y_zero, if_neg]
|
||||
simp only [x_zero, y_zero]
|
||||
have hyp1 := hyp (div_two_le_of_lt_two left) (div_two_le_of_lt_two right)
|
||||
by_cases p : f (decide (x % 2 = 1)) (decide (y % 2 = 1)) = true <;>
|
||||
simp [p, Nat.pow_succ, mul_succ, Nat.add_assoc]
|
||||
@@ -560,7 +560,7 @@ theorem and_mod_two_pow : (a &&& b) % 2 ^ n = (a % 2 ^ n) &&& (b % 2 ^ n) :=
|
||||
@[simp, grind =] theorem zero_or (x : Nat) : 0 ||| x = x := by
|
||||
simp only [HOr.hOr, OrOp.or, lor]
|
||||
unfold bitwise
|
||||
simp [@eq_comm _ 0]
|
||||
simp
|
||||
|
||||
@[simp, grind =] theorem or_zero (x : Nat) : x ||| 0 = x := by
|
||||
simp only [HOr.hOr, OrOp.or, lor]
|
||||
@@ -720,8 +720,8 @@ theorem testBit_two_pow_mul_add (a : Nat) {b i : Nat} (b_lt : b < 2^i) (j : Nat)
|
||||
rw [succ_pred_eq_of_pos] <;> omega
|
||||
rw [i_def]
|
||||
simp only [testBit_eq_decide_div_mod_eq, Nat.pow_add, Nat.mul_assoc]
|
||||
simp only [Nat.mul_add_div (Nat.two_pow_pos _), Nat.mul_add_mod]
|
||||
simp [Nat.pow_succ, Nat.mul_comm _ 2, Nat.mul_assoc, Nat.mul_add_mod]
|
||||
simp only [Nat.mul_add_div (Nat.two_pow_pos _)]
|
||||
simp [Nat.pow_succ, Nat.mul_comm _ 2, Nat.mul_assoc]
|
||||
| inr j_ge =>
|
||||
have j_def : j = i + (j-i) := (Nat.add_sub_cancel' j_ge).symm
|
||||
simp only [
|
||||
@@ -789,7 +789,7 @@ abbrev mul_add_lt_is_or := @two_pow_add_eq_or_of_lt
|
||||
theorem bitwise_mul_two_pow (of_false_false : f false false = false := by rfl) :
|
||||
(bitwise f x y) * 2 ^ n = bitwise f (x * 2 ^ n) (y * 2 ^ n) := by
|
||||
apply Nat.eq_of_testBit_eq
|
||||
simp only [testBit_mul_two_pow, testBit_bitwise of_false_false, Bool.if_false_right]
|
||||
simp only [testBit_mul_two_pow, testBit_bitwise of_false_false]
|
||||
intro i
|
||||
by_cases hn : n ≤ i
|
||||
· simp [hn]
|
||||
|
||||
@@ -37,7 +37,7 @@ theorem compare_eq_ite_le (a b : Nat) :
|
||||
· next hlt => simp [Nat.le_of_lt hlt, Nat.not_le.2 hlt]
|
||||
· next hge =>
|
||||
split
|
||||
· next hgt => simp [Nat.le_of_lt hgt, Nat.not_le.2 hgt]
|
||||
· next hgt => simp [Nat.not_le.2 hgt]
|
||||
· next hle => simp [Nat.not_lt.1 hge, Nat.not_lt.1 hle]
|
||||
|
||||
@[deprecated compare_eq_ite_le (since := "2025-03_28")]
|
||||
|
||||
@@ -512,7 +512,7 @@ theorem sub_mul_div_of_le (x n p : Nat) (h₁ : n*p ≤ x) : (x - n*p) / n = x /
|
||||
rw [mul_succ] at h₁
|
||||
exact h₁
|
||||
rw [sub_succ, ← IH h₂, div_eq_sub_div h₀ h₃]
|
||||
simp [Nat.pred_succ, mul_succ, Nat.sub_sub]
|
||||
simp [mul_succ, Nat.sub_sub]
|
||||
|
||||
theorem mul_sub_div (x n p : Nat) (h₁ : x < n*p) : (n * p - (x + 1)) / n = p - ((x / n) + 1) := by
|
||||
have npos : 0 < n := (eq_zero_or_pos _).resolve_left fun n0 => by
|
||||
|
||||
@@ -80,7 +80,7 @@ theorem lt_div_mul_self (h : 0 < k) (w : k ≤ x) : x - k < x / k * k := by
|
||||
theorem div_pos (hba : b ≤ a) (hb : 0 < b) : 0 < a / b := by
|
||||
cases b
|
||||
· contradiction
|
||||
· simp [Nat.pos_iff_ne_zero, div_eq_zero_iff_lt, hba]
|
||||
· simp [Nat.pos_iff_ne_zero, hba]
|
||||
|
||||
theorem div_le_div_left (hcb : c ≤ b) (hc : 0 < c) : a / b ≤ a / c :=
|
||||
(Nat.le_div_iff_mul_le hc).2 <|
|
||||
|
||||
@@ -137,7 +137,7 @@ theorem dvd_sub_iff_left {m n k : Nat} (hkn : k ≤ n) (h : m ∣ k) : m ∣ n -
|
||||
|
||||
protected theorem mul_dvd_mul {a b c d : Nat} : a ∣ b → c ∣ d → a * c ∣ b * d
|
||||
| ⟨e, he⟩, ⟨f, hf⟩ =>
|
||||
⟨e * f, by simp [he, hf, Nat.mul_assoc, Nat.mul_left_comm, Nat.mul_comm]⟩
|
||||
⟨e * f, by simp [he, hf, Nat.mul_left_comm, Nat.mul_comm]⟩
|
||||
|
||||
protected theorem mul_dvd_mul_left (a : Nat) (h : b ∣ c) : a * b ∣ a * c :=
|
||||
Nat.mul_dvd_mul (Nat.dvd_refl a) h
|
||||
@@ -161,7 +161,7 @@ protected theorem dvd_eq_true_of_mod_eq_zero {m n : Nat} (h : n % m == 0) : (m
|
||||
simp [Nat.dvd_of_mod_eq_zero, eq_of_beq h]
|
||||
|
||||
protected theorem dvd_eq_false_of_mod_ne_zero {m n : Nat} (h : n % m != 0) : (m ∣ n) = False := by
|
||||
simp [eq_of_beq] at h
|
||||
simp at h
|
||||
simp [dvd_iff_mod_eq_zero, h]
|
||||
|
||||
end Nat
|
||||
|
||||
@@ -142,7 +142,7 @@ theorem foldTR_loop_congr {α : Type u} {n m : Nat} (w : n = m)
|
||||
| succ m, n, f => by
|
||||
have t : (m + 1) + n = m + (n + 1) := by omega
|
||||
rw [foldTR.loop]
|
||||
simp only [succ_eq_add_one, Nat.add_sub_cancel]
|
||||
simp only [succ_eq_add_one]
|
||||
rw [fold_congr t, foldTR_loop_congr t, go, fold]
|
||||
congr
|
||||
omega
|
||||
|
||||
@@ -54,7 +54,7 @@ theorem gcd_def (x y : Nat) : gcd x y = if x = 0 then y else gcd (y % x) x := by
|
||||
|
||||
@[simp] theorem gcd_zero_right (n : Nat) : gcd n 0 = n := by
|
||||
cases n with
|
||||
| zero => simp [gcd_succ]
|
||||
| zero => simp
|
||||
| succ n =>
|
||||
-- `simp [gcd_succ]` produces an invalid term unless `gcd_succ` is proved with `id rfl` instead
|
||||
rw [gcd_succ]
|
||||
|
||||
@@ -1044,7 +1044,7 @@ theorem div_le_iff_le_mul_of_dvd (hb : b ≠ 0) (hba : b ∣ a) : a / b ≤ c
|
||||
exact ⟨mul_le_mul_right b, fun h ↦ Nat.le_of_mul_le_mul_right h (zero_lt_of_ne_zero hb)⟩
|
||||
|
||||
protected theorem div_lt_div_right (ha : a ≠ 0) : a ∣ b → a ∣ c → (b / a < c / a ↔ b < c) := by
|
||||
rintro ⟨d, rfl⟩ ⟨e, rfl⟩; simp [Nat.mul_div_cancel, Nat.pos_iff_ne_zero.2 ha]
|
||||
rintro ⟨d, rfl⟩ ⟨e, rfl⟩; simp [Nat.pos_iff_ne_zero.2 ha]
|
||||
|
||||
protected theorem div_lt_div_left (ha : a ≠ 0) (hba : b ∣ a) (hca : c ∣ a) :
|
||||
a / b < a / c ↔ c < b := by
|
||||
@@ -1164,7 +1164,7 @@ protected theorem pow_le_pow_iff_right {a n m : Nat} (h : 1 < a) :
|
||||
constructor
|
||||
· apply Decidable.by_contra
|
||||
intros w
|
||||
simp [Decidable.not_imp_iff_and_not] at w
|
||||
simp at w
|
||||
apply Nat.lt_irrefl (a ^ n)
|
||||
exact Nat.lt_of_le_of_lt w.1 (Nat.pow_lt_pow_of_lt h w.2)
|
||||
· intro w
|
||||
@@ -1320,7 +1320,7 @@ theorem le_log2 (h : n ≠ 0) : k ≤ n.log2 ↔ 2 ^ k ≤ n := by
|
||||
| k+1 =>
|
||||
rw [log2]; split
|
||||
· have n0 : 0 < n / 2 := (Nat.le_div_iff_mul_le (by decide)).2 ‹_›
|
||||
simp only [Nat.add_le_add_iff_right, le_log2 (Nat.ne_of_gt n0), le_div_iff_mul_le,
|
||||
simp only [Nat.add_le_add_iff_right, le_log2 (Nat.ne_of_gt n0),
|
||||
Nat.pow_succ]
|
||||
exact Nat.le_div_iff_mul_le (by decide)
|
||||
· simp only [le_zero_eq, succ_ne_zero, false_iff]
|
||||
@@ -1434,7 +1434,7 @@ theorem le_iff_ne_zero_of_dvd (ha : a ≠ 0) (hab : a ∣ b) : a ≤ b ↔ b ≠
|
||||
|
||||
theorem div_ne_zero_iff_of_dvd (hba : b ∣ a) : a / b ≠ 0 ↔ a ≠ 0 ∧ b ≠ 0 := by
|
||||
obtain rfl | hb := Decidable.em (b = 0) <;>
|
||||
simp [Nat.div_ne_zero_iff, Nat.le_iff_ne_zero_of_dvd, *]
|
||||
simp [Nat.le_iff_ne_zero_of_dvd, *]
|
||||
|
||||
theorem pow_mod (a b n : Nat) : a ^ b % n = (a % n) ^ b % n := by
|
||||
induction b with
|
||||
@@ -1706,12 +1706,12 @@ theorem shiftRight_succ_inside : ∀m n, m >>> (n+1) = (m/2) >>> n
|
||||
rw [shiftRight_succ_inside _ k, shiftRight_succ]
|
||||
|
||||
@[simp] theorem zero_shiftLeft : ∀ n, 0 <<< n = 0
|
||||
| 0 => by simp [shiftLeft]
|
||||
| n + 1 => by simp [shiftLeft, zero_shiftLeft n, shiftLeft_succ]
|
||||
| 0 => by simp
|
||||
| n + 1 => by simp [zero_shiftLeft n, shiftLeft_succ]
|
||||
|
||||
@[simp] theorem zero_shiftRight : ∀ n, 0 >>> n = 0
|
||||
| 0 => by simp [shiftRight]
|
||||
| n + 1 => by simp [shiftRight, zero_shiftRight n, shiftRight_succ]
|
||||
| 0 => by simp
|
||||
| n + 1 => by simp [zero_shiftRight n, shiftRight_succ]
|
||||
|
||||
theorem shiftLeft_add (m n : Nat) : ∀ k, m <<< (n + k) = (m <<< n) <<< k
|
||||
| 0 => rfl
|
||||
|
||||
@@ -226,7 +226,7 @@ theorem Poly.denote_insert (ctx : Context) (k : Nat) (v : Var) (p : Poly) :
|
||||
· by_cases h₂ : Nat.beq v v'
|
||||
· simp only [insert, h₁, h₂, cond_false, cond_true]
|
||||
simp [Nat.eq_of_beq_eq_true h₂]
|
||||
· simp only [insert, h₁, h₂, cond_false, cond_true]
|
||||
· simp only [insert, h₁, h₂, cond_false]
|
||||
simp [denote_insert]
|
||||
|
||||
attribute [local simp] Poly.denote_insert
|
||||
@@ -253,7 +253,7 @@ attribute [local simp] Poly.denote_append
|
||||
theorem Poly.denote_cons (ctx : Context) (k : Nat) (v : Var) (p : Poly) : denote ctx ((k, v) :: p) = k * v.denote ctx + p.denote ctx := by
|
||||
match p with
|
||||
| [] => simp
|
||||
| _ :: m => simp [denote_cons]
|
||||
| _ :: m => simp
|
||||
|
||||
attribute [local simp] Poly.denote_cons
|
||||
|
||||
@@ -434,13 +434,13 @@ theorem Expr.denote_toPoly_go (ctx : Context) (e : Expr) :
|
||||
simp [toPoly.go, h, Var.denote]
|
||||
| case3 k i => simp [toPoly.go]
|
||||
| case4 k a b iha ihb => simp [toPoly.go, iha, ihb]
|
||||
| case5 k k' a h => simp [toPoly.go, h, eq_of_beq h]
|
||||
| case5 k k' a h => simp [toPoly.go, eq_of_beq h]
|
||||
| case6 k a k' h ih =>
|
||||
simp only [toPoly.go, denote, mul_eq]
|
||||
simp [h, cond_false, ih, Nat.mul_assoc]
|
||||
| case7 k a k' h =>
|
||||
simp only [toPoly.go, denote, mul_eq]
|
||||
simp [h, eq_of_beq h]
|
||||
simp [eq_of_beq h]
|
||||
| case8 k a k' h ih =>
|
||||
simp only [toPoly.go, denote, mul_eq]
|
||||
simp [h, cond_false, ih, Nat.mul_assoc]
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Nat
|
||||
| succ a ih =>
|
||||
cases a
|
||||
· simp
|
||||
· simp_all [succ_eq_add_one, Nat.right_distrib]
|
||||
· simp_all [Nat.right_distrib]
|
||||
omega
|
||||
|
||||
@[simp] protected theorem mul_lt_mul_right (a0 : 0 < a) : b * a < c * a ↔ b < c := by
|
||||
|
||||
@@ -142,7 +142,7 @@ where
|
||||
subst m₂
|
||||
by_cases heq : k₁ + k₂ == 0 <;> simp! [heq, ih]
|
||||
· simp [← Nat.add_assoc, ← Nat.right_distrib, eq_of_beq heq]
|
||||
· simp [Nat.right_distrib, Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
|
||||
· simp [Nat.right_distrib, Nat.add_assoc]
|
||||
|
||||
theorem Poly.denote_insertSorted (ctx : Context) (k : Nat) (m : Mon) (p : Poly) : (p.insertSorted k m).denote ctx = p.denote ctx + k * m.denote ctx := by
|
||||
match p with
|
||||
|
||||
@@ -84,7 +84,7 @@ theorem toArray_eq_singleton_iff {o : Option α} : o.toArray = #[a] ↔ o = some
|
||||
|
||||
theorem size_toArray_eq_zero_iff {o : Option α} :
|
||||
o.toArray.size = 0 ↔ o = none := by
|
||||
simp [Array.size]
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem size_toArray_eq_one_iff {o : Option α} :
|
||||
|
||||
@@ -82,7 +82,7 @@ abbrev attach_map_coe := @attach_map_val
|
||||
|
||||
theorem attachWith_map_val {p : α → Prop} (f : α → β) (o : Option α) (H : ∀ a, o = some a → p a) :
|
||||
((o.attachWith p H).map fun (i : { i // p i}) => f i.val) = o.map f := by
|
||||
cases o <;> simp [H]
|
||||
cases o <;> simp
|
||||
|
||||
@[deprecated attachWith_map_val (since := "2025-02-17")]
|
||||
abbrev attachWith_map_coe := @attachWith_map_val
|
||||
@@ -202,7 +202,7 @@ theorem map_attachWith_eq_pmap {o : Option α} {P : α → Prop} {H : ∀ (a :
|
||||
@[simp]
|
||||
theorem map_attach_eq_attachWith {o : Option α} {p : α → Prop} (f : ∀ a, o = some a → p a) :
|
||||
o.attach.map (fun x => ⟨x.1, f x.1 x.2⟩) = o.attachWith p f := by
|
||||
cases o <;> simp_all [Function.comp_def]
|
||||
cases o <;> simp_all
|
||||
|
||||
@[grind =] theorem attach_bind {o : Option α} {f : α → Option β} :
|
||||
(o.bind f).attach =
|
||||
@@ -289,7 +289,7 @@ theorem toArray_pmap {p : α → Prop} {o : Option α} {f : (a : α) → p a →
|
||||
cases o with
|
||||
| none => simp
|
||||
| some a =>
|
||||
simp only [attach_some, eq_mp_eq_cast, id_eq, pbind_some]
|
||||
simp only [attach_some, pbind_some]
|
||||
rw [attach_congr pfilter_some]
|
||||
split <;> simp [*]
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ theorem join_ne_none' : ¬x.join = none ↔ ∃ z, x = some (some z) :=
|
||||
join_ne_none
|
||||
|
||||
theorem join_eq_none_iff : o.join = none ↔ o = none ∨ o = some none :=
|
||||
match o with | none | some none | some (some _) => by simp [bind_id_eq_join]
|
||||
match o with | none | some none | some (some _) => by simp
|
||||
|
||||
@[deprecated join_eq_none_iff (since := "2025-04-10")]
|
||||
abbrev join_eq_none := @join_eq_none_iff
|
||||
@@ -302,7 +302,7 @@ abbrev map_eq_some := @map_eq_some_iff
|
||||
abbrev map_eq_some' := @map_eq_some_iff
|
||||
|
||||
@[simp] theorem map_eq_none_iff : x.map f = none ↔ x = none := by
|
||||
cases x <;> simp [map_none, map_some, eq_self_iff_true]
|
||||
cases x <;> simp [map_none, map_some]
|
||||
|
||||
@[deprecated map_eq_none_iff (since := "2025-04-10")]
|
||||
abbrev map_eq_none := @map_eq_none_iff
|
||||
|
||||
@@ -110,7 +110,7 @@ theorem forIn'_id_yield_eq_pelim
|
||||
|
||||
theorem forIn'_join [Monad m] [LawfulMonad m] (b : β) (o : Option (Option α))
|
||||
(f : (a : α) → a ∈ o.join → β → m (ForInStep β)) :
|
||||
forIn' o.join b f = forIn' o b (fun o' ho' b => ForInStep.yield <$> forIn' o' b (fun a ha b' => f a (by simp_all [join_eq_some_iff]) b')) := by
|
||||
forIn' o.join b f = forIn' o b (fun o' ho' b => ForInStep.yield <$> forIn' o' b (fun a ha b' => f a (by simp_all) b')) := by
|
||||
cases o with
|
||||
| none => simp
|
||||
| some a => simpa using forIn'_congr rfl rfl (by simp)
|
||||
|
||||
@@ -351,7 +351,7 @@ theorem compareOfLessAndEq_eq_swap_of_lt_iff_not_gt_and_ne {α : Type u} [LT α]
|
||||
simp only [h', this, ↓reduceIte, Ordering.swap_eq]
|
||||
· rename_i h' h''
|
||||
replace h' := (h y x).mpr ⟨h', Ne.symm h''⟩
|
||||
simp only [h', Ne.symm h'', ↓reduceIte, Ordering.swap_lt]
|
||||
simp only [h', ↓reduceIte, Ordering.swap_lt]
|
||||
|
||||
theorem lt_iff_not_gt_and_ne_of_antisymm_of_total_of_not_le
|
||||
{α : Type u} [LT α] [LE α] [DecidableLT α] [DecidableEq α]
|
||||
|
||||
@@ -716,7 +716,7 @@ theorem ISize.shiftLeft_or {a b c : ISize} : (a ||| b) <<< c = (a <<< c) ||| (b
|
||||
@[simp] theorem Int32.neg_one_shiftLeft_or_shiftLeft {a b : Int32} :
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp [← Int32.shiftLeft_or]
|
||||
@[simp] theorem Int64.neg_one_shiftLeft_or_shiftLeft {a b : Int8} :
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp [← Int64.shiftLeft_or]
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp
|
||||
@[simp] theorem ISize.neg_one_shiftLeft_or_shiftLeft {a b : ISize} :
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp [← ISize.shiftLeft_or]
|
||||
|
||||
|
||||
@@ -1622,23 +1622,23 @@ theorem ISize.toInt_div_of_ne_right (a b : ISize) (h : b ≠ -1) : (a / b).toInt
|
||||
exact Or.inr (by simpa [← toBitVec_inj] using h)
|
||||
|
||||
theorem Int8.toInt16_ne_minValue (a : Int8) : a.toInt16 ≠ Int16.minValue :=
|
||||
have := a.le_toInt; by simp [← Int16.toInt_inj, Int16.toInt_minValue]; omega
|
||||
have := a.le_toInt; by simp [← Int16.toInt_inj]; omega
|
||||
theorem Int8.toInt32_ne_minValue (a : Int8) : a.toInt32 ≠ Int32.minValue :=
|
||||
have := a.le_toInt; by simp [← Int32.toInt_inj, Int32.toInt_minValue]; omega
|
||||
have := a.le_toInt; by simp [← Int32.toInt_inj]; omega
|
||||
theorem Int8.toInt64_ne_minValue (a : Int8) : a.toInt64 ≠ Int64.minValue :=
|
||||
have := a.le_toInt; by simp [← Int64.toInt_inj, Int64.toInt_minValue]; omega
|
||||
have := a.le_toInt; by simp [← Int64.toInt_inj]; omega
|
||||
theorem Int8.toISize_ne_minValue (a : Int8) : a.toISize ≠ ISize.minValue :=
|
||||
have := a.le_toInt; have := ISize.toInt_minValue_le; by simp [← ISize.toInt_inj]; omega
|
||||
|
||||
theorem Int16.toInt32_ne_minValue (a : Int16) : a.toInt32 ≠ Int32.minValue :=
|
||||
have := a.le_toInt; by simp [← Int32.toInt_inj, Int32.toInt_minValue]; omega
|
||||
have := a.le_toInt; by simp [← Int32.toInt_inj]; omega
|
||||
theorem Int16.toInt64_ne_minValue (a : Int16) : a.toInt64 ≠ Int64.minValue :=
|
||||
have := a.le_toInt; by simp [← Int64.toInt_inj, Int64.toInt_minValue]; omega
|
||||
have := a.le_toInt; by simp [← Int64.toInt_inj]; omega
|
||||
theorem Int16.toISize_ne_minValue (a : Int16) : a.toISize ≠ ISize.minValue :=
|
||||
have := a.le_toInt; have := ISize.toInt_minValue_le; by simp [← ISize.toInt_inj]; omega
|
||||
|
||||
theorem Int32.toInt64_ne_minValue (a : Int32) : a.toInt64 ≠ Int64.minValue :=
|
||||
have := a.le_toInt; by simp [← Int64.toInt_inj, Int64.toInt_minValue]; omega
|
||||
have := a.le_toInt; by simp [← Int64.toInt_inj]; omega
|
||||
theorem Int32.toISize_ne_minValue (a : Int32) (ha : a ≠ minValue) : a.toISize ≠ ISize.minValue := by
|
||||
have := a.le_toInt
|
||||
have := ISize.toInt_minValue_le
|
||||
|
||||
@@ -163,7 +163,7 @@ def toUTF8 (a : @& String) : ByteArray :=
|
||||
|
||||
@[simp] theorem size_toUTF8 (s : String) : s.toUTF8.size = s.utf8ByteSize := by
|
||||
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, utf8ByteSize.go, Nat.add_comm, *]
|
||||
|
||||
/--
|
||||
Accesses the indicated byte in the UTF-8 encoding of a string.
|
||||
|
||||
@@ -1231,7 +1231,7 @@ theorem USize.shiftLeft_add {a b c : USize} (hb : b < USize.ofNat System.Platfor
|
||||
@[simp] theorem UInt32.neg_one_shiftLeft_or_shiftLeft {a b : UInt32} :
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp [← UInt32.shiftLeft_or]
|
||||
@[simp] theorem UInt64.neg_one_shiftLeft_or_shiftLeft {a b : UInt8} :
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp [← UInt64.shiftLeft_or]
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp
|
||||
@[simp] theorem USize.neg_one_shiftLeft_or_shiftLeft {a b : USize} :
|
||||
(-1) <<< b ||| a <<< b = (-1) <<< b := by simp [← USize.shiftLeft_or]
|
||||
|
||||
|
||||
@@ -1765,7 +1765,7 @@ theorem USize.le_iff_toFin_le {a b : USize} : a ≤ b ↔ a.toFin ≤ b.toFin :=
|
||||
simp [lt_iff_toNat_lt, UInt32.lt_iff_toNat_lt]
|
||||
@[simp] theorem USize.toUInt32_lt {a b : USize} : a.toUInt32 < b.toUInt32 ↔ a % 4294967296 < b % 4294967296 := by
|
||||
rw [← UInt32.toUSize_lt, toUSize_toUInt32]
|
||||
simp [lt_iff_toNat_lt, UInt32.lt_iff_toNat_lt]
|
||||
simp [lt_iff_toNat_lt]
|
||||
|
||||
@[simp] theorem UInt64.toUSize_lt {a b : UInt64} : a.toUSize < b.toUSize ↔ a % UInt64.ofNat USize.size < b % UInt64.ofNat USize.size := by
|
||||
simp only [USize.lt_iff_toNat_lt, toNat_toUSize, lt_iff_toNat_lt, UInt64.toNat_mod, toNat_ofNat', Nat.reducePow]
|
||||
@@ -1815,10 +1815,10 @@ theorem USize.le_iff_toFin_le {a b : USize} : a ≤ b ↔ a.toFin ≤ b.toFin :=
|
||||
simp [le_iff_toNat_le, UInt32.le_iff_toNat_le]
|
||||
@[simp] theorem USize.toUInt32_le {a b : USize} : a.toUInt32 ≤ b.toUInt32 ↔ a % 4294967296 ≤ b % 4294967296 := by
|
||||
rw [← UInt32.toUSize_le, toUSize_toUInt32]
|
||||
simp [le_iff_toNat_le, UInt32.le_iff_toNat_le]
|
||||
simp [le_iff_toNat_le]
|
||||
|
||||
@[simp] theorem UInt64.toUSize_le {a b : UInt64} : a.toUSize ≤ b.toUSize ↔ a % UInt64.ofNat USize.size ≤ b % UInt64.ofNat USize.size := by
|
||||
simp only [USize.le_iff_toNat_le, toNat_toUSize, le_iff_toNat_le, UInt64.toNat_mod, UInt64.reduceToNat]
|
||||
simp only [USize.le_iff_toNat_le, toNat_toUSize, le_iff_toNat_le, UInt64.toNat_mod]
|
||||
cases System.Platform.numBits_eq <;> simp_all [USize.size]
|
||||
|
||||
@[simp] theorem UInt16.toUInt8_neg (a : UInt16) : (-a).toUInt8 = -a.toUInt8 := UInt8.toBitVec_inj.1 (by simp)
|
||||
@@ -1927,7 +1927,7 @@ theorem USize.sub_eq_add_mul (a b : USize) : a - b = a + USize.ofNatLT (USize.si
|
||||
@[simp] theorem UInt16.ofNat_usizeSize_sub_one : UInt16.ofNat (USize.size - 1) = 65535 := UInt16.toNat.inj (by simp)
|
||||
@[simp] theorem UInt32.ofNat_usizeSize_sub_one : UInt32.ofNat (USize.size - 1) = 4294967295 := UInt32.toNat.inj (by simp)
|
||||
@[simp] theorem USize.ofNat_uInt64Size_sub_one : USize.ofNat (UInt64.size - 1) = USize.ofNatLT (USize.size - 1) (Nat.sub_one_lt (Nat.pos_iff_ne_zero.1 size_pos)) :=
|
||||
USize.toNat.inj (by simp [USize.toNat_ofNat])
|
||||
USize.toNat.inj (by simp)
|
||||
|
||||
@[simp] theorem UInt16.toUInt8_sub (a b : UInt16) : (a - b).toUInt8 = a.toUInt8 - b.toUInt8 := by
|
||||
simp [UInt16.sub_eq_add_neg, UInt8.sub_eq_add_neg]
|
||||
@@ -2093,11 +2093,11 @@ theorem USize.ofNat_eq_iff_mod_eq_toNat (a : Nat) (b : USize) : USize.ofNat a =
|
||||
@[simp] theorem USize.ofInt_one : ofInt 1 = 1 := by
|
||||
rcases System.Platform.numBits_eq with h | h <;>
|
||||
· apply USize.toNat_inj.mp
|
||||
simp_all [USize.ofInt, USize.ofNat, size, toNat]
|
||||
simp_all [USize.ofInt, USize.ofNat, toNat]
|
||||
@[simp] theorem USize.ofInt_neg_one : ofInt (-1) = -1 := by
|
||||
rcases System.Platform.numBits_eq with h | h <;>
|
||||
· apply USize.toNat_inj.mp
|
||||
simp_all [USize.ofInt, USize.ofNat, size, toNat]
|
||||
simp_all [USize.ofInt, USize.ofNat, toNat]
|
||||
|
||||
@[simp] theorem UInt8.ofNat_add (a b : Nat) : UInt8.ofNat (a + b) = UInt8.ofNat a + UInt8.ofNat b := by
|
||||
simp [UInt8.ofNat_eq_iff_mod_eq_toNat]
|
||||
|
||||
@@ -292,7 +292,7 @@ See however `foldl_subtype` below.
|
||||
theorem foldl_attach {xs : Vector α n} {f : β → α → β} {b : β} :
|
||||
xs.attach.foldl (fun acc t => f acc t.1) b = xs.foldl f b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldl_attach]
|
||||
simp
|
||||
|
||||
/--
|
||||
If we fold over `l.attach` with a function that ignores the membership predicate,
|
||||
@@ -307,7 +307,7 @@ See however `foldr_subtype` below.
|
||||
theorem foldr_attach {xs : Vector α n} {f : α → β → β} {b : β} :
|
||||
xs.attach.foldr (fun t acc => f t.1 acc) b = xs.foldr f b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldr_attach]
|
||||
simp
|
||||
|
||||
@[grind =]
|
||||
theorem attach_map {xs : Vector α n} {f : α → β} :
|
||||
@@ -378,7 +378,7 @@ theorem pmap_append' {p : α → Prop} {f : ∀ a : α, p a → β} {xs : Vector
|
||||
{H : ∀ (a : α), a ∈ xs ++ ys → P a} :
|
||||
(xs ++ ys).attachWith P H = xs.attachWith P (fun a h => H a (mem_append_left ys h)) ++
|
||||
ys.attachWith P (fun a h => H a (mem_append_right xs h)) := by
|
||||
simp [attachWith, attach_append, map_pmap, pmap_append]
|
||||
simp [attachWith]
|
||||
|
||||
@[simp, grind =] theorem pmap_reverse {P : α → Prop} {f : (a : α) → P a → β} {xs : Vector α n}
|
||||
(H : ∀ (a : α), a ∈ xs.reverse → P a) :
|
||||
@@ -439,7 +439,7 @@ theorem back?_attach {xs : Vector α n} :
|
||||
theorem countP_attach {xs : Vector α n} {p : α → Bool} :
|
||||
xs.attach.countP (fun a : {x // x ∈ xs} => p a) = xs.countP p := by
|
||||
cases xs
|
||||
simp [Function.comp_def]
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem countP_attachWith {p : α → Prop} {q : α → Bool} {xs : Vector α n} {H : ∀ a ∈ xs, p a} :
|
||||
|
||||
@@ -77,7 +77,7 @@ theorem countP_le_size {xs : Vector α n} : countP p xs ≤ n := by
|
||||
simp
|
||||
|
||||
theorem countP_replicate {a : α} {n : Nat} : countP p (replicate n a) = if p a then n else 0 := by
|
||||
simp only [replicate_eq_mk_replicate, countP_cast, countP_mk]
|
||||
simp only [replicate_eq_mk_replicate, countP_mk]
|
||||
simp [Array.countP_replicate]
|
||||
|
||||
@[deprecated countP_replicate (since := "2025-03-18")]
|
||||
@@ -91,7 +91,7 @@ theorem boole_getElem_le_countP {p : α → Bool} {xs : Vector α n} (h : i < n)
|
||||
theorem countP_set {p : α → Bool} {xs : Vector α n} {a : α} (h : i < n) :
|
||||
(xs.set i a).countP p = xs.countP p - (if p xs[i] then 1 else 0) + (if p a then 1 else 0) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.countP_set, h]
|
||||
simp [Array.countP_set]
|
||||
|
||||
@[simp] theorem countP_true : (countP fun (_ : α) => true) = (fun (_ : Vector α n) => n) := by
|
||||
funext xs
|
||||
@@ -177,12 +177,12 @@ theorem count_le_count_push {a b : α} {xs : Vector α n} : count a xs ≤ count
|
||||
theorem boole_getElem_le_count {a : α} {xs : Vector α n} (h : i < n) :
|
||||
(if xs[i] == a then 1 else 0) ≤ xs.count a := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.boole_getElem_le_count, h]
|
||||
simp [Array.boole_getElem_le_count]
|
||||
|
||||
theorem count_set {a b : α} {xs : Vector α n} (h : i < n) :
|
||||
(xs.set i a).count b = xs.count b - (if xs[i] == b then 1 else 0) + (if a == b then 1 else 0) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.count_set, h]
|
||||
simp [Array.count_set]
|
||||
|
||||
@[simp] theorem count_cast {xs : Vector α n} : (xs.cast h).count a = xs.count a := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
@@ -203,7 +203,7 @@ theorem count_singleton_self {a : α} : count a #v[a] = 1 := by simp
|
||||
@[simp]
|
||||
theorem count_pos_iff {a : α} {xs : Vector α n} : 0 < count a xs ↔ a ∈ xs := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.count_pos_iff, beq_iff_eq, exists_eq_right]
|
||||
simp [Array.count_pos_iff]
|
||||
|
||||
@[simp] theorem one_le_count_iff {a : α} {xs : Vector α n} : 1 ≤ count a xs ↔ a ∈ xs :=
|
||||
count_pos_iff
|
||||
@@ -222,14 +222,14 @@ theorem count_eq_size {xs : Vector α n} : count a xs = n ↔ ∀ b ∈ xs, a =
|
||||
simp [Array.count_eq_size]
|
||||
|
||||
@[simp] theorem count_replicate_self {a : α} {n : Nat} : count a (replicate n a) = n := by
|
||||
simp only [replicate_eq_mk_replicate, count_cast, count_mk]
|
||||
simp only [replicate_eq_mk_replicate, count_mk]
|
||||
simp
|
||||
|
||||
@[deprecated count_replicate_self (since := "2025-03-18")]
|
||||
abbrev count_mkVector_self := @count_replicate_self
|
||||
|
||||
theorem count_replicate {a b : α} {n : Nat} : count a (replicate n b) = if b == a then n else 0 := by
|
||||
simp only [replicate_eq_mk_replicate, count_cast, count_mk]
|
||||
simp only [replicate_eq_mk_replicate, count_mk]
|
||||
simp [Array.count_replicate]
|
||||
|
||||
@[deprecated count_replicate (since := "2025-03-18")]
|
||||
|
||||
@@ -42,7 +42,7 @@ theorem getElem?_eraseIdx_of_lt {xs : Vector α n} {i : Nat} (h : i < n) {j : Na
|
||||
theorem getElem?_eraseIdx_of_ge {xs : Vector α n} {i : Nat} (h : i < n) {j : Nat} (h' : i ≤ j) :
|
||||
(xs.eraseIdx i)[j]? = xs[j + 1]? := by
|
||||
rw [getElem?_eraseIdx]
|
||||
simp only [dite_eq_ite, ite_eq_right_iff]
|
||||
simp only [ite_eq_right_iff]
|
||||
intro h'
|
||||
omega
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ theorem extract_append_extract {xs : Vector α n} {i j k : Nat} :
|
||||
theorem push_extract_getElem {xs : Vector α n} {i j : Nat} (h : j < n) :
|
||||
(xs.extract i j).push xs[j] = (xs.extract (min i j) (j + 1)).cast (by omega) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
theorem extract_succ_right {xs : Vector α n} {i j : Nat} (w : i < j + 1) (h : j < n) :
|
||||
xs.extract i (j + 1) = ((xs.extract i j).push xs[j]).cast (by omega) := by
|
||||
@@ -67,7 +67,7 @@ theorem extract_sub_one {xs : Vector α n} {i j : Nat} (h : j < n) :
|
||||
theorem getElem?_extract_of_lt {xs : Vector α n} {i j k : Nat} (h : k < min j n - i) :
|
||||
(xs.extract i j)[k]? = some (xs[i + k]'(by omega)) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [getElem?_extract, h]
|
||||
simp [h]
|
||||
|
||||
theorem getElem?_extract_of_succ {xs : Vector α n} {j : Nat} :
|
||||
(xs.extract 0 (j + 1))[j]? = xs[j]? := by
|
||||
@@ -161,7 +161,7 @@ theorem mem_extract_iff_getElem {xs : Vector α n} {a : α} {i j : Nat} :
|
||||
theorem set_eq_push_extract_append_extract {xs : Vector α n} {i : Nat} (h : i < n) {a : α} :
|
||||
xs.set i a = ((xs.extract 0 i).push a ++ (xs.extract (i + 1) n)).cast (by omega) := by
|
||||
rcases xs with ⟨as, rfl⟩
|
||||
simp [Array.set_eq_push_extract_append_extract, h]
|
||||
simp [Array.set_eq_push_extract_append_extract]
|
||||
|
||||
@[grind =]
|
||||
theorem extract_reverse {xs : Vector α n} {i j : Nat} :
|
||||
|
||||
@@ -30,7 +30,7 @@ open Nat
|
||||
|
||||
@[simp, grind] theorem findSome?_empty : (#v[] : Vector α 0).findSome? f = none := rfl
|
||||
@[simp, grind] theorem findSome?_push {xs : Vector α n} : (xs.push a).findSome? f = (xs.findSome? f).or (f a) := by
|
||||
cases xs; simp [List.findSome?_append]
|
||||
cases xs; simp
|
||||
|
||||
@[grind]
|
||||
theorem findSome?_singleton {a : α} {f : α → Option β} : #v[a].findSome? f = f a := by
|
||||
@@ -124,7 +124,7 @@ theorem getElem_zero_flatten.proof {xss : Vector (Vector α m) n} (h : 0 < n * m
|
||||
theorem getElem_zero_flatten {xss : Vector (Vector α m) n} (h : 0 < n * m) :
|
||||
(flatten xss)[0] = (xss.findSome? fun xs => xs[0]?).get (getElem_zero_flatten.proof h) := by
|
||||
have t := getElem?_zero_flatten (xss := xss)
|
||||
simp [getElem?_eq_getElem, h] at t
|
||||
simp [h] at t
|
||||
simp [← t]
|
||||
|
||||
@[grind =]
|
||||
@@ -251,7 +251,7 @@ theorem find?_flatten_eq_none_iff {xs : Vector (Vector α m) n} {p : α → Bool
|
||||
@[simp, grind =] theorem find?_flatMap {xs : Vector α n} {f : α → Vector β m} {p : β → Bool} :
|
||||
(xs.flatMap f).find? p = xs.findSome? (fun x => (f x).find? p) := by
|
||||
cases xs
|
||||
simp [Array.find?_flatMap, Array.flatMap_toArray]
|
||||
simp [Array.find?_flatMap]
|
||||
|
||||
|
||||
theorem find?_flatMap_eq_none_iff {xs : Vector α n} {f : α → Vector β m} {p : β → Bool} :
|
||||
|
||||
@@ -98,22 +98,22 @@ theorem getElem_insertIdx {xs : Vector α n} {x : α} {i k : Nat} (w : i ≤ n)
|
||||
else
|
||||
xs[k-1] := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.getElem_insertIdx, w]
|
||||
simp [Array.getElem_insertIdx]
|
||||
|
||||
theorem getElem_insertIdx_of_lt {xs : Vector α n} {x : α} {i k : Nat} (w : i ≤ n) (h : k < i) :
|
||||
(xs.insertIdx i x)[k] = xs[k] := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.getElem_insertIdx, w, h]
|
||||
simp [Array.getElem_insertIdx, h]
|
||||
|
||||
theorem getElem_insertIdx_self {xs : Vector α n} {x : α} {i : Nat} (w : i ≤ n) :
|
||||
(xs.insertIdx i x)[i] = x := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.getElem_insertIdx, w]
|
||||
simp [Array.getElem_insertIdx]
|
||||
|
||||
theorem getElem_insertIdx_of_gt {xs : Vector α n} {x : α} {i k : Nat} (w : k ≤ n) (h : k > i) :
|
||||
(xs.insertIdx i x)[k] = xs[k - 1] := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.getElem_insertIdx, w, h]
|
||||
simp [Array.getElem_insertIdx]
|
||||
rw [dif_neg (by omega), dif_neg (by omega)]
|
||||
|
||||
@[grind =]
|
||||
@@ -127,7 +127,7 @@ theorem getElem?_insertIdx {xs : Vector α n} {x : α} {i k : Nat} (h : i ≤ n)
|
||||
else
|
||||
xs[k-1]? := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.getElem?_insertIdx, h]
|
||||
simp [Array.getElem?_insertIdx]
|
||||
|
||||
theorem getElem?_insertIdx_of_lt {xs : Vector α n} {x : α} {i k : Nat} (w : i ≤ n) (h : k < i) :
|
||||
(xs.insertIdx i x)[k]? = xs[k]? := by
|
||||
|
||||
@@ -55,7 +55,7 @@ theorem toArray_mk {xs : Array α} (h : xs.size = n) : (Vector.mk xs h).toArray
|
||||
|
||||
@[simp] theorem push_mk {xs : Array α} {size : xs.size = n} :
|
||||
(Vector.mk xs size).push =
|
||||
fun x => Vector.mk (xs.push x) (by simp [size, Nat.succ_eq_add_one]) := rfl
|
||||
fun x => Vector.mk (xs.push x) (by simp [size]) := rfl
|
||||
|
||||
@[simp] theorem pop_mk {xs : Array α} {size : xs.size = n} :
|
||||
(Vector.mk xs size).pop = Vector.mk xs.pop (by simp [size]) := rfl
|
||||
@@ -96,14 +96,14 @@ theorem toArray_mk {xs : Array α} (h : xs.size = n) : (Vector.mk xs h).toArray
|
||||
(Vector.mk xs h).eraseIdx i h' = Vector.mk (xs.eraseIdx i) (by simp [h]) := rfl
|
||||
|
||||
@[simp] theorem eraseIdx!_mk {xs : Array α} {h : xs.size = n} {i} (hi : i < n) :
|
||||
(Vector.mk xs h).eraseIdx! i = Vector.mk (xs.eraseIdx i) (by simp [h, hi]) := by
|
||||
(Vector.mk xs h).eraseIdx! i = Vector.mk (xs.eraseIdx i) (by simp [h]) := by
|
||||
simp [Vector.eraseIdx!, hi]
|
||||
|
||||
@[simp] theorem insertIdx_mk {xs : Array α} {h : xs.size = n} {i x} (h') :
|
||||
(Vector.mk xs h).insertIdx i x h' = Vector.mk (xs.insertIdx i x) (by simp [h, h']) := rfl
|
||||
(Vector.mk xs h).insertIdx i x h' = Vector.mk (xs.insertIdx i x) (by simp [h]) := rfl
|
||||
|
||||
@[simp] theorem insertIdx!_mk {xs : Array α} {h : xs.size = n} {i x} (hi : i ≤ n) :
|
||||
(Vector.mk xs h).insertIdx! i x = Vector.mk (xs.insertIdx i x) (by simp [h, hi]) := by
|
||||
(Vector.mk xs h).insertIdx! i x = Vector.mk (xs.insertIdx i x) (by simp [h]) := by
|
||||
simp [Vector.insertIdx!, hi]
|
||||
|
||||
@[simp] theorem cast_mk {xs : Array α} {h : xs.size = n} {h' : n = m} :
|
||||
@@ -367,7 +367,7 @@ theorem toArray_mapM_go [Monad m] [LawfulMonad m] {f : α → m β} {xs : Vector
|
||||
@[simp, grind] theorem toArray_singleton {x : α} : (Vector.singleton x).toArray = #[x] := rfl
|
||||
|
||||
@[simp, grind] theorem toArray_swap {xs : Vector α n} {i j} (hi hj) : (xs.swap i j).toArray =
|
||||
xs.toArray.swap i j (by simp [hi, hj]) (by simp [hi, hj]) := rfl
|
||||
xs.toArray.swap i j (by simp [hj]) (by simp [hi]) := rfl
|
||||
|
||||
@[simp, grind] theorem toArray_swapIfInBounds {xs : Vector α n} {i j} :
|
||||
(xs.swapIfInBounds i j).toArray = xs.toArray.swapIfInBounds i j := rfl
|
||||
@@ -539,14 +539,14 @@ theorem toList_eraseIdx {xs : Vector α n} {i} (h) :
|
||||
|
||||
@[simp] theorem toList_eraseIdx! {xs : Vector α n} {i} (hi : i < n) :
|
||||
(xs.eraseIdx! i).toList = xs.toList.eraseIdx i := by
|
||||
cases xs; simp_all [Array.eraseIdx!]
|
||||
cases xs; simp_all
|
||||
|
||||
theorem toList_insertIdx {xs : Vector α n} {i x} (h) :
|
||||
(xs.insertIdx i x h).toList = xs.toList.insertIdx i x := by simp [toList]
|
||||
|
||||
theorem toList_insertIdx! {xs : Vector α n} {i x} (hi : i ≤ n) :
|
||||
(xs.insertIdx! i x).toList = xs.toList.insertIdx i x := by
|
||||
cases xs; simp_all [Array.insertIdx!]
|
||||
cases xs; simp_all
|
||||
|
||||
theorem toList_cast {xs : Vector α n} (h : n = m) :
|
||||
(xs.cast h).toList = xs.toList := rfl
|
||||
@@ -593,7 +593,7 @@ theorem toList_swap {xs : Vector α n} {i j} (hi hj) :
|
||||
(xs.swap i j).toList = (xs.toList.set i xs[j]).set j xs[i] := rfl
|
||||
|
||||
@[simp] theorem toList_take {xs : Vector α n} {i} : (xs.take i).toList = xs.toList.take i := by
|
||||
simp [toList, List.take_of_length_le]
|
||||
simp [toList]
|
||||
|
||||
@[simp] theorem toList_zipWith {f : α → β → γ} {as : Vector α n} {bs : Vector β n} :
|
||||
(Vector.zipWith f as bs).toList = List.zipWith f as.toList bs.toList := by
|
||||
@@ -822,7 +822,7 @@ theorem none_eq_getElem?_iff {xs : Vector α n} {i : Nat} : none = xs[i]? ↔ n
|
||||
simp
|
||||
|
||||
theorem getElem?_eq_none {xs : Vector α n} (h : n ≤ i) : xs[i]? = none := by
|
||||
simp [getElem?_eq_none_iff, h]
|
||||
simp [h]
|
||||
|
||||
-- This is a more aggressive pattern than for `List/Array.getElem?_eq_none`, because
|
||||
-- `length/size` won't appear.
|
||||
@@ -854,16 +854,16 @@ theorem getElem_eq_iff {xs : Vector α n} {i : Nat} {h : i < n} : xs[i] = x ↔
|
||||
exact ⟨fun w => ⟨h, w⟩, fun h => h.2⟩
|
||||
|
||||
theorem getElem_eq_getElem?_get {xs : Vector α n} {i : Nat} (h : i < n) :
|
||||
xs[i] = xs[i]?.get (by simp [getElem?_eq_getElem, h]) := by
|
||||
simp [getElem_eq_iff]
|
||||
xs[i] = xs[i]?.get (by simp [h]) := by
|
||||
simp
|
||||
|
||||
theorem getD_getElem? {xs : Vector α n} {i : Nat} {d : α} :
|
||||
xs[i]?.getD d = if p : i < n then xs[i]'p else d := by
|
||||
if h : i < n then
|
||||
simp [h, getElem?_def]
|
||||
simp [h]
|
||||
else
|
||||
have p : i ≥ n := Nat.le_of_not_gt h
|
||||
simp [getElem?_eq_none p, h]
|
||||
simp [h]
|
||||
|
||||
@[simp] theorem getElem?_empty {i : Nat} : (#v[] : Vector α 0)[i]? = none := rfl
|
||||
|
||||
@@ -880,7 +880,7 @@ set_option linter.indexVariables false in
|
||||
theorem getElem_push {xs : Vector α n} {x : α} {i : Nat} (h : i < n + 1) :
|
||||
(xs.push x)[i] = if h : i < n then xs[i] else x := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.getElem_push, h]
|
||||
simp [Array.getElem_push]
|
||||
|
||||
theorem getElem?_push {xs : Vector α n} {x : α} {i : Nat} : (xs.push x)[i]? = if i = n then some x else xs[i]? := by
|
||||
simp [getElem?_def, getElem_push]
|
||||
@@ -1220,12 +1220,12 @@ instance [BEq α] [LawfulBEq α] (a : α) (as : Vector α n) : Decidable (a ∈
|
||||
@[simp] theorem any_push [BEq α] {as : Vector α n} {a : α} {p : α → Bool} :
|
||||
(as.push a).any p = (as.any p || p a) := by
|
||||
rcases as with ⟨as, rfl⟩
|
||||
simp [Array.any_push]
|
||||
simp
|
||||
|
||||
@[simp] theorem all_push [BEq α] {as : Vector α n} {a : α} {p : α → Bool} :
|
||||
(as.push a).all p = (as.all p && p a) := by
|
||||
rcases as with ⟨as, rfl⟩
|
||||
simp [Array.all_push]
|
||||
simp
|
||||
|
||||
@[simp] theorem contains_push [BEq α] {xs : Vector α n} {a : α} {b : α} :
|
||||
(xs.push a).contains b = (xs.contains b || b == a) := by
|
||||
@@ -1237,7 +1237,7 @@ instance [BEq α] [LawfulBEq α] (a : α) (as : Vector α n) : Decidable (a ∈
|
||||
@[grind] theorem getElem_set {xs : Vector α n} {i : Nat} {x : α} (hi : i < n) {j : Nat} (hj : j < n) :
|
||||
(xs.set i x hi)[j] = if i = j then x else xs[j] := by
|
||||
cases xs
|
||||
split <;> simp_all [Array.getElem_set]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp] theorem getElem_set_self {xs : Vector α n} {i : Nat} {x : α} (hi : i < n) :
|
||||
(xs.set i x hi)[i] = x := by simp [getElem_set]
|
||||
@@ -1251,10 +1251,10 @@ abbrev getElem_set_eq := @getElem_set_self
|
||||
@[grind] theorem getElem?_set {xs : Vector α n} {x : α} (hi : i < n) :
|
||||
(xs.set i x hi)[j]? = if i = j then some x else xs[j]? := by
|
||||
cases xs
|
||||
split <;> simp_all [getElem?_eq_getElem, getElem_set]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp] theorem getElem?_set_self {xs : Vector α n} {x : α} (hi : i < n) :
|
||||
(xs.set i x hi)[i]? = some x := by simp [getElem?_eq_getElem, hi]
|
||||
(xs.set i x hi)[i]? = some x := by simp [hi]
|
||||
|
||||
@[simp] theorem getElem?_set_ne {xs : Vector α n} {x : α} (hi : i < n) (h : i ≠ j) :
|
||||
(xs.set i x hi)[j]? = xs[j]? := by
|
||||
@@ -1298,10 +1298,10 @@ theorem mem_or_eq_of_mem_set {xs : Vector α n} {i : Nat} {a b : α} {hi : i < n
|
||||
@[grind] theorem getElem_setIfInBounds {xs : Vector α n} {x : α} (hj : j < n) :
|
||||
(xs.setIfInBounds i x)[j] = if i = j then x else xs[j] := by
|
||||
cases xs
|
||||
split <;> simp_all [Array.getElem_setIfInBounds]
|
||||
split <;> simp_all
|
||||
|
||||
@[simp] theorem getElem_setIfInBounds_self {xs : Vector α n} {x : α} (hi : i < n) :
|
||||
(xs.setIfInBounds i x)[i] = x := by simp [getElem_setIfInBounds, hi]
|
||||
(xs.setIfInBounds i x)[i] = x := by simp [getElem_setIfInBounds]
|
||||
|
||||
@[deprecated getElem_setIfInBounds_self (since := "2024-12-12")]
|
||||
abbrev getElem_setIfInBounds_eq := @getElem_setIfInBounds_self
|
||||
@@ -1318,7 +1318,7 @@ theorem getElem?_setIfInBounds_self {xs : Vector α n} {x : α} :
|
||||
(xs.setIfInBounds i x)[i]? = if i < n then some x else none := by simp [getElem?_setIfInBounds]
|
||||
|
||||
@[simp] theorem getElem?_setIfInBounds_self_of_lt {xs : Vector α n} {x : α} (h : i < n) :
|
||||
(xs.setIfInBounds i x)[i]? = some x := by simp [getElem?_setIfInBounds, h]
|
||||
(xs.setIfInBounds i x)[i]? = some x := by simp [h]
|
||||
|
||||
@[simp] theorem getElem?_setIfInBounds_ne {xs : Vector α n} {x : α} (h : i ≠ j) :
|
||||
(xs.setIfInBounds i x)[j]? = xs[j]? := by simp [getElem?_setIfInBounds, h]
|
||||
@@ -1669,7 +1669,7 @@ theorem getElem_append {xs : Vector α n} {ys : Vector α m} (hi : i < n + m) :
|
||||
(xs ++ ys)[i] = if h : i < n then xs[i] else ys[i - n] := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
rcases ys with ⟨ys, rfl⟩
|
||||
simp [Array.getElem_append, hi]
|
||||
simp [Array.getElem_append]
|
||||
|
||||
@[simp]
|
||||
theorem getElem_append_left {xs : Vector α n} {ys : Vector α m} (hi : i < n) :
|
||||
@@ -1683,7 +1683,7 @@ theorem getElem_append_right {xs : Vector α n} {ys : Vector α m} (h : i < n +
|
||||
theorem getElem?_append_left {xs : Vector α n} {ys : Vector α m} (hn : i < n) :
|
||||
(xs ++ ys)[i]? = xs[i]? := by
|
||||
have hn' : i < n + m := by omega
|
||||
simp_all [getElem?_eq_getElem, getElem_append]
|
||||
simp_all
|
||||
|
||||
theorem getElem?_append_right {xs : Vector α n} {ys : Vector α m} (h : n ≤ i) :
|
||||
(xs ++ ys)[i]? = ys[i - n]? := by
|
||||
@@ -2036,7 +2036,7 @@ theorem flatMap_singleton {f : α → Vector β m} {x : α} : #v[x].flatMap f =
|
||||
(xs ++ ys).flatMap f = (xs.flatMap f ++ ys.flatMap f).cast (by simp [Nat.add_mul]) := by
|
||||
rcases xs with ⟨xs⟩
|
||||
rcases ys with ⟨ys⟩
|
||||
simp [flatMap_def, flatten_append]
|
||||
simp [flatMap_def]
|
||||
|
||||
theorem flatMap_assoc {xs : Vector α n} {f : α → Vector β m} {g : β → Vector γ k} :
|
||||
(xs.flatMap f).flatMap g = (xs.flatMap fun x => (f x).flatMap g).cast (by simp [Nat.mul_assoc]) := by
|
||||
@@ -2107,7 +2107,7 @@ abbrev getElem_mkVector := @getElem_replicate
|
||||
abbrev getElem?_mkVector := @getElem?_replicate
|
||||
|
||||
@[simp] theorem getElem?_replicate_of_lt {n : Nat} {i : Nat} (h : i < n) : (replicate n a)[i]? = some a := by
|
||||
simp [getElem?_replicate, h]
|
||||
simp [h]
|
||||
|
||||
@[deprecated getElem?_replicate_of_lt (since := "2025-03-18")]
|
||||
abbrev getElem?_mkVector_of_lt := @getElem?_replicate_of_lt
|
||||
@@ -2197,21 +2197,21 @@ abbrev flatten_mkVector_empty := @flatten_replicate_empty
|
||||
|
||||
@[simp] theorem flatten_replicate_singleton : (replicate n #v[a]).flatten = (replicate n a).cast (by simp) := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[deprecated flatten_replicate_singleton (since := "2025-03-18")]
|
||||
abbrev flatten_mkVector_singleton := @flatten_replicate_singleton
|
||||
|
||||
@[simp] theorem flatten_replicate_replicate : (replicate n (replicate m a)).flatten = replicate (n * m) a := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[deprecated flatten_replicate_replicate (since := "2025-03-18")]
|
||||
abbrev flatten_mkVector_mkVector := @flatten_replicate_replicate
|
||||
|
||||
theorem flatMap_replicate {f : α → Vector β m} : (replicate n a).flatMap f = (replicate n (f a)).flatten := by
|
||||
ext i h
|
||||
simp [h]
|
||||
simp
|
||||
|
||||
@[deprecated flatMap_replicate (since := "2025-03-18")]
|
||||
abbrev flatMap_mkVector := @flatMap_replicate
|
||||
@@ -2402,7 +2402,7 @@ theorem id_run_foldrM {f : α → β → Id β} {b} {xs : Vector α n} :
|
||||
@[simp] theorem foldlM_reverse [Monad m] {xs : Vector α n} {f : β → α → m β} {b} :
|
||||
xs.reverse.foldlM f b = xs.foldrM (fun x y => f y x) b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldlM_reverse]
|
||||
simp
|
||||
|
||||
@[simp] theorem foldrM_reverse [Monad m] {xs : Vector α n} {f : α → β → m β} {b} :
|
||||
xs.reverse.foldrM f b = xs.foldlM (fun x y => f y x) b := by
|
||||
@@ -2412,7 +2412,7 @@ theorem id_run_foldrM {f : α → β → Id β} {b} {xs : Vector α n} :
|
||||
@[simp, grind] theorem foldrM_push [Monad m] {f : α → β → m β} {init : β} {xs : Vector α n} {a : α} :
|
||||
(xs.push a).foldrM f init = f a init >>= xs.foldrM f := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldrM_push]
|
||||
simp
|
||||
|
||||
/-! ### foldl / foldr -/
|
||||
|
||||
@@ -2435,12 +2435,12 @@ theorem foldr_congr {xs ys : Vector α n} (h₀ : xs = ys) {f g : α → β →
|
||||
@[simp, grind] theorem foldl_push {f : β → α → β} {init : β} {xs : Vector α n} {a : α} :
|
||||
(xs.push a).foldl f init = f (xs.foldl f init) a := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldl_push]
|
||||
simp
|
||||
|
||||
@[simp, grind] theorem foldr_push {f : α → β → β} {init : β} {xs : Vector α n} {a : α} :
|
||||
(xs.push a).foldr f init = xs.foldr f (f a init) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldr_push]
|
||||
simp
|
||||
|
||||
theorem foldl_map {f : β₁ → β₂} {g : α → β₂ → α} {xs : Vector β₁ n} {init : α} :
|
||||
(xs.map f).foldl g init = xs.foldl (fun x y => g x (f y)) init := by
|
||||
@@ -2726,7 +2726,7 @@ theorem contains_append [BEq α] {xs : Vector α n} {ys : Vector α m} {x : α}
|
||||
theorem contains_flatten [BEq α] {xs : Vector (Vector α n) m} {x : α} :
|
||||
(xs.flatten).contains x = xs.any fun xs => xs.contains x := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Function.comp_def]
|
||||
simp
|
||||
|
||||
@[simp, grind]
|
||||
theorem contains_reverse [BEq α] {xs : Vector α n} {x : α} :
|
||||
@@ -2788,7 +2788,7 @@ theorem pop_append {xs : Vector α n} {ys : Vector α m} :
|
||||
(xs ++ ys).pop = if h : m = 0 then xs.pop.cast (by omega) else (xs ++ ys.pop).cast (by omega) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
rcases ys with ⟨ys, rfl⟩
|
||||
simp only [mk_append_mk, pop_mk, List.length_eq_zero_iff, Array.toList_eq_nil_iff, cast_mk, mk_eq]
|
||||
simp only [mk_append_mk, pop_mk, cast_mk, mk_eq]
|
||||
rw [Array.pop_append]
|
||||
split <;> simp_all
|
||||
|
||||
@@ -3010,7 +3010,7 @@ theorem getElem_replace_of_ne {xs : Vector α n} {i : Nat} {h : i < n} (h' : xs[
|
||||
(xs ++ ys).replace a b = if a ∈ xs then xs.replace a b ++ ys else xs ++ ys.replace a b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
rcases ys with ⟨ys, rfl⟩
|
||||
simp only [mk_append_mk, replace_mk, eq_mk, Array.replace_append]
|
||||
simp only [mk_append_mk, replace_mk, Array.replace_append]
|
||||
split <;> simp_all
|
||||
|
||||
theorem replace_append_left {xs : Vector α n} {ys : Vector α m} (h : a ∈ xs) :
|
||||
|
||||
@@ -160,7 +160,7 @@ protected theorem le_iff_lt_or_eq [DecidableEq α] [LT α] [DecidableLT α]
|
||||
{xs ys : Vector α n} : lex xs ys = false ↔ ys ≤ xs := by
|
||||
cases xs
|
||||
cases ys
|
||||
simp [Array.not_lt_iff_ge]
|
||||
simp
|
||||
|
||||
instance [DecidableEq α] [LT α] [DecidableLT α] : DecidableLT (Vector α n) :=
|
||||
fun xs ys => decidable_of_iff (lex xs ys = true) lex_eq_true_iff_lt
|
||||
@@ -206,7 +206,7 @@ theorem lex_eq_false_iff_exists [BEq α] [PartialEquivBEq α] (lt : α → α
|
||||
(∃ (i : Nat) (h : i < n),(∀ j, (hj : j < i) → xs[j] == ys[j]) ∧ lt ys[i] xs[i]) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
rcases ys with ⟨ys, n₂⟩
|
||||
simp_all [Array.lex_eq_false_iff_exists, n₂]
|
||||
simp_all [Array.lex_eq_false_iff_exists]
|
||||
|
||||
protected theorem lt_iff_exists [DecidableEq α] [LT α] [DecidableLT α] {xs ys : Vector α n} :
|
||||
xs < ys ↔
|
||||
|
||||
@@ -186,7 +186,7 @@ theorem mapFinIdx_eq_append_iff {xs : Vector α (n + m)} {f : (i : Nat) → α
|
||||
rcases ys with ⟨ys, rfl⟩
|
||||
rcases zs with ⟨zs, rfl⟩
|
||||
simp only [mapFinIdx_mk, mk_append_mk, eq_mk, Array.mapFinIdx_eq_append_iff, toArray_mapFinIdx,
|
||||
mk_eq, toArray_append, exists_and_left, exists_prop]
|
||||
mk_eq, toArray_append]
|
||||
constructor
|
||||
· rintro ⟨ys', zs', rfl, h₁, h₂⟩
|
||||
have h₁' := congrArg Array.size h₁
|
||||
@@ -290,7 +290,7 @@ theorem mapIdx_eq_push_iff {xs : Vector α (n + 1)} {b : β} :
|
||||
mapIdx f xs = ys.push b ↔
|
||||
∃ (a : α) (zs : Vector α n), xs = zs.push a ∧ mapIdx f zs = ys ∧ f n a = b := by
|
||||
rw [mapIdx_eq_mapFinIdx, mapFinIdx_eq_push_iff]
|
||||
simp only [mapFinIdx_eq_mapIdx, exists_and_left, exists_prop]
|
||||
simp only [mapFinIdx_eq_mapIdx]
|
||||
constructor
|
||||
· rintro ⟨zs, a, rfl, rfl, rfl⟩
|
||||
exact ⟨a, zs, by simp⟩
|
||||
@@ -327,7 +327,7 @@ theorem mapIdx_eq_iff {xs : Vector α n} {f : Nat → α → β} {ys : Vector β
|
||||
· specialize h' w
|
||||
simp_all
|
||||
· simp only [Nat.not_lt] at w
|
||||
simp_all [Array.getElem?_eq_none_iff.mpr w]
|
||||
simp_all
|
||||
|
||||
theorem mapIdx_eq_mapIdx_iff {xs : Vector α n} :
|
||||
mapIdx f xs = mapIdx g xs ↔ ∀ (i : Nat) (h : i < n), f i xs[i] = g i xs[i] := by
|
||||
|
||||
@@ -80,13 +80,13 @@ theorem foldrM_map [Monad m] [LawfulMonad m] {f : β₁ → β₂} {g : β₂
|
||||
{xs : Vector α n} {q : α → Prop} (H : ∀ a, a ∈ xs → q a) {f : β → { x // q x} → m β} {b} :
|
||||
(xs.attachWith q H).foldlM f b = xs.attach.foldlM (fun b ⟨a, h⟩ => f b ⟨a, H _ h⟩) b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldlM_map]
|
||||
simp
|
||||
|
||||
@[simp] theorem foldrM_attachWith [Monad m] [LawfulMonad m]
|
||||
{xs : Vector α n} {q : α → Prop} (H : ∀ a, a ∈ xs → q a) {f : { x // q x} → β → m β} {b} :
|
||||
(xs.attachWith q H).foldrM f b = xs.attach.foldrM (fun a acc => f ⟨a.1, H _ a.2⟩ acc) b := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.foldrM_map]
|
||||
simp
|
||||
|
||||
/-! ### forM -/
|
||||
|
||||
@@ -146,7 +146,7 @@ theorem forIn'_eq_foldlM [Monad m] [LawfulMonad m]
|
||||
forIn' xs init (fun a m b => pure (.yield (f a m b))) =
|
||||
pure (f := m) (xs.attach.foldl (fun b ⟨a, h⟩ => f a h b) init) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.forIn'_pure_yield_eq_foldl, Array.foldl_map]
|
||||
simp [Array.forIn'_pure_yield_eq_foldl]
|
||||
|
||||
theorem idRun_forIn'_yield_eq_foldl
|
||||
{xs : Vector α n} (f : (a : α) → a ∈ xs → β → Id β) (init : β) :
|
||||
@@ -194,7 +194,7 @@ theorem forIn_eq_foldlM [Monad m] [LawfulMonad m]
|
||||
forIn xs init (fun a b => pure (.yield (f a b))) =
|
||||
pure (f := m) (xs.foldl (fun b a => f a b) init) := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp [Array.forIn_pure_yield_eq_foldl, Array.foldl_map]
|
||||
simp [Array.forIn_pure_yield_eq_foldl]
|
||||
|
||||
theorem idRun_forIn_yield_eq_foldl
|
||||
{xs : Vector α n} (f : α → β → Id β) (init : β) :
|
||||
|
||||
@@ -44,7 +44,7 @@ theorem Perm.toList {as bs : Vector α n} : as ~ bs → as.toList ~ bs.toList :=
|
||||
|
||||
@[simp] theorem perm_mk (as bs : Array α) (ha : as.size = n) (hb : bs.size = n) :
|
||||
mk as ha ~ mk bs hb ↔ as ~ bs := by
|
||||
simp [perm_iff_toArray_perm, ha, hb]
|
||||
simp [perm_iff_toArray_perm]
|
||||
|
||||
theorem toArray_perm_iff (xs : Vector α n) (ys : Array α) : xs.toArray ~ ys ↔ ∃ h, xs ~ Vector.mk ys h := by
|
||||
constructor
|
||||
@@ -112,7 +112,7 @@ theorem Perm.push_comm (x y : α) {xs ys : Vector α n} (p : xs ~ ys) :
|
||||
theorem swap_perm {xs : Vector α n} {i j : Nat} (h₁ : i < n) (h₂ : j < n) :
|
||||
xs.swap i j ~ xs := by
|
||||
rcases xs with ⟨xs, rfl⟩
|
||||
simp only [swap, perm_iff_toList_perm, toList_set]
|
||||
simp only [swap, perm_iff_toList_perm]
|
||||
apply set_set_perm
|
||||
|
||||
namespace Perm
|
||||
|
||||
@@ -39,7 +39,7 @@ theorem range'_eq_mk_range' {start size step} :
|
||||
|
||||
@[simp, grind =] theorem getElem_range' {start size step i} (h : i < size) :
|
||||
(range' start size step)[i] = start + step * i := by
|
||||
simp [range', h]
|
||||
simp [range']
|
||||
|
||||
@[simp, grind =] theorem getElem?_range' {start size step i} :
|
||||
(range' start size step)[i]? = if i < size then some (start + step * i) else none := by
|
||||
@@ -58,7 +58,7 @@ theorem range'_zero : range' s 0 step = #v[] := by
|
||||
|
||||
@[simp] theorem range'_inj : range' s n = range' s' n ↔ (n = 0 ∨ s = s') := by
|
||||
rw [← toArray_inj]
|
||||
simp [List.range'_inj]
|
||||
simp
|
||||
|
||||
@[grind =]
|
||||
theorem mem_range' {n} : m ∈ range' s n step ↔ ∃ i < n, m = s + step * i := by
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user