123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566moduletypeOrderedType=Set.OrderedTypemoduletypeS=sigtypeelttypetvalempty:tvalis_empty:t->boolvalmem:elt->t->boolvaladd:elt->t->tvalsingleton:elt->tvalremove:elt->t->tvalunion:t->t->tvalinter:t->t->tvaldisjoint:t->t->boolvaldiff:t->t->tvalcompare:t->t->intvalequal:t->t->boolvalsubset:t->t->boolvaliter:(elt->unit)->t->unitvalmap:(elt->elt)->t->tvalfold:(elt->'a->'a)->t->'a->'avalfor_all:(elt->bool)->t->boolvalexists:(elt->bool)->t->boolvalfilter:(elt->bool)->t->tvalfilter_map:(elt->eltoption)->t->tvalpartition:(elt->bool)->t->(t*t)valcardinal:t->intvalelements:t->eltlistvalmin_elt:t->eltvalmin_elt_opt:t->eltoptionvalmax_elt:t->eltvalmax_elt_opt:t->eltoptionvalchoose:t->eltvalchoose_opt:t->eltoptionvalsplit:elt->t->(t*bool*t)valfind:elt->t->eltvalfind_opt:elt->t->eltoptionvalfind_first:(elt->bool)->t->eltvalfind_first_opt:(elt->bool)->t->eltoptionvalfind_last:(elt->bool)->t->eltvalfind_last_opt:(elt->bool)->t->eltoptionvalof_list:eltlist->tvalto_seq_from:elt->t->eltStdcompat__seq.tvalto_seq:t->eltStdcompat__seq.tvalto_rev_seq:t->eltStdcompat__seq.tvaladd_seq:eltStdcompat__seq.t->t->tvalof_seq:eltStdcompat__seq.t->tend(*
module Make = Set.Make
*)moduleMake(Ord:OrderedType)=structincludeSet.Make(Ord)typeinternal=Empty|Nodeofinternal*elt*internal*intexternalt_of_internal:internal->t="%identity"externalinternal_of_t:t->internal="%identity"letheight=function|Empty->0|Node(_,_,_,h)->hletcreatelvr=lethl=heightlinlethr=heightrinNode(l,v,r,(ifhl>=hrthenhl+1elsehr+1))letballvr=lethl=matchlwithEmpty->0|Node(_,_,_,h)->hinlethr=matchrwithEmpty->0|Node(_,_,_,h)->hinifhl>hr+2thenbeginmatchlwithEmpty->invalid_arg"Set.bal"|Node(ll,lv,lr,_)->ifheightll>=heightlrthencreatelllv(createlrvr)elsebeginmatchlrwithEmpty->invalid_arg"Set.bal"|Node(lrl,lrv,lrr,_)->create(createlllvlrl)lrv(createlrrvr)endendelseifhr>hl+2thenbeginmatchrwithEmpty->invalid_arg"Set.bal"|Node(rl,rv,rr,_)->ifheightrr>=heightrlthencreate(createlvrl)rvrrelsebeginmatchrlwithEmpty->invalid_arg"Set.bal"|Node(rll,rlv,rlr,_)->create(createlvrll)rlv(createrlrrvrr)endendelseNode(l,v,r,(ifhl>=hrthenhl+1elsehr+1))letrecadd_min_elementx=function|Empty->internal_of_t(singletonx)|Node(l,v,r,_)->bal(add_min_elementxl)vrletrecadd_max_elementx=function|Empty->internal_of_t(singletonx)|Node(l,v,r,_)->ballv(add_max_elementxr)letrecjoinlvr=match(l,r)with(Empty,_)->add_min_elementvr|(_,Empty)->add_max_elementvl|(Node(ll,lv,lr,lh),Node(rl,rv,rr,rh))->iflh>rh+2thenballllv(joinlrvr)elseifrh>lh+2thenbal(joinlvrl)rvrrelsecreatelvrlettry_joinlvr=if(l=Empty||Ord.compare(max_elt(t_of_internall))v<0)&&(r=Empty||Ord.comparev(min_elt(t_of_internalr))<0)thenjoinlvrelseinternal_of_t(union(t_of_internall)(addv(t_of_internalr)))letrecremove_min_elt=function|Empty->invalid_arg"Set.remove_min_elt"|Node(Empty,_,r,_)->r|Node(l,v,r,_)->bal(remove_min_eltl)vrlettry_concatt1t2=match(t1,t2)with|(Empty,t)->t|(t,Empty)->t|(_,_)->try_joint1(min_elt(t_of_internalt2))(remove_min_eltt2)typeenumeration=End|Moreofelt*internal*enumerationletrecsnoc_enumse=matchswithEmpty->e|Node(l,v,r,_h)->snoc_enumr(More(v,l,e))letrecrev_seq_of_enum_c()=matchcwith|End->Stdcompat__seq.Nil|More(x,t,rest)->Stdcompat__seq.Cons(x,rev_seq_of_enum_(snoc_enumtrest))letto_rev_seq(s:t)=lets:internal=Obj.magicsinrev_seq_of_enum_(snoc_enumsEnd)(*
let to_rev_seq s =
Stdcompat__list.to_seq (List.rev (elements s))
*)(*
let of_list l = List.fold_left (fun s item -> add item s) empty l
*)(*
let rec iter f = function
| Empty -> ()
| Node (l, v, r, _) as t ->
iter f l;
f v;
iter f r
let iter (f : elt -> unit) (s : t) : unit =
iter f (internal_of_t s)
let rec fold f s a =
match s with
| Empty -> a
| Node (l, v, r, _) as t ->
let a = fold f l a in
let a = f v a in
fold f r a
let fold (f : elt -> 'a -> 'a) (s : t) (a : 'a) : 'a =
fold f (internal_of_t s) a
(*
let iter f s =
List.iter f (elements s)
let fold f s a =
List.fold_left (fun a item -> f item a) a (elements s)
*)
*)letrecfilter_mapf=function|Empty->Empty|Node(l,v,r,_)ast->(* enforce left-to-right evaluation order *)letl'=filter_mapflinletv'=fvinletr'=filter_mapfrinbeginmatchv'with|Somev'->ifl==l'&&v==v'&&r==r'thentelsetry_joinl'v'r'|None->try_concatl'r'endletfilter_map(f:elt->eltoption)(s:t):t=t_of_internal(filter_mapf(internal_of_ts))(*
type map_changed =
| Changed of t
| Unchanged of elt list
let filter_map f s =
match
fold (fun item accu ->
match accu, f item with
| Changed set, None -> Changed set
| Changed set, Some item' -> Changed (add item' set)
| Unchanged list, None -> Changed (of_list list)
| Unchanged list, Some item' ->
if item == item' then Unchanged (item :: list)
else Changed (add item' (of_list list)))
s (Unchanged [])
with
| Changed s -> s
| Unchanged _ -> s
*)(*
type split_bis =
| Found
| NotFound of internal * (unit -> internal)
let rec split_bis x = function
| Empty ->
NotFound (Empty, (fun () -> Empty))
| Node (l, v, r, _) ->
let c = Ord.compare x v in
if c = 0 then Found
else if c < 0 then
match split_bis x l with
| Found -> Found
| NotFound (ll, rl) -> NotFound (ll, (fun () -> join (rl ()) v r))
else
match split_bis x r with
| Found -> Found
| NotFound (lr, rr) -> NotFound (join l v lr, rr)
let rec disjoint s1 s2 =
match (s1, s2) with
(Empty, _) | (_, Empty) -> true
| (Node (l1, v1, r1, _), t2) ->
if s1 == s2 then false
else match split_bis v1 t2 with
NotFound(l2, r2) -> disjoint l1 l2 && disjoint r1 (r2 ())
| Found -> false
let disjoint (s1 : t) (s2 : t) : bool =
disjoint (internal_of_t s1) (internal_of_t s2)
(*
let disjoint s s' =
is_empty (inter s s')
*)
*)(*
let add_seq i m =
Stdcompat__seq.fold_left (fun s x -> add x s) m i
let of_seq i = add_seq i empty
let rec cons_enum s e =
match s with
Empty -> e
| Node (l, v, r, _h) -> cons_enum l (More(v, r, e))
let rec seq_of_enum_ c () = match c with
| End -> Stdcompat__seq.Nil
| More (x, t, rest) ->
Stdcompat__seq.Cons (x, seq_of_enum_ (cons_enum t rest))
let to_seq (s : t) =
let s : internal = Obj.magic s in
seq_of_enum_ (cons_enum s End)
let to_seq_from low s =
let s : internal = Obj.magic s in
let rec aux low s c = match s with
| Empty -> c
| Node (l, v, r, _h) ->
begin match Ord.compare v low with
| 0 -> More (v, r, c)
| n when n<0 -> aux low r c
| _ -> aux low l (More (v, r, c))
end
in
seq_of_enum_ (aux low s End)
(*
let to_seq s =
Stdcompat__list.to_seq (elements s)
let elements_from low s =
let rec cut l =
match l with
| [] -> []
| hd :: tl ->
if Ord.compare low hd < 0 then
cut tl
else
l in
cut (elements s)
let to_seq_from low s =
Stdcompat__list.to_seq (elements_from low s)
*)
*)(*
exception Find of elt
let rec find_internal x = function
Empty -> raise Not_found
| Node (l, v, r, _h) ->
let c = Ord.compare x v in
if c = 0 then v
else find_internal x (if c < 0 then l else r)
let find x (s : t) =
let s : internal = Obj.magic s in
find_internal x s
(*
let find x s =
try
iter (fun y ->
if Ord.compare x y = 0 then
raise (Find y)) s;
raise Not_found
with Find y -> y
*)
*)(*
let min_elt_opt s =
Stdcompat__tools.option_find min_elt s
let max_elt_opt s =
Stdcompat__tools.option_find max_elt s
let choose_opt s =
Stdcompat__tools.option_find choose s
let rec find_first_aux v0 f = function
Empty ->
v0
| Node (l, v, r, _h) ->
if f v then
find_first_aux v f l
else
find_first_aux v0 f r
let rec find_first_internal f = function
Empty ->
raise Not_found
| Node (l, v, r, _h) ->
if f v then
find_first_aux v f l
else
find_first_internal f r
let find_first f (s : t) =
let s : internal = Obj.magic s in
find_first_internal f s
let rec find_first_opt_aux v0 f = function
Empty ->
Some v0
| Node (l, v, r, _h) ->
if f v then
find_first_opt_aux v f l
else
find_first_opt_aux v0 f r
let rec find_first_opt_internal f = function
Empty ->
None
| Node (l, v, r, _h) ->
if f v then
find_first_opt_aux v f l
else
find_first_opt_internal f r
let find_first_opt f (s : t) =
let s : internal = Obj.magic s in
find_first_opt_internal f s
let rec find_last_aux v0 f = function
Empty ->
v0
| Node (l, v, r, _h) ->
if f v then
find_last_aux v f r
else
find_last_aux v0 f l
let rec find_last_internal f = function
Empty ->
raise Not_found
| Node (l, v, r, _h) ->
if f v then
find_last_aux v f r
else
find_last_internal f l
let find_last f (s : t) =
let s : internal = Obj.magic s in
find_last_internal f s
let rec find_last_opt_aux v0 f = function
Empty ->
Some v0
| Node (l, v, r, _h) ->
if f v then
find_last_opt_aux v f r
else
find_last_opt_aux v0 f l
let rec find_last_opt_internal f = function
Empty ->
None
| Node (l, v, r, _h) ->
if f v then
find_last_opt_aux v f r
else
find_last_opt_internal f l
let find_last_opt f (s : t) =
let s : internal = Obj.magic s in
find_last_opt_internal f s
let rec find_opt_internal x = function
Empty -> None
| Node (l, v, r, _h) ->
let c = Ord.compare x v in
if c = 0 then Some v
else find_opt_internal x (if c < 0 then l else r)
let find_opt f (s : t) =
let s : internal = Obj.magic s in
find_opt_internal f s
(*
let find_opt x s =
Stdcompat__tools.option_find (find x) s
exception Find of elt
let find_first_opt p s =
try
iter (fun x ->
if p x then
raise (Find x)) s;
None
with Find x -> Some x
let find_first p s =
try
iter (fun x ->
if p x then
raise (Find x)) s;
raise Not_found
with Find x -> x
exception Local_not_found
let find_last_opt p s =
let last = ref None in
try
iter (fun x ->
if p x then
last := Some x
else
match !last with
| None -> raise Local_not_found
| Some x -> raise (Find x)) s;
!last
with
| Local_not_found -> None
| Find x -> !last
let find_last p s =
match find_last_opt p s with
| None -> raise Not_found
| Some x -> x
*)
*)(*
let rec map f = function
| Empty -> Empty
| Node (l, v, r, _) as t ->
(* enforce left-to-right evaluation order *)
let l' = map f l in
let v' = f v in
let r' = map f r in
if l == l' && v == v' && r == r' then t
else try_join l' v' r'
let map f s =
(Obj.magic (map f (Obj.magic s : internal)) : t)
(*
let map f s =
match
fold (fun item accu ->
let item' = f item in
match accu with
| Changed set -> Changed (add item' set)
| Unchanged list ->
if item == item' then Unchanged (item :: list)
else Changed (add item' (of_list list)))
s (Unchanged [])
with
| Changed s -> s
| Unchanged _ -> s
*)
*)(*
let split x s =
let add item (passed, (l, present, r)) =
if passed then
(passed, (l, present, add item r))
else
let o = Ord.compare item x in
if o < 0 then (passed, (add item l, present, add item r))
else if o > 0 then (true, (l, false, add item r))
else (true, (l, true, r)) in
snd (fold add s (false, (empty, false, empty)))
*)end