2 (** Flexible arrays implemented with Braun trees.
5 - W. Braun, M. Rem, A logarithmic implementation of flexible arrays.
6 Memorandum MR83/4. Eindhoven University of Technology. 1983.
7 - Hoogerwoord, R. R. A logarithmic implementation of flexible arrays.
8 Conference on Mathematics of Program Construction. 1992.
9 - Chris Okasaki. Three Algorithms on Braun Trees (Functional Pearl)
10 J. Functional Programming 7 (6) 661–666. 1997
12 See also braun_trees.mlw for an implementation of priority queues using
13 Braun trees (and a proof that a Braun tree has logarithmic height).
15 Author: Jean-Christophe Filliâtre (CNRS)
18 (** First, we work on bare Braun trees *)
23 use int.ComputerDivision
24 use export bintree.Tree
25 use export bintree.Size
28 predicate braun (t: tree 'a) = match t with
30 | Node l _ r -> (size l = size r || size l = size r + 1) && braun l && braun r
33 let rec function get_tree (t: tree 'a) (i: int) : 'a
34 requires { 0 <= i < size t }
41 if mod i 2 = 1 then get_tree l (div i 2) else get_tree r (div i 2 - 1)
44 let rec function set_tree (t: tree 'a) (i: int) (v: 'a) : (r: tree 'a)
45 requires { 0 <= i < size t }
48 ensures { size r = size t }
50 ensures { get_tree r i = v }
51 ensures { forall j. 0 <= j < t.size -> j<>i -> get_tree r j = get_tree t j }
55 if i = 0 then Node l v r else
56 if mod i 2 = 1 then Node (set_tree l (div i 2) v) x r
57 else Node l x (set_tree r (div i 2 - 1) v)
60 let rec make_tree2 (n: int) (v: 'a) : (l: tree 'a, r: tree 'a)
63 ensures { size l = n+1 && size r = n }
64 ensures { braun l && braun r }
65 ensures { forall i. 0 <= i < size l -> get_tree l i = v }
66 ensures { forall i. 0 <= i < size r -> get_tree r i = v }
68 Node Empty v Empty, Empty
69 else if mod n 2 = 1 then
70 let l, r = make_tree2 (div n 2) v in
71 Node l v r, Node r v r
73 let l, r = make_tree2 (div n 2 - 1) v in
74 Node l v l, Node l v r
76 let make_tree (n: int) (v: 'a) : (r: tree 'a)
78 ensures { size r = n }
80 ensures { forall i. 0 <= i < size r -> get_tree r i = v }
81 = let _, r = make_tree2 n v in r
83 (* left insertion/removal *)
85 let rec cons_tree (v: 'a) (t: tree 'a) : (r: tree 'a)
88 ensures { size r = size t + 1 }
90 ensures { get_tree r 0 = v }
91 ensures { forall i. 0 <= i < size t -> get_tree r (i+1) = get_tree t i }
93 | Empty -> Node Empty v Empty
94 | Node l x r -> Node (cons_tree x r) v l
97 let rec tail_tree (t: tree 'a) : (r: tree 'a)
99 requires { size t > 0 }
101 ensures { size r = size t - 1 }
103 ensures { forall i. 0 < i < size t -> get_tree r (i-1) = get_tree t i }
106 | Node Empty _ Empty -> Empty
107 | Node l _ r -> Node r (get_tree l 0) (tail_tree l)
110 (* right insertion/removal *)
112 let rec snoc_tree (s: int) (t: tree 'a) (v: 'a) : (r: tree 'a)
114 requires { s = size t }
116 ensures { size r = size t + 1 }
118 ensures { forall i. 0 <= i < size t -> get_tree r i = get_tree t i }
119 ensures { get_tree r s = v }
121 | Empty -> Node Empty v Empty
122 | Node l x r -> if mod s 2 = 1 then Node (snoc_tree (div s 2) l v) x r
123 else Node l x (snoc_tree (div s 2 - 1) r v)
126 let rec liat_tree (s: int) (t: tree 'a) : (r: tree 'a)
128 requires { s = size t > 0 }
130 ensures { size r = size t - 1 }
132 ensures { forall i. 0 <= i < size r -> get_tree r i = get_tree t i }
135 | Node Empty _ Empty -> Empty
136 | Node l x r -> if mod s 2 = 0 then Node (liat_tree (div s 2) l) x r
137 else Node l x (liat_tree (div s 2) r)
140 (* TODO: Okasaki's of_list *)
144 (** Second, we encapsulate Braun trees in a record, together with its
145 size and suitable invariants. *)
147 module FlexibleArrays
156 invariant { B.braun tree }
157 invariant { B.size tree = size >= 0 }
159 let constant empty : t 'a
160 = { size = 0; tree = B.Empty }
161 ensures { result.size = 0 }
163 let function get (t: t 'a) (i: int) : 'a
164 requires { 0 <= i < t.size }
165 = B.get_tree t.tree i
167 let set (t: t 'a) (i: int) (v: 'a) : (r: t 'a)
168 requires { 0 <= i < t.size }
169 ensures { r.size = t.size }
170 ensures { get r i = v }
171 ensures { forall j. 0 <= j < t.size -> j<>i -> get r j = get t j }
172 = { size = t.size; tree = B.set_tree t.tree i v }
174 let make_tree (n: int) (v: 'a) : (r: t 'a)
176 ensures { r.size = n }
177 ensures { forall i. 0 <= i < r.size -> get r i = v }
178 = { size = n; tree = B.make_tree n v }
180 (* left insertion/removal *)
182 let cons (v: 'a) (t: t 'a) : (r: t 'a)
183 ensures { size r = size t + 1 }
184 ensures { get r 0 = v }
185 ensures { forall i. 0 <= i < t.size -> get r (i+1) = get t i }
186 = { size = t.size + 1; tree = B.cons_tree v t.tree }
188 let tail (t: t 'a) : (r: t 'a)
189 requires { t.size > 0 }
190 ensures { r.size = t.size - 1 }
191 ensures { forall i. 0 < i < size t -> get r (i-1) = get t i }
192 = { size = t.size - 1; tree = B.tail_tree t.tree }
194 (* right insertion/removal *)
196 let snoc (t: t 'a) (v: 'a) : (r: t 'a)
197 ensures { r.size = t.size + 1 }
198 ensures { forall i. 0 <= i < t.size -> get r i = get t i }
199 ensures { get r t.size = v }
200 = { size = t.size + 1; tree = B.snoc_tree t.size t.tree v }
202 let liat (t: t 'a) : (r: t 'a)
203 requires { t.size > 0 }
204 ensures { r.size = t.size - 1 }
205 ensures { forall i. 0 <= i < r.size -> get r i = get t i }
206 = { size = t.size - 1; tree = B.liat_tree t.size t.tree }