|
| 1 | +/- |
| 2 | +Copyright (c) 2018 Scott Morrison. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Scott Morrison, Bhavik Mehta |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module category_theory.punit |
| 7 | +! leanprover-community/mathlib commit 2738d2ca56cbc63be80c3bd48e9ed90ad94e947d |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.CategoryTheory.Functor.Const |
| 12 | +import Mathlib.CategoryTheory.DiscreteCategory |
| 13 | + |
| 14 | +/-! |
| 15 | +# The category `Discrete PUnit` |
| 16 | +
|
| 17 | +We define `star : C ⥤ Discrete PUnit` sending everything to `PUnit.star`, |
| 18 | +show that any two functors to `Discrete PUnit` are naturally isomorphic, |
| 19 | +and construct the equivalence `(Discrete PUnit ⥤ C) ≌ C`. |
| 20 | +-/ |
| 21 | + |
| 22 | + |
| 23 | +universe v u |
| 24 | + |
| 25 | +-- morphism levels before object levels. See note [CategoryTheory universes]. |
| 26 | +namespace CategoryTheory |
| 27 | + |
| 28 | +variable (C : Type u) [Category.{v} C] |
| 29 | + |
| 30 | +namespace Functor |
| 31 | + |
| 32 | +/-- The constant functor sending everything to `PUnit.star`. -/ |
| 33 | +@[simps!] |
| 34 | +def star : C ⥤ Discrete PUnit := |
| 35 | + (Functor.const _).obj ⟨⟨⟩⟩ |
| 36 | +#align category_theory.functor.star CategoryTheory.Functor.star |
| 37 | +-- Porting note: simp can simplify this |
| 38 | +attribute [nolint simpNF] star_map_down_down |
| 39 | +variable {C} |
| 40 | + |
| 41 | +/-- Any two functors to `Discrete PUnit` are isomorphic. -/ |
| 42 | +@[simps!] |
| 43 | +def pUnitExt (F G : C ⥤ Discrete PUnit) : F ≅ G := by |
| 44 | + refine NatIso.ofComponents (fun X => eqToIso ?_) fun {X} {Y} f => ?_ |
| 45 | + · simp only [eq_iff_true_of_subsingleton] |
| 46 | + · aesop_cat |
| 47 | +#align category_theory.functor.punit_ext CategoryTheory.Functor.pUnitExt |
| 48 | +-- Porting note: simp does indeed fire for these despite the linter warning |
| 49 | +attribute [nolint simpNF] pUnitExt_hom_app_down_down pUnitExt_inv_app_down_down |
| 50 | + |
| 51 | +/-- Any two functors to `Discrete PUnit` are *equal*. |
| 52 | +You probably want to use `pUnitExt` instead of this. -/ |
| 53 | +theorem pUnit_ext' (F G : C ⥤ Discrete PUnit) : F = G := by |
| 54 | + refine Functor.ext (fun X => ?_) fun {X} {Y} f => ?_ |
| 55 | + · simp only [eq_iff_true_of_subsingleton] |
| 56 | + · aesop_cat |
| 57 | +#align category_theory.functor.punit_ext' CategoryTheory.Functor.pUnit_ext' |
| 58 | + |
| 59 | +/-- The functor from `Discrete PUnit` sending everything to the given object. -/ |
| 60 | +abbrev fromPUnit (X : C) : Discrete PUnit.{v + 1} ⥤ C := |
| 61 | + (Functor.const _).obj X |
| 62 | +#align category_theory.functor.from_punit CategoryTheory.Functor.fromPUnit |
| 63 | + |
| 64 | +/-- Functors from `Discrete PUnit` are equivalent to the category itself. -/ |
| 65 | +@[simps] |
| 66 | +def equiv : Discrete PUnit ⥤ C ≌ C where |
| 67 | + functor := |
| 68 | + { obj := fun F => F.obj ⟨⟨⟩⟩ |
| 69 | + map := fun θ => θ.app ⟨⟨⟩⟩ } |
| 70 | + inverse := Functor.const _ |
| 71 | + unitIso := by |
| 72 | + apply NatIso.ofComponents _ _ |
| 73 | + intro X |
| 74 | + apply Discrete.natIso |
| 75 | + rintro ⟨⟨⟩⟩ |
| 76 | + apply Iso.refl _ |
| 77 | + intros |
| 78 | + ext ⟨⟨⟩⟩ |
| 79 | + simp |
| 80 | + counitIso := by |
| 81 | + refine' NatIso.ofComponents Iso.refl _ |
| 82 | + intro X Y f |
| 83 | + dsimp; simp |
| 84 | +#align category_theory.functor.equiv CategoryTheory.Functor.equiv |
| 85 | + |
| 86 | +-- See note [dsimp, simp]. |
| 87 | +end Functor |
| 88 | + |
| 89 | +/-- A category being equivalent to `PUnit` is equivalent to it having a unique morphism between |
| 90 | + any two objects. (In fact, such a category is also a groupoid; |
| 91 | + see `CategoryTheory.Groupoid.ofHomUnique`) -/ |
| 92 | +theorem equiv_pUnit_iff_unique : |
| 93 | + Nonempty (C ≌ Discrete PUnit) ↔ Nonempty C ∧ ∀ x y : C, Nonempty <| Unique (x ⟶ y) := by |
| 94 | + constructor |
| 95 | + · rintro ⟨h⟩ |
| 96 | + refine' ⟨⟨h.inverse.obj ⟨⟨⟩⟩⟩, fun x y => Nonempty.intro _⟩ |
| 97 | + let f : x ⟶ y := by |
| 98 | + have hx : x ⟶ h.inverse.obj ⟨⟨⟩⟩ := by convert h.unit.app x |
| 99 | + have hy : h.inverse.obj ⟨⟨⟩⟩ ⟶ y := by convert h.unitInv.app y |
| 100 | + exact hx ≫ hy |
| 101 | + suffices sub : Subsingleton (x ⟶ y) from uniqueOfSubsingleton f |
| 102 | + have : ∀ z, z = h.unit.app x ≫ (h.functor ⋙ h.inverse).map z ≫ h.unitInv.app y := by |
| 103 | + intro z |
| 104 | + simp [congrArg (· ≫ h.unitInv.app y) (h.unit.naturality z)] |
| 105 | + apply Subsingleton.intro |
| 106 | + intro a b |
| 107 | + rw [this a, this b] |
| 108 | + simp only [Functor.comp_map] |
| 109 | + congr 3 |
| 110 | + apply ULift.ext |
| 111 | + simp |
| 112 | + · rintro ⟨⟨p⟩, h⟩ |
| 113 | + haveI := fun x y => (h x y).some |
| 114 | + refine' |
| 115 | + Nonempty.intro |
| 116 | + (CategoryTheory.Equivalence.mk ((Functor.const _).obj ⟨⟨⟩⟩) |
| 117 | + ((@Functor.const <| Discrete PUnit).obj p) ?_ (by apply Functor.pUnitExt)) |
| 118 | + exact |
| 119 | + NatIso.ofComponents |
| 120 | + (fun _ => |
| 121 | + { hom := default |
| 122 | + inv := default }) |
| 123 | + fun {X} {Y} f => by aesop_cat |
| 124 | +#align category_theory.equiv_punit_iff_unique CategoryTheory.equiv_pUnit_iff_unique |
| 125 | + |
| 126 | +end CategoryTheory |
| 127 | + |
0 commit comments