(************************************************************************) (* * The Rocq Prover / The Rocq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************)
module type OrderedType = sig type t val compare : t -> t -> int end
module type MonadS = sig type +'a t val return : 'a -> 'a t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t end
module type S = Map.S
module type UExtS = sig
include CSig.UMapS
module Set : CSig.USetS withtype elt = key val get : key -> 'a t -> 'a valset : key -> 'a -> 'a t -> 'a t val modify : key -> (key -> 'a -> 'a) -> 'a t -> 'a t val domain : 'a t -> Set.t val bind : (key -> 'a) -> Set.t -> 'a t val height : 'a t -> int val filter_range : (key -> int) -> 'a t -> 'a t val of_list : (key * 'a) list -> 'a t val symmetric_diff_fold :
(key -> 'a option -> 'a option -> 'b -> 'b) -> 'a t -> 'a t -> 'b -> 'b
module Smart : sig valmap : ('a -> 'a) -> 'a t -> 'a t val mapi : (key -> 'a -> 'a) -> 'a t -> 'a t end
module Monad(M : MonadS) : sig val fold : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t val mapi : (key -> 'a -> 'b M.t) -> 'a t -> 'b t M.t end end
module type ExtS = sig
include CSig.MapS
module Set : CSig.SetS withtype elt = key
include UExtS withtype key := key andtype'a t := 'a t and module Set := Set
module Monad(M:MonadS) : sig
include module typeof Monad(M) val fold_left : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t val fold_right : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t end
val fold_left : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b val fold_right : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b val fold_left_map : (key -> 'a -> 'b -> 'b * 'c) -> 'a t -> 'b -> 'b * 'c t val fold_right_map : (key -> 'a -> 'b -> 'b * 'c) -> 'a t -> 'b -> 'b * 'c t end
module MapExt (M : Map.OrderedType) : sig type'a map = 'a Map.Make(M).t valset : M.t -> 'a -> 'a map -> 'a map val get : M.t -> 'a map -> 'a val modify : M.t -> (M.t -> 'a -> 'a) -> 'a map -> 'a map val domain : 'a map -> Set.Make(M).t val bind : (M.t -> 'a) -> Set.Make(M).t -> 'a map val fold_left : (M.t -> 'a -> 'b -> 'b) -> 'a map -> 'b -> 'b val fold_right : (M.t -> 'a -> 'b -> 'b) -> 'a map -> 'b -> 'b val fold_left_map : (M.t -> 'a -> 'b -> 'b * 'c) -> 'a map -> 'b -> 'b * 'c map val fold_right_map : (M.t -> 'a -> 'b -> 'b * 'c) -> 'a map -> 'b -> 'b * 'c map val height : 'a map -> int val filter_range : (M.t -> int) -> 'a map -> 'a map val symmetric_diff_fold :
(M.t -> 'a option -> 'a option -> 'b -> 'b) -> 'a map -> 'a map -> 'b -> 'b val of_list : (M.t * 'a) list -> 'a map
module Smart : sig valmap : ('a -> 'a) -> 'a map -> 'a map val mapi : (M.t -> 'a -> 'a) -> 'a map -> 'a map end
module Monad(MS : MonadS) : sig val fold : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t val fold_left : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t val fold_right : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t val mapi : (M.t -> 'a -> 'b MS.t) -> 'a map -> 'b map MS.t end end = struct (** This unsafe module is a way to access to the actual implementations of OCamlsetsandmapswithoutreimplementingthemourselves.Itisquite dubiousthattheseimplementationswilleverbechanged...Nonetheless, ifthishappens,wecanstillimplementalesscleverversionof[domain].
*)
type _set =
| SEmpty
| SNode ofset * M.t * set * int
let map_prj : 'a map -> 'a _map = Obj.magic let map_inj : 'a _map -> 'a map = Obj.magic let set_prj : set -> _set = Obj.magic let set_inj : _set -> set = Obj.magic
let rec set k v (s : 'a map) : 'a map = match map_prj s with
| MEmpty -> raise Not_found
| MNode {l; v=k'; d=v'; r; h} -> let c = M.compare k k' in if c < 0then let l' = set k v l in if l == l' then s else map_inj (MNode {l=l'; v=k'; d=v'; r; h}) elseif c = 0then if v' == v then s else map_inj (MNode {l; v=k'; d=v; r; h}) else let r' = set k v r in if r == r' then s else map_inj (MNode {l; v=k'; d=v'; r=r'; h})
let rec get k (s:'a map) : 'a = match map_prj s with
| MEmpty -> assert false
| MNode {l; v=k'; d=v; r; h} -> let c = M.compare k k' in if c < 0then get k l elseif c = 0then v else get k r
let rec modify k f (s : 'a map) : 'a map = match map_prj s with
| MEmpty -> raise Not_found
| MNode {l; v; d; r; h} -> let c = M.compare k v in if c < 0then let l' = modify k f l in if l == l' then s else map_inj (MNode {l=l'; v; d; r; h}) elseif c = 0then let d' = f v d in if d' == d then s else map_inj (MNode {l; v; d=d'; r; h}) else let r' = modify k f r in if r == r' then s else map_inj (MNode {l; v; d; r=r'; h})
let rec domain (s : 'a map) : set = match map_prj s with
| MEmpty -> set_inj SEmpty
| MNode {l; v; r; h; _} ->
set_inj (SNode (domain l, v, domain r, h)) (** This function is essentially identity, but OCaml current stdlib does not takeadvantageofthesimilarityofthetwostructures,soweintroduce
this unsafe loophole. *)
let rec bind f (s : set) : 'a map = match set_prj s with
| SEmpty -> map_inj MEmpty
| SNode (l, k, r, h) ->
map_inj (MNode { l=bind f l; v=k; d=f k; r=bind f r; h}) (** Dual operation of [domain]. *)
let rec fold_left f (s : 'a map) accu = match map_prj s with
| MEmpty -> accu
| MNode {l; v=k; d=v; r; h} -> let accu = f k v (fold_left f l accu) in
fold_left f r accu
let rec fold_right f (s : 'a map) accu = match map_prj s with
| MEmpty -> accu
| MNode {l; v=k; d=v; r; h} -> let accu = f k v (fold_right f r accu) in
fold_right f l accu
let rec fold_left_map f (s : 'a map) accu = match map_prj s with
| MEmpty -> accu, map_inj MEmpty
| MNode {l; v=k; d=v; r; h} -> let accu, l = fold_left_map f l accu in let accu, v = f k v accu in let accu, r = fold_left_map f r accu in
accu, map_inj (MNode {l; v=k; d=v; r; h})
let rec fold_right_map f (s : 'a map) accu = match map_prj s with
| MEmpty -> accu, map_inj MEmpty
| MNode {l; v=k; d=v; r; h} -> let accu, r = fold_right_map f r accu in let accu, v = f k v accu in let accu, l = fold_right_map f l accu in
accu, map_inj (MNode {l; v=k; d=v; r; h})
let height s = match map_prj s with
| MEmpty -> 0
| MNode {h;_} -> h
(* Filter based on a range *) let filter_range in_range m = let rec aux m = function
| MEmpty -> m
| MNode {l; v; d; r; _} -> let vr = in_range v in (* the range is below the current value *) if vr < 0then aux m (map_prj l) (* the range is above the current value *) elseif vr > 0then aux m (map_prj r) (* The current value is in the range *) else let m = aux m (map_prj l) in let m = aux m (map_prj r) in
F.add v d m in aux F.empty (map_prj m)
let of_list l = let fold accu (x, v) = F.add x v accu in List.fold_left fold F.empty l
type'a sequenced =
| End
| More of M.t * 'a * 'a F.t * 'a sequenced
let rec seq_cons m rest = match map_prj m with
| MEmpty -> rest
| MNode {l; v; d; r; _ } -> seq_cons l (More (v, d, r, rest))
let rec fold_seq f acc = function
| End -> acc
| More (k, v, m, r) -> f k v @@ fold_seq f (F.fold f m acc) r
let move_to_acc (m, acc) = match map_prj m with
| MEmpty -> assert false
| MNode {l; v; d; r; _ } -> l, More (v, d, r, acc)
let rec symmetric_cons ((lm, la) as l) ((rm, ra) as r) = if lm == rm then la, ra else let lh = height lm in let rh = height rm in if lh == rh then
symmetric_cons (move_to_acc l) (move_to_acc r) elseif lh < rh then
symmetric_cons l (move_to_acc r) else
symmetric_cons (move_to_acc l) r
let symmetric_diff_fold f lm rm acc = let rec aux s acc = match s with
| End, rs -> fold_seq (fun k v -> f k None (Some v)) acc rs
| ls, End -> fold_seq (fun k v -> f k (Some v) None) acc ls
| (More (kl, vl, tl, rl) as ls), (More (kr, vr, tr, rr) as rs) -> let cmp = M.compare kl kr in if cmp == 0then let rem = aux (symmetric_cons (tl, rl) (tr, rr)) acc in if vl == vr then rem else f kl (Some vl) (Some vr) rem elseif cmp < 0then
f kl (Some vl) None @@ aux (seq_cons tl rl, rs) acc else
f kr None (Some vr) @@ aux (ls, seq_cons tr rr) acc in aux (symmetric_cons (lm, End) (rm, End)) acc
module Smart = struct
let rec map f (s : 'a map) = match map_prj s with
| MEmpty -> map_inj MEmpty
| MNode {l; v=k; d=v; r; h} -> let l' = map f l in let r' = map f r in let v' = f v in if l == l' && r == r' && v == v' then s else map_inj (MNode {l=l'; v=k; d=v'; r=r'; h})
let rec mapi f (s : 'a map) = match map_prj s with
| MEmpty -> map_inj MEmpty
| MNode {l; v=k; d=v; r; h} -> let l' = mapi f l in let r' = mapi f r in let v' = f k v in if l == l' && r == r' && v == v' then s else map_inj (MNode {l=l'; v=k; d=v'; r=r'; h})
end
module Monad(M : MonadS) = struct
open M
let rec fold_left f s accu = match map_prj s with
| MEmpty -> return accu
| MNode {l; v=k; d=v; r; h} ->
fold_left f l accu >>= fun accu ->
f k v accu >>= fun accu ->
fold_left f r accu
let rec fold_right f s accu = match map_prj s with
| MEmpty -> return accu
| MNode {l; v=k; d=v; r; h} ->
fold_right f r accu >>= fun accu ->
f k v accu >>= fun accu ->
fold_right f l accu
let fold = fold_left
let rec mapi f s = match map_prj s with
| MEmpty -> return (map_inj MEmpty)
| MNode {l; v=k; d=v; r; h} ->
mapi f l >>= fun l ->
mapi f r >>= fun r ->
f k v >>= fun v ->
return (map_inj (MNode {l; v=k; d=v; r; h}))
end
end
module Make(M : Map.OrderedType) = struct
include Map.Make(M)
include MapExt(M) end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.