refactor(library/tactic): add auxiliary module 'library/tactic/elaborate'
This commit is contained in:
parent
7c016191d2
commit
f3fdc70400
11 changed files with 85 additions and 41 deletions
|
@ -8,7 +8,6 @@ Author: Leonardo de Moura
|
|||
#include "util/numerics/register_module.h"
|
||||
#include "util/sexpr/register_module.h"
|
||||
#include "library/register_module.h"
|
||||
// #include "library/simplifier/register_module.h"
|
||||
#include "library/tactic/register_module.h"
|
||||
#include "frontends/lean/register_module.h"
|
||||
|
||||
|
@ -17,7 +16,6 @@ void register_modules() {
|
|||
register_numerics_module();
|
||||
register_sexpr_module();
|
||||
register_core_module();
|
||||
// register_simplifier_module();
|
||||
register_tactic_module();
|
||||
register_frontend_lean_module();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ bool is_reducible_off(environment const & env, name const & n);
|
|||
|
||||
/** \brief Create a type checker that takes the "reducibility" hints into account. */
|
||||
std::unique_ptr<type_checker> mk_type_checker(environment const & env, name_generator const & ngen,
|
||||
bool relax_main_opaque, bool only_main_reducible = false);
|
||||
bool relax_main_opaque = true, bool only_main_reducible = false);
|
||||
std::unique_ptr<type_checker> mk_type_checker(environment const & env, bool relax_main_opaque, bool only_main_reducible = false);
|
||||
|
||||
void initialize_reducible();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
add_library(tactic goal.cpp proof_state.cpp tactic.cpp
|
||||
apply_tactic.cpp intros_tactic.cpp rename_tactic.cpp trace_tactic.cpp
|
||||
exact_tactic.cpp expr_to_tactic.cpp init_module.cpp)
|
||||
exact_tactic.cpp expr_to_tactic.cpp elaborate.cpp init_module.cpp)
|
||||
|
||||
target_link_libraries(tactic ${LEAN_LIBS})
|
||||
|
|
|
@ -19,8 +19,8 @@ Author: Leonardo de Moura
|
|||
#include "library/occurs.h"
|
||||
#include "library/metavar_closure.h"
|
||||
#include "library/type_util.h"
|
||||
#include "library/tactic/apply_tactic.h"
|
||||
#include "library/tactic/expr_to_tactic.h"
|
||||
#include "library/tactic/apply_tactic.h"
|
||||
|
||||
namespace lean {
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,7 @@ Author: Leonardo de Moura
|
|||
*/
|
||||
#pragma once
|
||||
#include "util/lua.h"
|
||||
#include "library/tactic/tactic.h"
|
||||
#include "library/tactic/elaborate.h"
|
||||
namespace lean {
|
||||
tactic apply_tactic(elaborate_fn const & fn, expr const & e, bool rev_goals = false, bool relax_main_opaque = true);
|
||||
tactic eassumption_tactic(bool relax_main_opaque = true);
|
||||
|
|
35
src/library/tactic/elaborate.cpp
Normal file
35
src/library/tactic/elaborate.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "library/unifier.h"
|
||||
#include "library/tactic/elaborate.h"
|
||||
|
||||
namespace lean {
|
||||
optional<expr> elaborate_with_respect_to(environment const & env, io_state const & ios, elaborate_fn const & elab,
|
||||
proof_state & s, expr const & e) {
|
||||
name_generator ngen = s.get_ngen();
|
||||
substitution subst = s.get_subst();
|
||||
goals const & gs = s.get_goals();
|
||||
if (empty(gs))
|
||||
return none_expr();
|
||||
auto ecs = elab(head(gs), ngen.mk_child(), e);
|
||||
expr new_e = ecs.first;
|
||||
buffer<constraint> cs;
|
||||
to_buffer(ecs.second, cs);
|
||||
to_buffer(s.get_postponed(), cs);
|
||||
unifier_config cfg(ios.get_options());
|
||||
unify_result_seq rseq = unify(env, cs.size(), cs.data(), ngen.mk_child(), subst, cfg);
|
||||
if (auto p = rseq.pull()) {
|
||||
substitution new_subst = p->first.first;
|
||||
constraints new_postponed = p->first.second;
|
||||
new_e = new_subst.instantiate(new_e);
|
||||
s = proof_state(gs, new_subst, ngen, new_postponed);
|
||||
return some_expr(new_e);
|
||||
} else {
|
||||
return none_expr();
|
||||
}
|
||||
}
|
||||
}
|
28
src/library/tactic/elaborate.h
Normal file
28
src/library/tactic/elaborate.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "library/tactic/tactic.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Function for elaborating expressions nested in tactics.
|
||||
Some tactics contain nested expression (aka pre-terms) that need to be elaborated.
|
||||
*/
|
||||
typedef std::function<pair<expr, constraints>(goal const &, name_generator const &, expr const &)> elaborate_fn;
|
||||
|
||||
/** \brief Try to elaborate expression \c e using the elaboration function \c elab. The elaboration is performed
|
||||
with respect to (local context of) the first goal in \c s. The constraints generated during elaboration
|
||||
are solved using the higher-order unifier. When solving the constraints any postponed constraint in \c s
|
||||
is also considered. Only the first solution returned by the unifier is considered.
|
||||
If the whole process succeeds, then the elaborated expression is returned, and the proof state is updated.
|
||||
The following fields in the name generator may be updated: name-generator and substitution.
|
||||
|
||||
If the proof state has no goal, the elaboration or unifier fails, then none is returned and the proof state
|
||||
is not modified.
|
||||
*/
|
||||
optional<expr> elaborate_with_respect_to(environment const & env, io_state const & ios, elaborate_fn const & elab,
|
||||
proof_state & s, expr const & e);
|
||||
}
|
|
@ -5,42 +5,29 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "kernel/type_checker.h"
|
||||
#include "library/unifier.h"
|
||||
#include "library/reducible.h"
|
||||
#include "library/tactic/tactic.h"
|
||||
#include "library/tactic/elaborate.h"
|
||||
#include "library/tactic/expr_to_tactic.h"
|
||||
|
||||
namespace lean {
|
||||
tactic exact_tactic(elaborate_fn const & elab, expr const & e) {
|
||||
return tactic01([=](environment const & env, io_state const & ios, proof_state const & s) {
|
||||
name_generator ngen = s.get_ngen();
|
||||
substitution subst = s.get_subst();
|
||||
goals const & gs = s.get_goals();
|
||||
if (empty(gs))
|
||||
return none_proof_state();
|
||||
goal const & g = head(gs);
|
||||
expr new_e;
|
||||
buffer<constraint> cs;
|
||||
auto ecs = elab(g, ngen.mk_child(), e);
|
||||
new_e = ecs.first;
|
||||
to_buffer(ecs.second, cs);
|
||||
to_buffer(s.get_postponed(), cs);
|
||||
unifier_config cfg(ios.get_options());
|
||||
unify_result_seq rseq = unify(env, cs.size(), cs.data(), ngen.mk_child(), subst, cfg);
|
||||
if (auto p = rseq.pull()) {
|
||||
substitution new_subst = p->first.first;
|
||||
constraints new_postponed = p->first.second;
|
||||
new_e = new_subst.instantiate(new_e);
|
||||
bool relax_main_opaque = true;
|
||||
auto tc = mk_type_checker(env, ngen.mk_child(), relax_main_opaque);
|
||||
auto e_t_cs = tc->infer(new_e);
|
||||
expr t = new_subst.instantiate(g.get_type());
|
||||
proof_state new_s = s;
|
||||
if (auto new_e = elaborate_with_respect_to(env, ios, elab, new_s, e)) {
|
||||
name_generator ngen = new_s.get_ngen();
|
||||
substitution subst = new_s.get_subst();
|
||||
goals const & gs = new_s.get_goals();
|
||||
goal const & g = head(gs);
|
||||
auto tc = mk_type_checker(env, ngen.mk_child());
|
||||
auto e_t_cs = tc->infer(*new_e);
|
||||
expr t = subst.instantiate(g.get_type());
|
||||
auto dcs = tc->is_def_eq(e_t_cs.first, t);
|
||||
if (dcs.first && !dcs.second && !e_t_cs.second) {
|
||||
expr new_p = g.abstract(new_e);
|
||||
expr new_p = g.abstract(*new_e);
|
||||
check_has_no_local(new_p, e, "exact");
|
||||
new_subst.assign(g.get_name(), new_p);
|
||||
return some(proof_state(tail(gs), new_subst, ngen, new_postponed));
|
||||
subst.assign(g.get_name(), new_p);
|
||||
return some(proof_state(new_s, tail(gs), subst, ngen));
|
||||
}
|
||||
}
|
||||
return none_proof_state();
|
||||
|
@ -48,9 +35,7 @@ tactic exact_tactic(elaborate_fn const & elab, expr const & e) {
|
|||
}
|
||||
|
||||
static expr * g_exact_tac_fn = nullptr;
|
||||
|
||||
expr const & get_exact_tac_fn() { return *g_exact_tac_fn; }
|
||||
|
||||
void initialize_exact_tactic() {
|
||||
name exact_tac_name({"tactic", "exact"});
|
||||
g_exact_tac_fn = new expr(Const(exact_tac_name));
|
||||
|
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
|||
#pragma once
|
||||
#include "kernel/pos_info_provider.h"
|
||||
#include "library/tactic/tactic.h"
|
||||
#include "library/tactic/elaborate.h"
|
||||
|
||||
namespace lean {
|
||||
/**
|
||||
|
|
|
@ -22,10 +22,12 @@ class proof_state {
|
|||
constraints m_postponed;
|
||||
public:
|
||||
proof_state(goals const & gs, substitution const & s, name_generator const & ngen, constraints const & postponed);
|
||||
proof_state(proof_state const & s, goals const & gs, substitution const & subst, name_generator const & ngen):
|
||||
proof_state(gs, subst, ngen, s.m_postponed) {}
|
||||
proof_state(proof_state const & s, goals const & gs, substitution const & subst):
|
||||
proof_state(gs, subst, s.m_ngen, s.m_postponed) {}
|
||||
proof_state(s, gs, subst, s.m_ngen) {}
|
||||
proof_state(proof_state const & s, goals const & gs, name_generator const & ngen):
|
||||
proof_state(gs, s.m_subst, ngen, s.m_postponed) {}
|
||||
proof_state(s, gs, s.m_subst, ngen) {}
|
||||
proof_state(proof_state const & s, goals const & gs):
|
||||
proof_state(s, gs, s.m_subst) {}
|
||||
proof_state(proof_state const & s, name_generator const & ngen):
|
||||
|
|
|
@ -14,11 +14,6 @@ Author: Leonardo de Moura
|
|||
#include "library/tactic/proof_state.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Function for elaborating expressions nested in tactics.
|
||||
Some tactics contain nested expression (aka pre-terms) that need to be elaborated.
|
||||
*/
|
||||
typedef std::function<pair<expr, constraints>(goal const &, name_generator const &, expr const &)> elaborate_fn;
|
||||
|
||||
/** \brief Throw an exception is \c v contains local constants, \c e is only used for position information. */
|
||||
void check_has_no_local(expr const & v, expr const & e, char const * tac_name);
|
||||
|
||||
|
|
Loading…
Reference in a new issue