l3lab/ntp-mathlib huggingface dataset:
/-- Given a `p : R[X]` and a `x : S` such that `p.eval₂ f x = 0`,
`f p.leadingCoeff * x` is integral. -/
theorem RingHom.isIntegralElem_leadingCoeff_mul (h : p.eval₂ f x = 0) :
    f.IsIntegralElem (f p.leadingCoeff * x) := by
  by_cases h' : 1 ≤ p.natDegree
  · use normalizeScaleRoots p
    have : p ≠ 0 := fun h'' => by
      rw [h'', natDegree_zero] at h'
      exact Nat.not_succ_le_zero 0 h'
    use normalizeScaleRoots_monic p this
    rw [normalizeScaleRoots_eval₂_leadingCoeff_mul p h' f x, h, mul_zero]
  · by_cases hp : p.map f = 0
    · apply_fun fun q => coeff q p.natDegree at hp
      rw [coeff_map, coeff_zero, coeff_natDegree] at hp
      rw [hp, zero_mul]
      exact f.isIntegralElem_zero
    · rw [Nat.one_le_iff_ne_zero, Classical.not_not] at h'
      rw [eq_C_of_natDegree_eq_zero h', eval₂_C] at h
      suffices p.map f = 0 by exact (hp this).elim
      

Proof state:
case neg
R : Type u_1
A : Type u_2
B : Type u_3
S : Type u_4
inst✝⁵ : CommRing R
inst✝⁴ : CommRing A
inst✝³ : Ring B
inst✝² : CommRing S
inst✝¹ : Algebra R A
inst✝ : Algebra R B
f✝¹ : R →+* S
f✝ : R →+* B
f : R →+* S
p : R[X]
x : S
h : f (coeff p 0) = 0
h' : natDegree p = 0
hp : ¬Polynomial.map f p = 0
⊢ Polynomial.map f p = 0

Next tactic:
rw [eq_C_of_natDegree_eq_zero h', map_C, h, C_eq_zero]
/-- Given a `p : R[X]` and a root `x : S`,
then `p.leadingCoeff • x : S` is integral over `R`. -/
theorem isIntegral_leadingCoeff_smul [Algebra R S] (h : aeval x p = 0) :
    IsIntegral R (p.leadingCoeff • x) := by
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
S : Type u_4
inst✝⁶ : CommRing R
inst✝⁵ : CommRing A
inst✝⁴ : Ring B
inst✝³ : CommRing S
inst✝² : Algebra R A
inst✝¹ : Algebra R B
f✝¹ : R →+* S
f✝ : R →+* B
f : R →+* S
p : R[X]
x : S
inst✝ : Algebra R S
h : (aeval x) p = 0
⊢ IsIntegral R (leadingCoeff p • x)

Next tactic:
rw [aeval_def] at h
/-- Given a `p : R[X]` and a root `x : S`,
then `p.leadingCoeff • x : S` is integral over `R`. -/
theorem isIntegral_leadingCoeff_smul [Algebra R S] (h : aeval x p = 0) :
    IsIntegral R (p.leadingCoeff • x) := by
  rw [aeval_def] at h
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
S : Type u_4
inst✝⁶ : CommRing R
inst✝⁵ : CommRing A
inst✝⁴ : Ring B
inst✝³ : CommRing S
inst✝² : Algebra R A
inst✝¹ : Algebra R B
f✝¹ : R →+* S
f✝ : R →+* B
f : R →+* S
p : R[X]
x : S
inst✝ : Algebra R S
h : eval₂ (algebraMap R S) x p = 0
⊢ IsIntegral R (leadingCoeff p • x)

Next tactic:
rw [Algebra.smul_def]
/-- Given a `p : R[X]` and a root `x : S`,
then `p.leadingCoeff • x : S` is integral over `R`. -/
theorem isIntegral_leadingCoeff_smul [Algebra R S] (h : aeval x p = 0) :
    IsIntegral R (p.leadingCoeff • x) := by
  rw [aeval_def] at h
  rw [Algebra.smul_def]
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
S : Type u_4
inst✝⁶ : CommRing R
inst✝⁵ : CommRing A
inst✝⁴ : Ring B
inst✝³ : CommRing S
inst✝² : Algebra R A
inst✝¹ : Algebra R B
f✝¹ : R →+* S
f✝ : R →+* B
f : R →+* S
p : R[X]
x : S
inst✝ : Algebra R S
h : eval₂ (algebraMap R S) x p = 0
⊢ IsIntegral R ((algebraMap R S) (leadingCoeff p) * x)

Next tactic:
exact (algebraMap R S).isIntegralElem_leadingCoeff_mul p x h
instance integralClosure.isIntegralClosure (R A : Type*) [CommRing R] [CommRing A] [Algebra R A] :
    IsIntegralClosure (integralClosure R A) R A where
  algebraMap_injective' := Subtype.coe_injective
  isIntegral_iff {x} := ⟨fun h => ⟨⟨x, h⟩, rfl⟩, by 

Proof state:
R : Type u_1
A : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing A
inst✝ : Algebra R A
x : A
⊢ (∃ y, (algebraMap (↥(integralClosure R A)) A) y = x) → IsIntegral R x

Next tactic:
rintro ⟨⟨_, h⟩, rfl⟩
instance integralClosure.isIntegralClosure (R A : Type*) [CommRing R] [CommRing A] [Algebra R A] :
    IsIntegralClosure (integralClosure R A) R A where
  algebraMap_injective' := Subtype.coe_injective
  isIntegral_iff {x} := ⟨fun h => ⟨⟨x, h⟩, rfl⟩, by rintro ⟨⟨_, h⟩, rfl⟩; 

Proof state:
case intro.mk
R : Type u_1
A : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing A
inst✝ : Algebra R A
val✝ : A
h : val✝ ∈ integralClosure R A
⊢ IsIntegral R ((algebraMap (↥(integralClosure R A)) A) { val := val✝, property := h })

Next tactic:
exact h
theorem noZeroSMulDivisors [Algebra R A] [IsScalarTower R A B] [NoZeroSMulDivisors R B] :
    NoZeroSMulDivisors R A := by
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : CommRing B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsIntegralClosure A R B
inst✝² : Algebra R A
inst✝¹ : IsScalarTower R A B
inst✝ : NoZeroSMulDivisors R B
⊢ NoZeroSMulDivisors R A

Next tactic:
refine'
    Function.Injective.noZeroSMulDivisors _ (IsIntegralClosure.algebraMap_injective A R B)
      (map_zero _) fun _ _ => _
theorem noZeroSMulDivisors [Algebra R A] [IsScalarTower R A B] [NoZeroSMulDivisors R B] :
    NoZeroSMulDivisors R A := by
  refine'
    Function.Injective.noZeroSMulDivisors _ (IsIntegralClosure.algebraMap_injective A R B)
      (map_zero _) fun _ _ => _
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : CommRing B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsIntegralClosure A R B
inst✝² : Algebra R A
inst✝¹ : IsScalarTower R A B
inst✝ : NoZeroSMulDivisors R B
x✝¹ : R
x✝ : A
⊢ (algebraMap A B) (x✝¹ • x✝) = x✝¹ • (algebraMap A B) x✝

Next tactic:
simp only [Algebra.algebraMap_eq_smul_one, IsScalarTower.smul_assoc]
@[simp]
theorem mk'_one (h : IsIntegral R (1 : B) := isIntegral_one) : mk' A 1 h = 1 :=
  algebraMap_injective A R B <| by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝⁵ : CommRing R
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsIntegralClosure A R B
h : optParam (IsIntegral R 1) (_ : IsIntegral R 1)
⊢ (algebraMap A B) (mk' A 1 h) = (algebraMap A B) 1

Next tactic:
rw [algebraMap_mk', RingHom.map_one]
@[simp]
theorem mk'_zero (h : IsIntegral R (0 : B) := isIntegral_zero) : mk' A 0 h = 0 :=
  algebraMap_injective A R B <| by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝⁵ : CommRing R
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsIntegralClosure A R B
h : optParam (IsIntegral R 0) (_ : IsIntegral R 0)
⊢ (algebraMap A B) (mk' A 0 h) = (algebraMap A B) 0

Next tactic:
rw [algebraMap_mk', RingHom.map_zero]
theorem mk'_add (x y : B) (hx : IsIntegral R x) (hy : IsIntegral R y) :
    mk' A (x + y) (hx.add hy) = mk' A x hx + mk' A y hy :=
  algebraMap_injective A R B <| by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝⁵ : CommRing R
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsIntegralClosure A R B
x y : B
hx : IsIntegral R x
hy : IsIntegral R y
⊢ (algebraMap A B) (mk' A (x + y) (_ : IsIntegral R (x + y))) = (algebraMap A B) (mk' A x hx + mk' A y hy)

Next tactic:
simp only [algebraMap_mk', RingHom.map_add]
theorem mk'_mul (x y : B) (hx : IsIntegral R x) (hy : IsIntegral R y) :
    mk' A (x * y) (hx.mul hy) = mk' A x hx * mk' A y hy :=
  algebraMap_injective A R B <| by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝⁵ : CommRing R
inst✝⁴ : CommRing A
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsIntegralClosure A R B
x y : B
hx : IsIntegral R x
hy : IsIntegral R y
⊢ (algebraMap A B) (mk' A (x * y) (_ : IsIntegral R (x * y))) = (algebraMap A B) (mk' A x hx * mk' A y hy)

Next tactic:
simp only [algebraMap_mk', RingHom.map_mul]
@[simp]
theorem mk'_algebraMap [Algebra R A] [IsScalarTower R A B] (x : R)
    (h : IsIntegral R (algebraMap R B x) := isIntegral_algebraMap) :
    IsIntegralClosure.mk' A (algebraMap R B x) h = algebraMap R A x :=
  algebraMap_injective A R B <| by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : CommRing A
inst✝⁵ : CommRing B
inst✝⁴ : Algebra R B
inst✝³ : Algebra A B
inst✝² : IsIntegralClosure A R B
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
x : R
h : optParam (IsIntegral R ((algebraMap R B) x)) (_ : IsIntegral R ((algebraMap R B) x))
⊢ (algebraMap A B) (mk' A ((algebraMap R B) x) h) = (algebraMap A B) ((algebraMap R A) x)

Next tactic:
rw [algebraMap_mk', ← IsScalarTower.algebraMap_apply]
/-- If `B / S / R` is a tower of ring extensions where `S` is integral over `R`,
then `S` maps (uniquely) into an integral closure `B / A / R`. -/
noncomputable def lift : S →ₐ[R] A where
  toFun x := mk' A (algebraMap S B x) (IsIntegral.algebraMap (h x))
  map_one' := by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹¹ : CommRing R
inst✝¹⁰ : CommRing A
inst✝⁹ : CommRing B
inst✝⁸ : Algebra R B
inst✝⁷ : Algebra A B
inst✝⁶ : IsIntegralClosure A R B
S : Type u_4
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : Algebra S B
inst✝² : IsScalarTower R S B
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
h : Algebra.IsIntegral R S
⊢ (fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x))) 1 = 1

Next tactic:
simp only [RingHom.map_one, mk'_one]
/-- If `B / S / R` is a tower of ring extensions where `S` is integral over `R`,
then `S` maps (uniquely) into an integral closure `B / A / R`. -/
noncomputable def lift : S →ₐ[R] A where
  toFun x := mk' A (algebraMap S B x) (IsIntegral.algebraMap (h x))
  map_one' := by simp only [RingHom.map_one, mk'_one]
  map_zero' := by simp only [RingHom.map_zero, mk'_zero]
  map_add' x y := by simp_rw [← mk'_add, RingHom.map_add]
  map_mul' x y := by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹¹ : CommRing R
inst✝¹⁰ : CommRing A
inst✝⁹ : CommRing B
inst✝⁸ : Algebra R B
inst✝⁷ : Algebra A B
inst✝⁶ : IsIntegralClosure A R B
S : Type u_4
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : Algebra S B
inst✝² : IsScalarTower R S B
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
h : Algebra.IsIntegral R S
x y : S
⊢ OneHom.toFun
      { toFun := fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x)),
        map_one' := (_ : mk' A ((algebraMap S B) 1) (_ : IsIntegral R ((algebraMap S B) 1)) = 1) }
      (x * y) =
    OneHom.toFun
        { toFun := fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x)),
          map_one' := (_ : mk' A ((algebraMap S B) 1) (_ : IsIntegral R ((algebraMap S B) 1)) = 1) }
        x *
      OneHom.toFun
        { toFun := fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x)),
          map_one' := (_ : mk' A ((algebraMap S B) 1) (_ : IsIntegral R ((algebraMap S B) 1)) = 1) }
        y

