module 1Lab.Resizing where
Propositional resizingπ
Ordinarily, the collection of all predicates on types lives in the next universe up, This is because predicates are not special in type theory: they are ordinary type families, that just so happen to be valued in propositions. For most purposes we can work with this limitation: this is called predicative mathematics. But, for a few classes of theorems, predicativity is too restrictive: Even if we donβt have a single universe of propositions that can accommodate all predicates, we would still like for universes to be closed under power-sets.
Using some of Agdaβs more suspicious features, we can achieve this in
a way which does not break computation too much. Specifically, weβll use
a combination of NO_UNIVERSE_CHECK
, postulates, and rewrite
rules.
We start with the NO_UNIVERSE_CHECK
part: We define the
small type of propositions, Ξ©
, to be a
record containing a Type
(together with an irrelevant proof
that this type is a proposition), but contrary to the universe checker,
which would like us to put Ξ© : Typeβ
, we instead force
Ξ© : Type
.
{-# NO_UNIVERSE_CHECK #-} record Ξ© : Type where constructor el field β£_β£ : Type is-tr : is-prop β£_β£ open Ξ© public
This type, a priori, only contains the propositions whose underlying
type lives in the first universe. However, we can populate it using a
NO_UNIVERSE_CHECK
-powered higher inductive type, the βsmall
propositional
truncationβ:
{-# NO_UNIVERSE_CHECK #-} data β‘ {β} (A : Type β) : Type where inc : A β β‘ A squash : (x y : β‘ A) β x β‘ y
Just like the ordinary propositional truncation, every type can be
squashed, but unlike the ordinary propositional truncation, the β‘
-squashing of a type always
lives in the lowest universe. If
is a proposition in any universe,
is its name in the zeroth universe.
instance H-Level-β‘ : β {β} {T : Type β} {n} β H-Level (β‘ T) (suc n) H-Level-β‘ = prop-instance squash open hlevel-projection Ξ©-hlevel-proj : hlevel-projection (quote Ξ©.β£_β£) Ξ©-hlevel-proj .has-level = quote Ξ©.is-tr Ξ©-hlevel-proj .get-level x = pure (quoteTerm (suc zero)) Ξ©-hlevel-proj .get-argument (arg _ t β· _) = pure t Ξ©-hlevel-proj .get-argument _ = typeError []
We can also prove a univalence principle for Ξ©
:
Ξ©-ua : {A B : Ξ©} β (β£ A β£ β β£ B β£) β (β£ B β£ β β£ A β£) β A β‘ B Ξ©-ua {A} {B} f g i .β£_β£ = ua (prop-ext! f g) i Ξ©-ua {A} {B} f g i .is-tr = is-propβpathp (Ξ» i β is-prop-is-prop {A = ua (prop-ext! f g) i}) (A .is-tr) (B .is-tr) i instance abstract H-Level-Ξ© : β {n} β H-Level Ξ© (2 + n) H-Level-Ξ© = basic-instance 2 $ retractβis-hlevel 2 (Ξ» r β el β£ r β£ (r .is-tr)) (Ξ» r β el β£ r β£ (r .is-tr)) (Ξ» x β Ξ©-ua (Ξ» x β x) Ξ» x β x) (n-Type-is-hlevel {lzero} 1)
The β‘
type former is a functor (in
the handwavy sense that it supports a βmapβ operation), and can be
projected from into propositions of any universe. These functions
compute on inc
s, as usual.
β‘-map : β {β β'} {A : Type β} {B : Type β'} β (A β B) β β‘ A β β‘ B β‘-map f (inc x) = inc (f x) β‘-map f (squash x y i) = squash (β‘-map f x) (β‘-map f y) i β‘-rec : β {β β'} {A : Type β} {B : Type β'} β is-prop B β (A β B) β β‘ A β B β‘-rec bp f (inc x) = f x β‘-rec bp f (squash x y i) = bp (β‘-rec bp f x) (β‘-rec bp f y) i elΞ© : β {β} (T : Type β) β Ξ© elΞ© T .β£_β£ = β‘ T elΞ© T .is-tr = squash
β‘-elim : β {β β'} {A : Type β} {P : β‘ A β Type β'} β (β x β is-prop (P x)) β (β x β P (inc x)) β β x β P x β‘-elim pprop go (inc x) = go x β‘-elim pprop go (squash x y i) = is-propβpathp (Ξ» i β pprop (squash x y i)) (β‘-elim pprop go x) (β‘-elim pprop go y) i instance Inductive-β‘ : β {β β' βm} {A : Type β} {P : β‘ A β Type β'} β¦ i : Inductive (β x β P (inc x)) βm β¦ β β¦ _ : β {x} β H-Level (P x) 1 β¦ β Inductive (β x β P x) βm Inductive-β‘ β¦ i β¦ = record { methods = i .Inductive.methods ; from = Ξ» f β β‘-elim (Ξ» x β hlevel 1) (i .Inductive.from f) } β‘-out : β {β} {A : Type β} β is-prop A β β‘ A β A β‘-out ap = β‘-rec ap (Ξ» x β x) β‘-out! : β {β} {A : Type β} β β¦ _ : H-Level A 1 β¦ β β‘ A β A β‘-out! = rec! Ξ» x β x β‘-rec-set : β {β β'} {A : Type β} {B : Type β'} β is-set B β (f : A β B) β (β x y β f x β‘ f y) β β‘ A β B β‘-rec-set B-set f f-const a = fst $ β‘-elim (Ξ» _ β is-constantβimage-is-prop B-set f f-const) (Ξ» a β f a , inc (a , refl)) a β‘-idempotent : β {β} {A : Type β} β is-prop A β β‘ A β A β‘-idempotent aprop = prop-ext squash aprop (β‘-out aprop) inc β‘-ap : β {β β'} {A : Type β} {B : Type β'} β β‘ (A β B) β β‘ A β β‘ B β‘-ap (inc f) (inc g) = inc (f g) β‘-ap (inc f) (squash g g' i) = squash (β‘-ap (inc f) g) (β‘-ap (inc f) g') i β‘-ap (squash f f' i) g = squash (β‘-ap f g) (β‘-ap f' g) i β‘-bind : β {β β'} {A : Type β} {B : Type β'} β β‘ A β (A β β‘ B) β β‘ B β‘-bind (inc x) f = f x β‘-bind (squash x x' i) f = squash (β‘-bind x f) (β‘-bind x' f) i instance Map-β‘ : Map (eff β‘) Map-β‘ .Map.map = β‘-map Idiom-β‘ : Idiom (eff β‘) Idiom-β‘ .Idiom.pure = inc Idiom-β‘ .Idiom._<*>_ = β‘-ap Bind-β‘ : Bind (eff β‘) Bind-β‘ .Bind._>>=_ = β‘-bind is-setβlocally-small : β {β} {A : Type β} β is-set A β is-identity-system {A = A} (Ξ» x y β β‘ (x β‘ y)) (Ξ» x β inc refl) is-setβlocally-small a-set .to-path = β‘-rec (a-set _ _) id is-setβlocally-small a-set .to-path-over p = is-propβpathp (Ξ» _ β squash) _ _ to-is-true : β {P Q : Ξ©} β¦ _ : H-Level β£ Q β£ 0 β¦ β β£ P β£ β P β‘ Q to-is-true prf = Ξ©-ua (Ξ» _ β hlevel 0 .centre) (Ξ» _ β prf) tr-β‘ : β {β} {A : Type β} β β₯ A β₯ β β‘ A tr-β‘ (inc x) = inc x tr-β‘ (squash x y i) = squash (tr-β‘ x) (tr-β‘ y) i β‘-tr : β {β} {A : Type β} β β‘ A β β₯ A β₯ β‘-tr (inc x) = inc x β‘-tr (squash x y i) = squash (β‘-tr x) (β‘-tr y) i
Connectivesπ
The universe of small propositions contains true, false, conjunctions, disjunctions, and implications.
β€Ξ© : Ξ© β£ β€Ξ© β£ = β€ β€Ξ© .is-tr = hlevel 1 β₯Ξ© : Ξ© β£ β₯Ξ© β£ = β₯ β₯Ξ© .is-tr = hlevel 1 _β§Ξ©_ : Ξ© β Ξ© β Ξ© β£ P β§Ξ© Q β£ = β£ P β£ Γ β£ Q β£ (P β§Ξ© Q) .is-tr = hlevel 1 _β¨Ξ©_ : Ξ© β Ξ© β Ξ© β£ P β¨Ξ© Q β£ = β₯ β£ P β£ β β£ Q β£ β₯ (P β¨Ξ© Q) .is-tr = hlevel 1 _βΞ©_ : Ξ© β Ξ© β Ξ© β£ P βΞ© Q β£ = β£ P β£ β β£ Q β£ (P βΞ© Q) .is-tr = hlevel 1 ¬Ω_ : Ξ© β Ξ© ¬Ω P = P βΞ© β₯Ξ©
Furthermore, we can quantify over types of arbitrary size and still
land in Ξ©
.
βΞ© : β {β} (A : Type β) β (A β Ξ©) β Ξ© β£ βΞ© A P β£ = β‘ (Ξ£[ x β A ] β£ P x β£) βΞ© A P .is-tr = squash βΞ© : β {β} (A : Type β) β (A β Ξ©) β Ξ© β£ βΞ© A P β£ = β‘ (β (x : A) β β£ P x β£) βΞ© A P .is-tr = squash syntax βΞ© A (Ξ» x β B) = βΞ©[ x β A ] B syntax βΞ© A (Ξ» x β B) = βΞ©[ x β A ] B
These connectives and quantifiers are only provided for completeness; if you find yourself building nested propositions, it is generally a good idea to construct the large proposition by hand, and then use truncation to turn it into a small proposition.
module _ {β β'} {A : Type β} {B : Type β'} (f : A β B) where Ξ©-image : Type β' Ξ©-image = Ξ£[ b β B ] β‘ (fibre f b) Ξ©-corestriction : A β Ξ©-image Ξ©-corestriction a = f a , inc (a , refl) opaque Ξ©-corestriction-is-surjective : is-surjective Ξ©-corestriction Ξ©-corestriction-is-surjective = elim! Ξ» y x fx=y β pure (x , Ξ£-prop-path! fx=y)