feat(kernel): add binder annotations (implicit, cast)

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-05-01 10:35:02 -07:00
parent 2b97474958
commit a5ae4b6570
3 changed files with 56 additions and 18 deletions

View file

@ -133,7 +133,7 @@ void expr_app::dealloc(buffer<expr_cell*> & todelete) {
static unsigned dec(unsigned k) { return k == 0 ? 0 : k - 1; } static unsigned dec(unsigned k) { return k == 0 ? 0 : k - 1; }
// Expr binders (Lambda, Pi) // Expr binders (Lambda, Pi)
expr_binder::expr_binder(expr_kind k, name const & n, expr const & t, expr const & b): expr_binder::expr_binder(expr_kind k, name const & n, expr const & t, expr const & b, expr_binder_info const & i):
expr_composite(k, ::lean::hash(t.hash(), b.hash()), expr_composite(k, ::lean::hash(t.hash(), b.hash()),
t.has_metavar() || b.has_metavar(), t.has_metavar() || b.has_metavar(),
t.has_local() || b.has_local(), t.has_local() || b.has_local(),
@ -142,7 +142,8 @@ expr_binder::expr_binder(expr_kind k, name const & n, expr const & t, expr const
std::max(get_free_var_range(t), dec(get_free_var_range(b)))), std::max(get_free_var_range(t), dec(get_free_var_range(b)))),
m_name(n), m_name(n),
m_domain(t), m_domain(t),
m_body(b) { m_body(b),
m_info(i) {
lean_assert(k == expr_kind::Lambda || k == expr_kind::Pi); lean_assert(k == expr_kind::Lambda || k == expr_kind::Pi);
} }
void expr_binder::dealloc(buffer<expr_cell*> & todelete) { void expr_binder::dealloc(buffer<expr_cell*> & todelete) {
@ -389,7 +390,7 @@ expr update_rev_app(expr const & e, unsigned num, expr const * new_args) {
expr update_binder(expr const & e, expr const & new_domain, expr const & new_body) { expr update_binder(expr const & e, expr const & new_domain, expr const & new_body) {
if (!is_eqp(binder_domain(e), new_domain) || !is_eqp(binder_body(e), new_body)) if (!is_eqp(binder_domain(e), new_domain) || !is_eqp(binder_body(e), new_body))
return mk_binder(e.kind(), binder_name(e), new_domain, new_body); return mk_binder(e.kind(), binder_name(e), new_domain, new_body, binder_info(e));
else else
return e; return e;
} }
@ -468,8 +469,8 @@ expr copy(expr const & a) {
case expr_kind::Sort: return mk_sort(sort_level(a)); case expr_kind::Sort: return mk_sort(sort_level(a));
case expr_kind::Macro: return mk_macro(to_macro(a)->m_definition, macro_num_args(a), macro_args(a)); case expr_kind::Macro: return mk_macro(to_macro(a)->m_definition, macro_num_args(a), macro_args(a));
case expr_kind::App: return mk_app(app_fn(a), app_arg(a)); case expr_kind::App: return mk_app(app_fn(a), app_arg(a));
case expr_kind::Lambda: return mk_lambda(binder_name(a), binder_domain(a), binder_body(a)); case expr_kind::Lambda: return mk_lambda(binder_name(a), binder_domain(a), binder_body(a), binder_info(a));
case expr_kind::Pi: return mk_pi(binder_name(a), binder_domain(a), binder_body(a)); case expr_kind::Pi: return mk_pi(binder_name(a), binder_domain(a), binder_body(a), binder_info(a));
case expr_kind::Let: return mk_let(let_name(a), let_type(a), let_value(a), let_body(a)); case expr_kind::Let: return mk_let(let_name(a), let_type(a), let_value(a), let_body(a));
case expr_kind::Meta: return mk_metavar(mlocal_name(a), mlocal_type(a)); case expr_kind::Meta: return mk_metavar(mlocal_name(a), mlocal_type(a));
case expr_kind::Local: return mk_local(mlocal_name(a), mlocal_type(a)); case expr_kind::Local: return mk_local(mlocal_name(a), mlocal_type(a));
@ -477,6 +478,18 @@ expr copy(expr const & a) {
lean_unreachable(); // LCOV_EXCL_LINE lean_unreachable(); // LCOV_EXCL_LINE
} }
serializer & operator<<(serializer & s, expr_binder_info const & i) {
s.write_bool(i.is_implicit());
s.write_bool(i.is_cast());
return s;
}
static expr_binder_info read_expr_binder_info(deserializer & d) {
bool imp = d.read_bool();
bool cast = d.read_bool();
return expr_binder_info(imp, cast);
}
class expr_serializer : public object_serializer<expr, expr_hash_alloc, expr_eqp> { class expr_serializer : public object_serializer<expr, expr_hash_alloc, expr_eqp> {
typedef object_serializer<expr, expr_hash_alloc, expr_eqp> super; typedef object_serializer<expr, expr_hash_alloc, expr_eqp> super;
max_sharing_fn m_max_sharing_fn; max_sharing_fn m_max_sharing_fn;
@ -506,7 +519,7 @@ class expr_serializer : public object_serializer<expr, expr_hash_alloc, expr_eqp
write_core(app_fn(a)); write_core(app_arg(a)); write_core(app_fn(a)); write_core(app_arg(a));
break; break;
case expr_kind::Lambda: case expr_kind::Pi: case expr_kind::Lambda: case expr_kind::Pi:
s << binder_name(a); write_core(binder_domain(a)); write_core(binder_body(a)); s << binder_name(a) << binder_info(a); write_core(binder_domain(a)); write_core(binder_body(a));
break; break;
case expr_kind::Let: case expr_kind::Let:
s << let_name(a); write_core(let_type(a)); write_core(let_value(a)); write_core(let_body(a)); s << let_name(a); write_core(let_type(a)); write_core(let_value(a)); write_core(let_body(a));
@ -528,9 +541,10 @@ class expr_deserializer : public object_deserializer<expr> {
public: public:
expr read_binder(expr_kind k) { expr read_binder(expr_kind k) {
deserializer & d = get_owner(); deserializer & d = get_owner();
name n = read_name(d); name n = read_name(d);
expr t = read(); expr_binder_info i = read_expr_binder_info(d);
return mk_binder(k, n, t, read()); expr t = read();
return mk_binder(k, n, t, read(), i);
} }
expr read() { expr read() {

View file

@ -72,6 +72,7 @@ public:
}; };
class macro_definition; class macro_definition;
class expr_binder_info;
/** /**
\brief Exprs for encoding formulas/expressions, types and proofs. \brief Exprs for encoding formulas/expressions, types and proofs.
@ -118,7 +119,7 @@ public:
friend expr mk_app(expr const & f, expr const & a); friend expr mk_app(expr const & f, expr const & a);
friend expr mk_pair(expr const & f, expr const & s, expr const & t); friend expr mk_pair(expr const & f, expr const & s, expr const & t);
friend expr mk_proj(bool fst, expr const & p); friend expr mk_proj(bool fst, expr const & p);
friend expr mk_binder(expr_kind k, name const & n, expr const & t, expr const & e); friend expr mk_binder(expr_kind k, name const & n, expr const & t, expr const & e, expr_binder_info const & i);
friend expr mk_let(name const & n, expr const & t, expr const & v, expr const & e); friend expr mk_let(name const & n, expr const & t, expr const & v, expr const & e);
friend expr mk_macro(macro_definition * m, unsigned num, expr const * args); friend expr mk_macro(macro_definition * m, unsigned num, expr const * args);
@ -204,18 +205,33 @@ public:
expr const & get_arg() const { return m_arg; } expr const & get_arg() const { return m_arg; }
}; };
/**
\brief Auxiliary annotation for binders (Lambda and Pi). This information
is only used for elaboration.
*/
class expr_binder_info {
bool m_implicit; //! if true, binder argument is an implicit argument
bool m_cast; //! if true, binder argument is a target for using cast
public:
expr_binder_info(bool implicit = false, bool cast = false):m_implicit(implicit), m_cast(cast) {}
bool is_implicit() const { return m_implicit; }
bool is_cast() const { return m_cast; }
};
/** \brief Super class for lambda, pi and sigma */ /** \brief Super class for lambda, pi and sigma */
class expr_binder : public expr_composite { class expr_binder : public expr_composite {
name m_name; name m_name;
expr m_domain; expr m_domain;
expr m_body; expr m_body;
expr_binder_info m_info;
friend class expr_cell; friend class expr_cell;
void dealloc(buffer<expr_cell*> & todelete); void dealloc(buffer<expr_cell*> & todelete);
public: public:
expr_binder(expr_kind k, name const & n, expr const & t, expr const & e); expr_binder(expr_kind k, name const & n, expr const & t, expr const & e, expr_binder_info const & i = expr_binder_info());
name const & get_name() const { return m_name; } name const & get_name() const { return m_name; }
expr const & get_domain() const { return m_domain; } expr const & get_domain() const { return m_domain; }
expr const & get_body() const { return m_body; } expr const & get_body() const { return m_body; }
expr_binder_info const & get_info() const { return m_info; }
}; };
/** \brief Let expressions */ /** \brief Let expressions */
@ -354,9 +370,15 @@ template<typename T> expr mk_app(T const & args) { return mk_app(args.size(), ar
expr mk_rev_app(unsigned num_args, expr const * args); expr mk_rev_app(unsigned num_args, expr const * args);
template<typename T> expr mk_rev_app(T const & args) { return mk_rev_app(args.size(), args.data()); } template<typename T> expr mk_rev_app(T const & args) { return mk_rev_app(args.size(), args.data()); }
template<typename T> expr mk_rev_app(expr const & f, T const & args) { return mk_rev_app(f, args.size(), args.data()); } template<typename T> expr mk_rev_app(expr const & f, T const & args) { return mk_rev_app(f, args.size(), args.data()); }
inline expr mk_binder(expr_kind k, name const & n, expr const & t, expr const & e) { return expr(new expr_binder(k, n, t, e)); } inline expr mk_binder(expr_kind k, name const & n, expr const & t, expr const & e, expr_binder_info const & i = expr_binder_info()) {
inline expr mk_lambda(name const & n, expr const & t, expr const & e) { return mk_binder(expr_kind::Lambda, n, t, e); } return expr(new expr_binder(k, n, t, e, i));
inline expr mk_pi(name const & n, expr const & t, expr const & e) { return mk_binder(expr_kind::Pi, n, t, e); } }
inline expr mk_lambda(name const & n, expr const & t, expr const & e, expr_binder_info const & i = expr_binder_info()) {
return mk_binder(expr_kind::Lambda, n, t, e, i);
}
inline expr mk_pi(name const & n, expr const & t, expr const & e, expr_binder_info const & i = expr_binder_info()) {
return mk_binder(expr_kind::Pi, n, t, e, i);
}
inline expr mk_let(name const & n, expr const & t, expr const & v, expr const & e) { return expr(new expr_let(n, t, v, e)); } inline expr mk_let(name const & n, expr const & t, expr const & v, expr const & e) { return expr(new expr_let(n, t, v, e)); }
inline expr mk_sort(level const & l) { return expr(new expr_sort(l)); } inline expr mk_sort(level const & l) { return expr(new expr_sort(l)); }
@ -444,6 +466,7 @@ inline expr const & app_arg(expr_cell * e) { return to_app(e)->g
inline name const & binder_name(expr_cell * e) { return to_binder(e)->get_name(); } inline name const & binder_name(expr_cell * e) { return to_binder(e)->get_name(); }
inline expr const & binder_domain(expr_cell * e) { return to_binder(e)->get_domain(); } inline expr const & binder_domain(expr_cell * e) { return to_binder(e)->get_domain(); }
inline expr const & binder_body(expr_cell * e) { return to_binder(e)->get_body(); } inline expr const & binder_body(expr_cell * e) { return to_binder(e)->get_body(); }
inline expr_binder_info const & binder_info(expr_cell * e) { return to_binder(e)->get_info(); }
inline level const & sort_level(expr_cell * e) { return to_sort(e)->get_level(); } inline level const & sort_level(expr_cell * e) { return to_sort(e)->get_level(); }
inline name const & let_name(expr_cell * e) { return to_let(e)->get_name(); } inline name const & let_name(expr_cell * e) { return to_let(e)->get_name(); }
inline expr const & let_value(expr_cell * e) { return to_let(e)->get_value(); } inline expr const & let_value(expr_cell * e) { return to_let(e)->get_value(); }
@ -467,6 +490,7 @@ inline expr const & app_arg(expr const & e) { return to_app(e)->
inline name const & binder_name(expr const & e) { return to_binder(e)->get_name(); } inline name const & binder_name(expr const & e) { return to_binder(e)->get_name(); }
inline expr const & binder_domain(expr const & e) { return to_binder(e)->get_domain(); } inline expr const & binder_domain(expr const & e) { return to_binder(e)->get_domain(); }
inline expr const & binder_body(expr const & e) { return to_binder(e)->get_body(); } inline expr const & binder_body(expr const & e) { return to_binder(e)->get_body(); }
inline expr_binder_info const & binder_info(expr const & e) { return to_binder(e)->get_info(); }
inline level const & sort_level(expr const & e) { return to_sort(e)->get_level(); } inline level const & sort_level(expr const & e) { return to_sort(e)->get_level(); }
inline name const & let_name(expr const & e) { return to_let(e)->get_name(); } inline name const & let_name(expr const & e) { return to_let(e)->get_name(); }
inline expr const & let_value(expr const & e) { return to_let(e)->get_value(); } inline expr const & let_value(expr const & e) { return to_let(e)->get_value(); }

View file

@ -377,7 +377,7 @@ struct type_checker::imp {
ensure_sort(t, binder_domain(e)); ensure_sort(t, binder_domain(e));
} }
auto b = open_binder_body(e); auto b = open_binder_body(e);
r = mk_pi(binder_name(e), binder_domain(e), abstract_p(infer_type_core(b.first, infer_only), b.second)); r = mk_pi(binder_name(e), binder_domain(e), abstract_p(infer_type_core(b.first, infer_only), b.second), binder_info(e));
break; break;
} }
case expr_kind::Pi: { case expr_kind::Pi: {