3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

integrate polysat into bv solver

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2022-01-26 20:20:45 +01:00
parent 3f5df04dc4
commit ff93c03972
14 changed files with 459 additions and 74 deletions

View file

@ -78,13 +78,13 @@ namespace polysat {
SASSERT(is_propagation(lit));
}
void bool_var_manager::asserted(sat::literal lit, unsigned lvl, unsigned dep) {
void bool_var_manager::asserted(sat::literal lit, unsigned lvl, dep_t dep) {
LOG("Asserted " << lit << " @ " << lvl);
assign(kind_t::decision, lit, lvl, nullptr, dep);
SASSERT(is_decision(lit));
}
void bool_var_manager::assign(kind_t k, sat::literal lit, unsigned lvl, clause* reason, unsigned dep) {
void bool_var_manager::assign(kind_t k, sat::literal lit, unsigned lvl, clause* reason, dep_t dep) {
SASSERT(!is_assigned(lit));
SASSERT(k != kind_t::unassigned);
m_value[lit.index()] = l_true;

View file

@ -29,7 +29,7 @@ namespace polysat {
svector<sat::bool_var> m_unused; // previously deleted variables that can be reused by new_var();
svector<lbool> m_value; // current value (indexed by literal)
unsigned_vector m_level; // level of assignment (indexed by variable)
unsigned_vector m_deps; // dependencies of external asserts
svector<dep_t> m_deps; // dependencies of external asserts
unsigned_vector m_activity; //
svector<kind_t> m_kind; // decision or propagation?
// Clause associated with the assignment (indexed by variable):
@ -40,7 +40,7 @@ namespace polysat {
var_queue m_free_vars; // free Boolean variables
vector<ptr_vector<clause>> m_watch; // watch list for literals into clauses
void assign(kind_t k, sat::literal lit, unsigned lvl, clause* reason, unsigned dep = null_dependency);
void assign(kind_t k, sat::literal lit, unsigned lvl, clause* reason, dep_t dep = null_dependency);
public:
@ -66,7 +66,7 @@ namespace polysat {
unsigned level(sat::literal lit) const { return level(lit.var()); }
clause* reason(sat::bool_var var) const { SASSERT(is_assigned(var)); return is_propagation(var) ? m_clause[var] : nullptr; }
clause* reason(sat::literal lit) const { return reason(lit.var()); }
unsigned dep(sat::literal lit) const { return lit == sat::null_literal ? null_dependency : m_deps[lit.var()]; }
dep_t dep(sat::literal lit) const { return lit == sat::null_literal ? null_dependency : m_deps[lit.var()]; }
clause* lemma(sat::bool_var var) const { SASSERT(is_decision(var)); return m_clause[var]; }
@ -83,7 +83,7 @@ namespace polysat {
void propagate(sat::literal lit, unsigned lvl, clause& reason);
void decide(sat::literal lit, unsigned lvl, clause& lemma);
void eval(sat::literal lit, unsigned lvl);
void asserted(sat::literal lit, unsigned lvl, unsigned dep);
void asserted(sat::literal lit, unsigned lvl, dep_t dep);
void unassign(sat::literal lit);
std::ostream& display(std::ostream& out) const;

View file

@ -83,6 +83,12 @@ namespace polysat {
return l_undef;
}
lbool solver::unit_propagate() {
flet<uint64_t> _max_d(m_max_decisions, m_stats.m_num_decisions + 1);
return check_sat();
}
dd::pdd_manager& solver::sz2pdd(unsigned sz) const {
m_pdd.reserve(sz + 1);
if (!m_pdd[sz])
@ -164,7 +170,7 @@ namespace polysat {
}
void solver::assign_eh(signed_constraint c, unsigned dep) {
void solver::assign_eh(signed_constraint c, dep_t dep) {
SASSERT(at_base_level());
SASSERT(c);
if (is_conflict())
@ -195,6 +201,7 @@ namespace polysat {
m_linear_solver.new_constraint(*c.get());
#endif
}
bool solver::can_propagate() {
return m_qhead < m_search.size() && !is_conflict();
@ -592,7 +599,7 @@ namespace polysat {
SASSERT(!m_conflict.empty());
}
void solver::unsat_core(unsigned_vector& deps) {
void solver::unsat_core(svector<dep_t>& deps) {
deps.reset();
for (auto c : m_conflict) {
auto d = m_bvars.dep(c.blit());

View file

@ -192,8 +192,6 @@ namespace polysat {
void narrow(pvar v);
void linear_propagate();
/// Evaluate term under the current assignment.
bool try_eval(pdd const& p, rational& out_value) const;
bool is_conflict() const { return !m_conflict.empty(); }
bool at_base_level() const;
@ -231,6 +229,9 @@ namespace polysat {
bool wlist_invariant();
bool assignment_invariant();
bool verify_sat();
bool can_propagate();
void propagate();
public:
@ -255,7 +256,7 @@ namespace polysat {
/**
* retrieve unsat core dependencies
*/
void unsat_core(unsigned_vector& deps);
void unsat_core(svector<dep_t>& deps);
/**
* Add variable with bit-size.
@ -302,6 +303,11 @@ namespace polysat {
unsigned get_level(pvar v) const { SASSERT(is_assigned(v)); return m_justification[v].level(); }
/**
* Evaluate term under the current assignment.
*/
bool try_eval(pdd const& p, rational& out_value) const;
/** Create constraints */
signed_constraint eq(pdd const& p) { return m_constraints.eq(p); }
signed_constraint diseq(pdd const& p) { return ~m_constraints.eq(p); }
@ -325,39 +331,38 @@ namespace polysat {
signed_constraint bit(pdd const& p, unsigned i) { return m_constraints.bit(p, i); }
/** Create and activate polynomial constraints. */
void add_eq(pdd const& p, unsigned dep = null_dependency) { assign_eh(eq(p), dep); }
void add_diseq(pdd const& p, unsigned dep = null_dependency) { assign_eh(diseq(p), dep); }
void add_ule(pdd const& p, pdd const& q, unsigned dep = null_dependency) { assign_eh(ule(p, q), dep); }
void add_ult(pdd const& p, pdd const& q, unsigned dep = null_dependency) { assign_eh(ult(p, q), dep); }
void add_sle(pdd const& p, pdd const& q, unsigned dep = null_dependency) { assign_eh(sle(p, q), dep); }
void add_slt(pdd const& p, pdd const& q, unsigned dep = null_dependency) { assign_eh(slt(p, q), dep); }
void add_noovfl(pdd const& p, pdd const& q, unsigned dep = null_dependency) { assign_eh(~mul_ovfl(p, q), dep); }
void add_ovfl(pdd const& p, pdd const& q, unsigned dep = null_dependency) { assign_eh(mul_ovfl(p, q), dep); }
void add_eq(pdd const& p, dep_t dep = null_dependency) { assign_eh(eq(p), dep); }
void add_diseq(pdd const& p, dep_t dep = null_dependency) { assign_eh(diseq(p), dep); }
void add_ule(pdd const& p, pdd const& q, dep_t dep = null_dependency) { assign_eh(ule(p, q), dep); }
void add_ult(pdd const& p, pdd const& q, dep_t dep = null_dependency) { assign_eh(ult(p, q), dep); }
void add_sle(pdd const& p, pdd const& q, dep_t dep = null_dependency) { assign_eh(sle(p, q), dep); }
void add_slt(pdd const& p, pdd const& q, dep_t dep = null_dependency) { assign_eh(slt(p, q), dep); }
void add_noovfl(pdd const& p, pdd const& q, dep_t dep = null_dependency) { assign_eh(~mul_ovfl(p, q), dep); }
void add_ovfl(pdd const& p, pdd const& q, dep_t dep = null_dependency) { assign_eh(mul_ovfl(p, q), dep); }
void add_ule(pdd const& p, rational const& q, unsigned dep = null_dependency) { add_ule(p, p.manager().mk_val(q), dep); }
void add_ule(rational const& p, pdd const& q, unsigned dep = null_dependency) { add_ule(q.manager().mk_val(p), q, dep); }
void add_ule(pdd const& p, unsigned q, unsigned dep = null_dependency) { add_ule(p, rational(q), dep); }
void add_ule(unsigned p, pdd const& q, unsigned dep = null_dependency) { add_ule(rational(p), q, dep); }
void add_ult(pdd const& p, rational const& q, unsigned dep = null_dependency) { add_ult(p, p.manager().mk_val(q), dep); }
void add_ult(rational const& p, pdd const& q, unsigned dep = null_dependency) { add_ult(q.manager().mk_val(p), q, dep); }
void add_ult(pdd const& p, unsigned q, unsigned dep = null_dependency) { add_ult(p, rational(q), dep); }
void add_ult(unsigned p, pdd const& q, unsigned dep = null_dependency) { add_ult(rational(p), q, dep); }
void add_noovfl(pdd const& p, rational const& q, unsigned dep = null_dependency) { add_noovfl(p, p.manager().mk_val(q), dep); }
void add_noovfl(rational const& p, pdd const& q, unsigned dep = null_dependency) { add_noovfl(q, p, dep); }
void add_noovfl(pdd const& p, unsigned q, unsigned dep = null_dependency) { add_noovfl(p, rational(q), dep); }
void add_noovfl(unsigned p, pdd const& q, unsigned dep = null_dependency) { add_noovfl(q, p, dep); }
void add_ule(pdd const& p, rational const& q, dep_t dep = null_dependency) { add_ule(p, p.manager().mk_val(q), dep); }
void add_ule(rational const& p, pdd const& q, dep_t dep = null_dependency) { add_ule(q.manager().mk_val(p), q, dep); }
void add_ule(pdd const& p, unsigned q, dep_t dep = null_dependency) { add_ule(p, rational(q), dep); }
void add_ule(unsigned p, pdd const& q, dep_t dep = null_dependency) { add_ule(rational(p), q, dep); }
void add_ult(pdd const& p, rational const& q, dep_t dep = null_dependency) { add_ult(p, p.manager().mk_val(q), dep); }
void add_ult(rational const& p, pdd const& q, dep_t dep = null_dependency) { add_ult(q.manager().mk_val(p), q, dep); }
void add_ult(pdd const& p, unsigned q, dep_t dep = null_dependency) { add_ult(p, rational(q), dep); }
void add_ult(unsigned p, pdd const& q, dep_t dep = null_dependency) { add_ult(rational(p), q, dep); }
void add_noovfl(pdd const& p, rational const& q, dep_t dep = null_dependency) { add_noovfl(p, p.manager().mk_val(q), dep); }
void add_noovfl(rational const& p, pdd const& q, dep_t dep = null_dependency) { add_noovfl(q, p, dep); }
void add_noovfl(pdd const& p, unsigned q, dep_t dep = null_dependency) { add_noovfl(p, rational(q), dep); }
void add_noovfl(unsigned p, pdd const& q, dep_t dep = null_dependency) { add_noovfl(q, p, dep); }
/**
* Activate the constraint corresponding to the given boolean variable.
* Note: to deactivate, use push/pop.
*/
void assign_eh(signed_constraint c, unsigned dep);
void assign_eh(signed_constraint c, dep_t dep);
/**
* main state transitions.
* Unit propagation accessible over API.
*/
bool can_propagate();
void propagate();
lbool unit_propagate();
/**
* External context managment.

View file

@ -29,8 +29,8 @@ namespace polysat {
typedef dd::bdd bdd;
typedef dd::bddv bddv;
typedef unsigned pvar;
const unsigned null_dependency = UINT_MAX;
typedef unsigned dep_t;
const dep_t null_dependency = std::numeric_limits<unsigned>::max();;
const pvar null_var = UINT_MAX;
}