mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
integrating new integer primal loop
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
4bb5302def
commit
e24db56650
17 changed files with 183 additions and 66 deletions
|
@ -30,6 +30,7 @@ Notes:
|
|||
#include "simplify_tactic.h"
|
||||
#include "goal2sat.h"
|
||||
#include "ast_pp.h"
|
||||
#include "model_smt2_pp.h"
|
||||
|
||||
// incremental SAT solver.
|
||||
class inc_sat_solver : public solver {
|
||||
|
@ -396,14 +397,15 @@ private:
|
|||
(*m_mc)(m_model);
|
||||
}
|
||||
SASSERT(m_model);
|
||||
// IF_VERBOSE(0, model_smt2_pp(verbose_stream(), m, *(m_model.get()), 0););
|
||||
|
||||
DEBUG_CODE(
|
||||
for (unsigned i = 0; i < m_fmls.size(); ++i) {
|
||||
expr_ref tmp(m);
|
||||
VERIFY(m_model->eval(m_fmls[i].get(), tmp));
|
||||
CTRACE("opt", !m.is_true(tmp),
|
||||
tout << "Evaluation failed: " << mk_pp(m_fmls[i].get(), m) << "\n";);
|
||||
tout << "Evaluation failed: " << mk_pp(m_fmls[i].get(), m)
|
||||
<< " to " << tmp << "\n";
|
||||
model_smt2_pp(tout, m, *(m_model.get()), 0););
|
||||
SASSERT(m.is_true(tmp));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -251,11 +251,11 @@ namespace opt {
|
|||
}
|
||||
|
||||
void maxsmt::update_lower(rational const& r) {
|
||||
if (m_lower > r) m_lower = r;
|
||||
m_lower = r;
|
||||
}
|
||||
|
||||
void maxsmt::update_upper(rational const& r) {
|
||||
if (m_upper < r) m_upper = r;
|
||||
m_upper = r;
|
||||
}
|
||||
|
||||
void maxsmt::get_model(model_ref& mdl) {
|
||||
|
|
|
@ -247,8 +247,7 @@ namespace opt {
|
|||
mdl = m_model;
|
||||
}
|
||||
|
||||
void context::get_model(model_ref& mdl) {
|
||||
mdl = m_model;
|
||||
void context::fix_model(model_ref& mdl) {
|
||||
if (mdl) {
|
||||
if (m_model_converter) {
|
||||
(*m_model_converter)(mdl, 0);
|
||||
|
@ -257,6 +256,16 @@ namespace opt {
|
|||
}
|
||||
}
|
||||
|
||||
void context::set_model(model_ref& mdl) {
|
||||
m_model = mdl;
|
||||
fix_model(mdl);
|
||||
}
|
||||
|
||||
void context::get_model(model_ref& mdl) {
|
||||
mdl = m_model;
|
||||
fix_model(mdl);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -384,6 +393,9 @@ namespace opt {
|
|||
break;
|
||||
}
|
||||
}
|
||||
TRACE("opt",
|
||||
model_smt2_pp(tout << "Model:\n", m, *mdl, 0);
|
||||
mdl->eval(term, val); tout << term << " " << val << "\n";);
|
||||
VERIFY(mdl->eval(term, val) && is_numeral(val, r));
|
||||
}
|
||||
|
||||
|
@ -914,9 +926,12 @@ namespace opt {
|
|||
objective const& obj = m_objectives[i];
|
||||
rational r;
|
||||
switch(obj.m_type) {
|
||||
case O_MINIMIZE:
|
||||
if (m_model->eval(obj.m_term, val) && is_numeral(val, r)) {
|
||||
case O_MINIMIZE: {
|
||||
bool evaluated = m_model->eval(obj.m_term, val);
|
||||
TRACE("opt", tout << obj.m_term << " " << val << " " << evaluated << " " << is_numeral(val, r) << "\n";);
|
||||
if (evaluated && is_numeral(val, r)) {
|
||||
inf_eps val = inf_eps(obj.m_adjust_value(r));
|
||||
TRACE("opt", tout << "adjusted value: " << val << "\n";);
|
||||
if (is_lower) {
|
||||
m_optsmt.update_lower(obj.m_index, val);
|
||||
}
|
||||
|
@ -925,9 +940,13 @@ namespace opt {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case O_MAXIMIZE:
|
||||
if (m_model->eval(obj.m_term, val) && is_numeral(val, r)) {
|
||||
}
|
||||
case O_MAXIMIZE: {
|
||||
bool evaluated = m_model->eval(obj.m_term, val);
|
||||
TRACE("opt", tout << obj.m_term << " " << val << "\n";);
|
||||
if (evaluated && is_numeral(val, r)) {
|
||||
inf_eps val = inf_eps(obj.m_adjust_value(r));
|
||||
TRACE("opt", tout << "adjusted value: " << val << "\n";);
|
||||
if (is_lower) {
|
||||
m_optsmt.update_lower(obj.m_index, val);
|
||||
}
|
||||
|
@ -936,10 +955,13 @@ namespace opt {
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case O_MAXSMT: {
|
||||
bool ok = true;
|
||||
for (unsigned j = 0; ok && j < obj.m_terms.size(); ++j) {
|
||||
if (m_model->eval(obj.m_terms[j], val)) {
|
||||
bool evaluated = m_model->eval(obj.m_terms[j], val);
|
||||
TRACE("opt", tout << mk_pp(obj.m_terms[j], m) << " " << val << "\n";);
|
||||
if (evaluated) {
|
||||
if (!m.is_true(val)) {
|
||||
r += obj.m_weights[j];
|
||||
}
|
||||
|
@ -949,11 +971,14 @@ namespace opt {
|
|||
}
|
||||
}
|
||||
if (ok) {
|
||||
maxsmt& ms = *m_maxsmts.find(obj.m_id);
|
||||
if (is_lower) {
|
||||
m_maxsmts.find(obj.m_id)->update_upper(r);
|
||||
ms.update_upper(r);
|
||||
TRACE("opt", tout << r << " " << ms.get_upper() << "\n";);
|
||||
}
|
||||
else {
|
||||
m_maxsmts.find(obj.m_id)->update_lower(r);
|
||||
ms.update_lower(r);
|
||||
TRACE("opt", tout << r << " " << ms.get_lower() << "\n";);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -147,6 +147,8 @@ namespace opt {
|
|||
virtual void set_hard_constraints(ptr_vector<expr> & hard);
|
||||
virtual lbool optimize();
|
||||
virtual void get_model(model_ref& m);
|
||||
virtual void set_model(model_ref& m);
|
||||
virtual void fix_model(model_ref& m);
|
||||
virtual void collect_statistics(statistics& stats) const;
|
||||
virtual proof* get_proof() { return 0; }
|
||||
virtual void get_labels(svector<symbol> & r) {}
|
||||
|
|
|
@ -38,7 +38,10 @@ namespace opt {
|
|||
return l_undef;
|
||||
}
|
||||
m_solver->get_model(m_model);
|
||||
IF_VERBOSE(1, model_smt2_pp(verbose_stream() << "new model:\n", m, *m_model, 0););
|
||||
IF_VERBOSE(1,
|
||||
model_ref mdl(m_model);
|
||||
cb.fix_model(mdl);
|
||||
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);
|
||||
|
@ -65,6 +68,7 @@ namespace opt {
|
|||
fmls.push_back(m.mk_or(gt.size(), gt.c_ptr()));
|
||||
fml = m.mk_and(fmls.size(), fmls.c_ptr());
|
||||
IF_VERBOSE(10, verbose_stream() << "dominates: " << fml << "\n";);
|
||||
TRACE("opt", tout << fml << "\n";);
|
||||
m_solver->assert_expr(fml);
|
||||
}
|
||||
|
||||
|
@ -77,6 +81,7 @@ namespace opt {
|
|||
}
|
||||
fml = m.mk_not(m.mk_and(le.size(), le.c_ptr()));
|
||||
IF_VERBOSE(10, verbose_stream() << "not dominated by: " << fml << "\n";);
|
||||
TRACE("opt", tout << fml << "\n";);
|
||||
m_solver->assert_expr(fml);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace opt {
|
|||
virtual expr_ref mk_gt(unsigned i, model_ref& model) = 0;
|
||||
virtual expr_ref mk_ge(unsigned i, model_ref& model) = 0;
|
||||
virtual expr_ref mk_le(unsigned i, model_ref& model) = 0;
|
||||
virtual void set_model(model_ref& m) = 0;
|
||||
virtual void fix_model(model_ref& m) = 0;
|
||||
};
|
||||
class pareto_base {
|
||||
protected:
|
||||
|
|
|
@ -194,6 +194,7 @@ namespace opt {
|
|||
inf_eps val = get_optimizer().maximize(v, blocker, has_shared);
|
||||
inf_eps val2;
|
||||
m_valid_objectives[i] = true;
|
||||
TRACE("opt", tout << (has_shared?"has shared":"non-shared") << "\n";);
|
||||
if (m_context.get_context().update_model(has_shared)) {
|
||||
if (has_shared) {
|
||||
val2 = current_objective_value(i);
|
||||
|
@ -302,20 +303,31 @@ namespace opt {
|
|||
|
||||
if (typeid(smt::theory_inf_arith) == typeid(opt)) {
|
||||
smt::theory_inf_arith& th = dynamic_cast<smt::theory_inf_arith&>(opt);
|
||||
return expr_ref(th.mk_ge(m_fm, v, val), m);
|
||||
return th.mk_ge(m_fm, v, val);
|
||||
}
|
||||
|
||||
if (typeid(smt::theory_mi_arith) == typeid(opt)) {
|
||||
smt::theory_mi_arith& th = dynamic_cast<smt::theory_mi_arith&>(opt);
|
||||
SASSERT(val.is_finite());
|
||||
return expr_ref(th.mk_ge(m_fm, v, val.get_numeral()), m);
|
||||
return th.mk_ge(m_fm, v, val.get_numeral());
|
||||
}
|
||||
|
||||
if (typeid(smt::theory_i_arith) == typeid(opt)) {
|
||||
SASSERT(val.is_finite());
|
||||
SASSERT(val.get_infinitesimal().is_zero());
|
||||
smt::theory_i_arith& th = dynamic_cast<smt::theory_i_arith&>(opt);
|
||||
return expr_ref(th.mk_ge(m_fm, v, val.get_rational()), m);
|
||||
return th.mk_ge(m_fm, v, val.get_rational());
|
||||
}
|
||||
|
||||
if (typeid(smt::theory_idl) == typeid(opt)) {
|
||||
smt::theory_idl& th = dynamic_cast<smt::theory_idl&>(opt);
|
||||
return th.mk_ge(m_fm, v, val.get_rational());
|
||||
}
|
||||
|
||||
if (typeid(smt::theory_rdl) == typeid(opt) &&
|
||||
val.get_infinitesimal().is_zero()) {
|
||||
smt::theory_rdl& th = dynamic_cast<smt::theory_rdl&>(opt);
|
||||
return th.mk_ge(m_fm, v, val.get_rational());
|
||||
}
|
||||
|
||||
// difference logic?
|
||||
|
|
|
@ -170,11 +170,13 @@ namespace opt {
|
|||
}
|
||||
|
||||
void optsmt::update_lower(unsigned idx, inf_eps const& v) {
|
||||
TRACE("opt", tout << "v" << idx << " >= " << v << "\n";);
|
||||
m_lower_fmls[idx] = m_s->mk_ge(idx, v);
|
||||
m_lower[idx] = v;
|
||||
}
|
||||
|
||||
void optsmt::update_upper(unsigned idx, inf_eps const& v) {
|
||||
TRACE("opt", tout << "v" << idx << " <= " << v << "\n";);
|
||||
m_upper[idx] = v;
|
||||
}
|
||||
|
||||
|
@ -302,6 +304,9 @@ namespace opt {
|
|||
lbool is_sat = l_true;
|
||||
expr_ref block(m), tmp(m);
|
||||
|
||||
for (unsigned i = 0; i < obj_index; ++i) {
|
||||
commit_assignment(i);
|
||||
}
|
||||
while (is_sat == l_true && !m_cancel) {
|
||||
is_sat = m_s->check_sat(0, 0);
|
||||
if (is_sat != l_true) break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue