mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
merge
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
b482dbd589
379 changed files with 7440 additions and 3352 deletions
33
src/sat/CMakeLists.txt
Normal file
33
src/sat/CMakeLists.txt
Normal 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
|
||||
)
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";);
|
||||
|
||||
|
|
11
src/sat/sat_solver/CMakeLists.txt
Normal file
11
src/sat/sat_solver/CMakeLists.txt
Normal 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
|
||||
)
|
|
@ -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();
|
||||
|
|
11
src/sat/tactic/CMakeLists.txt
Normal file
11
src/sat/tactic/CMakeLists.txt
Normal 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
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue