mirror of
https://github.com/Z3Prover/z3
synced 2025-06-28 00:48:45 +00:00
Phase saving and some minor changes (#5209)
* Implement phase saving * Implement signed comparison on BDD vectors * Add fdd::non_zero * Simplify construction of fdds over disjoint variables * Minor changes to adding constraint
This commit is contained in:
parent
09f31ebb0a
commit
12444c7e8b
7 changed files with 156 additions and 31 deletions
|
@ -937,6 +937,26 @@ namespace dd {
|
||||||
bdd bdd_manager::mk_ult(bddv const& a, bddv const& b) { return mk_ule(a, b) && !mk_eq(a, b); }
|
bdd bdd_manager::mk_ult(bddv const& a, bddv const& b) { return mk_ule(a, b) && !mk_eq(a, b); }
|
||||||
bdd bdd_manager::mk_ugt(bddv const& a, bddv const& b) { return mk_ult(b, a); }
|
bdd bdd_manager::mk_ugt(bddv const& a, bddv const& b) { return mk_ult(b, a); }
|
||||||
|
|
||||||
|
bdd bdd_manager::mk_sle(bddv const& a, bddv const& b) {
|
||||||
|
SASSERT(a.size() == b.size());
|
||||||
|
// Note: sle can be reduced to ule by flipping the sign bits of both arguments
|
||||||
|
bdd lt = mk_false();
|
||||||
|
bdd eq = mk_true();
|
||||||
|
unsigned const sz = a.size();
|
||||||
|
if (sz > 0) {
|
||||||
|
lt = a[sz - 1] && !b[sz - 1];
|
||||||
|
eq = !(a[sz - 1] ^ b[sz - 1]);
|
||||||
|
for (unsigned i = sz - 1; i-- > 0; ) {
|
||||||
|
lt |= eq && (!a[i] && b[i]);
|
||||||
|
eq &= !(a[i] ^ b[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lt || eq;
|
||||||
|
}
|
||||||
|
bdd bdd_manager::mk_sge(bddv const& a, bddv const& b) { return mk_sle(b, a); }
|
||||||
|
bdd bdd_manager::mk_slt(bddv const& a, bddv const& b) { return mk_sle(a, b) && !mk_eq(a, b); }
|
||||||
|
bdd bdd_manager::mk_sgt(bddv const& a, bddv const& b) { return mk_slt(b, a); }
|
||||||
|
|
||||||
bddv bdd_manager::mk_add(bddv const& a, bddv const& b) {
|
bddv bdd_manager::mk_add(bddv const& a, bddv const& b) {
|
||||||
SASSERT(a.size() == b.size());
|
SASSERT(a.size() == b.size());
|
||||||
bdd carry = mk_false();
|
bdd carry = mk_false();
|
||||||
|
@ -1098,13 +1118,6 @@ namespace dd {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
bdd bdd_manager::mk_sle(bddv const& a, bddv const& b);
|
|
||||||
bdd bdd_manager::mk_sge(bddv const& a, bddv const& b) { return mk_sle(b, a); }
|
|
||||||
bdd bdd_manager::mk_slt(bddv const& a, bddv const& b) { return mk_sle(a, b) && !mk_eq(a, b); }
|
|
||||||
bdd bdd_manager::mk_sgt(bddv const& a, bddv const& b) { return mk_slt(b, a); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void bddv::shl() {
|
void bddv::shl() {
|
||||||
for (unsigned j = size(); j-- > 1;)
|
for (unsigned j = size(); j-- > 1;)
|
||||||
m_bits[j] = m_bits[j - 1];
|
m_bits[j] = m_bits[j - 1];
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace dd {
|
||||||
fdd::fdd(bdd_manager& manager, unsigned_vector&& vars)
|
fdd::fdd(bdd_manager& manager, unsigned_vector&& vars)
|
||||||
: m_pos2var(std::move(vars))
|
: m_pos2var(std::move(vars))
|
||||||
, m_var2pos()
|
, m_var2pos()
|
||||||
// , m(&manager)
|
, m(&manager)
|
||||||
, m_var(manager.mk_var(m_pos2var))
|
, m_var(manager.mk_var(m_pos2var))
|
||||||
{
|
{
|
||||||
for (unsigned pos = 0; pos < m_pos2var.size(); ++pos) {
|
for (unsigned pos = 0; pos < m_pos2var.size(); ++pos) {
|
||||||
|
@ -34,6 +34,14 @@ namespace dd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bdd fdd::non_zero() const {
|
||||||
|
bdd non_zero = m->mk_false();
|
||||||
|
for (unsigned var : m_pos2var) {
|
||||||
|
non_zero |= m->mk_var(var);
|
||||||
|
}
|
||||||
|
return non_zero;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned fdd::var2pos(unsigned var) const {
|
unsigned fdd::var2pos(unsigned var) const {
|
||||||
return var < m_var2pos.size() ? m_var2pos[var] : UINT_MAX;
|
return var < m_var2pos.size() ? m_var2pos[var] : UINT_MAX;
|
||||||
}
|
}
|
||||||
|
@ -48,27 +56,54 @@ namespace dd {
|
||||||
}
|
}
|
||||||
|
|
||||||
find_t fdd::find(bdd b, rational& out_val) const {
|
find_t fdd::find(bdd b, rational& out_val) const {
|
||||||
|
return find_hint(b, rational::zero(), out_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
find_t fdd::find_hint(bdd b, rational const& hint, rational& out_val) const {
|
||||||
out_val = 0;
|
out_val = 0;
|
||||||
if (b.is_false())
|
if (b.is_false())
|
||||||
return find_t::empty;
|
return find_t::empty;
|
||||||
bool is_unique = true;
|
bool is_unique = true;
|
||||||
|
bool hint_ok = !hint.is_zero(); // since we choose the 'lo' branch by default, we don't need to check the hint when it is 0.
|
||||||
unsigned num_vars = 0;
|
unsigned num_vars = 0;
|
||||||
while (!b.is_true()) {
|
while (!b.is_true()) {
|
||||||
++num_vars;
|
++num_vars;
|
||||||
unsigned const pos = var2pos(b.var());
|
unsigned const pos = var2pos(b.var());
|
||||||
SASSERT(pos != UINT_MAX && "Unexpected BDD variable");
|
SASSERT(pos != UINT_MAX && "Unexpected BDD variable");
|
||||||
|
|
||||||
|
bool go_hi = false;
|
||||||
if (b.lo().is_false()) {
|
if (b.lo().is_false()) {
|
||||||
|
go_hi = true;
|
||||||
|
if (hint_ok && !hint.get_bit(pos))
|
||||||
|
hint_ok = false;
|
||||||
|
}
|
||||||
|
else if (b.hi().is_false()) {
|
||||||
|
if (hint_ok && hint.get_bit(pos))
|
||||||
|
hint_ok = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This is the only case where we have a choice
|
||||||
|
// => follow the hint
|
||||||
|
SASSERT(!b.lo().is_false() && !b.hi().is_false());
|
||||||
|
is_unique = false;
|
||||||
|
if (hint_ok && hint.get_bit(pos))
|
||||||
|
go_hi = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (go_hi) {
|
||||||
out_val += rational::power_of_two(pos);
|
out_val += rational::power_of_two(pos);
|
||||||
b = b.hi();
|
b = b.hi();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (!b.hi().is_false())
|
|
||||||
is_unique = false;
|
|
||||||
b = b.lo();
|
b = b.lo();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (num_vars != num_bits())
|
if (num_vars != num_bits())
|
||||||
is_unique = false;
|
is_unique = false;
|
||||||
|
// If a variable corresponding to a 1-bit in hint does not appear in the BDD,
|
||||||
|
// out_val is wrong at this point, so we set it explicitly.
|
||||||
|
if (hint_ok)
|
||||||
|
out_val = hint;
|
||||||
|
// TODO: instead of computing out_val incrementally, we could mark the visited 'hi'-positions and only compute out_val from the marks when !hint_ok.
|
||||||
return is_unique ? find_t::singleton : find_t::multiple;
|
return is_unique ? find_t::singleton : find_t::multiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,14 @@ namespace dd {
|
||||||
class fdd {
|
class fdd {
|
||||||
unsigned_vector m_pos2var; // pos -> BDD var
|
unsigned_vector m_pos2var; // pos -> BDD var
|
||||||
unsigned_vector m_var2pos; // var -> pos (pos = place number in the bit representation, 0 is LSB's place)
|
unsigned_vector m_var2pos; // var -> pos (pos = place number in the bit representation, 0 is LSB's place)
|
||||||
// bdd_manager* m; // NOTE: currently unused
|
bdd_manager* m;
|
||||||
bddv m_var;
|
bddv m_var;
|
||||||
|
|
||||||
static unsigned_vector seq(unsigned count) {
|
static unsigned_vector seq(unsigned count, unsigned start = 0, unsigned step = 1) {
|
||||||
unsigned_vector result;
|
unsigned_vector result;
|
||||||
for (unsigned i = 0; i < count; ++i)
|
unsigned k = start;
|
||||||
result.push_back(i);
|
for (unsigned i = 0; i < count; ++i, k += step)
|
||||||
|
result.push_back(k);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ namespace dd {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Initialize FDD using BDD variables from 0 to num_bits-1. */
|
/** Initialize FDD using BDD variables from 0 to num_bits-1. */
|
||||||
fdd(bdd_manager& manager, unsigned num_bits) : fdd(manager, seq(num_bits)) { }
|
fdd(bdd_manager& manager, unsigned num_bits, unsigned start = 0, unsigned step = 1) : fdd(manager, seq(num_bits, start, step)) { }
|
||||||
fdd(bdd_manager& manager, unsigned_vector const& vars) : fdd(manager, unsigned_vector(vars)) { }
|
fdd(bdd_manager& manager, unsigned_vector const& vars) : fdd(manager, unsigned_vector(vars)) { }
|
||||||
fdd(bdd_manager& manager, unsigned_vector&& vars);
|
fdd(bdd_manager& manager, unsigned_vector&& vars);
|
||||||
|
|
||||||
|
@ -55,6 +56,9 @@ namespace dd {
|
||||||
|
|
||||||
bddv const& var() const { return m_var; }
|
bddv const& var() const { return m_var; }
|
||||||
|
|
||||||
|
/** Equivalent to var() != 0 */
|
||||||
|
bdd non_zero() const;
|
||||||
|
|
||||||
/** Checks whether the integer val is contained in the BDD when viewed as set of integers.
|
/** Checks whether the integer val is contained in the BDD when viewed as set of integers.
|
||||||
* Precondition: the bdd only contains variables managed by this fdd.
|
* Precondition: the bdd only contains variables managed by this fdd.
|
||||||
*/
|
*/
|
||||||
|
@ -64,6 +68,9 @@ namespace dd {
|
||||||
* Precondition: the bdd only contains variables managed by this fdd.
|
* Precondition: the bdd only contains variables managed by this fdd.
|
||||||
*/
|
*/
|
||||||
find_t find(bdd b, rational& out_val) const;
|
find_t find(bdd b, rational& out_val) const;
|
||||||
|
|
||||||
|
/** Like find, but returns hint if it is contained in the BDD. */
|
||||||
|
find_t find_hint(bdd b, rational const& hint, rational& out_val) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace polysat {
|
||||||
pvar v = q.var();
|
pvar v = q.var();
|
||||||
rational a = q.hi().val();
|
rational a = q.hi().val();
|
||||||
rational b = q.lo().val();
|
rational b = q.lo().val();
|
||||||
bddv const& x = s.sz2bits(s.size(v)).var();
|
bddv const& x = s.var2bits(v).var();
|
||||||
bdd xs = (a * x + b == rational(0));
|
bdd xs = (a * x + b == rational(0));
|
||||||
s.intersect_viable(v, xs);
|
s.intersect_viable(v, xs);
|
||||||
s.push_cjust(v, this);
|
s.push_cjust(v, this);
|
||||||
|
|
|
@ -41,14 +41,14 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool solver::is_viable(pvar v, rational const& val) {
|
bool solver::is_viable(pvar v, rational const& val) {
|
||||||
return sz2bits(size(v)).contains(m_viable[v], val);
|
return var2bits(v).contains(m_viable[v], val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_non_viable(pvar v, rational const& val) {
|
void solver::add_non_viable(pvar v, rational const& val) {
|
||||||
LOG("pvar " << v << " /= " << val);
|
LOG("pvar " << v << " /= " << val);
|
||||||
TRACE("polysat", tout << "v" << v << " /= " << val << "\n";);
|
TRACE("polysat", tout << "v" << v << " /= " << val << "\n";);
|
||||||
SASSERT(is_viable(v, val));
|
SASSERT(is_viable(v, val));
|
||||||
auto& bits = sz2bits(size(v));
|
auto const& bits = var2bits(v);
|
||||||
intersect_viable(v, bits.var() != val);
|
intersect_viable(v, bits.var() != val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
dd::find_t solver::find_viable(pvar v, rational & val) {
|
dd::find_t solver::find_viable(pvar v, rational & val) {
|
||||||
return sz2bits(size(v)).find(m_viable[v], val);
|
return var2bits(v).find_hint(m_viable[v], m_value[v], val);
|
||||||
}
|
}
|
||||||
|
|
||||||
solver::solver(reslimit& lim):
|
solver::solver(reslimit& lim):
|
||||||
|
@ -148,13 +148,18 @@ namespace polysat {
|
||||||
m_free_vars.del_var_eh(v);
|
m_free_vars.del_var_eh(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solver::add_constraint(constraint* c) {
|
||||||
|
SASSERT(c);
|
||||||
|
LOG("Adding constraint: " << *c);
|
||||||
|
m_constraints.push_back(c);
|
||||||
|
c->narrow(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void solver::add_eq(pdd const& p, unsigned dep) {
|
void solver::add_eq(pdd const& p, unsigned dep) {
|
||||||
p_dependency_ref d(mk_dep(dep), m_dm);
|
p_dependency_ref d(mk_dep(dep), m_dm);
|
||||||
constraint* c = constraint::eq(m_level, p, d);
|
constraint* c = constraint::eq(m_level, p, d);
|
||||||
LOG("Adding constraint: " << *c);
|
|
||||||
m_constraints.push_back(c);
|
|
||||||
add_watch(*c);
|
add_watch(*c);
|
||||||
c->narrow(*this);
|
add_constraint(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_diseq(pdd const& p, unsigned dep) {
|
void solver::add_diseq(pdd const& p, unsigned dep) {
|
||||||
|
@ -166,32 +171,35 @@ namespace polysat {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned sz = size(p.var());
|
unsigned sz = size(p.var());
|
||||||
auto slack = add_var(size(p.var()));
|
auto slack = add_var(sz);
|
||||||
auto q = p + var(slack);
|
auto q = p + var(slack);
|
||||||
add_eq(q, dep);
|
add_eq(q, dep);
|
||||||
bdd non_zero = m_bdd.mk_false();
|
auto non_zero = sz2bits(sz).non_zero();
|
||||||
for (unsigned i = 0; i < sz; ++i)
|
|
||||||
non_zero |= m_bdd.mk_var(i);
|
|
||||||
p_dependency_ref d(mk_dep(dep), m_dm);
|
p_dependency_ref d(mk_dep(dep), m_dm);
|
||||||
constraint* c = constraint::viable(m_level, slack, non_zero, d);
|
constraint* c = constraint::viable(m_level, slack, non_zero, d);
|
||||||
m_constraints.push_back(c);
|
add_constraint(c);
|
||||||
c->narrow(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_ule(pdd const& p, pdd const& q, unsigned dep) {
|
void solver::add_ule(pdd const& p, pdd const& q, unsigned dep) {
|
||||||
// save for later
|
p_dependency_ref d(mk_dep(dep), m_dm);
|
||||||
|
constraint* c = constraint::ule(m_level, p, q, d);
|
||||||
|
add_watch(*c);
|
||||||
|
add_constraint(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_sle(pdd const& p, pdd const& q, unsigned dep) {
|
void solver::add_sle(pdd const& p, pdd const& q, unsigned dep) {
|
||||||
// save for later
|
// save for later
|
||||||
|
NOT_IMPLEMENTED_YET();
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_ult(pdd const& p, pdd const& q, unsigned dep) {
|
void solver::add_ult(pdd const& p, pdd const& q, unsigned dep) {
|
||||||
// save for later
|
// save for later
|
||||||
|
NOT_IMPLEMENTED_YET();
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_slt(pdd const& p, pdd const& q, unsigned dep) {
|
void solver::add_slt(pdd const& p, pdd const& q, unsigned dep) {
|
||||||
// save for later
|
// save for later
|
||||||
|
NOT_IMPLEMENTED_YET();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace polysat {
|
||||||
|
|
||||||
friend class eq_constraint;
|
friend class eq_constraint;
|
||||||
friend class var_constraint;
|
friend class var_constraint;
|
||||||
|
friend class ule_constraint;
|
||||||
|
|
||||||
typedef ptr_vector<constraint> constraints;
|
typedef ptr_vector<constraint> constraints;
|
||||||
|
|
||||||
|
@ -150,6 +151,7 @@ namespace polysat {
|
||||||
|
|
||||||
dd::pdd_manager& sz2pdd(unsigned sz);
|
dd::pdd_manager& sz2pdd(unsigned sz);
|
||||||
dd::fdd const& sz2bits(unsigned sz);
|
dd::fdd const& sz2bits(unsigned sz);
|
||||||
|
dd::fdd const& var2bits(pvar v) { return sz2bits(size(v)); }
|
||||||
|
|
||||||
void push_level();
|
void push_level();
|
||||||
void pop_levels(unsigned num_levels);
|
void pop_levels(unsigned num_levels);
|
||||||
|
@ -201,6 +203,8 @@ namespace polysat {
|
||||||
void backjump(unsigned new_level);
|
void backjump(unsigned new_level);
|
||||||
void add_lemma(constraint* c);
|
void add_lemma(constraint* c);
|
||||||
|
|
||||||
|
void add_constraint(constraint* c);
|
||||||
|
|
||||||
bool invariant();
|
bool invariant();
|
||||||
bool invariant(scoped_ptr_vector<constraint> const& cs);
|
bool invariant(scoped_ptr_vector<constraint> const& cs);
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,27 @@ public:
|
||||||
eq = m.mk_eq(nv, kr);
|
eq = m.mk_eq(nv, kr);
|
||||||
SASSERT(eq.is_const() && (eq.is_true() == (n == k)));
|
SASSERT(eq.is_const() && (eq.is_true() == (n == k)));
|
||||||
|
|
||||||
|
bdd cmp = nv <= kv;
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nr <= kr)));
|
||||||
|
cmp = nv >= kv;
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nr >= kr)));
|
||||||
|
cmp = nv < kv;
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nr < kr)));
|
||||||
|
cmp = nv > kv;
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nr > kr)));
|
||||||
|
|
||||||
|
// signed versions
|
||||||
|
rational const nrs = (nr < modulus / 2) ? nr : nr - modulus;
|
||||||
|
rational const krs = (kr < modulus / 2) ? kr : kr - modulus;
|
||||||
|
cmp = nv.sle(kv);
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nrs <= krs)));
|
||||||
|
cmp = nv.sge(kv);
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nrs >= krs)));
|
||||||
|
cmp = nv.slt(kv);
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nrs < krs)));
|
||||||
|
cmp = nv.sgt(kv);
|
||||||
|
SASSERT(cmp.is_const() && (cmp.is_true() == (nrs > krs)));
|
||||||
|
|
||||||
bddv quotv = m.mk_zero(num_bits);
|
bddv quotv = m.mk_zero(num_bits);
|
||||||
bddv remv = m.mk_zero(num_bits);
|
bddv remv = m.mk_zero(num_bits);
|
||||||
nv.quot_rem(kv, quotv, remv);
|
nv.quot_rem(kv, quotv, remv);
|
||||||
|
@ -367,6 +388,41 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_fdd_twovars() {
|
||||||
|
std::cout << "test_fdd_twovars\n";
|
||||||
|
bdd_manager m(6);
|
||||||
|
fdd const x_dom(m, 3, 0, 2);
|
||||||
|
fdd const y_dom(m, 3, 1, 2);
|
||||||
|
bddv const& x = x_dom.var();
|
||||||
|
bddv const& y = y_dom.var();
|
||||||
|
SASSERT_EQ(x - y <= rational(0), x == y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_fdd_find_hint() {
|
||||||
|
std::cout << "test_fdd_find_hint\n";
|
||||||
|
bdd_manager m(4);
|
||||||
|
fdd const x_dom(m, 4);
|
||||||
|
bddv const& x = x_dom.var();
|
||||||
|
|
||||||
|
bdd s358 = x == rational(3) || x == rational(5) || x == rational(8);
|
||||||
|
rational r;
|
||||||
|
SASSERT_EQ(x_dom.find_hint(s358, rational(8), r), find_t::multiple);
|
||||||
|
SASSERT_EQ(r, 8);
|
||||||
|
SASSERT_EQ(x_dom.find_hint(s358, rational(5), r), find_t::multiple);
|
||||||
|
SASSERT_EQ(r, 5);
|
||||||
|
SASSERT_EQ(x_dom.find_hint(s358, rational(3), r), find_t::multiple);
|
||||||
|
SASSERT_EQ(r, 3);
|
||||||
|
SASSERT_EQ(x_dom.find_hint(s358, rational(7), r), find_t::multiple);
|
||||||
|
SASSERT(r == 3 || r == 5 || r == 8);
|
||||||
|
|
||||||
|
SASSERT_EQ(x_dom.find_hint(x == rational(5), rational(3), r), find_t::singleton);
|
||||||
|
SASSERT_EQ(r, 5);
|
||||||
|
SASSERT_EQ(x_dom.find_hint(x == rational(5), rational(5), r), find_t::singleton);
|
||||||
|
SASSERT_EQ(r, 5);
|
||||||
|
|
||||||
|
SASSERT_EQ(x_dom.find_hint(s358 && (x == rational(4)), rational(5), r), find_t::empty);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -386,4 +442,6 @@ void tst_bdd() {
|
||||||
dd::test_bdd::test_fdd3();
|
dd::test_bdd::test_fdd3();
|
||||||
dd::test_bdd::test_fdd4();
|
dd::test_bdd::test_fdd4();
|
||||||
dd::test_bdd::test_fdd_reorder();
|
dd::test_bdd::test_fdd_reorder();
|
||||||
|
dd::test_bdd::test_fdd_twovars();
|
||||||
|
dd::test_bdd::test_fdd_find_hint();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue