package unionFind

  1. Overview
  2. Docs
Implementations of the union-find data structure

Install

Dune Dependency

Authors

Maintainers

Sources

archive.tar.gz
md5=3311141704584930d9e7358ef0edf2f4
sha512=116dfd8078f697012f8b53f518d6e05fca09b1d57b7ce7724b0789bf6d2ecacc7efa462a6bbcdf486358ce17e84f5d106a7e799d9b44cbc0755e433fdd82b724

doc/src/unionFind/StoreMap.ml.html

Source file StoreMap.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
(***************************************************************************)
(*                                                                         *)
(*                                 UnionFind                               *)
(*                                                                         *)
(*                       François Pottier, Inria Paris                     *)
(*                                                                         *)
(*  Copyright Inria. All rights reserved. This file is distributed under   *)
(*  the terms of the GNU Library General Public License version 2, with a  *)
(*  special exception on linking, as described in the file LICENSE.        *)
(***************************************************************************)

module type INTMAP = sig
  type 'a t
  val empty: 'a t
  val find: int -> 'a t -> 'a
  val add: int -> 'a -> 'a t -> 'a t
end

module Make (IntMap : INTMAP) = struct

(* A store is implemented as a pair of an integer address and a map of
   integer addresses to values. We maintain the invariant that the
   domain of the map [content] is the semi-open interval of zero
   (included) up to [limit] (excluded). *)

type 'a store = {
  (* The next available address. *)
  limit:   int;
  (* The content of the store. *)
  content: 'a IntMap.t
}

let new_store () = {
  limit = 0;
  content = IntMap.empty
}

(* A reference is just an integer address. *)

type 'a rref =
  int

let make s v =
  let x = s.limit in
  {
    limit = x + 1;
    content = IntMap.add x v s.content
  },
  x

(* [check s x] checks that the address [x] is in range for the store [s]. If
   this dynamic check fails, then the user is confused and has passed us an
   address that is associated with some other store. (If the check succeeds,
   the user may be confused too! but we cannot detect it.) *)

exception InvalidRef

let check (s : 'a store) (x : 'a rref) =
  (* We do not check that [x] is nonnegative. An overflow cannot occur,
     since that would imply that we have filled the memory with a huge
     array. *)
   if x >= s.limit then
     raise InvalidRef

let get s x =
  (* Failure of this assertion would indicate that the user has passed us
     an address that is associated with some other store. *)
  check s x;
  s,
  IntMap.find x s.content

let set s x v =
  (* Failure of this assertion would indicate that the user has passed us
     an address that is associated with some other store. *)
  check s x;
  {
    limit = s.limit;
    content = IntMap.add x v s.content
  }

let eq s (x : int) (y : int) =
  (* Failure of this assertion would indicate that the user has passed us
     an address that is associated with some other store. *)
  check s x;
  check s y;
  s,
  x = y

end

(* Include the most common instance of the above functor. *)

include Make(Map.Make(struct
  type t = int
  let compare = (-) (* ok since the arguments are nonnegative integers *)
end))
OCaml

Innovation. Community. Security.