[GOAL]
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : CommSemiring S
inst✝ : Nontrivial R
⊢ ¬Separable 0
[PROOFSTEP]
rintro ⟨x, y, h⟩
[GOAL]
case intro.intro
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : CommSemiring S
inst✝ : Nontrivial R
x y : R[X]
h : x * 0 + y * ↑derivative 0 = 1
⊢ False
[PROOFSTEP]
simp only [derivative_zero, mul_zero, add_zero, zero_ne_one] at h
[GOAL]
R : Type u
inst✝² : CommSemiring R
S : Type v
inst✝¹ : CommSemiring S
inst✝ : Subsingleton R
f : R[X]
⊢ Separable f
[PROOFSTEP]
simp [Separable, IsCoprime]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
a : R
⊢ Separable (X + ↑C a)
[PROOFSTEP]
rw [separable_def, derivative_add, derivative_X, derivative_C, add_zero]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
a : R
⊢ IsCoprime (X + ↑C a) 1
[PROOFSTEP]
exact isCoprime_one_right
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
⊢ Separable X
[PROOFSTEP]
rw [separable_def, derivative_X]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
⊢ IsCoprime X 1
[PROOFSTEP]
exact isCoprime_one_right
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
r : R
⊢ Separable (↑C r) ↔ IsUnit r
[PROOFSTEP]
rw [separable_def, derivative_C, isCoprime_zero_right, isUnit_C]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (f * g)
⊢ Separable f
[PROOFSTEP]
have := h.of_mul_left_left
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (f * g)
this : IsCoprime f (↑derivative (f * g))
⊢ Separable f
[PROOFSTEP]
rw [derivative_mul] at this
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (f * g)
this : IsCoprime f (↑derivative f * g + f * ↑derivative g)
⊢ Separable f
[PROOFSTEP]
exact IsCoprime.of_mul_right_left (IsCoprime.of_add_mul_left_right this)
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (f * g)
⊢ Separable g
[PROOFSTEP]
rw [mul_comm] at h
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (g * f)
⊢ Separable g
[PROOFSTEP]
exact h.of_mul_left
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
hf : Separable f
hfg : g ∣ f
⊢ Separable g
[PROOFSTEP]
rcases hfg with ⟨f', rfl⟩
[GOAL]
case intro
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
g f' : R[X]
hf : Separable (g * f')
⊢ Separable g
[PROOFSTEP]
exact Separable.of_mul_left hf
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (f * g)
⊢ IsCoprime f g
[PROOFSTEP]
have := h.of_mul_left_left
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (f * g)
this : IsCoprime f (↑derivative (f * g))
⊢ IsCoprime f g
[PROOFSTEP]
rw [derivative_mul] at this
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f g : R[X]
h : Separable (f * g)
this : IsCoprime f (↑derivative f * g + f * ↑derivative g)
⊢ IsCoprime f g
[PROOFSTEP]
exact IsCoprime.of_mul_right_right (IsCoprime.of_add_mul_left_right this)
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f : R[X]
n : ℕ
h : Separable (f ^ (n + 2))
⊢ IsUnit f ∨ Separable f ∧ n + 2 = 1 ∨ n + 2 = 0
[PROOFSTEP]
rw [pow_succ, pow_succ] at h
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
f : R[X]
n : ℕ
h : Separable (f * (f * f ^ n))
⊢ IsUnit f ∨ Separable f ∧ n + 2 = 1 ∨ n + 2 = 0
[PROOFSTEP]
exact Or.inl (isCoprime_self.1 h.isCoprime.of_mul_right_left)
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p : R[X]
h : Separable p
f : R →+* S
a b : R[X]
H : a * p + b * ↑derivative p = 1
⊢ Polynomial.map f a * Polynomial.map f p + Polynomial.map f b * ↑derivative (Polynomial.map f p) = 1
[PROOFSTEP]
rw [derivative_map, ← Polynomial.map_mul, ← Polynomial.map_mul, ← Polynomial.map_add, H, Polynomial.map_one]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hp : Separable p
hq : q * q ∣ p
⊢ IsUnit q
[PROOFSTEP]
obtain ⟨p, rfl⟩ := hq
[GOAL]
case intro
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : Separable (q * q * p)
⊢ IsUnit q
[PROOFSTEP]
apply isCoprime_self.mp
[GOAL]
case intro
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : Separable (q * q * p)
⊢ IsCoprime q q
[PROOFSTEP]
have : IsCoprime (q * (q * p)) (q * (derivative q * p + derivative q * p + q * derivative p)) :=
  by
  simp only [← mul_assoc, mul_add]
  dsimp only [Separable] at hp
  convert hp using 1
  rw [derivative_mul, derivative_mul]
  ring
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : Separable (q * q * p)
⊢ IsCoprime (q * (q * p)) (q * (↑derivative q * p + ↑derivative q * p + q * ↑derivative p))
[PROOFSTEP]
simp only [← mul_assoc, mul_add]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : Separable (q * q * p)
⊢ IsCoprime (q * q * p) (q * ↑derivative q * p + q * ↑derivative q * p + q * q * ↑derivative p)
[PROOFSTEP]
dsimp only [Separable] at hp
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : IsCoprime (q * q * p) (↑derivative (q * q * p))
⊢ IsCoprime (q * q * p) (q * ↑derivative q * p + q * ↑derivative q * p + q * q * ↑derivative p)
[PROOFSTEP]
convert hp using 1
[GOAL]
case h.e'_4
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : IsCoprime (q * q * p) (↑derivative (q * q * p))
⊢ q * ↑derivative q * p + q * ↑derivative q * p + q * q * ↑derivative p = ↑derivative (q * q * p)
[PROOFSTEP]
rw [derivative_mul, derivative_mul]
[GOAL]
case h.e'_4
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : IsCoprime (q * q * p) (↑derivative (q * q * p))
⊢ q * ↑derivative q * p + q * ↑derivative q * p + q * q * ↑derivative p =
    (↑derivative q * q + q * ↑derivative q) * p + q * q * ↑derivative p
[PROOFSTEP]
ring
[GOAL]
case intro
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
q p : R[X]
hp : Separable (q * q * p)
this : IsCoprime (q * (q * p)) (q * (↑derivative q * p + ↑derivative q * p + q * ↑derivative p))
⊢ IsCoprime q q
[PROOFSTEP]
exact IsCoprime.of_mul_right_left (IsCoprime.of_mul_left_left this)
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hq : ¬IsUnit q
hsep : Separable p
⊢ multiplicity q p ≤ 1
[PROOFSTEP]
contrapose! hq
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hsep : Separable p
hq : 1 < multiplicity q p
⊢ IsUnit q
[PROOFSTEP]
apply isUnit_of_self_mul_dvd_separable hsep
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hsep : Separable p
hq : 1 < multiplicity q p
⊢ q * q ∣ p
[PROOFSTEP]
rw [← sq]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hsep : Separable p
hq : 1 < multiplicity q p
⊢ q ^ 2 ∣ p
[PROOFSTEP]
apply multiplicity.pow_dvd_of_le_multiplicity
[GOAL]
case a
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hsep : Separable p
hq : 1 < multiplicity q p
⊢ ↑2 ≤ multiplicity q p
[PROOFSTEP]
have h : ⟨Part.Dom 1 ∧ Part.Dom 1, fun _ ↦ 2⟩ ≤ multiplicity q p := PartENat.add_one_le_of_lt hq
[GOAL]
case a
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hsep : Separable p
hq : 1 < multiplicity q p
h : { Dom := 1.Dom ∧ 1.Dom, get := fun x => 2 } ≤ multiplicity q p
⊢ ↑2 ≤ multiplicity q p
[PROOFSTEP]
rw [and_self] at h
[GOAL]
case a
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q✝ : ℕ
p q : R[X]
hsep : Separable p
hq : 1 < multiplicity q p
h : { Dom := 1.Dom, get := fun x => 2 } ≤ multiplicity q p
⊢ ↑2 ≤ multiplicity q p
[PROOFSTEP]
exact h
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q : ℕ
p : R[X]
hsep : Separable p
⊢ Squarefree p
[PROOFSTEP]
rw [multiplicity.squarefree_iff_multiplicity_le_one p]
[GOAL]
R : Type u
inst✝¹ : CommSemiring R
S : Type v
inst✝ : CommSemiring S
p✝ q : ℕ
p : R[X]
hsep : Separable p
⊢ ∀ (x : R[X]), multiplicity x p ≤ 1 ∨ IsUnit x
[PROOFSTEP]
exact fun f => or_iff_not_imp_right.mpr fun hunit => multiplicity_le_one_of_separable hunit hsep
[GOAL]
R : Type u
inst✝ : CommRing R
x : R
⊢ Separable (X - ↑C x)
[PROOFSTEP]
simpa only [sub_eq_add_neg, C_neg] using separable_X_add_C (-x)
[GOAL]
R : Type u
inst✝ : CommRing R
f g : R[X]
hf : Separable f
hg : Separable g
h : IsCoprime f g
⊢ Separable (f * g)
[PROOFSTEP]
rw [separable_def, derivative_mul]
[GOAL]
R : Type u
inst✝ : CommRing R
f g : R[X]
hf : Separable f
hg : Separable g
h : IsCoprime f g
⊢ IsCoprime (f * g) (↑derivative f * g + f * ↑derivative g)
[PROOFSTEP]
exact ((hf.mul_right h).add_mul_left_right _).mul_left ((h.symm.mul_right hg).mul_add_right_right _)
[GOAL]
R : Type u
inst✝ : CommRing R
ι : Type u_1
f : ι → R[X]
s✝ : Finset ι
a : ι
s : Finset ι
has : ¬a ∈ s
ih :
  (∀ (x : ι), x ∈ s → ∀ (y : ι), y ∈ s → x ≠ y → IsCoprime (f x) (f y)) →
    (∀ (x : ι), x ∈ s → Separable (f x)) → Separable (∏ x in s, f x)
h1 : ∀ (x : ι), x ∈ insert a s → ∀ (y : ι), y ∈ insert a s → x ≠ y → IsCoprime (f x) (f y)
h2 : ∀ (x : ι), x ∈ insert a s → Separable (f x)
⊢ Separable (∏ x in insert a s, f x)
[PROOFSTEP]
simp_rw [Finset.forall_mem_insert, forall_and] at h1 h2
[GOAL]
R : Type u
inst✝ : CommRing R
ι : Type u_1
f : ι → R[X]
s✝ : Finset ι
a : ι
s : Finset ι
has : ¬a ∈ s
ih :
  (∀ (x : ι), x ∈ s → ∀ (y : ι), y ∈ s → x ≠ y → IsCoprime (f x) (f y)) →
    (∀ (x : ι), x ∈ s → Separable (f x)) → Separable (∏ x in s, f x)
h2 : Separable (f a) ∧ ∀ (x : ι), x ∈ s → Separable (f x)
h1 :
  ((a ≠ a → IsCoprime (f a) (f a)) ∧ ∀ (x : ι), x ∈ s → a ≠ x → IsCoprime (f a) (f x)) ∧
    (∀ (x : ι), x ∈ s → x ≠ a → IsCoprime (f x) (f a)) ∧
      ∀ (x : ι), x ∈ s → ∀ (x_2 : ι), x_2 ∈ s → x ≠ x_2 → IsCoprime (f x) (f x_2)
⊢ Separable (∏ x in insert a s, f x)
[PROOFSTEP]
rw [prod_insert has]
[GOAL]
R : Type u
inst✝ : CommRing R
ι : Type u_1
f : ι → R[X]
s✝ : Finset ι
a : ι
s : Finset ι
has : ¬a ∈ s
ih :
  (∀ (x : ι), x ∈ s → ∀ (y : ι), y ∈ s → x ≠ y → IsCoprime (f x) (f y)) →
    (∀ (x : ι), x ∈ s → Separable (f x)) → Separable (∏ x in s, f x)
h2 : Separable (f a) ∧ ∀ (x : ι), x ∈ s → Separable (f x)
h1 :
  ((a ≠ a → IsCoprime (f a) (f a)) ∧ ∀ (x : ι), x ∈ s → a ≠ x → IsCoprime (f a) (f x)) ∧
    (∀ (x : ι), x ∈ s → x ≠ a → IsCoprime (f x) (f a)) ∧
      ∀ (x : ι), x ∈ s → ∀ (x_2 : ι), x_2 ∈ s → x ≠ x_2 → IsCoprime (f x) (f x_2)
⊢ Separable (f a * ∏ x in s, f x)
[PROOFSTEP]
exact
  h2.1.mul (ih h1.2.2 h2.2) (IsCoprime.prod_right fun i his => h1.1.2 i his <| Ne.symm <| ne_of_mem_of_not_mem his has)
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
ι : Type u_1
f : ι → R
s : Finset ι
hfs : Separable (∏ i in s, (X - ↑C (f i)))
x y : ι
hx : x ∈ s
hy : y ∈ s
hfxy : f x = f y
⊢ x = y
[PROOFSTEP]
by_contra hxy
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
ι : Type u_1
f : ι → R
s : Finset ι
hfs : Separable (∏ i in s, (X - ↑C (f i)))
x y : ι
hx : x ∈ s
hy : y ∈ s
hfxy : f x = f y
hxy : ¬x = y
⊢ False
[PROOFSTEP]
rw [← insert_erase hx, prod_insert (not_mem_erase _ _), ← insert_erase (mem_erase_of_ne_of_mem (Ne.symm hxy) hy),
  prod_insert (not_mem_erase _ _), ← mul_assoc, hfxy, ← sq] at hfs
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
ι : Type u_1
f : ι → R
s : Finset ι
x y : ι
hfs : Separable ((X - ↑C (f y)) ^ 2 * ∏ x in Finset.erase (Finset.erase s x) y, (X - ↑C (f x)))
hx : x ∈ s
hy : y ∈ s
hfxy : f x = f y
hxy : ¬x = y
⊢ False
[PROOFSTEP]
cases (hfs.of_mul_left.of_pow (not_isUnit_X_sub_C _) two_ne_zero).2
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
s : Multiset R
hs : Separable (Multiset.prod (Multiset.map (fun a => X - ↑C a) s))
⊢ Multiset.Nodup s
[PROOFSTEP]
rw [Multiset.nodup_iff_ne_cons_cons]
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
s : Multiset R
hs : Separable (Multiset.prod (Multiset.map (fun a => X - ↑C a) s))
⊢ ∀ (a : R) (t : Multiset R), s ≠ a ::ₘ a ::ₘ t
[PROOFSTEP]
rintro a t rfl
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
a : R
t : Multiset R
hs : Separable (Multiset.prod (Multiset.map (fun a => X - ↑C a) (a ::ₘ a ::ₘ t)))
⊢ False
[PROOFSTEP]
refine' not_isUnit_X_sub_C a (isUnit_of_self_mul_dvd_separable hs _)
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
a : R
t : Multiset R
hs : Separable (Multiset.prod (Multiset.map (fun a => X - ↑C a) (a ::ₘ a ::ₘ t)))
⊢ (X - ↑C a) * (X - ↑C a) ∣ Multiset.prod (Multiset.map (fun a => X - ↑C a) (a ::ₘ a ::ₘ t))
[PROOFSTEP]
simpa only [Multiset.map_cons, Multiset.prod_cons] using mul_dvd_mul_left _ (dvd_mul_right _ _)
[GOAL]
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
⊢ Separable (X ^ n - ↑C ↑u)
[PROOFSTEP]
nontriviality R
[GOAL]
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
⊢ Separable (X ^ n - ↑C ↑u)
[PROOFSTEP]
rcases n.eq_zero_or_pos with (rfl | hpos)
[GOAL]
case inl
R : Type u
inst✝ : CommRing R
u : Rˣ
✝ : Nontrivial R
hn : IsUnit ↑0
⊢ Separable (X ^ 0 - ↑C ↑u)
[PROOFSTEP]
simp at hn
[GOAL]
case inr
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
⊢ Separable (X ^ n - ↑C ↑u)
[PROOFSTEP]
apply (separable_def' (X ^ n - C (u : R))).2
[GOAL]
case inr
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
⊢ ∃ a b, a * (X ^ n - ↑C ↑u) + b * ↑derivative (X ^ n - ↑C ↑u) = 1
[PROOFSTEP]
obtain ⟨n', hn'⟩ := hn.exists_left_inv
[GOAL]
case inr.intro
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
n' : R
hn' : n' * ↑n = 1
⊢ ∃ a b, a * (X ^ n - ↑C ↑u) + b * ↑derivative (X ^ n - ↑C ↑u) = 1
[PROOFSTEP]
refine' ⟨-C ↑u⁻¹, C (↑u⁻¹ : R) * C n' * X, _⟩
[GOAL]
case inr.intro
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
n' : R
hn' : n' * ↑n = 1
⊢ -↑C ↑u⁻¹ * (X ^ n - ↑C ↑u) + ↑C ↑u⁻¹ * ↑C n' * X * ↑derivative (X ^ n - ↑C ↑u) = 1
[PROOFSTEP]
rw [derivative_sub, derivative_C, sub_zero, derivative_pow X n, derivative_X, mul_one]
[GOAL]
case inr.intro
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
n' : R
hn' : n' * ↑n = 1
⊢ -↑C ↑u⁻¹ * (X ^ n - ↑C ↑u) + ↑C ↑u⁻¹ * ↑C n' * X * (↑C ↑n * X ^ (n - 1)) = 1
[PROOFSTEP]
calc
  -C ↑u⁻¹ * (X ^ n - C ↑u) + C ↑u⁻¹ * C n' * X * (↑n * X ^ (n - 1)) =
      C (↑u⁻¹ * ↑u) - C ↑u⁻¹ * X ^ n + C ↑u⁻¹ * C (n' * ↑n) * (X * X ^ (n - 1)) :=
    by
    simp only [C.map_mul, C_eq_nat_cast]
    ring
  _ = 1 := by
    simp only [Units.inv_mul, hn', C.map_one, mul_one, ← pow_succ, Nat.sub_add_cancel (show 1 ≤ n from hpos),
      sub_add_cancel]
[GOAL]
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
n' : R
hn' : n' * ↑n = 1
⊢ -↑C ↑u⁻¹ * (X ^ n - ↑C ↑u) + ↑C ↑u⁻¹ * ↑C n' * X * (↑n * X ^ (n - 1)) =
    ↑C (↑u⁻¹ * ↑u) - ↑C ↑u⁻¹ * X ^ n + ↑C ↑u⁻¹ * ↑C (n' * ↑n) * (X * X ^ (n - 1))
[PROOFSTEP]
simp only [C.map_mul, C_eq_nat_cast]
[GOAL]
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
n' : R
hn' : n' * ↑n = 1
⊢ -↑C ↑u⁻¹ * (X ^ n - ↑C ↑u) + ↑C ↑u⁻¹ * ↑C n' * X * (↑n * X ^ (n - 1)) =
    ↑C ↑u⁻¹ * ↑C ↑u - ↑C ↑u⁻¹ * X ^ n + ↑C ↑u⁻¹ * (↑C n' * ↑n) * (X * X ^ (n - 1))
[PROOFSTEP]
ring
[GOAL]
R : Type u
inst✝ : CommRing R
n : ℕ
u : Rˣ
hn : IsUnit ↑n
✝ : Nontrivial R
hpos : n > 0
n' : R
hn' : n' * ↑n = 1
⊢ ↑C (↑u⁻¹ * ↑u) - ↑C ↑u⁻¹ * X ^ n + ↑C ↑u⁻¹ * ↑C (n' * ↑n) * (X * X ^ (n - 1)) = 1
[PROOFSTEP]
simp only [Units.inv_mul, hn', C.map_one, mul_one, ← pow_succ, Nat.sub_add_cancel (show 1 ≤ n from hpos),
  sub_add_cancel]
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
p : R[X]
hsep : Separable p
x : R
⊢ rootMultiplicity x p ≤ 1
[PROOFSTEP]
by_cases hp : p = 0
[GOAL]
case pos
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
p : R[X]
hsep : Separable p
x : R
hp : p = 0
⊢ rootMultiplicity x p ≤ 1
[PROOFSTEP]
simp [hp]
[GOAL]
case neg
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
p : R[X]
hsep : Separable p
x : R
hp : ¬p = 0
⊢ rootMultiplicity x p ≤ 1
[PROOFSTEP]
rw [rootMultiplicity_eq_multiplicity, dif_neg hp, ← PartENat.coe_le_coe, PartENat.natCast_get, Nat.cast_one]
[GOAL]
case neg
R : Type u
inst✝¹ : CommRing R
inst✝ : Nontrivial R
p : R[X]
hsep : Separable p
x : R
hp : ¬p = 0
⊢ multiplicity (X - ↑C x) p ≤ 1
[PROOFSTEP]
exact multiplicity_le_one_of_separable (not_isUnit_X_sub_C _) hsep
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsDomain R
p : R[X]
hsep : Separable p
x : R
⊢ Multiset.count x (roots p) ≤ 1
[PROOFSTEP]
rw [count_roots p]
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsDomain R
p : R[X]
hsep : Separable p
x : R
⊢ rootMultiplicity x p ≤ 1
[PROOFSTEP]
exact rootMultiplicity_le_one_of_separable hsep x
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
h : ↑derivative f ≠ 0
g : F[X]
hg1 : g ∈ nonunits F[X]
_hg2 : g ≠ 0
x✝ : g ∣ f
hg4 : g ∣ ↑derivative f
p : F[X]
hg3 : f = g * p
u : F[X]ˣ
hu : ↑u = p
⊢ f ∣ ↑derivative f
[PROOFSTEP]
conv_lhs => rw [hg3, ← hu]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
h : ↑derivative f ≠ 0
g : F[X]
hg1 : g ∈ nonunits F[X]
_hg2 : g ≠ 0
x✝ : g ∣ f
hg4 : g ∣ ↑derivative f
p : F[X]
hg3 : f = g * p
u : F[X]ˣ
hu : ↑u = p
| f
[PROOFSTEP]
rw [hg3, ← hu]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
h : ↑derivative f ≠ 0
g : F[X]
hg1 : g ∈ nonunits F[X]
_hg2 : g ≠ 0
x✝ : g ∣ f
hg4 : g ∣ ↑derivative f
p : F[X]
hg3 : f = g * p
u : F[X]ˣ
hu : ↑u = p
| f
[PROOFSTEP]
rw [hg3, ← hu]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
h : ↑derivative f ≠ 0
g : F[X]
hg1 : g ∈ nonunits F[X]
_hg2 : g ≠ 0
x✝ : g ∣ f
hg4 : g ∣ ↑derivative f
p : F[X]
hg3 : f = g * p
u : F[X]ˣ
hu : ↑u = p
| f
[PROOFSTEP]
rw [hg3, ← hu]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
h : ↑derivative f ≠ 0
g : F[X]
hg1 : g ∈ nonunits F[X]
_hg2 : g ≠ 0
x✝ : g ∣ f
hg4 : g ∣ ↑derivative f
p : F[X]
hg3 : f = g * p
u : F[X]ˣ
hu : ↑u = p
⊢ g * ↑u ∣ ↑derivative f
[PROOFSTEP]
rwa [Units.mul_right_dvd]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F →+* K
p : F[X]
⊢ Separable (map f p) ↔ Separable p
[PROOFSTEP]
simp_rw [separable_def, derivative_map, isCoprime_map]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
ι : Type u_1
f : ι → F
s : Finset ι
H : ∀ (x : ι), x ∈ s → ∀ (y : ι), y ∈ s → f x = f y → x = y
⊢ Separable (∏ i in s, (X - ↑C (f i)))
[PROOFSTEP]
rw [← prod_attach]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
ι : Type u_1
f : ι → F
s : Finset ι
H : ∀ (x : ι), x ∈ s → ∀ (y : ι), y ∈ s → f x = f y → x = y
⊢ Separable (∏ x in attach s, (X - ↑C (f ↑x)))
[PROOFSTEP]
exact
  separable_prod'
    (fun x _hx y _hy hxy =>
      @pairwise_coprime_X_sub_C _ _ { x // x ∈ s } (fun x => f x) (fun x y hxy => Subtype.eq <| H x.1 x.2 y.1 y.2 hxy) _
        _ hxy)
    fun _ _ => separable_X_sub_C
[GOAL]
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
ι : Type u_1
inst✝ : Fintype ι
f : ι → F
⊢ (∀ (x : ι), x ∈ univ → ∀ (y : ι), y ∈ univ → f x = f y → x = y) ↔ Function.Injective f
[PROOFSTEP]
simp_rw [mem_univ, true_imp_iff, Function.Injective]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
⊢ Separable f ∨ ¬Separable f ∧ ∃ g, Irreducible g ∧ ↑(expand F p) g = f
[PROOFSTEP]
rcases p.eq_zero_or_pos with (rfl | hp)
[GOAL]
case inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
HF : CharP F 0
⊢ Separable f ∨ ¬Separable f ∧ ∃ g, Irreducible g ∧ ↑(expand F 0) g = f
[PROOFSTEP]
haveI := CharP.charP_to_charZero F
[GOAL]
case inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
HF : CharP F 0
this : CharZero F
⊢ Separable f ∨ ¬Separable f ∧ ∃ g, Irreducible g ∧ ↑(expand F 0) g = f
[PROOFSTEP]
have := natDegree_eq_zero_of_derivative_eq_zero H
[GOAL]
case inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
HF : CharP F 0
this✝ : CharZero F
this : natDegree f = 0
⊢ Separable f ∨ ¬Separable f ∧ ∃ g, Irreducible g ∧ ↑(expand F 0) g = f
[PROOFSTEP]
have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne'
[GOAL]
case inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
HF : CharP F 0
this✝¹ : CharZero F
this✝ : natDegree f = 0
this : natDegree f ≠ 0
⊢ Separable f ∨ ¬Separable f ∧ ∃ g, Irreducible g ∧ ↑(expand F 0) g = f
[PROOFSTEP]
contradiction
[GOAL]
case inr
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
hp : p > 0
⊢ Separable f ∨ ¬Separable f ∧ ∃ g, Irreducible g ∧ ↑(expand F p) g = f
[PROOFSTEP]
haveI := isLocalRingHom_expand F hp
[GOAL]
case inr
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
hp : p > 0
this : IsLocalRingHom ↑(expand F p)
⊢ Separable f ∨ ¬Separable f ∧ ∃ g, Irreducible g ∧ ↑(expand F p) g = f
[PROOFSTEP]
exact
  Or.inr
    ⟨by rw [separable_iff_derivative_ne_zero hf, Classical.not_not, H], contract p f,
      of_irreducible_map (expand F p : F[X] →+* F[X]) (by rwa [← expand_contract p H hp.ne'] at hf ),
      expand_contract p H hp.ne'⟩
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
hp : p > 0
this : IsLocalRingHom ↑(expand F p)
⊢ ¬Separable f
[PROOFSTEP]
rw [separable_iff_derivative_ne_zero hf, Classical.not_not, H]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
H : ↑derivative f = 0
hp : p > 0
this : IsLocalRingHom ↑(expand F p)
⊢ Irreducible (↑↑(expand F p) (contract p f))
[PROOFSTEP]
rwa [← expand_contract p H hp.ne'] at hf
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : p ≠ 0
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : Nat.Prime p
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
[GOAL]
case h
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
N : ℕ
ih : ∀ (m : ℕ), m < N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
f : F[X]
hf : Irreducible f
hn : natDegree f = N
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
[GOAL]
case h.inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
N : ℕ
ih : ∀ (m : ℕ), m < N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
f : F[X]
hf : Irreducible f
hn : natDegree f = N
h : Separable f
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
refine' ⟨0, f, h, _⟩
[GOAL]
case h.inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
N : ℕ
ih : ∀ (m : ℕ), m < N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
f : F[X]
hf : Irreducible f
hn : natDegree f = N
h : Separable f
⊢ ↑(expand F (p ^ 0)) f = f
[PROOFSTEP]
rw [pow_zero, expand_one]
[GOAL]
case h.inr.intro.intro.intro
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
N : ℕ
ih : ∀ (m : ℕ), m < N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
f : F[X]
hf : Irreducible f
hn : natDegree f = N
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
cases' N with N
[GOAL]
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
ih :
  ∀ (m : ℕ),
    m < Nat.zero → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.zero
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
[GOAL]
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
ih :
  ∀ (m : ℕ),
    m < Nat.zero → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : f = ↑C (coeff f 0)
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
[GOAL]
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : coeff f 0 = 0
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
ih :
  ∀ (m : ℕ),
    m < Nat.zero → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : f = ↑C (coeff f 0)
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
have hf0 : f ≠ 0 := hf.ne_zero
[GOAL]
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : coeff f 0 = 0
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
ih :
  ∀ (m : ℕ),
    m < Nat.zero → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : f = ↑C (coeff f 0)
hf0 : f ≠ 0
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
rw [h1, C_0] at hn
[GOAL]
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : coeff f 0 = 0
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
ih :
  ∀ (m : ℕ),
    m < Nat.zero → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : f = 0
hf0 : f ≠ 0
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
exact absurd hn hf0
[GOAL]
case h.inr.intro.intro.intro.succ
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
have hg1 : g.natDegree * p = N.succ := by rwa [← natDegree_expand, hgf]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
⊢ natDegree g * p = Nat.succ N
[PROOFSTEP]
rwa [← natDegree_expand, hgf]
[GOAL]
case h.inr.intro.intro.intro.succ
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : natDegree g * p = Nat.succ N
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
have hg2 : g.natDegree ≠ 0 := by
  intro this
  rw [this, zero_mul] at hg1
  cases hg1
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : natDegree g * p = Nat.succ N
⊢ natDegree g ≠ 0
[PROOFSTEP]
intro this
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : natDegree g * p = Nat.succ N
this : natDegree g = 0
⊢ False
[PROOFSTEP]
rw [this, zero_mul] at hg1
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : 0 = Nat.succ N
this : natDegree g = 0
⊢ False
[PROOFSTEP]
cases hg1
[GOAL]
case h.inr.intro.intro.intro.succ
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : natDegree g * p = Nat.succ N
hg2 : natDegree g ≠ 0
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
have hg3 : g.natDegree < N.succ := by
  rw [← mul_one g.natDegree, ← hg1]
  exact Nat.mul_lt_mul_of_pos_left hp.one_lt hg2.bot_lt
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : natDegree g * p = Nat.succ N
hg2 : natDegree g ≠ 0
⊢ natDegree g < Nat.succ N
[PROOFSTEP]
rw [← mul_one g.natDegree, ← hg1]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : natDegree g * p = Nat.succ N
hg2 : natDegree g ≠ 0
⊢ natDegree g * 1 < natDegree g * p
[PROOFSTEP]
exact Nat.mul_lt_mul_of_pos_left hp.one_lt hg2.bot_lt
[GOAL]
case h.inr.intro.intro.intro.succ
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : ↑(expand F p) g = f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
hg1 : natDegree g * p = Nat.succ N
hg2 : natDegree g ≠ 0
hg3 : natDegree g < Nat.succ N
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
rcases ih _ hg3 hg rfl with ⟨n, g, hg4, rfl⟩
[GOAL]
case h.inr.intro.intro.intro.succ.intro.intro.intro
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
n : ℕ
g : F[X]
hg4 : Separable g
hg : Irreducible (↑(expand F (p ^ n)) g)
hgf : ↑(expand F p) (↑(expand F (p ^ n)) g) = f
hg1 : natDegree (↑(expand F (p ^ n)) g) * p = Nat.succ N
hg2 : natDegree (↑(expand F (p ^ n)) g) ≠ 0
hg3 : natDegree (↑(expand F (p ^ n)) g) < Nat.succ N
⊢ ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
[PROOFSTEP]
refine' ⟨n + 1, g, hg4, _⟩
[GOAL]
case h.inr.intro.intro.intro.succ.intro.intro.intro
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f✝ : F[X]
hf✝ : Irreducible f✝
hp : Nat.Prime p
x✝ : ℕ
hn✝ : natDegree f✝ = x✝
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
N : ℕ
ih :
  ∀ (m : ℕ),
    m < Nat.succ N → ∀ {f : F[X]}, Irreducible f → natDegree f = m → ∃ n g, Separable g ∧ ↑(expand F (p ^ n)) g = f
hn : natDegree f = Nat.succ N
n : ℕ
g : F[X]
hg4 : Separable g
hg : Irreducible (↑(expand F (p ^ n)) g)
hgf : ↑(expand F p) (↑(expand F (p ^ n)) g) = f
hg1 : natDegree (↑(expand F (p ^ n)) g) * p = Nat.succ N
hg2 : natDegree (↑(expand F (p ^ n)) g) ≠ 0
hg3 : natDegree (↑(expand F (p ^ n)) g) < Nat.succ N
⊢ ↑(expand F (p ^ (n + 1))) g = f
[PROOFSTEP]
rw [← hgf, expand_expand, pow_succ]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hf : Separable (↑(expand F (p ^ n)) f)
⊢ IsUnit f ∨ n = 0
[PROOFSTEP]
rw [or_iff_not_imp_right]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hf : Separable (↑(expand F (p ^ n)) f)
⊢ ¬n = 0 → IsUnit f
[PROOFSTEP]
rintro hn : n ≠ 0
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hf : Separable (↑(expand F (p ^ n)) f)
hn : n ≠ 0
⊢ IsUnit f
[PROOFSTEP]
have hf2 : derivative (expand F (p ^ n) f) = 0 := by
  rw [derivative_expand, Nat.cast_pow, CharP.cast_eq_zero, zero_pow hn.bot_lt, zero_mul, mul_zero]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hf : Separable (↑(expand F (p ^ n)) f)
hn : n ≠ 0
⊢ ↑derivative (↑(expand F (p ^ n)) f) = 0
[PROOFSTEP]
rw [derivative_expand, Nat.cast_pow, CharP.cast_eq_zero, zero_pow hn.bot_lt, zero_mul, mul_zero]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hf : Separable (↑(expand F (p ^ n)) f)
hn : n ≠ 0
hf2 : ↑derivative (↑(expand F (p ^ n)) f) = 0
⊢ IsUnit f
[PROOFSTEP]
rw [separable_def, hf2, isCoprime_zero_right, isUnit_iff] at hf
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hf : ∃ r, IsUnit r ∧ ↑C r = ↑(expand F (p ^ n)) f
hn : n ≠ 0
hf2 : ↑derivative (↑(expand F (p ^ n)) f) = 0
⊢ IsUnit f
[PROOFSTEP]
rcases hf with ⟨r, hr, hrf⟩
[GOAL]
case intro.intro
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hn : n ≠ 0
hf2 : ↑derivative (↑(expand F (p ^ n)) f) = 0
r : F
hr : IsUnit r
hrf : ↑C r = ↑(expand F (p ^ n)) f
⊢ IsUnit f
[PROOFSTEP]
rw [eq_comm, expand_eq_C (pow_pos hp _)] at hrf
[GOAL]
case intro.intro
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
n : ℕ
hp : 0 < p
hn : n ≠ 0
hf2 : ↑derivative (↑(expand F (p ^ n)) f) = 0
r : F
hr : IsUnit r
hrf : f = ↑C r
⊢ IsUnit f
[PROOFSTEP]
rwa [hrf, isUnit_C]
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ : ℕ
g₁ : F[X]
hg₁ : Separable g₁
hgf₁ : ↑(expand F (p ^ n₁)) g₁ = f
n₂ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
hgf₂ : ↑(expand F (p ^ n₂)) g₂ = f
⊢ n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
revert g₁ g₂
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
⊢ ∀ (g₁ : F[X]),
    Separable g₁ →
      ↑(expand F (p ^ n₁)) g₁ = f → ∀ (g₂ : F[X]), Separable g₂ → ↑(expand F (p ^ n₂)) g₂ = f → n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
clear! K
[GOAL]
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
⊢ ∀ (g₁ : F[X]),
    Separable g₁ →
      ↑(expand F (p ^ n₁)) g₁ = f → ∀ (g₂ : F[X]), Separable g₂ → ↑(expand F (p ^ n₂)) g₂ = f → n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
wlog hn : n₁ ≤ n₂
[GOAL]
case inr
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
this :
  ∀ {F : Type u} [inst : Field F] (p : ℕ) [HF : CharP F p] {f : F[X]},
    Irreducible f →
      0 < p →
        ∀ (n₁ n₂ : ℕ),
          n₁ ≤ n₂ →
            ∀ (g₁ : F[X]),
              Separable g₁ →
                ↑(expand F (p ^ n₁)) g₁ = f →
                  ∀ (g₂ : F[X]), Separable g₂ → ↑(expand F (p ^ n₂)) g₂ = f → n₁ = n₂ ∧ g₁ = g₂
hn : ¬n₁ ≤ n₂
⊢ ∀ (g₁ : F[X]),
    Separable g₁ →
      ↑(expand F (p ^ n₁)) g₁ = f → ∀ (g₂ : F[X]), Separable g₂ → ↑(expand F (p ^ n₂)) g₂ = f → n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
intro g₁ hg₁ Hg₁ g₂ hg₂ Hg₂
[GOAL]
case inr
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
this :
  ∀ {F : Type u} [inst : Field F] (p : ℕ) [HF : CharP F p] {f : F[X]},
    Irreducible f →
      0 < p →
        ∀ (n₁ n₂ : ℕ),
          n₁ ≤ n₂ →
            ∀ (g₁ : F[X]),
              Separable g₁ →
                ↑(expand F (p ^ n₁)) g₁ = f →
                  ∀ (g₂ : F[X]), Separable g₂ → ↑(expand F (p ^ n₂)) g₂ = f → n₁ = n₂ ∧ g₁ = g₂
hn : ¬n₁ ≤ n₂
g₁ : F[X]
hg₁ : Separable g₁
Hg₁ : ↑(expand F (p ^ n₁)) g₁ = f
g₂ : F[X]
hg₂ : Separable g₂
Hg₂ : ↑(expand F (p ^ n₂)) g₂ = f
⊢ n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
simpa only [eq_comm] using this p hf hp n₂ n₁ (le_of_not_le hn) g₂ hg₂ Hg₂ g₁ hg₁ Hg₁
[GOAL]
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
hn : n₁ ≤ n₂
⊢ ∀ (g₁ : F[X]),
    Separable g₁ →
      ↑(expand F (p ^ n₁)) g₁ = f → ∀ (g₂ : F[X]), Separable g₂ → ↑(expand F (p ^ n₂)) g₂ = f → n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
have hf0 : f ≠ 0 := hf.ne_zero
[GOAL]
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
hn : n₁ ≤ n₂
hf0 : f ≠ 0
⊢ ∀ (g₁ : F[X]),
    Separable g₁ →
      ↑(expand F (p ^ n₁)) g₁ = f → ∀ (g₂ : F[X]), Separable g₂ → ↑(expand F (p ^ n₂)) g₂ = f → n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
intros g₁ hg₁ hgf₁ g₂ hg₂ hgf₂
[GOAL]
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
hn : n₁ ≤ n₂
hf0 : f ≠ 0
g₁ : F[X]
hg₁ : Separable g₁
hgf₁ : ↑(expand F (p ^ n₁)) g₁ = f
g₂ : F[X]
hg₂ : Separable g₂
hgf₂ : ↑(expand F (p ^ n₂)) g₂ = f
⊢ n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
rw [le_iff_exists_add] at hn
[GOAL]
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ n₂ : ℕ
hn : ∃ c, n₂ = n₁ + c
hf0 : f ≠ 0
g₁ : F[X]
hg₁ : Separable g₁
hgf₁ : ↑(expand F (p ^ n₁)) g₁ = f
g₂ : F[X]
hg₂ : Separable g₂
hgf₂ : ↑(expand F (p ^ n₂)) g₂ = f
⊢ n₁ = n₂ ∧ g₁ = g₂
[PROOFSTEP]
rcases hn with ⟨k, rfl⟩
[GOAL]
case intro
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ : ℕ
hf0 : f ≠ 0
g₁ : F[X]
hg₁ : Separable g₁
hgf₁ : ↑(expand F (p ^ n₁)) g₁ = f
g₂ : F[X]
hg₂ : Separable g₂
k : ℕ
hgf₂ : ↑(expand F (p ^ (n₁ + k))) g₂ = f
⊢ n₁ = n₁ + k ∧ g₁ = g₂
[PROOFSTEP]
rw [← hgf₁, pow_add, expand_mul, expand_inj (pow_pos hp n₁)] at hgf₂
[GOAL]
case intro
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ : ℕ
hf0 : f ≠ 0
g₁ : F[X]
hg₁ : Separable g₁
hgf₁ : ↑(expand F (p ^ n₁)) g₁ = f
g₂ : F[X]
hg₂ : Separable g₂
k : ℕ
hgf₂ : ↑(expand F (p ^ k)) g₂ = g₁
⊢ n₁ = n₁ + k ∧ g₁ = g₂
[PROOFSTEP]
subst hgf₂
[GOAL]
case intro
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
f : F[X]
hf : Irreducible f
hp : 0 < p
n₁ : ℕ
hf0 : f ≠ 0
g₂ : F[X]
hg₂ : Separable g₂
k : ℕ
hg₁ : Separable (↑(expand F (p ^ k)) g₂)
hgf₁ : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) g₂) = f
⊢ n₁ = n₁ + k ∧ ↑(expand F (p ^ k)) g₂ = g₂
[PROOFSTEP]
subst hgf₁
[GOAL]
case intro
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
k : ℕ
hg₁ : Separable (↑(expand F (p ^ k)) g₂)
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) g₂))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) g₂) ≠ 0
⊢ n₁ = n₁ + k ∧ ↑(expand F (p ^ k)) g₂ = g₂
[PROOFSTEP]
rcases isUnit_or_eq_zero_of_separable_expand p k hp hg₁ with (h | rfl)
[GOAL]
case intro.inl
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
k : ℕ
hg₁ : Separable (↑(expand F (p ^ k)) g₂)
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) g₂))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) g₂) ≠ 0
h : IsUnit g₂
⊢ n₁ = n₁ + k ∧ ↑(expand F (p ^ k)) g₂ = g₂
[PROOFSTEP]
rw [isUnit_iff] at h
[GOAL]
case intro.inl
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
k : ℕ
hg₁ : Separable (↑(expand F (p ^ k)) g₂)
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) g₂))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) g₂) ≠ 0
h : ∃ r, IsUnit r ∧ ↑C r = g₂
⊢ n₁ = n₁ + k ∧ ↑(expand F (p ^ k)) g₂ = g₂
[PROOFSTEP]
rcases h with ⟨r, hr, rfl⟩
[GOAL]
case intro.inl.intro.intro
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ k : ℕ
r : F
hr : IsUnit r
hg₂ : Separable (↑C r)
hg₁ : Separable (↑(expand F (p ^ k)) (↑C r))
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) (↑C r)))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) (↑C r)) ≠ 0
⊢ n₁ = n₁ + k ∧ ↑(expand F (p ^ k)) (↑C r) = ↑C r
[PROOFSTEP]
simp_rw [expand_C] at hf
[GOAL]
case intro.inl.intro.intro
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ k : ℕ
r : F
hr : IsUnit r
hg₂ : Separable (↑C r)
hg₁ : Separable (↑(expand F (p ^ k)) (↑C r))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ k)) (↑C r)) ≠ 0
hf : Irreducible (↑C r)
⊢ n₁ = n₁ + k ∧ ↑(expand F (p ^ k)) (↑C r) = ↑C r
[PROOFSTEP]
exact absurd (isUnit_C.2 hr) hf.1
[GOAL]
case intro.inr
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
hg₁ : Separable (↑(expand F (p ^ 0)) g₂)
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂) ≠ 0
⊢ n₁ = n₁ + 0 ∧ ↑(expand F (p ^ 0)) g₂ = g₂
[PROOFSTEP]
rw [add_zero, pow_zero, expand_one]
[GOAL]
case intro.inr
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
hg₁ : Separable (↑(expand F (p ^ 0)) g₂)
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂) ≠ 0
⊢ n₁ = n₁ ∧ g₂ = g₂
[PROOFSTEP]
constructor
[GOAL]
case intro.inr.left
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
hg₁ : Separable (↑(expand F (p ^ 0)) g₂)
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂) ≠ 0
⊢ n₁ = n₁
[PROOFSTEP]
rfl
[GOAL]
case intro.inr.right
F✝ : Type u
inst✝¹ : Field F✝
p✝ : ℕ
F : Type u
inst✝ : Field F
p : ℕ
HF : CharP F p
hp : 0 < p
n₁ : ℕ
g₂ : F[X]
hg₂ : Separable g₂
hg₁ : Separable (↑(expand F (p ^ 0)) g₂)
hf : Irreducible (↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂))
hf0 : ↑(expand F (p ^ n₁)) (↑(expand F (p ^ 0)) g₂) ≠ 0
⊢ g₂ = g₂
[PROOFSTEP]
rfl
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
n : ℕ
⊢ Separable (X ^ n - 1) ↔ ↑n ≠ 0
[PROOFSTEP]
refine' ⟨_, fun h => separable_X_pow_sub_C_unit 1 (IsUnit.mk0 (↑n) h)⟩
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
n : ℕ
⊢ Separable (X ^ n - 1) → ↑n ≠ 0
[PROOFSTEP]
rw [separable_def', derivative_sub, derivative_X_pow, derivative_one, sub_zero]
  -- Suppose `(n : F) = 0`, then the derivative is `0`, so `X ^ n - 1` is a unit, contradiction.
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
n : ℕ
⊢ (∃ a b, a * (X ^ n - 1) + b * (↑C ↑n * X ^ (n - 1)) = 1) → ↑n ≠ 0
[PROOFSTEP]
rintro (h : IsCoprime _ _) hn'
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
n : ℕ
h : IsCoprime (X ^ n - 1) (↑C ↑n * X ^ (n - 1))
hn' : ↑n = 0
⊢ False
[PROOFSTEP]
rw [hn', C_0, zero_mul, isCoprime_zero_right] at h
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
n : ℕ
h : IsUnit (X ^ n - 1)
hn' : ↑n = 0
⊢ False
[PROOFSTEP]
exact not_isUnit_X_pow_sub_one F n h
[GOAL]
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
p : F[X]
hsep : Separable p
hsplit : Splits (algebraMap F K) p
⊢ Fintype.card ↑(rootSet p K) = natDegree p
[PROOFSTEP]
simp_rw [rootSet_def, Finset.coe_sort_coe, Fintype.card_coe]
[GOAL]
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
p : F[X]
hsep : Separable p
hsplit : Splits (algebraMap F K) p
⊢ card (Multiset.toFinset (roots (map (algebraMap F K) p))) = natDegree p
[PROOFSTEP]
rw [Multiset.toFinset_card_of_nodup, ← natDegree_eq_card_roots hsplit]
[GOAL]
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
p : F[X]
hsep : Separable p
hsplit : Splits (algebraMap F K) p
⊢ Multiset.Nodup (roots (map (algebraMap F K) p))
[PROOFSTEP]
exact nodup_roots hsep.map
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
⊢ h = ↑C (leadingCoeff h) * (X - ↑C x)
[PROOFSTEP]
have h_ne_zero : h ≠ 0 := by
  rintro rfl
  exact not_separable_zero h_sep
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
⊢ h ≠ 0
[PROOFSTEP]
rintro rfl
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h_sep : Separable 0
h_root : eval x 0 = 0
h_splits : Splits i 0
h_roots : ∀ (y : K), y ∈ roots (map i 0) → y = ↑i x
⊢ False
[PROOFSTEP]
exact not_separable_zero h_sep
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ h = ↑C (leadingCoeff h) * (X - ↑C x)
[PROOFSTEP]
apply Polynomial.eq_X_sub_C_of_splits_of_single_root i h_splits
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ roots (map i h) = {↑i x}
[PROOFSTEP]
apply Finset.mk.inj
[GOAL]
case x
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ { val := roots (map i h), nodup := ?nodup } = { val := {↑i x}, nodup := ?nodup }
[PROOFSTEP]
change _ = {i x}
[GOAL]
case x
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ { val := roots (map i h), nodup := ?nodup } = {↑i x}
[PROOFSTEP]
rw [Finset.eq_singleton_iff_unique_mem]
[GOAL]
case x
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ ↑i x ∈ { val := roots (map i h), nodup := ?nodup } ∧
    ∀ (x_1 : K), x_1 ∈ { val := roots (map i h), nodup := ?nodup } → x_1 = ↑i x
case nodup
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ Multiset.Nodup (roots (map i h))
[PROOFSTEP]
constructor
[GOAL]
case x.left
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ ↑i x ∈ { val := roots (map i h), nodup := ?nodup }
[PROOFSTEP]
apply Finset.mem_mk.mpr
[GOAL]
case x.left
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ ↑i x ∈ roots (map i h)
[PROOFSTEP]
rw [mem_roots (show h.map i ≠ 0 from map_ne_zero h_ne_zero)]
[GOAL]
case x.left
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ IsRoot (map i h) (↑i x)
[PROOFSTEP]
rw [IsRoot.def, ← eval₂_eq_eval_map, eval₂_hom, h_root]
[GOAL]
case x.left
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ ↑i 0 = 0
[PROOFSTEP]
exact RingHom.map_zero i
[GOAL]
case nodup
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ Multiset.Nodup (roots (map i h))
[PROOFSTEP]
exact nodup_roots (Separable.map h_sep)
[GOAL]
case x.right
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i : F →+* K
x : F
h : F[X]
h_sep : Separable h
h_root : eval x h = 0
h_splits : Splits i h
h_roots : ∀ (y : K), y ∈ roots (map i h) → y = ↑i x
h_ne_zero : h ≠ 0
⊢ ∀ (x_1 : K), x_1 ∈ { val := roots (map i h), nodup := (_ : Multiset.Nodup (roots (map i h))) } → x_1 = ↑i x
[PROOFSTEP]
exact h_roots
[GOAL]
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
⊢ ∃ s, map i f = ↑C (↑i (leadingCoeff f)) * ∏ a in s, (X - ↑C a)
[PROOFSTEP]
obtain ⟨s, h⟩ := (splits_iff_exists_multiset _).1 sp
[GOAL]
case intro
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
s : Multiset K
h : map i f = ↑C (↑i (leadingCoeff f)) * Multiset.prod (Multiset.map (fun a => X - ↑C a) s)
⊢ ∃ s, map i f = ↑C (↑i (leadingCoeff f)) * ∏ a in s, (X - ↑C a)
[PROOFSTEP]
use s.toFinset
[GOAL]
case h
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
s : Multiset K
h : map i f = ↑C (↑i (leadingCoeff f)) * Multiset.prod (Multiset.map (fun a => X - ↑C a) s)
⊢ map i f = ↑C (↑i (leadingCoeff f)) * ∏ a in Multiset.toFinset s, (X - ↑C a)
[PROOFSTEP]
rw [h, Finset.prod_eq_multiset_prod, ← Multiset.toFinset_eq]
[GOAL]
case h
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
s : Multiset K
h : map i f = ↑C (↑i (leadingCoeff f)) * Multiset.prod (Multiset.map (fun a => X - ↑C a) s)
⊢ Multiset.Nodup s
[PROOFSTEP]
apply nodup_of_separable_prod
[GOAL]
case h.hs
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
s : Multiset K
h : map i f = ↑C (↑i (leadingCoeff f)) * Multiset.prod (Multiset.map (fun a => X - ↑C a) s)
⊢ Separable (Multiset.prod (Multiset.map (fun a => X - ↑C a) s))
[PROOFSTEP]
apply Separable.of_mul_right
[GOAL]
case h.hs.h
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
s : Multiset K
h : map i f = ↑C (↑i (leadingCoeff f)) * Multiset.prod (Multiset.map (fun a => X - ↑C a) s)
⊢ Separable (?h.hs.f * Multiset.prod (Multiset.map (fun a => X - ↑C a) s))
case h.hs.f
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
s : Multiset K
h : map i f = ↑C (↑i (leadingCoeff f)) * Multiset.prod (Multiset.map (fun a => X - ↑C a) s)
⊢ K[X]
[PROOFSTEP]
rw [← h]
[GOAL]
case h.hs.h
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
i✝ i : F →+* K
f : F[X]
sep : Separable f
sp : Splits i f
s : Multiset K
h : map i f = ↑C (↑i (leadingCoeff f)) * Multiset.prod (Multiset.map (fun a => X - ↑C a) s)
⊢ Separable (map i f)
[PROOFSTEP]
exact sep.map
[GOAL]
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
⊢ Separable f
[PROOFSTEP]
rw [separable_iff_derivative_ne_zero hf, Ne, ← degree_eq_bot, degree_derivative_eq]
[GOAL]
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
⊢ ¬↑(natDegree f - 1) = ⊥
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case hp
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
⊢ 0 < natDegree f
[PROOFSTEP]
rw [pos_iff_ne_zero, Ne, natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff]
[GOAL]
case hp
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
⊢ ¬f = ↑C (coeff f 0)
[PROOFSTEP]
refine' fun hf1 => hf.not_unit _
[GOAL]
case hp
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
hf1 : f = ↑C (coeff f 0)
⊢ IsUnit f
[PROOFSTEP]
rw [hf1, isUnit_C, isUnit_iff_ne_zero]
[GOAL]
case hp
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
hf1 : f = ↑C (coeff f 0)
⊢ coeff f 0 ≠ 0
[PROOFSTEP]
intro hf2
[GOAL]
case hp
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
hf1 : f = ↑C (coeff f 0)
hf2 : coeff f 0 = 0
⊢ False
[PROOFSTEP]
rw [hf2, C_0] at hf1
[GOAL]
case hp
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
inst✝ : CharZero F
f : F[X]
hf : Irreducible f
hf1 : f = 0
hf2 : coeff f 0 = 0
⊢ False
[PROOFSTEP]
exact absurd hf1 hf.ne_zero
[GOAL]
F : Type u_1
inst✝ : Field F
x : F
⊢ Separable (minpoly F x)
[PROOFSTEP]
rw [minpoly.eq_X_sub_C']
[GOAL]
F : Type u_1
inst✝ : Field F
x : F
⊢ Separable (X - ↑C x)
[PROOFSTEP]
exact separable_X_sub_C
[GOAL]
F : Type u_1
K : Type u_2
E : Type u_3
inst✝⁶ : Field F
inst✝⁵ : Field K
inst✝⁴ : Field E
inst✝³ : Algebra F K
inst✝² : Algebra F E
inst✝¹ : Algebra K E
inst✝ : IsScalarTower F K E
h : IsSeparable F E
x : K
⊢ IsIntegral F x ∧ Separable (minpoly F x)
[PROOFSTEP]
refine' (isSeparable_iff.1 h (algebraMap K E x)).imp isIntegral_tower_bot_of_isIntegral_field fun hs => _
[GOAL]
F : Type u_1
K : Type u_2
E : Type u_3
inst✝⁶ : Field F
inst✝⁵ : Field K
inst✝⁴ : Field E
inst✝³ : Algebra F K
inst✝² : Algebra F E
inst✝¹ : Algebra K E
inst✝ : IsScalarTower F K E
h : IsSeparable F E
x : K
hs : Separable (minpoly F (↑(algebraMap K E) x))
⊢ Separable (minpoly F x)
[PROOFSTEP]
obtain ⟨q, hq⟩ := minpoly.dvd F x ((aeval_algebraMap_eq_zero_iff _ _ _).mp (minpoly.aeval F ((algebraMap K E) x)))
[GOAL]
case intro
F : Type u_1
K : Type u_2
E : Type u_3
inst✝⁶ : Field F
inst✝⁵ : Field K
inst✝⁴ : Field E
inst✝³ : Algebra F K
inst✝² : Algebra F E
inst✝¹ : Algebra K E
inst✝ : IsScalarTower F K E
h : IsSeparable F E
x : K
hs : Separable (minpoly F (↑(algebraMap K E) x))
q : F[X]
hq : minpoly F (↑(algebraMap K E) x) = minpoly F x * q
⊢ Separable (minpoly F x)
[PROOFSTEP]
rw [hq] at hs
[GOAL]
case intro
F : Type u_1
K : Type u_2
E : Type u_3
inst✝⁶ : Field F
inst✝⁵ : Field K
inst✝⁴ : Field E
inst✝³ : Algebra F K
inst✝² : Algebra F E
inst✝¹ : Algebra K E
inst✝ : IsScalarTower F K E
h : IsSeparable F E
x : K
q : F[X]
hs : Separable (minpoly F x * q)
hq : minpoly F (↑(algebraMap K E) x) = minpoly F x * q
⊢ Separable (minpoly F x)
[PROOFSTEP]
exact hs.of_mul_left
[GOAL]
F : Type u_1
K : Type u_2
E : Type u_3
inst✝⁹ : Field F
inst✝⁸ : Field K
inst✝⁷ : Field E
inst✝⁶ : Algebra F K
inst✝⁵ : Algebra F E
inst✝⁴ : Algebra K E
inst✝³ : IsScalarTower F K E
E' : Type u_4
inst✝² : Field E'
inst✝¹ : Algebra F E'
f : E →ₐ[F] E'
inst✝ : IsSeparable F E'
⊢ IsSeparable F E
[PROOFSTEP]
letI : Algebra E E' := RingHom.toAlgebra f.toRingHom
[GOAL]
F : Type u_1
K : Type u_2
E : Type u_3
inst✝⁹ : Field F
inst✝⁸ : Field K
inst✝⁷ : Field E
inst✝⁶ : Algebra F K
inst✝⁵ : Algebra F E
inst✝⁴ : Algebra K E
inst✝³ : IsScalarTower F K E
E' : Type u_4
inst✝² : Field E'
inst✝¹ : Algebra F E'
f : E →ₐ[F] E'
inst✝ : IsSeparable F E'
this : Algebra E E' := RingHom.toAlgebra ↑f
⊢ IsSeparable F E
[PROOFSTEP]
haveI : IsScalarTower F E E' := IsScalarTower.of_algebraMap_eq fun x => (f.commutes x).symm
[GOAL]
F : Type u_1
K : Type u_2
E : Type u_3
inst✝⁹ : Field F
inst✝⁸ : Field K
inst✝⁷ : Field E
inst✝⁶ : Algebra F K
inst✝⁵ : Algebra F E
inst✝⁴ : Algebra K E
inst✝³ : IsScalarTower F K E
E' : Type u_4
inst✝² : Field E'
inst✝¹ : Algebra F E'
f : E →ₐ[F] E'
inst✝ : IsSeparable F E'
this✝ : Algebra E E' := RingHom.toAlgebra ↑f
this : IsScalarTower F E E'
⊢ IsSeparable F E
[PROOFSTEP]
exact isSeparable_tower_bot_of_isSeparable F E E'
[GOAL]
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁵ : CommRing S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K S
inst✝ : Algebra K L
pb : PowerBasis K S
h_sep : Separable (minpoly K pb.gen)
h_splits : Splits (algebraMap K L) (minpoly K pb.gen)
⊢ Fintype.card (S →ₐ[K] L) = pb.dim
[PROOFSTEP]
let s := ((minpoly K pb.gen).map (algebraMap K L)).roots.toFinset
[GOAL]
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁵ : CommRing S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K S
inst✝ : Algebra K L
pb : PowerBasis K S
h_sep : Separable (minpoly K pb.gen)
h_splits : Splits (algebraMap K L) (minpoly K pb.gen)
s : Finset L := Multiset.toFinset (roots (Polynomial.map (algebraMap K L) (minpoly K pb.gen)))
⊢ Fintype.card (S →ₐ[K] L) = pb.dim
[PROOFSTEP]
let _ := (PowerBasis.AlgHom.fintype pb : Fintype (S →ₐ[K] L))
[GOAL]
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁵ : CommRing S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K S
inst✝ : Algebra K L
pb : PowerBasis K S
h_sep : Separable (minpoly K pb.gen)
h_splits : Splits (algebraMap K L) (minpoly K pb.gen)
s : Finset L := Multiset.toFinset (roots (Polynomial.map (algebraMap K L) (minpoly K pb.gen)))
x✝ : Fintype (S →ₐ[K] L) := PowerBasis.AlgHom.fintype pb
⊢ Fintype.card (S →ₐ[K] L) = pb.dim
[PROOFSTEP]
rw [Fintype.card_congr pb.liftEquiv', Fintype.card_of_subtype s (fun x => Multiset.mem_toFinset), ←
  pb.natDegree_minpoly, natDegree_eq_card_roots h_splits, Multiset.toFinset_card_of_nodup]
[GOAL]
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁵ : CommRing S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K S
inst✝ : Algebra K L
pb : PowerBasis K S
h_sep : Separable (minpoly K pb.gen)
h_splits : Splits (algebraMap K L) (minpoly K pb.gen)
s : Finset L := Multiset.toFinset (roots (Polynomial.map (algebraMap K L) (minpoly K pb.gen)))
x✝ : Fintype (S →ₐ[K] L) := PowerBasis.AlgHom.fintype pb
⊢ Multiset.Nodup (roots (Polynomial.map (algebraMap K L) (minpoly K pb.gen)))
[PROOFSTEP]
exact nodup_roots ((separable_map (algebraMap K L)).mpr h_sep)


[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : IsIso f
⊢ (f.op ≫ (inv f).op).unop = (𝟙 (op Y)).unop
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : IsIso f
⊢ ((inv f).op ≫ f.op).unop = (𝟙 (op X)).unop
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : IsIso f.op
⊢ (f ≫ (inv f.op).unop).op = (𝟙 X).op
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : IsIso f.op
⊢ ((inv f.op).unop ≫ f).op = (𝟙 Y).op
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ
f : X ⟶ Y
⊢ IsIso f.unop ↔ IsIso f
[PROOFSTEP]
rw [← isIso_op_iff f.unop, Quiver.Hom.op_unop]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst✝ : IsIso f
⊢ (inv f).op = inv f.op
[PROOFSTEP]
aesop_cat_nonterminal
[GOAL]
case hom_inv_id
C : Type u₁
inst : Category.{v₁, u₁} C
X Y : C
f : X ⟶ Y
inst_1 : IsIso f
⊢ f.op ≫ (inv f).op = 𝟙 (op Y)
[PROOFSTEP]
rw [← op_comp, IsIso.inv_hom_id, op_id]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y : Cᵒᵖ
f : X ⟶ Y
inst✝ : IsIso f
⊢ (inv f).unop = inv f.unop
[PROOFSTEP]
aesop_cat_nonterminal
[GOAL]
case hom_inv_id
C : Type u₁
inst : Category.{v₁, u₁} C
X Y : Cᵒᵖ
f : X ⟶ Y
inst_1 : IsIso f
⊢ f.unop ≫ (inv f).unop = 𝟙 Y.unop
[PROOFSTEP]
rw [← unop_comp, IsIso.inv_hom_id, unop_id]
[GOAL]
C : Type u₁
inst✝² : Category.{v₁, u₁} C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
F : C ⥤ D
inst✝ : Faithful F
X✝ Y✝ : Cᵒᵖ
a₁✝ a₂✝ : X✝ ⟶ Y✝
h : F.op.map a₁✝ = F.op.map a₂✝
⊢ a₁✝.unop = a₂✝.unop
[PROOFSTEP]
simpa using map_injective F (Quiver.Hom.op_inj h)
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F : Cᵒᵖ ⥤ D
⊢ F.rightOp.leftOp = F
[PROOFSTEP]
cases F
[GOAL]
case mk
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
toPrefunctor✝ : Cᵒᵖ ⥤q D
map_id✝ : ∀ (X : Cᵒᵖ), toPrefunctor✝.map (𝟙 X) = 𝟙 (toPrefunctor✝.obj X)
map_comp✝ :
  ∀ {X Y Z : Cᵒᵖ} (f : X ⟶ Y) (g : Y ⟶ Z), toPrefunctor✝.map (f ≫ g) = toPrefunctor✝.map f ≫ toPrefunctor✝.map g
⊢ (mk toPrefunctor✝).rightOp.leftOp = mk toPrefunctor✝
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ⟶ G
X Y : Cᵒᵖ
f : X ⟶ Y
⊢ (G.op.map f ≫ (fun X => (app α X.unop).op) Y).unop = ((fun X => (app α X.unop).op) X ≫ F.op.map f).unop
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ⟶ G
X Y : C
f : X ⟶ Y
⊢ ((Functor.unop G).map f ≫ (fun X => (app α (op X)).unop) Y).op =
    ((fun X => (app α (op X)).unop) X ≫ (Functor.unop F).map f).op
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ⟶ G.op
X Y : C
f : X ⟶ Y
⊢ (G.map f ≫ (fun X => (app α (op X)).unop) Y).op = ((fun X => (app α (op X)).unop) X ≫ F.map f).op
[PROOFSTEP]
simpa only [Functor.op_map] using (α.naturality f.op).symm
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : Functor.unop F ⟶ Functor.unop G
X Y : Cᵒᵖ
f : X ⟶ Y
⊢ (G.map f ≫ (fun X => (app α X.unop).op) Y).unop = ((fun X => (app α X.unop).op) X ≫ F.map f).unop
[PROOFSTEP]
simpa only [Functor.unop_map] using (α.naturality f.unop).symm
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G H : C ⥤ Dᵒᵖ
α : F ⟶ G
X Y : Cᵒᵖ
f : X ⟶ Y
⊢ (G.leftOp.map f ≫ (fun X => (app α X.unop).unop) Y).op = ((fun X => (app α X.unop).unop) X ≫ F.leftOp.map f).op
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G H : C ⥤ Dᵒᵖ
α : F.leftOp ⟶ G.leftOp
X Y : C
f : X ⟶ Y
⊢ (G.map f ≫ (fun X => (app α (op X)).op) Y).unop = ((fun X => (app α (op X)).op) X ≫ F.map f).unop
[PROOFSTEP]
simpa only [Functor.leftOp_map] using (α.naturality f.op).symm
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G H : Cᵒᵖ ⥤ D
α : F ⟶ G
X Y : C
f : X ⟶ Y
⊢ (G.rightOp.map f ≫ (fun X => (app α (op X)).op) Y).unop = ((fun X => (app α (op X)).op) X ≫ F.rightOp.map f).unop
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G H : Cᵒᵖ ⥤ D
α : F.rightOp ⟶ G.rightOp
X Y : Cᵒᵖ
f : X ⟶ Y
⊢ (G.map f ≫ (fun X => (app α X.unop).unop) Y).op = ((fun X => (app α X.unop).unop) X ≫ F.map f).op
[PROOFSTEP]
simpa only [Functor.rightOp_map] using (α.naturality f.unop).symm
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X✝ Y✝ : C
X Y : Cᵒᵖ
f : X ≅ Y
⊢ f.hom.unop ≫ f.inv.unop = 𝟙 Y.unop
[PROOFSTEP]
simp only [← unop_comp, f.inv_hom_id, unop_id]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X✝ Y✝ : C
X Y : Cᵒᵖ
f : X ≅ Y
⊢ f.inv.unop ≫ f.hom.unop = 𝟙 X.unop
[PROOFSTEP]
simp only [← unop_comp, f.hom_inv_id, unop_id]
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X✝ Y✝ : C
X Y : Cᵒᵖ
f : X ≅ Y
⊢ Iso.op (unop f) = f
[PROOFSTEP]
ext
[GOAL]
case w
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X✝ Y✝ : C
X Y : Cᵒᵖ
f : X ≅ Y
⊢ (Iso.op (unop f)).hom = f.hom
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X✝ Y✝ X Y : C
f : X ≅ Y
⊢ unop (Iso.op f) = f
[PROOFSTEP]
ext
[GOAL]
case w
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X✝ Y✝ X Y : C
f : X ≅ Y
⊢ (unop (Iso.op f)).hom = f.hom
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
⊢ NatTrans.op α.hom ≫ NatTrans.op α.inv = 𝟙 G.op
[PROOFSTEP]
ext
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ NatTrans.app (NatTrans.op α.hom ≫ NatTrans.op α.inv) x✝ = NatTrans.app (𝟙 G.op) x✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ (NatTrans.app α.hom x✝.unop).op ≫ (NatTrans.app α.inv x✝.unop).op = 𝟙 (op (G.obj x✝.unop))
[PROOFSTEP]
rw [← op_comp]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ (NatTrans.app α.inv x✝.unop ≫ NatTrans.app α.hom x✝.unop).op = 𝟙 (op (G.obj x✝.unop))
[PROOFSTEP]
rw [α.inv_hom_id_app]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ (𝟙 (G.obj x✝.unop)).op = 𝟙 (op (G.obj x✝.unop))
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
⊢ NatTrans.op α.inv ≫ NatTrans.op α.hom = 𝟙 F.op
[PROOFSTEP]
ext
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ NatTrans.app (NatTrans.op α.inv ≫ NatTrans.op α.hom) x✝ = NatTrans.app (𝟙 F.op) x✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ (NatTrans.app α.inv x✝.unop).op ≫ (NatTrans.app α.hom x✝.unop).op = 𝟙 (op (F.obj x✝.unop))
[PROOFSTEP]
rw [← op_comp]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ (NatTrans.app α.hom x✝.unop ≫ NatTrans.app α.inv x✝.unop).op = 𝟙 (op (F.obj x✝.unop))
[PROOFSTEP]
rw [α.hom_inv_id_app]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F ≅ G
x✝ : Cᵒᵖ
⊢ (𝟙 (F.obj x✝.unop)).op = 𝟙 (op (F.obj x✝.unop))
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
⊢ NatTrans.removeOp α.hom ≫ NatTrans.removeOp α.inv = 𝟙 G
[PROOFSTEP]
ext
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ NatTrans.app (NatTrans.removeOp α.hom ≫ NatTrans.removeOp α.inv) x✝ = NatTrans.app (𝟙 G) x✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ (NatTrans.app α.hom (op x✝)).unop ≫ (NatTrans.app α.inv (op x✝)).unop = 𝟙 (G.obj x✝)
[PROOFSTEP]
rw [← unop_comp]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ (NatTrans.app α.inv (op x✝) ≫ NatTrans.app α.hom (op x✝)).unop = 𝟙 (G.obj x✝)
[PROOFSTEP]
rw [α.inv_hom_id_app]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ (𝟙 (G.op.obj (op x✝))).unop = 𝟙 (G.obj x✝)
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
⊢ NatTrans.removeOp α.inv ≫ NatTrans.removeOp α.hom = 𝟙 F
[PROOFSTEP]
ext
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ NatTrans.app (NatTrans.removeOp α.inv ≫ NatTrans.removeOp α.hom) x✝ = NatTrans.app (𝟙 F) x✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ (NatTrans.app α.inv (op x✝)).unop ≫ (NatTrans.app α.hom (op x✝)).unop = 𝟙 (F.obj x✝)
[PROOFSTEP]
rw [← unop_comp]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ (NatTrans.app α.hom (op x✝) ≫ NatTrans.app α.inv (op x✝)).unop = 𝟙 (F.obj x✝)
[PROOFSTEP]
rw [α.hom_inv_id_app]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : C ⥤ D
α : F.op ≅ G.op
x✝ : C
⊢ (𝟙 (F.op.obj (op x✝))).unop = 𝟙 (F.obj x✝)
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
⊢ NatTrans.unop α.hom ≫ NatTrans.unop α.inv = 𝟙 (Functor.unop G)
[PROOFSTEP]
ext
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ NatTrans.app (NatTrans.unop α.hom ≫ NatTrans.unop α.inv) x✝ = NatTrans.app (𝟙 (Functor.unop G)) x✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ (NatTrans.app α.hom (op x✝)).unop ≫ (NatTrans.app α.inv (op x✝)).unop = 𝟙 (G.obj (op x✝)).unop
[PROOFSTEP]
rw [← unop_comp]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ (NatTrans.app α.inv (op x✝) ≫ NatTrans.app α.hom (op x✝)).unop = 𝟙 (G.obj (op x✝)).unop
[PROOFSTEP]
rw [α.inv_hom_id_app]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ (𝟙 (G.obj (op x✝))).unop = 𝟙 (G.obj (op x✝)).unop
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
⊢ NatTrans.unop α.inv ≫ NatTrans.unop α.hom = 𝟙 (Functor.unop F)
[PROOFSTEP]
ext
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ NatTrans.app (NatTrans.unop α.inv ≫ NatTrans.unop α.hom) x✝ = NatTrans.app (𝟙 (Functor.unop F)) x✝
[PROOFSTEP]
dsimp
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ (NatTrans.app α.inv (op x✝)).unop ≫ (NatTrans.app α.hom (op x✝)).unop = 𝟙 (F.obj (op x✝)).unop
[PROOFSTEP]
rw [← unop_comp]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ (NatTrans.app α.hom (op x✝) ≫ NatTrans.app α.inv (op x✝)).unop = 𝟙 (F.obj (op x✝)).unop
[PROOFSTEP]
rw [α.hom_inv_id_app]
[GOAL]
case w.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F✝ G✝ : C ⥤ D
F G : Cᵒᵖ ⥤ Dᵒᵖ
α : F ≅ G
x✝ : C
⊢ (𝟙 (F.obj (op x✝))).unop = 𝟙 (F.obj (op x✝)).unop
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
X : Cᵒᵖ
⊢ e.functor.op.map (NatTrans.app (NatIso.op e.unitIso).symm.hom X) ≫
      NatTrans.app (NatIso.op e.counitIso).symm.hom (e.functor.op.obj X) =
    𝟙 (e.functor.op.obj X)
[PROOFSTEP]
apply Quiver.Hom.unop_inj
[GOAL]
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
X : Cᵒᵖ
⊢ (e.functor.op.map (NatTrans.app (NatIso.op e.unitIso).symm.hom X) ≫
        NatTrans.app (NatIso.op e.counitIso).symm.hom (e.functor.op.obj X)).unop =
    (𝟙 (e.functor.op.obj X)).unop
[PROOFSTEP]
dsimp
[GOAL]
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : C ≌ D
X : Cᵒᵖ
⊢ NatTrans.app e.counitIso.inv (e.functor.obj X.unop) ≫ e.functor.map (NatTrans.app e.unitIso.inv X.unop) =
    𝟙 (e.functor.obj X.unop)
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : Cᵒᵖ ≌ Dᵒᵖ
X : C
⊢ (Functor.unop e.functor).map (NatTrans.app (NatIso.unop e.unitIso).symm.hom X) ≫
      NatTrans.app (NatIso.unop e.counitIso).symm.hom ((Functor.unop e.functor).obj X) =
    𝟙 ((Functor.unop e.functor).obj X)
[PROOFSTEP]
apply Quiver.Hom.op_inj
[GOAL]
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : Cᵒᵖ ≌ Dᵒᵖ
X : C
⊢ ((Functor.unop e.functor).map (NatTrans.app (NatIso.unop e.unitIso).symm.hom X) ≫
        NatTrans.app (NatIso.unop e.counitIso).symm.hom ((Functor.unop e.functor).obj X)).op =
    (𝟙 ((Functor.unop e.functor).obj X)).op
[PROOFSTEP]
dsimp
[GOAL]
case a
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
e : Cᵒᵖ ≌ Dᵒᵖ
X : C
⊢ NatTrans.app e.counitIso.inv (e.functor.obj (Opposite.op X)) ≫
      e.functor.map (NatTrans.app e.unitIso.inv (Opposite.op X)) =
    𝟙 (e.functor.obj (Opposite.op X))
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
A B : Cᵒᵖ
x✝ : A ≅ B
⊢ (fun g => Iso.op g) ((fun f => Iso.unop f) x✝) = x✝
[PROOFSTEP]
ext
[GOAL]
case w
C : Type u₁
inst✝ : Category.{v₁, u₁} C
A B : Cᵒᵖ
x✝ : A ≅ B
⊢ ((fun g => Iso.op g) ((fun f => Iso.unop f) x✝)).hom = x✝.hom
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝ : Category.{v₁, u₁} C
A B : Cᵒᵖ
x✝ : B.unop ≅ A.unop
⊢ (fun f => Iso.unop f) ((fun g => Iso.op g) x✝) = x✝
[PROOFSTEP]
ext
[GOAL]
case w
C : Type u₁
inst✝ : Category.{v₁, u₁} C
A B : Cᵒᵖ
x✝ : B.unop ≅ A.unop
⊢ ((fun f => Iso.unop f) ((fun g => Iso.op g) x✝)).hom = x✝.hom
[PROOFSTEP]
rfl
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
⊢ ∀ {X Y : (C ⥤ D)ᵒᵖ} (f : X ⟶ Y),
    (𝟭 (C ⥤ D)ᵒᵖ).map f ≫ ((fun F => Iso.op (opUnopIso F.unop)) Y).hom =
      ((fun F => Iso.op (opUnopIso F.unop)) X).hom ≫ (opHom C D ⋙ opInv C D).map f
[PROOFSTEP]
intro F G f
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (C ⥤ D)ᵒᵖ
f : F ⟶ G
⊢ (𝟭 (C ⥤ D)ᵒᵖ).map f ≫ ((fun F => Iso.op (opUnopIso F.unop)) G).hom =
    ((fun F => Iso.op (opUnopIso F.unop)) F).hom ≫ (opHom C D ⋙ opInv C D).map f
[PROOFSTEP]
dsimp [opUnopIso]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (C ⥤ D)ᵒᵖ
f : F ⟶ G
⊢ f ≫ (NatIso.ofComponents fun X => Iso.refl (G.unop.obj X)).hom.op =
    (NatIso.ofComponents fun X => Iso.refl (F.unop.obj X)).hom.op ≫ (NatTrans.mk fun X => NatTrans.app f.unop X).op
[PROOFSTEP]
rw [show f = f.unop.op by simp, ← op_comp, ← op_comp]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (C ⥤ D)ᵒᵖ
f : F ⟶ G
⊢ f = f.unop.op
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (C ⥤ D)ᵒᵖ
f : F ⟶ G
⊢ ((NatIso.ofComponents fun X => Iso.refl (G.unop.obj X)).hom ≫ f.unop).op =
    ((NatTrans.mk fun X => NatTrans.app f.unop.op.unop X) ≫
        (NatIso.ofComponents fun X => Iso.refl (F.unop.obj X)).hom).op
[PROOFSTEP]
congr 1
[GOAL]
case e_f
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (C ⥤ D)ᵒᵖ
f : F ⟶ G
⊢ (NatIso.ofComponents fun X => Iso.refl (G.unop.obj X)).hom ≫ f.unop =
    (NatTrans.mk fun X => NatTrans.app f.unop.op.unop X) ≫ (NatIso.ofComponents fun X => Iso.refl (F.unop.obj X)).hom
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
⊢ ∀ {X Y : (Cᵒᵖ ⥤ D)ᵒᵖ} (f : X ⟶ Y),
    (𝟭 (Cᵒᵖ ⥤ D)ᵒᵖ).map f ≫ ((fun F => Iso.op (rightOpLeftOpIso F.unop)) Y).hom =
      ((fun F => Iso.op (rightOpLeftOpIso F.unop)) X).hom ≫
        (mk { obj := fun F => F.unop.rightOp, map := fun {X Y} η => NatTrans.rightOp η.unop } ⋙
              mk { obj := fun F => op F.leftOp, map := fun {X Y} η => (NatTrans.leftOp η).op }).map
          f
[PROOFSTEP]
intro F G η
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (Cᵒᵖ ⥤ D)ᵒᵖ
η : F ⟶ G
⊢ (𝟭 (Cᵒᵖ ⥤ D)ᵒᵖ).map η ≫ ((fun F => Iso.op (rightOpLeftOpIso F.unop)) G).hom =
    ((fun F => Iso.op (rightOpLeftOpIso F.unop)) F).hom ≫
      (mk { obj := fun F => F.unop.rightOp, map := fun {X Y} η => NatTrans.rightOp η.unop } ⋙
            mk { obj := fun F => op F.leftOp, map := fun {X Y} η => (NatTrans.leftOp η).op }).map
        η
[PROOFSTEP]
dsimp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (Cᵒᵖ ⥤ D)ᵒᵖ
η : F ⟶ G
⊢ η ≫ (rightOpLeftOpIso G.unop).hom.op =
    (rightOpLeftOpIso F.unop).hom.op ≫ (NatTrans.leftOp (NatTrans.rightOp η.unop)).op
[PROOFSTEP]
rw [show η = η.unop.op by simp, ← op_comp, ← op_comp]
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (Cᵒᵖ ⥤ D)ᵒᵖ
η : F ⟶ G
⊢ η = η.unop.op
[PROOFSTEP]
simp
[GOAL]
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (Cᵒᵖ ⥤ D)ᵒᵖ
η : F ⟶ G
⊢ ((rightOpLeftOpIso G.unop).hom ≫ η.unop).op =
    (NatTrans.leftOp (NatTrans.rightOp η.unop.op.unop) ≫ (rightOpLeftOpIso F.unop).hom).op
[PROOFSTEP]
congr 1
[GOAL]
case e_f
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
F G : (Cᵒᵖ ⥤ D)ᵒᵖ
η : F ⟶ G
⊢ (rightOpLeftOpIso G.unop).hom ≫ η.unop =
    NatTrans.leftOp (NatTrans.rightOp η.unop.op.unop) ≫ (rightOpLeftOpIso F.unop).hom
[PROOFSTEP]
aesop_cat