CS153/hw6/bin/datastructures.ml
jmug 0c04936ccf Updated hw6 to a newer version
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
2025-01-24 21:23:08 -08:00

117 lines
2.8 KiB
OCaml

(** Data structures, signatures *)
(** Comparable, printable type *)
module type OrdPrintT =
sig
type t
val compare : t -> t -> int
val to_string : t -> string
end
(** Extended sets *)
module type SetS =
sig
include Set.S
val of_list : elt list -> t (* added to Set.S in OCaml 4.02 *)
val to_string : t -> string
val string_of_elt : elt -> string
val printer : Format.formatter -> t -> unit
end
module MakeSet (Ord : OrdPrintT) : SetS with type elt = Ord.t =
struct
include Set.Make (Ord)
let of_list = List.fold_left (fun s e -> add e s) empty
let to_string t =
let s = elements t
|> List.map Ord.to_string
|> String.concat ", "
in
"{" ^ s ^ "}"
let string_of_elt = Ord.to_string
let printer f t = Format.pp_print_string f (to_string t)
end
(** Extended maps *)
module type MapS =
sig
include Map.S
val update : ('a -> 'a) -> key -> 'a t -> 'a t
val find_or : 'a -> 'a t -> key -> 'a
val update_or : 'a -> ('a -> 'a) -> key -> 'a t -> 'a t
val diff_keys : ('a -> 'a -> int) -> 'a t -> 'a t -> key list
val to_string : (key -> 'a -> string) -> 'a t -> string
val printer : (key -> 'a -> string) -> Format.formatter -> 'a t -> unit
end
module MakeMap (Ord : OrdPrintT) : MapS with type key = Ord.t =
struct
include Map.Make (Ord)
let update f k m =
add k (f @@ find k m) m
let find_or d m k =
try find k m with Not_found -> d
let diff_keys cmp_v m n =
let module S = MakeSet(Ord) in
let has_binding_or_add m k v l =
try if cmp_v v @@ find k m == 0 then l else S.add k l
with Not_found -> S.add k l
in
S.empty |> fold (has_binding_or_add n) m
|> fold (has_binding_or_add m) n
|> S.elements
let update_or d f k m =
add k (f @@ find_or d m k) m
let to_string val_str t =
let s = bindings t
|> List.map (fun (k,v) -> Ord.to_string k ^ "=" ^ val_str k v)
|> String.concat ", "
in
"{" ^ s ^ "}"
let printer val_str f t = Format.pp_print_string f (to_string val_str t)
end
(** Useful instances *)
module Lbl =
struct
type t = Ll.lbl
let compare = String.compare
let to_string l = l
end
module LblM = MakeMap (Lbl)
module LblS = MakeSet (Lbl)
module Uid =
struct
type t = Ll.uid
let compare = String.compare
let to_string u = "%" ^ u
end
module UidS = MakeSet (Uid)
module UidM = MakeMap (Uid)
(** For testing *)
let uidm (b:(Ll.uid * 'a) list) : 'a UidM.t =
List.fold_left (fun m (k,v) -> UidM.add k v m) UidM.empty b
let lblm (b:(Ll.lbl * 'a) list) : 'a LblM.t =
List.fold_left (fun m (k,v) -> LblM.add k v m) LblM.empty b
let uids (l:Ll.uid list) : UidS.t = UidS.of_list l
let lbls (l:Ll.lbl list) : LblS.t = LblS.of_list l