{-# OPTIONS --without-K --exact-split #-}
module _ where

open import BasicTypes
open import BasicFunctions

Hlevel types

Higher levels of the homotopical structure:

  • Contractible types (\(-2\))
  • Propositions (\(-1\))
  • Sets (\(0\))
  • Groupoids (\(1\))

Contractible types

A contractible type is a type such that every element is equal to a point, the center of contraction.

isContr
  :  {: Level} (A : Type ℓ)
  --------------
   Type ℓ

isContr A = Σ A (λ a  ((x : A)  a == x))

Synonym:

Contractible = isContr
is-singleton = isContr
isSingleton  = isContr
_is-contr    = isContr

If a type is contractible, any of its points is a center of contraction:

<img “src=”assets/images/issinglenton.png” width=“400” align=“right”>

contr-connects
  :  {: Level} {A : Type ℓ}
   A is-contr
  ----------------------
   (a a' : A)  a ≡ a'

contr-connects (c₁ , f) c₂ x = ! (f c₂) · (f x)

Propositions

A type is a mere proposition if any two inhabitants of the type are equal.

isProp
  :  {: Level} (A : Type ℓ)  Type ℓ

isProp A = ((x y : A)  x == y)

More syntax:

is-subsingleton = isProp
isSubsingleton  = isProp
_is-prop         = isProp

Let’s stop a bit. So, these propositios, also named “mere” propositions tell us: in a proposition, its elements are connected with each other. Subsinglenton (which is, subset of a singlenton (a unit point set)) is empty or it has the element. Propositions can be seen as equivalent to 𝟘 or 𝟙.

  • Contractible types ≃ 𝟙
  • Propositions ≃ (𝟘 if it’s not inhabited or 𝟙 if it’s inhabited)

Therefore, we will find a theorem later that says “if A is a proposition, and it’s inhabited then it’s contractible”, and it makes sense perfectly.

hProp
  :  (: Level)  Type (lsuc ℓ)

hProp ℓ =(Type ℓ) isProp

In practice, we might want to say a type holds certain property and then we can use the convenient following predicate.

_has-property_
  :  {: Level}
   (A : Type ℓ)
   (P : Type ℓ  hProp ℓ)
   Type ℓ

A has-property P = π₁ (P A)

_holds-property = _has-property_
_has-fun-property_
  :  {ℓ₁ ℓ₂ : Level} {X : Type ℓ₁}{Y : Type ℓ₂}
   (f : X  Y)
   (P :  {X : Type ℓ₁}{Y : Type ℓ₂}  (X  Y)  hProp (ℓ₁ ⊔ ℓ₂))
   Type (ℓ₁ ⊔ ℓ₂)

f has-fun-property P = π₁ (P f)
_has-endo-property_
  :  {ℓ₁ ℓ₂ : Level} {X : Type ℓ₁}
   (f : X  X)
   (P :  {X : Type ℓ₁}  (X  X)  hProp ℓ₂)
   Type ℓ₂

f has-endo-property P = π₁ (P f)

Additionally, we may need to say, more explicity that two type share any property whenever they are equivalent. Recall, these types do not need to be in the same universe, however, for simplicity and to avoid dealing with lifting types, we’ll assume they live in the same universe. Also, we require a path, instead of the equivalence because at this point, we have not define yet its type.

_has-all-properties-of_because-of-≡_
    :  {: Level}
     (A : Type ℓ)
     (B : Type ℓ)
     A ≡ B
    -------------------------------------
     (P : Type ℓ  hProp ℓ)
     B has-property P  A has-property P

A has-all-properties-of B because-of-≡ path
  = λ P BholdsP  tr (_has-property P) (! path) BholdsP
  where open import Transport

Now with (homotopy) propositional, we can consider the notion of subtype, which is, just the ∑-type about the collection of terms that holds some given property, we can use the following type sub-type for a proposition \(P : A → U\) for some type \(A\). Assuming at least there

subtype
  :  {: Level} {A : Type ℓ}
   (P : A  hProp ℓ)
   Type ℓ

subtype P =(domain P) (π₁ ∘ P)

We prove now that the basic type (⊥, ⊤) are indeed (mere) propositions:

⊥-is-prop :  {: Level}   isProp (⊥ ℓ)
⊥-is-prop ()
⊤-is-prop :  {: Level}   isProp (⊤ ℓ)
⊤-is-prop _ _ = idp

More syntax:

𝟘-is-prop = ⊥-is-prop
𝟙-is-prop = ⊤-is-prop

Sets

A type is a set& by definition if any two equalities on the type are equal Sets are types without any higherdimensional structure*, all parallel paths are homotopic and the homotopy is given by a continuous function on the two paths.

isSet
  :  {: Level}  Type ℓ  Type ℓ
isSet A = (x y : A)  isProp (x == y)

More syntax:

_is-set = isSet

The type of sets

hSet
  :   (: Level)  Type (lsuc ℓ)

hSet ℓ =(Type ℓ) isSet

Groupoids

isGroupoid
  :  {: Level}  Type ℓ  Type ℓ

isGroupoid A  = (a₀ a₁ : A)  isSet (a₀ ≡ a₁)

More syntax:

_is-groupoid = isGroupoid
Groupoid
  :  (: Level)  Type (lsuc ℓ)

Groupoid ℓ =(Type ℓ) isGroupoid

And, in case, we go a bit further, we have 2-groupoids. We can continue define more h-levels for all natural numbers, however, we are not going to use them.

is-2-Groupoid
   :  {: Level}  Type ℓ  Type ℓ

is-2-Groupoid A  = (a₀ a₁ : A)  isGroupoid (a₀ ≡ a₁)

is-2-groupoid = is-2-Groupoid