mirror of
https://github.com/Z3Prover/z3
synced 2025-10-04 23:13:57 +00:00
bug fixes to pb; working on model extraction
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
26bf64a0c3
commit
2c577a304d
15 changed files with 348 additions and 197 deletions
|
@ -50,13 +50,13 @@ namespace opt {
|
|||
case l_undef:
|
||||
return l_undef;
|
||||
case l_true: {
|
||||
model_ref model;
|
||||
model_ref mdl;
|
||||
expr_ref_vector ans(m);
|
||||
s.get_model(model);
|
||||
s.get_model(mdl);
|
||||
|
||||
for (unsigned i = 0; i < aux.size(); ++i) {
|
||||
expr_ref val(m);
|
||||
VERIFY(model->eval(m_soft[i].get(), val));
|
||||
VERIFY(mdl->eval(m_soft[i].get(), val));
|
||||
if (m.is_true(val)) {
|
||||
ans.push_back(m_soft[i].get());
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ namespace opt {
|
|||
if (ans.size() > m_answer.size()) {
|
||||
m_answer.reset();
|
||||
m_answer.append(ans);
|
||||
m_model = mdl.get();
|
||||
}
|
||||
if (m_answer.size() == m_upper) {
|
||||
return l_true;
|
||||
|
@ -150,6 +151,9 @@ namespace opt {
|
|||
void core_maxsat::collect_statistics(statistics& st) const {
|
||||
// nothing specific
|
||||
}
|
||||
void core_maxsat::get_model(model_ref& mdl) {
|
||||
mdl = m_model.get();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace opt {
|
|||
expr_ref_vector m_soft;
|
||||
expr_ref_vector m_answer;
|
||||
unsigned m_upper;
|
||||
model_ref m_model;
|
||||
public:
|
||||
core_maxsat(ast_manager& m, solver& s, expr_ref_vector& soft_constraints);
|
||||
virtual ~core_maxsat();
|
||||
|
@ -41,7 +42,7 @@ namespace opt {
|
|||
virtual expr_ref_vector get_assignment() const;
|
||||
virtual void set_cancel(bool f);
|
||||
virtual void collect_statistics(statistics& st) const;
|
||||
|
||||
virtual void get_model(model_ref& mdl);
|
||||
private:
|
||||
void set2vector(expr_set const& set, ptr_vector<expr>& es) const;
|
||||
expr_ref mk_at_most(expr_set const& set, unsigned k);
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace opt {
|
|||
expr_ref_vector m_aux;
|
||||
expr_ref_vector m_assignment;
|
||||
unsigned m_upper_size;
|
||||
model_ref m_model;
|
||||
|
||||
ref<solver> m_s;
|
||||
solver & m_original_solver;
|
||||
|
@ -300,13 +301,12 @@ namespace opt {
|
|||
|
||||
if (is_sat == l_true) {
|
||||
// Get a list of satisfying m_soft
|
||||
model_ref model;
|
||||
s().get_model(model);
|
||||
s().get_model(m_model);
|
||||
|
||||
m_assignment.reset();
|
||||
for (unsigned i = 0; i < m_orig_soft.size(); ++i) {
|
||||
expr_ref val(m);
|
||||
VERIFY(model->eval(m_orig_soft[i].get(), val));
|
||||
VERIFY(m_model->eval(m_orig_soft[i].get(), val));
|
||||
if (m.is_true(val)) {
|
||||
m_assignment.push_back(m_orig_soft[i].get());
|
||||
}
|
||||
|
@ -318,6 +318,10 @@ namespace opt {
|
|||
return is_sat;
|
||||
}
|
||||
|
||||
void get_model(model_ref& mdl) {
|
||||
mdl = m_model.get();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
fu_malik::fu_malik(ast_manager& m, solver& s, expr_ref_vector& soft_constraints) {
|
||||
|
@ -348,6 +352,10 @@ namespace opt {
|
|||
void fu_malik::collect_statistics(statistics& st) const {
|
||||
m_imp->collect_statistics(st);
|
||||
}
|
||||
void fu_malik::get_model(model_ref& m) {
|
||||
m_imp->get_model(m);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace opt {
|
|||
virtual expr_ref_vector get_assignment() const;
|
||||
virtual void set_cancel(bool f);
|
||||
virtual void collect_statistics(statistics& st) const;
|
||||
virtual void get_model(model_ref& m);
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -52,6 +52,9 @@ namespace opt {
|
|||
if (m_msolver) {
|
||||
is_sat = (*m_msolver)();
|
||||
m_answer.append(m_msolver->get_assignment());
|
||||
if (is_sat == l_true) {
|
||||
m_msolver->get_model(m_model);
|
||||
}
|
||||
}
|
||||
|
||||
// Infrastructure for displaying and storing solution is TBD.
|
||||
|
@ -105,6 +108,10 @@ namespace opt {
|
|||
if (m_lower > r) m_lower = r;
|
||||
}
|
||||
|
||||
void maxsmt::get_model(model_ref& mdl) {
|
||||
mdl = m_model.get();
|
||||
}
|
||||
|
||||
void maxsmt::commit_assignment() {
|
||||
SASSERT(m_s);
|
||||
for (unsigned i = 0; i < m_answer.size(); ++i) {
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace opt {
|
|||
virtual expr_ref_vector get_assignment() const = 0;
|
||||
virtual void set_cancel(bool f) = 0;
|
||||
virtual void collect_statistics(statistics& st) const = 0;
|
||||
virtual void get_model(model_ref& mdl) = 0;
|
||||
};
|
||||
/**
|
||||
Takes solver with hard constraints added.
|
||||
|
@ -52,6 +53,7 @@ namespace opt {
|
|||
rational m_upper;
|
||||
scoped_ptr<maxsmt_solver> m_msolver;
|
||||
symbol m_maxsat_engine;
|
||||
model_ref m_model;
|
||||
public:
|
||||
maxsmt(ast_manager& m): m(m), m_s(0), m_cancel(false), m_soft_constraints(m), m_answer(m) {}
|
||||
|
||||
|
@ -78,15 +80,11 @@ namespace opt {
|
|||
rational get_lower() const;
|
||||
rational get_upper() const;
|
||||
void update_lower(rational const& r);
|
||||
|
||||
|
||||
void get_model(model_ref& mdl);
|
||||
expr_ref_vector get_assignment() const;
|
||||
|
||||
void display_answer(std::ostream& out) const;
|
||||
|
||||
void display_answer(std::ostream& out) const;
|
||||
void collect_statistics(statistics& st) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
bool is_maxsat_problem(vector<rational> const& ws) const;
|
||||
|
|
|
@ -108,12 +108,16 @@ namespace opt {
|
|||
|
||||
void context::get_model(model_ref& mdl) {
|
||||
mdl = m_model;
|
||||
if (m_model_converter) {
|
||||
(*m_model_converter)(mdl, 0);
|
||||
}
|
||||
}
|
||||
|
||||
lbool context::execute_min_max(unsigned index, bool committed, bool is_max) {
|
||||
// HACK: reuse m_optsmt without regard for box reuse and not considering
|
||||
// use-case of lex.
|
||||
lbool result = m_optsmt(get_solver());
|
||||
if (result == l_true) m_optsmt.get_model(m_model);
|
||||
if (committed) m_optsmt.commit_assignment(index);
|
||||
return result;
|
||||
}
|
||||
|
@ -122,6 +126,7 @@ namespace opt {
|
|||
lbool context::execute_maxsat(symbol const& id, bool committed) {
|
||||
maxsmt& ms = *m_maxsmts.find(id);
|
||||
lbool result = ms(get_solver());
|
||||
if (result == l_true) ms.get_model(m_model);
|
||||
if (committed) ms.commit_assignment();
|
||||
return result;
|
||||
}
|
||||
|
@ -177,11 +182,10 @@ namespace opt {
|
|||
tactic_ref tac1 = mk_elim01_tactic(m);
|
||||
tactic_ref tac2 = mk_lia2card_tactic(m);
|
||||
tactic_ref tac = and_then(tac1.get(), tac2.get());
|
||||
model_converter_ref mc; // TBD: expose model converter upwards and apply to returned model.
|
||||
proof_converter_ref pc;
|
||||
expr_dependency_ref core(m);
|
||||
goal_ref_buffer result;
|
||||
(*tac)(g, result, mc, pc, core); // TBD: have this an attribute so we can cancel.
|
||||
(*tac)(g, result, m_model_converter, pc, core); // TBD: have this an attribute so we can cancel.
|
||||
SASSERT(result.size() == 1);
|
||||
goal* r = result[0];
|
||||
fmls.reset();
|
||||
|
|
|
@ -29,6 +29,7 @@ Notes:
|
|||
#include "opt_solver.h"
|
||||
#include "optsmt.h"
|
||||
#include "maxsmt.h"
|
||||
#include "model_converter.h"
|
||||
|
||||
namespace opt {
|
||||
|
||||
|
@ -83,6 +84,7 @@ namespace opt {
|
|||
map_id m_indices;
|
||||
vector<objective> m_objectives;
|
||||
model_ref m_model;
|
||||
model_converter_ref m_model_converter;
|
||||
obj_map<func_decl, unsigned> m_objective_fns;
|
||||
public:
|
||||
context(ast_manager& m);
|
||||
|
|
|
@ -121,6 +121,7 @@ namespace opt {
|
|||
inf_eps v(r);
|
||||
if (m_lower[idx] < v) {
|
||||
m_lower[idx] = v;
|
||||
s->get_model(m_model);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,6 +262,10 @@ namespace opt {
|
|||
return m_is_max[i]?m_upper[i]:-m_lower[i];
|
||||
}
|
||||
|
||||
void optsmt::get_model(model_ref& mdl) {
|
||||
mdl = m_model.get();
|
||||
}
|
||||
|
||||
// force lower_bound(i) <= objective_value(i)
|
||||
void optsmt::commit_assignment(unsigned i) {
|
||||
inf_eps mid(0);
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace opt {
|
|||
svector<bool> m_is_max;
|
||||
svector<smt::theory_var> m_vars;
|
||||
symbol m_engine;
|
||||
model_ref m_model;
|
||||
public:
|
||||
optsmt(ast_manager& m): m(m), s(0), m_cancel(false), m_objs(m) {}
|
||||
|
||||
|
@ -56,6 +57,7 @@ namespace opt {
|
|||
inf_eps get_value(unsigned index) const;
|
||||
inf_eps get_lower(unsigned index) const;
|
||||
inf_eps get_upper(unsigned index) const;
|
||||
void get_model(model_ref& mdl);
|
||||
|
||||
void update_lower(unsigned idx, rational const& r);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace smt {
|
|||
rational m_min_cost; // current maximal cost assignment.
|
||||
u_map<theory_var> m_bool2var; // bool_var -> theory_var
|
||||
svector<bool_var> m_var2bool; // theory_var -> bool_var
|
||||
model_ref m_model;
|
||||
public:
|
||||
theory_weighted_maxsat(ast_manager& m):
|
||||
theory(m.mk_family_id("weighted_maxsat")),
|
||||
|
@ -186,6 +187,7 @@ namespace smt {
|
|||
m_bool2var.reset();
|
||||
m_var2bool.reset();
|
||||
m_min_cost_atom = 0;
|
||||
m_model = 0;
|
||||
}
|
||||
|
||||
virtual theory * mk_fresh(context * new_ctx) { return alloc(theory_weighted_maxsat, new_ctx->get_manager()); }
|
||||
|
@ -194,6 +196,9 @@ namespace smt {
|
|||
virtual void new_eq_eh(theory_var v1, theory_var v2) { }
|
||||
virtual void new_diseq_eh(theory_var v1, theory_var v2) { }
|
||||
|
||||
void get_model(model_ref& mdl) {
|
||||
mdl = m_model.get();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
@ -239,9 +244,11 @@ namespace smt {
|
|||
m_min_cost = weight;
|
||||
m_cost_save.reset();
|
||||
m_cost_save.append(m_costs);
|
||||
ctx.get_model(m_model);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -284,6 +291,7 @@ namespace opt {
|
|||
expr_ref_vector m_assignment;
|
||||
vector<rational> m_weights;
|
||||
rational m_upper;
|
||||
model_ref m_model;
|
||||
|
||||
imp(ast_manager& m, opt_solver& s, expr_ref_vector& soft_constraints, vector<rational> const& weights):
|
||||
m(m), s(s), m_soft(soft_constraints), m_assignment(m), m_weights(weights)
|
||||
|
@ -337,6 +345,7 @@ namespace opt {
|
|||
}
|
||||
}
|
||||
m_upper = wth.get_min_cost();
|
||||
wth.get_model(m_model);
|
||||
TRACE("opt", tout << "min cost: " << m_upper << "\n";);
|
||||
wth.reset();
|
||||
return result;
|
||||
|
@ -349,6 +358,11 @@ namespace opt {
|
|||
rational get_upper() const {
|
||||
return m_upper;
|
||||
}
|
||||
|
||||
void get_model(model_ref& mdl) {
|
||||
mdl = m_model.get();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
wmaxsmt::wmaxsmt(ast_manager& m, opt_solver& s, expr_ref_vector& soft_constraints, vector<rational> const& weights) {
|
||||
|
@ -380,6 +394,9 @@ namespace opt {
|
|||
void wmaxsmt::collect_statistics(statistics& st) const {
|
||||
// no-op
|
||||
}
|
||||
void wmaxsmt::get_model(model_ref& mdl) {
|
||||
m_imp->get_model(mdl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace opt {
|
|||
virtual expr_ref_vector get_assignment() const;
|
||||
virtual void set_cancel(bool f);
|
||||
virtual void collect_statistics(statistics& st) const;
|
||||
virtual void get_model(model_ref& mdl);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue