Skip to content

Commit e21474b

Browse files
Merge main into nightly-testing
2 parents 6e433d2 + 5c78955 commit e21474b

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

Batteries/Data/List/Basic.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,3 +1066,14 @@ where
10661066
| a :: as, acc => match (a :: as).dropPrefix? i with
10671067
| none => go as (a :: acc)
10681068
| some s => (acc.reverse, s)
1069+
1070+
/--
1071+
Computes the product of the elements of a list.
1072+
1073+
Examples:
1074+
1075+
[a, b, c].prod = a * (b * (c * 1))
1076+
[2, 3, 5].prod = 30
1077+
-/
1078+
@[expose] def prod [Mul α] [One α] (xs : List α) : α :=
1079+
xs.foldr (· * ·) 1

Batteries/Data/List/Lemmas.lean

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,3 +660,88 @@ theorem append_eq_of_isPrefixOf?_eq_some [BEq α] [LawfulBEq α] {xs ys zs : Lis
660660

661661
theorem append_eq_of_isSuffixOf?_eq_some [BEq α] [LawfulBEq α] {xs ys zs : List α}
662662
(h : xs.isSuffixOf? ys = some zs) : zs ++ xs = ys := by simp_all
663+
664+
/-! ### sum/prod -/
665+
666+
private theorem foldr_eq_foldl_aux (f : α → α → α) (init : α) [Std.Associative f]
667+
[Std.LawfulIdentity f init] {l : List α} :
668+
l.foldl f a = f a (l.foldl f init) := by
669+
induction l generalizing a with
670+
| nil => simp [Std.LawfulRightIdentity.right_id]
671+
| cons b l ih =>
672+
simp [Std.LawfulLeftIdentity.left_id, ih (a := f a b), ih (a := b), Std.Associative.assoc]
673+
674+
theorem foldr_eq_foldl (f : α → α → α) (init : α) [Std.Associative f]
675+
[Std.LawfulIdentity f init] {l : List α} :
676+
l.foldr f init = l.foldl f init := by
677+
induction l with
678+
| nil => rfl
679+
| cons a l ih => simp [ih, Std.LawfulLeftIdentity.left_id, foldr_eq_foldl_aux (a := a)]
680+
681+
@[simp, grind =]
682+
theorem prod_nil [Mul α] [One α] : ([] : List α).prod = 1 := rfl
683+
684+
@[simp, grind =]
685+
theorem prod_cons [Mul α] [One α] {a : α} {l : List α} : (a :: l).prod = a * l.prod := rfl
686+
687+
theorem prod_one_cons [Mul α] [One α] [Std.LawfulLeftIdentity (α := α) (· * ·) 1] {l : List α} :
688+
(1 :: l).prod = l.prod := by simp [Std.LawfulLeftIdentity.left_id]
689+
690+
theorem prod_singleton [Mul α] [One α] [Std.LawfulRightIdentity (α := α) (· * ·) 1] {a : α} :
691+
[a].prod = a := by simp [Std.LawfulRightIdentity.right_id]
692+
693+
theorem prod_pair [Mul α] [One α] [Std.LawfulRightIdentity (α := α) (· * ·) 1] {a b : α} :
694+
[a, b].prod = a * b := by simp [Std.LawfulRightIdentity.right_id]
695+
696+
@[simp, grind =]
697+
theorem prod_append [Mul α] [One α] [Std.LawfulLeftIdentity (α := α) (· * ·) 1]
698+
[Std.Associative (α := α) (· * ·)] {l₁ l₂ : List α} : (l₁ ++ l₂).prod = l₁.prod * l₂.prod := by
699+
induction l₁ with simp [Std.LawfulLeftIdentity.left_id, Std.Associative.assoc, *]
700+
701+
theorem prod_concat [Mul α] [One α] [Std.LawfulIdentity (α := α) (· * ·) 1]
702+
[Std.Associative (α := α) (· * ·)] {l : List α} {a : α} :
703+
(l.concat a).prod = l.prod * a := by simp [Std.LawfulRightIdentity.right_id]
704+
705+
@[simp, grind =]
706+
theorem prod_flatten [Mul α] [One α] [Std.LawfulIdentity (α := α) (· * ·) 1]
707+
[Std.Associative (α := α) (· * ·)] {l : List (List α)} :
708+
l.flatten.prod = (l.map prod).prod := by
709+
induction l with simp [*]
710+
711+
theorem prod_eq_foldr [Mul α] [One α] {l : List α} :
712+
l.prod = l.foldr (· * ·) 1 := rfl
713+
714+
theorem prod_eq_foldl [Mul α] [One α] [Std.Associative (α := α) (· * ·)]
715+
[Std.LawfulIdentity (α := α) (· * ·) 1] {l : List α} :
716+
l.prod = l.foldl (· * ·) 1 := foldr_eq_foldl ..
717+
718+
theorem sum_zero_cons [Add α] [Zero α] [Std.LawfulLeftIdentity (α := α) (· + ·) 0] {l : List α} :
719+
(0 :: l).sum = l.sum := by simp [Std.LawfulLeftIdentity.left_id]
720+
721+
theorem sum_singleton [Add α] [Zero α] [Std.LawfulRightIdentity (α := α) (· + ·) 0] {a : α} :
722+
[a].sum = a := by simp [Std.LawfulRightIdentity.right_id]
723+
724+
theorem sum_pair [Add α] [Zero α] [Std.LawfulRightIdentity (α := α) (· + ·) 0] {a b : α} :
725+
[a, b].sum = a + b := by simp [Std.LawfulRightIdentity.right_id]
726+
727+
@[simp, grind =]
728+
theorem sum_append [Add α] [Zero α] [Std.LawfulLeftIdentity (α := α) (· + ·) 0]
729+
[Std.Associative (α := α) (· + ·)] {l₁ l₂ : List α} : (l₁ ++ l₂).sum = l₁.sum + l₂.sum := by
730+
induction l₁ with simp [Std.LawfulLeftIdentity.left_id, Std.Associative.assoc, *]
731+
732+
theorem sum_concat [Add α] [Zero α] [Std.LawfulIdentity (α := α) (· + ·) 0]
733+
[Std.Associative (α := α) (· + ·)] {l : List α} {a : α} :
734+
(l.concat a).sum = l.sum + a := by simp [Std.LawfulRightIdentity.right_id]
735+
736+
@[simp, grind =]
737+
theorem sum_flatten [Add α] [Zero α] [Std.LawfulIdentity (α := α) (· + ·) 0]
738+
[Std.Associative (α := α) (· + ·)] {l : List (List α)} :
739+
l.flatten.sum = (l.map sum).sum := by
740+
induction l with simp [*]
741+
742+
theorem sum_eq_foldr [Add α] [Zero α] {l : List α} :
743+
l.sum = l.foldr (· + ·) 0 := rfl
744+
745+
theorem sum_eq_foldl [Add α] [Zero α] [Std.Associative (α := α) (· + ·)]
746+
[Std.LawfulIdentity (α := α) (· + ·) 0] {l : List α} :
747+
l.sum = l.foldl (· + ·) 0 := foldr_eq_foldl ..

0 commit comments

Comments
 (0)