l3lab/ntp-mathlib huggingface dataset:
/-- Elements of the uniformity (defined generally for completions) can be characterized in terms
of the distance. -/
protected theorem mem_uniformity_dist (s : Set (Completion α × Completion α)) :
    s ∈ 𝓤 (Completion α) ↔ ∃ ε > 0, ∀ {a b}, dist a b < ε → (a, b) ∈ s := by
  constructor
  · /- Start from an entourage `s`. It contains a closed entourage `t`. Its pullback in `α` is an
      entourage, so it contains an `ε`-neighborhood of the diagonal by definition of the entourages
      in metric spaces. Then `t` contains an `ε`-neighborhood of the diagonal in `Completion α`, as
      closed properties pass to the completion. -/
    intro hs
    rcases mem_uniformity_isClosed hs with ⟨t, ht, ⟨tclosed, ts⟩⟩
    have A : { x : α × α | (↑x.1, ↑x.2) ∈ t } ∈ uniformity α :=
      uniformContinuous_def.1 (uniformContinuous_coe α) t ht
    rcases mem_uniformity_dist.1 A with ⟨ε, εpos, hε⟩
    refine' ⟨ε, εpos, @fun x y hxy ↦ _⟩
    have : ε ≤ dist x y ∨ (x, y) ∈ t := by
      refine' induction_on₂ x y _ _
      · have : { x : Completion α × Completion α | ε ≤ dist x.fst x.snd ∨ (x.fst, x.snd) ∈ t } =
               { p : Completion α × Completion α | ε ≤ dist p.1 p.2 } ∪ t := by ext; simp
        rw [this]
        apply IsClosed.union _ tclosed
        exact isClosed_le continuous_const Completion.uniformContinuous_dist.continuous
      · intro x y
        rw [Completion.dist_eq]
        by_cases h : ε ≤ dist x y
        · exact Or.inl h
        · have Z := hε (not_le.1 h)
          simp only [Set.mem_setOf_eq] at Z
          exact Or.inr Z
    simp only [not_le.mpr hxy, false_or_iff, not_le] at this
    exact ts this
  · /- Start from a set `s` containing an ε-neighborhood of the diagonal in `Completion α`. To show
        that it is an entourage, we use the fact that `dist` is uniformly continuous on
        `Completion α × Completion α` (this is a general property of the extension of uniformly
        continuous functions). Therefore, the preimage of the ε-neighborhood of the diagonal in ℝ
        is an entourage in `Completion α × Completion α`. Massaging this property, it follows that
        the ε-neighborhood of the diagonal is an entourage in `Completion α`, and therefore this is
        also the case of `s`. -/
    rintro ⟨ε, εpos, hε⟩
    let r : Set (ℝ × ℝ) := { p | dist p.1 p.2 < ε }
    have : r ∈ uniformity ℝ := Metric.dist_mem_uniformity εpos
    have T := uniformContinuous_def.1 (@Completion.uniformContinuous_dist α _) r this
    simp only [uniformity_prod_eq_prod, mem_prod_iff, exists_prop, Filter.mem_map,
      Set.mem_setOf_eq] at T
    

Proof state:
case mpr.intro.intro
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
s : Set (Completion α × Completion α)
ε : ℝ
εpos : ε > 0
hε : ∀ {a b : Completion α}, dist a b < ε → (a, b) ∈ s
r : Set (ℝ × ℝ) := {p | dist p.1 p.2 < ε}
this : r ∈ 𝓤 ℝ
T :
  ∃ t₁ ∈ 𝓤 (Completion α),
    ∃ t₂ ∈ 𝓤 (Completion α),
      t₁ ×ˢ t₂ ⊆ (fun p => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' {x | dist (dist x.1.1 x.1.2) (dist x.2.1 x.2.2) < ε}
⊢ s ∈ 𝓤 (Completion α)

Next tactic:
rcases T with ⟨t1, ht1, t2, ht2, ht⟩
/-- If two points are at distance 0, then they coincide. -/
protected theorem eq_of_dist_eq_zero (x y : Completion α) (h : dist x y = 0) : x = y := by
  /- This follows from the separation of `Completion α` and from the description of
    entourages in terms of the distance. -/
  

Proof state:
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
x y : Completion α
h : dist x y = 0
⊢ x = y

Next tactic:
have : SeparatedSpace (Completion α) := by infer_instance
/-- If two points are at distance 0, then they coincide. -/
protected theorem eq_of_dist_eq_zero (x y : Completion α) (h : dist x y = 0) : x = y := by
  /- This follows from the separation of `Completion α` and from the description of
    entourages in terms of the distance. -/
  have : SeparatedSpace (Completion α) := by 

Proof state:
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
x y : Completion α
h : dist x y = 0
⊢ SeparatedSpace (Completion α)

Next tactic:
infer_instance
/-- If two points are at distance 0, then they coincide. -/
protected theorem eq_of_dist_eq_zero (x y : Completion α) (h : dist x y = 0) : x = y := by
  /- This follows from the separation of `Completion α` and from the description of
    entourages in terms of the distance. -/
  have : SeparatedSpace (Completion α) := by infer_instance
  

Proof state:
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
x y : Completion α
h : dist x y = 0
this : SeparatedSpace (Completion α)
⊢ x = y

Next tactic:
refine' separated_def.1 this x y fun s hs ↦ _
/-- If two points are at distance 0, then they coincide. -/
protected theorem eq_of_dist_eq_zero (x y : Completion α) (h : dist x y = 0) : x = y := by
  /- This follows from the separation of `Completion α` and from the description of
    entourages in terms of the distance. -/
  have : SeparatedSpace (Completion α) := by infer_instance
  refine' separated_def.1 this x y fun s hs ↦ _
  

Proof state:
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
x y : Completion α
h : dist x y = 0
this : SeparatedSpace (Completion α)
s : Set (Completion α × Completion α)
hs : s ∈ 𝓤 (Completion α)
⊢ (x, y) ∈ s

Next tactic:
rcases (Completion.mem_uniformity_dist s).1 hs with ⟨ε, εpos, hε⟩
/-- If two points are at distance 0, then they coincide. -/
protected theorem eq_of_dist_eq_zero (x y : Completion α) (h : dist x y = 0) : x = y := by
  /- This follows from the separation of `Completion α` and from the description of
    entourages in terms of the distance. -/
  have : SeparatedSpace (Completion α) := by infer_instance
  refine' separated_def.1 this x y fun s hs ↦ _
  rcases (Completion.mem_uniformity_dist s).1 hs with ⟨ε, εpos, hε⟩
  

Proof state:
case intro.intro
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
x y : Completion α
h : dist x y = 0
this : SeparatedSpace (Completion α)
s : Set (Completion α × Completion α)
hs : s ∈ 𝓤 (Completion α)
ε : ℝ
εpos : ε > 0
hε : ∀ {a b : Completion α}, dist a b < ε → (a, b) ∈ s
⊢ (x, y) ∈ s

Next tactic:
rw [← h] at εpos
/-- If two points are at distance 0, then they coincide. -/
protected theorem eq_of_dist_eq_zero (x y : Completion α) (h : dist x y = 0) : x = y := by
  /- This follows from the separation of `Completion α` and from the description of
    entourages in terms of the distance. -/
  have : SeparatedSpace (Completion α) := by infer_instance
  refine' separated_def.1 this x y fun s hs ↦ _
  rcases (Completion.mem_uniformity_dist s).1 hs with ⟨ε, εpos, hε⟩
  rw [← h] at εpos
  

Proof state:
case intro.intro
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
x y : Completion α
h : dist x y = 0
this : SeparatedSpace (Completion α)
s : Set (Completion α × Completion α)
hs : s ∈ 𝓤 (Completion α)
ε : ℝ
εpos : ε > dist x y
hε : ∀ {a b : Completion α}, dist a b < ε → (a, b) ∈ s
⊢ (x, y) ∈ s

Next tactic:
exact hε εpos
/-- Reformulate `Completion.mem_uniformity_dist` in terms that are suitable for the definition
of the metric space structure. -/
protected theorem uniformity_dist' :
    𝓤 (Completion α) = ⨅ ε : { ε : ℝ // 0 < ε }, 𝓟 { p | dist p.1 p.2 < ε.val } := by
  

Proof state:
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
⊢ 𝓤 (Completion α) = ⨅ ε, 𝓟 {p | dist p.1 p.2 < ↑ε}

Next tactic:
ext s
/-- Reformulate `Completion.mem_uniformity_dist` in terms that are suitable for the definition
of the metric space structure. -/
protected theorem uniformity_dist' :
    𝓤 (Completion α) = ⨅ ε : { ε : ℝ // 0 < ε }, 𝓟 { p | dist p.1 p.2 < ε.val } := by
  ext s; 

Proof state:
case a
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
s : Set (Completion α × Completion α)
⊢ s ∈ 𝓤 (Completion α) ↔ s ∈ ⨅ ε, 𝓟 {p | dist p.1 p.2 < ↑ε}

Next tactic:
rw [mem_iInf_of_directed]
/-- Reformulate `Completion.mem_uniformity_dist` in terms that are suitable for the definition
of the metric space structure. -/
protected theorem uniformity_dist' :
    𝓤 (Completion α) = ⨅ ε : { ε : ℝ // 0 < ε }, 𝓟 { p | dist p.1 p.2 < ε.val } := by
  ext s; rw [mem_iInf_of_directed]
  · 

Proof state:
case a
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
s : Set (Completion α × Completion α)
⊢ s ∈ 𝓤 (Completion α) ↔ ∃ i, s ∈ 𝓟 {p | dist p.1 p.2 < ↑i}

Next tactic:
simp [Completion.mem_uniformity_dist, subset_def]
/-- Reformulate `Completion.mem_uniformity_dist` in terms that are suitable for the definition
of the metric space structure. -/
protected theorem uniformity_dist' :
    𝓤 (Completion α) = ⨅ ε : { ε : ℝ // 0 < ε }, 𝓟 { p | dist p.1 p.2 < ε.val } := by
  ext s; rw [mem_iInf_of_directed]
  · simp [Completion.mem_uniformity_dist, subset_def]
  · 

Proof state:
case a.h
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
s : Set (Completion α × Completion α)
⊢ Directed (fun x x_1 => x ≥ x_1) fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}

Next tactic:
rintro ⟨r, hr⟩ ⟨p, hp⟩
/-- Reformulate `Completion.mem_uniformity_dist` in terms that are suitable for the definition
of the metric space structure. -/
protected theorem uniformity_dist' :
    𝓤 (Completion α) = ⨅ ε : { ε : ℝ // 0 < ε }, 𝓟 { p | dist p.1 p.2 < ε.val } := by
  ext s; rw [mem_iInf_of_directed]
  · simp [Completion.mem_uniformity_dist, subset_def]
  · rintro ⟨r, hr⟩ ⟨p, hp⟩
    

Proof state:
case a.h.mk.mk
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
s : Set (Completion α × Completion α)
r : ℝ
hr : 0 < r
p : ℝ
hp : 0 < p
⊢ ∃ z,
    (fun x x_1 => x ≥ x_1) ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) { val := r, property := hr })
        ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) z) ∧
      (fun x x_1 => x ≥ x_1) ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) { val := p, property := hp })
        ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) z)

