l3lab/ntp-mathlib huggingface dataset:
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · 

Proof state:
case succ.refine_1
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x : GaloisField (Nat.succ n✝) n
hx :
  x ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
⊢ ∀
    x ∈
      Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)),
    (aeval x) (X ^ Nat.succ n✝ ^ n - X) = 0

Next tactic:
rintro x (⟨r, rfl⟩ | hx)
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · 

Proof state:
case succ.refine_1.inl.intro
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x : GaloisField (Nat.succ n✝) n
hx :
  x ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
r : ZMod (Nat.succ n✝)
⊢ (aeval ((algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) r)) (X ^ Nat.succ n✝ ^ n - X) = 0

Next tactic:
simp only [map_sub, map_pow, aeval_X]
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · simp only [map_sub, map_pow, aeval_X]
      

Proof state:
case succ.refine_1.inl.intro
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x : GaloisField (Nat.succ n✝) n
hx :
  x ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
r : ZMod (Nat.succ n✝)
⊢ (algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) r ^ Nat.succ n✝ ^ n -
      (algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) r =
    0

Next tactic:
rw [← map_pow, ZMod.pow_card_pow, sub_self]
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · simp only [map_sub, map_pow, aeval_X]
      rw [← map_pow, ZMod.pow_card_pow, sub_self]
    · 

Proof state:
case succ.refine_1.inr
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x✝ : GaloisField (Nat.succ n✝) n
hx✝ :
  x✝ ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
x : GaloisField (Nat.succ n✝) n
hx : x ∈ rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X))
⊢ (aeval x) (X ^ Nat.succ n✝ ^ n - X) = 0

Next tactic:
dsimp only [GaloisField] at hx
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · simp only [map_sub, map_pow, aeval_X]
      rw [← map_pow, ZMod.pow_card_pow, sub_self]
    · dsimp only [GaloisField] at hx
      

Proof state:
case succ.refine_1.inr
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x✝ : GaloisField (Nat.succ n✝) n
hx✝ :
  x✝ ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
x : GaloisField (Nat.succ n✝) n
hx : x ∈ rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X))
⊢ (aeval x) (X ^ Nat.succ n✝ ^ n - X) = 0

Next tactic:
rwa [mem_rootSet_of_ne aux] at hx
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · simp only [map_sub, map_pow, aeval_X]
      rw [← map_pow, ZMod.pow_card_pow, sub_self]
    · dsimp only [GaloisField] at hx
      rwa [mem_rootSet_of_ne aux] at hx
  · 

Proof state:
case succ.refine_2
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x : GaloisField (Nat.succ n✝) n
hx :
  x ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
⊢ (aeval 0) (X ^ Nat.succ n✝ ^ n - X) = 0

