3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-08 12:11:23 +00:00
delta has to be computed based on Simplex tableau not on difference graph.
This commit is contained in:
Nikolaj Bjorner 2020-04-27 17:07:12 -07:00
parent 3a63c3751e
commit 4f462925a0
7 changed files with 91 additions and 21 deletions

View file

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

View file

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

View file

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