{-# OPTIONS --cubical --allow-unsolved-metas #-}
open import Cubical.Core.Everything
{-
ROSETTA STONE for TRANSLATING between THREE SUBJECTS:
1. logic
2. computer science
3. homotopy theory (dealing with shapes)
x ≡ y 1. "the values x and y are the same"
2. "the type of witnesses that x and y are the same"
3. "the space of paths from x to y"
x ≡ y → y ≡ x
1. "if x is the same as y, then also y is the same as x"
2. "there is a function transforming witnesses that x ≡ y
into witnesses that y ≡ x"
3. ???
⊥ 1. "contradiction"
2. "the empty type"
3. "the empty space"
In Cubical Agda, we picture types to be spaces.
Every value of a type is then pictured as a point of the associated space.
Here is a picture of the space associated to ℕ:
0 1 2 3 4 5 ...
In this space, there is no path between 0 and 1.
Here is a picture of another space:
+----+
|####|
|####|
+----+
In this space, there is a path from every point to every other point.
Here is a picture of yet another space:
A----B C
|####| /#\
|####| +---+
+----+
In this space, there is a path from A to B, but
there is no path from A to C.
In logic, if a ≡ b and b ≡ c, then we may conclude that a ≡ c.
In homotopy theory, if we have a path from a to b and
if we have a path from b to c, then we may concatenate those
two paths to obtain a path from a to c.
-}
data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
_+_ : ℕ → ℕ → ℕ
zero + b = b
succ a + b = succ (a + b)
-- "Pair X" is the type of (ordered) pairs of values of X.
data Pair (X : Set) : Set where
mk : X → X → Pair X
first : {X : Set} → Pair X → X
first (mk a b) = a
-- "UnorderedPair X" is the type of unordered pairs of values of X.
data UnorderedPair (X : Set) : Set where
mk : X → X → UnorderedPair X
swap : (a b : X) → mk a b ≡ mk b a
first' : {X : Set} → UnorderedPair X → X
first' (mk a b) = a
first' (swap a b i) = {!!}
-- We are happy that this hole cannot be filled in.
sum' : UnorderedPair ℕ → ℕ
sum' (mk a b) = a + b
sum' (swap a b i) = {!!}
-- We are happy that this hole can be filled in.
-- In Cubical Agda, there can be more witnesses of equality than
-- just provided by "refl". For instance, "swap" provides additional
-- witnesses.
-- Let's define the type of numbers modulo 4:
-- -4=0, -3=1, -2=2, -1=3, 0, 1, 2, 3, 4=0, 5=1, 6=2, 7=3, 8=4, ...
data ℤmod4 : Set where
zer : ℤmod4
suc : ℤmod4 → ℤmod4
wrap : (x : ℤmod4) → x ≡ suc (suc (suc (suc x)))
data ℤmod4' : Set where
zer' : ℤmod4'
suc' : ℤmod4' → ℤmod4'
wrap' : zer' ≡ suc' (suc' (suc' (suc' zer')))
-- Here is a picture of ℤmod4':
-- +----------------+
-- | |
-- 0 1 2 3 4 5 6 7 8 9 10 ...
-- | | | |
-- +------------------+ |
-- | |
-- +-----------------+
data S¹ : Set where
base : S¹
loop : base ≡ base
-- Here is a picture of the circle (just the boundary, not filled in):
-- *
-- / \
-- \_A
base' : S¹
base' = loop i1
-- If p is any path in Cubical Agda, then p i0 is its beginning
-- and p i1 is its end. And "p i0.5" would be its midpoint.
-- And "p i0.25" would be its first-quarter-point.
refl : {X : Set} {x : X} → x ≡ x
refl {X} {x} i = x
-- refl {X} {x} = λ i → x
symm : {X : Set} {a b : X} → a ≡ b → b ≡ a
symm {X} {a} {b} p i = p (~ i)
-- symm {X} {a} {b} p = λ i → p (~ i)
cong : {X Y : Set} {a b : X} → (f : X → Y) → a ≡ b → f a ≡ f b
cong = {!!}
-- The following principle is called "function extensionality".
-- It is often expected by blackboard mathematicians.
-- It is available (by a one-line proof) in Cubical Agda.
-- It is not available in standard Agda.
funext : {X Y : Set} {f g : X → Y} → ((x : X) → f x ≡ g x) → f ≡ g
funext = {!!}
-- How many paths are there from base to base?
-- How many values does the same "base ≡ base" have?
-- refl, loop, loop · loop, loop · loop · loop, ...,
-- symm loop, symm loop · symm loop, ...
-- We will also have the path loop · refl · loop,
-- however this path will be the SAME as loop · loop.
-- The path loop · symm loop will be the SAME as refl.
data Interval : Set where
left : Interval
right : Interval
seg : left ≡ right
-- Here is a picture of the interval:
-- +--------+
-- Here is a picture of yet another space:
data Foo : Set where
left : Foo
right : Foo
seg₁ : left ≡ right
seg₂ : left ≡ right
-- +----+
-- / \
-- + +
-- \ /
-- +----+
-- +---+
-- |###|
-- |###|
-- +---+
data FilledSquare : Set where
upper-left-corner : FilledSquare
lower-right-corner : FilledSquare
path₁ : upper-left-corner ≡ lower-right-corner
path₂ : upper-left-corner ≡ lower-right-corner
body : path₁ ≡ path₂
toℕ : ℤmod4' → ℕ
toℕ zer' = zero
toℕ (suc' x) = succ (toℕ x)
toℕ (wrap' i) = {!!}
-- Note: toℕ (suc' zer') will be succ zero.
-- toℕ (suc' (suc' (suc' (suc' (suc' zer'))))) will be 5.
-- And (suc' zer') is the same as (suc' (suc' (suc' (suc' (suc' zer'))))).
-- So, by congruence, also 1 should be the same as 5 in ℕ.
_ : suc zer ≡ suc (suc (suc (suc (suc zer))))
_ = wrap (suc zer)
_ : suc' zer' ≡ suc' (suc' (suc' (suc' (suc' zer'))))
_ = {!cong suc' wrap'!}
example : UnorderedPair ℕ
example = mk (succ zero) (succ (succ zero))
example' : UnorderedPair ℕ
example' = mk (succ (succ zero)) (succ zero)
dream : example ≡ example'
dream = swap (succ zero) (succ (succ zero))
-- How can we define the type of unordered pairs of values of X?
-- One answer: Use sorted ordered pairs to represent
-- unordered pairs. For instance, the unordered pair
-- of the numbers 20 and 5 would be represented by
-- (5 , 20). The unordered pair of the numbers 5 and 20
-- would be the SAME unordered pair and it would be
-- represented by the same ordered pair (5 , 20).
-- This is a good approach, HOWEVER it requires some
-- ordering on X.
-- Second answer: Just promise to never use ≡.
-- Instead only use a custom-tailored approximate
-- equality ≈.
_≈_ : {X : Set} → Pair X → Pair X → Set
(mk a b) ≈ (mk a' b') = {!(a ≡ a' × b ≡ b') ⊎ (a ≡ b' × b ≡ a')!}
-- This is called the "setoid hell".