diff options
Diffstat (limited to 'tactics/rewrite.ml4')
| -rw-r--r-- | tactics/rewrite.ml4 | 143 |
1 files changed, 101 insertions, 42 deletions
diff --git a/tactics/rewrite.ml4 b/tactics/rewrite.ml4 index df79bf3eef..9ad4196977 100644 --- a/tactics/rewrite.ml4 +++ b/tactics/rewrite.ml4 @@ -224,6 +224,7 @@ type hypinfo = { c2 : constr; c : (Tacinterp.interp_sign * Genarg.glob_constr_and_expr with_bindings) option; abs : (constr * types) option; + flags : Unification.unify_flags; } let goalevars evars = fst evars @@ -251,7 +252,7 @@ let rec decompose_app_rel env evd t = (* let nc, c', cl = push_rel_context_to_named_context env c in *) (* let env' = reset_with_named_context nc env in *) -let decompose_applied_relation env sigma orig (c,l) left2right = +let decompose_applied_relation env sigma flags orig (c,l) left2right = let c' = c in let ctype = Typing.type_of env sigma c' in let find_rel ty = @@ -265,7 +266,8 @@ let decompose_applied_relation env sigma orig (c,l) left2right = else Some { cl=eqclause; prf=(Clenv.clenv_value eqclause); car=ty1; rel = equiv; - l2r=left2right; c1=c1; c2=c2; c=orig; abs=None } + l2r=left2right; c1=c1; c2=c2; c=orig; abs=None; + flags = flags } in match find_rel ctype with | Some c -> c @@ -276,30 +278,52 @@ let decompose_applied_relation env sigma orig (c,l) left2right = | None -> error "The term does not end with an applied homogeneous relation." open Tacinterp -let decompose_applied_relation_expr env sigma (is, (c,l)) left2right = +let decompose_applied_relation_expr env sigma flags (is, (c,l)) left2right = let sigma, cbl = Tacinterp.interp_open_constr_with_bindings is env sigma (c,l) in - decompose_applied_relation env sigma (Some (is, (c,l))) cbl left2right - -let rewrite_unif_flags = { - Unification.modulo_conv_on_closed_terms = None; - Unification.use_metas_eagerly = true; - Unification.modulo_delta = empty_transparent_state; - Unification.resolve_evars = true; - Unification.use_evars_pattern_unification = true; - Unification.modulo_eta = true -} + decompose_applied_relation env sigma flags (Some (is, (c,l))) cbl left2right + +let rewrite_db = "rewrite" let conv_transparent_state = (Idpred.empty, Cpred.full) -let rewrite2_unif_flags = { - Unification.modulo_conv_on_closed_terms = Some conv_transparent_state; +let _ = + Auto.add_auto_init + (fun () -> + Auto.create_hint_db false rewrite_db conv_transparent_state true) + +let rewrite_transparent_state () = + Auto.Hint_db.transparent_state (Auto.searchtable_map rewrite_db) + +let rewrite_unif_flags = { + Unification.modulo_conv_on_closed_terms = None; Unification.use_metas_eagerly = 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.modulo_eta = true } +let rewrite2_unif_flags = + { Unification.modulo_conv_on_closed_terms = Some conv_transparent_state; + Unification.use_metas_eagerly = 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.modulo_eta = true + } + +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.modulo_delta = ts; + Unification.modulo_delta_types = ts; + Unification.resolve_evars = true; + Unification.use_evars_pattern_unification = true; + Unification.modulo_eta = true } + let convertible env evd x y = Reductionops.is_conv env evd x y @@ -307,11 +331,11 @@ let allowK = true let refresh_hypinfo env sigma hypinfo = if hypinfo.abs = None then - let {l2r=l2r; c=c;cl=cl} = hypinfo in + let {l2r=l2r; c=c;cl=cl;flags=flags} = hypinfo in match c with | Some c -> (* Refresh the clausenv to not get the same meta twice in the goal. *) - decompose_applied_relation_expr env sigma c l2r; + decompose_applied_relation_expr env sigma flags c l2r; | _ -> hypinfo else hypinfo @@ -327,10 +351,7 @@ let unify_eqn env sigma hypinfo t = env', prf, c1, c2, car, rel | None -> let env' = - try clenv_unify allowK ~flags:rewrite_unif_flags CONV left t cl - with Pretype_errors.PretypeError _ -> - (* For Ring essentially, only when doing setoid_rewrite *) - clenv_unify allowK ~flags:rewrite2_unif_flags CONV left t cl + clenv_unify allowK ~flags:!hypinfo.flags CONV left t cl in let env' = Clenvtac.clenv_pose_dependent_evars true env' in (* let env' = Clenv.clenv_pose_metas_as_evars env' (Evd.undefined_metas env'.evd) in *) @@ -610,9 +631,9 @@ let apply_rule hypinfo loccs : strategy = end | _ -> None -let apply_lemma (evm,c) left2right loccs : strategy = +let apply_lemma flags (evm,c) left2right loccs : strategy = fun env avoid t ty cstr evars -> - let hypinfo = ref (decompose_applied_relation env (goalevars evars) None c left2right) in + let hypinfo = ref (decompose_applied_relation env (goalevars evars) flags None c left2right) in apply_rule hypinfo loccs env avoid t ty cstr evars let make_leibniz_proof c ty r = @@ -852,7 +873,7 @@ let subterm all flags (s : strategy) : strategy = rew_from = t; rew_to = unfold_match env (goalevars evars) cst prf.rew_to }) | x' -> x) - | _ -> if all then Some None else None + | _ -> None in aux let all_subterms = subterm true default_flags @@ -950,22 +971,24 @@ module Strategies = let outermost (s : strategy) : strategy = fix (fun out -> choice s (one_subterm out)) - let lemmas cs : strategy = + let lemmas flags cs : strategy = List.fold_left (fun tac (l,l2r) -> - choice tac (apply_lemma l l2r (false,[]))) + choice tac (apply_lemma flags l l2r (false,[]))) fail cs let inj_open c = (Evd.empty,c) let old_hints (db : string) : strategy = let rules = Autorewrite.find_rewrites db in - lemmas (List.map (fun hint -> (inj_open (hint.Autorewrite.rew_lemma, NoBindings), hint.Autorewrite.rew_l2r)) rules) + lemmas rewrite_unif_flags + (List.map (fun hint -> (inj_open (hint.Autorewrite.rew_lemma, NoBindings), hint.Autorewrite.rew_l2r)) rules) let hints (db : string) : strategy = fun env avoid t ty cstr evars -> let rules = Autorewrite.find_matches db t in - lemmas (List.map (fun hint -> (inj_open (hint.Autorewrite.rew_lemma, NoBindings), hint.Autorewrite.rew_l2r)) rules) - env avoid t ty cstr evars + let lemma hint = (inj_open (hint.Autorewrite.rew_lemma, NoBindings), hint.Autorewrite.rew_l2r) in + let lems = List.map lemma rules in + lemmas rewrite_unif_flags lems env avoid t ty cstr evars let reduce (r : Redexpr.red_expr) : strategy = let rfn, ckind = Redexpr.reduction_of_red_expr r in @@ -1009,10 +1032,10 @@ let get_hypinfo_ids {c = opt} = | None -> [] | Some (is, gc) -> List.map fst is.lfun @ is.avoid_ids -let rewrite_with c left2right loccs : strategy = +let rewrite_with flags c left2right loccs : strategy = fun env avoid t ty cstr evars -> let gevars = goalevars evars in - let hypinfo = ref (decompose_applied_relation_expr env gevars c left2right) in + let hypinfo = ref (decompose_applied_relation_expr env gevars flags c left2right) in let avoid = get_hypinfo_ids !hypinfo @ avoid in rewrite_strat default_flags loccs hypinfo env avoid t ty cstr (gevars, cstrevars evars) @@ -1238,7 +1261,7 @@ let cl_rewrite_clause_new_strat ?abs strat clause = let cl_rewrite_clause_newtac' l left2right occs clause = Proof_global.run_tactic (Proofview.tclFOCUS 1 1 - (cl_rewrite_clause_new_strat (rewrite_with l left2right occs) clause)) + (cl_rewrite_clause_new_strat (rewrite_with rewrite_unif_flags l left2right occs) clause)) let cl_rewrite_clause_strat strat clause gl = init_setoid (); @@ -1249,7 +1272,7 @@ let cl_rewrite_clause_strat strat clause gl = tclFAIL 0 (str"setoid rewrite failed: strategy failed") gl let cl_rewrite_clause l left2right occs clause gl = - cl_rewrite_clause_strat (rewrite_with l left2right occs) clause gl + cl_rewrite_clause_strat (rewrite_with (general_rewrite_unif_flags ()) l left2right occs) clause gl open Pp open Pcoq @@ -1269,7 +1292,8 @@ let occurrences_of = function let apply_constr_expr c l2r occs = fun env avoid t ty cstr evars -> let evd, c = Constrintern.interp_open_constr (goalevars evars) env c in - apply_lemma (evd, (c, NoBindings)) l2r occs env avoid t ty cstr (evd, cstrevars evars) + apply_lemma (general_rewrite_unif_flags ()) (evd, (c, NoBindings)) + l2r occs env avoid t ty cstr (evd, cstrevars evars) let interp_constr_list env sigma = List.map (fun c -> @@ -1348,7 +1372,7 @@ ARGUMENT EXTEND rewstrategy TYPED AS strategy | [ "old_hints" preident(h) ] -> [ Strategies.old_hints h ] | [ "hints" preident(h) ] -> [ Strategies.hints h ] | [ "terms" constr_list(h) ] -> [ fun env avoid t ty cstr evars -> - Strategies.lemmas (interp_constr_list env (goalevars evars) h) env avoid t ty cstr evars ] + Strategies.lemmas rewrite_unif_flags (interp_constr_list env (goalevars evars) h) env avoid t ty cstr evars ] | [ "eval" red_expr(r) ] -> [ fun env avoid t ty cstr evars -> Strategies.reduce (Tacinterp.interp_redexp env (goalevars evars) r) env avoid t ty cstr evars ] | [ "fold" constr(c) ] -> [ Strategies.fold c ] @@ -1414,7 +1438,7 @@ let declare_an_instance n s args = let declare_instance a aeq n s = declare_an_instance n s [a;aeq] let anew_instance global binders instance fields = - new_instance binders instance (CRecord (dummy_loc,None,fields)) + new_instance binders instance (Some (CRecord (dummy_loc,None,fields))) ~global:(not (Vernacexpr.use_section_locality ())) ~generalize:false None let declare_instance_refl global binders a aeq n lemma = @@ -1686,7 +1710,7 @@ let add_morphism glob binders m s n = [cHole; s; m])) in let tac = Tacinterp.interp <:tactic<add_morphism_tactic>> in - ignore(new_instance ~global:glob binders instance (CRecord (dummy_loc,None,[])) + ignore(new_instance ~global:glob binders instance (Some (CRecord (dummy_loc,None,[]))) ~generalize:false ~tac ~hook:(declare_projection n instance_id) None) VERNAC COMMAND EXTEND AddSetoid1 @@ -1728,7 +1752,7 @@ let check_evar_map_of_evars_defs evd = check_freemetas_is_empty rebus2 freemetas2 ) metas -let unification_rewrite l2r c1 c2 cl car rel but gl = +let unification_rewrite flags l2r c1 c2 cl car rel but gl = let env = pf_env gl in let (evd',c') = try @@ -1740,7 +1764,7 @@ let unification_rewrite l2r c1 c2 cl car rel but gl = Pretype_errors.PretypeError _ -> (* ~flags:(true,true) to make Ring work (since it really exploits conversion) *) - Unification.w_unify_to_subterm ~flags:rewrite2_unif_flags + Unification.w_unify_to_subterm ~flags:flags env ((if l2r then c1 else c2),but) cl.evd in let evd' = Typeclasses.resolve_typeclasses ~fail:false env evd' in @@ -1753,15 +1777,18 @@ let unification_rewrite l2r c1 c2 cl car rel but gl = check_evar_map_of_evars_defs cl'.evd; let prf = nf (Clenv.clenv_value cl') and prfty = nf (Clenv.clenv_type cl') in let cl' = { cl' with templval = mk_freelisted prf ; templtyp = mk_freelisted prfty } in - {cl=cl'; prf=(mkRel 1); car=car; rel=rel; l2r=l2r; c1=c1; c2=c2; c=None; abs=Some (prf, prfty)} + {cl=cl'; prf=(mkRel 1); car=car; rel=rel; l2r=l2r; c1=c1; c2=c2; c=None; abs=Some (prf, prfty); + flags = flags} let get_hyp gl evars (c,l) clause l2r = - let hi = decompose_applied_relation (pf_env gl) evars None (c,l) l2r in + let flags = rewrite2_unif_flags in + let hi = decompose_applied_relation (pf_env gl) evars flags None (c,l) l2r in let but = match clause with | Some id -> pf_get_hyp_typ gl id | None -> Evarutil.nf_evar evars (pf_concl gl) in - unification_rewrite hi.l2r hi.c1 hi.c2 hi.cl hi.car hi.rel but gl + { unification_rewrite flags hi.l2r hi.c1 hi.c2 hi.cl hi.car hi.rel but gl with + flags = rewrite_unif_flags } let general_rewrite_flags = { under_lambdas = false; on_morphisms = true } @@ -1912,3 +1939,35 @@ TACTIC EXTEND fold_matches let c' = fold_matches (pf_env gl) (project gl) c in change (Some (snd (pattern_of_constr (project gl) c))) c' onConcl gl ] END + +TACTIC EXTEND myapply +| [ "myapply" global(id) constr_list(l) ] -> [ + fun gl -> + let gr = id in + let _, impls = List.hd (Impargs.implicits_of_global gr) in + let ty = Global.type_of_global gr in + let env = pf_env gl in + let evars = ref (project gl) in + let app = + let rec aux ty impls args args' = + match impls, kind_of_term ty with + | Some (_, _, (_, _)) :: impls, Prod (n, t, t') -> + let arg = Evarutil.e_new_evar evars env t in + aux (subst1 arg t') impls args (arg :: args') + | None :: impls, Prod (n, t, t') -> + (match args with + | [] -> + if dependent (mkRel 1) t' then + let arg = Evarutil.e_new_evar evars env t in + aux (subst1 arg t') impls args (arg :: args') + else + let arg = Evarutil.mk_new_meta () in + evars := meta_declare (destMeta arg) t !evars; + aux (subst1 arg t') impls args (arg :: args') + | arg :: args -> + aux (subst1 arg t') impls args (arg :: args')) + | _, _ -> mkApp (constr_of_global gr, Array.of_list (List.rev args')) + in aux ty impls l [] + in + tclTHEN (Refiner.tclEVARS !evars) (apply app) gl ] +END |
