3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

improving perf of mutex finding, revert semantics of 0 timeout to no-timeout. Issue #791

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-11-17 04:26:17 +02:00
parent e65d80dedd
commit e9db934f1a
10 changed files with 116 additions and 74 deletions

View file

@ -192,9 +192,8 @@ public:
lbool mus_solver() {
lbool is_sat = l_true;
if (!init()) return l_undef;
init_local();
is_sat = init_local();
trace();
is_sat = process_mutex();
if (is_sat != l_true) return is_sat;
while (m_lower < m_upper) {
if (m_lower >= m_upper) break;
@ -233,10 +232,9 @@ public:
lbool primal_dual_solver() {
if (!init()) return l_undef;
init_local();
lbool is_sat = init_local();
trace();
exprs cs;
lbool is_sat = process_mutex();
if (is_sat != l_true) return is_sat;
while (m_lower < m_upper) {
is_sat = check_sat_hill_climb(m_asms);
@ -274,54 +272,6 @@ public:
return l_true;
}
lbool process_mutex() {
vector<expr_ref_vector> mutexes;
lbool is_sat = s().find_mutexes(m_asms, mutexes);
if (is_sat != l_true) {
return is_sat;
}
for (unsigned i = 0; i < mutexes.size(); ++i) {
process_mutex(mutexes[i]);
}
if (!mutexes.empty()) {
trace();
}
return l_true;
}
void process_mutex(expr_ref_vector& mutex) {
TRACE("opt",
for (unsigned i = 0; i < mutex.size(); ++i) {
tout << mk_pp(mutex[i].get(), m) << " |-> " << get_weight(mutex[i].get()) << "\n";
});
if (mutex.size() <= 1) {
return;
}
sort_assumptions(mutex);
ptr_vector<expr> core(mutex.size(), mutex.c_ptr());
remove_soft(core, m_asms);
rational weight(0), sum1(0), sum2(0);
vector<rational> weights;
for (unsigned i = 0; i < mutex.size(); ++i) {
rational w = get_weight(mutex[i].get());
weights.push_back(w);
sum1 += w;
m_asm2weight.remove(mutex[i].get());
}
for (unsigned i = mutex.size(); i > 0; ) {
--i;
expr_ref soft(m.mk_or(i+1, mutex.c_ptr()), m);
rational w = weights[i];
weight = w - weight;
m_lower += weight*rational(i);
sum2 += weight*rational(i+1);
add_soft(soft, weight);
for (; i > 0 && weights[i-1] == w; --i) {}
weight = w;
}
SASSERT(sum1 == sum2);
}
lbool check_sat_hill_climb(expr_ref_vector& asms1) {
expr_ref_vector asms(asms1);
lbool is_sat = l_true;
@ -854,12 +804,18 @@ public:
m_dump_benchmarks = _p.dump_benchmarks();
}
void init_local() {
lbool init_local() {
m_upper.reset();
m_lower.reset();
m_trail.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) {
add_soft(m_soft[i], m_weights[i]);
obj_map<expr, rational> new_soft;
lbool is_sat = find_mutexes(new_soft);
if (is_sat != l_true) {
return is_sat;
}
obj_map<expr, rational>::iterator it = new_soft.begin(), end = new_soft.end();
for (; it != end; ++it) {
add_soft(it->m_key, it->m_value);
}
m_max_upper = m_upper;
m_found_feasible_optimum = false;
@ -867,6 +823,7 @@ public:
add_upper_bound_block();
m_csmodel = 0;
m_correction_set_size = 0;
return l_true;
}
virtual void commit_assignment() {

View file

@ -38,7 +38,8 @@ namespace opt {
m_c(c),
m_soft(soft),
m_weights(ws),
m_assertions(m) {
m_assertions(m),
m_trail(m) {
c.get_base_model(m_model);
SASSERT(m_model);
updt_params(c.params());
@ -152,6 +153,67 @@ namespace opt {
verbose_stream() << "(opt." << solver << " [" << l << ":" << u << "])\n";);
}
lbool maxsmt_solver_base::find_mutexes(obj_map<expr, rational>& new_soft) {
m_lower.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) {
new_soft.insert(m_soft[i], m_weights[i]);
}
vector<expr_ref_vector> mutexes;
lbool is_sat = s().find_mutexes(m_soft, mutexes);
if (is_sat != l_true) {
return is_sat;
}
for (unsigned i = 0; i < mutexes.size(); ++i) {
process_mutex(mutexes[i], new_soft);
}
return l_true;
}
struct maxsmt_compare_soft {
obj_map<expr, rational> const& m_soft;
maxsmt_compare_soft(obj_map<expr, rational> const& soft): m_soft(soft) {}
bool operator()(expr* a, expr* b) const {
return m_soft.find(a) > m_soft.find(b);
}
};
void maxsmt_solver_base::process_mutex(expr_ref_vector& mutex, obj_map<expr, rational>& new_soft) {
TRACE("opt",
for (unsigned i = 0; i < mutex.size(); ++i) {
tout << mk_pp(mutex[i].get(), m) << " |-> " << new_soft.find(mutex[i].get()) << "\n";
});
if (mutex.size() <= 1) {
return;
}
maxsmt_compare_soft cmp(new_soft);
ptr_vector<expr> _mutex(mutex.size(), mutex.c_ptr());
std::sort(_mutex.begin(), _mutex.end(), cmp);
mutex.reset();
mutex.append(_mutex.size(), _mutex.c_ptr());
rational weight(0), sum1(0), sum2(0);
vector<rational> weights;
for (unsigned i = 0; i < mutex.size(); ++i) {
rational w = new_soft.find(mutex[i].get());
weights.push_back(w);
sum1 += w;
new_soft.remove(mutex[i].get());
}
for (unsigned i = mutex.size(); i > 0; ) {
--i;
expr_ref soft(m.mk_or(i+1, mutex.c_ptr()), m);
m_trail.push_back(soft);
rational w = weights[i];
weight = w - weight;
m_lower += weight*rational(i);
sum2 += weight*rational(i+1);
new_soft.insert(soft, weight);
for (; i > 0 && weights[i-1] == w; --i) {}
weight = w;
}
SASSERT(sum1 == sum2);
}
maxsmt::maxsmt(maxsat_context& c, unsigned index):
@ -310,4 +372,5 @@ namespace opt {
}
};

View file

@ -62,6 +62,7 @@ namespace opt {
const expr_ref_vector m_soft;
vector<rational> m_weights;
expr_ref_vector m_assertions;
expr_ref_vector m_trail;
rational m_lower;
rational m_upper;
model_ref m_model;
@ -95,12 +96,17 @@ namespace opt {
~scoped_ensure_theory();
smt::theory_wmaxsat& operator()();
};
lbool find_mutexes(obj_map<expr, rational>& new_soft);
protected:
void enable_sls(bool force);
void trace_bounds(char const* solver);
void process_mutex(expr_ref_vector& mutex, obj_map<expr, rational>& new_soft);
};
/**

View file

@ -40,19 +40,28 @@ namespace opt {
lbool operator()() {
TRACE("opt", tout << "weighted maxsat\n";);
scoped_ensure_theory wth(*this);
lbool is_sat = l_true;
bool was_sat = false;
for (unsigned i = 0; i < m_soft.size(); ++i) {
wth().assert_weighted(m_soft[i], m_weights[i]);
obj_map<expr, rational> soft;
lbool is_sat = find_mutexes(soft);
if (is_sat != l_true) {
return is_sat;
}
while (l_true == is_sat) {
is_sat = s().check_sat(0,0);
rational offset = m_lower;
m_upper = offset;
bool was_sat = false;
obj_map<expr, rational>::iterator it = soft.begin(), end = soft.end();
for (; it != end; ++it) {
wth().assert_weighted(it->m_key, it->m_value);
m_upper += it->m_value;
}
trace_bounds("wmax");
while (l_true == is_sat && m_lower < m_upper) {
is_sat = s().check_sat(0, 0);
if (m.canceled()) {
is_sat = l_undef;
}
if (is_sat == l_true) {
if (wth().is_optimal()) {
m_upper = wth().get_min_cost();
m_upper = offset + wth().get_min_cost();
s().get_model(m_model);
}
expr_ref fml = wth().mk_block();
@ -63,11 +72,11 @@ namespace opt {
}
if (was_sat) {
wth().get_assignment(m_assignment);
m_upper = offset + wth().get_min_cost();
}
if (is_sat == l_false && was_sat) {
is_sat = l_true;
}
m_upper = wth().get_min_cost();
if (is_sat == l_true) {
m_lower = m_upper;
}