refactor(frontends/lean/local_context): move mvar2meta mapping to elaborator
This commit is contained in:
parent
fce1113b80
commit
354c456639
3 changed files with 17 additions and 21 deletions
|
@ -68,6 +68,9 @@ elaborator_context::elaborator_context(environment const & env, io_state const &
|
||||||
m_use_local_instances = get_elaborator_local_instances(ios.get_options());
|
m_use_local_instances = get_elaborator_local_instances(ios.get_options());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Mapping from metavariable names to metavariable applications (?M ...) */
|
||||||
|
typedef name_map<expr> mvar2meta;
|
||||||
|
|
||||||
/** \brief Helper class for implementing the \c elaborate functions. */
|
/** \brief Helper class for implementing the \c elaborate functions. */
|
||||||
class elaborator : public coercion_info_manager {
|
class elaborator : public coercion_info_manager {
|
||||||
typedef name_map<expr> local_tactic_hints;
|
typedef name_map<expr> local_tactic_hints;
|
||||||
|
@ -80,6 +83,7 @@ class elaborator : public coercion_info_manager {
|
||||||
// representing the context where ?m was created.
|
// representing the context where ?m was created.
|
||||||
local_context m_context; // current local context: a list of local constants
|
local_context m_context; // current local context: a list of local constants
|
||||||
local_context m_full_context; // superset of m_context, it also contains non-contextual locals.
|
local_context m_full_context; // superset of m_context, it also contains non-contextual locals.
|
||||||
|
mvar2meta m_mvar2meta;
|
||||||
cache m_cache;
|
cache m_cache;
|
||||||
|
|
||||||
// mapping from metavariable name ?m to tactic expression that should be used to solve it.
|
// mapping from metavariable name ?m to tactic expression that should be used to solve it.
|
||||||
|
@ -185,16 +189,21 @@ public:
|
||||||
expr whnf(expr const & e, constraint_seq & s) { return m_tc[m_relax_main_opaque]->whnf(e, s); }
|
expr whnf(expr const & e, constraint_seq & s) { return m_tc[m_relax_main_opaque]->whnf(e, s); }
|
||||||
expr mk_app(expr const & f, expr const & a, tag g) { return ::lean::mk_app(f, a).set_tag(g); }
|
expr mk_app(expr const & f, expr const & a, tag g) { return ::lean::mk_app(f, a).set_tag(g); }
|
||||||
|
|
||||||
|
void register_meta(expr const & meta) {
|
||||||
|
lean_assert(is_meta(meta));
|
||||||
|
m_mvar2meta.insert(mlocal_name(get_app_fn(meta)), meta);
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief Convert the metavariable to the metavariable application that captures
|
/** \brief Convert the metavariable to the metavariable application that captures
|
||||||
the context where it was defined.
|
the context where it was defined.
|
||||||
*/
|
*/
|
||||||
optional<expr> mvar_to_meta(expr const & mvar) {
|
optional<expr> mvar_to_meta(expr const & mvar) {
|
||||||
lean_assert(is_metavar(mvar));
|
lean_assert(is_metavar(mvar));
|
||||||
name const & m = mlocal_name(mvar);
|
name const & m = mlocal_name(mvar);
|
||||||
if (auto it = m_context.find_meta(m))
|
if (auto it = m_mvar2meta.find(m))
|
||||||
return it;
|
return some_expr(*it);
|
||||||
else
|
else
|
||||||
return m_full_context.find_meta(m);
|
return none_expr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Store the pair (pos(e), type(r)) in the info_data if m_info_manager is available. */
|
/** \brief Store the pair (pos(e), type(r)) in the info_data if m_info_manager is available. */
|
||||||
|
@ -310,6 +319,7 @@ public:
|
||||||
lean_assert(is_choice(e));
|
lean_assert(is_choice(e));
|
||||||
// Possible optimization: try to lookahead and discard some of the alternatives.
|
// Possible optimization: try to lookahead and discard some of the alternatives.
|
||||||
expr m = m_full_context.mk_meta(t, e.get_tag());
|
expr m = m_full_context.mk_meta(t, e.get_tag());
|
||||||
|
register_meta(m);
|
||||||
bool relax = m_relax_main_opaque;
|
bool relax = m_relax_main_opaque;
|
||||||
auto fn = [=](expr const & meta, expr const & /* type */, substitution const & /* s */,
|
auto fn = [=](expr const & meta, expr const & /* type */, substitution const & /* s */,
|
||||||
name_generator const & /* ngen */) {
|
name_generator const & /* ngen */) {
|
||||||
|
@ -324,6 +334,7 @@ public:
|
||||||
lean_assert(is_by(e));
|
lean_assert(is_by(e));
|
||||||
expr tac = visit(get_by_arg(e), cs);
|
expr tac = visit(get_by_arg(e), cs);
|
||||||
expr m = m_context.mk_meta(t, e.get_tag());
|
expr m = m_context.mk_meta(t, e.get_tag());
|
||||||
|
register_meta(m);
|
||||||
m_local_tactic_hints.insert(mlocal_name(get_app_fn(m)), tac);
|
m_local_tactic_hints.insert(mlocal_name(get_app_fn(m)), tac);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@ -332,6 +343,7 @@ public:
|
||||||
lean_assert(is_proof_qed_annotation(e));
|
lean_assert(is_proof_qed_annotation(e));
|
||||||
pair<expr, constraint_seq> ecs = visit(get_annotation_arg(e));
|
pair<expr, constraint_seq> ecs = visit(get_annotation_arg(e));
|
||||||
expr m = m_full_context.mk_meta(t, e.get_tag());
|
expr m = m_full_context.mk_meta(t, e.get_tag());
|
||||||
|
register_meta(m);
|
||||||
constraint c = mk_proof_qed_cnstr(env(), m, ecs.first, ecs.second, m_unifier_config, m_relax_main_opaque);
|
constraint c = mk_proof_qed_cnstr(env(), m, ecs.first, ecs.second, m_unifier_config, m_relax_main_opaque);
|
||||||
cs += c;
|
cs += c;
|
||||||
return m;
|
return m;
|
||||||
|
@ -416,6 +428,7 @@ public:
|
||||||
return choose(std::make_shared<coercion_elaborator>(*this, f, choices, coes, false));
|
return choose(std::make_shared<coercion_elaborator>(*this, f, choices, coes, false));
|
||||||
};
|
};
|
||||||
f = m_full_context.mk_meta(none_expr(), f.get_tag());
|
f = m_full_context.mk_meta(none_expr(), f.get_tag());
|
||||||
|
register_meta(f);
|
||||||
cs += mk_choice_cnstr(f, choice_fn, to_delay_factor(cnstr_group::Basic), true, j, relax);
|
cs += mk_choice_cnstr(f, choice_fn, to_delay_factor(cnstr_group::Basic), true, j, relax);
|
||||||
lean_assert(is_meta(f));
|
lean_assert(is_meta(f));
|
||||||
// let type checker add constraint
|
// let type checker add constraint
|
||||||
|
@ -480,6 +493,7 @@ public:
|
||||||
bool relax = m_relax_main_opaque;
|
bool relax = m_relax_main_opaque;
|
||||||
type_checker & tc = *m_tc[relax];
|
type_checker & tc = *m_tc[relax];
|
||||||
expr m = m_full_context.mk_meta(some_expr(expected_type), a.get_tag());
|
expr m = m_full_context.mk_meta(some_expr(expected_type), a.get_tag());
|
||||||
|
register_meta(m);
|
||||||
constraint c = mk_coercion_cnstr(tc, *this, m, a, a_type, j, to_delay_factor(cnstr_group::Basic), relax);
|
constraint c = mk_coercion_cnstr(tc, *this, m, a, a_type, j, to_delay_factor(cnstr_group::Basic), relax);
|
||||||
return to_ecs(m, c);
|
return to_ecs(m, c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,6 @@ expr local_context::mk_metavar(optional<expr> const & type, tag g) {
|
||||||
expr local_context::mk_meta(optional<expr> const & type, tag g) {
|
expr local_context::mk_meta(optional<expr> const & type, tag g) {
|
||||||
expr mvar = mk_metavar(type, g);
|
expr mvar = mk_metavar(type, g);
|
||||||
expr meta = apply_context(mvar, g);
|
expr meta = apply_context(mvar, g);
|
||||||
m_mvar2meta.insert(mlocal_name(mvar), meta);
|
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,13 +103,6 @@ void local_context::add_local(expr const & l) {
|
||||||
lean_assert(is_local(head(m_ctx_abstracted)));
|
lean_assert(is_local(head(m_ctx_abstracted)));
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<expr> local_context::find_meta(name const & n) const {
|
|
||||||
if (auto it = m_mvar2meta.find(n))
|
|
||||||
return some_expr(*it);
|
|
||||||
else
|
|
||||||
return none_expr();
|
|
||||||
}
|
|
||||||
|
|
||||||
list<expr> const & local_context::get_data() const {
|
list<expr> const & local_context::get_data() const {
|
||||||
return m_ctx;
|
return m_ctx;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,11 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/expr.h"
|
#include "kernel/expr.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
/** \brief Mapping from metavariable names to metavariable applications (?M ...) */
|
|
||||||
typedef name_map<expr> mvar2meta;
|
|
||||||
|
|
||||||
/** \brief Auxiliary data-structure for storing the local context,
|
/** \brief Auxiliary data-structure for storing the local context,
|
||||||
and creating metavariables in the scope of the local context efficiently
|
and creating metavariables in the scope of the local context efficiently
|
||||||
*/
|
*/
|
||||||
class local_context {
|
class local_context {
|
||||||
name_generator m_ngen;
|
name_generator m_ngen;
|
||||||
mvar2meta m_mvar2meta;
|
|
||||||
list<expr> m_ctx; // current local context: a list of local constants
|
list<expr> m_ctx; // current local context: a list of local constants
|
||||||
list<expr> m_ctx_abstracted; // m_ctx where elements have been abstracted
|
list<expr> m_ctx_abstracted; // m_ctx where elements have been abstracted
|
||||||
public:
|
public:
|
||||||
|
@ -81,12 +77,6 @@ public:
|
||||||
/** \brief Return context as a list */
|
/** \brief Return context as a list */
|
||||||
list<expr> const & get_data() const;
|
list<expr> const & get_data() const;
|
||||||
|
|
||||||
/** \brief Return the metavariable application associated with the metavariable name
|
|
||||||
\c n. The metavariable application contains the context where \c n was created.
|
|
||||||
Return none if \c n was not created using this local context object.
|
|
||||||
*/
|
|
||||||
optional<expr> find_meta(name const & n) const;
|
|
||||||
|
|
||||||
void add_local(expr const & l);
|
void add_local(expr const & l);
|
||||||
|
|
||||||
/** \brief Scope object for restoring the content of the context */
|
/** \brief Scope object for restoring the content of the context */
|
||||||
|
|
Loading…
Reference in a new issue