module Cat.Connected where

Connected categories🔗

We can straightforwardly adapt the definition of connectedness via propositional truncations from types ( to pregroupoids:

record is-connected-groupoid {o } (C : Precategory o ) : Type (o  ) where
  no-eta-equality
  open Precategory C
  field
    point :  Ob 
    path :  x y   Hom x y 

Note that this definition can be stated without requiring to be a groupoid; however, for general categories, it is too strong: for example, we would like the walking arrow to be connected, but there is no morphism from to

Instead, we say that a precategory is connected if its total localisation is a connected groupoid; in other words, if it has exactly one connected component. Explicitly, this means that it has at least one object, and that every two objects can be connected by a finite zigzag of morphisms.

is-connected-cat :  {o } (C : Precategory o )  Type (o  )
is-connected-cat C = is-connected-groupoid (Localisation C (Total C))

We define some helpers for proving that a concrete category is connected: it suffices to exhibit an object such that any other object is connected to by a zigzag (compare this with pointed connected types!).

module _ {o } {C : Precategory o } (gpd : is-pregroupoid C) where
  open Cat.Morphism C

  mk-connected-groupoid
    : (c : Ob)  (∀ x  Hom c x)
     is-connected-groupoid C
  {-# INLINE mk-connected-groupoid #-}
  mk-connected-groupoid c paths = record where
    point = inc c
    path x y = inc (paths y  gpd (paths x) .is-invertible.inv)

mk-connected-cat
  :  {o } {C : Precategory o } (open Precategory C)
   (c : Ob)  (∀ x  Meander C c x)
   is-connected-cat C
{-# INLINE mk-connected-cat #-}
mk-connected-cat {C = C} = mk-connected-groupoid (Free-groupoid-is-groupoid C)

As a simple example, any category with an initial or terminal object is connected. In particular, the terminal category is connected.1

⊤Cat-is-connected : is-connected-cat ⊤Cat
⊤Cat-is-connected = mk-connected-cat _ λ _  []

module _ {o } {C : Precategory o } where
  private module C = Precategory C

  initial→connected : Initial C  is-connected-cat C
  initial→connected init = mk-connected-cat bot λ _  zig ¡ []
    where open Initial init

  terminal→connected : Terminal C  is-connected-cat C
  terminal→connected term = mk-connected-cat top λ _  zag ! _ []
    where open Terminal term

The opposite of a connected category is again connected.

  ^op-connected : is-connected-cat C  is-connected-cat (C ^op)
  ^op-connected conn .point = conn .point
  ^op-connected conn .path x y =
    Free-groupoid^op C .F₁ <$> conn .path y x

We now show that this definition of connectedness is equivalent to asking for the set of connected components to be contractible. The forward implication easily follows from the elimination principle of zigzags into sets:

  connected→π₀-is-contr : is-connected-cat C  is-contr (π₀ ʻ C)
  connected→π₀-is-contr conn = case conn .point of λ x  contr (inc x)
    (elim! λ y  rec! (Meander-rec-≡ (π₀ C) inc quot) (conn .path x y))

Showing the converse implication is not as straightforward: in order to go from paths in to zigzags, we would like to use the effectivity of quotients, but the relation is not a congruence!2

Luckily, we can define the free congruence generated by two objects are related by this congruence if there merely exists a zigzag between them3. We can then show that the quotient of this congruence is equivalent to so we can conclude that it is contractible and apply effectivity to get a zigzag.

  π₀-is-contr→connected : is-contr (π₀ ʻ C)  is-connected-cat C
  π₀-is-contr→connected π₀-contr = conn where
    R : Congruence  C  (o  )
    R ._∼_ x y         =  Meander C x y 
    R .has-is-prop _ _ = squash
    R .reflᶜ    = inc []
    R ._∙ᶜ_ p q = ∥-∥-map₂ _++_ q p
    R .symᶜ     = ∥-∥-map (reverse C)

    is : Iso (quotient R) (π₀ ʻ C)
    is .fst = Coeq-rec inc (elim! λ x y  Meander-rec-≡ (π₀ C) inc quot)
    is .snd .is-iso.from = Coeq-rec inc λ (x , y , f) 
      quot (inc (zig f []))
    is .snd .is-iso.rinv = elim! λ _  refl
    is .snd .is-iso.linv = elim! λ _  refl

    conn : is-connected-cat C
    conn .point = case π₀-contr .centre of λ { .inc*  inc }
    conn .path x y = effective R
      (is-contr→is-prop (Iso→is-hlevel 0 is π₀-contr) (inc x) (inc y))

  connected≃π₀-is-contr : is-connected-cat C  is-contr (π₀ ʻ C)
  connected≃π₀-is-contr = prop-ext (hlevel 1) (hlevel 1)
    connected→π₀-is-contr π₀-is-contr→connected

Connected categories enjoy the following recursion principle: to define a map where is a connected category and is a set, it suffices to give a map from the objects of that gives the same result for any two objects connected by a morphism.

  connected-∥-∥-rec!
    : is-connected-cat C
      {ℓ'} {X : Type ℓ'}  _ : H-Level X 2 
     (r : C.Ob  X)
     (∀ {x y} (f : C.Hom x y)  r x  r y)
      C.Ob   X
  connected-∥-∥-rec! conn r r-const = ∥-∥-rec-set! r λ x y 
    case conn .path x y of
      Meander-rec-≡ (el! _) r r-const

  1. But the initial category isn’t: even though any of its points would be connected by a zigzag, there are no such points.↩︎

  2. In a general category, it may fail to be symmetric (we call those where it is pregroupoids), and it may fail to be valued in propositions (those are the thin categories).↩︎

  3. Thinking of Zigzag, vaguely, as the reflexive, transitive and symmetric closure of Hom.↩︎