@@ -1,13 +1,299 @@
2−empty = []
2+module Map (empty,singleton,insert,lookup,remove,member,fold) where
3−singleton k v = [(k,v)]
4−insert k v dict = (k,v):dict
6−fst pair = let (a,b) = pair in a
4+import Data.Maybe (isJust)
8−member key = exists (\pair -> fst pair == key)
6+data NColor = Red | Black
10−delete key = filter (\pair -> fst pair == key)
8+data RBTree k v = Node NColor k v (RBTree k v) (RBTree k v) | Empty
11−intersect d1 d2 = filter (\pair -> member (fst pair) d2) d1
9+
12−difference d1 d2 = filter (\pair -> not (member (fst pair) d2)) d1
10+raise = console.log
13−union d1 d2 = d1 ++ difference d2 d1
11+
14+-- Helpers for checking invariants
16+-- Check that the tree has an equal number of black nodes on each path
18+ let path_numBlacks t =
21+ ; Node col _ _ l r ->
22+ let { bl = path_numBlacks l ; br = path_numBlacks r } in
23+ if bl /= br || bl == 0-1 || br == 0-1
25+ else bl + (if col == Red then 0 else 1)
27+ in 0-1 /= path_numBlacks t
32+ ; Node Black _ _ _ _ -> True
37+ { Node Red _ _ (Node Red _ _ _ _) _ -> False
38+ ; Node Red _ _ _ (Node Red _ _ _ _) -> False
40+ ; Node _ _ _ l r -> redBlack_children l && redBlack_children r
47+ case findExtreme f (f (l,r)) of
49+ ; Just k' -> Just k' }
52+findminRbt t = findExtreme fst t
53+findmaxRbt t = findExtreme snd t
56+-- Returns True if either xo or yo is Nothing
57+-- Otherwise returns the result of comparing the values using f
59+optionRelation f u xo yo =
63+ ; (Just x, Just y) -> f x y }
65+olt xo yo = optionRelation (< ) True xo yo
66+olte xo yo = optionRelation (<=) True xo yo
72+ let (lmax,rmin) = (findmaxRbt l, findminRbt r) in
73+ olte lmax (Just k) && olte (Just k) rmin && ordered l && ordered r
76+-- Check that there aren't any right red nodes in the tree *)
80+ ; Node _ _ _ (Node Black _ _ _ _) (Node Red _ _ _ _) -> False
81+ ; Node _ _ _ Empty (Node Red _ _ _ _) -> False
82+ ; Node _ _ _ l r -> (leftLeaning l) && (leftLeaning r)
86+ ordered t && rootBlack t && redBlack_children t &&
87+ equal_pathLen t && leftLeaning t
89+--** End invariant helpers *****
94+ { Node _ k v Empty _ -> (k,v)
95+ ; Node _ _ _ l _ -> min l
96+ ; Empty -> console.log "(min Empty) is not defined"
101+ { Node _ k v _ Empty -> (k,v)
102+ ; Node _ _ _ _ r -> max r
103+ ; Empty -> console.log "(max Empty) is not defined"
109+ ; Node _ k' v l r ->
110+ case compare k k' of
113+ ; GT -> lookup k r }
117+member k t = isJust $ lookup k t
121+ { Node cy ky vy a (Node cz kz vz b c) -> Node cy kz vz (Node Red ky vy a b) c
122+ ; _ -> raise "rotateLeft of a node without enough children" }
124+-- rotateRight -- the reverse, and
125+-- makes Y have Z's color, and makes Z Red.
128+ { Node cz kz vz (Node cy ky vy a b) c -> Node cz ky vy a (Node Red kz vz b c)
129+ ; _ -> raise "rotateRight of a node without enough children" }
131+rotateLeftIfNeeded t =
133+ { Node _ _ _ _ (Node Red _ _ _ _) -> rotateLeft t
136+rotateRightIfNeeded t =
138+ { Node _ _ _ (Node Red _ _ (Node Red _ _ _ _) _) _ -> rotateRight t
141+otherColor c = case c of { Red -> Black ; Black -> Red }
145+ { Node c1 bk bv (Node c2 ak av la ra) (Node c3 ck cv lc rc) ->
146+ Node (otherColor c1) bk bv
147+ (Node (otherColor c2) ak av la ra)
148+ (Node (otherColor c3) ck cv lc rc)
149+ ; _ -> raise "color_flip called on a Empty or Node with a Empty child" }
151+color_flipIfNeeded t =
153+ { Node _ _ _ (Node Red _ _ _ _) (Node Red _ _ _ _) -> color_flip t
156+fixUp t = color_flipIfNeeded (rotateRightIfNeeded (rotateLeftIfNeeded t))
161+ { Node Red k v l r -> Node Black k v l r
164+-- Invariant: t is a valid left-leaning rb tree *)
168+ { Empty -> Node Red k v Empty Empty
169+ ; Node c k' v' l r ->
170+ let h = case compare k k' of
171+ { LT -> Node c k' v' (ins l) r
172+ ; EQ -> Node c k' v l r -- replace
173+ ; GT -> Node c k' v' l (ins r) }
175+ in if not (invariants_hold t) then
176+ raise "invariants broken before insert"
177+ else (let new_t = ensureBlackRoot (ins t) in
178+ if not (invariants_hold new_t) then
179+ raise "invariants broken after insert"
182+singleton k v = insert k v Empty
187+ { Node Red _ _ _ _ -> True
192+ { Node _ _ _ (Node Red _ _ _ _) _ -> True
197+ { Node _ _ _ (Node _ _ _ (Node Red _ _ _ _) _) _ -> True
202+ { Node _ _ _ _ (Node Red _ _ _ _) -> True
207+ { Node _ _ _ _ (Node _ _ _ (Node Red _ _ _ _) _) -> True
212+ let t' = color_flip t in
216+ { Node _ _ _ (Node Red _ _ _ _) _ ->
217+ color_flip (rotateLeft (Node c k v l (rotateRight r)))
222+ let t' = color_flip t in
223+ if isRedLeftLeft t' then color_flip (rotateRight t') else t'
225+moveRedLeftIfNeeded t =
226+ if not (isRedLeft t) && not (isRedLeftLeft t)
230+moveRedRightIfNeeded t =
231+ if not (isRedRight t) && not (isRedRightLeft t)
238+ { Node _ _ _ Empty _ -> Empty
239+ ; _ -> let t' = moveRedLeftIfNeeded t in
241+ { Node c k v l r -> fixUp (Node c k v (del l) r)
244+ in ensureBlackRoot (del t)
248+ let t' = if isRedLeft t then rotateRight t else t in
250+ { Node _ _ _ _ Empty -> Empty
251+ ; _ -> let t'' = moveRedRightIfNeeded t' in
253+ { Node c k v l r -> fixUp (Node c k v l (del r))
254+ ; Empty -> Empty } }
255+ in ensureBlackRoot (del t)
259+ eq_and_noRightNode t = case t of { Node _ k' _ _ Empty -> k == k' ; _ -> False }
260+ ; eq t = case t of { Node _ k' _ _ _ -> k == k' ; _ -> False }
262+ let t' = moveRedLeftIfNeeded t in
264+ { Node c k' v l r -> fixUp (Node c k' v (del l) r)
265+ ; Empty -> raise "delLT on Empty" }
267+ case t of -- Replace with successor
269+ let (k',v') = min r in
270+ fixUp (Node c k' v' l (deleteMin r))
271+ ; Empty -> raise "delEQ called on a Empty" }
274+ { Node c k' v l r -> fixUp (Node c k' v l (del r))
275+ ; Empty -> raise "delGT called on a Empty" }
279+ ; Node _ k' _ _ _ ->
280+ if k < k' then delLT t
281+ else (let t' = if isRedLeft t then rotateRight t else t in
282+ if eq_and_noRightNode t' then Empty
283+ else (let t = moveRedRightIfNeeded t in
284+ if eq t then delEQ t else delGT t)) }
286+ in if not (invariants_hold t) then
287+ raise "invariants broken before remove"
288+ else (let t' = ensureBlackRoot (del t) in
289+ if invariants_hold t' then t' else
290+ raise "invariants broken after remove")
295+ ; Node _ k v l r -> fold f (f k v (fold f acc l)) r