feat(frontends/lean): process theorems in parallel

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-07-12 22:50:57 +01:00
parent 0a556c4a91
commit 7ccb9a389c
4 changed files with 47 additions and 4 deletions

View file

@ -291,9 +291,23 @@ environment definition_cmd_core(parser & p, bool is_theorem, bool _is_opaque) {
env = add_decl_alias(env, n, mk_constant(real_n));
level_param_names new_ls;
if (is_theorem) {
// TODO(Leo): delay theorems
if (p.num_threads() > 1) {
// add as axiom, and create a task to prove the theorem
expr saved_type = type;
expr saved_value = value;
environment saved_env = env;
std::tie(type, new_ls) = p.elaborate_type(type);
env = module::add(env, check(env, mk_axiom(real_n, append(ls, new_ls), type)));
p.add_delayed_theorem([=, &p]() {
level_param_names new_ls;
expr type, value;
std::tie(type, value, new_ls) = p.elaborate_definition_at(saved_env, n, saved_type, saved_value);
return check(saved_env, mk_theorem(real_n, append(ls, new_ls), type, value));
});
} else {
std::tie(type, value, new_ls) = p.elaborate_definition(n, type, value);
env = module::add(env, check(env, mk_theorem(real_n, append(ls, new_ls), type, value)));
}
} else {
std::tie(type, value, new_ls) = p.elaborate_definition(n, type, value);
env = module::add(env, check(env, mk_definition(env, real_n, append(ls, new_ls), type, value, modifiers.m_is_opaque)));

View file

@ -75,7 +75,7 @@ parser::parser(environment const & env, io_state const & ios,
m_env(env), m_ios(ios), m_ngen(g_tmp_prefix),
m_verbose(true), m_use_exceptions(use_exceptions),
m_scanner(strm, strm_name), m_local_level_decls(lds), m_local_decls(eds),
m_pos_table(std::make_shared<pos_info_table>()) {
m_pos_table(std::make_shared<pos_info_table>()), m_theorem_queue(num_threads > 1 ? num_threads - 1 : 0) {
m_scanner.set_line(line);
m_num_threads = num_threads;
m_no_undef_id_error = false;
@ -87,6 +87,15 @@ parser::parser(environment const & env, io_state const & ios,
[&]() { sync_command(); });
}
parser::~parser() {
try {
if (!m_theorem_queue.done()) {
m_theorem_queue.interrupt();
m_theorem_queue.join();
}
} catch (...) {}
}
bool parser::has_tactic_decls() {
if (!m_has_tactic_decls)
m_has_tactic_decls = ::lean::has_tactic_decls(m_env);
@ -484,6 +493,12 @@ std::tuple<expr, expr, level_param_names> parser::elaborate_definition(name cons
return ::lean::elaborate(m_env, m_local_level_decls, m_ios, n, t, v, &pp);
}
std::tuple<expr, expr, level_param_names> parser::elaborate_definition_at(environment const & env, name const & n, expr const & t,
expr const & v) {
parser_pos_provider pp = get_pos_provider();
return ::lean::elaborate(env, m_local_level_decls, m_ios, n, t, v, &pp);
}
[[ noreturn ]] void throw_invalid_open_binder(pos_info const & pos) {
throw parser_error("invalid binder, '(', '{', '[', '{{', '⦃' or identifier expected", pos);
}
@ -1035,6 +1050,9 @@ bool parser::parse_commands() {
[&]() { sync_command(); });
}
} catch (interrupt_parser) {}
for (certified_declaration const & thm : m_theorem_queue.join()) {
m_env.replace(thm);
}
return !m_found_errors;
}

View file

@ -13,6 +13,7 @@ Author: Leonardo de Moura
#include "util/exception.h"
#include "util/thread_script_state.h"
#include "util/script_exception.h"
#include "util/worker_queue.h"
#include "util/name_generator.h"
#include "kernel/environment.h"
#include "kernel/expr_maps.h"
@ -63,6 +64,8 @@ class parser {
optional<bool> m_has_num;
optional<bool> m_has_string;
optional<bool> m_has_tactic_decls;
// We process theorems in parallel
worker_queue<certified_declaration> m_theorem_queue;
void display_error_pos(unsigned line, unsigned pos);
void display_error_pos(pos_info p);
@ -130,6 +133,7 @@ public:
local_level_decls const & lds = local_level_decls(),
local_expr_decls const & eds = local_expr_decls(),
unsigned line = 1);
~parser();
environment const & env() const { return m_env; }
io_state const & ios() const { return m_ios; }
@ -157,6 +161,9 @@ public:
expr mk_app(expr fn, expr arg, pos_info const & p);
expr mk_app(std::initializer_list<expr> const & args, pos_info const & p);
unsigned num_threads() const { return m_num_threads; }
void add_delayed_theorem(std::function<certified_declaration()> const & fn) { m_theorem_queue.add(fn); }
/** \brief Read the next token. */
void scan() { m_curr = m_scanner.scan(m_env); }
/** \brief Return the current token */
@ -260,6 +267,8 @@ public:
std::tuple<expr, level_param_names> elaborate(expr const & e) { return elaborate_at(m_env, e); }
/** \brief Elaborate the definition n : t := v */
std::tuple<expr, expr, level_param_names> elaborate_definition(name const & n, expr const & t, expr const & v);
/** \brief Elaborate the definition n : t := v in the given environment*/
std::tuple<expr, expr, level_param_names> elaborate_definition_at(environment const & env, name const & n, expr const & t, expr const & v);
parser_pos_provider get_pos_provider() const { return parser_pos_provider(m_pos_table, get_stream_name(), m_last_cmd_pos); }

View file

@ -115,5 +115,7 @@ public:
for (auto & t : m_threads)
t->request_interrupt();
}
bool done() const { return m_done; }
};
}