diff options
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | doc/refman/RefMan-tac.tex | 32 | ||||
-rw-r--r-- | grammar/q_coqast.ml4 | 15 | ||||
-rw-r--r-- | interp/smartlocate.ml | 4 | ||||
-rw-r--r-- | interp/smartlocate.mli | 2 | ||||
-rw-r--r-- | intf/genredexpr.mli | 6 | ||||
-rw-r--r-- | parsing/g_tactic.ml4 | 18 | ||||
-rw-r--r-- | pretyping/miscops.ml | 25 | ||||
-rw-r--r-- | pretyping/miscops.mli | 6 | ||||
-rw-r--r-- | printing/ppconstr.ml | 10 | ||||
-rw-r--r-- | proofs/redexpr.ml | 66 | ||||
-rw-r--r-- | tactics/tacintern.ml | 23 | ||||
-rw-r--r-- | tactics/tacinterp.ml | 6 | ||||
-rw-r--r-- | tactics/tacsubst.ml | 16 | ||||
-rw-r--r-- | test-suite/success/simpl.v | 34 | ||||
-rw-r--r-- | theories/Numbers/Cyclic/Abstract/CyclicAxioms.v | 2 |
16 files changed, 176 insertions, 91 deletions
@@ -156,6 +156,8 @@ Tactics - "change ... in ..." and "simpl ... in ..." now consider nested occurrences (possible source of incompatibilities since this alters the numbering of occurrences). +- simpl, vm_compute and native_compute can be given a notation string to a + constant as argument. - The "change p with c" tactic semantics changed, now type-checking "c" at each matching occurrence "t" of the pattern "p", and converting "t" with "c". diff --git a/doc/refman/RefMan-tac.tex b/doc/refman/RefMan-tac.tex index 75ba90f03..5c87b12cc 100644 --- a/doc/refman/RefMan-tac.tex +++ b/doc/refman/RefMan-tac.tex @@ -3080,16 +3080,17 @@ The term \verb+forall n:nat, (plus (S n) (S n))+ is not reduced by {\tt hnf}. These tactics apply to any goal. They try to reduce a term to something still readable instead of fully normalizing it. They perform -a sort of strong normalisation with two key differences: +a sort of strong normalization with two key differences: \begin{itemize} -\item They unfold a constant if and only if it leads to an - $\iota$-reduction, i.e. reducing a match or unfold a fixpoint. -\item While reducing (co)fixpoints, the tactics use the name of the +\item They unfold a constant if and only if it leads to a + $\iota$-reduction, i.e. reducing a match or unfolding a fixpoint. +\item While reducing a constant unfolding to (co)fixpoints, + the tactics use the name of the constant the (co)fixpoint comes from instead of the (co)fixpoint definition in recursive calls. \end{itemize} -The \texttt{cbn} tactic claims to be a more principled, faster and more +The \texttt{cbn} tactic is claimed to be a more principled, faster and more predictable replacement for \texttt{simpl}. The \texttt{cbn} tactic accepts the same flags as \texttt{cbv} and @@ -3169,27 +3170,32 @@ reduced to \texttt{S t}. [\qualid$_1$\ldots\qualid$_k$] iota zeta} and {\tt cbn beta delta -[\qualid$_1$\ldots\qualid$_k$] iota zeta} (see \ref{vmcompute}). -\item {\tt simpl {\term}} +\item {\tt simpl {\pattern}} - This applies {\tt simpl} only to the occurrences of {\term} in the + This applies {\tt simpl} only to the subterms matching {\pattern} in the current goal. -\item {\tt simpl {\term} at \num$_1$ \dots\ \num$_i$} +\item {\tt simpl {\pattern} at \num$_1$ \dots\ \num$_i$} This applies {\tt simpl} only to the \num$_1$, \dots, \num$_i$ - occurrences of {\term} in the current goal. + occurrences of the subterms matching {\pattern} in the current goal. \ErrMsg {\tt Too few occurrences} -\item {\tt simpl {\ident}} +\item {\tt simpl {\qualid}}\\ + {\tt simpl {\qstring}} This applies {\tt simpl} only to the applicative subterms whose head - occurrence is {\ident}. + occurrence is the unfoldable constant {\qualid} (the constant can be + referred to by its notation using {\qstring} if such a notation + exists). -\item {\tt simpl {\ident} at \num$_1$ \dots\ \num$_i$} +\item {\tt simpl {\qualid} at \num$_1$ \dots\ \num$_i$}\\ + {\tt simpl {\qstring} at \num$_1$ \dots\ \num$_i$}\\ This applies {\tt simpl} only to the \num$_1$, \dots, \num$_i$ -applicative subterms whose head occurrence is {\ident}. + applicative subterms whose head occurrence is {\qualid} (or + {\qstring}). \end{Variants} diff --git a/grammar/q_coqast.ml4 b/grammar/q_coqast.ml4 index 02becc496..d6d13375e 100644 --- a/grammar/q_coqast.ml4 +++ b/grammar/q_coqast.ml4 @@ -46,6 +46,10 @@ let mlexpr_of_reference = function | Libnames.Ident (loc,id) -> let loc = of_coqloc loc in <:expr< Libnames.Ident $dloc$ $mlexpr_of_ident id$ >> +let mlexpr_of_union f g = function + | Util.Inl a -> <:expr< Util.Inl $f a$ >> + | Util.Inr b -> <:expr< Util.Inr $g b$ >> + let mlexpr_of_located f (loc,x) = let loc = of_coqloc loc in <:expr< ($dloc$, $f x$) >> @@ -184,10 +188,15 @@ let rec mlexpr_of_constr = function let mlexpr_of_occ_constr = mlexpr_of_occurrences mlexpr_of_constr +let mlexpr_of_occ_ref_or_constr = + mlexpr_of_occurrences + (mlexpr_of_union + (mlexpr_of_by_notation mlexpr_of_reference) mlexpr_of_constr) + let mlexpr_of_red_expr = function | Genredexpr.Red b -> <:expr< Genredexpr.Red $mlexpr_of_bool b$ >> | Genredexpr.Hnf -> <:expr< Genredexpr.Hnf >> - | Genredexpr.Simpl o -> <:expr< Genredexpr.Simpl $mlexpr_of_option mlexpr_of_occ_constr o$ >> + | Genredexpr.Simpl o -> <:expr< Genredexpr.Simpl $mlexpr_of_option mlexpr_of_occ_ref_or_constr o$ >> | Genredexpr.Cbv f -> <:expr< Genredexpr.Cbv $mlexpr_of_red_flags f$ >> | Genredexpr.Cbn f -> @@ -203,8 +212,8 @@ let mlexpr_of_red_expr = function | Genredexpr.Pattern l -> let f = mlexpr_of_list mlexpr_of_occ_constr in <:expr< Genredexpr.Pattern $f l$ >> - | Genredexpr.CbvVm o -> <:expr< Genredexpr.CbvVm $mlexpr_of_option mlexpr_of_occ_constr o$ >> - | Genredexpr.CbvNative o -> <:expr< Genredexpr.CbvNative $mlexpr_of_option mlexpr_of_occ_constr o$ >> + | Genredexpr.CbvVm o -> <:expr< Genredexpr.CbvVm $mlexpr_of_option mlexpr_of_occ_ref_or_constr o$ >> + | Genredexpr.CbvNative o -> <:expr< Genredexpr.CbvNative $mlexpr_of_option mlexpr_of_occ_ref_or_constr o$ >> | Genredexpr.ExtraRedExpr s -> <:expr< Genredexpr.ExtraRedExpr $mlexpr_of_string s$ >> diff --git a/interp/smartlocate.ml b/interp/smartlocate.ml index 7ad5561e3..422497ab3 100644 --- a/interp/smartlocate.ml +++ b/interp/smartlocate.ml @@ -75,3 +75,7 @@ let smart_global_inductive = function | ByNotation (loc,ntn,sc) -> destIndRef (Notation.interp_notation_as_global_reference loc isIndRef ntn sc) + +let loc_of_smart_reference = function + | AN r -> loc_of_reference r + | ByNotation (loc,_,_) -> loc diff --git a/interp/smartlocate.mli b/interp/smartlocate.mli index 9006e3687..f8840ca0e 100644 --- a/interp/smartlocate.mli +++ b/interp/smartlocate.mli @@ -37,3 +37,5 @@ val smart_global : ?head:bool -> reference or_by_notation -> global_reference (** The same for inductive types *) val smart_global_inductive : reference or_by_notation -> inductive +(** Return the loc of a smart reference *) +val loc_of_smart_reference : reference or_by_notation -> Loc.t diff --git a/intf/genredexpr.mli b/intf/genredexpr.mli index 1096ecb1f..a59278bb0 100644 --- a/intf/genredexpr.mli +++ b/intf/genredexpr.mli @@ -32,7 +32,7 @@ type 'a glob_red_flag = { type ('a,'b,'c) red_expr_gen = | Red of bool | Hnf - | Simpl of 'c Locus.with_occurrences option + | Simpl of ('b,'c) Util.union Locus.with_occurrences option | Cbv of 'b glob_red_flag | Cbn of 'b glob_red_flag | Lazy of 'b glob_red_flag @@ -40,8 +40,8 @@ type ('a,'b,'c) red_expr_gen = | Fold of 'a list | Pattern of 'a Locus.with_occurrences list | ExtraRedExpr of string - | CbvVm of 'c Locus.with_occurrences option - | CbvNative of 'c Locus.with_occurrences option + | CbvVm of ('b,'c) Util.union Locus.with_occurrences option + | CbvNative of ('b,'c) Util.union Locus.with_occurrences option type ('a,'b,'c) may_eval = | ConstrTerm of 'a diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4 index 3b01e988a..324efe53e 100644 --- a/parsing/g_tactic.ml4 +++ b/parsing/g_tactic.ml4 @@ -254,6 +254,12 @@ GEXTEND Gram pattern_occ: [ [ c = constr; nl = occs -> (nl,c) ] ] ; + ref_or_pattern_occ: + (* If a string, it is interpreted as a ref + (anyway a Coq string does not reduce) *) + [ [ c = smart_global; nl = occs -> nl,Inl c + | c = constr; nl = occs -> nl,Inr c ] ] + ; unfold_occ: [ [ c = smart_global; nl = occs -> (nl,c) ] ] ; @@ -336,13 +342,13 @@ GEXTEND Gram red_tactic: [ [ IDENT "red" -> Red false | IDENT "hnf" -> Hnf - | IDENT "simpl"; po = OPT pattern_occ -> Simpl po + | IDENT "simpl"; po = OPT ref_or_pattern_occ -> Simpl po | IDENT "cbv"; s = strategy_flag -> Cbv s | IDENT "cbn"; s = strategy_flag -> Cbn s | IDENT "lazy"; s = strategy_flag -> Lazy s | IDENT "compute"; delta = delta_flag -> Cbv (all_with delta) - | IDENT "vm_compute"; po = OPT pattern_occ -> CbvVm po - | IDENT "native_compute"; po = OPT pattern_occ -> CbvNative po + | IDENT "vm_compute"; po = OPT ref_or_pattern_occ -> CbvVm po + | IDENT "native_compute"; po = OPT ref_or_pattern_occ -> CbvNative po | IDENT "unfold"; ul = LIST1 unfold_occ SEP "," -> Unfold ul | IDENT "fold"; cl = LIST1 constr -> Fold cl | IDENT "pattern"; pl = LIST1 pattern_occ SEP"," -> Pattern pl ] ] @@ -351,13 +357,13 @@ GEXTEND Gram red_expr: [ [ IDENT "red" -> Red false | IDENT "hnf" -> Hnf - | IDENT "simpl"; po = OPT pattern_occ -> Simpl po + | IDENT "simpl"; po = OPT ref_or_pattern_occ -> Simpl po | IDENT "cbv"; s = strategy_flag -> Cbv s | IDENT "cbn"; s = strategy_flag -> Cbn s | IDENT "lazy"; s = strategy_flag -> Lazy s | IDENT "compute"; delta = delta_flag -> Cbv (all_with delta) - | IDENT "vm_compute"; po = OPT pattern_occ -> CbvVm po - | IDENT "native_compute"; po = OPT pattern_occ -> CbvNative po + | IDENT "vm_compute"; po = OPT ref_or_pattern_occ -> CbvVm po + | IDENT "native_compute"; po = OPT ref_or_pattern_occ -> CbvNative po | IDENT "unfold"; ul = LIST1 unfold_occ SEP "," -> Unfold ul | IDENT "fold"; cl = LIST1 constr -> Fold cl | IDENT "pattern"; pl = LIST1 pattern_occ SEP"," -> Pattern pl diff --git a/pretyping/miscops.ml b/pretyping/miscops.ml index 83e33f84e..3e5f7577b 100644 --- a/pretyping/miscops.ml +++ b/pretyping/miscops.ml @@ -6,7 +6,9 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) +open Util open Misctypes +open Genredexpr (** Mapping [cast_type] *) @@ -36,3 +38,26 @@ let intro_pattern_naming_eq nam1 nam2 = match nam1, nam2 with | IntroIdentifier id1, IntroIdentifier id2 -> Names.Id.equal id1 id2 | IntroFresh id1, IntroFresh id2 -> Names.Id.equal id1 id2 | _ -> false + +(** Mapping [red_expr_gen] *) + +let map_flags f flags = + { flags with rConst = List.map f flags.rConst } + +let map_occs f (occ,e) = (occ,f e) + +let map_union f g = function + | Inl a -> Inl (f a) + | Inr b -> Inr (g b) + +let map_red_expr_gen f g h = function + | Fold l -> Fold (List.map f l) + | Pattern occs_l -> Pattern (List.map (map_occs f) occs_l) + | Simpl occs_o -> Simpl (Option.map (map_occs (map_union g h)) occs_o) + | Unfold occs_l -> Unfold (List.map (map_occs g) occs_l) + | Cbv flags -> Cbv (map_flags g flags) + | Lazy flags -> Lazy (map_flags g flags) + | CbvVm occs_o -> CbvVm (Option.map (map_occs (map_union g h)) occs_o) + | CbvNative occs_o -> CbvNative (Option.map (map_occs (map_union g h)) occs_o) + | Cbn flags -> Cbn (map_flags g flags) + | ExtraRedExpr _ | Red _ | Hnf _ as x -> x diff --git a/pretyping/miscops.mli b/pretyping/miscops.mli index 6235533d7..eb9b4a780 100644 --- a/pretyping/miscops.mli +++ b/pretyping/miscops.mli @@ -7,6 +7,7 @@ (************************************************************************) open Misctypes +open Genredexpr (** Mapping [cast_type] *) @@ -21,3 +22,8 @@ val glob_sort_eq : glob_sort -> glob_sort -> bool val intro_pattern_naming_eq : intro_pattern_naming_expr -> intro_pattern_naming_expr -> bool + +(** Mapping [red_expr_gen] *) + +val map_red_expr_gen : ('a -> 'd) -> ('b -> 'e) -> ('c -> 'f) -> + ('a,'b,'c) red_expr_gen -> ('d,'e,'f) red_expr_gen diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml index f90ded281..fd4676530 100644 --- a/printing/ppconstr.ml +++ b/printing/ppconstr.ml @@ -753,10 +753,14 @@ end) = struct let pr_metaid id = str"?" ++ pr_id id + let pr_union pr1 pr2 = function + | Inl a -> pr1 a + | Inr b -> pr2 b + let pr_red_expr (pr_constr,pr_lconstr,pr_ref,pr_pattern) = function | Red false -> keyword "red" | Hnf -> keyword "hnf" - | Simpl o -> keyword "simpl" ++ pr_opt (pr_with_occurrences pr_pattern) o + | Simpl o -> keyword "simpl" ++ pr_opt (pr_with_occurrences (pr_union pr_ref pr_pattern)) o | Cbv f -> if f.rBeta && f.rIota && f.rZeta && f.rDelta && List.is_empty f.rConst then keyword "compute" @@ -779,9 +783,9 @@ end) = struct | ExtraRedExpr s -> str s | CbvVm o -> - keyword "vm_compute" ++ pr_opt (pr_with_occurrences pr_pattern) o + keyword "vm_compute" ++ pr_opt (pr_with_occurrences (pr_union pr_ref pr_pattern)) o | CbvNative o -> - keyword "native_compute" ++ pr_opt (pr_with_occurrences pr_pattern) o + keyword "native_compute" ++ pr_opt (pr_with_occurrences (pr_union pr_ref pr_pattern)) o let pr_may_eval test prc prlc pr2 pr3 = function | ConstrEval (r,c) -> diff --git a/proofs/redexpr.ml b/proofs/redexpr.ml index acdc52400..fb501c7a5 100644 --- a/proofs/redexpr.ml +++ b/proofs/redexpr.ml @@ -173,19 +173,31 @@ let out_arg = function let out_with_occurrences (occs,c) = (Locusops.occurrences_map (List.map out_arg) occs, c) +let e_red f env evm c = evm, f env evm c + +let head_style = false (* Turn to true to have a semantics where simpl + only reduce at the head when an evaluable reference is given, e.g. + 2+n would just reduce to S(1+n) instead of S(S(n)) *) + +let contextualize f g = function + | Some (occs,c) -> + let l = Locusops.occurrences_map (List.map out_arg) occs in + let b,c,h = match c with + | Inl r -> true, PRef (global_of_evaluable_reference r),f + | Inr c -> + let b = if head_style then false else (* compat *) is_reference c in + b,c,g in + e_red (contextually b (l,c) (fun _ -> h)) + | None -> e_red g + let reduction_of_red_expr env = let make_flag = make_flag env in - let e_red f env evm c = evm, f env evm c in let rec reduction_of_red_expr = function | Red internal -> if internal then (e_red try_red_product,DEFAULTcast) else (e_red red_product,DEFAULTcast) | Hnf -> (e_red hnf_constr,DEFAULTcast) - | Simpl (Some (_,c as lp)) -> - let f = contextually (is_reference c) (out_with_occurrences lp) - (fun _ -> simpl) - in (e_red f,DEFAULTcast) - | Simpl None -> (e_red simpl,DEFAULTcast) + | Simpl o -> (contextualize (if head_style then whd_simpl else simpl) simpl o,DEFAULTcast) | Cbv f -> (e_red (cbv_norm_flags (make_flag f)),DEFAULTcast) | Cbn f -> let f = strong (fun env evd x -> Stack.zip ~refold:true @@ -201,50 +213,16 @@ let reduction_of_red_expr env = (try reduction_of_red_expr (String.Map.find s !red_expr_tab) with Not_found -> error("unknown user-defined reduction \""^s^"\""))) - | CbvVm (Some lp) -> - let b = is_reference (snd lp) in - let lp = out_with_occurrences lp in - let vmfun _ env map c = - let tpe = Retyping.get_type_of env map c in - Vnorm.cbv_vm env c tpe - in - let redfun = contextually b lp vmfun in - (e_red redfun, VMcast) - | CbvVm None -> (e_red cbv_vm, VMcast) - | CbvNative (Some lp) -> - let b = is_reference (snd lp) in - let lp = out_with_occurrences lp in - let nativefun _ env map c = - let tpe = Retyping.get_type_of env map c in - let evars = Nativenorm.evars_of_evar_map map in - Nativenorm.native_norm env evars c tpe - in - let redfun = contextually b lp nativefun in - (e_red redfun, NATIVEcast) - | CbvNative None -> (e_red cbv_native, NATIVEcast) + | CbvVm o -> (contextualize cbv_vm cbv_vm o, VMcast) + | CbvNative o -> (contextualize cbv_native cbv_native o, VMcast) in reduction_of_red_expr -let subst_flags subs flags = - { flags with rConst = List.map subs flags.rConst } - -let subst_occs subs (occ,e) = (occ,subs e) - -let subst_gen_red_expr subs_a subs_b subs_c = function - | Fold l -> Fold (List.map subs_a l) - | Pattern occs_l -> Pattern (List.map (subst_occs subs_a) occs_l) - | Simpl occs_o -> Simpl (Option.map (subst_occs subs_c) occs_o) - | Unfold occs_l -> Unfold (List.map (subst_occs subs_b) occs_l) - | Cbv flags -> Cbv (subst_flags subs_b flags) - | Lazy flags -> Lazy (subst_flags subs_b flags) - | e -> e - -let subst_red_expr subs e = - subst_gen_red_expr +let subst_red_expr subs = + Miscops.map_red_expr_gen (Mod_subst.subst_mps subs) (Mod_subst.subst_evaluable_reference subs) (Patternops.subst_pattern subs) - e let inReduction : bool * string * red_expr -> obj = declare_object diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml index f3c7680b0..0a9182e0b 100644 --- a/tactics/tacintern.ml +++ b/tactics/tacintern.ml @@ -344,8 +344,21 @@ let intern_typed_pattern ist p = (* type it, so we remember the pattern as a glob_constr only *) (intern_constr_gen true false ist p,dummy_pat) -let intern_typed_pattern_with_occurrences ist (l,p) = - (l,intern_typed_pattern ist p) +let intern_typed_pattern_or_ref_with_occurrences ist (l,p) = + match p with + | Inl r -> l, + (try Inl (intern_evaluable ist r) + with e when Logic.catchable_exception e -> + (* Compatibility. In practice, this means that the code above + is useless. Still the idea of having either an evaluable + ref or a pattern seems interesting, with "head" reduction + in case of an evaluable ref, and "strong" reduction in the + subterm matched when a pattern) *) + let r = match r with + | AN r -> r + | _ -> Qualid (loc_of_smart_reference r,qualid_of_path (path_of_global (smart_global r))) in + Inr (intern_typed_pattern ist (CRef(r,None)))) + | Inr c -> l, Inr (intern_typed_pattern ist c) (* This seems fairly hacky, but it's the first way I've found to get proper globalization of [unfold]. --adamc *) @@ -370,9 +383,9 @@ let intern_red_expr ist = function | Cbn f -> Cbn (intern_flag ist f) | Lazy f -> Lazy (intern_flag ist f) | Pattern l -> Pattern (List.map (intern_constr_with_occurrences ist) l) - | Simpl o -> Simpl (Option.map (intern_typed_pattern_with_occurrences ist) o) - | CbvVm o -> CbvVm (Option.map (intern_typed_pattern_with_occurrences ist) o) - | CbvNative o -> CbvNative (Option.map (intern_typed_pattern_with_occurrences ist) o) + | Simpl o -> Simpl (Option.map (intern_typed_pattern_or_ref_with_occurrences ist) o) + | CbvVm o -> CbvVm (Option.map (intern_typed_pattern_or_ref_with_occurrences ist) o) + | CbvNative o -> CbvNative (Option.map (intern_typed_pattern_or_ref_with_occurrences ist) o) | (Red _ | Hnf | ExtraRedExpr _ as r ) -> r let intern_in_hyp_as ist lf (clear,id,ipat) = diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml index 54fbbbe27..63eb200de 100644 --- a/tactics/tacinterp.ml +++ b/tactics/tacinterp.ml @@ -680,8 +680,10 @@ let interp_constr_with_occurrences ist env sigma (occs,c) = let (sigma,c_interp) = interp_constr ist env sigma c in sigma , (interp_occurrences ist occs, c_interp) -let interp_closed_typed_pattern_with_occurrences ist env sigma (occs, c) = - let _, p = interp_typed_pattern ist env sigma c in +let interp_closed_typed_pattern_with_occurrences ist env sigma (occs, a) = + let p = match a with + | Inl b -> Inl (interp_evaluable ist env sigma b) + | Inr c -> Inr (snd (interp_typed_pattern ist env sigma c)) in interp_occurrences ist occs, p let interp_constr_with_occurrences_and_name_as_list = diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml index 2f47b9000..5a02a53f3 100644 --- a/tactics/tacsubst.ml +++ b/tactics/tacsubst.ml @@ -114,17 +114,11 @@ let subst_glob_constr_or_pattern subst (c,p) = let subst_pattern_with_occurrences subst (l,p) = (l,subst_glob_constr_or_pattern subst p) -let subst_redexp subst = function - | Unfold l -> Unfold (List.map (subst_unfold subst) l) - | Fold l -> Fold (List.map (subst_glob_constr subst) l) - | Cbv f -> Cbv (subst_flag subst f) - | Cbn f -> Cbn (subst_flag subst f) - | Lazy f -> Lazy (subst_flag subst f) - | Pattern l -> Pattern (List.map (subst_constr_with_occurrences subst) l) - | Simpl o -> Simpl (Option.map (subst_pattern_with_occurrences subst) o) - | CbvVm o -> CbvVm (Option.map (subst_pattern_with_occurrences subst) o) - | CbvNative o -> CbvNative (Option.map (subst_pattern_with_occurrences subst) o) - | (Red _ | Hnf | ExtraRedExpr _ as r) -> r +let subst_redexp subst = + Miscops.map_red_expr_gen + (subst_glob_constr subst) + (subst_evaluable subst) + (subst_glob_constr_or_pattern subst) let subst_raw_may_eval subst = function | ConstrEval (r,c) -> ConstrEval (subst_redexp subst r,subst_glob_constr subst c) diff --git a/test-suite/success/simpl.v b/test-suite/success/simpl.v index 271e6ef76..66a92ea41 100644 --- a/test-suite/success/simpl.v +++ b/test-suite/success/simpl.v @@ -45,3 +45,37 @@ Goal forall A B (a:A) l f (i:B), fold_right f i ((a :: l))=i. simpl. admit. Qed. (* Qed will fail if simplification is incorrect (de Bruijn!) *) + +(* Check that maximally inserted arguments do not break interpretation + of references in simpl, vm_compute etc. *) + +Arguments fst {A} {B} p. + +Goal fst (0,0) = 0. +simpl fst. +Fail set (fst _). +Abort. + +Goal fst (0,0) = 0. +vm_compute fst. +Fail set (fst _). +Abort. + +Goal let f x := x + 0 in f 0 = 0. +intro. +vm_compute f. +Fail set (f _). +Abort. + +(* This is a compatibility test with a non evaluable reference, maybe + not to be kept for long *) +Goal 0+0=0. +simpl @eq. +Abort. + +(* Check reference by notation in simpl *) + +Goal 0+0 = 0. +simpl "+". +Fail set (_ + _). +Abort. diff --git a/theories/Numbers/Cyclic/Abstract/CyclicAxioms.v b/theories/Numbers/Cyclic/Abstract/CyclicAxioms.v index 17c69d226..3586cb7f2 100644 --- a/theories/Numbers/Cyclic/Abstract/CyclicAxioms.v +++ b/theories/Numbers/Cyclic/Abstract/CyclicAxioms.v @@ -290,7 +290,7 @@ Module ZnZ. intros p Hp. generalize (spec_of_pos p). case (of_pos p); intros n w1; simpl. - case n; simpl Npos; auto with zarith. + case n; auto with zarith. intros p1 Hp1; contradict Hp; apply Z.le_ngt. replace (base digits) with (1 * base digits + 0) by ring. rewrite Hp1. |