definition theorem example

Given an indexed category — a pseudofunctor assigning a category to each object and a reindexing functor to each — the Grothendieck construction is the category whose

  • objects are pairs with and ;
  • morphisms are pairs with in and in ;
  • composition is (using ).

The projection , , is a Grothendieck fibration: every morphism has a cartesian lift ending at , the universal way of pulling back along . The theorem is that this is an equivalence:

with the fibre recovering . For a set-valued functor this is the Category of Elements, and the fibres are discrete.

Sources: Grothendieck, SGA 1 exposé VI; Jacobs, Categorical Logic and Type Theory ch. 1; Spivak, Generalized Lens Categories via functors arXiv:1908.02202 (notes); St Clere Smithe, Bayesian Updates Compose Optically arXiv:2006.01631 (notes) §3; Braithwaite, Hedges & St Clere Smithe arXiv:2305.06112 (notes) Definitions 8–9, 12; Cockett et al., Reverse derivative categories arXiv:1910.07065 (notes) Definitions 25–28.

Grothendieck lenses: the fibrewise opposite

Spivak’s observation (1908.02202) is that taking the Grothendieck construction of the fibrewise opposite yields categories of bidirectional morphisms. A morphism in is a forward map together with a backward map . Special cases:

indexed category backward part
, the simple fibration: objects of , maps cartesian lenses
: maps are functions Bayesian lensesa state-dependent kernel
state-indexed familiesdependent Bayesian lenseskernels whose type depends on the state
the linear-maps fibration of a differential categoryreverse-derivative lenses linear in the second argument

So “lens” is a Grothendieck construction whose fibres are opposite categories: the forward pass lives in the base, the backward pass lives in the fibre over the point the forward pass was computed at. That is why a lens’s backward map always takes the forward input as an extra argument — it is indexed by it.

Fibrations and sections

A section of is a functor with . For a lens-shaped fibration, a section is “a choice of backward pass for every forward map”, and functoriality of is a chain rule:

  • reverse differentiation is a (strict) section (Reverse Derivative Category, Cruttwell et al. Proposition 2.7);
  • Bayesian inversion is a section up to almost-sure equality (Braithwaite et al., Proposition 11; Bayesian Inversion);
  • gradient assignment for parameterized statistical games is only a lax section (AutoBayes Remark 30; Lax Functor).

Examples

  • -style predicates: the subobject fibration of a topos, whose fibres are the posets of predicates on each object (Subobject Classifier).
  • The codomain fibration has fibres the slices ; reindexing is pullback. This is the setting of dependent types and base change.
  • A monoid action , viewed as a functor , has as Grothendieck construction the action groupoid/category (Monoid Action).

Docs: plain Julia — Catlab has no dedicated API for this; related: Catlab v0.16 docs · GATlab standard library

# ∫F for a set-valued indexed family: objects are pairs (c, x ∈ F(c)).
# Here F = fibres of a function π : E → C, i.e. the category of elements of a discrete fibration.
C = [:boat, :car]
F = Dict(:boat => [:sail, :motor], :car => [:petrol, :electric, :hybrid])
total = [(c, x) for c in C for x in F[c]]          # objects of ∫F
length(total)                                       # 5
# The simple fibration: a lens (A,A′) → (B,B′) is a base map f and a fibre map f♯ : A × B′ → A′.
struct SimpleLens{G,P}; get::G; put::P; end
compose(ℓ2::SimpleLens, ℓ1::SimpleLens) =
    SimpleLens(ℓ2.get ∘ ℓ1.get, (a, c′) -> ℓ1.put(a, ℓ2.put(ℓ1.get(a), c′)))
square = SimpleLens(x -> x^2, (x, dy) -> 2x * dy)   # the reverse derivative of x ↦ x²
sine   = SimpleLens(sin, (x, dy) -> cos(x) * dy)
ℓ = compose(sine, square)                           # x ↦ sin(x²) with its backward pass
ℓ.put(1.3, 1.0) ≈ cos(1.3^2) * 2 * 1.3              # the chain rule, as fibre composition: true
import Mathlib
open CategoryTheory
#check Grothendieck                 -- ∫ F for F : C ⥤ Cat (covariant convention)
#check @Grothendieck.forget         -- the projection ∫ F ⥤ C
#check Functor.Elements             -- the set-valued case: the category of elements
-- The simple fibration's Grothendieck construction: lenses with a fibre-indexed backward map.
data Lens a a' b b' = Lens { get :: a -> b, put :: a -> b' -> a' }
 
(|>) :: Lens a a' b b' -> Lens b b' c c' -> Lens a a' c c'
Lens f f' |> Lens g g' = Lens (g . f) (\a c' -> f' a (g' (f a) c'))
 
square, sine :: Lens Double Double Double Double
square = Lens (^ 2) (\x dy -> 2 * x * dy)
sine   = Lens sin (\x dy -> cos x * dy)
-- put (square |> sine) 1.3 1.0 == cos (1.3^2) * 2 * 1.3