refactor(kernel): cleanup instantiate and abstract procedures, implement update procedures
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
db31cc37a1
commit
72e1678ad9
7 changed files with 109 additions and 158 deletions
|
@ -1,6 +1,6 @@
|
||||||
add_library(kernel level.cpp diff_cnstrs.cpp expr.cpp expr_eq_fn.cpp
|
add_library(kernel level.cpp diff_cnstrs.cpp expr.cpp expr_eq_fn.cpp
|
||||||
for_each_fn.cpp occurs.cpp replace_fn.cpp free_vars.cpp
|
for_each_fn.cpp occurs.cpp replace_fn.cpp free_vars.cpp abstract.cpp
|
||||||
# abstract.cpp instantiate.cpp
|
instantiate.cpp
|
||||||
# normalizer.cpp context.cpp level.cpp object.cpp environment.cpp
|
# normalizer.cpp context.cpp level.cpp object.cpp environment.cpp
|
||||||
# type_checker.cpp kernel.cpp occurs.cpp metavar.cpp
|
# type_checker.cpp kernel.cpp occurs.cpp metavar.cpp
|
||||||
# justification.cpp unification_constraint.cpp kernel_exception.cpp
|
# justification.cpp unification_constraint.cpp kernel_exception.cpp
|
||||||
|
|
|
@ -294,10 +294,50 @@ unsigned get_depth(expr const & e) {
|
||||||
|
|
||||||
bool operator==(expr const & a, expr const & b) { return expr_eq_fn()(a, b); }
|
bool operator==(expr const & a, expr const & b) { return expr_eq_fn()(a, b); }
|
||||||
|
|
||||||
|
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 mk_app(new_fn, new_arg);
|
||||||
|
else
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr update_proj(expr const & e, expr const & new_arg) {
|
||||||
|
if (!is_eqp(proj_arg(e), new_arg))
|
||||||
|
return mk_proj(is_fst(e), new_arg);
|
||||||
|
else
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr update_pair(expr const & e, expr const & new_first, expr const & new_second, expr const & new_type) {
|
||||||
|
if (!is_eqp(pair_first(e), new_first) || !is_eqp(pair_second(e), new_second) || !is_eqp(pair_type(e), new_type))
|
||||||
|
return mk_pair(new_first, new_second, new_type);
|
||||||
|
else
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
return mk_binder(e.kind(), binder_name(e), new_domain, new_body);
|
||||||
|
else
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr update_let(expr const & e, optional<expr> const & new_type, expr const & new_val, expr const & new_body) {
|
||||||
|
if (!is_eqp(let_type(e), new_type) || !is_eqp(let_value(e), new_val) || !is_eqp(let_body(e), new_body))
|
||||||
|
return mk_let(let_name(e), new_type, new_val, new_body);
|
||||||
|
else
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr update_mlocal(expr const & e, expr const & new_type) {
|
||||||
|
if (!is_eqp(mlocal_type(e), new_type))
|
||||||
|
return mk_mlocal(is_metavar(e), mlocal_name(e), new_type);
|
||||||
|
else
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool is_arrow(expr const & t) {
|
bool is_arrow(expr const & t) {
|
||||||
optional<bool> r = t.raw()->is_arrow();
|
optional<bool> r = t.raw()->is_arrow();
|
||||||
if (r) {
|
if (r) {
|
||||||
|
|
|
@ -122,15 +122,11 @@ public:
|
||||||
friend expr mk_var(unsigned idx);
|
friend expr mk_var(unsigned idx);
|
||||||
friend expr mk_sort(level const & l);
|
friend expr mk_sort(level const & l);
|
||||||
friend expr mk_constant(name const & n, levels const & ls);
|
friend expr mk_constant(name const & n, levels const & ls);
|
||||||
friend expr mk_metavar(name const & n, expr const & t);
|
friend expr mk_mlocal(bool is_meta, name const & n, expr const & t);
|
||||||
friend expr mk_local(name const & n, expr const & t);
|
|
||||||
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_fst(expr const & p);
|
friend expr mk_proj(bool fst, expr const & p);
|
||||||
friend expr mk_snd(expr const & p);
|
friend expr mk_binder(expr_kind k, name const & n, expr const & t, expr const & e);
|
||||||
friend expr mk_lambda(name const & n, expr const & t, expr const & e);
|
|
||||||
friend expr mk_pi(name const & n, expr const & t, expr const & e);
|
|
||||||
friend expr mk_sigma(name const & n, expr const & t, expr const & e);
|
|
||||||
friend expr mk_let(name const & n, optional<expr> const & t, expr const & v, expr const & e);
|
friend expr mk_let(name const & n, optional<expr> const & t, expr const & v, expr const & e);
|
||||||
friend expr mk_macro(macro * m);
|
friend expr mk_macro(macro * m);
|
||||||
|
|
||||||
|
@ -373,18 +369,21 @@ inline expr mk_constant(name const & n, levels const & ls) { return expr(new exp
|
||||||
inline expr mk_constant(name const & n) { return mk_constant(n, levels()); }
|
inline expr mk_constant(name const & n) { return mk_constant(n, levels()); }
|
||||||
inline expr Const(name const & n) { return mk_constant(n); }
|
inline expr Const(name const & n) { return mk_constant(n); }
|
||||||
inline expr mk_macro(macro * m) { return expr(new expr_macro(m)); }
|
inline expr mk_macro(macro * m) { return expr(new expr_macro(m)); }
|
||||||
inline expr mk_metavar(name const & n, expr const & t) { return expr(new expr_mlocal(true, n, t)); }
|
inline expr mk_mlocal(bool is_meta, name const & n, expr const & t) { return expr(new expr_mlocal(is_meta, n, t)); }
|
||||||
inline expr mk_local(name const & n, expr const & t) { return expr(new expr_mlocal(false, n, t)); }
|
inline expr mk_metavar(name const & n, expr const & t) { return mk_mlocal(true, n, t); }
|
||||||
|
inline expr mk_local(name const & n, expr const & t) { return mk_mlocal(false, n, t); }
|
||||||
inline expr mk_pair(expr const & f, expr const & s, expr const & t) { return expr(new expr_dep_pair(f, s, t)); }
|
inline expr mk_pair(expr const & f, expr const & s, expr const & t) { return expr(new expr_dep_pair(f, s, t)); }
|
||||||
inline expr mk_fst(expr const & a) { return expr(new expr_proj(true, a)); }
|
inline expr mk_proj(bool first, expr const & a) { return expr(new expr_proj(first, a)); }
|
||||||
inline expr mk_snd(expr const & a) { return expr(new expr_proj(false, a)); }
|
inline expr mk_fst(expr const & a) { return mk_proj(true, a); }
|
||||||
|
inline expr mk_snd(expr const & a) { return mk_proj(false, a); }
|
||||||
inline expr mk_app(expr const & f, expr const & a) { return expr(new expr_app(f, a)); }
|
inline expr mk_app(expr const & f, expr const & a) { return expr(new expr_app(f, a)); }
|
||||||
expr mk_app(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()); }
|
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(T const & args) { return mk_app(args.size(), args.data()); }
|
||||||
inline expr mk_lambda(name const & n, expr const & t, expr const & e) { return expr(new expr_binder(expr_kind::Lambda, n, t, e)); }
|
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_pi(name const & n, expr const & t, expr const & e) { return expr(new expr_binder(expr_kind::Pi, n, t, e)); }
|
inline expr mk_lambda(name const & n, expr const & t, expr const & e) { return mk_binder(expr_kind::Lambda, n, t, e); }
|
||||||
inline expr mk_sigma(name const & n, expr const & t, expr const & e) { return expr(new expr_binder(expr_kind::Sigma, n, t, e)); }
|
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_sigma(name const & n, expr const & t, expr const & e) { return mk_binder(expr_kind::Sigma, n, t, e); }
|
||||||
inline expr mk_let(name const & n, optional<expr> const & t, expr const & v, expr const & e) {
|
inline expr mk_let(name const & n, optional<expr> const & t, expr const & v, expr const & e) {
|
||||||
return expr(new expr_let(n, t, v, e));
|
return expr(new expr_let(n, t, v, e));
|
||||||
}
|
}
|
||||||
|
@ -556,7 +555,6 @@ struct expr_cell_offset_eqp { unsigned operator()(expr_cell_offset const & p1, e
|
||||||
*/
|
*/
|
||||||
expr copy(expr const & e);
|
expr copy(expr const & e);
|
||||||
|
|
||||||
|
|
||||||
// =======================================
|
// =======================================
|
||||||
// Update
|
// Update
|
||||||
expr update_app(expr const & e, expr const & new_fn, expr const & new_arg);
|
expr update_app(expr const & e, expr const & new_fn, expr const & new_arg);
|
||||||
|
|
|
@ -8,12 +8,11 @@ Author: Leonardo de Moura
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include "kernel/free_vars.h"
|
#include "kernel/free_vars.h"
|
||||||
#include "kernel/replace_fn.h"
|
#include "kernel/replace_fn.h"
|
||||||
#include "kernel/metavar.h"
|
|
||||||
#include "kernel/instantiate.h"
|
#include "kernel/instantiate.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
template<bool ClosedSubst>
|
template<bool ClosedSubst>
|
||||||
expr instantiate_core(expr const & a, unsigned s, unsigned n, expr const * subst, optional<ro_metavar_env> const & menv) {
|
expr instantiate_core(expr const & a, unsigned s, unsigned n, expr const * subst) {
|
||||||
return replace(a, [=](expr const & m, unsigned offset) -> expr {
|
return replace(a, [=](expr const & m, unsigned offset) -> expr {
|
||||||
if (is_var(m)) {
|
if (is_var(m)) {
|
||||||
unsigned vidx = var_idx(m);
|
unsigned vidx = var_idx(m);
|
||||||
|
@ -22,56 +21,45 @@ expr instantiate_core(expr const & a, unsigned s, unsigned n, expr const * subst
|
||||||
if (ClosedSubst)
|
if (ClosedSubst)
|
||||||
return subst[n - (vidx - s - offset) - 1];
|
return subst[n - (vidx - s - offset) - 1];
|
||||||
else
|
else
|
||||||
return lift_free_vars(subst[n - (vidx - s - offset) - 1], offset, menv);
|
return lift_free_vars(subst[n - (vidx - s - offset) - 1], offset);
|
||||||
} else {
|
} else {
|
||||||
return mk_var(vidx - n);
|
return mk_var(vidx - n);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
} else if (is_metavar(m)) {
|
|
||||||
expr r = m;
|
|
||||||
for (unsigned i = 0; i < n; i++) {
|
|
||||||
expr v = ClosedSubst ? subst[i] : lift_free_vars(subst[i], offset + n - i - 1, menv);
|
|
||||||
r = add_inst(r, offset + s + n - i - 1, v, menv);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
} else {
|
} else {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
expr instantiate_with_closed(expr const & a, unsigned n, expr const * s, optional<ro_metavar_env> const & menv) {
|
expr instantiate_with_closed(expr const & e, unsigned s, unsigned n, expr const * subst) { return instantiate_core<true>(e, s, n, subst); }
|
||||||
lean_assert(std::all_of(s, s+n, [&](expr const & e) { return !has_free_var(e, 0, std::numeric_limits<unsigned>::max(), menv); }));
|
expr instantiate_with_closed(expr const & e, unsigned n, expr const * s) { return instantiate_with_closed(e, 0, n, s); }
|
||||||
return instantiate_core<true>(a, 0, n, s, menv);
|
|
||||||
}
|
|
||||||
expr instantiate_with_closed(expr const & e, unsigned n, expr const * s, ro_metavar_env const & menv) { return instantiate_with_closed(e, n, s, some_ro_menv(menv)); }
|
|
||||||
expr instantiate_with_closed(expr const & e, unsigned n, expr const * s) { return instantiate_with_closed(e, n, s, none_ro_menv()); }
|
|
||||||
expr instantiate_with_closed(expr const & e, std::initializer_list<expr> const & l) { return instantiate_with_closed(e, l.size(), l.begin()); }
|
expr instantiate_with_closed(expr const & e, std::initializer_list<expr> const & l) { return instantiate_with_closed(e, l.size(), l.begin()); }
|
||||||
expr instantiate_with_closed(expr const & e, expr const & s, optional<ro_metavar_env> const & menv) { return instantiate_with_closed(e, 1, &s, menv); }
|
|
||||||
expr instantiate_with_closed(expr const & e, expr const & s) { return instantiate_with_closed(e, 1, &s); }
|
expr instantiate_with_closed(expr const & e, expr const & s) { return instantiate_with_closed(e, 1, &s); }
|
||||||
expr instantiate_with_closed(expr const & e, expr const & s, ro_metavar_env const & menv) { return instantiate_with_closed(e, s, some_ro_menv(menv)); }
|
expr instantiate(expr const & e, unsigned s, unsigned n, expr const * subst) { return instantiate_core<false>(e, s, n, subst); }
|
||||||
|
expr instantiate(expr const & e, unsigned n, expr const * s) { return instantiate(e, 0, n, s); }
|
||||||
expr instantiate(expr const & a, unsigned s, unsigned n, expr const * subst, optional<ro_metavar_env> const & menv) {
|
|
||||||
return instantiate_core<false>(a, s, n, subst, menv);
|
|
||||||
}
|
|
||||||
expr instantiate(expr const & e, unsigned n, expr const * s, optional<ro_metavar_env> const & menv) { return instantiate(e, 0, n, s, menv); }
|
|
||||||
expr instantiate(expr const & e, unsigned n, expr const * s, ro_metavar_env const & menv) { return instantiate(e, n, s, some_ro_menv(menv)); }
|
|
||||||
expr instantiate(expr const & e, unsigned n, expr const * s) { return instantiate(e, n, s, none_ro_menv()); }
|
|
||||||
expr instantiate(expr const & e, std::initializer_list<expr> const & l) { return instantiate(e, l.size(), l.begin()); }
|
expr instantiate(expr const & e, std::initializer_list<expr> const & l) { return instantiate(e, l.size(), l.begin()); }
|
||||||
expr instantiate(expr const & e, unsigned i, expr const & s, optional<ro_metavar_env> const & menv) { return instantiate(e, i, 1, &s, menv); }
|
expr instantiate(expr const & e, unsigned i, expr const & s) { return instantiate(e, i, 1, &s); }
|
||||||
expr instantiate(expr const & e, unsigned i, expr const & s, ro_metavar_env const & menv) { return instantiate(e, i, 1, &s, some_ro_menv(menv)); }
|
expr instantiate(expr const & e, expr const & s) { return instantiate(e, 0, s); }
|
||||||
expr instantiate(expr const & e, unsigned i, expr const & s) { return instantiate(e, i, 1, &s, none_ro_menv()); }
|
|
||||||
expr instantiate(expr const & e, expr const & s, optional<ro_metavar_env> const & menv) { return instantiate(e, 1, &s, menv); }
|
|
||||||
expr instantiate(expr const & e, expr const & s, ro_metavar_env const & menv) { return instantiate(e, s, some_ro_menv(menv)); }
|
|
||||||
expr instantiate(expr const & e, expr const & s) { return instantiate(e, s, none_ro_menv()); }
|
|
||||||
|
|
||||||
bool is_head_beta(expr const & t) {
|
bool is_head_beta(expr const & t) {
|
||||||
return is_app(t) && is_lambda(arg(t, 0));
|
expr const * it = &t;
|
||||||
|
while (is_app(*it)) {
|
||||||
|
expr const & f = app_fn(*it);
|
||||||
|
if (is_lambda(f)) {
|
||||||
|
return true;
|
||||||
|
} else if (is_app(f)) {
|
||||||
|
it = &f;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr apply_beta(expr f, unsigned num_args, expr const * args, optional<ro_metavar_env> const & menv) {
|
expr apply_beta(expr f, unsigned num_args, expr const * args) {
|
||||||
if (!is_lambda(f)) {
|
if (!is_lambda(f)) {
|
||||||
buffer<expr> new_args;
|
buffer<expr> new_args;
|
||||||
new_args.push_back(f);
|
new_args.push_back(f);
|
||||||
|
@ -79,12 +67,12 @@ expr apply_beta(expr f, unsigned num_args, expr const * args, optional<ro_metava
|
||||||
return mk_app(new_args);
|
return mk_app(new_args);
|
||||||
} else {
|
} else {
|
||||||
unsigned m = 1;
|
unsigned m = 1;
|
||||||
while (is_lambda(abst_body(f)) && m < num_args) {
|
while (is_lambda(binder_body(f)) && m < num_args) {
|
||||||
f = abst_body(f);
|
f = binder_body(f);
|
||||||
m++;
|
m++;
|
||||||
}
|
}
|
||||||
lean_assert(m <= num_args);
|
lean_assert(m <= num_args);
|
||||||
expr r = instantiate(abst_body(f), m, args, menv);
|
expr r = instantiate(binder_body(f), m, args);
|
||||||
if (m == num_args) {
|
if (m == num_args) {
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,34 +84,40 @@ expr apply_beta(expr f, unsigned num_args, expr const * args, optional<ro_metava
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr apply_beta(expr f, unsigned num_args, expr const * args, ro_metavar_env const & menv) { return apply_beta(f, num_args, args, some_ro_menv(menv)); }
|
|
||||||
expr apply_beta(expr f, unsigned num_args, expr const * args) { return apply_beta(f, num_args, args, none_ro_menv()); }
|
|
||||||
|
|
||||||
expr head_beta_reduce(expr const & t, optional<ro_metavar_env> const & menv) {
|
expr head_beta_reduce(expr const & t) {
|
||||||
if (!is_head_beta(t)) {
|
if (!is_head_beta(t)) {
|
||||||
return t;
|
return t;
|
||||||
} else {
|
} else {
|
||||||
return apply_beta(arg(t, 0), num_args(t) - 1, &arg(t, 1), menv);
|
buffer<expr> args;
|
||||||
|
expr const * it = &t;
|
||||||
|
while (true) {
|
||||||
|
lean_assert(is_app(*it));
|
||||||
|
expr f = app_fn(*it);
|
||||||
|
args.push_back(app_arg(*it));
|
||||||
|
if (is_lambda(f)) {
|
||||||
|
return apply_beta(f, args.size(), args.data());
|
||||||
|
} else {
|
||||||
|
lean_assert(is_app(f));
|
||||||
|
it = &f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr head_beta_reduce(expr const & t) { return head_beta_reduce(t, none_ro_menv()); }
|
|
||||||
expr head_beta_reduce(expr const & t, ro_metavar_env const & menv) { return head_beta_reduce(t, some_ro_menv(menv)); }
|
|
||||||
|
|
||||||
expr beta_reduce(expr t, optional<ro_metavar_env> const & menv) {
|
expr beta_reduce(expr t) {
|
||||||
auto f = [=](expr const & m, unsigned) -> expr {
|
auto f = [=](expr const & m, unsigned) -> expr {
|
||||||
if (is_head_beta(m))
|
if (is_head_beta(m))
|
||||||
return head_beta_reduce(m, menv);
|
return head_beta_reduce(m);
|
||||||
else
|
else
|
||||||
return m;
|
return m;
|
||||||
};
|
};
|
||||||
while (true) {
|
while (true) {
|
||||||
expr new_t = replace_fn<decltype(f)>(f)(t);
|
expr new_t = replace_fn(f)(t);
|
||||||
if (new_t == t)
|
if (new_t == t)
|
||||||
return new_t;
|
return new_t;
|
||||||
else
|
else
|
||||||
t = new_t;
|
t = new_t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr beta_reduce(expr t, ro_metavar_env const & menv) { return beta_reduce(t, some_ro_menv(menv)); }
|
|
||||||
expr beta_reduce(expr t) { return beta_reduce(t, none_ro_menv()); }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,52 +13,21 @@ class ro_metavar_env;
|
||||||
\brief Replace the free variables with indices 0, ..., n-1 with s[n-1], ..., s[0] in e.
|
\brief Replace the free variables with indices 0, ..., n-1 with s[n-1], ..., s[0] in e.
|
||||||
|
|
||||||
\pre s[0], ..., s[n-1] must be closed expressions (i.e., no free variables).
|
\pre s[0], ..., s[n-1] must be closed expressions (i.e., no free variables).
|
||||||
|
|
||||||
\remark When the parameter menv is not none, this function will minimize the use
|
|
||||||
of the local entry inst in metavariables occurring in \c e.
|
|
||||||
*/
|
*/
|
||||||
expr instantiate_with_closed(expr const & e, unsigned n, expr const * s, optional<ro_metavar_env> const & menv);
|
|
||||||
expr instantiate_with_closed(expr const & e, unsigned n, expr const * s, ro_metavar_env const & menv);
|
|
||||||
expr instantiate_with_closed(expr const & e, unsigned n, expr const * s);
|
expr instantiate_with_closed(expr const & e, unsigned n, expr const * s);
|
||||||
expr instantiate_with_closed(expr const & e, std::initializer_list<expr> const & l);
|
expr instantiate_with_closed(expr const & e, std::initializer_list<expr> const & l);
|
||||||
expr instantiate_with_closed(expr const & e, expr const & s, optional<ro_metavar_env> const & menv);
|
|
||||||
expr instantiate_with_closed(expr const & e, expr const & s, ro_metavar_env const & menv);
|
|
||||||
expr instantiate_with_closed(expr const & e, expr const & s);
|
expr instantiate_with_closed(expr const & e, expr const & s);
|
||||||
|
|
||||||
/**
|
/** \brief Replace the free variables with indices 0, ..., n-1 with s[n-1], ..., s[0] in e. */
|
||||||
\brief Replace the free variables with indices 0, ..., n-1 with s[n-1], ..., s[0] in e.
|
|
||||||
|
|
||||||
\remark When the parameter menv is not none, this function will minimize the use
|
|
||||||
of the local entry inst in metavariables occurring in \c e.
|
|
||||||
*/
|
|
||||||
expr instantiate(expr const & e, unsigned n, expr const * s, optional<ro_metavar_env> const & menv);
|
|
||||||
expr instantiate(expr const & e, unsigned n, expr const * s, ro_metavar_env const & menv);
|
|
||||||
expr instantiate(expr const & e, unsigned n, expr const * s);
|
expr instantiate(expr const & e, unsigned n, expr const * s);
|
||||||
expr instantiate(expr const & e, std::initializer_list<expr> const & l);
|
expr instantiate(expr const & e, std::initializer_list<expr> const & l);
|
||||||
/**
|
/** \brief Replace free variable \c i with \c s in \c e. */
|
||||||
\brief Replace free variable \c i with \c s in \c e.
|
|
||||||
*/
|
|
||||||
expr instantiate(expr const & e, unsigned i, expr const & s, optional<ro_metavar_env> const & menv);
|
|
||||||
expr instantiate(expr const & e, unsigned i, expr const & s, ro_metavar_env const & menv);
|
|
||||||
expr instantiate(expr const & e, unsigned i, expr const & s);
|
expr instantiate(expr const & e, unsigned i, expr const & s);
|
||||||
/**
|
/** \brief Replace free variable \c 0 with \c s in \c e. */
|
||||||
\brief Replace free variable \c 0 with \c s in \c e.
|
|
||||||
*/
|
|
||||||
expr instantiate(expr const & e, expr const & s, optional<ro_metavar_env> const & menv);
|
|
||||||
expr instantiate(expr const & e, expr const & s, ro_metavar_env const & menv);
|
|
||||||
expr instantiate(expr const & e, expr const & s);
|
expr instantiate(expr const & e, expr const & s);
|
||||||
|
|
||||||
expr apply_beta(expr f, unsigned num_args, expr const * args, optional<ro_metavar_env> const & menv);
|
|
||||||
expr apply_beta(expr f, unsigned num_args, expr const * args, ro_metavar_env const & menv);
|
|
||||||
expr apply_beta(expr f, unsigned num_args, expr const * args);
|
expr apply_beta(expr f, unsigned num_args, expr const * args);
|
||||||
|
|
||||||
bool is_head_beta(expr const & t);
|
bool is_head_beta(expr const & t);
|
||||||
|
|
||||||
expr head_beta_reduce(expr const & t, optional<ro_metavar_env> const & menv);
|
|
||||||
expr head_beta_reduce(expr const & t, ro_metavar_env const & menv);
|
|
||||||
expr head_beta_reduce(expr const & t);
|
expr head_beta_reduce(expr const & t);
|
||||||
|
|
||||||
expr beta_reduce(expr t, optional<ro_metavar_env> const & menv);
|
|
||||||
expr beta_reduce(expr t, ro_metavar_env const & menv);
|
|
||||||
expr beta_reduce(expr t);
|
expr beta_reduce(expr t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,9 @@ add_test(diff_cnstrs ${CMAKE_CURRENT_BINARY_DIR}/diff_cnstrs)
|
||||||
# target_link_libraries(metavar ${EXTRA_LIBS})
|
# target_link_libraries(metavar ${EXTRA_LIBS})
|
||||||
# add_test(metavar ${CMAKE_CURRENT_BINARY_DIR}/metavar)
|
# add_test(metavar ${CMAKE_CURRENT_BINARY_DIR}/metavar)
|
||||||
# set_tests_properties(metavar PROPERTIES ENVIRONMENT "LEAN_PATH=${LEAN_BINARY_DIR}/shell")
|
# set_tests_properties(metavar PROPERTIES ENVIRONMENT "LEAN_PATH=${LEAN_BINARY_DIR}/shell")
|
||||||
# add_executable(instantiate instantiate.cpp)
|
add_executable(instantiate instantiate.cpp)
|
||||||
# target_link_libraries(instantiate ${EXTRA_LIBS})
|
target_link_libraries(instantiate ${EXTRA_LIBS})
|
||||||
# add_test(instantiate ${CMAKE_CURRENT_BINARY_DIR}/instantiate)
|
add_test(instantiate ${CMAKE_CURRENT_BINARY_DIR}/instantiate)
|
||||||
# add_executable(universe_constraints universe_constraints.cpp)
|
# add_executable(universe_constraints universe_constraints.cpp)
|
||||||
# target_link_libraries(universe_constraints ${EXTRA_LIBS})
|
# target_link_libraries(universe_constraints ${EXTRA_LIBS})
|
||||||
# add_test(universe_constraints ${CMAKE_CURRENT_BINARY_DIR}/universe_constraints)
|
# add_test(universe_constraints ${CMAKE_CURRENT_BINARY_DIR}/universe_constraints)
|
||||||
|
|
|
@ -7,7 +7,6 @@ Author: Leonardo de Moura
|
||||||
#include "util/test.h"
|
#include "util/test.h"
|
||||||
#include "kernel/abstract.h"
|
#include "kernel/abstract.h"
|
||||||
#include "kernel/instantiate.h"
|
#include "kernel/instantiate.h"
|
||||||
#include "kernel/metavar.h"
|
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
|
||||||
static void tst1() {
|
static void tst1() {
|
||||||
|
@ -22,18 +21,14 @@ static void tst1() {
|
||||||
expr N = Const("N");
|
expr N = Const("N");
|
||||||
expr F1 = Fun({x, N}, x)(f, a);
|
expr F1 = Fun({x, N}, x)(f, a);
|
||||||
lean_assert(is_head_beta(F1));
|
lean_assert(is_head_beta(F1));
|
||||||
std::cout << F1 << " --> " << head_beta_reduce(F1) << "\n";
|
lean_assert(head_beta_reduce(F1) == f(a));
|
||||||
lean_assert_eq(head_beta_reduce(F1), f(a));
|
|
||||||
expr F2 = Fun({{h, N >> (N >> (N >> N))}, {y, N}}, h(y))(f, a, b, c);
|
expr F2 = Fun({{h, N >> (N >> (N >> N))}, {y, N}}, h(y))(f, a, b, c);
|
||||||
lean_assert(is_head_beta(F2));
|
lean_assert(is_head_beta(F2));
|
||||||
std::cout << F2 << " --> " << head_beta_reduce(F2) << "\n";
|
lean_assert(head_beta_reduce(F2) == f(a, b, c));
|
||||||
lean_assert_eq(head_beta_reduce(F2), f(a, b, c));
|
|
||||||
expr F3 = Fun({x, N}, f(Fun({y, N}, y)(x), x))(a);
|
expr F3 = Fun({x, N}, f(Fun({y, N}, y)(x), x))(a);
|
||||||
lean_assert(is_head_beta(F3));
|
lean_assert(is_head_beta(F3));
|
||||||
std::cout << F3 << " --> " << head_beta_reduce(F3) << "\n";
|
lean_assert(head_beta_reduce(F3) == f(Fun({y, N}, y)(a), a));
|
||||||
lean_assert_eq(head_beta_reduce(F3), f(Fun({y, N}, y)(a), a));
|
lean_assert(beta_reduce(F3) == f(a, a));
|
||||||
std::cout << F3 << " --> " << beta_reduce(F3) << "\n";
|
|
||||||
lean_assert_eq(beta_reduce(F3), f(a, a));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tst2() {
|
static void tst2() {
|
||||||
|
@ -42,57 +37,12 @@ static void tst2() {
|
||||||
expr f = Const("f");
|
expr f = Const("f");
|
||||||
expr N = Const("N");
|
expr N = Const("N");
|
||||||
expr F1 = Let({x, a}, f(x));
|
expr F1 = Let({x, a}, f(x));
|
||||||
lean_assert_eq(head_beta_reduce(F1), F1);
|
lean_assert(head_beta_reduce(F1) == F1);
|
||||||
}
|
|
||||||
|
|
||||||
static void tst3() {
|
|
||||||
metavar_env menv;
|
|
||||||
expr f = Const("f");
|
|
||||||
expr a = Const("a");
|
|
||||||
expr T = Const("T");
|
|
||||||
expr m1 = menv->mk_metavar();
|
|
||||||
expr m2 = menv->mk_metavar(context({{"x", T}, {"y", T}}));
|
|
||||||
lean_assert_eq(instantiate(f(m1, Var(0)), 0, a, menv), f(m1, a));
|
|
||||||
lean_assert_ne(instantiate(f(m1, Var(0)), 0, a, menv), instantiate(f(m1, Var(0)), 0, a));
|
|
||||||
lean_assert_ne(instantiate(f(m2, Var(0)), 0, a, menv), f(m2, a));
|
|
||||||
lean_assert_eq(instantiate(f(m2, Var(0)), 0, a, menv), f(add_inst(m2, 0, a), a));
|
|
||||||
expr x = Const("x");
|
|
||||||
lean_assert_eq(instantiate(Fun({x, T}, f(m1, Var(1), Var(0))), 0, f(Var(0)), menv),
|
|
||||||
Fun({x, T}, f(m1, f(Var(1)), Var(0))));
|
|
||||||
lean_assert_eq(instantiate(Fun({x, T}, f(m2, Var(1), Var(0))), 0, f(Var(0)), menv),
|
|
||||||
Fun({x, T}, f(add_inst(m2, 1, f(Var(1))), f(Var(1)), Var(0))));
|
|
||||||
lean_assert_eq(instantiate(Fun({x, T}, f(m2, Var(3), Var(0))), 2, f(Var(0)), menv),
|
|
||||||
Fun({x, T}, f(m2, f(Var(1)), Var(0))));
|
|
||||||
lean_assert_eq(instantiate(Fun({x, T}, f(m1, Var(3), Var(0))), 2, f(Var(0)), menv),
|
|
||||||
Fun({x, T}, f(m1, f(Var(1)), Var(0))));
|
|
||||||
lean_assert_eq(instantiate(Fun({x, T}, f(m2, Var(3), Var(0))), 1, f(Var(0)), menv),
|
|
||||||
Fun({x, T}, f(m2, Var(2), Var(0))));
|
|
||||||
expr m3 = menv->mk_metavar(context({{"x", T}, {"y", T}, {"z", T}}));
|
|
||||||
lean_assert_eq(instantiate(Fun({x, T}, f(m3, Var(3), Var(0))), 1, f(Var(0)), menv),
|
|
||||||
Fun({x, T}, f(add_inst(m3, 2, f(Var(1))), Var(2), Var(0))));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tst4() {
|
|
||||||
metavar_env menv;
|
|
||||||
expr T = Const("T");
|
|
||||||
expr m1 = menv->mk_metavar();
|
|
||||||
expr m2 = menv->mk_metavar(context({{"x", T}, {"y", T}}));
|
|
||||||
expr f = Const("f");
|
|
||||||
expr g = Const("f");
|
|
||||||
expr x = Const("x");
|
|
||||||
expr a = Const("a");
|
|
||||||
expr F1 = Fun({x, T}, g(x, m1))(a);
|
|
||||||
expr F2 = Fun({x, T}, g(x, m2))(a);
|
|
||||||
lean_assert_eq(head_beta_reduce(F1, menv), g(a, m1));
|
|
||||||
lean_assert_eq(head_beta_reduce(F1), g(a, add_inst(m1, 0, a)));
|
|
||||||
lean_assert_eq(head_beta_reduce(F2, menv), g(a, add_inst(m2, 0, a)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
save_stack_info();
|
save_stack_info();
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
tst3();
|
|
||||||
tst4();
|
|
||||||
return has_violations() ? 1 : 0;
|
return has_violations() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue