\begin{code}
{-# OPTIONS --cubical --safe --postfix-projections #-}
module Cardinality.Finite.ManifestBishop where
open import Prelude hiding (_≃_; isEquiv)
import Cardinality.Finite.ManifestBishop.Inductive as 𝕃
import Cardinality.Finite.ManifestBishop.Container as ℒ
open import Cardinality.Finite.ManifestBishop.Isomorphism
open import Data.Fin
private
variable
u : Level
U : A → Type u
private
module DisplayBishEquiv {a} {A : Type a} where
open ℒ
open import Snippets.Equivalence
open import Container
open import Container.List
open import Data.Sigma.Properties
open import Relation.Binary.Equivalence.Reasoning (⇔-equiv {a}) public
ℬ⇔Fin≃ :
\end{code}
%<*bishop-is-equiv-type>
\begin{code}
ℬ A ⇔ ∃[ n ] (Fin n ≃ A)
\end{code}
%</bishop-is-equiv-type>
\begin{code}
ℬ⇔Fin≃ =
\end{code}
%<*bishop-is-equiv>
\begin{code}
ℬ A ≋⟨⟩
Σ[ xs ⦂ List A ] ((x : A) → x ∈! xs) ≋⟨⟩
Σ[ xs ⦂ List A ] ((x : A) → isContr (x ∈ xs)) ≋⟨⟩
Σ[ xs ⦂ List A ] ((x : A) → isContr (fiber (snd xs) x)) ≋⟨⟩
Σ[ xs ⦂ List A ] isEquiv (snd xs) ≋⟨⟩
Σ[ xs ⦂ ⟦ ℕ , Fin ⟧ A ] isEquiv (snd xs) ≋⟨⟩
Σ[ xs ⦂ Σ[ n ⦂ ℕ ] (Fin n → A) ] isEquiv (snd xs) ≋⟨ reassoc ⟩
Σ[ n ⦂ ℕ ] Σ[ f ⦂ (Fin n → A) ] isEquiv f ≋⟨⟩
∃[ n ] (Fin n ≃ A) ∎
\end{code}
%</bishop-is-equiv>
\begin{code}
open import Prelude using (_≃_; isEquiv)
module _ where
open ℒ
ℬ⇔Fin≃ : ℬ A ⇔ ∃[ n ] (Fin n ≃ A)
ℬ⇔Fin≃ .fun ((n , xs) , cov) .fst = n
ℬ⇔Fin≃ .fun ((n , xs) , cov) .snd .fst = xs
ℬ⇔Fin≃ .fun ((n , xs) , cov) .snd .snd .equiv-proof = cov
ℬ⇔Fin≃ .inv (n , (xs , cov)) = ((n , xs) , cov .equiv-proof)
ℬ⇔Fin≃ .rightInv (n , (xs , cov)) i .fst = n
ℬ⇔Fin≃ .rightInv (n , (xs , cov)) i .snd .fst = xs
ℬ⇔Fin≃ .rightInv (n , (xs , cov)) i .snd .snd .equiv-proof = cov .equiv-proof
ℬ⇔Fin≃ .leftInv _ = refl
module _ where
open 𝕃
open import Cardinality.Finite.SplitEnumerable hiding (_|×|_; ℰ!⟨Tuple⟩)
import Cardinality.Finite.SplitEnumerable as SplitEnumerable
open import Cardinality.Finite.SplitEnumerable.Inductive
open import Cardinality.Finite.SplitEnumerable.Isomorphism
ℬ⇒ℰ! : ℬ A → ℰ! A
ℬ⇒ℰ! xs .fst = xs .fst
ℬ⇒ℰ! xs .snd x = xs .snd x .fst
ℬ⇒Discrete : ℬ A → Discrete A
ℬ⇒Discrete = ℰ!⇒Discrete ∘ fun 𝕃⇔ℒ⟨ℰ!⟩ ∘ ℬ⇒ℰ!
module SplitEnumToBishop where
ℰ!⇒ℬ : ℰ! A → ℬ A
ℰ!⇒ℬ xs = λ where
.fst → uniques disc (xs .fst)
.snd x → ∈⇒∈! disc x (xs .fst) (xs .snd x)
where
disc = ℰ!⇒Discrete (𝕃⇔ℒ⟨ℰ!⟩ .fun xs)
ℬ⇒Fin≃ : ℬ A → ∃[ n ] (Fin n ≃ A)
ℬ⇒Fin≃ = ℬ⇔Fin≃ .fun ∘ 𝕃⇔ℒ⟨ℬ⟩ .fun
private
module PiClosNoPoly {A : Type₀} {U : A → Type₀} where
open import Data.Tuple.UniverseMonomorphic
open TupleUniverseMonomorphic
ℰ!⇒ℬ : ℰ! B → _
ℰ!⇒ℬ = 𝕃⇔ℒ⟨ℬ⟩ .fun ∘ SplitEnumToBishop.ℰ!⇒ℬ
_|Π|_ : ℰ! A → ((x : A) → ℰ! (U x)) → ℰ! ((x : A) → U x)
_|Π|_ xs =
subst
(λ t → {A : t → Type _} → ((x : t) → ℰ! (A x)) → ℰ! ((x : t) → (A x)))
(ua (ℬ⇔Fin≃ .fun (ℰ!⇒ℬ xs) .snd))
(subst ℰ! (isoToPath Tuple⇔ΠFin) ∘ ℰ!⟨Tuple⟩)
open SplitEnumToBishop public
isoLift : Lift b A ⇔ A
isoLift = iso lower lift (λ _ → refl) λ _ → refl
open import Data.Tuple
module _ {a} {u} {A : Type a} {U : A → Type u} where
\end{code}
%<*pi-clos>
\begin{code}
_|Π|_ : ℰ! A → ((x : A) → ℰ! (U x)) → ℰ! ((x : A) → U x)
\end{code}
%</pi-clos>
\begin{code}
_|Π|_ xs =
subst
(λ t → {A : t → Type _} → ((x : t) → ℰ! (A x)) → ℰ! ((x : t) → (A x)))
(ua (isoToEquiv isoLift ⟨ trans-≃ ⟩ ℬ⇔Fin≃ .fun (𝕃⇔ℒ⟨ℬ⟩ .fun (ℰ!⇒ℬ xs)) .snd))
(subst ℰ! (isoToPath (isoLift {b = a} ⟨ trans-⇔ ⟩ Tuple⇔ΠFin)) ∘ ℰ!⟨Lift⟩ ∘ SplitEnumerable.ℰ!⟨Tuple⟩)
open import HITs.PropositionalTruncation.Sugar
ℬ⇒Choice : ℬ A → ((x : A) → ∥ U x ∥) → ∥ (∀ x → U x) ∥
ℬ⇒Choice ba =
subst
(λ t → {U : t → Type _} → ((x : t) → ∥ U x ∥) → ∥ ((x : t) → U x) ∥)
(ua (isoToEquiv isoLift ⟨ trans-≃ ⟩ ℬ⇔Fin≃ .fun (𝕃⇔ℒ⟨ℬ⟩ .fun ba) .snd))
((ind ∥$∥_) ∘ trav _ ∘ tab)
where
trav : ∀ n {T : Lift a (Fin n) → Type b} → Tuple n (∥_∥ ∘ T) → ∥ Tuple n T ∥
trav zero xs = ∣ _ ∣
trav (suc n) (x , xs) = do
x′ ← x
xs′ ← trav n xs
∣ x′ , xs′ ∣
module BishopClosures where
\end{code}
%<*times-clos-sig>
\begin{code}
_|×|_ : ℬ A →
ℬ B →
ℬ (A × B)
\end{code}
%</times-clos-sig>
\begin{code}
xs |×| ys = ℰ!⇒ℬ (ℬ⇒ℰ! xs SplitEnumerable.|×| ℬ⇒ℰ! ys)
\end{code}
\begin{code}
open import Cubical.Foundations.HLevels
open import Relation.Nullary.Decidable.Logic
_|→|_ : ℬ A → ℬ B → ℬ (A → B)
xs |→| ys = ℰ!⇒ℬ (ℬ⇒ℰ! xs |Π| λ _ → ℬ⇒ℰ! ys)
filter : ∀ {p} {P : A → Type p} → (∀ x → isProp (P x)) → (∀ x → Dec (P x)) → ℬ A → ℬ (Σ[ x ⦂ A ] P x)
filter isPropP P? = ℰ!⇒ℬ ∘ filter-subobject isPropP P? ∘ ℬ⇒ℰ!
module _ {a} {b} {A : Type a} {B : Type b} where
\end{code}
%<*iso-finite>
\begin{code}
iso-finite : ℬ A →
ℬ B →
ℬ (Σ[ f,g ⦂ (A → B) × (B → A) ]
( (f,g .fst ∘ f,g .snd ≡ id) ×
(f,g .snd ∘ f,g .fst ≡ id)))
iso-finite ℬ⟨A⟩ ℬ⟨B⟩ =
filter
(λ _ → isPropEqs)
(λ { (f , g) → (f ∘ g) ≟ᴮ id && (g ∘ f) ≟ᴬ id})
((ℬ⟨A⟩ |→| ℬ⟨B⟩) |×| (ℬ⟨B⟩ |→| ℬ⟨A⟩))
\end{code}
%</iso-finite>
\begin{code}
where
ℬ⟨f⟩ : ℬ (A → B)
ℬ⟨f⟩ = (ℬ⟨A⟩ |→| ℬ⟨B⟩)
ℬ⟨g⟩ : ℬ (B → A)
ℬ⟨g⟩ = (ℬ⟨B⟩ |→| ℬ⟨A⟩)
_≟ᴮ_ = ℬ⇒Discrete (ℬ⟨B⟩ |→| ℬ⟨B⟩)
_≟ᴬ_ = ℬ⇒Discrete (ℬ⟨A⟩ |→| ℬ⟨A⟩)
isPropEqs : {g : A → A} {f : B → B} → isProp ((f ≡ id) × (g ≡ id))
isPropEqs = isOfHLevelΣ 1 (Discrete→isSet _≟ᴮ_ _ _) λ _ → (Discrete→isSet _≟ᴬ_ _ _)
_|⇔|_ : ℬ A → ℬ B → ℬ (A ⇔ B)
xs |⇔| ys = subst ℬ (isoToPath form) (iso-finite xs ys)
where
form : (Σ[ fg ⦂ ((A → B) × (B → A)) ] (((fg .fst ∘ fg .snd) ≡ id) × ((fg .snd ∘ fg .fst) ≡ id))) ⇔ (A ⇔ B)
form .fun ((f , g) , (leftInv , rightInv)) = iso f g (λ x i → leftInv i x) (λ x i → rightInv i x)
form .inv (iso f g leftInv rightInv) = ((f , g) , ((λ i x → leftInv x i) , (λ i x → rightInv x i)))
form .rightInv _ = refl
form .leftInv _ = refl
private
module DecTerm (f : A → B) (g : B → A) where
decTerm : Type _
decTerm =
\end{code}
%<*dec-type>
\begin{code}
Dec (f ∘ g ≡ id)
\end{code}
%</dec-type>