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 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-prop β£_β£
is-tr 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
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
: A β β‘ A
inc : (x y : β‘ A) β x β‘ y squash
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. Thus if
is a proposition in any universe,
is its name in the zeroth universe.
instance
: β {β} {T : Type β} {n} β H-Level (β‘ T) (suc n)
H-Level-β‘ = prop-instance squash
H-Level-β‘
open hlevel-projection
: 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 [] Ξ©-hlevel-proj
We can also prove a univalence principle for Ξ©
: if
are logically equivalent, then they are equal.
: {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 =
Ξ©-ua (Ξ» i β is-prop-is-prop {A = ua (prop-ext! f g) i})
is-propβpathp (A .is-tr) (B .is-tr) i
instance abstract
: β {n} β H-Level Ξ© (2 + n)
H-Level-Ξ© = basic-instance 2 $ retractβis-hlevel 2
H-Level-Ξ© (Ξ» 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 inc
s, as usual.
: β {β β'} {A : Type β} {B : Type β'}
β‘-map β (A β B) β β‘ A β β‘ B
(inc x) = inc (f x)
β‘-map f (squash x y i) = squash (β‘-map f x) (β‘-map f y) i
β‘-map f
: β {β β'} {A : Type β} {B : Type β'} β is-prop B β (A β B) β β‘ A β B
β‘-rec (inc x) = f x
β‘-rec bp f (squash x y i) = bp (β‘-rec bp f x) (β‘-rec bp f y) i
β‘-rec bp f
: β {β} (T : Type β) β Ξ©
elΞ© .β£_β£ = β‘ T
elΞ© T .is-tr = squash elΞ© T
β‘-elim: β {β β'} {A : Type β} {P : β‘ A β Type β'}
β (β x β is-prop (P x))
β (β x β P (inc x))
β β x β P x
(inc x) = go x
β‘-elim pprop go (squash x y i) =
β‘-elim pprop go (Ξ» i β pprop (squash x y i)) (β‘-elim pprop go x) (β‘-elim pprop go y) i
is-propβpathp
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
= record
Inductive-β‘ β¦ i β¦ { methods = i .Inductive.methods
; from = Ξ» f β β‘-elim (Ξ» x β hlevel 1) (i .Inductive.from f)
}
: β {β} {A : Type β} β is-prop A β β‘ A β A
β‘-out = β‘-rec ap (Ξ» x β x)
β‘-out ap
β‘-out!: β {β} {A : Type β}
β β¦ _ : H-Level A 1 β¦
β β‘ A β A
= rec! Ξ» x β x
β‘-out!
: β {β β'} {A : Type β} {X : Type β'} β is-prop A β (A β X) β β‘ A β X
β‘-out-rec = go (β‘-out A-prop x)
β‘-out-rec A-prop go x
β‘-out-elim: β {β β'} {A : Type β} {P : β‘ A β Type β'}
β is-prop A
β (β x β P (inc x))
β β x β P x
{P = P} A-prop go x =
β‘-out-elim (go (β‘-out A-prop x))
subst P prop!
β‘-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
: β {β} {A : Type β} β is-prop A β β‘ A β A
β‘-idempotent = prop-ext squash aprop (β‘-out aprop) inc
β‘-idempotent aprop
β‘-ap: β {β β'} {A : Type β} {B : Type β'}
β β‘ (A β B) β β‘ A β β‘ B
(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
β‘-ap
β‘-bind: β {β β'} {A : Type β} {B : Type β'}
β β‘ A β (A β β‘ B) β β‘ B
(inc x) f = f x
β‘-bind (squash x x' i) f = squash (β‘-bind x f) (β‘-bind x' f) i
β‘-bind
instance
: Map (eff β‘)
Map-β‘ .Map.map = β‘-map
Map-β‘
: Idiom (eff β‘)
Idiom-β‘ .Idiom.pure = inc
Idiom-β‘ .Idiom._<*>_ = β‘-ap
Idiom-β‘
: Bind (eff β‘)
Bind-β‘ .Bind._>>=_ = β‘-bind
Bind-β‘
is-setβlocally-small: β {β} {A : Type β}
β is-set A
β is-identity-system {A = A} (Ξ» x y β β‘ (x β‘ y)) (Ξ» x β inc refl)
.to-path = β‘-rec (a-set _ _) id
is-setβlocally-small a-set .to-path-over p = is-propβpathp (Ξ» _ β squash) _ _
is-setβlocally-small a-set
to-is-true: β {P Q : Ξ©} β¦ _ : H-Level β£ Q β£ 0 β¦
β β£ P β£
β P β‘ Q
= Ξ©-ua (Ξ» _ β hlevel!) Ξ» _ β prf
to-is-true prf
: β {β} {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 β‘-tr
Connectivesπ
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 β Ξ©) β Ξ©
βΞ© = β‘ (Ξ£[ x β A ] β£ P x β£)
β£ βΞ© A P β£ .is-tr = squash
βΞ© A P
: β {β} (A : Type β) β (A β Ξ©) β Ξ©
βΞ© = β‘ (β (x : A) β β£ P x β£)
β£ βΞ© A P β£ .is-tr = squash
βΞ© A P
syntax βΞ© A (Ξ» x β B) = βΞ©[ x β A ] B
syntax βΞ© A (Ξ» x β B) = βΞ©[ x β A ] B
instance
Extensional-Ξ£-β‘: β {β β' βr} {A : Type β} {B : A β Type β'}
β β¦ ea : Extensional A βr β¦ β Extensional (Ξ£ A Ξ» x β β‘ (B x)) βr
= Ξ£-prop-extensional (Ξ» x β hlevel 1) ea Extensional-Ξ£-β‘ β¦ ea β¦
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
: Type β'
Ξ©-image = Ξ£[ b β B ] β‘ (fibre f b)
Ξ©-image
: A β Ξ©-image
Ξ©-corestriction = f a , inc (a , refl)
Ξ©-corestriction a
opaque: is-surjective Ξ©-corestriction
Ξ©-corestriction-is-surjective = elim! Ξ» y x fx=y β pure (x , Ξ£-prop-path! fx=y) Ξ©-corestriction-is-surjective