3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-16 13:58:45 +00:00

Justifications

This commit is contained in:
CEisenhofer 2022-12-07 15:53:17 +01:00
parent 7d58a29bd5
commit b5647f4d35
3 changed files with 90 additions and 48 deletions

View file

@ -53,12 +53,9 @@ unsigned PackedRow::population_cnt(
return popcnt;
}
void PackedRow::get_reason(
sat::literal_vector& tmp_clause,
const unsigned_vector& col_to_var,
PackedRow& cols_vals,
PackedRow& tmp_col2,
literal prop) {
// Gets the reason why the literal "prop" was propagated
void PackedRow::get_reason(literal_vector& tmp_clause, const unsigned_vector& column_to_var, PackedRow& cols_vals, PackedRow& tmp_col2, literal prop) {
tmp_col2.set_and(*this, cols_vals);
for (int i = 0; i < size; i++) {
if (!mp[i])
@ -70,15 +67,13 @@ void PackedRow::get_reason(
while (at != 0) {
unsigned col = extra + (at - 1) + i * 64;
SASSERT((*this)[col] == 1);
unsigned var = col_to_var[col];
unsigned var = column_to_var[col];
if (var == prop.var()) {
tmp_clause.push_back(prop);
tmp_clause.push_back(~prop); // TODO: Why not negated?
std::swap(tmp_clause[0], tmp_clause.back());
}
else {
bool val_bool = tmp_col2[col]; // NSB: double check if z3 use of sign is compatible
tmp_clause.push_back(sat::literal(var, val_bool));
}
else
tmp_clause.push_back(literal(var, tmp_col2[col])); // NSB: double check if z3 use of sign is compatible
extra += at;
if (extra == 64)
@ -408,9 +403,8 @@ void EGaussian::eliminate() {
// Since we XOR into *all*, this is Gauss-Jordan (and not just Gauss)
for (unsigned k_row = 0; k_row < end_row; k_row++) {
// xor rows K and I
if (k_row != row_i && m_mat[k_row][col]) {
if (k_row != row_i && m_mat[k_row][col])
m_mat[k_row].xor_in(m_mat[row_i]);
}
}
row_i++;
}
@ -586,7 +580,7 @@ bool EGaussian::find_truths(
svector<gauss_watched>& ws,
unsigned& i,
unsigned& j,
unsigned var,
bool_var var,
unsigned row_n,
gauss_data& gqd) {
@ -683,8 +677,6 @@ bool EGaussian::find_truths(
TRACE("xor", tout << "--> found new watch: " << new_resp_var+1;);
find_truth_ret_fnewwatch++;
// printf("%d:This row is find new watch:%d => orig %d p:%d n",row_n ,
// new_resp_var,orig_basic , p);
if (was_resp_var) {
/// clear watchlist, because only one responsible value in watchlist
@ -785,6 +777,17 @@ void EGaussian::update_cols_vals_set(bool force) {
}
}
last_val_update = m_solver.s().trail_size();
std::cout << "Col-Unassigned: ";
for (int i = 0; i < 64 * cols_unset->size; ++i) {
std::cout << (*cols_unset)[i];
}
std::cout << "\n";
std::cout << "Col-Values: ";
for (int i = 0; i < 64 * cols_vals->size; ++i) {
std::cout << (*cols_vals)[i];
}
std::cout << std::endl;
}
void EGaussian::prop_lit(const gauss_data& gqd, unsigned row_i, literal ret_lit_prop) {

View file

@ -46,19 +46,19 @@ namespace xr {
friend class solver;
unsigned matrix_num;
unsigned row_num;
unsigned m_matrix_idx;
unsigned m_row_idx;
//XOR
justification(const unsigned matrix_num, const unsigned row_num):
matrix_num(matrix_num),
row_num(row_num) {
SASSERT(matrix_num != -1);
SASSERT(row_num != -1);
justification(unsigned matrix_idx, unsigned row_idx):
m_matrix_idx(matrix_idx),
m_row_idx(row_idx) {
SASSERT(matrix_idx != -1);
SASSERT(row_idx != -1);
}
public:
justification() : matrix_num(-1), row_num(-1) {}
justification() : m_matrix_idx(-1), m_row_idx(-1) {}
void deallocate(small_object_allocator& a) { a.deallocate(get_obj_size(), sat::constraint_base::mem2base_ptr(this)); }
sat::ext_constraint_idx to_index() const { return sat::constraint_base::mem2base(this); }
@ -67,20 +67,20 @@ namespace xr {
}
static size_t get_obj_size() { return sat::constraint_base::obj_size(sizeof(justification)); }
unsigned get_matrix_num() const {
return matrix_num;
unsigned get_matrix_idx() const {
return m_matrix_idx;
}
unsigned get_row_num() const {
return row_num;
unsigned get_row_idx() const {
return m_row_idx;
}
bool isNull() const {
return matrix_num == -1;
return m_matrix_idx == -1;
}
bool operator==(const justification other) const {
return matrix_num == other.matrix_num && row_num == other.row_num;
return m_matrix_idx == other.m_matrix_idx && m_row_idx == other.m_row_idx;
}
bool operator!=(const justification other) const {
@ -90,7 +90,7 @@ namespace xr {
inline std::ostream& operator<<(std::ostream& os, const justification& pb) {
if (!pb.isNull()) {
return os << " xor reason, matrix= " << pb.get_matrix_num() << " row: " << pb.get_row_num();
return os << " xor reason, matrix= " << pb.get_matrix_idx() << " row: " << pb.get_row_idx();
}
return os << " NULL";
}
@ -198,15 +198,15 @@ namespace xr {
return false;
}
const unsigned& operator[](const unsigned at) const {
const unsigned& operator[](unsigned at) const {
return m_vars[at];
}
unsigned& operator[](const unsigned at) {
unsigned& operator[](unsigned at) {
return m_vars[at];
}
void shrink(const unsigned newsize) {
void shrink(unsigned newsize) {
m_vars.shrink(newsize);
}
@ -274,8 +274,8 @@ namespace xr {
friend class PackedMatrix;
friend class EGaussian;
PackedRow(const unsigned _size, int64_t* const _mp) :
mp(_mp+1),
PackedRow(unsigned _size, int64_t* const _mp) :
mp(_mp + 1),
rhs_internal(*_mp),
size(_size) {}
@ -375,7 +375,7 @@ namespace xr {
}
}
inline bool operator[](const unsigned i) const {
inline bool operator[](unsigned i) const {
return (mp[i / 64] >> (i % 64)) & 1;
}
@ -414,7 +414,7 @@ namespace xr {
void get_reason(
literal_vector& tmp_clause,
const unsigned_vector& col_to_var,
const unsigned_vector& column_to_var,
PackedRow& cols_vals,
PackedRow& tmp_col2,
literal prop
@ -441,7 +441,7 @@ namespace xr {
#endif
}
void resize(const unsigned num_rows, unsigned num_cols) {
void resize(unsigned num_rows, unsigned num_cols) {
num_cols = num_cols / 64 + (bool)(num_cols % 64);
if (numRows * (numCols + 1) < (int)num_rows * ((int)num_cols + 1)) {
size_t size = sizeof(int64_t) * num_rows*(num_cols+1);
@ -458,7 +458,7 @@ namespace xr {
numCols = num_cols;
}
void resizeNumRows(const unsigned num_rows) {
void resizeNumRows(unsigned num_rows) {
SASSERT((int)num_rows <= numRows);
numRows = num_rows;
}
@ -564,12 +564,12 @@ namespace xr {
~EGaussian();
bool is_initialized() const;
///returns FALSE in case of conflict
// returns FALSE in case of conflict
bool find_truths(
svector<gauss_watched>& ws,
unsigned& i,
unsigned& j,
unsigned var,
bool_var var,
unsigned row_n,
gauss_data& gqd
);
@ -589,6 +589,26 @@ namespace xr {
void update_matrix_no(unsigned n);
void check_watchlist_sanity();
void move_back_xor_clauses();
void output_variable_assignment(std::ostream& out, sat::solver* s) {
for (unsigned i = 0; i < m_num_cols; i++) {
out << "v" << m_column_to_var[i] << "=" << (s->value(m_column_to_var[i]) == l_undef ? "?" : (s->value(m_column_to_var[i]) == l_true ? "1" : "0")) << " ";
}
out << std::endl;
for (unsigned i = 0; i < m_num_cols; i++) {
out << "v" << m_column_to_var[i] << "=";
if (s->get_justification(m_column_to_var[i]).is_none())
out << "d";
else if (s->get_justification(m_column_to_var[i]).is_binary_clause())
out << "b";
else if (s->get_justification(m_column_to_var[i]).is_clause())
out << "c";
else
out << "j" << s->get_justification(m_column_to_var[i]).get_ext_justification_idx();
out << " ";
}
out << std::endl;
}
private:
xr::solver& m_solver; // original sat solver
@ -652,9 +672,13 @@ namespace xr {
// TODO: Maybe compress further
bool_vector satisfied_xors;
// Someone is responsible for this column if TRUE
// Someone is responsible for this column if the respective entry is true
// we always WATCH this variable
// A variable is responsible if there is only one row that has a 1 there
// v1 v2 v3
// 1 0 1
// 0 1 1
// "row 0" is responsible for v1, "row 1" is responsible for v2
bool_vector var_has_resp_row;
// row_to_var_non_resp[ROW] gives VAR it's NOT responsible for

View file

@ -227,9 +227,24 @@ namespace xr {
return sat::justification(-1);
}
void solver::get_antecedents(sat::literal l, sat::ext_justification_idx idx,
sat::literal_vector & r, bool probing) {
void solver::get_antecedents(literal l, sat::ext_justification_idx idx,
literal_vector & r, bool probing) {
auto& j = justification::from_index(idx);
int32_t ID;
literal_vector* cl = m_gmatrices[j.get_matrix_idx()]->get_reason(j.get_row_idx(), ID);
std::cout << "Justification from matrix " << j.get_matrix_idx() << " on row " << j.get_row_idx() << " (ID: " << ID << "):\n";
for (unsigned i = 0; i < cl->size(); i++) {
std::cout << (*cl)[i] << "(" << s().value((*cl)[i]) << ") ";
(*cl)[i].neg();
}
std::cout << std::endl;
r.append(*cl);
std::cout << "Overall assignments: ";
m_gmatrices[j.get_matrix_idx()]->output_variable_assignment(std::cout, &s());
}
sat::check_result solver::check() {
@ -342,7 +357,7 @@ namespace xr {
s().set_conflict();
return false;
case 1: {
s().assign_scoped(sat::literal(constraint[0], !constraint.m_rhs));
s().assign_scoped(literal(constraint[0], !constraint.m_rhs));
s().propagate(false);
return false;
}