@@ -11,14 +11,15 @@ module Dict (empty,singleton,insert
1111import Maybe as Maybe
1212import Native.Error as Error
1313import List as List
14+import Native.Utils (compare)
1415
1516data NColor = Red | Black
1617
17−data Dict k v = Node NColor k v (Dict k v) (Dict k v) | Empty
18+data Dict k v = RBNode NColor k v (Dict k v) (Dict k v) | RBEmpty
1819
1920-- Create an empty dictionary.
20−empty : Dict k v
21−empty = Empty
21+empty : Dict (Comparable k) v
22+empty = RBEmpty
2223
2324{-- Helpers for checking invariants
2425
@@ -26,33 +27,32 @@ empty = Empty
2627equal_pathLen t =
2728 let path_numBlacks t =
2829 case t of
29− { Empty -> 1
30− ; Node col _ _ l r ->
30+ RBEmpty -> 1
31+ RBNode col _ _ l r ->
3132 let { bl = path_numBlacks l ; br = path_numBlacks r } in
3233 if bl /= br || bl == 0-1 || br == 0-1
3334 then 0-1
3435 else bl + (if col == Red then 0 else 1)
35− }
3636 in 0-1 /= path_numBlacks t
3737
3838rootBlack t =
3939 case t of
40− { Empty -> True
41− ; Node Black _ _ _ _ -> True
42− ; _ -> False }
40+ RBEmpty -> True
41+ RBNode Black _ _ _ _ -> True
42+ _ -> False
4343
4444redBlack_children t =
4545 case t of
46− { Node Red _ _ (Node Red _ _ _ _) _ -> False
47− ; Node Red _ _ _ (Node Red _ _ _ _) -> False
48− ; Empty -> True
49− ; Node _ _ _ l r -> redBlack_children l && redBlack_children r
46+ { RBNode Red _ _ (RBNode Red _ _ _ _) _ -> False
47+ ; RBNode Red _ _ _ (RBNode Red _ _ _ _) -> False
48+ ; RBEmpty -> True
49+ ; RBNode _ _ _ l r -> redBlack_children l && redBlack_children r
5050 }
5151
5252findExtreme f t =
5353 case t of
54− { Empty -> Nothing
55− ; Node c k _ l r ->
54+ { RBEmpty -> Nothing
55+ ; RBNode c k _ l r ->
5656 case findExtreme f (f (l,r)) of
5757 { Nothing -> Just k
5858 ; Just k' -> Just k' }
@@ -76,8 +76,8 @@ olte xo yo = optionRelation (<=) True xo yo
7676
7777ordered t =
7878 case t of
79− { Empty -> True
80− ; Node c k v l r ->
79+ { RBEmpty -> True
80+ ; RBNode c k v l r ->
8181 let (lmax,rmin) = (findmaxRbt l, findminRbt r) in
8282 olte lmax (Just k) && olte (Just k) rmin && ordered l && ordered r
8383 }
@@ -85,10 +85,10 @@ ordered t =
8585-- Check that there aren't any right red nodes in the tree *)
8686leftLeaning t =
8787 case t of
88− { Empty -> True
89− ; Node _ _ _ (Node Black _ _ _ _) (Node Red _ _ _ _) -> False
90− ; Node _ _ _ Empty (Node Red _ _ _ _) -> False
91− ; Node _ _ _ l r -> (leftLeaning l) && (leftLeaning r)
88+ { RBEmpty -> True
89+ ; RBNode _ _ _ (RBNode Black _ _ _ _) (RBNode Red _ _ _ _) -> False
90+ ; RBNode _ _ _ RBEmpty (RBNode Red _ _ _ _) -> False
91+ ; RBNode _ _ _ l r -> (leftLeaning l) && (leftLeaning r)
9292 }
9393
9494invariants_hold t =
@@ -102,36 +102,37 @@ invariants_hold t =
102102min : Dict k v -> (k,v)
103103min t =
104104 case t of
105− Node _ k v Empty _ -> (k,v)
106− Node _ _ _ l _ -> min l
107− Empty -> Error.raise "(min Empty) is not defined"
105+ RBNode _ k v RBEmpty _ -> (k,v)
106+ RBNode _ _ _ l _ -> min l
107+ RBEmpty -> Error.raise "(min Empty) is not defined"
108108
109109{--
110110max t =
111111 case t of
112− { Node _ k v _ Empty -> (k,v)
113− ; Node _ _ _ _ r -> max r
114− ; Empty -> Error.raise "(max Empty) is not defined"
112+ { RBNode _ k v _ RBEmpty -> (k,v)
113+ ; RBNode _ _ _ _ r -> max r
114+ ; RBEmpty -> Error.raise "(max Empty) is not defined"
115115 }
116116--}
117117
118118-- Lookup the value associated with a key.
119−lookup : k -> Dict k v -> Maybe v
119+lookup : Comparable k -> Dict (Comparable k) v -> Maybe v
120120lookup k t =
121121 case t of
122− Empty -> Nothing
123− Node _ k' v l r ->
122+ RBEmpty -> Nothing
123+ RBNode _ k' v l r ->
124124 case compare k k' of
125125 LT -> lookup k l
126126 EQ -> Just v
127127 GT -> lookup k r
128128
129−-- Find the value associated with a key. If the key is not found, return the default value.
130−findWithDefault : v -> k -> Dict k v -> v
129+-- Find the value associated with a key. If the key is not found,
130+-- return the default value.
131+findWithDefault : v -> Comparable k -> Dict (Comparable k) v -> v
131132findWithDefault base k t =
132133 case t of
133− Empty -> base
134− Node _ k' v l r ->
134+ RBEmpty -> base
135+ RBNode _ k' v l r ->
135136 case compare k k' of
136137 LT -> findWithDefault base k l
137138 EQ -> v
@@ -141,8 +142,8 @@ findWithDefault base k t =
141142-- Find the value associated with a key. If the key is not found, there will be a runtime error.
142143find k t =
143144 case t of
144− { Empty -> Error.raise "Key was not found in dictionary!"
145− ; Node _ k' v l r ->
145+ { RBEmpty -> Error.raise "Key was not found in dictionary!"
146+ ; RBNode _ k' v l r ->
146147 case compare k k' of
147148 { LT -> find k l
148149 ; EQ -> v
@@ -151,14 +152,14 @@ find k t =
151152--}
152153
153154-- Determine if a key is in a dictionary.
154−member : k -> Dict k v -> Bool
155+member : Comparable k -> Dict (Comparable k) v -> Bool
155156-- Does t contain k?
156157member k t = Maybe.isJust $ lookup k t
157158
158159rotateLeft : Dict k v -> Dict k v
159160rotateLeft t =
160161 case t of
161− Node cy ky vy a (Node cz kz vz b c) -> Node cy kz vz (Node Red ky vy a b) c
162+ RBNode cy ky vy a (RBNode cz kz vz b c) -> RBNode cy kz vz (RBNode Red ky vy a b) c
162163 _ -> Error.raise "rotateLeft of a node without enough children"
163164
164165-- rotateRight -- the reverse, and
@@ -166,19 +167,19 @@ rotateLeft t =
166167rotateRight : Dict k v -> Dict k v
167168rotateRight t =
168169 case t of
169− Node cz kz vz (Node cy ky vy a b) c -> Node cz ky vy a (Node Red kz vz b c)
170+ RBNode cz kz vz (RBNode cy ky vy a b) c -> RBNode cz ky vy a (RBNode Red kz vz b c)
170171 _ -> Error.raise "rotateRight of a node without enough children"
171172
172173rotateLeftIfNeeded : Dict k v -> Dict k v
173174rotateLeftIfNeeded t =
174175 case t of
175− Node _ _ _ _ (Node Red _ _ _ _) -> rotateLeft t
176+ RBNode _ _ _ _ (RBNode Red _ _ _ _) -> rotateLeft t
176177 _ -> t
177178
178179rotateRightIfNeeded : Dict k v -> Dict k v
179180rotateRightIfNeeded t =
180181 case t of
181− Node _ _ _ (Node Red _ _ (Node Red _ _ _ _) _) _ -> rotateRight t
182+ RBNode _ _ _ (RBNode Red _ _ (RBNode Red _ _ _ _) _) _ -> rotateRight t
182183 _ -> t
183184
184185otherColor c = case c of { Red -> Black ; Black -> Red }
@@ -186,16 +187,16 @@ otherColor c = case c of { Red -> Black ; Black -> Red }
186187color_flip : Dict k v -> Dict k v
187188color_flip t =
188189 case t of
189− Node c1 bk bv (Node c2 ak av la ra) (Node c3 ck cv lc rc) ->
190− Node (otherColor c1) bk bv
191− (Node (otherColor c2) ak av la ra)
192− (Node (otherColor c3) ck cv lc rc)
190+ RBNode c1 bk bv (RBNode c2 ak av la ra) (RBNode c3 ck cv lc rc) ->
191+ RBNode (otherColor c1) bk bv
192+ (RBNode (otherColor c2) ak av la ra)
193+ (RBNode (otherColor c3) ck cv lc rc)
193194 _ -> Error.raise "color_flip called on a Empty or Node with a Empty child"
194195
195196color_flipIfNeeded : Dict k v -> Dict k v
196197color_flipIfNeeded t =
197198 case t of
198− Node _ _ _ (Node Red _ _ _ _) (Node Red _ _ _ _) -> color_flip t
199+ RBNode _ _ _ (RBNode Red _ _ _ _) (RBNode Red _ _ _ _) -> color_flip t
199200 _ -> t
200201
201202fixUp t = color_flipIfNeeded (rotateRightIfNeeded (rotateLeftIfNeeded t))
@@ -203,21 +204,21 @@ fixUp t = color_flipIfNeeded (rotateRightIfNeeded (rotateLeftIfNeeded t))
203204ensureBlackRoot : Dict k v -> Dict k v
204205ensureBlackRoot t =
205206 case t of
206− Node Red k v l r -> Node Black k v l r
207+ RBNode Red k v l r -> RBNode Black k v l r
207208 _ -> t
208209
209−-- Insert a key-value pair into a dictionary. Replaces value when there is a collision.
210−-- Invariant: t is a valid left-leaning rb tree *)
211−insert : k -> v -> Dict k v -> Dict k v
212−insert k v t =
210+-- Insert a key-value pair into a dictionary. Replaces value when there is
211+-- a collision.
212+insert : Comparable k -> v -> Dict (Comparable k) v -> Dict (Comparable k) v
213+insert k v t = -- Invariant: t is a valid left-leaning rb tree
213214 let ins t =
214215 case t of
215− Empty -> Node Red k v Empty Empty
216− Node c k' v' l r ->
216+ RBEmpty -> RBNode Red k v RBEmpty RBEmpty
217+ RBNode c k' v' l r ->
217218 let h = case compare k k' of
218− LT -> Node c k' v' (ins l) r
219− EQ -> Node c k' v l r -- replace
220− GT -> Node c k' v' l (ins r)
219+ LT -> RBNode c k' v' (ins l) r
220+ EQ -> RBNode c k' v l r -- replace
221+ GT -> RBNode c k' v' l (ins r)
221222 in fixUp h
222223 in ensureBlackRoot (ins t)
223224{--
@@ -230,47 +231,47 @@ insert k v t =
230231--}
231232
232233-- Create a dictionary with one key-value pair.
233−singleton : k -> v -> Dict k v
234−singleton k v = insert k v Empty
234+singleton : Comparable k -> v -> Dict (Comparable k) v
235+singleton k v = insert k v RBEmpty
235236
236237isRed : Dict k v -> Bool
237238isRed t =
238239 case t of
239− Node Red _ _ _ _ -> True
240+ RBNode Red _ _ _ _ -> True
240241 _ -> False
241242
242243isRedLeft : Dict k v -> Bool
243244isRedLeft t =
244245 case t of
245− Node _ _ _ (Node Red _ _ _ _) _ -> True
246+ RBNode _ _ _ (RBNode Red _ _ _ _) _ -> True
246247 _ -> False
247248
248249isRedLeftLeft : Dict k v -> Bool
249250isRedLeftLeft t =
250251 case t of
251− Node _ _ _ (Node _ _ _ (Node Red _ _ _ _) _) _ -> True
252+ RBNode _ _ _ (RBNode _ _ _ (RBNode Red _ _ _ _) _) _ -> True
252253 _ -> False
253254
254255isRedRight : Dict k v -> Bool
255256isRedRight t =
256257 case t of
257− Node _ _ _ _ (Node Red _ _ _ _) -> True
258+ RBNode _ _ _ _ (RBNode Red _ _ _ _) -> True
258259 _ -> False
259260
260261isRedRightLeft : Dict k v -> Bool
261262isRedRightLeft t =
262263 case t of
263− Node _ _ _ _ (Node _ _ _ (Node Red _ _ _ _) _) -> True
264+ RBNode _ _ _ _ (RBNode _ _ _ (RBNode Red _ _ _ _) _) -> True
264265 _ -> False
265266
266267moveRedLeft : Dict k v -> Dict k v
267268moveRedLeft t =
268269 let t' = color_flip t in
269270 case t' of
270− Node c k v l r ->
271+ RBNode c k v l r ->
271272 case r of
272− Node _ _ _ (Node Red _ _ _ _) _ ->
273− color_flip (rotateLeft (Node c k v l (rotateRight r)))
273+ RBNode _ _ _ (RBNode Red _ _ _ _) _ ->
274+ color_flip (rotateLeft (RBNode c k v l (rotateRight r)))
274275 _ -> t'
275276 _ -> t'
276277
@@ -291,10 +292,10 @@ deleteMin : Dict k v -> Dict k v
291292deleteMin t =
292293 let del t =
293294 case t of
294− Node _ _ _ Empty _ -> Empty
295+ RBNode _ _ _ RBEmpty _ -> RBEmpty
295296 _ -> case moveRedLeftIfNeeded t of
296− Node c k v l r -> fixUp (Node c k v (del l) r)
297− Empty -> Empty
297+ RBNode c k v l r -> fixUp (RBNode c k v (del l) r)
298+ RBEmpty -> RBEmpty
298299 in ensureBlackRoot (del t)
299300
300301{--
@@ -302,36 +303,37 @@ deleteMax t =
302303 let del t =
303304 let t' = if isRedLeft t then rotateRight t else t in
304305 case t' of
305− { Node _ _ _ _ Empty -> Empty
306+ { RBNode _ _ _ _ RBEmpty -> RBEmpty
306307 ; _ -> let t'' = moveRedRightIfNeeded t' in
307308 case t'' of
308− { Node c k v l r -> fixUp (Node c k v l (del r))
309− ; Empty -> Empty } }
309+ { RBNode c k v l r -> fixUp (RBNode c k v l (del r))
310+ ; RBEmpty -> RBEmpty } }
310311 in ensureBlackRoot (del t)
311312--}
312313
313−-- Remove a key-value pair from a dictionary. If the key is not found, no changes are made.
314−remove : k -> Dict k v -> Dict k v
314+-- Remove a key-value pair from a dictionary. If the key is not found,
315+-- no changes are made.
316+remove : Comparable k -> Dict (Comparable k) v -> Dict (Comparable k) v
315317remove k t =
316318 let eq_and_noRightNode t =
317− case t of { Node _ k' _ _ Empty -> k == k' ; _ -> False }
318− eq t = case t of { Node _ k' _ _ _ -> k == k' ; _ -> False }
319+ case t of { RBNode _ k' _ _ RBEmpty -> k == k' ; _ -> False }
320+ eq t = case t of { RBNode _ k' _ _ _ -> k == k' ; _ -> False }
319321 delLT t = case moveRedLeftIfNeeded t of
320− Node c k' v l r -> fixUp (Node c k' v (del l) r)
321− Empty -> Error.raise "delLT on Empty"
322+ RBNode c k' v l r -> fixUp (RBNode c k' v (del l) r)
323+ RBEmpty -> Error.raise "delLT on Empty"
322324 delEQ t = case t of -- Replace with successor
323− Node c _ _ l r -> let (k',v') = min r in
324− fixUp (Node c k' v' l (deleteMin r))
325− Empty -> Error.raise "delEQ called on a Empty"
325+ RBNode c _ _ l r -> let (k',v') = min r in
326+ fixUp (RBNode c k' v' l (deleteMin r))
327+ RBEmpty -> Error.raise "delEQ called on a Empty"
326328 delGT t = case t of
327− Node c k' v l r -> fixUp (Node c k' v l (del r))
328− Empty -> Error.raise "delGT called on a Empty"
329+ RBNode c k' v l r -> fixUp (RBNode c k' v l (del r))
330+ RBEmpty -> Error.raise "delGT called on a Empty"
329331 del t = case t of
330− Empty -> Empty
331− Node _ k' _ _ _ ->
332+ RBEmpty -> RBEmpty
333+ RBNode _ k' _ _ _ ->
332334 if k < k' then delLT t else
333335 let u = if isRedLeft t then rotateRight t else t in
334− if eq_and_noRightNode u then Empty else
336+ if eq_and_noRightNode u then RBEmpty else
335337 let t' = moveRedRightIfNeeded t in
336338 if eq t' then delEQ t' else delGT t'
337339 in if member k t then ensureBlackRoot (del t) else t
@@ -344,52 +346,58 @@ remove k t =
344346--}
345347
346348-- Apply a function to all values in a dictionary.
347−map : (a -> b) -> Dict k a -> Dict k b
349+map : (a -> b) -> Dict (Comparable k) a -> Dict (Comparable k) b
348350map f t =
349351 case t of
350− Empty -> Empty
351− Node c k v l r -> Node c k (f v) (map f l) (map f r)
352+ RBEmpty -> RBEmpty
353+ RBNode c k v l r -> RBNode c k (f v) (map f l) (map f r)
352354
353−-- Fold over the key-value pairs in a dictionary, in order from lowest key to highest key.
354−foldl : (k -> v -> b -> b) -> b -> Dict k v -> b
355+-- Fold over the key-value pairs in a dictionary, in order from lowest
356+-- key to highest key.
357+foldl : (Comparable k -> v -> b -> b) -> b -> Dict (Comparable k) v -> b
355358foldl f acc t =
356359 case t of
357− Empty -> acc
358− Node _ k v l r -> foldl f (f k v (foldl f acc l)) r
360+ RBEmpty -> acc
361+ RBNode _ k v l r -> foldl f (f k v (foldl f acc l)) r
359362
360−-- Fold over the key-value pairs in a dictionary, in order from highest key to lowest key.
361−foldr : (k -> v -> b -> b) -> b -> Dict k v -> b
363+-- Fold over the key-value pairs in a dictionary, in order from highest
364+-- key to lowest key.
365+foldr : (Comparable k -> v -> b -> b) -> b -> Dict (Comparable k) v -> b
362366foldr f acc t =
363367 case t of
364− Empty -> acc
365− Node _ k v l r -> foldr f (f k v (foldr f acc r)) l
368+ RBEmpty -> acc
369+ RBNode _ k v l r -> foldr f (f k v (foldr f acc r)) l
366370
367−-- Combine two dictionaries. If there is a collision, preference is given to the first dictionary.
368−union : Dict k v -> Dict k v -> Dict k v
371+-- Combine two dictionaries. If there is a collision, preference is given
372+-- to the first dictionary.
373+union : Dict (Comparable k) v -> Dict (Comparable k) v -> Dict (Comparable k) v
369374union t1 t2 = foldl insert t2 t1
370375
371−-- Keep a key-value pair when its key appears in the second dictionary. Preference is given to values in the first dictionary.
372−intersect : Dict k v -> Dict k v -> Dict k v
376+-- Keep a key-value pair when its key appears in the second dictionary.
377+-- Preference is given to values in the first dictionary.
378+intersect : Dict (Comparable k) v
379+ -> Dict (Comparable k) v -> Dict (Comparable k) v
373380intersect t1 t2 =
374381 let combine k v t = if k `member` t2 then insert k v t else t
375382 in foldl combine empty t1
376383
377−-- Keep a key-value pair when its key does not appear in the second dictionary. Preference is given to the first dictionary.
378−diff : Dict k v -> Dict k v -> Dict k v
384+-- Keep a key-value pair when its key does not appear in the second dictionary.
385+-- Preference is given to the first dictionary.
386+diff : Dict (Comparable k) v -> Dict (Comparable k) v -> Dict (Comparable k) v
379387diff t1 t2 = foldl (\k v t -> remove k t) t1 t2
380388
381389-- Get all of the keys in a dictionary.
382−keys : Dict k v -> [k]
390+keys : Dict (Comparable k) v -> [Comparable k]
383391keys t = foldr (\k v acc -> k :: acc) [] t
384392
385393-- Get all of the values in a dictionary.
386−values : Dict k v -> [v]
394+values : Dict (Comparable k) v -> [v]
387395values t = foldr (\k v acc -> v :: acc) [] t
388396
389397-- Convert a dictionary into an association list of key-value pairs.
390−toList : Dict k v -> [(k,v)]
398+toList : Dict (Comparable k) v -> [(Comparable k,v)]
391399toList t = foldr (\k v acc -> (k,v) :: acc) [] t
392400
393401-- Convert an association list into a dictionary.
394−fromList : [(k,v)] -> Dict k v
395−fromList assocs = List.foldl (uncurry insert) empty assocs
402+fromList : [(Comparable k,v)] -> Dict (Comparable k) v
403+fromList assocs = List.foldl (\(k,v) d -> insert k v d) empty assocs