feat(frontends/lean): improve support for user defined tactics

This commit is contained in:
Leonardo de Moura 2015-02-27 16:39:39 -08:00
parent c9ffc2fec8
commit cf56935b01
3 changed files with 36 additions and 2 deletions

View file

@ -617,7 +617,12 @@ expr elaborator::visit_app(expr const & e, constraint_seq & cs) {
constraint_seq a_cs;
expr d_type = binding_domain(f_type);
if (d_type == get_tactic_expr_type()) {
expr r = mk_app(f, mk_tactic_expr(app_arg(e)), e.get_tag());
expr const & a = app_arg(e);
expr r;
if (is_local(a) && (mlocal_type(a) == get_tactic_expr_type() || m_in_equation_lhs))
r = mk_app(f, a, e.get_tag());
else
r = mk_app(f, mk_tactic_expr(a), e.get_tag());
cs += f_cs + a_cs;
return r;
} else {

View file

@ -99,7 +99,10 @@ bool is_tactic_expr(expr const & e) {
expr const & get_tactic_expr_expr(expr const & e) {
lean_assert(is_tactic_expr(e));
return macro_arg(e, 0);
expr const * it = &e;
while (is_tactic_expr(*it))
it = &macro_arg(*it, 0);
return *it;
}
void check_tactic_expr(expr const & e, char const * error_msg) {

View file

@ -0,0 +1,26 @@
context
open tactic
definition cases_refl (e : expr) : tactic :=
cases e; apply rfl
definition cases_lst_refl : expr_list → tactic
| cases_lst_refl expr_list.nil := apply rfl
| cases_lst_refl (expr_list.cons a l) := cases a; cases_lst_refl l
-- Similar to cases_refl, but make sure the argument is not an arbitrary expression.
definition eq_rec {A : Type} {a b : A} (e : a = b) : tactic :=
cases e; apply rfl
end
notation `cases_lst` l:(foldr `,` (h t, tactic.expr_list.cons h t) tactic.expr_list.nil) := cases_lst_refl l
open prod
theorem tst₁ (a : nat × nat) : (pr1 a, pr2 a) = a :=
by cases_refl a
theorem tst₂ (a b : nat × nat) (h₁ : pr₁ a = pr₁ b) (h₂ : pr₂ a = pr₂ b) : a = b :=
by cases_lst a, b, h₁, h₂
open nat
theorem tst₃ (a b : nat) (h : a = b) : a + b = b + a :=
by eq_rec h