]> matita.cs.unibo.it Git - helm.git/commitdiff
Naif version of the union find
authorAndrea Asperti <andrea.asperti@unibo.it>
Thu, 5 Nov 2009 15:10:55 +0000 (15:10 +0000)
committerAndrea Asperti <andrea.asperti@unibo.it>
Thu, 5 Nov 2009 15:10:55 +0000 (15:10 +0000)
helm/software/components/extlib/hExtlib.ml
helm/software/components/extlib/hExtlib.mli

index 237d4e77f34e2e1611fa8d04ab5639932fd24f2b..13dd2f2665da9fa8f8aed93c542d18b20ebf2c15 100644 (file)
@@ -331,6 +331,49 @@ let rec list_assoc_all a = function
    | _ :: tl                 -> list_assoc_all a tl
 ;;
 
+let rec rm_assoc n = function
+  | [] -> assert false
+  | (x,i)::tl when n=x -> i,tl
+  | p::tl -> let i,tl = rm_assoc n tl in i,p::tl
+;;
+
+(* naif implementation of the union-find merge operation
+   canonicals maps elements to canonicals
+   elements maps canonicals to the classes *)
+let merge canonicals elements n m =
+  let cn,canonicals = rm_assoc n canonicals in
+  let cm,canonicals = rm_assoc m canonicals in
+  let ln,elements = rm_assoc cn elements in
+  let lm,elements = rm_assoc cm elements in
+  let canonicals = 
+    (n,cm)::(m,cm)::List.map 
+      (fun ((x,xc) as p)  -> 
+        if xc = cn then (x,cm) else p) canonicals
+  in 
+  let elements = (cm,ln@lm)::elements 
+  in
+    canonicals,elements
+;;
+
+(* f x gives the direct dependencies of x;
+   x must not belong to (f x) and (f x) must
+   be a subset of l *)
+let clusters f l =
+  let canonicals = List.map (fun x -> (x,x)) l in
+  let elements = List.map (fun x -> (x,[x])) l in
+  let _,elements = 
+    List.fold_left 
+     (fun (canonicals,elements) x ->
+       let dep = f x in
+        List.fold_left 
+          (fun (canonicals,elements) d ->
+             merge canonicals elements d x) 
+          (canonicals,elements) dep)
+     (canonicals,elements) l
+  in
+    List.map snd elements
+;;
+
 (** {2 File predicates} *)
 
 let is_dir fname =
index 34b4e3103680d0ae90a02882e9d53e09d0f3bd54..c0b8c466737729ce177fa9ba8c5047cff27dafad 100644 (file)
@@ -133,6 +133,9 @@ val list_seq: int -> int -> int list
 (* like List.assoc but returns all bindings *)
 val list_assoc_all: 'a -> ('a * 'b) list -> 'b list
 
+val rm_assoc : 'a -> ('a * 'b) list -> 'b * ('a * 'b) list
+
+val clusters : ('a -> 'a list) -> 'a list -> 'a list list
 (** {2 Debugging & Profiling} *)
 
 type profiler = { profile : 'a 'b. ('a -> 'b) -> 'a -> 'b }