-- Mathlib/RingTheory/IntegralClosure/IsIntegral/Basic.lean
theorem Submodule.span_range_natDegree_eq_adjoin {R A} [CommRing R] [Semiring A] [Algebra R A]
    {x : A} {f : R[X]} (hf : f.Monic) (hfx : aeval x f = 0) :
    span R (Finset.image (x ^ ·) (Finset.range (natDegree f))) =
      Subalgebra.toSubmodule (Algebra.adjoin R {x})

Proof state:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
⊢ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree)) = Subalgebra.toSubmodule (Algebra.adjoin R {x})

Tactic:
refine (span_le.mpr fun s hs ↦ ?_).antisymm fun r hr ↦ ?_

Result:
case refine_1
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
s : A
hs : s ∈ ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))
⊢ s ∈ ↑(Subalgebra.toSubmodule (Algebra.adjoin R {x}))

case refine_2
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
r : A
hr : r ∈ Subalgebra.toSubmodule (Algebra.adjoin R {x})
⊢ r ∈ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Proof state:
case refine_2.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
p : R[X]
hr : (aeval x) p ∈ (aeval x).range
⊢ (aeval x) p ∈ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Tactic:
rw [← modByMonic_add_div p hf, map_add, map_mul, hfx,
    zero_mul, add_zero, ← sum_C_mul_X_pow_eq (p %ₘ f), aeval_def, eval₂_sum, sum_def]

Result:
case refine_2.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
p : R[X]
hr : (aeval x) p ∈ (aeval x).range
⊢ ∑ n ∈ (p %ₘ f).support, eval₂ (algebraMap R A) x (C ((p %ₘ f).coeff n) * X ^ n) ∈
    span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Proof state:
case refine_1.intro.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
k : ℕ
hs : x ^ k ∈ ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))
⊢ x ^ k ∈ ↑(Subalgebra.toSubmodule (Algebra.adjoin R {x}))

Tactic:
exact (Algebra.adjoin R {x}).pow_mem (Algebra.subset_adjoin rfl) k

Result:
no goals

Proof state:
case refine_2
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
r : A
hr : r ∈ (aeval x).range
⊢ r ∈ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Tactic:
rcases (aeval x).mem_range.mp hr with ⟨p, rfl⟩

Result:
case refine_2.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
p : R[X]
hr : (aeval x) p ∈ (aeval x).range
⊢ (aeval x) p ∈ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Proof state:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
⊢ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree)) = Subalgebra.toSubmodule (Algebra.adjoin R {x})

Tactic:
have hf1 : f ≠ 1 := by rintro rfl; simp [one_ne_zero' A] at hfx

Result:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
⊢ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree)) = Subalgebra.toSubmodule (Algebra.adjoin R {x})

Proof state:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
a✝ : Nontrivial A
hf : Monic 1
hfx : (aeval x) 1 = 0
⊢ False

Tactic:
simp [one_ne_zero' A] at hfx

Result:
no goals

Proof state:
case refine_2.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
p : R[X]
hr : (aeval x) p ∈ (aeval x).range
⊢ ∑ n ∈ (p %ₘ f).support, eval₂ (algebraMap R A) x (C ((p %ₘ f).coeff n) * X ^ n) ∈
    span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Tactic:
refine sum_mem fun k hkq ↦ ?_

Result:
case refine_2.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
p : R[X]
hr : (aeval x) p ∈ (aeval x).range
k : ℕ
hkq : k ∈ (p %ₘ f).support
⊢ eval₂ (algebraMap R A) x (C ((p %ₘ f).coeff k) * X ^ k) ∈
    span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Proof state:
case refine_1
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
s : A
hs : s ∈ ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))
⊢ s ∈ ↑(Subalgebra.toSubmodule (Algebra.adjoin R {x}))

Tactic:
rcases Finset.mem_image.1 hs with ⟨k, -, rfl⟩

Result:
case refine_1.intro.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
k : ℕ
hs : x ^ k ∈ ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))
⊢ x ^ k ∈ ↑(Subalgebra.toSubmodule (Algebra.adjoin R {x}))

Proof state:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
⊢ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree)) = Subalgebra.toSubmodule (Algebra.adjoin R {x})

Tactic:
nontriviality A

Result:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
⊢ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree)) = Subalgebra.toSubmodule (Algebra.adjoin R {x})

Proof state:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
⊢ f ≠ 1

Tactic:
rintro rfl

Result:
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
a✝ : Nontrivial A
hf : Monic 1
hfx : (aeval x) 1 = 0
⊢ False

Proof state:
case refine_2.intro
R : Type u_5
A : Type u_6
inst✝² : CommRing R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
f : R[X]
hf : f.Monic
hfx : (aeval x) f = 0
a✝ : Nontrivial A
hf1 : f ≠ 1
p : R[X]
hr : (aeval x) p ∈ (aeval x).range
k : ℕ
hkq : k ∈ (p %ₘ f).support
⊢ (p %ₘ f).coeff k • x ^ k ∈ span R ↑(Finset.image (fun x_1 => x ^ x_1) (Finset.range f.natDegree))

Tactic:
exact smul_mem _ _ (subset_span <| Finset.mem_image_of_mem _ <| Finset.mem_range.mpr <|
  (le_natDegree_of_mem_supp _ hkq).trans_lt <| natDegree_modByMonic_lt p hf hf1)

Result:
no goals