l3lab/ntp-mathlib huggingface dataset:
/-- The convex hull of an affine basis is the intersection of the half-spaces defined by the
corresponding barycentric coordinates. -/
theorem AffineBasis.convexHull_eq_nonneg_coord {ι : Type*} (b : AffineBasis ι R E) :
    convexHull R (range b) = { x | ∀ i, 0 ≤ b.coord i x } := by
  rw [convexHull_range_eq_exists_affineCombination]
  ext x
  refine' ⟨_, fun hx => _⟩
  · rintro ⟨s, w, hw₀, hw₁, rfl⟩ i
    by_cases hi : i ∈ s
    · rw [b.coord_apply_combination_of_mem hi hw₁]
      exact hw₀ i hi
    · rw [b.coord_apply_combination_of_not_mem hi hw₁]
  · have hx' : x ∈ affineSpan R (range b) := by
      rw [b.tot]
      exact AffineSubspace.mem_top R E x
    

Proof state:
case h.refine'_2
R : Type u_1
R' : Type u_2
E : Type u_3
F : Type u_4
ι✝ : Type u_5
ι' : Type u_6
α : Type u_7
inst✝⁹ : LinearOrderedField R
inst✝⁸ : LinearOrderedField R'
inst✝⁷ : AddCommGroup E
inst✝⁶ : AddCommGroup F
inst✝⁵ : LinearOrderedAddCommGroup α
inst✝⁴ : Module R E
inst✝³ : Module R F
inst✝² : Module R α
inst✝¹ : OrderedSMul R α
s : Set E
i j : ι✝
c : R
t : Finset ι✝
w : ι✝ → R
z : ι✝ → E
inst✝ : Fintype ι✝
f : ι✝ → R
ι : Type u_8
b : AffineBasis ι R E
x : E
hx : x ∈ {x | ∀ (i : ι), 0 ≤ (coord b i) x}
hx' : x ∈ affineSpan R (Set.range ⇑b)
⊢ x ∈ {x | ∃ s w, (∀ i ∈ s, 0 ≤ w i) ∧ Finset.sum s w = 1 ∧ (affineCombination R s ⇑b) w = x}

Next tactic:
obtain ⟨s, w, hw₁, rfl⟩ := (mem_affineSpan_iff_eq_affineCombination R E).mp hx'
/-- The convex hull of an affine basis is the intersection of the half-spaces defined by the
corresponding barycentric coordinates. -/
theorem AffineBasis.convexHull_eq_nonneg_coord {ι : Type*} (b : AffineBasis ι R E) :
    convexHull R (range b) = { x | ∀ i, 0 ≤ b.coord i x } := by
  rw [convexHull_range_eq_exists_affineCombination]
  ext x
  refine' ⟨_, fun hx => _⟩
  · rintro ⟨s, w, hw₀, hw₁, rfl⟩ i
    by_cases hi : i ∈ s
    · rw [b.coord_apply_combination_of_mem hi hw₁]
      exact hw₀ i hi
    · rw [b.coord_apply_combination_of_not_mem hi hw₁]
  · have hx' : x ∈ affineSpan R (range b) := by
      rw [b.tot]
      exact AffineSubspace.mem_top R E x
    obtain ⟨s, w, hw₁, rfl⟩ := (mem_affineSpan_iff_eq_affineCombination R E).mp hx'
    

Proof state:
case h.refine'_2.intro.intro.intro
R : Type u_1
R' : Type u_2
E : Type u_3
F : Type u_4
ι✝ : Type u_5
ι' : Type u_6
α : Type u_7
inst✝⁹ : LinearOrderedField R
inst✝⁸ : LinearOrderedField R'
inst✝⁷ : AddCommGroup E
inst✝⁶ : AddCommGroup F
inst✝⁵ : LinearOrderedAddCommGroup α
inst✝⁴ : Module R E
inst✝³ : Module R F
inst✝² : Module R α
inst✝¹ : OrderedSMul R α
s✝ : Set E
i j : ι✝
c : R
t : Finset ι✝
w✝ : ι✝ → R
z : ι✝ → E
inst✝ : Fintype ι✝
f : ι✝ → R
ι : Type u_8
b : AffineBasis ι R E
s : Finset ι
w : ι → R
hw₁ : ∑ i in s, w i = 1
hx : (affineCombination R s ⇑b) w ∈ {x | ∀ (i : ι), 0 ≤ (coord b i) x}
hx' : (affineCombination R s ⇑b) w ∈ affineSpan R (Set.range ⇑b)
⊢ (affineCombination R s ⇑b) w ∈ {x | ∃ s w, (∀ i ∈ s, 0 ≤ w i) ∧ Finset.sum s w = 1 ∧ (affineCombination R s ⇑b) w = x}

Next tactic:
refine' ⟨s, w, _, hw₁, rfl⟩
/-- The convex hull of an affine basis is the intersection of the half-spaces defined by the
corresponding barycentric coordinates. -/
theorem AffineBasis.convexHull_eq_nonneg_coord {ι : Type*} (b : AffineBasis ι R E) :
    convexHull R (range b) = { x | ∀ i, 0 ≤ b.coord i x } := by
  rw [convexHull_range_eq_exists_affineCombination]
  ext x
  refine' ⟨_, fun hx => _⟩
  · rintro ⟨s, w, hw₀, hw₁, rfl⟩ i
    by_cases hi : i ∈ s
    · rw [b.coord_apply_combination_of_mem hi hw₁]
      exact hw₀ i hi
    · rw [b.coord_apply_combination_of_not_mem hi hw₁]
  · have hx' : x ∈ affineSpan R (range b) := by
      rw [b.tot]
      exact AffineSubspace.mem_top R E x
    obtain ⟨s, w, hw₁, rfl⟩ := (mem_affineSpan_iff_eq_affineCombination R E).mp hx'
    refine' ⟨s, w, _, hw₁, rfl⟩
    

Proof state:
case h.refine'_2.intro.intro.intro
R : Type u_1
R' : Type u_2
E : Type u_3
F : Type u_4
ι✝ : Type u_5
ι' : Type u_6
α : Type u_7
inst✝⁹ : LinearOrderedField R
inst✝⁸ : LinearOrderedField R'
inst✝⁷ : AddCommGroup E
inst✝⁶ : AddCommGroup F
inst✝⁵ : LinearOrderedAddCommGroup α
inst✝⁴ : Module R E
inst✝³ : Module R F
inst✝² : Module R α
inst✝¹ : OrderedSMul R α
s✝ : Set E
i j : ι✝
c : R
t : Finset ι✝
w✝ : ι✝ → R
z : ι✝ → E
inst✝ : Fintype ι✝
f : ι✝ → R
ι : Type u_8
b : AffineBasis ι R E
s : Finset ι
w : ι → R
hw₁ : ∑ i in s, w i = 1
hx : (affineCombination R s ⇑b) w ∈ {x | ∀ (i : ι), 0 ≤ (coord b i) x}
hx' : (affineCombination R s ⇑b) w ∈ affineSpan R (Set.range ⇑b)
⊢ ∀ i ∈ s, 0 ≤ w i

Next tactic:
intro i hi
/-- The convex hull of an affine basis is the intersection of the half-spaces defined by the
corresponding barycentric coordinates. -/
theorem AffineBasis.convexHull_eq_nonneg_coord {ι : Type*} (b : AffineBasis ι R E) :
    convexHull R (range b) = { x | ∀ i, 0 ≤ b.coord i x } := by
  rw [convexHull_range_eq_exists_affineCombination]
  ext x
  refine' ⟨_, fun hx => _⟩
  · rintro ⟨s, w, hw₀, hw₁, rfl⟩ i
    by_cases hi : i ∈ s
    · rw [b.coord_apply_combination_of_mem hi hw₁]
      exact hw₀ i hi
    · rw [b.coord_apply_combination_of_not_mem hi hw₁]
  · have hx' : x ∈ affineSpan R (range b) := by
      rw [b.tot]
      exact AffineSubspace.mem_top R E x
    obtain ⟨s, w, hw₁, rfl⟩ := (mem_affineSpan_iff_eq_affineCombination R E).mp hx'
    refine' ⟨s, w, _, hw₁, rfl⟩
    intro i hi
    

Proof state:
case h.refine'_2.intro.intro.intro
R : Type u_1
R' : Type u_2
E : Type u_3
F : Type u_4
ι✝ : Type u_5
ι' : Type u_6
α : Type u_7
inst✝⁹ : LinearOrderedField R
inst✝⁸ : LinearOrderedField R'
inst✝⁷ : AddCommGroup E
inst✝⁶ : AddCommGroup F
inst✝⁵ : LinearOrderedAddCommGroup α
inst✝⁴ : Module R E
inst✝³ : Module R F
inst✝² : Module R α
inst✝¹ : OrderedSMul R α
s✝ : Set E
i✝ j : ι✝
c : R
t : Finset ι✝
w✝ : ι✝ → R
z : ι✝ → E
inst✝ : Fintype ι✝
f : ι✝ → R
ι : Type u_8
b : AffineBasis ι R E
s : Finset ι
w : ι → R
hw₁ : ∑ i in s, w i = 1
hx : (affineCombination R s ⇑b) w ∈ {x | ∀ (i : ι), 0 ≤ (coord b i) x}
hx' : (affineCombination R s ⇑b) w ∈ affineSpan R (Set.range ⇑b)
i : ι
hi : i ∈ s
⊢ 0 ≤ w i

Next tactic:
specialize hx i
/-- The convex hull of an affine basis is the intersection of the half-spaces defined by the
corresponding barycentric coordinates. -/
theorem AffineBasis.convexHull_eq_nonneg_coord {ι : Type*} (b : AffineBasis ι R E) :
    convexHull R (range b) = { x | ∀ i, 0 ≤ b.coord i x } := by
  rw [convexHull_range_eq_exists_affineCombination]
  ext x
  refine' ⟨_, fun hx => _⟩
  · rintro ⟨s, w, hw₀, hw₁, rfl⟩ i
    by_cases hi : i ∈ s
    · rw [b.coord_apply_combination_of_mem hi hw₁]
      exact hw₀ i hi
    · rw [b.coord_apply_combination_of_not_mem hi hw₁]
  · have hx' : x ∈ affineSpan R (range b) := by
      rw [b.tot]
      exact AffineSubspace.mem_top R E x
    obtain ⟨s, w, hw₁, rfl⟩ := (mem_affineSpan_iff_eq_affineCombination R E).mp hx'
    refine' ⟨s, w, _, hw₁, rfl⟩
    intro i hi
    specialize hx i
    

Proof state:
case h.refine'_2.intro.intro.intro
R : Type u_1
R' : Type u_2
E : Type u_3
F : Type u_4
ι✝ : Type u_5
ι' : Type u_6
α : Type u_7
inst✝⁹ : LinearOrderedField R
inst✝⁸ : LinearOrderedField R'
inst✝⁷ : AddCommGroup E
inst✝⁶ : AddCommGroup F
inst✝⁵ : LinearOrderedAddCommGroup α
inst✝⁴ : Module R E
inst✝³ : Module R F
inst✝² : Module R α
inst✝¹ : OrderedSMul R α
s✝ : Set E
i✝ j : ι✝
c : R
t : Finset ι✝
w✝ : ι✝ → R
z : ι✝ → E
inst✝ : Fintype ι✝
f : ι✝ → R
ι : Type u_8
b : AffineBasis ι R E
s : Finset ι
w : ι → R
hw₁ : ∑ i in s, w i = 1
hx' : (affineCombination R s ⇑b) w ∈ affineSpan R (Set.range ⇑b)
i : ι
hi : i ∈ s
hx : 0 ≤ (coord b i) ((affineCombination R s ⇑b) w)
⊢ 0 ≤ w i

Next tactic:
rw [b.coord_apply_combination_of_mem hi hw₁] at hx
/-- The convex hull of an affine basis is the intersection of the half-spaces defined by the
corresponding barycentric coordinates. -/
theorem AffineBasis.convexHull_eq_nonneg_coord {ι : Type*} (b : AffineBasis ι R E) :
    convexHull R (range b) = { x | ∀ i, 0 ≤ b.coord i x } := by
  rw [convexHull_range_eq_exists_affineCombination]
  ext x
  refine' ⟨_, fun hx => _⟩
  · rintro ⟨s, w, hw₀, hw₁, rfl⟩ i
    by_cases hi : i ∈ s
    · rw [b.coord_apply_combination_of_mem hi hw₁]
      exact hw₀ i hi
    · rw [b.coord_apply_combination_of_not_mem hi hw₁]
  · have hx' : x ∈ affineSpan R (range b) := by
      rw [b.tot]
      exact AffineSubspace.mem_top R E x
    obtain ⟨s, w, hw₁, rfl⟩ := (mem_affineSpan_iff_eq_affineCombination R E).mp hx'
    refine' ⟨s, w, _, hw₁, rfl⟩
    intro i hi
    specialize hx i
    rw [b.coord_apply_combination_of_mem hi hw₁] at hx
    

Proof state:
case h.refine'_2.intro.intro.intro
R : Type u_1
R' : Type u_2
E : Type u_3
F : Type u_4
ι✝ : Type u_5
ι' : Type u_6
α : Type u_7
inst✝⁹ : LinearOrderedField R
inst✝⁸ : LinearOrderedField R'
inst✝⁷ : AddCommGroup E
inst✝⁶ : AddCommGroup F
inst✝⁵ : LinearOrderedAddCommGroup α
inst✝⁴ : Module R E
inst✝³ : Module R F
inst✝² : Module R α
inst✝¹ : OrderedSMul R α
s✝ : Set E
i✝ j : ι✝
c : R
t : Finset ι✝
w✝ : ι✝ → R
z : ι✝ → E
inst✝ : Fintype ι✝
f : ι✝ → R
ι : Type u_8
b : AffineBasis ι R E
s : Finset ι
w : ι → R
hw₁ : ∑ i in s, w i = 1
hx' : (affineCombination R s ⇑b) w ∈ affineSpan R (Set.range ⇑b)
i : ι
hi : i ∈ s
hx : 0 ≤ w i
⊢ 0 ≤ w i

Next tactic:
exact hx
/-- **Fundamental theorem of algebra**: every non constant complex polynomial
  has a root -/
theorem exists_root {f : ℂ[X]} (hf : 0 < degree f) : ∃ z : ℂ, IsRoot f z := by
  

Proof state:
f : ℂ[X]
hf : 0 < degree f
⊢ ∃ z, IsRoot f z

Next tactic:
by_contra! hf'
/-- **Fundamental theorem of algebra**: every non constant complex polynomial
  has a root -/
theorem exists_root {f : ℂ[X]} (hf : 0 < degree f) : ∃ z : ℂ, IsRoot f z := by
  by_contra! hf'
  /- Since `f` has no roots, `f⁻¹` is differentiable. And since `f` is a polynomial, it tends to
  infinity at infinity, thus `f⁻¹` tends to zero at infinity. By Liouville's theorem, `f⁻¹ = 0`. -/
  

Proof state:
f : ℂ[X]
hf : 0 < degree f
hf' : ∀ (z : ℂ), ¬IsRoot f z
⊢ False

Next tactic:
have (z : ℂ) : (f.eval z)⁻¹ = 0 :=
    (f.differentiable.inv hf').apply_eq_of_tendsto_cocompact z <|
      Metric.cobounded_eq_cocompact (α := ℂ) ▸ (Filter.tendsto_inv₀_cobounded.comp <| by
        simpa only [tendsto_norm_atTop_iff_cobounded]
          using f.tendsto_norm_atTop hf tendsto_norm_cobounded_atTop)
/-- **Fundamental theorem of algebra**: every non constant complex polynomial
  has a root -/
theorem exists_root {f : ℂ[X]} (hf : 0 < degree f) : ∃ z : ℂ, IsRoot f z := by
  by_contra! hf'
  /- Since `f` has no roots, `f⁻¹` is differentiable. And since `f` is a polynomial, it tends to
  infinity at infinity, thus `f⁻¹` tends to zero at infinity. By Liouville's theorem, `f⁻¹ = 0`. -/
  have (z : ℂ) : (f.eval z)⁻¹ = 0 :=
    (f.differentiable.inv hf').apply_eq_of_tendsto_cocompact z <|
      Metric.cobounded_eq_cocompact (α := ℂ) ▸ (Filter.tendsto_inv₀_cobounded.comp <| by
        

Proof state:
f : ℂ[X]
hf : 0 < degree f
hf' : ∀ (z : ℂ), ¬IsRoot f z
z : ℂ
⊢ Filter.Tendsto (fun x => eval x f) (cobounded ℂ) (cobounded ℂ)

Next tactic:
simpa only [tendsto_norm_atTop_iff_cobounded]
          using f.tendsto_norm_atTop hf tendsto_norm_cobounded_atTop
/-- **Fundamental theorem of algebra**: every non constant complex polynomial
  has a root -/
theorem exists_root {f : ℂ[X]} (hf : 0 < degree f) : ∃ z : ℂ, IsRoot f z := by
  by_contra! hf'
  /- Since `f` has no roots, `f⁻¹` is differentiable. And since `f` is a polynomial, it tends to
  infinity at infinity, thus `f⁻¹` tends to zero at infinity. By Liouville's theorem, `f⁻¹ = 0`. -/
  have (z : ℂ) : (f.eval z)⁻¹ = 0 :=
    (f.differentiable.inv hf').apply_eq_of_tendsto_cocompact z <|
      Metric.cobounded_eq_cocompact (α := ℂ) ▸ (Filter.tendsto_inv₀_cobounded.comp <| by
        simpa only [tendsto_norm_atTop_iff_cobounded]
          using f.tendsto_norm_atTop hf tendsto_norm_cobounded_atTop)
  -- Thus `f = 0`, contradicting the fact that `0 < degree f`.
  

Proof state:
f : ℂ[X]
hf : 0 < degree f
hf' : ∀ (z : ℂ), ¬IsRoot f z
this : ∀ (z : ℂ), (eval z f)⁻¹ = 0
⊢ False

Next tactic:
obtain rfl : f = C 0 := Polynomial.funext fun z ↦ inv_injective <| by simp [this]
/-- **Fundamental theorem of algebra**: every non constant complex polynomial
  has a root -/
theorem exists_root {f : ℂ[X]} (hf : 0 < degree f) : ∃ z : ℂ, IsRoot f z := by
  by_contra! hf'
  /- Since `f` has no roots, `f⁻¹` is differentiable. And since `f` is a polynomial, it tends to
  infinity at infinity, thus `f⁻¹` tends to zero at infinity. By Liouville's theorem, `f⁻¹ = 0`. -/
  have (z : ℂ) : (f.eval z)⁻¹ = 0 :=
    (f.differentiable.inv hf').apply_eq_of_tendsto_cocompact z <|
      Metric.cobounded_eq_cocompact (α := ℂ) ▸ (Filter.tendsto_inv₀_cobounded.comp <| by
        simpa only [tendsto_norm_atTop_iff_cobounded]
          using f.tendsto_norm_atTop hf tendsto_norm_cobounded_atTop)
  -- Thus `f = 0`, contradicting the fact that `0 < degree f`.
  obtain rfl : f = C 0 := Polynomial.funext fun z ↦ inv_injective <| by 

Proof state:
f : ℂ[X]
hf : 0 < degree f
hf' : ∀ (z : ℂ), ¬IsRoot f z
this : ∀ (z : ℂ), (eval z f)⁻¹ = 0
z : ℂ
⊢ (eval z f)⁻¹ = (eval z (C 0))⁻¹

Next tactic:
simp [this]
/-- **Fundamental theorem of algebra**: every non constant complex polynomial
  has a root -/
theorem exists_root {f : ℂ[X]} (hf : 0 < degree f) : ∃ z : ℂ, IsRoot f z := by
  by_contra! hf'
  /- Since `f` has no roots, `f⁻¹` is differentiable. And since `f` is a polynomial, it tends to
  infinity at infinity, thus `f⁻¹` tends to zero at infinity. By Liouville's theorem, `f⁻¹ = 0`. -/
  have (z : ℂ) : (f.eval z)⁻¹ = 0 :=
    (f.differentiable.inv hf').apply_eq_of_tendsto_cocompact z <|
      Metric.cobounded_eq_cocompact (α := ℂ) ▸ (Filter.tendsto_inv₀_cobounded.comp <| by
        simpa only [tendsto_norm_atTop_iff_cobounded]
          using f.tendsto_norm_atTop hf tendsto_norm_cobounded_atTop)
  -- Thus `f = 0`, contradicting the fact that `0 < degree f`.
  obtain rfl : f = C 0 := Polynomial.funext fun z ↦ inv_injective <| by simp [this]
  

Proof state:
hf : 0 < degree (C 0)
hf' : ∀ (z : ℂ), ¬IsRoot (C 0) z
this : ∀ (z : ℂ), (eval z (C 0))⁻¹ = 0
⊢ False

Next tactic:
simp at hf
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
⊢ ∀ (a b c : M →* N), a * b * c = a * (b * c)

Next tactic:
intros
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
a✝ b✝ c✝ : M →* N
⊢ a✝ * b✝ * c✝ = a✝ * (b✝ * c✝)

Next tactic:
ext
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; 

Proof state:
case h
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
a✝ b✝ c✝ : M →* N
x✝ : M
⊢ (a✝ * b✝ * c✝) x✝ = (a✝ * (b✝ * c✝)) x✝

Next tactic:
apply mul_assoc
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
⊢ ∀ (a : M →* N), 1 * a = a

Next tactic:
intros
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
a✝ : M →* N
⊢ 1 * a✝ = a✝

Next tactic:
ext
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; 

Proof state:
case h
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
a✝ : M →* N
x✝ : M
⊢ (1 * a✝) x✝ = a✝ x✝

Next tactic:
apply one_mul
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
⊢ ∀ (a : M →* N), a * 1 = a

Next tactic:
intros
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
a✝ : M →* N
⊢ a✝ * 1 = a✝

Next tactic:
ext
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; ext; 

Proof state:
case h
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
a✝ : M →* N
x✝ : M
⊢ (a✝ * 1) x✝ = a✝ x✝

Next tactic:
apply mul_one
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; ext; apply mul_one
  mul_comm := by intros; ext; apply mul_comm
  npow n f :=
    { toFun := fun x => f x ^ n, map_one' := by 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
n : ℕ
f : M →* N
⊢ (fun x => f x ^ n) 1 = 1

Next tactic:
simp
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; ext; apply mul_one
  mul_comm := by intros; ext; apply mul_comm
  npow n f :=
    { toFun := fun x => f x ^ n, map_one' := by simp, map_mul' := fun x y => by 

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
n : ℕ
f : M →* N
x y : M
⊢ OneHom.toFun { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) } (x * y) =
    OneHom.toFun { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) } x *
      OneHom.toFun { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) } y

Next tactic:
simp [mul_pow]
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; ext; apply mul_one
  mul_comm := by intros; ext; apply mul_comm
  npow n f :=
    { toFun := fun x => f x ^ n, map_one' := by simp, map_mul' := fun x y => by simp [mul_pow] }
  npow_zero f := by
    

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
f : M →* N
⊢ (fun n f =>
        { toOneHom := { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) },
          map_mul' := (_ : ∀ (x y : M), f (x * y) ^ n = f x ^ n * f y ^ n) })
      0 f =
    1

Next tactic:
ext x
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; ext; apply mul_one
  mul_comm := by intros; ext; apply mul_comm
  npow n f :=
    { toFun := fun x => f x ^ n, map_one' := by simp, map_mul' := fun x y => by simp [mul_pow] }
  npow_zero f := by
    ext x
    

Proof state:
case h
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
f : M →* N
x : M
⊢ ((fun n f =>
          { toOneHom := { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) },
            map_mul' := (_ : ∀ (x y : M), f (x * y) ^ n = f x ^ n * f y ^ n) })
        0 f)
      x =
    1 x

Next tactic:
simp
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; ext; apply mul_one
  mul_comm := by intros; ext; apply mul_comm
  npow n f :=
    { toFun := fun x => f x ^ n, map_one' := by simp, map_mul' := fun x y => by simp [mul_pow] }
  npow_zero f := by
    ext x
    simp
  npow_succ n f := by
    

Proof state:
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
n : ℕ
f : M →* N
⊢ (fun n f =>
        { toOneHom := { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) },
          map_mul' := (_ : ∀ (x y : M), f (x * y) ^ n = f x ^ n * f y ^ n) })
      (n + 1) f =
    f *
      (fun n f =>
          { toOneHom := { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) },
            map_mul' := (_ : ∀ (x y : M), f (x * y) ^ n = f x ^ n * f y ^ n) })
        n f

Next tactic:
ext x
/-- `(M →* N)` is a `CommMonoid` if `N` is commutative. -/
@[to_additive "`(M →+ N)` is an `AddCommMonoid` if `N` is commutative."]
instance MonoidHom.commMonoid [MulOneClass M] [CommMonoid N] :
    CommMonoid (M →* N) where
  mul := (· * ·)
  mul_assoc := by intros; ext; apply mul_assoc
  one := 1
  one_mul := by intros; ext; apply one_mul
  mul_one := by intros; ext; apply mul_one
  mul_comm := by intros; ext; apply mul_comm
  npow n f :=
    { toFun := fun x => f x ^ n, map_one' := by simp, map_mul' := fun x y => by simp [mul_pow] }
  npow_zero f := by
    ext x
    simp
  npow_succ n f := by
    ext x
    

Proof state:
case h
M : Type uM
N : Type uN
P : Type uP
Q : Type uQ
inst✝¹ : MulOneClass M
inst✝ : CommMonoid N
n : ℕ
f : M →* N
x : M
⊢ ((fun n f =>
          { toOneHom := { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) },
            map_mul' := (_ : ∀ (x y : M), f (x * y) ^ n = f x ^ n * f y ^ n) })
        (n + 1) f)
      x =
    (f *
        (fun n f =>
            { toOneHom := { toFun := fun x => f x ^ n, map_one' := (_ : f 1 ^ n = 1) },
              map_mul' := (_ : ∀ (x y : M), f (x * y) ^ n = f x ^ n * f y ^ n) })
          n f)
      x

Next tactic:
simp [pow_succ]