3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-19 10:52:02 +00:00

add xor parity solver feature

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-02-20 16:55:00 -08:00
parent cb050998e5
commit 98c5a779b4
6 changed files with 665 additions and 108 deletions

View file

@ -32,9 +32,7 @@ namespace sat {
void reset() { memset(this, 0, sizeof(*this)); }
};
// class card_allocator;
class card {
//friend class card_allocator;
unsigned m_index;
literal m_lit;
unsigned m_k;
@ -53,6 +51,22 @@ namespace sat {
void negate();
};
class xor {
unsigned m_index;
literal m_lit;
unsigned m_size;
literal m_lits[0];
public:
static size_t get_obj_size(unsigned num_lits) { return sizeof(xor) + num_lits * sizeof(literal); }
xor(unsigned index, literal lit, literal_vector const& lits);
unsigned index() const { return m_index; }
literal lit() const { return m_lit; }
literal operator[](unsigned i) const { return m_lits[i]; }
unsigned size() const { return m_size; }
void swap(unsigned i, unsigned j) { std::swap(m_lits[i], m_lits[j]); }
void negate() { m_lits[0].neg(); }
};
struct ineq {
literal_vector m_lits;
unsigned_vector m_coeffs;
@ -61,29 +75,48 @@ namespace sat {
void push(literal l, unsigned c) { m_lits.push_back(l); m_coeffs.push_back(c); }
};
typedef ptr_vector<card> watch;
typedef ptr_vector<card> card_watch;
typedef ptr_vector<xor> xor_watch;
struct var_info {
watch* m_lit_watch[2];
card* m_card;
var_info(): m_card(0) {
m_lit_watch[0] = 0;
m_lit_watch[1] = 0;
card_watch* m_card_watch[2];
xor_watch* m_xor_watch;
card* m_card;
xor* m_xor;
var_info(): m_xor_watch(0), m_card(0), m_xor(0) {
m_card_watch[0] = 0;
m_card_watch[1] = 0;
}
void reset() {
dealloc(m_card);
dealloc(card_extension::set_tag_non_empty(m_lit_watch[0]));
dealloc(card_extension::set_tag_non_empty(m_lit_watch[1]));
dealloc(m_xor);
dealloc(card_extension::set_tag_non_empty(m_card_watch[0]));
dealloc(card_extension::set_tag_non_empty(m_card_watch[1]));
dealloc(card_extension::set_tag_non_empty(m_xor_watch));
}
};
template<typename T>
static ptr_vector<T>* set_tag_empty(ptr_vector<T>* c) {
return TAG(ptr_vector<T>*, c, 1);
}
template<typename T>
static bool is_tag_empty(ptr_vector<T> const* c) {
return !c || GET_TAG(c) == 1;
}
template<typename T>
static ptr_vector<T>* set_tag_non_empty(ptr_vector<T>* c) {
return UNTAG(ptr_vector<T>*, c);
}
static ptr_vector<card>* set_tag_empty(ptr_vector<card>* c);
static bool is_tag_empty(ptr_vector<card> const* c);
static ptr_vector<card>* set_tag_non_empty(ptr_vector<card>* c);
solver* m_solver;
stats m_stats;
ptr_vector<card> m_constraints;
ptr_vector<card> m_cards;
ptr_vector<xor> m_xors;
// watch literals
svector<var_info> m_var_infos;
@ -98,8 +131,14 @@ namespace sat {
int m_bound;
tracked_uint_set m_active_var_set;
literal_vector m_lemma;
// literal_vector m_literals;
unsigned m_num_propagations_since_pop;
bool m_has_xor;
unsigned_vector m_parity_marks;
literal_vector m_parity_trail;
void ensure_parity_size(bool_var v);
unsigned get_parity(bool_var v);
void inc_parity(bool_var v);
void reset_parity(bool_var v);
solver& s() const { return *m_solver; }
void init_watch(card& c, bool is_true);
@ -111,13 +150,44 @@ namespace sat {
void clear_watch(card& c);
void reset_coeffs();
void reset_marked_literals();
void unwatch_literal(literal w, card* c);
// xor specific functionality
void clear_watch(xor& x);
void watch_literal(xor& x, literal lit);
void unwatch_literal(literal w, xor* x);
void init_watch(xor& x, bool is_true);
void assign(xor& x, literal lit);
void set_conflict(xor& x, literal lit);
bool parity(xor const& x, unsigned offset) const;
lbool add_assign(xor& x, literal alit);
void asserted_xor(literal l, ptr_vector<xor>* xors, xor* x);
bool is_card_index(unsigned idx) const { return 0 == (idx & 0x1); }
card& index2card(unsigned idx) const { SASSERT(is_card_index(idx)); return *m_cards[idx >> 1]; }
xor& index2xor(unsigned idx) const { SASSERT(!is_card_index(idx)); return *m_xors[idx >> 1]; }
void get_xor_antecedents(unsigned index, literal_vector& r);
template<typename T>
bool remove(ptr_vector<T>& ts, T* t) {
unsigned sz = ts.size();
for (unsigned j = 0; j < sz; ++j) {
if (ts[j] == t) {
std::swap(ts[j], ts[sz-1]);
ts.pop_back();
return sz == 1;
}
}
return false;
}
inline lbool value(literal lit) const { return m_solver->value(lit); }
inline unsigned lvl(literal lit) const { return m_solver->lvl(lit); }
inline unsigned lvl(bool_var v) const { return m_solver->lvl(v); }
void unwatch_literal(literal w, card* c);
bool remove(ptr_vector<card>& cards, card* c);
void normalize_active_coeffs();
void inc_coeff(literal l, int offset);
@ -131,6 +201,7 @@ namespace sat {
// validation utilities
bool validate_conflict(card& c);
bool validate_conflict(xor& x);
bool validate_assign(literal_vector const& lits, literal lit);
bool validate_lemma();
bool validate_unit_propagation(card const& c);
@ -143,12 +214,16 @@ namespace sat {
void display(std::ostream& out, ineq& p) const;
void display(std::ostream& out, card& c, bool values) const;
void display(std::ostream& out, xor& c, bool values) const;
void display_watch(std::ostream& out, bool_var v) const;
void display_watch(std::ostream& out, bool_var v, bool sign) const;
public:
card_extension();
virtual ~card_extension();
virtual void set_solver(solver* s) { m_solver = s; }
void add_at_least(bool_var v, literal_vector const& lits, unsigned k);
void add_xor(bool_var v, literal_vector const& lits);
virtual void propagate(literal l, ext_constraint_idx idx, bool & keep);
virtual bool resolve_conflict();
virtual void get_antecedents(literal l, ext_justification_idx idx, literal_vector & r);