{-# OPTIONS --cubical --erasure --guardedness --safe #-}
module FinChoice where
open import Cubical.Core.Primitives
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.HLevels
open import Cubical.Foundations.Function
open import Cubical.Data.Empty as ⊥
open import Cubical.Data.FinData.Base
open import Cubical.Data.Nat
open import Cubical.Data.Nat.Order
open import Cubical.Data.Sigma
open import PropTrunc
private
variable
ℓ ℓ' ℓ'' : Level
A B C : Type ℓ
∥-∥recFin : {m : ℕ} {P : Fin m → Type ℓ}
{B : Type ℓ'} (isPropB : isProp B)
→ ((∀ i → P i) → B)
→ ((∀ i → ∥ P i ∥) → B)
∥-∥recFin {m = zero} _ untruncHyp _ = untruncHyp (λ ())
∥-∥recFin {m = suc m} {P = P} {B = B} isPropB untruncHyp truncFam =
∥-∥rec (isProp→ isPropB) δ (truncFam zero) (truncFam ∘ suc)
where
δ : P zero → (∀ i → ∥ P (suc i) ∥) → B
δ p₀ = ∥-∥recFin isPropB
(λ pₛ → untruncHyp (λ { zero → p₀ ; (suc i) → pₛ i }))
∥∥-×→ : {A : Type ℓ} {B : Type ℓ'} → ∥ A ∥ × ∥ B ∥ → ∥ A × B ∥
∥∥-×→ = uncurry (∥-∥rec (isProp→ isPropPropTrunc)
(λ a → ∥-∥rec isPropPropTrunc (λ b → ∣ a , b ∣)))
Finite-Choice : {A : (i : ℕ) → Type ℓ} → (n : ℕ)
→ (∀ (i : ℕ) → i < n → ∥ A i ∥)
→ ∥ ((i : ℕ) → i < n → A i) ∥
Finite-Choice zero f = ∣ (λ i p → ⊥.rec (¬-<-zero p)) ∣
Finite-Choice {ℓ} {A} (suc zero) f = ∥-∥map [2] (f zero ≤-refl)
where
[2] : A 0 → (i : ℕ) → i < 1 → A i
[2] a0 zero p = a0
[2] a0 (suc i) p = ⊥.rec (¬-<-zero (pred-≤-pred p))
Finite-Choice {ℓ} {A} (suc m@(suc n)) f =
∥-∥map δ (∥∥-×→ (Finite-Choice m (λ i q → f i (<-trans q <-suc)) , f m <-suc))
where
δ : ((i : ℕ) → i < suc n → A i) × A (suc n) → (j : ℕ) → j < suc (suc n) → A j
δ (f , asn) zero p = f zero (suc-≤-suc zero-≤)
δ (f , asn) j@(suc i) p with i ≟ n
... | lt v = f j (n ∸ j , ρ (suc n) (suc j) (suc-≤-suc v))
where
ρ : ∀ (n m : ℕ) → (m ≤ n) → n ∸ m + m ≡ n
ρ zero zero p = refl
ρ zero (suc m) p = ⊥.rec (¬-<-zero p)
ρ (suc n) zero p = cong suc (+-zero n)
ρ (suc n) (suc m) p = +-suc (n ∸ m) m ∙ cong suc (ρ n m (pred-≤-pred p))
... | eq u = transport (cong (λ j → A (suc j)) (sym u)) asn
... | gt z = ⊥.rec (¬m<m (≤-trans z (pred-≤-pred (pred-≤-pred p))))
module _ (Bset : isSet B) where
LBset' : isSet' B
LBset' = isSet→isSet' Bset
Lrec→Set : (f : A → B) (kf : 2-Constant f) → ∥ A ∥ → B
Lhelper : (f : A → B) (kf : 2-Constant f) → (t u : ∥ A ∥)
→ Lrec→Set f kf t ≡ Lrec→Set f kf u
Lrec→Set f kf ∣ x ∣ = f x
Lrec→Set f kf (squash t u i) = Lhelper f kf t u i
Lhelper f kf ∣ x ∣ ∣ y ∣ = kf x y
Lhelper f kf (squash t u i) v
= LBset' (Lhelper f kf t v) (Lhelper f kf u v) (Lhelper f kf t u) refl i
Lhelper f kf t (squash u v i)
= LBset' (Lhelper f kf t u) (Lhelper f kf t v) refl (Lhelper f kf u v) i
Weakly-Constant : {A : Type ℓ} {B : Type ℓ'} (f : A → B)
→ Type (ℓ-max ℓ ℓ')
Weakly-Constant {ℓ} {ℓ'} {A} {B} f = (x y : A) → f x ≡ f y
WC-Factorisation : {A : Type ℓ} {B : Type ℓ'} → isSet B → (f : A → B)
→ Weakly-Constant f
→ Σ (∥ A ∥ → B) (λ g → (∀ (x : A) → (f x ≡ g ∣ x ∣)))
WC-Factorisation issetB f wCons = Lrec→Set issetB f wCons , λ x → wCons x x