{-# OPTIONS --without-K #-}
module sets.fin.universe where
open import sum
open import decidable
open import equality.core
open import equality.calculus
open import equality.inspect
open import function.isomorphism
open import function.core
open import function.extensionality
open import function.fibration
open import function.overloading
open import sets.core
open import sets.properties
open import sets.nat.core
hiding (_≟_)
open import sets.nat.ordering
hiding (compare)
open import sets.fin.core
open import sets.fin.ordering
open import sets.fin.properties
open import sets.unit
open import sets.empty
open import sets.bool
open import sets.vec.dependent
open import hott.level.core
open import hott.level.closure
open import hott.level.sets
fin-struct-iso : ∀ {n} → Fin (suc n) ≅ (⊤ ⊎ Fin n)
fin-struct-iso = record
{ to = λ { zero → inj₁ tt; (suc i) → inj₂ i }
; from = [ (λ _ → zero) ,⊎ (suc) ]
; iso₁ = λ { zero → refl ; (suc i) → refl }
; iso₂ = λ { (inj₁ _) → refl; (inj₂ i) → refl } }
fin0-empty : ⊥ ≅ Fin 0
fin0-empty = sym≅ (empty-⊥-iso (λ ()))
fin1-unit : ⊤ ≅ Fin 1
fin1-unit = record
{ to = λ _ → zero
; from = λ { zero → tt ; (suc ()) }
; iso₁ = λ _ → refl
; iso₂ = λ { zero → refl ; (suc ()) } }
fin2-bool : Bool ≅ Fin 2
fin2-bool = record
{ to = λ b → if b then # 0 else # 1
; from = true ∷∷ false ∷∷ ⟦⟧
; iso₁ = λ { true → refl ; false → refl }
; iso₂ = refl ∷∷ refl ∷∷ ⟦⟧ }
fin-sum : ∀ {n m} → (Fin n ⊎ Fin m) ≅ Fin (n + m)
fin-sum {0} = record
{ to = λ { (inj₁ ()) ; (inj₂ j) → j }
; from = λ { j → inj₂ j }
; iso₁ = λ { (inj₁ ()); (inj₂ j) → refl }
; iso₂ = λ _ → refl }
fin-sum {suc n}{m} = begin
(Fin (suc n) ⊎ Fin m)
≅⟨ ⊎-ap-iso fin-struct-iso refl≅ ⟩
((⊤ ⊎ Fin n) ⊎ Fin m)
≅⟨ ⊎-assoc-iso ⟩
(⊤ ⊎ (Fin n ⊎ Fin m))
≅⟨ ⊎-ap-iso refl≅ fin-sum ⟩
(⊤ ⊎ Fin (n + m))
≅⟨ sym≅ fin-struct-iso ⟩
Fin (suc (n + m))
∎
where open ≅-Reasoning
fin-prod : ∀ {n m} → (Fin n × Fin m) ≅ Fin (n * m)
fin-prod {0} = iso (λ { (() , _) }) (λ ()) (λ { (() , _) }) (λ ())
fin-prod {suc n}{m} = begin
(Fin (suc n) × Fin m)
≅⟨ ×-ap-iso fin-struct-iso refl≅ ⟩
((⊤ ⊎ Fin n) × Fin m)
≅⟨ ⊎×-distr-iso ⟩
((⊤ × Fin m) ⊎ (Fin n × Fin m))
≅⟨ ⊎-ap-iso ×-left-unit fin-prod ⟩
(Fin m ⊎ (Fin (n * m)))
≅⟨ fin-sum ⟩
(Fin (m + (n * m)))
≡⟨ refl ⟩
Fin (suc n * m)
∎
where open ≅-Reasoning
fin-exp : ∀ {n m} → (Fin n → Fin m) ≅ Fin (m ^ n)
fin-exp {0} = record
{ to = λ f → zero
; from = (λ ()) ∷∷ ⟦⟧
; iso₁ = λ f → funext λ ()
; iso₂ = refl ∷∷ ⟦⟧ }
fin-exp {suc n}{m} = begin
(Fin (suc n) → Fin m)
≅⟨ (Π-ap-iso fin-struct-iso λ _ → refl≅) ⟩
((⊤ ⊎ Fin n) → Fin m)
≅⟨ iso (λ f → f (inj₁ tt) , f ∘' inj₂)
(λ { (i , _) (inj₁ _) → i
; (_ , g) (inj₂ i) → g i })
(λ f → funext λ { (inj₁ tt) → refl
; (inj₂ i) → refl })
(λ { (i , g) → refl }) ⟩
(Fin m × (Fin n → Fin m))
≅⟨ ×-ap-iso refl≅ fin-exp ⟩
(Fin m × Fin (m ^ n))
≅⟨ fin-prod ⟩
Fin (m ^ (suc n))
∎
where open ≅-Reasoning
factorial : ℕ → ℕ
factorial 0 = 1
factorial (suc n) = suc n * factorial n
fin-inj-iso : ∀ {n} → (Fin n ≅ Fin n) ≅ (Fin n ↣ Fin n)
fin-inj-iso {n} = record
{ to = λ f → (apply f , iso⇒inj f)
; from = λ { (f , inj) → inj⇒iso f inj }
; iso₁ = λ f → iso-eq-h2 (fin-set n) (fin-set n) refl
; iso₂ = λ { (f , inj) → inj-eq-h2 (fin-set n) refl } }
fin-iso-iso : ∀ {n} → (Fin n ↣ Fin n) ≅ Fin (factorial n)
fin-iso-iso {0} = record
{ to = λ { (f , _) → zero }
; from = λ _ → (λ ()) , (λ { {()} p })
; iso₁ = λ { (f , _) → inj-eq-h2 (fin-set _) (funext λ ()) }
; iso₂ = λ { zero → refl ; (suc ()) } }
fin-iso-iso {suc n} = begin
(X ↣ X)
≅⟨ sym≅ (total-iso classify) ⟩
(Σ X λ i → classify ⁻¹ i)
≅⟨ (Σ-ap-iso₂ λ i → trans≅ (sym≅ (const-fibre i)) fibre-zero-iso) ⟩
(Fin (suc n) × (Fin n ↣ Fin n))
≅⟨ ×-ap-iso refl≅ fin-iso-iso ⟩
(Fin (suc n) × Fin (factorial n))
≅⟨ fin-prod ⟩
Fin (factorial (suc n))
∎
where
X = Fin (suc n)
open ≅-Reasoning
classify : (X ↣ X) → X
classify (f , _) = f zero
const-fibre : (i : X) → classify ⁻¹ zero ≅ classify ⁻¹ i
const-fibre i = begin
( Σ (X ↣ X) λ { (f , _) → f zero ≡ zero } )
≅⟨ ( Σ-ap-iso (transpose-inj-iso' zero i) (λ { (f , inj)
→ mk-prop-iso (fin-set _ _ _) (fin-set _ _ _)
(ap (transpose zero i)) (u f) }) ) ⟩
( Σ (X ↣ X) λ { (f , _) → f zero ≡ i } )
∎
where
u : (f : X → X)
→ transpose zero i (f zero) ≡ i
→ f zero ≡ zero
u f p = sym (_≅_.iso₁ (transpose-iso zero i) (f zero))
· (ap (transpose zero i) p
· transpose-β₂ zero i)
fibre-zero-iso : classify ⁻¹ zero ≅ (Fin n ↣ Fin n)
fibre-zero-iso = record
{ to = λ { (f , z) → fin-inj-remove₀ f z }
; from = λ { g → fin-inj-add g , refl }
; iso₁ = λ { (f , p)
→ unapΣ (inj-eq-h2 (fin-set (suc n))
(funext (α f p ))
, h1⇒prop (fin-set (suc n) _ _) _ _) }
; iso₂ = λ g → inj-eq-h2 (fin-set n) refl }
where
α : (f : Fin (suc n) ↣ Fin (suc n))
→ (p : apply f zero ≡ zero)
→ (i : Fin (suc n))
→ apply (fin-inj-add (fin-inj-remove₀ f p)) i
≡ apply f i
α _ p zero = sym p
α (f , f-inj) p (suc i) = pred-β (f (suc i))
(λ q → fin-disj _ (f-inj (p · sym q)))
fin-subsets : ∀ {n} → (Fin n → Bool) ≅ Fin (2 ^ n)
fin-subsets = trans≅ (Π-ap-iso refl≅ λ _ → fin2-bool) fin-exp