l3lab/ntp-mathlib huggingface dataset:
theorem mono_inl_iff {A B : C} {c₁ c₂ : BinaryCofan A B} (hc₁ : IsColimit c₁) (hc₂ : IsColimit c₂) :
    Mono c₁.inl ↔ Mono c₂.inl := by
  suffices
    ∀ (c₁ c₂ : BinaryCofan A B) (_ : IsColimit c₁) (_ : IsColimit c₂) (_ : Mono c₁.inl),
      Mono c₂.inl
    by 

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A B : C
c₁ c₂ : BinaryCofan A B
hc₁ : IsColimit c₁
hc₂ : IsColimit c₂
this : ∀ (c₁ c₂ : BinaryCofan A B), IsColimit c₁ → IsColimit c₂ → Mono (BinaryCofan.inl c₁) → Mono (BinaryCofan.inl c₂)
⊢ Mono (BinaryCofan.inl c₁) ↔ Mono (BinaryCofan.inl c₂)

Next tactic:
exact ⟨fun h₁ => this _ _ hc₁ hc₂ h₁, fun h₂ => this _ _ hc₂ hc₁ h₂⟩
theorem mono_inl_iff {A B : C} {c₁ c₂ : BinaryCofan A B} (hc₁ : IsColimit c₁) (hc₂ : IsColimit c₂) :
    Mono c₁.inl ↔ Mono c₂.inl := by
  suffices
    ∀ (c₁ c₂ : BinaryCofan A B) (_ : IsColimit c₁) (_ : IsColimit c₂) (_ : Mono c₁.inl),
      Mono c₂.inl
    by exact ⟨fun h₁ => this _ _ hc₁ hc₂ h₁, fun h₂ => this _ _ hc₂ hc₁ h₂⟩
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A B : C
c₁ c₂ : BinaryCofan A B
hc₁ : IsColimit c₁
hc₂ : IsColimit c₂
⊢ ∀ (c₁ c₂ : BinaryCofan A B), IsColimit c₁ → IsColimit c₂ → Mono (BinaryCofan.inl c₁) → Mono (BinaryCofan.inl c₂)

Next tactic:
intro c₁ c₂ hc₁ hc₂
theorem mono_inl_iff {A B : C} {c₁ c₂ : BinaryCofan A B} (hc₁ : IsColimit c₁) (hc₂ : IsColimit c₂) :
    Mono c₁.inl ↔ Mono c₂.inl := by
  suffices
    ∀ (c₁ c₂ : BinaryCofan A B) (_ : IsColimit c₁) (_ : IsColimit c₂) (_ : Mono c₁.inl),
      Mono c₂.inl
    by exact ⟨fun h₁ => this _ _ hc₁ hc₂ h₁, fun h₂ => this _ _ hc₂ hc₁ h₂⟩
  intro c₁ c₂ hc₁ hc₂
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A B : C
c₁✝ c₂✝ : BinaryCofan A B
hc₁✝ : IsColimit c₁✝
hc₂✝ : IsColimit c₂✝
c₁ c₂ : BinaryCofan A B
hc₁ : IsColimit c₁
hc₂ : IsColimit c₂
⊢ Mono (BinaryCofan.inl c₁) → Mono (BinaryCofan.inl c₂)

Next tactic:
intro
theorem mono_inl_iff {A B : C} {c₁ c₂ : BinaryCofan A B} (hc₁ : IsColimit c₁) (hc₂ : IsColimit c₂) :
    Mono c₁.inl ↔ Mono c₂.inl := by
  suffices
    ∀ (c₁ c₂ : BinaryCofan A B) (_ : IsColimit c₁) (_ : IsColimit c₂) (_ : Mono c₁.inl),
      Mono c₂.inl
    by exact ⟨fun h₁ => this _ _ hc₁ hc₂ h₁, fun h₂ => this _ _ hc₂ hc₁ h₂⟩
  intro c₁ c₂ hc₁ hc₂
  intro
  

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
A B : C
c₁✝ c₂✝ : BinaryCofan A B
hc₁✝ : IsColimit c₁✝
hc₂✝ : IsColimit c₂✝
c₁ c₂ : BinaryCofan A B
hc₁ : IsColimit c₁
hc₂ : IsColimit c₂
x✝ : Mono (BinaryCofan.inl c₁)
⊢ Mono (BinaryCofan.inl c₂)

Next tactic:
simpa only [IsColimit.comp_coconePointUniqueUpToIso_hom] using
    mono_comp c₁.inl (hc₁.coconePointUniqueUpToIso hc₂).hom
theorem mk' (h : ∀ A B : C, ∃ (c : BinaryCofan A B) (_ : IsColimit c), Mono c.inl) : MonoCoprod C :=
  ⟨fun A B c' hc' => by
    

Proof state:
C : Type u_1
inst✝ : Category.{u_2, u_1} C
h : ∀ (A B : C), ∃ c x, Mono (BinaryCofan.inl c)
A B : C
c' : BinaryCofan A B
hc' : IsColimit c'
⊢ Mono (BinaryCofan.inl c')

Next tactic:
obtain ⟨c, hc₁, hc₂⟩ := h A B
theorem mk' (h : ∀ A B : C, ∃ (c : BinaryCofan A B) (_ : IsColimit c), Mono c.inl) : MonoCoprod C :=
  ⟨fun A B c' hc' => by
    obtain ⟨c, hc₁, hc₂⟩ := h A B
    

Proof state:
case intro.intro
C : Type u_1
inst✝ : Category.{u_2, u_1} C
h : ∀ (A B : C), ∃ c x, Mono (BinaryCofan.inl c)
A B : C
c' : BinaryCofan A B
hc' : IsColimit c'
c : BinaryCofan A B
hc₁ : IsColimit c
hc₂ : Mono (BinaryCofan.inl c)
⊢ Mono (BinaryCofan.inl c')

Next tactic:
simpa only [mono_inl_iff hc' hc₁] using hc₂
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    

Proof state:
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B : Type u
⊢ ∃ c x, Mono (BinaryCofan.inl c)

Next tactic:
refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · 

Proof state:
case refine'_1
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B : Type u
⊢ IsColimit (BinaryCofan.mk Sum.inl Sum.inr)

Next tactic:
exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          funext x
          rcases x with x | x
          · exact congr_fun h₁ x
          · exact congr_fun h₂ x)
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          

Proof state:
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
x : (BinaryCofan.mk Sum.inl Sum.inr).pt
⊢ T✝

Next tactic:
rcases x with x | x
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          

Proof state:
case inl
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
x : A
⊢ T✝
case inr C : Type u_1 inst✝ : Category.{?u.13782, u_1} C A B T✝ : Type u f₁ : A ⟶ T✝ f₂ : B ⟶ T✝ x : B ⊢ T✝

Next tactic:
exacts [f₁ x, f₂ x]
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
⊢ BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr) ≫
      (fun {T} f₁ f₂ x => Sum.casesOn x (fun x => f₁ x) fun x => f₂ x) f₁ f₂ =
    f₁

Next tactic:
rfl
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by 

Proof state:
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
⊢ BinaryCofan.inr (BinaryCofan.mk Sum.inl Sum.inr) ≫
      (fun {T} f₁ f₂ x => Sum.casesOn x (fun x => f₁ x) fun x => f₂ x) f₁ f₂ =
    f₂

Next tactic:
rfl
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          

Proof state:
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
m : (BinaryCofan.mk Sum.inl Sum.inr).pt ⟶ T✝
h₁ : BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₁
h₂ : BinaryCofan.inr (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₂
⊢ m = (fun {T} f₁ f₂ x => Sum.casesOn x (fun x => f₁ x) fun x => f₂ x) f₁ f₂

Next tactic:
funext x
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          funext x
          

Proof state:
case h
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
m : (BinaryCofan.mk Sum.inl Sum.inr).pt ⟶ T✝
h₁ : BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₁
h₂ : BinaryCofan.inr (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₂
x : (BinaryCofan.mk Sum.inl Sum.inr).pt
⊢ m x = (fun {T} f₁ f₂ x => Sum.casesOn x (fun x => f₁ x) fun x => f₂ x) f₁ f₂ x

Next tactic:
rcases x with x | x
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          funext x
          rcases x with x | x
          · 

Proof state:
case h.inl
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
m : (BinaryCofan.mk Sum.inl Sum.inr).pt ⟶ T✝
h₁ : BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₁
h₂ : BinaryCofan.inr (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₂
x : A
⊢ m (Sum.inl x) = (fun {T} f₁ f₂ x => Sum.casesOn x (fun x => f₁ x) fun x => f₂ x) f₁ f₂ (Sum.inl x)

Next tactic:
exact congr_fun h₁ x
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          funext x
          rcases x with x | x
          · exact congr_fun h₁ x
          · 

Proof state:
case h.inr
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B T✝ : Type u
f₁ : A ⟶ T✝
f₂ : B ⟶ T✝
m : (BinaryCofan.mk Sum.inl Sum.inr).pt ⟶ T✝
h₁ : BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₁
h₂ : BinaryCofan.inr (BinaryCofan.mk Sum.inl Sum.inr) ≫ m = f₂
x : B
⊢ m (Sum.inr x) = (fun {T} f₁ f₂ x => Sum.casesOn x (fun x => f₁ x) fun x => f₂ x) f₁ f₂ (Sum.inr x)

Next tactic:
exact congr_fun h₂ x
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          funext x
          rcases x with x | x
          · exact congr_fun h₁ x
          · exact congr_fun h₂ x)
    · 

Proof state:
case refine'_2
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B : Type u
⊢ Mono (BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr))

Next tactic:
rw [mono_iff_injective]
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          funext x
          rcases x with x | x
          · exact congr_fun h₁ x
          · exact congr_fun h₂ x)
    · rw [mono_iff_injective]
      

Proof state:
case refine'_2
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B : Type u
⊢ Function.Injective (BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr))

Next tactic:
intro a₁ a₂ h
instance monoCoprodType : MonoCoprod (Type u) :=
  MonoCoprod.mk' fun A B => by
    refine' ⟨BinaryCofan.mk (Sum.inl : A ⟶ Sum A B) Sum.inr, _, _⟩
    · exact BinaryCofan.IsColimit.mk _
        (fun f₁ f₂ x => by
          rcases x with x | x
          exacts [f₁ x, f₂ x])
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ => by rfl)
        (fun f₁ f₂ m h₁ h₂ => by
          funext x
          rcases x with x | x
          · exact congr_fun h₁ x
          · exact congr_fun h₂ x)
    · rw [mono_iff_injective]
      intro a₁ a₂ h
      

Proof state:
case refine'_2
C : Type u_1
inst✝ : Category.{?u.13782, u_1} C
A B : Type u
a₁ a₂ : (pair A B).obj { as := WalkingPair.left }
h : BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr) a₁ = BinaryCofan.inl (BinaryCofan.mk Sum.inl Sum.inr) a₂
⊢ a₁ = a₂

Next tactic:
simpa using h
@[ext]
lemma Bornology.ext (t t' : Bornology α)
    (h_cobounded : @Bornology.cobounded α t = @Bornology.cobounded α t') :
    t = t' := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
t t' : Bornology α
h_cobounded : cobounded α = cobounded α
⊢ t = t'

Next tactic:
cases t
@[ext]
lemma Bornology.ext (t t' : Bornology α)
    (h_cobounded : @Bornology.cobounded α t = @Bornology.cobounded α t') :
    t = t' := by
  cases t
  

Proof state:
case mk
ι : Type u_1
α : Type u_2
β : Type u_3
t' : Bornology α
cobounded'✝ : Filter α
le_cofinite'✝ : cobounded'✝ ≤ cofinite
h_cobounded : cobounded α = cobounded α
⊢ { cobounded' := cobounded'✝, le_cofinite' := le_cofinite'✝ } = t'

Next tactic:
cases t'
@[ext]
lemma Bornology.ext (t t' : Bornology α)
    (h_cobounded : @Bornology.cobounded α t = @Bornology.cobounded α t') :
    t = t' := by
  cases t
  cases t'
  

Proof state:
case mk.mk
ι : Type u_1
α : Type u_2
β : Type u_3
cobounded'✝¹ : Filter α
le_cofinite'✝¹ : cobounded'✝¹ ≤ cofinite
cobounded'✝ : Filter α
le_cofinite'✝ : cobounded'✝ ≤ cofinite
h_cobounded : cobounded α = cobounded α
⊢ { cobounded' := cobounded'✝¹, le_cofinite' := le_cofinite'✝¹ } =
    { cobounded' := cobounded'✝, le_cofinite' := le_cofinite'✝ }

Next tactic:
congr
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps]
def Bornology.ofBounded {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (singleton_mem : ∀ x, {x} ∈ B) : Bornology α where
  cobounded' :=
    { sets := { s : Set α | sᶜ ∈ B }
      univ_sets := by 

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
singleton_mem : ∀ (x : α), {x} ∈ B
⊢ univ ∈ {s | sᶜ ∈ B}

Next tactic:
rwa [← compl_univ] at empty_mem
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps]
def Bornology.ofBounded {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (singleton_mem : ∀ x, {x} ∈ B) : Bornology α where
  cobounded' :=
    { sets := { s : Set α | sᶜ ∈ B }
      univ_sets := by rwa [← compl_univ] at empty_mem
      sets_of_superset := fun hx hy => subset_mem _ hx _ (compl_subset_compl.mpr hy)
      inter_sets := fun hx hy => by 

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
singleton_mem : ∀ (x : α), {x} ∈ B
x✝ y✝ : Set α
hx : x✝ ∈ {s | sᶜ ∈ B}
hy : y✝ ∈ {s | sᶜ ∈ B}
⊢ x✝ ∩ y✝ ∈ {s | sᶜ ∈ B}

Next tactic:
simpa [compl_inter] using union_mem _ hx _ hy
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps]
def Bornology.ofBounded {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (singleton_mem : ∀ x, {x} ∈ B) : Bornology α where
  cobounded' :=
    { sets := { s : Set α | sᶜ ∈ B }
      univ_sets := by rwa [← compl_univ] at empty_mem
      sets_of_superset := fun hx hy => subset_mem _ hx _ (compl_subset_compl.mpr hy)
      inter_sets := fun hx hy => by simpa [compl_inter] using union_mem _ hx _ hy }
  le_cofinite' := by
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
singleton_mem : ∀ (x : α), {x} ∈ B
⊢ { sets := {s | sᶜ ∈ B}, univ_sets := (_ : univᶜ ∈ B),
      sets_of_superset := (_ : ∀ {x y : Set α}, x ∈ {s | sᶜ ∈ B} → x ⊆ y → yᶜ ∈ B),
      inter_sets := (_ : ∀ {x y : Set α}, x ∈ {s | sᶜ ∈ B} → y ∈ {s | sᶜ ∈ B} → x ∩ y ∈ {s | sᶜ ∈ B}) } ≤
    cofinite

Next tactic:
rw [le_cofinite_iff_compl_singleton_mem]
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps]
def Bornology.ofBounded {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (singleton_mem : ∀ x, {x} ∈ B) : Bornology α where
  cobounded' :=
    { sets := { s : Set α | sᶜ ∈ B }
      univ_sets := by rwa [← compl_univ] at empty_mem
      sets_of_superset := fun hx hy => subset_mem _ hx _ (compl_subset_compl.mpr hy)
      inter_sets := fun hx hy => by simpa [compl_inter] using union_mem _ hx _ hy }
  le_cofinite' := by
    rw [le_cofinite_iff_compl_singleton_mem]
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
singleton_mem : ∀ (x : α), {x} ∈ B
⊢ ∀ (x : α),
    {x}ᶜ ∈
      { sets := {s | sᶜ ∈ B}, univ_sets := (_ : univᶜ ∈ B),
        sets_of_superset := (_ : ∀ {x y : Set α}, x ∈ {s | sᶜ ∈ B} → x ⊆ y → yᶜ ∈ B),
        inter_sets := (_ : ∀ {x y : Set α}, x ∈ {s | sᶜ ∈ B} → y ∈ {s | sᶜ ∈ B} → x ∩ y ∈ {s | sᶜ ∈ B}) }

Next tactic:
intro x
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps]
def Bornology.ofBounded {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (singleton_mem : ∀ x, {x} ∈ B) : Bornology α where
  cobounded' :=
    { sets := { s : Set α | sᶜ ∈ B }
      univ_sets := by rwa [← compl_univ] at empty_mem
      sets_of_superset := fun hx hy => subset_mem _ hx _ (compl_subset_compl.mpr hy)
      inter_sets := fun hx hy => by simpa [compl_inter] using union_mem _ hx _ hy }
  le_cofinite' := by
    rw [le_cofinite_iff_compl_singleton_mem]
    intro x
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
singleton_mem : ∀ (x : α), {x} ∈ B
x : α
⊢ {x}ᶜ ∈
    { sets := {s | sᶜ ∈ B}, univ_sets := (_ : univᶜ ∈ B),
      sets_of_superset := (_ : ∀ {x y : Set α}, x ∈ {s | sᶜ ∈ B} → x ⊆ y → yᶜ ∈ B),
      inter_sets := (_ : ∀ {x y : Set α}, x ∈ {s | sᶜ ∈ B} → y ∈ {s | sᶜ ∈ B} → x ∩ y ∈ {s | sᶜ ∈ B}) }

Next tactic:
change {x}ᶜᶜ ∈ B
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps]
def Bornology.ofBounded {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (singleton_mem : ∀ x, {x} ∈ B) : Bornology α where
  cobounded' :=
    { sets := { s : Set α | sᶜ ∈ B }
      univ_sets := by rwa [← compl_univ] at empty_mem
      sets_of_superset := fun hx hy => subset_mem _ hx _ (compl_subset_compl.mpr hy)
      inter_sets := fun hx hy => by simpa [compl_inter] using union_mem _ hx _ hy }
  le_cofinite' := by
    rw [le_cofinite_iff_compl_singleton_mem]
    intro x
    change {x}ᶜᶜ ∈ B
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
singleton_mem : ∀ (x : α), {x} ∈ B
x : α
⊢ {x}ᶜᶜ ∈ B

Next tactic:
rw [compl_compl]
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps]
def Bornology.ofBounded {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (singleton_mem : ∀ x, {x} ∈ B) : Bornology α where
  cobounded' :=
    { sets := { s : Set α | sᶜ ∈ B }
      univ_sets := by rwa [← compl_univ] at empty_mem
      sets_of_superset := fun hx hy => subset_mem _ hx _ (compl_subset_compl.mpr hy)
      inter_sets := fun hx hy => by simpa [compl_inter] using union_mem _ hx _ hy }
  le_cofinite' := by
    rw [le_cofinite_iff_compl_singleton_mem]
    intro x
    change {x}ᶜᶜ ∈ B
    rw [compl_compl]
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
singleton_mem : ∀ (x : α), {x} ∈ B
x : α
⊢ {x} ∈ B

Next tactic:
exact singleton_mem x
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps!]
def Bornology.ofBounded' {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (sUnion_univ : ⋃₀ B = univ) :
    Bornology α :=
  Bornology.ofBounded B empty_mem subset_mem union_mem fun x => by
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
sUnion_univ : ⋃₀ B = univ
x : α
⊢ {x} ∈ B

Next tactic:
rw [sUnion_eq_univ_iff] at sUnion_univ
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps!]
def Bornology.ofBounded' {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (sUnion_univ : ⋃₀ B = univ) :
    Bornology α :=
  Bornology.ofBounded B empty_mem subset_mem union_mem fun x => by
    rw [sUnion_eq_univ_iff] at sUnion_univ
    

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
sUnion_univ : ∀ (a : α), ∃ b ∈ B, a ∈ b
x : α
⊢ {x} ∈ B

Next tactic:
rcases sUnion_univ x with ⟨s, hs, hxs⟩
/-- A constructor for bornologies by specifying the bounded sets,
and showing that they satisfy the appropriate conditions. -/
@[simps!]
def Bornology.ofBounded' {α : Type*} (B : Set (Set α))
    (empty_mem : ∅ ∈ B)
    (subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B)
    (union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B)
    (sUnion_univ : ⋃₀ B = univ) :
    Bornology α :=
  Bornology.ofBounded B empty_mem subset_mem union_mem fun x => by
    rw [sUnion_eq_univ_iff] at sUnion_univ
    rcases sUnion_univ x with ⟨s, hs, hxs⟩
    

Proof state:
case intro.intro
ι : Type u_1
α✝ : Type u_2
β : Type u_3
α : Type u_4
B : Set (Set α)
empty_mem : ∅ ∈ B
subset_mem : ∀ s₁ ∈ B, ∀ s₂ ⊆ s₁, s₂ ∈ B
union_mem : ∀ s₁ ∈ B, ∀ s₂ ∈ B, s₁ ∪ s₂ ∈ B
sUnion_univ : ∀ (a : α), ∃ b ∈ B, a ∈ b
x : α
s : Set α
hs : s ∈ B
hxs : x ∈ s
⊢ {x} ∈ B

Next tactic:
exact subset_mem s hs {x} (singleton_subset_iff.mpr hxs)
@[simp]
theorem isBounded_compl_iff : IsBounded sᶜ ↔ IsCobounded s := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Bornology α
s t : Set α
x : α
⊢ IsBounded sᶜ ↔ IsCobounded s

Next tactic:
rw [isBounded_def, isCobounded_def, compl_compl]
@[simp]
theorem isBounded_empty : IsBounded (∅ : Set α) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Bornology α
s t : Set α
x : α
⊢ IsBounded ∅

Next tactic:
rw [isBounded_def, compl_empty]
@[simp]
theorem isBounded_empty : IsBounded (∅ : Set α) := by
  rw [isBounded_def, compl_empty]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Bornology α
s t : Set α
x : α
⊢ univ ∈ cobounded α

Next tactic:
exact univ_mem
theorem nonempty_of_not_isBounded (h : ¬IsBounded s) : s.Nonempty := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Bornology α
s t : Set α
x : α
h : ¬IsBounded s
⊢ Set.Nonempty s

Next tactic:
rw [nonempty_iff_ne_empty]
theorem nonempty_of_not_isBounded (h : ¬IsBounded s) : s.Nonempty := by
  rw [nonempty_iff_ne_empty]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : Bornology α
s t : Set α
x : α
h : ¬IsBounded s
⊢ s ≠ ∅

Next tactic:
rintro rfl