l3lab/ntp-mathlib huggingface dataset:
/-- `repr` preserves addition, up to multiples of `f` -/
theorem repr_add_sub_repr_add_repr_mem_span (h : IsAdjoinRoot S f) (x y : S) :
    h.repr (x + y) - (h.repr x + h.repr y) ∈ Ideal.span ({f} : Set R[X]) := by
  

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRoot S f
x y : S
⊢ repr h (x + y) - (repr h x + repr h y) ∈ Ideal.span {f}

Next tactic:
rw [← h.ker_map, RingHom.mem_ker, map_sub, h.map_repr, map_add, h.map_repr, h.map_repr, sub_self]
/-- Extensionality of the `IsAdjoinRoot` structure itself. See `IsAdjoinRootMonic.ext_elem`
for extensionality of the ring elements. -/
theorem ext_map (h h' : IsAdjoinRoot S f) (eq : ∀ x, h.map x = h'.map x) : h = h' := by
  

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h h' : IsAdjoinRoot S f
eq : ∀ (x : R[X]), h.map x = h'.map x
⊢ h = h'

Next tactic:
cases h
/-- Extensionality of the `IsAdjoinRoot` structure itself. See `IsAdjoinRootMonic.ext_elem`
for extensionality of the ring elements. -/
theorem ext_map (h h' : IsAdjoinRoot S f) (eq : ∀ x, h.map x = h'.map x) : h = h' := by
  cases h; 

Proof state:
case mk
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h' : IsAdjoinRoot S f
map✝ : R[X] →+* S
map_surjective✝ : Function.Surjective ⇑map✝
ker_map✝ : RingHom.ker map✝ = Ideal.span {f}
algebraMap_eq✝ : algebraMap R S = RingHom.comp map✝ C
eq :
  ∀ (x : R[X]),
    { map := map✝, map_surjective := map_surjective✝, ker_map := ker_map✝, algebraMap_eq := algebraMap_eq✝ }.map x =
      h'.map x
⊢ { map := map✝, map_surjective := map_surjective✝, ker_map := ker_map✝, algebraMap_eq := algebraMap_eq✝ } = h'

Next tactic:
cases h'
/-- Extensionality of the `IsAdjoinRoot` structure itself. See `IsAdjoinRootMonic.ext_elem`
for extensionality of the ring elements. -/
theorem ext_map (h h' : IsAdjoinRoot S f) (eq : ∀ x, h.map x = h'.map x) : h = h' := by
  cases h; cases h'; 

Proof state:
case mk.mk
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
map✝¹ : R[X] →+* S
map_surjective✝¹ : Function.Surjective ⇑map✝¹
ker_map✝¹ : RingHom.ker map✝¹ = Ideal.span {f}
algebraMap_eq✝¹ : algebraMap R S = RingHom.comp map✝¹ C
map✝ : R[X] →+* S
map_surjective✝ : Function.Surjective ⇑map✝
ker_map✝ : RingHom.ker map✝ = Ideal.span {f}
algebraMap_eq✝ : algebraMap R S = RingHom.comp map✝ C
eq :
  ∀ (x : R[X]),
    { map := map✝¹, map_surjective := map_surjective✝¹, ker_map := ker_map✝¹, algebraMap_eq := algebraMap_eq✝¹ }.map x =
      { map := map✝, map_surjective := map_surjective✝, ker_map := ker_map✝, algebraMap_eq := algebraMap_eq✝ }.map x
⊢ { map := map✝¹, map_surjective := map_surjective✝¹, ker_map := ker_map✝¹, algebraMap_eq := algebraMap_eq✝¹ } =
    { map := map✝, map_surjective := map_surjective✝, ker_map := ker_map✝, algebraMap_eq := algebraMap_eq✝ }

Next tactic:
congr
/-- Extensionality of the `IsAdjoinRoot` structure itself. See `IsAdjoinRootMonic.ext_elem`
for extensionality of the ring elements. -/
theorem ext_map (h h' : IsAdjoinRoot S f) (eq : ∀ x, h.map x = h'.map x) : h = h' := by
  cases h; cases h'; congr
  

