mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 04:03:39 +00:00
deal with compiler warnings and include value exchange prior to final check.
This commit is contained in:
parent
ce615ee116
commit
0e8969ce60
|
@ -428,6 +428,8 @@ namespace sat {
|
||||||
for (unsigned i = 0; i < num_vars(); ++i)
|
for (unsigned i = 0; i < num_vars(); ++i)
|
||||||
m_model[i] = to_lbool(value(i));
|
m_model[i] = to_lbool(value(i));
|
||||||
save_priorities();
|
save_priorities();
|
||||||
|
if (m_plugin && !m_in_external_flip && m_restart_count == 0)
|
||||||
|
m_plugin->on_restart(); // import values if there are any updated ones.
|
||||||
if (m_plugin && !m_in_external_flip)
|
if (m_plugin && !m_in_external_flip)
|
||||||
m_last_result = m_plugin->on_save_model();
|
m_last_result = m_plugin->on_save_model();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,31 +13,13 @@ Author:
|
||||||
|
|
||||||
Nikolaj Bjorner (nbjorner) 2023-02-07
|
Nikolaj Bjorner (nbjorner) 2023-02-07
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
Uses quadratic solver method from nia_ls in hybrid-smt
|
Uses quadratic solver method from nia_ls in hybrid-smt
|
||||||
(with a bug fix for when order of roots are swapped)
|
(with a bug fix for when order of roots are swapped)
|
||||||
Other features from nia_ls are also used as a starting point,
|
Other features from nia_ls are also used as a starting point,
|
||||||
such as tabu and fallbacks.
|
such as tabu and fallbacks.
|
||||||
|
|
||||||
Todo:
|
|
||||||
|
|
||||||
- add fairness for which variable to flip and direction (by age fifo).
|
|
||||||
- maintain age per variable, per sign
|
|
||||||
|
|
||||||
- include more general tabu measure
|
|
||||||
-
|
|
||||||
|
|
||||||
- random walk when there is no applicable update
|
|
||||||
- repair_down can fail repeatedely. Then allow a mode to reset arguments similar to
|
|
||||||
repair of literals.
|
|
||||||
|
|
||||||
- avoid overflow for nested products
|
|
||||||
|
|
||||||
Done:
|
|
||||||
- add tabu for flipping variable back to the same value.
|
|
||||||
- remember last variable/delta and block -delta = last_delta && last_variable = current_variable
|
|
||||||
- include measures for bounded updates
|
|
||||||
- per variable maintain increasing range
|
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
#include "ast/sls/sls_arith_base.h"
|
#include "ast/sls/sls_arith_base.h"
|
||||||
|
@ -1439,6 +1421,20 @@ namespace sls {
|
||||||
}
|
}
|
||||||
for (auto bv : m_tmp_set)
|
for (auto bv : m_tmp_set)
|
||||||
vi.m_bool_vars_of.push_back(bv);
|
vi.m_bool_vars_of.push_back(bv);
|
||||||
|
|
||||||
|
m_tmp_nat_set.reset();
|
||||||
|
m_tmp_nat_set.assure_domain(ctx.clauses().size() + 1);
|
||||||
|
|
||||||
|
for (auto bv : vi.m_bool_vars_of) {
|
||||||
|
for (auto lit : { sat::literal(bv, false), sat::literal(bv, true) }) {
|
||||||
|
for (auto ci : ctx.get_use_list(lit)) {
|
||||||
|
if (m_tmp_nat_set.contains(ci))
|
||||||
|
continue;
|
||||||
|
m_tmp_nat_set.insert(ci);
|
||||||
|
vi.m_clauses_of.push_back(ci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename num_t>
|
template<typename num_t>
|
||||||
|
@ -2435,6 +2431,7 @@ namespace sls {
|
||||||
template<typename num_t>
|
template<typename num_t>
|
||||||
void arith_base<num_t>::collect_statistics(statistics& st) const {
|
void arith_base<num_t>::collect_statistics(statistics& st) const {
|
||||||
st.update("sls-arith-steps", m_stats.m_steps);
|
st.update("sls-arith-steps", m_stats.m_steps);
|
||||||
|
st.update("sls-arith-propagations", m_stats.m_propagations);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename num_t>
|
template<typename num_t>
|
||||||
|
@ -2838,6 +2835,24 @@ namespace sls {
|
||||||
m_fixed_atoms.insert(bv);
|
m_fixed_atoms.insert(bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename num_t>
|
||||||
|
void arith_base<num_t>::add_lookahead(sat::bool_var bv) {
|
||||||
|
auto* ineq = get_ineq(bv);
|
||||||
|
if (!ineq)
|
||||||
|
return;
|
||||||
|
num_t na, nb;
|
||||||
|
for (auto const& [x, nl] : ineq->m_nonlinear) {
|
||||||
|
if (is_fixed(x))
|
||||||
|
continue;
|
||||||
|
if (is_linear(x, nl, nb))
|
||||||
|
find_linear_moves(*ineq, x, nb);
|
||||||
|
else if (is_quadratic(x, nl, na, nb))
|
||||||
|
find_quadratic_moves(*ineq, x, na, nb, ineq->m_args_value);
|
||||||
|
else
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// for every variable e, for every atom containing e
|
// for every variable e, for every atom containing e
|
||||||
// add lookahead for e.
|
// add lookahead for e.
|
||||||
// m_fixable_atoms contains atoms that can be fixed.
|
// m_fixable_atoms contains atoms that can be fixed.
|
||||||
|
@ -3254,6 +3269,7 @@ namespace sls {
|
||||||
|
|
||||||
template<typename num_t>
|
template<typename num_t>
|
||||||
void arith_base<num_t>::start_propagation() {
|
void arith_base<num_t>::start_propagation() {
|
||||||
|
++m_stats.m_propagations;
|
||||||
updt_params();
|
updt_params();
|
||||||
if (m_config.use_clausal_lookahead)
|
if (m_config.use_clausal_lookahead)
|
||||||
m_clausal_sls.search();
|
m_clausal_sls.search();
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace sls {
|
||||||
struct stats {
|
struct stats {
|
||||||
unsigned m_steps = 0;
|
unsigned m_steps = 0;
|
||||||
unsigned m_restarts = 0;
|
unsigned m_restarts = 0;
|
||||||
|
unsigned m_propagations = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -120,6 +121,7 @@ namespace sls {
|
||||||
unsigned m_def_idx = UINT_MAX;
|
unsigned m_def_idx = UINT_MAX;
|
||||||
vector<std::pair<num_t, sat::bool_var>> m_linear_occurs;
|
vector<std::pair<num_t, sat::bool_var>> m_linear_occurs;
|
||||||
sat::bool_var_vector m_bool_vars_of;
|
sat::bool_var_vector m_bool_vars_of;
|
||||||
|
unsigned_vector m_clauses_of;
|
||||||
unsigned_vector m_muls;
|
unsigned_vector m_muls;
|
||||||
unsigned_vector m_adds;
|
unsigned_vector m_adds;
|
||||||
optional<bound> m_lo, m_hi;
|
optional<bound> m_lo, m_hi;
|
||||||
|
@ -216,6 +218,7 @@ namespace sls {
|
||||||
svector<double> m_prob_break;
|
svector<double> m_prob_break;
|
||||||
indexed_uint_set m_bool_var_atoms;
|
indexed_uint_set m_bool_var_atoms;
|
||||||
indexed_uint_set m_tmp_set;
|
indexed_uint_set m_tmp_set;
|
||||||
|
nat_set m_tmp_nat_set;
|
||||||
|
|
||||||
void invariant();
|
void invariant();
|
||||||
void invariant(ineq const& i);
|
void invariant(ineq const& i);
|
||||||
|
@ -381,6 +384,7 @@ namespace sls {
|
||||||
double lookahead(expr* e, bool update_score);
|
double lookahead(expr* e, bool update_score);
|
||||||
void add_lookahead(bool_info& i, expr* e);
|
void add_lookahead(bool_info& i, expr* e);
|
||||||
void add_lookahead(bool_info& i, sat::bool_var bv);
|
void add_lookahead(bool_info& i, sat::bool_var bv);
|
||||||
|
void add_lookahead(sat::bool_var bv);
|
||||||
ptr_vector<expr> const& get_fixable_exprs(expr* e);
|
ptr_vector<expr> const& get_fixable_exprs(expr* e);
|
||||||
bool apply_move(expr* f, ptr_vector<expr> const& vars, arith_move_type t);
|
bool apply_move(expr* f, ptr_vector<expr> const& vars, arith_move_type t);
|
||||||
expr* get_candidate_unsat();
|
expr* get_candidate_unsat();
|
||||||
|
|
|
@ -121,22 +121,14 @@ namespace sls {
|
||||||
template<typename num_t>
|
template<typename num_t>
|
||||||
void arith_clausal<num_t>::add_lookahead_on_unsat_vars() {
|
void arith_clausal<num_t>::add_lookahead_on_unsat_vars() {
|
||||||
a.m_updates.reset();
|
a.m_updates.reset();
|
||||||
a.m_fixed_atoms.reset();
|
|
||||||
TRACE("arith_verbose", tout << "unsat-vars ";
|
TRACE("arith_verbose", tout << "unsat-vars ";
|
||||||
for (auto v : ctx.unsat_vars())
|
for (auto v : ctx.unsat_vars())
|
||||||
if (a.get_ineq(v)) tout << mk_bounded_pp(ctx.atom(v), a.m) << " ";
|
if (a.get_ineq(v)) tout << mk_bounded_pp(ctx.atom(v), a.m) << " ";
|
||||||
tout << "\n";);
|
tout << "\n";);
|
||||||
|
|
||||||
for (auto v : ctx.unsat_vars()) {
|
for (auto v : ctx.unsat_vars())
|
||||||
auto* ineq = a.get_ineq(v);
|
a.add_lookahead(v);
|
||||||
if (!ineq)
|
|
||||||
continue;
|
|
||||||
auto e = ctx.atom(v);
|
|
||||||
auto& i = a.get_bool_info(e);
|
|
||||||
auto const& vars = a.get_fixable_exprs(e);
|
|
||||||
for (auto v : vars)
|
|
||||||
a.add_lookahead(i, v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,7 +138,6 @@ namespace sls {
|
||||||
template<typename num_t>
|
template<typename num_t>
|
||||||
void arith_clausal<num_t>::add_lookahead_on_false_literals() {
|
void arith_clausal<num_t>::add_lookahead_on_false_literals() {
|
||||||
a.m_updates.reset();
|
a.m_updates.reset();
|
||||||
a.m_fixed_atoms.reset();
|
|
||||||
|
|
||||||
unsigned sz = a.m_bool_var_atoms.size();
|
unsigned sz = a.m_bool_var_atoms.size();
|
||||||
bool is_big = sz > 45u;
|
bool is_big = sz > 45u;
|
||||||
|
@ -164,47 +155,25 @@ namespace sls {
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
//unsigned num_sampled = 0;
|
if (is_big) {
|
||||||
for (unsigned i = std::min(sz, 45u); i-- > 0;) {
|
for (unsigned i = 45, j = 90; j-- > 0 && i-- > 0 && sz > 0;) {
|
||||||
if (is_big) {
|
|
||||||
idx = ctx.rand(sz);
|
idx = ctx.rand(sz);
|
||||||
bv = a.m_bool_var_atoms[idx];
|
bv = a.m_bool_var_atoms[idx];
|
||||||
}
|
|
||||||
else
|
|
||||||
bv = a.m_bool_var_atoms[i];
|
|
||||||
|
|
||||||
if (occurs_negative(bv)) {
|
|
||||||
auto e = ctx.atom(bv);
|
|
||||||
auto& i = a.get_bool_info(e);
|
|
||||||
a.add_lookahead(i, bv);
|
|
||||||
//++num_sampled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_big) {
|
|
||||||
--sz;
|
--sz;
|
||||||
a.m_bool_var_atoms.swap_elems(idx, sz);
|
a.m_bool_var_atoms.swap_elems(idx, sz);
|
||||||
|
if (occurs_negative(bv))
|
||||||
|
a.add_lookahead(bv);
|
||||||
|
else
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
#if 0
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
for (auto bv : a.m_bool_var_atoms) {
|
bv = a.m_bool_var_atoms[i];
|
||||||
if (ctx.unsat_vars().contains(bv))
|
if (occurs_negative(bv))
|
||||||
continue;
|
a.add_lookahead(bv);
|
||||||
auto* ineq = a.get_ineq(bv);
|
}
|
||||||
if (!ineq)
|
|
||||||
continue;
|
|
||||||
sat::literal lit(bv, !ineq->is_true());
|
|
||||||
auto const& ul = ctx.get_use_list(~lit);
|
|
||||||
if (ul.begin() == ul.end())
|
|
||||||
continue;
|
|
||||||
// literal is false in some clause but none of the clauses where it occurs false are unsat.
|
|
||||||
|
|
||||||
auto e = ctx.atom(bv);
|
|
||||||
auto& i = a.get_bool_info(e);
|
|
||||||
|
|
||||||
a.add_lookahead(i, bv);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename num_t>
|
template<typename num_t>
|
||||||
|
@ -300,50 +269,38 @@ namespace sls {
|
||||||
if (!a.update_num(v, delta))
|
if (!a.update_num(v, delta))
|
||||||
return -1;
|
return -1;
|
||||||
double score = 0;
|
double score = 0;
|
||||||
m_tmp_nat_set.reset();
|
for (auto ci : vi.m_clauses_of) {
|
||||||
m_tmp_nat_set.assure_domain(ctx.clauses().size() + 1);
|
auto const& c = ctx.get_clause(ci);
|
||||||
for (auto bv : vi.m_bool_vars_of) {
|
unsigned num_true = 0;
|
||||||
for (auto lit : { sat::literal(bv, false), sat::literal(bv, true) }) {
|
for (auto lit : c) {
|
||||||
for (auto ci : ctx.get_use_list(lit)) {
|
auto bv = lit.var();
|
||||||
if (m_tmp_nat_set.contains(ci)) {
|
auto ineq = a.get_ineq(bv);
|
||||||
continue;
|
if (ineq) {
|
||||||
}
|
if (ineq->is_true() != lit.sign())
|
||||||
m_tmp_nat_set.insert(ci);
|
++num_true;
|
||||||
|
|
||||||
auto const& c = ctx.get_clause(ci);
|
|
||||||
unsigned num_true = 0;
|
|
||||||
for (auto lit : c) {
|
|
||||||
auto bv = lit.var();
|
|
||||||
auto ineq = a.get_ineq(bv);
|
|
||||||
if (ineq) {
|
|
||||||
if (ineq->is_true() != lit.sign())
|
|
||||||
++num_true;
|
|
||||||
}
|
|
||||||
else if (ctx.is_true(lit))
|
|
||||||
++num_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CTRACE("arith_verbose", c.m_num_trues != num_true && (c.m_num_trues == 0 || num_true == 0),
|
|
||||||
tout << "clause: " << c
|
|
||||||
<< " v" << v << " += " << delta
|
|
||||||
<< " new-true lits: " << num_true
|
|
||||||
<< " old-true lits: " << c.m_num_trues
|
|
||||||
<< " w: " << c.m_weight << "\n";
|
|
||||||
for (auto lit : c)
|
|
||||||
if (a.get_ineq(lit.var()))
|
|
||||||
tout << lit << " " << *a.get_ineq(lit.var()) << "\n";);
|
|
||||||
if (c.m_num_trues > 0 && num_true == 0)
|
|
||||||
score -= c.m_weight;
|
|
||||||
else if (c.m_num_trues == 0 && num_true > 0)
|
|
||||||
score += c.m_weight;
|
|
||||||
}
|
}
|
||||||
|
else if (ctx.is_true(lit))
|
||||||
|
++num_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTRACE("arith_verbose", c.m_num_trues != num_true && (c.m_num_trues == 0 || num_true == 0),
|
||||||
|
tout << "clause: " << c
|
||||||
|
<< " v" << v << " += " << delta
|
||||||
|
<< " new-true lits: " << num_true
|
||||||
|
<< " old-true lits: " << c.m_num_trues
|
||||||
|
<< " w: " << c.m_weight << "\n";
|
||||||
|
for (auto lit : c)
|
||||||
|
if (a.get_ineq(lit.var()))
|
||||||
|
tout << lit << " " << *a.get_ineq(lit.var()) << "\n";);
|
||||||
|
if (c.m_num_trues > 0 && num_true == 0)
|
||||||
|
score -= c.m_weight;
|
||||||
|
else if (c.m_num_trues == 0 && num_true > 0)
|
||||||
|
score += c.m_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verbose_stream() << num_clauses << " " << num_dup << "\n";
|
||||||
// revert the update
|
// revert the update
|
||||||
a.update_args_value(v, vi.value() - delta);
|
a.update_args_value(v, vi.value() - delta);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,6 @@ namespace sls {
|
||||||
unsigned m_best_last_step = 0;
|
unsigned m_best_last_step = 0;
|
||||||
unsigned m_num_lookaheads = 0;
|
unsigned m_num_lookaheads = 0;
|
||||||
|
|
||||||
nat_set m_tmp_nat_set;
|
|
||||||
|
|
||||||
// avoid checking the same updates twice
|
// avoid checking the same updates twice
|
||||||
var_t m_last_var = UINT_MAX;
|
var_t m_last_var = UINT_MAX;
|
||||||
num_t m_last_delta;
|
num_t m_last_delta;
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref basic_plugin::eval_ite(app* e) {
|
expr_ref basic_plugin::eval_ite(app* e) {
|
||||||
expr* c, * th, * el;
|
expr* c = nullptr, * th = nullptr, * el = nullptr;
|
||||||
VERIFY(m.is_ite(e, c, th, el));
|
VERIFY(m.is_ite(e, c, th, el));
|
||||||
if (bval0(c))
|
if (bval0(c))
|
||||||
return ctx.get_value(th);
|
return ctx.get_value(th);
|
||||||
|
|
|
@ -396,13 +396,12 @@ double sls_engine::find_best_move_mc(ptr_vector<func_decl> & to_evaluate, double
|
||||||
// main search loop
|
// main search loop
|
||||||
lbool sls_engine::search() {
|
lbool sls_engine::search() {
|
||||||
lbool res = l_undef;
|
lbool res = l_undef;
|
||||||
double score = 0.0, old_score = 0.0;
|
double score = 0.0;
|
||||||
unsigned new_const = (unsigned)-1, new_bit;
|
unsigned new_const = (unsigned)-1, new_bit;
|
||||||
mpz new_value;
|
mpz new_value;
|
||||||
move_type move;
|
move_type move;
|
||||||
|
|
||||||
score = rescore();
|
score = rescore();
|
||||||
unsigned sz = m_assertions.size();
|
|
||||||
|
|
||||||
while (check_restart(m_stats.m_moves)) {
|
while (check_restart(m_stats.m_moves)) {
|
||||||
if (!m_manager.inc())
|
if (!m_manager.inc())
|
||||||
|
@ -435,7 +434,6 @@ lbool sls_engine::search() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_score = score;
|
|
||||||
new_const = (unsigned)-1;
|
new_const = (unsigned)-1;
|
||||||
|
|
||||||
// find best increasing move
|
// find best increasing move
|
||||||
|
|
|
@ -986,7 +986,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bv_eval::fold_oper(bvect& out, app* t, unsigned i, std::function<void(bvect&, bvval const&)> const& f) {
|
void bv_eval::fold_oper(bvect& out, app* t, unsigned i, std::function<void(bvect&, bvval const&)> const& f) {
|
||||||
auto i2 = i == 0 ? 1 : 0;
|
unsigned i2 = i == 0 ? 1 : 0;
|
||||||
auto const& c = wval(t->get_arg(i2));
|
auto const& c = wval(t->get_arg(i2));
|
||||||
for (unsigned j = 0; j < c.nw; ++j)
|
for (unsigned j = 0; j < c.nw; ++j)
|
||||||
out[j] = c.bits()[j];
|
out[j] = c.bits()[j];
|
||||||
|
@ -1242,8 +1242,6 @@ namespace sls {
|
||||||
bool bv_eval::try_repair_sdiv(bvect const& e, bvval& a, bvval& b, unsigned i) {
|
bool bv_eval::try_repair_sdiv(bvect const& e, bvval& a, bvval& b, unsigned i) {
|
||||||
|
|
||||||
bool sign_a = a.sign();
|
bool sign_a = a.sign();
|
||||||
bool sign_b = b.sign();
|
|
||||||
bool sign_e = e.get(a.bw - 1);
|
|
||||||
|
|
||||||
// y = 0, x >= 0 -> -1
|
// y = 0, x >= 0 -> -1
|
||||||
if (i == 0 && b.is_zero() && a.is_ones(e) && a.try_set(m_zero))
|
if (i == 0 && b.is_zero() && a.is_ones(e) && a.try_set(m_zero))
|
||||||
|
|
|
@ -676,7 +676,6 @@ namespace sls {
|
||||||
for (unsigned i = 0; i < m_update_stack[depth].size(); ++i) {
|
for (unsigned i = 0; i < m_update_stack[depth].size(); ++i) {
|
||||||
auto [e, is_bv] = m_update_stack[depth][i];
|
auto [e, is_bv] = m_update_stack[depth][i];
|
||||||
TRACE("bv_verbose", tout << "update " << mk_bounded_pp(e, m) << "\n";);
|
TRACE("bv_verbose", tout << "update " << mk_bounded_pp(e, m) << "\n";);
|
||||||
bool old_truth = false;
|
|
||||||
if (t == e)
|
if (t == e)
|
||||||
;
|
;
|
||||||
else if (is_bv) {
|
else if (is_bv) {
|
||||||
|
@ -684,7 +683,6 @@ namespace sls {
|
||||||
wval(e).commit_eval_ignore_tabu();
|
wval(e).commit_eval_ignore_tabu();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
old_truth = m_ev.get_bool_value(e);
|
|
||||||
SASSERT(m.is_bool(e));
|
SASSERT(m.is_bool(e));
|
||||||
auto v1 = m_ev.bval1(e);
|
auto v1 = m_ev.bval1(e);
|
||||||
|
|
||||||
|
|
|
@ -197,8 +197,6 @@ namespace sls {
|
||||||
g.mk(m.mk_true(), 0, 0, nullptr);
|
g.mk(m.mk_true(), 0, 0, nullptr);
|
||||||
if (!g.find(m.mk_false()))
|
if (!g.find(m.mk_false()))
|
||||||
g.mk(m.mk_false(), 0, 0, nullptr);
|
g.mk(m.mk_false(), 0, 0, nullptr);
|
||||||
|
|
||||||
// merge all equalities
|
|
||||||
// check for conflict with disequalities during propagation
|
// check for conflict with disequalities during propagation
|
||||||
if (merge_eqs) {
|
if (merge_eqs) {
|
||||||
TRACE("euf", tout << "root literals " << ctx.root_literals() << "\n");
|
TRACE("euf", tout << "root literals " << ctx.root_literals() << "\n");
|
||||||
|
@ -279,7 +277,7 @@ namespace sls {
|
||||||
void euf_plugin::validate_model() {
|
void euf_plugin::validate_model() {
|
||||||
auto& g = *m_g;
|
auto& g = *m_g;
|
||||||
for (auto lit : ctx.root_literals()) {
|
for (auto lit : ctx.root_literals()) {
|
||||||
euf::enode* a, * b;
|
euf::enode* a = nullptr, * b = nullptr;
|
||||||
if (!ctx.is_true(lit))
|
if (!ctx.is_true(lit))
|
||||||
continue;
|
continue;
|
||||||
auto e = ctx.atom(lit.var());
|
auto e = ctx.atom(lit.var());
|
||||||
|
|
|
@ -276,7 +276,7 @@ namespace sls {
|
||||||
ptr_vector<expr> const& seq_plugin::lhs(expr* eq) {
|
ptr_vector<expr> const& seq_plugin::lhs(expr* eq) {
|
||||||
auto& ev = get_eval(eq);
|
auto& ev = get_eval(eq);
|
||||||
if (ev.lhs.empty()) {
|
if (ev.lhs.empty()) {
|
||||||
expr* x, * y;
|
expr* x = nullptr, * y = nullptr;
|
||||||
VERIFY(m.is_eq(eq, x, y));
|
VERIFY(m.is_eq(eq, x, y));
|
||||||
seq.str.get_concat(x, ev.lhs);
|
seq.str.get_concat(x, ev.lhs);
|
||||||
seq.str.get_concat(y, ev.rhs);
|
seq.str.get_concat(y, ev.rhs);
|
||||||
|
@ -332,7 +332,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::bval1_seq(app* e) {
|
bool seq_plugin::bval1_seq(app* e) {
|
||||||
expr* a, *b;
|
expr* a = nullptr, *b = nullptr;
|
||||||
SASSERT(e->get_family_id() == seq.get_family_id());
|
SASSERT(e->get_family_id() == seq.get_family_id());
|
||||||
switch (e->get_decl_kind()) {
|
switch (e->get_decl_kind()) {
|
||||||
case OP_SEQ_CONTAINS:
|
case OP_SEQ_CONTAINS:
|
||||||
|
@ -433,7 +433,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case OP_SEQ_AT: {
|
case OP_SEQ_AT: {
|
||||||
expr* x, * offset;
|
expr* x = nullptr, * offset = nullptr;
|
||||||
VERIFY(seq.str.is_at(e, x, offset));
|
VERIFY(seq.str.is_at(e, x, offset));
|
||||||
zstring r = strval0(x);
|
zstring r = strval0(x);
|
||||||
expr_ref offset_e = ctx.get_value(offset);
|
expr_ref offset_e = ctx.get_value(offset);
|
||||||
|
@ -613,14 +613,14 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
void seq_plugin::repair_up_str_length(app* e) {
|
void seq_plugin::repair_up_str_length(app* e) {
|
||||||
expr* x;
|
expr* x = nullptr;
|
||||||
VERIFY(seq.str.is_length(e, x));
|
VERIFY(seq.str.is_length(e, x));
|
||||||
zstring val_x = strval0(x);
|
zstring val_x = strval0(x);
|
||||||
update(e, rational(val_x.length()));
|
update(e, rational(val_x.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void seq_plugin::repair_up_str_indexof(app* e) {
|
void seq_plugin::repair_up_str_indexof(app* e) {
|
||||||
expr* x, * y, * z = nullptr;
|
expr* x = nullptr, * y = nullptr, * z = nullptr;
|
||||||
VERIFY(seq.str.is_index(e, x, y, z) || seq.str.is_index(e, x, y));
|
VERIFY(seq.str.is_index(e, x, y, z) || seq.str.is_index(e, x, y));
|
||||||
zstring val_x = strval0(x);
|
zstring val_x = strval0(x);
|
||||||
zstring val_y = strval0(y);
|
zstring val_y = strval0(y);
|
||||||
|
@ -801,6 +801,7 @@ namespace sls {
|
||||||
index -= len_x;
|
index -= len_x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
unsigned last_diff = 0;
|
unsigned last_diff = 0;
|
||||||
for (unsigned i = 1; i <= val.length() && i <= val_other.length(); ++i) {
|
for (unsigned i = 1; i <= val.length() && i <= val_other.length(); ++i) {
|
||||||
if (val[val.length() - i] != val_other[val_other.length() - i]) {
|
if (val[val.length() - i] != val_other[val_other.length() - i]) {
|
||||||
|
@ -809,7 +810,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (last_diff != 0) {
|
if (last_diff != 0) {
|
||||||
unsigned index = last_diff;
|
unsigned index = last_diff;
|
||||||
for (auto x : w) {
|
for (auto x : w) {
|
||||||
|
@ -1273,7 +1274,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_replace(app* e) {
|
bool seq_plugin::repair_down_str_replace(app* e) {
|
||||||
expr* x, * y, * z;
|
expr* x = nullptr, * y = nullptr, * z = nullptr;
|
||||||
VERIFY(seq.str.is_replace(e, x, y, z));
|
VERIFY(seq.str.is_replace(e, x, y, z));
|
||||||
zstring r = strval0(e);
|
zstring r = strval0(e);
|
||||||
if (r == strval1(e))
|
if (r == strval1(e))
|
||||||
|
@ -1293,7 +1294,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_itos(app* e) {
|
bool seq_plugin::repair_down_str_itos(app* e) {
|
||||||
expr* x;
|
expr* x = nullptr;
|
||||||
VERIFY(seq.str.is_itos(e, x));
|
VERIFY(seq.str.is_itos(e, x));
|
||||||
zstring se = strval0(e);
|
zstring se = strval0(e);
|
||||||
rational r(se.encode().c_str());
|
rational r(se.encode().c_str());
|
||||||
|
@ -1305,7 +1306,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_stoi(app* e) {
|
bool seq_plugin::repair_down_str_stoi(app* e) {
|
||||||
expr* x;
|
expr* x = nullptr;
|
||||||
rational r;
|
rational r;
|
||||||
VERIFY(seq.str.is_stoi(e, x));
|
VERIFY(seq.str.is_stoi(e, x));
|
||||||
VERIFY(a.is_numeral(ctx.get_value(e), r) && r.is_int());
|
VERIFY(a.is_numeral(ctx.get_value(e), r) && r.is_int());
|
||||||
|
@ -1330,7 +1331,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_at(app* e) {
|
bool seq_plugin::repair_down_str_at(app* e) {
|
||||||
expr* x, * y;
|
expr* x = nullptr, * y = nullptr;
|
||||||
VERIFY(seq.str.is_at(e, x, y));
|
VERIFY(seq.str.is_at(e, x, y));
|
||||||
zstring se = strval0(e);
|
zstring se = strval0(e);
|
||||||
// std::cout << "repair-str-at: " << mk_pp(e, m) << ": \"" << se << "\"" << std::endl;
|
// std::cout << "repair-str-at: " << mk_pp(e, m) << ": \"" << se << "\"" << std::endl;
|
||||||
|
@ -1387,7 +1388,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_indexof(app* e) {
|
bool seq_plugin::repair_down_str_indexof(app* e) {
|
||||||
expr* x, * y, * offset = nullptr;
|
expr* x = nullptr, * y = nullptr, * offset = nullptr;
|
||||||
VERIFY(seq.str.is_index(e, x, y, offset) || seq.str.is_index(e, x, y));
|
VERIFY(seq.str.is_index(e, x, y, offset) || seq.str.is_index(e, x, y));
|
||||||
rational value;
|
rational value;
|
||||||
VERIFY(a.is_numeral(ctx.get_value(e), value) && value.is_int());
|
VERIFY(a.is_numeral(ctx.get_value(e), value) && value.is_int());
|
||||||
|
@ -1437,7 +1438,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_prefixof(app* e) {
|
bool seq_plugin::repair_down_str_prefixof(app* e) {
|
||||||
expr* a, * b;
|
expr* a = nullptr, * b = nullptr;
|
||||||
VERIFY(seq.str.is_prefix(e, a, b));
|
VERIFY(seq.str.is_prefix(e, a, b));
|
||||||
zstring sa = strval0(a);
|
zstring sa = strval0(a);
|
||||||
zstring sb = strval0(b);
|
zstring sb = strval0(b);
|
||||||
|
@ -1475,7 +1476,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_suffixof(app* e) {
|
bool seq_plugin::repair_down_str_suffixof(app* e) {
|
||||||
expr* a, * b;
|
expr* a = nullptr, * b = nullptr;
|
||||||
VERIFY(seq.str.is_suffix(e, a, b));
|
VERIFY(seq.str.is_suffix(e, a, b));
|
||||||
zstring sa = strval0(a);
|
zstring sa = strval0(a);
|
||||||
zstring sb = strval0(b);
|
zstring sb = strval0(b);
|
||||||
|
@ -1513,7 +1514,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_contains(expr* e) {
|
bool seq_plugin::repair_down_str_contains(expr* e) {
|
||||||
expr* a, *b;
|
expr* a = nullptr, *b = nullptr;
|
||||||
VERIFY(seq.str.is_contains(e, a, b));
|
VERIFY(seq.str.is_contains(e, a, b));
|
||||||
zstring sa = strval0(a);
|
zstring sa = strval0(a);
|
||||||
zstring sb = strval0(b);
|
zstring sb = strval0(b);
|
||||||
|
@ -1568,7 +1569,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_str_extract(app* e) {
|
bool seq_plugin::repair_down_str_extract(app* e) {
|
||||||
expr* x, * offset, * len;
|
expr* x = nullptr, * offset = nullptr, * len = nullptr;
|
||||||
VERIFY(seq.str.is_extract(e, x, offset, len));
|
VERIFY(seq.str.is_extract(e, x, offset, len));
|
||||||
SASSERT(strval0(e) != strval1(e));
|
SASSERT(strval0(e) != strval1(e));
|
||||||
zstring v = strval0(e);
|
zstring v = strval0(e);
|
||||||
|
@ -1832,7 +1833,7 @@ namespace sls {
|
||||||
auto& ev = get_eval(t);
|
auto& ev = get_eval(t);
|
||||||
ev.max_length = 1;
|
ev.max_length = 1;
|
||||||
}
|
}
|
||||||
expr* x, * offset, * len;
|
expr* x = nullptr, * offset = nullptr, * len = nullptr;
|
||||||
rational len_r;
|
rational len_r;
|
||||||
if (seq.str.is_extract(t, x, offset, len) && a.is_numeral(len, len_r)) {
|
if (seq.str.is_extract(t, x, offset, len) && a.is_numeral(len, len_r)) {
|
||||||
auto& ev = get_eval(t);
|
auto& ev = get_eval(t);
|
||||||
|
@ -1855,7 +1856,6 @@ namespace sls {
|
||||||
auto e = ctx.atom(lit.var());
|
auto e = ctx.atom(lit.var());
|
||||||
if (!is_seq_predicate(e))
|
if (!is_seq_predicate(e))
|
||||||
return;
|
return;
|
||||||
auto a = to_app(e);
|
|
||||||
if (bval1(e) == lit.sign())
|
if (bval1(e) == lit.sign())
|
||||||
ctx.flip(lit.var());
|
ctx.flip(lit.var());
|
||||||
}
|
}
|
||||||
|
@ -1890,7 +1890,7 @@ namespace sls {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool seq_plugin::repair_down_in_re(app* e) {
|
bool seq_plugin::repair_down_in_re(app* e) {
|
||||||
expr* x, * y;
|
expr* x = nullptr, * y = nullptr;
|
||||||
VERIFY(seq.str.is_in_re(e, x, y));
|
VERIFY(seq.str.is_in_re(e, x, y));
|
||||||
auto info = seq.re.get_info(y);
|
auto info = seq.re.get_info(y);
|
||||||
if (!info.interpreted)
|
if (!info.interpreted)
|
||||||
|
|
|
@ -212,7 +212,7 @@ namespace sls {
|
||||||
m_sat_phase[v] = ctx.get_best_phase(v);
|
m_sat_phase[v] = ctx.get_best_phase(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smt_plugin::export_to_sls() {
|
bool smt_plugin::export_to_sls() {
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
if (m_has_units) {
|
if (m_has_units) {
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
|
@ -132,7 +132,7 @@ static bool parse_dimacs_core(Buffer & in, std::ostream& err, sat::solver & solv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (dimacs::lex_error) {
|
catch (dimacs::lex_error& ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -280,7 +280,7 @@ namespace dimacs {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (lex_error) {
|
catch (dimacs::lex_error&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,13 +103,14 @@ namespace smt {
|
||||||
m_smt_plugin->check(fmls, clauses);
|
m_smt_plugin->check(fmls, clauses);
|
||||||
m_smt_plugin->get_shared_clauses(m_shared_clauses);
|
m_smt_plugin->get_shared_clauses(m_shared_clauses);
|
||||||
}
|
}
|
||||||
else if (!m_parallel_mode)
|
else if (m_parallel_mode && m_smt_plugin->completed()) {
|
||||||
propagate_local_search();
|
|
||||||
else if (m_smt_plugin->completed()) {
|
|
||||||
m_smt_plugin->finalize(m_model, m_st);
|
m_smt_plugin->finalize(m_model, m_st);
|
||||||
m_smt_plugin = nullptr;
|
m_smt_plugin = nullptr;
|
||||||
m_init_search = false;
|
m_init_search = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
propagate_local_search();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_sls::pop_scope_eh(unsigned n) {
|
void theory_sls::pop_scope_eh(unsigned n) {
|
||||||
|
@ -152,17 +153,29 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void theory_sls::update_propagation_scope() {
|
||||||
|
if (m_propagation_scope > ctx.get_scope_level() && m_propagation_scope == m_max_propagation_scope) {
|
||||||
|
m_smt_plugin->smt_values_to_sls();
|
||||||
|
}
|
||||||
|
m_propagation_scope = ctx.get_scope_level();
|
||||||
|
m_max_propagation_scope = std::max(m_max_propagation_scope, m_propagation_scope);
|
||||||
|
}
|
||||||
|
|
||||||
void theory_sls::propagate_local_search() {
|
void theory_sls::propagate_local_search() {
|
||||||
if (!m_has_unassigned_clause_after_resolve)
|
if (!m_has_unassigned_clause_after_resolve)
|
||||||
return;
|
return;
|
||||||
if (m_parallel_mode || !m_smt_plugin)
|
if (!m_smt_plugin)
|
||||||
return;
|
return;
|
||||||
++m_after_resolve_decide_count;
|
++m_after_resolve_decide_count;
|
||||||
if (100 + m_after_resolve_decide_gap > m_after_resolve_decide_count)
|
if (100 + m_after_resolve_decide_gap > m_after_resolve_decide_count) {
|
||||||
|
//update_propagation_scope();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
m_after_resolve_decide_gap *= 2;
|
m_after_resolve_decide_gap *= 2;
|
||||||
if (!shared_clauses_are_true())
|
if (!shared_clauses_are_true()) {
|
||||||
|
update_propagation_scope();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
m_resolve_count = 0;
|
m_resolve_count = 0;
|
||||||
m_has_unassigned_clause_after_resolve = false;
|
m_has_unassigned_clause_after_resolve = false;
|
||||||
run_guided_sls();
|
run_guided_sls();
|
||||||
|
|
|
@ -73,6 +73,8 @@ namespace smt {
|
||||||
unsigned m_after_resolve_decide_count = 0;
|
unsigned m_after_resolve_decide_count = 0;
|
||||||
unsigned m_resolve_count = 0;
|
unsigned m_resolve_count = 0;
|
||||||
unsigned m_resolve_gap = 0;
|
unsigned m_resolve_gap = 0;
|
||||||
|
unsigned m_max_propagation_scope = 0;
|
||||||
|
unsigned m_propagation_scope = 0;
|
||||||
mutable bool m_init_search = false;
|
mutable bool m_init_search = false;
|
||||||
mutable ::statistics m_st;
|
mutable ::statistics m_st;
|
||||||
vector<sat::literal_vector> m_shared_clauses;
|
vector<sat::literal_vector> m_shared_clauses;
|
||||||
|
@ -95,6 +97,8 @@ namespace smt {
|
||||||
void run_guided_sls();
|
void run_guided_sls();
|
||||||
void finalize() const;
|
void finalize() const;
|
||||||
|
|
||||||
|
void update_propagation_scope();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
theory_sls(context& ctx);
|
theory_sls(context& ctx);
|
||||||
~theory_sls() override;
|
~theory_sls() override;
|
||||||
|
|
Loading…
Reference in a new issue