aboutsummaryrefslogtreecommitdiff
path: root/pretyping
diff options
context:
space:
mode:
authorMatthieu Sozeau2018-10-08 02:14:07 +0200
committerMatthieu Sozeau2018-10-26 18:29:36 +0200
commit9f65b8bf9775dd571a806e10ac356b1b8f8ae2c5 (patch)
tree56a49e0cd7d6ee19d4bb25ff0165e1c1466a7e73 /pretyping
parentbe144dcaa1d1d8ff22e9e39f49fd247e813ac1f8 (diff)
Cleanup evar_extra: remove evar_info's store and add maps to evar_map
Diffstat (limited to 'pretyping')
-rw-r--r--pretyping/evarsolve.ml33
-rw-r--r--pretyping/pretyping.ml9
-rw-r--r--pretyping/typeclasses.ml45
-rw-r--r--pretyping/typeclasses.mli5
4 files changed, 37 insertions, 55 deletions
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 22f438c00c..9422a96f21 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -1238,19 +1238,26 @@ let check_evar_instance evd evk1 body conv_algo =
| Success evd -> evd
| UnifFailure _ -> raise (IllTypedInstance (evenv,ty, evi.evar_concl))
-let update_evar_source ev1 ev2 evd =
+let update_evar_info ev1 ev2 evd =
let loc, evs2 = evar_source ev2 evd in
- match evs2 with
- | (Evar_kinds.QuestionMark _ | Evar_kinds.ImplicitArg (_, _, false)) ->
- let evi = Evd.find evd ev1 in
- Evd.add evd ev1 {evi with evar_source = loc, evs2}
- | _ -> evd
-
+ let evd =
+ (* We keep the obligation evar flag during evar-evar unifications *)
+ if is_obligation_evar evd ev2 then
+ let evi = Evd.find evd ev1 in
+ let evd = Evd.add evd ev1 {evi with evar_source = loc, evs2} in
+ Evd.set_obligation_evar evd ev1
+ else evd
+ in
+ (** [ev1] inherits the unresolvability status from [ev2] *)
+ if not (Evd.is_resolvable_evar evd ev2) then
+ Evd.set_resolvable_evar evd ev1 false
+ else evd
+
let solve_evar_evar_l2r force f g env evd aliases pbty ev1 (evk2,_ as ev2) =
try
let evd,body = project_evar_on_evar force g env evd aliases 0 pbty ev1 ev2 in
let evd' = Evd.define evk2 body evd in
- let evd' = update_evar_source (fst (destEvar evd body)) evk2 evd' in
+ let evd' = update_evar_info (fst (destEvar evd body)) evk2 evd' in
check_evar_instance evd' evk2 body g
with EvarSolvedOnTheFly (evd,c) ->
f env evd pbty ev2 c
@@ -1258,13 +1265,9 @@ let solve_evar_evar_l2r force f g env evd aliases pbty ev1 (evk2,_ as ev2) =
let opp_problem = function None -> None | Some b -> Some (not b)
let preferred_orientation evd evk1 evk2 =
- let _,src1 = (Evd.find_undefined evd evk1).evar_source in
- let _,src2 = (Evd.find_undefined evd evk2).evar_source in
- (* This is a heuristic useful for program to work *)
- match src1,src2 with
- | (Evar_kinds.QuestionMark _ | Evar_kinds.ImplicitArg (_, _, false)) , _ -> true
- | _, (Evar_kinds.QuestionMark _ | Evar_kinds.ImplicitArg (_, _, false)) -> false
- | _ -> true
+ if is_obligation_evar evd evk1 then true
+ else if is_obligation_evar evd evk2 then false
+ else true
let solve_evar_evar_aux force f g env evd pbty (evk1,args1 as ev1) (evk2,args2 as ev2) =
let aliases = make_alias_map env evd in
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index f2881e4a19..37afcf75e1 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -510,6 +510,15 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : GlobEnv.t) (sigma
| Some ty -> sigma, ty
| None -> new_type_evar env sigma loc in
let sigma, uj_val = new_evar env sigma ~src:(loc,k) ~naming ty in
+ let sigma =
+ if Flags.is_program_mode () then
+ match k with
+ | Evar_kinds.QuestionMark _
+ | Evar_kinds.ImplicitArg (_, _, false) ->
+ Evd.set_obligation_evar sigma (fst (destEvar sigma uj_val))
+ | _ -> sigma
+ else sigma
+ in
sigma, { uj_val; uj_type = ty }
| GHole (k, _naming, Some arg) ->
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 0bc35e5358..07821f03e5 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -481,37 +481,10 @@ let instances r =
let is_class gr =
GlobRef.Map.exists (fun _ v -> GlobRef.equal v.cl_impl gr) !classes
-(* To embed a boolean for resolvability status.
- This is essentially a hack to mark which evars correspond to
- goals and do not need to be resolved when we have nested [resolve_all_evars]
- calls (e.g. when doing apply in an External hint in typeclass_instances).
- Would be solved by having real evars-as-goals.
-
- Nota: we will only check the resolvability status of undefined evars.
- *)
-
-let resolvable = Proofview.Unsafe.typeclass_resolvable
-
-let set_resolvable s b =
- if b then Store.remove s resolvable
- else Store.set s resolvable ()
-
-let is_resolvable evi =
- assert (match evi.evar_body with Evar_empty -> true | _ -> false);
- Option.is_empty (Store.get evi.evar_extra resolvable)
-
-let mark_resolvability_undef b evi =
- if is_resolvable evi == (b : bool) then evi
- else
- let t = set_resolvable evi.evar_extra b in
- { evi with evar_extra = t }
-
-let mark_resolvability b evi =
- assert (match evi.evar_body with Evar_empty -> true | _ -> false);
- mark_resolvability_undef b evi
-
-let mark_unresolvable evi = mark_resolvability false evi
-let mark_resolvable evi = mark_resolvability true evi
+let mark_resolvability_undef evm evk b =
+ let resolvable = Evd.is_resolvable_evar evm evk in
+ if b == resolvable then evm
+ else Evd.set_resolvable_evar evm evk b
open Evar_kinds
type evar_filter = Evar.t -> Evar_kinds.t -> bool
@@ -524,18 +497,18 @@ let no_goals_or_obligations _ = function
| _ -> true
let mark_resolvability filter b sigma =
- let map ev evi =
- if filter ev (snd evi.evar_source) then mark_resolvability_undef b evi
- else evi
+ let map ev evi evm =
+ if filter ev (snd evi.evar_source) then mark_resolvability_undef evm ev b
+ else evm
in
- Evd.raw_map_undefined map sigma
+ Evd.fold_undefined map sigma sigma
let mark_unresolvables ?(filter=all_evars) sigma = mark_resolvability filter false sigma
let mark_resolvables ?(filter=all_evars) sigma = mark_resolvability filter true sigma
let has_typeclasses filter evd =
let check ev evi =
- filter ev (snd evi.evar_source) && is_resolvable evi && is_class_evar evd evi
+ filter ev (snd evi.evar_source) && Evd.is_resolvable_evar evd ev && is_class_evar evd evi
in
Evar.Map.exists check (Evd.undefined_map evd)
diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli
index f0437be4ed..de9a99a868 100644
--- a/pretyping/typeclasses.mli
+++ b/pretyping/typeclasses.mli
@@ -107,12 +107,9 @@ val no_goals_or_obligations : evar_filter
An unresolvable evar is an evar the type-class engine will NOT try to solve
*)
-val set_resolvable : Evd.Store.t -> bool -> Evd.Store.t
-val is_resolvable : evar_info -> bool
-val mark_unresolvable : evar_info -> evar_info
val mark_unresolvables : ?filter:evar_filter -> evar_map -> evar_map
val mark_resolvables : ?filter:evar_filter -> evar_map -> evar_map
-val mark_resolvable : evar_info -> evar_info
+
val is_class_evar : evar_map -> evar_info -> bool
val is_class_type : evar_map -> EConstr.types -> bool