module Spice where
open import Cubical.Foundations.Prelude
renaming ( congS to ap
; cong to apd
; congP to apP
; subst to tpt
)
open import Cubical.Foundations.HLevels
open import Cubical.Foundations.Equiv
open import Cubical.Foundations.Function
open import Cubical.Relation.Binary.Order.Toset
import Cubical.HITs.PropositionalTruncation as PTrunc
import Cubical.Functions.Logic as L
open import Cubical.Data.Sigma
open import Cubical.Data.Nat
import Cubical.Data.Nat.Order as Nat
open import Cubical.Data.Unit renaming (Unit to π ; tt to β)
open import Cubical.Data.Empty hiding (rec)
open import Cubical.Data.Sum hiding (rec)
import Cubical.Data.Sum as β using (rec)
variable
β β' β'' : Level
A B C : Type β
module SLists where
infixr 10 _β·_
data SList {β} (A : Type β) : Type β where
[] : SList A
_β·_ : A β SList A β SList A
swap : (x y : A) (xs : SList A) β x β· y β· xs β‘ y β· x β· xs
trunc : isSet (SList A)
module SListElim where
module _ (P : SList A β Type β')
([]* : P [])
(_β·*_ : (x : A) {xs : SList A} β P xs β P (x β· xs))
(swap* : (x y : A) {xs : SList A} (p : P xs) β PathP (Ξ» i β P (swap x y xs i)) (x β·* (y β·* p)) (y β·* (x β·* p)))
(trunc* : (xs : SList A) β isSet (P xs)) where
ind : (xs : SList A) β P xs
ind [] = []*
ind (x β· xs) = x β·* ind xs
ind (swap x y xs i) = swap* x y (ind xs) i
ind (trunc x y p q i j) =
isSetβSquareP (Ξ» i j β trunc* (trunc x y p q i j)) (apd ind p) (apd ind q) refl refl i j
module _ {A : Type β} (P : SList A β Type β')
([]* : P [])
(_β·*_ : (x : A) {xs : SList A} β P xs β P (x β· xs))
(trunc* : (xs : SList A) β isProp (P xs)) where
private
swap* : (x y : A) {xs : SList A} (p : P xs) β PathP (Ξ» i β P (swap x y xs i)) (x β·* (y β·* p)) (y β·* (x β·* p))
swap* x y {xs} p = isPropβPathP (Ξ» i β trunc* (swap x y xs i)) (x β·* (y β·* p)) (y β·* (x β·* p))
indProp : (xs : SList A) β P xs
indProp = ind P []* _β·*_ swap* (Ξ» xs β isPropβisSet (trunc* xs))
module _ {A : Type β} (P : Type β')
([]* : P)
(_β·*_ : A β P β P)
(swap* : (x y : A) β (p : P) β Path P (x β·* (y β·* p)) (y β·* (x β·* p)))
(trunc* : isSet P) where
rec : SList A β P
rec = ind (Ξ» _ β P) []* (Ξ» x {xs} β x β·*_) (Ξ» x y {xs} β swap* x y) (Ξ» _ β trunc*)
as : SList β
as = 1 β· 2 β· 3 β· []
bs : SList β
bs = 3 β· 2 β· 1 β· []
p : as β‘ bs
p = swap 1 2 _ β ap (2 β·_) (swap 1 3 _) β swap 2 3 _
q : as β‘ bs
q = ap (1 β·_) (swap 2 3 _) β swap 1 3 _ β ap (3 β·_) (swap 1 2 _)
_ : p β‘ q
_ = trunc as bs p q
module Monoid where
open import Cubical.Data.List
pattern [_βΆ_] a b = a β· b β· []
pattern [_βΆ_βΆ_] a b c = a β· b β· c β· []
pattern [_βΆ_βΆ_βΆ_] a b c d = a β· b β· c β· d β· []
pattern [_βΆ_βΆ_βΆ_βΆ_] a b c d e = a β· b β· c β· d β· e β· []
record Mon {a} (A : Type a) : Type a where
infixr 10 _β_
field
e : A
_β_ : A β A β A
unitl : β x β e β x β‘ x
unitr : β x β x β e β‘ x
assocr : β x y z β (x β y) β z β‘ x β (y β z)
open Mon
record MonHom {a b} {A : Type a} {B : Type b} (M : Mon A) (N : Mon B) : Type (β-max a b) where
private
module M = Mon M
module N = Mon N
field
Ο : A β B
preserves-e : Ο M.e β‘ N.e
preserves-β : β x y β Ο (x M.β y) β‘ Ο x N.β Ο y
open MonHom
ListMon : β {a} {A : Type a} β Mon (List A)
ListMon .e = []
ListMon ._β_ = _++_
ListMon .unitl xs = refl
ListMon .unitr = ++-unit-r
ListMon .assocr = ++-assoc
Ξ· : β {a} {A : Type a} β A β List A
Ξ· a = [ a ]
module _ {a m} {A : Type a} {M : Type m} (M* : Mon M) where
private
module M = Mon M*
eval : (A β M) β List A β M
eval f [] = M.e
eval f (x β· xs) = f x M.β eval f xs
[_]_β― = eval
module _ (h* : MonHom ListMon M*) (f : A β M) where
private
module h = MonHom h*
eval-uniq : h.Ο β Ξ· β‘ f β β xs β h.Ο xs β‘ eval f xs
eval-uniq p [] =
h.preserves-e
eval-uniq p (x β· xs) =
h.preserves-β [ x ] xs
β ap (M._β h.Ο xs) (funExtβ» p x)
β ap (f x M.β_) (eval-uniq p xs)
[_]_β―-uniq = eval-uniq
π+β¨_β©-Mon : β {a} (A : Type a) β Mon (π β A)
π+β¨ A β©-Mon .e = inl β
π+β¨ A β©-Mon ._β_ (inl β) y = y
π+β¨ A β©-Mon ._β_ (inr x) y = inr x
π+β¨ A β©-Mon .unitl x = refl
π+β¨ A β©-Mon .unitr (inl β) = refl
π+β¨ A β©-Mon .unitr (inr x) = refl
π+β¨ A β©-Mon .assocr (inl β) y z = refl
π+β¨ A β©-Mon .assocr (inr x) (inl β) z = refl
π+β¨ A β©-Mon .assocr (inr x) (inr y) z = refl
head : β {a} {A : Type a} β List A β π β A
head {A = A} = [ π+β¨ A β©-Mon ] inr β―
_ : head {A = β} [] β‘ inl β
_ = refl
_ : head {A = β} [ 2 βΆ 1 βΆ 3 ] β‘ inr 2
_ = refl
module CMonoid where
open SLists
pattern [_] a = a β· []
pattern [_βΆ_] a b = a β· b β· []
pattern [_βΆ_βΆ_] a b c = a β· b β· c β· []
pattern [_βΆ_βΆ_βΆ_] a b c d = a β· b β· c β· d β· []
pattern [_βΆ_βΆ_βΆ_βΆ_] a b c d e = a β· b β· c β· d β· e β· []
module _ {β} {A : Type β} where
infixr 5 _++_
_++_ : SList A β SList A β SList A
_++_ = SListElim.rec (SList A β SList A)
(Ξ» ys β ys)
(Ξ» x h ys β x β· h ys)
(Ξ» x y h i β Ξ» ys β swap x y (h ys) i)
(isSetβ trunc)
++-unit-r : (xs : SList A) β xs ++ [] β‘ xs
++-unit-r = SListElim.indProp (Ξ» xs β xs ++ [] β‘ xs)
refl
(Ξ» x {xs} h i β x β· h i)
(Ξ» xs β trunc (xs ++ []) xs)
++-assoc : (xs ys zs : SList A) β (xs ++ ys) ++ zs β‘ xs ++ ys ++ zs
++-assoc = SListElim.indProp (Ξ» xs β (ys zs : SList A) β (xs ++ ys) ++ zs β‘ xs ++ ys ++ zs)
(Ξ» ys zs β refl)
(Ξ» x {xs} h ys zs i β x β· h ys zs i)
(Ξ» xs β isPropΞ 2 Ξ» x y β trunc ((xs ++ x) ++ y) (xs ++ x ++ y))
β·-comm : (x : A) (xs : SList A) β x β· xs β‘ xs ++ [ x ]
β·-comm x = SListElim.indProp (Ξ» xs β x β· xs β‘ xs ++ [ x ])
refl
(Ξ» y {xs} h β swap x y xs β ap (y β·_) h)
(Ξ» xs β trunc (x β· xs) (xs ++ [ x ]))
++-comm : (xs ys : SList A) β xs ++ ys β‘ ys ++ xs
++-comm = SListElim.indProp (Ξ» xs β (ys : SList A) β xs ++ ys β‘ ys ++ xs)
(Ξ» ys β sym (++-unit-r ys))
(Ξ» x {xs} h ys i β
hcomp (Ξ» j β Ξ» { (i = i0) β x β· h ys (~ j)
; (i = i1) β ++-assoc ys [ x ] xs j })
(β·-comm x ys i ++ xs))
(Ξ» xs β isPropΞ (Ξ» ys β trunc (xs ++ ys) (ys ++ xs)))
record CMon {a} (A : Type a) : Type a where
infixr 10 _β_
field
e : A
_β_ : A β A β A
unitl : β x β e β x β‘ x
assocr : β x y z β (x β y) β z β‘ x β (y β z)
comm : β x y β x β y β‘ y β x
hLevel : isSet A
open CMon
record CMonHom {a b} {A : Type a} {B : Type b} (M : CMon A) (N : CMon B) : Type (β-max a b) where
private
module M = CMon M
module N = CMon N
field
Ο : A β B
preserves-e : Ο M.e β‘ N.e
preserves-β : β x y β Ο (x M.β y) β‘ Ο x N.β Ο y
open CMonHom
SListCMon : β {a} {A : Type a} β CMon (SList A)
SListCMon .e = []
SListCMon ._β_ = _++_
SListCMon .unitl xs = refl
SListCMon .assocr = ++-assoc
SListCMon .comm = ++-comm
SListCMon .hLevel = trunc
Ξ· : β {a} {A : Type a} β A β SList A
Ξ· a = [ a ]
hPropCMon : β {β} β CMon (hProp β)
hPropCMon .e = (β₯* , isPropβ₯*)
hPropCMon ._β_ = L._β_
hPropCMon .unitl x =
L.ββΆ PTrunc.rec (x .snd) (Ξ» { (inr x) β x ; (inl ()) })
ββΆ Ξ» x β PTrunc.β£ (inr x) β£β
hPropCMon .assocr = Ξ» x y z β (sym (L.β-assoc x y z))
hPropCMon .comm = L.β-comm
hPropCMon .hLevel = isSetHProp
module _ {a m} {A : Type a} {M : Type m} (M* : CMon M) where
private
module M = CMon M*
eval : (A β M) β SList A β M
eval f = SListElim.rec M
M.e
(Ξ» a h β f a M.β h)
(Ξ» x y h β sym (M.assocr (f x) (f y) h) ββ ap (M._β h) (M.comm (f x) (f y)) ββ M.assocr (f y) (f x) h)
M.hLevel
[_]_β― = eval
eval-cons : β x xs β {f : A β M} β eval f (x β· xs) β‘ f x M.β eval f xs
eval-cons x xs = refl
module _ (h* : CMonHom SListCMon M*) (f : A β M) where
private
module h = CMonHom h*
eval-uniq : h.Ο β Ξ· β‘ f β β xs β h.Ο xs β‘ eval f xs
eval-uniq p = SListElim.indProp (Ξ» xs β h.Ο xs β‘ eval f xs)
h.preserves-e
(Ξ» x {xs} H β h.preserves-β [ x ] xs β ap (M._β h.Ο xs) (funExtβ» p x) β ap (f x M.β_) H)
(Ξ» xs β M.hLevel (h.Ο xs) (eval f xs))
[_]_β―-uniq = eval-uniq
module SymHead (T@(A , A*) : Toset β β') where
private
_β€_ = TosetStr._β€_ A*
isPropValued = TosetStr.is-prop-valued A*
antisym = TosetStr.is-antisym A*
trans = TosetStr.is-trans A*
totality = TosetStr.is-total A*
reflexivity = TosetStr.is-refl A*
isSetA = TosetStr.is-set A*
infixr 20 _β_
β-min : (a b : A) β (a β€ b) β (b β€ a) β A
β-min a b = β.rec (Ξ» p β a) (Ξ» q β b)
β-2Const : (a b : A) β 2-Constant (β-min a b)
β-2Const a b =
β.elim (Ξ» aβ€b -> β.elim (Ξ» _ -> refl) (Ξ» bβ€a -> antisym a b aβ€b bβ€a))
(Ξ» bβ€a -> β.elim (Ξ» aβ€b -> antisym b a bβ€a aβ€b) (Ξ» _ -> refl))
_β_ : A β A β A
_β_ a b =
PTrunc.recβSet (IsToset.is-set (TosetStr.isToset A*))
(β-min a b) (β-2Const a b) (totality a b)
β-aβ€b : (a b : A) β (a β€ b) β (a β b) β‘ a
β-aβ€b a b p = PTrunc.SetElim.helper
isSetA
(β-min a b)
(β-2Const a b)
(totality a b)
PTrunc.β£ (inl p) β£β
β-bβ€a : (a b : A) β (b β€ a) β (a β b) β‘ b
β-bβ€a a b q = PTrunc.SetElim.helper
isSetA
(β-min a b)
(β-2Const a b)
(totality a b)
PTrunc.β£ inr q β£β
β-meet : (a b : A) β (a β b) β€ a Γ (a β b) β€ b
β-meet a b =
( PTrunc.rec (isPropValued (a β b) a)
(β.rec (Ξ» p β tpt (_β€ a) (sym (β-aβ€b a b p)) (reflexivity a))
Ξ» q β tpt (_β€ a) (sym (β-bβ€a a b q)) q)
(totality a b)
, PTrunc.rec (isPropValued (a β b) b)
(β.rec (Ξ» p β tpt (_β€ b) (sym (β-aβ€b a b p)) p)
Ξ» q β tpt (_β€ b) (sym (β-bβ€a a b q)) (reflexivity b))
(totality a b))
β-univβ : (a b x : A) β x β€ (a β b) β (x β€ a) Γ (x β€ b)
β-univβ a b x p =
( trans x (a β b) a p (β-meet a b .fst)
, trans x (a β b) b p (β-meet a b .snd))
β-univβ : (a b x : A) β (x β€ a) Γ (x β€ b) β x β€ (a β b)
β-univβ a b x (p , q) =
PTrunc.rec (isPropValued x (a β b))
(β.rec (Ξ» r β tpt (x β€_) (sym (β-aβ€b a b r)) p)
(Ξ» s β tpt (x β€_) (sym (β-bβ€a a b s)) q))
(totality a b)
β-univ : (a b x : A) β (x β€ (a β b)) β ((x β€ a) Γ (x β€ b))
β-univ a b x =
propBiimplβEquiv (isPropValued x (a β b))
(isPropΓ (isPropValued x a) (isPropValued x b))
(β-univβ a b x) (β-univβ a b x)
γβ‘ : (a b : A) β ((x : A) β x β€ a β x β€ b) β a β‘ b
γβ‘ a b f = antisym a b (f a .fst (reflexivity a)) (invEq (f b) (reflexivity b))
β-assoc : (a b c : A) β (a β b) β c β‘ a β (b β c)
β-assoc a b c =
γβ‘ ((a β b) β c) (a β b β c)
Ξ» x β compEquiv (β-univ (a β b) c x)
(compEquiv (Ξ£-cong-equiv (β-univ a b x) (Ξ» _ β idEquiv (x β€ c)))
(compEquiv Ξ£-assoc-β (compEquiv (Ξ£-cong-equiv (idEquiv (x β€ a))
(Ξ» _ β invEquiv (β-univ b c x))) (invEquiv (β-univ a (b β c) x)))))
β-comm : (a b : A) β a β b β‘ b β a
β-comm a b = γβ‘ (a β b) (b β a)
Ξ» x β compEquiv (β-univ a b x) (compEquiv Ξ£-swap-β (invEquiv (β-univ b a x)))
infixr 20 _β_
_β_ : π β A β π β A β π β A
inl β β b = b
inr x β inl β = inr x
inr x β inr y = inr (x β y)
β-unitl : (x : π β A) β x β‘ x
β-unitl (inl β) = refl
β-unitl (inr x) = refl
β-assoc : (a b c : π β A) β (a β b) β c β‘ a β (b β c)
β-assoc (inl β) b c = refl
β-assoc (inr a) (inl β) c = refl
β-assoc (inr a) (inr b) (inl β) = refl
β-assoc (inr a) (inr b) (inr c) = ap inr (β-assoc a b c)
β-comm : (a b : π β A) β a β b β‘ b β a
β-comm (inl β) (inl β) = refl
β-comm (inl β) (inr b) = refl
β-comm (inr a) (inl β) = refl
β-comm (inr a) (inr b) = ap inr (β-comm a b)
MaybeCMon : CMon (π β A)
MaybeCMon .e = inl β
MaybeCMon ._β_ = _β_
MaybeCMon .unitl = Ξ» _ β refl
MaybeCMon .assocr = β-assoc
MaybeCMon .comm = β-comm
MaybeCMon .hLevel = isSetβ isSetUnit (IsToset.is-set (TosetStr.isToset A*))
head : SList A β π β A
head = [ MaybeCMon ] inr β―
β* : IsToset {β = β-zero} {β' = β-zero} {A = β} Nat._β€_
β* .IsToset.is-set = isSetβ
β* .IsToset.is-prop-valued a b = Nat.isPropβ€
β* .IsToset.is-refl a = Nat.β€-refl
β* .IsToset.is-trans a b c = Nat.β€-trans
β* .IsToset.is-antisym a b = Nat.β€-antisym
β* .IsToset.is-total a b with (Nat._β_ a b)
... | Nat.lt x = PTrunc.β£ (inl (Nat.<-weaken x)) β£β
... | Nat.eq x = PTrunc.β£ (inl (tpt (Ξ» y β (y Nat.β€ b)) (sym x) Nat.β€-refl)) β£β
... | Nat.gt x = PTrunc.β£ (inr (Nat.<-weaken x)) β£β
open SymHead (β , (tosetstr Nat._β€_ β*))
_ : head [] β‘ inl β
_ = refl
_ : head [ 4 βΆ 6 βΆ 9 βΆ 6 βΆ 7 ] β‘ inr 4
_ = refl