3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-22 11:07:51 +00:00

integrating int-blaster

This commit is contained in:
Nikolaj Bjorner 2023-12-10 19:55:25 -08:00
parent d72938ba9a
commit a5491804c7
13 changed files with 209 additions and 69 deletions

View file

@ -1,4 +1,4 @@
/*++
/*++
Copyright (c) 2021 Microsoft Corporation
Module Name:
@ -12,6 +12,7 @@ Author:
--*/
#include "util/log.h"
#include "sat/smt/polysat/polysat_core.h"
#include "sat/smt/polysat/polysat_constraints.h"
#include "sat/smt/polysat/polysat_ule.h"
@ -23,16 +24,34 @@ namespace polysat {
pdd lhs = p, rhs = q;
bool is_positive = true;
ule_constraint::simplify(is_positive, lhs, rhs);
auto* c = alloc(ule_constraint, p, q);
m_trail.push(new_obj_trail(c));
auto sc = signed_constraint(ckind_t::ule_t, c);
auto* cnstr = alloc(ule_constraint, p, q);
c.trail().push(new_obj_trail(cnstr));
auto sc = signed_constraint(ckind_t::ule_t, cnstr);
return is_positive ? sc : ~sc;
}
signed_constraint constraints::umul_ovfl(pdd const& p, pdd const& q) {
auto* c = alloc(umul_ovfl_constraint, p, q);
m_trail.push(new_obj_trail(c));
return signed_constraint(ckind_t::umul_ovfl_t, c);
auto* cnstr = alloc(umul_ovfl_constraint, p, q);
c.trail().push(new_obj_trail(cnstr));
return signed_constraint(ckind_t::umul_ovfl_t, cnstr);
}
bool signed_constraint::is_eq(pvar& v, rational& val) {
if (m_sign)
return false;
if (!is_ule())
return false;
auto const& ule = to_ule();
auto const& l = ule.lhs(), &r = ule.rhs();
if (!r.is_zero())
return false;
if (!l.is_unilinear())
return false;
if (!l.hi().is_one())
return false;
v = l.var();
val = -l.lo().val();
return true;
}
lbool signed_constraint::eval(assignment& a) const {
@ -44,4 +63,11 @@ namespace polysat {
if (m_sign) out << "~";
return out << *m_constraint;
}
bool signed_constraint::is_always_true() const {
return m_sign ? m_constraint->is_always_false() : m_constraint->is_always_true();
}
bool signed_constraint::is_always_false() const {
return m_sign ? m_constraint->is_always_true() : m_constraint->is_always_false();
}
}

View file

@ -41,6 +41,8 @@ namespace polysat {
virtual std::ostream& display(std::ostream& out) const = 0;
virtual lbool eval() const = 0;
virtual lbool eval(assignment const& a) const = 0;
virtual bool is_always_true() const = 0;
virtual bool is_always_false() const = 0;
};
inline std::ostream& operator<<(std::ostream& out, constraint const& c) { return c.display(out); }
@ -61,6 +63,8 @@ namespace polysat {
unsigned_vector const& vars() const { return m_constraint->vars(); }
unsigned var(unsigned idx) const { return m_constraint->var(idx); }
bool contains_var(pvar v) const { return m_constraint->contains_var(v); }
bool is_always_true() const;
bool is_always_false() const;
lbool eval(assignment& a) const;
ckind_t op() const { return m_op; }
bool is_ule() const { return m_op == ule_t; }
@ -68,27 +72,27 @@ namespace polysat {
bool is_smul_fl() const { return m_op == smul_fl_t; }
ule_constraint const& to_ule() const { return *reinterpret_cast<ule_constraint*>(m_constraint); }
umul_ovfl_constraint const& to_umul_ovfl() const { return *reinterpret_cast<umul_ovfl_constraint*>(m_constraint); }
bool is_eq(pvar& v, rational& val) { throw default_exception("nyi"); }
bool is_eq(pvar& v, rational& val);
std::ostream& display(std::ostream& out) const;
};
inline std::ostream& operator<<(std::ostream& out, signed_constraint const& c) { return c.display(out); }
class constraints {
trail_stack& m_trail;
core& c;
public:
constraints(trail_stack& c) : m_trail(c) {}
constraints(core& c) : c(c) {}
signed_constraint eq(pdd const& p) { return ule(p, p.manager().mk_val(0)); }
signed_constraint eq(pdd const& p, rational const& v) { return eq(p - p.manager().mk_val(v)); }
signed_constraint ule(pdd const& p, pdd const& q);
signed_constraint sle(pdd const& p, pdd const& q) { throw default_exception("nyi"); }
signed_constraint ult(pdd const& p, pdd const& q) { throw default_exception("nyi"); }
signed_constraint slt(pdd const& p, pdd const& q) { throw default_exception("nyi"); }
signed_constraint sle(pdd const& p, pdd const& q) { auto sh = rational::power_of_two(p.power_of_2() - 1); return ule(p + sh, q + sh); }
signed_constraint ult(pdd const& p, pdd const& q) { return ~ule(q, p); }
signed_constraint slt(pdd const& p, pdd const& q) { return ~sle(q, p); }
signed_constraint umul_ovfl(pdd const& p, pdd const& q);
signed_constraint smul_ovfl(pdd const& p, pdd const& q) { throw default_exception("nyi"); }
signed_constraint smul_udfl(pdd const& p, pdd const& q) { throw default_exception("nyi"); }
signed_constraint bit(pdd const& p, unsigned i) { throw default_exception("nyi"); }
signed_constraint smul_ovfl(pdd const& p, pdd const& q) { throw default_exception("smul ovfl nyi"); }
signed_constraint smul_udfl(pdd const& p, pdd const& q) { throw default_exception("smult-udfl nyi"); }
signed_constraint bit(pdd const& p, unsigned i) { throw default_exception("bit nyi"); }
signed_constraint diseq(pdd const& p) { return ~eq(p); }
signed_constraint diseq(pdd const& p, pdd const& q) { return diseq(p - q); }
@ -138,4 +142,4 @@ namespace polysat {
//signed_constraint even(pdd const& p) { return parity_at_least(p, 1); }
//signed_constraint odd(pdd const& p) { return ~even(p); }
};
}
}

View file

@ -80,7 +80,7 @@ namespace polysat {
core::core(solver_interface& s) :
s(s),
m_viable(*this),
m_constraints(s.trail()),
m_constraints(*this),
m_assignment(*this),
m_var_queue(m_activity)
{}

View file

@ -84,7 +84,8 @@ namespace polysat {
void get_bitvector_prefixes(pvar v, pvar_vector& out);
void get_fixed_bits(pvar v, svector<justified_fixed_bits>& fixed_bits);
bool inconsistent() const;
void add_clause(char const* name, std::initializer_list<signed_constraint> cs, bool is_redundant);
void add_watch(unsigned idx, unsigned var);
@ -114,29 +115,28 @@ namespace polysat {
signed_constraint bit(pdd const& p, unsigned i) { return m_constraints.bit(p, i); }
pdd lshr(pdd a, pdd b) { throw default_exception("nyi"); }
pdd ashr(pdd a, pdd b) { throw default_exception("nyi"); }
pdd shl(pdd a, pdd b) { throw default_exception("nyi"); }
pdd band(pdd a, pdd b) { throw default_exception("nyi"); }
pdd bxor(pdd a, pdd b) { throw default_exception("nyi"); }
pdd bor(pdd a, pdd b) { throw default_exception("nyi"); }
pdd bnand(pdd a, pdd b) { throw default_exception("nyi"); }
pdd bxnor(pdd a, pdd b) { throw default_exception("nyi"); }
pdd bnor(pdd a, pdd b) { throw default_exception("nyi"); }
pdd bnot(pdd a) { throw default_exception("nyi"); }
std::pair<pdd, pdd> quot_rem(pdd const& n, pdd const& d) { throw default_exception("nyi"); }
pdd zero_ext(pdd a, unsigned sz) { throw default_exception("nyi"); }
pdd sign_ext(pdd a, unsigned sz) { throw default_exception("nyi"); }
pdd extract(pdd src, unsigned hi, unsigned lo) { throw default_exception("nyi"); }
pdd concat(unsigned n, pdd const* args) { throw default_exception("nyi"); }
pdd lshr(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("lshr nyi"); }
pdd ashr(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("ashr nyi"); }
pdd shl(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("shlh nyi"); }
pdd band(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("band nyi"); }
pdd bxor(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("bxor nyi"); }
pdd bor(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("bir ==nyi"); }
pdd bnand(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("bnand nyi"); }
pdd bxnor(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("bxnor nyi"); }
pdd bnor(pdd a, pdd b) { NOT_IMPLEMENTED_YET(); throw default_exception("bnotr nyi"); }
pdd bnot(pdd a) { NOT_IMPLEMENTED_YET(); throw default_exception("bnot nyi"); }
pdd zero_ext(pdd a, unsigned sz) { NOT_IMPLEMENTED_YET(); throw default_exception("zero ext nyi"); }
pdd sign_ext(pdd a, unsigned sz) { NOT_IMPLEMENTED_YET(); throw default_exception("sign ext nyi"); }
pdd extract(pdd src, unsigned hi, unsigned lo) { NOT_IMPLEMENTED_YET(); throw default_exception("extract nyi"); }
pdd concat(unsigned n, pdd const* args) { NOT_IMPLEMENTED_YET(); throw default_exception("concat nyi"); }
pvar add_var(unsigned sz);
pdd var(pvar p) { return m_vars[p]; }
unsigned size(pvar v) const { return var2pdd(v).power_of_2(); }
unsigned size(pvar v) const { return m_vars[v].power_of_2(); }
constraints& cs() { return m_constraints; }
trail_stack& trail();
std::ostream& display(std::ostream& out) const { throw default_exception("nyi"); }
std::ostream& display(std::ostream& out) const { NOT_IMPLEMENTED_YET(); throw default_exception("nyi"); }
};
}

View file

@ -343,4 +343,22 @@ namespace polysat {
return eval(a.apply_to(lhs()), a.apply_to(rhs()));
}
bool ule_constraint::is_always_true() const {
if (lhs().is_zero())
return true; // 0 <= p
if (rhs().is_max())
return true; // p <= -1
if (lhs().is_val() && rhs().is_val())
return lhs().val() <= rhs().val();
return false;
}
bool ule_constraint::is_always_false() const {
if (lhs().is_never_zero() && rhs().is_zero())
return true; // p > 0, q = 0
if (lhs().is_val() && rhs().is_val())
return lhs().val() > rhs().val();
return false;
}
}

View file

@ -35,6 +35,8 @@ namespace polysat {
std::ostream& display(std::ostream& out) const override;
lbool eval() const override;
lbool eval(assignment const& a) const override;
bool is_always_true() const override;
bool is_always_false() const override;
bool is_eq() const { return m_rhs.is_zero(); }
unsigned power_of_2() const { return m_lhs.power_of_2(); }

View file

@ -34,6 +34,8 @@ namespace polysat {
std::ostream& display(std::ostream& out) const override;
lbool eval() const override;
lbool eval(assignment const& a) const override;
bool is_always_true() const override { return false; } // todo port
bool is_always_false() const override { return false; }
};
}

View file

@ -90,6 +90,8 @@ namespace polysat {
}
lbool viable::find_viable(pvar v, rational& lo, rational& hi) {
return l_undef;
fixed_bits_info fbi;
#if 0
@ -1007,7 +1009,7 @@ namespace polysat {
}
void viable::log(pvar v) {
throw default_exception("nyi");
//
}

View file

@ -186,36 +186,36 @@ namespace polysat {
template <bool FORWARD>
bool refine_viable(pvar v, rational const& val, fixed_bits_info const& fbi) {
throw default_exception("nyi");
throw default_exception("refine nyi");
}
bool refine_viable(pvar v, rational const& val) {
throw default_exception("nyi");
throw default_exception("refine nyi");
}
template <bool FORWARD>
bool refine_bits(pvar v, rational const& val, fixed_bits_info const& fbi) {
throw default_exception("nyi");
throw default_exception("refine nyi");
}
template <bool FORWARD>
entry* refine_bits(pvar v, rational const& val, unsigned num_bits, fixed_bits_info const& fbi) {
throw default_exception("nyi");
throw default_exception("refine nyi");
}
bool refine_equal_lin(pvar v, rational const& val) {
throw default_exception("nyi");
throw default_exception("refine nyi");
}
bool refine_disequal_lin(pvar v, rational const& val) {
throw default_exception("nyi");
throw default_exception("refine nyi");
}
void set_conflict_by_interval(pvar v, unsigned w, ptr_vector<entry>& intervals, unsigned first_interval);
bool set_conflict_by_interval_rec(pvar v, unsigned w, entry** intervals, unsigned num_intervals, bool& create_lemma, uint_set& vars_to_explain);
std::pair<entry*, bool> find_value(rational const& val, entry* entries) {
throw default_exception("nyi");
throw default_exception("fine_value nyi");
}
bool collect_bit_information(pvar v, bool add_conflict, fixed_bits_info& out_fbi);