feat(library/compiler): do not generate code for decls that have irrelevant types

We were generating hundreds of definitions that just return
`lean::box(0)`.
This commit is contained in:
Leonardo de Moura 2019-03-07 12:48:16 -08:00
parent 057d90b7ff
commit 67f4698593
5 changed files with 13 additions and 20 deletions

View file

@ -136,10 +136,14 @@ bool is_main_fn_type(expr const & type) {
}
}
environment compile(environment const & env, options const & opts, names const & cs) {
environment compile(environment const & env, options const & opts, names cs) {
if (!is_codegen_enabled(opts))
return env;
/* Do not generate code for irrelevant decls */
cs = filter(cs, [&](name const & c) { return !is_irrelevant_type(env, env.get(c).get_type());});
if (empty(cs)) return env;
for (name const & c : cs) {
if (is_main_fn(env, c) && !is_main_fn_type(env.get(c).get_type())) {
throw exception("invalid `main` function, it must have type `list string -> io uint32`");

View file

@ -7,7 +7,7 @@ Author: Leonardo de Moura
#pragma once
#include "kernel/environment.h"
namespace lean {
environment compile(environment const & env, options const & opts, names const & cs);
environment compile(environment const & env, options const & opts, names cs);
inline environment compile(environment const & env, options const & opts, name const & c) {
return compile(env, opts, names(c));
}

View file

@ -317,25 +317,8 @@ public:
default:
break;
}
if (is_lc_proof(e)) return false;
type_checker tc(m_st, m_lctx);
e_type = tc.whnf(e_type);
if (is_sort(e_type)) {
return false;
} else if (tc.is_prop(e_type)) {
return false;
} else if (is_pi(e_type)) {
/* Functions that return types are not relevant */
flet<local_ctx> save_lctx(m_lctx, m_lctx);
while (is_pi(e_type)) {
expr fvar = m_lctx.mk_local_decl(ngen(), binding_name(e_type), binding_domain(e_type));
e_type = whnf(instantiate(binding_body(e_type), fvar));
}
if (is_sort(e_type))
return false;
}
if (is_irrelevant_type(m_st, m_lctx, e_type)) return false;
return true;
}

View file

@ -434,6 +434,11 @@ bool is_irrelevant_type(type_checker::state & st, local_ctx lctx, expr const & t
return false;
}
bool is_irrelevant_type(environment const & env, expr const & type) {
type_checker::state st(env);
return is_irrelevant_type(st, local_context(), type);
}
void collect_used(expr const & e, name_hash_set & S) {
if (!has_fvar(e)) return;
for_each(e, [&](expr const & e, unsigned) {

View file

@ -148,6 +148,7 @@ inline bool is_runtime_builtin_type(expr const & e) {
bool is_runtime_scalar_type(name const & n);
bool is_irrelevant_type(type_checker::state & st, local_ctx lctx, expr const & type);
bool is_irrelevant_type(environment const & env, expr const & type);
void collect_used(expr const & e, name_hash_set & S);
/* Return true iff `e` contains a free variable in `s` */