l3lab/ntp-mathlib huggingface dataset:
attribute [local instance] Ideal.Quotient.field in
theorem separable_map {S} [CommRing S] [Nontrivial S] (f : F →+* S) {p : F[X]} :
    (p.map f).Separable ↔ p.Separable := by
  refine ⟨fun H ↦ ?_, fun H ↦ H.map⟩
  obtain ⟨m, hm⟩ := Ideal.exists_maximal S
  have := Separable.map H (f := Ideal.Quotient.mk m)
  

Proof state:
case intro
F : Type u
inst✝³ : Field F
K : Type v
inst✝² : Field K
S : Type u_1
inst✝¹ : CommRing S
inst✝ : Nontrivial S
f : F →+* S
p : F[X]
H : Separable (map f p)
m : Ideal S
hm : Ideal.IsMaximal m
this : Separable (map (Ideal.Quotient.mk m) (map f p))
⊢ Separable p

Next tactic:
rwa [map_map, separable_def, derivative_map, isCoprime_map] at this
theorem separable_prod_X_sub_C_iff' {ι : Sort _} {f : ι → F} {s : Finset ι} :
    (∏ i in s, (X - C (f i))).Separable ↔ ∀ x ∈ s, ∀ y ∈ s, f x = f y → x = y :=
  ⟨fun hfs x hx y hy hfxy => hfs.inj_of_prod_X_sub_C hx hy hfxy, fun H => by
    

Proof state:
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
ι : Type u_1
f : ι → F
s : Finset ι
H : ∀ x ∈ s, ∀ y ∈ s, f x = f y → x = y
⊢ Separable (∏ i in s, (X - C (f i)))

Next tactic:
rw [← prod_attach]
theorem separable_prod_X_sub_C_iff' {ι : Sort _} {f : ι → F} {s : Finset ι} :
    (∏ i in s, (X - C (f i))).Separable ↔ ∀ x ∈ s, ∀ y ∈ s, f x = f y → x = y :=
  ⟨fun hfs x hx y hy hfxy => hfs.inj_of_prod_X_sub_C hx hy hfxy, fun H => by
    rw [← prod_attach]
    

Proof state:
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
ι : Type u_1
f : ι → F
s : Finset ι
H : ∀ x ∈ s, ∀ y ∈ s, f x = f y → x = y
⊢ Separable (∏ x in attach s, (X - C (f ↑x)))

Next tactic:
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
theorem separable_prod_X_sub_C_iff {ι : Sort _} [Fintype ι] {f : ι → F} :
    (∏ i, (X - C (f i))).Separable ↔ Function.Injective f :=
  separable_prod_X_sub_C_iff'.trans <| by 

Proof state:
F : Type u
inst✝² : Field F
K : Type v
inst✝¹ : Field K
ι : Type u_1
inst✝ : Fintype ι
f : ι → F
⊢ (∀ x ∈ univ, ∀ y ∈ univ, f x = f y → x = y) ↔ Function.Injective f

Next tactic:
simp_rw [mem_univ, true_imp_iff, Function.Injective]
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    

Proof state:
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

Next tactic:
rcases p.eq_zero_or_pos with (rfl | hp)
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · 

Proof state:
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

Next tactic:
haveI := CharP.charP_to_charZero F
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · haveI := CharP.charP_to_charZero F
      

Proof state:
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

Next tactic:
have := natDegree_eq_zero_of_derivative_eq_zero H
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · haveI := CharP.charP_to_charZero F
      have := natDegree_eq_zero_of_derivative_eq_zero H
      

Proof state:
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

Next tactic:
have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne'
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · haveI := CharP.charP_to_charZero F
      have := natDegree_eq_zero_of_derivative_eq_zero H
      have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne'
      

Proof state:
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

Next tactic:
contradiction
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · haveI := CharP.charP_to_charZero F
      have := natDegree_eq_zero_of_derivative_eq_zero H
      have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne'
      contradiction
    

Proof state:
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

Next tactic:
haveI := isLocalRingHom_expand F hp
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · haveI := CharP.charP_to_charZero F
      have := natDegree_eq_zero_of_derivative_eq_zero H
      have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne'
      contradiction
    haveI := isLocalRingHom_expand F hp
    

Proof state:
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

Next tactic:
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'⟩
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · haveI := CharP.charP_to_charZero F
      have := natDegree_eq_zero_of_derivative_eq_zero H
      have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne'
      contradiction
    haveI := isLocalRingHom_expand F hp
    exact
      Or.inr
        ⟨by 

Proof state:
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

Next tactic:
rw [separable_iff_derivative_ne_zero hf, Classical.not_not, H]
theorem separable_or {f : F[X]} (hf : Irreducible f) :
    f.Separable ∨ ¬f.Separable ∧ ∃ g : F[X], Irreducible g ∧ expand F p g = f :=
  if H : derivative f = 0 then by
    rcases p.eq_zero_or_pos with (rfl | hp)
    · haveI := CharP.charP_to_charZero F
      have := natDegree_eq_zero_of_derivative_eq_zero H
      have := (natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_irreducible hf).ne'
      contradiction
    haveI := isLocalRingHom_expand F hp
    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 

Proof state:
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))

Next tactic:
rwa [← expand_contract p H hp.ne'] at hf
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  

Proof state:
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

Next tactic:
replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  

Proof state:
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

Next tactic:
induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  

Proof state:
case h
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
N : ℕ
ih : ∀ 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

Next tactic:
rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · 

Proof state:
case h.inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
N : ℕ
ih : ∀ 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

Next tactic:
refine' ⟨0, f, h, _⟩
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    

Proof state:
case h.inl
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
N : ℕ
ih : ∀ 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

Next tactic:
rw [pow_zero, expand_one]
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · 

Proof state:
case h.inr.intro.intro.intro
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
N : ℕ
ih : ∀ 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

Next tactic:
cases' N with N
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · 

Proof state:
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : (expand F p) g = f
ih : ∀ 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

Next tactic:
rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      

Proof state:
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : (expand F p) g = f
ih : ∀ 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

Next tactic:
rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      

Proof state:
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
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 < 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

Next tactic:
have hf0 : f ≠ 0 := hf.ne_zero
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      have hf0 : f ≠ 0 := hf.ne_zero
      

Proof state:
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
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 < 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

Next tactic:
rw [h1, C_0] at hn
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      have hf0 : f ≠ 0 := hf.ne_zero
      rw [h1, C_0] at hn
      

Proof state:
case h.inr.intro.intro.intro.zero
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
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 < 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

Next tactic:
exact absurd hn hf0
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      have hf0 : f ≠ 0 := hf.ne_zero
      rw [h1, C_0] at hn
      exact absurd hn hf0
    

Proof state:
case h.inr.intro.intro.intro.succ
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : (expand F p) g = f
N : ℕ
ih : ∀ 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

Next tactic:
have hg1 : g.natDegree * p = N.succ := by rwa [← natDegree_expand, hgf]
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      have hf0 : f ≠ 0 := hf.ne_zero
      rw [h1, C_0] at hn
      exact absurd hn hf0
    have hg1 : g.natDegree * p = N.succ := by 

Proof state:
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : (expand F p) g = f
N : ℕ
ih : ∀ 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

Next tactic:
rwa [← natDegree_expand, hgf]
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      have hf0 : f ≠ 0 := hf.ne_zero
      rw [h1, C_0] at hn
      exact absurd hn hf0
    have hg1 : g.natDegree * p = N.succ := by rwa [← natDegree_expand, hgf]
    

Proof state:
case h.inr.intro.intro.intro.succ
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : (expand F p) g = f
N : ℕ
ih : ∀ 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

Next tactic:
have hg2 : g.natDegree ≠ 0 := by
      intro this
      rw [this, zero_mul] at hg1
      cases hg1
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      have hf0 : f ≠ 0 := hf.ne_zero
      rw [h1, C_0] at hn
      exact absurd hn hf0
    have hg1 : g.natDegree * p = N.succ := by rwa [← natDegree_expand, hgf]
    have hg2 : g.natDegree ≠ 0 := by
      

Proof state:
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : (expand F p) g = f
N : ℕ
ih : ∀ 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

Next tactic:
intro this
theorem exists_separable_of_irreducible {f : F[X]} (hf : Irreducible f) (hp : p ≠ 0) :
    ∃ (n : ℕ) (g : F[X]), g.Separable ∧ expand F (p ^ n) g = f := by
  replace hp : p.Prime := (CharP.char_is_prime_or_zero F p).resolve_right hp
  induction' hn : f.natDegree using Nat.strong_induction_on with N ih generalizing f
  rcases separable_or p hf with (h | ⟨h1, g, hg, hgf⟩)
  · refine' ⟨0, f, h, _⟩
    rw [pow_zero, expand_one]
  · cases' N with N
    · rw [natDegree_eq_zero_iff_degree_le_zero, degree_le_zero_iff] at hn
      rw [hn, separable_C, isUnit_iff_ne_zero, Classical.not_not] at h1
      have hf0 : f ≠ 0 := hf.ne_zero
      rw [h1, C_0] at hn
      exact absurd hn hf0
    have hg1 : g.natDegree * p = N.succ := by rwa [← natDegree_expand, hgf]
    have hg2 : g.natDegree ≠ 0 := by
      intro this
      

Proof state:
F : Type u
inst✝¹ : Field F
K : Type v
inst✝ : Field K
p : ℕ
HF : CharP F p
hp : Nat.Prime p
f : F[X]
hf : Irreducible f
h1 : ¬Separable f
g : F[X]
hg : Irreducible g
hgf : (expand F p) g = f
N : ℕ
ih : ∀ 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

Next tactic:
rw [this, zero_mul] at hg1