Next tactic:
use ⟨min r p, lt_min hr hp⟩
/-- Reformulate `Completion.mem_uniformity_dist` in terms that are suitable for the definition
of the metric space structure. -/
protected theorem uniformity_dist' :
    𝓤 (Completion α) = ⨅ ε : { ε : ℝ // 0 < ε }, 𝓟 { p | dist p.1 p.2 < ε.val } := by
  ext s; rw [mem_iInf_of_directed]
  · simp [Completion.mem_uniformity_dist, subset_def]
  · rintro ⟨r, hr⟩ ⟨p, hp⟩
    use ⟨min r p, lt_min hr hp⟩
    

Proof state:
case h
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
s : Set (Completion α × Completion α)
r : ℝ
hr : 0 < r
p : ℝ
hp : 0 < p
⊢ (fun x x_1 => x ≥ x_1) ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) { val := r, property := hr })
      ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) { val := min r p, property := (_ : 0 < min r p) }) ∧
    (fun x x_1 => x ≥ x_1) ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) { val := p, property := hp })
      ((fun ε => 𝓟 {p | dist p.1 p.2 < ↑ε}) { val := min r p, property := (_ : 0 < min r p) })

Next tactic:
simp (config := { contextual := true }) [lt_min_iff]
protected theorem uniformity_dist : 𝓤 (Completion α) = ⨅ ε > 0, 𝓟 { p | dist p.1 p.2 < ε } := by
  

