3
0
Fork 0
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:
Nikolaj Bjorner 2013-12-10 15:16:58 -08:00
parent 26bf64a0c3
commit 2c577a304d
15 changed files with 348 additions and 197 deletions

View file

@ -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();
}
};

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
};
};

View file

@ -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) {

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
};
};