module Homotopy.Space.Delooping where
Deloopingsπ
A natural question to ask, given that all pointed types have a fundamental group, is whether every group arises as the fundamental group of some type. The answer to this question is βyesβ, but in the annoying way that questions like these tend to be answered: Given any group we construct a type with We call the delooping of
data Deloop : Type β where base : Deloop path : β G β β base β‘ base path-sq : (x y : β G β) β Square refl (path x) (path (x β y)) (path y) squash : is-groupoid Deloop Deloopβ : Typeβ β Deloopβ = Deloop , base
private instance H-Level-Deloop : β {n} β H-Level Deloop (3 + n) H-Level-Deloop = basic-instance 3 squash
The delooping is constructed as a higher inductive type. We have a
generic base
point, and a
constructor expressing that Deloop
is a groupoid; Since it
is a groupoid, it has a set of loops point β‘ point
: this is
necessary, since otherwise we would not be able to prove that
We then have the βinterestingβ higher constructors: path
lets us turn
any element of
to a path point β‘ point
, and path-sq
expresses
that path
is a group
homomorphism. More specifically, path-sq
fills the
square below:
Using the uniqueness result for double composition
,
we derive that path
is a
homomorphism in the traditional sense:
abstract path-β : β x y β path (x β y) β‘ path x β path y path-β x y i j = Β·Β·-unique refl (path x) (path y) (path (x β y) , path-sq x y) (path x β path y , β-filler _ _) i .fst j
And the standard argument shows that path
, being a group
homomorphism, preserves the group identity.
path-unit : path unit β‘ refl path-unit = path unit β‘β¨ sym (β-idr _) β©β‘ path unit β β refl β β‘Λβ¨ apΒ‘ (β-invr _) β©β‘Λ path unit β path unit β sym (path unit) β‘β¨ β-assoc _ _ _ β apβ _β_ (sym (path-β _ _)) refl β©β‘ path β unit β unit β β sym (path unit) β‘β¨ ap! G.idr β©β‘ path unit β sym (path unit) β‘β¨ β-invr _ β©β‘ refl β
We define an elimination principle for Deloop
, which has the following
monstruous type since it works for mapping into arbitrary groupoids. As
usual, if weβre mapping into a family of types thatβs more truncated
(i.e.Β a family of sets or propositions), some of the higher cases become
automatic.
Deloop-elim : β {β'} (P : Deloop β Type β') β (β x β is-groupoid (P x)) β (p : P base) β (ploop : β x β PathP (Ξ» i β P (path x i)) p p) β ( β x y β SquareP (Ξ» i j β P (path-sq x y i j)) (Ξ» _ β p) (ploop x) (ploop (x β y)) (ploop y)) β β x β P x
unquoteDef Deloop-elim = make-elim-with (default-elim-visible into 3) Deloop-elim (quote Deloop) unquoteDecl Deloop-elim-set = make-elim-with (default-elim-visible into 2) Deloop-elim-set (quote Deloop) unquoteDecl Deloop-elim-prop = make-elim-with (default-elim-visible into 1) Deloop-elim-prop (quote Deloop)
We can then proceed to characterise the type point β‘ x
by an encode-decode argument. We define a family Code
, where the fibre over
base
is
definitionally G
; Then we exhibit inverse equivalences
base β‘ x β Code x
and Code x β base β‘ x
, which
fit together to establish G β‘ (base β‘ base)
.
Weβll want to define the family Code
by induction on
Deloop
. First, since we have to map into a groupoid, weβll map into the type
rather than
This takes care of the truncation constructor (which is hidden from the
page since it is entirely formulaic): letβs tackle the rest in order. We
can also handle the base
case, since
Code base = G
was already a part of our specification.
Code : Deloop β Set β Code = go module Code where open is-iso base-case : Set β β£ base-case β£ = β G β base-case .is-tr = hlevel 2
To handle the path case, weβll have to produce, given an element
an equivalence
by univalence, we can then lift this equivalence to a path
which we can use as the path-case
. While there might be
many maps
one is canonical: the Yoneda embedding
map, sending
to
path-case : β G β β base-case β‘ base-case path-case x = n-ua eqv module path-case where remβ : is-iso (_β x) remβ .inv = _β x β»ΒΉ remβ .rinv x = cancelr inversel remβ .linv x = cancelr inverser eqv : β G β β β G β eqv .fst = _ eqv .snd = is-isoβis-equiv remβ open path-case
Finally, we can satisfy the coherence case path-sq
by an
algebraic calculation on paths:
coh : β x y β Square refl (path-case x) (path-case (x β y)) (path-case y) coh x y = n-Type-square $ transport (sym Squareβ‘double-composite-path) $ ua (eqv x) β ua (eqv y) β‘Λβ¨ uaβ β©β‘Λ ua (eqv x βe eqv y) β‘β¨ ap ua (Ξ£-prop-path! (funext Ξ» _ β sym associative)) β©β‘ ua (eqv (x β y)) β
go : Deloop β Set β go base = base-case go (path x i) = path-case x i go (path-sq x y i j) = coh x y i j go (squash x y p q Ξ± Ξ² i j k) = n-Type-is-hlevel 2 (Code x) (Code y) (Ξ» i β Code (p i)) (Ξ» i β Code (q i)) (Ξ» i j β Code (Ξ± i j)) (Ξ» i j β Code (Ξ² i j)) i j k
We can then define the encoding and decoding functions. The encoding
function encode
is given by lifting a
path from Deloop
to Code
. For decoding, we do
induction on Deloop
with
Code x .fst β base β‘ x
as the motive.
opaque encode : β x β base β‘ x β Code Κ» x encode x p = subst (Code Κ»_) p unit decode : β x β Code Κ» x β base β‘ x decode = go where coh : β x β PathP (Ξ» i β Code Κ» path x i β base β‘ path x i) path path coh x i c j = hcomp (β i β¨ β j) Ξ» where k (k = i0) β path (ua-unglue (Code.path-case.eqv x) i c) j k (i = i0) β path-sq c x (~ k) j k (i = i1) β path c j k (j = i0) β base k (j = i1) β path x (i β¨ ~ k) go : β x β Code Κ» x β base β‘ x go base c = path c go (path x i) c = coh x i c go (path-sq x y i j) = is-setβsquarep (Ξ» i j β fun-is-hlevel {A = Code Κ» path-sq x y i j} 2 (Deloop.squash base (path-sq x y i j)) ) (Ξ» i β path) (coh x) (coh (x β y)) (coh y) i j go (squash x y p q Ξ± Ξ² i j k) = is-hlevelβis-hlevel-dep {B = Ξ» x β Code Κ» x β base β‘ x} 2 (Ξ» x β hlevel 3) (go x) (go y) (Ξ» i β go (p i)) (Ξ» i β go (q i)) (Ξ» i j β go (Ξ± i j)) (Ξ» i j β go (Ξ² i j)) (squash x y p q Ξ± Ξ²) i j k
Proving that these are inverses finishes the proof. For one
direction, we use path induction to reduce to the case
decode base (encode base refl) β‘ refl
; A quick argument
tells us that encode base refl
is
the group identity, and since path
is a group
homomorphism, we have path unit = refl
, as required.
opaque unfolding encode encodeβdecode : β {x} (p : base β‘ x) β decode x (encode x p) β‘ p encodeβdecode p = J (Ξ» y p β decode y (encode y p) β‘ p) (ap path (transport-refl _) β path-unit) p
In the other direction, we do induction on deloopings; Since the
motive is a family of propositions, we can use Deloop-elim-prop
instead of the
full Deloop-elim
, which reduces the
goal to proving
decodeβencode : β x (c : Code Κ» x) β encode x (decode x c) β‘ c decodeβencode = Deloop-elim-prop (Ξ» x β (c : Code Κ» x) β encode x (decode x c) β‘ c) (Ξ» x β Ξ -is-hlevel 1 Ξ» _ β Code x .is-tr _ _) Ξ» c β transport-refl _ β G.idl
This completes the proof, and lets us establish that the fundamental
group of Deloop
is G
, which
is what we wanted.
GβΞ©B : β G β β (base β‘ base) GβΞ©B = IsoβEquiv (decode base , iso (encode base) encodeβdecode (decodeβencode base)) Gβ‘ΟβB : G β‘ Οβββ 0 (Deloop , base) Gβ‘ΟβB = β«-Path (total-hom (Ξ» x β inc (path x)) record { pres-β = Ξ» x y β ap β₯_β₯β.inc (path-β _ _) }) (β-is-equiv (GβΞ©B .snd) (β₯-β₯β-idempotent (squash base base)))
Since Deloop
is a groupoid, each of
its loop spaces is automatically a set, so we do not
necessarily need the truncation when taking its fundamental
group. This alternative construction is worth mentioning since it allows
us to trade a proof that encode
preserves multiplication
for proofs that it also preserves the identity, inverses, differences,
etc.
encode-is-group-hom : is-group-hom (ΟβGroupoid.on-Ξ© Deloopβ squash) (G .snd) (encode base) encode-is-group-hom .is-group-hom.pres-β x y = eqv.injectiveβ (eqv.Ξ΅ _) $ path (encode base x β encode base y) β‘β¨ path-β (encode base x) (encode base y) β©β‘ path (encode base x) β path (encode base y) β‘β¨ apβ _β_ (eqv.Ξ΅ _) (eqv.Ξ΅ _) β©β‘ x β y β where module eqv = Equiv GβΞ©B
module encode where open is-group-hom encode-is-group-hom public open Equiv (Equiv.inverse GβΞ©B) public instance H-Level-Deloop : β {n} {β} {G : Group β} β H-Level (Deloop G) (3 + n) H-Level-Deloop {n} = basic-instance 3 squash
For abelian groupsπ
module _ {β} (G : Group β) (ab : is-commutative-group G) where open Group-on (G .snd) open is-group-hom opaque
If
is an abelian group, then we can characterise the loop spaces of
based at totally arbitrary points, rather than the above
characterisation which only applies for the loop space at base
. Our proof
starts with the following immediate observation: multiplication in
is commutative as well.
β-comm : (p q : Path (Deloop G) base base) β p β q β‘ q β p β-comm p q = encode.injective G (encode.pres-β G _ _ Β·Β· ab _ _ Β·Β· sym (encode.pres-β G _ _))
Weβll construct a function that computes the βwinding
numberβ of a loop with
arbitrary base.
winding : {x : Deloop G} β x β‘ x β β G β winding {x = x} = go x module windingβ± where
hl : (x : Deloop G) β is-set (x β‘ x β β G β) hl _ = hlevel 2 interleaved mutual go : (x : Deloop G) β x β‘ x β β G β coherence : Type _ [ i1 β¦ (Ξ» ._ β (x : β G β) β PathP (Ξ» i β path {G = G} x i β‘ path x i β β G β) (encode G base) (encode G base)) ] coh : outS coherence
deg : base β‘ base β β G β deg = encode G base go base loop = deg loop
If the loop is indeed based at the base
point
constructor, then we can appeal to the existing construction; Weβll
abbreviate it as deg
for this construction.
Since our codomain is a set, the higher cases are both handled
mechanically; We omit them from the page in the interest of parsimony.
Weβre left with tackling the path
case, which
means constructing a term exhibiting the coherence
below:
coherence = inS ( β b β PathP (Ξ» i β path b i β‘ path b i β β G β) deg deg)
This condition is a bit funky, since at first glance it looks like
all we must do is equate deg
with itself. However, weβre
doing this over a non-trivial identification in the domain. By
extensionality for dependent functions, the above is equivalent to
showing that deg
produces identical results
given an element
and loops
fiting into a commutative square
Since commutativity of the diagram above says precisely that is the conjugate of by we can reason about conjugation instead; And since weβve shown that this conjugation is just again. That finishes the construction:
abstract coh b = funext-dep Ξ» {xβ} {xβ} p β ap deg $ sym $ xβ β‘Λβ¨ pathpβconj p β©β‘Λ conj (path b) xβ β‘β¨ conj-commutative (β-comm xβ (path b)) β©β‘ xβ β go (path x i) loop = coh x i loop
go (path-sq x y i j) = is-setβsquarep (Ξ» i j β hl (path-sq x y i j)) (Ξ» j β encode G base) (coh x) (coh (x β y)) (coh y) i j go (squash x y p q Ξ± Ξ² i j k) = is-hlevelβis-hlevel-dep 2 (Ξ» x β is-hlevel-suc 2 (hl x)) (go x) (go y) (Ξ» i β go (p i)) (Ξ» j β go (q j)) (Ξ» i j β go (Ξ± i j)) (Ξ» i j β go (Ξ² i j)) (squash x y p q Ξ± Ξ²) i j k {-# DISPLAY windingβ±.go _ p = winding p #-}
We could go on to define the inverse to winding
similar to how we
constructed decode
, but thereβs a trick:
since being an equivalence is a proposition, if we want to show
is an equivalence for arbitrary
it suffices to do so for
but weβve already shown thatβs an equivalence! A similar remark
allows us to conclude that
is a group homomorphism
opaque winding-is-equiv : β x β is-equiv (winding {x}) winding-is-equiv = Deloop-elim-prop G _ (Ξ» _ β hlevel 1) $ Equiv.inverse (GβΞ©B G) .snd winding-is-group-hom : β x β is-group-hom (ΟβGroupoid.on-Ξ© (Deloop G , x) (hlevel 3)) (G .snd) (winding {x}) winding-is-group-hom = Deloop-elim-prop G _ (Ξ» x β hlevel 1) Ξ» where .pres-β x y β encode.pres-β G x y
We can then obtain a nice interface for working with winding
.
module winding {x} where open Equiv (winding , winding-is-equiv x) public open is-group-hom (winding-is-group-hom x) public pathα΅ : (x : Deloop G) β β G β β x β‘ x pathα΅ _ = winding.from
-- Want: pathα΅ base β‘ path, definitionally -- Have: pathα΅ base is a projection from some opaque record -- Soln: Evil hack! opaque unfolding winding-is-equiv winding-is-equiv-base : winding-is-equiv base β‘ Equiv.inverse (GβΞ©B G) .snd winding-is-equiv-base = prop! {-# REWRITE winding-is-equiv-base #-} _ : pathα΅ base β‘ path _ = refl -- MUST check! pathα΅-sq : β (x : Deloop G) g h β Square refl (pathα΅ x g) (pathα΅ x (g β h)) (pathα΅ x h) pathα΅-sq = Deloop-elim-prop G _ (Ξ» x β hlevel 1) Ξ» g h β path-sq g h Deloop-is-connected : β {β} {G : Group β} β is-connectedβ (Deloop G , base) Deloop-is-connected = Deloop-elim-prop _ _ (Ξ» _ β hlevel 1) (inc refl)