mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
fix and coallesce clique functionality
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
1600823435
commit
ea601dd403
17 changed files with 361 additions and 119 deletions
|
@ -162,7 +162,6 @@ public:
|
|||
if (m_asm2weight.find(e, weight)) {
|
||||
weight += w;
|
||||
m_asm2weight.insert(e, weight);
|
||||
m_upper += w;
|
||||
return;
|
||||
}
|
||||
if (is_literal(e)) {
|
||||
|
@ -174,7 +173,6 @@ public:
|
|||
s().assert_expr(fml);
|
||||
}
|
||||
new_assumption(asum, w);
|
||||
m_upper += w;
|
||||
}
|
||||
|
||||
void new_assumption(expr* e, rational const& w) {
|
||||
|
@ -805,7 +803,6 @@ public:
|
|||
}
|
||||
|
||||
lbool init_local() {
|
||||
m_upper.reset();
|
||||
m_lower.reset();
|
||||
m_trail.reset();
|
||||
obj_map<expr, rational> new_soft;
|
||||
|
|
|
@ -235,6 +235,9 @@ namespace opt {
|
|||
else if (maxsat_engine == symbol("wmax")) {
|
||||
m_msolver = mk_wmax(m_c, m_weights, m_soft_constraints);
|
||||
}
|
||||
else if (maxsat_engine == symbol("sortmax")) {
|
||||
m_msolver = mk_sortmax(m_c, m_weights, m_soft_constraints);
|
||||
}
|
||||
else {
|
||||
warning_msg("solver %s is not recognized, using default 'maxres'", maxsat_engine.str().c_str());
|
||||
m_msolver = mk_maxres(m_c, m_index, m_weights, m_soft_constraints);
|
||||
|
|
141
src/opt/sortmax.cpp
Normal file
141
src/opt/sortmax.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sortmax.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Theory based MaxSAT.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2016-11-18
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include "maxsmt.h"
|
||||
#include "uint_set.h"
|
||||
#include "ast_pp.h"
|
||||
#include "model_smt2_pp.h"
|
||||
#include "smt_theory.h"
|
||||
#include "smt_context.h"
|
||||
#include "opt_context.h"
|
||||
#include "sorting_network.h"
|
||||
#include "filter_model_converter.h"
|
||||
|
||||
namespace opt {
|
||||
|
||||
class sortmax : public maxsmt_solver_base {
|
||||
public:
|
||||
typedef expr* literal;
|
||||
typedef ptr_vector<expr> literal_vector;
|
||||
psort_nw<sortmax> m_sort;
|
||||
expr_ref_vector m_trail;
|
||||
func_decl_ref_vector m_fresh;
|
||||
ref<filter_model_converter> m_filter;
|
||||
sortmax(maxsat_context& c, weights_t& ws, expr_ref_vector const& soft):
|
||||
maxsmt_solver_base(c, ws, soft), m_sort(*this), m_trail(m), m_fresh(m) {}
|
||||
|
||||
virtual ~sortmax() {}
|
||||
|
||||
lbool operator()() {
|
||||
obj_map<expr, rational> soft;
|
||||
if (!init()) {
|
||||
return l_false;
|
||||
}
|
||||
lbool is_sat = find_mutexes(soft);
|
||||
if (is_sat != l_true) {
|
||||
return is_sat;
|
||||
}
|
||||
m_filter = alloc(filter_model_converter, m);
|
||||
rational offset = m_lower;
|
||||
m_upper = offset;
|
||||
expr_ref_vector in(m);
|
||||
expr_ref tmp(m);
|
||||
ptr_vector<expr> out;
|
||||
obj_map<expr, rational>::iterator it = soft.begin(), end = soft.end();
|
||||
for (; it != end; ++it) {
|
||||
unsigned n = it->m_value.get_unsigned();
|
||||
while (n > 0) {
|
||||
in.push_back(it->m_key);
|
||||
--n;
|
||||
}
|
||||
m_upper += it->m_value;
|
||||
}
|
||||
m_sort.sorting(in.size(), in.c_ptr(), out);
|
||||
unsigned first = 0;
|
||||
while (l_true == is_sat && first < out.size() && m_lower < m_upper) {
|
||||
trace_bounds("sortmax");
|
||||
s().assert_expr(out[first]);
|
||||
is_sat = s().check_sat(0, 0);
|
||||
TRACE("opt", tout << is_sat << "\n"; s().display(tout); tout << "\n";);
|
||||
if (m.canceled()) {
|
||||
is_sat = l_undef;
|
||||
}
|
||||
if (is_sat == l_true) {
|
||||
++first;
|
||||
s().get_model(m_model);
|
||||
update_assignment();
|
||||
for (; first < out.size() && is_true(out[first]); ++first) {
|
||||
s().assert_expr(out[first]);
|
||||
}
|
||||
TRACE("opt", model_smt2_pp(tout, m, *m_model.get(), 0););
|
||||
m_upper = m_lower + rational(out.size() - first);
|
||||
(*m_filter)(m_model);
|
||||
}
|
||||
}
|
||||
if (is_sat == l_false) {
|
||||
is_sat = l_true;
|
||||
m_lower = m_upper;
|
||||
}
|
||||
TRACE("opt", tout << "min cost: " << m_upper << "\n";);
|
||||
return is_sat;
|
||||
}
|
||||
|
||||
void update_assignment() {
|
||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||
m_assignment[i] = is_true(m_soft[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_true(expr* e) {
|
||||
expr_ref tmp(m);
|
||||
return m_model->eval(e, tmp) && m.is_true(tmp);
|
||||
}
|
||||
|
||||
// definitions used for sorting network
|
||||
literal mk_false() { return m.mk_false(); }
|
||||
literal mk_true() { return m.mk_true(); }
|
||||
literal mk_max(literal a, literal b) { return trail(m.mk_or(a, b)); }
|
||||
literal mk_min(literal a, literal b) { return trail(m.mk_and(a, b)); }
|
||||
literal mk_not(literal a) { if (m.is_not(a,a)) return a; return trail(m.mk_not(a)); }
|
||||
|
||||
std::ostream& pp(std::ostream& out, literal lit) { return out << mk_pp(lit, m); }
|
||||
|
||||
literal trail(literal l) {
|
||||
m_trail.push_back(l);
|
||||
return l;
|
||||
}
|
||||
literal fresh() {
|
||||
expr_ref fr(m.mk_fresh_const("sn", m.mk_bool_sort()), m);
|
||||
func_decl* f = to_app(fr)->get_decl();
|
||||
m_fresh.push_back(f);
|
||||
m_filter->insert(f);
|
||||
return trail(fr);
|
||||
}
|
||||
|
||||
void mk_clause(unsigned n, literal const* lits) {
|
||||
s().assert_expr(mk_or(m, n, lits));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
maxsmt_solver_base* mk_sortmax(maxsat_context& c, weights_t& ws, expr_ref_vector const& soft) {
|
||||
return alloc(sortmax, c, ws, soft);
|
||||
}
|
||||
|
||||
}
|
|
@ -51,7 +51,10 @@ namespace opt {
|
|||
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;
|
||||
expr_ref tmp(m);
|
||||
if (!m_model->eval(it->m_key, tmp) || !m.is_true(tmp)) {
|
||||
m_upper += it->m_value;
|
||||
}
|
||||
}
|
||||
trace_bounds("wmax");
|
||||
while (l_true == is_sat && m_lower < m_upper) {
|
||||
|
|
|
@ -25,5 +25,7 @@ Notes:
|
|||
namespace opt {
|
||||
maxsmt_solver_base* mk_wmax(maxsat_context& c, weights_t & ws, expr_ref_vector const& soft);
|
||||
|
||||
maxsmt_solver_base* mk_sortmax(maxsat_context& c, weights_t & ws, expr_ref_vector const& soft);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue