l3lab/ntp-mathlib huggingface dataset:
theorem posDef_pi_iff [Fintype ι] {R} [OrderedCommRing R] [∀ i, Module R (Mᵢ i)]
    {Q : ∀ i, QuadraticForm R (Mᵢ i)} : (pi Q).PosDef ↔ ∀ i, (Q i).PosDef := by
  simp_rw [posDef_iff_nonneg, nonneg_pi_iff]
  constructor
  · rintro ⟨hle, ha⟩
    intro i
    exact ⟨hle i, anisotropic_of_pi ha i⟩
  · intro h
    refine' ⟨fun i => (h i).1, fun x hx => funext fun i => (h i).2 _ _⟩
    rw [pi_apply, Finset.sum_eq_zero_iff_of_nonneg fun j _ => ?_] at hx
    · 

Proof state:
case mpr
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁷ : CommSemiring R✝
inst✝⁶ : (i : ι) → AddCommMonoid (Mᵢ i)
inst✝⁵ : (i : ι) → AddCommMonoid (Nᵢ i)
inst✝⁴ : (i : ι) → Module R✝ (Mᵢ i)
inst✝³ : (i : ι) → Module R✝ (Nᵢ i)
inst✝² : Fintype ι
R : Type u_9
inst✝¹ : OrderedCommRing R
inst✝ : (i : ι) → Module R (Mᵢ i)
Q : (i : ι) → QuadraticForm R (Mᵢ i)
h : ∀ (i : ι), (∀ (x : Mᵢ i), 0 ≤ (Q i) x) ∧ Anisotropic (Q i)
x : (i : ι) → Mᵢ i
hx : ∀ i ∈ Finset.univ, (Q i) (x i) = 0
i : ι
⊢ (Q i) (x i) = 0

Next tactic:
exact hx _ (Finset.mem_univ _)
theorem posDef_pi_iff [Fintype ι] {R} [OrderedCommRing R] [∀ i, Module R (Mᵢ i)]
    {Q : ∀ i, QuadraticForm R (Mᵢ i)} : (pi Q).PosDef ↔ ∀ i, (Q i).PosDef := by
  simp_rw [posDef_iff_nonneg, nonneg_pi_iff]
  constructor
  · rintro ⟨hle, ha⟩
    intro i
    exact ⟨hle i, anisotropic_of_pi ha i⟩
  · intro h
    refine' ⟨fun i => (h i).1, fun x hx => funext fun i => (h i).2 _ _⟩
    rw [pi_apply, Finset.sum_eq_zero_iff_of_nonneg fun j _ => ?_] at hx
    · exact hx _ (Finset.mem_univ _)
    

Proof state:
ι : Type u_1
R✝ : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁷ : CommSemiring R✝
inst✝⁶ : (i : ι) → AddCommMonoid (Mᵢ i)
inst✝⁵ : (i : ι) → AddCommMonoid (Nᵢ i)
inst✝⁴ : (i : ι) → Module R✝ (Mᵢ i)
inst✝³ : (i : ι) → Module R✝ (Nᵢ i)
inst✝² : Fintype ι
R : Type u_9
inst✝¹ : OrderedCommRing R
inst✝ : (i : ι) → Module R (Mᵢ i)
Q : (i : ι) → QuadraticForm R (Mᵢ i)
h : ∀ (i : ι), (∀ (x : Mᵢ i), 0 ≤ (Q i) x) ∧ Anisotropic (Q i)
x : (i : ι) → Mᵢ i
hx : ∑ i : ι, (Q i) (x i) = 0
i j : ι
x✝ : j ∈ Finset.univ
⊢ 0 ≤ (Q j) (x j)

Next tactic:
exact (h j).1 _
@[simp] theorem polar_pi (Q : ∀ i, QuadraticForm R (Mᵢ i)) (x y : ∀ i, Mᵢ i) :
    polar (pi Q) x y = ∑ i, polar (Q i) (x i) (y i) := by
  

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁵ : CommRing R
inst✝⁴ : (i : ι) → AddCommGroup (Mᵢ i)
inst✝³ : (i : ι) → AddCommGroup (Nᵢ i)
inst✝² : (i : ι) → Module R (Mᵢ i)
inst✝¹ : (i : ι) → Module R (Nᵢ i)
inst✝ : Fintype ι
Q : (i : ι) → QuadraticForm R (Mᵢ i)
x y : (i : ι) → Mᵢ i
⊢ polar (⇑(pi Q)) x y = ∑ i : ι, polar (⇑(Q i)) (x i) (y i)

Next tactic:
dsimp [polar]
@[simp] theorem polar_pi (Q : ∀ i, QuadraticForm R (Mᵢ i)) (x y : ∀ i, Mᵢ i) :
    polar (pi Q) x y = ∑ i, polar (Q i) (x i) (y i) := by
  dsimp [polar]
  

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁵ : CommRing R
inst✝⁴ : (i : ι) → AddCommGroup (Mᵢ i)
inst✝³ : (i : ι) → AddCommGroup (Nᵢ i)
inst✝² : (i : ι) → Module R (Mᵢ i)
inst✝¹ : (i : ι) → Module R (Nᵢ i)
inst✝ : Fintype ι
Q : (i : ι) → QuadraticForm R (Mᵢ i)
x y : (i : ι) → Mᵢ i
⊢ (pi Q) (x + y) - (pi Q) x - (pi Q) y = ∑ i : ι, ((Q i) (x i + y i) - (Q i) (x i) - (Q i) (y i))

Next tactic:
simp_rw [Finset.sum_sub_distrib, pi_apply, Pi.add_apply]
@[simp] theorem polarBilin_pi (Q : ∀ i, QuadraticForm R (Mᵢ i)) :
    (pi Q).polarBilin = ∑ i, (Q i).polarBilin.comp (.proj i) (.proj i) :=
  BilinForm.ext <| fun x y => (polar_pi _ _ _).trans <| by 

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁵ : CommRing R
inst✝⁴ : (i : ι) → AddCommGroup (Mᵢ i)
inst✝³ : (i : ι) → AddCommGroup (Nᵢ i)
inst✝² : (i : ι) → Module R (Mᵢ i)
inst✝¹ : (i : ι) → Module R (Nᵢ i)
inst✝ : Fintype ι
Q : (i : ι) → QuadraticForm R (Mᵢ i)
x y : (i : ι) → Mᵢ i
⊢ ∑ i : ι, polar (⇑(Q i)) (x i) (y i) =
    BilinForm.bilin (∑ i : ι, BilinForm.comp (polarBilin (Q i)) (LinearMap.proj i) (LinearMap.proj i)) x y

Next tactic:
simp
@[simp] theorem associated_pi [Invertible (2 : R)] (Q : ∀ i, QuadraticForm R (Mᵢ i)) :
    associated (pi Q) = ∑ i, (Q i).associated.comp (.proj i) (.proj i) := by
  

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁶ : CommRing R
inst✝⁵ : (i : ι) → AddCommGroup (Mᵢ i)
inst✝⁴ : (i : ι) → AddCommGroup (Nᵢ i)
inst✝³ : (i : ι) → Module R (Mᵢ i)
inst✝² : (i : ι) → Module R (Nᵢ i)
inst✝¹ : Fintype ι
inst✝ : Invertible 2
Q : (i : ι) → QuadraticForm R (Mᵢ i)
⊢ associated (pi Q) = ∑ i : ι, BilinForm.comp (associated (Q i)) (LinearMap.proj i) (LinearMap.proj i)

Next tactic:
dsimp [associated, associatedHom]
@[simp] theorem associated_pi [Invertible (2 : R)] (Q : ∀ i, QuadraticForm R (Mᵢ i)) :
    associated (pi Q) = ∑ i, (Q i).associated.comp (.proj i) (.proj i) := by
  dsimp [associated, associatedHom]
  

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁶ : CommRing R
inst✝⁵ : (i : ι) → AddCommGroup (Mᵢ i)
inst✝⁴ : (i : ι) → AddCommGroup (Nᵢ i)
inst✝³ : (i : ι) → Module R (Mᵢ i)
inst✝² : (i : ι) → Module R (Nᵢ i)
inst✝¹ : Fintype ι
inst✝ : Invertible 2
Q : (i : ι) → QuadraticForm R (Mᵢ i)
⊢ { val := ⅟2, property := (_ : ⅟2 ∈ Set.center R) } • polarBilin (pi Q) =
    ∑ i : ι,
      BilinForm.comp ({ val := ⅟2, property := (_ : ⅟2 ∈ Set.center R) } • polarBilin (Q i)) (LinearMap.proj i)
        (LinearMap.proj i)

Next tactic:
rw [polarBilin_pi, Finset.smul_sum]
@[simp] theorem associated_pi [Invertible (2 : R)] (Q : ∀ i, QuadraticForm R (Mᵢ i)) :
    associated (pi Q) = ∑ i, (Q i).associated.comp (.proj i) (.proj i) := by
  dsimp [associated, associatedHom]
  rw [polarBilin_pi, Finset.smul_sum]
  

Proof state:
ι : Type u_1
R : Type u_2
M₁ : Type u_3
M₂ : Type u_4
N₁ : Type u_5
N₂ : Type u_6
Mᵢ : ι → Type u_7
Nᵢ : ι → Type u_8
inst✝⁶ : CommRing R
inst✝⁵ : (i : ι) → AddCommGroup (Mᵢ i)
inst✝⁴ : (i : ι) → AddCommGroup (Nᵢ i)
inst✝³ : (i : ι) → Module R (Mᵢ i)
inst✝² : (i : ι) → Module R (Nᵢ i)
inst✝¹ : Fintype ι
inst✝ : Invertible 2
Q : (i : ι) → QuadraticForm R (Mᵢ i)
⊢ ∑ x : ι,
      { val := ⅟2, property := (_ : ⅟2 ∈ Set.center R) } •
        BilinForm.comp (polarBilin (Q x)) (LinearMap.proj x) (LinearMap.proj x) =
    ∑ i : ι,
      BilinForm.comp ({ val := ⅟2, property := (_ : ⅟2 ∈ Set.center R) } • polarBilin (Q i)) (LinearMap.proj i)
        (LinearMap.proj i)

Next tactic:
rfl
@[to_additive (attr := simps tensorObj_as leftUnitor rightUnitor associator) Discrete.addMonoidal]
instance Discrete.monoidal : MonoidalCategory (Discrete M)
    where
  tensorUnit := Discrete.mk 1
  tensorObj X Y := Discrete.mk (X.as * Y.as)
  whiskerLeft X _ _ f := eqToHom (by 

Proof state:
M : Type u
inst✝ : Monoid M
X x✝¹ x✝ : Discrete M
f : x✝¹ ⟶ x✝
⊢ (fun X Y => { as := X.as * Y.as }) X x✝¹ = (fun X Y => { as := X.as * Y.as }) X x✝

Next tactic:
dsimp
@[to_additive (attr := simps tensorObj_as leftUnitor rightUnitor associator) Discrete.addMonoidal]
instance Discrete.monoidal : MonoidalCategory (Discrete M)
    where
  tensorUnit := Discrete.mk 1
  tensorObj X Y := Discrete.mk (X.as * Y.as)
  whiskerLeft X _ _ f := eqToHom (by dsimp; 

Proof state:
M : Type u
inst✝ : Monoid M
X x✝¹ x✝ : Discrete M
f : x✝¹ ⟶ x✝
⊢ { as := X.as * x✝¹.as } = { as := X.as * x✝.as }

Next tactic:
rw [eq_of_hom f]
@[to_additive (attr := simps tensorObj_as leftUnitor rightUnitor associator) Discrete.addMonoidal]
instance Discrete.monoidal : MonoidalCategory (Discrete M)
    where
  tensorUnit := Discrete.mk 1
  tensorObj X Y := Discrete.mk (X.as * Y.as)
  whiskerLeft X _ _ f := eqToHom (by dsimp; rw [eq_of_hom f])
  whiskerRight f X := eqToHom (by 

Proof state:
M : Type u
inst✝ : Monoid M
X₁✝ X₂✝ : Discrete M
f : X₁✝ ⟶ X₂✝
X : Discrete M
⊢ (fun X Y => { as := X.as * Y.as }) X₁✝ X = (fun X Y => { as := X.as * Y.as }) X₂✝ X

Next tactic:
dsimp
@[to_additive (attr := simps tensorObj_as leftUnitor rightUnitor associator) Discrete.addMonoidal]
instance Discrete.monoidal : MonoidalCategory (Discrete M)
    where
  tensorUnit := Discrete.mk 1
  tensorObj X Y := Discrete.mk (X.as * Y.as)
  whiskerLeft X _ _ f := eqToHom (by dsimp; rw [eq_of_hom f])
  whiskerRight f X := eqToHom (by dsimp; 

Proof state:
M : Type u
inst✝ : Monoid M
X₁✝ X₂✝ : Discrete M
f : X₁✝ ⟶ X₂✝
X : Discrete M
⊢ { as := X₁✝.as * X.as } = { as := X₂✝.as * X.as }

Next tactic:
rw [eq_of_hom f]
@[to_additive (attr := simps tensorObj_as leftUnitor rightUnitor associator) Discrete.addMonoidal]
instance Discrete.monoidal : MonoidalCategory (Discrete M)
    where
  tensorUnit := Discrete.mk 1
  tensorObj X Y := Discrete.mk (X.as * Y.as)
  whiskerLeft X _ _ f := eqToHom (by dsimp; rw [eq_of_hom f])
  whiskerRight f X := eqToHom (by dsimp; rw [eq_of_hom f])
  tensorHom f g := eqToHom (by 

Proof state:
M : Type u
inst✝ : Monoid M
X₁✝ Y₁✝ X₂✝ Y₂✝ : Discrete M
f : X₁✝ ⟶ Y₁✝
g : X₂✝ ⟶ Y₂✝
⊢ (fun X Y => { as := X.as * Y.as }) X₁✝ X₂✝ = (fun X Y => { as := X.as * Y.as }) Y₁✝ Y₂✝

Next tactic:
dsimp
@[to_additive (attr := simps tensorObj_as leftUnitor rightUnitor associator) Discrete.addMonoidal]
instance Discrete.monoidal : MonoidalCategory (Discrete M)
    where
  tensorUnit := Discrete.mk 1
  tensorObj X Y := Discrete.mk (X.as * Y.as)
  whiskerLeft X _ _ f := eqToHom (by dsimp; rw [eq_of_hom f])
  whiskerRight f X := eqToHom (by dsimp; rw [eq_of_hom f])
  tensorHom f g := eqToHom (by dsimp; 

Proof state:
M : Type u
inst✝ : Monoid M
X₁✝ Y₁✝ X₂✝ Y₂✝ : Discrete M
f : X₁✝ ⟶ Y₁✝
g : X₂✝ ⟶ Y₂✝
⊢ { as := X₁✝.as * X₂✝.as } = { as := Y₁✝.as * Y₂✝.as }

Next tactic:
rw [eq_of_hom f, eq_of_hom g]
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    

Proof state:
a : ℕ
ha : a ≤ pred a
⊢ IsMin a

Next tactic:
cases a
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · 

Proof state:
case zero
ha : zero ≤ pred zero
⊢ IsMin zero

Next tactic:
exact isMin_bot
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · exact isMin_bot
    · 

Proof state:
case succ
n✝ : ℕ
ha : succ n✝ ≤ pred (succ n✝)
⊢ IsMin (succ n✝)

Next tactic:
exact (not_succ_le_self _ ha).elim
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · exact isMin_bot
    · exact (not_succ_le_self _ ha).elim
  le_pred_of_lt {a} {b} h := by
    

Proof state:
a b : ℕ
h : a < b
⊢ a ≤ pred b

Next tactic:
cases b
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · exact isMin_bot
    · exact (not_succ_le_self _ ha).elim
  le_pred_of_lt {a} {b} h := by
    cases b
    · 

Proof state:
case zero
a : ℕ
h : a < zero
⊢ a ≤ pred zero

Next tactic:
exact (a.not_lt_zero h).elim
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · exact isMin_bot
    · exact (not_succ_le_self _ ha).elim
  le_pred_of_lt {a} {b} h := by
    cases b
    · exact (a.not_lt_zero h).elim
    · 

Proof state:
case succ
a n✝ : ℕ
h : a < succ n✝
⊢ a ≤ pred (succ n✝)

Next tactic:
exact le_of_succ_le_succ h
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · exact isMin_bot
    · exact (not_succ_le_self _ ha).elim
  le_pred_of_lt {a} {b} h := by
    cases b
    · exact (a.not_lt_zero h).elim
    · exact le_of_succ_le_succ h
  le_of_pred_lt {a} {b} h := by
    

Proof state:
a b : ℕ
h : pred a < b
⊢ a ≤ b

Next tactic:
cases a
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · exact isMin_bot
    · exact (not_succ_le_self _ ha).elim
  le_pred_of_lt {a} {b} h := by
    cases b
    · exact (a.not_lt_zero h).elim
    · exact le_of_succ_le_succ h
  le_of_pred_lt {a} {b} h := by
    cases a
    · 

Proof state:
case zero
b : ℕ
h : pred zero < b
⊢ zero ≤ b

Next tactic:
exact b.zero_le
@[reducible]
instance : PredOrder ℕ where
  pred := pred
  pred_le := pred_le
  min_of_le_pred {a} ha := by
    cases a
    · exact isMin_bot
    · exact (not_succ_le_self _ ha).elim
  le_pred_of_lt {a} {b} h := by
    cases b
    · exact (a.not_lt_zero h).elim
    · exact le_of_succ_le_succ h
  le_of_pred_lt {a} {b} h := by
    cases a
    · exact b.zero_le
    · 

Proof state:
case succ
b n✝ : ℕ
h : pred (succ n✝) < b
⊢ succ n✝ ≤ b

Next tactic:
exact h
theorem succ_iterate (a : ℕ) : ∀ n, succ^[n] a = a + n
  | 0 => rfl
  | n + 1 => by
    

Proof state:
a n : ℕ
⊢ succ^[n + 1] a = a + (n + 1)

Next tactic:
rw [Function.iterate_succ', add_succ]
theorem succ_iterate (a : ℕ) : ∀ n, succ^[n] a = a + n
  | 0 => rfl
  | n + 1 => by
    rw [Function.iterate_succ', add_succ]
    

Proof state:
a n : ℕ
⊢ (succ ∘ succ^[n]) a = succ (a + n)

Next tactic:
exact congr_arg _ (succ_iterate a n)
theorem pred_iterate (a : ℕ) : ∀ n, pred^[n] a = a - n
  | 0 => rfl
  | n + 1 => by
    

Proof state:
a n : ℕ
⊢ pred^[n + 1] a = a - (n + 1)

Next tactic:
rw [Function.iterate_succ', sub_succ]
theorem pred_iterate (a : ℕ) : ∀ n, pred^[n] a = a - n
  | 0 => rfl
  | n + 1 => by
    rw [Function.iterate_succ', sub_succ]
    

Proof state:
a n : ℕ
⊢ (pred ∘ pred^[n]) a = pred (a - n)

Next tactic:
exact congr_arg _ (pred_iterate a n)
instance : IsSuccArchimedean ℕ :=
  ⟨fun {a} {b} h => ⟨b - a, by 

Proof state:
a b : ℕ
h : a ≤ b
⊢ Order.succ^[b - a] a = b

Next tactic:
rw [succ_eq_succ, succ_iterate, add_tsub_cancel_of_le h]
instance : IsPredArchimedean ℕ :=
  ⟨fun {a} {b} h => ⟨b - a, by 

Proof state:
a b : ℕ
h : a ≤ b
⊢ Order.pred^[b - a] b = a

Next tactic:
rw [pred_eq_pred, pred_iterate, tsub_tsub_cancel_of_le h]
/-- On a compact uniform space, the topology determines the uniform structure, entourages are
exactly the neighborhoods of the diagonal. -/
theorem nhdsSet_diagonal_eq_uniformity [CompactSpace α] : 𝓝ˢ (diagonal α) = 𝓤 α := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : CompactSpace α
⊢ 𝓝ˢ (diagonal α) = 𝓤 α

Next tactic:
refine' nhdsSet_diagonal_le_uniformity.antisymm _
/-- On a compact uniform space, the topology determines the uniform structure, entourages are
exactly the neighborhoods of the diagonal. -/
theorem nhdsSet_diagonal_eq_uniformity [CompactSpace α] : 𝓝ˢ (diagonal α) = 𝓤 α := by
  refine' nhdsSet_diagonal_le_uniformity.antisymm _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : CompactSpace α
⊢ 𝓤 α ≤ 𝓝ˢ (diagonal α)

Next tactic:
have :
    (𝓤 (α × α)).HasBasis (fun U => U ∈ 𝓤 α) fun U =>
      (fun p : (α × α) × α × α => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U := by
    rw [uniformity_prod_eq_comap_prod]
    exact (𝓤 α).basis_sets.prod_self.comap _
/-- On a compact uniform space, the topology determines the uniform structure, entourages are
exactly the neighborhoods of the diagonal. -/
theorem nhdsSet_diagonal_eq_uniformity [CompactSpace α] : 𝓝ˢ (diagonal α) = 𝓤 α := by
  refine' nhdsSet_diagonal_le_uniformity.antisymm _
  have :
    (𝓤 (α × α)).HasBasis (fun U => U ∈ 𝓤 α) fun U =>
      (fun p : (α × α) × α × α => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : CompactSpace α
⊢ HasBasis (𝓤 (α × α)) (fun U => U ∈ 𝓤 α) fun U => (fun p => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U

Next tactic:
rw [uniformity_prod_eq_comap_prod]
/-- On a compact uniform space, the topology determines the uniform structure, entourages are
exactly the neighborhoods of the diagonal. -/
theorem nhdsSet_diagonal_eq_uniformity [CompactSpace α] : 𝓝ˢ (diagonal α) = 𝓤 α := by
  refine' nhdsSet_diagonal_le_uniformity.antisymm _
  have :
    (𝓤 (α × α)).HasBasis (fun U => U ∈ 𝓤 α) fun U =>
      (fun p : (α × α) × α × α => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U := by
    rw [uniformity_prod_eq_comap_prod]
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : CompactSpace α
⊢ HasBasis (Filter.comap (fun p => ((p.1.1, p.2.1), p.1.2, p.2.2)) (𝓤 α ×ˢ 𝓤 α)) (fun U => U ∈ 𝓤 α) fun U =>
    (fun p => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U

Next tactic:
exact (𝓤 α).basis_sets.prod_self.comap _
/-- On a compact uniform space, the topology determines the uniform structure, entourages are
exactly the neighborhoods of the diagonal. -/
theorem nhdsSet_diagonal_eq_uniformity [CompactSpace α] : 𝓝ˢ (diagonal α) = 𝓤 α := by
  refine' nhdsSet_diagonal_le_uniformity.antisymm _
  have :
    (𝓤 (α × α)).HasBasis (fun U => U ∈ 𝓤 α) fun U =>
      (fun p : (α × α) × α × α => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U := by
    rw [uniformity_prod_eq_comap_prod]
    exact (𝓤 α).basis_sets.prod_self.comap _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : CompactSpace α
this : HasBasis (𝓤 (α × α)) (fun U => U ∈ 𝓤 α) fun U => (fun p => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U
⊢ 𝓤 α ≤ 𝓝ˢ (diagonal α)

Next tactic:
refine' (isCompact_diagonal.nhdsSet_basis_uniformity this).ge_iff.2 fun U hU => _
/-- On a compact uniform space, the topology determines the uniform structure, entourages are
exactly the neighborhoods of the diagonal. -/
theorem nhdsSet_diagonal_eq_uniformity [CompactSpace α] : 𝓝ˢ (diagonal α) = 𝓤 α := by
  refine' nhdsSet_diagonal_le_uniformity.antisymm _
  have :
    (𝓤 (α × α)).HasBasis (fun U => U ∈ 𝓤 α) fun U =>
      (fun p : (α × α) × α × α => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U := by
    rw [uniformity_prod_eq_comap_prod]
    exact (𝓤 α).basis_sets.prod_self.comap _
  refine' (isCompact_diagonal.nhdsSet_basis_uniformity this).ge_iff.2 fun U hU => _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
inst✝ : CompactSpace α
this : HasBasis (𝓤 (α × α)) (fun U => U ∈ 𝓤 α) fun U => (fun p => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U
U : Set (α × α)
hU : U ∈ 𝓤 α
⊢ ⋃ x ∈ diagonal α, ball x ((fun p => ((p.1.1, p.2.1), p.1.2, p.2.2)) ⁻¹' U ×ˢ U) ∈ 𝓤 α

Next tactic:
exact mem_of_superset hU fun ⟨x, y⟩ hxy => mem_iUnion₂.2
    ⟨(x, x), rfl, refl_mem_uniformity hU, hxy⟩
theorem unique_uniformity_of_compact [t : TopologicalSpace γ] [CompactSpace γ]
    {u u' : UniformSpace γ} (h : u.toTopologicalSpace = t) (h' : u'.toTopologicalSpace = t) :
    u = u' := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
t : TopologicalSpace γ
inst✝ : CompactSpace γ
u u' : UniformSpace γ
h : toTopologicalSpace = t
h' : toTopologicalSpace = t
⊢ u = u'

Next tactic:
refine UniformSpace.ext ?_
theorem unique_uniformity_of_compact [t : TopologicalSpace γ] [CompactSpace γ]
    {u u' : UniformSpace γ} (h : u.toTopologicalSpace = t) (h' : u'.toTopologicalSpace = t) :
    u = u' := by
  refine UniformSpace.ext ?_
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
t : TopologicalSpace γ
inst✝ : CompactSpace γ
u u' : UniformSpace γ
h : toTopologicalSpace = t
h' : toTopologicalSpace = t
⊢ 𝓤 γ = 𝓤 γ

Next tactic:
have : @CompactSpace γ u.toTopologicalSpace := by rwa [h]
theorem unique_uniformity_of_compact [t : TopologicalSpace γ] [CompactSpace γ]
    {u u' : UniformSpace γ} (h : u.toTopologicalSpace = t) (h' : u'.toTopologicalSpace = t) :
    u = u' := by
  refine UniformSpace.ext ?_
  have : @CompactSpace γ u.toTopologicalSpace := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
t : TopologicalSpace γ
inst✝ : CompactSpace γ
u u' : UniformSpace γ
h : toTopologicalSpace = t
h' : toTopologicalSpace = t
⊢ CompactSpace γ

Next tactic:
rwa [h]
theorem unique_uniformity_of_compact [t : TopologicalSpace γ] [CompactSpace γ]
    {u u' : UniformSpace γ} (h : u.toTopologicalSpace = t) (h' : u'.toTopologicalSpace = t) :
    u = u' := by
  refine UniformSpace.ext ?_
  have : @CompactSpace γ u.toTopologicalSpace := by rwa [h]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
t : TopologicalSpace γ
inst✝ : CompactSpace γ
u u' : UniformSpace γ
h : toTopologicalSpace = t
h' : toTopologicalSpace = t
this : CompactSpace γ
⊢ 𝓤 γ = 𝓤 γ

Next tactic:
have : @CompactSpace γ u'.toTopologicalSpace := by rwa [h']
theorem unique_uniformity_of_compact [t : TopologicalSpace γ] [CompactSpace γ]
    {u u' : UniformSpace γ} (h : u.toTopologicalSpace = t) (h' : u'.toTopologicalSpace = t) :
    u = u' := by
  refine UniformSpace.ext ?_
  have : @CompactSpace γ u.toTopologicalSpace := by rwa [h]
  have : @CompactSpace γ u'.toTopologicalSpace := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
t : TopologicalSpace γ
inst✝ : CompactSpace γ
u u' : UniformSpace γ
h : toTopologicalSpace = t
h' : toTopologicalSpace = t
this : CompactSpace γ
⊢ CompactSpace γ

Next tactic:
rwa [h']
theorem unique_uniformity_of_compact [t : TopologicalSpace γ] [CompactSpace γ]
    {u u' : UniformSpace γ} (h : u.toTopologicalSpace = t) (h' : u'.toTopologicalSpace = t) :
    u = u' := by
  refine UniformSpace.ext ?_
  have : @CompactSpace γ u.toTopologicalSpace := by rwa [h]
  have : @CompactSpace γ u'.toTopologicalSpace := by rwa [h']
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : UniformSpace α
inst✝¹ : UniformSpace β
t : TopologicalSpace γ
inst✝ : CompactSpace γ
u u' : UniformSpace γ
h : toTopologicalSpace = t
h' : toTopologicalSpace = t
this✝ : CompactSpace γ
this : CompactSpace γ
⊢ 𝓤 γ = 𝓤 γ

Next tactic:
rw [@compactSpace_uniformity _ u, compactSpace_uniformity, h, h']
/-- The unique uniform structure inducing a given compact topological structure. -/
def uniformSpaceOfCompactT2 [TopologicalSpace γ] [CompactSpace γ] [T2Space γ] : UniformSpace γ
    where
  uniformity := 𝓝ˢ (diagonal γ)
  refl := principal_le_nhdsSet
  symm := continuous_swap.tendsto_nhdsSet fun x => Eq.symm
  comp := by
    /-  This is the difficult part of the proof. We need to prove that, for each neighborhood `W`
        of the diagonal `Δ`, there exists a smaller neighborhood `V` such that `V ○ V ⊆ W`.
        -/
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : UniformSpace α
inst✝³ : UniformSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : CompactSpace γ
inst✝ : T2Space γ
⊢ (Filter.lift' (𝓝ˢ (diagonal γ)) fun s => s ○ s) ≤ 𝓝ˢ (diagonal γ)

Next tactic:
set 𝓝Δ := 𝓝ˢ (diagonal γ)
/-- The unique uniform structure inducing a given compact topological structure. -/
def uniformSpaceOfCompactT2 [TopologicalSpace γ] [CompactSpace γ] [T2Space γ] : UniformSpace γ
    where
  uniformity := 𝓝ˢ (diagonal γ)
  refl := principal_le_nhdsSet
  symm := continuous_swap.tendsto_nhdsSet fun x => Eq.symm
  comp := by
    /-  This is the difficult part of the proof. We need to prove that, for each neighborhood `W`
        of the diagonal `Δ`, there exists a smaller neighborhood `V` such that `V ○ V ⊆ W`.
        -/
    set 𝓝Δ := 𝓝ˢ (diagonal γ)
    -- The filter of neighborhoods of Δ
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : UniformSpace α
inst✝³ : UniformSpace β
inst✝² : TopologicalSpace γ
inst✝¹ : CompactSpace γ
inst✝ : T2Space γ
𝓝Δ : Filter (γ × γ) := 𝓝ˢ (diagonal γ)
⊢ (Filter.lift' 𝓝Δ fun s => s ○ s) ≤ 𝓝Δ

Next tactic:
set F := 𝓝Δ.lift' fun s : Set (γ × γ) => s ○ s