mirror of
https://github.com/Z3Prover/z3
synced 2025-08-17 08:42:15 +00:00
merge with master
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
c513f3ca09
883 changed files with 13979 additions and 16480 deletions
|
@ -2,7 +2,6 @@ z3_add_component(opt
|
|||
SOURCES
|
||||
maxres.cpp
|
||||
maxsmt.cpp
|
||||
mss.cpp
|
||||
opt_cmds.cpp
|
||||
opt_context.cpp
|
||||
opt_lns.cpp
|
||||
|
|
|
@ -64,7 +64,7 @@ Notes:
|
|||
#include "opt/opt_params.hpp"
|
||||
#include "opt/maxsmt.h"
|
||||
#include "opt/maxres.h"
|
||||
#include "opt/mss.h"
|
||||
// #include "opt/mss.h"
|
||||
|
||||
using namespace opt;
|
||||
|
||||
|
@ -91,7 +91,6 @@ private:
|
|||
obj_map<expr, rational> m_asm2weight;
|
||||
ptr_vector<expr> m_new_core;
|
||||
mus m_mus;
|
||||
mss m_mss;
|
||||
expr_ref_vector m_trail;
|
||||
strategy_t m_st;
|
||||
rational m_max_upper;
|
||||
|
@ -122,7 +121,6 @@ public:
|
|||
m_index(index),
|
||||
m_B(m), m_asms(m), m_defs(m),
|
||||
m_mus(c.get_solver()),
|
||||
m_mss(c.get_solver(), m),
|
||||
m_trail(m),
|
||||
m_st(st),
|
||||
m_correction_set_size(0),
|
||||
|
@ -244,7 +242,7 @@ public:
|
|||
case l_true:
|
||||
get_current_correction_set(cs);
|
||||
if (cs.empty()) {
|
||||
m_found_feasible_optimum = m_model.get() != 0;
|
||||
m_found_feasible_optimum = m_model.get() != nullptr;
|
||||
m_lower = m_upper;
|
||||
}
|
||||
else {
|
||||
|
@ -448,7 +446,7 @@ public:
|
|||
rational w = split_core(corr_set);
|
||||
cs_max_resolve(corr_set, w);
|
||||
IF_VERBOSE(2, verbose_stream() << "(opt.maxres.correction-set " << corr_set.size() << ")\n";);
|
||||
m_csmodel = 0;
|
||||
m_csmodel = nullptr;
|
||||
m_correction_set_size = 0;
|
||||
}
|
||||
|
||||
|
@ -493,7 +491,7 @@ public:
|
|||
}
|
||||
|
||||
void process_unsat(exprs const& core) {
|
||||
IF_VERBOSE(3, verbose_stream() << "(maxres cs model valid: " << (m_csmodel.get() != 0) << " cs size:" << m_correction_set_size << " core: " << core.size() << ")\n";);
|
||||
IF_VERBOSE(3, verbose_stream() << "(maxres cs model valid: " << (m_csmodel.get() != nullptr) << " cs size:" << m_correction_set_size << " core: " << core.size() << ")\n";);
|
||||
expr_ref fml(m);
|
||||
remove_core(core);
|
||||
SASSERT(!core.empty());
|
||||
|
@ -529,7 +527,7 @@ public:
|
|||
if (m_c.sat_enabled()) {
|
||||
// SAT solver core extracts some model
|
||||
// during unsat core computation.
|
||||
mdl = 0;
|
||||
mdl = nullptr;
|
||||
s().get_model(mdl);
|
||||
}
|
||||
else {
|
||||
|
@ -538,7 +536,7 @@ public:
|
|||
if (mdl.get() && w < m_upper) {
|
||||
update_assignment(mdl.get());
|
||||
}
|
||||
return 0 != mdl.get();
|
||||
return nullptr != mdl.get();
|
||||
}
|
||||
|
||||
lbool minimize_core(exprs& core) {
|
||||
|
@ -728,7 +726,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (upper >= m_upper) {
|
||||
if (upper > m_upper) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -737,6 +735,7 @@ public:
|
|||
}
|
||||
|
||||
m_model = mdl;
|
||||
m_c.model_updated(mdl);
|
||||
|
||||
TRACE("opt", model_smt2_pp(tout << "updated model\n", m, *m_model, 0););
|
||||
|
||||
|
@ -834,7 +833,7 @@ public:
|
|||
m_found_feasible_optimum = false;
|
||||
m_last_index = 0;
|
||||
add_upper_bound_block();
|
||||
m_csmodel = 0;
|
||||
m_csmodel = nullptr;
|
||||
m_correction_set_size = 0;
|
||||
return l_true;
|
||||
}
|
||||
|
@ -858,7 +857,7 @@ public:
|
|||
smt_solver->assert_expr(s().get_assertion(i));
|
||||
}
|
||||
smt_solver->assert_expr(core);
|
||||
lbool is_sat = smt_solver->check_sat(0, 0);
|
||||
lbool is_sat = smt_solver->check_sat(0, nullptr);
|
||||
if (is_sat == l_true) {
|
||||
IF_VERBOSE(0, verbose_stream() << "not a core\n";);
|
||||
}
|
||||
|
@ -878,7 +877,7 @@ public:
|
|||
}
|
||||
smt_solver->assert_expr(n);
|
||||
}
|
||||
lbool is_sat = smt_solver->check_sat(0, 0);
|
||||
lbool is_sat = smt_solver->check_sat(0, nullptr);
|
||||
if (is_sat == l_false) {
|
||||
IF_VERBOSE(0, verbose_stream() << "assignment is infeasible\n";);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace opt {
|
|||
return dynamic_cast<smt::theory_wmaxsat*>(th);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ namespace opt {
|
|||
rational l = m_adjust_value(m_lower);
|
||||
rational u = m_adjust_value(m_upper);
|
||||
if (l > u) std::swap(l, u);
|
||||
verbose_stream() << "(opt." << solver << " [" << l << ":" << u << "])\n";);
|
||||
verbose_stream() << "(opt." << solver << " [" << l << ":" << u << "])\n";);
|
||||
}
|
||||
|
||||
lbool maxsmt_solver_base::find_mutexes(obj_map<expr, rational>& new_soft) {
|
||||
|
@ -228,7 +228,7 @@ namespace opt {
|
|||
|
||||
lbool maxsmt::operator()() {
|
||||
lbool is_sat = l_undef;
|
||||
m_msolver = 0;
|
||||
m_msolver = nullptr;
|
||||
symbol const& maxsat_engine = m_c.maxsat_engine();
|
||||
IF_VERBOSE(1, verbose_stream() << "(maxsmt)\n";);
|
||||
TRACE("opt", tout << "maxsmt\n";
|
||||
|
@ -405,6 +405,10 @@ namespace opt {
|
|||
return m_c.get_solver();
|
||||
}
|
||||
|
||||
void maxsmt::model_updated(model* mdl) {
|
||||
m_c.model_updated(mdl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -72,15 +72,15 @@ namespace opt {
|
|||
public:
|
||||
maxsmt_solver_base(maxsat_context& c, weights_t& ws, expr_ref_vector const& soft);
|
||||
|
||||
virtual ~maxsmt_solver_base() {}
|
||||
virtual rational get_lower() const { return m_lower; }
|
||||
virtual rational get_upper() const { return m_upper; }
|
||||
virtual bool get_assignment(unsigned index) const { return m_assignment[index]; }
|
||||
virtual void collect_statistics(statistics& st) const { }
|
||||
virtual void get_model(model_ref& mdl, svector<symbol>& labels) { mdl = m_model.get(); labels = m_labels;}
|
||||
~maxsmt_solver_base() override {}
|
||||
rational get_lower() const override { return m_lower; }
|
||||
rational get_upper() const override { return m_upper; }
|
||||
bool get_assignment(unsigned index) const override { return m_assignment[index]; }
|
||||
void collect_statistics(statistics& st) const override { }
|
||||
void get_model(model_ref& mdl, svector<symbol>& labels) override { mdl = m_model.get(); labels = m_labels;}
|
||||
virtual void commit_assignment();
|
||||
void set_model() { s().get_model(m_model); s().get_labels(m_labels); }
|
||||
virtual void updt_params(params_ref& p);
|
||||
void updt_params(params_ref& p) override;
|
||||
solver& s();
|
||||
bool init();
|
||||
void set_mus(bool f);
|
||||
|
@ -146,6 +146,7 @@ namespace opt {
|
|||
bool get_assignment(unsigned index) const;
|
||||
void display_answer(std::ostream& out) const;
|
||||
void collect_statistics(statistics& st) const;
|
||||
void model_updated(model* mdl);
|
||||
private:
|
||||
bool is_maxsat_problem(weights_t& ws) const;
|
||||
void verify_assignment();
|
||||
|
|
285
src/opt/mss.cpp
285
src/opt/mss.cpp
|
@ -1,285 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
mss.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
MSS/MCS extraction.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-2-8
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "solver/solver.h"
|
||||
#include "opt/mss.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "model/model_smt2_pp.h"
|
||||
|
||||
namespace opt {
|
||||
|
||||
|
||||
mss::mss(solver& s, ast_manager& m): m_s(s), m(m) {
|
||||
}
|
||||
|
||||
mss::~mss() {
|
||||
}
|
||||
|
||||
bool mss::check_result() {
|
||||
lbool is_sat = m_s.check_sat(m_mss.size(), m_mss.c_ptr());
|
||||
if (is_sat == l_undef) return true;
|
||||
SASSERT(m_mss.empty() || is_sat == l_true);
|
||||
if (is_sat == l_false) return false;
|
||||
expr_set::iterator it = m_mcs.begin(), end = m_mcs.end();
|
||||
for (; it != end; ++it) {
|
||||
m_mss.push_back(*it);
|
||||
is_sat = m_s.check_sat(m_mss.size(), m_mss.c_ptr());
|
||||
m_mss.pop_back();
|
||||
if (is_sat == l_undef) return true;
|
||||
SASSERT(is_sat == l_false);
|
||||
if (is_sat == l_true) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void mss::initialize(exprs& literals) {
|
||||
expr* n;
|
||||
expr_set lits, core_lits;
|
||||
for (unsigned i = 0; i < literals.size(); ++i) {
|
||||
n = literals[i];
|
||||
lits.insert(n);
|
||||
m.is_not(n, n);
|
||||
if (!is_uninterp_const(n)) {
|
||||
throw default_exception("arguments have to be uninterpreted literals");
|
||||
}
|
||||
}
|
||||
exprs rest_core;
|
||||
expr_ref tmp(m);
|
||||
//
|
||||
// the last core is a dummy core. It contains literals that
|
||||
// did not occur in previous cores and did not evaluate to true
|
||||
// in the current model.
|
||||
//
|
||||
for (unsigned i = 0; i < m_cores.size(); ++i) {
|
||||
exprs const& core = m_cores[i];
|
||||
for (unsigned j = 0; j < core.size(); ++j) {
|
||||
expr* n = core[j];
|
||||
if (!core_lits.contains(n)) {
|
||||
core_lits.insert(n);
|
||||
if (m_model->eval(n, tmp) && m.is_true(tmp)) {
|
||||
add_mss(n);
|
||||
}
|
||||
else {
|
||||
m_todo.push_back(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < literals.size(); ++i) {
|
||||
expr* n = literals[i];
|
||||
if (!core_lits.contains(n)) {
|
||||
if (m_model->eval(n, tmp) && m.is_true(tmp)) {
|
||||
m_mss.push_back(n);
|
||||
}
|
||||
else {
|
||||
rest_core.push_back(n);
|
||||
core_lits.insert(n);
|
||||
m_todo.push_back(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_cores.push_back(rest_core);
|
||||
}
|
||||
|
||||
void mss::add_mss(expr* n) {
|
||||
if (!m_mss_set.contains(n)) {
|
||||
m_mss_set.insert(n);
|
||||
m_mss.push_back(n);
|
||||
}
|
||||
}
|
||||
|
||||
void mss::update_core(exprs& core) {
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < core.size(); ++i) {
|
||||
expr* n = core[i];
|
||||
if (!m_mss_set.contains(n)) {
|
||||
if (i != j) {
|
||||
core[j] = core[i];
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
core.resize(j);
|
||||
}
|
||||
|
||||
void mss::update_mss() {
|
||||
expr_ref tmp(m);
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < m_todo.size(); ++i) {
|
||||
expr* n = m_todo[i];
|
||||
SASSERT(!m_mss_set.contains(n));
|
||||
if (m_mcs.contains(n)) {
|
||||
continue; // remove from cores.
|
||||
}
|
||||
if (m_model->eval(n, tmp) && m.is_true(tmp)) {
|
||||
add_mss(n);
|
||||
}
|
||||
else {
|
||||
if (j != i) {
|
||||
m_todo[j] = m_todo[i];
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
m_todo.resize(j);
|
||||
}
|
||||
|
||||
lbool mss::operator()(model* initial_model, vector<exprs> const& _cores, exprs& literals, exprs& mcs) {
|
||||
m_mss.reset();
|
||||
m_todo.reset();
|
||||
m_model = initial_model;
|
||||
m_cores.reset();
|
||||
SASSERT(m_model);
|
||||
m_cores.append(_cores);
|
||||
initialize(literals);
|
||||
TRACE("opt",
|
||||
display_vec(tout << "lits: ", literals.size(), literals.c_ptr());
|
||||
display(tout););
|
||||
lbool is_sat = l_true;
|
||||
for (unsigned i = 0; is_sat == l_true && i < m_cores.size(); ++i) {
|
||||
bool has_mcs = false;
|
||||
bool is_last = i + 1 < m_cores.size();
|
||||
SASSERT(check_invariant());
|
||||
update_core(m_cores[i]); // remove members of mss
|
||||
is_sat = process_core(1, m_cores[i], has_mcs, is_last);
|
||||
}
|
||||
if (is_sat == l_true) {
|
||||
SASSERT(check_invariant());
|
||||
TRACE("opt", display(tout););
|
||||
literals.reset();
|
||||
literals.append(m_mss);
|
||||
mcs.reset();
|
||||
expr_set::iterator it = m_mcs.begin(), end = m_mcs.end();
|
||||
for (; it != end; ++it) {
|
||||
mcs.push_back(*it);
|
||||
}
|
||||
SASSERT(check_result());
|
||||
}
|
||||
m_mcs.reset();
|
||||
m_mss_set.reset();
|
||||
IF_VERBOSE(2, display_vec(verbose_stream() << "mcs: ", mcs.size(), mcs.c_ptr()););
|
||||
return is_sat;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// at least one literal in core is false in current model.
|
||||
// pick literals in core that are not yet in mss.
|
||||
//
|
||||
lbool mss::process_core(unsigned sz, exprs& core, bool& has_mcs, bool is_last) {
|
||||
SASSERT(sz > 0);
|
||||
if (core.empty()) {
|
||||
return l_true;
|
||||
}
|
||||
if (m.canceled()) {
|
||||
return l_undef;
|
||||
}
|
||||
if (sz == 1 && core.size() == 1 && is_last && !has_mcs) {
|
||||
// there has to be at least one false
|
||||
// literal in the core.
|
||||
TRACE("opt", tout << "mcs: " << mk_pp(core[0], m) << "\n";);
|
||||
m_mcs.insert(core[0]);
|
||||
return l_true;
|
||||
}
|
||||
sz = std::min(sz, core.size());
|
||||
TRACE("opt", display_vec(tout << "process (total " << core.size() << ") :", sz, core.c_ptr()););
|
||||
unsigned sz_save = m_mss.size();
|
||||
m_mss.append(sz, core.c_ptr());
|
||||
lbool is_sat = m_s.check_sat(m_mss.size(), m_mss.c_ptr());
|
||||
IF_VERBOSE(3, display_vec(verbose_stream() << "mss: ", m_mss.size(), m_mss.c_ptr()););
|
||||
m_mss.resize(sz_save);
|
||||
switch (is_sat) {
|
||||
case l_true:
|
||||
m_s.get_model(m_model);
|
||||
update_mss();
|
||||
DEBUG_CODE(
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
SASSERT(m_mss_set.contains(core[i]));
|
||||
});
|
||||
update_core(core);
|
||||
return process_core(2*sz, core, has_mcs, is_last);
|
||||
case l_false:
|
||||
if (sz == 1) {
|
||||
has_mcs = true;
|
||||
m_mcs.insert(core[0]);
|
||||
core[0] = core.back();
|
||||
core.pop_back();
|
||||
}
|
||||
else {
|
||||
exprs core2;
|
||||
core2.append(core.size()-sz, core.c_ptr()+sz);
|
||||
core.resize(sz);
|
||||
is_sat = process_core(sz, core2, has_mcs, false);
|
||||
if (is_sat != l_true) {
|
||||
return is_sat;
|
||||
}
|
||||
update_core(core);
|
||||
}
|
||||
return process_core(1, core, has_mcs, is_last);
|
||||
case l_undef:
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
return l_true;
|
||||
}
|
||||
|
||||
void mss::display_vec(std::ostream& out, unsigned sz, expr* const* args) const {
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
out << mk_pp(args[i], m) << " ";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
void mss::display(std::ostream& out) const {
|
||||
for (unsigned i = 0; i < m_cores.size(); ++i) {
|
||||
display_vec(out << "core: ", m_cores[i].size(), m_cores[i].c_ptr());
|
||||
}
|
||||
expr_set::iterator it = m_mcs.begin(), end = m_mcs.end();
|
||||
out << "mcs:\n";
|
||||
for (; it != end; ++it) {
|
||||
out << mk_pp(*it, m) << "\n";
|
||||
}
|
||||
out << "\n";
|
||||
out << "mss:\n";
|
||||
for (unsigned i = 0; i < m_mss.size(); ++i) {
|
||||
out << mk_pp(m_mss[i], m) << "\n";
|
||||
}
|
||||
out << "\n";
|
||||
if (m_model) {
|
||||
model_smt2_pp(out, m, *(m_model.get()), 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool mss::check_invariant() const {
|
||||
if (!m_model) return true;
|
||||
expr_ref tmp(m);
|
||||
for (unsigned i = 0; i < m_mss.size(); ++i) {
|
||||
expr* n = m_mss[i];
|
||||
if (!m_model->eval(n, tmp)) return true;
|
||||
CTRACE("opt", !m.is_true(tmp), tout << mk_pp(n, m) << " |-> " << mk_pp(tmp, m) << "\n";);
|
||||
SASSERT(!m.is_false(tmp));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
mss.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Maximal satisfying subset/minimal correction sets: MSS/MCS
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-2-8
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef MSS_H_
|
||||
#define MSS_H_
|
||||
|
||||
namespace opt {
|
||||
class mss {
|
||||
solver& m_s;
|
||||
ast_manager& m;
|
||||
typedef ptr_vector<expr> exprs;
|
||||
typedef obj_hashtable<expr> expr_set;
|
||||
exprs m_mss;
|
||||
expr_set m_mcs;
|
||||
expr_set m_mss_set;
|
||||
vector<exprs> m_cores;
|
||||
exprs m_todo;
|
||||
model_ref m_model;
|
||||
public:
|
||||
mss(solver& s, ast_manager& m);
|
||||
~mss();
|
||||
|
||||
lbool operator()(model* initial_model, vector<exprs> const& cores, exprs& literals, exprs& mcs);
|
||||
|
||||
|
||||
void get_model(model_ref& mdl) { mdl = m_model; }
|
||||
|
||||
private:
|
||||
void initialize(exprs& literals);
|
||||
bool check_result();
|
||||
void add_mss(expr* n);
|
||||
void update_mss();
|
||||
void update_core(exprs& core);
|
||||
lbool process_core(unsigned sz, exprs& core, bool& has_mcs, bool is_last);
|
||||
void display(std::ostream& out) const;
|
||||
void display_vec(std::ostream& out, unsigned sz, expr* const* args) const;
|
||||
bool check_invariant() const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -52,7 +52,7 @@ public:
|
|||
assert_soft_cmd(opt::context* opt):
|
||||
parametric_cmd("assert-soft"),
|
||||
m_idx(0),
|
||||
m_formula(0),
|
||||
m_formula(nullptr),
|
||||
m_opt(opt)
|
||||
{}
|
||||
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
virtual void reset(cmd_context & ctx) {
|
||||
m_idx = 0;
|
||||
m_formula = 0;
|
||||
m_formula = nullptr;
|
||||
}
|
||||
|
||||
virtual char const * get_usage() const { return "<formula> [:weight <rational-weight>] [:id <symbol>]"; }
|
||||
|
|
|
@ -23,7 +23,7 @@ Notes:
|
|||
|
||||
class cmd_context;
|
||||
|
||||
void install_opt_cmds(cmd_context & ctx, opt::context* opt = 0);
|
||||
void install_opt_cmds(cmd_context & ctx, opt::context* opt = nullptr);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -122,7 +122,8 @@ namespace opt {
|
|||
m_arith(m),
|
||||
m_bv(m),
|
||||
m_hard_constraints(m),
|
||||
m_solver(0),
|
||||
m_solver(nullptr),
|
||||
m_pareto1(false),
|
||||
m_box_index(UINT_MAX),
|
||||
m_optsmt(m),
|
||||
m_scoped_state(m),
|
||||
|
@ -138,6 +139,7 @@ namespace opt {
|
|||
p.set_bool("unsat_core", true);
|
||||
p.set_bool("elim_to_real", true);
|
||||
updt_params(p);
|
||||
m_model_counter = 0;
|
||||
}
|
||||
|
||||
context::~context() {
|
||||
|
@ -279,16 +281,15 @@ namespace opt {
|
|||
if (pri == symbol("lns")) {
|
||||
return execute_lns();
|
||||
}
|
||||
|
||||
IF_VERBOSE(1, verbose_stream() << "(optimize:check-sat)\n");
|
||||
lbool is_sat = s.check_sat(0,0);
|
||||
TRACE("opt", s.display(tout << "initial search result: " << is_sat << "\n"););
|
||||
display_benchmark();
|
||||
IF_VERBOSE(1, verbose_stream() << "(optimize:check-sat)\n";);
|
||||
lbool is_sat = s.check_sat(0,nullptr);
|
||||
TRACE("opt", tout << "initial search result: " << is_sat << "\n";
|
||||
s.display(tout););
|
||||
if (is_sat != l_false) {
|
||||
s.get_model(m_model);
|
||||
s.get_labels(m_labels);
|
||||
if (is_sat == l_true) {
|
||||
validate_model();
|
||||
}
|
||||
model_updated(m_model.get());
|
||||
}
|
||||
if (is_sat != l_true) {
|
||||
TRACE("opt", tout << m_hard_constraints << "\n";);
|
||||
|
@ -303,7 +304,14 @@ namespace opt {
|
|||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
is_sat = execute(m_objectives[0], true, false);
|
||||
if (m_pareto1) {
|
||||
is_sat = l_false;
|
||||
m_pareto1 = false;
|
||||
}
|
||||
else {
|
||||
m_pareto1 = (pri == symbol("pareto"));
|
||||
is_sat = execute(m_objectives[0], true, false);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
opt_params optp(m_params);
|
||||
|
@ -318,9 +326,9 @@ namespace opt {
|
|||
is_sat = execute_box();
|
||||
}
|
||||
else {
|
||||
is_sat = execute_lex();
|
||||
m_pareto1 = (pri == symbol("pareto"));
|
||||
is_sat = execute(m_objectives[0], true, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_sat == l_true) validate_model();
|
||||
|
@ -358,12 +366,24 @@ namespace opt {
|
|||
fix_model(mdl);
|
||||
}
|
||||
|
||||
bool context::contains_quantifiers() const {
|
||||
for (expr* f : m_hard_constraints) {
|
||||
if (has_quantifiers(f)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
lbool context::execute_min_max(unsigned index, bool committed, bool scoped, bool is_max) {
|
||||
if (scoped) get_solver().push();
|
||||
lbool result = m_optsmt.lex(index, is_max);
|
||||
if (result == l_true) m_optsmt.get_model(m_model, m_labels);
|
||||
if (scoped) get_solver().pop(1);
|
||||
if (result == l_true && committed) m_optsmt.commit_assignment(index);
|
||||
if (result == l_true && m_optsmt.is_unbounded(index, is_max) && contains_quantifiers()) {
|
||||
throw default_exception("unbounded objectives on quantified constraints is not supported");
|
||||
result = l_undef;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -396,8 +416,8 @@ namespace opt {
|
|||
*/
|
||||
bool context::scoped_lex() {
|
||||
if (m_maxsat_engine == symbol("maxres")) {
|
||||
for (unsigned i = 0; i < m_objectives.size(); ++i) {
|
||||
if (m_objectives[i].m_type != O_MAXSMT) return true;
|
||||
for (auto const& o : m_objectives) {
|
||||
if (o.m_type != O_MAXSMT) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -407,14 +427,16 @@ namespace opt {
|
|||
lbool context::execute_lex() {
|
||||
lbool r = l_true;
|
||||
bool sc = scoped_lex();
|
||||
IF_VERBOSE(1, verbose_stream() << "(optsmt:lex)\n";);
|
||||
for (unsigned i = 0; r == l_true && i < m_objectives.size(); ++i) {
|
||||
bool is_last = i + 1 == m_objectives.size();
|
||||
r = execute(m_objectives[i], i + 1 < m_objectives.size(), sc && !is_last);
|
||||
IF_VERBOSE(1, verbose_stream() << "(opt :lex)\n";);
|
||||
unsigned sz = m_objectives.size();
|
||||
for (unsigned i = 0; r == l_true && i < sz; ++i) {
|
||||
objective const& o = m_objectives[i];
|
||||
bool is_last = i + 1 == sz;
|
||||
r = execute(o, i + 1 < sz, sc && !is_last && o.m_type != O_MAXSMT);
|
||||
if (r == l_true && !get_lower_as_num(i).is_finite()) {
|
||||
return r;
|
||||
}
|
||||
if (r == l_true && i + 1 < m_objectives.size()) {
|
||||
if (r == l_true && i + 1 < sz) {
|
||||
update_lower();
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +451,7 @@ namespace opt {
|
|||
return l_true;
|
||||
}
|
||||
if (m_box_index < m_objectives.size()) {
|
||||
m_model = 0;
|
||||
m_model = nullptr;
|
||||
++m_box_index;
|
||||
return l_undef;
|
||||
}
|
||||
|
@ -678,8 +700,7 @@ namespace opt {
|
|||
expr_fast_mark1 visited;
|
||||
is_bv proc(m);
|
||||
try {
|
||||
for (unsigned i = 0; i < m_objectives.size(); ++i) {
|
||||
objective & obj = m_objectives[i];
|
||||
for (objective& obj : m_objectives) {
|
||||
if (obj.m_type != O_MAXSMT) return false;
|
||||
maxsmt& ms = *m_maxsmts.find(obj.m_id);
|
||||
for (unsigned j = 0; j < ms.size(); ++j) {
|
||||
|
@ -690,8 +711,8 @@ namespace opt {
|
|||
for (unsigned i = 0; i < sz; i++) {
|
||||
quick_for_each_expr(proc, visited, get_solver().get_assertion(i));
|
||||
}
|
||||
for (unsigned i = 0; i < m_hard_constraints.size(); ++i) {
|
||||
quick_for_each_expr(proc, visited, m_hard_constraints[i].get());
|
||||
for (expr* f : m_hard_constraints) {
|
||||
quick_for_each_expr(proc, visited, f);
|
||||
}
|
||||
}
|
||||
catch (is_bv::found) {
|
||||
|
@ -937,7 +958,7 @@ namespace opt {
|
|||
func_decl* f = m.mk_fresh_func_decl(name,"", domain.size(), domain.c_ptr(), m.mk_bool_sort());
|
||||
m_objective_fns.insert(f, index);
|
||||
m_objective_refs.push_back(f);
|
||||
m_objective_orig.insert(f, sz > 0 ? args[0] : 0);
|
||||
m_objective_orig.insert(f, sz > 0 ? args[0] : nullptr);
|
||||
return m.mk_app(f, sz, args);
|
||||
}
|
||||
|
||||
|
@ -979,7 +1000,7 @@ namespace opt {
|
|||
}
|
||||
mk_atomic(terms);
|
||||
SASSERT(obj.m_id == id);
|
||||
obj.m_term = orig_term?to_app(orig_term):0;
|
||||
obj.m_term = orig_term?to_app(orig_term):nullptr;
|
||||
obj.m_terms.reset();
|
||||
obj.m_terms.append(terms);
|
||||
obj.m_weights.reset();
|
||||
|
@ -1038,6 +1059,22 @@ namespace opt {
|
|||
}
|
||||
}
|
||||
|
||||
void context::model_updated(model* md) {
|
||||
opt_params optp(m_params);
|
||||
symbol prefix = optp.solution_prefix();
|
||||
if (prefix == symbol::null || prefix == symbol("")) return;
|
||||
model_ref mdl = md->copy();
|
||||
fix_model(mdl);
|
||||
std::ostringstream buffer;
|
||||
buffer << prefix << (m_model_counter++) << ".smt2";
|
||||
std::ofstream out(buffer.str());
|
||||
if (out) {
|
||||
model_smt2_pp(out, m, *mdl, 0);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool context::verify_model(unsigned index, model* md, rational const& _v) {
|
||||
rational r;
|
||||
app_ref term = m_objectives[index].m_term;
|
||||
|
@ -1046,10 +1083,6 @@ namespace opt {
|
|||
}
|
||||
rational v = m_objectives[index].m_adjust_value(_v);
|
||||
expr_ref val(m);
|
||||
//
|
||||
// we have to clone the model so that maxsat solver can use
|
||||
// internal variables that are otherwise deleted from the model.
|
||||
//
|
||||
model_ref mdl = md->copy();
|
||||
fix_model(mdl);
|
||||
|
||||
|
@ -1277,6 +1310,9 @@ namespace opt {
|
|||
}
|
||||
|
||||
void context::display_assignment(std::ostream& out) {
|
||||
if (m_scoped_state.m_objectives.size() != m_objectives.size()) {
|
||||
throw default_exception("check-sat has not been called with latest objectives");
|
||||
}
|
||||
out << "(objectives\n";
|
||||
for (unsigned i = 0; i < m_scoped_state.m_objectives.size(); ++i) {
|
||||
objective const& obj = m_scoped_state.m_objectives[i];
|
||||
|
@ -1408,6 +1444,7 @@ namespace opt {
|
|||
|
||||
void context::set_pareto(pareto_base* p) {
|
||||
m_pareto = p;
|
||||
m_pareto1 = p != nullptr;
|
||||
}
|
||||
|
||||
void context::collect_statistics(statistics& stats) const {
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace opt {
|
|||
virtual unsigned num_objectives() = 0;
|
||||
virtual bool verify_model(unsigned id, model* mdl, rational const& v) = 0;
|
||||
virtual void set_model(model_ref& _m) = 0;
|
||||
virtual void model_updated(model* mdl) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -146,8 +147,9 @@ namespace opt {
|
|||
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;
|
||||
scoped_ptr<lns> m_lns;
|
||||
bool m_pareto1;
|
||||
scoped_ptr<qe::qmax> m_qmax;
|
||||
sref_vector<model> m_box_models;
|
||||
unsigned m_box_index;
|
||||
|
@ -156,9 +158,10 @@ namespace opt {
|
|||
map_t m_maxsmts;
|
||||
scoped_state m_scoped_state;
|
||||
vector<objective> m_objectives;
|
||||
model_ref m_model;
|
||||
model_ref m_model;
|
||||
model_converter_ref m_model_converter;
|
||||
generic_model_converter_ref m_fm;
|
||||
unsigned m_model_counter;
|
||||
obj_map<func_decl, unsigned> m_objective_fns;
|
||||
obj_map<func_decl, expr*> m_objective_orig;
|
||||
func_decl_ref_vector m_objective_refs;
|
||||
|
@ -173,7 +176,7 @@ namespace opt {
|
|||
std::string m_unknown;
|
||||
public:
|
||||
context(ast_manager& m);
|
||||
virtual ~context();
|
||||
~context() override;
|
||||
unsigned add_soft_constraint(expr* f, rational const& w, symbol const& id);
|
||||
unsigned add_objective(app* t, bool is_max);
|
||||
void add_hard_constraint(expr* f);
|
||||
|
@ -181,6 +184,7 @@ namespace opt {
|
|||
void get_hard_constraints(expr_ref_vector& hard);
|
||||
expr_ref get_objective(unsigned i);
|
||||
|
||||
#if 0
|
||||
virtual void push();
|
||||
virtual void pop(unsigned n);
|
||||
virtual bool empty() { return m_scoped_state.m_objectives.empty(); }
|
||||
|
@ -200,11 +204,32 @@ namespace opt {
|
|||
virtual void display_assignment(std::ostream& out);
|
||||
virtual bool is_pareto() { return m_pareto.get() != 0; }
|
||||
virtual void set_logic(symbol const& s) { m_logic = s; }
|
||||
#endif
|
||||
void push() override;
|
||||
void pop(unsigned n) override;
|
||||
bool empty() override { return m_scoped_state.m_objectives.empty(); }
|
||||
void set_hard_constraints(ptr_vector<expr> & hard) override;
|
||||
lbool optimize() override;
|
||||
void set_model(model_ref& _m) override { m_model = _m; }
|
||||
void get_model_core(model_ref& _m) override;
|
||||
void get_box_model(model_ref& _m, unsigned index) override;
|
||||
void fix_model(model_ref& _m) override;
|
||||
void collect_statistics(statistics& stats) const override;
|
||||
proof* get_proof() override { return nullptr; }
|
||||
void get_labels(svector<symbol> & r) override;
|
||||
void get_unsat_core(ptr_vector<expr> & r) override;
|
||||
std::string reason_unknown() const override;
|
||||
void set_reason_unknown(char const* msg) override { m_unknown = msg; }
|
||||
|
||||
void display_assignment(std::ostream& out) override;
|
||||
bool is_pareto() override { return m_pareto.get() != nullptr; }
|
||||
void set_logic(symbol const& s) override { m_logic = s; }
|
||||
|
||||
void set_clausal(bool f) { m_is_clausal = f; }
|
||||
|
||||
void display(std::ostream& out);
|
||||
static void collect_param_descrs(param_descrs & r);
|
||||
virtual void updt_params(params_ref const& p);
|
||||
void updt_params(params_ref const& p) override;
|
||||
params_ref& get_params() { return m_params; }
|
||||
|
||||
expr_ref get_lower(unsigned idx);
|
||||
|
@ -216,13 +241,13 @@ namespace opt {
|
|||
std::string to_string() const;
|
||||
|
||||
|
||||
virtual unsigned num_objectives() { return m_scoped_state.m_objectives.size(); }
|
||||
virtual expr_ref mk_gt(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);
|
||||
unsigned num_objectives() override { return m_scoped_state.m_objectives.size(); }
|
||||
expr_ref mk_gt(unsigned i, model_ref& model) override;
|
||||
expr_ref mk_ge(unsigned i, model_ref& model) override;
|
||||
expr_ref mk_le(unsigned i, model_ref& model) override;
|
||||
|
||||
#if 0
|
||||
virtual smt::context& smt_context() { return m_opt_solver->get_context(); }
|
||||
virtual generic_model_converter& fm() { return *m_fm; }
|
||||
virtual bool sat_enabled() const { return 0 != m_sat_solver.get(); }
|
||||
virtual solver& get_solver();
|
||||
virtual ast_manager& get_manager() const { return this->m; }
|
||||
|
@ -230,15 +255,27 @@ namespace opt {
|
|||
virtual void enable_sls(bool force);
|
||||
virtual symbol const& maxsat_engine() const { return m_maxsat_engine; }
|
||||
virtual void get_base_model(model_ref& _m);
|
||||
#endif
|
||||
generic_model_converter& fm() override { return *m_fm; }
|
||||
smt::context& smt_context() override { return m_opt_solver->get_context(); }
|
||||
bool sat_enabled() const override { return nullptr != m_sat_solver.get(); }
|
||||
solver& get_solver() override;
|
||||
ast_manager& get_manager() const override { return this->m; }
|
||||
params_ref& params() override { return m_params; }
|
||||
void enable_sls(bool force) override;
|
||||
symbol const& maxsat_engine() const override { return m_maxsat_engine; }
|
||||
void get_base_model(model_ref& _m) override;
|
||||
|
||||
|
||||
virtual bool verify_model(unsigned id, model* mdl, rational const& v);
|
||||
bool verify_model(unsigned id, model* mdl, rational const& v) override;
|
||||
|
||||
void model_updated(model* mdl) override;
|
||||
|
||||
void get_lns_literals(expr_ref_vector& lits);
|
||||
|
||||
private:
|
||||
lbool execute(objective const& obj, bool committed, bool scoped);
|
||||
lbool execute_min_max(unsigned index, bool committed, bool scoped, bool is_max);
|
||||
lbool execute_min_max(unsigned index, bool committed, bool scoped, bool is_max);
|
||||
lbool execute_maxsat(symbol const& s, bool committed, bool scoped);
|
||||
lbool execute_lex();
|
||||
lbool execute_box();
|
||||
|
@ -246,6 +283,7 @@ namespace opt {
|
|||
lbool execute_lns();
|
||||
lbool adjust_unknown(lbool r);
|
||||
bool scoped_lex();
|
||||
bool contains_quantifiers() const;
|
||||
expr_ref to_expr(inf_eps const& n);
|
||||
void to_exprs(inf_eps const& n, expr_ref_vector& es);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ def_module_params('opt',
|
|||
('maxsat_engine', SYMBOL, 'maxres', "select engine for maxsat: 'core_maxsat', 'wmax', 'maxres', 'pd-maxres'"),
|
||||
('priority', SYMBOL, 'lex', "select how to priortize objectives: 'lex' (lexicographic), 'pareto', 'box', or 'lns' (large neighborhood search)"),
|
||||
('dump_benchmarks', BOOL, False, 'dump benchmarks for profiling'),
|
||||
('solution_prefix', SYMBOL, '', "path prefix to dump intermediary, but non-optimal, solutions"),
|
||||
('timeout', UINT, UINT_MAX, 'timeout (in milliseconds) (UINT_MAX and 0 mean no timeout)'),
|
||||
('rlimit', UINT, 0, 'resource limit (0 means no limit)'),
|
||||
('enable_sls', BOOL, False, 'enable SLS tuning during weighted maxsast'),
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace opt {
|
|||
|
||||
lbool gia_pareto::operator()() {
|
||||
expr_ref fml(m);
|
||||
lbool is_sat = m_solver->check_sat(0, 0);
|
||||
lbool is_sat = m_solver->check_sat(0, nullptr);
|
||||
if (is_sat == l_true) {
|
||||
{
|
||||
solver::scoped_push _s(*m_solver.get());
|
||||
|
@ -45,7 +45,7 @@ namespace opt {
|
|||
model_smt2_pp(verbose_stream() << "new model:\n", m, *mdl, 0););
|
||||
// TBD: we can also use local search to tune solution coordinate-wise.
|
||||
mk_dominates();
|
||||
is_sat = m_solver->check_sat(0, 0);
|
||||
is_sat = m_solver->check_sat(0, nullptr);
|
||||
}
|
||||
}
|
||||
if (is_sat == l_undef) {
|
||||
|
@ -91,7 +91,7 @@ namespace opt {
|
|||
|
||||
lbool oia_pareto::operator()() {
|
||||
solver::scoped_push _s(*m_solver.get());
|
||||
lbool is_sat = m_solver->check_sat(0, 0);
|
||||
lbool is_sat = m_solver->check_sat(0, nullptr);
|
||||
if (m.canceled()) {
|
||||
is_sat = l_undef;
|
||||
}
|
||||
|
|
|
@ -87,9 +87,9 @@ namespace opt {
|
|||
params_ref & p):
|
||||
pareto_base(m, cb, s, p) {
|
||||
}
|
||||
virtual ~gia_pareto() {}
|
||||
~gia_pareto() override {}
|
||||
|
||||
virtual lbool operator()();
|
||||
lbool operator()() override;
|
||||
};
|
||||
|
||||
// opportunistic improvement algorithm.
|
||||
|
@ -101,9 +101,9 @@ namespace opt {
|
|||
params_ref & p):
|
||||
pareto_base(m, cb, s, p) {
|
||||
}
|
||||
virtual ~oia_pareto() {}
|
||||
~oia_pareto() override {}
|
||||
|
||||
virtual lbool operator()();
|
||||
lbool operator()() override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ public:
|
|||
|
||||
|
||||
|
||||
|
||||
bool opt_stream_buffer::parse_token(char const* token) {
|
||||
skip_whitespace();
|
||||
char const* t = token;
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace opt {
|
|||
|
||||
solver* opt_solver::translate(ast_manager& m, params_ref const& p) {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void opt_solver::collect_param_descrs(param_descrs & r) {
|
||||
|
@ -227,9 +227,13 @@ namespace opt {
|
|||
smt::theory_var v = m_objective_vars[i];
|
||||
bool has_shared = false;
|
||||
inf_eps val = get_optimizer().maximize(v, blocker, has_shared);
|
||||
get_model(m_model);
|
||||
inf_eps val2;
|
||||
m_valid_objectives[i] = true;
|
||||
TRACE("opt", tout << (has_shared?"has shared":"non-shared") << "\n";);
|
||||
if (!m_models[i]) {
|
||||
set_model(i);
|
||||
}
|
||||
if (m_context.get_context().update_model(has_shared)) {
|
||||
if (has_shared && val != current_objective_value(i)) {
|
||||
decrement_value(i, val);
|
||||
|
@ -247,7 +251,7 @@ namespace opt {
|
|||
tout << "objective: " << mk_pp(m_objective_terms[i].get(), m) << "\n";
|
||||
tout << "maximal value: " << val << "\n";
|
||||
tout << "new condition: " << blocker << "\n";
|
||||
model_smt2_pp(tout << "update model:\n", m, *m_models[i], 0); });
|
||||
if (m_models[i]) model_smt2_pp(tout << "update model:\n", m, *m_models[i], 0); });
|
||||
}
|
||||
|
||||
void opt_solver::set_model(unsigned i) {
|
||||
|
@ -261,7 +265,7 @@ namespace opt {
|
|||
expr_ref ge = mk_ge(i, val);
|
||||
TRACE("opt", tout << ge << "\n";);
|
||||
assert_expr(ge);
|
||||
lbool is_sat = m_context.check(0, 0);
|
||||
lbool is_sat = m_context.check(0, nullptr);
|
||||
is_sat = adjust_result(is_sat);
|
||||
if (is_sat == l_true) {
|
||||
set_model(i);
|
||||
|
@ -299,6 +303,7 @@ namespace opt {
|
|||
|
||||
void opt_solver::get_model_core(model_ref & m) {
|
||||
m_context.get_model(m);
|
||||
if (!m) m = m_model; else m_model = m;
|
||||
}
|
||||
|
||||
proof * opt_solver::get_proof() {
|
||||
|
@ -316,7 +321,7 @@ namespace opt {
|
|||
void opt_solver::get_labels(svector<symbol> & r) {
|
||||
r.reset();
|
||||
buffer<symbol> tmp;
|
||||
m_context.get_relevant_labels(0, tmp);
|
||||
m_context.get_relevant_labels(nullptr, tmp);
|
||||
r.append(tmp.size(), tmp.c_ptr());
|
||||
}
|
||||
|
||||
|
@ -340,7 +345,7 @@ namespace opt {
|
|||
m_objective_values.push_back(inf_eps(rational(-1), inf_rational()));
|
||||
m_objective_terms.push_back(term);
|
||||
m_valid_objectives.push_back(true);
|
||||
m_models.push_back(0);
|
||||
m_models.push_back(nullptr);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ namespace opt {
|
|||
generic_model_converter& m_fm;
|
||||
progress_callback * m_callback;
|
||||
symbol m_logic;
|
||||
model_ref m_model;
|
||||
svector<smt::theory_var> m_objective_vars;
|
||||
vector<inf_eps> m_objective_values;
|
||||
sref_vector<model> m_models;
|
||||
|
@ -85,6 +86,31 @@ namespace opt {
|
|||
bool m_was_unknown;
|
||||
public:
|
||||
opt_solver(ast_manager & m, params_ref const & p, generic_model_converter& fm);
|
||||
~opt_solver() override;
|
||||
|
||||
solver* translate(ast_manager& m, params_ref const& p) override;
|
||||
void updt_params(params_ref const& p) override;
|
||||
void collect_param_descrs(param_descrs & r) override;
|
||||
void collect_statistics(statistics & st) const override;
|
||||
void assert_expr_core(expr * t) override;
|
||||
void push_core() override;
|
||||
void pop_core(unsigned n) override;
|
||||
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override;
|
||||
void get_unsat_core(ptr_vector<expr> & r) override;
|
||||
void get_model_core(model_ref & _m) override;
|
||||
proof * get_proof() override;
|
||||
std::string reason_unknown() const override;
|
||||
void set_reason_unknown(char const* msg) override;
|
||||
void get_labels(svector<symbol> & r) override;
|
||||
void set_progress_callback(progress_callback * callback) override;
|
||||
unsigned get_num_assertions() const override;
|
||||
expr * get_assertion(unsigned idx) const override;
|
||||
ast_manager& get_manager() const override { return m; }
|
||||
lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) override;
|
||||
lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores) override;
|
||||
expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); }
|
||||
|
||||
#if 0
|
||||
virtual ~opt_solver();
|
||||
|
||||
virtual solver* translate(ast_manager& m, params_ref const& p);
|
||||
|
@ -108,7 +134,7 @@ namespace opt {
|
|||
virtual ast_manager& get_manager() const { return m; }
|
||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes);
|
||||
virtual lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores);
|
||||
virtual expr_ref_vector cube(expr_ref_vector&, unsigned) { return expr_ref_vector(m); }
|
||||
#endif
|
||||
void set_logic(symbol const& logic);
|
||||
|
||||
smt::theory_var add_objective(app* term);
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace opt {
|
|||
while (!m.canceled()) {
|
||||
SASSERT(delta_per_step.is_int());
|
||||
SASSERT(delta_per_step.is_pos());
|
||||
is_sat = m_s->check_sat(0, 0);
|
||||
is_sat = m_s->check_sat(0, nullptr);
|
||||
if (is_sat == l_true) {
|
||||
bound = update_lower();
|
||||
if (!get_max_delta(lower, delta_index)) {
|
||||
|
@ -161,6 +161,14 @@ namespace opt {
|
|||
return l_true;
|
||||
}
|
||||
|
||||
bool optsmt::is_unbounded(unsigned obj_index, bool is_maximize) {
|
||||
if (is_maximize) {
|
||||
return !m_upper[obj_index].is_finite();
|
||||
}
|
||||
else {
|
||||
return !m_lower[obj_index].is_finite();
|
||||
}
|
||||
}
|
||||
|
||||
lbool optsmt::geometric_lex(unsigned obj_index, bool is_maximize) {
|
||||
arith_util arith(m);
|
||||
|
@ -180,7 +188,7 @@ namespace opt {
|
|||
while (!m.canceled()) {
|
||||
SASSERT(delta_per_step.is_int());
|
||||
SASSERT(delta_per_step.is_pos());
|
||||
is_sat = m_s->check_sat(0, 0);
|
||||
is_sat = m_s->check_sat(0, nullptr);
|
||||
if (is_sat == l_true) {
|
||||
m_s->maximize_objective(obj_index, bound);
|
||||
m_s->get_model(m_model);
|
||||
|
@ -408,7 +416,7 @@ namespace opt {
|
|||
bounds.push_back(bound);
|
||||
}
|
||||
else {
|
||||
bounds.push_back(0);
|
||||
bounds.push_back(nullptr);
|
||||
mid.push_back(inf_eps());
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +429,7 @@ namespace opt {
|
|||
case l_true:
|
||||
IF_VERBOSE(2, verbose_stream() << "(optsmt lower bound for v" << m_vars[i] << " := " << m_upper[i] << ")\n";);
|
||||
m_lower[i] = mid[i];
|
||||
th.enable_record_conflict(0);
|
||||
th.enable_record_conflict(nullptr);
|
||||
m_s->assert_expr(update_lower());
|
||||
break;
|
||||
case l_false:
|
||||
|
@ -436,10 +444,10 @@ namespace opt {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
th.enable_record_conflict(0);
|
||||
th.enable_record_conflict(nullptr);
|
||||
return l_undef;
|
||||
}
|
||||
th.enable_record_conflict(0);
|
||||
th.enable_record_conflict(nullptr);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
@ -497,7 +505,7 @@ namespace opt {
|
|||
commit_assignment(i);
|
||||
}
|
||||
while (is_sat == l_true && !m.canceled()) {
|
||||
is_sat = m_s->check_sat(0, 0);
|
||||
is_sat = m_s->check_sat(0, nullptr);
|
||||
if (is_sat != l_true) break;
|
||||
|
||||
m_s->maximize_objective(obj_index, bound);
|
||||
|
@ -591,7 +599,7 @@ namespace opt {
|
|||
m_lower.push_back(inf_eps(rational(-1),inf_rational(0)));
|
||||
m_upper.push_back(inf_eps(rational(1), inf_rational(0)));
|
||||
m_lower_fmls.push_back(m.mk_true());
|
||||
m_models.push_back(0);
|
||||
m_models.push_back(nullptr);
|
||||
return m_objs.size()-1;
|
||||
}
|
||||
|
||||
|
@ -607,7 +615,7 @@ namespace opt {
|
|||
m_vars.reset();
|
||||
m_model.reset();
|
||||
m_lower_fmls.reset();
|
||||
m_s = 0;
|
||||
m_s = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace opt {
|
|||
sref_vector<model> m_models;
|
||||
public:
|
||||
optsmt(ast_manager& m):
|
||||
m(m), m_s(0), m_objs(m), m_lower_fmls(m) {}
|
||||
m(m), m_s(nullptr), m_objs(m), m_lower_fmls(m) {}
|
||||
|
||||
void setup(opt_solver& solver);
|
||||
|
||||
|
@ -49,6 +49,8 @@ namespace opt {
|
|||
|
||||
lbool lex(unsigned obj_index, bool is_maximize);
|
||||
|
||||
bool is_unbounded(unsigned obj_index, bool is_maximize);
|
||||
|
||||
unsigned add(app* t);
|
||||
|
||||
void updt_params(params_ref& p);
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace opt {
|
|||
while (l_true == is_sat && first < out.size() && m_lower < m_upper) {
|
||||
trace_bounds("sortmax");
|
||||
s().assert_expr(out[first]);
|
||||
is_sat = s().check_sat(0, 0);
|
||||
is_sat = s().check_sat(0, nullptr);
|
||||
TRACE("opt", tout << is_sat << "\n"; s().display(tout); tout << "\n";);
|
||||
if (m.canceled()) {
|
||||
is_sat = l_undef;
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace opt {
|
|||
while (!m.canceled() && m_lower < m_upper) {
|
||||
//mk_assumptions(asms);
|
||||
//is_sat = s().preferred_sat(asms, cores);
|
||||
is_sat = s().check_sat(0, 0);
|
||||
is_sat = s().check_sat(0, nullptr);
|
||||
if (m.canceled()) {
|
||||
is_sat = l_undef;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ namespace opt {
|
|||
void verify_core(expr_ref_vector const& core) {
|
||||
s().push();
|
||||
s().assert_expr(core);
|
||||
VERIFY(l_false == s().check_sat(0, 0));
|
||||
VERIFY(l_false == s().check_sat(0, nullptr));
|
||||
s().pop(1);
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ namespace opt {
|
|||
rational remove_negations(smt::theory_wmaxsat& th, expr_ref_vector const& core, ptr_vector<expr>& keys, vector<rational>& weights) {
|
||||
rational min_weight(-1);
|
||||
for (unsigned i = 0; i < core.size(); ++i) {
|
||||
expr* e = 0;
|
||||
expr* e = nullptr;
|
||||
VERIFY(m.is_not(core[i], e));
|
||||
keys.push_back(m_keys[e]);
|
||||
rational weight = m_weights[e];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue