@ -84,7 +84,7 @@ sym p i = p (inot i)
id : {A : Type} -> A -> A
id x = x
the : (A : T ype) -> A -> A
the : (A : Pret ype) -> A -> A
the A x = x
-- The eliminator for the interval says that if you have x : A i0 and y : A i1,
@ -266,12 +266,12 @@ fill A {phi} u a0 i =
(\j [ (phi = i1) as p -> u (iand i j) p, (i = i0) -> outS a0 ])
(inS (outS a0))
hfill : {A : Type} {phi : I} (u : (i : I) -> Partial phi A) -> Sub A phi (u i0) -> I -> A
hfill {A} {phi} u a0 i = fill (\i -> A) {phi} u a0 i
hcomp : {A : Type} {phi : I} (u : (i : I) -> Partial phi A) -> Sub A phi (u i0) -> A
hcomp {A} {phi} u a0 = comp (\i -> A) {phi} u a0
hfill : {A : Type} {phi : I} (u : (i : I) -> Partial phi A) -> (a0 : Sub A phi (u i0)) -> I -> A
hfill {A} {phi} u a0 i = fill (\i -> A) {phi} u a0 i
-- For instance, the filler of the previous composition square
-- tells us that trans p refl = p:
@ -296,11 +296,11 @@ transpFun : {A : Type} {B : Type} {C : Type} {D : Type} (p : Path A B) (q : Path
(\x -> transp (\i -> q i) (f (transp (\i -> p (inot i)) x)))
transpFun p q f = refl
-- transpDFun : {A : I -> Type} {B : (i : I) -> A i -> Type}
-- -> (f : (x : A i0) -> B i0 x)
-- -> Path (transp (\i -> (x : A i) -> B i x) f)
-- (\x -> transp (\i -> B i (fill (\j -> A (inot j)) (\k []) (inS x) (inot i))) (f (fill (\j -> A (inot j)) (\k []) (inS x) i1)))
-- transpDFun f = refl
transpDFun : {A : I -> Type} {B : (i : I) -> A i -> Type}
-> (f : (x : A i0) -> B i0 x)
-> Path (transp (\i -> (x : A i) -> B i x) f)
(\x -> transp (\i -> B i (fill (\j -> A (inot j)) (\k []) (inS x) (inot i))) (f (fill (\j -> A (inot j)) (\k []) (inS x) i1)))
transpDFun f = refl
-- When considering the more general case of a composition respecing sides,
-- the outer transport becomes a composition.
@ -628,10 +628,10 @@ notp = univalence (IsoToEquiv (not, involToIso not notInvol))
data bottom : Type where {}
elimBottom : (P : bottom -> T ype) -> (b : bottom) -> P b
elimBottom : (P : bottom -> Pret ype) -> (b : bottom) -> P b
elimBottom P = \case {}
absurd : {P : T ype} -> bottom -> P
absurd : {P : Pret ype} -> bottom -> P
absurd = \case {}
-- We prove that true != false by transporting along the path
@ -715,6 +715,20 @@ Nat_elim P pz ps = \case
zero -> pz
succ x -> ps x (Nat_elim P pz ps x)
zeroNotSucc : {x : Nat} -> Path zero (succ x) -> bottom
zeroNotSucc p = transp (\i -> fun (p i)) (p i0) where
fun : Nat -> Type
fun = \case
zero -> Nat
succ x -> bottom
succInj : {x : Nat} {y : Nat} -> Path (succ x) (succ y) -> Path x y
succInj p i = pred (p i) where
pred : Nat -> Nat
pred = \case
zero -> zero
succ x -> x
-- The type of integers can be defined as A + B, where "pos n" means +n
-- and "neg n" means -(n + 1).
@ -882,41 +896,40 @@ data Susp (A : Type) : Type where
data Unit : Type where
tt : Unit
poSusp : Type -> Type
poSusp A = Pushout {A} {Unit} {Unit} (\x -> tt) (\x -> tt)
poSusp_to_Susp : {A : Type} -> poSusp A -> Susp A
poSusp_to_Susp = \case
inl x -> north
inr x -> south
push x i -> merid x i
Susp_to_poSusp : {A : Type} -> Susp A -> poSusp A
Susp_to_poSusp = \case
north -> inl tt
south -> inr tt
merid x i -> push x i
Susp_to_poSusp_to_Susp : {A : Type} -> (x : Susp A) -> Path (poSusp_to_Susp (Susp_to_poSusp x)) x
Susp_to_poSusp_to_Susp = \case
north -> refl
south -> refl
merid x i -> refl
unitEta : (x : Unit) -> Path x tt
unitEta = \case tt -> refl
unitContr : isContr Unit
unitContr = (tt, \x -> sym (unitEta x))
poSusp_to_Susp_to_poSusp : {A : Type} -> (x : poSusp A) -> Path (Susp_to_poSusp (poSusp_to_Susp x)) x
poSusp_to_Susp_to_poSusp {A} = \case
inl x -> cong inl (sym (unitEta x))
inr x -> cong inr (sym (unitEta x))
push x i -> refl
poSusp : Type -> Type
poSusp A = Pushout {A} {Unit} {Unit} (\x -> tt) (\x -> tt)
Susp_is_poSusp : {A : Type} -> Path (Susp A) (poSusp A)
Susp_is_poSusp {A} = univalence (IsoToEquiv (Susp_to_poSusp {A}, poSusp_to_Susp {A}, poSusp_to_Susp_to_poSusp {A}, Susp_to_poSusp_to_Susp {A}))
Susp_is_poSusp {A} = univalence (IsoToEquiv (Susp_to_poSusp {A}, poSusp_to_Susp {A}, poSusp_to_Susp_to_poSusp {A}, Susp_to_poSusp_to_Susp {A})) where
poSusp_to_Susp : {A : Type} -> poSusp A -> Susp A
poSusp_to_Susp = \case
inl x -> north
inr x -> south
push x i -> merid x i
Susp_to_poSusp : {A : Type} -> Susp A -> poSusp A
Susp_to_poSusp = \case
north -> inl tt
south -> inr tt
merid x i -> push x i
Susp_to_poSusp_to_Susp : {A : Type} -> (x : Susp A) -> Path (poSusp_to_Susp (Susp_to_poSusp x)) x
Susp_to_poSusp_to_Susp = \case
north -> refl
south -> refl
merid x i -> refl
poSusp_to_Susp_to_poSusp : {A : Type} -> (x : poSusp A) -> Path (Susp_to_poSusp (poSusp_to_Susp x)) x
poSusp_to_Susp_to_poSusp {A} = \case
inl x -> cong inl (sym (unitEta x))
inr x -> cong inr (sym (unitEta x))
push x i -> refl
data T2 : Type where
baseT : T2
@ -929,41 +942,42 @@ data T2 : Type where
(i = i1) -> pathOne j
]
torusToCircs : T2 -> S1 * S1
torusToCircs = \case
baseT -> (base, base)
pathOne i -> (loop i, base)
pathTwo i -> (base, loop i)
square i j -> (loop i, loop j)
circsToTorus : (S1 * S1) -> T2
circsToTorus pair = go pair.1 pair.2
where
baseCase : S1 -> T2
baseCase = \case
base -> baseT
loop j -> pathTwo j
loopCase : Path baseCase baseCase
loopCase i = \case
base -> pathOne i
loop j -> square i j
go : S1 -> S1 -> T2
go = \case
base -> baseCase
loop i -> loopCase i
torusToCircsToTorus : (x : T2) -> Path (circsToTorus (torusToCircs x)) x
torusToCircsToTorus = \case
baseT -> refl
pathOne i -> refl
pathTwo i -> refl
square i j -> refl
circsToTorusToCircs : (p : S1 * S1) -> Path (torusToCircs (circsToTorus p)) p
circsToTorusToCircs pair = go pair.1 pair.2
where
TorusIsTwoCircles : Path T2 (S1 * S1)
TorusIsTwoCircles = univalence (IsoToEquiv theIso) where
torusToCircs : T2 -> S1 * S1
torusToCircs = \case
baseT -> (base, base)
pathOne i -> (loop i, base)
pathTwo i -> (base, loop i)
square i j -> (loop i, loop j)
circsToTorus : (S1 * S1) -> T2
circsToTorus pair = go pair.1 pair.2
where
baseCase : S1 -> T2
baseCase = \case
base -> baseT
loop j -> pathTwo j
loopCase : Path baseCase baseCase
loopCase i = \case
base -> pathOne i
loop j -> square i j
go : S1 -> S1 -> T2
go = \case
base -> baseCase
loop i -> loopCase i
torusToCircsToTorus : (x : T2) -> Path (circsToTorus (torusToCircs x)) x
torusToCircsToTorus = \case
baseT -> refl
pathOne i -> refl
pathTwo i -> refl
square i j -> refl
circsToTorusToCircs : (p : S1 * S1) -> Path (torusToCircs (circsToTorus p)) p
circsToTorusToCircs pair = go pair.1 pair.2 where
baseCase : (y : S1) -> Path (torusToCircs (circsToTorus (base, y))) (base, y)
baseCase = \case
base -> refl
@ -979,11 +993,9 @@ circsToTorusToCircs pair = go pair.1 pair.2
base -> baseCase
loop i -> loopCase i
TorusIsTwoCircles : Path T2 (S1 * S1)
TorusIsTwoCircles = univalence (IsoToEquiv theIso) where
theIso : Iso T2 (S1 * S1)
theIso = (torusToCircs, circsToTorus, circsToTorusToCircs, torusToCircsToTorus)
abs : Int -> Nat
abs = \case
pos n -> n
@ -1041,15 +1053,169 @@ isProp A = (x : A) (y : A) -> Path x y
data Sq (A : Type) : Type where
inc : A -> Sq A
sq i : (x : A) (y : A) -> Sq A [ (i = i0) -> inc x, (i = i1) -> inc y ]
sq i : (x : Sq A) (y : Sq A) -> Sq A [ (i = i0) -> x, (i = i1) -> y ]
isProp_isSet : {A : Type} -> isProp A -> isHSet A
isProp_isSet h {a} {b} p q j i =
hcomp {A}
(\k [ (i = i0) -> h a a k
, (i = i1) -> h a b k
, (j = i0) -> h a (p i) k
, (j = i1) -> h a (q i) k
])
(inS a)
Sq_rec : {A : Type} {B : Type}
-> isProp B
-> (f : A -> B)
-> Sq A -> B
Sq_rec prop f = \case
inc x -> f x
sq x y i -> prop (f x) (f y) i
Sq_rec prop f =
\case
inc x -> f x
sq x y i -> prop (work x) (work y) i
where
work : Sq A -> B
work = \case
inc x -> f x
hitTranspExample : Path (inc false) (inc true)
hitTranspExample i = transp (\i -> Sq (notp i)) (sq true false i)
hitTranspExample i = transp (\i -> Sq (notp i)) (sq (inc true) (inc false) i)
data S2 : Type where
base2 : S2
surf2 i j : S2 [ (i = i0) -> base2, (i = i1) -> base2, (j = i0) -> base2, (j = i1) -> base2]
S2IsSuspS1 : Path S2 (Susp S1)
S2IsSuspS1 = univalence (IsoToEquiv iso) where
toS2 : Susp S1 -> S2
toS2 = \case { north -> base2; south -> base2; merid x i -> sphMerid x i } where
sphMerid = \case
base -> \i -> base2
loop j -> \i -> surf2 i j
suspSurf : I -> I -> I -> Susp S1
suspSurf i j = hfill {Susp S1} (\k [ (i = i0) -> north
, (i = i1) -> merid base (inot k)
, (j = i0) -> merid base (iand (inot k) i)
, (j = i1) -> merid base (iand (inot k) i)
])
(inS (merid (loop j) i))
fromS2 : S2 -> Susp S1
fromS2 = \case { base2 -> north; surf2 i j -> suspSurf i j i1 }
toFromS2 : (x : S2) -> Path (toS2 (fromS2 x)) x
toFromS2 = \case { base2 -> refl; surf2 i j -> refl }
fromToS2 : (x : Susp S1) -> Path (fromS2 (toS2 x)) x
fromToS2 = \case { north -> refl; south -> \i -> merid base i; merid x i -> meridCase i x } where
meridCase : (i : I) (x : S1) -> Path (fromS2 (toS2 (merid x i))) (merid x i)
meridCase i = \case
base -> \k -> merid base (iand i k)
loop j -> \k -> suspSurf i j (inot k)
iso : Iso S2 (Susp S1)
iso = (fromS2, toS2, fromToS2, toFromS2)
data S3 : Type where
base3 : S3
surf3 i j k : S3 [ (i = i0) -> base3, (i = i1) -> base3, (j = i0) -> base3, (j = i1) -> base3, (k = i0) -> base3, (k = i1) -> base3 ]
S3IsSuspS2 : Path S3 (Susp S2)
S3IsSuspS2 = univalence (IsoToEquiv iso) where
toS3 : Susp S2 -> S3
toS3 = \case { north -> base3; south -> base3; merid x i -> sphMerid x i } where
sphMerid = \case
base2 -> \i -> base3
surf2 j k -> \i -> surf3 i j k
suspSurf : I -> I -> I -> I -> Susp S2
suspSurf i j k = hfill {Susp S2} (\l [ (i = i0) -> north
, (i = i1) -> merid base2 (inot l)
, (j = i0) -> merid base2 (iand (inot l) i)
, (j = i1) -> merid base2 (iand (inot l) i)
, (k = i0) -> merid base2 (iand (inot l) i)
, (k = i1) -> merid base2 (iand (inot l) i)
])
(inS (merid (surf2 j k) i))
fromS3 : S3 -> Susp S2
fromS3 = \case { base3 -> north; surf3 i j k -> suspSurf i j k i1 }
toFromS3 : (x : S3) -> Path (toS3 (fromS3 x)) x
toFromS3 = \case { base3 -> refl; surf3 i j k -> refl }
fromToS3 : (x : Susp S2) -> Path (fromS3 (toS3 x)) x
fromToS3 = \case { north -> refl; south -> \i -> merid base2 i; merid x i -> meridCase i x } where
meridCase : (i : I) (x : S2) -> Path (fromS3 (toS3 (merid x i))) (merid x i)
meridCase i = \case
base2 -> \k -> merid base2 (iand i k)
surf2 j k -> \l -> suspSurf i j k (inot l)
iso : Iso S3 (Susp S2)
iso = (fromS3, toS3, fromToS3, toFromS3)
Eq_s : {A : Pretype} -> A -> A -> Pretype
{-# PRIMITIVE Eq_s #-}
refl_s : {A : Pretype} {x : A} -> Eq_s x x
{-# PRIMITIVE refl_s #-}
J_s : {A : Pretype} {x : A} (P : (y : A) -> Eq_s x y -> Pretype) -> P x (refl_s {A} {x}) -> {y : A} -> (p : Eq_s x y) -> P y p
{-# PRIMITIVE J_s #-}
ap_s : {A : Pretype} {B : Pretype} (f : A -> B) {x : A} {y : A} -> Eq_s x y -> Eq_s (f x) (f y)
ap_s {A} {B} f {x} {y} = J_s (\y p -> Eq_s (f x) (f y)) refl_s
subst_s : {A : Pretype} (P : A -> Pretype) {x : A} {y : A} -> Eq_s x y -> P x -> P y
subst_s {A} P {x} {z} p px = J_s {A} {x} (\y p -> P x -> P y) id p px
sym_s : {A : Pretype} {x : A} {y : A} -> Eq_s x y -> Eq_s y x
sym_s {A} {x} {y} = J_s {A} {x} (\y p -> Eq_s y x) refl_s
K_s : {A : Pretype} {x : A} (P : Eq_s x x -> Pretype) -> P (refl_s {A} {x}) -> (p : Eq_s x x) -> P p
{-# PRIMITIVE K_s #-}
UIP : {A : Pretype} {x : A} {y : A} (p : Eq_s x y) (q : Eq_s x y) -> Eq_s p q
UIP {A} {x} {y} p q = J_s (\y p -> (q : Eq_s x y) -> Eq_s p q) (uipRefl A x) p q where
uipRefl : (A : Pretype) (x : A) (p : Eq_s x x) -> Eq_s refl_s p
uipRefl A x p = K_s {A} {x} (\q -> Eq_s refl_s q) refl_s p
strictEq_pathEq : {A : Type} {x : A} {y : A} -> Eq_s x y -> Path x y
strictEq_pathEq {A} {x} {y} eq = J_s {A} {x} (\y p -> Path x y) (\i -> x) {y} eq
seq_pathRefl : {A : Type} {x : A} (p : Eq_s x x) -> Eq_s (strictEq_pathEq p) (refl {A} {x})
seq_pathRefl {A} {x} p = K_s (\p -> Eq_s (strictEq_pathEq {A} {x} {x} p) (refl {A} {x})) refl_s p
Path_nat_strict_nat : (x : Nat) (y : Nat) -> Path x y -> Eq_s x y
Path_nat_strict_nat = \case { zero -> zeroCase; succ x -> succCase x } where
zeroCase : (y : Nat) -> Path zero y -> Eq_s zero y
zeroCase = \case
zero -> \p -> refl_s
succ x -> \p -> absurd (zeroNotSucc p)
succCase : (x : Nat) (y : Nat) -> Path (succ x) y -> Eq_s (succ x) y
succCase x = \case
zero -> \p -> absurd (zeroNotSucc (sym p))
succ y -> \p -> ap_s succ (Path_nat_strict_nat x y (succInj p))
pathToEqS_K : {A : Type} {x : A}
-> (s : {x : A} {y : A} -> Path x y -> Eq_s x y)
-> (P : Path x x -> Type) -> P refl -> (p : Path x x) -> P p
pathToEqS_K {A} {x} p_to_s P pr loop = transp (\i -> P (inv x loop i)) psloop where
psloop : P (strictEq_pathEq (p_to_s loop))
psloop = K_s (\l -> P (strictEq_pathEq {A} {x} {x} l)) pr (p_to_s {x} {x} loop)
inv : (y : A) (l : Path x y) -> Path (strictEq_pathEq (p_to_s l)) l
inv y l = J {A} {x} (\y l -> Path (strictEq_pathEq (p_to_s l)) l) (strictEq_pathEq aux) {y} l where
aux : Eq_s (strictEq_pathEq (p_to_s (\i -> x))) (\i -> x)
aux = seq_pathRefl (p_to_s (\i -> x))
pathToEq_isSet : {A : Type} -> ({x : A} {y : A} -> Path x y -> Eq_s x y) -> isHSet A
pathToEq_isSet {A} p_to_s {x} {y} p q = axK_to_isSet {A} (\{x} -> pathToEqS_K {A} {x} p_to_s) {x} {y} p q where
axK_to_isSet : {A : Type} -> ({x : A} -> (P : Path x x -> Type) -> P refl -> (p : Path x x) -> P p) -> isHSet A
axK_to_isSet K {x} {y} p q = J (\y p -> (q : Path x y) -> Path p q) (uipRefl x) p q where
uipRefl : (x : A) (p : Path x x) -> Path refl p
uipRefl x p = K {x} (\q -> Path refl q) refl p
Nat_isSet : isHSet Nat
Nat_isSet {x} {y} = pathToEq_isSet {Nat} (\{x} {y} -> Path_nat_strict_nat x y) {x} {y}