l3lab/ntp-mathlib huggingface dataset:
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  

Proof state:
case intro
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ R
⊢ 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))
        ((Ideal.Quotient.mk (Ideal.map C I)) f)) =
    (Ideal.Quotient.mk (Ideal.map C I)) f

Next tactic:
apply induction_on 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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · 

Proof state:
case intro.h_C
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ R
⊢ ∀ (a : R),
    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))
          ((Ideal.Quotient.mk (Ideal.map C I)) (C a))) =
      (Ideal.Quotient.mk (Ideal.map C I)) (C a)

Next tactic:
intro r
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    

Proof state:
case intro.h_C
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r✝ : R
I : Ideal R
f : MvPolynomial σ R
r : R
⊢ 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))
        ((Ideal.Quotient.mk (Ideal.map C I)) (C r))) =
    (Ideal.Quotient.mk (Ideal.map C I)) (C r)

Next tactic:
rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
  · 

Proof state:
case intro.h_add
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ R
⊢ ∀ (p q : MvPolynomial σ R),
    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))
            ((Ideal.Quotient.mk (Ideal.map C I)) p)) =
        (Ideal.Quotient.mk (Ideal.map C I)) p →
      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))
              ((Ideal.Quotient.mk (Ideal.map C I)) q)) =
          (Ideal.Quotient.mk (Ideal.map C I)) q →
        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))
              ((Ideal.Quotient.mk (Ideal.map C I)) (p + q))) =
          (Ideal.Quotient.mk (Ideal.map C I)) (p + q)

Next tactic:
intros p q hp hq
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
  · intros p q hp hq
    

Proof state:
case intro.h_add
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p q : MvPolynomial σ R
hp :
  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))
        ((Ideal.Quotient.mk (Ideal.map C I)) p)) =
    (Ideal.Quotient.mk (Ideal.map C I)) p
hq :
  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))
        ((Ideal.Quotient.mk (Ideal.map C I)) q)) =
    (Ideal.Quotient.mk (Ideal.map C I)) q
⊢ 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))
        ((Ideal.Quotient.mk (Ideal.map C I)) (p + q))) =
    (Ideal.Quotient.mk (Ideal.map C I)) (p + q)

Next tactic:
erw [Ideal.Quotient.lift_mk] at hp hq ⊢
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
  · intros p q hp hq
    erw [Ideal.Quotient.lift_mk] at hp hq ⊢
    

Proof state:
case intro.h_add
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p q : MvPolynomial σ R
hp :
  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)) ((eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) p) =
    (Ideal.Quotient.mk (Ideal.map C I)) p
hq :
  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)) ((eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) q) =
    (Ideal.Quotient.mk (Ideal.map C I)) q
⊢ 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))
      ((eval₂Hom (RingHom.comp C (Ideal.Quotient.mk I)) X) (p + q)) =
    (Ideal.Quotient.mk (Ideal.map C I)) (p + q)

Next tactic:
simp only [Submodule.Quotient.quot_mk_eq_mk, eval₂_add, RingHom.map_add, coe_eval₂Hom,
      Ideal.Quotient.lift_mk, Ideal.Quotient.mk_eq_mk] at hp hq ⊢
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
  · intros p q hp hq
    erw [Ideal.Quotient.lift_mk] at hp hq ⊢
    simp only [Submodule.Quotient.quot_mk_eq_mk, eval₂_add, RingHom.map_add, coe_eval₂Hom,
      Ideal.Quotient.lift_mk, Ideal.Quotient.mk_eq_mk] at hp hq ⊢
    

Proof state:
case intro.h_add
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p q : MvPolynomial σ R
hp :
  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)) (eval₂ (RingHom.comp C (Ideal.Quotient.mk I)) X p) =
    (Ideal.Quotient.mk (Ideal.map C I)) p
hq :
  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)) (eval₂ (RingHom.comp C (Ideal.Quotient.mk I)) X q) =
    (Ideal.Quotient.mk (Ideal.map C I)) q
⊢ 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)) (eval₂ (RingHom.comp C (Ideal.Quotient.mk I)) X p) +
      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)) (eval₂ (RingHom.comp C (Ideal.Quotient.mk I)) X q) =
    (Ideal.Quotient.mk (Ideal.map C I)) p + (Ideal.Quotient.mk (Ideal.map C I)) q

