Homotopies
Let's consider the type theory represent of proposition "
Note
Apply AC we introduced in last course:
So we can see there's some relation between
And this relation is what we call homotopy.
Formal definition
For two dependent functions
Here
module _ {l1 l2} {A : Set l1} {B : A → Set l2} where
_~_ : (f g : (x : A) → B x) → Set (l1 ⊔ l2)
f ~ g = (x : A) → f x ≡ g x
Here we can say
Example
neg-bool : Bool → Bool
neg-bool true = false
neg-bool false = true
There's no way can we prove:
Instead, we can define a pointwise identification between the values of
neg-neg-bool : (neg-bool ∘ neg-bool) ~ id
neg-neg-bool false = refl
neg-neg-bool true = refl
Commutativity of Diagrams1
We can use homotopies to express the commutativity of diagrams.
For example, we say that a triangle commutes if it comes equipped with a homotopy
A square is similar:
Here
And we can have homotopies between homotopies:
If
then the type of homotopies
And we can push this further, homotopies of homotopies of homotopies, homotopies4, etc.
Operations on Homotopies
refl-htpy:
inv-htpy:
concat-htpy:
We will often write
refl-htpy : {A : Set} {B : A → Set} (f : (x : A) → B x) → f ~ f
refl-htpy = λ f x → refl
inv-htpy : {A : Set} {B : A → Set} {f g : (x : A) → B x} → f ~ g → g ~ f
inv-htpy htpy = λ x → sym (htpy x)
concat-htpy : {A : Set} {B : A → Set} {f g h : (x : A) → B x} → f ~ g → g ~ h → f ~ h
concat-htpy htpy1 htpy2 = λ x → trans (htpy1 x) (htpy2 x)
_·_ : {A : Set} {B : A → Set} {f g h : (x : A) → B x} → f ~ g → g ~ h → f ~ h
_·_ = concat-htpy
Laws of Homotopies
Homotopies satisfy the groupoid laws, ie. associative, has left and right unit (refl-htpy), left and right inverse law.
assoc-htpy : {A B : Set} {f g h i : A → B} (H : f ~ g) (K : g ~ h) (L : h ~ i) → (((H · K) · L) ~ (H · (K · L)))
assoc-htpy H K L = λ x → trans-assoc (H x) {K x} {L x}
left-unit-htpy : {A B : Set} {f g : A → B} (H : f ~ g) → ((refl-htpy f · H) ~ H)
left-unit-htpy H = λ x → refl
right-unit : {A : Set} {x y : A} {p : x ≡ y} → (trans p (refl {x = y})) ≡ p
right-unit {p = refl} = refl
right-unit-htpy : {A B : Set} {f g : A → B} (H : f ~ g) → ((H · (refl-htpy g)) ~ H)
right-unit-htpy {_} {_} {f} {g} H = λ x → right-unit
right-inv : {A : Set} {x y : A} (p : x ≡ y) → (trans p (sym p)) ≡ refl
right-inv refl = refl
left-inv : {A : Set} {x y : A} (p : x ≡ y) → (trans (sym p) p) ≡ refl
left-inv refl = refl
left-inv-htpy : {A B : Set} {f g : A → B} (H : f ~ g) → (((inv-htpy H) · H) ~ (refl-htpy g))
left-inv-htpy H = λ x → left-inv (H x)
right-inv-htpy : {A B : Set} {f g : A → B} (H : f ~ g) → ((H · (inv-htpy H)) ~ (refl-htpy f))
right-inv-htpy H = λ x → right-inv (H x)
Whiskering
Whiskering operations are operations that allow us to compose homotopies with functions.
- Suppose
for two functions , and let . We define
f-chain-H : {A B C : Set} {f g : A → B} (h : B → C) (H : f ~ g) → ((h ∘ f) ~ (h ∘ g))
f-chain-H h H = λ x → cong h (H x)
- Suppose
and for two functions . We define
H-chain-f : {A B C : Set} {g h : B → C} (H : g ~ h) (f : A → B) → ((h ∘ f) ~ (g ∘ f))
H-chain-f H f = λ x → sym (H (f x))
Bi-invertible maps
We can use homotopies to define sections, retractions and equivalence of a map.
-
A section is a right inverse of some morphism.
For any equivalence
we define to be the section of .sec : {l1 l2 : Level} {A : Set l1} {B : Set l2} (f : A → B) → Set (l1 ⊔ l2) sec {_} {_} {A} {B} f = Σ (B → A) (λ g → ((f ∘ g) ~ id))
-
A retraction is a left inverse of some morphism.
retr : {l1 l2 : Level} {A : Set l1} {B : Set l2} (f : A → B) → Set (l1 ⊔ l2) retr {_} {_} {A} {B} f = Σ (B → A) (λ h → ((h ∘ f) ~ id))
-
equivalence = section + retraction
is-equiv : {l1 l2 : Level} {A : Set l1} {B : Set l2} (f : A → B) → Set (l1 ⊔ l2) is-equiv {_} {_} {A} {B} f = sec f × retr f
Or "f is bi-invertible".
We will write
for the type of all equivalences from to . -
Besides, we can define
:has-inverse : {l1 l2 : Level} {A : Set l1} {B : Set l2} (f : A → B) → Set (l1 ⊔ l2) has-inverse{_} {_} {A} {B} f = Σ (B → A) (λ g → ((f ∘ g) ~ id) × ((g ∘ f) ~ id))
We can prove that
is-equiv-to-has-inverse : {A : Set} {B : Set} {f : A → B} → is-equiv f → has-inverse f
is-equiv-to-has-inverse {f = f} ((r-inv , r-homo), (l-inv , l-homo)) =
r-inv , (r-homo ,
inv-htpy (inv-htpy
l-homo · (
H-chain-f (H-chain-f l-homo r-inv · f-chain-H l-inv r-homo) f
)
)
)
has-inverse-to-is-equiv : {A : Set} {B : Set} {f : A → B} → has-inverse f → is-equiv f
has-inverse-to-is-equiv (inv , (r-homo , l-homo)) = (inv , r-homo) , (inv , l-homo)
Example of Equivalences
Ref section 9.2.9 and 9.2.10 of the book Introduction to Homotopy Type Theory
Laws & Operations on Equivalences
We have
Function Extensionality & Univalence Axiom
Let
With these, we can define function extensionality:
The principle of functional extensionality states that two functions are equal if their values are equal at every argument. —— nLab
Similarly, we can define the univalence axiom (UA):
In intensional type theory, identity types behave like path space objects; this viewpoint is called homotopy type theory. This induces furthermore a notion of homotopy fibers, hence of homotopy equivalences between types.
On the other hand, if type theory contains a universe Type, so that types can be considered as points of Type, then between two types we also have an identity type Paths
. The univalence axiom says that these two notions of “sameness” for types are the same. —— nLab
Identification in Σ-types
We can characterize the identity type of Σ-type as a Σ-type of identity types.
Fix an
Assume
By
Recall the
And we can then define
Eq-Σ : {A : Set} {B : A → Set} (z : Σ A B) (z' : Σ A B) → Set
Eq-Σ {_} {B} z z' = Σ (fst z ≡ fst z') (λ p → transport B p (snd z) ≡ snd z')
To show this is reflexive, we should have a term:
This is easy to construct such a term with a pair of refl
(notice fst
refl
and snd
refl
in this pair is in different types 3):
refl-Eq-Σ : ∀{A : Set} {B : A → Set} (z : Σ A B) → Eq-Σ z z
refl-Eq-Σ z = refl , refl
With path induction4, we can push this a step further to:
pair-Eq : ∀{A : Set} {B : A → Set} {z : Σ A B} {z' : Σ A B} →
(z ≡ z') → Eq-Σ z z'
pair-Eq {_} {_} {z} refl = refl-Eq-Σ z
And reversely:
Eq-pair : ∀{A : Set} {B : A → Set} {z : Σ A B} {z' : Σ A B} →
Eq-Σ z z' → (z ≡ z')
Eq-pair (refl , refl) = refl
And we can find that
inv-l : ∀{A : Set} {B : A → Set} {z : Σ A B} {z' : Σ A B} (w : Eq-Σ z z') →
pair-Eq ( Eq-pair w ) ≡ w
inv-l (refl , refl) = refl
inv-r : ∀{A : Set} {B : A → Set} {z : Σ A B} {z' : Σ A B} (r : z ≡ z') →
Eq-pair ( pair-Eq r ) ≡ r
inv-r refl = refl
So we can find out that
Thus we can form an equivalence between
Materials
Lecture Note
Record on Youtube
todo: DO learn the category theory.
Ref Note 3 if you forget the definition of
You may see a lot of proofs in this section of course are just simple combination of refl
s in different types. When writing Agda code, refl
s' types are omitted, one need to read the type signature of the whole function. Is letting the same notation stands for things in different types and leave the hard work to a type inference program a good idea? Or, should the IDE at least "expand" the type when human beings are reading the code?
It is so easy to write such a proof in Agda, comparing with the difficulty of writing a proof with hands (thinking about applying path induction again and again). I can hardly believe that this proof is correct, but it is just identical to the term on the book, those proof assistant tools are all magic.