3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-07-27 17:02:27 -07:00
commit b482dbd589
379 changed files with 7440 additions and 3352 deletions

33
src/sat/CMakeLists.txt Normal file
View file

@ -0,0 +1,33 @@
z3_add_component(sat
SOURCES
ba_solver.cpp
dimacs.cpp
sat_asymm_branch.cpp
sat_ccc.cpp
sat_clause.cpp
sat_clause_set.cpp
sat_clause_use_list.cpp
sat_cleaner.cpp
sat_config.cpp
sat_drat.cpp
sat_elim_eqs.cpp
sat_iff3_finder.cpp
sat_integrity_checker.cpp
sat_local_search.cpp
sat_lookahead.cpp
sat_model_converter.cpp
sat_mus.cpp
sat_parallel.cpp
sat_probing.cpp
sat_scc.cpp
sat_simplifier.cpp
sat_solver.cpp
sat_watched.cpp
COMPONENT_DEPENDENCIES
util
PYG_FILES
sat_asymm_branch_params.pyg
sat_params.pyg
sat_scc_params.pyg
sat_simplifier_params.pyg
)

View file

@ -2204,14 +2204,14 @@ namespace sat {
// ----------------------------------
// lp based relaxation
void ba_solver::lp_add_var(int coeff, lean::var_index v, lhs_t& lhs, rational& rhs) {
void ba_solver::lp_add_var(int coeff, lp::var_index v, lhs_t& lhs, rational& rhs) {
if (coeff < 0) {
rhs += rational(coeff);
}
lhs.push_back(std::make_pair(rational(coeff), v));
}
void ba_solver::lp_add_clause(lean::lar_solver& s, svector<lean::var_index> const& vars, clause const& c) {
void ba_solver::lp_add_clause(lp::lar_solver& s, svector<lp::var_index> const& vars, clause const& c) {
lhs_t lhs;
rational rhs;
if (c.frozen()) return;
@ -2219,26 +2219,26 @@ namespace sat {
for (literal l : c) {
lp_add_var(l.sign() ? -1 : 1, vars[l.var()], lhs, rhs);
}
s.add_constraint(lhs, lean::GE, rhs);
s.add_constraint(lhs, lp::GE, rhs);
}
void ba_solver::lp_lookahead_reduction() {
lean::lar_solver solver;
lp::lar_solver solver;
solver.settings().set_message_ostream(&std::cout);
solver.settings().set_debug_ostream(&std::cout);
solver.settings().print_statistics = true;
solver.settings().report_frequency = 1000;
// solver.settings().simplex_strategy() = lean::simplex_strategy_enum::lu; - runs out of memory
// solver.settings().simplex_strategy() = lp::simplex_strategy_enum::lu; - runs out of memory
// TBD: set rlimit on the solver
svector<lean::var_index> vars;
svector<lp::var_index> vars;
for (unsigned i = 0; i < s().num_vars(); ++i) {
lean::var_index v = solver.add_var(i, false);
lp::var_index v = solver.add_var(i, false);
vars.push_back(v);
solver.add_var_bound(v, lean::GE, rational::zero());
solver.add_var_bound(v, lean::LE, rational::one());
solver.add_var_bound(v, lp::GE, rational::zero());
solver.add_var_bound(v, lp::LE, rational::one());
switch (value(v)) {
case l_true: solver.add_var_bound(v, lean::GE, rational::one()); break;
case l_false: solver.add_var_bound(v, lean::LE, rational::zero()); break;
case l_true: solver.add_var_bound(v, lp::GE, rational::one()); break;
case l_false: solver.add_var_bound(v, lp::LE, rational::zero()); break;
default: break;
}
}
@ -2263,7 +2263,7 @@ namespace sat {
int co = p.get_coeff(i);
lp_add_var(l.sign() ? -co : co, vars[l.var()], lhs, rhs);
}
solver.add_constraint(lhs, lean::GE, rhs);
solver.add_constraint(lhs, lp::GE, rhs);
break;
}
default:
@ -2274,8 +2274,8 @@ namespace sat {
std::cout << "lp solve\n";
std::cout.flush();
lean::lp_status st = solver.solve();
if (st == lean::INFEASIBLE) {
lp::lp_status st = solver.solve();
if (st == lp::lp_status::INFEASIBLE) {
std::cout << "infeasible\n";
s().set_conflict(justification());
return;
@ -2283,30 +2283,30 @@ namespace sat {
std::cout << "feasible\n";
std::cout.flush();
for (unsigned i = 0; i < s().num_vars(); ++i) {
lean::var_index v = vars[i];
lp::var_index v = vars[i];
if (value(v) != l_undef) continue;
// TBD: take initial model into account to limit queries.
std::cout << "solve v" << v << "\n";
std::cout.flush();
solver.push();
solver.add_var_bound(v, lean::GE, rational::one());
solver.add_var_bound(v, lp::GE, rational::one());
st = solver.solve();
solver.pop(1);
if (st == lean::INFEASIBLE) {
if (st == lp::lp_status::INFEASIBLE) {
std::cout << "found unit: " << literal(v, true) << "\n";
s().assign(literal(v, true), justification());
solver.add_var_bound(v, lean::LE, rational::zero());
solver.add_var_bound(v, lp::LE, rational::zero());
continue;
}
solver.push();
solver.add_var_bound(v, lean::LE, rational::zero());
solver.add_var_bound(v, lp::LE, rational::zero());
st = solver.solve();
solver.pop(1);
if (st == lean::INFEASIBLE) {
if (st == lp::lp_status::INFEASIBLE) {
std::cout << "found unit: " << literal(v, false) << "\n";
s().assign(literal(v, false), justification());
solver.add_var_bound(v, lean::GE, rational::zero());
solver.add_var_bound(v, lp::GE, rational::zero());
continue;
}
}

View file

@ -267,10 +267,10 @@ namespace sat {
void gc_half(char const* _method);
void mutex_reduction();
typedef vector<std::pair<rational, lean::var_index>> lhs_t;
typedef vector<std::pair<rational, lp::var_index>> lhs_t;
void lp_lookahead_reduction();
void lp_add_var(int coeff, lean::var_index v, lhs_t& lhs, rational& rhs);
void lp_add_clause(lean::lar_solver& s, svector<lean::var_index> const& vars, clause const& c);
void lp_add_var(int coeff, lp::var_index v, lhs_t& lhs, rational& rhs);
void lp_add_clause(lp::lar_solver& s, svector<lp::var_index> const& vars, clause const& c);
unsigned use_count(literal lit) const { return m_cnstr_use_list[lit.index()].size() + m_clause_use_list.get(lit).size(); }

View file

@ -59,6 +59,7 @@ namespace sat {
sat = false;
continue;
}
if (sat)
continue;
bool sign = l.sign();
@ -126,7 +127,7 @@ namespace sat {
}
return ok;
}
model_converter::entry & model_converter::mk(kind k, bool_var v) {
m_entries.push_back(entry(k, v));
entry & e = m_entries.back();
@ -210,7 +211,7 @@ namespace sat {
out << l;
}
out << ")";
}
}
out << ")\n";
}
@ -223,4 +224,22 @@ namespace sat {
for (entry const & e : m_entries) s.insert(e.m_var);
}
unsigned model_converter::max_var(unsigned min) const {
unsigned result = min;
vector<entry>::const_iterator it = m_entries.begin();
vector<entry>::const_iterator end = m_entries.end();
for (; it != end; ++it) {
literal_vector::const_iterator lvit = it->m_clauses.begin();
literal_vector::const_iterator lvend = it->m_clauses.end();
for (; lvit != lvend; ++lvit) {
literal l = *lvit;
if (l != null_literal) {
if (l.var() > result)
result = l.var();
}
}
}
return result;
}
};

View file

@ -26,7 +26,7 @@ namespace sat {
\brief Stores eliminated variables and Blocked clauses.
It uses these clauses to extend/patch the model produced for the
simplified CNF formula.
This information may also be used to support incremental solving.
If new clauses are asserted into the SAT engine, then we can
restore the state by re-asserting all clauses in the model
@ -50,7 +50,7 @@ namespace sat {
m_kind(src.m_kind),
m_clauses(src.m_clauses) {
}
bool_var var() const { return m_var; }
bool_var var() const { return m_var; }
kind get_kind() const { return static_cast<kind>(m_kind); }
};
private:
@ -75,8 +75,9 @@ namespace sat {
void copy(model_converter const & src);
void collect_vars(bool_var_set & s) const;
unsigned max_var(unsigned min) const;
};
};
#endif

View file

@ -2884,7 +2884,7 @@ namespace sat {
unsigned j = 0;
for (unsigned i = 0; i < clauses.size(); ++i) {
clause & c = *(clauses[i]);
if (c.contains(lit)) {
if (c.contains(lit) || c.contains(~lit)) {
detach_clause(c);
del_clause(c);
}
@ -2940,6 +2940,7 @@ namespace sat {
w = max_var(m_clauses, w);
w = max_var(true, w);
w = max_var(false, w);
v = m_mc.max_var(w);
for (unsigned i = 0; i < m_trail.size(); ++i) {
if (m_trail[i].var() > w) w = m_trail[i].var();
}
@ -3430,9 +3431,9 @@ namespace sat {
}
}
}
// Algorithm 7: Corebased Algorithm with Chunking
static void back_remove(sat::literal_vector& lits, sat::literal l) {
for (unsigned i = lits.size(); i > 0; ) {
--i;
@ -3456,7 +3457,7 @@ namespace sat {
}
}
}
static lbool core_chunking(sat::solver& s, model const& m, sat::bool_var_vector const& vars, sat::literal_vector const& asms, vector<sat::literal_vector>& conseq, unsigned K) {
sat::literal_vector lambda;
for (unsigned i = 0; i < vars.size(); i++) {
@ -3656,7 +3657,7 @@ namespace sat {
SASSERT(search_lvl() == 1);
unsigned num_iterations = 0;
extract_fixed_consequences(unfixed_lits, assumptions, unfixed_vars, conseq);
extract_fixed_consequences(unfixed_lits, assumptions, unfixed_vars, conseq);
update_unfixed_literals(unfixed_lits, unfixed_vars);
while (!unfixed_lits.empty()) {
if (scope_lvl() > search_lvl()) {
@ -3671,7 +3672,7 @@ namespace sat {
unsigned num_assigned = 0;
lbool is_sat = l_true;
for (; it != end; ++it) {
literal lit = *it;
literal lit = *it;
if (value(lit) != l_undef) {
++num_fixed;
if (lvl(lit) <= 1 && value(lit) == l_true) {
@ -3726,8 +3727,8 @@ namespace sat {
<< " iterations: " << num_iterations
<< " variables: " << unfixed_lits.size()
<< " fixed: " << conseq.size()
<< " status: " << is_sat
<< " pre-assigned: " << num_fixed
<< " status: " << is_sat
<< " pre-assigned: " << num_fixed
<< " unfixed: " << lits.size() - conseq.size() - unfixed_lits.size()
<< ")\n";);

View file

@ -0,0 +1,11 @@
z3_add_component(sat_solver
SOURCES
inc_sat_solver.cpp
COMPONENT_DEPENDENCIES
aig_tactic
arith_tactics
bv_tactics
core_tactics
sat_tactic
solver
)

View file

@ -155,7 +155,7 @@ public:
}
bool is_literal(expr* e) const {
return
return
is_uninterp_const(e) ||
(m.is_not(e, e) && is_uninterp_const(e));
}
@ -179,7 +179,7 @@ public:
asm2fml.insert(assumptions[i], assumptions[i]);
}
}
TRACE("sat", tout << _assumptions << "\n";);
dep2asm_t dep2asm;
m_model = 0;
@ -192,7 +192,7 @@ public:
init_reason_unknown();
r = m_solver.check(m_asms.size(), m_asms.c_ptr());
switch (r) {
case l_true:
if (sz > 0) {
@ -385,14 +385,14 @@ public:
return r;
}
// build map from bound variables to
// build map from bound variables to
// the consequences that cover them.
u_map<unsigned> bool_var2conseq;
for (unsigned i = 0; i < lconseq.size(); ++i) {
TRACE("sat", tout << lconseq[i] << "\n";);
bool_var2conseq.insert(lconseq[i][0].var(), i);
}
// extract original fixed variables
u_map<expr*> asm2dep;
extract_asm2dep(dep2asm, asm2dep);
@ -583,7 +583,7 @@ private:
lbool internalize_vars(expr_ref_vector const& vars, sat::bool_var_vector& bvars) {
for (unsigned i = 0; i < vars.size(); ++i) {
internalize_var(vars[i], bvars);
internalize_var(vars[i], bvars);
}
return l_true;
}
@ -595,7 +595,7 @@ private:
bool internalized = false;
if (is_uninterp_const(v) && m.is_bool(v)) {
sat::bool_var b = m_map.to_bool_var(v);
if (b != sat::null_bool_var) {
bvars.push_back(b);
internalized = true;
@ -621,7 +621,7 @@ private:
else if (is_uninterp_const(v) && bvutil.is_bv(v)) {
// variable does not occur in assertions, so is unconstrained.
}
CTRACE("sat", !internalized, tout << "unhandled variable " << mk_pp(v, m) << "\n";);
CTRACE("sat", !internalized, tout << "unhandled variable " << mk_pp(v, m) << "\n";);
return internalized;
}
@ -648,7 +648,7 @@ private:
}
expr_ref val(m);
expr_ref_vector conj(m);
internalize_value(value, v, val);
internalize_value(value, v, val);
while (!premises.empty()) {
expr* e = 0;
VERIFY(asm2dep.find(premises.pop().index(), e));
@ -739,16 +739,14 @@ private:
extract_asm2dep(dep2asm, asm2dep);
sat::literal_vector const& core = m_solver.get_core();
TRACE("sat",
dep2asm_t::iterator it2 = dep2asm.begin();
dep2asm_t::iterator end2 = dep2asm.end();
for (; it2 != end2; ++it2) {
tout << mk_pp(it2->m_key, m) << " |-> " << sat::literal(it2->m_value) << "\n";
for (auto kv : dep2asm) {
tout << mk_pp(kv.m_key, m) << " |-> " << sat::literal(kv.m_value) << "\n";
}
tout << "core: ";
for (unsigned i = 0; i < core.size(); ++i) {
tout << core[i] << " ";
tout << "asm2fml: ";
for (auto kv : asm2fml) {
tout << mk_pp(kv.m_key, m) << " |-> " << mk_pp(kv.m_value, m) << "\n";
}
tout << "\n";
tout << "core: "; for (auto c : core) tout << c << " "; tout << "\n";
);
m_core.reset();

View file

@ -0,0 +1,11 @@
z3_add_component(sat_tactic
SOURCES
atom2bool_var.cpp
goal2sat.cpp
sat_tactic.cpp
COMPONENT_DEPENDENCIES
sat
tactic
TACTIC_HEADERS
sat_tactic.h
)