2 (** Pairing heaps (M. Fredman, R. Sedgewick, D. Sleator, R. Tarjan, 1986).
4 Purely applicative implementation, following Okasaki's implementation
5 in his book "Purely Functional Data Structures" (Section 5.5).
7 Author: Mário Pereira (Université Paris Sud)
15 val predicate le elt elt
17 clone relations.TotalPreOrder with
18 type t = elt, predicate rel = le, axiom .
22 function size heap : int
24 function occ elt heap : int
26 predicate mem (x: elt) (h: heap) = occ x h > 0
28 function minimum heap : elt
30 predicate is_minimum (x: elt) (h: heap) =
31 mem x h && forall e. mem e h -> le x e
34 forall h. 0 < size h -> is_minimum (minimum h) h
36 val constant empty : heap
37 ensures { size result = 0 }
38 ensures { forall x. occ x result = 0 }
40 val is_empty (h: heap) : bool
41 ensures { result <-> size h = 0 }
43 val size (h: heap) : int
44 ensures { result = size h }
46 val merge (h1 h2: heap) : heap
47 ensures { forall x. occ x result = occ x h1 + occ x h2 }
48 ensures { size result = size h1 + size h2 }
50 val insert (x: elt) (h: heap) : heap
51 ensures { occ x result = occ x h + 1 }
52 ensures { forall y. y <> x -> occ y h = occ y result }
53 ensures { size result = size h + 1 }
55 val find_min (h: heap) : elt
56 requires { size h > 0 }
57 ensures { result = minimum h }
59 val delete_min (h: heap) : heap
60 requires { size h > 0 }
61 ensures { let x = minimum h in occ x result = occ x h - 1 }
62 ensures { forall y. y <> minimum h -> occ y result = occ y h }
63 ensures { size result = size h - 1 }
73 type raw_heap = E | H tree
74 with tree = T elt (list tree)
84 function size_heap (h: raw_heap) : int = match h with
88 with size_tree (t: tree) : int = match t with
89 | T _ l -> 1 + size_list l
91 with size_list (l: list tree) : int = match l with
93 | Cons t l -> size_tree t + size_list l
96 let rec lemma size_nonneg (h: raw_heap)
97 ensures { size_heap h >= 0 }
101 | H t -> size_tree_nonneg t
103 with lemma size_tree_nonneg (t: tree)
104 ensures { size_tree t >= 0 }
106 = match t with T _ l -> size_list_nonneg l end
107 with lemma size_list_nonneg (l: list tree)
108 ensures { size_list l >= 0 }
113 size_tree_nonneg t; size_list_nonneg r
116 let lemma size_empty (h: raw_heap)
117 ensures { size_heap h = 0 <-> h = E }
120 | H t -> size_tree_nonneg t
131 function occ_heap (x: elt) (h: raw_heap) : int = match h with
133 | H t -> occ_tree x t
135 with occ_tree (x: elt) (t: tree) : int = match t with
136 | T e l -> (if x = e then 1 else 0) + occ_list x l
138 with occ_list (x: elt) (l: list tree) : int = match l with
140 | Cons t r -> occ_tree x t + occ_list x r
143 let rec lemma occ_nonneg (x: elt) (h: raw_heap)
144 ensures { occ_heap x h >= 0 }
148 | H t -> occ_tree_nonneg x t
150 with lemma occ_tree_nonneg (x: elt) (t: tree)
151 ensures { occ_tree x t >= 0 }
153 = match t with T _ l -> occ_list_nonneg x l end
154 with lemma occ_list_nonneg (x: elt) (l: list tree)
155 ensures { occ_list x l >= 0 }
160 occ_tree_nonneg x t; occ_list_nonneg x r
163 predicate mem (x: elt) (h: raw_heap) =
166 predicate mem_tree (x: elt) (t: tree) =
169 predicate mem_list (x: elt) (l: list tree) =
183 val predicate le elt elt
184 clone relations.TotalPreOrder with
185 type t = elt, predicate rel = le, axiom .
187 (* [e] is no greater than the root of [h], if any *)
188 predicate le_tree (e: elt) (t: tree) = match t with
192 predicate le_root (e: elt) (h: raw_heap) = match h with
198 forall x y h. le x y -> le_root y h -> le_root x h
200 (* [e] is no greater than the roots of the trees in [l] *)
201 predicate le_roots (e: elt) (l: list tree) = match l with
203 | Cons t r -> le_tree e t && le_roots e r
206 lemma le_roots_trans:
207 forall x y l. le x y -> le_roots y l -> le_roots x l
209 predicate heap (h: raw_heap) = match h with
213 with heap_tree (t: tree) = match t with
214 | T x l -> le_roots x l && heap_list l
216 with heap_list (l: list tree) = match l with
218 | Cons t r -> heap_tree t && heap_list r
221 type heap = { h: raw_heap }
225 function size (hh: heap) : int = size_heap hh.h
226 function occ (e: elt) (hh: heap) : int = occ_heap e hh.h
228 let rec lemma heap_mem (h: raw_heap)
231 ensures { forall x. le_root x h -> forall y. mem y h -> le x y }
234 | H t -> heap_mem_tree t
236 with heap_mem_tree (t: tree)
237 requires { heap_tree t }
239 ensures { forall x. le_tree x t -> forall y. mem_tree y t -> le x y }
240 = match t with T _ l -> heap_mem_list l end
241 with heap_mem_list (l: list tree)
242 requires { heap_list l }
244 ensures { forall x. le_roots x l -> forall y. mem_list y l -> le x y }
252 predicate is_minimum_tree (x: elt) (t: tree) =
253 mem_tree x t && forall e. mem_tree e t -> le x e
255 predicate is_minimum (x: elt) (h: raw_heap) =
256 mem x h && forall e. mem e h -> le x e
258 function minimum_tree tree : elt
259 axiom minimum_tree_def: forall x l. minimum_tree (T x l) = x
261 function minimum raw_heap : elt
262 axiom minimum_def: forall t. minimum (H t) = minimum_tree t
264 function minimum_heap (hh: heap) : elt =
267 let lemma root_is_minimum (h: raw_heap)
268 requires { 0 < size_heap h }
270 ensures { is_minimum (minimum h) h }
273 | H (T e l) -> occ_list_nonneg e l
276 let constant empty : heap = { h = E }
277 ensures { size_heap result.h = 0 }
278 ensures { forall e. not (mem e result.h) }
280 let is_empty (hh: heap) : bool
281 ensures { result <-> size_heap hh.h = 0 }
282 = match hh.h with E -> true | _ -> false end
284 let merge (h1 h2: heap) : heap
285 ensures { size_heap result.h = size_heap h1.h + size_heap h2.h }
286 ensures { forall x. occ_heap x result.h
287 = occ_heap x h1.h + occ_heap x h2.h }
288 = match h1.h, h2.h with
289 | E, h | h, E -> { h = h }
290 | H (T x1 l1), H (T x2 l2) ->
292 { h = H (T x1 (Cons (T x2 l2) l1)) }
294 { h = H (T x2 (Cons (T x1 l1) l2)) }
297 let insert (x: elt) (hh: heap) : heap
298 ensures { size_heap result.h = size_heap hh.h + 1 }
299 ensures { occ_heap x result.h = occ_heap x hh.h + 1 }
300 ensures { forall y. x <> y -> occ_heap y result.h = occ_heap y hh.h }
301 = merge { h = H (T x Nil) } hh
303 let find_min (hh: heap) : elt
304 requires { 0 < size_heap hh.h }
305 ensures { result = minimum hh.h }
311 let rec merge_pairs (l: list tree) : heap
312 requires { heap_list l }
313 ensures { size_heap result.h = size_list l }
314 ensures { forall x. occ_heap x result.h = occ_list x l }
318 | Cons t Nil -> { h = H t }
319 | Cons t1 (Cons t2 r) ->
320 let h1 = { h = H t1 } in
321 let h2 = { h = H t2 } in
322 merge (merge h1 h2) (merge_pairs r)
325 let delete_min (hh: heap) : heap
326 requires { 0 < size_heap hh.h }
327 ensures { occ_heap (minimum hh.h) result.h =
328 occ_heap (minimum hh.h) hh.h - 1 }
329 ensures { forall y. y <> minimum hh.h ->
330 occ_heap y result.h = occ_heap y hh.h }
331 ensures { size_heap result.h = size_heap hh.h - 1 }
346 type elt, type heap, val le,
347 function size, function occ,
348 function minimum = minimum_heap,
349 val empty, val is_empty, val merge,
350 val insert, val find_min, val delete_min