l3lab/ntp-mathlib huggingface dataset:
theorem uniformity_lift_le_swap {g : Set (α × α) → Filter β} {f : Filter β} (hg : Monotone g)
    (h : ((𝓤 α).lift fun s => g (preimage Prod.swap s)) ≤ f) : (𝓤 α).lift g ≤ f :=
  calc
    (𝓤 α).lift g ≤ (Filter.map (@Prod.swap α α) <| 𝓤 α).lift g :=
      lift_mono uniformity_le_symm le_rfl
    _ ≤ _ := by 

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
g : Set (α × α) → Filter β
f : Filter β
hg : Monotone g
h : (Filter.lift (𝓤 α) fun s => g (Prod.swap ⁻¹' s)) ≤ f
⊢ Filter.lift (map Prod.swap (𝓤 α)) g ≤ f

Next tactic:
rw [map_lift_eq2 hg, image_swap_eq_preimage_swap]
theorem uniformity_lift_le_swap {g : Set (α × α) → Filter β} {f : Filter β} (hg : Monotone g)
    (h : ((𝓤 α).lift fun s => g (preimage Prod.swap s)) ≤ f) : (𝓤 α).lift g ≤ f :=
  calc
    (𝓤 α).lift g ≤ (Filter.map (@Prod.swap α α) <| 𝓤 α).lift g :=
      lift_mono uniformity_le_symm le_rfl
    _ ≤ _ := by rw [map_lift_eq2 hg, image_swap_eq_preimage_swap]; 

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
g : Set (α × α) → Filter β
f : Filter β
hg : Monotone g
h : (Filter.lift (𝓤 α) fun s => g (Prod.swap ⁻¹' s)) ≤ f
⊢ Filter.lift (𝓤 α) (g ∘ preimage Prod.swap) ≤ f

Next tactic:
exact h
theorem uniformity_lift_le_comp {f : Set (α × α) → Filter β} (h : Monotone f) :
    ((𝓤 α).lift fun s => f (s ○ s)) ≤ (𝓤 α).lift f :=
  calc
    ((𝓤 α).lift fun s => f (s ○ s)) = ((𝓤 α).lift' fun s : Set (α × α) => s ○ s).lift f := by
      

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
f : Set (α × α) → Filter β
h : Monotone f
⊢ (Filter.lift (𝓤 α) fun s => f (s ○ s)) = Filter.lift (Filter.lift' (𝓤 α) fun s => s ○ s) f

Next tactic:
rw [lift_lift'_assoc]
theorem uniformity_lift_le_comp {f : Set (α × α) → Filter β} (h : Monotone f) :
    ((𝓤 α).lift fun s => f (s ○ s)) ≤ (𝓤 α).lift f :=
  calc
    ((𝓤 α).lift fun s => f (s ○ s)) = ((𝓤 α).lift' fun s : Set (α × α) => s ○ s).lift f := by
      rw [lift_lift'_assoc]
      

Proof state:
case hg
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
f : Set (α × α) → Filter β
h : Monotone f
⊢ Monotone fun s => s ○ s
case hh
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
f : Set (α × α) → Filter β
h : Monotone f
⊢ Monotone f

Next tactic:
exact monotone_id.compRel monotone_id
theorem uniformity_lift_le_comp {f : Set (α × α) → Filter β} (h : Monotone f) :
    ((𝓤 α).lift fun s => f (s ○ s)) ≤ (𝓤 α).lift f :=
  calc
    ((𝓤 α).lift fun s => f (s ○ s)) = ((𝓤 α).lift' fun s : Set (α × α) => s ○ s).lift f := by
      rw [lift_lift'_assoc]
      exact monotone_id.compRel monotone_id
      

Proof state:
case hh
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
f : Set (α × α) → Filter β
h : Monotone f
⊢ Monotone f

Next tactic:
exact h
/-- See also `comp_open_symm_mem_uniformity_sets`. -/
theorem comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ⊆ s := by
  

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
⊢ ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ⊆ s

Next tactic:
obtain ⟨w, w_in, w_sub⟩ : ∃ w ∈ 𝓤 α, w ○ w ⊆ s := comp_mem_uniformity_sets hs
/-- See also `comp_open_symm_mem_uniformity_sets`. -/
theorem comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ⊆ s := by
  obtain ⟨w, w_in, w_sub⟩ : ∃ w ∈ 𝓤 α, w ○ w ⊆ s := comp_mem_uniformity_sets hs
  

Proof state:
case intro.intro
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
w_sub : w ○ w ⊆ s
⊢ ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ⊆ s

Next tactic:
use symmetrizeRel w, symmetrize_mem_uniformity w_in, symmetric_symmetrizeRel w
/-- See also `comp_open_symm_mem_uniformity_sets`. -/
theorem comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ⊆ s := by
  obtain ⟨w, w_in, w_sub⟩ : ∃ w ∈ 𝓤 α, w ○ w ⊆ s := comp_mem_uniformity_sets hs
  use symmetrizeRel w, symmetrize_mem_uniformity w_in, symmetric_symmetrizeRel w
  

Proof state:
case right
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
w_sub : w ○ w ⊆ s
⊢ symmetrizeRel w ○ symmetrizeRel w ⊆ s

Next tactic:
have : symmetrizeRel w ⊆ w := symmetrizeRel_subset_self w
/-- See also `comp_open_symm_mem_uniformity_sets`. -/
theorem comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ⊆ s := by
  obtain ⟨w, w_in, w_sub⟩ : ∃ w ∈ 𝓤 α, w ○ w ⊆ s := comp_mem_uniformity_sets hs
  use symmetrizeRel w, symmetrize_mem_uniformity w_in, symmetric_symmetrizeRel w
  have : symmetrizeRel w ⊆ w := symmetrizeRel_subset_self w
  

Proof state:
case right
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
w_sub : w ○ w ⊆ s
this : symmetrizeRel w ⊆ w
⊢ symmetrizeRel w ○ symmetrizeRel w ⊆ s

Next tactic:
calc symmetrizeRel w ○ symmetrizeRel w
    _ ⊆ w ○ w := by mono
    _ ⊆ s     := w_sub
/-- See also `comp_open_symm_mem_uniformity_sets`. -/
theorem comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ⊆ s := by
  obtain ⟨w, w_in, w_sub⟩ : ∃ w ∈ 𝓤 α, w ○ w ⊆ s := comp_mem_uniformity_sets hs
  use symmetrizeRel w, symmetrize_mem_uniformity w_in, symmetric_symmetrizeRel w
  have : symmetrizeRel w ⊆ w := symmetrizeRel_subset_self w
  calc symmetrizeRel w ○ symmetrizeRel w
    _ ⊆ w ○ w := by 

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
w_sub : w ○ w ⊆ s
this : symmetrizeRel w ⊆ w
⊢ symmetrizeRel w ○ symmetrizeRel w ⊆ w ○ w

Next tactic:
mono
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
⊢ ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s

Next tactic:
rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  

Proof state:
case intro.intro.intro
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
⊢ ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s

Next tactic:
rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  

Proof state:
case intro.intro.intro.intro.intro.intro
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
⊢ ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s

Next tactic:
use t, t_in, t_symm
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  use t, t_in, t_symm
  

Proof state:
case right
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
⊢ t ○ t ○ t ⊆ s

Next tactic:
have : t ⊆ t ○ t := subset_comp_self_of_mem_uniformity t_in
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  use t, t_in, t_symm
  have : t ⊆ t ○ t := subset_comp_self_of_mem_uniformity t_in
  -- porting note: Needed the following `have`s to make `mono` work
  

Proof state:
case right
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
this : t ⊆ t ○ t
⊢ t ○ t ○ t ⊆ s

Next tactic:
have ht := Subset.refl t
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  use t, t_in, t_symm
  have : t ⊆ t ○ t := subset_comp_self_of_mem_uniformity t_in
  -- porting note: Needed the following `have`s to make `mono` work
  have ht := Subset.refl t
  

Proof state:
case right
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
this : t ⊆ t ○ t
ht : t ⊆ t
⊢ t ○ t ○ t ⊆ s

Next tactic:
have hw := Subset.refl w
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  use t, t_in, t_symm
  have : t ⊆ t ○ t := subset_comp_self_of_mem_uniformity t_in
  -- porting note: Needed the following `have`s to make `mono` work
  have ht := Subset.refl t
  have hw := Subset.refl w
  

Proof state:
case right
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
this : t ⊆ t ○ t
ht : t ⊆ t
hw : w ⊆ w
⊢ t ○ t ○ t ⊆ s

Next tactic:
calc
    t ○ t ○ t ⊆ w ○ t := by mono
    _ ⊆ w ○ (t ○ t) := by mono
    _ ⊆ w ○ w := by mono
    _ ⊆ s := w_sub
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  use t, t_in, t_symm
  have : t ⊆ t ○ t := subset_comp_self_of_mem_uniformity t_in
  -- porting note: Needed the following `have`s to make `mono` work
  have ht := Subset.refl t
  have hw := Subset.refl w
  calc
    t ○ t ○ t ⊆ w ○ t := by 

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
this : t ⊆ t ○ t
ht : t ⊆ t
hw : w ⊆ w
⊢ t ○ t ○ t ⊆ w ○ t

Next tactic:
mono
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  use t, t_in, t_symm
  have : t ⊆ t ○ t := subset_comp_self_of_mem_uniformity t_in
  -- porting note: Needed the following `have`s to make `mono` work
  have ht := Subset.refl t
  have hw := Subset.refl w
  calc
    t ○ t ○ t ⊆ w ○ t := by mono
    _ ⊆ w ○ (t ○ t) := by 

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
this : t ⊆ t ○ t
ht : t ⊆ t
hw : w ⊆ w
⊢ w ○ t ⊆ w ○ (t ○ t)

Next tactic:
mono
theorem comp_comp_symm_mem_uniformity_sets {s : Set (α × α)} (hs : s ∈ 𝓤 α) :
    ∃ t ∈ 𝓤 α, SymmetricRel t ∧ t ○ t ○ t ⊆ s := by
  rcases comp_symm_mem_uniformity_sets hs with ⟨w, w_in, _, w_sub⟩
  rcases comp_symm_mem_uniformity_sets w_in with ⟨t, t_in, t_symm, t_sub⟩
  use t, t_in, t_symm
  have : t ⊆ t ○ t := subset_comp_self_of_mem_uniformity t_in
  -- porting note: Needed the following `have`s to make `mono` work
  have ht := Subset.refl t
  have hw := Subset.refl w
  calc
    t ○ t ○ t ⊆ w ○ t := by mono
    _ ⊆ w ○ (t ○ t) := by mono
    _ ⊆ w ○ w := by 

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
s : Set (α × α)
hs : s ∈ 𝓤 α
w : Set (α × α)
w_in : w ∈ 𝓤 α
left✝ : SymmetricRel w
w_sub : w ○ w ⊆ s
t : Set (α × α)
t_in : t ∈ 𝓤 α
t_symm : SymmetricRel t
t_sub : t ○ t ⊆ w
this : t ⊆ t ○ t
ht : t ⊆ t
hw : w ⊆ w
⊢ w ○ (t ○ t) ⊆ w ○ w

Next tactic:
mono
theorem mem_ball_symmetry {V : Set (β × β)} (hV : SymmetricRel V) {x y} :
    x ∈ ball y V ↔ y ∈ ball x V :=
  show (x, y) ∈ Prod.swap ⁻¹' V ↔ (x, y) ∈ V by
    

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V : Set (β × β)
hV : SymmetricRel V
x y : β
⊢ (x, y) ∈ Prod.swap ⁻¹' V ↔ (x, y) ∈ V

Next tactic:
unfold SymmetricRel at hV
theorem mem_ball_symmetry {V : Set (β × β)} (hV : SymmetricRel V) {x y} :
    x ∈ ball y V ↔ y ∈ ball x V :=
  show (x, y) ∈ Prod.swap ⁻¹' V ↔ (x, y) ∈ V by
    unfold SymmetricRel at hV
    

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V : Set (β × β)
hV : Prod.swap ⁻¹' V = V
x y : β
⊢ (x, y) ∈ Prod.swap ⁻¹' V ↔ (x, y) ∈ V

Next tactic:
rw [hV]
theorem ball_eq_of_symmetry {V : Set (β × β)} (hV : SymmetricRel V) {x} :
    ball x V = { y | (y, x) ∈ V } := by
  

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V : Set (β × β)
hV : SymmetricRel V
x : β
⊢ ball x V = {y | (y, x) ∈ V}

Next tactic:
ext y
theorem ball_eq_of_symmetry {V : Set (β × β)} (hV : SymmetricRel V) {x} :
    ball x V = { y | (y, x) ∈ V } := by
  ext y
  

Proof state:
case h
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V : Set (β × β)
hV : SymmetricRel V
x y : β
⊢ y ∈ ball x V ↔ y ∈ {y | (y, x) ∈ V}

Next tactic:
rw [mem_ball_symmetry hV]
theorem ball_eq_of_symmetry {V : Set (β × β)} (hV : SymmetricRel V) {x} :
    ball x V = { y | (y, x) ∈ V } := by
  ext y
  rw [mem_ball_symmetry hV]
  

Proof state:
case h
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V : Set (β × β)
hV : SymmetricRel V
x y : β
⊢ x ∈ ball y V ↔ y ∈ {y | (y, x) ∈ V}

Next tactic:
exact Iff.rfl
theorem mem_comp_of_mem_ball {V W : Set (β × β)} {x y z : β} (hV : SymmetricRel V)
    (hx : x ∈ ball z V) (hy : y ∈ ball z W) : (x, y) ∈ V ○ W := by
  

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W : Set (β × β)
x y z : β
hV : SymmetricRel V
hx : x ∈ ball z V
hy : y ∈ ball z W
⊢ (x, y) ∈ V ○ W

Next tactic:
rw [mem_ball_symmetry hV] at hx
theorem mem_comp_of_mem_ball {V W : Set (β × β)} {x y z : β} (hV : SymmetricRel V)
    (hx : x ∈ ball z V) (hy : y ∈ ball z W) : (x, y) ∈ V ○ W := by
  rw [mem_ball_symmetry hV] at hx
  

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W : Set (β × β)
x y z : β
hV : SymmetricRel V
hx : z ∈ ball x V
hy : y ∈ ball z W
⊢ (x, y) ∈ V ○ W

Next tactic:
exact ⟨z, hx, hy⟩
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
p : β × β
⊢ p ∈ V ○ M ○ W ↔ Set.Nonempty (ball p.1 V ×ˢ ball p.2 W ∩ M)

Next tactic:
cases' p with x y
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  cases' p with x y
  

Proof state:
case mk
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
x y : β
⊢ (x, y) ∈ V ○ M ○ W ↔ Set.Nonempty (ball (x, y).1 V ×ˢ ball (x, y).2 W ∩ M)

Next tactic:
constructor
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  cases' p with x y
  constructor
  · 

Proof state:
case mk.mp
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
x y : β
⊢ (x, y) ∈ V ○ M ○ W → Set.Nonempty (ball (x, y).1 V ×ˢ ball (x, y).2 W ∩ M)

Next tactic:
rintro ⟨z, ⟨w, hpw, hwz⟩, hzy⟩
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  cases' p with x y
  constructor
  · rintro ⟨z, ⟨w, hpw, hwz⟩, hzy⟩
    

Proof state:
case mk.mp.intro.intro.intro.intro
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
x y z : β
hzy : (z, (x, y).2) ∈ W
w : β
hpw : (((x, y).1, z).1, w) ∈ V
hwz : (w, ((x, y).1, z).2) ∈ M
⊢ Set.Nonempty (ball (x, y).1 V ×ˢ ball (x, y).2 W ∩ M)

Next tactic:
exact ⟨(w, z), ⟨hpw, by rwa [mem_ball_symmetry hW']⟩, hwz⟩
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  cases' p with x y
  constructor
  · rintro ⟨z, ⟨w, hpw, hwz⟩, hzy⟩
    exact ⟨(w, z), ⟨hpw, by 

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
x y z : β
hzy : (z, (x, y).2) ∈ W
w : β
hpw : (((x, y).1, z).1, w) ∈ V
hwz : (w, ((x, y).1, z).2) ∈ M
⊢ (w, z).2 ∈ ball (x, y).2 W

Next tactic:
rwa [mem_ball_symmetry hW']
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  cases' p with x y
  constructor
  · rintro ⟨z, ⟨w, hpw, hwz⟩, hzy⟩
    exact ⟨(w, z), ⟨hpw, by rwa [mem_ball_symmetry hW']⟩, hwz⟩
  · 

Proof state:
case mk.mpr
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
x y : β
⊢ Set.Nonempty (ball (x, y).1 V ×ˢ ball (x, y).2 W ∩ M) → (x, y) ∈ V ○ M ○ W

Next tactic:
rintro ⟨⟨w, z⟩, ⟨w_in, z_in⟩, hwz⟩
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  cases' p with x y
  constructor
  · rintro ⟨z, ⟨w, hpw, hwz⟩, hzy⟩
    exact ⟨(w, z), ⟨hpw, by rwa [mem_ball_symmetry hW']⟩, hwz⟩
  · rintro ⟨⟨w, z⟩, ⟨w_in, z_in⟩, hwz⟩
    

Proof state:
case mk.mpr.intro.mk.intro.intro
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
x y w z : β
hwz : (w, z) ∈ M
w_in : (w, z).1 ∈ ball (x, y).1 V
z_in : (w, z).2 ∈ ball (x, y).2 W
⊢ (x, y) ∈ V ○ M ○ W

Next tactic:
rw [mem_ball_symmetry hW'] at z_in
theorem mem_comp_comp {V W M : Set (β × β)} (hW' : SymmetricRel W) {p : β × β} :
    p ∈ V ○ M ○ W ↔ (ball p.1 V ×ˢ ball p.2 W ∩ M).Nonempty := by
  cases' p with x y
  constructor
  · rintro ⟨z, ⟨w, hpw, hwz⟩, hzy⟩
    exact ⟨(w, z), ⟨hpw, by rwa [mem_ball_symmetry hW']⟩, hwz⟩
  · rintro ⟨⟨w, z⟩, ⟨w_in, z_in⟩, hwz⟩
    rw [mem_ball_symmetry hW'] at z_in
    

Proof state:
case mk.mpr.intro.mk.intro.intro
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
V W M : Set (β × β)
hW' : SymmetricRel W
x y w z : β
hwz : (w, z) ∈ M
w_in : (w, z).1 ∈ ball (x, y).1 V
z_in : (x, y).2 ∈ ball (w, z).2 W
⊢ (x, y) ∈ V ○ M ○ W

Next tactic:
exact ⟨z, ⟨w, w_in, hwz⟩, z_in⟩
theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α := by
  

Proof state:
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
x : α
s : Set α
⊢ s ∈ 𝓝 x ↔ {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α

Next tactic:
refine' ⟨_, fun hs => _⟩
theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α := by
  refine' ⟨_, fun hs => _⟩
  · 

Proof state:
case refine'_1
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
x : α
s : Set α
⊢ s ∈ 𝓝 x → {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α

Next tactic:
simp only [mem_nhds_iff, isOpen_uniformity, and_imp, exists_imp]
theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α := by
  refine' ⟨_, fun hs => _⟩
  · simp only [mem_nhds_iff, isOpen_uniformity, and_imp, exists_imp]
    

Proof state:
case refine'_1
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
x : α
s : Set α
⊢ ∀ x_1 ⊆ s, (∀ x ∈ x_1, {p | p.1 = x → p.2 ∈ x_1} ∈ 𝓤 α) → x ∈ x_1 → {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α

Next tactic:
intro t ts ht xt
theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α := by
  refine' ⟨_, fun hs => _⟩
  · simp only [mem_nhds_iff, isOpen_uniformity, and_imp, exists_imp]
    intro t ts ht xt
    

Proof state:
case refine'_1
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
x : α
s t : Set α
ts : t ⊆ s
ht : ∀ x ∈ t, {p | p.1 = x → p.2 ∈ t} ∈ 𝓤 α
xt : x ∈ t
⊢ {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α

Next tactic:
filter_upwards [ht x xt] using fun y h eq => ts (h eq)
theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α := by
  refine' ⟨_, fun hs => _⟩
  · simp only [mem_nhds_iff, isOpen_uniformity, and_imp, exists_imp]
    intro t ts ht xt
    filter_upwards [ht x xt] using fun y h eq => ts (h eq)
  · 

Proof state:
case refine'_2
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
x : α
s : Set α
hs : {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α
⊢ s ∈ 𝓝 x

Next tactic:
refine' mem_nhds_iff.mpr ⟨{ x | { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α }, _, _, hs⟩
theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α := by
  refine' ⟨_, fun hs => _⟩
  · simp only [mem_nhds_iff, isOpen_uniformity, and_imp, exists_imp]
    intro t ts ht xt
    filter_upwards [ht x xt] using fun y h eq => ts (h eq)
  · refine' mem_nhds_iff.mpr ⟨{ x | { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α }, _, _, hs⟩
    · 

Proof state:
case refine'_2.refine'_1
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
x : α
s : Set α
hs : {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α
⊢ {x | {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α} ⊆ s

Next tactic:
exact fun y hy => refl_mem_uniformity hy rfl
theorem mem_nhds_uniformity_iff_right {x : α} {s : Set α} :
    s ∈ 𝓝 x ↔ { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α := by
  refine' ⟨_, fun hs => _⟩
  · simp only [mem_nhds_iff, isOpen_uniformity, and_imp, exists_imp]
    intro t ts ht xt
    filter_upwards [ht x xt] using fun y h eq => ts (h eq)
  · refine' mem_nhds_iff.mpr ⟨{ x | { p : α × α | p.1 = x → p.2 ∈ s } ∈ 𝓤 α }, _, _, hs⟩
    · exact fun y hy => refl_mem_uniformity hy rfl
    · 

Proof state:
case refine'_2.refine'_2
α : Type ua
β : Type ub
γ : Type uc
δ : Type ud
ι : Sort u_1
inst✝ : UniformSpace α
x : α
s : Set α
hs : {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α
⊢ IsOpen {x | {p | p.1 = x → p.2 ∈ s} ∈ 𝓤 α}

Next tactic:
refine' isOpen_uniformity.mpr fun y hy => _