[sledge] Define Map as a functor over the Tree underlying Core.Map

Summary:
This diff defines Map as a functorover the underlying implementation
of Core.Map. This results in map values that are just trees, with no
comparison function closures, and with the same interface (almost) and
underlying data structure implementation as Core.Map.

Reviewed By: ngorogiannis

Differential Revision: D20583758

fbshipit-source-id: 5a4997b51
master
Josh Berdine 5 years ago committed by Facebook GitHub Bot
parent ae3c059fe9
commit d5fe9aa11d

@ -58,7 +58,7 @@ module Subst : sig
end = struct end = struct
type t = Term.t Term.Map.t [@@deriving compare, equal, sexp_of] type t = Term.t Term.Map.t [@@deriving compare, equal, sexp_of]
let t_of_sexp = Term.Map.t_of_sexp Term.t_of_sexp Term.t_of_sexp let t_of_sexp = Term.Map.t_of_sexp Term.t_of_sexp
let pp = Term.Map.pp Term.pp Term.pp let pp = Term.Map.pp Term.pp Term.pp
let pp_diff = let pp_diff =
@ -72,7 +72,7 @@ end = struct
let fold = Term.Map.fold let fold = Term.Map.fold
let iteri = Term.Map.iteri let iteri = Term.Map.iteri
let for_alli = Term.Map.for_alli let for_alli = Term.Map.for_alli
let to_alist = Term.Map.to_alist let to_alist = Term.Map.to_alist ~key_order:`Increasing
(** look up a term in a substitution *) (** look up a term in a substitution *)
let apply s a = Term.Map.find s a |> Option.value ~default:a let apply s a = Term.Map.find s a |> Option.value ~default:a

@ -5,39 +5,45 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*) *)
open Import0
include Map_intf include Map_intf
module Make (Key : OrderedType) : S with type key = Key.t = struct module Make (Key : sig
module M = Stdlib.Map.Make (Key) type t [@@deriving compare, sexp_of]
end) : S with type key = Key.t = struct
module KeyMap = Core.Map.Make_plain (Key)
module Key = KeyMap.Key
type key = Key.t type key = Key.t
type 'a t = 'a M.t
let compare = M.compare include KeyMap.Tree
let equal = M.equal
let sexp_of_t sexp_of_val m = let compare = compare_direct
List.sexp_of_t
(Sexplib.Conv.sexp_of_pair Key.sexp_of_t sexp_of_val)
(M.bindings m)
let t_of_sexp key_of_sexp val_of_sexp sexp = let to_map t =
List.fold_left Base.Map.Using_comparator.of_tree ~comparator:Key.comparator t
~f:(fun m (k, v) -> M.add k v m)
~init:M.empty let of_map m = Base.Map.Using_comparator.to_tree m
(List.t_of_sexp
(Sexplib.Conv.pair_of_sexp key_of_sexp val_of_sexp) let merge_skewed x y ~combine =
sexp) of_map (Core.Map.merge_skewed (to_map x) (to_map y) ~combine)
let find_and_remove m k =
let found = ref None in
let m =
change m k ~f:(fun v ->
found := v ;
None )
in
Option.map ~f:(fun v -> (v, m)) !found
let pp pp_k pp_v fs m = let pp pp_k pp_v fs m =
Format.fprintf fs "@[<1>[%a]@]" Format.fprintf fs "@[<1>[%a]@]"
(List.pp ",@ " (fun fs (k, v) -> (List.pp ",@ " (fun fs (k, v) ->
Format.fprintf fs "@[%a @<2>↦ %a@]" pp_k k pp_v v )) Format.fprintf fs "@[%a @<2>↦ %a@]" pp_k k pp_v v ))
(M.bindings m) (to_alist m)
let pp_diff ~data_equal pp_key pp_val pp_diff_val fs (x, y) = let pp_diff ~data_equal pp_key pp_val pp_diff_val fs (x, y) =
let pp_diff_val fs = function let pp_diff_elt fs = function
| k, `Left v -> | k, `Left v ->
Format.fprintf fs "-- [@[%a@ @<2>↦ %a@]]" pp_key k pp_val v Format.fprintf fs "-- [@[%a@ @<2>↦ %a@]]" pp_key k pp_val v
| k, `Right v -> | k, `Right v ->
@ -45,88 +51,7 @@ module Make (Key : OrderedType) : S with type key = Key.t = struct
| k, `Unequal vv -> | k, `Unequal vv ->
Format.fprintf fs "[@[%a@ @<2>↦ %a@]]" pp_key k pp_diff_val vv Format.fprintf fs "[@[%a@ @<2>↦ %a@]]" pp_key k pp_diff_val vv
in in
let sd = let sd = Core.Sequence.to_list (symmetric_diff ~data_equal x y) in
M.merge if not (List.is_empty sd) then
(fun _ v1o v2o -> Format.fprintf fs "[@[<hv>%a@]];@ " (List.pp ";@ " pp_diff_elt) sd
match (v1o, v2o) with
| Some v1, Some v2 when not (data_equal v1 v2) ->
Some (`Unequal (v1, v2))
| Some v1, None -> Some (`Left v1)
| None, Some v2 -> Some (`Right v2)
| _ -> None )
x y
in
if not (M.is_empty sd) then
Format.fprintf fs "[@[<hv>%a@]];@ "
(List.pp ";@ " pp_diff_val)
(M.bindings sd)
let empty = M.empty
let set m ~key ~data = M.add key data m
let add_exn m ~key ~data =
M.update key
(function None -> Some data | Some _ -> raise Duplicate)
m
let add_multi m ~key ~data =
M.update key
(function None -> Some [data] | Some vs -> Some (data :: vs))
m
let remove m k = M.remove k m
let update m k ~f = M.update k (fun vo -> Some (f vo)) m
let merge m n ~f =
M.merge
(fun k v1o v2o ->
match (v1o, v2o) with
| Some v1, Some v2 -> f ~key:k (`Both (v1, v2))
| Some v1, None -> f ~key:k (`Left v1)
| None, Some v2 -> f ~key:k (`Right v2)
| None, None -> None )
m n
let merge_skewed m n ~combine =
M.merge
(fun k v1o v2o ->
match (v1o, v2o) with
| Some v1, Some v2 -> Some (combine ~key:k v1 v2)
| Some _, None -> v1o
| None, Some _ -> v2o
| None, None -> None )
m n
let map m ~f = M.map f m
let filter_keys m ~f = M.filter (fun k _ -> f k) m
let filter_mapi m ~f =
M.fold
(fun k v m ->
match f ~key:k ~data:v with Some v' -> M.add k v' m | None -> m )
m M.empty
let is_empty = M.is_empty
let length = M.cardinal
let mem m k = M.mem k m
let find m k = M.find_opt k m
let find_and_remove m k =
let found = ref None in
let m =
M.update k
(fun v ->
found := v ;
None )
m
in
Option.map ~f:(fun v -> (v, m)) !found
let find_multi m k = try M.find k m with Not_found -> []
let data m = M.fold (fun _ v s -> v :: s) m []
let to_alist = M.bindings
let iter m ~f = M.iter (fun _ v -> f v) m
let iteri m ~f = M.iter (fun k v -> f ~key:k ~data:v) m
let for_alli m ~f = M.for_all (fun key data -> f ~key ~data) m
let fold m ~init ~f = M.fold (fun key data s -> f ~key ~data s) m init
end end

@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*) *)
open Import0
include module type of Map_intf include module type of Map_intf
module Make (Key : OrderedType) : S with type key = Key.t
module Make (Key : sig
type t [@@deriving compare, sexp_of]
end) : S with type key = Key.t

@ -9,60 +9,27 @@ open Import0
module type S = sig module type S = sig
type key type key
type +'a t
val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int module Key : sig
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool type t = key
val sexp_of_t : ('a -> Sexp.t) -> 'a t -> Sexp.t
val t_of_sexp : (Sexp.t -> key) -> (Sexp.t -> 'a) -> Sexp.t -> 'a t
val pp : key pp -> 'a pp -> 'a t pp
val pp_diff :
data_equal:('a -> 'a -> bool)
-> key pp
-> 'a pp
-> ('a * 'a) pp
-> ('a t * 'a t) pp
(* initial constructors *) include Core.Comparator.S with type t := t
val empty : 'a t end
(* constructors *) include Core_kernel.Map_intf.Make_S_plain_tree(Key).S
val set : 'a t -> key:key -> data:'a -> 'a t
val add_exn : 'a t -> key:key -> data:'a -> 'a t
val add_multi : 'a list t -> key:key -> data:'a -> 'a list t
val remove : 'a t -> key -> 'a t
val update : 'a t -> key -> f:('a option -> 'a) -> 'a t
val merge : val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
'a t
-> 'b t
-> f:
( key:key
-> [`Both of 'a * 'b | `Left of 'a | `Right of 'b]
-> 'c option)
-> 'c t
val merge_skewed : val merge_skewed :
'a t -> 'a t -> combine:(key:key -> 'a -> 'a -> 'a) -> 'a t 'a t -> 'a t -> combine:(key:key -> 'a -> 'a -> 'a) -> 'a t
val map : 'a t -> f:('a -> 'b) -> 'b t
val filter_keys : 'a t -> f:(key -> bool) -> 'a t
val filter_mapi : 'a t -> f:(key:key -> data:'a -> 'b option) -> 'b t
(* queries *)
val is_empty : 'b t -> bool
val length : 'b t -> int
val mem : 'a t -> key -> bool
val find : 'a t -> key -> 'a option
val find_and_remove : 'a t -> key -> ('a * 'a t) option val find_and_remove : 'a t -> key -> ('a * 'a t) option
val find_multi : 'a list t -> key -> 'a list val pp : key pp -> 'a pp -> 'a t pp
val data : 'a t -> 'a list
val to_alist : 'a t -> (key * 'a) list
(* traversals *) val pp_diff :
val iter : 'a t -> f:('a -> unit) -> unit data_equal:('a -> 'a -> bool)
val iteri : 'a t -> f:(key:key -> data:'a -> unit) -> unit -> key pp
val for_alli : 'a t -> f:(key:key -> data:'a -> bool) -> bool -> 'a pp
val fold : 'a t -> init:'s -> f:(key:key -> data:'a -> 's -> 's) -> 's -> ('a * 'a) pp
-> ('a t * 'a t) pp
end end

@ -100,7 +100,7 @@ end = struct
end end
include T include T
module Map = Map.Make (T) module Map = struct include Map.Make (T) include Provide_of_sexp (T) end
module Set = struct include Set.Make (T) include Provide_of_sexp (T) end module Set = struct include Set.Make (T) include Provide_of_sexp (T) end
let fix (f : (t -> 'a as 'f) -> 'f) (bot : 'f) (e : t) : 'a = let fix (f : (t -> 'a as 'f) -> 'f) (bot : 'f) (e : t) : 'a =
@ -334,7 +334,7 @@ module Var = struct
module Subst = struct module Subst = struct
type t = T.t Map.t [@@deriving compare, equal, sexp_of] type t = T.t Map.t [@@deriving compare, equal, sexp_of]
let t_of_sexp = Map.t_of_sexp T.t_of_sexp T.t_of_sexp let t_of_sexp = Map.t_of_sexp T.t_of_sexp
let invariant s = let invariant s =
Invariant.invariant [%here] s [%sexp_of: t] Invariant.invariant [%here] s [%sexp_of: t]

@ -141,7 +141,11 @@ module Var : sig
end end
end end
module Map : Map.S with type key := t module Map : sig
include Map.S with type key := t
val t_of_sexp : (Sexp.t -> 'a) -> Sexp.t -> 'a t
end
val ppx : Var.strength -> t pp val ppx : Var.strength -> t pp
val pp : t pp val pp : t pp

Loading…
Cancel
Save