mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 00:55:31 +00:00
add model correction
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
c75fd02c95
commit
2428bf18f1
11 changed files with 156 additions and 65 deletions
|
@ -965,37 +965,57 @@ namespace qe {
|
|||
|
||||
typedef opt::model_based_opt::var var;
|
||||
typedef vector<var> vars;
|
||||
|
||||
|
||||
opt::bound_type maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& value, expr_ref& bound) {
|
||||
opt::inf_eps maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& bound) {
|
||||
opt::model_based_opt mbo;
|
||||
|
||||
opt::inf_eps value;
|
||||
obj_map<expr, rational> ts;
|
||||
obj_map<expr, unsigned> tids;
|
||||
vars coeffs;
|
||||
rational c(0), mul(1);
|
||||
linearize(mdl, mul, t, c, ts);
|
||||
linearize(mdl, mul, t, c, ts);
|
||||
extract_coefficients(ts, tids, coeffs);
|
||||
mbo.set_objective(coeffs, c);
|
||||
|
||||
for (unsigned i = 0; i < fmls.size(); ++i) {
|
||||
linearize(mdl, mbo, fmls[i], tids);
|
||||
}
|
||||
|
||||
|
||||
rational val;
|
||||
opt::bound_type result = mbo.maximize(val);
|
||||
value = a.mk_numeral(val, false);
|
||||
switch (result) {
|
||||
case opt::unbounded:
|
||||
value = mbo.maximize();
|
||||
|
||||
|
||||
|
||||
expr_ref val(a.mk_numeral(value.get_rational(), false), m);
|
||||
if (!value.is_finite()) {
|
||||
bound = m.mk_false();
|
||||
break;
|
||||
case opt::strict:
|
||||
bound = a.mk_le(value, t);
|
||||
break;
|
||||
case opt::non_strict:
|
||||
bound = a.mk_lt(value, t);
|
||||
break;
|
||||
return value;
|
||||
}
|
||||
|
||||
// update model
|
||||
ptr_vector<expr> vars;
|
||||
obj_map<expr, unsigned>::iterator it = tids.begin(), end = tids.end();
|
||||
for (; it != end; ++it) {
|
||||
expr* e = it->m_key;
|
||||
if (is_uninterp_const(e)) {
|
||||
unsigned id = it->m_value;
|
||||
func_decl* f = to_app(e)->get_decl();
|
||||
expr_ref val(a.mk_numeral(mbo.get_value(id), false), m);
|
||||
mdl.register_decl(f, val);
|
||||
}
|
||||
else {
|
||||
TRACE("qe", tout << "omitting model update for non-uninterpreted constant " << mk_pp(e, m) << "\n";);
|
||||
}
|
||||
}
|
||||
|
||||
if (value.get_infinitesimal().is_neg()) {
|
||||
bound = a.mk_le(val, t);
|
||||
}
|
||||
else {
|
||||
bound = a.mk_lt(val, t);
|
||||
}
|
||||
return result;
|
||||
return value;
|
||||
}
|
||||
|
||||
void extract_coefficients(obj_map<expr, rational> const& ts, obj_map<expr, unsigned>& tids, vars& coeffs) {
|
||||
|
@ -1033,8 +1053,8 @@ namespace qe {
|
|||
return m_imp->a.get_family_id();
|
||||
}
|
||||
|
||||
opt::bound_type arith_project_plugin::maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& value, expr_ref& bound) {
|
||||
return m_imp->maximize(fmls, mdl, t, value, bound);
|
||||
opt::inf_eps arith_project_plugin::maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& bound) {
|
||||
return m_imp->maximize(fmls, mdl, t, bound);
|
||||
}
|
||||
|
||||
bool arith_project(model& model, app* var, expr_ref_vector& lits) {
|
||||
|
|
|
@ -22,14 +22,15 @@ namespace qe {
|
|||
|
||||
class arith_project_plugin : public project_plugin {
|
||||
struct imp;
|
||||
imp* m_imp;
|
||||
imp* m_imp;
|
||||
public:
|
||||
arith_project_plugin(ast_manager& m);
|
||||
virtual ~arith_project_plugin();
|
||||
virtual bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits);
|
||||
virtual bool solve(model& model, app_ref_vector& vars, expr_ref_vector& lits);
|
||||
virtual family_id get_family_id();
|
||||
opt::bound_type maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& value, expr_ref& bound);
|
||||
|
||||
opt::inf_eps maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& bound);
|
||||
};
|
||||
|
||||
bool arith_project(model& model, app* var, expr_ref_vector& lits);
|
||||
|
|
|
@ -213,9 +213,9 @@ class mbp::impl {
|
|||
public:
|
||||
|
||||
|
||||
opt::bound_type maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& value, expr_ref& bound) {
|
||||
opt::inf_eps maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& bound) {
|
||||
arith_project_plugin arith(m);
|
||||
return arith.maximize(fmls, mdl, t, value, bound);
|
||||
return arith.maximize(fmls, mdl, t, bound);
|
||||
}
|
||||
|
||||
void extract_literals(model& model, expr_ref_vector& fmls) {
|
||||
|
@ -421,6 +421,6 @@ void mbp::extract_literals(model& model, expr_ref_vector& lits) {
|
|||
m_impl->extract_literals(model, lits);
|
||||
}
|
||||
|
||||
opt::bound_type mbp::maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& value, expr_ref& bound) {
|
||||
return m_impl->maximize(fmls, mdl, t, value, bound);
|
||||
opt::inf_eps mbp::maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& bound) {
|
||||
return m_impl->maximize(fmls, mdl, t, bound);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace qe {
|
|||
\brief
|
||||
Maximize objective t under current model for constraints in fmls.
|
||||
*/
|
||||
opt::bound_type maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& value, expr_ref& bound);
|
||||
opt::inf_eps maximize(expr_ref_vector const& fmls, model& mdl, app* t, expr_ref& bound);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1162,8 +1162,7 @@ namespace qe {
|
|||
m_level(0),
|
||||
m_mode(mode),
|
||||
m_avars(m),
|
||||
m_free_vars(m),
|
||||
m_value(m)
|
||||
m_free_vars(m)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
@ -1283,17 +1282,15 @@ namespace qe {
|
|||
}
|
||||
|
||||
app* m_objective;
|
||||
expr_ref m_value;
|
||||
opt::bound_type m_bound;
|
||||
opt::inf_eps m_value;
|
||||
bool m_was_sat;
|
||||
|
||||
lbool maximize(expr_ref_vector const& fmls, app* t, expr_ref& value, opt::bound_type& bound) {
|
||||
lbool maximize(expr_ref_vector const& fmls, app* t, opt::inf_eps& value) {
|
||||
expr_ref_vector defs(m);
|
||||
expr_ref fml = negate_core(fmls);
|
||||
hoist(fml);
|
||||
m_objective = t;
|
||||
m_value = 0;
|
||||
m_bound = opt::unbounded;
|
||||
m_value = opt::inf_eps();
|
||||
m_was_sat = false;
|
||||
m_pred_abs.abstract_atoms(fml, defs);
|
||||
fml = m_pred_abs.mk_abstract(fml);
|
||||
|
@ -1319,7 +1316,6 @@ namespace qe {
|
|||
throw tactic_exception(s.c_str());
|
||||
}
|
||||
value = m_value;
|
||||
bound = m_bound;
|
||||
return l_true;
|
||||
}
|
||||
|
||||
|
@ -1327,16 +1323,16 @@ namespace qe {
|
|||
TRACE("qe", tout << "maximize: " << core << "\n";);
|
||||
m_was_sat |= !core.empty();
|
||||
expr_ref bound(m);
|
||||
m_bound = m_mbp.maximize(core, mdl, m_objective, m_value, bound);
|
||||
m_value = m_mbp.maximize(core, mdl, m_objective, bound);
|
||||
m_ex.assert_expr(bound);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
lbool maximize(expr_ref_vector const& fmls, app* t, expr_ref& value, opt::bound_type& bound, params_ref const& p) {
|
||||
lbool maximize(expr_ref_vector const& fmls, app* t, opt::inf_eps& value, params_ref const& p) {
|
||||
ast_manager& m = fmls.get_manager();
|
||||
qsat qs(m, p, qsat_maximize);
|
||||
return qs.maximize(fmls, t, value, bound);
|
||||
return qs.maximize(fmls, t, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace qe {
|
|||
void collect_statistics(statistics& st) const;
|
||||
};
|
||||
|
||||
lbool maximize(expr_ref_vector const& fmls, app* t, expr_ref& value, opt::bound_type& bound, params_ref const& p);
|
||||
lbool maximize(expr_ref_vector const& fmls, app* t, opt::inf_eps& value, params_ref const& p);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue