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/locals.h"
#include "library/coercion.h" #include "library/coercion.h"
#include "library/reducible.h" #include "library/reducible.h"
#include "library/normalize.h"
#include "frontends/lean/util.h" #include "frontends/lean/util.h"
#include "frontends/lean/parser.h" #include "frontends/lean/parser.h"
#include "frontends/lean/calc.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(); expr e = p.parse_expr();
list<expr> ctx = locals_to_context(e, p); list<expr> ctx = locals_to_context(e, p);
level_param_names ls = to_level_param_names(collect_univ_params(e)); level_param_names ls = to_level_param_names(collect_univ_params(e));
level_param_names new_ls; level_param_names new_ls;
std::tie(e, new_ls) = p.elaborate_relaxed(e, ctx); 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); 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(); auto reg = p.regular_stream();
formatter const & fmt = reg.get_formatter(); formatter const & fmt = reg.get_formatter();
options opts = p.ios().get_options(); options opts = p.ios().get_options();
@ -100,6 +108,14 @@ environment check_cmd(parser & p) {
return p.env(); 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 &) { environment exit_cmd(parser &) {
throw interrupt_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("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("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("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("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("reducible", "mark definitions as reducible/irreducible for automation", reducible_cmd));
add_cmd(r, cmd_info("irreducible", "mark definitions as irreducible for automation", irreducible_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", char const * commands[] = {"theorem", "axiom", "variable", "protected", "private", "opaque", "definition", "coercion",
"variables", "[persistent]", "[visible]", "[instance]", "variables", "[persistent]", "[visible]", "[instance]",
"[off]", "[on]", "[none]", "[class]", "[coercion]", "[reducible]", "reducible", "irreducible", "[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", "inductive", "record", "renaming", "extends", "structure", "module", "universe",
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation", "context", "precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation", "context",
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "tactic_hint", "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 <memory>
#include <utility> #include <utility>
#include <algorithm> #include <algorithm>
#include "util/flet.h"
#include "util/name_generator.h" #include "util/name_generator.h"
#include "util/name_set.h" #include "util/name_set.h"
#include "kernel/environment.h" #include "kernel/environment.h"
@ -204,6 +205,12 @@ public:
bool is_opaque(declaration const & d) const; bool is_opaque(declaration const & d) const;
/** \brief Return true iff the constant \c c is opaque with respect to this type checker. */ /** \brief Return true iff the constant \c c is opaque with respect to this type checker. */
bool is_opaque(expr const & c) const; 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; 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/io_state.h"
#include "library/kernel_bindings.h" #include "library/kernel_bindings.h"
#include "library/match.h" #include "library/match.h"
#include "library/normalize.h"
#include "library/sorry.h" #include "library/sorry.h"
#include "library/placeholder.h" #include "library/placeholder.h"
#include "library/print.h" #include "library/print.h"
@ -35,7 +34,6 @@ void initialize_library_module() {
initialize_print(); initialize_print();
initialize_placeholder(); initialize_placeholder();
initialize_match(); initialize_match();
initialize_normalize();
initialize_kernel_bindings(); initialize_kernel_bindings();
initialize_io_state(); initialize_io_state();
initialize_unifier(); initialize_unifier();
@ -81,7 +79,6 @@ void finalize_library_module() {
finalize_unifier(); finalize_unifier();
finalize_io_state(); finalize_io_state();
finalize_kernel_bindings(); finalize_kernel_bindings();
finalize_normalize();
finalize_match(); finalize_match();
finalize_placeholder(); finalize_placeholder();
finalize_print(); finalize_print();

View file

@ -8,21 +8,12 @@ Author: Leonardo de Moura
#include "kernel/type_checker.h" #include "kernel/type_checker.h"
#include "kernel/instantiate.h" #include "kernel/instantiate.h"
#include "kernel/abstract.h" #include "kernel/abstract.h"
#include "library/reducible.h"
namespace lean { 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 { class normalize_fn {
type_checker m_tc; std::unique_ptr<type_checker> m_tc;
name_generator m_ngen; name_generator m_ngen;
expr normalize_binding(expr const & e) { expr normalize_binding(expr const & e) {
expr d = normalize(binding_domain(e)); expr d = normalize(binding_domain(e));
@ -40,7 +31,7 @@ class normalize_fn {
} }
expr normalize(expr e) { expr normalize(expr e) {
e = m_tc.whnf(e).first; e = m_tc->whnf(e).first;
switch (e.kind()) { switch (e.kind()) {
case expr_kind::Var: case expr_kind::Constant: case expr_kind::Sort: case expr_kind::Var: case expr_kind::Constant: case expr_kind::Sort:
case expr_kind::Meta: case expr_kind::Local: case expr_kind::Macro: case expr_kind::Meta: case expr_kind::Local: case expr_kind::Macro:
@ -54,9 +45,15 @@ class normalize_fn {
} }
public: 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()(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, 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 { namespace lean {
/** \brief Return the \c e normal form with respect to the environment \c env. */ /** \brief Return the \c e normal form with respect to the environment \c env. */
expr normalize(environment const & env, expr const & e); expr normalize(environment const & env, expr const & e);
void initialize_normalize(); expr normalize(environment const & env, level_param_names const & ls, expr const & e);
void finalize_normalize();
} }

View file

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