packages feed

hoq-0.1.0.0: examples/hlevel.hoq

data Nat = zero | suc Nat

data Sigma (A : Type) (B : A -> Type) = pair (a : A) (B a)

proj1 : (A : Type) (B : A -> Type) -> Sigma A B -> A
proj1 _ _ (pair a _) = a

proj2 : (A : Type) (B : A -> Type) (x : Sigma A B) -> B (proj1 A B x)
proj2 _ _ (pair _ b) = b

isContr : Type -> Type
isContr A = Sigma A (\a -> (a' : A) -> a = a')

I-isContr : isContr I
I-isContr = pair left (\i -> path (\j -> squeeze i j))

isProp : Type -> Type
isProp A = (a a' : A) -> a = a'

isSet : Type -> Type
isSet A = (a a' : A) -> isProp (a = a')

of-hlevel : Nat -> Type -> Type
of-hlevel zero A = isContr A
of-hlevel (suc n) A = (a a' : A) -> of-hlevel n (a = a')

h1-prop : (A : Type) -> of-hlevel (suc zero) A -> isProp A
h1-prop A f a a' = proj1 (a = a') (\p -> (p' : a = a') -> p = p') (f a a')

idp : (A : Type) (a : A) -> a = a
idp A a = path (\_ -> a)

transport : (A : Type) (B : A -> Type) (a a' : A) -> a = a' -> B a -> B a'
transport A B _ _ p x = coe (\i -> B (p @ i)) left x right

psqueeze : (A : Type) (a a' : A) (p : a = a') (i : I) -> a = p @ i
psqueeze A a a' p i = path (\j -> p @ squeeze i j)

J : (A : Type) (a : A) (B : (a' : A) -> a = a' -> Type) -> B a (idp A a) -> (a' : A) (p : a = a') -> B a' p
J A a B b a' p = coe (\i -> B (p @ i) (psqueeze A a a' p i)) left b right

inv : (A : Type) (a a' : A) -> a = a' -> a' = a
inv A a a' p = transport A (\x -> x = a) a a' p (idp A a)

comp : (A : Type) (a a' a'' : A) -> a = a' -> a' = a'' -> a = a''
comp A a a' a'' p q = transport A (\x -> a = x) a' a'' q p

inv-comp : (A : Type) (a a' : A) (p : a = a') -> comp A a' a a' (inv A a a' p) p = idp A a'
inv-comp A a a' p = J A a (\x q -> comp A x a x (inv A a x q) q = idp A x) (idp (a = a) (idp A a)) a' p

contr-prop : (A : Type) -> isContr A -> isProp A
contr-prop A (pair c f) a a' = comp A a c a' (inv A c a (f a)) (f a')

prop-h1 : (A : Type) -> isProp A -> of-hlevel (suc zero) A
prop-h1 A f a a' = pair (comp A a a a' (inv A a a (f a a)) (f a a'))
                        (J A a (\x q -> comp A a a x (inv A a a (f a a)) (f a x) = q) (inv-comp A a a (f a a)) a')

prop-set : (A : Type) -> isProp A -> isSet A
prop-set A p a a' = contr-prop (a = a') (prop-h1 A p a a')

isProp-isProp : (A : Type) -> isProp (isProp A)
isProp-isProp A f g = path (\i a a' -> prop-set A f a a' (f a a') (g a a') @ i)

Sigma-eq : (A : Type) (B : A -> Type) (a a' : A) (b : B a) (b' : B a') (p : a = a')
    -> transport A B a a' p b = b' -> Path (\_ -> Sigma A B) (pair a b) (pair a' b')
Sigma-eq A B a a' b b' p = J A a
    (\a' p -> (b' : B a') -> transport A B a a' p b = b' -> Path (\_ -> Sigma A B) (pair a b) (pair a' b'))
    (\b' q -> path (\i -> pair a (q @ i))) a' p b'

isContr-isProp : (A : Type) -> isProp (isContr A)
isContr-isProp A (pair a1 f1) (pair a2 f2) = Sigma-eq A (\a -> (a' : A) -> a = a') a1 a2 f1 f2 (f1 a2)
    (path (\i a' -> prop-set A (contr-prop A (pair a1 f1)) a2 a'
        (transport A (\a -> (a' : A) -> a = a') a1 a2 (f1 a2) f1 a') (f2 a') @ i))

of-hlevel-isProp : (n : Nat) (A : Type) -> isProp (of-hlevel n A)
of-hlevel-isProp zero A = isContr-isProp A
of-hlevel-isProp (suc n) A f g = path (\i a a' -> of-hlevel-isProp n (a = a') (f a a') (g a a') @ i)