Proof state:
case mk.mk.e_map
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
map✝¹ : R[X] →+* S
map_surjective✝¹ : Function.Surjective ⇑map✝¹
ker_map✝¹ : RingHom.ker map✝¹ = Ideal.span {f}
algebraMap_eq✝¹ : algebraMap R S = RingHom.comp map✝¹ C
map✝ : R[X] →+* S
map_surjective✝ : Function.Surjective ⇑map✝
ker_map✝ : RingHom.ker map✝ = Ideal.span {f}
algebraMap_eq✝ : algebraMap R S = RingHom.comp map✝ C
eq :
  ∀ (x : R[X]),
    { map := map✝¹, map_surjective := map_surjective✝¹, ker_map := ker_map✝¹, algebraMap_eq := algebraMap_eq✝¹ }.map x =
      { map := map✝, map_surjective := map_surjective✝, ker_map := ker_map✝, algebraMap_eq := algebraMap_eq✝ }.map x
⊢ map✝¹ = map✝

Next tactic:
exact RingHom.ext eq
/-- Extensionality of the `IsAdjoinRoot` structure itself. See `IsAdjoinRootMonic.ext_elem`
for extensionality of the ring elements. -/
@[ext]
theorem ext (h h' : IsAdjoinRoot S f) (eq : h.root = h'.root) : h = h' :=
  h.ext_map h' fun x => by 

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h h' : IsAdjoinRoot S f
eq : root h = root h'
x : R[X]
⊢ h.map x = h'.map x

Next tactic:
rw [← h.aeval_eq, ← h'.aeval_eq, eq]
/-- Auxiliary lemma for `IsAdjoinRoot.lift` -/
theorem eval₂_repr_eq_eval₂_of_map_eq (h : IsAdjoinRoot S f) (z : S) (w : R[X])
    (hzw : h.map w = z) : (h.repr z).eval₂ i x = w.eval₂ i x := by
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z : S
w : R[X]
hzw : h.map w = z
⊢ eval₂ i x (repr h z) = eval₂ i x w

Next tactic:
rw [eq_comm, ← sub_eq_zero, ← h.map_repr z, ← map_sub, h.map_eq_zero_iff] at hzw
/-- Auxiliary lemma for `IsAdjoinRoot.lift` -/
theorem eval₂_repr_eq_eval₂_of_map_eq (h : IsAdjoinRoot S f) (z : S) (w : R[X])
    (hzw : h.map w = z) : (h.repr z).eval₂ i x = w.eval₂ i x := by
  rw [eq_comm, ← sub_eq_zero, ← h.map_repr z, ← map_sub, h.map_eq_zero_iff] at hzw
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z : S
w : R[X]
hzw : f ∣ repr h z - w
⊢ eval₂ i x (repr h z) = eval₂ i x w

Next tactic:
obtain ⟨y, hy⟩ := hzw
/-- Auxiliary lemma for `IsAdjoinRoot.lift` -/
theorem eval₂_repr_eq_eval₂_of_map_eq (h : IsAdjoinRoot S f) (z : S) (w : R[X])
    (hzw : h.map w = z) : (h.repr z).eval₂ i x = w.eval₂ i x := by
  rw [eq_comm, ← sub_eq_zero, ← h.map_repr z, ← map_sub, h.map_eq_zero_iff] at hzw
  obtain ⟨y, hy⟩ := hzw
  

Proof state:
case intro
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z : S
w y : R[X]
hy : repr h z - w = f * y
⊢ eval₂ i x (repr h z) = eval₂ i x w

Next tactic:
rw [← sub_eq_zero, ← eval₂_sub, hy, eval₂_mul, hx, zero_mul]
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
  map_add' z w := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z + h.repr w), eval₂_add]
    · rw [map_add, map_repr, map_repr]
  map_one' := by
    

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
⊢ (fun z => eval₂ i x (repr h z)) 1 = 1

Next tactic:
dsimp only
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
  map_add' z w := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z + h.repr w), eval₂_add]
    · rw [map_add, map_repr, map_repr]
  map_one' := by
    dsimp only -- Porting note: added
    

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
⊢ eval₂ i x (repr h 1) = 1

Next tactic:
rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_one _), eval₂_one]
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
  map_add' z w := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z + h.repr w), eval₂_add]
    · rw [map_add, map_repr, map_repr]
  map_one' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_one _), eval₂_one]
  map_mul' z w := by
    

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z w : S
⊢ OneHom.toFun { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) }
      (z * w) =
    OneHom.toFun { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) } z *
      OneHom.toFun { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) } w

Next tactic:
dsimp only
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
  map_add' z w := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z + h.repr w), eval₂_add]
    · rw [map_add, map_repr, map_repr]
  map_one' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_one _), eval₂_one]
  map_mul' z w := by
    dsimp only -- Porting note: added
    

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z w : S
⊢ eval₂ i x (repr h (z * w)) = eval₂ i x (repr h z) * eval₂ i x (repr h w)

Next tactic:
rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z * h.repr w), eval₂_mul]
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
  map_add' z w := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z + h.repr w), eval₂_add]
    · rw [map_add, map_repr, map_repr]
  map_one' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_one _), eval₂_one]
  map_mul' z w := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z * h.repr w), eval₂_mul]
    · 

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z w : S
⊢ h.map (repr h z * repr h w) = z * w

Next tactic:
rw [map_mul, map_repr, map_repr]
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
⊢ OneHom.toFun
      (↑{
          toOneHom :=
            { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) },
          map_mul' :=
            (_ :
              ∀ (z w : S),
                OneHom.toFun
                    { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) }
                    (z * w) =
                  OneHom.toFun
                      { toFun := fun z => eval₂ i x (repr h z),
                        map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) }
                      z *
                    OneHom.toFun
                      { toFun := fun z => eval₂ i x (repr h z),
                        map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) }
                      w) })
      0 =
    0

Next tactic:
dsimp only
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
⊢ eval₂ i x (repr h 0) = 0

Next tactic:
rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
  map_add' z w := by
    dsimp only -- Porting note: added
    

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z w : S
⊢ eval₂ i x (repr h (z + w)) = eval₂ i x (repr h z) + eval₂ i x (repr h w)

Next tactic:
rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z + h.repr w), eval₂_add]
/-- Lift a ring homomorphism `R →+* T` to `S →+* T` by specifying a root `x` of `f` in `T`,
where `S` is given by adjoining a root of `f` to `R`. -/
def lift (h : IsAdjoinRoot S f) : S →+* T where
  toFun z := (h.repr z).eval₂ i x
  map_zero' := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ (map_zero _), eval₂_zero]
  map_add' z w := by
    dsimp only -- Porting note: added
    rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ (h.repr z + h.repr w), eval₂_add]
    · 

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z w : S
⊢ h.map (repr h z + repr h w) = z + w

Next tactic:
rw [map_add, map_repr, map_repr]
@[simp]
theorem lift_map (h : IsAdjoinRoot S f) (z : R[X]) : h.lift i x hx (h.map z) = z.eval₂ i x := by
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z : R[X]
⊢ (lift i x hx h) (h.map z) = eval₂ i x z

Next tactic:
rw [lift, RingHom.coe_mk]
@[simp]
theorem lift_map (h : IsAdjoinRoot S f) (z : R[X]) : h.lift i x hx (h.map z) = z.eval₂ i x := by
  rw [lift, RingHom.coe_mk]
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z : R[X]
⊢ { toOneHom := { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) },
        map_mul' :=
          (_ :
            ∀ (z w : S),
              OneHom.toFun
                  { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) }
                  (z * w) =
                OneHom.toFun
                    { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) }
                    z *
                  OneHom.toFun
                    { toFun := fun z => eval₂ i x (repr h z), map_one' := (_ : (fun z => eval₂ i x (repr h z)) 1 = 1) }
                    w) }
      (h.map z) =
    eval₂ i x z

Next tactic:
dsimp
@[simp]
theorem lift_map (h : IsAdjoinRoot S f) (z : R[X]) : h.lift i x hx (h.map z) = z.eval₂ i x := by
  rw [lift, RingHom.coe_mk]
  dsimp -- Porting note: added
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
z : R[X]
⊢ eval₂ i x (repr h (h.map z)) = eval₂ i x z

Next tactic:
rw [h.eval₂_repr_eq_eval₂_of_map_eq hx _ _ rfl]
@[simp]
theorem lift_root (h : IsAdjoinRoot S f) : h.lift i x hx h.root = x := by
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
⊢ (lift i x hx h) (root h) = x

Next tactic:
rw [← h.map_X, lift_map, eval₂_X]
@[simp]
theorem lift_algebraMap (h : IsAdjoinRoot S f) (a : R) : h.lift i x hx (algebraMap R S a) = i a :=
  by 

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
a : R
⊢ (lift i x hx h) ((algebraMap R S) a) = i a

