refactor(kernel/abstract): add abstract_locals, and remove abstract_p

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-06-21 10:23:59 -07:00
parent 67088b130e
commit 2c3e3cb544
4 changed files with 14 additions and 24 deletions

View file

@ -28,20 +28,25 @@ expr abstract(expr const & e, unsigned s, unsigned n, expr const * subst) {
expr abstract(expr const & e, unsigned n, expr const * subst) { return abstract(e, 0, n, subst); }
expr abstract(expr const & e, expr const & s, unsigned i) { return abstract(e, i, 1, &s); }
expr abstract_p(expr const & e, unsigned n, expr const * s) {
lean_assert(std::all_of(s, s+n, closed));
return replace(e, [=](expr const & e, unsigned offset) -> optional<expr> {
expr abstract_locals(expr const & e, unsigned n, expr const * subst) {
lean_assert(std::all_of(subst, subst+n, [](expr const & e) { return closed(e) && is_local(e); }));
if (!has_local(e))
return e;
return replace(e, [=](expr const & m, unsigned offset) -> optional<expr> {
if (!has_local(m))
return some_expr(m); // expression m does not contain local constants
if (closed(e)) {
unsigned i = n;
while (i > 0) {
--i;
if (is_eqp(s[i], e))
return some_expr(copy_tag(e, mk_var(offset + n - i - 1)));
if (subst[i] == m)
return some_expr(copy_tag(m, mk_var(offset + n - i - 1)));
}
}
return none_expr();
});
}
#define MkBinder(FName) \
expr FName(std::initializer_list<std::pair<expr const &, expr const &>> const & l, expr const & b) { \
expr r = b; \

View file

@ -22,15 +22,9 @@ inline expr abstract(expr const & e, std::initializer_list<expr> const & l) { re
/** \brief Replace s with variable #i in the given expression. \pre s is closed */
expr abstract(expr const & e, expr const & s, unsigned i);
/**
\brief Replace the expressions s[0], ..., s[n-1] in e with var(n-1), ..., var(0).
Pointer comparison is used to compare subexpressions of e with the s[i]'s.
\pre s[0], ..., s[n-1] must be closed expressions (i.e., no free variables).
*/
expr abstract_p(expr const & e, unsigned n, expr const * s);
inline expr abstract_p(expr const & e, expr const & s) { return abstract_p(e, 1, &s); }
/** \brief Similar to abstract, but all values in s are local constants. */
expr abstract_locals(expr const & e, unsigned n, expr const * s);
inline expr abstract_local(expr const & e, expr const & s) { return abstract_locals(e, 1, &s); }
/**
\brief Create a lambda expression (lambda (x : t) b), the term b is abstracted using abstract(b, constant(x)).

View file

@ -342,7 +342,7 @@ struct type_checker::imp {
ensure_sort(t, binding_domain(e));
}
auto b = open_binding_body(e);
r = mk_pi(binding_name(e), binding_domain(e), abstract_p(infer_type_core(b.first, infer_only), b.second), binding_info(e));
r = mk_pi(binding_name(e), binding_domain(e), abstract_local(infer_type_core(b.first, infer_only), b.second), binding_info(e));
break;
}
case expr_kind::Pi: {

View file

@ -242,15 +242,6 @@ static void tst11() {
std::cout << abstract(mk_lambda("x", t, f(a, mk_lambda("y", t, f(b, a)))), Const("a")) << "\n";
lean_assert(abstract(mk_lambda("x", t, f(a, mk_lambda("y", t, f(b, a)))), Const("a")) ==
mk_lambda("x", t, f(Var(1), mk_lambda("y", t, f(b, Var(2))))));
{
scoped_expr_caching set(false);
std::cout << abstract_p(mk_lambda("x", t, f(a, mk_lambda("y", t, f(b, a)))), Const("a")) << "\n";
lean_assert(abstract_p(mk_lambda("x", t, f(a, mk_lambda("y", t, f(b, a)))), Const("a")) ==
mk_lambda("x", t, f(a, mk_lambda("y", t, f(b, a)))));
std::cout << abstract_p(mk_lambda("x", t, f(a, mk_lambda("y", t, f(b, a)))), a) << "\n";
lean_assert(abstract_p(mk_lambda("x", t, f(a, mk_lambda("y", t, f(b, a)))), a) ==
mk_lambda("x", t, f(Var(1), mk_lambda("y", t, f(b, Var(2))))));
}
lean_assert(substitute(f(f(f(a))), f(a), b) == f(f(b)));
}