3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-05 21:53:23 +00:00
This commit is contained in:
Anh-Dung Phan 2013-11-25 12:16:34 -08:00
parent 8fe50ff2d9
commit 87a2b99091
8 changed files with 38 additions and 14 deletions

View file

@ -98,7 +98,7 @@ public:
expr_ref_vector minimize_model(ptr_vector<expr> const & formulas, model_ref& mdl); expr_ref_vector minimize_model(ptr_vector<expr> const & formulas, model_ref& mdl);
/** /**
\brief extract literals from formulas that satisfy formulas. \brief extract literals from model that satisfy formulas.
\pre model satisfies formulas \pre model satisfies formulas
*/ */

View file

@ -104,8 +104,6 @@ namespace opt {
} }
} }
static unsigned g_checksat_count = 0;
bool opt_solver::dump_benchmarks() { bool opt_solver::dump_benchmarks() {
return m_dump_benchmarks; return m_dump_benchmarks;
} }

View file

@ -34,6 +34,17 @@ Notes:
namespace smt { namespace smt {
enum min_flow_result {
// Min cost flow problem is infeasible.
// Diff logic optimization could be unbounded or infeasible.
INFEASIBLE,
// Min cost flow and diff logic optimization are both optimal.
OPTIMAL,
// Min cost flow problem is unbounded.
// Diff logic optimization has to be infeasible.
UNBOUNDED,
};
enum pivot_rule { enum pivot_rule {
// First eligible edge pivot rule // First eligible edge pivot rule
// Edges are traversed in a wraparound fashion // Edges are traversed in a wraparound fashion
@ -281,6 +292,7 @@ namespace smt {
bool edge_in_tree(edge_id id) const; bool edge_in_tree(edge_id id) const;
bool is_infeasible();
bool check_well_formed(); bool check_well_formed();
bool check_optimal(); bool check_optimal();
@ -294,7 +306,7 @@ namespace smt {
// Minimize cost flows // Minimize cost flows
// Return true if found an optimal solution, and return false if unbounded // Return true if found an optimal solution, and return false if unbounded
bool min_cost(pivot_rule pr = FIRST_ELIGIBLE); min_flow_result min_cost(pivot_rule pr = FIRST_ELIGIBLE);
// Compute the optimal solution // Compute the optimal solution
numeral get_optimal_solution(vector<numeral> & result, bool is_dual); numeral get_optimal_solution(vector<numeral> & result, bool is_dual);

View file

@ -263,13 +263,12 @@ namespace smt {
} }
// Minimize cost flows // Minimize cost flows
// Return true if found an optimal solution, and return false if unbounded
template<typename Ext> template<typename Ext>
bool network_flow<Ext>::min_cost(pivot_rule pr) { min_flow_result network_flow<Ext>::min_cost(pivot_rule pr) {
initialize(); initialize();
while (choose_entering_edge(pr)) { while (choose_entering_edge(pr)) {
bool bounded = choose_leaving_edge(); bool bounded = choose_leaving_edge();
if (!bounded) return false; if (!bounded) return UNBOUNDED;
update_flows(); update_flows();
if (m_enter_id != m_leave_id) { if (m_enter_id != m_leave_id) {
SASSERT(edge_in_tree(m_leave_id)); SASSERT(edge_in_tree(m_leave_id));
@ -282,9 +281,23 @@ namespace smt {
SASSERT(check_well_formed()); SASSERT(check_well_formed());
} }
} }
if (is_infeasible()) return INFEASIBLE;
TRACE("network_flow", tout << "Found optimal solution.\n";); TRACE("network_flow", tout << "Found optimal solution.\n";);
SASSERT(check_optimal()); SASSERT(check_optimal());
return true; return OPTIMAL;
}
template<typename Ext>
bool network_flow<Ext>::is_infeasible() {
#if 0
// Flows of artificial arcs should be zero
unsigned num_nodes = m_graph.get_num_nodes();
unsigned num_edges = m_graph.get_num_edges();
for (unsigned i = 1; i < num_nodes; ++i) {
if (m_flows[num_edges - i].is_pos()) return true;
}
#endif
return false;
} }
// Get the optimal solution // Get the optimal solution

View file

@ -434,7 +434,7 @@ namespace smt {
bool m_eager_gcd; // true if gcd should be applied at every add_row bool m_eager_gcd; // true if gcd should be applied at every add_row
unsigned m_final_check_idx; unsigned m_final_check_idx;
u_map<uint_set> m_objective_vars; u_map<uint_set> m_objective_theory_vars;
// backtracking // backtracking
svector<bound_trail> m_bound_trail; svector<bound_trail> m_bound_trail;

View file

@ -1015,7 +1015,7 @@ namespace smt {
theory_var v = internalize_term_core(term); theory_var v = internalize_term_core(term);
uint_set vars; uint_set vars;
if (get_theory_vars(term, vars)) { if (get_theory_vars(term, vars)) {
m_objective_vars.insert(v, vars); m_objective_theory_vars.insert(v, vars);
} }
return v; return v;
} }
@ -1024,9 +1024,9 @@ namespace smt {
inf_eps_rational<inf_rational> theory_arith<Ext>::maximize(theory_var v) { inf_eps_rational<inf_rational> theory_arith<Ext>::maximize(theory_var v) {
bool r = max_min(v, true); bool r = max_min(v, true);
if (r || at_upper(v)) { if (r || at_upper(v)) {
if (m_objective_vars.contains(v)) { if (m_objective_theory_vars.contains(v)) {
// FIXME: put this block inside verbose code // FIXME: put this block inside verbose code
uint_set & vars = m_objective_vars[v]; uint_set & vars = m_objective_theory_vars[v];
uint_set::iterator it = vars.begin(), end = vars.end(); uint_set::iterator it = vars.begin(), end = vars.end();
ast_manager& m = get_manager(); ast_manager& m = get_manager();
IF_VERBOSE(1, IF_VERBOSE(1,

View file

@ -1226,6 +1226,7 @@ namespace smt {
m_nl_rounds = 0; m_nl_rounds = 0;
m_nl_gb_exhausted = false; m_nl_gb_exhausted = false;
m_nl_strategy_idx = 0; m_nl_strategy_idx = 0;
m_objective_theory_vars .reset();
theory::reset_eh(); theory::reset_eh();
} }

View file

@ -1027,8 +1027,8 @@ inf_eps_rational<inf_rational> theory_diff_logic<Ext>::maximize(theory_var v) {
} }
network_flow<GExt> net_flow(m_graph, balances); network_flow<GExt> net_flow(m_graph, balances);
bool is_optimal = net_flow.min_cost(); min_flow_result result = net_flow.min_cost();
if (is_optimal) { if (result == OPTIMAL) {
numeral objective_value = net_flow.get_optimal_solution(m_objective_assignments[v], true) + numeral(m_objective_consts[v]); numeral objective_value = net_flow.get_optimal_solution(m_objective_assignments[v], true) + numeral(m_objective_consts[v]);
IF_VERBOSE(1, verbose_stream() << "Optimal value of objective " << v << ": " << objective_value << std::endl;); IF_VERBOSE(1, verbose_stream() << "Optimal value of objective " << v << ": " << objective_value << std::endl;);