My working unpac repository
at opam/upstream/seq 552 lines 18 kB view raw
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. *) 9(* *) 10(* All rights reserved. This file is distributed under the terms of *) 11(* the GNU Lesser General Public License version 2.1, with the *) 12(* special exception on linking described in the file LICENSE. *) 13(* *) 14(**************************************************************************) 15 16module type OrderedType = 17 sig 18 type t 19 val compare: t -> t -> int 20 end 21 22module type S = 23 sig 24 type key 25 type !+'a t 26 val empty: 'a t 27 val add: key -> 'a -> 'a t -> 'a t 28 val add_to_list: key -> 'a -> 'a list t -> 'a list t 29 val update: key -> ('a option -> 'a option) -> 'a t -> 'a t 30 val singleton: key -> 'a -> 'a t 31 val remove: key -> 'a t -> 'a t 32 val merge: 33 (key -> 'a option -> 'b option -> 'c option) -> 34 'a t -> 'b t -> 'c t 35 val union: (key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t 36 val cardinal: 'a t -> int 37 val bindings: 'a t -> (key * 'a) list 38 val min_binding: 'a t -> (key * 'a) 39 val min_binding_opt: 'a t -> (key * 'a) option 40 val max_binding: 'a t -> (key * 'a) 41 val max_binding_opt: 'a t -> (key * 'a) option 42 val choose: 'a t -> (key * 'a) 43 val choose_opt: 'a t -> (key * 'a) option 44 val find: key -> 'a t -> 'a 45 val find_opt: key -> 'a t -> 'a option 46 val find_first: (key -> bool) -> 'a t -> key * 'a 47 val find_first_opt: (key -> bool) -> 'a t -> (key * 'a) option 48 val find_last: (key -> bool) -> 'a t -> key * 'a 49 val find_last_opt: (key -> bool) -> 'a t -> (key * 'a) option 50 val iter: (key -> 'a -> unit) -> 'a t -> unit 51 val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b 52 val map: ('a -> 'b) -> 'a t -> 'b t 53 val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t 54 val filter: (key -> 'a -> bool) -> 'a t -> 'a t 55 val filter_map: (key -> 'a -> 'b option) -> 'a t -> 'b t 56 val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t 57 val split: key -> 'a t -> 'a t * 'a option * 'a t 58 val is_empty: 'a t -> bool 59 val is_singleton: 'a t -> bool 60 val mem: key -> 'a t -> bool 61 val equal: ('a -> 'a -> bool) -> 'a t -> 'a t -> bool 62 val compare: ('a -> 'a -> int) -> 'a t -> 'a t -> int 63 val for_all: (key -> 'a -> bool) -> 'a t -> bool 64 val exists: (key -> 'a -> bool) -> 'a t -> bool 65 val to_list : 'a t -> (key * 'a) list 66 val of_list : (key * 'a) list -> 'a t 67 val to_seq : 'a t -> (key * 'a) Seq.t 68 val to_rev_seq : 'a t -> (key * 'a) Seq.t 69 val to_seq_from : key -> 'a t -> (key * 'a) Seq.t 70 val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t 71 val of_seq : (key * 'a) Seq.t -> 'a t 72 end 73 74module Make(Ord: OrderedType) = struct 75 76 type key = Ord.t 77 78 type 'a t = 79 Empty 80 | Node of {l:'a t; v:key; d:'a; r:'a t; h:int} 81 82 let height = function 83 Empty -> 0 84 | Node {h} -> h 85 86 let create l x d r = 87 let hl = height l and hr = height r in 88 Node{l; v=x; d; r; h=(if hl >= hr then hl + 1 else hr + 1)} 89 90 let singleton x d = Node{l=Empty; v=x; d; r=Empty; h=1} 91 92 let bal l x d r = 93 let hl = match l with Empty -> 0 | Node {h} -> h in 94 let hr = match r with Empty -> 0 | Node {h} -> h in 95 if hl > hr + 2 then begin 96 match l with 97 Empty -> invalid_arg "Map.bal" 98 | Node{l=ll; v=lv; d=ld; r=lr} -> 99 if height ll >= height lr then 100 create ll lv ld (create lr x d r) 101 else begin 102 match lr with 103 Empty -> invalid_arg "Map.bal" 104 | Node{l=lrl; v=lrv; d=lrd; r=lrr}-> 105 create (create ll lv ld lrl) lrv lrd (create lrr x d r) 106 end 107 end else if hr > hl + 2 then begin 108 match r with 109 Empty -> invalid_arg "Map.bal" 110 | Node{l=rl; v=rv; d=rd; r=rr} -> 111 if height rr >= height rl then 112 create (create l x d rl) rv rd rr 113 else begin 114 match rl with 115 Empty -> invalid_arg "Map.bal" 116 | Node{l=rll; v=rlv; d=rld; r=rlr} -> 117 create (create l x d rll) rlv rld (create rlr rv rd rr) 118 end 119 end else 120 Node{l; v=x; d; r; h=(if hl >= hr then hl + 1 else hr + 1)} 121 122 let empty = Empty 123 124 let is_empty = function Empty -> true | _ -> false 125 126 let is_singleton = function 127 | Node{l=Empty; r=Empty} -> true 128 | Empty | Node _ -> false 129 130 let rec add x data = function 131 Empty -> 132 Node{l=Empty; v=x; d=data; r=Empty; h=1} 133 | Node {l; v; d; r; h} as m -> 134 let c = Ord.compare x v in 135 if c = 0 then 136 if d == data then m else Node{l; v=x; d=data; r; h} 137 else if c < 0 then 138 let ll = add x data l in 139 if l == ll then m else bal ll v d r 140 else 141 let rr = add x data r in 142 if r == rr then m else bal l v d rr 143 144 let rec find x = function 145 Empty -> 146 raise Not_found 147 | Node {l; v; d; r} -> 148 let c = Ord.compare x v in 149 if c = 0 then d 150 else find x (if c < 0 then l else r) 151 152 let rec find_first_aux v0 d0 f = function 153 Empty -> 154 (v0, d0) 155 | Node {l; v; d; r} -> 156 if f v then 157 find_first_aux v d f l 158 else 159 find_first_aux v0 d0 f r 160 161 let rec find_first f = function 162 Empty -> 163 raise Not_found 164 | Node {l; v; d; r} -> 165 if f v then 166 find_first_aux v d f l 167 else 168 find_first f r 169 170 let rec find_first_opt_aux v0 d0 f = function 171 Empty -> 172 Some (v0, d0) 173 | Node {l; v; d; r} -> 174 if f v then 175 find_first_opt_aux v d f l 176 else 177 find_first_opt_aux v0 d0 f r 178 179 let rec find_first_opt f = function 180 Empty -> 181 None 182 | Node {l; v; d; r} -> 183 if f v then 184 find_first_opt_aux v d f l 185 else 186 find_first_opt f r 187 188 let rec find_last_aux v0 d0 f = function 189 Empty -> 190 (v0, d0) 191 | Node {l; v; d; r} -> 192 if f v then 193 find_last_aux v d f r 194 else 195 find_last_aux v0 d0 f l 196 197 let rec find_last f = function 198 Empty -> 199 raise Not_found 200 | Node {l; v; d; r} -> 201 if f v then 202 find_last_aux v d f r 203 else 204 find_last f l 205 206 let rec find_last_opt_aux v0 d0 f = function 207 Empty -> 208 Some (v0, d0) 209 | Node {l; v; d; r} -> 210 if f v then 211 find_last_opt_aux v d f r 212 else 213 find_last_opt_aux v0 d0 f l 214 215 let rec find_last_opt f = function 216 Empty -> 217 None 218 | Node {l; v; d; r} -> 219 if f v then 220 find_last_opt_aux v d f r 221 else 222 find_last_opt f l 223 224 let rec find_opt x = function 225 Empty -> 226 None 227 | Node {l; v; d; r} -> 228 let c = Ord.compare x v in 229 if c = 0 then Some d 230 else find_opt x (if c < 0 then l else r) 231 232 let rec mem x = function 233 Empty -> 234 false 235 | Node {l; v; r} -> 236 let c = Ord.compare x v in 237 c = 0 || mem x (if c < 0 then l else r) 238 239 let rec min_binding = function 240 Empty -> raise Not_found 241 | Node {l=Empty; v; d} -> (v, d) 242 | Node {l} -> min_binding l 243 244 let rec min_binding_opt = function 245 Empty -> None 246 | Node {l=Empty; v; d} -> Some (v, d) 247 | Node {l}-> min_binding_opt l 248 249 let rec max_binding = function 250 Empty -> raise Not_found 251 | Node {v; d; r=Empty} -> (v, d) 252 | Node {r} -> max_binding r 253 254 let rec max_binding_opt = function 255 Empty -> None 256 | Node {v; d; r=Empty} -> Some (v, d) 257 | Node {r} -> max_binding_opt r 258 259 let rec remove_min_binding = function 260 Empty -> invalid_arg "Map.remove_min_elt" 261 | Node {l=Empty; r} -> r 262 | Node {l; v; d; r} -> bal (remove_min_binding l) v d r 263 264 let merge t1 t2 = 265 match (t1, t2) with 266 (Empty, t) -> t 267 | (t, Empty) -> t 268 | (_, _) -> 269 let (x, d) = min_binding t2 in 270 bal t1 x d (remove_min_binding t2) 271 272 let rec remove x = function 273 Empty -> 274 Empty 275 | (Node {l; v; d; r} as m) -> 276 let c = Ord.compare x v in 277 if c = 0 then merge l r 278 else if c < 0 then 279 let ll = remove x l in if l == ll then m else bal ll v d r 280 else 281 let rr = remove x r in if r == rr then m else bal l v d rr 282 283 let rec update x f = function 284 Empty -> 285 begin match f None with 286 | None -> Empty 287 | Some data -> Node{l=Empty; v=x; d=data; r=Empty; h=1} 288 end 289 | Node {l; v; d; r; h} as m -> 290 let c = Ord.compare x v in 291 if c = 0 then begin 292 match f (Some d) with 293 | None -> merge l r 294 | Some data -> 295 if d == data then m else Node{l; v=x; d=data; r; h} 296 end else if c < 0 then 297 let ll = update x f l in 298 if l == ll then m else bal ll v d r 299 else 300 let rr = update x f r in 301 if r == rr then m else bal l v d rr 302 303 let add_to_list x data m = 304 let add = function None -> Some [data] | Some l -> Some (data :: l) in 305 update x add m 306 307 let rec iter f = function 308 Empty -> () 309 | Node {l; v; d; r} -> 310 iter f l; f v d; iter f r 311 312 let rec map f = function 313 Empty -> 314 Empty 315 | Node {l; v; d; r; h} -> 316 let l' = map f l in 317 let d' = f d in 318 let r' = map f r in 319 Node{l=l'; v; d=d'; r=r'; h} 320 321 let rec mapi f = function 322 Empty -> 323 Empty 324 | Node {l; v; d; r; h} -> 325 let l' = mapi f l in 326 let d' = f v d in 327 let r' = mapi f r in 328 Node{l=l'; v; d=d'; r=r'; h} 329 330 let rec fold f m accu = 331 match m with 332 Empty -> accu 333 | Node {l; v; d; r} -> 334 fold f r (f v d (fold f l accu)) 335 336 let rec for_all p = function 337 Empty -> true 338 | Node {l; v; d; r} -> p v d && for_all p l && for_all p r 339 340 let rec exists p = function 341 Empty -> false 342 | Node {l; v; d; r} -> p v d || exists p l || exists p r 343 344 (* Beware: those two functions assume that the added k is *strictly* 345 smaller (or bigger) than all the present keys in the tree; it 346 does not test for equality with the current min (or max) key. 347 348 Indeed, they are only used during the "join" operation which 349 respects this precondition. 350 *) 351 352 let rec add_min_binding k x = function 353 | Empty -> singleton k x 354 | Node {l; v; d; r} -> 355 bal (add_min_binding k x l) v d r 356 357 let rec add_max_binding k x = function 358 | Empty -> singleton k x 359 | Node {l; v; d; r} -> 360 bal l v d (add_max_binding k x r) 361 362 (* Same as create and bal, but no assumptions are made on the 363 relative heights of l and r. *) 364 365 let rec join l v d r = 366 match (l, r) with 367 (Empty, _) -> add_min_binding v d r 368 | (_, Empty) -> add_max_binding v d l 369 | (Node{l=ll; v=lv; d=ld; r=lr; h=lh}, 370 Node{l=rl; v=rv; d=rd; r=rr; h=rh}) -> 371 if lh > rh + 2 then bal ll lv ld (join lr v d r) else 372 if rh > lh + 2 then bal (join l v d rl) rv rd rr else 373 create l v d r 374 375 (* Merge two trees l and r into one. 376 All elements of l must precede the elements of r. 377 No assumption on the heights of l and r. *) 378 379 let concat t1 t2 = 380 match (t1, t2) with 381 (Empty, t) -> t 382 | (t, Empty) -> t 383 | (_, _) -> 384 let (x, d) = min_binding t2 in 385 join t1 x d (remove_min_binding t2) 386 387 let concat_or_join t1 v d t2 = 388 match d with 389 | Some d -> join t1 v d t2 390 | None -> concat t1 t2 391 392 let rec split x = function 393 Empty -> 394 (Empty, None, Empty) 395 | Node {l; v; d; r} -> 396 let c = Ord.compare x v in 397 if c = 0 then (l, Some d, r) 398 else if c < 0 then 399 let (ll, pres, rl) = split x l in (ll, pres, join rl v d r) 400 else 401 let (lr, pres, rr) = split x r in (join l v d lr, pres, rr) 402 403 let rec merge f s1 s2 = 404 match (s1, s2) with 405 (Empty, Empty) -> Empty 406 | (Node {l=l1; v=v1; d=d1; r=r1; h=h1}, _) when h1 >= height s2 -> 407 let (l2, d2, r2) = split v1 s2 in 408 concat_or_join (merge f l1 l2) v1 (f v1 (Some d1) d2) (merge f r1 r2) 409 | (_, Node {l=l2; v=v2; d=d2; r=r2}) -> 410 let (l1, d1, r1) = split v2 s1 in 411 concat_or_join (merge f l1 l2) v2 (f v2 d1 (Some d2)) (merge f r1 r2) 412 | _ -> 413 assert false 414 415 let rec union f s1 s2 = 416 match (s1, s2) with 417 | (Empty, s) | (s, Empty) -> s 418 | (Node {l=l1; v=v1; d=d1; r=r1; h=h1}, 419 Node {l=l2; v=v2; d=d2; r=r2; h=h2}) -> 420 if h1 >= h2 then 421 let (l2, d2, r2) = split v1 s2 in 422 let l = union f l1 l2 and r = union f r1 r2 in 423 match d2 with 424 | None -> join l v1 d1 r 425 | Some d2 -> concat_or_join l v1 (f v1 d1 d2) r 426 else 427 let (l1, d1, r1) = split v2 s1 in 428 let l = union f l1 l2 and r = union f r1 r2 in 429 match d1 with 430 | None -> join l v2 d2 r 431 | Some d1 -> concat_or_join l v2 (f v2 d1 d2) r 432 433 let rec filter p = function 434 Empty -> Empty 435 | Node {l; v; d; r} as m -> 436 (* call [p] in the expected left-to-right order *) 437 let l' = filter p l in 438 let pvd = p v d in 439 let r' = filter p r in 440 if pvd then if l==l' && r==r' then m else join l' v d r' 441 else concat l' r' 442 443 let rec filter_map f = function 444 Empty -> Empty 445 | Node {l; v; d; r} -> 446 (* call [f] in the expected left-to-right order *) 447 let l' = filter_map f l in 448 let fvd = f v d in 449 let r' = filter_map f r in 450 begin match fvd with 451 | Some d' -> join l' v d' r' 452 | None -> concat l' r' 453 end 454 455 let rec partition p = function 456 Empty -> (Empty, Empty) 457 | Node {l; v; d; r} -> 458 (* call [p] in the expected left-to-right order *) 459 let (lt, lf) = partition p l in 460 let pvd = p v d in 461 let (rt, rf) = partition p r in 462 if pvd 463 then (join lt v d rt, concat lf rf) 464 else (concat lt rt, join lf v d rf) 465 466 type 'a enumeration = End | More of key * 'a * 'a t * 'a enumeration 467 468 let rec cons_enum m e = 469 match m with 470 Empty -> e 471 | Node {l; v; d; r} -> cons_enum l (More(v, d, r, e)) 472 473 let compare cmp m1 m2 = 474 let rec compare_aux e1 e2 = 475 match (e1, e2) with 476 (End, End) -> 0 477 | (End, _) -> -1 478 | (_, End) -> 1 479 | (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> 480 let c = Ord.compare v1 v2 in 481 if c <> 0 then c else 482 let c = cmp d1 d2 in 483 if c <> 0 then c else 484 compare_aux (cons_enum r1 e1) (cons_enum r2 e2) 485 in compare_aux (cons_enum m1 End) (cons_enum m2 End) 486 487 let equal cmp m1 m2 = 488 let rec equal_aux e1 e2 = 489 match (e1, e2) with 490 (End, End) -> true 491 | (End, _) -> false 492 | (_, End) -> false 493 | (More(v1, d1, r1, e1), More(v2, d2, r2, e2)) -> 494 Ord.compare v1 v2 = 0 && cmp d1 d2 && 495 equal_aux (cons_enum r1 e1) (cons_enum r2 e2) 496 in equal_aux (cons_enum m1 End) (cons_enum m2 End) 497 498 let rec cardinal = function 499 Empty -> 0 500 | Node {l; r} -> cardinal l + 1 + cardinal r 501 502 let rec bindings_aux accu = function 503 Empty -> accu 504 | Node {l; v; d; r} -> bindings_aux ((v, d) :: bindings_aux accu r) l 505 506 let bindings s = 507 bindings_aux [] s 508 509 let choose = min_binding 510 511 let choose_opt = min_binding_opt 512 513 let to_list = bindings 514 let of_list bs = List.fold_left (fun m (k, v) -> add k v m) empty bs 515 516 let add_seq i m = 517 Seq.fold_left (fun m (k,v) -> add k v m) m i 518 519 let of_seq i = add_seq i empty 520 521 let rec seq_of_enum_ c () = match c with 522 | End -> Seq.Nil 523 | More (k,v,t,rest) -> Seq.Cons ((k,v), seq_of_enum_ (cons_enum t rest)) 524 525 let to_seq m = 526 seq_of_enum_ (cons_enum m End) 527 528 let rec snoc_enum s e = 529 match s with 530 Empty -> e 531 | Node{l; v; d; r} -> snoc_enum r (More(v, d, l, e)) 532 533 let rec rev_seq_of_enum_ c () = match c with 534 | End -> Seq.Nil 535 | More (k,v,t,rest) -> 536 Seq.Cons ((k,v), rev_seq_of_enum_ (snoc_enum t rest)) 537 538 let to_rev_seq c = 539 rev_seq_of_enum_ (snoc_enum c End) 540 541 let to_seq_from low m = 542 let rec aux low m c = match m with 543 | Empty -> c 544 | Node {l; v; d; r; _} -> 545 begin match Ord.compare v low with 546 | 0 -> More (v, d, r, c) 547 | n when n<0 -> aux low r c 548 | _ -> aux low l (More (v, d, r, c)) 549 end 550 in 551 seq_of_enum_ (aux low m End) 552end