{-# OPTIONS -WnoUnsupportedIndexedMatch #-}
module Cubical.Structures.Set.CMon.SList.Sort.Equiv where
open import Cubical.Structures.Prelude
open import Cubical.Data.Empty as ⊥
open import Cubical.Data.Maybe as Maybe
open import Cubical.Data.Nat
open import Cubical.Data.Nat.Order renaming (_≤_ to _≤ℕ_; _<_ to _<ℕ_)
open import Cubical.Data.Sigma
open import Cubical.Data.Sum as ⊎
open import Cubical.Induction.WellFounded
open import Cubical.Relation.Binary
open import Cubical.Relation.Binary.Order
open import Cubical.Relation.Nullary
open import Cubical.Relation.Nullary.HLevels
open import Cubical.Data.List hiding (tail)
open import Cubical.Data.List.Properties hiding (tail)
open import Cubical.HITs.PropositionalTruncation as P
open import Cubical.Functions.Embedding
import Cubical.Data.List as L
open import Cubical.Functions.Logic as L hiding (¬_; ⊥)
open import Cubical.Structures.Prelude
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 renaming (_∷_ to _∷*_; [] to []*; [_] to [_]*; _++_ to _++*_)
import Cubical.Structures.Set.CMon.SList.Base as S
open import Cubical.Structures.Set.CMon.SList.Length as S
open import Cubical.Structures.Set.CMon.SList.Membership as S
open import Cubical.Structures.Set.CMon.SList.Sort.Base
open import Cubical.Structures.Set.CMon.SList.Sort.Sort
open import Cubical.Structures.Set.CMon.SList.Sort.Order
open Iso
private
variable
ℓ : Level
A : Type ℓ
module MDef = F.Definition M.MonSig M.CMonEqSig M.CMonSEq
module LDef = F.Definition M.MonSig M.MonEqSig M.MonSEq
module Sort↔Order {ℓ : Level} {A : Type ℓ} (isSetA : isSet A) where
open Sort isSetA
open Sort.Section isSetA
open Sort→Order isSetA
open Order→Sort
open IsToset
open Toset
IsHeadLeastSection : (SList A -> List A) -> Type _
IsHeadLeastSection s = isSection s × isHeadLeast s
IsSortSection : (SList A -> List A) -> Type _
IsSortSection s = isSection s × isHeadLeast s × isTailSorted s
HasHeadLeastSectionAndIsDiscrete : Type _
HasHeadLeastSectionAndIsDiscrete = (Σ _ IsHeadLeastSection) × (Discrete A)
HasSortSection : Type _
HasSortSection = Σ (SList A -> List A) IsSortSection
HasSortSectionAndIsDiscrete : Type _
HasSortSectionAndIsDiscrete = HasSortSection × (Discrete A)
IsSortSection→IsHeadLeastSection : ∀ s -> IsSortSection s -> IsHeadLeastSection s
IsSortSection→IsHeadLeastSection s (section , isHeadLeast , _) = section , isHeadLeast
order→sort : HasDecOrder -> HasSortSectionAndIsDiscrete
order→sort (_≤_ , isToset , isDec) =
(sort _≤_ isToset isDec , subst (λ isSetA' -> Sort.isSortSection isSetA' (sort _≤_ isToset isDec)) (isPropIsSet _ _) (Order→Sort.sortIsSortSection _≤_ isToset isDec)) , isDiscreteA _≤_ isToset isDec
order→isHeadLeast : HasDecOrder -> HasHeadLeastSectionAndIsDiscrete
order→isHeadLeast p = let ((s , sIsSort) , r) = order→sort p in (s , IsSortSection→IsHeadLeastSection s sIsSort) , r
isHeadLeast→order : HasHeadLeastSectionAndIsDiscrete -> HasDecOrder
isHeadLeast→order ((s , sIsSection , sIsSort) , discA) =
_≤_ s sIsSection , ≤IsToset s sIsSection sIsSort , dec≤ s sIsSection discA
sort→order : HasSortSectionAndIsDiscrete -> HasDecOrder
sort→order ((s , sIsSort) , r) = isHeadLeast→order ((s , IsSortSection→IsHeadLeastSection s sIsSort) , r)
order→isHeadLeast→order : ∀ x -> isHeadLeast→order (order→isHeadLeast x) ≡ x
order→isHeadLeast→order (_≤_ , isToset , isDec) =
Σ≡Prop (λ _≤'_ -> isOfHLevelΣ 1 (isPropIsToset _) (λ p -> isPropΠ2 λ x y -> isPropDec (is-prop-valued p x y))) (sym ≤≡)
where
_≤*_ : A -> A -> Type _
_≤*_ = isHeadLeast→order (order→isHeadLeast (_≤_ , isToset , isDec)) .fst
≤*isToset : IsToset _≤*_
≤*isToset = isHeadLeast→order (order→isHeadLeast (_≤_ , isToset , isDec)) .snd .fst
isoTo : ∀ x y -> x ≤ y -> x ≤* y
isoTo x y x≤y with isDec x y
... | yes p = refl
... | no ¬p = ⊥.rec (¬p x≤y)
isoFrom : ∀ x y -> x ≤* y -> x ≤ y
isoFrom x y x≤y with isDec x y
... | yes p = p
... | no ¬p = ⊥.rec (¬p (subst (_≤ y) (just-inj y x x≤y) (is-refl isToset y)))
iso≤ : ∀ x y -> Iso (x ≤ y) (x ≤* y)
iso≤ x y = iso (isoTo x y) (isoFrom x y) (λ p -> is-prop-valued ≤*isToset x y _ p) (λ p -> is-prop-valued isToset x y _ p)
≤≡ : _≤_ ≡ _≤*_
≤≡ = funExt λ x -> funExt λ y -> isoToPath (iso≤ x y)
sort→order→sort : ∀ x -> order→sort (sort→order x) ≡ x
sort→order→sort ((s , sIsSection , sIsSort) , discA) =
Σ≡Prop (λ _ -> isPropDiscrete)
$ Σ≡Prop isPropIsSortSection
$ sym
$ funExt λ xs -> uniqueSort' _≤*_ ≤*isToset ≤*dec s xs (sIsSection , ∣_∣₁ ∘ sIsSort')
where
s' : SList A -> List A
s' = order→sort (sort→order ((s , sIsSection , sIsSort) , discA)) .fst .fst
s'IsSortSection : isSortSection s'
s'IsSortSection = order→sort (sort→order ((s , sIsSection , sIsSort) , discA)) .fst .snd
_≤*_ : A -> A -> Type _
_≤*_ = _≤_ s sIsSection
≤*isToset : IsToset _≤*_
≤*isToset = ≤IsToset s sIsSection (sIsSort .fst)
≤*dec : ∀ x y -> Dec (x ≤* y)
≤*dec = dec≤ s sIsSection discA
IsSorted* : List A -> Type _
IsSorted* = IsSorted _≤*_ ≤*isToset ≤*dec
sIsSort'' : ∀ xs n -> n ≡ L.length (s xs) -> IsSorted* (s xs)
sIsSort'' xs n p with n | s xs | inspect s xs
... | zero | [] | _ = sorted-nil
... | zero | y ∷ ys | _ = ⊥.rec (znots p)
... | suc _ | [] | _ = ⊥.rec (snotz p)
... | suc _ | y ∷ [] | _ = sorted-one y
... | suc m | y ∷ z ∷ zs | [ q ]ᵢ = induction (sIsSort'' (list→slist (z ∷ zs)) m (injSuc p ∙ wit))
where
wit : suc (L.length zs) ≡ L.length (s (list→slist (z ∷ zs)))
wit = sym $
L.length (s (list→slist (z ∷ zs))) ≡⟨ sortLength≡ s sIsSection (list→slist (z ∷ zs)) ⟩
S.length (list→slist (z ∷ zs)) ≡⟨ sym (sortLength≡α s sIsSection (z ∷ zs)) ⟩
L.length (z ∷ zs) ∎
z∷zsSorted : s (list→slist (z ∷ zs)) ≡ z ∷ zs
z∷zsSorted = sortUnique s sIsSection (z ∷ zs) (sIsSort .snd y (z ∷ zs) ∣ _ , q ∣₁)
induction : IsSorted* (s (list→slist (z ∷ zs))) -> IsSorted* (y ∷ z ∷ zs)
induction IH =
sorted-cons y z zs
(isSorted→≤ s sIsSection y z (sIsSort .fst y z _ ∣ _ , q ∣₁ (L.inr (L.inl refl))))
(subst IsSorted* z∷zsSorted IH)
sIsSort' : ∀ xs -> IsSorted* (s xs)
sIsSort' xs = sIsSort'' xs (L.length (s xs)) refl
order⊂isHeadLeast : isEmbedding order→isHeadLeast
order⊂isHeadLeast = injEmbedding (isSet× (isSetΣ (isSetΠ (λ _ -> isOfHLevelList 0 isSetA)) λ q -> isProp→isSet (isProp× (isPropIsSection q) (isPropIsHeadLeast q))) (isProp→isSet isPropDiscrete))
(λ p -> sym (order→isHeadLeast→order _) ∙ congS isHeadLeast→order p ∙ order→isHeadLeast→order _)
sort↔order : Iso HasDecOrder HasSortSectionAndIsDiscrete
sort↔order = iso order→sort sort→order sort→order→sort order→isHeadLeast→order
sort≃order : HasDecOrder ≃ HasSortSectionAndIsDiscrete
sort≃order = isoToEquiv sort↔order
sort≃strict-order : HasDecStrictOrder ≃ HasSortSectionAndIsDiscrete
sort≃strict-order = compEquiv (invEquiv HasDecOrder≃HasDecStrictOrder) sort≃order
sort≃lattice : Discrete A -> TotalMeetSemiLatticeStr A ≃ HasSortSection
sort≃lattice discA =
TotalMeetSemiLatticeStr A ≃⟨ HasDecOrder≃DecTotalMeetSemiLattice discA ⟩
HasDecOrder ≃⟨ sort≃order ⟩
HasSortSectionAndIsDiscrete ≃⟨ Σ-contractSnd (λ _ -> isContrDiscreteA) ⟩
HasSortSection ■
where
isContrDiscreteA : isContr (Discrete A)
isContrDiscreteA = discA , λ z -> funExt λ x -> funExt λ y -> isPropDec (isSetA x y) (discA x y) (z x y)
module Triangle {ℓ : Level} {A : Type ℓ} (decOrder : Toset.HasDecOrder {A = A}) where
_≤_ : A -> A -> Type _
_≤_ = fst decOrder
tosetA : IsToset _≤_
tosetA = snd decOrder .fst
decOrderA : ∀ x y -> Dec (x ≤ y)
decOrderA = snd decOrder .snd
open IsToset tosetA
open Sort↔Order is-set
open Order→Sort _≤_ tosetA decOrderA
open Sort→Order is-set
OList : Type ℓ
OList = Σ (List A) IsSorted
quotient* : List A -> SList A
quotient* = list→slist
sort* : List A -> OList
sort* xs = sort (quotient* xs) , sortIsSorted (quotient* xs)
triangle : quotient* ∘ fst ∘ sort* ≡ quotient*
triangle = funExt λ xs -> sortIsPermute (quotient* xs)
module Univalence {ℓ : Level} {A : Type ℓ} (is-set : isSet A) where
open import Cubical.Foundations.Transport
module FreeLMonDef = F.Definition M.MonSig M.MonEqSig M.MonSEq
module FreeCMonDef = F.Definition M.MonSig M.CMonEqSig M.CMonSEq
module _ (freeLMonDef : ∀ {ℓ' ℓ''} -> FreeLMonDef.Free ℓ' ℓ'' 2)
(freeCMonDef : ∀ {ℓ' ℓ''} -> FreeCMonDef.Free ℓ' ℓ'' 2) where
LA : Type ℓ
LA = FreeLMonDef.Free.F {ℓ' = ℓ} freeLMonDef A
LA≡ListA : LA ≡ List A
LA≡ListA = FreeLMonDef.free≡ freeLMonDef listDef is-set
MA : Type ℓ
MA = FreeCMonDef.Free.F {ℓ' = ℓ} freeCMonDef A
MA≡SListA : MA ≡ SList A
MA≡SListA = FreeCMonDef.free≡ freeCMonDef slistDef is-set
quotientHom* : _
quotientHom* = FreeLMonDef.Free.ext freeLMonDef
(FreeCMonDef.Free.trunc {ℓ' = ℓ} freeCMonDef is-set)
(M.cmonSatMon (FreeCMonDef.Free.sat freeCMonDef))
(FreeCMonDef.Free.η freeCMonDef)
quotient* : LA -> MA
quotient* = quotientHom* .fst