algebra.group.piMathlib.Algebra.Group.Pi.Lemmas

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

feat(data/set/intervals/pi): f.update i '' Icc a b = Icc (f.update i a) (f.update i b) (#18892)

and corresponding lemmas for pi.single

Diff
@@ -314,6 +314,16 @@ This is the `mul_hom` version of `pi.single`. -/
 
 variables {f}
 
+@[to_additive]
+lemma pi.mul_single_sup [Π i, semilattice_sup (f i)] [Π i, has_one (f i)] (i : I) (x y : f i) :
+  pi.mul_single i (x ⊔ y) = pi.mul_single i x ⊔ pi.mul_single i y :=
+function.update_sup _ _ _ _
+
+@[to_additive]
+lemma pi.mul_single_inf [Π i, semilattice_inf (f i)] [Π i, has_one (f i)] (i : I) (x y : f i) :
+  pi.mul_single i (x ⊓ y) = pi.mul_single i x ⊓ pi.mul_single i y :=
+function.update_inf _ _ _ _
+
 @[to_additive]
 lemma pi.mul_single_mul [Π i, mul_one_class $ f i] (i : I) (x y : f i) :
   mul_single i (x * y) = mul_single i x * mul_single i y :=

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

feat(order/monotone/basic): function.update is monotone (#18841)

and pi.single too

Diff
@@ -485,3 +485,14 @@ noncomputable def function.extend_by_one.hom [mul_one_class R] : (ι → R) →*
   map_mul' := λ f g, by { simpa using function.extend_mul s f g 1 1 } }
 
 end extend
+
+namespace pi
+variables [decidable_eq I] [Π i, preorder (f i)] [Π i, has_one (f i)]
+
+@[to_additive] lemma mul_single_mono : monotone (pi.mul_single i : f i → Π i, f i) :=
+function.update_mono
+
+@[to_additive] lemma mul_single_strict_mono : strict_mono (pi.mul_single i : f i → Π i, f i) :=
+function.update_strict_mono
+
+end pi

(no changes)

(no changes)

feat(algebra/group_with_zero): add lemmas about f * pi.single i x (#6418)

Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>

Diff
@@ -22,7 +22,7 @@ universes u v w
 variables {ι α : Type*}
 variable {I : Type u}     -- The indexing type
 variable {f : I → Type v} -- The family of types already equipped with instances
-variables (x y : Π i, f i) (i : I)
+variables (x y : Π i, f i) (i j : I)
 
 @[to_additive]
 lemma set.preimage_one {α β : Type*} [has_one β] (s : set β) [decidable ((1 : β) ∈ s)] :
@@ -333,6 +333,22 @@ lemma pi.single_mul [Π i, mul_zero_class $ f i] (i : I) (x y : f i) :
   single i (x * y) = single i x * single i y :=
 (mul_hom.single f i).map_mul x y
 
+lemma pi.single_mul_left_apply [Π i, mul_zero_class $ f i] (a : f i) :
+  pi.single i (a * x i) j = pi.single i a j * x j :=
+(pi.apply_single (λ i, (* x i)) (λ i, zero_mul _) _ _ _).symm
+
+lemma pi.single_mul_right_apply [Π i, mul_zero_class $ f i] (a : f i) :
+  pi.single i (x i * a) j = x j * pi.single i a j :=
+(pi.apply_single (λ i, ((*) (x i))) (λ i, mul_zero _) _ _ _).symm
+
+lemma pi.single_mul_left [Π i, mul_zero_class $ f i] (a : f i) :
+  pi.single i (a * x i) = pi.single i a * x :=
+funext $ λ j, pi.single_mul_left_apply _ _ _ _
+
+lemma pi.single_mul_right [Π i, mul_zero_class $ f i] (a : f i) :
+  pi.single i (x i * a) = x * pi.single i a :=
+funext $ λ j, pi.single_mul_right_apply _ _ _ _
+
 /-- The injection into a pi group at different indices commutes.
 
 For injections of commuting elements at the same index, see `commute.map` -/

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(first ported)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -470,49 +470,49 @@ open Pi
 
 variable (f)
 
-#print OneHom.single /-
+#print OneHom.mulSingle /-
 /-- The one-preserving homomorphism including a single value
 into a dependent family of values, as functions supported at a point.
 
 This is the `one_hom` version of `pi.mul_single`. -/
 @[to_additive ZeroHom.single
       "The zero-preserving homomorphism including a single value\ninto a dependent family of values, as functions supported at a point.\n\nThis is the `zero_hom` version of `pi.single`."]
-def OneHom.single [∀ i, One <| f i] (i : I) : OneHom (f i) (∀ i, f i)
+def OneHom.mulSingle [∀ i, One <| f i] (i : I) : OneHom (f i) (∀ i, f i)
     where
   toFun := mulSingle i
   map_one' := mulSingle_one i
-#align one_hom.single OneHom.single
+#align one_hom.single OneHom.mulSingle
 #align zero_hom.single ZeroHom.single
 -/
 
-#print OneHom.single_apply /-
+#print OneHom.mulSingle_apply /-
 @[simp, to_additive]
-theorem OneHom.single_apply [∀ i, One <| f i] (i : I) (x : f i) :
-    OneHom.single f i x = mulSingle i x :=
+theorem OneHom.mulSingle_apply [∀ i, One <| f i] (i : I) (x : f i) :
+    OneHom.mulSingle f i x = mulSingle i x :=
   rfl
-#align one_hom.single_apply OneHom.single_apply
+#align one_hom.single_apply OneHom.mulSingle_apply
 #align zero_hom.single_apply ZeroHom.single_apply
 -/
 
-#print MonoidHom.single /-
+#print MonoidHom.mulSingle /-
 /-- The monoid homomorphism including a single monoid into a dependent family of additive monoids,
 as functions supported at a point.
 
 This is the `monoid_hom` version of `pi.mul_single`. -/
 @[to_additive
       "The additive monoid homomorphism including a single additive\nmonoid into a dependent family of additive monoids, as functions supported at a point.\n\nThis is the `add_monoid_hom` version of `pi.single`."]
-def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :=
-  { OneHom.single f i with map_mul' := mulSingle_op₂ (fun _ => (· * ·)) (fun _ => one_mul _) _ }
-#align monoid_hom.single MonoidHom.single
+def MonoidHom.mulSingle [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :=
+  { OneHom.mulSingle f i with map_mul' := mulSingle_op₂ (fun _ => (· * ·)) (fun _ => one_mul _) _ }
+#align monoid_hom.single MonoidHom.mulSingle
 #align add_monoid_hom.single AddMonoidHom.single
 -/
 
-#print MonoidHom.single_apply /-
+#print MonoidHom.mulSingle_apply /-
 @[simp, to_additive]
-theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
-    MonoidHom.single f i x = mulSingle i x :=
+theorem MonoidHom.mulSingle_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
+    MonoidHom.mulSingle f i x = mulSingle i x :=
   rfl
-#align monoid_hom.single_apply MonoidHom.single_apply
+#align monoid_hom.single_apply MonoidHom.mulSingle_apply
 #align add_monoid_hom.single_apply AddMonoidHom.single_apply
 -/
 
@@ -553,7 +553,7 @@ theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I
 @[to_additive]
 theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
     mulSingle i (x * y) = mulSingle i x * mulSingle i y :=
-  (MonoidHom.single f i).map_hMul x y
+  (MonoidHom.mulSingle f i).map_hMul x y
 #align pi.mul_single_mul Pi.mulSingle_mul
 #align pi.single_add Pi.single_add
 -/
@@ -562,17 +562,17 @@ theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
 @[to_additive]
 theorem Pi.mulSingle_inv [∀ i, Group <| f i] (i : I) (x : f i) :
     mulSingle i x⁻¹ = (mulSingle i x)⁻¹ :=
-  (MonoidHom.single f i).map_inv x
+  (MonoidHom.mulSingle f i).map_inv x
 #align pi.mul_single_inv Pi.mulSingle_inv
 #align pi.single_neg Pi.single_neg
 -/
 
-#print Pi.single_div /-
+#print Pi.mulSingle_div /-
 @[to_additive]
-theorem Pi.single_div [∀ i, Group <| f i] (i : I) (x y : f i) :
+theorem Pi.mulSingle_div [∀ i, Group <| f i] (i : I) (x y : f i) :
     mulSingle i (x / y) = mulSingle i x / mulSingle i y :=
-  (MonoidHom.single f i).map_div x y
-#align pi.single_div Pi.single_div
+  (MonoidHom.mulSingle f i).map_div x y
+#align pi.single_div Pi.mulSingle_div
 #align pi.single_sub Pi.single_sub
 -/
 
Diff
@@ -4,8 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 -/
 import Logic.Pairwise
-import Algebra.Hom.GroupInstances
-import Data.Pi.Algebra
+import Algebra.Group.Hom.Instances
+import Algebra.Group.Pi.Basic
 import Data.Set.Function
 import Tactic.PiInstances
 
Diff
@@ -665,20 +665,20 @@ theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type _} [Comm
     have hl := congr_fun h l
     have hm := (congr_fun h m).symm
     have hn := (congr_fun h n).symm
-    simp only [mul_apply, mul_single_apply, if_pos rfl] at hk hl hm hn 
+    simp only [mul_apply, mul_single_apply, if_pos rfl] at hk hl hm hn
     rcases eq_or_ne k m with (rfl | hkm)
     · refine' Or.inl ⟨rfl, not_ne_iff.mp fun hln => (hv _).elim⟩
       rcases eq_or_ne k l with (rfl | hkl)
-      · rwa [if_neg hln.symm, if_neg hln.symm, one_mul, one_mul] at hn 
-      · rwa [if_neg hkl.symm, if_neg hln, one_mul, one_mul] at hl 
+      · rwa [if_neg hln.symm, if_neg hln.symm, one_mul, one_mul] at hn
+      · rwa [if_neg hkl.symm, if_neg hln, one_mul, one_mul] at hl
     · rcases eq_or_ne m n with (rfl | hmn)
       · rcases eq_or_ne k l with (rfl | hkl)
-        · rw [if_neg hkm.symm, if_neg hkm.symm, one_mul, if_pos rfl] at hm 
+        · rw [if_neg hkm.symm, if_neg hkm.symm, one_mul, if_pos rfl] at hm
           exact Or.inr (Or.inr ⟨hm, rfl, rfl⟩)
         · simpa only [if_neg hkm, if_neg hkl, mul_one] using hk
-      · rw [if_neg hkm.symm, if_neg hmn, one_mul, mul_one] at hm 
+      · rw [if_neg hkm.symm, if_neg hmn, one_mul, mul_one] at hm
         obtain rfl := (ite_ne_right_iff.mp (ne_of_eq_of_ne hm.symm hu)).1
-        rw [if_neg hkm, if_neg hkm, one_mul, mul_one] at hk 
+        rw [if_neg hkm, if_neg hkm, one_mul, mul_one] at hk
         obtain rfl := (ite_ne_right_iff.mp (ne_of_eq_of_ne hk.symm hu)).1
         exact Or.inr (Or.inl ⟨hk.trans (if_pos rfl), rfl, rfl⟩)
   · rintro (⟨rfl, rfl⟩ | ⟨rfl, rfl, rfl⟩ | ⟨h, rfl, rfl⟩)
Diff
@@ -625,7 +625,7 @@ theorem Pi.mulSingle_commute [∀ i, MulOneClass <| f i] :
   by_cases h2 : j = k; · subst h2; simp [hij]
   simp [h1, h2]
 #align pi.mul_single_commute Pi.mulSingle_commute
-#align pi.single_commute Pi.single_commute
+#align pi.single_commute Pi.single_addCommute
 -/
 
 #print Pi.mulSingle_apply_commute /-
@@ -638,7 +638,7 @@ theorem Pi.mulSingle_apply_commute [∀ i, MulOneClass <| f i] (x : ∀ i, f i)
   · rfl
   · exact Pi.mulSingle_commute hij _ _
 #align pi.mul_single_apply_commute Pi.mulSingle_apply_commute
-#align pi.single_apply_commute Pi.single_apply_commute
+#align pi.single_apply_commute Pi.single_apply_addCommute
 -/
 
 #print Pi.update_eq_div_mul_mulSingle /-
Diff
@@ -3,11 +3,11 @@ Copyright (c) 2018 Simon Hudon. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 -/
-import Mathbin.Logic.Pairwise
-import Mathbin.Algebra.Hom.GroupInstances
-import Mathbin.Data.Pi.Algebra
-import Mathbin.Data.Set.Function
-import Mathbin.Tactic.PiInstances
+import Logic.Pairwise
+import Algebra.Hom.GroupInstances
+import Data.Pi.Algebra
+import Data.Set.Function
+import Tactic.PiInstances
 
 #align_import algebra.group.pi from "leanprover-community/mathlib"@"e4bc74cbaf429d706cb9140902f7ca6c431e75a4"
 
Diff
@@ -298,7 +298,7 @@ given by `pi.mul_hom f x b = f b x`. -/
 def Pi.mulHom {γ : Type w} [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f i) : γ →ₙ* ∀ i, f i
     where
   toFun x i := g i x
-  map_mul' x y := funext fun i => (g i).map_mul x y
+  map_mul' x y := funext fun i => (g i).map_hMul x y
 #align pi.mul_hom Pi.mulHom
 #align pi.add_hom Pi.addHom
 -/
@@ -553,7 +553,7 @@ theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I
 @[to_additive]
 theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
     mulSingle i (x * y) = mulSingle i x * mulSingle i y :=
-  (MonoidHom.single f i).map_mul x y
+  (MonoidHom.single f i).map_hMul x y
 #align pi.mul_single_mul Pi.mulSingle_mul
 #align pi.single_add Pi.single_add
 -/
@@ -579,7 +579,7 @@ theorem Pi.single_div [∀ i, Group <| f i] (i : I) (x y : f i) :
 #print Pi.single_mul /-
 theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
     single i (x * y) = single i x * single i y :=
-  (MulHom.single f i).map_mul x y
+  (MulHom.single f i).map_hMul x y
 #align pi.single_mul Pi.single_mul
 -/
 
Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2018 Simon Hudon. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
-
-! This file was ported from Lean 3 source module algebra.group.pi
-! leanprover-community/mathlib commit e4bc74cbaf429d706cb9140902f7ca6c431e75a4
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Logic.Pairwise
 import Mathbin.Algebra.Hom.GroupInstances
@@ -14,6 +9,8 @@ import Mathbin.Data.Pi.Algebra
 import Mathbin.Data.Set.Function
 import Mathbin.Tactic.PiInstances
 
+#align_import algebra.group.pi from "leanprover-community/mathlib"@"e4bc74cbaf429d706cb9140902f7ca6c431e75a4"
+
 /-!
 # Pi instances for groups and monoids
 
Diff
@@ -36,12 +36,14 @@ variable {f : I → Type v}
 -- The family of types already equipped with instances
 variable (x y : ∀ i, f i) (i j : I)
 
+#print Set.preimage_one /-
 @[to_additive]
 theorem Set.preimage_one {α β : Type _} [One β] (s : Set β) [Decidable ((1 : β) ∈ s)] :
     (1 : α → β) ⁻¹' s = if (1 : β) ∈ s then Set.univ else ∅ :=
   Set.preimage_const 1 s
 #align set.preimage_one Set.preimage_one
 #align set.preimage_zero Set.preimage_zero
+-/
 
 namespace Pi
 
@@ -277,12 +279,14 @@ end Pi
 
 namespace MulHom
 
+#print MulHom.coe_mul /-
 @[to_additive]
 theorem coe_mul {M N} {mM : Mul M} {mN : CommSemigroup N} (f g : M →ₙ* N) :
     (f * g : M → N) = fun x => f x * g x :=
   rfl
 #align mul_hom.coe_mul MulHom.coe_mul
 #align add_hom.coe_add AddHom.coe_add
+-/
 
 end MulHom
 
@@ -328,6 +332,7 @@ def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g :
 #align pi.add_monoid_hom Pi.addMonoidHom
 -/
 
+#print Pi.monoidHom_injective /-
 @[to_additive]
 theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f i)] [MulOneClass γ]
     (g : ∀ i, γ →* f i) (hg : ∀ i, Function.Injective (g i)) :
@@ -335,6 +340,7 @@ theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f
   Pi.mulHom_injective (fun i => (g i).toMulHom) hg
 #align pi.monoid_hom_injective Pi.monoidHom_injective
 #align pi.add_monoid_hom_injective Pi.addMonoidHom_injective
+-/
 
 variable (f) [∀ i, Mul (f i)]
 
@@ -364,6 +370,7 @@ def Pi.constMulHom (α β : Type _) [Mul β] : β →ₙ* α → β
 #align pi.const_add_hom Pi.constAddHom
 -/
 
+#print MulHom.coeFn /-
 /-- Coercion of a `mul_hom` into a function is itself a `mul_hom`.
 See also `mul_hom.eval`. -/
 @[to_additive
@@ -375,6 +382,7 @@ def MulHom.coeFn (α β : Type _) [Mul α] [CommSemigroup β] : (α →ₙ* β)
   map_mul' x y := rfl
 #align mul_hom.coe_fn MulHom.coeFn
 #align add_hom.coe_fn AddHom.coeFn
+-/
 
 #print MulHom.compLeft /-
 /-- Semigroup homomorphism between the function spaces `I → α` and `I → β`, induced by a semigroup
@@ -502,13 +510,16 @@ def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :
 #align add_monoid_hom.single AddMonoidHom.single
 -/
 
+#print MonoidHom.single_apply /-
 @[simp, to_additive]
 theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
     MonoidHom.single f i x = mulSingle i x :=
   rfl
 #align monoid_hom.single_apply MonoidHom.single_apply
 #align add_monoid_hom.single_apply AddMonoidHom.single_apply
+-/
 
+#print MulHom.single /-
 /-- The multiplicative homomorphism including a single `mul_zero_class`
 into a dependent family of `mul_zero_class`es, as functions supported at a point.
 
@@ -519,69 +530,91 @@ def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i
   toFun := single i
   map_mul' := Pi.single_op₂ (fun _ => (· * ·)) (fun _ => MulZeroClass.zero_mul _) _
 #align mul_hom.single MulHom.single
+-/
 
 variable {f}
 
+#print Pi.mulSingle_sup /-
 @[to_additive]
 theorem Pi.mulSingle_sup [∀ i, SemilatticeSup (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
     Pi.mulSingle i (x ⊔ y) = Pi.mulSingle i x ⊔ Pi.mulSingle i y :=
   Function.update_sup _ _ _ _
 #align pi.mul_single_sup Pi.mulSingle_sup
 #align pi.single_sup Pi.single_sup
+-/
 
+#print Pi.mulSingle_inf /-
 @[to_additive]
 theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
     Pi.mulSingle i (x ⊓ y) = Pi.mulSingle i x ⊓ Pi.mulSingle i y :=
   Function.update_inf _ _ _ _
 #align pi.mul_single_inf Pi.mulSingle_inf
 #align pi.single_inf Pi.single_inf
+-/
 
+#print Pi.mulSingle_mul /-
 @[to_additive]
 theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
     mulSingle i (x * y) = mulSingle i x * mulSingle i y :=
   (MonoidHom.single f i).map_mul x y
 #align pi.mul_single_mul Pi.mulSingle_mul
 #align pi.single_add Pi.single_add
+-/
 
+#print Pi.mulSingle_inv /-
 @[to_additive]
 theorem Pi.mulSingle_inv [∀ i, Group <| f i] (i : I) (x : f i) :
     mulSingle i x⁻¹ = (mulSingle i x)⁻¹ :=
   (MonoidHom.single f i).map_inv x
 #align pi.mul_single_inv Pi.mulSingle_inv
 #align pi.single_neg Pi.single_neg
+-/
 
+#print Pi.single_div /-
 @[to_additive]
 theorem Pi.single_div [∀ i, Group <| f i] (i : I) (x y : f i) :
     mulSingle i (x / y) = mulSingle i x / mulSingle i y :=
   (MonoidHom.single f i).map_div x y
 #align pi.single_div Pi.single_div
 #align pi.single_sub Pi.single_sub
+-/
 
+#print Pi.single_mul /-
 theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
     single i (x * y) = single i x * single i y :=
   (MulHom.single f i).map_mul x y
 #align pi.single_mul Pi.single_mul
+-/
 
+#print Pi.single_mul_left_apply /-
 theorem Pi.single_mul_left_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (a * x i) j = Pi.single i a j * x j :=
   (Pi.apply_single (fun i => (· * x i)) (fun i => MulZeroClass.zero_mul _) _ _ _).symm
 #align pi.single_mul_left_apply Pi.single_mul_left_apply
+-/
 
+#print Pi.single_mul_right_apply /-
 theorem Pi.single_mul_right_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (x i * a) j = x j * Pi.single i a j :=
   (Pi.apply_single (fun i => (· * ·) (x i)) (fun i => MulZeroClass.mul_zero _) _ _ _).symm
 #align pi.single_mul_right_apply Pi.single_mul_right_apply
+-/
 
+#print Pi.single_mul_left /-
 theorem Pi.single_mul_left [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (a * x i) = Pi.single i a * x :=
   funext fun j => Pi.single_mul_left_apply _ _ _ _
 #align pi.single_mul_left Pi.single_mul_left
+-/
 
+#print Pi.single_mul_right /-
 theorem Pi.single_mul_right [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (x i * a) = x * Pi.single i a :=
   funext fun j => Pi.single_mul_right_apply _ _ _ _
 #align pi.single_mul_right Pi.single_mul_right
+-/
 
+#print Pi.mulSingle_commute /-
 /-- The injection into a pi group at different indices commutes.
 
 For injections of commuting elements at the same index, see `commute.map` -/
@@ -596,7 +629,9 @@ theorem Pi.mulSingle_commute [∀ i, MulOneClass <| f i] :
   simp [h1, h2]
 #align pi.mul_single_commute Pi.mulSingle_commute
 #align pi.single_commute Pi.single_commute
+-/
 
+#print Pi.mulSingle_apply_commute /-
 /-- The injection into a pi group with the same values commutes. -/
 @[to_additive "The injection into an additive pi group with the same values commutes."]
 theorem Pi.mulSingle_apply_commute [∀ i, MulOneClass <| f i] (x : ∀ i, f i) (i j : I) :
@@ -607,7 +642,9 @@ theorem Pi.mulSingle_apply_commute [∀ i, MulOneClass <| f i] (x : ∀ i, f i)
   · exact Pi.mulSingle_commute hij _ _
 #align pi.mul_single_apply_commute Pi.mulSingle_apply_commute
 #align pi.single_apply_commute Pi.single_apply_commute
+-/
 
+#print Pi.update_eq_div_mul_mulSingle /-
 @[to_additive update_eq_sub_add_single]
 theorem Pi.update_eq_div_mul_mulSingle [∀ i, Group <| f i] (g : ∀ i : I, f i) (x : f i) :
     Function.update g i x = g / mulSingle i (g i) * mulSingle i x :=
@@ -617,7 +654,9 @@ theorem Pi.update_eq_div_mul_mulSingle [∀ i, Group <| f i] (g : ∀ i : I, f i
   · simp
   · simp [Function.update_noteq h.symm, h]
 #align pi.update_eq_div_mul_single Pi.update_eq_div_mul_mulSingle
+-/
 
+#print Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle /-
 @[to_additive Pi.single_add_single_eq_single_add_single]
 theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type _} [CommMonoid M]
     {k l m n : I} {u v : M} (hu : u ≠ 1) (hv : v ≠ 1) :
@@ -651,6 +690,7 @@ theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type _} [Comm
     · simp_rw [← Pi.mulSingle_mul, h, mul_single_one]
 #align pi.mul_single_mul_mul_single_eq_mul_single_mul_mul_single Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle
 #align pi.single_add_single_eq_single_add_single Pi.single_add_single_eq_single_add_single
+-/
 
 end Single
 
@@ -693,17 +733,21 @@ theorem update_div [∀ i, Div (f i)] [DecidableEq I] (f₁ f₂ : ∀ i, f i) (
 
 variable [One α] [Nonempty ι] {a : α}
 
+#print Function.const_eq_one /-
 @[simp, to_additive]
 theorem const_eq_one : const ι a = 1 ↔ a = 1 :=
   @const_inj _ _ _ _ 1
 #align function.const_eq_one Function.const_eq_one
 #align function.const_eq_zero Function.const_eq_zero
+-/
 
+#print Function.const_ne_one /-
 @[to_additive]
 theorem const_ne_one : const ι a ≠ 1 ↔ a ≠ 1 :=
   const_eq_one.Not
 #align function.const_ne_one Function.const_ne_one
 #align function.const_ne_zero Function.const_ne_zero
+-/
 
 end Function
 
Diff
@@ -48,7 +48,7 @@ namespace Pi
 #print Pi.semigroup /-
 @[to_additive]
 instance semigroup [∀ i, Semigroup <| f i] : Semigroup (∀ i : I, f i) := by
-  refine_struct { mul := (· * ·).. } <;> pi_instance_derive_field
+  refine_struct { mul := (· * ·) .. } <;> pi_instance_derive_field
 #align pi.semigroup Pi.semigroup
 #align pi.add_semigroup Pi.addSemigroup
 -/
@@ -57,7 +57,7 @@ instance semigroup [∀ i, Semigroup <| f i] : Semigroup (∀ i : I, f i) := by
 instance semigroupWithZero [∀ i, SemigroupWithZero <| f i] : SemigroupWithZero (∀ i : I, f i) := by
   refine_struct
       { zero := (0 : ∀ i, f i)
-        mul := (· * ·).. } <;>
+        mul := (· * ·) .. } <;>
     pi_instance_derive_field
 #align pi.semigroup_with_zero Pi.semigroupWithZero
 -/
@@ -65,7 +65,7 @@ instance semigroupWithZero [∀ i, SemigroupWithZero <| f i] : SemigroupWithZero
 #print Pi.commSemigroup /-
 @[to_additive]
 instance commSemigroup [∀ i, CommSemigroup <| f i] : CommSemigroup (∀ i : I, f i) := by
-  refine_struct { mul := (· * ·).. } <;> pi_instance_derive_field
+  refine_struct { mul := (· * ·) .. } <;> pi_instance_derive_field
 #align pi.comm_semigroup Pi.commSemigroup
 #align pi.add_comm_semigroup Pi.addCommSemigroup
 -/
@@ -75,7 +75,7 @@ instance commSemigroup [∀ i, CommSemigroup <| f i] : CommSemigroup (∀ i : I,
 instance mulOneClass [∀ i, MulOneClass <| f i] : MulOneClass (∀ i : I, f i) := by
   refine_struct
       { one := (1 : ∀ i, f i)
-        mul := (· * ·).. } <;>
+        mul := (· * ·) .. } <;>
     pi_instance_derive_field
 #align pi.mul_one_class Pi.mulOneClass
 #align pi.add_zero_class Pi.addZeroClass
@@ -201,7 +201,7 @@ instance rightCancelMonoid [∀ i, RightCancelMonoid <| f i] : RightCancelMonoid
   refine_struct
       { one := (1 : ∀ i, f i)
         mul := (· * ·)
-        npow := Monoid.npow.. } <;>
+        npow := Monoid.npow .. } <;>
     pi_instance_derive_field
 #align pi.right_cancel_monoid Pi.rightCancelMonoid
 #align pi.add_right_cancel_monoid Pi.addRightCancelMonoid
@@ -235,7 +235,7 @@ instance cancelCommMonoid [∀ i, CancelCommMonoid <| f i] : CancelCommMonoid (
 instance mulZeroClass [∀ i, MulZeroClass <| f i] : MulZeroClass (∀ i : I, f i) := by
   refine_struct
       { zero := (0 : ∀ i, f i)
-        mul := (· * ·).. } <;>
+        mul := (· * ·) .. } <;>
     pi_instance_derive_field
 #align pi.mul_zero_class Pi.mulZeroClass
 -/
@@ -245,7 +245,7 @@ instance mulZeroOneClass [∀ i, MulZeroOneClass <| f i] : MulZeroOneClass (∀
   refine_struct
       { zero := (0 : ∀ i, f i)
         one := (1 : ∀ i, f i)
-        mul := (· * ·).. } <;>
+        mul := (· * ·) .. } <;>
     pi_instance_derive_field
 #align pi.mul_zero_one_class Pi.mulZeroOneClass
 -/
@@ -629,20 +629,20 @@ theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type _} [Comm
     have hl := congr_fun h l
     have hm := (congr_fun h m).symm
     have hn := (congr_fun h n).symm
-    simp only [mul_apply, mul_single_apply, if_pos rfl] at hk hl hm hn
+    simp only [mul_apply, mul_single_apply, if_pos rfl] at hk hl hm hn 
     rcases eq_or_ne k m with (rfl | hkm)
     · refine' Or.inl ⟨rfl, not_ne_iff.mp fun hln => (hv _).elim⟩
       rcases eq_or_ne k l with (rfl | hkl)
-      · rwa [if_neg hln.symm, if_neg hln.symm, one_mul, one_mul] at hn
-      · rwa [if_neg hkl.symm, if_neg hln, one_mul, one_mul] at hl
+      · rwa [if_neg hln.symm, if_neg hln.symm, one_mul, one_mul] at hn 
+      · rwa [if_neg hkl.symm, if_neg hln, one_mul, one_mul] at hl 
     · rcases eq_or_ne m n with (rfl | hmn)
       · rcases eq_or_ne k l with (rfl | hkl)
-        · rw [if_neg hkm.symm, if_neg hkm.symm, one_mul, if_pos rfl] at hm
+        · rw [if_neg hkm.symm, if_neg hkm.symm, one_mul, if_pos rfl] at hm 
           exact Or.inr (Or.inr ⟨hm, rfl, rfl⟩)
         · simpa only [if_neg hkm, if_neg hkl, mul_one] using hk
-      · rw [if_neg hkm.symm, if_neg hmn, one_mul, mul_one] at hm
+      · rw [if_neg hkm.symm, if_neg hmn, one_mul, mul_one] at hm 
         obtain rfl := (ite_ne_right_iff.mp (ne_of_eq_of_ne hm.symm hu)).1
-        rw [if_neg hkm, if_neg hkm, one_mul, mul_one] at hk
+        rw [if_neg hkm, if_neg hkm, one_mul, mul_one] at hk 
         obtain rfl := (ite_ne_right_iff.mp (ne_of_eq_of_ne hk.symm hu)).1
         exact Or.inr (Or.inl ⟨hk.trans (if_pos rfl), rfl, rfl⟩)
   · rintro (⟨rfl, rfl⟩ | ⟨rfl, rfl, rfl⟩ | ⟨h, rfl, rfl⟩)
Diff
@@ -36,12 +36,6 @@ variable {f : I → Type v}
 -- The family of types already equipped with instances
 variable (x y : ∀ i, f i) (i j : I)
 
-/- warning: set.preimage_one -> Set.preimage_one is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : One.{u2} β] (s : Set.{u2} β) [_inst_2 : Decidable (Membership.Mem.{u2, u2} β (Set.{u2} β) (Set.hasMem.{u2} β) (OfNat.ofNat.{u2} β 1 (OfNat.mk.{u2} β 1 (One.one.{u2} β _inst_1))) s)], Eq.{succ u1} (Set.{u1} α) (Set.preimage.{u1, u2} α β (OfNat.ofNat.{max u1 u2} (α -> β) 1 (OfNat.mk.{max u1 u2} (α -> β) 1 (One.one.{max u1 u2} (α -> β) (Pi.instOne.{u1, u2} α (fun (ᾰ : α) => β) (fun (i : α) => _inst_1))))) s) (ite.{succ u1} (Set.{u1} α) (Membership.Mem.{u2, u2} β (Set.{u2} β) (Set.hasMem.{u2} β) (OfNat.ofNat.{u2} β 1 (OfNat.mk.{u2} β 1 (One.one.{u2} β _inst_1))) s) _inst_2 (Set.univ.{u1} α) (EmptyCollection.emptyCollection.{u1} (Set.{u1} α) (Set.hasEmptyc.{u1} α)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : One.{u1} β] (s : Set.{u1} β) [_inst_2 : Decidable (Membership.mem.{u1, u1} β (Set.{u1} β) (Set.instMembershipSet.{u1} β) (OfNat.ofNat.{u1} β 1 (One.toOfNat1.{u1} β _inst_1)) s)], Eq.{succ u2} (Set.{u2} α) (Set.preimage.{u2, u1} α β (OfNat.ofNat.{max u2 u1} (α -> β) 1 (One.toOfNat1.{max u2 u1} (α -> β) (Pi.instOne.{u2, u1} α (fun (a._@.Mathlib.Algebra.Group.Pi._hyg.93 : α) => β) (fun (i : α) => _inst_1)))) s) (ite.{succ u2} (Set.{u2} α) (Membership.mem.{u1, u1} β (Set.{u1} β) (Set.instMembershipSet.{u1} β) (OfNat.ofNat.{u1} β 1 (One.toOfNat1.{u1} β _inst_1)) s) _inst_2 (Set.univ.{u2} α) (EmptyCollection.emptyCollection.{u2} (Set.{u2} α) (Set.instEmptyCollectionSet.{u2} α)))
-Case conversion may be inaccurate. Consider using '#align set.preimage_one Set.preimage_oneₓ'. -/
 @[to_additive]
 theorem Set.preimage_one {α β : Type _} [One β] (s : Set β) [Decidable ((1 : β) ∈ s)] :
     (1 : α → β) ⁻¹' s = if (1 : β) ∈ s then Set.univ else ∅ :=
@@ -283,12 +277,6 @@ end Pi
 
 namespace MulHom
 
-/- warning: mul_hom.coe_mul -> MulHom.coe_mul is a dubious translation:
-lean 3 declaration is
-  forall {M : Type.{u1}} {N : Type.{u2}} {mM : Mul.{u1} M} {mN : CommSemigroup.{u2} N} (f : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (g : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))), Eq.{max (succ u1) (succ u2)} (M -> N) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (M -> N) (M -> N) (M -> N) (instHMul.{max u1 u2} (M -> N) (Pi.instMul.{u1, u2} M (fun (ᾰ : M) => N) (fun (i : M) => Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g)) (fun (x : M) => HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f x) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g x))
-but is expected to have type
-  forall {M : Type.{u2}} {N : Type.{u1}} {mM : Mul.{u2} M} {mN : CommSemigroup.{u1} N} (f : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) (g : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))), Eq.{max (succ u2) (succ u1)} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (instHMul.{max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (Pi.instMul.{u2, u1} M (fun (ᾰ : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (fun (i : M) => Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) i) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) i) mN)))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g)) (fun (x : M) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) (Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) mN))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f x) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g x))
-Case conversion may be inaccurate. Consider using '#align mul_hom.coe_mul MulHom.coe_mulₓ'. -/
 @[to_additive]
 theorem coe_mul {M N} {mM : Mul M} {mN : CommSemigroup N} (f g : M →ₙ* N) :
     (f * g : M → N) = fun x => f x * g x :=
@@ -340,12 +328,6 @@ def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g :
 #align pi.add_monoid_hom Pi.addMonoidHom
 -/
 
-/- warning: pi.monoid_hom_injective -> Pi.monoidHom_injective is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (coeFn.{max (succ u2) (succ u3), max (succ u3) (succ u2)} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (fun (_x : MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) => γ -> (f i)) (MonoidHom.hasCoeToFun.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), (fun (i : I) => f i) i) (coeFn.{max (succ (max u1 u2)) (succ u3), max (succ u3) (succ (max u1 u2))} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => γ -> (forall (i : I), (fun (i : I) => f i) i)) (MonoidHom.hasCoeToFun.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (FunLike.coe.{max (succ u2) (succ u3), succ u3, succ u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : γ) => f i) _x) (MulHomClass.toFunLike.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MonoidHomClass.toMulHomClass.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) _inst_3 (_inst_2 i) (MonoidHom.monoidHomClass.{u3, u2} γ (f i) _inst_3 (_inst_2 i)))) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), f i) (FunLike.coe.{max (max (succ u1) (succ u2)) (succ u3), succ u3, max (succ u1) (succ u2)} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : γ) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
-Case conversion may be inaccurate. Consider using '#align pi.monoid_hom_injective Pi.monoidHom_injectiveₓ'. -/
 @[to_additive]
 theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f i)] [MulOneClass γ]
     (g : ∀ i, γ →* f i) (hg : ∀ i, Function.Injective (g i)) :
@@ -382,12 +364,6 @@ def Pi.constMulHom (α β : Type _) [Mul β] : β →ₙ* α → β
 #align pi.const_add_hom Pi.constAddHom
 -/
 
-/- warning: mul_hom.coe_fn -> MulHom.coeFn is a dubious translation:
-lean 3 declaration is
-  forall (α : Type.{u1}) (β : Type.{u2}) [_inst_2 : Mul.{u1} α] [_inst_3 : CommSemigroup.{u2} β], MulHom.{max u2 u1, max u1 u2} (MulHom.{u1, u2} α β _inst_2 (Semigroup.toHasMul.{u2} β (CommSemigroup.toSemigroup.{u2} β _inst_3))) (α -> β) (MulHom.hasMul.{u1, u2} α β _inst_2 _inst_3) (Pi.instMul.{u1, u2} α (fun (ᾰ : α) => β) (fun (i : α) => Semigroup.toHasMul.{u2} β (CommSemigroup.toSemigroup.{u2} β _inst_3)))
-but is expected to have type
-  forall (α : Type.{u1}) (β : Type.{u2}) [_inst_2 : Mul.{u1} α] [_inst_3 : CommSemigroup.{u2} β], MulHom.{max u2 u1, max u1 u2} (MulHom.{u1, u2} α β _inst_2 (Semigroup.toMul.{u2} β (CommSemigroup.toSemigroup.{u2} β _inst_3))) (α -> β) (MulHom.instMulMulHomToMulToSemigroup.{u1, u2} α β _inst_2 _inst_3) (Pi.instMul.{u1, u2} α (fun (ᾰ : α) => β) (fun (i : α) => Semigroup.toMul.{u2} β (CommSemigroup.toSemigroup.{u2} β _inst_3)))
-Case conversion may be inaccurate. Consider using '#align mul_hom.coe_fn MulHom.coeFnₓ'. -/
 /-- Coercion of a `mul_hom` into a function is itself a `mul_hom`.
 See also `mul_hom.eval`. -/
 @[to_additive
@@ -526,12 +502,6 @@ def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :
 #align add_monoid_hom.single AddMonoidHom.single
 -/
 
-/- warning: monoid_hom.single_apply -> MonoidHom.single_apply is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (coeFn.{max (succ (max u1 u2)) (succ u2), max (succ u2) (succ (max u1 u2))} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => (f i) -> (forall (i : I), f i)) (MonoidHom.hasCoeToFun.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x)
-but is expected to have type
-  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : f i) => forall (i : I), f i) x) (FunLike.coe.{max (succ u1) (succ u2), succ u2, max (succ u1) (succ u2)} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (fun (_x : f i) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : f i) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x)
-Case conversion may be inaccurate. Consider using '#align monoid_hom.single_apply MonoidHom.single_applyₓ'. -/
 @[simp, to_additive]
 theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
     MonoidHom.single f i x = mulSingle i x :=
@@ -539,12 +509,6 @@ theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
 #align monoid_hom.single_apply MonoidHom.single_apply
 #align add_monoid_hom.single_apply AddMonoidHom.single_apply
 
-/- warning: mul_hom.single -> MulHom.single is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (i : I), MulHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i)) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i)))
-but is expected to have type
-  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (i : I), MulHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i)) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toMul.{u2} (f i) (_inst_2 i)))
-Case conversion may be inaccurate. Consider using '#align mul_hom.single MulHom.singleₓ'. -/
 /-- The multiplicative homomorphism including a single `mul_zero_class`
 into a dependent family of `mul_zero_class`es, as functions supported at a point.
 
@@ -558,12 +522,6 @@ def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i
 
 variable {f}
 
-/- warning: pi.mul_single_sup -> Pi.mulSingle_sup is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeSup.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Sup.sup.{u2} (f i) (SemilatticeSup.toHasSup.{u2} (f i) (_inst_2 i)) x y)) (Sup.sup.{max u1 u2} (forall (i : I), f i) (Pi.hasSup.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeSup.toHasSup.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeSup.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Sup.sup.{u2} (f i) (SemilatticeSup.toSup.{u2} (f i) (_inst_2 i)) x y)) (Sup.sup.{max u2 u1} (forall (i : I), f i) (Pi.instSupForAll.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeSup.toSup.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
-Case conversion may be inaccurate. Consider using '#align pi.mul_single_sup Pi.mulSingle_supₓ'. -/
 @[to_additive]
 theorem Pi.mulSingle_sup [∀ i, SemilatticeSup (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
     Pi.mulSingle i (x ⊔ y) = Pi.mulSingle i x ⊔ Pi.mulSingle i y :=
@@ -571,12 +529,6 @@ theorem Pi.mulSingle_sup [∀ i, SemilatticeSup (f i)] [∀ i, One (f i)] (i : I
 #align pi.mul_single_sup Pi.mulSingle_sup
 #align pi.single_sup Pi.single_sup
 
-/- warning: pi.mul_single_inf -> Pi.mulSingle_inf is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeInf.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Inf.inf.{u2} (f i) (SemilatticeInf.toHasInf.{u2} (f i) (_inst_2 i)) x y)) (Inf.inf.{max u1 u2} (forall (i : I), f i) (Pi.hasInf.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeInf.toHasInf.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeInf.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Inf.inf.{u2} (f i) (SemilatticeInf.toInf.{u2} (f i) (_inst_2 i)) x y)) (Inf.inf.{max u2 u1} (forall (i : I), f i) (Pi.instInfForAll.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeInf.toInf.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
-Case conversion may be inaccurate. Consider using '#align pi.mul_single_inf Pi.mulSingle_infₓ'. -/
 @[to_additive]
 theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
     Pi.mulSingle i (x ⊓ y) = Pi.mulSingle i x ⊓ Pi.mulSingle i y :=
@@ -584,12 +536,6 @@ theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I
 #align pi.mul_single_inf Pi.mulSingle_inf
 #align pi.single_inf Pi.single_inf
 
-/- warning: pi.mul_single_mul -> Pi.mulSingle_mul is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulOneClass.toHasMul.{u2} (f i) (_inst_2 i))) x y)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toHasMul.{u2} (f i) (_inst_2 i)))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i y))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i))) x y)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toMul.{u2} (f i) (_inst_2 i)))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i y))
-Case conversion may be inaccurate. Consider using '#align pi.mul_single_mul Pi.mulSingle_mulₓ'. -/
 @[to_additive]
 theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
     mulSingle i (x * y) = mulSingle i x * mulSingle i y :=
@@ -597,12 +543,6 @@ theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
 #align pi.mul_single_mul Pi.mulSingle_mul
 #align pi.single_add Pi.single_add
 
-/- warning: pi.mul_single_inv -> Pi.mulSingle_inv is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), Group.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) i (Inv.inv.{u2} (f i) (DivInvMonoid.toHasInv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))) x)) (Inv.inv.{max u1 u2} (forall (i : I), f i) (Pi.instInv.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => DivInvMonoid.toHasInv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i)))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) i x))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), Group.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => InvOneClass.toOne.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) i (Inv.inv.{u2} (f i) (InvOneClass.toInv.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) x)) (Inv.inv.{max u2 u1} (forall (i : I), f i) (Pi.instInv.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => InvOneClass.toInv.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i)))))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => InvOneClass.toOne.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) i x))
-Case conversion may be inaccurate. Consider using '#align pi.mul_single_inv Pi.mulSingle_invₓ'. -/
 @[to_additive]
 theorem Pi.mulSingle_inv [∀ i, Group <| f i] (i : I) (x : f i) :
     mulSingle i x⁻¹ = (mulSingle i x)⁻¹ :=
@@ -610,12 +550,6 @@ theorem Pi.mulSingle_inv [∀ i, Group <| f i] (i : I) (x : f i) :
 #align pi.mul_single_inv Pi.mulSingle_inv
 #align pi.single_neg Pi.single_neg
 
-/- warning: pi.single_div -> Pi.single_div is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), Group.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) i (HDiv.hDiv.{u2, u2, u2} (f i) (f i) (f i) (instHDiv.{u2} (f i) (DivInvMonoid.toHasDiv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i)))) x y)) (HDiv.hDiv.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHDiv.{max u1 u2} (forall (i : I), f i) (Pi.instDiv.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => DivInvMonoid.toHasDiv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) i y))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), Group.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => InvOneClass.toOne.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) i (HDiv.hDiv.{u2, u2, u2} (f i) (f i) (f i) (instHDiv.{u2} (f i) (DivInvMonoid.toDiv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i)))) x y)) (HDiv.hDiv.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHDiv.{max u1 u2} (forall (i : I), f i) (Pi.instDiv.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => DivInvMonoid.toDiv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => InvOneClass.toOne.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) i x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => InvOneClass.toOne.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) i y))
-Case conversion may be inaccurate. Consider using '#align pi.single_div Pi.single_divₓ'. -/
 @[to_additive]
 theorem Pi.single_div [∀ i, Group <| f i] (i : I) (x y : f i) :
     mulSingle i (x / y) = mulSingle i x / mulSingle i y :=
@@ -623,67 +557,31 @@ theorem Pi.single_div [∀ i, Group <| f i] (i : I) (x y : f i) :
 #align pi.single_div Pi.single_div
 #align pi.single_sub Pi.single_sub
 
-/- warning: pi.single_mul -> Pi.single_mul is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) x y)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i)))) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i x) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i y))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) x y)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toMul.{u2} (f i) (_inst_2 i)))) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i x) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i y))
-Case conversion may be inaccurate. Consider using '#align pi.single_mul Pi.single_mulₓ'. -/
 theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
     single i (x * y) = single i x * single i y :=
   (MulHom.single f i).map_mul x y
 #align pi.single_mul Pi.single_mul
 
-/- warning: pi.single_mul_left_apply -> Pi.single_mul_left_apply is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) a (x i)) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toHasMul.{u2} (f j) (_inst_2 j))) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a j) (x j))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) a (x i)) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toMul.{u2} (f j) (_inst_2 j))) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a j) (x j))
-Case conversion may be inaccurate. Consider using '#align pi.single_mul_left_apply Pi.single_mul_left_applyₓ'. -/
 theorem Pi.single_mul_left_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (a * x i) j = Pi.single i a j * x j :=
   (Pi.apply_single (fun i => (· * x i)) (fun i => MulZeroClass.zero_mul _) _ _ _).symm
 #align pi.single_mul_left_apply Pi.single_mul_left_apply
 
-/- warning: pi.single_mul_right_apply -> Pi.single_mul_right_apply is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) (x i) a) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toHasMul.{u2} (f j) (_inst_2 j))) (x j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a j))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) (x i) a) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toMul.{u2} (f j) (_inst_2 j))) (x j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a j))
-Case conversion may be inaccurate. Consider using '#align pi.single_mul_right_apply Pi.single_mul_right_applyₓ'. -/
 theorem Pi.single_mul_right_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (x i * a) j = x j * Pi.single i a j :=
   (Pi.apply_single (fun i => (· * ·) (x i)) (fun i => MulZeroClass.mul_zero _) _ _ _).symm
 #align pi.single_mul_right_apply Pi.single_mul_right_apply
 
-/- warning: pi.single_mul_left -> Pi.single_mul_left is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) a (x i))) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i)))) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a) x)
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) a (x i))) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toMul.{u2} (f i) (_inst_2 i)))) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a) x)
-Case conversion may be inaccurate. Consider using '#align pi.single_mul_left Pi.single_mul_leftₓ'. -/
 theorem Pi.single_mul_left [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (a * x i) = Pi.single i a * x :=
   funext fun j => Pi.single_mul_left_apply _ _ _ _
 #align pi.single_mul_left Pi.single_mul_left
 
-/- warning: pi.single_mul_right -> Pi.single_mul_right is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) (x i) a)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i)))) x (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) (x i) a)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toMul.{u2} (f i) (_inst_2 i)))) x (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a))
-Case conversion may be inaccurate. Consider using '#align pi.single_mul_right Pi.single_mul_rightₓ'. -/
 theorem Pi.single_mul_right [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (x i * a) = x * Pi.single i a :=
   funext fun j => Pi.single_mul_right_apply _ _ _ _
 #align pi.single_mul_right Pi.single_mul_right
 
-/- warning: pi.mul_single_commute -> Pi.mulSingle_commute is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)], Pairwise.{u1} I (fun (i : I) (j : I) => forall (x : f i) (y : f j), Commute.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toHasMul.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) j y))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)], Pairwise.{u1} I (fun (i : I) (j : I) => forall (x : f i) (y : f j), Commute.{max u2 u1} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toMul.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) j y))
-Case conversion may be inaccurate. Consider using '#align pi.mul_single_commute Pi.mulSingle_commuteₓ'. -/
 /-- The injection into a pi group at different indices commutes.
 
 For injections of commuting elements at the same index, see `commute.map` -/
@@ -699,12 +597,6 @@ theorem Pi.mulSingle_commute [∀ i, MulOneClass <| f i] :
 #align pi.mul_single_commute Pi.mulSingle_commute
 #align pi.single_commute Pi.single_commute
 
-/- warning: pi.mul_single_apply_commute -> Pi.mulSingle_apply_commute is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (x : forall (i : I), f i) (i : I) (j : I), Commute.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toHasMul.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i (x i)) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) j (x j))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (x : forall (i : I), f i) (i : I) (j : I), Commute.{max u2 u1} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toMul.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i (x i)) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) j (x j))
-Case conversion may be inaccurate. Consider using '#align pi.mul_single_apply_commute Pi.mulSingle_apply_commuteₓ'. -/
 /-- The injection into a pi group with the same values commutes. -/
 @[to_additive "The injection into an additive pi group with the same values commutes."]
 theorem Pi.mulSingle_apply_commute [∀ i, MulOneClass <| f i] (x : ∀ i, f i) (i j : I) :
@@ -716,12 +608,6 @@ theorem Pi.mulSingle_apply_commute [∀ i, MulOneClass <| f i] (x : ∀ i, f i)
 #align pi.mul_single_apply_commute Pi.mulSingle_apply_commute
 #align pi.single_apply_commute Pi.single_apply_commute
 
-/- warning: pi.update_eq_div_mul_single -> Pi.update_eq_div_mul_mulSingle is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), Group.{u2} (f i)] (g : forall (i : I), f i) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (a : I), f a) (Function.update.{succ u1, succ u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) g i x) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (a : I), f a) (forall (a : I), f a) (forall (a : I), f a) (instHMul.{max u1 u2} (forall (a : I), f a) (Pi.instMul.{u1, u2} I (fun (a : I) => f a) (fun (i : I) => MulOneClass.toHasMul.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))))) (HDiv.hDiv.{max u1 u2, max u1 u2, max u1 u2} (forall (a : I), f a) (forall (a : I), f a) (forall (a : I), f a) (instHDiv.{max u1 u2} (forall (a : I), f a) (Pi.instDiv.{u1, u2} I (fun (a : I) => f a) (fun (i : I) => DivInvMonoid.toHasDiv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) g (Pi.mulSingle.{u1, u2} I (fun (a : I) => f a) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) i (g i))) (Pi.mulSingle.{u1, u2} I (fun (a : I) => f a) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) i x))
-but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), Group.{u2} (f i)] (g : forall (i : I), f i) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (a : I), f a) (Function.update.{succ u1, succ u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) g i x) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (a : I), f a) (forall (a : I), f a) (forall (a : I), f a) (instHMul.{max u1 u2} (forall (a : I), f a) (Pi.instMul.{u1, u2} I (fun (a : I) => f a) (fun (i : I) => MulOneClass.toMul.{u2} (f i) (Monoid.toMulOneClass.{u2} (f i) (DivInvMonoid.toMonoid.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))))) (HDiv.hDiv.{max u1 u2, max u1 u2, max u1 u2} (forall (a : I), f a) (forall (a : I), f a) (forall (a : I), f a) (instHDiv.{max u1 u2} (forall (a : I), f a) (Pi.instDiv.{u1, u2} I (fun (a : I) => f a) (fun (i : I) => DivInvMonoid.toDiv.{u2} (f i) (Group.toDivInvMonoid.{u2} (f i) (_inst_2 i))))) g (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => InvOneClass.toOne.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) i (g i))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => InvOneClass.toOne.{u2} (f i) (DivInvOneMonoid.toInvOneClass.{u2} (f i) (DivisionMonoid.toDivInvOneMonoid.{u2} (f i) (Group.toDivisionMonoid.{u2} (f i) (_inst_2 i))))) i x))
-Case conversion may be inaccurate. Consider using '#align pi.update_eq_div_mul_single Pi.update_eq_div_mul_mulSingleₓ'. -/
 @[to_additive update_eq_sub_add_single]
 theorem Pi.update_eq_div_mul_mulSingle [∀ i, Group <| f i] (g : ∀ i : I, f i) (x : f i) :
     Function.update g i x = g / mulSingle i (g i) * mulSingle i x :=
@@ -732,12 +618,6 @@ theorem Pi.update_eq_div_mul_mulSingle [∀ i, Group <| f i] (g : ∀ i : I, f i
   · simp [Function.update_noteq h.symm, h]
 #align pi.update_eq_div_mul_single Pi.update_eq_div_mul_mulSingle
 
-/- warning: pi.mul_single_mul_mul_single_eq_mul_single_mul_mul_single -> Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle is a dubious translation:
-lean 3 declaration is
-  forall {I : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} I] {M : Type.{u2}} [_inst_2 : CommMonoid.{u2} M] {k : I} {l : I} {m : I} {n : I} {u : M} {v : M}, (Ne.{succ u2} M u (OfNat.ofNat.{u2} M 1 (OfNat.mk.{u2} M 1 (One.one.{u2} M (MulOneClass.toHasOne.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))))))) -> (Ne.{succ u2} M v (OfNat.ofNat.{u2} M 1 (OfNat.mk.{u2} M 1 (One.one.{u2} M (MulOneClass.toHasOne.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))))))) -> (Iff (Eq.{succ (max u1 u2)} (I -> M) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (I -> M) (I -> M) (I -> M) (instHMul.{max u1 u2} (I -> M) (Pi.instMul.{u1, u2} I (fun (i : I) => M) (fun (i : I) => MulOneClass.toHasMul.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))))) (Pi.mulSingle.{u1, u2} I (fun {k : I} => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))) k u) (Pi.mulSingle.{u1, u2} I (fun (i : I) => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))) l v)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (I -> M) (I -> M) (I -> M) (instHMul.{max u1 u2} (I -> M) (Pi.instMul.{u1, u2} I (fun (i : I) => M) (fun (i : I) => MulOneClass.toHasMul.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))) m u) (Pi.mulSingle.{u1, u2} I (fun (i : I) => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))) n v))) (Or (And (Eq.{succ u1} I k m) (Eq.{succ u1} I l n)) (Or (And (Eq.{succ u2} M u v) (And (Eq.{succ u1} I k n) (Eq.{succ u1} I l m))) (And (Eq.{succ u2} M (HMul.hMul.{u2, u2, u2} M M M (instHMul.{u2} M (MulOneClass.toHasMul.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2)))) u v) (OfNat.ofNat.{u2} M 1 (OfNat.mk.{u2} M 1 (One.one.{u2} M (MulOneClass.toHasOne.{u2} M (Monoid.toMulOneClass.{u2} M (CommMonoid.toMonoid.{u2} M _inst_2))))))) (And (Eq.{succ u1} I k l) (Eq.{succ u1} I m n))))))
-but is expected to have type
-  forall {I : Type.{u2}} [_inst_1 : DecidableEq.{succ u2} I] {M : Type.{u1}} [_inst_2 : CommMonoid.{u1} M] {k : I} {l : I} {m : I} {n : I} {u : M} {v : M}, (Ne.{succ u1} M u (OfNat.ofNat.{u1} M 1 (One.toOfNat1.{u1} M (Monoid.toOne.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2))))) -> (Ne.{succ u1} M v (OfNat.ofNat.{u1} M 1 (One.toOfNat1.{u1} M (Monoid.toOne.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2))))) -> (Iff (Eq.{succ (max u2 u1)} (I -> M) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (I -> M) (I -> M) (I -> M) (instHMul.{max u2 u1} (I -> M) (Pi.instMul.{u2, u1} I (fun (i : I) => M) (fun (i : I) => MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2))))) (Pi.mulSingle.{u2, u1} I (fun (k : I) => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => Monoid.toOne.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2)) k u) (Pi.mulSingle.{u2, u1} I (fun (i : I) => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => Monoid.toOne.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2)) l v)) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (I -> M) (I -> M) (I -> M) (instHMul.{max u2 u1} (I -> M) (Pi.instMul.{u2, u1} I (fun (i : I) => M) (fun (i : I) => MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2))))) (Pi.mulSingle.{u2, u1} I (fun (i : I) => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => Monoid.toOne.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2)) m u) (Pi.mulSingle.{u2, u1} I (fun (i : I) => M) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => Monoid.toOne.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2)) n v))) (Or (And (Eq.{succ u2} I k m) (Eq.{succ u2} I l n)) (Or (And (Eq.{succ u1} M u v) (And (Eq.{succ u2} I k n) (Eq.{succ u2} I l m))) (And (Eq.{succ u1} M (HMul.hMul.{u1, u1, u1} M M M (instHMul.{u1} M (MulOneClass.toMul.{u1} M (Monoid.toMulOneClass.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2)))) u v) (OfNat.ofNat.{u1} M 1 (One.toOfNat1.{u1} M (Monoid.toOne.{u1} M (CommMonoid.toMonoid.{u1} M _inst_2))))) (And (Eq.{succ u2} I k l) (Eq.{succ u2} I m n))))))
-Case conversion may be inaccurate. Consider using '#align pi.mul_single_mul_mul_single_eq_mul_single_mul_mul_single Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingleₓ'. -/
 @[to_additive Pi.single_add_single_eq_single_add_single]
 theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type _} [CommMonoid M]
     {k l m n : I} {u v : M} (hu : u ≠ 1) (hv : v ≠ 1) :
@@ -813,24 +693,12 @@ theorem update_div [∀ i, Div (f i)] [DecidableEq I] (f₁ f₂ : ∀ i, f i) (
 
 variable [One α] [Nonempty ι] {a : α}
 
-/- warning: function.const_eq_one -> Function.const_eq_one is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u1}} {α : Type.{u2}} [_inst_1 : One.{u2} α] [_inst_2 : Nonempty.{succ u1} ι] {a : α}, Iff (Eq.{max (succ u1) (succ u2)} (ι -> α) (Function.const.{succ u2, succ u1} α ι a) (OfNat.ofNat.{max u1 u2} (ι -> α) 1 (OfNat.mk.{max u1 u2} (ι -> α) 1 (One.one.{max u1 u2} (ι -> α) (Pi.instOne.{u1, u2} ι (fun (ᾰ : ι) => α) (fun (i : ι) => _inst_1)))))) (Eq.{succ u2} α a (OfNat.ofNat.{u2} α 1 (OfNat.mk.{u2} α 1 (One.one.{u2} α _inst_1))))
-but is expected to have type
-  forall {ι : Type.{u2}} {α : Type.{u1}} [_inst_1 : One.{u1} α] [_inst_2 : Nonempty.{succ u2} ι] {a : α}, Iff (Eq.{max (succ u2) (succ u1)} (ι -> α) (Function.const.{succ u1, succ u2} α ι a) (OfNat.ofNat.{max u2 u1} (ι -> α) 1 (One.toOfNat1.{max u2 u1} (ι -> α) (Pi.instOne.{u2, u1} ι (fun (a._@.Init.Prelude._hyg.54 : ι) => α) (fun (i : ι) => _inst_1))))) (Eq.{succ u1} α a (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α _inst_1)))
-Case conversion may be inaccurate. Consider using '#align function.const_eq_one Function.const_eq_oneₓ'. -/
 @[simp, to_additive]
 theorem const_eq_one : const ι a = 1 ↔ a = 1 :=
   @const_inj _ _ _ _ 1
 #align function.const_eq_one Function.const_eq_one
 #align function.const_eq_zero Function.const_eq_zero
 
-/- warning: function.const_ne_one -> Function.const_ne_one is a dubious translation:
-lean 3 declaration is
-  forall {ι : Type.{u1}} {α : Type.{u2}} [_inst_1 : One.{u2} α] [_inst_2 : Nonempty.{succ u1} ι] {a : α}, Iff (Ne.{max (succ u1) (succ u2)} (ι -> α) (Function.const.{succ u2, succ u1} α ι a) (OfNat.ofNat.{max u1 u2} (ι -> α) 1 (OfNat.mk.{max u1 u2} (ι -> α) 1 (One.one.{max u1 u2} (ι -> α) (Pi.instOne.{u1, u2} ι (fun (ᾰ : ι) => α) (fun (i : ι) => _inst_1)))))) (Ne.{succ u2} α a (OfNat.ofNat.{u2} α 1 (OfNat.mk.{u2} α 1 (One.one.{u2} α _inst_1))))
-but is expected to have type
-  forall {ι : Type.{u2}} {α : Type.{u1}} [_inst_1 : One.{u1} α] [_inst_2 : Nonempty.{succ u2} ι] {a : α}, Iff (Ne.{max (succ u2) (succ u1)} (ι -> α) (Function.const.{succ u1, succ u2} α ι a) (OfNat.ofNat.{max u2 u1} (ι -> α) 1 (One.toOfNat1.{max u2 u1} (ι -> α) (Pi.instOne.{u2, u1} ι (fun (a._@.Init.Prelude._hyg.54 : ι) => α) (fun (i : ι) => _inst_1))))) (Ne.{succ u1} α a (OfNat.ofNat.{u1} α 1 (One.toOfNat1.{u1} α _inst_1)))
-Case conversion may be inaccurate. Consider using '#align function.const_ne_one Function.const_ne_oneₓ'. -/
 @[to_additive]
 theorem const_ne_one : const ι a ≠ 1 ↔ a ≠ 1 :=
   const_eq_one.Not
Diff
@@ -693,12 +693,8 @@ theorem Pi.mulSingle_commute [∀ i, MulOneClass <| f i] :
     Pairwise fun i j => ∀ (x : f i) (y : f j), Commute (mulSingle i x) (mulSingle j y) :=
   by
   intro i j hij x y; ext k
-  by_cases h1 : i = k;
-  · subst h1
-    simp [hij]
-  by_cases h2 : j = k;
-  · subst h2
-    simp [hij]
+  by_cases h1 : i = k; · subst h1; simp [hij]
+  by_cases h2 : j = k; · subst h2; simp [hij]
   simp [h1, h2]
 #align pi.mul_single_commute Pi.mulSingle_commute
 #align pi.single_commute Pi.single_commute
Diff
@@ -287,7 +287,7 @@ namespace MulHom
 lean 3 declaration is
   forall {M : Type.{u1}} {N : Type.{u2}} {mM : Mul.{u1} M} {mN : CommSemigroup.{u2} N} (f : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (g : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))), Eq.{max (succ u1) (succ u2)} (M -> N) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (M -> N) (M -> N) (M -> N) (instHMul.{max u1 u2} (M -> N) (Pi.instMul.{u1, u2} M (fun (ᾰ : M) => N) (fun (i : M) => Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g)) (fun (x : M) => HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f x) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g x))
 but is expected to have type
-  forall {M : Type.{u2}} {N : Type.{u1}} {mM : Mul.{u2} M} {mN : CommSemigroup.{u1} N} (f : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) (g : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))), Eq.{max (succ u2) (succ u1)} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (instHMul.{max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (Pi.instMul.{u2, u1} M (fun (ᾰ : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (fun (i : M) => Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) i) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) i) mN)))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g)) (fun (x : M) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) mN))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f x) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g x))
+  forall {M : Type.{u2}} {N : Type.{u1}} {mM : Mul.{u2} M} {mN : CommSemigroup.{u1} N} (f : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) (g : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))), Eq.{max (succ u2) (succ u1)} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (instHMul.{max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (Pi.instMul.{u2, u1} M (fun (ᾰ : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) ᾰ) (fun (i : M) => Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) i) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) i) mN)))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g)) (fun (x : M) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) (Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) x) mN))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f x) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g x))
 Case conversion may be inaccurate. Consider using '#align mul_hom.coe_mul MulHom.coe_mulₓ'. -/
 @[to_additive]
 theorem coe_mul {M N} {mM : Mul M} {mN : CommSemigroup N} (f g : M →ₙ* N) :
@@ -344,7 +344,7 @@ def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g :
 lean 3 declaration is
   forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (coeFn.{max (succ u2) (succ u3), max (succ u3) (succ u2)} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (fun (_x : MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) => γ -> (f i)) (MonoidHom.hasCoeToFun.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), (fun (i : I) => f i) i) (coeFn.{max (succ (max u1 u2)) (succ u3), max (succ u3) (succ (max u1 u2))} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => γ -> (forall (i : I), (fun (i : I) => f i) i)) (MonoidHom.hasCoeToFun.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
 but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (FunLike.coe.{max (succ u2) (succ u3), succ u3, succ u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : γ) => f i) _x) (MulHomClass.toFunLike.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MonoidHomClass.toMulHomClass.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) _inst_3 (_inst_2 i) (MonoidHom.monoidHomClass.{u3, u2} γ (f i) _inst_3 (_inst_2 i)))) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), f i) (FunLike.coe.{max (max (succ u1) (succ u2)) (succ u3), succ u3, max (succ u1) (succ u2)} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : γ) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (FunLike.coe.{max (succ u2) (succ u3), succ u3, succ u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : γ) => f i) _x) (MulHomClass.toFunLike.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MonoidHomClass.toMulHomClass.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) _inst_3 (_inst_2 i) (MonoidHom.monoidHomClass.{u3, u2} γ (f i) _inst_3 (_inst_2 i)))) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), f i) (FunLike.coe.{max (max (succ u1) (succ u2)) (succ u3), succ u3, max (succ u1) (succ u2)} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : γ) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
 Case conversion may be inaccurate. Consider using '#align pi.monoid_hom_injective Pi.monoidHom_injectiveₓ'. -/
 @[to_additive]
 theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f i)] [MulOneClass γ]
@@ -530,7 +530,7 @@ def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :
 lean 3 declaration is
   forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (coeFn.{max (succ (max u1 u2)) (succ u2), max (succ u2) (succ (max u1 u2))} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => (f i) -> (forall (i : I), f i)) (MonoidHom.hasCoeToFun.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x)
 but is expected to have type
-  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : f i) => forall (i : I), f i) x) (FunLike.coe.{max (succ u1) (succ u2), succ u2, max (succ u1) (succ u2)} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (fun (_x : f i) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : f i) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x)
+  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : f i) => forall (i : I), f i) x) (FunLike.coe.{max (succ u1) (succ u2), succ u2, max (succ u1) (succ u2)} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (fun (_x : f i) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2397 : f i) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x)
 Case conversion may be inaccurate. Consider using '#align monoid_hom.single_apply MonoidHom.single_applyₓ'. -/
 @[simp, to_additive]
 theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
Diff
@@ -558,6 +558,12 @@ def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i
 
 variable {f}
 
+/- warning: pi.mul_single_sup -> Pi.mulSingle_sup is a dubious translation:
+lean 3 declaration is
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeSup.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Sup.sup.{u2} (f i) (SemilatticeSup.toHasSup.{u2} (f i) (_inst_2 i)) x y)) (Sup.sup.{max u1 u2} (forall (i : I), f i) (Pi.hasSup.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeSup.toHasSup.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
+but is expected to have type
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeSup.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Sup.sup.{u2} (f i) (SemilatticeSup.toSup.{u2} (f i) (_inst_2 i)) x y)) (Sup.sup.{max u2 u1} (forall (i : I), f i) (Pi.instSupForAll.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeSup.toSup.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
+Case conversion may be inaccurate. Consider using '#align pi.mul_single_sup Pi.mulSingle_supₓ'. -/
 @[to_additive]
 theorem Pi.mulSingle_sup [∀ i, SemilatticeSup (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
     Pi.mulSingle i (x ⊔ y) = Pi.mulSingle i x ⊔ Pi.mulSingle i y :=
@@ -565,6 +571,12 @@ theorem Pi.mulSingle_sup [∀ i, SemilatticeSup (f i)] [∀ i, One (f i)] (i : I
 #align pi.mul_single_sup Pi.mulSingle_sup
 #align pi.single_sup Pi.single_sup
 
+/- warning: pi.mul_single_inf -> Pi.mulSingle_inf is a dubious translation:
+lean 3 declaration is
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeInf.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Inf.inf.{u2} (f i) (SemilatticeInf.toHasInf.{u2} (f i) (_inst_2 i)) x y)) (Inf.inf.{max u1 u2} (forall (i : I), f i) (Pi.hasInf.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeInf.toHasInf.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
+but is expected to have type
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), SemilatticeInf.{u2} (f i)] [_inst_3 : forall (i : I), One.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i (Inf.inf.{u2} (f i) (SemilatticeInf.toInf.{u2} (f i) (_inst_2 i)) x y)) (Inf.inf.{max u2 u1} (forall (i : I), f i) (Pi.instInfForAll.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => SemilatticeInf.toInf.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_3 i) i y))
+Case conversion may be inaccurate. Consider using '#align pi.mul_single_inf Pi.mulSingle_infₓ'. -/
 @[to_additive]
 theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
     Pi.mulSingle i (x ⊓ y) = Pi.mulSingle i x ⊓ Pi.mulSingle i y :=
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 
 ! This file was ported from Lean 3 source module algebra.group.pi
-! leanprover-community/mathlib commit 90df25ded755a2cf9651ea850d1abe429b1e4eb1
+! leanprover-community/mathlib commit e4bc74cbaf429d706cb9140902f7ca6c431e75a4
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -558,6 +558,20 @@ def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i
 
 variable {f}
 
+@[to_additive]
+theorem Pi.mulSingle_sup [∀ i, SemilatticeSup (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
+    Pi.mulSingle i (x ⊔ y) = Pi.mulSingle i x ⊔ Pi.mulSingle i y :=
+  Function.update_sup _ _ _ _
+#align pi.mul_single_sup Pi.mulSingle_sup
+#align pi.single_sup Pi.single_sup
+
+@[to_additive]
+theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
+    Pi.mulSingle i (x ⊓ y) = Pi.mulSingle i x ⊓ Pi.mulSingle i y :=
+  Function.update_inf _ _ _ _
+#align pi.mul_single_inf Pi.mulSingle_inf
+#align pi.single_inf Pi.single_inf
+
 /- warning: pi.mul_single_mul -> Pi.mulSingle_mul is a dubious translation:
 lean 3 declaration is
   forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i) (y : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulOneClass.toHasMul.{u2} (f i) (_inst_2 i))) x y)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toHasMul.{u2} (f i) (_inst_2 i)))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i y))
Diff
@@ -40,7 +40,7 @@ variable (x y : ∀ i, f i) (i j : I)
 lean 3 declaration is
   forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : One.{u2} β] (s : Set.{u2} β) [_inst_2 : Decidable (Membership.Mem.{u2, u2} β (Set.{u2} β) (Set.hasMem.{u2} β) (OfNat.ofNat.{u2} β 1 (OfNat.mk.{u2} β 1 (One.one.{u2} β _inst_1))) s)], Eq.{succ u1} (Set.{u1} α) (Set.preimage.{u1, u2} α β (OfNat.ofNat.{max u1 u2} (α -> β) 1 (OfNat.mk.{max u1 u2} (α -> β) 1 (One.one.{max u1 u2} (α -> β) (Pi.instOne.{u1, u2} α (fun (ᾰ : α) => β) (fun (i : α) => _inst_1))))) s) (ite.{succ u1} (Set.{u1} α) (Membership.Mem.{u2, u2} β (Set.{u2} β) (Set.hasMem.{u2} β) (OfNat.ofNat.{u2} β 1 (OfNat.mk.{u2} β 1 (One.one.{u2} β _inst_1))) s) _inst_2 (Set.univ.{u1} α) (EmptyCollection.emptyCollection.{u1} (Set.{u1} α) (Set.hasEmptyc.{u1} α)))
 but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : One.{u1} β] (s : Set.{u1} β) [_inst_2 : Decidable (Membership.mem.{u1, u1} β (Set.{u1} β) (Set.instMembershipSet.{u1} β) (OfNat.ofNat.{u1} β 1 (One.toOfNat1.{u1} β _inst_1)) s)], Eq.{succ u2} (Set.{u2} α) (Set.preimage.{u2, u1} α β (OfNat.ofNat.{max u2 u1} (α -> β) 1 (One.toOfNat1.{max u2 u1} (α -> β) (Pi.instOne.{u2, u1} α (fun (a._@.Mathlib.Algebra.Group.Pi._hyg.90 : α) => β) (fun (i : α) => _inst_1)))) s) (ite.{succ u2} (Set.{u2} α) (Membership.mem.{u1, u1} β (Set.{u1} β) (Set.instMembershipSet.{u1} β) (OfNat.ofNat.{u1} β 1 (One.toOfNat1.{u1} β _inst_1)) s) _inst_2 (Set.univ.{u2} α) (EmptyCollection.emptyCollection.{u2} (Set.{u2} α) (Set.instEmptyCollectionSet.{u2} α)))
+  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : One.{u1} β] (s : Set.{u1} β) [_inst_2 : Decidable (Membership.mem.{u1, u1} β (Set.{u1} β) (Set.instMembershipSet.{u1} β) (OfNat.ofNat.{u1} β 1 (One.toOfNat1.{u1} β _inst_1)) s)], Eq.{succ u2} (Set.{u2} α) (Set.preimage.{u2, u1} α β (OfNat.ofNat.{max u2 u1} (α -> β) 1 (One.toOfNat1.{max u2 u1} (α -> β) (Pi.instOne.{u2, u1} α (fun (a._@.Mathlib.Algebra.Group.Pi._hyg.93 : α) => β) (fun (i : α) => _inst_1)))) s) (ite.{succ u2} (Set.{u2} α) (Membership.mem.{u1, u1} β (Set.{u1} β) (Set.instMembershipSet.{u1} β) (OfNat.ofNat.{u1} β 1 (One.toOfNat1.{u1} β _inst_1)) s) _inst_2 (Set.univ.{u2} α) (EmptyCollection.emptyCollection.{u2} (Set.{u2} α) (Set.instEmptyCollectionSet.{u2} α)))
 Case conversion may be inaccurate. Consider using '#align set.preimage_one Set.preimage_oneₓ'. -/
 @[to_additive]
 theorem Set.preimage_one {α β : Type _} [One β] (s : Set β) [Decidable ((1 : β) ∈ s)] :
@@ -608,21 +608,45 @@ theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
   (MulHom.single f i).map_mul x y
 #align pi.single_mul Pi.single_mul
 
+/- warning: pi.single_mul_left_apply -> Pi.single_mul_left_apply is a dubious translation:
+lean 3 declaration is
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) a (x i)) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toHasMul.{u2} (f j) (_inst_2 j))) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a j) (x j))
+but is expected to have type
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) a (x i)) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toMul.{u2} (f j) (_inst_2 j))) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a j) (x j))
+Case conversion may be inaccurate. Consider using '#align pi.single_mul_left_apply Pi.single_mul_left_applyₓ'. -/
 theorem Pi.single_mul_left_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (a * x i) j = Pi.single i a j * x j :=
   (Pi.apply_single (fun i => (· * x i)) (fun i => MulZeroClass.zero_mul _) _ _ _).symm
 #align pi.single_mul_left_apply Pi.single_mul_left_apply
 
+/- warning: pi.single_mul_right_apply -> Pi.single_mul_right_apply is a dubious translation:
+lean 3 declaration is
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) (x i) a) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toHasMul.{u2} (f j) (_inst_2 j))) (x j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a j))
+but is expected to have type
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) (j : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{succ u2} (f j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) (x i) a) j) (HMul.hMul.{u2, u2, u2} (f j) (f j) (f j) (instHMul.{u2} (f j) (MulZeroClass.toMul.{u2} (f j) (_inst_2 j))) (x j) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a j))
+Case conversion may be inaccurate. Consider using '#align pi.single_mul_right_apply Pi.single_mul_right_applyₓ'. -/
 theorem Pi.single_mul_right_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (x i * a) j = x j * Pi.single i a j :=
   (Pi.apply_single (fun i => (· * ·) (x i)) (fun i => MulZeroClass.mul_zero _) _ _ _).symm
 #align pi.single_mul_right_apply Pi.single_mul_right_apply
 
+/- warning: pi.single_mul_left -> Pi.single_mul_left is a dubious translation:
+lean 3 declaration is
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) a (x i))) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i)))) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a) x)
+but is expected to have type
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) a (x i))) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toMul.{u2} (f i) (_inst_2 i)))) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a) x)
+Case conversion may be inaccurate. Consider using '#align pi.single_mul_left Pi.single_mul_leftₓ'. -/
 theorem Pi.single_mul_left [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (a * x i) = Pi.single i a * x :=
   funext fun j => Pi.single_mul_left_apply _ _ _ _
 #align pi.single_mul_left Pi.single_mul_left
 
+/- warning: pi.single_mul_right -> Pi.single_mul_right is a dubious translation:
+lean 3 declaration is
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i))) (x i) a)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toHasMul.{u2} (f i) (_inst_2 i)))) x (Pi.single.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toHasZero.{u2} (f i) (_inst_2 i)) i a))
+but is expected to have type
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} (x : forall (i : I), f i) (i : I) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulZeroClass.{u2} (f i)] (a : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i (HMul.hMul.{u2, u2, u2} (f i) (f i) (f i) (instHMul.{u2} (f i) (MulZeroClass.toMul.{u2} (f i) (_inst_2 i))) (x i) a)) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (forall (i : I), f i) (forall (i : I), f i) (forall (i : I), f i) (instHMul.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulZeroClass.toMul.{u2} (f i) (_inst_2 i)))) x (Pi.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulZeroClass.toZero.{u2} (f i) (_inst_2 i)) i a))
+Case conversion may be inaccurate. Consider using '#align pi.single_mul_right Pi.single_mul_rightₓ'. -/
 theorem Pi.single_mul_right [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (x i * a) = x * Pi.single i a :=
   funext fun j => Pi.single_mul_right_apply _ _ _ _
@@ -848,17 +872,21 @@ namespace Pi
 
 variable [DecidableEq I] [∀ i, Preorder (f i)] [∀ i, One (f i)]
 
+#print Pi.mulSingle_mono /-
 @[to_additive]
 theorem mulSingle_mono : Monotone (Pi.mulSingle i : f i → ∀ i, f i) :=
   Function.update_mono
 #align pi.mul_single_mono Pi.mulSingle_mono
 #align pi.single_mono Pi.single_mono
+-/
 
+#print Pi.mulSingle_strictMono /-
 @[to_additive]
 theorem mulSingle_strictMono : StrictMono (Pi.mulSingle i : f i → ∀ i, f i) :=
   Function.update_strictMono
 #align pi.mul_single_strict_mono Pi.mulSingle_strictMono
 #align pi.single_strict_mono Pi.single_strictMono
+-/
 
 end Pi
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 
 ! This file was ported from Lean 3 source module algebra.group.pi
-! leanprover-community/mathlib commit 246f6f7989ff86bd07e1b014846f11304f33cf9e
+! leanprover-community/mathlib commit 90df25ded755a2cf9651ea850d1abe429b1e4eb1
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -844,3 +844,21 @@ noncomputable def Function.ExtendByOne.hom [MulOneClass R] : (ι → R) →* η
 
 end Extend
 
+namespace Pi
+
+variable [DecidableEq I] [∀ i, Preorder (f i)] [∀ i, One (f i)]
+
+@[to_additive]
+theorem mulSingle_mono : Monotone (Pi.mulSingle i : f i → ∀ i, f i) :=
+  Function.update_mono
+#align pi.mul_single_mono Pi.mulSingle_mono
+#align pi.single_mono Pi.single_mono
+
+@[to_additive]
+theorem mulSingle_strictMono : StrictMono (Pi.mulSingle i : f i → ∀ i, f i) :=
+  Function.update_strictMono
+#align pi.mul_single_strict_mono Pi.mulSingle_strictMono
+#align pi.single_strict_mono Pi.single_strictMono
+
+end Pi
+
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 
 ! This file was ported from Lean 3 source module algebra.group.pi
-! leanprover-community/mathlib commit c3291da49cfa65f0d43b094750541c0731edc932
+! leanprover-community/mathlib commit 246f6f7989ff86bd07e1b014846f11304f33cf9e
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -34,7 +34,7 @@ variable {I : Type u}
 variable {f : I → Type v}
 
 -- The family of types already equipped with instances
-variable (x y : ∀ i, f i) (i : I)
+variable (x y : ∀ i, f i) (i j : I)
 
 /- warning: set.preimage_one -> Set.preimage_one is a dubious translation:
 lean 3 declaration is
@@ -608,6 +608,26 @@ theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
   (MulHom.single f i).map_mul x y
 #align pi.single_mul Pi.single_mul
 
+theorem Pi.single_mul_left_apply [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (a * x i) j = Pi.single i a j * x j :=
+  (Pi.apply_single (fun i => (· * x i)) (fun i => MulZeroClass.zero_mul _) _ _ _).symm
+#align pi.single_mul_left_apply Pi.single_mul_left_apply
+
+theorem Pi.single_mul_right_apply [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (x i * a) j = x j * Pi.single i a j :=
+  (Pi.apply_single (fun i => (· * ·) (x i)) (fun i => MulZeroClass.mul_zero _) _ _ _).symm
+#align pi.single_mul_right_apply Pi.single_mul_right_apply
+
+theorem Pi.single_mul_left [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (a * x i) = Pi.single i a * x :=
+  funext fun j => Pi.single_mul_left_apply _ _ _ _
+#align pi.single_mul_left Pi.single_mul_left
+
+theorem Pi.single_mul_right [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (x i * a) = x * Pi.single i a :=
+  funext fun j => Pi.single_mul_right_apply _ _ _ _
+#align pi.single_mul_right Pi.single_mul_right
+
 /- warning: pi.mul_single_commute -> Pi.mulSingle_commute is a dubious translation:
 lean 3 declaration is
   forall {I : Type.{u1}} {f : I -> Type.{u2}} [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)], Pairwise.{u1} I (fun (i : I) (j : I) => forall (x : f i) (y : f j), Commute.{max u1 u2} (forall (i : I), f i) (Pi.instMul.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => MulOneClass.toHasMul.{u2} (f i) (_inst_2 i))) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) j y))
Diff
@@ -287,7 +287,7 @@ namespace MulHom
 lean 3 declaration is
   forall {M : Type.{u1}} {N : Type.{u2}} {mM : Mul.{u1} M} {mN : CommSemigroup.{u2} N} (f : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (g : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))), Eq.{max (succ u1) (succ u2)} (M -> N) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (M -> N) (M -> N) (M -> N) (instHMul.{max u1 u2} (M -> N) (Pi.instMul.{u1, u2} M (fun (ᾰ : M) => N) (fun (i : M) => Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g)) (fun (x : M) => HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f x) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g x))
 but is expected to have type
-  forall {M : Type.{u2}} {N : Type.{u1}} {mM : Mul.{u2} M} {mN : CommSemigroup.{u1} N} (f : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) (g : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))), Eq.{max (succ u2) (succ u1)} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (instHMul.{max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (Pi.instMul.{u2, u1} M (fun (ᾰ : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (fun (i : M) => Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) i) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) i) mN)))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g)) (fun (x : M) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) (Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) mN))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f x) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g x))
+  forall {M : Type.{u2}} {N : Type.{u1}} {mM : Mul.{u2} M} {mN : CommSemigroup.{u1} N} (f : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) (g : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))), Eq.{max (succ u2) (succ u1)} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (instHMul.{max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (Pi.instMul.{u2, u1} M (fun (ᾰ : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) ᾰ) (fun (i : M) => Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) i) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) i) mN)))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g)) (fun (x : M) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) x) mN))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f x) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g x))
 Case conversion may be inaccurate. Consider using '#align mul_hom.coe_mul MulHom.coe_mulₓ'. -/
 @[to_additive]
 theorem coe_mul {M N} {mM : Mul M} {mN : CommSemigroup N} (f g : M →ₙ* N) :
@@ -344,7 +344,7 @@ def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g :
 lean 3 declaration is
   forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (coeFn.{max (succ u2) (succ u3), max (succ u3) (succ u2)} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (fun (_x : MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) => γ -> (f i)) (MonoidHom.hasCoeToFun.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), (fun (i : I) => f i) i) (coeFn.{max (succ (max u1 u2)) (succ u3), max (succ u3) (succ (max u1 u2))} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => γ -> (forall (i : I), (fun (i : I) => f i) i)) (MonoidHom.hasCoeToFun.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
 but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (FunLike.coe.{max (succ u2) (succ u3), succ u3, succ u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : γ) => f i) _x) (MulHomClass.toFunLike.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MonoidHomClass.toMulHomClass.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) _inst_3 (_inst_2 i) (MonoidHom.monoidHomClass.{u3, u2} γ (f i) _inst_3 (_inst_2 i)))) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), f i) (FunLike.coe.{max (max (succ u1) (succ u2)) (succ u3), succ u3, max (succ u1) (succ u2)} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : γ) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (FunLike.coe.{max (succ u2) (succ u3), succ u3, succ u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : γ) => f i) _x) (MulHomClass.toFunLike.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MonoidHomClass.toMulHomClass.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) _inst_3 (_inst_2 i) (MonoidHom.monoidHomClass.{u3, u2} γ (f i) _inst_3 (_inst_2 i)))) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), f i) (FunLike.coe.{max (max (succ u1) (succ u2)) (succ u3), succ u3, max (succ u1) (succ u2)} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : γ) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
 Case conversion may be inaccurate. Consider using '#align pi.monoid_hom_injective Pi.monoidHom_injectiveₓ'. -/
 @[to_additive]
 theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f i)] [MulOneClass γ]
@@ -530,7 +530,7 @@ def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :
 lean 3 declaration is
   forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (coeFn.{max (succ (max u1 u2)) (succ u2), max (succ u2) (succ (max u1 u2))} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => (f i) -> (forall (i : I), f i)) (MonoidHom.hasCoeToFun.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x)
 but is expected to have type
-  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : f i) => forall (i : I), f i) x) (FunLike.coe.{max (succ u1) (succ u2), succ u2, max (succ u1) (succ u2)} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (fun (_x : f i) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : f i) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x)
+  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : f i) => forall (i : I), f i) x) (FunLike.coe.{max (succ u1) (succ u2), succ u2, max (succ u1) (succ u2)} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (fun (_x : f i) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : f i) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x)
 Case conversion may be inaccurate. Consider using '#align monoid_hom.single_apply MonoidHom.single_applyₓ'. -/
 @[simp, to_additive]
 theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
Diff
@@ -553,7 +553,7 @@ This is the `mul_hom` version of `pi.single`. -/
 def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i
     where
   toFun := single i
-  map_mul' := Pi.single_op₂ (fun _ => (· * ·)) (fun _ => zero_mul _) _
+  map_mul' := Pi.single_op₂ (fun _ => (· * ·)) (fun _ => MulZeroClass.zero_mul _) _
 #align mul_hom.single MulHom.single
 
 variable {f}
Diff
@@ -287,7 +287,7 @@ namespace MulHom
 lean 3 declaration is
   forall {M : Type.{u1}} {N : Type.{u2}} {mM : Mul.{u1} M} {mN : CommSemigroup.{u2} N} (f : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (g : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))), Eq.{max (succ u1) (succ u2)} (M -> N) (HMul.hMul.{max u1 u2, max u1 u2, max u1 u2} (M -> N) (M -> N) (M -> N) (instHMul.{max u1 u2} (M -> N) (Pi.instMul.{u1, u2} M (fun (ᾰ : M) => N) (fun (i : M) => Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN)))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g)) (fun (x : M) => HMul.hMul.{u2, u2, u2} N N N (instHMul.{u2} N (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) f x) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) (fun (_x : MulHom.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) => M -> N) (MulHom.hasCoeToFun.{u1, u2} M N mM (Semigroup.toHasMul.{u2} N (CommSemigroup.toSemigroup.{u2} N mN))) g x))
 but is expected to have type
-  forall {M : Type.{u2}} {N : Type.{u1}} {mM : Mul.{u2} M} {mN : CommSemigroup.{u1} N} (f : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) (g : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))), Eq.{max (succ u2) (succ u1)} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) ᾰ) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) ᾰ) (instHMul.{max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) ᾰ) (Pi.instMul.{u2, u1} M (fun (ᾰ : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) ᾰ) (fun (i : M) => Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) i) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) i) mN)))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g)) (fun (x : M) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) x) (Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) x) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) x) mN))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f x) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g x))
+  forall {M : Type.{u2}} {N : Type.{u1}} {mM : Mul.{u2} M} {mN : CommSemigroup.{u1} N} (f : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) (g : MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))), Eq.{max (succ u2) (succ u1)} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (HMul.hMul.{max u2 u1, max u2 u1, max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (instHMul.{max u2 u1} (forall (ᾰ : M), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (Pi.instMul.{u2, u1} M (fun (ᾰ : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) ᾰ) (fun (i : M) => Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) i) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) i) mN)))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g)) (fun (x : M) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) (Semigroup.toMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) (CommSemigroup.toSemigroup.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) x) mN))) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) f x) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M (fun (_x : M) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : M) => N) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (MulHom.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN))) M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)) (MulHom.mulHomClass.{u2, u1} M N mM (Semigroup.toMul.{u1} N (CommSemigroup.toSemigroup.{u1} N mN)))) g x))
 Case conversion may be inaccurate. Consider using '#align mul_hom.coe_mul MulHom.coe_mulₓ'. -/
 @[to_additive]
 theorem coe_mul {M N} {mM : Mul M} {mN : CommSemigroup N} (f g : M →ₙ* N) :
@@ -344,7 +344,7 @@ def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g :
 lean 3 declaration is
   forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (coeFn.{max (succ u2) (succ u3), max (succ u3) (succ u2)} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (fun (_x : MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) => γ -> (f i)) (MonoidHom.hasCoeToFun.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), (fun (i : I) => f i) i) (coeFn.{max (succ (max u1 u2)) (succ u3), max (succ u3) (succ (max u1 u2))} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => γ -> (forall (i : I), (fun (i : I) => f i) i)) (MonoidHom.hasCoeToFun.{u3, max u1 u2} γ (forall (i : I), (fun (i : I) => f i) i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => (fun (i : I) => f i) i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
 but is expected to have type
-  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (FunLike.coe.{max (succ u2) (succ u3), succ u3, succ u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : γ) => f i) _x) (MulHomClass.toFunLike.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MonoidHomClass.toMulHomClass.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) _inst_3 (_inst_2 i) (MonoidHom.monoidHomClass.{u3, u2} γ (f i) _inst_3 (_inst_2 i)))) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), f i) (FunLike.coe.{max (max (succ u1) (succ u2)) (succ u3), succ u3, max (succ u1) (succ u2)} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : γ) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
+  forall {I : Type.{u1}} {f : I -> Type.{u2}} {γ : Type.{u3}} [_inst_1 : Nonempty.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] [_inst_3 : MulOneClass.{u3} γ] (g : forall (i : I), MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)), (forall (i : I), Function.Injective.{succ u3, succ u2} γ (f i) (FunLike.coe.{max (succ u2) (succ u3), succ u3, succ u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : γ) => f i) _x) (MulHomClass.toFunLike.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MonoidHomClass.toMulHomClass.{max u2 u3, u3, u2} (MonoidHom.{u3, u2} γ (f i) _inst_3 (_inst_2 i)) γ (f i) _inst_3 (_inst_2 i) (MonoidHom.monoidHomClass.{u3, u2} γ (f i) _inst_3 (_inst_2 i)))) (g i))) -> (Function.Injective.{succ u3, max (succ u1) (succ u2)} γ (forall (i : I), f i) (FunLike.coe.{max (max (succ u1) (succ u2)) (succ u3), succ u3, max (succ u1) (succ u2)} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (fun (_x : γ) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : γ) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) (MulOneClass.toMul.{u3} γ _inst_3) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max (max u1 u2) u3, u3, max u1 u2} (MonoidHom.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u3, max u1 u2} γ (forall (i : I), f i) _inst_3 (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (Pi.monoidHom.{u1, u2, u3} I (fun (i : I) => f i) γ (fun (i : I) => _inst_2 i) _inst_3 g)))
 Case conversion may be inaccurate. Consider using '#align pi.monoid_hom_injective Pi.monoidHom_injectiveₓ'. -/
 @[to_additive]
 theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f i)] [MulOneClass γ]
@@ -530,7 +530,7 @@ def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :
 lean 3 declaration is
   forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} (forall (i : I), f i) (coeFn.{max (succ (max u1 u2)) (succ u2), max (succ u2) (succ (max u1 u2))} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (fun (_x : MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) => (f i) -> (forall (i : I), f i)) (MonoidHom.hasCoeToFun.{u2, max u1 u2} (f i) (forall (i : I), f i) ((fun (i : I) => _inst_2 i) i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => (fun (i : I) => _inst_2 i) i))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I (fun (i : I) => f i) (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toHasOne.{u2} (f i) (_inst_2 i)) i x)
 but is expected to have type
-  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : f i) => forall (i : I), f i) x) (FunLike.coe.{max (succ u1) (succ u2), succ u2, max (succ u1) (succ u2)} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (fun (_x : f i) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2398 : f i) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x)
+  forall {I : Type.{u1}} (f : I -> Type.{u2}) [_inst_1 : DecidableEq.{succ u1} I] [_inst_2 : forall (i : I), MulOneClass.{u2} (f i)] (i : I) (x : f i), Eq.{max (succ u1) (succ u2)} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : f i) => forall (i : I), f i) x) (FunLike.coe.{max (succ u1) (succ u2), succ u2, max (succ u1) (succ u2)} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (fun (_x : f i) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2372 : f i) => forall (i : I), f i) _x) (MulHomClass.toFunLike.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (MulOneClass.toMul.{u2} (f i) (_inst_2 i)) (MulOneClass.toMul.{max u1 u2} (forall (i : I), f i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (MonoidHomClass.toMulHomClass.{max u1 u2, u2, max u1 u2} (MonoidHom.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))) (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i)) (MonoidHom.monoidHomClass.{u2, max u1 u2} (f i) (forall (i : I), f i) (_inst_2 i) (Pi.mulOneClass.{u1, u2} I (fun (i : I) => f i) (fun (i : I) => _inst_2 i))))) (MonoidHom.single.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => _inst_2 i) i) x) (Pi.mulSingle.{u1, u2} I f (fun (a : I) (b : I) => _inst_1 a b) (fun (i : I) => MulOneClass.toOne.{u2} (f i) (_inst_2 i)) i x)
 Case conversion may be inaccurate. Consider using '#align monoid_hom.single_apply MonoidHom.single_applyₓ'. -/
 @[simp, to_additive]
 theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :

Changes in mathlib4

