fix(frontends/lean): add 'eval' command

This commit is contained in:
Leonardo de Moura 2014-09-26 20:16:03 -07:00
parent 345b65a91b
commit 8e7aac1eb4
10 changed files with 58 additions and 22 deletions

View file

@ -17,6 +17,7 @@ Author: Leonardo de Moura
#include "library/locals.h"
#include "library/coercion.h"
#include "library/reducible.h"
#include "library/normalize.h"
#include "frontends/lean/util.h"
#include "frontends/lean/parser.h"
#include "frontends/lean/calc.h"
@ -83,14 +84,21 @@ environment end_scoped_cmd(parser & p) {
}
}
environment check_cmd(parser & p) {
/** \brief Auxiliary function for check/eval */
static std::tuple<expr, level_param_names> parse_local_expr(parser & p) {
expr e = p.parse_expr();
list<expr> ctx = locals_to_context(e, p);
level_param_names ls = to_level_param_names(collect_univ_params(e));
level_param_names new_ls;
std::tie(e, new_ls) = p.elaborate_relaxed(e, ctx);
return std::make_tuple(e, append(ls, new_ls));
}
environment check_cmd(parser & p) {
expr e; level_param_names ls;
std::tie(e, ls) = parse_local_expr(p);
auto tc = mk_type_checker(p.env(), p.mk_ngen(), true);
expr type = tc->check(e, append(ls, new_ls)).first;
expr type = tc->check(e, ls).first;
auto reg = p.regular_stream();
formatter const & fmt = reg.get_formatter();
options opts = p.ios().get_options();
@ -100,6 +108,14 @@ environment check_cmd(parser & p) {
return p.env();
}
environment eval_cmd(parser & p) {
expr e; level_param_names ls;
std::tie(e, ls) = parse_local_expr(p);
expr r = normalize(p.env(), ls, e);
p.regular_stream() << r << endl;
return p.env();
}
environment exit_cmd(parser &) {
throw interrupt_parser();
}
@ -358,6 +374,7 @@ void init_cmd_table(cmd_table & r) {
add_cmd(r, cmd_info("namespace", "open a new namespace", namespace_cmd));
add_cmd(r, cmd_info("end", "close the current namespace/section", end_scoped_cmd));
add_cmd(r, cmd_info("check", "type check given expression, and display its type", check_cmd));
add_cmd(r, cmd_info("eval", "evaluate given expression", eval_cmd));
add_cmd(r, cmd_info("coercion", "add a new coercion", coercion_cmd));
add_cmd(r, cmd_info("reducible", "mark definitions as reducible/irreducible for automation", reducible_cmd));
add_cmd(r, cmd_info("irreducible", "mark definitions as irreducible for automation", irreducible_cmd));

View file

@ -79,7 +79,7 @@ void init_token_table(token_table & t) {
char const * commands[] = {"theorem", "axiom", "variable", "protected", "private", "opaque", "definition", "coercion",
"variables", "[persistent]", "[visible]", "[instance]",
"[off]", "[on]", "[none]", "[class]", "[coercion]", "[reducible]", "reducible", "irreducible",
"evaluate", "check", "print", "end", "namespace", "section", "import",
"evaluate", "check", "eval", "print", "end", "namespace", "section", "import",
"inductive", "record", "renaming", "extends", "structure", "module", "universe",
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation", "context",
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "tactic_hint",

View file

@ -8,6 +8,7 @@ Author: Leonardo de Moura
#include <memory>
#include <utility>
#include <algorithm>
#include "util/flet.h"
#include "util/name_generator.h"
#include "util/name_set.h"
#include "kernel/environment.h"
@ -204,6 +205,12 @@ public:
bool is_opaque(declaration const & d) const;
/** \brief Return true iff the constant \c c is opaque with respect to this type checker. */
bool is_opaque(expr const & c) const;
template<typename F>
typename std::result_of<F()>::type with_params(level_param_names const & ps, F && f) {
flet<level_param_names const *> updt(m_params, &ps);
return f();
}
};
typedef std::shared_ptr<type_checker> type_checker_ref;

View file

@ -25,7 +25,6 @@ Author: Leonardo de Moura
#include "library/io_state.h"
#include "library/kernel_bindings.h"
#include "library/match.h"
#include "library/normalize.h"
#include "library/sorry.h"
#include "library/placeholder.h"
#include "library/print.h"
@ -35,7 +34,6 @@ void initialize_library_module() {
initialize_print();
initialize_placeholder();
initialize_match();
initialize_normalize();
initialize_kernel_bindings();
initialize_io_state();
initialize_unifier();
@ -81,7 +79,6 @@ void finalize_library_module() {
finalize_unifier();
finalize_io_state();
finalize_kernel_bindings();
finalize_normalize();
finalize_match();
finalize_placeholder();
finalize_print();

View file

@ -8,20 +8,11 @@ Author: Leonardo de Moura
#include "kernel/type_checker.h"
#include "kernel/instantiate.h"
#include "kernel/abstract.h"
#include "library/reducible.h"
namespace lean {
static name * g_tmp_prefix = nullptr;
void initialize_normalize() {
g_tmp_prefix = new name(name::mk_internal_unique_name());
}
void finalize_normalize() {
delete g_tmp_prefix;
}
class normalize_fn {
type_checker m_tc;
std::unique_ptr<type_checker> m_tc;
name_generator m_ngen;
expr normalize_binding(expr const & e) {
@ -40,7 +31,7 @@ class normalize_fn {
}
expr normalize(expr e) {
e = m_tc.whnf(e).first;
e = m_tc->whnf(e).first;
switch (e.kind()) {
case expr_kind::Var: case expr_kind::Constant: case expr_kind::Sort:
case expr_kind::Meta: case expr_kind::Local: case expr_kind::Macro:
@ -54,9 +45,15 @@ class normalize_fn {
}
public:
normalize_fn(environment const & env):m_tc(env), m_ngen(*g_tmp_prefix) {}
normalize_fn(environment const & env):m_tc(mk_type_checker(env, true)), m_ngen(m_tc->mk_ngen()) {}
expr operator()(expr const & e) { return normalize(e); }
expr operator()(level_param_names const & ls, expr const & e) {
return m_tc->with_params(ls, [&]() {
return normalize(e);
});
}
};
expr normalize(environment const & env, expr const & e) { return normalize_fn(env)(e); }
expr normalize(environment const & env, level_param_names const & ls, expr const & e) { return normalize_fn(env)(ls, e); }
}

View file

@ -10,6 +10,5 @@ Author: Leonardo de Moura
namespace lean {
/** \brief Return the \c e normal form with respect to the environment \c env. */
expr normalize(environment const & env, expr const & e);
void initialize_normalize();
void finalize_normalize();
expr normalize(environment const & env, level_param_names const & ls, expr const & e);
}

View file

@ -71,14 +71,18 @@ struct reducible_config {
template class scoped_ext<reducible_config>;
typedef scoped_ext<reducible_config> reducible_ext;
static name * g_tmp_prefix = nullptr;
void initialize_reducible() {
g_class_name = new name("reducible");
g_key = new std::string("redu");
g_tmp_prefix = new name(name::mk_internal_unique_name());
reducible_ext::initialize();
}
void finalize_reducible() {
reducible_ext::finalize();
delete g_tmp_prefix;
delete g_key;
delete g_class_name;
}
@ -128,4 +132,7 @@ std::unique_ptr<type_checker> mk_type_checker(environment const & env, name_gene
true, pred)));
}
}
std::unique_ptr<type_checker> mk_type_checker(environment const & env, bool relax_main_opaque, bool only_main_reducible) {
return mk_type_checker(env, name_generator(*g_tmp_prefix), relax_main_opaque, only_main_reducible);
}
}

View file

@ -36,6 +36,7 @@ bool is_reducible_off(environment const & env, name const & n);
/** \brief Create a type checker that takes the "reducibility" hints into account. */
std::unique_ptr<type_checker> mk_type_checker(environment const & env, name_generator const & ngen,
bool relax_main_opaque, bool only_main_reducible = false);
std::unique_ptr<type_checker> mk_type_checker(environment const & env, bool relax_main_opaque, bool only_main_reducible = false);
void initialize_reducible();
void finalize_reducible();

7
tests/lean/num5.lean Normal file
View file

@ -0,0 +1,7 @@
import data.num
open num
eval 3+2
eval 3+2*5
eval 5*5
eval eq.rec (eq.refl 2) (eq.refl 2)

View file

@ -0,0 +1,4 @@
5
13
25
eq.refl 2