/-- The unique `RingHom` from `ℤ√d` to a ring `R`, constructed by replacing `√d` with the provided
root. Conversely, this associates to every mapping `ℤ√d →+* R` a value of `√d` in `R`. -/
@[simps]
def lift {d : ℤ} : { r : R // r * r = ↑d } ≃ (ℤ√d →+* R) where
  toFun r :=
    { toFun := fun a => a.1 + a.2 * (r : R)
      map_zero' := by simp
      map_add' := fun a b => by
        simp only [add_re, Int.cast_add, add_im]
        ring
      map_one' := by simp
      map_mul' := fun a b => by
        have :
          (a.re + a.im * r : R) * (b.re + b.im * r) =
            a.re * b.re + (a.re * b.im + a.im * b.re) * r + a.im * b.im * (r * r) := by
          ring
        simp only [mul_re, Int.cast_add, Int.cast_mul, mul_im, this, r.prop]
        ring }
  invFun f := ⟨f sqrtd, by rw [← f.map_mul, dmuld, map_intCast]⟩
  left_inv r := by
    ext
    simp
  right_inv f := by
    -- Porting note: was `ext`
    

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
f : ℤ√d →+* R
⊢ (fun r =>
        {
          toMonoidHom :=
            { toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
              map_mul' :=
                (_ :
                  ∀ (a b : ℤ√d),
                    OneHom.toFun { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } (a * b) =
                      OneHom.toFun { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                        OneHom.toFun { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } b) },
          map_zero' := (_ : ↑0 + ↑0 * ↑r = 0),
          map_add' :=
            (_ :
              ∀ (a b : ℤ√d),
                OneHom.toFun
                    (↑{ toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
                        map_mul' :=
                          (_ :
                            ∀ (a b : ℤ√d),
                              OneHom.toFun { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                  (a * b) =
                                OneHom.toFun
                                    { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                                  OneHom.toFun
                                    { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } b) })
                    (a + b) =
                  OneHom.toFun
                      (↑{ toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
                          map_mul' :=
                            (_ :
                              ∀ (a b : ℤ√d),
                                OneHom.toFun
                                    { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                    (a * b) =
                                  OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                                    OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } b) })
                      a +
                    OneHom.toFun
                      (↑{ toOneHom := { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) },
                          map_mul' :=
                            (_ :
                              ∀ (a b : ℤ√d),
                                OneHom.toFun
                                    { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) }
                                    (a * b) =
                                  OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } a *
                                    OneHom.toFun
                                      { toFun := fun a => ↑a.re + ↑a.im * ↑r, map_one' := (_ : ↑1 + ↑0 * ↑r = 1) } b) })
                      b) })
      ((fun f => { val := f sqrtd, property := (_ : f sqrtd * f sqrtd = ↑d) }) f) =
    f

Next tactic:
refine hom_ext _ _ ?_