{-# OPTIONS --cubical --exact-split --safe #-}
module Cubical.Structures.Set.CMon.SList.Seely where
open import Cubical.Foundations.Everything
open import Cubical.Data.Sigma
open import Cubical.Data.Nat
open import Cubical.Data.Nat.Order
open import Cubical.Data.Empty as ⊥
open import Cubical.Induction.WellFounded
import Cubical.Data.List as L
open import Cubical.HITs.PropositionalTruncation as P
open import Cubical.Data.Sum as ⊎
import Cubical.Structures.Set.Mon.Desc as M
import Cubical.Structures.Set.CMon.Desc as M
import Cubical.Structures.Free as F
open import Cubical.Structures.Sig
open import Cubical.Structures.Str public
open import Cubical.Structures.Tree
open import Cubical.Structures.Eq
open import Cubical.Structures.Arity
open import Cubical.Structures.Set.Mon.List
open import Cubical.Structures.Set.CMon.SList.Base as SList
module _ {ℓ} {A B : Type ℓ} where
open SListDef.Free
isSetSList× : isSet (SList A × SList B)
isSetSList× = isSet× trunc trunc
slist×-α : sig M.MonSig (SList A × SList B) -> (SList A × SList B)
slist×-α (M.`e , i) = [] , []
slist×-α (M.`⊕ , i) = (i fzero) .fst ++ (i fone) .fst , (i fzero) .snd ++ (i fone) .snd
slist×-sat : < (SList A × SList B) , slist×-α > ⊨ M.CMonSEq
slist×-sat (M.`mon M.`unitl) ρ = refl
slist×-sat (M.`mon M.`unitr) ρ = ≡-× (slist-sat (M.`mon M.`unitr) (fst ∘ ρ)) ((slist-sat (M.`mon M.`unitr) (snd ∘ ρ)))
slist×-sat (M.`mon M.`assocr) ρ = ≡-× (slist-sat (M.`mon M.`assocr) (fst ∘ ρ)) ((slist-sat (M.`mon M.`assocr) (snd ∘ ρ)))
slist×-sat M.`comm ρ = ≡-× (slist-sat M.`comm (fst ∘ ρ)) ((slist-sat M.`comm (snd ∘ ρ)))
f-η : A ⊎ B -> SList A × SList B
f-η (inl x) = [ x ] , []
f-η (inr x) = [] , [ x ]
f-hom : structHom < SList (A ⊎ B) , slist-α > < (SList A × SList B) , slist×-α >
f-hom = ext slistDef isSetSList× slist×-sat f-η
f : SList (A ⊎ B) -> SList A × SList B
f = f-hom .fst
mmap : ∀ {X Y : Type ℓ} -> (X -> Y) -> SList X -> SList Y
mmap f = ext slistDef trunc slist-sat ([_] ∘ f) .fst
mmap-++ : ∀ {X Y : Type ℓ} -> ∀ f xs ys -> mmap {X = X} {Y = Y} f (xs ++ ys) ≡ mmap f xs ++ mmap f ys
mmap-++ f xs ys = sym (ext slistDef trunc slist-sat ([_] ∘ f) .snd M.`⊕ ⟪ xs ⨾ ys ⟫)
mmap-∷ : ∀ {X Y : Type ℓ} -> ∀ f x xs -> mmap {X = X} {Y = Y} f (x ∷ xs) ≡ f x ∷ mmap f xs
mmap-∷ f x xs = mmap-++ f [ x ] xs
g : SList A × SList B -> SList (A ⊎ B)
g (as , bs) = mmap inl as ++ mmap inr bs
g-++ : ∀ xs ys -> g xs ++ g ys ≡ g (xs .fst ++ ys .fst , xs .snd ++ ys .snd)
g-++ (as , bs) (cs , ds) = sym $
g (as ++ cs , bs ++ ds)
≡⟨ cong (_++ mmap inr (bs ++ ds)) (mmap-++ inl as cs) ⟩
(mmap inl as ++ mmap inl cs) ++ (mmap inr (bs ++ ds))
≡⟨ cong ((mmap inl as ++ mmap inl cs) ++_) (mmap-++ inr bs ds) ⟩
(mmap inl as ++ mmap inl cs) ++ (mmap inr bs ++ mmap inr ds)
≡⟨ assoc-++ (mmap inl as ++ mmap inl cs) (mmap inr bs) (mmap inr ds) ⟩
((mmap inl as ++ mmap inl cs) ++ mmap inr bs) ++ mmap inr ds
≡⟨ cong (_++ mmap inr ds) (sym (assoc-++ (mmap inl as) (mmap inl cs) (mmap inr bs))) ⟩
(mmap inl as ++ (mmap inl cs ++ mmap inr bs)) ++ mmap inr ds
≡⟨ cong (λ z → (mmap inl as ++ z) ++ mmap inr ds) (comm-++ (mmap inl cs) (mmap inr bs)) ⟩
(mmap inl as ++ (mmap inr bs ++ mmap inl cs)) ++ mmap inr ds
≡⟨ cong (_++ mmap inr ds) (assoc-++ (mmap inl as) (mmap inr bs) (mmap inl cs)) ⟩
((mmap inl as ++ mmap inr bs) ++ mmap inl cs) ++ mmap inr ds
≡⟨ sym (assoc-++ (mmap inl as ++ mmap inr bs) (mmap inl cs) (mmap inr ds)) ⟩
(mmap inl as ++ mmap inr bs) ++ (mmap inl cs ++ mmap inr ds)
≡⟨⟩
g (as , bs) ++ g (cs , ds)
∎
g-hom : structHom < (SList A × SList B) , slist×-α > < SList (A ⊎ B) , slist-α >
g-hom = g , g-is-hom
where
g-is-hom : structIsHom < SList A × SList B , slist×-α > < SList (A ⊎ B) , slist-α > g
g-is-hom M.`e i = refl
g-is-hom M.`⊕ i = g-++ (i fzero) (i fone)
module _ {ℓ} {X : Type ℓ} (h : structHom < SList X , slist-α > < SList X , slist-α >) (h-η : ∀ x -> h .fst [ x ] ≡ [ x ]) where
univ-htpy : ∀ xs -> h .fst xs ≡ xs
univ-htpy xs = h~η♯ xs ∙ η♯~id xs
where
h~η♯ : ∀ xs -> h .fst xs ≡ ext slistDef trunc slist-sat [_] .fst xs
h~η♯ = ElimProp.f (trunc _ _) (sym (h .snd M.`e ⟪⟫)) λ x {xs} p ->
h .fst (x ∷ xs) ≡⟨ sym (h .snd M.`⊕ ⟪ [ x ] ⨾ xs ⟫) ⟩
h .fst [ x ] ++ h .fst xs ≡⟨ congS (_++ h .fst xs) (h-η x) ⟩
x ∷ h .fst xs ≡⟨ congS (x ∷_) p ⟩
x ∷ ext slistDef trunc slist-sat [_] .fst xs ∎
η♯~id : ∀ xs -> ext slistDef trunc slist-sat [_] .fst xs ≡ xs
η♯~id xs = congS (λ h -> h .fst xs) (ext-β slistDef trunc slist-sat (idHom < SList X , slist-α >))
g-f : ∀ xs -> g (f xs) ≡ xs
g-f = univ-htpy (structHom∘ _ _ < SList (A ⊎ B) , slist-α > g-hom f-hom) lemma
where
lemma : ∀ x -> g (f [ x ]) ≡ [ x ]
lemma (inl x) = refl
lemma (inr x) = refl
f-mmap-inl : ∀ as -> f (mmap inl as) ≡ (as , [])
f-mmap-inl = ElimProp.f (isSetSList× _ _) refl λ x {xs} p ->
f (mmap inl (x ∷ xs)) ≡⟨ cong f (mmap-∷ inl x xs) ⟩
f (inl x ∷ mmap inl xs) ≡⟨ sym (f-hom .snd M.`⊕ ⟪ [ inl x ] ⨾ mmap inl xs ⟫) ⟩
x ∷ f (mmap inl xs) .fst , f (mmap inl xs) .snd ≡⟨ congS (λ z -> x ∷ z .fst , z .snd) p ⟩
x ∷ xs , [] ∎
f-mmap-inr : ∀ as -> f (mmap inr as) ≡ ([] , as)
f-mmap-inr = ElimProp.f (isSetSList× _ _) refl λ x {xs} p ->
f (mmap inr (x ∷ xs)) ≡⟨ cong f (mmap-∷ inr x xs) ⟩
f (inr x ∷ mmap inr xs) ≡⟨ sym (f-hom .snd M.`⊕ ⟪ [ inr x ] ⨾ mmap inr xs ⟫) ⟩
f (mmap inr xs) .fst , x ∷ f (mmap inr xs) .snd ≡⟨ congS (λ z -> z .fst , x ∷ z .snd) p ⟩
[] , x ∷ xs ∎
f-g : ∀ xs -> f (g xs) ≡ xs
f-g (as , bs) =
f (g (as , bs))
≡⟨ sym (f-hom .snd M.`⊕ ⟪ mmap inl as ⨾ mmap inr bs ⟫) ⟩
(f (mmap inl as) .fst ++ f (mmap inr bs) .fst) , (f (mmap inl as) .snd ++ f (mmap inr bs) .snd)
≡⟨ congS (λ z -> (z .fst ++ f (mmap inr bs) .fst) , (z .snd ++ f (mmap inr bs) .snd)) (f-mmap-inl as) ⟩
as ++ f (mmap inr bs) .fst , [] ++ f (mmap inr bs) .snd
≡⟨ congS (λ z -> as ++ z .fst , [] ++ z .snd) (f-mmap-inr bs) ⟩
as ++ [] , bs
≡⟨ congS (λ zs -> zs , bs) (unitr-++ as) ⟩
as , bs ∎
seely : SList (A ⊎ B) ≃ SList A × SList B
seely = isoToEquiv (iso f g f-g g-f)