Next tactic:
rw [← coeff_zero_eq_aeval_zero']
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · simp only [map_sub, map_pow, aeval_X]
      rw [← map_pow, ZMod.pow_card_pow, sub_self]
    · dsimp only [GaloisField] at hx
      rwa [mem_rootSet_of_ne aux] at hx
  · rw [← coeff_zero_eq_aeval_zero']
    

Proof state:
case succ.refine_2
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x : GaloisField (Nat.succ n✝) n
hx :
  x ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
⊢ (algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) (coeff (X ^ Nat.succ n✝ ^ n - X) 0) = 0

Next tactic:
simp only [coeff_X_pow, coeff_X_zero, sub_zero, _root_.map_eq_zero, ite_eq_right_iff,
      one_ne_zero, coeff_sub]
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · simp only [map_sub, map_pow, aeval_X]
      rw [← map_pow, ZMod.pow_card_pow, sub_self]
    · dsimp only [GaloisField] at hx
      rwa [mem_rootSet_of_ne aux] at hx
  · rw [← coeff_zero_eq_aeval_zero']
    simp only [coeff_X_pow, coeff_X_zero, sub_zero, _root_.map_eq_zero, ite_eq_right_iff,
      one_ne_zero, coeff_sub]
    

Proof state:
case succ.refine_2
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x : GaloisField (Nat.succ n✝) n
hx :
  x ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
⊢ 0 = Nat.succ n✝ ^ n → False

Next tactic:
intro hn
theorem finrank {n} (h : n ≠ 0) : FiniteDimensional.finrank (ZMod p) (GaloisField p n) = n := by
  set g_poly := (X ^ p ^ n - X : (ZMod p)[X])
  have hp : 1 < p := h_prime.out.one_lt
  have aux : g_poly ≠ 0 := FiniteField.X_pow_card_pow_sub_X_ne_zero _ h hp
  -- Porting note : in the statment of `key`, replaced `g_poly` by its value otherwise the
  -- proof fails
  have key : Fintype.card (g_poly.rootSet (GaloisField p n)) = g_poly.natDegree :=
    card_rootSet_eq_natDegree (galois_poly_separable p _ (dvd_pow (dvd_refl p) h))
      (SplittingField.splits (X ^ p ^ n - X : (ZMod p)[X]))
  have nat_degree_eq : g_poly.natDegree = p ^ n :=
    FiniteField.X_pow_card_pow_sub_X_natDegree_eq _ h hp
  rw [nat_degree_eq] at key
  suffices g_poly.rootSet (GaloisField p n) = Set.univ by
    simp_rw [this, ← Fintype.ofEquiv_card (Equiv.Set.univ _)] at key
    -- Porting note: prevents `card_eq_pow_finrank` from using a wrong instance for `Fintype`
    rw [@card_eq_pow_finrank (ZMod p) _ _ _ _ _ (_), ZMod.card] at key
    exact Nat.pow_right_injective (Nat.Prime.one_lt' p).out key
  rw [Set.eq_univ_iff_forall]
  suffices ∀ (x) (hx : x ∈ (⊤ : Subalgebra (ZMod p) (GaloisField p n))),
      x ∈ (X ^ p ^ n - X : (ZMod p)[X]).rootSet (GaloisField p n)
    by simpa
  rw [← SplittingField.adjoin_rootSet]
  simp_rw [Algebra.mem_adjoin_iff]
  intro x hx
  -- We discharge the `p = 0` separately, to avoid typeclass issues on `ZMod p`.
  cases p; cases hp
  refine Subring.closure_induction hx ?_ ?_ ?_ ?_ ?_ ?_ <;> simp_rw [mem_rootSet_of_ne aux]
  · rintro x (⟨r, rfl⟩ | hx)
    · simp only [map_sub, map_pow, aeval_X]
      rw [← map_pow, ZMod.pow_card_pow, sub_self]
    · dsimp only [GaloisField] at hx
      rwa [mem_rootSet_of_ne aux] at hx
  · rw [← coeff_zero_eq_aeval_zero']
    simp only [coeff_X_pow, coeff_X_zero, sub_zero, _root_.map_eq_zero, ite_eq_right_iff,
      one_ne_zero, coeff_sub]
    intro hn
    

Proof state:
case succ.refine_2
p : ℕ
inst✝ : Fact (Nat.Prime p)
n✝² n✝¹ n : ℕ
h : n ≠ 0
n✝ : ℕ
h_prime : Fact (Nat.Prime (Nat.succ n✝))
g_poly : (ZMod (Nat.succ n✝))[X] := X ^ Nat.succ n✝ ^ n - X
hp : 1 < Nat.succ n✝
aux : g_poly ≠ 0
key : Fintype.card ↑(rootSet g_poly (GaloisField (Nat.succ n✝) n)) = Nat.succ n✝ ^ n
nat_degree_eq : natDegree g_poly = Nat.succ n✝ ^ n
x : GaloisField (Nat.succ n✝) n
hx :
  x ∈
    Subring.closure
      (Set.range ⇑(algebraMap (ZMod (Nat.succ n✝)) (GaloisField (Nat.succ n✝) n)) ∪
        rootSet (X ^ Nat.succ n✝ ^ n - X) (SplittingField (X ^ Nat.succ n✝ ^ n - X)))
hn : 0 = Nat.succ n✝ ^ n
⊢ False

Next tactic:
exact Nat.not_lt_zero 1 (pow_eq_zero hn.symm ▸ hp)