Compare commits

...

7 Commits

Author SHA1 Message Date
Paul Reichert
5b9ddd2cbe poke 2026-02-25 11:29:10 +01:00
Paul Reichert
52f7ab2bcb fix foldr_eq_foldl 2026-02-20 09:31:19 +01:00
Paul Reichert
674fa9cf5e add foldr_eq_foldl 2026-02-20 09:31:19 +01:00
Paul Reichert
c7b96c2eda cleanups and fixes 2026-02-20 09:31:19 +01:00
Paul Reichert
d5ac1f0ed9 more 2026-02-20 09:31:17 +01:00
Paul Reichert
0f22ca353f array/list/vector lemmas 2026-02-20 09:30:04 +01:00
Paul Reichert
6f0a972e55 Perm.pairwise_iff 2026-02-20 09:30:04 +01:00
5 changed files with 145 additions and 7 deletions

View File

@@ -72,6 +72,9 @@ theorem toArray_eq : List.toArray as = xs ↔ as = xs.toList := by
/-! ### size -/
theorem size_singleton {x : α} : #[x].size = 1 := by
simp
theorem eq_empty_of_size_eq_zero (h : xs.size = 0) : xs = #[] := by
cases xs
simp_all
@@ -3483,6 +3486,21 @@ theorem foldl_eq_foldr_reverse {xs : Array α} {f : β → α → β} {b} :
theorem foldr_eq_foldl_reverse {xs : Array α} {f : α β β} {b} :
xs.foldr f b = xs.reverse.foldl (fun x y => f y x) b := by simp
theorem foldl_eq_apply_foldr {xs : Array α} {f : α α α}
[Std.Associative f] [Std.LawfulRightIdentity f init] :
xs.foldl f x = f x (xs.foldr f init) := by
simp [ foldl_toList, foldr_toList, List.foldl_eq_apply_foldr]
theorem foldr_eq_apply_foldl {xs : Array α} {f : α α α}
[Std.Associative f] [Std.LawfulLeftIdentity f init] :
xs.foldr f x = f (xs.foldl f init) x := by
simp [ foldl_toList, foldr_toList, List.foldr_eq_apply_foldl]
theorem foldr_eq_foldl {xs : Array α} {f : α α α}
[Std.Associative f] [Std.LawfulIdentity f init] :
xs.foldr f init = xs.foldl f init := by
simp [foldl_eq_apply_foldr, Std.LawfulLeftIdentity.left_id]
@[simp] theorem foldr_push_eq_append {as : Array α} {bs : Array β} {f : α β} (w : start = as.size) :
as.foldr (fun a xs => Array.push xs (f a)) bs start 0 = bs ++ (as.map f).reverse := by
subst w
@@ -4335,16 +4353,33 @@ def sum_eq_sum_toList := @sum_toList
@[simp, grind =]
theorem sum_append [Zero α] [Add α] [Std.Associative (α := α) (· + ·)]
[Std.LeftIdentity (α := α) (· + ·) 0] [Std.LawfulLeftIdentity (α := α) (· + ·) 0]
[Std.LawfulLeftIdentity (α := α) (· + ·) 0]
{as₁ as₂ : Array α} : (as₁ ++ as₂).sum = as₁.sum + as₂.sum := by
simp [ sum_toList, List.sum_append]
@[simp, grind =]
theorem sum_singleton [Add α] [Zero α] [Std.LawfulRightIdentity (· + ·) (0 : α)] {x : α} :
#[x].sum = x := by
simp [Array.sum_eq_foldr, Std.LawfulRightIdentity.right_id x]
@[simp, grind =]
theorem sum_push [Add α] [Zero α] [Std.Associative (α := α) (· + ·)]
[Std.LawfulIdentity (· + ·) (0 : α)] {xs : Array α} {x : α} :
(xs.push x).sum = xs.sum + x := by
simp [Array.sum_eq_foldr, Std.LawfulRightIdentity.right_id, Std.LawfulLeftIdentity.left_id,
Array.foldr_assoc]
@[simp, grind =]
theorem sum_reverse [Zero α] [Add α] [Std.Associative (α := α) (· + ·)]
[Std.Commutative (α := α) (· + ·)]
[Std.LawfulLeftIdentity (α := α) (· + ·) 0] (xs : Array α) : xs.reverse.sum = xs.sum := by
simp [ sum_toList, List.sum_reverse]
theorem sum_eq_foldl [Zero α] [Add α] [Std.Associative (α := α) (· + ·)]
[Std.LawfulIdentity (· + ·) (0 : α)] {xs : Array α} :
xs.sum = xs.foldl (init := 0) (· + ·) := by
simp [ sum_toList, List.sum_eq_foldl]
theorem foldl_toList_eq_flatMap {l : List α} {acc : Array β}
{F : Array β α Array β} {G : α List β}
(H : acc a, (F acc a).toList = acc.toList ++ G a) :

