diff --git a/Partition.mli b/Partition.mli index 699eac1..03df3ca 100644 --- a/Partition.mli +++ b/Partition.mli @@ -43,13 +43,19 @@ module type S = (** {1 Projection} *) - (** The value of the call [repr i p] is [Some j], if the item [i] - is in the partition [p] and its representative is [j]. If [i] - is not in [p], then the value is [None]. *) - val repr : item -> partition -> item option + (** The value of the call [repr i p] is [j] if the item [i] is in + the partition [p] and its representative is [j]. If [i] is not + in [p], then the value is [i]. *) + val repr : item -> partition -> item - (** The side-effect of the call [print p] is the printing of the - partition [p] on a buffer, based on [Ord.to_string]. *) + (** The value of the call [mem i p] is [Some j] if the item [i] is + in the partition [p] and its representative is [j]. If [i] is + not in [p], then the value is [None]. *) + val mem : item -> partition -> item option + + (** The call [print p] is a value of type [Buffer.t] containing + strings denoting the partition [p], based on + [Ord.to_string]. *) val print : partition -> Buffer.t (** {1 Predicates} *) @@ -58,7 +64,8 @@ module type S = items [i] and [j] belong to the same equivalence class in the partition [p], that is, [i] and [j] have the same representative. In particular, if either [i] or [j] do not - belong to [p], the value of [is_equiv i j p] is [false].*) + belong to [p], the value of [is_equiv i j p] is [false]. See + [mem] above. *) val is_equiv : item -> item -> partition -> bool end diff --git a/Partition0.ml b/Partition0.ml index 6ba824e..cd8b26f 100644 --- a/Partition0.ml +++ b/Partition0.ml @@ -2,15 +2,12 @@ module Make (Item: Partition.Item) = struct - type item = Item.t let equal i j = Item.compare i j = 0 module ItemMap = Map.Make (Item) - type height = int - type partition = item ItemMap.t type t = partition @@ -23,14 +20,14 @@ module Make (Item: Partition.Item) = else repr parent partition let is_equiv (i: item) (j: item) (p: partition) : bool = - try equal (repr i p) (repr j p) with - Not_found -> false + try equal (repr i p) (repr j p) with Not_found -> false let get_or_set (i: item) (p: partition) : item * partition = try repr i p, p with Not_found -> i, ItemMap.add i i p - let repr item partition = - try Some (repr item partition) with Not_found -> None + let mem i p = try Some (repr i p) with Not_found -> None + + let repr i p = try repr i p with Not_found -> i let equiv (i: item) (j: item) (p: partition) : partition = let ri, p = get_or_set i p in @@ -48,6 +45,5 @@ module Make (Item: Partition.Item) = Printf.sprintf "%s -> %s\n" (Item.to_string src) (Item.to_string dst) in Buffer.add_string buffer link - in ItemMap.iter print p; buffer - + in (ItemMap.iter print p; buffer) end diff --git a/Partition1.ml b/Partition1.ml index 07323f4..7d9320a 100644 --- a/Partition1.ml +++ b/Partition1.ml @@ -1,5 +1,5 @@ (* Persistent implementation of Union/Find with height-balanced - forests and without path compression: O(n*log(n)). + forests and no path compression: O(n*log(n)). In the definition of type [t], the height component is that of the source, that is, if [ItemMap.find i m = (j,h)], then [h] is the @@ -26,18 +26,18 @@ module Make (Item: Partition.Item) = let j, _ as i' = ItemMap.find i p in if equal i j then i' else seek j p - let repr item partition = fst (seek item partition) + let repr i p = fst (seek i p) let is_equiv (i: item) (j: item) (p: partition) : bool = - try equal (repr i p) (repr j p) with - Not_found -> false - - let repr item partition = - try Some (repr item partition) with Not_found -> None + try equal (repr i p) (repr j p) with Not_found -> false let get_or_set (i: item) (p: partition) = try seek i p, p with - Not_found -> let i' = i,0 in (i', ItemMap.add i i' p) + Not_found -> let i' = i,0 in i', ItemMap.add i i' p + + let mem i p = try Some (repr i p) with Not_found -> None + + let repr i p = try repr i p with Not_found -> i let equiv (i: item) (j: item) (p: partition) : partition = let (ri,hi), p = get_or_set i p in diff --git a/Partition2.ml b/Partition2.ml index bfb9e26..ef2f7e7 100644 --- a/Partition2.ml +++ b/Partition2.ml @@ -1,5 +1,5 @@ (** Persistent implementation of the Union/Find algorithm with - height-balanced forests and without path compression. *) + height-balanced forests and no path compression. *) module Make (Item: Partition.Item) = struct @@ -59,19 +59,20 @@ module Make (Item: Partition.Item) = Root hi -> i,hi | Link (j,_) -> seek j p - let repr item partition = fst (seek item partition) + let repr i p = fst (seek i p) let is_equiv (i: item) (j: item) (p: partition) : bool = try equal (repr i p) (repr j p) with Not_found -> false - let repr item partition = - try Some (repr item partition) with Not_found -> None - let get_or_set (i: item) (p: partition) = try seek i p, p with Not_found -> let n = i,0 in (n, root n p) + let mem i p = try Some (repr i p) with Not_found -> None + + let repr i p = try repr i p with Not_found -> i + let equiv (i: item) (j: item) (p: partition) : partition = let (ri,hi as ni), p = get_or_set i p in let (rj,hj as nj), p = get_or_set j p in diff --git a/Partition3.ml b/Partition3.ml index e831990..42fcd7a 100644 --- a/Partition3.ml +++ b/Partition3.ml @@ -14,7 +14,11 @@ module Make (Item: Partition.Item) = upwardly and otherwise is a link to another node. Those trees are height-balanced. The type [node] implements nodes in those trees. *) - type node = {item: item; mutable height: int; mutable parent: node} + type node = { + item : item; + mutable height : int; + mutable parent : node + } module ItemMap = Map.Make (Item) @@ -39,21 +43,22 @@ module Make (Item: Partition.Item) = if node.parent == node then node else find_root node.parent in find_root (ItemMap.find i p) - let repr item partition = (seek item partition).item + let repr i p = (seek i p).item let is_equiv (i: item) (j: item) (p: partition) : bool = try equal (repr i p) (repr j p) with Not_found -> false - let repr item partition = - try Some (repr item partition) with Not_found -> None - let get_or_set item (p: partition) = try seek item p, p with Not_found -> let rec loop = {item; height=0; parent=loop} in loop, ItemMap.add item loop p + let mem i p = try Some (repr i p) with Not_found -> None + + let repr i p = try repr i p with Not_found -> i + let link src dst = src.parent <- dst let equiv (i: item) (j: item) (p: partition) : partition =