mirror of
https://github.com/Z3Prover/z3
synced 2025-06-26 15:53:41 +00:00
add find_two
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
3c035daaa6
commit
4e8bd4425f
3 changed files with 45 additions and 13 deletions
|
@ -147,9 +147,15 @@ namespace polysat {
|
||||||
reset_cache();
|
reset_cache();
|
||||||
if (sign)
|
if (sign)
|
||||||
e = m.mk_not(e);
|
e = m.mk_not(e);
|
||||||
expr* a = m.mk_const(m.mk_const_decl(symbol(dep), m.mk_bool_sort()));
|
if (dep == null_dep) {
|
||||||
s->assert_expr(e, a);
|
s->assert_expr(e);
|
||||||
IF_VERBOSE(10, verbose_stream() << "(assert (! " << expr_ref(e, m) << " :named " << expr_ref(a, m) << "))\n");
|
IF_VERBOSE(10, verbose_stream() << "(assert " << expr_ref(e, m) << ")\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expr* a = m.mk_const(m.mk_const_decl(symbol(dep), m.mk_bool_sort()));
|
||||||
|
s->assert_expr(e, a);
|
||||||
|
IF_VERBOSE(10, verbose_stream() << "(assert (! " << expr_ref(e, m) << " :named " << expr_ref(a, m) << "))\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_ule(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) override {
|
void add_ule(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) override {
|
||||||
|
@ -245,7 +251,7 @@ namespace polysat {
|
||||||
// try reducing val by setting bits to 0, starting at the msb.
|
// try reducing val by setting bits to 0, starting at the msb.
|
||||||
for (unsigned k = bit_width; k-- > 0; ) {
|
for (unsigned k = bit_width; k-- > 0; ) {
|
||||||
if (!val.get_bit(k)) {
|
if (!val.get_bit(k)) {
|
||||||
add_bit0(k, 0);
|
add_bit0(k, null_dep);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// try decreasing k-th bit
|
// try decreasing k-th bit
|
||||||
|
@ -258,9 +264,9 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
pop(1);
|
pop(1);
|
||||||
if (result == l_true)
|
if (result == l_true)
|
||||||
add_bit0(k, 0);
|
add_bit0(k, null_dep);
|
||||||
else if (result == l_false)
|
else if (result == l_false)
|
||||||
add_bit1(k, 0);
|
add_bit1(k, null_dep);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -287,9 +293,9 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
pop(1);
|
pop(1);
|
||||||
if (result == l_true)
|
if (result == l_true)
|
||||||
add_bit1(k, 0);
|
add_bit1(k, null_dep);
|
||||||
else if (result == l_false)
|
else if (result == l_false)
|
||||||
add_bit0(k, 0);
|
add_bit0(k, null_dep);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -297,6 +303,26 @@ namespace polysat {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool find_two(rational& out1, rational& out2) {
|
||||||
|
out1 = model();
|
||||||
|
bool ok = true;
|
||||||
|
push();
|
||||||
|
add(m.mk_eq(mk_numeral(out1), x), true, null_dep);
|
||||||
|
switch (check()) {
|
||||||
|
case l_true:
|
||||||
|
out2 = model();
|
||||||
|
break;
|
||||||
|
case l_false:
|
||||||
|
out2 = out1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pop(1);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& display(std::ostream& out) const override {
|
std::ostream& display(std::ostream& out) const override {
|
||||||
return out << *s;
|
return out << *s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ namespace polysat {
|
||||||
/// e.g., the vector [ c, b, a ] represents a*x^2 + b*x + c.
|
/// e.g., the vector [ c, b, a ] represents a*x^2 + b*x + c.
|
||||||
using univariate = vector<rational>;
|
using univariate = vector<rational>;
|
||||||
|
|
||||||
|
const dep_t null_dep = UINT_MAX;
|
||||||
|
|
||||||
virtual ~univariate_solver() = default;
|
virtual ~univariate_solver() = default;
|
||||||
|
|
||||||
virtual void push() = 0;
|
virtual void push() = 0;
|
||||||
|
@ -70,6 +72,14 @@ namespace polysat {
|
||||||
*/
|
*/
|
||||||
virtual bool find_max(rational& out_max) = 0;
|
virtual bool find_max(rational& out_max) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find up to two viable values.
|
||||||
|
*
|
||||||
|
* Precondition: check() returned l_true
|
||||||
|
* returns: true on success, false on resource out
|
||||||
|
*/
|
||||||
|
virtual bool find_two(rational& out1, rational& out2) = 0;
|
||||||
|
|
||||||
virtual void add_ule(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) = 0;
|
virtual void add_ule(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) = 0;
|
||||||
virtual void add_umul_ovfl(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) = 0;
|
virtual void add_umul_ovfl(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) = 0;
|
||||||
virtual void add_smul_ovfl(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) = 0;
|
virtual void add_smul_ovfl(univariate const& lhs, univariate const& rhs, bool sign, dep_t dep) = 0;
|
||||||
|
|
|
@ -799,11 +799,7 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool viable::query_find_fallback(pvar v, univariate_solver& us, rational& lo, rational& hi) {
|
lbool viable::query_find_fallback(pvar v, univariate_solver& us, rational& lo, rational& hi) {
|
||||||
if (!us.find_min(lo))
|
return us.find_two(lo, hi) ? l_true : l_undef;
|
||||||
return l_undef;
|
|
||||||
if (!us.find_max(hi))
|
|
||||||
return l_undef;
|
|
||||||
return l_true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool viable::query_min_fallback(pvar v, univariate_solver& us, rational& lo) {
|
lbool viable::query_min_fallback(pvar v, univariate_solver& us, rational& lo) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue