This is ported from the Midlands Graduate School 2019 lecture notes https://www.cs.bham.ac.uk/~mhe/HoTT-UF.in-Agda-Lecture-Notes/HoTT-UF-Agda.html https://github.com/martinescardo/HoTT-UF.Agda-Lecture-Notes \begin{code} {-# OPTIONS --safe --without-K #-} module MGS.Subsingleton-Truncation where open import MGS.Powerset public open import MGS.Embeddings public is-inhabited : 𝓤 ̇ → 𝓤 ⁺ ̇ is-inhabited {𝓤} X = (P : 𝓤 ̇ ) → is-subsingleton P → (X → P) → P inhabitation-is-subsingleton : global-dfunext → (X : 𝓤 ̇ ) → is-subsingleton (is-inhabited X) inhabitation-is-subsingleton fe X = Π-is-subsingleton fe (λ P → Π-is-subsingleton fe (λ (s : is-subsingleton P) → Π-is-subsingleton fe (λ (f : X → P) → s))) inhabited-intro : {X : 𝓤 ̇ } → X → is-inhabited X inhabited-intro x = λ P s f → f x inhabited-recursion : {X P : 𝓤 ̇ } → is-subsingleton P → (X → P) → is-inhabited X → P inhabited-recursion s f φ = φ (codomain f) s f inhabited-recursion-computation : {X P : 𝓤 ̇ } (i : is-subsingleton P) (f : X → P) (x : X) → inhabited-recursion i f (inhabited-intro x) = f x inhabited-recursion-computation i f x = refl (f x) inhabited-induction : global-dfunext → {X : 𝓤 ̇ } {P : is-inhabited X → 𝓤 ̇ } (i : (s : is-inhabited X) → is-subsingleton (P s)) (f : (x : X) → P (inhabited-intro x)) → (s : is-inhabited X) → P s inhabited-induction fe {X} {P} i f s = φ' s where φ : X → P s φ x = transport P (inhabitation-is-subsingleton fe X (inhabited-intro x) s) (f x) φ' : is-inhabited X → P s φ' = inhabited-recursion (i s) φ inhabited-computation : (fe : global-dfunext) {X : 𝓤 ̇ } {P : is-inhabited X → 𝓤 ̇ } (i : (s : is-inhabited X) → is-subsingleton (P s)) (f : (x : X) → P (inhabited-intro x)) (x : X) → inhabited-induction fe i f (inhabited-intro x) = f x inhabited-computation fe i f x = i (inhabited-intro x) (inhabited-induction fe i f (inhabited-intro x)) (f x) inhabited-subsingletons-are-pointed : (P : 𝓤 ̇ ) → is-subsingleton P → is-inhabited P → P inhabited-subsingletons-are-pointed P s = inhabited-recursion s (𝑖𝑑 P) inhabited-functorial : global-dfunext → (X : 𝓤 ⁺ ̇ ) (Y : 𝓤 ̇ ) → (X → Y) → is-inhabited X → is-inhabited Y inhabited-functorial fe X Y f = inhabited-recursion (inhabitation-is-subsingleton fe Y) (inhabited-intro ∘ f) image' : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } → (X → Y) → (𝓤 ⊔ 𝓥)⁺ ̇ image' f = Σ y ꞉ codomain f , is-inhabited (Σ x ꞉ domain f , f x = y) restriction' : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → image' f → Y restriction' f (y , _) = y corestriction' : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → X → image' f corestriction' f x = f x , inhabited-intro (x , refl (f x)) is-surjection' : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } → (X → Y) → (𝓤 ⊔ 𝓥)⁺ ̇ is-surjection' f = (y : codomain f) → is-inhabited (Σ x ꞉ domain f , f x = y) record subsingleton-truncations-exist : 𝓤ω where field ∥_∥ : {𝓤 : Universe} → 𝓤 ̇ → 𝓤 ̇ ∥∥-is-subsingleton : {𝓤 : Universe} {X : 𝓤 ̇ } → is-subsingleton ∥ X ∥ ∣_∣ : {𝓤 : Universe} {X : 𝓤 ̇ } → X → ∥ X ∥ ∥∥-recursion : {𝓤 𝓥 : Universe} {X : 𝓤 ̇ } {P : 𝓥 ̇ } → is-subsingleton P → (X → P) → ∥ X ∥ → P infix 0 ∥_∥ module basic-truncation-development (pt : subsingleton-truncations-exist) (hfe : global-hfunext) where open subsingleton-truncations-exist pt public hunapply : {X : 𝓤 ̇ } {A : X → 𝓥 ̇ } {f g : Π A} → f ∼ g → f = g hunapply = hfunext-gives-dfunext hfe ∥∥-recursion-computation : {X : 𝓤 ̇ } {P : 𝓥 ̇ } → (i : is-subsingleton P) → (f : X → P) → (x : X) → ∥∥-recursion i f ∣ x ∣ = f x ∥∥-recursion-computation i f x = i (∥∥-recursion i f ∣ x ∣) (f x) ∥∥-induction : {X : 𝓤 ̇ } {P : ∥ X ∥ → 𝓥 ̇ } → ((s : ∥ X ∥) → is-subsingleton (P s)) → ((x : X) → P ∣ x ∣) → (s : ∥ X ∥) → P s ∥∥-induction {𝓤} {𝓥} {X} {P} i f s = φ' s where φ : X → P s φ x = transport P (∥∥-is-subsingleton ∣ x ∣ s) (f x) φ' : ∥ X ∥ → P s φ' = ∥∥-recursion (i s) φ ∥∥-computation : {X : 𝓤 ̇ } {P : ∥ X ∥ → 𝓥 ̇ } → (i : (s : ∥ X ∥) → is-subsingleton (P s)) → (f : (x : X) → P ∣ x ∣) → (x : X) → ∥∥-induction i f ∣ x ∣ = f x ∥∥-computation i f x = i ∣ x ∣ (∥∥-induction i f ∣ x ∣) (f x) ∥∥-functor : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } → (X → Y) → ∥ X ∥ → ∥ Y ∥ ∥∥-functor f = ∥∥-recursion ∥∥-is-subsingleton (λ x → ∣ f x ∣) ∥∥-agrees-with-inhabitation : (X : 𝓤 ̇ ) → ∥ X ∥ ↔ is-inhabited X ∥∥-agrees-with-inhabitation X = a , b where a : ∥ X ∥ → is-inhabited X a = ∥∥-recursion (inhabitation-is-subsingleton hunapply X) inhabited-intro b : is-inhabited X → ∥ X ∥ b = inhabited-recursion ∥∥-is-subsingleton ∣_∣ _∨_ : 𝓤 ̇ → 𝓥 ̇ → 𝓤 ⊔ 𝓥 ̇ A ∨ B = ∥ A + B ∥ infixl 20 _∨_ ∃ : {X : 𝓤 ̇ } → (X → 𝓥 ̇ ) → 𝓤 ⊔ 𝓥 ̇ ∃ A = (∥ Σ A ∥) -∃ : {𝓤 𝓥 : Universe} (X : 𝓤 ̇ ) (Y : X → 𝓥 ̇ ) → 𝓤 ⊔ 𝓥 ̇ -∃ X Y = ∃ Y syntax -∃ A (λ x → b) = ∃ x ꞉ A , b infixr -1 -∃ ∨-is-subsingleton : {A : 𝓤 ̇ } {B : 𝓥 ̇ } → is-subsingleton (A ∨ B) ∨-is-subsingleton = ∥∥-is-subsingleton ∃-is-subsingleton : {X : 𝓤 ̇ } {A : X → 𝓥 ̇ } → is-subsingleton (∃ A) ∃-is-subsingleton = ∥∥-is-subsingleton image : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } → (X → Y) → 𝓤 ⊔ 𝓥 ̇ image f = Σ y ꞉ codomain f , ∃ x ꞉ domain f , f x = y restriction : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → image f → Y restriction f (y , _) = y corestriction : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → X → image f corestriction f x = f x , ∣ (x , refl (f x)) ∣ is-surjection : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } → (X → Y) → 𝓤 ⊔ 𝓥 ̇ is-surjection f = (y : codomain f) → ∃ x ꞉ domain f , f x = y being-surjection-is-subsingleton : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → is-subsingleton (is-surjection f) being-surjection-is-subsingleton f = Π-is-subsingleton hunapply (λ y → ∃-is-subsingleton) corestriction-is-surjection : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → is-surjection (corestriction f) corestriction-is-surjection f (y , s) = ∥∥-functor g s where g : (Σ x ꞉ domain f , f x = y) → Σ x ꞉ domain f , corestriction f x = (y , s) g (x , p) = x , to-subtype-= (λ _ → ∃-is-subsingleton) p surjection-induction : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → is-surjection f → (P : Y → 𝓦 ̇ ) → ((y : Y) → is-subsingleton (P y)) → ((x : X) → P (f x)) → (y : Y) → P y surjection-induction f i P j α y = ∥∥-recursion (j y) φ (i y) where φ : fiber f y → P y φ (x , r) = transport P r (α x) ∣∣-is-surjection : (X : 𝓤 ̇ ) → is-surjection (λ (x : X) → ∣ x ∣) ∣∣-is-surjection X s = γ where f : X → ∃ x ꞉ X , ∣ x ∣ = s f x = ∣ (x , ∥∥-is-subsingleton ∣ x ∣ s) ∣ γ : ∃ x ꞉ X , ∣ x ∣ = s γ = ∥∥-recursion ∥∥-is-subsingleton f s singletons-are-inhabited : (X : 𝓤 ̇ ) → is-singleton X → ∥ X ∥ singletons-are-inhabited X s = ∣ center X s ∣ inhabited-subsingletons-are-singletons : (X : 𝓤 ̇ ) → ∥ X ∥ → is-subsingleton X → is-singleton X inhabited-subsingletons-are-singletons X t i = c , φ where c : X c = ∥∥-recursion i (𝑖𝑑 X) t φ : (x : X) → c = x φ = i c singleton-iff-inhabited-subsingleton : (X : 𝓤 ̇ ) → is-singleton X ↔ (∥ X ∥ × is-subsingleton X) singleton-iff-inhabited-subsingleton X = (λ (s : is-singleton X) → singletons-are-inhabited X s , singletons-are-subsingletons X s) , Σ-induction (inhabited-subsingletons-are-singletons X) equiv-iff-embedding-and-surjection : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → is-equiv f ↔ (is-embedding f × is-surjection f) equiv-iff-embedding-and-surjection f = (a , b) where a : is-equiv f → is-embedding f × is-surjection f a e = (λ y → singletons-are-subsingletons (fiber f y) (e y)) , (λ y → singletons-are-inhabited (fiber f y) (e y)) b : is-embedding f × is-surjection f → is-equiv f b (e , s) y = inhabited-subsingletons-are-singletons (fiber f y) (s y) (e y) equiv-=-embedding-and-surjection : {X : 𝓤 ̇ } {Y : 𝓥 ̇ } (f : X → Y) → propext (𝓤 ⊔ 𝓥) → is-equiv f = (is-embedding f × is-surjection f) equiv-=-embedding-and-surjection f pe = pe (being-equiv-is-subsingleton hunapply hunapply f) (×-is-subsingleton (being-embedding-is-subsingleton hunapply f) (being-surjection-is-subsingleton f)) (lr-implication (equiv-iff-embedding-and-surjection f)) (rl-implication (equiv-iff-embedding-and-surjection f)) fix : {X : 𝓤 ̇ } → (X → X) → 𝓤 ̇ fix f = Σ x ꞉ domain f , f x = x from-fix : {X : 𝓤 ̇ } (f : X → X) → fix f → X from-fix f = pr₁ to-fix : {X : 𝓤 ̇ } (f : X → X) → wconstant f → X → fix f to-fix f κ x = f x , κ (f x) x fix-is-subsingleton : {X : 𝓤 ̇ } (f : X → X) → wconstant f → is-subsingleton (fix f) fix-is-subsingleton {𝓤} {X} f κ = γ where a : (y x : X) → (f x = x) ≃ (f y = x) a y x = transport (_= x) (κ x y) , transport-is-equiv (_= x) (κ x y) b : (y : X) → fix f ≃ singleton-type' (f y) b y = Σ-cong (a y) c : X → is-singleton (fix f) c y = equiv-to-singleton (b y) (singleton-types'-are-singletons X (f y)) d : fix f → is-singleton (fix f) d = c ∘ from-fix f γ : is-subsingleton (fix f) γ = subsingleton-criterion d choice-function : 𝓤 ̇ → 𝓤 ⁺ ̇ choice-function X = is-inhabited X → X wconstant-endomap-gives-choice-function : {X : 𝓤 ̇ } → wconstant-endomap X → choice-function X wconstant-endomap-gives-choice-function {𝓤} {X} (f , κ) = from-fix f ∘ γ where γ : is-inhabited X → fix f γ = inhabited-recursion (fix-is-subsingleton f κ) (to-fix f κ) choice-function-gives-wconstant-endomap : global-dfunext → {X : 𝓤 ̇ } → choice-function X → wconstant-endomap X choice-function-gives-wconstant-endomap fe {X} c = f , κ where f : X → X f = c ∘ inhabited-intro κ : wconstant f κ x y = ap c (inhabitation-is-subsingleton fe X (inhabited-intro x) (inhabited-intro y)) module find-hidden-root where open basic-arithmetic-and-order public μρ : (f : ℕ → ℕ) → root f → root f μρ f r = minimal-root-is-root f (root-gives-minimal-root f r) μρ-root : (f : ℕ → ℕ) → root f → ℕ μρ-root f r = pr₁ (μρ f r) μρ-root-is-root : (f : ℕ → ℕ) (r : root f) → f (μρ-root f r) = 0 μρ-root-is-root f r = pr₂ (μρ f r) μρ-root-minimal : (f : ℕ → ℕ) (m : ℕ) (p : f m = 0) → (n : ℕ) → f n = 0 → μρ-root f (m , p) ≤ n μρ-root-minimal f m p n q = not-<-gives-≥ (μρ-root f (m , p)) n γ where φ : ¬ (f n ≠ 0) → ¬ (n < μρ-root f (m , p)) φ = contrapositive (pr₂ (pr₂ (root-gives-minimal-root f (m , p))) n) γ : ¬ (n < μρ-root f (m , p)) γ = φ (dni (f n = 0) q) μρ-wconstant : (f : ℕ → ℕ) → wconstant (μρ f) μρ-wconstant f (n , p) (n' , p') = r where m m' : ℕ m = μρ-root f (n , p) m' = μρ-root f (n' , p') l : m ≤ m' l = μρ-root-minimal f n p m' (μρ-root-is-root f (n' , p')) l' : m' ≤ m l' = μρ-root-minimal f n' p' m (μρ-root-is-root f (n , p)) q : m = m' q = ≤-anti _ _ l l' r : μρ f (n , p) = μρ f (n' , p') r = to-subtype-= (λ _ → ℕ-is-set (f _) 0) q find-existing-root : (f : ℕ → ℕ) → is-inhabited (root f) → root f find-existing-root f = h ∘ g where γ : root f → fix (μρ f) γ = to-fix (μρ f) (μρ-wconstant f) g : is-inhabited (root f) → fix (μρ f) g = inhabited-recursion (fix-is-subsingleton (μρ f) (μρ-wconstant f)) γ h : fix (μρ f) → root f h = from-fix (μρ f) module find-existing-root-example where f : ℕ → ℕ f 0 = 1 f 1 = 1 f 2 = 0 f 3 = 1 f 4 = 0 f 5 = 1 f 6 = 1 f 7 = 0 f (succ (succ (succ (succ (succ (succ (succ (succ x)))))))) = x root-existence : is-inhabited (root f) root-existence = inhabited-intro (8 , refl 0) r : root f r = find-existing-root f root-existence x : ℕ x = pr₁ r x-is-root : f x = 0 x-is-root = pr₂ r p : x = 2 p = refl _ module exit-∥∥ (pt : subsingleton-truncations-exist) (hfe : global-hfunext) where open basic-truncation-development pt hfe open find-hidden-root find-∥∥-existing-root : (f : ℕ → ℕ) → (∃ n ꞉ ℕ , f n = 0) → Σ n ꞉ ℕ , f n = 0 find-∥∥-existing-root f = k where γ : root f → fix (μρ f) γ = to-fix (μρ f) (μρ-wconstant f) g : ∥ root f ∥ → fix (μρ f) g = ∥∥-recursion (fix-is-subsingleton (μρ f) (μρ-wconstant f)) γ h : fix (μρ f) → root f h = from-fix (μρ f) k : ∥ root f ∥ → root f k = h ∘ g module find-∥∥-existing-root-example where f : ℕ → ℕ f 0 = 1 f 1 = 1 f 2 = 0 f 3 = 1 f 4 = 0 f 5 = 1 f 6 = 1 f 7 = 0 f (succ (succ (succ (succ (succ (succ (succ (succ x)))))))) = x root-∥∥-existence : ∥ root f ∥ root-∥∥-existence = ∣ 8 , refl 0 ∣ r : root f r = find-∥∥-existing-root f root-∥∥-existence x : ℕ x = pr₁ r x-is-root : f x = 0 x-is-root = pr₂ r NB : find-∥∥-existing-root f = from-fix (μρ f) ∘ ∥∥-recursion (fix-is-subsingleton (μρ f) (μρ-wconstant f)) (to-fix (μρ f) (μρ-wconstant f)) NB = refl _ p : x = 2 p = ap (pr₁ ∘ from-fix (μρ f)) (∥∥-recursion-computation (fix-is-subsingleton (μρ f) (μρ-wconstant f)) (to-fix (μρ f) (μρ-wconstant f)) (8 , refl _)) wconstant-endomap-gives-∥∥-choice-function : {X : 𝓤 ̇ } → wconstant-endomap X → (∥ X ∥ → X) wconstant-endomap-gives-∥∥-choice-function {𝓤} {X} (f , κ) = from-fix f ∘ γ where γ : ∥ X ∥ → fix f γ = ∥∥-recursion (fix-is-subsingleton f κ) (to-fix f κ) ∥∥-choice-function-gives-wconstant-endomap : {X : 𝓤 ̇ } → (∥ X ∥ → X) → wconstant-endomap X ∥∥-choice-function-gives-wconstant-endomap {𝓤} {X} c = f , κ where f : X → X f = c ∘ ∣_∣ κ : wconstant f κ x y = ap c (∥∥-is-subsingleton ∣ x ∣ ∣ y ∣) ∥∥-recursion-set : (X : 𝓤 ̇ ) (Y : 𝓥 ̇ ) → is-set Y → (f : X → Y) → wconstant f → ∥ X ∥ → Y ∥∥-recursion-set {𝓤} {𝓥} X Y s f κ = f' where ψ : (y y' : Y) → (Σ x ꞉ X , f x = y) → (Σ x' ꞉ X , f x' = y') → y = y' ψ y y' (x , r) (x' , r') = y =⟨ r ⁻¹ ⟩ f x =⟨ κ x x' ⟩ f x' =⟨ r' ⟩ y' ∎ φ : (y y' : Y) → (∃ x ꞉ X , f x = y) → (∃ x' ꞉ X , f x' = y') → y = y' φ y y' u u' = ∥∥-recursion (s y y') (λ - → ∥∥-recursion (s y y') (ψ y y' -) u') u P : 𝓤 ⊔ 𝓥 ̇ P = image f i : is-subsingleton P i (y , u) (y' , u') = to-subtype-= (λ _ → ∃-is-subsingleton) (φ y y' u u') g : ∥ X ∥ → P g = ∥∥-recursion i (corestriction f) h : P → Y h = restriction f f' : ∥ X ∥ → Y f' = h ∘ g \end{code}