mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
fix wrong simplex backtracking
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
d2db8007d8
commit
05a39cb2cf
|
@ -144,7 +144,7 @@ app * pb_util::mk_lt(unsigned num_args, rational const * _coeffs, expr * const *
|
||||||
args.push_back(f);
|
args.push_back(f);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
args.push_back(m.mk_not(f));
|
args.push_back(m.mk_not(_args[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!d.is_one()) {
|
if (!d.is_one()) {
|
||||||
|
|
|
@ -126,7 +126,7 @@ namespace simplex {
|
||||||
row get_infeasible_row();
|
row get_infeasible_row();
|
||||||
var_t get_base_var(row const& r) const { return m_row2base[r.id()]; }
|
var_t get_base_var(row const& r) const { return m_row2base[r.id()]; }
|
||||||
numeral const& get_base_coeff(row const& r) const { return m_vars[m_row2base[r.id()]].m_base_coeff; }
|
numeral const& get_base_coeff(row const& r) const { return m_vars[m_row2base[r.id()]].m_base_coeff; }
|
||||||
void del_row(row const& r);
|
void del_row(var_t base_var);
|
||||||
void set_lower(var_t var, eps_numeral const& b);
|
void set_lower(var_t var, eps_numeral const& b);
|
||||||
void set_upper(var_t var, eps_numeral const& b);
|
void set_upper(var_t var, eps_numeral const& b);
|
||||||
void get_lower(var_t var, scoped_eps_numeral& b) const { b = m_vars[var].m_lower; }
|
void get_lower(var_t var, scoped_eps_numeral& b) const { b = m_vars[var].m_lower; }
|
||||||
|
@ -157,6 +157,7 @@ namespace simplex {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void del_row(row const& r);
|
||||||
var_t select_var_to_fix();
|
var_t select_var_to_fix();
|
||||||
pivot_strategy_t pivot_strategy();
|
pivot_strategy_t pivot_strategy();
|
||||||
var_t select_smallest_var() { return m_to_patch.empty()?null_var:m_to_patch.erase_min(); }
|
var_t select_smallest_var() { return m_to_patch.empty()?null_var:m_to_patch.erase_min(); }
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace simplex {
|
||||||
em.set(m_vars[base_var].m_value, value);
|
em.set(m_vars[base_var].m_value, value);
|
||||||
add_patch(base_var);
|
add_patch(base_var);
|
||||||
SASSERT(well_formed_row(r));
|
SASSERT(well_formed_row(r));
|
||||||
|
SASSERT(well_formed());
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,10 +136,51 @@ namespace simplex {
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
void simplex<Ext>::del_row(row const& r) {
|
void simplex<Ext>::del_row(row const& r) {
|
||||||
TRACE("simplex", tout << r.id() << "\n";);
|
var_t var = m_row2base[r.id()];
|
||||||
m_vars[m_row2base[r.id()]].m_is_base = false;
|
m_vars[var].m_is_base = false;
|
||||||
|
m_vars[var].m_lower_valid = false;
|
||||||
|
m_vars[var].m_upper_valid = false;
|
||||||
m_row2base[r.id()] = null_var;
|
m_row2base[r.id()] = null_var;
|
||||||
M.del(r);
|
M.del(r);
|
||||||
|
SASSERT(M.col_begin(var) == M.col_end(var));
|
||||||
|
SASSERT(well_formed());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ext>
|
||||||
|
void simplex<Ext>::del_row(var_t var) {
|
||||||
|
TRACE("simplex", tout << var << "\n";);
|
||||||
|
row r;
|
||||||
|
if (is_base(var)) {
|
||||||
|
r = row(m_vars[var].m_base2row);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
col_iterator it = M.col_begin(var), end = M.col_end(var);
|
||||||
|
if (it == end) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
typename matrix::row_entry const& re = it.get_row_entry();
|
||||||
|
r = it.get_row();
|
||||||
|
var_t old_base = m_row2base[r.id()];
|
||||||
|
scoped_eps_numeral new_value(em);
|
||||||
|
var_info& vi = m_vars[old_base];
|
||||||
|
if (below_lower(old_base)) {
|
||||||
|
new_value = vi.m_lower;
|
||||||
|
}
|
||||||
|
else if (above_upper(old_base)) {
|
||||||
|
new_value = vi.m_upper;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_value = vi.m_value;
|
||||||
|
}
|
||||||
|
// need to move var such that old_base comes in bound.
|
||||||
|
update_and_pivot(old_base, var, re.m_coeff, new_value);
|
||||||
|
SASSERT(is_base(var));
|
||||||
|
SASSERT(m_vars[var].m_base2row == r.id());
|
||||||
|
SASSERT(!below_lower(old_base) && !above_upper(old_base));
|
||||||
|
}
|
||||||
|
del_row(r);
|
||||||
|
TRACE("simplex", display(tout););
|
||||||
|
SASSERT(well_formed());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
|
@ -164,6 +206,7 @@ namespace simplex {
|
||||||
em.sub(b, vi.m_value, delta);
|
em.sub(b, vi.m_value, delta);
|
||||||
update_value(var, delta);
|
update_value(var, delta);
|
||||||
}
|
}
|
||||||
|
SASSERT(well_formed());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
|
@ -177,6 +220,7 @@ namespace simplex {
|
||||||
em.sub(b, vi.m_value, delta);
|
em.sub(b, vi.m_value, delta);
|
||||||
update_value(var, delta);
|
update_value(var, delta);
|
||||||
}
|
}
|
||||||
|
SASSERT(well_formed());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
|
@ -194,6 +238,7 @@ namespace simplex {
|
||||||
scoped_eps_numeral delta(em);
|
scoped_eps_numeral delta(em);
|
||||||
em.sub(b, m_vars[var].m_value, delta);
|
em.sub(b, m_vars[var].m_value, delta);
|
||||||
update_value(var, delta);
|
update_value(var, delta);
|
||||||
|
SASSERT(well_formed());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
|
@ -345,6 +390,7 @@ namespace simplex {
|
||||||
SASSERT(well_formed_row(row(r_k)));
|
SASSERT(well_formed_row(row(r_k)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SASSERT(well_formed());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ext>
|
template<typename Ext>
|
||||||
|
@ -883,7 +929,13 @@ namespace simplex {
|
||||||
var_t s = m_row2base[i];
|
var_t s = m_row2base[i];
|
||||||
if (s == null_var) continue;
|
if (s == null_var) continue;
|
||||||
SASSERT(i == m_vars[s].m_base2row);
|
SASSERT(i == m_vars[s].m_base2row);
|
||||||
SASSERT(well_formed_row(row(i)));
|
VERIFY(well_formed_row(row(i)));
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < m_vars.size(); ++i) {
|
||||||
|
if (!is_base(i)) {
|
||||||
|
SASSERT(!above_upper(i));
|
||||||
|
SASSERT(!below_lower(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -909,7 +961,11 @@ namespace simplex {
|
||||||
sum += tmp;
|
sum += tmp;
|
||||||
SASSERT(s != it->m_var || m.eq(m_vars[s].m_base_coeff, it->m_coeff));
|
SASSERT(s != it->m_var || m.eq(m_vars[s].m_base_coeff, it->m_coeff));
|
||||||
}
|
}
|
||||||
SASSERT(em.is_zero(sum));
|
if (!em.is_zero(sum)) {
|
||||||
|
IF_VERBOSE(0, M.display_row(verbose_stream(), r););
|
||||||
|
TRACE("pb", display(tout << "non-well formed row\n"); M.display_row(tout << "row: ", r););
|
||||||
|
throw default_exception("non-well formed row");
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@ namespace opt {
|
||||||
}
|
}
|
||||||
(*m_pbsls.get())();
|
(*m_pbsls.get())();
|
||||||
m_pbsls->get_model(m_model);
|
m_pbsls->get_model(m_model);
|
||||||
|
mdl = m_model.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void bvsls_opt(model_ref& mdl) {
|
void bvsls_opt(model_ref& mdl) {
|
||||||
|
@ -235,6 +236,7 @@ namespace opt {
|
||||||
SASSERT(res.is_sat == l_true || res.is_sat == l_undef);
|
SASSERT(res.is_sat == l_true || res.is_sat == l_undef);
|
||||||
if (res.is_sat == l_true) {
|
if (res.is_sat == l_true) {
|
||||||
m_bvsls->get_model(m_model);
|
m_bvsls->get_model(m_model);
|
||||||
|
mdl = m_model.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,8 @@ namespace smt {
|
||||||
m_trail(m),
|
m_trail(m),
|
||||||
one(mgr)
|
one(mgr)
|
||||||
{
|
{
|
||||||
init_max_flips();
|
reset();
|
||||||
|
one = mpz(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
~imp() {
|
~imp() {
|
||||||
|
@ -153,7 +154,6 @@ namespace smt {
|
||||||
m_assignment.push_back(true);
|
m_assignment.push_back(true);
|
||||||
m_hard_occ.push_back(unsigned_vector());
|
m_hard_occ.push_back(unsigned_vector());
|
||||||
m_soft_occ.push_back(unsigned_vector());
|
m_soft_occ.push_back(unsigned_vector());
|
||||||
one = mpz(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_max_flips() {
|
void init_max_flips() {
|
||||||
|
@ -406,7 +406,14 @@ namespace smt {
|
||||||
else if (break_count == min_bc && m_rng(5) == 1) {
|
else if (break_count == min_bc && m_rng(5) == 1) {
|
||||||
min_bc_index = i;
|
min_bc_index = i;
|
||||||
}
|
}
|
||||||
VERIFY(-break_count == flip(~lit));
|
int new_break_count = flip(~lit);
|
||||||
|
if (-break_count != new_break_count) {
|
||||||
|
verbose_stream() << lit << "\n";
|
||||||
|
IF_VERBOSE(0, display(verbose_stream(), cls););
|
||||||
|
display(verbose_stream());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
// VERIFY(-break_count == flip(~lit));
|
||||||
}
|
}
|
||||||
if (m_rng(100) <= m_non_greedy_percent) {
|
if (m_rng(100) <= m_non_greedy_percent) {
|
||||||
lit = cls.m_lits[m_rng(cls.m_lits.size())];
|
lit = cls.m_lits[m_rng(cls.m_lits.size())];
|
||||||
|
@ -472,11 +479,12 @@ namespace smt {
|
||||||
m_assignment[l.var()] = !m_assignment[l.var()];
|
m_assignment[l.var()] = !m_assignment[l.var()];
|
||||||
int break_count = 0;
|
int break_count = 0;
|
||||||
unsigned_vector const& occh = m_hard_occ[l.var()];
|
unsigned_vector const& occh = m_hard_occ[l.var()];
|
||||||
scoped_mpz value(mgr);
|
scoped_mpz value(mgr);
|
||||||
for (unsigned i = 0; i < occh.size(); ++i) {
|
for (unsigned i = 0; i < occh.size(); ++i) {
|
||||||
unsigned j = occh[i];
|
unsigned j = occh[i];
|
||||||
value = m_clauses[j].m_value;
|
clause& cls = m_clauses[j];
|
||||||
if (eval(m_clauses[j])) {
|
value = cls.m_value;
|
||||||
|
if (eval(cls)) {
|
||||||
if (m_hard_false.contains(j)) {
|
if (m_hard_false.contains(j)) {
|
||||||
break_count--;
|
break_count--;
|
||||||
m_hard_false.remove(j);
|
m_hard_false.remove(j);
|
||||||
|
@ -488,7 +496,6 @@ namespace smt {
|
||||||
m_hard_false.insert(j);
|
m_hard_false.insert(j);
|
||||||
}
|
}
|
||||||
else if (value < m_clauses[j].m_value) {
|
else if (value < m_clauses[j].m_value) {
|
||||||
break_count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ namespace opt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void get_model(model_ref& mdl) { mdl = m_model.get(); }
|
virtual void get_model(model_ref& mdl) { mdl = m_model.get(); }
|
||||||
|
void set_model() { s().get_model(m_model); }
|
||||||
virtual void updt_params(params_ref& p) {
|
virtual void updt_params(params_ref& p) {
|
||||||
m_params.copy(p);
|
m_params.copy(p);
|
||||||
s().updt_params(p);
|
s().updt_params(p);
|
||||||
|
@ -104,8 +105,12 @@ namespace opt {
|
||||||
m_upper.reset();
|
m_upper.reset();
|
||||||
m_assignment.reset();
|
m_assignment.reset();
|
||||||
for (unsigned i = 0; i < m_weights.size(); ++i) {
|
for (unsigned i = 0; i < m_weights.size(); ++i) {
|
||||||
m_upper += m_weights[i];
|
expr_ref val(m);
|
||||||
m_assignment.push_back(false);
|
VERIFY(m_model->eval(m_soft[i].get(), val));
|
||||||
|
m_assignment.push_back(m.is_true(val));
|
||||||
|
if (!m_assignment.back()) {
|
||||||
|
m_upper += m_weights[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr* mk_not(expr* e) {
|
expr* mk_not(expr* e) {
|
||||||
|
@ -255,6 +260,14 @@ namespace opt {
|
||||||
m_upper += rational(1);
|
m_upper += rational(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void process_sat() {
|
||||||
|
svector<bool> assignment;
|
||||||
|
update_assignment(assignment);
|
||||||
|
if (check_lazy_soft(assignment)) {
|
||||||
|
update_sigmas();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bcd2(solver* s, ast_manager& m):
|
bcd2(solver* s, ast_manager& m):
|
||||||
maxsmt_solver_base(s, m),
|
maxsmt_solver_base(s, m),
|
||||||
|
@ -263,7 +276,6 @@ namespace opt {
|
||||||
m_trail(m),
|
m_trail(m),
|
||||||
m_soft_constraints(m),
|
m_soft_constraints(m),
|
||||||
m_enable_lazy(true) {
|
m_enable_lazy(true) {
|
||||||
m_enable_lazy = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~bcd2() {}
|
virtual ~bcd2() {}
|
||||||
|
@ -272,11 +284,15 @@ namespace opt {
|
||||||
expr_ref fml(m), r(m);
|
expr_ref fml(m), r(m);
|
||||||
lbool is_sat = l_undef;
|
lbool is_sat = l_undef;
|
||||||
expr_ref_vector asms(m);
|
expr_ref_vector asms(m);
|
||||||
bool first = true;
|
|
||||||
enable_sls();
|
enable_sls();
|
||||||
solver::scoped_push _scope1(s());
|
solver::scoped_push _scope1(s());
|
||||||
init();
|
init();
|
||||||
init_bcd();
|
init_bcd();
|
||||||
|
if (m_cancel) {
|
||||||
|
normalize_bounds();
|
||||||
|
return l_undef;
|
||||||
|
}
|
||||||
|
process_sat();
|
||||||
while (m_lower < m_upper) {
|
while (m_lower < m_upper) {
|
||||||
IF_VERBOSE(1, verbose_stream() << "(wmaxsat.bcd2 [" << m_lower << ":" << m_upper << "])\n";);
|
IF_VERBOSE(1, verbose_stream() << "(wmaxsat.bcd2 [" << m_lower << ":" << m_upper << "])\n";);
|
||||||
assert_soft();
|
assert_soft();
|
||||||
|
@ -293,15 +309,9 @@ namespace opt {
|
||||||
case l_undef:
|
case l_undef:
|
||||||
normalize_bounds();
|
normalize_bounds();
|
||||||
return l_undef;
|
return l_undef;
|
||||||
case l_true: {
|
case l_true:
|
||||||
svector<bool> assignment;
|
process_sat();
|
||||||
update_assignment(assignment);
|
break;
|
||||||
first = false;
|
|
||||||
if (check_lazy_soft(assignment)) {
|
|
||||||
update_sigmas();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case l_false: {
|
case l_false: {
|
||||||
ptr_vector<expr> unsat_core;
|
ptr_vector<expr> unsat_core;
|
||||||
uint_set subC, soft;
|
uint_set subC, soft;
|
||||||
|
@ -322,7 +332,7 @@ namespace opt {
|
||||||
r = mk_fresh();
|
r = mk_fresh();
|
||||||
relax(subC, soft, c_s.m_R, delta);
|
relax(subC, soft, c_s.m_R, delta);
|
||||||
c_s.m_lower = refine(c_s.m_R, lower + delta - rational(1));
|
c_s.m_lower = refine(c_s.m_R, lower + delta - rational(1));
|
||||||
c_s.m_upper = rational(first?1:0);
|
c_s.m_upper = rational::one();
|
||||||
c_s.m_upper += sum_of_sigmas(c_s.m_R);
|
c_s.m_upper += sum_of_sigmas(c_s.m_R);
|
||||||
c_s.m_mid = div(c_s.m_lower + c_s.m_upper, rational(2));
|
c_s.m_mid = div(c_s.m_lower + c_s.m_upper, rational(2));
|
||||||
c_s.m_r = r;
|
c_s.m_r = r;
|
||||||
|
@ -337,12 +347,7 @@ namespace opt {
|
||||||
m_lower = compute_lower();
|
m_lower = compute_lower();
|
||||||
}
|
}
|
||||||
normalize_bounds();
|
normalize_bounds();
|
||||||
if (first) {
|
return l_true;
|
||||||
return is_sat;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return l_true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -533,13 +538,18 @@ namespace opt {
|
||||||
expr_ref fml(m);
|
expr_ref fml(m);
|
||||||
vector<rational> ws;
|
vector<rational> ws;
|
||||||
ptr_vector<expr> rs;
|
ptr_vector<expr> rs;
|
||||||
|
rational w(0);
|
||||||
for (unsigned j = 0; j < core.m_R.size(); ++j) {
|
for (unsigned j = 0; j < core.m_R.size(); ++j) {
|
||||||
unsigned idx = core.m_R[j];
|
unsigned idx = core.m_R[j];
|
||||||
ws.push_back(m_weights[idx]);
|
ws.push_back(m_weights[idx]);
|
||||||
rs.push_back(m_soft_aux[idx].get()); // TBD: check
|
w += ws.back();
|
||||||
|
rs.push_back(m_soft_aux[idx].get());
|
||||||
}
|
}
|
||||||
|
w.neg();
|
||||||
|
w += core.m_mid;
|
||||||
|
ws.push_back(w);
|
||||||
|
rs.push_back(core.m_r);
|
||||||
fml = pb.mk_le(ws.size(), ws.c_ptr(), rs.c_ptr(), core.m_mid);
|
fml = pb.mk_le(ws.size(), ws.c_ptr(), rs.c_ptr(), core.m_mid);
|
||||||
fml = m.mk_or(core.m_r, fml);
|
|
||||||
s().assert_expr(fml);
|
s().assert_expr(fml);
|
||||||
}
|
}
|
||||||
void display(std::ostream& out) {
|
void display(std::ostream& out) {
|
||||||
|
@ -604,7 +614,7 @@ namespace opt {
|
||||||
}
|
}
|
||||||
lbool is_sat = l_true;
|
lbool is_sat = l_true;
|
||||||
while (l_true == is_sat) {
|
while (l_true == is_sat) {
|
||||||
IF_VERBOSE(1, verbose_stream() << "(wmaxsat.pb solve with upper bound: " << m_upper << ")\n";);
|
TRACE("opt", s().display(tout<<"looping\n"););
|
||||||
m_upper.reset();
|
m_upper.reset();
|
||||||
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
for (unsigned i = 0; i < m_soft.size(); ++i) {
|
||||||
VERIFY(m_model->eval(nsoft[i].get(), val));
|
VERIFY(m_model->eval(nsoft[i].get(), val));
|
||||||
|
@ -614,11 +624,10 @@ namespace opt {
|
||||||
m_upper += m_weights[i];
|
m_upper += m_weights[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
IF_VERBOSE(1, verbose_stream() << "(wmaxsat.pb solve with upper bound: " << m_upper << ")\n";);
|
||||||
TRACE("opt", tout << "new upper: " << m_upper << "\n";);
|
TRACE("opt", tout << "new upper: " << m_upper << "\n";);
|
||||||
|
|
||||||
fml = u.mk_lt(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper);
|
fml = m.mk_not(u.mk_ge(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper));
|
||||||
|
|
||||||
TRACE("opt", s().display(tout<<"looping\n"););
|
|
||||||
solver::scoped_push _scope2(s());
|
solver::scoped_push _scope2(s());
|
||||||
s().assert_expr(fml);
|
s().assert_expr(fml);
|
||||||
is_sat = s().check_sat(0,0);
|
is_sat = s().check_sat(0,0);
|
||||||
|
@ -840,7 +849,11 @@ namespace opt {
|
||||||
tout << mk_pp(bs[i], m) << " " << ws[i] << "\n";
|
tout << mk_pp(bs[i], m) << " " << ws[i] << "\n";
|
||||||
});
|
});
|
||||||
maxs->init_soft(ws, nbs);
|
maxs->init_soft(ws, nbs);
|
||||||
lbool is_sat = (*maxs)();
|
lbool is_sat = maxs->s().check_sat(0,0);
|
||||||
|
if (is_sat == l_true) {
|
||||||
|
maxs->set_model();
|
||||||
|
is_sat = (*maxs)();
|
||||||
|
}
|
||||||
SASSERT(maxs->get_lower() > k);
|
SASSERT(maxs->get_lower() > k);
|
||||||
k = maxs->get_lower();
|
k = maxs->get_lower();
|
||||||
return is_sat;
|
return is_sat;
|
||||||
|
|
|
@ -529,11 +529,9 @@ namespace smt {
|
||||||
numeral k = rep.k();
|
numeral k = rep.k();
|
||||||
theory_var slack;
|
theory_var slack;
|
||||||
bool_var abv2;
|
bool_var abv2;
|
||||||
row r;
|
|
||||||
TRACE("pb", display(tout << abv <<"\n", rep););
|
TRACE("pb", display(tout << abv <<"\n", rep););
|
||||||
if (m_ineq_rep.find(rep, abv2)) {
|
if (m_ineq_rep.find(rep, abv2)) {
|
||||||
slack = abv2;
|
slack = abv2;
|
||||||
r = m_ineq_row_info.find(abv2).m_row;
|
|
||||||
TRACE("pb",
|
TRACE("pb",
|
||||||
tout << "Old row: " << abv << " |-> " << slack << " ";
|
tout << "Old row: " << abv << " |-> " << slack << " ";
|
||||||
tout << m_ineq_row_info.find(abv2).m_bound << " vs. " << k << "\n";
|
tout << m_ineq_row_info.find(abv2).m_bound << " vs. " << k << "\n";
|
||||||
|
@ -572,10 +570,10 @@ namespace smt {
|
||||||
m_simplex.ensure_var(slack);
|
m_simplex.ensure_var(slack);
|
||||||
vars.push_back(slack);
|
vars.push_back(slack);
|
||||||
coeffs.push_back(mpz(-1));
|
coeffs.push_back(mpz(-1));
|
||||||
r = m_simplex.add_row(slack, vars.size(), vars.c_ptr(), coeffs.c_ptr());
|
m_simplex.add_row(slack, vars.size(), vars.c_ptr(), coeffs.c_ptr());
|
||||||
TRACE("pb", tout << "New row: " << abv << " " << k << "\n"; display(tout, rep););
|
TRACE("pb", tout << "New row: " << abv << " " << k << "\n"; display(tout, rep););
|
||||||
}
|
}
|
||||||
m_ineq_row_info.insert(abv, row_info(slack, k, rep, r));
|
m_ineq_row_info.insert(abv, row_info(slack, k, rep));
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("pb", display(tout, *c););
|
TRACE("pb", display(tout, *c););
|
||||||
|
@ -1310,7 +1308,7 @@ namespace smt {
|
||||||
m_ineq_row_info.erase(v);
|
m_ineq_row_info.erase(v);
|
||||||
bool_var v2 = m_ineq_rep.find(r_info.m_rep);
|
bool_var v2 = m_ineq_rep.find(r_info.m_rep);
|
||||||
if (v == v2) {
|
if (v == v2) {
|
||||||
m_simplex.del_row(r_info.m_row);
|
m_simplex.del_row(r_info.m_slack);
|
||||||
m_ineq_rep.erase(r_info.m_rep);
|
m_ineq_rep.erase(r_info.m_rep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1433,7 +1431,7 @@ namespace smt {
|
||||||
|
|
||||||
justification* js = 0;
|
justification* js = 0;
|
||||||
|
|
||||||
if (m_conflict_frequency == 0 || (0 == (c.m_num_propagations % m_conflict_frequency))) {
|
if (m_conflict_frequency == 0 || (m_conflict_frequency -1 == (c.m_num_propagations % m_conflict_frequency))) {
|
||||||
resolve_conflict(c);
|
resolve_conflict(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1854,6 +1852,8 @@ namespace smt {
|
||||||
case l_undef:
|
case l_undef:
|
||||||
maxsum += c.coeff(i);
|
maxsum += c.coeff(i);
|
||||||
break;
|
break;
|
||||||
|
case l_false:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("pb", display(tout << "validate: ", c, true);
|
TRACE("pb", display(tout << "validate: ", c, true);
|
||||||
|
|
|
@ -185,9 +185,8 @@ namespace smt {
|
||||||
unsigned m_slack; // slack variable in simplex tableau
|
unsigned m_slack; // slack variable in simplex tableau
|
||||||
numeral m_bound; // bound
|
numeral m_bound; // bound
|
||||||
arg_t m_rep; // representative
|
arg_t m_rep; // representative
|
||||||
row m_row;
|
row_info(theory_var slack, numeral const& b, arg_t const& r):
|
||||||
row_info(theory_var slack, numeral const& b, arg_t const& r, row const& ro):
|
m_slack(slack), m_bound(b), m_rep(r) {}
|
||||||
m_slack(slack), m_bound(b), m_rep(r), m_row(ro) {}
|
|
||||||
row_info(): m_slack(0) {}
|
row_info(): m_slack(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -124,8 +124,6 @@ static void test4() {
|
||||||
feas(S);
|
feas(S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void tst_simplex() {
|
void tst_simplex() {
|
||||||
Simplex S;
|
Simplex S;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "model_v2_pp.h"
|
#include "model_v2_pp.h"
|
||||||
#include "reg_decl_plugins.h"
|
#include "reg_decl_plugins.h"
|
||||||
#include "theory_pb.h"
|
#include "theory_pb.h"
|
||||||
|
#include "th_rewriter.h"
|
||||||
|
|
||||||
unsigned populate_literals(unsigned k, smt::literal_vector& lits) {
|
unsigned populate_literals(unsigned k, smt::literal_vector& lits) {
|
||||||
SASSERT(k < (1u << lits.size()));
|
SASSERT(k < (1u << lits.size()));
|
||||||
|
@ -19,7 +20,105 @@ unsigned populate_literals(unsigned k, smt::literal_vector& lits) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class pb_fuzzer {
|
||||||
|
ast_manager& m;
|
||||||
|
random_gen rand;
|
||||||
|
smt_params params;
|
||||||
|
smt::context ctx;
|
||||||
|
expr_ref_vector vars;
|
||||||
|
|
||||||
|
public:
|
||||||
|
pb_fuzzer(ast_manager& m): m(m), rand(0), ctx(m, params), vars(m) {
|
||||||
|
params.m_model = true;
|
||||||
|
params.m_pb_enable_simplex = true;
|
||||||
|
unsigned N = 3;
|
||||||
|
for (unsigned i = 0; i < N; ++i) {
|
||||||
|
std::stringstream strm;
|
||||||
|
strm << "b" << i;
|
||||||
|
vars.push_back(m.mk_const(symbol(strm.str().c_str()), m.mk_bool_sort()));
|
||||||
|
std::cout << "(declare-const " << strm.str() << " Bool)\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fuzz() {
|
||||||
|
enable_trace("pb");
|
||||||
|
enable_trace("simplex");
|
||||||
|
unsigned nr = 0;
|
||||||
|
for (unsigned i = 0; i < 100000; ++i) {
|
||||||
|
fuzz_round(nr, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void add_ineq() {
|
||||||
|
pb_util pb(m);
|
||||||
|
expr_ref fml(m), tmp(m);
|
||||||
|
th_rewriter rw(m);
|
||||||
|
vector<rational> coeffs(vars.size());
|
||||||
|
expr_ref_vector args(vars);
|
||||||
|
while (true) {
|
||||||
|
rational k(rand(6));
|
||||||
|
for (unsigned i = 0; i < coeffs.size(); ++i) {
|
||||||
|
int v = 3 - rand(5);
|
||||||
|
coeffs[i] = rational(v);
|
||||||
|
if (coeffs[i].is_neg()) {
|
||||||
|
args[i] = m.mk_not(args[i].get());
|
||||||
|
coeffs[i].neg();
|
||||||
|
k += coeffs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fml = pb.mk_ge(args.size(), coeffs.c_ptr(), args.c_ptr(), k);
|
||||||
|
rw(fml, tmp);
|
||||||
|
rw(tmp, tmp);
|
||||||
|
if (pb.is_ge(tmp)) {
|
||||||
|
fml = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "(assert " << fml << ")\n";
|
||||||
|
ctx.assert_expr(fml);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void fuzz_round(unsigned& num_rounds, unsigned lvl) {
|
||||||
|
unsigned num_rounds2 = 0;
|
||||||
|
lbool is_sat = l_true;
|
||||||
|
std::cout << "(push)\n";
|
||||||
|
ctx.push();
|
||||||
|
unsigned r = 0;
|
||||||
|
while (is_sat == l_true && r <= num_rounds + 1) {
|
||||||
|
add_ineq();
|
||||||
|
std::cout << "(check-sat)\n";
|
||||||
|
is_sat = ctx.check();
|
||||||
|
if (lvl > 0 && is_sat == l_true) {
|
||||||
|
fuzz_round(num_rounds2, lvl-1);
|
||||||
|
}
|
||||||
|
++r;
|
||||||
|
}
|
||||||
|
num_rounds = r;
|
||||||
|
std::cout << "; number of rounds: " << num_rounds << " level: " << lvl << "\n";
|
||||||
|
ctx.pop(1);
|
||||||
|
std::cout << "(pop)\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void fuzz_pb()
|
||||||
|
{
|
||||||
|
ast_manager m;
|
||||||
|
reg_decl_plugins(m);
|
||||||
|
pb_fuzzer fuzzer(m);
|
||||||
|
fuzzer.fuzz();
|
||||||
|
}
|
||||||
|
|
||||||
void tst_theory_pb() {
|
void tst_theory_pb() {
|
||||||
|
|
||||||
|
fuzz_pb();
|
||||||
|
|
||||||
ast_manager m;
|
ast_manager m;
|
||||||
smt_params params;
|
smt_params params;
|
||||||
params.m_model = true;
|
params.m_model = true;
|
||||||
|
|
|
@ -187,7 +187,7 @@ Notes:
|
||||||
else {
|
else {
|
||||||
SASSERT(2*k <= n);
|
SASSERT(2*k <= n);
|
||||||
m_t = full?GE_FULL:GE;
|
m_t = full?GE_FULL:GE;
|
||||||
card(k, n, xs, out);
|
psort_nw<psort_expr>::card(k, n, xs, out);
|
||||||
return out[k-1];
|
return out[k-1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,8 +322,8 @@ Notes:
|
||||||
|
|
||||||
void cmp(literal x1, literal x2, literal y1, literal y2) {
|
void cmp(literal x1, literal x2, literal y1, literal y2) {
|
||||||
switch(m_t) {
|
switch(m_t) {
|
||||||
case LE: cmp_le(x1, x2, y1, y2); break;
|
case LE: case LE_FULL: cmp_le(x1, x2, y1, y2); break;
|
||||||
case GE: cmp_ge(x1, x2, y1, y2); break;
|
case GE: case GE_FULL: cmp_ge(x1, x2, y1, y2); break;
|
||||||
case EQ: cmp_eq(x1, x2, y1, y2); break;
|
case EQ: cmp_eq(x1, x2, y1, y2); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ Notes:
|
||||||
void card(unsigned k, unsigned n, literal const* xs, literal_vector& out) {
|
void card(unsigned k, unsigned n, literal const* xs, literal_vector& out) {
|
||||||
TRACE("pb", tout << "card k:" << k << " n: " << n << "\n";);
|
TRACE("pb", tout << "card k:" << k << " n: " << n << "\n";);
|
||||||
if (n <= k) {
|
if (n <= k) {
|
||||||
sorting(n, xs, out);
|
psort_nw<psort_expr>::sorting(n, xs, out);
|
||||||
}
|
}
|
||||||
else if (use_dcard(k, n)) {
|
else if (use_dcard(k, n)) {
|
||||||
dsorting(k, n, xs, out);
|
dsorting(k, n, xs, out);
|
||||||
|
@ -485,7 +485,7 @@ Notes:
|
||||||
out.push_back(xs[0]);
|
out.push_back(xs[0]);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
merge(1, xs, 1, xs+1, out);
|
psort_nw<psort_expr>::merge(1, xs, 1, xs+1, out);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (use_dsorting(n)) {
|
if (use_dsorting(n)) {
|
||||||
|
|
Loading…
Reference in a new issue