l3lab/ntp-mathlib huggingface dataset:
/-- **Structure theorem of finitely generated modules over a PID** : A finitely generated
  module over a PID is isomorphic to the product of a free module and a direct sum of some
  `R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
    ∃ (n : ℕ) (ι : Type u) (_ : Fintype ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ),
      Nonempty <| N ≃ₗ[R] (Fin n →₀ R) × ⨁ i : ι, R ⧸ R ∙ p i ^ e i := by
  haveI := isNoetherian_submodule' (torsion R N)
  haveI := Module.Finite.of_surjective _ (torsion R N).mkQ_surjective
  obtain ⟨I, fI, p, hp, e, ⟨h⟩⟩ :=
    equiv_directSum_of_isTorsion.{u, v} (@torsion_isTorsion R N _ _ _)
  obtain ⟨n, ⟨g⟩⟩ := @Module.basisOfFiniteTypeTorsionFree' R _ _ _ (N ⧸ torsion R N) _ _ _ _
  haveI : Module.Projective R (N ⧸ torsion R N) := Module.Projective.of_basis ⟨g⟩
  obtain ⟨f, hf⟩ := Module.projective_lifting_property _ LinearMap.id (torsion R N).mkQ_surjective
  

Proof state:
case intro.intro.intro.intro.intro.intro.mk.ofRepr.intro
R : Type u
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type v
inst✝³ : AddCommGroup M
inst✝² : Module R M
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
h' : Finite R N
this✝¹ : IsNoetherian R ↥(torsion R N)
this✝ : Finite R (N ⧸ torsion R N)
I : Type u
fI : Fintype I
p : I → R
hp : ∀ (i : I), Irreducible (p i)
e : I → ℕ
h : ↥(torsion R N) ≃ₗ[R] ⨁ (i : I), R ⧸ span R {p i ^ e i}
n : ℕ
g : (N ⧸ torsion R N) ≃ₗ[R] Fin n →₀ R
this : Projective R (N ⧸ torsion R N)
f : N ⧸ torsion R N →ₗ[R] N
hf : mkQ (torsion R N) ∘ₗ f = LinearMap.id
⊢ ∃ n ι x p,
    ∃ (_ : ∀ (i : ι), Irreducible (p i)), ∃ e, Nonempty (N ≃ₗ[R] (Fin n →₀ R) × ⨁ (i : ι), R ⧸ span R {p i ^ e i})

Next tactic:
refine'
    ⟨n, I, fI, p, hp, e,
      ⟨(lequivProdOfRightSplitExact (torsion R N).injective_subtype _ hf).symm.trans <|
          (h.prod g).trans <| LinearEquiv.prodComm.{u, u} R _ (Fin n →₀ R) ⟩⟩
/-- **Structure theorem of finitely generated modules over a PID** : A finitely generated
  module over a PID is isomorphic to the product of a free module and a direct sum of some
  `R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
    ∃ (n : ℕ) (ι : Type u) (_ : Fintype ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ),
      Nonempty <| N ≃ₗ[R] (Fin n →₀ R) × ⨁ i : ι, R ⧸ R ∙ p i ^ e i := by
  haveI := isNoetherian_submodule' (torsion R N)
  haveI := Module.Finite.of_surjective _ (torsion R N).mkQ_surjective
  obtain ⟨I, fI, p, hp, e, ⟨h⟩⟩ :=
    equiv_directSum_of_isTorsion.{u, v} (@torsion_isTorsion R N _ _ _)
  obtain ⟨n, ⟨g⟩⟩ := @Module.basisOfFiniteTypeTorsionFree' R _ _ _ (N ⧸ torsion R N) _ _ _ _
  haveI : Module.Projective R (N ⧸ torsion R N) := Module.Projective.of_basis ⟨g⟩
  obtain ⟨f, hf⟩ := Module.projective_lifting_property _ LinearMap.id (torsion R N).mkQ_surjective
  refine'
    ⟨n, I, fI, p, hp, e,
      ⟨(lequivProdOfRightSplitExact (torsion R N).injective_subtype _ hf).symm.trans <|
          (h.prod g).trans <| LinearEquiv.prodComm.{u, u} R _ (Fin n →₀ R) ⟩⟩
  

Proof state:
case intro.intro.intro.intro.intro.intro.mk.ofRepr.intro
R : Type u
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
inst✝⁴ : IsPrincipalIdealRing R
M : Type v
inst✝³ : AddCommGroup M
inst✝² : Module R M
N : Type (max u v)
inst✝¹ : AddCommGroup N
inst✝ : Module R N
h' : Finite R N
this✝¹ : IsNoetherian R ↥(torsion R N)
this✝ : Finite R (N ⧸ torsion R N)
I : Type u
fI : Fintype I
p : I → R
hp : ∀ (i : I), Irreducible (p i)
e : I → ℕ
h : ↥(torsion R N) ≃ₗ[R] ⨁ (i : I), R ⧸ span R {p i ^ e i}
n : ℕ
g : (N ⧸ torsion R N) ≃ₗ[R] Fin n →₀ R
this : Projective R (N ⧸ torsion R N)
f : N ⧸ torsion R N →ₗ[R] N
hf : mkQ (torsion R N) ∘ₗ f = LinearMap.id
⊢ LinearMap.range (Submodule.subtype (torsion R N)) = LinearMap.ker (mkQ (torsion R N))

Next tactic:
rw [range_subtype, ker_mkQ]
theorem monomial_one_eq_iff [Nontrivial R] {i j : ℕ} :
    (monomial i 1 : R[X]) = monomial j 1 ↔ i = j := by
  -- Porting note: `ofFinsupp.injEq` is required.
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Nontrivial R
i j : ℕ
⊢ (monomial i) 1 = (monomial j) 1 ↔ i = j

Next tactic:
simp_rw [← ofFinsupp_single, ofFinsupp.injEq]
theorem monomial_one_eq_iff [Nontrivial R] {i j : ℕ} :
    (monomial i 1 : R[X]) = monomial j 1 ↔ i = j := by
  -- Porting note: `ofFinsupp.injEq` is required.
  simp_rw [← ofFinsupp_single, ofFinsupp.injEq]
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Nontrivial R
i j : ℕ
⊢ ((fun₀ | i => 1) = fun₀ | j => 1) ↔ i = j

Next tactic:
exact AddMonoidAlgebra.of_injective.eq_iff
instance infinite [Nontrivial R] : Infinite R[X] :=
  Infinite.of_injective (fun i => monomial i 1) fun m n h => by 

Proof state:
R : Type u
a b : R
m✝ n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Nontrivial R
m n : ℕ
h : (fun i => (monomial i) 1) m = (fun i => (monomial i) 1) n
⊢ m = n

Next tactic:
simpa [monomial_one_eq_iff] using h
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q r f : R[X]
⊢ Finset.card (support f) ≤ 1 ↔ ∃ n a, f = (monomial n) a

Next tactic:
constructor
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · 

Proof state:
case mp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q r f : R[X]
⊢ Finset.card (support f) ≤ 1 → ∃ n a, f = (monomial n) a

Next tactic:
intro H
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    

Proof state:
case mp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q r f : R[X]
H : Finset.card (support f) ≤ 1
⊢ ∃ n a, f = (monomial n) a

Next tactic:
rw [Finset.card_le_one_iff_subset_singleton] at H
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    

Proof state:
case mp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q r f : R[X]
H : ∃ x, support f ⊆ {x}
⊢ ∃ n a, f = (monomial n) a

Next tactic:
rcases H with ⟨n, hn⟩
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    

Proof state:
case mp.intro
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
⊢ ∃ n a, f = (monomial n) a

Next tactic:
refine' ⟨n, f.coeff n, _⟩
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    

Proof state:
case mp.intro
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
⊢ f = (monomial n) (coeff f n)

Next tactic:
ext i
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    

Proof state:
case mp.intro.a
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
i : ℕ
⊢ coeff f i = coeff ((monomial n) (coeff f n)) i

Next tactic:
by_cases hi : i = n
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · 

Proof state:
case pos
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
i : ℕ
hi : i = n
⊢ coeff f i = coeff ((monomial n) (coeff f n)) i

Next tactic:
simp [hi, coeff_monomial]
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · 

Proof state:
case neg
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
i : ℕ
hi : ¬i = n
⊢ coeff f i = coeff ((monomial n) (coeff f n)) i

Next tactic:
have : f.coeff i = 0 := by
        rw [← not_mem_support_iff]
        exact fun hi' => hi (Finset.mem_singleton.1 (hn hi'))
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · have : f.coeff i = 0 := by
        

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
i : ℕ
hi : ¬i = n
⊢ coeff f i = 0

Next tactic:
rw [← not_mem_support_iff]
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · have : f.coeff i = 0 := by
        rw [← not_mem_support_iff]
        

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
i : ℕ
hi : ¬i = n
⊢ i ∉ support f

Next tactic:
exact fun hi' => hi (Finset.mem_singleton.1 (hn hi'))
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · have : f.coeff i = 0 := by
        rw [← not_mem_support_iff]
        exact fun hi' => hi (Finset.mem_singleton.1 (hn hi'))
      

Proof state:
case neg
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r f : R[X]
n : ℕ
hn : support f ⊆ {n}
i : ℕ
hi : ¬i = n
this : coeff f i = 0
⊢ coeff f i = coeff ((monomial n) (coeff f n)) i

Next tactic:
simp [this, Ne.symm hi, coeff_monomial]
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · have : f.coeff i = 0 := by
        rw [← not_mem_support_iff]
        exact fun hi' => hi (Finset.mem_singleton.1 (hn hi'))
      simp [this, Ne.symm hi, coeff_monomial]
  · 

Proof state:
case mpr
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q r f : R[X]
⊢ (∃ n a, f = (monomial n) a) → Finset.card (support f) ≤ 1

Next tactic:
rintro ⟨n, a, rfl⟩
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · have : f.coeff i = 0 := by
        rw [← not_mem_support_iff]
        exact fun hi' => hi (Finset.mem_singleton.1 (hn hi'))
      simp [this, Ne.symm hi, coeff_monomial]
  · rintro ⟨n, a, rfl⟩
    

Proof state:
case mpr.intro.intro
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
a : R
⊢ Finset.card (support ((monomial n) a)) ≤ 1

Next tactic:
rw [← Finset.card_singleton n]
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · have : f.coeff i = 0 := by
        rw [← not_mem_support_iff]
        exact fun hi' => hi (Finset.mem_singleton.1 (hn hi'))
      simp [this, Ne.symm hi, coeff_monomial]
  · rintro ⟨n, a, rfl⟩
    rw [← Finset.card_singleton n]
    

Proof state:
case mpr.intro.intro
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
a : R
⊢ Finset.card (support ((monomial n) a)) ≤ Finset.card {n}

Next tactic:
apply Finset.card_le_of_subset
theorem card_support_le_one_iff_monomial {f : R[X]} :
    Finset.card f.support ≤ 1 ↔ ∃ n a, f = monomial n a := by
  constructor
  · intro H
    rw [Finset.card_le_one_iff_subset_singleton] at H
    rcases H with ⟨n, hn⟩
    refine' ⟨n, f.coeff n, _⟩
    ext i
    by_cases hi : i = n
    · simp [hi, coeff_monomial]
    · have : f.coeff i = 0 := by
        rw [← not_mem_support_iff]
        exact fun hi' => hi (Finset.mem_singleton.1 (hn hi'))
      simp [this, Ne.symm hi, coeff_monomial]
  · rintro ⟨n, a, rfl⟩
    rw [← Finset.card_singleton n]
    apply Finset.card_le_of_subset
    

Proof state:
case mpr.intro.intro.a
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
a : R
⊢ support ((monomial n) a) ⊆ {n}

Next tactic:
exact support_monomial' _ _
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
⊢ f = g

Next tactic:
set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
⊢ f = g

Next tactic:
set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
⊢ f = g

Next tactic:
have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    ext : 1
    · ext
      simp [h₁, RingEquiv.toRingHom_eq_coe]
    · refine MonoidHom.ext_mnat ?_
      simpa [RingEquiv.toRingHom_eq_coe] using h₂
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
⊢ f' = g'

Next tactic:
ext : 1
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    ext : 1
    · 

Proof state:
case h₁
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
⊢ RingHom.comp f' AddMonoidAlgebra.singleZeroRingHom = RingHom.comp g' AddMonoidAlgebra.singleZeroRingHom

Next tactic:
ext
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    ext : 1
    · ext
      

Proof state:
case h₁.a
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
x✝ : R
⊢ (RingHom.comp f' AddMonoidAlgebra.singleZeroRingHom) x✝ = (RingHom.comp g' AddMonoidAlgebra.singleZeroRingHom) x✝

Next tactic:
simp [h₁, RingEquiv.toRingHom_eq_coe]
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    ext : 1
    · ext
      simp [h₁, RingEquiv.toRingHom_eq_coe]
    · 

Proof state:
case h_of
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
⊢ MonoidHom.comp (↑f') (AddMonoidAlgebra.of R ℕ) = MonoidHom.comp (↑g') (AddMonoidAlgebra.of R ℕ)

Next tactic:
refine MonoidHom.ext_mnat ?_
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    ext : 1
    · ext
      simp [h₁, RingEquiv.toRingHom_eq_coe]
    · refine MonoidHom.ext_mnat ?_
      

Proof state:
case h_of
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
⊢ (MonoidHom.comp (↑f') (AddMonoidAlgebra.of R ℕ)) (Multiplicative.ofAdd 1) =
    (MonoidHom.comp (↑g') (AddMonoidAlgebra.of R ℕ)) (Multiplicative.ofAdd 1)

Next tactic:
simpa [RingEquiv.toRingHom_eq_coe] using h₂
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    ext : 1
    · ext
      simp [h₁, RingEquiv.toRingHom_eq_coe]
    · refine MonoidHom.ext_mnat ?_
      simpa [RingEquiv.toRingHom_eq_coe] using h₂
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
A : f' = g'
⊢ f = g

Next tactic:
have B : f = f'.comp (toFinsuppIso R) := by
    rw [hf', RingHom.comp_assoc]
    ext x
    simp only [RingEquiv.toRingHom_eq_coe, RingEquiv.symm_apply_apply, Function.comp_apply,
      RingHom.coe_comp, RingEquiv.coe_toRingHom]
theorem ringHom_ext {S} [Semiring S] {f g : R[X] →+* S} (h₁ : ∀ a, f (C a) = g (C a))
    (h₂ : f X = g X) : f = g := by
  set f' := f.comp (toFinsuppIso R).symm.toRingHom with hf'
  set g' := g.comp (toFinsuppIso R).symm.toRingHom with hg'
  have A : f' = g' := by
    -- Porting note: Was `ext; simp [..]; simpa [..] using h₂`.
    ext : 1
    · ext
      simp [h₁, RingEquiv.toRingHom_eq_coe]
    · refine MonoidHom.ext_mnat ?_
      simpa [RingEquiv.toRingHom_eq_coe] using h₂
  have B : f = f'.comp (toFinsuppIso R) := by
    

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
S : Type u_1
inst✝ : Semiring S
f g : R[X] →+* S
h₁ : ∀ (a : R), f (C a) = g (C a)
h₂ : f X = g X
f' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hf' : f' = RingHom.comp f (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
g' : AddMonoidAlgebra R ℕ →+* S := RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
hg' : g' = RingHom.comp g (RingEquiv.toRingHom (RingEquiv.symm (toFinsuppIso R)))
A : f' = g'
⊢ f = RingHom.comp f' ↑(toFinsuppIso R)

Next tactic:
rw [hf', RingHom.comp_assoc]