refactor(frontends/lean/elaborator): remove m_accumulated and eager metavariable instantiation
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
60ab6d3bd8
commit
c5aea3eba7
1 changed files with 9 additions and 52 deletions
|
@ -297,7 +297,6 @@ class elaborator {
|
||||||
context m_full_context; // superset of m_context, it also contains non-contextual locals.
|
context m_full_context; // superset of m_context, it also contains non-contextual locals.
|
||||||
|
|
||||||
pos_info_provider * m_pos_provider; // optional expression position information used when reporting errors.
|
pos_info_provider * m_pos_provider; // optional expression position information used when reporting errors.
|
||||||
justification m_accumulated; // accumulate justification of eagerly used substitutions
|
|
||||||
constraint_vect m_constraints; // constraints that must be solved for the elaborated term to be type correct.
|
constraint_vect m_constraints; // constraints that must be solved for the elaborated term to be type correct.
|
||||||
local_tactic_hints m_local_tactic_hints; // mapping from metavariable name ?m to tactic expression that should be used to solve it.
|
local_tactic_hints m_local_tactic_hints; // mapping from metavariable name ?m to tactic expression that should be used to solve it.
|
||||||
// this mapping is populated by the 'by tactic-expr' expression.
|
// this mapping is populated by the 'by tactic-expr' expression.
|
||||||
|
@ -316,8 +315,7 @@ class elaborator {
|
||||||
|
|
||||||
/** \brief Auxiliary object for creating backtracking points, and replacing the local scopes.
|
/** \brief Auxiliary object for creating backtracking points, and replacing the local scopes.
|
||||||
|
|
||||||
\remark A new scope can only be created when m_constraints and m_subst are empty,
|
\remark A new scope can only be created when m_constraints and m_subst are empty.
|
||||||
and m_accumulated is none.
|
|
||||||
*/
|
*/
|
||||||
struct new_scope {
|
struct new_scope {
|
||||||
elaborator & m_main;
|
elaborator & m_main;
|
||||||
|
@ -326,7 +324,6 @@ class elaborator {
|
||||||
new_scope(elaborator & e, list<expr> const & ctx, list<expr> const & full_ctx, substitution const & s):
|
new_scope(elaborator & e, list<expr> const & ctx, list<expr> const & full_ctx, substitution const & s):
|
||||||
m_main(e), m_context_scope(e.m_context, ctx), m_full_context_scope(e.m_full_context, full_ctx) {
|
m_main(e), m_context_scope(e.m_context, ctx), m_full_context_scope(e.m_full_context, full_ctx) {
|
||||||
lean_assert(m_main.m_constraints.empty());
|
lean_assert(m_main.m_constraints.empty());
|
||||||
lean_assert(m_main.m_accumulated.is_none());
|
|
||||||
m_main.m_tc[0]->push();
|
m_main.m_tc[0]->push();
|
||||||
m_main.m_tc[1]->push();
|
m_main.m_tc[1]->push();
|
||||||
m_main.m_subst = s;
|
m_main.m_subst = s;
|
||||||
|
@ -335,10 +332,8 @@ class elaborator {
|
||||||
m_main.m_tc[0]->pop();
|
m_main.m_tc[0]->pop();
|
||||||
m_main.m_tc[1]->pop();
|
m_main.m_tc[1]->pop();
|
||||||
m_main.m_constraints.clear();
|
m_main.m_constraints.clear();
|
||||||
m_main.m_accumulated = justification();
|
|
||||||
m_main.m_subst = substitution();
|
m_main.m_subst = substitution();
|
||||||
lean_assert(m_main.m_constraints.empty());
|
lean_assert(m_main.m_constraints.empty());
|
||||||
lean_assert(m_main.m_accumulated.is_none());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -384,10 +379,9 @@ class elaborator {
|
||||||
try {
|
try {
|
||||||
new_scope s(m_elab, m_ctx, m_full_ctx, m_subst);
|
new_scope s(m_elab, m_ctx, m_full_ctx, m_subst);
|
||||||
expr r = m_elab.visit(c);
|
expr r = m_elab.visit(c);
|
||||||
justification j = m_elab.m_accumulated;
|
|
||||||
m_elab.consume_tc_cnstrs();
|
m_elab.consume_tc_cnstrs();
|
||||||
list<constraint> cs = to_list(m_elab.m_constraints.begin(), m_elab.m_constraints.end());
|
list<constraint> cs = to_list(m_elab.m_constraints.begin(), m_elab.m_constraints.end());
|
||||||
cs = cons(mk_eq_cnstr(m_mvar, r, j, m_relax_main_opaque), cs);
|
cs = cons(mk_eq_cnstr(m_mvar, r, justification(), m_relax_main_opaque), cs);
|
||||||
return optional<constraints>(cs);
|
return optional<constraints>(cs);
|
||||||
} catch (exception &) {}
|
} catch (exception &) {}
|
||||||
}
|
}
|
||||||
|
@ -451,12 +445,11 @@ class elaborator {
|
||||||
try {
|
try {
|
||||||
new_scope s(m_elab, m_ctx, m_full_ctx, m_subst);
|
new_scope s(m_elab, m_ctx, m_full_ctx, m_subst);
|
||||||
expr r = m_elab.visit(pre); // use elaborator to create metavariables, levels, etc.
|
expr r = m_elab.visit(pre); // use elaborator to create metavariables, levels, etc.
|
||||||
justification j = m_elab.m_accumulated;
|
|
||||||
m_elab.consume_tc_cnstrs();
|
m_elab.consume_tc_cnstrs();
|
||||||
for (auto & c : m_elab.m_constraints)
|
for (auto & c : m_elab.m_constraints)
|
||||||
c = update_justification(c, mk_composite1(m_jst, c.get_justification()));
|
c = update_justification(c, mk_composite1(m_jst, c.get_justification()));
|
||||||
list<constraint> cs = to_list(m_elab.m_constraints.begin(), m_elab.m_constraints.end());
|
list<constraint> cs = to_list(m_elab.m_constraints.begin(), m_elab.m_constraints.end());
|
||||||
cs = cons(mk_eq_cnstr(m_meta, r, mk_composite1(m_jst, j), m_relax_main_opaque), cs);
|
cs = cons(mk_eq_cnstr(m_meta, r, m_jst, m_relax_main_opaque), cs);
|
||||||
return optional<constraints>(cs);
|
return optional<constraints>(cs);
|
||||||
} catch (exception &) {
|
} catch (exception &) {
|
||||||
return optional<constraints>();
|
return optional<constraints>();
|
||||||
|
@ -551,52 +544,16 @@ public:
|
||||||
return m_tc[m_relax_main_opaque]->whnf(e);
|
return m_tc[m_relax_main_opaque]->whnf(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Clear constraint buffer \c m_constraints, and associated datastructures
|
/** \brief Clear constraint buffer \c m_constraints, and \c m_subst */
|
||||||
\c m_subst and \c m_accumulated.
|
|
||||||
|
|
||||||
\remark \c m_subst contains solutions obtained by eagerly solving the "easy" constraints
|
|
||||||
in \c m_subst, and \c m_accumulated store the justifications of all substitutions eagerly
|
|
||||||
applied.
|
|
||||||
*/
|
|
||||||
void clear_constraints() {
|
void clear_constraints() {
|
||||||
m_constraints.clear();
|
m_constraints.clear();
|
||||||
m_subst = substitution();
|
m_subst = substitution();
|
||||||
m_accumulated = justification();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_cnstr_core(constraint const & c) {
|
void add_cnstr(constraint const & c) {
|
||||||
m_constraints.push_back(c);
|
m_constraints.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Add \c c to \c m_constraints, but also tries to update \c m_subst using \c c.
|
|
||||||
The idea is to "populate" \c m_subst using easy/simple constraints.
|
|
||||||
This trick improves the number of places where coercions can be applied.
|
|
||||||
In the future, we may also use this information to implement eager pruning of choice
|
|
||||||
constraints.
|
|
||||||
|
|
||||||
\remark The justification \c m_accumulated is "appended" to \c c.
|
|
||||||
This justification justifies all substitutions used.
|
|
||||||
|
|
||||||
\remark By appeding \c m_accumulated we know we are not missing any dependency,
|
|
||||||
but this is a coarse approximation of that actual dependencies.
|
|
||||||
*/
|
|
||||||
void add_cnstr(constraint c) {
|
|
||||||
if (!m_accumulated.is_none())
|
|
||||||
c = update_justification(c, mk_composite1(c.get_justification(), m_accumulated));
|
|
||||||
add_cnstr_core(c);
|
|
||||||
if (unify_simple(m_subst, c) == unify_status::Failed)
|
|
||||||
throw unifier_exception(c.get_justification(), m_subst);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Eagerly instantiate metavars using \c m_subst.
|
|
||||||
\remark We update \c m_accumulated with any justifications used.
|
|
||||||
*/
|
|
||||||
expr instantiate_metavars(expr const & e) {
|
|
||||||
auto e_j = m_subst.instantiate_metavars(e);
|
|
||||||
m_accumulated = mk_composite1(m_accumulated, e_j.second);
|
|
||||||
return e_j.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static expr save_tag(expr && e, tag g) {
|
static expr save_tag(expr && e, tag g) {
|
||||||
e.set_tag(g);
|
e.set_tag(g);
|
||||||
return e;
|
return e;
|
||||||
|
@ -743,7 +700,7 @@ public:
|
||||||
if (!is_pi(f_type))
|
if (!is_pi(f_type))
|
||||||
f_type = whnf(f_type);
|
f_type = whnf(f_type);
|
||||||
if (!is_pi(f_type) && has_metavar(f_type)) {
|
if (!is_pi(f_type) && has_metavar(f_type)) {
|
||||||
f_type = whnf(instantiate_metavars(f_type));
|
f_type = whnf(f_type);
|
||||||
if (!is_pi(f_type) && is_meta(f_type)) {
|
if (!is_pi(f_type) && is_meta(f_type)) {
|
||||||
// let type checker add constraint
|
// let type checker add constraint
|
||||||
f_type = m_tc[m_relax_main_opaque]->ensure_pi(f_type, f);
|
f_type = m_tc[m_relax_main_opaque]->ensure_pi(f_type, f);
|
||||||
|
@ -824,7 +781,7 @@ public:
|
||||||
expr new_a = apply_coercion(a, a_type, expected_type);
|
expr new_a = apply_coercion(a, a_type, expected_type);
|
||||||
bool coercion_worked = false;
|
bool coercion_worked = false;
|
||||||
if (!is_eqp(a, new_a)) {
|
if (!is_eqp(a, new_a)) {
|
||||||
expr new_a_type = instantiate_metavars(infer_type(new_a));
|
expr new_a_type = infer_type(new_a);
|
||||||
coercion_worked = m_tc[relax]->is_def_eq(new_a_type, expected_type, j);
|
coercion_worked = m_tc[relax]->is_def_eq(new_a_type, expected_type, j);
|
||||||
}
|
}
|
||||||
if (coercion_worked) {
|
if (coercion_worked) {
|
||||||
|
@ -892,7 +849,7 @@ public:
|
||||||
}
|
}
|
||||||
expr d_type = binding_domain(f_type);
|
expr d_type = binding_domain(f_type);
|
||||||
expr a = visit_expecting_type_of(app_arg(e), d_type);
|
expr a = visit_expecting_type_of(app_arg(e), d_type);
|
||||||
expr a_type = instantiate_metavars(infer_type(a));
|
expr a_type = infer_type(a);
|
||||||
expr r = mk_app(f, a, e.get_tag());
|
expr r = mk_app(f, a, e.get_tag());
|
||||||
|
|
||||||
justification j = mk_app_justification(r, a, d_type, a_type);
|
justification j = mk_app_justification(r, a, d_type, a_type);
|
||||||
|
@ -979,7 +936,7 @@ public:
|
||||||
if (is_sort(t))
|
if (is_sort(t))
|
||||||
return e;
|
return e;
|
||||||
if (has_metavar(t)) {
|
if (has_metavar(t)) {
|
||||||
t = whnf(instantiate_metavars(t));
|
t = whnf(t);
|
||||||
if (is_sort(t))
|
if (is_sort(t))
|
||||||
return e;
|
return e;
|
||||||
if (is_meta(t)) {
|
if (is_meta(t)) {
|
||||||
|
|
Loading…
Reference in a new issue