l3lab/ntp-mathlib huggingface dataset:
/-- Alternative `Dilation` constructor when the distance hypothesis is over `dist` -/
def mkOfDistEq {α β} [PseudoMetricSpace α] [PseudoMetricSpace β] (f : α → β)
    (h : ∃ r : ℝ≥0, r ≠ 0 ∧ ∀ x y : α, dist (f x) (f y) = r * dist x y) : α →ᵈ β :=
  mkOfNNDistEq f <|
    h.imp fun r hr =>
      ⟨hr.1, fun x y => NNReal.eq <| by 

Proof state:
α✝ : Type u_1
β✝ : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝³ : PseudoEMetricSpace α✝
inst✝² : PseudoEMetricSpace β✝
α : Type ?u.25323
β : Type ?u.25326
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
f : α → β
h : ∃ r, r ≠ 0 ∧ ∀ (x y : α), dist (f x) (f y) = ↑r * dist x y
r : ℝ≥0
hr : r ≠ 0 ∧ ∀ (x y : α), dist (f x) (f y) = ↑r * dist x y
x y : α
⊢ ↑(nndist (f x) (f y)) = ↑(r * nndist x y)

Next tactic:
rw [coe_nndist, hr.2, NNReal.coe_mul, coe_nndist]
theorem antilipschitz : AntilipschitzWith (ratio f)⁻¹ (f : α → β) := fun x y => by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x✝ y✝ z : α
s : Set α
x y : α
⊢ edist x y ≤ ↑(ratio f)⁻¹ * edist (f x) (f y)

Next tactic:
have hr : ratio f ≠ 0 := ratio_ne_zero f
theorem antilipschitz : AntilipschitzWith (ratio f)⁻¹ (f : α → β) := fun x y => by
  have hr : ratio f ≠ 0 := ratio_ne_zero f
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x✝ y✝ z : α
s : Set α
x y : α
hr : ratio f ≠ 0
⊢ edist x y ≤ ↑(ratio f)⁻¹ * edist (f x) (f y)

Next tactic:
exact mod_cast
    (ENNReal.mul_le_iff_le_inv (ENNReal.coe_ne_zero.2 hr) ENNReal.coe_ne_top).1 (edist_eq f x y).ge
/-- The identity is a dilation -/
protected def id (α) [PseudoEMetricSpace α] : α →ᵈ α where
  toFun := id
  edist_eq' := ⟨1, one_ne_zero, fun x y => by 

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁵ : PseudoEMetricSpace α✝
inst✝⁴ : PseudoEMetricSpace β
inst✝³ : PseudoEMetricSpace γ
inst✝² : DilationClass F α✝ β
inst✝¹ : DilationClass G β γ
f : F
g : G
x✝ y✝ z : α✝
s : Set α✝
α : Type ?u.28866
inst✝ : PseudoEMetricSpace α
x y : α
⊢ edist (id x) (id y) = ↑1 * edist x y

Next tactic:
simp only [id.def, ENNReal.coe_one, one_mul]
theorem ratio_id : ratio (Dilation.id α) = 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s : Set α
⊢ ratio (Dilation.id α) = 1

Next tactic:
by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
theorem ratio_id : ratio (Dilation.id α) = 1 := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s : Set α
h : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ ratio (Dilation.id α) = 1

Next tactic:
rw [ratio, if_pos h]
theorem ratio_id : ratio (Dilation.id α) = 1 := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · rw [ratio, if_pos h]
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s : Set α
h : ¬∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ ratio (Dilation.id α) = 1

Next tactic:
push_neg at h
theorem ratio_id : ratio (Dilation.id α) = 1 := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · rw [ratio, if_pos h]
  · push_neg at h
    

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s : Set α
h : ∃ x y, edist x y ≠ 0 ∧ edist x y ≠ ⊤
⊢ ratio (Dilation.id α) = 1

Next tactic:
rcases h with ⟨x, y, hne⟩
theorem ratio_id : ratio (Dilation.id α) = 1 := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · rw [ratio, if_pos h]
  · push_neg at h
    rcases h with ⟨x, y, hne⟩
    

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x✝ y✝ z : α
s : Set α
x y : α
hne : edist x y ≠ 0 ∧ edist x y ≠ ⊤
⊢ ratio (Dilation.id α) = 1

Next tactic:
refine' (ratio_unique hne.1 hne.2 _).symm
theorem ratio_id : ratio (Dilation.id α) = 1 := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · rw [ratio, if_pos h]
  · push_neg at h
    rcases h with ⟨x, y, hne⟩
    refine' (ratio_unique hne.1 hne.2 _).symm
    

Proof state:
case neg.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x✝ y✝ z : α
s : Set α
x y : α
hne : edist x y ≠ 0 ∧ edist x y ≠ ⊤
⊢ edist ((Dilation.id α) x) ((Dilation.id α) y) = ↑1 * edist x y

Next tactic:
simp
/-- The composition of dilations is a dilation -/
def comp (g : β →ᵈ γ) (f : α →ᵈ β) : α →ᵈ γ where
  toFun := g ∘ f
  edist_eq' := ⟨ratio g * ratio f, mul_ne_zero (ratio_ne_zero g) (ratio_ne_zero f),
    fun x y => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x✝ y✝ z : α
s : Set α
g : β →ᵈ γ
f : α →ᵈ β
x y : α
⊢ edist ((⇑g ∘ ⇑f) x) ((⇑g ∘ ⇑f) y) = ↑(ratio g * ratio f) * edist x y

Next tactic:
simp_rw [Function.comp, edist_eq, ENNReal.coe_mul, mul_assoc]
/-- Ratio of the composition `g.comp f` of two dilations is the product of their ratios. We assume
that there exist two points in `α` at extended distance neither `0` nor `∞` because otherwise
`Dilation.ratio (g.comp f) = Dilation.ratio f = 1` while `Dilation.ratio g` can be any number. This
version works for most general spaces, see also `Dilation.ratio_comp` for a version assuming that
`α` is a nontrivial metric space. -/
theorem ratio_comp' {g : β →ᵈ γ} {f : α →ᵈ β}
    (hne : ∃ x y : α, edist x y ≠ 0 ∧ edist x y ≠ ⊤) : ratio (g.comp f) = ratio g * ratio f := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x y z : α
s : Set α
g : β →ᵈ γ
f : α →ᵈ β
hne : ∃ x y, edist x y ≠ 0 ∧ edist x y ≠ ⊤
⊢ ratio (comp g f) = ratio g * ratio f

Next tactic:
rcases hne with ⟨x, y, hα⟩
/-- Ratio of the composition `g.comp f` of two dilations is the product of their ratios. We assume
that there exist two points in `α` at extended distance neither `0` nor `∞` because otherwise
`Dilation.ratio (g.comp f) = Dilation.ratio f = 1` while `Dilation.ratio g` can be any number. This
version works for most general spaces, see also `Dilation.ratio_comp` for a version assuming that
`α` is a nontrivial metric space. -/
theorem ratio_comp' {g : β →ᵈ γ} {f : α →ᵈ β}
    (hne : ∃ x y : α, edist x y ≠ 0 ∧ edist x y ≠ ⊤) : ratio (g.comp f) = ratio g * ratio f := by
  rcases hne with ⟨x, y, hα⟩
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x✝ y✝ z : α
s : Set α
g : β →ᵈ γ
f : α →ᵈ β
x y : α
hα : edist x y ≠ 0 ∧ edist x y ≠ ⊤
⊢ ratio (comp g f) = ratio g * ratio f

Next tactic:
have hgf := (edist_eq (g.comp f) x y).symm
/-- Ratio of the composition `g.comp f` of two dilations is the product of their ratios. We assume
that there exist two points in `α` at extended distance neither `0` nor `∞` because otherwise
`Dilation.ratio (g.comp f) = Dilation.ratio f = 1` while `Dilation.ratio g` can be any number. This
version works for most general spaces, see also `Dilation.ratio_comp` for a version assuming that
`α` is a nontrivial metric space. -/
theorem ratio_comp' {g : β →ᵈ γ} {f : α →ᵈ β}
    (hne : ∃ x y : α, edist x y ≠ 0 ∧ edist x y ≠ ⊤) : ratio (g.comp f) = ratio g * ratio f := by
  rcases hne with ⟨x, y, hα⟩
  have hgf := (edist_eq (g.comp f) x y).symm
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x✝ y✝ z : α
s : Set α
g : β →ᵈ γ
f : α →ᵈ β
x y : α
hα : edist x y ≠ 0 ∧ edist x y ≠ ⊤
hgf : ↑(ratio (comp g f)) * edist x y = edist ((comp g f) x) ((comp g f) y)
⊢ ratio (comp g f) = ratio g * ratio f

Next tactic:
simp_rw [coe_comp, Function.comp, edist_eq, ← mul_assoc, ENNReal.mul_eq_mul_right hα.1 hα.2]
    at hgf
/-- Ratio of the composition `g.comp f` of two dilations is the product of their ratios. We assume
that there exist two points in `α` at extended distance neither `0` nor `∞` because otherwise
`Dilation.ratio (g.comp f) = Dilation.ratio f = 1` while `Dilation.ratio g` can be any number. This
version works for most general spaces, see also `Dilation.ratio_comp` for a version assuming that
`α` is a nontrivial metric space. -/
theorem ratio_comp' {g : β →ᵈ γ} {f : α →ᵈ β}
    (hne : ∃ x y : α, edist x y ≠ 0 ∧ edist x y ≠ ⊤) : ratio (g.comp f) = ratio g * ratio f := by
  rcases hne with ⟨x, y, hα⟩
  have hgf := (edist_eq (g.comp f) x y).symm
  simp_rw [coe_comp, Function.comp, edist_eq, ← mul_assoc, ENNReal.mul_eq_mul_right hα.1 hα.2]
    at hgf
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x✝ y✝ z : α
s : Set α
g : β →ᵈ γ
f : α →ᵈ β
x y : α
hα : edist x y ≠ 0 ∧ edist x y ≠ ⊤
hgf : ↑(ratio (comp g f)) = ↑(ratio g) * ↑(ratio f)
⊢ ratio (comp g f) = ratio g * ratio f

Next tactic:
rwa [← ENNReal.coe_eq_coe, ENNReal.coe_mul]
@[simp]
theorem ratio_mul (f g : α →ᵈ α) : ratio (f * g) = ratio f * ratio g := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x y z : α
s : Set α
f g : α →ᵈ α
⊢ ratio (f * g) = ratio f * ratio g

Next tactic:
by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
@[simp]
theorem ratio_mul (f g : α →ᵈ α) : ratio (f * g) = ratio f * ratio g := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x y z : α
s : Set α
f g : α →ᵈ α
h : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ ratio (f * g) = ratio f * ratio g

Next tactic:
simp [ratio_of_trivial, h]
@[simp]
theorem ratio_mul (f g : α →ᵈ α) : ratio (f * g) = ratio f * ratio g := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · simp [ratio_of_trivial, h]
  

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x y z : α
s : Set α
f g : α →ᵈ α
h : ¬∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ ratio (f * g) = ratio f * ratio g

Next tactic:
push_neg at h
@[simp]
theorem ratio_mul (f g : α →ᵈ α) : ratio (f * g) = ratio f * ratio g := by
  by_cases h : ∀ x y : α, edist x y = 0 ∨ edist x y = ∞
  · simp [ratio_of_trivial, h]
  push_neg at h
  

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f✝ : F
g✝ : G
x y z : α
s : Set α
f g : α →ᵈ α
h : ∃ x y, edist x y ≠ 0 ∧ edist x y ≠ ⊤
⊢ ratio (f * g) = ratio f * ratio g

Next tactic:
exact ratio_comp' h
@[simp]
theorem cancel_left {g : β →ᵈ γ} {f₁ f₂ : α →ᵈ β} (hg : Injective g) :
    g.comp f₁ = g.comp f₂ ↔ f₁ = f₂ :=
  ⟨fun h => Dilation.ext fun x => hg <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g✝ : G
x✝ y z : α
s : Set α
g : β →ᵈ γ
f₁ f₂ : α →ᵈ β
hg : Injective ⇑g
h : comp g f₁ = comp g f₂
x : α
⊢ g (f₁ x) = g (f₂ x)

Next tactic:
rw [← comp_apply, h, comp_apply]
/-- Dilations scale the diameter by `ratio f` in pseudoemetric spaces. -/
theorem ediam_image (s : Set α) : EMetric.diam ((f : α → β) '' s) = ratio f * EMetric.diam s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s✝ s : Set α
⊢ EMetric.diam (⇑f '' s) = ↑(ratio f) * EMetric.diam s

Next tactic:
refine' ((lipschitz f).ediam_image_le s).antisymm _
/-- Dilations scale the diameter by `ratio f` in pseudoemetric spaces. -/
theorem ediam_image (s : Set α) : EMetric.diam ((f : α → β) '' s) = ratio f * EMetric.diam s := by
  refine' ((lipschitz f).ediam_image_le s).antisymm _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s✝ s : Set α
⊢ ↑(ratio f) * EMetric.diam s ≤ EMetric.diam (⇑f '' s)

Next tactic:
apply ENNReal.mul_le_of_le_div'
/-- Dilations scale the diameter by `ratio f` in pseudoemetric spaces. -/
theorem ediam_image (s : Set α) : EMetric.diam ((f : α → β) '' s) = ratio f * EMetric.diam s := by
  refine' ((lipschitz f).ediam_image_le s).antisymm _
  apply ENNReal.mul_le_of_le_div'
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s✝ s : Set α
⊢ EMetric.diam s ≤ EMetric.diam (⇑f '' s) / ↑(ratio f)

Next tactic:
rw [div_eq_mul_inv, mul_comm, ← ENNReal.coe_inv]
/-- Dilations scale the diameter by `ratio f` in pseudoemetric spaces. -/
theorem ediam_image (s : Set α) : EMetric.diam ((f : α → β) '' s) = ratio f * EMetric.diam s := by
  refine' ((lipschitz f).ediam_image_le s).antisymm _
  apply ENNReal.mul_le_of_le_div'
  rw [div_eq_mul_inv, mul_comm, ← ENNReal.coe_inv]
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s✝ s : Set α
⊢ EMetric.diam s ≤ ↑(ratio f)⁻¹ * EMetric.diam (⇑f '' s)
case h
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s✝ s : Set α
⊢ ratio f ≠ 0

Next tactic:
exacts [(antilipschitz f).le_mul_ediam_image s, ratio_ne_zero f]
/-- A dilation scales the diameter of the range by `ratio f`. -/
theorem ediam_range : EMetric.diam (range (f : α → β)) = ratio f * EMetric.diam (univ : Set α) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s : Set α
⊢ EMetric.diam (range ⇑f) = ↑(ratio f) * EMetric.diam univ

Next tactic:
rw [← image_univ]
/-- A dilation scales the diameter of the range by `ratio f`. -/
theorem ediam_range : EMetric.diam (range (f : α → β)) = ratio f * EMetric.diam (univ : Set α) := by
  rw [← image_univ]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x y z : α
s : Set α
⊢ EMetric.diam (⇑f '' univ) = ↑(ratio f) * EMetric.diam univ

Next tactic:
exact ediam_image f univ
/-- A dilation maps closed balls to closed balls and scales the radius by `ratio f`. -/
theorem mapsTo_emetric_closedBall (x : α) (r' : ℝ≥0∞) :
    MapsTo (f : α → β) (EMetric.closedBall x r') (EMetric.closedBall (f x) (ratio f * r')) :=
  -- Porting note: Added `by exact`
  fun y hy => (edist_eq f y x).trans_le <| mul_le_mul_left' (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝⁴ : PseudoEMetricSpace α
inst✝³ : PseudoEMetricSpace β
inst✝² : PseudoEMetricSpace γ
inst✝¹ : DilationClass F α β
inst✝ : DilationClass G β γ
f : F
g : G
x✝ y✝ z : α
s : Set α
x : α
r' : ℝ≥0∞
y : α
hy : y ∈ EMetric.closedBall x r'
⊢ edist y x ≤ r'

Next tactic:
exact hy
/-- A dilation scales the diameter by `ratio f` in pseudometric spaces. -/
theorem diam_image (s : Set α) : Metric.diam ((f : α → β) '' s) = ratio f * Metric.diam s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : DilationClass F α β
f : F
s : Set α
⊢ Metric.diam (⇑f '' s) = ↑(ratio f) * Metric.diam s

Next tactic:
simp [Metric.diam, ediam_image, ENNReal.toReal_mul]
theorem diam_range : Metric.diam (range (f : α → β)) = ratio f * Metric.diam (univ : Set α) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : DilationClass F α β
f : F
⊢ Metric.diam (range ⇑f) = ↑(ratio f) * Metric.diam univ

Next tactic:
rw [← image_univ, diam_image]
theorem toAffineMap_injective : Injective (toAffineMap : (P₁ ≃ᵃ[k] P₂) → P₁ →ᵃ[k] P₂) := by
  

Proof state:
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
⊢ Injective toAffineMap

Next tactic:
rintro ⟨e, el, h⟩ ⟨e', el', h'⟩ H
theorem toAffineMap_injective : Injective (toAffineMap : (P₁ ≃ᵃ[k] P₂) → P₁ →ᵃ[k] P₂) := by
  rintro ⟨e, el, h⟩ ⟨e', el', h'⟩ H
  -- porting note: added `AffineMap.mk.injEq`
  

Proof state:
case mk.mk
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), e (v +ᵥ p) = el v +ᵥ e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), e' (v +ᵥ p) = el' v +ᵥ e' p
H : ↑{ toEquiv := e, linear := el, map_vadd' := h } = ↑{ toEquiv := e', linear := el', map_vadd' := h' }
⊢ { toEquiv := e, linear := el, map_vadd' := h } = { toEquiv := e', linear := el', map_vadd' := h' }

Next tactic:
simp only [toAffineMap_mk, AffineMap.mk.injEq, Equiv.coe_inj,
    LinearEquiv.toLinearMap_inj] at H
theorem toAffineMap_injective : Injective (toAffineMap : (P₁ ≃ᵃ[k] P₂) → P₁ →ᵃ[k] P₂) := by
  rintro ⟨e, el, h⟩ ⟨e', el', h'⟩ H
  -- porting note: added `AffineMap.mk.injEq`
  simp only [toAffineMap_mk, AffineMap.mk.injEq, Equiv.coe_inj,
    LinearEquiv.toLinearMap_inj] at H
  

Proof state:
case mk.mk
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), e (v +ᵥ p) = el v +ᵥ e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), e' (v +ᵥ p) = el' v +ᵥ e' p
H : e = e' ∧ el = el'
⊢ { toEquiv := e, linear := el, map_vadd' := h } = { toEquiv := e', linear := el', map_vadd' := h' }

Next tactic:
congr
theorem toAffineMap_injective : Injective (toAffineMap : (P₁ ≃ᵃ[k] P₂) → P₁ →ᵃ[k] P₂) := by
  rintro ⟨e, el, h⟩ ⟨e', el', h'⟩ H
  -- porting note: added `AffineMap.mk.injEq`
  simp only [toAffineMap_mk, AffineMap.mk.injEq, Equiv.coe_inj,
    LinearEquiv.toLinearMap_inj] at H
  congr
  

Proof state:
case mk.mk.e_toEquiv
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), e (v +ᵥ p) = el v +ᵥ e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), e' (v +ᵥ p) = el' v +ᵥ e' p
H : e = e' ∧ el = el'
⊢ e = e'
case mk.mk.e_linear
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), e (v +ᵥ p) = el v +ᵥ e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), e' (v +ᵥ p) = el' v +ᵥ e' p
H : e = e' ∧ el = el'
⊢ el = el'

Next tactic:
exacts [H.1, H.2]
/-- Construct an affine equivalence by verifying the relation between the map and its linear part at
one base point. Namely, this function takes a map `e : P₁ → P₂`, a linear equivalence
`e' : V₁ ≃ₗ[k] V₂`, and a point `p` such that for any other point `p'` we have
`e p' = e' (p' -ᵥ p) +ᵥ e p`. -/
def mk' (e : P₁ → P₂) (e' : V₁ ≃ₗ[k] V₂) (p : P₁) (h : ∀ p' : P₁, e p' = e' (p' -ᵥ p) +ᵥ e p) :
    P₁ ≃ᵃ[k] P₂ where
  toFun := e
  invFun := fun q' : P₂ => e'.symm (q' -ᵥ e p) +ᵥ p
  left_inv p' := by 

Proof state:
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ → P₂
e' : V₁ ≃ₗ[k] V₂
p : P₁
h : ∀ (p' : P₁), e p' = e' (p' -ᵥ p) +ᵥ e p
p' : P₁
⊢ (fun q' => (LinearEquiv.symm e') (q' -ᵥ e p) +ᵥ p) (e p') = p'

Next tactic:
simp [h p', vadd_vsub, vsub_vadd]