{-# OPTIONS --guardedness #-}
import Equality.Path as P
module Lens.Non-dependent.Higher.Coinductive.Erased
{e⁺} (eq : ∀ {a p} → P.Equality-with-paths a p e⁺) where
open P.Derived-definitions-and-properties eq
open import Logical-equivalence using (_⇔_)
open import Prelude
import Colimit.Sequential.Very-erased eq as CS
open import Equality.Decidable-UIP equality-with-J using (Constant)
open import Equality.Path.Isomorphisms eq
open import Equivalence equality-with-J as Eq
using (_≃_; Is-equivalence)
open import Equivalence.Erased.Cubical eq as EEq using (_≃ᴱ_)
open import Equivalence.Erased.Contractible-preimages.Cubical eq
using (_⁻¹ᴱ_)
open import Erased.Cubical eq
open import Function-universe equality-with-J as F hiding (id; _∘_)
open import H-level equality-with-J as H-level
open import H-level.Closure equality-with-J
open import H-level.Truncation.Propositional.Erased eq as T
using (∥_∥ᴱ; ∣_∣)
import H-level.Truncation.Propositional.Non-recursive.Erased eq as N
open import H-level.Truncation.Propositional.One-step eq as O
using (∣_∣; ∥_∥¹-out-^; ∥_∥¹-in-^; ∣_,_∣-in-^)
open import Univalence-axiom equality-with-J
open import Lens.Non-dependent eq
import Lens.Non-dependent.Higher.Erased eq as Higher
import Lens.Non-dependent.Higher.Capriotti.Variant.Erased.Variant eq
as V
open import Lens.Non-dependent.Higher.Coherently.Coinductive eq
import Lens.Non-dependent.Higher.Coinductive eq as C
import Lens.Non-dependent.Higher.Coinductive.Small eq as S
private
variable
a b p : Level
A B : Type a
n : ℕ
private
@0 ∥∥ᴱ→≃-lemma :
Block "∥∥ᴱ→≃-lemma" →
(f₀ : A → B) →
(∃ λ (f₊ : ∀ n → ∥ A ∥¹-out-^ (1 + n) → B) →
(∀ x → f₊ zero ∣ x ∣ ≡ f₀ x) ×
(∀ n x → f₊ (suc n) ∣ x ∣ ≡ f₊ n x)) ≃
(∃ λ (f₊ : ∀ n → ∥ A ∥¹-in-^ (1 + n) → B) →
(∀ x → f₊ zero ∣ x ∣ ≡ f₀ x) ×
(∀ n x → f₊ (suc n) ∣ n , x ∣-in-^ ≡ f₊ n x))
∥∥ᴱ→≃-lemma ⊠ _ =
inverse $
Σ-cong {k₁ = equivalence}
(∀-cong ext λ n →
→-cong₁ ext (inverse $ O.∥∥¹-out-^≃∥∥¹-in-^ (suc n))) λ f →
∃-cong λ _ → ∀-cong ext λ n →
Π-cong-contra ext (O.∥∥¹-out-^≃∥∥¹-in-^ (suc n)) λ x →
≡⇒≃ $ cong (λ y → f (suc n) y ≡
f n (_≃_.to (O.∥∥¹-out-^≃∥∥¹-in-^ (suc n)) x)) $
sym $ O.∣∣≡∣,∣-in-^ (1 + n)
∥∥ᴱ→≃ :
Block "∥∥ᴱ→≃" →
{A : Type a} {B : Type b} →
@0 Univalence (a ⊔ b) →
(∥ A ∥ᴱ → B)
≃
(∃ λ (f : A → B) → Erased (C.Coherently-constant f))
∥∥ᴱ→≃ bl {A = A} {B = B} univ =
(∥ A ∥ᴱ → B) ↝⟨ →-cong ext T.∥∥ᴱ≃∥∥ᴱ F.id ⟩
(N.∥ A ∥ᴱ → B) ↝⟨ CS.universal-property ⟩
(∃ λ (f₀ : A → B) →
Erased (∃ λ (f₊ : ∀ n → ∥ A ∥¹-out-^ (1 + n) → B) →
(∀ x → f₊ zero ∣ x ∣ ≡ f₀ x) ×
(∀ n x → f₊ (suc n) ∣ x ∣ ≡ f₊ n x))) ↝⟨ ∃-cong (λ f → Erased-cong (∥∥ᴱ→≃-lemma bl f)) ⟩
(∃ λ (f₀ : A → B) →
Erased (∃ λ (f₊ : ∀ n → ∥ A ∥¹-in-^ (1 + n) → B) →
(∀ x → f₊ zero ∣ x ∣ ≡ f₀ x) ×
(∀ n x → f₊ (suc n) ∣ n , x ∣-in-^ ≡ f₊ n x))) ↝⟨ ∃-cong (λ f → Erased-cong (inverse $
C.Coherently-constant′≃ bl)) ⟩
(∃ λ (f : A → B) → Erased (C.Coherently-constant′ f)) ↝⟨ ∃-cong (λ f → Erased-cong (inverse $
C.Coherently-constant≃Coherently-constant′ bl univ)) ⟩□
(∃ λ (f : A → B) → Erased (C.Coherently-constant f)) □
@0 cong-from-∥∥ᴱ→≃-truncation-is-proposition :
(bl : Block "∥∥ᴱ→≃")
{A : Type a} {B : Type b}
(univ : Univalence (a ⊔ b)) →
{f : A → B} {c : C.Coherently-constant f}
{x y : A} {p : ∣ x ∣ ≡ ∣ y ∣} →
cong (_≃_.from (∥∥ᴱ→≃ bl univ) (f , [ c ])) p ≡
c .property x y
cong-from-∥∥ᴱ→≃-truncation-is-proposition
bl {A = A} univ {f = f} {c = c} {x = x} {y = y} {p = p} =
cong (_≃_.from (∥∥ᴱ→≃ bl univ) (f , [ c ])) p ≡⟨⟩
cong (_≃_.from CS.universal-property (f , [ g bl ]) ∘
_≃_.to T.∥∥ᴱ≃∥∥ᴱ)
p ≡⟨ sym $ cong-∘ _ _ _ ⟩
(cong (_≃_.from CS.universal-property (f , [ g bl ])) $
cong (_≃_.to T.∥∥ᴱ≃∥∥ᴱ) p) ≡⟨ cong (cong _) $ mono₁ 1 N.∥∥ᴱ-proposition _ _ ⟩
cong (_≃_.from CS.universal-property (f , [ g bl ]))
(N.∥∥ᴱ-proposition N.∣ x ∣ N.∣ y ∣) ≡⟨⟩
cong (_≃_.from CS.universal-property (f , [ g bl ]))
(trans (sym (CS.∣∣₊≡∣∣₀ x))
(trans (cong CS.∣_∣₊ (O.∣∣-constant x y))
(CS.∣∣₊≡∣∣₀ y))) ≡⟨ trans (cong-trans _ _ _) $
cong₂ trans
(cong-sym _ _)
(trans (cong-trans _ _ _) $
cong (flip trans _) $
cong-∘ _ _ _) ⟩
trans
(sym $ cong (_≃_.from CS.universal-property (f , [ g bl ]))
(CS.∣∣₊≡∣∣₀ x))
(trans
(cong (_≃_.from CS.universal-property (f , [ g bl ]) ∘ CS.∣_∣₊)
(O.∣∣-constant x y))
(cong (_≃_.from CS.universal-property (f , [ g bl ]))
(CS.∣∣₊≡∣∣₀ y))) ≡⟨ cong₂ trans
(cong sym CS.rec-∣∣₊≡∣∣₀)
(cong (trans _) CS.rec-∣∣₊≡∣∣₀) ⟩
trans (sym $ proj₁ (proj₂ (g bl)) x)
(trans (cong (proj₁ (g bl) 0) (O.∣∣-constant x y))
(proj₁ (proj₂ (g bl)) y)) ≡⟨ lemma bl ⟩∎
c .property x y ∎
where
g : ∀ _ → _
g bl =
_≃_.from (∥∥ᴱ→≃-lemma bl _) $
_≃_.to (C.Coherently-constant′≃ bl) $
_≃_.to (C.Coherently-constant≃Coherently-constant′ bl univ) c
lemma :
∀ bl →
trans (sym $ proj₁ (proj₂ (g bl)) x)
(trans (cong (proj₁ (g bl) 0) (O.∣∣-constant x y))
(proj₁ (proj₂ (g bl)) y)) ≡
c .property x y
lemma bl@⊠ =
trans (sym $ proj₁ (proj₂ (g bl)) x)
(trans (cong (proj₁ (g bl) 0) (O.∣∣-constant x y))
(proj₁ (proj₂ (g bl)) y)) ≡⟨⟩
trans (sym $ refl _)
(trans (cong (O.rec′ f (c .property)) (O.∣∣-constant x y))
(refl _)) ≡⟨ trans (cong₂ trans sym-refl (trans-reflʳ _)) $
trans-reflˡ _ ⟩
cong (O.rec′ f (c .property)) (O.∣∣-constant x y) ≡⟨ O.rec-∣∣-constant ⟩∎
c .property x y ∎
Coherently-constant :
{A : Type a} → (A → Type p) → Type (a ⊔ lsuc p)
Coherently-constant P =
∃ λ (f : ∀ x y → P x → P y) →
Erased (∃ λ (c : C.Coherently-constant P) →
∀ x y → f x y ≡ subst id (c .property x y))
Coherently-constant≃ᴱCoherently-constant :
{A : Type a} {P : A → Type p} →
@0 Univalence (a ⊔ lsuc p) →
@0 Univalence p →
Coherently-constant P ≃ᴱ V.Coherently-constant P
Coherently-constant≃ᴱCoherently-constant
{a = a} {p = p} {A = A} {P = P} univ′ univ =
block λ bl →
Coherently-constant P ↔⟨⟩
(∃ λ (P-const : ∀ x y → P x → P y) →
Erased (
∃ λ (c : C.Coherently-constant P) →
∀ x y →
P-const x y ≡ subst id (c .property x y))) ↔⟨ (∃-cong λ P-const → Erased-cong (
∃-cong λ c → ∀-cong ext λ x → ∀-cong ext λ y →
≡⇒≃ $ cong (P-const x y ≡_) (
subst id (c .property x y) ≡⟨ cong (subst id) $ sym $
cong-from-∥∥ᴱ→≃-truncation-is-proposition bl univ′ ⟩
subst id
(cong (_≃_.from (∥∥ᴱ→≃ bl univ′) (P , [ c ]))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣)) ≡⟨ (⟨ext⟩ λ _ → sym $
subst-∘ _ _ _) ⟩∎
subst (_≃_.from (∥∥ᴱ→≃ bl univ′) (P , [ c ]))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣) ∎))) ⟩
(∃ λ (P-const : ∀ x y → P x → P y) →
Erased (
∃ λ (c : C.Coherently-constant P) →
∀ x y →
P-const x y ≡
subst (_≃_.from (∥∥ᴱ→≃ bl univ′) (P , [ c ]))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣))) ↔⟨ (∃-cong λ _ → Erased-cong (∃-cong λ _ →
Eq.extensionality-isomorphism bad-ext F.∘
(∀-cong ext λ _ → Eq.extensionality-isomorphism bad-ext))) ⟩
(∃ λ (P-const : ∀ x y → P x → P y) →
Erased (
∃ λ (c : C.Coherently-constant P) →
P-const ≡
λ x y →
subst (_≃_.from (∥∥ᴱ→≃ bl univ′) (P , [ c ]))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣))) ↔⟨ (∃-cong λ P-const → Erased-cong (
∃-cong λ c → ≡⇒≃ $ cong (P-const ≡_) $ sym $
⟨ext⟩ λ x → ⟨ext⟩ λ y →
cong₂ (λ (f : P y → P y) (g : P x → P x) →
f ∘
subst (_≃_.from (∥∥ᴱ→≃ bl univ′) (P , [ c ]))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣) ∘
g)
(cong _≃_.to $
trans (cong ≡⇒≃ $ cong-refl (_$ y)) $
≡⇒↝-refl)
(cong _≃_.from $
trans (cong ≡⇒≃ $ cong-refl (_$ x)) $
≡⇒↝-refl))) ⟩
(∃ λ (P-const : ∀ x y → P x → P y) →
Erased (
∃ λ (c : C.Coherently-constant P) →
P-const ≡
λ x y →
≡⇒→ (cong (_$ y) (refl P)) ∘
subst (_≃_.from (∥∥ᴱ→≃ bl univ′) (P , [ c ]))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣) ∘
_≃_.from (≡⇒≃ (cong (_$ x) (refl P))))) ↝⟨ (∃-cong λ P-const → inverse $
EEq.drop-⊤-left-Σ-≃ᴱ-Erased
(EEq.other-singleton-with-Π-≃ᴱ-≃ᴱ-⊤ ext univ)) ⟩
(∃ λ (P-const : ∀ x y → P x → P y) →
∃ λ ((Q , P≃) : ∃ λ (Q : A → Type p) → ∀ x → P x ≃ᴱ Q x) →
Erased (
∃ λ (c : C.Coherently-constant Q) →
P-const ≡
λ x y →
_≃ᴱ_.from (P≃ y) ∘
subst (_≃_.from (∥∥ᴱ→≃ bl univ′) (Q , [ c ]))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣) ∘
_≃ᴱ_.to (P≃ x))) ↔⟨ (∃-cong λ _ →
Σ-assoc F.∘
(∃-cong λ _ → ∃-comm) F.∘
inverse Σ-assoc F.∘
(∃-cong λ _ → Erased-Σ↔Σ)) ⟩
(∃ λ (P-const : ∀ x y → P x → P y) →
∃ λ ((Q , c) : ∃ λ (Q : A → Type p) →
Erased (C.Coherently-constant Q)) →
∃ λ (P≃ : ∀ x → P x ≃ᴱ Q x) →
Erased (P-const ≡
λ x y →
_≃ᴱ_.from (P≃ y) ∘
subst (_≃_.from (∥∥ᴱ→≃ bl univ′) (Q , c))
(T.truncation-is-proposition ∣ x ∣ ∣ y ∣) ∘
_≃ᴱ_.to (P≃ x))) ↔⟨ (∃-cong λ _ →
Σ-cong (inverse $ ∥∥ᴱ→≃ bl univ′) λ _ → Eq.id) ⟩
(∃ λ (P-const : ∀ x y → P x → P y) →
∃ λ (Q : ∥ A ∥ᴱ → Type p) →
∃ λ (P≃ : ∀ x → P x ≃ᴱ Q ∣ x ∣) →
Erased (P-const ≡
λ x y →
_≃ᴱ_.from (P≃ y) ∘
subst Q (T.truncation-is-proposition ∣ x ∣ ∣ y ∣) ∘
_≃ᴱ_.to (P≃ x))) ↔⟨⟩
V.Coherently-constant′ P ↝⟨ inverse V.Coherently-constant≃ᴱCoherently-constant′ ⟩□
V.Coherently-constant P □
Lens : Type a → Type b → Type (lsuc (a ⊔ b))
Lens A B = ∃ λ (get : A → B) → Coherently-constant (get ⁻¹ᴱ_)
module Lens {A : Type a} {B : Type b} (l : Lens A B) where
get : A → B
get = proj₁ l
get⁻¹ᴱ-const : (b₁ b₂ : B) → get ⁻¹ᴱ b₁ → get ⁻¹ᴱ b₂
get⁻¹ᴱ-const b₁ b₂ = proj₁ (proj₂ l) b₁ b₂
set : A → B → A
set a b = $⟨ get⁻¹ᴱ-const (get a) b ⟩
(get ⁻¹ᴱ get a → get ⁻¹ᴱ b) ↝⟨ _$ (a , [ refl _ ]) ⟩
get ⁻¹ᴱ b ↝⟨ proj₁ ⟩□
A □
instance
has-getter-and-setter : Has-getter-and-setter (Lens {a = a} {b = b})
has-getter-and-setter = record
{ get = Lens.get
; set = Lens.set
}
Lens≃ᴱLens :
Block "Lens≃ᴱLens" →
{A : Type a} {B : Type b} →
@0 Univalence (lsuc (a ⊔ b)) →
@0 Univalence (a ⊔ b) →
Lens A B ≃ᴱ V.Lens A B
Lens≃ᴱLens ⊠ {A = A} {B = B} univ′ univ =
(∃ λ (get : A → B) → Coherently-constant (get ⁻¹ᴱ_)) ↝⟨ (∃-cong λ _ →
Coherently-constant≃ᴱCoherently-constant univ′ univ) ⟩□
(∃ λ (get : A → B) → V.Coherently-constant (get ⁻¹ᴱ_)) □
from-Lens≃ᴱLens-preserves-getters-and-setters :
(bl : Block "Lens≃ᴱLens")
{A : Type a} {B : Type b}
(@0 univ′ : Univalence (lsuc (a ⊔ b)))
(@0 univ : Univalence (a ⊔ b)) →
Preserves-getters-and-setters-→ A B
(_≃ᴱ_.from (Lens≃ᴱLens bl univ′ univ))
from-Lens≃ᴱLens-preserves-getters-and-setters ⊠ _ _ l =
refl _
, ⟨ext⟩ λ a → ⟨ext⟩ λ b →
proj₁ (get⁻¹ᴱ-const (get a) b (a , [ refl (get a) ])) ∎
where
open V.Lens l
@0 Lens≃ᴱLens-preserves-getters-and-setters :
(bl : Block "Lens≃ᴱLens")
{A : Type a} {B : Type b}
(@0 univ′ : Univalence (lsuc (a ⊔ b)))
(@0 univ : Univalence (a ⊔ b)) →
Preserves-getters-and-setters-⇔ A B
(_≃ᴱ_.logical-equivalence (Lens≃ᴱLens bl univ′ univ))
Lens≃ᴱLens-preserves-getters-and-setters bl univ′ univ =
Preserves-getters-and-setters-⇔-inverse
{f = _≃ᴱ_.logical-equivalence
(inverse $ Lens≃ᴱLens bl univ′ univ)} $
Preserves-getters-and-setters-→-↠-⇔
(_≃_.surjection (EEq.≃ᴱ→≃ $ inverse $ Lens≃ᴱLens bl univ′ univ))
(from-Lens≃ᴱLens-preserves-getters-and-setters bl univ′ univ)
Lens≃ᴱHigher-lens :
Block "Lens≃ᴱHigher-Lens" →
{A : Type a} {B : Type b} →
@0 Univalence (lsuc (a ⊔ b)) →
@0 Univalence (a ⊔ b) →
Lens A B ≃ᴱ Higher.Lens A B
Lens≃ᴱHigher-lens bl {A = A} {B = B} univ′ univ =
Lens A B ↝⟨ Lens≃ᴱLens bl univ′ univ ⟩
V.Lens A B ↝⟨ V.Lens≃ᴱHigher-lens bl univ ⟩□
Higher.Lens A B □
@0 Lens≃ᴱHigher-lens-preserves-getters-and-setters :
(bl : Block "Lens≃ᴱHigher-lens")
{A : Type a} {B : Type b}
(@0 univ′ : Univalence (lsuc (a ⊔ b)))
(@0 univ : Univalence (a ⊔ b)) →
Preserves-getters-and-setters-⇔ A B
(_≃ᴱ_.logical-equivalence (Lens≃ᴱHigher-lens bl univ′ univ))
Lens≃ᴱHigher-lens-preserves-getters-and-setters bl univ′ univ =
Preserves-getters-and-setters-⇔-∘
{f = _≃ᴱ_.logical-equivalence $ V.Lens≃ᴱHigher-lens bl univ}
{g = _≃ᴱ_.logical-equivalence $ Lens≃ᴱLens bl univ′ univ}
(V.Lens≃ᴱHigher-lens-preserves-getters-and-setters bl univ)
(Lens≃ᴱLens-preserves-getters-and-setters bl univ′ univ)
H-level-Coherently-constant :
{A : Type a} {P : A → Type p} →
@0 Univalence (lsuc (a ⊔ p)) →
@0 Univalence (a ⊔ lsuc p) →
@0 Univalence p →
((a : A) → H-level n (P a)) →
H-level n (Coherently-constant P)
H-level-Coherently-constant {n = n} univ₁ univ₂ univ₃ h =
Σ-closure n
(Π-closure ext n λ _ →
Π-closure ext n λ _ →
Π-closure ext n λ _ →
h _) λ _ →
H-level-Erased n (
Σ-closure n
(S.H-level-Coinductive-Coherently-constant
univ₁ univ₂ univ₃ h) λ _ →
Π-closure ext n λ _ →
Π-closure ext n λ _ →
H-level.⇒≡ n $
Π-closure ext n λ _ →
h _)
lens-preserves-h-level :
{A : Type a} {B : Type b} →
@0 Univalence (lsuc (a ⊔ b)) →
@0 Univalence (a ⊔ b) →
∀ n → (B → H-level n A) → (A → H-level n B) →
H-level n (Lens A B)
lens-preserves-h-level univ₁ univ₂ n hA hB =
Σ-closure n
(Π-closure ext n λ a →
hB a) λ _ →
H-level-Coherently-constant univ₁ univ₁ univ₂ λ b →
Σ-closure n (hA b) λ a →
H-level-Erased n (
H-level.⇒≡ n (hB a))
@0 h-level-respects-lens-from-inhabited :
{A : Type a} {B : Type b} →
Univalence (lsuc (a ⊔ b)) →
Univalence (a ⊔ b) →
∀ n → Lens A B → A → H-level n A → H-level n B
h-level-respects-lens-from-inhabited univ′ univ n =
Higher.h-level-respects-lens-from-inhabited n ∘
_≃ᴱ_.to (Lens≃ᴱHigher-lens ⊠ univ′ univ)
@0 lens-preserves-h-level-of-domain :
{A : Type a} {B : Type b} →
Univalence (lsuc (a ⊔ b)) →
Univalence (a ⊔ b) →
∀ n → H-level (1 + n) A → H-level (1 + n) (Lens A B)
lens-preserves-h-level-of-domain univ′ univ n hA =
H-level.[inhabited⇒+]⇒+ n λ l →
lens-preserves-h-level univ′ univ (1 + n) (λ _ → hA) λ a →
h-level-respects-lens-from-inhabited univ′ univ _ l a hA