Martin Escardo 2012.

Based on [1] and [2].

1. Nicolai Kraus, Martín Escardó, Thierry Coquand & Thorsten Altenkirch.
   Generalizations of Hedberg’s Theorem.
   TLCA 2013
   https://doi.org/10.1007/978-3-642-38946-7_14

2. Nicolai Kraus, Martín Escardó, Thierry Coquand & Thorsten Altenkirch.
   Notions of Anonymous Existence in Martin-Löf Type Theory.
   Logical Methods in Computer Science, March 24, 2017, Volume 13, Issue 1.
   https://doi.org/10.23638/LMCS-13(1:15)2017

\begin{code}

{-# OPTIONS --safe --without-K #-}

module UF.ExitPropTrunc where

open import MLTT.Spartan
open import UF.Base
open import UF.Hedberg
open import UF.KrausLemma
open import UF.PropTrunc
open import UF.Subsingletons

to-fix : {X : 𝓤 ̇ } (f : X  X)  wconstant f  X  fix f
to-fix f g x = (f x , g x (f x))

from-to-fix : {X : 𝓤 ̇ } (f : X  X) (κ : wconstant f)
             from-fix f  to-fix f κ  f
from-to-fix f κ w = refl

to-from-fix : {X : 𝓤 ̇ } (f : X  X) (κ : wconstant f)
             to-fix f κ  from-fix f  id
to-from-fix f κ _ = fix-is-prop f κ _ _

has-split-support' : 𝓤 ̇  𝓤  ̇
has-split-support' {𝓤} X = Σ P  𝓤 ̇ , is-prop P × (X  P)

fix-has-split-support' : {X : 𝓤 ̇ }
                        collapsible X
                        has-split-support' X
fix-has-split-support' {𝓤} {X} (f , κ) =
 fix f , fix-is-prop f κ , to-fix f κ , from-fix f

has-prop-truncation : (𝓥 : Universe)  𝓤 ̇  (𝓤  𝓥) ̇
has-prop-truncation {𝓤} 𝓥 X =
 Σ X'  𝓤 ̇ , is-prop X'
           × (X  X')
           × ((P : 𝓥 ̇ )  is-prop P  (X  P)  X'  P)

split-truncation : {X : 𝓤 ̇ }
                  has-split-support' X
                   𝓥  has-prop-truncation 𝓥 X
split-truncation {𝓤} {X} (X' , i , f , g) V = X' , i , f , λ P j h x'  h (g x')

collapsible-has-prop-truncation : {X : 𝓤 ̇ }
                                 collapsible X
                                  𝓥  has-prop-truncation 𝓥 X
collapsible-has-prop-truncation {𝓤} {X} c =
 split-truncation (fix-has-split-support' c)

module split-support-and-collapsibility (pe : propositional-truncations-exist) where

 open PropositionalTruncation pe

 has-split-support : 𝓤 ̇  𝓤 ̇
 has-split-support X =  X   X

 has-split-support→ : {X : 𝓤 ̇ }  has-split-support X  has-split-support' X
 has-split-support→ {𝓤} {X} f =  X  , ∥∥-is-prop ,  x   x ) , f

 has-split-support← : {X : 𝓤 ̇ }  has-split-support' X  has-split-support X
 has-split-support← {𝓤} {X} (P , P-is-prop , g , f) = f  ∥∥-rec P-is-prop g

\end{code}

TODO. Are the above two functions mutually inverse and hence we get an
equivalence?

\begin{code}

 collapsible-gives-split-support : {X : 𝓤 ̇ }
                                  collapsible X
                                  has-split-support X
 collapsible-gives-split-support {𝓤} {X} (f , κ) s = x
  where
   g :  X   fix f
   g = ∥∥-rec (fix-is-prop f κ) (to-fix f κ)

   x : X
   x = from-fix f (g s)

 exit-prop-trunc : {X : 𝓤 ̇ }
                  (f : X  X)
                  wconstant f
                   X   X
 exit-prop-trunc f κ = collapsible-gives-split-support (f , κ)

 exit-prop-trunc-is-fixed : {X : 𝓤 ̇ }
                            (f : X  X)
                            (κ : wconstant f)
                            (s :  X )
                           f (exit-prop-trunc f κ s)  exit-prop-trunc f κ s
 exit-prop-trunc-is-fixed f κ s =
  (from-fix-is-fixed f (∥∥-rec (fix-is-prop f κ) (to-fix f κ) s))⁻¹

 split-support-gives-collapsible : {X : 𝓤 ̇ }
                                  has-split-support X
                                  collapsible X
 split-support-gives-collapsible {𝓤} {X} g = γ
  where
   f : X  X
   f x = g  x 

   κ : (x y : X)  f x  f y
   κ x y = ap g (∥∥-is-prop  x   y )

   γ : collapsible X
   γ = f , κ

\end{code}

Added 23rd September 2024. Perhaps the following is better notation
for the above.

\begin{code}

∥_∥⌜_⌝ : (X : 𝓤 ̇)  collapsible X  𝓤 ̇
 X ∥⌜ f , w  = fix f

∥∥⌜_⌝-is-prop : {X : 𝓤 ̇ } (c : collapsible X)  is-prop  X ∥⌜ c 
∥∥⌜ f , w ⌝-is-prop = fix-is-prop f w

∣_∣⌜_⌝ : {X : 𝓤 ̇ }  X  (c : collapsible X)   X ∥⌜ c 
 x ∣⌜ f , w  = to-fix f w x

\end{code}

Notice that recursion principle doesn't require the family A to be
prop-valued, which allows us to exit truncations.

\begin{code}

∥∥⌜_⌝-rec : {X : 𝓤 ̇ } (c : collapsible X) {A : 𝓥 ̇ }
          (X  A)   X ∥⌜ c   A
∥∥⌜ c ⌝-rec {A} g (x , φ) = g x

∣∣⌜_⌝-exit : {X : 𝓤 ̇} (c : collapsible X)   X ∥⌜ c   X
∣∣⌜ c ⌝-exit = ∥∥⌜ c ⌝-rec id

infix 0 ∥_∥⌜_⌝
infix 0 ∣_∣⌜_⌝

module propositional-truncation-of-decidable-type
        (pt : propositional-truncations-exist)
       where

 open propositional-truncations-exist pt public

 module _ {X : 𝓤 ̇ } (c : collapsible X) where

  ∥∥⌜_⌝-to-∥∥ :  X ∥⌜ c    X 
  ∥∥⌜_⌝-to-∥∥ = ∥∥⌜ c ⌝-rec ∣_∣

  ∥∥-to-∥∥⌜_⌝ :  X    X ∥⌜ c 
  ∥∥-to-∥∥⌜_⌝ = ∥∥-rec (∥∥⌜ c ⌝-is-prop) ∣_∣⌜ c 

  collapsible-types-have-split-support :  X   X
  collapsible-types-have-split-support s = ∣∣⌜ c ⌝-exit (∥∥-to-∥∥⌜_⌝ s)

\end{code}

TODO. Perhaps rewrite all uses of this file to use the new notation,
and get rid of the original old notation.