3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-23 14:23:40 +00:00

Merge branch 'master' of https://github.com/z3prover/z3 into opt

This commit is contained in:
Nikolaj Bjorner 2016-12-26 10:19:51 -08:00
commit cb10a618a1
13 changed files with 68 additions and 27 deletions

View file

@ -289,6 +289,10 @@ extern "C" {
//LOG_Z3_optimize_from_file(c, d, s); //LOG_Z3_optimize_from_file(c, d, s);
std::ifstream is(s); std::ifstream is(s);
if (!is) { if (!is) {
std::ostringstream strm;
strm << "Could not open file " << s;
throw default_exception(strm.str());
SET_ERROR_CODE(Z3_PARSER_ERROR); SET_ERROR_CODE(Z3_PARSER_ERROR);
return; return;
} }

View file

@ -350,8 +350,10 @@ namespace opt {
for (unsigned i = 0; i < m_soft_constraints.size(); ++i) { for (unsigned i = 0; i < m_soft_constraints.size(); ++i) {
expr* e = m_soft_constraints[i]; expr* e = m_soft_constraints[i];
bool is_not = m.is_not(e, e); bool is_not = m.is_not(e, e);
out << mk_pp(e, m) out << m_weights[i] << ": " << mk_pp(e, m)
<< ((is_not != get_assignment(i))?" |-> true\n":" |-> false\n"); << ((is_not != get_assignment(i))?" |-> true ":" |-> false ")
<< "\n";
} }
} }

View file

@ -792,10 +792,14 @@ namespace opt {
arg = mk_not(m, arg); arg = mk_not(m, arg);
offset -= weight; offset -= weight;
} }
if (m.is_true(arg) || weight.is_zero()) { if (m.is_true(arg)) {
IF_VERBOSE(1, verbose_stream() << weight << ": " << mk_pp(m_objectives[index].m_terms[i].get(), m) << " |-> true\n";);
}
else if (weight.is_zero()) {
// skip // skip
} }
else if (m.is_false(arg)) { else if (m.is_false(arg)) {
IF_VERBOSE(1, verbose_stream() << weight << ": " << mk_pp(m_objectives[index].m_terms[i].get(), m) << " |-> false\n";);
offset += weight; offset += weight;
} }
else { else {

View file

@ -26,6 +26,7 @@ namespace sat {
m_always_true("always_true"), m_always_true("always_true"),
m_always_false("always_false"), m_always_false("always_false"),
m_caching("caching"), m_caching("caching"),
m_restart_max(0),
m_random("random"), m_random("random"),
m_geometric("geometric"), m_geometric("geometric"),
m_luby("luby"), m_luby("luby"),
@ -66,7 +67,8 @@ namespace sat {
m_restart_initial = p.restart_initial(); m_restart_initial = p.restart_initial();
m_restart_factor = p.restart_factor(); m_restart_factor = p.restart_factor();
m_restart_max = p.restart_max();
m_random_freq = p.random_freq(); m_random_freq = p.random_freq();
m_random_seed = p.random_seed(); m_random_seed = p.random_seed();
if (m_random_seed == 0) if (m_random_seed == 0)

View file

@ -52,6 +52,7 @@ namespace sat {
restart_strategy m_restart; restart_strategy m_restart;
unsigned m_restart_initial; unsigned m_restart_initial;
double m_restart_factor; // for geometric case double m_restart_factor; // for geometric case
unsigned m_restart_max;
double m_random_freq; double m_random_freq;
unsigned m_random_seed; unsigned m_random_seed;
unsigned m_burst_search; unsigned m_burst_search;

View file

@ -7,6 +7,7 @@ def_module_params('sat',
('phase.caching.off', UINT, 100, 'phase caching off period (in number of conflicts)'), ('phase.caching.off', UINT, 100, 'phase caching off period (in number of conflicts)'),
('restart', SYMBOL, 'luby', 'restart strategy: luby or geometric'), ('restart', SYMBOL, 'luby', 'restart strategy: luby or geometric'),
('restart.initial', UINT, 100, 'initial restart (number of conflicts)'), ('restart.initial', UINT, 100, 'initial restart (number of conflicts)'),
('restart.max', UINT, 0, 'maximal number of restarts. Ignored if set to 0'),
('restart.factor', DOUBLE, 1.5, 'restart increment factor for geometric strategy'), ('restart.factor', DOUBLE, 1.5, 'restart increment factor for geometric strategy'),
('random_freq', DOUBLE, 0.01, 'frequency of random case splits'), ('random_freq', DOUBLE, 0.01, 'frequency of random case splits'),
('random_seed', UINT, 0, 'random seed'), ('random_seed', UINT, 0, 'random seed'),

View file

@ -744,7 +744,6 @@ namespace sat {
simplify_problem(); simplify_problem();
if (check_inconsistent()) return l_false; if (check_inconsistent()) return l_false;
if (m_config.m_max_conflicts == 0) { if (m_config.m_max_conflicts == 0) {
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat \"abort: max-conflicts = 0\")\n";); IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat \"abort: max-conflicts = 0\")\n";);
return l_undef; return l_undef;
@ -766,6 +765,12 @@ namespace sat {
simplify_problem(); simplify_problem();
if (check_inconsistent()) return l_false; if (check_inconsistent()) return l_false;
gc(); gc();
if (m_config.m_restart_max != 0 && m_config.m_restart_max <= m_restarts) {
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat \"abort: max-restarts\")\n";);
return l_undef;
}
} }
} }
catch (abort_solver) { catch (abort_solver) {
@ -1126,6 +1131,7 @@ namespace sat {
m_restart_threshold = m_config.m_restart_initial; m_restart_threshold = m_config.m_restart_initial;
m_luby_idx = 1; m_luby_idx = 1;
m_gc_threshold = m_config.m_gc_initial; m_gc_threshold = m_config.m_gc_initial;
m_restarts = 0;
m_min_d_tk = 1.0; m_min_d_tk = 1.0;
m_stopwatch.reset(); m_stopwatch.reset();
m_stopwatch.start(); m_stopwatch.start();
@ -1308,6 +1314,7 @@ namespace sat {
void solver::restart() { void solver::restart() {
m_stats.m_restart++; m_stats.m_restart++;
m_restarts++;
IF_VERBOSE(1, IF_VERBOSE(1,
verbose_stream() << "(sat-restart :conflicts " << m_stats.m_conflict << " :decisions " << m_stats.m_decision verbose_stream() << "(sat-restart :conflicts " << m_stats.m_conflict << " :decisions " << m_stats.m_decision
<< " :restarts " << m_stats.m_restart << mk_stat(*this) << " :restarts " << m_stats.m_restart << mk_stat(*this)

View file

@ -293,6 +293,7 @@ namespace sat {
protected: protected:
unsigned m_conflicts; unsigned m_conflicts;
unsigned m_restarts;
unsigned m_conflicts_since_restart; unsigned m_conflicts_since_restart;
unsigned m_restart_threshold; unsigned m_restart_threshold;
unsigned m_luby_idx; unsigned m_luby_idx;

View file

@ -264,7 +264,7 @@ namespace smt {
} }
void arith_eq_adapter::collect_statistics(::statistics & st) const { void arith_eq_adapter::collect_statistics(::statistics & st) const {
st.update("eq adapter", m_stats.m_num_eq_axioms); st.update("arith eq adapter", m_stats.m_num_eq_axioms);
} }
void arith_eq_adapter::display_already_processed(std::ostream & out) const { void arith_eq_adapter::display_already_processed(std::ostream & out) const {

View file

@ -465,7 +465,7 @@ namespace smt {
tout << s_ante << "\n" << s_conseq << "\n";); tout << s_ante << "\n" << s_conseq << "\n";);
literal lits[2] = {l_ante, l_conseq}; literal lits[2] = {l_ante, l_conseq};
ctx.mk_th_axiom(get_id(), 2, lits); mk_clause(l_ante, l_conseq, 0, 0);
if (ctx.relevancy()) { if (ctx.relevancy()) {
if (l_ante == false_literal) { if (l_ante == false_literal) {
ctx.mark_as_relevant(l_conseq); ctx.mark_as_relevant(l_conseq);
@ -934,11 +934,13 @@ namespace smt {
template<typename Ext> template<typename Ext>
void theory_arith<Ext>::mk_clause(literal l1, literal l2, unsigned num_params, parameter * params) { void theory_arith<Ext>::mk_clause(literal l1, literal l2, unsigned num_params, parameter * params) {
TRACE("arith", literal lits[2]; lits[0] = l1; lits[1] = l2; get_context().display_literals_verbose(tout, 2, lits); tout << "\n";);
get_context().mk_th_axiom(get_id(), l1, l2, num_params, params); get_context().mk_th_axiom(get_id(), l1, l2, num_params, params);
} }
template<typename Ext> template<typename Ext>
void theory_arith<Ext>::mk_clause(literal l1, literal l2, literal l3, unsigned num_params, parameter * params) { void theory_arith<Ext>::mk_clause(literal l1, literal l2, literal l3, unsigned num_params, parameter * params) {
TRACE("arith", literal lits[3]; lits[0] = l1; lits[1] = l2; lits[2] = l3; get_context().display_literals_verbose(tout, 3, lits); tout << "\n";);
get_context().mk_th_axiom(get_id(), l1, l2, l3, num_params, params); get_context().mk_th_axiom(get_id(), l1, l2, l3, num_params, params);
} }

View file

@ -44,6 +44,7 @@ namespace smt {
SASSERT(lower_bound(v).is_rational()); SASSERT(lower_bound(v).is_rational());
numeral const & val = lower_bound(v).get_rational(); numeral const & val = lower_bound(v).get_rational();
value_sort_pair key(val, is_int_src(v)); value_sort_pair key(val, is_int_src(v));
TRACE("arith_eq", tout << mk_pp(get_enode(v)->get_owner(), get_manager()) << " = " << val << "\n";);
theory_var v2; theory_var v2;
if (m_fixed_var_table.find(key, v2)) { if (m_fixed_var_table.find(key, v2)) {
if (v2 < static_cast<int>(get_num_vars()) && is_fixed(v2) && lower_bound(v2).get_rational() == val) { if (v2 < static_cast<int>(get_num_vars()) && is_fixed(v2) && lower_bound(v2).get_rational() == val) {
@ -247,6 +248,7 @@ namespace smt {
// //
// x1 <= k1 x1 >= k1, x2 <= x1 + k2 x2 >= x1 + k2 // x1 <= k1 x1 >= k1, x2 <= x1 + k2 x2 >= x1 + k2
// //
TRACE("arith_eq_propagation", tout << "fixed\n";);
lower(x2)->push_justification(ante, numeral::zero(), proofs_enabled()); lower(x2)->push_justification(ante, numeral::zero(), proofs_enabled());
upper(x2)->push_justification(ante, numeral::zero(), proofs_enabled()); upper(x2)->push_justification(ante, numeral::zero(), proofs_enabled());
m_stats.m_fixed_eqs++; m_stats.m_fixed_eqs++;
@ -324,28 +326,42 @@ namespace smt {
template<typename Ext> template<typename Ext>
void theory_arith<Ext>::propagate_eq_to_core(theory_var x, theory_var y, antecedents& antecedents) { void theory_arith<Ext>::propagate_eq_to_core(theory_var x, theory_var y, antecedents& antecedents) {
// Ignore equality if variables are already known to be equal. // Ignore equality if variables are already known to be equal.
ast_manager& m = get_manager();
if (is_equal(x, y)) if (is_equal(x, y))
return; return;
// I doesn't make sense to propagate an equality (to the core) of variables of different sort. // I doesn't make sense to propagate an equality (to the core) of variables of different sort.
if (get_manager().get_sort(var2expr(x)) != get_manager().get_sort(var2expr(y))) { if (m.get_sort(var2expr(x)) != m.get_sort(var2expr(y))) {
TRACE("arith", tout << mk_pp(var2expr(x), get_manager()) << " = " << mk_pp(var2expr(y), get_manager()) << "\n";); TRACE("arith", tout << mk_pp(var2expr(x), m) << " = " << mk_pp(var2expr(y), m) << "\n";);
return; return;
} }
context & ctx = get_context(); context & ctx = get_context();
region & r = ctx.get_region(); region & r = ctx.get_region();
enode * _x = get_enode(x); enode * _x = get_enode(x);
enode * _y = get_enode(y); enode * _y = get_enode(y);
eq_vector const& eqs = antecedents.eqs();
literal_vector const& lits = antecedents.lits();
justification * js = justification * js =
ctx.mk_justification( ctx.mk_justification(
ext_theory_eq_propagation_justification( ext_theory_eq_propagation_justification(
get_id(), r, get_id(), r,
antecedents.lits().size(), antecedents.lits().c_ptr(), lits.size(), lits.c_ptr(),
antecedents.eqs().size(), antecedents.eqs().c_ptr(), eqs.size(), eqs.c_ptr(),
_x, _y, _x, _y,
antecedents.num_params(), antecedents.params("eq-propagate"))); antecedents.num_params(), antecedents.params("eq-propagate")));
TRACE("arith_eq", tout << "detected equality: #" << _x->get_owner_id() << " = #" << _y->get_owner_id() << "\n"; TRACE("arith_eq", tout << "detected equality: #" << _x->get_owner_id() << " = #" << _y->get_owner_id() << "\n";
display_var(tout, x); display_var(tout, x);
display_var(tout, y);); display_var(tout, y););
TRACE("arith_eq_propagation",
for (unsigned i = 0; i < lits.size(); ++i) {
ctx.display_detailed_literal(tout, lits[i]);
tout << "\n";
}
for (unsigned i = 0; i < eqs.size(); ++i) {
tout << mk_pp(eqs[i].first->get_owner(), m) << " = " << mk_pp(eqs[i].second->get_owner(), m) << "\n";
}
tout << " ==> ";
tout << mk_pp(_x->get_owner(), m) << " = " << mk_pp(_y->get_owner(), m) << "\n";
);
ctx.assign_eq(_x, _y, eq_justification(js)); ctx.assign_eq(_x, _y, eq_justification(js));
} }
}; };

View file

@ -27,22 +27,22 @@ namespace smt {
template<typename Ext> template<typename Ext>
void theory_arith<Ext>::collect_statistics(::statistics & st) const { void theory_arith<Ext>::collect_statistics(::statistics & st) const {
st.update("arith conflicts", m_stats.m_conflicts); st.update("arith conflicts", m_stats.m_conflicts);
st.update("add rows", m_stats.m_add_rows); st.update("arith add rows", m_stats.m_add_rows);
st.update("pivots", m_stats.m_pivots); st.update("arith pivots", m_stats.m_pivots);
st.update("assert lower", m_stats.m_assert_lower); st.update("arith assert lower", m_stats.m_assert_lower);
st.update("assert upper", m_stats.m_assert_upper); st.update("arith assert upper", m_stats.m_assert_upper);
st.update("assert diseq", m_stats.m_assert_diseq); st.update("arith assert diseq", m_stats.m_assert_diseq);
st.update("bound prop", m_stats.m_bound_props); st.update("arith bound prop", m_stats.m_bound_props);
st.update("fixed eqs", m_stats.m_fixed_eqs); st.update("arith fixed eqs", m_stats.m_fixed_eqs);
st.update("offset eqs", m_stats.m_offset_eqs); st.update("arith offset eqs", m_stats.m_offset_eqs);
st.update("gcd tests", m_stats.m_gcd_tests); st.update("arith gcd tests", m_stats.m_gcd_tests);
st.update("ineq splits", m_stats.m_branches); st.update("arith ineq splits", m_stats.m_branches);
st.update("gomory cuts", m_stats.m_gomory_cuts); st.update("arith gomory cuts", m_stats.m_gomory_cuts);
st.update("max-min", m_stats.m_max_min); st.update("arith max-min", m_stats.m_max_min);
st.update("grobner", m_stats.m_gb_compute_basis); st.update("arith grobner", m_stats.m_gb_compute_basis);
st.update("pseudo nonlinear", m_stats.m_nl_linear); st.update("arith pseudo nonlinear", m_stats.m_nl_linear);
st.update("nonlinear bounds", m_stats.m_nl_bounds); st.update("arith nonlinear bounds", m_stats.m_nl_bounds);
st.update("nonlinear horner", m_stats.m_nl_cross_nested); st.update("arith nonlinear horner", m_stats.m_nl_cross_nested);
m_arith_eq_adapter.collect_statistics(st); m_arith_eq_adapter.collect_statistics(st);
} }

View file

@ -808,6 +808,7 @@ namespace smt {
void theory_pb::assign_eh(bool_var v, bool is_true) { void theory_pb::assign_eh(bool_var v, bool is_true) {
ptr_vector<ineq>* ineqs = 0; ptr_vector<ineq>* ineqs = 0;
literal nlit(v, is_true); literal nlit(v, is_true);
init_watch(v);
TRACE("pb", tout << "assign: " << ~nlit << "\n";); TRACE("pb", tout << "assign: " << ~nlit << "\n";);
ineqs = m_var_infos[v].m_lit_watch[nlit.sign()]; ineqs = m_var_infos[v].m_lit_watch[nlit.sign()];
if (ineqs != 0) { if (ineqs != 0) {