0 | module Data.Unique.Vect
3 | import Decidable.Equality
6 | %hide Misc.NotElem.NotElem
15 | data UniqueVect : (0 n : Nat) -> (0 a : Type) -> DecEq a => Type where
16 | Nil : {0 a : Type} -> DecEq a => UniqueVect 0 a
17 | (::) : {0 a : Type} -> DecEq a =>
19 | (xs : UniqueVect n a) ->
20 | {auto prf : NotElem x xs} ->
25 | data NotElem : DecEq a => (x : a) -> (xs : UniqueVect n a) -> Type where
26 | NotInEmptyVect : DecEq a => (x : a) -> NotElem {a=a} x []
27 | NotInNonEmptyVect : (de : DecEq a) =>
29 | (xs : UniqueVect n a) ->
30 | (ne : NotElem x xs) ->
31 | (neq : IsNo (decEq x y)) =>
32 | (prf : NotElem y xs) =>
37 | data Elem : DecEq a => (x : a) -> (xs : UniqueVect n a) -> Type where
40 | {xs : UniqueVect k a} ->
41 | (prf : NotElem x xs) =>
45 | {xs : UniqueVect k a} ->
46 | (prf : NotElem y xs) =>
47 | (later : Elem x xs) ->
53 | data All : DecEq a => (0 p : a -> Type) -> UniqueVect rank a -> Type where
54 | Nil : DecEq a => {0 p : a -> Type} -> All p []
55 | (::) : DecEq a => {0 p : a -> Type} ->
57 | {0 xs : UniqueVect k a} ->
66 | {x : a} -> DecEq a => Uninhabited (Elem x []) where
67 | uninhabited Here
impossible
68 | uninhabited (There later
) impossible
72 | decElemInUniqueVect : DecEq a =>
73 | (x : a) -> (xs : UniqueVect n a) -> Dec (Elem x xs)
74 | decElemInUniqueVect x [] = No absurd
75 | decElemInUniqueVect x (y :: ys) = case decEq x y of
76 | Yes Refl => Yes Here
77 | No neq => case decElemInUniqueVect x ys of
78 | Yes prf => Yes $
There prf
79 | No nprf => No $
\case
81 | (There later) => nprf later
84 | notElem : DecEq a =>
86 | {xs : UniqueVect n a} ->
87 | Not (Elem x xs) -> NotElem x xs
88 | notElem {xs = []} f = NotInEmptyVect x
89 | notElem {xs = (y :: ys)} f with (decEq x y)
90 | _ | (Yes Refl) = absurd (f Here)
91 | _ | (No neq) = NotInNonEmptyVect
92 | {neq=(proofIneqIsNo neq)} ys (notElem (\e => f ?notElem_there
))
95 | toVect : DecEq a => UniqueVect n a -> Vect n a
97 | toVect (x :: xs) = x :: toVect xs
101 | fromVect : DecEq a => Vect n a -> (m : Nat ** UniqueVect m a)
102 | fromVect [] = (
0 ** [])
103 | fromVect (x :: xs) =
104 | let (
k ** t)
= fromVect xs
105 | in case decElemInUniqueVect x t of
106 | Yes prf => (
k ** t)
107 | No nprf => (
S k ** (::) x t {prf=notElem nprf})
111 | indexOf : DecEq a => {0 n : Nat} -> {0 xs : UniqueVect n a} ->
114 | indexOf (There later) = FS (indexOf later)
117 | length : DecEq a => UniqueVect n a -> Nat
119 | length (x :: xs) = 1 + length xs
124 | (xs : UniqueVect n a) ->
125 | (elem : Elem x xs) ->
126 | UniqueVect (n `minus` (finToNat (FS (indexOf elem)))) a
127 | drop {n=S k} (_ :: xs) Here = rewrite minusZeroRight k in xs
128 | drop (_ :: xs) (There later) = drop xs later
132 | Test1 : UniqueVect 5 String
133 | Test1 = ["a", "b", "c", "d", "e"]
136 | wher : Elem "c" Test1
137 | wher = There $
There $
Here
142 | removeIndex : DecEq a =>
144 | (xs : UniqueVect (S n) a) ->
147 | removeIndex (x :: xs) FZ = xs
148 | removeIndex {n = (S k)} (x :: xs) (FS i)
149 | = (::) x (removeIndex xs i) {prf=removingElemIsStillNotElem}
154 | removingElemIsStillNotElem : DecEq a =>
157 | {xs : UniqueVect (S n) a} ->
159 | (ne : NotElem x xs) =>
160 | NotElem x (removeIndex xs i)
161 | removingElemIsStillNotElem {xs = (_ :: _)} {ne = (NotInNonEmptyVect _ ne)} {i = FZ}
163 | removingElemIsStillNotElem {n = (S k)} {xs = (y :: ys)} {ne = (NotInNonEmptyVect ys ne)} {i = (FS j)}
164 | = NotInNonEmptyVect (removeIndex ys j) removingElemIsStillNotElem {prf=removingElemIsStillNotElem}
171 | notEqualNotElem : DecEq a =>
173 | (neq : IsNo (decEq x y)) ->
175 | notEqualNotElem _ = NotInNonEmptyVect [] (NotInEmptyVect x)
179 | notEqualNotElem2 : DecEq a =>
181 | (neq : IsNo (decEq x y)) ->
183 | notEqualNotElem2 neq = notEqualNotElem {x=y} {y=x} (isNoSym neq)
188 | numUnique : {n, m : Nat} -> DecEq a => UniqueVect n a -> UniqueVect m a -> Nat
190 | numUnique (x :: xs) ys = case decElemInUniqueVect x ys of
191 | Yes _ => numUnique xs ys
192 | No _ => 1 + numUnique xs ys
197 | numOverlap : {n, m : Nat} -> DecEq a =>
198 | UniqueVect n a -> UniqueVect m a -> Nat
199 | numOverlap [] ys = 0
200 | numOverlap (x :: xs) ys = case decElemInUniqueVect x ys of
201 | Yes _ => 1 + numOverlap xs ys
202 | No _ => numOverlap xs ys
207 | numSymmetricDifference : {n, m : Nat} -> DecEq a =>
208 | UniqueVect n a -> UniqueVect m a -> Nat
209 | numSymmetricDifference [] ys = m
210 | numSymmetricDifference (x :: xs) ys = case decElemInUniqueVect x ys of
212 | Yes Here => numSymmetricDifference xs (removeIndex ys FZ)
213 | Yes (There later) => numSymmetricDifference xs (removeIndex ys (FS (indexOf later)))
214 | No _ => 1 + numSymmetricDifference xs ys
217 | public export infixr 5 +++
222 | (xs : UniqueVect n a) ->
223 | (ys : UniqueVect m a) ->
224 | UniqueVect (numUnique xs ys) a
226 | (x :: xs) +++ ys with (decElemInUniqueVect x ys)
227 | _ | (Yes prf) = xs +++ ys
228 | _ | (No nprf) = (::) x (xs +++ ys) {prf=expandUnique {prfy=notElem nprf}}
232 | expandUnique : DecEq a =>
234 | {xs : UniqueVect n a} ->
235 | {ys : UniqueVect m a} ->
236 | (prfx : NotElem x xs) =>
237 | (prfy : NotElem x ys) =>
238 | NotElem x (xs +++ ys)
243 | intersect : DecEq a =>
244 | (xs : UniqueVect n a) ->
245 | (ys : UniqueVect m a) ->
246 | UniqueVect (numOverlap xs ys) a
247 | intersect [] ys = []
248 | intersect (x :: xs) ys with (decElemInUniqueVect x ys)
249 | _ | (Yes prf) = (::) x (intersect xs ys) {prf=notElemIntersect}
250 | _ | (No nprf) = intersect xs ys
255 | notElemIntersect : DecEq a =>
257 | {xs : UniqueVect n a} ->
258 | {ys : UniqueVect m a} ->
259 | (prfx : NotElem x xs) =>
260 | (prfy : Elem x ys) =>
261 | NotElem x (intersect xs ys)
267 | allElemIntersectFst : DecEq a =>
268 | (xs : UniqueVect n a) ->
269 | (ys : UniqueVect m a) ->
270 | All (\x => Elem x xs) (intersect xs ys)
271 | allElemIntersectFst = ?allElemIntersect_rhs
276 | allElemIntersectSnd : DecEq a =>
277 | (xs : UniqueVect n a) ->
278 | (ys : UniqueVect m a) ->
279 | All (\x => Elem x ys) (intersect xs ys)
280 | allElemIntersectSnd = ?allElemIntersect_rhs2
284 | symmetricDifference : DecEq a => {n, m : Nat} ->
285 | (xs : UniqueVect n a) ->
286 | (ys : UniqueVect m a) ->
287 | UniqueVect (numSymmetricDifference xs ys) a
288 | symmetricDifference [] ys = ys
289 | symmetricDifference (x :: xs) ys = ?symmetricDifference_rhs
299 | l1 : UniqueVect 3 String
300 | l1 = ["a", "b", "c"]
303 | l2 : UniqueVect 3 String
304 | l2 = ["c", "d", "e"]
307 | l3 : UniqueVect 5 String
311 | l4 : UniqueVect 1 String
312 | l4 = intersect l1 l2