{-# OPTIONS --safe #-}
module Finite.OnLists where
open import Prelude
open import Data.List
open import Data.List.Membership
ℰ! : Type a → Type a
ℰ! A = Σ[ xs ⦂ List A ] × (∀ x → x ∈ xs)
sup-Σ : List A →
((x : A) → List (P x)) →
List (Σ A P)
sup-Σ xs ys = concatMap (λ x → mapl (x ,_) (ys x)) xs
cov-Σ : (x : A)
→ (y : P x)
→ (xs : List A)
→ (ys : ∀ x → List (P x))
→ x ∈ xs
→ y ∈ ys x
→ (x , y) ∈ sup-Σ xs ys
cov-Σ xᵢ yᵢ (x ∷ xs) ys (suc n , x∈xs) y∈ys =
mapl (x ,_) (ys x) ++◇ cov-Σ xᵢ yᵢ xs ys (n , x∈xs) y∈ys
cov-Σ xᵢ yᵢ (x ∷ xs) ys (zero , x∈xs) y∈ys =
subst (λ x′ → (xᵢ , yᵢ) ∈ sup-Σ (x′ ∷ xs) ys) (sym x∈xs)
(mapl (xᵢ ,_) (ys xᵢ) ◇++ cong-∈ _ (ys xᵢ) y∈ys)
_|Σ|_ : ℰ! A → (∀ x → ℰ! (P x)) → ℰ! (Σ A P)
(xs |Σ| ys) .fst = sup-Σ (xs .fst) (fst ∘′ ys)
(xs |Σ| ys) .snd (x , y) = cov-Σ x y (xs .fst) (fst ∘′ ys) (xs .snd x) (ys x .snd y)
ℬ : Type a → Type a
ℬ A = Σ[ xs ⦂ List A ] × ∀ x → x ∈! xs
ℰ!⇒Discrete : ℰ! A → Discrete A
ℰ!⇒Discrete e x y with e .snd x | inspect (e .snd) x | e .snd y | inspect (e .snd) y
... | i , p | 〖 ex 〗 | j , q | 〖 ey 〗 with discreteFin i j
... | yes i≡j = yes (sym p ; cong (e .fst !!_) i≡j ; q)
... | no i≢j = no λ x≡y → i≢j (cong fst (sym ex) ; cong (fst ∘′ e .snd) x≡y ; cong fst ey)
ℰ!⇒ℬ : ℰ! A → ℬ A
ℰ!⇒ℬ xs = λ where
.fst → uniques disc (xs .fst)
.snd x → ∈⇒∈! disc x (xs .fst) (xs .snd x)
where
disc = ℰ!⇒Discrete xs
ℱ : Type a → Type a
ℱ A = ∃ n × (Fin n ≃ A)
ℬ→ℱ : ℬ A → ℱ A
ℬ→ℱ (xs , f) .fst = length xs
ℬ→ℱ (xs , f) .snd .fst = xs !!_
ℬ→ℱ (xs , f) .snd .snd .equiv-proof = f