diff options
| author | Hugo Herbelin | 2014-09-30 09:50:07 +0200 |
|---|---|---|
| committer | Hugo Herbelin | 2014-09-30 10:02:47 +0200 |
| commit | a1be9ce30ed0c59d3cd8651ff0c624a24a6d3fc9 (patch) | |
| tree | a2d0ce66634899dd71d5abb8e525cf1a7ebad7cb | |
| parent | 538b77dbb3b7799dc4d2e18033fc4fbf2eb26f7f (diff) | |
Seeing IntroWildcard as an action intro pattern rather than as a naming pattern
(the action is "clear").
Added subst_intropattern which was missing since the introduction of
ApplyOn intro patterns.
Still to do: make "intros _ ?id" working without interferences when
"id" is precisely the internal name used for hypotheses to discard.
| -rw-r--r-- | grammar/q_coqast.ml4 | 1 | ||||
| -rw-r--r-- | intf/misctypes.mli | 2 | ||||
| -rw-r--r-- | parsing/g_tactic.ml4 | 4 | ||||
| -rw-r--r-- | pretyping/evd.ml | 3 | ||||
| -rw-r--r-- | pretyping/miscops.ml | 1 | ||||
| -rw-r--r-- | printing/miscprint.ml | 2 | ||||
| -rw-r--r-- | tactics/inv.ml | 4 | ||||
| -rw-r--r-- | tactics/tacintern.ml | 4 | ||||
| -rw-r--r-- | tactics/tacinterp.ml | 8 | ||||
| -rw-r--r-- | tactics/tacsubst.ml | 15 | ||||
| -rw-r--r-- | tactics/tactics.ml | 27 | ||||
| -rw-r--r-- | test-suite/success/intros.v | 5 |
12 files changed, 48 insertions, 28 deletions
diff --git a/grammar/q_coqast.ml4 b/grammar/q_coqast.ml4 index 25d4c0b23c..1eadf7dfdc 100644 --- a/grammar/q_coqast.ml4 +++ b/grammar/q_coqast.ml4 @@ -62,7 +62,6 @@ let mlexpr_of_intro_pattern_disjunctive = function _ -> failwith "mlexpr_of_intro_pattern_disjunctive: TODO" let mlexpr_of_intro_pattern_naming = function - | Misctypes.IntroWildcard -> <:expr< Misctypes.IntroWildcard >> | Misctypes.IntroAnonymous -> <:expr< Misctypes.IntroAnonymous >> | Misctypes.IntroFresh id -> <:expr< Misctypes.IntroFresh (mlexpr_of_ident $dloc$ id) >> | Misctypes.IntroIdentifier id -> diff --git a/intf/misctypes.mli b/intf/misctypes.mli index c61da0e306..2c8ac3a693 100644 --- a/intf/misctypes.mli +++ b/intf/misctypes.mli @@ -21,11 +21,11 @@ type 'constr intro_pattern_expr = | IntroNaming of intro_pattern_naming_expr | IntroAction of 'constr intro_pattern_action_expr and intro_pattern_naming_expr = - | IntroWildcard | IntroIdentifier of Id.t | IntroFresh of Id.t | IntroAnonymous and 'constr intro_pattern_action_expr = + | IntroWildcard | IntroOrAndPattern of 'constr or_and_intro_pattern_expr | IntroInjection of (Loc.t * 'constr intro_pattern_expr) list | IntroApplyOn of 'constr * (Loc.t * 'constr intro_pattern_expr) diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4 index 3e83e2ca18..80edccfeb1 100644 --- a/parsing/g_tactic.ml4 +++ b/parsing/g_tactic.ml4 @@ -296,8 +296,7 @@ GEXTEND Gram naming_intropattern: [ [ prefix = pattern_ident -> IntroFresh prefix | "?" -> IntroAnonymous - | id = ident -> IntroIdentifier id - | "_" -> IntroWildcard ] ] + | id = ident -> IntroIdentifier id ] ] ; nonsimple_intropattern: [ [ l = simple_intropattern -> l @@ -307,6 +306,7 @@ GEXTEND Gram simple_intropattern: [ [ pat = or_and_intropattern -> !@loc, IntroAction (IntroOrAndPattern pat) | pat = equality_intropattern -> !@loc, IntroAction pat + | "_" -> !@loc, IntroAction IntroWildcard | pat = simple_intropattern; "/"; c = constr -> !@loc, IntroAction (IntroApplyOn (c,pat)) | pat = naming_intropattern -> !@loc, IntroNaming pat ] ] diff --git a/pretyping/evd.ml b/pretyping/evd.ml index ffc1ea2a77..826fd59ba8 100644 --- a/pretyping/evd.ml +++ b/pretyping/evd.ml @@ -612,8 +612,7 @@ let add_name_newly_undefined naming evk evi (evtoid,idtoev) = (Loc.ghost,"",str "Already an existential evar of name " ++ pr_id id); id' | Misctypes.IntroFresh id -> - Namegen.next_ident_away_from id (fun id -> Idmap.mem id idtoev) - | Misctypes.IntroWildcard -> assert false in + Namegen.next_ident_away_from id (fun id -> Idmap.mem id idtoev) in (EvMap.add evk id evtoid, Idmap.add id evk idtoev) let add_name_undefined naming evk evi (evtoid,idtoev as evar_names) = diff --git a/pretyping/miscops.ml b/pretyping/miscops.ml index e96e3a8b7f..83e33f84ea 100644 --- a/pretyping/miscops.ml +++ b/pretyping/miscops.ml @@ -34,6 +34,5 @@ let glob_sort_eq g1 g2 = match g1, g2 with let intro_pattern_naming_eq nam1 nam2 = match nam1, nam2 with | IntroAnonymous, IntroAnonymous -> true | IntroIdentifier id1, IntroIdentifier id2 -> Names.Id.equal id1 id2 -| IntroWildcard, IntroWildcard -> true | IntroFresh id1, IntroFresh id2 -> Names.Id.equal id1 id2 | _ -> false diff --git a/printing/miscprint.ml b/printing/miscprint.ml index 682cc3abe7..b47deab0fa 100644 --- a/printing/miscprint.ml +++ b/printing/miscprint.ml @@ -18,12 +18,12 @@ let rec pr_intro_pattern prc (_,pat) = match pat with | IntroAction p -> pr_intro_pattern_action prc p and pr_intro_pattern_naming = function - | IntroWildcard -> str "_" | IntroIdentifier id -> Nameops.pr_id id | IntroFresh id -> str "?" ++ Nameops.pr_id id | IntroAnonymous -> str "?" and pr_intro_pattern_action prc = function + | IntroWildcard -> str "_" | IntroOrAndPattern pll -> pr_or_and_intro_pattern prc pll | IntroInjection pl -> str "[=" ++ hv 0 (prlist_with_sep spc (pr_intro_pattern prc) pl) ++ diff --git a/tactics/inv.ml b/tactics/inv.ml index 081b62b18c..457068c6cd 100644 --- a/tactics/inv.ml +++ b/tactics/inv.ml @@ -286,12 +286,12 @@ let error_too_many_names pats = str ".") let rec get_names (allow_conj,issimple) (loc,pat as x) = match pat with - | IntroNaming IntroWildcard -> - error "Discarding pattern not allowed for inversion equations." | IntroNaming IntroAnonymous | IntroForthcoming _ -> error "Anonymous pattern not allowed for inversion equations." | IntroNaming (IntroFresh _) -> error "Fresh pattern not allowed for inversion equations." + | IntroAction IntroWildcard -> + error "Discarding pattern not allowed for inversion equations." | IntroAction (IntroRewrite _) -> error "Rewriting pattern not allowed for inversion equations." | IntroAction (IntroOrAndPattern [[]]) when allow_conj -> (None, []) diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml index 23be275520..08dd0dff48 100644 --- a/tactics/tacintern.ml +++ b/tactics/tacintern.ml @@ -254,14 +254,14 @@ and intern_intro_pattern_naming lf ist = function IntroIdentifier (intern_ident lf ist id) | IntroFresh id -> IntroFresh (intern_ident lf ist id) - | IntroWildcard | IntroAnonymous as x -> x + | IntroAnonymous as x -> x and intern_intro_pattern_action lf ist = function | IntroOrAndPattern l -> IntroOrAndPattern (intern_or_and_intro_pattern lf ist l) | IntroInjection l -> IntroInjection (List.map (intern_intro_pattern lf ist) l) - | IntroRewrite _ as x -> x + | IntroWildcard | IntroRewrite _ as x -> x | IntroApplyOn (c,pat) -> IntroApplyOn (intern_constr ist c, intern_intro_pattern lf ist pat) diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml index 991eac57ed..cd460ebbe7 100644 --- a/tactics/tacinterp.ml +++ b/tactics/tacinterp.ml @@ -423,8 +423,8 @@ let rec intropattern_ids (loc,pat) = match pat with | IntroAction (IntroInjection l) -> List.flatten (List.map intropattern_ids l) | IntroAction (IntroApplyOn (c,pat)) -> intropattern_ids pat - | IntroNaming (IntroWildcard | IntroAnonymous | IntroFresh _) - | IntroAction (IntroRewrite _) + | IntroNaming (IntroAnonymous | IntroFresh _) + | IntroAction (IntroWildcard | IntroRewrite _) | IntroForthcoming _ -> [] let extract_ids ids lfun = @@ -799,7 +799,7 @@ let rec interp_intro_pattern ist env sigma = function and interp_intro_pattern_naming loc ist env sigma = function | IntroFresh id -> IntroFresh (interp_fresh_ident ist env sigma id) | IntroIdentifier id -> interp_intro_pattern_naming_var loc ist env sigma id - | (IntroWildcard | IntroAnonymous) as x -> x + | IntroAnonymous as x -> x and interp_intro_pattern_action ist env sigma = function | IntroOrAndPattern l -> @@ -812,7 +812,7 @@ and interp_intro_pattern_action ist env sigma = function let c = fun env sigma -> interp_constr ist env sigma c in let sigma,ipat = interp_intro_pattern ist env sigma ipat in sigma, IntroApplyOn (c,ipat) - | IntroRewrite _ as x -> sigma, x + | IntroWildcard | IntroRewrite _ as x -> sigma, x and interp_or_and_intro_pattern ist env sigma = List.fold_map (interp_intro_pattern_list_as_list ist env) sigma diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml index b1d03f86e2..27d0d7e0fd 100644 --- a/tactics/tacsubst.ml +++ b/tactics/tacsubst.ml @@ -47,6 +47,18 @@ let subst_glob_with_bindings subst (c,bl) = let subst_glob_with_bindings_arg subst (clear,c) = (clear,subst_glob_with_bindings subst c) +let rec subst_intro_pattern subst = function + | loc,IntroAction p -> loc, IntroAction (subst_intro_pattern_action subst p) + | loc, IntroNaming _ | loc, IntroForthcoming _ as x -> x + +and subst_intro_pattern_action subst = function + | IntroApplyOn (t,pat) -> + IntroApplyOn (subst_glob_constr subst t,subst_intro_pattern subst pat) + | IntroOrAndPattern l -> + IntroOrAndPattern (List.map (List.map (subst_intro_pattern subst)) l) + | IntroInjection l -> IntroInjection (List.map (subst_intro_pattern subst) l) + | IntroWildcard | IntroRewrite _ as x -> x + let subst_induction_arg subst = function | clear,ElimOnConstr c -> clear,ElimOnConstr (subst_glob_with_bindings subst c) | clear,ElimOnAnonHyp n as x -> x @@ -135,7 +147,8 @@ let rec subst_match_goal_hyps subst = function let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with (* Basic tactics *) - | TacIntroPattern _ | TacIntroMove _ as x -> x + | TacIntroPattern l -> TacIntroPattern (List.map (subst_intro_pattern subst) l) + | TacIntroMove _ as x -> x | TacExact c -> TacExact (subst_glob_constr subst c) | TacApply (a,ev,cb,cl) -> TacApply (a,ev,List.map (subst_glob_with_bindings_arg subst) cb,cl) diff --git a/tactics/tactics.ml b/tactics/tactics.ml index 69a72db4f7..2ccad790f1 100644 --- a/tactics/tactics.ml +++ b/tactics/tactics.ml @@ -1852,8 +1852,6 @@ let rec prepare_naming loc = function | IntroIdentifier id -> NamingMustBe (loc,id) | IntroAnonymous -> NamingAvoid [] | IntroFresh id -> NamingBasedOn (id,[]) - | IntroWildcard -> - error "Did you really mind erasing the newly generated hypothesis?" let rec explicit_intro_names = function | (_, IntroForthcoming _) :: l -> explicit_intro_names l @@ -1864,8 +1862,8 @@ let rec explicit_intro_names = function explicit_intro_names (l@l') | (_, IntroAction (IntroApplyOn (c,pat))) :: l' -> explicit_intro_names (pat::l') -| (_, (IntroNaming (IntroWildcard | IntroAnonymous | IntroFresh _) - | IntroAction (IntroRewrite _))) :: l -> +| (_, (IntroNaming (IntroAnonymous | IntroFresh _) + | IntroAction (IntroWildcard | IntroRewrite _))) :: l -> explicit_intro_names l | [] -> [] @@ -1884,6 +1882,16 @@ let check_thin_clash_then id thin avoid tac = else tac thin +let make_tmp_naming avoid l = function + (* In theory, we could use a tmp id like "wild_id" for all actions + but we prefer to avoid it to avoid this kind of "ugly" names *) + (* Alternatively, we could have called check_thin_clash_then on + IntroAnonymous, but at the cost of a "renaming"; Note that in the + case of IntroFresh, we should use check_thin_clash_then anyway to + prevent the case of an IntroFresh precisely using the wild_id *) + | IntroWildcard -> NamingBasedOn (wild_id,avoid@explicit_intro_names l) + | _ -> NamingAvoid(avoid@explicit_intro_names l) + let fit_bound n = function | None -> true | Some (use_bound,n') -> not use_bound || n = n' @@ -1912,7 +1920,7 @@ let rec intro_patterns_core b avoid ids thin destopt bound n tac = function (fun ids -> intro_patterns_core b avoid ids thin destopt bound (n+List.length ids) tac l) | IntroAction pat -> - intro_then_gen (NamingAvoid(avoid@explicit_intro_names l)) + intro_then_gen (make_tmp_naming avoid l pat) MoveLast true false (intro_pattern_action loc (b || not (List.is_empty l)) false pat thin (fun thin bound' -> intro_patterns_core b avoid ids thin destopt bound' 0 @@ -1923,10 +1931,6 @@ let rec intro_patterns_core b avoid ids thin destopt bound n tac = function and intro_pattern_naming loc b avoid ids pat thin destopt bound n tac l = match pat with - | IntroWildcard -> - intro_then_gen (NamingBasedOn(wild_id,avoid@explicit_intro_names l)) - MoveLast true false - (fun id -> intro_patterns_core b avoid ids ((loc,id)::thin) destopt bound (n+1) tac l) | IntroIdentifier id -> check_thin_clash_then id thin avoid (fun thin -> intro_then_gen (NamingMustBe (loc,id)) destopt true false @@ -1942,6 +1946,8 @@ and intro_pattern_naming loc b avoid ids pat thin destopt bound n tac l = (fun id -> intro_patterns_core b avoid (id::ids) thin destopt bound (n+1) tac l) and intro_pattern_action loc b style pat thin tac id = match pat with + | IntroWildcard -> + tac ((loc,id)::thin) None [] | IntroOrAndPattern ll -> intro_or_and_pattern loc b ll thin tac id | IntroInjection l' -> @@ -2091,8 +2097,7 @@ let letin_tac_gen with_eq abs ty = let heq = match ido with | IntroAnonymous -> new_fresh_id [id] (add_prefix "Heq" id) gl | IntroFresh heq_base -> new_fresh_id [id] heq_base gl - | IntroIdentifier id -> id - | _ -> Errors.error "Expect an introduction pattern naming one hypothesis." in + | IntroIdentifier id -> id in let eqdata = build_coq_eq_data () in let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in let sigma, eq = Evd.fresh_global env (Proofview.Goal.sigma gl) eqdata.eq in diff --git a/test-suite/success/intros.v b/test-suite/success/intros.v index bb9fc0c50d..9443d01e3b 100644 --- a/test-suite/success/intros.v +++ b/test-suite/success/intros.v @@ -28,3 +28,8 @@ Goal forall n p, n + p = 0. intros [|*]; intro p. Abort. +(* Check non-interference of "_" with name generation *) +Goal True -> True -> True. +intros _ ?. +exact H. +Qed. |
