l3lab/ntp-mathlib huggingface dataset:
/-- Let `K` be the field of fraction of an integrally closed domain `R` and let `L` be a separable
extension of `K`, generated by an integral power basis `B` such that the minimal polynomial of
`B.gen` is Eisenstein at `p`. Given `z : L` integral over `R`, if `Q : R[X]` is such that
`aeval B.gen Q = p • z`, then `p ∣ Q.coeff 0`. -/
theorem dvd_coeff_zero_of_aeval_eq_prime_smul_of_minpoly_isEisensteinAt {B : PowerBasis K L}
    (hp : Prime p) (hBint : IsIntegral R B.gen) {z : L} {Q : R[X]} (hQ : aeval B.gen Q = p • z)
    (hzint : IsIntegral R z) (hei : (minpoly R B.gen).IsEisensteinAt 𝓟) : p ∣ Q.coeff 0 := by
  -- First define some abbreviations.
  letI := B.finiteDimensional
  let P := minpoly R B.gen
  obtain ⟨n, hn⟩ := Nat.exists_eq_succ_of_ne_zero B.dim_pos.ne'
  have finrank_K_L : FiniteDimensional.finrank K L = B.dim := B.finrank
  have deg_K_P : (minpoly K B.gen).natDegree = B.dim := B.natDegree_minpoly
  have deg_R_P : P.natDegree = B.dim := by
    rw [← deg_K_P, minpoly.isIntegrallyClosed_eq_field_fractions' K hBint,
      (minpoly.monic hBint).natDegree_map (algebraMap R K)]
  choose! f hf using
    hei.isWeaklyEisensteinAt.exists_mem_adjoin_mul_eq_pow_natDegree_le (minpoly.aeval R B.gen)
      (minpoly.monic hBint)
  simp only [(minpoly.monic hBint).natDegree_map, deg_R_P] at hf

  -- The Eisenstein condition shows that `p` divides `Q.coeff 0`
  -- if `p^n.succ` divides the following multiple of `Q.coeff 0^n.succ`:
  suffices
      p ^ n.succ ∣ Q.coeff 0 ^ n.succ * ((-1) ^ (n.succ * n) * (minpoly R B.gen).coeff 0 ^ n) by
    have hndiv : ¬p ^ 2 ∣ (minpoly R B.gen).coeff 0 := fun h =>
      hei.not_mem ((span_singleton_pow p 2).symm ▸ Ideal.mem_span_singleton.2 h)
    refine @Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd R _ _ _ _ n hp (?_ : _ ∣ _) hndiv
    convert (IsUnit.dvd_mul_right ⟨(-1) ^ (n.succ * n), rfl⟩).mpr this using 1
    push_cast
    ring_nf
    rw [mul_comm _ 2, pow_mul, neg_one_sq, one_pow, mul_one]

  -- We claim the quotient of `Q^n * _` by `p^n` is the following `r`:
  have aux : ∀ i ∈ (range (Q.natDegree + 1)).erase 0, B.dim ≤ i + n := by
    intro i hi
    simp only [mem_range, mem_erase] at hi
    

Proof state:
R : Type u
K : Type v
L : Type z
p : R
inst✝¹⁰ : CommRing R
inst✝⁹ : Field K
inst✝⁸ : Field L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra R L
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K L
inst✝³ : IsSeparable K L
inst✝² : IsDomain R
inst✝¹ : IsFractionRing R K
inst✝ : IsIntegrallyClosed R
B : PowerBasis K L
hp : _root_.Prime p
hBint : IsIntegral R B.gen
z : L
Q : R[X]
hQ : (aeval B.gen) Q = p • z
hzint : IsIntegral R z
hei : IsEisensteinAt (minpoly R B.gen) (Submodule.span R {p})
this : FiniteDimensional K L := finiteDimensional B
P : R[X] := minpoly R B.gen
n : ℕ
hn : B.dim = succ n
finrank_K_L : FiniteDimensional.finrank K L = B.dim
deg_K_P : natDegree (minpoly K B.gen) = B.dim
deg_R_P : natDegree P = B.dim
f : ℕ → L
hf : ∀ (i : ℕ), B.dim ≤ i → f i ∈ adjoin R {B.gen} ∧ (algebraMap R L) p * f i = B.gen ^ i
i : ℕ
hi : i ≠ 0 ∧ i < natDegree Q + 1
⊢ B.dim ≤ i + n

Next tactic:
rw [hn]
/-- Let `K` be the field of fraction of an integrally closed domain `R` and let `L` be a separable
extension of `K`, generated by an integral power basis `B` such that the minimal polynomial of
`B.gen` is Eisenstein at `p`. Given `z : L` integral over `R`, if `Q : R[X]` is such that
`aeval B.gen Q = p • z`, then `p ∣ Q.coeff 0`. -/
theorem dvd_coeff_zero_of_aeval_eq_prime_smul_of_minpoly_isEisensteinAt {B : PowerBasis K L}
    (hp : Prime p) (hBint : IsIntegral R B.gen) {z : L} {Q : R[X]} (hQ : aeval B.gen Q = p • z)
    (hzint : IsIntegral R z) (hei : (minpoly R B.gen).IsEisensteinAt 𝓟) : p ∣ Q.coeff 0 := by
  -- First define some abbreviations.
  letI := B.finiteDimensional
  let P := minpoly R B.gen
  obtain ⟨n, hn⟩ := Nat.exists_eq_succ_of_ne_zero B.dim_pos.ne'
  have finrank_K_L : FiniteDimensional.finrank K L = B.dim := B.finrank
  have deg_K_P : (minpoly K B.gen).natDegree = B.dim := B.natDegree_minpoly
  have deg_R_P : P.natDegree = B.dim := by
    rw [← deg_K_P, minpoly.isIntegrallyClosed_eq_field_fractions' K hBint,
      (minpoly.monic hBint).natDegree_map (algebraMap R K)]
  choose! f hf using
    hei.isWeaklyEisensteinAt.exists_mem_adjoin_mul_eq_pow_natDegree_le (minpoly.aeval R B.gen)
      (minpoly.monic hBint)
  simp only [(minpoly.monic hBint).natDegree_map, deg_R_P] at hf

  -- The Eisenstein condition shows that `p` divides `Q.coeff 0`
  -- if `p^n.succ` divides the following multiple of `Q.coeff 0^n.succ`:
  suffices
      p ^ n.succ ∣ Q.coeff 0 ^ n.succ * ((-1) ^ (n.succ * n) * (minpoly R B.gen).coeff 0 ^ n) by
    have hndiv : ¬p ^ 2 ∣ (minpoly R B.gen).coeff 0 := fun h =>
      hei.not_mem ((span_singleton_pow p 2).symm ▸ Ideal.mem_span_singleton.2 h)
    refine @Prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd R _ _ _ _ n hp (?_ : _ ∣ _) hndiv
    convert (IsUnit.dvd_mul_right ⟨(-1) ^ (n.succ * n), rfl⟩).mpr this using 1
    push_cast
    ring_nf
    rw [mul_comm _ 2, pow_mul, neg_one_sq, one_pow, mul_one]

  -- We claim the quotient of `Q^n * _` by `p^n` is the following `r`:
  have aux : ∀ i ∈ (range (Q.natDegree + 1)).erase 0, B.dim ≤ i + n := by
    intro i hi
    simp only [mem_range, mem_erase] at hi
    rw [hn]
    

Proof state:
R : Type u
K : Type v
L : Type z
p : R
inst✝¹⁰ : CommRing R
inst✝⁹ : Field K
inst✝⁸ : Field L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra R L
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K L
inst✝³ : IsSeparable K L
inst✝² : IsDomain R
inst✝¹ : IsFractionRing R K
inst✝ : IsIntegrallyClosed R
B : PowerBasis K L
hp : _root_.Prime p
hBint : IsIntegral R B.gen
z : L
Q : R[X]
hQ : (aeval B.gen) Q = p • z
hzint : IsIntegral R z
hei : IsEisensteinAt (minpoly R B.gen) (Submodule.span R {p})
this : FiniteDimensional K L := finiteDimensional B
P : R[X] := minpoly R B.gen
n : ℕ
hn : B.dim = succ n
finrank_K_L : FiniteDimensional.finrank K L = B.dim
deg_K_P : natDegree (minpoly K B.gen) = B.dim
deg_R_P : natDegree P = B.dim
f : ℕ → L
hf : ∀ (i : ℕ), B.dim ≤ i → f i ∈ adjoin R {B.gen} ∧ (algebraMap R L) p * f i = B.gen ^ i
i : ℕ
hi : i ≠ 0 ∧ i < natDegree Q + 1
⊢ succ n ≤ i + n

Next tactic:
exact le_add_pred_of_pos _ hi.1
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hQ : ∀ i ∈ range (natDegree Q + 1), p ∣ coeff Q i
hz : (aeval x) Q = p • z
⊢ z ∈ adjoin A {x}

Next tactic:
choose! f hf using hQ
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : (aeval x) Q = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
⊢ z ∈ adjoin A {x}

Next tactic:
rw [aeval_eq_sum_range, sum_range] at hz
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
⊢ z ∈ adjoin A {x}

Next tactic:
conv_lhs at hz =>
    congr
    next => skip
    ext i
    rw [hf i (mem_range.2 (Fin.is_lt i)), ← smul_smul]
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
| ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i

Next tactic:
congr
    next => skip
    ext i
    rw [hf i (mem_range.2 (Fin.is_lt i)), ← smul_smul]
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
| ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i

Next tactic:
congr
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    congr
    

Proof state:
case s
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
| univ
case f
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
| fun i => coeff Q ↑i • x ^ ↑i

Next tactic:
next => skip
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    congr
    next => 

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
| univ

Next tactic:
skip
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    congr
    next => skip
    

Proof state:
case f
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
| fun i => coeff Q ↑i • x ^ ↑i

Next tactic:
ext i
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    congr
    next => skip
    ext i
    

Proof state:
case f.h
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
hz : ∑ i : Fin (natDegree Q + 1), coeff Q ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
i : Fin (natDegree Q + 1)
| coeff Q ↑i • x ^ ↑i

Next tactic:
rw [hf i (mem_range.2 (Fin.is_lt i)), ← smul_smul]
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    congr
    next => skip
    ext i
    rw [hf i (mem_range.2 (Fin.is_lt i)), ← smul_smul]
  

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
f : ℕ → A
hz : ∑ i : Fin (natDegree Q + 1), p • f ↑i • x ^ ↑i = p • z
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
⊢ z ∈ adjoin A {x}

Next tactic:
rw [← smul_sum] at hz
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    congr
    next => skip
    ext i
    rw [hf i (mem_range.2 (Fin.is_lt i)), ← smul_smul]
  rw [← smul_sum] at hz
  

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
f : ℕ → A
hz : p • ∑ x_1 : Fin (natDegree Q + 1), f ↑x_1 • x ^ ↑x_1 = p • z
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
⊢ z ∈ adjoin A {x}

Next tactic:
rw [← smul_right_injective _ hp hz]
theorem mem_adjoin_of_dvd_coeff_of_dvd_aeval {A B : Type*} [CommSemiring A] [CommRing B]
    [Algebra A B] [NoZeroSMulDivisors A B] {Q : A[X]} {p : A} {x z : B} (hp : p ≠ 0)
    (hQ : ∀ i ∈ range (Q.natDegree + 1), p ∣ Q.coeff i) (hz : aeval x Q = p • z) :
    z ∈ adjoin A ({x} : Set B) := by
  choose! f hf using hQ
  rw [aeval_eq_sum_range, sum_range] at hz
  conv_lhs at hz =>
    congr
    next => skip
    ext i
    rw [hf i (mem_range.2 (Fin.is_lt i)), ← smul_smul]
  rw [← smul_sum] at hz
  rw [← smul_right_injective _ hp hz]
  

