3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-16 05:48:44 +00:00

Replace the use of optional<rational> by inf_eps_rational<rational>

Also handle composite objectives correctly.
This commit is contained in:
Phan Anh Dung 2013-10-19 06:03:21 +02:00
parent a44044fb15
commit 53f78f7d19
9 changed files with 50 additions and 43 deletions

View file

@ -16,7 +16,6 @@ Notes:
--*/ --*/
#include "opt_context.h" #include "opt_context.h"
#include "fu_malik.h" #include "fu_malik.h"
#include "weighted_maxsat.h" #include "weighted_maxsat.h"
@ -62,7 +61,7 @@ namespace opt {
} }
if (!m_objectives.empty()) { if (!m_objectives.empty()) {
vector<optional<rational> > values; vector<inf_eps_rational<rational> > values;
for (unsigned i = 0; i < fmls_copy.size(); ++i) { for (unsigned i = 0; i < fmls_copy.size(); ++i) {
s->assert_expr(fmls_copy[i].get()); s->assert_expr(fmls_copy[i].get());
} }
@ -75,11 +74,7 @@ namespace opt {
} }
for (unsigned i = 0; i < values.size(); ++i) { for (unsigned i = 0; i < values.size(); ++i) {
if (values[i]) { std::cout << "objective function: " << mk_pp(m_objectives[i].get(), m) << " -> " << values[i].to_string() << "\n";
std::cout << "objective function: " << mk_pp(m_objectives[i].get(), m) << " -> " << *values[i] << "\n";
} else {
std::cout << "objective function: " << mk_pp(m_objectives[i].get(), m) << " -> unbounded\n";
}
} }
} }

View file

@ -66,7 +66,6 @@ namespace opt {
}; };
} }
#endif #endif

View file

@ -7,7 +7,6 @@ namespace opt {
opt_solver::opt_solver(ast_manager & m, params_ref const & p, symbol const & l): opt_solver::opt_solver(ast_manager & m, params_ref const & p, symbol const & l):
solver_na2as(m), solver_na2as(m),
m_manager(m),
m_params(p), m_params(p),
m_context(m, m_params), m_context(m, m_params),
m_objective_enabled(false) { m_objective_enabled(false) {
@ -15,7 +14,7 @@ namespace opt {
if (m_logic != symbol::null) if (m_logic != symbol::null)
m_context.set_logic(m_logic); m_context.set_logic(m_logic);
} }
opt_solver::~opt_solver() { opt_solver::~opt_solver() {
} }
@ -64,14 +63,14 @@ namespace opt {
lbool opt_solver::check_sat_core(unsigned num_assumptions, expr * const * assumptions) { lbool opt_solver::check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
TRACE("opt_solver_na2as", tout << "smt_opt_solver::check_sat_core: " << num_assumptions << "\n";); TRACE("opt_solver_na2as", tout << "opt_opt_solver::check_sat_core: " << num_assumptions << "\n";);
lbool r = m_context.check(num_assumptions, assumptions); lbool r = m_context.check(num_assumptions, assumptions);
if (r == l_true && m_objective_enabled) { if (r == l_true && m_objective_enabled) {
bool is_bounded = get_optimizer().max(m_objective_var); bool is_bounded = get_optimizer().maximize(m_objective_var);
if (is_bounded) { if (is_bounded) {
m_objective_value = get_optimizer().get_objective_value(m_objective_var); m_objective_value = get_optimizer().get_objective_value(m_objective_var);
} else { } else {
optional<rational> r; inf_eps_rational<rational> r(rational(1), rational(0));
m_objective_value = r; m_objective_value = r;
} }
} }
@ -132,7 +131,7 @@ namespace opt {
m_objective_enabled = enable; m_objective_enabled = enable;
} }
optional<rational> opt_solver::get_objective_value() { inf_eps_rational<rational> opt_solver::get_objective_value() {
return m_objective_value; return m_objective_value;
} }

View file

@ -20,6 +20,7 @@ Notes:
#ifndef _OPT_SOLVER_H_ #ifndef _OPT_SOLVER_H_
#define _OPT_SOLVER_H_ #define _OPT_SOLVER_H_
#include"inf_eps_rational.h"
#include"ast.h" #include"ast.h"
#include"params.h" #include"params.h"
#include"solver_na2as.h" #include"solver_na2as.h"
@ -37,8 +38,7 @@ namespace opt {
symbol m_logic; symbol m_logic;
bool m_objective_enabled; bool m_objective_enabled;
smt::theory_var m_objective_var; smt::theory_var m_objective_var;
ast_manager& m_manager; inf_eps_rational<rational> m_objective_value;
optional<rational> m_objective_value;
public: public:
opt_solver(ast_manager & m, params_ref const & p, symbol const & l); opt_solver(ast_manager & m, params_ref const & p, symbol const & l);
virtual ~opt_solver(); virtual ~opt_solver();
@ -64,7 +64,7 @@ namespace opt {
void set_objective(app* term); void set_objective(app* term);
void toggle_objective(bool enable); void toggle_objective(bool enable);
optional<rational> get_objective_value(); inf_eps_rational<rational> get_objective_value();
private: private:
smt::theory_opt& get_optimizer(); smt::theory_opt& get_optimizer();
}; };

View file

@ -31,7 +31,7 @@ namespace opt {
*/ */
lbool mathsat_style_opt(opt_solver& s, lbool mathsat_style_opt(opt_solver& s,
expr_ref_vector& objectives, svector<bool> const& is_max, expr_ref_vector& objectives, svector<bool> const& is_max,
vector<optional<rational> >& values) { vector<inf_eps_rational<rational> >& values) {
enable_trace("maximize"); enable_trace("maximize");
// First check_sat call for initialize theories // First check_sat call for initialize theories
lbool is_sat = s.check_sat(0, 0); lbool is_sat = s.check_sat(0, 0);
@ -39,38 +39,47 @@ namespace opt {
return l_false; return l_false;
} }
s.push();
// Assume there is only one objective function // Assume there is only one objective function
ast_manager& m = objectives.get_manager(); ast_manager& m = objectives.get_manager();
arith_util autil(m); arith_util autil(m);
app* objective = is_max[0] ? (app*) objectives[0].get() : autil.mk_uminus(objectives[0].get()); app* objective = m.mk_fresh_const("objective", autil.mk_real());
if (is_max[0]) {
s.assert_expr(autil.mk_eq(objective, objectives[0].get()));
} else {
s.assert_expr(autil.mk_eq(objective, autil.mk_uminus(objectives[0].get())));
};
s.set_objective(objective); s.set_objective(objective);
s.toggle_objective(true); s.toggle_objective(true);
is_sat = s.check_sat(0, 0); is_sat = s.check_sat(0, 0);
while (is_sat != l_false) { while (is_sat != l_false) {
// Extract values for objectives. // Extract values for objectives
optional<rational> rat; inf_eps_rational<rational> val;
rat = s.get_objective_value(); val = is_max[0] ? s.get_objective_value() : -s.get_objective_value();
// Unbounded objective // Check whether objective is unbounded
if (!rat) { if (!val.is_rational()) {
values.reset(); values.reset();
values.push_back(rat); values.push_back(val);
return l_true; break;
} }
// If values have initial data, they will be dropped. // If values have initial data, they will be dropped
values.reset(); values.reset();
values.push_back(rat); values.push_back(val);
// Assert there must be something better. // Assert there must be something better
expr_ref_vector assumptions(m); expr_ref_vector assumptions(m);
expr* bound = m.mk_fresh_const("bound", m.mk_bool_sort()); expr* bound = m.mk_fresh_const("bound", m.mk_bool_sort());
assumptions.push_back(bound); assumptions.push_back(bound);
expr* r = autil.mk_numeral(*rat, false); expr* r = autil.mk_numeral(val.get_rational(), false);
s.assert_expr(m.mk_eq(bound, is_max[0] ? autil.mk_gt(objectives[0].get(), r) : autil.mk_lt(objectives[0].get(), r))); s.assert_expr(m.mk_eq(bound, is_max[0] ? autil.mk_gt(objectives[0].get(), r) : autil.mk_lt(objectives[0].get(), r)));
is_sat = s.check_sat(1, assumptions.c_ptr()); is_sat = s.check_sat(1, assumptions.c_ptr());
} }
s.pop(1);
return l_true; return l_true;
} }
@ -82,7 +91,7 @@ namespace opt {
lbool optimize_objectives(opt_solver& s, lbool optimize_objectives(opt_solver& s,
expr_ref_vector& objectives, svector<bool> const& is_max, expr_ref_vector& objectives, svector<bool> const& is_max,
vector<optional<rational> >& values) { vector<inf_eps_rational<rational> >& values) {
return mathsat_style_opt(s, objectives, is_max, values); return mathsat_style_opt(s, objectives, is_max, values);
} }
} }

View file

@ -29,7 +29,7 @@ namespace opt {
lbool optimize_objectives(opt_solver& s, lbool optimize_objectives(opt_solver& s,
expr_ref_vector& objectives, svector<bool> const& is_max, expr_ref_vector& objectives, svector<bool> const& is_max,
vector<optional<rational> >& values); vector<inf_eps_rational<rational> >& values);
}; };
#endif #endif

View file

@ -992,9 +992,9 @@ namespace smt {
// Optimization // Optimization
// //
// ----------------------------------- // -----------------------------------
virtual bool max(theory_var v) { return max_min(v, true); } virtual bool maximize(theory_var v) { return max_min(v, true); }
virtual theory_var add_objective(app* term); virtual theory_var add_objective(app* term);
virtual optional<rational> get_objective_value(theory_var v); virtual inf_eps_rational<rational> get_objective_value(theory_var v);
inf_rational m_objective; inf_rational m_objective;
// ----------------------------------- // -----------------------------------

View file

@ -19,6 +19,7 @@ Revision History:
#ifndef _THEORY_ARITH_AUX_H_ #ifndef _THEORY_ARITH_AUX_H_
#define _THEORY_ARITH_AUX_H_ #define _THEORY_ARITH_AUX_H_
#include"inf_eps_rational.h"
#include"theory_arith.h" #include"theory_arith.h"
namespace smt { namespace smt {
@ -960,12 +961,10 @@ namespace smt {
} }
template<typename Ext> template<typename Ext>
optional<rational> theory_arith<Ext>::get_objective_value(theory_var v) { inf_eps_rational<rational> theory_arith<Ext>::get_objective_value(theory_var v) {
optional<rational> rat; inf_eps_rational<rational> val;
if (m_objective.is_rational()) { val = m_objective.get_rational();
rat = m_objective.get_rational(); return val;
};
return rat;
} }
/** /**

View file

@ -18,15 +18,21 @@ Notes:
--*/ --*/
#include "inf_eps_rational.h"
#ifndef _THEORY_OPT_H_ #ifndef _THEORY_OPT_H_
#define _THEORY_OPT_H_ #define _THEORY_OPT_H_
namespace smt { namespace smt {
class theory_opt { class theory_opt {
public: public:
virtual bool max(theory_var v) { UNREACHABLE(); return false; }; virtual bool maximize(theory_var v) { UNREACHABLE(); return false; };
virtual theory_var add_objective(app* term) { UNREACHABLE(); return null_theory_var; } virtual theory_var add_objective(app* term) { UNREACHABLE(); return null_theory_var; }
virtual optional<rational> get_objective_value(theory_var v) { UNREACHABLE(); optional<rational> r; return r;} virtual inf_eps_rational<rational> get_objective_value(theory_var v) {
UNREACHABLE();
inf_eps_rational<rational> r(rational(1), rational(0));
return r;
}
}; };
} }