\import Equiv
\import Equiv.Path
\import Logic
\import Order.PartialOrder
\import Paths
\import Paths.Meta
\import Arith.Nat
\open Nat(+)
\func isProp (A : \Type) => \Pi (a a' : A) -> a = a'
\where
\use \level levelProp (A : \Type) (e e' : isProp A) : e = e'
=> path (\lam i a a' => isProp=>isSet A e a a' (e a a') (e' a a') @ i)
\func \infix 2 ofHLevel_-1+ (A : \Type) (n : Nat) : \Type \elim n
| 0 => isProp A
| suc n => \Pi (a a' : A) -> (a = a') ofHLevel_-1+ n
\where
\use \level levelProp (A : \Type) (n : Nat) (e e' : A ofHLevel_-1+ n) : e = e' \elim n
| 0 => isProp.levelProp A e e'
| suc n => path (\lam i a a' => levelProp (a = a') n (e a a') (e' a a') @ i)
\func isProp=>isSet (A : \Type) (p : isProp A) (a a' : A) : isProp (a = a') => isContr=>isProp (isProp=>HLevel_-2+1 A p a a')
\func isSet (A : \Type) => A ofHLevel_-1+ 1
\func isGpd (A : \Type) => A ofHLevel_-1+ 2
\lemma isSet=>isGpd (A : \Type) (p : isSet A) : isGpd A => \lam a a' => isProp=>isSet (a = a') (p a a')
\func hLevel-inh {A : \Type} (n : Nat) (f : A -> A ofHLevel_-1+ n) : A ofHLevel_-1+ n \elim n
| 0 => \lam a => f a a
| suc n => \lam a => f a a
\class Contr (A : \Type) (center : A) (contraction : \Pi (a' : A) -> center = a')
\where {
\func make {A : \Type} (a : A) (p : \Pi (a' : A) -> a = a') => \new Contr A a p
\use \level levelProp (A : \Type) (c1 c2 : Contr A) : c1 = c2 => exts Contr {
| center => c1.contraction c2.center
| contraction a' => isProp=>isSet A (isContr=>isProp c1) c2.center a' _ _
}
}
\lemma contr-equiv (A B : Contr) {f : A -> B} : Equiv f
=> \new QEquiv {
| ret _ => A.center
| ret_f x => A.contraction x
| f_sec y => isContr=>isProp B _ _
}
\func isContr=>isProp {A : \Type} (c : Contr A) : isProp A => \lam a a' => inv (c.contraction a) *> c.contraction a'
\lemma isContr'=>isProp {A : \Type} (c : A -> Contr A) : isProp A => \lam a => isContr=>isProp (c a) a
\lemma isProp=>isContr {A : \Type} (p : isProp A) (a : A) : Contr A => Contr.make a (p a)
\lemma isProp'=>isContr {A : \Type} (p : isProp A) (a : TruncP A) : Contr A \elim a
| inP a => isProp=>isContr p a
\func I-isContr : Contr I \cowith
| center => left
| contraction i => path (I.squeeze i)
\func \infix 2 ofHLevel_-2+ (A : \Type) (n : Nat) : \Prop \elim n
| 0 => Contr A
| suc n => \Pi (a a' : A) -> (a = a') ofHLevel_-2+ n
\func HLevel_-2+1=>HLevel_-1 (A : \Type) (n : Nat) (p : A ofHLevel_-2+ suc n) : A ofHLevel_-1+ n \elim n
| 0 => \lam a a' => Contr.center {p a a'}
| suc n => \lam a a' => HLevel_-2+1=>HLevel_-1 (a = a') n (p a a')
\func isProp=>HLevel_-2+1 (A : \Type) (p : isProp A) (a a' : A) : Contr (a = a') => \new Contr (a = a') {
| center => inv (p a a) *> p a a'
| contraction => Jl (\lam x q => inv (p a a) *> p a x = q) (inv_*> (p a a))
}
\lemma HLevel_-1=>HLevel_-2+1 (A : \Type) (n : Nat) (p : A ofHLevel_-1+ n) : A ofHLevel_-2+ suc n \elim n
| 0 => isProp=>HLevel_-2+1 A p
| suc n => \lam a a' => HLevel_-1=>HLevel_-2+1 (a = a') n (p a a')
\func HLevel_-1_suc {A : \Type} {n : Nat} (p : A ofHLevel_-1+ n) : A ofHLevel_-1+ suc n \elim n
| 0 => isProp=>isSet A p
| suc n => \lam a a' => HLevel_-1_suc (p a a')
\func HLevel_-1_+ {A : \Type} {k : Nat} (n : Nat) (p : A ofHLevel_-1+ k) : A ofHLevel_-1+ k + n \elim n
| 0 => p
| suc n => HLevel_-1_suc (HLevel_-1_+ n p)
\func HLevel_-1_<= {A : \Type} (k : Nat) (n : Nat) (q : k <= n) (p : A ofHLevel_-1+ k) : A ofHLevel_-1+ n
=> rewriteI (<=_exists q) (HLevel_-1_+ (n -' k) p)
-- | hLevels are closed under retracts
\func HLevel-retracts (s : Section) {n : Nat} (p : s.B ofHLevel_-1+ n) : s.A ofHLevel_-1+ n \elim n
| 0 => \lam a a' => inv (s.ret_f a) *> pmap s.ret (p (s a) (s a')) *> s.ret_f a'
| suc n => \lam a a' => HLevel-retracts (pmapSection s) (p (s a) (s a'))
-- | hLevels are closed under pi-types
\func HLevels-pi {A : \Type} (B : A -> \Type) {n : Nat} (p : \Pi (a : A) -> B a ofHLevel_-1+ n) : (\Pi (a : A) -> B a) ofHLevel_-1+ n \elim n
| 0 => \lam f f' => path (\lam i a => p a (f a) (f' a) @ i)
| suc n => \lam f f' => HLevel-retracts (piEquiv B f f') (HLevels-pi (\lam a => f a = f' a) (\lam a => p a (f a) (f' a)))
-- | hLevels are closed under sigma-types
\func HLevels-sigma {A : \Type} (B : A -> \Type) {n : Nat} (pA : A ofHLevel_-1+ n) (pB : \Pi (a : A) -> B a ofHLevel_-1+ n) : (\Sigma (a : A) (B a)) ofHLevel_-1+ n \elim n
| 0 => \lam p p' => ext (pA p.1 p'.1, pB p'.1 _ _)
| suc n => \lam p p' => HLevel-retracts (sigmaEquiv B p p') (HLevels-sigma (transport B __ p.2 = p'.2) (pA p.1 p'.1) (\lam s => pB _ _ _))
-- | hLevels are closed under embeddings
\func HLevels-embeddings (e : Embedding) {n : Nat} (p : e.B ofHLevel_-1+ n) : e.A ofHLevel_-1+ n \elim n
| 0 => \lam a a' => sec {e.isEmb a a'} (p (e a) (e a'))
| suc n => \lam a a' => HLevels-embeddings (pmapEmbedding e) (p (e a) (e a'))
-- | Contr-based hLevels are closed under retracts
\lemma HLevel_-2-retracts (s : Section) {n : Nat} (p : s.B ofHLevel_-2+ n) : s.A ofHLevel_-2+ n \elim n
| 0 => \have a0 => s.ret (Contr.center {p}) \in Contr.make a0 (\lam a => inv (s.ret_f a0) *> pmap s.ret (isContr=>isProp p (s a0) (s a)) *> s.ret_f a)
| suc n => \lam a a' => HLevel_-2-retracts (pmapSection s) (p (s a) (s a'))
-- | Contr-based hLevels are closed under pi-types
\lemma HLevels_-2-pi {A : \Type} (B : A -> \Type) {n : Nat} (p : \Pi (a : A) -> B a ofHLevel_-2+ n) : (\Pi (a : A) -> B a) ofHLevel_-2+ n \elim n
| 0 => Contr.make (\lam a => Contr.center {p a}) (\lam f => path (\lam i a => Contr.contraction {p a} (f a) @ i))
| suc n => \lam f f' => HLevel_-2-retracts (piEquiv B f f') (HLevels_-2-pi (\lam a => f a = f' a) (\lam a => p a (f a) (f' a)))
-- | Contr-based hLevels are closed under sigma-types
\lemma HLevels_-2-sigma {A : \Type} (B : A -> \Type) {n : Nat} (pA : A ofHLevel_-2+ n) (pB : \Pi (a : A) -> B a ofHLevel_-2+ n) : (\Sigma (a : A) (B a)) ofHLevel_-2+ n \elim n
| 0 => \let | a0 => Contr.center {pA}
| p0 => ((a0, Contr.center {pB a0}) : \Sigma (a : A) (B a))
\in Contr.make p0 (\lam p => ext (Contr.contraction {pA} p.1, isContr=>isProp (pB p.1) _ _))
| suc n => \lam p p' => HLevel_-2-retracts (sigmaEquiv B p p') (HLevels_-2-sigma (transport B __ p.2 = p'.2) (pA p.1 p'.1) (\lam s => pB _ _ _))