l3lab/ntp-mathlib huggingface dataset:
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    

Proof state:
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < natDegree p
pzero : p ≠ 0
⊢ coeff p (natDegree p) ≠ 0

Next tactic:
rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; 

Proof state:
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < natDegree p
pzero : p ≠ 0
⊢ ¬p = 0

Next tactic:
exact pzero
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  

Proof state:
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < natDegree p
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
⊢ ∃ q, map f q = p ∧ degree q = degree p

Next tactic:
obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  

Proof state:
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < natDegree p
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
⊢ ∃ q, map f q = p ∧ degree q = degree p

Next tactic:
have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    

Proof state:
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < natDegree p
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
⊢ degree lead = ↑(natDegree p)

Next tactic:
rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
  

Proof state:
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < natDegree p
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
deg_lead : degree lead = ↑(natDegree p)
⊢ ∃ q, map f q = p ∧ degree q = degree p

Next tactic:
rw [hdeg] at deg_erase
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
  rw [hdeg] at deg_erase
  

Proof state:
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < n
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
deg_lead : degree lead = ↑(natDegree p)
⊢ ∃ q, map f q = p ∧ degree q = degree p

Next tactic:
obtain ⟨erase, herase⟩ :=
    hn p.eraseLead.natDegree deg_erase (erase_mem_lifts p.natDegree hlifts)
      (refl p.eraseLead.natDegree)
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
  rw [hdeg] at deg_erase
  obtain ⟨erase, herase⟩ :=
    hn p.eraseLead.natDegree deg_erase (erase_mem_lifts p.natDegree hlifts)
      (refl p.eraseLead.natDegree)
  

Proof state:
case neg.intro.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < n
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
deg_lead : degree lead = ↑(natDegree p)
erase : R[X]
herase : map f erase = Polynomial.erase (natDegree p) p ∧ degree erase = degree (Polynomial.erase (natDegree p) p)
⊢ ∃ q, map f q = p ∧ degree q = degree p

Next tactic:
use erase + lead
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
  rw [hdeg] at deg_erase
  obtain ⟨erase, herase⟩ :=
    hn p.eraseLead.natDegree deg_erase (erase_mem_lifts p.natDegree hlifts)
      (refl p.eraseLead.natDegree)
  use erase + lead
  

Proof state:
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < n
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
deg_lead : degree lead = ↑(natDegree p)
erase : R[X]
herase : map f erase = Polynomial.erase (natDegree p) p ∧ degree erase = degree (Polynomial.erase (natDegree p) p)
⊢ map f (erase + lead) = p ∧ degree (erase + lead) = degree p

Next tactic:
constructor
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
  rw [hdeg] at deg_erase
  obtain ⟨erase, herase⟩ :=
    hn p.eraseLead.natDegree deg_erase (erase_mem_lifts p.natDegree hlifts)
      (refl p.eraseLead.natDegree)
  use erase + lead
  constructor
  · 

Proof state:
case h.left
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < n
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
deg_lead : degree lead = ↑(natDegree p)
erase : R[X]
herase : map f erase = Polynomial.erase (natDegree p) p ∧ degree erase = degree (Polynomial.erase (natDegree p) p)
⊢ map f (erase + lead) = p

Next tactic:
simp only [hlead, herase, Polynomial.map_add]
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
  rw [hdeg] at deg_erase
  obtain ⟨erase, herase⟩ :=
    hn p.eraseLead.natDegree deg_erase (erase_mem_lifts p.natDegree hlifts)
      (refl p.eraseLead.natDegree)
  use erase + lead
  constructor
  · simp only [hlead, herase, Polynomial.map_add]
    

Proof state:
case h.left
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < n
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
deg_lead : degree lead = ↑(natDegree p)
erase : R[X]
herase : map f erase = Polynomial.erase (natDegree p) p ∧ degree erase = degree (Polynomial.erase (natDegree p) p)
⊢ Polynomial.erase (natDegree p) p + (monomial (natDegree p)) (coeff p (natDegree p)) = p

Next tactic:
rw [← eraseLead, ← leadingCoeff]
/-- A polynomial lifts if and only if it can be lifted to a polynomial of the same degree. -/
theorem mem_lifts_and_degree_eq {p : S[X]} (hlifts : p ∈ lifts f) :
    ∃ q : R[X], map f q = p ∧ q.degree = p.degree := by
  generalize hd : p.natDegree = d
  revert hd p
  induction' d using Nat.strong_induction_on with n hn
  intros p hlifts hdeg
  by_cases erase_zero : p.eraseLead = 0
  · rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
    exact
      monomial_mem_lifts_and_degree_eq
        (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
  have pzero : p ≠ 0 := by
    intro habs
    exfalso
    rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
    exact erase_zero
  have lead_zero : p.coeff p.natDegree ≠ 0 := by
    rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
  obtain ⟨lead, hlead⟩ :=
    monomial_mem_lifts_and_degree_eq
      (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
  have deg_lead : lead.degree = p.natDegree := by
    rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
  rw [hdeg] at deg_erase
  obtain ⟨erase, herase⟩ :=
    hn p.eraseLead.natDegree deg_erase (erase_mem_lifts p.natDegree hlifts)
      (refl p.eraseLead.natDegree)
  use erase + lead
  constructor
  · simp only [hlead, herase, Polynomial.map_add]
    rw [← eraseLead, ← leadingCoeff]
    

Proof state:
case h.left
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ m < n, ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
p : S[X]
hlifts : p ∈ lifts f
hdeg : natDegree p = n
erase_zero : ¬eraseLead p = 0
deg_erase : natDegree (eraseLead p) < n
pzero : p ≠ 0
lead_zero : coeff p (natDegree p) ≠ 0
lead : R[X]
hlead :
  map f lead = (monomial (natDegree p)) (coeff p (natDegree p)) ∧
    degree lead = degree ((monomial (natDegree p)) (coeff p (natDegree p)))
deg_lead : degree lead = ↑(natDegree p)
erase : R[X]
herase : map f erase = Polynomial.erase (natDegree p) p ∧ degree erase = degree (Polynomial.erase (natDegree p) p)
⊢ eraseLead p + (monomial (natDegree p)) (leadingCoeff p) = p

Next tactic:
rw [eraseLead_add_monomial_natDegree_leadingCoeff p]