{-# OPTIONS --lossy-unification -vtc.def.fun:10 #-}
open import Cat.Instances.Sets.Complete
open import Cat.Bi.Instances.Spans
open import Cat.Bi.Diagram.Monad
open import Cat.Instances.Sets
open import Cat.Bi.Base
open import Cat.Prelude

module Cat.Bi.Diagram.Monad.Spans {β„“} where

Monads in Spans(Sets)πŸ”—

Let C\mathcal{C} be a strict category. Whatever your favourite strict category might be β€” it doesn’t matter in this case. Let C0\mathcal{C}_0 denote its set of objects, and write C(x,y)\mathcal{C}(x, y) for its Hom-family. We know that families are equivalently fibrations, so that we may define

C1=βˆ‘x,y:C0C(x,y), \mathcal{C}_1 = \sum_{x, y : \mathcal{C}_0} \mathcal{C}(x, y)\text{,}

and, since the family is valued in Sets{{\mathbf{Sets}}} and indexed by a set, so is C1\mathcal{C}_1. We can picture C1\mathcal{C}_1 together with the components of its first projection as a span in the category of sets

Under this presentation, what does the composition operation correspond to? Well, it takes something in the object of composable morphisms, a certain subset of C1Γ—C1\mathcal{C}_1 \times \mathcal{C}_1, and yields a morphism, i.e.Β something in C1\mathcal{C}_1. Moreover, this commutes with taking source/target: The source of the composition is the source of its first argument, and the target is the target of its second argument. The key observation, that will lead to a new representation of categories, is that the object of composable morphisms is precisely the composition C1∘C1\mathcal{C}_1 \circ \mathcal{C}_1 in the bicategory Span(Sets){\mathbf{Span}}({{\mathbf{Sets}}})!

Phrased like this, we see that the composition map gives an associative and unital procedure for mapping (C1C1)β‡’C1(\mathcal{C}_1\mathcal{C}_1) {\Rightarrow}\mathcal{C}_1 in a certain bicategory β€” a monad in that bicategory.

Spans[Sets] : Prebicategory _ _ _
Spans[Sets] = Spanᡇ (Sets β„“) Sets-pullbacks

strict-category→span-monad
  : (C : Precategory β„“ β„“) (cset : is-set (C .Ob))
  β†’ Monad Spans[Sets] (el _ cset)
strict-category→span-monad C cset = m where
  open Monad
  open n-Type (el {n = 2} _ cset) using (H-Level-n-type)
  open Precategory.HLevel-instance C
  module C = Precategory C

  homs : Span (Sets β„“) (el _ cset) (el _ cset)
  homs .apex = el (Σ[ x ∈ C .Ob ] Σ[ y ∈ C .Ob ] (C .Hom x y)) (hlevel 2)
  homs .left (x , _ , _) = x
  homs .right (_ , y , _) = y

  mult : _ Sb.β‡’ _
  mult .map ((x , y , f) , (z , xβ€² , g) , p) =
    z , y , subst (Ξ» e β†’ C.Hom e y) p f C.∘ g
  mult .left = refl
  mult .right = refl

  unit : _ Sb.β‡’ _
  unit .map x = x , x , C .id
  unit .left = refl
  unit .right = refl

  m : Monad Spans[Sets] (el (C .Ob) cset)
  m .M = homs
  m .ΞΌ = mult
  m .Ξ· = unit

It is annoying, but entirely straightforward, to verify that the operations mult and unit defined above do constitute a monad in Span(Sets){\mathbf{Span}}({{\mathbf{Sets}}}). We omit the verification here and instruct the curious reader to check the proof on GitHub.

Conversely, if we have an associative and unital method mapping composable morphisms into morphisms, it stands to reason that we should be able to recover a category. Indeed, we can! The verification is once more annoying, but unsurprising. Since it’s less of a nightmare this time around, we include it in full below.

span-monadβ†’strict-category : βˆ€ (C : Set β„“) β†’ Monad Spans[Sets] C β†’ Precategory _ _
span-monad→strict-category C monad = precat where
  open Monad monad

  open n-Type C using (H-Level-n-type)
  open n-Type (M .apex) using (H-Level-n-type)

  precat : Precategory _ _
  precat .Ob = ∣ C ∣
  precat .Hom a b = Ξ£[ s ∈ ∣ M .apex ∣ ] ((M .left s ≑ a) Γ— (M .right s ≑ b))
  precat .Hom-set x y = hlevel 2
  precat .id {x} = Ξ· .map x , sym (happly (Ξ· .left) x) , sym (happly (Ξ· .right) x)
  precat ._∘_ (f , fs , ft) (g , gs , gt) =
      ΞΌ .map (f , g , fs βˆ™ sym gt)
    , sym (happly (ΞΌ .left) _) βˆ™ gs
    , sym (happly (ΞΌ .right) _) βˆ™ ft

The family of morphisms Hom(x,y){\mathbf{Hom}}(x,y) of our recovered category is precisely the fibre of (s,t):C1β†’C0Γ—C0(s,t) : \mathcal{C}_1 \to \mathcal{C}_0 \times \mathcal{C}_0 over the pair x,yx, y. The commutativity conditions for 2-cells in Span(Sets){\mathbf{Span}}({{\mathbf{Sets}}}) implies that source and target are preserved through composition, and that the identity morphism β€” that is, the image of xx under the unit map β€” lies in the fibre over x,xx, x.

The verification follows from the monad laws, and it would be trivial in extensional type theory, but the tradeoff for decidable type-checking is having to munge paths sometimes. This is one of those times:

  precat .idr {x} {y} f = Ξ£-prop-path (Ξ» _ β†’ hlevel 1)
    ( ap (ΞΌ .map) (ap (f .fst ,_) (Ξ£-prop-path (Ξ» _ β†’ C .is-tr _ _) refl))
    βˆ™ happly (ap map ΞΌ-unitr) (f .fst , x , f .snd .fst))
  precat .idl {x} {y} f = Ξ£-prop-path (Ξ» _ β†’ hlevel 1)
    ( ap (ΞΌ .map) (ap (Ξ· .map y ,_) (Ξ£-prop-path (Ξ» _ β†’ C .is-tr _ _) refl))
    βˆ™ happly (ap map ΞΌ-unitl) (y , f .fst , sym (f .snd .snd)))
  precat .assoc f g h = Ξ£-prop-path (Ξ» _ β†’ hlevel 1)
    ( ap (ΞΌ .map) (ap (f .fst ,_) (Ξ£-prop-path (Ξ» _ β†’ hlevel 1)
        (ap (ΞΌ .map) (ap (g .fst ,_)
          (Ξ£-prop-path (Ξ» _ β†’ hlevel 1) (refl {x = h .fst}))))))
    Β·Β· happly (ap map ΞΌ-assoc)
        ( f .fst , (g .fst , h .fst , g .snd .fst βˆ™ sym (h .snd .snd))
        , f .snd .fst βˆ™ sym (g .snd .snd)
        )
    Β·Β· ap (ΞΌ .map) (Ξ£-pathp (ap (ΞΌ .map) (ap (f .fst ,_)
        (Ξ£-prop-path (Ξ» _ β†’ hlevel 1) refl)))
           (Σ-pathp-dep refl (is-prop→pathp (λ _ → hlevel 1) _ _))))