3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-26 18:45:33 +00:00

Add BDD utilities; use them for narrowing/propagation of linear equality constraints (#5192)

* Add a few helper methods for encoding sets of integers as BDDs

* Use BDD functions in solver

* Add bdd::find_int

* Use bdd::find_int in solver

* Add narrowing for linear equality constraints

* Simplify code for linear propagation

* Add test for later

* Narrowing can only handle linear constraints with a single variable

* Need to push_cjust
This commit is contained in:
Jakob Rath 2021-04-16 17:44:18 +02:00 committed by GitHub
parent e970fe5034
commit f72e30e539
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 208 additions and 104 deletions

View file

@ -73,6 +73,46 @@ namespace dd {
std::cout << c1 << "\n";
std::cout << c1.bdd_size() << "\n";
}
static void test_int() {
unsigned const w = 3; // bit width
bdd_manager m(w);
vector<bdd> num;
for (unsigned n = 0; n < (1<<w); ++n)
num.push_back(m.mk_int(rational(n), w));
for (unsigned k = 0; k < (1 << w); ++k)
for (unsigned n = 0; n < (1 << w); ++n)
SASSERT(num[k].contains_int(rational(n), w) == (n == k));
bdd s0127 = num[0] || num[1] || num[2] || num[7];
SASSERT(s0127.contains_int(rational(0), w));
SASSERT(s0127.contains_int(rational(1), w));
SASSERT(s0127.contains_int(rational(2), w));
SASSERT(!s0127.contains_int(rational(3), w));
SASSERT(!s0127.contains_int(rational(4), w));
SASSERT(!s0127.contains_int(rational(5), w));
SASSERT(!s0127.contains_int(rational(6), w));
SASSERT(s0127.contains_int(rational(7), w));
bdd s123 = num[1] || num[2] || num[3];
SASSERT((s0127 && s123) == (num[1] || num[2]));
// larger width constrains additional bits
SASSERT(m.mk_int(rational(6), 3) != m.mk_int(rational(6), 4));
// 4*x + 2 == 0 (mod 2^3) has no solutions
SASSERT(m.mk_affine(rational(4), rational(2), 3).is_false());
// 3*x + 2 == 0 (mod 2^3) has the unique solution 2
SASSERT(m.mk_affine(rational(3), rational(2), 3) == num[2]);
// 2*x + 2 == 0 (mod 2^3) has the solutions 3, 7
SASSERT(m.mk_affine(rational(2), rational(2), 3) == (num[3] || num[7]));
// 12*x + 8 == 0 (mod 2^4) has the solutions 2, 6, 10, 14
bdd expected = m.mk_int(rational(2), 4) || m.mk_int(rational(6), 4) || m.mk_int(rational(10), 4) || m.mk_int(rational(14), 4);
SASSERT(m.mk_affine(rational(12), rational(8), 4) == expected);
SASSERT(m.mk_affine(rational(0), rational(0), 3).is_true());
SASSERT(m.mk_affine(rational(0), rational(1), 3).is_false());
// 2*x == 0 (mod 2^3) has the solutions 0, 4
SASSERT(m.mk_affine(rational(2), rational(0), 3) == (num[0] || num[4]));
}
}
void tst_bdd() {
@ -80,4 +120,5 @@ void tst_bdd() {
dd::test2();
dd::test3();
dd::test4();
dd::test_int();
}