feat(kernel): add binder annotations (implicit, cast)
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
2b97474958
commit
a5ae4b6570
3 changed files with 56 additions and 18 deletions
|
@ -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() {
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
Loading…
Reference in a new issue