mirror of
https://github.com/Z3Prover/z3
synced 2025-07-20 11:22:04 +00:00
instrument for align solver=2, 6
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fca9939371
commit
8a996dc2ac
9 changed files with 700 additions and 660 deletions
|
@ -5024,12 +5024,14 @@ br_status seq_rewriter::mk_re_star(expr* a, expr_ref& result) {
|
||||||
* (re.range c_1 c_n)
|
* (re.range c_1 c_n)
|
||||||
*/
|
*/
|
||||||
br_status seq_rewriter::mk_re_range(expr* lo, expr* hi, expr_ref& result) {
|
br_status seq_rewriter::mk_re_range(expr* lo, expr* hi, expr_ref& result) {
|
||||||
zstring s;
|
zstring slo, shi;
|
||||||
unsigned len = 0;
|
unsigned len = 0;
|
||||||
bool is_empty = false;
|
bool is_empty = false;
|
||||||
if (str().is_string(lo, s) && s.length() != 1)
|
if (str().is_string(lo, slo) && slo.length() != 1)
|
||||||
is_empty = true;
|
is_empty = true;
|
||||||
if (str().is_string(hi, s) && s.length() != 1)
|
if (str().is_string(hi, shi) && shi.length() != 1)
|
||||||
|
is_empty = true;
|
||||||
|
if (slo.length() == 1 && shi.length() == 1 && slo[0] > shi[0])
|
||||||
is_empty = true;
|
is_empty = true;
|
||||||
len = min_length(lo).second;
|
len = min_length(lo).second;
|
||||||
if (len > 1)
|
if (len > 1)
|
||||||
|
@ -5246,7 +5248,17 @@ br_status seq_rewriter::reduce_re_is_empty(expr* r, expr_ref& result) {
|
||||||
else if (re().is_range(r, r1, r2) &&
|
else if (re().is_range(r, r1, r2) &&
|
||||||
str().is_string(r1, s1) && str().is_string(r2, s2) &&
|
str().is_string(r1, s1) && str().is_string(r2, s2) &&
|
||||||
s1.length() == 1 && s2.length() == 1) {
|
s1.length() == 1 && s2.length() == 1) {
|
||||||
result = m().mk_bool_val(s1[0] <= s2[0]);
|
result = m().mk_bool_val(s1[0] > s2[0]);
|
||||||
|
return BR_DONE;
|
||||||
|
}
|
||||||
|
else if (re().is_range(r, r1, r2) &&
|
||||||
|
str().is_string(r1, s1) && s1.length() != 1) {
|
||||||
|
result = m().mk_true();
|
||||||
|
return BR_DONE;
|
||||||
|
}
|
||||||
|
else if (re().is_range(r, r1, r2) &&
|
||||||
|
str().is_string(r2, s2) && s2.length() != 1) {
|
||||||
|
result = m().mk_true();
|
||||||
return BR_DONE;
|
return BR_DONE;
|
||||||
}
|
}
|
||||||
else if ((re().is_loop(r, r1, lo) ||
|
else if ((re().is_loop(r, r1, lo) ||
|
||||||
|
@ -5307,6 +5319,7 @@ br_status seq_rewriter::mk_le_core(expr * l, expr * r, expr_ref & result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
|
br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
|
||||||
|
TRACE("seq", tout << mk_pp(l, m()) << " == " << mk_pp(r, m()) << "\n");
|
||||||
expr_ref_vector res(m());
|
expr_ref_vector res(m());
|
||||||
expr_ref_pair_vector new_eqs(m());
|
expr_ref_pair_vector new_eqs(m());
|
||||||
if (m_util.is_re(l)) {
|
if (m_util.is_re(l)) {
|
||||||
|
|
|
@ -14,34 +14,51 @@
|
||||||
|
|
||||||
namespace lp {
|
namespace lp {
|
||||||
|
|
||||||
int_solver::patcher::patcher(int_solver& lia):
|
int_solver::patcher::patcher(int_solver& lia):
|
||||||
lia(lia),
|
lia(lia),
|
||||||
lra(lia.lra),
|
lra(lia.lra),
|
||||||
lrac(lia.lrac)
|
lrac(lia.lrac)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void int_solver::patcher::remove_fixed_vars_from_base() {
|
||||||
|
unsigned num = lra.A_r().column_count();
|
||||||
|
for (unsigned v = 0; v < num; v++) {
|
||||||
|
if (!lia.is_base(v) || !lia.is_fixed(v))
|
||||||
|
continue;
|
||||||
|
auto const & r = lra.basic2row(v);
|
||||||
|
for (auto const& c : r) {
|
||||||
|
if (c.var() != v && !lia.is_fixed(c.var())) {
|
||||||
|
lra.pivot(c.var(), v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lia_move int_solver::patcher::patch_nbasic_columns() {
|
lia_move int_solver::patcher::patch_nbasic_columns() {
|
||||||
lia.settings().stats().m_patches++;
|
remove_fixed_vars_from_base();
|
||||||
lp_assert(lia.is_feasible());
|
lia.settings().stats().m_patches++;
|
||||||
m_patch_success = 0;
|
lp_assert(lia.is_feasible());
|
||||||
m_patch_fail = 0;
|
m_patch_success = 0;
|
||||||
unsigned num = lra.A_r().column_count();
|
m_patch_fail = 0;
|
||||||
for (unsigned v = 0; v < num; v++) {
|
m_num_ones = 0;
|
||||||
if (lia.is_base(v))
|
m_num_divides = 0;
|
||||||
continue;
|
unsigned num = lra.A_r().column_count();
|
||||||
patch_nbasic_column(v);
|
for (unsigned v = 0; v < num; v++) {
|
||||||
|
if (lia.is_base(v))
|
||||||
|
continue;
|
||||||
|
patch_nbasic_column(v);
|
||||||
|
}
|
||||||
|
lp_assert(lia.is_feasible());
|
||||||
|
verbose_stream() << "patch " << m_patch_success << " fails " << m_patch_fail << " ones " << m_num_ones << " divides " << m_num_divides << "\n";
|
||||||
|
//lra.display(verbose_stream());
|
||||||
|
//exit(0);
|
||||||
|
if (!lia.has_inf_int()) {
|
||||||
|
lia.settings().stats().m_patches_success++;
|
||||||
|
return lia_move::sat;
|
||||||
|
}
|
||||||
|
return lia_move::undef;
|
||||||
}
|
}
|
||||||
// for (unsigned j : lia.lrac.m_r_nbasis)
|
|
||||||
// patch_nbasic_column(j);
|
|
||||||
lp_assert(lia.is_feasible());
|
|
||||||
verbose_stream() << "patch " << m_patch_success << " fails " << m_patch_fail << "\n";
|
|
||||||
if (!lia.has_inf_int()) {
|
|
||||||
lia.settings().stats().m_patches_success++;
|
|
||||||
return lia_move::sat;
|
|
||||||
}
|
|
||||||
return lia_move::undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
void int_solver::patcher::patch_nbasic_column(unsigned j) {
|
void int_solver::patcher::patch_nbasic_column(unsigned j) {
|
||||||
impq & val = lrac.m_r_x[j];
|
impq & val = lrac.m_r_x[j];
|
||||||
|
@ -54,8 +71,24 @@ void int_solver::patcher::patch_nbasic_column(unsigned j) {
|
||||||
bool m_is_one = m.is_one();
|
bool m_is_one = m.is_one();
|
||||||
bool val_is_int = lia.value_is_int(j);
|
bool val_is_int = lia.value_is_int(j);
|
||||||
|
|
||||||
|
|
||||||
|
const auto & A = lra.A_r();
|
||||||
|
if (!m_is_one) {
|
||||||
|
verbose_stream() << "divisor: " << m << "\n";
|
||||||
|
lia.display_column(verbose_stream(), j);
|
||||||
|
for (auto c : A.column(j)) {
|
||||||
|
unsigned row_index = c.var();
|
||||||
|
lia.display_row(verbose_stream(), A.m_rows[row_index]);
|
||||||
|
verbose_stream() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check whether value of j is already a multiple of m.
|
// check whether value of j is already a multiple of m.
|
||||||
if (val_is_int && (m_is_one || (val.x / m).is_int())) {
|
if (val_is_int && (m_is_one || (val.x / m).is_int())) {
|
||||||
|
if (m_is_one)
|
||||||
|
++m_num_ones;
|
||||||
|
else
|
||||||
|
++m_num_divides;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,12 +110,14 @@ void int_solver::patcher::patch_nbasic_column(unsigned j) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
verbose_stream() << "TARGET v" << j << " -> [";
|
verbose_stream() << "TARGET v" << j << " -> [";
|
||||||
if (inf_l) verbose_stream() << "-oo"; else verbose_stream() << ceil(l.x);
|
if (inf_l) verbose_stream() << "-oo"; else verbose_stream() << ceil(l.x);
|
||||||
verbose_stream() << ", ";
|
verbose_stream() << ", ";
|
||||||
if (inf_u) verbose_stream() << "oo"; else verbose_stream() << floor(u.x);
|
if (inf_u) verbose_stream() << "oo"; else verbose_stream() << floor(u.x);
|
||||||
verbose_stream() << "]";
|
verbose_stream() << "]";
|
||||||
verbose_stream() << ", m: " << m << ", val: " << val << ", is_int: " << lra.column_is_int(j) << "\n";
|
verbose_stream() << ", m: " << m << ", val: " << val << ", is_int: " << lra.column_is_int(j) << "\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!inf_l) {
|
if (!inf_l) {
|
||||||
l = impq(m_is_one ? ceil(l) : m * ceil(l / m));
|
l = impq(m_is_one ? ceil(l) : m * ceil(l / m));
|
||||||
|
@ -472,14 +507,11 @@ bool int_solver::at_upper(unsigned j) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & int_solver::display_row(std::ostream & out, lp::row_strip<rational> const & row) const {
|
std::ostream & int_solver::display_row(std::ostream & out, lp::row_strip<rational> const & row) const {
|
||||||
bool first = true;
|
bool first = true;
|
||||||
auto & rslv = lrac.m_r_solver;
|
auto & rslv = lrac.m_r_solver;
|
||||||
for (const auto &c : row)
|
for (const auto &c : row) {
|
||||||
{
|
if (is_fixed(c.var())) {
|
||||||
if (is_fixed(c.var()))
|
if (!get_value(c.var()).is_zero()) {
|
||||||
{
|
|
||||||
if (!get_value(c.var()).is_zero())
|
|
||||||
{
|
|
||||||
impq val = get_value(c.var()) * c.coeff();
|
impq val = get_value(c.var()) * c.coeff();
|
||||||
if (!first && val.is_pos())
|
if (!first && val.is_pos())
|
||||||
out << "+";
|
out << "+";
|
||||||
|
@ -498,17 +530,11 @@ for (const auto &c : row)
|
||||||
}
|
}
|
||||||
else if (c.coeff().is_minus_one())
|
else if (c.coeff().is_minus_one())
|
||||||
out << "-";
|
out << "-";
|
||||||
else
|
else {
|
||||||
{
|
if (c.coeff().is_pos() && !first)
|
||||||
if (c.coeff().is_pos())
|
out << "+";
|
||||||
{
|
|
||||||
if (!first)
|
|
||||||
out << "+";
|
|
||||||
}
|
|
||||||
if (c.coeff().is_big())
|
if (c.coeff().is_big())
|
||||||
{
|
|
||||||
out << " b*";
|
out << " b*";
|
||||||
}
|
|
||||||
else
|
else
|
||||||
out << c.coeff();
|
out << c.coeff();
|
||||||
}
|
}
|
||||||
|
@ -516,8 +542,7 @@ for (const auto &c : row)
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
out << "\n";
|
out << "\n";
|
||||||
for (const auto &c : row)
|
for (const auto &c : row) {
|
||||||
{
|
|
||||||
if (is_fixed(c.var()))
|
if (is_fixed(c.var()))
|
||||||
continue;
|
continue;
|
||||||
rslv.print_column_info(c.var(), out);
|
rslv.print_column_info(c.var(), out);
|
||||||
|
@ -526,14 +551,13 @@ for (const auto &c : row)
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& int_solver::display_row_info(std::ostream & out, unsigned row_index) const {
|
std::ostream& int_solver::display_row_info(std::ostream & out, unsigned row_index) const {
|
||||||
auto & rslv = lrac.m_r_solver;
|
auto & rslv = lrac.m_r_solver;
|
||||||
auto const& row = rslv.m_A.m_rows[row_index];
|
auto const& row = rslv.m_A.m_rows[row_index];
|
||||||
return display_row(out, row);
|
return display_row(out, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool int_solver::shift_var(unsigned j, unsigned range) {
|
bool int_solver::shift_var(unsigned j, unsigned range) {
|
||||||
if (is_fixed(j) || is_base(j))
|
if (is_fixed(j) || is_base(j))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -46,12 +46,15 @@ class int_solver {
|
||||||
lar_core_solver& lrac;
|
lar_core_solver& lrac;
|
||||||
unsigned m_patch_success = 0;
|
unsigned m_patch_success = 0;
|
||||||
unsigned m_patch_fail = 0;
|
unsigned m_patch_fail = 0;
|
||||||
|
unsigned m_num_ones = 0;
|
||||||
|
unsigned m_num_divides = 0;
|
||||||
public:
|
public:
|
||||||
patcher(int_solver& lia);
|
patcher(int_solver& lia);
|
||||||
bool should_apply() const { return true; }
|
bool should_apply() const { return true; }
|
||||||
lia_move operator()() { return patch_nbasic_columns(); }
|
lia_move operator()() { return patch_nbasic_columns(); }
|
||||||
void patch_nbasic_column(unsigned j);
|
void patch_nbasic_column(unsigned j);
|
||||||
private:
|
private:
|
||||||
|
void remove_fixed_vars_from_base();
|
||||||
lia_move patch_nbasic_columns();
|
lia_move patch_nbasic_columns();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,8 @@ public:
|
||||||
|
|
||||||
void solve();
|
void solve();
|
||||||
|
|
||||||
|
void pivot(int entering, int leaving) { m_r_solver.pivot(entering, leaving); }
|
||||||
|
|
||||||
bool lower_bounds_are_set() const { return true; }
|
bool lower_bounds_are_set() const { return true; }
|
||||||
|
|
||||||
const indexed_vector<mpq> & get_pivot_row() const {
|
const indexed_vector<mpq> & get_pivot_row() const {
|
||||||
|
|
|
@ -393,26 +393,31 @@ public:
|
||||||
void clear_inf_set() {
|
void clear_inf_set() {
|
||||||
m_mpq_lar_core_solver.m_r_solver.inf_set().clear();
|
m_mpq_lar_core_solver.m_r_solver.inf_set().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void remove_column_from_inf_set(unsigned j) {
|
inline void remove_column_from_inf_set(unsigned j) {
|
||||||
m_mpq_lar_core_solver.m_r_solver.remove_column_from_inf_set(j);
|
m_mpq_lar_core_solver.m_r_solver.remove_column_from_inf_set(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pivot(int entering, int leaving) {
|
||||||
|
m_mpq_lar_core_solver.pivot(entering, leaving);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ChangeReport>
|
template <typename ChangeReport>
|
||||||
void change_basic_columns_dependend_on_a_given_nb_column_report(unsigned j,
|
void change_basic_columns_dependend_on_a_given_nb_column_report(unsigned j,
|
||||||
const numeric_pair<mpq> & delta,
|
const numeric_pair<mpq> & delta,
|
||||||
const ChangeReport& after) {
|
const ChangeReport& after) {
|
||||||
|
|
||||||
for (const auto & c : A_r().m_columns[j]) {
|
for (const auto & c : A_r().m_columns[j]) {
|
||||||
unsigned bj = m_mpq_lar_core_solver.m_r_basis[c.var()];
|
unsigned bj = m_mpq_lar_core_solver.m_r_basis[c.var()];
|
||||||
if (tableau_with_costs()) {
|
if (tableau_with_costs())
|
||||||
m_basic_columns_with_changed_cost.insert(bj);
|
m_basic_columns_with_changed_cost.insert(bj);
|
||||||
}
|
m_mpq_lar_core_solver.m_r_solver.add_delta_to_x_and_track_feasibility(bj, - A_r().get_val(c) * delta);
|
||||||
m_mpq_lar_core_solver.m_r_solver.add_delta_to_x_and_track_feasibility(bj, - A_r().get_val(c) * delta);
|
after(bj);
|
||||||
after(bj);
|
TRACE("change_x_del",
|
||||||
TRACE("change_x_del",
|
tout << "changed basis column " << bj << ", it is " <<
|
||||||
tout << "changed basis column " << bj << ", it is " <<
|
( m_mpq_lar_core_solver.m_r_solver.column_is_feasible(bj)?"feas":"inf") << std::endl;);
|
||||||
( m_mpq_lar_core_solver.m_r_solver.column_is_feasible(bj)? "feas":"inf") << std::endl;);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ChangeReport>
|
template <typename ChangeReport>
|
||||||
void set_value_for_nbasic_column_report(unsigned j,
|
void set_value_for_nbasic_column_report(unsigned j,
|
||||||
|
|
|
@ -324,7 +324,7 @@ pivot_column_tableau(unsigned j, unsigned piv_row_index) {
|
||||||
if(! m_A.pivot_row_to_row_given_cell(piv_row_index, c, j)) {
|
if(! m_A.pivot_row_to_row_given_cell(piv_row_index, c, j)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (m_pivoted_rows!= nullptr)
|
if (m_pivoted_rows != nullptr)
|
||||||
m_pivoted_rows->insert(c.var());
|
m_pivoted_rows->insert(c.var());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -162,13 +162,14 @@ template <typename T, typename X>void lp_primal_core_solver<T, X>::advance_on_en
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!is_zero(t)) {
|
if (!is_zero(t)) {
|
||||||
if (this->current_x_is_feasible() ) {
|
if (this->current_x_is_feasible()) {
|
||||||
if (m_sign_of_entering_delta == -1)
|
if (m_sign_of_entering_delta == -1)
|
||||||
t = -t;
|
t = -t;
|
||||||
}
|
}
|
||||||
this->update_basis_and_x_tableau(entering, leaving, t);
|
this->update_basis_and_x_tableau(entering, leaving, t);
|
||||||
this->iters_with_no_cost_growing() = 0;
|
this->iters_with_no_cost_growing() = 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this->pivot_column_tableau(entering, this->m_basis_heading[leaving]);
|
this->pivot_column_tableau(entering, this->m_basis_heading[leaving]);
|
||||||
this->change_basis(entering, leaving);
|
this->change_basis(entering, leaving);
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,15 +908,20 @@ namespace smt {
|
||||||
inf_numeral l, u;
|
inf_numeral l, u;
|
||||||
numeral m;
|
numeral m;
|
||||||
unsigned num_patched = 0, num_not_patched = 0;
|
unsigned num_patched = 0, num_not_patched = 0;
|
||||||
|
unsigned num_one = 0, num_divides = 0;
|
||||||
for (theory_var v = 0; v < num; v++) {
|
for (theory_var v = 0; v < num; v++) {
|
||||||
if (!is_non_base(v))
|
if (!is_non_base(v))
|
||||||
continue;
|
continue;
|
||||||
get_freedom_interval(v, inf_l, l, inf_u, u, m);
|
get_freedom_interval(v, inf_l, l, inf_u, u, m);
|
||||||
if (m.is_one() && get_value(v).is_int())
|
if (m.is_one() && get_value(v).is_int()) {
|
||||||
|
num_one++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
// check whether value of v is already a multiple of m.
|
// check whether value of v is already a multiple of m.
|
||||||
if ((get_value(v).get_rational() / m).is_int())
|
if ((get_value(v).get_rational() / m).is_int()) {
|
||||||
|
num_divides++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("patch_int",
|
TRACE("patch_int",
|
||||||
tout << "TARGET v" << v << " -> [";
|
tout << "TARGET v" << v << " -> [";
|
||||||
|
@ -927,13 +932,14 @@ namespace smt {
|
||||||
tout << ", m: " << m << ", val: " << get_value(v) << ", is_int: " << is_int(v) << "\n";);
|
tout << ", m: " << m << ", val: " << get_value(v) << ", is_int: " << is_int(v) << "\n";);
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
verbose_stream() << "TARGET v" << v << " -> [";
|
verbose_stream() << "TARGET v" << v << " -> [";
|
||||||
if (inf_l) verbose_stream() << "-oo"; else verbose_stream() << ceil(l);
|
if (inf_l) verbose_stream() << "-oo"; else verbose_stream() << ceil(l);
|
||||||
verbose_stream() << ", ";
|
verbose_stream() << ", ";
|
||||||
if (inf_u) verbose_stream() << "oo"; else verbose_stream() << floor(u);
|
if (inf_u) verbose_stream() << "oo"; else verbose_stream() << floor(u);
|
||||||
verbose_stream() << "]";
|
verbose_stream() << "]";
|
||||||
verbose_stream() << ", m: " << m << ", val: " << get_value(v) << ", is_int: " << is_int(v) << "\n";
|
verbose_stream() << ", m: " << m << ", val: " << get_value(v) << ", is_int: " << is_int(v) << "\n";
|
||||||
|
#endif
|
||||||
if (!inf_l)
|
if (!inf_l)
|
||||||
l = ceil(l);
|
l = ceil(l);
|
||||||
if (!inf_u)
|
if (!inf_u)
|
||||||
|
@ -957,7 +963,9 @@ namespace smt {
|
||||||
set_value(v, inf_numeral(0));
|
set_value(v, inf_numeral(0));
|
||||||
}
|
}
|
||||||
SASSERT(m_to_patch.empty());
|
SASSERT(m_to_patch.empty());
|
||||||
verbose_stream() << "patched " << num_patched << " not patched " << num_not_patched << "\n";
|
verbose_stream() << "patched " << num_patched << " not patched " << num_not_patched << " ones " << num_one << " divides " << num_divides << "\n";
|
||||||
|
//display(verbose_stream());
|
||||||
|
//exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue