File: Mathlib/RingTheory/AdjoinRoot.lean

full_name: AdjoinRoot
code: /-- Adjoin a root of a polynomial `f` to a commutative ring `R`. We define the new ring
as the quotient of `R[X]` by the principal ideal generated by `f`. -/
def AdjoinRoot [CommRing R] (f : R[X]) : Type u 
goal: Type u

full_name: AdjoinRoot.instCommRing
code: instance instCommRing : CommRing (AdjoinRoot f) 
goal: CommRing (AdjoinRoot f)

full_name: AdjoinRoot.instInhabited
code: instance : Inhabited (AdjoinRoot f) 
goal: Inhabited (AdjoinRoot f)

full_name: AdjoinRoot.instDecidableEq
code: instance : DecidableEq (AdjoinRoot f) 
goal: DecidableEq (AdjoinRoot f)

full_name: AdjoinRoot.nontrivial
code: protected theorem nontrivial [IsDomain R] (h : degree f ≠ 0) : Nontrivial (AdjoinRoot f) 
goal: Nontrivial (AdjoinRoot f)

full_name: AdjoinRoot.mk
code: /-- Ring homomorphism from `R[x]` to `AdjoinRoot f` sending `X` to the `root`. -/
def mk : R[X] →+* AdjoinRoot f 
goal: R[X] →+* AdjoinRoot f

full_name: AdjoinRoot.induction_on
code: @[elab_as_elim]
theorem induction_on {C : AdjoinRoot f → Prop} (x : AdjoinRoot f) (ih : ∀ p : R[X], C (mk f p)) :
    C x 
goal: C x

full_name: AdjoinRoot.of
code: /-- Embedding of the original ring `R` into `AdjoinRoot f`. -/
def of : R →+* AdjoinRoot f 
goal: R →+* AdjoinRoot f

full_name: AdjoinRoot.instSMulAdjoinRoot
code: instance instSMulAdjoinRoot [DistribSMul S R] [IsScalarTower S R R] : SMul S (AdjoinRoot f) 
goal: SMul S (AdjoinRoot f)

full_name: AdjoinRoot.instDistribSMulOfIsScalarTower
code: instance [DistribSMul S R] [IsScalarTower S R R] : DistribSMul S (AdjoinRoot f) 
goal: DistribSMul S (AdjoinRoot f)

full_name: AdjoinRoot.smul_mk
code: @[simp]
theorem smul_mk [DistribSMul S R] [IsScalarTower S R R] (a : S) (x : R[X]) :
    a • mk f x = mk f (a • x) 
goal: a • (AdjoinRoot.mk f) x = (AdjoinRoot.mk f) (a • x)

full_name: AdjoinRoot.smul_of
code: theorem smul_of [DistribSMul S R] [IsScalarTower S R R] (a : S) (x : R) :
    a • of f x = of f (a • x) 
goal: a • (AdjoinRoot.of f) x = (AdjoinRoot.of f) (a • x)

full_name: AdjoinRoot.instIsScalarTower
code: instance (R₁ R₂ : Type*) [SMul R₁ R₂] [DistribSMul R₁ R] [DistribSMul R₂ R] [IsScalarTower R₁ R R]
    [IsScalarTower R₂ R R] [IsScalarTower R₁ R₂ R] (f : R[X]) :
    IsScalarTower R₁ R₂ (AdjoinRoot f) 
goal: IsScalarTower R₁ R₂ (AdjoinRoot f)

full_name: AdjoinRoot.instSMulCommClass
code: instance (R₁ R₂ : Type*) [DistribSMul R₁ R] [DistribSMul R₂ R] [IsScalarTower R₁ R R]
    [IsScalarTower R₂ R R] [SMulCommClass R₁ R₂ R] (f : R[X]) :
    SMulCommClass R₁ R₂ (AdjoinRoot f) 
goal: SMulCommClass R₁ R₂ (AdjoinRoot f)

full_name: AdjoinRoot.isScalarTower_right
code: instance isScalarTower_right [DistribSMul S R] [IsScalarTower S R R] :
    IsScalarTower S (AdjoinRoot f) (AdjoinRoot f) 
goal: IsScalarTower S (AdjoinRoot f) (AdjoinRoot f)

full_name: AdjoinRoot.instDistribMulActionOfIsScalarTower
code: instance [Monoid S] [DistribMulAction S R] [IsScalarTower S R R] (f : R[X]) :
    DistribMulAction S (AdjoinRoot f) 
goal: DistribMulAction S (AdjoinRoot f)

full_name: AdjoinRoot.instAlgebra
code: instance [CommSemiring S] [Algebra S R] : Algebra S (AdjoinRoot f) 
goal: Algebra S (AdjoinRoot f)

full_name: AdjoinRoot.algebraMap_eq
code: @[simp]
theorem algebraMap_eq : algebraMap R (AdjoinRoot f) = of f 
goal: algebraMap R (AdjoinRoot f) = AdjoinRoot.of f

full_name: AdjoinRoot.algebraMap_eq'
code: theorem algebraMap_eq' [CommSemiring S] [Algebra S R] :
    algebraMap S (AdjoinRoot f) = (of f).comp (algebraMap S R) 
goal: algebraMap S (AdjoinRoot f) = (AdjoinRoot.of f).comp (algebraMap S R)

full_name: AdjoinRoot.finiteType
code: theorem finiteType : Algebra.FiniteType R (AdjoinRoot f) 
goal: Algebra.FiniteType R (AdjoinRoot f)

full_name: AdjoinRoot.finitePresentation
code: theorem finitePresentation : Algebra.FinitePresentation R (AdjoinRoot f) 
goal: Algebra.FinitePresentation R (AdjoinRoot f)

full_name: AdjoinRoot.root
code: /-- The adjoined root. -/
def root : AdjoinRoot f 
goal: AdjoinRoot f

full_name: AdjoinRoot.hasCoeT
code: instance hasCoeT : CoeTC R (AdjoinRoot f) 
goal: CoeTC R (AdjoinRoot f)

full_name: AdjoinRoot.algHom_ext
code: /-- Two `R`-`AlgHom` from `AdjoinRoot f` to the same `R`-algebra are the same iff
    they agree on `root f`. -/
@[ext]
theorem algHom_ext [Semiring S] [Algebra R S] {g₁ g₂ : AdjoinRoot f →ₐ[R] S}
    (h : g₁ (root f) = g₂ (root f)) : g₁ = g₂ 
goal: g₁ = g₂

full_name: AdjoinRoot.mk_eq_mk
code: @[simp]
theorem mk_eq_mk {g h : R[X]} : mk f g = mk f h ↔ f ∣ g - h 
goal: (AdjoinRoot.mk f) g = (AdjoinRoot.mk f) h ↔ f ∣ g - h

full_name: AdjoinRoot.mk_eq_zero
code: @[simp]
theorem mk_eq_zero {g : R[X]} : mk f g = 0 ↔ f ∣ g 
goal: (AdjoinRoot.mk f) g = 0 ↔ f ∣ g

full_name: AdjoinRoot.mk_self
code: @[simp]
theorem mk_self : mk f f = 0 
goal: (AdjoinRoot.mk f) f = 0

full_name: AdjoinRoot.mk_C
code: @[simp]
theorem mk_C (x : R) : mk f (C x) = x 
goal: (AdjoinRoot.mk f) (Polynomial.C x) = (AdjoinRoot.of f) x

full_name: AdjoinRoot.mk_X
code: @[simp]
theorem mk_X : mk f X = root f 
goal: (AdjoinRoot.mk f) Polynomial.X = AdjoinRoot.root f

full_name: AdjoinRoot.mk_ne_zero_of_degree_lt
code: theorem mk_ne_zero_of_degree_lt (hf : Monic f) {g : R[X]} (h0 : g ≠ 0) (hd : degree g < degree f) :
    mk f g ≠ 0 
goal: (AdjoinRoot.mk f) g ≠ 0

full_name: AdjoinRoot.mk_ne_zero_of_natDegree_lt
code: theorem mk_ne_zero_of_natDegree_lt (hf : Monic f) {g : R[X]} (h0 : g ≠ 0)
    (hd : natDegree g < natDegree f) : mk f g ≠ 0 
goal: (AdjoinRoot.mk f) g ≠ 0

full_name: AdjoinRoot.aeval_eq
code: @[simp]
theorem aeval_eq (p : R[X]) : aeval (root f) p = mk f p 
goal: (Polynomial.aeval (AdjoinRoot.root f)) p = (AdjoinRoot.mk f) p

full_name: AdjoinRoot.adjoinRoot_eq_top
code: theorem adjoinRoot_eq_top : Algebra.adjoin R ({root f} : Set (AdjoinRoot f)) = ⊤ 
goal: Algebra.adjoin R {AdjoinRoot.root f} = ⊤

full_name: AdjoinRoot.eval₂_root
code: @[simp]
theorem eval₂_root (f : R[X]) : f.eval₂ (of f) (root f) = 0 
goal: Polynomial.eval₂ (AdjoinRoot.of f) (AdjoinRoot.root f) f = 0

full_name: AdjoinRoot.isRoot_root
code: theorem isRoot_root (f : R[X]) : IsRoot (f.map (of f)) (root f) 
goal: (Polynomial.map (AdjoinRoot.of f) f).IsRoot (AdjoinRoot.root f)

full_name: AdjoinRoot.isAlgebraic_root
code: theorem isAlgebraic_root (hf : f ≠ 0) : IsAlgebraic R (root f) 
goal: IsAlgebraic R (AdjoinRoot.root f)

full_name: AdjoinRoot.of.injective_of_degree_ne_zero
code: theorem of.injective_of_degree_ne_zero [IsDomain R] (hf : f.degree ≠ 0) :
    Function.Injective (AdjoinRoot.of f) 
goal: Function.Injective ⇑(AdjoinRoot.of f)

full_name: AdjoinRoot.lift
code: /-- Lift a ring homomorphism `i : R →+* S` to `AdjoinRoot f →+* S`. -/
def lift (i : R →+* S) (x : S) (h : f.eval₂ i x = 0) : AdjoinRoot f →+* S 
goal: AdjoinRoot f →+* S

full_name: AdjoinRoot.lift_mk
code: @[simp]
theorem lift_mk (g : R[X]) : lift i a h (mk f g) = g.eval₂ i a 
goal: (AdjoinRoot.lift i a h) ((AdjoinRoot.mk f) g) = Polynomial.eval₂ i a g

full_name: AdjoinRoot.lift_root
code: @[simp]
theorem lift_root : lift i a h (root f) = a 
goal: (AdjoinRoot.lift i a h) (AdjoinRoot.root f) = a

full_name: AdjoinRoot.lift_of
code: @[simp]
theorem lift_of {x : R} : lift i a h x = i x 
goal: (AdjoinRoot.lift i a h) ((AdjoinRoot.of f) x) = i x

full_name: AdjoinRoot.lift_comp_of
code: @[simp]
theorem lift_comp_of : (lift i a h).comp (of f) = i 
goal: (AdjoinRoot.lift i a h).comp (AdjoinRoot.of f) = i

full_name: AdjoinRoot.liftHom
code: /-- Produce an algebra homomorphism `AdjoinRoot f →ₐ[R] S` sending `root f` to
a root of `f` in `S`. -/
def liftHom (x : S) (hfx : aeval x f = 0) : AdjoinRoot f →ₐ[R] S 
goal: AdjoinRoot f →ₐ[R] S

full_name: AdjoinRoot.coe_liftHom
code: @[simp]
theorem coe_liftHom (x : S) (hfx : aeval x f = 0) :
    (liftHom f x hfx : AdjoinRoot f →+* S) = lift (algebraMap R S) x hfx 
goal: ↑(AdjoinRoot.liftHom f x hfx) = AdjoinRoot.lift (algebraMap R S) x hfx

full_name: AdjoinRoot.aeval_algHom_eq_zero
code: @[simp]
theorem aeval_algHom_eq_zero (ϕ : AdjoinRoot f →ₐ[R] S) : aeval (ϕ (root f)) f = 0 
goal: (Polynomial.aeval (ϕ (AdjoinRoot.root f))) f = 0

full_name: AdjoinRoot.liftHom_eq_algHom
code: @[simp]
theorem liftHom_eq_algHom (f : R[X]) (ϕ : AdjoinRoot f →ₐ[R] S) :
    liftHom f (ϕ (root f)) (aeval_algHom_eq_zero f ϕ) = ϕ 
goal: AdjoinRoot.liftHom f (ϕ (AdjoinRoot.root f)) ⋯ = ϕ

full_name: AdjoinRoot.liftHom_mk
code: @[simp]
theorem liftHom_mk {g : R[X]} : liftHom f a hfx (mk f g) = aeval a g 
goal: (AdjoinRoot.liftHom f a hfx) ((AdjoinRoot.mk f) g) = (Polynomial.aeval a) g

full_name: AdjoinRoot.liftHom_root
code: @[simp]
theorem liftHom_root : liftHom f a hfx (root f) = a 
goal: (AdjoinRoot.liftHom f a hfx) (AdjoinRoot.root f) = a

full_name: AdjoinRoot.liftHom_of
code: @[simp]
theorem liftHom_of {x : R} : liftHom f a hfx (of f x) = algebraMap _ _ x 
goal: (AdjoinRoot.liftHom f a hfx) ((AdjoinRoot.of f) x) = (algebraMap R S) x

full_name: AdjoinRoot.root_isInv
code: @[simp]
theorem root_isInv (r : R) : of _ r * root (C r * X - 1) = 1 
goal: (AdjoinRoot.of (Polynomial.C r * Polynomial.X - 1)) r * AdjoinRoot.root (Polynomial.C r * Polynomial.X - 1) = 1

full_name: AdjoinRoot.algHom_subsingleton
code: theorem algHom_subsingleton {S : Type*} [CommRing S] [Algebra R S] {r : R} :
    Subsingleton (AdjoinRoot (C r * X - 1) →ₐ[R] S) 
goal: Subsingleton (AdjoinRoot (Polynomial.C r * Polynomial.X - 1) →ₐ[R] S)

full_name: AdjoinRoot.isDomain_of_prime
code: theorem isDomain_of_prime (hf : Prime f) : IsDomain (AdjoinRoot f) 
goal: IsDomain (AdjoinRoot f)

full_name: AdjoinRoot.noZeroSMulDivisors_of_prime_of_degree_ne_zero
code: theorem noZeroSMulDivisors_of_prime_of_degree_ne_zero [IsDomain R] (hf : Prime f)
    (hf' : f.degree ≠ 0) : NoZeroSMulDivisors R (AdjoinRoot f) 
goal: NoZeroSMulDivisors R (AdjoinRoot f)

full_name: AdjoinRoot.span_maximal_of_irreducible
code: instance span_maximal_of_irreducible [Fact (Irreducible f)] : (span {f}).IsMaximal 
goal: (Ideal.span {f}).IsMaximal

full_name: AdjoinRoot.instGroupWithZero
code: noncomputable instance instGroupWithZero [Fact (Irreducible f)] : GroupWithZero (AdjoinRoot f) 
goal: GroupWithZero (AdjoinRoot f)

full_name: AdjoinRoot.instField
code: noncomputable instance instField [Fact (Irreducible f)] : Field (AdjoinRoot f) 
goal: Field (AdjoinRoot f)

full_name: AdjoinRoot.coe_injective
code: theorem coe_injective (h : degree f ≠ 0) : Function.Injective ((↑) : K → AdjoinRoot f) 
goal: Function.Injective ⇑(AdjoinRoot.of f)

full_name: AdjoinRoot.coe_injective'
code: theorem coe_injective' [Fact (Irreducible f)] : Function.Injective ((↑) : K → AdjoinRoot f) 
goal: Function.Injective ⇑(AdjoinRoot.of f)

full_name: AdjoinRoot.mul_div_root_cancel
code: theorem mul_div_root_cancel [Fact (Irreducible f)] :
    (X - C (root f)) * ((f.map (of f)) / (X - C (root f))) = f.map (of f) 
goal: (Polynomial.X - Polynomial.C (AdjoinRoot.root f)) *
    (Polynomial.map (AdjoinRoot.of f) f / (Polynomial.X - Polynomial.C (AdjoinRoot.root f))) =
  Polynomial.map (AdjoinRoot.of f) f

full_name: AdjoinRoot.instIsNoetherianRing
code: instance [CommRing R] [IsNoetherianRing R] {f : R[X]} : IsNoetherianRing (AdjoinRoot f) 
goal: IsNoetherianRing (AdjoinRoot f)

full_name: AdjoinRoot.isIntegral_root'
code: theorem isIntegral_root' (hg : g.Monic) : IsIntegral R (root g) 
goal: IsIntegral R (AdjoinRoot.root g)

full_name: AdjoinRoot.modByMonicHom
code: /-- `AdjoinRoot.modByMonicHom` sends the equivalence class of `f` mod `g` to `f %ₘ g`.

This is a well-defined right inverse to `AdjoinRoot.mk`, see `AdjoinRoot.mk_leftInverse`. -/
def modByMonicHom (hg : g.Monic) : AdjoinRoot g →ₗ[R] R[X] 
goal: AdjoinRoot g →ₗ[R] R[X]

full_name: AdjoinRoot.modByMonicHom_mk
code: @[simp]
theorem modByMonicHom_mk (hg : g.Monic) (f : R[X]) : modByMonicHom hg (mk g f) = f %ₘ g 
goal: (AdjoinRoot.modByMonicHom hg) ((AdjoinRoot.mk g) f) = f %ₘ g

full_name: AdjoinRoot.mk_leftInverse
code: theorem mk_leftInverse (hg : g.Monic) : Function.LeftInverse (mk g) (modByMonicHom hg) 
goal: Function.LeftInverse ⇑(AdjoinRoot.mk g) ⇑(AdjoinRoot.modByMonicHom hg)

full_name: AdjoinRoot.mk_surjective
code: theorem mk_surjective : Function.Surjective (mk g) 
goal: Function.Surjective ⇑(AdjoinRoot.mk g)

full_name: AdjoinRoot.powerBasisAux'
code: /-- The elements `1, root g, ..., root g ^ (d - 1)` form a basis for `AdjoinRoot g`,
where `g` is a monic polynomial of degree `d`. -/
def powerBasisAux' (hg : g.Monic) : Basis (Fin g.natDegree) R (AdjoinRoot g) 
goal: Basis (Fin g.natDegree) R (AdjoinRoot g)

full_name: AdjoinRoot.powerBasisAux'_repr_symm_apply
code: theorem powerBasisAux'_repr_symm_apply (hg : g.Monic) (c : Fin g.natDegree →₀ R) :
    (powerBasisAux' hg).repr.symm c = mk g (∑ i : Fin _, monomial i (c i)) 
goal: (AdjoinRoot.powerBasisAux' hg).repr.symm c = (AdjoinRoot.mk g) (∑ i : Fin g.natDegree, (Polynomial.monomial ↑i) (c i))

full_name: AdjoinRoot.powerBasisAux'_repr_apply_to_fun
code: @[simp]
theorem powerBasisAux'_repr_apply_to_fun (hg : g.Monic) (f : AdjoinRoot g) (i : Fin g.natDegree) :
    (powerBasisAux' hg).repr f i = (modByMonicHom hg f).coeff ↑i 
goal: ((AdjoinRoot.powerBasisAux' hg).repr f) i = ((AdjoinRoot.modByMonicHom hg) f).coeff ↑i

full_name: AdjoinRoot.powerBasis'_dim
code: /-- The power basis `1, root g, ..., root g ^ (d - 1)` for `AdjoinRoot g`,
where `g` is a monic polynomial of degree `d`. -/
@[simps]
def powerBasis' (hg : g.Monic) : PowerBasis R (AdjoinRoot g) 
goal: (AdjoinRoot.powerBasis' hg).dim = g.natDegree

full_name: AdjoinRoot.powerBasis'
code: /-- The power basis `1, root g, ..., root g ^ (d - 1)` for `AdjoinRoot g`,
where `g` is a monic polynomial of degree `d`. -/
@[simps]
def powerBasis' (hg : g.Monic) : PowerBasis R (AdjoinRoot g) 
goal: PowerBasis R (AdjoinRoot g)

full_name: AdjoinRoot.powerBasis'_gen
code: /-- The power basis `1, root g, ..., root g ^ (d - 1)` for `AdjoinRoot g`,
where `g` is a monic polynomial of degree `d`. -/
@[simps]
def powerBasis' (hg : g.Monic) : PowerBasis R (AdjoinRoot g) 
goal: (AdjoinRoot.powerBasis' hg).gen = AdjoinRoot.root g

full_name: AdjoinRoot.isIntegral_root
code: theorem isIntegral_root (hf : f ≠ 0) : IsIntegral K (root f) 
goal: IsIntegral K (AdjoinRoot.root f)

full_name: AdjoinRoot.minpoly_root
code: theorem minpoly_root (hf : f ≠ 0) : minpoly K (root f) = f * C f.leadingCoeff⁻¹ 
goal: minpoly K (AdjoinRoot.root f) = f * Polynomial.C f.leadingCoeff⁻¹

full_name: AdjoinRoot.powerBasisAux
code: /-- The elements `1, root f, ..., root f ^ (d - 1)` form a basis for `AdjoinRoot f`,
where `f` is an irreducible polynomial over a field of degree `d`. -/
def powerBasisAux (hf : f ≠ 0) : Basis (Fin f.natDegree) K (AdjoinRoot f) 
goal: Basis (Fin f.natDegree) K (AdjoinRoot f)

full_name: AdjoinRoot.powerBasis
code: /-- The power basis `1, root f, ..., root f ^ (d - 1)` for `AdjoinRoot f`,
where `f` is an irreducible polynomial over a field of degree `d`. -/
@[simps!]  -- Porting note: was `[simps]`
def powerBasis (hf : f ≠ 0) : PowerBasis K (AdjoinRoot f) 
goal: PowerBasis K (AdjoinRoot f)

full_name: AdjoinRoot.powerBasis_dim
code: /-- The power basis `1, root f, ..., root f ^ (d - 1)` for `AdjoinRoot f`,
where `f` is an irreducible polynomial over a field of degree `d`. -/
@[simps!]  -- Porting note: was `[simps]`
def powerBasis (hf : f ≠ 0) : PowerBasis K (AdjoinRoot f) 
goal: (AdjoinRoot.powerBasis hf).dim = f.natDegree

full_name: AdjoinRoot.powerBasis_gen
code: /-- The power basis `1, root f, ..., root f ^ (d - 1)` for `AdjoinRoot f`,
where `f` is an irreducible polynomial over a field of degree `d`. -/
@[simps!]  -- Porting note: was `[simps]`
def powerBasis (hf : f ≠ 0) : PowerBasis K (AdjoinRoot f) 
goal: (AdjoinRoot.powerBasis hf).gen = AdjoinRoot.root f

full_name: AdjoinRoot.minpoly_powerBasis_gen
code: theorem minpoly_powerBasis_gen (hf : f ≠ 0) :
    minpoly K (powerBasis hf).gen = f * C f.leadingCoeff⁻¹ 
goal: minpoly K (AdjoinRoot.powerBasis hf).gen = f * Polynomial.C f.leadingCoeff⁻¹

full_name: AdjoinRoot.minpoly_powerBasis_gen_of_monic
code: theorem minpoly_powerBasis_gen_of_monic (hf : f.Monic) (hf' : f ≠ 0 := hf.ne_zero) :
    minpoly K (powerBasis hf').gen = f 
goal: minpoly K (AdjoinRoot.powerBasis hf').gen = f

full_name: AdjoinRoot.Minpoly.toAdjoin
code: /-- The surjective algebra morphism `R[X]/(minpoly R x) → R[x]`.
If `R` is a integrally closed domain and `x` is integral, this is an isomorphism,
see `minpoly.equivAdjoin`. -/
@[simps!]
def Minpoly.toAdjoin : AdjoinRoot (minpoly R x) →ₐ[R] adjoin R ({x} : Set S) 
goal: AdjoinRoot (minpoly R x) →ₐ[R] ↥(Algebra.adjoin R {x})

full_name: AdjoinRoot.Minpoly.toAdjoin_apply
code: /-- The surjective algebra morphism `R[X]/(minpoly R x) → R[x]`.
If `R` is a integrally closed domain and `x` is integral, this is an isomorphism,
see `minpoly.equivAdjoin`. -/
@[simps!]
def Minpoly.toAdjoin : AdjoinRoot (minpoly R x) →ₐ[R] adjoin R ({x} : Set S) 
goal: ∀ (a : R[X] ⧸ Submodule.toAddSubgroup (Ideal.span {minpoly R x})),
  (AdjoinRoot.Minpoly.toAdjoin R x) a =
    (QuotientAddGroup.lift (Submodule.toAddSubgroup (Ideal.span {minpoly R x}))
        ↑(Polynomial.eval₂RingHom (algebraMap R ↥(Algebra.adjoin R {x})) ⟨x, ⋯⟩) ⋯)
      a

full_name: AdjoinRoot.Minpoly.toAdjoin_apply'
code: theorem Minpoly.toAdjoin_apply' (a : AdjoinRoot (minpoly R x)) :
    Minpoly.toAdjoin R x a =
      liftHom (minpoly R x) (⟨x, self_mem_adjoin_singleton R x⟩ : adjoin R ({x} : Set S))
        (by simp [← Subalgebra.coe_eq_zero, aeval_subalgebra_coe]) a 
goal: (AdjoinRoot.Minpoly.toAdjoin R x) a = (AdjoinRoot.liftHom (minpoly R x) ⟨x, ⋯⟩ ⋯) a

full_name: AdjoinRoot.Minpoly.toAdjoin.apply_X
code: theorem Minpoly.toAdjoin.apply_X :
    Minpoly.toAdjoin R x (mk (minpoly R x) X) = ⟨x, self_mem_adjoin_singleton R x⟩ 
goal: (AdjoinRoot.Minpoly.toAdjoin R x) ((AdjoinRoot.mk (minpoly R x)) Polynomial.X) = ⟨x, ⋯⟩

full_name: AdjoinRoot.Minpoly.toAdjoin.surjective
code: theorem Minpoly.toAdjoin.surjective : Function.Surjective (Minpoly.toAdjoin R x) 
goal: Function.Surjective ⇑(AdjoinRoot.Minpoly.toAdjoin R x)

full_name: AdjoinRoot.equiv'_symm_apply
code: /-- If `S` is an extension of `R` with power basis `pb` and `g` is a monic polynomial over `R`
such that `pb.gen` has a minimal polynomial `g`, then `S` is isomorphic to `AdjoinRoot g`.

Compare `PowerBasis.equivOfRoot`, which would require
`h₂ : aeval pb.gen (minpoly R (root g)) = 0`; that minimal polynomial is not
guaranteed to be identical to `g`. -/
@[simps (config := .asFn)]
def equiv' (h₁ : aeval (root g) (minpoly R pb.gen) = 0) (h₂ : aeval pb.gen g = 0) :
    AdjoinRoot g ≃ₐ[R] S 
goal: ⇑(AdjoinRoot.equiv' g pb h₁ h₂).symm = ⇑(pb.lift (AdjoinRoot.root g) h₁)

full_name: AdjoinRoot.equiv'_apply
code: /-- If `S` is an extension of `R` with power basis `pb` and `g` is a monic polynomial over `R`
such that `pb.gen` has a minimal polynomial `g`, then `S` is isomorphic to `AdjoinRoot g`.

Compare `PowerBasis.equivOfRoot`, which would require
`h₂ : aeval pb.gen (minpoly R (root g)) = 0`; that minimal polynomial is not
guaranteed to be identical to `g`. -/
@[simps (config := .asFn)]
def equiv' (h₁ : aeval (root g) (minpoly R pb.gen) = 0) (h₂ : aeval pb.gen g = 0) :
    AdjoinRoot g ≃ₐ[R] S 
goal: ⇑(AdjoinRoot.equiv' g pb h₁ h₂) = ⇑(AdjoinRoot.liftHom g pb.gen h₂)

full_name: AdjoinRoot.equiv'
code: /-- If `S` is an extension of `R` with power basis `pb` and `g` is a monic polynomial over `R`
such that `pb.gen` has a minimal polynomial `g`, then `S` is isomorphic to `AdjoinRoot g`.

Compare `PowerBasis.equivOfRoot`, which would require
`h₂ : aeval pb.gen (minpoly R (root g)) = 0`; that minimal polynomial is not
guaranteed to be identical to `g`. -/
@[simps (config := .asFn)]
def equiv' (h₁ : aeval (root g) (minpoly R pb.gen) = 0) (h₂ : aeval pb.gen g = 0) :
    AdjoinRoot g ≃ₐ[R] S 
goal: AdjoinRoot g ≃ₐ[R] S

full_name: AdjoinRoot.equiv'_toAlgHom
code: theorem equiv'_toAlgHom (h₁ : aeval (root g) (minpoly R pb.gen) = 0) (h₂ : aeval pb.gen g = 0) :
    (equiv' g pb h₁ h₂).toAlgHom = AdjoinRoot.liftHom g pb.gen h₂ 
goal: ↑(AdjoinRoot.equiv' g pb h₁ h₂) = AdjoinRoot.liftHom g pb.gen h₂

full_name: AdjoinRoot.equiv'_symm_toAlgHom
code: theorem equiv'_symm_toAlgHom (h₁ : aeval (root g) (minpoly R pb.gen) = 0)
    (h₂ : aeval pb.gen g = 0) : (equiv' g pb h₁ h₂).symm.toAlgHom = pb.lift (root g) h₁ 
goal: ↑(AdjoinRoot.equiv' g pb h₁ h₂).symm = pb.lift (AdjoinRoot.root g) h₁

full_name: AdjoinRoot.equiv
code: /-- If `L` is a field extension of `F` and `f` is a polynomial over `F` then the set
of maps from `F[x]/(f)` into `L` is in bijection with the set of roots of `f` in `L`. -/
def equiv (f : F[X]) (hf : f ≠ 0) :
    (AdjoinRoot f →ₐ[F] L) ≃ { x // x ∈ f.aroots L } 
goal: (AdjoinRoot f →ₐ[F] L) ≃ { x // x ∈ f.aroots L }

full_name: AdjoinRoot.quotMapOfEquivQuotMapCMapSpanMk
code: /-- The natural isomorphism `R[α]/(I[α]) ≅ R[α]/((I[x] ⊔ (f)) / (f))` for `α` a root of
`f : R[X]` and `I : Ideal R`.

See `adjoin_root.quot_map_of_equiv` for the isomorphism with `(R/I)[X] / (f mod I)`. -/
def quotMapOfEquivQuotMapCMapSpanMk :
    AdjoinRoot f ⧸ I.map (of f) ≃+*
      AdjoinRoot f ⧸ (I.map (C : R →+* R[X])).map (Ideal.Quotient.mk (span {f})) 
goal: AdjoinRoot f ⧸ Ideal.map (AdjoinRoot.of f) I ≃+*
  AdjoinRoot f ⧸ Ideal.map (Ideal.Quotient.mk (Ideal.span {f})) (Ideal.map Polynomial.C I)

full_name: AdjoinRoot.quotMapOfEquivQuotMapCMapSpanMk_mk
code: @[simp]
theorem quotMapOfEquivQuotMapCMapSpanMk_mk (x : AdjoinRoot f) :
    quotMapOfEquivQuotMapCMapSpanMk I f (Ideal.Quotient.mk (I.map (of f)) x) =
      Ideal.Quotient.mk (Ideal.map (Ideal.Quotient.mk (span {f})) (I.map (C : R →+* R[X]))) x 
goal: (AdjoinRoot.quotMapOfEquivQuotMapCMapSpanMk I f) ((Ideal.Quotient.mk (Ideal.map (AdjoinRoot.of f) I)) x) =
  (Ideal.Quotient.mk (Ideal.map (Ideal.Quotient.mk (Ideal.span {f})) (Ideal.map Polynomial.C I))) x

full_name: AdjoinRoot.quotMapOfEquivQuotMapCMapSpanMk_symm_mk
code: theorem quotMapOfEquivQuotMapCMapSpanMk_symm_mk (x : AdjoinRoot f) :
    (quotMapOfEquivQuotMapCMapSpanMk I f).symm
        (Ideal.Quotient.mk ((I.map (C : R →+* R[X])).map (Ideal.Quotient.mk (span {f}))) x) =
      Ideal.Quotient.mk (I.map (of f)) x 
goal: (AdjoinRoot.quotMapOfEquivQuotMapCMapSpanMk I f).symm
    ((Ideal.Quotient.mk (Ideal.map (Ideal.Quotient.mk (Ideal.span {f})) (Ideal.map Polynomial.C I))) x) =
  (Ideal.Quotient.mk (Ideal.map (AdjoinRoot.of f) I)) x

full_name: AdjoinRoot.quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk
code: /-- The natural isomorphism `R[α]/((I[x] ⊔ (f)) / (f)) ≅ (R[x]/I[x])/((f) ⊔ I[x] / I[x])`
  for `α` a root of `f : R[X]` and `I : Ideal R`-/
def quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk :
    AdjoinRoot f ⧸ (I.map (C : R →+* R[X])).map (Ideal.Quotient.mk (span ({f} : Set R[X]))) ≃+*
      (R[X] ⧸ I.map (C : R →+* R[X])) ⧸
        (span ({f} : Set R[X])).map (Ideal.Quotient.mk (I.map (C : R →+* R[X]))) 
goal: AdjoinRoot f ⧸ Ideal.map (Ideal.Quotient.mk (Ideal.span {f})) (Ideal.map Polynomial.C I) ≃+*
  (R[X] ⧸ Ideal.map Polynomial.C I) ⧸ Ideal.map (Ideal.Quotient.mk (Ideal.map Polynomial.C I)) (Ideal.span {f})

full_name: AdjoinRoot.quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk_mk
code: theorem quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk_mk (p : R[X]) :
    quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk I f (Ideal.Quotient.mk _ (mk f p)) =
      quotQuotMk (I.map C) (span {f}) p 
goal: (AdjoinRoot.quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk I f)
    ((Ideal.Quotient.mk (Ideal.map (Ideal.Quotient.mk (Ideal.span {f})) (Ideal.map Polynomial.C I)))
      ((AdjoinRoot.mk f) p)) =
  (DoubleQuot.quotQuotMk (Ideal.map Polynomial.C I) (Ideal.span {f})) p

full_name: AdjoinRoot.quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk_symm_quotQuotMk
code: @[simp]
theorem quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk_symm_quotQuotMk (p : R[X]) :
    (quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk I f).symm (quotQuotMk (I.map C) (span {f}) p) =
      Ideal.Quotient.mk (Ideal.map (Ideal.Quotient.mk (span {f})) (I.map (C : R →+* R[X])))
        (mk f p) 
goal: (AdjoinRoot.quotMapCMapSpanMkEquivQuotMapCQuotMapSpanMk I f).symm
    ((DoubleQuot.quotQuotMk (Ideal.map Polynomial.C I) (Ideal.span {f})) p) =
  (Ideal.Quotient.mk (Ideal.map (Ideal.Quotient.mk (Ideal.span {f})) (Ideal.map Polynomial.C I))) ((AdjoinRoot.mk f) p)

full_name: AdjoinRoot.Polynomial.quotQuotEquivComm
code: /-- The natural isomorphism `(R/I)[x]/(f mod I) ≅ (R[x]/I*R[x])/(f mod I[x])` where
  `f : R[X]` and `I : Ideal R`-/
def Polynomial.quotQuotEquivComm :
    (R ⧸ I)[X] ⧸ span ({f.map (Ideal.Quotient.mk I)} : Set (Polynomial (R ⧸ I))) ≃+*
      (R[X] ⧸ (I.map C)) ⧸ span ({(Ideal.Quotient.mk (I.map C)) f} : Set (R[X] ⧸ (I.map C))) 
goal: (R ⧸ I)[X] ⧸ Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f} ≃+*
  (R[X] ⧸ Ideal.map Polynomial.C I) ⧸ Ideal.span {(Ideal.Quotient.mk (Ideal.map Polynomial.C I)) f}

full_name: AdjoinRoot.Polynomial.quotQuotEquivComm_mk
code: @[simp]
theorem Polynomial.quotQuotEquivComm_mk (p : R[X]) :
    (Polynomial.quotQuotEquivComm I f) (Ideal.Quotient.mk _ (p.map (Ideal.Quotient.mk I))) =
      Ideal.Quotient.mk (span ({(Ideal.Quotient.mk (I.map C)) f} : Set (R[X] ⧸ (I.map C))))
      (Ideal.Quotient.mk (I.map C) p) 
goal: (AdjoinRoot.Polynomial.quotQuotEquivComm I f)
    ((Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f}))
      (Polynomial.map (Ideal.Quotient.mk I) p)) =
  (Ideal.Quotient.mk (Ideal.span {(Ideal.Quotient.mk (Ideal.map Polynomial.C I)) f}))
    ((Ideal.Quotient.mk (Ideal.map Polynomial.C I)) p)

full_name: AdjoinRoot.Polynomial.quotQuotEquivComm_symm_mk_mk
code: @[simp]
theorem Polynomial.quotQuotEquivComm_symm_mk_mk (p : R[X]) :
    (Polynomial.quotQuotEquivComm I f).symm (Ideal.Quotient.mk (span
    ({(Ideal.Quotient.mk (I.map C)) f} : Set (R[X] ⧸ (I.map C)))) (Ideal.Quotient.mk (I.map C) p)) =
      Ideal.Quotient.mk (span {f.map (Ideal.Quotient.mk I)}) (p.map (Ideal.Quotient.mk I)) 
goal: (AdjoinRoot.Polynomial.quotQuotEquivComm I f).symm
    ((Ideal.Quotient.mk (Ideal.span {(Ideal.Quotient.mk (Ideal.map Polynomial.C I)) f}))
      ((Ideal.Quotient.mk (Ideal.map Polynomial.C I)) p)) =
  (Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f})) (Polynomial.map (Ideal.Quotient.mk I) p)

full_name: AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot
code: /-- The natural isomorphism `R[α]/I[α] ≅ (R/I)[X]/(f mod I)` for `α` a root of `f : R[X]`
  and `I : Ideal R`. -/
def quotAdjoinRootEquivQuotPolynomialQuot :
    AdjoinRoot f ⧸ I.map (of f) ≃+*
    (R ⧸ I)[X] ⧸ span ({f.map (Ideal.Quotient.mk I)} : Set (R ⧸ I)[X]) 
goal: AdjoinRoot f ⧸ Ideal.map (AdjoinRoot.of f) I ≃+* (R ⧸ I)[X] ⧸ Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f}

full_name: AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot_mk_of
code: @[simp]
theorem quotAdjoinRootEquivQuotPolynomialQuot_mk_of (p : R[X]) :
    quotAdjoinRootEquivQuotPolynomialQuot I f (Ideal.Quotient.mk (I.map (of f)) (mk f p)) =
      Ideal.Quotient.mk (span ({f.map (Ideal.Quotient.mk I)} : Set (R ⧸ I)[X]))
      (p.map (Ideal.Quotient.mk I)) 
goal: (AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot I f)
    ((Ideal.Quotient.mk (Ideal.map (AdjoinRoot.of f) I)) ((AdjoinRoot.mk f) p)) =
  (Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f})) (Polynomial.map (Ideal.Quotient.mk I) p)

full_name: AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot_symm_mk_mk
code: @[simp]
theorem quotAdjoinRootEquivQuotPolynomialQuot_symm_mk_mk (p : R[X]) :
    (quotAdjoinRootEquivQuotPolynomialQuot I f).symm
        (Ideal.Quotient.mk (span ({f.map (Ideal.Quotient.mk I)} : Set (R ⧸ I)[X]))
        (p.map (Ideal.Quotient.mk I))) =
      Ideal.Quotient.mk (I.map (of f)) (mk f p) 
goal: (AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot I f).symm
    ((Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f}))
      (Polynomial.map (Ideal.Quotient.mk I) p)) =
  (Ideal.Quotient.mk (Ideal.map (AdjoinRoot.of f) I)) ((AdjoinRoot.mk f) p)

full_name: AdjoinRoot.quotEquivQuotMap_apply
code: /-- Promote `AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot` to an alg_equiv.  -/
@[simps!]
noncomputable def quotEquivQuotMap (f : R[X]) (I : Ideal R) :
    (AdjoinRoot f ⧸ Ideal.map (of f) I) ≃ₐ[R]
      (R ⧸ I)[X] ⧸ Ideal.span ({Polynomial.map (Ideal.Quotient.mk I) f} : Set (R ⧸ I)[X]) 
goal: (AdjoinRoot.quotEquivQuotMap f I) a = (AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot I f) a

full_name: AdjoinRoot.quotEquivQuotMap_symm_apply
code: /-- Promote `AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot` to an alg_equiv.  -/
@[simps!]
noncomputable def quotEquivQuotMap (f : R[X]) (I : Ideal R) :
    (AdjoinRoot f ⧸ Ideal.map (of f) I) ≃ₐ[R]
      (R ⧸ I)[X] ⧸ Ideal.span ({Polynomial.map (Ideal.Quotient.mk I) f} : Set (R ⧸ I)[X]) 
goal: (AdjoinRoot.quotEquivQuotMap f I).symm a = (AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot I f).symm a

full_name: AdjoinRoot.quotEquivQuotMap
code: /-- Promote `AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot` to an alg_equiv.  -/
@[simps!]
noncomputable def quotEquivQuotMap (f : R[X]) (I : Ideal R) :
    (AdjoinRoot f ⧸ Ideal.map (of f) I) ≃ₐ[R]
      (R ⧸ I)[X] ⧸ Ideal.span ({Polynomial.map (Ideal.Quotient.mk I) f} : Set (R ⧸ I)[X]) 
goal: (AdjoinRoot f ⧸ Ideal.map (AdjoinRoot.of f) I) ≃ₐ[R] (R ⧸ I)[X] ⧸ Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f}

full_name: AdjoinRoot.quotEquivQuotMap_apply_mk
code: @[simp]
theorem quotEquivQuotMap_apply_mk (f g : R[X]) (I : Ideal R) :
    AdjoinRoot.quotEquivQuotMap f I (Ideal.Quotient.mk (Ideal.map (of f) I) (AdjoinRoot.mk f g)) =
      Ideal.Quotient.mk (Ideal.span ({Polynomial.map (Ideal.Quotient.mk I) f} : Set (R ⧸ I)[X]))
      (g.map (Ideal.Quotient.mk I)) 
goal: (AdjoinRoot.quotEquivQuotMap f I) ((Ideal.Quotient.mk (Ideal.map (AdjoinRoot.of f) I)) ((AdjoinRoot.mk f) g)) =
  (Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f})) (Polynomial.map (Ideal.Quotient.mk I) g)

full_name: AdjoinRoot.quotEquivQuotMap_symm_apply_mk
code: theorem quotEquivQuotMap_symm_apply_mk (f g : R[X]) (I : Ideal R) :
    (AdjoinRoot.quotEquivQuotMap f I).symm (Ideal.Quotient.mk _
      (Polynomial.map (Ideal.Quotient.mk I) g)) =
        Ideal.Quotient.mk (Ideal.map (of f) I) (AdjoinRoot.mk f g) 
goal: (AdjoinRoot.quotEquivQuotMap f I).symm
    ((Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) f}))
      (Polynomial.map (Ideal.Quotient.mk I) g)) =
  (Ideal.Quotient.mk (Ideal.map (AdjoinRoot.of f) I)) ((AdjoinRoot.mk f) g)

full_name: PowerBasis.quotientEquivQuotientMinpolyMap_symm_apply
code: /-- Let `α` have minimal polynomial `f` over `R` and `I` be an ideal of `R`,
then `R[α] / (I) = (R[x] / (f)) / pS = (R/p)[x] / (f mod p)`. -/
@[simps!]
noncomputable def quotientEquivQuotientMinpolyMap (pb : PowerBasis R S) (I : Ideal R) :
    (S ⧸ I.map (algebraMap R S)) ≃ₐ[R]
      Polynomial (R ⧸ I) ⧸
        Ideal.span ({(minpoly R pb.gen).map (Ideal.Quotient.mk I)} : Set (Polynomial (R ⧸ I))) 
goal: ∀ (a : (R ⧸ I)[X] ⧸ Ideal.span {Polynomial.map (Ideal.Quotient.mk I) (minpoly R pb.gen)}),
  (pb.quotientEquivQuotientMinpolyMap I).symm a =
    (↑↑(AlgEquiv.ofRingEquiv ⋯)).symm ((↑↑(AdjoinRoot.quotEquivQuotMap (minpoly R pb.gen) I)).symm a)

full_name: PowerBasis.quotientEquivQuotientMinpolyMap
code: /-- Let `α` have minimal polynomial `f` over `R` and `I` be an ideal of `R`,
then `R[α] / (I) = (R[x] / (f)) / pS = (R/p)[x] / (f mod p)`. -/
@[simps!]
noncomputable def quotientEquivQuotientMinpolyMap (pb : PowerBasis R S) (I : Ideal R) :
    (S ⧸ I.map (algebraMap R S)) ≃ₐ[R]
      Polynomial (R ⧸ I) ⧸
        Ideal.span ({(minpoly R pb.gen).map (Ideal.Quotient.mk I)} : Set (Polynomial (R ⧸ I))) 
goal: (S ⧸ Ideal.map (algebraMap R S) I) ≃ₐ[R]
  (R ⧸ I)[X] ⧸ Ideal.span {Polynomial.map (Ideal.Quotient.mk I) (minpoly R pb.gen)}

full_name: PowerBasis.quotientEquivQuotientMinpolyMap_apply
code: /-- Let `α` have minimal polynomial `f` over `R` and `I` be an ideal of `R`,
then `R[α] / (I) = (R[x] / (f)) / pS = (R/p)[x] / (f mod p)`. -/
@[simps!]
noncomputable def quotientEquivQuotientMinpolyMap (pb : PowerBasis R S) (I : Ideal R) :
    (S ⧸ I.map (algebraMap R S)) ≃ₐ[R]
      Polynomial (R ⧸ I) ⧸
        Ideal.span ({(minpoly R pb.gen).map (Ideal.Quotient.mk I)} : Set (Polynomial (R ⧸ I))) 
goal: ∀ (a : S ⧸ Ideal.map (algebraMap R S) I),
  (pb.quotientEquivQuotientMinpolyMap I) a =
    (AdjoinRoot.quotAdjoinRootEquivQuotPolynomialQuot I (minpoly R pb.gen))
      ((Ideal.quotientMap (Ideal.map (AdjoinRoot.of (minpoly R pb.gen)) I)
          ↑(↑(AdjoinRoot.equiv' (minpoly R pb.gen) pb ⋯ ⋯)).symm ⋯)
        a)

full_name: PowerBasis.quotientEquivQuotientMinpolyMap_apply_mk
code: theorem quotientEquivQuotientMinpolyMap_apply_mk (pb : PowerBasis R S) (I : Ideal R) (g : R[X]) :
    pb.quotientEquivQuotientMinpolyMap I (Ideal.Quotient.mk (I.map (algebraMap R S))
      (aeval pb.gen g)) = Ideal.Quotient.mk
        (Ideal.span ({(minpoly R pb.gen).map (Ideal.Quotient.mk I)} : Set (Polynomial (R ⧸ I))))
          (g.map (Ideal.Quotient.mk I)) 
goal: (pb.quotientEquivQuotientMinpolyMap I)
    ((Ideal.Quotient.mk (Ideal.map (algebraMap R S) I)) ((Polynomial.aeval pb.gen) g)) =
  (Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) (minpoly R pb.gen)}))
    (Polynomial.map (Ideal.Quotient.mk I) g)

full_name: PowerBasis.quotientEquivQuotientMinpolyMap_symm_apply_mk
code: theorem quotientEquivQuotientMinpolyMap_symm_apply_mk (pb : PowerBasis R S) (I : Ideal R)
    (g : R[X]) :
    (pb.quotientEquivQuotientMinpolyMap I).symm (Ideal.Quotient.mk (Ideal.span
      ({(minpoly R pb.gen).map (Ideal.Quotient.mk I)} : Set (Polynomial (R ⧸ I))))
        (g.map (Ideal.Quotient.mk I))) = Ideal.Quotient.mk (I.map (algebraMap R S))
          (aeval pb.gen g) 
goal: (pb.quotientEquivQuotientMinpolyMap I).symm
    ((Ideal.Quotient.mk (Ideal.span {Polynomial.map (Ideal.Quotient.mk I) (minpoly R pb.gen)}))
      (Polynomial.map (Ideal.Quotient.mk I) g)) =
  (Ideal.Quotient.mk (Ideal.map (algebraMap R S) I)) ((Polynomial.aeval pb.gen) g)

full_name: Irreducible.exists_dvd_monic_irreducible_of_isIntegral
code: /-- If `L / K` is an integral extension, `K` is a domain, `L` is a field, then any irreducible
polynomial over `L` divides some monic irreducible polynomial over `K`. -/
theorem Irreducible.exists_dvd_monic_irreducible_of_isIntegral {K L : Type*}
    [CommRing K] [IsDomain K] [Field L] [Algebra K L] [Algebra.IsIntegral K L] {f : L[X]}
    (hf : Irreducible f) : ∃ g : K[X], g.Monic ∧ Irreducible g ∧ f ∣ g.map (algebraMap K L) 
goal: ∃ g, g.Monic ∧ Irreducible g ∧ f ∣ Polynomial.map (algebraMap K L) g