feat(kernel): add trust_imported flag, it skips type checking of 'pre-compiled' Lean modules

"Pre-compiled" .olean files were already type checked. The flag -t instructs to Lean to skip
type checking when importing these files.
TODO: add a check-sum.

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-12-29 03:43:45 -08:00
parent 411ebbc3c1
commit 9fdf2a3f55
3 changed files with 43 additions and 10 deletions

View file

@ -15,6 +15,7 @@ Author: Leonardo de Moura
#include "util/realpath.h" #include "util/realpath.h"
#include "util/sstream.h" #include "util/sstream.h"
#include "util/lean_path.h" #include "util/lean_path.h"
#include "util/flet.h"
#include "kernel/for_each_fn.h" #include "kernel/for_each_fn.h"
#include "kernel/find_fn.h" #include "kernel/find_fn.h"
#include "kernel/kernel_exception.h" #include "kernel/kernel_exception.h"
@ -355,11 +356,13 @@ void environment_cell::check_no_cached_type(expr const & e) {
v is not convertible to \c t. v is not convertible to \c t.
*/ */
void environment_cell::check_type(name const & n, expr const & t, expr const & v) { void environment_cell::check_type(name const & n, expr const & t, expr const & v) {
if (m_type_check) {
m_type_checker->check_type(t); m_type_checker->check_type(t);
expr v_t = m_type_checker->check(v); expr v_t = m_type_checker->check(v);
if (!m_type_checker->is_convertible(v_t, t)) if (!m_type_checker->is_convertible(v_t, t))
throw def_type_mismatch_exception(env(), n, t, v, v_t); throw def_type_mismatch_exception(env(), n, t, v, v_t);
} }
}
/** \brief Throw exception if it is not a valid new definition */ /** \brief Throw exception if it is not a valid new definition */
void environment_cell::check_new_definition(name const & n, expr const & t, expr const & v) { void environment_cell::check_new_definition(name const & n, expr const & t, expr const & v) {
@ -407,7 +410,11 @@ void environment_cell::add_definition(name const & n, expr const & t, expr const
void environment_cell::add_definition(name const & n, expr const & v, bool opaque) { void environment_cell::add_definition(name const & n, expr const & v, bool opaque) {
check_no_cached_type(v); check_no_cached_type(v);
check_name(n); check_name(n);
expr v_t = m_type_checker->check(v); expr v_t;
if (m_type_check)
v_t = m_type_checker->check(v);
else
v_t = m_type_checker->infer_type(v);
unsigned w = get_max_weight(v) + 1; unsigned w = get_max_weight(v) + 1;
register_named_object(mk_definition(n, v_t, v, w)); register_named_object(mk_definition(n, v_t, v, w));
if (opaque) if (opaque)
@ -434,6 +441,7 @@ void environment_cell::set_opaque(name const & n, bool opaque) {
void environment_cell::add_axiom(name const & n, expr const & t) { void environment_cell::add_axiom(name const & n, expr const & t) {
check_no_cached_type(t); check_no_cached_type(t);
check_name(n); check_name(n);
if (m_type_check)
m_type_checker->check_type(t); m_type_checker->check_type(t);
register_named_object(mk_axiom(n, t)); register_named_object(mk_axiom(n, t));
} }
@ -442,6 +450,7 @@ void environment_cell::add_axiom(name const & n, expr const & t) {
void environment_cell::add_var(name const & n, expr const & t) { void environment_cell::add_var(name const & n, expr const & t) {
check_no_cached_type(t); check_no_cached_type(t);
check_name(n); check_name(n);
if (m_type_check)
m_type_checker->check_type(t); m_type_checker->check_type(t);
register_named_object(mk_var_decl(n, t)); register_named_object(mk_var_decl(n, t));
} }
@ -534,6 +543,10 @@ void environment_cell::import_builtin(char const * id, std::function<void()> fn)
} }
} }
void environment_cell::set_trusted_imported(bool flag) {
m_trust_imported = flag;
}
static char const * g_olean_header = "oleanfile"; static char const * g_olean_header = "oleanfile";
static char const * g_olean_end_file = "EndFile"; static char const * g_olean_end_file = "EndFile";
void environment_cell::export_objects(std::string const & fname) { void environment_cell::export_objects(std::string const & fname) {
@ -598,6 +611,7 @@ bool environment_cell::load_core(std::string const & fname, io_state const & ios
} }
bool environment_cell::import(std::string const & fname, io_state const & ios) { bool environment_cell::import(std::string const & fname, io_state const & ios) {
flet<bool> set(m_type_check, !m_trust_imported);
return load_core(realpath(find_file(fname, {".olean"}).c_str()), ios, optional<std::string>(fname)); return load_core(realpath(find_file(fname, {".olean"}).c_str()), ios, optional<std::string>(fname));
} }
@ -607,12 +621,16 @@ void environment_cell::load(std::string const & fname, io_state const & ios) {
environment_cell::environment_cell(): environment_cell::environment_cell():
m_num_children(0) { m_num_children(0) {
m_trust_imported = false;
m_type_check = true;
init_uvars(); init_uvars();
} }
environment_cell::environment_cell(std::shared_ptr<environment_cell> const & parent): environment_cell::environment_cell(std::shared_ptr<environment_cell> const & parent):
m_num_children(0), m_num_children(0),
m_parent(parent) { m_parent(parent) {
m_trust_imported = false;
m_type_check = true;
parent->inc_children(); parent->inc_children();
} }

View file

@ -43,7 +43,8 @@ class environment_cell {
object_dictionary m_object_dictionary; object_dictionary m_object_dictionary;
std::unique_ptr<type_checker> m_type_checker; std::unique_ptr<type_checker> m_type_checker;
std::set<name> m_imported_modules; // set of imported files and builtin modules std::set<name> m_imported_modules; // set of imported files and builtin modules
bool m_trust_imported; // if true, then imported modules are not type checked.
bool m_type_check; // auxiliary flag used to implement m_trust_imported.
std::vector<std::unique_ptr<environment_extension>> m_extensions; std::vector<std::unique_ptr<environment_extension>> m_extensions;
friend class environment_extension; friend class environment_extension;
@ -324,6 +325,12 @@ public:
void load(std::string const & fname, io_state const & ios); void load(std::string const & fname, io_state const & ios);
/**
\brief When trusted_imported flag is true, the environment will
not type check imported modules.
*/
void set_trusted_imported(bool flag);
/** /**
\brief Execute function \c fn. Any object created by \c fn \brief Execute function \c fn. Any object created by \c fn
is not exported by the environment. is not exported by the environment.

View file

@ -65,6 +65,7 @@ static void display_help(std::ostream & out) {
std::cout << " --luahook=num -c how often the Lua interpreter checks the interrupted flag,\n"; std::cout << " --luahook=num -c how often the Lua interpreter checks the interrupted flag,\n";
std::cout << " it is useful for interrupting non-terminating user scripts,\n"; std::cout << " it is useful for interrupting non-terminating user scripts,\n";
std::cout << " 0 means 'do not check'.\n"; std::cout << " 0 means 'do not check'.\n";
std::cout << " --trust -t trust imported modules\n";
#if defined(LEAN_USE_BOOST) #if defined(LEAN_USE_BOOST)
std::cout << " --tstack=num -s thread stack size in Kb\n"; std::cout << " --tstack=num -s thread stack size in Kb\n";
#endif #endif
@ -95,6 +96,7 @@ static struct option g_long_options[] = {
{"luahook", required_argument, 0, 'c'}, {"luahook", required_argument, 0, 'c'},
{"githash", no_argument, 0, 'g'}, {"githash", no_argument, 0, 'g'},
{"output", required_argument, 0, 'o'}, {"output", required_argument, 0, 'o'},
{"trust", no_argument, 0, 't'},
#if defined(LEAN_USE_BOOST) #if defined(LEAN_USE_BOOST)
{"tstack", required_argument, 0, 's'}, {"tstack", required_argument, 0, 's'},
#endif #endif
@ -107,10 +109,11 @@ int main(int argc, char ** argv) {
lean::register_modules(); lean::register_modules();
bool kernel_only = false; bool kernel_only = false;
bool export_objects = false; bool export_objects = false;
bool trust_imported = false;
std::string output; std::string output;
input_kind default_k = input_kind::Lean; // default input_kind default_k = input_kind::Lean; // default
while (true) { while (true) {
int c = getopt_long(argc, argv, "klupgvhc:012s:012o:", g_long_options, NULL); int c = getopt_long(argc, argv, "tklupgvhc:012s:012o:", g_long_options, NULL);
if (c == -1) if (c == -1)
break; // end of command line break; // end of command line
switch (c) { switch (c) {
@ -148,6 +151,9 @@ int main(int argc, char ** argv) {
output = optarg; output = optarg;
export_objects = true; export_objects = true;
break; break;
case 't':
trust_imported = true;
break;
default: default:
std::cerr << "Unknown command line option\n"; std::cerr << "Unknown command line option\n";
display_help(std::cerr); display_help(std::cerr);
@ -164,6 +170,7 @@ int main(int argc, char ** argv) {
std::cout << "Type Ctrl-D or 'Exit.' to exit or 'Help.' for help."<< std::endl; std::cout << "Type Ctrl-D or 'Exit.' to exit or 'Help.' for help."<< std::endl;
#endif #endif
environment env; environment env;
env->set_trusted_imported(trust_imported);
io_state ios; io_state ios;
init_frontend(env, ios, kernel_only); init_frontend(env, ios, kernel_only);
script_state S; script_state S;
@ -179,6 +186,7 @@ int main(int argc, char ** argv) {
} }
} else { } else {
environment env; environment env;
env->set_trusted_imported(trust_imported);
io_state ios; io_state ios;
init_frontend(env, ios, kernel_only); init_frontend(env, ios, kernel_only);
script_state S; script_state S;