aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorherbelin2011-06-18 20:35:22 +0000
committerherbelin2011-06-18 20:35:22 +0000
commit9d7499dcd4440aca458cb190ed108ae9b3adff17 (patch)
tree600b19fc9ca74cb6149676276b670e731e12ae66
parentc79db26e91c61bfa085e667ae14733a463b73423 (diff)
Generalizing flag use_evars_pattern_unification into a flag
use_pattern_unification common for evars and metas. As a compensation, add a flag use_meta_bound_pattern_unification to restore the old mechanism of pattern unification for metas applied to rels only (this is used e.g. by auto). Not sure yet, what could be the most appropriate set of flags. Added documentation of the flags. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@14221 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--CHANGES3
-rw-r--r--lib/flags.ml2
-rw-r--r--lib/flags.mli2
-rw-r--r--pretyping/unification.ml86
-rw-r--r--pretyping/unification.mli5
-rw-r--r--proofs/clenvtac.ml5
-rw-r--r--tactics/auto.ml7
-rw-r--r--tactics/class_tactics.ml45
-rw-r--r--tactics/equality.ml11
-rw-r--r--tactics/rewrite.ml415
-rw-r--r--tactics/tactics.ml2
11 files changed, 105 insertions, 38 deletions
diff --git a/CHANGES b/CHANGES
index 511c057f3f..10b0f09cf0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -33,6 +33,9 @@ Tactics
result in some rare incompatibilities (solvable by adapting name hypotheses).
- Introduction pattern "_" made more robust.
- Tactic (and Eval command) vm_compute can now be interrupted via Ctrl-C.
+- Unification in "apply" supports unification of patterns of the form
+ ?f x y = g(x,y) (compatibility ensured by using
+ "Unset Tactic Pattern Unification").
Vernacular commands
diff --git a/lib/flags.ml b/lib/flags.ml
index e8763bc79f..b9965af5dd 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -36,7 +36,7 @@ let raw_print = ref false
(* Compatibility mode *)
-type compat_version = V8_2
+type compat_version = V8_2 | V8_3
let compat_version = ref None
let version_strictly_greater v =
match !compat_version with None -> true | Some v' -> v'>v
diff --git a/lib/flags.mli b/lib/flags.mli
index f7e3c17597..4fd042e225 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -25,7 +25,7 @@ val load_proofs : load_proofs ref
val raw_print : bool ref
-type compat_version = V8_2
+type compat_version = V8_2 | V8_3
val compat_version : compat_version option ref
val version_strictly_greater : compat_version -> bool
val version_less_or_equal : compat_version -> bool
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 5a2dfead7c..79debed864 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -156,29 +156,71 @@ let _ =
optread = (fun () -> !global_evars_pattern_unification_flag);
optwrite = (:=) global_evars_pattern_unification_flag }
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optname = "pattern-unification for existential variables in tactics";
+ optkey = ["Tactic";"Pattern";"Unification"];
+ optread = (fun () -> !global_evars_pattern_unification_flag);
+ optwrite = (:=) global_evars_pattern_unification_flag }
+
type unify_flags = {
modulo_conv_on_closed_terms : Names.transparent_state option;
- use_metas_eagerly : bool;
+ (* What this flag controls was activated with all constants transparent, *)
+ (* even for auto, since Coq V5.10 *)
+
+ use_metas_eagerly_in_conv_on_closed_terms : bool;
+ (* This refinement of the conversion on closed terms is activable *)
+ (* (and activated for apply, rewrite but not auto since Feb 2008 for 8.2) *)
+
modulo_delta : Names.transparent_state;
+ (* This controls which constant are unfoldable; this is on for apply *)
+ (* (but not simple apply) since Feb 2008 for 8.2 *)
+
modulo_delta_types : Names.transparent_state;
+
resolve_evars : bool;
- use_evars_pattern_unification : bool;
+ (* This says if type classes instances resolution must be used to infer *)
+ (* the remaining evars *)
+
+ use_pattern_unification : bool;
+ (* This says if type classes instances resolution must be used to infer *)
+ (* the remaining evars *)
+
+ use_meta_bound_pattern_unification : bool;
+ (* This solves pattern "?n x1 ... xn = t" when the xi are distinct rels *)
+ (* This allows for instance to unify "forall x:A, B(x)" with "A' -> B'" *)
+ (* This was on for all tactics, including auto, since Sep 2006 for 8.1 *)
+
frozen_evars : ExistentialSet.t;
+ (* Evars of this set are considered axioms and never instantiated *)
+ (* Useful e.g. for autorewrite *)
+
restrict_conv_on_strict_subterms : bool;
+ (* No conversion at the root of the term; potentially useful for rewrite *)
+
modulo_betaiota : bool;
+ (* Support betaiota in the reduction *)
+ (* Note that zeta is always used *)
+
modulo_eta : bool;
+ (* Support eta in the reduction *)
+
allow_K_in_toplevel_higher_order_unification : bool
+ (* This is used only in second/higher order unification when looking for *)
+ (* subterms (rewrite and elim) *)
}
(* Default flag for unifying a type against a type (e.g. apply) *)
(* We set all conversion flags *)
let default_unify_flags = {
modulo_conv_on_closed_terms = Some full_transparent_state;
- use_metas_eagerly = true;
+ use_metas_eagerly_in_conv_on_closed_terms = true;
modulo_delta = full_transparent_state;
modulo_delta_types = full_transparent_state;
resolve_evars = false;
- use_evars_pattern_unification = true;
+ use_pattern_unification = true;
+ use_meta_bound_pattern_unification = true;
frozen_evars = ExistentialSet.empty;
restrict_conv_on_strict_subterms = false;
modulo_betaiota = true;
@@ -193,11 +235,12 @@ let default_unify_flags = {
(* out of "simple apply" *)
let default_no_delta_unify_flags = {
modulo_conv_on_closed_terms = Some full_transparent_state;
- use_metas_eagerly = true;
+ use_metas_eagerly_in_conv_on_closed_terms = true;
modulo_delta = empty_transparent_state;
modulo_delta_types = full_transparent_state;
resolve_evars = false;
- use_evars_pattern_unification = false;
+ use_pattern_unification = false;
+ use_meta_bound_pattern_unification = true;
frozen_evars = ExistentialSet.empty;
restrict_conv_on_strict_subterms = false;
modulo_betaiota = false;
@@ -212,11 +255,12 @@ let default_no_delta_unify_flags = {
(* call w_unify for induction/destruct/case/elim (13/6/2011) *)
let elim_flags = {
modulo_conv_on_closed_terms = Some full_transparent_state;
- use_metas_eagerly = true;
+ use_metas_eagerly_in_conv_on_closed_terms = true;
modulo_delta = full_transparent_state;
modulo_delta_types = full_transparent_state;
resolve_evars = false;
- use_evars_pattern_unification = true;
+ use_pattern_unification = true;
+ use_meta_bound_pattern_unification = true;
frozen_evars = ExistentialSet.empty;
restrict_conv_on_strict_subterms = false; (* ? *)
modulo_betaiota = false;
@@ -226,11 +270,12 @@ let elim_flags = {
let elim_no_delta_flags = {
modulo_conv_on_closed_terms = Some full_transparent_state;
- use_metas_eagerly = true;
+ use_metas_eagerly_in_conv_on_closed_terms = true;
modulo_delta = empty_transparent_state;
modulo_delta_types = full_transparent_state;
resolve_evars = false;
- use_evars_pattern_unification = false;
+ use_pattern_unification = false;
+ use_meta_bound_pattern_unification = true;
frozen_evars = ExistentialSet.empty;
restrict_conv_on_strict_subterms = false; (* ? *)
modulo_betaiota = false;
@@ -242,9 +287,15 @@ let set_no_head_reduction flags =
{ flags with restrict_conv_on_strict_subterms = true }
let use_evars_pattern_unification flags =
- !global_evars_pattern_unification_flag && flags.use_evars_pattern_unification
+ !global_evars_pattern_unification_flag && flags.use_pattern_unification
&& Flags.version_strictly_greater Flags.V8_2
+let use_metas_pattern_unification flags nb l =
+ !global_evars_pattern_unification_flag && flags.use_pattern_unification
+ || (Flags.version_less_or_equal Flags.V8_3 ||
+ flags.use_meta_bound_pattern_unification) &&
+ array_for_all (fun c -> isRel c && destRel c <= nb) l
+
let expand_key env = function
| Some (ConstKey cst) -> constant_opt_value env cst
| Some (VarKey id) -> (try named_body id env with Not_found -> None)
@@ -355,15 +406,15 @@ let unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb flag
reduce curenvnb pb b substn cM cN)
| App (f1,l1), _ when
- (isMeta f1 || use_evars_pattern_unification flags &&
- isAllowedEvar flags f1) &
+ (isMeta f1 && use_metas_pattern_unification flags (snd curenvnb) l1
+ || use_evars_pattern_unification flags && isAllowedEvar flags f1) &
is_unification_pattern curenvnb f1 l1 cN &
not (dependent f1 cN) ->
solve_pattern_eqn_array curenvnb f1 l1 cN substn
| _, App (f2,l2) when
- (isMeta f2 || use_evars_pattern_unification flags &&
- isAllowedEvar flags f2) &
+ (isMeta f2 && use_metas_pattern_unification flags (snd curenvnb) l2
+ || use_evars_pattern_unification flags && isAllowedEvar flags f2) &
is_unification_pattern curenvnb f2 l2 cM &
not (dependent f2 cM) ->
solve_pattern_eqn_array curenvnb f2 l2 cM substn
@@ -429,10 +480,11 @@ let unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb flag
(it is used by apply and rewrite); it might now be redundant
with the support for delta-expansion (which is used
essentially for apply)... *)
+ not (subterm_restriction b flags) &&
match flags.modulo_conv_on_closed_terms with
| None -> false
- | Some convflags when not (subterm_restriction b flags) ->
- let subst = if flags.use_metas_eagerly then metasubst else ms in
+ | Some convflags ->
+ let subst = if flags.use_metas_eagerly_in_conv_on_closed_terms then metasubst else ms in
match subst_defined_metas subst cM with
| None -> (* some undefined Metas in cM *) false
| Some m1 ->
diff --git a/pretyping/unification.mli b/pretyping/unification.mli
index 44b1c3889c..37eaa58026 100644
--- a/pretyping/unification.mli
+++ b/pretyping/unification.mli
@@ -12,11 +12,12 @@ open Evd
type unify_flags = {
modulo_conv_on_closed_terms : Names.transparent_state option;
- use_metas_eagerly : bool;
+ use_metas_eagerly_in_conv_on_closed_terms : bool;
modulo_delta : Names.transparent_state;
modulo_delta_types : Names.transparent_state;
resolve_evars : bool;
- use_evars_pattern_unification : bool;
+ use_pattern_unification : bool;
+ use_meta_bound_pattern_unification : bool;
frozen_evars : ExistentialSet.t;
restrict_conv_on_strict_subterms : bool;
modulo_betaiota : bool;
diff --git a/proofs/clenvtac.ml b/proofs/clenvtac.ml
index a266405f7a..ec9aada73c 100644
--- a/proofs/clenvtac.ml
+++ b/proofs/clenvtac.ml
@@ -102,11 +102,12 @@ let e_res_pf clenv = res_pf clenv ~with_evars:true ~flags:dft
let fail_quick_unif_flags = {
modulo_conv_on_closed_terms = Some full_transparent_state;
- use_metas_eagerly = false;
+ use_metas_eagerly_in_conv_on_closed_terms = false;
modulo_delta = empty_transparent_state;
modulo_delta_types = full_transparent_state;
resolve_evars = false;
- use_evars_pattern_unification = false;
+ use_pattern_unification = false;
+ use_meta_bound_pattern_unification = true; (* ? *)
frozen_evars = ExistentialSet.empty;
restrict_conv_on_strict_subterms = false; (* ? *)
modulo_betaiota = false;
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 18e71661ff..af9420a245 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -840,11 +840,12 @@ open Unification
let auto_unif_flags = {
modulo_conv_on_closed_terms = Some full_transparent_state;
- use_metas_eagerly = false;
+ use_metas_eagerly_in_conv_on_closed_terms = false;
modulo_delta = empty_transparent_state;
modulo_delta_types = full_transparent_state;
resolve_evars = true;
- use_evars_pattern_unification = false;
+ use_pattern_unification = false;
+ use_meta_bound_pattern_unification = true;
frozen_evars = ExistentialSet.empty;
restrict_conv_on_strict_subterms = false; (* Compat *)
modulo_betaiota = false;
@@ -971,7 +972,7 @@ and my_find_search mod_delta =
else my_find_search_nodelta
and my_find_search_delta db_list local_db hdc concl =
- let flags = {auto_unif_flags with use_metas_eagerly = true} in
+ let flags = {auto_unif_flags with use_metas_eagerly_in_conv_on_closed_terms = true} in
let f = hintmap_of hdc concl in
if occur_existential concl then
list_map_append
diff --git a/tactics/class_tactics.ml4 b/tactics/class_tactics.ml4
index b460222b95..aed9f59857 100644
--- a/tactics/class_tactics.ml4
+++ b/tactics/class_tactics.ml4
@@ -74,11 +74,12 @@ open Unification
let auto_unif_flags = {
modulo_conv_on_closed_terms = Some full_transparent_state;
- use_metas_eagerly = true;
+ use_metas_eagerly_in_conv_on_closed_terms = true;
modulo_delta = var_full_transparent_state;
modulo_delta_types = full_transparent_state;
resolve_evars = false;
- use_evars_pattern_unification = true;
+ use_pattern_unification = true;
+ use_meta_bound_pattern_unification = true;
frozen_evars = ExistentialSet.empty;
restrict_conv_on_strict_subterms = false; (* ? *)
modulo_betaiota = true;
diff --git a/tactics/equality.ml b/tactics/equality.ml
index d2970603ea..3a40994f8c 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -82,11 +82,12 @@ type conditions =
let rewrite_unif_flags = {
Unification.modulo_conv_on_closed_terms = None;
- Unification.use_metas_eagerly = true;
+ Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
Unification.modulo_delta = empty_transparent_state;
Unification.modulo_delta_types = empty_transparent_state;
Unification.resolve_evars = true;
- Unification.use_evars_pattern_unification = true;
+ Unification.use_pattern_unification = true;
+ Unification.use_meta_bound_pattern_unification = true;
Unification.frozen_evars = ExistentialSet.empty;
Unification.restrict_conv_on_strict_subterms = false;
Unification.modulo_betaiota = false;
@@ -142,17 +143,19 @@ let rewrite_conv_closed_unif_flags = {
(* We have this flag for historical reasons, it has e.g. the consequence *)
(* to rewrite "?x+2" in "y+(1+1)=0" or to rewrite "?x+?x" in "2+(1+1)=0" *)
- Unification.use_metas_eagerly = true;
+ Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
(* Combined with modulo_conv_on_closed_terms, this flag allows since 8.2 *)
(* to rewrite e.g. "?x+(2+?x)" in "1+(1+2)=0" *)
Unification.modulo_delta = empty_transparent_state;
Unification.modulo_delta_types = full_transparent_state;
Unification.resolve_evars = false;
- Unification.use_evars_pattern_unification = true;
+ Unification.use_pattern_unification = true;
(* To rewrite "?n x y" in "y+x=0" when ?n is *)
(* a preexisting evar of the goal*)
+ Unification.use_meta_bound_pattern_unification = true;
+
Unification.frozen_evars = ExistentialSet.empty;
(* This is set dynamically *)
diff --git a/tactics/rewrite.ml4 b/tactics/rewrite.ml4
index 821284ec7f..5400827bcf 100644
--- a/tactics/rewrite.ml4
+++ b/tactics/rewrite.ml4
@@ -302,11 +302,12 @@ let rewrite_transparent_state () =
let rewrite_unif_flags = {
Unification.modulo_conv_on_closed_terms = None;
- Unification.use_metas_eagerly = true;
+ Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
Unification.modulo_delta = empty_transparent_state;
Unification.modulo_delta_types = full_transparent_state;
Unification.resolve_evars = true;
- Unification.use_evars_pattern_unification = true;
+ Unification.use_pattern_unification = true;
+ Unification.use_meta_bound_pattern_unification = true;
Unification.frozen_evars = ExistentialSet.empty;
Unification.restrict_conv_on_strict_subterms = false;
Unification.modulo_betaiota = false;
@@ -316,11 +317,12 @@ let rewrite_unif_flags = {
let rewrite2_unif_flags =
{ Unification.modulo_conv_on_closed_terms = Some conv_transparent_state;
- Unification.use_metas_eagerly = true;
+ Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
Unification.modulo_delta = empty_transparent_state;
Unification.modulo_delta_types = conv_transparent_state;
Unification.resolve_evars = true;
- Unification.use_evars_pattern_unification = true;
+ Unification.use_pattern_unification = true;
+ Unification.use_meta_bound_pattern_unification = true;
Unification.frozen_evars = ExistentialSet.empty;
Unification.restrict_conv_on_strict_subterms = false;
Unification.modulo_betaiota = true;
@@ -331,11 +333,12 @@ let rewrite2_unif_flags =
let general_rewrite_unif_flags () =
let ts = rewrite_transparent_state () in
{ Unification.modulo_conv_on_closed_terms = Some ts;
- Unification.use_metas_eagerly = true;
+ Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
Unification.modulo_delta = ts;
Unification.modulo_delta_types = ts;
Unification.resolve_evars = true;
- Unification.use_evars_pattern_unification = true;
+ Unification.use_pattern_unification = true;
+ Unification.use_meta_bound_pattern_unification = true;
Unification.frozen_evars = ExistentialSet.empty;
Unification.restrict_conv_on_strict_subterms = false;
Unification.modulo_betaiota = true;
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 060cd94a87..97928c87c2 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -842,6 +842,7 @@ type conjunction_status =
let make_projection sigma params cstr sign elim i n c =
let elim = match elim with
| NotADefinedRecordUseScheme elim ->
+ (* bugs: goes from right to left when i increases! *)
let (na,b,t) = List.nth cstr.cs_args i in
let b = match b with None -> mkRel (i+1) | Some b -> b in
let branch = it_mkLambda_or_LetIn b cstr.cs_args in
@@ -856,6 +857,7 @@ let make_projection sigma params cstr sign elim i n c =
else
None
| DefinedRecord l ->
+ (* goes from left to right when i increases! *)
match List.nth l i with
| Some proj ->
let t = Typeops.type_of_constant (Global.env()) proj in