# Functoriality of set truncation ```agda module foundation.functoriality-set-truncation where ``` <details><summary>Imports</summary> ```agda open import foundation.action-on-identifications-functions open import foundation.dependent-pair-types open import foundation.functoriality-truncation open import foundation.images open import foundation.injective-maps open import foundation.propositional-truncations open import foundation.set-truncations open import foundation.sets open import foundation.slice open import foundation.surjective-maps open import foundation.uniqueness-image open import foundation.uniqueness-set-truncations open import foundation.universal-property-image open import foundation.universal-property-set-truncation open import foundation.universe-levels open import foundation.whiskering-homotopies-composition open import foundation-core.contractible-types open import foundation-core.embeddings open import foundation-core.equivalences open import foundation-core.fibers-of-maps open import foundation-core.function-types open import foundation-core.functoriality-dependent-pair-types open import foundation-core.homotopies open import foundation-core.identity-types open import foundation-core.propositions open import foundation-core.truncation-levels ``` </details> ## Idea The [universal property of the set truncation](foundation.universal-property-set-truncation.md) implies that the [set truncation](foundation.set-truncations.md) acts functorially on maps between types. ## Definitions ### The functorial action of set-truncations on maps ```agda module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A → B) where abstract unique-map-trunc-Set : is-contr ( Σ ( type-trunc-Set A → type-trunc-Set B) ( λ h → (h ∘ unit-trunc-Set) ~ (unit-trunc-Set ∘ f))) unique-map-trunc-Set = unique-map-trunc zero-𝕋 f map-trunc-Set : type-trunc-Set A → type-trunc-Set B map-trunc-Set = map-trunc zero-𝕋 f naturality-unit-trunc-Set : map-trunc-Set ∘ unit-trunc-Set ~ unit-trunc-Set ∘ f naturality-unit-trunc-Set = naturality-unit-trunc zero-𝕋 f htpy-uniqueness-map-trunc-Set : (h : type-trunc-Set A → type-trunc-Set B) → (H : h ∘ unit-trunc-Set ~ unit-trunc-Set ∘ f) → map-trunc-Set ~ h htpy-uniqueness-map-trunc-Set = htpy-uniqueness-map-trunc zero-𝕋 f ``` ### Functorial action of set-truncation on binary maps ```agda module _ {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {C : UU l3} (f : A → B → C) where binary-map-trunc-Set : type-trunc-Set A → type-trunc-Set B → type-trunc-Set C binary-map-trunc-Set x y = map-trunc-Set ( λ (x' , y') → f x' y') ( map-inv-equiv-distributive-trunc-product-Set A B (x , y)) ``` ## Properties ### The functorial action of set truncations preserves identity maps ```agda id-map-trunc-Set : {l1 : Level} {A : UU l1} → map-trunc-Set (id {A = A}) ~ id id-map-trunc-Set = id-map-trunc zero-𝕋 ``` ### The functorial action of set truncations preserves composition ```agda preserves-comp-map-trunc-Set : {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {C : UU l3} (g : B → C) (f : A → B) → map-trunc-Set (g ∘ f) ~ (map-trunc-Set g ∘ map-trunc-Set f) preserves-comp-map-trunc-Set = preserves-comp-map-trunc zero-𝕋 ``` ### The functorial action of set truncations preserves homotopies ```agda htpy-trunc-Set : {l1 l2 : Level} {A : UU l1} {B : UU l2} {f g : A → B} → (f ~ g) → (map-trunc-Set f ~ map-trunc-Set g) htpy-trunc-Set = htpy-trunc ``` ### The functorial action of set truncations preserves equivalences ```agda map-equiv-trunc-Set : {l1 l2 : Level} {A : UU l1} {B : UU l2} → (A ≃ B) → type-trunc-Set A → type-trunc-Set B map-equiv-trunc-Set = map-equiv-trunc zero-𝕋 is-equiv-map-trunc-Set : {l1 l2 : Level} {A : UU l1} {B : UU l2} → (e : A ≃ B) → is-equiv (map-equiv-trunc-Set e) is-equiv-map-trunc-Set = is-equiv-map-equiv-trunc zero-𝕋 equiv-trunc-Set : {l1 l2 : Level} {A : UU l1} {B : UU l2} → (A ≃ B) → (type-trunc-Set A ≃ type-trunc-Set B) equiv-trunc-Set = equiv-trunc zero-𝕋 ``` ```agda module _ {l1 l2 : Level} (A : UU l1) (B : A → UU l2) where square-trunc-Σ-Set : ( map-equiv-trunc-Σ-Set A B ∘ unit-trunc-Set) ~ ( unit-trunc-Set ∘ tot (λ x → unit-trunc-Set)) square-trunc-Σ-Set = pr2 (center (trunc-Σ-Set A B)) htpy-map-equiv-trunc-Σ-Set : map-trunc-Set (tot (λ x → unit-trunc-Set)) ~ (map-equiv-trunc-Σ-Set A B) htpy-map-equiv-trunc-Σ-Set = htpy-uniqueness-map-trunc-Set ( tot (λ x → unit-trunc-Set)) ( map-equiv-trunc-Σ-Set A B) ( square-trunc-Σ-Set) abstract is-equiv-map-trunc-tot-unit-trunc-Set : is-equiv (map-trunc-Set (tot (λ (x : A) → unit-trunc-Set {A = B x}))) is-equiv-map-trunc-tot-unit-trunc-Set = is-equiv-htpy-equiv ( equiv-trunc-Σ-Set A B) ( htpy-map-equiv-trunc-Σ-Set) ``` ### The set truncation functor preserves injective maps ```agda module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A → B) where abstract is-injective-map-trunc-Set : is-injective f → is-injective (map-trunc-Set f) is-injective-map-trunc-Set H {x} {y} = apply-dependent-universal-property-trunc-Set' ( λ u → set-Prop ( function-Prop (map-trunc-Set f u = map-trunc-Set f y) ( Id-Prop (trunc-Set A) u y))) ( λ a → apply-dependent-universal-property-trunc-Set' ( λ v → set-Prop ( function-Prop ( map-trunc-Set f (unit-trunc-Set a) = map-trunc-Set f v) ( Id-Prop (trunc-Set A) (unit-trunc-Set a) v))) ( λ b p → apply-universal-property-trunc-Prop ( apply-effectiveness-unit-trunc-Set ( ( inv (naturality-unit-trunc-Set f a)) ∙ ( p ∙ (naturality-unit-trunc-Set f b)))) ( Id-Prop (trunc-Set A) (unit-trunc-Set a) (unit-trunc-Set b)) ( λ q → ap unit-trunc-Set (H q))) ( y)) ( x) ``` ### The set truncation functor preserves surjective maps ```agda module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A → B) where abstract is-surjective-map-trunc-Set : is-surjective f → is-surjective (map-trunc-Set f) is-surjective-map-trunc-Set H = apply-dependent-universal-property-trunc-Set' ( λ x → set-Prop (trunc-Prop (fiber (map-trunc-Set f) x))) ( λ b → apply-universal-property-trunc-Prop ( H b) ( trunc-Prop (fiber (map-trunc-Set f) (unit-trunc-Set b))) ( λ (a , p) → unit-trunc-Prop ( ( unit-trunc-Set a) , ( naturality-unit-trunc-Set f a ∙ ap unit-trunc-Set p)))) ``` ### If the set truncation of a map `f` is surjective, then `f` is surjective ```agda abstract is-surjective-is-surjective-map-trunc-Set : is-surjective (map-trunc-Set f) → is-surjective f is-surjective-is-surjective-map-trunc-Set H b = apply-universal-property-trunc-Prop ( H (unit-trunc-Set b)) ( trunc-Prop (fiber f b)) ( λ (x , p) → apply-universal-property-trunc-Prop ( is-surjective-unit-trunc-Set A x) ( trunc-Prop (fiber f b)) ( λ where ( a , refl) → apply-universal-property-trunc-Prop ( apply-effectiveness-unit-trunc-Set ( inv (naturality-unit-trunc-Set f a) ∙ p)) ( trunc-Prop (fiber f b)) ( λ q → unit-trunc-Prop (a , q)))) ``` ### Set truncation preserves the image of a map ```agda module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (f : A → B) where inclusion-trunc-im-Set : type-trunc-Set (im f) → type-trunc-Set B inclusion-trunc-im-Set = map-trunc-Set (inclusion-im f) abstract is-emb-inclusion-trunc-im-Set : is-emb inclusion-trunc-im-Set is-emb-inclusion-trunc-im-Set = is-emb-is-injective ( is-set-type-trunc-Set) ( is-injective-map-trunc-Set ( inclusion-im f) ( is-injective-is-emb (is-emb-inclusion-im f))) emb-trunc-im-Set : type-trunc-Set (im f) ↪ type-trunc-Set B pr1 emb-trunc-im-Set = inclusion-trunc-im-Set pr2 emb-trunc-im-Set = is-emb-inclusion-trunc-im-Set abstract is-injective-inclusion-trunc-im-Set : is-injective inclusion-trunc-im-Set is-injective-inclusion-trunc-im-Set = is-injective-is-emb is-emb-inclusion-trunc-im-Set map-hom-slice-trunc-im-Set : type-trunc-Set A → type-trunc-Set (im f) map-hom-slice-trunc-im-Set = map-trunc-Set (map-unit-im f) triangle-hom-slice-trunc-im-Set : map-trunc-Set f ~ (inclusion-trunc-im-Set ∘ map-trunc-Set (map-unit-im f)) triangle-hom-slice-trunc-im-Set = ( htpy-trunc-Set (triangle-unit-im f)) ∙h ( preserves-comp-map-trunc-Set (inclusion-im f) (map-unit-im f)) hom-slice-trunc-im-Set : hom-slice (map-trunc-Set f) inclusion-trunc-im-Set pr1 hom-slice-trunc-im-Set = map-hom-slice-trunc-im-Set pr2 hom-slice-trunc-im-Set = triangle-hom-slice-trunc-im-Set abstract is-surjective-map-hom-slice-trunc-im-Set : is-surjective map-hom-slice-trunc-im-Set is-surjective-map-hom-slice-trunc-im-Set = is-surjective-map-trunc-Set ( map-unit-im f) ( is-surjective-map-unit-im f) abstract is-image-trunc-im-Set : is-image ( map-trunc-Set f) ( emb-trunc-im-Set) ( hom-slice-trunc-im-Set) is-image-trunc-im-Set = is-image-is-surjective ( map-trunc-Set f) ( emb-trunc-im-Set) ( hom-slice-trunc-im-Set) ( is-surjective-map-hom-slice-trunc-im-Set) abstract unique-equiv-trunc-im-Set : is-contr ( Σ ( equiv-slice ( inclusion-im (map-trunc-Set f)) ( inclusion-trunc-im-Set)) ( λ e → htpy-hom-slice (map-trunc-Set f) ( inclusion-trunc-im-Set) ( comp-hom-slice (map-trunc-Set f) ( inclusion-im (map-trunc-Set f)) ( inclusion-trunc-im-Set) ( hom-equiv-slice ( inclusion-im (map-trunc-Set f)) ( inclusion-trunc-im-Set) ( e)) ( unit-im (map-trunc-Set f))) ( hom-slice-trunc-im-Set))) unique-equiv-trunc-im-Set = uniqueness-im ( map-trunc-Set f) ( emb-trunc-im-Set) ( hom-slice-trunc-im-Set) ( is-image-trunc-im-Set) equiv-slice-trunc-im-Set : equiv-slice (inclusion-im (map-trunc-Set f)) inclusion-trunc-im-Set equiv-slice-trunc-im-Set = pr1 (center unique-equiv-trunc-im-Set) equiv-trunc-im-Set : im (map-trunc-Set f) ≃ type-trunc-Set (im f) equiv-trunc-im-Set = pr1 equiv-slice-trunc-im-Set map-equiv-trunc-im-Set : im (map-trunc-Set f) → type-trunc-Set (im f) map-equiv-trunc-im-Set = map-equiv equiv-trunc-im-Set triangle-trunc-im-Set : ( inclusion-im (map-trunc-Set f)) ~ ( inclusion-trunc-im-Set ∘ map-equiv-trunc-im-Set) triangle-trunc-im-Set = pr2 equiv-slice-trunc-im-Set htpy-hom-slice-trunc-im-Set : htpy-hom-slice ( map-trunc-Set f) ( inclusion-trunc-im-Set) ( comp-hom-slice ( map-trunc-Set f) ( inclusion-im (map-trunc-Set f)) ( inclusion-trunc-im-Set) ( hom-equiv-slice ( inclusion-im (map-trunc-Set f)) ( inclusion-trunc-im-Set) ( equiv-slice-trunc-im-Set)) ( unit-im (map-trunc-Set f))) ( hom-slice-trunc-im-Set) htpy-hom-slice-trunc-im-Set = pr2 (center unique-equiv-trunc-im-Set) htpy-map-hom-slice-trunc-im-Set : ( map-equiv-trunc-im-Set ∘ (map-unit-im (map-trunc-Set f))) ~ ( map-hom-slice-trunc-im-Set) htpy-map-hom-slice-trunc-im-Set = pr1 htpy-hom-slice-trunc-im-Set tetrahedron-map-hom-slice-trunc-im-Set : ( ( triangle-trunc-im-Set ·r map-unit-im (map-trunc-Set f)) ∙h ( inclusion-trunc-im-Set ·l htpy-map-hom-slice-trunc-im-Set)) ~ ( triangle-hom-slice-trunc-im-Set) tetrahedron-map-hom-slice-trunc-im-Set = pr2 htpy-hom-slice-trunc-im-Set unit-im-map-trunc-Set : im f → im (map-trunc-Set f) pr1 (unit-im-map-trunc-Set x) = unit-trunc-Set (pr1 x) pr2 (unit-im-map-trunc-Set x) = apply-universal-property-trunc-Prop (pr2 x) ( trunc-Prop (fiber (map-trunc-Set f) (unit-trunc-Set (pr1 x)))) ( λ u → unit-trunc-Prop ( ( unit-trunc-Set (pr1 u)) , ( naturality-unit-trunc-Set f (pr1 u) ∙ ap unit-trunc-Set (pr2 u)))) left-square-unit-im-map-trunc-Set : ( map-unit-im (map-trunc-Set f) ∘ unit-trunc-Set) ~ ( unit-im-map-trunc-Set ∘ map-unit-im f) left-square-unit-im-map-trunc-Set a = eq-Eq-im ( map-trunc-Set f) ( map-unit-im (map-trunc-Set f) (unit-trunc-Set a)) ( unit-im-map-trunc-Set (map-unit-im f a)) ( naturality-unit-trunc-Set f a) right-square-unit-im-map-trunc-Set : ( inclusion-im (map-trunc-Set f) ∘ unit-im-map-trunc-Set) ~ ( unit-trunc-Set ∘ inclusion-im f) right-square-unit-im-map-trunc-Set x = refl abstract is-set-truncation-im-map-trunc-Set : is-set-truncation ( im-Set (trunc-Set B) (map-trunc-Set f)) ( unit-im-map-trunc-Set) is-set-truncation-im-map-trunc-Set = is-set-truncation-is-equiv-is-set-truncation ( im-Set (trunc-Set B) (map-trunc-Set f)) ( unit-im-map-trunc-Set) ( trunc-Set (im f)) ( unit-trunc-Set) ( λ b → is-injective-inclusion-trunc-im-Set ( ( inv (triangle-trunc-im-Set (unit-im-map-trunc-Set b))) ∙ ( inv (naturality-unit-trunc-Set (inclusion-im f) b)))) ( is-set-truncation-trunc-Set (im f)) ( is-equiv-map-equiv equiv-trunc-im-Set) ```