mathlib3
mathlib4
chore: Move monoid with zero instances on pi types (#12286)

Move everything that can't be additivised out of Algebra.Group.Pi.Lemmas:

Diff
@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 -/
 import Mathlib.Algebra.Group.Hom.Instances
-import Mathlib.Data.Int.Cast.Defs
 import Mathlib.Data.Set.Function
 import Mathlib.Logic.Pairwise
 
@@ -17,6 +16,10 @@ This file proves lemmas about the instances defined in `Algebra.Group.Pi.Basic`
 imports.
 -/
 
+assert_not_exists AddMonoidWithOne
+-- TODO (after #11855)
+-- assert_not_exists MulZeroClass
+
 universe u v w
 
 variable {ι α : Type*}
@@ -35,49 +38,6 @@ theorem Set.preimage_one {α β : Type*} [One β] (s : Set β) [Decidable ((1 :
 #align set.preimage_one Set.preimage_one
 #align set.preimage_zero Set.preimage_zero
 
-namespace Pi
-
-instance addMonoidWithOne [∀ i, AddMonoidWithOne <| f i] : AddMonoidWithOne (∀ i : I, f i) :=
-  { addMonoid with
-    natCast := fun n _ => n
-    natCast_zero := funext fun _ => AddMonoidWithOne.natCast_zero
-    natCast_succ := fun n => funext fun _ => AddMonoidWithOne.natCast_succ n
-  }
-
-instance addGroupWithOne [∀ i, AddGroupWithOne <| f i] : AddGroupWithOne (∀ i : I, f i) :=
-  { addGroup, addMonoidWithOne with
-    intCast := fun z _ => z
-    intCast_ofNat := fun n => funext fun _ => AddGroupWithOne.intCast_ofNat n
-    intCast_negSucc := fun n => funext fun _ => AddGroupWithOne.intCast_negSucc n
-  }
-
-instance mulZeroClass [∀ i, MulZeroClass <| f i] : MulZeroClass (∀ i : I, f i) :=
-  { zero := (0 : ∀ i, f i)
-    mul := (· * ·)
-    --pi_instance
-    zero_mul := by intros; ext; exact zero_mul _
-    mul_zero := by intros; ext; exact mul_zero _
-}
-#align pi.mul_zero_class Pi.mulZeroClass
-
-instance mulZeroOneClass [∀ i, MulZeroOneClass <| f i] : MulZeroOneClass (∀ i : I, f i) :=
-  { mulZeroClass, mulOneClass with }
-#align pi.mul_zero_one_class Pi.mulZeroOneClass
-
-instance monoidWithZero [∀ i, MonoidWithZero <| f i] : MonoidWithZero (∀ i : I, f i) :=
-  { monoid, mulZeroClass with }
-#align pi.monoid_with_zero Pi.monoidWithZero
-
-instance commMonoidWithZero [∀ i, CommMonoidWithZero <| f i] : CommMonoidWithZero (∀ i : I, f i) :=
-  { monoidWithZero, commMonoid with }
-#align pi.comm_monoid_with_zero Pi.commMonoidWithZero
-
-instance semigroupWithZero [∀ i, SemigroupWithZero <| f i] : SemigroupWithZero (∀ i : I, f i) :=
-  { semigroup, mulZeroClass with }
-#align pi.semigroup_with_zero Pi.semigroupWithZero
-
-end Pi
-
 namespace MulHom
 
 @[to_additive]
@@ -304,17 +264,6 @@ theorem MonoidHom.mulSingle_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i)
 #align monoid_hom.single_apply MonoidHom.mulSingle_apply
 #align add_monoid_hom.single_apply AddMonoidHom.single_apply
 
-/-- The multiplicative homomorphism including a single `MulZeroClass`
-into a dependent family of `MulZeroClass`es, as functions supported at a point.
-
-This is the `MulHom` version of `Pi.single`. -/
-@[simps]
-def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i where
-  toFun := Pi.single i
-  map_mul' := Pi.single_op₂ (fun _ => (· * ·)) (fun _ => zero_mul _) _
-#align mul_hom.single MulHom.single
-#align mul_hom.single_apply MulHom.single_apply
-
 variable {f}
 
 @[to_additive]
@@ -352,31 +301,6 @@ theorem Pi.mulSingle_div [∀ i, Group <| f i] (i : I) (x y : f i) :
 #align pi.single_div Pi.mulSingle_div
 #align pi.single_sub Pi.single_sub
 
-theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
-    single i (x * y) = single i x * single i y :=
-  (MulHom.single f i).map_mul x y
-#align pi.single_mul Pi.single_mul
-
-theorem Pi.single_mul_left_apply [∀ i, MulZeroClass <| f i] (a : f i) :
-    Pi.single i (a * x i) j = Pi.single i a j * x j :=
-  (Pi.apply_single (fun i => (· * x i)) (fun _ => zero_mul _) _ _ _).symm
-#align pi.single_mul_left_apply Pi.single_mul_left_apply
-
-theorem Pi.single_mul_right_apply [∀ i, MulZeroClass <| f i] (a : f i) :
-    Pi.single i (x i * a) j = x j * Pi.single i a j :=
-  (Pi.apply_single (fun i => (· * ·) (x i)) (fun _ => mul_zero _) _ _ _).symm
-#align pi.single_mul_right_apply Pi.single_mul_right_apply
-
-theorem Pi.single_mul_left [∀ i, MulZeroClass <| f i] (a : f i) :
-    Pi.single i (a * x i) = Pi.single i a * x :=
-  funext fun _ => Pi.single_mul_left_apply _ _ _ _
-#align pi.single_mul_left Pi.single_mul_left
-
-theorem Pi.single_mul_right [∀ i, MulZeroClass <| f i] (a : f i) :
-    Pi.single i (x i * a) = x * Pi.single i a :=
-  funext fun _ => Pi.single_mul_right_apply _ _ _ _
-#align pi.single_mul_right Pi.single_mul_right
-
 section
 variable [∀ i, Mul <| f i]
 
chore: Rename a few lemmas about Pi.mulSingle (#12317)

Before this PR, the MonoidHom version of Pi.mulSingle was called MonoidHom.single for brevity; but this is confusing when contrasted with MulHom.single which is about Pi.single.

After this PR, the name is MonoidHom.mulSingle.

Also fix the name of Pi.single_div since it is about Pi.mulSingle (and we don't have the lemma that would be called Pi.single_div).

Diff
@@ -271,17 +271,16 @@ This is the `OneHom` version of `Pi.mulSingle`. -/
       as functions supported at a point.
 
       This is the `ZeroHom` version of `Pi.single`."]
-def OneHom.single [∀ i, One <| f i] (i : I) : OneHom (f i) (∀ i, f i) where
+nonrec def OneHom.mulSingle [∀ i, One <| f i] (i : I) : OneHom (f i) (∀ i, f i) where
   toFun := mulSingle i
   map_one' := mulSingle_one i
-#align one_hom.single OneHom.single
+#align one_hom.single OneHom.mulSingle
 #align zero_hom.single ZeroHom.single
 
 @[to_additive (attr := simp)]
-theorem OneHom.single_apply [∀ i, One <| f i] (i : I) (x : f i) :
-    OneHom.single f i x = mulSingle i x :=
-  rfl
-#align one_hom.single_apply OneHom.single_apply
+theorem OneHom.mulSingle_apply [∀ i, One <| f i] (i : I) (x : f i) :
+    mulSingle f i x = Pi.mulSingle i x := rfl
+#align one_hom.single_apply OneHom.mulSingle_apply
 #align zero_hom.single_apply ZeroHom.single_apply
 
 /-- The monoid homomorphism including a single monoid into a dependent family of additive monoids,
@@ -293,16 +292,16 @@ This is the `MonoidHom` version of `Pi.mulSingle`. -/
       of additive monoids, as functions supported at a point.
 
       This is the `AddMonoidHom` version of `Pi.single`."]
-def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :=
-  { OneHom.single f i with map_mul' := mulSingle_op₂ (fun _ => (· * ·)) (fun _ => one_mul _) _ }
-#align monoid_hom.single MonoidHom.single
+def MonoidHom.mulSingle [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :=
+  { OneHom.mulSingle f i with map_mul' := mulSingle_op₂ (fun _ => (· * ·)) (fun _ => one_mul _) _ }
+#align monoid_hom.single MonoidHom.mulSingle
 #align add_monoid_hom.single AddMonoidHom.single
 
 @[to_additive (attr := simp)]
-theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
-    MonoidHom.single f i x = mulSingle i x :=
+theorem MonoidHom.mulSingle_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
+    mulSingle f i x = Pi.mulSingle i x :=
   rfl
-#align monoid_hom.single_apply MonoidHom.single_apply
+#align monoid_hom.single_apply MonoidHom.mulSingle_apply
 #align add_monoid_hom.single_apply AddMonoidHom.single_apply
 
 /-- The multiplicative homomorphism including a single `MulZeroClass`
@@ -335,22 +334,22 @@ theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I
 @[to_additive]
 theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
     mulSingle i (x * y) = mulSingle i x * mulSingle i y :=
-  (MonoidHom.single f i).map_mul x y
+  (MonoidHom.mulSingle f i).map_mul x y
 #align pi.mul_single_mul Pi.mulSingle_mul
 #align pi.single_add Pi.single_add
 
 @[to_additive]
 theorem Pi.mulSingle_inv [∀ i, Group <| f i] (i : I) (x : f i) :
     mulSingle i x⁻¹ = (mulSingle i x)⁻¹ :=
-  (MonoidHom.single f i).map_inv x
+  (MonoidHom.mulSingle f i).map_inv x
 #align pi.mul_single_inv Pi.mulSingle_inv
 #align pi.single_neg Pi.single_neg
 
 @[to_additive]
-theorem Pi.single_div [∀ i, Group <| f i] (i : I) (x y : f i) :
+theorem Pi.mulSingle_div [∀ i, Group <| f i] (i : I) (x y : f i) :
     mulSingle i (x / y) = mulSingle i x / mulSingle i y :=
-  (MonoidHom.single f i).map_div x y
-#align pi.single_div Pi.single_div
+  (MonoidHom.mulSingle f i).map_div x y
+#align pi.single_div Pi.mulSingle_div
 #align pi.single_sub Pi.single_sub
 
 theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
chore: refactor to avoid importing Ring for Group topics (#11913)

This is a far from a complete success at the PR title, but it makes a fair bit of progress, and then guards this with appropriate assert_not_exists Ring statements.

It also breaks apart the Mathlib.GroupTheory.Subsemigroup.[Center|Centralizer] files, to pull the Set.center and Set.centralizer declarations into their own files not depending on Subsemigroup.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>

Diff
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 -/
 import Mathlib.Algebra.Group.Hom.Instances
+import Mathlib.Data.Int.Cast.Defs
 import Mathlib.Data.Set.Function
 import Mathlib.Logic.Pairwise
 
chore(*): remove empty lines between variable statements (#11418)

Empty lines were removed by executing the following Python script twice

import os
import re


# Loop through each file in the repository
for dir_path, dirs, files in os.walk('.'):
  for filename in files:
    if filename.endswith('.lean'):
      file_path = os.path.join(dir_path, filename)

      # Open the file and read its contents
      with open(file_path, 'r') as file:
        content = file.read()

      # Use a regular expression to replace sequences of "variable" lines separated by empty lines
      # with sequences without empty lines
      modified_content = re.sub(r'(variable.*\n)\n(variable(?! .* in))', r'\1\2', content)

      # Write the modified content back to the file
      with open(file_path, 'w') as file:
        file.write(modified_content)
Diff
@@ -19,7 +19,6 @@ imports.
 universe u v w
 
 variable {ι α : Type*}
-
 variable {I : Type u}
 
 -- The indexing type
chore: Remove Init.CCLemmas (#10696)

Those lemmas were weird and unused, except the last few about transitivity of = and , which I moved to Logic.Basic

Diff
@@ -3,7 +3,6 @@ Copyright (c) 2018 Simon Hudon. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 -/
-import Mathlib.Init.CCLemmas
 import Mathlib.Algebra.Group.Hom.Instances
 import Mathlib.Data.Set.Function
 import Mathlib.Logic.Pairwise
move: Algebraic pi instances (#10693)

Rename

  • Data.Pi.Algebra to Algebra.Group.Pi.Basic
  • Algebra.Group.Pi to Algebra.Group.Pi.Lemmas

Move a few instances from the latter to the former, the goal being that Algebra.Group.Pi.Basic is about all the pi instances of the classes defined in Algebra.Group.Defs. Algebra.Group.Pi.Lemmas will need further rearranging.

Diff
@@ -5,29 +5,16 @@ Authors: Simon Hudon, Patrick Massot
 -/
 import Mathlib.Init.CCLemmas
 import Mathlib.Algebra.Group.Hom.Instances
-import Mathlib.Data.Pi.Algebra
 import Mathlib.Data.Set.Function
 import Mathlib.Logic.Pairwise
 
 #align_import algebra.group.pi from "leanprover-community/mathlib"@"e4bc74cbaf429d706cb9140902f7ca6c431e75a4"
 
 /-!
-# Pi instances for groups and monoids
+# Extra lemmas about products of monoids and groups
 
-This file defines instances for group, monoid, semigroup and related structures on Pi types.
--/
-
-/-
-  Porting notes:
-
-  See this Zulip discussion: [https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/not.20porting.20pi_instance]
-
-  * This file now includes the pi instances for `AddMonoidWithOne` and `AddGroupWithOne`
-  * This file relied on the `pi_instance` tactic, which was not available at the time of porting.
-    The comment `--pi_instance` is inserted before all fields which were previously derived by
-    `pi_instance`.
-  * This file previously gave data fields explicitly. Now previously-defined instances are sourced
-    via `with` as much as possible.
+This file proves lemmas about the instances defined in `Algebra.Group.Pi.Basic` that require more
+imports.
 -/
 
 universe u v w
@@ -51,51 +38,6 @@ theorem Set.preimage_one {α β : Type*} [One β] (s : Set β) [Decidable ((1 :
 
 namespace Pi
 
-@[to_additive]
-instance semigroup [∀ i, Semigroup <| f i] : Semigroup (∀ i : I, f i) :=
-  { mul := (· * ·)
-    --pi_instance
-    mul_assoc := by intros; ext; exact mul_assoc _ _ _ }
-#align pi.semigroup Pi.semigroup
-#align pi.add_semigroup Pi.addSemigroup
-
-@[to_additive]
-instance commSemigroup [∀ i, CommSemigroup <| f i] : CommSemigroup (∀ i : I, f i) :=
-  { semigroup with
-    --pi_instance
-    mul_comm := by intros; ext; exact mul_comm _ _
-  }
-#align pi.comm_semigroup Pi.commSemigroup
-#align pi.add_comm_semigroup Pi.addCommSemigroup
-
-@[to_additive]
-instance mulOneClass [∀ i, MulOneClass <| f i] : MulOneClass (∀ i : I, f i) :=
-  { one := (1 : ∀ i, f i)
-    mul := (· * ·)
-    --pi_instance
-    one_mul := by intros; ext; exact one_mul _
-    mul_one := by intros; ext; exact mul_one _
-  }
-#align pi.mul_one_class Pi.mulOneClass
-#align pi.add_zero_class Pi.addZeroClass
-
-@[to_additive]
-instance invOneClass [∀ i, InvOneClass <| f i] : InvOneClass (∀ i : I, f i) :=
-  { one := (1 : ∀ i, f i)
-    inv := (· ⁻¹)
-    inv_one := by intros; ext; exact inv_one }
-
-@[to_additive]
-instance monoid [∀ i, Monoid <| f i] : Monoid (∀ i : I, f i) :=
-  { semigroup, mulOneClass with
-    npow := fun n x i => x i ^ n
-    --pi_instance
-    npow_zero := by intros; ext; exact Monoid.npow_zero _
-    npow_succ := by intros; ext; exact Monoid.npow_succ _ _
-  }
-#align pi.monoid Pi.monoid
-#align pi.add_monoid Pi.addMonoid
-
 instance addMonoidWithOne [∀ i, AddMonoidWithOne <| f i] : AddMonoidWithOne (∀ i : I, f i) :=
   { addMonoid with
     natCast := fun n _ => n
@@ -103,59 +45,6 @@ instance addMonoidWithOne [∀ i, AddMonoidWithOne <| f i] : AddMonoidWithOne (
     natCast_succ := fun n => funext fun _ => AddMonoidWithOne.natCast_succ n
   }
 
-@[to_additive]
-instance commMonoid [∀ i, CommMonoid <| f i] : CommMonoid (∀ i : I, f i) :=
-  { monoid, commSemigroup with }
-#align pi.comm_monoid Pi.commMonoid
-#align pi.add_comm_monoid Pi.addCommMonoid
-
-@[to_additive Pi.subNegMonoid]
-instance divInvMonoid [∀ i, DivInvMonoid <| f i] : DivInvMonoid (∀ i : I, f i) :=
-  { monoid with
-    inv := Inv.inv
-    div := Div.div
-    zpow := fun z x i => x i ^ z
-    --pi_instance
-    div_eq_mul_inv := by intros; ext; exact div_eq_mul_inv _ _
-    zpow_zero' := by intros; ext; exact DivInvMonoid.zpow_zero' _
-    zpow_succ' := by intros; ext; exact DivInvMonoid.zpow_succ' _ _
-    zpow_neg' := by intros; ext; exact DivInvMonoid.zpow_neg' _ _
-  }
-
-@[to_additive Pi.subNegZeroMonoid]
-instance divInvOneMonoid [∀ i, DivInvOneMonoid <| f i] : DivInvOneMonoid (∀ i : I, f i) :=
-  { divInvMonoid with
-    inv_one := by ext; exact inv_one }
-
-@[to_additive]
-instance involutiveInv [∀ i, InvolutiveInv <| f i] : InvolutiveInv (∀ i, f i) :=
-  { inv := Inv.inv
-    --pi_instance
-    inv_inv := by intros; ext; exact inv_inv _
-  }
-
-@[to_additive Pi.subtractionMonoid]
-instance divisionMonoid [∀ i, DivisionMonoid <| f i] : DivisionMonoid (∀ i, f i) :=
-  { divInvMonoid, involutiveInv with
-    --pi_instance
-    mul_inv_rev := by intros; ext; exact mul_inv_rev _ _
-    inv_eq_of_mul := by
-      intros _ _ h; ext; exact DivisionMonoid.inv_eq_of_mul _ _ (congrFun h _)
-  }
-
-@[to_additive Pi.subtractionCommMonoid]
-instance [∀ i, DivisionCommMonoid <| f i] : DivisionCommMonoid (∀ i, f i) :=
-  { divisionMonoid, commSemigroup with }
-
-@[to_additive]
-instance group [∀ i, Group <| f i] : Group (∀ i : I, f i) :=
-  { divInvMonoid with
-    --pi_instance
-    mul_left_inv := by intros; ext; exact mul_left_inv _
-    }
-#align pi.group Pi.group
-#align pi.add_group Pi.addGroup
-
 instance addGroupWithOne [∀ i, AddGroupWithOne <| f i] : AddGroupWithOne (∀ i : I, f i) :=
   { addGroup, addMonoidWithOne with
     intCast := fun z _ => z
@@ -163,61 +52,6 @@ instance addGroupWithOne [∀ i, AddGroupWithOne <| f i] : AddGroupWithOne (∀
     intCast_negSucc := fun n => funext fun _ => AddGroupWithOne.intCast_negSucc n
   }
 
-@[to_additive]
-instance commGroup [∀ i, CommGroup <| f i] : CommGroup (∀ i : I, f i) :=
-  { group, commMonoid with }
-#align pi.comm_group Pi.commGroup
-#align pi.add_comm_group Pi.addCommGroup
-
-@[to_additive]
-instance [∀ i, Mul <| f i] [∀ i, IsLeftCancelMul <| f i] : IsLeftCancelMul (∀ i : I, f i) where
-  mul_left_cancel  _ _ _ h := funext fun _ => mul_left_cancel (congr_fun h _)
-
-@[to_additive]
-instance [∀ i, Mul <| f i] [∀ i, IsRightCancelMul <| f i] : IsRightCancelMul (∀ i : I, f i) where
-  mul_right_cancel  _ _ _ h := funext fun _ => mul_right_cancel (congr_fun h _)
-
-@[to_additive]
-instance [∀ i, Mul <| f i] [∀ i, IsCancelMul <| f i] : IsCancelMul (∀ i : I, f i) where
-
-@[to_additive]
-instance leftCancelSemigroup [∀ i, LeftCancelSemigroup <| f i] :
-    LeftCancelSemigroup (∀ i : I, f i) :=
-  { semigroup with mul_left_cancel := fun _ _ _ => mul_left_cancel }
-#align pi.left_cancel_semigroup Pi.leftCancelSemigroup
-#align pi.add_left_cancel_semigroup Pi.addLeftCancelSemigroup
-
-@[to_additive]
-instance rightCancelSemigroup [∀ i, RightCancelSemigroup <| f i] :
-    RightCancelSemigroup (∀ i : I, f i) :=
-  { semigroup with mul_right_cancel := fun _ _ _ => mul_right_cancel }
-#align pi.right_cancel_semigroup Pi.rightCancelSemigroup
-#align pi.add_right_cancel_semigroup Pi.addRightCancelSemigroup
-
-@[to_additive]
-instance leftCancelMonoid [∀ i, LeftCancelMonoid <| f i] : LeftCancelMonoid (∀ i : I, f i) :=
-  { leftCancelSemigroup, monoid with }
-#align pi.left_cancel_monoid Pi.leftCancelMonoid
-#align pi.add_left_cancel_monoid Pi.addLeftCancelMonoid
-
-@[to_additive]
-instance rightCancelMonoid [∀ i, RightCancelMonoid <| f i] : RightCancelMonoid (∀ i : I, f i) :=
-  { rightCancelSemigroup, monoid with }
-#align pi.right_cancel_monoid Pi.rightCancelMonoid
-#align pi.add_right_cancel_monoid Pi.addRightCancelMonoid
-
-@[to_additive]
-instance cancelMonoid [∀ i, CancelMonoid <| f i] : CancelMonoid (∀ i : I, f i) :=
-  { leftCancelMonoid, rightCancelMonoid with }
-#align pi.cancel_monoid Pi.cancelMonoid
-#align pi.add_cancel_monoid Pi.addCancelMonoid
-
-@[to_additive]
-instance cancelCommMonoid [∀ i, CancelCommMonoid <| f i] : CancelCommMonoid (∀ i : I, f i) :=
-  { leftCancelMonoid, commMonoid with }
-#align pi.cancel_comm_monoid Pi.cancelCommMonoid
-#align pi.add_cancel_comm_monoid Pi.addCancelCommMonoid
-
 instance mulZeroClass [∀ i, MulZeroClass <| f i] : MulZeroClass (∀ i : I, f i) :=
   { zero := (0 : ∀ i, f i)
     mul := (· * ·)
chore(*): drop $/<| before fun (#9361)

Subset of #9319

Diff
@@ -171,11 +171,11 @@ instance commGroup [∀ i, CommGroup <| f i] : CommGroup (∀ i : I, f i) :=
 
 @[to_additive]
 instance [∀ i, Mul <| f i] [∀ i, IsLeftCancelMul <| f i] : IsLeftCancelMul (∀ i : I, f i) where
-  mul_left_cancel  _ _ _ h := funext <| fun _ => mul_left_cancel (congr_fun h _)
+  mul_left_cancel  _ _ _ h := funext fun _ => mul_left_cancel (congr_fun h _)
 
 @[to_additive]
 instance [∀ i, Mul <| f i] [∀ i, IsRightCancelMul <| f i] : IsRightCancelMul (∀ i : I, f i) where
-  mul_right_cancel  _ _ _ h := funext <| fun _ => mul_right_cancel (congr_fun h _)
+  mul_right_cancel  _ _ _ h := funext fun _ => mul_right_cancel (congr_fun h _)
 
 @[to_additive]
 instance [∀ i, Mul <| f i] [∀ i, IsCancelMul <| f i] : IsCancelMul (∀ i : I, f i) where
feat(Algebra/Group): lemmas about Commute (#8756)
Diff
@@ -545,6 +545,26 @@ theorem Pi.single_mul_right [∀ i, MulZeroClass <| f i] (a : f i) :
   funext fun _ => Pi.single_mul_right_apply _ _ _ _
 #align pi.single_mul_right Pi.single_mul_right
 
+section
+variable [∀ i, Mul <| f i]
+
+@[to_additive]
+theorem SemiconjBy.pi {x y z : ∀ i, f i} (h : ∀ i, SemiconjBy (x i) (y i) (z i)) :
+    SemiconjBy x y z :=
+  funext h
+
+@[to_additive]
+theorem Pi.semiconjBy_iff {x y z : ∀ i, f i} :
+    SemiconjBy x y z ↔ ∀ i, SemiconjBy (x i) (y i) (z i) := Function.funext_iff
+
+@[to_additive]
+theorem Commute.pi {x y : ∀ i, f i} (h : ∀ i, Commute (x i) (y i)) : Commute x y := .pi h
+
+@[to_additive]
+theorem Pi.commute_iff {x y : ∀ i, f i} : Commute x y ↔ ∀ i, Commute (x i) (y i) := semiconjBy_iff
+
+end
+
 /-- The injection into a pi group at different indices commutes.
 
 For injections of commuting elements at the same index, see `Commute.map` -/
fix(Tactic/ToAdditive): handle AddCommute and AddSemiconjBy correctly (#8757)

This removes the need for many manual overrides, and corrects some bad names.

We have to make sure to leave function_commute and function_semiconjBy untouched.

Diff
@@ -563,7 +563,7 @@ theorem Pi.mulSingle_commute [∀ i, MulOneClass <| f i] :
     simp [hij]
   simp [h1, h2]
 #align pi.mul_single_commute Pi.mulSingle_commute
-#align pi.single_commute Pi.single_commute
+#align pi.single_commute Pi.single_addCommute
 
 /-- The injection into a pi group with the same values commutes. -/
 @[to_additive "The injection into an additive pi group with the same values commutes."]
@@ -573,7 +573,7 @@ theorem Pi.mulSingle_apply_commute [∀ i, MulOneClass <| f i] (x : ∀ i, f i)
   · rfl
   · exact Pi.mulSingle_commute hij _ _
 #align pi.mul_single_apply_commute Pi.mulSingle_apply_commute
-#align pi.single_apply_commute Pi.single_apply_commute
+#align pi.single_apply_commute Pi.single_apply_addCommute
 
 @[to_additive]
 theorem Pi.update_eq_div_mul_mulSingle [∀ i, Group <| f i] (g : ∀ i : I, f i) (x : f i) :
feat: add missing IsCancelMul instances (#8748)

This is not exhaustive

Diff
@@ -169,25 +169,28 @@ instance commGroup [∀ i, CommGroup <| f i] : CommGroup (∀ i : I, f i) :=
 #align pi.comm_group Pi.commGroup
 #align pi.add_comm_group Pi.addCommGroup
 
+@[to_additive]
+instance [∀ i, Mul <| f i] [∀ i, IsLeftCancelMul <| f i] : IsLeftCancelMul (∀ i : I, f i) where
+  mul_left_cancel  _ _ _ h := funext <| fun _ => mul_left_cancel (congr_fun h _)
+
+@[to_additive]
+instance [∀ i, Mul <| f i] [∀ i, IsRightCancelMul <| f i] : IsRightCancelMul (∀ i : I, f i) where
+  mul_right_cancel  _ _ _ h := funext <| fun _ => mul_right_cancel (congr_fun h _)
+
+@[to_additive]
+instance [∀ i, Mul <| f i] [∀ i, IsCancelMul <| f i] : IsCancelMul (∀ i : I, f i) where
+
 @[to_additive]
 instance leftCancelSemigroup [∀ i, LeftCancelSemigroup <| f i] :
     LeftCancelSemigroup (∀ i : I, f i) :=
-  { semigroup with
-    --pi_instance
-    mul_left_cancel := by
-      intros _ _ _ h; ext; exact LeftCancelSemigroup.mul_left_cancel _ _ _ (congr_fun h _);
-  }
+  { semigroup with mul_left_cancel := fun _ _ _ => mul_left_cancel }
 #align pi.left_cancel_semigroup Pi.leftCancelSemigroup
 #align pi.add_left_cancel_semigroup Pi.addLeftCancelSemigroup
 
 @[to_additive]
 instance rightCancelSemigroup [∀ i, RightCancelSemigroup <| f i] :
     RightCancelSemigroup (∀ i : I, f i) :=
-  { semigroup with
-    --pi_instance
-    mul_right_cancel := by
-      intros _ _ _ h; ext; exact RightCancelSemigroup.mul_right_cancel _ _ _ (congr_fun h _)
-  }
+  { semigroup with mul_right_cancel := fun _ _ _ => mul_right_cancel }
 #align pi.right_cancel_semigroup Pi.rightCancelSemigroup
 #align pi.add_right_cancel_semigroup Pi.addRightCancelSemigroup
 
refactor(Algebra/Hom): transpose Hom and file name (#8095)

I believe the file defining a type of morphisms belongs alongside the file defining the structure this morphism works on. So I would like to reorganize the files in the Mathlib.Algebra.Hom folder so that e.g. Mathlib.Algebra.Hom.Ring becomes Mathlib.Algebra.Ring.Hom and Mathlib.Algebra.Hom.NonUnitalAlg becomes Mathlib.Algebra.Algebra.NonUnitalHom.

While fixing the imports I went ahead and sorted them for good luck.

The full list of changes is: renamed: Mathlib/Algebra/Hom/NonUnitalAlg.lean -> Mathlib/Algebra/Algebra/NonUnitalHom.lean renamed: Mathlib/Algebra/Hom/Aut.lean -> Mathlib/Algebra/Group/Aut.lean renamed: Mathlib/Algebra/Hom/Commute.lean -> Mathlib/Algebra/Group/Commute/Hom.lean renamed: Mathlib/Algebra/Hom/Embedding.lean -> Mathlib/Algebra/Group/Embedding.lean renamed: Mathlib/Algebra/Hom/Equiv/Basic.lean -> Mathlib/Algebra/Group/Equiv/Basic.lean renamed: Mathlib/Algebra/Hom/Equiv/TypeTags.lean -> Mathlib/Algebra/Group/Equiv/TypeTags.lean renamed: Mathlib/Algebra/Hom/Equiv/Units/Basic.lean -> Mathlib/Algebra/Group/Units/Equiv.lean renamed: Mathlib/Algebra/Hom/Equiv/Units/GroupWithZero.lean -> Mathlib/Algebra/GroupWithZero/Units/Equiv.lean renamed: Mathlib/Algebra/Hom/Freiman.lean -> Mathlib/Algebra/Group/Freiman.lean renamed: Mathlib/Algebra/Hom/Group/Basic.lean -> Mathlib/Algebra/Group/Hom/Basic.lean renamed: Mathlib/Algebra/Hom/Group/Defs.lean -> Mathlib/Algebra/Group/Hom/Defs.lean renamed: Mathlib/Algebra/Hom/GroupAction.lean -> Mathlib/GroupTheory/GroupAction/Hom.lean renamed: Mathlib/Algebra/Hom/GroupInstances.lean -> Mathlib/Algebra/Group/Hom/Instances.lean renamed: Mathlib/Algebra/Hom/Iterate.lean -> Mathlib/Algebra/GroupPower/IterateHom.lean renamed: Mathlib/Algebra/Hom/Centroid.lean -> Mathlib/Algebra/Ring/CentroidHom.lean renamed: Mathlib/Algebra/Hom/Ring/Basic.lean -> Mathlib/Algebra/Ring/Hom/Basic.lean renamed: Mathlib/Algebra/Hom/Ring/Defs.lean -> Mathlib/Algebra/Ring/Hom/Defs.lean renamed: Mathlib/Algebra/Hom/Units.lean -> Mathlib/Algebra/Group/Units/Hom.lean

Zulip thread: https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Reorganizing.20.60Mathlib.2EAlgebra.2EHom.60

Diff
@@ -4,10 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 -/
 import Mathlib.Init.CCLemmas
-import Mathlib.Logic.Pairwise
-import Mathlib.Algebra.Hom.GroupInstances
+import Mathlib.Algebra.Group.Hom.Instances
 import Mathlib.Data.Pi.Algebra
 import Mathlib.Data.Set.Function
+import Mathlib.Logic.Pairwise
 
 #align_import algebra.group.pi from "leanprover-community/mathlib"@"e4bc74cbaf429d706cb9140902f7ca6c431e75a4"
 
chore: exactly 4 spaces in theorems (#7328)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -246,7 +246,7 @@ namespace MulHom
 
 @[to_additive]
 theorem coe_mul {M N} {_ : Mul M} {_ : CommSemigroup N} (f g : M →ₙ* N) : (f * g : M → N) =
-  fun x => f x * g x := rfl
+    fun x => f x * g x := rfl
 #align mul_hom.coe_mul MulHom.coe_mul
 #align add_hom.coe_add AddHom.coe_add
 
refactor: split Algebra.Hom.Group and Algebra.Hom.Ring (#7094)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -3,6 +3,7 @@ Copyright (c) 2018 Simon Hudon. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 -/
+import Mathlib.Init.CCLemmas
 import Mathlib.Logic.Pairwise
 import Mathlib.Algebra.Hom.GroupInstances
 import Mathlib.Data.Pi.Algebra
chore: drop MulZeroClass. in mul_zero/zero_mul (#6682)

Search&replace MulZeroClass.mul_zero -> mul_zero, MulZeroClass.zero_mul -> zero_mul.

These were introduced by Mathport, as the full name of mul_zero is actually MulZeroClass.mul_zero (it's exported with the short name).

Diff
@@ -523,12 +523,12 @@ theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
 
 theorem Pi.single_mul_left_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (a * x i) j = Pi.single i a j * x j :=
-  (Pi.apply_single (fun i => (· * x i)) (fun _ => MulZeroClass.zero_mul _) _ _ _).symm
+  (Pi.apply_single (fun i => (· * x i)) (fun _ => zero_mul _) _ _ _).symm
 #align pi.single_mul_left_apply Pi.single_mul_left_apply
 
 theorem Pi.single_mul_right_apply [∀ i, MulZeroClass <| f i] (a : f i) :
     Pi.single i (x i * a) j = x j * Pi.single i a j :=
-  (Pi.apply_single (fun i => (· * ·) (x i)) (fun _ => MulZeroClass.mul_zero _) _ _ _).symm
+  (Pi.apply_single (fun i => (· * ·) (x i)) (fun _ => mul_zero _) _ _ _).symm
 #align pi.single_mul_right_apply Pi.single_mul_right_apply
 
 theorem Pi.single_mul_left [∀ i, MulZeroClass <| f i] (a : f i) :
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -31,7 +31,7 @@ This file defines instances for group, monoid, semigroup and related structures
 
 universe u v w
 
-variable {ι α : Type _}
+variable {ι α : Type*}
 
 variable {I : Type u}
 
@@ -42,7 +42,7 @@ variable {f : I → Type v}
 variable (x y : ∀ i, f i) (i j : I)
 
 @[to_additive]
-theorem Set.preimage_one {α β : Type _} [One β] (s : Set β) [Decidable ((1 : β) ∈ s)] :
+theorem Set.preimage_one {α β : Type*} [One β] (s : Set β) [Decidable ((1 : β) ∈ s)] :
     (1 : α → β) ⁻¹' s = if (1 : β) ∈ s then Set.univ else ∅ :=
   Set.preimage_const 1 s
 #align set.preimage_one Set.preimage_one
@@ -315,7 +315,7 @@ def Pi.evalMulHom (i : I) : (∀ i, f i) →ₙ* f i where
 
 /-- `Function.const` as a `MulHom`. -/
 @[to_additive (attr := simps) "`Function.const` as an `AddHom`."]
-def Pi.constMulHom (α β : Type _) [Mul β] :
+def Pi.constMulHom (α β : Type*) [Mul β] :
     β →ₙ* α → β where
   toFun := Function.const α
   map_mul' _ _ := rfl
@@ -330,7 +330,7 @@ See also `MulHom.eval`. -/
 @[to_additive (attr := simps) "Coercion of an `AddHom` into a function is itself an `AddHom`.
 
 See also `AddHom.eval`."]
-def MulHom.coeFn (α β : Type _) [Mul α] [CommSemigroup β] :
+def MulHom.coeFn (α β : Type*) [Mul α] [CommSemigroup β] :
     (α →ₙ* β) →ₙ* α → β where
   toFun g := g
   map_mul' _ _ := rfl
@@ -343,7 +343,7 @@ def MulHom.coeFn (α β : Type _) [Mul α] [CommSemigroup β] :
 homomorphism `f` between `α` and `β`. -/
 @[to_additive (attr := simps) "Additive semigroup homomorphism between the function spaces `I → α`
 and `I → β`, induced by an additive semigroup homomorphism `f` between `α` and `β`"]
-protected def MulHom.compLeft {α β : Type _} [Mul α] [Mul β] (f : α →ₙ* β) (I : Type _) :
+protected def MulHom.compLeft {α β : Type*} [Mul α] [Mul β] (f : α →ₙ* β) (I : Type*) :
     (I → α) →ₙ* I → β where
   toFun h := f ∘ h
   map_mul' _ _ := by ext; simp
@@ -375,7 +375,7 @@ def Pi.evalMonoidHom (i : I) : (∀ i, f i) →* f i where
 
 /-- `Function.const` as a `MonoidHom`. -/
 @[to_additive (attr := simps) "`Function.const` as an `AddMonoidHom`."]
-def Pi.constMonoidHom (α β : Type _) [MulOneClass β] : β →* α → β where
+def Pi.constMonoidHom (α β : Type*) [MulOneClass β] : β →* α → β where
   toFun := Function.const α
   map_one' := rfl
   map_mul' _ _ := rfl
@@ -391,7 +391,7 @@ See also `MonoidHom.eval`. -/
 an `AddMonoidHom`.
 
 See also `AddMonoidHom.eval`."]
-def MonoidHom.coeFn (α β : Type _) [MulOneClass α] [CommMonoid β] : (α →* β) →* α → β where
+def MonoidHom.coeFn (α β : Type*) [MulOneClass α] [CommMonoid β] : (α →* β) →* α → β where
   toFun g := g
   map_one' := rfl
   map_mul' _ _ := rfl
@@ -405,8 +405,8 @@ homomorphism `f` between `α` and `β`. -/
 @[to_additive (attr := simps)
   "Additive monoid homomorphism between the function spaces `I → α` and `I → β`, induced by an
   additive monoid homomorphism `f` between `α` and `β`"]
-protected def MonoidHom.compLeft {α β : Type _} [MulOneClass α] [MulOneClass β] (f : α →* β)
-    (I : Type _) : (I → α) →* I → β where
+protected def MonoidHom.compLeft {α β : Type*} [MulOneClass α] [MulOneClass β] (f : α →* β)
+    (I : Type*) : (I → α) →* I → β where
   toFun h := f ∘ h
   map_one' := by ext; dsimp; simp
   map_mul' _ _ := by ext; simp
@@ -582,7 +582,7 @@ theorem Pi.update_eq_div_mul_mulSingle [∀ i, Group <| f i] (g : ∀ i : I, f i
 #align pi.update_eq_sub_add_single Pi.update_eq_div_mul_mulSingle
 
 @[to_additive]
-theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type _} [CommMonoid M]
+theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type*} [CommMonoid M]
     {k l m n : I} {u v : M} (hu : u ≠ 1) (hv : v ≠ 1) :
     (mulSingle k u : I → M) * mulSingle l v = mulSingle m u * mulSingle n v ↔
       k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u * v = 1 ∧ k = l ∧ m = n := by
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,17 +2,14 @@
 Copyright (c) 2018 Simon Hudon. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
-
-! This file was ported from Lean 3 source module algebra.group.pi
-! leanprover-community/mathlib commit e4bc74cbaf429d706cb9140902f7ca6c431e75a4
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Logic.Pairwise
 import Mathlib.Algebra.Hom.GroupInstances
 import Mathlib.Data.Pi.Algebra
 import Mathlib.Data.Set.Function
 
+#align_import algebra.group.pi from "leanprover-community/mathlib"@"e4bc74cbaf429d706cb9140902f7ca6c431e75a4"
+
 /-!
 # Pi instances for groups and monoids
 
feat(Algebra/Group/[Pi, InjSurj]): add missing boilerplate for InvOneClass and DivInvOneMonoid (#5904)
Diff
@@ -81,6 +81,12 @@ instance mulOneClass [∀ i, MulOneClass <| f i] : MulOneClass (∀ i : I, f i)
 #align pi.mul_one_class Pi.mulOneClass
 #align pi.add_zero_class Pi.addZeroClass
 
+@[to_additive]
+instance invOneClass [∀ i, InvOneClass <| f i] : InvOneClass (∀ i : I, f i) :=
+  { one := (1 : ∀ i, f i)
+    inv := (· ⁻¹)
+    inv_one := by intros; ext; exact inv_one }
+
 @[to_additive]
 instance monoid [∀ i, Monoid <| f i] : Monoid (∀ i : I, f i) :=
   { semigroup, mulOneClass with
@@ -118,6 +124,11 @@ instance divInvMonoid [∀ i, DivInvMonoid <| f i] : DivInvMonoid (∀ i : I, f
     zpow_neg' := by intros; ext; exact DivInvMonoid.zpow_neg' _ _
   }
 
+@[to_additive Pi.subNegZeroMonoid]
+instance divInvOneMonoid [∀ i, DivInvOneMonoid <| f i] : DivInvOneMonoid (∀ i : I, f i) :=
+  { divInvMonoid with
+    inv_one := by ext; exact inv_one }
+
 @[to_additive]
 instance involutiveInv [∀ i, InvolutiveInv <| f i] : InvolutiveInv (∀ i, f i) :=
   { inv := Inv.inv
chore: fix grammar 1/3 (#5001)

All of these are doc fixes

Diff
@@ -380,7 +380,7 @@ def Pi.constMonoidHom (α β : Type _) [MulOneClass β] : β →* α → β wher
 
 See also `MonoidHom.eval`. -/
 @[to_additive (attr := simps) "Coercion of an `AddMonoidHom` into a function is itself
-a `AddMonoidHom`.
+an `AddMonoidHom`.
 
 See also `AddMonoidHom.eval`."]
 def MonoidHom.coeFn (α β : Type _) [MulOneClass α] [CommMonoid β] : (α →* β) →* α → β where
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 
 ! This file was ported from Lean 3 source module algebra.group.pi
-! leanprover-community/mathlib commit 90df25ded755a2cf9651ea850d1abe429b1e4eb1
+! leanprover-community/mathlib commit e4bc74cbaf429d706cb9140902f7ca6c431e75a4
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -473,6 +473,20 @@ def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i
 
 variable {f}
 
+@[to_additive]
+theorem Pi.mulSingle_sup [∀ i, SemilatticeSup (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
+    Pi.mulSingle i (x ⊔ y) = Pi.mulSingle i x ⊔ Pi.mulSingle i y :=
+  Function.update_sup _ _ _ _
+#align pi.mul_single_sup Pi.mulSingle_sup
+#align pi.single_sup Pi.single_sup
+
+@[to_additive]
+theorem Pi.mulSingle_inf [∀ i, SemilatticeInf (f i)] [∀ i, One (f i)] (i : I) (x y : f i) :
+    Pi.mulSingle i (x ⊓ y) = Pi.mulSingle i x ⊓ Pi.mulSingle i y :=
+  Function.update_inf _ _ _ _
+#align pi.mul_single_inf Pi.mulSingle_inf
+#align pi.single_inf Pi.single_inf
+
 @[to_additive]
 theorem Pi.mulSingle_mul [∀ i, MulOneClass <| f i] (i : I) (x y : f i) :
     mulSingle i (x * y) = mulSingle i x * mulSingle i y :=
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Simon Hudon, Patrick Massot
 
 ! This file was ported from Lean 3 source module algebra.group.pi
-! leanprover-community/mathlib commit b3f25363ae62cb169e72cd6b8b1ac97bacf21ca7
+! leanprover-community/mathlib commit 90df25ded755a2cf9651ea850d1abe429b1e4eb1
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -42,7 +42,7 @@ variable {I : Type u}
 variable {f : I → Type v}
 
 -- The family of types already equipped with instances
-variable (x y : ∀ i, f i) (i : I)
+variable (x y : ∀ i, f i) (i j : I)
 
 @[to_additive]
 theorem Set.preimage_one {α β : Type _} [One β] (s : Set β) [Decidable ((1 : β) ∈ s)] :
@@ -499,6 +499,26 @@ theorem Pi.single_mul [∀ i, MulZeroClass <| f i] (i : I) (x y : f i) :
   (MulHom.single f i).map_mul x y
 #align pi.single_mul Pi.single_mul
 
+theorem Pi.single_mul_left_apply [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (a * x i) j = Pi.single i a j * x j :=
+  (Pi.apply_single (fun i => (· * x i)) (fun _ => MulZeroClass.zero_mul _) _ _ _).symm
+#align pi.single_mul_left_apply Pi.single_mul_left_apply
+
+theorem Pi.single_mul_right_apply [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (x i * a) j = x j * Pi.single i a j :=
+  (Pi.apply_single (fun i => (· * ·) (x i)) (fun _ => MulZeroClass.mul_zero _) _ _ _).symm
+#align pi.single_mul_right_apply Pi.single_mul_right_apply
+
+theorem Pi.single_mul_left [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (a * x i) = Pi.single i a * x :=
+  funext fun _ => Pi.single_mul_left_apply _ _ _ _
+#align pi.single_mul_left Pi.single_mul_left
+
+theorem Pi.single_mul_right [∀ i, MulZeroClass <| f i] (a : f i) :
+    Pi.single i (x i * a) = x * Pi.single i a :=
+  funext fun _ => Pi.single_mul_right_apply _ _ _ _
+#align pi.single_mul_right Pi.single_mul_right
+
 /-- The injection into a pi group at different indices commutes.
 
 For injections of commuting elements at the same index, see `Commute.map` -/
@@ -665,3 +685,21 @@ noncomputable def Function.ExtendByOne.hom [MulOneClass R] :
 #align function.extend_by_zero.hom_apply Function.ExtendByZero.hom_apply
 
 end Extend
+
+namespace Pi
+
+variable [DecidableEq I] [∀ i, Preorder (f i)] [∀ i, One (f i)]
+
+@[to_additive]
+theorem mulSingle_mono : Monotone (Pi.mulSingle i : f i → ∀ i, f i) :=
+  Function.update_mono
+#align pi.mul_single_mono Pi.mulSingle_mono
+#align pi.single_mono Pi.single_mono
+
+@[to_additive]
+theorem mulSingle_strictMono : StrictMono (Pi.mulSingle i : f i → ∀ i, f i) :=
+  Function.update_strictMono
+#align pi.mul_single_strict_mono Pi.mulSingle_strictMono
+#align pi.single_strict_mono Pi.single_strictMono
+
+end Pi
fix: use to_additive (attr := _) here and there (#2073)
Diff
@@ -247,16 +247,16 @@ section MulHom
 
 /-- A family of MulHom's `f a : γ →ₙ* β a` defines a MulHom `Pi.mulHom f : γ →ₙ* Π a, β a`
 given by `Pi.mulHom f x b = f b x`. -/
-@[to_additive
-      "A family of AddHom's `f a : γ → β a` defines an AddHom `Pi.addHom f : γ → Π a, β a` given by
-      `Pi.addHom f x b = f b x`.",
-  simps]
+@[to_additive (attr := simps)
+  "A family of AddHom's `f a : γ → β a` defines an AddHom `Pi.addHom f : γ → Π a, β a` given by
+  `Pi.addHom f x b = f b x`."]
 def Pi.mulHom {γ : Type w} [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f i) : γ →ₙ* ∀ i, f i where
   toFun x i := g i x
   map_mul' x y := funext fun i => (g i).map_mul x y
 #align pi.mul_hom Pi.mulHom
 #align pi.add_hom Pi.addHom
 #align pi.mul_hom_apply Pi.mulHom_apply
+#align pi.add_hom_apply Pi.addHom_apply
 
 @[to_additive]
 theorem Pi.mulHom_injective {γ : Type w} [Nonempty I] [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f i)
@@ -268,10 +268,9 @@ theorem Pi.mulHom_injective {γ : Type w} [Nonempty I] [∀ i, Mul (f i)] [Mul 
 
 /-- A family of monoid homomorphisms `f a : γ →* β a` defines a monoid homomorphism
 `Pi.monoidHom f : γ →* Π a, β a` given by `Pi.monoidHom f x b = f b x`. -/
-@[to_additive
-      "A family of additive monoid homomorphisms `f a : γ →+ β a` defines a monoid homomorphism
-      `Pi.addMonoidHom f : γ →+ Π a, β a` given by `Pi.addMonoidHom f x b = f b x`.",
-  simps]
+@[to_additive (attr := simps)
+  "A family of additive monoid homomorphisms `f a : γ →+ β a` defines a monoid homomorphism
+  `Pi.addMonoidHom f : γ →+ Π a, β a` given by `Pi.addMonoidHom f x b = f b x`."]
 def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g : ∀ i, γ →* f i) :
     γ →* ∀ i, f i :=
   { Pi.mulHom fun i => (g i).toMulHom with
@@ -280,6 +279,7 @@ def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g :
 #align pi.monoid_hom Pi.monoidHom
 #align pi.add_monoid_hom Pi.addMonoidHom
 #align pi.monoid_hom_apply Pi.monoidHom_apply
+#align pi.add_monoid_hom_apply Pi.addMonoidHom_apply
 
 @[to_additive]
 theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f i)] [MulOneClass γ]
@@ -294,19 +294,19 @@ variable (f) [(i : I) → Mul (f i)]
 /-- Evaluation of functions into an indexed collection of semigroups at a point is a semigroup
 homomorphism.
 This is `Function.eval i` as a `MulHom`. -/
-@[to_additive
-      "Evaluation of functions into an indexed collection of additive semigroups at a point is an
-      additive semigroup homomorphism. This is `Function.eval i` as an `AddHom`.",
-  simps]
+@[to_additive (attr := simps)
+  "Evaluation of functions into an indexed collection of additive semigroups at a point is an
+  additive semigroup homomorphism. This is `Function.eval i` as an `AddHom`."]
 def Pi.evalMulHom (i : I) : (∀ i, f i) →ₙ* f i where
   toFun g := g i
   map_mul' _ _ := Pi.mul_apply _ _ i
 #align pi.eval_mul_hom Pi.evalMulHom
 #align pi.eval_add_hom Pi.evalAddHom
 #align pi.eval_mul_hom_apply Pi.evalMulHom_apply
+#align pi.eval_add_hom_apply Pi.evalAddHom_apply
 
 /-- `Function.const` as a `MulHom`. -/
-@[to_additive "`Function.const` as an `AddHom`.", simps]
+@[to_additive (attr := simps) "`Function.const` as an `AddHom`."]
 def Pi.constMulHom (α β : Type _) [Mul β] :
     β →ₙ* α → β where
   toFun := Function.const α
@@ -314,15 +314,14 @@ def Pi.constMulHom (α β : Type _) [Mul β] :
 #align pi.const_mul_hom Pi.constMulHom
 #align pi.const_add_hom Pi.constAddHom
 #align pi.const_mul_hom_apply Pi.constMulHom_apply
+#align pi.const_add_hom_apply Pi.constAddHom_apply
 
 /-- Coercion of a `MulHom` into a function is itself a `MulHom`.
 
 See also `MulHom.eval`. -/
-@[to_additive
-      "Coercion of an `AddHom` into a function is itself an `AddHom`.
+@[to_additive (attr := simps) "Coercion of an `AddHom` into a function is itself an `AddHom`.
 
-      See also `AddHom.eval`. ",
-  simps]
+See also `AddHom.eval`."]
 def MulHom.coeFn (α β : Type _) [Mul α] [CommSemigroup β] :
     (α →ₙ* β) →ₙ* α → β where
   toFun g := g
@@ -330,13 +329,12 @@ def MulHom.coeFn (α β : Type _) [Mul α] [CommSemigroup β] :
 #align mul_hom.coe_fn MulHom.coeFn
 #align add_hom.coe_fn AddHom.coeFn
 #align mul_hom.coe_fn_apply MulHom.coeFn_apply
+#align add_hom.coe_fn_apply AddHom.coeFn_apply
 
 /-- Semigroup homomorphism between the function spaces `I → α` and `I → β`, induced by a semigroup
 homomorphism `f` between `α` and `β`. -/
-@[to_additive
-      "Additive semigroup homomorphism between the function spaces `I → α` and `I → β`, induced by
-      an additive semigroup homomorphism `f` between `α` and `β`",
-  simps]
+@[to_additive (attr := simps) "Additive semigroup homomorphism between the function spaces `I → α`
+and `I → β`, induced by an additive semigroup homomorphism `f` between `α` and `β`"]
 protected def MulHom.compLeft {α β : Type _} [Mul α] [Mul β] (f : α →ₙ* β) (I : Type _) :
     (I → α) →ₙ* I → β where
   toFun h := f ∘ h
@@ -344,6 +342,7 @@ protected def MulHom.compLeft {α β : Type _} [Mul α] [Mul β] (f : α →ₙ*
 #align mul_hom.comp_left MulHom.compLeft
 #align add_hom.comp_left AddHom.compLeft
 #align mul_hom.comp_left_apply MulHom.compLeft_apply
+#align add_hom.comp_left_apply AddHom.compLeft_apply
 
 end MulHom
 
@@ -354,53 +353,50 @@ variable (f) [(i : I) → MulOneClass (f i)]
 /-- Evaluation of functions into an indexed collection of monoids at a point is a monoid
 homomorphism.
 This is `Function.eval i` as a `MonoidHom`. -/
-@[to_additive
-      "Evaluation of functions into an indexed collection of additive monoids at a point is an
-      additive monoid homomorphism. This is `Function.eval i` as an `AddMonoidHom`.",
-  simps]
-def Pi.evalMonoidHom (i : I) :
-    (∀ i, f i) →* f i where
+@[to_additive (attr := simps) "Evaluation of functions into an indexed collection of additive
+monoids at a point is an additive monoid homomorphism. This is `Function.eval i` as an
+`AddMonoidHom`."]
+def Pi.evalMonoidHom (i : I) : (∀ i, f i) →* f i where
   toFun g := g i
   map_one' := Pi.one_apply i
   map_mul' _ _ := Pi.mul_apply _ _ i
 #align pi.eval_monoid_hom Pi.evalMonoidHom
 #align pi.eval_add_monoid_hom Pi.evalAddMonoidHom
 #align pi.eval_monoid_hom_apply Pi.evalMonoidHom_apply
+#align pi.eval_add_monoid_hom_apply Pi.evalAddMonoidHom_apply
 
 /-- `Function.const` as a `MonoidHom`. -/
-@[to_additive "`Function.const` as an `AddMonoidHom`.", simps]
-def Pi.constMonoidHom (α β : Type _) [MulOneClass β] :
-    β →* α → β where
+@[to_additive (attr := simps) "`Function.const` as an `AddMonoidHom`."]
+def Pi.constMonoidHom (α β : Type _) [MulOneClass β] : β →* α → β where
   toFun := Function.const α
   map_one' := rfl
   map_mul' _ _ := rfl
 #align pi.const_monoid_hom Pi.constMonoidHom
 #align pi.const_add_monoid_hom Pi.constAddMonoidHom
 #align pi.const_monoid_hom_apply Pi.constMonoidHom_apply
+#align pi.const_add_monoid_hom_apply Pi.constAddMonoidHom_apply
 
 /-- Coercion of a `MonoidHom` into a function is itself a `MonoidHom`.
 
 See also `MonoidHom.eval`. -/
-@[to_additive
-      "Coercion of an `AddMonoidHom` into a function is itself a `AddMonoidHom`.
+@[to_additive (attr := simps) "Coercion of an `AddMonoidHom` into a function is itself
+a `AddMonoidHom`.
 
-      See also `AddMonoidHom.eval`. ",
-  simps]
-def MonoidHom.coeFn (α β : Type _) [MulOneClass α] [CommMonoid β] :
-    (α →* β) →* α → β where
+See also `AddMonoidHom.eval`."]
+def MonoidHom.coeFn (α β : Type _) [MulOneClass α] [CommMonoid β] : (α →* β) →* α → β where
   toFun g := g
   map_one' := rfl
   map_mul' _ _ := rfl
 #align monoid_hom.coe_fn MonoidHom.coeFn
 #align add_monoid_hom.coe_fn AddMonoidHom.coeFn
 #align monoid_hom.coe_fn_apply MonoidHom.coeFn_apply
+#align add_monoid_hom.coe_fn_apply AddMonoidHom.coeFn_apply
 
 /-- Monoid homomorphism between the function spaces `I → α` and `I → β`, induced by a monoid
 homomorphism `f` between `α` and `β`. -/
-@[to_additive
-      "Additive monoid homomorphism between the function spaces `I → α` and `I → β`, induced by an
-      additive monoid homomorphism `f` between `α` and `β`",
-  simps]
+@[to_additive (attr := simps)
+  "Additive monoid homomorphism between the function spaces `I → α` and `I → β`, induced by an
+  additive monoid homomorphism `f` between `α` and `β`"]
 protected def MonoidHom.compLeft {α β : Type _} [MulOneClass α] [MulOneClass β] (f : α →* β)
     (I : Type _) : (I → α) →* I → β where
   toFun h := f ∘ h
@@ -409,6 +405,7 @@ protected def MonoidHom.compLeft {α β : Type _} [MulOneClass α] [MulOneClass
 #align monoid_hom.comp_left MonoidHom.compLeft
 #align add_monoid_hom.comp_left AddMonoidHom.compLeft
 #align monoid_hom.comp_left_apply MonoidHom.compLeft_apply
+#align add_monoid_hom.comp_left_apply AddMonoidHom.compLeft_apply
 
 end MonoidHom
 
@@ -429,8 +426,7 @@ This is the `OneHom` version of `Pi.mulSingle`. -/
       as functions supported at a point.
 
       This is the `ZeroHom` version of `Pi.single`."]
-def OneHom.single [∀ i, One <| f i] (i : I) :
-    OneHom (f i) (∀ i, f i) where
+def OneHom.single [∀ i, One <| f i] (i : I) : OneHom (f i) (∀ i, f i) where
   toFun := mulSingle i
   map_one' := mulSingle_one i
 #align one_hom.single OneHom.single
@@ -469,8 +465,7 @@ into a dependent family of `MulZeroClass`es, as functions supported at a point.
 
 This is the `MulHom` version of `Pi.single`. -/
 @[simps]
-def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) :
-    f i →ₙ* ∀ i, f i where
+def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) : f i →ₙ* ∀ i, f i where
   toFun := Pi.single i
   map_mul' := Pi.single_op₂ (fun _ => (· * ·)) (fun _ => zero_mul _) _
 #align mul_hom.single MulHom.single
@@ -658,7 +653,7 @@ section Extend
 variable {η : Type v} (R : Type w) (s : ι → η)
 
 /-- `Function.extend s f 1` as a bundled hom. -/
-@[to_additive Function.ExtendByZero.hom "`Function.extend s f 0` as a bundled hom.", simps]
+@[to_additive (attr := simps) Function.ExtendByZero.hom "`Function.extend s f 0` as a bundled hom."]
 noncomputable def Function.ExtendByOne.hom [MulOneClass R] :
     (ι → R) →* η → R where
   toFun f := Function.extend s f 1
@@ -667,5 +662,6 @@ noncomputable def Function.ExtendByOne.hom [MulOneClass R] :
 #align function.extend_by_one.hom Function.ExtendByOne.hom
 #align function.extend_by_zero.hom Function.ExtendByZero.hom
 #align function.extend_by_one.hom_apply Function.ExtendByOne.hom_apply
+#align function.extend_by_zero.hom_apply Function.ExtendByZero.hom_apply
 
 end Extend
chore: add missing #align statements (#1902)

This PR is the result of a slight variant on the following "algorithm"

  • take all mathlib 3 names, remove _ and make all uppercase letters into lowercase
  • take all mathlib 4 names, remove _ and make all uppercase letters into lowercase
  • look for matches, and create pairs (original_lean3_name, OriginalLean4Name)
  • for pairs that do not have an align statement:
    • use Lean 4 to lookup the file + position of the Lean 4 name
    • add an #align statement just before the next empty line
  • manually fix some tiny mistakes (e.g., empty lines in proofs might cause the #align statement to have been inserted too early)
Diff
@@ -256,6 +256,7 @@ def Pi.mulHom {γ : Type w} [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f
   map_mul' x y := funext fun i => (g i).map_mul x y
 #align pi.mul_hom Pi.mulHom
 #align pi.add_hom Pi.addHom
+#align pi.mul_hom_apply Pi.mulHom_apply
 
 @[to_additive]
 theorem Pi.mulHom_injective {γ : Type w} [Nonempty I] [∀ i, Mul (f i)] [Mul γ] (g : ∀ i, γ →ₙ* f i)
@@ -278,6 +279,7 @@ def Pi.monoidHom {γ : Type w} [∀ i, MulOneClass (f i)] [MulOneClass γ] (g :
     map_one' := funext fun i => (g i).map_one }
 #align pi.monoid_hom Pi.monoidHom
 #align pi.add_monoid_hom Pi.addMonoidHom
+#align pi.monoid_hom_apply Pi.monoidHom_apply
 
 @[to_additive]
 theorem Pi.monoidHom_injective {γ : Type w} [Nonempty I] [∀ i, MulOneClass (f i)] [MulOneClass γ]
@@ -301,6 +303,7 @@ def Pi.evalMulHom (i : I) : (∀ i, f i) →ₙ* f i where
   map_mul' _ _ := Pi.mul_apply _ _ i
 #align pi.eval_mul_hom Pi.evalMulHom
 #align pi.eval_add_hom Pi.evalAddHom
+#align pi.eval_mul_hom_apply Pi.evalMulHom_apply
 
 /-- `Function.const` as a `MulHom`. -/
 @[to_additive "`Function.const` as an `AddHom`.", simps]
@@ -310,6 +313,7 @@ def Pi.constMulHom (α β : Type _) [Mul β] :
   map_mul' _ _ := rfl
 #align pi.const_mul_hom Pi.constMulHom
 #align pi.const_add_hom Pi.constAddHom
+#align pi.const_mul_hom_apply Pi.constMulHom_apply
 
 /-- Coercion of a `MulHom` into a function is itself a `MulHom`.
 
@@ -325,6 +329,7 @@ def MulHom.coeFn (α β : Type _) [Mul α] [CommSemigroup β] :
   map_mul' _ _ := rfl
 #align mul_hom.coe_fn MulHom.coeFn
 #align add_hom.coe_fn AddHom.coeFn
+#align mul_hom.coe_fn_apply MulHom.coeFn_apply
 
 /-- Semigroup homomorphism between the function spaces `I → α` and `I → β`, induced by a semigroup
 homomorphism `f` between `α` and `β`. -/
@@ -338,6 +343,7 @@ protected def MulHom.compLeft {α β : Type _} [Mul α] [Mul β] (f : α →ₙ*
   map_mul' _ _ := by ext; simp
 #align mul_hom.comp_left MulHom.compLeft
 #align add_hom.comp_left AddHom.compLeft
+#align mul_hom.comp_left_apply MulHom.compLeft_apply
 
 end MulHom
 
@@ -359,6 +365,7 @@ def Pi.evalMonoidHom (i : I) :
   map_mul' _ _ := Pi.mul_apply _ _ i
 #align pi.eval_monoid_hom Pi.evalMonoidHom
 #align pi.eval_add_monoid_hom Pi.evalAddMonoidHom
+#align pi.eval_monoid_hom_apply Pi.evalMonoidHom_apply
 
 /-- `Function.const` as a `MonoidHom`. -/
 @[to_additive "`Function.const` as an `AddMonoidHom`.", simps]
@@ -369,6 +376,7 @@ def Pi.constMonoidHom (α β : Type _) [MulOneClass β] :
   map_mul' _ _ := rfl
 #align pi.const_monoid_hom Pi.constMonoidHom
 #align pi.const_add_monoid_hom Pi.constAddMonoidHom
+#align pi.const_monoid_hom_apply Pi.constMonoidHom_apply
 
 /-- Coercion of a `MonoidHom` into a function is itself a `MonoidHom`.
 
@@ -385,6 +393,7 @@ def MonoidHom.coeFn (α β : Type _) [MulOneClass α] [CommMonoid β] :
   map_mul' _ _ := rfl
 #align monoid_hom.coe_fn MonoidHom.coeFn
 #align add_monoid_hom.coe_fn AddMonoidHom.coeFn
+#align monoid_hom.coe_fn_apply MonoidHom.coeFn_apply
 
 /-- Monoid homomorphism between the function spaces `I → α` and `I → β`, induced by a monoid
 homomorphism `f` between `α` and `β`. -/
@@ -399,6 +408,7 @@ protected def MonoidHom.compLeft {α β : Type _} [MulOneClass α] [MulOneClass
   map_mul' _ _ := by ext; simp
 #align monoid_hom.comp_left MonoidHom.compLeft
 #align add_monoid_hom.comp_left AddMonoidHom.compLeft
+#align monoid_hom.comp_left_apply MonoidHom.compLeft_apply
 
 end MonoidHom
 
@@ -464,6 +474,7 @@ def MulHom.single [∀ i, MulZeroClass <| f i] (i : I) :
   toFun := Pi.single i
   map_mul' := Pi.single_op₂ (fun _ => (· * ·)) (fun _ => zero_mul _) _
 #align mul_hom.single MulHom.single
+#align mul_hom.single_apply MulHom.single_apply
 
 variable {f}
 
@@ -655,5 +666,6 @@ noncomputable def Function.ExtendByOne.hom [MulOneClass R] :
   map_mul' f g := by simpa using Function.extend_mul s f g 1 1
 #align function.extend_by_one.hom Function.ExtendByOne.hom
 #align function.extend_by_zero.hom Function.ExtendByZero.hom
+#align function.extend_by_one.hom_apply Function.ExtendByOne.hom_apply
 
 end Extend
chore: the style linter shouldn't complain about long #align lines (#1643)
Diff
@@ -565,9 +565,7 @@ theorem Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle {M : Type _} [Comm
     · rfl
     · apply mul_comm
     · simp_rw [← Pi.mulSingle_mul, h, mulSingle_one]
-#align
-  pi.mul_single_mul_mul_single_eq_mul_single_mul_mul_single
-  Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle
+#align pi.mul_single_mul_mul_single_eq_mul_single_mul_mul_single Pi.mulSingle_mul_mulSingle_eq_mulSingle_mul_mulSingle
 #align pi.single_add_single_eq_single_add_single Pi.single_add_single_eq_single_add_single
 
 end Single
Diff
@@ -623,7 +623,7 @@ section Piecewise
 theorem Set.piecewise_mul [∀ i, Mul (f i)] (s : Set I) [∀ i, Decidable (i ∈ s)]
     (f₁ f₂ g₁ g₂ : ∀ i, f i) :
     s.piecewise (f₁ * f₂) (g₁ * g₂) = s.piecewise f₁ g₁ * s.piecewise f₂ g₂ :=
-  s.piecewise_op₂ _ _ _ _ fun _ => (· * ·)
+  s.piecewise_op₂ f₁ _ _ _ fun _ => (· * ·)
 #align set.piecewise_mul Set.piecewise_mul
 #align set.piecewise_add Set.piecewise_add
 
@@ -638,7 +638,7 @@ theorem Set.piecewise_inv [∀ i, Inv (f i)] (s : Set I) [∀ i, Decidable (i 
 theorem Set.piecewise_div [∀ i, Div (f i)] (s : Set I) [∀ i, Decidable (i ∈ s)]
     (f₁ f₂ g₁ g₂ : ∀ i, f i) :
     s.piecewise (f₁ / f₂) (g₁ / g₂) = s.piecewise f₁ g₁ / s.piecewise f₂ g₂ :=
-  s.piecewise_op₂ _ _ _ _ fun _ => (· / ·)
+  s.piecewise_op₂ f₁ _ _ _ fun _ => (· / ·)
 #align set.piecewise_div Set.piecewise_div
 #align set.piecewise_sub Set.piecewise_sub
 
feat: improve the way to_additive deals with attributes (#1314)
  • The new syntax for any attributes that need to be copied by to_additive is @[to_additive (attrs := simp, ext, simps)]
  • Adds the auxiliary declarations generated by the simp and simps attributes to the to_additive-dictionary.
  • Future issue: Does not yet translate auxiliary declarations for other attributes (including custom simp-attributes). In particular it's possible that norm_cast might generate some auxiliary declarations.
  • Fixes #950
  • Fixes #953
  • Fixes #1149
  • This moves the interaction between to_additive and simps from the Simps file to the toAdditive file for uniformity.
  • Make the same changes to @[reassoc]

Co-authored-by: Johan Commelin <johan@commelin.net> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -426,7 +426,7 @@ def OneHom.single [∀ i, One <| f i] (i : I) :
 #align one_hom.single OneHom.single
 #align zero_hom.single ZeroHom.single
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem OneHom.single_apply [∀ i, One <| f i] (i : I) (x : f i) :
     OneHom.single f i x = mulSingle i x :=
   rfl
@@ -447,7 +447,7 @@ def MonoidHom.single [∀ i, MulOneClass <| f i] (i : I) : f i →* ∀ i, f i :
 #align monoid_hom.single MonoidHom.single
 #align add_monoid_hom.single AddMonoidHom.single
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem MonoidHom.single_apply [∀ i, MulOneClass <| f i] (i : I) (x : f i) :
     MonoidHom.single f i x = mulSingle i x :=
   rfl
@@ -574,7 +574,7 @@ end Single
 
 namespace Function
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem update_one [∀ i, One (f i)] [DecidableEq I] (i : I) : update (1 : ∀ i, f i) i 1 = 1 :=
   update_eq_self i (1 : (a : I) → f a)
 #align function.update_one Function.update_one
@@ -603,7 +603,7 @@ theorem update_div [∀ i, Div (f i)] [DecidableEq I] (f₁ f₂ : ∀ i, f i) (
 
 variable [One α] [Nonempty ι] {a : α}
 
-@[simp, to_additive]
+@[to_additive (attr := simp)]
 theorem const_eq_one : const ι a = 1 ↔ a = 1 :=
   @const_inj _ _ _ _ 1
 #align function.const_eq_one Function.const_eq_one
fix: add missing natCast and intCast fields (#1197)

These were dropped during the port.

Diff
@@ -93,7 +93,11 @@ instance monoid [∀ i, Monoid <| f i] : Monoid (∀ i : I, f i) :=
 #align pi.add_monoid Pi.addMonoid
 
 instance addMonoidWithOne [∀ i, AddMonoidWithOne <| f i] : AddMonoidWithOne (∀ i : I, f i) :=
-  { addMonoid with }
+  { addMonoid with
+    natCast := fun n _ => n
+    natCast_zero := funext fun _ => AddMonoidWithOne.natCast_zero
+    natCast_succ := fun n => funext fun _ => AddMonoidWithOne.natCast_succ n
+  }
 
 @[to_additive]
 instance commMonoid [∀ i, CommMonoid <| f i] : CommMonoid (∀ i : I, f i) :=
@@ -144,7 +148,11 @@ instance group [∀ i, Group <| f i] : Group (∀ i : I, f i) :=
 #align pi.add_group Pi.addGroup
 
 instance addGroupWithOne [∀ i, AddGroupWithOne <| f i] : AddGroupWithOne (∀ i : I, f i) :=
-  { addGroup with }
+  { addGroup, addMonoidWithOne with
+    intCast := fun z _ => z
+    intCast_ofNat := fun n => funext fun _ => AddGroupWithOne.intCast_ofNat n
+    intCast_negSucc := fun n => funext fun _ => AddGroupWithOne.intCast_negSucc n
+  }
 
 @[to_additive]
 instance commGroup [∀ i, CommGroup <| f i] : CommGroup (∀ i : I, f i) :=
feat: port algebra.group.pi (#1088)

mathlib3port tracking sha: b3f25363ae62cb169e72cd6b8b1ac97bacf21ca7

Porting notes

  • Moved AddMonoidWithOne and AddGroupWithOne here from their original files.
  • Corrected the name of Pi.Single to Pi.single in Data.Pi.Algebra, on which this depends. (Note: this change was only done in the final two commits, which can be split off into a subsequent PR for a good history if need be.)
  • Replaced explicit data fields by sourcing previously-defined instances where possible, as per this zulip discussion
  • Changed a name: update_eq_div_mulSingle => update_eq_div_mul_mulSingle, as it involves a multiplication of two mulSingles. (Note: the additive version in mathlib is update_eq_sub_add_single, and to_additive "agrees" that update_eq_div_mul_mulSingle is the right name in mathlib4.)

Review questions

  • Are we sure about using instances as sources where possible? Just want to double-check that it won't cause any problems.
  • If so, should the "highest-up" or "lowest-down" instances be used for sourcing when diamonds occur? E.g. Foo extends Bar0, Bar1, and both have relevant instances bar0, bar1. However, Bar1 extends Baz, and we also have a relevant instance baz which suffices for everything not in Bar0. Should the instance for Foo start { bar0, bar1 with ... } or { bar0, baz with ... }? Does it matter?
  • Should the data mul := (· * ·), zero := (0 : ∀ i, f i) remain explicit or be obtained by sourcing Pi.instMul, Pi.instZero respectively?

Dependencies 59

60 files ported (100.0%)
30228 lines ported (100.0%)

All dependencies are ported!