\begin{code}
{-# OPTIONS --safe #-}
module FinitenessConditions where
open import Prelude
open import Axiom
module _ {A : Type a} {B : Type b} where
Pointwise : (B → B → Type c) → (A → B) → (A → B) → Type _
\end{code}
%<*pointwise>
\begin{code}
Pointwise R f g = ∀ x → [ f x ] ≡ ([ g x ] ⦂ B / R)
\end{code}
%</pointwise>
\begin{code}
private variable _~_ : B → B → Type c
private variable R : B → B → Type c
\end{code}
%<*distribute>
\begin{code}[number=dist]
dist : (A → B) / Pointwise R → (A → B / R)
dist = rec/ (isSetΠ λ _ → squash/) (λ f → [_] ∘ f) (λ _ _ → funExt)
\end{code}
%</distribute>
\begin{code}
quot-pre : (A : Type a) → Typeω
quot-pre A = ∀ {b c} (B : Type b) (R : B → B → Type c) →
\end{code}
%<*quot-pre>
\begin{code}[number=quot-pre]
Σ[ trav ⦂ ((A → B / R) → (A → B) / Pointwise R) ] ×
(trav ∘ dist ≡ id) × (dist ∘ trav ≡ id)
\end{code}
%</quot-pre>
\begin{code}
inj-dist : Injective (dist {A = A} {B = B} {R = _~_})
inj-dist {x = x} {y = y} =
elimProp2/
{P = λ x y → dist x ≡ dist y → x ≡ y}
(λ _ _ → isProp→ (squash/ _ _))
(λ x y p → eq/ x y λ z → cong (_$ z) p)
x y
record SplitQuotientedChoiceAt (A : Type a) (B : Type b) (_~_ : B → B → Type c) : Type (a ℓ⊔ b ℓ⊔ c) where
no-eta-equality
field
undistrib : SplitSurjective (dist {A = A} {B = B} {R = _~_})
trav : (A → B / _~_) → (A → B) / Pointwise _~_
trav f = undistrib f .fst
dist∘trav : (f : A → B / _~_) (x : A) → dist (trav f) x ≡ f x
dist∘trav f x = cong (_$ x) (undistrib f .snd)
un-trav : (f : A → B) → trav ([_] ∘ f) ≡ [ f ]
un-trav f =
elimProp/
{B = λ xs → xs ≡ trav ([_] ∘ f) → xs ≡ [ f ]}
(λ _ → isProp→ (squash/ _ _))
(λ g p → eq/ _ _ λ x → cong (λ h → dist h x) p ; dist∘trav ([_] ∘ f) x)
(trav ([_] ∘ f)) refl
trav∘dist : (x : (A → B) / Pointwise _~_)
→ trav (dist x) ≡ x
trav∘dist = elimProp/ (λ _ → squash/ _ _) un-trav
comm-quot : (A → B / _~_) ⇔ (A → B) / Pointwise _~_
comm-quot .fun = trav
comm-quot .inv = dist
comm-quot .rightInv = trav∘dist
comm-quot .leftInv x = funExt (dist∘trav x)
choose~canonical : (k : A → B / _~_) → ∥ ∃ k′ × [_] ∘ k′ ≡ k ∥
choose~canonical k =
elimProp/ {B = λ k′ → dist k′ ≡ k → ∥ ∃ k′ × [_] ∘ k′ ≡ k ∥}
(λ _ → isProp→ squash)
(λ k′ r → ∣ k′ , r ∣)
(trav k)
(undistrib k .snd)
elim~canonical : (P : (A → B / _~_) → Type c)
→ (∀ k → isProp (P k))
→ (∀ k′ → P ([_] ∘ k′))
→ ∀ k → P k
elim~canonical P prop r k = ∥rec∥ (prop _) (λ { (k′ , p) → subst P p (r k′) }) (choose~canonical k)
SplitQuotientedChoice : Type a → ∀ b c → Type _
SplitQuotientedChoice A b c =
∀ {B : Type b} {_~_ : B → B → Type c} → SplitQuotientedChoiceAt A B _~_
SplitQuotientedChoiceω : Type a → Typeω
SplitQuotientedChoiceω A = ∀ {b c} → SplitQuotientedChoice A b c
open SplitQuotientedChoiceAt
record QuotientedChoiceAt (A : Type a) (B : Type b) (_~_ : B → B → Type c) : Type (a ℓ⊔ b ℓ⊔ c) where
field ∥undistrib∥ : Surjective (dist {A = A} {B = B} {R = _~_})
splitQuotientedChoiceAt : SplitQuotientedChoiceAt A B _~_
splitQuotientedChoiceAt .undistrib f =
∥rec∥
(λ x y → Σ≡Prop (λ _ → isSet→ squash/ _ _) (inj-dist (x .snd ; sym (y .snd))))
id
(∥undistrib∥ f)
open QuotientedChoiceAt public
[_]-pw : (A → B) → (A → B / R)
[ f ]-pw x = [ f x ]
QProjectiveAt : (A : Type a) → (B : Type b) → (R : B → B → Type c) → Type _
QProjectiveAt A B _~_ = Surjective (([_] ∘_) ⦂ ((A → B) → (A → B / _~_)))
open import Cubical.Foundations.Univalence using (hPropExt)
QProjective-QComm-equiv : QuotientedChoiceAt A B _~_ ≡ QProjectiveAt A B _~_
QProjective-QComm-equiv = hPropExt qc-prop (isPropΠ (λ _ → squash)) projective-fwd projective-bwd where
qc-prop : isProp (QuotientedChoiceAt A B _~_)
qc-prop x y i = record { ∥undistrib∥ = isPropΠ (λ _ → squash) (∥undistrib∥ x) (∥undistrib∥ y) i}
projective-fwd : ∀ {A : Type a} {B : Type b} {_~_ : B → B → Type c}
→ QuotientedChoiceAt A B _~_ → QProjectiveAt A B _~_
projective-fwd {A = A} {B = B} {_~_ = _~_} q f = ∥bind∥ fwd (∥undistrib∥ q f) where
fwd : Fibre dist f → ∥ Fibre (([_] ∘_) ⦂ ((A → B) → (A → B / _~_))) f ∥
fwd (g , e) = elimProp/-with {D = λ g → dist g ≡ f} (λ _ _ → squash)
(λ h e' → ∣ h , e' ∣)
g
e
projective-bwd : ∀ {A : Type a} {B : Type b} {_~_ : B → B → Type c}
→ QProjectiveAt A B _~_ → QuotientedChoiceAt A B _~_
projective-bwd {A = A} {B = B} {_~_ = _~_} q = record { ∥undistrib∥ = λ f → ∥bind∥ (bwd f) (q f) } where
bwd : ∀ f → Fibre (([_] ∘_) ⦂ ((A → B) → (A → B / _~_))) f → ∥ Fibre dist f ∥
bwd f (g , e) = ∣ [ g ] , e ∣
QuotientedChoice : Type a → ∀ b c → Type _
QuotientedChoice A b c = ∀ {B : Type b} {_~_ : B → B → Type c} → QuotientedChoiceAt A B _~_
isPropQuotientedChoice : isProp (QuotientedChoice A b c)
isPropQuotientedChoice x y i .∥undistrib∥ z = squash (x .∥undistrib∥ z) (y .∥undistrib∥ z) i
QuotientedChoiceω : Type a → Typeω
QuotientedChoiceω A = ∀ {b c} → QuotientedChoice A b c
quotientedChoiceSplit : QuotientedChoice A b c → SplitQuotientedChoice A b c
quotientedChoiceSplit fp = splitQuotientedChoiceAt fp
Choice⇒QuotientedChoice : Choice A (b ℓ⊔ c) → QuotientedChoice A b c
Choice⇒QuotientedChoice aoc .∥undistrib∥ f =
∥rec∥ squash (λ h → ∣ [ (λ x → h x .fst) ] , (funExt λ x → snd (h x)) ∣) (aoc (λ x′ → []-surj (f x′)))
module _ where
open import HITs.SetTruncation
AOC⇒QuotientedChoice : AOC a a → ({A : Type a} → QuotientedChoice A a a)
AOC⇒QuotientedChoice aoc .∥undistrib∥ f =
let ac = aoc squash₂ λ x′ → []-surj (∥rec∥₂ squash/ f x′)
in ∥rec∥ squash (λ h → ∣ [ (λ x → h ∣ x ∣₂ .fst) ] , (funExt λ x → h ∣ x ∣₂ .snd ) ∣) ac
open import Data.Sigma.Subset
open import Data.Sigma.Properties
module _ {A : Type a} (set : isSet A) (qc : SplitQuotientedChoice A (a ℓ⊔ b) a) where
SplitQuotientedChoice⇒Choice : Choice A b
SplitQuotientedChoice⇒Choice {B = 𝒰} f = ∥map∥ (Π⇔Σ set .inv) combined-sigma-trunc
where
f/ : A → Subset/ A 𝒰
f/ x = subset-quot (x , f x)
fst/ : Subset/ A 𝒰 → A
fst/ = rec/ set fst λ _ _ → id
f⁻ : Fibre dist f/
f⁻ = qc .undistrib f/
fst∘f : ∀ x → fst/ (f/ x) ≡ x
fst∘f x =
∥elim∥
{ P = λ f·x → fst/ (subset-quot (x , f·x)) ≡ x }
(λ _ → set _ _)
(λ _ → refl)
(f x)
combined-sigma-trunc : ∥ Π⟨Σ⟩ A 𝒰 ∥
combined-sigma-trunc =
elimProp/
{ B = λ f⁻ → dist f⁻ ≡ f/ → ∥ Π⟨Σ⟩ A 𝒰 ∥ }
(λ _ → isProp→ squash)
(λ f⁻ f⁻Π → ∣ f⁻ , (λ x → cong (fst/ ∘ (_$ x)) f⁻Π ; fst∘f x) ∣)
(f⁻ .fst) (f⁻ .snd)
QuotientedChoice⇔SplitQuotientedChoice : QuotientedChoice A b c ⇔ SplitQuotientedChoice A b c
QuotientedChoice⇔SplitQuotientedChoice .fun = quotientedChoiceSplit
QuotientedChoice⇔SplitQuotientedChoice .inv qc .∥undistrib∥ y = ∣ qc .undistrib y ∣
QuotientedChoice⇔SplitQuotientedChoice .rightInv qc i .undistrib = qc .undistrib
QuotientedChoice⇔SplitQuotientedChoice .leftInv _ = isPropQuotientedChoice _ _
QuotientedChoice⇔Choice : AOC a a ↔ ({A : Type a} → QuotientedChoice A a a)
QuotientedChoice⇔Choice .fst = AOC⇒QuotientedChoice
QuotientedChoice⇔Choice .snd qc set = SplitQuotientedChoice⇒Choice set (quotientedChoiceSplit qc)
quotientedChoice⊥ : SplitQuotientedChoice ⊥ b c
quotientedChoice⊥ .undistrib y = [ absurd ] , (funExt λ ())
module UnitInst where
unitTrav : B / _~_ → (⊤ → B) / Pointwise _~_
unitTrav = rec/ squash/ ([_] ∘ const) (λ x y x~y → eq/ _ _ λ i → eq/ x y x~y)
quotientedChoice⊤ : SplitQuotientedChoice ⊤ b c
quotientedChoice⊤ .undistrib f = unitTrav (f tt) , funExt (λ x →
elimProp/
{B = λ ftt → ftt ≡ f tt → dist (unitTrav ftt) tt ≡ f tt }
(λ _ → isProp→ (squash/ _ _))
(λ ftt p → p)
(f tt)
refl)
open UnitInst using (quotientedChoice⊤) public
module BoolInst where
boolTrav : B / _~_ → B / _~_ → (Bool → B) / Pointwise _~_
boolTrav =
rec2/
squash/
(λ f t → [ bool f t ])
(λ x y z p → eq/ _ _ λ { false → eq/ _ _ p ; true → refl })
(λ x y z p → eq/ _ _ λ { false → refl ; true → eq/ _ _ p })
quotientedChoiceBool : SplitQuotientedChoice Bool b c
quotientedChoiceBool .undistrib f = boolTrav (f false) (f true) , funExt (λ x →
elimProp2/
{P = λ l r → l ≡ f false → r ≡ f true → dist (boolTrav l r) x ≡ f x}
(λ _ _ → isProp→ (isProp→ (squash/ _ _)))
(λ fl tr fp tp → bool {P = λ x → [ bool′ fl tr x ] ≡ f x } fp tp x)
(f false)
(f true)
refl
refl)
open BoolInst using (quotientedChoiceBool) public
module ProdInst
(finLhs : SplitQuotientedChoiceω A)
(finRhs : SplitQuotientedChoiceω B)
where
lemma : (f g : A → B → C) → Pointwise (Pointwise _~_) f g → [ uncurry f ] ≡ [ uncurry g ]
lemma {C = C} {_~_ = _~_} f g p = eq/ {R = Pointwise _~_} _ _ λ { (x , y) → effective/ (λ x y → isPropΠ λ _ → squash/ _ _) er _ _ (p x) y }
where
er : isEquivRel (λ f g → ∀ x → [ f x ] ≡ [ g x ])
er .isEquivRel.reflexive a x = refl
er .isEquivRel.symmetric a b p x = sym (p x)
er .isEquivRel.transitive a b c p q x = p x ; q x
prodTrav : {C : Type c} {_~_ : C → C → Type b} → (A × B → C / _~_) → (A × B → C) / Pointwise _~_
prodTrav {C = C} {_~_ = _~_} f = rec/ squash/ ([_] ∘ uncurry) lemma (fst (undistrib finLhs (λ x → fst (undistrib finRhs (curry f x)))))
quotientedChoiceProd : SplitQuotientedChoiceω (A × B)
quotientedChoiceProd {B = C} {_~_ = _~_} .undistrib f = prodTrav f ,
funExt
(λ { (x , y) →
elimProp/
{B = λ r → r ≡ unLhs .fst → dist (rec/ squash/ ([_] ∘ uncurry) lemma r) (x , y) ≡ f (x , y) }
(λ _ → isProp→ (squash/ _ _))
(λ h q →
dist [ uncurry h ] (x , y) ≡⟨⟩
[ h x y ] ≡⟨ cong (λ e → dist (e x) y) (cong dist q ; unLhs .snd) ⟩
dist (unRhs x .fst) y ≡⟨ cong (_$ y) (unRhs x .snd) ⟩
f (x , y) ∎
)
_ refl
})
where
unRhs : (x : A) → Fibre dist (curry f x)
unRhs x = undistrib finRhs (curry f x)
unLhs : Fibre dist (λ x → fst (unRhs x))
unLhs = undistrib finLhs (λ x → fst (unRhs x))
open ProdInst using (quotientedChoiceProd) public
module SumInst
(finLhs : SplitQuotientedChoice A b c)
(finRhs : SplitQuotientedChoice B b c)
where
sumTrav : (A → C) / Pointwise _~_ → (B → C) / Pointwise _~_ → (A ⊎ B → C) / Pointwise _~_
sumTrav =
rec2/
squash/
(λ f g → [ either f g ])
(λ f g h p → eq/ _ _ λ { (inl x) → p x ; (inr x) → refl} )
(λ f g h p → eq/ _ _ λ { (inl x) → refl ; (inr x) → p x })
quotientedChoiceSum : SplitQuotientedChoice (A ⊎ B) b c
quotientedChoiceSum .undistrib f = sumTrav
(fst (undistrib finLhs (f ∘ inl))) (fst (undistrib finRhs (f ∘ inr))) ,
funExt (λ t →
elimProp2/
{P = λ x y → x ≡ fst (undistrib finLhs (f ∘ inl)) → y ≡ fst (undistrib finRhs (f ∘ inr)) → dist (sumTrav x y) t ≡ f t }
(λ _ _ → isProp→ (isProp→ (squash/ _ _)))
(λ g h p q →
let lhs = cong dist p ; undistrib finLhs (f ∘ inl) .snd
rhs = cong dist q ; undistrib finRhs (f ∘ inr) .snd
in either {C = λ t → dist [ either g h ] t ≡ f t} (λ x → cong (_$ x) lhs) (λ x → cong (_$ x) rhs) t )
_ _ refl refl)
open SumInst using (quotientedChoiceSum) public
module LiftInst
(finPres : SplitQuotientedChoice A b c)
{ℓ : Level}
where
liftTrav : {B : Type b} {_~_ : B → B → Type c} → (Lift {ℓ₂ = ℓ} A → B / _~_) → (Lift {ℓ₂ = ℓ} A → B) / Pointwise _~_
liftTrav y = rec/ squash/ (λ f → [ f ∘ lower ]) (λ f g p → eq/ _ _ λ x → p (lower x) ) (undistrib finPres (y ∘ lift) .fst)
open import Data.Lift.Properties
quotientedChoiceLift : SplitQuotientedChoice (Lift {ℓ₂ = ℓ} A) b c
quotientedChoiceLift .undistrib y = liftTrav y ,
elimProp/
{B = λ y′ → y′ ≡ (undistrib finPres (λ x → y (lift x)) .fst) → dist (rec/ squash/ (λ f → [ f ∘ lower ] ) _ y′ ) ≡ y}
(λ _ → isProp→ (isSetΠ (λ _ → squash/ ) _ _ ) )
(λ f p → funExt (λ { (lift h) → (cong (λ e → dist e h) p) ; cong (_$ h) (undistrib finPres (y ∘ lift) .snd) } ))
_
refl
open LiftInst using (quotientedChoiceLift) public
module CircInst where
open import Cubical.HITs.S1
circTrav : B / _~_ → (S¹ → B) / Pointwise _~_
circTrav = rec/ squash/ ([_] ∘ const) (λ x y x~y → eq/ _ _ λ i → eq/ x y x~y)
quotientedChoiceS : SplitQuotientedChoice S¹ b c
quotientedChoiceS .undistrib f = circTrav (f base) ,
funExt (toPropElim (λ _ → squash/ _ _)
(elimProp/
{B = λ ftt → ftt ≡ f base → dist (circTrav ftt) base ≡ f base }
(λ _ → isProp→ (squash/ _ _))
(λ ftt p → p)
(f base)
refl))
\end{code}