Theorem: CategoryTheory.equiv_pUnit_iff_unique
File: Mathlib/CategoryTheory/PUnit.lean

tactic: constructor
state_before: C : Type u
inst✝ : Category C
⊢ Nonempty (C ≌ Discrete PUnit) ↔ Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))

tactic: rintro ⟨h⟩
state_before: case mp
C : Type u
inst✝ : Category C
⊢ Nonempty (C ≌ Discrete PUnit) → Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))

tactic: refine' ⟨⟨h.inverse.obj ⟨⟨⟩⟩⟩, fun x y => Nonempty.intro _⟩
state_before: case mp.intro
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
⊢ Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))

tactic: let f : x ⟶  y := by
  have hx : x ⟶ h.inverse.obj ⟨⟨⟩⟩ := by convert h.unit.app x
  have hy : h.inverse.obj ⟨⟨⟩⟩ ⟶ y := by convert h.unitInv.app y
  exact hx ≫ hy
state_before: case mp.intro
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
⊢ Unique (x ⟶ y)

tactic: suffices sub : Subsingleton (x ⟶  y) from uniqueOfSubsingleton f
state_before: case mp.intro
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
⊢ Unique (x ⟶ y)

tactic: apply Subsingleton.intro
state_before: case mp.intro
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
this : ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y
⊢ Subsingleton (x ⟶ y)

tactic: intro a b
state_before: case mp.intro.allEq
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
this : ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y
⊢ ∀ (a b : x ⟶ y), a = b

tactic: rw [this a, this b]
state_before: case mp.intro.allEq
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
this : ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y
a b : x ⟶ y
⊢ a = b

tactic: simp only [Functor.comp_map]
state_before: case mp.intro.allEq
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
this : ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y
a b : x ⟶ y
⊢ (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map a ≫ (Equivalence.unitInv h).app y =
    (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map b ≫ (Equivalence.unitInv h).app y

tactic: congr 3
state_before: case mp.intro.allEq
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
this : ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y
a b : x ⟶ y
⊢ (Equivalence.unit h).app x ≫ h.inverse.map (h.functor.map a) ≫ (Equivalence.unitInv h).app y =
    (Equivalence.unit h).app x ≫ h.inverse.map (h.functor.map b) ≫ (Equivalence.unitInv h).app y

tactic: apply ULift.ext
state_before: case mp.intro.allEq.e_a.e_a.e_a
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
this : ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y
a b : x ⟶ y
⊢ h.functor.map a = h.functor.map b

tactic: simp
state_before: case mp.intro.allEq.e_a.e_a.e_a.h
C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
this : ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y
a b : x ⟶ y
⊢ (h.functor.map a).down = (h.functor.map b).down

tactic: have hx : x ⟶ h.inverse.obj ⟨⟨⟩⟩ := by convert h.unit.app x
state_before: C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
⊢ x ⟶ y

tactic: have hy : h.inverse.obj ⟨⟨⟩⟩ ⟶ y := by convert h.unitInv.app y
state_before: C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
hx : x ⟶ h.inverse.obj { as := PUnit.unit }
⊢ x ⟶ y

tactic: exact hx ≫ hy
state_before: C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
hx : x ⟶ h.inverse.obj { as := PUnit.unit }
hy : h.inverse.obj { as := PUnit.unit } ⟶ y
⊢ x ⟶ y

tactic: convert h.unit.app x
state_before: C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
⊢ x ⟶ h.inverse.obj { as := PUnit.unit }

tactic: convert h.unitInv.app y
state_before: C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
hx : x ⟶ h.inverse.obj { as := PUnit.unit }
⊢ h.inverse.obj { as := PUnit.unit } ⟶ y

tactic: intro z
state_before: C : Type u
inst✝ : Category C
h : C ≌ Discrete PUnit
x y : C
f : x ⟶ y :=
  let_fun hx :=
    Eq.mpr (_ : (x ⟶ h.inverse.obj { as := PUnit.unit }) = ((𝟭 C).obj x ⟶ (h.functor ⋙ h.inverse).obj x))
      ((Equivalence.unit h).app x);
  let_fun hy :=
    Eq.mpr (_ : (h.inverse.obj { as := PUnit.unit } ⟶ y) = ((h.functor ⋙ h.inverse).obj y ⟶ (𝟭 C).obj y))
      ((Equivalence.unitInv h).app y);
  hx ≫ hy
⊢ ∀ (z : x ⟶ y), z = (Equivalence.unit h).app x ≫ (h.functor ⋙ h.inverse).map z ≫ (Equivalence.unitInv h).app y

tactic: rintro ⟨⟨p⟩, h⟩
state_before: case mpr
C : Type u
inst✝ : Category C
⊢ (Nonempty C ∧ ∀ (x y : C), Nonempty (Unique (x ⟶ y))) → Nonempty (C ≌ Discrete PUnit)

tactic: haveI := fun x y => (h x y).some
state_before: case mpr.intro.intro
C : Type u
inst✝ : Category C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
⊢ Nonempty (C ≌ Discrete PUnit)

tactic: refine'
  Nonempty.intro
    (CategoryTheory.Equivalence.mk ((Functor.const _).obj ⟨⟨⟩⟩)
      ((@Functor.const <| Discrete PUnit).obj p) ?_ (by apply Functor.pUnitExt))
state_before: case mpr.intro.intro
C : Type u
inst✝ : Category C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
this : (x y : C) → Unique (x ⟶ y)
⊢ Nonempty (C ≌ Discrete PUnit)

tactic: exact
  NatIso.ofComponents fun _ =>
    { hom := default
      inv := default }
state_before: case mpr.intro.intro
C : Type u
inst✝ : Category C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
this : (x y : C) → Unique (x ⟶ y)
⊢ 𝟭 C ≅ (Functor.const C).obj { as := PUnit.unit } ⋙ (Functor.const (Discrete PUnit)).obj p

tactic: apply Functor.pUnitExt
state_before: C : Type u
inst✝ : Category C
h : ∀ (x y : C), Nonempty (Unique (x ⟶ y))
p : C
this : (x y : C) → Unique (x ⟶ y)
⊢ (Functor.const (Discrete PUnit)).obj p ⋙ (Functor.const C).obj { as := PUnit.unit } ≅ 𝟭 (Discrete PUnit)