8.1.3 The universal cover in type theory

8.1.3 The universal cover in type theory

Let us consider how we might express the preceding proof in

type theory

.
We have already remarked that the path

fibration

of

𝕊

1

is represented by the type family

(

x

↦

(

𝖻𝖺𝗌𝖾

=

x

)

)

.
We have also already seen a good candidate for the

universal cover

of

𝕊

1

: it’s none other than the type family

c

:

𝕊

1

→

𝒰

which we defined in

\autoref

sec:pi1s1-initial-thoughts!
By definition, the fiber of this family over

𝖻𝖺𝗌𝖾

is

ℤ

, while the effect of transporting around

𝗅𝗈𝗈𝗉

is to add one — thus it behaves just as we would expect from

\autoref

fig:winding.

However, since we don’t know yet that this family behaves like a universal cover is supposed to (for

instance

, that its

total space

is

simply connected

), we use a different name for it.
For reference, therefore, we repeat the definition.

Definition 8.1.1

(Universal Cover of

S

1

).

Define

code

:

S

1

→

U

by circle-recursion, with

𝖼𝗈𝖽𝖾

⁢

(

𝖻𝖺𝗌𝖾

)

:

≡

ℤ

𝖺𝗉

𝖼𝗈𝖽𝖾

⁢

(

𝗅𝗈𝗈𝗉

)

:=

𝗎𝖺

⁢

(

𝗌𝗎𝖼𝖼

)

.

We emphasize briefly the definition of this family, since it is so different from how one usually defines covering spaces in classical

homotopy theory

.
To define a

function

by circle

recursion

, we need to find a point and a
loop in the codomain. In this case, the codomain is

𝒰

, and the point
we choose is

ℤ

, corresponding to our expectation that the
fiber of the universal cover should be the integers. The loop we choose
is the

successor

/

predecessor

isomorphism

on

ℤ

, which
corresponds to the fact that going around the loop in the base goes up
one level on the helix. Univalence is necessary for this part of the
proof, because we need to convert a

non-trivial

equivalence

on

ℤ

into an

identity

.

We call this the fibration of “codes”, because its

elements

are combinatorial data that act as codes for paths on the circle: the integer

n

codes for the path which loops around the circle

n

times.

From this definition, it is simple to calculate that transporting with

𝖼𝗈𝖽𝖾

takes

𝗅𝗈𝗈𝗉

to the successor function, and

𝗅𝗈𝗈𝗉

-

1

to the predecessor function:

Lemma 8.1.2

.

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

𝖼𝗈𝖽𝖾

⁢

(

𝗅𝗈𝗈𝗉

,

x

)

=

x

+

1

and

transport

code

⁢

(

loop

-

1

,

x

)

=

x

-

1

.

Proof.

For the first equation, we calculate as follows:

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

𝖼𝗈𝖽𝖾

⁢

(

𝗅𝗈𝗈𝗉

,

x

)

=

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

A

↦

A

(

(

𝖼𝗈𝖽𝖾

(

𝗅𝗈𝗈𝗉

)

)

,

x

)

(by \autorefthm:transport-compose)

=

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

A

↦

A

⁢

(

𝗎𝖺

⁢

(

𝗌𝗎𝖼𝖼

)

,

x

)

(by computation for $\mathsf{rec}_{\mathbb{S}^{1}}$)

=

x

+

1

.

(by computation for $\mathsf{ua}$)

The second equation follows from the first, because

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

B

⁢

(

p

,

–

)

and

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

B

⁢

(

p

-

1

,

–

)

are always

inverses

, so

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

𝖼𝗈𝖽𝖾

⁢

(

𝗅𝗈𝗈𝗉

-

1

,

–

)

must be the inverse of

𝗌𝗎𝖼𝖼

.
∎

We can now see what was wrong with our first approach: we defined

f

and

g

only on the fibers

Ω

⁢

(

𝕊

1

)

and

ℤ

, when we should have defined a whole

morphism

of fibrations

over

𝕊

1

.
In type theory, this means we should have defined functions having types

∏

x

:

𝕊

1

(

(

𝖻𝖺𝗌𝖾

=

x

)

→

𝖼𝗈𝖽𝖾

(

x

)

)

and/or

(1)

∏

x

:

𝕊

1

(

𝖼𝗈𝖽𝖾

(

x

)

→

(

𝖻𝖺𝗌𝖾

=

x

)

)

(2)

instead of only the special cases of these when

x

is

𝖻𝖺𝗌𝖾

.
This is also an instance of a common observation in type theory: when attempting to prove something about particular inhabitants of some inductive type, it is often easier to generalize the statement so that it refers to

all

inhabitants of that type, which we can then prove by

induction

.
Looked at in this way, the proof of

Ω

⁢

(

𝕊

1

)

=

ℤ

fits into the same pattern as the

characterization

of the identity types of

coproducts

and

natural numbers

in

\autoref

sec:compute-coprod,

\autoref

sec:compute-nat.

At this point, there are two ways to finish the proof.
We can continue mimicking the classical

argument

by constructing (

1

) or (

2

) (it doesn’t matter which), proving that a

homotopy equivalence

between total spaces induces an equivalence on fibers, and then that the total space of the universal cover is

contractible

.
The first type-theoretic proof of

Ω

⁢

(

𝕊

1

)

=

ℤ

followed this pattern; we call it the

homotopy-theoretic

proof.

Later, however, we discovered that there is an alternative proof, which has a more type-theoretic feel and more closely follows the proofs in

\autoref

sec:compute-coprod,

\autoref

sec:compute-nat.
In this proof, we directly

construct

both (

1

) and (

2

), and prove that they are mutually inverse by calculation.
We will call this the

encode-decode

proof, because we call the functions (

1

) and (

2

)

encode

and

decode

respectively.
Both proofs use the same construction of the cover given above.
Where the classical proof induces an equivalence on fibers from an equivalence between total spaces, the encode-decode proof constructs the inverse map (

decode

) explicitly as a map between fibers.
And where the classical proof uses

contractibility

, the encode-decode proof uses path induction, circle induction, and integer induction.
These are the same tools used to prove contractibility—indeed, path induction

is

essentially contractibility of the path fibration composed with

𝗍𝗋𝖺𝗇𝗌𝗉𝗈𝗋𝗍

—but they are applied in a different way.

Since this is a book about

homotopy type theory

, we present the encode-decode proof first.
A

homotopy

theorist who gets lost is encouraged to skip to the homotopy-theoretic proof (

\autoref

subsec:pi1s1-homotopy-theory).

Title

8.1.3 The universal cover in type theory

\metatable

Generated on Thu Feb 8 19:40:23 2018 by

LaTeXML