feat(library/type_context): allow nested tmp modes
TODO: The tmp_type_context class is obsolete after this change. We should remove it.
This commit is contained in:
parent
11dcab1b31
commit
65bc3ca1eb
2 changed files with 94 additions and 105 deletions
|
|
@ -267,8 +267,7 @@ void type_context::init_core(transparency_mode m) {
|
||||||
m_transparency_mode = m;
|
m_transparency_mode = m;
|
||||||
m_in_is_def_eq = false;
|
m_in_is_def_eq = false;
|
||||||
m_is_def_eq_depth = 0;
|
m_is_def_eq_depth = 0;
|
||||||
m_tmp_uassignment = nullptr;
|
m_tmp_data = nullptr;
|
||||||
m_tmp_eassignment = nullptr;
|
|
||||||
m_unfold_pred = nullptr;
|
m_unfold_pred = nullptr;
|
||||||
m_transparency_pred = nullptr;
|
m_transparency_pred = nullptr;
|
||||||
m_approximate = false;
|
m_approximate = false;
|
||||||
|
|
@ -704,8 +703,8 @@ expr type_context::whnf_core(expr const & e) {
|
||||||
} else if (is_idx_metavar(e)) {
|
} else if (is_idx_metavar(e)) {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
unsigned idx = to_meta_idx(e);
|
unsigned idx = to_meta_idx(e);
|
||||||
if (idx < m_tmp_eassignment->size()) {
|
if (idx < m_tmp_data->m_eassignment.size()) {
|
||||||
if (auto v = (*m_tmp_eassignment)[idx]) {
|
if (auto v = m_tmp_data->m_eassignment[idx]) {
|
||||||
m_used_assignment = true;
|
m_used_assignment = true;
|
||||||
return whnf_core(*v);
|
return whnf_core(*v);
|
||||||
}
|
}
|
||||||
|
|
@ -1120,39 +1119,24 @@ bool type_context::is_proof(expr const & e) {
|
||||||
/* -------------------------------
|
/* -------------------------------
|
||||||
Temporary assignment mode support
|
Temporary assignment mode support
|
||||||
------------------------------- */
|
------------------------------- */
|
||||||
void type_context::set_tmp_mode(buffer<optional<level>> & tmp_uassignment, buffer<optional<expr>> & tmp_eassignment) {
|
|
||||||
lean_assert(!in_tmp_mode());
|
|
||||||
lean_assert(m_tmp_trail.empty());
|
|
||||||
m_tmp_mvar_lctx = m_lctx;
|
|
||||||
m_tmp_uassignment = &tmp_uassignment;
|
|
||||||
m_tmp_eassignment = &tmp_eassignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
void type_context::reset_tmp_mode() {
|
|
||||||
lean_trace(name({"type_context", "tmp_vars"}), tout() << "clear tmp vars\n";);
|
|
||||||
m_tmp_trail.clear();
|
|
||||||
m_tmp_uassignment = nullptr;
|
|
||||||
m_tmp_eassignment = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void type_context::ensure_num_tmp_mvars(unsigned num_uvars, unsigned num_mvars) {
|
void type_context::ensure_num_tmp_mvars(unsigned num_uvars, unsigned num_mvars) {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
if (m_tmp_uassignment->size() < num_uvars)
|
if (m_tmp_data->m_uassignment.size() < num_uvars)
|
||||||
m_tmp_uassignment->resize(num_uvars, none_level());
|
m_tmp_data->m_uassignment.resize(num_uvars, none_level());
|
||||||
if (m_tmp_eassignment->size() < num_mvars)
|
if (m_tmp_data->m_eassignment.size() < num_mvars)
|
||||||
m_tmp_eassignment->resize(num_mvars, none_expr());
|
m_tmp_data->m_eassignment.resize(num_mvars, none_expr());
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<level> type_context::get_tmp_uvar_assignment(unsigned idx) const {
|
optional<level> type_context::get_tmp_uvar_assignment(unsigned idx) const {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
lean_assert(idx < m_tmp_uassignment->size());
|
lean_assert(idx < m_tmp_data->m_uassignment.size());
|
||||||
return (*m_tmp_uassignment)[idx];
|
return m_tmp_data->m_uassignment[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<expr> type_context::get_tmp_mvar_assignment(unsigned idx) const {
|
optional<expr> type_context::get_tmp_mvar_assignment(unsigned idx) const {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
lean_assert(idx < m_tmp_eassignment->size());
|
lean_assert(idx < m_tmp_data->m_eassignment.size());
|
||||||
return (*m_tmp_eassignment)[idx];
|
return m_tmp_data->m_eassignment[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<level> type_context::get_tmp_assignment(level const & l) const {
|
optional<level> type_context::get_tmp_assignment(level const & l) const {
|
||||||
|
|
@ -1168,44 +1152,44 @@ optional<expr> type_context::get_tmp_assignment(expr const & e) const {
|
||||||
void type_context::assign_tmp(level const & u, level const & l) {
|
void type_context::assign_tmp(level const & u, level const & l) {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
lean_assert(is_idx_metauniv(u));
|
lean_assert(is_idx_metauniv(u));
|
||||||
lean_assert(to_meta_idx(u) < m_tmp_uassignment->size());
|
lean_assert(to_meta_idx(u) < m_tmp_data->m_uassignment.size());
|
||||||
unsigned idx = to_meta_idx(u);
|
unsigned idx = to_meta_idx(u);
|
||||||
if (!m_scopes.empty() && !(*m_tmp_uassignment)[idx]) {
|
if (!m_scopes.empty() && !m_tmp_data->m_uassignment[idx]) {
|
||||||
m_tmp_trail.emplace_back(tmp_trail_kind::Level, idx);
|
m_tmp_data->m_trail.emplace_back(tmp_trail_kind::Level, idx);
|
||||||
}
|
}
|
||||||
(*m_tmp_uassignment)[idx] = l;
|
m_tmp_data->m_uassignment[idx] = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_context::assign_tmp(expr const & m, expr const & v) {
|
void type_context::assign_tmp(expr const & m, expr const & v) {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
lean_assert(is_idx_metavar(m));
|
lean_assert(is_idx_metavar(m));
|
||||||
lean_assert(to_meta_idx(m) < m_tmp_eassignment->size());
|
lean_assert(to_meta_idx(m) < m_tmp_data->m_eassignment.size());
|
||||||
unsigned idx = to_meta_idx(m);
|
unsigned idx = to_meta_idx(m);
|
||||||
lean_trace(name({"type_context", "tmp_vars"}),
|
lean_trace(name({"type_context", "tmp_vars"}),
|
||||||
tout() << "assign ?x_" << idx << " := " << v << "\n";);
|
tout() << "assign ?x_" << idx << " := " << v << "\n";);
|
||||||
if (!m_scopes.empty() && !(*m_tmp_eassignment)[idx]) {
|
if (!m_scopes.empty() && !m_tmp_data->m_eassignment[idx]) {
|
||||||
m_tmp_trail.emplace_back(tmp_trail_kind::Expr, idx);
|
m_tmp_data->m_trail.emplace_back(tmp_trail_kind::Expr, idx);
|
||||||
}
|
}
|
||||||
(*m_tmp_eassignment)[to_meta_idx(m)] = v;
|
m_tmp_data->m_eassignment[to_meta_idx(m)] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
level type_context::mk_tmp_univ_mvar() {
|
level type_context::mk_tmp_univ_mvar() {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
unsigned idx = m_tmp_uassignment->size();
|
unsigned idx = m_tmp_data->m_uassignment.size();
|
||||||
m_tmp_uassignment->push_back(none_level());
|
m_tmp_data->m_uassignment.push_back(none_level());
|
||||||
return mk_idx_metauniv(idx);
|
return mk_idx_metauniv(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr type_context::mk_tmp_mvar(expr const & type) {
|
expr type_context::mk_tmp_mvar(expr const & type) {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
unsigned idx = m_tmp_eassignment->size();
|
unsigned idx = m_tmp_data->m_eassignment.size();
|
||||||
m_tmp_eassignment->push_back(none_expr());
|
m_tmp_data->m_eassignment.push_back(none_expr());
|
||||||
return mk_idx_metavar(idx, type);
|
return mk_idx_metavar(idx, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_context::clear_tmp_eassignment() {
|
void type_context::clear_tmp_eassignment() {
|
||||||
lean_assert(in_tmp_mode());
|
lean_assert(in_tmp_mode());
|
||||||
m_tmp_eassignment->clear();
|
m_tmp_data->m_eassignment.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------
|
/* -----------------------------------
|
||||||
|
|
@ -1302,7 +1286,7 @@ expr type_context::instantiate_mvars(expr const & e, bool postpone_push_delayed)
|
||||||
|
|
||||||
void type_context::push_scope() {
|
void type_context::push_scope() {
|
||||||
if (in_tmp_mode()) {
|
if (in_tmp_mode()) {
|
||||||
m_scopes.emplace_back(m_mctx, m_tmp_uassignment->size(), m_tmp_eassignment->size(), m_tmp_trail.size());
|
m_scopes.emplace_back(m_mctx, m_tmp_data->m_uassignment.size(), m_tmp_data->m_eassignment.size(), m_tmp_data->m_trail.size());
|
||||||
} else {
|
} else {
|
||||||
m_scopes.emplace_back(m_mctx, 0, 0, 0);
|
m_scopes.emplace_back(m_mctx, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -1314,20 +1298,20 @@ void type_context::pop_scope() {
|
||||||
m_mctx = s.m_mctx;
|
m_mctx = s.m_mctx;
|
||||||
if (in_tmp_mode()) {
|
if (in_tmp_mode()) {
|
||||||
unsigned old_sz = s.m_tmp_trail_sz;
|
unsigned old_sz = s.m_tmp_trail_sz;
|
||||||
while (m_tmp_trail.size() > old_sz) {
|
while (m_tmp_data->m_trail.size() > old_sz) {
|
||||||
auto const & t = m_tmp_trail.back();
|
auto const & t = m_tmp_data->m_trail.back();
|
||||||
if (t.first == tmp_trail_kind::Level) {
|
if (t.first == tmp_trail_kind::Level) {
|
||||||
(*m_tmp_uassignment)[t.second] = none_level();
|
m_tmp_data->m_uassignment[t.second] = none_level();
|
||||||
} else {
|
} else {
|
||||||
lean_trace(name({"type_context", "tmp_vars"}),
|
lean_trace(name({"type_context", "tmp_vars"}),
|
||||||
tout() << "unassign ?x_" << t.second << " := " << *((*m_tmp_eassignment)[t.second]) << "\n";);
|
tout() << "unassign ?x_" << t.second << " := " << *(m_tmp_data->m_eassignment[t.second]) << "\n";);
|
||||||
(*m_tmp_eassignment)[t.second] = none_expr();
|
m_tmp_data->m_eassignment[t.second] = none_expr();
|
||||||
}
|
}
|
||||||
m_tmp_trail.pop_back();
|
m_tmp_data->m_trail.pop_back();
|
||||||
}
|
}
|
||||||
lean_assert(old_sz == m_tmp_trail.size());
|
lean_assert(old_sz == m_tmp_data->m_trail.size());
|
||||||
m_tmp_uassignment->shrink(s.m_tmp_uassignment_sz);
|
m_tmp_data->m_uassignment.shrink(s.m_tmp_uassignment_sz);
|
||||||
m_tmp_eassignment->shrink(s.m_tmp_eassignment_sz);
|
m_tmp_data->m_eassignment.shrink(s.m_tmp_eassignment_sz);
|
||||||
}
|
}
|
||||||
m_scopes.pop_back();
|
m_scopes.pop_back();
|
||||||
}
|
}
|
||||||
|
|
@ -1776,7 +1760,7 @@ bool type_context::process_assignment(expr const & m, expr const & v) {
|
||||||
The code is slightly different for tmp mode because the metavariables
|
The code is slightly different for tmp mode because the metavariables
|
||||||
do not store their local context. */
|
do not store their local context. */
|
||||||
if (in_tmp_mode()) {
|
if (in_tmp_mode()) {
|
||||||
if (m_tmp_mvar_lctx.find_local_decl(arg)) {
|
if (m_tmp_data->m_mvar_lctx.find_local_decl(arg)) {
|
||||||
/* m is of the form (?M@C ... l ...) where l is a local constant in C */
|
/* m is of the form (?M@C ... l ...) where l is a local constant in C */
|
||||||
if (!approximate())
|
if (!approximate())
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1955,7 +1939,7 @@ struct check_assignment_fn : public replace_visitor {
|
||||||
|
|
||||||
bool in_ctx;
|
bool in_ctx;
|
||||||
if (m_ctx.in_tmp_mode()) {
|
if (m_ctx.in_tmp_mode()) {
|
||||||
in_ctx = static_cast<bool>(m_ctx.m_tmp_mvar_lctx.find_local_decl(e));
|
in_ctx = static_cast<bool>(m_ctx.m_tmp_data->m_mvar_lctx.find_local_decl(e));
|
||||||
} else {
|
} else {
|
||||||
in_ctx = static_cast<bool>(m_mvar_decl->get_context().find_local_decl(e));
|
in_ctx = static_cast<bool>(m_mvar_decl->get_context().find_local_decl(e));
|
||||||
}
|
}
|
||||||
|
|
@ -3215,12 +3199,12 @@ struct instance_synthesizer {
|
||||||
environment const & env() const { return m_ctx.env(); }
|
environment const & env() const { return m_ctx.env(); }
|
||||||
|
|
||||||
void push_scope() {
|
void push_scope() {
|
||||||
lean_trace(name({"type_context", "tmp_vars"}), tout() << "push_scope, trail_sz: " << m_ctx.m_tmp_trail.size() << "\n";);
|
lean_trace(name({"type_context", "tmp_vars"}), tout() << "push_scope, trail_sz: " << m_ctx.m_tmp_data->m_trail.size() << "\n";);
|
||||||
m_ctx.push_scope();
|
m_ctx.push_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_scope() {
|
void pop_scope() {
|
||||||
lean_trace(name({"type_context", "tmp_vars"}), tout() << "pop_scope, trail_sz: " << m_ctx.m_tmp_trail.size() << "\n";);
|
lean_trace(name({"type_context", "tmp_vars"}), tout() << "pop_scope, trail_sz: " << m_ctx.m_tmp_data->m_trail.size() << "\n";);
|
||||||
m_ctx.pop_scope();
|
m_ctx.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3647,33 +3631,34 @@ expr type_context::eta_expand(expr const & e) {
|
||||||
return locals.mk_lambda(r);
|
return locals.mk_lambda(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_type_context::tmp_type_context(type_context & ctx, unsigned num_umeta, unsigned num_emeta): m_ctx(ctx) {
|
tmp_type_context::tmp_type_context(type_context & ctx, unsigned num_umeta, unsigned num_emeta):
|
||||||
|
m_ctx(ctx), m_tmp_data(m_tmp_uassignment, m_tmp_eassignment, ctx.lctx()) {
|
||||||
m_tmp_uassignment.resize(num_umeta, none_level());
|
m_tmp_uassignment.resize(num_umeta, none_level());
|
||||||
m_tmp_eassignment.resize(num_emeta, none_expr());
|
m_tmp_eassignment.resize(num_emeta, none_expr());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tmp_type_context::is_def_eq(expr const & e1, expr const & e2) {
|
bool tmp_type_context::is_def_eq(expr const & e1, expr const & e2) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.is_def_eq(e1, e2);
|
return m_ctx.is_def_eq(e1, e2);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::infer(expr const & e) {
|
expr tmp_type_context::infer(expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.infer(e);
|
return m_ctx.infer(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::whnf(expr const & e) {
|
expr tmp_type_context::whnf(expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.whnf(e);
|
return m_ctx.whnf(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
level tmp_type_context::mk_tmp_univ_mvar() {
|
level tmp_type_context::mk_tmp_univ_mvar() {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_tmp_univ_mvar();
|
return m_ctx.mk_tmp_univ_mvar();
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::mk_tmp_mvar(expr const & type) {
|
expr tmp_type_context::mk_tmp_mvar(expr const & type) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_tmp_mvar(type);
|
return m_ctx.mk_tmp_mvar(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3692,47 +3677,47 @@ void tmp_type_context::clear_eassignment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::instantiate_mvars(expr const & e) {
|
expr tmp_type_context::instantiate_mvars(expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.instantiate_mvars(e);
|
return m_ctx.instantiate_mvars(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tmp_type_context::assign(expr const & m, expr const & v) {
|
void tmp_type_context::assign(expr const & m, expr const & v) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
m_ctx.assign(m, v);
|
m_ctx.assign(m, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::mk_lambda(buffer<expr> const & locals, expr const & e) {
|
expr tmp_type_context::mk_lambda(buffer<expr> const & locals, expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_lambda(locals, e);
|
return m_ctx.mk_lambda(locals, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::mk_pi(buffer<expr> const & locals, expr const & e) {
|
expr tmp_type_context::mk_pi(buffer<expr> const & locals, expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_pi(locals, e);
|
return m_ctx.mk_pi(locals, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::mk_lambda(expr const & local, expr const & e) {
|
expr tmp_type_context::mk_lambda(expr const & local, expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_lambda(local, e);
|
return m_ctx.mk_lambda(local, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::mk_pi(expr const & local, expr const & e) {
|
expr tmp_type_context::mk_pi(expr const & local, expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_pi(local, e);
|
return m_ctx.mk_pi(local, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::mk_lambda(std::initializer_list<expr> const & locals, expr const & e) {
|
expr tmp_type_context::mk_lambda(std::initializer_list<expr> const & locals, expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_lambda(locals, e);
|
return m_ctx.mk_lambda(locals, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr tmp_type_context::mk_pi(std::initializer_list<expr> const & locals, expr const & e) {
|
expr tmp_type_context::mk_pi(std::initializer_list<expr> const & locals, expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.mk_pi(locals, e);
|
return m_ctx.mk_pi(locals, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tmp_type_context::is_prop(expr const & e) {
|
bool tmp_type_context::is_prop(expr const & e) {
|
||||||
type_context::tmp_mode_scope_with_buffers tmp_scope(m_ctx, m_tmp_uassignment, m_tmp_eassignment);
|
type_context::tmp_mode_scope_with_data tmp_scope(m_ctx, m_tmp_data);
|
||||||
return m_ctx.is_prop(e);
|
return m_ctx.is_prop(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,28 @@ class type_context : public abstract_type_context {
|
||||||
scope_data(metavar_context const & mctx, unsigned usz, unsigned esz, unsigned tsz):
|
scope_data(metavar_context const & mctx, unsigned usz, unsigned esz, unsigned tsz):
|
||||||
m_mctx(mctx), m_tmp_uassignment_sz(usz), m_tmp_eassignment_sz(esz), m_tmp_trail_sz(tsz) {}
|
m_mctx(mctx), m_tmp_uassignment_sz(usz), m_tmp_eassignment_sz(esz), m_tmp_trail_sz(tsz) {}
|
||||||
};
|
};
|
||||||
|
friend class tmp_type_context;
|
||||||
|
/* This class supports temporary meta-variables "mode". In this "tmp" mode,
|
||||||
|
is_metavar_decl_ref and is_univ_metavar_decl_ref are treated as opaque constants,
|
||||||
|
and temporary metavariables (idx_metavar) are treated as metavariables,
|
||||||
|
and their assignment is stored at m_tmp_eassignment and m_tmp_uassignment.
|
||||||
|
|
||||||
|
m_tmp_eassignment and m_tmp_uassignment store assignment for temporary/idx metavars
|
||||||
|
|
||||||
|
These assignments are only used during type class resolution and matching operations.
|
||||||
|
They are references to stack allocated buffers provided by customers.
|
||||||
|
They are nullptr if type_context is not in tmp_mode. */
|
||||||
|
struct tmp_data {
|
||||||
|
tmp_uassignment & m_uassignment;
|
||||||
|
tmp_eassignment & m_eassignment;
|
||||||
|
/* m_tmp_mvar_local_context contains m_lctx when tmp mode is activated.
|
||||||
|
This is the context for all temporary meta-variables. */
|
||||||
|
local_context m_mvar_lctx;
|
||||||
|
/* undo/trail stack for m_tmp_uassignment/m_tmp_eassignment */
|
||||||
|
tmp_trail m_trail;
|
||||||
|
tmp_data(tmp_uassignment & uassignment, tmp_eassignment & eassignment, local_context const & lctx):
|
||||||
|
m_uassignment(uassignment), m_eassignment(eassignment), m_mvar_lctx(lctx) {}
|
||||||
|
};
|
||||||
typedef buffer<scope_data> scopes;
|
typedef buffer<scope_data> scopes;
|
||||||
typedef list<pair<name, expr>> local_instances;
|
typedef list<pair<name, expr>> local_instances;
|
||||||
metavar_context m_mctx;
|
metavar_context m_mctx;
|
||||||
|
|
@ -201,26 +223,9 @@ class type_context : public abstract_type_context {
|
||||||
bool m_in_is_def_eq;
|
bool m_in_is_def_eq;
|
||||||
/* m_is_def_eq_depth is only used for tracing purposes */
|
/* m_is_def_eq_depth is only used for tracing purposes */
|
||||||
unsigned m_is_def_eq_depth;
|
unsigned m_is_def_eq_depth;
|
||||||
/* This class supports temporary meta-variables "mode". In this "tmp" mode,
|
|
||||||
is_metavar_decl_ref and is_univ_metavar_decl_ref are treated as opaque constants,
|
|
||||||
and temporary metavariables (idx_metavar) are treated as metavariables,
|
|
||||||
and their assignment is stored at m_tmp_eassignment and m_tmp_uassignment.
|
|
||||||
|
|
||||||
m_tmp_eassignment and m_tmp_uassignment store assignment for temporary/idx metavars
|
|
||||||
|
|
||||||
These assignments are only used during type class resolution and matching operations.
|
|
||||||
They are references to stack allocated buffers provided by customers.
|
|
||||||
They are nullptr if type_context is not in tmp_mode. */
|
|
||||||
tmp_eassignment * m_tmp_eassignment;
|
|
||||||
tmp_uassignment * m_tmp_uassignment;
|
|
||||||
/* m_tmp_mvar_local_context contains m_lctx when tmp mode is activated.
|
|
||||||
This is the context for all temporary meta-variables. */
|
|
||||||
local_context m_tmp_mvar_lctx;
|
|
||||||
/* undo/trail stack for m_tmp_uassignment/m_tmp_eassignment */
|
|
||||||
tmp_trail m_tmp_trail;
|
|
||||||
/* Stack of backtracking point (aka scope) */
|
/* Stack of backtracking point (aka scope) */
|
||||||
scopes m_scopes;
|
scopes m_scopes;
|
||||||
|
tmp_data * m_tmp_data;
|
||||||
/* If m_approximate == true, then enable approximate higher-order unification
|
/* If m_approximate == true, then enable approximate higher-order unification
|
||||||
even if we are not in tmp_mode */
|
even if we are not in tmp_mode */
|
||||||
bool m_approximate;
|
bool m_approximate;
|
||||||
|
|
@ -469,36 +474,35 @@ public:
|
||||||
Temporary assignment mode.
|
Temporary assignment mode.
|
||||||
It is used when performing type class resolution and matching.
|
It is used when performing type class resolution and matching.
|
||||||
-------------------------- */
|
-------------------------- */
|
||||||
private:
|
|
||||||
void set_tmp_mode(buffer<optional<level>> & tmp_uassignment, buffer<optional<expr>> & tmp_eassignment);
|
|
||||||
void reset_tmp_mode();
|
|
||||||
public:
|
public:
|
||||||
struct tmp_mode_scope {
|
struct tmp_mode_scope {
|
||||||
type_context & m_ctx;
|
type_context & m_ctx;
|
||||||
buffer<optional<level>> m_tmp_uassignment;
|
buffer<optional<level>> m_tmp_uassignment;
|
||||||
buffer<optional<expr>> m_tmp_eassignment;
|
buffer<optional<expr>> m_tmp_eassignment;
|
||||||
tmp_mode_scope(type_context & ctx, unsigned next_uidx = 0, unsigned next_midx = 0):m_ctx(ctx) {
|
tmp_data * m_old_data;
|
||||||
|
tmp_data m_data;
|
||||||
|
tmp_mode_scope(type_context & ctx, unsigned next_uidx = 0, unsigned next_midx = 0):
|
||||||
|
m_ctx(ctx), m_old_data(ctx.m_tmp_data), m_data(m_tmp_uassignment, m_tmp_eassignment, ctx.lctx()) {
|
||||||
m_tmp_uassignment.resize(next_uidx, none_level());
|
m_tmp_uassignment.resize(next_uidx, none_level());
|
||||||
m_tmp_eassignment.resize(next_midx, none_expr());
|
m_tmp_eassignment.resize(next_midx, none_expr());
|
||||||
m_ctx.set_tmp_mode(m_tmp_uassignment, m_tmp_eassignment);
|
m_ctx.m_tmp_data = &m_data;
|
||||||
}
|
}
|
||||||
~tmp_mode_scope() {
|
~tmp_mode_scope() {
|
||||||
m_ctx.reset_tmp_mode();
|
m_ctx.m_tmp_data = m_old_data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct tmp_mode_scope_with_buffers {
|
struct tmp_mode_scope_with_data {
|
||||||
type_context & m_ctx;
|
type_context & m_ctx;
|
||||||
tmp_mode_scope_with_buffers(type_context & ctx,
|
tmp_data * m_old_data;
|
||||||
buffer<optional<level>> & tmp_uassignment,
|
tmp_mode_scope_with_data(type_context & ctx, tmp_data & data):
|
||||||
buffer<optional<expr>> & tmp_eassignment):
|
m_ctx(ctx), m_old_data(ctx.m_tmp_data) {
|
||||||
m_ctx(ctx) {
|
m_ctx.m_tmp_data = &data;
|
||||||
m_ctx.set_tmp_mode(tmp_uassignment, tmp_eassignment);
|
|
||||||
}
|
}
|
||||||
~tmp_mode_scope_with_buffers() {
|
~tmp_mode_scope_with_data() {
|
||||||
m_ctx.reset_tmp_mode();
|
m_ctx.m_tmp_data = m_old_data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
bool in_tmp_mode() const { return m_tmp_uassignment != nullptr; }
|
bool in_tmp_mode() const { return m_tmp_data != nullptr; }
|
||||||
void ensure_num_tmp_mvars(unsigned num_uvars, unsigned num_mvars);
|
void ensure_num_tmp_mvars(unsigned num_uvars, unsigned num_mvars);
|
||||||
optional<level> get_tmp_uvar_assignment(unsigned idx) const;
|
optional<level> get_tmp_uvar_assignment(unsigned idx) const;
|
||||||
optional<expr> get_tmp_mvar_assignment(unsigned idx) const;
|
optional<expr> get_tmp_mvar_assignment(unsigned idx) const;
|
||||||
|
|
@ -716,10 +720,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
class tmp_type_context : public abstract_type_context {
|
class tmp_type_context : public abstract_type_context {
|
||||||
type_context & m_ctx;
|
type_context & m_ctx;
|
||||||
buffer<optional<level>> m_tmp_uassignment;
|
buffer<optional<level>> m_tmp_uassignment;
|
||||||
buffer<optional<expr>> m_tmp_eassignment;
|
buffer<optional<expr>> m_tmp_eassignment;
|
||||||
|
type_context::tmp_data m_tmp_data;
|
||||||
public:
|
public:
|
||||||
tmp_type_context(type_context & ctx, unsigned num_umeta = 0, unsigned num_emeta = 0);
|
tmp_type_context(type_context & ctx, unsigned num_umeta = 0, unsigned num_emeta = 0);
|
||||||
type_context & ctx() const { return m_ctx; }
|
type_context & ctx() const { return m_ctx; }
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue