mirror of
https://github.com/Z3Prover/z3
synced 2025-08-08 12:11:23 +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
|
@ -414,6 +414,7 @@ private:
|
|||
}
|
||||
break;
|
||||
case DL_PROCESSED:
|
||||
TRACE("arith", display_edge(tout << "processed twice: ", e););
|
||||
// if two edges with the same source/target occur in the graph.
|
||||
break;
|
||||
default:
|
||||
|
@ -514,10 +515,8 @@ public:
|
|||
// The method assumes the graph is feasible before the invocation.
|
||||
bool enable_edge(edge_id id) {
|
||||
edge& e = m_edges[id];
|
||||
SASSERT(is_feasible());
|
||||
bool r = true;
|
||||
if (!is_feasible()) {
|
||||
return false;
|
||||
}
|
||||
if (!e.is_enabled()) {
|
||||
e.enable(m_timestamp);
|
||||
m_last_enabled_edge = id;
|
||||
|
|
|
@ -985,6 +985,8 @@ namespace smt {
|
|||
TRACE("opt", S.display(tout); );
|
||||
SASSERT(is_sat != l_false);
|
||||
lbool is_fin = S.minimize(w);
|
||||
|
||||
ensure_rational_solution(S);
|
||||
|
||||
switch (is_fin) {
|
||||
case l_true: {
|
||||
|
@ -1010,10 +1012,10 @@ namespace smt {
|
|||
}
|
||||
for (unsigned i = 0; i < num_nodes; ++i) {
|
||||
mpq_inf const& val = S.get_value(i);
|
||||
rational q(val.first), eps(val.second);
|
||||
rational q(val.first);
|
||||
SASSERT(rational(val.second).is_zero());
|
||||
numeral a(q);
|
||||
m_assignment[i] = a;
|
||||
// TBD: if epsilon is != 0, then adjust a by some small fraction.
|
||||
}
|
||||
inf_eps result(rational(0), r);
|
||||
blocker = mk_gt(v, result);
|
||||
|
|
|
@ -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