{-# OPTIONS --cubical --safe #-}
module Data.Bag where
open import Prelude
open import Algebra
open import Path.Reasoning
infixr 5 _∷_
data ⟅_⟆ (A : Type a) : Type a where
[] : ⟅ A ⟆
_∷_ : A → ⟅ A ⟆ → ⟅ A ⟆
com : ∀ x y xs → x ∷ y ∷ xs ≡ y ∷ x ∷ xs
trunc : isSet ⟅ A ⟆
record Elim {a ℓ}
(A : Type a)
(P : ⟅ A ⟆ → Type ℓ)
: Type (a ℓ⊔ ℓ) where
constructor elim
field
⟅_⟆-set : ∀ {xs} → isSet (P xs)
⟅_⟆[] : P []
⟅_⟆_∷_⟨_⟩ : ∀ x xs → P xs → P (x ∷ xs)
private z = ⟅_⟆[]; f = ⟅_⟆_∷_⟨_⟩
field
⟅_⟆-com : (∀ x y xs pxs →
PathP (λ i → P (com x y xs i))
(f x (y ∷ xs) (f y xs pxs))
(f y (x ∷ xs) (f x xs pxs)))
⟅_⟆⇓ : (xs : ⟅ A ⟆) → P xs
⟅ [] ⟆⇓ = z
⟅ x ∷ xs ⟆⇓ = f x xs ⟅ xs ⟆⇓
⟅ com x y xs i ⟆⇓ = ⟅_⟆-com x y xs ⟅ xs ⟆⇓ i
⟅ trunc xs ys x y i j ⟆⇓ =
isOfHLevel→isOfHLevelDep 2
(λ xs → ⟅_⟆-set {xs})
⟅ xs ⟆⇓ ⟅ ys ⟆⇓
(cong ⟅_⟆⇓ x) (cong ⟅_⟆⇓ y)
(trunc xs ys x y)
i j
open Elim
infixr 0 elim-syntax
elim-syntax : ∀ {a ℓ}
→ (A : Type a)
→ (⟅ A ⟆ → Type ℓ)
→ Type (a ℓ⊔ ℓ)
elim-syntax = Elim
syntax elim-syntax A (λ xs → Pxs) = xs ⦂⟅ A ⟆→ Pxs
record ElimProp {a ℓ} (A : Type a) (P : ⟅ A ⟆ → Type ℓ) : Type (a ℓ⊔ ℓ) where
constructor elim-prop
field
⟦_⟧-prop : ∀ {xs} → isProp (P xs)
⟦_⟧[] : P []
⟦_⟧_∷_⟨_⟩ : ∀ x xs → P xs → P (x ∷ xs)
private z = ⟦_⟧[]; f = ⟦_⟧_∷_⟨_⟩
⟦_⟧⇑ = elim
(isProp→isSet ⟦_⟧-prop)
z f
(λ x y xs pxs → toPathP (⟦_⟧-prop (transp (λ i → P (com x y xs i)) i0
(f x (y ∷ xs) (f y xs pxs))) (f y (x ∷ xs) (f x xs pxs))))
⟦_⟧⇓ = ⟅ ⟦_⟧⇑ ⟆⇓
open ElimProp
infixr 0 elim-prop-syntax
elim-prop-syntax : ∀ {a ℓ} → (A : Type a) → (⟅ A ⟆ → Type ℓ) → Type (a ℓ⊔ ℓ)
elim-prop-syntax = ElimProp
syntax elim-prop-syntax A (λ xs → Pxs) = xs ⦂⟅ A ⟆→∥ Pxs ∥
record [⟅_⟆→_] {a b} (A : Type a) (B : Type b) : Type (a ℓ⊔ b) where
constructor rec
field
[_]-set : isSet B
[_]_∷_ : A → B → B
[_][] : B
private f = [_]_∷_; z = [_][]
field
[_]-com : ∀ x y xs → f x (f y xs) ≡ f y (f x xs)
[_]⇑ = elim [_]-set z (λ x _ → f x) (λ x y _ → [_]-com x y)
[_]↓ = ⟅ [_]⇑ ⟆⇓
open [⟅_⟆→_]
infixr 5 _∪_
_∪_ : ⟅ A ⟆ → ⟅ A ⟆ → ⟅ A ⟆
_∪_ = λ xs ys → [ ys ∪′ ]↓ xs
where
_∪′ : ⟅ A ⟆ → [⟅ A ⟆→ ⟅ A ⟆ ]
[ ys ∪′ ]-set = trunc
[ ys ∪′ ] x ∷ xs = x ∷ xs
[ ys ∪′ ][] = ys
[ ys ∪′ ]-com = com
∪-assoc : (xs ys zs : ⟅ A ⟆) →
(xs ∪ ys) ∪ zs ≡ xs ∪ (ys ∪ zs)
∪-assoc = λ xs ys zs → ⟦ ∪-assoc′ ys zs ⟧⇓ xs
where
∪-assoc′ : ∀ ys zs →
xs ⦂⟅ A ⟆→∥ (xs ∪ ys) ∪ zs ≡ xs ∪ (ys ∪ zs) ∥
⟦ ∪-assoc′ ys zs ⟧-prop = trunc _ _
⟦ ∪-assoc′ ys zs ⟧[] = refl
⟦ ∪-assoc′ ys zs ⟧ x ∷ xs ⟨ P ⟩ = cong (x ∷_) P
∪-cons : ∀ (x : A) xs ys
→ (x ∷ xs) ∪ ys ≡ xs ∪ (x ∷ ys)
∪-cons = λ x xs ys → ⟦ ∪-cons′ x ys ⟧⇓ xs
where
∪-cons′ : ∀ x ys →
xs ⦂⟅ A ⟆→∥ (x ∷ xs) ∪ ys ≡ xs ∪ (x ∷ ys) ∥
⟦ ∪-cons′ x ys ⟧-prop = trunc _ _
⟦ ∪-cons′ x ys ⟧[] = refl
⟦ ∪-cons′ x ys ⟧ y ∷ xs ⟨ P ⟩ = cong (_∪ ys) (com x y xs) ; cong (y ∷_) P
∪-idʳ : (xs : ⟅ A ⟆) → xs ∪ [] ≡ xs
∪-idʳ = ⟦ ∪-idʳ′ ⟧⇓
where
∪-idʳ′ : xs ⦂⟅ A ⟆→∥ xs ∪ [] ≡ xs ∥
⟦ ∪-idʳ′ ⟧-prop = trunc _ _
⟦ ∪-idʳ′ ⟧[] = refl
⟦ ∪-idʳ′ ⟧ x ∷ xs ⟨ P ⟩ = cong (x ∷_) P
∪-comm : (xs ys : ⟅ A ⟆) → xs ∪ ys ≡ ys ∪ xs
∪-comm {A = A} = λ xs ys → ⟦ ∪-comm′ ys ⟧⇓ xs
where
∪-comm′ : (ys : ⟅ A ⟆) →
xs ⦂⟅ A ⟆→∥ xs ∪ ys ≡ ys ∪ xs ∥
⟦ ∪-comm′ ys ⟧-prop = trunc _ _
⟦ ∪-comm′ ys ⟧[] = sym (∪-idʳ ys)
⟦ ∪-comm′ ys ⟧ x ∷ xs ⟨ P ⟩ =
(x ∷ xs) ∪ ys ≡⟨ cong (x ∷_) P ⟩
(x ∷ ys) ∪ xs ≡⟨ ∪-cons x ys xs ⟩
ys ∪ x ∷ xs ∎
⟅⟆-commutative-monoid : ∀ {a} (A : Type a) → CommutativeMonoid ⟅ A ⟆
Monoid._∙_ (CommutativeMonoid.monoid (⟅⟆-commutative-monoid A)) = _∪_
Monoid.ε (CommutativeMonoid.monoid (⟅⟆-commutative-monoid A)) = []
Monoid.assoc (CommutativeMonoid.monoid (⟅⟆-commutative-monoid A)) = ∪-assoc
Monoid.ε∙ (CommutativeMonoid.monoid (⟅⟆-commutative-monoid A)) _ = refl
Monoid.∙ε (CommutativeMonoid.monoid (⟅⟆-commutative-monoid A)) = ∪-idʳ
CommutativeMonoid.comm (⟅⟆-commutative-monoid A) = ∪-comm
module _ {ℓ} {𝑆 : Type ℓ} (mon : CommutativeMonoid 𝑆) (sIsSet : isSet 𝑆) where
open CommutativeMonoid mon
⟦_⟧ : (A → 𝑆) → ⟅ A ⟆ → 𝑆
⟦_⟧ = λ h → [ ⟦ h ⟧′ ]↓
where
⟦_⟧′ : (A → 𝑆) → [⟅ A ⟆→ 𝑆 ]
[ ⟦ h ⟧′ ] x ∷ xs = h x ∙ xs
[ ⟦ h ⟧′ ][] = ε
[ ⟦ h ⟧′ ]-com x y xs =
h x ∙ (h y ∙ xs)
≡˘⟨ assoc _ _ _ ⟩
(h x ∙ h y) ∙ xs
≡⟨ cong (_∙ xs) (comm _ _) ⟩
(h y ∙ h x) ∙ xs
≡⟨ assoc _ _ _ ⟩
h y ∙ (h x ∙ xs) ∎
[ ⟦ h ⟧′ ]-set = sIsSet
record ⟦_≡_⟧ {a b} {A : Type a} {B : Type b}
(h : ⟅ A ⟆ → B)
(xf : [⟅ A ⟆→ B ])
: Type (a ℓ⊔ b) where
constructor elim-univ
field
⟦_≡⟧_∷_ : ∀ x xs → h (x ∷ xs) ≡ [ xf ] x ∷ h xs
⟦_≡⟧[] : h [] ≡ [ xf ][]
⟦_≡⟧⇓ : ∀ xs → h xs ≡ [ xf ]↓ xs
⟦_≡⟧⇓ = ⟦ ≡⇓′ ⟧⇓
where
≡⇓′ : xs ⦂⟅ A ⟆→∥ h xs ≡ [ xf ]↓ xs ∥
⟦ ≡⇓′ ⟧-prop = [ xf ]-set _ _
⟦ ≡⇓′ ⟧[] = ⟦_≡⟧[]
⟦ ≡⇓′ ⟧ x ∷ xs ⟨ P ⟩ = ⟦_≡⟧_∷_ x _ ; cong ([ xf ] x ∷_) P
open ⟦_≡_⟧
record ⟦_⊚_≡_⟧ {a b c} {A : Type a} {B : Type b} {C : Type c}
(h : B → C)
(xf : [⟅ A ⟆→ B ])
(yf : [⟅ A ⟆→ C ])
: Type (a ℓ⊔ b ℓ⊔ c)
where
constructor elim-fuse
field
⟦_∘≡⟧_∷_ : ∀ x xs → h ([ xf ] x ∷ xs) ≡ [ yf ] x ∷ h xs
⟦_∘≡⟧[] : h [ xf ][] ≡ [ yf ][]
⟦_∘≡⟧⇓ : ∀ xs → h ([ xf ]↓ xs) ≡ [ yf ]↓ xs
⟦_∘≡⟧⇓ = ⟦ ≡⇓′ ⟧⇓
where
≡⇓′ : xs ⦂⟅ A ⟆→∥ h ([ xf ]↓ xs) ≡ [ yf ]↓ xs ∥
⟦ ≡⇓′ ⟧-prop = [ yf ]-set _ _
⟦ ≡⇓′ ⟧[] = ⟦_∘≡⟧[]
⟦ ≡⇓′ ⟧ x ∷ xs ⟨ P ⟩ = ⟦_∘≡⟧_∷_ x _ ; cong ([ yf ] x ∷_) P
open ⟦_⊚_≡_⟧
map-alg : (A → B) → [⟅ A ⟆→ ⟅ B ⟆ ]
[ map-alg f ]-set = trunc
[ map-alg f ][] = []
[ map-alg f ] x ∷ xs = f x ∷ xs
[ map-alg f ]-com x y = com (f x) (f y)
map : (A → B) → ⟅ A ⟆ → ⟅ B ⟆
map f = [ map-alg f ]↓
[_]∘_ : [⟅ B ⟆→ C ] → (A → B) → [⟅ A ⟆→ C ]
[ [ g ]∘ f ]-set = [ g ]-set
[ [ g ]∘ f ][] = [ g ][]
[ [ g ]∘ f ] x ∷ xs = [ g ] f x ∷ xs
[ [ g ]∘ f ]-com x y = [ g ]-com (f x) (f y)
map-fuse : ∀ (g : [⟅ B ⟆→ C ]) (f : A → B)
→ [ g ]↓ ∘ map f ≡ [ [ g ]∘ f ]↓
map-fuse g f = funExt ⟦ map-fuse′ g f ∘≡⟧⇓
where
map-fuse′ : (g : [⟅ B ⟆→ C ]) (f : A → B)
→ ⟦ [ g ]↓ ⊚ map-alg f ≡ [ g ]∘ f ⟧
⟦ map-fuse′ g f ∘≡⟧ x ∷ xs = refl
⟦ map-fuse′ g f ∘≡⟧[] = refl
bind : ⟅ A ⟆ → (A → ⟅ B ⟆) → ⟅ B ⟆
bind xs f = ⟦ ⟅⟆-commutative-monoid _ ⟧ trunc f xs