mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
integrating diff opt
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
80ba830091
commit
99b4ce037d
10 changed files with 67 additions and 59 deletions
|
@ -312,18 +312,17 @@ namespace opt {
|
|||
mk_simplify_tactic(m));
|
||||
tactic_ref tac2 = mk_elim01_tactic(m);
|
||||
tactic_ref tac3 = mk_lia2card_tactic(m);
|
||||
tactic_ref tac;
|
||||
opt_params optp(m_params);
|
||||
if (optp.elim_01()) {
|
||||
tac = and_then(tac0.get(), tac2.get(), tac3.get());
|
||||
m_simplify = and_then(tac0.get(), tac2.get(), tac3.get());
|
||||
}
|
||||
else {
|
||||
tac = tac0.get();
|
||||
m_simplify = tac0.get();
|
||||
}
|
||||
proof_converter_ref pc;
|
||||
expr_dependency_ref core(m);
|
||||
goal_ref_buffer result;
|
||||
(*tac)(g, result, m_model_converter, pc, core); // TBD: have this an attribute so we can cancel.
|
||||
(*m_simplify)(g, result, m_model_converter, pc, core);
|
||||
SASSERT(result.size() == 1);
|
||||
goal* r = result[0];
|
||||
fmls.reset();
|
||||
|
@ -708,6 +707,9 @@ namespace opt {
|
|||
if (m_solver) {
|
||||
m_solver->set_cancel(f);
|
||||
}
|
||||
if (m_simplify) {
|
||||
m_simplify->set_cancel(f);
|
||||
}
|
||||
m_optsmt.set_cancel(f);
|
||||
map_t::iterator it = m_maxsmts.begin(), end = m_maxsmts.end();
|
||||
for (; it != end; ++it) {
|
||||
|
@ -719,6 +721,9 @@ namespace opt {
|
|||
if (m_solver) {
|
||||
m_solver->collect_statistics(stats);
|
||||
}
|
||||
if (m_simplify) {
|
||||
m_simplify->collect_statistics(stats);
|
||||
}
|
||||
map_t::iterator it = m_maxsmts.begin(), end = m_maxsmts.end();
|
||||
for (; it != end; ++it) {
|
||||
it->m_value->collect_statistics(stats);
|
||||
|
|
|
@ -30,6 +30,7 @@ Notes:
|
|||
#include "optsmt.h"
|
||||
#include "maxsmt.h"
|
||||
#include "model_converter.h"
|
||||
#include "tactic.h"
|
||||
|
||||
namespace opt {
|
||||
|
||||
|
@ -89,6 +90,7 @@ namespace opt {
|
|||
obj_map<func_decl, unsigned> m_objective_fns;
|
||||
obj_map<func_decl, expr*> m_objective_orig;
|
||||
func_decl_ref_vector m_objective_refs;
|
||||
tactic_ref m_simplify;
|
||||
public:
|
||||
context(ast_manager& m);
|
||||
~context();
|
||||
|
|
|
@ -133,15 +133,17 @@ namespace opt {
|
|||
return r;
|
||||
}
|
||||
|
||||
void opt_solver::maximize_objectives() {
|
||||
void opt_solver::maximize_objectives(expr_ref_vector& blockers) {
|
||||
expr_ref blocker(m);
|
||||
for (unsigned i = 0; i < m_objective_vars.size(); ++i) {
|
||||
maximize_objective(i);
|
||||
maximize_objective(i, blocker);
|
||||
blockers.push_back(blocker);
|
||||
}
|
||||
}
|
||||
|
||||
void opt_solver::maximize_objective(unsigned i) {
|
||||
void opt_solver::maximize_objective(unsigned i, expr_ref& blocker) {
|
||||
smt::theory_var v = m_objective_vars[i];
|
||||
m_objective_values[i] = get_optimizer().maximize(v);
|
||||
m_objective_values[i] = get_optimizer().maximize(v, blocker);
|
||||
m_context.get_context().update_model();
|
||||
TRACE("opt", { model_ref mdl; get_model(mdl); model_smt2_pp(tout << "update model: ", m, *mdl, 0); });
|
||||
}
|
||||
|
@ -231,20 +233,7 @@ namespace opt {
|
|||
|
||||
// difference logic?
|
||||
return expr_ref(m.mk_true(), m);
|
||||
}
|
||||
|
||||
expr_ref opt_solver::mk_gt(unsigned var, inf_eps const& val) {
|
||||
if (val.get_infinity().is_pos()) {
|
||||
return expr_ref(m.mk_false(), m);
|
||||
}
|
||||
else if (val.get_infinity().is_neg()) {
|
||||
return expr_ref(m.mk_true(), m);
|
||||
}
|
||||
else {
|
||||
inf_rational n = val.get_numeral();
|
||||
return expr_ref(get_optimizer().mk_gt(m_objective_vars[var], n), m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void opt_solver::reset_objectives() {
|
||||
m_objective_vars.reset();
|
||||
|
|
|
@ -75,12 +75,11 @@ namespace opt {
|
|||
|
||||
smt::theory_var add_objective(app* term);
|
||||
void reset_objectives();
|
||||
void maximize_objective(unsigned i);
|
||||
void maximize_objectives();
|
||||
void maximize_objective(unsigned i, expr_ref& blocker);
|
||||
void maximize_objectives(expr_ref_vector& blockers);
|
||||
|
||||
vector<inf_eps> const& get_objective_values();
|
||||
inf_eps const & get_objective_value(unsigned obj_index);
|
||||
expr_ref mk_gt(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; }
|
||||
|
|
|
@ -124,7 +124,8 @@ namespace opt {
|
|||
}
|
||||
|
||||
void optsmt::update_lower() {
|
||||
m_s->maximize_objectives();
|
||||
expr_ref_vector disj(m);
|
||||
m_s->maximize_objectives(disj);
|
||||
m_s->get_model(m_model);
|
||||
set_max(m_lower, m_s->get_objective_values());
|
||||
IF_VERBOSE(1,
|
||||
|
@ -134,13 +135,7 @@ namespace opt {
|
|||
verbose_stream() << "\n";
|
||||
model_pp(verbose_stream(), *m_model);
|
||||
);
|
||||
expr_ref_vector disj(m);
|
||||
expr_ref constraint(m);
|
||||
|
||||
for (unsigned i = 0; i < m_lower.size(); ++i) {
|
||||
inf_eps const& v = m_lower[i];
|
||||
disj.push_back(m_s->mk_gt(i, v));
|
||||
}
|
||||
expr_ref constraint(m);
|
||||
constraint = m.mk_or(disj.size(), disj.c_ptr());
|
||||
m_s->assert_expr(constraint);
|
||||
}
|
||||
|
@ -237,25 +232,23 @@ namespace opt {
|
|||
|
||||
lbool optsmt::basic_lex(unsigned obj_index) {
|
||||
lbool is_sat = l_true;
|
||||
expr_ref block(m);
|
||||
|
||||
expr_ref block(m), tmp(m);
|
||||
|
||||
while (is_sat == l_true && !m_cancel) {
|
||||
is_sat = m_s->check_sat(0, 0);
|
||||
if (is_sat != l_true) break;
|
||||
|
||||
m_s->maximize_objective(obj_index);
|
||||
m_s->maximize_objective(obj_index, block);
|
||||
m_s->get_model(m_model);
|
||||
inf_eps obj = m_s->get_objective_value(obj_index);
|
||||
if (obj > m_lower[obj_index]) {
|
||||
m_lower[obj_index] = obj;
|
||||
IF_VERBOSE(1, verbose_stream() << "(optsmt lower bound: " << obj << ")\n";);
|
||||
for (unsigned i = obj_index+1; i < m_vars.size(); ++i) {
|
||||
m_s->maximize_objective(i);
|
||||
m_s->maximize_objective(i, tmp);
|
||||
m_lower[i] = m_s->get_objective_value(i);
|
||||
}
|
||||
}
|
||||
block = m_s->mk_gt(obj_index, obj);
|
||||
m_s->assert_expr(block);
|
||||
|
||||
// TBD: only works for simplex
|
||||
|
@ -289,14 +282,13 @@ namespace opt {
|
|||
is_sat = m_s->check_sat(0, 0);
|
||||
if (is_sat != l_true) break;
|
||||
was_sat = true;
|
||||
m_s->maximize_objective(obj_index);
|
||||
m_s->maximize_objective(obj_index, block);
|
||||
m_s->get_model(m_model);
|
||||
inf_eps obj = m_s->get_objective_value(obj_index);
|
||||
if (obj > m_lower[obj_index]) {
|
||||
m_lower[obj_index] = obj;
|
||||
IF_VERBOSE(1, verbose_stream() << "(optsmt lower bound: " << obj << ")\n";);
|
||||
}
|
||||
block = m_s->mk_gt(obj_index, obj);
|
||||
m_s->assert_expr(block);
|
||||
}
|
||||
|
||||
|
@ -347,10 +339,12 @@ namespace opt {
|
|||
|
||||
|
||||
inf_eps optsmt::get_lower(unsigned i) const {
|
||||
if (i >= m_lower.size()) return inf_eps();
|
||||
return m_lower[i];
|
||||
}
|
||||
|
||||
inf_eps optsmt::get_upper(unsigned i) const {
|
||||
if (i >= m_upper.size()) return inf_eps();
|
||||
return m_upper[i];
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue