Add eta-reduction

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-07-26 12:37:13 -07:00
parent ed13132c12
commit a241d5f4b1
2 changed files with 9 additions and 8 deletions

View file

@ -293,6 +293,7 @@ inline expr_numeral * to_numeral(expr const & e) { return to_numeral(e.r
inline unsigned get_rc(expr_cell * e) { return e->get_rc(); } inline unsigned get_rc(expr_cell * e) { return e->get_rc(); }
inline bool is_shared(expr_cell * e) { return get_rc(e) > 1; } inline bool is_shared(expr_cell * e) { return get_rc(e) > 1; }
inline unsigned var_idx(expr_cell * e) { return to_var(e)->get_vidx(); } inline unsigned var_idx(expr_cell * e) { return to_var(e)->get_vidx(); }
inline bool is_var(expr_cell * e, unsigned i) { return is_var(e) && var_idx(e) == i; }
inline name const & const_name(expr_cell * e) { return to_constant(e)->get_name(); } inline name const & const_name(expr_cell * e) { return to_constant(e)->get_name(); }
inline unsigned const_pos(expr_cell * e) { return to_constant(e)->get_pos(); } inline unsigned const_pos(expr_cell * e) { return to_constant(e)->get_pos(); }
inline unsigned num_args(expr_cell * e) { return to_app(e)->get_num_args(); } inline unsigned num_args(expr_cell * e) { return to_app(e)->get_num_args(); }
@ -307,6 +308,7 @@ inline mpz const & num_value(expr_cell * e) { return to_numeral(e)->
inline unsigned get_rc(expr const & e) { return e.raw()->get_rc(); } inline unsigned get_rc(expr const & e) { return e.raw()->get_rc(); }
inline bool is_shared(expr const & e) { return get_rc(e) > 1; } inline bool is_shared(expr const & e) { return get_rc(e) > 1; }
inline unsigned var_idx(expr const & e) { return to_var(e)->get_vidx(); } inline unsigned var_idx(expr const & e) { return to_var(e)->get_vidx(); }
inline bool is_var(expr const & e, unsigned i) { return is_var(e) && var_idx(e) == i; }
inline name const & const_name(expr const & e) { return to_constant(e)->get_name(); } inline name const & const_name(expr const & e) { return to_constant(e)->get_name(); }
inline unsigned const_pos(expr const & e) { return to_constant(e)->get_pos(); } inline unsigned const_pos(expr const & e) { return to_constant(e)->get_pos(); }
inline unsigned num_args(expr const & e) { return to_app(e)->get_num_args(); } inline unsigned num_args(expr const & e) { return to_app(e)->get_num_args(); }

View file

@ -6,6 +6,7 @@ Author: Leonardo de Moura
*/ */
#include <algorithm> #include <algorithm>
#include "expr.h" #include "expr.h"
#include "free_vars.h"
#include "list.h" #include "list.h"
#include "buffer.h" #include "buffer.h"
#include "trace.h" #include "trace.h"
@ -63,27 +64,25 @@ expr reify_closure(expr const & a, context const & c, unsigned k) {
lean_assert(is_lambda(a)); lean_assert(is_lambda(a));
expr new_t = reify(normalize(abst_type(a), c, k), k); expr new_t = reify(normalize(abst_type(a), c, k), k);
expr new_b = reify(normalize(abst_body(a), extend(c, value(k)), k+1), k+1); expr new_b = reify(normalize(abst_body(a), extend(c, value(k)), k+1), k+1);
return lambda(abst_name(a), new_t, new_b);
#if 0
// TODO: ETA-reduction // TODO: ETA-reduction
if (is_app(new_b)) { if (is_app(new_b)) {
// (lambda (x:T) (app f ... (var 0))) // (lambda (x:T) (app f ... (var 0)))
// check eta-rule applicability // check eta-rule applicability
unsigned n = num_args(new_b); unsigned n = num_args(new_b);
lean_assert(n >= 2); if (is_var(arg(new_b, n - 1), 0) &&
expr const & last_arg = arg(new_b, n - 1); std::all_of(begin_args(new_b),
if (is_var(last_arg) && var_idx(last_arg) == 0) { end_args(new_b) - 1,
[](expr const & arg) { return !has_free_var(arg, 0); })) {
if (n == 2) if (n == 2)
return arg(new_b, 0); return lower_free_vars(arg(new_b, 0), 1);
else else
return app(n - 1, begin_args(new_b)); return lower_free_vars(app(n - 1, begin_args(new_b)), 1);
} }
return lambda(abst_name(a), new_t, new_b); return lambda(abst_name(a), new_t, new_b);
} }
else { else {
return lambda(abst_name(a), new_t, new_b); return lambda(abst_name(a), new_t, new_b);
} }
#endif
} }
expr reify(value const & v, unsigned k) { expr reify(value const & v, unsigned k) {
lean_trace("normalize", tout << "Reify kind: " << static_cast<unsigned>(v.kind()) << "\n"; lean_trace("normalize", tout << "Reify kind: " << static_cast<unsigned>(v.kind()) << "\n";