open import 1Lab.Equiv.FromPath open import 1Lab.Univalence open import 1Lab.HLevel open import 1Lab.Equiv open import 1Lab.Path open import 1Lab.Type module 1Lab.Type.Prop where
The (impredicative) universe of propositionsπ
One result that Cubical Agda does not let us conclude, which is handy in the development of topos theory (and locale theory by extension), is that universes of propositions are closed under arbitrary quantification: If is a family of propositions at level , but , then β even though that dependent product has at most one element, and so can not be a very large type at all.
We work around this using one of Agdaβs wildly unsafe features, NO_UNIVERSE_CHECK
. Like the name implies, it turns off universe checking for a particular (group of) declarations β which would quickly lead to inconsistency when used without care.
{-# NO_UNIVERSE_CHECK #-} record Prop* : Type where field {β} : Level β£_β£ : Type β is-tr : is-prop β£_β£ open Prop* hiding (β) public
The first thing we establish is a characterisation of paths in Prop*, as is tradition. This definition is also covered in unsafety: Agda does not let us conclude that the types exist at the same level simply from biimplication, so it needs to be convinced. Painfully. With more than one postulate. Yikes.
prop-ua : β {A B : Prop*} β (β£ A β£ β β£ B β£) Γ (β£ B β£ β β£ A β£) β A β‘ B prop-ua {A} {B} (f , g) i = prop where -- Safe: we're ignoring the levels anyway.. These types are props! -- They're all at level zero! Begone, Agda. postulate levels : Path Level (A .Prop*.β) (B .Prop*.β) eqv : is-equiv g eqv .is-eqv y .centre = f y , A .is-tr _ _ eqv .is-eqv y .paths (x , p) i = B .is-tr (f y) x i , Ξ» j β is-propβsquarep (Ξ» i j β A .is-tr) (Ξ» j β g (B .is-tr (f y) x j)) (Ξ» j β A .is-tr (g (f y)) y j) p (Ξ» _ β y) i j path-of-types : (i : I) β Type (levels i) path-of-types i = Glue β£ A β£ Ξ» where (i = i0) β β£ A β£ , id , id-equiv (i = i1) β β£ B β£ , g , eqv -- Safe: is-prop is a prop, so any two of its values are equal. We -- can't use the standard methods here (is-prop-is-prop, etc) because -- you can't form PathPs over types with dependent levels. postulate trs : (i : I) β Sub (is-prop (path-of-types i)) (i β¨ ~ i) Ξ» { (i = i0) β A .is-tr ; (i = i1) β B .is-tr } prop : Prop* prop .Prop*.β = levels i prop .β£_β£ = path-of-types i prop .is-tr = outS (trs i) prop-ua-is-equiv : β {A B} β is-equiv (prop-ua {A} {B}) prop-ua-is-equiv {A} {B} = is-isoβis-equiv (iso inverse isr isl) where inverse : β {A B} β A β‘ B β (β£ A β£ β β£ B β£) Γ (β£ B β£ β β£ A β£) inverse p = transp (Ξ» i β β£ p i β£) i0 , transp (Ξ» i β β£ p (~ i) β£) i0 isr : β {A B} β is-right-inverse (inverse {A} {B}) prop-ua isr {A} = J (Ξ» y p β prop-ua (inverse p) β‘ p) prop-ua-id-equiv where postulate -- Safe: ua (transport refl) β‘ refl, the other two components don't -- matter. Can't show this because of the "levels" and "trs" -- postulates. prop-ua-id-equiv : β {A} β prop-ua {A} (transport refl , transport refl) β‘ refl isl : is-left-inverse (inverse {A} {B}) prop-ua isl x = Ξ£-pathp (funext (Ξ» _ β B .is-tr _ _)) (funext (Ξ» _ β A .is-tr _ _))