refactor(kernel/expr): tag expressions at "creation" time
This commit is contained in:
parent
d960c1994e
commit
814778abb1
4 changed files with 185 additions and 135 deletions
|
@ -20,7 +20,7 @@ expr abstract(expr const & e, unsigned s, unsigned n, expr const * subst) {
|
|||
while (i > 0) {
|
||||
--i;
|
||||
if (subst[i] == e)
|
||||
return some_expr(copy_tag(e, mk_var(offset + s + n - i - 1)));
|
||||
return some_expr(mk_var(offset + s + n - i - 1, e.get_tag()));
|
||||
}
|
||||
}
|
||||
return none_expr();
|
||||
|
@ -41,7 +41,7 @@ expr abstract_locals(expr const & e, unsigned n, expr const * subst) {
|
|||
while (i > 0) {
|
||||
--i;
|
||||
if (mlocal_name(subst[i]) == mlocal_name(m))
|
||||
return some_expr(copy_tag(m, mk_var(offset + n - i - 1)));
|
||||
return some_expr(mk_var(offset + n - i - 1, m.get_tag()));
|
||||
}
|
||||
}
|
||||
return none_expr();
|
||||
|
|
|
@ -52,7 +52,8 @@ unsigned hash_levels(levels const & ls) {
|
|||
|
||||
LEAN_THREAD_VALUE(unsigned, g_hash_alloc_counter, 0);
|
||||
|
||||
expr_cell::expr_cell(expr_kind k, unsigned h, bool has_expr_mv, bool has_univ_mv, bool has_local, bool has_param_univ):
|
||||
expr_cell::expr_cell(expr_kind k, unsigned h, bool has_expr_mv, bool has_univ_mv,
|
||||
bool has_local, bool has_param_univ, tag g):
|
||||
m_flags(0),
|
||||
m_kind(static_cast<unsigned>(k)),
|
||||
m_has_expr_mv(has_expr_mv),
|
||||
|
@ -60,7 +61,7 @@ expr_cell::expr_cell(expr_kind k, unsigned h, bool has_expr_mv, bool has_univ_mv
|
|||
m_has_local(has_local),
|
||||
m_has_param_univ(has_param_univ),
|
||||
m_hash(h),
|
||||
m_tag(nulltag),
|
||||
m_tag(g),
|
||||
m_rc(0) {
|
||||
// m_hash_alloc does not need to be a unique identifier.
|
||||
// We want diverse hash codes because given expr_cell * c1 and expr_cell * c2,
|
||||
|
@ -110,8 +111,8 @@ bool is_meta(expr const & e) {
|
|||
|
||||
// Expr variables
|
||||
DEF_THREAD_MEMORY_POOL(get_var_allocator, sizeof(expr_var));
|
||||
expr_var::expr_var(unsigned idx):
|
||||
expr_cell(expr_kind::Var, idx, false, false, false, false),
|
||||
expr_var::expr_var(unsigned idx, tag g):
|
||||
expr_cell(expr_kind::Var, idx, false, false, false, false, g),
|
||||
m_vidx(idx) {
|
||||
if (idx == std::numeric_limits<unsigned>::max())
|
||||
throw exception("invalid free variable index, de Bruijn index is too big");
|
||||
|
@ -123,8 +124,9 @@ void expr_var::dealloc() {
|
|||
|
||||
// Expr constants
|
||||
DEF_THREAD_MEMORY_POOL(get_const_allocator, sizeof(expr_const));
|
||||
expr_const::expr_const(name const & n, levels const & ls):
|
||||
expr_cell(expr_kind::Constant, ::lean::hash(n.hash(), hash_levels(ls)), false, has_meta(ls), false, has_param(ls)),
|
||||
expr_const::expr_const(name const & n, levels const & ls, tag g):
|
||||
expr_cell(expr_kind::Constant, ::lean::hash(n.hash(), hash_levels(ls)), false,
|
||||
has_meta(ls), false, has_param(ls), g),
|
||||
m_name(n),
|
||||
m_levels(ls) {
|
||||
}
|
||||
|
@ -139,10 +141,10 @@ unsigned binder_info::hash() const {
|
|||
|
||||
// Expr metavariables and local variables
|
||||
DEF_THREAD_MEMORY_POOL(get_mlocal_allocator, sizeof(expr_mlocal));
|
||||
expr_mlocal::expr_mlocal(bool is_meta, name const & n, expr const & t):
|
||||
expr_mlocal::expr_mlocal(bool is_meta, name const & n, expr const & t, tag g):
|
||||
expr_composite(is_meta ? expr_kind::Meta : expr_kind::Local, n.hash(), is_meta || t.has_expr_metavar(), t.has_univ_metavar(),
|
||||
!is_meta || t.has_local(), t.has_param_univ(),
|
||||
1, get_free_var_range(t)),
|
||||
1, get_free_var_range(t), g),
|
||||
m_name(n),
|
||||
m_type(t) {}
|
||||
void expr_mlocal::dealloc(buffer<expr_cell*> & todelete) {
|
||||
|
@ -152,8 +154,8 @@ void expr_mlocal::dealloc(buffer<expr_cell*> & todelete) {
|
|||
}
|
||||
|
||||
DEF_THREAD_MEMORY_POOL(get_local_allocator, sizeof(expr_local));
|
||||
expr_local::expr_local(name const & n, name const & pp_name, expr const & t, binder_info const & bi):
|
||||
expr_mlocal(false, n, t),
|
||||
expr_local::expr_local(name const & n, name const & pp_name, expr const & t, binder_info const & bi, tag g):
|
||||
expr_mlocal(false, n, t, g),
|
||||
m_pp_name(pp_name),
|
||||
m_bi(bi) {}
|
||||
void expr_local::dealloc(buffer<expr_cell*> & todelete) {
|
||||
|
@ -164,21 +166,22 @@ void expr_local::dealloc(buffer<expr_cell*> & todelete) {
|
|||
|
||||
// Composite expressions
|
||||
expr_composite::expr_composite(expr_kind k, unsigned h, bool has_expr_mv, bool has_univ_mv,
|
||||
bool has_local, bool has_param_univ, unsigned w, unsigned fv_range):
|
||||
expr_cell(k, h, has_expr_mv, has_univ_mv, has_local, has_param_univ),
|
||||
bool has_local, bool has_param_univ, unsigned w, unsigned fv_range, tag g):
|
||||
expr_cell(k, h, has_expr_mv, has_univ_mv, has_local, has_param_univ, g),
|
||||
m_weight(w),
|
||||
m_free_var_range(fv_range) {}
|
||||
|
||||
// Expr applications
|
||||
DEF_THREAD_MEMORY_POOL(get_app_allocator, sizeof(expr_app));
|
||||
expr_app::expr_app(expr const & fn, expr const & arg):
|
||||
expr_app::expr_app(expr const & fn, expr const & arg, tag g):
|
||||
expr_composite(expr_kind::App, ::lean::hash(fn.hash(), arg.hash()),
|
||||
fn.has_expr_metavar() || arg.has_expr_metavar(),
|
||||
fn.has_univ_metavar() || arg.has_univ_metavar(),
|
||||
fn.has_local() || arg.has_local(),
|
||||
fn.has_param_univ() || arg.has_param_univ(),
|
||||
inc_weight(add_weight(get_weight(fn), get_weight(arg))),
|
||||
std::max(get_free_var_range(fn), get_free_var_range(arg))),
|
||||
std::max(get_free_var_range(fn), get_free_var_range(arg)),
|
||||
g),
|
||||
m_fn(fn), m_arg(arg) {
|
||||
m_hash = ::lean::hash(m_hash, m_weight);
|
||||
}
|
||||
|
@ -202,14 +205,15 @@ bool operator==(binder_info const & i1, binder_info const & i2) {
|
|||
|
||||
// Expr binders (Lambda, Pi)
|
||||
DEF_THREAD_MEMORY_POOL(get_binding_allocator, sizeof(expr_binding));
|
||||
expr_binding::expr_binding(expr_kind k, name const & n, expr const & t, expr const & b, binder_info const & i):
|
||||
expr_binding::expr_binding(expr_kind k, name const & n, expr const & t, expr const & b, binder_info const & i, tag g):
|
||||
expr_composite(k, ::lean::hash(t.hash(), b.hash()),
|
||||
t.has_expr_metavar() || b.has_expr_metavar(),
|
||||
t.has_univ_metavar() || b.has_univ_metavar(),
|
||||
t.has_local() || b.has_local(),
|
||||
t.has_param_univ() || b.has_param_univ(),
|
||||
inc_weight(add_weight(get_weight(t), get_weight(b))),
|
||||
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))),
|
||||
g),
|
||||
m_binder(n, t, i),
|
||||
m_body(b) {
|
||||
m_hash = ::lean::hash(m_hash, m_weight);
|
||||
|
@ -224,8 +228,8 @@ void expr_binding::dealloc(buffer<expr_cell*> & todelete) {
|
|||
|
||||
// Expr Sort
|
||||
DEF_THREAD_MEMORY_POOL(get_sort_allocator, sizeof(expr_sort));
|
||||
expr_sort::expr_sort(level const & l):
|
||||
expr_cell(expr_kind::Sort, ::lean::hash(l), false, has_meta(l), false, has_param(l)),
|
||||
expr_sort::expr_sort(level const & l, tag g):
|
||||
expr_cell(expr_kind::Sort, ::lean::hash(l), false, has_meta(l), false, has_param(l), g),
|
||||
m_level(l) {
|
||||
}
|
||||
expr_sort::~expr_sort() {}
|
||||
|
@ -274,7 +278,7 @@ static unsigned get_free_var_range(unsigned num, expr const * args) {
|
|||
return r;
|
||||
}
|
||||
|
||||
expr_macro::expr_macro(macro_definition const & m, unsigned num, expr const * args):
|
||||
expr_macro::expr_macro(macro_definition const & m, unsigned num, expr const * args, tag g):
|
||||
expr_composite(expr_kind::Macro,
|
||||
lean::hash(num, [&](unsigned i) { return args[i].hash(); }, m.hash()),
|
||||
std::any_of(args, args+num, [](expr const & e) { return e.has_expr_metavar(); }),
|
||||
|
@ -282,7 +286,8 @@ expr_macro::expr_macro(macro_definition const & m, unsigned num, expr const * ar
|
|||
std::any_of(args, args+num, [](expr const & e) { return e.has_local(); }),
|
||||
std::any_of(args, args+num, [](expr const & e) { return e.has_param_univ(); }),
|
||||
inc_weight(add_weight(num, args)),
|
||||
get_free_var_range(num, args)),
|
||||
get_free_var_range(num, args),
|
||||
g),
|
||||
m_definition(m),
|
||||
m_num_args(num) {
|
||||
m_args = new expr[num];
|
||||
|
@ -321,20 +326,30 @@ inline expr cache(expr && e) { return e; }
|
|||
bool enable_expr_caching(bool) { return true; } // NOLINT
|
||||
#endif
|
||||
|
||||
expr mk_var(unsigned idx) { return cache(expr(new (get_var_allocator().allocate()) expr_var(idx))); }
|
||||
expr mk_constant(name const & n, levels const & ls) { return cache(expr(new (get_const_allocator().allocate()) expr_const(n, ls))); }
|
||||
expr mk_macro(macro_definition const & m, unsigned num, expr const * args) { return cache(expr(new expr_macro(m, num, args))); }
|
||||
expr mk_metavar(name const & n, expr const & t) { return cache(expr(new (get_mlocal_allocator().allocate()) expr_mlocal(true, n, t))); }
|
||||
expr mk_local(name const & n, name const & pp_n, expr const & t, binder_info const & bi) {
|
||||
return cache(expr(new (get_local_allocator().allocate()) expr_local(n, pp_n, t, bi)));
|
||||
expr mk_var(unsigned idx, tag g) {
|
||||
return cache(expr(new (get_var_allocator().allocate()) expr_var(idx, g)));
|
||||
}
|
||||
expr mk_app(expr const & f, expr const & a) {
|
||||
return cache(expr(new (get_app_allocator().allocate()) expr_app(f, a)));
|
||||
expr mk_constant(name const & n, levels const & ls, tag g) {
|
||||
return cache(expr(new (get_const_allocator().allocate()) expr_const(n, ls, g)));
|
||||
}
|
||||
expr mk_binding(expr_kind k, name const & n, expr const & t, expr const & e, binder_info const & i) {
|
||||
return cache(expr(new (get_binding_allocator().allocate()) expr_binding(k, n, t, e, i)));
|
||||
expr mk_macro(macro_definition const & m, unsigned num, expr const * args, tag g) {
|
||||
return cache(expr(new expr_macro(m, num, args, g)));
|
||||
}
|
||||
expr mk_metavar(name const & n, expr const & t, tag g) {
|
||||
return cache(expr(new (get_mlocal_allocator().allocate()) expr_mlocal(true, n, t, g)));
|
||||
}
|
||||
expr mk_local(name const & n, name const & pp_n, expr const & t, binder_info const & bi, tag g) {
|
||||
return cache(expr(new (get_local_allocator().allocate()) expr_local(n, pp_n, t, bi, g)));
|
||||
}
|
||||
expr mk_app(expr const & f, expr const & a, tag g) {
|
||||
return cache(expr(new (get_app_allocator().allocate()) expr_app(f, a, g)));
|
||||
}
|
||||
expr mk_binding(expr_kind k, name const & n, expr const & t, expr const & e, binder_info const & i, tag g) {
|
||||
return cache(expr(new (get_binding_allocator().allocate()) expr_binding(k, n, t, e, i, g)));
|
||||
}
|
||||
expr mk_sort(level const & l, tag g) {
|
||||
return cache(expr(new (get_sort_allocator().allocate()) expr_sort(l, g)));
|
||||
}
|
||||
expr mk_sort(level const & l) { return cache(expr(new (get_sort_allocator().allocate()) expr_sort(l))); }
|
||||
// =======================================
|
||||
|
||||
typedef buffer<expr_cell*> del_buffer;
|
||||
|
@ -365,38 +380,38 @@ void expr_cell::dealloc() {
|
|||
}
|
||||
|
||||
// Auxiliary constructors
|
||||
expr mk_app(expr const & f, unsigned num_args, expr const * args) {
|
||||
expr mk_app(expr const & f, unsigned num_args, expr const * args, tag g) {
|
||||
expr r = f;
|
||||
for (unsigned i = 0; i < num_args; i++)
|
||||
r = mk_app(r, args[i]);
|
||||
r = mk_app(r, args[i], g);
|
||||
return r;
|
||||
}
|
||||
|
||||
expr mk_app(unsigned num_args, expr const * args) {
|
||||
expr mk_app(unsigned num_args, expr const * args, tag g) {
|
||||
lean_assert(num_args >= 2);
|
||||
return mk_app(mk_app(args[0], args[1]), num_args - 2, args+2);
|
||||
return mk_app(mk_app(args[0], args[1], g), num_args - 2, args+2, g);
|
||||
}
|
||||
|
||||
expr mk_rev_app(expr const & f, unsigned num_args, expr const * args) {
|
||||
expr mk_rev_app(expr const & f, unsigned num_args, expr const * args, tag g) {
|
||||
expr r = f;
|
||||
unsigned i = num_args;
|
||||
while (i > 0) {
|
||||
--i;
|
||||
r = mk_app(r, args[i]);
|
||||
r = mk_app(r, args[i], g);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
expr mk_rev_app(unsigned num_args, expr const * args) {
|
||||
expr mk_rev_app(unsigned num_args, expr const * args, tag g) {
|
||||
lean_assert(num_args >= 2);
|
||||
return mk_rev_app(mk_app(args[num_args-1], args[num_args-2]), num_args-2, args);
|
||||
return mk_rev_app(mk_app(args[num_args-1], args[num_args-2], g), num_args-2, args, g);
|
||||
}
|
||||
|
||||
expr mk_app_vars(expr const & f, unsigned n) {
|
||||
expr mk_app_vars(expr const & f, unsigned n, tag g) {
|
||||
expr r = f;
|
||||
while (n > 0) {
|
||||
--n;
|
||||
r = mk_app(r, Var(n));
|
||||
r = mk_app(r, mk_var(n, g), g);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -453,14 +468,16 @@ static name const & get_default_var_name() {
|
|||
static name const & g_default_var_name = get_default_var_name(); // force it to be initialized
|
||||
|
||||
bool is_default_var_name(name const & n) { return n == get_default_var_name(); }
|
||||
expr mk_arrow(expr const & t, expr const & e) { return mk_pi(get_default_var_name(), t, e); }
|
||||
expr mk_arrow(expr const & t, expr const & e, tag g) {
|
||||
return mk_pi(get_default_var_name(), t, e, binder_info(), g);
|
||||
}
|
||||
|
||||
expr mk_pi(unsigned sz, expr const * domain, expr const & range) {
|
||||
expr mk_pi(unsigned sz, expr const * domain, expr const & range, tag g) {
|
||||
expr r = range;
|
||||
unsigned i = sz;
|
||||
while (i > 0) {
|
||||
--i;
|
||||
r = mk_pi(name(g_default_var_name, i), domain[i], r);
|
||||
r = mk_pi(name(g_default_var_name, i), domain[i], r, binder_info(), g);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -494,7 +511,7 @@ expr copy_tag(expr const & e, expr && new_e) {
|
|||
|
||||
expr update_app(expr const & e, expr const & new_fn, expr const & new_arg) {
|
||||
if (!is_eqp(app_fn(e), new_fn) || !is_eqp(app_arg(e), new_arg))
|
||||
return copy_tag(e, mk_app(new_fn, new_arg));
|
||||
return mk_app(new_fn, new_arg, e.get_tag());
|
||||
else
|
||||
return e;
|
||||
}
|
||||
|
@ -503,24 +520,24 @@ expr update_rev_app(expr const & e, unsigned num, expr const * new_args) {
|
|||
expr const * it = &e;
|
||||
for (unsigned i = 0; i < num - 1; i++) {
|
||||
if (!is_app(*it) || !is_eqp(app_arg(*it), new_args[i]))
|
||||
return copy_tag(e, mk_rev_app(num, new_args));
|
||||
return mk_rev_app(num, new_args, e.get_tag());
|
||||
it = &app_fn(*it);
|
||||
}
|
||||
if (!is_eqp(*it, new_args[num - 1]))
|
||||
return copy_tag(e, mk_rev_app(num, new_args));
|
||||
return mk_rev_app(num, new_args, e.get_tag());
|
||||
return e;
|
||||
}
|
||||
|
||||
expr update_binding(expr const & e, expr const & new_domain, expr const & new_body) {
|
||||
if (!is_eqp(binding_domain(e), new_domain) || !is_eqp(binding_body(e), new_body))
|
||||
return copy_tag(e, mk_binding(e.kind(), binding_name(e), new_domain, new_body, binding_info(e)));
|
||||
return mk_binding(e.kind(), binding_name(e), new_domain, new_body, binding_info(e), e.get_tag());
|
||||
else
|
||||
return e;
|
||||
}
|
||||
|
||||
expr update_binding(expr const & e, expr const & new_domain, expr const & new_body, binder_info const & bi) {
|
||||
if (!is_eqp(binding_domain(e), new_domain) || !is_eqp(binding_body(e), new_body) || bi != binding_info(e))
|
||||
return copy_tag(e, mk_binding(e.kind(), binding_name(e), new_domain, new_body, bi));
|
||||
return mk_binding(e.kind(), binding_name(e), new_domain, new_body, bi, e.get_tag());
|
||||
else
|
||||
return e;
|
||||
}
|
||||
|
@ -529,16 +546,16 @@ expr update_mlocal(expr const & e, expr const & new_type) {
|
|||
if (is_eqp(mlocal_type(e), new_type))
|
||||
return e;
|
||||
else if (is_metavar(e))
|
||||
return copy_tag(e, mk_metavar(mlocal_name(e), new_type));
|
||||
return mk_metavar(mlocal_name(e), new_type, e.get_tag());
|
||||
else
|
||||
return copy_tag(e, mk_local(mlocal_name(e), local_pp_name(e), new_type, local_info(e)));
|
||||
return mk_local(mlocal_name(e), local_pp_name(e), new_type, local_info(e), e.get_tag());
|
||||
}
|
||||
|
||||
expr update_local(expr const & e, expr const & new_type, binder_info const & bi) {
|
||||
if (is_eqp(mlocal_type(e), new_type) && local_info(e) == bi)
|
||||
return e;
|
||||
else
|
||||
return copy_tag(e, mk_local(mlocal_name(e), local_pp_name(e), new_type, bi));
|
||||
return mk_local(mlocal_name(e), local_pp_name(e), new_type, bi, e.get_tag());
|
||||
}
|
||||
|
||||
expr update_local(expr const & e, binder_info const & bi) {
|
||||
|
@ -547,14 +564,14 @@ expr update_local(expr const & e, binder_info const & bi) {
|
|||
|
||||
expr update_sort(expr const & e, level const & new_level) {
|
||||
if (!is_eqp(sort_level(e), new_level))
|
||||
return copy_tag(e, mk_sort(new_level));
|
||||
return mk_sort(new_level, e.get_tag());
|
||||
else
|
||||
return e;
|
||||
}
|
||||
|
||||
expr update_constant(expr const & e, levels const & new_levels) {
|
||||
if (!is_eqp(const_levels(e), new_levels))
|
||||
return copy_tag(e, mk_constant(const_name(e), new_levels));
|
||||
return mk_constant(const_name(e), new_levels, e.get_tag());
|
||||
else
|
||||
return e;
|
||||
}
|
||||
|
@ -569,7 +586,7 @@ expr update_macro(expr const & e, unsigned num, expr const * args) {
|
|||
if (i == num)
|
||||
return e;
|
||||
}
|
||||
return copy_tag(e, mk_macro(to_macro(e)->m_definition, num, args));
|
||||
return mk_macro(to_macro(e)->m_definition, num, args, e.get_tag());
|
||||
}
|
||||
|
||||
bool is_atomic(expr const & e) {
|
||||
|
|
|
@ -69,7 +69,7 @@ protected:
|
|||
|
||||
static void dec_ref(expr & c, buffer<expr_cell*> & todelete);
|
||||
public:
|
||||
expr_cell(expr_kind k, unsigned h, bool has_expr_mv, bool has_univ_mv, bool has_local, bool has_param_univ);
|
||||
expr_cell(expr_kind k, unsigned h, bool has_expr_mv, bool has_univ_mv, bool has_local, bool has_param_univ, tag g);
|
||||
expr_kind kind() const { return static_cast<expr_kind>(m_kind); }
|
||||
unsigned hash() const { return m_hash; }
|
||||
unsigned hash_alloc() const { return m_hash_alloc; }
|
||||
|
@ -128,29 +128,35 @@ public:
|
|||
|
||||
expr_cell * raw() const { return m_ptr; }
|
||||
|
||||
friend expr mk_var(unsigned idx);
|
||||
friend expr mk_sort(level const & l);
|
||||
friend expr mk_constant(name const & n, levels const & ls);
|
||||
friend expr mk_metavar(name const & n, expr const & t);
|
||||
friend expr mk_local(name const & n, name const & pp_n, expr const & t, binder_info const & bi);
|
||||
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_proj(bool fst, expr const & p);
|
||||
friend expr mk_binding(expr_kind k, name const & n, expr const & t, expr const & e, binder_info const & i);
|
||||
friend expr mk_macro(macro_definition const & m, unsigned num, expr const * args);
|
||||
friend expr mk_var(unsigned idx, tag g);
|
||||
friend expr mk_sort(level const & l, tag g);
|
||||
friend expr mk_constant(name const & n, levels const & ls, tag g);
|
||||
friend expr mk_metavar(name const & n, expr const & t, tag g);
|
||||
friend expr mk_local(name const & n, name const & pp_n, expr const & t, binder_info const & bi,
|
||||
tag g);
|
||||
friend expr mk_app(expr const & f, expr const & a, tag g);
|
||||
friend expr mk_pair(expr const & f, expr const & s, expr const & t, tag g);
|
||||
friend expr mk_proj(bool fst, expr const & p, tag g);
|
||||
friend expr mk_binding(expr_kind k, name const & n, expr const & t, expr const & e, binder_info const & i,
|
||||
tag g);
|
||||
friend expr mk_macro(macro_definition const & m, unsigned num, expr const * args, tag g);
|
||||
|
||||
friend bool is_eqp(expr const & a, expr const & b) { return a.m_ptr == b.m_ptr; }
|
||||
// Overloaded operator() can be used to create applications
|
||||
expr operator()(expr const & a1) const;
|
||||
expr operator()(expr const & a1, expr const & a2) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5, expr const & a6) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5, expr const & a6,
|
||||
expr const & a7) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5, expr const & a6,
|
||||
expr const & a7, expr const & a8) const;
|
||||
expr operator()(expr const & a1, tag g = nulltag) const;
|
||||
expr operator()(expr const & a1, expr const & a2, tag g = nulltag) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, tag g = nulltag) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4,
|
||||
tag g = nulltag) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4,
|
||||
expr const & a5, tag g = nulltag) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4,
|
||||
expr const & a5, expr const & a6, tag g = nulltag) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4,
|
||||
expr const & a5, expr const & a6, expr const & a7, tag g = nulltag) const;
|
||||
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4,
|
||||
expr const & a5, expr const & a6, expr const & a7, expr const & a8,
|
||||
tag g = nulltag) const;
|
||||
};
|
||||
|
||||
expr copy_tag(expr const & e, expr && new_e);
|
||||
|
@ -181,7 +187,7 @@ class expr_var : public expr_cell {
|
|||
friend expr_cell;
|
||||
void dealloc();
|
||||
public:
|
||||
expr_var(unsigned idx);
|
||||
expr_var(unsigned idx, tag g);
|
||||
unsigned get_vidx() const { return m_vidx; }
|
||||
};
|
||||
|
||||
|
@ -192,7 +198,7 @@ class expr_const : public expr_cell {
|
|||
friend expr_cell;
|
||||
void dealloc();
|
||||
public:
|
||||
expr_const(name const & n, levels const & ls);
|
||||
expr_const(name const & n, levels const & ls, tag g);
|
||||
name const & get_name() const { return m_name; }
|
||||
levels const & get_levels() const { return m_levels; }
|
||||
};
|
||||
|
@ -206,7 +212,7 @@ protected:
|
|||
friend unsigned get_free_var_range(expr const & e);
|
||||
public:
|
||||
expr_composite(expr_kind k, unsigned h, bool has_expr_mv, bool has_univ_mv, bool has_local,
|
||||
bool has_param_univ, unsigned w, unsigned fv_range);
|
||||
bool has_param_univ, unsigned w, unsigned fv_range, tag g);
|
||||
};
|
||||
|
||||
/** \brief Metavariables and local constants */
|
||||
|
@ -217,7 +223,7 @@ protected:
|
|||
friend expr_cell;
|
||||
void dealloc(buffer<expr_cell*> & todelete);
|
||||
public:
|
||||
expr_mlocal(bool is_meta, name const & n, expr const & t);
|
||||
expr_mlocal(bool is_meta, name const & n, expr const & t, tag g);
|
||||
name const & get_name() const { return m_name; }
|
||||
expr const & get_type() const { return m_type; }
|
||||
};
|
||||
|
@ -273,7 +279,7 @@ class expr_local : public expr_mlocal {
|
|||
friend expr_cell;
|
||||
void dealloc(buffer<expr_cell*> & todelete);
|
||||
public:
|
||||
expr_local(name const & n, name const & pp_name, expr const & t, binder_info const & bi);
|
||||
expr_local(name const & n, name const & pp_name, expr const & t, binder_info const & bi, tag g);
|
||||
name const & get_pp_name() const { return m_pp_name; }
|
||||
binder_info const & get_info() const { return m_bi; }
|
||||
};
|
||||
|
@ -285,7 +291,7 @@ class expr_app : public expr_composite {
|
|||
friend expr_cell;
|
||||
void dealloc(buffer<expr_cell*> & todelete);
|
||||
public:
|
||||
expr_app(expr const & fn, expr const & arg);
|
||||
expr_app(expr const & fn, expr const & arg, tag g);
|
||||
expr const & get_fn() const { return m_fn; }
|
||||
expr const & get_arg() const { return m_arg; }
|
||||
};
|
||||
|
@ -296,7 +302,7 @@ class binder {
|
|||
expr m_type;
|
||||
binder_info m_info;
|
||||
public:
|
||||
binder(name const & n, expr const & t, binder_info const & bi = binder_info()):
|
||||
binder(name const & n, expr const & t, binder_info const & bi):
|
||||
m_name(n), m_type(t), m_info(bi) {}
|
||||
name const & get_name() const { return m_name; }
|
||||
expr const & get_type() const { return m_type; }
|
||||
|
@ -311,7 +317,8 @@ class expr_binding : public expr_composite {
|
|||
friend class expr_cell;
|
||||
void dealloc(buffer<expr_cell*> & todelete);
|
||||
public:
|
||||
expr_binding(expr_kind k, name const & n, expr const & t, expr const & e, binder_info const & i = binder_info());
|
||||
expr_binding(expr_kind k, name const & n, expr const & t, expr const & e,
|
||||
binder_info const & i, tag g);
|
||||
name const & get_name() const { return m_binder.get_name(); }
|
||||
expr const & get_domain() const { return m_binder.get_type(); }
|
||||
expr const & get_body() const { return m_body; }
|
||||
|
@ -325,7 +332,7 @@ class expr_sort : public expr_cell {
|
|||
friend expr_cell;
|
||||
void dealloc();
|
||||
public:
|
||||
expr_sort(level const & l);
|
||||
expr_sort(level const & l, tag g);
|
||||
~expr_sort();
|
||||
level const & get_level() const { return m_level; }
|
||||
};
|
||||
|
@ -399,7 +406,7 @@ class expr_macro : public expr_composite {
|
|||
friend expr update_macro(expr const & e, unsigned num, expr const * args);
|
||||
void dealloc(buffer<expr_cell*> & todelete);
|
||||
public:
|
||||
expr_macro(macro_definition const & v, unsigned num, expr const * args);
|
||||
expr_macro(macro_definition const & v, unsigned num, expr const * args, tag g);
|
||||
~expr_macro();
|
||||
|
||||
macro_definition const & get_def() const { return m_definition; }
|
||||
|
@ -442,79 +449,105 @@ bool is_meta(expr const & e);
|
|||
|
||||
// =======================================
|
||||
// Constructors
|
||||
expr mk_var(unsigned idx);
|
||||
expr mk_var(unsigned idx, tag g = nulltag);
|
||||
inline expr Var(unsigned idx) { return mk_var(idx); }
|
||||
expr mk_constant(name const & n, levels const & ls);
|
||||
expr mk_constant(name const & n, levels const & ls, tag g = nulltag);
|
||||
inline expr mk_constant(name const & n) { return mk_constant(n, levels()); }
|
||||
inline expr Const(name const & n) { return mk_constant(n); }
|
||||
expr mk_macro(macro_definition const & m, unsigned num = 0, expr const * args = nullptr);
|
||||
expr mk_metavar(name const & n, expr const & t);
|
||||
expr mk_local(name const & n, name const & pp_n, expr const & t, binder_info const & bi);
|
||||
inline expr mk_local(name const & n, expr const & t) { return mk_local(n, n, t, binder_info()); }
|
||||
inline expr mk_local(name const & n, expr const & t, binder_info const & bi) { return mk_local(n, n, t, bi); }
|
||||
inline expr Local(name const & n, expr const & t, binder_info const & bi = binder_info()) { return mk_local(n, t, bi); }
|
||||
expr mk_app(expr const & f, expr const & a);
|
||||
expr mk_app(expr const & f, unsigned num_args, expr const * args);
|
||||
expr mk_app(unsigned num_args, expr const * args);
|
||||
inline expr mk_app(std::initializer_list<expr> const & l) { return mk_app(l.size(), l.begin()); }
|
||||
template<typename T> expr mk_app(T const & args) { return mk_app(args.size(), args.data()); }
|
||||
template<typename T> expr mk_app(expr const & f, T const & args) { return mk_app(f, args.size(), args.data()); }
|
||||
expr mk_rev_app(expr const & f, 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(expr const & f, T const & args) { return mk_rev_app(f, args.size(), args.data()); }
|
||||
expr mk_binding(expr_kind k, name const & n, expr const & t, expr const & e, binder_info const & i = binder_info());
|
||||
inline expr mk_lambda(name const & n, expr const & t, expr const & e, binder_info const & i = binder_info()) {
|
||||
return mk_binding(expr_kind::Lambda, n, t, e, i);
|
||||
expr mk_macro(macro_definition const & m, unsigned num = 0, expr const * args = nullptr, tag g = nulltag);
|
||||
expr mk_metavar(name const & n, expr const & t, tag g = nulltag);
|
||||
expr mk_local(name const & n, name const & pp_n, expr const & t, binder_info const & bi, tag g = nulltag);
|
||||
inline expr mk_local(name const & n, expr const & t, tag g = nulltag) { return mk_local(n, n, t, binder_info(), g); }
|
||||
inline expr mk_local(name const & n, expr const & t, binder_info const & bi, tag g = nulltag) {
|
||||
return mk_local(n, n, t, bi, g);
|
||||
}
|
||||
inline expr mk_pi(name const & n, expr const & t, expr const & e, binder_info const & i = binder_info()) {
|
||||
return mk_binding(expr_kind::Pi, n, t, e, i);
|
||||
inline expr Local(name const & n, expr const & t, binder_info const & bi = binder_info(), tag g = nulltag) {
|
||||
return mk_local(n, t, bi, g);
|
||||
}
|
||||
expr mk_sort(level const & l);
|
||||
expr mk_app(expr const & f, expr const & a, tag g = nulltag);
|
||||
expr mk_app(expr const & f, unsigned num_args, expr const * args, tag g = nulltag);
|
||||
expr mk_app(unsigned num_args, expr const * args, tag g = nulltag);
|
||||
inline expr mk_app(std::initializer_list<expr> const & l, tag g = nulltag) {
|
||||
return mk_app(l.size(), l.begin(), g);
|
||||
}
|
||||
template<typename T> expr mk_app(T const & args, tag g = nulltag) { return mk_app(args.size(), args.data(), g); }
|
||||
template<typename T> expr mk_app(expr const & f, T const & args, tag g = nulltag) {
|
||||
return mk_app(f, args.size(), args.data(), g);
|
||||
}
|
||||
expr mk_rev_app(expr const & f, unsigned num_args, expr const * args, tag g = nulltag);
|
||||
expr mk_rev_app(unsigned num_args, expr const * args, tag g = nulltag);
|
||||
template<typename T> expr mk_rev_app(T const & args, tag g = nulltag) { return mk_rev_app(args.size(), args.data(), g); }
|
||||
template<typename T> expr mk_rev_app(expr const & f, T const & args, tag g = nulltag) {
|
||||
return mk_rev_app(f, args.size(), args.data(), g);
|
||||
}
|
||||
expr mk_binding(expr_kind k, name const & n, expr const & t, expr const & e,
|
||||
binder_info const & i = binder_info(), tag g = nulltag);
|
||||
inline expr mk_lambda(name const & n, expr const & t, expr const & e,
|
||||
binder_info const & i = binder_info(), tag g = nulltag) {
|
||||
return mk_binding(expr_kind::Lambda, n, t, e, i, g);
|
||||
}
|
||||
inline expr mk_pi(name const & n, expr const & t, expr const & e, binder_info const & i = binder_info(), tag g = nulltag) {
|
||||
return mk_binding(expr_kind::Pi, n, t, e, i, g);
|
||||
}
|
||||
expr mk_sort(level const & l, tag g = nulltag);
|
||||
|
||||
/** \brief Return <tt>Pi(x.{sz-1}, domain[sz-1], ..., Pi(x.{0}, domain[0], range)...)</tt> */
|
||||
expr mk_pi(unsigned sz, expr const * domain, expr const & range);
|
||||
inline expr mk_pi(buffer<expr> const & domain, expr const & range) { return mk_pi(domain.size(), domain.data(), range); }
|
||||
expr mk_pi(unsigned sz, expr const * domain, expr const & range, tag g = nulltag);
|
||||
inline expr mk_pi(buffer<expr> const & domain, expr const & range, tag g = nulltag) {
|
||||
return mk_pi(domain.size(), domain.data(), range, g);
|
||||
}
|
||||
|
||||
expr mk_Prop();
|
||||
expr mk_Type();
|
||||
|
||||
bool is_default_var_name(name const & n);
|
||||
expr mk_arrow(expr const & t, expr const & e);
|
||||
expr mk_arrow(expr const & t, expr const & e, tag g = nulltag);
|
||||
inline expr operator>>(expr const & t, expr const & e) { return mk_arrow(t, e); }
|
||||
|
||||
// Auxiliary
|
||||
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3) { return mk_app({e1, e2, e3}); }
|
||||
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app({e1, e2, e3, e4}); }
|
||||
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) {
|
||||
return mk_app({e1, e2, e3, e4, e5});
|
||||
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3, tag g = nulltag) {
|
||||
return mk_app({e1, e2, e3}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1) const { return mk_app({*this, a1}); }
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2) const { return mk_app({*this, a1, a2}); }
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3) const { return mk_app({*this, a1, a2, a3}); }
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const {
|
||||
return mk_app({*this, a1, a2, a3, a4});
|
||||
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3, expr const & e4, tag g = nulltag) {
|
||||
return mk_app({e1, e2, e3, e4}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5});
|
||||
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5,
|
||||
tag g = nulltag) {
|
||||
return mk_app({e1, e2, e3, e4, e5}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a, tag g) const {
|
||||
return mk_app({*this, a}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, tag g) const {
|
||||
return mk_app({*this, a1, a2}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, tag g) const {
|
||||
return mk_app({*this, a1, a2, a3}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, tag g) const {
|
||||
return mk_app({*this, a1, a2, a3, a4}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4,
|
||||
expr const & a5, tag g) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5,
|
||||
expr const & a6) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5, a6});
|
||||
expr const & a6, tag g) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5, a6}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5,
|
||||
expr const & a6, expr const & a7) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5, a6, a7});
|
||||
expr const & a6, expr const & a7, tag g) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5, a6, a7}, g);
|
||||
}
|
||||
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5,
|
||||
expr const & a6, expr const & a7, expr const & a8) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5, a6, a7, a8});
|
||||
expr const & a6, expr const & a7, expr const & a8, tag g) const {
|
||||
return mk_app({*this, a1, a2, a3, a4, a5, a6, a7, a8}, g);
|
||||
}
|
||||
|
||||
/** \brief Return application (...((f x_{n-1}) x_{n-2}) ... x_0) */
|
||||
expr mk_app_vars(expr const & f, unsigned n);
|
||||
expr mk_app_vars(expr const & f, unsigned n, tag g = nulltag);
|
||||
|
||||
expr mk_local_for(expr const & b, name_generator const & ngen);
|
||||
expr mk_local_for(expr const & b, name_generator const & ngen, tag g = nulltag);
|
||||
|
||||
bool enable_expr_caching(bool f);
|
||||
/** \brief Helper class for temporarily enabling/disabling expression caching */
|
||||
|
|
|
@ -30,7 +30,7 @@ struct instantiate_easy_fn {
|
|||
if (app && is_app(a))
|
||||
if (auto new_a = operator()(app_arg(a), false))
|
||||
if (auto new_f = operator()(app_fn(a), true))
|
||||
return some_expr(copy_tag(a, mk_app(*new_f, *new_a)));
|
||||
return some_expr(mk_app(*new_f, *new_a, a.get_tag()));
|
||||
return none_expr();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue