4 (* Red-black trees (data type) *)
9 type color = Red | Black
13 | Node color tree key value tree
15 (* occurrence of a key/value pair in a tree *)
17 predicate memt (t : tree) (k : key) (v : value) =
20 | Node _ l k' v' r -> (k = k' /\ v = v') \/ memt l k v \/ memt r k v
24 forall l r : tree, k k' : key, v v' : value, c c' : color.
25 memt (Node c l k v r) k' v' -> memt (Node c' l k v r) k' v'
27 (* binary search tree *)
31 predicate lt_tree (x : key) (t : tree) =
32 forall k : key. forall v : value. memt t k v -> k < x
34 predicate gt_tree (x : key) (t : tree) =
35 forall k : key. forall v : value. memt t k v -> x < k
37 lemma lt_leaf: forall x: key. lt_tree x Leaf
39 lemma gt_leaf: forall x: key. gt_tree x Leaf
42 forall x y: key, v: value, l r: tree, c: color.
43 lt_tree x l -> lt_tree x r -> y < x -> lt_tree x (Node c l y v r)
46 forall x y: key, v: value, l r: tree, c: color.
47 gt_tree x l -> gt_tree x r -> x < y -> gt_tree x (Node c l y v r)
50 forall x y: key, v: value, l r: tree, c: color.
51 lt_tree x (Node c l y v r) -> y < x
54 forall x y: key, v: value, l r: tree, c: color.
55 gt_tree x (Node c l y v r) -> x < y
58 forall x y: key, v: value, l r: tree, c : color.
59 lt_tree x (Node c l y v r) -> lt_tree x l
62 forall x y: key, v: value, l r: tree, c: color.
63 lt_tree x (Node c l y v r) -> lt_tree x r
66 forall x y: key, v: value, l r: tree, c: color.
67 gt_tree x (Node c l y v r) -> gt_tree x l
70 forall x y: key, v: value, l r: tree, c: color.
71 gt_tree x (Node c l y v r) -> gt_tree x r
74 forall x: key, t: tree. lt_tree x t -> forall v: value. not (memt t x v)
77 forall x y: key. x < y -> forall t: tree. lt_tree x t -> lt_tree y t
79 lemma gt_tree_not_in :
80 forall x: key, t: tree. gt_tree x t -> forall v: value. not (memt t x v)
83 forall x y: key. y < x -> forall t: tree. gt_tree x t -> gt_tree y t
85 predicate bst (t : tree) =
88 | Node _ l k _ r -> bst l /\ bst r /\ lt_tree k l /\ gt_tree k r
91 lemma bst_Leaf : bst Leaf
94 forall k: key, v: value, l r: tree, c: color. bst (Node c l k v r) -> bst l
97 forall k: key, v: value, l r: tree, c: color. bst (Node c l k v r) -> bst r
100 forall c c': color, k: key, v: value, l r: tree.
101 bst (Node c l k v r) -> bst (Node c' l k v r)
104 forall kx ky: key, vx vy: value, a b c: tree, c1 c2 c3 c4: color.
105 bst (Node c1 a kx vx (Node c2 b ky vy c)) ->
106 bst (Node c3 (Node c4 a kx vx b) ky vy c)
109 forall kx ky: key, vx vy: value, a b c: tree, c1 c2 c3 c4: color.
110 bst (Node c3 (Node c4 a kx vx b) ky vy c) ->
111 bst (Node c1 a kx vx (Node c2 b ky vy c))
113 (* [rbtree n t]: red black tree invariant
114 [t] is a properly balanced red-black tree, i.e. it
115 satisfies the following two invariants:
116 - a red node has no red son
117 - any path from the root to a leaf has exactly [n] black nodes
120 predicate is_not_red (t : tree) =
122 | Node Red _ _ _ _ -> false
123 | Leaf | Node Black _ _ _ _ -> true
126 predicate rbtree (n : int) (t : tree) =
130 | Node Red l _ _ r ->
131 rbtree n l /\ rbtree n r /\ is_not_red l /\ is_not_red r
132 | Node Black l _ _ r ->
133 rbtree (n-1) l /\ rbtree (n-1) r
140 forall k:key, v:value. rbtree 0 (Node Red Leaf k v Leaf)
143 forall x: key, v: value, l r: tree, c: color.
144 (exists n: int. rbtree n (Node c l x v r)) -> exists n: int. rbtree n l
147 forall x: key, v: value, l r: tree, c: color.
148 (exists n: int. rbtree n (Node c l x v r)) -> exists n: int. rbtree n r
154 let rec find (t : tree) (k : key) : value
157 ensures { memt t k result }
158 raises { Not_found -> forall v : value. not (memt t k v) }
160 | Leaf -> raise Not_found
163 else if k < k' then find l k
164 else (* k > k' *) find r k
169 (** `almost_rbtree n t`: `t` may have one red-red conflict at its root;
170 it satisfies `rbtree n` everywhere else *)
172 predicate almost_rbtree (n : int) (t : tree) =
176 | Node Red l _ _ r ->
177 rbtree n l /\ rbtree n r
178 | Node Black l _ _ r ->
179 rbtree (n-1) l /\ rbtree (n-1) r
182 lemma rbtree_almost_rbtree:
183 forall n: int, t: tree. rbtree n t -> almost_rbtree n t
185 lemma rbtree_almost_rbtree_ex:
187 (exists n: int. rbtree n s) -> exists n: int. almost_rbtree n s
189 lemma almost_rbtree_rbtree_black:
190 forall x: key, v: value, l r: tree, n: int.
191 almost_rbtree n (Node Black l x v r) -> rbtree n (Node Black l x v r)
193 (** `lbalance c x l r` acts as a black node constructor,
194 solving a possible red-red conflict on `l`, using the following
197 B (R (R a x b) y c) z d
198 B (R a x (R b y c)) z d -> R (B a x b) y (R c z d)
201 The result is not necessarily a black node. *)
203 let lbalance (l : tree) (k : key) (v : value) (r : tree)
204 requires { lt_tree k l /\ gt_tree k r /\ bst l /\ bst r }
205 ensures { bst result /\
206 (forall n : int. almost_rbtree n l -> rbtree n r -> rbtree (n+1) result)
208 forall k':key, v':value.
209 memt result k' v' <->
210 if k' = k then v' = v else (memt l k' v' \/ memt r k' v') }
212 | Node Red (Node Red a kx vx b) ky vy c
213 | Node Red a kx vx (Node Red b ky vy c) ->
214 Node Red (Node Black a kx vx b) ky vy (Node Black c k v r)
219 (** `rbalance l x r` is similar to `lbalance`, solving a possible red-red
220 conflict on `r`. The balancing schema is similar:
222 B a x (R (R b y c) z d)
223 B a x (R b y (R c z d)) -> R (B a x b) y (R c z d)
227 let rbalance (l : tree) (k : key) (v : value) (r : tree)
228 requires { lt_tree k l /\ gt_tree k r /\ bst l /\ bst r }
229 ensures { bst result /\
230 (forall n : int. almost_rbtree n r -> rbtree n l -> rbtree (n+1) result)
232 forall k':key, v':value.
233 memt result k' v' <->
234 if k' = k then v' = v else (memt l k' v' \/ memt r k' v') }
236 | Node Red (Node Red b ky vy c) kz vz d
237 | Node Red b ky vy (Node Red c kz vz d) ->
238 Node Red (Node Black l k v b) ky vy (Node Black c kz vz d)
243 (* `insert x s` inserts `x` in tree `s`, resulting in a possible top red-red
244 conflict when `s` is red. *)
246 let rec insert (t : tree) (k : key) (v : value) : tree
247 requires { bst t /\ exists n: int. rbtree n t }
249 ensures { bst result /\
250 (forall n : int. rbtree n t -> almost_rbtree n result /\
251 (is_not_red t -> rbtree n result)) /\
253 forall k':key, v':value.
254 memt result k' v' <-> if k' = k then v' = v else memt t k' v' }
257 Node Red Leaf k v Leaf
258 | Node Red l k' v' r ->
259 if k < k' then Node Red (insert l k v) k' v' r
260 else if k' < k then Node Red l k' v' (insert r k v)
261 else (* k = k' *) Node Red l k' v r
262 | Node Black l k' v' r ->
263 if k < k' then lbalance (insert l k v) k' v' r
264 else if k' < k then rbalance l k' v' (insert r k v)
265 else (* k = k' *) Node Black l k' v r
268 (* finally `add x s` calls `insert` and recolors the root as black *)
270 let add (t : tree) (k : key) (v : value) : tree
271 requires { bst t /\ exists n:int. rbtree n t }
272 ensures { bst result /\ (exists n:int. rbtree n result) /\
274 forall k':key, v':value.
275 memt result k' v' <-> if k' = k then v' = v else memt t k' v' }
276 = match insert t k v with
277 | Node _ l k' v' r -> Node Black l k' v' r
285 (* the VACID-0 interface = mutable map with default value*)
290 type rbt = (value, tree)
292 predicate inv (r : rbt) =
293 let (_, t) = r in bst t /\ exists n : int. rbtree n t
295 let function default (r : rbt) : value =
298 predicate mem (r : rbt) (k : key) (v : value) =
300 memt t k v \/ (v = d /\ forall v':value. not (memt t k v'))
303 ensures { inv !result /\
304 default !result = d /\
305 forall k:key, v:value. mem !result k v <-> v = d }
306 = let x = (d, Leaf) in ref x (* BUG: ref (d, Leaf) *)
308 let replace (m : ref rbt) k v
311 default !m = default (old !m) /\
312 forall k':key, v':value.
313 mem !m k' v' <-> if k' = k then v' = v else mem (old !m) k' v' }
317 let lookup (m : ref rbt) k
319 ensures { mem !m k result }
321 try find t k with Not_found -> d end
323 (* the easy way: implements `remove` using `replace` *)
324 let remove (m : ref rbt) k
327 default !m = default (old !m) /\
328 forall k':key, v':value.
329 mem !m k' v' <-> if k' = k then v' = default !m else mem (old !m) k' v' }
330 = replace m k (default !m)