[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
⊢ p ∈ lifts f ↔ ∃ q, map f q = p
[PROOFSTEP]
simp only [coe_mapRingHom, lifts, RingHom.mem_rangeS]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
⊢ p ∈ lifts f ↔ p ∈ Set.range (map f)
[PROOFSTEP]
simp only [coe_mapRingHom, lifts, Set.mem_range, RingHom.mem_rangeS]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
⊢ p ∈ lifts f ↔ p ∈ RingHom.rangeS (mapRingHom f)
[PROOFSTEP]
simp only [coe_mapRingHom, lifts, Set.mem_range, RingHom.mem_rangeS]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
⊢ p ∈ lifts f ↔ ∀ (n : ℕ), coeff p n ∈ Set.range ↑f
[PROOFSTEP]
rw [lifts_iff_ringHom_rangeS, mem_map_rangeS f]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
⊢ (∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f) ↔ ∀ (n : ℕ), coeff p n ∈ Set.range ↑f
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f✝ f : R →+* S
r : R
⊢ ↑(mapRingHom f) (↑C r) = ↑C (↑f r)
[PROOFSTEP]
simp only [coe_mapRingHom, map_C, Set.mem_univ, Subsemiring.coe_top, eq_self_iff_true, and_self_iff]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f✝ f : R →+* S
s : S
h : s ∈ Set.range ↑f
⊢ ↑C s ∈ lifts f
[PROOFSTEP]
obtain ⟨r, rfl⟩ := Set.mem_range.1 h
[GOAL]
case intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f✝ f : R →+* S
r : R
h : ↑f r ∈ Set.range ↑f
⊢ ↑C (↑f r) ∈ lifts f
[PROOFSTEP]
use C r
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f✝ f : R →+* S
r : R
h : ↑f r ∈ Set.range ↑f
⊢ ↑(mapRingHom f) (↑C r) = ↑C (↑f r)
[PROOFSTEP]
simp only [coe_mapRingHom, map_C, Set.mem_univ, Subsemiring.coe_top, eq_self_iff_true, and_self_iff]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f✝ f : R →+* S
⊢ ↑(mapRingHom f) X = X
[PROOFSTEP]
simp only [coe_mapRingHom, Set.mem_univ, Subsemiring.coe_top, eq_self_iff_true, map_X, and_self_iff]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f✝ f : R →+* S
n : ℕ
⊢ ↑(mapRingHom f) (X ^ n) = X ^ n
[PROOFSTEP]
simp only [coe_mapRingHom, map_pow, Set.mem_univ, Subsemiring.coe_top, eq_self_iff_true, map_X, and_self_iff]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
r : R
hp : p ∈ lifts f
⊢ ↑C (↑f r) * p ∈ lifts f
[PROOFSTEP]
simp only [lifts, RingHom.mem_rangeS] at hp ⊢
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
r : R
hp : ∃ x, ↑(mapRingHom f) x = p
⊢ ∃ x, ↑(mapRingHom f) x = ↑C (↑f r) * p
[PROOFSTEP]
obtain ⟨p₁, rfl⟩ := hp
[GOAL]
case intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
r : R
p₁ : R[X]
⊢ ∃ x, ↑(mapRingHom f) x = ↑C (↑f r) * ↑(mapRingHom f) p₁
[PROOFSTEP]
use C r * p₁
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
r : R
p₁ : R[X]
⊢ ↑(mapRingHom f) (↑C r * p₁) = ↑C (↑f r) * ↑(mapRingHom f) p₁
[PROOFSTEP]
simp only [coe_mapRingHom, map_C, map_mul]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
h : s ∈ Set.range ↑f
⊢ ↑(monomial n) s ∈ lifts f
[PROOFSTEP]
obtain ⟨r, rfl⟩ := Set.mem_range.1 h
[GOAL]
case intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
r : R
h : ↑f r ∈ Set.range ↑f
⊢ ↑(monomial n) (↑f r) ∈ lifts f
[PROOFSTEP]
use monomial n r
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
r : R
h : ↑f r ∈ Set.range ↑f
⊢ ↑(mapRingHom f) (↑(monomial n) r) = ↑(monomial n) (↑f r)
[PROOFSTEP]
simp only [coe_mapRingHom, Set.mem_univ, map_monomial, Subsemiring.coe_top, eq_self_iff_true, and_self_iff]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : p ∈ lifts f
⊢ erase n p ∈ lifts f
[PROOFSTEP]
rw [lifts_iff_ringHom_rangeS, mem_map_rangeS] at h ⊢
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : ∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f
⊢ ∀ (n_1 : ℕ), coeff (erase n p) n_1 ∈ RingHom.rangeS f
[PROOFSTEP]
intro k
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : ∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f
k : ℕ
⊢ coeff (erase n p) k ∈ RingHom.rangeS f
[PROOFSTEP]
by_cases hk : k = n
[GOAL]
case pos
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : ∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f
k : ℕ
hk : k = n
⊢ coeff (erase n p) k ∈ RingHom.rangeS f
[PROOFSTEP]
use 0
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : ∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f
k : ℕ
hk : k = n
⊢ ↑f 0 = coeff (erase n p) k
[PROOFSTEP]
simp only [hk, RingHom.map_zero, erase_same]
[GOAL]
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : ∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f
k : ℕ
hk : ¬k = n
⊢ coeff (erase n p) k ∈ RingHom.rangeS f
[PROOFSTEP]
obtain ⟨i, hi⟩ := h k
[GOAL]
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : ∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f
k : ℕ
hk : ¬k = n
i : R
hi : ↑f i = coeff p k
⊢ coeff (erase n p) k ∈ RingHom.rangeS f
[PROOFSTEP]
use i
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
n : ℕ
h : ∀ (n : ℕ), coeff p n ∈ RingHom.rangeS f
k : ℕ
hk : ¬k = n
i : R
hi : ↑f i = coeff p k
⊢ ↑f i = coeff (erase n p) k
[PROOFSTEP]
simp only [hi, hk, erase_ne, Ne.def, not_false_iff]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hl : ↑(monomial n) s ∈ lifts f
⊢ ∃ q, map f q = ↑(monomial n) s ∧ degree q = degree (↑(monomial n) s)
[PROOFSTEP]
by_cases hzero : s = 0
[GOAL]
case pos
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hl : ↑(monomial n) s ∈ lifts f
hzero : s = 0
⊢ ∃ q, map f q = ↑(monomial n) s ∧ degree q = degree (↑(monomial n) s)
[PROOFSTEP]
use 0
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hl : ↑(monomial n) s ∈ lifts f
hzero : s = 0
⊢ map f 0 = ↑(monomial n) s ∧ degree 0 = degree (↑(monomial n) s)
[PROOFSTEP]
simp only [hzero, degree_zero, eq_self_iff_true, and_self_iff, monomial_zero_right, Polynomial.map_zero]
[GOAL]
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hl : ↑(monomial n) s ∈ lifts f
hzero : ¬s = 0
⊢ ∃ q, map f q = ↑(monomial n) s ∧ degree q = degree (↑(monomial n) s)
[PROOFSTEP]
rw [lifts_iff_set_range] at hl
[GOAL]
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hl : ↑(monomial n) s ∈ Set.range (map f)
hzero : ¬s = 0
⊢ ∃ q, map f q = ↑(monomial n) s ∧ degree q = degree (↑(monomial n) s)
[PROOFSTEP]
obtain ⟨q, hq⟩ := hl
[GOAL]
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : map f q = ↑(monomial n) s
⊢ ∃ q, map f q = ↑(monomial n) s ∧ degree q = degree (↑(monomial n) s)
[PROOFSTEP]
replace hq := (ext_iff.1 hq) n
[GOAL]
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
⊢ ∃ q, map f q = ↑(monomial n) s ∧ degree q = degree (↑(monomial n) s)
[PROOFSTEP]
have hcoeff : f (q.coeff n) = s := by
  simp [coeff_monomial] at hq
  exact hq
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
⊢ ↑f (coeff q n) = s
[PROOFSTEP]
simp [coeff_monomial] at hq
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : ↑f (coeff q n) = s
⊢ ↑f (coeff q n) = s
[PROOFSTEP]
exact hq
[GOAL]
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
⊢ ∃ q, map f q = ↑(monomial n) s ∧ degree q = degree (↑(monomial n) s)
[PROOFSTEP]
use monomial n (q.coeff n)
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
⊢ map f (↑(monomial n) (coeff q n)) = ↑(monomial n) s ∧ degree (↑(monomial n) (coeff q n)) = degree (↑(monomial n) s)
[PROOFSTEP]
constructor
[GOAL]
case h.left
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
⊢ map f (↑(monomial n) (coeff q n)) = ↑(monomial n) s
[PROOFSTEP]
simp only [hcoeff, map_monomial]
[GOAL]
case h.right
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
⊢ degree (↑(monomial n) (coeff q n)) = degree (↑(monomial n) s)
[PROOFSTEP]
have hqzero : q.coeff n ≠ 0 := by
  intro habs
  simp only [habs, RingHom.map_zero] at hcoeff
  exact hzero hcoeff.symm
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
⊢ coeff q n ≠ 0
[PROOFSTEP]
intro habs
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
habs : coeff q n = 0
⊢ False
[PROOFSTEP]
simp only [habs, RingHom.map_zero] at hcoeff
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
habs : coeff q n = 0
hcoeff : 0 = s
⊢ False
[PROOFSTEP]
exact hzero hcoeff.symm
[GOAL]
case h.right
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
hqzero : coeff q n ≠ 0
⊢ degree (↑(monomial n) (coeff q n)) = degree (↑(monomial n) s)
[PROOFSTEP]
rw [← C_mul_X_pow_eq_monomial]
[GOAL]
case h.right
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
hqzero : coeff q n ≠ 0
⊢ degree (↑C (coeff q n) * X ^ n) = degree (↑(monomial n) s)
[PROOFSTEP]
rw [← C_mul_X_pow_eq_monomial]
[GOAL]
case h.right
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
s : S
n : ℕ
hzero : ¬s = 0
q : R[X]
hq : coeff (map f q) n = coeff (↑(monomial n) s) n
hcoeff : ↑f (coeff q n) = s
hqzero : coeff q n ≠ 0
⊢ degree (↑C (coeff q n) * X ^ n) = degree (↑C s * X ^ n)
[PROOFSTEP]
simp only [hzero, hqzero, Ne.def, not_false_iff, degree_C_mul_X_pow]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
hlifts : p ∈ lifts f
⊢ ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
generalize hd : p.natDegree = d
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
hlifts : p ∈ lifts f
d : ℕ
hd : natDegree p = d
⊢ ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
revert hd p
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
d : ℕ
⊢ ∀ {p : S[X]}, p ∈ lifts f → natDegree p = d → ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
induction' d using Nat.strong_induction_on with n hn
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), m < n → ∀ {p : S[X]}, p ∈ lifts f → natDegree p = m → ∃ q, map f q = p ∧ degree q = degree p
⊢ ∀ {p : S[X]}, p ∈ lifts f → natDegree p = n → ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
intros p hlifts hdeg
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
⊢ ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
by_cases erase_zero : p.eraseLead = 0
[GOAL]
case pos
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
⊢ ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
rw [← eraseLead_add_monomial_natDegree_leadingCoeff p, erase_zero, zero_add, leadingCoeff]
[GOAL]
case pos
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
⊢ ∃ q,
    map f q = ↑(monomial (natDegree p)) (coeff p (natDegree p)) ∧
      degree q = degree (↑(monomial (natDegree p)) (coeff p (natDegree p)))
[PROOFSTEP]
exact monomial_mem_lifts_and_degree_eq (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
[GOAL]
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
⊢ ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
have deg_erase := Or.resolve_right (eraseLead_natDegree_lt_or_eraseLead_eq_zero p) erase_zero
[GOAL]
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
⊢ ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
have pzero : p ≠ 0 := by
  intro habs
  exfalso
  rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
  exact erase_zero
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
⊢ p ≠ 0
[PROOFSTEP]
intro habs
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
habs : p = 0
⊢ False
[PROOFSTEP]
exfalso
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
habs : p = 0
⊢ False
[PROOFSTEP]
rw [habs, eraseLead_zero, eq_self_iff_true, not_true] at erase_zero
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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 : False
deg_erase : natDegree (eraseLead p) < natDegree p
habs : p = 0
⊢ False
[PROOFSTEP]
exact erase_zero
[GOAL]
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
⊢ ∃ q, map f q = p ∧ degree q = degree p
[PROOFSTEP]
have lead_zero : p.coeff p.natDegree ≠ 0 := by rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]; exact pzero
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
rw [← leadingCoeff, Ne.def, leadingCoeff_eq_zero]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
exact pzero
[GOAL]
case neg
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
obtain ⟨lead, hlead⟩ :=
  monomial_mem_lifts_and_degree_eq (monomial_mem_lifts p.natDegree ((lifts_iff_coeff_lifts p).1 hlifts p.natDegree))
[GOAL]
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
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]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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)
[PROOFSTEP]
rw [hlead.2, ← C_mul_X_pow_eq_monomial, degree_C_mul_X_pow p.natDegree lead_zero]
[GOAL]
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
rw [hdeg] at deg_erase
[GOAL]
case neg.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
obtain ⟨erase, herase⟩ :=
  hn p.eraseLead.natDegree deg_erase (erase_mem_lifts p.natDegree hlifts) (refl p.eraseLead.natDegree)
