l3lab/ntp-mathlib huggingface dataset:
/-- The inverse of a block-triangular matrix is block-triangular. -/
theorem blockTriangular_inv_of_blockTriangular [LinearOrder α] [Invertible M]
    (hM : BlockTriangular M b) : BlockTriangular M⁻¹ b := by
  clear N
  induction' hs : univ.image b using Finset.strongInduction with s ih generalizing m
  subst hs
  intro i j hij
  haveI : Inhabited m := ⟨i⟩
  let k := (univ.image b).max' (univ_nonempty.image _)
  let b' := fun i : { a // b a < k } => b ↑i
  let A := M.toBlock (fun i => b i < k) fun j => b j < k
  obtain hbi | hi : b i = k ∨ _ := (le_max' _ (b i) <| mem_image_of_mem _ <| mem_univ _).eq_or_lt
  · have : M⁻¹.toBlock (fun i => k ≤ b i) (fun i => b i < k) ⟨i, hbi.ge⟩ ⟨j, hbi ▸ hij⟩ = 0 := by
      simp only [toBlock_inverse_eq_zero hM k, Matrix.zero_apply]
    simp [this.symm]
  haveI : Invertible A := hM.invertibleToBlock _
  have hA : A.BlockTriangular b' := hM.submatrix
  have hb' : image b' univ ⊂ image b univ := by
    convert image_subtype_univ_ssubset_image_univ k b _ (fun a => a < k) (lt_irrefl _)
    convert max'_mem (α := α) _ _
  have hij' : b' ⟨j, hij.trans hi⟩ < b' ⟨i, hi⟩ := by 

Proof state:
α : Type u_1
β : Type u_2
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁶ : CommRing R
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : LinearOrder α
m : Type u_3
M : Matrix m m R
b : m → α
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : Invertible M
hM : BlockTriangular M b
ih :
  ∀ t ⊂ image b univ,
    ∀ {m : Type u_3} {M : Matrix m m R} {b : m → α} [inst : DecidableEq m] [inst_1 : Fintype m] [inst_2 : Invertible M],
      BlockTriangular M b → image b univ = t → BlockTriangular M⁻¹ b
i j : m
hij : b j < b i
this✝ : Inhabited m
k : α := max' (image b univ) (_ : Finset.Nonempty (image b univ))
b' : { a // b a < k } → α := fun i => b ↑i
A : Matrix { a // b a < k } { a // b a < k } R := toBlock M (fun i => b i < k) fun j => b j < k
hi : b i < max' (image b univ) (_ : ∃ x, x ∈ image b univ)
this : Invertible A
hA : BlockTriangular A b'
hb' : image b' univ ⊂ image b univ
⊢ b' { val := j, property := (_ : b j < k) } < b' { val := i, property := hi }

Next tactic:
simp_rw [hij]
/-- The inverse of a block-triangular matrix is block-triangular. -/
theorem blockTriangular_inv_of_blockTriangular [LinearOrder α] [Invertible M]
    (hM : BlockTriangular M b) : BlockTriangular M⁻¹ b := by
  clear N
  induction' hs : univ.image b using Finset.strongInduction with s ih generalizing m
  subst hs
  intro i j hij
  haveI : Inhabited m := ⟨i⟩
  let k := (univ.image b).max' (univ_nonempty.image _)
  let b' := fun i : { a // b a < k } => b ↑i
  let A := M.toBlock (fun i => b i < k) fun j => b j < k
  obtain hbi | hi : b i = k ∨ _ := (le_max' _ (b i) <| mem_image_of_mem _ <| mem_univ _).eq_or_lt
  · have : M⁻¹.toBlock (fun i => k ≤ b i) (fun i => b i < k) ⟨i, hbi.ge⟩ ⟨j, hbi ▸ hij⟩ = 0 := by
      simp only [toBlock_inverse_eq_zero hM k, Matrix.zero_apply]
    simp [this.symm]
  haveI : Invertible A := hM.invertibleToBlock _
  have hA : A.BlockTriangular b' := hM.submatrix
  have hb' : image b' univ ⊂ image b univ := by
    convert image_subtype_univ_ssubset_image_univ k b _ (fun a => a < k) (lt_irrefl _)
    convert max'_mem (α := α) _ _
  have hij' : b' ⟨j, hij.trans hi⟩ < b' ⟨i, hi⟩ := by simp_rw [hij]
  

Proof state:
case H.inr
α : Type u_1
β : Type u_2
n : Type u_4
o : Type u_5
m' : α → Type u_6
n' : α → Type u_7
R : Type v
inst✝⁶ : CommRing R
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : LinearOrder α
m : Type u_3
M : Matrix m m R
b : m → α
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : Invertible M
hM : BlockTriangular M b
ih :
  ∀ t ⊂ image b univ,
    ∀ {m : Type u_3} {M : Matrix m m R} {b : m → α} [inst : DecidableEq m] [inst_1 : Fintype m] [inst_2 : Invertible M],
      BlockTriangular M b → image b univ = t → BlockTriangular M⁻¹ b
i j : m
hij : b j < b i
this✝ : Inhabited m
k : α := max' (image b univ) (_ : Finset.Nonempty (image b univ))
b' : { a // b a < k } → α := fun i => b ↑i
A : Matrix { a // b a < k } { a // b a < k } R := toBlock M (fun i => b i < k) fun j => b j < k
hi : b i < max' (image b univ) (_ : ∃ x, x ∈ image b univ)
this : Invertible A
hA : BlockTriangular A b'
hb' : image b' univ ⊂ image b univ
hij' : b' { val := j, property := (_ : b j < k) } < b' { val := i, property := hi }
⊢ M⁻¹ i j = 0

Next tactic:
simp [hM.inv_toBlock k, (ih (image b' univ) hb' hA rfl hij').symm]
theorem IsMinOn.comp_mapsTo {t : Set δ} {g : δ → α} {b : δ} (hf : IsMinOn f s a) (hg : MapsTo g t s)
    (ha : g b = a) : IsMinOn (f ∘ g) t b := fun y hy => by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝¹ : Preorder β
inst✝ : Preorder γ
f : α → β
s : Set α
l : Filter α
a : α
t✝ : Set α
l' : Filter α
t : Set δ
g : δ → α
b : δ
hf : IsMinOn f s a
hg : MapsTo g t s
ha : g b = a
y : δ
hy : y ∈ t
⊢ y ∈ {x | (fun x => (f ∘ g) b ≤ (f ∘ g) x) x}

Next tactic:
simpa only [ha, (· ∘ ·)] using hf (hg hy)
theorem IsMinFilter.sub (hf : IsMinFilter f l a) (hg : IsMaxFilter g l a) :
    IsMinFilter (fun x => f x - g x) l a := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝ : OrderedAddCommGroup β
f g : α → β
a : α
s : Set α
l : Filter α
hf : IsMinFilter f l a
hg : IsMaxFilter g l a
⊢ IsMinFilter (fun x => f x - g x) l a

Next tactic:
simpa only [sub_eq_add_neg] using hf.add hg.neg
theorem IsMaxFilter.sub (hf : IsMaxFilter f l a) (hg : IsMinFilter g l a) :
    IsMaxFilter (fun x => f x - g x) l a := by 

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝ : OrderedAddCommGroup β
f g : α → β
a : α
s : Set α
l : Filter α
hf : IsMaxFilter f l a
hg : IsMinFilter g l a
⊢ IsMaxFilter (fun x => f x - g x) l a

Next tactic:
simpa only [sub_eq_add_neg] using hf.add hg.neg
theorem IsMinOn.sub (hf : IsMinOn f s a) (hg : IsMaxOn g s a) :
    IsMinOn (fun x => f x - g x) s a := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝ : OrderedAddCommGroup β
f g : α → β
a : α
s : Set α
l : Filter α
hf : IsMinOn f s a
hg : IsMaxOn g s a
⊢ IsMinOn (fun x => f x - g x) s a

Next tactic:
simpa only [sub_eq_add_neg] using hf.add hg.neg
theorem IsMaxOn.sub (hf : IsMaxOn f s a) (hg : IsMinOn g s a) :
    IsMaxOn (fun x => f x - g x) s a := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
δ : Type x
inst✝ : OrderedAddCommGroup β
f g : α → β
a : α
s : Set α
l : Filter α
hf : IsMaxOn f s a
hg : IsMinOn g s a
⊢ IsMaxOn (fun x => f x - g x) s a

Next tactic:
simpa only [sub_eq_add_neg] using hf.add hg.neg
theorem Filter.EventuallyLE.isMaxFilter {α β : Type*} [Preorder β] {f g : α → β} {a : α}
    {l : Filter α} (hle : g ≤ᶠ[l] f) (hfga : f a = g a) (h : IsMaxFilter f l a) :
    IsMaxFilter g l a := by
  

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
α : Type u_1
β : Type u_2
inst✝ : Preorder β
f g : α → β
a : α
l : Filter α
hle : g ≤ᶠ[l] f
hfga : f a = g a
h : IsMaxFilter f l a
⊢ IsMaxFilter g l a

Next tactic:
refine' hle.mp (h.mono fun x hf hgf => _)
theorem Filter.EventuallyLE.isMaxFilter {α β : Type*} [Preorder β] {f g : α → β} {a : α}
    {l : Filter α} (hle : g ≤ᶠ[l] f) (hfga : f a = g a) (h : IsMaxFilter f l a) :
    IsMaxFilter g l a := by
  refine' hle.mp (h.mono fun x hf hgf => _)
  

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
α : Type u_1
β : Type u_2
inst✝ : Preorder β
f g : α → β
a : α
l : Filter α
hle : g ≤ᶠ[l] f
hfga : f a = g a
h : IsMaxFilter f l a
x : α
hf : f x ≤ f a
hgf : g x ≤ f x
⊢ g x ≤ g a

Next tactic:
rw [← hfga]
theorem Filter.EventuallyLE.isMaxFilter {α β : Type*} [Preorder β] {f g : α → β} {a : α}
    {l : Filter α} (hle : g ≤ᶠ[l] f) (hfga : f a = g a) (h : IsMaxFilter f l a) :
    IsMaxFilter g l a := by
  refine' hle.mp (h.mono fun x hf hgf => _)
  rw [← hfga]
  

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
α : Type u_1
β : Type u_2
inst✝ : Preorder β
f g : α → β
a : α
l : Filter α
hle : g ≤ᶠ[l] f
hfga : f a = g a
h : IsMaxFilter f l a
x : α
hf : f x ≤ f a
hgf : g x ≤ f x
⊢ g x ≤ f a

Next tactic:
exact le_trans hgf hf
theorem IsExtrFilter.congr {α β : Type*} [Preorder β] {f g : α → β} {a : α} {l : Filter α}
    (h : IsExtrFilter f l a) (heq : f =ᶠ[l] g) (hfga : f a = g a) : IsExtrFilter g l a := by
  

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
α : Type u_1
β : Type u_2
inst✝ : Preorder β
f g : α → β
a : α
l : Filter α
h : IsExtrFilter f l a
heq : f =ᶠ[l] g
hfga : f a = g a
⊢ IsExtrFilter g l a

Next tactic:
rw [IsExtrFilter] at *
theorem IsExtrFilter.congr {α β : Type*} [Preorder β] {f g : α → β} {a : α} {l : Filter α}
    (h : IsExtrFilter f l a) (heq : f =ᶠ[l] g) (hfga : f a = g a) : IsExtrFilter g l a := by
  rw [IsExtrFilter] at *
  

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
δ : Type x
α : Type u_1
β : Type u_2
inst✝ : Preorder β
f g : α → β
a : α
l : Filter α
h : IsMinFilter f l a ∨ IsMaxFilter f l a
heq : f =ᶠ[l] g
hfga : f a = g a
⊢ IsMinFilter g l a ∨ IsMaxFilter g l a

Next tactic:
rwa [← heq.isMaxFilter_iff hfga, ← heq.isMinFilter_iff hfga]
instance toDilationClass : DilationClass (α →ᵈ β) α β where
  coe := toFun
  coe_injective' f g h := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
f g : α →ᵈ β
h : f.toFun = g.toFun
⊢ f = g

Next tactic:
cases f
instance toDilationClass : DilationClass (α →ᵈ β) α β where
  coe := toFun
  coe_injective' f g h := by cases f; 

Proof state:
case mk
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
g : α →ᵈ β
toFun✝ : α → β
edist_eq'✝ : ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (toFun✝ x) (toFun✝ y) = ↑r * edist x y
h : { toFun := toFun✝, edist_eq' := edist_eq'✝ }.toFun = g.toFun
⊢ { toFun := toFun✝, edist_eq' := edist_eq'✝ } = g

Next tactic:
cases g
instance toDilationClass : DilationClass (α →ᵈ β) α β where
  coe := toFun
  coe_injective' f g h := by cases f; cases g; 

Proof state:
case mk.mk
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
toFun✝¹ : α → β
edist_eq'✝¹ : ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (toFun✝¹ x) (toFun✝¹ y) = ↑r * edist x y
toFun✝ : α → β
edist_eq'✝ : ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (toFun✝ x) (toFun✝ y) = ↑r * edist x y
h : { toFun := toFun✝¹, edist_eq' := edist_eq'✝¹ }.toFun = { toFun := toFun✝, edist_eq' := edist_eq'✝ }.toFun
⊢ { toFun := toFun✝¹, edist_eq' := edist_eq'✝¹ } = { toFun := toFun✝, edist_eq' := edist_eq'✝ }

Next tactic:
congr
@[nontriviality]
theorem ratio_of_subsingleton [Subsingleton α] [DilationClass F α β] (f : F) : ratio f = 1 :=
  if_pos <| 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✝¹ : Subsingleton α
inst✝ : DilationClass F α β
f : F
x y : α
⊢ edist x y = 0 ∨ edist x y = ⊤

Next tactic:
simp [Subsingleton.elim x y]
theorem ratio_ne_zero [DilationClass F α β] (f : F) : ratio f ≠ 0 := 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✝ : DilationClass F α β
f : F
⊢ ratio f ≠ 0

Next tactic:
rw [ratio]
theorem ratio_ne_zero [DilationClass F α β] (f : F) : ratio f ≠ 0 := by
  rw [ratio]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoEMetricSpace α
inst✝¹ : PseudoEMetricSpace β
inst✝ : DilationClass F α β
f : F
⊢ (if ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤ then 1
    else Exists.choose (_ : ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (f x) (f y) = ↑r * edist x y)) ≠
    0

Next tactic:
split_ifs
theorem ratio_ne_zero [DilationClass F α β] (f : F) : ratio f ≠ 0 := by
  rw [ratio]; split_ifs
  · 

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✝ : DilationClass F α β
f : F
h✝ : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ 1 ≠ 0

Next tactic:
exact one_ne_zero
theorem ratio_ne_zero [DilationClass F α β] (f : F) : ratio f ≠ 0 := by
  rw [ratio]; split_ifs
  · exact one_ne_zero
  

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✝ : DilationClass F α β
f : F
h✝ : ¬∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ Exists.choose (_ : ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (f x) (f y) = ↑r * edist x y) ≠ 0

Next tactic:
exact (DilationClass.edist_eq' f).choose_spec.1
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist 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✝ : DilationClass F α β
f : F
x y : α
⊢ edist (f x) (f y) = ↑(ratio f) * edist x y

Next tactic:
rw [ratio]
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist x y := by
  rw [ratio]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoEMetricSpace α
inst✝¹ : PseudoEMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
⊢ edist (f x) (f y) =
    ↑(if ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤ then 1
        else Exists.choose (_ : ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (f x) (f y) = ↑r * edist x y)) *
      edist x y

Next tactic:
split_ifs with key
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist x y := by
  rw [ratio]; split_ifs with key
  · 

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✝ : DilationClass F α β
f : F
x y : α
key : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ edist (f x) (f y) = ↑1 * edist x y

Next tactic:
rcases DilationClass.edist_eq' f with ⟨r, hne, hr⟩
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist x y := by
  rw [ratio]; split_ifs with key
  · rcases DilationClass.edist_eq' f with ⟨r, hne, hr⟩
    

Proof state:
case pos.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoEMetricSpace α
inst✝¹ : PseudoEMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
key : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
r : ℝ≥0
hne : r ≠ 0
hr : ∀ (x y : α), edist (f x) (f y) = ↑r * edist x y
⊢ edist (f x) (f y) = ↑1 * edist x y

Next tactic:
replace hr := hr x y
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist x y := by
  rw [ratio]; split_ifs with key
  · rcases DilationClass.edist_eq' f with ⟨r, hne, hr⟩
    replace hr := hr x y
    

Proof state:
case pos.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoEMetricSpace α
inst✝¹ : PseudoEMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
key : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
r : ℝ≥0
hne : r ≠ 0
hr : edist (f x) (f y) = ↑r * edist x y
⊢ edist (f x) (f y) = ↑1 * edist x y

Next tactic:
cases' key x y with h h
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist x y := by
  rw [ratio]; split_ifs with key
  · rcases DilationClass.edist_eq' f with ⟨r, hne, hr⟩
    replace hr := hr x y
    cases' key x y with h h
    · 

Proof state:
case pos.intro.intro.inl
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoEMetricSpace α
inst✝¹ : PseudoEMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
key : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
r : ℝ≥0
hne : r ≠ 0
hr : edist (f x) (f y) = ↑r * edist x y
h : edist x y = 0
⊢ edist (f x) (f y) = ↑1 * edist x y

Next tactic:
simp only [hr, h, mul_zero]
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist x y := by
  rw [ratio]; split_ifs with key
  · rcases DilationClass.edist_eq' f with ⟨r, hne, hr⟩
    replace hr := hr x y
    cases' key x y with h h
    · simp only [hr, h, mul_zero]
    · 

Proof state:
case pos.intro.intro.inr
α : Type u_1
β : Type u_2
γ : Type u_3
F : Type u_4
G : Type u_5
inst✝² : PseudoEMetricSpace α
inst✝¹ : PseudoEMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
key : ∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
r : ℝ≥0
hne : r ≠ 0
hr : edist (f x) (f y) = ↑r * edist x y
h : edist x y = ⊤
⊢ edist (f x) (f y) = ↑1 * edist x y

Next tactic:
simp [hr, h, hne]
@[simp]
theorem edist_eq [DilationClass F α β] (f : F) (x y : α) :
    edist (f x) (f y) = ratio f * edist x y := by
  rw [ratio]; split_ifs with key
  · rcases DilationClass.edist_eq' f with ⟨r, hne, hr⟩
    replace hr := hr x y
    cases' key x y with h h
    · simp only [hr, h, mul_zero]
    · simp [hr, h, hne]
  

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✝ : DilationClass F α β
f : F
x y : α
key : ¬∀ (x y : α), edist x y = 0 ∨ edist x y = ⊤
⊢ edist (f x) (f y) = ↑(Exists.choose (_ : ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (f x) (f y) = ↑r * edist x y)) * edist x y

Next tactic:
exact (DilationClass.edist_eq' f).choose_spec.2 x y
@[simp]
theorem nndist_eq {α β F : Type*} [PseudoMetricSpace α] [PseudoMetricSpace β] [DilationClass F α β]
    (f : F) (x y : α) : nndist (f x) (f y) = ratio f * nndist 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 β✝
α : Type u_6
β : Type u_7
F : Type u_8
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
⊢ nndist (f x) (f y) = ratio f * nndist x y

Next tactic:
simp only [← ENNReal.coe_eq_coe, ← edist_nndist, ENNReal.coe_mul, edist_eq]
@[simp]
theorem dist_eq {α β F : Type*} [PseudoMetricSpace α] [PseudoMetricSpace β] [DilationClass F α β]
    (f : F) (x y : α) : dist (f x) (f y) = ratio f * dist 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 β✝
α : Type u_6
β : Type u_7
F : Type u_8
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
⊢ dist (f x) (f y) = ↑(ratio f) * dist x y

Next tactic:
simp only [dist_nndist, nndist_eq, NNReal.coe_mul]
/-- The `ratio` is equal to the distance ratio for any two points with nonzero finite distance.
`dist` and `nndist` versions below -/
theorem ratio_unique [DilationClass F α β] {f : F} {x y : α} {r : ℝ≥0} (h₀ : edist x y ≠ 0)
    (htop : edist x y ≠ ⊤) (hr : edist (f x) (f y) = r * edist x y) : r = 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✝ : DilationClass F α β
f : F
x y : α
r : ℝ≥0
h₀ : edist x y ≠ 0
htop : edist x y ≠ ⊤
hr : edist (f x) (f y) = ↑r * edist x y
⊢ r = ratio f

Next tactic:
simpa only [hr, ENNReal.mul_eq_mul_right h₀ htop, ENNReal.coe_eq_coe] using edist_eq f x y
/-- The `ratio` is equal to the distance ratio for any two points
with nonzero finite distance; `nndist` version -/
theorem ratio_unique_of_nndist_ne_zero {α β F : Type*} [PseudoMetricSpace α] [PseudoMetricSpace β]
    [DilationClass F α β] {f : F} {x y : α} {r : ℝ≥0} (hxy : nndist x y ≠ 0)
    (hr : nndist (f x) (f y) = r * nndist x y) : r = ratio f :=
  ratio_unique (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_6
β : Type u_7
F : Type u_8
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
r : ℝ≥0
hxy : nndist x y ≠ 0
hr : nndist (f x) (f y) = r * nndist x y
⊢ edist x y ≠ 0

Next tactic:
rwa [edist_nndist, ENNReal.coe_ne_zero]
/-- The `ratio` is equal to the distance ratio for any two points
with nonzero finite distance; `nndist` version -/
theorem ratio_unique_of_nndist_ne_zero {α β F : Type*} [PseudoMetricSpace α] [PseudoMetricSpace β]
    [DilationClass F α β] {f : F} {x y : α} {r : ℝ≥0} (hxy : nndist x y ≠ 0)
    (hr : nndist (f x) (f y) = r * nndist x y) : r = ratio f :=
  ratio_unique (by rwa [edist_nndist, ENNReal.coe_ne_zero]) (edist_ne_top 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 β✝
α : Type u_6
β : Type u_7
F : Type u_8
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
r : ℝ≥0
hxy : nndist x y ≠ 0
hr : nndist (f x) (f y) = r * nndist x y
⊢ edist (f x) (f y) = ↑r * edist x y

Next tactic:
rw [edist_nndist, edist_nndist, hr, ENNReal.coe_mul]
/-- The `ratio` is equal to the distance ratio for any two points
with nonzero finite distance; `dist` version -/
theorem ratio_unique_of_dist_ne_zero {α β} {F : Type*} [PseudoMetricSpace α] [PseudoMetricSpace β]
    [DilationClass F α β] {f : F} {x y : α} {r : ℝ≥0} (hxy : dist x y ≠ 0)
    (hr : dist (f x) (f y) = r * dist x y) : r = ratio f :=
  ratio_unique_of_nndist_ne_zero (NNReal.coe_ne_zero.1 hxy) <|
    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_7
β : Type u_8
F : Type u_6
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : DilationClass F α β
f : F
x y : α
r : ℝ≥0
hxy : dist x y ≠ 0
hr : dist (f x) (f y) = ↑r * dist x y
⊢ ↑(nndist (f x) (f y)) = ↑(r * nndist x y)

Next tactic:
rw [coe_nndist, hr, NNReal.coe_mul, coe_nndist]
/-- Alternative `Dilation` constructor when the distance hypothesis is over `nndist` -/
def mkOfNNDistEq {α β} [PseudoMetricSpace α] [PseudoMetricSpace β] (f : α → β)
    (h : ∃ r : ℝ≥0, r ≠ 0 ∧ ∀ x y : α, nndist (f x) (f y) = r * nndist x y) : α →ᵈ β where
  toFun := f
  edist_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.24314
β : Type ?u.24317
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
f : α → β
h : ∃ r, r ≠ 0 ∧ ∀ (x y : α), nndist (f x) (f y) = r * nndist x y
⊢ ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (f x) (f y) = ↑r * edist x y

Next tactic:
rcases h with ⟨r, hne, h⟩
/-- Alternative `Dilation` constructor when the distance hypothesis is over `nndist` -/
def mkOfNNDistEq {α β} [PseudoMetricSpace α] [PseudoMetricSpace β] (f : α → β)
    (h : ∃ r : ℝ≥0, r ≠ 0 ∧ ∀ x y : α, nndist (f x) (f y) = r * nndist x y) : α →ᵈ β where
  toFun := f
  edist_eq' := by
    rcases h with ⟨r, hne, 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 β✝
α : Type ?u.24314
β : Type ?u.24317
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
f : α → β
r : ℝ≥0
hne : r ≠ 0
h : ∀ (x y : α), nndist (f x) (f y) = r * nndist x y
⊢ ∃ r, r ≠ 0 ∧ ∀ (x y : α), edist (f x) (f y) = ↑r * edist x y

Next tactic:
refine' ⟨r, hne, fun x y => _⟩
/-- Alternative `Dilation` constructor when the distance hypothesis is over `nndist` -/
def mkOfNNDistEq {α β} [PseudoMetricSpace α] [PseudoMetricSpace β] (f : α → β)
    (h : ∃ r : ℝ≥0, r ≠ 0 ∧ ∀ x y : α, nndist (f x) (f y) = r * nndist x y) : α →ᵈ β where
  toFun := f
  edist_eq' := by
    rcases h with ⟨r, hne, h⟩
    refine' ⟨r, hne, fun x y => _⟩
    

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 β✝
α : Type ?u.24314
β : Type ?u.24317
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
f : α → β
r : ℝ≥0
hne : r ≠ 0
h : ∀ (x y : α), nndist (f x) (f y) = r * nndist x y
x y : α
⊢ edist (f x) (f y) = ↑r * edist x y

Next tactic:
rw [edist_nndist, edist_nndist, ← ENNReal.coe_mul, h x y]