diff options
author | msozeau <msozeau@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2011-02-10 13:13:45 +0000 |
---|---|---|
committer | msozeau <msozeau@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2011-02-10 13:13:45 +0000 |
commit | c24849ef42adda2c5792f02a2c04f75505a7002a (patch) | |
tree | ca711824b9fa9277fc90a0484b758f382a2e5968 /tactics/rewrite.ml4 | |
parent | e095b5756e2a10d037deb9e91f45747bb233a37a (diff) |
- proper printing of setoid_rewrite tactic applications
- keep a list of names to avoid when going under lambdas so as not to
clash with bound ltac variables (fixes Random contrib).
- remove unused argument of strategies.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@13819 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'tactics/rewrite.ml4')
-rw-r--r-- | tactics/rewrite.ml4 | 158 |
1 files changed, 88 insertions, 70 deletions
diff --git a/tactics/rewrite.ml4 b/tactics/rewrite.ml4 index 4bc580b9c..437fb4e32 100644 --- a/tactics/rewrite.ml4 +++ b/tactics/rewrite.ml4 @@ -225,6 +225,9 @@ type hypinfo = { abs : (constr * types) option; } +let goalevars evars = fst evars +let cstrevars evars = snd evars + let evd_convertible env evd x y = try ignore(Evarconv.the_conv_x env x y evd); true with _ -> false @@ -450,7 +453,7 @@ type rewrite_result_info = { type rewrite_result = rewrite_result_info option -type strategy = Environ.env -> evar_map -> constr -> types -> +type strategy = Environ.env -> identifier list -> constr -> types -> constr option -> evars -> rewrite_result option let get_rew_prf r = match r.rew_prf with @@ -459,7 +462,7 @@ let get_rew_prf r = match r.rew_prf with mkCast (mkApp (Coqlib.build_coq_eq_refl (), [| r.rew_car; r.rew_from |]), c, mkApp (Coqlib.build_coq_eq (), [| r.rew_car; r.rew_from; r.rew_to |])) -let resolve_subrelation env sigma car rel prf rel' res = +let resolve_subrelation env avoid car rel prf rel' res = if eq_constr rel rel' then res else (* try let evd' = Evarconv.the_conv_x env rel rel' res.rew_evars in *) @@ -472,14 +475,14 @@ let resolve_subrelation env sigma car rel prf rel' res = rew_prf = RewPrf (rel', appsub); rew_evars = evars } -let resolve_morphism env sigma oldt m ?(fnewt=fun x -> x) args args' cstr evars = +let resolve_morphism env avoid oldt m ?(fnewt=fun x -> x) args args' cstr evars = let evars, morph_instance, proj, sigargs, m', args, args' = let first = try (array_find args' (fun i b -> b <> None)) with Not_found -> raise (Invalid_argument "resolve_morphism") in let morphargs, morphobjs = array_chop first args in let morphargs', morphobjs' = array_chop first args' in let appm = mkApp(m, morphargs) in - let appmtype = Typing.type_of env sigma appm in + let appmtype = Typing.type_of env (goalevars evars) appm in let cstrs = List.map (Option.map (fun r -> r.rew_car, get_rew_rel r.rew_prf)) (Array.to_list morphobjs') in (* Desired signature *) let evars, appmtype', signature, sigargs = @@ -520,22 +523,19 @@ let resolve_morphism env sigma oldt m ?(fnewt=fun x -> x) args args' cstr evars [ a, Some r ] -> evars, proof, a, r, oldt, fnewt newt | _ -> assert(false) -let apply_constraint env sigma car rel prf cstr res = +let apply_constraint env avoid car rel prf cstr res = match cstr with | None -> res - | Some r -> resolve_subrelation env sigma car rel prf r res + | Some r -> resolve_subrelation env avoid car rel prf r res let eq_env x y = x == y -let goalevars evars = fst evars -let cstrevars evars = snd evars - let apply_rule hypinfo loccs : strategy = let (nowhere_except_in,occs) = loccs in let is_occ occ = if nowhere_except_in then List.mem occ occs else not (List.mem occ occs) in let occ = ref 0 in - fun env sigma t ty cstr evars -> + fun env avoid t ty cstr evars -> if not (eq_env !hypinfo.cl.env env) then hypinfo := refresh_hypinfo env (goalevars evars) !hypinfo; let unif = unify_eqn env (goalevars evars) hypinfo t in if unif <> None then incr occ; @@ -547,14 +547,14 @@ let apply_rule hypinfo loccs : strategy = let res = { rew_car = ty; rew_from = c1; rew_to = c2; rew_prf = RewPrf (rel, prf); rew_evars = env'.evd, cstrevars evars } - in Some (Some (apply_constraint env sigma car rel prf cstr res)) + in Some (Some (apply_constraint env avoid car rel prf cstr res)) end | _ -> None let apply_lemma (evm,c) left2right loccs : strategy = - fun env sigma t ty cstr evars -> + fun env avoid t ty cstr evars -> let hypinfo = ref (decompose_applied_relation env (goalevars evars) None c left2right) in - apply_rule hypinfo loccs env sigma t ty cstr evars + apply_rule hypinfo loccs env avoid t ty cstr evars let make_leibniz_proof c ty r = let prf = @@ -628,7 +628,7 @@ let unfold_match env sigma sk app = | _ -> app let subterm all flags (s : strategy) : strategy = - let rec aux env sigma t ty cstr evars = + let rec aux env avoid t ty cstr evars = let cstr' = Option.map (fun c -> (ty, Some c)) cstr in match kind_of_term t with | App (m, args) -> @@ -638,7 +638,7 @@ let subterm all flags (s : strategy) : strategy = (fun (acc, evars, progress) arg -> if progress <> None && not all then (None :: acc, evars, progress) else - let res = s env sigma arg (Typing.type_of env sigma arg) None evars in + let res = s env avoid arg (Typing.type_of env (goalevars evars) arg) None evars in match res with | Some None -> (None :: acc, evars, if progress = None then Some false else progress) | Some (Some r) -> (Some r :: acc, r.rew_evars, Some true) @@ -650,7 +650,7 @@ let subterm all flags (s : strategy) : strategy = | Some false -> Some None | Some true -> let args' = Array.of_list (List.rev args') in - let evars', prf, car, rel, c1, c2 = resolve_morphism env sigma t m args args' cstr' evars' in + let evars', prf, car, rel, c1, c2 = resolve_morphism env avoid t m args args' cstr' evars' in let res = { rew_car = ty; rew_from = c1; rew_to = c2; rew_prf = RewPrf (rel, prf); rew_evars = evars' } @@ -659,14 +659,14 @@ let subterm all flags (s : strategy) : strategy = in if flags.on_morphisms then let evarsref = ref (snd evars) in - let mty = Typing.type_of env sigma m in + let mty = Typing.type_of env (goalevars evars) m in let cstr', m, mty, argsl, args = let argsl = Array.to_list args in - match lift_cstr env sigma evarsref argsl m mty None with + match lift_cstr env (goalevars evars) evarsref argsl m mty None with | Some (cstr', m, mty, args) -> Some cstr', m, mty, args, Array.of_list args | None -> None, m, mty, argsl, args in - let m' = s env sigma m mty cstr' (fst evars, !evarsref) in + let m' = s env avoid m mty cstr' (fst evars, !evarsref) in match m' with | None -> rewrite_args None (* Standard path, try rewrite on arguments *) | Some None -> rewrite_args (Some false) @@ -686,14 +686,14 @@ let subterm all flags (s : strategy) : strategy = in match prf with | RewPrf (rel, prf) -> - Some (Some (apply_constraint env sigma res.rew_car rel prf cstr res)) + Some (Some (apply_constraint env avoid res.rew_car rel prf cstr res)) | _ -> Some (Some res) else rewrite_args None | Prod (n, x, b) when noccurn 1 b -> let b = subst1 mkProp b in - let tx = Typing.type_of env sigma x and tb = Typing.type_of env sigma b in - let res = aux env sigma (mkApp (arrow_morphism tx tb, [| x; b |])) ty cstr evars in + let tx = Typing.type_of env (goalevars evars) x and tb = Typing.type_of env (goalevars evars) b in + let res = aux env avoid (mkApp (arrow_morphism tx tb, [| x; b |])) ty cstr evars in (match res with | Some (Some r) -> Some (Some { r with rew_to = unfold_impl r.rew_to }) | _ -> res) @@ -714,20 +714,21 @@ let subterm all flags (s : strategy) : strategy = | Prod (n, dom, codom) when eq_constr ty mkProp -> let lam = mkLambda (n, dom, codom) in - let res = aux env sigma (mkApp (Lazy.force coq_all, [| dom; lam |])) ty cstr evars in + let res = aux env avoid (mkApp (Lazy.force coq_all, [| dom; lam |])) ty cstr evars in (match res with | Some (Some r) -> Some (Some { r with rew_to = unfold_all r.rew_to }) | _ -> res) | Lambda (n, t, b) when flags.under_lambdas -> - let env' = Environ.push_rel (n, None, t) env in - let b' = s env' sigma b (Typing.type_of env' sigma b) (unlift_cstr env sigma cstr) evars in + let n' = name_app (fun id -> Tactics.fresh_id_in_env avoid id env) n in + let env' = Environ.push_rel (n', None, t) env in + let b' = s env' avoid b (Typing.type_of env' (goalevars evars) b) (unlift_cstr env (goalevars evars) cstr) evars in (match b' with | Some (Some r) -> let prf = match r.rew_prf with | RewPrf (rel, prf) -> - let rel = pointwise_or_dep_relation n t r.rew_car rel in - let prf = mkLambda (n, t, prf) in + let rel = pointwise_or_dep_relation n' t r.rew_car rel in + let prf = mkLambda (n', t, prf) in RewPrf (rel, prf) | x -> x in @@ -739,9 +740,9 @@ let subterm all flags (s : strategy) : strategy = | _ -> b') | Case (ci, p, c, brs) -> - let cty = Typing.type_of env sigma c in + let cty = Typing.type_of env (goalevars evars) c in let cstr' = Some (mkApp (Lazy.force coq_eq, [| cty |])) in - let c' = s env sigma c cty cstr' evars in + let c' = s env avoid c cty cstr' evars in (match c' with | Some (Some r) -> Some (Some (make_leibniz_proof (mkCase (ci, lift 1 p, mkRel 1, Array.map (lift 1) brs)) ty r)) @@ -751,7 +752,7 @@ let subterm all flags (s : strategy) : strategy = let found, brs' = Array.fold_left (fun (found, acc) br -> if found <> None then (found, fun x -> lift 1 br :: acc x) else - match s env sigma br ty cstr evars with + match s env avoid br ty cstr evars with | Some (Some r) -> (Some r, fun x -> mkRel 1 :: acc x) | _ -> (None, fun x -> lift 1 br :: acc x)) (None, fun x -> []) brs @@ -762,12 +763,12 @@ let subterm all flags (s : strategy) : strategy = Some (Some (make_leibniz_proof ctxc ty r)) | None -> x else - match try Some (fold_match env sigma t) with Not_found -> None with + match try Some (fold_match env (goalevars evars) t) with Not_found -> None with | None -> x | Some (cst, _, t') -> - match aux env sigma t' ty cstr evars with + match aux env avoid t' ty cstr evars with | Some (Some prf) -> Some (Some { prf with - rew_from = t; rew_to = unfold_match env sigma cst prf.rew_to }) + rew_from = t; rew_to = unfold_match env (goalevars evars) cst prf.rew_to }) | x' -> x) | _ -> if all then Some None else None @@ -779,8 +780,8 @@ let one_subterm = subterm false default_flags (** Requires transitivity of the rewrite step, if not a reduction. Not tail-recursive. *) -let transitivity env sigma (res : rewrite_result_info) (next : strategy) : rewrite_result option = - match next env sigma res.rew_to res.rew_car (get_rew_rel res.rew_prf) res.rew_evars with +let transitivity env avoid (res : rewrite_result_info) (next : strategy) : rewrite_result option = + match next env avoid res.rew_to res.rew_car (get_rew_rel res.rew_prf) res.rew_evars with | None -> None | Some None -> Some (Some res) | Some (Some res') -> @@ -807,13 +808,13 @@ module Strategies = struct let fail : strategy = - fun env sigma t ty cstr evars -> None + fun env avoid t ty cstr evars -> None let id : strategy = - fun env sigma t ty cstr evars -> Some None + fun env avoid t ty cstr evars -> Some None let refl : strategy = - fun env sigma t ty cstr evars -> + fun env avoid t ty cstr evars -> let evars, rel = match cstr with | None -> new_cstr_evar evars env (mk_relation ty) | Some r -> evars, r @@ -826,23 +827,23 @@ module Strategies = rew_prf = RewPrf (rel, proof); rew_evars = evars }) let progress (s : strategy) : strategy = - fun env sigma t ty cstr evars -> - match s env sigma t ty cstr evars with + fun env avoid t ty cstr evars -> + match s env avoid t ty cstr evars with | None -> None | Some None -> None | r -> r let seq fst snd : strategy = - fun env sigma t ty cstr evars -> - match fst env sigma t ty cstr evars with + fun env avoid t ty cstr evars -> + match fst env avoid t ty cstr evars with | None -> None - | Some None -> snd env sigma t ty cstr evars - | Some (Some res) -> transitivity env sigma res snd + | Some None -> snd env avoid t ty cstr evars + | Some (Some res) -> transitivity env avoid res snd let choice fst snd : strategy = - fun env sigma t ty cstr evars -> - match fst env sigma t ty cstr evars with - | None -> snd env sigma t ty cstr evars + fun env avoid t ty cstr evars -> + match fst env avoid t ty cstr evars with + | None -> snd env avoid t ty cstr evars | res -> res let try_ str : strategy = choice str id @@ -880,15 +881,15 @@ module Strategies = lemmas (List.map (fun hint -> (inj_open (hint.Autorewrite.rew_lemma, NoBindings), hint.Autorewrite.rew_l2r)) rules) let hints (db : string) : strategy = - fun env sigma t ty cstr evars -> + 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 sigma t ty cstr evars + env avoid t ty cstr evars let reduce (r : Redexpr.red_expr) : strategy = let rfn, ckind = Redexpr.reduction_of_red_expr r in - fun env sigma t ty cstr evars -> - let t' = rfn env sigma t in + fun env avoid t ty cstr evars -> + let t' = rfn env (goalevars evars) t in if eq_constr t' t then Some None else @@ -906,15 +907,21 @@ let rewrite_strat flags occs hyp = Strategies.choice app (subterm true flags (fun env -> aux () env)) in aux () +let get_hypinfo_ids {c = opt} = + match opt with + | None -> [] + | Some (is, gc) -> List.map fst is.lfun @ is.avoid_ids + let rewrite_with c left2right loccs : strategy = - fun env sigma t ty cstr evars -> + fun env avoid t ty cstr evars -> let gevars = goalevars evars in let hypinfo = ref (decompose_applied_relation_expr env gevars c left2right) in - rewrite_strat default_flags loccs hypinfo env sigma t ty cstr (gevars, cstrevars evars) + let avoid = get_hypinfo_ids !hypinfo @ avoid in + rewrite_strat default_flags loccs hypinfo env avoid t ty cstr (gevars, cstrevars evars) -let apply_strategy (s : strategy) env sigma concl cstr evars = +let apply_strategy (s : strategy) env avoid concl cstr evars = let res = - s env sigma concl (Typing.type_of env sigma concl) + s env avoid concl (Typing.type_of env (goalevars evars) concl) (Option.map snd cstr) evars in match res with @@ -939,7 +946,7 @@ exception RewriteFailure type result = (evar_map * constr option * types) option option -let cl_rewrite_clause_aux ?(abs=None) strat env sigma concl is_hyp : result = +let cl_rewrite_clause_aux ?(abs=None) strat env avoid sigma concl is_hyp : result = let cstr = let sort = mkProp in let impl = Lazy.force impl in @@ -948,7 +955,7 @@ let cl_rewrite_clause_aux ?(abs=None) strat env sigma concl is_hyp : result = | Some _ -> (sort, impl) in let evars = (create_evar_defs sigma, Evd.empty) in - let eq = apply_strategy strat env sigma concl (Some cstr) evars in + let eq = apply_strategy strat env avoid concl (Some cstr) evars in match eq with | Some (Some (p, evars, car, oldt, newt)) -> let evars' = solve_constraints env evars in @@ -1033,7 +1040,7 @@ let cl_rewrite_clause_tac ?abs strat meta clause gl = | Some id -> pf_get_hyp_typ gl id, Some id | None -> pf_concl gl, None in - let res = cl_rewrite_clause_aux ?abs strat (pf_env gl) (project gl) concl is_hyp in + let res = cl_rewrite_clause_aux ?abs strat (pf_env gl) [] (project gl) concl is_hyp in treat res with | Loc.Exc_located (_, TypeClassError (env, (UnsatisfiableConstraints _ as e))) @@ -1121,7 +1128,7 @@ let cl_rewrite_clause_newtac ?abs strat clause = | None -> concl, None in let res = - try cl_rewrite_clause_aux ?abs strat env sigma ty is_hyp + try cl_rewrite_clause_aux ?abs strat env [] sigma ty is_hyp with | Loc.Exc_located (_, TypeClassError (env, (UnsatisfiableConstraints _ as e))) | TypeClassError (env, (UnsatisfiableConstraints _ as e)) -> @@ -1186,9 +1193,9 @@ let interp_strategy ist gl c = c let glob_strategy ist l = l let subst_strategy evm l = l -let apply_constr_expr c l2r occs = fun env sigma -> - let evd, c = Constrintern.interp_open_constr sigma env c in - apply_lemma (evd, (c, NoBindings)) l2r occs env sigma +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) let interp_constr_list env sigma = List.map (fun c -> @@ -1230,26 +1237,37 @@ ARGUMENT EXTEND rewstrategy TYPED AS strategy | [ "choice" rewstrategy(h) rewstrategy(h') ] -> [ Strategies.choice h h' ] | [ "old_hints" preident(h) ] -> [ Strategies.old_hints h ] | [ "hints" preident(h) ] -> [ Strategies.hints h ] - | [ "terms" constr_list(h) ] -> [ fun env sigma -> - Strategies.lemmas (interp_constr_list env sigma h) env sigma ] - | [ "eval" red_expr(r) ] -> [ fun env sigma -> - Strategies.reduce (Tacinterp.interp_redexp env sigma r) env sigma ] + | [ "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 ] + | [ "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 ] END type constr_expr_with_bindings = constr_expr with_bindings -type glob_constr_with_bindings = interp_sign * glob_constr_and_expr with_bindings +type glob_constr_with_bindings = glob_constr_and_expr with_bindings +type glob_constr_with_bindings_sign = interp_sign * glob_constr_and_expr with_bindings -let pr_glob_constr_with_bindings _ _ _ s = Pp.str "<constr_expr_with_bindings>" +let pr_glob_constr_with_bindings_sign _ _ _ (ge : glob_constr_with_bindings_sign) = Printer.pr_glob_constr (fst (fst (snd ge))) +let pr_glob_constr_with_bindings _ _ _ (ge : glob_constr_with_bindings) = Printer.pr_glob_constr (fst (fst ge)) +let pr_constr_expr_with_bindings prc _ _ (ge : constr_expr_with_bindings) = prc (fst ge) let interp_glob_constr_with_bindings ist gl c = (ist, c) let glob_glob_constr_with_bindings ist l = Tacinterp.intern_constr_with_bindings ist l let subst_glob_constr_with_bindings s c = subst_glob_with_bindings s c -ARGUMENT EXTEND glob_constr_with_bindings TYPED AS glob_constr_with_bindings - PRINTED BY pr_glob_constr_with_bindings +ARGUMENT EXTEND glob_constr_with_bindings + PRINTED BY pr_glob_constr_with_bindings_sign + INTERPRETED BY interp_glob_constr_with_bindings GLOBALIZED BY glob_glob_constr_with_bindings SUBSTITUTED BY subst_glob_constr_with_bindings + + RAW_TYPED AS constr_expr_with_bindings + RAW_PRINTED BY pr_constr_expr_with_bindings + + GLOB_TYPED AS glob_constr_with_bindings + GLOB_PRINTED BY pr_glob_constr_with_bindings + [ constr_with_bindings(bl) ] -> [ bl ] END |