3 (*****************************************************************************)
6 (* todo: could take an incr/decr func in param, to make it generic
7 * opti: remember the min/max (optimisation to have intersect biggest x -> x)
8 * opti: avoid all those rev, and avoid the intervise
9 * (but yes the algo are then more complex :)
10 * opti: balanced set intervalle
13 (*****************************************************************************)
14 type seti
= elt list
(* last elements is in first pos, ordered reverse *)
15 and elt
= Exact
of int | Interv
of int * int
17 (* invariant= ordered list, no incoherent interv (one elem or zero elem),
18 * merged (intervalle are separated) *)
21 xs
+> List.fold_left
(fun min e
->
24 if i
<= min
then pr2
(sprintf
"i = %d, min = %d" i min
);
25 (* todo: should be even stronger, shoud be i > min+1 *)
34 ignore
(aux min_int
(List.rev xs
));
37 let string_of_seti xs
=
39 join
"," (xs
+> List.rev
+> map
(function
40 | (Exact i
) -> string_of_int i
41 | (Interv
(i
,j
)) -> Printf.sprintf
"%d - %d" i j
)) ^
44 (*****************************************************************************)
47 let pack newi j
= function
48 | [] -> [Interv
(newi
,j
)]
49 | (Exact z
)::xs
-> (Interv
(newi
, j
))::(if newi
= z
then xs
else (Exact z
)::xs
)
50 | (Interv
(i'
, j'
))::xs
->
52 then (Interv
(i'
, j
))::xs
(* merge *)
53 else (Interv
(newi
, j
))::(Interv
(i'
, j'
))::xs
56 (* the only possible merges are when x = i-1, otherwise, the job is done before *)
57 let rec (add2
: int -> seti
-> seti
) = fun x
-> function
59 | (Exact i
)::xs
when x
> i
+1 -> (Exact x
)::(Exact i
)::xs
60 | (Interv
(i
,j
)::xs
) when x
> j
+1 -> (Exact x
)::(Interv
(i
,j
))::xs
61 | (Interv
(i
,j
)::xs
) when x
= j
+1 -> (Interv
(i
,x
))::xs
62 | (Exact i
)::xs
when x
= i
+1 -> (Interv
(i
,x
))::xs
64 | (Exact i
)::xs
when i
= x
-> (Exact i
)::xs
65 | (Interv
(i
,j
)::xs
) when x
<= j
&& x
>= i
-> (Interv
(i
,j
))::xs
67 (* let _ = log "Cache miss" in *)
70 | (Exact i
)::xs
when x
= i
-1 -> pack x i xs
71 | (Exact i
)::xs
when x
< i
-1 -> (Exact i
)::add x xs
73 | (Interv
(i
,j
)::xs
) when x
= i
-1 -> pack x j xs
74 | (Interv
(i
,j
)::xs
) when x
< i
-1 -> (Interv
(i
,j
))::add x xs
75 | _ -> raise Impossible
77 and add x y
= let _ = count5
() in add2 x y
80 let rec tolist2 = function
82 | (Exact i
)::xs
-> i
::tolist2 xs
83 | (Interv
(i
,j
))::xs
-> enum i j
@ tolist2 xs
84 let rec tolist xs
= List.rev
(tolist2 xs
)
86 let rec fromlist = function xs
-> List.fold_left
(fun a e
-> add e a
) empty xs
88 let intervise = function
89 | Exact x
-> Interv
(x
,x
)
91 let exactize = function
92 | Interv
(i
,j
) when i
= j
-> Exact i
94 let exactize2 x y
= if x
= y
then Exact x
else Interv
(x
,y
)
97 let rec (remove
: int -> seti
-> seti
) = fun x xs
->
99 | [] -> [] (* pb, not in *)
103 | Sup
-> xs
(* pb, not in *)
104 | Inf
-> (Exact z
)::remove x zs
106 | (Interv
(i
,j
)::zs
) ->
107 if x
> j
then xs
(* pb not in *)
109 if x
>= i
&& x
<= j
then
111 let _ = assert (j
> i
) in (* otherwise can lead to construct seti such as [7,6] when removing 6 from [6,6] *)
113 | _ when x
= i
-> [exactize2 (i
+1) j
]
114 | _ when x
= j
-> [exactize2 i
(j
-1)]
115 | _ -> [exactize2 (x
+1) j
; exactize2 i
(x
-1)]
117 else (Interv
(i
,j
))::remove x zs
119 (* let _ = Example (remove 635 [Interv (3, 635)] = [Interv (3, 634)]) *)
120 (* let _ = Example (remove 2 [Interv (6, 7); Interv(1,4)] = [Interv (6,7); Interv (3,4); Exact 1]) *)
121 (* let _ = Example (remove 6 [Interv (6, 7); Interv(1,4)] = [Exact 7; Interv (1,4)]) *)
122 (* let _ = Example (remove 1 [Interv (6, 7); Interv(1,2)] = [Interv (6,7); Exact 2]) *)
123 (* let _ = Example (remove 3 [Interv (1, 7)] = [Interv (4,7); Interv (1,2)]) *)
124 let _ = assert_equal
(remove
3 [Interv
(1, 7)]) [Interv
(4,7); Interv
(1,2)]
125 let _ = assert_equal
(remove
4 [Interv
(3, 4)]) [Exact
(3);]
126 (* let _ = example (try (ignore(remove 6 [Interv (6, 6)] = []); false) with _ -> true) *)
129 let rec mem e
= function
137 | (Interv
(i
,j
)::xs
) ->
140 if e
>= i
&& e
<= j
then true
143 let iter f xs
= xs
+> List.iter
146 | Interv
(i
, j
) -> for k
= i
to j
do f k
done
149 let is_empty xs
= xs
= []
150 let choose = function
151 | [] -> failwith
"not supposed to be called with empty set"
153 | (Interv
(i
,j
))::xs
-> i
155 let elements xs
= tolist xs
156 let rec cardinal = function
158 | (Exact
_)::xs
-> 1+cardinal xs
159 | (Interv
(i
,j
)::xs
) -> (j
-i
) +1 + cardinal xs
161 (*****************************************************************************)
162 (* TODO: could return corresponding osetb ? *)
163 let rec inter xs ys
=
164 let rec aux = fun xs ys
->
170 | (Interv
(i1
, j1
), Interv
(i2
, j2
)) ->
171 (match i1
<=> i2
with
173 (match j1
<=> j2
with
174 | Equal
-> (Interv
(i1
,j1
))::aux xs ys
177 | Inf
-> (Interv
(i1
, j1
))::aux xs
((Interv
(j1
+1, j2
))::ys
)
178 (* [ ] [ TODO? could have [ so cant englobe right now, but would be better *)
180 | Sup
-> (Interv
(i1
, j2
))::aux ((Interv
(j2
+1, j1
))::xs
) ys
185 if j1
< i2
then aux xs
(y
::ys
) (* need order ? *)
189 (match j1
<=> j2
with
190 | Equal
-> (Interv
(i2
, j1
))::aux xs ys
193 | Inf
-> (Interv
(i2
, j1
))::aux xs
((Interv
(j1
+1, j2
))::ys
)
196 | Sup
-> (Interv
(i2
, j2
))::aux ((Interv
(j2
+1, j1
))::xs
) ys
200 | Sup
-> aux (y
::ys
) (x
::xs
) (* can cos commutative *)
202 | _ -> raise Impossible
(* intervise *)
205 (* TODO avoid the rev rev, but aux good ? need order ? *)
206 List.rev_map
exactize (aux (List.rev_map
intervise xs
) (List.rev_map
intervise ys
))
209 let rec aux = fun xs ys
->
215 | (Interv
(i1
, j1
), Interv
(i2
, j2
)) ->
216 (match i1
<=> i2
with
218 (match j1
<=> j2
with
219 | Equal
-> (Interv
(i1
,j1
))::aux xs ys
222 | Inf
-> (Interv
(i1
, j1
))::aux xs
((Interv
(j1
+1, j2
))::ys
)
223 (* [ ] [ TODO? could have [ so cant englobe right now, but would be better *)
225 | Sup
-> (Interv
(i1
, j2
))::aux ((Interv
(j2
+1, j1
))::xs
) ys
230 if j1
< i2
then Interv
(i1
, j1
):: aux xs
(y
::ys
)
234 (match j1
<=> j2
with
235 | Equal
-> (Interv
(i1
, j1
))::aux xs ys
238 | Inf
-> (Interv
(i1
, j1
))::aux xs
((Interv
(j1
+1, j2
))::ys
)
241 | Sup
-> (Interv
(i1
, j2
))::aux ((Interv
(j2
+1, j1
))::xs
) ys
245 | Sup
-> aux (y
::ys
) (x
::xs
) (* can cos commutative *)
247 | _ -> raise Impossible
(* intervise *)
250 (* union_set (tolist xs) (tolist ys) +> fromlist *)
251 List.rev_map
exactize (aux (List.rev_map
intervise xs
) (List.rev_map
intervise ys
))
253 (* bug/feature: discovered by vlad rusu, my invariant for intervalle is
254 * not very strong, should return (Interv (1,4)) *)
255 (* let _ = Example (union [Interv (1, 4)] [Interv (1, 3)] = ([Exact 4; Interv (1,3)])) *)
258 let rec aux = fun xs ys
->
264 | (Interv
(i1
, j1
), Interv
(i2
, j2
)) ->
265 (match i1
<=> i2
with
267 (match j1
<=> j2
with
271 | Inf
-> aux xs
((Interv
(j1
+1, j2
))::ys
)
274 | Sup
-> aux ((Interv
(j2
+1, j1
))::xs
) ys
279 if j1
< i2
then Interv
(i1
, j1
):: aux xs
(y
::ys
)
283 (match j1
<=> j2
with
284 | Equal
-> (Interv
(i1
, i2
-1))::aux xs ys
(* -1 cos exlude [ *)
287 | Inf
-> (Interv
(i1
, i2
-1))::aux xs
((Interv
(j1
+1, j2
))::ys
)
290 | Sup
-> (Interv
(i1
, i2
-1))::aux ((Interv
(j2
+1, j1
))::xs
) ys
295 if j2
< i1
then aux (x
::xs
) ys
299 (match j1
<=> j2
with
303 | Inf
-> aux xs
((Interv
(j1
+1, j2
))::ys
)
306 | Sup
-> aux ((Interv
(j2
+1, j1
))::xs
) ys
311 | _ -> raise Impossible
(* intervise *)
314 (* minus_set (tolist xs) (tolist ys) +> fromlist *)
315 List.rev_map
exactize (aux (List.rev_map
intervise xs
) (List.rev_map
intervise ys
))
318 (* let _ = Example (diff [Interv (3,7)] [Interv (4,5)] = [Interv (6, 7); Exact 3]) *)
320 (*****************************************************************************)
321 let rec debug = function
323 | (Exact i
)::xs
-> (Printf.sprintf
"Exact:%d;" i
) ^
(debug xs
)
324 | (Interv
(i
,j
)::xs
) -> (Printf.sprintf
"Interv:(%d,%d);" i j
) ^
debug xs
326 (*****************************************************************************)
327 (* if operation return wrong result, then may later have to patch them *)
328 let patch1 xs
= List.map
exactize xs
329 let patch2 xs
= xs
+> List.map
(fun e
->
331 | Interv
(i
,j
) when i
> j
&& i
= j
+1 ->
332 let _ = pr2
(sprintf
"i = %d, j = %d" i j
) in
338 xs
+> List.fold_left
(fun (min
,acc
) e
->
343 else (i
, (Exact i
)::acc
)
345 (j
, (Interv
(i
,j
)::acc
))
348 aux min_int
(List.rev xs
) +> snd