l3lab/ntp-mathlib huggingface dataset:
lemma center_iff_op_centroid (a : α) :
    a ∈ NonUnitalSubsemiring.center α ↔ L a = R a ∧ (L a) ∈ Set.range CentroidHom.toEnd := by
  constructor
  · exact fun ha ↦ ⟨AddMonoidHom.ext <| IsMulCentral.comm ha, ⟨centerToCentroid ⟨a, ha⟩, rfl⟩⟩
  · rintro ⟨hc, ⟨T, hT⟩⟩
    have e1 (d : α) : T d = a * d := congr($hT d)
    have e2 (d : α) : T d = d * a := congr($(hT.trans hc) d)
    constructor
    case comm => exact (congr($hc ·))
    case left_assoc => simpa [e1] using (map_mul_right T · ·)
    

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝¹² : NonUnitalNonAssocSemiring α
inst✝¹¹ : Monoid M
inst✝¹⁰ : Monoid N
inst✝⁹ : Semiring R
inst✝⁸ : DistribMulAction M α
inst✝⁷ : SMulCommClass M α α
inst✝⁶ : IsScalarTower M α α
inst✝⁵ : DistribMulAction N α
inst✝⁴ : SMulCommClass N α α
inst✝³ : IsScalarTower N α α
inst✝² : Module R α
inst✝¹ : SMulCommClass R α α
inst✝ : IsScalarTower R α α
a : α
hc : L a = R a
T : CentroidHom α
hT : toEnd T = L a
e1 : ∀ (d : α), T d = a * d
e2 : ∀ (d : α), T d = d * a
⊢ ∀ (a_1 c : α), a_1 * a * c = a_1 * (a * c)

Next tactic:
case mid_assoc => exact fun b c ↦ by simpa [e1 c, e2 b] using
      (map_mul_right T b c).symm.trans <| map_mul_left T b c
lemma center_iff_op_centroid (a : α) :
    a ∈ NonUnitalSubsemiring.center α ↔ L a = R a ∧ (L a) ∈ Set.range CentroidHom.toEnd := by
  constructor
  · exact fun ha ↦ ⟨AddMonoidHom.ext <| IsMulCentral.comm ha, ⟨centerToCentroid ⟨a, ha⟩, rfl⟩⟩
  · rintro ⟨hc, ⟨T, hT⟩⟩
    have e1 (d : α) : T d = a * d := congr($hT d)
    have e2 (d : α) : T d = d * a := congr($(hT.trans hc) d)
    constructor
    case comm => exact (congr($hc ·))
    case left_assoc => simpa [e1] using (map_mul_right T · ·)
    case mid_assoc => 

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝¹² : NonUnitalNonAssocSemiring α
inst✝¹¹ : Monoid M
inst✝¹⁰ : Monoid N
inst✝⁹ : Semiring R
inst✝⁸ : DistribMulAction M α
inst✝⁷ : SMulCommClass M α α
inst✝⁶ : IsScalarTower M α α
inst✝⁵ : DistribMulAction N α
inst✝⁴ : SMulCommClass N α α
inst✝³ : IsScalarTower N α α
inst✝² : Module R α
inst✝¹ : SMulCommClass R α α
inst✝ : IsScalarTower R α α
a : α
hc : L a = R a
T : CentroidHom α
hT : toEnd T = L a
e1 : ∀ (d : α), T d = a * d
e2 : ∀ (d : α), T d = d * a
⊢ ∀ (a_1 c : α), a_1 * a * c = a_1 * (a * c)

Next tactic:
exact fun b c ↦ by simpa [e1 c, e2 b] using
      (map_mul_right T b c).symm.trans <| map_mul_left T b c
lemma center_iff_op_centroid (a : α) :
    a ∈ NonUnitalSubsemiring.center α ↔ L a = R a ∧ (L a) ∈ Set.range CentroidHom.toEnd := by
  constructor
  · exact fun ha ↦ ⟨AddMonoidHom.ext <| IsMulCentral.comm ha, ⟨centerToCentroid ⟨a, ha⟩, rfl⟩⟩
  · rintro ⟨hc, ⟨T, hT⟩⟩
    have e1 (d : α) : T d = a * d := congr($hT d)
    have e2 (d : α) : T d = d * a := congr($(hT.trans hc) d)
    constructor
    case comm => exact (congr($hc ·))
    case left_assoc => simpa [e1] using (map_mul_right T · ·)
    case mid_assoc => exact fun b c ↦ by 

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝¹² : NonUnitalNonAssocSemiring α
inst✝¹¹ : Monoid M
inst✝¹⁰ : Monoid N
inst✝⁹ : Semiring R
inst✝⁸ : DistribMulAction M α
inst✝⁷ : SMulCommClass M α α
inst✝⁶ : IsScalarTower M α α
inst✝⁵ : DistribMulAction N α
inst✝⁴ : SMulCommClass N α α
inst✝³ : IsScalarTower N α α
inst✝² : Module R α
inst✝¹ : SMulCommClass R α α
inst✝ : IsScalarTower R α α
a : α
hc : L a = R a
T : CentroidHom α
hT : toEnd T = L a
e1 : ∀ (d : α), T d = a * d
e2 : ∀ (d : α), T d = d * a
b c : α
⊢ b * a * c = b * (a * c)

Next tactic:
simpa [e1 c, e2 b] using
      (map_mul_right T b c).symm.trans <| map_mul_left T b c
lemma center_iff_op_centroid (a : α) :
    a ∈ NonUnitalSubsemiring.center α ↔ L a = R a ∧ (L a) ∈ Set.range CentroidHom.toEnd := by
  constructor
  · exact fun ha ↦ ⟨AddMonoidHom.ext <| IsMulCentral.comm ha, ⟨centerToCentroid ⟨a, ha⟩, rfl⟩⟩
  · rintro ⟨hc, ⟨T, hT⟩⟩
    have e1 (d : α) : T d = a * d := congr($hT d)
    have e2 (d : α) : T d = d * a := congr($(hT.trans hc) d)
    constructor
    case comm => exact (congr($hc ·))
    case left_assoc => simpa [e1] using (map_mul_right T · ·)
    case mid_assoc => exact fun b c ↦ by simpa [e1 c, e2 b] using
      (map_mul_right T b c).symm.trans <| map_mul_left T b c
    

Proof state:
case mpr.intro.intro.right_assoc
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝¹² : NonUnitalNonAssocSemiring α
inst✝¹¹ : Monoid M
inst✝¹⁰ : Monoid N
inst✝⁹ : Semiring R
inst✝⁸ : DistribMulAction M α
inst✝⁷ : SMulCommClass M α α
inst✝⁶ : IsScalarTower M α α
inst✝⁵ : DistribMulAction N α
inst✝⁴ : SMulCommClass N α α
inst✝³ : IsScalarTower N α α
inst✝² : Module R α
inst✝¹ : SMulCommClass R α α
inst✝ : IsScalarTower R α α
a : α
hc : L a = R a
T : CentroidHom α
hT : toEnd T = L a
e1 : ∀ (d : α), T d = a * d
e2 : ∀ (d : α), T d = d * a
⊢ ∀ (a_1 b : α), a_1 * b * a = a_1 * (b * a)

Next tactic:
case right_assoc => simpa [e2] using (map_mul_left T · ·)
lemma center_iff_op_centroid (a : α) :
    a ∈ NonUnitalSubsemiring.center α ↔ L a = R a ∧ (L a) ∈ Set.range CentroidHom.toEnd := by
  constructor
  · exact fun ha ↦ ⟨AddMonoidHom.ext <| IsMulCentral.comm ha, ⟨centerToCentroid ⟨a, ha⟩, rfl⟩⟩
  · rintro ⟨hc, ⟨T, hT⟩⟩
    have e1 (d : α) : T d = a * d := congr($hT d)
    have e2 (d : α) : T d = d * a := congr($(hT.trans hc) d)
    constructor
    case comm => exact (congr($hc ·))
    case left_assoc => simpa [e1] using (map_mul_right T · ·)
    case mid_assoc => exact fun b c ↦ by simpa [e1 c, e2 b] using
      (map_mul_right T b c).symm.trans <| map_mul_left T b c
    

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝¹² : NonUnitalNonAssocSemiring α
inst✝¹¹ : Monoid M
inst✝¹⁰ : Monoid N
inst✝⁹ : Semiring R
inst✝⁸ : DistribMulAction M α
inst✝⁷ : SMulCommClass M α α
inst✝⁶ : IsScalarTower M α α
inst✝⁵ : DistribMulAction N α
inst✝⁴ : SMulCommClass N α α
inst✝³ : IsScalarTower N α α
inst✝² : Module R α
inst✝¹ : SMulCommClass R α α
inst✝ : IsScalarTower R α α
a : α
hc : L a = R a
T : CentroidHom α
hT : toEnd T = L a
e1 : ∀ (d : α), T d = a * d
e2 : ∀ (d : α), T d = d * a
⊢ ∀ (a_1 b : α), a_1 * b * a = a_1 * (b * a)

Next tactic:
case right_assoc => simpa [e2] using (map_mul_left T · ·)
lemma center_iff_op_centroid (a : α) :
    a ∈ NonUnitalSubsemiring.center α ↔ L a = R a ∧ (L a) ∈ Set.range CentroidHom.toEnd := by
  constructor
  · exact fun ha ↦ ⟨AddMonoidHom.ext <| IsMulCentral.comm ha, ⟨centerToCentroid ⟨a, ha⟩, rfl⟩⟩
  · rintro ⟨hc, ⟨T, hT⟩⟩
    have e1 (d : α) : T d = a * d := congr($hT d)
    have e2 (d : α) : T d = d * a := congr($(hT.trans hc) d)
    constructor
    case comm => exact (congr($hc ·))
    case left_assoc => simpa [e1] using (map_mul_right T · ·)
    case mid_assoc => exact fun b c ↦ by simpa [e1 c, e2 b] using
      (map_mul_right T b c).symm.trans <| map_mul_left T b c
    case right_assoc => 

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝¹² : NonUnitalNonAssocSemiring α
inst✝¹¹ : Monoid M
inst✝¹⁰ : Monoid N
inst✝⁹ : Semiring R
inst✝⁸ : DistribMulAction M α
inst✝⁷ : SMulCommClass M α α
inst✝⁶ : IsScalarTower M α α
inst✝⁵ : DistribMulAction N α
inst✝⁴ : SMulCommClass N α α
inst✝³ : IsScalarTower N α α
inst✝² : Module R α
inst✝¹ : SMulCommClass R α α
inst✝ : IsScalarTower R α α
a : α
hc : L a = R a
T : CentroidHom α
hT : toEnd T = L a
e1 : ∀ (d : α), T d = a * d
e2 : ∀ (d : α), T d = d * a
⊢ ∀ (a_1 b : α), a_1 * b * a = a_1 * (b * a)

Next tactic:
simpa [e2] using (map_mul_left T · ·)
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by 

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ T 1 ∈ NonUnitalSubsemiring.center α

Next tactic:
refine ⟨?_, ?_, ?_, ?_⟩
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by refine ⟨?_, ?_, ?_, ?_⟩; 

Proof state:
case refine_1
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (a : α), T 1 * a = a * T 1
case refine_2
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (b c : α), T 1 * (b * c) = T 1 * b * c
case refine_3
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (a c : α), a * T 1 * c = a * (T 1 * c)
case refine_4
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (a b : α), a * b * T 1 = a * (b * T 1)

Next tactic:
all_goals simp [← map_mul_left, ← map_mul_right]
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by refine ⟨?_, ?_, ?_, ?_⟩; all_goals 

Proof state:
case refine_1
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (a : α), T 1 * a = a * T 1

Next tactic:
simp [← map_mul_left, ← map_mul_right]
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by refine ⟨?_, ?_, ?_, ?_⟩; all_goals 

Proof state:
case refine_2
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (b c : α), T 1 * (b * c) = T 1 * b * c

Next tactic:
simp [← map_mul_left, ← map_mul_right]
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by refine ⟨?_, ?_, ?_, ?_⟩; all_goals 

Proof state:
case refine_3
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (a c : α), a * T 1 * c = a * (T 1 * c)

Next tactic:
simp [← map_mul_left, ← map_mul_right]
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by refine ⟨?_, ?_, ?_, ?_⟩; all_goals 

Proof state:
case refine_4
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (a b : α), a * b * T 1 = a * (b * T 1)

Next tactic:
simp [← map_mul_left, ← map_mul_right]
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by refine ⟨?_, ?_, ?_, ?_⟩; all_goals simp [← map_mul_left, ← map_mul_right]⟩
    left_inv := fun z ↦ Subtype.ext <| by 

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
z : ↥(NonUnitalSubsemiring.center α)
⊢ ↑((fun T => { val := T 1, property := (_ : IsMulCentral (T 1)) }) (MulHom.toFun src✝.toMulHom z)) = ↑z

Next tactic:
simp [centerToCentroid_apply]
/-- The canonical isomorphism from the center of a (non-associative) semiring onto its centroid. -/
def centerIsoCentroid : NonUnitalSubsemiring.center α ≃+* CentroidHom α :=
  { centerToCentroid with
    invFun := fun T ↦
      ⟨T 1, by refine ⟨?_, ?_, ?_, ?_⟩; all_goals simp [← map_mul_left, ← map_mul_right]⟩
    left_inv := fun z ↦ Subtype.ext <| by simp [centerToCentroid_apply]
    right_inv := fun T ↦ CentroidHom.ext <| by 

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonAssocSemiring α
src✝ : ↥(NonUnitalSubsemiring.center α) →ₙ+* CentroidHom α := centerToCentroid
T : CentroidHom α
⊢ ∀ (a : α), (MulHom.toFun src✝.toMulHom ((fun T => { val := T 1, property := (_ : IsMulCentral (T 1)) }) T)) a = T a

Next tactic:
simp [centerToCentroid_apply, ← map_mul_right]
/-- Negation of `CentroidHom`s as a `CentroidHom`. -/
instance : Neg (CentroidHom α) :=
  ⟨fun f ↦
    { (-f : α →+ α) with
      map_mul_left' := fun a b ↦ by
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f : CentroidHom α
src✝ : α →+ α := -↑f
a b : α
⊢ ZeroHom.toFun
      (↑{ toZeroHom := ↑src✝,
          map_add' :=
            (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
      (a * b) =
    a *
      ZeroHom.toFun
        (↑{ toZeroHom := ↑src✝,
            map_add' :=
              (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
        b

Next tactic:
change -f (a * b) = a * (-f b)
/-- Negation of `CentroidHom`s as a `CentroidHom`. -/
instance : Neg (CentroidHom α) :=
  ⟨fun f ↦
    { (-f : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change -f (a * b) = a * (-f b)
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f : CentroidHom α
src✝ : α →+ α := -↑f
a b : α
⊢ -f (a * b) = a * -f b

Next tactic:
simp [map_mul_left]
/-- Negation of `CentroidHom`s as a `CentroidHom`. -/
instance : Neg (CentroidHom α) :=
  ⟨fun f ↦
    { (-f : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change -f (a * b) = a * (-f b)
        simp [map_mul_left]
      map_mul_right' := fun a b ↦ by
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f : CentroidHom α
src✝ : α →+ α := -↑f
a b : α
⊢ ZeroHom.toFun
      (↑{ toZeroHom := ↑src✝,
          map_add' :=
            (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
      (a * b) =
    ZeroHom.toFun
        (↑{ toZeroHom := ↑src✝,
            map_add' :=
              (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
        a *
      b

Next tactic:
change -f (a * b) = (-f a) * b
/-- Negation of `CentroidHom`s as a `CentroidHom`. -/
instance : Neg (CentroidHom α) :=
  ⟨fun f ↦
    { (-f : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change -f (a * b) = a * (-f b)
        simp [map_mul_left]
      map_mul_right' := fun a b ↦ by
        change -f (a * b) = (-f a) * b
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f : CentroidHom α
src✝ : α →+ α := -↑f
a b : α
⊢ -f (a * b) = -f a * b

Next tactic:
simp [map_mul_right]
instance : Sub (CentroidHom α) :=
  ⟨fun f g ↦
    { (f - g : α →+ α) with
      map_mul_left' := fun a b ↦ by
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f g : CentroidHom α
src✝ : α →+ α := ↑f - ↑g
a b : α
⊢ ZeroHom.toFun
      (↑{ toZeroHom := ↑src✝,
          map_add' :=
            (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
      (a * b) =
    a *
      ZeroHom.toFun
        (↑{ toZeroHom := ↑src✝,
            map_add' :=
              (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
        b

Next tactic:
change (⇑f - ⇑g) (a * b) = a * (⇑f - ⇑g) b
instance : Sub (CentroidHom α) :=
  ⟨fun f g ↦
    { (f - g : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change (⇑f - ⇑g) (a * b) = a * (⇑f - ⇑g) b
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f g : CentroidHom α
src✝ : α →+ α := ↑f - ↑g
a b : α
⊢ (⇑f - ⇑g) (a * b) = a * (⇑f - ⇑g) b

Next tactic:
simp [map_mul_left, mul_sub]
instance : Sub (CentroidHom α) :=
  ⟨fun f g ↦
    { (f - g : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change (⇑f - ⇑g) (a * b) = a * (⇑f - ⇑g) b
        simp [map_mul_left, mul_sub]
      map_mul_right' := fun a b ↦ by
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f g : CentroidHom α
src✝ : α →+ α := ↑f - ↑g
a b : α
⊢ ZeroHom.toFun
      (↑{ toZeroHom := ↑src✝,
          map_add' :=
            (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
      (a * b) =
    ZeroHom.toFun
        (↑{ toZeroHom := ↑src✝,
            map_add' :=
              (_ : ∀ (x y : α), ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) })
        a *
      b

Next tactic:
change (⇑f - ⇑g) (a * b) = ((⇑f - ⇑g) a) * b
instance : Sub (CentroidHom α) :=
  ⟨fun f g ↦
    { (f - g : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change (⇑f - ⇑g) (a * b) = a * (⇑f - ⇑g) b
        simp [map_mul_left, mul_sub]
      map_mul_right' := fun a b ↦ by
        change (⇑f - ⇑g) (a * b) = ((⇑f - ⇑g) a) * b
        

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalNonAssocRing α
f g : CentroidHom α
src✝ : α →+ α := ↑f - ↑g
a b : α
⊢ (⇑f - ⇑g) (a * b) = (⇑f - ⇑g) a * b

Next tactic:
simp [map_mul_right, sub_mul]
/-- A prime associative ring has commutative centroid. -/
@[reducible]
def commRing (h : ∀ a b : α, (∀ r : α, a * r * b = 0) → a = 0 ∨ b = 0) : CommRing (CentroidHom α) :=
  { CentroidHom.instRing with
    mul_comm := fun f g ↦ by
      

Proof state:
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalRing α
h : ∀ (a b : α), (∀ (r : α), a * r * b = 0) → a = 0 ∨ b = 0
src✝ : Ring (CentroidHom α) := instRing
f g : CentroidHom α
⊢ f * g = g * f

Next tactic:
ext
/-- A prime associative ring has commutative centroid. -/
@[reducible]
def commRing (h : ∀ a b : α, (∀ r : α, a * r * b = 0) → a = 0 ∨ b = 0) : CommRing (CentroidHom α) :=
  { CentroidHom.instRing with
    mul_comm := fun f g ↦ by
      ext
      

Proof state:
case h
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalRing α
h : ∀ (a b : α), (∀ (r : α), a * r * b = 0) → a = 0 ∨ b = 0
src✝ : Ring (CentroidHom α) := instRing
f g : CentroidHom α
a✝ : α
⊢ (f * g) a✝ = (g * f) a✝

Next tactic:
refine' sub_eq_zero.1 (or_self_iff.1 <| (h _ _) fun r ↦ _)
/-- A prime associative ring has commutative centroid. -/
@[reducible]
def commRing (h : ∀ a b : α, (∀ r : α, a * r * b = 0) → a = 0 ∨ b = 0) : CommRing (CentroidHom α) :=
  { CentroidHom.instRing with
    mul_comm := fun f g ↦ by
      ext
      refine' sub_eq_zero.1 (or_self_iff.1 <| (h _ _) fun r ↦ _)
      

Proof state:
case h
F : Type u_1
M : Type u_2
N : Type u_3
R : Type u_4
α : Type u_5
inst✝ : NonUnitalRing α
h : ∀ (a b : α), (∀ (r : α), a * r * b = 0) → a = 0 ∨ b = 0
src✝ : Ring (CentroidHom α) := instRing
f g : CentroidHom α
a✝ r : α
⊢ ((f * g) a✝ - (g * f) a✝) * r * ((f * g) a✝ - (g * f) a✝) = 0

Next tactic:
rw [mul_assoc, sub_mul, sub_eq_zero, ← map_mul_right, ← map_mul_right, coe_mul, coe_mul,
        comp_mul_comm]
@[simp]
theorem SlashAction.neg_slash {β G α γ : Type*} [Group G] [AddGroup α] [SMul γ α]
    [SlashAction β G α γ] (k : β) (g : G) (a : α) : (-a) ∣[k;γ] g = -a ∣[k;γ] g :=
  eq_neg_of_add_eq_zero_left <| by
    

Proof state:
β : Type u_1
G : Type u_2
α : Type u_3
γ : Type u_4
inst✝³ : Group G
inst✝² : AddGroup α
inst✝¹ : SMul γ α
inst✝ : SlashAction β G α γ
k : β
g : G
a : α
⊢ (-a) ∣[k;γ] g + a ∣[k;γ] g = 0

Next tactic:
rw [← SlashAction.add_slash, add_left_neg, SlashAction.zero_slash]
@[simp]
theorem SlashAction.smul_slash_of_tower {R β G α : Type*} (γ : Type*) [Group G] [AddGroup α]
    [Monoid γ] [MulAction γ α] [SMul R γ] [SMul R α] [IsScalarTower R γ α] [SlashAction β G α γ]
    (k : β) (g : G) (a : α) (r : R) : (r • a) ∣[k;γ] g = r • a ∣[k;γ] g := by
  

Proof state:
R : Type u_1
β : Type u_2
G : Type u_3
α : Type u_4
γ : Type u_5
inst✝⁷ : Group G
inst✝⁶ : AddGroup α
inst✝⁵ : Monoid γ
inst✝⁴ : MulAction γ α
inst✝³ : SMul R γ
inst✝² : SMul R α
inst✝¹ : IsScalarTower R γ α
inst✝ : SlashAction β G α γ
k : β
g : G
a : α
r : R
⊢ (r • a) ∣[k;γ] g = r • a ∣[k;γ] g

Next tactic:
rw [← smul_one_smul γ r a, SlashAction.smul_slash, smul_one_smul]
/-- Slash_action induced by a monoid homomorphism.-/
def monoidHomSlashAction {β G H α γ : Type*} [Group G] [AddMonoid α] [SMul γ α] [Group H]
    [SlashAction β G α γ] (h : H →* G) : SlashAction β H α γ where
  map k g := SlashAction.map γ k (h g)
  zero_slash k g := SlashAction.zero_slash k (h g)
  slash_one k a := by 

Proof state:
β : Type u_1
G : Type u_2
H : Type u_3
α : Type u_4
γ : Type u_5
inst✝⁴ : Group G
inst✝³ : AddMonoid α
inst✝² : SMul γ α
inst✝¹ : Group H
inst✝ : SlashAction β G α γ
h : H →* G
k : β
a : α
⊢ (fun k g => SlashAction.map γ k (h g)) k 1 a = a

Next tactic:
simp only [map_one, SlashAction.slash_one]
/-- Slash_action induced by a monoid homomorphism.-/
def monoidHomSlashAction {β G H α γ : Type*} [Group G] [AddMonoid α] [SMul γ α] [Group H]
    [SlashAction β G α γ] (h : H →* G) : SlashAction β H α γ where
  map k g := SlashAction.map γ k (h g)
  zero_slash k g := SlashAction.zero_slash k (h g)
  slash_one k a := by simp only [map_one, SlashAction.slash_one]
  slash_mul k g gg a := by 

Proof state:
β : Type u_1
G : Type u_2
H : Type u_3
α : Type u_4
γ : Type u_5
inst✝⁴ : Group G
inst✝³ : AddMonoid α
inst✝² : SMul γ α
inst✝¹ : Group H
inst✝ : SlashAction β G α γ
h : H →* G
k : β
g gg : H
a : α
⊢ (fun k g => SlashAction.map γ k (h g)) k (g * gg) a =
    (fun k g => SlashAction.map γ k (h g)) k gg ((fun k g => SlashAction.map γ k (h g)) k g a)

Next tactic:
simp only [map_mul, SlashAction.slash_mul]
private theorem slash_mul (k : ℤ) (A B : GL(2, ℝ)⁺) (f : ℍ → ℂ) :
    f ∣[k](A * B) = (f ∣[k]A) ∣[k]B := by
  

Proof state:
Γ : Subgroup SL(2, ℤ)
k✝ : ℤ
f✝ : ℍ → ℂ
k : ℤ
A B : ↥GL(2, ℝ)⁺
f : ℍ → ℂ
⊢ f ∣[k](A * B) = (f ∣[k]A) ∣[k]B

Next tactic:
ext1 x
private theorem slash_mul (k : ℤ) (A B : GL(2, ℝ)⁺) (f : ℍ → ℂ) :
    f ∣[k](A * B) = (f ∣[k]A) ∣[k]B := by
  ext1 x
  

Proof state:
case h
Γ : Subgroup SL(2, ℤ)
k✝ : ℤ
f✝ : ℍ → ℂ
k : ℤ
A B : ↥GL(2, ℝ)⁺
f : ℍ → ℂ
x : ℍ
⊢ (f ∣[k](A * B)) x = ((f ∣[k]A) ∣[k]B) x

Next tactic:
simp_rw [slash, UpperHalfPlane.denom_cocycle A B x]
private theorem slash_mul (k : ℤ) (A B : GL(2, ℝ)⁺) (f : ℍ → ℂ) :
    f ∣[k](A * B) = (f ∣[k]A) ∣[k]B := by
  ext1 x
  simp_rw [slash, UpperHalfPlane.denom_cocycle A B x]
  

Proof state:
case h
Γ : Subgroup SL(2, ℤ)
k✝ : ℤ
f✝ : ℍ → ℂ
k : ℤ
A B : ↥GL(2, ℝ)⁺
f : ℍ → ℂ
x : ℍ
⊢ f ((A * B) • x) * ↑(Matrix.det ↑↑(A * B)) ^ (k - 1) * (denom A (smulAux B x) * denom B x) ^ (-k) =
    f (A • B • x) * ↑(Matrix.det ↑↑A) ^ (k - 1) * denom A (B • x) ^ (-k) * ↑(Matrix.det ↑↑B) ^ (k - 1) *
      denom B x ^ (-k)

Next tactic:
have e3 : (A * B) • x = A • B • x := by convert UpperHalfPlane.mul_smul' A B x
private theorem slash_mul (k : ℤ) (A B : GL(2, ℝ)⁺) (f : ℍ → ℂ) :
    f ∣[k](A * B) = (f ∣[k]A) ∣[k]B := by
  ext1 x
  simp_rw [slash, UpperHalfPlane.denom_cocycle A B x]
  have e3 : (A * B) • x = A • B • x := by 

Proof state:
Γ : Subgroup SL(2, ℤ)
k✝ : ℤ
f✝ : ℍ → ℂ
k : ℤ
A B : ↥GL(2, ℝ)⁺
f : ℍ → ℂ
x : ℍ
⊢ (A * B) • x = A • B • x

Next tactic:
convert UpperHalfPlane.mul_smul' A B x