module Data.Partial.Properties where
private variable
: Level
o o' â„“ : Type â„“
A B C X Y
abstract
Properties of partial elements🔗
This module establishes some elementary properties of partial elements, and the information ordering on them. First, as long as is a set, the information ordering is an actual poset:
: {x : ↯ A} → x ⊑ x
⊑-refl .implies x-def = x-def
⊑-refl .refines _ = refl
⊑-refl
: {x y z : ↯ A} → x ⊑ y → y ⊑ z → x ⊑ z
⊑-trans .implies = q .implies ∘ p .implies
⊑-trans p q {x = x} {y} {z} p q .refines x-def =
⊑-trans .elt _ ≡⟨ q .refines (p .implies x-def) ⟩
z .elt _ ≡⟨ p .refines x-def ⟩
y .elt _ ∎
x
: {x y : ↯ A} → x ⊑ y → y ⊑ x → x ≡ y
⊑-antisym {x = x} {y = y} p q = part-ext (p .implies) (q .implies) λ xd yd →
⊑-antisym .refines yd ↯-indep x ∙ q
We actually have that never
is
the bottom element, as claimed:
: {x : ↯ A} → never ⊑ x
never-⊑ .implies ()
never-⊑ .refines () never-⊑
Our mapping operation preserves ordering, is functorial, and preserves the bottom element:
part-map-⊑: ∀ {f : A → B} {x y : ↯ A}
→ x ⊑ y → part-map f x ⊑ part-map f y
.implies = p .implies
part-map-⊑ p {f = f} p .refines d = ap f (p .refines d)
part-map-⊑
: ∀ (x : ↯ A) → part-map (λ a → a) x ≡ x
part-map-id = part-ext id id λ _ _ →
part-map-id x
↯-indep x
part-map-∘: ∀ (f : B → C) (g : A → B)
→ ∀ (x : ↯ A) → part-map (f ∘ g) x ≡ part-map f (part-map g x)
= part-ext id id λ _ _ →
part-map-∘ f g x (f ∘ g) (↯-indep x)
ap
: ∀ {f : A → B} {x} → part-map f never ⊑ x
part-map-never .implies ()
part-map-never .refines () part-map-never
Finally, we can characterise the adjunction-unit-to-be, always
.
: {x y : A} → always x ≡ always y → x ≡ y
always-inj {x = x} p =
always-inj (λ y p → (d : ⌞ y ⌟) → x ≡ y .elt d) (λ _ → refl) p tt
J
: {x : ↯ A} {y : A} → (∀ d → x .elt d ≡ y) → x ⊑ always y
always-⊑ .implies _ = tt
always-⊑ p .refines d = sym (p d)
always-⊑ p
: {x : A} {y : ↯ A} → y ↓ x → always x ⊑ y
always-⊒ (p , q) .implies _ = p
always-⊒ (p , q) .refines _ = q
always-⊒
: {x : A} (f : A → B) → part-map f (always x) ≡ always (f x)
always-natural = part-ext (λ _ → tt) (λ _ → tt) λ _ _ → refl always-natural f
Programming with partial elements🔗
The partial element monad is quite odd from a programming perspective. First, note that if is a proposition, then we can summon up an element of seemingly out of the void.
: (X : Type ℓ) → is-prop X → ↯ X
assume↯ .def = elΩ X
assume↯ X X-prop .elt = □-out X-prop assume↯ X X-prop
We can use a similar trick to create an element of
for an arbitrary type
by using is-contr X
as our domain of definition. This gives
rise to a sort of definite description principle for
: (X : Type ℓ) → ↯ X
desc↯ .def = elΩ (is-contr X)
desc↯ X .elt □contr = □-out! □contr .centre desc↯ X
Partial elements are injective types🔗
The type of partial elements is an injective object for every type
First, observe that we can extend a map along an embedding by sending each to a partial element that is defined when the fibre of over is inhabited by some such that is itself defined.
: (X → ↯ A) → (X ↪ Y) → Y → ↯ A
extend↯ .def = elΩ (Σ[ y* ∈ fibre (e .fst) y ] ⌞ f (y* .fst) ⌟)
extend↯ f e y .elt =
extend↯ f e y (Σ-is-hlevel 1 (e .snd y) (λ _ → hlevel 1))
□-out-rec (λ ((x , _) , fx↓) → f x .elt fx↓)
Proving that the extension of along with is a bit of a chore due to all of the propositional resizing required. The key idea is that both and its extension have equivalent domains of definition, and agree when both are defined essentially by definition.
extends↯: ⦃ _ : H-Level A 2 ⦄
→ (f : X → ↯ A) (e : X ↪ Y)
→ ∀ (x : X) → extend↯ f e (e · x) ≡ f x
Unfortunately, proof assistants. The domain of definition of
extends↯ f e (e · x)
is always a proposition, but we need
to truncate it to resize it into Ω
.
This means that we need to wrap our proofs in a bunch of eliminators,
which makes them quite ugly.
=
extends↯ f e x to from agree
part-ext where
to : ⌞ extend↯ f e (e · x) ⌟ → ⌞ f x ⌟
to = rec! λ x' p fx'↓ →
(λ x → ∣ f x .def ∣)
subst (has-prop-fibres→injective (e .fst) (e .snd) p)
fx'↓
: ⌞ f x ⌟ → ⌞ extend↯ f e (e · x) ⌟
from = pure ((x , refl) , fx↓)
from fx↓
: (fex↓ : ⌞ extend↯ f e (e · x) ⌟) (fx↓ : ⌞ f x ⌟) → extend↯ f e (e · x) .elt fex↓ ≡ f x .elt fx↓
agree =
agree (Σ-is-hlevel 1 (e .snd (e · x)) (λ _ → hlevel 1)) λ where
□-out-elim ((x' , ex'=ex) , fx'↓) fx↓ →
(λ x fx↓ → f x .elt fx↓) (has-prop-fibres→injective (e .fst) (e .snd) ex'=ex) prop! ap₂