{-# OPTIONS --cubical --exact-split #-}
module FMSetUniv where
open import Cubical.Foundations.Everything
import Cubical.Data.Empty as ⊥
import Cubical.Functions.Logic as L
open import Cubical.HITs.FiniteMultiset
open import Cubical.Data.Unit.Base
open import Cubical.Data.Nat
open import Cubical.Data.FinSet
open import Cubical.Relation.Nullary
open import Cubical.HITs.PropositionalTruncation as P
open import Cubical.Data.Sum as S
open import Cubical.Data.Unit as ⊤
open import Cubical.Data.Sigma
postulate
TODO : ∀ {ℓ} {A : Type ℓ} → A
module _ {n : Level} where
⊥* : hProp n
⊥* = ⊥.⊥* , \{ () }
⊔-identityˡ* : (P : hProp n) → ⊥* L.⊔ P ≡ P
⊔-identityˡ* P = L.⇒∶ (L.⊔-elim ⊥* P (λ _ → P) (λ ()) (λ x → x))
⇐∶ L.inr
module _ {n : Level} {A : Type n} {isDiscA : Discrete A} where
decElim : ∀ {ℓ ℓ'} {P : Type ℓ} {A : Dec P → Type ℓ'} → ((p : P) → A (yes p)) → ((q : ¬ P) → A (no q)) → (p : Dec P) → A p
decElim ifyes ifno (yes p) = ifyes p
decElim ifyes ifno (no ¬p) = ifno ¬p
isDiscA-β-yes : (a x : A) (p : a ≡ x) -> isDiscA a x ≡ yes p
isDiscA-β-yes a x p =
decElim {A = \d -> d ≡ yes p}
(\q -> congS yes (Discrete→isSet isDiscA a x q p))
(\q -> ⊥.rec (q p))
(isDiscA a x)
isDiscA-β-refl : (x : A) -> isDiscA x x ≡ yes refl
isDiscA-β-refl x = isDiscA-β-yes x x refl
isDiscA-β-no : (a x : A) (p : ¬ (a ≡ x)) -> isDiscA a x ≡ no p
isDiscA-β-no a x p =
decElim {A = \d -> d ≡ no p}
(\q -> ⊥.rec (p q))
(\q -> congS no (isProp→ ⊥.isProp⊥ q p))
(isDiscA a x)
module Mem {n : Level} {A : Type n} {isSetA : isSet A} (x : A) where
private
よ : A → hProp n
よ a = (a ≡ x) , isSetA a x
module mem = FMSetUniversal isSetHProp ⊥* L._⊔_ L.⊔-comm L.⊔-assoc ⊔-identityˡ* よ
opaque
_∈_ : FMSet A → hProp n
_∈_ = mem.f-extend
module Length {n : Level} {A : Type n} where
private
module 1♯ = FMSetUniversal {A = A} isSetℕ 0 _+_ +-comm +-assoc (\_ -> refl) (\_ -> 1)
opaque
length : FMSet A -> ℕ
length = 1♯.f-extend
length-[] : length [] ≡ 0
length-[] = 1♯.f-extend-nil
length-∷ : ∀ {x xs} -> length (x ∷ xs) ≡ 1 + length xs
length-∷ {x = x} {xs = xs} = 1♯.f-extend-cons x xs
length-++ : ∀ {xs ys} -> length (xs ++ ys) ≡ length xs + length ys
length-++ {xs = xs} {ys = ys} = 1♯.f-extend-++ xs ys
length-0 : ∀ {xs} -> length xs ≡ 0 -> xs ≡ []
length-0 {xs = xs} =
ElimProp.f {B = \xs -> length xs ≡ 0 -> xs ≡ []}
(isProp→ (trunc _ _)) (\_ -> refl) (\x {xs} f p -> ⊥.rec (snotz (sym (length-∷ {x = x} {xs = xs}) ∙ p))) xs
module Count {n : Level} {A : Type n} {isDiscA : Discrete A} (x : A) where
private
Χ : A → ℕ
Χ a = decRec (\_ -> 1) (\_ -> 0) (isDiscA a x)
Χ-β : Χ x ≡ 1
Χ-β = congS (decRec _ _) (isDiscA-β-refl {isDiscA = isDiscA} x)
module count = FMSetUniversal isSetℕ 0 _+_ +-comm +-assoc (\_ -> refl) Χ
opaque
_∈ᵐ_ : FMSet A → ℕ
_∈ᵐ_ = count.f-extend
∈ᵐ-[] : (_∈ᵐ_ []) ≡ 0
∈ᵐ-[] = count.f-extend-nil
∈ᵐ-∷ : ∀ {xs} -> (_∈ᵐ_ (x ∷ xs)) ≡ 1 + _∈ᵐ_ xs
∈ᵐ-∷ {xs = xs} = let q = count.f-extend-cons x xs in q ∙ congS (_+ _∈ᵐ_ xs) Χ-β
∈ᵐ-++ : ∀ {xs ys} -> (_∈ᵐ_ (xs ++ ys)) ≡ (_∈ᵐ_ xs) + (_∈ᵐ_ ys)
∈ᵐ-++ {xs = xs} {ys = ys} = let q = count.f-extend-++ xs ys in q
module Remove {n : Level} {A : Type n} {isDiscA : Discrete A} (x : A) where
private
r : A -> FMSet A
r a = decRec (\_ -> []) (\_ -> [ a ]) (isDiscA a x)
module rem = FMSetUniversal {A = A} trunc [] _++_ comm-++ assoc-++ unitl-++ r
rem : FMSet A → FMSet A
rem = rem.f-extend
_ : Remove.rem {isDiscA = discreteℕ} 2 (1 ∷ 2 ∷ 3 ∷ 2 ∷ []) ≡ (1 ∷ 3 ∷ [])
_ = refl
module _ {n : Level} (A : Type n) where
supp : (A -> ℕ) -> Type n
supp f = Σ[ a ∈ A ] ¬ (f a ≡ 0)
FMultiSet : Type n
FMultiSet = Σ[ f ∈ (A -> ℕ) ] isFinSet (supp f)