## lustrec / src / mmap.ml @ 08cbfc23

History | View | Annotate | Download (10.7 KB)

1 |
(***********************************************************************) |
---|---|

2 |
(* *) |

3 |
(* OCaml *) |

4 |
(* *) |

5 |
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) |

6 |
(* *) |

7 |
(* Copyright 1996 Institut National de Recherche en Informatique et *) |

8 |
(* en Automatique. All rights reserved. This file is distributed *) |

9 |
(* under the terms of the GNU Library General Public License, with *) |

10 |
(* the special exception on linking described in file ../LICENSE. *) |

11 |
(* *) |

12 |
(***********************************************************************) |

13 | |

14 |
module type OrderedType = |

15 |
sig |

16 |
type t |

17 |
val compare: t -> t -> int |

18 |
end |

19 | |

20 |
module type S = |

21 |
sig |

22 |
type key |

23 |
type +'a t |

24 |
val empty: 'a t |

25 |
val is_empty: 'a t -> bool |

26 |
val mem: key -> 'a t -> bool |

27 |
val add: key -> 'a -> 'a t -> 'a t |

28 |
val singleton: key -> 'a -> 'a t |

29 |
val remove: key -> 'a t -> 'a t |

30 |
val merge: |

31 |
(key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t |

32 |
val compare: ('a -> 'a -> int) -> 'a t -> 'a t -> int |

33 |
val equal: ('a -> 'a -> bool) -> 'a t -> 'a t -> bool |

34 |
val iter: (key -> 'a -> unit) -> 'a t -> unit |

35 |
val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b |

36 |
val for_all: (key -> 'a -> bool) -> 'a t -> bool |

37 |
val exists: (key -> 'a -> bool) -> 'a t -> bool |

38 |
val filter: (key -> 'a -> bool) -> 'a t -> 'a t |

39 |
val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t |

40 |
val cardinal: 'a t -> int |

41 |
val bindings: 'a t -> (key * 'a) list |

42 |
val min_binding: 'a t -> (key * 'a) |

43 |
val max_binding: 'a t -> (key * 'a) |

44 |
val choose: 'a t -> (key * 'a) |

45 |
val split: key -> 'a t -> 'a t * 'a option * 'a t |

46 |
val find: key -> 'a t -> 'a |

47 |
val map: ('a -> 'b) -> 'a t -> 'b t |

48 |
val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t |

49 |
end |

50 | |

51 |
module Make(Ord: OrderedType) = struct |

52 | |

53 |
type key = Ord.t |

54 | |

55 |
type 'a t = |

56 |
Empty |

57 |
| Node of 'a t * key * 'a * 'a t * int |

58 | |

59 |
let height = function |

60 |
Empty -> 0 |

61 |
| Node(_,_,_,_,h) -> h |

62 | |

63 |
let create l x d r = |

64 |
let hl = height l and hr = height r in |

65 |
Node(l, x, d, r, (if hl >= hr then hl + 1 else hr + 1)) |

66 | |

67 |
let singleton x d = Node(Empty, x, d, Empty, 1) |

68 | |

69 |
let bal l x d r = |

70 |
let hl = match l with Empty -> 0 | Node(_,_,_,_,h) -> h in |

71 |
let hr = match r with Empty -> 0 | Node(_,_,_,_,h) -> h in |

72 |
if hl > hr + 2 then begin |

73 |
match l with |

74 |
Empty -> invalid_arg "Map.bal" |

75 |
| Node(ll, lv, ld, lr, _) -> |

76 |
if height ll >= height lr then |

77 |
create ll lv ld (create lr x d r) |

78 |
else begin |

79 |
match lr with |

80 |
Empty -> invalid_arg "Map.bal" |

81 |
| Node(lrl, lrv, lrd, lrr, _)-> |

82 |
create (create ll lv ld lrl) lrv lrd (create lrr x d r) |

83 |
end |

84 |
end else if hr > hl + 2 then begin |

85 |
match r with |

86 |
Empty -> invalid_arg "Map.bal" |

87 |
| Node(rl, rv, rd, rr, _) -> |

88 |
if height rr >= height rl then |

89 |
create (create l x d rl) rv rd rr |

90 |
else begin |

91 |
match rl with |

92 |
Empty -> invalid_arg "Map.bal" |

93 |
| Node(rll, rlv, rld, rlr, _) -> |

94 |
create (create l x d rll) rlv rld (create rlr rv rd rr) |

95 |
end |

96 |
end else |

97 |
Node(l, x, d, r, (if hl >= hr then hl + 1 else hr + 1)) |

98 | |

99 |
let empty = Empty |

100 | |

101 |
let is_empty = function Empty -> true | _ -> false |

102 | |

103 |
let rec add x data = function |

104 |
Empty -> |

105 |
Node(Empty, x, data, Empty, 1) |

106 |
| Node(l, v, d, r, h) -> |

107 |
let c = Ord.compare x v in |

108 |
if c = 0 then |

109 |
Node(l, x, data, r, h) |

110 |
else if c < 0 then |

111 |
bal (add x data l) v d r |

112 |
else |

113 |
bal l v d (add x data r) |

114 | |

115 |
let rec find x = function |

116 |
Empty -> |

117 |
raise Not_found |

118 |
| Node(l, v, d, r, _) -> |

119 |
let c = Ord.compare x v in |

120 |
if c = 0 then d |

121 |
else find x (if c < 0 then l else r) |

122 | |

123 |
let rec mem x = function |

124 |
Empty -> |

125 |
false |

126 |
| Node(l, v, d, r, _) -> |

127 |
let c = Ord.compare x v in |

128 |
c = 0 || mem x (if c < 0 then l else r) |

129 | |

130 |
let rec min_binding = function |

131 |
Empty -> raise Not_found |

132 |
| Node(Empty, x, d, r, _) -> (x, d) |

133 |
| Node(l, x, d, r, _) -> min_binding l |

134 | |

135 |
let rec max_binding = function |

136 |
Empty -> raise Not_found |

137 |
| Node(l, x, d, Empty, _) -> (x, d) |

138 |
| Node(l, x, d, r, _) -> max_binding r |

139 | |

140 |
let rec remove_min_binding = function |

141 |
Empty -> invalid_arg "Map.remove_min_elt" |

142 |
| Node(Empty, x, d, r, _) -> r |

143 |
| Node(l, x, d, r, _) -> bal (remove_min_binding l) x d r |

144 | |

145 |
let merge t1 t2 = |

146 |
match (t1, t2) with |

147 |
(Empty, t) -> t |

148 |
| (t, Empty) -> t |

149 |
| (_, _) -> |

150 |
let (x, d) = min_binding t2 in |

151 |
bal t1 x d (remove_min_binding t2) |

152 | |

153 |
let rec remove x = function |

154 |
Empty -> |

155 |
Empty |

156 |
| Node(l, v, d, r, h) -> |

157 |
let c = Ord.compare x v in |

158 |
if c = 0 then |

159 |
merge l r |

160 |
else if c < 0 then |

161 |
bal (remove x l) v d r |

162 |
else |

163 |
bal l v d (remove x r) |

164 | |

165 |
let rec iter f = function |

166 |
Empty -> () |

167 |
| Node(l, v, d, r, _) -> |

168 |
iter f l; f v d; iter f r |

169 | |

170 |
let rec map f = function |

171 |
Empty -> |

172 |
Empty |

173 |
| Node(l, v, d, r, h) -> |

174 |
let l' = map f l in |

175 |
let d' = f d in |

176 |
let r' = map f r in |

177 |
Node(l', v, d', r', h) |

178 | |

179 |
let rec mapi f = function |

180 |
Empty -> |

181 |
Empty |

182 |
| Node(l, v, d, r, h) -> |

183 |
let l' = mapi f l in |

184 |
let d' = f v d in |

185 |
let r' = mapi f r in |

186 |
Node(l', v, d', r', h) |

187 | |

188 |
let rec fold f m accu = |

189 |
match m with |

190 |
Empty -> accu |

191 |
| Node(l, v, d, r, _) -> |

192 |
fold f r (f v d (fold f l accu)) |

193 | |

194 |
let rec for_all p = function |

195 |
Empty -> true |

196 |
| Node(l, v, d, r, _) -> p v d && for_all p l && for_all p r |

197 | |

198 |
let rec exists p = function |

199 |
Empty -> false |

200 |
| Node(l, v, d, r, _) -> p v d || exists p l || exists p r |

201 | |

202 |
(* Beware: those two functions assume that the added k is *strictly* |

203 |
smaller (or bigger) than all the present keys in the tree; it |

204 |
does not test for equality with the current min (or max) key. |

205 | |

206 |
Indeed, they are only used during the "join" operation which |

207 |
respects this precondition. |

208 |
*) |

209 | |

210 |
let rec add_min_binding k v = function |

211 |
| Empty -> singleton k v |

212 |
| Node (l, x, d, r, h) -> |

213 |
bal (add_min_binding k v l) x d r |

214 | |

215 |
let rec add_max_binding k v = function |

216 |
| Empty -> singleton k v |

217 |
| Node (l, x, d, r, h) -> |

218 |
bal l x d (add_max_binding k v r) |

219 | |

220 |
(* Same as create and bal, but no assumptions are made on the |

221 |
relative heights of l and r. *) |

222 | |

223 |
let rec join l v d r = |

224 |
match (l, r) with |

225 |
(Empty, _) -> add_min_binding v d r |

226 |
| (_, Empty) -> add_max_binding v d l |

227 |
| (Node(ll, lv, ld, lr, lh), Node(rl, rv, rd, rr, rh)) -> |

228 |
if lh > rh + 2 then bal ll lv ld (join lr v d r) else |

229 |
if rh > lh + 2 then bal (join l v d rl) rv rd rr else |

230 |
create l v d r |

231 | |

232 |
(* Merge two trees l and r into one. |

233 |
All elements of l must precede the elements of r. |

234 |
No assumption on the heights of l and r. *) |

235 | |

236 |
let concat t1 t2 = |

237 |
match (t1, t2) with |

238 |
(Empty, t) -> t |

239 |
| (t, Empty) -> t |

240 |
| (_, _) -> |

241 |
let (x, d) = min_binding t2 in |

242 |
join t1 x d (remove_min_binding t2) |

243 | |

244 |
let concat_or_join t1 v d t2 = |

245 |
match d with |

246 |
| Some d -> join t1 v d t2 |

247 |
| None -> concat t1 t2 |

248 | |

249 |
let rec split x = function |

250 |
Empty -> |

251 |
(Empty, None, Empty) |

252 |
| Node(l, v, d, r, _) -> |

253 |
let c = Ord.compare x v in |

254 |
if c = 0 then (l, Some d, r) |

255 |
else if c < 0 then |

256 |
let (ll, pres, rl) = split x l in (ll, pres, join rl v d r) |

257 |
else |

258 |
let (lr, pres, rr) = split x r in (join l v d lr, pres, rr) |

259 | |

260 |
let rec merge f s1 s2 = |

261 |
match (s1, s2) with |

262 |
(Empty, Empty) -> Empty |

263 |
| (Node (l1, v1, d1, r1, h1), _) when h1 >= height s2 -> |

264 |
let (l2, d2, r2) = split v1 s2 in |

265 |
concat_or_join (merge f l1 l2) v1 (f v1 (Some d1) d2) (merge f r1 r2) |

266 |
| (_, Node (l2, v2, d2, r2, h2)) -> |

267 |
let (l1, d1, r1) = split v2 s1 in |

268 |
concat_or_join (merge f l1 l2) v2 (f v2 d1 (Some d2)) (merge f r1 r2) |

269 |
| _ -> |

270 |
assert false |

271 | |

272 |
let rec filter p = function |

273 |
Empty -> Empty |

274 |
| Node(l, v, d, r, _) -> |

275 |
(* call [p] in the expected left-to-right order *) |

276 |
let l' = filter p l in |

277 |
let pvd = p v d in |

278 |
let r' = filter p r in |

279 |
if pvd then join l' v d r' else concat l' r' |

280 | |

281 |
let rec partition p = function |

282 |
Empty -> (Empty, Empty) |

283 |
| Node(l, v, d, r, _) -> |

284 |
(* call [p] in the expected left-to-right order *) |

285 |
let (lt, lf) = partition p l in |

286 |
let pvd = p v d in |

287 |
let (rt, rf) = partition p r in |

288 |
if pvd |

289 |
then (join lt v d rt, concat lf rf) |

290 |
else (concat lt rt, join lf v d rf) |

291 | |

292 |
type 'a enumeration = End | More of key * 'a * 'a t * 'a enumeration |

293 | |

294 |
let rec cons_enum m e = |

295 |
match m with |

296 |
Empty -> e |

297 |
| Node(l, v, d, r, _) -> cons_enum l (More(v, d, r, e)) |

298 | |

299 |
let compare cmp m1 m2 = |

300 |
let rec compare_aux e1 e2 = |

301 |
match (e1, e2) with |

302 |
(End, End) -> 0 |

303 |
| (End, _) -> -1 |

304 |
| (_, End) -> 1 |

305 |
| (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> |

306 |
let c = Ord.compare v1 v2 in |

307 |
if c <> 0 then c else |

308 |
let c = cmp d1 d2 in |

309 |
if c <> 0 then c else |

310 |
compare_aux (cons_enum r1 e1) (cons_enum r2 e2) |

311 |
in compare_aux (cons_enum m1 End) (cons_enum m2 End) |

312 | |

313 |
let equal cmp m1 m2 = |

314 |
let rec equal_aux e1 e2 = |

315 |
match (e1, e2) with |

316 |
(End, End) -> true |

317 |
| (End, _) -> false |

318 |
| (_, End) -> false |

319 |
| (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> |

320 |
Ord.compare v1 v2 = 0 && cmp d1 d2 && |

321 |
equal_aux (cons_enum r1 e1) (cons_enum r2 e2) |

322 |
in equal_aux (cons_enum m1 End) (cons_enum m2 End) |

323 | |

324 |
let rec cardinal = function |

325 |
Empty -> 0 |

326 |
| Node(l, _, _, r, _) -> cardinal l + 1 + cardinal r |

327 | |

328 |
let rec bindings_aux accu = function |

329 |
Empty -> accu |

330 |
| Node(l, v, d, r, _) -> bindings_aux ((v, d) :: bindings_aux accu r) l |

331 | |

332 |
let bindings s = |

333 |
bindings_aux [] s |

334 | |

335 |
let choose = min_binding |

336 | |

337 |
end |