mirror of
https://github.com/Z3Prover/z3
synced 2025-06-23 06:13:40 +00:00
refactor sat/sls interface. Remove wpm2 and bvsls dependencies
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a02cab2194
commit
ee1a1b1135
43 changed files with 609 additions and 891 deletions
|
@ -99,9 +99,9 @@ namespace opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bcd2(opt_solver* s, ast_manager& m, params_ref& p,
|
bcd2(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft):
|
vector<rational> const& ws, expr_ref_vector const& soft):
|
||||||
maxsmt_solver_base(s, m, p, ws, soft),
|
maxsmt_solver_base(c, ws, soft),
|
||||||
pb(m),
|
pb(m),
|
||||||
m_soft_aux(m),
|
m_soft_aux(m),
|
||||||
m_trail(m),
|
m_trail(m),
|
||||||
|
@ -116,7 +116,6 @@ namespace opt {
|
||||||
expr_ref fml(m), r(m);
|
expr_ref fml(m), r(m);
|
||||||
lbool is_sat = l_undef;
|
lbool is_sat = l_undef;
|
||||||
expr_ref_vector asms(m);
|
expr_ref_vector asms(m);
|
||||||
enable_sls();
|
|
||||||
solver::scoped_push _scope1(s());
|
solver::scoped_push _scope1(s());
|
||||||
init();
|
init();
|
||||||
init_bcd();
|
init_bcd();
|
||||||
|
@ -400,9 +399,9 @@ namespace opt {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
maxsmt_solver_base* opt::mk_bcd2(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* opt::mk_bcd2(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(bcd2, s, m, p, ws, soft);
|
return alloc(bcd2, c, ws, soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ Notes:
|
||||||
#include "maxsmt.h"
|
#include "maxsmt.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
maxsmt_solver_base* mk_bcd2(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* mk_bcd2(context& c, vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2013 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
bvsls_opt_solver.cpp
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Uses the bvsls engine for optimization
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Christoph (cwinter) 2014-3-28
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
|
|
||||||
#include "bvsls_opt_solver.h"
|
|
||||||
|
|
||||||
namespace opt {
|
|
||||||
|
|
||||||
bvsls_opt_solver::bvsls_opt_solver(ast_manager & m, params_ref const & p) :
|
|
||||||
opt_solver(m, p, symbol("QF_BV")),
|
|
||||||
m_manager(m),
|
|
||||||
m_params(p),
|
|
||||||
m_engine(m, p)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bvsls_opt_solver::~bvsls_opt_solver()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::updt_params(params_ref & p)
|
|
||||||
{
|
|
||||||
opt_solver::updt_params(p);
|
|
||||||
m_engine.updt_params(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::collect_param_descrs(param_descrs & r)
|
|
||||||
{
|
|
||||||
opt_solver::collect_param_descrs(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::collect_statistics(statistics & st) const
|
|
||||||
{
|
|
||||||
opt_solver::collect_statistics(st);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::assert_expr(expr * t) {
|
|
||||||
m_engine.assert_expr(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::push_core()
|
|
||||||
{
|
|
||||||
opt_solver::push_core();
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::pop_core(unsigned n)
|
|
||||||
{
|
|
||||||
opt_solver::pop_core(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
lbool bvsls_opt_solver::check_sat_core(unsigned num_assumptions, expr * const * assumptions)
|
|
||||||
{
|
|
||||||
SASSERT(num_assumptions == 0);
|
|
||||||
SASSERT(assumptions == 0);
|
|
||||||
return m_engine();
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::get_unsat_core(ptr_vector<expr> & r)
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::get_model(model_ref & m)
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
}
|
|
||||||
|
|
||||||
proof * bvsls_opt_solver::get_proof()
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string bvsls_opt_solver::reason_unknown() const
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::get_labels(svector<symbol> & r)
|
|
||||||
{
|
|
||||||
opt_solver::get_labels(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::set_cancel(bool f)
|
|
||||||
{
|
|
||||||
opt_solver::set_cancel(f);
|
|
||||||
m_engine.set_cancel(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::set_progress_callback(progress_callback * callback)
|
|
||||||
{
|
|
||||||
opt_solver::set_progress_callback(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned bvsls_opt_solver::get_num_assertions() const
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
}
|
|
||||||
|
|
||||||
expr * bvsls_opt_solver::get_assertion(unsigned idx) const
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
}
|
|
||||||
|
|
||||||
void bvsls_opt_solver::display(std::ostream & out) const
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2013 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
bvsls_opt_solver.h
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Uses the bvsls engine for optimization
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Christoph (cwinter) 2014-3-28
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#ifndef _BVSLS_OPT_SOLVER_H_
|
|
||||||
#define _BVSLS_OPT_SOLVER_H_
|
|
||||||
|
|
||||||
#include "bvsls_opt_engine.h"
|
|
||||||
#include "opt_solver.h"
|
|
||||||
|
|
||||||
namespace opt {
|
|
||||||
|
|
||||||
class bvsls_opt_solver : public opt_solver {
|
|
||||||
ast_manager & m_manager;
|
|
||||||
params_ref const & m_params;
|
|
||||||
bvsls_opt_engine m_engine;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bvsls_opt_solver(ast_manager & m, params_ref const & p);
|
|
||||||
virtual ~bvsls_opt_solver();
|
|
||||||
|
|
||||||
virtual void updt_params(params_ref & p);
|
|
||||||
virtual void collect_param_descrs(param_descrs & r);
|
|
||||||
virtual void collect_statistics(statistics & st) const;
|
|
||||||
virtual void assert_expr(expr * t);
|
|
||||||
virtual void push_core();
|
|
||||||
virtual void pop_core(unsigned n);
|
|
||||||
virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions);
|
|
||||||
virtual void get_unsat_core(ptr_vector<expr> & r);
|
|
||||||
virtual void get_model(model_ref & m);
|
|
||||||
virtual proof * get_proof();
|
|
||||||
virtual std::string reason_unknown() const;
|
|
||||||
virtual void get_labels(svector<symbol> & r);
|
|
||||||
virtual void set_cancel(bool f);
|
|
||||||
virtual void set_progress_callback(progress_callback * callback);
|
|
||||||
virtual unsigned get_num_assertions() const;
|
|
||||||
virtual expr * get_assertion(unsigned idx) const;
|
|
||||||
virtual void display(std::ostream & out) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -19,11 +19,13 @@ Notes:
|
||||||
#include "core_maxsat.h"
|
#include "core_maxsat.h"
|
||||||
#include "pb_decl_plugin.h"
|
#include "pb_decl_plugin.h"
|
||||||
#include "ast_pp.h"
|
#include "ast_pp.h"
|
||||||
|
#include "opt_context.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
core_maxsat::core_maxsat(ast_manager& m, solver& s, expr_ref_vector& soft_constraints):
|
core_maxsat::core_maxsat(context& c, expr_ref_vector& soft_constraints):
|
||||||
m(m), s(s), m_lower(0), m_upper(soft_constraints.size()), m_soft(soft_constraints) {
|
m(c.get_manager()), s(c.get_solver()),
|
||||||
|
m_lower(0), m_upper(soft_constraints.size()), m_soft(soft_constraints) {
|
||||||
m_answer.resize(m_soft.size(), false);
|
m_answer.resize(m_soft.size(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace opt {
|
||||||
unsigned m_lower;
|
unsigned m_lower;
|
||||||
model_ref m_model;
|
model_ref m_model;
|
||||||
public:
|
public:
|
||||||
core_maxsat(ast_manager& m, solver& s, expr_ref_vector& soft_constraints);
|
core_maxsat(context& c, expr_ref_vector& soft_constraints);
|
||||||
virtual ~core_maxsat();
|
virtual ~core_maxsat();
|
||||||
virtual lbool operator()();
|
virtual lbool operator()();
|
||||||
virtual rational get_lower() const;
|
virtual rational get_lower() const;
|
||||||
|
|
|
@ -23,9 +23,9 @@ Notes:
|
||||||
#include "goal.h"
|
#include "goal.h"
|
||||||
#include "probe.h"
|
#include "probe.h"
|
||||||
#include "tactic.h"
|
#include "tactic.h"
|
||||||
#include "smt_context.h"
|
|
||||||
#include "ast_pp.h"
|
#include "ast_pp.h"
|
||||||
#include "model_smt2_pp.h"
|
#include "model_smt2_pp.h"
|
||||||
|
#include "opt_context.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Fu & Malik procedure for MaxSAT. This procedure is based on
|
\brief Fu & Malik procedure for MaxSAT. This procedure is based on
|
||||||
|
@ -44,9 +44,9 @@ Notes:
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
struct fu_malik::imp {
|
struct fu_malik::imp {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
opt_solver & m_opt_solver;
|
solver& m_s;
|
||||||
ref<solver> m_s;
|
filter_model_converter& m_fm;
|
||||||
expr_ref_vector m_soft;
|
expr_ref_vector m_soft;
|
||||||
expr_ref_vector m_orig_soft;
|
expr_ref_vector m_orig_soft;
|
||||||
expr_ref_vector m_aux;
|
expr_ref_vector m_aux;
|
||||||
|
@ -55,10 +55,10 @@ namespace opt {
|
||||||
unsigned m_lower;
|
unsigned m_lower;
|
||||||
model_ref m_model;
|
model_ref m_model;
|
||||||
|
|
||||||
imp(ast_manager& m, opt_solver& s, expr_ref_vector const& soft):
|
imp(context& c, expr_ref_vector const& soft):
|
||||||
m(m),
|
m(c.get_manager()),
|
||||||
m_opt_solver(s),
|
m_s(c.get_solver()),
|
||||||
m_s(&s),
|
m_fm(c.fm()),
|
||||||
m_soft(soft),
|
m_soft(soft),
|
||||||
m_orig_soft(soft),
|
m_orig_soft(soft),
|
||||||
m_aux(m),
|
m_aux(m),
|
||||||
|
@ -69,7 +69,7 @@ namespace opt {
|
||||||
m_assignment.resize(m_soft.size(), false);
|
m_assignment.resize(m_soft.size(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
solver& s() { return *m_s; }
|
solver& s() { return m_s; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief One step of the Fu&Malik algorithm.
|
\brief One step of the Fu&Malik algorithm.
|
||||||
|
@ -96,10 +96,8 @@ namespace opt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void collect_statistics(statistics& st) const {
|
void collect_statistics(statistics& st) const {
|
||||||
if (m_s != &m_opt_solver) {
|
|
||||||
m_s->collect_statistics(st);
|
|
||||||
}
|
|
||||||
st.update("opt-fm-num-steps", m_soft.size() + 2 - m_upper);
|
st.update("opt-fm-num-steps", m_soft.size() + 2 - m_upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +143,8 @@ namespace opt {
|
||||||
app_ref block_var(m), tmp(m);
|
app_ref block_var(m), tmp(m);
|
||||||
block_var = m.mk_fresh_const("block_var", m.mk_bool_sort());
|
block_var = m.mk_fresh_const("block_var", m.mk_bool_sort());
|
||||||
m_aux[i] = m.mk_fresh_const("aux", m.mk_bool_sort());
|
m_aux[i] = m.mk_fresh_const("aux", m.mk_bool_sort());
|
||||||
m_opt_solver.mc().insert(block_var->get_decl());
|
m_fm.insert(block_var->get_decl());
|
||||||
m_opt_solver.mc().insert(to_app(m_aux[i].get())->get_decl());
|
m_fm.insert(to_app(m_aux[i].get())->get_decl());
|
||||||
m_soft[i] = m.mk_or(m_soft[i].get(), block_var);
|
m_soft[i] = m.mk_or(m_soft[i].get(), block_var);
|
||||||
block_vars.push_back(block_var);
|
block_vars.push_back(block_var);
|
||||||
tmp = m.mk_or(m_soft[i].get(), m_aux[i].get());
|
tmp = m.mk_or(m_soft[i].get(), m_aux[i].get());
|
||||||
|
@ -181,17 +179,6 @@ namespace opt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_solver() {
|
|
||||||
if (m_opt_solver.dump_benchmarks())
|
|
||||||
return;
|
|
||||||
|
|
||||||
solver& current_solver = s();
|
|
||||||
goal g(m, true, false);
|
|
||||||
unsigned num_assertions = current_solver.get_num_assertions();
|
|
||||||
for (unsigned i = 0; i < num_assertions; ++i) {
|
|
||||||
g.assert_expr(current_solver.get_assertion(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TBD: bug when cancel flag is set, fu_malik returns is_sat == l_true instead of l_undef
|
// TBD: bug when cancel flag is set, fu_malik returns is_sat == l_true instead of l_undef
|
||||||
lbool operator()() {
|
lbool operator()() {
|
||||||
|
@ -199,7 +186,6 @@ namespace opt {
|
||||||
if (m_soft.empty()) {
|
if (m_soft.empty()) {
|
||||||
return is_sat;
|
return is_sat;
|
||||||
}
|
}
|
||||||
set_solver();
|
|
||||||
solver::scoped_push _sp(s());
|
solver::scoped_push _sp(s());
|
||||||
expr_ref tmp(m);
|
expr_ref tmp(m);
|
||||||
|
|
||||||
|
@ -211,7 +197,7 @@ namespace opt {
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
m_aux.push_back(m.mk_fresh_const("p", m.mk_bool_sort()));
|
m_aux.push_back(m.mk_fresh_const("p", m.mk_bool_sort()));
|
||||||
m_opt_solver.mc().insert(to_app(m_aux.back())->get_decl());
|
m_fm.insert(to_app(m_aux.back())->get_decl());
|
||||||
tmp = m.mk_or(m_soft[i].get(), m_aux[i].get());
|
tmp = m.mk_or(m_soft[i].get(), m_aux[i].get());
|
||||||
s().assert_expr(tmp);
|
s().assert_expr(tmp);
|
||||||
}
|
}
|
||||||
|
@ -247,8 +233,8 @@ namespace opt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fu_malik::fu_malik(ast_manager& m, opt_solver& s, expr_ref_vector& soft_constraints) {
|
fu_malik::fu_malik(context& c, expr_ref_vector& soft_constraints) {
|
||||||
m_imp = alloc(imp, m, s, soft_constraints);
|
m_imp = alloc(imp, c, soft_constraints);
|
||||||
}
|
}
|
||||||
fu_malik::~fu_malik() {
|
fu_malik::~fu_malik() {
|
||||||
dealloc(m_imp);
|
dealloc(m_imp);
|
||||||
|
@ -281,49 +267,3 @@ namespace opt {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
|
||||||
void quick_explain(expr_ref_vector const& assumptions, expr_ref_vector & literals, bool has_set, expr_set & core) {
|
|
||||||
if (has_set && s().check_sat(assumptions.size(), assumptions.c_ptr()) == l_false) {
|
|
||||||
core.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SASSERT(!literals.empty());
|
|
||||||
if (literals.size() == 1) {
|
|
||||||
core.reset();
|
|
||||||
core.insert(literals[0].get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned mid = literals.size()/2;
|
|
||||||
expr_ref_vector ls1(m), ls2(m);
|
|
||||||
ls1.append(mid, literals.c_ptr());
|
|
||||||
ls2.append(literals.size()-mid, literals.c_ptr() + mid);
|
|
||||||
#if Z3DEBUG
|
|
||||||
expr_ref_vector ls(m);
|
|
||||||
ls.append(ls1);
|
|
||||||
ls.append(ls2);
|
|
||||||
SASSERT(ls.size() == literals.size());
|
|
||||||
for (unsigned i = 0; i < literals.size(); ++i) {
|
|
||||||
SASSERT(ls[i].get() == literals[i].get());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
expr_ref_vector as1(m);
|
|
||||||
as1.append(assumptions);
|
|
||||||
as1.append(ls1);
|
|
||||||
expr_set core2;
|
|
||||||
quick_explain(as1, ls2, !ls1.empty(), core2);
|
|
||||||
|
|
||||||
expr_ref_vector as2(m), cs2(m);
|
|
||||||
as2.append(assumptions);
|
|
||||||
set2vector(core2, cs2);
|
|
||||||
as2.append(cs2);
|
|
||||||
expr_set core1;
|
|
||||||
quick_explain(as2, ls1, !core2.empty(), core1);
|
|
||||||
|
|
||||||
set_union(core1, core2, core);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace opt {
|
||||||
struct imp;
|
struct imp;
|
||||||
imp* m_imp;
|
imp* m_imp;
|
||||||
public:
|
public:
|
||||||
fu_malik(ast_manager& m, opt_solver& s, expr_ref_vector& soft_constraints);
|
fu_malik(context& c, expr_ref_vector& soft_constraints);
|
||||||
virtual ~fu_malik();
|
virtual ~fu_malik();
|
||||||
virtual lbool operator()();
|
virtual lbool operator()();
|
||||||
virtual rational get_lower() const;
|
virtual rational get_lower() const;
|
||||||
|
|
|
@ -40,18 +40,19 @@ class inc_sat_solver : public solver {
|
||||||
expr_ref_vector m_fmls;
|
expr_ref_vector m_fmls;
|
||||||
expr_ref_vector m_current_fmls;
|
expr_ref_vector m_current_fmls;
|
||||||
unsigned_vector m_fmls_lim;
|
unsigned_vector m_fmls_lim;
|
||||||
expr_ref_vector m_core;
|
expr_ref_vector m_core;
|
||||||
atom2bool_var m_map;
|
atom2bool_var m_map;
|
||||||
model_ref m_model;
|
model_ref m_model;
|
||||||
model_converter_ref m_mc;
|
model_converter_ref m_mc;
|
||||||
tactic_ref m_preprocess;
|
tactic_ref m_preprocess;
|
||||||
unsigned m_num_scopes;
|
unsigned m_num_scopes;
|
||||||
sat::literal_vector m_asms;
|
sat::literal_vector m_asms;
|
||||||
goal_ref_buffer m_subgoals;
|
goal_ref_buffer m_subgoals;
|
||||||
proof_converter_ref m_pc;
|
proof_converter_ref m_pc;
|
||||||
model_converter_ref m_mc2;
|
model_converter_ref m_mc2;
|
||||||
expr_dependency_ref m_dep_core;
|
expr_dependency_ref m_dep_core;
|
||||||
|
expr_ref_vector m_soft;
|
||||||
|
vector<rational> m_weights;
|
||||||
|
|
||||||
typedef obj_map<expr, sat::literal> dep2asm_t;
|
typedef obj_map<expr, sat::literal> dep2asm_t;
|
||||||
public:
|
public:
|
||||||
|
@ -59,7 +60,8 @@ public:
|
||||||
m(m), m_solver(p,0), m_params(p),
|
m(m), m_solver(p,0), m_params(p),
|
||||||
m_fmls(m), m_current_fmls(m), m_core(m), m_map(m),
|
m_fmls(m), m_current_fmls(m), m_core(m), m_map(m),
|
||||||
m_num_scopes(0),
|
m_num_scopes(0),
|
||||||
m_dep_core(m) {
|
m_dep_core(m),
|
||||||
|
m_soft(m) {
|
||||||
m_params.set_bool("elim_vars", false);
|
m_params.set_bool("elim_vars", false);
|
||||||
m_solver.updt_params(m_params);
|
m_solver.updt_params(m_params);
|
||||||
params_ref simp2_p = p;
|
params_ref simp2_p = p;
|
||||||
|
@ -79,28 +81,31 @@ public:
|
||||||
mk_bit_blaster_tactic(m),
|
mk_bit_blaster_tactic(m),
|
||||||
mk_aig_tactic(),
|
mk_aig_tactic(),
|
||||||
using_params(mk_simplify_tactic(m), simp2_p));
|
using_params(mk_simplify_tactic(m), simp2_p));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~inc_sat_solver() {}
|
virtual ~inc_sat_solver() {}
|
||||||
|
|
||||||
virtual void set_progress_callback(progress_callback * callback) {
|
virtual void set_progress_callback(progress_callback * callback) {}
|
||||||
}
|
|
||||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
||||||
m_solver.pop_to_base_level();
|
m_solver.pop_to_base_level();
|
||||||
dep2asm_t dep2asm;
|
dep2asm_t dep2asm;
|
||||||
|
|
||||||
m_model = 0;
|
m_model = 0;
|
||||||
lbool r = internalize_formulas();
|
lbool r = internalize_formulas();
|
||||||
if (r != l_true) return r;
|
if (r != l_true) return r;
|
||||||
r = internalize_assumptions(num_assumptions, assumptions, dep2asm);
|
r = internalize_assumptions(num_assumptions, assumptions, dep2asm);
|
||||||
if (r != l_true) return r;
|
if (r != l_true) return r;
|
||||||
extract_assumptions(dep2asm, m_asms);
|
extract_assumptions(dep2asm, m_asms);
|
||||||
|
|
||||||
|
r = initialize_soft_constraints();
|
||||||
|
if (r != l_true) return r;
|
||||||
|
|
||||||
r = m_solver.check(m_asms.size(), m_asms.c_ptr());
|
r = m_solver.check(m_asms.size(), m_asms.c_ptr());
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case l_true:
|
case l_true:
|
||||||
check_assumptions(dep2asm);
|
if (num_assumptions > 0) {
|
||||||
|
check_assumptions(dep2asm);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case l_false:
|
case l_false:
|
||||||
// TBD: expr_dependency core is not accounted for.
|
// TBD: expr_dependency core is not accounted for.
|
||||||
|
@ -161,7 +166,6 @@ public:
|
||||||
m_params.set_bool("elim_vars", false);
|
m_params.set_bool("elim_vars", false);
|
||||||
m_solver.updt_params(m_params);
|
m_solver.updt_params(m_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void collect_statistics(statistics & st) const {
|
virtual void collect_statistics(statistics & st) const {
|
||||||
m_preprocess->collect_statistics(st);
|
m_preprocess->collect_statistics(st);
|
||||||
m_solver.collect_statistics(st);
|
m_solver.collect_statistics(st);
|
||||||
|
@ -186,18 +190,57 @@ public:
|
||||||
virtual void get_labels(svector<symbol> & r) {
|
virtual void get_labels(svector<symbol> & r) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned get_num_assertions() const {
|
virtual unsigned get_num_assertions() const {
|
||||||
return m_fmls.size();
|
return m_fmls.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual expr * get_assertion(unsigned idx) const {
|
virtual expr * get_assertion(unsigned idx) const {
|
||||||
return m_fmls[idx];
|
return m_fmls[idx];
|
||||||
}
|
}
|
||||||
|
void set_soft(unsigned sz, expr*const* soft, rational const* weights) {
|
||||||
|
m_soft.reset();
|
||||||
|
m_weights.reset();
|
||||||
|
m_soft.append(sz, soft);
|
||||||
|
m_weights.append(sz, weights);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
lbool initialize_soft_constraints() {
|
||||||
|
dep2asm_t dep2asm;
|
||||||
|
if (m_soft.empty()) {
|
||||||
|
return l_true;
|
||||||
|
}
|
||||||
|
expr_ref_vector soft(m_soft);
|
||||||
|
for (unsigned i = 0; i < soft.size(); ++i) {
|
||||||
|
expr* e = soft[i].get(), *e1;
|
||||||
|
if (is_uninterp_const(e) || (m.is_not(e, e1) && is_uninterp_const(e1))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
expr_ref asum(m), fml(m);
|
||||||
|
asum = m.mk_fresh_const("soft", m.mk_bool_sort());
|
||||||
|
fml = m.mk_iff(asum, e);
|
||||||
|
m_fmls.push_back(fml);
|
||||||
|
soft[i] = asum;
|
||||||
|
}
|
||||||
|
m_soft.reset();
|
||||||
|
lbool r = internalize_formulas();
|
||||||
|
if (r != l_true) return r;
|
||||||
|
r = internalize_assumptions(soft.size(), soft.c_ptr(), dep2asm);
|
||||||
|
sat::literal_vector lits;
|
||||||
|
svector<double> weights;
|
||||||
|
|
||||||
|
if (r == l_true) {
|
||||||
|
for (unsigned i = 0; i < soft.size(); ++i) {
|
||||||
|
weights.push_back(m_weights[i].get_double());
|
||||||
|
lits.push_back(dep2asm.find(soft[i].get()));
|
||||||
|
}
|
||||||
|
m_solver.initialize_soft(lits.size(), lits.c_ptr(), weights.c_ptr());
|
||||||
|
m_params.set_bool("optimize_model", true);
|
||||||
|
m_solver.updt_params(m_params);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
lbool internalize_goal(goal_ref& g, dep2asm_t& dep2asm) {
|
lbool internalize_goal(goal_ref& g, dep2asm_t& dep2asm) {
|
||||||
m_mc2.reset();
|
m_mc2.reset();
|
||||||
m_pc.reset();
|
m_pc.reset();
|
||||||
|
@ -295,10 +338,8 @@ private:
|
||||||
dep2asm_t::iterator it = dep2asm.begin(), end = dep2asm.end();
|
dep2asm_t::iterator it = dep2asm.begin(), end = dep2asm.end();
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
sat::literal lit = it->m_value;
|
sat::literal lit = it->m_value;
|
||||||
lbool polarity = lit.sign()?l_false:l_true;
|
if (sat::value_at(lit, ll_m) != l_true) {
|
||||||
lbool value = sat::value_at(lit.var(), ll_m);
|
IF_VERBOSE(0, verbose_stream() << mk_pp(it->m_key, m) << " does not evaluate to true\n";
|
||||||
if (value != polarity) {
|
|
||||||
IF_VERBOSE(0, verbose_stream() << mk_pp(it->m_key, m) << " evaluates to " << value << "\n";
|
|
||||||
verbose_stream() << m_asms << "\n";
|
verbose_stream() << m_asms << "\n";
|
||||||
m_solver.display_assignment(verbose_stream());
|
m_solver.display_assignment(verbose_stream());
|
||||||
m_solver.display(verbose_stream()););
|
m_solver.display(verbose_stream()););
|
||||||
|
@ -343,6 +384,12 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
solver* mk_inc_sat_solver(ast_manager& m, params_ref& p) {
|
solver* mk_inc_sat_solver(ast_manager& m, params_ref& p) {
|
||||||
return alloc(inc_sat_solver, m, p);
|
return alloc(inc_sat_solver, m, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_soft_inc_sat(solver* _s, unsigned sz, expr*const* soft, rational const* weights) {
|
||||||
|
inc_sat_solver* s = dynamic_cast<inc_sat_solver*>(_s);
|
||||||
|
s->set_soft(sz, soft, weights);
|
||||||
|
}
|
||||||
|
|
|
@ -24,4 +24,6 @@ Notes:
|
||||||
|
|
||||||
solver* mk_inc_sat_solver(ast_manager& m, params_ref& p);
|
solver* mk_inc_sat_solver(ast_manager& m, params_ref& p);
|
||||||
|
|
||||||
|
void set_soft_inc_sat(solver* s, unsigned sz, expr*const* soft, rational const* weights);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@ Notes:
|
||||||
#include "model_smt2_pp.h"
|
#include "model_smt2_pp.h"
|
||||||
#include "uint_set.h"
|
#include "uint_set.h"
|
||||||
#include "maxhs.h"
|
#include "maxhs.h"
|
||||||
|
#include "opt_context.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
@ -74,8 +75,8 @@ namespace opt {
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
maxhs(opt_solver* s, ast_manager& m, params_ref& p, vector<rational> const& ws, expr_ref_vector const& soft):
|
maxhs(context& c, vector<rational> const& ws, expr_ref_vector const& soft):
|
||||||
maxsmt_solver_base(s, m, p, ws, soft),
|
maxsmt_solver_base(c, ws, soft),
|
||||||
m_aux(m),
|
m_aux(m),
|
||||||
m_at_lower_bound(false) {
|
m_at_lower_bound(false) {
|
||||||
}
|
}
|
||||||
|
@ -528,7 +529,7 @@ namespace opt {
|
||||||
app_ref mk_fresh(sort* s) {
|
app_ref mk_fresh(sort* s) {
|
||||||
app_ref r(m);
|
app_ref r(m);
|
||||||
r = m.mk_fresh_const("r", s);
|
r = m.mk_fresh_const("r", s);
|
||||||
m_mc->insert(r->get_decl());
|
m_c.fm().insert(r->get_decl());
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,9 +554,9 @@ namespace opt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
maxsmt_solver_base* opt::mk_maxhs(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* opt::mk_maxhs(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(maxhs, s, m, p, ws, soft);
|
return alloc(maxhs, c, ws, soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ Notes:
|
||||||
#include "maxsmt.h"
|
#include "maxsmt.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
maxsmt_solver_base* mk_maxhs(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* mk_maxhs(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -60,6 +60,7 @@ Notes:
|
||||||
#include "mus.h"
|
#include "mus.h"
|
||||||
#include "mss.h"
|
#include "mss.h"
|
||||||
#include "inc_sat_solver.h"
|
#include "inc_sat_solver.h"
|
||||||
|
#include "opt_context.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace opt;
|
using namespace opt;
|
||||||
|
@ -83,10 +84,10 @@ private:
|
||||||
rational m_max_upper;
|
rational m_max_upper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
maxres(ast_manager& m, opt_solver* s, params_ref& p,
|
maxres(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft,
|
vector<rational> const& ws, expr_ref_vector const& soft,
|
||||||
strategy_t st):
|
strategy_t st):
|
||||||
maxsmt_solver_base(s, m, p, ws, soft),
|
maxsmt_solver_base(c, ws, soft),
|
||||||
m_B(m), m_asms(m),
|
m_B(m), m_asms(m),
|
||||||
m_mus(m_s, m),
|
m_mus(m_s, m),
|
||||||
m_mss(m_s, m),
|
m_mss(m_s, m),
|
||||||
|
@ -133,10 +134,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool mus_solver() {
|
lbool mus_solver() {
|
||||||
solver::scoped_push _sc(*m_s.get());
|
solver::scoped_push _sc(m_s);
|
||||||
init();
|
init();
|
||||||
init_local();
|
init_local();
|
||||||
enable_bvsat();
|
|
||||||
while (true) {
|
while (true) {
|
||||||
TRACE("opt",
|
TRACE("opt",
|
||||||
display_vec(tout, m_asms.size(), m_asms.c_ptr());
|
display_vec(tout, m_asms.size(), m_asms.c_ptr());
|
||||||
|
@ -159,7 +159,6 @@ public:
|
||||||
});
|
});
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
VERIFY(m_model->eval(m_soft[i].get(), tmp));
|
VERIFY(m_model->eval(m_soft[i].get(), tmp));
|
||||||
std::cout << mk_pp(m_soft[i].get(), m) << " -> " << tmp << "\n";
|
|
||||||
m_assignment[i] = m.is_true(tmp);
|
m_assignment[i] = m.is_true(tmp);
|
||||||
}
|
}
|
||||||
m_upper = m_lower;
|
m_upper = m_lower;
|
||||||
|
@ -179,11 +178,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool mus_mss_solver() {
|
lbool mus_mss_solver() {
|
||||||
solver::scoped_push _sc(*m_s.get());
|
solver::scoped_push _sc(s());
|
||||||
init();
|
init();
|
||||||
init_local();
|
init_local();
|
||||||
enable_bvsat();
|
enable_sls(m_asms);
|
||||||
enable_sls();
|
|
||||||
ptr_vector<expr> mcs;
|
ptr_vector<expr> mcs;
|
||||||
vector<ptr_vector<expr> > cores;
|
vector<ptr_vector<expr> > cores;
|
||||||
while (m_lower < m_upper) {
|
while (m_lower < m_upper) {
|
||||||
|
@ -222,11 +220,32 @@ public:
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lbool mss_solver() {
|
lbool mss_solver() {
|
||||||
NOT_IMPLEMENTED_YET();
|
NOT_IMPLEMENTED_YET();
|
||||||
return l_undef;
|
solver::scoped_push _sc(s());
|
||||||
|
init();
|
||||||
|
init_local();
|
||||||
|
ptr_vector<expr> mcs;
|
||||||
|
while (m_lower < m_upper) {
|
||||||
|
lbool is_sat = s().check_sat(0, 0);
|
||||||
|
// is_sat = get_mcs(mcs);
|
||||||
|
switch (is_sat) {
|
||||||
|
case l_undef:
|
||||||
|
return l_undef;
|
||||||
|
case l_false:
|
||||||
|
m_lower = m_upper;
|
||||||
|
break;
|
||||||
|
case l_true:
|
||||||
|
//
|
||||||
|
is_sat = process_sat(mcs);
|
||||||
|
if (is_sat != l_true) {
|
||||||
|
return is_sat;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_lower = m_upper;
|
||||||
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool operator()() {
|
lbool operator()() {
|
||||||
|
@ -322,7 +341,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool minimize_core(ptr_vector<expr>& core) {
|
lbool minimize_core(ptr_vector<expr>& core) {
|
||||||
if (m_sat_enabled) {
|
if (m_c.sat_enabled()) {
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
m_mus.reset();
|
m_mus.reset();
|
||||||
|
@ -593,8 +612,8 @@ public:
|
||||||
void verify_assignment() {
|
void verify_assignment() {
|
||||||
IF_VERBOSE(0, verbose_stream() << "verify assignment\n";);
|
IF_VERBOSE(0, verbose_stream() << "verify assignment\n";);
|
||||||
ref<solver> sat_solver = mk_inc_sat_solver(m, m_params);
|
ref<solver> sat_solver = mk_inc_sat_solver(m, m_params);
|
||||||
for (unsigned i = 0; i < m_assertions.size(); ++i) {
|
for (unsigned i = 0; i < s().get_num_assertions(); ++i) {
|
||||||
sat_solver->assert_expr(m_assertions[i].get());
|
sat_solver->assert_expr(s().get_assertion(i));
|
||||||
}
|
}
|
||||||
expr_ref n(m);
|
expr_ref n(m);
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
|
@ -612,18 +631,18 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
opt::maxsmt_solver_base* opt::mk_maxres(ast_manager& m, opt_solver* s, params_ref& p,
|
opt::maxsmt_solver_base* opt::mk_maxres(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(maxres, m, s, p, ws, soft, maxres::s_mus);
|
return alloc(maxres, c, ws, soft, maxres::s_mus);
|
||||||
}
|
}
|
||||||
|
|
||||||
opt::maxsmt_solver_base* opt::mk_mus_mss_maxres(ast_manager& m, opt_solver* s, params_ref& p,
|
opt::maxsmt_solver_base* opt::mk_mus_mss_maxres(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(maxres, m, s, p, ws, soft, maxres::s_mus_mss);
|
return alloc(maxres, c, ws, soft, maxres::s_mus_mss);
|
||||||
}
|
}
|
||||||
|
|
||||||
opt::maxsmt_solver_base* opt::mk_mss_maxres(ast_manager& m, opt_solver* s, params_ref& p,
|
opt::maxsmt_solver_base* opt::mk_mss_maxres(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(maxres, m, s, p, ws, soft, maxres::s_mss);
|
return alloc(maxres, c, ws, soft, maxres::s_mss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,15 @@ Notes:
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
maxsmt_solver_base* mk_maxres(
|
maxsmt_solver_base* mk_maxres(
|
||||||
ast_manager& m, opt_solver* s, params_ref& p,
|
context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
|
|
||||||
maxsmt_solver_base* mk_mus_mss_maxres(
|
maxsmt_solver_base* mk_mus_mss_maxres(
|
||||||
ast_manager& m, opt_solver* s, params_ref& p,
|
context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
|
|
||||||
maxsmt_solver_base* mk_mss_maxres(
|
maxsmt_solver_base* mk_mss_maxres(
|
||||||
ast_manager& m, opt_solver* s, params_ref& p,
|
context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,16 +26,14 @@ namespace opt {
|
||||||
|
|
||||||
class sls : public maxsmt_solver_base {
|
class sls : public maxsmt_solver_base {
|
||||||
public:
|
public:
|
||||||
sls(opt_solver* s, ast_manager& m, params_ref& p,
|
sls(context& c, vector<rational> const& ws, expr_ref_vector const& soft):
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft):
|
maxsmt_solver_base(c, ws, soft) {
|
||||||
maxsmt_solver_base(s, m, p, ws, soft) {
|
|
||||||
}
|
}
|
||||||
virtual ~sls() {}
|
virtual ~sls() {}
|
||||||
lbool operator()() {
|
lbool operator()() {
|
||||||
IF_VERBOSE(1, verbose_stream() << "(opt.sls)\n";);
|
IF_VERBOSE(1, verbose_stream() << "(opt.sls)\n";);
|
||||||
enable_bvsat();
|
|
||||||
enable_sls();
|
|
||||||
init();
|
init();
|
||||||
|
enable_sls(m_soft);
|
||||||
lbool is_sat = s().check_sat(0, 0);
|
lbool is_sat = s().check_sat(0, 0);
|
||||||
if (is_sat == l_true) {
|
if (is_sat == l_true) {
|
||||||
s().get_model(m_model);
|
s().get_model(m_model);
|
||||||
|
@ -54,9 +52,9 @@ namespace opt {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
maxsmt_solver_base* opt::mk_sls(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* opt::mk_sls(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(sls, s, m, p, ws, soft);
|
return alloc(sls, c, ws, soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ Notes:
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
|
||||||
maxsmt_solver_base* mk_sls(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* mk_sls(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,10 @@ Notes:
|
||||||
#include "maxres.h"
|
#include "maxres.h"
|
||||||
#include "maxhs.h"
|
#include "maxhs.h"
|
||||||
#include "bcd2.h"
|
#include "bcd2.h"
|
||||||
#include "wpm2.h"
|
|
||||||
#include "pbmax.h"
|
#include "pbmax.h"
|
||||||
#include "wmax.h"
|
#include "wmax.h"
|
||||||
#include "maxsls.h"
|
#include "maxsls.h"
|
||||||
#include "ast_pp.h"
|
#include "ast_pp.h"
|
||||||
#include "opt_params.hpp"
|
|
||||||
#include "pb_decl_plugin.h"
|
#include "pb_decl_plugin.h"
|
||||||
#include "pb_sls.h"
|
#include "pb_sls.h"
|
||||||
#include "tactical.h"
|
#include "tactical.h"
|
||||||
|
@ -38,19 +36,27 @@ Notes:
|
||||||
#include "qfbv_tactic.h"
|
#include "qfbv_tactic.h"
|
||||||
#include "card2bv_tactic.h"
|
#include "card2bv_tactic.h"
|
||||||
#include "uint_set.h"
|
#include "uint_set.h"
|
||||||
#include "opt_sls_solver.h"
|
|
||||||
#include "pb_preprocess_tactic.h"
|
#include "pb_preprocess_tactic.h"
|
||||||
#include "inc_sat_solver.h"
|
#include "opt_context.h"
|
||||||
|
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
maxsmt_solver_base::maxsmt_solver_base(
|
||||||
|
context& c, vector<rational> const& ws, expr_ref_vector const& soft):
|
||||||
|
m_s(c.get_solver()),
|
||||||
|
m(c.get_manager()),
|
||||||
|
m_c(c),
|
||||||
|
m_cancel(false), m_soft(m),
|
||||||
|
m_assertions(m) {
|
||||||
|
m_s.get_model(m_model);
|
||||||
|
SASSERT(m_model);
|
||||||
|
updt_params(c.params());
|
||||||
|
init_soft(ws, soft);
|
||||||
|
}
|
||||||
|
|
||||||
void maxsmt_solver_base::updt_params(params_ref& p) {
|
void maxsmt_solver_base::updt_params(params_ref& p) {
|
||||||
m_params.copy(p);
|
m_params.copy(p);
|
||||||
s().updt_params(p);
|
|
||||||
opt_params _p(p);
|
|
||||||
m_enable_sat = _p.enable_sat();
|
|
||||||
m_enable_sls = _p.enable_sls();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxsmt_solver_base::init_soft(vector<rational> const& weights, expr_ref_vector const& soft) {
|
void maxsmt_solver_base::init_soft(vector<rational> const& weights, expr_ref_vector const& soft) {
|
||||||
|
@ -90,132 +96,68 @@ namespace opt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct maxsmt_solver_base::is_bv {
|
|
||||||
struct found {};
|
|
||||||
ast_manager& m;
|
|
||||||
pb_util pb;
|
|
||||||
bv_util bv;
|
|
||||||
is_bv(ast_manager& m): m(m), pb(m), bv(m) {}
|
|
||||||
void operator()(var *) { throw found(); }
|
|
||||||
void operator()(quantifier *) { throw found(); }
|
|
||||||
void operator()(app *n) {
|
|
||||||
family_id fid = n->get_family_id();
|
|
||||||
if (fid != m.get_basic_family_id() &&
|
|
||||||
fid != pb.get_family_id() &&
|
|
||||||
fid != bv.get_family_id() &&
|
|
||||||
!is_uninterp_const(n)) {
|
|
||||||
throw found();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool maxsmt_solver_base::probe_bv() {
|
|
||||||
expr_fast_mark1 visited;
|
|
||||||
is_bv proc(m);
|
|
||||||
try {
|
|
||||||
unsigned sz = s().get_num_assertions();
|
|
||||||
for (unsigned i = 0; i < sz; i++) {
|
|
||||||
quick_for_each_expr(proc, visited, s().get_assertion(i));
|
|
||||||
}
|
|
||||||
sz = m_soft.size();
|
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
|
||||||
quick_for_each_expr(proc, visited, m_soft[i].get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (is_bv::found) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void maxsmt_solver_base::enable_inc_bvsat() {
|
|
||||||
m_params.set_bool("minimize_core", true);
|
|
||||||
solver* sat_solver = mk_inc_sat_solver(m, m_params);
|
|
||||||
unsigned sz = s().get_num_assertions();
|
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
|
||||||
sat_solver->assert_expr(s().get_assertion(i));
|
|
||||||
m_assertions.push_back(s().get_assertion(i));
|
|
||||||
}
|
|
||||||
m_s = sat_solver;
|
|
||||||
}
|
|
||||||
|
|
||||||
void maxsmt_solver_base::enable_bvsat() {
|
|
||||||
if (m_enable_sat && !m_sat_enabled && probe_bv()) {
|
|
||||||
enable_inc_bvsat();
|
|
||||||
m_sat_enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void maxsmt_solver_base::enable_sls() {
|
|
||||||
if (m_enable_sls && !m_sls_enabled && probe_bv()) {
|
|
||||||
m_params.set_uint("restarts", 20);
|
|
||||||
unsigned lvl = m_s->get_scope_level();
|
|
||||||
sls_solver* sls = alloc(sls_solver, m, m_s.get(), m_soft, m_weights, m_params);
|
|
||||||
m_s = sls;
|
|
||||||
while (lvl > 0) { m_s->push(); --lvl; }
|
|
||||||
m_sls_enabled = true;
|
|
||||||
sls->opt(m_model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void maxsmt_solver_base::set_mus(bool f) {
|
void maxsmt_solver_base::set_mus(bool f) {
|
||||||
params_ref p;
|
params_ref p;
|
||||||
p.set_bool("minimize_core", f);
|
p.set_bool("minimize_core", f);
|
||||||
m_s->updt_params(p);
|
m_s.updt_params(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void maxsmt_solver_base::enable_sls(expr_ref_vector const& soft) {
|
||||||
|
m_c.enable_sls(soft, m_weights);
|
||||||
}
|
}
|
||||||
|
|
||||||
app* maxsmt_solver_base::mk_fresh_bool(char const* name) {
|
app* maxsmt_solver_base::mk_fresh_bool(char const* name) {
|
||||||
app* result = m.mk_fresh_const(name, m.mk_bool_sort());
|
app* result = m.mk_fresh_const(name, m.mk_bool_sort());
|
||||||
m_mc->insert(result->get_decl());
|
m_c.fm().insert(result->get_decl());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxsmt::maxsmt(context& c):
|
||||||
|
m_s(c.get_solver()), m(c.get_manager()), m_c(c), m_cancel(false),
|
||||||
|
m_soft_constraints(m), m_answer(m) {}
|
||||||
|
|
||||||
lbool maxsmt::operator()(opt_solver* s) {
|
lbool maxsmt::operator()(solver* s) {
|
||||||
lbool is_sat;
|
lbool is_sat;
|
||||||
m_msolver = 0;
|
m_msolver = 0;
|
||||||
m_s = s;
|
symbol const& maxsat_engine = m_c.maxsat_engine();
|
||||||
IF_VERBOSE(1, verbose_stream() << "(maxsmt)\n";);
|
IF_VERBOSE(1, verbose_stream() << "(maxsmt)\n";);
|
||||||
TRACE("opt", tout << "maxsmt\n";);
|
TRACE("opt", tout << "maxsmt\n";);
|
||||||
if (m_soft_constraints.empty()) {
|
if (m_soft_constraints.empty()) {
|
||||||
TRACE("opt", tout << "no constraints\n";);
|
TRACE("opt", tout << "no constraints\n";);
|
||||||
m_msolver = 0;
|
m_msolver = 0;
|
||||||
is_sat = m_s->check_sat(0, 0);
|
is_sat = m_s.check_sat(0, 0);
|
||||||
}
|
}
|
||||||
else if (m_maxsat_engine == symbol("maxres")) {
|
else if (maxsat_engine == symbol("maxres")) {
|
||||||
m_msolver = mk_maxres(m, s, m_params, m_weights, m_soft_constraints);
|
m_msolver = mk_maxres(m_c, m_weights, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (m_maxsat_engine == symbol("mus-mss-maxres")) {
|
else if (maxsat_engine == symbol("mus-mss-maxres")) {
|
||||||
m_msolver = mk_mus_mss_maxres(m, s, m_params, m_weights, m_soft_constraints);
|
m_msolver = mk_mus_mss_maxres(m_c, m_weights, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (m_maxsat_engine == symbol("pbmax")) {
|
else if (maxsat_engine == symbol("pbmax")) {
|
||||||
m_msolver = mk_pbmax(m, s, m_params, m_weights, m_soft_constraints);
|
m_msolver = mk_pbmax(m_c, m_weights, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (m_maxsat_engine == symbol("wpm2")) {
|
else if (maxsat_engine == symbol("bcd2")) {
|
||||||
m_msolver = mk_wpm2(m, s, m_params, m_weights, m_soft_constraints);
|
m_msolver = mk_bcd2(m_c, m_weights, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (m_maxsat_engine == symbol("bcd2")) {
|
else if (maxsat_engine == symbol("maxhs")) {
|
||||||
m_msolver = mk_bcd2(m, s, m_params, m_weights, m_soft_constraints);
|
m_msolver = mk_maxhs(m_c, m_weights, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (m_maxsat_engine == symbol("maxhs")) {
|
else if (maxsat_engine == symbol("sls")) {
|
||||||
m_msolver = mk_maxhs(m, s, m_params, m_weights, m_soft_constraints);
|
|
||||||
}
|
|
||||||
else if (m_maxsat_engine == symbol("sls")) {
|
|
||||||
// NB: this is experimental one-round version of SLS
|
// NB: this is experimental one-round version of SLS
|
||||||
m_msolver = mk_sls(m, s, m_params, m_weights, m_soft_constraints);
|
m_msolver = mk_sls(m_c, m_weights, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (is_maxsat_problem(m_weights) && m_maxsat_engine == symbol("core_maxsat")) {
|
else if (is_maxsat_problem(m_weights) && maxsat_engine == symbol("core_maxsat")) {
|
||||||
m_msolver = alloc(core_maxsat, m, *m_s, m_soft_constraints);
|
m_msolver = alloc(core_maxsat, m_c, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else if (is_maxsat_problem(m_weights) && m_maxsat_engine == symbol("fu_malik")) {
|
else if (is_maxsat_problem(m_weights) && maxsat_engine == symbol("fu_malik")) {
|
||||||
m_msolver = alloc(fu_malik, m, *m_s, m_soft_constraints);
|
m_msolver = alloc(fu_malik, m_c, m_soft_constraints);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (m_maxsat_engine != symbol::null && m_maxsat_engine != symbol("wmax")) {
|
if (maxsat_engine != symbol::null && maxsat_engine != symbol("wmax")) {
|
||||||
warning_msg("solver %s is not recognized, using default 'wmax'",
|
warning_msg("solver %s is not recognized, using default 'wmax'",
|
||||||
m_maxsat_engine.str().c_str());
|
maxsat_engine.str().c_str());
|
||||||
}
|
}
|
||||||
m_msolver = mk_wmax(m, m_s.get(), m_params, m_weights, m_soft_constraints);
|
m_msolver = mk_wmax(m_c, m_weights, m_soft_constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_msolver) {
|
if (m_msolver) {
|
||||||
|
@ -242,13 +184,12 @@ namespace opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxsmt::verify_assignment() {
|
void maxsmt::verify_assignment() {
|
||||||
m_s->push();
|
solver::scoped_push _sp(m_s);
|
||||||
commit_assignment();
|
commit_assignment();
|
||||||
if (l_true != m_s->check_sat(0,0)) {
|
if (l_true != m_s.check_sat(0,0)) {
|
||||||
IF_VERBOSE(0, verbose_stream() << "could not verify assignment\n";);
|
IF_VERBOSE(0, verbose_stream() << "could not verify assignment\n";);
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
m_s->pop(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool maxsmt::get_assignment(unsigned idx) const {
|
bool maxsmt::get_assignment(unsigned idx) const {
|
||||||
|
@ -292,7 +233,6 @@ namespace opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxsmt::commit_assignment() {
|
void maxsmt::commit_assignment() {
|
||||||
SASSERT(m_s);
|
|
||||||
for (unsigned i = 0; i < m_soft_constraints.size(); ++i) {
|
for (unsigned i = 0; i < m_soft_constraints.size(); ++i) {
|
||||||
expr_ref tmp(m);
|
expr_ref tmp(m);
|
||||||
tmp = m_soft_constraints[i].get();
|
tmp = m_soft_constraints[i].get();
|
||||||
|
@ -300,7 +240,7 @@ namespace opt {
|
||||||
tmp = m.mk_not(tmp);
|
tmp = m.mk_not(tmp);
|
||||||
}
|
}
|
||||||
TRACE("opt", tout << "committing: " << tmp << "\n";);
|
TRACE("opt", tout << "committing: " << tmp << "\n";);
|
||||||
m_s->assert_expr(tmp);
|
m_s.assert_expr(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,9 +277,7 @@ namespace opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxsmt::updt_params(params_ref& p) {
|
void maxsmt::updt_params(params_ref& p) {
|
||||||
opt_params _p(p);
|
m_params.append(p);
|
||||||
m_maxsat_engine = _p.maxsat_engine();
|
|
||||||
m_params = p;
|
|
||||||
if (m_msolver) {
|
if (m_msolver) {
|
||||||
m_msolver->updt_params(p);
|
m_msolver->updt_params(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,16 @@ Notes:
|
||||||
#ifndef _OPT_MAXSMT_H_
|
#ifndef _OPT_MAXSMT_H_
|
||||||
#define _OPT_MAXSMT_H_
|
#define _OPT_MAXSMT_H_
|
||||||
|
|
||||||
#include "opt_solver.h"
|
#include"ast.h"
|
||||||
#include "statistics.h"
|
#include"params.h"
|
||||||
|
#include"solver.h"
|
||||||
|
#include"filter_model_converter.h"
|
||||||
|
#include"statistics.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
class context;
|
||||||
|
|
||||||
class maxsmt_solver {
|
class maxsmt_solver {
|
||||||
public:
|
public:
|
||||||
virtual ~maxsmt_solver() {}
|
virtual ~maxsmt_solver() {}
|
||||||
|
@ -44,8 +49,9 @@ namespace opt {
|
||||||
//
|
//
|
||||||
class maxsmt_solver_base : public maxsmt_solver {
|
class maxsmt_solver_base : public maxsmt_solver {
|
||||||
protected:
|
protected:
|
||||||
ref<solver> m_s;
|
solver& m_s;
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
|
context& m_c;
|
||||||
volatile bool m_cancel;
|
volatile bool m_cancel;
|
||||||
expr_ref_vector m_soft;
|
expr_ref_vector m_soft;
|
||||||
expr_ref_vector m_assertions;
|
expr_ref_vector m_assertions;
|
||||||
|
@ -53,55 +59,30 @@ namespace opt {
|
||||||
rational m_lower;
|
rational m_lower;
|
||||||
rational m_upper;
|
rational m_upper;
|
||||||
model_ref m_model;
|
model_ref m_model;
|
||||||
ref<filter_model_converter> m_mc; // model converter to remove fresh variables
|
|
||||||
svector<bool> m_assignment; // truth assignment to soft constraints
|
svector<bool> m_assignment; // truth assignment to soft constraints
|
||||||
params_ref m_params; // config
|
params_ref m_params; // config
|
||||||
bool m_enable_sls; // config
|
|
||||||
bool m_enable_sat; // config
|
|
||||||
bool m_sls_enabled;
|
|
||||||
bool m_sat_enabled;
|
|
||||||
struct is_bv;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
maxsmt_solver_base(opt_solver* s, ast_manager& m, params_ref& p,
|
maxsmt_solver_base(context& c, vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft):
|
|
||||||
m_s(s), m(m), m_cancel(false), m_soft(m),
|
|
||||||
m_assertions(m),
|
|
||||||
m_enable_sls(false), m_enable_sat(false),
|
|
||||||
m_sls_enabled(false), m_sat_enabled(false) {
|
|
||||||
m_s->get_model(m_model);
|
|
||||||
SASSERT(m_model);
|
|
||||||
updt_params(p);
|
|
||||||
set_converter(s->mc_ref().get());
|
|
||||||
init_soft(ws, soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~maxsmt_solver_base() {}
|
virtual ~maxsmt_solver_base() {}
|
||||||
virtual rational get_lower() const { return m_lower; }
|
virtual rational get_lower() const { return m_lower; }
|
||||||
virtual rational get_upper() const { return m_upper; }
|
virtual rational get_upper() const { return m_upper; }
|
||||||
virtual bool get_assignment(unsigned index) const { return m_assignment[index]; }
|
virtual bool get_assignment(unsigned index) const { return m_assignment[index]; }
|
||||||
virtual void set_cancel(bool f) { m_cancel = f; m_s->set_cancel(f); }
|
virtual void set_cancel(bool f) { m_cancel = f; s().set_cancel(f); }
|
||||||
virtual void collect_statistics(statistics& st) const {
|
virtual void collect_statistics(statistics& st) const { }
|
||||||
if (m_sls_enabled || m_sat_enabled) {
|
|
||||||
m_s->collect_statistics(st);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual void get_model(model_ref& mdl) { mdl = m_model.get(); }
|
virtual void get_model(model_ref& mdl) { mdl = m_model.get(); }
|
||||||
void set_model() { s().get_model(m_model); }
|
void set_model() { s().get_model(m_model); }
|
||||||
virtual void updt_params(params_ref& p);
|
virtual void updt_params(params_ref& p);
|
||||||
virtual void init_soft(vector<rational> const& weights, expr_ref_vector const& soft);
|
virtual void init_soft(vector<rational> const& weights, expr_ref_vector const& soft);
|
||||||
void add_hard(expr* e){ s().assert_expr(e); }
|
void add_hard(expr* e){ s().assert_expr(e); }
|
||||||
solver& s() { return *m_s; }
|
solver& s() { return m_s; }
|
||||||
void set_converter(filter_model_converter* mc) { m_mc = mc; }
|
|
||||||
void init();
|
void init();
|
||||||
expr* mk_not(expr* e);
|
expr* mk_not(expr* e);
|
||||||
bool probe_bv();
|
|
||||||
void set_mus(bool f);
|
void set_mus(bool f);
|
||||||
void enable_bvsat();
|
|
||||||
void enable_sls();
|
|
||||||
app* mk_fresh_bool(char const* name);
|
app* mk_fresh_bool(char const* name);
|
||||||
private:
|
protected:
|
||||||
void enable_inc_bvsat();
|
void enable_sls(expr_ref_vector const& soft);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,32 +91,27 @@ namespace opt {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class maxsmt {
|
class maxsmt {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
ref<opt_solver> m_s;
|
solver& m_s;
|
||||||
|
context& m_c;
|
||||||
|
scoped_ptr<maxsmt_solver> m_msolver;
|
||||||
volatile bool m_cancel;
|
volatile bool m_cancel;
|
||||||
expr_ref_vector m_soft_constraints;
|
expr_ref_vector m_soft_constraints;
|
||||||
expr_ref_vector m_answer;
|
expr_ref_vector m_answer;
|
||||||
vector<rational> m_weights;
|
vector<rational> m_weights;
|
||||||
rational m_lower;
|
rational m_lower;
|
||||||
rational m_upper;
|
rational m_upper;
|
||||||
scoped_ptr<maxsmt_solver> m_msolver;
|
|
||||||
symbol m_maxsat_engine;
|
|
||||||
model_ref m_model;
|
model_ref m_model;
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
public:
|
public:
|
||||||
maxsmt(ast_manager& m): m(m), m_s(0), m_cancel(false), m_soft_constraints(m), m_answer(m) {}
|
maxsmt(context& c);
|
||||||
|
lbool operator()(solver* s);
|
||||||
lbool operator()(opt_solver* s);
|
|
||||||
|
|
||||||
void set_cancel(bool f);
|
void set_cancel(bool f);
|
||||||
|
|
||||||
void updt_params(params_ref& p);
|
void updt_params(params_ref& p);
|
||||||
|
|
||||||
void add(expr* f, rational const& w);
|
void add(expr* f, rational const& w);
|
||||||
unsigned size() const { return m_soft_constraints.size(); }
|
unsigned size() const { return m_soft_constraints.size(); }
|
||||||
expr* operator[](unsigned idx) const { return m_soft_constraints[idx]; }
|
expr* operator[](unsigned idx) const { return m_soft_constraints[idx]; }
|
||||||
rational weight(unsigned idx) const { return m_weights[idx]; }
|
rational weight(unsigned idx) const { return m_weights[idx]; }
|
||||||
|
|
||||||
void commit_assignment();
|
void commit_assignment();
|
||||||
rational get_value() const;
|
rational get_value() const;
|
||||||
rational get_lower() const;
|
rational get_lower() const;
|
||||||
|
@ -146,13 +122,9 @@ namespace opt {
|
||||||
bool get_assignment(unsigned index) const;
|
bool get_assignment(unsigned index) const;
|
||||||
void display_answer(std::ostream& out) const;
|
void display_answer(std::ostream& out) const;
|
||||||
void collect_statistics(statistics& st) const;
|
void collect_statistics(statistics& st) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool is_maxsat_problem(vector<rational> const& ws) const;
|
bool is_maxsat_problem(vector<rational> const& ws) const;
|
||||||
|
|
||||||
void verify_assignment();
|
void verify_assignment();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,21 +26,21 @@ Notes:
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
|
||||||
mss::mss(ref<solver>& s, ast_manager& m): m_s(s), m(m), m_cancel(false) {
|
mss::mss(solver& s, ast_manager& m): m_s(s), m(m), m_cancel(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mss::~mss() {
|
mss::~mss() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mss::check_result() {
|
bool mss::check_result() {
|
||||||
lbool is_sat = m_s->check_sat(m_mss.size(), m_mss.c_ptr());
|
lbool is_sat = m_s.check_sat(m_mss.size(), m_mss.c_ptr());
|
||||||
if (is_sat == l_undef) return true;
|
if (is_sat == l_undef) return true;
|
||||||
SASSERT(is_sat == l_true);
|
SASSERT(is_sat == l_true);
|
||||||
if (is_sat == l_false) return false;
|
if (is_sat == l_false) return false;
|
||||||
expr_set::iterator it = m_mcs.begin(), end = m_mcs.end();
|
expr_set::iterator it = m_mcs.begin(), end = m_mcs.end();
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
m_mss.push_back(*it);
|
m_mss.push_back(*it);
|
||||||
is_sat = m_s->check_sat(m_mss.size(), m_mss.c_ptr());
|
is_sat = m_s.check_sat(m_mss.size(), m_mss.c_ptr());
|
||||||
m_mss.pop_back();
|
m_mss.pop_back();
|
||||||
if (is_sat == l_undef) return true;
|
if (is_sat == l_undef) return true;
|
||||||
SASSERT(is_sat == l_false);
|
SASSERT(is_sat == l_false);
|
||||||
|
@ -147,7 +147,7 @@ namespace opt {
|
||||||
lbool mss::operator()(vector<exprs> const& _cores, exprs& literals, exprs& mcs) {
|
lbool mss::operator()(vector<exprs> const& _cores, exprs& literals, exprs& mcs) {
|
||||||
m_mss.reset();
|
m_mss.reset();
|
||||||
m_todo.reset();
|
m_todo.reset();
|
||||||
m_s->get_model(m_model);
|
m_s.get_model(m_model);
|
||||||
SASSERT(m_model);
|
SASSERT(m_model);
|
||||||
vector<exprs> cores(_cores);
|
vector<exprs> cores(_cores);
|
||||||
TRACE("opt",
|
TRACE("opt",
|
||||||
|
@ -207,12 +207,12 @@ namespace opt {
|
||||||
TRACE("opt", display_vec(tout << "process (total " << core.size() << ") :", sz, core.c_ptr()););
|
TRACE("opt", display_vec(tout << "process (total " << core.size() << ") :", sz, core.c_ptr()););
|
||||||
unsigned sz_save = m_mss.size();
|
unsigned sz_save = m_mss.size();
|
||||||
m_mss.append(sz, core.c_ptr());
|
m_mss.append(sz, core.c_ptr());
|
||||||
lbool is_sat = m_s->check_sat(m_mss.size(), m_mss.c_ptr());
|
lbool is_sat = m_s.check_sat(m_mss.size(), m_mss.c_ptr());
|
||||||
IF_VERBOSE(1, display_vec(verbose_stream(), sz, core.c_ptr()););
|
IF_VERBOSE(2, display_vec(verbose_stream() << "mss: ", m_mss.size(), m_mss.c_ptr()););
|
||||||
m_mss.resize(sz_save);
|
m_mss.resize(sz_save);
|
||||||
switch (is_sat) {
|
switch (is_sat) {
|
||||||
case l_true:
|
case l_true:
|
||||||
m_s->get_model(m_model);
|
m_s.get_model(m_model);
|
||||||
update_mss();
|
update_mss();
|
||||||
DEBUG_CODE(
|
DEBUG_CODE(
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ Notes:
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
class mss {
|
class mss {
|
||||||
ref<solver>& m_s;
|
solver& m_s;
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
volatile bool m_cancel;
|
volatile bool m_cancel;
|
||||||
typedef ptr_vector<expr> exprs;
|
typedef ptr_vector<expr> exprs;
|
||||||
|
@ -32,7 +32,7 @@ namespace opt {
|
||||||
exprs m_todo;
|
exprs m_todo;
|
||||||
model_ref m_model;
|
model_ref m_model;
|
||||||
public:
|
public:
|
||||||
mss(ref<solver>& s, ast_manager& m);
|
mss(solver& s, ast_manager& m);
|
||||||
~mss();
|
~mss();
|
||||||
|
|
||||||
lbool operator()(vector<exprs> const& cores, exprs& literals, exprs& mcs);
|
lbool operator()(vector<exprs> const& cores, exprs& literals, exprs& mcs);
|
||||||
|
|
|
@ -29,13 +29,13 @@ using namespace opt;
|
||||||
//
|
//
|
||||||
|
|
||||||
struct mus::imp {
|
struct mus::imp {
|
||||||
ref<solver>& m_s;
|
solver& m_s;
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
expr_ref_vector m_cls2expr;
|
expr_ref_vector m_cls2expr;
|
||||||
obj_map<expr, unsigned> m_expr2cls;
|
obj_map<expr, unsigned> m_expr2cls;
|
||||||
volatile bool m_cancel;
|
volatile bool m_cancel;
|
||||||
|
|
||||||
imp(ref<solver>& s, ast_manager& m):
|
imp(solver& s, ast_manager& m):
|
||||||
m_s(s), m(m), m_cls2expr(m), m_cancel(false)
|
m_s(s), m(m), m_cls2expr(m), m_cancel(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ struct mus::imp {
|
||||||
unsigned sz = assumptions.size();
|
unsigned sz = assumptions.size();
|
||||||
assumptions.push_back(not_cls);
|
assumptions.push_back(not_cls);
|
||||||
add_core(core, assumptions);
|
add_core(core, assumptions);
|
||||||
lbool is_sat = m_s->check_sat(assumptions.size(), assumptions.c_ptr());
|
lbool is_sat = m_s.check_sat(assumptions.size(), assumptions.c_ptr());
|
||||||
assumptions.resize(sz);
|
assumptions.resize(sz);
|
||||||
switch (is_sat) {
|
switch (is_sat) {
|
||||||
case l_undef:
|
case l_undef:
|
||||||
|
@ -103,7 +103,7 @@ struct mus::imp {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
core_exprs.reset();
|
core_exprs.reset();
|
||||||
m_s->get_unsat_core(core_exprs);
|
m_s.get_unsat_core(core_exprs);
|
||||||
if (!core_exprs.contains(not_cls)) {
|
if (!core_exprs.contains(not_cls)) {
|
||||||
// core := core_exprs \ mus
|
// core := core_exprs \ mus
|
||||||
core.reset();
|
core.reset();
|
||||||
|
@ -124,7 +124,7 @@ struct mus::imp {
|
||||||
for (unsigned i = 0; i < mus.size(); ++i) {
|
for (unsigned i = 0; i < mus.size(); ++i) {
|
||||||
assumptions.push_back(m_cls2expr[mus[i]].get());
|
assumptions.push_back(m_cls2expr[mus[i]].get());
|
||||||
}
|
}
|
||||||
lbool is_sat = m_s->check_sat(assumptions.size(), assumptions.c_ptr());
|
lbool is_sat = m_s.check_sat(assumptions.size(), assumptions.c_ptr());
|
||||||
SASSERT(is_sat == l_false);
|
SASSERT(is_sat == l_false);
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
@ -147,7 +147,7 @@ struct mus::imp {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mus::mus(ref<solver>& s, ast_manager& m) {
|
mus::mus(solver& s, ast_manager& m) {
|
||||||
m_imp = alloc(imp, s, m);
|
m_imp = alloc(imp, s, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace opt {
|
||||||
struct imp;
|
struct imp;
|
||||||
imp * m_imp;
|
imp * m_imp;
|
||||||
public:
|
public:
|
||||||
mus(ref<solver>& s, ast_manager& m);
|
mus(solver& s, ast_manager& m);
|
||||||
~mus();
|
~mus();
|
||||||
/**
|
/**
|
||||||
Add soft constraint.
|
Add soft constraint.
|
||||||
|
|
|
@ -34,8 +34,10 @@ Notes:
|
||||||
#include "tactical.h"
|
#include "tactical.h"
|
||||||
#include "model_smt2_pp.h"
|
#include "model_smt2_pp.h"
|
||||||
#include "card2bv_tactic.h"
|
#include "card2bv_tactic.h"
|
||||||
#include "bvsls_opt_solver.h"
|
|
||||||
#include "nnf_tactic.h"
|
#include "nnf_tactic.h"
|
||||||
|
#include "inc_sat_solver.h"
|
||||||
|
#include "bv_decl_plugin.h"
|
||||||
|
#include "pb_decl_plugin.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
|
@ -114,13 +116,18 @@ namespace opt {
|
||||||
m_arith(m),
|
m_arith(m),
|
||||||
m_bv(m),
|
m_bv(m),
|
||||||
m_hard_constraints(m),
|
m_hard_constraints(m),
|
||||||
|
m_solver(0),
|
||||||
m_optsmt(m),
|
m_optsmt(m),
|
||||||
m_scoped_state(m),
|
m_scoped_state(m),
|
||||||
m_objective_refs(m)
|
m_fm(m),
|
||||||
|
m_objective_refs(m),
|
||||||
|
m_enable_sat(false),
|
||||||
|
m_enable_sls(false)
|
||||||
{
|
{
|
||||||
m_params.set_bool("model", true);
|
params_ref p;
|
||||||
m_params.set_bool("unsat_core", true);
|
p.set_bool("model", true);
|
||||||
m_solver = alloc(opt_solver, m, m_params, symbol());
|
p.set_bool("unsat_core", true);
|
||||||
|
updt_params(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
context::~context() {
|
context::~context() {
|
||||||
|
@ -172,9 +179,7 @@ namespace opt {
|
||||||
objective& obj = s.m_objectives[i];
|
objective& obj = s.m_objectives[i];
|
||||||
m_objectives.push_back(obj);
|
m_objectives.push_back(obj);
|
||||||
if (obj.m_type == O_MAXSMT) {
|
if (obj.m_type == O_MAXSMT) {
|
||||||
maxsmt* ms = alloc(maxsmt, m);
|
add_maxsmt(obj.m_id);
|
||||||
ms->updt_params(m_params);
|
|
||||||
m_maxsmts.insert(obj.m_id, ms);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_hard_constraints.append(s.m_hard);
|
m_hard_constraints.append(s.m_hard);
|
||||||
|
@ -184,18 +189,19 @@ namespace opt {
|
||||||
if (m_pareto) {
|
if (m_pareto) {
|
||||||
return execute_pareto();
|
return execute_pareto();
|
||||||
}
|
}
|
||||||
|
init_solver();
|
||||||
import_scoped_state();
|
import_scoped_state();
|
||||||
normalize();
|
normalize();
|
||||||
internalize();
|
internalize();
|
||||||
opt_solver& s = get_solver();
|
update_solver();
|
||||||
solver::scoped_push _sp(s);
|
solver& s = get_solver();
|
||||||
for (unsigned i = 0; i < m_hard_constraints.size(); ++i) {
|
for (unsigned i = 0; i < m_hard_constraints.size(); ++i) {
|
||||||
TRACE("opt", tout << "Hard constraint: " << mk_ismt2_pp(m_hard_constraints[i].get(), m) << std::endl;);
|
TRACE("opt", tout << "Hard constraint: " << mk_ismt2_pp(m_hard_constraints[i].get(), m) << std::endl;);
|
||||||
s.assert_expr(m_hard_constraints[i].get());
|
s.assert_expr(m_hard_constraints[i].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
IF_VERBOSE(1, verbose_stream() << "(optimize:check-sat)\n";);
|
IF_VERBOSE(1, verbose_stream() << "(optimize:check-sat)\n";);
|
||||||
lbool is_sat = s.check_sat_core(0,0);
|
lbool is_sat = s.check_sat(0,0);
|
||||||
TRACE("opt", tout << "initial search result: " << is_sat << "\n";);
|
TRACE("opt", tout << "initial search result: " << is_sat << "\n";);
|
||||||
if (is_sat != l_true) {
|
if (is_sat != l_true) {
|
||||||
m_model = 0;
|
m_model = 0;
|
||||||
|
@ -203,7 +209,7 @@ namespace opt {
|
||||||
}
|
}
|
||||||
IF_VERBOSE(1, verbose_stream() << "(optimize:sat)\n";);
|
IF_VERBOSE(1, verbose_stream() << "(optimize:sat)\n";);
|
||||||
s.get_model(m_model);
|
s.get_model(m_model);
|
||||||
m_optsmt.setup(s);
|
m_optsmt.setup(*m_opt_solver.get());
|
||||||
update_lower(true);
|
update_lower(true);
|
||||||
switch (m_objectives.size()) {
|
switch (m_objectives.size()) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -214,7 +220,6 @@ namespace opt {
|
||||||
opt_params optp(m_params);
|
opt_params optp(m_params);
|
||||||
symbol pri = optp.priority();
|
symbol pri = optp.priority();
|
||||||
if (pri == symbol("pareto")) {
|
if (pri == symbol("pareto")) {
|
||||||
_sp.disable_pop();
|
|
||||||
return execute_pareto();
|
return execute_pareto();
|
||||||
}
|
}
|
||||||
else if (pri == symbol("box")) {
|
else if (pri == symbol("box")) {
|
||||||
|
@ -233,7 +238,7 @@ namespace opt {
|
||||||
if (m_model_converter) {
|
if (m_model_converter) {
|
||||||
(*m_model_converter)(mdl, 0);
|
(*m_model_converter)(mdl, 0);
|
||||||
}
|
}
|
||||||
get_solver().mc()(mdl, 0);
|
m_fm(mdl, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +270,10 @@ namespace opt {
|
||||||
lbool context::execute_lex() {
|
lbool context::execute_lex() {
|
||||||
lbool r = l_true;
|
lbool r = l_true;
|
||||||
for (unsigned i = 0; r == l_true && i < m_objectives.size(); ++i) {
|
for (unsigned i = 0; r == l_true && i < m_objectives.size(); ++i) {
|
||||||
|
bool is_last = i + 1 == m_objectives.size();
|
||||||
|
if (!is_last) get_solver().push();
|
||||||
r = execute(m_objectives[i], i + 1 < m_objectives.size());
|
r = execute(m_objectives[i], i + 1 < m_objectives.size());
|
||||||
|
if (!is_last) get_solver().pop(1);
|
||||||
if (r == l_true && !get_lower_as_num(i).is_finite()) {
|
if (r == l_true && !get_lower_as_num(i).is_finite()) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -282,9 +290,8 @@ namespace opt {
|
||||||
for (unsigned i = 0; r == l_true && i < m_objectives.size(); ++i) {
|
for (unsigned i = 0; r == l_true && i < m_objectives.size(); ++i) {
|
||||||
objective const& obj = m_objectives[i];
|
objective const& obj = m_objectives[i];
|
||||||
if (obj.m_type == O_MAXSMT) {
|
if (obj.m_type == O_MAXSMT) {
|
||||||
get_solver().push();
|
solver::scoped_push _sp(get_solver());
|
||||||
r = execute(obj, false);
|
r = execute(obj, false);
|
||||||
get_solver().pop(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
@ -381,12 +388,13 @@ namespace opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool context::execute_pareto() {
|
lbool context::execute_pareto() {
|
||||||
|
|
||||||
if (!m_pareto) {
|
if (!m_pareto) {
|
||||||
m_pareto = alloc(gia_pareto, m, *this, m_solver.get(), m_params);
|
set_pareto(alloc(gia_pareto, m, *this, m_solver.get(), m_params));
|
||||||
}
|
}
|
||||||
lbool is_sat = (*(m_pareto.get()))();
|
lbool is_sat = (*(m_pareto.get()))();
|
||||||
if (is_sat != l_true) {
|
if (is_sat != l_true) {
|
||||||
m_pareto = 0;
|
set_pareto(0);
|
||||||
}
|
}
|
||||||
if (is_sat == l_true) {
|
if (is_sat == l_true) {
|
||||||
yield();
|
yield();
|
||||||
|
@ -395,7 +403,6 @@ namespace opt {
|
||||||
m_solver->pop(1);
|
m_solver->pop(1);
|
||||||
}
|
}
|
||||||
return is_sat;
|
return is_sat;
|
||||||
// NB. fix race condition for set_cancel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::display_bounds(std::ostream& out, bounds_t const& b) const {
|
void context::display_bounds(std::ostream& out, bounds_t const& b) const {
|
||||||
|
@ -411,10 +418,98 @@ namespace opt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_solver& context::get_solver() {
|
solver& context::get_solver() {
|
||||||
return *m_solver.get();
|
return *m_solver.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void context::init_solver() {
|
||||||
|
#pragma omp critical (opt_context)
|
||||||
|
{
|
||||||
|
m_opt_solver = alloc(opt_solver, m, m_params, m_fm, symbol());
|
||||||
|
m_solver = m_opt_solver.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void context::update_solver() {
|
||||||
|
if (!m_enable_sat || !probe_bv()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_maxsat_engine != symbol("maxres") &&
|
||||||
|
m_maxsat_engine != symbol("mus-mss-maxres") &&
|
||||||
|
m_maxsat_engine != symbol("bcd2") &&
|
||||||
|
m_maxsat_engine != symbol("sls")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_params.set_bool("minimize_core", true);
|
||||||
|
m_sat_solver = mk_inc_sat_solver(m, m_params);
|
||||||
|
unsigned sz = get_solver().get_num_assertions();
|
||||||
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
|
m_sat_solver->assert_expr(get_solver().get_assertion(i));
|
||||||
|
}
|
||||||
|
#pragma omp critical (opt_context)
|
||||||
|
{
|
||||||
|
m_solver = m_sat_solver.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void context::enable_sls(expr_ref_vector const& soft, vector<rational> const& weights) {
|
||||||
|
SASSERT(soft.size() == weights.size());
|
||||||
|
if (m_enable_sls && m_sat_solver.get()) {
|
||||||
|
set_soft_inc_sat(m_sat_solver.get(), soft.size(), soft.c_ptr(), weights.c_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct context::is_bv {
|
||||||
|
struct found {};
|
||||||
|
ast_manager& m;
|
||||||
|
pb_util pb;
|
||||||
|
bv_util bv;
|
||||||
|
is_bv(ast_manager& m): m(m), pb(m), bv(m) {}
|
||||||
|
void operator()(var *) { throw found(); }
|
||||||
|
void operator()(quantifier *) { throw found(); }
|
||||||
|
void operator()(app *n) {
|
||||||
|
family_id fid = n->get_family_id();
|
||||||
|
if (fid != m.get_basic_family_id() &&
|
||||||
|
fid != pb.get_family_id() &&
|
||||||
|
fid != bv.get_family_id() &&
|
||||||
|
!is_uninterp_const(n)) {
|
||||||
|
throw found();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool context::probe_bv() {
|
||||||
|
expr_fast_mark1 visited;
|
||||||
|
is_bv proc(m);
|
||||||
|
try {
|
||||||
|
for (unsigned i = 0; i < m_objectives.size(); ++i) {
|
||||||
|
objective & obj = m_objectives[i];
|
||||||
|
if (obj.m_type != O_MAXSMT) return false;
|
||||||
|
maxsmt& ms = *m_maxsmts.find(obj.m_id);
|
||||||
|
for (unsigned j = 0; j < ms.size(); ++j) {
|
||||||
|
quick_for_each_expr(proc, visited, ms[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsigned sz = get_solver().get_num_assertions();
|
||||||
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
|
quick_for_each_expr(proc, visited, get_solver().get_assertion(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (is_bv::found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void context::add_maxsmt(symbol const& id) {
|
||||||
|
maxsmt* ms = alloc(maxsmt, *this);
|
||||||
|
ms->updt_params(m_params);
|
||||||
|
#pragma omp critical (opt_context)
|
||||||
|
{
|
||||||
|
m_maxsmts.insert(id, ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool context::is_numeral(expr* e, rational & n) const {
|
bool context::is_numeral(expr* e, rational & n) const {
|
||||||
unsigned sz;
|
unsigned sz;
|
||||||
return m_arith.is_numeral(e, n) || m_bv.is_numeral(e, n, sz);
|
return m_arith.is_numeral(e, n) || m_bv.is_numeral(e, n, sz);
|
||||||
|
@ -440,28 +535,16 @@ namespace opt {
|
||||||
mk_simplify_tactic(m));
|
mk_simplify_tactic(m));
|
||||||
opt_params optp(m_params);
|
opt_params optp(m_params);
|
||||||
tactic_ref tac2, tac3;
|
tactic_ref tac2, tac3;
|
||||||
if (optp.engine() == "bvsls") {
|
if (optp.elim_01()) {
|
||||||
tac2 = mk_elim01_tactic(m);
|
tac2 = mk_elim01_tactic(m);
|
||||||
tac3 = mk_lia2card_tactic(m);
|
tac3 = mk_lia2card_tactic(m);
|
||||||
params_ref lia_p;
|
params_ref lia_p;
|
||||||
lia_p.set_bool("compile_equality", optp.pb_compile_equality());
|
lia_p.set_bool("compile_equality", optp.pb_compile_equality());
|
||||||
tac3->updt_params(lia_p);
|
tac3->updt_params(lia_p);
|
||||||
m_simplify = and_then(tac0.get(), tac2.get(), tac3.get(),
|
set_simplify(and_then(tac0.get(), tac2.get(), tac3.get()));
|
||||||
mk_card2bv_tactic(m),
|
|
||||||
mk_simplify_tactic(m),
|
|
||||||
mk_nnf_tactic(m));
|
|
||||||
m_solver = alloc(bvsls_opt_solver, m, m_params);
|
|
||||||
}
|
|
||||||
else if (optp.elim_01()) {
|
|
||||||
tac2 = mk_elim01_tactic(m);
|
|
||||||
tac3 = mk_lia2card_tactic(m);
|
|
||||||
params_ref lia_p;
|
|
||||||
lia_p.set_bool("compile_equality", optp.pb_compile_equality());
|
|
||||||
tac3->updt_params(lia_p);
|
|
||||||
m_simplify = and_then(tac0.get(), tac2.get(), tac3.get());
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_simplify = tac0.get();
|
set_simplify(tac0.get());
|
||||||
}
|
}
|
||||||
proof_converter_ref pc;
|
proof_converter_ref pc;
|
||||||
expr_dependency_ref core(m);
|
expr_dependency_ref core(m);
|
||||||
|
@ -657,9 +740,7 @@ namespace opt {
|
||||||
obj.m_type = O_MAXSMT;
|
obj.m_type = O_MAXSMT;
|
||||||
obj.m_weights.append(weights);
|
obj.m_weights.append(weights);
|
||||||
SASSERT(!m_maxsmts.contains(id));
|
SASSERT(!m_maxsmts.contains(id));
|
||||||
maxsmt* ms = alloc(maxsmt, m);
|
add_maxsmt(id);
|
||||||
ms->updt_params(m_params);
|
|
||||||
m_maxsmts.insert(id, ms);
|
|
||||||
}
|
}
|
||||||
SASSERT(obj.m_id == id);
|
SASSERT(obj.m_id == id);
|
||||||
obj.m_terms.reset();
|
obj.m_terms.reset();
|
||||||
|
@ -900,21 +981,38 @@ namespace opt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void context::set_simplify(tactic* tac) {
|
||||||
|
#pragma omp critical (opt_context)
|
||||||
|
{
|
||||||
|
m_simplify = tac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void context::set_pareto(pareto_base* p) {
|
||||||
|
#pragma omp critical (opt_context)
|
||||||
|
{
|
||||||
|
m_pareto = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void context::set_cancel(bool f) {
|
void context::set_cancel(bool f) {
|
||||||
if (m_solver) {
|
#pragma omp critical (opt_context)
|
||||||
m_solver->set_cancel(f);
|
{
|
||||||
}
|
if (m_solver) {
|
||||||
if (m_simplify) {
|
m_solver->set_cancel(f);
|
||||||
m_simplify->set_cancel(f);
|
}
|
||||||
}
|
if (m_pareto) {
|
||||||
if (m_pareto) {
|
m_pareto->set_cancel(f);
|
||||||
m_pareto->set_cancel(f);
|
}
|
||||||
|
if (m_simplify) {
|
||||||
|
m_simplify->set_cancel(f);
|
||||||
|
}
|
||||||
|
map_t::iterator it = m_maxsmts.begin(), end = m_maxsmts.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
it->m_value->set_cancel(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_optsmt.set_cancel(f);
|
m_optsmt.set_cancel(f);
|
||||||
map_t::iterator it = m_maxsmts.begin(), end = m_maxsmts.end();
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
it->m_value->set_cancel(f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::collect_statistics(statistics& stats) const {
|
void context::collect_statistics(statistics& stats) const {
|
||||||
|
@ -944,6 +1042,10 @@ namespace opt {
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
it->m_value->updt_params(m_params);
|
it->m_value->updt_params(m_params);
|
||||||
}
|
}
|
||||||
|
opt_params _p(p);
|
||||||
|
m_enable_sat = _p.enable_sat();
|
||||||
|
m_enable_sls = _p.enable_sls();
|
||||||
|
m_maxsat_engine = _p.maxsat_engine();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef obj_hashtable<func_decl> func_decl_set;
|
typedef obj_hashtable<func_decl> func_decl_set;
|
||||||
|
|
|
@ -108,7 +108,9 @@ namespace opt {
|
||||||
arith_util m_arith;
|
arith_util m_arith;
|
||||||
bv_util m_bv;
|
bv_util m_bv;
|
||||||
expr_ref_vector m_hard_constraints;
|
expr_ref_vector m_hard_constraints;
|
||||||
ref<opt_solver> m_solver;
|
ref<opt_solver> m_opt_solver;
|
||||||
|
ref<solver> m_solver;
|
||||||
|
ref<solver> m_sat_solver;
|
||||||
scoped_ptr<pareto_base> m_pareto;
|
scoped_ptr<pareto_base> m_pareto;
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
optsmt m_optsmt;
|
optsmt m_optsmt;
|
||||||
|
@ -116,11 +118,15 @@ namespace opt {
|
||||||
scoped_state m_scoped_state;
|
scoped_state m_scoped_state;
|
||||||
vector<objective> m_objectives;
|
vector<objective> m_objectives;
|
||||||
model_ref m_model;
|
model_ref m_model;
|
||||||
model_converter_ref m_model_converter;
|
model_converter_ref m_model_converter;
|
||||||
|
filter_model_converter m_fm;
|
||||||
obj_map<func_decl, unsigned> m_objective_fns;
|
obj_map<func_decl, unsigned> m_objective_fns;
|
||||||
obj_map<func_decl, expr*> m_objective_orig;
|
obj_map<func_decl, expr*> m_objective_orig;
|
||||||
func_decl_ref_vector m_objective_refs;
|
func_decl_ref_vector m_objective_refs;
|
||||||
tactic_ref m_simplify;
|
tactic_ref m_simplify;
|
||||||
|
bool m_enable_sat;
|
||||||
|
bool m_enable_sls;
|
||||||
|
symbol m_maxsat_engine;
|
||||||
public:
|
public:
|
||||||
context(ast_manager& m);
|
context(ast_manager& m);
|
||||||
virtual ~context();
|
virtual ~context();
|
||||||
|
@ -163,6 +169,15 @@ namespace opt {
|
||||||
virtual expr_ref mk_ge(unsigned i, model_ref& model);
|
virtual expr_ref mk_ge(unsigned i, model_ref& model);
|
||||||
virtual expr_ref mk_le(unsigned i, model_ref& model);
|
virtual expr_ref mk_le(unsigned i, model_ref& model);
|
||||||
|
|
||||||
|
smt::context& smt_context() { return m_opt_solver->get_context(); }
|
||||||
|
filter_model_converter& fm() { return m_fm; }
|
||||||
|
bool sat_enabled() const { return 0 != m_sat_solver.get(); }
|
||||||
|
solver& get_solver();
|
||||||
|
ast_manager& get_manager() { return this->m; }
|
||||||
|
params_ref& params() { return m_params; }
|
||||||
|
void enable_sls(expr_ref_vector const& soft, vector<rational> const& weights);
|
||||||
|
symbol const& maxsat_engine() const { return m_maxsat_engine; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void validate_feasibility(maxsmt& ms);
|
void validate_feasibility(maxsmt& ms);
|
||||||
|
@ -199,7 +214,14 @@ namespace opt {
|
||||||
inf_eps get_upper_as_num(unsigned idx);
|
inf_eps get_upper_as_num(unsigned idx);
|
||||||
|
|
||||||
|
|
||||||
opt_solver& get_solver();
|
struct is_bv;
|
||||||
|
bool probe_bv();
|
||||||
|
|
||||||
|
void init_solver();
|
||||||
|
void update_solver();
|
||||||
|
void add_maxsmt(symbol const& id);
|
||||||
|
void set_simplify(tactic *simplify);
|
||||||
|
void set_pareto(pareto_base* p);
|
||||||
|
|
||||||
bool is_numeral(expr* e, rational& n) const;
|
bool is_numeral(expr* e, rational& n) const;
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,14 @@ Notes:
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
opt_solver::opt_solver(ast_manager & mgr, params_ref const & p, symbol const & l):
|
opt_solver::opt_solver(ast_manager & mgr, params_ref const & p,
|
||||||
|
filter_model_converter& fm, symbol const & l):
|
||||||
solver_na2as(mgr),
|
solver_na2as(mgr),
|
||||||
m_params(p),
|
m_params(p),
|
||||||
m_context(mgr, m_params),
|
m_context(mgr, m_params),
|
||||||
m(mgr),
|
m(mgr),
|
||||||
m_dump_benchmarks(false),
|
m_dump_benchmarks(false),
|
||||||
m_fm(alloc(filter_model_converter, m)) {
|
m_fm(fm) {
|
||||||
m_logic = l;
|
m_logic = l;
|
||||||
if (m_logic != symbol::null) {
|
if (m_logic != symbol::null) {
|
||||||
m_context.set_logic(m_logic);
|
m_context.set_logic(m_logic);
|
||||||
|
@ -233,20 +234,20 @@ namespace opt {
|
||||||
|
|
||||||
if (typeid(smt::theory_inf_arith) == typeid(opt)) {
|
if (typeid(smt::theory_inf_arith) == typeid(opt)) {
|
||||||
smt::theory_inf_arith& th = dynamic_cast<smt::theory_inf_arith&>(opt);
|
smt::theory_inf_arith& th = dynamic_cast<smt::theory_inf_arith&>(opt);
|
||||||
return expr_ref(th.mk_ge(mc(), v, val), m);
|
return expr_ref(th.mk_ge(m_fm, v, val), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeid(smt::theory_mi_arith) == typeid(opt)) {
|
if (typeid(smt::theory_mi_arith) == typeid(opt)) {
|
||||||
smt::theory_mi_arith& th = dynamic_cast<smt::theory_mi_arith&>(opt);
|
smt::theory_mi_arith& th = dynamic_cast<smt::theory_mi_arith&>(opt);
|
||||||
SASSERT(val.is_finite());
|
SASSERT(val.is_finite());
|
||||||
return expr_ref(th.mk_ge(mc(), v, val.get_numeral()), m);
|
return expr_ref(th.mk_ge(m_fm, v, val.get_numeral()), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeid(smt::theory_i_arith) == typeid(opt)) {
|
if (typeid(smt::theory_i_arith) == typeid(opt)) {
|
||||||
SASSERT(val.is_finite());
|
SASSERT(val.is_finite());
|
||||||
SASSERT(val.get_infinitesimal().is_zero());
|
SASSERT(val.get_infinitesimal().is_zero());
|
||||||
smt::theory_i_arith& th = dynamic_cast<smt::theory_i_arith&>(opt);
|
smt::theory_i_arith& th = dynamic_cast<smt::theory_i_arith&>(opt);
|
||||||
return expr_ref(th.mk_ge(mc(), v, val.get_rational()), m);
|
return expr_ref(th.mk_ge(m_fm, v, val.get_rational()), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
// difference logic?
|
// difference logic?
|
||||||
|
|
|
@ -42,6 +42,7 @@ namespace opt {
|
||||||
smt_params m_params;
|
smt_params m_params;
|
||||||
smt::kernel m_context;
|
smt::kernel m_context;
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
|
filter_model_converter& m_fm;
|
||||||
progress_callback * m_callback;
|
progress_callback * m_callback;
|
||||||
symbol m_logic;
|
symbol m_logic;
|
||||||
bool m_objective_enabled;
|
bool m_objective_enabled;
|
||||||
|
@ -50,9 +51,8 @@ namespace opt {
|
||||||
bool m_dump_benchmarks;
|
bool m_dump_benchmarks;
|
||||||
static unsigned m_dump_count;
|
static unsigned m_dump_count;
|
||||||
statistics m_stats;
|
statistics m_stats;
|
||||||
ref<filter_model_converter> m_fm;
|
|
||||||
public:
|
public:
|
||||||
opt_solver(ast_manager & m, params_ref const & p, symbol const & l);
|
opt_solver(ast_manager & m, params_ref const & p, filter_model_converter& fm, symbol const & l);
|
||||||
virtual ~opt_solver();
|
virtual ~opt_solver();
|
||||||
|
|
||||||
virtual void updt_params(params_ref & p);
|
virtual void updt_params(params_ref & p);
|
||||||
|
@ -82,9 +82,6 @@ namespace opt {
|
||||||
inf_eps const & get_objective_value(unsigned obj_index);
|
inf_eps const & get_objective_value(unsigned obj_index);
|
||||||
expr_ref mk_ge(unsigned obj_index, inf_eps const& val);
|
expr_ref mk_ge(unsigned obj_index, inf_eps const& val);
|
||||||
|
|
||||||
filter_model_converter& mc() { return *(m_fm.get()); }
|
|
||||||
ref<filter_model_converter>& mc_ref() { return m_fm; }
|
|
||||||
|
|
||||||
static opt_solver& to_opt(solver& s);
|
static opt_solver& to_opt(solver& s);
|
||||||
bool dump_benchmarks();
|
bool dump_benchmarks();
|
||||||
|
|
||||||
|
|
|
@ -31,16 +31,14 @@ namespace opt {
|
||||||
|
|
||||||
class pbmax : public maxsmt_solver_base {
|
class pbmax : public maxsmt_solver_base {
|
||||||
public:
|
public:
|
||||||
pbmax(opt_solver* s, ast_manager& m, params_ref& p,
|
pbmax(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft):
|
vector<rational> const& ws, expr_ref_vector const& soft):
|
||||||
maxsmt_solver_base(s, m, p, ws, soft) {
|
maxsmt_solver_base(c, ws, soft) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~pbmax() {}
|
virtual ~pbmax() {}
|
||||||
|
|
||||||
lbool operator()() {
|
lbool operator()() {
|
||||||
enable_bvsat();
|
|
||||||
enable_sls();
|
|
||||||
|
|
||||||
TRACE("opt", s().display(tout); tout << "\n";
|
TRACE("opt", s().display(tout); tout << "\n";
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
|
@ -90,9 +88,9 @@ namespace opt {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
maxsmt_solver_base* opt::mk_pbmax(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* opt::mk_pbmax(context & c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(pbmax, s, m, p, ws, soft);
|
return alloc(pbmax, c, ws, soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ Notes:
|
||||||
#include "maxsmt.h"
|
#include "maxsmt.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
maxsmt_solver_base* mk_pbmax(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* mk_pbmax(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,15 +23,15 @@ Notes:
|
||||||
#include "smt_theory.h"
|
#include "smt_theory.h"
|
||||||
#include "smt_context.h"
|
#include "smt_context.h"
|
||||||
#include "theory_wmaxsat.h"
|
#include "theory_wmaxsat.h"
|
||||||
|
#include "opt_context.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
class maxsmt_solver_wbase : public maxsmt_solver_base {
|
class maxsmt_solver_wbase : public maxsmt_solver_base {
|
||||||
smt::context& ctx;
|
smt::context& ctx;
|
||||||
public:
|
public:
|
||||||
maxsmt_solver_wbase(opt_solver* s, ast_manager& m, smt::context& ctx, params_ref& p,
|
maxsmt_solver_wbase(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft):
|
vector<rational> const& ws, expr_ref_vector const& soft):
|
||||||
maxsmt_solver_base(s, m, p, ws, soft), ctx(ctx) {}
|
maxsmt_solver_base(c, ws, soft), ctx(c.smt_context()) {}
|
||||||
~maxsmt_solver_wbase() {}
|
~maxsmt_solver_wbase() {}
|
||||||
|
|
||||||
class scoped_ensure_theory {
|
class scoped_ensure_theory {
|
||||||
|
@ -52,7 +52,7 @@ namespace opt {
|
||||||
wth->reset();
|
wth->reset();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wth = alloc(smt::theory_wmaxsat, m, m_mc);
|
wth = alloc(smt::theory_wmaxsat, m, m_c.fm());
|
||||||
ctx.register_plugin(wth);
|
ctx.register_plugin(wth);
|
||||||
}
|
}
|
||||||
return wth;
|
return wth;
|
||||||
|
@ -76,9 +76,9 @@ namespace opt {
|
||||||
|
|
||||||
class wmax : public maxsmt_solver_wbase {
|
class wmax : public maxsmt_solver_wbase {
|
||||||
public:
|
public:
|
||||||
wmax(opt_solver* s, ast_manager& m, smt::context& ctx, params_ref& p,
|
wmax(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft):
|
vector<rational> const& ws, expr_ref_vector const& soft):
|
||||||
maxsmt_solver_wbase(s, m, ctx, p, ws, soft) {}
|
maxsmt_solver_wbase(c, ws, soft) {}
|
||||||
virtual ~wmax() {}
|
virtual ~wmax() {}
|
||||||
|
|
||||||
lbool operator()() {
|
lbool operator()() {
|
||||||
|
@ -122,9 +122,9 @@ namespace opt {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
maxsmt_solver_base* opt::mk_wmax(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* opt::mk_wmax(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
vector<rational> const& ws, expr_ref_vector const& soft) {
|
||||||
return alloc(wmax, s, m, s->get_context(), p, ws, soft);
|
return alloc(wmax, c, ws, soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ Notes:
|
||||||
#include "maxsmt.h"
|
#include "maxsmt.h"
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
maxsmt_solver_base* mk_wmax(ast_manager& m, opt_solver* s, params_ref& p,
|
maxsmt_solver_base* mk_wmax(context& c,
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
vector<rational> const& ws, expr_ref_vector const& soft);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
251
src/opt/wpm2.cpp
251
src/opt/wpm2.cpp
|
@ -1,251 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2014 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
wpm2.cpp
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
wpn2 based MaxSAT.
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Nikolaj Bjorner (nbjorner) 2014-4-17
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#include "wpm2.h"
|
|
||||||
#include "pbmax.h"
|
|
||||||
#include "pb_decl_plugin.h"
|
|
||||||
#include "uint_set.h"
|
|
||||||
#include "ast_pp.h"
|
|
||||||
#include "model_smt2_pp.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace opt {
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
|
||||||
// AAAI 2010
|
|
||||||
class wpm2 : public maxsmt_solver_base {
|
|
||||||
scoped_ptr<maxsmt_solver_base> maxs;
|
|
||||||
public:
|
|
||||||
wpm2(opt_solver* s, ast_manager& m, maxsmt_solver_base* _maxs, params_ref& p,
|
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft):
|
|
||||||
maxsmt_solver_base(s, m, p, ws, soft), maxs(_maxs) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~wpm2() {}
|
|
||||||
|
|
||||||
lbool operator()() {
|
|
||||||
enable_sls();
|
|
||||||
IF_VERBOSE(1, verbose_stream() << "(opt.wpm2)\n";);
|
|
||||||
solver::scoped_push _s(s());
|
|
||||||
pb_util u(m);
|
|
||||||
app_ref fml(m), a(m), b(m), c(m);
|
|
||||||
expr_ref val(m);
|
|
||||||
expr_ref_vector block(m), ans(m), al(m), am(m);
|
|
||||||
obj_map<expr, unsigned> ans_index;
|
|
||||||
vector<rational> amk;
|
|
||||||
vector<uint_set> sc;
|
|
||||||
init();
|
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
|
||||||
rational w = m_weights[i];
|
|
||||||
|
|
||||||
b = mk_fresh_bool("b");
|
|
||||||
block.push_back(b);
|
|
||||||
expr* bb = b;
|
|
||||||
|
|
||||||
a = mk_fresh_bool("a");
|
|
||||||
ans.push_back(a);
|
|
||||||
ans_index.insert(a, i);
|
|
||||||
fml = m.mk_or(m_soft[i].get(), b, m.mk_not(a));
|
|
||||||
s().assert_expr(fml);
|
|
||||||
|
|
||||||
c = mk_fresh_bool("c");
|
|
||||||
fml = m.mk_implies(c, u.mk_le(1,&w,&bb,rational(0)));
|
|
||||||
s().assert_expr(fml);
|
|
||||||
|
|
||||||
sc.push_back(uint_set());
|
|
||||||
sc.back().insert(i);
|
|
||||||
am.push_back(c);
|
|
||||||
amk.push_back(rational(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
expr_ref_vector asms(m);
|
|
||||||
ptr_vector<expr> core;
|
|
||||||
asms.append(ans);
|
|
||||||
asms.append(am);
|
|
||||||
lbool is_sat = s().check_sat(asms.size(), asms.c_ptr());
|
|
||||||
TRACE("opt",
|
|
||||||
tout << "\nassumptions: ";
|
|
||||||
for (unsigned i = 0; i < asms.size(); ++i) {
|
|
||||||
tout << mk_pp(asms[i].get(), m) << " ";
|
|
||||||
}
|
|
||||||
tout << "\n" << is_sat << "\n";
|
|
||||||
tout << "upper: " << m_upper << "\n";
|
|
||||||
tout << "lower: " << m_lower << "\n";
|
|
||||||
if (is_sat == l_true) {
|
|
||||||
model_ref mdl;
|
|
||||||
s().get_model(mdl);
|
|
||||||
model_smt2_pp(tout, m, *(mdl.get()), 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (m_cancel && is_sat != l_false) {
|
|
||||||
is_sat = l_undef;
|
|
||||||
}
|
|
||||||
if (is_sat == l_true) {
|
|
||||||
m_upper = m_lower;
|
|
||||||
s().get_model(m_model);
|
|
||||||
for (unsigned i = 0; i < block.size(); ++i) {
|
|
||||||
VERIFY(m_model->eval(m_soft[i].get(), val));
|
|
||||||
TRACE("opt", tout << mk_pp(block[i].get(), m) << " " << val << "\n";);
|
|
||||||
m_assignment[i] = m.is_true(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_sat != l_false) {
|
|
||||||
return is_sat;
|
|
||||||
}
|
|
||||||
s().get_unsat_core(core);
|
|
||||||
if (core.empty()) {
|
|
||||||
return l_false;
|
|
||||||
}
|
|
||||||
TRACE("opt",
|
|
||||||
tout << "core: ";
|
|
||||||
for (unsigned i = 0; i < core.size(); ++i) {
|
|
||||||
tout << mk_pp(core[i],m) << " ";
|
|
||||||
}
|
|
||||||
tout << "\n";);
|
|
||||||
uint_set A;
|
|
||||||
for (unsigned i = 0; i < core.size(); ++i) {
|
|
||||||
unsigned j;
|
|
||||||
if (ans_index.find(core[i], j)) {
|
|
||||||
A.insert(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (A.empty()) {
|
|
||||||
return l_false;
|
|
||||||
}
|
|
||||||
uint_set B;
|
|
||||||
rational k(0);
|
|
||||||
rational old_lower(m_lower);
|
|
||||||
for (unsigned i = 0; i < sc.size(); ++i) {
|
|
||||||
uint_set t(sc[i]);
|
|
||||||
t &= A;
|
|
||||||
if (!t.empty()) {
|
|
||||||
B |= sc[i];
|
|
||||||
k += amk[i];
|
|
||||||
m_lower -= amk[i];
|
|
||||||
sc[i] = sc.back();
|
|
||||||
sc.pop_back();
|
|
||||||
am[i] = am.back();
|
|
||||||
am.pop_back();
|
|
||||||
amk[i] = amk.back();
|
|
||||||
amk.pop_back();
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vector<rational> ws;
|
|
||||||
expr_ref_vector bs(m);
|
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
|
||||||
if (B.contains(i)) {
|
|
||||||
ws.push_back(m_weights[i]);
|
|
||||||
bs.push_back(block[i].get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE("opt", tout << "at most bound: " << k << "\n";);
|
|
||||||
is_sat = new_bound(al, ws, bs, k);
|
|
||||||
if (is_sat != l_true) {
|
|
||||||
return is_sat;
|
|
||||||
}
|
|
||||||
m_lower += k;
|
|
||||||
SASSERT(m_lower > old_lower);
|
|
||||||
TRACE("opt", tout << "new bound: " << m_lower << "\n";);
|
|
||||||
expr_ref B_le_k(m), B_ge_k(m);
|
|
||||||
B_le_k = u.mk_le(ws.size(), ws.c_ptr(), bs.c_ptr(), k);
|
|
||||||
B_ge_k = u.mk_ge(ws.size(), ws.c_ptr(), bs.c_ptr(), k);
|
|
||||||
s().assert_expr(B_ge_k);
|
|
||||||
al.push_back(B_ge_k);
|
|
||||||
IF_VERBOSE(1, verbose_stream() << "(opt.wpm2 [" << m_lower << ":" << m_upper << "])\n";);
|
|
||||||
IF_VERBOSE(2, verbose_stream() << "New lower bound: " << B_ge_k << "\n";);
|
|
||||||
|
|
||||||
c = mk_fresh_bool("c");
|
|
||||||
fml = m.mk_implies(c, B_le_k);
|
|
||||||
s().assert_expr(fml);
|
|
||||||
sc.push_back(B);
|
|
||||||
am.push_back(c);
|
|
||||||
amk.push_back(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void set_cancel(bool f) {
|
|
||||||
maxsmt_solver_base::set_cancel(f);
|
|
||||||
maxs->set_cancel(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void collect_statistics(statistics& st) const {
|
|
||||||
maxsmt_solver_base::collect_statistics(st);
|
|
||||||
maxs->collect_statistics(st);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
lbool new_bound(expr_ref_vector const& al,
|
|
||||||
vector<rational> const& ws,
|
|
||||||
expr_ref_vector const& bs,
|
|
||||||
rational& k) {
|
|
||||||
pb_util u(m);
|
|
||||||
expr_ref_vector al2(m);
|
|
||||||
al2.append(al);
|
|
||||||
// w_j*b_j > k
|
|
||||||
al2.push_back(m.mk_not(u.mk_le(ws.size(), ws.c_ptr(), bs.c_ptr(), k)));
|
|
||||||
return bound(al2, ws, bs, k);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// minimal k, such that al & w_j*b_j >= k is sat
|
|
||||||
// minimal k, such that al & 3*x + 4*y >= k is sat
|
|
||||||
// minimal k, such that al & (or (not x) w3) & (or (not y) w4)
|
|
||||||
//
|
|
||||||
lbool bound(expr_ref_vector const& al,
|
|
||||||
vector<rational> const& ws,
|
|
||||||
expr_ref_vector const& bs,
|
|
||||||
rational& k) {
|
|
||||||
expr_ref_vector nbs(m);
|
|
||||||
opt_solver::scoped_push _sc(maxs->s());
|
|
||||||
for (unsigned i = 0; i < al.size(); ++i) {
|
|
||||||
maxs->add_hard(al[i]);
|
|
||||||
}
|
|
||||||
for (unsigned i = 0; i < bs.size(); ++i) {
|
|
||||||
nbs.push_back(mk_not(bs[i]));
|
|
||||||
}
|
|
||||||
TRACE("opt",
|
|
||||||
maxs->s().display(tout);
|
|
||||||
tout << "\n";
|
|
||||||
for (unsigned i = 0; i < bs.size(); ++i) {
|
|
||||||
tout << mk_pp(bs[i], m) << " " << ws[i] << "\n";
|
|
||||||
});
|
|
||||||
maxs->init_soft(ws, nbs);
|
|
||||||
lbool is_sat = maxs->s().check_sat(0,0);
|
|
||||||
if (is_sat == l_true) {
|
|
||||||
maxs->set_model();
|
|
||||||
is_sat = (*maxs)();
|
|
||||||
}
|
|
||||||
SASSERT(maxs->get_lower() > k);
|
|
||||||
k = maxs->get_lower();
|
|
||||||
return is_sat;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
maxsmt_solver_base* opt::mk_wpm2(ast_manager& m, opt_solver* s, params_ref& p,
|
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft) {
|
|
||||||
|
|
||||||
ref<opt_solver> s0 = alloc(opt_solver, m, p, symbol());
|
|
||||||
// initialize model.
|
|
||||||
s0->check_sat(0,0);
|
|
||||||
maxsmt_solver_base* s2 = mk_pbmax(m, s0.get(), p, ws, soft);
|
|
||||||
return alloc(wpm2, s, m, s2, p, ws, soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2014 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
wpm2.h
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Wpm2 based MaxSAT.
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Nikolaj Bjorner (nbjorner) 2014-4-17
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
|
|
||||||
#ifndef _WPM2_H_
|
|
||||||
#define _WPM2_H_
|
|
||||||
|
|
||||||
#include "maxsmt.h"
|
|
||||||
|
|
||||||
namespace opt {
|
|
||||||
maxsmt_solver_base* mk_wpm2(ast_manager& m, opt_solver* s, params_ref& p,
|
|
||||||
vector<rational> const& ws, expr_ref_vector const& soft);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -105,6 +105,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
m_minimize_lemmas = p.minimize_lemmas();
|
m_minimize_lemmas = p.minimize_lemmas();
|
||||||
m_minimize_core = p.minimize_core();
|
m_minimize_core = p.minimize_core();
|
||||||
|
m_optimize_model = p.optimize_model();
|
||||||
m_dyn_sub_res = p.dyn_sub_res();
|
m_dyn_sub_res = p.dyn_sub_res();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace sat {
|
||||||
bool m_minimize_lemmas;
|
bool m_minimize_lemmas;
|
||||||
bool m_dyn_sub_res;
|
bool m_dyn_sub_res;
|
||||||
bool m_minimize_core;
|
bool m_minimize_core;
|
||||||
|
bool m_optimize_model;
|
||||||
|
|
||||||
|
|
||||||
symbol m_always_true;
|
symbol m_always_true;
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace sat {
|
||||||
|
|
||||||
lbool mus::operator()() {
|
lbool mus::operator()() {
|
||||||
flet<bool> _disable_min(s.m_config.m_minimize_core, false);
|
flet<bool> _disable_min(s.m_config.m_minimize_core, false);
|
||||||
|
flet<bool> _disable_opt(s.m_config.m_optimize_model, false);
|
||||||
TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
|
TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
|
||||||
IF_VERBOSE(2, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
|
IF_VERBOSE(2, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
|
||||||
reset();
|
reset();
|
||||||
|
|
|
@ -19,4 +19,5 @@ def_module_params('sat',
|
||||||
('minimize_lemmas', BOOL, True, 'minimize learned clauses'),
|
('minimize_lemmas', BOOL, True, 'minimize learned clauses'),
|
||||||
('dyn_sub_res', BOOL, True, 'dynamic subsumption resolution for minimizing learned clauses'),
|
('dyn_sub_res', BOOL, True, 'dynamic subsumption resolution for minimizing learned clauses'),
|
||||||
('minimize_core', BOOL, False, 'minimize computed core'),
|
('minimize_core', BOOL, False, 'minimize computed core'),
|
||||||
|
('optimize_model', BOOL, False, 'enable optimization of soft constraints'),
|
||||||
('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks')))
|
('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks')))
|
||||||
|
|
|
@ -50,8 +50,8 @@ namespace sat {
|
||||||
return m_elems[rnd(num_elems())];
|
return m_elems[rnd(num_elems())];
|
||||||
}
|
}
|
||||||
|
|
||||||
sls::sls(solver& s): s(s) {
|
sls::sls(solver& s): s(s), m_cancel(false) {
|
||||||
m_max_tries = 10000;
|
m_max_tries = 1000000;
|
||||||
m_prob_choose_min_var = 43;
|
m_prob_choose_min_var = 43;
|
||||||
m_clause_generation = 0;
|
m_clause_generation = 0;
|
||||||
}
|
}
|
||||||
|
@ -180,6 +180,7 @@ namespace sat {
|
||||||
m_use_list[c[j].index()].push_back(i);
|
m_use_list[c[j].index()].push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DEBUG_CODE(check_use_list(););
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned_vector const& sls::get_use(literal lit) {
|
unsigned_vector const& sls::get_use(literal lit) {
|
||||||
|
@ -242,7 +243,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sls::flip(literal lit) {
|
void sls::flip(literal lit) {
|
||||||
// IF_VERBOSE(0, verbose_stream() << lit << " ";);
|
//IF_VERBOSE(0, verbose_stream() << lit << " ";);
|
||||||
SASSERT(value_at(lit, m_model) == l_false);
|
SASSERT(value_at(lit, m_model) == l_false);
|
||||||
SASSERT(!m_tabu[lit.var()]);
|
SASSERT(!m_tabu[lit.var()]);
|
||||||
m_model[lit.var()] = lit.sign()?l_false:l_true;
|
m_model[lit.var()] = lit.sign()?l_false:l_true;
|
||||||
|
@ -266,9 +267,70 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sls::check_invariant() {
|
void sls::check_invariant() {
|
||||||
|
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||||
|
clause const& c = *m_clauses[i];
|
||||||
|
bool is_sat = c.satisfied_by(m_model);
|
||||||
|
SASSERT(is_sat != m_false.contains(i));
|
||||||
|
SASSERT(is_sat == m_num_true[i] > 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sls::check_use_list() {
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||||
|
clause const& c = *m_clauses[i];
|
||||||
|
for (unsigned j = 0; j < c.size(); ++j) {
|
||||||
|
unsigned idx = c[j].index();
|
||||||
|
SASSERT(m_use_list[idx].contains(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < m_use_list.size(); ++i) {
|
||||||
|
literal lit = to_literal(i);
|
||||||
|
for (unsigned j = 0; j < m_use_list[i].size(); ++j) {
|
||||||
|
clause const& c = *m_clauses[m_use_list[i][j]];
|
||||||
|
bool found = false;
|
||||||
|
for (unsigned k = 0; !found && k < c.size(); ++k) {
|
||||||
|
found = c[k] == lit;
|
||||||
|
}
|
||||||
|
SASSERT(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sls::display(std::ostream& out) const {
|
||||||
|
out << "Model\n";
|
||||||
|
for (bool_var v = 0; v < m_model.size(); ++v) {
|
||||||
|
out << v << ": " << m_model[v] << "\n";
|
||||||
|
}
|
||||||
|
out << "Clauses\n";
|
||||||
|
unsigned sz = m_false.num_elems();
|
||||||
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
|
out << *m_clauses[m_false[i]] << "\n";
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < m_clauses.size(); ++i) {
|
||||||
|
if (m_false.contains(i)) continue;
|
||||||
|
clause const& c = *m_clauses[i];
|
||||||
|
out << c << " " << m_num_true[i] << "\n";
|
||||||
|
}
|
||||||
|
bool has_tabu = false;
|
||||||
|
for (unsigned i = 0; !has_tabu && i < m_tabu.size(); ++i) {
|
||||||
|
has_tabu = m_tabu[i];
|
||||||
|
}
|
||||||
|
if (has_tabu) {
|
||||||
|
out << "Tabu: ";
|
||||||
|
for (unsigned i = 0; i < m_tabu.size(); ++i) {
|
||||||
|
if (m_tabu[i]) {
|
||||||
|
literal lit(i, false);
|
||||||
|
if (value_at(lit, m_model) == l_false) lit.neg();
|
||||||
|
out << lit << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wsls::wsls(solver& s):
|
wsls::wsls(solver& s):
|
||||||
sls(s)
|
sls(s)
|
||||||
{
|
{
|
||||||
|
@ -277,7 +339,7 @@ namespace sat {
|
||||||
|
|
||||||
wsls::~wsls() {}
|
wsls::~wsls() {}
|
||||||
|
|
||||||
void wsls::set_soft(unsigned sz, double const* weights, literal const* lits) {
|
void wsls::set_soft(unsigned sz, literal const* lits, double const* weights) {
|
||||||
m_soft.reset();
|
m_soft.reset();
|
||||||
m_weights.reset();
|
m_weights.reset();
|
||||||
m_soft.append(sz, lits);
|
m_soft.append(sz, lits);
|
||||||
|
@ -291,14 +353,17 @@ namespace sat {
|
||||||
// Initialize m_clause_weights, m_hscore, m_sscore.
|
// Initialize m_clause_weights, m_hscore, m_sscore.
|
||||||
//
|
//
|
||||||
m_best_value = m_false.empty()?evaluate_model():-1.0;
|
m_best_value = m_false.empty()?evaluate_model():-1.0;
|
||||||
|
m_best_model.reset();
|
||||||
m_clause_weights.reset();
|
m_clause_weights.reset();
|
||||||
m_hscore.reset();
|
m_hscore.reset();
|
||||||
m_sscore.reset();
|
m_sscore.reset();
|
||||||
m_H.reset();
|
m_H.reset();
|
||||||
m_S.reset();
|
m_S.reset();
|
||||||
|
m_best_model.append(s.get_model());
|
||||||
m_clause_weights.resize(m_clauses.size(), 1);
|
m_clause_weights.resize(m_clauses.size(), 1);
|
||||||
m_sscore.resize(s.num_vars(), 0.0);
|
m_sscore.resize(s.num_vars(), 0.0);
|
||||||
m_hscore.resize(s.num_vars(), 0);
|
m_hscore.resize(s.num_vars(), 0);
|
||||||
|
unsigned num_violated = 0;
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
literal lit = m_soft[i];
|
literal lit = m_soft[i];
|
||||||
m_sscore[lit.var()] = m_weights[i];
|
m_sscore[lit.var()] = m_weights[i];
|
||||||
|
@ -310,16 +375,19 @@ namespace sat {
|
||||||
m_hscore[i] = compute_hscore(i);
|
m_hscore[i] = compute_hscore(i);
|
||||||
refresh_scores(i);
|
refresh_scores(i);
|
||||||
}
|
}
|
||||||
|
DEBUG_CODE(check_invariant(););
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (; !m_cancel && i < m_max_tries; ++i) {
|
for (; !m_cancel && m_best_value > 0 && i < m_max_tries; ++i) {
|
||||||
wflip();
|
wflip();
|
||||||
}
|
}
|
||||||
IF_VERBOSE(2, verbose_stream() << "tries " << i << "\n";);
|
TRACE("sat", display(tout););
|
||||||
|
IF_VERBOSE(0, verbose_stream() << "tries " << i << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsls::wflip() {
|
void wsls::wflip() {
|
||||||
literal lit;
|
literal lit;
|
||||||
if (pick_wflip(lit)) {
|
if (pick_wflip(lit)) {
|
||||||
|
// IF_VERBOSE(0, verbose_stream() << lit << " ";);
|
||||||
wflip(lit);
|
wflip(lit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,8 +396,10 @@ namespace sat {
|
||||||
if (m_false.empty()) {
|
if (m_false.empty()) {
|
||||||
double val = evaluate_model();
|
double val = evaluate_model();
|
||||||
if (val < m_best_value || m_best_value < 0.0) {
|
if (val < m_best_value || m_best_value < 0.0) {
|
||||||
|
m_best_value = val;
|
||||||
m_best_model.reset();
|
m_best_model.reset();
|
||||||
m_best_model.append(m_model);
|
m_best_model.append(m_model);
|
||||||
|
IF_VERBOSE(0, verbose_stream() << "new value:" << val << "\n";);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsigned idx;
|
unsigned idx;
|
||||||
|
@ -337,6 +407,8 @@ namespace sat {
|
||||||
idx = m_H.choose(m_rand);
|
idx = m_H.choose(m_rand);
|
||||||
lit = literal(idx, false);
|
lit = literal(idx, false);
|
||||||
if (value_at(lit, m_model) == l_true) lit.neg();
|
if (value_at(lit, m_model) == l_true) lit.neg();
|
||||||
|
SASSERT(value_at(lit, m_model) == l_false);
|
||||||
|
TRACE("sat", tout << "flip H(" << m_H.num_elems() << ") " << lit << "\n";);
|
||||||
}
|
}
|
||||||
else if (!m_S.empty()) {
|
else if (!m_S.empty()) {
|
||||||
double score = 0.0;
|
double score = 0.0;
|
||||||
|
@ -353,16 +425,38 @@ namespace sat {
|
||||||
m_min_vars.push_back(literal(v, false));
|
m_min_vars.push_back(literal(v, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx = m_min_vars[m_rand(m_min_vars.size())].var(); // pick with largest sscore.
|
lit = m_min_vars[m_rand(m_min_vars.size())]; // pick with largest sscore.
|
||||||
|
SASSERT(value_at(lit, m_model) == l_false);
|
||||||
|
TRACE("sat", tout << "flip S(" << m_min_vars.size() << "," << score << ") " << lit << "\n";);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
update_hard_weights();
|
update_hard_weights();
|
||||||
if (!m_false.empty()) {
|
if (!m_false.empty()) {
|
||||||
unsigned cls_idx = m_false.choose(m_rand);
|
unsigned cls_idx = m_false.choose(m_rand);
|
||||||
|
clause const& c = *m_clauses[cls_idx];
|
||||||
|
lit = c[m_rand(c.size())];
|
||||||
|
TRACE("sat", tout << "flip hard(" << m_false.num_elems() << "," << c.size() << ") " << lit << "\n";);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lit = m_soft[m_rand(m_soft.size())];
|
m_min_vars.reset();
|
||||||
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
|
lit = m_soft[i];
|
||||||
|
if (value_at(lit, m_model) == l_false) {
|
||||||
|
m_min_vars.push_back(lit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_min_vars.empty()) {
|
||||||
|
SASSERT(m_best_value == 0.0);
|
||||||
|
UNREACHABLE(); // we should have exited the main loop before.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lit = m_min_vars[m_rand(m_min_vars.size())];
|
||||||
|
}
|
||||||
|
TRACE("sat", tout << "flip soft(" << m_min_vars.size() << ") " << lit << "\n";);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
SASSERT(value_at(lit, m_model) == l_false);
|
||||||
}
|
}
|
||||||
return !m_tabu[lit.var()];
|
return !m_tabu[lit.var()];
|
||||||
}
|
}
|
||||||
|
@ -408,7 +502,6 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_CODE(check_invariant(););
|
DEBUG_CODE(check_invariant(););
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,9 +581,29 @@ namespace sat {
|
||||||
// The score(v) is the reward on soft clauses for flipping v.
|
// The score(v) is the reward on soft clauses for flipping v.
|
||||||
for (unsigned j = 0; j < m_soft.size(); ++j) {
|
for (unsigned j = 0; j < m_soft.size(); ++j) {
|
||||||
unsigned v = m_soft[j].var();
|
unsigned v = m_soft[j].var();
|
||||||
double ss = value_at(m_soft[j], m_model)?(-m_weights[j]):m_weights[j];
|
double ss = (l_true == value_at(m_soft[j], m_model))?(-m_weights[j]):m_weights[j];
|
||||||
SASSERT(m_sscore[v] == ss);
|
SASSERT(m_sscore[v] == ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_H are values such that m_hscore >= 0.
|
||||||
|
for (bool_var v = 0; v < m_hscore.size(); ++v) {
|
||||||
|
SASSERT(m_hscore[v] > 0 == m_H.contains(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_S are values such that hscore = 0, sscore > 0
|
||||||
|
for (bool_var v = 0; v < m_sscore.size(); ++v) {
|
||||||
|
SASSERT((m_hscore[v] == 0 && m_sscore[v] > 0) == m_S.contains(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wsls::display(std::ostream& out) const {
|
||||||
|
sls::display(out);
|
||||||
|
out << "Best model\n";
|
||||||
|
for (bool_var v = 0; v < m_best_model.size(); ++v) {
|
||||||
|
out << v << ": " << m_best_model[v] << " h: " << m_hscore[v];
|
||||||
|
if (m_sscore[v] != 0.0) out << " s: " << m_sscore[v];
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,6 +60,8 @@ namespace sat {
|
||||||
virtual ~sls();
|
virtual ~sls();
|
||||||
lbool operator()(unsigned sz, literal const* tabu, bool reuse_model);
|
lbool operator()(unsigned sz, literal const* tabu, bool reuse_model);
|
||||||
void set_cancel(bool f) { m_cancel = f; }
|
void set_cancel(bool f) { m_cancel = f; }
|
||||||
|
void set_max_tries(unsigned mx) { m_max_tries = mx; }
|
||||||
|
virtual void display(std::ostream& out) const;
|
||||||
protected:
|
protected:
|
||||||
void init(unsigned sz, literal const* tabu, bool reuse_model);
|
void init(unsigned sz, literal const* tabu, bool reuse_model);
|
||||||
void init_tabu(unsigned sz, literal const* tabu);
|
void init_tabu(unsigned sz, literal const* tabu);
|
||||||
|
@ -69,6 +71,7 @@ namespace sat {
|
||||||
unsigned_vector const& get_use(literal lit);
|
unsigned_vector const& get_use(literal lit);
|
||||||
void flip(literal lit);
|
void flip(literal lit);
|
||||||
virtual void check_invariant();
|
virtual void check_invariant();
|
||||||
|
void check_use_list();
|
||||||
private:
|
private:
|
||||||
bool pick_flip(literal& lit);
|
bool pick_flip(literal& lit);
|
||||||
void flip();
|
void flip();
|
||||||
|
@ -91,9 +94,11 @@ namespace sat {
|
||||||
public:
|
public:
|
||||||
wsls(solver& s);
|
wsls(solver& s);
|
||||||
virtual ~wsls();
|
virtual ~wsls();
|
||||||
void set_soft(unsigned sz, double const* weights, literal const* lits);
|
void set_soft(unsigned sz, literal const* lits, double const* weights);
|
||||||
|
bool has_soft() const { return !m_soft.empty(); }
|
||||||
void opt(unsigned sz, literal const* tabu, bool reuse_model);
|
void opt(unsigned sz, literal const* tabu, bool reuse_model);
|
||||||
model const& get_model() { return m_best_model; }
|
model const& get_model() { return m_best_model; }
|
||||||
|
virtual void display(std::ostream& out) const;
|
||||||
private:
|
private:
|
||||||
void wflip();
|
void wflip();
|
||||||
void wflip(literal lit);
|
void wflip(literal lit);
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace sat {
|
||||||
m_asymm_branch(*this, p),
|
m_asymm_branch(*this, p),
|
||||||
m_probing(*this, p),
|
m_probing(*this, p),
|
||||||
m_mus(*this),
|
m_mus(*this),
|
||||||
|
m_wsls(*this),
|
||||||
m_inconsistent(false),
|
m_inconsistent(false),
|
||||||
m_num_frozen(0),
|
m_num_frozen(0),
|
||||||
m_activity_inc(128),
|
m_activity_inc(128),
|
||||||
|
@ -528,6 +529,10 @@ namespace sat {
|
||||||
return found_undef ? l_undef : l_false;
|
return found_undef ? l_undef : l_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solver::initialize_soft(unsigned sz, literal const* lits, double const* weights) {
|
||||||
|
m_wsls.set_soft(sz, lits, weights);
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------
|
// -----------------------
|
||||||
//
|
//
|
||||||
// Propagation
|
// Propagation
|
||||||
|
@ -1003,6 +1008,11 @@ namespace sat {
|
||||||
m_model[v] = value(v);
|
m_model[v] = value(v);
|
||||||
}
|
}
|
||||||
TRACE("sat_mc_bug", m_mc.display(tout););
|
TRACE("sat_mc_bug", m_mc.display(tout););
|
||||||
|
if (m_config.m_optimize_model) {
|
||||||
|
m_wsls.opt(0, 0, false);
|
||||||
|
m_model.reset();
|
||||||
|
m_model.append(m_wsls.get_model());
|
||||||
|
}
|
||||||
m_mc(m_model);
|
m_mc(m_model);
|
||||||
TRACE("sat", for (bool_var v = 0; v < num; v++) tout << v << ": " << m_model[v] << "\n";);
|
TRACE("sat", for (bool_var v = 0; v < num; v++) tout << v << ": " << m_model[v] << "\n";);
|
||||||
|
|
||||||
|
@ -2305,6 +2315,7 @@ namespace sat {
|
||||||
|
|
||||||
void solver::set_cancel(bool f) {
|
void solver::set_cancel(bool f) {
|
||||||
m_cancel = f;
|
m_cancel = f;
|
||||||
|
m_wsls.set_cancel(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::collect_statistics(statistics & st) const {
|
void solver::collect_statistics(statistics & st) const {
|
||||||
|
|
|
@ -33,6 +33,7 @@ Revision History:
|
||||||
#include"sat_iff3_finder.h"
|
#include"sat_iff3_finder.h"
|
||||||
#include"sat_probing.h"
|
#include"sat_probing.h"
|
||||||
#include"sat_mus.h"
|
#include"sat_mus.h"
|
||||||
|
#include"sat_sls.h"
|
||||||
#include"params.h"
|
#include"params.h"
|
||||||
#include"statistics.h"
|
#include"statistics.h"
|
||||||
#include"stopwatch.h"
|
#include"stopwatch.h"
|
||||||
|
@ -82,6 +83,7 @@ namespace sat {
|
||||||
asymm_branch m_asymm_branch;
|
asymm_branch m_asymm_branch;
|
||||||
probing m_probing;
|
probing m_probing;
|
||||||
mus m_mus;
|
mus m_mus;
|
||||||
|
wsls m_wsls;
|
||||||
bool m_inconsistent;
|
bool m_inconsistent;
|
||||||
// A conflict is usually a single justification. That is, a justification
|
// A conflict is usually a single justification. That is, a justification
|
||||||
// for false. If m_not_l is not null_literal, then m_conflict is a
|
// for false. If m_not_l is not null_literal, then m_conflict is a
|
||||||
|
@ -231,6 +233,7 @@ namespace sat {
|
||||||
if (memory::get_allocation_size() > m_config.m_max_memory) throw solver_exception(Z3_MAX_MEMORY_MSG);
|
if (memory::get_allocation_size() > m_config.m_max_memory) throw solver_exception(Z3_MAX_MEMORY_MSG);
|
||||||
}
|
}
|
||||||
typedef std::pair<literal, literal> bin_clause;
|
typedef std::pair<literal, literal> bin_clause;
|
||||||
|
void initialize_soft(unsigned sz, literal const* lits, double const* weights);
|
||||||
protected:
|
protected:
|
||||||
watch_list & get_wlist(literal l) { return m_watches[l.index()]; }
|
watch_list & get_wlist(literal l) { return m_watches[l.index()]; }
|
||||||
watch_list const & get_wlist(literal l) const { return m_watches[l.index()]; }
|
watch_list const & get_wlist(literal l) const { return m_watches[l.index()]; }
|
||||||
|
|
|
@ -36,6 +36,7 @@ Notes:
|
||||||
#include"model_v2_pp.h"
|
#include"model_v2_pp.h"
|
||||||
#include"tactic.h"
|
#include"tactic.h"
|
||||||
#include"ast_pp.h"
|
#include"ast_pp.h"
|
||||||
|
#include<strstream>
|
||||||
|
|
||||||
struct goal2sat::imp {
|
struct goal2sat::imp {
|
||||||
struct frame {
|
struct frame {
|
||||||
|
@ -78,8 +79,9 @@ struct goal2sat::imp {
|
||||||
m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
|
m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
void throw_op_not_handled() {
|
void throw_op_not_handled(std::string const& s) {
|
||||||
throw tactic_exception("operator not supported, apply simplifier before invoking translator");
|
std::string s0 = "operator " + s + " not supported, apply simplifier before invoking translator";
|
||||||
|
throw tactic_exception(s0.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void mk_clause(sat::literal l) {
|
void mk_clause(sat::literal l) {
|
||||||
|
@ -183,9 +185,12 @@ struct goal2sat::imp {
|
||||||
case OP_AND:
|
case OP_AND:
|
||||||
case OP_XOR:
|
case OP_XOR:
|
||||||
case OP_IMPLIES:
|
case OP_IMPLIES:
|
||||||
case OP_DISTINCT:
|
case OP_DISTINCT: {
|
||||||
TRACE("goal2sat_not_handled", tout << mk_ismt2_pp(t, m) << "\n";);
|
TRACE("goal2sat_not_handled", tout << mk_ismt2_pp(t, m) << "\n";);
|
||||||
throw_op_not_handled();
|
std::ostringstream strm;
|
||||||
|
strm << mk_ismt2_pp(t, m);
|
||||||
|
throw_op_not_handled(strm.str());
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
convert_atom(t, root, sign);
|
convert_atom(t, root, sign);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -24,7 +24,7 @@ Notes:
|
||||||
|
|
||||||
namespace smt {
|
namespace smt {
|
||||||
|
|
||||||
theory_wmaxsat::theory_wmaxsat(ast_manager& m, ref<filter_model_converter>& mc):
|
theory_wmaxsat::theory_wmaxsat(ast_manager& m, filter_model_converter& mc):
|
||||||
theory(m.mk_family_id("weighted_maxsat")),
|
theory(m.mk_family_id("weighted_maxsat")),
|
||||||
m_mc(mc),
|
m_mc(mc),
|
||||||
m_vars(m),
|
m_vars(m),
|
||||||
|
@ -91,7 +91,7 @@ bool_var theory_wmaxsat::assert_weighted(expr* fml, rational const& w) {
|
||||||
ast_manager& m = get_manager();
|
ast_manager& m = get_manager();
|
||||||
app_ref var(m), wfml(m);
|
app_ref var(m), wfml(m);
|
||||||
var = m.mk_fresh_const("w", m.mk_bool_sort());
|
var = m.mk_fresh_const("w", m.mk_bool_sort());
|
||||||
m_mc->insert(var->get_decl());
|
m_mc.insert(var->get_decl());
|
||||||
wfml = m.mk_or(var, fml);
|
wfml = m.mk_or(var, fml);
|
||||||
ctx.assert_expr(wfml);
|
ctx.assert_expr(wfml);
|
||||||
m_rweights.push_back(w);
|
m_rweights.push_back(w);
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace smt {
|
||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
stats() { reset(); }
|
stats() { reset(); }
|
||||||
};
|
};
|
||||||
ref<filter_model_converter> m_mc;
|
filter_model_converter& m_mc;
|
||||||
mutable unsynch_mpz_manager m_mpz;
|
mutable unsynch_mpz_manager m_mpz;
|
||||||
app_ref_vector m_vars; // Auxiliary variables per soft clause
|
app_ref_vector m_vars; // Auxiliary variables per soft clause
|
||||||
expr_ref_vector m_fmls; // Formulas per soft clause
|
expr_ref_vector m_fmls; // Formulas per soft clause
|
||||||
|
@ -50,7 +50,7 @@ namespace smt {
|
||||||
svector<bool> m_assigned;
|
svector<bool> m_assigned;
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
public:
|
public:
|
||||||
theory_wmaxsat(ast_manager& m, ref<filter_model_converter>& mc);
|
theory_wmaxsat(ast_manager& m, filter_model_converter& mc);
|
||||||
virtual ~theory_wmaxsat();
|
virtual ~theory_wmaxsat();
|
||||||
void get_assignment(svector<bool>& result);
|
void get_assignment(svector<bool>& result);
|
||||||
virtual void init_search_eh();
|
virtual void init_search_eh();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue