l3lab/ntp-mathlib huggingface dataset:
instance instSMul : SMul M (CentroidHom α) where
  smul n f :=
    { (n • f : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change n • f (a * b) = a * n • f b
        rw [map_mul_left f, ← mul_smul_comm]
      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✝¹² : 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 α α
n : M
f : CentroidHom α
src✝ : α →+ α := n • ↑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 n • f (a * b) = n • f a * b
instance instSMul : SMul M (CentroidHom α) where
  smul n f :=
    { (n • f : α →+ α) with
      map_mul_left' := fun a b ↦ by
        change n • f (a * b) = a * n • f b
        rw [map_mul_left f, ← mul_smul_comm]
      map_mul_right' := fun a b ↦ by
        change n • f (a * b) = n • 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✝¹² : 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 α α
n : M
f : CentroidHom α
src✝ : α →+ α := n • ↑f
a b : α
⊢ n • f (a * b) = n • f a * b

Next tactic:
rw [map_mul_right f, ← smul_mul_assoc]
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) 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✝¹² : 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 α α
f : CentroidHom α
n : ℕ
src✝ : AddMonoid.End α := toEnd f ^ n
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:
induction' n with n ih
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · 

Proof state:
case zero
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 α α
f : CentroidHom α
a b : α
src✝ : AddMonoid.End α := toEnd f ^ Nat.zero
⊢ 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:
exact rfl
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · 

Proof state:
case succ
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 α α
f : CentroidHom α
a b : α
n : ℕ
ih :
  let src := toEnd f ^ n;
  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
src✝ : AddMonoid.End α := toEnd f ^ Nat.succ n
⊢ 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:
simp
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          

Proof state:
case succ
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 α α
f : CentroidHom α
a b : α
n : ℕ
ih :
  let src := toEnd f ^ n;
  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
src✝ : AddMonoid.End α := toEnd f ^ Nat.succ n
⊢ (toEnd f ^ Nat.succ n) (a * b) = a * (toEnd f ^ Nat.succ n) b

Next tactic:
rw [pow_succ]
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          rw [pow_succ]
          

Proof state:
case succ
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 α α
f : CentroidHom α
a b : α
n : ℕ
ih :
  let src := toEnd f ^ n;
  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
src✝ : AddMonoid.End α := toEnd f ^ Nat.succ n
⊢ (toEnd f * toEnd f ^ n) (a * b) = a * (toEnd f * toEnd f ^ n) b

Next tactic:
exact (congr_arg f.toEnd ih).trans (f.map_mul_left' _ _)
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          rw [pow_succ]
          exact (congr_arg f.toEnd ih).trans (f.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✝¹² : 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 α α
f : CentroidHom α
n : ℕ
src✝ : AddMonoid.End α := toEnd f ^ n
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:
induction' n with n ih
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          rw [pow_succ]
          exact (congr_arg f.toEnd ih).trans (f.map_mul_left' _ _)
      map_mul_right' := fun a b ↦ by
        induction' n with n ih
        · 

Proof state:
case zero
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 α α
f : CentroidHom α
a b : α
src✝ : AddMonoid.End α := toEnd f ^ Nat.zero
⊢ 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:
exact rfl
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          rw [pow_succ]
          exact (congr_arg f.toEnd ih).trans (f.map_mul_left' _ _)
      map_mul_right' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · 

Proof state:
case succ
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 α α
f : CentroidHom α
a b : α
n : ℕ
ih :
  let src := toEnd f ^ n;
  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
src✝ : AddMonoid.End α := toEnd f ^ Nat.succ n
⊢ 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:
simp
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          rw [pow_succ]
          exact (congr_arg f.toEnd ih).trans (f.map_mul_left' _ _)
      map_mul_right' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          

Proof state:
case succ
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 α α
f : CentroidHom α
a b : α
n : ℕ
ih :
  let src := toEnd f ^ n;
  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
src✝ : AddMonoid.End α := toEnd f ^ Nat.succ n
⊢ (toEnd f ^ Nat.succ n) (a * b) = (toEnd f ^ Nat.succ n) a * b

Next tactic:
rw [pow_succ]
instance hasNPowNat : Pow (CentroidHom α) ℕ :=
  ⟨fun f n ↦
    { (f.toEnd ^ n : AddMonoid.End α) with
      map_mul_left' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          rw [pow_succ]
          exact (congr_arg f.toEnd ih).trans (f.map_mul_left' _ _)
      map_mul_right' := fun a b ↦ by
        induction' n with n ih
        · exact rfl
        · simp
          rw [pow_succ]
          

Proof state:
case succ
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 α α
f : CentroidHom α
a b : α
n : ℕ
ih :
  let src := toEnd f ^ n;
  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
src✝ : AddMonoid.End α := toEnd f ^ Nat.succ n
⊢ (toEnd f * toEnd f ^ n) (a * b) = (toEnd f * toEnd f ^ n) a * b

Next tactic:
exact (congr_arg f.toEnd ih).trans (f.map_mul_right' _ _)
theorem comp_mul_comm (T S : CentroidHom α) (a b : α) : (T ∘ S) (a * b) = (S ∘ T) (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✝¹² : 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 α α
T S : CentroidHom α
a b : α
⊢ (⇑T ∘ ⇑S) (a * b) = (⇑S ∘ ⇑T) (a * b)

Next tactic:
simp only [Function.comp_apply]
theorem comp_mul_comm (T S : CentroidHom α) (a b : α) : (T ∘ S) (a * b) = (S ∘ T) (a * b) := by
  simp only [Function.comp_apply]
  

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 α α
T S : CentroidHom α
a b : α
⊢ T (S (a * b)) = S (T (a * b))

Next tactic:
rw [map_mul_right, map_mul_left, ← map_mul_right, ← map_mul_left]
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := 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 α α
⊢ RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range ⇑L ∪ Set.range ⇑R)

Next tactic:
ext T
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := by
  ext T
  

Proof state:
case h
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 α α
T : AddMonoid.End α
⊢ T ∈ RingHom.rangeS (toEndRingHom α) ↔ T ∈ Subsemiring.centralizer (Set.range ⇑L ∪ Set.range ⇑R)

Next tactic:
refine ⟨?_, fun h ↦ ?_⟩
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := by
  ext T
  refine ⟨?_, fun h ↦ ?_⟩
  · 

Proof state:
case h.refine_1
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 α α
T : AddMonoid.End α
⊢ T ∈ RingHom.rangeS (toEndRingHom α) → T ∈ Subsemiring.centralizer (Set.range ⇑L ∪ Set.range ⇑R)

Next tactic:
rintro ⟨f, rfl⟩ S (⟨a, rfl⟩ | ⟨b, rfl⟩)
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := by
  ext T
  refine ⟨?_, fun h ↦ ?_⟩
  · rintro ⟨f, rfl⟩ S (⟨a, rfl⟩ | ⟨b, rfl⟩)
    · 

Proof state:
case h.refine_1.intro.inl.intro
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 α α
f : CentroidHom α
a : α
⊢ L a * (toEndRingHom α) f = (toEndRingHom α) f * L a

Next tactic:
exact AddMonoidHom.ext fun b ↦ (map_mul_left f a b).symm
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := by
  ext T
  refine ⟨?_, fun h ↦ ?_⟩
  · rintro ⟨f, rfl⟩ S (⟨a, rfl⟩ | ⟨b, rfl⟩)
    · exact AddMonoidHom.ext fun b ↦ (map_mul_left f a b).symm
    · 

Proof state:
case h.refine_1.intro.inr.intro
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 α α
f : CentroidHom α
b : α
⊢ R b * (toEndRingHom α) f = (toEndRingHom α) f * R b

Next tactic:
exact AddMonoidHom.ext fun a ↦ (map_mul_right f a b).symm
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := by
  ext T
  refine ⟨?_, fun h ↦ ?_⟩
  · rintro ⟨f, rfl⟩ S (⟨a, rfl⟩ | ⟨b, rfl⟩)
    · exact AddMonoidHom.ext fun b ↦ (map_mul_left f a b).symm
    · exact AddMonoidHom.ext fun a ↦ (map_mul_right f a b).symm
  · 

Proof state:
case h.refine_2
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 α α
T : AddMonoid.End α
h : T ∈ Subsemiring.centralizer (Set.range ⇑L ∪ Set.range ⇑R)
⊢ T ∈ RingHom.rangeS (toEndRingHom α)

Next tactic:
rw [Subsemiring.mem_centralizer_iff] at h
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := by
  ext T
  refine ⟨?_, fun h ↦ ?_⟩
  · rintro ⟨f, rfl⟩ S (⟨a, rfl⟩ | ⟨b, rfl⟩)
    · exact AddMonoidHom.ext fun b ↦ (map_mul_left f a b).symm
    · exact AddMonoidHom.ext fun a ↦ (map_mul_right f a b).symm
  · rw [Subsemiring.mem_centralizer_iff] at h
    

Proof state:
case h.refine_2
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 α α
T : AddMonoid.End α
h : ∀ g ∈ Set.range ⇑L ∪ Set.range ⇑R, g * T = T * g
⊢ T ∈ RingHom.rangeS (toEndRingHom α)

Next tactic:
refine ⟨⟨T, fun a b ↦ ?_, fun a b ↦ ?_⟩, rfl⟩
lemma centroid_eq_centralizer_mulLeftRight :
    RingHom.rangeS (toEndRingHom α) = Subsemiring.centralizer (Set.range L ∪ Set.range R) := by
  ext T
  refine ⟨?_, fun h ↦ ?_⟩
  · rintro ⟨f, rfl⟩ S (⟨a, rfl⟩ | ⟨b, rfl⟩)
    · exact AddMonoidHom.ext fun b ↦ (map_mul_left f a b).symm
    · exact AddMonoidHom.ext fun a ↦ (map_mul_right f a b).symm
  · rw [Subsemiring.mem_centralizer_iff] at h
    refine ⟨⟨T, fun a b ↦ ?_, fun a b ↦ ?_⟩, rfl⟩
    · 

Proof state:
case h.refine_2.refine_1
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 α α
T : AddMonoid.End α
h : ∀ g ∈ Set.range ⇑L ∪ Set.range ⇑R, g * T = T * g
a b : α
⊢ ZeroHom.toFun (↑T) (a * b) = a * ZeroHom.toFun (↑T) b

Next tactic:
exact congr($(h (L a) (.inl ⟨a, rfl⟩)) b).symm