l3lab/ntp-mathlib huggingface dataset:
instance : LinearOrderedRing (ℤ√d) := by 

Proof state:
d : ℕ
dnsq : Nonsquare d
⊢ LinearOrderedRing (ℤ√↑d)

Next tactic:
infer_instance
instance : OrderedRing (ℤ√d) := by 

Proof state:
d : ℕ
dnsq : Nonsquare d
⊢ OrderedRing (ℤ√↑d)

Next tactic:
infer_instance
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
⊢ norm a = 0 ↔ a = 0

Next tactic:
refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by 

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
h : a = 0
⊢ norm a = 0

Next tactic:
rw [h, norm_zero]
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : norm a = 0
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
dsimp only [norm] at ha
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re - d * a.im * a.im = 0
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
rw [sub_eq_zero] at ha
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
by_cases h : 0 ≤ d
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · 

Proof state:
case pos
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
h : 0 ≤ d
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    

Proof state:
case pos.intro
d' : ℕ
h_nonsquare : ∀ (n : ℤ), ↑d' ≠ n * n
a : ℤ√↑d'
ha : a.re * a.re = ↑d' * a.im * a.im
h : 0 ≤ ↑d'
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    

Proof state:
case pos.intro
d' : ℕ
h_nonsquare : ∀ (n : ℤ), ↑d' ≠ n * n
a : ℤ√↑d'
ha : a.re * a.re = ↑d' * a.im * a.im
h : 0 ≤ ↑d'
this : Nonsquare d'
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
exact divides_sq_eq_zero_z ha
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    exact divides_sq_eq_zero_z ha
  · 

Proof state:
case neg
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
h : ¬0 ≤ d
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
push_neg at h
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    exact divides_sq_eq_zero_z ha
  · push_neg at h
    

Proof state:
case neg
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
h : d < 0
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
suffices a.re * a.re = 0 by
      rw [eq_zero_of_mul_self_eq_zero this] at ha ⊢
      simpa only [true_and_iff, or_self_right, zero_re, zero_im, eq_self_iff_true, zero_eq_mul,
        mul_zero, mul_eq_zero, h.ne, false_or_iff, or_self_iff] using ha
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    exact divides_sq_eq_zero_z ha
  · push_neg at h
    suffices a.re * a.re = 0 by
      

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
h : d < 0
this : a.re * a.re = 0
⊢ a.re = 0.re ∧ a.im = 0.im

Next tactic:
rw [eq_zero_of_mul_self_eq_zero this] at ha ⊢
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    exact divides_sq_eq_zero_z ha
  · push_neg at h
    suffices a.re * a.re = 0 by
      rw [eq_zero_of_mul_self_eq_zero this] at ha ⊢
      

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : 0 * 0 = d * a.im * a.im
h : d < 0
this : a.re * a.re = 0
⊢ 0 = 0.re ∧ a.im = 0.im

Next tactic:
simpa only [true_and_iff, or_self_right, zero_re, zero_im, eq_self_iff_true, zero_eq_mul,
        mul_zero, mul_eq_zero, h.ne, false_or_iff, or_self_iff] using ha
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    exact divides_sq_eq_zero_z ha
  · push_neg at h
    suffices a.re * a.re = 0 by
      rw [eq_zero_of_mul_self_eq_zero this] at ha ⊢
      simpa only [true_and_iff, or_self_right, zero_re, zero_im, eq_self_iff_true, zero_eq_mul,
        mul_zero, mul_eq_zero, h.ne, false_or_iff, or_self_iff] using ha
    

Proof state:
case neg
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
h : d < 0
⊢ a.re * a.re = 0

Next tactic:
apply _root_.le_antisymm _ (mul_self_nonneg _)
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    exact divides_sq_eq_zero_z ha
  · push_neg at h
    suffices a.re * a.re = 0 by
      rw [eq_zero_of_mul_self_eq_zero this] at ha ⊢
      simpa only [true_and_iff, or_self_right, zero_re, zero_im, eq_self_iff_true, zero_eq_mul,
        mul_zero, mul_eq_zero, h.ne, false_or_iff, or_self_iff] using ha
    apply _root_.le_antisymm _ (mul_self_nonneg _)
    

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
h : d < 0
⊢ a.re * a.re ≤ 0

Next tactic:
rw [ha, mul_assoc]
theorem norm_eq_zero {d : ℤ} (h_nonsquare : ∀ n : ℤ, d ≠ n * n) (a : ℤ√d) : norm a = 0 ↔ a = 0 := by
  refine' ⟨fun ha => ext.mpr _, fun h => by rw [h, norm_zero]⟩
  dsimp only [norm] at ha
  rw [sub_eq_zero] at ha
  by_cases h : 0 ≤ d
  · obtain ⟨d', rfl⟩ := Int.eq_ofNat_of_zero_le h
    haveI : Nonsquare d' := ⟨fun n h => h_nonsquare n <| mod_cast h⟩
    exact divides_sq_eq_zero_z ha
  · push_neg at h
    suffices a.re * a.re = 0 by
      rw [eq_zero_of_mul_self_eq_zero this] at ha ⊢
      simpa only [true_and_iff, or_self_right, zero_re, zero_im, eq_self_iff_true, zero_eq_mul,
        mul_zero, mul_eq_zero, h.ne, false_or_iff, or_self_iff] using ha
    apply _root_.le_antisymm _ (mul_self_nonneg _)
    rw [ha, mul_assoc]
    

Proof state:
d : ℤ
h_nonsquare : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : a.re * a.re = d * a.im * a.im
h : d < 0
⊢ d * (a.im * a.im) ≤ 0

Next tactic:
exact mul_nonpos_of_nonpos_of_nonneg h.le (mul_self_nonneg _)
@[ext]
theorem hom_ext [Ring R] {d : ℤ} (f g : ℤ√d →+* R) (h : f sqrtd = g sqrtd) : f = g := by
  

Proof state:
R : Type
inst✝ : Ring R
d : ℤ
f g : ℤ√d →+* R
h : f sqrtd = g sqrtd
⊢ f = g

Next tactic:
ext ⟨x_re, x_im⟩
@[ext]
theorem hom_ext [Ring R] {d : ℤ} (f g : ℤ√d →+* R) (h : f sqrtd = g sqrtd) : f = g := by
  ext ⟨x_re, x_im⟩
  

Proof state:
case a.mk
R : Type
inst✝ : Ring R
d : ℤ
f g : ℤ√d →+* R
h : f sqrtd = g sqrtd
x_re x_im : ℤ
⊢ f { re := x_re, im := x_im } = g { re := x_re, im := x_im }

Next tactic:
simp [decompose, h]
/-- 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 

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑d }
⊢ (fun a => ↑a.re + ↑a.im * ↑r) 1 = 1

Next tactic:
simp
/-- 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
        

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑d }
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

Next tactic:
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
/-- 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
          

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑d }
a b : ℤ√d
⊢ (↑a.re + ↑a.im * ↑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)

Next tactic:
ring
/-- 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
        

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑d }
a b : ℤ√d
this :
  (↑a.re + ↑a.im * ↑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)
⊢ 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

Next tactic:
simp only [mul_re, Int.cast_add, Int.cast_mul, mul_im, this, r.prop]
/-- 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]
        

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑d }
a b : ℤ√d
this :
  (↑a.re + ↑a.im * ↑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)
⊢ ↑a.re * ↑b.re + ↑d * ↑a.im * ↑b.im + (↑a.re * ↑b.im + ↑a.im * ↑b.re) * ↑r =
    ↑a.re * ↑b.re + (↑a.re * ↑b.im + ↑a.im * ↑b.re) * ↑r + ↑a.im * ↑b.im * ↑d

Next tactic:
ring
/-- 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 

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑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) })
      0 =
    0

Next tactic:
simp
/-- 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
        

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑d }
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

Next tactic:
simp only [add_re, Int.cast_add, add_im]
/-- 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]
        

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
r : { r // r * r = ↑d }
a b : ℤ√d
⊢ ↑a.re + ↑b.re + (↑a.im + ↑b.im) * ↑r = ↑a.re + ↑a.im * ↑r + (↑b.re + ↑b.im * ↑r)

Next tactic:
ring
/-- 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 

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
f : ℤ√d →+* R
⊢ f sqrtd * f sqrtd = ↑d

Next tactic:
rw [← f.map_mul, dmuld, map_intCast]
/-- `lift r` is injective if `d` is non-square, and R has characteristic zero (that is, the map from
`ℤ` into `R` is injective). -/
theorem lift_injective [CharZero R] {d : ℤ} (r : { r : R // r * r = ↑d })
    (hd : ∀ n : ℤ, d ≠ n * n) : Function.Injective (lift r) :=
  (injective_iff_map_eq_zero (lift r)).mpr fun a ha => by
    

Proof state:
R : Type
inst✝¹ : CommRing R
inst✝ : CharZero R
d : ℤ
r : { r // r * r = ↑d }
hd : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : (lift r) a = 0
⊢ a = 0

Next tactic:
have h_inj : Function.Injective ((↑) : ℤ → R) := Int.cast_injective
/-- `lift r` is injective if `d` is non-square, and R has characteristic zero (that is, the map from
`ℤ` into `R` is injective). -/
theorem lift_injective [CharZero R] {d : ℤ} (r : { r : R // r * r = ↑d })
    (hd : ∀ n : ℤ, d ≠ n * n) : Function.Injective (lift r) :=
  (injective_iff_map_eq_zero (lift r)).mpr fun a ha => by
    have h_inj : Function.Injective ((↑) : ℤ → R) := Int.cast_injective
    

Proof state:
R : Type
inst✝¹ : CommRing R
inst✝ : CharZero R
d : ℤ
r : { r // r * r = ↑d }
hd : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : (lift r) a = 0
h_inj : Function.Injective Int.cast
⊢ a = 0

Next tactic:
suffices lift r a.norm = 0 by
      simp only [coe_int_re, add_zero, lift_apply_apply, coe_int_im, Int.cast_zero,
        zero_mul] at this
      rwa [← Int.cast_zero, h_inj.eq_iff, norm_eq_zero hd] at this
/-- `lift r` is injective if `d` is non-square, and R has characteristic zero (that is, the map from
`ℤ` into `R` is injective). -/
theorem lift_injective [CharZero R] {d : ℤ} (r : { r : R // r * r = ↑d })
    (hd : ∀ n : ℤ, d ≠ n * n) : Function.Injective (lift r) :=
  (injective_iff_map_eq_zero (lift r)).mpr fun a ha => by
    have h_inj : Function.Injective ((↑) : ℤ → R) := Int.cast_injective
    suffices lift r a.norm = 0 by
      

Proof state:
R : Type
inst✝¹ : CommRing R
inst✝ : CharZero R
d : ℤ
r : { r // r * r = ↑d }
hd : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : (lift r) a = 0
h_inj : Function.Injective Int.cast
this : (lift r) ↑(norm a) = 0
⊢ a = 0

Next tactic:
simp only [coe_int_re, add_zero, lift_apply_apply, coe_int_im, Int.cast_zero,
        zero_mul] at this
/-- `lift r` is injective if `d` is non-square, and R has characteristic zero (that is, the map from
`ℤ` into `R` is injective). -/
theorem lift_injective [CharZero R] {d : ℤ} (r : { r : R // r * r = ↑d })
    (hd : ∀ n : ℤ, d ≠ n * n) : Function.Injective (lift r) :=
  (injective_iff_map_eq_zero (lift r)).mpr fun a ha => by
    have h_inj : Function.Injective ((↑) : ℤ → R) := Int.cast_injective
    suffices lift r a.norm = 0 by
      simp only [coe_int_re, add_zero, lift_apply_apply, coe_int_im, Int.cast_zero,
        zero_mul] at this
      

Proof state:
R : Type
inst✝¹ : CommRing R
inst✝ : CharZero R
d : ℤ
r : { r // r * r = ↑d }
hd : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : (lift r) a = 0
h_inj : Function.Injective Int.cast
this : ↑(norm a) = 0
⊢ a = 0

Next tactic:
rwa [← Int.cast_zero, h_inj.eq_iff, norm_eq_zero hd] at this
/-- `lift r` is injective if `d` is non-square, and R has characteristic zero (that is, the map from
`ℤ` into `R` is injective). -/
theorem lift_injective [CharZero R] {d : ℤ} (r : { r : R // r * r = ↑d })
    (hd : ∀ n : ℤ, d ≠ n * n) : Function.Injective (lift r) :=
  (injective_iff_map_eq_zero (lift r)).mpr fun a ha => by
    have h_inj : Function.Injective ((↑) : ℤ → R) := Int.cast_injective
    suffices lift r a.norm = 0 by
      simp only [coe_int_re, add_zero, lift_apply_apply, coe_int_im, Int.cast_zero,
        zero_mul] at this
      rwa [← Int.cast_zero, h_inj.eq_iff, norm_eq_zero hd] at this
    

Proof state:
R : Type
inst✝¹ : CommRing R
inst✝ : CharZero R
d : ℤ
r : { r // r * r = ↑d }
hd : ∀ (n : ℤ), d ≠ n * n
a : ℤ√d
ha : (lift r) a = 0
h_inj : Function.Injective Int.cast
⊢ (lift r) ↑(norm a) = 0

Next tactic:
rw [norm_eq_mul_conj, RingHom.map_mul, ha, zero_mul]
/-- An element of `ℤ√d` has norm equal to `1` if and only if it is contained in the submonoid
of unitary elements. -/
theorem norm_eq_one_iff_mem_unitary {d : ℤ} {a : ℤ√d} : a.norm = 1 ↔ a ∈ unitary (ℤ√d) := by
  

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
a : ℤ√d
⊢ norm a = 1 ↔ a ∈ unitary (ℤ√d)

Next tactic:
rw [unitary.mem_iff_self_mul_star, ← norm_eq_mul_conj]
/-- An element of `ℤ√d` has norm equal to `1` if and only if it is contained in the submonoid
of unitary elements. -/
theorem norm_eq_one_iff_mem_unitary {d : ℤ} {a : ℤ√d} : a.norm = 1 ↔ a ∈ unitary (ℤ√d) := by
  rw [unitary.mem_iff_self_mul_star, ← norm_eq_mul_conj]
  

Proof state:
R : Type
inst✝ : CommRing R
d : ℤ
a : ℤ√d
⊢ norm a = 1 ↔ ↑(norm a) = 1

Next tactic:
norm_cast
/-- **Rolle's Theorem**, a version for a function on an open interval: if `f` has the same limit
`l` at `𝓝[>] a` and `𝓝[<] b`, then `deriv f c = 0` for some `c ∈ (a, b)`. This version
does not require differentiability of `f` because we define `deriv f c = 0` whenever `f` is not
differentiable at `c`. -/
theorem exists_deriv_eq_zero' (hab : a < b) (hfa : Tendsto f (𝓝[>] a) (𝓝 l))
    (hfb : Tendsto f (𝓝[<] b) (𝓝 l)) : ∃ c ∈ Ioo a b, deriv f c = 0 := by
  

Proof state:
f f' : ℝ → ℝ
a b l : ℝ
hab : a < b
hfa : Tendsto f (𝓝[>] a) (𝓝 l)
hfb : Tendsto f (𝓝[<] b) (𝓝 l)
⊢ ∃ c ∈ Ioo a b, deriv f c = 0

Next tactic:
by_cases h : ∀ x ∈ Ioo a b, DifferentiableAt ℝ f x