{-# OPTIONS --safe --postfix-projections #-} open import Cubical.Foundations.Prelude open import Cubical.Foundations.Function renaming (uncurry to λ⟨,⟩_) open import Cubical.Foundations.Isomorphism open import Cubical.Foundations.Equiv open import Cubical.Foundations.Univalence open import Cubical.Foundations.Transport open import Cubical.Foundations.CartesianKanOps open import Cubical.Data.Sigma.Properties module Cubical.Modalities.Lex (◯ : ∀ {ℓ} → Type ℓ → Type ℓ) (η : ∀ {ℓ} {A : Type ℓ} → A → ◯ A) (isModal : ∀ {ℓ} → Type ℓ → Type ℓ) (let isModalFam = λ {ℓ ℓ' : Level} {A : Type ℓ} (B : A → Type ℓ') → (x : A) → isModal (B x)) (idemp : ∀ {ℓ} {A : Type ℓ} → isModal (◯ A)) (≡-modal : ∀ {ℓ} {A : Type ℓ} {x y : A} (A-mod : isModal A) → isModal (x ≡ y)) (◯-ind : ∀ {ℓ ℓ'} {A : Type ℓ} {B : ◯ A → Type ℓ'} (B-mod : isModalFam B) (f : (x : A) → B (η x)) → ([x] : ◯ A) → B [x]) (◯-ind-β : ∀ {ℓ ℓ'} {A : Type ℓ} {B : ◯ A → Type ℓ'} (B-mod : isModalFam B) (f : (x : A) → B (η x)) (x : A) → ◯-ind B-mod f (η x) ≡ f x) (let Type◯ = λ (ℓ : Level) → Σ (Type ℓ) isModal) (◯-lex : ∀ {ℓ} → isModal (Type◯ ℓ)) where private variable ℓ ℓ' : Level η-at : (A : Type ℓ) → A → ◯ A η-at _ = η module _ where private variable A : Type ℓ B : Type ℓ' module ◯-rec (B-mod : isModal B) (f : A → B) where abstract ◯-rec : ◯ A → B ◯-rec = ◯-ind (λ _ → B-mod) f ◯-rec-β : (x : A) → ◯-rec (η x) ≡ f x ◯-rec-β = ◯-ind-β (λ _ → B-mod) f open ◯-rec module ◯-map (f : A → B) where abstract ◯-map : ◯ A → ◯ B ◯-map = ◯-rec idemp λ x → η (f x) ◯-map-β : (x : A) → ◯-map (η x) ≡ η (f x) ◯-map-β x = ◯-rec-β idemp _ x open ◯-rec open ◯-map module IsModalToUnitIsEquiv (A : Type ℓ) (A-mod : isModal A) where abstract inv : ◯ A → A inv = ◯-rec A-mod λ x → x η-retract : retract η inv η-retract = ◯-rec-β _ _ η-section : section η inv η-section = ◯-ind (λ _ → ≡-modal idemp) λ x i → η (η-retract x i) η-iso : Iso A (◯ A) Iso.fun η-iso = η Iso.inv η-iso = inv Iso.rightInv η-iso = η-section Iso.leftInv η-iso = η-retract η-is-equiv : isEquiv (η-at A) η-is-equiv = isoToIsEquiv η-iso abstract unit-is-equiv-to-is-modal : {A : Type ℓ} → isEquiv (η-at A) → isModal A unit-is-equiv-to-is-modal p = transport (cong isModal (sym (ua (η , p)))) idemp retract-is-modal : {A : Type ℓ} {B : Type ℓ'} → (A-mod : isModal A) (f : A → B) (g : B → A) (r : retract g f) → isModal B retract-is-modal {A = A} {B = B} A-mod f g r = unit-is-equiv-to-is-modal (isoToIsEquiv (iso η η-inv η-section η-retract)) where η-inv : ◯ B → B η-inv = f ∘ ◯-rec A-mod g η-retract : retract η η-inv η-retract b = cong f (◯-rec-β A-mod g b) ∙ r b η-section : section η η-inv η-section = ◯-ind (λ _ → ≡-modal idemp) (cong η ∘ η-retract) module LiftFam {A : Type ℓ} (B : A → Type ℓ') where module M = IsModalToUnitIsEquiv (Type◯ ℓ') ◯-lex abstract ◯-lift-fam : ◯ A → Type◯ ℓ' ◯-lift-fam = M.inv ∘ ◯-map (λ a → ◯ (B a) , idemp) ⟨◯⟩ : ◯ A → Type ℓ' ⟨◯⟩ [a] = ◯-lift-fam [a] .fst ⟨◯⟩-modal : isModalFam ⟨◯⟩ ⟨◯⟩-modal [a] = ◯-lift-fam [a] .snd ⟨◯⟩-compute : (x : A) → ⟨◯⟩ (η x) ≡ ◯ (B x) ⟨◯⟩-compute x = ⟨◯⟩ (η x) ≡⟨ cong (fst ∘ M.inv) (◯-map-β _ _) ⟩ M.inv (η (◯ (B x) , idemp)) .fst ≡⟨ cong fst (M.η-retract _) ⟩ ◯ (B x) ∎ open LiftFam using (⟨◯⟩; ⟨◯⟩-modal; ⟨◯⟩-compute) module LiftFamExtra {A : Type ℓ} {B : A → Type ℓ'} where ⟨◯⟩←◯ : ∀ {a} → ◯ (B a) → ⟨◯⟩ B (η a) ⟨◯⟩←◯ = transport (sym (⟨◯⟩-compute B _)) ⟨◯⟩→◯ : ∀ {a} → ⟨◯⟩ B (η a) → ◯ (B a) ⟨◯⟩→◯ = transport (⟨◯⟩-compute B _) ⟨η⟩ : ∀ {a} → B a → ⟨◯⟩ B (η a) ⟨η⟩ = ⟨◯⟩←◯ ∘ η abstract ⟨◯⟩→◯-section : ∀ {a} → section (⟨◯⟩→◯ {a}) ⟨◯⟩←◯ ⟨◯⟩→◯-section = transport⁻Transport (sym (⟨◯⟩-compute _ _)) module Combinators where private variable ℓ'' : Level A A′ : Type ℓ B : A → Type ℓ' C : Σ A B → Type ℓ'' λ/coe⟨_⟩_ : (p : A ≡ A′) → ((x : A′) → B (coe1→0 (λ i → p i) x)) → ((x : A) → B x) λ/coe⟨_⟩_ {B = B} p f = coe1→0 (λ i → (x : p i) → B (coei→0 (λ j → p j) i x)) f open Combinators module _ {A : Type ℓ} {B : A → Type ℓ'} where abstract Π-modal : isModalFam B → isModal ((x : A) → B x) Π-modal B-mod = retract-is-modal idemp η-inv η retr where η-inv : ◯ ((x : A) → B x) → (x : A) → B x η-inv [f] x = ◯-rec (B-mod x) (λ f → f x) [f] retr : retract η η-inv retr f = funExt λ x → ◯-rec-β (B-mod x) _ f Σ-modal : isModal A → isModalFam B → isModal (Σ A B) Σ-modal A-mod B-mod = retract-is-modal idemp η-inv η retr where h : ◯ (Σ A B) → A h = ◯-rec A-mod fst h-β : (x : Σ A B) → h (η x) ≡ fst x h-β = ◯-rec-β A-mod fst f : (i : I) (x : Σ A B) → B (h-β x i) f i x = coe1→i (λ j → B (h-β x j)) i (snd x) η-inv : ◯ (Σ A B) → Σ A B η-inv y = h y , ◯-ind (B-mod ∘ h) (f i0) y retr : (p : Σ A B) → η-inv (η p) ≡ p retr p = η-inv (η p) ≡⟨ ΣPathP (refl , ◯-ind-β _ _ _) ⟩ h (η p) , f i0 p ≡⟨ ΣPathP (h-β _ , λ i → f i p) ⟩ p ∎ module Σ-commute {A : Type ℓ} (B : A → Type ℓ') where open LiftFamExtra ◯Σ = ◯ (Σ A B) module Σ◯ where Σ◯ = Σ (◯ A) (⟨◯⟩ B) abstract Σ◯-modal : isModal Σ◯ Σ◯-modal = Σ-modal idemp (⟨◯⟩-modal _) open Σ◯ η-Σ◯ : Σ A B → Σ◯ η-Σ◯ (x , y) = η x , ⟨η⟩ y module Push where abstract fun : ◯Σ → Σ◯ fun = ◯-rec Σ◯-modal η-Σ◯ compute : fun ∘ η ≡ η-Σ◯ compute = funExt (◯-rec-β _ _) module Unpush where abstract fun : Σ◯ → ◯Σ fun = λ⟨,⟩ ◯-ind (λ _ → Π-modal λ _ → idemp) λ x → λ/coe⟨ ⟨◯⟩-compute B x ⟩ ◯-map (x ,_) compute : fun ∘ η-Σ◯ ≡ η compute = funExt λ p → fun (η-Σ◯ p) ≡⟨ funExt⁻ (◯-ind-β _ _ _) _ ⟩ transport refl (◯-map _ _) ≡⟨ transportRefl _ ⟩ ◯-map _ (⟨◯⟩→◯ (⟨η⟩ _)) ≡⟨ cong (◯-map _) (⟨◯⟩→◯-section _) ⟩ ◯-map _ (η _) ≡⟨ ◯-map-β _ _ ⟩ η p ∎ push-unpush-compute : Push.fun ∘ Unpush.fun ∘ η-Σ◯ ≡ η-Σ◯ push-unpush-compute = Push.fun ∘ Unpush.fun ∘ η-Σ◯ ≡⟨ cong (Push.fun ∘_) Unpush.compute ⟩ Push.fun ∘ η ≡⟨ Push.compute ⟩ η-Σ◯ ∎ unpush-push-compute : Unpush.fun ∘ Push.fun ∘ η ≡ η unpush-push-compute = Unpush.fun ∘ Push.fun ∘ η ≡⟨ cong (Unpush.fun ∘_) Push.compute ⟩ Unpush.fun ∘ η-Σ◯ ≡⟨ Unpush.compute ⟩ η ∎ is-section : section Unpush.fun Push.fun is-section = ◯-ind (λ x → ≡-modal idemp) λ x i → unpush-push-compute i x is-retract : retract Unpush.fun Push.fun is-retract = λ⟨,⟩ ◯-ind (λ _ → Π-modal λ _ → ≡-modal Σ◯-modal) λ x → λ/coe⟨ ⟨◯⟩-compute B x ⟩ ◯-ind (λ _ → ≡-modal Σ◯-modal) (λ y i → push-unpush-compute i (x , y)) push-sg-is-equiv : isEquiv Push.fun push-sg-is-equiv = isoToIsEquiv (iso Push.fun Unpush.fun is-retract is-section) isConnected : Type ℓ → Type ℓ isConnected A = isContr (◯ A) module FormalDiskBundle {A : Type ℓ} where 𝔻 : A → Type ℓ 𝔻 a = Σ[ x ∈ A ] η a ≡ η x