Next tactic:
simp_rw [← mk'_mul, RingHom.map_mul]
/-- If `B / S / R` is a tower of ring extensions where `S` is integral over `R`,
then `S` maps (uniquely) into an integral closure `B / A / R`. -/
noncomputable def lift : S →ₐ[R] A where
  toFun x := mk' A (algebraMap S B x) (IsIntegral.algebraMap (h x))
  map_one' := by simp only [RingHom.map_one, mk'_one]
  map_zero' := by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹¹ : CommRing R
inst✝¹⁰ : CommRing A
inst✝⁹ : CommRing B
inst✝⁸ : Algebra R B
inst✝⁷ : Algebra A B
inst✝⁶ : IsIntegralClosure A R B
S : Type u_4
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
inst✝³ : Algebra S B
inst✝² : IsScalarTower R S B
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
h : Algebra.IsIntegral R S
⊢ OneHom.toFun
      (↑{
          toOneHom :=
            { toFun := fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x)),
              map_one' := (_ : mk' A ((algebraMap S B) 1) (_ : IsIntegral R ((algebraMap S B) 1)) = 1) },
          map_mul' :=
            (_ :
              ∀ (x y : S),
                OneHom.toFun
                    { toFun := fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x)),
                      map_one' := (_ : mk' A ((algebraMap S B) 1) (_ : IsIntegral R ((algebraMap S B) 1)) = 1) }
                    (x * y) =
                  OneHom.toFun
                      { toFun := fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x)),
                        map_one' := (_ : mk' A ((algebraMap S B) 1) (_ : IsIntegral R ((algebraMap S B) 1)) = 1) }
                      x *
                    OneHom.toFun
                      { toFun := fun x => mk' A ((algebraMap S B) x) (_ : IsIntegral R ((algebraMap S B) x)),
                        map_one' := (_ : mk' A ((algebraMap S B) 1) (_ : IsIntegral R ((algebraMap S B) 1)) = 1) }
                      y) })
      0 =
    0

Next tactic:
simp only [RingHom.map_zero, mk'_zero]
/-- Integral closures are all isomorphic to each other. -/
noncomputable def equiv : A ≃ₐ[R] A' :=
  AlgEquiv.ofAlgHom (lift _ B (isIntegral_algebra R B)) (lift _ B (isIntegral_algebra R B))
    (by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹² : CommRing R
inst✝¹¹ : CommRing A
inst✝¹⁰ : CommRing B
inst✝⁹ : Algebra R B
inst✝⁸ : Algebra A B
inst✝⁷ : IsIntegralClosure A R B
A' : Type u_4
inst✝⁶ : CommRing A'
inst✝⁵ : Algebra A' B
inst✝⁴ : IsIntegralClosure A' R B
inst✝³ : Algebra R A
inst✝² : Algebra R A'
inst✝¹ : IsScalarTower R A B
inst✝ : IsScalarTower R A' B
⊢ AlgHom.comp (lift A' B (_ : Algebra.IsIntegral R A)) (lift A B (_ : Algebra.IsIntegral R A')) = AlgHom.id R A'

Next tactic:
ext x
/-- Integral closures are all isomorphic to each other. -/
noncomputable def equiv : A ≃ₐ[R] A' :=
  AlgEquiv.ofAlgHom (lift _ B (isIntegral_algebra R B)) (lift _ B (isIntegral_algebra R B))
    (by ext x; 

Proof state:
case H
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹² : CommRing R
inst✝¹¹ : CommRing A
inst✝¹⁰ : CommRing B
inst✝⁹ : Algebra R B
inst✝⁸ : Algebra A B
inst✝⁷ : IsIntegralClosure A R B
A' : Type u_4
inst✝⁶ : CommRing A'
inst✝⁵ : Algebra A' B
inst✝⁴ : IsIntegralClosure A' R B
inst✝³ : Algebra R A
inst✝² : Algebra R A'
inst✝¹ : IsScalarTower R A B
inst✝ : IsScalarTower R A' B
x : A'
⊢ (AlgHom.comp (lift A' B (_ : Algebra.IsIntegral R A)) (lift A B (_ : Algebra.IsIntegral R A'))) x = (AlgHom.id R A') x

Next tactic:
apply algebraMap_injective A' R B
/-- Integral closures are all isomorphic to each other. -/
noncomputable def equiv : A ≃ₐ[R] A' :=
  AlgEquiv.ofAlgHom (lift _ B (isIntegral_algebra R B)) (lift _ B (isIntegral_algebra R B))
    (by ext x; apply algebraMap_injective A' R B; 

Proof state:
case H.a
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹² : CommRing R
inst✝¹¹ : CommRing A
inst✝¹⁰ : CommRing B
inst✝⁹ : Algebra R B
inst✝⁸ : Algebra A B
inst✝⁷ : IsIntegralClosure A R B
A' : Type u_4
inst✝⁶ : CommRing A'
inst✝⁵ : Algebra A' B
inst✝⁴ : IsIntegralClosure A' R B
inst✝³ : Algebra R A
inst✝² : Algebra R A'
inst✝¹ : IsScalarTower R A B
inst✝ : IsScalarTower R A' B
x : A'
⊢ (algebraMap A' B)
      ((AlgHom.comp (lift A' B (_ : Algebra.IsIntegral R A)) (lift A B (_ : Algebra.IsIntegral R A'))) x) =
    (algebraMap A' B) ((AlgHom.id R A') x)

Next tactic:
simp
/-- Integral closures are all isomorphic to each other. -/
noncomputable def equiv : A ≃ₐ[R] A' :=
  AlgEquiv.ofAlgHom (lift _ B (isIntegral_algebra R B)) (lift _ B (isIntegral_algebra R B))
    (by ext x; apply algebraMap_injective A' R B; simp)
    (by 

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹² : CommRing R
inst✝¹¹ : CommRing A
inst✝¹⁰ : CommRing B
inst✝⁹ : Algebra R B
inst✝⁸ : Algebra A B
inst✝⁷ : IsIntegralClosure A R B
A' : Type u_4
inst✝⁶ : CommRing A'
inst✝⁵ : Algebra A' B
inst✝⁴ : IsIntegralClosure A' R B
inst✝³ : Algebra R A
inst✝² : Algebra R A'
inst✝¹ : IsScalarTower R A B
inst✝ : IsScalarTower R A' B
⊢ AlgHom.comp (lift A B (_ : Algebra.IsIntegral R A')) (lift A' B (_ : Algebra.IsIntegral R A)) = AlgHom.id R A

Next tactic:
ext x
/-- Integral closures are all isomorphic to each other. -/
noncomputable def equiv : A ≃ₐ[R] A' :=
  AlgEquiv.ofAlgHom (lift _ B (isIntegral_algebra R B)) (lift _ B (isIntegral_algebra R B))
    (by ext x; apply algebraMap_injective A' R B; simp)
    (by ext x; 

Proof state:
case H
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹² : CommRing R
inst✝¹¹ : CommRing A
inst✝¹⁰ : CommRing B
inst✝⁹ : Algebra R B
inst✝⁸ : Algebra A B
inst✝⁷ : IsIntegralClosure A R B
A' : Type u_4
inst✝⁶ : CommRing A'
inst✝⁵ : Algebra A' B
inst✝⁴ : IsIntegralClosure A' R B
inst✝³ : Algebra R A
inst✝² : Algebra R A'
inst✝¹ : IsScalarTower R A B
inst✝ : IsScalarTower R A' B
x : A
⊢ (AlgHom.comp (lift A B (_ : Algebra.IsIntegral R A')) (lift A' B (_ : Algebra.IsIntegral R A))) x = (AlgHom.id R A) x

Next tactic:
apply algebraMap_injective A R B
/-- Integral closures are all isomorphic to each other. -/
noncomputable def equiv : A ≃ₐ[R] A' :=
  AlgEquiv.ofAlgHom (lift _ B (isIntegral_algebra R B)) (lift _ B (isIntegral_algebra R B))
    (by ext x; apply algebraMap_injective A' R B; simp)
    (by ext x; apply algebraMap_injective A R B; 

Proof state:
case H.a
R : Type u_1
A : Type u_2
B : Type u_3
inst✝¹² : CommRing R
inst✝¹¹ : CommRing A
inst✝¹⁰ : CommRing B
inst✝⁹ : Algebra R B
inst✝⁸ : Algebra A B
inst✝⁷ : IsIntegralClosure A R B
A' : Type u_4
inst✝⁶ : CommRing A'
inst✝⁵ : Algebra A' B
inst✝⁴ : IsIntegralClosure A' R B
inst✝³ : Algebra R A
inst✝² : Algebra R A'
inst✝¹ : IsScalarTower R A B
inst✝ : IsScalarTower R A' B
x : A
⊢ (algebraMap A B) ((AlgHom.comp (lift A B (_ : Algebra.IsIntegral R A')) (lift A' B (_ : Algebra.IsIntegral R A))) x) =
    (algebraMap A B) ((AlgHom.id R A) x)

Next tactic:
simp
/-- If A is an R-algebra all of whose elements are integral over R,
and x is an element of an A-algebra that is integral over A, then x is integral over R.-/
theorem isIntegral_trans (A_int : Algebra.IsIntegral R A) (x : B) (hx : IsIntegral A x) :
    IsIntegral R x := by
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
S : Type u_4
T : Type u_5
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : Ring B
inst✝⁵ : CommRing S
inst✝⁴ : CommRing T
inst✝³ : Algebra A B
inst✝² : Algebra R B
f : R →+* S
g : S →+* T
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
A_int : Algebra.IsIntegral R A
x : B
hx : IsIntegral A x
⊢ IsIntegral R x

Next tactic:
rcases hx with ⟨p, pmonic, hp⟩
/-- If A is an R-algebra all of whose elements are integral over R,
and x is an element of an A-algebra that is integral over A, then x is integral over R.-/
theorem isIntegral_trans (A_int : Algebra.IsIntegral R A) (x : B) (hx : IsIntegral A x) :
    IsIntegral R x := by
  rcases hx with ⟨p, pmonic, hp⟩
  

Proof state:
case intro.intro
R : Type u_1
A : Type u_2
B : Type u_3
S : Type u_4
T : Type u_5
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : Ring B
inst✝⁵ : CommRing S
inst✝⁴ : CommRing T
inst✝³ : Algebra A B
inst✝² : Algebra R B
f : R →+* S
g : S →+* T
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
A_int : Algebra.IsIntegral R A
x : B
p : A[X]
pmonic : Monic p
hp : eval₂ (algebraMap A B) x p = 0
⊢ IsIntegral R x

Next tactic:
let S := adjoin R (p.frange : Set A)
/-- If A is an R-algebra all of whose elements are integral over R,
and x is an element of an A-algebra that is integral over A, then x is integral over R.-/
theorem isIntegral_trans (A_int : Algebra.IsIntegral R A) (x : B) (hx : IsIntegral A x) :
    IsIntegral R x := by
  rcases hx with ⟨p, pmonic, hp⟩
  let S := adjoin R (p.frange : Set A)
  

Proof state:
case intro.intro
R : Type u_1
A : Type u_2
B : Type u_3
S✝ : Type u_4
T : Type u_5
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : Ring B
inst✝⁵ : CommRing S✝
inst✝⁴ : CommRing T
inst✝³ : Algebra A B
inst✝² : Algebra R B
f : R →+* S✝
g : S✝ →+* T
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
A_int : Algebra.IsIntegral R A
x : B
p : A[X]
pmonic : Monic p
hp : eval₂ (algebraMap A B) x p = 0
S : Subalgebra R A := adjoin R ↑(frange p)
⊢ IsIntegral R x

Next tactic:
have : Module.Finite R S := ⟨(Subalgebra.toSubmodule S).fg_top.mpr <|
    fg_adjoin_of_finite p.frange.finite_toSet fun a _ ↦ A_int a⟩
/-- If A is an R-algebra all of whose elements are integral over R,
and x is an element of an A-algebra that is integral over A, then x is integral over R.-/
theorem isIntegral_trans (A_int : Algebra.IsIntegral R A) (x : B) (hx : IsIntegral A x) :
    IsIntegral R x := by
  rcases hx with ⟨p, pmonic, hp⟩
  let S := adjoin R (p.frange : Set A)
  have : Module.Finite R S := ⟨(Subalgebra.toSubmodule S).fg_top.mpr <|
    fg_adjoin_of_finite p.frange.finite_toSet fun a _ ↦ A_int a⟩
  

Proof state:
case intro.intro
R : Type u_1
A : Type u_2
B : Type u_3
S✝ : Type u_4
T : Type u_5
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : Ring B
inst✝⁵ : CommRing S✝
inst✝⁴ : CommRing T
inst✝³ : Algebra A B
inst✝² : Algebra R B
f : R →+* S✝
g : S✝ →+* T
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
A_int : Algebra.IsIntegral R A
x : B
p : A[X]
pmonic : Monic p
hp : eval₂ (algebraMap A B) x p = 0
S : Subalgebra R A := adjoin R ↑(frange p)
this : Module.Finite R ↥S
⊢ IsIntegral R x

Next tactic:
let p' : S[X] := p.toSubring S.toSubring subset_adjoin
/-- If A is an R-algebra all of whose elements are integral over R,
and x is an element of an A-algebra that is integral over A, then x is integral over R.-/
theorem isIntegral_trans (A_int : Algebra.IsIntegral R A) (x : B) (hx : IsIntegral A x) :
    IsIntegral R x := by
  rcases hx with ⟨p, pmonic, hp⟩
  let S := adjoin R (p.frange : Set A)
  have : Module.Finite R S := ⟨(Subalgebra.toSubmodule S).fg_top.mpr <|
    fg_adjoin_of_finite p.frange.finite_toSet fun a _ ↦ A_int a⟩
  let p' : S[X] := p.toSubring S.toSubring subset_adjoin
  

Proof state:
case intro.intro
R : Type u_1
A : Type u_2
B : Type u_3
S✝ : Type u_4
T : Type u_5
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : Ring B
inst✝⁵ : CommRing S✝
inst✝⁴ : CommRing T
inst✝³ : Algebra A B
inst✝² : Algebra R B
f : R →+* S✝
g : S✝ →+* T
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
A_int : Algebra.IsIntegral R A
x : B
p : A[X]
pmonic : Monic p
hp : eval₂ (algebraMap A B) x p = 0
S : Subalgebra R A := adjoin R ↑(frange p)
this : Module.Finite R ↥S
p' : (↥S)[X] := toSubring p (Subalgebra.toSubring S) (_ : ↑(frange p) ⊆ ↑(adjoin R ↑(frange p)))
⊢ IsIntegral R x

Next tactic:
have hSx : IsIntegral S x := ⟨p', (p.monic_toSubring _ _).mpr pmonic, by
    rw [IsScalarTower.algebraMap_eq S A B, ← eval₂_map]
    convert hp; apply p.map_toSubring S.toSubring⟩
/-- If A is an R-algebra all of whose elements are integral over R,
and x is an element of an A-algebra that is integral over A, then x is integral over R.-/
theorem isIntegral_trans (A_int : Algebra.IsIntegral R A) (x : B) (hx : IsIntegral A x) :
    IsIntegral R x := by
  rcases hx with ⟨p, pmonic, hp⟩
  let S := adjoin R (p.frange : Set A)
  have : Module.Finite R S := ⟨(Subalgebra.toSubmodule S).fg_top.mpr <|
    fg_adjoin_of_finite p.frange.finite_toSet fun a _ ↦ A_int a⟩
  let p' : S[X] := p.toSubring S.toSubring subset_adjoin
  have hSx : IsIntegral S x := ⟨p', (p.monic_toSubring _ _).mpr pmonic, by
    

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
S✝ : Type u_4
T : Type u_5
inst✝⁸ : CommRing R
inst✝⁷ : CommRing A
inst✝⁶ : Ring B
inst✝⁵ : CommRing S✝
inst✝⁴ : CommRing T
inst✝³ : Algebra A B
inst✝² : Algebra R B
f : R →+* S✝
g : S✝ →+* T
inst✝¹ : Algebra R A
inst✝ : IsScalarTower R A B
A_int : Algebra.IsIntegral R A
x : B
p : A[X]
pmonic : Monic p
hp : eval₂ (algebraMap A B) x p = 0
S : Subalgebra R A := adjoin R ↑(frange p)
this : Module.Finite R ↥S
p' : (↥S)[X] := toSubring p (Subalgebra.toSubring S) (_ : ↑(frange p) ⊆ ↑(adjoin R ↑(frange p)))
⊢ eval₂ (algebraMap (↥S) B) x p' = 0

Next tactic:
rw [IsScalarTower.algebraMap_eq S A B, ← eval₂_map]