module Cat.Diagram.Separator {o } (C : Precategory o ) where

Separating objects🔗

One of key property of is that we can demonstrate the equality of two functions by showing that they are equal pointwise. Categorically, this is equivalent to saying that we can determine the equality of two morphisms in solely by looking at global elements This is not the case for general categories equipped with a terminal object: the category of groups has a terminal object (the zero group), yet maps out of the zero group are unique1! In light of this, we can generalize the role that plays in to obtain the notion of separating object:

A separating object or separator is an object that lets us determine equality of morphisms solely by looking at the elements of Explicitly, is a separator if: - For every if for every then

In analogy to global elements, we will call morphisms out of a separator elements.

\ Warning

Some authors (notably (Borceux 1994)) use the term “generator” to in place of separator.

is-separator : Ob  Type _
is-separator s =
   {x y} {f g : Hom x y}
   (∀ (e : Hom s x)  f  e  g  e)
   f  g

Equivalently, an object is a separator if the hom functor is faithful. A good way to view this condition is that it ensures that the elements functor to be somewhat well-behaved.

separator→faithful :  {s}  is-separator s  is-faithful (Hom-from C s)
separator→faithful sep p = sep (happly p)

faithful→separator :  {s}  is-faithful (Hom-from C s)  is-separator s
faithful→separator faithful p = faithful (ext p)

Intuitively, a separator gives us an internal version of function extensionality, with pointwise equality replaced by equality. We can make this formal by showing that a separator gives us an identity system for morphisms in

separator-identity-system
  :  {s x y}
   is-separator s
   is-identity-system {A = Hom x y}
       f g   (e : Hom s x)  f  e  g  e)
       f e  refl)
separator-identity-system separate =
  set-identity-system  _ _  hlevel 1) separate

Separating families🔗

Many categories lack a single separating object but do have a family of separating objects The canonical example is the category of presheaves: we cannot determine equality of natural transformations by looking at all maps for a single but we can if we look at all maps This leads us to the following notion:

A separating family is a family of objects such that for every if for every and every then

is-separating-family :  {ℓi} {Idx : Type ℓi}  (Idx  Ob)  Type _
is-separating-family s =
   {x y} {f g : Hom x y}
   (∀ {i} (eᵢ : Hom (s i) x)  f  eᵢ  g  eᵢ)
   f  g

Equivalently, a family of objects is a separating family if the hom functors are jointly faithful.

separating-family→jointly-faithful
  :  {ℓi} {Idx : Type ℓi} {sᵢ : Idx  Ob}
   is-separating-family sᵢ
   is-jointly-faithful  i  Hom-from C (sᵢ i))
separating-family→jointly-faithful separates p = separates λ eᵢ  p _ $ₚ eᵢ

jointly-faithful→separating-family
  :  {ℓi} {Idx : Type ℓi} {sᵢ : Idx  Ob}
   is-jointly-faithful  i  Hom-from C (sᵢ i))
   is-separating-family sᵢ
jointly-faithful→separating-family faithful p = faithful λ i  funext p

Most of the theory of separating object generalizes directly to separating families. For instance, separating families also induce an identity system on morphisms.

separating-family-identity-system
  :  {ℓi} {Idx : Type ℓi} {sᵢ : Idx  Ob} {x y}
   is-separating-family sᵢ
   is-identity-system {A = Hom x y}
       f g   {i} (eᵢ : Hom (sᵢ i) x)  f  eᵢ  g  eᵢ)
       f e  refl)
separating-family-identity-system separate =
  set-identity-system  _ _  hlevel 1) separate

Separators and copowers🔗

Recall that if is copowered, then we can construct an approximation of any object by taking the copower for some Intuitively, this approximation works by adding a copy of for every generalized element In the category of sets, is the coproduct of copies of which is isomorphic to

Generalizing from we can attempt to approximate any object by taking the copower where is a separating object. While we don’t quite get an isomorphism we can show that the universal map out of the copower is an epimorphism.

To see this, let such that is a separating object, so it suffices to show that for every generalized element However, which immediately gives us by our hypothesis.

module _
  (copowers : (I : Set )  has-coproducts-indexed-by C  I )
  where
  open Copowers copowers

  separator→epi :  {s x}  is-separator s  is-epic (⊗!.match (Hom s x) s λ f  f)
  separator→epi {s} {x} separate f g p = separate λ e 
    f  e                                     ≡⟨ pushr (sym (⊗!.commute _ _)) 
    (f  (⊗!.match _ _ λ f  f))  ⊗!.ι _ _ e ≡⟨ p ⟩∘⟨refl 
    (g  (⊗!.match _ _ λ f  f))  ⊗!.ι _ _ e ≡⟨ pullr (⊗!.commute _ _) 
    g  e                                     

Conversely, if the canonical map is an epimorphism for every then is a separator.

Let such that for every Note that by our hypothesis, so Moreover, is an epi, so

  epi→separator :  {s}  (∀ {x}  is-epic (⊗!.match (Hom s x) s λ f  f))  is-separator s
  epi→separator epic {f = f} {g = g} p =
    epic f g $ ⊗!.unique₂ _ _ λ e 
      sym (assoc _ _ _)
       p _
       assoc _ _ _

A similar result holds for separating families, insofar that a family is a separating family if and only if the canonical map is an epimorphism.

  separating-family→epi
    :  (Idx : Set ) (sᵢ :  Idx   Ob)
     is-separating-family sᵢ
      {x}  is-epic (∐!.match (Σ[ i   Idx  ] Hom (sᵢ i) x) (sᵢ  fst) snd)

  epi→separating-family
    :  (Idx : Set )
     (sᵢ :  Idx   Ob)
     (∀ {x}  is-epic (∐!.match (Σ[ i   Idx  ] Hom (sᵢ i) x) (sᵢ  fst) snd))
     is-separating-family sᵢ
The proof is almost identical to the single-object case, so we omit the details.
  separating-family→epi Idx sᵢ separate f g p = separate λ {i} eᵢ 
    f  eᵢ                                     ≡⟨ pushr (sym (∐!.commute _ _)) 
    (f  ∐!.match _ _ snd)  ∐!.ι _ _ (i , eᵢ) ≡⟨ p ⟩∘⟨refl 
    (g  ∐!.match _ _ snd)  ∐!.ι _ _ (i , eᵢ) ≡⟨ pullr (∐!.commute _ _) 
    g  eᵢ                                     

  epi→separating-family Idx sᵢ epic {f = f} {g = g} p =
    epic f g $ ∐!.unique₂ _ _ λ (i , eᵢ) 
      sym (assoc _ _ _)
       p _
       assoc _ _ _

Existence of separating families🔗

If has equalisers and is conservative, then is a separating family.

equalisers+conservative→separator
  :  {s}
   has-equalisers C
   is-conservative (Hom-from C s)
   is-separator s

Let and suppose that for every We can then form the equaliser of and Note that if is invertible, then as holds by virtue of being an equaliser.

equalisers+conservative→separator equalisers f∘-conservative {f = f} {g = g} p =
  invertible→epic equ-invertible f g Eq.equal
  where
    module Eq = Equaliser (equalisers f g)

Moreover, is conservative, so it suffices to prove that precomposition of with an element is an equivalence. This follows immediately from the universal property of equalisers!

    equ-invertible : is-invertible Eq.equ
    equ-invertible =
      f∘-conservative $
      is-equiv→is-invertible $
      is-iso→is-equiv $ iso
         e  Eq.universal (p e))
         e  Eq.factors)
         h  sym (Eq.unique refl))

A similar line of argument lets us generalize this result to separating families.

equalisers+jointly-conservative→separating-family
  :  {κ} {Idx : Type κ} {sᵢ : Idx  Ob}
   has-equalisers C
   is-jointly-conservative  i  Hom-from C (sᵢ i))
   is-separating-family sᵢ
