2015-07-14 13:54:53 +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
|
|
|
|
*/
|
2015-07-14 18:21:39 +00:00
|
|
|
#include "util/sstream.h"
|
|
|
|
#include "library/scoped_ext.h"
|
2015-07-14 13:54:53 +00:00
|
|
|
#include "library/tactic/exact_tactic.h"
|
2015-07-14 18:21:39 +00:00
|
|
|
#include "library/tactic/expr_to_tactic.h"
|
|
|
|
#include "library/simplifier/rewrite_rule_set.h"
|
|
|
|
#include "library/simplifier/simp_tactic.h"
|
2015-07-14 13:54:53 +00:00
|
|
|
#include "frontends/lean/parser.h"
|
2015-07-14 18:21:39 +00:00
|
|
|
#include "frontends/lean/parse_tactic_location.h"
|
|
|
|
#include "frontends/lean/tokens.h"
|
2015-07-14 13:54:53 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
expr parse_simp_tactic(parser & p) {
|
2015-07-14 18:21:39 +00:00
|
|
|
buffer<expr> lemmas;
|
|
|
|
buffer<name> ns;
|
|
|
|
buffer<name> hiding;
|
|
|
|
optional<expr> tac;
|
|
|
|
while (true) {
|
|
|
|
if (p.curr_is_token(get_lbracket_tk())) {
|
|
|
|
p.next();
|
|
|
|
while (true) {
|
|
|
|
if (p.curr_is_identifier()) {
|
|
|
|
auto id_pos = p.pos();
|
|
|
|
name id = p.get_name_val();
|
|
|
|
p.next();
|
|
|
|
optional<name> real_ns = to_valid_namespace_name(p.env(), id);
|
|
|
|
if (real_ns) {
|
|
|
|
ns.push_back(*real_ns);
|
|
|
|
} else {
|
|
|
|
expr left = p.id_to_expr(id, id_pos);
|
|
|
|
unsigned rbp = 0;
|
|
|
|
while (rbp < p.curr_expr_lbp()) {
|
|
|
|
left = p.parse_led(left);
|
|
|
|
}
|
|
|
|
lemmas.push_back(left);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
lemmas.push_back(p.parse_expr());
|
|
|
|
}
|
|
|
|
if (!p.curr_is_token(get_comma_tk()))
|
|
|
|
break;
|
|
|
|
p.next();
|
|
|
|
}
|
|
|
|
p.check_token_next(get_rbracket_tk(), "invalid 'simp' tactic, ']' expected");
|
|
|
|
} else if (p.curr_is_token_or_id(get_hiding_tk())) {
|
|
|
|
p.next();
|
|
|
|
p.check_token_next(get_lbracket_tk(), "invalid 'simp' tactic, '[' expected");
|
|
|
|
while (true) {
|
|
|
|
auto id_pos = p.pos();
|
|
|
|
name id = p.check_constant_next("invalid 'simp' tactic, constant expected");
|
|
|
|
if (!is_rewrite_rule(p.env(), id))
|
|
|
|
throw parser_error(sstream() << "invalid 'simp' tactic, '" << id << "' is not an active rewriting rule", id_pos);
|
|
|
|
hiding.push_back(id);
|
|
|
|
if (!p.curr_is_token(get_comma_tk()))
|
|
|
|
break;
|
|
|
|
p.next();
|
|
|
|
}
|
|
|
|
p.check_token_next(get_rbracket_tk(), "invalid 'simp' tactic, ']' expected");
|
|
|
|
} else if (p.curr_is_token_or_id(get_using_tk())) {
|
|
|
|
if (tac)
|
|
|
|
throw parser_error("invalid 'simp' tactic, auxiliary tactic was already specified", p.pos());
|
|
|
|
p.next();
|
|
|
|
tac = p.parse_tactic(get_max_prec());
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
location loc = parse_tactic_location(p);
|
|
|
|
|
|
|
|
// Remark: simp_tac is the actual result
|
|
|
|
expr simp_tac = mk_simp_tactic_expr(lemmas, ns, hiding, tac, loc);
|
|
|
|
|
|
|
|
// Using (or_else simp_tac (exact sorry)) to simplify testing
|
2015-07-14 13:54:53 +00:00
|
|
|
auto pos = p.pos();
|
|
|
|
expr sorry = p.mk_sorry(pos);
|
2015-07-14 18:21:39 +00:00
|
|
|
expr exact_sorry = p.mk_app(get_exact_tac_fn(), sorry, pos);
|
|
|
|
return mk_app(get_or_else_tac_fn(), simp_tac, exact_sorry);
|
2015-07-14 13:54:53 +00:00
|
|
|
}
|
|
|
|
}
|