mirror of
https://github.com/Z3Prover/z3
synced 2025-06-27 16:38:45 +00:00
working on core-maxsat
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
2349a0fcdd
commit
293a97bdfc
7 changed files with 52 additions and 22 deletions
|
@ -18,6 +18,7 @@ Notes:
|
||||||
--*/
|
--*/
|
||||||
#include "core_maxsat.h"
|
#include "core_maxsat.h"
|
||||||
#include "card_decl_plugin.h"
|
#include "card_decl_plugin.h"
|
||||||
|
#include "ast_pp.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
@ -36,9 +37,9 @@ namespace opt {
|
||||||
solver::scoped_push _sp(s);
|
solver::scoped_push _sp(s);
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
expr* a = m.mk_fresh_const("p", m.mk_bool_sort());
|
expr* a = m.mk_fresh_const("p", m.mk_bool_sort());
|
||||||
aux.push_back(a);
|
aux.push_back(m.mk_not(a));
|
||||||
s.assert_expr(m.mk_implies(a, m_soft[i].get()));
|
s.assert_expr(m.mk_or(a, m_soft[i].get()));
|
||||||
block_vars.insert(a);
|
block_vars.insert(aux.back());
|
||||||
}
|
}
|
||||||
while (m_answer.size() < m_upper) {
|
while (m_answer.size() < m_upper) {
|
||||||
ptr_vector<expr> vars;
|
ptr_vector<expr> vars;
|
||||||
|
@ -60,20 +61,30 @@ namespace opt {
|
||||||
ans.push_back(m_soft[i].get());
|
ans.push_back(m_soft[i].get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TRACE("opt", tout << "sat\n";
|
||||||
|
for (unsigned i = 0; i < ans.size(); ++i) {
|
||||||
|
tout << mk_pp(ans[i].get(), m) << "\n";
|
||||||
|
});
|
||||||
if (ans.size() > m_answer.size()) {
|
if (ans.size() > m_answer.size()) {
|
||||||
m_answer.reset();
|
m_answer.reset();
|
||||||
m_answer.append(ans);
|
m_answer.append(ans);
|
||||||
}
|
}
|
||||||
unsigned k = m_soft.size()-m_answer.size()-1; // TBD: fix this
|
unsigned k = m_soft.size()-m_answer.size()-1;
|
||||||
expr_ref fml = mk_at_most(core_vars, k);
|
expr_ref fml = mk_at_most(core_vars, k);
|
||||||
|
TRACE("opt", tout << "add: " << fml << "\n";);
|
||||||
s.assert_expr(fml);
|
s.assert_expr(fml);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case l_false: {
|
case l_false: {
|
||||||
ptr_vector<expr> core;
|
ptr_vector<expr> core;
|
||||||
s.get_unsat_core(core);
|
s.get_unsat_core(core);
|
||||||
|
TRACE("opt", tout << "core";
|
||||||
for (unsigned i = 0; i < core.size(); ++i) {
|
for (unsigned i = 0; i < core.size(); ++i) {
|
||||||
core_vars.insert(core[i]);
|
tout << mk_pp(core[i], m) << " ";
|
||||||
|
}
|
||||||
|
tout << "\n";);
|
||||||
|
for (unsigned i = 0; i < core.size(); ++i) {
|
||||||
|
core_vars.insert(get_not(core[i]));
|
||||||
block_vars.remove(core[i]);
|
block_vars.remove(core[i]);
|
||||||
}
|
}
|
||||||
if (core.empty()) {
|
if (core.empty()) {
|
||||||
|
@ -84,6 +95,7 @@ namespace opt {
|
||||||
// at least one core variable is True
|
// at least one core variable is True
|
||||||
expr_ref fml = mk_at_most(core_vars, 0);
|
expr_ref fml = mk_at_most(core_vars, 0);
|
||||||
fml = m.mk_not(fml);
|
fml = m.mk_not(fml);
|
||||||
|
TRACE("opt", tout << "add: " << fml << "\n";);
|
||||||
s.assert_expr(fml);
|
s.assert_expr(fml);
|
||||||
}
|
}
|
||||||
--m_upper;
|
--m_upper;
|
||||||
|
@ -108,6 +120,12 @@ namespace opt {
|
||||||
return expr_ref(card.mk_at_most_k(es.size(), es.c_ptr(), k), m);
|
return expr_ref(card.mk_at_most_k(es.size(), es.c_ptr(), k), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr* core_maxsat::get_not(expr* e) const {
|
||||||
|
expr* result = 0;
|
||||||
|
VERIFY(m.is_not(e, result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
rational core_maxsat::get_lower() const {
|
rational core_maxsat::get_lower() const {
|
||||||
return rational(m_answer.size());
|
return rational(m_answer.size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace opt {
|
||||||
private:
|
private:
|
||||||
void set2vector(expr_set const& set, ptr_vector<expr>& es) const;
|
void set2vector(expr_set const& set, ptr_vector<expr>& es) const;
|
||||||
expr_ref mk_at_most(expr_set const& set, unsigned k);
|
expr_ref mk_at_most(expr_set const& set, unsigned k);
|
||||||
|
expr* get_not(expr* e) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@ Module Name:
|
||||||
fu_malik.h
|
fu_malik.h
|
||||||
|
|
||||||
Abstract:
|
Abstract:
|
||||||
|
|
||||||
Fu&Malik built-in optimization method.
|
Fu&Malik built-in optimization method.
|
||||||
Adapted from sample code in C.
|
Adapted from sample code in C.
|
||||||
|
|
||||||
|
@ -15,6 +16,10 @@ Author:
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
|
Takes solver with hard constraints added.
|
||||||
|
Returns a maximal satisfying subset of soft_constraints
|
||||||
|
that are still consistent with the solver state.
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#ifndef _OPT_FU_MALIK_H_
|
#ifndef _OPT_FU_MALIK_H_
|
||||||
#define _OPT_FU_MALIK_H_
|
#define _OPT_FU_MALIK_H_
|
||||||
|
@ -23,11 +28,6 @@ Notes:
|
||||||
#include "maxsmt.h"
|
#include "maxsmt.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
/**
|
|
||||||
Takes solver with hard constraints added.
|
|
||||||
Returns a maximal satisfying subset of soft_constraints
|
|
||||||
that are still consistent with the solver state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class fu_malik : public maxsmt_solver {
|
class fu_malik : public maxsmt_solver {
|
||||||
struct imp;
|
struct imp;
|
||||||
|
|
|
@ -3,7 +3,7 @@ Copyright (c) 2013 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
opt_maxsmt.cpp
|
maxsmt.cpp
|
||||||
|
|
||||||
Abstract:
|
Abstract:
|
||||||
|
|
||||||
|
@ -19,8 +19,10 @@ Notes:
|
||||||
|
|
||||||
#include "maxsmt.h"
|
#include "maxsmt.h"
|
||||||
#include "fu_malik.h"
|
#include "fu_malik.h"
|
||||||
|
#include "core_maxsat.h"
|
||||||
#include "weighted_maxsat.h"
|
#include "weighted_maxsat.h"
|
||||||
#include "ast_pp.h"
|
#include "ast_pp.h"
|
||||||
|
#include "opt_params.hpp"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
@ -35,8 +37,13 @@ namespace opt {
|
||||||
m_answer.append(m_soft_constraints);
|
m_answer.append(m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (is_maxsat_problem(m_weights)) {
|
else if (is_maxsat_problem(m_weights)) {
|
||||||
|
if (m_maxsat_engine == symbol("core_maxsat")) {
|
||||||
|
m_msolver = alloc(core_maxsat, m, s, m_soft_constraints);
|
||||||
|
}
|
||||||
|
else {
|
||||||
m_msolver = alloc(fu_malik, m, s, m_soft_constraints);
|
m_msolver = alloc(fu_malik, m, s, m_soft_constraints);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
m_msolver = alloc(wmaxsmt, m, opt_solver::to_opt(s), m_soft_constraints, m_weights);
|
m_msolver = alloc(wmaxsmt, m, opt_solver::to_opt(s), m_soft_constraints, m_weights);
|
||||||
}
|
}
|
||||||
|
@ -110,6 +117,8 @@ namespace opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxsmt::updt_params(params_ref& p) {
|
void maxsmt::updt_params(params_ref& p) {
|
||||||
|
opt_params _p(p);
|
||||||
|
m_maxsat_engine = _p.maxsat_engine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ Copyright (c) 2013 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
opt_maxsmt.h
|
maxsmt.h
|
||||||
|
|
||||||
Abstract:
|
Abstract:
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ namespace opt {
|
||||||
expr_ref_vector m_answer;
|
expr_ref_vector m_answer;
|
||||||
vector<rational> m_weights;
|
vector<rational> m_weights;
|
||||||
scoped_ptr<maxsmt_solver> m_msolver;
|
scoped_ptr<maxsmt_solver> m_msolver;
|
||||||
|
symbol m_maxsat_engine;
|
||||||
public:
|
public:
|
||||||
maxsmt(ast_manager& m): m(m), m_s(0), m_cancel(false), m_soft_constraints(m), m_answer(m) {}
|
maxsmt(ast_manager& m): m(m), m_s(0), m_cancel(false), m_soft_constraints(m), m_answer(m) {}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ def_module_params('opt',
|
||||||
export=True,
|
export=True,
|
||||||
params=(('timeout', UINT, UINT_MAX, 'set timeout'),
|
params=(('timeout', UINT, UINT_MAX, 'set timeout'),
|
||||||
('engine', SYMBOL, 'basic', "select optimization engine: 'basic', 'farkas', 'symba'"),
|
('engine', SYMBOL, 'basic', "select optimization engine: 'basic', 'farkas', 'symba'"),
|
||||||
|
('maxsat_engine', SYMBOL, 'fu_malik', "select engine for non-weighted maxsat: 'fu_malik', 'core_maxsat'"),
|
||||||
('pareto', BOOL, False, 'return a Pareto front (as opposed to a bounding box)'),
|
('pareto', BOOL, False, 'return a Pareto front (as opposed to a bounding box)'),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
|
@ -453,19 +453,19 @@ namespace smt {
|
||||||
|
|
||||||
void theory_card::pop_scope_eh(unsigned num_scopes) {
|
void theory_card::pop_scope_eh(unsigned num_scopes) {
|
||||||
unsigned sz = m_watch_lim[m_watch_lim.size()-num_scopes];
|
unsigned sz = m_watch_lim[m_watch_lim.size()-num_scopes];
|
||||||
for (unsigned i = m_watch_trail.size(); i > sz; ) {
|
while (m_watch_trail.size() > sz) {
|
||||||
--i;
|
|
||||||
ptr_vector<card>* cards = 0;
|
ptr_vector<card>* cards = 0;
|
||||||
VERIFY(m_watch.find(m_watch_trail[i], cards));
|
VERIFY(m_watch.find(m_watch_trail.back(), cards));
|
||||||
SASSERT(cards && !cards->empty());
|
SASSERT(cards && !cards->empty());
|
||||||
cards->pop_back();
|
cards->pop_back();
|
||||||
|
m_watch_trail.pop_back();
|
||||||
}
|
}
|
||||||
m_watch_lim.resize(m_watch_lim.size()-num_scopes);
|
m_watch_lim.resize(m_watch_lim.size()-num_scopes);
|
||||||
sz = m_cards_lim[m_cards_lim.size()-num_scopes];
|
sz = m_cards_lim[m_cards_lim.size()-num_scopes];
|
||||||
for (unsigned i = m_cards_trail.size(); i > sz; ) {
|
while (m_cards_trail.size() > sz) {
|
||||||
--i;
|
SASSERT(m_cards.contains(m_cards_trail.back()));
|
||||||
SASSERT(m_cards.contains(m_cards_trail[i]));
|
m_cards.remove(m_cards_trail.back());
|
||||||
m_cards.remove(m_cards_trail[i]);
|
m_cards_trail.pop_back();
|
||||||
}
|
}
|
||||||
m_cards_lim.resize(m_cards_lim.size()-num_scopes);
|
m_cards_lim.resize(m_cards_lim.size()-num_scopes);
|
||||||
}
|
}
|
||||||
|
@ -482,7 +482,7 @@ namespace smt {
|
||||||
TRACE("card", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
|
TRACE("card", ctx.display_literals_verbose(tout, lits.size(), lits.c_ptr()); tout << "\n";);
|
||||||
justification* js = 0;
|
justification* js = 0;
|
||||||
ctx.mk_clause(lits.size(), lits.c_ptr(), js, CLS_AUX_LEMMA, 0);
|
ctx.mk_clause(lits.size(), lits.c_ptr(), js, CLS_AUX_LEMMA, 0);
|
||||||
IF_VERBOSE(0,
|
IF_VERBOSE(1,
|
||||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||||
verbose_stream() << lits[i] << " ";
|
verbose_stream() << lits[i] << " ";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue