aboutsummaryrefslogtreecommitdiff
path: root/tactics
diff options
context:
space:
mode:
authorMatthieu Sozeau2016-05-23 19:47:38 +0200
committerMatthieu Sozeau2016-06-09 15:24:08 +0200
commit1e389def84cc3eafc8aa5d1a1505f078a58234bd (patch)
tree7492ba5ed1df0575f8ee4e3dd7894cfe340ff18f /tactics
parent1cdb96f0201b4dda6bdb5f326f60314ae9bf700b (diff)
Univs/(e)auto: fix bug #4450 polymorphic exact hints
The exact and e_exact tactics were not registering the universes and constraints of the hint correctly. Now using the same connect_hint_clenv as unify_resolve, they do. Also correct the implementation of prepare_hint to normalize the universes of the hint before abstracting its undefined universes. They are going to be refreshed at each application. This means that eauto using term can use multiple different instantiations of the universes of term if term introduces new universes. If we want just one instantiation then the term should be abbreviated in the goal first.
Diffstat (limited to 'tactics')
-rw-r--r--tactics/auto.ml21
-rw-r--r--tactics/auto.mli4
-rw-r--r--tactics/eauto.ml418
-rw-r--r--tactics/hints.ml6
4 files changed, 23 insertions, 26 deletions
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 647ff97148..45da04cf00 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -97,7 +97,7 @@ let connect_hint_clenv poly (c, _, ctx) clenv gl =
let evd = Evd.merge_context_set Evd.univ_flexible evd ctx in
{ clenv with evd = evd ; env = Proofview.Goal.env gl }, c
in clenv, c
-
+
let unify_resolve poly flags ((c : raw_hint), clenv) =
Proofview.Goal.nf_enter begin fun gl ->
let clenv, c = connect_hint_clenv poly c clenv gl in
@@ -112,19 +112,12 @@ let unify_resolve_gen poly = function
| Some flags -> unify_resolve poly flags
let exact poly (c,clenv) =
- let (c, _, _) = c in
- let ctx, c' =
- if poly then
- let evd', subst = Evd.refresh_undefined_universes clenv.evd in
- let ctx = Evd.evar_universe_context evd' in
- ctx, subst_univs_level_constr subst c
- else
- let ctx = Evd.evar_universe_context clenv.evd in
- ctx, c
- in
- Proofview.Goal.enter begin fun gl ->
- let sigma = Evd.merge_universe_context (Proofview.Goal.sigma gl) ctx in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma) (exact_check c')
+ Proofview.Goal.enter begin
+ fun gl ->
+ let clenv', c = connect_hint_clenv poly c clenv gl in
+ Tacticals.New.tclTHEN
+ (Proofview.Unsafe.tclEVARUNIVCONTEXT (Evd.evar_universe_context clenv'.evd))
+ (exact_check c)
end
(* Util *)
diff --git a/tactics/auto.mli b/tactics/auto.mli
index 2e5647f872..0276e8258d 100644
--- a/tactics/auto.mli
+++ b/tactics/auto.mli
@@ -26,8 +26,8 @@ val default_search_depth : int ref
val auto_flags_of_state : transparent_state -> Unification.unify_flags
val connect_hint_clenv : polymorphic -> raw_hint -> clausenv ->
- [ `NF ] Proofview.Goal.t -> clausenv * constr
-
+ 'a Proofview.Goal.t -> clausenv * constr
+
(** Try unification with the precompiled clause, then use registered Apply *)
val unify_resolve_nodelta : polymorphic -> (raw_hint * clausenv) -> unit Proofview.tactic
diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml4
index 568b1d17c0..cb206a7dd1 100644
--- a/tactics/eauto.ml4
+++ b/tactics/eauto.ml4
@@ -117,7 +117,7 @@ open Unification
(***************************************************************************)
let priority l = List.map snd (List.filter (fun (pr,_) -> Int.equal pr 0) l)
-
+
let unify_e_resolve poly flags (c,clenv) =
Proofview.Goal.nf_enter begin
fun gl ->
@@ -138,12 +138,14 @@ let hintmap_of hdc concl =
(* FIXME: should be (Hint_db.map_eauto hdc concl db) *)
let e_exact poly flags (c,clenv) =
- let (c, _, _) = c in
- let clenv', subst =
- if poly then Clenv.refresh_undefined_univs clenv
- else clenv, Univ.empty_level_subst
- in e_give_exact (* ~flags *) (Vars.subst_univs_level_constr subst c)
-
+ Proofview.Goal.enter begin
+ fun gl ->
+ let clenv', c = connect_hint_clenv poly c clenv gl in
+ Tacticals.New.tclTHEN
+ (Proofview.Unsafe.tclEVARUNIVCONTEXT (Evd.evar_universe_context clenv'.evd))
+ (Proofview.V82.tactic (e_give_exact c))
+ end
+
let rec e_trivial_fail_db db_list local_db goal =
let tacl =
registered_e_assumption ::
@@ -174,7 +176,7 @@ and e_my_find_search db_list local_db hdc concl =
let tac = function
| Res_pf (term,cl) -> unify_resolve poly st (term,cl)
| ERes_pf (term,cl) -> unify_e_resolve poly st (term,cl)
- | Give_exact (c,cl) -> Proofview.V82.tactic (e_exact poly st (c,cl))
+ | Give_exact (c,cl) -> e_exact poly st (c,cl)
| Res_pf_THEN_trivial_fail (term,cl) ->
Proofview.V82.tactic (tclTHEN (Proofview.V82.of_tactic (unify_e_resolve poly st (term,cl)))
(e_trivial_fail_db db_list local_db))
diff --git a/tactics/hints.ml b/tactics/hints.ml
index 1da464e6f4..a1beacd5ed 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -1097,10 +1097,12 @@ exception Found of constr * types
let prepare_hint check (poly,local) env init (sigma,c) =
let sigma = Typeclasses.resolve_typeclasses ~fail:false env sigma in
- (* We re-abstract over uninstantiated evars.
+ (* We re-abstract over uninstantiated evars and universes.
It is actually a bit stupid to generalize over evars since the first
thing make_resolves will do is to re-instantiate the products *)
- let c = drop_extra_implicit_args (Evarutil.nf_evar sigma c) in
+ let sigma, subst = Evd.nf_univ_variables sigma in
+ let c = Vars.subst_univs_constr subst (Evarutil.nf_evar sigma c) in
+ let c = drop_extra_implicit_args c in
let vars = ref (collect_vars c) in
let subst = ref [] in
let rec find_next_evar c = match kind_of_term c with