lean4-htt/src/library/tactic/norm_num_tactic.cpp

74 lines
3 KiB
C++

/*
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Robert Y. Lewis
*/
#include "kernel/type_checker.h"
#include "library/util.h"
#include "library/reducible.h"
#include "library/normalize.h"
#include "library/norm_num.h"
#include "library/tactic/expr_to_tactic.h"
namespace lean {
tactic norm_num_tactic() {
return tactic01([=](environment const & env, io_state const &, proof_state const & s) {
goals const & gs = s.get_goals();
if (empty(gs)) {
throw_no_goal_if_enabled(s);
return none_proof_state();
}
goal const & g = head(gs);
expr const & c = g.get_type();
expr lhs, rhs;
if (!is_eq(c, lhs, rhs)) {
throw_tactic_exception_if_enabled(s, "norm_num tactic failed, conclusion is not an equality");
return none_proof_state();
}
type_checker_ptr rtc = mk_type_checker(env, UnfoldReducible);
lhs = normalize(*rtc, lhs);
rhs = normalize(*rtc, rhs);
buffer<expr> hyps;
g.get_hyps(hyps);
local_context ctx(to_list(hyps));
try {
pair<expr, expr> p = mk_norm_num(env, ctx, lhs);
expr new_lhs = p.first;
expr new_lhs_pr = p.second;
pair<expr, expr> p2 = mk_norm_num(env, ctx, rhs);
expr new_rhs = p2.first;
expr new_rhs_pr = p2.second;
auto v_lhs = to_num(new_lhs), v_rhs = to_num(new_rhs);
if (v_lhs && v_rhs) {
if (*v_lhs == *v_rhs) {
type_checker tc(env);
expr g_prf = mk_trans(tc, new_lhs_pr, mk_symm(tc, new_rhs_pr));
substitution new_subst = s.get_subst();
assign(new_subst, g, g_prf);
return some_proof_state(proof_state(s, tail(gs), new_subst));
} else {
std::cout << "lhs: " << new_lhs << ", rhs: " << new_rhs << "\n";
throw_tactic_exception_if_enabled(s, "norm_num tactic failed, lhs doesn't match rhs");
return none_proof_state();
}
} else {
throw_tactic_exception_if_enabled(s, "norm_num tactic failed, one side is not a numeral");
return none_proof_state();
}
} catch (exception & ex) {
throw_tactic_exception_if_enabled(s, ex.what());
return none_proof_state();
}
});
}
void initialize_norm_num_tactic() {
register_tac(name{"tactic", "norm_num"},
[](type_checker &, elaborate_fn const &, expr const &, pos_info_provider const *) {
return norm_num_tactic();
});
}
void finalize_norm_num_tactic() {
}
}