mirror of
https://github.com/Z3Prover/z3
synced 2025-11-11 08:32:03 +00:00
na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
6ef6573598
commit
b6ba0395b4
1 changed files with 52 additions and 35 deletions
|
|
@ -94,19 +94,20 @@ struct smtmus::imp {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
solver& m_solver;
|
solver& m_solver;
|
||||||
solver_ref m_reset_solver;
|
solver_ref m_reset_solver;
|
||||||
solver* m_main_solver;
|
solver* m_main_solver;
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
arith_util a;
|
arith_util a;
|
||||||
obj_map<expr, unsigned> m_expr2lit;
|
model_ref m_model; // latest model, if any.
|
||||||
model_ref m_model;
|
expr_ref_vector m_soft; // original soft clauses or indicators
|
||||||
expr_ref_vector m_soft;
|
expr_ref_vector m_hard; // hard clauses, soft clauses removed
|
||||||
expr_ref_vector m_hard;
|
vector<expr_ref_vector> m_soft_clauses; // set of soft clauses extracted from indicators
|
||||||
vector<expr_ref_vector> m_soft_clauses;
|
obj_hashtable<func_decl> m_soft_vars; // variables used in soft clauses
|
||||||
obj_map<expr, func_decl_ref_vector*> m_lit2vars;
|
obj_map<expr, func_decl_ref_vector*> m_lit2vars; // map from literals in soft clauses to variables
|
||||||
obj_map<func_decl, unsigned_vector*> m_occurs;
|
obj_map<func_decl, unsigned_vector> m_soft_occurs; // map from variables to soft clause occurrences
|
||||||
obj_map<expr, ineq*> m_lit2ineq;
|
obj_map<func_decl, unsigned_vector> m_hard_occurs; // map from variables to hard clause occurrences
|
||||||
|
obj_map<expr, ineq*> m_lit2ineq; // map from literals to inequality abstraction
|
||||||
|
|
||||||
unsigned m_rotated = 0;
|
unsigned m_rotated = 0;
|
||||||
unsigned p_max_cores = 30;
|
unsigned p_max_cores = 30;
|
||||||
|
|
@ -123,12 +124,8 @@ struct smtmus::imp {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned add_soft(expr* lit) {
|
void add_soft(expr* lit) {
|
||||||
unsigned idx = m_soft.size();
|
|
||||||
m_expr2lit.insert(lit, idx);
|
|
||||||
m_soft.push_back(lit);
|
m_soft.push_back(lit);
|
||||||
TRACE("mus", tout << idx << ": " << mk_pp(lit, m) << "\n" << m_soft << "\n";);
|
|
||||||
return idx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize soft_clauses based on control variables in mus, or if mus already is a clause.
|
// initialize soft_clauses based on control variables in mus, or if mus already is a clause.
|
||||||
|
|
@ -197,22 +194,36 @@ struct smtmus::imp {
|
||||||
tout << "clause " << clause << "\n";);
|
tout << "clause " << clause << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_occurs(unsigned idx, func_decl* v, obj_map<func_decl, unsigned_vector>& occurs) {
|
||||||
|
if (!occurs.contains(v))
|
||||||
|
occurs.insert(v, unsigned_vector());
|
||||||
|
auto& occ = occurs[v];
|
||||||
|
if (!occ.empty() && occ.back() == idx)
|
||||||
|
return;
|
||||||
|
occ.push_back(idx);
|
||||||
|
}
|
||||||
|
|
||||||
void init_occurs() {
|
void init_occurs() {
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
for (auto const& clause : m_soft_clauses) {
|
for (auto const& clause : m_soft_clauses) {
|
||||||
for (auto* lit : clause) {
|
for (auto* lit : clause) {
|
||||||
auto const& vars = get_vars(lit);
|
for (auto* v : get_vars(lit)) {
|
||||||
for (auto* v : vars) {
|
init_occurs(idx, v, m_soft_occurs);
|
||||||
if (!m_occurs.contains(v))
|
m_soft_vars.insert(v);
|
||||||
m_occurs.insert(v, alloc(unsigned_vector));
|
|
||||||
auto& occ = *m_occurs[v];
|
|
||||||
if (!occ.empty() && occ.back() == idx)
|
|
||||||
continue;
|
|
||||||
occ.push_back(idx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
idx = 0;
|
||||||
|
func_decl_ref_vector vars(m);
|
||||||
|
for (auto* fml : m_hard) {
|
||||||
|
vars.reset();
|
||||||
|
extract_vars(fml, vars);
|
||||||
|
for (auto* v : vars)
|
||||||
|
if (m_soft_vars.contains(v))
|
||||||
|
init_occurs(idx, v, m_hard_occurs);
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_lit2ineq() {
|
void init_lit2ineq() {
|
||||||
|
|
@ -257,7 +268,7 @@ struct smtmus::imp {
|
||||||
else
|
else
|
||||||
basis.push_back(mul(coeff, t));
|
basis.push_back(mul(coeff, t));
|
||||||
}
|
}
|
||||||
else if (is_app(t) && m_occurs.contains(to_app(t)->get_decl())) {
|
else if (is_app(t) && m_soft_occurs.contains(to_app(t)->get_decl())) {
|
||||||
func_decl* v = to_app(t)->get_decl();
|
func_decl* v = to_app(t)->get_decl();
|
||||||
coeff1 = 0;
|
coeff1 = 0;
|
||||||
e->m_coeffs.find(v, coeff1);
|
e->m_coeffs.find(v, coeff1);
|
||||||
|
|
@ -287,9 +298,9 @@ struct smtmus::imp {
|
||||||
for (auto& [k, v] : m_lit2vars)
|
for (auto& [k, v] : m_lit2vars)
|
||||||
dealloc(v);
|
dealloc(v);
|
||||||
m_lit2vars.reset();
|
m_lit2vars.reset();
|
||||||
for (auto& [k, v] : m_occurs)
|
m_soft_vars.reset();
|
||||||
dealloc(v);
|
m_soft_occurs.reset();
|
||||||
m_occurs.reset();
|
m_hard_occurs.reset();
|
||||||
for (auto& [k, v] : m_lit2ineq)
|
for (auto& [k, v] : m_lit2ineq)
|
||||||
dealloc(v);
|
dealloc(v);
|
||||||
m_lit2ineq.reset();
|
m_lit2ineq.reset();
|
||||||
|
|
@ -331,11 +342,12 @@ struct smtmus::imp {
|
||||||
if (!shrunk[i] || crits[i])
|
if (!shrunk[i] || crits[i])
|
||||||
continue;
|
continue;
|
||||||
shrunk[i] = false;
|
shrunk[i] = false;
|
||||||
|
unsigned critical_extension_unused_vars = 1;
|
||||||
switch (solve(shrunk, max_cores > 0, false)) {
|
switch (solve(shrunk, max_cores > 0, false)) {
|
||||||
case l_true:
|
case l_true:
|
||||||
shrunk[i] = true;
|
shrunk[i] = true;
|
||||||
crits[i] = true;
|
crits[i] = true;
|
||||||
unsigned critical_extension_unused_vars = 1;
|
|
||||||
if (p_crit_ext)
|
if (p_crit_ext)
|
||||||
critical_extension_unused_vars = critical_extension(shrunk, crits, i);
|
critical_extension_unused_vars = critical_extension(shrunk, crits, i);
|
||||||
if (p_model_rotation && critical_extension_unused_vars > 0)
|
if (p_model_rotation && critical_extension_unused_vars > 0)
|
||||||
|
|
@ -451,7 +463,6 @@ struct smtmus::imp {
|
||||||
expr_ref val(m);
|
expr_ref val(m);
|
||||||
expr* lit2 = lit;
|
expr* lit2 = lit;
|
||||||
m.is_not(lit, lit2);
|
m.is_not(lit, lit2);
|
||||||
|
|
||||||
if (is_app(lit2) && to_app(lit2)->get_decl() == v && mdl.eval(v, val)) {
|
if (is_app(lit2) && to_app(lit2)->get_decl() == v && mdl.eval(v, val)) {
|
||||||
result.push_back(m.mk_bool_val(m.is_false(val)));
|
result.push_back(m.mk_bool_val(m.is_false(val)));
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -521,19 +532,25 @@ struct smtmus::imp {
|
||||||
|
|
||||||
bool rotate_get_falsified(bool_vector const& formula, model& mdl, func_decl* f, unsigned& falsified) {
|
bool rotate_get_falsified(bool_vector const& formula, model& mdl, func_decl* f, unsigned& falsified) {
|
||||||
falsified = UINT_MAX;
|
falsified = UINT_MAX;
|
||||||
for (auto i : *m_occurs[f]) {
|
for (auto i : m_soft_occurs[f]) {
|
||||||
if (formula[i] && !is_true(mdl, m_soft_clauses.get(i))) {
|
if (formula[i] && !is_true(mdl, m_soft_clauses.get(i))) {
|
||||||
if (falsified != UINT_MAX)
|
if (falsified != UINT_MAX)
|
||||||
return false;
|
return false;
|
||||||
falsified = i;
|
falsified = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return falsified != UINT_MAX;
|
if (falsified == UINT_MAX)
|
||||||
|
return false;
|
||||||
|
for (auto i : m_hard_occurs[f])
|
||||||
|
if (!mdl.is_true(m_hard.get(i)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_true(model& mdl, expr_ref_vector const& clause) {
|
bool is_true(model& mdl, expr_ref_vector const& clause) {
|
||||||
for (expr* lit : clause)
|
for (expr* lit : clause)
|
||||||
if (m.is_true(lit))
|
if (mdl.is_true(lit))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -556,7 +573,7 @@ struct smtmus::imp {
|
||||||
continue;
|
continue;
|
||||||
checked_vars.mark(v, true);
|
checked_vars.mark(v, true);
|
||||||
unsigned_vector hits;
|
unsigned_vector hits;
|
||||||
for (auto j : *m_occurs[v]) {
|
for (auto j : m_soft_occurs[v]) {
|
||||||
if (formula[j] && j != i && (are_conflicting(i, j, v) || m.is_bool(v->get_range())))
|
if (formula[j] && j != i && (are_conflicting(i, j, v) || m.is_bool(v->get_range())))
|
||||||
hits.push_back(j);
|
hits.push_back(j);
|
||||||
}
|
}
|
||||||
|
|
@ -620,7 +637,7 @@ smtmus::~smtmus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned smtmus::add_soft(expr* lit) {
|
unsigned smtmus::add_soft(expr* lit) {
|
||||||
return m_imp->add_soft(lit);
|
return m_imp->add_soft(lit), 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool smtmus::get_mus(expr_ref_vector& mus) {
|
lbool smtmus::get_mus(expr_ref_vector& mus) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue