mirror of
https://github.com/Z3Prover/z3
synced 2025-08-23 11:37:54 +00:00
adding arith sls
This commit is contained in:
parent
6a2d60a6ba
commit
96d815b904
17 changed files with 625 additions and 35 deletions
|
@ -78,12 +78,7 @@ namespace arith {
|
|||
m_eq_tail++;
|
||||
}
|
||||
public:
|
||||
void set_type(euf::solver& ctx, hint_type ty) {
|
||||
ctx.push(value_trail<unsigned>(m_eq_tail));
|
||||
ctx.push(value_trail<unsigned>(m_lit_tail));
|
||||
m_ty = ty;
|
||||
reset();
|
||||
}
|
||||
void set_type(euf::solver& ctx, hint_type ty);
|
||||
void set_num_le(unsigned n) { m_num_le = n; }
|
||||
void add_eq(euf::enode* a, euf::enode* b) { add(a, b, true); }
|
||||
void add_diseq(euf::enode* a, euf::enode* b) { add(a, b, false); }
|
||||
|
@ -96,12 +91,9 @@ namespace arith {
|
|||
}
|
||||
std::pair<rational, literal> const& lit(unsigned i) const { return m_literals[i]; }
|
||||
std::tuple<enode*, enode*, bool> const& eq(unsigned i) const { return m_eqs[i]; }
|
||||
arith_proof_hint* mk(euf::solver& s) {
|
||||
return new (s.get_region()) arith_proof_hint(m_ty, m_num_le, m_lit_head, m_lit_tail, m_eq_head, m_eq_tail);
|
||||
}
|
||||
arith_proof_hint* mk(euf::solver& s);
|
||||
};
|
||||
|
||||
|
||||
class solver : public euf::th_euf_solver {
|
||||
|
||||
friend struct arith_proof_hint;
|
||||
|
@ -144,7 +136,7 @@ namespace arith {
|
|||
};
|
||||
int_hashtable<var_value_hash, var_value_eq> m_model_eqs;
|
||||
|
||||
bool m_new_eq { false };
|
||||
bool m_new_eq = false;
|
||||
|
||||
|
||||
// temporary values kept during internalization
|
||||
|
@ -198,6 +190,85 @@ namespace arith {
|
|||
}
|
||||
};
|
||||
|
||||
// local search portion for arithmetic
|
||||
class sls {
|
||||
enum class ineq_kind { EQ, LE, LT, NE };
|
||||
enum class var_kind { INT, REAL };
|
||||
typedef unsigned var_t;
|
||||
typedef unsigned atom_t;
|
||||
|
||||
struct stats {
|
||||
unsigned m_num_flips = 0;
|
||||
};
|
||||
// encode args <= bound, args = bound, args < bound
|
||||
struct ineq {
|
||||
vector<std::pair<rational, var_t>> m_args;
|
||||
ineq_kind m_op = ineq_kind::LE;
|
||||
rational m_bound;
|
||||
rational m_args_value;
|
||||
|
||||
bool is_true() const {
|
||||
switch (m_op) {
|
||||
case ineq_kind::LE:
|
||||
return m_args_value <= m_bound;
|
||||
case ineq_kind::EQ:
|
||||
return m_args_value == m_bound;
|
||||
case ineq_kind::NE:
|
||||
return m_args_value != m_bound;
|
||||
default:
|
||||
return m_args_value < m_bound;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct var_info {
|
||||
rational m_value;
|
||||
rational m_best_value;
|
||||
var_kind m_kind = var_kind::INT;
|
||||
vector<std::pair<rational, atom_t>> m_atoms;
|
||||
};
|
||||
|
||||
struct atom_info {
|
||||
ineq m_ineq;
|
||||
unsigned m_clause_idx;
|
||||
bool m_is_bool = false;
|
||||
bool m_phase = false;
|
||||
bool m_best_phase = false;
|
||||
unsigned m_breaks = 0;
|
||||
};
|
||||
|
||||
solver& s;
|
||||
ast_manager& m;
|
||||
unsigned m_max_arith_steps = 0;
|
||||
stats m_stats;
|
||||
vector<atom_info> m_atoms;
|
||||
vector<var_info> m_vars;
|
||||
|
||||
bool flip();
|
||||
void log() {}
|
||||
bool flip_unsat() { return false; }
|
||||
bool flip_clauses() { return false; }
|
||||
bool flip_dscore() { return false; }
|
||||
// bool flip_dscore(clause const&);
|
||||
// bool flip(clause const&);
|
||||
rational dtt(ineq const& ineq) const { return dtt(ineq.m_args_value, ineq); }
|
||||
rational dtt(rational const& args, ineq const& ineq) const;
|
||||
rational dtt(ineq const& ineq, var_t v, rational const& new_value) const;
|
||||
// rational dts(clause const& cl, var_t v, rational const& new_value) const;
|
||||
// rational dts(clause const& cl) const;
|
||||
bool cm(ineq const& ineq, var_t v, rational& new_value);
|
||||
|
||||
rational value(var_t v) const { return m_vars[v].m_value; }
|
||||
public:
|
||||
sls(solver& s);
|
||||
void operator ()(bool_vector& phase);
|
||||
void set_bounds_begin();
|
||||
void set_bounds_end(unsigned num_literals);
|
||||
void set_bounds(enode* n);
|
||||
};
|
||||
|
||||
sls m_local_search;
|
||||
|
||||
typedef vector<std::pair<rational, lpvar>> var_coeffs;
|
||||
vector<rational> m_columns;
|
||||
var_coeffs m_left_side; // constraint left side
|
||||
|
@ -233,10 +304,10 @@ namespace arith {
|
|||
unsigned m_asserted_qhead = 0;
|
||||
|
||||
svector<std::pair<theory_var, theory_var> > m_assume_eq_candidates;
|
||||
unsigned m_assume_eq_head{ 0 };
|
||||
unsigned m_assume_eq_head = 0;
|
||||
lp::u_set m_tmp_var_set;
|
||||
|
||||
unsigned m_num_conflicts{ 0 };
|
||||
unsigned m_num_conflicts = 0;
|
||||
lp_api::stats m_stats;
|
||||
svector<scope> m_scopes;
|
||||
|
||||
|
@ -515,6 +586,11 @@ namespace arith {
|
|||
bool enable_ackerman_axioms(euf::enode* n) const override { return !a.is_add(n->get_expr()); }
|
||||
bool has_unhandled() const override { return m_not_handled != nullptr; }
|
||||
|
||||
void set_bounds_begin() override { m_local_search.set_bounds_begin(); }
|
||||
void set_bounds_end(unsigned num_literals) override { m_local_search.set_bounds_end(num_literals); }
|
||||
void set_bounds(enode* n) override { m_local_search.set_bounds(n); }
|
||||
void local_search(bool_vector& phase) override { m_local_search(phase); }
|
||||
|
||||
// bounds and equality propagation callbacks
|
||||
lp::lar_solver& lp() { return *m_solver; }
|
||||
lp::lar_solver const& lp() const { return *m_solver; }
|
||||
|
@ -523,4 +599,7 @@ namespace arith {
|
|||
void consume(rational const& v, lp::constraint_index j);
|
||||
bool bound_is_interesting(unsigned vi, lp::lconstraint_kind kind, const rational& bval) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue