feat(frontends/lean): add esimp tactic based on rewrite tactic
closes #358
This commit is contained in:
parent
7aac9f1fdb
commit
5b25da8c43
6 changed files with 66 additions and 17 deletions
|
@ -127,7 +127,7 @@
|
||||||
(,(rx (not (any "\.")) word-start
|
(,(rx (not (any "\.")) word-start
|
||||||
(or "\\b.*_tac" "Cond" "or_else" "then" "try" "when" "assumption" "eassumption" "rapply" "apply" "fapply" "rename" "intro" "intros"
|
(or "\\b.*_tac" "Cond" "or_else" "then" "try" "when" "assumption" "eassumption" "rapply" "apply" "fapply" "rename" "intro" "intros"
|
||||||
"generalize" "generalizes" "clear" "clears" "revert" "reverts" "back" "beta" "done" "exact" "repeat"
|
"generalize" "generalizes" "clear" "clears" "revert" "reverts" "back" "beta" "done" "exact" "repeat"
|
||||||
"whnf" "rotate" "rotate_left" "rotate_right" "inversion" "cases" "assert" "rewrite")
|
"whnf" "rotate" "rotate_left" "rotate_right" "inversion" "cases" "assert" "rewrite" "esimp" "unfold")
|
||||||
word-end)
|
word-end)
|
||||||
. 'font-lock-constant-face)
|
. 'font-lock-constant-face)
|
||||||
;; Types
|
;; Types
|
||||||
|
|
|
@ -415,6 +415,10 @@ static expr parse_rewrite_tactic_expr(parser & p, unsigned, expr const *, pos_in
|
||||||
return p.save_pos(parse_rewrite_tactic(p), pos);
|
return p.save_pos(parse_rewrite_tactic(p), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static expr parse_esimp_tactic_expr(parser & p, unsigned, expr const *, pos_info const & pos) {
|
||||||
|
return p.save_pos(parse_esimp_tactic(p), pos);
|
||||||
|
}
|
||||||
|
|
||||||
static expr parse_overwrite_notation(parser & p, unsigned, expr const *, pos_info const &) {
|
static expr parse_overwrite_notation(parser & p, unsigned, expr const *, pos_info const &) {
|
||||||
name n = p.check_id_next("invalid '#' local notation, identifier expected");
|
name n = p.check_id_next("invalid '#' local notation, identifier expected");
|
||||||
environment env = overwrite_notation(p.env(), n);
|
environment env = overwrite_notation(p.env(), n);
|
||||||
|
@ -485,6 +489,7 @@ parse_table init_nud_table() {
|
||||||
r = r.add({transition("let", mk_ext_action(parse_let_expr))}, x0);
|
r = r.add({transition("let", mk_ext_action(parse_let_expr))}, x0);
|
||||||
r = r.add({transition("calc", mk_ext_action(parse_calc_expr))}, x0);
|
r = r.add({transition("calc", mk_ext_action(parse_calc_expr))}, x0);
|
||||||
r = r.add({transition("rewrite", mk_ext_action(parse_rewrite_tactic_expr))}, x0);
|
r = r.add({transition("rewrite", mk_ext_action(parse_rewrite_tactic_expr))}, x0);
|
||||||
|
r = r.add({transition("esimp", mk_ext_action(parse_esimp_tactic_expr))}, x0);
|
||||||
r = r.add({transition("#", mk_ext_action(parse_overwrite_notation))}, x0);
|
r = r.add({transition("#", mk_ext_action(parse_overwrite_notation))}, x0);
|
||||||
r = r.add({transition("@", mk_ext_action(parse_explicit_expr))}, x0);
|
r = r.add({transition("@", mk_ext_action(parse_explicit_expr))}, x0);
|
||||||
r = r.add({transition("!", mk_ext_action(parse_consume_args_expr))}, x0);
|
r = r.add({transition("!", mk_ext_action(parse_consume_args_expr))}, x0);
|
||||||
|
|
|
@ -32,25 +32,29 @@ static expr parse_rule(parser & p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr parse_rewrite_element(parser & p) {
|
static expr parse_rewrite_unfold(parser & p) {
|
||||||
if (p.curr_is_token(get_up_tk()) || p.curr_is_token(get_caret_tk())) {
|
lean_assert(p.curr_is_token(get_up_tk()) || p.curr_is_token(get_caret_tk()));
|
||||||
|
p.next();
|
||||||
|
buffer<name> to_unfold;
|
||||||
|
if (p.curr_is_token(get_lcurly_tk())) {
|
||||||
p.next();
|
p.next();
|
||||||
buffer<name> to_unfold;
|
while (true) {
|
||||||
if (p.curr_is_token(get_lcurly_tk())) {
|
to_unfold.push_back(p.check_constant_next("invalid unfold rewrite step, identifier expected"));
|
||||||
|
if (!p.curr_is_token(get_comma_tk()))
|
||||||
|
break;
|
||||||
p.next();
|
p.next();
|
||||||
while (true) {
|
|
||||||
to_unfold.push_back(p.check_constant_next("invalid unfold rewrite step, identifier expected"));
|
|
||||||
if (!p.curr_is_token(get_comma_tk()))
|
|
||||||
break;
|
|
||||||
p.next();
|
|
||||||
}
|
|
||||||
p.check_token_next(get_rcurly_tk(), "invalid unfold rewrite step, ',' or '}' expected");
|
|
||||||
} else {
|
|
||||||
to_unfold.push_back(p.check_constant_next("invalid unfold rewrite step, identifier or '{' expected"));
|
|
||||||
}
|
}
|
||||||
location loc = parse_tactic_location(p);
|
p.check_token_next(get_rcurly_tk(), "invalid unfold rewrite step, ',' or '}' expected");
|
||||||
return mk_rewrite_unfold(to_list(to_unfold), loc);
|
} else {
|
||||||
|
to_unfold.push_back(p.check_constant_next("invalid unfold rewrite step, identifier or '{' expected"));
|
||||||
}
|
}
|
||||||
|
location loc = parse_tactic_location(p);
|
||||||
|
return mk_rewrite_unfold(to_list(to_unfold), loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
expr parse_rewrite_element(parser & p) {
|
||||||
|
if (p.curr_is_token(get_up_tk()) || p.curr_is_token(get_caret_tk()))
|
||||||
|
return parse_rewrite_unfold(p);
|
||||||
bool symm = false;
|
bool symm = false;
|
||||||
if (p.curr_is_token(get_sub_tk())) {
|
if (p.curr_is_token(get_sub_tk())) {
|
||||||
p.next();
|
p.next();
|
||||||
|
@ -123,4 +127,15 @@ expr parse_rewrite_tactic(parser & p) {
|
||||||
}
|
}
|
||||||
return mk_rewrite_tactic_expr(elems);
|
return mk_rewrite_tactic_expr(elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr parse_esimp_tactic(parser & p) {
|
||||||
|
buffer<expr> elems;
|
||||||
|
if (p.curr_is_token(get_up_tk()) || p.curr_is_token(get_caret_tk())) {
|
||||||
|
elems.push_back(parse_rewrite_unfold(p));
|
||||||
|
} else {
|
||||||
|
location loc = parse_tactic_location(p);
|
||||||
|
elems.push_back(mk_rewrite_reduce(loc));
|
||||||
|
}
|
||||||
|
return mk_rewrite_tactic_expr(elems);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,4 +10,5 @@ Author: Leonardo de Moura
|
||||||
namespace lean {
|
namespace lean {
|
||||||
class parser;
|
class parser;
|
||||||
expr parse_rewrite_tactic(parser & p);
|
expr parse_rewrite_tactic(parser & p);
|
||||||
|
expr parse_esimp_tactic(parser & p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ void init_token_table(token_table & t) {
|
||||||
{"[", g_max_prec}, {"]", 0}, {"⦃", g_max_prec}, {"⦄", 0}, {".{", 0}, {"Type", g_max_prec},
|
{"[", g_max_prec}, {"]", 0}, {"⦃", g_max_prec}, {"⦄", 0}, {".{", 0}, {"Type", g_max_prec},
|
||||||
{"{|", g_max_prec}, {"|}", 0}, {"⊢", 0}, {"⟨", g_max_prec}, {"⟩", 0}, {"^", 0}, {"↑", 0}, {"▸", 0},
|
{"{|", g_max_prec}, {"|}", 0}, {"⊢", 0}, {"⟨", g_max_prec}, {"⟩", 0}, {"^", 0}, {"↑", 0}, {"▸", 0},
|
||||||
{"using", 0}, {"|", 0}, {"!", g_max_prec}, {"?", 0}, {"with", 0}, {"...", 0}, {",", 0},
|
{"using", 0}, {"|", 0}, {"!", g_max_prec}, {"?", 0}, {"with", 0}, {"...", 0}, {",", 0},
|
||||||
{".", 0}, {":", 0}, {"::", 0}, {"calc", 0}, {"rewrite", 0}, {":=", 0}, {"--", 0}, {"#", 0},
|
{".", 0}, {":", 0}, {"::", 0}, {"calc", 0}, {"rewrite", 0}, {"esimp", 0}, {":=", 0}, {"--", 0}, {"#", 0},
|
||||||
{"(*", 0}, {"/-", 0}, {"begin", g_max_prec}, {"proof", g_max_prec}, {"qed", 0}, {"@", g_max_prec},
|
{"(*", 0}, {"/-", 0}, {"begin", g_max_prec}, {"proof", g_max_prec}, {"qed", 0}, {"@", g_max_prec},
|
||||||
{"sorry", g_max_prec}, {"+", g_plus_prec}, {g_cup, g_cup_prec}, {"->", g_arrow_prec},
|
{"sorry", g_max_prec}, {"+", g_plus_prec}, {g_cup, g_cup_prec}, {"->", g_arrow_prec},
|
||||||
{"?(", g_max_prec}, {"⌞", g_max_prec}, {"⌟", 0}, {"match", 0},
|
{"?(", g_max_prec}, {"⌞", g_max_prec}, {"⌟", 0}, {"match", 0},
|
||||||
|
|
28
tests/lean/run/esimp1.lean
Normal file
28
tests/lean/run/esimp1.lean
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
open nat
|
||||||
|
|
||||||
|
example (x y : nat) (H : (fun (a : nat), sigma.pr1 ⟨a, y⟩) x = 0) : x = 0 :=
|
||||||
|
begin
|
||||||
|
esimp at H,
|
||||||
|
exact H
|
||||||
|
end
|
||||||
|
|
||||||
|
definition foo [irreducible] (a : nat) := a
|
||||||
|
|
||||||
|
example (x y : nat) (H : (fun (a : nat), sigma.pr1 ⟨foo a, y⟩) x = 0) : x = 0 :=
|
||||||
|
begin
|
||||||
|
esimp ↑foo at H,
|
||||||
|
exact H
|
||||||
|
end
|
||||||
|
|
||||||
|
example (x y : nat) (H : x = 0) : (fun (a : nat), sigma.pr1 ⟨foo a, y⟩) x = 0 :=
|
||||||
|
begin
|
||||||
|
esimp ↑foo,
|
||||||
|
exact H
|
||||||
|
end
|
||||||
|
|
||||||
|
example (x y : nat) (H : x = 0) : (fun (a : nat), sigma.pr1 ⟨foo a, y⟩) x = 0 :=
|
||||||
|
begin
|
||||||
|
esimp,
|
||||||
|
unfold foo,
|
||||||
|
exact H
|
||||||
|
end
|
Loading…
Reference in a new issue