mirror of
https://github.com/Z3Prover/z3
synced 2025-04-29 03:45:51 +00:00
na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
253c954094
commit
cfd204e5fe
7 changed files with 107 additions and 71 deletions
|
@ -21,6 +21,7 @@ Author:
|
|||
#include <limits>
|
||||
#include "math/simplex/sparse_matrix.h"
|
||||
#include "util/heap.h"
|
||||
#include "util/map.h"
|
||||
#include "util/lbool.h"
|
||||
#include "util/uint_set.h"
|
||||
|
||||
|
@ -80,13 +81,20 @@ namespace polysat {
|
|||
numeral m_base_coeff;
|
||||
};
|
||||
|
||||
struct offset_eq {
|
||||
struct var_eq {
|
||||
var_t x, y;
|
||||
row r1, r2;
|
||||
offset_eq(var_t x, var_t y, row const& r1, row const& r2):
|
||||
var_eq(var_t x, var_t y, row const& r1, row const& r2):
|
||||
x(x), y(y), r1(r1), r2(r2) {}
|
||||
};
|
||||
|
||||
struct fix_entry {
|
||||
var_t x;
|
||||
row r;
|
||||
fix_entry(var_t x, row const& r): x(x), r(r) {}
|
||||
fix_entry():x(null_var), r(0) {}
|
||||
};
|
||||
|
||||
static const var_t null_var = UINT_MAX;
|
||||
reslimit& m_limit;
|
||||
mutable manager m;
|
||||
|
@ -96,7 +104,7 @@ namespace polysat {
|
|||
var_heap m_to_patch;
|
||||
vector<var_info> m_vars;
|
||||
vector<row_info> m_rows;
|
||||
vector<offset_eq> m_offset_eqs;
|
||||
vector<var_eq> m_var_eqs;
|
||||
bool m_bland { false };
|
||||
unsigned m_blands_rule_threshold { 1000 };
|
||||
random_gen m_random;
|
||||
|
@ -104,6 +112,7 @@ namespace polysat {
|
|||
unsigned m_infeasible_var { null_var };
|
||||
unsigned_vector m_base_vars;
|
||||
stats m_stats;
|
||||
map<numeral, fix_entry, typename manager::hash, typename manager::eq> m_value2fixed_var;
|
||||
|
||||
public:
|
||||
fixplex(reslimit& lim):
|
||||
|
@ -153,6 +162,7 @@ namespace polysat {
|
|||
bool is_offset_row(row const& r, numeral& cx, var_t& x, numeral& cy, var_t & y) const;
|
||||
void lookahead_eq(row const& r1, numeral const& cx, var_t x, numeral const& cy, var_t y);
|
||||
void get_offset_eqs(row const& r);
|
||||
void fixed_var_eh(row const& r, var_t x);
|
||||
void eq_eh(var_t x, var_t y, row const& r1, row const& r2);
|
||||
void pivot(var_t x_i, var_t x_j, numeral const& b, numeral const& value);
|
||||
numeral value2delta(var_t v, numeral const& new_value) const;
|
||||
|
@ -166,6 +176,7 @@ namespace polysat {
|
|||
bool is_free(var_t v) const { return lo(v) == hi(v); }
|
||||
bool is_non_free(var_t v) const { return !is_free(v); }
|
||||
bool is_fixed(var_t v) const { return lo(v) + 1 == hi(v); }
|
||||
bool is_valid_variable(var_t v) const { return v < m_vars.size(); }
|
||||
bool is_base(var_t x) const { return m_vars[x].m_is_base; }
|
||||
unsigned base2row(var_t x) const { return m_vars[x].m_base2row; }
|
||||
numeral const& row2value(row const& r) const { return m_rows[r.id()].m_value; }
|
||||
|
@ -206,6 +217,16 @@ namespace polysat {
|
|||
static const uint64_t max_numeral = 0; // std::limits<uint64_t>::max();
|
||||
struct manager {
|
||||
typedef uint64_t numeral;
|
||||
struct hash {
|
||||
unsigned operator()(numeral const& n) const {
|
||||
return static_cast<unsigned>(n);
|
||||
}
|
||||
};
|
||||
struct eq {
|
||||
bool operator()(numeral const& a, numeral const& b) const {
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
void reset() {}
|
||||
void reset(numeral& n) { n = 0; }
|
||||
void del(numeral const& n) {}
|
||||
|
|
|
@ -96,13 +96,13 @@ namespace polysat {
|
|||
numeral base_coeff = 0;
|
||||
numeral value = 0;
|
||||
for (auto const& e : M.row_entries(r)) {
|
||||
var_t v = e.m_var;
|
||||
var_t v = e.var();
|
||||
if (v == base_var)
|
||||
base_coeff = e.m_coeff;
|
||||
base_coeff = e.coeff();
|
||||
else {
|
||||
if (is_base(v))
|
||||
m_base_vars.push_back(v);
|
||||
value += e.m_coeff * m_vars[v].m_value;
|
||||
value += e.coeff() * m_vars[v].m_value;
|
||||
}
|
||||
}
|
||||
SASSERT(base_coeff != 0);
|
||||
|
@ -147,7 +147,7 @@ namespace polysat {
|
|||
row r = c.get_row();
|
||||
row_info& ri = m_rows[r.id()];
|
||||
var_t s = ri.m_base;
|
||||
ri.m_value += delta * c.get_row_entry().m_coeff;
|
||||
ri.m_value += delta * c.get_row_entry().coeff();
|
||||
set_base_value(s);
|
||||
add_patch(s);
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ namespace polysat {
|
|||
|
||||
pivot(x, y, b, new_value);
|
||||
|
||||
get_offset_eqs(row(base2row(y)));
|
||||
// get_offset_eqs(row(base2row(y)));
|
||||
|
||||
return l_true;
|
||||
}
|
||||
|
@ -249,8 +249,8 @@ namespace polysat {
|
|||
bool best_in_bounds = false;
|
||||
|
||||
for (auto const& r : M.row_entries(r)) {
|
||||
var_t y = r.m_var;
|
||||
numeral const & b = r.m_coeff;
|
||||
var_t y = r.var();
|
||||
numeral const & b = r.coeff();
|
||||
if (x == y)
|
||||
continue;
|
||||
if (!has_minimal_trailing_zeros(y, b))
|
||||
|
@ -353,7 +353,7 @@ namespace polysat {
|
|||
if (tz1 == 0)
|
||||
return true;
|
||||
for (auto col : M.col_entries(y)) {
|
||||
numeral c = col.get_row_entry().m_coeff;
|
||||
numeral c = col.get_row_entry().coeff();
|
||||
unsigned tz2 = m.trailing_zeros(c);
|
||||
if (tz1 > tz2)
|
||||
return false;
|
||||
|
@ -385,8 +385,8 @@ namespace polysat {
|
|||
auto r = base2row(x);
|
||||
numeral lo_sum = 0, hi_sum = 0, diff = 0;
|
||||
for (auto const& e : M.row_entries(row(r))) {
|
||||
var_t v = e.m_var;
|
||||
numeral const& c = e.m_coeff;
|
||||
var_t v = e.var();
|
||||
numeral const& c = e.coeff();
|
||||
if (lo(v) == hi(v))
|
||||
return false;
|
||||
lo_sum += lo(v) * c;
|
||||
|
@ -419,8 +419,8 @@ namespace polysat {
|
|||
numeral fixed = 0;
|
||||
unsigned parity = UINT_MAX;
|
||||
for (auto const& e : M.row_entries(row(r))) {
|
||||
var_t v = e.m_var;
|
||||
auto c = e.m_coeff;
|
||||
var_t v = e.var();
|
||||
auto c = e.coeff();
|
||||
if (is_fixed(v))
|
||||
fixed += value(v)*c;
|
||||
else
|
||||
|
@ -498,7 +498,7 @@ namespace polysat {
|
|||
auto z = row2base(r_z);
|
||||
auto& row_z = m_rows[rz];
|
||||
var_info& zI = m_vars[z];
|
||||
numeral c = col.get_row_entry().m_coeff;
|
||||
numeral c = col.get_row_entry().coeff();
|
||||
unsigned tz2 = m.trailing_zeros(c);
|
||||
SASSERT(tz1 <= tz2);
|
||||
numeral b1 = b >> tz1;
|
||||
|
@ -551,10 +551,7 @@ namespace polysat {
|
|||
void fixplex<Ext>::add_patch(var_t v) {
|
||||
SASSERT(is_base(v));
|
||||
CTRACE("polysat", !in_bounds(v), tout << "Add patch: v" << v << "\n";);
|
||||
if (in_bounds(v)) {
|
||||
|
||||
}
|
||||
else
|
||||
if (!in_bounds(v))
|
||||
m_to_patch.insert(v);
|
||||
}
|
||||
|
||||
|
@ -649,6 +646,8 @@ namespace polysat {
|
|||
*
|
||||
* Fixed variable equalities
|
||||
* -------------------------
|
||||
* Use persistent hash-table of variables that are fixed at values.
|
||||
* Update table when a variable gets fixed and check for collisions.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -669,10 +668,10 @@ namespace polysat {
|
|||
if (!row2integral(r))
|
||||
return false;
|
||||
for (auto const& e : M.row_entries(r)) {
|
||||
var_t v = e.m_var;
|
||||
var_t v = e.var();
|
||||
if (is_fixed(v))
|
||||
continue;
|
||||
numeral const& c = e.m_coeff;
|
||||
numeral const& c = e.coeff();
|
||||
if (x == null_var) {
|
||||
cx = c;
|
||||
x = v;
|
||||
|
@ -709,11 +708,23 @@ namespace polysat {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulate equalities between variables fixed to the same values.
|
||||
*/
|
||||
template<typename Ext>
|
||||
void fixplex<Ext>::fixed_var_eh(row const& r, var_t x) {
|
||||
numeral val = value(x);
|
||||
fix_entry e;
|
||||
if (m_value2fixed_var.find(val, e) && is_valid_variable(e.x) && is_fixed(e.x) && value(e.x) == val && e.x != x)
|
||||
eq_eh(x, y, e.r, r);
|
||||
else
|
||||
m_value2fixed_var.insert(val, fix_entry(x, r));
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
void fixplex<Ext>::eq_eh(var_t x, var_t y, row const& r1, row const& r2) {
|
||||
m_offset_eqs.push_back(offset_eq(x, y, r1, r2));
|
||||
}
|
||||
|
||||
m_var_eqs.push_back(var_eq(x, y, r1, r2));
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
std::ostream& fixplex<Ext>::display(std::ostream& out) const {
|
||||
|
@ -730,9 +741,9 @@ namespace polysat {
|
|||
template<typename Ext>
|
||||
std::ostream& fixplex<Ext>::display_row(std::ostream& out, row const& r, bool values) {
|
||||
for (auto const& e : M.row_entries(r)) {
|
||||
var_t v = e.m_var;
|
||||
if (e.m_coeff != 1)
|
||||
out << e.m_coeff << " * ";
|
||||
var_t v = e.var();
|
||||
if (e.coeff() != 1)
|
||||
out << e.coeff() << " * ";
|
||||
out << "v" << v << " ";
|
||||
if (values)
|
||||
out << value(v) << " [" << lo(v) << ", " << hi(v) << "[ ";
|
||||
|
@ -766,8 +777,8 @@ namespace polysat {
|
|||
numeral sum = 0;
|
||||
numeral base_coeff = m_rows[r.id()].m_base_coeff;
|
||||
for (auto const& e : M.row_entries(r)) {
|
||||
sum += value(e.m_var) * e.m_coeff;
|
||||
SASSERT(s != e.m_var || base_coeff == e.m_coeff);
|
||||
sum += value(e.var()) * e.coeff();
|
||||
SASSERT(s != e.var() || base_coeff == e.coeff());
|
||||
}
|
||||
if (sum >= base_coeff) {
|
||||
IF_VERBOSE(0, M.display_row(verbose_stream(), r););
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue