feat(library/data/expr): add support for regular local constants in blast tactic
We need them when inferring types and checking whether two expressions are definitionally equal or not. Remark: they are temporary objects, and should never be included in the blast state object.
This commit is contained in:
parent
21193156ef
commit
c652eeeac6
2 changed files with 53 additions and 3 deletions
|
@ -153,7 +153,7 @@ static name * g_prefix = nullptr;
|
||||||
static expr * g_dummy_type = nullptr; // dummy type for href/mref
|
static expr * g_dummy_type = nullptr; // dummy type for href/mref
|
||||||
|
|
||||||
static expr mk_href_core(unsigned idx) {
|
static expr mk_href_core(unsigned idx) {
|
||||||
return mk_local(name(*g_prefix, idx), *g_dummy_type);
|
return lean::mk_local(name(*g_prefix, idx), *g_dummy_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr mk_href(unsigned idx) {
|
expr mk_href(unsigned idx) {
|
||||||
|
@ -205,11 +205,34 @@ unsigned href_index(expr const & e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_href(expr const & e) {
|
bool has_href(expr const & e) {
|
||||||
return has_local(e);
|
return lean::has_local(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_mref(expr const & e) {
|
bool has_mref(expr const & e) {
|
||||||
return has_expr_metavar(e);
|
return lean::has_expr_metavar(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
expr mk_local(unsigned idx, expr const & t) {
|
||||||
|
lean_assert(is_cached(t));
|
||||||
|
return cache(lean::mk_local(name(*g_prefix, idx), t));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_local(expr const & e) {
|
||||||
|
return is_local(e) && mlocal_type(e) != *g_dummy_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_local(expr const & e) {
|
||||||
|
return lean::has_local(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned local_index(expr const & e) {
|
||||||
|
lean_assert(blast::is_local(e));
|
||||||
|
return mlocal_name(e).get_numeral();
|
||||||
|
}
|
||||||
|
|
||||||
|
expr const & local_type(expr const & e) {
|
||||||
|
lean_assert(blast::is_local(e));
|
||||||
|
return mlocal_type(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr mk_var(unsigned idx) {
|
expr mk_var(unsigned idx) {
|
||||||
|
@ -578,6 +601,26 @@ expr abstract_hrefs(expr const & e, unsigned n, expr const * subst) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr abstract_locals(expr const & e, unsigned n, expr const * subst) {
|
||||||
|
if (!blast::has_local(e))
|
||||||
|
return e;
|
||||||
|
lean_assert(std::all_of(subst, subst+n, [](expr const & e) { return closed(e) && blast::is_local(e); }));
|
||||||
|
return blast::replace(e, [=](expr const & m, unsigned offset) -> optional<expr> {
|
||||||
|
if (!blast::has_local(m))
|
||||||
|
return some_expr(m); // skip: m does not contain locals
|
||||||
|
if (is_local(m)) {
|
||||||
|
unsigned i = n;
|
||||||
|
while (i > 0) {
|
||||||
|
--i;
|
||||||
|
if (local_index(subst[i]) == local_index(m)) //
|
||||||
|
return some_expr(blast::mk_var(offset + n - i - 1));
|
||||||
|
}
|
||||||
|
return none_expr();
|
||||||
|
}
|
||||||
|
return none_expr();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void initialize_expr() {
|
void initialize_expr() {
|
||||||
g_prefix = new name(name::mk_internal_unique_name());
|
g_prefix = new name(name::mk_internal_unique_name());
|
||||||
g_dummy_type = new expr(mk_constant(*g_prefix));
|
g_dummy_type = new expr(mk_constant(*g_prefix));
|
||||||
|
|
|
@ -46,6 +46,7 @@ expr mk_href(unsigned idx);
|
||||||
expr mk_mref(unsigned idx);
|
expr mk_mref(unsigned idx);
|
||||||
expr mk_sort(level const & l);
|
expr mk_sort(level const & l);
|
||||||
expr mk_constant(name const & n, levels const & ls);
|
expr mk_constant(name const & n, levels const & ls);
|
||||||
|
expr mk_local(unsigned idx, expr const & t);
|
||||||
expr mk_app(expr const & f, expr const & a);
|
expr mk_app(expr const & f, expr const & a);
|
||||||
expr mk_app(expr const & f, unsigned num_args, expr const * args);
|
expr mk_app(expr const & f, unsigned num_args, expr const * args);
|
||||||
expr mk_app(unsigned num_args, expr const * args);
|
expr mk_app(unsigned num_args, expr const * args);
|
||||||
|
@ -76,6 +77,11 @@ bool has_href(expr const & e);
|
||||||
/** \brief Return true iff \c e contain mref's */
|
/** \brief Return true iff \c e contain mref's */
|
||||||
bool has_mref(expr const & e);
|
bool has_mref(expr const & e);
|
||||||
|
|
||||||
|
bool is_local(expr const & e);
|
||||||
|
unsigned local_index(expr const & e);
|
||||||
|
expr const & local_type(expr const & e);
|
||||||
|
bool has_local(expr const & e);
|
||||||
|
|
||||||
level update_succ(level const & l, level const & new_arg);
|
level update_succ(level const & l, level const & new_arg);
|
||||||
level update_max(level const & l, level const & new_lhs, level const & new_rhs);
|
level update_max(level const & l, level const & new_lhs, level const & new_rhs);
|
||||||
|
|
||||||
|
@ -105,6 +111,7 @@ expr instantiate_type_univ_params(declaration const & d, levels const & ls);
|
||||||
expr instantiate_value_univ_params(declaration const & d, levels const & ls);
|
expr instantiate_value_univ_params(declaration const & d, levels const & ls);
|
||||||
|
|
||||||
expr abstract_hrefs(expr const & e, unsigned n, expr const * s);
|
expr abstract_hrefs(expr const & e, unsigned n, expr const * s);
|
||||||
|
expr abstract_locals(expr const & e, unsigned n, expr const * s);
|
||||||
|
|
||||||
void initialize_expr();
|
void initialize_expr();
|
||||||
void finalize_expr();
|
void finalize_expr();
|
||||||
|
|
Loading…
Reference in a new issue