[GOAL]
case neg.intro.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
use erase + lead
[GOAL]
case h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
constructor
[GOAL]
case h.left
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
simp only [hlead, herase, Polynomial.map_add]
[GOAL]
case h.left
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
rw [← eraseLead, ← leadingCoeff]
[GOAL]
case h.left
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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
[PROOFSTEP]
rw [eraseLead_add_monomial_natDegree_leadingCoeff p]
[GOAL]
case h.right
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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)
⊢ degree (erase + lead) = degree p
[PROOFSTEP]
rw [degree_eq_natDegree pzero, ← deg_lead]
[GOAL]
case h.right
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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)
⊢ degree (erase + lead) = degree lead
[PROOFSTEP]
apply degree_add_eq_right_of_degree_lt
[GOAL]
case h.right.h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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)
⊢ degree erase < degree lead
[PROOFSTEP]
rw [herase.2, deg_lead, ← degree_eq_natDegree pzero]
[GOAL]
case h.right.h
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
n : ℕ
hn : ∀ (m : ℕ), 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)
⊢ degree (Polynomial.erase (natDegree p) p) < degree p
[PROOFSTEP]
exact degree_erase_lt pzero
[GOAL]
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 : Monic p
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
cases' subsingleton_or_nontrivial R with hR hR
[GOAL]
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 : Monic p
hR : Subsingleton R
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
obtain ⟨q, hq⟩ := mem_lifts_and_degree_eq hlifts
[GOAL]
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 : Monic p
hR : Subsingleton R
q : R[X]
hq : map f q = p ∧ degree q = degree p
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
exact ⟨q, hq.1, hq.2, monic_of_subsingleton _⟩
[GOAL]
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 : Monic p
hR : Nontrivial R
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
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
[GOAL]
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 : Monic p
hR : Nontrivial R
⊢ erase (natDegree p) p + X ^ natDegree p = p
[PROOFSTEP]
simpa only [hp.leadingCoeff, C_1, one_mul, eraseLead] using eraseLead_add_C_mul_X_pow p
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
by_cases h0 : erase p.natDegree p = 0
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : erase (natDegree p) p = 0
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
rw [← H, h0, zero_add]
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : erase (natDegree p) p = 0
⊢ ∃ q, map f q = X ^ natDegree p ∧ degree q = degree (X ^ natDegree p) ∧ Monic q
[PROOFSTEP]
refine' ⟨X ^ p.natDegree, _, _, monic_X_pow p.natDegree⟩
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : erase (natDegree p) p = 0
⊢ map f (X ^ natDegree p) = X ^ natDegree p
[PROOFSTEP]
rw [Polynomial.map_pow, map_X]
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : erase (natDegree p) p = 0
⊢ degree (X ^ natDegree p) = degree (X ^ natDegree p)
[PROOFSTEP]
rw [degree_X_pow, degree_X_pow]
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
obtain ⟨q, hq⟩ := mem_lifts_and_degree_eq (erase_mem_lifts p.natDegree hlifts)
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
have p_neq_0 : p ≠ 0 := by intro hp; apply h0; rw [hp]; simp only [natDegree_zero, erase_zero]
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
⊢ p ≠ 0
[PROOFSTEP]
intro hp
[GOAL]
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✝ : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
hp : p = 0
⊢ False
[PROOFSTEP]
apply h0
[GOAL]
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✝ : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
hp : p = 0
⊢ erase (natDegree p) p = 0
[PROOFSTEP]
rw [hp]
[GOAL]
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✝ : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
hp : p = 0
⊢ erase (natDegree 0) 0 = 0
[PROOFSTEP]
simp only [natDegree_zero, erase_zero]
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
p_neq_0 : p ≠ 0
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
have hdeg : q.degree < (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
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
p_neq_0 : p ≠ 0
⊢ degree q < degree (X ^ natDegree p)
[PROOFSTEP]
rw [@degree_X_pow R, hq.2, ← degree_eq_natDegree p_neq_0]
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
p_neq_0 : p ≠ 0
⊢ degree (erase (natDegree p) p) < degree p
[PROOFSTEP]
exact degree_erase_lt p_neq_0
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
p_neq_0 : p ≠ 0
hdeg : degree q < degree (X ^ natDegree p)
⊢ ∃ q, map f q = p ∧ degree q = degree p ∧ Monic q
[PROOFSTEP]
refine' ⟨q + X ^ p.natDegree, _, _, (monic_X_pow _).add_of_right hdeg⟩
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
p_neq_0 : p ≠ 0
hdeg : degree q < degree (X ^ natDegree p)
⊢ map f (q + X ^ natDegree p) = p
[PROOFSTEP]
rw [Polynomial.map_add, hq.1, Polynomial.map_pow, map_X, H]
[GOAL]
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 : Monic p
hR : Nontrivial R
H : erase (natDegree p) p + X ^ natDegree p = p
h0 : ¬erase (natDegree p) p = 0
q : R[X]
hq : map f q = erase (natDegree p) p ∧ degree q = degree (erase (natDegree p) p)
p_neq_0 : p ≠ 0
hdeg : degree q < degree (X ^ natDegree p)
⊢ degree (q + X ^ natDegree p) = degree p
[PROOFSTEP]
rw [degree_add_eq_right_of_degree_lt hdeg, degree_X_pow, degree_eq_natDegree hp.ne_zero]
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
hlifts : p ∈ lifts f
hp : Monic p
⊢ ∃ q, map f q = p ∧ natDegree q = natDegree p ∧ Monic q
[PROOFSTEP]
cases' subsingleton_or_nontrivial S with hR hR
[GOAL]
case inl
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
hlifts : p ∈ lifts f
hp : Monic p
hR : Subsingleton S
⊢ ∃ q, map f q = p ∧ natDegree q = natDegree p ∧ Monic q
[PROOFSTEP]
obtain rfl : p = 1 := Subsingleton.elim _ _
[GOAL]
case inl
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
hR : Subsingleton S
hlifts : 1 ∈ lifts f
hp : Monic 1
⊢ ∃ q, map f q = 1 ∧ natDegree q = natDegree 1 ∧ Monic q
[PROOFSTEP]
refine' ⟨1, Subsingleton.elim _ _, by simp, by simp⟩
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
hR : Subsingleton S
hlifts : 1 ∈ lifts f
hp : Monic 1
⊢ natDegree 1 = natDegree 1
[PROOFSTEP]
simp
[GOAL]
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
hR : Subsingleton S
hlifts : 1 ∈ lifts f
hp : Monic 1
⊢ Monic 1
[PROOFSTEP]
simp
[GOAL]
case inr
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
hlifts : p ∈ lifts f
hp : Monic p
hR : Nontrivial S
⊢ ∃ q, map f q = p ∧ natDegree q = natDegree p ∧ Monic q
[PROOFSTEP]
obtain ⟨p', h₁, h₂, h₃⟩ := lifts_and_degree_eq_and_monic hlifts hp
[GOAL]
case inr.intro.intro.intro
R : Type u
inst✝¹ : Semiring R
S : Type v
inst✝ : Semiring S
f : R →+* S
p : S[X]
hlifts : p ∈ lifts f
hp : Monic p
hR : Nontrivial S
p' : R[X]
h₁ : map f p' = p
h₂ : degree p' = degree p
h₃ : Monic p'
⊢ ∃ q, map f q = p ∧ natDegree q = natDegree p ∧ Monic q
[PROOFSTEP]
exact ⟨p', h₁, natDegree_eq_of_degree_eq h₂, h₃⟩
[GOAL]
R : Type u
inst✝¹ : Ring R
S : Type v
inst✝ : Ring S
f : R →+* S
p : S[X]
⊢ p ∈ lifts f ↔ p ∈ liftsRing f
[PROOFSTEP]
simp only [lifts, liftsRing, RingHom.mem_range, RingHom.mem_rangeS]
[GOAL]
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : Semiring S
inst✝ : Algebra R S
p : R[X]
⊢ ↑(mapAlg R S) p = map (algebraMap R S) p
[PROOFSTEP]
simp only [mapAlg, aeval_def, eval₂_eq_sum, map, algebraMap_apply, RingHom.coe_comp]
[GOAL]
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : Semiring S
inst✝ : Algebra R S
p : R[X]
⊢ (sum p fun e a => ↑C (↑(algebraMap R S) a) * X ^ e) = sum p fun e a => (↑C ∘ ↑(algebraMap R S)) a * X ^ e
[PROOFSTEP]
ext
[GOAL]
case a
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : Semiring S
inst✝ : Algebra R S
p : R[X]
n✝ : ℕ
⊢ coeff (sum p fun e a => ↑C (↑(algebraMap R S) a) * X ^ e) n✝ =
    coeff (sum p fun e a => (↑C ∘ ↑(algebraMap R S)) a * X ^ e) n✝
[PROOFSTEP]
congr
[GOAL]
R✝ : Type u
inst✝⁵ : CommSemiring R✝
S✝ : Type v
inst✝⁴ : Semiring S✝
inst✝³ : Algebra R✝ S✝
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : Semiring S
inst✝ : Algebra R S
p : S[X]
⊢ p ∈ lifts (algebraMap R S) ↔ p ∈ AlgHom.range (mapAlg R S)
[PROOFSTEP]
simp only [coe_mapRingHom, lifts, mapAlg_eq_map, AlgHom.mem_range, RingHom.mem_rangeS]
[GOAL]
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : Semiring S
inst✝ : Algebra R S
p : S[X]
r : R
hp : p ∈ lifts (algebraMap R S)
⊢ r • p ∈ lifts (algebraMap R S)
[PROOFSTEP]
rw [mem_lifts_iff_mem_alg] at hp ⊢
[GOAL]
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : Semiring S
inst✝ : Algebra R S
p : S[X]
r : R
hp : p ∈ AlgHom.range (mapAlg R S)
⊢ r • p ∈ AlgHom.range (mapAlg R S)
[PROOFSTEP]
exact Subalgebra.smul_mem (mapAlg R S).range hp r


[GOAL]
C : Type u
inst✝ : Category.{v, u} C
F G : C ⥤ Discrete PUnit
X : C
⊢ F.obj X = G.obj X
[PROOFSTEP]
simp only [eq_iff_true_of_subsingleton]
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
F G : C ⥤ Discrete PUnit
X : C
⊢ F.obj X = G.obj X
[PROOFSTEP]
simp only [eq_iff_true_of_subsingleton]
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
⊢ Nonempty (C ≌ Discrete PUnit) ↔ Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))
[PROOFSTEP]
constructor
[GOAL]
case mp
C : Type u
inst✝ : Category.{v, u} C
⊢ Nonempty (C ≌ Discrete PUnit) → Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))
[PROOFSTEP]
rintro ⟨h⟩
[GOAL]
case mp.intro
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
⊢ Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))
[PROOFSTEP]
refine' ⟨⟨h.inverse.obj ⟨⟨⟩⟩⟩, fun x y => Nonempty.intro _⟩
[GOAL]
case mp.intro
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
⊢ Unique (x ⟶ y)
[PROOFSTEP]
let f : x ⟶ y := by
  have hx : x ⟶ h.inverse.obj ⟨⟨⟩⟩ := by convert h.unit.app x
  have hy : h.inverse.obj ⟨⟨⟩⟩ ⟶ y := by convert h.unitInv.app y
  exact hx ≫ hy
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
⊢ x ⟶ y
[PROOFSTEP]
have hx : x ⟶ h.inverse.obj ⟨⟨⟩⟩ := by convert h.unit.app x
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
⊢ x ⟶ h.inverse.obj { as := PUnit.unit }
[PROOFSTEP]
convert h.unit.app x
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
hx : x ⟶ h.inverse.obj { as := PUnit.unit }
⊢ x ⟶ y
[PROOFSTEP]
have hy : h.inverse.obj ⟨⟨⟩⟩ ⟶ y := by convert h.unitInv.app y
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
hx : x ⟶ h.inverse.obj { as := PUnit.unit }
⊢ h.inverse.obj { as := PUnit.unit } ⟶ y
[PROOFSTEP]
convert h.unitInv.app y
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
hx : x ⟶ h.inverse.obj { as := PUnit.unit }
hy : h.inverse.obj { as := PUnit.unit } ⟶ y
⊢ x ⟶ y
[PROOFSTEP]
exact hx ≫ hy
[GOAL]
case mp.intro
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
⊢ Unique (x ⟶ y)
[PROOFSTEP]
suffices sub : Subsingleton (x ⟶ y) from uniqueOfSubsingleton f
[GOAL]
case mp.intro
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
⊢ Subsingleton (x ⟶ y)
[PROOFSTEP]
have : ∀ z, z = h.unit.app x ≫ (h.functor ⋙ h.inverse).map z ≫ h.unitInv.app y :=
  by
  intro z
  simp [congrArg (· ≫ h.unitInv.app y) (h.unit.naturality z)]
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
⊢ ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
[PROOFSTEP]
intro z
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
z : x ⟶ y
⊢ z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
[PROOFSTEP]
simp [congrArg (· ≫ h.unitInv.app y) (h.unit.naturality z)]
[GOAL]
case mp.intro
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
this :
  ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
