{-# OPTIONS --safe #-} module Data.Set where open import Prelude infixr 5 _β·_ data π¦ (A : Type a) : Type a where _β·_ : A β π¦ A β π¦ A β : π¦ A dup : β x xs β x β· x β· xs β‘ x β· xs comm : β x y xs β x β· y β· xs β‘ y β· x β· xs trunc : isSet (π¦ A) data π (A : Type a) (P : π¦ A β Type p) : Type (a ββ p) where β : π A P _β·_β¨_β© : A β (xs : π¦ A) β (Pβ¨xsβ© : P xs) β π A P embed : π A P β π¦ A embed β = β embed (x β· xs β¨ Pβ¨xsβ© β©) = x β· xs Alg : (P : π¦ A β Type p) β Type _ Alg P = (xs : π _ P) β P (embed xs) record Coherent {A : Type a} {P : π¦ A β Type p} (Ο : Alg P) : Type (a ββ p) where field c-trunc : β xs β isSet (P xs) c-com : β x y xs Pβ¨xsβ© β PathP (Ξ» i β P (comm x y xs i)) (Ο (x β· (y β· xs) β¨ Ο (y β· xs β¨ Pβ¨xsβ© β©) β©)) (Ο (y β· (x β· xs) β¨ Ο (x β· xs β¨ Pβ¨xsβ© β©) β© )) c-dup : β x xs Pβ¨xsβ© β PathP (Ξ» i β P (dup x xs i)) (Ο (x β· (x β· xs) β¨ Ο (x β· xs β¨ Pβ¨xsβ© β©) β©)) (Ο (x β· xs β¨ Pβ¨xsβ© β©)) open Coherent public π¦-foldr : (A β B β B) β B β Alg (const B) π¦-foldr f b β = b π¦-foldr f b (x β· xs β¨ Pβ¨xsβ© β©) = f x Pβ¨xsβ© Ξ¨ : (π¦ A β Type p) β Type _ Ξ¨ P = Ξ£[ Ο β¦ Alg P ] Γ Coherent Ο Ξ¨-syntax : (A : Type a) β (π¦ A β Type p) β Type _ Ξ¨-syntax _ = Ξ¨ syntax Ξ¨-syntax A (Ξ» x β e) = Ξ¨[ x β¦ π¦ A ] β¦ e Ο : Type a β Type b β Type _ Ο A B = Ξ¨ {A = A} (const B) β¦_β§ : {P : π¦ A β Type p} β Ξ¨ P β (xs : π¦ A) β P xs β¦ alg β§ β = alg .fst β β¦ alg β§ (x β· xs) = alg .fst (x β· xs β¨ β¦ alg β§ xs β©) β¦ alg β§ (comm x y xs i) = alg .snd .c-com x y xs (β¦ alg β§ xs) i β¦ alg β§ (dup x xs i) = alg .snd .c-dup x xs (β¦ alg β§ xs) i β¦ alg β§ (trunc xs ys p q i j) = isOfHLevelβisOfHLevelDep 2 (alg .snd .c-trunc) (β¦ alg β§ xs) (β¦ alg β§ ys) (cong β¦ alg β§ p) (cong β¦ alg β§ q) (trunc xs ys p q) i j prop-coh : {A : Type a} {P : π¦ A β Type p} {alg : Alg P} β (β xs β isProp (P xs)) β Coherent alg prop-coh P-isProp .c-trunc xs = isPropβisSet (P-isProp xs) prop-coh {P = P} {alg = alg} P-isProp .c-dup x xs Οβ¨xsβ© = toPathP (P-isProp (x β· xs) (transp (Ξ» i β P (dup x xs i)) i0 (alg (x β· (x β· xs) β¨ alg (x β· xs β¨ Οβ¨xsβ© β©) β©))) (alg (x β· xs β¨ Οβ¨xsβ© β©))) prop-coh {P = P} {alg = alg} P-isProp .c-com x y xs Οβ¨xsβ© = toPathP (P-isProp (y β· x β· xs) (transp (Ξ» i β P (comm x y xs i)) i0 (alg (x β· (y β· xs) β¨ alg (y β· xs β¨ Οβ¨xsβ© β©) β©))) (alg (y β· (x β· xs) β¨ alg (x β· xs β¨ Οβ¨xsβ© β©) β©))) infix 4 _β_ record AnEquality (A : Type a) : Type a where constructor _β_ field lhs rhs : π¦ A open AnEquality public EqualityProof-Alg : {B : Type b} (A : Type a) (P : π¦ A β AnEquality B) β Type (a ββ b) EqualityProof-Alg A P = Alg (Ξ» xs β let Pxs = P xs in lhs Pxs β‘ rhs Pxs) eq-coh : {A : Type a} {B : Type b} {P : π¦ A β AnEquality B} {alg : EqualityProof-Alg A P} β Coherent alg eq-coh {P = P} = prop-coh Ξ» xs β let Pxs = P xs in trunc (lhs Pxs) (rhs Pxs) union-alg : Ο A (π¦ A β π¦ A) union-alg .fst β ys = ys union-alg .fst (x β· xs β¨ Pβ¨xsβ© β©) ys = x β· Pβ¨xsβ© ys union-alg .snd .c-trunc _ = isSetΞ Ξ» _ β trunc union-alg .snd .c-com x y xs Pβ¨xsβ© i ys = comm x y (Pβ¨xsβ© ys) i union-alg .snd .c-dup x xs Pβ¨xsβ© i ys = dup x (Pβ¨xsβ© ys) i infixr 5 _βͺ_ _βͺ_ : π¦ A β π¦ A β π¦ A _βͺ_ = β¦ union-alg β§ β·-distrib : β (x : A) xs ys β x β· (xs βͺ ys) β‘ xs βͺ (x β· ys) β·-distrib x = β¦ alg x β§ where alg : β x β Ξ¨[ xs β¦ π¦ A ] β¦ (β ys β x β· (xs βͺ ys) β‘ xs βͺ (x β· ys)) alg x .fst β ys = refl alg x .fst (y β· xs β¨ Pβ¨xsβ© β©) ys = comm x y (xs βͺ ys) ΝΎ cong (y β·_) (Pβ¨xsβ© ys) alg x .snd = prop-coh Ξ» _ β isPropΞ Ξ» _ β trunc _ _ βͺ-idem : (xs : π¦ A) β xs βͺ xs β‘ xs βͺ-idem = β¦ alg β§ where alg : Ξ¨[ xs β¦ π¦ A ] β¦ ((xs βͺ xs) β‘ xs) alg .fst β = refl alg .snd = eq-coh alg .fst (x β· xs β¨ Pβ¨xsβ© β©) = (x β· xs) βͺ (x β· xs) β‘Λβ¨ β·-distrib x (x β· xs) xs β© x β· x β· xs βͺ xs β‘β¨ dup x (xs βͺ xs) β© x β· xs βͺ xs β‘β¨ cong (x β·_) Pβ¨xsβ© β© x β· xs β βͺ-idΚ³ : (xs : π¦ A) β (xs βͺ β β‘ xs) βͺ-idΚ³ = β¦ alg β§ where alg : Ξ¨[ xs β¦ π¦ A ] β¦ (xs βͺ β β‘ xs) alg .fst β = refl alg .fst (x β· xs β¨ Pβ¨xsβ© β©) = cong (x β·_) Pβ¨xsβ© alg .snd = eq-coh βͺ-com : (xs ys : π¦ A) β (xs βͺ ys β‘ ys βͺ xs) βͺ-com = β¦ alg β§ where alg : Ξ¨[ xs β¦ π¦ A ] β¦ (β ys β xs βͺ ys β‘ ys βͺ xs) alg .fst β ys = sym (βͺ-idΚ³ ys) alg .fst (x β· xs β¨ Pβ¨xsβ© β©) ys = cong (x β·_) (Pβ¨xsβ© ys) ΝΎ β·-distrib x ys xs alg .snd = prop-coh Ξ» _ β isPropΞ Ξ» _ β trunc _ _ βͺ-assoc : (xs ys zs : π¦ A) β ((xs βͺ ys) βͺ zs β‘ xs βͺ (ys βͺ zs)) βͺ-assoc = β¦ alg β§ where alg : Ξ¨[ xs β¦ π¦ A ] β¦ (β ys zs β (xs βͺ ys) βͺ zs β‘ xs βͺ (ys βͺ zs)) alg .fst β ys zs = refl alg .fst (x β· xs β¨ Pβ¨xsβ© β©) ys zs = cong (x β·_) (Pβ¨xsβ© ys zs) alg .snd = prop-coh Ξ» _ β isPropΞ Ξ» _ β isPropΞ Ξ» _ β trunc _ _ π¦-map : (A β B) β π¦ A β π¦ B π¦-map f = β¦ map-alg f β§ where map-alg : (A β B) β Ξ¨[ xs β¦ π¦ A ] β¦ π¦ B map-alg f .fst β = β map-alg f .fst (x β· _ β¨ xs β©) = f x β· xs map-alg f .snd .c-trunc _ = trunc map-alg f .snd .c-com x y _ = comm (f x) (f y) map-alg f .snd .c-dup x _ = dup (f x) map-βͺ : (f : A β B) (xs ys : π¦ A) β π¦-map f xs βͺ π¦-map f ys β‘ π¦-map f (xs βͺ ys) map-βͺ f xs ys = β¦ alg f ys β§ xs where alg : (f : A β B) (ys : π¦ A) β Ξ¨[ xs β¦ π¦ A ] β¦ ((π¦-map f xs βͺ π¦-map f ys) β‘ π¦-map f (xs βͺ ys)) alg f ys .fst β = refl alg f ys .fst (x β· _ β¨ xs β©) = cong (f x β·_) xs alg f ys .snd = prop-coh Ξ» _ β trunc _ _ module _ {A : Type a} where open import Truth sup-sing : A β π¦ A β Ξ© a sup-sing x = β¦ sup-alg x β§ where sup-alg : A β Ξ¨[ xs β¦ π¦ A ] β¦ Ξ© _ sup-alg x .fst β = True sup-alg x .fst (y β· _ β¨ β xββxs β©) = (x |β‘| y) |β§| β xββxs sup-alg x .snd .c-trunc _ = isSetΞ© sup-alg x .snd .c-com y z _ xs = sym (β§-assoc _ _ _) ΝΎ cong (_|β§| xs) (β§-com _ _ ) ΝΎ β§-assoc _ _ _ sup-alg x .snd .c-dup y _ xs = sym (β§-assoc _ _ _) ΝΎ cong (_|β§| xs) (β§-idem _) β _ββ_ : A β π¦ A β Type a β x ββ xs = ProofOf (sup-sing x xs) sup-sing-βͺ : (x : A) (xs ys : π¦ A) β β x ββ xs β β x ββ ys β β x ββ (xs βͺ ys) sup-sing-βͺ x xs ys p q = β¦ alg x ys q β§ xs p where alg : (x : A) (ys : π¦ A) β β x ββ ys β Ξ¨[ xs β¦ π¦ A ] β¦ (β x ββ xs β β x ββ (xs βͺ ys)) alg x ys q .fst β p = q alg x ys q .fst (y β· _ β¨ Pβ¨xsβ© β©) (p , ps) = p , Pβ¨xsβ© ps alg x ys q .snd = prop-coh Ξ» xs β isPropβ (IsProp (sup-sing x (xs βͺ ys)))