Proof state:
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
⊢ 𝓤 (Completion α) = ⨅ ε, ⨅ (_ : ε > 0), 𝓟 {p | dist p.1 p.2 < ε}

Next tactic:
simpa [iInf_subtype] using @Completion.uniformity_dist' α _
/-- Metric space structure on the completion of a pseudo_metric space. -/
instance instMetricSpace : MetricSpace (Completion α) where
  dist_self := Completion.dist_self
  eq_of_dist_eq_zero := Completion.eq_of_dist_eq_zero _ _
  dist_comm := Completion.dist_comm
  dist_triangle := Completion.dist_triangle
  dist := dist
  toUniformSpace := by 

Proof state:
α : Type u
β : Type v
inst✝ : PseudoMetricSpace α
⊢ UniformSpace (Completion α)

Next tactic:
infer_instance
theorem LipschitzWith.completion_extension [MetricSpace β] [CompleteSpace β] {f : α → β}
    {K : ℝ≥0} (h : LipschitzWith K f) : LipschitzWith K (Completion.extension f) :=
  LipschitzWith.of_dist_le_mul fun x y => induction_on₂ x y
    (isClosed_le (by 

Proof state:
α : Type u
β : Type v
inst✝² : PseudoMetricSpace α
inst✝¹ : MetricSpace β
inst✝ : CompleteSpace β
f : α → β
K : ℝ≥0
h : LipschitzWith K f
x y : Completion α
⊢ Continuous fun x => dist (Completion.extension f x.1) (Completion.extension f x.2)

Next tactic:
continuity
theorem LipschitzWith.completion_extension [MetricSpace β] [CompleteSpace β] {f : α → β}
    {K : ℝ≥0} (h : LipschitzWith K f) : LipschitzWith K (Completion.extension f) :=
  LipschitzWith.of_dist_le_mul fun x y => induction_on₂ x y
    (isClosed_le (by continuity) (by 

Proof state:
α : Type u
β : Type v
inst✝² : PseudoMetricSpace α
inst✝¹ : MetricSpace β
inst✝ : CompleteSpace β
f : α → β
K : ℝ≥0
h : LipschitzWith K f
x y : Completion α
⊢ Continuous fun x => ↑K * dist x.1 x.2

Next tactic:
continuity
theorem LipschitzWith.completion_extension [MetricSpace β] [CompleteSpace β] {f : α → β}
    {K : ℝ≥0} (h : LipschitzWith K f) : LipschitzWith K (Completion.extension f) :=
  LipschitzWith.of_dist_le_mul fun x y => induction_on₂ x y
    (isClosed_le (by continuity) (by continuity)) <| by
      

Proof state:
α : Type u
β : Type v
inst✝² : PseudoMetricSpace α
inst✝¹ : MetricSpace β
inst✝ : CompleteSpace β
f : α → β
K : ℝ≥0
h : LipschitzWith K f
x y : Completion α
⊢ ∀ (a b : α), dist (Completion.extension f (↑α a)) (Completion.extension f (↑α b)) ≤ ↑K * dist (↑α a) (↑α b)

Next tactic:
simpa only [extension_coe h.uniformContinuous, Completion.dist_eq] using h.dist_le_mul
theorem Isometry.completion_extension [MetricSpace β] [CompleteSpace β] {f : α → β}
    (h : Isometry f) : Isometry (Completion.extension f) :=
  Isometry.of_dist_eq fun x y => induction_on₂ x y
    (isClosed_eq (by 

Proof state:
α : Type u
β : Type v
inst✝² : PseudoMetricSpace α
inst✝¹ : MetricSpace β
inst✝ : CompleteSpace β
f : α → β
h : Isometry f
x y : Completion α
⊢ Continuous fun x => dist (Completion.extension f x.1) (Completion.extension f x.2)

Next tactic:
continuity
theorem Isometry.completion_extension [MetricSpace β] [CompleteSpace β] {f : α → β}
    (h : Isometry f) : Isometry (Completion.extension f) :=
  Isometry.of_dist_eq fun x y => induction_on₂ x y
    (isClosed_eq (by continuity) (by 

Proof state:
α : Type u
β : Type v
inst✝² : PseudoMetricSpace α
inst✝¹ : MetricSpace β
inst✝ : CompleteSpace β
f : α → β
h : Isometry f
x y : Completion α
⊢ Continuous fun x => dist x.1 x.2

Next tactic:
continuity
theorem Isometry.completion_extension [MetricSpace β] [CompleteSpace β] {f : α → β}
    (h : Isometry f) : Isometry (Completion.extension f) :=
  Isometry.of_dist_eq fun x y => induction_on₂ x y
    (isClosed_eq (by continuity) (by continuity)) fun _ _ ↦ by
      

Proof state:
α : Type u
β : Type v
inst✝² : PseudoMetricSpace α
inst✝¹ : MetricSpace β
inst✝ : CompleteSpace β
f : α → β
h : Isometry f
x y : Completion α
x✝¹ x✝ : α
⊢ dist (Completion.extension f (↑α x✝¹)) (Completion.extension f (↑α x✝)) = dist (↑α x✝¹) (↑α x✝)

Next tactic:
simp only [extension_coe h.uniformContinuous, Completion.dist_eq, h.dist_eq]
theorem sinh_half_dist (z w : ℍ) :
    sinh (dist z w / 2) = dist (z : ℂ) w / (2 * sqrt (z.im * w.im)) := by
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
⊢ sinh (dist z w / 2) = dist ↑z ↑w / (2 * sqrt (im z * im w))

Next tactic:
rw [dist_eq, mul_div_cancel_left (arsinh _) two_ne_zero, sinh_arsinh]
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
⊢ cosh (dist z w / 2) = dist (↑z) ((starRingEnd ℂ) ↑w) / (2 * sqrt (im z * im w))

Next tactic:
have H₁ : (2 ^ 2 : ℝ) = 4 := by norm_num1
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  have H₁ : (2 ^ 2 : ℝ) = 4 := by 

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
⊢ 2 ^ 2 = 4

Next tactic:
norm_num1
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  have H₁ : (2 ^ 2 : ℝ) = 4 := by norm_num1
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
H₁ : 2 ^ 2 = 4
⊢ cosh (dist z w / 2) = dist (↑z) ((starRingEnd ℂ) ↑w) / (2 * sqrt (im z * im w))

Next tactic:
have H₂ : 0 < z.im * w.im := mul_pos z.im_pos w.im_pos
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  have H₁ : (2 ^ 2 : ℝ) = 4 := by norm_num1
  have H₂ : 0 < z.im * w.im := mul_pos z.im_pos w.im_pos
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
H₁ : 2 ^ 2 = 4
H₂ : 0 < im z * im w
⊢ cosh (dist z w / 2) = dist (↑z) ((starRingEnd ℂ) ↑w) / (2 * sqrt (im z * im w))

Next tactic:
have H₃ : 0 < 2 * sqrt (z.im * w.im) := mul_pos two_pos (sqrt_pos.2 H₂)
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  have H₁ : (2 ^ 2 : ℝ) = 4 := by norm_num1
  have H₂ : 0 < z.im * w.im := mul_pos z.im_pos w.im_pos
  have H₃ : 0 < 2 * sqrt (z.im * w.im) := mul_pos two_pos (sqrt_pos.2 H₂)
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
H₁ : 2 ^ 2 = 4
H₂ : 0 < im z * im w
H₃ : 0 < 2 * sqrt (im z * im w)
⊢ cosh (dist z w / 2) = dist (↑z) ((starRingEnd ℂ) ↑w) / (2 * sqrt (im z * im w))

Next tactic:
rw [← sq_eq_sq (cosh_pos _).le (div_nonneg dist_nonneg H₃.le), cosh_sq', sinh_half_dist, div_pow,
    div_pow, one_add_div (pow_ne_zero 2 H₃.ne'), mul_pow, sq_sqrt H₂.le, H₁]
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  have H₁ : (2 ^ 2 : ℝ) = 4 := by norm_num1
  have H₂ : 0 < z.im * w.im := mul_pos z.im_pos w.im_pos
  have H₃ : 0 < 2 * sqrt (z.im * w.im) := mul_pos two_pos (sqrt_pos.2 H₂)
  rw [← sq_eq_sq (cosh_pos _).le (div_nonneg dist_nonneg H₃.le), cosh_sq', sinh_half_dist, div_pow,
    div_pow, one_add_div (pow_ne_zero 2 H₃.ne'), mul_pow, sq_sqrt H₂.le, H₁]
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
H₁ : 2 ^ 2 = 4
H₂ : 0 < im z * im w
H₃ : 0 < 2 * sqrt (im z * im w)
⊢ (4 * (im z * im w) + dist ↑z ↑w ^ 2) / (4 * (im z * im w)) = dist (↑z) ((starRingEnd ℂ) ↑w) ^ 2 / (4 * (im z * im w))

Next tactic:
congr 1
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  have H₁ : (2 ^ 2 : ℝ) = 4 := by norm_num1
  have H₂ : 0 < z.im * w.im := mul_pos z.im_pos w.im_pos
  have H₃ : 0 < 2 * sqrt (z.im * w.im) := mul_pos two_pos (sqrt_pos.2 H₂)
  rw [← sq_eq_sq (cosh_pos _).le (div_nonneg dist_nonneg H₃.le), cosh_sq', sinh_half_dist, div_pow,
    div_pow, one_add_div (pow_ne_zero 2 H₃.ne'), mul_pow, sq_sqrt H₂.le, H₁]
  congr 1
  

Proof state:
case e_a
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
H₁ : 2 ^ 2 = 4
H₂ : 0 < im z * im w
H₃ : 0 < 2 * sqrt (im z * im w)
⊢ 4 * (im z * im w) + dist ↑z ↑w ^ 2 = dist (↑z) ((starRingEnd ℂ) ↑w) ^ 2

Next tactic:
simp only [Complex.dist_eq, Complex.sq_abs, Complex.normSq_sub, Complex.normSq_conj,
    Complex.conj_conj, Complex.mul_re, Complex.conj_re, Complex.conj_im, coe_im]
theorem cosh_half_dist (z w : ℍ) :
    cosh (dist z w / 2) = dist (z : ℂ) (conj (w : ℂ)) / (2 * sqrt (z.im * w.im)) := by
  have H₁ : (2 ^ 2 : ℝ) = 4 := by norm_num1
  have H₂ : 0 < z.im * w.im := mul_pos z.im_pos w.im_pos
  have H₃ : 0 < 2 * sqrt (z.im * w.im) := mul_pos two_pos (sqrt_pos.2 H₂)
  rw [← sq_eq_sq (cosh_pos _).le (div_nonneg dist_nonneg H₃.le), cosh_sq', sinh_half_dist, div_pow,
    div_pow, one_add_div (pow_ne_zero 2 H₃.ne'), mul_pow, sq_sqrt H₂.le, H₁]
  congr 1
  simp only [Complex.dist_eq, Complex.sq_abs, Complex.normSq_sub, Complex.normSq_conj,
    Complex.conj_conj, Complex.mul_re, Complex.conj_re, Complex.conj_im, coe_im]
  

Proof state:
case e_a
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
H₁ : 2 ^ 2 = 4
H₂ : 0 < im z * im w
H₃ : 0 < 2 * sqrt (im z * im w)
⊢ 4 * (im z * im w) + (Complex.normSq ↑z + Complex.normSq ↑w - 2 * ((↑z).re * (↑w).re - im z * -im w)) =
    Complex.normSq ↑z + Complex.normSq ↑w - 2 * ((↑z).re * (↑w).re - im z * im w)

Next tactic:
ring
theorem tanh_half_dist (z w : ℍ) :
    tanh (dist z w / 2) = dist (z : ℂ) w / dist (z : ℂ) (conj ↑w) := by
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
⊢ tanh (dist z w / 2) = dist ↑z ↑w / dist (↑z) ((starRingEnd ℂ) ↑w)

Next tactic:
rw [tanh_eq_sinh_div_cosh, sinh_half_dist, cosh_half_dist, div_div_div_comm, div_self, div_one]
theorem tanh_half_dist (z w : ℍ) :
    tanh (dist z w / 2) = dist (z : ℂ) w / dist (z : ℂ) (conj ↑w) := by
  rw [tanh_eq_sinh_div_cosh, sinh_half_dist, cosh_half_dist, div_div_div_comm, div_self, div_one]
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
⊢ 2 * sqrt (im z * im w) ≠ 0

Next tactic:
exact (mul_pos (zero_lt_two' ℝ) (sqrt_pos.2 <| mul_pos z.im_pos w.im_pos)).ne'
theorem exp_half_dist (z w : ℍ) :
    exp (dist z w / 2) = (dist (z : ℂ) w + dist (z : ℂ) (conj ↑w)) / (2 * sqrt (z.im * w.im)) := by
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
⊢ rexp (dist z w / 2) = (dist ↑z ↑w + dist (↑z) ((starRingEnd ℂ) ↑w)) / (2 * sqrt (im z * im w))

Next tactic:
rw [← sinh_add_cosh, sinh_half_dist, cosh_half_dist, add_div]
theorem cosh_dist (z w : ℍ) : cosh (dist z w) = 1 + dist (z : ℂ) w ^ 2 / (2 * z.im * w.im) := by
  

Proof state:
z✝ w✝ : ℍ
r R : ℝ
z w : ℍ
⊢ cosh (dist z w) = 1 + dist ↑z ↑w ^ 2 / (2 * im z * im w)

Next tactic:
rw [dist_eq, cosh_two_mul, cosh_sq', add_assoc, ← two_mul, sinh_arsinh, div_pow, mul_pow,
    sq_sqrt (mul_pos z.im_pos w.im_pos).le, sq (2 : ℝ), mul_assoc, ← mul_div_assoc, mul_assoc,
    mul_div_mul_left _ _ (two_ne_zero' ℝ)]
theorem sinh_half_dist_add_dist (a b c : ℍ) : sinh ((dist a b + dist b c) / 2) =
    (dist (a : ℂ) b * dist (c : ℂ) (conj ↑b) + dist (b : ℂ) c * dist (a : ℂ) (conj ↑b)) /
      (2 * sqrt (a.im * c.im) * dist (b : ℂ) (conj ↑b)) := by
  

Proof state:
z w : ℍ
r R : ℝ
a b c : ℍ
⊢ sinh ((dist a b + dist b c) / 2) =
    (dist ↑a ↑b * dist (↑c) ((starRingEnd ℂ) ↑b) + dist ↑b ↑c * dist (↑a) ((starRingEnd ℂ) ↑b)) /
      (2 * sqrt (im a * im c) * dist (↑b) ((starRingEnd ℂ) ↑b))

Next tactic:
simp only [add_div _ _ (2 : ℝ), sinh_add, sinh_half_dist, cosh_half_dist, div_mul_div_comm]
theorem sinh_half_dist_add_dist (a b c : ℍ) : sinh ((dist a b + dist b c) / 2) =
    (dist (a : ℂ) b * dist (c : ℂ) (conj ↑b) + dist (b : ℂ) c * dist (a : ℂ) (conj ↑b)) /
      (2 * sqrt (a.im * c.im) * dist (b : ℂ) (conj ↑b)) := by
  simp only [add_div _ _ (2 : ℝ), sinh_add, sinh_half_dist, cosh_half_dist, div_mul_div_comm]
  

Proof state:
z w : ℍ
r R : ℝ
a b c : ℍ
⊢ dist ↑a ↑b * dist (↑b) ((starRingEnd ℂ) ↑c) / (2 * sqrt (im a * im b) * (2 * sqrt (im b * im c))) +
      dist (↑a) ((starRingEnd ℂ) ↑b) * dist ↑b ↑c / (2 * sqrt (im a * im b) * (2 * sqrt (im b * im c))) =
    (dist ↑a ↑b * dist (↑c) ((starRingEnd ℂ) ↑b) + dist ↑b ↑c * dist (↑a) ((starRingEnd ℂ) ↑b)) /
      (2 * sqrt (im a * im c) * dist (↑b) ((starRingEnd ℂ) ↑b))

Next tactic:
rw [← add_div, Complex.dist_self_conj, coe_im, abs_of_pos b.im_pos, mul_comm (dist (b : ℂ) _),
    dist_comm (b : ℂ), Complex.dist_conj_comm, mul_mul_mul_comm, mul_mul_mul_comm _ _ _ b.im]
theorem sinh_half_dist_add_dist (a b c : ℍ) : sinh ((dist a b + dist b c) / 2) =
    (dist (a : ℂ) b * dist (c : ℂ) (conj ↑b) + dist (b : ℂ) c * dist (a : ℂ) (conj ↑b)) /
      (2 * sqrt (a.im * c.im) * dist (b : ℂ) (conj ↑b)) := by
  simp only [add_div _ _ (2 : ℝ), sinh_add, sinh_half_dist, cosh_half_dist, div_mul_div_comm]
  rw [← add_div, Complex.dist_self_conj, coe_im, abs_of_pos b.im_pos, mul_comm (dist (b : ℂ) _),
    dist_comm (b : ℂ), Complex.dist_conj_comm, mul_mul_mul_comm, mul_mul_mul_comm _ _ _ b.im]
  

Proof state:
z w : ℍ
r R : ℝ
a b c : ℍ
⊢ (dist ↑a ↑b * dist (↑c) ((starRingEnd ℂ) ↑b) + dist (↑a) ((starRingEnd ℂ) ↑b) * dist ↑b ↑c) /
      (2 * 2 * (sqrt (im a * im b) * sqrt (im b * im c))) =
    (dist ↑a ↑b * dist (↑c) ((starRingEnd ℂ) ↑b) + dist (↑a) ((starRingEnd ℂ) ↑b) * dist ↑b ↑c) /
      (2 * 2 * (sqrt (im a * im c) * im b))

Next tactic:
congr 2
theorem sinh_half_dist_add_dist (a b c : ℍ) : sinh ((dist a b + dist b c) / 2) =
    (dist (a : ℂ) b * dist (c : ℂ) (conj ↑b) + dist (b : ℂ) c * dist (a : ℂ) (conj ↑b)) /
      (2 * sqrt (a.im * c.im) * dist (b : ℂ) (conj ↑b)) := by
  simp only [add_div _ _ (2 : ℝ), sinh_add, sinh_half_dist, cosh_half_dist, div_mul_div_comm]
  rw [← add_div, Complex.dist_self_conj, coe_im, abs_of_pos b.im_pos, mul_comm (dist (b : ℂ) _),
    dist_comm (b : ℂ), Complex.dist_conj_comm, mul_mul_mul_comm, mul_mul_mul_comm _ _ _ b.im]
  congr 2
  

Proof state:
case e_a.e_a
z w : ℍ
r R : ℝ
a b c : ℍ
⊢ sqrt (im a * im b) * sqrt (im b * im c) = sqrt (im a * im c) * im b

Next tactic:
rw [sqrt_mul, sqrt_mul, sqrt_mul, mul_comm (sqrt a.im), mul_mul_mul_comm, mul_self_sqrt,
      mul_comm]