This commit is contained in:
parent
85c10d012b
commit
531b33442d
3 changed files with 176 additions and 0 deletions
|
@ -44,6 +44,7 @@ const remarkAgda: RemarkPlugin = ({ base, publicDir }: Options) => {
|
||||||
`--html-dir=${agdaOutDir}`,
|
`--html-dir=${agdaOutDir}`,
|
||||||
"--highlight-occurrences",
|
"--highlight-occurrences",
|
||||||
"--html-highlight=code",
|
"--html-highlight=code",
|
||||||
|
"--allow-unsolved-metas",
|
||||||
path,
|
path,
|
||||||
],
|
],
|
||||||
{},
|
{},
|
||||||
|
|
|
@ -49,3 +49,26 @@ transport {l₁} {l₂} {A} {x} {y} P refl = id
|
||||||
infix 4 _≢_
|
infix 4 _≢_
|
||||||
_≢_ : ∀ {A : Set} → A → A → Set
|
_≢_ : ∀ {A : Set} → A → A → Set
|
||||||
x ≢ y = ¬ (x ≡ y)
|
x ≢ y = ¬ (x ≡ y)
|
||||||
|
|
||||||
|
module dependent-product where
|
||||||
|
infixr 4 _,_
|
||||||
|
infixr 2 _×_
|
||||||
|
|
||||||
|
record Σ {l₁ l₂} (A : Set l₁) (B : A → Set l₂) : Set (l₁ ⊔ l₂) where
|
||||||
|
constructor _,_
|
||||||
|
field
|
||||||
|
fst : A
|
||||||
|
snd : B fst
|
||||||
|
open Σ
|
||||||
|
{-# BUILTIN SIGMA Σ #-}
|
||||||
|
syntax Σ A (λ x → B) = Σ[ x ∈ A ] B
|
||||||
|
|
||||||
|
_×_ : {l : Level} (A B : Set l) → Set l
|
||||||
|
_×_ A B = Σ A (λ _ → B)
|
||||||
|
open dependent-product public
|
||||||
|
|
||||||
|
_∘_ : {A B C : Set} (g : B → C) → (f : A → B) → A → C
|
||||||
|
(g ∘ f) a = g (f a)
|
||||||
|
|
||||||
|
_∼_ : {A B : Set} (f g : A → B) → Set
|
||||||
|
_∼_ {A} f g = (x : A) → f x ≡ g x
|
||||||
|
|
152
src/content/posts/2024-06-28-boolean-equivalences.lagda.md
Normal file
152
src/content/posts/2024-06-28-boolean-equivalences.lagda.md
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
---
|
||||||
|
title: "Boolean equivalences"
|
||||||
|
slug: 2024-06-28-boolean-equivalences
|
||||||
|
date: 2024-06-28T21:37:04.299Z
|
||||||
|
tags: ["agda", "type-theory", "hott"]
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
||||||
|
This post is about a problem I recently proved that seemed simple going in, but
|
||||||
|
I struggled with it for quite a while. The problem statement is as follows:
|
||||||
|
|
||||||
|
Show that:
|
||||||
|
|
||||||
|
$$
|
||||||
|
(2 \simeq 2) \simeq 2
|
||||||
|
$$
|
||||||
|
|
||||||
|
This problem is exercise 2.13 of the [Homotopy Type Theory book][book]. If you
|
||||||
|
are planning to attempt this problem, spoilers ahead!
|
||||||
|
|
||||||
|
[book]: https://homotopytypetheory.org/book/
|
||||||
|
|
||||||
|
<small>The following line imports some of the definitions used in this post.</small>
|
||||||
|
|
||||||
|
```
|
||||||
|
open import Prelude
|
||||||
|
```
|
||||||
|
|
||||||
|
## The problem explained
|
||||||
|
|
||||||
|
With just the notation, the problem may not be clear.
|
||||||
|
$2$ represents the set with only 2 elements in it, which is the booleans. The
|
||||||
|
elements of $2$ are $\textrm{true}$ and $\textrm{false}$.
|
||||||
|
In this expression, $\simeq$ denotes [_homotopy equivalence_][1] between sets,
|
||||||
|
which you can think of as an isomorphism.
|
||||||
|
For some function $f : A \rightarrow B$, we say that $f$ is an equivalence if:
|
||||||
|
|
||||||
|
[1]: https://en.wikipedia.org/wiki/Homotopy#Homotopy_equivalence
|
||||||
|
|
||||||
|
- there exists a $g : B \rightarrow A$
|
||||||
|
- $f \circ g$ is homotopic to the identity map $\textrm{id}_B : B \rightarrow B$
|
||||||
|
- $g \circ f$ is homotopic to the identity map $\textrm{id}_A : A \rightarrow A$
|
||||||
|
|
||||||
|
We can write this in Agda like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
record isEquiv {A B : Set} (f : A → B) : Set where
|
||||||
|
constructor mkEquiv
|
||||||
|
field
|
||||||
|
g : B → A
|
||||||
|
f∘g : (f ∘ g) ∼ id
|
||||||
|
g∘f : (g ∘ f) ∼ id
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, the expression $2 \simeq 2$ simply expresses an equivalence between the
|
||||||
|
boolean set to itself. Here's an example of a function that satisfies this equivalence:
|
||||||
|
|
||||||
|
```
|
||||||
|
bool-id : Bool → Bool
|
||||||
|
bool-id b = b
|
||||||
|
```
|
||||||
|
|
||||||
|
We can prove that it satisfies the equivalence, by giving it an inverse function
|
||||||
|
(itself), and proving that the inverse is homotopic to identity (which is true
|
||||||
|
definitionally):
|
||||||
|
|
||||||
|
```
|
||||||
|
bool-id-eqv : isEquiv bool-id
|
||||||
|
bool-id-eqv = mkEquiv bool-id id-homotopy id-homotopy
|
||||||
|
where
|
||||||
|
id-homotopy : (bool-id ∘ bool-id) ∼ id
|
||||||
|
id-homotopy _ = refl
|
||||||
|
```
|
||||||
|
|
||||||
|
We can package these together into a single definition that combines the
|
||||||
|
function along with proof of its equivalence properties using a dependent
|
||||||
|
pair[^1]:
|
||||||
|
|
||||||
|
[^1]: A dependent pair (or $\Sigma$-type) is like a regular pair $\langle x, y\rangle$, but where $y$ can depend on $x$.
|
||||||
|
For example, $\langle x , \textrm{isPrime}(x) \rangle$.
|
||||||
|
In this case it's useful since we can carry the equivalence information along with the function itself.
|
||||||
|
This type is rather core to Martin-Löf Type Theory, you can read more about it [here][dependent-pair].
|
||||||
|
|
||||||
|
[dependent-pair]: https://en.wikipedia.org/wiki/Dependent_type#%CE%A3_type
|
||||||
|
|
||||||
|
```
|
||||||
|
_≃_ : (A B : Set) → Set
|
||||||
|
A ≃ B = Σ (A → B) (λ f → isEquiv f)
|
||||||
|
```
|
||||||
|
|
||||||
|
<small>Hint: (click the $\Sigma$ to see how it's defined!)</small>
|
||||||
|
|
||||||
|
This gives us an equivalence:
|
||||||
|
|
||||||
|
```
|
||||||
|
bool-eqv : Bool ≃ Bool
|
||||||
|
bool-eqv = bool-id , bool-id-eqv
|
||||||
|
```
|
||||||
|
|
||||||
|
Great! Now what?
|
||||||
|
|
||||||
|
## The space of equivalences
|
||||||
|
|
||||||
|
Turns out, the definition I gave above is just _one_ of multiple possible
|
||||||
|
equivalences between the boolean type and itself. Here is another possible
|
||||||
|
definition:
|
||||||
|
|
||||||
|
```
|
||||||
|
bool-neg : Bool → Bool
|
||||||
|
bool-neg true = false
|
||||||
|
bool-neg false = true
|
||||||
|
```
|
||||||
|
|
||||||
|
The remarkable thing about this is that nothing is changed by flipping true and
|
||||||
|
false. Someone using booleans would not be able to tell if you gave them a
|
||||||
|
boolean type where true and false were flipped. Simply put, the constructors
|
||||||
|
true and false are simply names and nothing can distinguish them.
|
||||||
|
|
||||||
|
We can show this by proving that `bool-neg` also forms an equivalence by using
|
||||||
|
itself as the inverse.
|
||||||
|
|
||||||
|
```
|
||||||
|
bool-neg-eqv : isEquiv bool-neg
|
||||||
|
bool-neg-eqv = mkEquiv bool-neg neg-homotopy neg-homotopy
|
||||||
|
where
|
||||||
|
neg-homotopy : (bool-neg ∘ bool-neg) ∼ id
|
||||||
|
neg-homotopy true = refl
|
||||||
|
neg-homotopy false = refl
|
||||||
|
|
||||||
|
bool-eqv2 : Bool ≃ Bool
|
||||||
|
bool-eqv2 = bool-neg , bool-neg-eqv
|
||||||
|
```
|
||||||
|
|
||||||
|
You could imagine more complicated functions over booleans that may also exhibit
|
||||||
|
this equivalence property. So how many different elements of the type $2 \simeq
|
||||||
|
2$ exist?
|
||||||
|
|
||||||
|
## Proving $2 \simeq 2$ only has 2 inhabitants
|
||||||
|
|
||||||
|
It turns out there are only 2 equivalences, the 2 that we already found. But how
|
||||||
|
do we know this for a fact? Well, if there are only 2 equivalences, that means
|
||||||
|
there are only 2 inhabitants of the type $2 \simeq 2$. We can prove that this
|
||||||
|
type only has 2 inhabitants by establishing an equivalence between this type and
|
||||||
|
another type that is known to have 2 inhabitants, such as the boolean type!
|
||||||
|
|
||||||
|
That's where the main exercise statement comes in: "show that" $(2 \simeq 2)
|
||||||
|
\simeq 2$, or in other words, find an inhabitant of this type.
|
||||||
|
|
||||||
|
```
|
||||||
|
_ : (Bool ≃ Bool) ≃ Bool
|
||||||
|
_ = {! !}
|
||||||
|
```
|
Loading…
Reference in a new issue