6 | module Data.List.Fresh
8 | import public Data.So
10 | %hide Builtin.infixr.(#)
17 | BRel a = a -> a -> Bool
19 | export infix 4 #
, ##
, #?
22 | data FreshList : (a : Type) -> (neq : BRel a) -> Type
26 | (##) : {neq : BRel a} -> (x : a) -> (xs : FreshList a neq) -> Bool
29 | (#) : {neq : BRel a} -> (x : a) -> (xs : FreshList a neq) -> Type
32 | data FreshList : (a : Type) -> (neq : BRel a) -> Type where
33 | Nil : FreshList a neq
34 | (::) : (x : a) -> (xs : FreshList a neq) ->
35 | {auto 0 fresh : x # xs} ->
38 | %name FreshList
xs, ys, zs
41 | x ## (y :: xs) = (x `neq` y) && (x ## xs)
43 | x # xs = So (x ## xs)
45 | namespace FreshList1
48 | data FreshList1 : (a : Type) -> (neq : BRel a) -> Type where
49 | (::) : (x : a) -> (xs : FreshList a neq) ->
50 | {auto 0 fresh : x # xs} ->
54 | {0 A : Type} {0 Aneq : BRel A}
55 | {0 B : Type} {0 Bneq : BRel B}
57 | (Injectivity : (x,y : A) -> So (x `Aneq` y) -> So (F x `Bneq` F y))
60 | map : FreshList A Aneq -> FreshList B Bneq
63 | 0 mapFreshness : {x : A} -> (ys : FreshList A Aneq) ->
64 | x # ys -> F x # map ys
67 | map ((x :: xs) {fresh}) = (F x :: map xs) {fresh = mapFreshness xs fresh}
71 | mapFreshness (y :: ys) p
72 | = let (x_fresh_y, x_fresh_ys) = soAnd p in
73 | andSo (Injectivity _ _ x_fresh_y, mapFreshness ys x_fresh_ys)
77 | data Empty : FreshList a neq -> Type where
81 | data NonEmpty : FreshList a neq -> Type where
82 | IsNonEmpty : NonEmpty ((x :: xs) {fresh})
85 | length : FreshList a neq -> Nat
87 | length (x :: xs) = 1 + length xs
90 | fromMaybe : Maybe a -> FreshList a neq
91 | fromMaybe Nothing = []
92 | fromMaybe (Just x) = [x]
98 | uncons : FreshList a neq -> Maybe (a , FreshList a neq)
100 | uncons (x :: xs) = Just (x, xs)
103 | toFreshList1 : FreshList a neq -> Maybe (FreshList1 a neq)
104 | toFreshList1 [] = Nothing
105 | toFreshList1 (x :: xs) = Just (x :: xs)
108 | head : (xs : FreshList a neq) -> (isNonEmpty : NonEmpty xs) => a
109 | head (x :: xs) {isNonEmpty = IsNonEmpty} = x
112 | tail : (xs : FreshList a neq) -> (isNonEmpty : NonEmpty xs) => FreshList a neq
113 | tail (x :: xs) {isNonEmpty = IsNonEmpty} = xs
116 | 0 (.freshness) : (xs : FreshList a neq) -> (isNonEmpty : NonEmpty xs) =>
118 | (((x :: xs) {fresh}).freshness) {isNonEmpty = IsNonEmpty} = fresh
121 | parameters (0 x : a) (ys : FreshList a neq) {auto isNonEmpty : NonEmpty ys}
123 | 0 headFreshness : x # ys -> So (x `neq` head ys)
126 | 0 tailFreshness : x # ys -> x # (tail ys)
128 | headFreshness x (y :: ys) {isNonEmpty = IsNonEmpty} freshness
129 | = fst (soAnd freshness)
130 | tailFreshness x (y :: ys) {isNonEmpty = IsNonEmpty} freshness
131 | = snd (soAnd freshness)
134 | take : Nat -> FreshList a neq -> FreshList a neq
136 | 0 takeFreshness : (n : Nat) -> (xs : FreshList a neq) -> y # xs -> y # take n xs
140 | take (S n) ((x :: xs) {fresh}) = (x :: take n xs) {fresh = takeFreshness n xs fresh}
142 | takeFreshness 0 xs fresh = Oh
143 | takeFreshness (S n) [] fresh = Oh
144 | takeFreshness (S n) (x :: xs) fresh =
145 | let (y_neq_x, y_fresh_xs) = soAnd fresh in
146 | andSo (y_neq_x, takeFreshness n xs y_fresh_xs)
149 | drop : Nat -> FreshList a neq -> FreshList a neq
152 | drop (S n) (x :: xs) = drop n xs
159 | takeWhile : (pred : a -> Bool) -> FreshList a neq -> FreshList a neq
161 | 0 takeWhileFreshness : (pred : a -> Bool) -> (xs : FreshList a neq) ->
162 | y # xs -> y # takeWhile pred xs
164 | takeWhile pred [] = []
165 | takeWhile pred ((x :: xs) {fresh}) = case pred x of
166 | True => (x :: takeWhile pred xs) {fresh = takeWhileFreshness pred xs fresh}
169 | takeWhileFreshness pred [] fresh
171 | takeWhileFreshness pred (x :: xs) fresh with (pred x)
172 | takeWhileFreshness pred (x :: xs) fresh | True
173 | = let (y_fresh_x, y_fresh_xs) = soAnd fresh in
174 | andSo (y_fresh_x, takeWhileFreshness pred xs y_fresh_xs)
175 | takeWhileFreshness pred (x :: xs) fresh | False
179 | dropWhile : (pred : a -> Bool) -> FreshList a neq -> FreshList a neq
182 | 0 dropWhileFreshness : (pred : a -> Bool) -> (xs : FreshList a neq) ->
183 | y # xs -> y # dropWhile pred xs
186 | dropWhile pred [] = []
187 | dropWhile pred ((x :: xs) {fresh}) = case pred x of
188 | True => (x :: dropWhile pred xs) {fresh = dropWhileFreshness pred xs fresh}
191 | dropWhileFreshness pred [] fresh = Oh
192 | dropWhileFreshness pred (x :: xs) fresh with (pred x)
193 | dropWhileFreshness pred (x :: xs) fresh | False
195 | dropWhileFreshness pred (x :: xs) fresh | True
196 | = let (y_neq_x, y_fresh_xs) = soAnd fresh in
197 | andSo (y_neq_x, dropWhileFreshness pred xs y_fresh_xs)
200 | filter : (pred : a -> Bool) -> FreshList a neq -> FreshList a neq
202 | 0 filterFreshness : (pred : a -> Bool) -> (xs : FreshList a neq) ->
203 | y # xs -> y # filter pred xs
205 | filter pred [] = []
206 | filter pred ((x :: xs) {fresh}) = case pred x of
207 | False => filter pred xs
208 | True => (x :: filter pred xs) {fresh = filterFreshness pred xs fresh}
210 | filterFreshness pred [] fresh = Oh
211 | filterFreshness pred (x :: xs) fresh with (pred x)
212 | filterFreshness pred (x :: xs) fresh | False
213 | = let (y_neq_x, y_fresh_xs) = soAnd fresh in
214 | filterFreshness pred xs y_fresh_xs
215 | filterFreshness pred (x :: xs) fresh | True
216 | = let (y_neq_x, y_fresh_xs) = soAnd fresh in
217 | andSo (y_neq_x, filterFreshness pred xs y_fresh_xs)
221 | decideFreshness : {neq : BRel a} ->
222 | (x : a) -> (ys : FreshList a neq) ->
224 | decideFreshness x ys with (x ## ys)
225 | decideFreshness x ys | True = Yes Oh
226 | decideFreshness x ys | False = No absurd
229 | foldl : (f : b -> a -> b) -> b -> FreshList a neq -> b
231 | foldl f x (y :: ys) = foldl f (x `f` y) ys
234 | foldr : (f : a -> b -> b) -> b -> FreshList a neq -> b
236 | foldr f x (val :: vals) = (val `f` foldr f x vals)
245 | FreshSnoc : {a : Type} -> {neq : BRel a} -> SnocList a -> FreshList a neq -> Type
248 | castAux : (sx : SnocList a) -> (xs : FreshList a neq) ->
249 | {auto 0 fresh : FreshSnoc {neq} sx xs} -> FreshList a neq
253 | FreshSnoc [<] xs = ()
254 | FreshSnoc (sx :< x) xs = (fresh : x # xs ** FreshSnoc sx ((x :: xs) {fresh}))
256 | castAux [<] xs = xs
257 | castAux (sx :< x) xs {fresh}
258 | = castAux sx ((x :: xs) {fresh = fresh.fst}) {fresh = fresh.snd}
261 | Fresh : {a : Type} -> {neq : BRel a} -> SnocList a -> Type
262 | Fresh {neq} sx = FreshSnoc {neq} sx []
265 | cast : (sx : SnocList a) -> {auto 0 fresh : Fresh {neq} sx} -> FreshList a neq
266 | cast sx = castAux sx []