Next tactic:
rw [hp, hq]
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
  · intros p q hp hq
    erw [Ideal.Quotient.lift_mk] at hp hq ⊢
    simp only [Submodule.Quotient.quot_mk_eq_mk, eval₂_add, RingHom.map_add, coe_eval₂Hom,
      Ideal.Quotient.lift_mk, Ideal.Quotient.mk_eq_mk] at hp hq ⊢
    rw [hp, hq]
  · 

Proof state:
case intro.h_X
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f : MvPolynomial σ R
⊢ ∀ (p : MvPolynomial σ R) (n : σ),
    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))
            ((Ideal.Quotient.mk (Ideal.map C I)) p)) =
        (Ideal.Quotient.mk (Ideal.map C I)) p →
      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))
            ((Ideal.Quotient.mk (Ideal.map C I)) (p * X n))) =
        (Ideal.Quotient.mk (Ideal.map C I)) (p * X n)

Next tactic:
intros p i hp
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
  · intros p q hp hq
    erw [Ideal.Quotient.lift_mk] at hp hq ⊢
    simp only [Submodule.Quotient.quot_mk_eq_mk, eval₂_add, RingHom.map_add, coe_eval₂Hom,
      Ideal.Quotient.lift_mk, Ideal.Quotient.mk_eq_mk] at hp hq ⊢
    rw [hp, hq]
  · intros p i hp
    

Proof state:
case intro.h_X
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p : MvPolynomial σ R
i : σ
hp :
  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))
        ((Ideal.Quotient.mk (Ideal.map C I)) p)) =
    (Ideal.Quotient.mk (Ideal.map C I)) p
⊢ 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))
        ((Ideal.Quotient.mk (Ideal.map C I)) (p * X i))) =
    (Ideal.Quotient.mk (Ideal.map C I)) (p * X i)

Next tactic:
simp only [Submodule.Quotient.quot_mk_eq_mk, coe_eval₂Hom, Ideal.Quotient.lift_mk,
      Ideal.Quotient.mk_eq_mk, eval₂_mul, RingHom.map_mul, eval₂_X] at hp ⊢
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
  obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective f
  apply induction_on f
  · intro r
    rw [Ideal.Quotient.lift_mk, eval₂Hom_C, RingHom.comp_apply, eval₂_C, Ideal.Quotient.lift_mk,
      RingHom.comp_apply]
  · intros p q hp hq
    erw [Ideal.Quotient.lift_mk] at hp hq ⊢
    simp only [Submodule.Quotient.quot_mk_eq_mk, eval₂_add, RingHom.map_add, coe_eval₂Hom,
      Ideal.Quotient.lift_mk, Ideal.Quotient.mk_eq_mk] at hp hq ⊢
    rw [hp, hq]
  · intros p i hp
    simp only [Submodule.Quotient.quot_mk_eq_mk, coe_eval₂Hom, Ideal.Quotient.lift_mk,
      Ideal.Quotient.mk_eq_mk, eval₂_mul, RingHom.map_mul, eval₂_X] at hp ⊢
    

Proof state:
case intro.h_X
R : Type u_1
σ : Type u_2
inst✝ : CommRing R
r : R
I : Ideal R
f p : MvPolynomial σ R
i : σ
hp :
  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)) (eval₂ (RingHom.comp C (Ideal.Quotient.mk I)) X p) =
    (Ideal.Quotient.mk (Ideal.map C I)) p
⊢ 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)) (eval₂ (RingHom.comp C (Ideal.Quotient.mk I)) X p) *
      (Ideal.Quotient.mk (Ideal.map C I)) (X i) =
    (Ideal.Quotient.mk (Ideal.map C I)) p * (Ideal.Quotient.mk (Ideal.map C I)) (X i)

Next tactic:
simp only [hp]
protected theorem id_map {α : TypeVec n} (x : F α) : TypeVec.id <$$> x = x := by
  

Proof state:
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α : TypeVec.{u} n
x : F α
⊢ TypeVec.id <$$> x = x

Next tactic:
rw [← abs_repr x]
protected theorem id_map {α : TypeVec n} (x : F α) : TypeVec.id <$$> x = x := by
  rw [← abs_repr x]
  

Proof state:
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α : TypeVec.{u} n
x : F α
⊢ TypeVec.id <$$> abs (repr x) = abs (repr x)

Next tactic:
cases' repr x with a f
protected theorem id_map {α : TypeVec n} (x : F α) : TypeVec.id <$$> x = x := by
  rw [← abs_repr x]
  cases' repr x with a f
  

Proof state:
case mk
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α : TypeVec.{u} n
x : F α
a : (P F).A
f : MvPFunctor.B (P F) a ⟹ α
⊢ TypeVec.id <$$> abs { fst := a, snd := f } = abs { fst := a, snd := f }

