module 1Lab.Type.Sigma.Basis where
Σ-bases of types🔗
Like most type formers, types have a universal property: for every pair of functions there is a unique universal map that commutes with first and second projections. In other words, a type is the universal type equipped with a pair of projections
This means that “being a type” is a property of a type equipped with a pair of functions This leads us to the following notion.
private variable
: Level
ℓ ℓ' ℓ'' : Type ℓ
T A A' X X' Y Y' Z Z' : A → Type ℓ
B P Q : X → A
p₁ : (x : X) → B (p₁ x) p₂
A pair of functions form a of when the induced map is an equivalence.
record is-Σ-basis
{ℓa ℓb ℓx}
(X : Type ℓx)
(A : Type ℓa) (B : A → Type ℓb)
(p₁ : X → A) (p₂ : (x : X) → B (p₁ x))
: Type (ℓa ⊔ ℓb ⊔ ℓx) where
field
: is-equiv {B = Σ A B} ⟨ p₁ , p₂ ⟩ ⟨⟩-equiv
The intuition behind the name “basis” is that a choice of of allows us to write elements of as a sum of elements of
: X ≃ Σ A B
basis = _ , ⟨⟩-equiv
basis
module basis = Equiv basis
Likewise, an of consists of a pair of maps that form a of
record Σ-basis
{ℓa ℓb ℓx}
(X : Type ℓx)
(A : Type ℓa) (B : A → Type ℓb)
: Type (ℓa ⊔ ℓb ⊔ ℓx) where
field
: X → A
proj₁ : (x : X) → B (proj₁ x)
proj₂ : is-Σ-basis X A B proj₁ proj₂
has-basis
open is-Σ-basis has-basis public
Note that we could have equivalently defined in terms of a single map
is-equiv→is-Σ-basis: ∀ {f : X → Σ A B}
→ is-equiv f
→ is-Σ-basis X A B (fst ∘ f) (snd ∘ f)
.is-Σ-basis.⟨⟩-equiv .is-eqv ab = eqv .is-eqv ab
is-equiv→is-Σ-basis eqv
Equiv→Σ-basis: X ≃ Σ A B
→ Σ-basis X A B
.Σ-basis.proj₁ x = fst (Equiv.to f x)
Equiv→Σ-basis f .Σ-basis.proj₂ x = snd (Equiv.to f x)
Equiv→Σ-basis f .Σ-basis.has-basis = is-equiv→is-Σ-basis (f .snd) Equiv→Σ-basis f
is-iso→is-Σ-basis: {p₁ : X → A} {p₂ : (x : X) → B (p₁ x)}
→ is-iso {B = Σ A B} ⟨ p₁ , p₂ ⟩
→ is-Σ-basis X A B p₁ p₂
.is-Σ-basis.⟨⟩-equiv = is-iso→is-equiv isom
is-iso→is-Σ-basis isom
is-Σ-basis→Σ-basis: {p₁ : X → A} {p₂ : (x : X) → B (p₁ x)}
→ is-Σ-basis X A B p₁ p₂
→ Σ-basis X A B
= record { has-basis = p₁-p₂-basis }
is-Σ-basis→Σ-basis p₁-p₂-basis {-# INLINE is-Σ-basis→Σ-basis #-}
Iso→Σ-basis: Iso X (Σ A B)
→ Σ-basis X A B
= Equiv→Σ-basis (Iso→Equiv f)
Iso→Σ-basis f {-# INLINE Iso→Σ-basis #-}
Examples of Σ-bases🔗
module _ where
open is-Σ-basis
The first and second projections out of form an
: is-Σ-basis (Σ A B) A B fst snd
fst-snd-is-Σ-basis .⟨⟩-equiv = id-equiv fst-snd-is-Σ-basis
More interestingly, if form a of then and form a for the path space of
ap-is-Σ-basis: {p₁ : X → A} {p₂ : (x : X) → B (p₁ x)}
→ ∀ {x y : X}
→ is-Σ-basis X A B p₁ p₂
→ is-Σ-basis (x ≡ y) (p₁ x ≡ p₁ y) (λ p → PathP (λ i → B (p i)) (p₂ x) (p₂ y))
(ap p₁)
(ap p₂)
The proof is a nice equivalence chase. Our ultimate goal is to show that is an equivalence. However, we know that paths in types are equivalent to pairs of paths, so we can use 2-for-3 for equivalences to reduce the problem to showing that is an equivalence. This just is another way of asking that is an embedding, and every equivalence is an embedding!
{p₁ = p₁} {p₂ = p₂} {x = x} {y = y} ΣX .⟨⟩-equiv =
ap-is-Σ-basis (Σ-pathp≃ .snd) ⟩
is-equiv ⟨ ap p₁ , ap p₂ ⟩ ←⟨ equiv-cancell (ap ⟨ p₁ , p₂ ⟩) ←⟨ equiv→cancellable ⟩
is-equiv .⟨⟩-equiv ⟩∎ is-equiv ⟨ p₁ , p₂ ⟩ ←⟨ ΣX
We can also lift to function types: if form a for then and form a for
postcompose-is-Σ-basis: {p₁ : Y → A} {p₂ : (y : Y) → B (p₁ y)}
→ is-Σ-basis Y A B p₁ p₂
→ is-Σ-basis (X → Y) (X → A) (λ f → (x : X) → B (f x)) (p₁ ∘_) (p₂ ∘_)
This follows a similar line of reasoning as the previous proof. We start by using 2-for-3 for equivalences to distribute the postcomposition out of the universal map. Next, precomposition by an equivalence is itself an equivalence, so it suffices to show that is an equivalence, which is exactly our hypothesis.
{Y = Y} {A = A} {B = B} {X = X} {p₁ = p₁} {p₂ = p₂} ΣY .⟨⟩-equiv =
postcompose-is-Σ-basis _ , p₂ ∘_ ⟩ ←⟨ equiv-cancell (inverse-is-equiv (Σ-Π-distrib .snd)) ⟩
is-equiv ⟨ p₁ ∘(⟨ p₁ , p₂ ⟩ ∘_) ←⟨ precompose-is-equiv ⟩
is-equiv .⟨⟩-equiv ⟩∎ is-equiv ⟨ p₁ , p₂ ⟩ ←⟨ ΣY
Combining Σ-bases🔗
The following series of lemmas describe various ways we can combine
module _
{ℓx ℓp ℓa ℓb ℓc ℓd}
{X : Type ℓx} {P : X → Type ℓp}
{A : Type ℓa} {B : A → Type ℓb}
{C : (a : A) → Type ℓc} {D : (a : A) → B a → C a → Type ℓd}
where
open Σ-basis
If has a and has a for every then can be equipped with a basis.
Σ-basis-swap₂: (ΣX : Σ-basis X A B)
→ (ΣP : ∀ x → Σ-basis (P x) (C (ΣX .proj₁ x)) (D (ΣX .proj₁ x) (ΣX .proj₂ x)))
→ Σ-basis (Σ X P) (Σ A C) (λ ac → Σ[ b ∈ B (ac .fst) ] D (ac .fst) b (ac .snd))
The key here is that the basis of is only allowed depend on the first component of the of so we can commute the and components of the iterated type we get after expanding out
=
Σ-basis-swap₂ ΣX ΣP
Equiv→Σ-basis $(basis ΣX) (λ x → basis (ΣP x)) ⟩
Σ X P ≃⟨ Σ-ap (a , b) ∈ Σ A B ] Σ[ c ∈ C a ] D a b c ≃˘⟨ Σ-assoc ⟩
Σ[ (λ a → Σ-swap₂) ⟩
Σ[ a ∈ A ] Σ[ b ∈ B a ] Σ[ c ∈ C a ] D a b c ≃⟨ Σ-ap-snd
Σ[ a ∈ A ] Σ[ c ∈ C a ] Σ[ b ∈ B a ] D a b c ≃⟨ Σ-assoc ⟩(a , c) ∈ Σ A C ] Σ[ b ∈ B a ] D a b c ≃∎ Σ[
module _
{ℓx ℓa ℓb ℓy ℓc ℓd ℓz ℓe ℓf}
{X : Type ℓx} {A : Type ℓa} {B : A → Type ℓb}
{Y : Type ℓy} {C : Type ℓc} {D : C → Type ℓd}
{Z : Y → Type ℓz} {E : (c : C) → Type ℓe} {F : (c : C) → D c → E c → Type ℓf}
where
open Σ-basis
Our previous lemma gives us a useful technique for constructing To show that has a it suffices to show that:
- has a basis; and
- has a basis; and
- For every has a basis; and
- has a basis; and finally
- for every has a
This is particularly useful for constructing of record types whose first and second components are also record types: the first three bases for and let us give decompositions of record types into types, and the final two bases let us re-arrange the components of those decompositions back into place.
Σ-basis-shuffle: (ΣX : Σ-basis X A B)
→ (ΣY : Σ-basis Y C E)
→ (ΣZ : ∀ {y} → Σ-basis (Z y) (D (ΣY .proj₁ y)) (λ d → F (ΣY .proj₁ y) d (ΣY .proj₂ y)))
→ (ΣA : Σ-basis A C D)
→ (ΣB : ∀ {a} → Σ-basis (B a) (E (ΣA .proj₁ a)) λ e → F (ΣA .proj₁ a) (ΣA .proj₂ a) e)
→ Σ-basis X Y Z
=
Σ-basis-shuffle ΣX ΣY ΣZ ΣA ΣB
Equiv→Σ-basis $
X ≃⟨ basis ΣX ⟩(Σ-basis-swap₂ ΣA (λ a → ΣB)) ⟩
Σ A B ≃⟨ basis (c , e) ∈ Σ C E ] Σ[ d ∈ D c ] F c d e ≃˘⟨ Σ-ap (basis ΣY) (λ _ → basis ΣZ) ⟩
Σ[ Σ Y Z ≃∎
-- Bundled forms of is-Σ-basis results.
module _ where
open Σ-basis
: Σ-basis (Σ A B) A B
Σ-Σ-basis = is-Σ-basis→Σ-basis fst-snd-is-Σ-basis
Σ-Σ-basis {-# INLINE Σ-Σ-basis #-}
Path-Σ-basis: {x y : X}
→ (ΣX : Σ-basis X A B)
→ Σ-basis (x ≡ y)
(ΣX .proj₁ x ≡ ΣX .proj₁ y)
(λ p → PathP (λ i → B (p i)) (ΣX .proj₂ x) (ΣX .proj₂ y))
= is-Σ-basis→Σ-basis (ap-is-Σ-basis (ΣX .has-basis))
Path-Σ-basis ΣX {-# INLINE Path-Σ-basis #-}
Σ-bases and h-levels🔗
A is an encoding of an equivalence so we can use them to characterise the h-levels of types.
Σ-basis→is-hlevel: (n : Nat)
→ Σ-basis X A B
→ (is-hlevel A n)
→ (∀ (a : A) → is-hlevel (B a) n)
→ is-hlevel X n
Σ-basis→is-contr: Σ-basis X A B
→ (A-contr : is-contr A)
→ (B-contr : is-contr (B (A-contr .centre)))
→ is-contr X
The proofs of these facts are straightforward: h-levels are invariant under equivalences, and we can characterise the h-levels of types via their components.
=
Σ-basis→is-hlevel n ΣX A-hl B-hl (basis ΣX) $
Equiv→is-hlevel n
Σ-is-hlevel n A-hl B-hl
=
Σ-basis→is-contr ΣX A-contr B-contr 0 (basis ΣX) (Σ-is-contr A-contr B-contr) Equiv→is-hlevel
Σ-bases and identity systems🔗
Every for a type induces an identity system on where paths are coded by a path in and a path over that path in
is-Σ-basis→identity-system: {p₁ : X → A} {p₂ : (x : X) → B (p₁ x)}
→ is-Σ-basis X A B p₁ p₂
→ is-identity-system
(λ x y → Σ[ p ∈ p₁ x ≡ p₁ y ] PathP (λ i → B (p i)) (p₂ x) (p₂ y))
(λ x → refl , refl)
{p₁ = p₁} {p₂ = p₂} ΣX =
is-Σ-basis→identity-system
equiv-path→identity-system $(⟨ ap p₁ , ap p₂ ⟩ , ap-is-Σ-basis ΣX .is-Σ-basis.⟨⟩-equiv) e⁻¹
module _
{R : X → X → Type ℓ} {S : A → A → Type ℓ'} {T : ∀ {a a'} → B a → B a' → S a a' → Type ℓ''}
{r : (x : X) → R x x} {s : (a : A) → S a a}
where
open Σ-basis
We can generalize the previous lemma to get a general strategy for forming identity systems via To start, let be a type with an and be a correspondence on that has an where and
If there is some such that is an identity system and is a proposition for all and then is an identity system on
Σ-basis→total-identity-system: (ΣX : Σ-basis X A B)
→ (ΣR : ∀ {x y} → Σ-basis (R x y) (S (ΣX .proj₁ x) (ΣX .proj₁ y)) (T (ΣX .proj₂ x) (ΣX .proj₂ y)))
→ is-identity-system S s
→ (∀ {a a'} → (p : S a a') (b : B a) → is-prop (Σ[ b' ∈ B a' ] T b b' p))
→ is-identity-system R r
The type signature of this lemma is scarier than the proof. To start, recall that is an identity system on if and only if the type is a proposition for every We shall proceed by constructing a basis on
Our assumptions state that has a and has a for every Moreover, the first component of the basis of is which does not depend on the second component of the basis of This means that forms a for Finally, is contractible, as is an identity system, and is a proposition by our assumptions, so must be a proposition, which in turn implies that must also be a proposition.
=
Σ-basis→total-identity-system ΣX ΣR ids idt λ {x} →
singleton-prop→identity-system 1
Σ-basis→is-hlevel (R-singleton-Σ-basis x)
(is-contr→is-prop (is-contr-ΣR ids))
(λ as → idt (as .snd) (ΣX .proj₂ x))
where
R-singleton-Σ-basis: ∀ (x : X)
→ Σ-basis (Σ X (R x))
(Σ[ a ∈ A ] S (ΣX .proj₁ x) a)
(λ (a , c) → Σ[ b ∈ B a ] T (ΣX .proj₂ x) b c)
= Σ-basis-swap₂ ΣX (λ y → ΣR {x} {y}) R-singleton-Σ-basis x
Reasoning🔗
module _ {ℓx ℓa ℓb} {X : Type ℓx} {A : Type ℓa} {B : A → Type ℓb} where
open Σ-basis
record Σ-basis-path (ΣX : Σ-basis X A B) {a a' : A} (b : B a) (b' : B a') : Type ℓx where
no-eta-equality
field
: basis.from ΣX (a , b) ≡ basis.from ΣX (a' , b')
path
: a ≡ a'
base = ap fst $ Equiv.injective (basis ΣX e⁻¹) path
base
: PathP (λ i → B (base i)) b b'
over = ap snd $ Equiv.injective (basis ΣX e⁻¹) path
over
open Σ-basis-path
via-Σ-basis: {a a' : A} {b : B a} {b' : B a'}
→ (ΣX : Σ-basis X A B)
→ (p : Σ-basis-path ΣX b b')
→ PathP (λ i → B (base p i)) b b'
= over p
via-Σ-basis ΣX p
Σ-basis-path-step: {ΣX : Σ-basis X A B}
→ ∀ {a a' a''} {b' : B a'} {b'' : B a''}
→ (b : B a)
→ Σ-basis-path ΣX b' b''
→ basis.from ΣX (a , b) ≡ basis.from ΣX (a' , b')
→ Σ-basis-path ΣX b b''
{ΣX = ΣX} b q p .Σ-basis-path.path = p ∙ q .path
Σ-basis-path-step
_∎Σ : ∀ {ΣX : Σ-basis X A B} {a : A} (b : B a) → Σ-basis-path ΣX b b
= record { path = refl }
b ∎Σ
syntax Σ-basis-path-step b q p = b ≡Σ⟨ p ⟩ q
infixr 2 Σ-basis-path-step
infix 3 _∎Σ