module 1Lab.Resizing wherePropositional 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 closed computation too much. Specifically, we
can use the evil NO_UNIVERSE_CHECK pragma: 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 Ξ© publicThis type, a priori, only contains the propositions whose underlying
type lives in the first universe. However, we can populate it using a
second NO_UNIVERSE_CHECK pragma, this time forcing the propositional truncation of
an arbitrary type into the first universe.
{-# NO_UNIVERSE_CHECK #-}
data β‘ {β} (A : Type β) : Type where
inc : A β β‘ A
squash : (x y : β‘ A) β x β‘ yJust 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. Thus 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 Ξ©: if
are logically equivalent, then they are equal.
Ξ©-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 id id)
(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 incs, 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
β‘-out-rec : β {β β'} {A : Type β} {X : Type β'} β is-prop A β (A β X) β β‘ A β X
β‘-out-rec A-prop go x = go (β‘-out A-prop x)
β‘-out-elim
: β {β β'} {A : Type β} {P : β‘ A β Type β'}
β is-prop A
β (β x β P (inc x))
β β x β P x
β‘-out-elim {P = P} A-prop go x =
subst P prop! (go (β‘-out A-prop 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!) Ξ» _ β 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) iConnectivesπ
The universe of small propositions contains true, false, conjunctions, disjunctions, and (bi)implications.
infixr 10 _β§Ξ©_
infixr 9 _β¨Ξ©_
infixr 8 _βΞ©_β€Ξ© : Ξ©
β£ β€Ξ© β£ = β€
β€Ξ© .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 ] Binstance
Extensional-Ξ£-β‘
: β {β β' βr} {A : Type β} {B : A β Type β'}
β β¦ ea : Extensional A βr β¦ β Extensional (Ξ£ A Ξ» x β β‘ (B x)) βr
Extensional-Ξ£-β‘ β¦ ea β¦ = Ξ£-prop-extensional (Ξ» x β hlevel 1) eaThese 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)