mirror of
https://github.com/Z3Prover/z3
synced 2025-08-26 04:56:03 +00:00
code and notes
This commit is contained in:
parent
6044389446
commit
bffefc5331
3 changed files with 31 additions and 6 deletions
|
@ -5153,6 +5153,8 @@ namespace polynomial {
|
||||||
//
|
//
|
||||||
unsigned sz = R->size();
|
unsigned sz = R->size();
|
||||||
for (unsigned i = 0; i < sz; i++) {
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
|
if (sz > 100 && i % 100 == 0)
|
||||||
|
checkpoint();
|
||||||
monomial * m = R->m(i);
|
monomial * m = R->m(i);
|
||||||
numeral const & a = R->a(i);
|
numeral const & a = R->a(i);
|
||||||
if (m->degree_of(x) == deg_R) {
|
if (m->degree_of(x) == deg_R) {
|
||||||
|
@ -5571,6 +5573,7 @@ namespace polynomial {
|
||||||
h = mk_one();
|
h = mk_one();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
checkpoint();
|
||||||
TRACE(resultant, tout << "A: " << A << "\nB: " << B << "\n";);
|
TRACE(resultant, tout << "A: " << A << "\nB: " << B << "\n";);
|
||||||
degA = degree(A, x);
|
degA = degree(A, x);
|
||||||
degB = degree(B, x);
|
degB = degree(B, x);
|
||||||
|
|
|
@ -81,12 +81,15 @@ namespace smt {
|
||||||
// If the unsat core only contains assumptions,
|
// If the unsat core only contains 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); })) {
|
||||||
IF_VERBOSE(0, verbose_stream() << "Worker " << id << " determined formula unsat");
|
IF_VERBOSE(0, verbose_stream() << "Worker " << id << " determined formula unsat\n");
|
||||||
b.set_unsat(l2g, unsat_core);
|
b.set_unsat(l2g, unsat_core);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (expr * e : unsat_core)
|
||||||
|
if (asms.contains(e))
|
||||||
|
b.report_assumption_used(l2g, e); // report assumptions used in unsat core, so they can be used in final core
|
||||||
|
|
||||||
// TODO: can share lemmas here, such as new units and not(and(unsat_core)), binary clauses, etc.
|
// TODO: can share lemmas here, such as new units and not(and(unsat_core)), binary clauses, etc.
|
||||||
// TODO: remember assumptions used in core so that they get used for the final core.
|
|
||||||
IF_VERBOSE(0, verbose_stream() << "Worker " << id << " found unsat cube: " << mk_pp(mk_and(cube), m) << "\n");
|
IF_VERBOSE(0, verbose_stream() << "Worker " << id << " found unsat cube: " << mk_pp(mk_and(cube), m) << "\n");
|
||||||
b.share_lemma(l2g, mk_not(mk_and(unsat_core)));
|
b.share_lemma(l2g, mk_not(mk_and(unsat_core)));
|
||||||
// share_units();
|
// share_units();
|
||||||
|
@ -216,7 +219,7 @@ namespace smt {
|
||||||
if (m_state != state::is_running)
|
if (m_state != state::is_running)
|
||||||
return;
|
return;
|
||||||
m_state = state::is_unsat;
|
m_state = state::is_unsat;
|
||||||
p.ctx.m_unsat_core.reset();
|
SASSERT(p.ctx.m_unsat_core.empty());
|
||||||
for (expr* e : unsat_core)
|
for (expr* e : unsat_core)
|
||||||
p.ctx.m_unsat_core.push_back(l2g(e));
|
p.ctx.m_unsat_core.push_back(l2g(e));
|
||||||
cancel_workers();
|
cancel_workers();
|
||||||
|
@ -240,6 +243,11 @@ namespace smt {
|
||||||
cancel_workers();
|
cancel_workers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parallel::batch_manager::report_assumption_used(ast_translation& l2g, expr* assumption) {
|
||||||
|
std::scoped_lock lock(mux);
|
||||||
|
m_used_assumptions.insert(l2g(assumption))
|
||||||
|
}
|
||||||
|
|
||||||
lbool parallel::batch_manager::get_result() const {
|
lbool parallel::batch_manager::get_result() const {
|
||||||
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.
|
||||||
|
@ -247,7 +255,12 @@ namespace smt {
|
||||||
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_cubes.empty())
|
if (!m_cubes.empty())
|
||||||
throw default_exception("inconsistent end state");
|
throw default_exception("inconsistent end state");
|
||||||
// TODO collect unsat core from assumptions, if any. -- this is for the version where asms are passed in (currently, asms are empty)
|
if (!m_assumptions_used.empty()) {
|
||||||
|
// collect unsat core from assumptions used, if any.
|
||||||
|
SASSERT(p.ctx.m_unsat_core.empty());
|
||||||
|
for (auto a : m_assumptions_used)
|
||||||
|
p.ctx.m_unsat_core.push_back(a);
|
||||||
|
}
|
||||||
return l_false;
|
return l_false;
|
||||||
case state::is_unsat:
|
case state::is_unsat:
|
||||||
return l_false;
|
return l_false;
|
||||||
|
@ -385,7 +398,7 @@ namespace smt {
|
||||||
expr_ref g_atom(l2g(A_worker[i]), l2g.to());
|
expr_ref g_atom(l2g(A_worker[i]), l2g.to());
|
||||||
if (!m_split_atoms.contains(g_atom))
|
if (!m_split_atoms.contains(g_atom))
|
||||||
m_split_atoms.push_back(g_atom);
|
m_split_atoms.push_back(g_atom);
|
||||||
add_split_atom(g_atom, initial_m_cubes_size); // start from the initial size of m_cubes to ONLY split the NEW worker cubes
|
add_split_atom(g_atom, initial_m_cubes_size); // start from the initial size of m_cubes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,6 +440,13 @@ namespace smt {
|
||||||
if (m.has_trace_stream())
|
if (m.has_trace_stream())
|
||||||
throw default_exception("trace streams have to be off in parallel mode");
|
throw default_exception("trace streams have to be off in parallel mode");
|
||||||
|
|
||||||
|
struct scoped_clear_table {
|
||||||
|
obj_hashtable& ht;
|
||||||
|
scoped_clear(obj_hashtable& ht) : ht(ht) {}
|
||||||
|
~scoped_clear() { ht.reset(); }
|
||||||
|
};
|
||||||
|
scoped_clear_table clear(m_batch_manager.m_used_assumptions);
|
||||||
|
|
||||||
{
|
{
|
||||||
m_batch_manager.initialize();
|
m_batch_manager.initialize();
|
||||||
m_workers.reset();
|
m_workers.reset();
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace smt {
|
||||||
unsigned m_max_batch_size = 10;
|
unsigned m_max_batch_size = 10;
|
||||||
unsigned m_exception_code = 0;
|
unsigned m_exception_code = 0;
|
||||||
std::string m_exception_msg;
|
std::string m_exception_msg;
|
||||||
|
obj_hashtable<expr> m_assumptions_used; // assumptions used in unsat cores, to be used in final core
|
||||||
|
|
||||||
// called from batch manager to cancel other workers if we've reached a verdict
|
// called from batch manager to cancel other workers if we've reached a verdict
|
||||||
void cancel_workers() {
|
void cancel_workers() {
|
||||||
|
@ -76,6 +77,7 @@ namespace smt {
|
||||||
// the batch manager re-enqueues unprocessed cubes and optionally splits them using the split_atoms returned by this and workers.
|
// the batch manager re-enqueues unprocessed cubes and optionally splits them using the split_atoms returned by this and workers.
|
||||||
//
|
//
|
||||||
void return_cubes(ast_translation& l2g, vector<expr_ref_vector>const& cubes, expr_ref_vector const& split_atoms);
|
void return_cubes(ast_translation& l2g, vector<expr_ref_vector>const& cubes, expr_ref_vector const& split_atoms);
|
||||||
|
void report_assumption_used(ast_translation& l2g, expr* assumption);
|
||||||
void share_lemma(ast_translation& l2g, expr* lemma);
|
void share_lemma(ast_translation& l2g, expr* lemma);
|
||||||
lbool get_result() const;
|
lbool get_result() const;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue