l3lab/ntp-mathlib huggingface dataset:
theorem eval₂_C_mk_eq_zero {I : Ideal R} {a : MvPolynomial σ R}
    (ha : a ∈ (Ideal.map (C : R →+* MvPolynomial σ R) I : Ideal (MvPolynomial σ R))) :
    eval₂Hom (C.comp (Ideal.Quotient.mk I)) X a = 0 := by
  rw [as_sum a]
  rw [coe_eval₂Hom, eval₂_sum]
  refine' Finset.sum_eq_zero fun n _ => _
  simp only [eval₂_monomial, Function.comp_apply, RingHom.coe_comp]
  refine' mul_eq_zero_of_left _ _
  suffices coeff n a ∈ I by
    

Proof state:
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
a : MvPolynomial σ R
ha : a ∈ Ideal.map C I
n : σ →₀ ℕ
x✝ : n ∈ support a
this : coeff n a ∈ I
⊢ C ((Ideal.Quotient.mk I) (coeff n a)) = 0

Next tactic:
rw [← @Ideal.mk_ker R _ I, RingHom.mem_ker] at this
theorem eval₂_C_mk_eq_zero {I : Ideal R} {a : MvPolynomial σ R}
    (ha : a ∈ (Ideal.map (C : R →+* MvPolynomial σ R) I : Ideal (MvPolynomial σ R))) :
    eval₂Hom (C.comp (Ideal.Quotient.mk I)) X a = 0 := by
  rw [as_sum a]
  rw [coe_eval₂Hom, eval₂_sum]
  refine' Finset.sum_eq_zero fun n _ => _
  simp only [eval₂_monomial, Function.comp_apply, RingHom.coe_comp]
  refine' mul_eq_zero_of_left _ _
  suffices coeff n a ∈ I by
    rw [← @Ideal.mk_ker R _ I, RingHom.mem_ker] at this
    

Proof state:
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
a : MvPolynomial σ R
ha : a ∈ Ideal.map C I
n : σ →₀ ℕ
x✝ : n ∈ support a
this : (Ideal.Quotient.mk I) (coeff n a) = 0
⊢ C ((Ideal.Quotient.mk I) (coeff n a)) = 0

Next tactic:
simp only [this, C_0]
theorem eval₂_C_mk_eq_zero {I : Ideal R} {a : MvPolynomial σ R}
    (ha : a ∈ (Ideal.map (C : R →+* MvPolynomial σ R) I : Ideal (MvPolynomial σ R))) :
    eval₂Hom (C.comp (Ideal.Quotient.mk I)) X a = 0 := by
  rw [as_sum a]
  rw [coe_eval₂Hom, eval₂_sum]
  refine' Finset.sum_eq_zero fun n _ => _
  simp only [eval₂_monomial, Function.comp_apply, RingHom.coe_comp]
  refine' mul_eq_zero_of_left _ _
  suffices coeff n a ∈ I by
    rw [← @Ideal.mk_ker R _ I, RingHom.mem_ker] at this
    simp only [this, C_0]
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
a : MvPolynomial σ R
ha : a ∈ Ideal.map C I
n : σ →₀ ℕ
x✝ : n ∈ support a
⊢ coeff n a ∈ I

Next tactic:
exact mem_map_C_iff.1 ha n
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
⊢ Function.RightInverse
    (eval₂
      (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
        (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
      fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i))
    ⇑(Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))

Next tactic:
intro f
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ (R ⧸ I)
⊢ (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) f) =
    f

Next tactic:
apply induction_on f
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · 

