feat(library/modules): add option for discarding the proof of imported theorems (after checking them)
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
28b9d17a14
commit
ade5d99023
5 changed files with 70 additions and 40 deletions
|
@ -1165,17 +1165,19 @@ static void to_string_buffer(lua_State * L, int i, buffer<std::string> & r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int import_modules(environment const & env, lua_State * L, int s) {
|
static int import_modules(environment const & env, lua_State * L, int s) {
|
||||||
|
int nargs = lua_gettop(L);
|
||||||
buffer<std::string> mnames;
|
buffer<std::string> mnames;
|
||||||
to_string_buffer(L, s, mnames);
|
to_string_buffer(L, s, mnames);
|
||||||
unsigned num_threads = 1;
|
unsigned num_threads = 1;
|
||||||
int nargs = lua_gettop(L);
|
bool keep_proofs = false;
|
||||||
if (nargs > s)
|
if (nargs > s)
|
||||||
num_threads = lua_tonumber(L, s+1);
|
num_threads = lua_tonumber(L, s+1);
|
||||||
|
if (nargs > s+1)
|
||||||
if (nargs > s + 1 && is_io_state(L, s+2))
|
keep_proofs = lua_toboolean(L, s+2);
|
||||||
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, to_io_state(L, s+2)));
|
if (nargs > s+2 && is_io_state(L, s+3))
|
||||||
|
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, keep_proofs, to_io_state(L, s+3)));
|
||||||
else
|
else
|
||||||
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, get_io_state(L)));
|
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, keep_proofs, get_io_state(L)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int import_modules(lua_State * L) {
|
static int import_modules(lua_State * L) {
|
||||||
|
|
|
@ -107,30 +107,6 @@ environment add(environment const & env, std::string const & k, std::function<vo
|
||||||
|
|
||||||
static std::string g_decl("decl");
|
static std::string g_decl("decl");
|
||||||
|
|
||||||
static void declaration_reader(deserializer & d, module_idx midx, shared_environment & senv,
|
|
||||||
std::function<void(asynch_update_fn const &)> & add_asynch_update,
|
|
||||||
std::function<void(delayed_update_fn const &)> &) {
|
|
||||||
declaration decl = read_declaration(d, midx);
|
|
||||||
environment env = senv.env();
|
|
||||||
if (env.trust_lvl() > LEAN_BELIEVER_TRUST_LEVEL) {
|
|
||||||
senv.add(decl);
|
|
||||||
} else if (LEAN_ASYNCH_IMPORT_THEOREM && decl.is_theorem()) {
|
|
||||||
// First, we add the theorem as an axiom, and create an asychronous task for
|
|
||||||
// checking the actual theorem, and replace the axiom with the actual theorem.
|
|
||||||
certified_declaration tmp_c = check(env, mk_axiom(decl.get_name(), decl.get_params(), decl.get_type()));
|
|
||||||
senv.add(tmp_c);
|
|
||||||
add_asynch_update([=](shared_environment & senv) {
|
|
||||||
certified_declaration c = check(env, decl);
|
|
||||||
senv.replace(c);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
certified_declaration c = check(env, decl);
|
|
||||||
senv.add(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static register_module_object_reader_fn g_reg_decl_reader(g_decl, declaration_reader);
|
|
||||||
|
|
||||||
environment add(environment const & env, certified_declaration const & d) {
|
environment add(environment const & env, certified_declaration const & d) {
|
||||||
environment new_env = env.add(d);
|
environment new_env = env.add(d);
|
||||||
declaration _d = d.get_declaration();
|
declaration _d = d.get_declaration();
|
||||||
|
@ -174,6 +150,7 @@ struct import_modules_fn {
|
||||||
typedef std::tuple<module_idx, unsigned, delayed_update_fn> delayed_update;
|
typedef std::tuple<module_idx, unsigned, delayed_update_fn> delayed_update;
|
||||||
shared_environment m_senv;
|
shared_environment m_senv;
|
||||||
unsigned m_num_threads;
|
unsigned m_num_threads;
|
||||||
|
bool m_keep_proofs;
|
||||||
io_state m_ios;
|
io_state m_ios;
|
||||||
mutex m_asynch_mutex;
|
mutex m_asynch_mutex;
|
||||||
condition_variable m_asynch_cv;
|
condition_variable m_asynch_cv;
|
||||||
|
@ -195,8 +172,8 @@ struct import_modules_fn {
|
||||||
typedef std::shared_ptr<module_info> module_info_ptr;
|
typedef std::shared_ptr<module_info> module_info_ptr;
|
||||||
std::unordered_map<std::string, module_info_ptr> m_module_info;
|
std::unordered_map<std::string, module_info_ptr> m_module_info;
|
||||||
|
|
||||||
import_modules_fn(environment const & env, unsigned num_threads, io_state const & ios):
|
import_modules_fn(environment const & env, unsigned num_threads, bool keep_proofs, io_state const & ios):
|
||||||
m_senv(env), m_num_threads(num_threads), m_ios(ios),
|
m_senv(env), m_num_threads(num_threads), m_keep_proofs(keep_proofs), m_ios(ios),
|
||||||
m_import_counter(0), m_all_modules_imported(false) {
|
m_import_counter(0), m_all_modules_imported(false) {
|
||||||
if (m_num_threads == 0)
|
if (m_num_threads == 0)
|
||||||
m_num_threads = 1;
|
m_num_threads = 1;
|
||||||
|
@ -273,6 +250,41 @@ struct import_modules_fn {
|
||||||
add_asynch_task([=](shared_environment &) { import_module(r); });
|
add_asynch_task([=](shared_environment &) { import_module(r); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declaration theorem2axiom(declaration const & decl) {
|
||||||
|
lean_assert(decl.is_theorem());
|
||||||
|
return mk_axiom(decl.get_name(), decl.get_params(), decl.get_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
void import_decl(deserializer & d, module_idx midx) {
|
||||||
|
declaration decl = read_declaration(d, midx);
|
||||||
|
environment env = m_senv.env();
|
||||||
|
if (env.trust_lvl() > LEAN_BELIEVER_TRUST_LEVEL) {
|
||||||
|
if (!m_keep_proofs && decl.is_theorem())
|
||||||
|
m_senv.add(theorem2axiom(decl));
|
||||||
|
else
|
||||||
|
m_senv.add(decl);
|
||||||
|
} else if (LEAN_ASYNCH_IMPORT_THEOREM && decl.is_theorem()) {
|
||||||
|
// First, we add the theorem as an axiom, and create an asychronous task for
|
||||||
|
// checking the actual theorem, and replace the axiom with the actual theorem.
|
||||||
|
certified_declaration tmp_c = check(env, theorem2axiom(decl));
|
||||||
|
m_senv.add(tmp_c);
|
||||||
|
add_asynch_task([=](shared_environment & m_senv) {
|
||||||
|
certified_declaration c = check(env, decl);
|
||||||
|
if (m_keep_proofs)
|
||||||
|
m_senv.replace(c);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (!m_keep_proofs && decl.is_theorem()) {
|
||||||
|
// check theorem, but add an axiom
|
||||||
|
check(env, decl);
|
||||||
|
m_senv.add(check(env, theorem2axiom(decl)));
|
||||||
|
} else {
|
||||||
|
certified_declaration c = check(env, decl);
|
||||||
|
m_senv.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void import_module(module_info_ptr const & r) {
|
void import_module(module_info_ptr const & r) {
|
||||||
std::string s(r->m_obj_code.data(), r->m_obj_code.size());
|
std::string s(r->m_obj_code.data(), r->m_obj_code.size());
|
||||||
std::istringstream in(s, std::ios_base::binary);
|
std::istringstream in(s, std::ios_base::binary);
|
||||||
|
@ -291,14 +303,16 @@ struct import_modules_fn {
|
||||||
d >> k;
|
d >> k;
|
||||||
if (k == g_olean_end_file) {
|
if (k == g_olean_end_file) {
|
||||||
break;
|
break;
|
||||||
|
} else if (k == g_decl) {
|
||||||
|
import_decl(d, r->m_module_idx);
|
||||||
} else {
|
} else {
|
||||||
object_readers & readers = get_object_readers();
|
object_readers & readers = get_object_readers();
|
||||||
auto it = readers.find(k);
|
auto it = readers.find(k);
|
||||||
if (it == readers.end())
|
if (it == readers.end())
|
||||||
throw exception(sstream() << "file '" << r->m_fname << "' has been corrupted");
|
throw exception(sstream() << "file '" << r->m_fname << "' has been corrupted");
|
||||||
it->second(d, r->m_module_idx, m_senv, add_asynch_update, add_delayed_update);
|
it->second(d, r->m_module_idx, m_senv, add_asynch_update, add_delayed_update);
|
||||||
obj_counter++;
|
|
||||||
}
|
}
|
||||||
|
obj_counter++;
|
||||||
}
|
}
|
||||||
if (atomic_fetch_sub_explicit(&m_import_counter, 1u, memory_order_relaxed) == 1u) {
|
if (atomic_fetch_sub_explicit(&m_import_counter, 1u, memory_order_relaxed) == 1u) {
|
||||||
m_all_modules_imported = true;
|
m_all_modules_imported = true;
|
||||||
|
@ -404,12 +418,12 @@ struct import_modules_fn {
|
||||||
};
|
};
|
||||||
|
|
||||||
environment import_modules(environment const & env, unsigned num_modules, std::string const * modules,
|
environment import_modules(environment const & env, unsigned num_modules, std::string const * modules,
|
||||||
unsigned num_threads, io_state const & ios) {
|
unsigned num_threads, bool keep_proofs, io_state const & ios) {
|
||||||
return import_modules_fn(env, num_threads, ios)(num_modules, modules);
|
return import_modules_fn(env, num_threads, keep_proofs, ios)(num_modules, modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
environment import_module(environment const & env, std::string const & module,
|
environment import_module(environment const & env, std::string const & module,
|
||||||
unsigned num_threads, io_state const & ios) {
|
unsigned num_threads, bool keep_proofs, io_state const & ios) {
|
||||||
return import_modules(env, 1, &module, num_threads, ios);
|
return import_modules(env, 1, &module, num_threads, keep_proofs, ios);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,14 @@ namespace lean {
|
||||||
\brief Return an environment based on \c env, where all modules in \c modules are imported.
|
\brief Return an environment based on \c env, where all modules in \c modules are imported.
|
||||||
Modules included directly or indirectly by them are also imported.
|
Modules included directly or indirectly by them are also imported.
|
||||||
The environment \c env is usually an empty environment.
|
The environment \c env is usually an empty environment.
|
||||||
|
|
||||||
|
If \c keep_proofs is false, then the proof of the imported theorems is discarded after being
|
||||||
|
checked. The idea is to save memory.
|
||||||
*/
|
*/
|
||||||
environment import_modules(environment const & env, unsigned num_modules, std::string const * modules,
|
environment import_modules(environment const & env, unsigned num_modules, std::string const * modules,
|
||||||
unsigned num_threads, io_state const & ios);
|
unsigned num_threads, bool keep_proofs, io_state const & ios);
|
||||||
environment import_module(environment const & env, std::string const & module,
|
environment import_module(environment const & env, std::string const & module,
|
||||||
unsigned num_threads, io_state const & ios);
|
unsigned num_threads, bool keep_proofs, io_state const & ios);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Store/Export module using \c env to the output stream \c out.
|
\brief Store/Export module using \c env to the output stream \c out.
|
||||||
|
|
|
@ -8,7 +8,7 @@ assert(env:get("H2"):is_theorem())
|
||||||
env = add_decl(env, mk_definition("B", Bool, A))
|
env = add_decl(env, mk_definition("B", Bool, A))
|
||||||
env:export("mod1_mod.olean")
|
env:export("mod1_mod.olean")
|
||||||
|
|
||||||
local env2 = import_modules("mod1_mod.olean")
|
local env2 = import_modules("mod1_mod.olean", 1, true)
|
||||||
assert(env2:get("A"):type() == Bool)
|
assert(env2:get("A"):type() == Bool)
|
||||||
assert(env2:get("A"):is_var_decl())
|
assert(env2:get("A"):is_var_decl())
|
||||||
assert(env2:get("H1"):type() == A)
|
assert(env2:get("H1"):type() == A)
|
||||||
|
@ -19,3 +19,14 @@ assert(env2:get("H2"):value() == H1)
|
||||||
assert(env2:get("B"):type() == Bool)
|
assert(env2:get("B"):type() == Bool)
|
||||||
assert(env2:get("B"):value() == A)
|
assert(env2:get("B"):value() == A)
|
||||||
assert(env2:get("B"):is_definition())
|
assert(env2:get("B"):is_definition())
|
||||||
|
|
||||||
|
local env3 = import_modules("mod1_mod.olean")
|
||||||
|
assert(env3:get("A"):type() == Bool)
|
||||||
|
assert(env3:get("A"):is_var_decl())
|
||||||
|
assert(env3:get("H1"):type() == A)
|
||||||
|
assert(env3:get("H1"):is_axiom())
|
||||||
|
assert(env3:get("H2"):type() == A)
|
||||||
|
assert(env3:get("H2"):is_axiom())
|
||||||
|
assert(env3:get("B"):type() == Bool)
|
||||||
|
assert(env3:get("B"):value() == A)
|
||||||
|
assert(env3:get("B"):is_definition())
|
||||||
|
|
|
@ -37,7 +37,7 @@ end
|
||||||
|
|
||||||
print("importing...")
|
print("importing...")
|
||||||
local initt = os.clock()
|
local initt = os.clock()
|
||||||
local env2 = import_modules(mod_names, 4)
|
local env2 = import_modules(mod_names, 4, true)
|
||||||
print(string.format("elapsed time: %.2f\n", os.clock() - initt))
|
print(string.format("elapsed time: %.2f\n", os.clock() - initt))
|
||||||
for i = 1, NumMods do
|
for i = 1, NumMods do
|
||||||
for j = 1, NumThs do
|
for j = 1, NumThs do
|
||||||
|
|
Loading…
Reference in a new issue