Theorem: Polynomial.lifts_and_degree_eq_and_monic
File: Mathlib/Algebra/Polynomial/Lifts.lean

tactic: cases' subsingleton_or_nontrivial R with hR hR
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case inl
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Subsingleton R
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

case inr
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

tactic: have H : erase p.natDegree p + X ^ p.natDegree = p := by
  simpa only [hp.leadingCoeff, C_1, one_mul, eraseLead] using eraseLead_add_C_mul_X_pow p
state_before: case inr
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case inr
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

tactic: by_cases h0 : erase p.natDegree p = 0
state_before: case inr
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case pos
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

case neg
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

tactic: obtain ⟨q, hq⟩ := mem_lifts_and_degree_eq (erase_mem_lifts p.natDegree hlifts)
state_before: case neg
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case neg.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

tactic: have p_neq_0 : p ≠ 0 := by intro hp; apply h0; rw [hp]; simp only [natDegree_zero, erase_zero]
state_before: case neg.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case neg.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

tactic: have hdeg : q.degree < ((X : R[X]) ^ p.natDegree).degree := by
  rw [@degree_X_pow R, hq.2, ← degree_eq_natDegree p_neq_0]
  exact degree_erase_lt p_neq_0
state_before: case neg.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case neg.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
hdeg : q.degree < (X ^ p.natDegree).degree
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

tactic: refine ⟨q + X ^ p.natDegree, ?_, ?_, (monic_X_pow _).add_of_right hdeg⟩
state_before: case neg.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
hdeg : q.degree < (X ^ p.natDegree).degree
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case neg.intro.refine_1
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
hdeg : q.degree < (X ^ p.natDegree).degree
⊢ map f (q + X ^ p.natDegree) = p

case neg.intro.refine_2
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
hdeg : q.degree < (X ^ p.natDegree).degree
⊢ (q + X ^ p.natDegree).degree = p.degree

tactic: obtain ⟨q, hq⟩ := mem_lifts_and_degree_eq hlifts
state_before: case inl
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Subsingleton R
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case inl.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Subsingleton R
q : R[X]
hq : map f q = p ∧ q.degree = p.degree
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic

tactic: exact ⟨q, hq.1, hq.2, monic_of_subsingleton _⟩
state_before: case inl.intro
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Subsingleton R
q : R[X]
hq : map f q = p ∧ q.degree = p.degree
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: no goals

tactic: simpa only [hp.leadingCoeff, C_1, one_mul, eraseLead] using eraseLead_add_C_mul_X_pow p
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
⊢ erase p.natDegree p + X ^ p.natDegree = p
state_after: no goals

tactic: rw [← H, h0, zero_add]
state_before: case pos
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ ∃ q, map f q = p ∧ q.degree = p.degree ∧ q.Monic
state_after: case pos
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ ∃ q, map f q = X ^ p.natDegree ∧ q.degree = (X ^ p.natDegree).degree ∧ q.Monic

tactic: refine ⟨X ^ p.natDegree, ?_, ?_, monic_X_pow p.natDegree⟩
state_before: case pos
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ ∃ q, map f q = X ^ p.natDegree ∧ q.degree = (X ^ p.natDegree).degree ∧ q.Monic
state_after: case pos.refine_1
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ map f (X ^ p.natDegree) = X ^ p.natDegree

case pos.refine_2
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ (X ^ p.natDegree).degree = (X ^ p.natDegree).degree

tactic: rw [Polynomial.map_pow, map_X]
state_before: case pos.refine_1
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ map f (X ^ p.natDegree) = X ^ p.natDegree
state_after: no goals

tactic: rw [degree_X_pow, degree_X_pow]
state_before: case pos.refine_2
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : erase p.natDegree p = 0
⊢ (X ^ p.natDegree).degree = (X ^ p.natDegree).degree
state_after: no goals

tactic: intro hp
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
⊢ p ≠ 0
state_after: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp✝ : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
hp : p = 0
⊢ False

tactic: apply h0
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp✝ : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
hp : p = 0
⊢ False
state_after: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp✝ : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
hp : p = 0
⊢ erase p.natDegree p = 0

tactic: rw [hp]
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp✝ : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
hp : p = 0
⊢ erase p.natDegree p = 0
state_after: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp✝ : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
hp : p = 0
⊢ erase (natDegree 0) 0 = 0

tactic: simp only [natDegree_zero, erase_zero]
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp✝ : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
hp : p = 0
⊢ erase (natDegree 0) 0 = 0
state_after: no goals

tactic: rw [@degree_X_pow R, hq.2, ← degree_eq_natDegree p_neq_0]
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
⊢ q.degree < (X ^ p.natDegree).degree
state_after: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
⊢ (erase p.natDegree p).degree < p.degree

tactic: exact degree_erase_lt p_neq_0
state_before: R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
⊢ (erase p.natDegree p).degree < p.degree
state_after: no goals

tactic: rw [Polynomial.map_add, hq.1, Polynomial.map_pow, map_X, H]
state_before: case neg.intro.refine_1
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
hdeg : q.degree < (X ^ p.natDegree).degree
⊢ map f (q + X ^ p.natDegree) = p
state_after: no goals

tactic: rw [degree_add_eq_right_of_degree_lt hdeg, degree_X_pow, degree_eq_natDegree hp.ne_zero]
state_before: case neg.intro.refine_2
R : Type u
inst✝² : Semiring R
S : Type v
inst✝¹ : Semiring S
f : R →+* S
inst✝ : Nontrivial S
p : S[X]
hlifts : p ∈ lifts f
hp : p.Monic
hR : Nontrivial R
H : erase p.natDegree p + X ^ p.natDegree = p
h0 : ¬erase p.natDegree p = 0
q : R[X]
hq : map f q = erase p.natDegree p ∧ q.degree = (erase p.natDegree p).degree
p_neq_0 : p ≠ 0
hdeg : q.degree < (X ^ p.natDegree).degree
⊢ (q + X ^ p.natDegree).degree = p.degree
state_after: no goals