Next tactic:
rw [← abs_map]
protected theorem id_map {α : TypeVec n} (x : F α) : TypeVec.id <$$> x = x := by
  rw [← abs_repr x]
  cases' repr x with a f
  rw [← abs_map]
  

Proof state:
case mk
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α : TypeVec.{u} n
x : F α
a : (P F).A
f : MvPFunctor.B (P F) a ⟹ α
⊢ abs (TypeVec.id <$$> { fst := a, snd := f }) = abs { fst := a, snd := f }

Next tactic:
rfl
@[simp]
theorem comp_map {α β γ : TypeVec n} (f : α ⟹ β) (g : β ⟹ γ) (x : F α) :
    (g ⊚ f) <$$> x = g <$$> f <$$> x := by
  

Proof state:
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α β γ : TypeVec.{u} n
f : α ⟹ β
g : β ⟹ γ
x : F α
⊢ (g ⊚ f) <$$> x = g <$$> f <$$> x

Next tactic:
rw [← abs_repr x]
@[simp]
theorem comp_map {α β γ : TypeVec n} (f : α ⟹ β) (g : β ⟹ γ) (x : F α) :
    (g ⊚ f) <$$> x = g <$$> f <$$> x := by
  rw [← abs_repr x]
  

Proof state:
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α β γ : TypeVec.{u} n
f : α ⟹ β
g : β ⟹ γ
x : F α
⊢ (g ⊚ f) <$$> abs (repr x) = g <$$> f <$$> abs (repr x)

Next tactic:
cases' repr x with a f
@[simp]
theorem comp_map {α β γ : TypeVec n} (f : α ⟹ β) (g : β ⟹ γ) (x : F α) :
    (g ⊚ f) <$$> x = g <$$> f <$$> x := by
  rw [← abs_repr x]
  cases' repr x with a f
  

Proof state:
case mk
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α β γ : TypeVec.{u} n
f✝ : α ⟹ β
g : β ⟹ γ
x : F α
a : (P F).A
f : MvPFunctor.B (P F) a ⟹ α
⊢ (g ⊚ f✝) <$$> abs { fst := a, snd := f } = g <$$> f✝ <$$> abs { fst := a, snd := f }

Next tactic:
rw [← abs_map, ← abs_map, ← abs_map]
@[simp]
theorem comp_map {α β γ : TypeVec n} (f : α ⟹ β) (g : β ⟹ γ) (x : F α) :
    (g ⊚ f) <$$> x = g <$$> f <$$> x := by
  rw [← abs_repr x]
  cases' repr x with a f
  rw [← abs_map, ← abs_map, ← abs_map]
  

Proof state:
case mk
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α β γ : TypeVec.{u} n
f✝ : α ⟹ β
g : β ⟹ γ
x : F α
a : (P F).A
f : MvPFunctor.B (P F) a ⟹ α
⊢ abs ((g ⊚ f✝) <$$> { fst := a, snd := f }) = abs (g <$$> f✝ <$$> { fst := a, snd := f })

Next tactic:
rfl
theorem liftP_iff {α : TypeVec n} (p : ∀ ⦃i⦄, α i → Prop) (x : F α) :
    LiftP p x ↔ ∃ a f, x = abs ⟨a, f⟩ ∧ ∀ i j, p (f i j) := by
  

Proof state:
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α : TypeVec.{u} n
p : ⦃i : Fin2 n⦄ → α i → Prop
x : F α
⊢ LiftP p x ↔ ∃ a f, x = abs { fst := a, snd := f } ∧ ∀ (i : Fin2 n) (j : MvPFunctor.B (P F) a i), p (f i j)

Next tactic:
constructor
theorem liftP_iff {α : TypeVec n} (p : ∀ ⦃i⦄, α i → Prop) (x : F α) :
    LiftP p x ↔ ∃ a f, x = abs ⟨a, f⟩ ∧ ∀ i j, p (f i j) := by
  constructor
  · 

Proof state:
case mp
n : ℕ
F : TypeVec.{u} n → Type u_1
inst✝ : MvFunctor F
q : MvQPF F
α : TypeVec.{u} n
p : ⦃i : Fin2 n⦄ → α i → Prop
x : F α
⊢ LiftP p x → ∃ a f, x = abs { fst := a, snd := f } ∧ ∀ (i : Fin2 n) (j : MvPFunctor.B (P F) a i), p (f i j)

Next tactic:
rintro ⟨y, hy⟩