3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-03 04:41:21 +00:00

bug fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-06-22 15:01:12 -07:00
parent 9ebe980b44
commit 5752830f71
10 changed files with 112 additions and 46 deletions

View file

@ -831,15 +831,17 @@ struct pb2bv_rewriter::imp {
p.get_bool("keep_pb_constraints", false) || p.get_bool("keep_pb_constraints", false) ||
p.get_bool("sat.pb.solver", false) || p.get_bool("sat.pb.solver", false) ||
p.get_bool("pb.solver", false) || p.get_bool("pb.solver", false) ||
gparams::get_module("sat").get_bool("pb.solver", false); gparams::get_module("sat").get_sym("pb.solver", symbol()) == symbol("solver") ;
} }
bool pb_num_system() const { bool pb_num_system() const {
return m_params.get_bool("pb_num_system", false); return m_params.get_bool("pb_num_system", false) ||
gparams::get_module("sat").get_sym("pb.solver", symbol()) == symbol("sorting");
} }
bool pb_totalizer() const { bool pb_totalizer() const {
return m_params.get_bool("pb_totalizer", false); return m_params.get_bool("pb_totalizer", false) ||
gparams::get_module("sat").get_sym("pb.solver", symbol()) == symbol("totalizer");
} }
imp(ast_manager& m, params_ref const& p): imp(ast_manager& m, params_ref const& p):

View file

@ -241,7 +241,7 @@ namespace sat {
if (slack < bound) { if (slack < bound) {
literal lit = p[j].second; literal lit = p[j].second;
SASSERT(value(p[j].second) == l_false); SASSERT(value(lit) == l_false);
for (unsigned i = j + 1; i < sz; ++i) { for (unsigned i = j + 1; i < sz; ++i) {
if (lvl(lit) < lvl(p[i].second)) { if (lvl(lit) < lvl(p[i].second)) {
lit = p[i].second; lit = p[i].second;
@ -365,7 +365,10 @@ namespace sat {
literal_vector to_assign; literal_vector to_assign;
while (!m_pb_undef.empty()) { while (!m_pb_undef.empty()) {
index1 = m_pb_undef.back(); index1 = m_pb_undef.back();
if (index1 == num_watch) index1 = index; // it was swapped with index above.
literal lit = p[index1].second; literal lit = p[index1].second;
if (value(lit) != l_undef) std::cout << "not undef: " << index1 << " " << lit << " " << value(lit) << "\n";
SASSERT(value(lit) == l_undef);
TRACE("sat", tout << index1 << " " << lit << "\n";); TRACE("sat", tout << index1 << " " << lit << "\n";);
if (slack >= bound + p[index1].first) { if (slack >= bound + p[index1].first) {
break; break;
@ -376,9 +379,7 @@ namespace sat {
for (literal lit : to_assign) { for (literal lit : to_assign) {
if (inconsistent()) break; if (inconsistent()) break;
if (value(lit) == l_undef) { assign(p, lit);
assign(p, lit);
}
} }
} }
@ -594,8 +595,8 @@ namespace sat {
unsigned sz = x.size(); unsigned sz = x.size();
TRACE("sat", tout << "assign: " << x.lit() << ": " << ~alit << "@" << lvl(~alit) << "\n";); TRACE("sat", tout << "assign: " << x.lit() << ": " << ~alit << "@" << lvl(~alit) << "\n";);
SASSERT(value(alit) != l_undef);
SASSERT(x.lit() == null_literal || value(x.lit()) == l_true); SASSERT(x.lit() == null_literal || value(x.lit()) == l_true);
SASSERT(value(alit) != l_undef);
unsigned index = 0; unsigned index = 0;
for (; index <= 2; ++index) { for (; index <= 2; ++index) {
if (x[index].var() == alit.var()) break; if (x[index].var() == alit.var()) break;
@ -791,9 +792,7 @@ namespace sat {
m_bound += offset; m_bound += offset;
inc_coeff(consequent, offset); inc_coeff(consequent, offset);
get_xor_antecedents(consequent, idx, js, m_lemma); get_xor_antecedents(consequent, idx, js, m_lemma);
for (unsigned i = 0; i < m_lemma.size(); ++i) { for (literal l : m_lemma) process_antecedent(~l, offset);
process_antecedent(~m_lemma[i], offset);
}
++m_stats.m_num_xor_resolves; ++m_stats.m_num_xor_resolves;
} }
else if (is_pb_index(index)) { else if (is_pb_index(index)) {
@ -803,9 +802,7 @@ namespace sat {
inc_coeff(consequent, offset); inc_coeff(consequent, offset);
get_pb_antecedents(consequent, p, m_lemma); get_pb_antecedents(consequent, p, m_lemma);
TRACE("sat", display(tout, p, true); tout << m_lemma << "\n";); TRACE("sat", display(tout, p, true); tout << m_lemma << "\n";);
for (unsigned i = 0; i < m_lemma.size(); ++i) { for (literal l : m_lemma) process_antecedent(~l, offset);
process_antecedent(~m_lemma[i], offset);
}
++m_stats.m_num_pb_resolves; ++m_stats.m_num_pb_resolves;
} }
else { else {
@ -1063,12 +1060,16 @@ namespace sat {
void card_extension::propagate(literal l, ext_constraint_idx idx, bool & keep) { void card_extension::propagate(literal l, ext_constraint_idx idx, bool & keep) {
SASSERT(value(l) == l_true);
TRACE("sat", tout << l << " " << idx << "\n";); TRACE("sat", tout << l << " " << idx << "\n";);
if (is_pb_index(idx)) { if (is_pb_index(idx)) {
pb& p = index2pb(idx); pb& p = index2pb(idx);
if (l.var() == p.lit().var()) { if (l.var() == p.lit().var()) {
init_watch(p, !l.sign()); init_watch(p, !l.sign());
} }
else if (p.lit() != null_literal && value(p.lit()) != l_true) {
keep = false;
}
else { else {
keep = l_undef != add_assign(p, ~l); keep = l_undef != add_assign(p, ~l);
} }
@ -1078,6 +1079,9 @@ namespace sat {
if (l.var() == c.lit().var()) { if (l.var() == c.lit().var()) {
init_watch(c, !l.sign()); init_watch(c, !l.sign());
} }
else if (c.lit() != null_literal && value(c.lit()) != l_true) {
keep = false;
}
else { else {
keep = l_undef != add_assign(c, ~l); keep = l_undef != add_assign(c, ~l);
} }
@ -1087,6 +1091,9 @@ namespace sat {
if (l.var() == x.lit().var()) { if (l.var() == x.lit().var()) {
init_watch(x, !l.sign()); init_watch(x, !l.sign());
} }
else if (x.lit() != null_literal && value(x.lit()) != l_true) {
keep = false;
}
else { else {
keep = l_undef != add_assign(x, ~l); keep = l_undef != add_assign(x, ~l);
} }
@ -1206,6 +1213,16 @@ namespace sat {
SASSERT(p.lit() == null_literal || value(p.lit()) == l_true); SASSERT(p.lit() == null_literal || value(p.lit()) == l_true);
TRACE("sat", display(tout, p, true);); TRACE("sat", display(tout, p, true););
if (value(l) == l_false) {
for (wliteral wl : p) {
literal lit = wl.second;
if (lit != l && value(lit) == l_false) {
r.push_back(~lit);
}
}
return;
}
// unsigned coeff = get_coeff(p, l); // unsigned coeff = get_coeff(p, l);
unsigned coeff = 0; unsigned coeff = 0;
for (unsigned j = 0; j < p.num_watch(); ++j) { for (unsigned j = 0; j < p.num_watch(); ++j) {
@ -1214,6 +1231,13 @@ namespace sat {
break; break;
} }
} }
if (coeff == 0) {
std::cout << l << " coeff: " << coeff << "\n";
display(std::cout, p, true);
}
SASSERT(coeff > 0);
unsigned slack = p.slack() - coeff; unsigned slack = p.slack() - coeff;
unsigned i = p.num_watch(); unsigned i = p.num_watch();
@ -1225,6 +1249,10 @@ namespace sat {
} }
for (; i < p.size(); ++i) { for (; i < p.size(); ++i) {
literal lit = p[i].second; literal lit = p[i].second;
if (l_false != value(lit)) {
std::cout << l << " index: " << i << " slack: " << slack << " h: " << h << " coeff: " << coeff << "\n";
display(std::cout, p, true);
}
SASSERT(l_false == value(lit)); SASSERT(l_false == value(lit));
r.push_back(~lit); r.push_back(~lit);
} }

View file

@ -82,6 +82,9 @@ namespace sat {
unsigned index() const { return m_index; } unsigned index() const { return m_index; }
literal lit() const { return m_lit; } literal lit() const { return m_lit; }
wliteral operator[](unsigned i) const { return m_wlits[i]; } wliteral operator[](unsigned i) const { return m_wlits[i]; }
wliteral const* begin() const { return m_wlits; }
wliteral const* end() const { return (wliteral const*)m_wlits + m_size; }
unsigned k() const { return m_k; } unsigned k() const { return m_k; }
unsigned size() const { return m_size; } unsigned size() const { return m_size; }
unsigned slack() const { return m_slack; } unsigned slack() const { return m_slack; }

View file

@ -147,6 +147,24 @@ namespace sat {
m_step_size_min = 0.06; m_step_size_min = 0.06;
m_reward_multiplier = 0.9; m_reward_multiplier = 0.9;
m_reward_offset = 1000000.0; m_reward_offset = 1000000.0;
// PB parameters
s = p.pb_solver();
if (s == symbol("circuit")) {
m_pb_solver = PB_CIRCUIT;
}
else if (s == symbol("sorting")) {
m_pb_solver = PB_SORTING;
}
else if (s == symbol("totalizer")) {
m_pb_solver = PB_TOTALIZER;
}
else if (s == symbol("solver")) {
m_pb_solver = PB_SOLVER;
}
else {
throw sat_param_exception("invalid PB solver");
}
} }
void config::collect_param_descrs(param_descrs & r) { void config::collect_param_descrs(param_descrs & r) {

View file

@ -50,6 +50,13 @@ namespace sat {
BH_LRB BH_LRB
}; };
enum pb_solver {
PB_SOLVER,
PB_CIRCUIT,
PB_SORTING,
PB_TOTALIZER
};
struct config { struct config {
unsigned long long m_max_memory; unsigned long long m_max_memory;
phase_selection m_phase; phase_selection m_phase;
@ -99,7 +106,9 @@ namespace sat {
symbol m_psm; symbol m_psm;
symbol m_glue; symbol m_glue;
symbol m_glue_psm; symbol m_glue_psm;
symbol m_psm_glue; symbol m_psm_glue;
pb_solver m_pb_solver;
// branching heuristic settings. // branching heuristic settings.
branching_heuristic m_branching_heuristic; branching_heuristic m_branching_heuristic;

View file

@ -29,7 +29,7 @@ def_module_params('sat',
('drat.file', SYMBOL, '', 'file to dump DRAT proofs'), ('drat.file', SYMBOL, '', 'file to dump DRAT proofs'),
('drat.check', BOOL, False, 'build up internal proof and check'), ('drat.check', BOOL, False, 'build up internal proof and check'),
('cardinality.solver', BOOL, False, 'use cardinality solver'), ('cardinality.solver', BOOL, False, 'use cardinality solver'),
('pb.solver', BOOL, False, 'use pb solver'), ('pb.solver', SYMBOL, 'circuit', 'method for handling Pseudo-Boolean constraints: circuit (arithmetical circuit), sorting (sorting circuit), totalizer (use totalizer encoding), solver (use SMT solver)'),
('xor.solver', BOOL, False, 'use xor solver'), ('xor.solver', BOOL, False, 'use xor solver'),
('local_search_threads', UINT, 0, 'number of local search threads to find satisfiable solution'), ('local_search_threads', UINT, 0, 'number of local search threads to find satisfiable solution'),
('local_search', BOOL, False, 'use local search instead of CDCL'), ('local_search', BOOL, False, 'use local search instead of CDCL'),

View file

@ -1961,10 +1961,8 @@ namespace sat {
} }
case justification::EXT_JUSTIFICATION: { case justification::EXT_JUSTIFICATION: {
fill_ext_antecedents(consequent, js); fill_ext_antecedents(consequent, js);
literal_vector::iterator it = m_ext_antecedents.begin(); for (literal l : m_ext_antecedents)
literal_vector::iterator end = m_ext_antecedents.end(); process_antecedent(l, num_marks);
for (; it != end; ++it)
process_antecedent(*it, num_marks);
break; break;
} }
default: default:
@ -2082,10 +2080,9 @@ namespace sat {
} }
case justification::EXT_JUSTIFICATION: { case justification::EXT_JUSTIFICATION: {
fill_ext_antecedents(consequent, js); fill_ext_antecedents(consequent, js);
literal_vector::iterator it = m_ext_antecedents.begin(); for (literal l : m_ext_antecedents) {
literal_vector::iterator end = m_ext_antecedents.end(); process_antecedent_for_unsat_core(l);
for (; it != end; ++it) }
process_antecedent_for_unsat_core(*it);
break; break;
} }
default: default:
@ -2199,10 +2196,9 @@ namespace sat {
SASSERT(not_l != null_literal); SASSERT(not_l != null_literal);
r = lvl(not_l); r = lvl(not_l);
fill_ext_antecedents(~not_l, js); fill_ext_antecedents(~not_l, js);
literal_vector::iterator it = m_ext_antecedents.begin(); for (literal l : m_ext_antecedents) {
literal_vector::iterator end = m_ext_antecedents.end(); r = std::max(r, lvl(l));
for (; it != end; ++it) }
r = std::max(r, lvl(*it));
return r; return r;
} }
default: default:
@ -2414,10 +2410,8 @@ namespace sat {
case justification::EXT_JUSTIFICATION: { case justification::EXT_JUSTIFICATION: {
literal consequent(var, value(var) == l_false); literal consequent(var, value(var) == l_false);
fill_ext_antecedents(consequent, js); fill_ext_antecedents(consequent, js);
literal_vector::iterator it = m_ext_antecedents.begin(); for (literal l : m_ext_antecedents) {
literal_vector::iterator end = m_ext_antecedents.end(); if (!process_antecedent_for_minimization(l)) {
for (; it != end; ++it) {
if (!process_antecedent_for_minimization(*it)) {
reset_unmark(old_size); reset_unmark(old_size);
return false; return false;
} }
@ -2540,10 +2534,8 @@ namespace sat {
} }
case justification::EXT_JUSTIFICATION: { case justification::EXT_JUSTIFICATION: {
fill_ext_antecedents(m_lemma[i], js); fill_ext_antecedents(m_lemma[i], js);
literal_vector::iterator it = m_ext_antecedents.begin(); for (literal l : m_ext_antecedents) {
literal_vector::iterator end = m_ext_antecedents.end(); update_lrb_reasoned(l);
for (; it != end; ++it) {
update_lrb_reasoned(*it);
} }
break; break;
} }
@ -3776,11 +3768,9 @@ namespace sat {
} }
case justification::EXT_JUSTIFICATION: { case justification::EXT_JUSTIFICATION: {
fill_ext_antecedents(lit, js); fill_ext_antecedents(lit, js);
literal_vector::iterator it = m_ext_antecedents.begin(); for (literal l : m_ext_antecedents) {
literal_vector::iterator end = m_ext_antecedents.end(); if (check_domain(lit, l) && all_found) {
for (; it != end; ++it) { s |= m_antecedents.find(l.var());
if (check_domain(lit, *it) && all_found) {
s |= m_antecedents.find(it->var());
} }
else { else {
all_found = false; all_found = false;

View file

@ -266,8 +266,10 @@ public:
m_params.append(p); m_params.append(p);
sat_params p1(p); sat_params p1(p);
m_params.set_bool("elim_vars", false); m_params.set_bool("elim_vars", false);
m_params.set_bool("keep_cardinality_constraints", p1.pb_solver() || p1.cardinality_solver()); m_params.set_bool("keep_cardinality_constraints", p1.cardinality_solver());
m_params.set_bool("keep_pb_constraints", p1.pb_solver()); m_params.set_bool("keep_pb_constraints", m_solver.get_config().m_pb_solver == sat::PB_SOLVER);
m_params.set_bool("pb_num_system", m_solver.get_config().m_pb_solver == sat::PB_SORTING);
m_params.set_bool("pb_totalizer", m_solver.get_config().m_pb_solver == sat::PB_TOTALIZER);
m_params.set_bool("xor_solver", p1.xor_solver()); m_params.set_bool("xor_solver", p1.xor_solver());
m_solver.updt_params(m_params); m_solver.updt_params(m_params);
m_optimize_model = m_params.get_bool("optimize_model", false); m_optimize_model = m_params.get_bool("optimize_model", false);

View file

@ -425,6 +425,8 @@ public:
return r; return r;
} }
// unfortunately, params_ref is not thread safe
// so better create a local copy of the parameters.
params_ref get_module(symbol const & module_name) { params_ref get_module(symbol const & module_name) {
params_ref result; params_ref result;
params_ref * ps = 0; params_ref * ps = 0;

View file

@ -333,8 +333,21 @@ public:
reset(); reset();
} }
void inc_ref() { m_ref_count++; } void inc_ref() {
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); } #pragma omp critical (params)
{
m_ref_count++;
}
}
void dec_ref() {
bool is_last;
SASSERT(m_ref_count > 0);
#pragma omp critical (params)
{
is_last = 0 == --m_ref_count;
}
if (is_last) dealloc(this);
}
bool empty() const { return m_entries.empty(); } bool empty() const { return m_entries.empty(); }
bool contains(symbol const & k) const; bool contains(symbol const & k) const;
@ -344,7 +357,6 @@ public:
void reset(symbol const & k); void reset(symbol const & k);
void reset(char const * k); void reset(char const * k);
void validate(param_descrs const & p) { void validate(param_descrs const & p) {
svector<params::entry>::iterator it = m_entries.begin(); svector<params::entry>::iterator it = m_entries.begin();
svector<params::entry>::iterator end = m_entries.end(); svector<params::entry>::iterator end = m_entries.end();