Families and fibrations
Introduction
The notion of family of “objects” indexed over an object of the same type is ubiquitous is mathematics and computer science.
It appears everywhere in topology and algebraic geometry, in the form of bundles, covering maps, or, more generally, fibrations.
In type theory, it is the fundamental idea captured by the notion of dependent type, on which Martin-Löf intuitionistic type theory is based.
Definition
Restricting ourselves to \(\mathrm{Set}\), the category of sets, for the time being (and ignoring issues of size), it is straightforward to give a formal definition of what a family of sets is:
Given a set A
, a family over A
is a function from A
to the objects of the category of sets (or equivalently, on the other side of the adjunction, a functor from A
regarded as a discrete category to \(\mathrm{Set}\)).
This is a perfectly valid definition, but it has two problems:
It can be awkward to work with functions between objects of different “sorts” (like sets and universes).
It is not clear how to generalize the idea to other categories, like \(\mathrm{Top}\) (the category of topological spaces and continuous maps), for example. In fact, we would like a family of spaces to be “continuous” in some sense, but in order for that to make sense, we would need to define a topology on the class of topological spaces.
Display maps
Fortunately, there is a very simple construction that helps bringing this definition to a form which is much easier to work with.
Let’s start with a family of sets B
over A
, defined as above: B : A → Set
.
Define the “total space” of the family as the disjoint union (or dependent sum) of all the sets of the family (I’ll use type theoretic notation from now on):
E = Σ (a : A) . B a
The fibration (or display map) associated to the family B
is defined to be the first projection:
proj₁ : E → A
So far, we haven’t done very much. The interesting observation is that we can always recover a family of sets from any function E → A
.
In fact, suppose that now E
is any set, and p : E → A
any function. We can define a family of sets:
B : A → Set
B a = p ⁻¹ a
as the function that associates to each point in A
, its inverse image (or fiber) in E
.
It is now straightforward to check that these two mappings between families and fibrations are inverses of one another.
Intuitively, given a family B
, the corresponding fibration maps each element of all possible sets in the family to its “index” in A
. Viceversa, given a fibration p : E → A
, the corresponding family is just the family of fibers of p
.
Here is formalization in Agda of this correspondence as an isomorphism between families and fibrations. This uses agda-base instead of the standard library, as it needs univalence in order to make the isomorphism explicit.
Examples of constructions
Once we understand how families and fibrations are really two views of the same concept, we can look at a number of constructions for families, and check how they look like in the world of fibrations.
Dependent sum
The simplest construction is the total space:
E = Σ (x : A). B x
As we already know, this corresponds to the domain of the associated fibration.
Dependent product
Given a family of sets B
over A
, a choice function is a function that assigns to each element x
of A
, an element y
of B x
. This is called a dependent function in type theory.
The corresponding notion for a fibration p : E → A
is a function s : A → E
such that for each x : A
, the index of s x
is exactly x
. In other words, p ∘ s ≡ id
, i.e. s
is a section of p
.
The set of such sections is called the dependent product of the family B
.
Pullbacks
Let A
and A'
be two sets, and B
a family over A
. Suppose we have a function
r : A' → A
We can easily define a family B'
over A'
by composing with r
:
B' : A' → Set
B' x = B (r x)
What does the fibration p' : E' → A'
associated to B'
look like in terms of the fibration p : E → A
associated to B
?
Well, given an element b
in the total space of B'
, b
is going to be in B' x
for some x : A'
. Since B' x ≡ B (r x)
by definition, b
can also be regarded as an element of the total space of B
. So we have a map s : E' → E
, and we can draw the following diagram:
The commutativity of this diagram follows from the immediate observation that the index above s b
is exactly r x
.
Now, given elements x : A'
, and b : E
, saying that p b ≡ r x
is equivalent to saying that b
is in B (r x)
. In that case, b
can be regarded as an element of B' x
, which means that there exists a b'
in E'
such that p' b' ≡ x
and s b' ≡ b
.
What this says is that the above diagram is a pullback square.
Adjoints
It is important to note that the previous constructions are related in interesting ways.
Let’s look at a simple special case of the pullback construction, i.e. when B
is a trivial family of just one element. That means that the display map p
associated to B
is the canonical map
p : B → 1
So, if A'
is any other type, we get that the pullback of p
along the unique map r : A' → 1
is the product B × A
.
This defines a functor
\[ A^\ast : \mathrm{Set} → \mathrm{Set}/A \]
where \(\mathrm{Set}/A\) denotes the slice category of sets over A
. Furthermore, the dependent product and dependent sum constructions defined above give rise to functors:
\[ Σ_A, Π_A : \mathrm{Set}/A → \mathrm{Set} \]
Now, it is clear that, given a fibration p : X → A
and a set Y
, functions X → Y
are the same as morphisms X → Y × A
in the slice category. So \(Σ_A\) is left adjoint to \(A^\ast\).
Dually, functions from Y
to the set of sections of p
correspond to functions Y × A → X
in the slice category, thus giving an adjuction between \(A^*\) and \(Π_A\).
So we have the following chain of adjunctions:
\[ Σ_A \vdash A^* \vdash Π_A \]
Conclusion
The correspondence between indexed families and fibrations exemplified here extends well beyond the category of sets, and can be abstracted using the notions of Cartesian morphisms and fibred categories.
In type theory, it is useful to think of this correspondence when working with models of dependently typed theories in locally cartesian closed categories, and I hope that the examples given here show why slice categories and pullback functors play an important role in that setting.
Comments