Proof state:
case h_C
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ (R ⧸ I)
⊢ ∀ (a : R ⧸ I),
    (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
          (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
        (eval₂
          (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
            (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
          (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (C a)) =
      C a

Next tactic:
intro r
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    

Proof state:
case h_C
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r✝ : R
I : Ideal R
f : MvPolynomial σ (R ⧸ I)
r : R ⧸ I
⊢ (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (C r)) =
    C r

Next tactic:
obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
    

Proof state:
case h_C.intro
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r✝ : R
I : Ideal R
f : MvPolynomial σ (R ⧸ I)
r : R
⊢ (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (C ((Ideal.Quotient.mk I) r))) =
    C ((Ideal.Quotient.mk I) r)

Next tactic:
rw [eval₂_C, Ideal.Quotient.lift_mk, RingHom.comp_apply, Ideal.Quotient.lift_mk, eval₂Hom_C,
      RingHom.comp_apply]
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
    rw [eval₂_C, Ideal.Quotient.lift_mk, RingHom.comp_apply, Ideal.Quotient.lift_mk, eval₂Hom_C,
      RingHom.comp_apply]
  · 

Proof state:
case h_add
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ (R ⧸ I)
⊢ ∀ (p q : MvPolynomial σ (R ⧸ I)),
    (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
            (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
          (eval₂
            (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
              (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
            (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) p) =
        p →
      (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
              (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
            (eval₂
              (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
                (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
              (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) q) =
          q →
        (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
              (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
            (eval₂
              (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
                (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
              (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (p + q)) =
          p + q

Next tactic:
intros p q hp hq
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
    rw [eval₂_C, Ideal.Quotient.lift_mk, RingHom.comp_apply, Ideal.Quotient.lift_mk, eval₂Hom_C,
      RingHom.comp_apply]
  · intros p q hp hq
    

Proof state:
case h_add
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p q : MvPolynomial σ (R ⧸ I)
hp :
  (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) p) =
    p
hq :
  (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) q) =
    q
⊢ (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (p + q)) =
    p + q

Next tactic:
simp only [RingHom.map_add, MvPolynomial.coe_eval₂Hom, coe_eval₂Hom, MvPolynomial.eval₂_add]
      at hp hq ⊢
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
    rw [eval₂_C, Ideal.Quotient.lift_mk, RingHom.comp_apply, Ideal.Quotient.lift_mk, eval₂Hom_C,
      RingHom.comp_apply]
  · intros p q hp hq
    simp only [RingHom.map_add, MvPolynomial.coe_eval₂Hom, coe_eval₂Hom, MvPolynomial.eval₂_add]
      at hp hq ⊢
    

Proof state:
case h_add
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p q : MvPolynomial σ (R ⧸ I)
hp :
  (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) p) =
    p
hq :
  (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) q) =
    q
⊢ (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
          (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
        (eval₂
          (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
            (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
          (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) p) +
      (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
          (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
        (eval₂
          (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
            (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
          (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) q) =
    p + q

Next tactic:
rw [hp, hq]
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
    rw [eval₂_C, Ideal.Quotient.lift_mk, RingHom.comp_apply, Ideal.Quotient.lift_mk, eval₂Hom_C,
      RingHom.comp_apply]
  · intros p q hp hq
    simp only [RingHom.map_add, MvPolynomial.coe_eval₂Hom, coe_eval₂Hom, MvPolynomial.eval₂_add]
      at hp hq ⊢
    rw [hp, hq]
  · 

Proof state:
case h_X
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ (R ⧸ I)
⊢ ∀ (p : MvPolynomial σ (R ⧸ I)) (n : σ),
    (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
            (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
          (eval₂
            (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
              (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
            (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) p) =
        p →
      (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
            (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
          (eval₂
            (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
              (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
            (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (p * X n)) =
        p * X n

Next tactic:
intros p i hp
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
    rw [eval₂_C, Ideal.Quotient.lift_mk, RingHom.comp_apply, Ideal.Quotient.lift_mk, eval₂Hom_C,
      RingHom.comp_apply]
  · intros p q hp hq
    simp only [RingHom.map_add, MvPolynomial.coe_eval₂Hom, coe_eval₂Hom, MvPolynomial.eval₂_add]
      at hp hq ⊢
    rw [hp, hq]
  · intros p i hp
    

Proof state:
case h_X
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p : MvPolynomial σ (R ⧸ I)
i : σ
hp :
  (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) p) =
    p
⊢ (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (p * X i)) =
    p * X i

Next tactic:
simp only [coe_eval₂Hom] at hp
lemma quotientEquivQuotientMvPolynomial_rightInverse (I : Ideal R) :
    Function.RightInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  apply induction_on f
  · intro r
    obtain ⟨r, rfl⟩ := Ideal.Quotient.mk_surjective r
    rw [eval₂_C, Ideal.Quotient.lift_mk, RingHom.comp_apply, Ideal.Quotient.lift_mk, eval₂Hom_C,
      RingHom.comp_apply]
  · intros p q hp hq
    simp only [RingHom.map_add, MvPolynomial.coe_eval₂Hom, coe_eval₂Hom, MvPolynomial.eval₂_add]
      at hp hq ⊢
    rw [hp, hq]
  · intros p i hp
    simp only [coe_eval₂Hom] at hp
    

Proof state:
case h_X
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p : MvPolynomial σ (R ⧸ I)
i : σ
hp :
  (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) p) =
    p
⊢ (Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
      (eval₂
        (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
          (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
        (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i)) (p * X i)) =
    p * X i

Next tactic:
simp only [hp, coe_eval₂Hom, Ideal.Quotient.lift_mk, eval₂_mul, RingHom.map_mul, eval₂_X]
lemma quotientEquivQuotientMvPolynomial_leftInverse (I : Ideal R) :
    Function.LeftInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
⊢ Function.LeftInverse
    (eval₂
      (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
        (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
      fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i))
    ⇑(Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
        (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))

Next tactic:
intro f
lemma quotientEquivQuotientMvPolynomial_leftInverse (I : Ideal R) :
    Function.LeftInverse
      (eval₂ (Ideal.Quotient.lift I
        ((Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R))).comp C)
          fun i hi => quotient_map_C_eq_zero hi)
          fun i => Ideal.Quotient.mk (Ideal.map C I : Ideal (MvPolynomial σ R)) (X i))
      (Ideal.Quotient.lift (Ideal.map C I : Ideal (MvPolynomial σ R))
        (eval₂Hom (C.comp (Ideal.Quotient.mk I)) X) fun a ha => eval₂_C_mk_eq_zero ha) := by
  intro f
  

Proof state:
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ R ⧸ Ideal.map C I
⊢ eval₂
      (Ideal.Quotient.lift I (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C)
        (_ : ∀ i ∈ I, (RingHom.comp (Ideal.Quotient.mk (Ideal.map C I)) C) i = 0))
      (fun i => (Ideal.Quotient.mk (Ideal.map C I)) (X i))
      ((Ideal.Quotient.lift (Ideal.map C I) (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X)
          (_ : ∀ a ∈ Ideal.map C I, (eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) a = 0))
        f) =
    f

Next tactic:
obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f