2020-04-09 16:02:06 +04:00
|
|
|
(* Polymorphic sets *)
|
|
|
|
|
|
|
|
module RB = RedBlack
|
|
|
|
|
|
|
|
type 'elt t = {
|
|
|
|
tree : 'elt RB.t;
|
|
|
|
cmp : 'elt -> 'elt -> int
|
|
|
|
}
|
|
|
|
|
|
|
|
type 'elt set = 'elt t
|
|
|
|
|
|
|
|
let create ~cmp = {tree = RB.empty; cmp}
|
|
|
|
|
2020-04-13 21:19:49 +04:00
|
|
|
let empty set = {tree = RB.empty; cmp=set.cmp}
|
2020-04-09 16:02:06 +04:00
|
|
|
|
|
|
|
let is_empty set = RB.is_empty set.tree
|
|
|
|
|
|
|
|
let add elt set = {set with tree = RB.add ~cmp:set.cmp RB.New elt set.tree}
|
|
|
|
|
|
|
|
let find elt set =
|
|
|
|
try RB.find ~cmp:set.cmp elt set.tree with
|
2020-04-22 22:47:43 +04:00
|
|
|
Not_found -> raise Not_found
|
2020-04-09 16:02:06 +04:00
|
|
|
|
|
|
|
let find_opt elt set = RB.find_opt ~cmp:set.cmp elt set.tree
|
|
|
|
|
2020-05-08 18:24:42 +04:00
|
|
|
let mem elt set = match RB.find_opt ~cmp:set.cmp elt set.tree with None -> false | Some _ -> true
|
|
|
|
|
|
|
|
type 'a added = {set : 'a set; duplicates : 'a list; added : 'a list}
|
|
|
|
|
|
|
|
let add_list elts set =
|
|
|
|
let aux = fun {set ; duplicates ; added} elt ->
|
|
|
|
if mem elt set
|
|
|
|
then {set; duplicates = elt :: duplicates ; added}
|
|
|
|
else {set = add elt set; duplicates; added = elt :: added} in
|
|
|
|
List.fold_left aux {set; duplicates=[]; added = []} elts
|
|
|
|
|
2020-04-09 16:02:06 +04:00
|
|
|
let elements set = RB.elements set.tree
|
|
|
|
|
2020-06-19 06:45:25 +04:00
|
|
|
let get_compare set = set.cmp
|
|
|
|
|
2020-04-09 16:02:06 +04:00
|
|
|
let iter f set = RB.iter f set.tree
|
|
|
|
|
|
|
|
let fold_inc f set = RB.fold_inc (fun ~elt -> f elt) set.tree
|