aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/cMap.ml14
-rw-r--r--lib/cMap.mli4
-rw-r--r--pretyping/reductionops.ml52
-rw-r--r--pretyping/reductionops.mli4
4 files changed, 42 insertions, 32 deletions
diff --git a/lib/cMap.ml b/lib/cMap.ml
index bf0a33768..4c94f122a 100644
--- a/lib/cMap.ml
+++ b/lib/cMap.ml
@@ -19,11 +19,13 @@ sig
include Map.S
module Set : Set.S with type elt = key
val domain : 'a t -> Set.t
+ val bind : (key -> 'a) -> Set.t -> 'a t
end
-module Domain (M : Map.OrderedType) :
+module MapExt (M : Map.OrderedType) :
sig
val domain : 'a Map.Make(M).t -> Set.Make(M).t
+ val bind : (M.t -> 'a) -> Set.Make(M).t -> 'a Map.Make(M).t
end =
struct
(** This unsafe module is a way to access to the actual implementations of
@@ -50,11 +52,17 @@ struct
(** This function is essentially identity, but OCaml current stdlib does not
take advantage of the similarity of the two structures, so we introduce
this unsafe loophole. *)
-
+
+ let rec bind f (s : set) : 'a map = match Obj.magic s with
+ | SEmpty -> Obj.magic MEmpty
+ | SNode (l, k, r, h) ->
+ Obj.magic (MNode (bind f l, k, f k, bind f r, h))
+ (** Dual operation of [domain]. *)
+
end
module Make(M : Map.OrderedType) =
struct
include Map.Make(M)
- include Domain(M)
+ include MapExt(M)
end
diff --git a/lib/cMap.mli b/lib/cMap.mli
index 9b7043d9e..222138828 100644
--- a/lib/cMap.mli
+++ b/lib/cMap.mli
@@ -27,6 +27,10 @@ sig
val domain : 'a t -> Set.t
(** Recover the set of keys defined in the map. *)
+ val bind : (key -> 'a) -> Set.t -> 'a t
+ (** [bind f s] transform the set [x1; ...; xn] into [x1 := f x1; ...;
+ xn := f xn]. *)
+
end
module Make(M : Map.OrderedType) : ExtS with
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index e86732658..ad5f5a7ae 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -782,7 +782,7 @@ let whd_meta sigma c = match kind_of_term c with
* Differs from (strong whd_meta). *)
let plain_instance s c =
let rec irec n u = match kind_of_term u with
- | Meta p -> (try lift n (List.assoc p s) with Not_found -> u)
+ | Meta p -> (try lift n (Metamap.find p s) with Not_found -> u)
| App (f,l) when isCast f ->
let (f,_,t) = destCast f in
let l' = Array.map (irec n) l in
@@ -791,7 +791,7 @@ let plain_instance s c =
(* Don't flatten application nodes: this is used to extract a
proof-term from a proof-tree and we want to keep the structure
of the proof-tree *)
- (try let g = List.assoc p s in
+ (try let g = Metamap.find p s in
match kind_of_term g with
| App _ ->
let h = Id.of_string "H" in
@@ -800,13 +800,12 @@ let plain_instance s c =
with Not_found -> mkApp (f,l'))
| _ -> mkApp (irec n f,l'))
| Cast (m,_,_) when isMeta m ->
- (try lift n (List.assoc (destMeta m) s) with Not_found -> u)
+ (try lift n (Metamap.find (destMeta m) s) with Not_found -> u)
| _ ->
map_constr_with_binders succ irec n u
in
- match s with
- | [] -> c
- | _ -> irec 0 c
+ if Metamap.is_empty s then c
+ else irec 0 c
(* [instance] is used for [res_pf]; the call to [local_strong whd_betaiota]
has (unfortunately) different subtle side effects:
@@ -1041,32 +1040,32 @@ let meta_value evd mv =
let rec valrec mv =
match meta_opt_fvalue evd mv with
| Some (b,_) ->
- instance evd
- (List.map (fun mv' -> (mv',valrec mv')) (Metaset.elements b.freemetas))
- b.rebus
+ let metas = Metamap.bind valrec b.freemetas in
+ instance evd metas b.rebus
| None -> mkMeta mv
in
valrec mv
let meta_instance sigma b =
- let c_sigma =
- List.map
- (fun mv -> (mv,meta_value sigma mv)) (Metaset.elements b.freemetas)
- in
- match c_sigma with
- | [] -> b.rebus
- | _ -> instance sigma c_sigma b.rebus
+ let fm = b.freemetas in
+ if Metaset.is_empty fm then b.rebus
+ else
+ let c_sigma = Metamap.bind (fun mv -> meta_value sigma mv) fm in
+ instance sigma c_sigma b.rebus
let nf_meta sigma c = meta_instance sigma (mk_freelisted c)
(* Instantiate metas that create beta/iota redexes *)
let meta_reducible_instance evd b =
- let fm = Metaset.elements b.freemetas in
- let metas = List.fold_left (fun l mv ->
- match (try meta_opt_fvalue evd mv with Not_found -> None) with
- | Some (g,(_,s)) -> (mv,(g.rebus,s))::l
- | None -> l) [] fm in
+ let fm = b.freemetas in
+ let fold mv accu =
+ let fvalue = try meta_opt_fvalue evd mv with Not_found -> None in
+ match fvalue with
+ | None -> accu
+ | Some (g, (_, s)) -> Metamap.add mv (g.rebus, s) accu
+ in
+ let metas = Metaset.fold fold fm Metamap.empty in
let rec irec u =
let u = whd_betaiota Evd.empty u in
match kind_of_term u with
@@ -1074,7 +1073,7 @@ let meta_reducible_instance evd b =
let m = destMeta (strip_outer_cast c) in
(match
try
- let g, s = List.assoc m metas in
+ let g, s = Metamap.find m metas in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isConstruct g || not is_coerce then Some g else None
with Not_found -> None
@@ -1085,7 +1084,7 @@ let meta_reducible_instance evd b =
let m = destMeta (strip_outer_cast f) in
(match
try
- let g, s = List.assoc m metas in
+ let g, s = Metamap.find m metas in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isLambda g || not is_coerce then Some g else None
with Not_found -> None
@@ -1093,15 +1092,14 @@ let meta_reducible_instance evd b =
| Some g -> irec (mkApp (g,l))
| None -> mkApp (f,Array.map irec l))
| Meta m ->
- (try let g, s = List.assoc m metas in
+ (try let g, s = Metamap.find m metas in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if not is_coerce then irec g else u
with Not_found -> u)
| _ -> map_constr irec u
in
- match fm with
- | [] -> (* nf_betaiota? *) b.rebus
- | _ -> irec b.rebus
+ if Metaset.is_empty fm then (* nf_betaiota? *) b.rebus
+ else irec b.rebus
let head_unfold_under_prod ts env _ c =
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index 588914c58..b98a7d309 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -225,8 +225,8 @@ val is_trans_fconv : conv_pb -> transparent_state -> env -> evar_map -> constr
(** {6 Special-Purpose Reduction Functions } *)
val whd_meta : evar_map -> constr -> constr
-val plain_instance : (metavariable * constr) list -> constr -> constr
-val instance :evar_map -> (metavariable * constr) list -> constr -> constr
+val plain_instance : constr Metamap.t -> constr -> constr
+val instance : evar_map -> constr Metamap.t -> constr -> constr
val head_unfold_under_prod : transparent_state -> reduction_function
(** {6 Heuristic for Conversion with Evar } *)