Release coccinelle-0.2.1-rc1
[bpt/coccinelle.git] / commons / seti.ml
index 8313657..19896b2 100644 (file)
@@ -5,38 +5,38 @@ open Common
 
 (* todo: could take an incr/decr func in param, to make it generic
  * opti: remember the min/max (optimisation to have intersect biggest x -> x)
- * opti: avoid all those rev, and avoid the intervise 
+ * opti: avoid all those rev, and avoid the intervise
  * (but yes the algo are then more complex :)
- * opti: balanced set intervalle 
+ * opti: balanced set intervalle
 *)
 
 (*****************************************************************************)
 type seti = elt list (* last elements is in first pos, ordered reverse *)
   and elt = Exact of int | Interv of int * int
 
-(* invariant= ordered list, no incoherent interv (one elem or zero elem), 
+(* invariant= ordered list, no incoherent interv (one elem or zero elem),
  * merged (intervalle are separated) *)
-let invariant xs = 
-  let rec aux min xs = 
-    xs +> List.fold_left (fun min e -> 
-      match e with 
-      | Exact i -> 
+let invariant xs =
+  let rec aux min xs =
+    xs +> List.fold_left (fun min e ->
+      match e with
+      | Exact i ->
           if i <= min then pr2 (sprintf "i = %d, min = %d" i min);
           (* todo: should be even stronger, shoud be i > min+1 *)
           assert (i > min);
           i
-      | Interv (i,j) -> 
+      | Interv (i,j) ->
           assert (i > min);
           assert (j > i);
           j
     ) min
   in
-  ignore(aux min_int (List.rev xs)); 
+  ignore(aux min_int (List.rev xs));
   ()
 
-let string_of_seti xs = 
-  "[" ^  
-    join "," (xs +> List.rev +> map (function 
+let string_of_seti xs =
+  "[" ^
+    join "," (xs +> List.rev +> map (function
     | (Exact i) -> string_of_int i
     | (Interv (i,j)) -> Printf.sprintf "%d - %d" i j)) ^
     "]"
@@ -46,42 +46,42 @@ let empty = []
 
 let pack newi j = function
   | [] -> [Interv (newi,j)]
-  | (Exact z)::xs -> 
+  | (Exact z)::xs ->
       (Interv (newi, j))::(if newi =|= z then xs else (Exact z)::xs)
-  | (Interv (i', j'))::xs -> 
-      if newi =|= j' 
+  | (Interv (i', j'))::xs ->
+      if newi =|= j'
       then (Interv (i', j))::xs  (* merge *)
       else (Interv (newi, j))::(Interv (i', j'))::xs
-        
+
 
 (* the only possible merges are when x = i-1, otherwise, the job is done before *)
-let rec (add2: int -> seti -> seti) = fun x -> function 
+let rec (add2: int -> seti -> seti) = fun x -> function
   | [] -> [Exact x]
   | (Exact i)::xs when x > i+1 -> (Exact x)::(Exact i)::xs
   | (Interv (i,j)::xs) when x > j+1 -> (Exact x)::(Interv (i,j))::xs
   | (Interv (i,j)::xs) when x =|= j+1 -> (Interv (i,x))::xs
   | (Exact i)::xs when x =|= i+1 -> (Interv (i,x))::xs
-      
+
   | (Exact i)::xs when i =|= x   -> (Exact i)::xs
   | (Interv (i,j)::xs) when x <= j && x >= i -> (Interv (i,j))::xs
-  | other -> 
+  | other ->
 (*         let _ = log "Cache miss" in *)
       let _ = count2 () in
       (match other with
-      |       (Exact i)::xs when x =|= i-1 -> pack x i xs 
+      |       (Exact i)::xs when x =|= i-1 -> pack x i xs
       |       (Exact i)::xs when x < i-1 -> (Exact i)::add x xs
-                
+
       |       (Interv (i,j)::xs) when x =|= i-1 -> pack x j xs
       |       (Interv (i,j)::xs) when x < i-1 -> (Interv (i,j))::add x xs
       |       _ -> raise Impossible
       )
-and add x y = let _ = count5 () in add2 x y                                                         
+and add x y = let _ = count5 () in add2 x y
+
 
-            
 let rec tolist2 = function
   | [] -> []
   | (Exact i)::xs -> i::tolist2 xs
-  | (Interv (i,j))::xs -> enum i j @ tolist2 xs 
+  | (Interv (i,j))::xs -> enum i j @ tolist2 xs
 let rec tolist xs = List.rev (tolist2 xs)
 
 let rec fromlist = function xs -> List.fold_left (fun a e -> add e a) empty xs
@@ -95,18 +95,18 @@ let exactize = function
 let exactize2 x y = if x =|= y then Exact x else Interv (x,y)
 
 
-let rec (remove: int -> seti -> seti) = fun x xs -> 
+let rec (remove: int -> seti -> seti) = fun x xs ->
   match xs with
   | [] -> [] (*  pb, not in  *)
-  | (Exact z)::zs -> 
+  | (Exact z)::zs ->
       (match x <=> z with
       | Equal -> zs
       | Sup -> xs  (*  pb, not in *)
       | Inf -> (Exact z)::remove x zs
-      ) 
-  | (Interv (i,j)::zs) -> 
+      )
+  | (Interv (i,j)::zs) ->
       if x > j then xs (*  pb not in *)
-      else 
+      else
         if x >= i && x <= j then
           (
             let _ = assert (j > i) in (* otherwise can lead to construct seti such as [7,6] when removing 6 from [6,6] *)
@@ -126,51 +126,51 @@ let _ = assert_equal (remove 3 [Interv (1, 7)])  [Interv (4,7); Interv (1,2)]
 let _ = assert_equal (remove 4 [Interv (3, 4)])  [Exact (3);]
 (* let _ = example (try (ignore(remove 6 [Interv (6, 6)] = []); false) with _ -> true)   *)
 
-    
+
 let rec mem e = function
-  | [] -> false 
-  | (Exact x)::xs -> 
+  | [] -> false
+  | (Exact x)::xs ->
       (match e <=> x with
       | Equal -> true
       | Sup -> false
       | Inf -> mem e xs
-      ) 
-  | (Interv (i,j)::xs) -> 
+      )
+  | (Interv (i,j)::xs) ->
       if e > j then false
-      else 
+      else
         if e >= i && e <= j then true
       else mem e xs
 
-let iter f xs = xs +> List.iter 
+let iter f xs = xs +> List.iter
   (function
   | Exact i -> f i
   | Interv (i, j) -> for k = i to j do f k done
   )
-        
+
 let is_empty xs = xs =*= []
 let choose = function
   | [] -> failwith "not supposed to be called with empty set"
   | (Exact i)::xs -> i
   | (Interv (i,j))::xs -> i
-      
+
 let elements xs = tolist xs
 let rec cardinal = function
   | [] -> 0
   | (Exact _)::xs -> 1+cardinal xs
   | (Interv (i,j)::xs) -> (j-i) +1 + cardinal xs
-      
+
 (*****************************************************************************)
 (*  TODO: could return corresponding osetb ? *)
-let rec inter xs ys = 
-  let rec aux = fun xs ys -> 
+let rec inter xs ys =
+  let rec aux = fun xs ys ->
     match (xs, ys) with
     | (_, []) -> []
     | ([],_)  -> []
-    | (x::xs, y::ys) -> 
+    | (x::xs, y::ys) ->
         (match (x, y) with
-        | (Interv (i1, j1), Interv (i2, j2)) -> 
+        | (Interv (i1, j1), Interv (i2, j2)) ->
             (match i1 <=> i2 with
-            | Equal -> 
+            | Equal ->
                 (match j1 <=> j2 with
                 | Equal -> (Interv (i1,j1))::aux xs ys
                     (*  [  ] *)
@@ -182,11 +182,11 @@ let rec inter xs ys =
                     (*  [    ] *)
                     (*  [ ] [       same *)
                 )
-            | Inf -> 
+            | Inf ->
                 if j1 < i2 then aux xs (y::ys) (* need order ? *)
                   (*  [    ] *)
                   (*         [ ] *)
-                else 
+                else
                   (match j1 <=> j2 with
                   | Equal -> (Interv (i2, j1))::aux xs ys
                       (*  [    ] *)
@@ -205,17 +205,17 @@ let rec inter xs ys =
   in
   (* TODO avoid the rev rev, but aux good ? need order ?  *)
   List.rev_map exactize (aux (List.rev_map intervise xs) (List.rev_map intervise ys))
-      
-let union xs ys = 
-  let rec aux = fun xs ys -> 
+
+let union xs ys =
+  let rec aux = fun xs ys ->
     match (xs, ys) with
     | (vs, []) -> vs
     | ([],vs)  -> vs
-    | (x::xs, y::ys) -> 
+    | (x::xs, y::ys) ->
         (match (x, y) with
-        | (Interv (i1, j1), Interv (i2, j2)) -> 
+        | (Interv (i1, j1), Interv (i2, j2)) ->
             (match i1 <=> i2 with
-            | Equal -> 
+            | Equal ->
                 (match j1 <=> j2 with
                 | Equal -> (Interv (i1,j1))::aux xs ys
                     (*  [  ] *)
@@ -227,11 +227,11 @@ let union xs ys =
                     (*  [    ] *)
                     (*  [ ] [       same *)
                 )
-            | Inf -> 
+            | Inf ->
                 if j1 < i2 then Interv (i1, j1):: aux xs (y::ys)
                   (*  [    ] *)
                   (*         [ ] *)
-                else 
+                else
                   (match j1 <=> j2 with
                   | Equal -> (Interv (i1, j1))::aux xs ys
                       (*  [    ] *)
@@ -255,16 +255,16 @@ let union xs ys =
  * not very strong, should return (Interv (1,4)) *)
 (* let _ = Example (union [Interv (1, 4)] [Interv (1, 3)] = ([Exact 4; Interv (1,3)])) *)
 
-let diff xs ys = 
-  let rec aux = fun xs ys -> 
+let diff xs ys =
+  let rec aux = fun xs ys ->
     match (xs, ys) with
     | (vs, []) -> vs
     | ([],vs)  -> []
-    | (x::xs, y::ys) -> 
+    | (x::xs, y::ys) ->
         (match (x, y) with
-        | (Interv (i1, j1), Interv (i2, j2)) -> 
+        | (Interv (i1, j1), Interv (i2, j2)) ->
             (match i1 <=> i2 with
-            | Equal -> 
+            | Equal ->
                 (match j1 <=> j2 with
                 | Equal -> aux xs ys
                     (*  [  ] *)
@@ -276,11 +276,11 @@ let diff xs ys =
                     (*  [    ] *)
                     (*  [ ]  *)
                 )
-            | Inf -> 
+            | Inf ->
                 if j1 < i2 then Interv (i1, j1):: aux xs (y::ys)
                   (*  [    ] *)
                   (*         [ ] *)
-                else 
+                else
                   (match j1 <=> j2 with
                   | Equal -> (Interv (i1, i2-1))::aux xs ys (* -1 cos exlude [ *)
                       (*  [    ] *)
@@ -292,11 +292,11 @@ let diff xs ys =
                       (*  [       ] *)
                       (*     [ ]  *)
                   )
-            | Sup -> 
+            | Sup ->
                 if j2 < i1 then aux (x::xs) ys
                   (*       [    ] *)
                   (*  [ ] *)
-                else 
+                else
                   (match j1 <=> j2 with
                   | Equal -> aux xs ys
                       (*         [    ] *)
@@ -317,7 +317,7 @@ let diff xs ys =
 
 
 (*     let _ = Example (diff [Interv (3,7)] [Interv (4,5)] = [Interv (6, 7); Exact 3]) *)
+
 (*****************************************************************************)
 let rec debug = function
   | [] -> ""
@@ -327,22 +327,22 @@ let rec debug = function
 (*****************************************************************************)
 (* if operation return wrong result, then may later have to patch them *)
 let patch1 xs = List.map exactize xs
-let patch2 xs = xs +> List.map (fun e -> 
+let patch2 xs = xs +> List.map (fun e ->
   match e with
-  | Interv (i,j) when i > j && i =|= j+1 -> 
+  | Interv (i,j) when i > j && i =|= j+1 ->
       let _ = pr2 (sprintf "i = %d, j = %d" i j) in
       Exact i
   | e -> e
 )
-let patch3 xs = 
-  let rec aux min xs = 
-    xs +> List.fold_left (fun (min,acc) e -> 
-      match e with 
-      | Exact i -> 
-          if i =|= min 
+let patch3 xs =
+  let rec aux min xs =
+    xs +> List.fold_left (fun (min,acc) e ->
+      match e with
+      | Exact i ->
+          if i =|= min
           then (min, acc)
           else (i, (Exact i)::acc)
-      | Interv (i,j) -> 
+      | Interv (i,j) ->
           (j, (Interv (i,j)::acc))
     ) (min, [])
   in