@@ -660,3 +660,88 @@ theorem append_eq_of_isPrefixOf?_eq_some [BEq α] [LawfulBEq α] {xs ys zs : Lis
660660
661661theorem 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