From 5adc1ae9357e42937a601aab57d16b2190e10536 Mon Sep 17 00:00:00 2001 From: Chloe Brown Date: Fri, 16 Jun 2023 15:06:59 +0100 Subject: Reset using only co-de Bruijn syntax. --- src/Thinning.idr | 566 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 331 insertions(+), 235 deletions(-) (limited to 'src/Thinning.idr') diff --git a/src/Thinning.idr b/src/Thinning.idr index d2d65df..1ba5eb0 100644 --- a/src/Thinning.idr +++ b/src/Thinning.idr @@ -1,246 +1,187 @@ +||| A setoid of context thinnings. module Thinning -import Data.Singleton -import Data.SnocList.Elem +import Control.Order +import Control.Relation +import Data.Either +import Data.Nat +import Syntax.PreorderReasoning + +import public Data.SnocList.Elem %prefix_record_projections off +infix 4 <~> + -- Definition ------------------------------------------------------------------ +||| An injective, order-preserving map from one context to another. public export data Thins : SnocList a -> SnocList a -> Type where - Empty : [<] `Thins` [<] - Drop : sx `Thins` sy -> sx `Thins` sy :< z - Keep : - (thin : sx `Thins` sy) -> - sx :< z `Thins` sy :< z + ||| Identity map. + Id : sx `Thins` sx + ||| Empty map. + Empty : [<] `Thins` sx + ||| Skips over an element in the target context. + Drop : sx `Thins` sy -> sx `Thins` sy :< y + ||| Extends both contexts with a new element. + Keep : sx `Thins` sy -> sx :< z `Thins` sy :< z %name Thins thin --- Utility --------------------------------------------------------------------- - -public export -data Len : SnocList a -> Type where - Z : Len [<] - S : Len sx -> Len (sx :< x) - -%name Len k, m, n - -%hint -public export -length : (sx : SnocList a) -> Len sx -length [<] = Z -length (sx :< x) = S (length sx) - -%hint +||| Apply a thinning to an element of the source context. export -lenAppend : Len sx -> Len sy -> Len (sx ++ sy) -lenAppend k Z = k -lenAppend k (S m) = S (lenAppend k m) - -%hint -public export -lenPred : Len (sx :< x) -> Len sx -lenPred (S k) = k - -export -Cast (Len sx) Nat where - cast Z = 0 - cast (S k) = S (cast k) - --- Smart Constructors ---------------------------------------------------------- - -export -empty : (len : Len sx) => [<] `Thins` sx -empty {len = Z} = Empty -empty {len = S k} = Drop empty - -public export -id : (len : Len sx) => sx `Thins` sx -id {len = Z} = Empty -id {len = S k} = Keep id - -public export -point : Len sx => Elem ty sx -> [ Elem z sx -> Elem z sy +index : sx `Thins` sy -> Elem x sx -> Elem x sy +index Id i = i index (Drop thin) i = There (index thin i) index (Keep thin) Here = Here index (Keep thin) (There i) = There (index thin i) +||| An equivalence relation on thinnings. Two thinnings are equal if they have +||| the same action on elements. public export -(.) : sy `Thins` sz -> sx `Thins` sy -> sx `Thins` sz -Empty . thin1 = thin1 -Drop thin2 . thin1 = Drop (thin2 . thin1) -Keep thin2 . Drop thin1 = Drop (thin2 . thin1) -Keep thin2 . Keep thin1 = Keep (thin2 . thin1) +record (<~>) (thin1, thin2 : sx `Thins` sy) where + constructor MkEquivalence + equiv : forall x. (i : Elem x sx) -> index thin1 i = index thin2 i -export -(++) : sx `Thins` sy -> sz `Thins` sw -> sx ++ sz `Thins` sy ++ sw -thin2 ++ Empty = thin2 -thin2 ++ (Drop thin1) = Drop (thin2 ++ thin1) -thin2 ++ (Keep thin1) = Keep (thin2 ++ thin1) +%name (<~>) prf --- Commuting Triangles and Coverings ------------------------------------------- +--- Properties -data Triangle : sy `Thins` sz -> sx `Thins` sy -> sx `Thins` sz -> Type where - EmptyAny : Triangle Empty thin1 thin1 - DropAny : Triangle thin2 thin1 thin -> Triangle (Drop thin2) thin1 (Drop thin) - KeepDrop : Triangle thin2 thin1 thin -> Triangle (Keep thin2) (Drop thin1) (Drop thin) - KeepKeep : Triangle thin2 thin1 thin -> Triangle (Keep thin2) (Keep thin1) (Keep thin) +-- Relational -public export -data Overlap = Covers | Partitions +export +irrelevantEquiv : + {0 thin1, thin2 : sx `Thins` sy} -> + (0 prf : thin1 <~> thin2) -> + thin1 <~> thin2 +irrelevantEquiv prf = MkEquivalence (\i => irrelevantEq $ prf.equiv i) -namespace Covering - public export - data Covering : Overlap -> sx `Thins` sz -> sy `Thins` sz -> Type where - EmptyEmpty : Covering ov Empty Empty - DropKeep : Covering ov thin1 thin2 -> Covering ov (Drop thin1) (Keep thin2) - KeepDrop : Covering ov thin1 thin2 -> Covering ov (Keep thin1) (Drop thin2) - KeepKeep : Covering Covers thin1 thin2 -> Covering Covers (Keep thin1) (Keep thin2) +export +Reflexive (sx `Thins` sy) (<~>) where + reflexive = MkEquivalence (\i => Refl) -public export -record Coproduct {sx, sy, sz : SnocList a} (thin1 : sx `Thins` sz) (thin2 : sy `Thins` sz) where - constructor MkCoprod - {0 sw : SnocList a} - {thin1' : sx `Thins` sw} - {thin2' : sy `Thins` sw} - {thin : sw `Thins` sz} - 0 left : Triangle thin thin1' thin1 - 0 right : Triangle thin thin2' thin2 - 0 cover : Covering Covers thin1' thin2' +export +Symmetric (sx `Thins` sy) (<~>) where + symmetric prf = MkEquivalence (\i => sym $ prf.equiv i) export -coprod : (thin1 : sx `Thins` sz) -> (thin2 : sy `Thins` sz) -> Coproduct thin1 thin2 -coprod Empty Empty = MkCoprod EmptyAny EmptyAny EmptyEmpty -coprod (Drop thin1) (Drop thin2) = - { left $= DropAny, right $= DropAny } (coprod thin1 thin2) -coprod (Drop thin1) (Keep thin2) = - { left $= KeepDrop, right $= KeepKeep, cover $= DropKeep } (coprod thin1 thin2) -coprod (Keep thin1) (Drop thin2) = - { left $= KeepKeep, right $= KeepDrop, cover $= KeepDrop } (coprod thin1 thin2) -coprod (Keep thin1) (Keep thin2) = - { left $= KeepKeep, right $= KeepKeep, cover $= KeepKeep } (coprod thin1 thin2) +Transitive (sx `Thins` sy) (<~>) where + transitive prf1 prf2 = MkEquivalence (\i => trans (prf1.equiv i) (prf2.equiv i)) --- Splitting off Contexts ------------------------------------------------------ +export +Equivalence (sx `Thins` sy) (<~>) where -public export -data Split : (global, local : SnocList a) -> (thin : sx `Thins` global ++ local) -> Type where - MkSplit : - (thin2 : sx `Thins` global) -> - (thin1 : used `Thins` local) -> - Split global local (thin2 ++ thin1) +export +Preorder (sx `Thins` sy) (<~>) where -public export -split : Len local -> (thin : sx `Thins` global ++ local) -> Split global local thin -split Z thin = MkSplit thin Empty -split (S k) (Drop thin) with (split k thin) - split (S k) (Drop .(thin2 ++ thin1)) | MkSplit thin2 thin1 = MkSplit thin2 (Drop thin1) -split (S k) (Keep thin) with (split k thin) - split (S k) (Keep .(thin2 ++ thin1)) | MkSplit thin2 thin1 = MkSplit thin2 (Keep thin1) +export +dropCong : thin1 <~> thin2 -> Drop thin1 <~> Drop thin2 +dropCong prf = MkEquivalence (\i => cong There $ prf.equiv i) --- Thinned Things -------------------------------------------------------------- +export +keepCong : thin1 <~> thin2 -> Keep thin1 <~> Keep thin2 +keepCong prf = MkEquivalence + (\i => + case i of + Here => Refl + There i => cong There $ prf.equiv i) -public export -record Thinned (T : SnocList a -> Type) (sx : SnocList a) where - constructor Over - {0 support : SnocList a} - value : T support - thin : support `Thins` sx +-- Indexing -public export -record OverlapPair (overlap : Overlap) (T, U : SnocList a -> Type) (sx : SnocList a) where - constructor MakePair - left : Thinned T sx - right : Thinned U sx - 0 cover : Covering overlap left.thin right.thin +export +indexId : (i : Elem x sx) -> index Id i = i +indexId i = Refl -public export -Pair : (T, U : SnocList a -> Type) -> SnocList a -> Type -Pair = OverlapPair Covers +export +indexDrop : + (thin : sx `Thins` sy) -> + (i : Elem x sx) -> + index (Drop thin) i = There (index thin i) +indexDrop thin i = Refl -public export -MkPair : Thinned t sx -> Thinned u sx -> Thinned (OverlapPair Covers t u) sx -MkPair (t `Over` thin1) (u `Over` thin2) = - let cp = coprod thin1 thin2 in - MakePair (t `Over` cp.thin1') (u `Over` cp.thin2') cp.cover `Over` cp.thin +export +indexKeepHere : (thin : sx `Thins` sy) -> index (Keep thin) Here = Here +indexKeepHere thin = Refl -public export -record Binds (local : SnocList a) (T : SnocList a -> Type) (sx : SnocList a) where - constructor MakeBound - {0 used : SnocList a} - value : T (sx ++ used) - thin : used `Thins` local +export +indexKeepThere : + (thin : sx `Thins` sy) -> + (i : Elem x sx) -> + index (Keep thin) (There i) = There (index thin i) +indexKeepThere thin i = Refl -public export -MkBound : Len local -> Thinned t (sx ++ local) -> Thinned (Binds local t) sx -MkBound k (value `Over` thin) with (split k thin) - MkBound k (value `Over` .(thin2 ++ thin1)) | MkSplit thin2 thin1 = - MakeBound value thin1 `Over` thin2 +-- Other -public export -map : (forall ctx. t ctx -> u ctx) -> Thinned t ctx -> Thinned u ctx -map f (value `Over` thin) = f value `Over` thin +thinToEmpty : sx `Thins` [<] -> sx = [<] +thinToEmpty Id = Refl +thinToEmpty Empty = Refl -public export -drop : Thinned t sx -> Thinned t (sx :< x) -drop (value `Over` thin) = value `Over` Drop thin +0 thinLen : sx `Thins` sy -> length sx `LTE` length sy +thinLen Id = reflexive +thinLen Empty = LTEZero +thinLen (Drop thin) = lteSuccRight (thinLen thin) +thinLen (Keep thin) = LTESucc (thinLen thin) -public export -wkn : Thinned t sx -> sx `Thins` sy -> Thinned t sy -wkn (value `Over` thin) thin' = value `Over` thin' . thin +idUnique' : (thin : sx `Thins` sx) -> (i : Elem x sx) -> index thin i = i +idUnique' Id i = Refl +idUnique' (Drop thin) i = void $ LTEImpliesNotGT (thinLen thin) reflexive +idUnique' (Keep thin) Here = Refl +idUnique' (Keep thin) (There i) = cong There $ idUnique' thin i --- Properties ------------------------------------------------------------------ +export +idUnique : (thin1, thin2 : sx `Thins` sx) -> thin1 <~> thin2 +idUnique thin1 thin2 = + MkEquivalence + (\i => trans (idUnique' thin1 i) (sym $ idUnique' thin2 i)) export -lenUnique : (k, m : Len sx) -> k = m -lenUnique Z Z = Refl -lenUnique (S k) (S m) = cong S (lenUnique k m) +emptyUnique : (thin1, thin2 : [<] `Thins` sx) -> thin1 <~> thin2 +emptyUnique thin1 thin2 = MkEquivalence (\i => absurd i) +-- Smart Constructors ---------------------------------------------------------- + +||| Point map. The representable thinning of an element. export -emptyUnique : (thin1, thin2 : [<] `Thins` sx) -> thin1 = thin2 -emptyUnique Empty Empty = Refl -emptyUnique (Drop thin1) (Drop thin2) = cong Drop (emptyUnique thin1 thin2) +Point : Elem x sx -> [ (thin : sx `Thins` sy) -> id @{len} . thin = thin -identityLeft {len = Z} thin = Refl -identityLeft {len = S k} (Drop thin) = cong Drop (identityLeft thin) -identityLeft {len = S k} (Keep thin) = cong Keep (identityLeft thin) +indexPoint : (i : Elem x sx) -> index (Point i) Here = i +indexPoint Here = Refl +indexPoint (There i) = cong There $ indexPoint i export -identityRight : (len : Len sx) => (thin : sx `Thins` sy) -> thin . id @{len} = thin -identityRight {len = Z} Empty = Refl -identityRight (Drop thin) = cong Drop (identityRight thin) -identityRight {len = S k} (Keep thin) = cong Keep (identityRight thin) +pointCong : {0 i, j : Elem x sx} -> i = j -> Point i <~> Point j +pointCong prf = MkEquivalence (\Here => cong (\i => index (Point i) Here) prf) export -identitySquared : (len : Len sx) -> id @{len} . id @{len} = id @{len} -identitySquared Z = Refl -identitySquared (S k) = cong Keep (identitySquared k) +dropPoint : (i : Elem x sx) -> Drop (Point i) <~> Point (There i) +dropPoint i = MkEquivalence (\Here => Refl) export -assoc : - (thin3 : sz `Thins` sw) -> - (thin2 : sy `Thins` sz) -> - (thin1 : sx `Thins` sy) -> - thin3 . (thin2 . thin1) = (thin3 . thin2) . thin1 -assoc Empty thin2 thin1 = Refl -assoc (Drop thin3) thin2 thin1 = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) (Drop thin2) thin1 = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) (Keep thin2) (Drop thin1) = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) (Keep thin2) (Keep thin1) = cong Keep (assoc thin3 thin2 thin1) +keepEmptyIsPoint : Keep Empty <~> Point Here +keepEmptyIsPoint = MkEquivalence (\Here => Refl) +-- Operations ------------------------------------------------------------------ + +||| Composition of two thinnings. export -indexId : (len : Len sx) => (i : Elem x sx) -> index (id @{len}) i = i -indexId {len = S k} Here = Refl -indexId {len = S k} (There i) = cong There (indexId i) +(.) : sy `Thins` sz -> sx `Thins` sy -> sx `Thins` sz +Id . thin1 = thin1 +Empty . Id = Empty +Empty . Empty = Empty +Drop thin2 . Id = Drop thin2 +Drop thin2 . Empty = Empty +Drop thin2 . Drop thin1 = Drop (thin2 . Drop thin1) +Drop thin2 . Keep thin1 = Drop (thin2 . Keep thin1) +Keep thin2 . Id = Keep thin2 +Keep thin2 . Empty = Empty +Keep thin2 . Drop thin1 = Drop (thin2 . thin1) +Keep thin2 . Keep thin1 = Keep (thin2 . thin1) + +--- Properties export indexHomo : @@ -248,69 +189,224 @@ indexHomo : (thin1 : sx `Thins` sy) -> (i : Elem x sx) -> index thin2 (index thin1 i) = index (thin2 . thin1) i +indexHomo Id thin1 i = Refl +indexHomo Empty Id i impossible indexHomo Empty Empty i impossible -indexHomo (Drop thin2) thin1 i = cong There (indexHomo thin2 thin1 i) -indexHomo (Keep thin2) (Drop thin1) i = cong There (indexHomo thin2 thin1 i) +indexHomo (Drop thin2) Id i = Refl +indexHomo (Drop thin2) (Drop thin1) i = cong There $ indexHomo thin2 (Drop thin1) i +indexHomo (Drop thin2) (Keep thin1) i = cong There $ indexHomo thin2 (Keep thin1) i +indexHomo (Keep thin2) Id i = Refl +indexHomo (Keep thin2) (Drop thin1) i = cong There $ indexHomo thin2 thin1 i indexHomo (Keep thin2) (Keep thin1) Here = Refl -indexHomo (Keep thin2) (Keep thin1) (There i) = cong There (indexHomo thin2 thin1 i) +indexHomo (Keep thin2) (Keep thin1) (There i) = cong There $ indexHomo thin2 thin1 i --- Objects +-- Categorical export -indexPoint : (len : Len sx) => (i : Elem x sx) -> index (point @{len} i) Here = i -indexPoint Here = Refl -indexPoint (There i) = cong There (indexPoint i) +identityLeft : (thin : sx `Thins` sy) -> Id . thin <~> thin +identityLeft thin = reflexive export -MkTriangle : - (thin2 : sy `Thins` sz) -> - (thin1 : sx `Thins` sy) -> - Triangle thin2 thin1 (thin2 . thin1) -MkTriangle Empty thin1 = EmptyAny -MkTriangle (Drop thin2) thin1 = DropAny (MkTriangle thin2 thin1) -MkTriangle (Keep thin2) (Drop thin1) = KeepDrop (MkTriangle thin2 thin1) -MkTriangle (Keep thin2) (Keep thin1) = KeepKeep (MkTriangle thin2 thin1) +identityRight : (thin : sx `Thins` sy) -> thin . Id <~> thin +identityRight Id = reflexive +identityRight Empty = reflexive +identityRight (Drop thin) = reflexive +identityRight (Keep thin) = reflexive export -triangleCorrect : Triangle thin2 thin1 thin -> thin2 . thin1 = thin -triangleCorrect EmptyAny = Refl -triangleCorrect (DropAny t) = cong Drop (triangleCorrect t) -triangleCorrect (KeepDrop t) = cong Drop (triangleCorrect t) -triangleCorrect (KeepKeep t) = cong Keep (triangleCorrect t) +assoc : + (thin3 : sz `Thins` sw) -> + (thin2 : sy `Thins` sz) -> + (thin1 : sx `Thins` sy) -> + thin3 . (thin2 . thin1) <~> (thin3 . thin2) . thin1 +assoc thin3 thin2 thin1 = MkEquivalence (\i => Calc $ + |~ index (thin3 . (thin2 . thin1)) i + ~~ index thin3 (index (thin2 . thin1) i) ..<(indexHomo thin3 (thin2 . thin1) i) + ~~ index thin3 (index thin2 (index thin1 i)) ..<(cong (index thin3) $ indexHomo thin2 thin1 i) + ~~ index (thin3 . thin2) (index thin1 i) ...(indexHomo thin3 thin2 (index thin1 i)) + ~~ index ((thin3 . thin2) . thin1) i ...(indexHomo (thin3 . thin2) thin1) i) -export -coprodEta : - {thin1 : sx `Thins` sz} -> - {thin2 : sy `Thins` sz} -> - (thin : sz `Thins` sw) -> - (cover : Covering Covers thin1 thin2) -> - coprod (thin . thin1) (thin . thin2) = - MkCoprod (MkTriangle thin thin1) (MkTriangle thin thin2) cover -coprodEta Empty EmptyEmpty = Refl -coprodEta (Drop thin) cover = rewrite coprodEta thin cover in Refl -coprodEta (Keep thin) (DropKeep cover) = rewrite coprodEta thin cover in Refl -coprodEta (Keep thin) (KeepDrop cover) = rewrite coprodEta thin cover in Refl -coprodEta (Keep thin) (KeepKeep cover) = rewrite coprodEta thin cover in Refl +-- Other export -dropIsWkn : (len : Len sx) => (v : Thinned t sx) -> drop {x} v = wkn v (Drop $ id @{len}) -dropIsWkn (value `Over` thin) = sym $ cong ((value `Over`) . Drop) $ identityLeft thin +dropLeft : + (thin2 : sy `Thins` sz) -> + (thin1 : sx `Thins` sy) -> + Drop thin2 . thin1 <~> Drop (thin2 . thin1) +dropLeft thin2 Id = symmetric $ dropCong $ identityRight thin2 +dropLeft thin2 Empty = emptyUnique Empty (Drop (thin2 . Empty)) +dropLeft thin2 (Drop thin1) = reflexive +dropLeft thin2 (Keep thin1) = reflexive export -wknId : (len : Len sx) => (v : Thinned t sx) -> wkn v (id @{len}) = v -wknId (value `Over` thin) = cong (value `Over`) $ identityLeft thin +keepDrop : + (thin2 : sy `Thins` sz) -> + (thin1 : sx `Thins` sy) -> + Keep thin2 . Drop thin1 <~> Drop (thin2 . thin1) +keepDrop thin2 thin1 = reflexive export -wknHomo : - (v : Thinned t sx) -> +keepHomo : (thin2 : sy `Thins` sz) -> (thin1 : sx `Thins` sy) -> - wkn (wkn v thin1) thin2 = wkn v (thin2 . thin1) -wknHomo (value `Over` thin) thin2 thin1 = cong (value `Over`) $ assoc thin2 thin1 thin + Keep thin2 . Keep thin1 <~> Keep (thin2 . thin1) +keepHomo thin2 thin1 = reflexive + +export +pointRight : + (thin : sx `Thins` sy) -> + (i : Elem x sx) -> + thin . Point i <~> Point (index thin i) +pointRight Id i = reflexive +pointRight (Drop thin) i = transitive (dropLeft thin (Point i)) (dropCong (pointRight thin i)) +pointRight (Keep thin) Here = keepCong (emptyUnique (thin . Empty) Empty) +pointRight (Keep thin) (There i) = dropCong (pointRight thin i) + +-- Coverings and Coproducts ---------------------------------------------------- -%hint +||| Proof that the thinnings are jointly surjective. +public export +record Covering (thin1 : sx `Thins` sz) (thin2 : sy `Thins` sz) where + constructor MkCovering + covers : + forall x. + (i : Elem x sz) -> + Either (j ** index thin1 j = i) (k ** index thin2 k = i) + +||| Unique thinning that factors into a covering. +public export +record Coproduct (thin1 : sx `Thins` sz) (thin2 : sy `Thins` sz) where + constructor MkCoproduct + {0 sw : SnocList _} + {thin1' : sx `Thins` sw} + {thin2' : sy `Thins` sw} + {factor : sw `Thins` sz} + 0 left : factor . thin1' <~> thin1 + 0 right : factor . thin2' <~> thin2 + 0 cover : Covering thin1' thin2' + +%name Covering cover +%name Coproduct cp + +--- Properties + +-- Coverings + +coverSym : Covering thin1 thin2 -> Covering thin2 thin1 +coverSym cover = MkCovering (\i => mirror $ cover.covers i) + +coverId : (0 thin : sx `Thins` sy) -> Covering Id thin +coverId thin = MkCovering (\i => Left (i ** Refl)) + +coverDropKeep : Covering thin1 thin2 -> Covering (Drop thin1) (Keep thin2) +coverDropKeep cover = MkCovering + (\i => case i of + Here => Right (Here ** Refl) + There i => case cover.covers i of + Left (j ** prf) => Left (j ** cong There prf) + Right (k ** prf) => Right (There k ** cong There prf)) + +coverKeepDrop : Covering thin1 thin2 -> Covering (Keep thin1) (Drop thin2) +coverKeepDrop cp = coverSym $ coverDropKeep $ coverSym cp + +coverKeepKeep : Covering thin1 thin2 -> Covering (Keep thin1) (Keep thin2) +coverKeepKeep cover = MkCovering + (\i => case i of + Here => Left (Here ** Refl) + There i => case cover.covers i of + Left (j ** prf) => Left (There j ** cong There prf) + Right (k ** prf) => Right (There k ** cong There prf)) + +-- Coproducts + +coprodSym : Coproduct thin1 thin2 -> Coproduct thin2 thin1 +coprodSym cp = MkCoproduct cp.right cp.left (coverSym cp.cover) + +coprodId : (thin : sx `Thins` sy) -> Coproduct Id thin +coprodId thin = + MkCoproduct + { thin1' = Id + , thin2' = thin + , factor = Id + , left = reflexive + , right = reflexive + , cover = coverId thin + } + +coprodEmpty : (thin : sx `Thins` sy) -> Coproduct Empty thin +coprodEmpty thin = + MkCoproduct + { thin1' = Empty + , thin2' = Id + , factor = thin + , left = emptyUnique (thin . Empty) Empty + , right = identityRight thin + , cover = coverSym $ coverId Empty + } + +||| Finds the coproduct of two thinnings. export -retractSingleton : Singleton sy -> sx `Thins` sy -> Singleton sx -retractSingleton s Empty = s -retractSingleton (Val (sy :< z)) (Drop thin) = retractSingleton (Val sy) thin -retractSingleton (Val (sy :< z)) (Keep thin) = pure (:< z) <*> retractSingleton (Val sy) thin +coprod : + (thin1 : sx `Thins` sz) -> + (thin2 : sy `Thins` sz) -> + Coproduct thin1 thin2 +coprod Id thin2 = coprodId thin2 +coprod Empty thin2 = coprodEmpty thin2 +coprod (Drop thin1) Id = coprodSym $ coprodId (Drop thin1) +coprod (Drop thin1) Empty = coprodSym $ coprodEmpty (Drop thin1) +coprod (Drop thin1) (Drop thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = cp.thin1' + , thin2' = cp.thin2' + , factor = Drop cp.factor + , left = transitive (dropLeft cp.factor cp.thin1') (dropCong cp.left) + , right = transitive (dropLeft cp.factor cp.thin2') (dropCong cp.right) + , cover = cp.cover + } +coprod (Drop thin1) (Keep thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = Drop cp.thin1' + , thin2' = Keep cp.thin2' + , factor = Keep cp.factor + , left = transitive (keepDrop cp.factor cp.thin1') (dropCong cp.left) + , right = transitive (keepHomo cp.factor cp.thin2') (keepCong cp.right) + , cover = coverDropKeep cp.cover + } +coprod (Keep thin1) Id = coprodSym $ coprodId (Keep thin1) +coprod (Keep thin1) Empty = coprodSym $ coprodEmpty (Keep thin1) +coprod (Keep thin1) (Drop thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = Keep cp.thin1' + , thin2' = Drop cp.thin2' + , factor = Keep cp.factor + , left = transitive (keepHomo cp.factor cp.thin1') (keepCong cp.left) + , right = transitive (keepDrop cp.factor cp.thin2') (dropCong cp.right) + , cover = coverKeepDrop cp.cover + } +coprod (Keep thin1) (Keep thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = Keep cp.thin1' + , thin2' = Keep cp.thin2' + , factor = Keep cp.factor + , left = transitive (keepHomo cp.factor cp.thin1') (keepCong cp.left) + , right = transitive (keepHomo cp.factor cp.thin2') (keepCong cp.right) + , cover = coverKeepKeep cp.cover + } + +-- Coproduct Equivalence ------------------------------------------------------- + +namespace Coproduct + public export + data (<~>) : + {0 thin1 : sx `Thins` sa} -> + {0 thin2 : sy `Thins` sa} -> + {0 thin3 : sz `Thins` sa} -> + {0 thin4 : sw `Thins` sa} -> + Coproduct thin1 thin2 -> + Coproduct thin3 thin4 -> + Type + where -- cgit v1.2.3