-- Mathlib/RingTheory/Polynomial/Eisenstein/IsIntegral.lean
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)

Proof state:
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 (Q.natDegree + 1), p • f ↑i • x ^ ↑i = p • z
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}

Tactic:
rw [← smul_sum] at hz

Result:
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 (Q.natDegree + 1), f ↑x_1 • x ^ ↑x_1 = p • z
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}

Proof state:
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 (Q.natDegree + 1), f ↑x_1 • x ^ ↑x_1 = p • z
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}

Tactic:
rw [← smul_right_injective _ hp hz]

Result:
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 (Q.natDegree + 1), f ↑x_1 • x ^ ↑x_1 = p • z
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ ∑ x_1 : Fin (Q.natDegree + 1), f ↑x_1 • x ^ ↑x_1 ∈ adjoin A {x}

Proof state:
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 (Q.natDegree + 1), f ↑x_1 • x ^ ↑x_1 = p • z
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ ∑ x_1 : Fin (Q.natDegree + 1), f ↑x_1 • x ^ ↑x_1 ∈ adjoin A {x}

Tactic:
exact
  Subalgebra.sum_mem _ fun _ _ =>
    Subalgebra.smul_mem _ (Subalgebra.pow_mem _ (subset_adjoin (Set.mem_singleton _)) _) _

Result:
no goals

Proof state:
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 (Q.natDegree + 1), p ∣ Q.coeff i
hz : (aeval x) Q = p • z
⊢ z ∈ adjoin A {x}

Tactic:
choose! f hf using hQ

Result:
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 (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}

Proof state:
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 (Q.natDegree + 1), Q.coeff ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}

Tactic:
conv_lhs at hz =>
  congr
  next => skip
  ext i
  rw [hf i (mem_range.2 (Fin.is_lt i)), ← smul_smul]

Result:
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 (Q.natDegree + 1), p • f ↑i • x ^ ↑i = p • z
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}

Proof state:
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 (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}

Tactic:
rw [aeval_eq_sum_range, sum_range] at hz

Result:
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 (Q.natDegree + 1), Q.coeff ↑i • x ^ ↑i = p • z
f : ℕ → A
hf : ∀ i ∈ range (Q.natDegree + 1), Q.coeff i = p * f i
⊢ z ∈ adjoin A {x}