View File

@@ -126,6 +126,14 @@ theorem swap_perm {xs : Array α} {i j : Nat} (h₁ : i < xs.size) (h₂ : j < x
simp only [swap, perm_iff_toList_perm, toList_set]
apply set_set_perm
theorem Perm.pairwise_iff {R : α α Prop} (S : {x y}, R x y R y x) {xs ys : Array α}
: _p : xs.Perm ys, xs.toList.Pairwise R ys.toList.Pairwise R := by
simpa only [perm_iff_toList_perm] using List.Perm.pairwise_iff S
theorem Perm.pairwise {R : α α Prop} {xs ys : Array α} (hp : xs ~ ys)
(hR : xs.toList.Pairwise R) (hsymm : {x y}, R x y R y x) :
ys.toList.Pairwise R := (hp.pairwise_iff hsymm).mp hR
namespace Perm
set_option linter.indexVariables false in

View File

@@ -1838,6 +1838,11 @@ theorem sum_append [Add α] [Zero α] [Std.LawfulLeftIdentity (α := α) (· +
[Std.Associative (α := α) (· + ·)] {l₁ l₂ : List α} : (l₁ ++ l₂).sum = l₁.sum + l₂.sum := by
induction l₁ generalizing l₂ <;> simp_all [Std.Associative.assoc, Std.LawfulLeftIdentity.left_id]
@[simp, grind =]
theorem sum_singleton [Add α] [Zero α] [Std.LawfulRightIdentity (· + ·) (0 : α)] {x : α} :
[x].sum = x := by
simp [List.sum_eq_foldr, Std.LawfulRightIdentity.right_id x]
@[simp, grind =]
theorem sum_reverse [Zero α] [Add α] [Std.Associative (α := α) (· + ·)]
[Std.Commutative (α := α) (· + ·)]
@@ -2727,6 +2732,31 @@ theorem foldr_assoc {op : ααα} [ha : Std.Associative op] :
simp only [foldr_cons, ha.assoc]
rw [foldr_assoc]
theorem foldl_eq_apply_foldr {xs : List α} {f : α α α}
[Std.Associative f] [Std.LawfulRightIdentity f init] :
xs.foldl f x = f x (xs.foldr f init) := by
induction xs generalizing x
· simp [Std.LawfulRightIdentity.right_id]
· simp [foldl_assoc, *]
theorem foldr_eq_apply_foldl {xs : List α} {f : α α α}
[Std.Associative f] [Std.LawfulLeftIdentity f init] :
xs.foldr f x = f (xs.foldl f init) x := by
have : Std.Associative (fun x y => f y x) := by simp [Std.Associative.assoc]
have : Std.RightIdentity (fun x y => f y x) init :=
have : Std.LawfulRightIdentity (fun x y => f y x) init := by simp [Std.LawfulLeftIdentity.left_id]
rw [ List.reverse_reverse (as := xs), foldr_reverse, foldl_eq_apply_foldr, foldl_reverse]
theorem foldr_eq_foldl {xs : List α} {f : α α α}
[Std.Associative f] [Std.LawfulIdentity f init] :
xs.foldr f init = xs.foldl f init := by
simp [foldl_eq_apply_foldr, Std.LawfulLeftIdentity.left_id]
theorem sum_eq_foldl [Zero α] [Add α] [Std.Associative (α := α) (· + ·)]
[Std.LawfulIdentity (· + ·) (0 : α)] {xs : List α} :
xs.sum = xs.foldl (init := 0) (· + ·) := by
simp [sum_eq_foldr, foldl_eq_apply_foldr, Std.LawfulLeftIdentity.left_id]
-- The argument `f : α₁ → α₂` is intentionally explicit, as it is sometimes not found by unification.
theorem foldl_hom (f : α₁ α₂) {g₁ : α₁ β α₁} {g₂ : α₂ β α₂} {l : List β} {init : α₁}
(H : x y, g₂ (f x) y = f (g₁ x y)) : l.foldl g₂ (f init) = f (l.foldl g₁ init) := by

View File

@@ -101,6 +101,17 @@ theorem toArray_mk {xs : Array α} (h : xs.size = n) : (Vector.mk xs h).toArray
@[simp] theorem foldr_mk {f : α β β} {b : β} {xs : Array α} (h : xs.size = n) :
(Vector.mk xs h).foldr f b = xs.foldr f b := rfl
@[simp, grind =] theorem foldlM_toArray [Monad m]
{f : β α m β} {init : β} {xs : Vector α n} :
xs.toArray.foldlM f init = xs.foldlM f init := rfl
@[simp, grind =] theorem foldrM_toArray [Monad m]
{f : α β m β} {init : β} {xs : Vector α n} :
xs.toArray.foldrM f init = xs.foldrM f init := rfl
@[simp, grind =] theorem foldl_toArray (f : β α β) {init : β} {xs : Vector α n} :
xs.toArray.foldl f init = xs.foldl f init := rfl
@[simp] theorem drop_mk {xs : Array α} {h : xs.size = n} {i} :
(Vector.mk xs h).drop i = Vector.mk (xs.extract i xs.size) (by simp [h]) := rfl
@@ -514,17 +525,32 @@ protected theorem ext {xs ys : Vector α n} (h : (i : Nat) → (_ : i < n) → x
@[grind =_] theorem toList_toArray {xs : Vector α n} : xs.toArray.toList = xs.toList := rfl
theorem toArray_toList {xs : Vector α n} : xs.toList.toArray = xs.toArray := rfl
@[simp, grind =] theorem foldlM_toList [Monad m]
{f : β α m β} {init : β} {xs : Vector α n} :
xs.toList.foldlM f init = xs.foldlM f init := by
rw [ foldlM_toArray, toArray_toList, List.foldlM_toArray]
@[simp, grind =] theorem foldl_toList (f : β α β) {init : β} {xs : Vector α n} :
xs.toList.foldl f init = xs.foldl f init :=
List.foldl_eq_foldlM .. foldlM_toList ..
@[simp, grind =] theorem foldrM_toList [Monad m]
{f : α β m β} {init : β} {xs : Vector α n} :
xs.toList.foldrM f init = xs.foldrM f init := by
rw [ foldrM_toArray, toArray_toList, List.foldrM_toArray]
@[simp, grind =] theorem foldr_toList (f : α β β) {init : β} {xs : Vector α n} :
xs.toList.foldr f init = xs.foldr f init :=
List.foldr_eq_foldrM .. foldrM_toList ..
@[simp, grind =] theorem toList_mk : (Vector.mk xs h).toList = xs.toList := rfl
@[simp, grind =] theorem sum_toList [Add α] [Zero α] {xs : Vector α n} :
xs.toList.sum = xs.sum := by
rw [ toList_toArray, Array.sum_toList, sum_toArray]
@[simp, grind =]
theorem toList_zip {as : Vector α n} {bs : Vector β n} :
(Vector.zip as bs).toList = List.zip as.toList bs.toList := by
rw [mk_zip_mk, toList_mk, Array.toList_zip, toList_toArray, toList_toArray]
@[simp] theorem getElem_toList {xs : Vector α n} {i : Nat} (h : i < xs.toList.length) :
xs.toList[i] = xs[i]'(by simpa using h) := by
cases xs
@@ -609,6 +635,11 @@ theorem toList_swap {xs : Vector α n} {i j} (hi hj) :
@[simp] theorem toList_take {xs : Vector α n} {i} : (xs.take i).toList = xs.toList.take i := by
simp [toList]
@[simp, grind =]
theorem toList_zip {as : Vector α n} {bs : Vector β n} :
(Vector.zip as bs).toList = List.zip as.toList bs.toList := by
rw [mk_zip_mk, toList_mk, Array.toList_zip, toList_toArray, toList_toArray]
@[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
rcases as with as, rfl
@@ -703,6 +734,9 @@ protected theorem eq_empty {xs : Vector α 0} : xs = #v[] := by
/-! ### size -/
theorem size_singleton {x : α} : #v[x].size = 1 := by
simp
theorem eq_empty_of_size_eq_zero {xs : Vector α n} (h : n = 0) : xs = #v[].cast h.symm := by
rcases xs with xs, rfl
apply toArray_inj.1
@@ -2448,6 +2482,21 @@ theorem foldl_eq_foldr_reverse {xs : Vector α n} {f : β → α → β} {b} :
theorem foldr_eq_foldl_reverse {xs : Vector α n} {f : α β β} {b} :
xs.foldr f b = xs.reverse.foldl (fun x y => f y x) b := by simp
theorem foldl_eq_apply_foldr {xs : Vector α n} {f : α α α}
[Std.Associative f] [Std.LawfulRightIdentity f init] :
xs.foldl f x = f x (xs.foldr f init) := by
simp [ foldl_toList, foldr_toList, List.foldl_eq_apply_foldr]
theorem foldr_eq_apply_foldl {xs : Vector α n} {f : α α α}
[Std.Associative f] [Std.LawfulLeftIdentity f init] :
xs.foldr f x = f (xs.foldl f init) x := by
simp [ foldl_toList, foldr_toList, List.foldr_eq_apply_foldl]
theorem foldr_eq_foldl {xs : Vector α n} {f : α α α}
[Std.Associative f] [Std.LawfulIdentity f init] :
xs.foldr f init = xs.foldl f init := by
simp [foldl_eq_apply_foldr, Std.LawfulLeftIdentity.left_id]
theorem foldl_assoc {op : α α α} [ha : Std.Associative op] {xs : Vector α n} {a₁ a₂} :
xs.foldl op (op a₁ a₂) = op a₁ (xs.foldl op a₂) := by
rcases xs with xs, rfl
@@ -3064,8 +3113,25 @@ theorem sum_append [Zero α] [Add α] [Std.Associative (α := α) (· + ·)]
{as₁ as₂ : Vector α n} : (as₁ ++ as₂).sum = as₁.sum + as₂.sum := by
simp [ sum_toList, List.sum_append]
@[simp, grind =]
theorem sum_singleton [Add α] [Zero α] [Std.LawfulRightIdentity (· + ·) (0 : α)] {x : α} :
#v[x].sum = x := by
simp [ sum_toList, Std.LawfulRightIdentity.right_id x]
@[simp, grind =]
theorem sum_push [Add α] [Zero α] [Std.Associative (α := α) (· + ·)]
[Std.LawfulIdentity (· + ·) (0 : α)] {xs : Vector α n} {x : α} :
(xs.push x).sum = xs.sum + x := by
simp [ sum_toArray]
@[simp, grind =]
theorem sum_reverse [Zero α] [Add α] [Std.Associative (α := α) (· + ·)]
[Std.Commutative (α := α) (· + ·)]
[Std.LawfulLeftIdentity (α := α) (· + ·) 0] (xs : Vector α n) : xs.reverse.sum = xs.sum := by
simp [ sum_toList, List.sum_reverse]
theorem sum_eq_foldl [Zero α] [Add α]
[Std.Associative (α := α) (· + ·)] [Std.LawfulIdentity (· + ·) (0 : α)]
{xs : Vector α n} :
xs.sum = xs.foldl (b := 0) (· + ·) := by
simp [ sum_toList, List.sum_eq_foldl]

View File

@@ -1,4 +1,3 @@
@[simp] theorem Array.size_singleton : #[a].size = 1 := rfl
@[simp] theorem USize.not_size_le_one : ¬ USize.size 1 := by cases USize.size_eq <;> simp (config := { decide := true }) [*]
def f := #[true].any id 0 USize.size