l3lab/ntp-mathlib huggingface dataset:
@[to_additive (attr := ext)]
theorem Monoid.ext {M : Type u} ⦃m₁ m₂ : Monoid M⦄
    (h_mul : (letI := m₁; HMul.hMul : M → M → M) = (letI := m₂; HMul.hMul : M → M → M)) :
    m₁ = m₂ := by
  have : m₁.toMulOneClass = m₂.toMulOneClass := MulOneClass.ext h_mul
  have h₁ : m₁.one = m₂.one := congr_arg (·.one) (this)
  let f : @MonoidHom M M m₁.toMulOneClass m₂.toMulOneClass :=
    @MonoidHom.mk _ _ (_) _ (@OneHom.mk _ _ (_) _ id h₁)
      (fun x y => congr_fun (congr_fun h_mul x) y)
  have : m₁.npow = m₂.npow := by
    ext n x
    exact @MonoidHom.map_pow M M m₁ m₂ f x n
  rcases m₁ with @⟨@⟨⟨_⟩⟩, ⟨_⟩⟩
  rcases m₂ with @⟨@⟨⟨_⟩⟩, ⟨_⟩⟩
  

Proof state:
case mk.mk.mk.mk.mk.mk.mk.mk
M : Type u
npow✝¹ : ℕ → M → M
mul✝¹ : M → M → M
mul_assoc✝¹ : ∀ (a b c : M), a * b * c = a * (b * c)
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
one✝¹ : M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow✝ : ℕ → M → M
mul✝ : M → M → M
mul_assoc✝ : ∀ (a b c : M), a * b * c = a * (b * c)
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
one✝ : M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
h_mul : HMul.hMul = HMul.hMul
this✝ : toMulOneClass = toMulOneClass
h₁ : One.one = One.one
f : M →* M := { toOneHom := { toFun := id, map_one' := h₁ }, map_mul' := (_ : ∀ (x y : M), x * y = x * y) }
this : Monoid.npow = Monoid.npow
⊢ mk one_mul✝¹ mul_one✝¹ npow✝¹ = mk one_mul✝ mul_one✝ npow✝

Next tactic:
congr
@[to_additive]
theorem CommMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@CommMonoid.toMonoid M) := by
  

Proof state:
M : Type u
⊢ Function.Injective (@toMonoid M)

Next tactic:
rintro ⟨⟩ ⟨⟩ h
@[to_additive]
theorem CommMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@CommMonoid.toMonoid M) := by
  rintro ⟨⟩ ⟨⟩ h
  

Proof state:
case mk.mk
M : Type u
toMonoid✝¹ : Monoid M
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toMonoid✝ : Monoid M
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toMonoid = toMonoid
⊢ mk mul_comm✝¹ = mk mul_comm✝

Next tactic:
congr
@[to_additive]
theorem LeftCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@LeftCancelMonoid.toMonoid M) := by
  

Proof state:
M : Type u
⊢ Function.Injective (@toMonoid M)

Next tactic:
rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
@[to_additive]
theorem LeftCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@LeftCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  

Proof state:
case mk.mk.mk.mk
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ mk one_mul✝¹ mul_one✝¹ npow✝¹ = mk one_mul✝ mul_one✝ npow✝

Next tactic:
congr
@[to_additive]
theorem LeftCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@LeftCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.e_toLeftCancelSemigroup.e_toSemigroup
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ toSemigroup✝¹ = toSemigroup✝

Next tactic:
injection h
@[to_additive]
theorem LeftCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@LeftCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.e_toOne
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ toOne✝¹ = toOne✝

Next tactic:
injection h
@[to_additive]
theorem LeftCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@LeftCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.e_npow
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ npow✝¹ = npow✝

Next tactic:
injection h
@[to_additive]
theorem RightCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@RightCancelMonoid.toMonoid M) := by
  

Proof state:
M : Type u
⊢ Function.Injective (@toMonoid M)

Next tactic:
rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
@[to_additive]
theorem RightCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@RightCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  

Proof state:
case mk.mk.mk.mk
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_right_cancel✝¹ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_right_cancel✝ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ mk one_mul✝¹ mul_one✝¹ npow✝¹ = mk one_mul✝ mul_one✝ npow✝

Next tactic:
congr
@[to_additive]
theorem RightCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@RightCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.e_toRightCancelSemigroup.e_toSemigroup
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_right_cancel✝¹ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_right_cancel✝ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ toSemigroup✝¹ = toSemigroup✝

Next tactic:
injection h
@[to_additive]
theorem RightCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@RightCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.e_toOne
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_right_cancel✝¹ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_right_cancel✝ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ toOne✝¹ = toOne✝

Next tactic:
injection h
@[to_additive]
theorem RightCancelMonoid.toMonoid_injective {M : Type u} :
    Function.Injective (@RightCancelMonoid.toMonoid M) := by
  rintro @⟨@⟨⟩⟩ @⟨@⟨⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.e_npow
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_right_cancel✝¹ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_right_cancel✝ : ∀ (a b c : M), a * b = c * b → a = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
h : toMonoid = toMonoid
⊢ npow✝¹ = npow✝

Next tactic:
injection h
@[to_additive]
theorem CancelMonoid.toLeftCancelMonoid_injective {M : Type u} :
    Function.Injective (@CancelMonoid.toLeftCancelMonoid M) := by
  

Proof state:
M : Type u
⊢ Function.Injective (@toLeftCancelMonoid M)

Next tactic:
rintro ⟨⟩ ⟨⟩ h
@[to_additive]
theorem CancelMonoid.toLeftCancelMonoid_injective {M : Type u} :
    Function.Injective (@CancelMonoid.toLeftCancelMonoid M) := by
  rintro ⟨⟩ ⟨⟩ h
  

Proof state:
case mk.mk
M : Type u
toLeftCancelMonoid✝¹ : LeftCancelMonoid M
mul_right_cancel✝¹ : ∀ (a b c : M), a * b = c * b → a = c
toLeftCancelMonoid✝ : LeftCancelMonoid M
mul_right_cancel✝ : ∀ (a b c : M), a * b = c * b → a = c
h : toLeftCancelMonoid = toLeftCancelMonoid
⊢ mk mul_right_cancel✝¹ = mk mul_right_cancel✝

Next tactic:
congr
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  

Proof state:
M : Type u
⊢ Function.Injective (@toCommMonoid M)

Next tactic:
rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  

Proof state:
case mk.mk.mk.mk.mk.mk
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toCommMonoid = toCommMonoid
⊢ mk mul_comm✝¹ = mk mul_comm✝

Next tactic:
congr
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_toLeftCancelSemigroup.e_toSemigroup
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toCommMonoid = toCommMonoid
⊢ toSemigroup✝¹ = toSemigroup✝

Next tactic:
{
    injection h with h'
    injection h' }
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> {
    

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_toLeftCancelSemigroup.e_toSemigroup
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toCommMonoid = toCommMonoid
⊢ toSemigroup✝¹ = toSemigroup✝

Next tactic:
injection h with h'
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> {
    injection h with h'
    

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_toLeftCancelSemigroup.e_toSemigroup
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h' :
  Monoid.mk (_ : ∀ (a : M), 1 * a = a) (_ : ∀ (a : M), a * 1 = a) LeftCancelMonoid.npow =
    Monoid.mk (_ : ∀ (a : M), 1 * a = a) (_ : ∀ (a : M), a * 1 = a) LeftCancelMonoid.npow
⊢ toSemigroup✝¹ = toSemigroup✝

Next tactic:
injection h'
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_toOne
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toCommMonoid = toCommMonoid
⊢ toOne✝¹ = toOne✝

Next tactic:
{
    injection h with h'
    injection h' }
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> {
    

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_toOne
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toCommMonoid = toCommMonoid
⊢ toOne✝¹ = toOne✝

Next tactic:
injection h with h'
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> {
    injection h with h'
    

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_toOne
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h' :
  Monoid.mk (_ : ∀ (a : M), 1 * a = a) (_ : ∀ (a : M), a * 1 = a) LeftCancelMonoid.npow =
    Monoid.mk (_ : ∀ (a : M), 1 * a = a) (_ : ∀ (a : M), a * 1 = a) LeftCancelMonoid.npow
⊢ toOne✝¹ = toOne✝

Next tactic:
injection h'
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> 

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_npow
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toCommMonoid = toCommMonoid
⊢ npow✝¹ = npow✝

Next tactic:
{
    injection h with h'
    injection h' }
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> {
    

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_npow
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h : toCommMonoid = toCommMonoid
⊢ npow✝¹ = npow✝

Next tactic:
injection h with h'
@[to_additive]
theorem CancelCommMonoid.toCommMonoid_injective {M : Type u} :
    Function.Injective (@CancelCommMonoid.toCommMonoid M) := by
  rintro @⟨@⟨@⟨⟩⟩⟩ @⟨@⟨@⟨⟩⟩⟩ h
  congr <;> {
    injection h with h'
    

Proof state:
case mk.mk.mk.mk.mk.mk.e_toLeftCancelMonoid.e_npow
M : Type u
toOne✝¹ : One M
npow✝¹ : ℕ → M → M
npow_zero✝¹ : ∀ (x : M), npow✝¹ 0 x = 1
toSemigroup✝¹ : Semigroup M
mul_left_cancel✝¹ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝¹ : ∀ (a : M), 1 * a = a
mul_one✝¹ : ∀ (a : M), a * 1 = a
npow_succ✝¹ : ∀ (n : ℕ) (x : M), npow✝¹ (n + 1) x = x * npow✝¹ n x
mul_comm✝¹ : ∀ (a b : M), a * b = b * a
toOne✝ : One M
npow✝ : ℕ → M → M
npow_zero✝ : ∀ (x : M), npow✝ 0 x = 1
toSemigroup✝ : Semigroup M
mul_left_cancel✝ : ∀ (a b c : M), a * b = a * c → b = c
one_mul✝ : ∀ (a : M), 1 * a = a
mul_one✝ : ∀ (a : M), a * 1 = a
npow_succ✝ : ∀ (n : ℕ) (x : M), npow✝ (n + 1) x = x * npow✝ n x
mul_comm✝ : ∀ (a b : M), a * b = b * a
h' :
  Monoid.mk (_ : ∀ (a : M), 1 * a = a) (_ : ∀ (a : M), a * 1 = a) LeftCancelMonoid.npow =
    Monoid.mk (_ : ∀ (a : M), 1 * a = a) (_ : ∀ (a : M), a * 1 = a) LeftCancelMonoid.npow
⊢ npow✝¹ = npow✝

Next tactic:
injection h'
@[to_additive (attr := ext)]
theorem DivInvMonoid.ext {M : Type*} ⦃m₁ m₂ : DivInvMonoid M⦄
    (h_mul : (letI := m₁; HMul.hMul : M → M → M) = (letI := m₂; HMul.hMul : M → M → M))
    (h_inv : (letI := m₁; Inv.inv : M → M) = (letI := m₂; Inv.inv : M → M)) : m₁ = m₂ := by
  

Proof state:
M : Type u_1
m₁ m₂ : DivInvMonoid M
h_mul : HMul.hMul = HMul.hMul
h_inv : Inv.inv = Inv.inv
⊢ m₁ = m₂

Next tactic:
have h_mon := Monoid.ext h_mul
@[to_additive (attr := ext)]
theorem DivInvMonoid.ext {M : Type*} ⦃m₁ m₂ : DivInvMonoid M⦄
    (h_mul : (letI := m₁; HMul.hMul : M → M → M) = (letI := m₂; HMul.hMul : M → M → M))
    (h_inv : (letI := m₁; Inv.inv : M → M) = (letI := m₂; Inv.inv : M → M)) : m₁ = m₂ := by
  have h_mon := Monoid.ext h_mul
  

Proof state:
M : Type u_1
m₁ m₂ : DivInvMonoid M
h_mul : HMul.hMul = HMul.hMul
h_inv : Inv.inv = Inv.inv
h_mon : toMonoid = toMonoid
⊢ m₁ = m₂

Next tactic:
have h₁ : m₁.one = m₂.one := congr_arg (·.one) h_mon
@[to_additive (attr := ext)]
theorem DivInvMonoid.ext {M : Type*} ⦃m₁ m₂ : DivInvMonoid M⦄
    (h_mul : (letI := m₁; HMul.hMul : M → M → M) = (letI := m₂; HMul.hMul : M → M → M))
    (h_inv : (letI := m₁; Inv.inv : M → M) = (letI := m₂; Inv.inv : M → M)) : m₁ = m₂ := by
  have h_mon := Monoid.ext h_mul
  have h₁ : m₁.one = m₂.one := congr_arg (·.one) h_mon
  

Proof state:
M : Type u_1
m₁ m₂ : DivInvMonoid M
h_mul : HMul.hMul = HMul.hMul
h_inv : Inv.inv = Inv.inv
h_mon : toMonoid = toMonoid
h₁ : One.one = One.one
⊢ m₁ = m₂

Next tactic:
let f : @MonoidHom M M m₁.toMulOneClass m₂.toMulOneClass :=
    @MonoidHom.mk _ _ (_) _ (@OneHom.mk _ _ (_) _ id h₁)
      (fun x y => congr_fun (congr_fun h_mul x) y)
@[to_additive (attr := ext)]
theorem DivInvMonoid.ext {M : Type*} ⦃m₁ m₂ : DivInvMonoid M⦄
    (h_mul : (letI := m₁; HMul.hMul : M → M → M) = (letI := m₂; HMul.hMul : M → M → M))
    (h_inv : (letI := m₁; Inv.inv : M → M) = (letI := m₂; Inv.inv : M → M)) : m₁ = m₂ := by
  have h_mon := Monoid.ext h_mul
  have h₁ : m₁.one = m₂.one := congr_arg (·.one) h_mon
  let f : @MonoidHom M M m₁.toMulOneClass m₂.toMulOneClass :=
    @MonoidHom.mk _ _ (_) _ (@OneHom.mk _ _ (_) _ id h₁)
      (fun x y => congr_fun (congr_fun h_mul x) y)
  

Proof state:
M : Type u_1
m₁ m₂ : DivInvMonoid M
h_mul : HMul.hMul = HMul.hMul
h_inv : Inv.inv = Inv.inv
h_mon : toMonoid = toMonoid
h₁ : One.one = One.one
f : M →* M := { toOneHom := { toFun := id, map_one' := h₁ }, map_mul' := (_ : ∀ (x y : M), x * y = x * y) }
⊢ m₁ = m₂

Next tactic:
have : m₁.npow = m₂.npow := congr_arg (·.npow) h_mon