aboutsummaryrefslogtreecommitdiffhomepage
path: root/pretyping/pretyping.ml
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping/pretyping.ml')
-rw-r--r--pretyping/pretyping.ml62
1 files changed, 35 insertions, 27 deletions
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index 5383101b4..6dbf7915b 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -142,19 +142,27 @@ type inference_flags = {
expand_evars : bool
}
-let apply_typeclasses env evdref fail_evar =
+let fold_pending_holes f (sigma,sigma') =
+ Evd.fold_undefined
+ (fun evk _ acc -> if Evd.mem sigma evk then acc else f evk acc)
+ sigma'
+
+let is_pending_hole (sigma,sigma') evk =
+ Evd.is_undefined sigma' evk && not (Evd.mem sigma evk)
+
+let apply_typeclasses env evdref pending fail_evar =
evdref := Typeclasses.resolve_typeclasses
~filter:(if Flags.is_program_mode ()
- then Typeclasses.no_goals_or_obligations else Typeclasses.no_goals)
+ then (fun evk evi -> is_pending_hole pending evk && Typeclasses.no_goals_or_obligations evk evi)
+ else (fun evk evi -> is_pending_hole pending evk && Typeclasses.no_goals evk evi))
~split:true ~fail:fail_evar env !evdref;
if Flags.is_program_mode () then (* Try optionally solving the obligations *)
evdref := Typeclasses.resolve_typeclasses
- ~filter:Typeclasses.all_evars ~split:true ~fail:false env !evdref
+ ~filter:(fun evk evi -> is_pending_hole pending evk && Typeclasses.all_evars evk evi) ~split:true ~fail:false env !evdref
-let apply_inference_hook hook initial_sigma evdref =
- evdref := fold_undefined (fun evk evi sigma ->
- if not (Evd.mem initial_sigma evk) &&
- is_undefined sigma evk (* i.e. not defined by side-effect *)
+let apply_inference_hook hook evdref pending =
+ evdref := fold_pending_holes (fun evk sigma ->
+ if Evd.is_undefined sigma evk (* in particular not defined by side-effect *)
then
try
let c = hook sigma evk in
@@ -162,7 +170,7 @@ let apply_inference_hook hook initial_sigma evdref =
with Exit ->
sigma
else
- sigma) !evdref !evdref
+ sigma) pending !evdref
let apply_heuristics env evdref fail_evar =
(* Resolve eagerly, potentially making wrong choices *)
@@ -171,39 +179,39 @@ let apply_heuristics env evdref fail_evar =
with e when Errors.noncritical e ->
let e = Errors.push e in if fail_evar then raise e
-let check_typeclasses_instances_are_solved env sigma =
+let check_typeclasses_instances_are_solved env current_sigma pending =
(* Naive way, call resolution again with failure flag *)
- apply_typeclasses env (ref sigma) true
+ apply_typeclasses env (ref current_sigma) pending true
-let check_extra_evars_are_solved env initial_sigma sigma =
- Evd.fold_undefined
- (fun evk evi () ->
- if not (Evd.mem initial_sigma evk) then
- let (loc,k) = evar_source evk sigma in
+let check_extra_evars_are_solved env current_sigma pending =
+ fold_pending_holes
+ (fun evk () ->
+ if not (Evd.is_defined current_sigma evk) then
+ let (loc,k) = evar_source evk current_sigma in
match k with
| Evar_kinds.ImplicitArg (gr, (i, id), false) -> ()
| _ ->
- let evi = nf_evar_info sigma (Evd.find_undefined sigma evk) in
- error_unsolvable_implicit loc env sigma evi k None) sigma ()
+ let evi = nf_evar_info current_sigma (Evd.find_undefined current_sigma evk) in
+ error_unsolvable_implicit loc env current_sigma evi k None) pending ()
-let check_evars_are_solved env initial_sigma sigma =
- check_typeclasses_instances_are_solved env sigma;
- check_problems_are_solved env sigma;
- check_extra_evars_are_solved env initial_sigma sigma
+let check_evars_are_solved env current_sigma pending =
+ check_typeclasses_instances_are_solved env current_sigma pending;
+ check_problems_are_solved env current_sigma;
+ check_extra_evars_are_solved env current_sigma pending
(* Try typeclasses, hooks, unification heuristics ... *)
-let solve_remaining_evars flags env initial_sigma sigma =
- let evdref = ref sigma in
- if flags.use_typeclasses then apply_typeclasses env evdref false;
+let solve_remaining_evars flags env current_sigma pending =
+ let evdref = ref current_sigma in
+ if flags.use_typeclasses then apply_typeclasses env evdref pending false;
if Option.has_some flags.use_hook then
- apply_inference_hook (Option.get flags.use_hook env) initial_sigma evdref;
+ apply_inference_hook (Option.get flags.use_hook env) evdref pending;
if flags.use_unif_heuristics then apply_heuristics env evdref false;
- if flags.fail_evar then check_evars_are_solved env initial_sigma !evdref;
+ if flags.fail_evar then check_evars_are_solved env !evdref pending;
!evdref
let process_inference_flags flags env initial_sigma (sigma,c) =
- let sigma = solve_remaining_evars flags env initial_sigma sigma in
+ let sigma = solve_remaining_evars flags env sigma (initial_sigma,sigma) in
let c = if flags.expand_evars then nf_evar sigma c else c in
sigma,c