mirror of
https://github.com/Z3Prover/z3
synced 2025-05-11 17:54:43 +00:00
fix #4116
delta has to be computed based on Simplex tableau not on difference graph.
This commit is contained in:
parent
3a63c3751e
commit
4f462925a0
7 changed files with 91 additions and 21 deletions
|
@ -341,7 +341,9 @@ void theory_diff_logic<Ext>::pop_scope_eh(unsigned num_scopes) {
|
|||
m_scopes.shrink(new_lvl);
|
||||
unsigned num_edges = m_graph.get_num_edges();
|
||||
m_graph.pop(num_scopes);
|
||||
if (num_edges != m_graph.get_num_edges() && m_num_simplex_edges > 0) {
|
||||
TRACE("arith", m_graph.display(tout););
|
||||
SASSERT(m_graph.is_feasible());
|
||||
if (true || (num_edges != m_graph.get_num_edges() && m_num_simplex_edges > 0)) {
|
||||
m_S.reset();
|
||||
m_num_simplex_edges = 0;
|
||||
m_objective_rows.reset();
|
||||
|
@ -565,6 +567,7 @@ bool theory_diff_logic<Ext>::propagate_atom(atom* a) {
|
|||
}
|
||||
int edge_id = a->get_asserted_edge();
|
||||
if (!m_graph.enable_edge(edge_id)) {
|
||||
TRACE("arith", display(tout););
|
||||
set_neg_cycle_conflict();
|
||||
return false;
|
||||
}
|
||||
|
@ -685,11 +688,8 @@ void theory_diff_logic<Ext>::set_neg_cycle_conflict() {
|
|||
context & ctx = get_context();
|
||||
TRACE("arith_conflict",
|
||||
tout << "conflict: ";
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
ctx.display_literal_info(tout, lits[i]);
|
||||
}
|
||||
tout << "\n";
|
||||
);
|
||||
for (literal lit : lits) ctx.display_literal_info(tout, lit);
|
||||
tout << "\n";);
|
||||
|
||||
if (dump_lemmas()) {
|
||||
symbol logic(m_lia_or_lra == is_lia ? "QF_LIA" : "QF_LRA");
|
||||
|
@ -911,6 +911,7 @@ void theory_diff_logic<Ext>::compute_delta() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
template<typename Ext>
|
||||
void theory_diff_logic<Ext>::init_model(smt::model_generator & m) {
|
||||
m_factory = alloc(arith_factory, get_manager());
|
||||
|
@ -935,9 +936,11 @@ model_value_proc * theory_diff_logic<Ext>::mk_value(enode * n, model_generator &
|
|||
|
||||
template<typename Ext>
|
||||
void theory_diff_logic<Ext>::display(std::ostream & out) const {
|
||||
for (unsigned i = 0; i < m_atoms.size(); ++i) {
|
||||
m_atoms[i]->display(*this, out);
|
||||
out << "atoms\n";
|
||||
for (atom* a : m_atoms) {
|
||||
a->display(*this, out) << "\n";
|
||||
}
|
||||
out << "graph\n";
|
||||
m_graph.display(out);
|
||||
}
|
||||
|
||||
|
@ -1150,6 +1153,8 @@ void theory_diff_logic<Ext>::update_simplex(Simplex& S) {
|
|||
}
|
||||
S.set_lower(node2simplex(get_zero(true)), mpq_inf(mpq(0), mpq(0)));
|
||||
S.set_upper(node2simplex(get_zero(true)), mpq_inf(mpq(0), mpq(0)));
|
||||
S.set_lower(node2simplex(get_zero(false)), mpq_inf(mpq(0), mpq(0)));
|
||||
S.set_upper(node2simplex(get_zero(false)), mpq_inf(mpq(0), mpq(0)));
|
||||
svector<unsigned> vars;
|
||||
scoped_mpq_vector coeffs(mgr);
|
||||
coeffs.push_back(mpq(1));
|
||||
|
@ -1215,6 +1220,8 @@ typename theory_diff_logic<Ext>::inf_eps theory_diff_logic<Ext>::value(theory_va
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename Ext>
|
||||
typename theory_diff_logic<Ext>::inf_eps
|
||||
theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shared) {
|
||||
|
@ -1224,6 +1231,9 @@ theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shar
|
|||
Simplex& S = m_S;
|
||||
ast_manager& m = get_manager();
|
||||
|
||||
CTRACE("arith",!m_graph.is_feasible(), m_graph.display(tout););
|
||||
SASSERT(m_graph.is_feasible());
|
||||
|
||||
update_simplex(S);
|
||||
|
||||
TRACE("arith",
|
||||
|
@ -1235,7 +1245,12 @@ theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shar
|
|||
tout << "Free coefficient " << m_objective_consts[v] << "\n";
|
||||
);
|
||||
|
||||
TRACE("opt", S.display(tout); display(tout););
|
||||
TRACE("opt",
|
||||
S.display(tout);
|
||||
for (unsigned i = 0; i < m_graph.get_num_nodes(); ++i)
|
||||
tout << "$" << i << ": " << node2simplex(i) << "\n";
|
||||
display(tout);
|
||||
);
|
||||
|
||||
// optimize
|
||||
lbool is_sat = S.make_feasible();
|
||||
|
@ -1252,8 +1267,6 @@ theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shar
|
|||
simplex::mpq_ext::eps_numeral const& val = S.get_value(w);
|
||||
inf_rational r(-rational(val.first), -rational(val.second));
|
||||
Simplex::row row = m_objective_rows[v];
|
||||
TRACE("opt", tout << r << " " << "\n";
|
||||
S.display_row(tout, row, true););
|
||||
Simplex::row_iterator it = S.row_begin(row), end = S.row_end(row);
|
||||
expr_ref_vector& core = m_objective_assignments[v];
|
||||
expr_ref tmp(m);
|
||||
|
@ -1269,13 +1282,21 @@ theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker, bool& has_shar
|
|||
}
|
||||
}
|
||||
}
|
||||
compute_delta();
|
||||
ensure_rational_solution(S);
|
||||
TRACE("opt", tout << r << " " << "\n";
|
||||
S.display_row(tout, row, true);
|
||||
S.display(tout);
|
||||
);
|
||||
|
||||
for (unsigned i = 0; i < m_graph.get_num_nodes(); ++i) {
|
||||
unsigned w = node2simplex(i);
|
||||
simplex::mpq_ext::eps_numeral const& val = S.get_value(w);
|
||||
rational r = rational(val.first) + m_delta*rational(val.second);
|
||||
auto const& val = S.get_value(w);
|
||||
SASSERT(rational(val.second).is_zero());
|
||||
rational r = rational(val.first);
|
||||
m_graph.set_assignment(i, numeral(r));
|
||||
}
|
||||
CTRACE("arith",!m_graph.is_feasible(), m_graph.display(tout););
|
||||
SASSERT(m_graph.is_feasible());
|
||||
inf_eps r1(rational(0), r);
|
||||
blocker = mk_gt(v, r1);
|
||||
return inf_eps(rational(0), r + m_objective_consts[v]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue