l3lab/ntp-mathlib huggingface dataset:
theorem induction_on [AddMonoid G] {p : k[G] → Prop} (f : k[G])
    (hM : ∀ g, p (of k G (Multiplicative.ofAdd g)))
    (hadd : ∀ f g : k[G], p f → p g → p (f + g))
    (hsmul : ∀ (r : k) (f), p f → p (r • f)) : p f := by
  refine' Finsupp.induction_linear f _ (fun f g hf hg => hadd f g hf hg) fun g r => _
  · 

Proof state:
case refine'_1
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddMonoid G
p : k[G] → Prop
f : k[G]
hM : ∀ (g : G), p ((of k G) (Multiplicative.ofAdd g))
hadd : ∀ (f g : k[G]), p f → p g → p (f + g)
hsmul : ∀ (r : k) (f : k[G]), p f → p (r • f)
⊢ p 0

Next tactic:
simpa using hsmul 0 (of k G (Multiplicative.ofAdd 0)) (hM 0)
theorem induction_on [AddMonoid G] {p : k[G] → Prop} (f : k[G])
    (hM : ∀ g, p (of k G (Multiplicative.ofAdd g)))
    (hadd : ∀ f g : k[G], p f → p g → p (f + g))
    (hsmul : ∀ (r : k) (f), p f → p (r • f)) : p f := by
  refine' Finsupp.induction_linear f _ (fun f g hf hg => hadd f g hf hg) fun g r => _
  · simpa using hsmul 0 (of k G (Multiplicative.ofAdd 0)) (hM 0)
  · 

Proof state:
case refine'_2
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddMonoid G
p : k[G] → Prop
f : k[G]
hM : ∀ (g : G), p ((of k G) (Multiplicative.ofAdd g))
hadd : ∀ (f g : k[G]), p f → p g → p (f + g)
hsmul : ∀ (r : k) (f : k[G]), p f → p (r • f)
g : G
r : k
⊢ p fun₀ | g => r

Next tactic:
convert hsmul r (of k G (Multiplicative.ofAdd g)) (hM g)
theorem induction_on [AddMonoid G] {p : k[G] → Prop} (f : k[G])
    (hM : ∀ g, p (of k G (Multiplicative.ofAdd g)))
    (hadd : ∀ f g : k[G], p f → p g → p (f + g))
    (hsmul : ∀ (r : k) (f), p f → p (r • f)) : p f := by
  refine' Finsupp.induction_linear f _ (fun f g hf hg => hadd f g hf hg) fun g r => _
  · simpa using hsmul 0 (of k G (Multiplicative.ofAdd 0)) (hM 0)
  · convert hsmul r (of k G (Multiplicative.ofAdd g)) (hM g)
    -- Porting note: Was `simp only`.
    

Proof state:
case h.e'_1
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddMonoid G
p : k[G] → Prop
f : k[G]
hM : ∀ (g : G), p ((of k G) (Multiplicative.ofAdd g))
hadd : ∀ (f g : k[G]), p f → p g → p (f + g)
hsmul : ∀ (r : k) (f : k[G]), p f → p (r • f)
g : G
r : k
⊢ (fun₀ | g => r) = r • (of k G) (Multiplicative.ofAdd g)

Next tactic:
rw [of_apply, toAdd_ofAdd, smul_single', mul_one]
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ Equiv.toFun
      { toFun := equivMapDomain Multiplicative.ofAdd, invFun := src✝.invFun,
        left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
        right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
      (x * y) =
    Equiv.toFun
        { toFun := equivMapDomain Multiplicative.ofAdd, invFun := src✝.invFun,
          left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        x *
      Equiv.toFun
        { toFun := equivMapDomain Multiplicative.ofAdd, invFun := src✝.invFun,
          left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        y

Next tactic:
dsimp only []
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ equivMapDomain Multiplicative.ofAdd (x * y) =
    equivMapDomain Multiplicative.ofAdd x * equivMapDomain Multiplicative.ofAdd y

Next tactic:
repeat' rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ equivMapDomain Multiplicative.ofAdd (x * y) =
    equivMapDomain Multiplicative.ofAdd x * equivMapDomain Multiplicative.ofAdd y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ Finsupp.mapDomain (⇑Multiplicative.ofAdd) (x * y) =
    equivMapDomain Multiplicative.ofAdd x * equivMapDomain Multiplicative.ofAdd y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ Finsupp.mapDomain (⇑Multiplicative.ofAdd) (x * y) =
    Finsupp.mapDomain (⇑Multiplicative.ofAdd) x * equivMapDomain Multiplicative.ofAdd y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ Finsupp.mapDomain (⇑Multiplicative.ofAdd) (x * y) =
    Finsupp.mapDomain (⇑Multiplicative.ofAdd) x * Finsupp.mapDomain (⇑Multiplicative.ofAdd) y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' rw [equivMapDomain_eq_mapDomain (M := k)]
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ Finsupp.mapDomain (⇑Multiplicative.ofAdd) (x * y) =
    Finsupp.mapDomain (⇑Multiplicative.ofAdd) x * Finsupp.mapDomain (⇑Multiplicative.ofAdd) y

Next tactic:
dsimp [Multiplicative.ofAdd]
/-- The equivalence between `AddMonoidAlgebra` and `MonoidAlgebra` in terms of
`Multiplicative` -/
protected def AddMonoidAlgebra.toMultiplicative [Semiring k] [Add G] :
    AddMonoidAlgebra k G ≃+* MonoidAlgebra k (Multiplicative G) :=
  { Finsupp.domCongr
      Multiplicative.ofAdd with
    toFun := equivMapDomain Multiplicative.ofAdd
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' rw [equivMapDomain_eq_mapDomain (M := k)]
      dsimp [Multiplicative.ofAdd]
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Add G
src✝ : (G →₀ k) ≃+ (Multiplicative G →₀ k) := Finsupp.domCongr Multiplicative.ofAdd
x y : k[G]
⊢ Finsupp.mapDomain (fun x => x) (x * y) = Finsupp.mapDomain (fun x => x) x * Finsupp.mapDomain (fun x => x) y

Next tactic:
exact MonoidAlgebra.mapDomain_mul (α := Multiplicative G) (β := k)
        (MulHom.id (Multiplicative G)) x y
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ Equiv.toFun
      { toFun := equivMapDomain Additive.ofMul, invFun := src✝.invFun,
        left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
        right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
      (x * y) =
    Equiv.toFun
        { toFun := equivMapDomain Additive.ofMul, invFun := src✝.invFun,
          left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        x *
      Equiv.toFun
        { toFun := equivMapDomain Additive.ofMul, invFun := src✝.invFun,
          left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        y

Next tactic:
dsimp only []
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ equivMapDomain Additive.ofMul (x * y) = equivMapDomain Additive.ofMul x * equivMapDomain Additive.ofMul y

Next tactic:
repeat' rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ equivMapDomain Additive.ofMul (x * y) = equivMapDomain Additive.ofMul x * equivMapDomain Additive.ofMul y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ Finsupp.mapDomain (⇑Additive.ofMul) (x * y) = equivMapDomain Additive.ofMul x * equivMapDomain Additive.ofMul y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ Finsupp.mapDomain (⇑Additive.ofMul) (x * y) = Finsupp.mapDomain (⇑Additive.ofMul) x * equivMapDomain Additive.ofMul y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ Finsupp.mapDomain (⇑Additive.ofMul) (x * y) =
    Finsupp.mapDomain (⇑Additive.ofMul) x * Finsupp.mapDomain (⇑Additive.ofMul) y

Next tactic:
rw [equivMapDomain_eq_mapDomain (M := k)]
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' rw [equivMapDomain_eq_mapDomain (M := k)]
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ Finsupp.mapDomain (⇑Additive.ofMul) (x * y) =
    Finsupp.mapDomain (⇑Additive.ofMul) x * Finsupp.mapDomain (⇑Additive.ofMul) y

Next tactic:
dsimp [Additive.ofMul]
/-- The equivalence between `MonoidAlgebra` and `AddMonoidAlgebra` in terms of `Additive` -/
protected def MonoidAlgebra.toAdditive [Semiring k] [Mul G] :
    MonoidAlgebra k G ≃+* AddMonoidAlgebra k (Additive G) :=
  { Finsupp.domCongr Additive.ofMul with
    toFun := equivMapDomain Additive.ofMul
    map_mul' := fun x y => by
      -- Porting note: `dsimp` is required for beta reduction.
      dsimp only []
      repeat' rw [equivMapDomain_eq_mapDomain (M := k)]
      dsimp [Additive.ofMul]
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : Mul G
src✝ : (G →₀ k) ≃+ (Additive G →₀ k) := Finsupp.domCongr Additive.ofMul
x y : MonoidAlgebra k G
⊢ Finsupp.mapDomain (fun x => x) (x * y) = Finsupp.mapDomain (fun x => x) x * Finsupp.mapDomain (fun x => x) y

Next tactic:
convert MonoidAlgebra.mapDomain_mul (β := k) (MulHom.id G) x y
/-- `Finsupp.single 0` as a `RingHom` -/
@[simps]
def singleZeroRingHom [Semiring k] [AddMonoid G] : k →+* k[G] :=
  { Finsupp.singleAddHom 0 with
    map_one' := rfl
    -- Porting note: Was `rw`.
    map_mul' := fun x y => by 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddMonoid G
src✝ : k →+ G →₀ k := singleAddHom 0
x y : k
⊢ OneHom.toFun { toFun := src✝.toFun, map_one' := (_ : ZeroHom.toFun (↑src✝) 1 = ZeroHom.toFun (↑src✝) 1) } (x * y) =
    OneHom.toFun { toFun := src✝.toFun, map_one' := (_ : ZeroHom.toFun (↑src✝) 1 = ZeroHom.toFun (↑src✝) 1) } x *
      OneHom.toFun { toFun := src✝.toFun, map_one' := (_ : ZeroHom.toFun (↑src✝) 1 = ZeroHom.toFun (↑src✝) 1) } y

Next tactic:
simp only [singleAddHom, single_mul_single, zero_add]
/-- The opposite of an `R[I]` is ring equivalent to
the `AddMonoidAlgebra Rᵐᵒᵖ I` over the opposite ring, taking elements to their opposite. -/
@[simps! (config := { simpRhs := true }) apply symm_apply]
protected noncomputable def opRingEquiv [AddCommMonoid G] :
    k[G]ᵐᵒᵖ ≃+* kᵐᵒᵖ[G] :=
  { MulOpposite.opAddEquiv.symm.trans
      (Finsupp.mapRange.addEquiv (MulOpposite.opAddEquiv : k ≃+ kᵐᵒᵖ)) with
    map_mul' := by
      -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddCommMonoid G
src✝ : (G →₀ k)ᵐᵒᵖ ≃+ (G →₀ kᵐᵒᵖ) := AddEquiv.trans (AddEquiv.symm opAddEquiv) (mapRange.addEquiv opAddEquiv)
⊢ ∀ (x y : k[G]ᵐᵒᵖ), Equiv.toFun src✝.toEquiv (x * y) = Equiv.toFun src✝.toEquiv x * Equiv.toFun src✝.toEquiv y

Next tactic:
rw [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe]
/-- The opposite of an `R[I]` is ring equivalent to
the `AddMonoidAlgebra Rᵐᵒᵖ I` over the opposite ring, taking elements to their opposite. -/
@[simps! (config := { simpRhs := true }) apply symm_apply]
protected noncomputable def opRingEquiv [AddCommMonoid G] :
    k[G]ᵐᵒᵖ ≃+* kᵐᵒᵖ[G] :=
  { MulOpposite.opAddEquiv.symm.trans
      (Finsupp.mapRange.addEquiv (MulOpposite.opAddEquiv : k ≃+ kᵐᵒᵖ)) with
    map_mul' := by
      -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
      rw [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe]; 

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddCommMonoid G
src✝ : (G →₀ k)ᵐᵒᵖ ≃+ (G →₀ kᵐᵒᵖ) := AddEquiv.trans (AddEquiv.symm opAddEquiv) (mapRange.addEquiv opAddEquiv)
⊢ ∀ (x y : k[G]ᵐᵒᵖ), ↑src✝ (x * y) = ↑src✝ x * ↑src✝ y

Next tactic:
erw [AddEquiv.coe_toEquiv]
/-- The opposite of an `R[I]` is ring equivalent to
the `AddMonoidAlgebra Rᵐᵒᵖ I` over the opposite ring, taking elements to their opposite. -/
@[simps! (config := { simpRhs := true }) apply symm_apply]
protected noncomputable def opRingEquiv [AddCommMonoid G] :
    k[G]ᵐᵒᵖ ≃+* kᵐᵒᵖ[G] :=
  { MulOpposite.opAddEquiv.symm.trans
      (Finsupp.mapRange.addEquiv (MulOpposite.opAddEquiv : k ≃+ kᵐᵒᵖ)) with
    map_mul' := by
      -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
      rw [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe]; erw [AddEquiv.coe_toEquiv]
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddCommMonoid G
src✝ : (G →₀ k)ᵐᵒᵖ ≃+ (G →₀ kᵐᵒᵖ) := AddEquiv.trans (AddEquiv.symm opAddEquiv) (mapRange.addEquiv opAddEquiv)
⊢ ∀ (x y : k[G]ᵐᵒᵖ), src✝ (x * y) = src✝ x * src✝ y

Next tactic:
rw [← AddEquiv.coe_toAddMonoidHom]
/-- The opposite of an `R[I]` is ring equivalent to
the `AddMonoidAlgebra Rᵐᵒᵖ I` over the opposite ring, taking elements to their opposite. -/
@[simps! (config := { simpRhs := true }) apply symm_apply]
protected noncomputable def opRingEquiv [AddCommMonoid G] :
    k[G]ᵐᵒᵖ ≃+* kᵐᵒᵖ[G] :=
  { MulOpposite.opAddEquiv.symm.trans
      (Finsupp.mapRange.addEquiv (MulOpposite.opAddEquiv : k ≃+ kᵐᵒᵖ)) with
    map_mul' := by
      -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
      rw [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe]; erw [AddEquiv.coe_toEquiv]
      rw [← AddEquiv.coe_toAddMonoidHom]
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddCommMonoid G
src✝ : (G →₀ k)ᵐᵒᵖ ≃+ (G →₀ kᵐᵒᵖ) := AddEquiv.trans (AddEquiv.symm opAddEquiv) (mapRange.addEquiv opAddEquiv)
⊢ ∀ (x y : k[G]ᵐᵒᵖ),
    (AddEquiv.toAddMonoidHom src✝) (x * y) = (AddEquiv.toAddMonoidHom src✝) x * (AddEquiv.toAddMonoidHom src✝) y

Next tactic:
refine Iff.mpr (AddMonoidHom.map_mul_iff (R := k[G]ᵐᵒᵖ) (S := kᵐᵒᵖ[G]) _) ?_
/-- The opposite of an `R[I]` is ring equivalent to
the `AddMonoidAlgebra Rᵐᵒᵖ I` over the opposite ring, taking elements to their opposite. -/
@[simps! (config := { simpRhs := true }) apply symm_apply]
protected noncomputable def opRingEquiv [AddCommMonoid G] :
    k[G]ᵐᵒᵖ ≃+* kᵐᵒᵖ[G] :=
  { MulOpposite.opAddEquiv.symm.trans
      (Finsupp.mapRange.addEquiv (MulOpposite.opAddEquiv : k ≃+ kᵐᵒᵖ)) with
    map_mul' := by
      -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
      rw [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe]; erw [AddEquiv.coe_toEquiv]
      rw [← AddEquiv.coe_toAddMonoidHom]
      refine Iff.mpr (AddMonoidHom.map_mul_iff (R := k[G]ᵐᵒᵖ) (S := kᵐᵒᵖ[G]) _) ?_
      -- Porting note: Was `ext`.
      

Proof state:
k : Type u₁
G : Type u₂
H : Type u_1
R : Type u_2
inst✝¹ : Semiring k
inst✝ : AddCommMonoid G
src✝ : (G →₀ k)ᵐᵒᵖ ≃+ (G →₀ kᵐᵒᵖ) := AddEquiv.trans (AddEquiv.symm opAddEquiv) (mapRange.addEquiv opAddEquiv)
⊢ AddMonoidHom.compr₂ AddMonoidHom.mul (AddEquiv.toAddMonoidHom src✝) =
    AddMonoidHom.compl₂ (AddMonoidHom.comp AddMonoidHom.mul (AddEquiv.toAddMonoidHom src✝))
      (AddEquiv.toAddMonoidHom src✝)

Next tactic:
refine AddMonoidHom.mul_op_ext _ _ <| addHom_ext' fun i₁ => AddMonoidHom.ext fun r₁ =>
        AddMonoidHom.mul_op_ext _ _ <| addHom_ext' fun i₂ => AddMonoidHom.ext fun r₂ => ?_