Next tactic:
rw [h.algebraMap_apply, lift_map, eval₂_C]
/-- Auxiliary lemma for `apply_eq_lift` -/
theorem apply_eq_lift (h : IsAdjoinRoot S f) (g : S →+* T) (hmap : ∀ a, g (algebraMap R S a) = i a)
    (hroot : g h.root = x) (a : S) : g a = h.lift i x hx a := by
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
g : S →+* T
hmap : ∀ (a : R), g ((algebraMap R S) a) = i a
hroot : g (root h) = x
a : S
⊢ g a = (lift i x hx h) a

Next tactic:
rw [← h.map_repr a, Polynomial.as_sum_range_C_mul_X_pow (h.repr a)]
/-- Auxiliary lemma for `apply_eq_lift` -/
theorem apply_eq_lift (h : IsAdjoinRoot S f) (g : S →+* T) (hmap : ∀ a, g (algebraMap R S a) = i a)
    (hroot : g h.root = x) (a : S) : g a = h.lift i x hx a := by
  rw [← h.map_repr a, Polynomial.as_sum_range_C_mul_X_pow (h.repr a)]
  

Proof state:
R : Type u
S : Type v
inst✝³ : CommRing R
inst✝² : Ring S
f : R[X]
inst✝¹ : Algebra R S
T : Type u_1
inst✝ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
h : IsAdjoinRoot S f
g : S →+* T
hmap : ∀ (a : R), g ((algebraMap R S) a) = i a
hroot : g (root h) = x
a : S
⊢ g (h.map (Finset.sum (Finset.range (natDegree (repr h a) + 1)) fun i => C (coeff (repr h a) i) * X ^ i)) =
    (lift i x hx h)
      (h.map (Finset.sum (Finset.range (natDegree (repr h a) + 1)) fun i => C (coeff (repr h a) i) * X ^ i))

Next tactic:
simp only [map_sum, map_mul, map_pow, h.map_X, hroot, ← h.algebraMap_apply, hmap, lift_root,
    lift_algebraMap]
@[simp]
theorem liftHom_map (h : IsAdjoinRoot S f) (z : R[X]) : h.liftHom x hx' (h.map z) = aeval x z := by
  

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : Ring S
f : R[X]
inst✝² : Algebra R S
T : Type u_1
inst✝¹ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
inst✝ : Algebra R T
hx' : (aeval x) f = 0
h : IsAdjoinRoot S f
z : R[X]
⊢ (liftHom x hx' h) (h.map z) = (aeval x) z

Next tactic:
rw [← lift_algebraMap_apply, lift_map, aeval_def]
@[simp]
theorem liftHom_root (h : IsAdjoinRoot S f) : h.liftHom x hx' h.root = x := by
  

Proof state:
R : Type u
S : Type v
inst✝⁴ : CommRing R
inst✝³ : Ring S
f : R[X]
inst✝² : Algebra R S
T : Type u_1
inst✝¹ : CommRing T
i : R →+* T
x : T
hx : eval₂ i x f = 0
inst✝ : Algebra R T
hx' : (aeval x) f = 0
h : IsAdjoinRoot S f
⊢ (liftHom x hx' h) (root h) = x

Next tactic:
rw [← lift_algebraMap_apply, lift_root]
/-- `AdjoinRoot f` is indeed given by adjoining a root of `f`. -/
protected def isAdjoinRoot : IsAdjoinRoot (AdjoinRoot f) f where
  map := AdjoinRoot.mk f
  map_surjective := Ideal.Quotient.mk_surjective
  ker_map := by
    

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
⊢ RingHom.ker (mk f) = Ideal.span {f}

Next tactic:
ext
/-- `AdjoinRoot f` is indeed given by adjoining a root of `f`. -/
protected def isAdjoinRoot : IsAdjoinRoot (AdjoinRoot f) f where
  map := AdjoinRoot.mk f
  map_surjective := Ideal.Quotient.mk_surjective
  ker_map := by
    ext
    

Proof state:
case h
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
x✝ : R[X]
⊢ x✝ ∈ RingHom.ker (mk f) ↔ x✝ ∈ Ideal.span {f}

Next tactic:
rw [RingHom.mem_ker, ← @AdjoinRoot.mk_self _ _ f, AdjoinRoot.mk_eq_mk, Ideal.mem_span_singleton,
      ← dvd_add_left (dvd_refl f), sub_add_cancel]
@[simp]
theorem isAdjoinRoot_root_eq_root : (AdjoinRoot.isAdjoinRoot f).root = AdjoinRoot.root f := by
  

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
⊢ IsAdjoinRoot.root (AdjoinRoot.isAdjoinRoot f) = root f

Next tactic:
simp only [IsAdjoinRoot.root, AdjoinRoot.root, AdjoinRoot.isAdjoinRoot_map_eq_mk]
@[simp]
theorem isAdjoinRootMonic_root_eq_root (hf : Monic f) :
    (AdjoinRoot.isAdjoinRootMonic f hf).root = AdjoinRoot.root f := by
  

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
hf : Monic f
⊢ IsAdjoinRoot.root (AdjoinRoot.isAdjoinRootMonic f hf).toIsAdjoinRoot = root f

Next tactic:
simp only [IsAdjoinRoot.root, AdjoinRoot.root, AdjoinRoot.isAdjoinRootMonic_map_eq_mk]
theorem map_modByMonic (h : IsAdjoinRootMonic S f) (g : R[X]) : h.map (g %ₘ f) = h.map g := by
  

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
g : R[X]
⊢ h.map (g %ₘ f) = h.map g

Next tactic:
rw [← RingHom.sub_mem_ker_iff, mem_ker_map, modByMonic_eq_sub_mul_div _ h.Monic, sub_right_comm,
    sub_self, zero_sub, dvd_neg]
theorem map_modByMonic (h : IsAdjoinRootMonic S f) (g : R[X]) : h.map (g %ₘ f) = h.map g := by
  rw [← RingHom.sub_mem_ker_iff, mem_ker_map, modByMonic_eq_sub_mul_div _ h.Monic, sub_right_comm,
    sub_self, zero_sub, dvd_neg]
  

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
g : R[X]
⊢ f ∣ f * (g /ₘ f)

Next tactic:
exact ⟨_, rfl⟩
theorem modByMonic_repr_map (h : IsAdjoinRootMonic S f) (g : R[X]) :
    h.repr (h.map g) %ₘ f = g %ₘ f :=
  modByMonic_eq_of_dvd_sub h.Monic <| by 

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
g : R[X]
⊢ f ∣ IsAdjoinRoot.repr h.toIsAdjoinRoot (h.map g) - g

Next tactic:
rw [← h.mem_ker_map, RingHom.sub_mem_ker_iff, map_repr]
/-- `IsAdjoinRoot.modByMonicHom` sends the equivalence class of `f` mod `g` to `f %ₘ g`. -/
def modByMonicHom (h : IsAdjoinRootMonic S f) : S →ₗ[R] R[X] where
  toFun x := h.repr x %ₘ f
  map_add' x y := by
    

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
x y : S
⊢ (fun x => IsAdjoinRoot.repr h.toIsAdjoinRoot x %ₘ f) (x + y) =
    (fun x => IsAdjoinRoot.repr h.toIsAdjoinRoot x %ₘ f) x + (fun x => IsAdjoinRoot.repr h.toIsAdjoinRoot x %ₘ f) y

Next tactic:
conv_lhs =>
      rw [← h.map_repr x, ← h.map_repr y, ← map_add]
      dsimp only -- Porting note: added
      rw [h.modByMonic_repr_map, add_modByMonic]
/-- `IsAdjoinRoot.modByMonicHom` sends the equivalence class of `f` mod `g` to `f %ₘ g`. -/
def modByMonicHom (h : IsAdjoinRootMonic S f) : S →ₗ[R] R[X] where
  toFun x := h.repr x %ₘ f
  map_add' x y := by
    conv_lhs =>
      

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : Ring S
f : R[X]
inst✝ : Algebra R S
h : IsAdjoinRootMonic S f
x y : S
| (fun x => IsAdjoinRoot.repr h.toIsAdjoinRoot x %ₘ f) (x + y)

Next tactic:
rw [← h.map_repr x, ← h.map_repr y, ← map_add]
      dsimp only -- Porting note: added
      rw [h.modByMonic_repr_map, add_modByMonic]