\begin{code} {-# OPTIONS --cubical --safe --postfix-projections #-} module Cardinality.Finite.Kuratowski where open import Prelude open import Algebra.Construct.Free.Semilattice open import Algebra.Construct.Free.Semilattice.Relation.Unary open import Cardinality.Finite.ManifestEnumerable open import Cardinality.Finite.ManifestEnumerable.Inductive renaming (_∈_ to _L∈_) open import HITs.PropositionalTruncation import HITs.PropositionalTruncation as PropTrunc open import HITs.PropositionalTruncation.Sugar open import Data.Fin 𝒦ᶠ : Type a → Type a \end{code} %<*kuratowski-finite-def> \begin{code} 𝒦ᶠ A = Σ[ xs ⦂ 𝒦 A ] ((x : A) → x ∈ xs) \end{code} %</kuratowski-finite-def> \begin{code} 𝒦ᶠ⇒∥ℰ∥ : 𝒦ᶠ A → ∥ ℰ A ∥ 𝒦ᶠ⇒∥ℰ∥ K = map₂ (λ p x → p x (K .snd x)) ∥$∥ ∥ enum ∥⇓ (K .fst) where enum : xs ∈𝒦 A ⇒∥ ∥ Σ[ ys ⦂ List A ] (∀ x → x ∈ xs → ∥ x L∈ ys ∥) ∥ ∥ ∥ enum ∥-prop = squash ∥ enum ∥[] = ∣ [] , (λ _ ()) ∣ ∥ enum ∥ x ∷ xs ⟨ Pxs ⟩ = cons ∥$∥ Pxs where cons : _ cons (ys , p) .fst = x ∷ ys cons (ys , p) .snd z zs = zs >>= either′ (∣_∣ ∘ (f0 ,_)) ((push ∥$∥_) ∘ p z) open import Algebra.Construct.Free.Semilattice.Extensionality open import Algebra.Construct.Free.Semilattice.FromList open import Data.Sigma.Properties isProp𝒦ᶠ : isProp (𝒦ᶠ A) isProp𝒦ᶠ Kˣ Kʸ = ΣProp≡ (λ K p q i x → isProp-◇ {xs = K} (p x) (q x) i) {Kˣ} {Kʸ} (extensional (fst Kˣ) (fst Kʸ) λ x → const (Kʸ .snd x) iff const (Kˣ .snd x)) ℰ⇒𝒦 : ℰ A → 𝒦ᶠ A ℰ⇒𝒦 E .fst = fromList (E .fst) ℰ⇒𝒦 E .snd x = ∈List⇒∈𝒦 (E .fst) (E .snd x) open import Cubical.HITs.S1 using (S¹) 𝒦ᶠ⟨S¹⟩ : 𝒦ᶠ S¹ 𝒦ᶠ⟨S¹⟩ = ℰ⇒𝒦 ℰ⟨S¹⟩ ∥ℰ∥⇔𝒦 : \end{code} %<*manifest-enum-kuratowski> \begin{code} ∥ ℰ A ∥ ⇔ 𝒦ᶠ A \end{code} %</manifest-enum-kuratowski> \begin{code} ∥ℰ∥⇔𝒦 .fun = PropTrunc.rec isProp𝒦ᶠ ℰ⇒𝒦 ∥ℰ∥⇔𝒦 .inv = 𝒦ᶠ⇒∥ℰ∥ ∥ℰ∥⇔𝒦 .leftInv x = squash _ x ∥ℰ∥⇔𝒦 .rightInv x = isProp𝒦ᶠ _ x open import Cardinality.Finite.Cardinal using (𝒞; 𝒞⇒Discrete) open import Cardinality.Finite.ManifestBishop using (ℬ⇒ℰ!; ℰ!⇒ℬ) open import Cardinality.Finite.ManifestEnumerable using (ℰ!⇒ℰ; ℰ⇒ℰ!) open import Relation.Nullary.Discrete.Properties 𝒞⇔𝒦×Discrete : \end{code} %<*card-iso-kuratowski> \begin{code} 𝒞 A ⇔ 𝒦ᶠ A × Discrete A \end{code} %</card-iso-kuratowski> \begin{code} 𝒞⇔𝒦×Discrete .fun ca .fst = ∥ℰ∥⇔𝒦 .fun (ℰ!⇒ℰ ∘ ℬ⇒ℰ! ∥$∥ ca) 𝒞⇔𝒦×Discrete .fun ca .snd = 𝒞⇒Discrete ca 𝒞⇔𝒦×Discrete .inv (ka , d) = ℰ!⇒ℬ ∘ ℰ⇒ℰ! d ∥$∥ ∥ℰ∥⇔𝒦 .inv ka 𝒞⇔𝒦×Discrete .rightInv _ = isOfHLevelΣ 1 isProp𝒦ᶠ (λ _ → isPropDiscrete) _ _ 𝒞⇔𝒦×Discrete .leftInv _ = squash _ _ open import Relation.Nullary.Decidable.Properties open import Relation.Nullary.Omniscience open import HITs.PropositionalTruncation.Properties private variable p : Level 𝒦ᶠ⇒Exhaustible : 𝒦ᶠ A → Exhaustible p A 𝒦ᶠ⇒Exhaustible K P? = ∣ ◻? P? (K .fst) ∣yes⇒ (λ ◻Pxs x → recompute (P? x) (P∈◇ x (K .fst) (K .snd x) ◻Pxs)) ∣no⇒ λ ¬◻Pxs ∀P → ¬◻Pxs (map-◻ ∀P (K .fst)) \end{code} %<*kuratowski-prop-omniscient> \begin{code} 𝒦ᶠ⇒Prop-Omniscient : 𝒦ᶠ A → Prop-Omniscient p A 𝒦ᶠ⇒Prop-Omniscient K P? = PropTrunc.rec (isPropDec squash) (map-dec ∣_∣ refute-trunc ∘ λ xs → ℰ⇒Omniscient xs P?) (𝒦ᶠ⇒∥ℰ∥ K) \end{code} %</kuratowski-prop-omniscient>