feat(library/init/meta/match_tactic): add helper tactics on top of match tactic

This commit is contained in:
Leonardo de Moura 2016-08-06 14:13:41 -07:00
parent 5eddff44ab
commit e52cffd04d
2 changed files with 78 additions and 0 deletions

View file

@ -34,4 +34,70 @@ meta_constant match_pattern_core : transparency → pattern → expr → tactic
meta_definition match_pattern : pattern → expr → tactic (list expr) :=
match_pattern_core semireducible
open expr
/- Helper function for converting a term (λ x_1 ... x_n, t) into a pattern
where x_1 ... x_n are metavariables -/
private meta_definition to_pattern_core : expr → tactic (expr × list expr)
| (lam n bi d b) := do
id ← mk_fresh_name,
x ← return $ local_const id n bi d,
new_b ← return $ instantiate_var b x,
(p, xs) ← to_pattern_core new_b,
return (p, x::xs)
| e := return (e, [])
/- Given a pre-term of the form (λ x_1 ... x_n, t[x_1, ..., x_n]), converts it
into the pattern t[?x_1, ..., ?x_n] -/
meta_definition pexpr_to_pattern (p : pexpr) : tactic pattern :=
do e ← to_expr p,
(new_p, xs) ← to_pattern_core e,
mk_pattern [] xs new_p xs
/- Convert pre-term into a pattern and try to match e.
Given p of the form (λ x_1 ... x_n, t[x_1, ..., x_n]), a successful
match will produce a list of length n. -/
meta_definition match_expr (p : pexpr) (e : expr) : tactic (list expr) :=
do new_p ← pexpr_to_pattern p,
match_pattern new_p e
private meta_definition match_subexpr_core : pattern → list expr → tactic (list expr)
| p [] := failed
| p (e::es) :=
match_pattern p e
<|>
match_subexpr_core p es
<|>
if (is_app e = tt) then match_subexpr_core p (get_app_args e)
else failed
/- Similar to match_expr, but it tries to match a subexpression of e.
Remark: the procedure does not go inside binders. -/
meta_definition match_subexpr (p : pexpr) (e : expr) : tactic (list expr) :=
do new_p ← pexpr_to_pattern p,
match_subexpr_core new_p [e]
/- Match the main goal target. -/
meta_definition match_target (p : pexpr) : tactic (list expr) :=
target >>= match_expr p
/- Match a subterm in the main goal target. -/
meta_definition match_target_subexpr (p : pexpr) : tactic (list expr) :=
target >>= match_subexpr p
private meta_definition match_hypothesis_core : pattern → list expr → tactic (expr × list expr)
| p [] := failed
| p (h::hs) := do
h_type ← infer_type h,
(do r ← match_pattern p h_type, return (h, r))
<|>
match_hypothesis_core p hs
/- Match hypothesis in the main goal target.
The result is pair (hypothesis, substitution). -/
meta_definition match_hypothesis (p : pexpr) : tactic (expr × list expr) :=
do ctx ← local_context,
new_p ← pexpr_to_pattern p,
match_hypothesis_core new_p ctx
end tactic

View file

@ -0,0 +1,12 @@
open tactic
axiom Sorry : ∀ {A:Type}, A
example (a b c : nat) (h₀ : c > 0) (h₁ : a > 1) (h₂ : b > 0) : a + b + c = 0 :=
by do
[x, y] ← match_target_subexpr `(λ x y : nat, x + y) | failed,
trace "------ subterms -------",
trace x, trace y,
(h, [z]) ← match_hypothesis `(λ x : nat, x > 1) | failed,
trace "--- hypothesis of the form x > 1 ---",
trace h, trace z,
refine `(Sorry)