fix(kernel/metavar): make sure the justification and substitution are always matching each other
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
2c6d4d2225
commit
7c8daf8974
4 changed files with 74 additions and 43 deletions
|
@ -141,9 +141,7 @@ justification metavar_env::get_justification(expr const & m) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
justification metavar_env::get_justification(name const & m) const {
|
justification metavar_env::get_justification(name const & m) const {
|
||||||
auto it = const_cast<metavar_env*>(this)->m_metavar_data.splay_find(m);
|
return get_subst_jst(m).second;
|
||||||
lean_assert(it);
|
|
||||||
return it->m_justification;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool metavar_env::is_assigned(name const & m) const {
|
bool metavar_env::is_assigned(name const & m) const {
|
||||||
|
@ -191,9 +189,22 @@ expr apply_local_context(expr const & a, local_context const & lctx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr metavar_env::get_subst(expr const & m) const {
|
std::pair<expr, justification> metavar_env::get_subst_jst(expr const & m) const {
|
||||||
lean_assert(is_metavar(m));
|
lean_assert(is_metavar(m));
|
||||||
auto it = const_cast<metavar_env*>(this)->m_metavar_data.splay_find(metavar_name(m));
|
auto p = get_subst_jst(metavar_name(m));
|
||||||
|
expr r = p.first;
|
||||||
|
if (p.first) {
|
||||||
|
local_context const & lctx = metavar_lctx(m);
|
||||||
|
if (lctx)
|
||||||
|
r = apply_local_context(r, lctx);
|
||||||
|
return mk_pair(r, p.second);
|
||||||
|
} else {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<expr, justification> metavar_env::get_subst_jst(name const & m) const {
|
||||||
|
auto it = const_cast<metavar_env*>(this)->m_metavar_data.splay_find(m);
|
||||||
if (it->m_subst) {
|
if (it->m_subst) {
|
||||||
if (has_assigned_metavar(it->m_subst, *this)) {
|
if (has_assigned_metavar(it->m_subst, *this)) {
|
||||||
buffer<justification> jsts;
|
buffer<justification> jsts;
|
||||||
|
@ -204,16 +215,16 @@ expr metavar_env::get_subst(expr const & m) const {
|
||||||
it->m_subst = new_subst;
|
it->m_subst = new_subst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
local_context const & lctx = metavar_lctx(m);
|
return mk_pair(it->m_subst, it->m_justification);
|
||||||
expr r = it->m_subst;
|
|
||||||
if (lctx)
|
|
||||||
r = apply_local_context(r, lctx);
|
|
||||||
return r;
|
|
||||||
} else {
|
} else {
|
||||||
return expr();
|
return mk_pair(expr(), justification());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr metavar_env::get_subst(expr const & m) const {
|
||||||
|
return get_subst_jst(m).first;
|
||||||
|
}
|
||||||
|
|
||||||
class instantiate_metavars_proc : public replace_visitor {
|
class instantiate_metavars_proc : public replace_visitor {
|
||||||
protected:
|
protected:
|
||||||
metavar_env const & m_menv;
|
metavar_env const & m_menv;
|
||||||
|
@ -226,8 +237,9 @@ protected:
|
||||||
|
|
||||||
virtual expr visit_metavar(expr const & m, context const & ctx) {
|
virtual expr visit_metavar(expr const & m, context const & ctx) {
|
||||||
if (is_metavar(m) && m_menv.is_assigned(m)) {
|
if (is_metavar(m) && m_menv.is_assigned(m)) {
|
||||||
push_back(m_menv.get_justification(m));
|
auto p = m_menv.get_subst_jst(m);
|
||||||
expr r = m_menv.get_subst(m);
|
expr r = p.first;
|
||||||
|
push_back(p.second);
|
||||||
if (has_assigned_metavar(r, m_menv)) {
|
if (has_assigned_metavar(r, m_menv)) {
|
||||||
return visit(r, ctx);
|
return visit(r, ctx);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -91,6 +91,15 @@ public:
|
||||||
bool has_type(expr const & m) const;
|
bool has_type(expr const & m) const;
|
||||||
bool has_type(name const & m) const;
|
bool has_type(name const & m) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Return the substitution and justification for the given metavariable.
|
||||||
|
|
||||||
|
If the metavariable is not assigned in this substitution, then it returns the null
|
||||||
|
expression.
|
||||||
|
*/
|
||||||
|
std::pair<expr, justification> get_subst_jst(name const & m) const;
|
||||||
|
std::pair<expr, justification> get_subst_jst(expr const & m) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return the justification for an assigned metavariable.
|
\brief Return the justification for an assigned metavariable.
|
||||||
\pre is_metavar(m)
|
\pre is_metavar(m)
|
||||||
|
|
|
@ -184,18 +184,11 @@ class elaborator::imp {
|
||||||
return m_state.m_menv.is_assigned(m);
|
return m_state.m_menv.is_assigned(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Return the substitution for an assigned metavariable */
|
/** \brief Return the substitution (and justification) for an assigned metavariable */
|
||||||
expr get_mvar_subst(expr const & m) const {
|
std::pair<expr, justification> get_subst_jst(expr const & m) const {
|
||||||
lean_assert(is_metavar(m));
|
lean_assert(is_metavar(m));
|
||||||
lean_assert(is_assigned(m));
|
lean_assert(is_assigned(m));
|
||||||
return m_state.m_menv.get_subst(m);
|
return m_state.m_menv.get_subst_jst(m);
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Return the justification/justification for an assigned metavariable */
|
|
||||||
justification get_mvar_justification(expr const & m) const {
|
|
||||||
lean_assert(is_metavar(m));
|
|
||||||
lean_assert(is_assigned(m));
|
|
||||||
return m_state.m_menv.get_justification(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Return the type of an metavariable */
|
/** \brief Return the type of an metavariable */
|
||||||
|
@ -396,8 +389,9 @@ class elaborator::imp {
|
||||||
if (is_metavar(a)) {
|
if (is_metavar(a)) {
|
||||||
if (is_assigned(a)) {
|
if (is_assigned(a)) {
|
||||||
// Case 1
|
// Case 1
|
||||||
justification new_jst(new substitution_justification(c, get_mvar_justification(a)));
|
auto s_j = get_subst_jst(a);
|
||||||
push_updated_constraint(c, is_lhs, get_mvar_subst(a), new_jst);
|
justification new_jst(new substitution_justification(c, s_j.second));
|
||||||
|
push_updated_constraint(c, is_lhs, s_j.first, new_jst);
|
||||||
return Processed;
|
return Processed;
|
||||||
} else if (!has_local_context(a)) {
|
} else if (!has_local_context(a)) {
|
||||||
// Case 2
|
// Case 2
|
||||||
|
@ -433,8 +427,9 @@ class elaborator::imp {
|
||||||
|
|
||||||
if (is_app(a) && is_metavar(arg(a, 0)) && is_assigned(arg(a, 0))) {
|
if (is_app(a) && is_metavar(arg(a, 0)) && is_assigned(arg(a, 0))) {
|
||||||
// Case 4
|
// Case 4
|
||||||
justification new_jst(new substitution_justification(c, get_mvar_justification(arg(a, 0))));
|
auto s_j = get_subst_jst(arg(a, 0));
|
||||||
expr new_f = get_mvar_subst(arg(a, 0));
|
justification new_jst(new substitution_justification(c, s_j.second));
|
||||||
|
expr new_f = s_j.first;
|
||||||
expr new_a = update_app(a, 0, new_f);
|
expr new_a = update_app(a, 0, new_f);
|
||||||
if (m_state.m_menv.beta_reduce_metavar_application())
|
if (m_state.m_menv.beta_reduce_metavar_application())
|
||||||
new_a = head_beta_reduce(new_a);
|
new_a = head_beta_reduce(new_a);
|
||||||
|
|
|
@ -608,22 +608,37 @@ a : Bool, b : Bool, H : ?M3::2, H_na : ?M3::7 ⊢ a ≺ if Bool (if Bool a b ⊤
|
||||||
?M3::11
|
?M3::11
|
||||||
H
|
H
|
||||||
H_na
|
H_na
|
||||||
Assignment
|
Normalize assignment
|
||||||
a : Bool, b : Bool ⊢ ?M3::2 ≈ ?M3::0
|
?M3::0
|
||||||
Destruct/Decompose
|
Assignment
|
||||||
a : Bool,
|
a : Bool, b : Bool ⊢ ?M3::2 ≈ ?M3::0
|
||||||
b : Bool ⊢
|
Destruct/Decompose
|
||||||
Π H : ?M3::2, ?M3::5 ≺ Π _ : ?M3::0, ?M3::1[lift:0:1]
|
a : Bool,
|
||||||
(line: 27: pos: 4) Type of argument 3 must be convertible to the expected type in the application of
|
b : Bool ⊢
|
||||||
Discharge::explicit
|
Π H : ?M3::2, ?M3::5 ≺ Π _ : ?M3::0, ?M3::1[lift:0:1]
|
||||||
with arguments:
|
(line: 27: pos: 4) Type of argument 3 must be convertible to the expected type in the application of
|
||||||
?M3::0
|
Discharge::explicit
|
||||||
?M3::1
|
with arguments:
|
||||||
λ H : ?M3::2,
|
?M3::0
|
||||||
DisjCases
|
?M3::1
|
||||||
(EM a)
|
λ H : ?M3::2,
|
||||||
(λ H_a : ?M3::6, H)
|
DisjCases
|
||||||
(λ H_na : ?M3::7, NotImp1 (MT H H_na))
|
(EM a)
|
||||||
|
(λ H_a : ?M3::6, H)
|
||||||
|
(λ H_na : ?M3::7, NotImp1 (MT H H_na))
|
||||||
|
Assignment
|
||||||
|
a : Bool, b : Bool ⊢ ?M3::0 ≈ (a ⇒ b) ⇒ a
|
||||||
|
Destruct/Decompose
|
||||||
|
a : Bool, b : Bool ⊢ ?M3::0 ⇒ ?M3::1 ≺ ((a ⇒ b) ⇒ a) ⇒ a
|
||||||
|
Destruct/Decompose
|
||||||
|
a : Bool ⊢
|
||||||
|
Π b : Bool, ?M3::0 ⇒ ?M3::1 ≺
|
||||||
|
Π b : Bool, ((a ⇒ b) ⇒ a) ⇒ a
|
||||||
|
Destruct/Decompose
|
||||||
|
⊢
|
||||||
|
Π a b : Bool, ?M3::0 ⇒ ?M3::1 ≺
|
||||||
|
Π a b : Bool, ((a ⇒ b) ⇒ a) ⇒ a
|
||||||
|
(line: 26: pos: 16) Type of definition 'pierce' must be convertible to expected type.
|
||||||
Assignment
|
Assignment
|
||||||
a : Bool, b : Bool, H : ?M3::2, H_na : ?M3::7 ⊢ ?M3::10 ≈ ?M3::8 ⇒ ?M3::9
|
a : Bool, b : Bool, H : ?M3::2, H_na : ?M3::7 ⊢ ?M3::10 ≈ ?M3::8 ⇒ ?M3::9
|
||||||
Destruct/Decompose
|
Destruct/Decompose
|
||||||
|
|
Loading…
Reference in a new issue