2015-02-03 01:02:14 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#include "library/tactic/rewrite_tactic.h"
|
|
|
|
#include "frontends/lean/parser.h"
|
|
|
|
#include "frontends/lean/tokens.h"
|
|
|
|
#include "frontends/lean/parse_tactic_location.h"
|
|
|
|
|
|
|
|
namespace lean {
|
2015-02-03 03:20:24 +00:00
|
|
|
static optional<expr> parse_pattern(parser & p) {
|
|
|
|
if (p.curr_is_token(get_lbracket_tk())) {
|
|
|
|
p.next();
|
|
|
|
expr r = p.parse_expr();
|
|
|
|
p.check_token_next(get_rbracket_tk(), "invalid rewrite pattern, ']' expected");
|
|
|
|
return some_expr(r);
|
|
|
|
} else {
|
|
|
|
return none_expr();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static expr parse_rule(parser & p) {
|
|
|
|
if (p.curr_is_token(get_lparen_tk())) {
|
|
|
|
p.next();
|
|
|
|
expr r = p.parse_expr();
|
|
|
|
p.check_token_next(get_rparen_tk(), "invalid rewrite pattern, ']' expected");
|
|
|
|
return r;
|
|
|
|
} else {
|
|
|
|
return p.parse_id();
|
|
|
|
}
|
2015-02-03 01:02:14 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 03:20:24 +00:00
|
|
|
expr parse_rewrite_element(parser & p) {
|
2015-02-03 01:02:14 +00:00
|
|
|
if (p.curr_is_token(get_slash_tk())) {
|
|
|
|
p.next();
|
2015-02-03 03:20:24 +00:00
|
|
|
name n = p.check_id_next("invalid unfold rewrite step, identifier expected");
|
2015-02-03 01:37:11 +00:00
|
|
|
location loc = parse_tactic_location(p);
|
2015-02-03 03:20:24 +00:00
|
|
|
return mk_rewrite_unfold(n, loc);
|
2015-02-03 01:02:14 +00:00
|
|
|
}
|
|
|
|
bool symm = false;
|
|
|
|
if (p.curr_is_token(get_sub_tk())) {
|
|
|
|
p.next();
|
|
|
|
symm = true;
|
|
|
|
}
|
|
|
|
if (p.curr_is_numeral()) {
|
|
|
|
unsigned n = p.parse_small_nat();
|
|
|
|
if (p.curr_is_token(get_question_tk())) {
|
|
|
|
p.next();
|
2015-02-03 03:20:24 +00:00
|
|
|
optional<expr> pat = parse_pattern(p);
|
|
|
|
expr H = parse_rule(p);
|
2015-02-03 01:37:11 +00:00
|
|
|
location loc = parse_tactic_location(p);
|
2015-02-03 03:20:24 +00:00
|
|
|
return mk_rewrite_at_most_n(pat, H, n, symm, loc);
|
2015-02-03 01:02:14 +00:00
|
|
|
} else if (p.curr_is_token(get_bang_tk())) {
|
|
|
|
p.next();
|
2015-02-03 03:20:24 +00:00
|
|
|
optional<expr> pat = parse_pattern(p);
|
|
|
|
expr H = parse_rule(p);
|
2015-02-03 01:37:11 +00:00
|
|
|
location loc = parse_tactic_location(p);
|
2015-02-03 03:20:24 +00:00
|
|
|
return mk_rewrite_exactly_n(pat, H, n, symm, loc);
|
2015-02-03 01:02:14 +00:00
|
|
|
} else {
|
2015-02-03 03:20:24 +00:00
|
|
|
optional<expr> pat = parse_pattern(p);
|
|
|
|
expr H = parse_rule(p);
|
2015-02-03 01:37:11 +00:00
|
|
|
location loc = parse_tactic_location(p);
|
2015-02-03 03:20:24 +00:00
|
|
|
return mk_rewrite_exactly_n(pat, H, n, symm, loc);
|
2015-02-03 01:02:14 +00:00
|
|
|
}
|
|
|
|
} else if (p.curr_is_token(get_question_tk())) {
|
|
|
|
p.next();
|
2015-02-03 03:20:24 +00:00
|
|
|
optional<expr> pat = parse_pattern(p);
|
|
|
|
expr H = parse_rule(p);
|
2015-02-03 01:37:11 +00:00
|
|
|
location loc = parse_tactic_location(p);
|
2015-02-03 03:20:24 +00:00
|
|
|
return mk_rewrite_zero_or_more(pat, H, symm, loc);
|
2015-02-03 01:02:14 +00:00
|
|
|
} else if (p.curr_is_token(get_bang_tk())) {
|
|
|
|
p.next();
|
2015-02-03 03:20:24 +00:00
|
|
|
optional<expr> pat = parse_pattern(p);
|
|
|
|
expr H = parse_rule(p);
|
2015-02-03 01:37:11 +00:00
|
|
|
location loc = parse_tactic_location(p);
|
2015-02-03 03:20:24 +00:00
|
|
|
return mk_rewrite_one_or_more(pat, H, symm, loc);
|
2015-02-03 01:02:14 +00:00
|
|
|
} else {
|
2015-02-03 03:20:24 +00:00
|
|
|
optional<expr> pat = parse_pattern(p);
|
|
|
|
expr H = parse_rule(p);
|
2015-02-03 01:37:11 +00:00
|
|
|
location loc = parse_tactic_location(p);
|
2015-02-03 03:20:24 +00:00
|
|
|
return mk_rewrite_once(pat, H, symm, loc);
|
2015-02-03 01:02:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
expr parse_rewrite_tactic(parser & p) {
|
2015-02-03 03:20:24 +00:00
|
|
|
buffer<expr> elems;
|
2015-02-03 01:02:14 +00:00
|
|
|
while (true) {
|
2015-02-03 01:37:11 +00:00
|
|
|
bool has_paren = false;
|
|
|
|
if (p.curr_is_token(get_lparen_tk())) {
|
|
|
|
has_paren = true;
|
|
|
|
p.next();
|
|
|
|
}
|
2015-02-03 01:02:14 +00:00
|
|
|
elems.push_back(parse_rewrite_element(p));
|
2015-02-03 01:37:11 +00:00
|
|
|
if (has_paren)
|
|
|
|
p.check_token_next(get_rparen_tk(), "invalid rewrite tactic element, ')' expected");
|
2015-02-03 01:02:14 +00:00
|
|
|
if (!p.curr_is_token(get_sub_tk()) &&
|
|
|
|
!p.curr_is_numeral() &&
|
|
|
|
!p.curr_is_token(get_bang_tk()) &&
|
|
|
|
!p.curr_is_token(get_question_tk()) &&
|
|
|
|
!p.curr_is_token(get_slash_tk()) &&
|
2015-02-03 01:37:11 +00:00
|
|
|
!p.curr_is_identifier() &&
|
2015-02-03 03:20:24 +00:00
|
|
|
!p.curr_is_token(get_lbracket_tk()) &&
|
2015-02-03 01:37:11 +00:00
|
|
|
!p.curr_is_token(get_lparen_tk()))
|
2015-02-03 01:02:14 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-02-03 01:37:11 +00:00
|
|
|
return mk_rewrite_tactic_expr(elems);
|
2015-02-03 01:02:14 +00:00
|
|
|
}
|
|
|
|
}
|