aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pretyping/evarutil.ml10
-rw-r--r--pretyping/evd.ml27
-rw-r--r--pretyping/evd.mli10
-rw-r--r--pretyping/typeclasses.ml18
-rw-r--r--tactics/class_tactics.ml429
5 files changed, 63 insertions, 31 deletions
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index 84f7254b1..1972aee28 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -79,15 +79,11 @@ let nf_evar_info evc info =
evar_body = match info.evar_body with
| Evar_empty -> Evar_empty
| Evar_defined c -> Evar_defined (Reductionops.nf_evar evc c) }
-let nf_evars evm =
- Evd.fold
- (fun ev evi evm' -> Evd.add evm' ev (nf_evar_info evm evi))
- evm Evd.empty
+
+let nf_evars evm = Evd.raw_map (fun _ evi -> nf_evar_info evm evi) evm
let nf_evars_undefined evm =
- Evd.fold_undefined
- (fun ev evi evm' -> Evd.add evm' ev (nf_evar_info evm evi))
- evm (defined_evars evm)
+ Evd.raw_map_undefined (fun _ evi -> nf_evar_info evm evi) evm
let nf_evar_map evd = Evd.evars_reset_evd (nf_evars evd) evd
let nf_evar_map_undefined evd = Evd.evars_reset_evd (nf_evars_undefined evd) evd
diff --git a/pretyping/evd.ml b/pretyping/evd.ml
index c92f6a5b3..cebce3abe 100644
--- a/pretyping/evd.ml
+++ b/pretyping/evd.ml
@@ -260,6 +260,33 @@ let fold f d a =
let fold_undefined f d a = ExMap.fold f d.undf_evars a
+let raw_map f d =
+ let f evk info =
+ let ans = f evk info in
+ let () = match info.evar_body, ans.evar_body with
+ | Evar_defined _, Evar_empty
+ | Evar_empty, Evar_defined _ ->
+ anomaly (str "Unrespectful mapping function.")
+ | _ -> ()
+ in
+ ans
+ in
+ let defn_evars = ExMap.mapi f d.defn_evars in
+ let undf_evars = ExMap.mapi f d.undf_evars in
+ { d with defn_evars; undf_evars; }
+
+let raw_map_undefined f d =
+ let f evk info =
+ let ans = f evk info in
+ let () = match ans.evar_body with
+ | Evar_defined _ ->
+ anomaly (str "Unrespectful mapping function.")
+ | _ -> ()
+ in
+ ans
+ in
+ { d with undf_evars = ExMap.mapi f d.undf_evars; }
+
let is_evar = mem
let is_defined d e = ExMap.mem e d.defn_evars
diff --git a/pretyping/evd.mli b/pretyping/evd.mli
index 354a5b533..0beb46571 100644
--- a/pretyping/evd.mli
+++ b/pretyping/evd.mli
@@ -127,6 +127,16 @@ val fold_undefined : (evar -> evar_info -> 'a -> 'a) -> evar_map -> 'a -> 'a
(** Same as {!fold}, but restricted to undefined evars. For efficiency
reasons. *)
+val raw_map : (evar -> evar_info -> evar_info) -> evar_map -> evar_map
+(** Apply the given function to all evars in the map. Beware: this function
+ expects the argument function to preserve the kind of [evar_body], i.e. it
+ must send [Evar_empty] to [Evar_empty] and [Evar_defined c] to some
+ [Evar_defined c']. *)
+
+val raw_map_undefined : (evar -> evar_info -> evar_info) -> evar_map -> evar_map
+(** Same as {!raw_map}, but restricted to undefined evars. For efficiency
+ reasons. *)
+
val define : evar -> constr -> evar_map -> evar_map
(** Set the body of an evar to the given constr. It is expected that:
{ul
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index e91749431..a1cb232ca 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -493,20 +493,20 @@ let no_goals_or_obligations _ = function
| _ -> true
let mark_resolvability filter b sigma =
- Evd.fold_undefined
- (fun ev evi evs ->
- if filter ev (snd evi.evar_source) then
- Evd.add evs ev (mark_resolvability_undef b evi)
- else Evd.add evs ev evi)
- sigma (Evd.defined_evars sigma)
+ let map ev evi =
+ if filter ev (snd evi.evar_source) then mark_resolvability_undef b evi
+ else evi
+ in
+ Evd.raw_map_undefined map sigma
let mark_unresolvables ?(filter=all_evars) sigma = mark_resolvability filter false sigma
let mark_resolvables sigma = mark_resolvability all_evars true sigma
let has_typeclasses filter evd =
- Evd.fold_undefined (fun ev evi has -> has ||
- (filter ev (snd evi.evar_source) && is_class_evar evd evi && is_resolvable evi))
- evd false
+ let check ev evi =
+ filter ev (snd evi.evar_source) && is_class_evar evd evi && is_resolvable evi
+ in
+ Evd.ExistentialMap.exists check (Evd.undefined_map evd)
let solve_instanciations_problem = ref (fun _ _ _ _ _ -> assert false)
diff --git a/tactics/class_tactics.ml4 b/tactics/class_tactics.ml4
index 646c57d95..c62499fdf 100644
--- a/tactics/class_tactics.ml4
+++ b/tactics/class_tactics.ml4
@@ -197,7 +197,7 @@ let rec catchable = function
| e -> Logic.catchable_exception e
let nb_empty_evars s =
- Evd.fold_undefined (fun ev evi acc -> succ acc) s 0
+ ExistentialMap.cardinal (undefined_map s)
let pr_ev evs ev = Printer.pr_constr_env (Goal.V82.env evs ev) (Evarutil.nf_evar evs (Goal.V82.concl evs ev))
@@ -629,26 +629,25 @@ let select_and_update_evars p oevd in_comp evd ev evi =
(** Do we still have unresolved evars that should be resolved ? *)
let has_undefined p oevd evd =
- Evd.fold_undefined (fun ev evi has -> has ||
- snd (p oevd ev evi))
- evd false
+ let check ev evi = snd (p oevd ev evi) in
+ ExistentialMap.exists check (Evd.undefined_map evd)
(** Revert the resolvability status of evars after resolution,
potentially unprotecting some evars that were set unresolvable
just for this call to resolution. *)
let revert_resolvability oevd evd =
- Evd.fold_undefined
- (fun ev evi evm ->
- try
- if not (Typeclasses.is_resolvable evi) then
- let evi' = Evd.find_undefined oevd ev in
- if Typeclasses.is_resolvable evi' then
- Evd.add evm ev (Typeclasses.mark_resolvable evi)
- else evm
- else evm
- with Not_found -> evm)
- evd evd
+ let map ev evi =
+ try
+ if not (Typeclasses.is_resolvable evi) then
+ let evi' = Evd.find_undefined oevd ev in
+ if Typeclasses.is_resolvable evi' then
+ Typeclasses.mark_resolvable evi
+ else evi
+ else evi
+ with Not_found -> evi
+ in
+ Evd.raw_map_undefined map evd
(** If [do_split] is [true], we try to separate the problem in
several components and then solve them separately *)