Proof state:
R : Type u
K : Type v
L : Type z
p✝ : R
inst✝¹⁴ : CommRing R
inst✝¹³ : Field K
inst✝¹² : Field L
inst✝¹¹ : Algebra K L
inst✝¹⁰ : Algebra R L
inst✝⁹ : Algebra R K
inst✝⁸ : IsScalarTower R K L
inst✝⁷ : IsSeparable K L
inst✝⁶ : IsDomain R
inst✝⁵ : IsFractionRing R K
inst✝⁴ : IsIntegrallyClosed R
A : Type u_1
B : Type u_2
inst✝³ : CommSemiring A
inst✝² : CommRing B
inst✝¹ : Algebra A B
inst✝ : NoZeroSMulDivisors A B
Q : A[X]
p : A
x z : B
hp : p ≠ 0
f : ℕ → A
hz : p • ∑ x_1 : Fin (natDegree Q + 1), f ↑x_1 • x ^ ↑x_1 = p • z
hf : ∀ i ∈ range (natDegree Q + 1), coeff Q i = p * f i
⊢ ∑ x_1 : Fin (natDegree Q + 1), f ↑x_1 • x ^ ↑x_1 ∈ adjoin A {x}

Next tactic:
exact
    Subalgebra.sum_mem _ fun _ _ =>
      Subalgebra.smul_mem _ (Subalgebra.pow_mem _ (subset_adjoin (Set.mem_singleton _)) _) _
/-- Let `K` be the field of fraction of an integrally closed domain `R` and let `L` be a separable
extension of `K`, generated by an integral power basis `B` such that the minimal polynomial of
`B.gen` is Eisenstein at `p`. Given `z : L` integral over `R`, if `p • z ∈ adjoin R {B.gen}`, then
`z ∈ adjoin R {B.gen}`. -/
theorem mem_adjoin_of_smul_prime_smul_of_minpoly_isEisensteinAt {B : PowerBasis K L}
    (hp : Prime p) (hBint : IsIntegral R B.gen) {z : L} (hzint : IsIntegral R z)
    (hz : p • z ∈ adjoin R ({B.gen} : Set L)) (hei : (minpoly R B.gen).IsEisensteinAt 𝓟) :
    z ∈ adjoin R ({B.gen} : Set L) := by
  -- First define some abbreviations.
  

Proof state:
R : Type u
K : Type v
L : Type z
p : R
inst✝¹⁰ : CommRing R
inst✝⁹ : Field K
inst✝⁸ : Field L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra R L
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K L
inst✝³ : IsSeparable K L
inst✝² : IsDomain R
inst✝¹ : IsFractionRing R K
inst✝ : IsIntegrallyClosed R
B : PowerBasis K L
hp : _root_.Prime p
hBint : IsIntegral R B.gen
z : L
hzint : IsIntegral R z
hz : p • z ∈ adjoin R {B.gen}
hei : IsEisensteinAt (minpoly R B.gen) (Submodule.span R {p})
⊢ z ∈ adjoin R {B.gen}

Next tactic:
have hndiv : ¬p ^ 2 ∣ (minpoly R B.gen).coeff 0 := fun h =>
    hei.not_mem ((span_singleton_pow p 2).symm ▸ Ideal.mem_span_singleton.2 h)
/-- Let `K` be the field of fraction of an integrally closed domain `R` and let `L` be a separable
extension of `K`, generated by an integral power basis `B` such that the minimal polynomial of
`B.gen` is Eisenstein at `p`. Given `z : L` integral over `R`, if `p • z ∈ adjoin R {B.gen}`, then
`z ∈ adjoin R {B.gen}`. -/
theorem mem_adjoin_of_smul_prime_smul_of_minpoly_isEisensteinAt {B : PowerBasis K L}
    (hp : Prime p) (hBint : IsIntegral R B.gen) {z : L} (hzint : IsIntegral R z)
    (hz : p • z ∈ adjoin R ({B.gen} : Set L)) (hei : (minpoly R B.gen).IsEisensteinAt 𝓟) :
    z ∈ adjoin R ({B.gen} : Set L) := by
  -- First define some abbreviations.
  have hndiv : ¬p ^ 2 ∣ (minpoly R B.gen).coeff 0 := fun h =>
    hei.not_mem ((span_singleton_pow p 2).symm ▸ Ideal.mem_span_singleton.2 h)
  

Proof state:
R : Type u
K : Type v
L : Type z
p : R
inst✝¹⁰ : CommRing R
inst✝⁹ : Field K
inst✝⁸ : Field L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra R L
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K L
inst✝³ : IsSeparable K L
inst✝² : IsDomain R
inst✝¹ : IsFractionRing R K
inst✝ : IsIntegrallyClosed R
B : PowerBasis K L
hp : _root_.Prime p
hBint : IsIntegral R B.gen
z : L
hzint : IsIntegral R z
hz : p • z ∈ adjoin R {B.gen}
hei : IsEisensteinAt (minpoly R B.gen) (Submodule.span R {p})
hndiv : ¬p ^ 2 ∣ coeff (minpoly R B.gen) 0
⊢ z ∈ adjoin R {B.gen}

Next tactic:
letI := finiteDimensional B
/-- Let `K` be the field of fraction of an integrally closed domain `R` and let `L` be a separable
extension of `K`, generated by an integral power basis `B` such that the minimal polynomial of
`B.gen` is Eisenstein at `p`. Given `z : L` integral over `R`, if `p • z ∈ adjoin R {B.gen}`, then
`z ∈ adjoin R {B.gen}`. -/
theorem mem_adjoin_of_smul_prime_smul_of_minpoly_isEisensteinAt {B : PowerBasis K L}
    (hp : Prime p) (hBint : IsIntegral R B.gen) {z : L} (hzint : IsIntegral R z)
    (hz : p • z ∈ adjoin R ({B.gen} : Set L)) (hei : (minpoly R B.gen).IsEisensteinAt 𝓟) :
    z ∈ adjoin R ({B.gen} : Set L) := by
  -- First define some abbreviations.
  have hndiv : ¬p ^ 2 ∣ (minpoly R B.gen).coeff 0 := fun h =>
    hei.not_mem ((span_singleton_pow p 2).symm ▸ Ideal.mem_span_singleton.2 h)
  letI := finiteDimensional B
  

Proof state:
R : Type u
K : Type v
L : Type z
p : R
inst✝¹⁰ : CommRing R
inst✝⁹ : Field K
inst✝⁸ : Field L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra R L
inst✝⁵ : Algebra R K
inst✝⁴ : IsScalarTower R K L
inst✝³ : IsSeparable K L
inst✝² : IsDomain R
inst✝¹ : IsFractionRing R K
inst✝ : IsIntegrallyClosed R
B : PowerBasis K L
hp : _root_.Prime p
hBint : IsIntegral R B.gen
z : L
hzint : IsIntegral R z
hz : p • z ∈ adjoin R {B.gen}
hei : IsEisensteinAt (minpoly R B.gen) (Submodule.span R {p})
hndiv : ¬p ^ 2 ∣ coeff (minpoly R B.gen) 0
this : FiniteDimensional K L := finiteDimensional B
⊢ z ∈ adjoin R {B.gen}

Next tactic:
set P := minpoly R B.gen with hP