The proof is more-or-less the same, so we omit the details.
equalisers+jointly-conservative→separating-family
  equalisers fᵢ∘-conservative {f = f} {g = g} p =
  invertible→epic equ-invertible f g Eq.equal
  where
    module Eq = Equaliser (equalisers f g)

    equ-invertible : is-invertible Eq.equ
    equ-invertible =
      fᵢ∘-conservative λ i 
      is-equiv→is-invertible $
      is-iso→is-equiv $ iso
         eᵢ  Eq.universal (p eᵢ))
         eᵢ  Eq.factors)
         h  sym (Eq.unique refl))

Our next result lets us relate separating objects and separating families. Clearly, a separating object yields a separating family; when does the converse hold?

One possible scenario is that there is an object such that every comes equipped with a section/retraction pair To see why, let and suppose that for every As is a separating family, it suffices to show that for every

Next, note that as and are a section/retraction pair. Moreover, so

by our hypothesis. Finally, we can use the fact that and are a section/retraction pair to observe that completeing the proof

retracts+separating-family→separator
  :  {κ} {Idx : Type κ} {sᵢ : Idx  Ob} {x : Ob}
   is-separating-family sᵢ
   (fᵢ :  i  Hom (sᵢ i) x)
   (∀ i  has-retract (fᵢ i))
   is-separator x
retracts+separating-family→separator separate fᵢ r {f = g} {g = h} p =
  separate λ {i} eᵢ 
    g  eᵢ                         ≡˘⟨ pullr (cancelr (r i .is-retract)) ≡˘
    (g  eᵢ  r i .retract)  fᵢ i ≡⟨ ap₂ _∘_ (p (eᵢ  r i .retract)) refl 
    (h  eᵢ  r i .retract)  fᵢ i ≡⟨ pullr (cancelr (r i .is-retract)) 
    h  eᵢ                         

We can immediately use this result to note that a separating family can be turned into a separating object, provided that:

  1. The separating family is indexed by a discrete type.
  2. The coproduct of exists.
  3. has a zero object.
zero+separating-family→separator
  :  {κ} {Idx : Type κ} {sᵢ : Idx  Ob} {∐s : Ob} {ι :  i  Hom (sᵢ i) ∐s}
    Idx-Discrete : Discrete Idx 
   Zero C
   is-separating-family sᵢ
   is-indexed-coproduct C sᵢ ι
   is-separator ∐s

This follows immediately from the fact that coproduct inclusions have retracts when hypotheses (1) and (3) hold.

zero+separating-family→separator {ι = ι} z separates coprod =
  retracts+separating-family→separator separates ι $
  zero→ι-has-retract C coprod z

Dense separators🔗

As noted in the previous sections, separating objects categorify the idea that the behaviour of functions can be determined by their action on elements. However, note that a separating object only lets us equate morphisms; ideally, we would be able to construct a morphism by giving a function on elements as well! This desire leads directly to the notion of a dense separating object.

An object dense separating object is a dense separating object or dense separator if:

  • For all a function induces a morphism and
  • For every generalized element and
  • The map is universal among all such maps.
record is-dense-separator (s : Ob) : Type (o  ) where
  no-eta-equality
  field
    universal
      :  {x y}
       (eta : Hom s x  Hom s y)
       Hom x y
    commute
      :  {x y}
       {eta : Hom s x  Hom s y}
       {e : Hom s x}
       universal eta  e  eta e
    unique
      :  {x y}
       {eta : Hom s x  Hom s y}
       (h : Hom x y)
       (∀ (e : Hom s x)  h  e  eta e)
       h  universal eta

As the name suggests, dense separators are separators: this follows directly from the uniqueness of the universal map.

  separate
    :  {x y}
     {f g : Hom x y}
     (∀ (e : Hom s x)  f  e  g  e)
     f  g
  separate p = unique _ p  sym (unique _ λ _  refl)

Equivalently, an object is a dense separator if the hom functor is fully faithful.

  dense-separator→ff
    :  {s}
     is-dense-separator s
     is-fully-faithful (Hom-from C s)
  dense-separator→ff dense =
    is-iso→is-equiv $ iso
      (dense .universal)
       eta  ext λ e  dense .commute)
       h  sym (dense .unique h  _  refl)))

  ff→dense-separator
    :  {s}
     is-fully-faithful (Hom-from C s)
     is-dense-separator s
  ff→dense-separator ff .universal =
    equiv→inverse ff
  ff→dense-separator ff .commute {eta = eta} {e = e} =
    equiv→counit ff eta $ₚ e
  ff→dense-separator ff .unique h p =
    sym (equiv→unit ff h)  ap (equiv→inverse ff) (ext p)

Furthermore, if is a dense separator, then every object is a copower This can be seen as providing a particularly strong form of the coyoneda lemma for as every object can be expressed as a colimit of a single object. Alternatively, this is a categorification of the idea that every set is a coproduct of copies of the point!

dense-separator→coyoneda
  :  {s}
   is-dense-separator s
    (x : Ob)
   is-indexed-coproduct C {Idx = Hom s x}  _  s)  f  f)
dense-separator→coyoneda {s = s} dense x = is-copower where
  module dense = is-dense-separator dense
  open is-indexed-coproduct

  is-copower : is-indexed-coproduct C {Idx = Hom s x}  _  s)  f  f)
  is-copower .match  = dense.universal
  is-copower .commute = dense.commute
  is-copower .unique h p = dense.unique _ p

The converse is also true: if every object is a copower then is a dense separator.

coyoneda→dense-separator
  :  {s}
   (∀ (x : Ob)  is-indexed-coproduct C {Idx = Hom s x}  _  s)  f  f))
   is-dense-separator s
coyoneda→dense-separator {s} coyo = dense where
  module coyo (x : Ob) = is-indexed-coproduct (coyo x)
  open is-dense-separator

  dense : is-dense-separator s
  dense .universal = coyo.match _
  dense .commute = coyo.commute _
  dense .unique h p = coyo.unique _ _ p

Dense separating families🔗

Next, we extend the notion of a dense separator to a family of objects.

A family of objects is a dense separating family if:

  • functions with induce maps and
  • For every and
  • The map is universal among all such maps.
record is-dense-separating-family
  {Idx : Type }
  (sᵢ : Idx  Ob)
  : Type (o  ) where
  no-eta-equality
  field
    universal
      :  {x y}
       (eta :  i  Hom (sᵢ i) x  Hom (sᵢ i) y)
       (∀ {i j} (f : Hom (sᵢ j) x) (g : Hom (sᵢ i) (sᵢ j))  eta i (f  g)  eta j f  g)
       Hom x y
    commute
      :  {x y}
       {eta :  i  Hom (sᵢ i) x  Hom (sᵢ i) y}
       {p :  {i j} (f : Hom (sᵢ j) x) (g : Hom (sᵢ i) (sᵢ j))  eta i (f  g)  eta j f  g}
       {i : Idx} {eᵢ : Hom (sᵢ i) x}
       universal eta p  eᵢ  eta i eᵢ
    unique
      :  {x y}
       {eta :  i  Hom (sᵢ i) x  Hom (sᵢ i) y}
       {p :  {i j} (f : Hom (sᵢ j) x) (g : Hom (sᵢ i) (sᵢ j))  eta i (f  g)  eta j f  g}
       (h : Hom x y)
       (∀ (i : Idx)  (eᵢ : Hom (sᵢ i) x)  h  eᵢ  eta i eᵢ)
       h  universal eta p

Like their single-object counterparts, dense separating families are also separating families; this follows immediately from the uniqueness of the universal map.

  separate
    :  {x y}
     {f g : Hom x y}
     (∀ (i : Idx) (eᵢ : Hom (sᵢ i) x)  f  eᵢ  g  eᵢ)
     f  g
  separate p =
    unique {p = λ _ _  assoc _ _ _} _ p
     sym (unique _ λ _ _  refl)

Equivalently, a dense separating family is an family such that the functors are jointly fully faithful. Unfortunately, we need to jump through some hoops to construct the appropriate functor from the full subcategory generated by into

  jointly-ff→dense-separating-family
    : is-jointly-fully-faithful (よcov C F∘ Functor.op (Forget-family {C = C} sᵢ))
     is-dense-separating-family sᵢ
  jointly-ff→dense-separating-family joint-ff .universal eta p =
    equiv→inverse joint-ff λ where
      .η  eta
      .is-natural _ _ g  ext λ f  p f g
  jointly-ff→dense-separating-family joint-ff .commute {i = i} {eᵢ = eᵢ} =
    equiv→counit joint-ff _ ηₚ i $ₚ eᵢ
  jointly-ff→dense-separating-family joint-ff .unique h p =
    sym (equiv→unit joint-ff h)  ap (equiv→inverse joint-ff) (ext p)

  dense-separating-family→jointly-ff
    : is-dense-separating-family sᵢ
     is-jointly-fully-faithful (よcov C F∘ Functor.op (Forget-family {C = C} sᵢ))
  dense-separating-family→jointly-ff dense =
    is-iso→is-equiv $ iso
       α  dense .universal (α .η)  f g  α .is-natural _ _ g $ₚ f))
       α  ext λ i eᵢ  dense .commute)
      λ h  sym (dense .unique h λ i eᵢ  refl)

We can also express this universality using the language of colimits. In particular, if is a dense separating family, then every object of can be expressed as a colimit over the diagram that takes a map to its domain.

  Approx :  x  Functor (Forget-family {C = C} sᵢ  x) C
  Approx x = Forget-family sᵢ F∘ Dom _ _

  is-dense-separating-family→coyoneda
    : is-dense-separating-family sᵢ
      (x : Ob)  is-colimit (Approx x) x θ↘

First, note that we have a canonical cocone that takes an object in slice to itself.

  is-dense-separating-family→coyoneda dense x = to-is-colimitp colim refl where
    module dense = is-dense-separating-family dense
    open make-is-colimit

    colim : make-is-colimit (Approx x) x
    colim .ψ x = x .map
    colim .commutes f = f .sq  idl _

Moreover, this cocone is universal: given another cocone over we can form a map by using the universal property of dense separating families.

    colim .universal eps p =
      dense.universal
         i fᵢ  eps (↓obj fᵢ))
         f g  sym (p (↓hom (sym (idl _)))))
    colim .factors {j} eps p =
      dense.universal _ _  colim .ψ j ≡⟨ dense.commute 
      eps (↓obj (j .map))             ≡⟨ ap eps (↓Obj-path _ _ refl refl refl) 
      eps j                           
    colim .unique eta p other q = dense.unique other  i fᵢ  q (↓obj fᵢ))

As expected, the converse also holds: the proof is more or less the previous proof in reverse, so we do not comment on it too deeply.

  coyoneda→is-dense-separating-family
    : (∀ (x : Ob)  is-colimit (Approx x) x θ↘)
     is-dense-separating-family sᵢ
  coyoneda→is-dense-separating-family colim = dense where
    module colim {x} = is-colimit (colim x)
    open is-dense-separating-family

    dense : is-dense-separating-family sᵢ
    dense .universal eta p =
      colim.universal
         f  eta _ (f .map))
         γ  sym (p _ _)  ap (eta _) (γ .sq  idl _))
    dense .commute {eᵢ = eᵢ} =
      colim.factors {j = ↓obj eᵢ} _ _
    dense .unique h p =
      colim.unique _ _ _ λ j  p _ (j .map)

  1. In other words, the zero group is a zero object.↩︎


References