⊢ Subsingleton (x ⟶ y)
[PROOFSTEP]
apply Subsingleton.intro
[GOAL]
case mp.intro.allEq
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
this :
  ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
⊢ ∀ (a b : x ⟶ y), a = b
[PROOFSTEP]
intro a b
[GOAL]
case mp.intro.allEq
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
this :
  ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
a b : x ⟶ y
⊢ a = b
[PROOFSTEP]
rw [this a, this b]
[GOAL]
case mp.intro.allEq
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
this :
  ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
a b : x ⟶ y
⊢ NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map a ≫ NatTrans.app (Equivalence.unitInv h) y =
    NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map b ≫ NatTrans.app (Equivalence.unitInv h) y
[PROOFSTEP]
simp only [Functor.comp_map]
[GOAL]
case mp.intro.allEq
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
this :
  ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
a b : x ⟶ y
⊢ NatTrans.app (Equivalence.unit h) x ≫ h.inverse.map (h.functor.map a) ≫ NatTrans.app (Equivalence.unitInv h) y =
    NatTrans.app (Equivalence.unit h) x ≫ h.inverse.map (h.functor.map b) ≫ NatTrans.app (Equivalence.unitInv h) y
[PROOFSTEP]
congr 3
[GOAL]
case mp.intro.allEq.e_a.e_a.e_a
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
this :
  ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
a b : x ⟶ y
⊢ h.functor.map a = h.functor.map b
[PROOFSTEP]
apply ULift.ext
[GOAL]
case mp.intro.allEq.e_a.e_a.e_a.h
C : Type u
inst✝ : Category.{v, u} C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      (id (NatTrans.app (Equivalence.unit h) x));
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      (id (NatTrans.app (Equivalence.unitInv h) y));
  hx ≫ hy
this :
  ∀ (z : x ⟶ y),
    z = NatTrans.app (Equivalence.unit h) x ≫ (h.functor ⋙ h.inverse).map z ≫ NatTrans.app (Equivalence.unitInv h) y
a b : x ⟶ y
⊢ (h.functor.map a).down = (h.functor.map b).down
[PROOFSTEP]
simp
[GOAL]
case mpr
C : Type u
inst✝ : Category.{v, u} C
⊢ (Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))) → Nonempty (C ≌ Discrete PUnit)
[PROOFSTEP]
rintro ⟨⟨p⟩, h⟩
[GOAL]
case mpr.intro.intro
C : Type u
inst✝ : Category.{v, u} C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
⊢ Nonempty (C ≌ Discrete PUnit)
[PROOFSTEP]
haveI := fun x y => (h x y).some
[GOAL]
case mpr.intro.intro
C : Type u
inst✝ : Category.{v, u} C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
this : (x y : C) → Unique (x ⟶ y)
⊢ Nonempty (C ≌ Discrete PUnit)
[PROOFSTEP]
refine'
  Nonempty.intro
    (CategoryTheory.Equivalence.mk ((Functor.const _).obj ⟨⟨⟩⟩) ((@Functor.const <| Discrete PUnit).obj p) ?_
      (by apply Functor.punitExt))
[GOAL]
C : Type u
inst✝ : Category.{v, u} C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
this : (x y : C) → Unique (x ⟶ y)
⊢ (Functor.const (Discrete PUnit)).obj p ⋙ (Functor.const C).obj { as := PUnit.unit } ≅ 𝟭 (Discrete PUnit)
[PROOFSTEP]
apply Functor.punitExt
[GOAL]
case mpr.intro.intro
C : Type u
inst✝ : Category.{v, u} C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
this : (x y : C) → Unique (x ⟶ y)
⊢ 𝟭 C ≅ (Functor.const C).obj { as := PUnit.unit } ⋙ (Functor.const (Discrete PUnit)).obj p
[PROOFSTEP]
exact
  NatIso.ofComponents fun _ =>
    { hom := default
      inv := default }


[GOAL]
α : Type u
r : α → α → Prop
inst✝ : IsIrrefl α r
a : α
l₁ l₂ : List α
h : Lex r (a :: l₁) (a :: l₂)
⊢ Lex r l₁ l₂
[PROOFSTEP]
cases' h with _ _ _ _ _ h _ _ _ _ h
[GOAL]
case cons
α : Type u
r : α → α → Prop
inst✝ : IsIrrefl α r
a : α
l₁ l₂ : List α
h : Lex r l₁ l₂
⊢ Lex r l₁ l₂
case rel α : Type u r : α → α → Prop inst✝ : IsIrrefl α r a : α l₁ l₂ : List α h : r a a ⊢ Lex r l₁ l₂
[PROOFSTEP]
exacts [h, (irrefl_of r a h).elim]
[GOAL]
α : Type u
r : α → α → Prop
inst✝¹ : IsOrderConnected α r
inst✝ : IsTrichotomous α r
a : α
l₁ : List α
b : α
l₂ l₃ : List α
h : Lex r l₁ l₃
⊢ Lex r (a :: l₁) (b :: l₂) ∨ Lex r (b :: l₂) (a :: l₃)
[PROOFSTEP]
rcases trichotomous_of r a b with (ab | rfl | ab)
[GOAL]
case inl
α : Type u
r : α → α → Prop
inst✝¹ : IsOrderConnected α r
inst✝ : IsTrichotomous α r
a : α
l₁ : List α
b : α
l₂ l₃ : List α
h : Lex r l₁ l₃
ab : r a b
⊢ Lex r (a :: l₁) (b :: l₂) ∨ Lex r (b :: l₂) (a :: l₃)
[PROOFSTEP]
exact Or.inl (rel ab)
[GOAL]
case inr.inl
α : Type u
r : α → α → Prop
inst✝¹ : IsOrderConnected α r
inst✝ : IsTrichotomous α r
a : α
l₁ l₂ l₃ : List α
h : Lex r l₁ l₃
⊢ Lex r (a :: l₁) (a :: l₂) ∨ Lex r (a :: l₂) (a :: l₃)
[PROOFSTEP]
exact (aux _ l₂ _ h).imp cons cons
[GOAL]
case inr.inr
α : Type u
r : α → α → Prop
inst✝¹ : IsOrderConnected α r
inst✝ : IsTrichotomous α r
a : α
l₁ : List α
b : α
l₂ l₃ : List α
h : Lex r l₁ l₃
ab : r b a
⊢ Lex r (a :: l₁) (b :: l₂) ∨ Lex r (b :: l₂) (a :: l₃)
[PROOFSTEP]
exact Or.inr (rel ab)
[GOAL]
α : Type u
r : α → α → Prop
inst✝ : IsTrichotomous α r
a : α
l₁ : List α
b : α
l₂ : List α
⊢ Lex r (a :: l₁) (b :: l₂) ∨ a :: l₁ = b :: l₂ ∨ Lex r (b :: l₂) (a :: l₁)
[PROOFSTEP]
rcases trichotomous_of r a b with (ab | rfl | ab)
[GOAL]
case inl
α : Type u
r : α → α → Prop
inst✝ : IsTrichotomous α r
a : α
l₁ : List α
b : α
l₂ : List α
ab : r a b
⊢ Lex r (a :: l₁) (b :: l₂) ∨ a :: l₁ = b :: l₂ ∨ Lex r (b :: l₂) (a :: l₁)
[PROOFSTEP]
exact Or.inl (rel ab)
[GOAL]
case inr.inl
α : Type u
r : α → α → Prop
inst✝ : IsTrichotomous α r
a : α
l₁ l₂ : List α
⊢ Lex r (a :: l₁) (a :: l₂) ∨ a :: l₁ = a :: l₂ ∨ Lex r (a :: l₂) (a :: l₁)
[PROOFSTEP]
exact (aux l₁ l₂).imp cons (Or.imp (congr_arg _) cons)
[GOAL]
case inr.inr
α : Type u
r : α → α → Prop
inst✝ : IsTrichotomous α r
a : α
l₁ : List α
b : α
l₂ : List α
ab : r b a
⊢ Lex r (a :: l₁) (b :: l₂) ∨ a :: l₁ = b :: l₂ ∨ Lex r (b :: l₂) (a :: l₁)
[PROOFSTEP]
exact Or.inr (Or.inr (rel ab))
[GOAL]
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
l₁ : List α
h : Lex r l₁ []
⊢ False
[PROOFSTEP]
cases h
[GOAL]
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ : List α
b : α
l₂ : List α
⊢ Decidable (Lex r (a :: l₁) (b :: l₂))
[PROOFSTEP]
haveI := decidableRel r l₁ l₂
[GOAL]
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ : List α
b : α
l₂ : List α
this : Decidable (Lex r l₁ l₂)
⊢ Decidable (Lex r (a :: l₁) (b :: l₂))
[PROOFSTEP]
refine' decidable_of_iff (r a b ∨ a = b ∧ Lex r l₁ l₂) ⟨fun h => _, fun h => _⟩
[GOAL]
case refine'_1
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ : List α
b : α
l₂ : List α
this : Decidable (Lex r l₁ l₂)
h : r a b ∨ a = b ∧ Lex r l₁ l₂
⊢ Lex r (a :: l₁) (b :: l₂)
[PROOFSTEP]
rcases h with (h | ⟨rfl, h⟩)
[GOAL]
case refine'_1.inl
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ : List α
b : α
l₂ : List α
this : Decidable (Lex r l₁ l₂)
h : r a b
⊢ Lex r (a :: l₁) (b :: l₂)
[PROOFSTEP]
exact Lex.rel h
[GOAL]
case refine'_1.inr.intro
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ l₂ : List α
this : Decidable (Lex r l₁ l₂)
h : Lex r l₁ l₂
⊢ Lex r (a :: l₁) (a :: l₂)
[PROOFSTEP]
exact Lex.cons h
[GOAL]
case refine'_2
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ : List α
b : α
l₂ : List α
this : Decidable (Lex r l₁ l₂)
h : Lex r (a :: l₁) (b :: l₂)
⊢ r a b ∨ a = b ∧ Lex r l₁ l₂
[PROOFSTEP]
rcases h with (_ | h | h)
[GOAL]
case refine'_2.cons
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ l₂ : List α
this : Decidable (Lex r l₁ l₂)
h : Lex r l₁ l₂
⊢ r a a ∨ a = a ∧ Lex r l₁ l₂
[PROOFSTEP]
exact Or.inr ⟨rfl, h⟩
[GOAL]
case refine'_2.rel
α : Type u
inst✝¹ : DecidableEq α
r : α → α → Prop
inst✝ : DecidableRel r
a : α
l₁ : List α
b : α
l₂ : List α
this : Decidable (Lex r l₁ l₂)
h : r a b
⊢ r a b ∨ a = b ∧ Lex r l₁ l₂
[PROOFSTEP]
exact Or.inl h
[GOAL]
α : Type u
inst✝ : DecidableEq α
l₁ l₂ : List α
H : length l₁ ≤ length l₂
h : l₁ ≠ l₂
⊢ Lex (fun x x_1 => x ≠ x_1) l₁ l₂
[PROOFSTEP]
induction' l₁ with a l₁ IH generalizing l₂
[GOAL]
case nil
α : Type u
inst✝ : DecidableEq α
l₁ l₂✝ : List α
H✝ : length l₁ ≤ length l₂✝
h✝ : l₁ ≠ l₂✝
l₂ : List α
H : length [] ≤ length l₂
h : [] ≠ l₂
⊢ Lex (fun x x_1 => x ≠ x_1) [] l₂
[PROOFSTEP]
cases' l₂ with b l₂
[GOAL]
case cons
α : Type u
inst✝ : DecidableEq α
l₁✝ l₂✝ : List α
H✝ : length l₁✝ ≤ length l₂✝
h✝ : l₁✝ ≠ l₂✝
a : α
l₁ : List α
IH : ∀ {l₂ : List α}, length l₁ ≤ length l₂ → l₁ ≠ l₂ → Lex (fun x x_1 => x ≠ x_1) l₁ l₂
l₂ : List α
H : length (a :: l₁) ≤ length l₂
h : a :: l₁ ≠ l₂
⊢ Lex (fun x x_1 => x ≠ x_1) (a :: l₁) l₂
[PROOFSTEP]
cases' l₂ with b l₂
[GOAL]
case nil.nil
α : Type u
inst✝ : DecidableEq α
l₁ l₂ : List α
H✝ : length l₁ ≤ length l₂
h✝ : l₁ ≠ l₂
H : length [] ≤ length []
h : [] ≠ []
⊢ Lex (fun x x_1 => x ≠ x_1) [] []
[PROOFSTEP]
contradiction
[GOAL]
case nil.cons
α : Type u
inst✝ : DecidableEq α
l₁ l₂✝ : List α
H✝ : length l₁ ≤ length l₂✝
h✝ : l₁ ≠ l₂✝
b : α
l₂ : List α
H : length [] ≤ length (b :: l₂)
h : [] ≠ b :: l₂
⊢ Lex (fun x x_1 => x ≠ x_1) [] (b :: l₂)
[PROOFSTEP]
apply nil
[GOAL]
case cons.nil
α : Type u
inst✝ : DecidableEq α
l₁✝ l₂ : List α
H✝ : length l₁✝ ≤ length l₂
h✝ : l₁✝ ≠ l₂
a : α
l₁ : List α
IH : ∀ {l₂ : List α}, length l₁ ≤ length l₂ → l₁ ≠ l₂ → Lex (fun x x_1 => x ≠ x_1) l₁ l₂
H : length (a :: l₁) ≤ length []
h : a :: l₁ ≠ []
⊢ Lex (fun x x_1 => x ≠ x_1) (a :: l₁) []
[PROOFSTEP]
exact (not_lt_of_ge H).elim (succ_pos _)
[GOAL]
case cons.cons
α : Type u
inst✝ : DecidableEq α
l₁✝ l₂✝ : List α
H✝ : length l₁✝ ≤ length l₂✝
h✝ : l₁✝ ≠ l₂✝
a : α
l₁ : List α
IH : ∀ {l₂ : List α}, length l₁ ≤ length l₂ → l₁ ≠ l₂ → Lex (fun x x_1 => x ≠ x_1) l₁ l₂
b : α
l₂ : List α
H : length (a :: l₁) ≤ length (b :: l₂)
h : a :: l₁ ≠ b :: l₂
⊢ Lex (fun x x_1 => x ≠ x_1) (a :: l₁) (b :: l₂)
[PROOFSTEP]
by_cases ab : a = b
[GOAL]
case pos
α : Type u
inst✝ : DecidableEq α
l₁✝ l₂✝ : List α
H✝ : length l₁✝ ≤ length l₂✝
h✝ : l₁✝ ≠ l₂✝
a : α
l₁ : List α
IH : ∀ {l₂ : List α}, length l₁ ≤ length l₂ → l₁ ≠ l₂ → Lex (fun x x_1 => x ≠ x_1) l₁ l₂
b : α
l₂ : List α
H : length (a :: l₁) ≤ length (b :: l₂)
h : a :: l₁ ≠ b :: l₂
ab : a = b
⊢ Lex (fun x x_1 => x ≠ x_1) (a :: l₁) (b :: l₂)
[PROOFSTEP]
subst b
[GOAL]
case pos
α : Type u
inst✝ : DecidableEq α
l₁✝ l₂✝ : List α
H✝ : length l₁✝ ≤ length l₂✝
h✝ : l₁✝ ≠ l₂✝
a : α
l₁ : List α
IH : ∀ {l₂ : List α}, length l₁ ≤ length l₂ → l₁ ≠ l₂ → Lex (fun x x_1 => x ≠ x_1) l₁ l₂
l₂ : List α
H : length (a :: l₁) ≤ length (a :: l₂)
h : a :: l₁ ≠ a :: l₂
⊢ Lex (fun x x_1 => x ≠ x_1) (a :: l₁) (a :: l₂)
[PROOFSTEP]
apply cons
[GOAL]
case pos.h
α : Type u
inst✝ : DecidableEq α
l₁✝ l₂✝ : List α
H✝ : length l₁✝ ≤ length l₂✝
h✝ : l₁✝ ≠ l₂✝
a : α
l₁ : List α
IH : ∀ {l₂ : List α}, length l₁ ≤ length l₂ → l₁ ≠ l₂ → Lex (fun x x_1 => x ≠ x_1) l₁ l₂
l₂ : List α
H : length (a :: l₁) ≤ length (a :: l₂)
h : a :: l₁ ≠ a :: l₂
⊢ Lex (fun x x_1 => x ≠ x_1) l₁ l₂
[PROOFSTEP]
exact IH (le_of_succ_le_succ H) (mt (congr_arg _) h)
[GOAL]
case neg
α : Type u
inst✝ : DecidableEq α
l₁✝ l₂✝ : List α
H✝ : length l₁✝ ≤ length l₂✝
h✝ : l₁✝ ≠ l₂✝
a : α
l₁ : List α
IH : ∀ {l₂ : List α}, length l₁ ≤ length l₂ → l₁ ≠ l₂ → Lex (fun x x_1 => x ≠ x_1) l₁ l₂
b : α
l₂ : List α
H : length (a :: l₁) ≤ length (b :: l₂)
h : a :: l₁ ≠ b :: l₂
ab : ¬a = b
⊢ Lex (fun x x_1 => x ≠ x_1) (a :: l₁) (b :: l₂)
[PROOFSTEP]
exact rel ab
[GOAL]
α : Type u
l₁ l₂ : List α
H : length l₁ ≤ length l₂
⊢ Lex (fun x x_1 => x ≠ x_1) l₁ l₂ ↔ l₁ ≠ l₂
[PROOFSTEP]
classical exact Decidable.List.Lex.ne_iff H
[GOAL]
α : Type u
l₁ l₂ : List α
H : length l₁ ≤ length l₂
⊢ Lex (fun x x_1 => x ≠ x_1) l₁ l₂ ↔ l₁ ≠ l₂
[PROOFSTEP]
exact Decidable.List.Lex.ne_iff H
[GOAL]
α : Type u
inst✝ : LinearOrder α
l l' : List α
⊢ lt l l' ↔ Lex (fun x x_1 => x < x_1) l l'
[PROOFSTEP]
constructor
[GOAL]
case mp
α : Type u
inst✝ : LinearOrder α
l l' : List α
⊢ lt l l' → Lex (fun x x_1 => x < x_1) l l'
[PROOFSTEP]
intro h
[GOAL]
case mpr
α : Type u
inst✝ : LinearOrder α
l l' : List α
⊢ Lex (fun x x_1 => x < x_1) l l' → lt l l'
[PROOFSTEP]
intro h
[GOAL]
case mp
α : Type u
inst✝ : LinearOrder α
l l' : List α
h : lt l l'
⊢ Lex (fun x x_1 => x < x_1) l l'
[PROOFSTEP]
induction h with
| nil b bs => exact Lex.nil
| @head a as b bs hab => apply Lex.rel; assumption
|
  @tail a as b bs hab hba _ ih =>
  have heq : a = b := _root_.le_antisymm (le_of_not_lt hba) (le_of_not_lt hab)
  subst b; apply Lex.cons; assumption
[GOAL]
case mp
α : Type u
inst✝ : LinearOrder α
l l' : List α
h : lt l l'
⊢ Lex (fun x x_1 => x < x_1) l l'
[PROOFSTEP]
induction h with
| nil b bs => exact Lex.nil
| @head a as b bs hab => apply Lex.rel; assumption
|
  @tail a as b bs hab hba _ ih =>
  have heq : a = b := _root_.le_antisymm (le_of_not_lt hba) (le_of_not_lt hab)
  subst b; apply Lex.cons; assumption
[GOAL]
case mp.nil
α : Type u
inst✝ : LinearOrder α
l l' : List α
b : α
bs : List α
⊢ Lex (fun x x_1 => x < x_1) [] (b :: bs)
[PROOFSTEP]

| nil b bs => exact Lex.nil
[GOAL]
case mp.nil
α : Type u
inst✝ : LinearOrder α
l l' : List α
b : α
bs : List α
⊢ Lex (fun x x_1 => x < x_1) [] (b :: bs)
[PROOFSTEP]
exact Lex.nil
[GOAL]
case mp.head
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
hab : a < b
⊢ Lex (fun x x_1 => x < x_1) (a :: as) (b :: bs)
[PROOFSTEP]

| @head a as b bs hab => apply Lex.rel; assumption
[GOAL]
case mp.head
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
hab : a < b
⊢ Lex (fun x x_1 => x < x_1) (a :: as) (b :: bs)
[PROOFSTEP]
apply Lex.rel
[GOAL]
case mp.head.h
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
hab : a < b
⊢ a < b
[PROOFSTEP]
assumption
[GOAL]
case mp.tail
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
hab : ¬a < b
hba : ¬b < a
a✝ : lt as bs
ih : Lex (fun x x_1 => x < x_1) as bs
⊢ Lex (fun x x_1 => x < x_1) (a :: as) (b :: bs)
[PROOFSTEP]

|
  @tail a as b bs hab hba _ ih =>
  have heq : a = b := _root_.le_antisymm (le_of_not_lt hba) (le_of_not_lt hab)
  subst b; apply Lex.cons; assumption
[GOAL]
case mp.tail
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
hab : ¬a < b
hba : ¬b < a
a✝ : lt as bs
ih : Lex (fun x x_1 => x < x_1) as bs
⊢ Lex (fun x x_1 => x < x_1) (a :: as) (b :: bs)
[PROOFSTEP]
have heq : a = b := _root_.le_antisymm (le_of_not_lt hba) (le_of_not_lt hab)
[GOAL]
case mp.tail
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
hab : ¬a < b
hba : ¬b < a
a✝ : lt as bs
ih : Lex (fun x x_1 => x < x_1) as bs
heq : a = b
⊢ Lex (fun x x_1 => x < x_1) (a :: as) (b :: bs)
[PROOFSTEP]
subst b
[GOAL]
case mp.tail
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as bs : List α
a✝ : lt as bs
ih : Lex (fun x x_1 => x < x_1) as bs
hab hba : ¬a < a
⊢ Lex (fun x x_1 => x < x_1) (a :: as) (a :: bs)
[PROOFSTEP]
apply Lex.cons
[GOAL]
case mp.tail.h
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as bs : List α
a✝ : lt as bs
ih : Lex (fun x x_1 => x < x_1) as bs
hab hba : ¬a < a
⊢ Lex (fun x x_1 => x < x_1) as bs
[PROOFSTEP]
assumption
[GOAL]
case mpr
α : Type u
inst✝ : LinearOrder α
l l' : List α
h : Lex (fun x x_1 => x < x_1) l l'
⊢ lt l l'
[PROOFSTEP]
induction h with
| @nil a as => apply lt.nil
| @cons a as bs _ ih => apply lt.tail <;> simp [ih]
| @rel a as b bs h => apply lt.head; assumption
[GOAL]
case mpr
α : Type u
inst✝ : LinearOrder α
l l' : List α
h : Lex (fun x x_1 => x < x_1) l l'
⊢ lt l l'
[PROOFSTEP]
induction h with
| @nil a as => apply lt.nil
| @cons a as bs _ ih => apply lt.tail <;> simp [ih]
| @rel a as b bs h => apply lt.head; assumption
[GOAL]
case mpr.nil
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
⊢ lt [] (a :: as)
[PROOFSTEP]

| @nil a as => apply lt.nil
[GOAL]
case mpr.nil
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
⊢ lt [] (a :: as)
[PROOFSTEP]
apply lt.nil
[GOAL]
case mpr.cons
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as bs : List α
h✝ : Lex (fun x x_1 => x < x_1) as bs
ih : lt as bs
⊢ lt (a :: as) (a :: bs)
[PROOFSTEP]

| @cons a as bs _ ih => apply lt.tail <;> simp [ih]
[GOAL]
case mpr.cons
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as bs : List α
h✝ : Lex (fun x x_1 => x < x_1) as bs
ih : lt as bs
⊢ lt (a :: as) (a :: bs)
[PROOFSTEP]
apply lt.tail
[GOAL]
case mpr.cons.a
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as bs : List α
h✝ : Lex (fun x x_1 => x < x_1) as bs
ih : lt as bs
⊢ ¬a < a
[PROOFSTEP]
simp [ih]
[GOAL]
case mpr.cons.a
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as bs : List α
h✝ : Lex (fun x x_1 => x < x_1) as bs
ih : lt as bs
⊢ ¬a < a
[PROOFSTEP]
simp [ih]
[GOAL]
case mpr.cons.a
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as bs : List α
h✝ : Lex (fun x x_1 => x < x_1) as bs
ih : lt as bs
⊢ lt as bs
[PROOFSTEP]
simp [ih]
[GOAL]
case mpr.rel
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
h : a < b
⊢ lt (a :: as) (b :: bs)
[PROOFSTEP]

| @rel a as b bs h => apply lt.head; assumption
[GOAL]
case mpr.rel
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
h : a < b
⊢ lt (a :: as) (b :: bs)
[PROOFSTEP]
apply lt.head
[GOAL]
case mpr.rel.a
α : Type u
inst✝ : LinearOrder α
l l' : List α
a : α
as : List α
b : α
bs : List α
h : a < b
⊢ a < b
[PROOFSTEP]
assumption


[GOAL]
α : Type ?u.37
β : Type ?u.40
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
⊢ inst✝¹ ≤ OuterMeasure.caratheodory (OuterMeasure.dirac a)
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : Type ?u.2205
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
h : a ∈ s
⊢ ↑↑(dirac a) s = 1
[PROOFSTEP]
have : ∀ t : Set α, a ∈ t → t.indicator (1 : α → ℝ≥0∞) a = 1 := fun t ht => indicator_of_mem ht 1
[GOAL]
α : Type u_1
β : Type ?u.2205
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
h : a ∈ s
this : ∀ (t : Set α), a ∈ t → indicator t 1 a = 1
⊢ ↑↑(dirac a) s = 1
[PROOFSTEP]
refine' le_antisymm (this univ trivial ▸ _) (this s h ▸ le_dirac_apply)
[GOAL]
α : Type u_1
β : Type ?u.2205
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
h : a ∈ s
this : ∀ (t : Set α), a ∈ t → indicator t 1 a = 1
⊢ ↑↑(dirac a) s ≤ indicator univ 1 a
[PROOFSTEP]
rw [← dirac_apply' a MeasurableSet.univ]
[GOAL]
α : Type u_1
β : Type ?u.2205
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
h : a ∈ s
this : ∀ (t : Set α), a ∈ t → indicator t 1 a = 1
⊢ ↑↑(dirac a) s ≤ ↑↑(dirac a) univ
[PROOFSTEP]
exact measure_mono (subset_univ s)
[GOAL]
α : Type u_1
β : Type ?u.3101
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s✝ : Set α
inst✝ : MeasurableSingletonClass α
a : α
s : Set α
⊢ ↑↑(dirac a) s = indicator s 1 a
[PROOFSTEP]
by_cases h : a ∈ s
[GOAL]
case pos
α : Type u_1
β : Type ?u.3101
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s✝ : Set α
inst✝ : MeasurableSingletonClass α
a : α
s : Set α
h : a ∈ s
⊢ ↑↑(dirac a) s = indicator s 1 a
[PROOFSTEP]
rw [dirac_apply_of_mem h, indicator_of_mem h, Pi.one_apply]
[GOAL]
case neg
α : Type u_1
β : Type ?u.3101
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s✝ : Set α
inst✝ : MeasurableSingletonClass α
a : α
s : Set α
h : ¬a ∈ s
⊢ ↑↑(dirac a) s = indicator s 1 a
[PROOFSTEP]
rw [indicator_of_not_mem h, ← nonpos_iff_eq_zero]
[GOAL]
case neg
α : Type u_1
β : Type ?u.3101
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s✝ : Set α
inst✝ : MeasurableSingletonClass α
a : α
s : Set α
h : ¬a ∈ s
⊢ ↑↑(dirac a) s ≤ 0
[PROOFSTEP]
calc
  dirac a s ≤ dirac a { a }ᶜ := measure_mono (subset_compl_comm.1 <| singleton_subset_iff.2 h)
  _ = 0 := by simp [dirac_apply' _ (measurableSet_singleton _).compl]
[GOAL]
α : Type u_1
β : Type ?u.3101
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s✝ : Set α
inst✝ : MeasurableSingletonClass α
a : α
s : Set α
h : ¬a ∈ s
⊢ ↑↑(dirac a) {a}ᶜ = 0
[PROOFSTEP]
simp [dirac_apply' _ (measurableSet_singleton _).compl]
[GOAL]
α : Type u_2
β : Type u_1
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
f : α → β
hf : Measurable f
a : α
s : Set β
hs : MeasurableSet s
⊢ ↑↑(map f (dirac a)) s = ↑↑(dirac (f a)) s
[PROOFSTEP]
simp [hs, map_apply hf hs, hf hs, indicator_apply]
[GOAL]
α : Type u_1
β : Type ?u.7321
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
μ : Measure α
a : α
⊢ restrict μ {a} = ↑↑μ {a} • dirac a
[PROOFSTEP]
ext1 s hs
[GOAL]
case h
α : Type u_1
β : Type ?u.7321
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
μ : Measure α
a : α
s : Set α
hs : MeasurableSet s
⊢ ↑↑(restrict μ {a}) s = ↑↑(↑↑μ {a} • dirac a) s
[PROOFSTEP]
by_cases ha : a ∈ s
[GOAL]
case pos
α : Type u_1
β : Type ?u.7321
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
μ : Measure α
a : α
s : Set α
hs : MeasurableSet s
ha : a ∈ s
⊢ ↑↑(restrict μ {a}) s = ↑↑(↑↑μ {a} • dirac a) s
[PROOFSTEP]
have : s ∩ { a } = { a } := by simpa
[GOAL]
α : Type u_1
β : Type ?u.7321
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
μ : Measure α
a : α
s : Set α
hs : MeasurableSet s
ha : a ∈ s
⊢ s ∩ {a} = {a}
[PROOFSTEP]
simpa
[GOAL]
case pos
α : Type u_1
β : Type ?u.7321
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
μ : Measure α
a : α
s : Set α
hs : MeasurableSet s
ha : a ∈ s
this : s ∩ {a} = {a}
⊢ ↑↑(restrict μ {a}) s = ↑↑(↑↑μ {a} • dirac a) s
[PROOFSTEP]
simp [*]
[GOAL]
case neg
α : Type u_1
β : Type ?u.7321
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
μ : Measure α
a : α
s : Set α
hs : MeasurableSet s
ha : ¬a ∈ s
⊢ ↑↑(restrict μ {a}) s = ↑↑(↑↑μ {a} • dirac a) s
[PROOFSTEP]
have : s ∩ { a } = ∅ := inter_singleton_eq_empty.2 ha
[GOAL]
case neg
α : Type u_1
β : Type ?u.7321
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
μ : Measure α
a : α
s : Set α
hs : MeasurableSet s
ha : ¬a ∈ s
this : s ∩ {a} = ∅
⊢ ↑↑(restrict μ {a}) s = ↑↑(↑↑μ {a} • dirac a) s
[PROOFSTEP]
simp [*]
[GOAL]
α : Type u_2
β : Type u_1
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s : Set α
inst✝¹ : Countable β
inst✝ : MeasurableSingletonClass β
μ : Measure α
f : α → β
hf : Measurable f
⊢ map f μ = sum fun b => ↑↑μ (f ⁻¹' {b}) • dirac b
[PROOFSTEP]
ext1 s hs
[GOAL]
case h
α : Type u_2
β : Type u_1
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s✝ : Set α
inst✝¹ : Countable β
inst✝ : MeasurableSingletonClass β
μ : Measure α
f : α → β
hf : Measurable f
s : Set β
hs : MeasurableSet s
⊢ ↑↑(map f μ) s = ↑↑(sum fun b => ↑↑μ (f ⁻¹' {b}) • dirac b) s
[PROOFSTEP]
have : ∀ y ∈ s, MeasurableSet (f ⁻¹' { y }) := fun y _ => hf (measurableSet_singleton _)
[GOAL]
case h
α : Type u_2
β : Type u_1
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s✝ : Set α
inst✝¹ : Countable β
inst✝ : MeasurableSingletonClass β
μ : Measure α
f : α → β
hf : Measurable f
s : Set β
hs : MeasurableSet s
this : ∀ (y : β), y ∈ s → MeasurableSet (f ⁻¹' {y})
⊢ ↑↑(map f μ) s = ↑↑(sum fun b => ↑↑μ (f ⁻¹' {b}) • dirac b) s
[PROOFSTEP]
simp [← tsum_measure_preimage_singleton (to_countable s) this, *, tsum_subtype s fun b => μ (f ⁻¹' { b }), ←
  indicator_mul_right s fun b => μ (f ⁻¹' { b })]
[GOAL]
α : Type u_1
β : Type ?u.17308
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s : Set α
inst✝¹ : Countable α
inst✝ : MeasurableSingletonClass α
μ : Measure α
⊢ (sum fun a => ↑↑μ {a} • dirac a) = μ
[PROOFSTEP]
simpa using (map_eq_sum μ id measurable_id).symm
[GOAL]
α : Type u_1
β : Type ?u.19567
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s✝ : Set α
inst✝¹ : Countable α
inst✝ : MeasurableSingletonClass α
μ : Measure α
s : Set α
hs : MeasurableSet s
⊢ ∑' (x : α), indicator s (fun x => ↑↑μ {x}) x = ↑↑(sum fun a => ↑↑μ {a} • dirac a) s
[PROOFSTEP]
simp only [Measure.sum_apply _ hs, Measure.smul_apply, smul_eq_mul, Measure.dirac_apply, Set.indicator_apply, mul_ite,
  Pi.one_apply, mul_one, mul_zero]
[GOAL]
α : Type u_1
β : Type ?u.19567
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s✝ : Set α
inst✝¹ : Countable α
inst✝ : MeasurableSingletonClass α
μ : Measure α
s : Set α
hs : MeasurableSet s
⊢ ↑↑(sum fun a => ↑↑μ {a} • dirac a) s = ↑↑μ s
[PROOFSTEP]
rw [μ.sum_smul_dirac]
[GOAL]
α : Type u_1
β : Type ?u.22509
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
⊢ s ∈ ae (dirac a) ↔ a ∈ s
[PROOFSTEP]
by_cases a ∈ s
[GOAL]
α : Type u_1
β : Type ?u.22509
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
⊢ s ∈ ae (dirac a) ↔ a ∈ s
[PROOFSTEP]
by_cases a ∈ s
[GOAL]
case pos
α : Type u_1
β : Type ?u.22509
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
h : a ∈ s
⊢ s ∈ ae (dirac a) ↔ a ∈ s
[PROOFSTEP]
simp [mem_ae_iff, dirac_apply', hs.compl, indicator_apply, *]
[GOAL]
case neg
α : Type u_1
β : Type ?u.22509
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
h : ¬a ∈ s
⊢ s ∈ ae (dirac a) ↔ a ∈ s
[PROOFSTEP]
simp [mem_ae_iff, dirac_apply', hs.compl, indicator_apply, *]
[GOAL]
α : Type u_1
β : Type ?u.24298
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
inst✝ : MeasurableSingletonClass α
a : α
⊢ ae (dirac a) = pure a
[PROOFSTEP]
ext s
[GOAL]
case a
α : Type u_1
β : Type ?u.24298
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s✝ : Set α
inst✝ : MeasurableSingletonClass α
a : α
s : Set α
⊢ s ∈ ae (dirac a) ↔ s ∈ pure a
[PROOFSTEP]
simp [mem_ae_iff, imp_false]
[GOAL]
α : Type u_2
β : Type ?u.26464
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
δ : Type u_1
inst✝ : MeasurableSingletonClass α
a : α
f : α → δ
⊢ f =ᶠ[ae (dirac a)] const α (f a)
[PROOFSTEP]
simp [Filter.EventuallyEq]
[GOAL]
α : Type u_1
β : Type ?u.27478
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
inst✝ : Decidable (a ∈ s)
⊢ Measure.restrict (dirac a) s = if a ∈ s then dirac a else 0
[PROOFSTEP]
split_ifs with has
[GOAL]
case pos
α : Type u_1
β : Type ?u.27478
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
inst✝ : Decidable (a ∈ s)
has : a ∈ s
⊢ Measure.restrict (dirac a) s = dirac a
[PROOFSTEP]
apply restrict_eq_self_of_ae_mem
[GOAL]
case pos.hs
α : Type u_1
β : Type ?u.27478
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
inst✝ : Decidable (a ∈ s)
has : a ∈ s
⊢ ∀ᵐ (x : α) ∂dirac a, x ∈ s
[PROOFSTEP]
rw [ae_dirac_iff]
[GOAL]
case pos.hs
α : Type u_1
β : Type ?u.27478
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
inst✝ : Decidable (a ∈ s)
has : a ∈ s
⊢ a ∈ s
[PROOFSTEP]
assumption
[GOAL]
case pos.hs
α : Type u_1
β : Type ?u.27478
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
inst✝ : Decidable (a ∈ s)
has : a ∈ s
⊢ MeasurableSet {x | x ∈ s}
[PROOFSTEP]
assumption
[GOAL]
case neg
α : Type u_1
β : Type ?u.27478
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
a : α
hs : MeasurableSet s
inst✝ : Decidable (a ∈ s)
has : ¬a ∈ s
⊢ Measure.restrict (dirac a) s = 0
[PROOFSTEP]
rw [restrict_eq_zero, dirac_apply' _ hs, indicator_of_not_mem has]
[GOAL]
α : Type u_1
β : Type ?u.28375
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s : Set α
a : α
inst✝¹ : MeasurableSingletonClass α
inst✝ : Decidable (a ∈ s)
⊢ Measure.restrict (dirac a) s = if a ∈ s then dirac a else 0
[PROOFSTEP]
split_ifs with has
[GOAL]
case pos
α : Type u_1
β : Type ?u.28375
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s : Set α
a : α
inst✝¹ : MeasurableSingletonClass α
inst✝ : Decidable (a ∈ s)
has : a ∈ s
⊢ Measure.restrict (dirac a) s = dirac a
[PROOFSTEP]
apply restrict_eq_self_of_ae_mem
[GOAL]
case pos.hs
α : Type u_1
β : Type ?u.28375
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s : Set α
a : α
inst✝¹ : MeasurableSingletonClass α
inst✝ : Decidable (a ∈ s)
has : a ∈ s
⊢ ∀ᵐ (x : α) ∂dirac a, x ∈ s
[PROOFSTEP]
rwa [ae_dirac_eq]
[GOAL]
case neg
α : Type u_1
β : Type ?u.28375
inst✝³ : MeasurableSpace α
inst✝² : MeasurableSpace β
s : Set α
a : α
inst✝¹ : MeasurableSingletonClass α
inst✝ : Decidable (a ∈ s)
has : ¬a ∈ s
⊢ Measure.restrict (dirac a) s = 0
[PROOFSTEP]
rw [restrict_eq_zero, dirac_apply, indicator_of_not_mem has]