mirror of
https://github.com/Z3Prover/z3
synced 2025-10-08 17:01:55 +00:00
update smt-parallel
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
f12d751007
commit
7eb6ef3161
3 changed files with 189 additions and 267 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
# Z3 Theorem Prover clang-format configuration
|
# Z3 Theorem Prover clang-format configuration
|
||||||
# Based on analysis of existing codebase style patterns
|
# Based on analysis of existing codebase style patterns
|
||||||
|
|
||||||
|
@ -12,7 +13,6 @@ UseTab: Never
|
||||||
ColumnLimit: 120
|
ColumnLimit: 120
|
||||||
|
|
||||||
# Braces
|
# Braces
|
||||||
BreakBeforeBraces: Linux
|
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: true
|
||||||
|
|
||||||
# Classes and structs
|
# Classes and structs
|
||||||
|
@ -25,7 +25,15 @@ AlwaysBreakAfterReturnType: None
|
||||||
AllowShortFunctionsOnASingleLine: Empty
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
# Ensure function-opening brace is attached to the signature
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
# Explicitly ensure function brace is not placed on a new line
|
||||||
|
BraceWrapping:
|
||||||
|
AfterFunction: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: false
|
||||||
# Spacing
|
# Spacing
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
SpaceAfterLogicalNot: false
|
SpaceAfterLogicalNot: false
|
||||||
|
@ -52,7 +60,7 @@ BreakBeforeTernaryOperators: true
|
||||||
SortIncludes: false # Z3 has specific include ordering conventions
|
SortIncludes: false # Z3 has specific include ordering conventions
|
||||||
|
|
||||||
# Namespaces
|
# Namespaces
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: All
|
||||||
|
|
||||||
# Comments and documentation
|
# Comments and documentation
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
|
|
|
@ -12,12 +12,10 @@ Abstract:
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
nbjorner 2020-01-31
|
nbjorner 2020-01-31
|
||||||
|
Ilana Shapiro 2025
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "util/scoped_ptr_vector.h"
|
#include "util/scoped_ptr_vector.h"
|
||||||
#include "ast/ast_util.h"
|
#include "ast/ast_util.h"
|
||||||
#include "ast/ast_pp.h"
|
#include "ast/ast_pp.h"
|
||||||
|
@ -26,15 +24,14 @@ Author:
|
||||||
#include "ast/simplifiers/then_simplifier.h"
|
#include "ast/simplifiers/then_simplifier.h"
|
||||||
#include "smt/smt_parallel.h"
|
#include "smt/smt_parallel.h"
|
||||||
#include "smt/smt_lookahead.h"
|
#include "smt/smt_lookahead.h"
|
||||||
// #include "params/smt_parallel_params.hpp"
|
|
||||||
#include "solver/solver_preprocess.h"
|
#include "solver/solver_preprocess.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <condition_variable>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
class bounded_pp_exprs {
|
class bounded_pp_exprs {
|
||||||
expr_ref_vector const &es;
|
expr_ref_vector const &es;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bounded_pp_exprs(expr_ref_vector const &es) : es(es) {}
|
bounded_pp_exprs(expr_ref_vector const &es) : es(es) {}
|
||||||
|
|
||||||
|
@ -56,13 +53,11 @@ namespace smt {
|
||||||
lbool parallel::operator()(expr_ref_vector const &asms) {
|
lbool parallel::operator()(expr_ref_vector const &asms) {
|
||||||
return l_undef;
|
return l_undef;
|
||||||
}
|
}
|
||||||
}
|
} // namespace smt
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
#define SHARE_SEARCH_TREE 1
|
#define SHARE_SEARCH_TREE 1
|
||||||
|
|
||||||
|
@ -70,23 +65,15 @@ namespace smt {
|
||||||
|
|
||||||
namespace smt {
|
namespace smt {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void parallel::worker::run() {
|
void parallel::worker::run() {
|
||||||
search_tree::node<cube_config> *node = nullptr;
|
search_tree::node<cube_config> *node = nullptr;
|
||||||
expr_ref_vector cube(m);
|
expr_ref_vector cube(m);
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
|
|
||||||
#if SHARE_SEARCH_TREE
|
|
||||||
if (!b.get_cube(m_g2l, id, cube, node)) {
|
if (!b.get_cube(m_g2l, id, cube, node)) {
|
||||||
LOG_WORKER(1, " no more cubes\n");
|
LOG_WORKER(1, " no more cubes\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (!get_cube(cube, node))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
collect_shared_clauses(m_g2l);
|
collect_shared_clauses(m_g2l);
|
||||||
|
|
||||||
check_cube_start:
|
check_cube_start:
|
||||||
|
@ -111,11 +98,7 @@ namespace smt {
|
||||||
auto atom = get_split_atom();
|
auto atom = get_split_atom();
|
||||||
if (!atom)
|
if (!atom)
|
||||||
goto check_cube_start;
|
goto check_cube_start;
|
||||||
#if SHARE_SEARCH_TREE
|
|
||||||
b.split(m_l2g, id, node, atom);
|
b.split(m_l2g, id, node, atom);
|
||||||
#else
|
|
||||||
split(node, atom);
|
|
||||||
#endif
|
|
||||||
simplify();
|
simplify();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +111,8 @@ namespace smt {
|
||||||
}
|
}
|
||||||
case l_false: {
|
case l_false: {
|
||||||
expr_ref_vector const &unsat_core = ctx->unsat_core();
|
expr_ref_vector const &unsat_core = ctx->unsat_core();
|
||||||
LOG_WORKER(2, " unsat core:\n"; for (auto c : unsat_core) verbose_stream() << mk_bounded_pp(c, m, 3) << "\n");
|
LOG_WORKER(2, " unsat core:\n";
|
||||||
|
for (auto c : unsat_core) verbose_stream() << mk_bounded_pp(c, m, 3) << "\n");
|
||||||
// If the unsat core only contains external assumptions,
|
// If the unsat core only contains external assumptions,
|
||||||
// unsatisfiability does not depend on the current cube and the entire problem is unsat.
|
// unsatisfiability does not depend on the current cube and the entire problem is unsat.
|
||||||
if (all_of(unsat_core, [&](expr *e) { return asms.contains(e); })) {
|
if (all_of(unsat_core, [&](expr *e) { return asms.contains(e); })) {
|
||||||
|
@ -138,14 +122,11 @@ namespace smt {
|
||||||
}
|
}
|
||||||
for (expr *e : unsat_core)
|
for (expr *e : unsat_core)
|
||||||
if (asms.contains(e))
|
if (asms.contains(e))
|
||||||
b.report_assumption_used(m_l2g, e); // report assumptions used in unsat core, so they can be used in final core
|
b.report_assumption_used(
|
||||||
|
m_l2g, e); // report assumptions used in unsat core, so they can be used in final core
|
||||||
|
|
||||||
LOG_WORKER(1, " found unsat cube\n");
|
LOG_WORKER(1, " found unsat cube\n");
|
||||||
#if SHARE_SEARCH_TREE
|
|
||||||
b.backtrack(m_l2g, unsat_core, node);
|
b.backtrack(m_l2g, unsat_core, node);
|
||||||
#else
|
|
||||||
backtrack(unsat_core, node);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,43 +135,9 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parallel::worker::get_cube(expr_ref_vector& cube, node*& n) {
|
parallel::worker::worker(unsigned id, parallel &p, expr_ref_vector const &_asms)
|
||||||
node* t = m_search_tree.activate_node(n);
|
: id(id), p(p), b(p.m_batch_manager), m_smt_params(p.ctx.get_fparams()), asms(m), m_g2l(p.ctx.m, m),
|
||||||
cube.reset();
|
m_l2g(m, p.ctx.m), m_search_tree(expr_ref(m)) {
|
||||||
if (!t) {
|
|
||||||
b.set_unsat(m_l2g, cube);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
n = t;
|
|
||||||
while (t) {
|
|
||||||
if (cube_config::literal_is_null(t->get_literal()))
|
|
||||||
break;
|
|
||||||
cube.push_back(t->get_literal());
|
|
||||||
t = t->parent();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parallel::worker::backtrack(expr_ref_vector const& core, node* n) {
|
|
||||||
vector<expr_ref> core_copy;
|
|
||||||
for (auto c : core)
|
|
||||||
core_copy.push_back(expr_ref(c, m));
|
|
||||||
m_search_tree.backtrack(n, core_copy);
|
|
||||||
//LOG_WORKER(1, m_search_tree.display(verbose_stream() << bounded_pp_exprs(core) << "\n"););
|
|
||||||
}
|
|
||||||
|
|
||||||
void parallel::worker::split(node* n, expr* atom) {
|
|
||||||
expr_ref lit(atom, m), nlit(m);
|
|
||||||
nlit = mk_not(m, lit);
|
|
||||||
IF_VERBOSE(1, verbose_stream() << "Batch manager splitting on literal: " << mk_bounded_pp(lit, m, 3) << "\n");
|
|
||||||
m_search_tree.split(n, lit, nlit);
|
|
||||||
}
|
|
||||||
|
|
||||||
parallel::worker::worker(unsigned id, parallel& p, expr_ref_vector const& _asms):
|
|
||||||
id(id), p(p), b(p.m_batch_manager), m_smt_params(p.ctx.get_fparams()), asms(m),
|
|
||||||
m_g2l(p.ctx.m, m),
|
|
||||||
m_l2g(m, p.ctx.m),
|
|
||||||
m_search_tree(expr_ref(m)) {
|
|
||||||
for (auto e : _asms)
|
for (auto e : _asms)
|
||||||
asms.push_back(m_g2l(e));
|
asms.push_back(m_g2l(e));
|
||||||
LOG_WORKER(1, " created with " << asms.size() << " assumptions\n");
|
LOG_WORKER(1, " created with " << asms.size() << " assumptions\n");
|
||||||
|
@ -198,34 +145,9 @@ namespace smt {
|
||||||
ctx = alloc(context, m, m_smt_params, p.ctx.get_params());
|
ctx = alloc(context, m, m_smt_params, p.ctx.get_params());
|
||||||
context::copy(p.ctx, *ctx, true);
|
context::copy(p.ctx, *ctx, true);
|
||||||
ctx->set_random_seed(id + m_smt_params.m_random_seed);
|
ctx->set_random_seed(id + m_smt_params.m_random_seed);
|
||||||
|
|
||||||
#if 0
|
|
||||||
smt_parallel_params pp(p.ctx.m_params);
|
|
||||||
m_config.m_threads_max_conflicts = ctx->get_fparams().m_threads_max_conflicts;
|
|
||||||
m_config.m_max_conflicts = ctx->get_fparams().m_max_conflicts;
|
|
||||||
m_config.m_relevant_units_only = pp.relevant_units_only();
|
|
||||||
m_config.m_never_cube = pp.never_cube();
|
|
||||||
m_config.m_share_conflicts = pp.share_conflicts();
|
|
||||||
m_config.m_share_units = pp.share_units();
|
|
||||||
m_config.m_share_units_initial_only = pp.share_units_initial_only();
|
|
||||||
m_config.m_cube_initial_only = pp.cube_initial_only();
|
|
||||||
m_config.m_max_conflict_mul = pp.max_conflict_mul();
|
|
||||||
m_config.m_max_greedy_cubes = pp.max_greedy_cubes();
|
|
||||||
m_config.m_num_split_lits = pp.num_split_lits();
|
|
||||||
m_config.m_backbone_detection = pp.backbone_detection();
|
|
||||||
m_config.m_iterative_deepening = pp.iterative_deepening();
|
|
||||||
m_config.m_beam_search = pp.beam_search();
|
|
||||||
m_config.m_explicit_hardness = pp.explicit_hardness();
|
|
||||||
m_config.m_cubetree = pp.cubetree();
|
|
||||||
m_config.m_max_cube_depth = pp.max_cube_depth();
|
|
||||||
m_config.m_inprocessing = pp.inprocessing();
|
|
||||||
m_config.m_inprocessing_delay = pp.inprocessing_delay();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// don't share initial units
|
// don't share initial units
|
||||||
ctx->pop_to_base_lvl();
|
ctx->pop_to_base_lvl();
|
||||||
m_num_shared_units = ctx->assigned_literals().size();
|
m_num_shared_units = ctx->assigned_literals().size();
|
||||||
|
|
||||||
m_num_initial_atoms = ctx->get_num_bool_vars();
|
m_num_initial_atoms = ctx->get_num_bool_vars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,8 +176,6 @@ namespace smt {
|
||||||
m_num_shared_units = sz;
|
m_num_shared_units = sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void parallel::worker::simplify() {
|
void parallel::worker::simplify() {
|
||||||
if (!m.inc())
|
if (!m.inc())
|
||||||
return;
|
return;
|
||||||
|
@ -274,6 +194,9 @@ namespace smt {
|
||||||
--m_config.m_inprocessing_delay;
|
--m_config.m_inprocessing_delay;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ctx->pop_to_base_lvl();
|
||||||
|
if (ctx->m_base_lvl > 0)
|
||||||
|
return; // simplification only at base level
|
||||||
m_config.m_inprocessing = false; // initial strategy is to immediately disable inprocessing for future calls.
|
m_config.m_inprocessing = false; // initial strategy is to immediately disable inprocessing for future calls.
|
||||||
dependent_expr_simplifier *s = ctx->m_simplifier.get();
|
dependent_expr_simplifier *s = ctx->m_simplifier.get();
|
||||||
if (!s) {
|
if (!s) {
|
||||||
|
@ -286,7 +209,6 @@ namespace smt {
|
||||||
init_preprocess(m, ctx->get_params(), *then_s, *ctx->m_fmls);
|
init_preprocess(m, ctx->get_params(), *then_s, *ctx->m_fmls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dependent_expr_state &fmls = *ctx->m_fmls.get();
|
dependent_expr_state &fmls = *ctx->m_fmls.get();
|
||||||
// extract assertions from ctx.
|
// extract assertions from ctx.
|
||||||
// it is possible to track proof objects here if wanted.
|
// it is possible to track proof objects here if wanted.
|
||||||
|
@ -303,8 +225,6 @@ namespace smt {
|
||||||
// run in-processing on the assertions
|
// run in-processing on the assertions
|
||||||
s->reduce();
|
s->reduce();
|
||||||
|
|
||||||
// LOG_WORKER(1, ""; fmls.display(verbose_stream() << " inprocess result\n"););
|
|
||||||
|
|
||||||
scoped_ptr<context> new_ctx = alloc(context, m, m_smt_params, p.ctx.get_params());
|
scoped_ptr<context> new_ctx = alloc(context, m, m_smt_params, p.ctx.get_params());
|
||||||
// extract simplified assertions from the simplifier
|
// extract simplified assertions from the simplifier
|
||||||
// create a new context with the simplified assertions
|
// create a new context with the simplified assertions
|
||||||
|
@ -313,19 +233,18 @@ namespace smt {
|
||||||
auto const &de = fmls[i];
|
auto const &de = fmls[i];
|
||||||
new_ctx->assert_expr(de.fml());
|
new_ctx->assert_expr(de.fml());
|
||||||
}
|
}
|
||||||
ctx = new_ctx.detach();
|
|
||||||
|
|
||||||
|
asserted_formulas &src_af = ctx->m_asserted_formulas;
|
||||||
|
asserted_formulas &dst_af = new_ctx->m_asserted_formulas;
|
||||||
|
src_af.get_macro_manager().copy_to(dst_af.get_macro_manager());
|
||||||
|
new_ctx->copy_user_propagator(*ctx, true);
|
||||||
|
ctx = new_ctx.detach();
|
||||||
ctx->setup_context(true);
|
ctx->setup_context(true);
|
||||||
ctx->internalize_assertions();
|
ctx->internalize_assertions();
|
||||||
|
|
||||||
auto old_atoms = m_num_initial_atoms;
|
auto old_atoms = m_num_initial_atoms;
|
||||||
m_num_shared_units = ctx->assigned_literals().size();
|
m_num_shared_units = ctx->assigned_literals().size();
|
||||||
m_num_initial_atoms = ctx->get_num_bool_vars();
|
m_num_initial_atoms = ctx->get_num_bool_vars();
|
||||||
|
|
||||||
|
|
||||||
LOG_WORKER(1, " inprocess " << old_atoms << " -> " << m_num_initial_atoms << "\n");
|
LOG_WORKER(1, " inprocess " << old_atoms << " -> " << m_num_initial_atoms << "\n");
|
||||||
|
|
||||||
// TODO: copy user-propagators similar to context::copy.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parallel::worker::collect_statistics(::statistics &st) const {
|
void parallel::worker::collect_statistics(::statistics &st) const {
|
||||||
|
@ -395,7 +314,8 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector parallel::batch_manager::return_shared_clauses(ast_translation& g2l, unsigned& worker_limit, unsigned worker_id) {
|
expr_ref_vector parallel::batch_manager::return_shared_clauses(ast_translation &g2l, unsigned &worker_limit,
|
||||||
|
unsigned worker_id) {
|
||||||
std::scoped_lock lock(mux);
|
std::scoped_lock lock(mux);
|
||||||
expr_ref_vector result(g2l.to());
|
expr_ref_vector result(g2l.to());
|
||||||
for (unsigned i = worker_limit; i < shared_clause_trail.size(); ++i) {
|
for (unsigned i = worker_limit; i < shared_clause_trail.size(); ++i) {
|
||||||
|
@ -413,17 +333,16 @@ namespace smt {
|
||||||
lbool r = l_undef;
|
lbool r = l_undef;
|
||||||
|
|
||||||
ctx->get_fparams().m_max_conflicts = std::min(m_config.m_threads_max_conflicts, m_config.m_max_conflicts);
|
ctx->get_fparams().m_max_conflicts = std::min(m_config.m_threads_max_conflicts, m_config.m_max_conflicts);
|
||||||
IF_VERBOSE(1, verbose_stream() << " Checking cube\n" << bounded_pp_exprs(cube) << "with max_conflicts: " << ctx->get_fparams().m_max_conflicts << "\n";);
|
IF_VERBOSE(1, verbose_stream() << " Checking cube\n"
|
||||||
|
<< bounded_pp_exprs(cube)
|
||||||
|
<< "with max_conflicts: " << ctx->get_fparams().m_max_conflicts << "\n";);
|
||||||
try {
|
try {
|
||||||
r = ctx->check(asms.size(), asms.data());
|
r = ctx->check(asms.size(), asms.data());
|
||||||
}
|
} catch (z3_error &err) {
|
||||||
catch (z3_error& err) {
|
|
||||||
b.set_exception(err.error_code());
|
b.set_exception(err.error_code());
|
||||||
}
|
} catch (z3_exception &ex) {
|
||||||
catch (z3_exception& ex) {
|
|
||||||
b.set_exception(ex.what());
|
b.set_exception(ex.what());
|
||||||
}
|
} catch (...) {
|
||||||
catch (...) {
|
|
||||||
b.set_exception("unknown exception");
|
b.set_exception("unknown exception");
|
||||||
}
|
}
|
||||||
asms.shrink(asms.size() - cube.size());
|
asms.shrink(asms.size() - cube.size());
|
||||||
|
@ -509,11 +428,13 @@ namespace smt {
|
||||||
if (m.limit().is_canceled())
|
if (m.limit().is_canceled())
|
||||||
return l_undef; // the main context was cancelled, so we return undef.
|
return l_undef; // the main context was cancelled, so we return undef.
|
||||||
switch (m_state) {
|
switch (m_state) {
|
||||||
case state::is_running: // batch manager is still running, but all threads have processed their cubes, which means all cubes were unsat
|
case state::is_running: // batch manager is still running, but all threads have processed their cubes, which
|
||||||
|
// means all cubes were unsat
|
||||||
if (!m_search_tree.is_closed())
|
if (!m_search_tree.is_closed())
|
||||||
throw default_exception("inconsistent end state");
|
throw default_exception("inconsistent end state");
|
||||||
if (!p.m_assumptions_used.empty()) {
|
if (!p.m_assumptions_used.empty()) {
|
||||||
// collect unsat core from assumptions used, if any --> case when all cubes were unsat, but depend on nonempty asms, so we need to add these asms to final unsat core
|
// collect unsat core from assumptions used, if any --> case when all cubes were unsat, but depend on
|
||||||
|
// nonempty asms, so we need to add these asms to final unsat core
|
||||||
SASSERT(p.ctx.m_unsat_core.empty());
|
SASSERT(p.ctx.m_unsat_core.empty());
|
||||||
for (auto a : p.m_assumptions_used)
|
for (auto a : p.m_assumptions_used)
|
||||||
p.ctx.m_unsat_core.push_back(a);
|
p.ctx.m_unsat_core.push_back(a);
|
||||||
|
@ -565,7 +486,6 @@ namespace smt {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parallel::batch_manager::initialize() {
|
void parallel::batch_manager::initialize() {
|
||||||
m_state = state::is_running;
|
m_state = state::is_running;
|
||||||
m_search_tree.reset();
|
m_search_tree.reset();
|
||||||
|
@ -593,7 +513,6 @@ namespace smt {
|
||||||
};
|
};
|
||||||
scoped_clear clear(*this);
|
scoped_clear clear(*this);
|
||||||
|
|
||||||
{
|
|
||||||
m_batch_manager.initialize();
|
m_batch_manager.initialize();
|
||||||
m_workers.reset();
|
m_workers.reset();
|
||||||
for (auto e : asms)
|
for (auto e : asms)
|
||||||
|
@ -610,9 +529,7 @@ namespace smt {
|
||||||
// Launch threads
|
// Launch threads
|
||||||
vector<std::thread> threads(num_threads);
|
vector<std::thread> threads(num_threads);
|
||||||
for (unsigned i = 0; i < num_threads; ++i) {
|
for (unsigned i = 0; i < num_threads; ++i) {
|
||||||
threads[i] = std::thread([&, i]() {
|
threads[i] = std::thread([&, i]() { m_workers[i]->run(); });
|
||||||
m_workers[i]->run();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for all threads to finish
|
// Wait for all threads to finish
|
||||||
|
@ -622,10 +539,9 @@ namespace smt {
|
||||||
for (auto w : m_workers)
|
for (auto w : m_workers)
|
||||||
w->collect_statistics(ctx.m_aux_stats);
|
w->collect_statistics(ctx.m_aux_stats);
|
||||||
m_batch_manager.collect_statistics(ctx.m_aux_stats);
|
m_batch_manager.collect_statistics(ctx.m_aux_stats);
|
||||||
}
|
|
||||||
|
|
||||||
return m_batch_manager.get_result();
|
return m_batch_manager.get_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace smt
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,6 +42,7 @@ namespace smt {
|
||||||
};
|
};
|
||||||
|
|
||||||
class batch_manager {
|
class batch_manager {
|
||||||
|
|
||||||
enum state {
|
enum state {
|
||||||
is_running,
|
is_running,
|
||||||
is_sat,
|
is_sat,
|
||||||
|
@ -49,6 +50,7 @@ namespace smt {
|
||||||
is_exception_msg,
|
is_exception_msg,
|
||||||
is_exception_code
|
is_exception_code
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stats {
|
struct stats {
|
||||||
unsigned m_max_cube_depth = 0;
|
unsigned m_max_cube_depth = 0;
|
||||||
unsigned m_num_cubes = 0;
|
unsigned m_num_cubes = 0;
|
||||||
|
@ -114,7 +116,7 @@ namespace smt {
|
||||||
bool m_share_units_initial_only = true;
|
bool m_share_units_initial_only = true;
|
||||||
bool m_cube_initial_only = true;
|
bool m_cube_initial_only = true;
|
||||||
bool m_inprocessing = true;
|
bool m_inprocessing = true;
|
||||||
unsigned m_inprocessing_delay = 0;
|
unsigned m_inprocessing_delay = 1;
|
||||||
unsigned m_max_cube_depth = 20;
|
unsigned m_max_cube_depth = 20;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,10 +147,6 @@ namespace smt {
|
||||||
m_config.m_threads_max_conflicts = (unsigned)(m_config.m_max_conflict_mul * m_config.m_threads_max_conflicts);
|
m_config.m_threads_max_conflicts = (unsigned)(m_config.m_max_conflict_mul * m_config.m_threads_max_conflicts);
|
||||||
} // allow for backoff scheme of conflicts within the thread for cube timeouts.
|
} // allow for backoff scheme of conflicts within the thread for cube timeouts.
|
||||||
|
|
||||||
bool get_cube(expr_ref_vector& cube, node*& n);
|
|
||||||
void backtrack(expr_ref_vector const& core, node* n);
|
|
||||||
void split(node* n, expr* atom);
|
|
||||||
|
|
||||||
void simplify();
|
void simplify();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue