3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

checkpoint

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2012-10-21 22:16:58 -07:00
parent 142bf71b35
commit 9359ab7ce5
124 changed files with 2 additions and 0 deletions

569
src/test/algebraic.cpp Normal file
View file

@ -0,0 +1,569 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
algebraic.cpp
Abstract:
Test Algebraic Numbers
Author:
Leonardo (leonardo) 2011-11-22
Notes:
--*/
#include"algebraic_numbers.h"
#include"polynomial_var2value.h"
#include"mpbq.h"
static void display_anums(std::ostream & out, scoped_anum_vector const & rs) {
out << "numbers in decimal:\n";
algebraic_numbers::manager & m = rs.m();
for (unsigned i = 0; i < rs.size(); i++) {
m.display_decimal(out, rs[i], 10);
out << "\n";
}
out << "numbers as root objects\n";
for (unsigned i = 0; i < rs.size(); i++) {
m.display_root(out, rs[i]);
out << "\n";
}
out << "numbers as intervals\n";
for (unsigned i = 0; i < rs.size(); i++) {
m.display_interval(out, rs[i]);
out << "\n";
}
}
static void tst1() {
unsynch_mpq_manager nm;
polynomial::manager m(nm);
polynomial_ref x(m);
x = m.mk_polynomial(m.mk_var());
polynomial_ref p(m);
p = 3*x - 2;
algebraic_numbers::manager am(nm);
scoped_anum_vector rs1(am);
std::cout << "p: " << p << "\n";
am.isolate_roots(p, rs1);
display_anums(std::cout, rs1);
SASSERT(rs1.size() == 1);
std::cout.flush();
p = (x^2) - 2;
std::cout << "p: " << p << "\n";
rs1.reset();
am.isolate_roots(p, rs1);
display_anums(std::cout, rs1);
SASSERT(rs1.size() == 2);
scoped_anum sqrt2(am);
am.set(sqrt2, rs1[1]);
scoped_mpq q(nm);
nm.set(q, 1, 3);
scoped_anum aq(am);
am.set(aq, q); // create algebraic number representing 1/3
am.add(sqrt2, aq, aq);
std::cout << "sqrt(2) + 1/3: ";
am.display_decimal(std::cout, aq, 10); std::cout << " "; am.display_interval(std::cout, aq);
std::cout << " "; am.display_root(std::cout, aq); std::cout << "\n";
am.set(aq, q);
am.add(rs1[0], aq, aq);
std::cout << "-sqrt(2) + 1/3: ";
am.display_decimal(std::cout, aq, 10); std::cout << " "; am.display_interval(std::cout, aq);
std::cout << " "; am.display_root(std::cout, aq); std::cout << "\n";
p = ((x^5) - x - 1)*(x-1)*(x-2);
std::cout << "p: " << p << "\n";
rs1.reset();
am.isolate_roots(p, rs1);
display_anums(std::cout, rs1);
SASSERT(rs1.size() == 3);
scoped_anum gauss(am);
am.set(gauss, rs1[1]);
std::cout << "compare(" << sqrt2 << ", " << gauss << "): " << am.compare(sqrt2, gauss) << "\n";
statistics st;
am.collect_statistics(st);
st.display_smt2(std::cout);
p = ((x^2) - 2)*((x^2) - 3);
std::cout << "p: " << p << "\n";
rs1.reset();
am.isolate_roots(p, rs1);
display_anums(std::cout, rs1);
SASSERT(rs1.size() == 4);
scoped_anum hidden_sqrt2(am);
am.set(hidden_sqrt2, rs1[2]);
std::cout << "compare(" << sqrt2 << ", " << hidden_sqrt2 << "): " << am.compare(sqrt2, hidden_sqrt2) << "\n";
st.reset();
am.collect_statistics(st);
st.display_smt2(std::cout);
std::cout << "sqrt(2)^4: " << (sqrt2^4) << "\n";
SASSERT(is_int(power(sqrt2, 4)));
SASSERT(power(sqrt2, 4) == 4);
scoped_anum sqrt2_gauss(am);
am.add(sqrt2, gauss, sqrt2_gauss);
std::cout << "sqrt2 + gauss: " << sqrt2_gauss << " "; am.display_root(std::cout, sqrt2_gauss); std::cout << "\n";
std::cout << "sqrt2*sqrt2: " << sqrt2*sqrt2 << "\n";
std::cout << "sqrt2*sqrt2 == 2: " << (sqrt2*sqrt2 == 2) << std::endl;
scoped_anum three(am);
am.set(three, -3);
std::cout << "(-3)^(1/5): " << root(three, 5) << "\n";
std::cout << "sqrt(2)^(1/3): " << root(sqrt2, 3) << "\n";
std::cout << "as-root-object(sqrt(2)^(1/3)): " << root_obj_pp(root(sqrt2, 3)) << "\n";
std::cout << "(sqrt(2) + 1)^(1/3): " << root(sqrt2 + 1, 3) << "\n";
std::cout << "as-root-object((sqrt(2) + 1)^(1/3)): " << root_obj_pp(root(sqrt2 + 1, 3)) << "\n";
std::cout << "(sqrt(2) + gauss)^(1/5): " << root(sqrt2 + gauss, 5) << "\n";
std::cout << "as-root-object(sqrt(2) + gauss)^(1/5): " << root_obj_pp(root(sqrt2 + gauss, 5)) << "\n";
std::cout << "(sqrt(2) / sqrt(2)): " << sqrt2 / hidden_sqrt2 << "\n";
std::cout << "(sqrt(2) / gauss): " << sqrt2 / gauss << "\n";
std::cout << "(sqrt(2) / gauss) 30 digits: " << decimal_pp(sqrt2 / gauss, 30) << "\n";
std::cout << "as-root-object(sqrt(2) / gauss): " << root_obj_pp(sqrt2 / gauss) << "\n";
std::cout << "is_int(sqrt(2)^(1/3)): " << am.is_int(root(sqrt2, 3)) << "\n";
scoped_anum tmp(am);
scoped_anum four(am);
am.set(four, 4);
am.set(tmp, sqrt2);
am.inv(tmp);
std::cout << "1/sqrt(2): " << tmp << "\n";
am.mul(tmp, four, tmp);
std::cout << "4*1/sqrt(2): " << tmp << " " << root_obj_pp(tmp) << "\n";
am.mul(tmp, sqrt2, tmp);
std::cout << "sqrt(2)*4*(1/sqrt2): " << tmp << " " << root_obj_pp(tmp) << "\n";
std::cout << "is_int(sqrt(2)*4*(1/sqrt2)): " << am.is_int(tmp) << ", after is-int: " << tmp << "\n";
p = (998*x - 1414)*((x^2) - 15);
std::cout << "p: " << p << "\n";
rs1.reset();
am.isolate_roots(p, rs1);
std::cout << "is-rational(sqrt2): " << am.is_rational(sqrt2) << "\n";
scoped_anum qr(am);
am.set(qr, rs1[1]);
std::cout << "qr: " << root_obj_pp(qr);
std::cout << ", is-rational: " << am.is_rational(qr) << ", val: " << root_obj_pp(qr) << "\n";
return;
std::cout << "compare(" << sqrt2 << ", " << gauss << "): " << am.compare(sqrt2, gauss) << "\n";
p = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225;
std::cout << "p: " << p << "\n";
rs1.reset();
am.isolate_roots(p, rs1);
display_anums(std::cout, rs1);
}
void tst_refine_mpbq() {
unsynch_mpq_manager qm;
mpbq_manager bqm(qm);
scoped_mpq q1(qm);
qm.set(q1, 5, 7);
scoped_mpbq l(bqm);
scoped_mpbq u(bqm);
std::cout << "using refine upper...\n";
bqm.to_mpbq(q1, l);
bqm.set(u, l);
bqm.mul2(u);
for (unsigned i = 0; i < 20; i++) {
std::cout << l << " < " << q1 << " < " << u << "\n";
bqm.display_decimal(std::cout, l, 20); std::cout << " < ";
qm.display_decimal(std::cout, q1, 20); std::cout << " < ";
bqm.display_decimal(std::cout, u, 20); std::cout << std::endl;
bqm.refine_upper(q1, l, u);
}
std::cout << "using refine lower...\n";
bqm.to_mpbq(q1, l);
bqm.set(u, l);
bqm.mul2(u);
for (unsigned i = 0; i < 20; i++) {
std::cout << l << " < " << q1 << " < " << u << "\n";
bqm.display_decimal(std::cout, l, 20); std::cout << " < ";
qm.display_decimal(std::cout, q1, 20); std::cout << " < ";
bqm.display_decimal(std::cout, u, 20); std::cout << std::endl;
bqm.refine_lower(q1, l, u);
}
}
void tst_mpbq_root() {
unsynch_mpq_manager qm;
mpbq_manager bqm(qm);
// scoped_mpbq q(bqm);
// q.set(q1, 1.4142135 , 7);
}
static void tst_wilkinson() {
// Test Wilkinson Polynomial
unsynch_mpq_manager nm;
polynomial::manager m(nm);
polynomial_ref x(m);
x = m.mk_polynomial(m.mk_var());
polynomial_ref p(m);
for (int i = 1; i <= 20; i++) {
if (i > 1)
p = p*(x - i);
else
p = (x - i);
}
std::cout << "Wilkinson's polynomial: " << p << "\n";
algebraic_numbers::manager am(nm);
scoped_anum_vector rs1(am);
std::cout << "p: " << p << "\n";
am.isolate_roots(p, rs1);
display_anums(std::cout, rs1);
SASSERT(rs1.size() == 20);
for (unsigned i = 0; i < rs1.size(); i++) {
SASSERT(am.is_int(rs1[i]));
}
}
static void tst_dejan() {
unsynch_mpq_manager qm;
algebraic_numbers::manager am(qm);
scoped_anum two101(am);
am.set(two101, 2);
am.root(two101, 11, two101);
scoped_anum two103(am);
am.set(two103, 2);
am.root(two103, 7, two103);
std::cout << "two101: " << two101 << " " << root_obj_pp(two101) << std::endl;
std::cout << "two103: " << two103 << " " << root_obj_pp(two103) << std::endl;
scoped_anum sum1(am);
am.add(two103, two101, sum1);
std::cout << "sum1: " << sum1 << " " << root_obj_pp(sum1) << "\n";
}
static void tst_select_small(mpbq_manager & m, scoped_mpbq const & l, scoped_mpbq const & u, bool expected) {
scoped_mpbq r(m);
std::cout << "----------\n";
std::cout << "lower: " << l << " as decimal: "; m.display_decimal(std::cout, l); std::cout << std::endl;
std::cout << "upper: " << u << " as decimal: "; m.display_decimal(std::cout, u); std::cout << std::endl;
VERIFY(m.select_small(l, u, r) == expected);
std::cout << "choice: " << r << " as decimal: "; m.display_decimal(std::cout, r); std::cout << std::endl;
}
static void tst_select_small(mpbq_manager & m, int64 n1, unsigned k1, int64 n2, unsigned k2, bool expected) {
scoped_mpbq l(m);
scoped_mpbq u(m);
m.set(l, n1, k1);
m.set(u, n2, k2);
tst_select_small(m, l, u, expected);
}
static void tst_select_small() {
unsynch_mpz_manager m;
mpbq_manager bqm(m);
tst_select_small(bqm, 1, 3, 3, 2, true);
tst_select_small(bqm, 10000000000000ll, 40, 11000, 10, true);
tst_select_small(bqm, 10000000000000ll, 40, 10001, 10, true);
tst_select_small(bqm, 1, 0, 1, 0, true);
tst_select_small(bqm, 1, 0, 2, 0, true);
tst_select_small(bqm, -1, 0, -1, 0, true);
tst_select_small(bqm, -2, 0, -1, 0, true);
tst_select_small(bqm, 0, 0, 1100, 10, true);
tst_select_small(bqm, 7, 3, 1001, 10, true);
tst_select_small(bqm, 1000, 10, 1001, 10, true);
scoped_mpbq l1(bqm);
l1 = 11;
bqm.power(l1, 64, l1);
scoped_mpbq l2(bqm);
l2 = l1 + 1;
bqm.div2k(l1, 64*3);
bqm.div2k(l2, 64*3);
tst_select_small(bqm, l1, l2, true);
l1 = 11;
bqm.power(l1, 64, l1);
l2 = l1 + 256;
bqm.div2k(l1, 64*3);
bqm.div2k(l2, 64*3);
tst_select_small(bqm, l1, l2, true);
}
static void tst_eval_sign(polynomial_ref const & p, anum_manager & am,
polynomial::var x0, anum const & v0, polynomial::var x1, anum const & v1, polynomial::var x2, anum const & v2,
int expected) {
polynomial::simple_var2value<anum_manager> x2v(am);
x2v.push_back(x0, v0);
x2v.push_back(x1, v1);
x2v.push_back(x2, v2);
std::cout << "--------------\n";
std::cout << "p: " << p << "\n";
std::cout << "x0 -> "; am.display_root(std::cout, v0); std::cout << "\n";
std::cout << "x1 -> "; am.display_root(std::cout, v1); std::cout << "\n";
std::cout << "x2 -> "; am.display_root(std::cout, v2); std::cout << "\n";
int s = am.eval_sign_at(p, x2v);
SASSERT((s == 0) == (expected == 0));
SASSERT((s < 0) == (expected < 0));
SASSERT((s > 0) == (expected > 0));
std::cout << "sign: " << s << "\n";
}
static void tst_eval_sign() {
enable_trace("anum_eval_sign");
unsynch_mpq_manager qm;
polynomial::manager pm(qm);
algebraic_numbers::manager am(qm);
polynomial_ref x0(pm);
polynomial_ref x1(pm);
polynomial_ref x2(pm);
x0 = pm.mk_polynomial(pm.mk_var());
x1 = pm.mk_polynomial(pm.mk_var());
x2 = pm.mk_polynomial(pm.mk_var());
polynomial_ref p(pm);
p = x0*x1 + (x1^2) + x2 + 2;
scoped_anum v0(am), v1(am), v2(am);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1);
am.set(v2, -2);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 0);
am.set(v1, 1);
am.set(v0, -3);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1);
am.set(v0, 2);
am.root(v0, 2, v0);
am.set(v1, 0);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 0);
am.set(v2, 1);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1);
am.set(v2, -3);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1);
am.set(v1, 1);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1);
am.set(v2, -4);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1);
am.set(v2, -5);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1);
am.set(v2, -2);
am.set(v1, v0);
am.neg(v1);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 0);
am.set(v2, -3);
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, -1);
p = x0*x1 + (x1^2) - x2 + 2;
tst_eval_sign(p, am, 0, v0, 1, v1, 2, v2, 1);
}
static void tst_isolate_roots(polynomial_ref const & p, anum_manager & am,
polynomial::var x0, anum const & v0, polynomial::var x1, anum const & v1, polynomial::var x2, anum const & v2) {
polynomial::simple_var2value<anum_manager> x2v(am);
x2v.push_back(x0, v0);
x2v.push_back(x1, v1);
x2v.push_back(x2, v2);
std::cout << "--------------\n";
std::cout << "p: " << p << "\n";
std::cout << "x0 -> "; am.display_root(std::cout, v0); std::cout << "\n";
std::cout << "x1 -> "; am.display_root(std::cout, v1); std::cout << "\n";
std::cout << "x2 -> "; am.display_root(std::cout, v2); std::cout << "\n";
scoped_anum_vector roots(am);
svector<int> signs;
am.isolate_roots(p, x2v, roots, signs);
SASSERT(roots.size() + 1 == signs.size());
std::cout << "roots:\n";
for (unsigned i = 0; i < roots.size(); i++) {
am.display_root(std::cout, roots[i]); std::cout << " "; am.display_decimal(std::cout, roots[i]); std::cout << "\n";
}
std::cout << "signs:\n";
for (unsigned i = 0; i < signs.size(); i++) {
if (i > 0)
std::cout << " 0 ";
if (signs[i] < 0) std::cout << "-";
else if (signs[i] == 0) std::cout << "0";
else std::cout << "+";
}
std::cout << "\n";
}
static void tst_isolate_roots() {
enable_trace("isolate_roots");
unsynch_mpq_manager qm;
polynomial::manager pm(qm);
algebraic_numbers::manager am(qm);
polynomial_ref x0(pm);
polynomial_ref x1(pm);
polynomial_ref x2(pm);
polynomial_ref x3(pm);
x0 = pm.mk_polynomial(pm.mk_var());
x1 = pm.mk_polynomial(pm.mk_var());
x2 = pm.mk_polynomial(pm.mk_var());
x3 = pm.mk_polynomial(pm.mk_var());
polynomial_ref p(pm);
p = x3*x1 + 1;
scoped_anum v0(am), v1(am), v2(am);
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
am.set(v1, 1);
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
am.set(v1, 2);
am.root(v1, 2, v1);
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x1 + x2)*x3 + 1;
am.set(v2, v1);
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x1 + x2)*x3 + x1*x2 + 2;
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x1 + x2)*(x3^3) + x1*x2 + 2;
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x1 + x2)*(x3^2) - x1*x2 - 2;
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = x0*(x1 + x2)*(x3^2) - x0*x1*x2 - 2;
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x1 - x2)*x3 + x1*x2 - 2;
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x1 - x2)*(x3^3) + x1*x2 - 2;
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x3 - x0)*(x3 - x0 - x1);
am.set(v0, 2);
am.root(v0, 2, v0); // x2 -> sqrt(2)
am.set(v1, 3);
am.root(v1, 2, v1); // x1 -> sqrt(3)
am.reset(v2);
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x3 - x0)*((x3 - x0 - x1)^2);
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
p = (x3 - x0)*(x3 - 2)*((x3 - 1)^2)*(x3 - x1);
tst_isolate_roots(p, am, 0, v0, 1, v1, 2, v2);
}
static void pp(polynomial_ref const & p, polynomial::var x) {
unsigned d = degree(p, x);
for (unsigned i = 0; i <= d; i++) {
std::cout << "(" << coeff(p, x, i) << ") ";
}
std::cout << "\n";
}
static void ex1() {
unsynch_mpq_manager qm;
polynomial::manager pm(qm);
polynomial_ref x(pm);
polynomial_ref a(pm);
polynomial_ref b(pm);
polynomial_ref c(pm);
x = pm.mk_polynomial(pm.mk_var());
a = pm.mk_polynomial(pm.mk_var());
b = pm.mk_polynomial(pm.mk_var());
c = pm.mk_polynomial(pm.mk_var());
polynomial_ref p(pm);
p = (a + 2*b)*(x^3) + x*a + (b^2);
polynomial_ref p1(pm);
p1 = derivative(p, 0);
polynomial_ref h2(pm);
unsigned d;
h2 = pseudo_remainder(p, p1, 0, d);
std::cout << "d: " << d << "\n";
std::cout << "p: "; pp(p, 0); std::cout << "\np': "; pp(p1, 0); std::cout << "\nh2: "; pp(h2, 0); std::cout << "\n";
polynomial_ref h3(pm);
h3 = pseudo_remainder(p1, h2, 0, d);
std::cout << "d: " << d << "\n";
std::cout << "h3: "; pp(h3, 0); std::cout << "\n";
algebraic_numbers::manager am(qm);
scoped_anum v1(am), v2(am);
am.set(v1, 2);
am.root(v1, 3, v1);
am.set(v2, 3);
am.root(v2, 3, v2);
polynomial::simple_var2value<anum_manager> x2v(am);
x2v.push_back(1, v1);
x2v.push_back(2, v2);
std::cout << "sign(h3(v1,v2)): " << am.eval_sign_at(h3, x2v) << "\n";
scoped_anum v0(am);
am.set(v0, -1);
x2v.push_back(0, v0);
std::cout << "sign(h2(v1,v2)): " << am.eval_sign_at(h2, x2v) << "\n";
std::cout << "sign(p'(v1,v2)): " << am.eval_sign_at(p1, x2v) << "\n";
std::cout << "sign(p(v1,v2)): " << am.eval_sign_at(p, x2v) << "\n";
polynomial::simple_var2value<anum_manager> x2v2(am);
x2v2.push_back(1, v1);
x2v2.push_back(2, v2);
scoped_mpq tmp(qm);
qm.set(tmp, -1);
qm.div(tmp, mpz(2), tmp);
std::cout << "tmp: "; qm.display(std::cout, tmp); std::cout << " "; qm.display_decimal(std::cout, tmp, 10); std::cout << "\n";
am.set(v0, tmp);
x2v2.push_back(0, v0);
std::cout << "v0: " << v0 << "\n";
std::cout << "sign(h2(v1,v2)): " << am.eval_sign_at(h2, x2v2) << "\n";
std::cout << "sign(p'(v1,v2)): " << am.eval_sign_at(p1, x2v2) << "\n";
std::cout << "sign(p(v1,v2)): " << am.eval_sign_at(p, x2v2) << "\n";
}
static void tst_root() {
unsynch_mpq_manager qm;
algebraic_numbers::manager am(qm);
scoped_anum v1(am), v2(am);
am.set(v1, 4);
am.root(v1, 2, v2);
std::cout << "root: " << v2 << "\n";
am.set(v1, 4);
am.root(v1, 4, v2);
std::cout << "root: " << root_obj_pp(v2) << "\n";
}
void tst_algebraic() {
// enable_trace("resultant_bug");
// enable_trace("poly_sign");
disable_trace("algebraic");
// enable_trace("mpbq_bug");
// enable_trace("mpz_mul2k");
// enable_trace("mpz_gcd");
tst_root();
tst_isolate_roots();
ex1();
tst_eval_sign();
tst_select_small();
tst_dejan();
tst_wilkinson();
tst1();
tst_refine_mpbq();
}

458
src/test/api.cpp Normal file
View file

@ -0,0 +1,458 @@
#ifdef _WINDOWS
#include "z3.h"
#include "z3_private.h"
#include <iostream>
#include "util.h"
#include "trace.h"
#include <map>
#include "trace.h"
void bv_invariant() {
#define SET(_i, _v) m[_i] = _v
#define GET(_ty,_i) reinterpret_cast<_ty>(m[_i])
std::map<int, void*> m;
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg,"MODEL","true");
Z3_context ctx = Z3_mk_context(cfg);
Z3_model _m = 0;
enable_trace("after_internalization");
enable_trace("final_check");
enable_trace("bv");
enable_trace("propagate_atoms");
enable_trace("assign_core");
enable_trace("bv_bug");
enable_trace("bv_bit_prop");
enable_trace("mark_as_relevant_core");
{SET(0x03BC7FD8, Z3_mk_bv_sort(ctx,32));}
{SET(0x03BCCD88, Z3_mk_int(ctx,0,GET(Z3_sort,0x03BC7FD8)));}
{SET(0x03BCCE08, Z3_mk_int(ctx,1,GET(Z3_sort,0x03BC7FD8)));}
{SET(0x03BC9428, Z3_mk_eq(ctx,GET(Z3_ast,0x03BCCD88),GET(Z3_ast,0x03BCCD88)));}
{SET(0x03CEC820, Z3_get_app_decl(ctx,GET(Z3_app,0x03BC9428)));}
{Z3_mk_string_symbol(ctx,"null");}
{Z3_mk_string_symbol(ctx,"isnull");}
{SET(0x03CEC870, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"null"),Z3_mk_string_symbol(ctx,"isnull"),0,0,0,0));}
{Z3_mk_string_symbol(ctx,"ArgumentException");}
{Z3_mk_string_symbol(ctx,"isArgumentException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC8C0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"ArgumentException"),Z3_mk_string_symbol(ctx,"isArgumentException"),1,args03CEE130,args03CEE160,args03CEE190));}
{Z3_mk_string_symbol(ctx,"String");}
{Z3_mk_string_symbol(ctx,"isString");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC910, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"String"),Z3_mk_string_symbol(ctx,"isString"),1,args03CEE130,args03CEE160,args03CEE190));}
{Z3_mk_string_symbol(ctx,"MethodBase");}
{Z3_mk_string_symbol(ctx,"isMethodBase");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC960, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"MethodBase"),Z3_mk_string_symbol(ctx,"isMethodBase"),1,args03CEE130,args03CEE160,args03CEE190));}
{Z3_mk_string_symbol(ctx,"Exception");}
{Z3_mk_string_symbol(ctx,"isException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CEC9B0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Exception"),Z3_mk_string_symbol(ctx,"isException"),1,args03CEE130,args03CEE160,args03CEE190));}
{Z3_mk_string_symbol(ctx,"Object");}
{Z3_mk_string_symbol(ctx,"isObject");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE130[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE160[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE190[1] = {0, }; SET(0x03CECA00, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Object"),Z3_mk_string_symbol(ctx,"isObject"),1,args03CEE130,args03CEE160,args03CEE190));}
{Z3_mk_string_symbol(ctx,"Box");}
{Z3_mk_string_symbol(ctx,"isBox");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03CECA50, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Term");}
{Z3_mk_string_symbol(ctx,"isTerm");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9430, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Term"),Z3_mk_string_symbol(ctx,"isTerm"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Box");}
{Z3_mk_string_symbol(ctx,"isBox");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9480, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"SystemException");}
{Z3_mk_string_symbol(ctx,"isSystemException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9520, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"SystemException"),Z3_mk_string_symbol(ctx,"isSystemException"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"RuntimeFieldHandle");}
{Z3_mk_string_symbol(ctx,"isRuntimeFieldHandle");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE94D0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"RuntimeFieldHandle"),Z3_mk_string_symbol(ctx,"isRuntimeFieldHandle"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Box");}
{Z3_mk_string_symbol(ctx,"isBox");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9570, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"RuntimeTypeHandle");}
{Z3_mk_string_symbol(ctx,"isRuntimeTypeHandle");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE95C0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"RuntimeTypeHandle"),Z3_mk_string_symbol(ctx,"isRuntimeTypeHandle"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Box");}
{Z3_mk_string_symbol(ctx,"isBox");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9610, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"NullReferenceException");}
{Z3_mk_string_symbol(ctx,"isNullReferenceException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9660, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"NullReferenceException"),Z3_mk_string_symbol(ctx,"isNullReferenceException"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"InvalidCastException");}
{Z3_mk_string_symbol(ctx,"isInvalidCastException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE96B0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"InvalidCastException"),Z3_mk_string_symbol(ctx,"isInvalidCastException"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"IndexOutOfRangeException");}
{Z3_mk_string_symbol(ctx,"isIndexOutOfRangeException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9700, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"IndexOutOfRangeException"),Z3_mk_string_symbol(ctx,"isIndexOutOfRangeException"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"StackOverflowException");}
{Z3_mk_string_symbol(ctx,"isStackOverflowException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9750, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"StackOverflowException"),Z3_mk_string_symbol(ctx,"isStackOverflowException"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"ExecutionEngineException");}
{Z3_mk_string_symbol(ctx,"isExecutionEngineException");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE97A0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"ExecutionEngineException"),Z3_mk_string_symbol(ctx,"isExecutionEngineException"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Box");}
{Z3_mk_string_symbol(ctx,"isBox");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE97F0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Box"),Z3_mk_string_symbol(ctx,"isBox"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Value");}
{Z3_mk_string_symbol(ctx,"isValue");}
{Z3_mk_string_symbol(ctx,"value");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"value"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9840, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Value"),Z3_mk_string_symbol(ctx,"isValue"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Value");}
{Z3_mk_string_symbol(ctx,"isValue");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE9890, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Value"),Z3_mk_string_symbol(ctx,"isValue"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Int32[]");}
{Z3_mk_string_symbol(ctx,"isInt32[]");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE160[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE190[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1C0[1] = {0, }; SET(0x03BE98E0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Int32[]"),Z3_mk_string_symbol(ctx,"isInt32[]"),1,args03CEE160,args03CEE190,args03CEE1C0));}
{Z3_mk_string_symbol(ctx,"Add");}
{Z3_mk_string_symbol(ctx,"isAdd");}
{Z3_mk_string_symbol(ctx,"left");}
{Z3_mk_string_symbol(ctx,"right");}
{Z3_symbol args03BEA4A0[2] = {Z3_mk_string_symbol(ctx,"left"), Z3_mk_string_symbol(ctx,"right"), }; Z3_sort args03BEA548[2] = {GET(Z3_sort,0x00000000), GET(Z3_sort,0x00000000), }; unsigned args03BEA580[2] = {0, 0, }; SET(0x03BE9930, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Add"),Z3_mk_string_symbol(ctx,"isAdd"),2,args03BEA4A0,args03BEA548,args03BEA580));}
{Z3_mk_string_symbol(ctx,"Add");}
{Z3_mk_string_symbol(ctx,"isAdd");}
{Z3_mk_string_symbol(ctx,"refId");}
{Z3_symbol args03CEE190[1] = {Z3_mk_string_symbol(ctx,"refId"), }; Z3_sort args03CEE1C0[1] = {GET(Z3_sort,0x03BC7FD8), }; unsigned args03CEE1F0[1] = {0, }; SET(0x03BE9980, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"Add"),Z3_mk_string_symbol(ctx,"isAdd"),1,args03CEE190,args03CEE1C0,args03CEE1F0));}
{Z3_mk_string_symbol(ctx,"address");}
{Z3_mk_string_symbol(ctx,"isaddress");}
{Z3_mk_string_symbol(ctx,"enc");}
{Z3_mk_string_symbol(ctx,"value1");}
{Z3_mk_string_symbol(ctx,"value2");}
{Z3_symbol args03BEA580[3] = {Z3_mk_string_symbol(ctx,"enc"), Z3_mk_string_symbol(ctx,"value1"), Z3_mk_string_symbol(ctx,"value2"), }; Z3_sort args03BEA628[3] = {GET(Z3_sort,0x03BC7FD8), GET(Z3_sort,0x00000000), GET(Z3_sort,0x00000000), }; unsigned args03BEA660[3] = {0, 0, 0, }; SET(0x03BE99D0, Z3_mk_constructor(ctx,Z3_mk_string_symbol(ctx,"address"),Z3_mk_string_symbol(ctx,"isaddress"),3,args03BEA580,args03BEA628,args03BEA660));}
{Z3_mk_string_symbol(ctx,"object");}
{Z3_constructor args03BEAC18[25] = {GET(Z3_constructor,0x03CEC870), GET(Z3_constructor,0x03CEC8C0), GET(Z3_constructor,0x03CEC910), GET(Z3_constructor,0x03CEC960), GET(Z3_constructor,0x03CEC9B0), GET(Z3_constructor,0x03CECA00), GET(Z3_constructor,0x03CECA50), GET(Z3_constructor,0x03BE9430), GET(Z3_constructor,0x03BE9480), GET(Z3_constructor,0x03BE9520), GET(Z3_constructor,0x03BE94D0), GET(Z3_constructor,0x03BE9570), GET(Z3_constructor,0x03BE95C0), GET(Z3_constructor,0x03BE9610), GET(Z3_constructor,0x03BE9660), GET(Z3_constructor,0x03BE96B0), GET(Z3_constructor,0x03BE9700), GET(Z3_constructor,0x03BE9750), GET(Z3_constructor,0x03BE97A0), GET(Z3_constructor,0x03BE97F0), GET(Z3_constructor,0x03BE9840), GET(Z3_constructor,0x03BE9890), GET(Z3_constructor,0x03BE98E0), GET(Z3_constructor,0x03BE9930), GET(Z3_constructor,0x03BE9980), }; SET(0x03CEE1C0, Z3_mk_constructor_list(ctx,25,args03BEAC18));}
{Z3_mk_string_symbol(ctx,"address");}
{Z3_constructor args03CEE1F0[1] = {GET(Z3_constructor,0x03BE99D0), }; SET(0x03CEE220, Z3_mk_constructor_list(ctx,1,args03CEE1F0));}
{Z3_symbol args03BEA580[2] = {Z3_mk_string_symbol(ctx,"object"), Z3_mk_string_symbol(ctx,"address"), }; Z3_sort args03BEA660[2] = {GET(Z3_sort,0x03BCD088), GET(Z3_sort,0x03BCD0C8), }; Z3_constructor_list args03BEA628[2] = {GET(Z3_constructor_list,0x03CEE1C0), GET(Z3_constructor_list,0x03CEE220), }; Z3_mk_datatypes(ctx,2, args03BEA580, args03BEA660, args03BEA628);SET(0x03BCD088, args03BEA660[0]);SET(0x03BCD0C8, args03BEA660[1]);}
{Z3_del_constructor_list(ctx,GET(Z3_constructor_list,0x03CEE1C0));}
{Z3_del_constructor_list(ctx,GET(Z3_constructor_list,0x03CEE220));}
{Z3_func_decl out002DE0DC; Z3_func_decl out002DE0E0; Z3_query_constructor(ctx,GET(Z3_constructor,0x03CEC870), 0, &out002DE0DC, &out002DE0E0, 0);SET(0x03BEAC30, out002DE0DC);SET(0x03BEB2F0, out002DE0E0);}
{Z3_func_decl out002DE0E0; Z3_func_decl out002DE0E4; Z3_func_decl args03CEE220[1] = {GET(Z3_func_decl,0x03BEB380), }; Z3_query_constructor(ctx,GET(Z3_constructor,0x03BE9840), 1, &out002DE0E0, &out002DE0E4, args03CEE220);SET(0x03BEB1D0, out002DE0E0);SET(0x03BEB338, out002DE0E4);SET(0x03BEB380, args03CEE220[0]);}
{Z3_func_decl out002DE0E0; Z3_func_decl out002DE0E4; Z3_func_decl args03BEA580[2] = {0, GET(Z3_func_decl,0x03BEC478), }; Z3_query_constructor(ctx,GET(Z3_constructor,0x03BE9930), 2, &out002DE0E0, &out002DE0E4, args03BEA580);SET(0x03BE9A20, out002DE0E0);SET(0x03BEB3C8, out002DE0E4);SET(0x03BEC430, args03BEA580[0]);SET(0x03BEC478, args03BEA580[1]); }
{Z3_func_decl out002DE0DC; Z3_func_decl out002DE0E0; Z3_func_decl args03BEA580[3] = {GET(Z3_func_decl,0x03BEC508), GET(Z3_func_decl,0x03BEC550), GET(Z3_func_decl,0x03BEC598), }; Z3_query_constructor(ctx,GET(Z3_constructor,0x03BE99D0), 3, &out002DE0DC, &out002DE0E0, args03BEA580);SET(0x03BE9A70, out002DE0DC);SET(0x03BEC4C0, out002DE0E0);SET(0x03BEC508, args03BEA580[0]);SET(0x03BEC550, args03BEA580[1]);SET(0x03BEC598, args03BEA580[2]);}
{SET(0x03BEB7F0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEAC30),0,0));}
{SET(0x03BCD088, Z3_get_domain(ctx,GET(Z3_func_decl,0x03BEC430),0));}
{SET(0x03BEB4F0, Z3_mk_bound(ctx,0,GET(Z3_sort,0x03BCD088)));}
{Z3_ast args03CEE220[1] = {GET(Z3_ast,0x03BEB4F0), }; SET(0x03BEC5E0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC430),1,args03CEE220));}
{SET(0x03BEB4F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC5E0),0));}
{SET(0x03BEC628, Z3_mk_eq(ctx,GET(Z3_ast,0x03BEC5E0),GET(Z3_ast,0x03BEB7F0)));}
{SET(0x03BE9AC0, Z3_get_app_decl(ctx,GET(Z3_app,0x03BEC628)));}
{Z3_ast args03CEE220[1] = {GET(Z3_ast,0x03BEC5E0), }; SET(0x03BEC670, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03CEE220));}
{Z3_ast args03CEE220[1] = {GET(Z3_ast,0x03BEC5E0), }; SET(0x03BEC6B8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB3C8),1,args03CEE220));}
{Z3_ast args03BEA580[2] = {GET(Z3_ast,0x03BEC670), GET(Z3_ast,0x03BEC6B8), }; SET(0x03BEC700, Z3_mk_or(ctx,2,args03BEA580));}
{SET(0x03BEC670, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC700),0));}
{SET(0x03BEC6B8, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC700),1));}
{Z3_ast args03BEA580[3] = {GET(Z3_ast,0x03BEC670), GET(Z3_ast,0x03BEC6B8), GET(Z3_ast,0x03BEC628), }; SET(0x03BE9B10, Z3_mk_or(ctx,3,args03BEA580));}
{Z3_mk_string_symbol(ctx,"x0");}
{Z3_sort args03CEE250[1] = {GET(Z3_sort,0x03BCD088), }; Z3_symbol args03CEE1F0[1] = {Z3_mk_string_symbol(ctx,"x0"), }; SET(0x03BED418, Z3_mk_quantifier(ctx,1,0,0,0,1,args03CEE250,args03CEE1F0,GET(Z3_ast,0x03BE9B10)));}
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BED418));}
{SET(0x03BCD088, Z3_get_domain(ctx,GET(Z3_func_decl,0x03BEC478),0));}
{Z3_ast args03CEE1F0[1] = {GET(Z3_ast,0x03BEB4F0), }; SET(0x03BEC790, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC478),1,args03CEE1F0));}
{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BEC790), GET(Z3_ast,0x03BEB7F0), }; SET(0x03BEC820, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BEAB30));}
{Z3_ast args03CEE1F0[1] = {GET(Z3_ast,0x03BEC790), }; SET(0x03BEC868, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03CEE1F0));}
{Z3_ast args03CEE1F0[1] = {GET(Z3_ast,0x03BEC790), }; SET(0x03BEC8B0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB3C8),1,args03CEE1F0));}
{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BEC868), GET(Z3_ast,0x03BEC8B0), }; SET(0x03BEC8F8, Z3_mk_or(ctx,2,args03BEAB30));}
{SET(0x03BEC868, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC8F8),0));}
{SET(0x03BEC8B0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC8F8),1));}
{Z3_ast args03BEAB30[3] = {GET(Z3_ast,0x03BEC868), GET(Z3_ast,0x03BEC8B0), GET(Z3_ast,0x03BEC820), }; SET(0x03BE9BB0, Z3_mk_or(ctx,3,args03BEAB30));}
{Z3_mk_string_symbol(ctx,"x0");}
{Z3_sort args03CEE280[1] = {GET(Z3_sort,0x03BCD088), }; Z3_symbol args03CEE2B0[1] = {Z3_mk_string_symbol(ctx,"x0"), }; SET(0x03BEE758, Z3_mk_quantifier(ctx,1,0,0,0,1,args03CEE280,args03CEE2B0,GET(Z3_ast,0x03BE9BB0)));}
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BEE758));}
{SET(0x03BEB8F0, Z3_mk_fresh_const(ctx,"x",GET(Z3_sort,0x03BCD088)));}
{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03BEC9D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BEAB30));}
{Z3_ast args03CEE2B0[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BECA18, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03CEE2B0));}
{Z3_ast args03CEE2B0[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BECA60, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB3C8),1,args03CEE2B0));}
{Z3_ast args03BEAB30[2] = {GET(Z3_ast,0x03BECA18), GET(Z3_ast,0x03BECA60), }; SET(0x03BECAA8, Z3_mk_or(ctx,2,args03BEAB30));}
{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03BECAA8),0));}
{SET(0x03BECA60, Z3_get_app_arg(ctx,GET(Z3_app,0x03BECAA8),1));}
{Z3_ast args03BEAB30[3] = {GET(Z3_ast,0x03BECA18), GET(Z3_ast,0x03BECA60), GET(Z3_ast,0x03BEC9D0), }; SET(0x03BE9C50, Z3_mk_or(ctx,3,args03BEAB30));}
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BE9C50));}
Z3_push(ctx);
{(Z3_check_and_get_model(ctx,0));}
{SET(0x03BFD780, Z3_mk_int(ctx,2,GET(Z3_sort,0x03BC7FD8)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFD780), 10);}
{SET(0x03C0DC08, Z3_mk_not(ctx,GET(Z3_ast,0x03BEC9D0)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DC08), 10);}
{SET(0x03C094A0, Z3_mk_ite(ctx,GET(Z3_ast,0x03BECA18),GET(Z3_ast,0x03BEB8F0),GET(Z3_ast,0x03BEB7F0)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C094A0), 10);}
{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094A0),0));}
{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094A0),1));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094A0),2));}
{SET(0x03C0DC50, Z3_mk_not(ctx,GET(Z3_ast,0x03BECA18)));}
{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC50),0));}
{Z3_ast args03C03310[1] = {GET(Z3_ast,0x03BEC9D0), }; SET(0x03C0DC98, Z3_mk_or(ctx,1,args03C03310));}
{SET(0x03C0DCE0, Z3_mk_implies(ctx,GET(Z3_ast,0x03BECA18),GET(Z3_ast,0x03C0DC98)));}
{SET(0x03C0DD28, Z3_mk_not(ctx,GET(Z3_ast,0x03C0DCE0)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DD28), 10);}
{SET(0x03C0DCE0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD28),0));}
{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),0));}
{SET(0x03C0DC98, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),1));}
{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC98),0));}
{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),0));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),1));}
{Z3_ast args03C07F90[3] = {GET(Z3_ast,0x03BCCE08), GET(Z3_ast,0x03BEB7F0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C094F0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9A70),3,args03C07F90));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C094F0), 10);}
{Z3_ast args03C07F90[3] = {GET(Z3_ast,0x03BFD780), GET(Z3_ast,0x03BEB7F0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C09540, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9A70),3,args03C07F90));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C09540), 10);}
{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),0));}
{SET(0x03C0DC98, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),1));}
{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC98),0));}
{Z3_pop(ctx,1);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BECA18), GET(Z3_ast,0x03BEC9D0), }; SET(0x03BFF5D8, Z3_mk_or(ctx,2,args03BFED58));}
{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFF5D8),0));}
{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFF5D8),1));}
{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),0));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),1));}
Z3_push(ctx);
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03C0D980, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB380),1,args03BC3DF8));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0D980), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0D980), GET(Z3_ast,0x03BCCE08), }; SET(0x03C0D9C8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0D9C8), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0D980), GET(Z3_ast,0x03BFD780), }; SET(0x03C0DD70, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DD70), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0D9C8), GET(Z3_ast,0x03C0DD70), }; SET(0x03C0DDB8, Z3_mk_or(ctx,2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DDB8), 10);}
{SET(0x03C0DCE0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD28),0));}
{SET(0x03BECA18, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),0));}
{SET(0x03C0DC98, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DCE0),1));}
{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DC98),0));}
{Z3_pop(ctx,1);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BECA60), GET(Z3_ast,0x03BEC9D0), }; SET(0x03C0DE00, Z3_mk_or(ctx,2,args03BFED58));}
{SET(0x03BECA60, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE00),0));}
{SET(0x03BEC9D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE00),1));}
{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),0));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEC9D0),1));}
Z3_push(ctx);
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BFF590, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC430),1,args03BC3DF8));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFF590), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF590), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C0DE90, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DE90), 10);}
{SET(0x03C0DE48, Z3_mk_not(ctx,GET(Z3_ast,0x03C0DE90)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DE48), 10);}
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF590), }; SET(0x03BFFC08, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03BC3DF8));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFFC08), 10);}
{SET(0x03C00440, Z3_mk_ite(ctx,GET(Z3_ast,0x03BFFC08),GET(Z3_ast,0x03BFF590),GET(Z3_ast,0x03BEB7F0)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C00440), 10);}
{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00440),0));}
{SET(0x03BFF590, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00440),1));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00440),2));}
{SET(0x03C0DED8, Z3_mk_not(ctx,GET(Z3_ast,0x03BFFC08)));}
{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DED8),0));}
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03C0DE90), }; SET(0x03C0DF20, Z3_mk_or(ctx,1,args03BC3DF8));}
{SET(0x03C0DF68, Z3_mk_implies(ctx,GET(Z3_ast,0x03BFFC08),GET(Z3_ast,0x03C0DF20)));}
{SET(0x03C0DFB0, Z3_mk_not(ctx,GET(Z3_ast,0x03C0DF68)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0DFB0), 10);}
{SET(0x03C0DF68, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DFB0),0));}
{SET(0x03BCCE08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094F0),0));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094F0),1));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C094F0),2));}
{SET(0x03BFD780, Z3_get_app_arg(ctx,GET(Z3_app,0x03C09540),0));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C09540),1));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C09540),2));}
{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DF68),0));}
{SET(0x03C0DF20, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DF68),1));}
{SET(0x03C0DE90, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DF20),0));}
{Z3_pop(ctx,1);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFFC08), GET(Z3_ast,0x03C0DE90), }; SET(0x03C0DFF8, Z3_mk_or(ctx,2,args03BFED58));}
{SET(0x03BFFC08, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DFF8),0));}
{SET(0x03C0DE90, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DFF8),1));}
{SET(0x03BFF590, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFFC08),0));}
{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03BFF590),0));}
{SET(0x03BFF590, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE90),0));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DE90),1));}
Z3_push(ctx);
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF590), }; SET(0x03C0E040, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB380),1,args03BC3DF8));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E040), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E040), GET(Z3_ast,0x03BCCE08), }; SET(0x03C0E088, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E088), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E040), GET(Z3_ast,0x03BFD780), }; SET(0x03C0E0D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E0D0), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E088), GET(Z3_ast,0x03C0E0D0), }; SET(0x03C0E118, Z3_mk_or(ctx,2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E118), 10);}
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BEB8F0), }; SET(0x03BFF7D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEC478),1,args03BC3DF8));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFF7D0), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF7D0), GET(Z3_ast,0x03BEB7F0), }; SET(0x03C0E1A8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E1A8), 10);}
{SET(0x03C0E160, Z3_mk_not(ctx,GET(Z3_ast,0x03C0E1A8)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E160), 10);}
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF7D0), }; SET(0x03BFF980, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB338),1,args03BC3DF8));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03BFF980), 10);}
{SET(0x03C00580, Z3_mk_ite(ctx,GET(Z3_ast,0x03BFF980),GET(Z3_ast,0x03BFF7D0),GET(Z3_ast,0x03BEB7F0)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C00580), 10);}
{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00580),0));}
{SET(0x03BFF7D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00580),1));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C00580),2));}
{SET(0x03C0E1F0, Z3_mk_not(ctx,GET(Z3_ast,0x03BFF980)));}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E1A8), GET(Z3_ast,0x03C0E1F0), }; SET(0x03C0E238, Z3_mk_or(ctx,2,args03BFED58));}
{SET(0x03C0E1A8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E238),0));}
{SET(0x03C0E1F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E238),1));}
{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E1F0),0));}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF980), GET(Z3_ast,0x03C0E160), }; SET(0x03C0E280, Z3_mk_and(ctx,2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E280), 10);}
{SET(0x03C0E2C8, Z3_mk_not(ctx,GET(Z3_ast,0x03C0E280)));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E2C8), 10);}
{SET(0x03C0E280, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E2C8),0));}
{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),0));}
{SET(0x03C0E160, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),1));}
{SET(0x03C0E1A8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E160),0));}
{Z3_pop(ctx,1);}
Z3_push(ctx);
{Z3_pop(ctx,1);}
{SET(0x03C0E280, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E2C8),0));}
{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),0));}
{SET(0x03C0E160, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),1));}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BFF980), GET(Z3_ast,0x03C0E1A8), }; SET(0x03C0E310, Z3_mk_or(ctx,2,args03BFED58));}
{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E310),0));}
{SET(0x03C0E1A8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E310),1));}
{SET(0x03BFF7D0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E1A8),0));}
{SET(0x03BEB7F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E1A8),1));}
Z3_push(ctx);
{Z3_ast args03BC3DF8[1] = {GET(Z3_ast,0x03BFF7D0), }; SET(0x03C0E358, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BEB380),1,args03BC3DF8));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E358), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E358), GET(Z3_ast,0x03BCCE08), }; SET(0x03C0E3A0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E3A0), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E358), GET(Z3_ast,0x03BFD780), }; SET(0x03C0E3E8, Z3_mk_app(ctx,GET(Z3_func_decl,0x03CEC820),2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C0E3E8), 10);}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0E3A0), GET(Z3_ast,0x03C0E3E8), }; SET(0x03BEEC08, Z3_mk_or(ctx,2,args03BFED58));}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03BEEC08), 10);}
{SET(0x03C0DCE0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD28),0));}
{Z3_pop(ctx,1);}
Z3_push(ctx);
{SET(0x03C0E280, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E2C8),0));}
{SET(0x03BFF980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),0));}
{SET(0x03C0E160, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0E280),1));}
{Z3_pop(ctx,1);}
{Z3_ast args03BEEC50[7] = {GET(Z3_ast,0x03BFF980), GET(Z3_ast,0x03C0DE48), GET(Z3_ast,0x03C0DFB0), GET(Z3_ast,0x03C0DCE0), GET(Z3_ast,0x03C0E118), GET(Z3_ast,0x03C0E160), GET(Z3_ast,0x03BEEC08), }; SET(0x03BEE6E8, Z3_mk_and(ctx,7,args03BEEC50));}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03C0DD28), GET(Z3_ast,0x03C0DDB8), }; SET(0x03BEEC50, Z3_mk_and(ctx,2,args03BFED58));}
{Z3_ast args03BFED58[2] = {GET(Z3_ast,0x03BEE6E8), GET(Z3_ast,0x03BEEC50), }; SET(0x03BEEC98, Z3_mk_or(ctx,2,args03BFED58));}
{SET(0x03BEE6E8, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC98),0));}
{SET(0x03BEEC50, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC98),1));}
{SET(0x03C0DD28, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC50),0));}
{SET(0x03C0DDB8, Z3_get_app_arg(ctx,GET(Z3_app,0x03BEEC50),1));}
{SET(0x03C0D9C8, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DDB8),0));}
{SET(0x03C0DD70, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DDB8),1));}
{SET(0x03C0D980, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD70),0));}
{SET(0x03BFD780, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0DD70),1));}
{SET(0x03BEB8F0, Z3_get_app_arg(ctx,GET(Z3_app,0x03C0D980),0));}
Z3_push(ctx);
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C0DC08));}
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03BEEC98));}
Z3_push(ctx);
{(Z3_check_and_get_model(ctx,&_m));}
{Z3_ast out002DE120; Z3_eval(ctx,_m, GET(Z3_ast,0x03BEB8F0), &out002DE120);SET(0x03C14AE8, out002DE120);}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C14AE8), 2);}
{Z3_ast args03C123F8[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03C14AE8), }; SET(0x03C14B78, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03C123F8));}
{Z3_ast args03BC3F18[1] = {GET(Z3_ast,0x03C14B78), }; SET(0x03C14B30, Z3_mk_and(ctx,1,args03BC3F18));}
{SET(0x03C14BC0, Z3_mk_not(ctx,GET(Z3_ast,0x03C14B30)));}
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C14BC0));}
{(Z3_check_and_get_model(ctx,&_m));}
{Z3_ast out002DE120; Z3_eval(ctx,_m, GET(Z3_ast,0x03BEB8F0), &out002DE120);SET(0x03C127D0, out002DE120);}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C127D0), 2);}
{Z3_ast args03C037E8[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03C127D0), }; SET(0x03C028D0, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03C037E8));}
{Z3_ast args03BC3EE8[1] = {GET(Z3_ast,0x03C028D0), }; SET(0x03C1F100, Z3_mk_and(ctx,1,args03BC3EE8));}
{SET(0x03C1F148, Z3_mk_not(ctx,GET(Z3_ast,0x03C1F100)));}
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C1F148));}
{(Z3_check_and_get_model(ctx,&_m));}
{Z3_ast out002DE120; Z3_eval(ctx,_m, GET(Z3_ast,0x03BEB8F0), &out002DE120);SET(0x03C1F5C8, out002DE120);}
{Z3_persist_ast(ctx,GET(Z3_ast,0x03C1F5C8), 2);}
{Z3_ast args03C05F78[2] = {GET(Z3_ast,0x03BEB8F0), GET(Z3_ast,0x03C1F5C8), }; SET(0x03C23580, Z3_mk_app(ctx,GET(Z3_func_decl,0x03BE9AC0),2,args03C05F78));}
{Z3_ast args03CEE490[1] = {GET(Z3_ast,0x03C23580), }; SET(0x03C23538, Z3_mk_and(ctx,1,args03CEE490));}
{SET(0x03C235C8, Z3_mk_not(ctx,GET(Z3_ast,0x03C23538)));}
{Z3_assert_cnstr(ctx,GET(Z3_ast,0x03C235C8));}
//{Z3_check(ctx);}
}
void test_apps() {
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg,"MODEL","true");
Z3_context ctx = Z3_mk_context(cfg);
Z3_symbol A = Z3_mk_string_symbol(ctx, "A");
Z3_symbol F = Z3_mk_string_symbol(ctx, "f");
Z3_sort SA = Z3_mk_uninterpreted_sort(ctx, A);
Z3_func_decl f = Z3_mk_func_decl(ctx, F, 1, &SA, SA);
Z3_symbol X = Z3_mk_string_symbol(ctx, "x");
Z3_ast x = Z3_mk_const(ctx, X, SA);
Z3_ast fx = Z3_mk_app(ctx, f, 1, &x);
Z3_ast ffx = Z3_mk_app(ctx, f, 1, &fx);
Z3_ast fffx = Z3_mk_app(ctx, f, 1, &ffx);
Z3_ast ffffx = Z3_mk_app(ctx, f, 1, &fffx);
Z3_ast fffffx = Z3_mk_app(ctx, f, 1, &ffffx);
Z3_ast fml = Z3_mk_not(ctx, Z3_mk_eq(ctx, x, fffffx));
Z3_assert_cnstr(ctx, fml);
Z3_lbool r = Z3_check(ctx);
std::cout << r << "\n";
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_bvneg() {
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg,"MODEL","true");
Z3_context ctx = Z3_mk_context(cfg);
{
Z3_sort bv30 = Z3_mk_bv_sort(ctx, 30);
Z3_ast x30 = Z3_mk_fresh_const(ctx, "x", bv30);
Z3_ast fml = Z3_mk_eq(ctx, Z3_mk_int(ctx, -1, bv30),
Z3_mk_bvadd(ctx, Z3_mk_int(ctx, 0, bv30),
x30));
Z3_assert_cnstr(ctx, fml);
Z3_lbool r = Z3_check(ctx);
std::cout << r << "\n";
}
{
Z3_sort bv31 = Z3_mk_bv_sort(ctx, 31);
Z3_ast x31 = Z3_mk_fresh_const(ctx, "x", bv31);
Z3_ast fml = Z3_mk_eq(ctx, Z3_mk_int(ctx, -1, bv31),
Z3_mk_bvadd(ctx, Z3_mk_int(ctx, 0, bv31),
x31));
Z3_assert_cnstr(ctx, fml);
Z3_lbool r = Z3_check(ctx);
std::cout << r << "\n";
}
{
Z3_sort bv32 = Z3_mk_bv_sort(ctx, 32);
Z3_ast x32 = Z3_mk_fresh_const(ctx, "x", bv32);
Z3_ast fml = Z3_mk_eq(ctx,
Z3_mk_int(ctx,-1, bv32),
Z3_mk_bvadd(ctx, Z3_mk_int(ctx, 0, bv32),
x32));
Z3_assert_cnstr(ctx, fml);
Z3_lbool r = Z3_check(ctx);
std::cout << r << "\n";
}
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void tst_api() {
test_apps();
test_bvneg();
bv_invariant();
}
#else
void tst_api() {
}
#endif

42
src/test/api_bug.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "z3.h"
#include "stdio.h"
void tst_api_bug() {
unsigned vmajor, vminor, vbuild, vrevision;
Z3_get_version(&vmajor, &vminor, &vbuild, &vrevision);
printf("Using Z3 Version %u.%u (build %u, revision %u)\n", vmajor, vminor, vbuild, vrevision);
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg, "MODEL", "true");
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort is = Z3_mk_int_sort(ctx);
Z3_sort ss = Z3_mk_set_sort(ctx, is);
Z3_ast e = Z3_mk_empty_set(ctx, is);
// { 42 }
Z3_ast fortytwo = Z3_mk_set_add(ctx, e, Z3_mk_int(ctx, 42, is));
// { 42, 43 }
Z3_ast fortythree = Z3_mk_set_add(ctx, fortytwo, Z3_mk_int(ctx, 43, is));
// { 42 } U { 42, 43 }
Z3_ast uargs[2] = { fortytwo, fortythree };
Z3_ast u = Z3_mk_set_union(ctx, 2, uargs);
Z3_symbol sym = Z3_mk_string_symbol(ctx, "mySet");
Z3_ast s = Z3_mk_const(ctx, sym, ss);
Z3_ast c = Z3_mk_eq(ctx, s, u);
Z3_push(ctx);
Z3_assert_cnstr(ctx, c);
Z3_model m;
printf("result %d\n", Z3_check_and_get_model(ctx, &m));
Z3_string ms = Z3_model_to_string(ctx, m);
printf("model : %s\n", ms);
}

View file

@ -0,0 +1,16 @@
#include "arith_rewriter.h"
#include "bv_decl_plugin.h"
#include "ast_pp.h"
void tst_arith_rewriter() {
ast_manager m;
m.register_decl_plugins();
arith_rewriter ar(m);
arith_util au(m);
expr_ref t1(m), t2(m), result(m);
t1 = au.mk_numeral(rational(0),false);
t2 = au.mk_numeral(rational(-3),false);
expr* args[2] = { t1, t2 };
ar.mk_mul(2, args, result);
std::cout << mk_pp(result, m) << "\n";
}

View file

@ -0,0 +1,67 @@
#include "arith_eq_solver.h"
#include "front_end_params.h"
typedef rational numeral;
typedef vector<numeral> row;
static void test_solve_integer_equations(
arith_eq_solver& asimp,
vector<row>& rows
)
{
row r_unsat;
if (asimp.solve_integer_equations(rows, r_unsat)) {
std::cout << "solved\n";
}
else {
std::cout << "not solved\n";
for (unsigned i = 0; i < r_unsat.size(); ++i) {
std::cout << " " << r_unsat[i];
}
std::cout << "\n";
}
}
void tst_arith_simplifier_plugin() {
front_end_params params;
ast_manager m;
arith_eq_solver asimp(m);
row r1;
row r2;
r1.push_back(numeral(1));
r1.push_back(numeral(2));
r1.push_back(numeral(1));
r1.push_back(numeral(2));
r2.push_back(numeral(1));
r2.push_back(numeral(2));
r2.push_back(numeral(1));
r2.push_back(numeral(2));
vector<row> rows;
rows.push_back(r1);
rows.push_back(r2);
#if 0
test_solve_integer_equations(asimp, rows);
rows[1][3] = numeral(3);
test_solve_integer_equations(asimp, rows);
#endif
rows[0][0] = numeral(1);
rows[0][1] = numeral(3);
rows[0][2] = numeral(0);
rows[0][3] = numeral(0);
rows[1][0] = numeral(1);
rows[1][1] = numeral(0);
rows[1][2] = numeral(3);
rows[1][3] = numeral(1);
test_solve_integer_equations(asimp, rows);
}

View file

@ -0,0 +1,53 @@
#include "array_property_expander.h"
#include "array_property_recognizer.h"
#include "smtparser.h"
#include "array_decl_plugin.h"
#include "ast_pp.h"
#include <sstream>
static void test_array_expand(ast_manager& m, expr* fml) {
std::cout << mk_pp(fml, m) << "\n";
expr_ref_vector result(m);
array_property_expander exp(m);
array_property_recognizer rec(m);
exp(1, &fml, result);
std::cout << mk_pp(result[0].get(), m) << "\n";
std::cout << rec(1, &fml) << "\n";
}
static void parse_string(char const* fml) {
ast_manager m;
m.register_plugin(symbol("array"), alloc(array_decl_plugin));
scoped_ptr<smtlib::parser> parser = smtlib::parser::create(m);
parser->initialize_smtlib();
std::ostringstream buffer;
buffer << "(benchmark array :status unknown :logic AUFLIA \n"
<< ":extrafuns ((A (Array Int Int)) (B (Array Int Int)))\n"
<< ":extrafuns ((C (Array Int (Array Int Int))))\n"
<< ":extrafuns ((D (Array Int Bool Int)))\n"
<< ":extrafuns ((i Int) (j Int))\n"
<< ":extrafuns ((f Int Int))\n"
<< ":formula " << fml << ")";
parser->parse_string(buffer.str().c_str());
smtlib::benchmark* b = parser->get_benchmark();
smtlib::theory::expr_iterator it = b->begin_formulas();
smtlib::theory::expr_iterator end = b->end_formulas();
for (; it != end; ++it) {
test_array_expand(m, *it);
}
}
void tst_array_property_expander() {
parse_string("(= A B)");
parse_string("(= A (store B i 4))");
parse_string("(= C (store C 0 (store (select C 0) i 1)))");
parse_string("(exists (i Int) (= C (store C 0 (store (select C 0) i 1))))");
parse_string("(forall (i Int) (b Bool) (= D (store D i b 4)))");
parse_string("(= (const[Array] 3) A)");
parse_string("(= (map[f] A) B)");
}

157
src/test/ast.cpp Normal file
View file

@ -0,0 +1,157 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_ast.cpp
Abstract:
Test AST module
Author:
Leonardo de Moura (leonardo) 2006-09-29.
Revision History:
--*/
#include "ast.h"
static void tst1() {
ast_manager m;
family_id fid = m.get_basic_family_id();
sort_ref b(m.mk_bool_sort(), m);
expr_ref a(m.mk_const(symbol("a"), b.get()), m);
expr_ref c(m.mk_const(symbol("c"), b.get()), m);
expr_ref i1(m.mk_app(fid, OP_AND, a.get(), c.get()), m);
expr_ref i2(m.mk_app(fid, OP_AND, a.get(), c.get()), m);
expr_ref i3(m.mk_app(fid, OP_OR, a.get(), c.get()), m);
SASSERT(i1.get() == i2.get());
SASSERT(i1.get() != i3.get());
// TODO use smart pointers to track references
// ast_manager m;
// ast_ref<numeral_ast> n1(m.mk_numeral(rational(2,3)), m);
// ast_ref<numeral_ast> n2(m.mk_numeral(rational(2,3)), m);
// SASSERT(n1 == n2);
// ast_ref<numeral_ast> n3(m.mk_numeral(rational(1,2)), m);
// SASSERT(n1 != n3);
// ast_ref<var_ast> v1 (m.mk_var(1), m);
// ast_ref<var_ast> v2 (m.mk_var(2), m);
// ast_ref<var_ast> v3 (m.mk_var(1), m);
// SASSERT(v1 != v2);
// SASSERT(v1 == v3);
// TRACE("ast", tout << "reseting v1\n";);
// v1.reset();
// TRACE("ast", tout << "overwriting v3\n";);
// v3 = v2;
// ast_ref<type_decl_ast> t1(m.mk_type_decl(symbol("int"), 0), m);
// ast_ref<type_ast> i(m.mk_type(t1.get(), 0, 0), m);
// ast_ref<const_decl_ast> foo_decl(m.mk_const_decl(symbol("foo"), i.get(), i.get()), m);
// ast_ref<const_decl_ast> x_decl(m.mk_const_decl(symbol("x"), i.get()), m);
// ast_ref<const_ast> x(m.mk_const(x_decl.get()), m);
// ast_ref<const_ast> foo_x(m.mk_const(foo_decl.get(), x.get()), m);
// ast_ref<const_ast> foo_foo_x(m.mk_const(foo_decl.get(), foo_x.get()), m);
// ast_ref<const_ast> foo_foo_x2(m.mk_const(foo_decl.get(), m.mk_const(foo_decl.get(), m.mk_const(x_decl.get()))), m);
// SASSERT(foo_foo_x2 == foo_foo_x);
}
void tst2() {
// ast_manager m;
// ast_vector<ast> m_nodes(m);
// m_nodes.push_back(m.mk_var(1));
// m_nodes.push_back(m.mk_numeral(rational(1,2)));
// m_nodes.push_back(m.mk_var(2));
// m_nodes[1] = m.mk_var(3);
// SASSERT(m_nodes[1]->kind() == AST_VAR);
// SASSERT(m_nodes.get(1)->kind() == AST_VAR);
// m_nodes.pop_back();
// SASSERT(m_nodes.size() == 2);
// SASSERT(!m_nodes.empty());
// m_nodes.set(1, m.mk_var(4));
// SASSERT(&(m_nodes.get_manager()) == &m);
}
static void tst3() {
// ast_manager m;
// ast_ref<> n(m.mk_var(1), m);
// n = m.mk_var(1);
// TRACE("ast", tout << n->get_id() << "\n";);
}
static void tst4() {
// ast_manager m;
// ast_ref<> n1(m.mk_var(1), m);
// ast_ref<> n2(m.mk_var(2), m);
// ast_ref<> n3(m.mk_var(3), m);
// weak_memoize<int> wm1;
// #ifdef Z3DEBUG
// int r;
// #endif
// SASSERT(!wm1.find(n1, r));
// wm1.insert(n2, 10);
// SASSERT(!wm1.find(n1, r));
// SASSERT(wm1.find(n2, r) && r == 10);
// wm1.insert(n2, 20);
// SASSERT(!wm1.find(n1, r));
// SASSERT(wm1.find(n2, r) && r == 20);
// wm1.insert(n1, 0);
// SASSERT(wm1.find(n1, r) && r == 0);
// SASSERT(wm1.find(n2, r) && r == 20);
}
static void tst5() {
ast_manager m;
sort_ref b(m.mk_bool_sort(), m);
expr_ref a1(m.mk_const(symbol("a1"), b.get()), m);
expr_ref a2(m.mk_const(symbol("a2"), b.get()), m);
expr_array arr1;
expr_array arr2;
expr_array arr3;
m.push_back(arr1, a1);
m.push_back(arr1, a2);
m.pop_back(arr1, arr2);
m.set(arr2, 0, a2, arr3);
SASSERT(m.size(arr1) == 2);
SASSERT(m.size(arr2) == 1);
SASSERT(m.size(arr3) == 1);
SASSERT(m.get(arr1, 0) == a1);
SASSERT(m.get(arr1, 1) == a2);
SASSERT(m.get(arr2, 0) == a1);
SASSERT(m.get(arr3, 0) == a2);
m.del(arr1);
m.del(arr2);
m.del(arr3);
}
struct foo {
unsigned m_id;
unsigned short m_ref_count;
unsigned char m_kind;
unsigned char m_arity;
bool m_val1:1;
bool m_val2:1;
};
void tst_ast() {
TRACE("ast",
tout << "sizeof(ast): " << sizeof(ast) << "\n";
tout << "sizeof(expr): " << sizeof(expr) << "\n";
tout << "sizeof(app): " << sizeof(app) << "\n";
);
TRACE("ast", tout << "sizeof(foo): " << sizeof(foo) << "\n";);
tst1();
tst2();
tst3();
tst4();
tst5();
}

59
src/test/ast_pp.cpp Normal file
View file

@ -0,0 +1,59 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_ast_pp.cpp
Abstract:
Test AST Pretty printing module
Author:
Nikolaj Bjorner (nbjorner) 2006-10-5
Revision History:
--*/
#include "ast.h"
#include "ast_pp.h"
#include "ast_dag_pp.h"
#include "smtparser.h"
#include <iostream>
void tst_ast_pp()
{
ast_manager m;
smtlib::parser* parser = smtlib::parser::create(m);
parser->initialize_smtlib();
if (!parser->parse_string(
"(benchmark test :extrasorts (A B) :extrafuns ((f A A) (g A A A) (x A) (p A bool)) \n"
":formula (p (f x))\n"
":extrafuns ((x1 Int) (y1 Int))\n"
":formula (<= 1 (+ x1 y1))\n"
":formula (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (p (g x x))))))\n"
":formula (p x)\n"
")")) {
SASSERT(false);
dealloc(parser);
return;
}
smtlib::benchmark* b = parser->get_benchmark();
for (unsigned j = 0; j < b->get_num_assumptions(); ++j) {
expr* e = b->get_assumptions()[j];
std::cout << mk_pp(e, m) << "\n";
ast_dag_pp(std::cout, m, e);
}
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
expr* e = b->begin_formulas()[j];
std::cout << mk_pp(e, m) << "\n";
ast_dag_pp(std::cout, m, e);
}
dealloc(parser);
}

90
src/test/ast_smt_pp.cpp Normal file
View file

@ -0,0 +1,90 @@
/*++
Copyright (c) 2008 Microsoft Corporation
Module Name:
tst_ast_smt_pp.cpp
Abstract:
Test AST Pretty printing module
Author:
Nikolaj Bjorner (nbjorner) 2008-09-04
Revision History:
--*/
#include "ast.h"
#include "ast_smt_pp.h"
#include "smtparser.h"
#include <iostream>
#include <sstream>
void tst_ast_smt_pp()
{
ast_manager m;
smtlib::parser* parser = smtlib::parser::create(m);
parser->initialize_smtlib();
if (!parser->parse_string(
"(benchmark test :extrasorts (A B) :extrafuns ((f A A) (g A A A) (x A) (p A bool)) \n"
":extrafuns ((arg0 BitVec[8]) (arg1 BitVec[8]) (arg2 BitVec[8]))\n"
":formula (p (f x))\n"
":extrafuns ((x1 Int) (y1 Int))\n"
":formula (<= 1 (+ x1 y1))\n"
":formula (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (let (x (g x x)) (p (g x x))))))\n"
":formula (p x)\n"
":formula (bvsge (bvadd arg0 arg2) (extract[7:0] bv3[32]))\n"
":formula (forall (x Int) (y Int) (z Int) (and (<= 1 x) (<= x y))) \n"
":formula (forall (x Int) (y Int) (z Int) (and (<= 2 (ite (<= z 1) x (* 2 x))) (<= x y)))\n"
":formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (<= z 1)) x (* 2 x))) (<= x y)))\n"
":formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (or (> x y) (<= z 1))) x (* 2 x))) (<= x y)))\n"
":extrafuns ((a1 Array))\n"
":formula (= x1 (select (store a1 y1 y1) x1))\n"
":extrafuns ((a2 Array[32:8]))\n"
":formula (= arg0 (select a2 bv0[32]))\n"
":datatypes ((list (cons (car Int) (cdr list)) nil))\n"
":extrafuns ((a list) (b list) (c list))\n"
":formula (is_nil nil)\n"
":datatypes ((list1 (cons1 (car1 Int) (cdr1 list2)) nil1) (list2 (cons1 (car2 list) (cdr2 list1)) nil2) )\n"
":formula (is_nil2 nil2)\n"
")")) {
SASSERT(false);
dealloc(parser);
return;
}
smtlib::benchmark* b = parser->get_benchmark();
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
expr* e = b->begin_formulas()[j];
ast_smt_pp pp(m);
pp.display(std::cout, e);
}
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
expr* e = b->begin_formulas()[j];
// print and parse formula again.
std::ostringstream buffer;
ast_smt_pp pp(m);
pp.display(buffer, e);
ast_manager m2;
smtlib::parser* parser2 = smtlib::parser::create(m2);
parser2->initialize_smtlib();
if (!parser2->parse_string(buffer.str().c_str())) {
SASSERT(false);
dealloc(parser2);
return;
}
dealloc(parser2);
}
dealloc(parser);
}

123
src/test/bit_blaster.cpp Normal file
View file

@ -0,0 +1,123 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
bit_blaster.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-06-05.
Revision History:
--*/
#include"bit_blaster.h"
#include"ast_pp.h"
#include"ast_ll_pp.h"
void mk_bits(ast_manager & m, char const * prefix, unsigned sz, expr_ref_vector & r) {
sort_ref b(m);
b = m.mk_bool_sort();
for (unsigned i = 0; i < sz; ++i) {
char buffer[128];
#ifdef _WINDOWS
sprintf_s(buffer, ARRAYSIZE(buffer), "%s%d.smt", prefix, i);
#else
sprintf(buffer, "%s%d.smt", prefix, i);
#endif
r.push_back(m.mk_const(symbol(buffer), b));
}
}
void display(std::ostream & out, expr_ref_vector & r, bool ll=true) {
ast_mark v;
for (unsigned i = 0; i < r.size(); i++) {
if (ll)
ast_ll_pp(out, r.get_manager(), r.get(i), v);
else
out << mk_pp(r.get(i), r.get_manager());
out << "\n";
}
}
void tst_adder(ast_manager & m, unsigned sz) {
// expr_ref_vector a(m);
// expr_ref_vector b(m);
// expr_ref_vector c(m);
// mk_bits(m, "a", sz, a);
// mk_bits(m, "b", sz, b);
// bool t = true;
// bit_blaster blaster(m, t);
// blaster.mk_adder(sz, a.c_ptr(), b.c_ptr(), c);
// TRACE("bit_blaster", display(tout, c););
}
void tst_multiplier(ast_manager & m, unsigned sz) {
// expr_ref_vector a(m);
// expr_ref_vector b(m);
// expr_ref_vector c(m);
// mk_bits(m, "a", sz, a);
// mk_bits(m, "b", sz, b);
// bool t = true;
// bit_blaster blaster(m, t);
// blaster.mk_multiplier(sz, a.c_ptr(), b.c_ptr(), c);
// TRACE("bit_blaster", display(tout, c););
}
void tst_le(ast_manager & m, unsigned sz) {
// expr_ref_vector a(m);
// expr_ref_vector b(m);
// expr_ref out(m);
// mk_bits(m, "a", sz, a);
// mk_bits(m, "b", sz, b);
// bool t = true;
// bit_blaster blaster(m, t);
// blaster.mk_ule(sz, a.c_ptr(), b.c_ptr(), out);
// TRACE("bit_blaster", tout << mk_pp(out, m) << "\n";);
// blaster.mk_sle(sz, a.c_ptr(), b.c_ptr(), out);
// TRACE("bit_blaster", tout << mk_pp(out, m) << "\n";);
}
void tst_eqs(ast_manager & m, unsigned sz) {
// expr_ref_vector a(m);
// expr_ref_vector b(m);
// expr_ref out(m);
// mk_bits(m, "a", sz, a);
// bool t = true;
// bit_blaster blaster(m, t);
// blaster.mk_eqs(sz, a.c_ptr(), b);
// TRACE("bit_blaster", display(tout, b, false););
}
void tst_sh(ast_manager & m, unsigned sz) {
// expr_ref_vector a(m);
// expr_ref_vector b(m);
// expr_ref_vector c(m);
// mk_bits(m, "a", sz, a);
// mk_bits(m, "b", sz, b);
// bool t = true;
// bit_blaster blaster(m, t);
// blaster.mk_shl(sz, a.c_ptr(), b.c_ptr(), c);
// TRACE("bit_blaster", tout << "shl\n"; display(tout, c););
// c.reset();
// blaster.mk_lshr(sz, a.c_ptr(), b.c_ptr(), c);
// TRACE("bit_blaster", tout << "lshr\n"; display(tout, c););
// c.reset();
// blaster.mk_ashr(sz, a.c_ptr(), b.c_ptr(), c);
// TRACE("bit_blaster", tout << "ashr " << c.size() << "\n"; display(tout, c, false););
}
void tst_bit_blaster() {
ast_manager m;
tst_adder(m, 4);
tst_multiplier(m, 4);
tst_le(m, 4);
tst_eqs(m, 8);
tst_sh(m, 4);
}

291
src/test/bit_vector.cpp Normal file
View file

@ -0,0 +1,291 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_bitvector.cpp
Abstract:
Test bitvector module
Author:
Leonardo de Moura (leonardo) 2006-10-03.
Revision History:
--*/
#include<cstdlib>
#include<iostream>
#include"bit_vector.h"
#include"vector.h"
static void tst1() {
bit_vector v1;
svector<bool> v2;
unsigned n = rand()%10000;
for (unsigned i = 0; i < n; i++) {
int op = rand()%6;
if (op <= 1) {
bool val = (rand()%2) != 0;
v1.push_back(val);
v2.push_back(val);
SASSERT(v1.size() == v2.size());
}
else if (op <= 3) {
SASSERT(v1.size() == v2.size());
if (v1.size() > 0) {
bool val = (rand()%2) != 0;
unsigned idx = rand()%v1.size();
SASSERT(v1.get(idx) == v2[idx]);
v1.set(idx, val);
v2[idx] = val;
SASSERT(v1.get(idx) == v2[idx]);
}
}
else if (op <= 4) {
SASSERT(v1.size() == v2.size());
if (v1.size() > 0) {
unsigned idx = rand()%v1.size();
SASSERT(v1.get(idx) == v2[idx]);
}
}
else if (op <= 5) {
SASSERT(v1.size() == v2.size());
for (unsigned j = 0; j < v1.size(); j++) {
SASSERT(v1.get(j) == v2[j]);
}
}
}
}
static void tst2() {
bit_vector b;
b.push_back(true);
b.push_back(false);
b.push_back(true);
b.resize(30);
SASSERT(b.get(0) == true);
SASSERT(b.get(1) == false);
SASSERT(b.get(2) == true);
SASSERT(b.get(3) == false);
SASSERT(b.get(29) == false);
}
static void tst_shift() {
bit_vector b;
b.resize(111);
b.set(105);
b.set(99);
b.set(98);
b.set(90);
b.set(80);
b.set(75);
b.set(33);
b.set(32);
b.set(31);
b.set(30);
b.set(10);
std::cout << "b: " << b << "\n";
b.shift_right(16);
std::cout << "b: " << b << "\n";
b.shift_right(1);
std::cout << "b: " << b << "\n";
b.shift_right(32);
std::cout << "b: " << b << "\n";
b.shift_right(42);
std::cout << "b: " << b << "\n";
b.shift_right(16);
std::cout << "b: " << b << "\n";
b.shift_right(63);
std::cout << "b: " << b << "\n";
}
static void tst_or() {
{
bit_vector b1;
bit_vector b2;
b1.resize(5);
b2.resize(10);
b1.set(4);
b2.set(8);
b2.set(3);
b2.set(2);
b2.set(1);
std::cout << b1 << "\n";
std::cout << b2 << "\n";
b1 |= b2;
SASSERT(b1.size() == 10);
std::cout << b1 << "\n";
SASSERT(b1 != b2);
SASSERT(b1 != b2);
b1.unset(4);
SASSERT(b1 == b2);
b1.unset(3);
SASSERT(b1 != b2);
}
{
bit_vector b1;
bit_vector b2;
b1.resize(2);
b2.resize(5);
b1.set(0);
b2.set(4);
b1 |= b2;
SASSERT(b1 != b2);
b2.set(0);
SASSERT(b1 == b2);
std::cout << "-----\n";
std::cout << b1 << "\n";
}
{
bit_vector b1;
bit_vector b2;
b1.resize(10);
b2.resize(10);
b1.set(5);
b2.set(8);
b2.set(3);
b2.resize(5);
b1 |= b2;
SASSERT(!b1.get(8));
SASSERT(b1.get(5));
SASSERT(b1.get(3));
}
{
bit_vector b1;
bit_vector b2;
b1.resize(123);
b2.resize(126);
b2.set(124);
b1.set(122);
b1.set(100);
b2.set(100);
b1.set(80);
b2.set(80);
b1.set(4);
b2.set(4);
SASSERT(b1!=b2);
b2.resize(123);
SASSERT(b1!=b2);
b1.resize(120);
b2.resize(120);
SASSERT(b1==b2);
b1.unset(80);
b1.unset(100);
SASSERT(b1!=b2);
b1 |= b2;
SASSERT(b1 == b2);
}
{
bit_vector b1;
bit_vector b2;
b1.resize(5);
b2.resize(10);
b2.set(8);
b1.set(4);
b2.set(1);
b1.set(0);
b1 |= b2;
SASSERT(b1.size() == 10);
SASSERT(b1.get(8) && b1.get(4) && b1.get(1) && b1.get(0) && !b1.get(9));
}
{
bit_vector b1;
bit_vector b2;
b1.resize(32);
b2.resize(32);
b1.set(1);
b1.set(5);
b2.set(8);
b2.set(0);
b1 |= b2;
SASSERT(b1.get(1) && b1.get(5) && b1.get(8) && b1.get(0) && !b1.get(11));
std::cout << "b1(size32): " << b1 << "\n";
}
}
static void tst_and() {
{
bit_vector b1;
bit_vector b2;
b1.resize(5);
b2.resize(3);
b2.set(2);
b1.set(2);
b1.set(4);
std::cout << "------\nb1: " << b1 << "\n";
b1 &= b2;
std::cout << "------\nb1: " << b1 << "\n";
SASSERT(!b1.get(4));
SASSERT(b1.get(2));
}
{
bit_vector b1;
bit_vector b2;
b1.resize(241);
b2.resize(128);
b1.set(240);
b1.set(232);
b1.set(127);
b1.set(128);
b1.set(8);
b2.set(127);
b2.set(5);
b1 &= b2;
SASSERT(!b1.get(240) && !b1.get(232) && !b1.get(128) && b1.get(127) && !b1.get(8) && !b1.get(5));
}
}
static void tst_crash() {
{
bit_vector b;
b.push_back(true);
b.resize(64);
SASSERT(!b.get(63));
SASSERT(b.get(0));
SASSERT(!b.get(1));
}
{
bit_vector b;
b.push_back(false);
b.resize(64, true);
SASSERT(b.get(63));
SASSERT(!b.get(0));
SASSERT(b.get(1));
}
}
static void tst_bv_reset() {
bit_vector b;
bool bit = true;
for (unsigned sz = 1; sz < 84; ++sz) {
b.reset();
b.resize(sz, bit);
for (unsigned i = 0; i < sz; ++i) {
SASSERT(bit == b.get(i));
}
for (unsigned sz2 = sz; sz2 < sz+10; ++sz2) {
b.resize(sz2, !bit);
for (unsigned i = sz; i < sz2; ++i) {
SASSERT(bit != b.get(i));
}
}
bit = !bit;
}
}
void tst_bit_vector() {
tst_crash();
tst_shift();
tst_or();
tst_and();
tst_bv_reset();
return;
tst2();
for (unsigned i = 0; i < 20; i++) {
std::cerr << i << std::endl;
tst1();
}
}

203
src/test/bits.cpp Normal file
View file

@ -0,0 +1,203 @@
// Test some bit hacks
#include"util.h"
#include"debug.h"
#include"vector.h"
#include"mpz.h"
#include"bit_util.h"
static void tst_shl(unsigned src_sz, unsigned const * src, unsigned k,
unsigned dst_sz, unsigned const * dst, bool trace = true) {
if (trace) {
std::cout << "shl({";
for (unsigned i = 0; i < src_sz; i++) {
if (i > 0) std::cout << ", ";
std::cout << src[i];
}
std::cout << "}, " << k << ")" << std::endl;
}
svector<unsigned> actual_dst;
actual_dst.resize(dst_sz, 0xAAAAAAAA);
for (unsigned sz = 1; sz <= dst_sz; sz++) {
if (trace)
std::cout << " for sz = " << sz << std::endl;
shl(src_sz, src, k, sz, actual_dst.c_ptr());
SASSERT(!has_one_at_first_k_bits(sz, actual_dst.c_ptr(), k));
for (unsigned i = 0; i < sz; i++) {
if (trace && dst[i] != actual_dst[i])
std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n";
SASSERT(dst[i] == actual_dst[i]);
}
if (sz == src_sz) {
unsigned nz1 = nlz(sz, src);
if (nz1 >= k && !is_zero(sz, src)) {
unsigned nz2 = nlz(sz, actual_dst.c_ptr());
if (nz1 - k != nz2) {
if (trace)
std::cout << "nlz BUG, nlz1: " << nz1 << ", k: " << k << ", nlz2: " << nz2 << std::endl;
UNREACHABLE();
}
}
}
if (sz >= src_sz + (k/32) + 1) {
svector<unsigned> new_src;
new_src.resize(sz, 0xAAAAAAAA);
shr(sz, actual_dst.c_ptr(), k, new_src.c_ptr());
for (unsigned i = 0; i < src_sz; i++) {
if (trace && src[i] != new_src[i]) {
std::cout << "shr BUG, inverting shl, at bit[" << i << "], " << new_src[i] << ", expected: " << src[i] << std::endl;
}
SASSERT(src[i] == new_src[i]);
}
}
}
if (trace)
std::cout << " shift by 1, k times" << std::endl;
copy(src_sz, src, dst_sz, actual_dst.c_ptr());
for (unsigned i = 0; i < k; i++) {
shl(dst_sz, actual_dst.c_ptr(), 1, dst_sz, actual_dst.c_ptr());
}
for (unsigned i = 0; i < dst_sz; i++) {
if (trace && dst[i] != actual_dst[i])
std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n";
SASSERT(dst[i] == actual_dst[i]);
}
if (src_sz <= dst_sz) {
if (trace)
std::cout << " self-shl" << std::endl;
shl(src_sz, src, k, src_sz, const_cast<unsigned*>(src));
for (unsigned i = 0; i < src_sz; i++) {
if (trace && src[i] != dst[i])
std::cout << "UNEXPECTED RESULT at [" << i << "]: " << src[i] << ", expected: " << dst[i] << "\n";
SASSERT(src[i] == actual_dst[i]);
}
}
}
static void tst_shl() {
{
unsigned src[2] = {0, 2}; unsigned dst[2] = {0, 2<<10};
tst_shl(2, src, 10, 2, dst);
}
{
unsigned src[2] = {2, 0}; unsigned dst[2] = {0, 2<<10};
tst_shl(2, src, 42, 2, dst);
}
{
unsigned src[2] = {0, 0}; unsigned dst[3] = {0, 0, 0};
tst_shl(2, src, 1, 3, dst);
}
{
unsigned src[2] = {0x80000009, 5}; unsigned dst[2] = {18, 11};
tst_shl(2, src, 1, 2, dst);
}
{
unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[2] = {18, 11};
tst_shl(2, src, 1, 2, dst);
}
{
unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[3] = {18, 11, 1};
tst_shl(2, src, 1, 3, dst);
}
{
unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[3] = {0, 18, 11};
tst_shl(2, src, 33, 3, dst);
}
{
unsigned src[2] = {0x80000009, 0x80000005}; unsigned dst[4] = {0, 18, 11, 1};
tst_shl(2, src, 33, 4, dst);
}
{
unsigned src[2] = {0xFFFFFFFF, 0xFFFFFFFF}; unsigned dst[2] = {0xFFFFFFF0, 0xFFFFFFFF};
tst_shl(2, src, 4, 2, dst);
}
}
static void tst_shr(unsigned src_sz, unsigned const * src, unsigned k,
unsigned const * dst, bool trace = true) {
if (trace) {
std::cout << "shr({";
for (unsigned i = 0; i < src_sz; i++) {
if (i > 0) std::cout << ", ";
std::cout << src[i];
}
std::cout << "}, " << k << ")" << std::endl;
}
svector<unsigned> actual_dst;
actual_dst.resize(src_sz, 0xAAAAAAAA);
shr(src_sz, src, k, actual_dst.c_ptr());
for (unsigned i = 0; i < src_sz; i++) {
if (trace && dst[i] != actual_dst[i])
std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n";
SASSERT(dst[i] == actual_dst[i]);
}
}
static void tst_shr() {
{
unsigned src[2] = {0, 0}; unsigned dst[2] = {0, 0};
tst_shr(2, src, 1, dst);
}
}
static void tst_shl_rand(unsynch_mpz_manager & m, unsigned sz, unsigned k, bool trace = true) {
// create a random bitvector of of size sz
svector<unsigned> src;
for (unsigned i = 0; i < sz; i++) {
src.push_back(rand());
}
// convert src into a mpz number
scoped_mpz _src(m);
scoped_mpz tmp(m);
unsigned i = sz;
while (i > 0) {
--i;
m.mul2k(_src, 32);
m.set(tmp, src[i]);
m.add(_src, tmp, _src);
}
// shift left by multiplying by 2^k
scoped_mpz _dst(m);
m.set(_dst, _src);
m.mul2k(_dst, k);
// convert _dst into a vector of unsigned values
svector<unsigned> dst;
scoped_mpz max(m);
m.set(max, 1);
m.mul2k(max, 32);
while (!m.is_zero(_dst)) {
m.mod(_dst, max, tmp);
SASSERT(m.is_uint64(tmp) && m.get_uint64(tmp) < UINT_MAX);
dst.push_back(static_cast<unsigned>(m.get_uint64(tmp)));
m.div(_dst, max, _dst);
}
while (dst.size() < src.size())
dst.push_back(0);
dst.push_back(0);
unsigned word_shift = (k / 32);
for (unsigned i = 0; i < word_shift; i++)
dst.push_back(0);
tst_shl(src.size(), src.c_ptr(), k, dst.size(), dst.c_ptr(), trace);
}
static void tst_shl_rand(unsigned N, unsigned sz, unsigned k, bool trace = false) {
unsynch_mpz_manager m;
for (unsigned i = 0; i < N; i++) {
unsigned _sz = rand() % sz;
if (_sz == 0)
_sz = 1;
unsigned _k = rand() % k;
if (_k == 0)
_k = 1;
tst_shl_rand(m, _sz, _k, trace);
}
}
void tst_bits() {
tst_shr();
tst_shl();
tst_shl_rand(100000, 4, 100);
}

48
src/test/buffer.cpp Normal file
View file

@ -0,0 +1,48 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
buffer.cpp
Abstract:
Test buffers.
Author:
Leonardo de Moura (leonardo) 2011-03-03.
Revision History:
--*/
#include"ptr_scoped_buffer.h"
typedef std::pair<int, int> point;
template class ptr_scoped_buffer<point>;
static void tst1() {
ptr_scoped_buffer<point> b;
SASSERT(b.empty());
b.push_back(alloc(point, 10, 20));
SASSERT(!b.empty());
point * p1 = alloc(point, 30, 20);
b.push_back(p1);
SASSERT(b.get(1) == p1);
b.push_back(alloc(point, 40, 20));
SASSERT(b.size() == 3);
b.pop_back();
SASSERT(b.get(0) != p1);
SASSERT(b.get(1) == p1);
point * p2 = alloc(point, 30, 20);
SASSERT(b.get(0) != p2);
b.set(0, p2);
SASSERT(b.get(0) == p2);
SASSERT(b.size() == 2);
b.push_back(alloc(point, 40, 40));
}
void tst_buffer() {
tst1();
}

View file

@ -0,0 +1,310 @@
#include "bv_simplifier_plugin.h"
#include "arith_decl_plugin.h"
#include "ast_pp.h"
class tst_bv_simplifier_plugin_cls {
ast_manager m_manager;
bv_simplifier_params m_bv_params;
basic_simplifier_plugin m_bsimp;
arith_util m_arith;
bv_simplifier_plugin m_simp;
bv_util m_bv_util;
family_id m_fid;
void get_num(expr* e, unsigned bv_size, rational& r) {
unsigned bv_size0;
if (!m_bv_util.is_numeral(e, r, bv_size0)) {
UNREACHABLE();
}
SASSERT(bv_size == bv_size0);
}
unsigned u32(expr* e) {
rational r;
std::cout << mk_pp(e,m_manager) << "\n";
get_num(e, 32, r);
return r.get_unsigned();
}
unsigned char u8(expr* e) {
rational r;
get_num(e, 8, r);
return static_cast<unsigned char>(r.get_unsigned());
}
int i32(expr* e) {
return static_cast<int>(u32(e));
}
uint64 u64(expr* e) {
rational r;
get_num(e, 64, r);
return r.get_uint64();
}
int64 i64(expr* e) {
rational r;
get_num(e, 64, r);
if (r >= power(rational(2), 63)) {
r -= power(rational(2), 64);
}
return r.get_int64();
}
bool ast2bool(expr* e) {
if (m_manager.is_true(e)) {
return true;
}
if (m_manager.is_false(e)) {
return false;
}
UNREACHABLE();
return false;
}
bool bit2bool(expr* e) {
rational r;
get_num(e, 1, r);
return 0 != r.get_unsigned();
}
expr* mk_int(unsigned i) {
return m_arith.mk_numeral(rational(i), true);
}
public:
tst_bv_simplifier_plugin_cls() :
m_bv_util(m_manager),
m_bsimp(m_manager),
m_arith(m_manager),
m_simp(m_manager, m_bsimp, m_bv_params),
m_fid(m_manager.get_family_id("bv")) {
m_manager.register_decl_plugins();
}
~tst_bv_simplifier_plugin_cls() {}
void test_num(unsigned a) {
expr_ref e(m_manager), e1(m_manager);
app_ref ar(m_manager);
int sa = static_cast<int>(a);
uint64 a64 = static_cast<uint64>(a);
e1 = m_bv_util.mk_numeral(rational(a), 32);
expr* const es[1] = { e1.get() };
ar = m_manager.mk_app(m_fid, OP_BNEG, e1.get());
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((0-a) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BNOT, e1.get());
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((~a) == u32(e.get()));
parameter params[2] = { parameter(32), parameter(32) };
ar = m_manager.mk_app(m_fid, OP_SIGN_EXT, 1, params, 1, es);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((int64)(int)a) == i64(e.get()));
ar = m_manager.mk_app(m_fid, OP_ZERO_EXT, 1, params, 1, es);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((uint64)a) == u64(e.get()));
params[0] = parameter(7);
params[1] = parameter(0);
ar = m_manager.mk_app(m_fid, OP_EXTRACT, 2, params, 1, es);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((unsigned char)a) == u8(e.get()));
params[0] = parameter(2);
ar = m_manager.mk_app(m_fid, OP_REPEAT, 1, params, 1, es);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((a64 << 32) | a64) == u64(e.get()));
ar = m_manager.mk_app(m_fid, OP_BREDOR, e1.get());
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a != 0) == bit2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_BREDAND, e1.get());
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a == 0xFFFFFFFF) == bit2bool(e.get()));
params[0] = parameter(8);
ar = m_manager.mk_app(m_fid, OP_ROTATE_LEFT, 1, params, 1, es);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((a << 8) | (a >> 24)) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_ROTATE_RIGHT, 1, params, 1, es);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((a >> 8) | (a << 24)) == u32(e.get()));
params[0] = parameter(m_manager.mk_sort(m_manager.get_family_id("arith"), INT_SORT));
ar = m_manager.mk_app(m_fid, OP_BV2INT, 1, params, 1, es);
expr* es2[1] = { ar.get() };
params[0] = parameter(32);
ar = m_manager.mk_app(m_fid, OP_INT2BV, 1, params, 1, es2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(a == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BIT0);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(!bit2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_BIT1);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(bit2bool(e.get()));
}
void test_pair(unsigned a, unsigned b) {
expr_ref e(m_manager), e1(m_manager), e2(m_manager);
app_ref ar(m_manager);
int sa = static_cast<int>(a);
int sb = static_cast<int>(b);
uint64 a64 = static_cast<uint64>(a);
uint64 b64 = static_cast<uint64>(b);
e1 = m_bv_util.mk_numeral(rational(a), 32);
e2 = m_bv_util.mk_numeral(rational(b), 32);
expr* const e1e2[] = { e1.get(), e2.get() };
ar = m_manager.mk_app(m_fid, OP_BADD, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a + b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BSUB, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a - b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BMUL, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a * b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BAND, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a & b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BOR, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a | b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BNOR, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(~(a | b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BXOR, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a ^ b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BXNOR, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((~(a ^ b)) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BNAND, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((~(a & b)) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_ULEQ, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a <= b) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_UGEQ, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a >= b) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_ULT, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a < b) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_UGT, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a > b) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_SLEQ, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((sa <= sb) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_SGEQ, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((sa >= sb) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_SLT, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((sa < sb) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_SGT, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((sa > sb) == ast2bool(e.get()));
ar = m_manager.mk_app(m_fid, OP_BSHL, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((b>=32)?0:(a << b)) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BLSHR, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((b>=32)?0:(a >> b)) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BASHR, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((sa >> b) == i32(e.get()));
if (b != 0) {
ar = m_manager.mk_app(m_fid, OP_BSDIV, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((sa / sb) == i32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BUDIV, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a / b) == u32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BSREM, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
//SASSERT((sa % sb) == i32(e.get()));
ar = m_manager.mk_app(m_fid, OP_BUREM, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a % b) == u32(e.get()));
// TBD: BSMOD.
}
ar = m_manager.mk_app(m_fid, OP_CONCAT, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT(((a64 << 32) | b64) == u64(e.get()));
ar = m_manager.mk_app(m_fid, OP_BCOMP, 2, e1e2);
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
SASSERT((a == b) == bit2bool(e.get()));
}
void test() {
unsigned_vector nums;
nums.push_back(0);
nums.push_back(1);
nums.push_back(-1);
nums.push_back(2);
nums.push_back(31);
nums.push_back(32);
nums.push_back(33);
nums.push_back(435562);
nums.push_back(-43556211);
// TBD add some random numbers.
for (unsigned i = 0; i < nums.size(); ++i) {
test_num(nums[i]);
for (unsigned j = 0; j < nums.size(); ++j) {
test_pair(nums[i], nums[j]);
}
}
}
};
void tst_bv_simplifier_plugin() {
tst_bv_simplifier_plugin_cls tst_cls;
tst_cls.test();
}

183
src/test/chashtable.cpp Normal file
View file

@ -0,0 +1,183 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
chashtable.cpp
Abstract:
Hashtable with chaining.
Author:
Leonardo de Moura (leonardo) 2011-04-14.
Revision History:
--*/
#include"chashtable.h"
#include"hashtable.h"
#include"hash.h"
#include"util.h"
typedef chashtable<int, int_hash, default_eq<int> > int_table;
typedef cmap<int, int, int_hash, default_eq<int> > int_map;
template class chashtable<int, int_hash, default_eq<int> >;
template class cmap<int, int, int_hash, default_eq<int> >;
template<typename T>
static void display(T const & beg, T const & end) {
for (T it = beg; it != end; ++it)
std::cout << *it << " ";
std::cout << "\n";
}
static void tst1() {
int_table t;
t.insert(10);
SASSERT(t.contains(10));
t.insert(20);
SASSERT(t.contains(20));
t.insert(30);
SASSERT(t.contains(30));
SASSERT(t.size() == 3);
display(t.begin(), t.end());
t.erase(20);
SASSERT(!t.contains(20));
SASSERT(t.size() == 2);
}
struct dummy_hash {
unsigned operator()(int v) const { return v % 2; }
};
typedef chashtable<int, dummy_hash, default_eq<int> > dint_table;
template class chashtable<int, dummy_hash, default_eq<int> >;
static void tst2() {
dint_table t;
t.insert(10);
t.insert(12);
SASSERT(t.used_slots() == 1);
display(t.begin(), t.end());
t.insert(13);
display(t.begin(), t.end());
SASSERT(t.used_slots() == 2);
t.insert(14);
SASSERT(t.used_slots() == 2);
SASSERT(t.size() == 4);
display(t.begin(), t.end());
t.erase(12);
SASSERT(!t.contains(12));
SASSERT(t.size() == 3);
SASSERT(t.contains(10));
SASSERT(!t.contains(12));
SASSERT(t.contains(14));
SASSERT(t.contains(13));
t.insert(16);
SASSERT(t.size() == 4);
t.insert(18);
SASSERT(t.size() == 5);
SASSERT(t.used_slots() == 2);
display(t.begin(), t.end());
t.erase(10);
display(t.begin(), t.end());
SASSERT(!t.contains(10));
SASSERT(!t.contains(12));
SASSERT(t.contains(14));
SASSERT(t.contains(13));
SASSERT(t.contains(16));
SASSERT(t.contains(18));
}
static void tst3() {
dint_table t;
t.insert(10);
t.insert(12);
SASSERT(t.used_slots() == 1);
SASSERT(t.contains(10));
SASSERT(t.contains(12));
t.erase(12);
t.erase(10);
SASSERT(t.size() == 0);
SASSERT(t.empty());
SASSERT(t.used_slots() == 0);
t.insert(10);
SASSERT(t.used_slots() == 1);
SASSERT(t.contains(10));
SASSERT(t.size() == 1);
}
typedef int_hashtable<int_hash, default_eq<int> > int_set;
template<typename T>
static void tst4(unsigned num, unsigned N) {
int_set s;
T t;
for (unsigned i = 0; i < num; i++) {
int v = rand() % N;
if (rand() % 3 == 2) {
TRACE("chashtable", tout << "erase " << v << "\n";);
s.erase(v);
t.erase(v);
SASSERT(!t.contains(v));
}
else {
TRACE("chashtable", tout << "insert " << v << "\n";);
s.insert(v);
t.insert(v);
SASSERT(t.contains(v));
}
SASSERT(s.size() == t.size());
SASSERT(s.empty() == t.empty());
}
std::cout << "size: " << s.size() << " " << t.size() << "\n";
int_set::iterator it1 = s.begin();
int_set::iterator end1 = s.end();
for(; it1 != end1; ++it1) {
SASSERT(t.contains(*it1));
}
typename T::iterator it2 = t.begin();
typename T::iterator end2 = t.end();
for(; it2 != end2; ++it2) {
SASSERT(s.contains(*it2));
SASSERT(t.contains(*it2));
}
}
static void tst5() {
dint_table t;
t.insert(4);
t.insert(9);
t.insert(8);
t.insert(1);
t.erase(1);
t.insert(7);
t.insert(1);
t.insert(2);
}
static void tst6() {
int_map m;
m.insert(10, 4);
SASSERT(m.contains(10));
DEBUG_CODE({
int r;
SASSERT(m.find(10, r) && r == 4);
});
}
void tst_chashtable() {
tst1();
tst2();
tst3();
tst6();
tst4<dint_table>(1000,10);
tst4<dint_table>(10000,10);
tst4<int_table>(50000,1000);
tst5();
}

View file

@ -0,0 +1,43 @@
#include "memory_manager.h"
#include "front_end_params.h"
#include "ast.h"
#include "arith_decl_plugin.h"
#include "bv_decl_plugin.h"
#include "smt_context.h"
void tst_check_assumptions()
{
memory::initialize(0);
front_end_params params;
ast_manager mgr;
mgr.register_decl_plugins();
sort_ref b(mgr.mk_bool_sort(), mgr);
func_decl_ref pPred(mgr.mk_func_decl(symbol("p"), 0, static_cast<sort * const *>(0), b), mgr);
func_decl_ref qPred(mgr.mk_func_decl(symbol("q"), 0, static_cast<sort * const *>(0), b), mgr);
func_decl_ref rPred(mgr.mk_func_decl(symbol("r"), 0, static_cast<sort * const *>(0), b), mgr);
app_ref p(mgr.mk_app(pPred,0,static_cast<expr * const *>(0)), mgr);
app_ref q(mgr.mk_app(qPred,0,static_cast<expr * const *>(0)), mgr);
app_ref r(mgr.mk_app(rPred,0,static_cast<expr * const *>(0)), mgr);
app_ref pOqOr(mgr.mk_or(p,q,r), mgr);
app_ref np(mgr.mk_not(p), mgr);
app_ref nq(mgr.mk_not(q), mgr);
app_ref nr(mgr.mk_not(r), mgr);
smt::context ctx(mgr, params);
ctx.assert_expr(pOqOr);
expr * npE = np.get();
lbool res1 = ctx.check(1, &npE);
SASSERT(res1==l_true);
ctx.assert_expr(npE);
expr * assumpt[] = { nq.get(), nr.get() };
//here it should crash
lbool res2 = ctx.check(2, assumpt);
}

View file

@ -0,0 +1,80 @@
#include "datalog_parser.h"
#include "ast_pp.h"
#include "arith_decl_plugin.h"
#include "dl_context.h"
#include "front_end_params.h"
using namespace datalog;
static void dparse_string(char const* str) {
ast_manager m;
front_end_params params;
m.register_decl_plugins();
context ctx(m, params);
parser* p = parser::create(ctx,m);
bool res=p->parse_string(str);
if (!res) {
std::cout << "Parser did not succeed on string\n"<<str<<"\n";
SASSERT(false);
}
#if 0
unsigned num_rules = p->get_num_rules();
for (unsigned j = 0; j < num_rules; ++j) {
rule* r = p->get_rules()[j];
std::cout << mk_pp(r->head(), m) << "\n";
for (unsigned i = 0; i < r->size(); ++i) {
std::cout << "body: " << mk_pp((*r)[i], m) << "\n";
}
}
#endif
dealloc(p);
}
static void dparse_file(char const* file) {
ast_manager m;
front_end_params params;
m.register_decl_plugins();
context ctx(m, params);
parser* p = parser::create(ctx,m);
if (!p->parse_file(file)) {
std::cout << "Failed to parse file\n";
}
#if 0
unsigned num_rules = p->get_num_rules();
for (unsigned j = 0; j < num_rules; ++j) {
rule* r = p->get_rules()[j];
std::cout << mk_pp(r->head(), m) << "\n";
for (unsigned i = 0; i < r->size(); ++i) {
std::cout << "body: " << mk_pp((*r)[i], m) << "\n";
}
}
#endif
dealloc(p);
}
void tst_datalog_parser() {
dparse_string("\nH :- C1(X,a,b), C2(Y,a,X) .");
dparse_string("N 128\n\nH :- C1(X,a,b), C2(Y,a,X) .");
dparse_string("N 128\nI 128\n\nC1(x : N, y : N, z : I)\nC2(x : N, y : N, z : N)\nH :- C1(X,a,b), C2(Y,a,X) .");
dparse_string("\nH :- C1(X,a,b), nC2(Y,a,X) .");
dparse_string("\nH :- C1(X,a,b),nC2(Y,a,X).");
dparse_string("\nH :- C1(X,a,b),\\\nC2(Y,a,X).");
dparse_string("\nH :- C1(X,a\\,\\b), C2(Y,a,X) .");
}
void tst_datalog_parser_file(char** argv, int argc, int & i) {
if (i + 1 < argc) {
dparse_file(argv[i+1]);
i++;
}
}

174
src/test/diff_logic.cpp Normal file
View file

@ -0,0 +1,174 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
diff_logic.cpp
Abstract:
Unit tests for difference logic
Author:
Leonardo de Moura (leonardo) 2006-11-22.
Revision History:
--*/
#ifdef _WINDOWS
#include"rational.h"
#include"diff_logic.h"
#include"smt_literal.h"
#include"util.h"
#include"debug.h"
struct diff_logic_ext {
typedef rational numeral;
typedef smt::literal explanation;
};
template class dl_graph<diff_logic_ext>;
typedef dl_graph<diff_logic_ext> dlg;
struct tst_dl_functor {
smt::literal_vector m_literals;
void operator()(smt::literal l) {
m_literals.push_back(l);
}
};
static void tst1() {
dlg g;
smt::literal l;
g.init_var(1);
g.init_var(2);
g.init_var(3);
g.enable_edge(g.add_edge(1, 2, rational(1), l));
g.enable_edge(g.add_edge(2, 3, rational(2), l));
g.push();
g.enable_edge(g.add_edge(1, 3, rational(4), l));
g.init_var(4);
g.enable_edge(g.add_edge(1, 4, rational(5), l));
g.enable_edge(g.add_edge(4, 2, rational(0), l));
g.pop(1);
}
static void tst2() {
dlg g;
rational w;
smt::literal l1(1);
smt::literal l2(2);
smt::literal l3(3);
smt::literal l4(4);
smt::literal l5(5);
smt::literal l6(6);
g.init_var(0);
g.init_var(1);
g.init_var(2);
g.init_var(3);
g.init_var(4);
smt::literal d;
SASSERT(g.enable_edge(g.add_edge(1, 2, rational(-1), l1)));
SASSERT(g.get_edge_weight(1, 2, w, d) && w == rational(-1));
SASSERT(!g.get_edge_weight(2, 3, w, d));
SASSERT(g.enable_edge(g.add_edge(2, 3, rational(-2), l2)));
SASSERT(g.enable_edge(g.add_edge(1, 4, rational(1), l3)));
SASSERT(g.get_edge_weight(1, 2, w, d) && w == rational(-1));
SASSERT(g.get_edge_weight(1, 4, w, d) && w == rational(1));
SASSERT(!g.get_edge_weight(1, 3, w, d));
SASSERT(g.enable_edge(g.add_edge(2, 4, rational(10), l6)));
SASSERT(g.is_feasible());
g.push();
SASSERT(g.enable_edge(g.add_edge(3, 0, rational(2), l4)));
SASSERT(!g.enable_edge(g.add_edge(0, 1, rational(-1), l5)));
SASSERT(!g.is_feasible());
TRACE("diff_logic", g.display(tout););
struct proc {
svector<bool> found;
proc():
found(7, false) {
}
void operator()(smt::literal l) {
found[l.var()] = true;
}
};
proc p;
g.traverse_neg_cycle(true, p);
SASSERT(p.found[0] == false);
SASSERT(p.found[1] == true);
SASSERT(p.found[2] == true);
SASSERT(p.found[3] == false);
SASSERT(p.found[4] == true);
SASSERT(p.found[5] == true);
SASSERT(p.found[6] == false);
g.pop(1);
SASSERT(g.is_feasible());
TRACE("diff_logic", g.display(tout););
}
static int add_edge(dlg& g, dl_var src, dl_var dst, int weight, unsigned lit) {
int id = g.add_edge(src, dst, rational(weight), smt::literal(lit));
bool ok = g.enable_edge(id);
SASSERT(ok);
return id;
}
static void tst3() {
dlg g;
for (unsigned i = 1; i <= 10; ++i) {
g.init_var(i);
}
add_edge(g, 1, 2, 1, 12);
add_edge(g, 1, 3, 1, 13);
add_edge(g, 1, 4, 1, 14);
add_edge(g, 2, 5, 1, 25);
add_edge(g, 2, 6, 1, 26);
add_edge(g, 3, 5, 1, 35);
add_edge(g, 4, 5, 1, 45);
add_edge(g, 4, 6, 1, 46);
int xy = add_edge(g, 5, 6, 1, 56);
add_edge(g, 5, 7, 1, 57);
add_edge(g, 5, 9, 1, 59);
add_edge(g, 6, 7, 1, 67);
add_edge(g, 6, 8, 1, 68);
add_edge(g, 6, 9, 1, 69);
add_edge(g, 6, 10, 1, 610);
add_edge(g, 8, 10, 1, 810);
add_edge(g, 9, 10, 1, 910);
TRACE("diff_logic", g.display(tout););
int e38 = g.add_edge(3, 8, rational(3), smt::literal(38));
std::cout << "Edge: " << e38 << "\n";
svector<edge_id> subsumed;
g.find_subsumed(xy, subsumed);
for (unsigned i = 0; i < subsumed.size(); ++i) {
std::cout << "subsumed: " << subsumed[i] << "\n";
SASSERT(e38 == subsumed[i]);
tst_dl_functor tst_fn;
g.explain_subsumed_lazy(xy, subsumed[i], tst_fn);
for (unsigned j = 0; j < tst_fn.m_literals.size(); ++j) {
std::cout << tst_fn.m_literals[j] << " ";
}
std::cout << "\n";
}
}
void tst_diff_logic() {
tst1();
tst2();
tst3();
}
#else
void tst_diff_logic() {
}
#endif

89
src/test/dl_context.cpp Normal file
View file

@ -0,0 +1,89 @@
#include "datalog_parser.h"
#include "ast_pp.h"
#include "arith_decl_plugin.h"
#include "dl_context.h"
#include "front_end_params.h"
using namespace datalog;
static lbool dl_context_eval_unary_predicate(ast_manager & m, context & ctx, char const* problem_text,
const char * pred_name) {
parser* p = parser::create(ctx,m);
TRUSTME( p->parse_string(problem_text) );
dealloc(p);
func_decl * pred = ctx.try_get_predicate_decl(symbol(pred_name));
SASSERT(pred);
SASSERT(pred->get_arity()==1);
app_ref query_app(m.mk_app(pred, m.mk_var(0, pred->get_domain()[0])), m);
lbool status = ctx.query(query_app);
SASSERT(status != l_undef);
return status;
}
static void dl_context_simple_query_test(params_ref & params) {
ast_manager m;
dl_decl_util decl_util(m);
front_end_params fparams;
context ctx(m, fparams);
ctx.updt_params(params);
lbool status = dl_context_eval_unary_predicate(m, ctx, "Z 64\n\nP(x:Z)\nP(\"a\").", "P");
#if 0
// TBD:
//zero corresponds to the first constant the datalog parser encountered, in our case "a"
app_ref c_0(decl_util.mk_constant(0, res1->get_signature()[0]), m);
app_ref c_1(decl_util.mk_constant(1, res1->get_signature()[0]), m);
relation_fact f(m);
f.push_back(c_0);
SASSERT(res1->contains_fact(f));
f[0]=c_1;
SASSERT(!res1->contains_fact(f));
#endif
}
void dl_context_saturate_file(params_ref & params, const char * f) {
ast_manager m;
dl_decl_util decl_util(m);
front_end_params fparams;
context ctx(m, fparams);
ctx.updt_params(params);
datalog::parser * parser = datalog::parser::create(ctx, m);
if (!parser->parse_file(f)) {
warning_msg("ERROR: failed to parse file");
return;
}
dealloc(parser);
std::cerr << "Saturating...\n";
ctx.dl_saturate();
std::cerr << "Done\n";
}
void tst_dl_context() {
symbol relations[] = { symbol("tr_skip"), symbol("tr_sparse"), symbol("tr_hashtable"), symbol("smt_relation2") };
const unsigned rel_cnt = sizeof(relations)/sizeof(symbol);
const char * test_file = "c:\\tvm\\src\\benchmarks\\datalog\\t0.datalog";
params_ref params;
for(unsigned rel_index=0; rel_index<rel_cnt; rel_index++) {
params.set_sym(":default-relation", relations[rel_index]);
for(int eager_checking=1; eager_checking>=0; eager_checking--) {
params.set_bool(":eager-emptiness-checking", eager_checking!=0);
std::cerr << "Testing " << relations[rel_index] << "\n";
std::cerr << "Eager emptiness checking " << (eager_checking!=0 ? "on" : "off") << "\n";
dl_context_simple_query_test(params);
dl_context_saturate_file(params, test_file);
}
}
}

View file

@ -0,0 +1,353 @@
#ifdef _WINDOWS
#include "dl_context.h"
#include "dl_finite_product_relation.h"
#include "dl_sparse_table.h"
namespace datalog {
typedef scoped_rel<table_base> table_aptr;
class collector_of_reduced : public table_row_pair_reduce_fn {
idx_set & m_acc;
public:
collector_of_reduced(idx_set & accumulator) : m_acc(accumulator) {}
virtual void operator()(table_element * func_columns, const table_element * merged_func_columns) {
m_acc.insert(static_cast<unsigned>(merged_func_columns[0]));
}
};
void test_functional_columns(front_end_params fparams, params_ref& params) {
ast_manager m;
context ctx(m, fparams);
ctx.updt_params(params);
relation_manager & rmgr(ctx.get_rmanager());
sparse_table_plugin & plugin =
static_cast<sparse_table_plugin &>(*ctx.get_rmanager().get_table_plugin(symbol("sparse")));
SASSERT(&plugin);
table_signature sig2;
sig2.push_back(2);
sig2.push_back(2);
sig2.set_functional_columns(1);
SASSERT(plugin.can_handle_signature(sig2));
table_fact f00;
f00.push_back(0);
f00.push_back(0);
table_fact f01;
f01.push_back(0);
f01.push_back(1);
table_fact f11;
f11.push_back(1);
f11.push_back(1);
{
table_aptr t0 = plugin.mk_empty(sig2);
SASSERT(t0->empty());
t0->add_fact(f00);
SASSERT(!t0->empty());
SASSERT(t0->get_size_estimate_rows()==1);
t0->add_fact(f01);
SASSERT(t0->get_size_estimate_rows()==1);
t0->add_fact(f11);
SASSERT(t0->get_size_estimate_rows()==2);
unsigned rem_cols0[]={0};
scoped_ptr<table_transformer_fn> project0 = rmgr.mk_project_fn(*t0, 1, rem_cols0);
table_aptr t1 = (*project0)(*t0);
SASSERT(t1->get_size_estimate_rows()==2);
SASSERT(t1->get_signature().functional_columns()==0); //project on non-functional column cancels functional
unsigned rem_cols1[]={1};
scoped_ptr<table_transformer_fn> project1 = rmgr.mk_project_fn(*t0, 1, rem_cols1);
table_aptr t2 = (*project1)(*t0);
SASSERT(t2->get_size_estimate_rows()==2);
idx_set acc;
collector_of_reduced * reducer = alloc(collector_of_reduced, acc);
scoped_ptr<table_transformer_fn> rproject = rmgr.mk_project_with_reduce_fn(*t0, 1, rem_cols0, reducer);
table_aptr rt = (*rproject)(*t0);
SASSERT(acc.num_elems()==1);
SASSERT(rt->get_size_estimate_rows()==1);
}
{
table_aptr t0 = plugin.mk_empty(sig2);
t0->add_fact(f01);
unsigned join_cols[]={1};
scoped_ptr<table_join_fn> join0 = rmgr.mk_join_fn(*t0, *t0, 1, join_cols, join_cols);
table_aptr t1 = (*join0)(*t0, *t0);
SASSERT(t1->get_signature().size()==4);
SASSERT(t1->get_signature().functional_columns()==2);
table_fact f0011;
f0011.push_back(0);
f0011.push_back(0);
f0011.push_back(1);
f0011.push_back(1);
SASSERT(t1->contains_fact(f0011));
table_fact f0111 = f0011;
f0111[1] = 1;
SASSERT(!t1->contains_fact(f0111));
}
{
table_aptr t0 = plugin.mk_empty(sig2);
t0->display(std::cout<<"0:");
SASSERT(t0->get_signature().functional_columns()==1);
table_fact aux_fact;
aux_fact = f01;
TRUSTME( t0->suggest_fact(aux_fact) );
t0->display(std::cout<<"1:");
SASSERT(t0->contains_fact(f01));
SASSERT(aux_fact[1]==1);
aux_fact = f00;
TRUSTME( !t0->suggest_fact(aux_fact) );
t0->display(std::cout<<"2:");
SASSERT(t0->contains_fact(f01));
SASSERT(!t0->contains_fact(f00));
SASSERT(aux_fact[1]==1);
t0->ensure_fact(f00);
t0->display(std::cout<<"3:");
SASSERT(t0->contains_fact(f00));
SASSERT(!t0->contains_fact(f01));
}
}
void test_finite_product_relation(front_end_params fparams, params_ref& params) {
ast_manager m;
context ctx(m, fparams);
ctx.updt_params(params);
dl_decl_util dl_util(m);
relation_manager & rmgr = ctx.get_rmanager();
relation_plugin & rel_plugin = *ctx.get_rmanager().get_relation_plugin(params.get_sym(":default-relation", symbol("sparse")));
SASSERT(&rel_plugin);
finite_product_relation_plugin plg(rel_plugin, rmgr);
sort_ref byte_srt_ref(dl_util.mk_sort(symbol("BYTE"), 256), m);
relation_sort byte_srt = byte_srt_ref;
relation_signature sig2;
sig2.push_back(byte_srt);
sig2.push_back(byte_srt);
relation_signature sig3(sig2);
sig3.push_back(byte_srt);
relation_signature sig4(sig3);
sig4.push_back(byte_srt);
app_ref seven_ref(dl_util.mk_numeral(7, byte_srt), m);
app_ref nine_ref(dl_util.mk_numeral(9, byte_srt), m);
relation_element seven = seven_ref;
relation_element nine = nine_ref;
relation_fact f7(m);
f7.push_back(seven);
relation_fact f9(m);
f9.push_back(nine);
relation_fact f77(f7);
f77.push_back(seven);
relation_fact f79(f7);
f79.push_back(nine);
relation_fact f97(f9);
f97.push_back(seven);
relation_fact f99(f9);
f99.push_back(nine);
relation_fact f779(f77);
f779.push_back(nine);
relation_fact f799(f79);
f799.push_back(nine);
relation_fact f977(f97);
f977.push_back(seven);
relation_fact f7797(f779);
f7797.push_back(seven);
relation_fact f7997(f799);
f7997.push_back(seven);
bool table_cols2[] = { true, false };
bool table_cols3[] = { true, false, false };
bool table_cols4[] = { true, true, false, false };
scoped_rel<relation_base> r1 = plg.mk_empty(sig2, table_cols2);
scoped_rel<relation_base> r2 = r1->clone();
scoped_rel<relation_base> r3 = r2->clone();
SASSERT(!r1->contains_fact(f77));
r1->add_fact(f77);
SASSERT(r1->contains_fact(f77));
r2->add_fact(f79);
r3->add_fact(f99);
r2->display( std::cout << "r2 0\n");
scoped_rel<relation_base> r4 = r2->clone();
r2->display( std::cout << "r2 1\n");
r4->display( std::cout << "r4 0\n");
SASSERT(!r4->contains_fact(f77));
SASSERT(r4->contains_fact(f79));
r4->add_fact(f77);
r4->display( std::cout << "r4 1\n");
SASSERT(r4->contains_fact(f77));
SASSERT(r4->contains_fact(f79));
r4->add_fact(f99);
r4->display( std::cout << "r4 2\n");
SASSERT(r4->contains_fact(f99));
std::cout << "------ testing union ------\n";
r2->display( std::cout << "r2\n");
scoped_ptr<relation_union_fn> union_op = rmgr.mk_union_fn(*r1, *r2, r3.get());
SASSERT(union_op);
(*union_op)(*r1, *r2, r3.get());
r1->display( std::cout << "r1\n");
r2->display( std::cout << "r2\n");
r3->display( std::cout << "r3\n");
SASSERT(r1->contains_fact(f77));
SASSERT(r1->contains_fact(f79));
SASSERT(!r1->contains_fact(f99));
SASSERT(!r3->contains_fact(f77));
SASSERT(r3->contains_fact(f79));
SASSERT(r3->contains_fact(f99));
std::cout << "------ testing join ------\n";
r1->reset();
r1->add_fact(f77);
r1->add_fact(f79);
r1->add_fact(f97);
r2->reset();
r2->add_fact(f97);
r2->add_fact(f99);
unsigned col0[] = { 0 };
unsigned col1[] = { 1 };
scoped_ptr<relation_join_fn> join_tt = rmgr.mk_join_fn(*r1, *r2, 1, col0, col0);
scoped_ptr<relation_join_fn> join_tr = rmgr.mk_join_fn(*r1, *r2, 1, col0, col1);
scoped_ptr<relation_join_fn> join_rr = rmgr.mk_join_fn(*r1, *r2, 1, col1, col1);
r1->display( std::cout << "r1\n");
r2->display( std::cout << "r2\n");
scoped_rel<relation_base> jr_tt = (*join_tt)(*r1, *r2);
scoped_rel<relation_base> jr_tr = (*join_tr)(*r1, *r2);
scoped_rel<relation_base> jr_rr = (*join_rr)(*r1, *r2);
jr_tt->display( std::cout << "tt\n");
jr_tr->display( std::cout << "tr\n");
jr_rr->display( std::cout << "rr\n");
SASSERT(!jr_tt->contains_fact(f7797));
SASSERT(jr_tr->contains_fact(f7797));
SASSERT(jr_rr->contains_fact(f7797));
std::cout << "------ testing project ------\n";
scoped_rel<relation_base> r31 = plg.mk_empty(sig3, table_cols3);
r31->add_fact(f779);
r31->add_fact(f977);
r31->add_fact(f799);
unsigned rem_1_rel[] = { 1 };
unsigned rem_2_rel[] = { 1, 2 };
unsigned rem_1_table[] = { 0 };
scoped_ptr<relation_transformer_fn> proj_1r = rmgr.mk_project_fn(*r31, 1, rem_1_rel);
scoped_ptr<relation_transformer_fn> proj_2r = rmgr.mk_project_fn(*r31, 2, rem_2_rel);
scoped_ptr<relation_transformer_fn> proj_1t = rmgr.mk_project_fn(*r31, 1, rem_1_table);
scoped_rel<relation_base> sr_1r = (*proj_1r)(*r31);
scoped_rel<relation_base> sr_2r = (*proj_2r)(*r31);
scoped_rel<relation_base> sr_1t = (*proj_1t)(*r31);
SASSERT(sr_1r->contains_fact(f79));
SASSERT(sr_1r->contains_fact(f97));
SASSERT(!sr_1r->contains_fact(f77));
SASSERT(sr_2r->contains_fact(f7));
SASSERT(sr_2r->contains_fact(f9));
SASSERT(sr_1t->contains_fact(f79));
SASSERT(!sr_1t->contains_fact(f97));
SASSERT(sr_1t->contains_fact(f77));
SASSERT(sr_1t->contains_fact(f99));
std::cout << "------ testing filter_interpreted ------\n";
scoped_rel<relation_base> r41 = plg.mk_empty(sig4, table_cols4);
r41->add_fact(f7797);
r41->add_fact(f7997);
app_ref cond(m.mk_and(
m.mk_not(m.mk_eq(m.mk_var(1,byte_srt), m.mk_var(2,byte_srt))), //#1!=#2
m.mk_not(m.mk_eq(m.mk_var(3,byte_srt), m.mk_var(2,byte_srt))) //#3!=#2
), m);
scoped_ptr<relation_mutator_fn> i_filter = rmgr.mk_filter_interpreted_fn(*r41, cond);
(*i_filter)(*r41);
SASSERT(r41->contains_fact(f7797));
SASSERT(!r41->contains_fact(f7997));
std::cout << "------ testing filter_by_negation ------\n";
r31->reset();
r31->add_fact(f779);
r31->add_fact(f977);
r31->add_fact(f799);
r1->reset();
r1->add_fact(f77);
r1->add_fact(f79);
unsigned nf_r31_cols[] = {1, 0, 1};
unsigned nf_r1_cols[] = {0, 0, 1};
scoped_ptr<relation_intersection_filter_fn> neg_filter = rmgr.mk_filter_by_negation_fn(*r31, *r1, 3,
nf_r31_cols, nf_r1_cols);
(*neg_filter)(*r31, *r1);
SASSERT(!r31->contains_fact(f779));
SASSERT(r31->contains_fact(f977));
SASSERT(r31->contains_fact(f799));
}
}
using namespace datalog;
void tst_dl_product_relation() {
front_end_params fparams;
params_ref params;
test_functional_columns(fparams, params);
params.set_sym(":default-relation", symbol("tr_sparse"));
test_finite_product_relation(fparams, params);
}
#else
void tst_dl_product_relation() {
}
#endif

239
src/test/dl_query.cpp Normal file
View file

@ -0,0 +1,239 @@
#include "datalog_parser.h"
#include "ast_pp.h"
#include "dl_table_relation.h"
#include "dl_context.h"
#include "front_end_params.h"
#include"stopwatch.h"
using namespace datalog;
void dl_query_ask_ground_query(context & ctx, func_decl * pred, relation_fact & f, bool should_be_successful) {
expr * const * q_args = reinterpret_cast<expr * const *>(f.c_ptr());
app * query = ctx.get_manager().mk_app(pred, q_args);
lbool is_sat = ctx.query(query);
std::cerr << "@@ query should succeed: " << should_be_successful << "\n";
SASSERT(is_sat != l_undef);
if((is_sat != l_true) == should_be_successful) {
std::cerr<<"wrong ground query answer!\n";
UNREACHABLE();
}
}
void dl_query_ask_for_last_arg(context & ctx, func_decl * pred, relation_fact & f, bool should_be_successful) {
ast_manager & m = ctx.get_manager();
expr_ref_vector query_args(m);
push_into_vector(query_args, f);
query_args.pop_back();
query_args.push_back(m.mk_var(0, pred->get_domain(query_args.size())));
app * query = ctx.get_manager().mk_app(pred, query_args.c_ptr());
lbool is_sat = ctx.query(query);
std::cerr << "@@ last arg query should succeed: " << should_be_successful << "\n";
SASSERT(is_sat != l_undef);
relation_fact res_fact(m);
res_fact.push_back(f.back());
if(ctx.result_contains_fact(res_fact)!=should_be_successful) {
std::cerr<<"wrong arg query answer!\n";
UNREACHABLE();
}
}
void dl_query_test(ast_manager & m, front_end_params & fparams, params_ref& params,
context & ctx_b, char const* problem_file, unsigned test_count,
bool use_magic_sets) {
dl_decl_util decl_util(m);
relation_manager & rel_mgr_b = ctx_b.get_rmanager();
context ctx_q(m, fparams);
params.set_bool(":magic-sets-for-queries", use_magic_sets);
ctx_q.updt_params(params);
{
parser* p = parser::create(ctx_q,m);
TRUSTME( p->parse_file(problem_file) );
dealloc(p);
}
relation_manager & rel_mgr_q = ctx_b.get_rmanager();
decl_set out_preds = ctx_b.get_output_predicates();
decl_set::iterator it = out_preds.begin();
decl_set::iterator end = out_preds.end();
for(; it!=end; ++it) {
func_decl * pred_b = *it;
std::cerr << "Checking queries on relation " << pred_b->get_name() << "\n";
func_decl * pred_q = ctx_q.try_get_predicate_decl(symbol(pred_b->get_name().bare_str()));
SASSERT(pred_q);
relation_base & rel_b = ctx_b.get_relation(pred_b);
relation_signature sig_b = rel_b.get_signature();
relation_signature sig_q = ctx_q.get_relation(pred_q).get_signature();
SASSERT(sig_b.size()==sig_q.size());
std::cerr << "Queries on random facts...\n";
relation_fact f_b(m);
relation_fact f_q(m);
for(unsigned attempt=0; attempt<test_count; attempt++) {
f_b.reset();
f_q.reset();
for(unsigned col=0; col<sig_b.size(); col++) {
uint64 sort_sz;
if(!decl_util.try_get_size(sig_q[col], sort_sz)) {
warning_msg("cannot get sort size");
return;
}
uint64 num = rand()%sort_sz;
app * el_b = decl_util.mk_numeral(num, sig_b[col]);
f_b.push_back(el_b);
app * el_q = decl_util.mk_numeral(num, sig_q[col]);
f_q.push_back(el_q);
}
bool found_in_b = rel_b.contains_fact(f_b);
dl_query_ask_ground_query(ctx_q, pred_q, f_q, found_in_b);
dl_query_ask_for_last_arg(ctx_q, pred_q, f_q, found_in_b);
}
std::cerr << "Queries on table facts...\n";
if(!rel_b.from_table()) {
warning_msg("relation is not a table_relation, skipping queries on facts");
}
table_relation & tr_b = static_cast<table_relation &>(rel_b);
table_base & table_b = tr_b.get_table();
table_fact tf;
unsigned table_sz = table_b.get_size_estimate_rows();
table_base::iterator fit = table_b.begin();
table_base::iterator fend = table_b.end();
for(; fit!=fend; ++fit) {
if(rand()%std::max(1u,table_sz/test_count)!=0) {
continue;
}
fit->get_fact(tf);
rel_mgr_q.table_fact_to_relation(sig_q, tf, f_q);
dl_query_ask_ground_query(ctx_q, pred_q, f_q, true);
dl_query_ask_for_last_arg(ctx_q, pred_q, f_q, true);
}
std::cerr << "Done.\n";
}
}
void dl_query_test_wpa(front_end_params & fparams, params_ref& params) {
params.set_bool(":magic-sets-for-queries", true);
ast_manager m;
m.register_decl_plugins();
arith_util arith(m);
const char * problem_dir = "C:\\tvm\\src\\z3_2\\debug\\test\\w0.datalog";
dl_decl_util dl_util(m);
std::cerr << "Testing queries on " << problem_dir <<"\n";
context ctx(m, fparams);
ctx.updt_params(params);
{
wpa_parser* p = wpa_parser::create(ctx, m);
TRUSTME( p->parse_directory(problem_dir) );
dealloc(p);
}
const unsigned attempts = 10;
func_decl * v_pred = ctx.try_get_predicate_decl(symbol("V"));
SASSERT(v_pred);
sort * var_sort = v_pred->get_domain(0);
uint64 var_sz;
TRUSTME( ctx.try_get_sort_constant_count(var_sort, var_sz) );
for(unsigned attempt=0; attempt<attempts; attempt++) {
unsigned el1 = rand()%var_sz;
unsigned el2 = rand()%var_sz;
expr_ref_vector q_args(m);
q_args.push_back(dl_util.mk_numeral(el1, var_sort));
q_args.push_back(dl_util.mk_numeral(el2, var_sort));
app_ref query_lit(m.mk_app(v_pred, q_args.c_ptr()), m);
lbool is_sat = ctx.query(query_lit);
SASSERT(is_sat != l_undef);
bool found = is_sat == l_true;
std::cerr<<"query finished: "<<found<<"\n";
relation_fact ans_fact(m);
ans_fact.push_back(to_app(q_args.back()));
q_args.pop_back();
q_args.push_back(m.mk_var(0, var_sort));
query_lit = m.mk_app(v_pred, q_args.c_ptr());
is_sat = ctx.query(query_lit.get());
SASSERT(is_sat != l_false);
std::cerr<<"non-ground query finished\n";
if(ctx.result_contains_fact(ans_fact)!=found) {
std::cerr<<"wrong wpa answer!\n";
UNREACHABLE();
}
}
}
void tst_dl_query() {
front_end_params fparams;
params_ref params;
params.set_sym(":default-table", symbol("sparse"));
params.set_sym(":default-relation", symbol("tr_sparse"));
//params.m_dl_default_table = symbol("hashtable");
//params.m_dl_default_relation = symbol("tr_hashtable");
//dl_query_test_wpa(params);
ast_manager m;
//const char * problem_file = "C:\\tvm\\src\\z3_2\\debug\\test\\test1.datalog";
//const char * problem_file = "C:\\tvm\\src\\benchmarks\\datalog\\test.datalog";
const char * problem_file = "C:\\tvm\\src\\benchmarks\\datalog\\t0.datalog";
//const char * problem_file = "C:\\tvm\\src\\benchmarks\\datalog\\p0.datalog";
std::cerr << "Testing queries on " << problem_file <<"\n";
context ctx_base(m, fparams);
ctx_base.updt_params(params);
{
parser* p = parser::create(ctx_base,m);
TRUSTME( p->parse_file(problem_file) );
dealloc(p);
}
ctx_base.dl_saturate();
for(unsigned use_restarts=0; use_restarts<=1; use_restarts++) {
params.set_uint(":initial-restart-timeout", use_restarts ? 100 : 0);
for(unsigned use_similar=0; use_similar<=1; use_similar++) {
params.set_uint(":similarity-compressor", use_similar != 0);
for(unsigned use_magic_sets=0; use_magic_sets<=1; use_magic_sets++) {
stopwatch watch;
watch.start();
std::cerr << "------- " << (use_restarts ? "With" : "Without") << " restarts -------\n";
std::cerr << "------- " << (use_similar ? "With" : "Without") << " similar compressor -------\n";
std::cerr << "------- " << (use_magic_sets ? "With" : "Without") << " magic sets -------\n";
dl_query_test(m, fparams, params, ctx_base, problem_file, 1, use_magic_sets!=0);
watch.stop();
std::cout << (use_restarts ? "With" : "Without") << " restarts\n";
std::cout << (use_similar ? "With" : "Without") << " similar compressor\n";
std::cout << (use_magic_sets ? "With" : "Without") << " magic sets\n";
std::cout << "Time: " << watch.get_current_seconds() << "\n\n";
std::cerr << "Time: " << watch.get_current_seconds() << "\n";
}
}
}
}

288
src/test/dl_relation.cpp Normal file
View file

@ -0,0 +1,288 @@
#ifdef _WINDOWS
#include "dl_context.h"
#include "dl_interval_relation.h"
#include "dl_bound_relation.h"
#include "dl_product_relation.h"
#include "util.h"
namespace datalog {
static void test_interval_relation() {
front_end_params params;
ast_manager ast_m;
context ctx(ast_m, params);
arith_util autil(ast_m);
relation_manager & m = ctx.get_rmanager();
m.register_plugin(alloc(interval_relation_plugin, m));
interval_relation_plugin& ip = dynamic_cast<interval_relation_plugin&>(*m.get_relation_plugin(symbol("interval_relation")));
SASSERT(&ip);
relation_signature sig;
sort* int_sort = autil.mk_int();
sig.push_back(int_sort);
sig.push_back(int_sort);
sig.push_back(int_sort);
sig.push_back(int_sort);
interval_relation& i1 = dynamic_cast<interval_relation&>(*ip.mk_empty(sig));
interval_relation& i2 = dynamic_cast<interval_relation&>(*ip.mk_full(0, sig));
i1.display(std::cout);
i2.display(std::cout);
SASSERT(i1.empty());
SASSERT(!i2.empty());
app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m);
app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m);
app_ref num1(ast_m);
cond1 = autil.mk_le(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true));
cond2 = autil.mk_le(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(1), true));
cond3 = autil.mk_le(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(2), true));
cond4 = autil.mk_ge(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true));
cond5 = autil.mk_ge(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(0), true));
cond6 = autil.mk_ge(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(5), true));
num1 = autil.mk_numeral(rational(4), true);
i2.filter_interpreted(cond1);
i2.display(std::cout);
// x0 <= 0
unsigned cols1[2] = { 1, 2};
unsigned cols2[2] = { 2, 3};
relation_join_fn* join1 = ip.mk_join_fn(i1, i2, 2, cols1, cols2);
relation_transformer_fn* proj1 = ip.mk_project_fn(i1, 2, cols2);
relation_transformer_fn* ren1 = ip.mk_rename_fn(i1, 2, cols2);
relation_union_fn* union1 = ip.mk_union_fn(i1, i2, &i1);
relation_mutator_fn* filterId1 = ip.mk_filter_identical_fn(i1, 2, cols1);
relation_mutator_fn* filterEq1 = ip.mk_filter_equal_fn(i1, num1, 2);
relation_mutator_fn* filterCond1 = ip.mk_filter_interpreted_fn(i1, cond2);
relation_base* i3 = (*join1)(i2, i2);
i3->display(std::cout);
relation_transformer_fn* proj2 = ip.mk_project_fn(*i3, 2, cols2);
(*filterEq1)(i2);
i2.display(std::cout);
// x0 <= 0
// x2 = 4
(*filterId1)(i2);
i2.display(std::cout);
// x0 <= 0
// x1 = x2 = 4
relation_fact fact1(ast_m);
fact1.push_back(autil.mk_numeral(rational(0), true));
fact1.push_back(autil.mk_numeral(rational(4), true));
fact1.push_back(autil.mk_numeral(rational(4), true));
fact1.push_back(autil.mk_numeral(rational(5), true));
SASSERT(i2.contains_fact(fact1));
fact1[0] = autil.mk_numeral(rational(-1), true);
SASSERT(i2.contains_fact(fact1));
fact1[0] = autil.mk_numeral(rational(1), true);
SASSERT(!i2.contains_fact(fact1));
relation_base* i5 = (*ren1)(i2);
i2.display(std::cout << "Orig\n");
i5->display(std::cout << "renamed 2 |-> 3 |-> 2\n");
(*filterCond1)(i2);
i2.display(std::cout);
// empty
SASSERT(i2.empty());
relation_base* i4 = (*proj2)(*i3);
i4->display(std::cout);
i1.deallocate();
i2.deallocate();
i3->deallocate();
i4->deallocate();
i5->deallocate();
dealloc(join1);
dealloc(proj1);
dealloc(ren1);
dealloc(union1);
dealloc(filterId1);
dealloc(filterEq1);
dealloc(filterCond1);
}
static void test_bound_relation() {
std::cout << "bound relation\n";
front_end_params params;
ast_manager ast_m;
context ctx(ast_m, params);
arith_util autil(ast_m);
relation_manager & m = ctx.get_rmanager();
m.register_plugin(alloc(bound_relation_plugin, m));
bound_relation_plugin& br = dynamic_cast<bound_relation_plugin&>(*m.get_relation_plugin(symbol("bound_relation")));
SASSERT(&br);
relation_signature sig;
sort* int_sort = autil.mk_int();
sig.push_back(int_sort);
sig.push_back(int_sort);
sig.push_back(int_sort);
sig.push_back(int_sort);
bound_relation& i1 = dynamic_cast<bound_relation&>(*br.mk_empty(sig));
bound_relation& i2 = dynamic_cast<bound_relation&>(*br.mk_full(0, sig));
i1.display(std::cout << "empty:\n");
i2.display(std::cout << "full:\n");
SASSERT(i1.empty());
SASSERT(!i2.empty());
app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m);
app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m);
app_ref num1(ast_m);
cond1 = autil.mk_lt(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true));
cond2 = autil.mk_lt(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(1), true));
cond3 = autil.mk_lt(ast_m.mk_var(2, int_sort), ast_m.mk_var(3, int_sort));
cond4 = autil.mk_ge(ast_m.mk_var(0, int_sort), autil.mk_numeral(rational(0), true));
cond5 = autil.mk_ge(ast_m.mk_var(1, int_sort), autil.mk_numeral(rational(0), true));
cond6 = autil.mk_ge(ast_m.mk_var(2, int_sort), autil.mk_numeral(rational(5), true));
app_ref lt_x0x1(ast_m), lt_x1x2(ast_m), lt_x0x3(ast_m), lt_x0x2(ast_m);
lt_x0x1 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(1, int_sort));
lt_x1x2 = autil.mk_lt(ast_m.mk_var(1, int_sort), ast_m.mk_var(2, int_sort));
lt_x0x2 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(2, int_sort));
lt_x0x3 = autil.mk_lt(ast_m.mk_var(0, int_sort), ast_m.mk_var(3, int_sort));
num1 = autil.mk_numeral(rational(4), true);
unsigned cols1[2] = { 1, 2};
unsigned cols2[2] = { 2, 3};
unsigned cols3[3] = { 0, 2, 3 };
relation_join_fn* join1 = br.mk_join_fn(i1, i2, 2, cols1, cols2);
relation_transformer_fn* proj1 = br.mk_project_fn(i1, 2, cols2);
relation_transformer_fn* ren1 = br.mk_rename_fn(i1, 3, cols3);
relation_union_fn* union1 = br.mk_union_fn(i1, i2, &i1);
relation_mutator_fn* filterId1 = br.mk_filter_identical_fn(i1, 2, cols1);
relation_mutator_fn* filterEq1 = br.mk_filter_equal_fn(i1, num1, 2);
relation_mutator_fn* filterCond1 = br.mk_filter_interpreted_fn(i1, cond3);
relation_base* i3 = (*join1)(i2, i2);
i3->display(std::cout);
relation_transformer_fn* proj2 = br.mk_project_fn(*i3, 2, cols2);
(*filterEq1)(i2);
i2.display(std::cout << "no-op still full\n");
// no-op
(*filterCond1)(i2);
i2.display(std::cout << "x2 < x3\n");
// x2 < x3
(*filterId1)(i2);
i2.display(std::cout << "id\n");
// x1 = x2 < x3
relation_fact fact1(ast_m);
i2.display(std::cout << "Orig\n");
std::cout << "renamed ";
for (unsigned i = 0; i < 3; ++i) {
std::cout << cols3[i] << " ";
}
std::cout << "\n";
relation_base* i5 = (*ren1)(i2);
i5->display(std::cout);
//SASSERT(i2.empty());
relation_base* i4 = (*proj2)(*i3);
i4->display(std::cout);
// test that equivalence classes are expanded.
// { x1 = x3, x0 < x1 x1 < x2} u { x2 = x3, x0 < x3 } = { x0 < x3 }
{
relation_base* b1 = br.mk_full(0, sig);
relation_base* b2 = br.mk_full(0, sig);
unsigned x1x3[2] = { 1, 3 };
unsigned x2x3[2] = { 2, 3 };
scoped_ptr<relation_mutator_fn> id1 = br.mk_filter_identical_fn(*b1, 2, x1x3);
scoped_ptr<relation_mutator_fn> ltx0x1 = br.mk_filter_interpreted_fn(*b1, lt_x0x1);
scoped_ptr<relation_mutator_fn> ltx1x2 = br.mk_filter_interpreted_fn(*b1, lt_x1x2);
scoped_ptr<relation_mutator_fn> ltx0x3 = br.mk_filter_interpreted_fn(*b2, lt_x0x3);
scoped_ptr<relation_mutator_fn> id2 = br.mk_filter_identical_fn(*b2, 2, x2x3);
(*id1)(*b1);
(*ltx0x1)(*b1);
(*ltx1x2)(*b1);
b2->display(std::cout << "b2:\n");
(*id2)(*b2);
b2->display(std::cout << "b2:\n");
(*ltx0x3)(*b2);
b2->display(std::cout << "b2:\n");
scoped_ptr<relation_union_fn> u = br.mk_union_fn(*b1, *b2, 0);
b1->display(std::cout << "b1:\n");
b2->display(std::cout << "b2:\n");
(*u)(*b1, *b2, 0);
b1->display(std::cout << "b1 u b2:\n");
// TBD check property;
b1->deallocate();
b2->deallocate();
}
// test that equivalence classes are expanded.
// { x1 = x2 = x3, x0 < x1} u { x1 = x3, x0 < x3, x0 < x2 } = { x0 < x2, x0 < x3 }
{
relation_base* b1 = br.mk_full(0, sig);
relation_base* b2 = br.mk_full(0, sig);
unsigned x0x3[2] = { 0, 3 };
unsigned x1x3[2] = { 1, 3 };
unsigned x2x3[2] = { 2, 3 };
scoped_ptr<relation_mutator_fn> id1 = br.mk_filter_identical_fn(*b1, 2, x1x3);
scoped_ptr<relation_mutator_fn> id2 = br.mk_filter_identical_fn(*b1, 2, x2x3);
scoped_ptr<relation_mutator_fn> ltx0x1 = br.mk_filter_interpreted_fn(*b1, lt_x0x1);
scoped_ptr<relation_mutator_fn> ltx0x2 = br.mk_filter_interpreted_fn(*b2, lt_x0x2);
scoped_ptr<relation_mutator_fn> ltx0x3 = br.mk_filter_interpreted_fn(*b2, lt_x0x3);
scoped_ptr<relation_mutator_fn> id3 = br.mk_filter_identical_fn(*b2, 2, x1x3);
(*id1)(*b1);
(*id2)(*b1);
(*ltx0x1)(*b1);
(*id3)(*b2);
(*ltx0x2)(*b2);
(*ltx0x3)(*b2);
scoped_ptr<relation_union_fn> u = br.mk_union_fn(*b1, *b2, 0);
b1->display(std::cout << "b1:\n");
b2->display(std::cout << "b2:\n");
(*u)(*b1, *b2, 0);
b1->display(std::cout << "b1 u b2:\n");
// TBD check property;
b1->deallocate();
b2->deallocate();
}
i1.deallocate();
i2.deallocate();
i3->deallocate();
i4->deallocate();
i5->deallocate();
dealloc(join1);
dealloc(proj1);
dealloc(ren1);
dealloc(union1);
dealloc(filterId1);
dealloc(filterEq1);
dealloc(filterCond1);
}
}
void tst_dl_relation() {
datalog::test_interval_relation();
datalog::test_bound_relation();
}
#else
void tst_dl_relation() {
}
#endif

118
src/test/dl_rule_set.cpp Normal file
View file

@ -0,0 +1,118 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
dl_rule_set.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-05-18.
Revision History:
--*/
#include"dl_context.h"
#include"dl_rule_set.h"
#include"dl_mk_filter_rules.h"
#include"dl_mk_simple_joins.h"
#include"smtparser.h"
#include"ast_pp.h"
#include<iostream>
#include<sstream>
void tst_dl_rule_set() {
enable_trace("mk_filter_rules");
front_end_params params;
ast_manager m;
smtlib::parser * parser = smtlib::parser::create(m);
parser->initialize_smtlib();
datalog::context ctx(m, params);
datalog::rule_set rs(ctx);
datalog::rule_manager& rm = ctx.get_rule_manager();
datalog::rule_ref_vector rv(rm);
if (!parser->parse_string(
"(benchmark test\n"
":extrapreds ((T Int Int) (Q Int Int) (R Int Int Int) (S Int Int Int) (DynActual Int Int Int) (GlobalSym Int Int) (HeapPointsTo Int Int Int) (Calls Int Int)) \n"
":extrapreds ((Actual Int Int Int) (PointsTo Int Int) (PointsTo0 Int Int) (FuncDecl0 Int Int) (Assign Int Int) (Load Int Int Int))\n"
":formula (forall (x Int) (=> (Q x 1) (T x x)))\n"
":formula (forall (v Int) (h Int) (=> (PointsTo0 v h) (PointsTo v h)))\n"
":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n"
":formula (forall (v Int) (h Int) (=> (FuncDecl0 v h) (PointsTo v h)))\n"
":formula (forall (v1 Int) (v2 Int) (h Int) (=> (and (PointsTo v2 h) (Assign v1 v2)) (PointsTo v1 h)))\n"
":formula (forall (x Int) (y Int) (z Int) (=> (and (Q x y) (T y z)) (T x y)))\n"
":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 0 h1) (PointsTo v h1)) (DynActual i1 2 v)))\n"
":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 1 h1) (PointsTo v h1)) (DynActual i1 3 v)))\n"
":formula (forall (i1 Int) (v Int) (fun Int) (c Int) (v1 Int) (h Int) (h1 Int) (=> (and (GlobalSym 0 fun) (HeapPointsTo fun 1 c) (Calls i1 c) (Actual i1 3 v1) (PointsTo v1 h) (HeapPointsTo h 2 h1) (PointsTo v h1)) (DynActual i1 4 v)))\n"
":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 f) (PointsTo v1 h1) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n"
":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (Load v2 v1 0) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n"
":formula (forall (v1 Int) (v2 Int) (h1 Int) (h2 Int) (f Int) (=> (and (not (Load v2 v1 0)) (HeapPointsTo h1 f h2)) (PointsTo v2 h1)))\n"
")")) {
SASSERT(false);
dealloc(parser);
return;
}
smtlib::benchmark * b = parser->get_benchmark();
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
expr * e = b->begin_formulas()[j];
ptr_vector<expr> todo;
todo.push_back(e);
while (!todo.empty()) {
e = todo.back();
todo.pop_back();
if (is_quantifier(e)) {
e = to_quantifier(e)->get_expr();
todo.push_back(e);
}
else if (is_app(e)) {
app* a = to_app(e);
if (is_uninterp(e) && !ctx.is_predicate(a->get_decl())) {
std::cout << "registering " << a->get_decl()->get_name() << "\n";
ctx.register_predicate(a->get_decl());
}
else {
todo.append(a->get_num_args(), a->get_args());
}
}
}
}
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
expr * e = b->begin_formulas()[j];
if (is_quantifier(e)) {
try {
rm.mk_rule(e, rv);
}
catch(...) {
std::cerr << "ERROR: it is not a valid Datalog rule:\n" << mk_pp(e, m) << "\n";
}
}
}
rs.add_rules(rv.size(), rv.c_ptr());
rs.display(std::cout);
datalog::mk_filter_rules p(ctx);
model_converter_ref mc;
proof_converter_ref pc;
datalog::rule_set * new_rs = p(rs, mc, pc);
std::cout << "\nAfter mk_filter:\n";
new_rs->display(std::cout);
datalog::mk_simple_joins p2(ctx);
datalog::rule_set * new_rs2 = p2(*new_rs, mc, pc);
std::cout << "\nAfter mk_simple_joins:\n";
new_rs2->display(std::cout);
dealloc(new_rs);
dealloc(new_rs2);
dealloc(parser);
}

View file

@ -0,0 +1,233 @@
#include "dl_smt_relation.h"
#include "arith_decl_plugin.h"
#include "dl_context.h"
#include "z3.h"
#include "z3_private.h"
namespace datalog {
void test_smt_relation_unit() {
ast_manager m;
m.register_decl_plugins();
arith_util a(m);
sort* int_sort = a.mk_int();
sort* real_sort = a.mk_real();
front_end_params params;
context ctx(m, params);
relation_manager & rm = ctx.get_rmanager();
relation_signature sig1;
sig1.push_back(int_sort);
sig1.push_back(int_sort);
sig1.push_back(real_sort);
smt_relation_plugin plugin(rm);
scoped_rel<relation_base> r1 = plugin.mk_empty(sig1);
// add_fact
relation_fact fact1(m);
fact1.push_back(a.mk_numeral(rational(1), true));
fact1.push_back(a.mk_numeral(rational(2), true));
fact1.push_back(a.mk_numeral(rational(3), false));
relation_fact fact2(m);
fact2.push_back(a.mk_numeral(rational(2), true));
fact2.push_back(a.mk_numeral(rational(2), true));
fact2.push_back(a.mk_numeral(rational(3), false));
r1->add_fact(fact1);
r1->display(std::cout << "r1: ");
// contains_fact
SASSERT(r1->contains_fact(fact1));
SASSERT(!r1->contains_fact(fact2));
// empty
scoped_rel<relation_base> r2 = plugin.mk_empty(sig1);
SASSERT(!r1->empty());
SASSERT(r2->empty());
// clone
scoped_rel<relation_base> r3 = r1->clone();
// complement?
r2->add_fact(fact2);
scoped_rel<relation_base> r4 = dynamic_cast<smt_relation&>(*r2).complement(0);
r4->display(std::cout << "complement r4: " );
// join
unsigned col_cnt = 2;
unsigned cols1[2] = {1, 2};
unsigned cols2[2] = {0, 2};
scoped_ptr<relation_join_fn> joinfn = plugin.mk_join_fn(*r1, *r4, col_cnt, cols1, cols2);
scoped_rel<relation_base> r5 = (*joinfn)(*r1, *r4);
r5->display(std::cout<< "join r5: ");
relation_fact fact3(m);
fact3.push_back(a.mk_numeral(rational(1), true));
fact3.push_back(a.mk_numeral(rational(2), true));
fact3.push_back(a.mk_numeral(rational(3), false));
fact3.push_back(a.mk_numeral(rational(2), true));
fact3.push_back(a.mk_numeral(rational(2), true));
fact3.push_back(a.mk_numeral(rational(3), false));
SASSERT(!r5->contains_fact(fact3));
fact3[5] = a.mk_numeral(rational(4), false);
SASSERT(!r5->contains_fact(fact3));
fact3[5] = a.mk_numeral(rational(3), false);
fact3[4] = a.mk_numeral(rational(3), true);
SASSERT(r5->contains_fact(fact3));
// project
unsigned removed_cols[2] = { 1, 4 };
scoped_ptr<relation_transformer_fn> projfn = plugin.mk_project_fn(*r5, col_cnt, removed_cols);
scoped_rel<relation_base> r6 = (*projfn)(*r5);
r6->display(std::cout<< "project r6: ");
// rename
unsigned cycle[3] = { 0, 2, 4 };
unsigned cycle_len = 3;
scoped_rel<relation_transformer_fn> renamefn = plugin.mk_rename_fn(*r5, cycle_len, cycle);
scoped_rel<relation_base> r7 = (*renamefn)(*r5);
r7->display(std::cout << "rename r7: ");
// union
// widen
relation_base* delta = 0;
scoped_ptr<relation_union_fn> widenfn = plugin.mk_widen_fn(*r1, *r2, delta);
scoped_ptr<relation_union_fn> unionfn = plugin.mk_union_fn(*r1, *r2, delta);
scoped_rel<relation_base> r8 = r1->clone();
(*unionfn)(*r8,*r2,0);
r8->display(std::cout << "union r8: ");
// filter_identical
unsigned identical_cols[2] = { 1, 3 };
scoped_ptr<relation_mutator_fn> filti = plugin.mk_filter_identical_fn(*r5, col_cnt, identical_cols);
scoped_rel<relation_base> r9 = r1->clone();
(*filti)(*r9);
r9->display(std::cout << "filter identical r9: ");
// filter_equal
app_ref value(m);
value = m.mk_const(symbol("x"), int_sort);
scoped_rel<relation_mutator_fn> eqn = plugin.mk_filter_equal_fn(*r5, value.get(), 3);
scoped_rel<relation_base> r10 = r1->clone();
(*eqn)(*r10);
r10->display(std::cout << "filter equal r10: ");
// filter_interpreted
app_ref cond(m);
cond = a.mk_lt(m.mk_var(3, int_sort), m.mk_var(4, int_sort));
scoped_rel<relation_mutator_fn> filtint = plugin.mk_filter_interpreted_fn(*r5, cond);
scoped_rel<relation_base> r11 = r5->clone();
(*filtint)(*r11);
r11->display(std::cout << "filter interpreted r11: ");
}
void test_smt_relation_api() {
enable_trace("smt_relation");
enable_trace("smt_relation2");
enable_trace("quant_elim");
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg, "DL_DEFAULT_RELATION", "smt_relation2");
Z3_context ctx = Z3_mk_context(cfg);
Z3_fixedpoint dl = Z3_mk_fixedpoint(ctx);
Z3_fixedpoint_inc_ref(ctx,dl);
Z3_del_config(cfg);
Z3_sort int_sort = Z3_mk_int_sort(ctx);
Z3_sort bool_sort = Z3_mk_bool_sort(ctx);
Z3_func_decl nil_decl, is_nil_decl;
Z3_func_decl cons_decl, is_cons_decl, head_decl, tail_decl;
Z3_sort list = Z3_mk_list_sort(
ctx,
Z3_mk_string_symbol(ctx, "list"),
int_sort,
&nil_decl,
&is_nil_decl,
&cons_decl,
&is_cons_decl,
&head_decl,
&tail_decl);
Z3_sort listint[2] = { list, int_sort };
Z3_symbol p_sym = Z3_mk_string_symbol(ctx, "p");
Z3_symbol q_sym = Z3_mk_string_symbol(ctx, "q");
Z3_func_decl p = Z3_mk_func_decl(ctx, p_sym, 2, listint, bool_sort);
Z3_func_decl q = Z3_mk_func_decl(ctx, q_sym, 2, listint, bool_sort);
Z3_fixedpoint_register_relation(ctx, dl, p);
Z3_fixedpoint_register_relation(ctx, dl, q);
Z3_ast zero = Z3_mk_numeral(ctx, "0", int_sort);
Z3_ast one = Z3_mk_numeral(ctx, "1", int_sort);
Z3_ast two = Z3_mk_numeral(ctx, "2", int_sort);
Z3_ast x = Z3_mk_bound(ctx, 0, list);
Z3_ast y = Z3_mk_bound(ctx, 1, int_sort);
Z3_ast z = Z3_mk_bound(ctx, 2, list);
Z3_ast zero_x[2] = { zero, x };
Z3_ast fx = Z3_mk_app(ctx, cons_decl, 2, zero_x);
Z3_ast zero_fx[2] = { zero, fx };
Z3_ast ffx = Z3_mk_app(ctx, cons_decl, 2, zero_fx);
Z3_ast xy[2] = { x, y };
Z3_ast zy[2] = { z, y };
Z3_ast ffxy[2] = { ffx, y };
Z3_ast fxy[2] = { fx, y };
Z3_ast zero_nil[2] = { zero, Z3_mk_app(ctx, nil_decl, 0, 0) };
Z3_ast f0 = Z3_mk_app(ctx, cons_decl, 2, zero_nil);
Z3_ast zero_f0[2] = { zero, f0 };
Z3_ast f1 = Z3_mk_app(ctx, cons_decl, 2, zero_f0);
Z3_ast zero_f1[2] = { zero, f1 };
Z3_ast f2 = Z3_mk_app(ctx, cons_decl, 2, zero_f1);
Z3_ast zero_f2[2] = { zero, f2 };
Z3_ast f3 = Z3_mk_app(ctx, cons_decl, 2, zero_f2);
Z3_ast zero_f3[2] = { zero, f3 };
Z3_ast f4 = Z3_mk_app(ctx, cons_decl, 2, zero_f3);
Z3_ast zero_f4[2] = { zero, f4 };
Z3_ast f5 = Z3_mk_app(ctx, cons_decl, 2, zero_f4);
Z3_ast zero_z[2] = { zero, z };
Z3_ast fz = Z3_mk_app(ctx, cons_decl, 2, zero_z);
Z3_ast pxy = Z3_mk_app(ctx, p, 2, xy);
Z3_ast pzy = Z3_mk_app(ctx, p, 2, zy);
Z3_ast qxy = Z3_mk_app(ctx, q, 2, xy);
Z3_ast qzy = Z3_mk_app(ctx, q, 2, zy);
Z3_ast even_y = Z3_mk_eq(ctx, zero, Z3_mk_mod(ctx, y, two));
Z3_ast odd_y = Z3_mk_eq(ctx, one, Z3_mk_mod(ctx, y, two));
// p(x, y) :- odd(y), p(z,y), f(z) = x . // dead rule.
// q(x, y) :- p(f(f(x)), y).
// p(x, y) :- q(f(x), y) // x decreases
// p(x, y) :- even y, x = f^5(0) // initial condition.
Z3_ast body1[3] = { pzy, Z3_mk_eq(ctx, fz, x), odd_y };
Z3_ast body2[2] = { pzy, Z3_mk_eq(ctx, ffx, z) };
Z3_ast body3[2] = { qzy, Z3_mk_eq(ctx, fx, z) };
Z3_ast body4[2] = { even_y, Z3_mk_eq(ctx, x, f5) };
Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 3, body1), pxy), 0);
Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body2), qxy), 0);
Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body3), pxy), 0);
Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body4), pxy), 0);
Z3_lbool r = Z3_fixedpoint_query(ctx, dl, pxy);
if (r != l_undef) {
std::cout << Z3_ast_to_string(ctx, Z3_fixedpoint_get_answer(ctx, dl)) << "\n";
}
Z3_del_context(ctx);
}
};
void tst_dl_smt_relation() {
datalog::test_smt_relation_api();
datalog::test_smt_relation_unit();
}

110
src/test/dl_table.cpp Normal file
View file

@ -0,0 +1,110 @@
#ifdef _WINDOWS
#include "dl_context.h"
#include "dl_table.h"
#include "dl_skip_table.h"
typedef datalog::table_base* (*mk_table_fn)(datalog::relation_manager& m, datalog::table_signature& sig);
static datalog::table_base* mk_bv_table(datalog::relation_manager& m, datalog::table_signature& sig) {
datalog::table_plugin * p = m.get_table_plugin(symbol("bitvector"));
SASSERT(p);
return p->mk_empty(sig);
}
static datalog::table_base* mk_skip_table(datalog::relation_manager& m, datalog::table_signature& sig) {
datalog::table_plugin * p = m.get_table_plugin(symbol("skip"));
SASSERT(p);
return p->mk_empty(sig);
}
static void test_table(mk_table_fn mk_table) {
datalog::table_signature sig;
sig.push_back(2);
sig.push_back(4);
sig.push_back(8);
sig.push_back(4);
front_end_params params;
ast_manager ast_m;
datalog::context ctx(ast_m, params);
datalog::relation_manager & m = ctx.get_rmanager();
ctx.get_rmanager().register_plugin(alloc(datalog::bitvector_table_plugin, ctx.get_rmanager()));
datalog::table_base* _tbl = mk_table(m, sig);
datalog::table_base& table = *_tbl;
datalog::table_fact row, row1, row2, row3;
row.push_back(1);
row.push_back(3);
row.push_back(7);
row.push_back(2);
row1 = row;
row[3] = 3;
row2 = row;
row[0] = 0;
row[3] = 1;
row3 = row;
table.add_fact(row1);
table.add_fact(row2);
table.display(std::cout);
datalog::table_base::iterator it = table.begin();
datalog::table_base::iterator end = table.end();
for (; it != end; ++it) {
it->get_fact(row);
for (unsigned j = 0; j < row.size(); ++j) {
std::cout << row[j] << " ";
}
std::cout << "\n";
}
SASSERT(table.contains_fact(row1));
SASSERT(table.contains_fact(row2));
SASSERT(!table.contains_fact(row3));
#if 0
table.remove_facts(1, &row1);
SASSERT(!table.contains_fact(row1));
#endif
table.add_fact(row1);
datalog::table_base* _tbl2 = mk_table(m, sig);
datalog::table_base& table2 = *_tbl2;
table2.add_fact(row2);
table2.add_fact(row3);
unsigned cols1[1] = { 1 };
unsigned cols2[1] = { 3 };
datalog::table_join_fn * j1 = m.mk_join_fn(table2, table, 1, cols1, cols2);
datalog::table_base* _tbl3 = (*j1)(table2,table);
_tbl3->display(std::cout);
datalog::table_join_fn * j2 = m.mk_join_fn(table2, table, 1, cols1, cols1);
datalog::table_base* _tbl4 = (*j2)(table2,table);
_tbl4->display(std::cout);
dealloc(j1);
dealloc(j2);
_tbl->deallocate();
(_tbl2->deallocate());
(_tbl3->deallocate());
(_tbl4->deallocate());
}
void test_dl_bitvector_table() {
test_table(mk_bv_table);
}
void test_dl_skip_table() {
test_table(mk_skip_table);
}
void tst_dl_table() {
test_dl_bitvector_table();
test_dl_skip_table();
}
#else
void tst_dl_table() {
}
#endif

51
src/test/dl_util.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "dl_util.h"
using namespace datalog;
void dl_util_two_array_sort() {
const unsigned num = 97;
unsigned a1[num];
unsigned a2[num];
for(unsigned i=0; i<num; i++) {
a1[i]=(i*30)%num;
a2[i]=(i*30)%num+3;
}
datalog::sort_two_arrays(num, a1, a2);
for(unsigned i=0; i<num; i++) {
SASSERT(a2[i]==i+3);
}
}
void dl_util_cycle_from_permutation() {
unsigned permutation_arr[] = { 0, 1, 4, 3, 2, 5, 6, 7 };
unsigned_vector perm(sizeof(permutation_arr)/sizeof(unsigned), permutation_arr);
unsigned_vector cycle;
datalog::cycle_from_permutation(perm, cycle);
SASSERT(cycle.size()==2);
SASSERT(cycle[0]==2 || cycle[0]==4);
SASSERT(cycle[1]==2 || cycle[1]==4);
SASSERT((cycle[0]==2) == (cycle[1]==4));
unsigned permutation_arr2[] = { 1, 2, 3, 4, 5, 6, 7, 0 };
unsigned len2 = sizeof(permutation_arr2)/sizeof(unsigned);
unsigned_vector perm2(len2, permutation_arr2);
cycle.reset();
datalog::cycle_from_permutation(perm2, cycle);
for(unsigned i=0; i<len2; i++) {
SASSERT( (cycle[i]+1)%len2==cycle[(i+1)%len2] );
}
}
void tst_dl_util() {
dl_util_two_array_sort();
dl_util_cycle_from_permutation();
}

35
src/test/escaped.cpp Normal file
View file

@ -0,0 +1,35 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
escaped_str.cpp
Abstract:
Escaped strings
Author:
Leonardo de Moura (leonardo) 2011-03-01.
Revision History:
--*/
#include"util.h"
void tst_escaped() {
std::cout << "[" << escaped("\"hello\"\"world\"\n\n") << "]\n";
std::cout << "[" << escaped("\"hello\"\nworld\"\n\n\n", true) << "]\n";
std::cout << "[" << escaped("\"hello\"\nworld\"\n", true) << "]\n";
std::cout << "[" << escaped("\"hello\"\nworld\"", true) << "]\n";
std::cout << "[" << escaped("\"hello\"\n\"world\"\n\n") << "]\n";
std::cout << "[" << escaped("\n\n\n", true) << "]\n";
std::cout << "[" << escaped("\n\n\n") << "]\n";
std::cout << "[" << escaped("\n", true) << "]\n";
std::cout << "[" << escaped("\n") << "]\n";
std::cout << "[" << escaped("", true) << "]\n";
std::cout << "[" << escaped("") << "]\n";
std::cout << "[" << escaped(0, true) << "]\n";
std::cout << "[" << escaped(0) << "]\n";
}

67
src/test/ex.cpp Normal file
View file

@ -0,0 +1,67 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
ex.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2011-04-28
Revision History:
--*/
#include<iostream>
#include"z3_exception.h"
class ex {
public:
virtual ~ex() {}
virtual char const * msg() const = 0;
};
class ex1 : public ex {
char const * m_msg;
public:
ex1(char const * m):m_msg(m) {}
virtual char const * msg() const { return m_msg; }
};
class ex2 : public ex {
std::string m_msg;
public:
ex2(char const * m):m_msg(m) {}
virtual char const * msg() const { return m_msg.c_str(); }
};
static void th() {
throw ex2("testing exception");
}
static void tst1() {
try {
th();
}
catch (ex & e) {
std::cerr << e.msg() << "\n";
}
}
static void tst2() {
try {
throw default_exception("Format %d %s", 12, "twelve");
}
catch (z3_exception& ex) {
std::cerr << ex.msg() << "\n";
}
}
void tst_ex() {
tst1();
tst2();
}

View file

@ -0,0 +1,43 @@
#include "expr_context_simplifier.h"
#include "smtparser.h"
#include "ast_pp.h"
static void simplify_formula(ast_manager& m, expr* e) {
expr_ref result(m);
expr_context_simplifier simp(m);
simp(e, result);
TRACE("expr_context_simplifier",
tout
<< mk_pp(e, m) << " |-> "
<< mk_pp(result.get(), m) << "\n";);
}
void tst_expr_context_simplifier() {
ast_manager m;
smtlib::parser* parser = smtlib::parser::create(m);
m.register_decl_plugins();
parser->initialize_smtlib();
parser->parse_string(
"(benchmark samples :logic QF_LIA \n"
" :extrafuns ((x Int) (y Int) (z Int) (u Int)) \n"
" :formula (and (<= 1 x) (or (<= 1 x) (<= x y))) \n"
" :formula (and (<= 2 (ite (<= z 1) (ite (<= z 1) x y) (* 2 x))) (<= x y)) \n"
")"
);
smtlib::benchmark* b = parser->get_benchmark();
smtlib::symtable const * table = b->get_symtable();
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
simplify_formula(m, b->begin_formulas()[j]);
}
dealloc(parser);
}

127
src/test/expr_delta.cpp Normal file
View file

@ -0,0 +1,127 @@
#include "expr_delta.h"
#include "smtparser.h"
#include "ast_pp.h"
#include "ast_smt_pp.h"
static void iterate_delta(ast_manager& m, expr_delta& delta) {
unsigned n = 0;
expr_ref_vector result(m);
std::cout << "Delta\n";
while (true) {
result.reset();
if (!delta.delta_dfs(n, result)) {
return;
}
std::cout << n << ": ";
for (unsigned i = 0; i < result.size(); ++i) {
std::cout << mk_pp(result[i].get(), m) << " ";
}
std::cout << "\n";
n++;
}
}
void tst_expr_delta1() {
ast_manager m;
smtlib::parser* parser = smtlib::parser::create(m);
parser->initialize_smtlib();
parser->parse_string(
"(benchmark samples :logic QF_LIA \n"
" :extrafuns ((a Int) (b Int) (c Int)) \n"
" :assumption (> a 0) \n"
" :assumption (> b 0) \n"
" :formula (forall (x Int) (y Int) (z Int) (and (<= 1 x) (<= x y))) \n"
" :formula (forall (x Int) (y Int) (z Int) (and (<= 2 (ite (<= z 1) x (* 2 x))) (<= x y)))\n"
" :formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (<= z 1)) x (* 2 x))) (<= x y)))\n"
" :formula (forall (x Int) (y Int) (and (<= 2 (ite (forall (z Int) (or (> x y) (<= z 1))) x (* 2 x))) (<= x y)))\n"
")"
);
smtlib::benchmark* b = parser->get_benchmark();
for (unsigned j = 0; j < b->get_num_formulas(); ++j) {
expr_delta delta(m);
for (unsigned i = 0; i < b->get_num_assumptions(); ++i) {
delta.assert_cnstr(b->get_assumptions()[i]);
}
delta.assert_cnstr(b->begin_formulas()[j]);
iterate_delta(m, delta);
}
dealloc(parser);
}
static void get_expr_delta(unsigned position, char const* in, char const* out) {
ast_manager m;
smtlib::parser* parser = smtlib::parser::create(m);
parser->initialize_smtlib();
if (!parser->parse_file(in)) {
std::cout << "error parsing file\n";
dealloc(parser);
return;
}
smtlib::benchmark* b = parser->get_benchmark();
SASSERT(b->get_num_formulas() == 1);
expr_delta delta(m);
for (unsigned i = 0; i < b->get_num_assumptions(); ++i) {
delta.assert_cnstr(b->get_assumptions()[i]);
}
delta.assert_cnstr(b->begin_formulas()[0]);
expr_ref_vector result(m);
if (!delta.delta_dfs(position, result)) {
std::cout << "done\n";
}
else {
ast_smt_pp pp(m);
std::ofstream outf(out);
if (outf.bad() || outf.fail()) {
std::cout << "Could not open output\n";
}
else {
switch(b->get_status()) {
case smtlib::benchmark::UNKNOWN:
pp.set_status("unknown");
break;
case smtlib::benchmark::SAT:
pp.set_status("sat");
break;
case smtlib::benchmark::UNSAT:
pp.set_status("unsat");
break;
}
pp.set_logic(b->get_logic().str().c_str());
for (unsigned i = 0; i + 1 < result.size(); ++i) {
pp.add_assumption(result[i].get());
}
pp.display(outf, result[result.size()-1].get());
std::cout << "ok\n";
}
}
dealloc(parser);
}
void tst_expr_delta(char** argv, int argc, int& i) {
if (i + 3 >= argc) {
std::cout << "Usage: <position:number> <input:file-name> <output:file-name>\n";
return;
}
++i;
unsigned position = atol(argv[i]);
++i;
char const* in_file = argv[i];
++i;
char const* out_file = argv[i];
get_expr_delta(position, in_file, out_file);
}

View file

@ -0,0 +1,50 @@
#include "expr_pattern_match.h"
#include "smtparser.h"
#include "ast_pp.h"
#include "arith_decl_plugin.h"
#include "bv_decl_plugin.h"
#include "array_decl_plugin.h"
void tst_expr_pattern_match() {
ast_manager manager;
manager.register_decl_plugins();
expr_pattern_match apm(manager);
apm.display(std::cout);
const char* test_string = "(benchmark patterns :status unknown :logic ALL \n"
":extrasorts (S) \n"
":extrafuns ((R S S bool)) \n"
":formula (forall (x S) (y S) (z S) \n"
" (or (not (R x y)) (not (R y z)) (R x z)) \n"
" ; :pats { (R x y) (R y z) } \n"
" :weight { 2 } \n"
" )\n"
")";
smtlib::parser* parser = smtlib::parser::create(manager);
parser->initialize_smtlib();
std::cout << "parsing test string\n";
if (!parser->parse_string(test_string)) {
UNREACHABLE();
}
std::cout << "test string parsed\n";
smtlib::benchmark* bench = parser->get_benchmark();
for (unsigned i = 0; i < bench->get_num_formulas(); ++i) {
expr* fml = bench->begin_formulas()[i];
SASSERT(fml->get_kind() == AST_QUANTIFIER);
quantifier* qf = to_quantifier(fml);
app_ref_vector patterns(manager);
unsigned weight = 0;
if (apm.match_quantifier(qf, patterns, weight)) {
std::cout << "Found pattern match\n";
for (unsigned i = 0; i < patterns.size(); ++i) {
ast_pp(std::cout, patterns[i].get(), manager) << "\n";
}
std::cout << "weight: " << weight << "\n";
}
}
dealloc(parser);
}

104
src/test/expr_rand.cpp Normal file
View file

@ -0,0 +1,104 @@
#include "expr_rand.h"
#include "ast_pp.h"
#include "bv_decl_plugin.h"
#include "array_decl_plugin.h"
#include "arith_decl_plugin.h"
#include "ast_smt_pp.h"
#include <iostream>
#include <sstream>
static unsigned rand_seed = 1;
void tst_expr_arith(unsigned num_files) {
ast_manager m;
m.register_decl_plugins();
expr_rand er(m);
er.seed(rand_seed);
er.initialize_arith(20);
family_id fid = m.get_family_id("arith");
sort* int_ty = m.mk_sort(fid, INT_SORT, 0, 0);
sort* real_ty = m.mk_sort(fid, REAL_SORT, 0, 0);
er.initialize_array(3, int_ty, int_ty);
er.initialize_array(3, int_ty, real_ty);
er.initialize_basic(20);
for (unsigned i = 0; i < num_files; ++i) {
expr_ref e(m);
er.get_next(m.mk_bool_sort(), e);
ast_smt_pp pp(m);
pp.set_logic("QF_AUFLIA");
std::ostringstream buffer;
buffer << "random_arith_" << i << ".smt";
std::cout << buffer.str() << "\n";
std::ofstream file(buffer.str().c_str());
pp.display(file, e.get());
file.close();
}
}
void tst_expr_rand(unsigned num_files) {
ast_manager m;
m.register_plugin(symbol("bv"), alloc(bv_decl_plugin));
m.register_plugin(symbol("array"), alloc(array_decl_plugin));
expr_rand er(m);
er.initialize_bv(20);
er.seed(rand_seed);
parameter p1(1);
parameter p2(2);
parameter p8(8);
parameter p32(32);
family_id bvfid = m.get_family_id("bv");
sort* bv1 = m.mk_sort(bvfid, BV_SORT, 1, &p1);
sort* bv2 = m.mk_sort(bvfid, BV_SORT, 1, &p2);
sort* bv8 = m.mk_sort(bvfid, BV_SORT, 1, &p8);
sort* bv32 = m.mk_sort(bvfid, BV_SORT, 1, &p32);
er.initialize_array(3, bv8, bv32);
er.initialize_array(3, bv1, bv1);
er.initialize_array(3, bv1, bv2);
er.initialize_array(3, bv2, bv1);
er.initialize_array(3, bv2, bv2);
er.initialize_array(3, bv8, bv8);
er.initialize_array(3, bv32, bv32);
er.initialize_basic(20);
for (unsigned i = 0; i < num_files; ++i) {
expr_ref e(m);
er.get_next(m.mk_bool_sort(), e);
ast_smt_pp pp(m);
pp.set_logic("QF_AUFBV");
std::ostringstream buffer;
buffer << "random_bv_" << i << ".smt";
std::cout << buffer.str() << "\n";
std::ofstream file(buffer.str().c_str());
pp.display(file, e.get());
file.close();
}
}
void tst_expr_rand(char** argv, int argc, int& i) {
if (i + 1 < argc) {
unsigned num_files = atol(argv[i+1]);
i += 1;
if (i + 1 < argc && 0 == strncmp(argv[i+1],"/rs:",3)) {
rand_seed = atol(argv[i+1]+4);
std::cout << "random seed:" << rand_seed << "\n";
i += 1;
}
if (i + 1 < argc && 0 == strcmp(argv[i+1],"/arith")) {
tst_expr_arith(num_files);
return;
}
tst_expr_rand(num_files);
}
}

397
src/test/ext_numeral.cpp Normal file
View file

@ -0,0 +1,397 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
ext_numeral.cpp
Abstract:
Unit tests for ext_numeral template.
Author:
Leonardo (leonardo) 2012-07-18
Notes:
--*/
#include<sstream>
#include"mpq.h"
#include"ext_numeral.h"
#define MK_TST_UNARY(NAME) \
static void tst_ ## NAME(int a, ext_numeral_kind ak, int expected_c, ext_numeral_kind expected_ck) { \
unsynch_mpq_manager m; \
scoped_mpq _a(m); \
m.set(_a, a); \
NAME(m, _a, ak); \
SASSERT(ak == expected_ck); \
if (expected_ck == EN_NUMERAL) { \
scoped_mpq _expected_c(m); \
m.set(_expected_c, expected_c); \
SASSERT(m.eq(_a, _expected_c)); \
} \
}
MK_TST_UNARY(neg);
MK_TST_UNARY(inv);
#define MK_TST_BIN_CORE(FUN_NAME, OP_NAME) \
static void FUN_NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, int expected_c, ext_numeral_kind expected_ck) { \
unsynch_mpq_manager m; \
scoped_mpq _a(m), _b(m), _c(m); \
m.set(_a, a); \
m.set(_b, b); \
ext_numeral_kind ck; \
OP_NAME(m, _a, ak, _b, bk, _c, ck); \
SASSERT(ck == expected_ck); \
if (expected_ck == EN_NUMERAL) { \
scoped_mpq _expected_c(m); \
m.set(_expected_c, expected_c); \
SASSERT(m.eq(_c, _expected_c)); \
} \
}
#define MK_TST_BIN(NAME) MK_TST_BIN_CORE(tst_ ## NAME, NAME)
#define MK_TST_COMM_BIN(NAME) \
MK_TST_BIN_CORE(tst_ ## NAME ## _core, NAME) \
static void tst_ ## NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, int expected_c, ext_numeral_kind expected_ck) { \
tst_ ## NAME ## _core(a, ak, b, bk, expected_c, expected_ck); \
tst_ ## NAME ## _core(b, bk, a, ak, expected_c, expected_ck); \
}
MK_TST_COMM_BIN(add);
MK_TST_BIN(sub);
MK_TST_COMM_BIN(mul);
static void tst1() {
tst_neg(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_neg(30, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY);
tst_neg(0, EN_NUMERAL, 0, EN_NUMERAL);
tst_neg(10, EN_NUMERAL, -10, EN_NUMERAL);
tst_neg(-7, EN_NUMERAL, 7, EN_NUMERAL);
tst_neg(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_neg(30, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_neg(-7, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_inv(0, EN_MINUS_INFINITY, 0, EN_NUMERAL);
tst_inv(0, EN_PLUS_INFINITY, 0, EN_NUMERAL);
tst_inv(1, EN_NUMERAL, 1, EN_NUMERAL);
tst_inv(-1, EN_NUMERAL, -1, EN_NUMERAL);
tst_add(0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_add(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_add(0, EN_MINUS_INFINITY, -1, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_add(0, EN_MINUS_INFINITY, 1, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_add(1, EN_MINUS_INFINITY, -1, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_add(1, EN_NUMERAL, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_add(-1, EN_NUMERAL, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_add(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_add(0, EN_NUMERAL, 2, EN_NUMERAL, 2, EN_NUMERAL);
tst_add(-3, EN_NUMERAL, 4, EN_NUMERAL, 1, EN_NUMERAL);
tst_add(-2, EN_NUMERAL, 0, EN_NUMERAL, -2, EN_NUMERAL);
tst_add(3, EN_NUMERAL, 4, EN_NUMERAL, 7, EN_NUMERAL);
tst_add(0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_add(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_add(0, EN_PLUS_INFINITY, 1, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_add(0, EN_PLUS_INFINITY, -1, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_add(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_add(-1, EN_NUMERAL, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_add(1, EN_NUMERAL, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_mul(0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_mul(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_mul(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_mul(0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_mul(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_NUMERAL);
tst_mul(0, EN_MINUS_INFINITY, 1, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_mul(0, EN_MINUS_INFINITY, 5, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_mul(0, EN_MINUS_INFINITY, -1, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_mul(0, EN_MINUS_INFINITY, -5, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_mul(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_NUMERAL);
tst_mul(0, EN_PLUS_INFINITY, 1, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_mul(0, EN_PLUS_INFINITY, 5, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_mul(0, EN_PLUS_INFINITY, -1, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_mul(0, EN_PLUS_INFINITY, -5, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_mul(0, EN_NUMERAL, 3, EN_NUMERAL, 0, EN_NUMERAL);
tst_mul(2, EN_NUMERAL, 3, EN_NUMERAL, 6, EN_NUMERAL);
tst_mul(-2, EN_NUMERAL, 3, EN_NUMERAL, -6, EN_NUMERAL);
tst_sub(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_PLUS_INFINITY, -10, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, -10, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, 3, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, 0, EN_MINUS_INFINITY);
tst_sub(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_PLUS_INFINITY, 3, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, 0, EN_PLUS_INFINITY);
tst_sub(0, EN_NUMERAL, 2, EN_NUMERAL, -2, EN_NUMERAL);
tst_sub(3, EN_NUMERAL, 2, EN_NUMERAL, 1, EN_NUMERAL);
tst_sub(3, EN_NUMERAL, -3, EN_NUMERAL, 6, EN_NUMERAL);
tst_sub(3, EN_NUMERAL, 3, EN_NUMERAL, 0, EN_NUMERAL);
tst_sub(3, EN_NUMERAL, 0, EN_NUMERAL, 3, EN_NUMERAL);
tst_sub(-3, EN_NUMERAL, -5, EN_NUMERAL, 2, EN_NUMERAL);
}
#define MK_TST_REL_CORE(FUN_NAME, OP_NAME) \
static void FUN_NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, bool expected) { \
unsynch_mpq_manager m; \
scoped_mpq _a(m), _b(m); \
m.set(_a, a); \
m.set(_b, b); \
bool r = OP_NAME(m, _a, ak, _b, bk); \
SASSERT(r == expected); \
}
#define MK_TST_REL(NAME) MK_TST_REL_CORE(tst_ ## NAME, NAME)
#define MK_TST_SYMM_REL(NAME) \
MK_TST_REL_CORE(tst_ ## NAME ## _core, NAME) \
static void tst_ ## NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, bool expected) { \
tst_ ## NAME ## _core(a, ak, b, bk, expected); \
tst_ ## NAME ## _core(b, bk, a, ak, expected); \
}
MK_TST_SYMM_REL(eq);
MK_TST_SYMM_REL(neq);
MK_TST_REL(lt);
MK_TST_REL(gt);
MK_TST_REL(le);
MK_TST_REL(ge);
static void tst2() {
tst_eq(0, EN_NUMERAL, 0, EN_NUMERAL, true);
tst_eq(0, EN_NUMERAL, 2, EN_NUMERAL, false);
tst_eq(3, EN_NUMERAL, 0, EN_NUMERAL, false);
tst_eq(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, false);
tst_eq(0, EN_PLUS_INFINITY, 3, EN_NUMERAL, false);
tst_eq(0, EN_PLUS_INFINITY, -2, EN_NUMERAL, false);
tst_eq(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, false);
tst_neq(0, EN_NUMERAL, 0, EN_NUMERAL, false);
tst_neq(0, EN_NUMERAL, 2, EN_NUMERAL, true);
tst_neq(3, EN_NUMERAL, 0, EN_NUMERAL, true);
tst_neq(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, true);
tst_neq(0, EN_PLUS_INFINITY, 3, EN_NUMERAL, true);
tst_neq(0, EN_PLUS_INFINITY, -2, EN_NUMERAL, true);
tst_neq(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, true);
tst_lt(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, true);
tst_lt(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, true);
tst_lt(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, true);
tst_lt(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, true);
tst_lt(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, true);
tst_lt(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, true);
tst_lt(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, true);
tst_lt(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, true);
tst_lt(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, true);
tst_lt(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, false);
tst_lt(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, false);
tst_lt(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, false);
tst_lt(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, false);
tst_lt(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, false);
tst_lt(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, false);
tst_lt(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, false);
tst_lt(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, false);
tst_lt(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, false);
tst_lt(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, true);
tst_lt(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, true);
tst_lt(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, true);
tst_lt(0, EN_NUMERAL, 10, EN_NUMERAL, true);
tst_lt(0, EN_NUMERAL, 0, EN_NUMERAL, false);
tst_lt(10, EN_NUMERAL, 10, EN_NUMERAL, false);
tst_lt(0, EN_NUMERAL, -3, EN_NUMERAL, false);
tst_lt(30, EN_NUMERAL, 10, EN_NUMERAL, false);
tst_lt(30, EN_NUMERAL, 40, EN_NUMERAL, true);
tst_lt(20, EN_NUMERAL, 0, EN_NUMERAL, false);
tst_lt(-20, EN_NUMERAL, -3, EN_NUMERAL, true);
tst_lt(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, false);
tst_lt(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, false);
tst_lt(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, false);
tst_le(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, true);
tst_le(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, true);
tst_le(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, true);
tst_le(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, true);
tst_le(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, true);
tst_le(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, true);
tst_le(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, true);
tst_le(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, true);
tst_le(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, true);
tst_le(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, false);
tst_le(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, false);
tst_le(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, false);
tst_le(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, false);
tst_le(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, false);
tst_le(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, false);
tst_le(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, false);
tst_le(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, false);
tst_le(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, false);
tst_le(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, true);
tst_le(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, true);
tst_le(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, true);
tst_le(0, EN_NUMERAL, 10, EN_NUMERAL, true);
tst_le(0, EN_NUMERAL, 0, EN_NUMERAL, true);
tst_le(10, EN_NUMERAL, 10, EN_NUMERAL, true);
tst_le(0, EN_NUMERAL, -3, EN_NUMERAL, false);
tst_le(30, EN_NUMERAL, 10, EN_NUMERAL, false);
tst_le(30, EN_NUMERAL, 40, EN_NUMERAL, true);
tst_le(20, EN_NUMERAL, 0, EN_NUMERAL, false);
tst_le(-20, EN_NUMERAL, -3, EN_NUMERAL, true);
tst_le(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, false);
tst_le(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, false);
tst_le(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, false);
tst_ge(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, false);
tst_ge(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, false);
tst_ge(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, false);
tst_ge(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, false);
tst_ge(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, false);
tst_ge(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, false);
tst_ge(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, false);
tst_ge(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, false);
tst_ge(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, false);
tst_ge(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, true);
tst_ge(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, true);
tst_ge(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, true);
tst_ge(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, true);
tst_ge(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, true);
tst_ge(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, true);
tst_ge(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, true);
tst_ge(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, true);
tst_ge(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, true);
tst_ge(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, false);
tst_ge(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, false);
tst_ge(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, false);
tst_ge(0, EN_NUMERAL, 10, EN_NUMERAL, false);
tst_ge(0, EN_NUMERAL, 0, EN_NUMERAL, true);
tst_ge(10, EN_NUMERAL, 10, EN_NUMERAL, true);
tst_ge(0, EN_NUMERAL, -3, EN_NUMERAL, true);
tst_ge(30, EN_NUMERAL, 10, EN_NUMERAL, true);
tst_ge(30, EN_NUMERAL, 40, EN_NUMERAL, false);
tst_ge(20, EN_NUMERAL, 0, EN_NUMERAL, true);
tst_ge(-20, EN_NUMERAL, -3, EN_NUMERAL, false);
tst_ge(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, true);
tst_ge(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, true);
tst_ge(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, true);
tst_gt(0, EN_MINUS_INFINITY, 10, EN_NUMERAL, false);
tst_gt(0, EN_MINUS_INFINITY, 0, EN_NUMERAL, false);
tst_gt(0, EN_MINUS_INFINITY, -3, EN_NUMERAL, false);
tst_gt(30, EN_MINUS_INFINITY, 10, EN_NUMERAL, false);
tst_gt(20, EN_MINUS_INFINITY, 0, EN_NUMERAL, false);
tst_gt(-20, EN_MINUS_INFINITY, -3, EN_NUMERAL, false);
tst_gt(0, EN_MINUS_INFINITY, 10, EN_PLUS_INFINITY, false);
tst_gt(0, EN_MINUS_INFINITY, 0, EN_PLUS_INFINITY, false);
tst_gt(10, EN_MINUS_INFINITY, -30, EN_PLUS_INFINITY, false);
tst_gt(0, EN_PLUS_INFINITY, 10, EN_NUMERAL, true);
tst_gt(0, EN_PLUS_INFINITY, 0, EN_NUMERAL, true);
tst_gt(0, EN_PLUS_INFINITY, -3, EN_NUMERAL, true);
tst_gt(30, EN_PLUS_INFINITY, 10, EN_NUMERAL, true);
tst_gt(20, EN_PLUS_INFINITY, 0, EN_NUMERAL, true);
tst_gt(-20, EN_PLUS_INFINITY, -3, EN_NUMERAL, true);
tst_gt(0, EN_PLUS_INFINITY, 10, EN_MINUS_INFINITY, true);
tst_gt(0, EN_PLUS_INFINITY, 0, EN_MINUS_INFINITY, true);
tst_gt(10, EN_PLUS_INFINITY, -30, EN_MINUS_INFINITY, true);
tst_gt(0, EN_NUMERAL, 0, EN_PLUS_INFINITY, false);
tst_gt(20, EN_NUMERAL, 10, EN_PLUS_INFINITY, false);
tst_gt(-20, EN_NUMERAL, -100, EN_PLUS_INFINITY, false);
tst_gt(0, EN_NUMERAL, 10, EN_NUMERAL, false);
tst_gt(0, EN_NUMERAL, 0, EN_NUMERAL, false);
tst_gt(10, EN_NUMERAL, 10, EN_NUMERAL, false);
tst_gt(0, EN_NUMERAL, -3, EN_NUMERAL, true);
tst_gt(30, EN_NUMERAL, 10, EN_NUMERAL, true);
tst_gt(30, EN_NUMERAL, 40, EN_NUMERAL, false);
tst_gt(20, EN_NUMERAL, 0, EN_NUMERAL, true);
tst_gt(-20, EN_NUMERAL, -3, EN_NUMERAL, false);
tst_gt(0, EN_NUMERAL, 10, EN_MINUS_INFINITY, true);
tst_gt(0, EN_NUMERAL, 0, EN_MINUS_INFINITY, true);
tst_gt(10, EN_NUMERAL, -30, EN_MINUS_INFINITY, true);
}
static void tst3() {
unsynch_mpq_manager m;
scoped_mpq a(m);
SASSERT(is_zero(m, a, EN_NUMERAL));
SASSERT(!is_zero(m, a, EN_PLUS_INFINITY));
SASSERT(!is_zero(m, a, EN_MINUS_INFINITY));
SASSERT(!is_pos(m, a, EN_NUMERAL));
SASSERT(is_pos(m, a, EN_PLUS_INFINITY));
SASSERT(!is_pos(m, a, EN_MINUS_INFINITY));
SASSERT(!is_infinite(EN_NUMERAL));
SASSERT(is_infinite(EN_PLUS_INFINITY));
SASSERT(is_infinite(EN_MINUS_INFINITY));
SASSERT(!is_neg(m, a, EN_NUMERAL));
SASSERT(!is_neg(m, a, EN_PLUS_INFINITY));
SASSERT(is_neg(m, a, EN_MINUS_INFINITY));
m.set(a, 10);
SASSERT(!is_zero(m, a, EN_NUMERAL));
SASSERT(is_pos(m, a, EN_NUMERAL));
SASSERT(!is_neg(m, a, EN_NUMERAL));
SASSERT(!is_infinite(EN_NUMERAL));
m.set(a, -5);
SASSERT(!is_zero(m, a, EN_NUMERAL));
SASSERT(!is_pos(m, a, EN_NUMERAL));
SASSERT(is_neg(m, a, EN_NUMERAL));
SASSERT(!is_infinite(EN_NUMERAL));
ext_numeral_kind ak;
ak = EN_MINUS_INFINITY;
reset(m, a, ak);
SASSERT(is_zero(m, a, EN_NUMERAL));
{
std::ostringstream buffer;
display(buffer, m, a, ak);
SASSERT(buffer.str() == "0");
}
{
std::ostringstream buffer;
m.set(a, -10);
display(buffer, m, a, ak);
SASSERT(buffer.str() == "-10");
}
{
std::ostringstream buffer;
display(buffer, m, a, EN_PLUS_INFINITY);
SASSERT(buffer.str() == "oo");
}
{
std::ostringstream buffer;
display(buffer, m, a, EN_MINUS_INFINITY);
SASSERT(buffer.str() == "-oo");
}
}
void tst_ext_numeral() {
tst1();
tst2();
tst3();
}

68
src/test/f2n.cpp Normal file
View file

@ -0,0 +1,68 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
f2n.cpp
Abstract:
Author:
Leonardo de Moura (leonardo) 2012-08-17.
Revision History:
--*/
#include"f2n.h"
#include"hwf.h"
#include"mpf.h"
static void tst1() {
hwf_manager hm;
f2n<hwf_manager> m(hm);
hwf a, b;
m.set(a, 11, 3);
m.floor(a, b);
std::cout << "floor(11/3): " << m.to_double(b) << "\n";
m.ceil(a, b);
std::cout << "ceil(11/3): " << m.to_double(b) << "\n";
m.set(a, -11, 3);
m.floor(a, b);
std::cout << "floor(-11/3): " << m.to_double(b) << "\n";
m.ceil(a, b);
std::cout << "ceil(-11/3): " << m.to_double(b) << "\n";
m.set(a, 11, 1);
m.floor(a, b);
std::cout << "floor(11): " << m.to_double(b) << "\n";
m.ceil(a, b);
std::cout << "ceil(11): " << m.to_double(b) << "\n";
}
static void tst2() {
std::cout << "using mpf...\n";
mpf_manager fm;
f2n<mpf_manager> m(fm);
scoped_mpf a(fm), b(fm);
m.set(a, 11, 3);
m.floor(a, b);
std::cout << "floor(11/3): " << m.to_double(b) << "\n";
m.ceil(a, b);
std::cout << "ceil(11/3): " << m.to_double(b) << "\n";
m.set(a, -11, 3);
m.floor(a, b);
std::cout << "floor(-11/3): " << m.to_double(b) << "\n";
m.ceil(a, b);
std::cout << "ceil(-11/3): " << m.to_double(b) << "\n";
m.set(a, 11, 1);
m.floor(a, b);
std::cout << "floor(11): " << m.to_double(b) << "\n";
m.ceil(a, b);
std::cout << "ceil(11): " << m.to_double(b) << "\n";
}
void tst_f2n() {
tst1();
tst2();
}

View file

@ -0,0 +1,18 @@
#include "factor_rewriter.h"
#include "bv_decl_plugin.h"
#include "ast_pp.h"
void tst_factor_rewriter() {
ast_manager m;
m.register_decl_plugins();
factor_rewriter_star fw(m);
arith_util a(m);
expr_ref fml1(m), fml2(m);
expr_ref z(m.mk_const(symbol("z"), a.mk_real()), m);
expr_ref two(a.mk_numeral(rational(2),false),m);
expr_ref zero(a.mk_numeral(rational(0),false),m);
fml1 = a.mk_le(zero, a.mk_mul(two, z, z));
fw(fml1, fml2);
std::cout << mk_pp(fml1, m) << " -> " << mk_pp(fml2, m) << "\n";
}

View file

@ -0,0 +1,79 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
foreach_file.cpp
Abstract:
Traverse files in a directory that match a given suffix.
Apply a method to each of the files.
Author:
Nikolaj Bjorner (nbjorner) 2006-11-3.
Revision History:
--*/
#ifdef _WINDOWS
#include <string>
#include <windows.h>
#include <strsafe.h>
#include "for_each_file.h"
bool for_each_file(for_each_file_proc& proc, const char* base, const char* suffix)
{
std::string pattern(base);
pattern += "\\";
pattern += suffix;
char buffer[MAX_PATH];
WIN32_FIND_DATAA data;
HANDLE h = FindFirstFileA(pattern.c_str(),&data);
while (h != INVALID_HANDLE_VALUE) {
StringCchPrintfA(buffer, ARRAYSIZE(buffer), "%s\\%s", base, data.cFileName);
if (!proc(buffer)) {
return false;
}
if (!FindNextFileA(h,&data)) {
break;
}
}
//
// Now recurse through sub-directories.
//
pattern = base;
pattern += "\\*";
h = FindFirstFileA(pattern.c_str(),&data);
while (h != INVALID_HANDLE_VALUE) {
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
data.cFileName[0] != '.'
){
std::string subdir(base);
subdir += "\\";
subdir += data.cFileName;
if (!for_each_file(proc, subdir.c_str(), suffix)) {
return false;
}
}
if (!FindNextFileA(h,&data)) {
break;
}
}
return true;
};
#endif

33
src/test/for_each_file.h Normal file
View file

@ -0,0 +1,33 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
foreach_file.h
Abstract:
Traverse files in a directory that match a given suffix.
Apply a method to each of the files.
Author:
Nikolaj Bjorner (nbjorner) 2006-11-3.
Revision History:
--*/
#pragma once
#ifndef _FOR_EACH_FILE_H_
#define _FOR_EACH_FILE_H_
struct for_each_file_proc {
virtual bool operator()(const char* file_path) = 0;
};
bool for_each_file(for_each_file_proc& proc, const char* base, const char* suffix);
#endif /* _FOR_EACH_FILE_H_ */

158
src/test/fvi.cpp Normal file
View file

@ -0,0 +1,158 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
fvi.cpp
Abstract:
Feature Vector Indexing.
Author:
Leonardo de Moura (leonardo) 2008-02-01.
Revision History:
--*/
#ifdef _WINDOWS
#include"fvi_def.h"
#include"trace.h"
typedef vector<int> data;
static int to_feature(int val) {
return val % 4;
}
static std::ostream & operator<<(std::ostream & out, data const & d) {
out << "[";
data::const_iterator it = d.begin();
data::const_iterator end = d.end();
for (bool first = true; it != end; ++it, first = false)
out << (first ? "" : " ") << *it << ":" << to_feature(*it);
out << "]";
return out;
}
#define NUM_FEATURES 5
struct to_feature_vector {
unsigned m_num_features;
to_feature_vector(unsigned n):m_num_features(n) {}
void operator()(data * d, unsigned * f) {
for (unsigned i = 0; i < m_num_features; i++) {
f[i] = to_feature((*d)[i]);
}
}
};
struct data_hash {
unsigned operator()(data * d) const {
unsigned r = 0;
data::iterator it = d->begin();
data::iterator end = d->end();
for (; it != end; ++it)
r += *it;
return r;
}
};
ptr_vector<data> g_datas;
static void collect() {
std::for_each(g_datas.begin(), g_datas.end(), delete_proc<data>());
}
static data * mk_random_data() {
data * d = alloc(data);
for (unsigned i = 0; i < NUM_FEATURES; i++)
d->push_back(rand() % 1000);
g_datas.push_back(d);
return d;
}
struct le_visitor {
data * m_data;
le_visitor(data * d):m_data(d) {}
bool operator()(data * other) {
// TRACE("fvi", tout << *other << " <= " << *m_data << "\n";);
for (unsigned i = 0; i < NUM_FEATURES; i++) {
SASSERT(to_feature((*other)[i]) <= to_feature((*m_data)[i]));
}
return true;
}
};
static void tst1(unsigned n1) {
typedef fvi<data, to_feature_vector, data_hash> data_set;
data_set index1(NUM_FEATURES, to_feature_vector(NUM_FEATURES));
ptr_vector<data> index2;
for (unsigned i = 0; i < n1; i++) {
int op = rand()%6;
if (op < 3) {
data * d = mk_random_data();
if (!index1.contains(d)) {
// TRACE("fvi", tout << "inserting: " << *d << "\n";);
index1.insert(d);
index2.push_back(d);
SASSERT(std::find(index2.begin(), index2.end(), d) != index2.end());
SASSERT(index1.contains(d));
}
}
else if (op < 4) {
if (!index2.empty()) {
unsigned idx = rand() % index2.size();
if (index2[idx]) {
SASSERT(index1.contains(index2[idx]));
}
}
}
else if (op < 5) {
if (!index2.empty()) {
unsigned idx = rand() % index2.size();
if (index2[idx]) {
// TRACE("fvi", tout << "erasing: " << *(index2[idx]) << "\n";);
index1.erase(index2[idx]);
SASSERT(!index1.contains(index2[idx]));
index2[idx] = 0;
}
}
}
else {
if (!index2.empty()) {
unsigned idx = rand() % index2.size();
data * d = index2[idx];
if (d)
index1.visit(d, le_visitor(d));
}
}
}
TRACE("fvi",
data_set::statistics s;
index1.stats(s);
tout << "size: " << s.m_size << "\n";
tout << "num. nodes: " << s.m_num_nodes << "\n";
tout << "num. leaves: " << s.m_num_leaves << "\n";
tout << "min. leaf size: " << s.m_min_leaf_size << "\n";
tout << "max. leaf size: " << s.m_max_leaf_size << "\n";
);
}
void tst_fvi() {
for (unsigned i = 0; i < 1000; i++)
tst1(100);
tst1(10000);
collect();
}
#else
void tst_fvi() {
}
#endif

View file

@ -0,0 +1,115 @@
#include "z3.h"
#include "trace.h"
#include "debug.h"
static Z3_ast mk_var(Z3_context ctx, char const* name, Z3_sort s) {
return Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, name), s);
}
static Z3_ast mk_int_var(Z3_context ctx, char const* name) {
return mk_var(ctx, name, Z3_mk_int_sort(ctx));
}
static void tst_get_implied_equalities1() {
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_del_config(cfg);
Z3_sort int_ty = Z3_mk_int_sort(ctx);
Z3_ast a = mk_int_var(ctx,"a");
Z3_ast b = mk_int_var(ctx,"b");
Z3_ast c = mk_int_var(ctx,"c");
Z3_ast d = mk_int_var(ctx,"d");
Z3_func_decl f = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx,"f"), 1, &int_ty, int_ty);
Z3_ast fa = Z3_mk_app(ctx, f, 1, &a);
Z3_ast fb = Z3_mk_app(ctx, f, 1, &b);
Z3_ast fc = Z3_mk_app(ctx, f, 1, &c);
unsigned const num_terms = 7;
unsigned i;
Z3_ast terms[7] = { a, b, c, d, fa, fb, fc };
unsigned class_ids[7] = { 0, 0, 0, 0, 0, 0, 0 };
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, a, b));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, b, d));
Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fa, fc));
Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fc, d));
Z3_get_implied_equalities(ctx, num_terms, terms, class_ids);
for (i = 0; i < num_terms; ++i) {
printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]);
}
SASSERT(class_ids[1] == class_ids[0]);
SASSERT(class_ids[2] != class_ids[0]);
SASSERT(class_ids[3] == class_ids[0]);
SASSERT(class_ids[4] != class_ids[0]);
SASSERT(class_ids[5] != class_ids[0]);
SASSERT(class_ids[6] != class_ids[0]);
SASSERT(class_ids[4] == class_ids[5]);
printf("asserting b <= f(a)\n");
Z3_assert_cnstr(ctx, Z3_mk_le(ctx, b, fa));
Z3_get_implied_equalities(ctx, num_terms, terms, class_ids);
for (i = 0; i < num_terms; ++i) {
printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]);
}
SASSERT(class_ids[1] == class_ids[0]);
SASSERT(class_ids[2] != class_ids[0]);
SASSERT(class_ids[3] == class_ids[0]);
SASSERT(class_ids[4] == class_ids[0]);
SASSERT(class_ids[5] == class_ids[0]);
SASSERT(class_ids[6] == class_ids[0]);
/* delete logical context */
Z3_del_context(ctx);
}
static void tst_get_implied_equalities2() {
enable_trace("after_search");
enable_trace("get_implied_equalities");
enable_trace("implied_equalities");
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_del_config(cfg);
Z3_sort int_ty = Z3_mk_int_sort(ctx);
Z3_sort a_ty = Z3_mk_array_sort(ctx, int_ty, int_ty);
Z3_ast a = mk_int_var(ctx,"a");
Z3_ast b = mk_int_var(ctx,"b");
Z3_ast c = mk_int_var(ctx,"c");
Z3_ast d = mk_int_var(ctx,"d");
Z3_ast one = Z3_mk_numeral(ctx, "1", int_ty);
Z3_ast two = Z3_mk_numeral(ctx, "2", int_ty);
Z3_ast x = Z3_mk_const_array(ctx, int_ty, one);
Z3_ast y = Z3_mk_store(ctx, x, one, a);
Z3_ast z = Z3_mk_store(ctx, y, two , b);
Z3_ast u = Z3_mk_store(ctx, x, two , b);
Z3_ast v = Z3_mk_store(ctx, u, one , a);
unsigned const num_terms = 5;
unsigned i;
Z3_ast terms[5] = { x, y, z, u, v};
unsigned class_ids[5] = { 0, 0, 0, 0, 0};
Z3_get_implied_equalities(ctx, num_terms, terms, class_ids);
for (i = 0; i < num_terms; ++i) {
printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]);
}
SASSERT(class_ids[1] != class_ids[0]);
SASSERT(class_ids[2] != class_ids[0]);
SASSERT(class_ids[3] != class_ids[0]);
SASSERT(class_ids[4] != class_ids[0]);
SASSERT(class_ids[4] == class_ids[2]);
SASSERT(class_ids[2] != class_ids[1]);
SASSERT(class_ids[3] != class_ids[1]);
SASSERT(class_ids[4] != class_ids[1]);
SASSERT(class_ids[3] != class_ids[2]);
/* delete logical context */
Z3_del_context(ctx);
}
void tst_get_implied_equalities() {
tst_get_implied_equalities1();
tst_get_implied_equalities2();
}

93
src/test/grobner.cpp Normal file
View file

@ -0,0 +1,93 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
grobner.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-12-05.
Revision History:
--*/
#include"smtparser.h"
#include"ast_pp.h"
#include"arith_decl_plugin.h"
#include"simplifier.h"
#include"basic_simplifier_plugin.h"
#include"arith_simplifier_plugin.h"
#include"front_end_params.h"
#include"grobner.h"
void display_eqs(grobner & gb, v_dependency_manager & dep_m) {
std::cerr << "RESULT:\n";
ptr_vector<grobner::equation> eqs;
gb.get_equations(eqs);
ptr_vector<grobner::equation>::iterator it = eqs.begin();
ptr_vector<grobner::equation>::iterator end = eqs.end();
for (; it != end; ++it) {
grobner::equation * eq = *it;
ptr_vector<void> exs;
v_dependency * d = eq->get_dependency();
dep_m.linearize(d, exs);
std::cerr << "{";
ptr_vector<void>::iterator it2 = exs.begin();
ptr_vector<void>::iterator end2 = exs.end();
for (bool first = true; it2 != end2; ++it2) {
if (first) first = false; else std::cerr << " ";
std::cerr << *it2;
}
std::cerr << "}, lc: " << eq->is_linear_combination() << ", ";
gb.display_equation(std::cerr, *eq);
}
}
void tst_grobner(char ** argv, int argc, int & i) {
front_end_params params;
if (i + 1 < argc) {
char const* file_path = argv[i+1];
ast_manager m;
smtlib::parser* parser = smtlib::parser::create(m);
m.register_decl_plugins();
parser->initialize_smtlib();
if (!parser->parse_file(file_path)) {
std::cout << "Could not parse file : " << file_path << std::endl;
dealloc(parser);
return;
}
smtlib::benchmark* b = parser->get_benchmark();
simplifier simp(m);
basic_simplifier_plugin * bp = alloc(basic_simplifier_plugin, m);
simp.register_plugin(bp);
simp.register_plugin(alloc(arith_simplifier_plugin, m, *bp, params));
arith_util util(m);
v_dependency_manager dep_m;
grobner gb(m, dep_m);
ptr_vector<expr>::const_iterator it = b->begin_axioms();
ptr_vector<expr>::const_iterator end = b->end_axioms();
for (unsigned idx = 1; it != end; ++it, ++idx) {
expr * ax = *it;
expr_ref s_ax(m);
proof_ref pr(m);
simp(ax, s_ax, pr);
std::cerr << mk_pp(s_ax, m) << "\n";
if (m.is_eq(s_ax))
gb.assert_eq(s_ax, dep_m.mk_leaf(reinterpret_cast<void*>(idx)));
}
gb.display(std::cerr);
gb.compute_basis(1024);
display_eqs(gb, dep_m);
dealloc(parser);
}
}

135
src/test/hashtable.cpp Normal file
View file

@ -0,0 +1,135 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_hashtable.cpp
Abstract:
Test hashtable module
Author:
Leonardo de Moura (leonardo) 2006-09-12.
Revision History:
--*/
#ifdef _WINDOWS
#include<iostream>
#include<hash_set>
#include<stdlib.h>
#include"hashtable.h"
#ifndef Z3DEBUG
#undef SASSERT
#define SASSERT(COND) { if (!(COND)) std::cerr << "ERROR: " << #COND << "\n"; } ((void) 0)
#endif
struct int_hash_proc { unsigned operator()(int x) const { return x * 3; } };
typedef int_hashtable<int_hash_proc, default_eq<int> > int_set;
typedef stdext::hash_set<int, stdext::hash_compare<int, std::less<int> > > safe_int_set;
// typedef safe_int_set int_set;
inline bool contains(int_set & h, int i) {
// return h.find(i) != h.end();
return h.contains(i);
}
const int N = 10000;
int vals[N];
static void tst1() {
int_set h1;
int size = 0;
for (int i = 1; i < N; i ++) {
int v = rand() % (N / 2);
h1.insert(v);
vals[i] = v;
SASSERT(contains(h1, v));
}
std::cout << "step1\n"; std::cout.flush();
for (int i = 1; i < N; i ++) {
SASSERT(contains(h1, vals[i]));
}
std::cout << "step2\n"; std::cout.flush();
for (int i = 1; i < N; i += 2) {
h1.erase(vals[i]);
SASSERT(!contains(h1, vals[i]));
}
std::cout << "step3\n"; std::cout.flush();
for (int i = 1; i < N; i += 2) {
h1.insert(vals[i]);
}
std::cout << "step4\n"; std::cout.flush();
for (int i = 1; i < N; i ++) {
SASSERT(contains(h1, vals[i]));
}
}
static void tst2() {
int_set h1;
safe_int_set h2;
int N = rand() % 1000;
for (int i = 0; i < N; i++) {
int v = rand()%1000;
if (rand() % 3 == 2) {
h1.erase(v);
h2.erase(v);
SASSERT(!contains(h1, v));
}
else {
h1.insert(v);
h2.insert(v);
SASSERT(contains(h1, v));
}
}
{
safe_int_set::iterator it = h2.begin();
safe_int_set::iterator end = h2.end();
for(; it != end; ++it) {
SASSERT(contains(h1, *it));
}
}
{
int_set::iterator it = h1.begin();
int_set::iterator end = h1.end();
int n = 0;
for (; it != end; ++it) {
SASSERT(contains(h1, *it));
n++;
}
SASSERT(n == h1.size());
}
SASSERT(h1.size() == h2.size());
// std::cout << "size: " << h1.size() << ", capacity: " << h1.capacity() << "\n"; std::cout.flush();
}
static void tst3() {
int_set h1;
h1.insert(10);
h1.insert(20);
h1.insert(30);
h1.erase(20);
int_set h2(h1);
SASSERT(h1.contains(10));
SASSERT(!h1.contains(20));
SASSERT(h1.contains(30));
SASSERT(h2.contains(10));
SASSERT(!h2.contains(20));
SASSERT(h2.contains(30));
SASSERT(h2.size() == 2);
}
void tst_hashtable() {
tst3();
for (int i = 0; i < 100; i++)
tst2();
tst1();
}
#else
void tst_hashtable() {
}
#endif

133
src/test/heap.cpp Normal file
View file

@ -0,0 +1,133 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_heap.cpp
Abstract:
Test heap template.
Author:
Leonardo de Moura (leonardo) 2006-09-18.
Revision History:
--*/
#include<iostream>
#include"heap.h"
#include"hashtable.h"
#include"trace.h"
struct lt_proc { bool operator()(int v1, int v2) const { return v1 < v2; } };
typedef heap<lt_proc> int_heap;
struct int_hash_proc { unsigned operator()(int v) const { return v * 17; }};
typedef int_hashtable<int_hash_proc, default_eq<int> > int_set;
#define N 10000
static void tst1() {
int_heap h(N);
int_set t;
for (int i = 0; i < N * 3; i++) {
int val = rand() % N;
if (!h.contains(val)) {
SASSERT(!t.contains(val));
h.insert(val);
t.insert(val);
}
else {
SASSERT(t.contains(val));
}
}
SASSERT(h.check_invariant());
int_set::iterator it = t.begin();
int_set::iterator end = t.end();
for (; it != end; ++it) {
SASSERT(h.contains(*it));
}
int last = -1;
while (!h.empty()) {
int m1 = h.min_value();
int m2 = h.erase_min();
SASSERT(m1 == m2);
SASSERT(last < m2);
}
}
int g_value[N];
struct lt_proc2 { bool operator()(int v1, int v2) const { SASSERT(v1 < N && v2 < N); return g_value[v1] < g_value[v2]; } };
typedef heap<lt_proc2> int_heap2;
static void init_values() {
for (unsigned i = 0; i < N; i++)
g_value[i] = rand();
}
static void dump_heap(const int_heap2 & h, std::ostream & out) {
// int_heap2::const_iterator it = h.begin();
// int_heap2::const_iterator end = h.end();
// for (; it != end; ++it) {
// out << *it << ":" << g_value[*it] << " ";
// }
// out << "\n";
}
static void tst2() {
int_heap2 h(N);
for (int i = 0; i < N * 10; i++) {
if (i % 1000 == 0) std::cout << "i: " << i << std::endl;
int cmd = rand() % 10;
if (cmd <= 3) {
// insert
int val = rand() % N;
if (!h.contains(val)) {
TRACE("heap", tout << "inserting: " << val << "\n";);
h.insert(val);
TRACE("heap", dump_heap(h, tout););
SASSERT(h.contains(val));
}
}
else if (cmd <= 6) {
int val = rand() % N;
if (h.contains(val)) {
TRACE("heap", tout << "removing: " << val << "\n";);
h.erase(val);
TRACE("heap", dump_heap(h, tout););
SASSERT(!h.contains(val));
}
}
else if (cmd <= 8) {
// increased & decreased
int val = rand() % N;
int old_v = g_value[val];
int new_v = rand();
if (h.contains(val)) {
g_value[val] = new_v;
if (old_v < new_v) {
TRACE("heap", tout << "value of: " << val << " increased old: " << old_v << " new: " << new_v << "\n";);
h.increased(val);
}
else {
TRACE("heap", tout << "value of: " << val << " decreased old: " << old_v << " new: " << new_v << "\n";);
h.decreased(val);
}
}
}
else {
SASSERT(h.check_invariant());
}
}
SASSERT(h.check_invariant());
}
void tst_heap() {
// enable_debug("heap");
enable_trace("heap");
tst1();
init_values();
tst2();
}

View file

@ -0,0 +1,60 @@
#include "horn_subsume_model_converter.h"
#include "arith_decl_plugin.h"
#include "model_smt2_pp.h"
void tst_horn_subsume_model_converter() {
ast_manager m;
m.register_decl_plugins();
arith_util a(m);
ptr_vector<sort> ints;
ints.push_back(a.mk_int());
ints.push_back(a.mk_int());
ints.push_back(a.mk_int());
func_decl_ref p(m), q(m), r(m);
p = m.mk_func_decl(symbol("p"), 2, ints.c_ptr(), m.mk_bool_sort());
q = m.mk_func_decl(symbol("q"), 2, ints.c_ptr(), m.mk_bool_sort());
r = m.mk_func_decl(symbol("r"), 2, ints.c_ptr(), m.mk_bool_sort());
ref<horn_subsume_model_converter> mc = alloc(horn_subsume_model_converter,m);
model_ref mr = alloc(model, m);
mc->insert(p, m.mk_app(q, a.mk_numeral(rational(1), true), a.mk_numeral(rational(2), true)));
model_converter_ref mcr = mc.get();
apply(mcr, mr, 0);
model_smt2_pp(std::cout, m, *mr.get(), 0);
mr = alloc(model, m);
mc->insert(p, m.mk_app(q, a.mk_numeral(rational(3), true), a.mk_numeral(rational(5), true)));
apply(mcr, mr, 0);
model_smt2_pp(std::cout, m, *mr.get(), 0);
mr = alloc(model, m);
mc->insert(p, m.mk_app(r, m.mk_var(0,a.mk_int()), m.mk_var(1, a.mk_int())));
apply(mcr, mr, 0);
model_smt2_pp(std::cout, m, *mr.get(), 0);
mr = alloc(model, m);
app_ref head1(m);
expr_ref body1(m), body2(m);
func_decl_ref pred(m);
head1 = m.mk_app(p, m.mk_var(0, a.mk_int()), m.mk_var(0, a.mk_int()));
body1 = m.mk_app(q, m.mk_var(1, a.mk_int()), m.mk_var(2, a.mk_int()));
VERIFY(mc->mk_horn(head1, body1, pred, body2));
mc->insert(pred, body2);
apply(mcr, mr, 0);
model_smt2_pp(std::cout, m, *mr.get(), 0);
mr = alloc(model, m);
head1 = m.mk_app(p, m.mk_var(0, a.mk_int()), m.mk_var(0, a.mk_int()));
body1 = m.mk_app(q, m.mk_var(1, a.mk_int()), m.mk_var(0, a.mk_int()));
VERIFY(mc->mk_horn(head1, body1, pred, body2));
mc->insert(pred, body2);
apply(mcr, mr, 0);
model_smt2_pp(std::cout, m, *mr.get(), 0);
}

117
src/test/hwf.cpp Normal file
View file

@ -0,0 +1,117 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
hwf.cpp
Abstract:
hwf repros...
Author:
Leonardo de Moura (leonardo) 2012-08-23.
Revision History:
--*/
#include"hwf.h"
#include"f2n.h"
#include"rational.h"
static void bug_set_double() {
hwf_manager m;
hwf a;
m.set(a, 0.1);
SASSERT(m.is_regular(a));
m.set(a, 1.1);
SASSERT(m.is_regular(a));
m.set(a, 11.3);
SASSERT(m.is_regular(a));
m.set(a, 0.0);
SASSERT(m.is_regular(a));
}
static void bug_to_rational() {
hwf_manager m;
hwf a;
unsynch_mpq_manager mq;
scoped_mpq r(mq);
double ad, rd;
m.set(a, 0.0);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
SASSERT(ad == rd);
m.set(a, 1.0);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
SASSERT(ad == rd);
m.set(a, 1.5);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
SASSERT(ad == rd);
m.set(a, 0.875);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
SASSERT(ad == rd);
m.set(a, -1.0);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
SASSERT(ad == rd);
m.set(a, -1.5);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
SASSERT(ad == rd);
m.set(a, -0.875);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
SASSERT(ad == rd);
m.set(a, 0.1);
m.to_rational(a, r);
ad = m.to_double(a);
rd = mq.get_double(r);
double diff = (ad-rd);
#ifdef _WINDOWS
// CMW: This one depends on the rounding mode,
// which is implicit in both hwf::set and in mpq::to_double.
SASSERT(diff >= -DBL_EPSILON && diff <= DBL_EPSILON);
#endif
}
static void bug_is_int() {
unsigned raw_val[2] = { 2147483648, 1077720461 };
double val = *(double*)(raw_val);
std::cout << val << "\n";
hwf_manager m;
hwf a;
m.set(a, val);
SASSERT(!m.is_int(a));
}
void tst_hwf() {
bug_is_int();
bug_set_double();
bug_to_rational();
}

View file

@ -0,0 +1,72 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
im_float_config.h
Abstract:
Auxiliary class for testing intervals with software floats end points.
Author:
Leonardo de Moura (leonardo) 2012-08-21.
Revision History:
--*/
#ifndef _IM_FLOAT_CONFIG_H_
#define _IM_FLOAT_CONFIG_H_
#include"f2n.h"
#include"mpf.h"
#include"hwf.h"
template<typename f_manager>
class im_float_config {
f2n<f_manager> m_manager;
public:
typedef f2n<f_manager> numeral_manager;
typedef typename f_manager::numeral numeral;
im_float_config(f_manager & m, unsigned ebits = 11, unsigned sbits = 53):m_manager(m, ebits, sbits) {}
struct interval {
numeral m_lower;
numeral m_upper;
};
void round_to_minus_inf() { m_manager.round_to_minus_inf(); }
void round_to_plus_inf() { m_manager.round_to_plus_inf(); }
void set_rounding(bool up) { m_manager.set_rounding(up); }
// Getters
numeral const & lower(interval const & a) const { return a.m_lower; }
numeral const & upper(interval const & a) const { return a.m_upper; }
numeral & lower(interval & a) { return a.m_lower; }
numeral & upper(interval & a) { return a.m_upper; }
bool lower_is_inf(interval const & a) const { return m_manager.m().is_ninf(a.m_lower); }
bool upper_is_inf(interval const & a) const { return m_manager.m().is_pinf(a.m_upper); }
bool lower_is_open(interval const & a) const { return lower_is_inf(a); }
bool upper_is_open(interval const & a) const { return upper_is_inf(a); }
// Setters
void set_lower(interval & a, numeral const & n) { m_manager.set(a.m_lower, n); }
void set_upper(interval & a, numeral const & n) { m_manager.set(a.m_upper, n); }
void set_lower_is_open(interval & a, bool v) {}
void set_upper_is_open(interval & a, bool v) {}
void set_lower_is_inf(interval & a, bool v) { if (v) m_manager.m().mk_ninf(m_manager.ebits(), m_manager.sbits(), a.m_lower); }
void set_upper_is_inf(interval & a, bool v) { if (v) m_manager.m().mk_pinf(m_manager.ebits(), m_manager.sbits(), a.m_upper); }
// Reference to numeral manager
numeral_manager & m() const { return const_cast<numeral_manager&>(m_manager); }
};
template<typename fmanager>
inline void del_f_interval(im_float_config<fmanager> & cfg, typename im_float_config<fmanager>::interval & a) {
cfg.m().del(a.m_lower);
cfg.m().del(a.m_upper);
}
#endif

609
src/test/imdd.cpp Normal file
View file

@ -0,0 +1,609 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
imdd.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-10-14.
Revision History:
--*/
#include"imdd.h"
static void tst0() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m), d4(m);
d1 = m.mk_empty(1);
d2 = m.mk_empty(1);
m.insert_dupdt(d1, 10, 20);
m.insert_dupdt(d1, 31, 50);
m.insert_dupdt(d2, 1, 5);
m.insert_dupdt(d2, 11, 13);
m.mk_product(d1, d2, d4);
m.mk_product(d4, d2, d4);
m.mk_product_dupdt(d1, d2);
std::cout << "d1:\n" << mk_ll_pp(d1, m) << "\n-------\n";
m.mk_product_dupdt(d1, d2);
std::cout << "d4:\n" << mk_ll_pp(d4, m) << "\nd1:\n" << mk_ll_pp(d1, m) << "\nd2:\n" << mk_ll_pp(d2, m) << "\n";
std::cout << d1 << "\n" << d2 << "\n";
m.mk_product_dupdt(d1, d1);
std::cout << "d1 X d1:\n" << mk_ll_pp(d1, m) << "\n";
}
static void add_triple(imdd_manager & m, imdd_ref & d, unsigned l1, unsigned u1, unsigned l2, unsigned u2, unsigned l3, unsigned u3,
bool destructive = false, bool memoize = true) {
unsigned lowers[3] = {l1, l2, l3};
unsigned uppers[3] = {u1, u2, u3};
if (destructive)
m.add_facts_dupdt(d, 3, lowers, uppers, memoize);
else
m.add_facts(d, d, 3, lowers, uppers, memoize);
// std::cout << mk_ll_pp(d, m) << "\n";
}
static void add_pair(imdd_manager & m, imdd_ref & d, unsigned l1, unsigned u1, unsigned l2, unsigned u2, bool destructive = false, bool memoize = true) {
unsigned lowers[2] = {l1, l2};
unsigned uppers[2] = {u1, u2};
if (destructive)
m.add_facts_dupdt(d, 2, lowers, uppers, memoize);
else
m.add_facts(d, d, 2, lowers, uppers, memoize);
// std::cout << mk_ll_pp(d, m) << "\n";
}
static void add_some_facts(imdd_manager & m, imdd_ref & d, bool destructive = false, bool memoize = true) {
std::cout << "destructive: " << destructive << ", memoize: " << memoize << std::endl;
add_triple(m, d, 1, 10, 3, 3, 0, 100, destructive, memoize);
std::cout << mk_ll_pp(d, m) << std::endl;
SASSERT(m.contains(d, 2, 3, 20));
SASSERT(!m.contains(d, 2, 4, 20));
SASSERT(!m.contains(d, 2, 3, 200));
SASSERT(!m.contains(d, 0, 3, 200));
SASSERT(m.contains(d,1,3,0));
add_triple(m, d, 3, 6, 3, 4, 7, 101, destructive, memoize);
std::cout << mk_ll_pp(d, m) << std::endl;
add_triple(m, d, 3, 6, 2, 2, 7, 101, destructive, memoize);
std::cout << mk_ll_pp(d, m) << std::endl;
add_triple(m, d, 3, 6, 5, 6, 7, 101, destructive, memoize);
SASSERT(m.contains(d, 2, 3, 20));
std::cout << mk_ll_pp(d, m) << std::endl;
SASSERT(!m.contains(d, 2, 4, 20));
SASSERT(m.contains(d, 3, 4, 20));
SASSERT(!m.contains(d, 2, 3, 200));
SASSERT(!m.contains(d, 0, 3, 200));
SASSERT(m.contains(d,1,3,0));
}
static void tst1() {
std::cout << "--------------------------------\n";
imdd_manager m;
{
imdd_ref d(m);
d = m.mk_empty(3);
add_some_facts(m, d);
}
{
imdd_ref d(m);
d = m.mk_empty(3);
add_some_facts(m, d, true, false);
m.defrag(d);
std::cout << mk_ll_pp(d, m) << "\n";
}
}
static void tst2() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 10, 20, 11, 21, 12, 22);
add_triple(m, d1, 30, 40, 31, 41, 32, 42);
d2 = m.mk_empty(3);
add_triple(m, d2, 15, 22, 15, 23, 7, 18);
add_triple(m, d2, 28, 42, 29, 39, 34, 46);
add_triple(m, d2, 28, 42, 29, 39, 100, 200);
add_triple(m, d2, 28, 42, 50, 60, 100, 200);
std::cout << mk_ll_pp(d1, m) << "\n";
std::cout << mk_ll_pp(d2, m) << "\n";
m.mk_union(d1, d2, d3);
SASSERT(m.subsumes(d3, d1));
SASSERT(m.subsumes(d3, d2));
SASSERT(!m.subsumes(d1, d3));
SASSERT(!m.subsumes(d2, d3));
std::cout << "d3: " << d3.get() << "\n" << mk_ll_pp(d3, m) << "\n";
m.mk_union_dupdt(d1, d2, false);
std::cout << "d1: " << d1.get() << "\n" << mk_ll_pp(d1, m) << "\n";
SASSERT(m.is_equal(d1, d3));
SASSERT(!m.is_equal(d2, d3));
SASSERT(!m.is_equal(d2, d1));
std::cout << "memory(d1): " << m.memory(d1) << "\n";
}
static void tst3() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m);
d1 = m.mk_empty(3);
unsigned mins[3] = {0,0,0};
unsigned maxs[3] = {127, 511, 255};
m.mk_complement(d1, d1, 3, mins, maxs);
std::cout << d1 << "\n";
m.mk_complement(d1, d1, 3, mins, maxs);
std::cout << d1 << "\n";
SASSERT(d1->empty());
d1 = m.mk_empty(3);
add_triple(m, d1, 10, 20, 11, 21, 12, 22);
add_triple(m, d1, 30, 40, 31, 41, 32, 42);
std::cout << d1 << "\n";
m.mk_complement(d1, d1, 3, mins, maxs);
std::cout << mk_ll_pp(d1,m) << "\n";
m.mk_filter_equal(d1, d1, 1, 15);
std::cout << "after selecting second column = 15\n" << mk_ll_pp(d1,m) << "\n";
}
static void tst4() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 1, 2, 2, 5, 4, 4);
add_triple(m, d1, 3, 4, 3, 4, 2, 5);
std::cout << "testing iterator:\n";
imdd_manager::iterator it = m.begin(d1);
imdd_manager::iterator end = m.end(d1);
for (; it != end; ++it) {
unsigned * tuple = *it;
std::cout << "[";
for (unsigned i = 0; i < d1->get_arity(); i++) {
if (i > 0)
std::cout << ", ";
std::cout << tuple[i];
}
std::cout << "]\n";
}
}
static void tst5() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
std::cout.flush();
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 100, 10, 20, 3, 10);
std::cout << mk_ll_pp(d1,m) << std::endl;
add_triple(m, d1, 5, 100, 34, 50, 98, 110);
std::cout << mk_ll_pp(d1,m) << std::endl;
unsigned vals[3] = {6, 8, 3};
SASSERT(!m.contains(d1, 3, vals));
add_triple(m, d1, 6, 25, 8, 30, 14, 50);
std::cout << mk_ll_pp(d1,m) << std::endl;
SASSERT(!m.contains(d1, 3, vals));
unsigned vars[2] = {0, 2};
d2 = d1;
d3 = d1;
m.mk_filter_identical(d1, d1, 2, vars);
vars[1] = 1;
std::cout << "d1:\n" << mk_ll_pp(d1,m) << "\n";
m.mk_filter_identical(d2, d2, 2, vars);
std::cout << "d2:\n" << mk_ll_pp(d2,m) << "\n";
vars[0] = 1;
vars[1] = 2;
m.mk_filter_identical(d3, d3, 2, vars);
std::cout << "d3:\n" << mk_ll_pp(d3,m) << "\n";
}
static void add_5tuple(imdd_manager & m, imdd_ref & d, unsigned l1, unsigned u1, unsigned l2, unsigned u2, unsigned l3, unsigned u3,
unsigned l4, unsigned u4, unsigned l5, unsigned u5, bool destructive = false, bool memoize = true) {
unsigned lowers[5] = {l1, l2, l3, l4, l5};
unsigned uppers[5] = {u1, u2, u3, u4, u5};
if (destructive)
m.add_facts_dupdt(d, 5, lowers, uppers, memoize);
else
m.add_facts(d, d, 5, lowers, uppers, memoize);
// std::cout << mk_ll_pp(d, m) << "\n";
}
static void tst6() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m);
std::cout.flush();
d1 = m.mk_empty(5);
// TODO: make a more complicated mk_filter_identical example
}
static void tst7() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d2(m), d3(m);
d2 = m.mk_empty(3);
add_triple(m, d2, 15, 22, 15, 23, 7, 18);
add_triple(m, d2, 28, 42, 29, 39, 34, 46);
add_triple(m, d2, 28, 42, 29, 39, 100, 200);
add_triple(m, d2, 28, 42, 50, 60, 100, 200);
std::cout << "mk_project\n";
std::cout << mk_ll_pp(d2, m) << "\n";
unsigned vars[1] = {1};
m.mk_project(d2, d3, 1, vars);
std::cout << mk_ll_pp(d3, m) << "\n";
}
static void tst8() {
std::cout << "--------------------------------\n";
// enable_trace("mk_swap_bug");
imdd_manager m;
imdd_ref d2(m), d3(m);
d2 = m.mk_empty(3);
add_triple(m, d2, 15, 22, 15, 23, 7, 18);
add_triple(m, d2, 28, 42, 29, 39, 34, 46);
add_triple(m, d2, 28, 42, 29, 39, 100, 200);
add_triple(m, d2, 28, 42, 50, 60, 100, 200);
std::cout << mk_ll_pp(d2, m) << "\n";
m.mk_swap(d2, d3, 0);
std::cout << "after swap 0<->1\n";
std::cout << mk_ll_pp(d3, m) << "\n";
m.mk_swap(d2, d3, 1);
std::cout << "after swap 1<->2\n";
std::cout << mk_ll_pp(d3, m) << "\n";
}
static void tst9() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d2(m), d3(m);
d2 = m.mk_empty(5);
add_5tuple(m, d2, 2,2, 3,3, 1, 1, 5, 10, 100, 200);
std::cout << mk_ll_pp(d2, m) << "\n";
add_5tuple(m, d2, 2,2, 3,3, 1, 1, 15, 20, 100, 200);
std::cout << mk_ll_pp(d2, m) << "\n";
add_5tuple(m, d2, 4,4, 5,5, 1, 1, 5, 10, 100, 200);
std::cout << mk_ll_pp(d2, m) << "\n";
add_5tuple(m, d2, 4,4, 5,5, 1, 1, 15, 20, 100, 200);
std::cout << mk_ll_pp(d2, m) << "\n";
m.mk_swap(d2, d3, 2);
std::cout << "after swap 2<->3\n";
std::cout << mk_ll_pp(d3, m) << "\n";
}
static void tst10() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 100, 10, 20, 3, 10);
add_triple(m, d1, 5, 100, 34, 50, 98, 110);
m.add_bounded_var(d1, d2, 0, 66, 72);
std::cout << mk_ll_pp(d1, m) << "\n";
std::cout << mk_ll_pp(d2, m) << "\n";
m.add_bounded_var(d1, d3, 1, 64, 73);
std::cout << mk_ll_pp(d3, m) << "\n";
}
static void tst11() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 100, 10, 20, 3, 10);
add_triple(m, d1, 5, 100, 34, 50, 98, 110);
add_triple(m, d1, 20, 30, 5, 25, 11, 13);
m.mk_filter_distinct(d1, d2, 1, 2);
std::cout << mk_ll_pp(d1, m) << "\n";
std::cout << "filter_distinct(1,2):\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst12() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 1, 10, 5, 25, 10, 13);
m.mk_filter_distinct(d1, d2, 1, 2);
std::cout << mk_ll_pp(d1, m) << "\n";
std::cout << "filter_distinct(1,2):\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst13() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 25, 1, 10, 10, 13);
add_triple(m, d1, 5, 25, 20, 30, 10, 13);
m.mk_filter_distinct(d1, d2, 0, 2);
std::cout << mk_ll_pp(d1, m) << "\n";
std::cout << "filter_distinct(0,2):\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst14() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 25, 1, 10, 10, 13);
add_triple(m, d1, 5, 25, 20, 30, 15, 18);
std::cout << "destructive version\n";
std::cout << mk_ll_pp(d1, m) << "\n";
m.mk_filter_distinct_dupdt(d1, 0, 2);
std::cout << "filter_distinct(0,2):\n";
std::cout << mk_ll_pp(d1, m) << "\n";
}
static void tst15() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 5, 1, 10, 5, 5);
std::cout << mk_ll_pp(d1, m) << "\n";
m.mk_filter_distinct(d1, d2, 0, 2);
std::cout << "filter_distinct(0,2):\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst16() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 15, 1, 10, 50, 500);
std::cout << mk_ll_pp(d1, m) << "\n";
m.mk_filter_disequal(d1, d2, 1, 4);
std::cout << "filter_disequal(var1,4):\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst17() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(3);
add_triple(m, d1, 5, 15, 10, 10, 50, 500);
std::cout << mk_ll_pp(d1, m) << "\n";
m.mk_filter_disequal(d1, d2, 1, 10);
std::cout << "filter_disequal(var1,10):\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst18() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d1(m), d2(m), d3(m);
d1 = m.mk_empty(2);
add_pair(m, d1, 1112, 1290, 1302, 1302);
std::cout << mk_ll_pp(d1, m) << "\n";
m.mk_swap(d1, d2, 0);
std::cout << "mk_swap 0:\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst19() {
std::cout << "--------------------------------\n";
imdd_manager m;
imdd_ref d2(m), d3(m);
d2 = m.mk_empty(3);
add_triple(m, d2, 15, 22, 15, 23, 7, 18);
add_triple(m, d2, 28, 42, 29, 39, 34, 46);
add_triple(m, d2, 28, 42, 29, 39, 100, 200);
add_triple(m, d2, 28, 42, 50, 60, 100, 200);
std::cout << "mk_project_dupdt\n";
std::cout << mk_ll_pp(d2, m) << "\n";
unsigned vars[1] = {1};
m.mk_project_dupdt(d2, 1, vars);
std::cout << "new table\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void init(unsigned* v, unsigned a, unsigned b, unsigned c) {
v[0] = a;
v[1] = b;
v[2] = c;
}
static void tst20() {
std::cout << "--------------------------------\n";
std::cout << "remove_facts\n";
imdd_manager m;
imdd_ref d2(m), d3(m);
d2 = m.mk_empty(3);
add_triple(m, d2, 15, 22, 15, 23, 7, 18);
add_triple(m, d2, 28, 42, 29, 39, 34, 46);
add_triple(m, d2, 28, 42, 29, 39, 100, 200);
add_triple(m, d2, 28, 42, 50, 60, 100, 200);
std::cout << mk_ll_pp(d2, m) << "\n";
//
// [15, 22] -> #1:{
// [15, 23] -> {[7, 18]}*$80}*$80
// [28, 42] -> #2:{
// [29, 39] -> {[34, 46], [100, 200]}*$160
// [50, 60] -> {[100, 200]}*$80}*$80}$80
//
unsigned lowers[3] = {23,1,1};
unsigned uppers[3] = {24,1,1};
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (no change)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
lowers[0] = 22;
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (no change)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
init(lowers, 22, 15, 0);
init(uppers, 24, 23, 0);
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (no change)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
init(lowers, 22, 15, 7);
init(uppers, 24, 23, 18);
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (narrow first interval)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
init(lowers, 22, 15, 8);
init(uppers, 24, 23, 18);
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (split first interval)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
init(lowers, 22, 15, 8);
init(uppers, 24, 23, 17);
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (split first interval)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
init(lowers, 22, 15, 8);
init(uppers, 24, 23, 19);
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (split first interval)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
init(lowers, 30, 20, 120);
init(uppers, 40, 60, 140);
m.remove_facts(d2, d3, 3, lowers, uppers);
std::cout << "new table (split second interval)\n";
std::cout << mk_ll_pp(d3, m) << "\n";
}
static void tst21() {
std::cout << "--------------------------------\n";
std::cout << "remove_facts\n";
imdd_manager m;
imdd_ref d2(m), d3(m);
d2 = m.mk_empty(3);
add_triple(m, d2, 15, 22, 15, 23, 7, 18);
add_triple(m, d2, 28, 42, 29, 39, 34, 46);
add_triple(m, d2, 28, 42, 29, 39, 100, 200);
add_triple(m, d2, 28, 42, 50, 60, 100, 200);
std::cout << mk_ll_pp(d2, m) << "\n";
//
// [15, 22] -> #1:{
// [15, 23] -> {[7, 18]}*$80}*$80
// [28, 42] -> #2:{
// [29, 39] -> {[34, 46], [100, 200]}*$160
// [50, 60] -> {[100, 200]}*$80}*$80}$80
//
unsigned lowers[3] = {23,1,1};
unsigned uppers[3] = {24,1,1};
d3 = d2;
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (no change)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
d2 = d3;
lowers[0] = 22;
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (no change)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
init(lowers, 22, 15, 0);
init(uppers, 24, 23, 0);
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (no change)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
init(lowers, 22, 15, 7);
init(uppers, 24, 23, 18);
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (narrow first interval)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
init(lowers, 22, 15, 8);
init(uppers, 24, 23, 18);
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (split first interval)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
init(lowers, 22, 15, 8);
init(uppers, 24, 23, 17);
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (split first interval)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
init(lowers, 22, 15, 8);
init(uppers, 24, 23, 19);
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (split first interval)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
init(lowers, 30, 20, 120);
init(uppers, 40, 60, 140);
m.remove_facts_dupdt(d2, 3, lowers, uppers);
std::cout << "new table (split second interval)\n";
std::cout << mk_ll_pp(d2, m) << "\n";
}
static void tst22() {
std::cout << "--------------------------------\n";
std::cout << "swap\n";
imdd_manager m;
imdd_ref d2(m), d3(m), d4(m);
d2 = m.mk_empty(3);
random_gen rand;
for (unsigned i = 0; i < 130; ++i) {
unsigned a = rand(20);
unsigned b = rand(20);
unsigned c = rand(20);
add_triple(m, d2, a, a, b, b, c, c);
}
std::cout << mk_ll_pp(d2, m) << "\n";
m.mk_swap(d2, d3, 0, true);
std::cout << mk_ll_pp(d3, m) << "\n";
m.mk_swap(d3, d4, 0, true);
std::cout << mk_ll_pp(d4, m) << "\n";
SASSERT(m.is_subset(d2, d4));
SASSERT(m.is_subset(d4, d2));
}
void tst_imdd() {
// enable_trace("imdd_add_bug");
// enable_trace("add_facts_bug");
enable_trace("mk_distinct_imdd");
enable_trace("mk_union_core");
tst22();
tst0();
tst1();
tst2();
tst3();
tst4();
tst5();
tst6();
tst7();
tst19();
tst8();
tst9();
tst10();
tst11();
tst12();
tst13();
tst14();
tst15();
tst16();
tst17();
tst18();
tst20();
tst21();
}

183
src/test/inf_rational.cpp Normal file
View file

@ -0,0 +1,183 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_inf_rational.cpp
Abstract:
Test for Rational numbers with infinitesimals
Author:
Leonardo de Moura (leonardo) 2006-09-18.
Nikolaj Bjorner (nbjorner) 2006-10-24.
Revision History:
--*/
#include"inf_rational.h"
static void tst0() {
inf_rational n(rational(0), false);
TRACE("inf_rational", tout << n << "\n";);
SASSERT(n < inf_rational::zero());
SASSERT(!(n >= inf_rational::zero()));
}
void test_inc_dec(
inf_rational& r,
inf_rational const & b_8_5,
inf_rational const & b_7_5,
inf_rational const & b_7_10,
inf_rational const & b_17_10
)
{
r += rational(1,5);
SASSERT (r == b_8_5);
r -= rational(1,5);
SASSERT (r == b_7_5);
r += inf_rational(1,5);
SASSERT (r == b_8_5);
r -= inf_rational(1,5);
SASSERT (r == b_7_5);
r /= rational(2,1);
SASSERT (r == b_7_10);
inf_rational r_pre = r++;
SASSERT (r_pre == b_7_10);
SASSERT (r == b_17_10);
inf_rational r_post = --r;
SASSERT (r_post == b_7_10);
SASSERT (r == b_7_10);
r_post = ++r;
SASSERT (r_post == b_17_10);
SASSERT (r == b_17_10);
r_pre = r--;
SASSERT (r_pre == b_17_10);
SASSERT (r == b_7_10);
r_pre = r;
r_pre += inf_rational(1,2);
r_post = r_pre;
r_post -= inf_rational(1,2);
SASSERT(r == r_post);
SASSERT(r + inf_rational(1,2) == r_pre);
r_pre = r;
r_pre /= rational(2,1);
r_post = r_pre;
r_post /= rational(1,2);
SASSERT(r == r_post);
SASSERT(rational(1,2) * r == r_pre);
SASSERT(r == r_pre / rational(1,2));
}
void
tst_inf_rational()
{
tst0();
inf_rational r1;
inf_rational r2(r1);
SASSERT (r1 == r2);
inf_rational r3(1);
inf_rational r4(0);
SASSERT (r4 == r1);
SASSERT (r3 != r4);
inf_rational r5(0,1);
inf_rational r6(1,1);
inf_rational r7(2,2);
inf_rational r8(7,5);
SASSERT (r1 == r5);
SASSERT (r6 == r3);
SASSERT (r7 == r3);
inf_rational r9(rational(7,5));
SASSERT (r8 == r9);
r9.reset();
SASSERT (r1 == r9);
SASSERT (r1.is_int());
SASSERT (!r8.is_int());
SASSERT (0 == r1.get_int64());
r9 = r8;
SASSERT (r8 == r9);
inf_rational n = numerator(r7);
inf_rational d = denominator(r7);
{
inf_rational b_8_5 = inf_rational(8,5);
inf_rational b_7_5 = inf_rational(7,5);
inf_rational b_7_10 = inf_rational(7,10);
inf_rational b_17_10 = inf_rational(17,10);
inf_rational r = r9;
test_inc_dec(r, b_8_5, b_7_5, b_7_10, b_17_10);
}
{
inf_rational b_8_5 = inf_rational(rational(8,5),true);
inf_rational b_7_5 = inf_rational(rational(7,5),true);
inf_rational b_7_10 = inf_rational(rational(7,5),true) / rational(2);
inf_rational b_17_10 = b_7_10 + inf_rational(1);
inf_rational r (rational(7,5),true);
test_inc_dec(r, b_8_5, b_7_5, b_7_10, b_17_10);
}
SASSERT(inf_rational(rational(1,2),true) > inf_rational(rational(1,2)));
SASSERT(inf_rational(rational(1,2),false) < inf_rational(rational(1,2)));
SASSERT(inf_rational(rational(1,2),true) >= inf_rational(rational(1,2)));
SASSERT(inf_rational(rational(1,2)) >= inf_rational(rational(1,2),false));
SASSERT(inf_rational(rational(1,2),false) != inf_rational(rational(1,2)));
SASSERT(inf_rational(rational(1,2),true) != inf_rational(rational(1,2)));
SASSERT(inf_rational(rational(1,2),false) != inf_rational(rational(1,2),true));
inf_rational h_neg(rational(1,2),false);
inf_rational h_pos(rational(1,2),true);
h_neg.neg();
SASSERT(h_neg == -inf_rational(rational(1,2),false));
h_neg.neg();
SASSERT(h_neg == inf_rational(rational(1,2),false));
SASSERT(r1.is_zero() && !r1.is_one() && !r1.is_neg() && r1.is_nonneg() && r1.is_nonpos() && !r1.is_pos());
SASSERT(!r3.is_zero() && r3.is_one() && !r3.is_neg() && r3.is_nonneg() && !r3.is_nonpos() && r3.is_pos());
SASSERT(floor(inf_rational(rational(1,2),false)) == rational());
SASSERT(floor(inf_rational(rational(1,2))) == rational());
SASSERT(floor(inf_rational(rational(),false)) == rational(-1));
SASSERT(floor(inf_rational(rational())) == rational());
SASSERT(floor(inf_rational(rational(),true)) == rational());
SASSERT(floor(inf_rational(rational(1),false)) == rational());
SASSERT(floor(inf_rational(rational(1))) == rational(1));
SASSERT(floor(inf_rational(rational(1),true)) == rational(1));
SASSERT(ceil(inf_rational(rational(1,2),false)) == rational(1));
SASSERT(ceil(inf_rational(rational(1,2))) == rational(1));
SASSERT(ceil(inf_rational(rational(),false)) == rational());
SASSERT(ceil(inf_rational(rational())) == rational());
SASSERT(ceil(inf_rational(rational(),true)) == rational(1));
SASSERT(ceil(inf_rational(rational(1),false)) == rational(1));
SASSERT(ceil(inf_rational(rational(1))) == rational(1));
SASSERT(ceil(inf_rational(rational(1),true)) == rational(2));
unsigned h = r9.hash();
inf_rational x(rational(1,2),true);
inf_rational y(1,2);
x.swap(y);
SASSERT (x == inf_rational(1,2));
SASSERT (y == inf_rational(rational(1,2),true));
SASSERT(inf_rational(1,2) == abs(-inf_rational(1,2)));
}

50
src/test/ini_file.cpp Normal file
View file

@ -0,0 +1,50 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
ini_file.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2007-05-10.
Revision History:
--*/
#include<sstream>
#include"ini_file.h"
#include"debug.h"
static void tst1() {
ini_params p;
int p1;
p.register_int_param("ipar1", 0, 100, p1);
int p2;
p.register_int_param("ipar2", -100, 100, p2);
bool p3;
p.register_bool_param("bpar1", p3);
bool p4;
p.register_bool_param("bpar2", p4);
unsigned p5;
p.register_unsigned_param("upar1", 0, 100, p5);
double p6;
p.register_percentage_param("ppar1", p6);
std::istringstream in("ipar1 = 100 ipar2=-30 bpar1 = true ;; COMMENT\n bpar2 = false upar1=30 ppar1 = 10");
p.read_ini_file(in);
SASSERT(p1 == 100);
SASSERT(p2 == -30);
SASSERT(p3);
SASSERT(!p4);
SASSERT(p5 == 30);
SASSERT(p6 == 0.1);
}
void tst_ini_file() {
tst1();
}

471
src/test/interval.cpp Normal file
View file

@ -0,0 +1,471 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
interval.h
Abstract:
Goodies/Templates for interval arithmetic
Author:
Leonardo de Moura (leonardo) 2012-07-19.
Revision History:
--*/
#include<cstdlib>
#include"interval_def.h"
#include"dependency.h"
#include"mpq.h"
#include"ast.h"
#include"debug.h"
template class interval_manager<im_default_config>;
typedef im_default_config::interval interval;
static void display_preamble(std::ostream & out) {
out << "(set-info :status unsat)\n";
out << "(set-option :auto-config true)\n";
out << "(set-option :numeral-as-real true)\n";
out << "(declare-const a Real)\n";
out << "(declare-const b Real)\n";
}
static void display_smt2_pos_numeral(std::ostream & out, unsynch_mpq_manager & m, mpq const & n) {
if (m.is_int(n)) {
m.display(out, n);
}
else {
out << "(/ ";
m.display(out, n.numerator());
out << " ";
m.display(out, n.denominator());
out << ")";
}
}
static void display_smt2_numeral(std::ostream & out, unsynch_mpq_manager & m, mpq const & n) {
if (m.is_neg(n)) {
scoped_mpq n_copy(m);
n_copy = n;
out << "(- ";
n_copy.neg();
display_smt2_pos_numeral(out, m, n_copy);
out << ")";
}
else {
display_smt2_pos_numeral(out, m, n);
}
}
static void display_constraint(std::ostream & out, unsynch_mpq_manager & m, char const * a, interval const & i,
bool include_lower = true, bool include_upper = true) {
out << "(and true";
if (!i.m_lower_inf && include_lower) {
out << " (" << (i.m_lower_open ? "<" : "<=") << " ";
display_smt2_numeral(out, m, i.m_lower);
out << " " << a << ")";
}
if (!i.m_upper_inf && include_upper) {
out << " (" << (i.m_upper_open ? "<" : "<=") << " " << a << " ";
display_smt2_numeral(out, m, i.m_upper);
out << ")";
}
out << ")";
}
static void assert_hyp(std::ostream & out, unsynch_mpq_manager & m, char const * a, interval const & i,
bool include_lower = true, bool include_upper = true) {
out << "(assert ";
display_constraint(out, m, a, i, include_lower, include_upper);
out << ")\n";
}
static void assert_conj(std::ostream & out, unsynch_mpq_manager & m, char const * a, interval const & i,
bool include_lower = true, bool include_upper = true) {
out << "(assert (not ";
display_constraint(out, m, a, i, include_lower, include_upper);
out << "))\n";
}
static bool mk_interval(im_default_config & cfg, interval & a, bool l_inf, bool l_open, int l_val, bool u_inf, bool u_open, int u_val) {
if (!l_inf && !u_inf) {
if (l_val > u_val)
return false;
if (l_val == u_val && (l_open || u_open))
return false;
}
if (l_inf) {
a.m_lower_open = true;
a.m_lower_inf = true;
}
else {
a.m_lower_open = l_open;
a.m_lower_inf = false;
cfg.m().set(a.m_lower, l_val);
}
if (u_inf) {
a.m_upper_open = true;
a.m_upper_inf = true;
}
else {
a.m_upper_open = u_open;
a.m_upper_inf = false;
cfg.m().set(a.m_upper, u_val);
}
return true;
}
static void mk_random_interval(im_default_config & cfg, interval & a, unsigned magnitude) {
switch (rand()%3) {
case 0:
// Neg, Neg
if (rand()%4 == 0) {
a.m_lower_open = true;
a.m_lower_inf = true;
a.m_upper_open = (rand()%2 == 0);
a.m_upper_inf = false;
cfg.m().set(a.m_upper, -static_cast<int>((rand()%magnitude)));
}
else {
a.m_upper_open = (rand()%2 == 0);
a.m_upper_inf = false;
int upper = -static_cast<int>((rand()%magnitude));
cfg.m().set(a.m_upper, upper);
a.m_lower_open = (rand()%2 == 0);
a.m_lower_inf = false;
cfg.m().set(a.m_lower, upper - static_cast<int>(rand()%magnitude) - (a.m_lower_open || a.m_upper_open ? 1 : 0));
}
break;
case 1:
// Neg, Pos
if (rand()%4 == 0) {
a.m_lower_open = true;
a.m_lower_inf = true;
}
else {
a.m_lower_open = (rand()%2 == 0);
a.m_lower_inf = false;
cfg.m().set(a.m_lower, -static_cast<int>((rand()%magnitude)) - 1);
}
if (rand()%4 == 0) {
a.m_upper_open = true;
a.m_upper_inf = true;
}
else {
a.m_upper_open = (rand()%2 == 0);
a.m_upper_inf = false;
cfg.m().set(a.m_upper, rand()%magnitude + 1);
}
break;
default:
// Neg, Neg
if (rand()%4 == 0) {
a.m_upper_open = true;
a.m_upper_inf = true;
a.m_lower_open = (rand()%2 == 0);
a.m_lower_inf = false;
cfg.m().set(a.m_lower, (rand()%magnitude));
}
else {
a.m_lower_open = (rand()%2 == 0);
a.m_lower_inf = false;
int lower = (rand()%magnitude);
cfg.m().set(a.m_lower, lower);
a.m_upper_open = (rand()%2 == 0);
a.m_upper_inf = false;
cfg.m().set(a.m_upper, lower + rand()%magnitude + (a.m_lower_open || a.m_upper_open ? 1 : 0));
}
break;
}
}
static void del_interval(im_default_config & cfg, interval & a) {
cfg.m().del(a.m_lower);
cfg.m().del(a.m_upper);
}
#define BUFFER_SZ 256
static int g_problem_id = 0;
static char g_buffer[BUFFER_SZ];
char const * get_next_file_name() {
#ifdef _WINDOWS
sprintf_s(g_buffer, BUFFER_SZ, "interval_lemma_%d.smt2", g_problem_id);
#else
sprintf(g_buffer, "interval_lemma_%d.smt2", g_problem_id);
#endif
g_problem_id++;
return g_buffer;
}
static void display_lemmas(unsynch_mpq_manager & nm, char const * result_term,
interval const & a, interval const & b, interval const & r, interval_deps const & deps) {
{
std::ofstream out(get_next_file_name());
display_preamble(out);
assert_hyp(out, nm, "a", a, dep_in_lower1(deps.m_lower_deps), dep_in_upper1(deps.m_lower_deps));
assert_hyp(out, nm, "b", b, dep_in_lower2(deps.m_lower_deps), dep_in_upper2(deps.m_lower_deps));
assert_conj(out, nm, result_term, r, true, false);
out << "(check-sat)\n";
}
{
std::ofstream out(get_next_file_name());
display_preamble(out);
assert_hyp(out, nm, "a", a, dep_in_lower1(deps.m_upper_deps), dep_in_upper1(deps.m_upper_deps));
assert_hyp(out, nm, "b", b, dep_in_lower2(deps.m_upper_deps), dep_in_upper2(deps.m_upper_deps));
assert_conj(out, nm, result_term, r, false, true);
out << "(check-sat)\n";
}
}
#define MK_BINARY(NAME, RES_TERM) \
static void tst_ ## NAME(unsigned N, unsigned magnitude) { \
unsynch_mpq_manager nm; \
im_default_config imc(nm); \
interval_manager<im_default_config> im(imc); \
interval a, b, r; \
\
for (unsigned i = 0; i < N; i++) { \
mk_random_interval(imc, a, magnitude); \
mk_random_interval(imc, b, magnitude); \
interval_deps deps; \
im.NAME(a, b, r, deps); \
\
display_lemmas(nm, RES_TERM, a, b, r, deps); \
} \
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); \
}
MK_BINARY(mul, "(* a b)");
MK_BINARY(add, "(+ a b)");
MK_BINARY(sub, "(- a b)");
static void tst_neg(unsigned N, unsigned magnitude) {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval a, b, r;
for (unsigned i = 0; i < N; i++) {
mk_random_interval(imc, a, magnitude);
interval_deps deps;
im.neg(a, r, deps);
display_lemmas(nm, "(- a)", a, b, r, deps);
}
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r);
}
static void tst_pw_2(unsigned N, unsigned magnitude) {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval a, b, r;
for (unsigned i = 0; i < N; i++) {
mk_random_interval(imc, a, magnitude);
interval_deps deps;
im.power(a, 2, r, deps);
display_lemmas(nm, "(* a a)", a, b, r, deps);
}
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r);
}
static void tst_pw_3(unsigned N, unsigned magnitude) {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval a, b, r;
for (unsigned i = 0; i < N; i++) {
mk_random_interval(imc, a, magnitude);
interval_deps deps;
im.power(a, 3, r, deps);
display_lemmas(nm, "(* a a a)", a, b, r, deps);
}
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r);
}
static void tst_root_2(unsigned N, unsigned magnitude, unsigned precision) {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval a, b, r;
scoped_mpq p(nm);
p = precision;
nm.inv(p);
unsigned i = 0;
while (i < N) {
mk_random_interval(imc, a, magnitude);
if (!im.lower_is_neg(a)) {
i++;
interval_deps deps;
im.nth_root(a, 2, p, r, deps);
display_lemmas(nm, "(^ a (/ 1.0 2.0))", a, b, r, deps);
}
}
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r);
}
static void tst_root_3(unsigned N, unsigned magnitude, unsigned precision) {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval a, b, r;
scoped_mpq p(nm);
p = precision;
nm.inv(p);
unsigned i = 0;
while (i < N) {
mk_random_interval(imc, a, magnitude);
i++;
interval_deps deps;
im.nth_root(a, 3, p, r, deps);
display_lemmas(nm, "(^ a (/ 1.0 3.0))", a, b, r, deps);
}
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r);
}
static void tst_inv(unsigned N, unsigned magnitude) {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval a, b, r;
for (unsigned i = 0; i < N; i++) {
while (true) {
mk_random_interval(imc, a, magnitude);
if (!im.contains_zero(a))
break;
}
interval_deps deps;
im.inv(a, r, deps);
display_lemmas(nm, "(/ 1 a)", a, b, r, deps);
}
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r);
}
static void tst_div(unsigned N, unsigned magnitude) {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval a, b, r;
for (unsigned i = 0; i < N; i++) {
mk_random_interval(imc, a, magnitude);
while (true) {
mk_random_interval(imc, b, magnitude);
if (!im.contains_zero(b))
break;
}
interval_deps deps;
im.div(a, b, r, deps);
display_lemmas(nm, "(/ a b)", a, b, r, deps);
}
del_interval(imc, a); del_interval(imc, b); del_interval(imc, r);
}
#include"im_float_config.h"
static void tst_float() {
unsynch_mpq_manager qm;
mpf_manager fm;
im_float_config<mpf_manager> ifc(fm);
interval_manager<im_float_config<mpf_manager> > im(ifc);
im_float_config<mpf_manager>::interval a, b, c;
scoped_mpq minus_one_third(qm), one_third(qm), two_third(qm), minus_two_third(qm);
qm.set(minus_one_third, -1, 3);
qm.set(one_third, 1, 3);
qm.set(two_third, 2, 3);
qm.set(minus_two_third, -2, 3);
ifc.round_to_minus_inf();
ifc.m().set(a.m_lower, minus_one_third);
ifc.round_to_plus_inf();
ifc.m().set(a.m_upper, two_third);
ifc.round_to_minus_inf();
ifc.m().set(b.m_lower, minus_two_third);
ifc.round_to_plus_inf();
ifc.m().set(b.m_upper, one_third);
im.display(std::cout, a);
std::cout << "\n";
im.display(std::cout, b);
std::cout << "\n";
interval_deps deps;
im.add(a, b, c, deps);
im.display(std::cout, c);
std::cout << "\n";
del_f_interval(ifc, a); del_f_interval(ifc, b); del_f_interval(ifc, c);
}
void tst_pi() {
unsynch_mpq_manager nm;
im_default_config imc(nm);
interval_manager<im_default_config> im(imc);
interval r;
for (unsigned i = 0; i < 8; i++) {
im.pi(i, r);
nm.display_decimal(std::cout, im.lower(r), 32); std::cout << " ";
nm.display_decimal(std::cout, im.upper(r), 32); std::cout << "\n";
SASSERT(nm.lt(im.lower(r), im.upper(r)));
}
del_interval(imc, r);
}
static void tst_pi_float() {
std::cout << "pi float...\n";
unsynch_mpq_manager qm;
mpf_manager fm;
im_float_config<mpf_manager> ifc(fm, 22, 106);
interval_manager<im_float_config<mpf_manager> > im(ifc);
scoped_mpq q(qm);
im_float_config<mpf_manager>::interval r;
for (unsigned i = 0; i < 8; i++) {
im.pi(i, r);
fm.to_rational(im.lower(r), q);
qm.display_decimal(std::cout, q, 32); std::cout << " ";
fm.to_rational(im.upper(r), q);
qm.display_decimal(std::cout, q, 32); std::cout << "\n";
}
del_f_interval(ifc, r);
}
#define NUM_TESTS 1000
#define SMALL_MAG 3
#define MID_MAG 10
void tst_interval() {
// enable_trace("interval_bug");
// tst_float();
// return;
// enable_trace("interval_nth_root");
// tst_pi();
// tst_pi_float();
tst_root_2(NUM_TESTS, MID_MAG, 100);
tst_root_3(NUM_TESTS, MID_MAG, 100);
tst_div(NUM_TESTS, SMALL_MAG);
tst_inv(NUM_TESTS, SMALL_MAG);
tst_pw_2(NUM_TESTS, SMALL_MAG);
tst_pw_3(NUM_TESTS, SMALL_MAG);
tst_neg(NUM_TESTS, SMALL_MAG);
tst_sub(NUM_TESTS, SMALL_MAG);
tst_mul(NUM_TESTS, SMALL_MAG);
tst_add(NUM_TESTS, SMALL_MAG);
}

View file

@ -0,0 +1,716 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
interval_skip_list.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-10-05.
Revision History:
--*/
#include"interval_skip_list.h"
#include"map.h"
#include"vector.h"
typedef sl_manager_base<unsigned> slist_manager;
template class interval_skip_list<unsigned_interval_skip_list_traits<unsigned, default_eq<unsigned>, 4, 4, false, slist_manager> >;
typedef interval_skip_list<unsigned_interval_skip_list_traits<unsigned, default_eq<unsigned>, 4, 4, false, slist_manager> > slist;
typedef u_map<unsigned> u2u_map;
typedef unsigned_isp_set<4, 4, slist_manager> uset;
static void tst1() {
slist_manager m;
slist l(m);
SASSERT(l.check_invariant());
SASSERT(l.empty());
// l.display_physical(std::cout);
l.insert(m, 20, 30, 5);
l.insert(m, 31, 32, 5);
l.insert(m, 18, 19, 5);
// l.display_physical(std::cout);
SASSERT(l.check_invariant());
l.insert(m, 10, 15, 8);
SASSERT(l.check_invariant());
// l.display_physical(std::cout);
l.insert(m, 5, 25, 7);
SASSERT(l.check_invariant());
// l.display_physical(std::cout);
l.insert(m, 23, 27, 5);
// l.display_physical(std::cout);
SASSERT(l.check_invariant());
l.deallocate(m);
}
static void tst2() {
slist_manager(m);
slist l(m);
for(unsigned i = 0; i < 50; i++) {
l.insert(m,i,i,i*10);
}
// l.display_physical(std::cout);
SASSERT(l.check_invariant());
for (unsigned i = 0; i < 25; i++) {
l.insert(m,i*2,i*2+1,i*20+1);
}
// l.display_physical(std::cout);
SASSERT(l.check_invariant());
for (unsigned i = 0; i < 15; i++) {
l.insert(m,i*3,i*3+2,i*30+1);
}
SASSERT(l.check_invariant());
// l.display_physical(std::cout);
// l.compress(4);
// l.display_physical(std::cout);
SASSERT(l.check_invariant());
l.deallocate(m);
}
static bool check_interval(slist & l, unsigned k1, unsigned k2, unsigned val) {
for (unsigned i = k1; i <= k2; i++) {
DEBUG_CODE({
unsigned _val;
SASSERT(l.contains(i, _val) && _val == val);
});
}
return true;
}
static bool check_no_interval(slist & l, unsigned k1, unsigned k2) {
for (unsigned i = k1; i <= k2; i++) {
DEBUG_CODE({
unsigned _val;
SASSERT(!l.contains(i, _val));
});
}
return true;
}
static void tst4() {
slist_manager m;
slist l(m);
l.insert(m, 1, 10, 0);
l.insert(m, 2, 5, 1);
SASSERT(check_no_interval(l,0,0));
SASSERT(check_interval(l,1,1,0));
SASSERT(check_interval(l,2,5,1));
SASSERT(check_interval(l,6,10,0));
SASSERT(check_no_interval(l,11,20));
SASSERT(l.check_invariant());
l.deallocate(m);
}
static void tst5() {
slist_manager m;
slist l(m);
l.insert(m, 1, 5, 0);
l.insert(m, 8, 100, 1);
l.insert(m, 8, 20, 1);
SASSERT(check_no_interval(l,0,0));
SASSERT(check_interval(l,1,5,0));
SASSERT(check_no_interval(l,6,7));
SASSERT(check_interval(l,8,100,1));
SASSERT(check_no_interval(l,101,200));
SASSERT(l.check_invariant());
l.deallocate(m);
}
static void tst6() {
slist_manager m;
slist l(m);
l.insert(m, 1, 5, 0);
l.insert(m, 8, 100, 1);
l.insert(m, 3, 20, 1);
SASSERT(check_no_interval(l,0,0));
SASSERT(check_interval(l,1,2,0));
SASSERT(check_interval(l,3,100,1));
SASSERT(check_no_interval(l,101,200));
SASSERT(l.check_invariant());
l.deallocate(m);
}
static void tst7() {
slist_manager m;
slist l(m);
l.insert(m, 1, 5, 0);
l.insert(m, 8, 100, 1);
l.insert(m, 2, 12, 0);
SASSERT(check_no_interval(l,0,0));
SASSERT(check_interval(l,1,12,0));
SASSERT(check_interval(l,13,100,1));
SASSERT(check_no_interval(l,101,200));
SASSERT(l.check_invariant());
l.deallocate(m);
}
static void tst8() {
slist_manager m;
slist l(m);
for (unsigned i = 0; i < 100; i++) {
l.insert(m, 10*i, 10*i+5, i);
}
SASSERT(!l.empty());
l.insert(m, 0, 10000, 0);
SASSERT(!l.has_more_than_k_entries(1));
// l.display_physical(std::cout);
l.deallocate(m);
}
struct for_each_contains {
slist const & m_other;
for_each_contains(slist const & other):m_other(other) {}
bool operator()(unsigned b, unsigned e, unsigned v) {
for (unsigned i = b; i <= e; i++) {
DEBUG_CODE({
unsigned _v;
SASSERT(m_other.contains(i, _v));
SASSERT(v == _v);
});
}
return true;
}
};
static void random_tsts(unsigned num_ops, unsigned max_key, unsigned max_val, unsigned max_interval_size) {
slist_manager m;
slist m1(m);
u2u_map m2;
for (unsigned i = 0; i < num_ops; i++) {
SASSERT(m1.check_invariant());
TRACE("interval_skip_list", tout << "i: " << i << "\n"; m1.display_physical(tout););
// std::cout << i << std::endl;
int op = rand()%8;
if (op < 3) {
unsigned bg = rand() % max_key;
unsigned sz = rand() % max_interval_size;
if (sz == 0) sz = 1;
unsigned val = rand() % max_val;
m1.insert(m, bg, bg+sz, val);
for (unsigned j = bg; j <= bg+sz; j++) {
DEBUG_CODE({
unsigned _val;
SASSERT(m1.contains(j, _val));
CTRACE("interval_skip_list", val != _val, tout << "i: " << i << ", j: " << j << ", val: " << val << ", _val: " << _val << "\n"; m1.display_physical(tout););
SASSERT(val == _val);
TRACE("interval_skip_list", tout << "[insert]: " << j << " -> " << val << "\n";);
});
m2.insert(j, val);
}
}
else if (op < 4) {
unsigned bg = rand() % max_key;
unsigned sz = rand() % max_interval_size;
if (sz == 0) sz = 1;
m1.erase(m, bg, bg+sz);
for (unsigned i = bg; i <= bg+sz; i++) {
m2.erase(i);
}
}
else if (op < 5) {
slist m1_copy(m);
m1_copy.copy(m, m1);
for_each_contains proc1(m1);
for_each_contains proc2(m1_copy);
m1.for_each(proc2);
m1_copy.for_each(proc1);
// m1.display_physical(std::cout);
// std::cout << "COPY===>\n";
// m1_copy->display_physical(std::cout);
m1_copy.deallocate(m);
}
else if (op < 6) {
m1.compress(m, 3);
}
else {
SASSERT(m1.check_invariant());
u2u_map::iterator it = m2.begin();
u2u_map::iterator end = m2.end();
for (; it != end; ++it) {
DEBUG_CODE({
unsigned _val;
CTRACE("interval_skip_list", !m1.contains(it->m_key, _val),
tout << it->m_key << " -> " << it->m_value << "\n";
m1.display_physical(tout););
SASSERT(m1.contains(it->m_key, _val));
SASSERT(it->m_value == _val);
});
}
}
}
// m1.display_physical(std::cout);
// m1.compress(4);
// m1.display_physical(std::cout);
m1.deallocate(m);
}
static void tst9() {
slist_manager m;
slist l(m);
l.insert(m,10,10,1);
l.insert(m,9,9,0);
l.insert(m,8,8,2);
l.insert(m,7,7,3);
l.insert(m,6,8,3);
SASSERT(!l.has_more_than_k_buckets(1));
SASSERT(check_no_interval(l,0,5));
SASSERT(check_interval(l,6,8,3));
SASSERT(check_interval(l,9,9,0));
SASSERT(check_interval(l,10,10,1));
SASSERT(check_no_interval(l,11,20));
l.deallocate(m);
}
static void tst10() {
slist_manager m;
slist l(m);
l.insert(m,10,10,1);
l.insert(m,13,16,2);
l.insert(m,17,28,3);
l.remove(m,12,19);
SASSERT(l.check_invariant());
SASSERT(check_no_interval(l,0,9));
SASSERT(check_interval(l,10,10,1));
SASSERT(check_no_interval(l,12,19));
SASSERT(check_interval(l,20,28,3));
SASSERT(check_no_interval(l,29,100));
l.remove(m,10,11);
SASSERT(l.check_invariant());
SASSERT(check_no_interval(l,0,19));
SASSERT(check_interval(l,20,28,3));
SASSERT(check_no_interval(l,29,100));
l.remove(m,0,1000);
SASSERT(l.empty());
SASSERT(l.check_invariant());
l.deallocate(m);
}
static void tst11() {
slist_manager m;
slist l(m);
l.insert(m,11,20,1);
l.insert(m,21,30,2);
l.insert(m,31,40,3);
l.insert(m,41,50,4);
l.insert(m,51,60,5);
l.compress(m,4);
SASSERT(check_no_interval(l,0,10));
SASSERT(check_interval(l,11,20,1));
SASSERT(check_interval(l,21,30,2));
SASSERT(check_interval(l,31,40,3));
SASSERT(check_interval(l,41,50,4));
SASSERT(check_interval(l,51,60,5));
SASSERT(check_no_interval(l,61,100));
SASSERT(l.check_invariant());
l.remove(m, 25, 26);
SASSERT(check_no_interval(l,0,10));
SASSERT(check_interval(l,11,20,1));
SASSERT(check_interval(l,21,24,2));
SASSERT(check_no_interval(l,25,26));
SASSERT(check_interval(l,27,30,2));
SASSERT(check_interval(l,31,40,3));
SASSERT(check_interval(l,41,50,4));
SASSERT(check_interval(l,51,60,5));
SASSERT(check_no_interval(l,61,100));
SASSERT(l.check_invariant());
l.remove(m, 44,48);
SASSERT(check_no_interval(l,0,10));
SASSERT(check_interval(l,11,20,1));
SASSERT(check_interval(l,21,24,2));
SASSERT(check_no_interval(l,25,26));
SASSERT(check_interval(l,27,30,2));
SASSERT(check_interval(l,31,40,3));
SASSERT(check_interval(l,41,43,4));
SASSERT(check_no_interval(l,44,48));
SASSERT(check_interval(l,49,50,4));
SASSERT(check_interval(l,51,60,5));
SASSERT(check_no_interval(l,61,100));
SASSERT(l.check_invariant());
l.remove(m, 22,24);
SASSERT(check_no_interval(l,0,10));
SASSERT(check_interval(l,11,20,1));
SASSERT(check_interval(l,21,21,2));
SASSERT(check_no_interval(l,22,26));
SASSERT(check_interval(l,27,30,2));
SASSERT(check_interval(l,31,40,3));
SASSERT(check_interval(l,41,43,4));
SASSERT(check_no_interval(l,44,48));
SASSERT(check_interval(l,49,50,4));
SASSERT(check_interval(l,51,60,5));
SASSERT(check_no_interval(l,61,100));
SASSERT(l.check_invariant());
l.remove(m, 42,49);
SASSERT(check_no_interval(l,0,10));
SASSERT(check_interval(l,11,20,1));
SASSERT(check_interval(l,21,21,2));
SASSERT(check_no_interval(l,22,26));
SASSERT(check_interval(l,27,30,2));
SASSERT(check_interval(l,31,40,3));
SASSERT(check_interval(l,41,41,4));
SASSERT(check_no_interval(l,42,49));
SASSERT(check_interval(l,50,50,4));
SASSERT(check_interval(l,51,60,5));
SASSERT(check_no_interval(l,61,100));
SASSERT(l.check_invariant());
// l.display_physical(std::cout);
l.deallocate(m);
}
static void tst12() {
slist_manager m;
slist l(m);
l.insert(m,10,10,0);
l.insert(m,9,9,0);
SASSERT(l.check_invariant());
l.insert(m,8,9,1);
SASSERT(l.check_invariant());
l.insert(m,7,7,2);
SASSERT(l.check_invariant());
l.insert(m,6,6,3);
SASSERT(l.check_invariant());
l.insert(m,4,5,2);
SASSERT(l.check_invariant());
l.insert(m,3,9,0);
// l.display_physical(std::cout);
l.deallocate(m);
}
static void tst13() {
slist_manager m;
uset s(m);
s.insert(m, 10, 30);
s.insert(m, 32, 40);
s.display(std::cout);
std::cout << ", mem: " << s.memory() << "\n";
s.deallocate(m);
}
struct obj {
unsigned m_val;
unsigned m_ref_count;
void inc_ref() {
m_ref_count++;
}
void dec_ref() {
SASSERT(m_ref_count > 0);
m_ref_count--;
if (m_ref_count == 0)
dealloc(this);
}
obj(unsigned v):m_val(v), m_ref_count(0) {
}
};
std::ostream & operator<<(std::ostream & out, obj * o) {
out << o->m_val << "{" << o->m_ref_count << "}";
return out;
}
struct obj_slist_manager : public sl_manager_base<obj*> {
void inc_ref_eh(obj * v) {
v->inc_ref();
}
void dec_ref_eh(obj * v) {
v->dec_ref();
}
};
struct inc_ref_functor {
unsigned_vector & refs;
inc_ref_functor(unsigned_vector & r):refs(r) {}
bool operator()(unsigned b, unsigned e, obj * val) {
refs[val->m_val]++;
return true;
}
};
template class interval_skip_list<unsigned_interval_skip_list_traits<obj*, default_eq<obj*>, 16, 16, true, obj_slist_manager> >;
typedef interval_skip_list<unsigned_interval_skip_list_traits<obj*, default_eq<obj*>, 16, 16, true, obj_slist_manager> > obj_slist;
void random_tsts_ref(unsigned num_ops, unsigned num_objs, unsigned max_key, unsigned max_interval_size) {
obj_slist_manager m;
obj_slist l(m);
ptr_vector<obj> objs;
unsigned_vector refs;
for (unsigned i = 0; i < num_objs; i++) {
objs.push_back(alloc(obj, i));
objs.back()->inc_ref();
refs.push_back(1);
}
for (unsigned i = 0; i < num_ops; i++) {
SASSERT(l.check_invariant());
TRACE("interval_skip_list", tout << "i: " << i << "\n"; l.display_physical(tout); tout << "\n";);
int op = rand()%5;
if (op < 3) {
unsigned bg = rand() % max_key;
unsigned sz = rand() % max_interval_size;
if (sz == 0) sz = 1;
unsigned val = rand() % num_objs;
TRACE("interval_skip_list", tout << "[inserting]: [" << bg << ", " << (bg+sz) << "] -> " << objs[val] << "\n";);
l.insert(m, bg, bg+sz, objs[val]);
SASSERT(objs[val]->m_ref_count > 1);
}
else if (op < 4) {
unsigned bg = rand() % max_key;
unsigned sz = rand() % max_interval_size;
if (sz == 0) sz = 1;
TRACE("interval_skip_list", tout << "[erasing]: [" << bg << ", " << (bg+sz) << "]\n";);
l.erase(m, bg, bg+sz);
}
else if (op < 5) {
obj_slist l_copy(m);
l_copy.copy(m, l);
TRACE("interval_skip_list", tout << "[copying]\n";);
l_copy.deallocate(m);
TRACE("interval_skip_list", tout << "[deleting copy]\n";);
}
else {
TRACE("interval_skip_list", tout << "[compressing]\n";);
l.compress(m, 3);
}
// check ref-counts
inc_ref_functor proc(refs);
l.for_each(proc);
for (unsigned i = 0; i < num_objs; i++) {
CTRACE("interval_skip_list", refs[i] != objs[i]->m_ref_count,
tout << "i: " << i << ", objs[i]: " << objs[i] << ", refs[i]: " << refs[i] << "\n\n";
l.display_physical(tout););
SASSERT(refs[i] == objs[i]->m_ref_count);
refs[i] = 1;
}
}
l.deallocate(m);
for (unsigned i = 0; i < num_objs; i++) {
SASSERT(objs[i]->m_ref_count == 1);
objs[i]->dec_ref();
}
}
void tst_ref() {
obj_slist_manager m;
obj_slist l(m);
for (unsigned i = 0; i < 30; i++) {
obj * n = alloc(obj, i);
l.insert(m, i*10, i*10+3, n);
// l.display_physical(std::cout);
// std::cout << "memory: " << l.memory() << "\n";
}
l.deallocate(m);
}
void tst_push_back_aux(slist::push_back_proc & push_back, unsigned num_ops, unsigned max_int, unsigned max_sep, unsigned max_val) {
unsigned prev_key;
if (push_back.empty())
prev_key = 0;
else
prev_key = push_back.last_key();
for (unsigned i = 0; i < num_ops; i++) {
unsigned next_key = prev_key + 1;
next_key += (rand() % max_sep);
unsigned sz = rand() % max_int;
if (sz == 0) sz = 1;
unsigned val = rand() % max_val;
push_back(next_key, next_key+sz, val);
SASSERT(!push_back.empty());
prev_key = push_back.last_key();
}
}
void tst_push_back1(unsigned num_ops, unsigned max_int, unsigned max_sep, unsigned max_val) {
slist_manager m;
slist l(m);
slist::push_back_proc push_back(m, l);
tst_push_back_aux(push_back, num_ops, max_int, max_sep, max_val);
// l.display_physical(std::cout);
SASSERT(l.check_invariant());
l.deallocate(m);
}
void tst_push_back2(unsigned num_ops, unsigned max_int, unsigned max_sep, unsigned max_val) {
slist_manager m;
slist l(m);
// insert some random values before creating push_back functor
for (unsigned i = 0; i < num_ops; i++) {
unsigned next_key = rand() % (num_ops * max_int/2);
unsigned sz = rand() % max_int;
if (sz == 0) sz = 1;
unsigned val = rand() % max_val;
l.insert(m, next_key, next_key+sz, val);
}
slist::push_back_proc push_back(m, l);
tst_push_back_aux(push_back, num_ops, max_int, max_sep, max_val);
// l.display_physical(std::cout);
SASSERT(l.check_invariant());
l.deallocate(m);
}
void tst_find_geq1() {
slist_manager m;
slist l(m);
l.insert(m, 10, 20, 4);
l.insert(m, 23, 30, 3);
l.insert(m, 40, 45, 10);
l.insert(m, 50, 66, 1);
l.insert(m, 100, 120, 21);
l.insert(m, 140, 200, 2);
slist::iterator it = l.find_geq(22);
SASSERT(it->begin_key() == 23);
it = l.find_geq(42);
SASSERT(it->begin_key() == 40);
it.move_to(130);
SASSERT(it->begin_key() == 140);
it.move_to(400);
SASSERT(it == l.end());
it = l.find_geq(300);
SASSERT(it == l.end());
it = l.find_geq(9);
SASSERT(it->begin_key() == 10);
it.move_to(105);
SASSERT(it->begin_key() == 100);
it = l.find_geq(15);
SASSERT(it->begin_key() == 10);
it.move_to(31);
SASSERT(it->begin_key() == 40);
it = l.find_geq(22);
SASSERT(it->begin_key() == 23);
it = l.find_geq(124);
SASSERT(it->begin_key() == 140);
it = l.find_geq(102);
SASSERT(it->begin_key() == 100);
// l.display_physical(std::cout);
l.deallocate(m);
}
struct add42 {
unsigned operator()(unsigned v) { return v + 42; }
};
void tst_move_to() {
slist_manager m;
slist l(m);
for (unsigned i = 0; i < 500; i++)
l.insert(m, i*10, i*10 + 5, i);
l.compress(m, 4);
slist::iterator it = l.find_geq(137);
SASSERT(it->begin_key() == 140);
it.move_to(947);
SASSERT(it->begin_key() == 950);
it.move_to(4955);
SASSERT(it->begin_key() == 4950);
it.move_to(4955);
SASSERT(it->begin_key() == 4950);
it.move_to(4956);
SASSERT(it->begin_key() == 4960);
it.move_to(4982);
SASSERT(it->begin_key() == 4980);
it.move_to(4987);
SASSERT(it->begin_key() == 4990);
it.move_to(4990);
SASSERT(it->begin_key() == 4990);
it.move_to(4995);
SASSERT(it->begin_key() == 4990);
it.move_to(4996);
SASSERT(it.at_end());
// l.display_physical(std::cout);
add42 f;
// l.display(std::cout); std::cout << "\n";
l.update_values(m, f);
// l.display(std::cout); std::cout << "\n";
l.deallocate(m);
}
static void tst_ext_iterator() {
slist_manager m;
slist l(m);
for (unsigned i = 0; i < 20; i++)
l.insert(m, i*10, i*10 + 5, i);
l.compress(m, 4);
l.display_physical(std::cout); std::cout << "\n";
slist::ext_iterator it;
slist::ext_iterator end;
SASSERT(end.at_end());
l.move_geq(it, 92);
SASSERT(!it.at_end());
SASSERT(it->begin_key() == 90);
it++;
SASSERT(it->begin_key() == 100);
it.erase(m);
SASSERT(it->begin_key() == 110);
it.erase(m);
SASSERT(it->begin_key() == 120);
it.erase(m);
it.erase(m);
it.erase(m);
it.erase(m);
SASSERT(it->begin_key() == 160);
SASSERT(l.check_invariant());
l.display_physical(std::cout); std::cout << "\n";
l.move_geq(it, 0);
SASSERT(it->begin_key() == 0);
it.erase(m);
SASSERT(it->begin_key() == 10);
it.erase(m);
SASSERT(it->begin_key() == 20);
it.erase(m);
SASSERT(it->begin_key() == 30);
it.erase(m);
SASSERT(it->begin_key() == 40);
it.erase(m);
SASSERT(it->begin_key() == 50);
l.display_physical(std::cout); std::cout << "\n";
l.deallocate(m);
}
void tst_interval_skip_list() {
std::cout << "unsigned map stats:\n";
slist::display_size_info(std::cout);
std::cout << "\nunsigned set stats:\n";
uset::display_size_info(std::cout);
std::cout << "\n";
tst1();
// enable_trace("interval_skip_list_insert_bug");
// enable_trace("interval_skip_list_bug");
// enable_trace("del_entries_upto_bug");
// enable_trace("insert_inside_bug");
// enable_trace("insert_at_bug");
tst2();
tst4();
tst5();
tst6();
tst7();
tst8();
tst9();
tst10();
tst11();
tst12();
tst13();
tst_find_geq1();
tst_move_to();
tst_push_back1(300, 4, 2, 10);
tst_push_back2(300, 4, 2, 10);
random_tsts(1000, 20, 20, 5);
random_tsts_ref(1000, 20, 20, 5);
tst_ref();
tst_ext_iterator();
}

44
src/test/list.cpp Normal file
View file

@ -0,0 +1,44 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
list.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2007-07-10.
Revision History:
--*/
#include"trace.h"
#include"util.h"
#include"region.h"
#include"list.h"
static void tst1() {
region r;
list<int> * l1 = new (r) list<int>(10);
list<int> * l2 = new (r) list<int>(20, l1);
list<int> * l3 = new (r) list<int>(30);
list<int> * l4 = new (r) list<int>(40, l3);
SASSERT(append(r, l1, static_cast<list<int> *>(0)) == l1);
SASSERT(append(r, l2, static_cast<list<int> *>(0)) == l2);
SASSERT(append(r, static_cast<list<int> *>(0), l2) == l2);
SASSERT(append(r, static_cast<list<int> *>(0), static_cast<list<int> *>(0)) == 0);
TRACE("list", display(tout, l2->begin(), l2->end()); tout << "\n";);
list<int> * l5 = append(r, l4, l2);
TRACE("list", display(tout, l5->begin(), l5->end()); tout << "\n";);
list<int> * l6 = append(r, l5, l5);
TRACE("list", display(tout, l6->begin(), l6->end()); tout << "\n";);
}
void tst_list() {
tst1();
}

232
src/test/main.cpp Normal file
View file

@ -0,0 +1,232 @@
#include<iostream>
#include<time.h>
#include<string>
#include<cstring>
#include"util.h"
#include"trace.h"
#include"debug.h"
#include"timeit.h"
#include"warning.h"
#include "memory_manager.h"
//
// Unit tests fail by asserting.
// If they return, we assume the unit test succeeds
// and print "PASS" to indicate success.
//
#define TST(MODULE) { \
std::string s("test "); \
s += #MODULE; \
void tst_##MODULE(); \
if (do_display_usage) \
std::cout << #MODULE << "\n"; \
for (int i = 0; i < argc; i++) \
if (strcmp(argv[i], #MODULE) == 0) { \
enable_trace(#MODULE); \
enable_debug(#MODULE); \
timeit timeit(true, s.c_str()); \
tst_##MODULE(); \
std::cout << "PASS" << std::endl; \
} \
}
#define TST_ARGV(MODULE) { \
std::string s("test "); \
s += #MODULE; \
void tst_##MODULE(char** argv, int argc, int& i); \
if (do_display_usage) \
std::cout << #MODULE << "\n"; \
for (int i = 0; i < argc; i++) \
if (strcmp(argv[i], #MODULE) == 0) { \
enable_trace(#MODULE); \
enable_debug(#MODULE); \
timeit timeit(true, s.c_str()); \
tst_##MODULE(argv, argc, i); \
std::cout << "PASS" << std::endl; \
} \
}
void error(const char * msg) {
std::cerr << "Error: " << msg << "\n";
std::cerr << "For usage information: test /h\n";
exit(1);
}
void display_usage() {
std::cout << "Z3 unit tests [version 1.0]. (C) Copyright 2006 Microsoft Corp.\n";
std::cout << "Usage: test [options] [module names]\n";
std::cout << "\nMisc.:\n";
std::cout << " /h prints this message.\n";
std::cout << " /v:level be verbose, where <level> is the verbosity level.\n";
std::cout << " /w enable warning messages.\n";
#if defined(Z3DEBUG) || defined(_TRACE)
std::cout << "\nDebugging support:\n";
#endif
#ifdef _TRACE
std::cout << " /tr:tag enable trace messages tagged with <tag>.\n";
#endif
#ifdef Z3DEBUG
std::cout << " /dbg:tag enable assertions tagged with <tag>.\n";
#endif
}
void parse_cmd_line_args(int argc, char ** argv, bool& do_display_usage) {
int i = 1;
while (i < argc) {
char * arg = argv[i];
if (arg[0] == '-' || arg[0] == '/') {
char * opt_name = arg + 1;
char * opt_arg = 0;
char * colon = strchr(arg, ':');
if (colon) {
opt_arg = colon + 1;
*colon = 0;
}
if (strcmp(opt_name, "h") == 0 ||
strcmp(opt_name, "?") == 0) {
display_usage();
do_display_usage = true;
return;
}
else if (strcmp(opt_name, "v") == 0) {
if (!opt_arg)
error("option argument (/v:level) is missing.");
long lvl = strtol(opt_arg, 0, 10);
set_verbosity_level(lvl);
}
else if (strcmp(opt_name, "w") == 0) {
enable_warning_messages(true);
}
#ifdef _TRACE
else if (strcmp(opt_name, "tr") == 0) {
if (!opt_arg)
error("option argument (/tr:tag) is missing.");
enable_trace(opt_arg);
}
#endif
#ifdef Z3DEBUG
else if (strcmp(opt_name, "dbg") == 0) {
if (!opt_arg)
error("option argument (/dbg:tag) is missing.");
enable_debug(opt_arg);
}
#endif
}
i++;
}
}
int main(int argc, char ** argv) {
memory::initialize(0);
bool do_display_usage = false;
parse_cmd_line_args(argc, argv, do_display_usage);
TST_ARGV(grobner);
TST(random);
TST(vector);
TST(symbol_table);
TST(region);
TST(symbol);
TST(heap);
TST(hashtable);
TST_ARGV(smtparser);
TST(rational);
TST(inf_rational);
TST(ast);
TST(optional);
TST(bit_vector);
TST(ast_pp);
TST(ast_smt_pp);
TST_ARGV(expr_delta);
TST(string_buffer);
TST(map);
TST(diff_logic);
TST(uint_set);
TST_ARGV(expr_rand);
TST(expr_context_simplifier);
TST(ini_file);
TST(expr_pattern_match);
TST(list);
TST(small_object_allocator);
TST(timeout);
TST(splay_tree);
TST(fvi);
TST(proof_checker);
TST(simplifier);
TST(bv_simplifier_plugin);
TST(bit_blaster);
TST(var_subst);
TST(simple_parser);
TST(symmetry);
TST_ARGV(symmetry_parse);
TST_ARGV(symmetry_prove);
TST(api);
TST(old_interval);
TST(interval_skip_list);
TST(no_overflow);
TST(memory);
TST(parallel);
TST(get_implied_equalities);
TST(arith_simplifier_plugin);
TST(quant_elim);
TST(matcher);
TST(datalog_parser);
TST(dl_rule_set);
TST_ARGV(datalog_parser_file);
TST(object_allocator);
TST(mpz);
TST(mpq);
TST(mpf);
TST(total_order);
TST(dl_table);
TST(dl_context);
TST(dl_smt_relation);
TST(dl_query);
TST(dl_util);
TST(dl_product_relation);
TST(dl_relation);
TST(imdd);
TST(array_property_expander);
TST(parray);
TST(stack);
TST(escaped);
TST(buffer);
TST(chashtable);
TST(ex);
TST(nlarith_util);
TST(api_bug);
TST(arith_rewriter);
TST(check_assumptions);
TST(smt_context);
TST(theory_dl);
TST(model_retrieval);
TST(factor_rewriter);
TST(smt2print_parse);
TST(substitution);
TST(polynomial);
TST(upolynomial);
TST(algebraic);
TST(polynomial_factorization);
TST(prime_generator);
TST(permutation);
TST(nlsat);
TST(qe_defs);
TST(ext_numeral);
TST(interval);
TST(quant_solve);
TST(f2n);
TST(hwf);
TST(trigo);
TST(bits);
TST(mpbq);
TST(mpfx);
TST(mpff);
TST(horn_subsume_model_converter);
TST(model2expr);
}
void initialize_mam() {}
void finalize_mam() {}

45
src/test/map.cpp Normal file
View file

@ -0,0 +1,45 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_map.cpp
Abstract:
Test simple mapping.
Author:
Leonardo de Moura (leonardo) 2006-10-14.
Revision History:
--*/
#include"map.h"
#include"str_hashtable.h"
static void tst1() {
map<char *, int, str_hash_proc, str_eq_proc> str2int;
str2int.insert("foo", 35);
SASSERT(str2int.contains("foo"));
SASSERT(str2int.find_iterator("foo") != str2int.end());
SASSERT((*(str2int.find_iterator("foo"))).m_value == 35);
SASSERT(str2int.size() == 1);
str2int.insert("boo", 32);
SASSERT(str2int.contains("foo"));
SASSERT(str2int.find_iterator("foo") != str2int.end());
SASSERT((*(str2int.find_iterator("foo"))).m_value == 35);
SASSERT(str2int.contains("boo"));
SASSERT(str2int.find_iterator("boo") != str2int.end());
SASSERT((*(str2int.find_iterator("boo"))).m_value == 32);
SASSERT(str2int.size() == 2);
str2int.remove("boo");
SASSERT(str2int.size() == 1);
SASSERT(!str2int.contains("boo"));
SASSERT(str2int.contains("foo"));
}
void tst_map() {
tst1();
}

113
src/test/matcher.cpp Normal file
View file

@ -0,0 +1,113 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
matcher.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-04-16.
Revision History:
--*/
#ifdef _WINDOWS
#include"matcher.h"
#include"ast_pp.h"
void tst_match(ast_manager & m, app * t, app * i) {
substitution s(m);
s.reserve(2, 10); // reserving a big number of variables to be safe.
matcher match(m);
std::cout << "Is " << mk_pp(i, m) << " an instance of " << mk_pp(t, m) << "\n";
if (match(t, i, s)) {
std::cout << "yes\n";
s.display(std::cout);
}
else {
std::cout << "no\n";
}
s.reset();
if (t->get_decl() == i->get_decl()) {
// trying to match the arguments of t and i
std::cout << "Are the arguments of " << mk_pp(i, m) << " an instance of the arguments of " << mk_pp(t, m) << "\n";
unsigned num_args = t->get_num_args();
unsigned j;
for (j = 0; j < num_args; j++) {
if (!match(t->get_arg(j), i->get_arg(j), s))
break;
}
if (j == num_args) {
std::cout << "yes\n";
s.display(std::cout);
// create some dummy term to test for applying the substitution.
sort_ref S( m.mk_sort(symbol("S")), m);
sort * domain[3] = {S, S, S};
func_decl_ref r( m.mk_func_decl(symbol("r"), 3, domain, S), m);
expr_ref x1( m.mk_var(0, S), m);
expr_ref x2( m.mk_var(1, S), m);
expr_ref x3( m.mk_var(2, S), m);
app_ref rxyzw( m.mk_app(r, x1.get(), x2.get(), x3.get()), m);
expr_ref result(m);
unsigned deltas[2] = {0,0};
s.apply(2, deltas, expr_offset(rxyzw, 0), result);
std::cout << "applying substitution to\n" << mk_pp(rxyzw,m) << "\nresult:\n" << mk_pp(result,m) << "\n";
}
else {
std::cout << "no\n";
}
}
std::cout << "\n";
}
void tst1() {
ast_manager m;
sort_ref s( m.mk_sort(symbol("S")), m);
func_decl_ref g( m.mk_func_decl(symbol("g"), s, s), m);
func_decl_ref h( m.mk_func_decl(symbol("h"), s, s), m);
sort * domain[2] = {s, s};
func_decl_ref f( m.mk_func_decl(symbol("f"), 2, domain, s), m);
app_ref a( m.mk_const(symbol("a"), s), m);
app_ref b( m.mk_const(symbol("b"), s), m);
expr_ref x( m.mk_var(0, s), m);
expr_ref y( m.mk_var(1, s), m);
app_ref gx( m.mk_app(g, x), m);
app_ref fgx_x( m.mk_app(f, gx.get(), x.get()), m);
app_ref ha( m.mk_app(h, a.get()), m);
app_ref gha( m.mk_app(g, ha.get()), m);
app_ref fgha_ha( m.mk_app(f, gha.get(), ha.get()), m);
tst_match(m, fgx_x, fgha_ha);
app_ref fgha_gha( m.mk_app(f, gha.get(), gha.get()), m);
tst_match(m, fgx_x, fgha_gha);
app_ref fxy( m.mk_app(f, x.get(), y.get()), m);
app_ref fyx( m.mk_app(f, y.get(), x.get()), m);
tst_match(m, fxy, fyx);
app_ref fygx( m.mk_app(f, y.get(), gx.get()), m);
tst_match(m, fxy, fygx);
tst_match(m, fygx, fxy);
}
void tst_matcher() {
tst1();
}
#else
void tst_matcher() {
}
#endif

54
src/test/memory.cpp Normal file
View file

@ -0,0 +1,54 @@
#ifdef _WINDOWS
#include "z3.h"
#include "z3_private.h"
#include <iostream>
#include "util.h"
#include "trace.h"
static bool oom = false;
static void err_handler(Z3_context c, Z3_error_code e) {
oom = true;
throw std::bad_alloc();
}
static void hit_me(char const* wm) {
Z3_config cfg;
Z3_context ctx;
oom = false;
cfg = Z3_mk_config();
Z3_set_param_value(cfg, "MEMORY_MAX_SIZE", wm);
ctx = Z3_mk_context(cfg);
Z3_set_error_handler(ctx, &err_handler);
unsigned i;
for (i = 1; !oom ; ++i) {
try {
Z3_mk_bv_sort(ctx,i);
}
catch (std::bad_alloc) {
std::cout << "caught\n";
}
}
std::cout << "oom " << i << "\n";
}
void tst_memory() {
hit_me("1");
Z3_reset_memory();
hit_me("2");
Z3_reset_memory();
hit_me("3");
Z3_reset_memory();
}
#else
void tst_memory() {
}
#endif

49
src/test/model2expr.cpp Normal file
View file

@ -0,0 +1,49 @@
#include "model2expr.h"
#include "ast_pp.h"
#include "arith_decl_plugin.h"
#include "model_smt2_pp.h"
void tst_model2expr() {
ast_manager m;
m.register_decl_plugins();
arith_util a(m);
ptr_vector<sort> ints;
ints.push_back(a.mk_int());
ints.push_back(a.mk_int());
ints.push_back(a.mk_int());
func_decl_ref p(m), q(m), x(m);
p = m.mk_func_decl(symbol("p"), 2, ints.c_ptr(), a.mk_int());
q = m.mk_func_decl(symbol("q"), 2, ints.c_ptr(), a.mk_int());
x = m.mk_const_decl(symbol("x"), a.mk_int());
expr_ref n0(m), n1(m), n2(m);
n0 = a.mk_numeral(rational(0), true);
n1 = a.mk_numeral(rational(1), true);
n2 = a.mk_numeral(rational(2), true);
model_ref md = alloc(model, m);
func_interp* fip = alloc(func_interp, m, 2);
func_interp* fiq = alloc(func_interp, m, 2);
expr_ref_vector args(m);
args.push_back(n1);
args.push_back(n2);
fip->insert_entry(args.c_ptr(), n1);
fiq->insert_entry(args.c_ptr(), n1);
args[0] = n0;
args[1] = n1;
fip->insert_entry(args.c_ptr(), n2);
fiq->insert_entry(args.c_ptr(), n2);
fip->set_else(n0);
md->register_decl(x, a.mk_numeral(rational(0), true));
md->register_decl(p, fip); // full
md->register_decl(q, fiq); // partial
expr_ref result(m);
model2expr(md, result);
model_smt2_pp(std::cout, m, *md, 0);
std::cout << mk_pp(result, m) << "\n";
}

View file

@ -0,0 +1,62 @@
#include "ast.h"
#include "front_end_params.h"
#include "smt_context.h"
#include "arith_decl_plugin.h"
#include "bv_decl_plugin.h"
#include "array_decl_plugin.h"
#include "model_v2_pp.h"
void tst_model_retrieval()
{
memory::initialize(0);
front_end_params params;
params.m_model = true;
ast_manager m;
m.register_decl_plugins();
family_id array_fid = m.get_family_id(symbol("array"));
array_util au(m);
array_decl_plugin& ad = *static_cast<array_decl_plugin *>(m.get_plugin(array_fid));
// arr_s and select_fn creation copy-pasted from z3.cpp
parameter sparams[2] = { parameter(to_sort(m.mk_bool_sort())), parameter(to_sort(m.mk_bool_sort())) };
sort_ref arr_s(m.mk_sort(array_fid, ARRAY_SORT, 2, sparams), m);
sort * domain2[2] = {arr_s, m.mk_bool_sort()};
func_decl_ref select_fn(
m.mk_func_decl(array_fid, OP_SELECT, 2, arr_s->get_parameters(), 2, domain2), m);
app_ref a1(m.mk_const(symbol("a1"), arr_s), m);
app_ref a2(m.mk_const(symbol("a2"), arr_s), m);
// (= true (select a1 true))
app_ref fml(m.mk_eq(m.mk_true(),
m.mk_app(select_fn.get(), a1, m.mk_true())), m);
smt::context ctx(m, params);
ctx.assert_expr(fml);
lbool check_result = ctx.check();
std::cout<<((check_result==l_true) ? "satisfiable" :
(check_result==l_false) ? "unsatisfiable" : "unknown")<<"\n";
ref<model> model;
ctx.get_model(model);
model_v2_pp(std::cout, *model, false);
expr_ref a1_val(model->get_const_interp(a1->get_decl()), m);
app_ref fml2(m.mk_eq(a2, a1_val), m);
ctx.assert_expr(fml2);
std::cout<<"--------------------------\n";
ctx.display(std::cout);
std::cout<<"--------------------------\n";
check_result = ctx.check();
ctx.display(std::cout);
std::cout<<"--------------------------\n";
std::cout<<((check_result==l_true) ? "satisfiable" :
(check_result==l_false) ? "unsatisfiable" : "unknown")<<"\n";
}

60
src/test/mpbq.cpp Normal file
View file

@ -0,0 +1,60 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
mpbq.cpp
Abstract:
mpbq tests...
Author:
Leonardo de Moura (leonardo) 2012-09-20
Revision History:
--*/
#include "mpbq.h"
static void tst1() {
unsynch_mpz_manager zm;
mpbq_manager m(zm);
scoped_mpbq a(m), b(m);
m.set(a, INT_MAX);
a = a + 1;
a = a * a;
a = a*3 - 1;
a = a * a - 5;
a = a * a - 7;
m.div2k(a, 67);
std::cout << a << "\n";
b = a;
m.approx(b, 32, true);
std::cout << b << "\n";
b = a;
m.approx(b, 32, false);
std::cout << b << "\n";
b = a; m.neg(b);
m.approx(b, 32, true);
std::cout << b << "\n";
b = a; m.neg(b);
m.approx(b, 32, false);
std::cout << b << "\n";
}
static void tst2() {
unsynch_mpz_manager zm;
mpbq_manager m(zm);
scoped_mpbq a(m), b(m);
m.set(a, 5);
m.set(b, 3);
m.approx_div(a, b, a, 128);
std::cout << a << "\n";
}
void tst_mpbq() {
tst1();
tst2();
}

88
src/test/mpf.cpp Normal file
View file

@ -0,0 +1,88 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
mpf.cpp
Abstract:
mpf repros...
Author:
Leonardo de Moura (leonardo) 2012-08-21.
Revision History:
--*/
#include"mpf.h"
#include"f2n.h"
static void bug_set_int() {
mpf_manager fm;
scoped_mpf a(fm);
fm.set(a, 11, 53, 3);
SASSERT(fm.to_double(a) == 3.0);
fm.set(a, 11, 53, 0);
SASSERT(fm.to_double(a) == 0.0);
fm.set(a, 11, 53, -1);
SASSERT(fm.to_double(a) == -1.0);
fm.set(a, 11, 53, INT_MAX);
SASSERT(fm.to_double(a) == (double)INT_MAX);
fm.set(a, 11, 53, INT_MIN);
SASSERT(fm.to_double(a) == (double)INT_MIN);
fm.set(a, 8, 24, 3);
SASSERT(fm.to_float(a) == 3.0);
SASSERT(fm.to_double(a) == 3.0);
fm.set(a, 8, 24, 0);
SASSERT(fm.to_float(a) == 0.0);
SASSERT(fm.to_double(a) == 0.0);
fm.set(a, 8, 24, -1);
SASSERT(fm.to_float(a) == -1.0);
SASSERT(fm.to_double(a) == -1.0);
fm.set(a, 8, 24, INT_MIN);
SASSERT(fm.to_float(a) == (float)INT_MIN);
// CMW: This one depends on the rounding mode, but fm.set(..., int) doesn't have one.
// fm.set(a, 8, 24, INT_MAX);
// SASSERT(fm.to_float(a) == (float)INT_MAX);
}
static void bug_set_double() {
mpf_manager fm;
scoped_mpf a(fm);
fm.set(a, 11, 53, 2.5);
SASSERT(fm.to_double(a) == 2.5);
fm.set(a, 11, 53, -42.25);
SASSERT(fm.to_double(a) == -42.25);
fm.set(a, 8, 24, (double)2.5);
SASSERT(fm.to_double(a) == 2.5);
fm.set(a, 8, 24, (double)-42.25);
SASSERT(fm.to_double(a) == -42.25);
fm.set(a, 8, 24, (float)2.5);
SASSERT(fm.to_float(a) == 2.5);
fm.set(a, 8, 24, (float)-42.25);
SASSERT(fm.to_float(a) == -42.25);
}
void tst_mpf() {
enable_trace("mpf_mul_bug");
bug_set_int();
bug_set_double();
}

666
src/test/mpff.cpp Normal file
View file

@ -0,0 +1,666 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
mpff.cpp
Abstract:
mpff tests...
Author:
Leonardo de Moura (leonardo) 2012-09-12.
Revision History:
--*/
#include<sstream>
#include"mpff.h"
#include"mpz.h"
#include"mpq.h"
static void tst1() {
try {
mpff_manager m;
// m.round_to_minus_inf();
scoped_mpff a(m), b(m);
m.set(a, 100);
m.set(b, -33);
std::cout << "a: " << a << ", b: " << b << "\n";
std::cout << "a*b: " << a*b << "\n";
for (unsigned i = 0; i < 100; i++) {
a = a*a;
std::cout << i << ": " << a << "\n";
}
}
catch (z3_exception & ex) {
std::cout << ex.msg() << "\n";
}
}
static void tst2() {
mpff_manager m;
scoped_mpff a(m), b(m);
m.set(a, static_cast<uint64>(100));
m.set(b, static_cast<int64>(-100));
std::cout << "[test2], a: " << a << ", b: " << b << "\n";
}
static void tst3() {
mpff_manager m;
scoped_mpff a(m), b(m), c(m);
m.set(a, 1);
m.set(b, 3);
m.div(a, b, c);
std::cout << "[div] c: " << c << "\n";
m.round_to_plus_inf();
m.reset(c);
m.div(a, b, c);
std::cout << "[div] c: " << c << "\n";
}
static void tst4() {
unsynch_mpz_manager zm;
mpff_manager m;
scoped_mpz a(zm);
scoped_mpff b(m);
zm.set(a, 2);
zm.power(a, 512, a);
m.set(b, zm, a);
std::cout << "[mpz->mpff] a: " << a << ", b: " << b << "\n";
}
static void tst5() {
mpff_manager m;
scoped_mpff a(m), b(m);
m.set(a, static_cast<uint64>(1) << 63);
m.display_raw(std::cout, a); std::cout << "\n";
SASSERT(m.is_zero(b));
SASSERT(m.lt(b, a));
m.set(b, -1);
SASSERT(m.lt(b, a));
}
static void tst6() {
mpff_manager m;
scoped_mpff a(m), b(m), one(m);
m.set(a, 1, 3);
std::cout << "mpff(1/3) " << a << "\n";
b = a;
m.next(b);
SASSERT(m.lt(a, b));
std::cout << "b: " << b << "\n";
m.prev(b);
SASSERT(m.eq(a, b));
m.ceil(b);
std::cout << "b: " << b << "\n";
m.set(b, 4, 3);
std::cout << "b: " << b << "\n";
m.ceil(b);
std::cout << "b: " << b << "\n";
}
static void tst7() {
mpff_manager m;
scoped_mpff a(m);
m.set(a, 2);
m.display_smt2(std::cout, a); std::cout << "\n";
m.set(a, -2);
m.display_smt2(std::cout, a); std::cout << "\n";
m.set(a, 1, 3);
m.display_smt2(std::cout, a); std::cout << "\n";
}
// if (!qm.le(qa, qt)) { TRACE("mpff_bug", tout << fa << "\n" << qa << "\n" << qt << "\n";); UNREACHABLE(); } \
#define MK_BIN_OP(OP) \
static void tst_ ## OP ## _core(int64 n1, uint64 d1, int64 n2, uint64 d2, unsigned precision = 2, unsigned exp = 0) { \
TRACE("mpff_bug", tout << n1 << "/" << d1 << ", " << n2 << "/" << d2 << "\n";); \
unsynch_mpq_manager qm; \
scoped_mpq qa(qm), qb(qm), qc(qm), qt(qm); \
\
mpff_manager fm(precision); \
scoped_mpff fa(fm), fb(fm), fc1(fm), fc2(fm); \
fm.set(fa, n1, d1); \
if (exp != 0) { int _exp = rand() % exp; if (rand() % 2 == 0) _exp = -_exp; fm.set_exponent(fa, _exp); } \
fm.to_mpq(fa, qm, qa); \
fm.set(fb, n2, d2); \
if (exp != 0) { int _exp = rand() % exp; if (rand() % 2 == 0) _exp = -_exp; fm.set_exponent(fb, _exp); } \
fm.to_mpq(fb, qm, qb); \
qm.OP(qa, qb, qc); \
{ \
fm.round_to_plus_inf(); \
fm.OP(fa, fb, fc1); \
fm.to_mpq(fc1, qm, qt); \
SASSERT(qm.le(qc, qt)); \
} \
{ \
fm.round_to_minus_inf(); \
fm.OP(fa, fb, fc2); \
fm.to_mpq(fc2, qm, qt); \
SASSERT(qm.le(qt, qc)); \
} \
SASSERT(fm.le(fc2, fc1)); \
}
MK_BIN_OP(add);
MK_BIN_OP(sub);
MK_BIN_OP(mul);
MK_BIN_OP(div);
#define MK_BIN_RANDOM_TST(OP) \
static void tst_ ## OP(unsigned N, unsigned max, unsigned prec = 2, bool is_div = false) { \
for (unsigned i = 0; i < N; i++) { \
int n1 = rand() % max; \
int d1 = rand() % max + 1; \
int n2 = rand() % max; \
int d2 = rand() % max + 1; \
if (rand () % 2 == 0) \
n1 = -n1; \
if (rand () % 2 == 0) \
n2 = -n2; \
if (is_div && n2 == 0) n2 = 1; \
tst_ ## OP ## _core(n1, d1, n2, d2, prec); \
tst_ ## OP ## _core(n1, d1, n2, d2, prec, 512); \
} \
}
MK_BIN_RANDOM_TST(add)
MK_BIN_RANDOM_TST(sub)
MK_BIN_RANDOM_TST(mul)
MK_BIN_RANDOM_TST(div)
static void tst_bug() {
unsynch_mpq_manager qm;
mpff_manager fm;
fm.round_to_plus_inf();
scoped_mpff a(fm);
fm.set(a, 41, 36);
scoped_mpq b(qm), c(qm);
qm.set(b, 41, 36);
fm.to_mpq(a, qm, c);
SASSERT(qm.le(b, c));
}
static void tst_bug2() {
mpff_manager fm(4);
scoped_mpff a(fm), b(fm);
fm.set(b, 1);
fm.sub(a, b, b);
fm.set(a, -1);
SASSERT(fm.eq(a, b));
fm.set(a, 1);
fm.set(b, 0);
fm.sub(a, b, a);
fm.set(b, 1);
SASSERT(fm.eq(a, b));
fm.set(a, 1);
fm.set(b, 1);
fm.sub(a, b, a);
SASSERT(fm.is_zero(a));
}
static void tst_set64(unsigned N, unsigned prec) {
mpff_manager fm(prec);
scoped_mpff a(fm);
fm.set(a, INT64_MAX);
SASSERT(fm.is_int64(a));
SASSERT(fm.is_uint64(a));
fm.inc(a);
SASSERT(!fm.is_int64(a));
SASSERT(fm.is_uint64(a));
SASSERT(fm.is_int(a));
fm.dec(a);
SASSERT(fm.is_int64(a));
SASSERT(fm.is_uint64(a));
fm.dec(a);
SASSERT(fm.is_int64(a));
SASSERT(fm.is_uint64(a));
fm.set(a, INT64_MIN);
SASSERT(fm.is_int64(a));
SASSERT(!fm.is_uint64(a));
fm.dec(a);
SASSERT(!fm.is_int64(a));
SASSERT(!fm.is_uint64(a));
SASSERT(fm.is_int(a));
fm.inc(a);
SASSERT(fm.is_int64(a));
SASSERT(!fm.is_uint64(a));
fm.inc(a);
SASSERT(fm.is_int64(a));
SASSERT(!fm.is_uint64(a));
fm.set(a, UINT64_MAX);
SASSERT(fm.is_uint64(a));
SASSERT(!fm.is_int64(a));
fm.inc(a);
SASSERT(!fm.is_uint64(a));
SASSERT(!fm.is_int64(a));
fm.dec(a);
SASSERT(fm.is_uint64(a));
SASSERT(!fm.is_int64(a));
fm.dec(a);
SASSERT(fm.is_uint64(a));
SASSERT(!fm.is_int64(a));
for (unsigned i = 0; i < N; i++) {
{
uint64 v = (static_cast<uint64>(rand()) << 32) + static_cast<uint64>(rand());
fm.set(a, v);
SASSERT(fm.is_uint64(a));
v = (static_cast<uint64>(rand() % 3) << 32) + static_cast<uint64>(rand());
fm.set(a, v);
SASSERT(fm.is_uint64(a));
}
{
int64 v = (static_cast<uint64>(rand() % INT_MAX) << 32) + static_cast<uint64>(rand());
if (rand()%2 == 0)
v = -v;
fm.set(a, v);
SASSERT(fm.is_int64(a));
v = (static_cast<uint64>(rand() % 3) << 32) + static_cast<uint64>(rand());
if (rand()%2 == 0)
v = -v;
fm.set(a, v);
SASSERT(fm.is_int64(a));
}
}
}
static void tst_capacity(unsigned prec = 2) {
mpff_manager m(prec);
scoped_mpff_vector v(m);
scoped_mpff a(m);
for (unsigned i = 0; i < 50000; i++) {
m.set(a, i);
v.push_back(a);
SASSERT(m.is_int(v.back()));
SASSERT(m.is_int64(v.back()));
SASSERT(m.is_uint64(v.back()));
}
for (unsigned i = 0; i < 50000; i++) {
SASSERT(m.get_int64(v[i]) == i);
}
}
static void tst_power(unsigned prec = 2) {
mpff_manager m(prec);
scoped_mpff a(m), b(m);
// 0^k == 0
SASSERT(m.is_zero(a));
m.power(a, 10, a);
SASSERT(m.is_zero(a));
// a != 0 ==> a^0 == 1
m.set(a, 33);
m.power(a, 0, a);
SASSERT(m.is_one(a));
m.set(a, -33);
m.power(a, 0, a);
SASSERT(m.is_one(a));
// a^1 == a
m.set(a, 33);
m.power(a, 1, b);
SASSERT(m.eq(a, b));
m.set(a, -33);
m.power(a, 1, b);
SASSERT(m.eq(a, b));
// checking special support for powers of 2
#ifdef Z3DEBUG
unsigned k;
#endif
m.set(a, 1);
SASSERT(m.is_power_of_two(a, k) && k == 0);
m.set(a, 2);
SASSERT(m.is_power_of_two(a, k) && k == 1);
m.set(a, 3);
SASSERT(!m.is_power_of_two(a, k));
m.set(a, 4);
SASSERT(m.is_power_of_two(a, k) && k == 2);
m.set(a, -4);
SASSERT(!m.is_power_of_two(a, k));
m.set(a, 8);
SASSERT(m.is_power_of_two(a, k) && k == 3);
m.set(a, 0);
SASSERT(!m.is_power_of_two(a));
m.set(a, UINT_MAX);
m.inc(a);
SASSERT(m.is_power_of_two(a, k) && k == 32);
SASSERT(m.get_uint64(a) == static_cast<uint64>(UINT_MAX) + 1);
m.power(a, 2, a);
SASSERT(m.is_power_of_two(a, k) && k == 64);
m.power(a, 4, a);
SASSERT(m.is_power_of_two(a, k) && k == 256);
m.round_to_plus_inf();
m.inc(a);
SASSERT(!m.is_power_of_two(a, k));
m.set(a, -4);
m.power(a, 3, a);
m.set(b, -64);
SASSERT(m.eq(a, b));
m.set(a, -4);
m.power(a, 4, a);
m.set(b, 256);
SASSERT(m.eq(a, b));
// additional tests
m.set(a, 5);
m.power(a, 3, a);
m.set(b, 5*5*5);
SASSERT(m.eq(a,b));
m.set(a, -5);
m.power(a, 3, a);
m.set(b, -5*5*5);
SASSERT(m.eq(a,b));
}
static void tst_sgn(unsigned prec) {
mpff_manager m(prec);
scoped_mpff a(m), b(m);
SASSERT(m.is_zero(a) && !m.is_pos(a) && !m.is_neg(a) && m.is_nonpos(a) && m.is_nonneg(a));
m.set(a, 3);
SASSERT(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a));
m.set(a, -3);
SASSERT(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a));
m.set(a, 8);
m.power(a, 256, a);
SASSERT(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a));
b = a;
m.neg(a);
SASSERT(m.neq(a, b));
SASSERT(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a));
m.neg(a);
SASSERT(m.eq(a, b));
m.set(a, 1);
SASSERT(m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a) && m.is_abs_one(a));
m.neg(a);
SASSERT(!m.is_one(a) && !m.is_zero(a) && m.is_minus_one(a) && m.is_abs_one(a));
m.set(a, 3);
SASSERT(!m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a));
m.set(a, 3);
b = a;
m.abs(a);
SASSERT(m.eq(a, b));
m.set(a, -3);
b = a;
m.abs(a);
SASSERT(!m.eq(a,b) && m.is_pos(a));
m.set(a, 1);
m.swap(a, a);
SASSERT(m.is_one(a));
m.set(b, -1);
m.swap(a, b);
SASSERT(m.is_one(b) && m.is_minus_one(a));
m.neg(a);
SASSERT(m.eq(a, b));
}
static void tst_limits(unsigned prec) {
mpff_manager m(prec);
scoped_mpff a(m), b(m), two(m);
m.set_max(a);
SASSERT(m.is_pos(a));
m.set_min(b);
SASSERT(m.is_neg(b));
m.neg(a);
SASSERT(m.eq(a, b));
m.set_max(a);
m.set_max(b);
m.round_to_minus_inf();
m.inc(a);
SASSERT(m.eq(a, b));
m.dec(a);
SASSERT(m.lt(a, b));
m.set_max(a);
m.round_to_plus_inf();
bool overflow = false;
try { m.inc(a); }
catch (mpff_manager::overflow_exception) { overflow = true; }
SASSERT(overflow);
m.set_max(a);
m.dec(a);
SASSERT(m.eq(a, b));
m.set_min(a);
m.set_min(b);
m.round_to_minus_inf();
m.inc(a);
SASSERT(m.eq(a, b));
overflow = true;
try { m.dec(a); }
catch (mpff_manager::overflow_exception) { overflow = true; }
SASSERT(overflow);
m.round_to_plus_inf();
m.set_min(a);
m.inc(a);
SASSERT(m.gt(a,b));
m.set_min(a);
m.dec(a);
SASSERT(m.eq(a,b));
m.set_plus_epsilon(a);
m.set_plus_epsilon(b);
SASSERT(!m.is_zero(a) && m.is_pos(a));
m.set(two, 2);
m.round_to_plus_inf();
m.div(a, two, a);
SASSERT(m.eq(a, b));
m.round_to_minus_inf();
m.div(a, two, a);
SASSERT(m.is_zero(a));
m.round_to_plus_inf();
m.set_plus_epsilon(a);
m.add(a, a, a);
SASSERT(m.gt(a, b));
m.round_to_minus_inf();
m.set_plus_epsilon(a);
m.add(a, a, a);
SASSERT(m.gt(a, b));
m.set_plus_epsilon(a);
m.sub(a, a, a);
SASSERT(m.is_zero(a));
m.set_plus_epsilon(a);
SASSERT(m.is_plus_epsilon(a));
SASSERT(!m.is_minus_epsilon(a));
m.neg(a);
SASSERT(!m.is_plus_epsilon(a));
SASSERT(m.is_minus_epsilon(a));
for (unsigned i = 0; i < 2; i++) {
m.set_rounding(i == 0);
m.set_plus_epsilon(a);
m.floor(a);
SASSERT(m.is_zero(a));
m.set_plus_epsilon(a);
m.ceil(a);
SASSERT(m.is_one(a));
m.set_minus_epsilon(a);
m.floor(a);
SASSERT(m.is_minus_one(a));
m.set_minus_epsilon(a);
m.ceil(a);
SASSERT(m.is_zero(a));
}
m.set_minus_epsilon(a);
m.set_minus_epsilon(b);
SASSERT(!m.is_zero(a) && m.is_neg(a));
m.set(two, 2);
m.round_to_minus_inf();
m.div(a, two, a);
SASSERT(m.eq(a, b));
m.round_to_plus_inf();
m.div(a, two, a);
SASSERT(m.is_zero(a));
m.round_to_plus_inf();
m.set_minus_epsilon(a);
m.add(a, a, a);
SASSERT(m.lt(a, b));
m.round_to_minus_inf();
m.set_minus_epsilon(a);
m.add(a, a, a);
SASSERT(m.lt(a, b));
m.set_minus_epsilon(a);
m.sub(a, a, a);
SASSERT(m.is_zero(a));
m.set_minus_epsilon(a);
SASSERT(!m.is_plus_epsilon(a));
SASSERT(m.is_minus_epsilon(a));
m.neg(a);
SASSERT(m.is_plus_epsilon(a));
SASSERT(!m.is_minus_epsilon(a));
}
static void tst_add_corner(unsigned prec) {
mpff_manager m(prec);
scoped_mpff a(m), b(m);
}
static void tst_decimal(int64 n, uint64 d, bool to_plus_inf, unsigned prec, char const * expected, unsigned decimal_places = UINT_MAX) {
mpff_manager m(prec);
scoped_mpff a(m);
m.set_rounding(to_plus_inf);
m.set(a, n, d);
m.display(std::cout, a); std::cout << std::endl;
m.display_decimal(std::cout, a, decimal_places); std::cout << std::endl;
std::ostringstream buffer;
m.display_decimal(buffer, a, decimal_places);
SASSERT(strcmp(expected, buffer.str().c_str()) == 0);
}
static void tst_decimal() {
tst_decimal(1, 3, false, 2, "0.3333333333333333333152632971252415927665424533188343048095703125");
tst_decimal(1, 3, false, 4, "0.33333333333333333333333333333333333333235375470764809374335938621898146193515111203602326039874270691143465228378772735595703125");
tst_decimal(-1, 3, true, 2, "-0.3333333333333333333152632971252415927665424533188343048095703125");
tst_decimal(-1, 3, false, 2, "-0.33333333333333333334236835143737920361672877334058284759521484375");
tst_decimal(0, 1, false, 2, "0");
tst_decimal(2, 1, false, 2, "2");
tst_decimal(-3, 1, false, 2, "-3");
tst_decimal(INT64_MAX, 1, false, 2, "9223372036854775807");
tst_decimal(4, 5, false, 2, "0.79999999999999999995663191310057982263970188796520233154296875");
tst_decimal(4, 5, false, 2, "0.7999999999?", 10);
tst_decimal(32, 5, true, 2, "6.4000000000000000000867361737988403547205962240695953369140625");
tst_decimal(32, 5, false, 2, "6.39999999999999999965305530480463858111761510372161865234375");
tst_decimal(-32, 5, false, 2, "-6.4000000000000000000867361737988403547205962240695953369140625");
tst_decimal(-32, 5, true, 2, "-6.39999999999999999965305530480463858111761510372161865234375");
}
static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) {
mpff_manager m;
scoped_mpff a(m);
m.set(a, n, d);
SASSERT(m.prev_power_of_two(a) == expected);
}
static void tst_prev_power_2() {
tst_prev_power_2(-10, 1, 0);
tst_prev_power_2(0, 1, 0);
tst_prev_power_2(1, 1, 0);
tst_prev_power_2(2, 1, 1);
tst_prev_power_2(3, 1, 1);
tst_prev_power_2(4, 1, 2);
tst_prev_power_2(5, 1, 2);
tst_prev_power_2(8, 1, 3);
tst_prev_power_2(9, 1, 3);
tst_prev_power_2(9, 2, 2);
tst_prev_power_2(9, 4, 1);
tst_prev_power_2(9, 5, 0);
tst_prev_power_2((1ll << 60) + 1, 1, 60);
tst_prev_power_2((1ll << 60), 1, 60);
tst_prev_power_2((1ll << 60) - 1, 1, 59);
tst_prev_power_2((1ll << 60), 3, 58);
}
static void tst_div(unsigned prec) {
mpff_manager m(prec);
scoped_mpff a(m), b(m), c(m);
m.round_to_plus_inf();
m.set(a, 1);
m.set(b, UINT64_MAX);
m.div(a, b, c);
m.display_raw(std::cout, a); std::cout << "\n";
m.display_raw(std::cout, b); std::cout << "\n";
std::cout << a << "/" << b << " <= " << c << "\n";
// 10...0 0...0
// 11111
}
void tst_mpff() {
disable_trace("mpff");
enable_trace("mpff_trace");
// enable_trace("mpff_bug");
// enable_trace("mpff_to_mpq");
//
tst_div(2);
tst_prev_power_2();
tst_decimal();
tst_div_core(679, 396, 279, 756, 2, 0);
tst_limits(2);
tst_limits(4);
tst_sgn(2);
tst_sgn(4);
tst_sgn(8);
tst_power(2);
tst_power(4);
tst_power(18);
tst_capacity(2);
tst_capacity(4);
tst_capacity(8);
tst_capacity(16);
tst_set64(1000, 2);
tst_set64(1000, 4);
tst_set64(1000, 6);
tst_bug2();
tst_sub(1000, 1024, 2);
tst_sub(1000, 1024, 4);
tst_div(1000, 1024, 2, true);
tst_div(1000, 1024, 4, true);
tst_mul(1000, 1024, 2);
tst_mul(1000, 1024, 4);
tst_add(1000, 1024, 2);
tst_add(1000, 1024, 4);
tst_sub(1000, UINT_MAX, 2);
tst_sub(1000, UINT_MAX, 4);
tst_div(1000, UINT_MAX, 2, true);
tst_div(1000, UINT_MAX, 4, true);
tst_mul(1000, UINT_MAX, 2);
tst_mul(1000, UINT_MAX, 4);
tst_add(1000, UINT_MAX, 2);
tst_add(1000, UINT_MAX, 4);
tst_bug2();
tst_bug();
tst_add_core(1,1, 1,1);
tst_add_core(1,3, 2,3);
tst1();
tst2();
tst3();
tst4();
tst5();
tst6();
tst7();
}

67
src/test/mpfx.cpp Normal file
View file

@ -0,0 +1,67 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
mpfx.cpp
Abstract:
Multi precision fixed point numbers.
Author:
Leonardo de Moura (leonardo) 2012-09-19
Revision History:
--*/
#include"mpfx.h"
static void tst1() {
mpfx_manager m;
scoped_mpfx a(m), b(m), c(m);
m.set(a, 1);
m.set(b, 2);
std::cout << a << " + " << b << " == " << (a+b) << "\n";
m.set(a, 5);
m.set(c, 3);
m.display_raw(std::cout, (a*a*b)/c); std::cout << "\n";
m.display_decimal(std::cout, (a*a*b)/c); std::cout << "\n";
m.display_decimal(std::cout, (a*a*b)/c, 10); std::cout << "\n";
m.round_to_plus_inf();
m.display_decimal(std::cout, (a*a*b)/c); std::cout << "\n";
m.set(a, -1, 4);
m.display_decimal(std::cout, a); std::cout << "\n";
}
static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) {
mpfx_manager m;
scoped_mpfx a(m);
m.set(a, n, d);
SASSERT(m.prev_power_of_two(a) == expected);
}
static void tst_prev_power_2() {
tst_prev_power_2(-10, 1, 0);
tst_prev_power_2(0, 1, 0);
tst_prev_power_2(1, 1, 0);
tst_prev_power_2(2, 1, 1);
tst_prev_power_2(3, 1, 1);
tst_prev_power_2(4, 1, 2);
tst_prev_power_2(5, 1, 2);
tst_prev_power_2(8, 1, 3);
tst_prev_power_2(9, 1, 3);
tst_prev_power_2(9, 2, 2);
tst_prev_power_2(9, 4, 1);
tst_prev_power_2(9, 5, 0);
tst_prev_power_2((1ll << 60) + 1, 1, 60);
tst_prev_power_2((1ll << 60), 1, 60);
tst_prev_power_2((1ll << 60) - 1, 1, 59);
tst_prev_power_2((1ll << 60), 3, 58);
}
void tst_mpfx() {
tst_prev_power_2();
tst1();
}

170
src/test/mpq.cpp Normal file
View file

@ -0,0 +1,170 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
mpq.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-06-21.
Revision History:
--*/
#include"mpq.h"
#include"rational.h"
#include"timeit.h"
static void tst0() {
synch_mpq_manager m;
mpq a, b;
m.set(a, 2, 3);
m.set(b, 4, 3);
m.div(a, b, b);
SASSERT(m.eq(b, m.mk_q(1, 2)));
}
static void tst1() {
synch_mpq_manager m;
char const * str = "1002034040050606089383838288182";
mpz v;
m.set(v, str);
std::cout << str << "\n" << m.to_string(v) << "\n";
mpz v2, v3;
m.mul(v, m.mk_z(-2), v2);
std::cout << "*-2 = \n" << m.to_string(v2) << "\n";
m.add(v, v2, v3);
m.neg(v3);
SASSERT(m.eq(v, v3));
SASSERT(m.le(v, v3));
SASSERT(m.ge(v, v3));
SASSERT(m.lt(v2, v));
SASSERT(m.le(v2, v));
SASSERT(m.gt(v, v2));
SASSERT(m.ge(v, v2));
SASSERT(m.neq(v, v2));
SASSERT(!m.neq(v, v3));
m.del(v);
m.del(v2);
m.del(v3);
}
static void mk_random_num_str(unsigned buffer_sz, char * buffer) {
unsigned div_pos;
unsigned sz = (rand() % (buffer_sz-2)) + 1;
if (rand() % 2 == 0) {
// integer
div_pos = sz + 1;
}
else {
div_pos = rand() % sz;
if (div_pos == 0)
div_pos++;
}
SASSERT(sz < buffer_sz);
for (unsigned i = 0; i < sz-1; i++) {
if (i == div_pos && i < sz-2) {
buffer[i] = '/';
i++;
buffer[i] = '1' + (rand() % 9);
}
else {
buffer[i] = '0' + (rand() % 10);
}
}
buffer[sz-1] = 0;
}
static void bug1() {
synch_mpq_manager m;
mpq a;
mpq b;
m.set(a, 2);
m.set(b, 1, 2);
m.inv(a, a);
SASSERT(m.eq(a, b));
}
static void bug2() {
synch_mpq_manager m;
mpq a;
mpq b;
m.set(a, -2);
m.set(b, -1, 2);
m.inv(a, a);
SASSERT(m.eq(a, b));
}
static void tst2() {
unsynch_mpq_manager m;
scoped_mpq a(m);
m.set(a, 1, 3);
std::cout << "1/3: ";
m.display_decimal(std::cout, a, 10);
std::cout << "\n1/4: ";
m.set(a, 1, 4);
m.display_decimal(std::cout, a, 10);
std::cout << "\n";
}
static void set_str_bug() {
unsynch_mpq_manager m;
scoped_mpq a(m);
scoped_mpq b(m);
m.set(a, "1.0");
std::cout << a << "\n";
m.set(b, 1);
SASSERT(a == b);
m.set(a, "1.1");
std::cout << a << "\n";
m.set(b, 11, 10);
SASSERT(a == b);
m.set(a, "1/3");
m.set(b, 1, 3);
std::cout << a << "\n";
SASSERT(a == b);
}
static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) {
unsynch_mpq_manager m;
scoped_mpq a(m);
m.set(a, n, d);
SASSERT(m.prev_power_of_two(a) == expected);
}
static void tst_prev_power_2() {
tst_prev_power_2(-10, 1, 0);
tst_prev_power_2(0, 1, 0);
tst_prev_power_2(1, 1, 0);
tst_prev_power_2(2, 1, 1);
tst_prev_power_2(3, 1, 1);
tst_prev_power_2(4, 1, 2);
tst_prev_power_2(5, 1, 2);
tst_prev_power_2(8, 1, 3);
tst_prev_power_2(9, 1, 3);
tst_prev_power_2(9, 2, 2);
tst_prev_power_2(9, 4, 1);
tst_prev_power_2(9, 5, 0);
tst_prev_power_2((1ll << 60) + 1, 1, 60);
tst_prev_power_2((1ll << 60), 1, 60);
tst_prev_power_2((1ll << 60) - 1, 1, 59);
tst_prev_power_2((1ll << 60), 3, 58);
}
void tst_mpq() {
tst_prev_power_2();
set_str_bug();
bug2();
bug1();
tst0();
tst1();
tst2();
}

510
src/test/mpz.cpp Normal file
View file

@ -0,0 +1,510 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
mpz.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-06-18.
Revision History:
--*/
#include"mpz.h"
#include"rational.h"
#include"timeit.h"
#include"scoped_numeral.h"
static void tst1() {
synch_mpz_manager m;
char const * str = "1002034040050606089383838288182";
mpz v;
m.set(v, str);
std::cout << str << "\n" << m.to_string(v) << "\n";
mpz v2, v3;
m.mul(v, m.mk_z(-2), v2);
std::cout << "*-2 = \n" << m.to_string(v2) << "\n";
m.add(v, v2, v3);
m.neg(v3);
SASSERT(m.eq(v, v3));
SASSERT(m.le(v, v3));
SASSERT(m.ge(v, v3));
SASSERT(m.lt(v2, v));
SASSERT(m.le(v2, v));
SASSERT(m.gt(v, v2));
SASSERT(m.ge(v, v2));
SASSERT(m.neq(v, v2));
SASSERT(!m.neq(v, v3));
m.del(v);
m.del(v2);
m.del(v3);
}
static void tst2() {
synch_mpz_manager m;
mpz v1, v2, v3;
m.set(v1, static_cast<int64>(UINT_MAX));
m.add(v1, m.mk_z(1), v2);
m.mul(v2, v2, v3);
std::cout << "v2:\n" << m.to_string(v2) << "\n";
std::cout << "v2*v2:\n" << m.to_string(v3) << "\n";
m.del(v1);
m.del(v2);
m.del(v3);
}
static void tst2b() {
synch_mpz_manager m;
mpz v1, v2, v3;
m.set(v1, static_cast<int64>(UINT_MAX));
m.add(v1, m.mk_z(1), v2);
m.mul(v2, v2, v3);
std::cout << "v2:\n" << m.to_string(v2) << "\n";
std::cout << "v2*v2:\n" << m.to_string(v3) << "\n";
m.mul(v2, v2, v2);
m.mul(v2, v2, v2);
m.mul(v2, v2, v2);
std::cout << "v2: " << m.to_string(v2) << "\n";
m.del(v1);
m.del(v2);
m.del(v3);
}
static void mk_random_num_str(unsigned buffer_sz, char * buffer) {
unsigned sz = (rand() % (buffer_sz-2)) + 1;
SASSERT(sz < buffer_sz);
for (unsigned i = 0; i < sz-1; i++) {
buffer[i] = '0' + (rand() % 10);
}
if (rand() % 2 == 0)
buffer[0] = '-';
buffer[sz-1] = 0;
}
static void bug1() {
synch_mpz_manager m;
mpz v1;
m.set(v1, "1002043949858757875676767675747473");
mpz v2;
m.sub(v1, v1, v2);
SASSERT(m.is_zero(v2));
m.del(v1);
m.del(v2);
}
static void bug2() {
synch_mpz_manager m;
mpz v1, v2, vout;
m.set(v1, "78160958900072552148646898355155840547214990303507678364419557473408815232466629049311995556059463490539128818602490221544425042127795");
m.set(v2, "403412298227858394469856607272647132163832860126054679347881638761723785858733108109249157334220127");
m.sub(v1, v2, vout);
m.del(v1);
m.del(v2);
m.del(vout);
}
static void bug3() {
synch_mpz_manager m;
mpz v1, v2;
m.set(v1, INT_MIN);
m.set(v2, INT_MAX);
m.add(v2, m.mk_z(1), v2);
m.neg(v1);
SASSERT(m.eq(v1, v2));
m.del(v1);
m.del(v2);
}
static void bug4() {
synch_mpz_manager m;
mpz x, y;
m.set(y, 4294967295ull);
m.set(x, 4026531839ull);
mpz result1;
m.bitwise_or(x, y, result1);
mpz result2;
m.set(result2, x);
m.bitwise_or(result2, y, result2);
std::cout << m.to_string(result1) << " " << m.to_string(result2) << "\n";
SASSERT(m.eq(result1, result2));
m.del(x); m.del(y); m.del(result1); m.del(result2);
}
void tst_div2k(synch_mpz_manager & m, mpz const & v, unsigned k) {
mpz x, y, two(2), pw;
m.machine_div2k(v, k, x);
m.power(two, k, pw);
m.machine_div(v, pw, y);
bool is_eq = m.eq(x, y);
CTRACE("mpz_2k", !is_eq, tout << "div: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";);
SASSERT(is_eq);
m.del(x);
m.del(y);
m.del(pw);
}
void tst_div2k(synch_mpz_manager & m, int v, unsigned k) {
mpz x;
m.set(x, v);
tst_div2k(m, x, k);
m.del(x);
}
void tst_div2k(synch_mpz_manager & m, char const * v, unsigned k) {
mpz x;
m.set(x, v);
tst_div2k(m, x, k);
m.del(x);
}
void tst_mul2k(synch_mpz_manager & m, mpz const & v, unsigned k) {
mpz x, y, two(2), pw;
m.mul2k(v, k, x);
m.power(two, k, pw);
m.mul(v, pw, y);
bool is_eq = m.eq(x, y);
CTRACE("mpz_2k", !is_eq, tout << "mul: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";);
SASSERT(is_eq);
m.del(x);
m.del(y);
m.del(pw);
}
void tst_mul2k(synch_mpz_manager & m, int v, unsigned k) {
mpz x;
m.set(x, v);
tst_mul2k(m, x, k);
m.del(x);
}
void tst_mul2k(synch_mpz_manager & m, char const * v, unsigned k) {
mpz x;
m.set(x, v);
tst_mul2k(m, x, k);
m.del(x);
}
static void tst_2k() {
synch_mpz_manager m;
tst_mul2k(m, 120, 32);
tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 22);
tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 22);
tst_div2k(m, 3, 1);
tst_div2k(m, 3, 2);
tst_div2k(m, 3, 0);
tst_div2k(m, 120, 32);
tst_div2k(m, 120, 0);
tst_div2k(m, 81, 2);
tst_div2k(m, -3, 1);
tst_div2k(m, -3, 2);
tst_div2k(m, -3, 0);
tst_div2k(m, -102, 4);
tst_div2k(m, 0, 3);
tst_div2k(m, 0, 1000);
tst_div2k(m, 7, 10000);
tst_div2k(m, -7, 1000);
tst_div2k(m, -7, 2);
tst_div2k(m, "1029384848584832828327176162636436484", 4);
tst_div2k(m, "1029384848584832828327176162636436484", 100);
tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 1);
tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 0);
tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 4);
tst_div2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 7);
tst_div2k(m, "102938484858483282832717616263643648433838737661626264364583983298239291919", 100);
tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 100);
tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 177);
tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 77);
tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 32);
tst_div2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64);
tst_div2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64);
tst_div2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 128);
tst_div2k(m, "-1092983874757371817626399990000000", 100);
tst_div2k(m, "-109298387475737181762639999000000231", 8);
tst_div2k(m, "-109298387475737181762639999000000231", 16);
tst_div2k(m, "-109298387475737181762639999000000231", 17);
tst_div2k(m, "-109298387475737181762639999000000231", 32);
tst_mul2k(m, 3, 1);
tst_mul2k(m, 3, 2);
tst_mul2k(m, 3, 0);
tst_mul2k(m, 120, 32);
tst_mul2k(m, 120, 0);
tst_mul2k(m, 81, 2);
tst_mul2k(m, -3, 1);
tst_mul2k(m, -3, 2);
tst_mul2k(m, -3, 0);
tst_mul2k(m, -102, 4);
tst_mul2k(m, 0, 3);
tst_mul2k(m, 0, 1000);
tst_mul2k(m, 7, 10000);
tst_mul2k(m, -7, 1000000);
tst_mul2k(m, -7, 2);
tst_mul2k(m, "1029384848584832828327176162636436484", 4);
tst_mul2k(m, "1029384848584832828327176162636436484", 100);
tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 1);
tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 0);
tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 4);
tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 22);
tst_mul2k(m, "102938484858483282832717616263643648481827437292943727163646457588332211", 7);
tst_mul2k(m, "102938484858483282832717616263643648433838737661626264364583983298239291919", 100);
tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 100);
tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 177);
tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 77);
tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 32);
tst_mul2k(m, "11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64);
tst_mul2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 64);
tst_mul2k(m, "-11579208923731619542357098500868790785326998466564056403945758400793872761761638458372762", 128);
tst_mul2k(m, "-1092983874757371817626399990000000", 100);
tst_mul2k(m, "-109298387475737181762639999000000231", 8);
tst_mul2k(m, "-109298387475737181762639999000000231", 16);
tst_mul2k(m, "-109298387475737181762639999000000231", 17);
tst_mul2k(m, "-109298387475737181762639999000000231", 32);
}
void tst_int_min_bug() {
synch_mpz_manager m;
mpz intmin(INT_MIN);
mpz big;
mpz expected;
mpz r;
m.set(big, UINT64_MAX);
m.set(expected, "18446744075857035263");
m.sub(big, intmin, r);
std::cout << "r: " << m.to_string(r) << "\nexpected: " << m.to_string(expected) << "\n";
SASSERT(m.eq(r, expected));
m.del(intmin);
m.del(big);
m.del(expected);
m.del(r);
}
void tst_scoped() {
synch_mpz_manager m;
scoped_synch_mpz a(m);
scoped_synch_mpz b(m);
m.set(a, 1000231);
m.set(b, "102928187172727273");
std::cout << "a: " << m.to_string(a) << "\n";
std::cout << "b: " << m.to_string(b) << "\n";
m.mul(a, b, b);
std::cout << "b: " << m.to_string(b) << "\n";
}
#define NUM_PRIMES 168
unsigned g_primes[NUM_PRIMES] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997 };
// Return a big number by multipling powers of the first NUM_PRIMES.
// - ratio: rand() % ratio == 0 is used to decide whether a specific prime will be included or not.
// - max_pw: if condition above is satisfied, then we use (rand() % max_pw) + 1 as the power.
void mk_big_num(unsynch_mpz_manager & m, unsigned ratio, unsigned max_pw, mpz & r) {
scoped_mpz tmp(m);
m.set(r, 1);
for (unsigned i = 0; i < NUM_PRIMES; i++) {
if ((rand() % ratio) == 0) {
m.power(mpz(g_primes[i]), (rand() % max_pw) + 1, tmp);
m.mul(r, tmp, r);
}
}
if ((rand() % 2) == 0)
m.neg(r);
}
void slow_gcd(unsynch_mpz_manager & m, mpz const & a, mpz const & b, mpz & c) {
scoped_mpz tmp1(m);
scoped_mpz tmp2(m);
scoped_mpz aux(m);
m.set(tmp1, a);
m.set(tmp2, b);
m.abs(tmp1);
m.abs(tmp2);
if (m.le(tmp1, tmp2))
m.swap(tmp1, tmp2);
if (m.is_zero(tmp2)) {
m.set(c, tmp1);
return;
}
for(;;) {
m.rem(tmp1, tmp2, aux);
if (m.is_zero(aux)) {
m.set(c, tmp2);
return;
}
m.set(tmp1, tmp2);
m.set(tmp2, aux);
}
}
void rand_tst_gcd(unsigned num, unsigned ratio, unsigned pw) {
unsynch_mpz_manager m;
scoped_mpz a(m);
scoped_mpz b(m);
scoped_mpz g1(m);
scoped_mpz g2(m);
for (unsigned i = 0; i < num; i++) {
mk_big_num(m, ratio, pw, a);
mk_big_num(m, ratio, pw, b);
slow_gcd(m, a, b, g1);
m.gcd(a, b, g2);
std::cout << "a: " << m.to_string(a) << "\n";
std::cout << "b: " << m.to_string(b) << "\n";
std::cout << "g1: " << m.to_string(g1) << "\n";
std::cout << "g2: " << m.to_string(g2) << "\n";
std::cout << "\n";
if (!m.eq(g1, g2)) {
std::cout << "\n\nBUG\n\n";
UNREACHABLE();
}
}
}
void tst_gcd() {
unsynch_mpz_manager m;
scoped_mpz a(m);
scoped_mpz b(m);
scoped_mpz g(m);
m.set(a, "125141154046000416200229049397707776");
m.set(b, "67062117506072642958648904906464");
m.gcd(a, b, g);
std::cout << "g: " << m.to_string(g) << "\n";
m.set(a, "664877781119188360263909568610284290708591605105963082581413244598320881431041311468785283029437655134762231312337924555674674176");
m.set(b, "21691055098083293041646678174999125628463716392747356050705870375852789453851926624107939885328471215366825649627326658281728580399051770334114658498352848410853519374962852431831492868108719406669605254329669417322836882756478295264");
for (unsigned i = 0; i < 50000; i++) {
m.del(g);
m.gcd(a, b, g);
// slow_gcd(m, a, b, g);
}
std::cout << "g: " << m.to_string(g) << "\n";
}
void tst_log2(unsynch_mpz_manager & m, mpz const & a) {
scoped_mpz b(m);
unsigned k = m.log2(a);
m.power(mpz(2), k, b);
SASSERT(m.is_zero(a) || m.le(b, a));
m.power(mpz(2), k+1, b);
SASSERT(m.le(a, b));
scoped_mpz neg_a(m);
m.set(neg_a, a);
m.neg(neg_a);
k = m.mlog2(neg_a);
m.power(mpz(2), k, b);
m.neg(b);
SASSERT(m.is_zero(neg_a) || m.le(neg_a, b));
m.power(mpz(2), k+1, b);
m.neg(b);
SASSERT(m.le(b, neg_a));
}
void tst_log2() {
unsynch_mpz_manager m;
for (unsigned i = 0; i <= 64; i++)
std::cout << "log2(" << i << "): " << m.log2(mpz(i)) << "\n";
for (unsigned i = 0; i < 1000; i++)
tst_log2(m, mpz(i));
scoped_mpz a(m);
m.set(a, "1029489380487098723984579237");
for (unsigned i = 0; i < 1000; i++) {
m.inc(a);
tst_log2(m, a);
}
}
void tst_root() {
unsynch_mpz_manager m;
scoped_mpz a(m);
m.set(a, 213);
VERIFY(!m.root(a, 5));
std::cout << "213^{1/5}: " << a << "\n";
SASSERT(m.eq(a, mpz(3)));
m.set(a, -213);
VERIFY(!m.root(a, 5));
std::cout << "-213^{1/5}: " << a << "\n";
SASSERT(m.eq(a, mpz(-2)));
m.set(a, 0);
VERIFY(m.root(a, 3));
SASSERT(m.is_zero(a));
m.set(a, 8);
VERIFY(m.root(a, 3));
SASSERT(m.eq(a, mpz(2)));
m.set(a, -8);
VERIFY(m.root(a, 3));
SASSERT(m.eq(a, mpz(-2)));
}
void tst_gcd_bug() {
unsynch_mpz_manager m;
scoped_mpz a(m), b(m), g(m);
m.set(a, INT_MIN);
m.set(b, INT_MIN);
m.gcd(a, b, g);
std::cout << "g: " << g << "\n";
}
void tst_div2k_bug() {
unsynch_mpz_manager m;
scoped_mpz a(m), b(m), g(m);
m.set(a, UINT_MAX);
m.machine_div2k(a, 32, b);
std::cout << "a: " << a << ", b: " << b << "\n";
}
static void tst5() {
unsynch_mpz_manager m;
scoped_mpz a(m);
a = 1;
std::cout << "1 -> " << m.log2(a) << "\n";
a = 5;
std::cout << "5 -> " << m.log2(a) << "\n";
a = 16;
std::cout << "16 -> " << m.log2(a) << "\n";
a = INT_MAX;
std::cout << "INT_MAX -> " << m.log2(a) << "\n";
a = INT_MAX/4;
std::cout << "INT_MAX/4 -> " << m.log2(a) << "\n";
}
static void tst_pw2() {
unsynch_mpz_manager m;
scoped_mpz a(m);
for (unsigned i = 0; i < 128; i++) {
m.power(mpz(2), i, a);
std::cout << "i: " << i << ", a: " << a << std::endl;
}
}
void tst_mpz() {
disable_trace("mpz");
enable_trace("mpz_2k");
tst_pw2();
tst5();
tst_div2k_bug();
rand_tst_gcd(50, 3, 2);
tst_2k();
tst_gcd_bug();
tst_root();
tst_log2();
// tst_gcd();
tst_scoped();
tst_int_min_bug();
bug4();
bug3();
bug1();
bug2();
tst1();
tst2();
tst2b();
}

45
src/test/nlarith_util.cpp Normal file
View file

@ -0,0 +1,45 @@
#include "nlarith_util.h"
#include "arith_decl_plugin.h"
#include "ast_pp.h"
void tst_nlarith_util() {
ast_manager M;
M.register_decl_plugins();
arith_util A(M);
sort_ref R(A.mk_real(), M);
app_ref one(A.mk_numeral(rational(1), false), M);
app_ref two(A.mk_numeral(rational(2), false), M);
app_ref ten(A.mk_numeral(rational(10), false), M);
app_ref x(M.mk_const(symbol("x"), R), M);
app_ref y(M.mk_const(symbol("y"), R), M);
app_ref z(M.mk_const(symbol("z"), R), M);
expr_ref p1(A.mk_le(A.mk_add(A.mk_mul(x,x,y), y), one), M);
expr_ref p2(A.mk_le(A.mk_add(A.mk_mul(x,x,y), z), one), M);
enable_trace("nlarith");
nlarith::util u(M);
nlarith::branch_conditions bc(M);
expr_ref_vector preds(M), branches(M);
vector<expr_ref_vector> substs;
expr* lits[2] = { p1.get(), p2.get() };
if (!u.create_branches(x.get(), 2, lits, bc)) {
std::cout << "Failed to create branches\n";
return;
}
for (unsigned i = 0; i < preds.size(); ++i) {
std::cout << "Pred: " << mk_pp(preds[i].get(), M) << "\n";
}
for (unsigned i = 0; i < branches.size(); ++i) {
std::cout << "Branch:\n" << mk_pp(branches[i].get(), M) << "\n";
for (unsigned j = 0; j < substs[i].size(); ++j) {
std::cout << mk_pp(preds[j].get(), M) << " |-> "
<< mk_pp(substs[i][j].get(), M) << "\n";
}
}
}

306
src/test/nlsat.cpp Normal file
View file

@ -0,0 +1,306 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
nlsat.cpp
Abstract:
nlsat procedure
Author:
Leonardo (leonardo) 2012-01-09
Notes:
--*/
#include"nlsat_assignment.h"
#include"nlsat_interval_set.h"
#include"nlsat_evaluator.h"
#include"nlsat_solver.h"
#include"util.h"
nlsat::interval_set_ref tst_interval(nlsat::interval_set_ref const & s1,
nlsat::interval_set_ref const & s2,
unsigned expected_num_intervals,
bool check_num_intervals = true) {
nlsat::interval_set_manager & ism = s1.m();
nlsat::interval_set_ref r(ism);
std::cout << "------------------\n";
std::cout << "s1: " << s1 << "\n";
std::cout << "s2: " << s2 << "\n";
r = ism.mk_union(s1, s2);
std::cout << "union(s1, s2): " << r << std::endl;
SASSERT(!check_num_intervals || ism.num_intervals(r) == expected_num_intervals);
SASSERT(ism.subset(s1, r));
SASSERT(ism.subset(s2, r));
if (ism.set_eq(s1, s2)) {
SASSERT(ism.set_eq(s1, r));
SASSERT(ism.set_eq(s2, r));
}
else {
SASSERT(ism.subset(s1, s2) || !ism.subset(r, s2));
SASSERT(ism.subset(s2, s1) || !ism.subset(r, s1));
}
nlsat::interval_set_ref r2(ism);
r2 = ism.mk_union(s2, s1);
SASSERT(ism.set_eq(r, r2));
anum zero;
nlsat::interval_set_ref full(ism);
nlsat::literal dummy(131, false);
full = ism.mk(true, true, zero, true, true, zero, dummy);
SASSERT(ism.set_eq(r, full) == ism.is_full(r));
return r;
}
static void tst3() {
enable_trace("nlsat_interval");
unsynch_mpq_manager qm;
anum_manager am(qm);
small_object_allocator allocator;
nlsat::interval_set_manager ism(am, allocator);
scoped_anum sqrt2(am), m_sqrt2(am), two(am), m_two(am), three(am), one(am), zero(am);
am.set(two, 2);
am.set(m_two, -2);
am.set(one, 1);
am.root(two, 2, sqrt2);
am.set(m_sqrt2, sqrt2);
am.neg(m_sqrt2);
am.set(three, 3);
nlsat::literal p1(1, false);
nlsat::literal p2(2, false);
nlsat::literal p3(3, false);
nlsat::literal p4(4, false);
nlsat::literal np2(2, true);
nlsat::interval_set_ref s1(ism), s2(ism), s3(ism), s4(ism);
s1 = ism.mk_empty();
std::cout << "s1: " << s1 << "\n";
s2 = ism.mk(true, true, zero, false, false, sqrt2, np2);
std::cout << "s2: " << s2 << "\n";
s3 = ism.mk(false, false, zero, false, false, two, p1);
std::cout << "s3: " << s3 << "\n";
s4 = ism.mk_union(s2, s3);
std::cout << "s4: " << s4 << "\n";
// Case
// s1: [ ... ]
// s2: [ ... ]
s1 = ism.mk(false, false, zero, false, false, two, p1);
s2 = ism.mk(false, false, zero, false, false, two, p2);
tst_interval(s1, s2, 1);
// Case
// s1: [ ... ]
// s2: [ ... ]
s1 = ism.mk(false, false, zero, false, false, two, p1);
s2 = ism.mk(false, false, m_sqrt2, false, false, one, p2);
s3 = ism.mk_union(s1, s2);
tst_interval(s1, s2, 2);
// Case
// s1: [ ... ]
// s2: [ ... ]
s1 = ism.mk(false, false, m_sqrt2, false, false, one, p1);
s2 = ism.mk(false, false, zero, false, false, two, p2);
tst_interval(s1, s2, 2);
// Case
// s1: [ ... ]
// s2: [ ... ]
s1 = ism.mk(false, false, m_sqrt2, false, false, one, p1);
s2 = ism.mk(false, false, two, false, false, three, p2);
tst_interval(s1, s2, 2);
// Case
// s1: [ ... ]
// s2: [ ... ]
s1 = ism.mk(false, false, m_sqrt2, false, false, three, p1);
s2 = ism.mk(false, false, zero, false, false, two, p2);
tst_interval(s1, s2, 1);
// Case
// s1: [ ... ]
// s2: [ ... ] [ ... ]
s1 = ism.mk(false, false, m_two, false, false, two, p1);
s2 = ism.mk(false, false, m_sqrt2, false, false, zero, p2);
s3 = ism.mk(false, false, one, false, false, three, p2);
s2 = ism.mk_union(s2, s3);
tst_interval(s1, s2, 2);
// Case
// s1: [ ... ]
// s2: [ ... ]
s1 = ism.mk(false, false, m_two, false, false, two, p1);
s2 = ism.mk(false, false, two, false, false, three, p2);
tst_interval(s1, s2, 2);
s2 = ism.mk(true, false, two, false, false, three, p2);
tst_interval(s1, s2, 2);
s2 = ism.mk(true, false, two, false, false, three, p1);
tst_interval(s1, s2, 1);
s1 = ism.mk(false, false, m_two, true, false, two, p1);
tst_interval(s1, s2, 2);
s1 = ism.mk(false, false, two, false, false, two, p1);
s2 = ism.mk(false, false, two, false, false, three, p2);
tst_interval(s1, s2, 1);
// Case
// s1: [ ... ] [ ... ]
// s2: [ .. ] [ ... ] [ ... ]
s1 = ism.mk(false, false, m_two, false, false, zero, p1);
s3 = ism.mk(false, false, one, false, false, three, p1);
s1 = ism.mk_union(s1, s3);
s2 = ism.mk(true, true, zero, false, false, m_sqrt2, p2);
tst_interval(s1, s2, 3);
s3 = ism.mk(false, false, one, false, false, sqrt2, p2);
s2 = ism.mk_union(s2, s3);
s3 = ism.mk(false, false, two, true, true, zero, p2);
s2 = ism.mk_union(s2, s3);
tst_interval(s1, s2, 4);
// Case
s1 = ism.mk(true, true, zero, false, false, one, p1);
s2 = ism.mk(true, false, one, true, true, zero, p2);
tst_interval(s1, s2, 2);
s2 = ism.mk(true, false, one, false, false, two, p2);
s3 = ism.mk(false, false, two, true, true, zero, p1);
s2 = ism.mk_union(s2, s3);
tst_interval(s1, s2, 3);
}
static nlsat::interval_set_ref mk_random(nlsat::interval_set_manager & ism, anum_manager & am, int range, int space, int tries, bool minus_inf, bool plus_inf,
nlsat::literal lit) {
static random_gen gen;
SASSERT(range > 0);
SASSERT(space > 0);
nlsat::interval_set_ref r(ism), curr(ism);
scoped_anum lower(am);
scoped_anum upper(am);
int prev = -range + (gen() % (space*4));
if (gen() % 3 == 0 && minus_inf) {
int next = prev + (gen() % space);
bool open = gen() % 2 == 0;
am.set(upper, next);
r = ism.mk(true, true, lower, open, false, upper, lit);
prev = next;
}
for (int i = 0; i < tries; i++) {
int l = prev + (gen() % space);
int u = l + (gen() % space);
bool lower_open = gen() % 2 == 0;
bool upper_open = gen() % 2 == 0;
if ((lower_open || upper_open) && l == u)
u++;
am.set(lower, l);
am.set(upper, u);
curr = ism.mk(lower_open, false, lower, upper_open, false, upper, lit);
r = ism.mk_union(r, curr);
prev = u;
}
if (gen() % 3 == 0 && plus_inf) {
int next = prev + (gen() % space);
bool open = gen() % 2 == 0;
am.set(lower, next);
curr = ism.mk(open, false, lower, true, true, upper, lit);
r = ism.mk_union(r, curr);
}
return r;
}
static void check_subset_result(nlsat::interval_set_ref const & s1,
nlsat::interval_set_ref const & s2,
nlsat::interval_set_ref const & r,
nlsat::literal l1,
nlsat::literal l2) {
nlsat::interval_set_manager ism(s1.m());
nlsat::interval_set_ref tmp(ism);
unsigned num = ism.num_intervals(r);
nlsat::literal_vector lits;
ism.get_justifications(r, lits);
SASSERT(lits.size() <= 2);
for (unsigned i = 0; i < num; i++) {
tmp = ism.get_interval(r, i);
ism.get_justifications(tmp, lits);
SASSERT(lits.size() == 1);
if (lits[0] == l1) {
SASSERT(ism.subset(tmp, s1));
}
else {
SASSERT(lits[0] == l2);
SASSERT(ism.subset(tmp, s2));
}
}
}
static void tst4() {
enable_trace("nlsat_interval");
unsynch_mpq_manager qm;
anum_manager am(qm);
small_object_allocator allocator;
nlsat::interval_set_manager ism(am, allocator);
nlsat::interval_set_ref s1(ism), s2(ism), r(ism);
nlsat::literal l1(1, false);
nlsat::literal l2(2, false);
for (unsigned i = 0; i < 100; i++) {
s1 = mk_random(ism, am, 20, 3, 10, true, true, l1);
s2 = mk_random(ism, am, 20, 3, 10, true, true, l2);
r = tst_interval(s1, s2, 0, false);
check_subset_result(s1, s2, r, l1, l2);
}
for (unsigned i = 0; i < 100; i++) {
s1 = mk_random(ism, am, 200, 100, 20, true, true, l1);
s2 = mk_random(ism, am, 200, 100, 20, true, true, l2);
r = tst_interval(s1, s2, 0, false);
check_subset_result(s1, s2, r, l1, l2);
}
}
static void tst5() {
params_ref ps;
nlsat::solver s(ps);
unsynch_mpq_manager & qm = s.qm();
anum_manager & am = s.am();
nlsat::pmanager & pm = s.pm();
nlsat::assignment as(am);
small_object_allocator allocator;
nlsat::interval_set_manager ism(am, allocator);
nlsat::evaluator ev(as, pm, allocator);
nlsat::var x0, x1;
x0 = pm.mk_var();
x1 = pm.mk_var();
polynomial_ref p(pm);
polynomial_ref _x0(pm), _x1(pm);
_x0 = pm.mk_polynomial(x0);
_x1 = pm.mk_polynomial(x1);
p = (_x0^2) + (_x1^2) - 2;
nlsat::poly * _p[1] = { p.get() };
bool is_even[1] = { false };
nlsat::bool_var b = s.mk_ineq_atom(nlsat::atom::GT, 1, _p, is_even);
nlsat::atom * a = s.bool_var2atom(b);
SASSERT(a != 0);
nlsat::interval_set_ref i(ism);
scoped_anum zero(am);
am.set(zero, 0);
as.set(0, zero);
i = ev.infeasible_intervals(a, true);
std::cout << "1) " << i << "\n";
as.set(1, zero);
i = ev.infeasible_intervals(a, true);
std::cout << "2) " << i << "\n";
}
void tst_nlsat() {
tst5();
tst4();
tst3();
}

711
src/test/no_overflow.cpp Normal file
View file

@ -0,0 +1,711 @@
/*++
Copyright (c) 2009 Microsoft Corporation
Module Name:
no_overflow.cpp
Abstract:
Test non-overflowing checks for arithmetic.
Author:
Yannick Moy (t-yanmoy) 2009-02-17.
Revision History:
--*/
#ifdef _WINDOWS
#include "z3.h"
#include "trace.h"
#include "rational.h"
#define TEST(TEST_NAME, TEST_OUTCOME, NEG_TEST_OUTCOME) \
do { \
if (TEST_NAME != NULL) \
{ \
Z3_push(ctx); \
Z3_assert_cnstr(ctx, TEST_NAME); \
SASSERT(Z3_check(ctx) == TEST_OUTCOME); \
Z3_pop(ctx, 1); \
\
Z3_push(ctx); \
Z3_assert_cnstr(ctx, Z3_mk_not(ctx, TEST_NAME)); \
SASSERT(Z3_check(ctx) == NEG_TEST_OUTCOME); \
Z3_pop(ctx, 1); \
} \
} while (0)
#define TEST_NO_OVERFLOW TEST(test_ovfl, Z3_L_TRUE, Z3_L_FALSE)
#define TEST_OVERFLOW TEST(test_ovfl, Z3_L_FALSE, Z3_L_TRUE)
#define TEST_NO_OVERFLOW_IFF(COND) \
do { \
if (COND) { \
TEST_NO_OVERFLOW; \
} \
else { \
TEST_OVERFLOW; \
} \
} while (0)
#define TEST_NO_UNDERFLOW TEST(test_udfl, Z3_L_TRUE, Z3_L_FALSE)
#define TEST_UNDERFLOW TEST(test_udfl, Z3_L_FALSE, Z3_L_TRUE)
#define TEST_NO_UNDERFLOW_IFF(COND) \
do { \
if (COND) { \
TEST_NO_UNDERFLOW; \
} \
else { \
TEST_UNDERFLOW; \
} \
} while (0)
#define TEST_ANY(TEST_NAME) \
do { \
Z3_push(ctx); \
Z3_assert_cnstr(ctx, TEST_NAME); \
Z3_check(ctx); /* ignore result of check */ \
Z3_pop(ctx, 1); \
} while (0)
#define TEST_ANY_OVERFLOW TEST_ANY(test_ovfl)
#define TEST_ANY_UNDERFLOW TEST_ANY(test_udfl)
Z3_ast mk_min(Z3_context ctx, Z3_sort bv, bool is_signed) {
unsigned bvsize = Z3_get_bv_sort_size(ctx, bv);
if (! is_signed) return Z3_mk_numeral(ctx, "0", bv);
unsigned sz = bvsize - 1;
rational min_bound = power(rational(2), sz);
min_bound.neg();
return Z3_mk_numeral(ctx, min_bound.to_string().c_str(), bv);
}
Z3_ast mk_max(Z3_context ctx, Z3_sort bv, bool is_signed) {
unsigned bvsize = Z3_get_bv_sort_size(ctx, bv);
unsigned sz = is_signed ? bvsize - 1 : bvsize;
rational max_bound = power(rational(2), sz);
--max_bound;
return Z3_mk_numeral(ctx, max_bound.to_string().c_str(), bv);
}
void test_add(unsigned bvsize, bool is_signed) {
TRACE("no_overflow", tout << "test_add: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";);
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize);
Z3_ast min = mk_min(ctx, bv, is_signed);
Z3_ast max = mk_max(ctx, bv, is_signed);
Z3_ast t1;
Z3_ast t2;
Z3_ast test_ovfl;
Z3_ast test_udfl;
t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv);
t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv);
test_ovfl = Z3_mk_bvadd_no_overflow(ctx, t1, t2, is_signed);
test_udfl = is_signed ? Z3_mk_bvadd_no_underflow(ctx, t1, t2) : NULL;
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW_IFF(bvsize == 1 && is_signed);
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW_IFF(! (bvsize == 1 && is_signed));
Z3_pop(ctx, 1);
if (is_signed) {
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW;
TEST_UNDERFLOW;
Z3_pop(ctx, 1);
}
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW_IFF(! is_signed);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW_IFF(bvsize == 1 && is_signed);
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_sub(unsigned bvsize, bool is_signed) {
TRACE("no_overflow", tout << "test_sub: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";);
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize);
Z3_ast min = mk_min(ctx, bv, is_signed);
Z3_ast max = mk_max(ctx, bv, is_signed);
Z3_ast t1;
Z3_ast t2;
Z3_ast test_ovfl;
Z3_ast test_udfl;
t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv);
t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv);
test_ovfl = is_signed ? Z3_mk_bvsub_no_overflow(ctx, t1, t2) : NULL;
test_udfl = Z3_mk_bvsub_no_underflow(ctx, t1, t2, is_signed);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed));
TEST_NO_UNDERFLOW_IFF(is_signed);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW_IFF(is_signed);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW_IFF(bvsize == 1 || is_signed);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed));
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW_IFF(! (bvsize != 1 && is_signed));
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW_IFF(bvsize == 1 && is_signed);
Z3_pop(ctx, 1);
if (is_signed) {
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv)));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
}
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW_IFF(bvsize == 1 && is_signed);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW_IFF(! is_signed);
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_neg(unsigned bvsize) {
TRACE("no_overflow", tout << "test_neg: bvsize = " << bvsize << "\n";);
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize);
Z3_ast min = mk_min(ctx, bv, /* is_signed = */ true);
Z3_ast max = mk_max(ctx, bv, /* is_signed = */ true);
Z3_ast t1;
Z3_ast test_ovfl;
t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv);
test_ovfl = Z3_mk_bvneg_no_overflow(ctx, t1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
TEST_NO_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW_IFF(bvsize != 1);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv)));
TEST_NO_OVERFLOW_IFF(bvsize != 1);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
TEST_NO_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
TEST_OVERFLOW;
Z3_pop(ctx, 1);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_mul(unsigned bvsize, bool is_signed) {
TRACE("no_overflow", tout << "test_mul: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";);
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize);
Z3_ast min = mk_min(ctx, bv, is_signed);
Z3_ast max = mk_max(ctx, bv, is_signed);
Z3_ast t1;
Z3_ast t2;
Z3_ast test_ovfl;
Z3_ast test_udfl;
t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv);
t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv);
test_ovfl = Z3_mk_bvmul_no_overflow(ctx, t1, t2, is_signed);
test_udfl = is_signed ? Z3_mk_bvmul_no_underflow(ctx, t1, t2) : NULL;
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed));
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv)));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW_IFF(! (bvsize == 1 && is_signed));
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
if (is_signed) {
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv)));
TEST_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
}
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW_IFF(! is_signed);
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW;
TEST_NO_UNDERFLOW_IFF(! (bvsize != 1 && is_signed));
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, max));
TEST_NO_OVERFLOW_IFF(bvsize == 1);
TEST_NO_UNDERFLOW;
Z3_pop(ctx, 1);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_div(unsigned bvsize) {
TRACE("no_overflow", tout << "test_div: bvsize = " << bvsize << "\n";);
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize);
Z3_ast min = mk_min(ctx, bv, /* is_signed = */ true);
Z3_ast max = mk_max(ctx, bv, /* is_signed = */ true);
Z3_ast t1;
Z3_ast t2;
Z3_ast test_ovfl;
t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv);
t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv);
test_ovfl = Z3_mk_bvsdiv_no_overflow(ctx, t1, t2);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW_IFF(bvsize != 1);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv)));
TEST_NO_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv)));
TEST_ANY_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "-1", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv)));
TEST_ANY_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "0", bv)));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "0", bv)));
TEST_ANY_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "-1", bv)));
TEST_OVERFLOW;
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
TEST_NO_OVERFLOW_IFF(bvsize != 1);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, min));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW_IFF(bvsize != 1);
Z3_pop(ctx, 1);
Z3_push(ctx);
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, max));
Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, min));
TEST_NO_OVERFLOW;
Z3_pop(ctx, 1);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
typedef Z3_ast (Z3_API *NO_OVFL_ARITH_FUNC)(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed);
typedef Z3_ast (Z3_API *ARITH_FUNC)(Z3_context ctx, Z3_ast t1, Z3_ast t2);
typedef enum { OVFL_FUNC, UDFL_FUNC } overflow_type;
typedef struct {
std::string name;
NO_OVFL_ARITH_FUNC no_overflow_func;
ARITH_FUNC func;
overflow_type type;
int extsize; // negative size indicates size of arguments should be doubled
bool do_unsigned;
bool non_zero; // second argument should not be null (for division)
bool sign_compar; // whether signed comparison should be used even for unsigned operation
} Equivalence_params;
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) {
return Z3_mk_bvsdiv_no_overflow(ctx, t1, t2);
}
Z3_ast Z3_API Z3_mk_bvneg_no_overflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) {
return Z3_mk_bvneg_no_overflow(ctx, t1);
}
Z3_ast Z3_API Z3_mk_bvneg_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2) {
return Z3_mk_bvneg(ctx, t1);
}
Z3_ast Z3_API Z3_mk_bvadd_no_underflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) {
return Z3_mk_bvadd_no_underflow(ctx, t1, t2);
}
Z3_ast Z3_API Z3_mk_bvsub_no_overflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) {
return Z3_mk_bvsub_no_overflow(ctx, t1, t2);
}
Z3_ast Z3_API Z3_mk_bvmul_no_underflow_wrapper(Z3_context ctx, Z3_ast t1, Z3_ast t2, Z3_bool is_signed) {
return Z3_mk_bvmul_no_underflow(ctx, t1, t2);
}
void test_equiv(Equivalence_params params, unsigned bvsize, bool is_signed) {
TRACE("no_overflow", tout << "test_" << params.name << "_equiv: bvsize = " << bvsize << ", is_signed = " << is_signed << "\n";);
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize);
Z3_ast min = mk_min(ctx, bv, is_signed);
Z3_ast max = mk_max(ctx, bv, is_signed);
Z3_ast t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv);
Z3_ast t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv);
Z3_ast real_test = (*params.no_overflow_func)(ctx, t1, t2, is_signed);
Z3_ast cond = NULL;
if (params.non_zero)
{
cond = Z3_mk_not(ctx, Z3_mk_eq(ctx, t2, Z3_mk_int(ctx, 0, bv)));
}
unsigned extsize = params.extsize < 0 ? bvsize : params.extsize;
if (is_signed) {
min = Z3_mk_sign_ext(ctx, extsize, min);
max = Z3_mk_sign_ext(ctx, extsize, max);
t1 = Z3_mk_sign_ext(ctx, extsize, t1);
t2 = Z3_mk_sign_ext(ctx, extsize, t2);
}
else {
min = Z3_mk_zero_ext(ctx, extsize, min);
max = Z3_mk_zero_ext(ctx, extsize, max);
t1 = Z3_mk_zero_ext(ctx, extsize, t1);
t2 = Z3_mk_zero_ext(ctx, extsize, t2);
}
Z3_ast r = (*params.func)(ctx, t1, t2);
Z3_ast check;
if (is_signed) {
check = (params.type == UDFL_FUNC) ? Z3_mk_bvsle(ctx, min, r) : Z3_mk_bvsle(ctx, r, max);
}
else {
if (params.sign_compar)
{
// check with signed comparison for subtraction of unsigned
check = (params.type == UDFL_FUNC) ? Z3_mk_bvsle(ctx, min, r) : Z3_mk_bvsle(ctx, r, max);
}
else
{
check = (params.type == UDFL_FUNC) ? Z3_mk_bvule(ctx, min, r) : Z3_mk_bvule(ctx, r, max);
}
}
Z3_push(ctx);
Z3_ast equiv = Z3_mk_iff(ctx, real_test, check);
if (cond != NULL)
{
equiv = Z3_mk_implies(ctx, cond, equiv);
}
Z3_assert_cnstr(ctx, Z3_mk_not(ctx, equiv));
SASSERT(Z3_check(ctx) == Z3_L_FALSE);
Z3_pop(ctx, 1);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
//void debug_mul() {
//
// unsigned bvsize = 2;
// bool is_signed = true;
//
// Z3_config cfg = Z3_mk_config();
// Z3_context ctx = Z3_mk_context(cfg);
// Z3_sort bv = Z3_mk_bv_sort(ctx, bvsize);
//
// Z3_ast min = mk_min(ctx, bv, is_signed);
// Z3_ast max = mk_max(ctx, bv, is_signed);
// Z3_ast t1;
// Z3_ast t2;
// Z3_ast test_udfl;
//
// t1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"x"), bv);
// t2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"y"), bv);
// test_udfl = Z3_mk_bvmul_no_underflow(ctx, t1, t2);
//
// Z3_push(ctx);
// Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t1, Z3_mk_numeral(ctx, "1", bv)));
// Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv)));
// //TEST_NO_UNDERFLOW;
// Z3_assert_cnstr(ctx, test_udfl);
// SASSERT(Z3_check(ctx) == Z3_TRUE);
// Z3_pop(ctx, 1);
//
// Z3_del_config(cfg);
// Z3_del_context(ctx);
//}
#define BVSIZES 4
#define TESTNUM 3
#define EQUIV_BVSIZES 4
#define EQUIV_TESTNUM 8
typedef void (*TESTFUN)(unsigned bvsize, bool is_signed);
void tst_no_overflow() {
unsigned bvsizes[BVSIZES] = { 1, 16, 32, 42 };
TESTFUN tests[TESTNUM] = { test_add, test_sub, test_mul };
for (int i = 0; i < BVSIZES; ++i) {
for (int j = 0; j < TESTNUM; ++j) {
tests[j](bvsizes[i], /* is_signed = */ true);
tests[j](bvsizes[i], /* is_signed = */ false);
}
test_neg(bvsizes[i]);
test_div(bvsizes[i]);
}
unsigned equiv_bvsizes[EQUIV_BVSIZES] = { 1, 2, 7, 16 };
// before performing the bound test, arguments are extended by a few bits to prevent overflow:
// * 1 is the default
// * 2 is used for subtraction, so that 1 bit is used for the sign event for unsigned subtraction
// * -1 to indicate that the bitsize should be doubled for multiplication
Equivalence_params equiv_tests[EQUIV_TESTNUM] = {
{ "ovfl_add", Z3_mk_bvadd_no_overflow, Z3_mk_bvadd, OVFL_FUNC,
1, /* do_unsigned = */ true, /* non_zero = */ false, /* sign_compar = */ false },
{ "udfl_add", Z3_mk_bvadd_no_underflow_wrapper, Z3_mk_bvadd, UDFL_FUNC,
1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false },
{ "ovfl_sub", Z3_mk_bvsub_no_overflow_wrapper, Z3_mk_bvsub, OVFL_FUNC,
1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false },
{ "udfl_sub", Z3_mk_bvsub_no_underflow, Z3_mk_bvsub, UDFL_FUNC,
2, /* do_unsigned = */ true, /* non_zero = */ false, /* sign_compar = */ true },
{ "ovfl_mul", Z3_mk_bvmul_no_overflow, Z3_mk_bvmul, OVFL_FUNC,
-1, /* do_unsigned = */ true, /* non_zero = */ false, /* sign_compar = */ false },
{ "udfl_mul", Z3_mk_bvmul_no_underflow_wrapper, Z3_mk_bvmul, UDFL_FUNC,
-1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false },
{ "ovfl_div", Z3_mk_bvsdiv_no_overflow_wrapper, Z3_mk_bvsdiv, OVFL_FUNC,
1, /* do_unsigned = */ false, /* non_zero = */ true, /* sign_compar = */ false },
{ "ovfl_neg", Z3_mk_bvneg_no_overflow_wrapper, Z3_mk_bvneg_wrapper, OVFL_FUNC,
1, /* do_unsigned = */ false, /* non_zero = */ false, /* sign_compar = */ false },
};
for (int i = 0; i < EQUIV_BVSIZES; ++i) {
for (int j = 0; j < EQUIV_TESTNUM; ++j) {
test_equiv(equiv_tests[j], equiv_bvsizes[i], /* is_signed = */ true);
if (equiv_tests[j].do_unsigned) {
test_equiv(equiv_tests[j], equiv_bvsizes[i], /* is_signed = */ false);
}
}
}
}
#else
void tst_no_overflow() {
}
#endif

View file

@ -0,0 +1,121 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
object_allocator.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-06-09.
Revision History:
--*/
#include"rational.h"
#include"object_allocator.h"
struct cell {
rational m_coeff;
unsigned m_i;
unsigned m_j;
cell * m_next_row;
cell * m_next_col;
public:
static unsigned g_num_allocated_cells;
static unsigned g_num_deallocated_cells;
static unsigned g_num_recycled_cells;
cell() {
g_num_allocated_cells++;
}
~cell() {
g_num_deallocated_cells++;
}
void reset() {
m_coeff.reset();
g_num_recycled_cells++;
}
};
unsigned cell::g_num_allocated_cells = 0;
unsigned cell::g_num_deallocated_cells = 0;
unsigned cell::g_num_recycled_cells = 0;
typedef object_allocator<cell, true, simple_reset_proc<cell> > cell_allocator;
static void tst1() {
cell_allocator m;
cell * c1 = m.allocate<true>();
cell * c2 = m.allocate<true>();
c1->m_coeff = rational(10);
m.recycle(c1);
cell * c3 = m.allocate<true>();
SASSERT(c3->m_coeff.is_zero());
}
static void tst2() {
cell_allocator m;
SASSERT(m.capacity() >= 2);
cell_allocator::worker_object_allocator m1 = m.get_worker_allocator(0);
cell_allocator::worker_object_allocator m2 = m.get_worker_allocator(1);
m.enable_concurrent(true);
vector<std::pair<cell *, int> > object_coeff_pairs;
unsigned num_resets = 0;
for (unsigned i = 0; i < 100000; i++) {
unsigned idx = rand() % 6;
if (idx < 4) {
cell * c;
if (idx < 2)
c = m1.allocate<true>();
else
c = m2.allocate<true>();
SASSERT(c->m_coeff.is_zero());
int val = rand();
c->m_coeff = rational(val);
object_coeff_pairs.push_back(std::make_pair(c, val));
}
else {
if (!object_coeff_pairs.empty()) {
unsigned idx = rand() % object_coeff_pairs.size();
cell * c = object_coeff_pairs[idx].first;
CTRACE("object_allocator", c->m_coeff != rational(object_coeff_pairs[idx].second), tout << c->m_coeff << " != " << rational(object_coeff_pairs[idx].second) << "\n";);
SASSERT(c->m_coeff == rational(object_coeff_pairs[idx].second));
if (idx < 5)
m1.recycle(c);
else
m2.recycle(c);
object_coeff_pairs.erase(object_coeff_pairs.begin() + idx);
}
}
if (rand() % 5000 == 0) {
m.enable_concurrent(false);
m.reset();
object_coeff_pairs.reset();
m.enable_concurrent(true);
num_resets++;
}
}
TRACE("object_allocator", tout << "num. resets: " << num_resets << "\n";);
}
void tst_object_allocator() {
tst1();
tst2();
TRACE("object_allocator", tout << "num. allocated cells: " << cell::g_num_allocated_cells << "\nnum. deallocated cells: " << cell::g_num_deallocated_cells <<
"\nnum. recycled cells: " << cell::g_num_recycled_cells << "\n";);
SASSERT(cell::g_num_allocated_cells == cell::g_num_deallocated_cells);
}

201
src/test/old_interval.cpp Normal file
View file

@ -0,0 +1,201 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
interval.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-12-10.
Revision History:
--*/
#include"old_interval.h"
static void tst1() {
ext_numeral inf(true);
ext_numeral minus_inf(false);
ext_numeral zero(0);
SASSERT(ext_numeral(10) + ext_numeral(3) == ext_numeral(13));
SASSERT(inf + zero == inf);
SASSERT(minus_inf + zero == minus_inf);
SASSERT(minus_inf + ext_numeral(3) == minus_inf);
SASSERT(inf + inf == inf);
SASSERT(minus_inf + minus_inf == minus_inf);
SASSERT(minus_inf + ext_numeral(10) == minus_inf);
SASSERT(minus_inf + ext_numeral(-10) == minus_inf);
SASSERT(inf + ext_numeral(10) == inf);
SASSERT(inf + ext_numeral(-10) == inf);
SASSERT(ext_numeral(10) - ext_numeral(3) == ext_numeral(7));
SASSERT(inf - zero == inf);
SASSERT(minus_inf - zero == minus_inf);
SASSERT(minus_inf - ext_numeral(3) == minus_inf);
SASSERT(inf - minus_inf == inf);
SASSERT(minus_inf - inf == minus_inf);
SASSERT(zero - minus_inf == inf);
SASSERT(zero - inf == minus_inf);
SASSERT(ext_numeral(-10) - minus_inf == inf);
SASSERT(ext_numeral(10) - minus_inf == inf);
SASSERT(ext_numeral(-10) - inf == minus_inf);
SASSERT(ext_numeral(10) - inf == minus_inf);
SASSERT(ext_numeral(10) * inf == inf);
SASSERT(ext_numeral(-10) * inf == minus_inf);
SASSERT(zero * inf == zero);
SASSERT(zero * minus_inf == zero);
SASSERT(zero * ext_numeral(10) == zero);
SASSERT(ext_numeral(10) * ext_numeral(-20) == ext_numeral(-200));
SASSERT(ext_numeral(3) * ext_numeral(2) == ext_numeral(6));
SASSERT(inf * inf == inf);
SASSERT(inf * minus_inf == minus_inf);
SASSERT(minus_inf * minus_inf == inf);
SASSERT(minus_inf * inf == minus_inf);
SASSERT(minus_inf * ext_numeral(10) == minus_inf);
SASSERT(minus_inf * ext_numeral(-10) == inf);
SASSERT(minus_inf < inf);
SASSERT(!(inf < minus_inf));
SASSERT(minus_inf < ext_numeral(10));
SASSERT(ext_numeral(-3) < inf);
SASSERT(ext_numeral(-10) < ext_numeral(4));
SASSERT(ext_numeral(2) < ext_numeral(10));
SASSERT(!(inf < ext_numeral(30)));
SASSERT(!(ext_numeral(10) < minus_inf));
SASSERT(!(inf < inf));
SASSERT(!(minus_inf < minus_inf));
SASSERT(!(zero < zero));
SASSERT(!(ext_numeral(10) < ext_numeral(10)));
SASSERT(inf > minus_inf);
SASSERT(inf > zero);
SASSERT(inf > ext_numeral(10));
SASSERT(ext_numeral(10) > minus_inf);
SASSERT(zero > minus_inf);
SASSERT(!(zero > inf));
SASSERT(!(minus_inf > inf));
SASSERT(inf >= minus_inf);
SASSERT(inf >= inf);
SASSERT(minus_inf >= minus_inf);
SASSERT(inf >= zero);
SASSERT(zero >= minus_inf);
SASSERT(inf <= inf);
SASSERT(minus_inf <= minus_inf);
SASSERT(zero <= inf);
SASSERT(minus_inf <= zero);
ext_numeral val(10);
val.neg();
SASSERT(val == ext_numeral(-10));
val = inf;
val.neg();
SASSERT(val == minus_inf);
val.neg();
SASSERT(val == inf);
SASSERT(minus_inf.sign());
SASSERT(!zero.sign());
SASSERT(!inf.sign());
SASSERT(ext_numeral(-10).sign());
SASSERT(!ext_numeral(10).sign());
SASSERT(inf.is_infinite());
SASSERT(minus_inf.is_infinite());
SASSERT(!zero.is_infinite());
SASSERT(!ext_numeral(10).is_infinite());
SASSERT(!inf.is_zero());
SASSERT(!minus_inf.is_zero());
SASSERT(zero.is_zero());
SASSERT(!ext_numeral(10).is_zero());
}
class interval_tester {
v_dependency_manager m;
interval singleton(int i) { return interval(m, rational(i)); }
interval all() { return interval(m); }
interval l(int i, bool o = false, int idx = 0) { return interval(m, rational(i), o, true, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx))); }
interval r(int i, bool o = false, int idx = 0) { return interval(m, rational(i), o, false, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx))); }
interval b(int l, int u, bool lo = false, bool uo = false, int idx_l = 0, int idx_u = 0) {
return interval(m, rational(l), lo, idx_l == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx_l)), rational(u), uo, idx_u == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx_u)));
}
void bugs() {
interval r1 = l(0);
interval r2 = b(-1, 0, false, true);
r1 *= r2;
}
void tst1() {
std::cerr << singleton(10) << "\n";
std::cerr << all() << "\n";
std::cerr << l(-10) << "\n";
std::cerr << r(10) << "\n";
std::cerr << l(-10, true) << "\n";
std::cerr << r(10, true) << "\n";
std::cerr << b(2, 10) << "\n";
std::cerr << wd(b(-5, 5, true, false, 1, 2) * b(-5, 5, false, true, 3, 4)) << "\n";
std::cerr << wd(l(2, false, 1) / b(2, 6, false, false, 2, 3)) << "\n";
std::cerr << wd(expt(b(-2, 3, true, false, 1, 2), 2)) << "\n";
std::cerr << wd(expt(b(-4, 3, true, false, 1, 2), 2)) << "\n";
std::cerr << wd(expt(b(2, 4, true, false, 1, 2), 2)) << "\n";
std::cerr << wd(expt(b(0, 3, true, false, 1, 2), 2)) << "\n";
std::cerr << wd(expt(b(-4, -2, true, false, 1, 2), 2)) << "\n";
std::cerr << b(2, 10, false, false, 1, 2) << " * " << l(10, false, 3).inv() << " = " << wd(b(2, 10, false, false, 1, 2) / l(10, false, 3)) << "\n";
std::cerr << b(-2, -1, false, true) << " * " << b(-3,0) << " = "; std::cerr.flush();
std::cerr << (b(-2, -1, false, true) * b(-3,0)) << "\n";
std::cerr << b(1, 2, true, false) << " * " << b(0,3) << " = "; std::cerr.flush();
std::cerr << (b(1, 2, true, false) * b(0,3)) << "\n";
std::cerr << b(1, 2, true, true) << " * " << b(-3,0) << " = "; std::cerr.flush();
std::cerr << (b(1, 2, true, true) * b(-3,0)) << "\n";
std::cerr << b(10,20) << " / " << b(0,1,true,false) << " = "; std::cerr.flush();
std::cerr << (b(10,20)/b(0,1,true,false)) << "\n";
std::cerr << (b(10,20)/b(0,2,true,false)) << "\n";
}
public:
void run() {
bugs();
tst1();
}
};
#include"basic_interval.h"
#include"mpz.h"
#include"scoped_numeral.h"
static void tst2() {
typedef basic_interval_manager<unsynch_mpz_manager, false> mpzi_manager;
typedef mpzi_manager::interval mpzi;
typedef mpzi_manager::scoped_interval scoped_mpzi;
unsynch_mpz_manager nm;
mpzi_manager m(nm);
scoped_mpzi x(m), y(m), z(m);
m.set(x, mpz(1), mpz(2));
m.set(y, mpz(-2), mpz(3));
m.add(x, y, z);
std::cout << "x: " << x << ", y: " << y << ", z: " << z << "\n";
SASSERT(nm.eq(z.lower(), mpz(-1)));
SASSERT(nm.eq(z.upper(), mpz(5)));
m.mul(x, y, z);
std::cout << "x: " << x << ", y: " << y << ", z: " << z << "\n";
SASSERT(nm.eq(z.lower(), mpz(-4)));
SASSERT(nm.eq(z.upper(), mpz(6)));
}
void tst_old_interval() {
tst2();
enable_trace("interval_bug");
interval_tester tester;
tester.run();
tst1();
}

74
src/test/optional.cpp Normal file
View file

@ -0,0 +1,74 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_optional.cpp
Abstract:
Test optional module
Author:
Leonardo de Moura (leonardo) 2006-09-29.
Revision History:
--*/
#include"trace.h"
#include"debug.h"
#include"optional.h"
static void tst1() {
optional<int> v;
SASSERT(!v);
SASSERT(v == false);
v = 10;
SASSERT(v);
SASSERT(*v == 10);
TRACE("optional", tout << sizeof(v) << "\n";);
}
struct OptFoo {
int m_x;
int m_y;
OptFoo(int x, int y):m_x(x), m_y(y) {
TRACE("optional", tout << "OptFoo created: " << m_x << " : " << m_y << "\n";);
}
~OptFoo() {
TRACE("optional", tout << "OptFoo deleted: " << m_x << " : " << m_y << "\n";);
}
};
static void tst2() {
optional<OptFoo> v;
SASSERT(!v);
v = OptFoo(10, 20);
SASSERT(v->m_x == 10);
SASSERT(v->m_y == 20);
v = OptFoo(200, 300);
SASSERT(v->m_x == 200);
SASSERT(v->m_y == 300);
TRACE("optional", tout << sizeof(v) << "\n";);
}
static void tst3() {
optional<int *> v;
SASSERT(!v);
int x = 10;
v = &x;
SASSERT(v);
SASSERT(*v == &x);
TRACE("optional", tout << sizeof(v) << "\n";);
SASSERT(*(*v) == 10);
}
void tst_optional() {
tst1();
tst2();
tst3();
}

58
src/test/par_dll.cpp Normal file
View file

@ -0,0 +1,58 @@
#include "z3.h"
#include "windows.h"
class thread_check {
CRITICAL_SECTION m_cs;
static DWORD __stdcall do_check(LPVOID _this) {
thread_check* th = static_cast<thread_check*>(_this);
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg,"MODEL","true");
Z3_context ctx = Z3_mk_context(cfg);
Z3_parse_smtlib_string(ctx, "(benchmark b :logic QF_UF :extrafuns ((f U U) (x U)) :formula (= (f x) x))", 0, 0, 0, 0, 0, 0);
Z3_ast f = Z3_get_smtlib_formula(ctx, 0);
Z3_assert_cnstr(ctx, f);
Z3_model m = 0;
Z3_lbool r = Z3_check_and_get_model(ctx,&m);
EnterCriticalSection(&th->m_cs);
printf("%d\n", r);
LeaveCriticalSection(&th->m_cs);
if (m) {
Z3_del_model(ctx, m);
}
return 0;
}
public:
thread_check() {
InitializeCriticalSection(&m_cs);
}
~thread_check() {
DeleteCriticalSection(&m_cs);
}
void do_checks(unsigned num_threads) {
HANDLE* handles = new HANDLE[num_threads];
for (unsigned i = 0; i < num_threads; ++i) {
HANDLE hThread = CreateThread(NULL, 0, &thread_check::do_check, this, 0, 0);
handles[i] = hThread;
}
WaitForMultipleObjects(num_threads, handles, TRUE, INFINITE);
for (unsigned i = 0; i < num_threads; ++i) {
CloseHandle(handles[i]);
}
delete[] handles;
}
};
extern "C"
__declspec(dllexport) int ChessTestRun() {
thread_check tc;
tc.do_checks(2);
return 0;
}

70
src/test/parallel.cpp Normal file
View file

@ -0,0 +1,70 @@
#ifdef _WINDOWS
#include "z3.h"
#include "z3_private.h"
#include <iostream>
#include "util.h"
#include "trace.h"
#include <map>
#include "trace.h"
#include "vector.h"
#include "buffer.h"
#undef ARRAYSIZE
#include "windows.h"
class thread_check {
CRITICAL_SECTION m_cs;
static DWORD __stdcall do_check(LPVOID _this) {
thread_check* th = static_cast<thread_check*>(_this);
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg,"MODEL","true");
Z3_context ctx = Z3_mk_context(cfg);
Z3_parse_smtlib_string(ctx, "(benchmark b :logic QF_UF :extrafuns ((f U U) (x U)) :formula (= (f x) x))", 0, 0, 0, 0, 0, 0);
Z3_ast f = Z3_get_smtlib_formula(ctx, 0);
Z3_assert_cnstr(ctx, f);
Z3_model m = 0;
Z3_lbool r = Z3_check_and_get_model(ctx,&m);
EnterCriticalSection(&th->m_cs);
printf("%d\n", r);
LeaveCriticalSection(&th->m_cs);
if (m) {
Z3_del_model(ctx, m);
}
return 0;
}
public:
thread_check() {
InitializeCriticalSection(&m_cs);
}
~thread_check() {
DeleteCriticalSection(&m_cs);
}
void do_checks(unsigned num_threads) {
ptr_buffer<void> handles;
for (unsigned i = 0; i < num_threads; ++i) {
HANDLE hThread = CreateThread(NULL, 0, &thread_check::do_check, this, 0, 0);
handles.push_back(hThread);
}
WaitForMultipleObjects(handles.size(), handles.c_ptr(), TRUE, INFINITE);
for (unsigned i = 0; i < handles.size(); ++i) {
CloseHandle(handles[i]);
}
}
};
void tst_parallel() {
thread_check tc;
tc.do_checks(2);
}
#else
void tst_parallel() {
}
#endif

314
src/test/parray.cpp Normal file
View file

@ -0,0 +1,314 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
parray.cpp
Abstract:
Test persistent arrays.
Author:
Leonardo de Moura (leonardo) 2011-02-23.
Revision History:
--*/
#include"parray.h"
#include"small_object_allocator.h"
#include"ast.h"
template<bool PRESERVE_ROOTS>
struct int_parray_config {
typedef int value;
typedef dummy_value_manager<int> value_manager;
typedef small_object_allocator allocator;
static const bool ref_count = false;
static const bool preserve_roots = PRESERVE_ROOTS;
static const unsigned max_trail_sz = 8;
static const unsigned factor = 2;
};
template<bool PRESERVE_ROOTS>
static void tst1() {
typedef parray_manager<int_parray_config<PRESERVE_ROOTS> > int_parray_manager;
typedef typename int_parray_manager::ref int_array;
dummy_value_manager<int> vm;
small_object_allocator a;
int_parray_manager m(vm, a);
int_array a1;
int_array a2;
int_array a3;
m.mk(a1);
SASSERT(m.size(a1) == 0);
m.push_back(a1, 10, a2);
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";);
SASSERT(m.size(a1) == 0);
SASSERT(m.size(a2) == 1);
m.push_back(a1, 20, a1);
m.push_back(a1, 30, a1);
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";);
SASSERT(m.get(a1, 0) == 20);
SASSERT(m.get(a1, 1) == 30);
SASSERT(m.get(a2, 0) == 10);
SASSERT(m.size(a1) == 2);
SASSERT(m.size(a2) == 1);
SASSERT(m.size(a3) == 0);
m.push_back(a2, 100, a3);
SASSERT(m.size(a3) == 2);
SASSERT(m.get(a3, 0) == 10);
SASSERT(m.get(a3, 1) == 100);
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";);
m.push_back(a2, 50);
SASSERT(m.get(a2, 0) == 10);
SASSERT(m.get(a2, 1) == 50);
SASSERT(m.size(a2) == 2);
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";);
m.del(a1);
m.del(a2);
m.del(a3);
}
template<bool PRESERVE_ROOTS>
static void tst2() {
typedef parray_manager<int_parray_config<PRESERVE_ROOTS> > int_parray_manager;
typedef typename int_parray_manager::ref int_array;
TRACE("parray", tout << "tst2\n";);
dummy_value_manager<int> vm;
small_object_allocator a;
int_parray_manager m(vm, a);
int_array a1;
int_array a2;
for (unsigned i = 0; i < 100; i++)
m.push_back(a1, i);
SASSERT(m.size(a1) == 100);
m.push_back(a1, 100, a2);
for (unsigned i = 0; i < 10; i++)
m.push_back(a2, i+101);
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";);
SASSERT(m.get(a1, 0) == 0);
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";);
for (unsigned i = 0; i < m.size(a1); i++) {
SASSERT(m.get(a1, i) == i);
}
for (unsigned i = 0; i < m.size(a2); i++) {
SASSERT(m.get(a2, i) == i);
}
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";);
m.unshare(a1);
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";);
m.del(a1);
m.del(a2);
}
template<bool PRESERVE_ROOTS>
static void tst3() {
typedef parray_manager<int_parray_config<PRESERVE_ROOTS> > int_parray_manager;
typedef typename int_parray_manager::ref int_array;
TRACE("parray", tout << "tst3\n";);
dummy_value_manager<int> vm;
small_object_allocator a;
int_parray_manager m(vm, a);
int_array a1;
int_array a2;
int_array a3;
int_array a4;
for (unsigned i = 0; i < 20; i++)
m.push_back(a1, i);
SASSERT(m.size(a1) == 20);
m.set(a1, 0, 1, a2);
for (unsigned i = 1; i < 20; i++) {
if (i == 6) {
m.copy(a2, a3);
m.pop_back(a3);
m.pop_back(a3);
m.push_back(a3, 40);
}
m.set(a2, i, i+1);
}
m.pop_back(a2, a4);
m.pop_back(a4);
m.push_back(a4, 30);
for (unsigned i = 0; i < 20; i++) {
SASSERT(m.get(a2, i) == i+1);
}
TRACE("parray",
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";
m.display_info(tout, a4); tout << "\n";
);
SASSERT(m.get(a1, 10) == 10);
TRACE("parray",
tout << "after rerooting...\n";
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";
m.display_info(tout, a4); tout << "\n";
);
SASSERT(m.size(a1) == 20);
SASSERT(m.size(a2) == 20);
SASSERT(m.size(a3) == 19);
SASSERT(m.size(a4) == 19);
for (unsigned i = 0; i < 20; i++) {
SASSERT(m.get(a1, i) == i);
SASSERT(m.get(a2, i) == i+1);
SASSERT(i >= 18 || m.get(a4, i) == i+1);
SASSERT(i >= 6 || m.get(a3, i) == i+1);
SASSERT(!(6 <= i && i <= 17) || m.get(a3, i) == i);
}
SASSERT(m.get(a4, 18) == 30);
SASSERT(m.get(a3, 18) == 40);
TRACE("parray",
tout << "after many gets...\n";
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";
m.display_info(tout, a4); tout << "\n";
);
m.unshare(a1);
TRACE("parray",
tout << "after unshare...\n";
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";
m.display_info(tout, a4); tout << "\n";
);
m.reroot(a4);
TRACE("parray",
tout << "after reroot...\n";
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";
m.display_info(tout, a4); tout << "\n";
);
m.unshare(a2);
TRACE("parray",
tout << "after second unshare...\n";
m.display_info(tout, a1); tout << "\n";
m.display_info(tout, a2); tout << "\n";
m.display_info(tout, a3); tout << "\n";
m.display_info(tout, a4); tout << "\n";
);
m.del(a1);
m.del(a2);
m.del(a3);
m.del(a4);
}
#if 0
// Moved to ast.cpp
struct expr_array_config {
typedef expr * value;
typedef ast_manager value_manager;
typedef small_object_allocator allocator;
static const bool ref_count = true;
static const bool preserve_roots = true;
static const unsigned max_trail_sz = 8;
static const unsigned factor = 2;
};
typedef parray_manager<expr_array_config> expr_array_manager;
typedef expr_array_manager::ref expr_array;
static void tst4() {
TRACE("parray", tout << "tst4\n";);
ast_manager m;
expr_array_manager m2(m, m.get_allocator());
expr_array a1;
expr_array a2;
expr * v0 = m.mk_var(0, m.mk_bool_sort());
expr * v1 = m.mk_var(1, m.mk_bool_sort());
expr * v2 = m.mk_var(2, m.mk_bool_sort());
expr * v3 = m.mk_var(3, m.mk_bool_sort());
m2.push_back(a1, v0);
m2.push_back(a1, v1);
m2.push_back(a1, v2, a2);
m2.push_back(a1, v3);
m2.push_back(a2, v2);
m2.pop_back(a1);
TRACE("parray",
m2.display_info(tout, a1); tout << "\n";
m2.display_info(tout, a2); tout << "\n";
);
m2.reroot(a1);
TRACE("parray",
m2.display_info(tout, a1); tout << "\n";
m2.display_info(tout, a2); tout << "\n";
);
m2.del(a1);
m2.del(a2);
}
#endif
static void tst5() {
ast_manager m;
expr_array a1;
expr_array a2;
m.mk(a1);
for (unsigned i = 0; i < 100; i++) {
m.push_back(a1, m.mk_var(i, m.mk_bool_sort()));
}
unsigned long long mem = memory::get_max_used_memory();
std::cout << "max. heap size: " << static_cast<double>(mem)/static_cast<double>(1024*1024) << " Mbytes\n";
m.copy(a1, a2);
for (unsigned i = 0; i < 1000000; i++) {
m.set(a1, i % 100, m.mk_var(rand() % 100, m.mk_bool_sort()));
}
mem = memory::get_max_used_memory();
std::cout << "max. heap size: " << static_cast<double>(mem)/static_cast<double>(1024*1024) << " Mbytes\n";
m.del(a2);
m.del(a1);
}
void tst_parray() {
// enable_trace("parray_mem");
tst1<true>();
tst2<true>();
tst3<true>();
tst1<false>();
tst2<false>();
tst3<false>();
// tst4();
tst5();
}

84
src/test/permutation.cpp Normal file
View file

@ -0,0 +1,84 @@
/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
permutation.cpp
Abstract:
Simple abstraction for managing permutations.
Author:
Leonardo de Moura (leonardo) 2012-01-04
Revision History:
--*/
#include"permutation.h"
#include"util.h"
#include"vector.h"
using namespace std;
void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const * p, unsigned * target) {
for (unsigned i = 0; i < sz; i++) {
target[i] = src[p[i]];
}
}
static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) {
unsigned_vector data;
unsigned_vector p;
unsigned_vector new_data;
data.resize(sz);
p.resize(sz);
new_data.resize(sz);
random_gen g;
for (unsigned i = 0; i < sz; i++)
p[i] = i;
// fill data with random numbers
for (unsigned i = 0; i < sz; i++)
data[i] = g() % max;
for (unsigned k = 0; k < num_tries; k ++) {
shuffle(p.size(), p.c_ptr(), g);
// std::cout << "p: "; display(std::cout, p.begin(), p.end()); std::cout << "\n";
// std::cout << "data: "; display(std::cout, data.begin(), data.end()); std::cout << "\n";
apply_permutation_copy(sz, data.c_ptr(), p.c_ptr(), new_data.c_ptr());
apply_permutation(sz, data.c_ptr(), p.c_ptr());
// std::cout << "data: "; display(std::cout, data.begin(), data.end()); std::cout << "\n";
for (unsigned i = 0; i < 0; i++)
SASSERT(data[i] == new_data[i]);
}
}
void tst_permutation() {
tst1(10, 1000, 5);
tst1(10, 1000, 1000);
tst1(10, 1000, UINT_MAX);
tst1(100, 1000, 33);
tst1(100, 1000, 1000);
tst1(100, 1000, UINT_MAX);
tst1(1000, 1000, 121);
tst1(1000, 1000, 1000);
tst1(1000, 1000, UINT_MAX);
tst1(33, 1000, 121);
tst1(33, 1000, 1000);
tst1(33, 1000, UINT_MAX);
tst1(121, 1000, 121);
tst1(121, 1000, 1000);
tst1(121, 1000, UINT_MAX);
for (unsigned i = 0; i < 1000; i++) {
tst1(1000, 2, 333);
tst1(1000, 2, 10000);
tst1(1000, 2, UINT_MAX);
}
random_gen g;
for (unsigned i = 0; i < 100000; i++) {
unsigned sz = (g() % 131) + 1;
tst1(sz, 1, sz*2);
tst1(sz, 1, UINT_MAX);
tst1(sz, 1, sz/2 + 1);
}
}

1850
src/test/polynomial.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,742 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
polynomial_factorization.cpp
Abstract:
Testing of factorization.
Author:
Dejan (t-dejanj) 2011-11-29
Notes:
--*/
#include"upolynomial_factorization_int.h"
#include"timeit.h"
#include"polynomial.h"
#if 0
#include"polynomial_factorization.h"
#endif
using namespace std;
// some prime numbers
unsigned primes[] = {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29
};
// [i,l]: how many factors the Knuth example has over p_i, when i = 0 it's Z, p_1 = 2, for l=0 distinct, for l = 1 total
unsigned knuth_factors[2][11] = {
// x^8 + x^6 + 10*x^4 + 10*x^3 + 8*x^2 + 2*x + 8
{2, 2, 3, 3, 2, 3, 1, 4, 3, 1, 1},
{8, 2, 3, 3, 2, 3, 1, 4, 3, 1, 1},
};
// [k,l,i]: how many factors the S_k has over p_i, when i = 0 it's Z, p_1 = 2, for l=0 distinct, for l = 1 total
unsigned swinnerton_dyer_factors[5][2][11] = {
// S1 = (x^2) - 2
{
// 2, 3, 5, 7,11,13,17,19,23,29, Z
{1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1},
{2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1}
},
// S2 = (x^4) - 10*(x^2) + 1
{
{1, 1, 2, 2, 2, 2, 2, 2, 4, 2, 1},
{4, 2, 2, 2, 2, 2, 2, 2, 4, 2, 1}
},
// S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576
{
{1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 1},
{8, 6, 4, 4, 4, 4, 4, 4, 4, 4, 1}
},
// S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225
{
{1, 4, 3, 4, 8, 8, 8, 8, 8, 8, 1},
{16, 12, 10, 8, 8, 8, 8, 8, 8, 8, 1}
},
// SA = S1*S2*S3*S4
{
//p = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, Z
{ 2, 6, 3, 6, 15, 11, 16, 15, 18, 15, 1},
{30, 21, 17, 16, 15, 15, 16, 15, 18, 15, 1}
}
};
int random_polynomial[20][2][11] = {
{
// 3*x^10 + 2*x^9 + 4*x^8 + 4*x^7 + 4*x^6 + x^5 + 3*x^2 + 3*x
{ 4, 3, 4, 4, 3, 4, 4, 4, 3, 4, 2 },
{ 7, 7, 4, 4, 3, 4, 4, 4, 3, 4, 2 },
},
{
// 4*x^9 + 4*x^8 + x^7 + x^6 + 2*x^5 + 3*x^4 + 4*x^2 + 4*x
{ 2, 2, 3, 3, 4, 2, 5, 3, 4, 2, 2 },
{ 5, 2, 3, 3, 4, 2, 5, 3, 5, 2, 2 },
},
{
// 3*x^10 + 4*x^9 + 3*x^8 + x^6 + 4*x^5 + 4*x^4 + x^2
{ 3, 2, 4, 4, 5, 3, 4, 2, 4, 5, 2 },
{ 6, 3, 5, 5, 6, 4, 5, 3, 5, 7, 3 },
},
{
// x^10 + 4*x^9 + x^8 + 3*x^7 + 3*x^4 + 3*x^3 + x^2 + 4*x
{ 3, 4, 4, 3, 3, 3, 4, 4, 5, 3, 2 },
{ 8, 4, 4, 3, 3, 3, 4, 4, 5, 3, 2 },
},
{
// x^9 + 2*x^8 + 3*x^7 + x^6 + 2*x^5 + 4*x^4 + 3*x^2
{ 3, 3, 3, 3, 4, 4, 4, 3, 3, 4, 2 },
{ 5, 6, 4, 5, 5, 6, 5, 4, 4, 5, 3 },
},
{
// x^10 + x^9 + 4*x^7 + x^6 + 3*x^5 + x^4 + x^3 + x
{ 3, 2, 3, 3, 3, 5, 3, 2, 4, 4, 2 },
{ 3, 2, 3, 3, 3, 5, 3, 2, 4, 4, 2 },
},
{
// 4*x^10 + 4*x^9 + x^8 + 2*x^7 + 3*x^6 + 4*x^5 + 3*x^4 + x^3 + 2*x^2 + 4*x
{ 3, 3, 2, 5, 3, 4, 2, 4, 5, 5, 2 },
{ 5, 3, 2, 5, 3, 4, 2, 4, 5, 5, 2 },
},
{
// 3*x^10 + 4*x^9 + 3*x^8 + x^7 + x^6 + 2*x^5 + x^4 + 2*x^3 + 2*x^2 + x
{ 3, 4, 6, 4, 4, 4, 4, 6, 6, 4, 3 },
{ 4, 4, 7, 4, 4, 4, 4, 6, 6, 4, 3 },
},
{
// 4*x^10 + x^9 + x^7 + 2*x^5 + 3*x^3 + x^2 + 4*x
{ 3, 3, 3, 4, 4, 5, 4, 5, 2, 4, 2 },
{ 4, 4, 3, 4, 4, 5, 4, 5, 2, 4, 2 },
},
{
// x^10 + 3*x^9 + 3*x^8 + x^7 + 3*x^6 + 3*x^5 + 3*x^4 + x^2 + 3*x
{ 2, 3, 4, 4, 3, 3, 4, 3, 3, 4, 2 },
{ 2, 4, 5, 4, 3, 3, 4, 3, 3, 4, 2 },
},
{
// x^10 + x^9 + 2*x^8 + x^7 + 4*x^6 + 2*x^5 + 3*x^4 + 4*x^3 + x^2 + 2*x
{ 3, 4, 4, 3, 3, 3, 3, 4, 5, 3, 2 },
{ 4, 4, 4, 3, 3, 3, 3, 4, 5, 3, 2 },
},
{
// 3*x^9 + x^8 + 3*x^7 + 3*x^6 + x^5 + 2*x^4 + 4*x^3 + 4*x^2 + 3*x
{ 4, 3, 3, 3, 5, 3, 6, 4, 2, 2, 2 },
{ 6, 4, 3, 3, 5, 3, 6, 4, 2, 2, 2 },
},
{
// 2*x^10 + 3*x^9 + 2*x^8 + 4*x^7 + x^6 + 3*x^5 + 2*x^3 + 3*x^2 + 2*x + 2
{ 3, 3, 3, 5, 4, 5, 6, 7, 4, 6, 3 },
{ 8, 4, 3, 7, 4, 5, 6, 7, 4, 7, 3 },
},
{
// 3*x^10 + x^9 + 4*x^8 + 2*x^7 + x^6 + 4*x^5 + x^4 + 3*x^3 + x + 2
{ 3, 3, 3, 2, 6, 4, 4, 4, 3, 3, 2 },
{ 3, 3, 3, 2, 6, 5, 4, 5, 3, 3, 2 },
},
{
// 4*x^10 + 2*x^9 + x^8 + x^6 + x^5 + 3*x^4 + 4*x^3 + x^2 + x
{ 3, 4, 2, 4, 4, 4, 4, 2, 3, 3, 2 },
{ 6, 4, 2, 4, 4, 4, 4, 2, 3, 3, 2 },
},
{
// 4*x^10 + 2*x^7 + 4*x^6 + 2*x^3 + x
{ 1, 3, 3, 3, 4, 4, 4, 3, 3, 2, 2 },
{ 1, 3, 3, 3, 4, 4, 4, 3, 3, 2, 2 },
},
{
// 4*x^10 + x^9 + x^8 + 4*x^7 + 4*x^4 + 2*x^2 + x + 4
{ 3, 4, 2, 5, 3, 6, 3, 6, 3, 3, 2 },
{ 3, 6, 2, 5, 3, 6, 3, 6, 3, 3, 2 },
},
{
// 3*x^10 + 2*x^8 + x^7 + x^6 + 3*x^4 + 3*x^3 + 4*x^2 + 3*x
{ 4, 3, 4, 3, 3, 3, 2, 4, 4, 3, 2 },
{ 5, 4, 4, 3, 3, 3, 2, 4, 4, 3, 2 },
},
{
// x^10 + 2*x^9 + 2*x^6 + 4*x^3 + 4*x^2
{ 1, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2 },
{ 10, 3, 3, 4, 4, 6, 4, 4, 4, 4, 3 },
},
{
// x^10 + 2*x^9 + 2*x^8 + 4*x^7 + 4*x^6 + x^5 + x^3 + x^2 + 3*x
{ 2, 4, 2, 3, 3, 3, 5, 5, 6, 2, 2 },
{ 2, 5, 2, 3, 3, 3, 5, 5, 6, 2, 2 },
}
};
static void tst_square_free_finite_1() {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
// example from Knuth, p. 442
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
// polynomials \prod_{i < p} (x - i)^i
for (unsigned prime_i = 0; prime_i < 5; ++ prime_i)
{
int p = primes[prime_i];
// make the polynomial
polynomial_ref f(pm);
f = x - 1;
for (int i = 2; i < p; ++ i) {
f = f*((x + (-i))^i);
}
cout << "Factoring " << f << " into square-free over Z_" << p << endl;
// convert to univariate over Z_p
upolynomial::zp_manager upm(nm);
upm.set_zp(p);
upolynomial::numeral_vector f_u;
upm.to_numeral_vector(f, f_u);
cout << "Input: "; upm.display(cout, f_u); cout << endl;
// factor it
upolynomial::zp_factors f_factors(upm);
cout << "Start: " << f_factors << endl;
upolynomial::zp_square_free_factor(upm, f_u, f_factors);
upolynomial::numeral_vector mult;
f_factors.multiply(mult);
cout << "Multiplied: "; upm.display(cout, mult); cout << endl;
SASSERT(upm.eq(mult, f_u));
// remove the temps
upm.reset(f_u);
upm.reset(mult);
}
}
static void tst_factor_finite_1() {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
// example from Knuth, p. 442
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
polynomial_ref K(pm);
K = (x^8) + (x^6) + 10*(x^4) + 10*(x^3) + 8*(x^2) + 2*x + 8;
// factor them for all the prime numbers
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i)
{
// make the Z_p
unsigned prime = primes[prime_i];
upolynomial::zp_manager upm(nm);
upm.set_zp(prime);
// make the polynomial in Z_p
upolynomial::numeral_vector K_u;
upm.to_numeral_vector(K, K_u);
cout << "Factoring " << K << "("; upm.display(cout, K_u); cout << ") in Z_" << prime << endl;
cout << "Expecting " << knuth_factors[0][prime_i] << " distinct factors, " << knuth_factors[1][prime_i] << " total" << endl;
// factor it
upolynomial::zp_factors factors(upm);
bool factorized = upolynomial::zp_factor(upm, K_u, factors);
// check the result
unsigned distinct = factors.distinct_factors();
unsigned total = factors.total_factors();
cout << "Got " << factors << endl;
cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl;
SASSERT(knuth_factors[0][prime_i] == distinct);
SASSERT(knuth_factors[1][prime_i] == total);
upolynomial::numeral_vector multiplied;
factors.multiply(multiplied);
SASSERT(upm.eq(K_u, multiplied));
upm.reset(multiplied);
// remove the temp
upm.reset(K_u);
}
}
static void tst_factor_finite_2() {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
// Swinnerton-Dyer polynomials (irreducible, modular factors of degree at most 2)
polynomial_ref S1 = (x^2) - 2;
polynomial_ref S2 = (x^4) - 10*(x^2) + 1;
polynomial_ref S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576;
polynomial_ref S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225;
vector<polynomial_ref> S;
S.push_back(S1);
S.push_back(S2);
S.push_back(S3);
S.push_back(S4);
S.push_back(S1*S2*S3*S4);
// factor all the S_i them for all the prime numbers
for (unsigned S_i = 0; S_i < S.size(); ++ S_i) {
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) {
unsigned prime = primes[prime_i];
upolynomial::zp_manager upm(nm);
upm.set_zp(prime);
upolynomial::numeral_vector S_i_u;
upm.to_numeral_vector(S[S_i], S_i_u);
cout << "Factoring "; upm.display(cout, S_i_u); cout << " over Z_" << prime << endl;
cout << "Expecting " << swinnerton_dyer_factors[S_i][0][prime_i] << " distinct factors, " << swinnerton_dyer_factors[S_i][1][prime_i] << " total" << endl;
upolynomial::zp_factors factors(upm);
upolynomial::zp_factor(upm, S_i_u, factors);
// check the result
unsigned distinct = factors.distinct_factors();
unsigned total = factors.total_factors();
cout << "Got " << factors << endl;
cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl;
SASSERT(swinnerton_dyer_factors[S_i][0][prime_i] == distinct);
SASSERT(swinnerton_dyer_factors[S_i][1][prime_i] == total);
upolynomial::numeral_vector multiplied;
factors.multiply(multiplied);
SASSERT(upm.eq(S_i_u, multiplied));
upm.reset(multiplied);
// remove the temp
upm.reset(S_i_u);
}
}
}
static void tst_factor_finite_3() {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
// random polynomials
vector<polynomial_ref> random_p;
random_p.push_back( 3*(x^10) + 2*(x^9) + 4*(x^8) + 4*(x^7) + 4*(x^6) + 1*(x^5) + 3*(x^2) + 3*x + 0 );
random_p.push_back( 4*(x^9) + 4*(x^8) + 1*(x^7) + 1*(x^6) + 2*(x^5) + 3*(x^4) + 4*(x^2) + 4*x + 0 );
random_p.push_back( 3*(x^10) + 4*(x^9) + 3*(x^8) + 1*(x^6) + 4*(x^5) + 4*(x^4) + 1*(x^2) + 0 );
random_p.push_back( 1*(x^10) + 4*(x^9) + 1*(x^8) + 3*(x^7) + 3*(x^4) + 3*(x^3) + 1*(x^2) + 4*x + 0 );
random_p.push_back( 1*(x^9) + 2*(x^8) + 3*(x^7) + 1*(x^6) + 2*(x^5) + 4*(x^4) + 3*(x^2) + 0 );
random_p.push_back( 1*(x^10) + 1*(x^9) + 4*(x^7) + 1*(x^6) + 3*(x^5) + 1*(x^4) + 1*(x^3) + 1*x + 0 );
random_p.push_back( 4*(x^10) + 4*(x^9) + 1*(x^8) + 2*(x^7) + 3*(x^6) + 4*(x^5) + 3*(x^4) + 1*(x^3) + 2*(x^2) + 4*x + 0 );
random_p.push_back( 3*(x^10) + 4*(x^9) + 3*(x^8) + 1*(x^7) + 1*(x^6) + 2*(x^5) + 1*(x^4) + 2*(x^3) + 2*(x^2) + 1*x + 0 );
random_p.push_back( 4*(x^10) + 1*(x^9) + 1*(x^7) + 2*(x^5) + 3*(x^3) + 1*(x^2) + 4*x + 0 );
random_p.push_back( 1*(x^10) + 3*(x^9) + 3*(x^8) + 1*(x^7) + 3*(x^6) + 3*(x^5) + 3*(x^4) + 1*(x^2) + 3*x + 0 );
random_p.push_back( 1*(x^10) + 1*(x^9) + 2*(x^8) + 1*(x^7) + 4*(x^6) + 2*(x^5) + 3*(x^4) + 4*(x^3) + 1*(x^2) + 2*x + 0 );
random_p.push_back( 3*(x^9) + 1*(x^8) + 3*(x^7) + 3*(x^6) + 1*(x^5) + 2*(x^4) + 4*(x^3) + 4*(x^2) + 3*x + 0 );
random_p.push_back( 2*(x^10) + 3*(x^9) + 2*(x^8) + 4*(x^7) + 1*(x^6) + 3*(x^5) + 2*(x^3) + 3*(x^2) + 2*x + 2 );
random_p.push_back( 3*(x^10) + 1*(x^9) + 4*(x^8) + 2*(x^7) + 1*(x^6) + 4*(x^5) + 1*(x^4) + 3*(x^3) + 1*x + 2 );
random_p.push_back( 4*(x^10) + 2*(x^9) + 1*(x^8) + 1*(x^6) + 1*(x^5) + 3*(x^4) + 4*(x^3) + 1*(x^2) + 1*x + 0 );
random_p.push_back( 4*(x^10) + 2*(x^7) + 4*(x^6) + 2*(x^3) + 1*x + 0 );
random_p.push_back( 4*(x^10) + 1*(x^9) + 1*(x^8) + 4*(x^7) + 4*(x^4) + 2*(x^2) + 1*x + 4 );
random_p.push_back( 3*(x^10) + 2*(x^8) + 1*(x^7) + 1*(x^6) + 3*(x^4) + 3*(x^3) + 4*(x^2) + 3*x + 0 );
random_p.push_back( 1*(x^10) + 2*(x^9) + 2*(x^6) + 4*(x^3) + 4*(x^2) + 0 );
random_p.push_back( 1*(x^10) + 2*(x^9) + 2*(x^8) + 4*(x^7) + 4*(x^6) + 1*(x^5) + 1*(x^3) + 1*(x^2) + 3*x + 0 );
// factor all the randoms them for all the prime numbers
for (unsigned random_i = 0; random_i < random_p.size(); ++ random_i) {
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) {
unsigned prime = primes[prime_i];
upolynomial::zp_manager upm(nm);
upm.set_zp(prime);
upolynomial::numeral_vector poly;
upm.to_numeral_vector(random_p[random_i], poly);
cout << "Factoring "; upm.display(cout, poly); cout << " over Z_" << prime << endl;
cout << "Expecting " << swinnerton_dyer_factors[random_i][0][prime_i] << " distinct factors, " << random_polynomial[random_i][1][prime_i] << " total" << endl;
upolynomial::zp_factors factors(upm);
upolynomial::zp_factor(upm, poly, factors);
// check the result
unsigned distinct = factors.distinct_factors();
unsigned total = factors.total_factors();
cout << "Got " << factors << endl;
cout << "Thats " << distinct << " distinct factors, " << total << " total" << endl;
SASSERT(random_polynomial[random_i][0][prime_i] == distinct);
SASSERT(random_polynomial[random_i][1][prime_i] == total);
upolynomial::numeral_vector multiplied;
factors.multiply(multiplied);
bool equal = upm.eq(poly, multiplied);
cout << (equal ? "equal" : "not equal") << endl;
SASSERT(equal);
upm.reset(multiplied);
// remove the temp
upm.reset(poly);
}
}
}
static void tst_factor_enumeration() {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
vector<polynomial_ref> factors;
for (int i = 0; i < 5; ++ i) {
polynomial_ref factor(pm);
factor = x + i;
factors.push_back(factor);
}
upolynomial::manager upm(nm);
upolynomial::zp_manager upm_13(nm);
upm_13.set_zp(13);
upolynomial::zp_factors factors_13(upm_13);
upolynomial::numeral constant;
nm.set(constant, 10);
factors_13.set_constant(constant);
for (unsigned i = 0; i < 5; ++ i) {
upolynomial::numeral_vector ufactor;
upm_13.to_numeral_vector(factors[i], ufactor);
factors_13.push_back(ufactor, 1);
upm.reset(ufactor);
}
cout << "All: " << factors_13 << endl;
upolynomial::factorization_degree_set degrees(factors_13);
degrees.display(cout); cout << endl;
scoped_mpz_vector left(nm), right(nm);
upolynomial::ufactorization_combination_iterator it(factors_13, degrees);
unsigned i = 0;
it.display(cout);
bool remove = false;
while (it.next(remove)) {
it.left(left);
it.right(right);
cout << "Left " << i << ": "; upm.display(cout, left); cout << endl;
cout << "Right " << i << ": "; upm.display(cout, right); cout << endl;
i ++;
if (i % 3 == 0) {
remove = true;
} else {
remove = false;
}
it.display(cout);
}
// SASSERT(i == 15);
return;
for (unsigned i = 0; i < 5; ++ i) {
factors_13.set_degree(i, factors_13.get_degree(i) + i);
}
cout << "Different: " << factors_13 << " of degree " << factors_13.get_degree() << endl;
upolynomial::factorization_degree_set degrees1(factors_13);
degrees1.display(cout); cout << endl; // [0, ..., 15]
polynomial_ref tmp1 = (x^3) + 1;
polynomial_ref tmp2 = (x^5) + 2;
polynomial_ref tmp3 = (x^7) + 3;
upolynomial::numeral_vector up1, up2, up3;
upm_13.to_numeral_vector(tmp1, up1);
upm_13.to_numeral_vector(tmp2, up2);
upm_13.to_numeral_vector(tmp3, up3);
upolynomial::zp_factors tmp(upm_13);
tmp.push_back(up1, 1);
tmp.push_back(up2, 1);
tmp.push_back(up3, 1);
upm_13.reset(up1);
upm_13.reset(up2);
upm_13.reset(up3);
cout << "Different: " << tmp << " of degree " << tmp.get_degree() << endl;
upolynomial::factorization_degree_set degrees2(tmp);
degrees2.display(cout); cout << endl;
tmp1 = (x^2) + 1;
tmp2 = (x^10) + 2;
tmp3 = x + 3;
upm_13.to_numeral_vector(tmp1, up1);
upm_13.to_numeral_vector(tmp2, up2);
upm_13.to_numeral_vector(tmp3, up3);
tmp.clear();
tmp.push_back(up1, 2);
tmp.push_back(up2, 1);
tmp.push_back(up3, 1);
cout << "Different: " << tmp << " of degree " << tmp.get_degree() << endl;
upm_13.reset(up1);
upm_13.reset(up2);
upm_13.reset(up3);
upolynomial::factorization_degree_set degrees3(tmp);
degrees3.display(cout); cout << endl;
degrees1.intersect(degrees3);
degrees1.display(cout); cout << endl;
}
static void tst_factor_square_free_univariate_1(unsigned max_length) {
polynomial::numeral_manager nm;
upolynomial::numeral test;
upolynomial::numeral p;
nm.set(test, -9);
nm.set(p, 5);
nm.mod(test, p, test);
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
cout << "R.<x> = QQ['x']" << endl;
// let's start with \prod (p_i x^{p_{i+1} - p_{i+1})
unsigned n_primes = sizeof(primes)/sizeof(unsigned);
max_length = std::min(max_length, n_primes);
for(unsigned length = 1; length < max_length; ++ length) {
// starting from prime_i going for length
for(unsigned start_i = 0; start_i < n_primes; ++ start_i) {
polynomial_ref f(pm);
bool first = true;
for (unsigned prime_i = 0; prime_i < length; ++ prime_i) {
int p1 = primes[(start_i + prime_i) % n_primes];
int p2 = primes[(start_i + prime_i + 1) % n_primes];
if (first) {
f = (p1*(x^p2) - p2);
first = false;
} else {
f = f*(p1*(x^p2) - p2);
}
}
upolynomial::manager upm(nm);
scoped_mpz_vector f_u(nm);
upm.to_numeral_vector(f, f_u);
cout << "factoring "; upm.display(cout, f_u); cout << endl;
cout << "expecting " << length << " factors ";
upolynomial::factors factors(upm);
bool ok = upolynomial::factor_square_free(upm, f_u, factors);
cout << "got " << factors << endl;
SASSERT(factors.distinct_factors() == length);
}
}
}
static void tst_factor_square_free_univariate_2() {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
// Swinnerton-Dyer polynomials (irreducible, modular factors of degree at most 2)
polynomial_ref S1 = (x^2) - 2;
polynomial_ref S2 = (x^4) - 10*(x^2) + 1;
polynomial_ref S3 = (x^8) - 40*(x^6) + 352*(x^4) - 960*(x^2) + 576;
polynomial_ref S4 = (x^16) - 136*(x^14) + 6476*(x^12) - 141912*(x^10) + 1513334*(x^8) - 7453176*(x^6) + 13950764*(x^4) - 5596840*(x^2) + 46225;
vector<polynomial_ref> S;
S.push_back(S1);
S.push_back(S2);
S.push_back(S3);
S.push_back(S4);
upolynomial::manager upm(nm);
// factor all the S_i them for all the prime numbers
for (unsigned S_i = 0; S_i < S.size(); ++ S_i) {
upolynomial::numeral_vector S_i_u;
upm.to_numeral_vector(S[S_i], S_i_u);
cout << "Factoring "; upm.display(cout, S_i_u); cout << " over Z " << endl;
upolynomial::factors factors(upm);
upolynomial::factor_square_free(upm, S_i_u, factors);
// check the result
cout << "Got " << factors << endl;
// remove the temp
upm.reset(S_i_u);
}
}
static void tst_factor_square_free_univariate_3() {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
polynomial_ref deg70 = (x^70) - 6*(x^65) - (x^60) + 60*(x^55) - 54*(x^50) - 230*(x^45) + 274*(x^40) + 542*(x^35) - 615*(x^30) - 1120*(x^25) + 1500*(x^20) - 160*(x^15) - 395*(x^10) + 76*(x^5) + 34;
upolynomial::manager upm(nm);
upolynomial::numeral_vector deg70_u;
upm.to_numeral_vector(deg70, deg70_u);
cout << "Factoring "; upm.display(cout, deg70_u); cout << " over Z " << endl;
upolynomial::factors factors(upm);
upolynomial::factor_square_free(upm, deg70_u, factors);
cout << "Got " << factors << endl;
upm.reset(deg70_u);
}
void tst_factor_swinnerton_dyer_big(unsigned max) {
polynomial::numeral_manager nm;
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
vector<polynomial_ref> roots;
vector<polynomial::var> vars;
unsigned n = std::min(max, static_cast<unsigned>(sizeof(primes)/sizeof(unsigned)));
for(unsigned prime_i = 0; prime_i < n; ++ prime_i) {
int prime = primes[prime_i];
cout << "Computing Swinnerton-Dyer[" << prime_i + 1 << "]" << endl;
polynomial_ref y(pm);
vars.push_back(pm.mk_var());
y = pm.mk_polynomial(vars.back());
polynomial_ref p(pm);
p = (y^2) - prime;
roots.push_back(p);
polynomial_ref computation = x;
for (unsigned i = 0; i < roots.size(); ++ i) {
polynomial_ref var(pm);
var = pm.mk_polynomial(vars[i]);
computation = computation - var;
}
{
timeit timer(true, "computing swinnerton-dyer");
for (unsigned i = 0; i < roots.size(); ++ i) {
polynomial_ref tmp(pm);
pm.resultant(computation, roots[i], vars[i], tmp);
computation = tmp;
}
}
cout << "Computed Swinnerton-Dyer[" << prime_i + 1 << "], degree = " << pm.total_degree(computation) << ", size = " << pm.size(computation) << endl;
cout << "Starting factoring " << endl;
{
timeit timer(true, "factoring swinnerton-dyer");
upolynomial::manager upm(nm);
scoped_mpz_vector sd_u(nm);
upm.to_numeral_vector(computation, sd_u);
upolynomial::factors factors(upm);
upolynomial::factor_square_free(upm, sd_u, factors);
cout << "Got " << factors.distinct_factors() << " factors" << endl;
}
}
}
static void tst_factor_square_free_multivariate_1(unsigned max_n) {
#if 0
polynomial::numeral_manager nm;
upolynomial::numeral test;
upolynomial::numeral p;
nm.set(test, -9);
nm.set(p, 5);
nm.mod(test, p, test);
polynomial::manager pm(nm);
polynomial_ref x(pm);
x = pm.mk_polynomial(pm.mk_var());
polynomial_ref y(pm);
y = pm.mk_polynomial(pm.mk_var());
// lets start simple x^n - y^n
for (unsigned prime_i = 0; prime_i < sizeof(primes)/sizeof(unsigned); ++ prime_i) {
unsigned prime = primes[prime_i];
if (prime > max_n) {
break;
}
polynomial_ref f = (x^prime) - (y^prime);
cout << "factoring: " << f << endl;
// factor
polynomial::factors factors(pm);
polynomial::factor_square_free_primitive(f, factors);
cout << "got: " << factors << endl;
}
#endif
}
void tst_polynomial_factorization() {
enable_trace("polynomial::factorization");
// enable_trace("polynomial::factorization::bughunt");
enable_trace("polynomial::factorization::multivariate");
// enable_trace("upolynomial");
// Z_p square-free factorization tests
// tst_square_free_finite_1();
// Z_p factorization tests
// tst_factor_finite_1();
// tst_factor_finite_2();
// tst_factor_finite_3();
// Z factorization
// tst_factor_enumeration();
// tst_factor_square_free_univariate_1(3);
// tst_factor_square_free_univariate_2();
// tst_factor_square_free_univariate_3();
// tst_factor_swinnerton_dyer_big(3);
// Multivariate factorization
tst_factor_square_free_multivariate_1(3);
}

View file

@ -0,0 +1,42 @@
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
prime_generator.cpp
Abstract:
Prime generator
Author:
Leonardo (leonardo) 2011-12-23
Notes:
--*/
#include"mpz.h"
#include"prime_generator.h"
void tst_prime_generator() {
unsynch_mpz_manager m;
scoped_mpz sqrt_p(m);
prime_generator gen;
for (unsigned i = 0; i < 10000; i++) {
uint64 p = gen(i);
std::cout << p << ", ";
if (i % 11 == 0) std::cout << "\n";
std::cout.flush();
if (p == 2)
continue;
m.set(sqrt_p, p);
m.root(sqrt_p, 2);
uint64 k = m.get_uint64(sqrt_p);
for (uint64 i = 2; i <= k; i++) {
SASSERT(p % i != 0);
}
}
std::cout << std::endl;
}

View file

@ -0,0 +1,29 @@
#include "proof_checker.h"
#include "ast_ll_pp.h"
void tst_checker1() {
ast_manager m(PGM_FINE);
expr_ref a(m);
proof_ref p1(m), p2(m), p3(m), p4(m);
bool result;
expr_ref_vector side_conditions(m);
a = m.mk_const(symbol("a"), m.mk_bool_sort());
p1 = m.mk_hypothesis(a.get());
p2 = m.mk_hypothesis(m.mk_not(a.get()));
ast_ll_pp(std::cout, m, p1.get());
ast_ll_pp(std::cout, m, p2.get());
proof* proofs[2] = { p1.get(), p2.get() };
p3 = m.mk_unit_resolution(2, proofs);
p4 = m.mk_lemma(p3.get(), a.get());
ast_ll_pp(std::cout, m, p4.get());
proof_checker checker(m);
p4 = m.mk_lemma(p3.get(), m.mk_or(a.get(), m.mk_not(a.get())));
ast_ll_pp(std::cout, m, p4.get());
result = checker.check(p4.get(), side_conditions);
SASSERT(result);
}
void tst_proof_checker() {
tst_checker1();
}

86
src/test/qe_defs.cpp Normal file
View file

@ -0,0 +1,86 @@
#include "arith_decl_plugin.h"
#include "qe.h"
#include "ast_pp.h"
#include "smtparser.h"
static void test_defs(ast_manager& m, expr* _fml) {
arith_util a(m);
app_ref x(m);
qe::def_vector defs(m);
expr_ref fml(_fml, m);
x = m.mk_const(symbol("x"), a.mk_int());
app* vars[1] = { x.get() };
front_end_params fparams;
qe::expr_quant_elim qelim(m, fparams);
lbool result = qelim.first_elim(1, vars, fml, defs);
std::cout << mk_pp(_fml, m) << "\n--->\n";
std::cout << mk_pp(fml, m) << "\n";
for (unsigned i = 0; i < defs.size(); ++i) {
std::cout << defs.var(i)->get_name() << " "
<< mk_pp(defs.def(i), m) << "\n";
}
std::cout << "\n";
}
static void test_defs_all(ast_manager& m, expr* _fml) {
arith_util a(m);
app_ref x(m);
expr_ref fml(_fml, m), fml0(_fml, m);
x = m.mk_const(symbol("x"), a.mk_int());
app* vars[1] = { x.get() };
front_end_params fparams;
qe::expr_quant_elim qelim(m, fparams);
lbool result = l_true;
while (result == l_true) {
fml = fml0;
qe::def_vector defs(m);
result = qelim.first_elim(1, vars, fml, defs);
std::cout << result << "\n";
std::cout << mk_pp(fml, m) << "\n";
for (unsigned i = 0; i < defs.size(); ++i) {
std::cout << defs.var(i)->get_name() << " "
<< mk_pp(defs.def(i), m) << "\n";
}
fml0 = m.mk_and(fml0, m.mk_not(fml));
}
}
static void test_defs(char const* str) {
ast_manager m;
m.register_decl_plugins();
scoped_ptr<smtlib::parser> parser = smtlib::parser::create(m);
parser->initialize_smtlib();
std::ostringstream buffer;
buffer << "(benchmark presburger :status unknown :logic AUFLIA "
<< ":extrafuns ((x Int) (y Int) (z Int))\n"
<< ":formula " << str << ")";
parser->parse_string(buffer.str().c_str());
smtlib::benchmark* b = parser->get_benchmark();
smtlib::theory::expr_iterator it = b->begin_formulas();
smtlib::theory::expr_iterator end = b->end_formulas();
for (; it != end; ++it) {
test_defs(m, *it);
}
}
void tst_qe_defs() {
enable_trace("qe");
test_defs("(and (<= (* 2 x) y) (>= (* 3 x) z) (<= (* 4 x) (* 2 z)) (= (mod x 2) 0))");
return;
test_defs("(and (<= (* 2 x) y) (>= (* 3 x) z) (= (mod x 2) 0))");
test_defs("(and (<= (* 2 x) y) (= (mod x 2) 0))");
test_defs("(= (* 2 x) y)");
test_defs("(or (< x 0) (> x 1))");
test_defs("(or (< x y) (> x y))");
test_defs("(= x y)");
test_defs("(<= x y)");
test_defs("(>= x y)");
test_defs("(and (<= (+ x y) 0) (<= (+ x z) 0))");
test_defs("(and (<= (+ x y) 0) (<= (+ (* 2 x) z) 0))");
test_defs("(and (<= (+ (* 3 x) y) 0) (<= (+ (* 2 x) z) 0))");
test_defs("(and (>= x y) (>= x z))");
test_defs("(< x y)");
test_defs("(> x y)");
}

485
src/test/quant_elim.cpp Normal file
View file

@ -0,0 +1,485 @@
#include "ast.h"
#include "front_end_params.h"
#include "simplifier.h"
#include "qe.h"
#include "basic_simplifier_plugin.h"
#include "arith_simplifier_plugin.h"
#include "array_simplifier_plugin.h"
#include "bv_simplifier_plugin.h"
#include "ast_pp.h"
#include "smtlib.h"
#include "smtparser.h"
#include "lbool.h"
#include <sstream>
static void test_qe(ast_manager& m, lbool expected_outcome, expr* fml, char const* option) {
// enable_trace("bit2int");
//enable_trace("gomory_cut");
enable_trace("final_check_arith");
enable_trace("arith_final_check");
//enable_trace("arith_branching");
enable_trace("theory_arith_int");
enable_trace("presburger");
enable_trace("quant_elim");
// enable_trace("arith_simplifier_plugin");
// enable_trace("non_linear");
// enable_trace("gomory_cut_detail");
// enable_trace("arith");
// enable_trace("bv");
// enable_trace("after_search");
// enable_trace("bv_bit_prop");
simplifier simp(m);
front_end_params params;
params.m_quant_elim = true;
std::cout << mk_pp(fml, m) << "\n";
qe::expr_quant_elim qe(m, params);
expr_ref result(m);
qe(m.mk_true(), fml, result);
std::cout << " -> " << mk_pp(result, m) << " " << expected_outcome << "\n";
if (expected_outcome == l_true && !m.is_true(result)) {
std::cout << "ERROR: expected true, instead got " << ast_pp(result, m).c_str() << "\n";
//exit(-1);
}
if (expected_outcome == l_false && !m.is_false(result)) {
std::cout << "ERROR: expected false, instead got " << ast_pp(result, m).c_str() << "\n";
//exit(-1);
}
}
static void test_formula(lbool expected_outcome, char const* fml) {
ast_manager m;
m.register_decl_plugins();
scoped_ptr<smtlib::parser> parser = smtlib::parser::create(m);
parser->initialize_smtlib();
std::ostringstream buffer;
buffer << "(benchmark presburger :status unknown :logic AUFLIA :extrapreds ((p1) (p2) (p3)) "
<< ":extrafuns ((a Int) (b Int))\n"
<< ":datatypes ((list (nil) (cons (hd Int) (tl list))))\n"
<< ":datatypes ((cell (cnil) (ccons (car cell) (cdr cell))))\n"
<< ":extrasorts (U)\n"
<< ":extrafuns ((f U U))\n"
<< ":formula " << fml << ")";
parser->parse_string(buffer.str().c_str());
smtlib::benchmark* b = parser->get_benchmark();
smtlib::theory::expr_iterator it = b->begin_formulas();
smtlib::theory::expr_iterator end = b->end_formulas();
for (; it != end; ++it) {
test_qe(m, expected_outcome, *it, 0);
}
}
void tst_quant_elim() {
test_formula(l_false,"(forall (x Int) (y Int) (or (= x 0) (< (* 5 y) (* 6 x)) (> (* 5 y) (* 6 x))))");
test_formula(l_false, "(forall (a Int) (b Int) (exists (x Int) (and (< a (* 20 x)) (< (* 20 x) b))))");
test_formula(l_undef, "(exists (u U) (= (f u) u))");
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 7 v))))))))");
test_formula(l_true, "(forall (x Int) (y Int) (implies (= (* 6 x) (* 5 y)) (exists (d Int) (= y (* 3 d)))))");
test_formula(l_undef, "(exists (x Int) (= (- a (mod x 4)) 0))");
// return;
// test_formula(l_true, "(exists (x Int) (y Int) (= 1 (+ (* 5 x) (* 3 y))))");
test_formula(l_undef, "(exists (a Bool) (b Bool) (or (and p1 a) (and p2 (not b))))");
test_formula(l_false,
"(forall (x Int) (q1 Int) (q2 Int) (r1 Int) (r2 Int) "
" (implies "
" (and (< x 4699) "
" (= (* 2622 x) (+ (* 65536 q1) r1)) "
" (<= 0 q1) "
" (<= 0 r1) "
" (< r1 65536) "
" (= x (+ (* 100 q2) r2)) "
" (<= 0 q2) "
" (<= 0 r2) "
" (< r2 100)) "
" (= q1 q2)))");
test_formula(l_undef,
"(forall (l list) (or (= l nil) (exists (x Int) (ll list) (= l (cons x ll)))))");
test_formula(l_false, "(exists (x Real) (forall (y Real) (>= x y)))");
test_formula(l_false, "(exists (x Real) (forall (y Real) (> x y)))");
test_formula(l_false, "(exists (x Real) (forall (y Real) (< x y)))");
test_formula(l_false, "(exists (x Real) (forall (y Real) (<= x y)))");
test_formula(l_true, "(exists (x Real) (exists (y Real) (< x y)))");
test_formula(l_true, "(exists (x Real) (exists (y Real) (<= x y)))");
test_formula(l_true, "(exists (x Real) (exists (y Real) (>= x y)))");
test_formula(l_true, "(exists (x Real) (exists (y Real) (> x y)))");
test_formula(l_true, "(forall (x Real) (exists (y Real) (< x y)))");
test_formula(l_true, "(forall (x Real) (exists (y Real) (<= x y)))");
test_formula(l_true, "(forall (x Real) (exists (y Real) (>= x y)))");
test_formula(l_true, "(forall (x Real) (exists (y Real) (> x y)))");
test_formula(l_false, "(forall (x Real) (forall (y Real) (< x y)))");
test_formula(l_false, "(forall (x Real) (forall (y Real) (<= x y)))");
test_formula(l_false, "(forall (x Real) (forall (y Real) (>= x y)))");
test_formula(l_false, "(forall (x Real) (forall (y Real) (> x y)))");
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 5 v))))))))");
test_formula(l_false, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))");
test_formula(l_true, "(forall (y Int) (implies (exists (d Int) (= y (* 6 d))) (exists (d Int) (= y (* 2 d)))))");
test_formula(l_true, "(forall (y Int) (implies (exists (d Int) (= y (* 65 d))) (exists (d Int) (= y (* 5 d)))))");
test_formula(l_true,
"(exists (z Int) (forall (w Int) (exists (x Int) (y Int) "
" (or (and (< (+ (* 3 x) w) 2) (< 1 (- (+ (* 2 x) z) w))) "
" (and (< z (* 2 y)) (> z y))))))");
test_formula(l_true, "(exists (x Int) (y Int) (and (> x 0) (>= y 0) (= 1 (- (* 3 x) (* 5 y)))))");
test_formula(l_true,
"(exists (a Int) (b Int) "
" (and (not (= a 1)) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))");
test_formula(l_true,
"(forall (x Int) (iff (and (not (= 0 (mod x 2))) (= 0 (mod (- x 1) 3))) "
" (or (= 0 (mod (- x 1) 12)) (= 0 (mod (- x 7) 12)))))");
test_formula(l_false, "(exists (x Int) (and (< (* 3 x) 2) (< 1 (* 2 x))))");
test_formula(l_true, "(forall (x Int) (y Int) (or (= 0 (mod x 5)) (not (= (* 6 x) (* 5 y)))))");
test_formula(l_false, "(forall (x Int) (exists (y Int) (= x (* 2 y))))");
test_formula(l_false,
"(forall (x Int) "
" (implies (not (= 0 (mod x 2))) "
" (or (= 0 (mod (- x 1) 4)) "
" (= 0 (mod (- x 1) 8)) "
" (= 0 (mod (- x 3) 8)) "
" (= 0 (mod (- x 1) 6)) "
" (= 0 (mod (- x 1) 14)) "
" (= 0 (mod (- x 9) 14)) "
" (= 0 (mod (- x 11) 14)) "
" (= 0 (mod (- x 5) 24)) "
" (= 0 (mod (- x 11) 24))))) ");
test_formula(l_true,
"(forall (x Int) (iff (and (not (= 0 (mod x 2))) (= 0 (mod (- x 1) 3))) "
" (or (= 0 (mod (- x 1) 12)) (= 0 (mod (- x 7) 12)))))");
test_formula(l_false,
"(forall (d Int) (c Int) (b Int) "
" (and (= c 0) (= d (* b c)) (= d 0)))");
//return;
test_formula(l_undef, "(exists (k!12 Int) (k!11 Int) (and (= (ite (= k!11 0) 0 k!11) k!11) (not (= (ite (= k!12 (+ 1)) 1 0) 0))))");
//return;
test_formula(l_false,
"(forall (a Int) (b Int) (x Int) (y Int) (z Int) "
" (implies (and (= (+ a 2) b) (= x (+ 1 (- b a))) (= y (- b 2)) (= z 3)) false))");
test_formula(l_false,
"(exists (a Int) (b Int) "
" (and (> a 1) (> b 1) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))");
test_formula(l_true, "(forall (d Int) (implies true (exists (x Int) (y Int) (and true true (= d (+ (* 3 x) (* 5 y)))))))");
// This one takes forever without bit-vectors
test_formula(l_true, "(forall (d Int) (implies (>= d 8) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))");
test_formula(l_true, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (- (* 3 x) (* 5 y)))))))");
test_formula(l_false, "(exists (x Int) (y Int) (z Int) (= 1 (- (* 4 x) (* 6 y))))");
//return;
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 8 v))))))))");
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 8 v))))))))");
#if 0
// too slow.
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 7 u) (* 8 v))))))))");
#endif
test_formula(l_true, "(forall (x Int) (exists (y Int) (and (<= (* 2 y) x) (< x (* 2 (+ y 1))))))");
test_formula(l_false, "(exists (x Int) (y Int) (and (> y 0) (> y (* 2 x)) (< y (+ x 2)) (= 0 (mod y 2))))");
test_formula(l_false, "(exists (x Int) (and (< (* 3 x) 3) (< 1 (* 2 x))))");
test_formula(l_true, "(exists (x Int) (and (< (* 3 x) 4) (< 1 (* 2 x))))");
test_formula(l_false, "(exists (x Int) (and (< (+ (* 3 x) 1) 10) (> (- (* 7 x) 6) 7) (= 0 (mod x 3))))");
test_formula(l_false, "(exists (x Int) (y Int) (and (< (- 1 (* 5 y)) x) (< (+ 1 y) (* 13 x)) (< (+ x 2) 0) (> y 0)))");
test_formula(l_false, "(exists (x Int) (y Int) (and (< (- 1 (* 5 y)) x) (< (+ 1 y) (* 13 x)) (< x -2)))");
test_formula(l_true, "(exists (w Int) (z Int) (y Int) (x Int) (and (< (- 1 (* 5 y)) (+ x (* 2 z))) (< (+ 1 y w (* -4 z)) (* 13 x)) (< x -2) (> z 0)))");
test_formula(l_true,
"(forall (w Int) "
" (exists (z Int) (y Int) (x Int) "
" (and (< (- 1 (* 5 y)) (+ x (* 2 z))) "
" (< (- (+ 1 y) (* 4 z)) (* 13 x)) "
" (< x -2) (> z 0) (< x 10)))) ");
test_formula(l_false,
"(forall (d Int) (c Int) (b Int) "
" (and (= c 0) (= d (* b c)) (= d 4)))");
test_formula(l_undef,
"(exists (d Int) (c Int) (b Int) "
" (and (= c 0) (= d (* b c)) (= d 0)))");
test_formula(l_undef,
"(exists (d Int) (c Int) (b Int) "
" (and (= c 0) (= d (* b c)) (= d 4)))");
// Tests from Harrison's HOL-light version of Cooper.
test_formula(l_true, "(forall (x Int) (y Int) (not (= (+ 1 (* 2 x)) (* 2 y))))");
test_formula(l_false, "(exists (x Int) (y Int) (= 1 (- (* 4 x) (* 6 y))))");
// "(forall (x Int) (implies (< b x) (<= a x)))"
// "(forall (x Int) (implies (< b x) (< a x)))"
test_formula(l_false, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))");
test_formula(l_true, "(forall (d Int) (implies true (exists (x Int) (y Int) (and true true (= d (+ (* 3 x) (* 5 y)))))))");
// This one takes forever without bit-vectors
test_formula(l_true, "(forall (d Int) (implies (>= d 8) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (+ (* 3 x) (* 5 y)))))))");
test_formula(l_true, "(forall (d Int) (implies (>= d 0) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= d (- (* 3 x) (* 5 y)))))))");
test_formula(l_true, "(exists (x Int) (y Int) (and (> x 0) (>= y 0) (= 1 (- (* 3 x) (* 5 y)))))");
test_formula(l_false, "(exists (x Int) (y Int) (z Int) (= 1 (- (* 4 x) (* 6 y))))");
// "(forall (x Int) (implies (< b (* 3 x)) (a < (* 3 x))))"
test_formula(l_false, "(forall (x Int) (y Int) (implies (<= x y) (< (+ 1 (* 2 x)) (* 2 y))))");
test_formula(l_true, "(forall (x Int) (y Int) (z Int) (implies (= (+ 1 (* 2 x)) (* 2 y)) (> (+ x y z) 129)))");
// Formula examples from Cooper's paper.
test_formula(l_true, "(forall (a Int) (exists (b Int) (or (< a (+ (* 4 b) (* 3 a))) (and (not (< a b)) (> a (+ b 1))))))");
test_formula(l_false, "(exists (y Int) (forall (x Int) (and (> (+ x (* 5 y)) 1) (> (- (* 13 x) y) 1) (< (+ x 2) 0))))");
// Harrison's formulas:
test_formula(l_false, "(forall (x Int) (y Int) (implies (and (>= x 0) (>= y 0)) (or (< (- (* 12 x) (* 8 y)) 0) (> (- (* 12 x) (* 8 y)) 2))))");
// test_formula(l_true, "(exists (x Int) (y Int) (= 1 (+ (* 5 x) (* 3 y))))");
test_formula(l_false, "(exists (x Int) (y Int) (= 1 (+ (* 5 x) (* 10 y))))");
test_formula(l_true, "(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 5 x) (* 6 y)))))");
test_formula(l_true, "(exists (x Int) (y Int) (z Int) (w Int) (= 1 (+ (* 2 w) (* 3 x) (* 4 y) (* 5 z))))");
test_formula(l_true, "(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 5 x) (* 3 y)))))");
test_formula(l_true, "(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 3 x) (* 5 y)))))");
test_formula(l_false,"(exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= 1 (- (* 6 x) (* 3 y)))))");
test_formula(l_true, "(forall (x Int) (y Int) (or (= 0 (mod x 5)) (= 0 (mod y 6)) (not (= (* 6 x) (* 5 y)))))");
test_formula(l_false,"(forall (x Int) (y Int) (or (not (= (* 6 x) (* 5 y)))))");
// Positive variant of the Bezout theorem (see the exercise). *)
test_formula(l_true, "(forall (z Int) (implies (> z 7) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= (+ (* 3 x) (* 5 y)) z)))))");
test_formula(l_false,"(forall (z Int) (implies (> z 2) (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= (+ (* 3 x) (* 5 y)) z)))))");
test_formula(l_true,
"(forall (z Int) (implies (<= z 7) "
" (iff (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= z (+ (* 3 x) (* 5 y))))) "
" (not (exists (x Int) (y Int) (and (>= x 0) (>= y 0) (= (- 7 z) (+ (* 3 x) (* 5 y))))))))) ");
// Basic result about congruences.
test_formula(l_true,
"(forall (x Int) "
" (iff (and (not (exists (m Int) (= x (* 2 m)))) (exists (m Int) (= x (+ (* 3 m) 1)))) "
" (or (exists (m Int) (= x (+ (* 12 m) 1))) (exists (m Int) (= x (+ (* 12 m) 7))))))");
// Inspired by the Collatz conjecture.
test_formula(l_false,
"(forall (a Int) (b Int) (x Int) (y Int) (z Int) "
" (implies (and (= (+ a 2) b) (= x (+ 1 (- b a))) (= y (- b 2)) (= z 3)) false))");
test_formula(l_true,
"(exists (a Int) (b Int) "
" (and (not (= a 1)) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))");
test_formula(l_false,
"(exists (a Int) (b Int) "
" (and (> a 1) (> b 1) (= a b) (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a))))))");
test_formula(l_false,
"(exists (a Int) (b Int) "
" (and (> a 1) (> b 1) "
" (or (= a (* 2 b)) (= (* 2 b) (+ 1 (* 3 a)))) "
" (or (= b (* 2 a)) (= (* 2 a) (+ 1 (* 3 b))))))");
#if 0
// Bob Constable's "stamp problem".
test_formula(l_true,
"(forall (x Int) (implies (>= x 8) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 5 v)))))))");
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 5 v))))))))");
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 7 v))))))))");
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 3 u) (* 8 v))))))))");
test_formula(l_true,
"(exists (l Int) (forall (x Int) (implies (>= x l) "
" (exists (u Int) (v Int) (and (>= u 0) (>= v 0) (= x (+ (* 7 u) (* 8 v))))))))");
#endif
// Example from reciprocal mult: (2622 * x)>>16 = x/100 within a range.
test_formula(l_true,
"(forall (x Int) (y Int) "
" (iff (exists (d Int) (= (+ x y) (* 2 d))) "
" (iff (exists (d Int) (= x (* 2 d))) (exists (d Int) (= y (* 2 d))))))");
test_formula(l_true,
"(forall (n Int) "
" (implies (and (< 0 n) (< n 2400)) "
" (or (and (<= n 2) (<= 2 (* 2 n))) "
" (and (<= n 3) (<= 3 (* 2 n))) "
" (and (<= n 5) (<= 5 (* 2 n))) "
" (and (<= n 7) (<= 7 (* 2 n))) "
" (and (<= n 13) (<= 13 (* 2 n))) "
" (and (<= n 23) (<= 23 (* 2 n))) "
" (and (<= n 43) (<= 43 (* 2 n))) "
" (and (<= n 83) (<= 83 (* 2 n))) "
" (and (<= n 163) (<= 163 (* 2 n))) "
" (and (<= n 317) (<= 317 (* 2 n))) "
" (and (<= n 631) (<= 631 (* 2 n))) "
" (and (<= n 1259) (<= 1259 (* 2 n))) "
" (and (<= n 2503) (<= 2503 (* 2 n)))))) ");
memory::finalize();
#ifdef _WINDOWS
_CrtDumpMemoryLeaks();
#endif
exit(0);
}

157
src/test/quant_solve.cpp Normal file
View file

@ -0,0 +1,157 @@
#include "ast.h"
#include "front_end_params.h"
#include "qe.h"
#include "arith_decl_plugin.h"
#include "ast_pp.h"
#include "lbool.h"
#include <sstream>
#include "expr_replacer.h"
#include "smt_solver.h"
static void validate_quant_solution(ast_manager& m, app* x, expr* fml, expr* t, expr* new_fml) {
// verify:
// new_fml <=> fml[t/x]
scoped_ptr<expr_replacer> rep = mk_expr_simp_replacer(m);
expr_substitution sub(m);
sub.insert(x, t);
rep->set_substitution(&sub);
expr_ref fml1(fml, m);
(*rep)(fml1);
expr_ref tmp(m);
tmp = m.mk_not(m.mk_iff(new_fml, fml1));
front_end_params fp;
smt::solver solver(m, fp);
solver.assert_expr(tmp);
lbool res = solver.check();
std::cout << res << "\n";
SASSERT(res == l_false);
}
static void test_quant_solver(ast_manager& m, app* x, expr* fml) {
front_end_params params;
params.m_quant_elim = true;
qe::expr_quant_elim qe(m, params);
expr_ref_vector terms(m);
expr_ref_vector fmls(m);
bool success = qe.solve_for_var(x, fml, terms, fmls);
std::cout << "------------------------\n";
std::cout << mk_pp(fml, m) << "\n";
if (success) {
for (unsigned i = 0; i < terms.size(); ++i) {
std::cout << mk_pp(x, m) << " = " << mk_pp(terms[i].get(), m) << "\n" << mk_pp(fmls[i].get(), m) << "\n";
validate_quant_solution(m, x, fml, terms[i].get(), fmls[i].get());
}
}
else {
std::cout << "failed\n";
}
}
static void test_quant_solver_rec(ast_manager& m, unsigned num_vars, app* const* xs, expr* fml) {
if (num_vars == 0) {
return;
}
front_end_params params;
params.m_quant_elim = true;
qe::expr_quant_elim qe(m, params);
expr_ref_vector fmls(m), ors(m), terms(m);
app* x = xs[0];
bool success = qe.solve_for_var(x, fml, terms, fmls);
std::cout << "------------------------\n";
std::cout << mk_pp(fml, m) << "\n";
if (success) {
for (unsigned i = 0; i < terms.size(); ++i) {
std::cout << mk_pp(x, m) << " = " << mk_pp(terms[i].get(), m) << "\n" << mk_pp(fmls[i].get(), m) << "\n";
validate_quant_solution(m, x, fml, terms[i].get(), fmls[i].get());
ors.reset();
if (m.is_or(fmls[i].get())) {
ors.append(to_app(fmls[i].get())->get_num_args(), to_app(fmls[i].get())->get_args());
}
else {
ors.push_back(fmls[i].get());
}
for (unsigned j = 0; j < ors.size(); ++j) {
test_quant_solver_rec(m, num_vars-1, xs+1, ors[j].get());
}
}
}
else {
std::cout << "failed\n";
}
}
static void test_quant_solve1() {
ast_manager m;
arith_util ar(m);
m.register_decl_plugins();
sort* i = ar.mk_int();
app_ref x(m.mk_const(symbol("x"),i), m);
app_ref y(m.mk_const(symbol("y"),i), m);
app_ref a(m.mk_const(symbol("a"),i), m);
app_ref b(m.mk_const(symbol("b"),i), m);
expr_ref n2(ar.mk_numeral(rational(2), true), m);
expr_ref n3(ar.mk_numeral(rational(3), true), m);
expr_ref n4(ar.mk_numeral(rational(4), true), m);
expr_ref n10(ar.mk_numeral(rational(10), true), m);
expr_ref n20(ar.mk_numeral(rational(20), true), m);
expr_ref x2(ar.mk_mul(n2, x), m);
expr_ref x3(ar.mk_mul(n3, x), m);
expr_ref fml1(m), fml2(m), fml3(m), fml4(m);
expr_ref fml(m), t1(m), t2(m);
fml1 = m.mk_eq(x, a);
fml2 = ar.mk_lt(x, a);
fml3 = ar.mk_gt(x, a);
fml4 = m.mk_and(ar.mk_lt(x, a), ar.mk_lt(x, b));
expr_ref fml5(m.mk_and(ar.mk_gt(x, a), ar.mk_lt(x, b)), m);
expr_ref fml6(ar.mk_le(x, a), m);
expr_ref fml7(ar.mk_ge(x, a), m);
expr_ref fml8(ar.mk_lt(ar.mk_mul(n2, x), a), m);
expr_ref fml9(m.mk_eq(ar.mk_mul(n2, x), a), m);
test_quant_solver(m, x.get(), fml1.get());
test_quant_solver(m, x.get(), fml2.get());
test_quant_solver(m, x.get(), fml3.get());
test_quant_solver(m, x.get(), fml4.get());
test_quant_solver(m, x.get(), fml5.get());
test_quant_solver(m, x.get(), fml6.get());
test_quant_solver(m, x.get(), fml7.get());
test_quant_solver(m, x.get(), fml8.get());
test_quant_solver(m, x.get(), fml9.get());
fml = ar.mk_lt(x2, a); test_quant_solver(m, x.get(), fml.get());
fml = ar.mk_gt(x2, a); test_quant_solver(m, x.get(), fml.get());
fml = ar.mk_le(x2, a); test_quant_solver(m, x.get(), fml.get());
fml = ar.mk_ge(x2, a); test_quant_solver(m, x.get(), fml.get());
fml = m.mk_and(ar.mk_lt(a, ar.mk_mul(n3,x)), ar.mk_lt(ar.mk_mul(n3,x), b));
test_quant_solver(m, x.get(), fml.get());
t1 = ar.mk_sub(ar.mk_mul(n2,y),b);
t2 = ar.mk_add(ar.mk_mul(n3,x),a);
fml1 = ar.mk_le(t1, t2);
t1 = ar.mk_sub(ar.mk_mul(n2,x),a);
t2 = ar.mk_add(ar.mk_mul(n4,y),b);
fml2 = ar.mk_le(t1,t2);
fml = m.mk_and(fml1, fml2);
app* xy[2] = { x.get(), y.get() };
test_quant_solver_rec(m, 2, xy, fml.get());
}
void tst_quant_solve() {
test_quant_solve1();
memory::finalize();
#ifdef _WINDOWS
_CrtDumpMemoryLeaks();
#endif
exit(0);
}

35
src/test/random.cpp Normal file
View file

@ -0,0 +1,35 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
random.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2007-08-24.
Revision History:
--*/
#include"util.h"
#include"trace.h"
static void tst1() {
random_gen r(0);
TRACE("random",
for (unsigned i = 0; i < 1000; i++) {
tout << r() << "\n";
});
}
void tst_random() {
tst1();
}

481
src/test/rational.cpp Normal file
View file

@ -0,0 +1,481 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_rational.cpp
Abstract:
Test rationals
Author:
Leonardo de Moura (leonardo) 2006-09-26.
Revision History:
--*/
#include<iostream>
#include"vector.h"
#include"rational.h"
#include"trace.h"
#include"ext_gcd.h"
#include"timeit.h"
static void tst1() {
rational r1(1);
rational r2(1,2);
rational r3(2,4);
SASSERT(r2 == r3);
SASSERT(r1 != r2);
SASSERT(r2 + r3 == r1);
SASSERT(r1.is_pos());
SASSERT((r2 - r1).is_neg());
SASSERT((r2 - r3).is_zero());
SASSERT(floor(r2).is_zero());
SASSERT(ceil(r2).is_one());
// std::cout << "-r2: " << (-r2) << ", floor(-r2):" << floor(-r2) << "\n";
SASSERT(floor(-r2).is_minus_one());
SASSERT(ceil(-r2).is_zero());
SASSERT(floor(r1) == r1);
SASSERT(ceil(r1) == r1);
rational r4(3,5);
SASSERT(r3 * r4 == rational(3, 10));
SASSERT(r3 / r4 == rational(5, 6));
rational r5(2,3);
SASSERT(r4 * r5 == rational(2, 5));
--r2;
SASSERT(r2 == -r3);
r2.neg();
SASSERT(r2 == r3);
--r2;
r2 = abs(r2);
SASSERT(r2 == r3);
--r2;
++r2;
SASSERT(r2 == r3);
SASSERT(r2 == abs(r2));
SASSERT(r4 * rational(1) == r4);
SASSERT((r4 * rational(0)).is_zero());
SASSERT(r4 * rational(-1) == -r4);
SASSERT(rational(1) * r4 == r4);
SASSERT((rational(0) * r4).is_zero());
SASSERT(rational(-1) * r4 == -r4);
SASSERT(r4 + rational(0) == r4);
SASSERT(ceil(r4).is_one());
// std::cout << "r3: " << r3 << ", r4: " << r4 << ", -r4: " << -r4 << ", r3 / (-r4): " << (r3 / (-r4)) << "\n";
SASSERT(r3 / (-r4) == rational(5,-6));
SASSERT(div(rational(7), rational(2)) == rational(3));
SASSERT(rational(7) % rational(4) == rational(3));
SASSERT(div(rational(7), rational(-2)) == rational(-3));
SASSERT(rational(3) + rational(5) == rational(8));
SASSERT(rational("13/10") + rational("7/10") == rational(2));
SASSERT(rational("100/20") == rational(5));
SASSERT(gcd(rational(12), rational(8)) == rational(4));
SASSERT(ceil(rational(-3,2)) == rational(-1));
SASSERT(floor(rational(-3,2)) == rational(-2));
SASSERT(ceil(rational(3,2)) == rational(2));
SASSERT(floor(rational(3,2)) == rational(1));
SASSERT(rational(3).is_pos());
SASSERT(rational(0).is_nonneg());
SASSERT(rational(3).is_pos());
SASSERT(rational(3).is_nonneg());
SASSERT(rational(0).is_nonneg());
SASSERT(!rational(3).is_zero());
SASSERT(!rational(-3).is_zero());
SASSERT(rational(0).is_zero());
SASSERT(rational(1).is_one());
SASSERT(!rational(2).is_one());
SASSERT(rational(3,4) >= rational(2,8));
SASSERT(rational(3,4) <= rational(7,8));
SASSERT(rational(3,4) <= rational(3,4));
SASSERT(rational(3,4) >= rational(3,4));
SASSERT(rational(3,4) > rational(2,8));
SASSERT(rational(3,4) < rational(7,8));
TRACE("rational", tout << rational(3,4) << "\n";);
TRACE("rational", tout << rational(7,9) << "\n";);
TRACE("rational", tout << rational(-3,7) << "\n";);
TRACE("rational", tout << rational(5,8) << "\n";);
TRACE("rational", tout << rational(4,2) << "\n";);
SASSERT(rational(3) + rational(2) == rational(5));
SASSERT(rational(3) - rational(2) == rational(1));
SASSERT(rational(3) * rational(2) == rational(6));
SASSERT(rational(6) / rational(2) == rational(3));
SASSERT(rational(6) % rational(4) == rational(2));
SASSERT(power(rational(2),0) == rational(1));
SASSERT(power(rational(2),1) == rational(2));
SASSERT(power(rational(2),3) == rational(8));
}
static void tst2() {
rational r1("10000000000000000000000000000000000");
rational r2("10000000000000000000000000000000000/3");
rational r3("20000000000000000000000000000000000/6");
TRACE("rational", tout << r1 << std::endl;);
TRACE("rational", tout << r2 << std::endl;);
TRACE("rational", tout << r3 << std::endl;);
SASSERT(r2 == r3);
SASSERT(r1 != r2);
SASSERT(rational(2)*r2 + r3 == r1);
SASSERT(r1.is_pos());
SASSERT((r2 - r1).is_neg());
SASSERT((r2 - r3).is_zero());
// std::cout << "===> " << floor(r2) << "\n";
{
rational r0("1/3000000000000000000000000");
SASSERT(ceil(r0).is_one());
SASSERT(floor(-r0).is_minus_one());
SASSERT(ceil(-r0).is_zero());
}
SASSERT(floor(r1) == r1);
SASSERT(ceil(r1) == r1);
rational r4("300000000/5");
SASSERT(rational(1,2) * r4 == rational("300000000/10"));
SASSERT(rational(1,2) / r4 == rational("5/600000000"));
rational r5(2,3);
SASSERT(r4 * r5 == rational("200000000/5"));
rational r6("10000000000000000000000000000000003/3");
--r6;
SASSERT(r6 == r2);
r6.neg();
SASSERT(r6 != r2);
SASSERT(abs(r6) == r2);
--r2;
++r2;
r2.neg();
SASSERT(r2 == r6);
SASSERT(r6 * rational(1) == r6);
SASSERT((r6 * rational(0)).is_zero());
SASSERT(r6 * rational(-1) == -r6);
SASSERT(rational(1) * r6 == r6);
SASSERT((rational(0) * r6).is_zero());
SASSERT(rational(-1) * r6 == -r6);
SASSERT(r6 + rational(0) == r6);
SASSERT(rational("300000000000000").is_pos());
SASSERT(rational("0000000000000000000").is_nonneg());
SASSERT(rational("0000000000000000000").is_nonpos());
SASSERT(rational("3000000000000000000/2").is_pos());
SASSERT(rational("3000000000000000000/2").is_nonneg());
SASSERT((-rational("3000000000000000000/2")).is_neg());
SASSERT(!rational("3000000000000000000/2").is_neg());
SASSERT(!rational("3000000000000000000/2").is_zero());
SASSERT(!rational("3000000000000000000/2").is_one());
SASSERT(rational("99999999999/2") >= rational("23/2"));
SASSERT(rational("99999999999/2") > rational("23/2"));
SASSERT(rational("23/2") <= rational("99999999999/2"));
SASSERT(rational("23/2") < rational("99999999999/2"));
SASSERT(!(rational("99999999999/2") < rational("23/2")));
rational int64_max("9223372036854775807");
rational int64_min(-int64_max - rational(1));
// is_int64
SASSERT(int64_max.is_int64());
SASSERT(int64_min.is_int64());
SASSERT(rational(0).is_int64());
SASSERT(rational(1).is_int64());
SASSERT(rational(-1).is_int64());
SASSERT(!(int64_max + rational(1)).is_int64());
SASSERT(!(int64_min - rational(1)).is_int64());
// is_uint64
SASSERT(int64_max.is_uint64());
SASSERT(!int64_min.is_uint64());
SASSERT(rational(0).is_uint64());
SASSERT(rational(1).is_uint64());
SASSERT(!rational(-1).is_uint64());
SASSERT((int64_max + rational(1)).is_uint64());
SASSERT(!(int64_min - rational(1)).is_uint64());
rational uint64_max(rational(1) + (rational(2) * int64_max));
SASSERT(uint64_max.is_uint64());
// get_int64, get_uint64
uint64 u1 = uint64_max.get_uint64();
uint64 u2 = UINT64_MAX;
SASSERT(u1 == u2);
std::cout << "int64_max: " << int64_max << ", INT64_MAX: " << INT64_MAX << ", int64_max.get_int64(): " << int64_max.get_int64() << ", int64_max.get_uint64(): " << int64_max.get_uint64() << "\n";
SASSERT(int64_max.get_int64() == INT64_MAX);
SASSERT(int64_min.get_int64() == INT64_MIN);
// extended Euclid:
}
void tst3() {
rational n1 = power(rational(2), 32);
TRACE("rational", tout << "n1: " << n1 << "\n";);
rational n2 = div(n1, rational(2));
rational n3 = div(rational(2), n2);
TRACE("rational",
tout << "n1: " << n1 << "\n";
tout << "n2: " << n2 << "\n";
tout << "n3: " << n3 << "\n";);
rational n4 = n1 - rational(3);
rational n5 = div(n4, rational(2));
TRACE("rational",
tout << "n4: " << n4 << "\n";
tout << "n5: " << n5 << "\n";);
SASSERT(n5 == rational("2147483646"));
}
void tst4() {
rational n1("4294967293");
TRACE("rational", tout << "n1: " << n1 << "\n";);
rational n2 = div(n1, rational(2));
}
void tst5() {
rational n1(1);
n1.neg();
rational n2("4294967295");
n1 /= n2;
TRACE("rational", tout << n1 << " " << n2 << " " << n1.is_big() << " " << n2.is_big() << "\n";);
n1 *= n2;
TRACE("rational", tout << "after: " << n1 << " " << n2 << "\n";);
SASSERT(n1.is_minus_one());
}
void tst6() {
rational t1(5);
rational t2(3);
rational a, b, g;
g = gcd(t1, t2, a, b);
t1 = rational(15);
t2 = rational(25);
g = gcd(t1, t2, a, b);
t1.neg();
g = gcd(t1, t2, a, b);
t2.neg();
g = gcd(t1, t2, a, b);
t1.neg();
g = gcd(t1, t2, a, b);
std::swap(t1, t2);
g = gcd(t1, t2, a, b);
t1.neg();
g = gcd(t1, t2, a, b);
t2.neg();
g = gcd(t1, t2, a, b);
t1.neg();
g = gcd(t1, t2, a, b);
}
class rational_tester {
public:
static void tst1() {
rational n1(-1);
rational n2(8);
SASSERT((n1 % n2).is_minus_one());
SASSERT(mod(n1, n2) == rational(7));
}
static void tst_hash(int val) {
rational n1(val);
rational n2("10203939394995449949494394932929");
rational n3(val);
n2 = n3;
SASSERT(n1.hash() == n2.hash());
}
static void tst2() {
tst_hash(0);
for (int i = 0; i <= 10000; i++) {
int r = rand() % INT_MAX;
if (rand()%2 == 1) r = -r;
tst_hash(r);
}
}
};
static void tst7() {
rational p;
p = power(rational(2), 32);
for (unsigned i = 1; i < 1000; i++) {
rational n(i);
rational x;
rational y;
rational gcd;
extended_gcd(n, p, gcd, x, y);
TRACE("gcd", tout << n << " " << p << ": " << gcd << " " << x << " " << y << "\n";);
SASSERT(!mod(n, rational(2)).is_one() || mod(n * x, p).is_one());
}
}
static void tst8() {
rational r;
SASSERT(!rational(-4).is_int_perfect_square(r) && r.is_zero());
SASSERT(!rational(-3).is_int_perfect_square(r) && r.is_zero());
SASSERT(!rational(-2).is_int_perfect_square(r) && r.is_zero());
SASSERT(!rational(-1).is_int_perfect_square(r) && r.is_zero());
SASSERT(rational(0).is_int_perfect_square(r) && r.is_zero());
SASSERT(rational(1).is_int_perfect_square(r) && r.is_one());
SASSERT(!rational(2).is_int_perfect_square(r) && r == rational(2));
SASSERT(!rational(3).is_int_perfect_square(r) && r == rational(2));
SASSERT(rational(4).is_int_perfect_square(r) && r == rational(2));
SASSERT(!rational(5).is_int_perfect_square(r) && r == rational(3));
SASSERT(!rational(6).is_int_perfect_square(r) && r == rational(3));
SASSERT(!rational(7).is_int_perfect_square(r) && r == rational(3));
SASSERT(!rational(8).is_int_perfect_square(r) && r == rational(3));
SASSERT(rational(9).is_int_perfect_square(r) && r == rational(3));
SASSERT(!rational(10).is_int_perfect_square(r) && r == rational(4));
SASSERT(!rational(11).is_int_perfect_square(r) && r == rational(4));
SASSERT(!rational(12).is_int_perfect_square(r) && r == rational(4));
SASSERT(!rational(13).is_int_perfect_square(r) && r == rational(4));
SASSERT(!rational(14).is_int_perfect_square(r) && r == rational(4));
SASSERT(!rational(15).is_int_perfect_square(r) && r == rational(4));
SASSERT(rational(16).is_int_perfect_square(r) && r == rational(4));
SASSERT(!rational(17).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(18).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(19).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(20).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(21).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(22).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(23).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(24).is_int_perfect_square(r) && r == rational(5));
SASSERT(rational(25).is_int_perfect_square(r) && r == rational(5));
SASSERT(!rational(26).is_int_perfect_square(r) && r == rational(6));
SASSERT(rational(36).is_int_perfect_square(r) && r == rational(6));
SASSERT(rational(1,9).is_perfect_square(r) && r == rational(1,3));
SASSERT(rational(4,9).is_perfect_square(r) && r == rational(2,3));
}
static void tstmod(rational const& m, rational const& n) {
//
// (=> (distinct n 0)
// (let ((q (div m n)) (r (mod m n)))
// (and (= m (+ (* n q) r))
// (<= 0 r (- (abs n) 1))))))
//
rational q = div(m,n);
rational r = mod(m,n);
std::cout << m << " " << n << " " << q << " " << r << "\n";
std::cout << m << " == " << n*q+r << "\n";
SASSERT(m == (n * q) + r);
SASSERT(rational::zero() <= r);
SASSERT(r < abs(n));
}
static void tst9() {
// record semantics of rational div/mod.
tstmod(rational("41000000000000"),rational("-7000000000000"));
tstmod(rational("-41000000000000"),rational("-7000000000000"));
tstmod(rational("-41000000000000"),rational("7000000000000"));
tstmod(rational("41000000000000"),rational("7000000000000"));
tstmod(rational(41),rational(-7));
tstmod(rational(-41),rational(-7));
tstmod(rational(-41),rational(7));
tstmod(rational(41),rational(7));
}
#define NUM_RATIONALS 1000000
#define MAGNITUDE 10000
static void tst10(bool use_ints) {
if (use_ints)
std::cout << "Testing multiplication performace using small ints\n";
else
std::cout << "Testing multiplication performace using small rationals\n";
vector<rational> vals;
vector<rational> vals2;
vector<float> fvals;
vals.resize(NUM_RATIONALS);
vals2.resize(NUM_RATIONALS);
fvals.resize(NUM_RATIONALS);
for (unsigned i = 0; i < NUM_RATIONALS; i++) {
int r1 = rand() % MAGNITUDE;
int r2 = use_ints ? 1 : rand() % MAGNITUDE;
if (r2 == 0) r2 = 1;
if (rand() % 2 == 0) r1 = -r1;
vals[i] = rational(r1, r2);
vals2[i] = rational(r1, r2);
fvals[i] = ((float)r1) / ((float)r2);
}
{
timeit t(true, "multiplication with rationals");
for (unsigned i = 0; i < NUM_RATIONALS - 1; i++) {
vals[i] *= vals[i+1];
}
}
{
timeit t(true, "multiplication with floats: ");
for (unsigned i = 0; i < NUM_RATIONALS - 1; i++) {
fvals[i] *= fvals[i+1];
}
}
std::cout << "\n";
}
#define NUM_RATIONALS2 10000
#define MAGNITUDE2 100000000
static void tst11(bool use_ints) {
vector<rational> vals;
vector<float> fvals;
vals.resize(NUM_RATIONALS2);
fvals.resize(NUM_RATIONALS2);
for (unsigned i = 0; i < NUM_RATIONALS2; i++) {
int r1 = rand() % MAGNITUDE2;
int r2 = use_ints ? 1 : rand() % MAGNITUDE2;
if (r2 == 0) r2 = 1;
if (rand() % 2 == 0) r1 = -r1;
vals[i] = rational(r1, r2);
fvals[i] = ((float)r1) / ((float)r2);
}
{
timeit t(true, "multiplication with big rationals");
for (unsigned j = 0; j < 10; j++)
for (unsigned i = 0; i < NUM_RATIONALS2-1; i++) {
vals[i] *= vals[i+1];
}
}
{
timeit t(true, "multiplication with floats: ");
for (unsigned j = 0; j < 10; j++)
for (unsigned i = 0; i < NUM_RATIONALS2-1; i++) {
fvals[i] *= fvals[i+1];
}
}
std::cout << "\n";
}
void tst_rational() {
TRACE("rational", tout << "starting rational test...\n";);
std::cout << "sizeof(rational): " << sizeof(rational) << "\n";
rational r1("10000000000000000000000000000000001");
r1.hash();
tst1();
tst2();
tst3();
tst4();
tst5();
std::cout << "running tst6" << std::endl;
tst6();
std::cout << "running tst7" << std::endl;
tst7();
std::cout << "running tst8" << std::endl;
tst8();
std::cout << "running tst9" << std::endl;
tst9();
std::cout << "running rational_tester::tst1" << std::endl;
rational_tester::tst1();
rational_tester::tst2();
tst11(true);
tst10(true);
tst10(false);
}

29
src/test/region.cpp Normal file
View file

@ -0,0 +1,29 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_region.cpp
Abstract:
Test region memory allocator.
Author:
Leonardo de Moura (leonardo) 2006-09-14.
Revision History:
--*/
#include<stdlib.h>
#include"region.h"
static void tst1() {
// TODO
}
void tst_region() {
tst1();
}

View file

@ -0,0 +1,61 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
simple_parser.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-06-14.
Revision History:
--*/
#include"cost_parser.h"
#include"cost_evaluator.h"
#include"arith_decl_plugin.h"
#include"ast_pp.h"
#include"well_sorted.h"
#include"warning.h"
void tst_simple_parser() {
ast_manager m;
m.register_decl_plugins();
arith_util m_util(m);
cost_parser p(m);
var_ref_vector vs(m);
cost_evaluator eval(m);
p.add_var("x");
p.add_var("y");
expr_ref r(m);
p.parse_string("(+ x (* y x))", r);
TRACE("simple_parser", tout << mk_pp(r, m) << "\n";);
p.parse_string("(+ x (* y x) x)", r);
float vals[2] = { 2.0f, 3.0f };
TRACE("simple_parser",
tout << mk_pp(r, m) << "\n";
tout << "val: " << eval(r, 2, vals) << "\n";);
p.parse_string("(+ x (* y x) x", r); // << error
p.parse_string("(x)", r); // << error
p.parse_string("(+ x))", r); // <<< this is accepted
TRACE("simple_parser", tout << mk_pp(r, m) << "\n";);
p.parse_string(")x)", r); // error
p.parse_string("(+ x (* 10 y) 2)", r);
TRACE("simple_parser",
tout << mk_pp(r, m) << "\n";
tout << "val: " << eval(r, 2, vals) << "\n";);
p.parse_string("(ite (and (> x 3) (<= y 4)) 2 10)", r);
TRACE("simple_parser",
tout << mk_pp(r, m) << "\n";
tout << "val: " << eval(r, 2, vals) << "\n";);
p.parse_string("(ite (or (> x 3) (<= y 4)) 2 10)", r);
TRACE("simple_parser",
tout << mk_pp(r, m) << "\n";
tout << "val: " << eval(r, 2, vals) << "\n";);
}

214
src/test/simplifier.cpp Normal file
View file

@ -0,0 +1,214 @@
#ifdef _WINDOWS
#include "z3.h"
#include "z3_private.h"
#include <iostream>
#include "util.h"
#include "trace.h"
void ev_const(Z3_context ctx, Z3_ast e) {
Z3_ast r = Z3_simplify(ctx, e);
TRACE("simplifier",
tout << Z3_ast_to_string(ctx, e) << " -> ";
tout << Z3_ast_to_string(ctx, r) << "\n";);
Z3_ast_kind k = Z3_get_ast_kind(ctx, r);
SASSERT(k == Z3_NUMERAL_AST ||
(k == Z3_APP_AST &&
(Z3_OP_TRUE == Z3_get_decl_kind(ctx,Z3_get_app_decl(ctx, Z3_to_app(ctx, r))) ||
Z3_OP_FALSE == Z3_get_decl_kind(ctx,Z3_get_app_decl(ctx, Z3_to_app(ctx, r))))));
}
void test_bv() {
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort bv1 = Z3_mk_bv_sort(ctx,1);
Z3_sort bv2 = Z3_mk_bv_sort(ctx,2);
Z3_sort bv72 = Z3_mk_bv_sort(ctx,72);
Z3_ast bit1_1 = Z3_mk_numeral(ctx, "1", bv1);
Z3_ast bit3_2 = Z3_mk_numeral(ctx, "3", bv2);
Z3_ast e = Z3_mk_eq(ctx, bit3_2, Z3_mk_sign_ext(ctx, 1, bit1_1));
SASSERT(Z3_simplify(ctx, e) == Z3_mk_true(ctx));
TRACE("simplifier", tout << Z3_ast_to_string(ctx, e) << "\n";);
Z3_ast b12 = Z3_mk_numeral(ctx, "12", bv72);
Z3_ast b13 = Z3_mk_numeral(ctx, "13", bv72);
ev_const(ctx, Z3_mk_bvnot(ctx,b12));
ev_const(ctx, Z3_mk_bvnot(ctx,Z3_simplify(ctx, Z3_mk_bvnot(ctx, b12))));
ev_const(ctx, Z3_mk_bvand(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvor(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvxor(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvnand(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvnor(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvxnor(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvneg(ctx,b12));
ev_const(ctx, Z3_mk_bvadd(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvsub(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvmul(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvudiv(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvsdiv(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvsrem(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvuge(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvsge(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvugt(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvsgt(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvule(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvult(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvsle(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvslt(ctx,b12,b13));
ev_const(ctx, Z3_mk_concat(ctx,b12,b13));
ev_const(ctx, Z3_mk_extract(ctx,43,1,b13));
ev_const(ctx, Z3_mk_sign_ext(ctx,33,b13));
ev_const(ctx, Z3_mk_zero_ext(ctx,33,b13));
ev_const(ctx, Z3_mk_bvshl(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvshl(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvlshr(ctx,b12,b13));
ev_const(ctx, Z3_mk_bvashr(ctx,b12,b13));
ev_const(ctx, Z3_mk_rotate_left(ctx,21,b13));
ev_const(ctx, Z3_mk_rotate_right(ctx,21,b13));
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_datatypes() {
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort int_ty, int_list;
Z3_func_decl nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl;
Z3_ast nil, l1;
int_ty = Z3_mk_int_sort(ctx);
int_list = Z3_mk_list_sort(ctx, Z3_mk_string_symbol(ctx, "int_list"), int_ty,
&nil_decl, &is_nil_decl, &cons_decl, &is_cons_decl, &head_decl, &tail_decl);
nil = Z3_mk_app(ctx, nil_decl, 0, 0);
Z3_ast a = Z3_simplify(ctx, Z3_mk_app(ctx, is_nil_decl, 1, &nil));
SASSERT(a == Z3_mk_true(ctx));
a = Z3_simplify(ctx, Z3_mk_app(ctx, is_cons_decl, 1, &nil));
SASSERT(a == Z3_mk_false(ctx));
Z3_ast one = Z3_mk_numeral(ctx, "1", int_ty);
Z3_ast args[2] = { one, nil };
l1 = Z3_mk_app(ctx, cons_decl, 2, args);
SASSERT(nil == Z3_simplify(ctx, Z3_mk_app(ctx, tail_decl, 1, &l1)));
SASSERT(one == Z3_simplify(ctx, Z3_mk_app(ctx, head_decl, 1, &l1)));
SASSERT(Z3_mk_false(ctx) == Z3_simplify(ctx, Z3_mk_eq(ctx, nil, l1)));
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_skolemize_bug() {
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg, "MODEL", "true");
Z3_set_param_value(cfg, "QUANT_FM","true");
Z3_set_param_value(cfg, "FM","true");
Z3_context ctx = Z3_mk_context(cfg);
Z3_del_config(cfg);
Z3_sort Real = Z3_mk_real_sort(ctx);
Z3_ast x = Z3_mk_bound(ctx, 0, Real);
Z3_symbol x_name = Z3_mk_string_symbol(ctx, "x");
Z3_ast y = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "y"), Real);
Z3_ast xp = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, "xp"), Real);
Z3_ast n0 = Z3_mk_numeral(ctx, "0", Real);
Z3_ast n1 = Z3_mk_numeral(ctx, "1", Real);
Z3_ast args1[2] = { x, n1 };
Z3_ast args2[2] = { x, y };
Z3_ast args[2] = { Z3_mk_eq(ctx, Z3_mk_add(ctx, 2, args1), xp),
Z3_mk_ge(ctx, Z3_mk_add(ctx, 2, args2), n0) };
Z3_ast f = Z3_mk_and(ctx, 2, args);
Z3_ast f2 = Z3_mk_exists(ctx, 0, 0, 0, 1, &Real, &x_name, f);
std::cout << Z3_ast_to_string(ctx, f2) << "\n";
Z3_ast f3 = Z3_simplify(ctx, f2);
std::cout << Z3_ast_to_string(ctx, f3) << "\n";
}
void test_bool() {
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_ast a = Z3_simplify(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, Z3_mk_false(ctx), Z3_mk_true(ctx))));
Z3_ast b = Z3_simplify(ctx, Z3_mk_not(ctx, Z3_mk_iff(ctx, Z3_mk_false(ctx), Z3_mk_true(ctx))));
SASSERT(Z3_mk_true(ctx) == a);
SASSERT(Z3_mk_true(ctx) == b);
TRACE("simplifier", tout << Z3_ast_to_string(ctx, a) << "\n";);
TRACE("simplifier", tout << Z3_ast_to_string(ctx, b) << "\n";);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void test_array() {
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_sort i = Z3_mk_int_sort(ctx);
Z3_ast n1 = Z3_mk_numeral(ctx, "1", i);
Z3_ast n2 = Z3_mk_numeral(ctx, "2", i);
Z3_ast n3 = Z3_mk_numeral(ctx, "3", i);
Z3_ast n4 = Z3_mk_numeral(ctx, "4", i);
Z3_ast s1 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"s1"), i);
Z3_ast s2 = Z3_mk_const(ctx, Z3_mk_string_symbol(ctx,"s2"), i);
Z3_ast c1 = Z3_mk_const_array(ctx, i, n1);
Z3_ast x1 = Z3_mk_store(ctx, Z3_mk_store(ctx, c1, n2, n3), n1, n4);
Z3_ast x2 = Z3_mk_store(ctx, Z3_mk_store(ctx, c1, n1, n4), n2, n3);
Z3_ast x3 = Z3_mk_store(ctx, Z3_mk_store(ctx, c1, s1, n1), n2, n3);
Z3_ast x4 = Z3_mk_store(ctx, Z3_mk_store(ctx, Z3_mk_store(ctx, c1, n2, n3), n1, n4), n2, n3);
Z3_ast xs[4] = { x1, x2, x3, x4};
Z3_ast exy = Z3_mk_eq(ctx, x2, x1);
Z3_ast rxy = Z3_simplify(ctx, exy);
SASSERT(rxy == Z3_mk_true(ctx));
SASSERT(Z3_simplify(ctx, Z3_mk_eq(ctx, x2, x3)) == Z3_mk_false(ctx));
for (unsigned i = 0; i < 4; ++i) {
for (unsigned j = 0; j < 4; ++j) {
exy = Z3_mk_eq(ctx, xs[i], xs[j]);
rxy = Z3_simplify(ctx, exy);
TRACE("simplifier",
tout << Z3_ast_to_string(ctx, exy);
tout << " -> " << Z3_ast_to_string(ctx, rxy) << "\n";
);
}
}
Z3_ast sel1 = Z3_mk_select(ctx, x1, n1);
Z3_ast sel2 = Z3_mk_select(ctx, x1, n4);
TRACE("simplifier",
tout << Z3_ast_to_string(ctx, Z3_simplify(ctx, sel1)) << "\n";
tout << Z3_ast_to_string(ctx, Z3_simplify(ctx, sel2)) << "\n";
);
Z3_del_config(cfg);
Z3_del_context(ctx);
}
void tst_simplifier() {
test_array();
test_bv();
test_datatypes();
test_bool();
test_skolemize_bug();
}
#else
void tst_simplifier() {
}
#endif

View file

@ -0,0 +1,34 @@
#include<iostream>
#include"util.h"
#include"trace.h"
#include"small_object_allocator.h"
void tst_small_object_allocator() {
small_object_allocator soa;
char * p1 = new (soa) char[13];
char * q1 = new (soa) char[14];
char * p2 = new (soa) char[13];
TRACE("small_object_allocator",
tout << "p1: " << (void*)p1 << " q1: " << (void*)q1 << " p2: " << (void*)p2 << "\n";);
soa.deallocate(13,p1);
char * p3 = new (soa) char[13];
TRACE("small_object_allocator", tout << "p3: " << (void*)p3 << "\n";);
char * r1 = new (soa) char[1];
char * r2 = new (soa) char[1];
char * r3 = new (soa) char[1];
char * r4 = new (soa) char[1];
TRACE("small_object_allocator",
tout << "r1: " << (void*)r1 << " r2: " << (void*)r2 << " r3: " << (void*)r3 << " r4: " << (void*)r4 << "\n";);
soa.deallocate(1,r1);
soa.deallocate(1,r3);
r1 = new (soa) char[1];
soa.deallocate(1,r4);
r4 = new (soa) char[1];
r3 = new (soa) char[1];
TRACE("small_object_allocator",
tout << "r1: " << (void*)r1 << " r2: " << (void*)r2 << " r3: " << (void*)r3 << " r4: " << (void*)r4 << "\n";);
}

View file

@ -0,0 +1,103 @@
// This is to test the print-parse facilities over the API
// for SMT-LIB2.
#include "z3.h"
#include <iostream>
void test_print(Z3_context ctx, Z3_ast a) {
Z3_set_ast_print_mode(ctx, Z3_PRINT_SMTLIB2_COMPLIANT);
char const* spec1 = Z3_benchmark_to_smtlib_string(ctx, "test", 0, 0, 0, 0, 0, a);
std::cout << spec1 << "\n";
Z3_ast b =
Z3_parse_smtlib2_string(ctx,
spec1,
0,
0,
0,
0,
0,
0);
char const* spec2 = Z3_ast_to_string(ctx, b);
std::cout << spec2 << "\n";
}
void test_parseprint(char const* spec) {
Z3_context ctx = Z3_mk_context(0);
std::cout << spec << "\n";
Z3_ast a =
Z3_parse_smtlib2_string(ctx,
spec,
0,
0,
0,
0,
0,
0);
test_print(ctx, a);
Z3_del_context(ctx);
}
void tst_smt2print_parse() {
// test basic datatypes
char const* spec1 =
"(declare-datatypes (T) ((list (nil) (cons (car T) (cdr list)))))\n"
"(declare-const x Int)\n"
"(declare-const l (list Int))\n"
"(declare-fun f ((list Int)) Bool)\n"
"(assert (f (cons x l)))\n";
test_parseprint(spec1);
// test basic arrays
char const* spec2 =
"(declare-const x Int)\n"
"(declare-const a (Array Int Int))\n"
"(declare-const b (Array (Array Int Int) Bool))\n"
"(assert (select b a))\n"
"(assert (= b ((as const (Array (Array Int Int) Bool)) true)))\n"
"(assert (= b (store b a true)))\n"
"(declare-const b1 (Array Bool Bool))\n"
"(declare-const b2 (Array Bool Bool))\n"
"(assert (= ((as const (Array Bool Bool)) false) ((_ map and) b1 b2)))\n";
// TBD: const, map, store
test_parseprint(spec2);
// Test mutually recursive datatypes
char const* spec3 =
"(declare-datatypes () ((list (nil) (cons (car tree) (cdr list))) (tree (leaf) (node (n list)))))\n"
"(declare-const x tree)\n"
"(declare-const l list)\n"
"(declare-fun f (list) Bool)\n"
"(assert (f (cons x l)))\n";
test_parseprint(spec3);
// Test arithmetic
char const* spec4 =
"(declare-const x Real)\n"
"(declare-const y Int)\n"
"(assert (= x 0.0))\n"
"(assert (= y 6))\n"
"(assert (> (/ x 1.4) (to_real y)))";
test_parseprint(spec4);
// Test bit-vectors
char const* spec5 =
"(declare-const x (_ BitVec 4))\n"
"(declare-const y (_ BitVec 4))\n"
"(assert (bvule x (bvmul y (concat ((_ extract 2 0) x) ((_ extract 3 3) #xf0)))))";
test_parseprint(spec5);
// Test ?
}

28
src/test/smt_context.cpp Normal file
View file

@ -0,0 +1,28 @@
#include "smt_context.h"
void tst_smt_context()
{
front_end_params params;
ast_manager m;
m.register_decl_plugins();
smt::context ctx(m, params);
app_ref a1(m.mk_const(symbol("a"), m.mk_bool_sort()), m);
app_ref b1(m.mk_const(symbol("b"), m.mk_bool_sort()), m);
app_ref c1(m.mk_const(symbol("c"), m.mk_bool_sort()), m);
app_ref na1(m.mk_not(a1), m);
ctx.assert_expr(na1);
ctx.assert_expr(m.mk_or(c1.get(), b1.get()));
{
app_ref nc(m.mk_not(c1), m);
ptr_vector<expr> assumptions;
assumptions.push_back(nc.get());
ctx.check(assumptions.size(), assumptions.c_ptr());
}
ctx.check();
}

52
src/test/smtparser.cpp Normal file
View file

@ -0,0 +1,52 @@
#ifdef _WINDOWS
#include <iostream>
#include <strstream>
#include <fstream>
#include <sstream>
#include "smtparser.h"
#include "for_each_file.h"
#include "array_decl_plugin.h"
#include "bv_decl_plugin.h"
class for_each_file_smt : public for_each_file_proc {
public:
for_each_file_smt() {}
bool operator()(char const * file_path) {
bool result = true;
std::cout << "Parsing: " << file_path << std::endl;
ast_manager ast_manager;
smtlib::parser* parser = smtlib::parser::create(ast_manager);
ast_manager.register_decl_plugins();
parser->initialize_smtlib();
if (!parser->parse_file(file_path)) {
std::cout << "Could not parse file : " << file_path << std::endl;
result = false;
}
dealloc(parser);
return result;
}
};
static bool test_directory(char const * base) {
for_each_file_smt foreach;
return for_each_file(foreach, base, "*.smt");
}
void tst_smtparser(char** argv, int argc, int & i) {
bool result = true;
if (i + 1 < argc) {
result = test_directory(argv[i+1]);
i += 1;
}
SASSERT(result);
}
#else
void tst_smtparser(char** argv, int argc, int & i) {
}
#endif

175
src/test/splay_tree.cpp Normal file
View file

@ -0,0 +1,175 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
splay_tree.cpp
Abstract:
Splay trees
Author:
Leonardo de Moura (leonardo) 2008-01-31.
Revision History:
--*/
#include"splay_tree_map.h"
#include"splay_tree_def.h"
#include"trace.h"
#include"vector.h"
#include"map.h"
#include"timeit.h"
struct icomp {
int operator()(int k1, int k2) const {
return k1 - k2;
}
};
struct visitor {
bool m_out;
int m_prev;
unsigned m_num;
visitor(bool f = true):m_out(f), m_prev(-1), m_num(0) {}
void operator()(int k, int d) {
SASSERT(m_prev < k);
SASSERT(d == 2 * k);
m_num++;
m_prev = k;
if (m_out) {
TRACE_CODE(tout << k << " ";);
}
}
};
static void tst1(unsigned n) {
splay_tree_map<int, int, icomp> s1;
svector<bool> s2(n, false);
unsigned size = 0;
unsigned num_op = rand()%1000;
for (unsigned i = 0; i < num_op; i++) {
unsigned op = rand()%5;
if (op < 3) {
unsigned idx = rand() % n;
TRACE("splay_tree_detail", tout << "inserting: " << idx << "\n";);
if (!s2[idx]) {
size++;
}
s2[idx] = true;
s1.insert(idx, idx*2);
}
else if (op < 4) {
unsigned idx = rand() % n;
TRACE("splay_tree_detail", tout << "erasing: " << idx << "\n";);
if (s2[idx]) {
size--;
}
s2[idx] = false;
s1.erase(idx);
}
else {
SASSERT((size == 0) == s1.empty());
for (unsigned idx = 0; idx < n; idx++) {
unsigned idx2 = rand() % n;
DEBUG_CODE(
int v;
SASSERT(s2[idx2] == s1.find(idx2, v));
SASSERT(!s2[idx2] || v == 2*idx2);
);
}
}
TRACE("splay_tree",
visitor v;
s1.visit(v);
tout << "\n";
int idx = rand()%n;
tout << "smaller than: " << idx << "\n";
visitor v2;
s1.visit_le(v2, idx);
tout << "\n";
tout << "greater than: " << idx << "\n";
visitor v3;
s1.visit_ge(v3, idx);
tout << "\n";);
visitor v(false);
s1.visit(v);
CTRACE("splay_tree", v.m_num != size, s1.display(tout); tout << "\n";);
SASSERT(v.m_num == size);
}
s1.reset();
SASSERT(s1.empty());
TRACE("splay_tree",
visitor v;;
s1.visit(v);
SASSERT(v.m_num == 0);
tout << "\n";);
}
static void tst_perf(int n1, int n2, int n3, int n4, int n5) {
u_map<int> values1;
svector<int> idxs;
splay_tree_map<int, int, icomp> values2;
{
timeit t(true, "building: ");
for (int i = 0; i < n2; i++) {
int idx = rand() % n1;
idxs.push_back(idx);
values1.insert(idxs[i], i);
}
for (int i = 0; i < n2; i++) {
values2.insert(idxs[i], i);
}
}
int s1, s2;
{
timeit t(true, "u_map: ");
s1 = 0;
for (int j = 0; j < n4; j++) {
for (int i = 0; i < n5; i++) {
int v;
values1.find(idxs[i], v);
s1 += v;
}
}
}
std::cout << s1 << "\n";
{
timeit t(true, "splay_tree: ");
s2 = 0;
for (int j = 0; j < n4; j++) {
for (int i = 0; i < n5; i++) {
int v;
values2.find(idxs[i], v);
s2 += v;
}
}
// for (int i = 0; i < n5; i++) {
// std::cout << idxs[i] << " ";
// }
std::cout << "\n";
// values2.display(std::cout);
}
std::cout << s2 << "\n";
}
void tst_splay_tree() {
for (unsigned i = 0; i < 100; i++) {
tst1(1 + rand()%31);
tst1(1 + rand()%100);
}
// tst_perf(10000000, 1000000, 10000, 1000000, 100);
}

75
src/test/stack.cpp Normal file
View file

@ -0,0 +1,75 @@
/*++
Copyright (c) 2007 Microsoft Corporation
Module Name:
stack.cpp
Abstract:
Low level stack (aka stack-based allocator).
Author:
Leonardo (leonardo) 2011-02-27
Notes:
--*/
#include<utility>
#include"stack.h"
#include"vector.h"
typedef std::pair<unsigned, unsigned> point;
static void tst1() {
stack s;
point * p1 = new (s) point(10, 20);
point * p2 = new (s) point(30, 40);
void * ptr = s.allocate(16000);
SASSERT(p2->first == 30 && p2->second == 40);
SASSERT(p1->first == 10 && p1->second == 20);
s.deallocate(static_cast<int*>(ptr));
s.deallocate(p2);
s.deallocate(p1);
}
static void tst2(unsigned num, unsigned del_rate) {
ptr_vector<char> ptrs;
stack s;
for (unsigned i = 0; i < num; i++) {
SASSERT(ptrs.empty() == s.empty());
SASSERT(s.empty() || ptrs.back() == s.top());
if (!ptrs.empty() && rand() % del_rate == 0) {
s.deallocate();
ptrs.pop_back();
}
else {
unsigned size;
if (rand()%10 == 0) {
size = 8192 + rand()%800;
}
else {
size = rand()%100;
}
char * ptr = static_cast<char*>(s.allocate(size));
ptrs.push_back(ptr);
}
}
while (s.empty()) {
SASSERT(ptrs.empty() == s.empty());
SASSERT(s.empty() || ptrs.back() == s.top());
s.deallocate();
ptrs.pop_back();
}
}
void tst_stack() {
tst1();
tst2(1000, 10);
tst2(2000, 2);
tst2(100000, 10);
tst2(300000, 5);
tst2(300000, 2);
tst2(300000, 7);
}

View file

@ -0,0 +1,52 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_string_buffer.cpp
Abstract:
Test string buffer
Author:
Leonardo de Moura (leonardo) 2006-10-14.
Revision History:
--*/
#include<cstdlib>
#include"debug.h"
#include"string_buffer.h"
#include"trace.h"
static void tst1() {
string_buffer<> b;
b << "Testing" << 10 << true;
SASSERT(strcmp(b.c_str(), "Testing10true") == 0);
}
static void tst2() {
string_buffer<> b;
for (unsigned i = 0; i < 10000; i++) {
int r = rand() % 10;
b << r;
}
TRACE("string_buffer", tout << b.c_str() << "\n";);
SASSERT(strlen(b.c_str()) == 10000);
}
static void tst3() {
string_buffer<32> b;
string_buffer<128> b2;
b2 << "World";
b << "Hello" << " " << b2;
SASSERT(strcmp(b.c_str(), "Hello World") == 0);
}
void tst_string_buffer() {
tst1();
tst2();
tst3();
}

37
src/test/substitution.cpp Normal file
View file

@ -0,0 +1,37 @@
#include "expr_substitution.h"
#include "front_end_params.h"
#include "substitution.h"
#include "unifier.h"
#include "bv_decl_plugin.h"
#include "ast_pp.h"
#include "arith_decl_plugin.h"
void tst_substitution()
{
memory::initialize(0);
front_end_params params;
params.m_model = true;
enable_trace("subst_bug");
ast_manager m;
m.register_decl_plugins();
var_ref v1(m.mk_var(0, m.mk_bool_sort()), m);
var_ref v2(m.mk_var(1, m.mk_bool_sort()), m);
substitution subst(m);
subst.reserve(1,2);
unifier unif(m);
bool ok1 = unif(v1.get(), v2.get(), subst, false);
bool ok2 = unif(v2.get(), v1.get(), subst, false);
expr_ref res(m);
TRACE("substitution", subst.display(tout););
TRACE("substitution", tout << ok1 << " " << ok2 << "\n";);
subst.display(std::cout);
subst.apply(v1.get(), res);
}

59
src/test/symbol.cpp Normal file
View file

@ -0,0 +1,59 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_symbol.cpp
Abstract:
Test symbol class.
Author:
Leonardo de Moura (leonardo) 2006-09-13.
Revision History:
--*/
#include<iostream>
#include"symbol.h"
#include"debug.h"
static void tst1() {
symbol s1("foo");
symbol s2("boo");
symbol s3("foo");
SASSERT(s1 != s2);
SASSERT(s1 == s3);
std::cout << s1 << " " << s2 << " " << s3 << "\n";
SASSERT(s1 == "foo");
SASSERT(s1 != "boo");
SASSERT(s2 != "foo");
SASSERT(s3 == "foo");
SASSERT(s2 == "boo");
SASSERT(lt(s2, s1));
SASSERT(!lt(s1, s2));
SASSERT(!lt(s1, s3));
SASSERT(lt(symbol("abcc"), symbol("abcd")));
SASSERT(!lt(symbol("abcd"), symbol("abcc")));
SASSERT(lt(symbol("abc"), symbol("abcc")));
SASSERT(!lt(symbol("abcd"), symbol("abc")));
SASSERT(lt(symbol(10), s1));
SASSERT(!lt(s1, symbol(10)));
SASSERT(lt(symbol(10), symbol(20)));
SASSERT(!lt(symbol(20), symbol(10)));
SASSERT(!lt(symbol(10), symbol(10)));
SASSERT(lt(symbol("a"), symbol("b")));
SASSERT(!lt(symbol("z"), symbol("b")));
SASSERT(!lt(symbol("zzz"), symbol("b")));
SASSERT(lt(symbol("zzz"), symbol("zzzb")));
}
void tst_symbol() {
tst1();
}

47
src/test/symbol_table.cpp Normal file
View file

@ -0,0 +1,47 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
tst_symbol_table.cpp
Abstract:
Test symbol table module.
Author:
Leonardo de Moura (leonardo) 2006-09-19.
Revision History:
--*/
#include"symbol_table.h"
static void tst1() {
symbol_table<int> t;
t.insert(symbol("foo"), 35);
SASSERT(t.contains(symbol("foo")));
SASSERT(!t.contains(symbol("boo")));
t.begin_scope();
t.insert(symbol("boo"), 20);
SASSERT(t.contains(symbol("boo")));
#ifdef Z3DEBUG
int tmp;
#endif
SASSERT(t.find(symbol("boo"), tmp) && tmp == 20);
SASSERT(t.find(symbol("foo"), tmp) && tmp == 35);
t.insert(symbol("foo"), 100);
SASSERT(t.find(symbol("foo"), tmp) && tmp == 100);
t.end_scope();
SASSERT(t.find(symbol("foo"), tmp) && tmp == 35);
SASSERT(!t.contains(symbol("boo")));
t.reset();
SASSERT(!t.contains(symbol("boo")));
SASSERT(!t.contains(symbol("foo")));
}
void tst_symbol_table() {
tst1();
}

1104
src/test/symmetry.cpp Normal file

File diff suppressed because it is too large Load diff

44
src/test/test_util.h Normal file
View file

@ -0,0 +1,44 @@
#pragma once
#include "stopwatch.h"
struct test_context {
bool test_ok;
unsigned test_fails;
unsigned fails;
double test_time;
stopwatch test_timer;
test_context() : fails(0) {}
};
#undef min
#undef max
#define TEST_CLASS(context, CLASS_NAME, TYPE, CALL_DESTRUCTORS) \
context.test_fails = 0; \
cout << "" << #CLASS_NAME << "<" << #TYPE << ">" << endl; \
CLASS_NAME ## _test< TYPE, CALL_DESTRUCTORS >::run_tests(context); \
context.fails += context.test_fails;
#define TEST_METHOD(context, METHOD) \
cout << "\t" << #METHOD << "... "; \
context.test_timer.reset(); \
context.test_ok = test_ ## METHOD; \
context.test_time = context.test_timer.get_seconds(); \
if (context.test_ok) { \
cout << "PASS"; \
if (context.test_time > 0) { \
cout << "(" << context.test_time << "s)"; \
} \
cout << endl; \
} \
else { \
cout << "FAIL"; \
if (context.test_time > 0) { \
cout << "(" << context.test_time << "s)"; \
} \
cout << endl; \
++ context.test_fails; \
} \

35
src/test/theory_dl.cpp Normal file
View file

@ -0,0 +1,35 @@
#include "smt_context.h"
#include "dl_decl_plugin.h"
#include "ast_pp.h"
#include "model_v2_pp.h"
void tst_theory_dl() {
ast_manager m;
front_end_params params;
params.m_model = true;
datalog::dl_decl_util u(m);
smt::context ctx(m, params);
m.register_decl_plugins();
expr_ref a(m), b(m), c(m);
sort_ref s(m);
s = u.mk_sort(symbol("S"),111);
a = m.mk_const(symbol("a"),s);
b = m.mk_const(symbol("b"),s);
ctx.assert_expr(u.mk_lt(a, b));
ctx.check();
ref<model> md;
ctx.get_model(md);
model_v2_pp(std::cout, *md.get());
c = m.mk_const(symbol("c"),s);
ctx.assert_expr(u.mk_lt(b, c));
ctx.check();
ctx.get_model(md);
model_v2_pp(std::cout, *md.get());
ctx.assert_expr(u.mk_lt(c, a));
std::cout << ctx.check() << "\n";
}

16
src/test/timeout.cpp Normal file
View file

@ -0,0 +1,16 @@
#include "timeout.h"
#include "trace.h"
#ifdef _WINDOWS
#include "windows.h"
void tst_timeout() {
}
#else
void tst_timeout() {
}
#endif

162
src/test/total_order.cpp Normal file
View file

@ -0,0 +1,162 @@
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
total_order.cpp
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2010-07-01.
Revision History:
--*/
#include"total_order.h"
#include"timeit.h"
static void tst1() {
uint_total_order to;
to.insert(1);
to.insert_after(1, 2);
to.insert_after(1, 3);
SASSERT(to.lt(1, 2));
SASSERT(to.lt(3, 2));
SASSERT(to.lt(1, 3));
SASSERT(!to.lt(2, 3));
SASSERT(!to.lt(3, 1));
SASSERT(!to.lt(2, 2));
std::cout << to << "\n";
}
static void tst2() {
uint_total_order to;
to.insert(1);
to.insert_after(1, 2);
to.insert_after(2, 3);
for (unsigned i = 0; i < 1000; i++) {
to.move_after(3, 1);
to.move_after(1, 2);
to.move_after(2, 3);
SASSERT(to.lt(1,2));
SASSERT(to.lt(2,3));
}
}
static void tst3(unsigned sz, unsigned num_rounds) {
uint_total_order to;
to.insert(0);
for (unsigned i = 0; i < sz; i++) {
to.insert_after(i, i+1);
}
for (unsigned i = 0; i < num_rounds; i++) {
unsigned v1 = rand() % sz;
unsigned v2 = rand() % sz;
if (v1 != v2)
to.move_after(v1, v2);
if (i % 1000 == 0) {
std::cout << "*";
std::cout.flush();
}
}
std::cout << std::endl;
}
void move_after(unsigned_vector & v, unsigned_vector & inv_v, unsigned a, unsigned b) {
if (a == b)
return;
// std::cout << std::endl;
// display(std::cout, v.begin(), v.end()); std::cout << std::endl;
// std::cout << "move_after(" << a << ", " << b << ")\n";
unsigned pos_a = inv_v[a];
unsigned pos_b = inv_v[b];
SASSERT(pos_a != pos_b);
if (pos_b < pos_a) {
for (unsigned i = pos_b; i < pos_a; i++) {
v[i] = v[i+1];
inv_v[v[i+1]] = i;
}
v[pos_a] = b;
inv_v[b] = pos_a;
SASSERT(inv_v[b] == inv_v[a] + 1);
}
else {
SASSERT(pos_b > pos_a);
for (unsigned i = pos_b; i > pos_a + 1; i--) {
v[i] = v[i-1];
inv_v[v[i-1]] = i;
}
v[pos_a+1] = b;
inv_v[b] = pos_a+1;
SASSERT(inv_v[b] == inv_v[a] + 1);
}
// display(std::cout, v.begin(), v.end()); std::cout << std::endl;
}
static void tst4(unsigned sz, unsigned num_rounds) {
uint_total_order to;
unsigned_vector v;
unsigned_vector inv_v;
to.insert(0);
v.push_back(0);
inv_v.push_back(0);
for (unsigned i = 0; i < sz; i++) {
to.insert_after(i, i+1);
v.push_back(i+1);
inv_v.push_back(i+1);
}
for (unsigned i = 0; i < num_rounds; i++) {
unsigned v1 = rand() % sz;
unsigned v2 = rand() % sz;
if (v1 != v2) {
to.move_after(v1, v2);
move_after(v, inv_v, v1, v2);
}
for (unsigned k = 0; k < sz - 1; k++) {
SASSERT(inv_v[v[k]] == k);
SASSERT(to.lt(v[k], v[k+1]));
}
if (i % 1000 == 0) {
std::cout << "*";
std::cout.flush();
}
}
std::cout << std::endl;
}
static void bad_case(unsigned sz, unsigned num_rounds) {
uint_total_order to;
to.insert(0);
for (unsigned i = 0; i < sz; i++) {
to.insert_after(i, i+1);
}
for (unsigned i = 0; i < num_rounds; i++) {
to.move_after(sz, 0);
for (unsigned j = 0; j < sz; j++) {
to.move_after(j, j+1);
}
if (i % 10 == 0) {
std::cout << "*";
std::cout.flush();
}
}
std::cout << std::endl;
}
void tst_total_order() {
bad_case(100, 1000);
tst1();
tst2();
tst4(3, 1000000);
tst4(100, 100000);
tst4(512, 100000);
tst4(1000, 100000);
tst3(100, 100000);
tst3(1000, 100000);
}

Some files were not shown because too many files have changed in this diff Show more