7 | module Data.OpenUnion
10 | import Data.List.AtIndex
11 | import Data.List.HasLength
13 | import Data.Nat.Order.Properties
14 | import Decidable.Equality
15 | import Syntax.WithProof
26 | data UnionT : (elt : a -> Type) -> (ts : List a) -> Type where
27 | Element : (k : Nat) -> (0 _ : AtIndex t ts k) -> elt t -> UnionT elt ts
32 | Union : List Type -> Type
33 | Union = UnionT Prelude.id
37 | Uninhabited (UnionT elt []) where
38 | uninhabited (Element _ p _) = void (uninhabited p)
43 | inj : (k : Nat) -> (0 _ : AtIndex t ts k) -> elt t -> UnionT elt ts
50 | prj : (k : Nat) -> (0 _ : AtIndex t ts k) -> UnionT elt ts -> Maybe (elt t)
51 | prj k p (Element k' q t) with (decEq k k')
52 | prj k p (Element k q t) | Yes Refl = rewrite atIndexUnique p q in Just t
53 | prj k p (Element k' q t) | No neq = Nothing
58 | split : Subset Nat (flip HasLength ss) ->
59 | UnionT elt (ss ++ ts) -> Either (UnionT elt ss) (UnionT elt ts)
60 | split m (Element n p t) with (@@ lt n (fst m))
61 | split m (Element n p t) | (
True ** lt)
62 | = Left (Element n (strengthenL m lt p) t)
63 | split m (Element n p t) | (
False ** notlt)
64 | = let 0 lte : lte (fst m) n === True
65 | = LteIslte (fst m) n (notltIsGTE n (fst m) notlt)
66 | in Right (Element (minus n (fst m)) (strengthenR m lte p) t)
72 | decomp : UnionT elt (t :: ts) -> Either (UnionT elt ts) (elt t)
73 | decomp (Element 0 (Z) t) = Right t
74 | decomp (Element (S n) (S p) t) = Left (Element n p t)
78 | decomp0 : UnionT elt [t] -> elt t
79 | decomp0 elt = case decomp elt of
85 | weakenR : UnionT elt ts -> UnionT elt (ts ++ us)
86 | weakenR (Element n p t) = Element n (weakenR p) t
92 | weakenL : Subset Nat (flip HasLength ss) -> UnionT elt ts -> UnionT elt (ss ++ ts)
93 | weakenL m (Element n p t) = Element (fst m + n) (weakenL m p) t