4 Author: Jean-Christophe FilliĆ¢tre (CNRS)
13 clone relations.TotalPreOrder with
14 type t = elt, predicate rel = le, axiom .
20 function occ elt t : int
22 predicate mem (x: elt) (t: t) = occ x t > 0
24 function minimum t : elt
26 predicate is_minimum (x: elt) (t: t) =
27 mem x t && forall e. mem e t -> le x e
30 forall t: t. 0 < size t -> is_minimum (minimum t) t
32 val constant empty : t
33 ensures { size result = 0 }
34 ensures { forall e. not (mem e result) }
37 ensures { result = size t }
39 val is_empty (t: t) : bool
40 ensures { result <-> size t = 0 }
42 val get_min (t: t) : elt
43 requires { 0 < size t }
44 ensures { result = minimum t }
46 val merge (t1 t2: t) : t
47 ensures { forall e. occ e result = occ e t1 + occ e t2 }
48 ensures { size result = size t1 + size t2 }
50 val add (x: elt) (t: t) : t
51 ensures { occ x result = occ x t + 1 }
52 ensures { forall e. e <> x -> occ e result = occ e t }
53 ensures { size result = size t + 1 }
55 val remove_min (t: t) : t
56 requires { 0 < size t }
57 ensures { occ (minimum t) result = occ (minimum t) t - 1 }
58 ensures { forall e. e <> minimum t -> occ e result = occ e t }
59 ensures { size result = size t - 1 }
67 use export bintree.Size
68 use export bintree.Occ
72 val predicate le elt elt
73 clone relations.TotalPreOrder with
74 type t = elt, predicate rel = le, axiom .
76 (* [e] is no greater than the root of [t], if any *)
77 predicate le_root (e: elt) (t: tree elt) = match t with
79 | Node _ x _ -> le e x
83 predicate heap (t: tree elt) = match t with
85 | Node l x r -> le_root x l && heap l && le_root x r && heap r
88 function minimum (tree elt) : elt
89 axiom minimum_def: forall l x r. minimum (Node l x r) = x
91 predicate is_minimum (x: elt) (t: tree elt) =
92 mem x t && forall e. mem e t -> le x e
94 (* the root is the smallest element *)
95 let rec lemma root_is_min (t: tree elt) : unit
96 requires { heap t && 0 < size t }
97 ensures { is_minimum (minimum t) t }
102 if not (is_empty l) then root_is_min l;
103 if not (is_empty r) then root_is_min r
106 let constant empty : tree elt = Empty
107 ensures { heap result }
108 ensures { size result = 0 }
109 ensures { forall e. not (mem e result) }
111 let get_min (t: tree elt) : elt
112 requires { heap t && 0 < size t }
113 ensures { result = minimum t }
120 let rec merge (t1 t2: tree elt) : tree elt
121 requires { heap t1 && heap t2 }
122 ensures { heap result }
123 ensures { forall e. occ e result = occ e t1 + occ e t2 }
124 ensures { size result = size t1 + size t2 }
125 variant { size t1 + size t2 }
130 | Node l1 x1 r1, Node l2 x2 r2 ->
132 Node (merge r1 t2) x1 l1
134 Node (merge r2 t1) x2 l2
137 let add (x: elt) (t: tree elt) : tree elt
139 ensures { heap result }
140 ensures { occ x result = occ x t + 1 }
141 ensures { forall e. e <> x -> occ e result = occ e t }
142 ensures { size result = size t + 1 }
144 merge (Node Empty x Empty) t
146 let remove_min (t: tree elt) : tree elt
147 requires { heap t && 0 < size t }
148 ensures { heap result }
149 ensures { occ (minimum t) result = occ (minimum t) t - 1 }
150 ensures { forall e. e <> minimum t -> occ e result = occ e t }
151 ensures { size result = size t - 1 }
155 | Node l _ r -> merge l r
165 use array.ArrayPermut
167 clone export array.Sorted with type elt = elt, predicate le = le, axiom .
173 let heapsort (a: array elt) : unit
175 ensures { permut_all (old a) a }
179 for i = 0 to n - 1 do
180 invariant { heap !t && size !t = i }
181 invariant { forall e.
182 M.occ e a.elts i n + H.occ e !t = M.occ e a.elts 0 n }
184 assert { M.occ a[i] a.elts i n = 1 + M.occ a[i] a.elts (i+1) n }
187 for i = 0 to n - 1 do
188 invariant { sorted_sub a 0 i }
189 invariant { heap !t && size !t = n - i }
190 invariant { forall j. 0 <= j < i -> forall e. mem e !t -> le a[j] e }
191 invariant { forall e.
192 M.occ e a.elts 0 i + H.occ e !t = M.occ e (a.elts at I) 0 n }