open import Cat.Instances.Functor
open import Cat.Functor.Base
open import Cat.Prelude
open import Cat.Thin

open import Data.Bool

import Cat.Reasoning

module Cat.Instances.Shape.Isomorphism where

The isomorphism categoryπŸ”—

The isomorphism category is the category with two points, along with a unique isomorphism between them.

Iso-poset : Proset lzero lzero
Iso-poset = make-proset {R = R} hlevel! _ _ hlevel! where
  R : Bool β†’ Bool β†’ Type
  R _ _ = ⊀

0β‰…1 : Precategory lzero lzero
0β‰…1 = Iso-poset .Proset.underlying

Note that the space of isomorphisms between any 2 objects is contractible.

0β‰…1-iso-contr : βˆ€ X Y β†’ is-contr (Isomorphism 0β‰…1 X Y)
0β‰…1-iso-contr _ _ .centre =
  0β‰…1.make-iso tt tt (hlevel 1 _ _) (hlevel 1 _ _)
0β‰…1-iso-contr _ _ .paths p =
  0β‰…1.β‰…-pathp refl refl refl

The isomorphism category is strict, as its objects form a set.

0β‰…1-is-strict : is-set 0β‰…1.Ob
0β‰…1-is-strict = hlevel!

The isomorphism category is not univalentπŸ”—

The isomorphism category is the canonical example of a non-univalent category. If it were univalent, then we’d get a path between true and false!

0β‰…1-not-univalent : is-category 0β‰…1 β†’ βŠ₯
0β‰…1-not-univalent is-cat =
  true≠false $ is-cat .to-path $
  0β‰…1-iso-contr true false .centre

Functors out of the isomorphism categoryπŸ”—

One important fact about the isomorphism category is that it classifies isomorphisms in categories, in the sense that functors out of 0β‰…1 into some category C\ca{C} are equivalent to isomorphisms in C\ca{C}.

Isos : βˆ€ {o β„“} β†’ Precategory o β„“ β†’ Type (o βŠ” β„“)
Isos π’ž = Ξ£[ A ∈ π’ž.Ob ] Ξ£[ B ∈ π’ž.Ob ] (A π’ž.β‰… B)
  where module π’ž = Cat.Reasoning π’ž

To prove this, we fix some category C\ca{C}, and construct an isomorphism between functors out of 0β‰…1 and isomorphisms in C\ca{C}.

module _ {o β„“} {π’ž : Precategory o β„“} where
  private
    module π’ž = Cat.Reasoning π’ž
    open Functor
    open π’ž._β‰…_

For the forward direction, we use the fact that all objects in 0β‰…1 are isomorphic to construct an iso between true and false, and then use the fact that functors preserve isomorphisms to obtain an isomorphism in C\ca{C}.

  functorβ†’iso : (F : Functor 0β‰…1 π’ž) β†’ Isos π’ž
  functor→iso F =
    _ , _ , F-map-iso F (0β‰…1-iso-contr true false .centre)

For the backwards direction, we are given an isomorphism X≅YX \cong Y in C\ca{C}. Our functor will map true to XX, and false to YY: this is somewhat arbitrary, but lines up with our choices for the forward direction. We then perform a big case bash to construct the mapping of morphisms, and unpack the components of the provided isomorphism into place. Functoriality follows by the fact that the provided isomorphism is indeed an isomorphism.

  isoβ†’functor : Isos π’ž β†’ Functor 0β‰…1 π’ž
  iso→functor (X , Y , isom) = fun
    where
      fun : Functor _ _
      fun .Fβ‚€ true = X
      fun .Fβ‚€ false = Y
      fun .F₁ {true} {true} _ = π’ž.id
      fun .F₁ {true} {false} _ = to isom
      fun .F₁ {false} {true} _ = from isom
      fun .F₁ {false} {false} _ = π’ž.id
      fun .F-id {true} = refl
      fun .F-id {false} = refl
      fun .F-∘ {true} {true} {z} f g = sym $ π’ž.idr _
      fun .F-∘ {true} {false} {true} f g = sym $ invr isom
      fun .F-∘ {true} {false} {false} f g = sym $ π’ž.idl _
      fun .F-∘ {false} {true} {true} f g = sym $ π’ž.idl _
      fun .F-∘ {false} {true} {false} f g = sym $ invl isom
      fun .F-∘ {false} {false} {z} f g = sym $ π’ž.idr _

Showing that this function is an equivalence is relatively simple: the only tricky part is figuring out which lemmas to use to characterise path spaces!

  iso≃functor : is-equiv isoβ†’functor
  iso≃functor = is-isoβ†’is-equiv (iso functorβ†’iso rinv linv) where
    rinv : is-right-inverse functor→iso iso→functor
    rinv F =
      Functor-path
        (Ξ» { true β†’ refl ; false β†’ refl })
        (Ξ» { {true} {true} _ β†’ sym (F-id F)
           ; {true} {false} tt β†’ refl
           ; {false} {true} tt β†’ refl
           ; {false} {false} tt β†’ sym (F-id F) })

    linv : is-left-inverse functor→iso iso→functor
    linv F = Ξ£-pathp refl $ Ξ£-pathp refl $ π’ž.β‰…-pathp refl refl refl