From 349c21d4de58a744fadde2ce558832790987d2fc Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 13 Jan 2013 11:33:11 -0800 Subject: [PATCH 001/101] Add configure script that is just a wrapper for python 'src/mk_make.py'. It makes the build more user friendly for users familiar with ./configure + make idiom Signed-off-by: Leonardo de Moura --- .gitignore | 1 - configure | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100755 configure diff --git a/.gitignore b/.gitignore index a935d9dba..77f4d1896 100644 --- a/.gitignore +++ b/.gitignore @@ -44,7 +44,6 @@ bld_rel_x64/* # Auto generated files. config.log config.status -configure install_tactic.cpp mem_initializer.cpp gparams_register_modules.cpp diff --git a/configure b/configure new file mode 100755 index 000000000..29408d3e7 --- /dev/null +++ b/configure @@ -0,0 +1,17 @@ +#!/bin/sh +if test -z $PYTHON; then + PYTHON=python +fi + +if ! which $PYTHON > /dev/null; then + echo "'$PYTHON' not found. Try to set the environment variable PYTHON." + exit 1 +fi + + +if ! $PYTHON -c "print('testing')" > /dev/null ; then + echo "'$PYTHON' failed to execute basic test script. Try to set the environment variable PYTHON with a working Python interpreter." + exit 1 +fi + +$PYTHON scripts/mk_make.py $* From 39d5b850e80aff10d9de2ce3e19684103c7a67f7 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 13 Jan 2013 12:59:39 -0800 Subject: [PATCH 002/101] Fix bug reported at http://stackoverflow.com/questions/14307692/unknown-when-using-defs Signed-off-by: Leonardo de Moura --- RELEASE_NOTES | 2 ++ src/smt/smt_setup.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 104828a45..a2257c610 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -53,6 +53,8 @@ Version 4.3.2 - Fixed crash reported at http://z3.codeplex.com/workitem/11. +- Fixed bug reported at http://stackoverflow.com/questions/14307692/unknown-when-using-defs + Version 4.3.1 ============= diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 96673e67e..1f020cdd3 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -275,7 +275,8 @@ namespace smt { m_context.register_plugin(alloc(smt::theory_dense_mi, m_manager, m_params)); } else { - if (m_params.m_arith_auto_config_simplex || st.m_num_uninterpreted_constants > 4 * st.m_num_bool_constants) { + if (m_params.m_arith_auto_config_simplex || st.m_num_uninterpreted_constants > 4 * st.m_num_bool_constants + || st.m_num_ite_terms > 0 /* theory_rdl and theory_frdl do not support ite-terms */) { // if (!st.m_has_rational && !m_params.m_model && st.m_arith_k_sum < rational(INT_MAX / 8)) { // TRACE("rdl_bug", tout << "using theory_smi_arith\n";); // m_context.register_plugin(alloc(smt::theory_smi_arith, m_manager, m_params)); From 6c35e08e4391b77ba4b014a249097c2d30db2862 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 14 Jan 2013 10:43:18 -0800 Subject: [PATCH 003/101] Make sure we do not use denominators != 1 when encoding values of algebraic extensions Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 107 +++++++++++++++++++++------ 1 file changed, 84 insertions(+), 23 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 394a7102a..947b8abfd 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -179,7 +179,7 @@ namespace realclosure { struct rational_function_value : public value { polynomial m_numerator; - polynomial m_denominator; + polynomial m_denominator; // it is only needed if the extension is not algebraic. extension * m_ext; bool m_depends_on_infinitesimals; //!< True if the polynomial expression depends on infinitesimal values. rational_function_value(extension * ext):value(false), m_ext(ext), m_depends_on_infinitesimals(false) {} @@ -2413,12 +2413,11 @@ namespace realclosure { \pre a is a rational function (algebraic) extension. - \remark If a is actually an integer, this method is also update its representation. + \remark If a is actually an integer, this method also updates its representation. */ bool is_algebraic_int(numeral const & a) { SASSERT(is_rational_function(a)); SASSERT(to_rational_function(a)->ext()->is_algebraic()); - // TODO return false; } @@ -2812,6 +2811,7 @@ namespace realclosure { \brief r <- p/a */ void div(unsigned sz, value * const * p, value * a, value_ref_buffer & r) { + r.reset(); value_ref a_i(*this); for (unsigned i = 0; i < sz; i++) { div(p[i], a, a_i); @@ -4182,10 +4182,10 @@ namespace realclosure { SASSERT(v->ext()->is_algebraic()); polynomial const & n = v->num(); polynomial const & d = v->den(); + SASSERT(is_rational_one(d)); unsigned _prec = prec; while (true) { if (!refine_coeffs_interval(n, _prec) || - !refine_coeffs_interval(d, _prec) || !refine_algebraic_interval(to_algebraic(v->ext()), _prec)) return false; @@ -4637,13 +4637,11 @@ namespace realclosure { tout << "\ninterval: "; bqim().display(tout, v->interval()); tout << "\n";); algebraic * x = to_algebraic(v->ext()); scoped_mpbqi num_interval(bqim()); + SASSERT(is_rational_one(v->den())); if (!expensive_algebraic_poly_interval(v->num(), x, num_interval)) return false; // it is zero SASSERT(!contains_zero(num_interval)); - scoped_mpbqi den_interval(bqim()); - VERIFY(expensive_algebraic_poly_interval(v->den(), x, den_interval)); - SASSERT(!contains_zero(den_interval)); - div(num_interval, den_interval, m_ini_precision, v->interval()); + set_interval(v->interval(), num_interval); SASSERT(!contains_zero(v->interval())); return true; // it is not zero } @@ -4787,18 +4785,11 @@ namespace realclosure { */ void normalize_all(extension * x, unsigned sz1, value * const * p1, unsigned sz2, value * const * p2, value_ref_buffer & new_p1, value_ref_buffer & new_p2) { if (x->is_algebraic()) { + SASSERT(sz2 == 1); + SASSERT(is_rational_one(p2[0])); value_ref_buffer p1_norm(*this); - value_ref_buffer p2_norm(*this); - // FUTURE: we don't need to invoke normalize_algebraic if degree of p1 < degree x->p() - normalize_algebraic(to_algebraic(x), sz1, p1, p1_norm); - if (p1_norm.empty()) { - new_p1.reset(); // result is 0 - } - else { - // FUTURE: we don't need to invoke normalize_algebraic if degree of p2 < degree x->p() - normalize_algebraic(to_algebraic(x), sz2, p2, p2_norm); - normalize_fraction(p1_norm.size(), p1_norm.c_ptr(), p2_norm.size(), p2_norm.c_ptr(), new_p1, new_p2); - } + normalize_algebraic(to_algebraic(x), sz1, p1, new_p1); + new_p2.reset(); new_p2.push_back(one()); } else { normalize_fraction(sz1, p1, sz2, p2, new_p1, new_p2); @@ -4858,6 +4849,7 @@ namespace realclosure { add_p_v(a, b, r); } else { + SASSERT(!a->ext()->is_algebraic()); // b_ad <- b * ad mul(b, ad.size(), ad.c_ptr(), b_ad); // num <- a + b * ad @@ -4913,6 +4905,7 @@ namespace realclosure { add_p_p(a, b, r); } else { + SASSERT(!a->ext()->is_algebraic()); value_ref_buffer an_bd(*this); value_ref_buffer bn_ad(*this); mul(an.size(), an.c_ptr(), bd.size(), bd.c_ptr(), an_bd); @@ -5071,6 +5064,7 @@ namespace realclosure { mul_p_v(a, b, r); } else { + SASSERT(!a->ext()->is_algebraic()); value_ref_buffer num(*this); // num <- b * an mul(b, an.size(), an.c_ptr(), num); @@ -5122,6 +5116,7 @@ namespace realclosure { mul_p_p(a, b, r); } else { + SASSERT(!a->ext()->is_algebraic()); value_ref_buffer num(*this); value_ref_buffer den(*this); mul(an.size(), an.c_ptr(), bn.size(), bn.c_ptr(), num); @@ -5203,16 +5198,82 @@ namespace realclosure { } } - void inv_rf(rational_function_value * a, value_ref & r) { - polynomial const & an = a->num(); - polynomial const & ad = a->den(); + /** + \brief Auxiliary function for inverting values of algebraic extensions. + p is the defining polynomial for the algebraic extension alpha. + q is the polynomial representing the value q(alpha). + + The procedure will store a polynomial in r that represents the value 1/q(a) + */ + void inv_algebraic(unsigned q_sz, value * const * q, unsigned p_sz, value * const * p, value_ref_buffer & r) { + TRACE("inv_algebraic", + tout << "q: "; display_poly(tout, q_sz, q); tout << "\n"; + tout << "p: "; display_poly(tout, p_sz, p); tout << "\n";); + SASSERT(q_sz > 0); + SASSERT(q_sz < p_sz); + value_ref_buffer A(*this); + A.append(q_sz, q); + value_ref_buffer R(*this); + R.push_back(one()); + value_ref_buffer Quo(*this), Rem(*this); + while (true) { + TRACE("inv_algebraic", + tout << "A: "; display_poly(tout, A.size(), A.c_ptr()); tout << "\n"; + tout << "R: "; display_poly(tout, R.size(), R.c_ptr()); tout << "\n";); + if (A.size() == 1) { + div(R.size(), R.c_ptr(), A[0], r); + TRACE("inv_algebraic", tout << "r: "; display_poly(tout, r.size(), r.c_ptr()); tout << "\n";); + return; + } + div_rem(p_sz, p, A.size(), A.c_ptr(), Quo, Rem); + // p == Quo * A + Rem + // since p = 0 + // Quo * A = -Rem + // thus, we update + // A <- -Rem + neg(Rem.size(), Rem.c_ptr(), A); + // R <- rem(Quo * R, p) + mul(R.size(), R.c_ptr(), Quo.size(), Quo.c_ptr(), r); + rem(r.size(), r.c_ptr(), p_sz, p, R); + SASSERT(R.size() < p_sz); + } + } + + /** + \brief r <- 1/a specialized version when a->ext() is algebraic. + It avoids the use of rational functions. + */ + void inv_algebraic(rational_function_value * a, value_ref & r) { + SASSERT(a->ext()->is_algebraic()); + SASSERT(is_rational_one(a->den())); + algebraic * x = to_algebraic(a->ext()); + polynomial const & q = a->num(); + value_ref_buffer new_num(*this); + SASSERT(q.size() < x->p().size()); + inv_algebraic(q.size(), q.c_ptr(), x->p().size(), x->p().c_ptr(), new_num); scoped_mpbqi ri(bqim()); bqim().inv(interval(a), ri); - r = mk_rational_function_value_core(a->ext(), ad.size(), ad.c_ptr(), an.size(), an.c_ptr()); + r = mk_rational_function_value_core(a->ext(), new_num.size(), new_num.c_ptr(), a->den().size(), a->den().c_ptr()); swap(r->interval(), ri); SASSERT(!contains_zero(r->interval())); } + void inv_rf(rational_function_value * a, value_ref & r) { + if (a->ext()->is_algebraic()) { + inv_algebraic(a, r); + } + else { + SASSERT(!a->ext()->is_algebraic()); + polynomial const & an = a->num(); + polynomial const & ad = a->den(); + scoped_mpbqi ri(bqim()); + bqim().inv(interval(a), ri); + r = mk_rational_function_value_core(a->ext(), ad.size(), ad.c_ptr(), an.size(), an.c_ptr()); + swap(r->interval(), ri); + SASSERT(!contains_zero(r->interval())); + } + } + void inv(value * a, value_ref & r) { if (a == 0) { throw exception("division by zero"); From 742f2b07dd1c0d4be12d3f820c3741812c878fd1 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 14 Jan 2013 11:08:32 -0800 Subject: [PATCH 004/101] Add support for compact string representation in the RCF API Signed-off-by: Leonardo de Moura --- src/api/api_rcf.cpp | 6 +++--- src/api/python/z3rcf.py | 5 ++++- src/api/z3_rcf.h | 4 ++-- src/math/realclosure/realclosure.cpp | 13 ++++++++----- src/math/realclosure/realclosure.h | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/api/api_rcf.cpp b/src/api/api_rcf.cpp index 6b9826af7..145f8f824 100644 --- a/src/api/api_rcf.cpp +++ b/src/api/api_rcf.cpp @@ -268,13 +268,13 @@ extern "C" { Z3_CATCH_RETURN(Z3_FALSE); } - Z3_string Z3_API Z3_rcf_num_to_string(Z3_context c, Z3_rcf_num a) { + Z3_string Z3_API Z3_rcf_num_to_string(Z3_context c, Z3_rcf_num a, Z3_bool compact) { Z3_TRY; - LOG_Z3_rcf_num_to_string(c, a); + LOG_Z3_rcf_num_to_string(c, a, compact); RESET_ERROR_CODE(); reset_rcf_cancel(c); std::ostringstream buffer; - rcfm(c).display(buffer, to_rcnumeral(a)); + rcfm(c).display(buffer, to_rcnumeral(a), compact != 0); return mk_c(c)->mk_external_string(buffer.str()); Z3_CATCH_RETURN(""); } diff --git a/src/api/python/z3rcf.py b/src/api/python/z3rcf.py index dd0696594..f63fc7efd 100644 --- a/src/api/python/z3rcf.py +++ b/src/api/python/z3rcf.py @@ -65,7 +65,10 @@ class RCFNum: return self.ctx.ref() def __repr__(self): - return Z3_rcf_num_to_string(self.ctx_ref(), self.num) + return Z3_rcf_num_to_string(self.ctx_ref(), self.num, False) + + def compact_str(self): + return Z3_rcf_num_to_string(self.ctx_ref(), self.num, True) def __add__(self, other): v = _to_rcfnum(other, self.ctx) diff --git a/src/api/z3_rcf.h b/src/api/z3_rcf.h index 87f376117..c46b43255 100644 --- a/src/api/z3_rcf.h +++ b/src/api/z3_rcf.h @@ -173,9 +173,9 @@ extern "C" { /** \brief Convert the RCF numeral into a string. - def_API('Z3_rcf_num_to_string', STRING, (_in(CONTEXT), _in(RCF_NUM))) + def_API('Z3_rcf_num_to_string', STRING, (_in(CONTEXT), _in(RCF_NUM), _in(BOOL))) */ - Z3_string Z3_API Z3_rcf_num_to_string(__in Z3_context c, __in Z3_rcf_num a); + Z3_string Z3_API Z3_rcf_num_to_string(__in Z3_context c, __in Z3_rcf_num a, __in Z3_bool compact); /** \brief Convert the RCF numeral into a string in decimal notation. diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 947b8abfd..593a8c0d2 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -5658,15 +5658,18 @@ namespace realclosure { display(out, a.m_value, true); for (unsigned i = 0; i < c.m_found.size(); i++) { algebraic * ext = c.m_found[i]; - out << ", r!" << ext->idx() << " = "; + out << "; r!" << ext->idx() << " := "; display_algebraic_def(out, ext, true); } out << "]"; } } - void display(std::ostream & out, numeral const & a) const { - display(out, a.m_value, false); + void display(std::ostream & out, numeral const & a, bool compact=false) const { + if (compact) + display_compact(out, a); + else + display(out, a.m_value, false); } void display_non_rational_in_decimal(std::ostream & out, numeral const & a, unsigned precision) { @@ -5927,9 +5930,9 @@ namespace realclosure { return gt(a, _b); } - void manager::display(std::ostream & out, numeral const & a) const { + void manager::display(std::ostream & out, numeral const & a, bool compact) const { save_interval_ctx ctx(this); - m_imp->display(out, a); + m_imp->display(out, a, compact); } void manager::display_decimal(std::ostream & out, numeral const & a, unsigned precision) const { diff --git a/src/math/realclosure/realclosure.h b/src/math/realclosure/realclosure.h index 146299b56..2b70d3be0 100644 --- a/src/math/realclosure/realclosure.h +++ b/src/math/realclosure/realclosure.h @@ -252,7 +252,7 @@ namespace realclosure { bool ge(numeral const & a, mpq const & b) { return !lt(a, b); } bool ge(numeral const & a, mpz const & b) { return !lt(a, b); } - void display(std::ostream & out, numeral const & a) const; + void display(std::ostream & out, numeral const & a, bool compact=false) const; /** \brief Display a real number in decimal notation. From 38e0b4a20aa5d60009cc26f14741c8441d1fb10c Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 14 Jan 2013 11:55:47 -0800 Subject: [PATCH 005/101] Fix bug. Add is_denominator_one macro. Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 94 +++++++++++++--------------- 1 file changed, 44 insertions(+), 50 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 593a8c0d2..878acd570 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -625,7 +625,9 @@ namespace realclosure { SASSERT(!qm().is_zero(b)); scoped_mpbqi bi(bqim()); set_interval(bi, b); - div(a, bi, prec, c); + scoped_mpbqi r(bqim()); + div(a, bi, prec, r); + swap(c, r); } /** @@ -933,6 +935,16 @@ namespace realclosure { bool is_rational_one(value_ref_buffer const & p) const { return p.size() == 1 && is_rational_one(p[0]); } + + bool is_denominator_one(rational_function_value * v) const { + if (v->ext()->is_algebraic()) { + // TODO: add assertion + return true; + } + else { + return is_rational_one(v->den()); + } + } template bool is_one(polynomial const & p) const { @@ -3062,7 +3074,7 @@ namespace realclosure { return qm().is_int(to_mpq(a)); else { rational_function_value * rf_a = to_rational_function(a); - return is_rational_one(rf_a->den()) && has_clean_denominators(rf_a->num()); + return is_denominator_one(rf_a) && has_clean_denominators(rf_a->num()); } } @@ -3297,7 +3309,7 @@ namespace realclosure { } else { rational_function_value * rf_a = to_rational_function(a); - if (is_rational_one(rf_a->den())) + if (!is_denominator_one(rf_a)) return false; else return gcd_int_coeffs(rf_a->num(), g); @@ -3369,7 +3381,7 @@ namespace realclosure { } else { rational_function_value * rf = to_rational_function(a); - SASSERT(is_rational_one(rf->den())); + SASSERT(is_denominator_one(rf)); value_ref_buffer new_ais(*this); value_ref ai(*this); polynomial const & p = rf->num(); @@ -4026,7 +4038,7 @@ namespace realclosure { extension and coefficients of the rational function. */ void update_rf_interval(rational_function_value * v, unsigned prec) { - if (is_rational_one(v->den())) { + if (is_denominator_one(v)) { polynomial_interval(v->num(), v->ext()->interval(), v->interval()); } else { @@ -4181,8 +4193,7 @@ namespace realclosure { bool refine_algebraic_interval(rational_function_value * v, unsigned prec) { SASSERT(v->ext()->is_algebraic()); polynomial const & n = v->num(); - polynomial const & d = v->den(); - SASSERT(is_rational_one(d)); + SASSERT(is_denominator_one(v)); unsigned _prec = prec; while (true) { if (!refine_coeffs_interval(n, _prec) || @@ -4637,7 +4648,7 @@ namespace realclosure { tout << "\ninterval: "; bqim().display(tout, v->interval()); tout << "\n";); algebraic * x = to_algebraic(v->ext()); scoped_mpbqi num_interval(bqim()); - SASSERT(is_rational_one(v->den())); + SASSERT(is_denominator_one(v)); if (!expensive_algebraic_poly_interval(v->num(), x, num_interval)) return false; // it is zero SASSERT(!contains_zero(num_interval)); @@ -4780,22 +4791,6 @@ namespace realclosure { rem(sz1, p1, p.size(), p.c_ptr(), new_p1); } - /** - \brief Apply normalize_algebraic (if applicable) & normalize_fraction. - */ - void normalize_all(extension * x, unsigned sz1, value * const * p1, unsigned sz2, value * const * p2, value_ref_buffer & new_p1, value_ref_buffer & new_p2) { - if (x->is_algebraic()) { - SASSERT(sz2 == 1); - SASSERT(is_rational_one(p2[0])); - value_ref_buffer p1_norm(*this); - normalize_algebraic(to_algebraic(x), sz1, p1, new_p1); - new_p2.reset(); new_p2.push_back(one()); - } - else { - normalize_fraction(sz1, p1, sz2, p2, new_p1, new_p2); - } - } - /** \brief Create a new value using the a->ext(), and the given numerator and denominator. Use interval(a) + interval(b) as an initial approximation for the interval of the result, and invoke determine_sign() @@ -4804,7 +4799,7 @@ namespace realclosure { SASSERT(num_sz > 0 && den_sz > 0); if (num_sz == 1 && den_sz == 1) { // In this case, the normalization rules guarantee that den is one. - SASSERT(is_rational_one(den[0])); + SASSERT(a->ext()->is_algebraic() || is_rational_one(den[0])); r = num[0]; } else { @@ -4826,7 +4821,7 @@ namespace realclosure { \brief Add a value of 'a' the form n/1 with b where rank(a) > rank(b) */ void add_p_v(rational_function_value * a, value * b, value_ref & r) { - SASSERT(is_rational_one(a->den())); + SASSERT(is_denominator_one(a)); SASSERT(compare_rank(a, b) > 0); polynomial const & an = a->num(); polynomial const & one = a->den(); @@ -4844,12 +4839,12 @@ namespace realclosure { value_ref_buffer b_ad(*this); value_ref_buffer num(*this); polynomial const & an = a->num(); - polynomial const & ad = a->den(); - if (is_rational_one(ad)) { + if (is_denominator_one(a)) { add_p_v(a, b, r); } else { SASSERT(!a->ext()->is_algebraic()); + polynomial const & ad = a->den(); // b_ad <- b * ad mul(b, ad.size(), ad.c_ptr(), b_ad); // num <- a + b * ad @@ -4859,7 +4854,7 @@ namespace realclosure { else { value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); - normalize_all(a->ext(), num.size(), num.c_ptr(), ad.size(), ad.c_ptr(), new_num, new_den); + normalize_fraction(num.size(), num.c_ptr(), ad.size(), ad.c_ptr(), new_num, new_den); if (new_num.empty()) r = 0; else @@ -4872,8 +4867,8 @@ namespace realclosure { \brief Add values 'a' and 'b' of the form n/1 and rank(a) == rank(b) */ void add_p_p(rational_function_value * a, rational_function_value * b, value_ref & r) { - SASSERT(is_rational_one(a->den())); - SASSERT(is_rational_one(b->den())); + SASSERT(is_denominator_one(a)); + SASSERT(is_denominator_one(b)); SASSERT(compare_rank(a, b) == 0); polynomial const & an = a->num(); polynomial const & one = a->den(); @@ -4898,14 +4893,14 @@ namespace realclosure { void add_rf_rf(rational_function_value * a, rational_function_value * b, value_ref & r) { SASSERT(compare_rank(a, b) == 0); polynomial const & an = a->num(); - polynomial const & ad = a->den(); polynomial const & bn = b->num(); - polynomial const & bd = b->den(); - if (is_rational_one(ad) && is_rational_one(bd)) { + if (is_denominator_one(a) && is_denominator_one(b)) { add_p_p(a, b, r); } else { SASSERT(!a->ext()->is_algebraic()); + polynomial const & ad = a->den(); + polynomial const & bd = b->den(); value_ref_buffer an_bd(*this); value_ref_buffer bn_ad(*this); mul(an.size(), an.c_ptr(), bd.size(), bd.c_ptr(), an_bd); @@ -4920,7 +4915,7 @@ namespace realclosure { mul(ad.size(), ad.c_ptr(), bd.size(), bd.c_ptr(), den); value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); - normalize_all(a->ext(), num.size(), num.c_ptr(), den.size(), den.c_ptr(), new_num, new_den); + normalize_fraction(num.size(), num.c_ptr(), den.size(), den.c_ptr(), new_num, new_den); if (new_num.empty()) r = 0; else @@ -5020,7 +5015,7 @@ namespace realclosure { SASSERT(num_sz > 0 && den_sz > 0); if (num_sz == 1 && den_sz == 1) { // In this case, the normalization rules guarantee that den is one. - SASSERT(is_rational_one(den[0])); + SASSERT(a->ext()->is_algebraic() || is_rational_one(den[0])); r = num[0]; } else { @@ -5042,7 +5037,7 @@ namespace realclosure { \brief Multiply a value of 'a' the form n/1 with b where rank(a) > rank(b) */ void mul_p_v(rational_function_value * a, value * b, value_ref & r) { - SASSERT(is_rational_one(a->den())); + SASSERT(is_denominator_one(a)); SASSERT(b != 0); SASSERT(compare_rank(a, b) > 0); polynomial const & an = a->num(); @@ -5059,19 +5054,19 @@ namespace realclosure { */ void mul_rf_v(rational_function_value * a, value * b, value_ref & r) { polynomial const & an = a->num(); - polynomial const & ad = a->den(); - if (is_rational_one(ad)) { + if (is_denominator_one(a)) { mul_p_v(a, b, r); } else { SASSERT(!a->ext()->is_algebraic()); + polynomial const & ad = a->den(); value_ref_buffer num(*this); // num <- b * an mul(b, an.size(), an.c_ptr(), num); SASSERT(num.size() == an.size()); value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); - normalize_all(a->ext(), num.size(), num.c_ptr(), ad.size(), ad.c_ptr(), new_num, new_den); + normalize_fraction(num.size(), num.c_ptr(), ad.size(), ad.c_ptr(), new_num, new_den); SASSERT(!new_num.empty()); mk_mul_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } @@ -5081,8 +5076,8 @@ namespace realclosure { \brief Multiply values 'a' and 'b' of the form n/1 and rank(a) == rank(b) */ void mul_p_p(rational_function_value * a, rational_function_value * b, value_ref & r) { - SASSERT(is_rational_one(a->den())); - SASSERT(is_rational_one(b->den())); + SASSERT(is_denominator_one(a)); + SASSERT(is_denominator_one(b)); SASSERT(compare_rank(a, b) == 0); polynomial const & an = a->num(); polynomial const & one = a->den(); @@ -5092,7 +5087,6 @@ namespace realclosure { SASSERT(!new_num.empty()); extension * x = a->ext(); if (x->is_algebraic()) { - // FUTURE: we don't need to invoke normalize_algebraic if degree of new_num < degree x->p() value_ref_buffer new_num2(*this); normalize_algebraic(to_algebraic(x), new_num.size(), new_num.c_ptr(), new_num2); SASSERT(!new_num.empty()); @@ -5109,14 +5103,14 @@ namespace realclosure { void mul_rf_rf(rational_function_value * a, rational_function_value * b, value_ref & r) { SASSERT(compare_rank(a, b) == 0); polynomial const & an = a->num(); - polynomial const & ad = a->den(); polynomial const & bn = b->num(); - polynomial const & bd = b->den(); - if (is_rational_one(ad) && is_rational_one(bd)) { + if (is_denominator_one(a) && is_denominator_one(b)) { mul_p_p(a, b, r); } else { SASSERT(!a->ext()->is_algebraic()); + polynomial const & ad = a->den(); + polynomial const & bd = b->den(); value_ref_buffer num(*this); value_ref_buffer den(*this); mul(an.size(), an.c_ptr(), bn.size(), bn.c_ptr(), num); @@ -5124,7 +5118,7 @@ namespace realclosure { SASSERT(!num.empty()); SASSERT(!den.empty()); value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); - normalize_all(a->ext(), num.size(), num.c_ptr(), den.size(), den.c_ptr(), new_num, new_den); + normalize_fraction(num.size(), num.c_ptr(), den.size(), den.c_ptr(), new_num, new_den); SASSERT(!new_num.empty()); mk_mul_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } @@ -5245,7 +5239,7 @@ namespace realclosure { */ void inv_algebraic(rational_function_value * a, value_ref & r) { SASSERT(a->ext()->is_algebraic()); - SASSERT(is_rational_one(a->den())); + SASSERT(is_denominator_one(a)); algebraic * x = to_algebraic(a->ext()); polynomial const & q = a->num(); value_ref_buffer new_num(*this); @@ -5489,7 +5483,7 @@ namespace realclosure { if (is_zero(v) || is_nz_rational(v)) return false; rational_function_value * rf = to_rational_function(v); - return num_nz_coeffs(rf->num()) > 1 || !is_rational_one(rf->den()); + return num_nz_coeffs(rf->num()) > 1 || !is_denominator_one(rf); } template @@ -5628,7 +5622,7 @@ namespace realclosure { qm().display(out, to_mpq(v)); else { rational_function_value * rf = to_rational_function(v); - if (is_rational_one(rf->den())) { + if (is_denominator_one(rf)) { display_polynomial_expr(out, rf->num(), rf->ext(), compact); } else if (is_rational_one(rf->num())) { From 025cb2a2a8fd161e68e847ba4ac742d2e40a77ae Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 14 Jan 2013 12:03:22 -0800 Subject: [PATCH 006/101] Avoid wasteful memory allocation Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 29 ++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 878acd570..71f0164ba 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -938,7 +938,7 @@ namespace realclosure { bool is_denominator_one(rational_function_value * v) const { if (v->ext()->is_algebraic()) { - // TODO: add assertion + SASSERT(v->den().size() == 0); // we do not use denominator for algebraic extensions return true; } else { @@ -1226,7 +1226,16 @@ namespace realclosure { rational_function_value * r = alloc(rational_function_value, ext); inc_ref(ext); set_p(r->num(), num_sz, num); - set_p(r->den(), den_sz, den); + if (ext->is_algebraic()) { + // Avoiding wasteful allocation... + // We do not use the denominator for algebraic extensions + SASSERT(den_sz == 0 || (den_sz == 1 && is_rational_one(den[0]))); + + SASSERT(r->den().size() == 0); + } + else { + set_p(r->den(), den_sz, den); + } r->set_depends_on_infinitesimals(depends_on_infinitesimals(ext) || depends_on_infinitesimals(num_sz, num) || depends_on_infinitesimals(den_sz, den)); return r; } @@ -4796,10 +4805,12 @@ namespace realclosure { Use interval(a) + interval(b) as an initial approximation for the interval of the result, and invoke determine_sign() */ void mk_add_value(rational_function_value * a, value * b, unsigned num_sz, value * const * num, unsigned den_sz, value * const * den, value_ref & r) { - SASSERT(num_sz > 0 && den_sz > 0); - if (num_sz == 1 && den_sz == 1) { + SASSERT(num_sz > 0); + // den_sz may be zero for algebraic extensions. + // We do not use denominators for algebraic extensions. + if (num_sz == 1 && den_sz <= 1) { // In this case, the normalization rules guarantee that den is one. - SASSERT(a->ext()->is_algebraic() || is_rational_one(den[0])); + SASSERT(den_sz == 0 || is_rational_one(den[0])); r = num[0]; } else { @@ -5012,10 +5023,12 @@ namespace realclosure { Use interval(a) * interval(b) as an initial approximation for the interval of the result, and invoke determine_sign() */ void mk_mul_value(rational_function_value * a, value * b, unsigned num_sz, value * const * num, unsigned den_sz, value * const * den, value_ref & r) { - SASSERT(num_sz > 0 && den_sz > 0); - if (num_sz == 1 && den_sz == 1) { + SASSERT(num_sz > 0); + if (num_sz == 1 && den_sz <= 1) { + // den_sz may be zero for algebraic extensions. + // We do not use denominators for algebraic extensions. // In this case, the normalization rules guarantee that den is one. - SASSERT(a->ext()->is_algebraic() || is_rational_one(den[0])); + SASSERT(den_sz == 0 || is_rational_one(den[0])); r = num[0]; } else { From 991a1528cdb38ceaec386954eb3d0bf3202a20fe Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 14 Jan 2013 12:17:15 -0800 Subject: [PATCH 007/101] Cache isolating interval for better pretty printing Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 71f0164ba..f76fe8039 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -281,7 +281,8 @@ namespace realclosure { struct algebraic : public extension { polynomial m_p; - sign_det * m_sign_det; //!< != 0 if m_interval constains more than one root of m_p. + mpbqi m_iso_interval; + sign_det * m_sign_det; //!< != 0 if m_iso_interval constains more than one root of m_p. unsigned m_sc_idx; //!< != UINT_MAX if m_sign_det != 0, in this case m_sc_idx < m_sign_det->m_sign_conditions.size() bool m_depends_on_infinitesimals; //!< True if the polynomial p depends on infinitesimal extensions. @@ -292,6 +293,7 @@ namespace realclosure { sign_det * sdt() const { return m_sign_det; } unsigned sc_idx() const { return m_sc_idx; } unsigned num_roots_inside_interval() const { return m_sign_det == 0 ? 1 : m_sign_det->num_roots(); } + mpbqi & iso_interval() { return m_iso_interval; } }; struct transcendental : public extension { @@ -808,6 +810,7 @@ namespace realclosure { void del_algebraic(algebraic * a) { reset_p(a->m_p); bqim().del(a->m_interval); + bqim().del(a->m_iso_interval); dec_ref_sign_det(a->m_sign_det); allocator().deallocate(sizeof(algebraic), a); } @@ -1793,6 +1796,7 @@ namespace realclosure { set_p(r->m_p, p_sz, p); set_interval(r->m_interval, interval); + set_interval(r->m_iso_interval, interval); r->m_sign_det = sd; inc_ref_sign_det(sd); r->m_sc_idx = sc_idx; @@ -5603,7 +5607,7 @@ namespace realclosure { out << "root("; display_polynomial(out, a->p(), display_free_var_proc(), compact); out << ", "; - bqim().display(out, a->interval()); + bqim().display(out, a->iso_interval()); out << ", "; if (a->sdt() != 0) display_sign_conditions(out, a->sdt()->sc(a->sc_idx()), a->sdt()->qs(), compact); From 799fe073db308b9e4a8d364a01521b5af1412a90 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 14 Jan 2013 14:20:52 -0800 Subject: [PATCH 008/101] Add API for extracting numerator/denominator of RCF numerals. Add field to store the original isolating interval before refinement. Signed-off-by: Leonardo de Moura --- src/api/api_rcf.cpp | 13 +++ src/api/python/z3rcf.py | 5 ++ src/api/z3_rcf.h | 8 ++ src/math/realclosure/realclosure.cpp | 122 ++++++++++++++++----------- 4 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/api/api_rcf.cpp b/src/api/api_rcf.cpp index 145f8f824..c52a35f5f 100644 --- a/src/api/api_rcf.cpp +++ b/src/api/api_rcf.cpp @@ -290,4 +290,17 @@ extern "C" { Z3_CATCH_RETURN(""); } + void Z3_API Z3_rcf_get_numerator_denominator(Z3_context c, Z3_rcf_num a, Z3_rcf_num * n, Z3_rcf_num * d) { + Z3_TRY; + LOG_Z3_rcf_get_numerator_denominator(c, a, n, d); + RESET_ERROR_CODE(); + reset_rcf_cancel(c); + rcnumeral _n, _d; + rcfm(c).clean_denominators(to_rcnumeral(a), _n, _d); + *n = from_rcnumeral(_n); + *d = from_rcnumeral(_d); + RETURN_Z3_rcf_get_numerator_denominator; + Z3_CATCH; + } + }; diff --git a/src/api/python/z3rcf.py b/src/api/python/z3rcf.py index f63fc7efd..b9c947b9f 100644 --- a/src/api/python/z3rcf.py +++ b/src/api/python/z3rcf.py @@ -154,3 +154,8 @@ class RCFNum: v = _to_rcfnum(other, self.ctx) return Z3_rcf_neq(self.ctx_ref(), self.num, v.num) + def split(self): + n = (RCFNumObj * 1)() + d = (RCFNumObj * 1)() + Z3_rcf_get_numerator_denominator(self.ctx_ref(), self.num, n, d) + return (RCFNum(n[0], self.ctx), RCFNum(d[0], self.ctx)) diff --git a/src/api/z3_rcf.h b/src/api/z3_rcf.h index c46b43255..305033690 100644 --- a/src/api/z3_rcf.h +++ b/src/api/z3_rcf.h @@ -184,6 +184,14 @@ extern "C" { */ Z3_string Z3_API Z3_rcf_num_to_decimal_string(__in Z3_context c, __in Z3_rcf_num a, __in unsigned prec); + /** + \brief Extract the "numerator" and "denominator" of the given RCF numeral. + We have that a = n/d, moreover n and d are not represented using rational functions. + + def_API('Z3_rcf_get_numerator_denominator', VOID, (_in(CONTEXT), _in(RCF_NUM), _out(RCF_NUM), _out(RCF_NUM))) + */ + void Z3_API Z3_rcf_get_numerator_denominator(__in Z3_context c, __in Z3_rcf_num a, __out Z3_rcf_num * n, __out Z3_rcf_num * d); + #ifdef __cplusplus }; #endif // __cplusplus diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index f76fe8039..d9892e689 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -1788,7 +1788,7 @@ namespace realclosure { /** \brief Create a new algebraic extension */ - algebraic * mk_algebraic(unsigned p_sz, value * const * p, mpbqi const & interval, sign_det * sd, unsigned sc_idx) { + algebraic * mk_algebraic(unsigned p_sz, value * const * p, mpbqi const & interval, mpbqi const & iso_interval, sign_det * sd, unsigned sc_idx) { unsigned idx = next_algebraic_idx(); void * mem = allocator().allocate(sizeof(algebraic)); algebraic * r = new (mem) algebraic(idx); @@ -1796,7 +1796,7 @@ namespace realclosure { set_p(r->m_p, p_sz, p); set_interval(r->m_interval, interval); - set_interval(r->m_iso_interval, interval); + set_interval(r->m_iso_interval, iso_interval); r->m_sign_det = sd; inc_ref_sign_det(sd); r->m_sc_idx = sc_idx; @@ -1808,8 +1808,8 @@ namespace realclosure { /** \brief Add a new root of p that is isolated by (interval, sd, sc_idx) to roots. */ - void add_root(unsigned p_sz, value * const * p, mpbqi const & interval, sign_det * sd, unsigned sc_idx, numeral_vector & roots) { - algebraic * a = mk_algebraic(p_sz, p, interval, sd, sc_idx); + void add_root(unsigned p_sz, value * const * p, mpbqi const & interval, mpbqi const & iso_interval, sign_det * sd, unsigned sc_idx, numeral_vector & roots) { + algebraic * a = mk_algebraic(p_sz, p, interval, iso_interval, sd, sc_idx); numeral r; set(r, mk_rational_function_value(a)); roots.push_back(r); @@ -1819,8 +1819,8 @@ namespace realclosure { \brief Simpler version of add_root that does not use sign_det data-structure. That is, interval contains only one root of p. */ - void add_root(unsigned p_sz, value * const * p, mpbqi const & interval, numeral_vector & roots) { - add_root(p_sz, p, interval, 0, UINT_MAX, roots); + void add_root(unsigned p_sz, value * const * p, mpbqi const & interval, mpbqi const & iso_interval, numeral_vector & roots) { + add_root(p_sz, p, interval, iso_interval, 0, UINT_MAX, roots); } /** @@ -1922,7 +1922,7 @@ namespace realclosure { \pre num_roots is the number of roots in the given interval */ - void sign_det_isolate_roots(unsigned p_sz, value * const * p, int num_roots, mpbqi const & interval, numeral_vector & roots) { + void sign_det_isolate_roots(unsigned p_sz, value * const * p, int num_roots, mpbqi const & interval, mpbqi const & iso_interval, numeral_vector & roots) { SASSERT(num_roots >= 2); scoped_polynomial_seq der_seq(*this); mk_derivatives(p_sz, p, der_seq); @@ -1992,7 +1992,7 @@ namespace realclosure { // q is a derivative of p. int q_eq_0, q_gt_0, q_lt_0; value_ref_buffer q2(*this); - count_signs_at_zeros(p_sz, p, q_sz, q, interval, num_roots, q_eq_0, q_gt_0, q_lt_0, q2); + count_signs_at_zeros(p_sz, p, q_sz, q, iso_interval, num_roots, q_eq_0, q_gt_0, q_lt_0, q2); TRACE("rcf_sign_det", tout << "q: "; display_poly(tout, q_sz, q); tout << "\n"; tout << "#(q == 0): " << q_eq_0 << ", #(q > 0): " << q_gt_0 << ", #(q < 0): " << q_lt_0 << "\n";); @@ -2003,7 +2003,7 @@ namespace realclosure { } bool use_q2 = M.n() == 3; mm().tensor_product(M_s, M, new_M_s); - expand_taqrs(taqrs, prs, p_sz, p, q_sz, q, use_q2, q2.size(), q2.c_ptr(), interval, + expand_taqrs(taqrs, prs, p_sz, p, q_sz, q, use_q2, q2.size(), q2.c_ptr(), iso_interval, // ---> new_taqrs, new_prs); SASSERT(new_M_s.n() == new_M_s.m()); // it is a square matrix @@ -2090,7 +2090,7 @@ namespace realclosure { SASSERT(M_s.n() == M_s.m()); SASSERT(M_s.n() == static_cast(num_roots)); sign_det * sd = mk_sign_det(M_s, prs, taqrs, qs, scs); for (unsigned idx = 0; idx < static_cast(num_roots); idx++) { - add_root(p_sz, p, interval, sd, idx, roots); + add_root(p_sz, p, interval, iso_interval, sd, idx, roots); } } @@ -2175,7 +2175,7 @@ namespace realclosure { m_p_sz(p_sz), m_p(p), m_depends_on_infinitesimals(dinf), m_sturm_seq(seq), m_result_roots(roots) {} }; - void bisect_isolate_roots(mpbqi & interval, int lower_sv, int upper_sv, bisect_ctx & ctx) { + void bisect_isolate_roots(mpbqi & interval, mpbqi & iso_interval, int lower_sv, int upper_sv, bisect_ctx & ctx) { SASSERT(lower_sv >= upper_sv); int num_roots = lower_sv - upper_sv; if (num_roots == 0) { @@ -2192,7 +2192,7 @@ namespace realclosure { } else { // interval is an isolating interval - add_root(ctx.m_p_sz, ctx.m_p, interval, ctx.m_result_roots); + add_root(ctx.m_p_sz, ctx.m_p, interval, iso_interval, ctx.m_result_roots); } } else if (ctx.m_depends_on_infinitesimals && check_precision(interval, m_max_precision)) { @@ -2204,21 +2204,37 @@ namespace realclosure { // - We switch to expensive sign determination procedure, since // the roots may be infinitely close to each other. // - sign_det_isolate_roots(ctx.m_p_sz, ctx.m_p, num_roots, interval, ctx.m_result_roots); + sign_det_isolate_roots(ctx.m_p_sz, ctx.m_p, num_roots, interval, iso_interval, ctx.m_result_roots); } else { scoped_mpbq mid(bqm()); bqm().add(interval.lower(), interval.upper(), mid); bqm().div2(mid); int mid_sv = sign_variations_at(ctx.m_sturm_seq, mid); - scoped_mpbqi left_interval(bqim()); - scoped_mpbqi right_interval(bqim()); - set_lower(left_interval, interval.lower()); - set_upper(left_interval, mid); - set_lower(right_interval, mid); - set_upper(right_interval, interval.upper()); - bisect_isolate_roots(left_interval, lower_sv, mid_sv, ctx); - bisect_isolate_roots(right_interval, mid_sv, upper_sv, ctx); + int num_left_roots = lower_sv - mid_sv; + int num_right_roots = mid_sv - upper_sv; + if (num_left_roots == 0) { + scoped_mpbqi right_interval(bqim()); + set_lower(right_interval, mid); + set_upper(right_interval, interval.upper()); + bisect_isolate_roots(right_interval, iso_interval, mid_sv, upper_sv, ctx); + } + else if (num_right_roots == 0) { + scoped_mpbqi left_interval(bqim()); + set_lower(left_interval, interval.lower()); + set_upper(left_interval, mid); + bisect_isolate_roots(left_interval, iso_interval, lower_sv, mid_sv, ctx); + } + else { + scoped_mpbqi left_interval(bqim()); + scoped_mpbqi right_interval(bqim()); + set_lower(left_interval, interval.lower()); + set_upper(left_interval, mid); + set_lower(right_interval, mid); + set_upper(right_interval, interval.upper()); + bisect_isolate_roots(left_interval, left_interval, lower_sv, mid_sv, ctx); + bisect_isolate_roots(right_interval, right_interval, mid_sv, upper_sv, ctx); + } } } @@ -2226,7 +2242,7 @@ namespace realclosure { \brief Entry point for the root isolation procedure based on bisection. */ void bisect_isolate_roots(// Input values - unsigned p_sz, value * const * p, mpbqi & interval, + unsigned p_sz, value * const * p, mpbqi & interval, mpbqi & iso_interval, // Extra Input values with already computed information scoped_polynomial_seq & sturm_seq, // sturm sequence for p int lower_sv, // number of sign variations at the lower bound of interval @@ -2235,7 +2251,7 @@ namespace realclosure { numeral_vector & roots) { bool dinf = depends_on_infinitesimals(p_sz, p); bisect_ctx ctx(p_sz, p, dinf, sturm_seq, roots); - bisect_isolate_roots(interval, lower_sv, upper_sv, ctx); + bisect_isolate_roots(interval, iso_interval, lower_sv, upper_sv, ctx); } /** @@ -2279,37 +2295,37 @@ namespace realclosure { scoped_mpbqi neg_interval(bqim()); mk_neg_interval(has_neg_lower, neg_lower_N, has_neg_upper, neg_upper_N, neg_interval); mk_pos_interval(has_pos_lower, pos_lower_N, has_pos_upper, pos_upper_N, pos_interval); - + scoped_mpbqi minf_zero(bqim()); + set_lower_inf(minf_zero); + set_upper_zero(minf_zero); + scoped_mpbqi zero_inf(bqim()); + set_lower_zero(zero_inf); + set_upper_inf(zero_inf); + if (num_neg_roots > 0) { if (num_neg_roots == 1) { - add_root(n, p, neg_interval, 0, UINT_MAX, roots); + add_root(n, p, neg_interval, minf_zero, 0, UINT_MAX, roots); } else { if (has_neg_lower) { - bisect_isolate_roots(n, p, neg_interval, seq, num_sv_minus_inf, num_sv_zero, roots); + bisect_isolate_roots(n, p, neg_interval, minf_zero, seq, num_sv_minus_inf, num_sv_zero, roots); } else { - scoped_mpbqi minf_zero(bqim()); - set_lower_inf(minf_zero); - set_upper_zero(minf_zero); - sign_det_isolate_roots(n, p, num_neg_roots, minf_zero, roots); + sign_det_isolate_roots(n, p, num_neg_roots, minf_zero, minf_zero, roots); } } } if (num_pos_roots > 0) { if (num_pos_roots == 1) { - add_root(n, p, pos_interval, 0, UINT_MAX, roots); + add_root(n, p, pos_interval, zero_inf, 0, UINT_MAX, roots); } else { if (has_pos_upper) { - bisect_isolate_roots(n, p, pos_interval, seq, num_sv_zero, num_sv_plus_inf, roots); + bisect_isolate_roots(n, p, pos_interval, zero_inf, seq, num_sv_zero, num_sv_plus_inf, roots); } else { - scoped_mpbqi zero_inf(bqim()); - set_lower_zero(zero_inf); - set_upper_inf(zero_inf); - sign_det_isolate_roots(n, p, num_pos_roots, zero_inf, roots); + sign_det_isolate_roots(n, p, num_pos_roots, zero_inf, zero_inf, roots); } } } @@ -3132,7 +3148,13 @@ namespace realclosure { value_ref_buffer p_num(*this), p_den(*this); value_ref d_num(*this), d_den(*this); clean_denominators_core(rf_a->num(), p_num, d_num); - clean_denominators_core(rf_a->den(), p_den, d_den); + if (is_denominator_one(rf_a)) { + p_den.push_back(one()); + d_den = one(); + } + else { + clean_denominators_core(rf_a->den(), p_den, d_den); + } value_ref x(*this); x = mk_rational_function_value(rf_a->ext()); mk_polynomial_value(p_num.size(), p_num.c_ptr(), x, p); @@ -3141,6 +3163,11 @@ namespace realclosure { mul(p, d_den, p); mul(q, d_num, q); } + if (sign(q) < 0) { + // make sure the denominator is positive + neg(p, p); + neg(q, q); + } } } @@ -3150,6 +3177,7 @@ namespace realclosure { and has_clean_denominators(clean_p) && has_clean_denominators(d) */ void clean_denominators_core(unsigned p_sz, value * const * p, value_ref_buffer & norm_p, value_ref & d) { + SASSERT(p_sz >= 1); value_ref_buffer nums(*this), dens(*this); value_ref a_n(*this), a_d(*this); bool all_one = true; @@ -4488,7 +4516,7 @@ namespace realclosure { int num_roots = x->num_roots_inside_interval(); SASSERT(x->sdt() != 0 || num_roots == 1); polynomial const & p = x->p(); - int taq_p_q = TaQ(p.size(), p.c_ptr(), q.size(), q.c_ptr(), x->interval()); + int taq_p_q = TaQ(p.size(), p.c_ptr(), q.size(), q.c_ptr(), x->iso_interval()); if (num_roots == 1 && taq_p_q == 0) return false; // q(x) is zero if (taq_p_q == num_roots) { @@ -4514,7 +4542,7 @@ namespace realclosure { SASSERT(x->sdt() != 0); int q_eq_0, q_gt_0, q_lt_0; value_ref_buffer q2(*this); - count_signs_at_zeros_core(taq_p_q, p.size(), p.c_ptr(), q.size(), q.c_ptr(), x->interval(), num_roots, q_eq_0, q_gt_0, q_lt_0, q2); + count_signs_at_zeros_core(taq_p_q, p.size(), p.c_ptr(), q.size(), q.c_ptr(), x->iso_interval(), num_roots, q_eq_0, q_gt_0, q_lt_0, q2); if (q_eq_0 > 0 && q_gt_0 == 0 && q_lt_0 == 0) { // q(x) is zero return false; @@ -4536,7 +4564,7 @@ namespace realclosure { // sdt.M_s * [1, ..., 1]^t = sdt.taqrs()^t // That is, // [1, ..., 1]^t = sdt.M_s^-1 * sdt.taqrs()^t - // Moreover the number of roots in x->interval() is equal to the number of rows and columns in sdt.M_s. + // Moreover the number of roots in x->iso_interval() is equal to the number of rows and columns in sdt.M_s. // The column j of std.M_s is associated with the sign condition sdt.m_scs[j]. // The row i of sdt.M_s is associated with the polynomial sdt.prs()[i]. // @@ -4548,21 +4576,21 @@ namespace realclosure { scoped_mpz_matrix new_M_s(mm()); mm().tensor_product(sdt.M_s, M, new_M_s); array const & prs = sdt.prs(); // polynomials associated with the rows of M_s - array const & taqrs = sdt.taqrs(); // For each i in [0, taqrs.size()) TaQ(p, prs[i]; x->interval()) == taqrs[i] + array const & taqrs = sdt.taqrs(); // For each i in [0, taqrs.size()) TaQ(p, prs[i]; x->iso_interval()) == taqrs[i] SASSERT(prs.size() == taqrs.size()); int_buffer new_taqrs; value_ref_buffer prq(*this); // fill new_taqrs using taqrs and the new tarski queries containing q (and q^2 when use_q2 == true). for (unsigned i = 0; i < taqrs.size(); i++) { - // Add TaQ(p, prs[i] * 1; x->interval()) + // Add TaQ(p, prs[i] * 1; x->iso_interval()) new_taqrs.push_back(taqrs[i]); - // Add TaQ(p, prs[i] * q; x->interval()) + // Add TaQ(p, prs[i] * q; x->iso_interval()) mul(prs[i].size(), prs[i].c_ptr(), q.size(), q.c_ptr(), prq); - new_taqrs.push_back(TaQ(p.size(), p.c_ptr(), prq.size(), prq.c_ptr(), x->interval())); + new_taqrs.push_back(TaQ(p.size(), p.c_ptr(), prq.size(), prq.c_ptr(), x->iso_interval())); if (use_q2) { - // Add TaQ(p, prs[i] * q^2; x->interval()) + // Add TaQ(p, prs[i] * q^2; x->iso_interval()) mul(prs[i].size(), prs[i].c_ptr(), q2.size(), q2.c_ptr(), prq); - new_taqrs.push_back(TaQ(p.size(), p.c_ptr(), prq.size(), prq.c_ptr(), x->interval())); + new_taqrs.push_back(TaQ(p.size(), p.c_ptr(), prq.size(), prq.c_ptr(), x->iso_interval())); } } int_buffer sc_cardinalities; @@ -4590,7 +4618,7 @@ namespace realclosure { } }); // Remark: - // Note that we found the sign of q for every root of p in the interval x->interval() :) + // Note that we found the sign of q for every root of p in the interval x->iso_interval() :) unsigned sc_idx = x->sc_idx(); if (use_q2) { if (sc_cardinalities[3*sc_idx] == 1) { From f0737bdf7f7fccdc575f425215cf52fc03dbea43 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 14 Jan 2013 18:30:36 -0800 Subject: [PATCH 009/101] Replace expensive_eval_sign_at with version that does not generate rational numbers Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 39 +++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index d9892e689..7982e28b4 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -3784,13 +3784,40 @@ namespace realclosure { \brief Evaluate the sign of p(b) by computing a value object. */ int expensive_eval_sign_at(unsigned n, value * const * p, mpbq const & b) { - SASSERT(n > 0); + SASSERT(n > 1); SASSERT(p[n - 1] != 0); - value_ref _b(*this); - _b = mk_rational(b); - value_ref pb(*this); - mk_polynomial_value(n, p, _b, pb); - return sign(pb); + // Actually, given b = c/2^k, we compute the sign of (2^k)^n*p(c) + // Original Horner Sequence + // ((a_n * b + a_{n-1})*b + a_{n-2})*b + a_{n-3} ... + // Variation of the Horner Sequence for (2^k)^n*p(b) + // ((a_n * c + a_{n-1}*2_k)*c + a_{n-2}*(2_k)^2)*c + a_{n-3}*(2_k)^3 ... + a_0*(2_k)^n + scoped_mpz mpz_twok(qm()); + qm().mul2k(mpz(1), b.k(), mpz_twok); + value_ref twok(*this), twok_i(*this); + twok = mk_rational(mpz_twok); + twok_i = twok; + value_ref c(*this); + c = mk_rational(b.numerator()); + + value_ref r(*this), ak(*this), rc(*this); + + r = p[n-1]; + unsigned i = n-1; + while (i > 0) { + --i; + if (is_zero(p[i])) { + mul(r, c, r); + } + else { + // ak <- a_i * (2^k)^(n-i) + mul(p[i], twok_i, ak); + // r <- r * c + a_i * (2^k)^(n-i) + mul(r, c, rc); + add(ak, rc, r); + } + mul(twok_i, twok, twok_i); + } + return sign(r); } /** From 5f0cb28ca39cfa83c4a7d10cf703f126e316ec5f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Jan 2013 17:05:31 +0000 Subject: [PATCH 010/101] .NET and Java APIs: added functions for global parameter management. Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 3 +- src/api/dotnet/Global.cs | 87 ++++++++++++++++++++++++++++++ src/api/dotnet/Microsoft.Z3.csproj | 1 + src/api/java/Global.java | 67 +++++++++++++++++++++++ 4 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 src/api/dotnet/Global.cs create mode 100644 src/api/java/Global.java diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index aee60c43f..6d322394c 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3518,8 +3518,7 @@ namespace Microsoft.Z3 public string GetParamValue(string id) { IntPtr res = IntPtr.Zero; - int r = Native.Z3_get_param_value(nCtx, id, out res); - if (r == (int)Z3_lbool.Z3_L_FALSE) + if (Native.Z3_get_param_value(nCtx, id, out res) == 0) return null; else return Marshal.PtrToStringAnsi(res); diff --git a/src/api/dotnet/Global.cs b/src/api/dotnet/Global.cs new file mode 100644 index 000000000..707264c82 --- /dev/null +++ b/src/api/dotnet/Global.cs @@ -0,0 +1,87 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Global.cs + +Abstract: + + Z3 Managed API: Global Functions + +Author: + + Christoph Wintersteiger (cwinter) 2013-01-15 + +Notes: + +--*/ + +using System; +using System.Runtime.InteropServices; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Global functions for Z3. + /// + /// + /// This (static) class contains functions that effect the behaviour of Z3 + /// globally across contexts, etc. + /// + public static class Global + { + /// + /// Set a global (or module) parameter, which is shared by all Z3 contexts. + /// + /// + /// When a Z3 module is initialized it will use the value of these parameters + /// when Z3_params objects are not provided. + /// The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + /// The character '.' is a delimiter (more later). + /// The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + /// Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + /// This function can be used to set parameters for a specific Z3 module. + /// This can be done by using .. + /// For example: + /// Z3_global_param_set('pp.decimal', 'true') + /// will set the parameter "decimal" in the module "pp" to true. + /// + public static void SetParameter(string id, string value) + { + Native.Z3_global_param_set(id, value); + } + + /// + /// Get a global (or module) parameter. + /// + /// + /// Returns null if the parameter does not exist. + /// The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + /// This function cannot be invoked simultaneously from different threads without synchronization. + /// The result string stored in param_value is stored in a shared location. + /// + public static string GetParameter(string id) + { + IntPtr t; + if (Native.Z3_global_param_get(id, out t) == 0) + return null; + else + return Marshal.PtrToStringAnsi(t); + } + + + /// + /// Restore the value of all global (and module) parameters. + /// + /// + /// This command will not affect already created objects (such as tactics and solvers) + /// + /// + public static void ResetParameters() + { + Native.Z3_global_param_reset_all(); + } + } +} diff --git a/src/api/dotnet/Microsoft.Z3.csproj b/src/api/dotnet/Microsoft.Z3.csproj index a1bb868eb..8f6e34517 100644 --- a/src/api/dotnet/Microsoft.Z3.csproj +++ b/src/api/dotnet/Microsoft.Z3.csproj @@ -341,6 +341,7 @@ + diff --git a/src/api/java/Global.java b/src/api/java/Global.java new file mode 100644 index 000000000..c08691ded --- /dev/null +++ b/src/api/java/Global.java @@ -0,0 +1,67 @@ +/** + * Global.java + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Global functions for Z3. + * + * This (static) class contains functions that effect the behaviour of Z3 + * globally across contexts, etc. + * + **/ +public final class Global +{ + /** + * Set a global (or module) parameter, which is shared by all Z3 contexts. + * + * When a Z3 module is initialized it will use the value of these parameters + * when Z3_params objects are not provided. + * The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + * The character '.' is a delimiter (more later). + * The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + * Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + * This function can be used to set parameters for a specific Z3 module. + * This can be done by using .. + * For example: + * Z3_global_param_set('pp.decimal', 'true') + * will set the parameter "decimal" in the module "pp" to true. + * + **/ + public static void SetParameter(String id, String value) + { + Native.globalParamSet(id, value); + } + + /** + * Get a global (or module) parameter. + * + * Returns null if the parameter does not exist. + * The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + * This function cannot be invoked simultaneously from different threads without synchronization. + * The result string stored in param_value is stored in a shared location. + * + **/ + public static String GetParameter(String id) + { + Native.StringPtr res = new Native.StringPtr(); + if (!Native.globalParamGet(id, res)) + return null; + else + return res.value; + } + + /** + * Restore the value of all global (and module) parameters. + * + * This command will not affect already created objects (such as tactics and solvers) + * + * @seealso SetParameter + **/ + public static void ResetParameters() + { + Native.globalParamResetAll(); + } +} From ca5eb5186d003afe910463b20850a809c24961f0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 15 Jan 2013 09:24:12 -0800 Subject: [PATCH 011/101] fix pretty printer for smt2 unary minus Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt_pp.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 66b467b92..3dc94d3b3 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -401,7 +401,12 @@ class smt_printer { if (m_autil.is_numeral(n, val, is_int)) { if (val.is_neg()) { val.neg(); - m_out << "(~ "; + if (m_is_smt2) { + m_out << "(- "; + } + else { + m_out << "(~ "; + } display_rational(val, is_int); m_out << ")"; } From 217c8375ce0fc9de72446e79039cdf710492d50b Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Tue, 15 Jan 2013 08:39:30 -0800 Subject: [PATCH 012/101] Add new rational function normalization procedure. Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 139 ++++++++++++++++----------- 1 file changed, 82 insertions(+), 57 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 7982e28b4..8f9697d98 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -3450,6 +3450,10 @@ namespace realclosure { // // --------------------------------- + bool is_monic(value_ref_buffer const & p) { + return p.size() > 0 && is_rational_one(p[p.size() - 1]); + } + /** \brief Force the leading coefficient of p to be 1. */ @@ -4762,14 +4766,20 @@ namespace realclosure { bool determine_sign(rational_function_value * v) { if (!contains_zero(v->interval())) return true; + bool r; switch (v->ext()->knd()) { - case extension::TRANSCENDENTAL: determine_transcendental_sign(v); return true; // it is never zero - case extension::INFINITESIMAL: determine_infinitesimal_sign(v); return true; // it is never zero - case extension::ALGEBRAIC: return determine_algebraic_sign(v); + case extension::TRANSCENDENTAL: determine_transcendental_sign(v); r = true; break; // it is never zero + case extension::INFINITESIMAL: determine_infinitesimal_sign(v); r = true; break; // it is never zero + case extension::ALGEBRAIC: r = determine_algebraic_sign(v); break; default: UNREACHABLE(); - return false; + r = false; } + TRACE("rcf_determine_sign_bug", + tout << "result: " << r << "\n"; + display_compact(tout, v); tout << "\n"; + tout << "sign: " << sign(v) << "\n";); + return r; } bool determine_sign(value_ref & r) { @@ -4784,10 +4794,10 @@ namespace realclosure { // --------------------------------- /** - \brief Set new_p1 and new_p2 using the following normalization rules: - - new_p1 <- p1/p2[0]; new_p2 <- one IF sz2 == 1 - - new_p1 <- one; new_p2 <- p2/p1[0]; IF sz1 == 1 - - new_p1 <- p1/gcd(p1, p2); new_p2 <- p2/gcd(p1, p2); Otherwise + \brief Compute polynomials new_p1 and new_p2 s.t. + - p1/p2 == new_p1/new_p2, AND + - new_p2 is a Monic polynomial, AND + - gcd(new_p1, new_p2) == 1 */ void normalize_fraction(unsigned sz1, value * const * p1, unsigned sz2, value * const * p2, value_ref_buffer & new_p1, value_ref_buffer & new_p2) { INC_DEPTH(); @@ -4800,47 +4810,58 @@ namespace realclosure { div(sz1, p1, p2[0], new_p1); new_p2.reset(); new_p2.push_back(one()); } - else if (sz1 == 1) { - SASSERT(sz2 > 1); - // - new_p1 <- one; new_p2 <- p2/p1[0]; IF sz1 == 1 - new_p1.reset(); new_p1.push_back(one()); - div(sz2, p2, p1[0], new_p2); - } else { - // - new_p1 <- p1/gcd(p1, p2); new_p2 <- p2/gcd(p1, p2); Otherwise - value_ref_buffer g(*this); - gcd(sz1, p1, sz2, p2, g); - if (is_rational_one(g)) { - new_p1.append(sz1, p1); - new_p2.append(sz2, p2); - } - else if (g.size() == sz1 || g.size() == sz2) { - // After dividing p1 and p2 by g, one of the quotients will have size 1. - // Thus, we have to apply the first two rules again. - value_ref_buffer tmp_p1(*this); - value_ref_buffer tmp_p2(*this); - div(sz1, p1, g.size(), g.c_ptr(), tmp_p1); - div(sz2, p2, g.size(), g.c_ptr(), tmp_p2); - if (tmp_p2.size() == 1) { - div(tmp_p1.size(), tmp_p1.c_ptr(), tmp_p2[0], new_p1); - new_p2.reset(); new_p2.push_back(one()); - } - else if (tmp_p1.size() == 1) { - SASSERT(tmp_p2.size() > 1); - new_p1.reset(); new_p1.push_back(one()); - div(tmp_p2.size(), tmp_p2.c_ptr(), tmp_p1[0], new_p2); - } - else { - UNREACHABLE(); - } + value * lc = p2[sz2 - 1]; + if (is_rational_one(lc)) { + // p2 is monic + normalize_num_monic_den(sz1, p1, sz2, p2, new_p1, new_p2); } else { - div(sz1, p1, g.size(), g.c_ptr(), new_p1); - div(sz2, p2, g.size(), g.c_ptr(), new_p2); - SASSERT(new_p1.size() > 1); - SASSERT(new_p2.size() > 1); + // p2 is not monic + value_ref_buffer tmp1(*this); + value_ref_buffer tmp2(*this); + div(sz1, p1, lc, tmp1); + div(sz2, p2, lc, tmp2); + normalize_num_monic_den(tmp1.size(), tmp1.c_ptr(), tmp2.size(), tmp2.c_ptr(), new_p1, new_p2); } } + TRACE("normalize_fraction_bug", + display_poly(tout, sz1, p1); tout << "\n"; + display_poly(tout, sz2, p2); tout << "\n"; + tout << "====>\n"; + display_poly(tout, new_p1.size(), new_p1.c_ptr()); tout << "\n"; + display_poly(tout, new_p2.size(), new_p2.c_ptr()); tout << "\n";); + } + + /** + \brief Auxiliary function for normalize_fraction. + It produces new_p1 and new_p2 s.t. + new_p1/new_p2 == p1/p2 + gcd(new_p1, new_p2) == 1 + + Assumptions: + \pre p2 is monic + \pre sz2 > 1 + */ + void normalize_num_monic_den(unsigned sz1, value * const * p1, unsigned sz2, value * const * p2, + value_ref_buffer & new_p1, value_ref_buffer & new_p2) { + SASSERT(sz2 > 1); + SASSERT(is_rational_one(p2[sz2-1])); + + value_ref_buffer g(*this); + + gcd(sz1, p1, sz2, p2, g); + SASSERT(is_monic(g)); + + if (is_rational_one(g)) { + new_p1.append(sz1, p1); + new_p2.append(sz2, p2); + } + else { + div(sz1, p1, g.size(), g.c_ptr(), new_p1); + div(sz2, p2, g.size(), g.c_ptr(), new_p2); + SASSERT(is_monic(new_p2)); + } } /** @@ -4925,10 +4946,8 @@ namespace realclosure { value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); normalize_fraction(num.size(), num.c_ptr(), ad.size(), ad.c_ptr(), new_num, new_den); - if (new_num.empty()) - r = 0; - else - mk_add_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); + SASSERT(!new_num.empty()); + mk_add_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } } } @@ -4986,10 +5005,8 @@ namespace realclosure { value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); normalize_fraction(num.size(), num.c_ptr(), den.size(), den.c_ptr(), new_num, new_den); - if (new_num.empty()) - r = 0; - else - mk_add_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); + SASSERT(!new_num.empty()); + mk_add_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } } } @@ -5334,7 +5351,11 @@ namespace realclosure { polynomial const & ad = a->den(); scoped_mpbqi ri(bqim()); bqim().inv(interval(a), ri); - r = mk_rational_function_value_core(a->ext(), ad.size(), ad.c_ptr(), an.size(), an.c_ptr()); + // The GCD of an and ad is one, we may use a simpler version of normalize + value_ref_buffer new_num(*this); + value_ref_buffer new_den(*this); + normalize_fraction(ad.size(), ad.c_ptr(), an.size(), an.c_ptr(), new_num, new_den); + r = mk_rational_function_value_core(a->ext(), new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr()); swap(r->interval(), ri); SASSERT(!contains_zero(r->interval())); } @@ -5712,16 +5733,16 @@ namespace realclosure { } } - void display_compact(std::ostream & out, numeral const & a) const { + void display_compact(std::ostream & out, value * a) const { collect_algebraic_refs c; - c.mark(a.m_value); + c.mark(a); if (c.m_found.empty()) { - display(out, a.m_value, true); + display(out, a, true); } else { std::sort(c.m_found.begin(), c.m_found.end(), rank_lt_proc()); out << "["; - display(out, a.m_value, true); + display(out, a, true); for (unsigned i = 0; i < c.m_found.size(); i++) { algebraic * ext = c.m_found[i]; out << "; r!" << ext->idx() << " := "; @@ -5731,6 +5752,10 @@ namespace realclosure { } } + void display_compact(std::ostream & out, numeral const & a) const { + display_compact(out, a.m_value); + } + void display(std::ostream & out, numeral const & a, bool compact=false) const { if (compact) display_compact(out, a); From eea33841068d71e45d79e93e32aeb7d3eb8dde12 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Tue, 15 Jan 2013 16:35:36 -0800 Subject: [PATCH 013/101] Add lazy normalization for algebraic extension values. Increase default max_precision to 128. Signed-off-by: Leonardo de Moura --- src/math/realclosure/rcf.pyg | 4 +++- src/math/realclosure/realclosure.cpp | 35 +++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/math/realclosure/rcf.pyg b/src/math/realclosure/rcf.pyg index a394ae32a..36c13035b 100644 --- a/src/math/realclosure/rcf.pyg +++ b/src/math/realclosure/rcf.pyg @@ -5,4 +5,6 @@ def_module_params('rcf', ('clean_denominators', BOOL, True, "clean denominators before root isolation"), ('initial_precision', UINT, 24, "a value k that is the initial interval size (as 1/2^k) when creating transcendentals and approximated division"), ('inf_precision', UINT, 24, "a value k that is the initial interval size (i.e., (0, 1/2^l)) used as an approximation for infinitesimal values"), - ('max_precision', UINT, 64, "during sign determination we switch from interval arithmetic to complete methods when the interval size is less than 1/2^k, where k is the max_precision"))) + ('max_precision', UINT, 128, "during sign determination we switch from interval arithmetic to complete methods when the interval size is less than 1/2^k, where k is the max_precision"), + ('lazy_algebraic_normalization', BOOL, True, "during sturm-seq and square-free polynomial computations, only normalize algebraic polynomial expressions when the definining polynomial is monic") + )) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 8f9697d98..50737a97b 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -378,11 +378,13 @@ namespace realclosure { unsigned m_inf_precision; //!< 2^m_inf_precision is used as the lower bound of oo and -2^m_inf_precision is used as the upper_bound of -oo scoped_mpbq m_plus_inf_approx; // lower bound for binary rational intervals used to approximate an infinite positive value scoped_mpbq m_minus_inf_approx; // upper bound for binary rational intervals used to approximate an infinite negative value - + bool m_lazy_algebraic_normalization; // Tracing unsigned m_exec_depth; + bool m_in_aux_values; // True if we are computing SquareFree polynomials or Sturm sequences. That is, the values being computed will be discarded. + volatile bool m_cancel; struct scoped_polynomial_seq { @@ -495,6 +497,8 @@ namespace realclosure { m_exec_depth = 0; + m_in_aux_values = false; + m_cancel = false; updt_params(p); @@ -723,6 +727,7 @@ namespace realclosure { m_ini_precision = p.initial_precision(); m_inf_precision = p.inf_precision(); m_max_precision = p.max_precision(); + m_lazy_algebraic_normalization = p.lazy_algebraic_normalization(); bqm().power(mpbq(2), m_inf_precision, m_plus_inf_approx); bqm().set(m_minus_inf_approx, m_plus_inf_approx); bqm().neg(m_minus_inf_approx); @@ -3454,6 +3459,10 @@ namespace realclosure { return p.size() > 0 && is_rational_one(p[p.size() - 1]); } + bool is_monic(polynomial const & p) { + return p.size() > 0 && is_rational_one(p[p.size() - 1]); + } + /** \brief Force the leading coefficient of p to be 1. */ @@ -3589,6 +3598,7 @@ namespace realclosure { Store in r the square free factors of p. */ void square_free(unsigned sz, value * const * p, value_ref_buffer & r) { + flet set(m_in_aux_values, true); if (sz <= 1) { r.append(sz, p); } @@ -3616,6 +3626,8 @@ namespace realclosure { */ void sturm_seq_core(scoped_polynomial_seq & seq) { INC_DEPTH(); + flet set(m_in_aux_values, true); + SASSERT(seq.size() >= 2); TRACE("rcf_sturm_seq", unsigned sz = seq.size(); @@ -3788,6 +3800,8 @@ namespace realclosure { \brief Evaluate the sign of p(b) by computing a value object. */ int expensive_eval_sign_at(unsigned n, value * const * p, mpbq const & b) { + flet set(m_in_aux_values, true); + SASSERT(n > 1); SASSERT(p[n - 1] != 0); // Actually, given b = c/2^k, we compute the sign of (2^k)^n*p(c) @@ -4877,7 +4891,13 @@ namespace realclosure { */ void normalize_algebraic(algebraic * x, unsigned sz1, value * const * p1, value_ref_buffer & new_p1) { polynomial const & p = x->p(); - rem(sz1, p1, p.size(), p.c_ptr(), new_p1); + if (!m_lazy_algebraic_normalization || !m_in_aux_values || is_monic(p)) { + rem(sz1, p1, p.size(), p.c_ptr(), new_p1); + } + else { + new_p1.reset(); + new_p1.append(sz1, p1); + } } /** @@ -5693,7 +5713,16 @@ namespace realclosure { } void display_poly(std::ostream & out, unsigned n, value * const * p) const { - display_polynomial(out, n, p, display_free_var_proc(), false); + collect_algebraic_refs c; + for (unsigned i = 0; i < n; i++) + c.mark(p[i]); + display_polynomial(out, n, p, display_free_var_proc(), true); + std::sort(c.m_found.begin(), c.m_found.end(), rank_lt_proc()); + for (unsigned i = 0; i < c.m_found.size(); i++) { + algebraic * ext = c.m_found[i]; + out << "\n r!" << ext->idx() << " := "; + display_algebraic_def(out, ext, true); + } } void display_ext(std::ostream & out, extension * r, bool compact) const { From 53094c6173aeee05cd912bcbd3e890de50c370f7 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Tue, 15 Jan 2013 17:43:22 -0800 Subject: [PATCH 014/101] Add gprof support Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 5d30ca0fc..205b8f948 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -72,6 +72,7 @@ PREFIX=os.path.split(os.path.split(os.path.split(PYTHON_PACKAGE_DIR)[0])[0])[0] GMP=False VS_PAR=False VS_PAR_NUM=8 +GPROF=False def is_windows(): return IS_WINDOWS @@ -373,6 +374,7 @@ def display_help(exit_code): print(" --staticlib build Z3 static library.") if not IS_WINDOWS: print(" -g, --gmp use GMP.") + print(" --gprof enable gprof") print("") print("Some influential environment variables:") if not IS_WINDOWS: @@ -389,12 +391,12 @@ def display_help(exit_code): # Parse configuration option for mk_make script def parse_options(): global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM - global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, PYTHON_PACKAGE_DIR + global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF try: options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:dsxhmcvtnp:gj', ['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', - 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=']) + 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof']) except: print("ERROR: Invalid command line option") display_help(1) @@ -439,6 +441,8 @@ def parse_options(): GMP = True elif opt in ('-j', '--java'): JAVA_ENABLED = True + elif opt == '--gprof': + GPROF = True else: print("ERROR: Invalid command line option '%s'" % opt) display_help(1) @@ -1321,6 +1325,9 @@ def mk_config(): CXX = find_cxx_compiler() CC = find_c_compiler() SLIBEXTRAFLAGS = '' + if GPROF: + CXXFLAGS = '%s -pg' % CXXFLAGS + LDFLAGS = '%s -pg' % LDFLAGS if GMP: test_gmp(CXX) ARITH = "gmp" @@ -1340,7 +1347,10 @@ def mk_config(): if DEBUG_MODE: CXXFLAGS = '%s -g -Wall' % CXXFLAGS else: - CXXFLAGS = '%s -O3 -D _EXTERNAL_RELEASE -fomit-frame-pointer' % CXXFLAGS + if GPROF: + CXXFLAGS = '%s -O3 -D _EXTERNAL_RELEASE' % CXXFLAGS + else: + CXXFLAGS = '%s -O3 -D _EXTERNAL_RELEASE -fomit-frame-pointer' % CXXFLAGS if is_CXX_clangpp(): CXXFLAGS = '%s -Wno-unknown-pragmas -Wno-overloaded-virtual -Wno-unused-value' % CXXFLAGS sysname = os.uname()[0] @@ -1403,6 +1413,8 @@ def mk_config(): print('OpenMP: %s' % HAS_OMP) print('Prefix: %s' % PREFIX) print('64-bit: %s' % is64()) + if GPROF: + print('gprof: enabled') print('Python version: %s' % distutils.sysconfig.get_python_version()) if is_java_enabled(): print('Java Home: %s' % JAVA_HOME) From c9b7ea35b62c1cd1013da62e3d87287a8ce5b741 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 16 Jan 2013 08:39:24 -0800 Subject: [PATCH 015/101] Fix typo Signed-off-by: Leonardo de Moura --- src/api/api_rcf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/api_rcf.cpp b/src/api/api_rcf.cpp index c52a35f5f..b325c4397 100644 --- a/src/api/api_rcf.cpp +++ b/src/api/api_rcf.cpp @@ -264,7 +264,7 @@ extern "C" { LOG_Z3_rcf_neq(c, a, b); RESET_ERROR_CODE(); reset_rcf_cancel(c); - return rcfm(c).eq(to_rcnumeral(a), to_rcnumeral(b)); + return rcfm(c).neq(to_rcnumeral(a), to_rcnumeral(b)); Z3_CATCH_RETURN(Z3_FALSE); } From bb386c0f18f48747ea91b8457547c20ff9c429b4 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 16 Jan 2013 11:19:11 -0800 Subject: [PATCH 016/101] Fix problem in inv_rf Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 224 ++++++++++++++++++++++----- 1 file changed, 189 insertions(+), 35 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 50737a97b..fc46c6d5c 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -1248,6 +1248,10 @@ namespace realclosure { return r; } + rational_function_value * mk_rational_function_value_core(algebraic * ext, unsigned num_sz, value * const * num) { + return mk_rational_function_value_core(ext, num_sz, num, 0, 0); + } + /** \brief Create a value using the given extension. */ @@ -2390,8 +2394,6 @@ namespace realclosure { value_ref d(*this); value_ref_buffer norm_p(*this); clean_denominators(n, p, norm_p, d); - if (sign(d) < 0) - neg(norm_p); nz_cd_isolate_roots(norm_p.size(), norm_p.c_ptr(), roots); } else { @@ -5302,63 +5304,215 @@ namespace realclosure { } /** - \brief Auxiliary function for inverting values of algebraic extensions. - p is the defining polynomial for the algebraic extension alpha. - q is the polynomial representing the value q(alpha). + \brief Invert 1/q(alpha) given that p(alpha) = 0. That is, we find h s.t. + + q(alpha) * h(alpha) = 1 + + The procedure succeeds (and returns true) if the GCD(q, p) = 1. - The procedure will store a polynomial in r that represents the value 1/q(a) + If the GCD(q, p) != 1, then it returns false, and store the GCD in g. + + The following procedure is essentially a special case of the extended polynomial GCD algorithm. */ - void inv_algebraic(unsigned q_sz, value * const * q, unsigned p_sz, value * const * p, value_ref_buffer & r) { + bool inv_algebraic(unsigned q_sz, value * const * q, unsigned p_sz, value * const * p, value_ref_buffer & g, value_ref_buffer & h) { TRACE("inv_algebraic", tout << "q: "; display_poly(tout, q_sz, q); tout << "\n"; tout << "p: "; display_poly(tout, p_sz, p); tout << "\n";); SASSERT(q_sz > 0); SASSERT(q_sz < p_sz); - value_ref_buffer A(*this); - A.append(q_sz, q); + // Q <- q + value_ref_buffer Q(*this); + Q.append(q_sz, q); + // R <- 1 value_ref_buffer R(*this); R.push_back(one()); - value_ref_buffer Quo(*this), Rem(*this); + value_ref_buffer Quo(*this), Rem(*this), aux(*this); + + // We find h(alpha), by rewriting the equation + // q(alpha) * h(alpha) = 1 + // until we have + // 1 * h(alpha) = R(alpha) while (true) { + // In every iteration of the loop we have + // Q(alpha) * h(alpha) = R(alpha) TRACE("inv_algebraic", - tout << "A: "; display_poly(tout, A.size(), A.c_ptr()); tout << "\n"; + tout << "Q: "; display_poly(tout, Q.size(), Q.c_ptr()); tout << "\n"; tout << "R: "; display_poly(tout, R.size(), R.c_ptr()); tout << "\n";); - if (A.size() == 1) { - div(R.size(), R.c_ptr(), A[0], r); - TRACE("inv_algebraic", tout << "r: "; display_poly(tout, r.size(), r.c_ptr()); tout << "\n";); - return; + if (Q.size() == 1) { + // If the new Q is the constant polynomial, they we are done. + // We just divide R by Q[0]. + // h(alpha) = R(alpha) / Q[0] + div(R.size(), R.c_ptr(), Q[0], h); + TRACE("inv_algebraic", tout << "h: "; display_poly(tout, h.size(), h.c_ptr()); tout << "\n";); + // g <- 1 + g.reset(); g.push_back(one()); + return true; + } + else { + div_rem(p_sz, p, Q.size(), Q.c_ptr(), Quo, Rem); + if (Rem.empty()) { + // failed + // GCD(q, p) != 1 + g = Q; + mk_monic(g); + return false; + } + else { + // By the definition of polynomial division, we have + // p == Quo * Q + Rem + // Since, we have p(alpha) = 0 + // Quo(alpha) * Q(alpha) = -Rem(alpha) (*) + // Now, if we multiply the equation + // Q(alpha) * h(alpha) = R(alpha) + // by Quo(alpha) and apply (*), we get + // -Rem(alpha) * h(alpha) = R(alpha) * Quo(alpha) + // Thus, we update Q, and R for the next iteration, as + // Q <- -REM + // R <- R * Quo + // Q <- -Rem + neg(Rem.size(), Rem.c_ptr(), Q); + mul(R.size(), R.c_ptr(), Quo.size(), Quo.c_ptr(), aux); + // Moreover since p(alpha) = 0, we can simplify Q, by using + // Q(alpha) = REM(Q, p)(alpha) + rem(aux.size(), aux.c_ptr(), p_sz, p, R); + SASSERT(R.size() < p_sz); + // + } } - div_rem(p_sz, p, A.size(), A.c_ptr(), Quo, Rem); - // p == Quo * A + Rem - // since p = 0 - // Quo * A = -Rem - // thus, we update - // A <- -Rem - neg(Rem.size(), Rem.c_ptr(), A); - // R <- rem(Quo * R, p) - mul(R.size(), R.c_ptr(), Quo.size(), Quo.c_ptr(), r); - rem(r.size(), r.c_ptr(), p_sz, p, R); - SASSERT(R.size() < p_sz); } } /** \brief r <- 1/a specialized version when a->ext() is algebraic. It avoids the use of rational functions. - */ + */ void inv_algebraic(rational_function_value * a, value_ref & r) { SASSERT(a->ext()->is_algebraic()); SASSERT(is_denominator_one(a)); - algebraic * x = to_algebraic(a->ext()); - polynomial const & q = a->num(); - value_ref_buffer new_num(*this); - SASSERT(q.size() < x->p().size()); - inv_algebraic(q.size(), q.c_ptr(), x->p().size(), x->p().c_ptr(), new_num); scoped_mpbqi ri(bqim()); bqim().inv(interval(a), ri); - r = mk_rational_function_value_core(a->ext(), new_num.size(), new_num.c_ptr(), a->den().size(), a->den().c_ptr()); - swap(r->interval(), ri); - SASSERT(!contains_zero(r->interval())); + algebraic * alpha = to_algebraic(a->ext()); + polynomial const & q = a->num(); + polynomial const & p = alpha->p(); + value_ref_buffer norm_q(*this); + // since p(alpha) = 0, we have that q(alpha) = rem(q, p)(alpha) + rem(q.size(), q.c_ptr(), p.size(), p.c_ptr(), norm_q); + SASSERT(norm_q.size() < p.size()); + value_ref_buffer new_num(*this), g(*this); + if (inv_algebraic(norm_q.size(), norm_q.c_ptr(), p.size(), p.c_ptr(), g, new_num)) { + if (new_num.size() == 1) { + r = new_num[0]; + } + else { + r = mk_rational_function_value_core(alpha, new_num.size(), new_num.c_ptr()); + swap(r->interval(), ri); + SASSERT(!contains_zero(r->interval())); + } + } + else { + // We failed to compute 1/a + // because q and p are not co-prime + // This can happen because we don't use minimal + // polynomials to represent algebraic extensions such + // as alpha. + + // We recover from the failure by refining the defining polynomial of alpha + // with p/gcd(p, q) + // Remark: g contains the gcd of p, q + // And try again :) + + value_ref_buffer new_p(*this); + div(p.size(), p.c_ptr(), g.size(), g.c_ptr(), new_p); + if (m_clean_denominators) { + value_ref_buffer tmp(*this); + value_ref d(*this); + clean_denominators(new_p.size(), new_p.c_ptr(), tmp, d); + new_p = tmp; + } + SASSERT(new_p.size() >= 2); + + if (new_p.size() == 2) { + // Easy case: alpha is actually equal to + // -new_p[0]/new_p[1] + value_ref alpha_val(*this); + alpha_val = new_p[0]; + neg(alpha_val, alpha_val); + div(alpha_val, new_p[1], alpha_val); + // Thus, a is equal to q(alpha_val) + value_ref new_a(*this); + mk_polynomial_value(q.size(), q.c_ptr(), alpha_val, new_a); + // Remark new_a does not depend on alpha anymore + // r == 1/inv(new_a) + inv(new_a, r); + } + else if (alpha->sdt() == 0) { + // Another easy case: we just have to replace + // alpha->p() with new_p. + // The m_iso_interval for p() is also an isolating interval for new_p, + // since the roots of new_p() are a subset of the roots of p + reset_p(alpha->m_p); + set_p(alpha->m_p, new_p.size(), new_p.c_ptr()); + + // The new call will succeed because q and new_p are co-prime + inv_algebraic(a, r); + } + else { + // Let sdt be alpha->sdt(); + // In pricipal, the signs of the polynomials sdt->qs can be used + // to discriminate the roots of new_p. The signs of this polynomials + // depend only on alpha, and not on the polynomial used to define alpha + // So, in principle, we can reuse m_qs and m_sign_conditions. + // However, we have to recompute the tarski queries with respect to new_p. + // This values will be different, since new_p has less roots than p. + // + // Instead of trying to reuse the information in sdt, we simply + // isolate the roots of new_p, and check the one that is equal to alpha. + // and copy all the information from them. + SASSERT(new_p.size() > 2); + // we can invoke nl_nz_sqf_isolate_roots, because we know + // - new_p is not linear + // - new_p is square free (it is a factor of the square free polynomial p) + // - 0 is not a root of new_p (it is a factor of p, and 0 is not a root of p) + numeral_vector roots; + nl_nz_sqf_isolate_roots(new_p.size(), new_p.c_ptr(), roots); + SASSERT(roots.size() > 0); + algebraic * new_alpha; + if (roots.size() == 1) { + new_alpha = to_algebraic(to_rational_function(roots[0].m_value)->ext()); + } + else { + value_ref alpha_val(*this); + alpha_val = mk_rational_function_value(alpha); + // search for the root that is equal to alpha + unsigned i = 0; + for (i = 0; i < roots.size(); i++) { + if (compare(alpha_val, roots[i].m_value) == 0) { + // found it; + break; + } + } + new_alpha = to_algebraic(to_rational_function(roots[i].m_value)->ext()); + } + SASSERT(new_alpha->p().size() == new_p.size()); + // We now that alpha and new_alpha represent the same value. + // Thus, we update alpha fields with the fields from new_alpha. + + // copy new_alpha->m_p + reset_p(alpha->m_p); + set_p(alpha->m_p, new_alpha->m_p.size(), new_alpha->m_p.c_ptr()); + // copy new_alpha->m_sign_det + inc_ref_sign_det(new_alpha->m_sign_det); + dec_ref_sign_det(alpha->m_sign_det); + alpha->m_sign_det = new_alpha->m_sign_det; + // copy remaining fields + set_interval(alpha->m_iso_interval, new_alpha->m_iso_interval); + alpha->m_sc_idx = new_alpha->m_sc_idx; + alpha->m_depends_on_infinitesimals = new_alpha->m_depends_on_infinitesimals; + + // The new call will succeed because q and new_p are co-prime + inv_algebraic(a, r); + } + } } void inv_rf(rational_function_value * a, value_ref & r) { From 50bf845b406fcebb3d3f0c46c9cd2ea488865df4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 16 Jan 2013 17:16:44 -0800 Subject: [PATCH 017/101] add tabulation/subsumption engine Signed-off-by: Nikolaj Bjorner --- src/muz_qe/tab_context.cpp | 235 +++++++++++++++++++++++++++++++++++++ src/muz_qe/tab_context.h | 45 +++++++ 2 files changed, 280 insertions(+) create mode 100644 src/muz_qe/tab_context.cpp create mode 100644 src/muz_qe/tab_context.h diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp new file mode 100644 index 000000000..81db5c5d0 --- /dev/null +++ b/src/muz_qe/tab_context.cpp @@ -0,0 +1,235 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + tab_context.cpp + +Abstract: + + Tabulation/subsumption/cyclic proof context. + +Author: + + Nikolaj Bjorner (nbjorner) 2013-01-15 + +Revision History: + +--*/ + +#include "tab_context.h" +#include "trail.h" +#include "dl_rule_set.h" +#include "dl_context.h" +#include "dl_mk_rule_inliner.h" + +namespace datalog { + + template + struct restore_rule : trail { + rule_ref_vector& m_rules; + rule_ref& m_rule; + + restore_rule(rule_ref_vector& rules, rule_ref& rule): m_rules(rules), m_rule(rule) { + m_rules.push_back(m_rule); + } + + virtual void undo(Ctx & ctx) { + m_rule = m_rules.back(); + m_rules.pop_back(); + } + }; + + class tab::imp { + enum instruction { + SELECT_RULE, + SELECT_PREDICATE, + BACKTRACK, + NEXT_RULE, + SATISFIABLE, + UNSATISFIABLE, + CANCEL + }; + context& m_ctx; + ast_manager& m; + rule_manager& rm; + rule_unifier m_unifier; + rule_set m_rules; + trail_stack m_trail; + instruction m_instruction; + rule_ref m_query; + rule_ref_vector m_query_trail; + unsigned m_predicate_index; + unsigned m_rule_index; + volatile bool m_cancel; + public: + imp(context& ctx): + m_ctx(ctx), + m(ctx.get_manager()), + rm(ctx.get_rule_manager()), + m_unifier(ctx), + m_rules(ctx), + m_trail(*this), + m_instruction(SELECT_PREDICATE), + m_query(rm), + m_query_trail(rm), + m_predicate_index(0), + m_rule_index(0), + m_cancel(false) + {} + + ~imp() {} + + lbool query(expr* query) { + m_ctx.ensure_opened(); + m_rules.reset(); + m_rules.add_rules(m_ctx.get_rules()); + rule_ref_vector query_rules(rm); + func_decl_ref query_pred(m); + rm.mk_query(query, query_pred, query_rules, m_query); + return run(); + } + + void cancel() { + m_cancel = true; + } + void cleanup() { + m_cancel = false; + m_trail.reset(); + m_query_trail.reset(); + } + void reset_statistics() { + // TBD + } + void collect_statistics(statistics& st) const { + // TBD + } + void display_certificate(std::ostream& out) const { + // TBD + } + expr_ref get_answer() { + // TBD + return expr_ref(0, m); + } +private: + + void select_predicate() { + unsigned num_predicates = m_query->get_uninterpreted_tail_size(); + if (num_predicates == 0) { + m_instruction = UNSATISFIABLE; + } + else { + m_instruction = SELECT_RULE; + m_predicate_index = 0; // TBD replace by better selection function. + m_rule_index = 0; + } + } + + void apply_rule(rule const& r) { + bool can_unify = m_unifier.unify_rules(*m_query, m_predicate_index, r); + if (can_unify) { + rule_ref new_query(rm); + m_unifier.apply(*m_query, m_predicate_index, r, new_query); + m_trail.push(restore_rule(m_query_trail, m_query)); + m_query = new_query; + TRACE("dl", m_query->display(m_ctx, tout);); + } + else { + m_instruction = NEXT_RULE; + } + } + + void select_rule() { + func_decl* p = m_query->get_decl(m_predicate_index); + rule_vector const& rules = m_rules.get_predicate_rules(p); + if (rules.size() >= m_rule_index) { + m_instruction = BACKTRACK; + } + else { + rule* r = rules[m_rule_index]; + m_trail.push_scope(); + m_rule_index++; + m_trail.push(value_trail(m_rule_index)); + m_trail.push(value_trail(m_predicate_index)); + apply_rule(*r); + } + } + + void backtrack() { + if (m_trail.get_num_scopes() == 0) { + m_instruction = SATISFIABLE; + } + else { + m_trail.pop_scope(1); + m_instruction = SELECT_RULE; + } + } + + void next_rule() { + SASSERT(m_trail.get_num_scopes() > 0); + m_trail.pop_scope(1); + m_instruction = SELECT_RULE; + } + + lbool run() { + m_instruction = SELECT_PREDICATE; + while (true) { + if (m_cancel) { + m_cancel = false; + return l_undef; + } + switch(m_instruction) { + case SELECT_PREDICATE: + select_predicate(); + break; + case SELECT_RULE: + select_rule(); + break; + case BACKTRACK: + backtrack(); + break; + case NEXT_RULE: // just use BACTRACK? + next_rule(); + break; + case SATISFIABLE: + return l_true; + case UNSATISFIABLE: + return l_false; + case CANCEL: + m_cancel = false; + return l_undef; + } + } + } + + }; + + tab::tab(context& ctx): + m_imp(alloc(imp, ctx)) { + } + tab::~tab() { + dealloc(m_imp); + } + lbool tab::query(expr* query) { + return m_imp->query(query); + } + void tab::cancel() { + m_imp->cancel(); + } + void tab::cleanup() { + m_imp->cleanup(); + } + void tab::reset_statistics() { + m_imp->reset_statistics(); + } + void tab::collect_statistics(statistics& st) const { + m_imp->collect_statistics(st); + } + void tab::display_certificate(std::ostream& out) const { + m_imp->display_certificate(out); + } + expr_ref tab::get_answer() { + return m_imp->get_answer(); + } + +}; diff --git a/src/muz_qe/tab_context.h b/src/muz_qe/tab_context.h new file mode 100644 index 000000000..f0a2eefed --- /dev/null +++ b/src/muz_qe/tab_context.h @@ -0,0 +1,45 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + tab_context.h + +Abstract: + + Tabulation/subsumption/cyclic proof context. + +Author: + + Nikolaj Bjorner (nbjorner) 2013-01-15 + +Revision History: + +--*/ +#ifndef _TAB_CONTEXT_H_ +#define _TAB_CONTEXT_H_ + +#include "ast.h" +#include "lbool.h" +#include "statistics.h" + +namespace datalog { + class context; + + class tab { + class imp; + imp* m_imp; + public: + tab(context& ctx); + ~tab(); + lbool query(expr* query); + void cancel(); + void cleanup(); + void reset_statistics(); + void collect_statistics(statistics& st) const; + void display_certificate(std::ostream& out) const; + expr_ref get_answer(); + }; +}; + +#endif From b19a47176bfc8f973b46207d089eabfa3cf20ccb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Jan 2013 08:17:21 -0800 Subject: [PATCH 018/101] working on tab Signed-off-by: Nikolaj Bjorner --- src/muz_qe/dl_context.cpp | 55 ++++++++++++++-- src/muz_qe/dl_context.h | 6 ++ src/muz_qe/dl_util.h | 1 + src/muz_qe/pdr_farkas_learner.cpp | 33 ---------- src/muz_qe/pdr_farkas_learner.h | 2 - src/muz_qe/tab_context.cpp | 103 ++++++++++++++++++++++-------- src/tactic/tactical.cpp | 1 - 7 files changed, 131 insertions(+), 70 deletions(-) diff --git a/src/muz_qe/dl_context.cpp b/src/muz_qe/dl_context.cpp index 5581732c8..8ef2ffa22 100644 --- a/src/muz_qe/dl_context.cpp +++ b/src/muz_qe/dl_context.cpp @@ -544,14 +544,16 @@ namespace datalog { unsigned context::get_num_levels(func_decl* pred) { switch(get_engine()) { case DATALOG_ENGINE: - throw default_exception("get_num_levels is unsupported for datalog engine"); + throw default_exception("get_num_levels is not supported for datalog engine"); case PDR_ENGINE: case QPDR_ENGINE: ensure_pdr(); return m_pdr->get_num_levels(pred); case BMC_ENGINE: case QBMC_ENGINE: - throw default_exception("get_num_levels is unsupported for bmc"); + throw default_exception("get_num_levels is not supported for bmc"); + case TAB_ENGINE: + throw default_exception("get_num_levels is not supported for tab"); default: throw default_exception("unknown engine"); } @@ -560,14 +562,16 @@ namespace datalog { expr_ref context::get_cover_delta(int level, func_decl* pred) { switch(get_engine()) { case DATALOG_ENGINE: - throw default_exception("operation is unsupported for datalog engine"); + throw default_exception("operation is not supported for datalog engine"); case PDR_ENGINE: case QPDR_ENGINE: ensure_pdr(); return m_pdr->get_cover_delta(level, pred); case BMC_ENGINE: case QBMC_ENGINE: - throw default_exception("operation is unsupported for BMC engine"); + throw default_exception("operation is not supported for BMC engine"); + case TAB_ENGINE: + throw default_exception("operation is not supported for TAB engine"); default: throw default_exception("unknown engine"); } @@ -576,7 +580,7 @@ namespace datalog { void context::add_cover(int level, func_decl* pred, expr* property) { switch(get_engine()) { case DATALOG_ENGINE: - throw default_exception("operation is unsupported for datalog engine"); + throw default_exception("operation is not supported for datalog engine"); case PDR_ENGINE: case QPDR_ENGINE: ensure_pdr(); @@ -584,7 +588,9 @@ namespace datalog { break; case BMC_ENGINE: case QBMC_ENGINE: - throw default_exception("operation is unsupported for BMC engine"); + throw default_exception("operation is not supported for BMC engine"); + case TAB_ENGINE: + throw default_exception("operation is not supported for TAB engine"); default: throw default_exception("unknown engine"); } @@ -720,7 +726,11 @@ namespace datalog { case QBMC_ENGINE: check_existential_tail(r); check_positive_predicates(r); - break; + break; + case TAB_ENGINE: + check_existential_tail(r); + check_positive_predicates(r); + break; default: UNREACHABLE(); break; @@ -921,6 +931,7 @@ namespace datalog { if (m_pdr.get()) m_pdr->cancel(); if (m_bmc.get()) m_bmc->cancel(); if (m_rel.get()) m_rel->cancel(); + if (m_tab.get()) m_tab->cancel(); } void context::cleanup() { @@ -928,6 +939,7 @@ namespace datalog { if (m_pdr.get()) m_pdr->cleanup(); if (m_bmc.get()) m_bmc->cleanup(); if (m_rel.get()) m_rel->cleanup(); + if (m_tab.get()) m_tab->cleanup(); } class context::engine_type_proc { @@ -974,6 +986,9 @@ namespace datalog { else if (e == symbol("qbmc")) { m_engine = QBMC_ENGINE; } + else if (e == symbol("tab")) { + m_engine = TAB_ENGINE; + } if (m_engine == LAST_ENGINE) { expr_fast_mark1 mark; @@ -1008,6 +1023,8 @@ namespace datalog { case BMC_ENGINE: case QBMC_ENGINE: return bmc_query(query); + case TAB_ENGINE: + return tab_query(query); default: UNREACHABLE(); return rel_query(query); @@ -1064,6 +1081,17 @@ namespace datalog { return m_bmc->query(query); } + void context::ensure_tab() { + if (!m_tab.get()) { + m_tab = alloc(tab, *this); + } + } + + lbool context::tab_query(expr* query) { + ensure_tab(); + return m_tab->query(query); + } + void context::ensure_rel() { if (!m_rel.get()) { m_rel = alloc(rel_context, *this); @@ -1100,6 +1128,10 @@ namespace datalog { ensure_rel(); m_last_answer = m_rel->get_last_answer(); return m_last_answer.get(); + case TAB_ENGINE: + ensure_tab(); + m_last_answer = m_tab->get_answer(); + return m_last_answer.get(); default: UNREACHABLE(); } @@ -1120,6 +1152,10 @@ namespace datalog { ensure_bmc(); m_bmc->display_certificate(out); return true; + case TAB_ENGINE: + ensure_tab(); + m_tab->display_certificate(out); + return true; default: return false; } @@ -1151,6 +1187,11 @@ namespace datalog { m_bmc->collect_statistics(st); } break; + case TAB_ENGINE: + if (m_tab) { + m_tab->collect_statistics(st); + } + break; default: break; } diff --git a/src/muz_qe/dl_context.h b/src/muz_qe/dl_context.h index d3309beb5..98380c9c8 100644 --- a/src/muz_qe/dl_context.h +++ b/src/muz_qe/dl_context.h @@ -35,6 +35,7 @@ Revision History: #include"dl_rule_set.h" #include"pdr_dl_interface.h" #include"dl_bmc_engine.h" +#include"tab_context.h" #include"rel_context.h" #include"lbool.h" #include"statistics.h" @@ -100,6 +101,7 @@ namespace datalog { scoped_ptr m_pdr; scoped_ptr m_bmc; scoped_ptr m_rel; + scoped_ptr m_tab; bool m_closed; bool m_saturation_was_run; @@ -434,6 +436,8 @@ namespace datalog { void ensure_bmc(); + void ensure_tab(); + void ensure_rel(); void new_query(); @@ -444,6 +448,8 @@ namespace datalog { lbool bmc_query(expr* query); + lbool tab_query(expr* query); + void check_quantifier_free(rule_ref& r); void check_uninterpreted_free(rule_ref& r); void check_existential_tail(rule_ref& r); diff --git a/src/muz_qe/dl_util.h b/src/muz_qe/dl_util.h index d9e437ccc..99256e70a 100644 --- a/src/muz_qe/dl_util.h +++ b/src/muz_qe/dl_util.h @@ -52,6 +52,7 @@ namespace datalog { QPDR_ENGINE, BMC_ENGINE, QBMC_ENGINE, + TAB_ENGINE, LAST_ENGINE }; diff --git a/src/muz_qe/pdr_farkas_learner.cpp b/src/muz_qe/pdr_farkas_learner.cpp index b8e043806..489b2437e 100644 --- a/src/muz_qe/pdr_farkas_learner.cpp +++ b/src/muz_qe/pdr_farkas_learner.cpp @@ -860,38 +860,5 @@ namespace pdr { } - void farkas_learner::test(char const* filename) { -#if 0 - // [Leo]: disabled because it uses an external component: SMT 1.0 parser - if (!filename) { - test(); - return; - } - ast_manager m; - reg_decl_plugins(m); - scoped_ptr p = smtlib::parser::create(m); - p->initialize_smtlib(); - - if (!p->parse_file(filename)) { - warning_msg("Failed to parse file %s\n", filename); - return; - } - expr_ref A(m), B(m); - - smtlib::theory::expr_iterator it = p->get_benchmark()->begin_axioms(); - smtlib::theory::expr_iterator end = p->get_benchmark()->end_axioms(); - A = m.mk_and(static_cast(end-it), it); - - it = p->get_benchmark()->begin_formulas(); - end = p->get_benchmark()->end_formulas(); - B = m.mk_and(static_cast(end-it), it); - - smt_params params; - pdr::farkas_learner fl(params, m); - expr_ref_vector lemmas(m); - bool res = fl.get_lemma_guesses(A, B, lemmas); - std::cout << "lemmas: " << pp_cube(lemmas, m) << "\n"; -#endif - } }; diff --git a/src/muz_qe/pdr_farkas_learner.h b/src/muz_qe/pdr_farkas_learner.h index 809f4cd7e..eb38455ab 100644 --- a/src/muz_qe/pdr_farkas_learner.h +++ b/src/muz_qe/pdr_farkas_learner.h @@ -99,8 +99,6 @@ public: void collect_statistics(statistics& st) const; - static void test(char const* filename); - }; diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index 81db5c5d0..c025a9ec5 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -30,7 +30,9 @@ namespace datalog { rule_ref_vector& m_rules; rule_ref& m_rule; - restore_rule(rule_ref_vector& rules, rule_ref& rule): m_rules(rules), m_rule(rule) { + restore_rule(rule_ref_vector& rules, rule_ref& rule): + m_rules(rules), + m_rule(rule) { m_rules.push_back(m_rule); } @@ -40,28 +42,51 @@ namespace datalog { } }; + enum tab_instruction { + SELECT_RULE, + SELECT_PREDICATE, + BACKTRACK, + NEXT_RULE, + SATISFIABLE, + UNSATISFIABLE, + CANCEL + }; + + std::ostream& operator<<(std::ostream& out, tab_instruction i) { + switch(i) { + case SELECT_RULE: return out << "select-rule"; + case SELECT_PREDICATE: return out << "select-predicate"; + case BACKTRACK: return out << "backtrack"; + case NEXT_RULE: return out << "next-rule"; + case SATISFIABLE: return out << "sat"; + case UNSATISFIABLE: return out << "unsat"; + case CANCEL: return out << "cancel"; + } + return out << "unmatched instruction"; + } + class tab::imp { - enum instruction { - SELECT_RULE, - SELECT_PREDICATE, - BACKTRACK, - NEXT_RULE, - SATISFIABLE, - UNSATISFIABLE, - CANCEL + struct stats { + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + unsigned m_num_unfold; + unsigned m_num_no_unfold; + unsigned m_num_subsume; }; + context& m_ctx; ast_manager& m; rule_manager& rm; rule_unifier m_unifier; rule_set m_rules; trail_stack m_trail; - instruction m_instruction; + tab_instruction m_instruction; rule_ref m_query; rule_ref_vector m_query_trail; unsigned m_predicate_index; unsigned m_rule_index; volatile bool m_cancel; + stats m_stats; public: imp(context& ctx): m_ctx(ctx), @@ -99,10 +124,12 @@ namespace datalog { m_query_trail.reset(); } void reset_statistics() { - // TBD + m_stats.reset(); } void collect_statistics(statistics& st) const { - // TBD + st.update("tab.num_unfold", m_stats.m_num_unfold); + st.update("tab.num_unfold_fail", m_stats.m_num_no_unfold); + st.update("tab.num_subsume", m_stats.m_num_subsume); } void display_certificate(std::ostream& out) const { // TBD @@ -111,12 +138,13 @@ namespace datalog { // TBD return expr_ref(0, m); } -private: + private: void select_predicate() { unsigned num_predicates = m_query->get_uninterpreted_tail_size(); if (num_predicates == 0) { m_instruction = UNSATISFIABLE; + IF_VERBOSE(1, m_query->display(m_ctx, verbose_stream()); ); } else { m_instruction = SELECT_RULE; @@ -125,37 +153,47 @@ private: } } - void apply_rule(rule const& r) { + void apply_rule(rule const& r) { + m_rule_index++; bool can_unify = m_unifier.unify_rules(*m_query, m_predicate_index, r); if (can_unify) { + m_stats.m_num_unfold++; + m_trail.push_scope(); + m_trail.push(value_trail(m_rule_index)); + m_trail.push(value_trail(m_predicate_index)); rule_ref new_query(rm); m_unifier.apply(*m_query, m_predicate_index, r, new_query); m_trail.push(restore_rule(m_query_trail, m_query)); m_query = new_query; TRACE("dl", m_query->display(m_ctx, tout);); + if (l_false == query_is_sat()) { + m_instruction = BACKTRACK; + } + else if (l_true == query_is_subsumed()) { + NOT_IMPLEMENTED_YET(); + } + else { + m_instruction = SELECT_PREDICATE; + } } else { - m_instruction = NEXT_RULE; + m_stats.m_num_no_unfold++; + m_instruction = SELECT_RULE; } } void select_rule() { func_decl* p = m_query->get_decl(m_predicate_index); rule_vector const& rules = m_rules.get_predicate_rules(p); - if (rules.size() >= m_rule_index) { + if (rules.size() <= m_rule_index) { m_instruction = BACKTRACK; } else { - rule* r = rules[m_rule_index]; - m_trail.push_scope(); - m_rule_index++; - m_trail.push(value_trail(m_rule_index)); - m_trail.push(value_trail(m_predicate_index)); - apply_rule(*r); + apply_rule(*rules[m_rule_index]); } } - void backtrack() { + void backtrack() { if (m_trail.get_num_scopes() == 0) { m_instruction = SATISFIABLE; } @@ -174,8 +212,9 @@ private: lbool run() { m_instruction = SELECT_PREDICATE; while (true) { + IF_VERBOSE(1, verbose_stream() << "run " << m_instruction << "\n";); if (m_cancel) { - m_cancel = false; + cleanup(); return l_undef; } switch(m_instruction) { @@ -192,15 +231,25 @@ private: next_rule(); break; case SATISFIABLE: - return l_true; - case UNSATISFIABLE: return l_false; + case UNSATISFIABLE: + return l_true; case CANCEL: m_cancel = false; return l_undef; } } - } + } + + lbool query_is_sat() { + expr_ref_vector fmls(m); + + return l_undef; + } + + lbool query_is_subsumed() { + return l_undef; + } }; diff --git a/src/tactic/tactical.cpp b/src/tactic/tactical.cpp index ca66b7a14..c3152ed58 100644 --- a/src/tactic/tactical.cpp +++ b/src/tactic/tactical.cpp @@ -19,7 +19,6 @@ Notes: #include"tactical.h" #include"scoped_timer.h" #include"cancel_eh.h" -#include"cooperate.h" #include"scoped_ptr_vector.h" #include"z3_omp.h" From c0f22039e41880069311f90ca8ebf5f772f0c4b5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Jan 2013 08:23:09 -0800 Subject: [PATCH 019/101] add back cooperate.h include (not used now, but will be) Signed-off-by: Nikolaj Bjorner --- src/tactic/tactical.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tactic/tactical.cpp b/src/tactic/tactical.cpp index c3152ed58..ca66b7a14 100644 --- a/src/tactic/tactical.cpp +++ b/src/tactic/tactical.cpp @@ -19,6 +19,7 @@ Notes: #include"tactical.h" #include"scoped_timer.h" #include"cancel_eh.h" +#include"cooperate.h" #include"scoped_ptr_vector.h" #include"z3_omp.h" From 3abf397560bfc8109f28707b61ad8de03c255777 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Jan 2013 19:30:00 +0000 Subject: [PATCH 020/101] Added Solver.AssertAndTrack Convenience fixes. Renamed Context.Const to Context.ConstProbe Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 6 +++--- src/api/dotnet/Solver.cs | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 6d322394c..35fe6611d 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -236,7 +236,7 @@ namespace Microsoft.Z3 /// /// Create a new enumeration sort. /// - public EnumSort MkEnumSort(Symbol name, Symbol[] enumNames) + public EnumSort MkEnumSort(Symbol name, params Symbol[] enumNames) { Contract.Requires(name != null); Contract.Requires(enumNames != null); @@ -252,7 +252,7 @@ namespace Microsoft.Z3 /// /// Create a new enumeration sort. /// - public EnumSort MkEnumSort(string name, string[] enumNames) + public EnumSort MkEnumSort(string name, params string[] enumNames) { Contract.Requires(enumNames != null); Contract.Ensures(Contract.Result() != null); @@ -3219,7 +3219,7 @@ namespace Microsoft.Z3 /// /// Create a probe that always evaluates to . /// - public Probe Const(double val) + public Probe ConstProbe(double val) { Contract.Ensures(Contract.Result() != null); diff --git a/src/api/dotnet/Solver.cs b/src/api/dotnet/Solver.cs index fe3a42fa4..8c07ef31e 100644 --- a/src/api/dotnet/Solver.cs +++ b/src/api/dotnet/Solver.cs @@ -117,6 +117,50 @@ namespace Microsoft.Z3 } } + /// + /// Assert multiple constraints into the solver, and track them (in the unsat) core + /// using the Boolean constants in ps. + /// + /// + /// This API is an alternative to with assumptions for extracting unsat cores. + /// Both APIs can be used in the same solver. The unsat core will contain a combination + /// of the Boolean variables provided using and the Boolean literals + /// provided using with assumptions. + /// + public void AssertAndTrack(BoolExpr[] constraints, BoolExpr[] ps) + { + Contract.Requires(constraints != null); + Contract.Requires(Contract.ForAll(constraints, c => c != null)); + Contract.Requires(Contract.ForAll(ps, c => c != null)); + Context.CheckContextMatch(constraints); + Context.CheckContextMatch(ps); + if (constraints.Length != ps.Length) + throw new Z3Exception("Argument size mismatch"); + + for (int i = 0 ; i < constraints.Length; i++) + Native.Z3_solver_assert_and_track(Context.nCtx, NativeObject, constraints[i].NativeObject, ps[i].NativeObject); + } + + /// + /// Assert a constraint into the solver, and track it (in the unsat) core + /// using the Boolean constant p. + /// + /// + /// This API is an alternative to with assumptions for extracting unsat cores. + /// Both APIs can be used in the same solver. The unsat core will contain a combination + /// of the Boolean variables provided using and the Boolean literals + /// provided using with assumptions. + /// + public void AssertAndTrack(BoolExpr constraint, BoolExpr p) + { + Contract.Requires(constraint != null); + Contract.Requires(p != null); + Context.CheckContextMatch(constraint); + Context.CheckContextMatch(p); + + Native.Z3_solver_assert_and_track(Context.nCtx, NativeObject, constraint.NativeObject, p.NativeObject); + } + /// /// The number of assertions in the solver. /// From 4b18c8f9c4c472ebd176e6535ca86e31b33d7304 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Jan 2013 19:31:02 +0000 Subject: [PATCH 021/101] Java API: syntactic adjustments, getters, setters, ... convenience parameters, etc. Signed-off-by: Christoph M. Wintersteiger --- examples/java/JavaExample.java | 1623 +++++++++--------- src/api/java/AST.java | 87 +- src/api/java/ASTDecRefQueue.java | 6 +- src/api/java/ASTMap.java | 50 +- src/api/java/ASTVector.java | 40 +- src/api/java/AlgebraicNum.java | 16 +- src/api/java/ApplyResult.java | 34 +- src/api/java/ApplyResultDecRefQueue.java | 4 +- src/api/java/ArraySort.java | 16 +- src/api/java/AstMapDecRefQueue.java | 4 +- src/api/java/AstVectorDecRefQueue.java | 4 +- src/api/java/BitVecExpr.java | 6 +- src/api/java/BitVecNum.java | 12 +- src/api/java/BitVecSort.java | 4 +- src/api/java/Constructor.java | 26 +- src/api/java/ConstructorList.java | 6 +- src/api/java/Context.java | 1604 +++++++++-------- src/api/java/DatatypeSort.java | 44 +- src/api/java/EnumSort.java | 10 +- src/api/java/Expr.java | 774 +++++---- src/api/java/FiniteDomainSort.java | 6 +- src/api/java/Fixedpoint.java | 163 +- src/api/java/FixedpointDecRefQueue.java | 4 +- src/api/java/FuncDecl.java | 164 +- src/api/java/FuncInterp.java | 80 +- src/api/java/FuncInterpDecRefQueue.java | 4 +- src/api/java/FuncInterpEntryDecRefQueue.java | 4 +- src/api/java/Global.java | 6 +- src/api/java/Goal.java | 126 +- src/api/java/GoalDecRefQueue.java | 4 +- src/api/java/IDecRefQueue.java | 20 +- src/api/java/IDisposable.java | 2 +- src/api/java/IntNum.java | 12 +- src/api/java/IntSymbol.java | 14 +- src/api/java/ListSort.java | 27 +- src/api/java/Log.java | 6 +- src/api/java/Model.java | 136 +- src/api/java/ModelDecRefQueue.java | 4 +- src/api/java/ParamDescrs.java | 38 +- src/api/java/ParamDescrsDecRefQueue.java | 4 +- src/api/java/Params.java | 56 +- src/api/java/ParamsDecRefQueue.java | 4 +- src/api/java/Pattern.java | 14 +- src/api/java/Probe.java | 29 +- src/api/java/ProbeDecRefQueue.java | 4 +- src/api/java/Quantifier.java | 126 +- src/api/java/RatNum.java | 26 +- src/api/java/RelationSort.java | 12 +- src/api/java/SetSort.java | 2 +- src/api/java/Solver.java | 183 +- src/api/java/SolverDecRefQueue.java | 4 +- src/api/java/Sort.java | 35 +- src/api/java/Statistics.java | 62 +- src/api/java/StatisticsDecRefQueue.java | 4 +- src/api/java/StringSymbol.java | 12 +- src/api/java/Symbol.java | 26 +- src/api/java/Tactic.java | 58 +- src/api/java/TacticDecRefQueue.java | 4 +- src/api/java/TupleSort.java | 24 +- src/api/java/UninterpretedSort.java | 2 +- src/api/java/Version.java | 8 +- src/api/java/Z3Exception.java | 1 - src/api/java/Z3Object.java | 34 +- 63 files changed, 2939 insertions(+), 2985 deletions(-) diff --git a/examples/java/JavaExample.java b/examples/java/JavaExample.java index b3cb939ac..a26c21d65 100644 --- a/examples/java/JavaExample.java +++ b/examples/java/JavaExample.java @@ -41,10 +41,10 @@ class JavaExample // / // / Where, finvis a fresh function declaration. - public BoolExpr InjAxiom(Context ctx, FuncDecl f, int i) throws Z3Exception + public BoolExpr injAxiom(Context ctx, FuncDecl f, int i) throws Z3Exception { - Sort[] domain = f.Domain(); - int sz = f.DomainSize(); + Sort[] domain = f.getDomain(); + int sz = f.getDomainSize(); if (i >= sz) { @@ -53,9 +53,9 @@ class JavaExample } /* declare the i-th inverse of f: finv */ - Sort finv_domain = f.Range(); + Sort finv_domain = f.getRange(); Sort finv_range = domain[i]; - FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); + FuncDecl finv = ctx.mkFuncDecl("f_fresh", finv_domain, finv_range); /* allocate temporary arrays */ Expr[] xs = new Expr[sz]; @@ -67,25 +67,25 @@ class JavaExample for (int j = 0; j < sz; j++) { types[j] = domain[j]; - names[j] = ctx.MkSymbol("x_" + Integer.toString(j)); - xs[j] = ctx.MkBound(j, types[j]); + names[j] = ctx.mkSymbol("x_" + Integer.toString(j)); + xs[j] = ctx.mkBound(j, types[j]); } Expr x_i = xs[i]; /* create f(x_0, ..., x_i, ..., x_{n-1}) */ - Expr fxs = f.Apply(xs); + Expr fxs = f.apply(xs); /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ - Expr finv_fxs = finv.Apply(fxs); + Expr finv_fxs = finv.apply(fxs); /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ - Expr eq = ctx.MkEq(finv_fxs, x_i); + Expr eq = ctx.mkEq(finv_fxs, x_i); /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ - Pattern p = ctx.MkPattern(new Expr[] { fxs }); + Pattern p = ctx.mkPattern(fxs); /* create & assert quantifier */ - BoolExpr q = ctx.MkForall(types, /* types of quantified variables */ + BoolExpr q = ctx.mkForall(types, /* types of quantified variables */ names, /* names of quantified variables */ eq, 1, new Pattern[] { p } /* patterns */, null, null, null); @@ -101,11 +101,11 @@ class JavaExample // / // / Where, finvis a fresh function declaration. - public BoolExpr InjAxiomAbs(Context ctx, FuncDecl f, int i) + public BoolExpr injAxiomAbs(Context ctx, FuncDecl f, int i) throws Z3Exception { - Sort[] domain = f.Domain(); - int sz = f.DomainSize(); + Sort[] domain = f.getDomain(); + int sz = f.getDomainSize(); if (i >= sz) { @@ -114,9 +114,9 @@ class JavaExample } /* declare the i-th inverse of f: finv */ - Sort finv_domain = f.Range(); + Sort finv_domain = f.getRange(); Sort finv_range = domain[i]; - FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); + FuncDecl finv = ctx.mkFuncDecl("f_fresh", finv_domain, finv_range); /* allocate temporary arrays */ Expr[] xs = new Expr[sz]; @@ -124,24 +124,24 @@ class JavaExample /* fill types, names and xs */ for (int j = 0; j < sz; j++) { - xs[j] = ctx.MkConst("x_" + Integer.toString(j), domain[j]); + xs[j] = ctx.mkConst("x_" + Integer.toString(j), domain[j]); } Expr x_i = xs[i]; /* create f(x_0, ..., x_i, ..., x_{n-1}) */ - Expr fxs = f.Apply(xs); + Expr fxs = f.apply(xs); /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ - Expr finv_fxs = finv.Apply(fxs); + Expr finv_fxs = finv.apply(fxs); /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ - Expr eq = ctx.MkEq(finv_fxs, x_i); + Expr eq = ctx.mkEq(finv_fxs, x_i); /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ - Pattern p = ctx.MkPattern(new Expr[] { fxs }); + Pattern p = ctx.mkPattern(fxs); /* create & assert quantifier */ - BoolExpr q = ctx.MkForall(xs, /* types of quantified variables */ + BoolExpr q = ctx.mkForall(xs, /* types of quantified variables */ eq, /* names of quantified variables */ 1, new Pattern[] { p } /* patterns */, null, null, null); @@ -154,10 +154,10 @@ class JavaExample // / This example uses the SMT-LIB parser to simplify the axiom // construction. // / - private BoolExpr CommAxiom(Context ctx, FuncDecl f) throws Exception + private BoolExpr commAxiom(Context ctx, FuncDecl f) throws Exception { - Sort t = f.Range(); - Sort[] dom = f.Domain(); + Sort t = f.getRange(); + Sort[] dom = f.getDomain(); if (dom.length != 2 || !t.equals(dom[0]) || !t.equals(dom[1])) { @@ -168,70 +168,70 @@ class JavaExample "function must be binary, and argument types must be equal to return type"); } - String bench = "(benchmark comm :formula (forall (x " + t.Name() - + ") (y " + t.Name() + ") (= (" + f.Name() + " x y) (" - + f.Name() + " y x))))"; - ctx.ParseSMTLIBString(bench, new Symbol[] { t.Name() }, - new Sort[] { t }, new Symbol[] { f.Name() }, + String bench = "(benchmark comm :formula (forall (x " + t.getName() + + ") (y " + t.getName() + ") (= (" + f.getName() + " x y) (" + + f.getName() + " y x))))"; + ctx.parseSMTLIBString(bench, new Symbol[] { t.getName() }, + new Sort[] { t }, new Symbol[] { f.getName() }, new FuncDecl[] { f }); - return ctx.SMTLIBFormulas()[0]; + return ctx.getSMTLIBFormulas()[0]; } // / "Hello world" example: create a Z3 logical context, and delete it. - public void SimpleExample() throws Z3Exception + public void simpleExample() throws Z3Exception { System.out.println("SimpleExample"); - Log.Append("SimpleExample"); + Log.append("SimpleExample"); { Context ctx = new Context(); /* do something with the context */ /* be kind to dispose manually and not wait for the GC. */ - ctx.Dispose(); + ctx.dispose(); } } - Model Check(Context ctx, BoolExpr f, Status sat) throws Z3Exception, + Model check(Context ctx, BoolExpr f, Status sat) throws Z3Exception, TestFailedException { - Solver s = ctx.MkSolver(); - s.Assert(f); - if (s.Check() != sat) + Solver s = ctx.mkSolver(); + s.assert_(f); + if (s.check() != sat) throw new TestFailedException(); if (sat == Status.SATISFIABLE) - return s.Model(); + return s.getModel(); else return null; } - void SolveTactical(Context ctx, Tactic t, Goal g, Status sat) + void solveTactical(Context ctx, Tactic t, Goal g, Status sat) throws Z3Exception, TestFailedException { - Solver s = ctx.MkSolver(t); + Solver s = ctx.mkSolver(t); System.out.println("\nTactical solver: " + s); - for (BoolExpr a : g.Formulas()) - s.Assert(a); + for (BoolExpr a : g.getFormulas()) + s.assert_(a); System.out.println("Solver: " + s); - if (s.Check() != sat) + if (s.check() != sat) throw new TestFailedException(); } - ApplyResult ApplyTactic(Context ctx, Tactic t, Goal g) throws Z3Exception + ApplyResult applyTactic(Context ctx, Tactic t, Goal g) throws Z3Exception { System.out.println("\nGoal: " + g); - ApplyResult res = t.Apply(g); + ApplyResult res = t.apply(g); System.out.println("Application result: " + res); Status q = Status.UNKNOWN; - for (Goal sg : res.Subgoals()) - if (sg.IsDecidedSat()) + for (Goal sg : res.getSubgoals()) + if (sg.isDecidedSat()) q = Status.SATISFIABLE; - else if (sg.IsDecidedUnsat()) + else if (sg.isDecidedUnsat()) q = Status.UNSATISFIABLE; switch (q) @@ -250,170 +250,156 @@ class JavaExample return res; } - void Prove(Context ctx, BoolExpr f, boolean useMBQI) throws Z3Exception, + void prove(Context ctx, BoolExpr f, boolean useMBQI) throws Z3Exception, TestFailedException { BoolExpr[] assumptions = new BoolExpr[0]; - Prove(ctx, f, useMBQI, assumptions); + prove(ctx, f, useMBQI, assumptions); } - void Prove(Context ctx, BoolExpr f, boolean useMBQI, BoolExpr assumption) - throws Z3Exception, TestFailedException - { - BoolExpr[] assumptions = { assumption }; - Prove(ctx, f, useMBQI, assumptions); - } - - void Prove(Context ctx, BoolExpr f, boolean useMBQI, BoolExpr[] assumptions) - throws Z3Exception, TestFailedException + void prove(Context ctx, BoolExpr f, boolean useMBQI, + BoolExpr... assumptions) throws Z3Exception, TestFailedException { System.out.println("Proving: " + f); - Solver s = ctx.MkSolver(); - Params p = ctx.MkParams(); - p.Add("mbqi", useMBQI); + Solver s = ctx.mkSolver(); + Params p = ctx.mkParams(); + p.add("mbqi", useMBQI); s.setParameters(p); for (BoolExpr a : assumptions) - s.Assert(a); - s.Assert(ctx.MkNot(f)); - Status q = s.Check(); + s.assert_(a); + s.assert_(ctx.mkNot(f)); + Status q = s.check(); switch (q) { case UNKNOWN: - System.out.println("Unknown because: " + s.ReasonUnknown()); + System.out.println("Unknown because: " + s.getReasonUnknown()); break; case SATISFIABLE: throw new TestFailedException(); case UNSATISFIABLE: - System.out.println("OK, proof: " + s.Proof()); + System.out.println("OK, proof: " + s.getProof()); break; } } - void Disprove(Context ctx, BoolExpr f, boolean useMBQI) throws Z3Exception, + void disprove(Context ctx, BoolExpr f, boolean useMBQI) throws Z3Exception, TestFailedException { BoolExpr[] a = {}; - Disprove(ctx, f, useMBQI, a); + disprove(ctx, f, useMBQI, a); } - void Disprove(Context ctx, BoolExpr f, boolean useMBQI, BoolExpr assumption) - throws Z3Exception, TestFailedException - { - BoolExpr[] a = { assumption }; - Disprove(ctx, f, useMBQI, a); - } - - void Disprove(Context ctx, BoolExpr f, boolean useMBQI, - BoolExpr[] assumptions) throws Z3Exception, TestFailedException + void disprove(Context ctx, BoolExpr f, boolean useMBQI, + BoolExpr... assumptions) throws Z3Exception, TestFailedException { System.out.println("Disproving: " + f); - Solver s = ctx.MkSolver(); - Params p = ctx.MkParams(); - p.Add("mbqi", useMBQI); + Solver s = ctx.mkSolver(); + Params p = ctx.mkParams(); + p.add("mbqi", useMBQI); s.setParameters(p); for (BoolExpr a : assumptions) - s.Assert(a); - s.Assert(ctx.MkNot(f)); - Status q = s.Check(); + s.assert_(a); + s.assert_(ctx.mkNot(f)); + Status q = s.check(); switch (q) { case UNKNOWN: - System.out.println("Unknown because: " + s.ReasonUnknown()); + System.out.println("Unknown because: " + s.getReasonUnknown()); break; case SATISFIABLE: - System.out.println("OK, model: " + s.Model()); + System.out.println("OK, model: " + s.getModel()); break; case UNSATISFIABLE: throw new TestFailedException(); } } - void ModelConverterTest(Context ctx) throws Z3Exception, + void modelConverterTest(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ModelConverterTest"); - ArithExpr xr = (ArithExpr) ctx.MkConst(ctx.MkSymbol("x"), - ctx.MkRealSort()); - ArithExpr yr = (ArithExpr) ctx.MkConst(ctx.MkSymbol("y"), - ctx.MkRealSort()); - Goal g4 = ctx.MkGoal(true, false, false); - g4.Assert(ctx.MkGt(xr, ctx.MkReal(10, 1))); - g4.Assert(ctx.MkEq(yr, - ctx.MkAdd(new ArithExpr[] { xr, ctx.MkReal(1, 1) }))); - g4.Assert(ctx.MkGt(yr, ctx.MkReal(1, 1))); + ArithExpr xr = (ArithExpr) ctx.mkConst(ctx.mkSymbol("x"), + ctx.mkRealSort()); + ArithExpr yr = (ArithExpr) ctx.mkConst(ctx.mkSymbol("y"), + ctx.mkRealSort()); + Goal g4 = ctx.mkGoal(true, false, false); + g4.assert_(ctx.mkGt(xr, ctx.mkReal(10, 1))); + g4.assert_(ctx.mkEq(yr, ctx.mkAdd(xr, ctx.mkReal(1, 1)))); + g4.assert_(ctx.mkGt(yr, ctx.mkReal(1, 1))); - ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g4); - if (ar.NumSubgoals() == 1 - && (ar.Subgoals()[0].IsDecidedSat() || ar.Subgoals()[0] - .IsDecidedUnsat())) + ApplyResult ar = applyTactic(ctx, ctx.mkTactic("simplify"), g4); + if (ar.getNumSubgoals() == 1 + && (ar.getSubgoals()[0].isDecidedSat() || ar.getSubgoals()[0] + .isDecidedUnsat())) throw new TestFailedException(); - ar = ApplyTactic(ctx, ctx.AndThen(ctx.MkTactic("simplify"), - ctx.MkTactic("solve-eqs"), null), g4); - if (ar.NumSubgoals() == 1 - && (ar.Subgoals()[0].IsDecidedSat() || ar.Subgoals()[0] - .IsDecidedUnsat())) + ar = applyTactic(ctx, ctx.andThen(ctx.mkTactic("simplify"), + ctx.mkTactic("solve-eqs")), g4); + if (ar.getNumSubgoals() == 1 + && (ar.getSubgoals()[0].isDecidedSat() || ar.getSubgoals()[0] + .isDecidedUnsat())) throw new TestFailedException(); - Solver s = ctx.MkSolver(); - for (BoolExpr e : ar.Subgoals()[0].Formulas()) - s.Assert(e); - Status q = s.Check(); + Solver s = ctx.mkSolver(); + for (BoolExpr e : ar.getSubgoals()[0].getFormulas()) + s.assert_(e); + Status q = s.check(); System.out.println("Solver says: " + q); - System.out.println("Model: \n" + s.Model()); + System.out.println("Model: \n" + s.getModel()); System.out.println("Converted Model: \n" - + ar.ConvertModel(0, s.Model())); + + ar.convertModel(0, s.getModel())); if (q != Status.SATISFIABLE) throw new TestFailedException(); } // / A simple array example. - void ArrayExample1(Context ctx) throws Z3Exception, TestFailedException + void arrayExample1(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ArrayExample1"); - Log.Append("ArrayExample1"); + Log.append("ArrayExample1"); - Goal g = ctx.MkGoal(true, false, false); - ArraySort asort = ctx.MkArraySort(ctx.IntSort(), ctx.MkBitVecSort(32)); - ArrayExpr aex = (ArrayExpr) ctx.MkConst(ctx.MkSymbol("MyArray"), asort); - Expr sel = ctx.MkSelect(aex, ctx.MkInt(0)); - g.Assert(ctx.MkEq(sel, ctx.MkBV(42, 32))); - Symbol xs = ctx.MkSymbol("x"); - IntExpr xc = (IntExpr) ctx.MkConst(xs, ctx.IntSort()); + Goal g = ctx.mkGoal(true, false, false); + ArraySort asort = ctx.mkArraySort(ctx.getIntSort(), + ctx.mkBitVecSort(32)); + ArrayExpr aex = (ArrayExpr) ctx.mkConst(ctx.mkSymbol("MyArray"), asort); + Expr sel = ctx.mkSelect(aex, ctx.mkInt(0)); + g.assert_(ctx.mkEq(sel, ctx.mkBV(42, 32))); + Symbol xs = ctx.mkSymbol("x"); + IntExpr xc = (IntExpr) ctx.mkConst(xs, ctx.getIntSort()); - Symbol fname = ctx.MkSymbol("f"); - Sort[] domain = { ctx.IntSort() }; - FuncDecl fd = ctx.MkFuncDecl(fname, domain, ctx.IntSort()); - Expr[] fargs = { ctx.MkConst(xs, ctx.IntSort()) }; - IntExpr fapp = (IntExpr) ctx.MkApp(fd, fargs); + Symbol fname = ctx.mkSymbol("f"); + Sort[] domain = { ctx.getIntSort() }; + FuncDecl fd = ctx.mkFuncDecl(fname, domain, ctx.getIntSort()); + Expr[] fargs = { ctx.mkConst(xs, ctx.getIntSort()) }; + IntExpr fapp = (IntExpr) ctx.mkApp(fd, fargs); - g.Assert(ctx.MkEq(ctx.MkAdd(new ArithExpr[] { xc, fapp }), - ctx.MkInt(123))); + g.assert_(ctx.mkEq(ctx.mkAdd(xc, fapp), ctx.mkInt(123))); - Solver s = ctx.MkSolver(); - for (BoolExpr a : g.Formulas()) - s.Assert(a); + Solver s = ctx.mkSolver(); + for (BoolExpr a : g.getFormulas()) + s.assert_(a); System.out.println("Solver: " + s); - Status q = s.Check(); + Status q = s.check(); System.out.println("Status: " + q); if (q != Status.SATISFIABLE) throw new TestFailedException(); - System.out.println("Model = " + s.Model()); + System.out.println("Model = " + s.getModel()); System.out.println("Interpretation of MyArray:\n" - + s.Model().FuncInterp(aex.FuncDecl())); - System.out - .println("Interpretation of x:\n" + s.Model().ConstInterp(xc)); - System.out.println("Interpretation of f:\n" + s.Model().FuncInterp(fd)); + + s.getModel().getFuncInterp(aex.getFuncDecl())); + System.out.println("Interpretation of x:\n" + + s.getModel().getConstInterp(xc)); + System.out.println("Interpretation of f:\n" + + s.getModel().getFuncInterp(fd)); System.out.println("Interpretation of MyArray as Term:\n" - + s.Model().FuncInterp(aex.FuncDecl())); + + s.getModel().getFuncInterp(aex.getFuncDecl())); } // / Prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 @@ -421,48 +407,48 @@ class JavaExample // / This example demonstrates how to use the array // theory. - public void ArrayExample2(Context ctx) throws Z3Exception, + public void arrayExample2(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ArrayExample2"); - Log.Append("ArrayExample2"); + Log.append("ArrayExample2"); - Sort int_type = ctx.IntSort(); - Sort array_type = ctx.MkArraySort(int_type, int_type); + Sort int_type = ctx.getIntSort(); + Sort array_type = ctx.mkArraySort(int_type, int_type); - ArrayExpr a1 = (ArrayExpr) ctx.MkConst("a1", array_type); - ArrayExpr a2 = ctx.MkArrayConst("a2", int_type, int_type); - Expr i1 = ctx.MkConst("i1", int_type); - Expr i2 = ctx.MkConst("i2", int_type); - Expr i3 = ctx.MkConst("i3", int_type); - Expr v1 = ctx.MkConst("v1", int_type); - Expr v2 = ctx.MkConst("v2", int_type); + ArrayExpr a1 = (ArrayExpr) ctx.mkConst("a1", array_type); + ArrayExpr a2 = ctx.mkArrayConst("a2", int_type, int_type); + Expr i1 = ctx.mkConst("i1", int_type); + Expr i2 = ctx.mkConst("i2", int_type); + Expr i3 = ctx.mkConst("i3", int_type); + Expr v1 = ctx.mkConst("v1", int_type); + Expr v2 = ctx.mkConst("v2", int_type); - Expr st1 = ctx.MkStore(a1, i1, v1); - Expr st2 = ctx.MkStore(a2, i2, v2); + Expr st1 = ctx.mkStore(a1, i1, v1); + Expr st2 = ctx.mkStore(a2, i2, v2); - Expr sel1 = ctx.MkSelect(a1, i3); - Expr sel2 = ctx.MkSelect(a2, i3); + Expr sel1 = ctx.mkSelect(a1, i3); + Expr sel2 = ctx.mkSelect(a2, i3); /* create antecedent */ - BoolExpr antecedent = ctx.MkEq(st1, st2); + BoolExpr antecedent = ctx.mkEq(st1, st2); /* * create consequent: i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, * i3) */ - BoolExpr consequent = ctx.MkOr(new BoolExpr[] { ctx.MkEq(i1, i3), - ctx.MkEq(i2, i3), ctx.MkEq(sel1, sel2) }); + BoolExpr consequent = ctx.mkOr(ctx.mkEq(i1, i3), ctx.mkEq(i2, i3), + ctx.mkEq(sel1, sel2)); /* * prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = * i3 or select(a1, i3) = select(a2, i3)) */ - BoolExpr thm = ctx.MkImplies(antecedent, consequent); + BoolExpr thm = ctx.mkImplies(antecedent, consequent); System.out .println("prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))"); System.out.println(thm); - Prove(ctx, thm, false); + prove(ctx, thm, false); } // / Show that distinct(a_0, ... , a_n) is @@ -471,39 +457,39 @@ class JavaExample // / This example also shows how to use the distinct // construct. - public void ArrayExample3(Context ctx) throws Z3Exception, + public void arrayExample3(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ArrayExample3"); - Log.Append("ArrayExample2"); + Log.append("ArrayExample2"); for (int n = 2; n <= 5; n++) { System.out.println("n = " + Integer.toString(n)); - Sort bool_type = ctx.MkBoolSort(); - Sort array_type = ctx.MkArraySort(bool_type, bool_type); + Sort bool_type = ctx.mkBoolSort(); + Sort array_type = ctx.mkArraySort(bool_type, bool_type); Expr[] a = new Expr[n]; /* create arrays */ for (int i = 0; i < n; i++) { - a[i] = ctx.MkConst("array_" + Integer.toString(i), array_type); + a[i] = ctx.mkConst("array_" + Integer.toString(i), array_type); } /* assert distinct(a[0], ..., a[n]) */ - BoolExpr d = ctx.MkDistinct(a); + BoolExpr d = ctx.mkDistinct(a); System.out.println(d); /* context is satisfiable if n < 5 */ - Model model = Check(ctx, d, n < 5 ? Status.SATISFIABLE + Model model = check(ctx, d, n < 5 ? Status.SATISFIABLE : Status.UNSATISFIABLE); if (n < 5) { for (int i = 0; i < n; i++) { System.out.println(a[i].toString() + " = " - + model.Evaluate(a[i], false)); + + model.evaluate(a[i], false)); } } } @@ -511,10 +497,10 @@ class JavaExample // / Sudoku solving example. - void SudokuExample(Context ctx) throws Z3Exception, TestFailedException + void sudokuExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("SudokuExample"); - Log.Append("SudokuExample"); + Log.append("SudokuExample"); // 9x9 matrix of integer variables IntExpr[][] X = new IntExpr[9][]; @@ -522,9 +508,9 @@ class JavaExample { X[i] = new IntExpr[9]; for (int j = 0; j < 9; j++) - X[i][j] = (IntExpr) ctx.MkConst( - ctx.MkSymbol("x_" + (i + 1) + "_" + (j + 1)), - ctx.IntSort()); + X[i][j] = (IntExpr) ctx.mkConst( + ctx.mkSymbol("x_" + (i + 1) + "_" + (j + 1)), + ctx.getIntSort()); } // each cell contains a value in {1, ..., 9} @@ -533,20 +519,19 @@ class JavaExample { cells_c[i] = new BoolExpr[9]; for (int j = 0; j < 9; j++) - cells_c[i][j] = ctx.MkAnd(new BoolExpr[] { - ctx.MkLe(ctx.MkInt(1), X[i][j]), - ctx.MkLe(X[i][j], ctx.MkInt(9)) }); + cells_c[i][j] = ctx.mkAnd(ctx.mkLe(ctx.mkInt(1), X[i][j]), + ctx.mkLe(X[i][j], ctx.mkInt(9))); } // each row contains a digit at most once BoolExpr[] rows_c = new BoolExpr[9]; for (int i = 0; i < 9; i++) - rows_c[i] = ctx.MkDistinct(X[i]); + rows_c[i] = ctx.mkDistinct(X[i]); // each column contains a digit at most once BoolExpr[] cols_c = new BoolExpr[9]; for (int j = 0; j < 9; j++) - cols_c[j] = ctx.MkDistinct(X[j]); + cols_c[j] = ctx.mkDistinct(X[j]); // each 3x3 square contains a digit at most once BoolExpr[][] sq_c = new BoolExpr[3][]; @@ -559,17 +544,17 @@ class JavaExample for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) square[3 * i + j] = X[3 * i0 + i][3 * j0 + j]; - sq_c[i0][j0] = ctx.MkDistinct(square); + sq_c[i0][j0] = ctx.mkDistinct(square); } } - BoolExpr sudoku_c = ctx.MkTrue(); + BoolExpr sudoku_c = ctx.mkTrue(); for (BoolExpr[] t : cells_c) - sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(t), sudoku_c }); - sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(rows_c), sudoku_c }); - sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(cols_c), sudoku_c }); + sudoku_c = ctx.mkAnd(ctx.mkAnd(t), sudoku_c); + sudoku_c = ctx.mkAnd(ctx.mkAnd(rows_c), sudoku_c); + sudoku_c = ctx.mkAnd(ctx.mkAnd(cols_c), sudoku_c); for (BoolExpr[] t : sq_c) - sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(t), sudoku_c }); + sudoku_c = ctx.mkAnd(ctx.mkAnd(t), sudoku_c); // sudoku instance, we use '0' for empty cells int[][] instance = { { 0, 0, 0, 0, 9, 4, 0, 3, 0 }, @@ -578,30 +563,27 @@ class JavaExample { 1, 0, 2, 0, 0, 0, 0, 0, 0 }, { 0, 7, 0, 0, 0, 0, 5, 2, 0 }, { 9, 0, 0, 0, 6, 5, 0, 0, 0 }, { 0, 4, 0, 9, 7, 0, 0, 0, 0 } }; - BoolExpr instance_c = ctx.MkTrue(); + BoolExpr instance_c = ctx.mkTrue(); for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) - instance_c = ctx - .MkAnd(new BoolExpr[] { - instance_c, - (BoolExpr) ctx.MkITE( - ctx.MkEq(ctx.MkInt(instance[i][j]), - ctx.MkInt(0)), - ctx.MkTrue(), - ctx.MkEq(X[i][j], - ctx.MkInt(instance[i][j]))) }); + instance_c = ctx.mkAnd( + instance_c, + (BoolExpr) ctx.mkITE( + ctx.mkEq(ctx.mkInt(instance[i][j]), + ctx.mkInt(0)), ctx.mkTrue(), + ctx.mkEq(X[i][j], ctx.mkInt(instance[i][j])))); - Solver s = ctx.MkSolver(); - s.Assert(sudoku_c); - s.Assert(instance_c); + Solver s = ctx.mkSolver(); + s.assert_(sudoku_c); + s.assert_(instance_c); - if (s.Check() == Status.SATISFIABLE) + if (s.check() == Status.SATISFIABLE) { - Model m = s.Model(); + Model m = s.getModel(); Expr[][] R = new Expr[9][9]; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) - R[i][j] = m.Evaluate(X[i][j], false); + R[i][j] = m.evaluate(X[i][j], false); System.out.println("Sudoku solution:"); for (int i = 0; i < 9; i++) { @@ -618,10 +600,10 @@ class JavaExample // / A basic example of how to use quantifiers. - void QuantifierExample1(Context ctx) throws Z3Exception + void quantifierExample1(Context ctx) throws Z3Exception { System.out.println("QuantifierExample"); - Log.Append("QuantifierExample"); + Log.append("QuantifierExample"); Sort[] types = new Sort[3]; IntExpr[] xs = new IntExpr[3]; @@ -630,87 +612,78 @@ class JavaExample for (int j = 0; j < 3; j++) { - types[j] = ctx.IntSort(); - names[j] = ctx.MkSymbol("x_" + Integer.toString(j)); - xs[j] = (IntExpr) ctx.MkConst(names[j], types[j]); - vars[j] = (IntExpr) ctx.MkBound(2 - j, types[j]); // <-- vars + types[j] = ctx.getIntSort(); + names[j] = ctx.mkSymbol("x_" + Integer.toString(j)); + xs[j] = (IntExpr) ctx.mkConst(names[j], types[j]); + vars[j] = (IntExpr) ctx.mkBound(2 - j, types[j]); // <-- vars // reversed! } - Expr body_vars = ctx - .MkAnd(new BoolExpr[] { - ctx.MkEq( - ctx.MkAdd(new ArithExpr[] { vars[0], - ctx.MkInt(1) }), ctx.MkInt(2)), - ctx.MkEq( - ctx.MkAdd(new ArithExpr[] { vars[1], - ctx.MkInt(2) }), - ctx.MkAdd(new ArithExpr[] { vars[2], - ctx.MkInt(3) })) }); + Expr body_vars = ctx.mkAnd( + ctx.mkEq(ctx.mkAdd(vars[0], ctx.mkInt(1)), ctx.mkInt(2)), + ctx.mkEq(ctx.mkAdd(vars[1], ctx.mkInt(2)), + ctx.mkAdd(vars[2], ctx.mkInt(3)))); - Expr body_const = ctx.MkAnd(new BoolExpr[] { - ctx.MkEq(ctx.MkAdd(new ArithExpr[] { xs[0], ctx.MkInt(1) }), - ctx.MkInt(2)), - ctx.MkEq(ctx.MkAdd(new ArithExpr[] { xs[1], ctx.MkInt(2) }), - ctx.MkAdd(new ArithExpr[] { xs[2], ctx.MkInt(3) })) }); + Expr body_const = ctx.mkAnd( + ctx.mkEq(ctx.mkAdd(xs[0], ctx.mkInt(1)), ctx.mkInt(2)), + ctx.mkEq(ctx.mkAdd(xs[1], ctx.mkInt(2)), + ctx.mkAdd(xs[2], ctx.mkInt(3)))); - Expr x = ctx.MkForall(types, names, body_vars, 1, null, null, - ctx.MkSymbol("Q1"), ctx.MkSymbol("skid1")); + Expr x = ctx.mkForall(types, names, body_vars, 1, null, null, + ctx.mkSymbol("Q1"), ctx.mkSymbol("skid1")); System.out.println("Quantifier X: " + x.toString()); - Expr y = ctx.MkForall(xs, body_const, 1, null, null, - ctx.MkSymbol("Q2"), ctx.MkSymbol("skid2")); + Expr y = ctx.mkForall(xs, body_const, 1, null, null, + ctx.mkSymbol("Q2"), ctx.mkSymbol("skid2")); System.out.println("Quantifier Y: " + y.toString()); } - void QuantifierExample2(Context ctx) throws Z3Exception + void quantifierExample2(Context ctx) throws Z3Exception { System.out.println("QuantifierExample2"); - Log.Append("QuantifierExample2"); + Log.append("QuantifierExample2"); Expr q1, q2; - FuncDecl f = ctx.MkFuncDecl("f", ctx.IntSort(), ctx.IntSort()); - FuncDecl g = ctx.MkFuncDecl("g", ctx.IntSort(), ctx.IntSort()); + FuncDecl f = ctx.mkFuncDecl("f", ctx.getIntSort(), ctx.getIntSort()); + FuncDecl g = ctx.mkFuncDecl("g", ctx.getIntSort(), ctx.getIntSort()); // Quantifier with Exprs as the bound variables. { - Expr x = ctx.MkConst("x", ctx.IntSort()); - Expr y = ctx.MkConst("y", ctx.IntSort()); - Expr f_x = ctx.MkApp(f, new Expr[] { x }); - Expr f_y = ctx.MkApp(f, new Expr[] { y }); - Expr g_y = ctx.MkApp(g, new Expr[] { y }); - Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, - g_y }) }; + Expr x = ctx.mkConst("x", ctx.getIntSort()); + Expr y = ctx.mkConst("y", ctx.getIntSort()); + Expr f_x = ctx.mkApp(f, x); + Expr f_y = ctx.mkApp(f, y); + Expr g_y = ctx.mkApp(g, y); + @SuppressWarnings("unused") + Pattern[] pats = new Pattern[] { ctx.mkPattern(f_x, g_y) }; Expr[] no_pats = new Expr[] { f_y }; Expr[] bound = new Expr[] { x, y }; - Expr body = ctx.MkAnd(new BoolExpr[] { ctx.MkEq(f_x, f_y), - ctx.MkEq(f_y, g_y) }); + Expr body = ctx.mkAnd(ctx.mkEq(f_x, f_y), ctx.mkEq(f_y, g_y)); - q1 = ctx.MkForall(bound, body, 1, null, no_pats, ctx.MkSymbol("q"), - ctx.MkSymbol("sk")); + q1 = ctx.mkForall(bound, body, 1, null, no_pats, ctx.mkSymbol("q"), + ctx.mkSymbol("sk")); System.out.println(q1); } // Quantifier with de-Brujin indices. { - Expr x = ctx.MkBound(1, ctx.IntSort()); - Expr y = ctx.MkBound(0, ctx.IntSort()); - Expr f_x = ctx.MkApp(f, new Expr[] { x }); - Expr f_y = ctx.MkApp(f, new Expr[] { y }); - Expr g_y = ctx.MkApp(g, new Expr[] { y }); - Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, - g_y }) }; + Expr x = ctx.mkBound(1, ctx.getIntSort()); + Expr y = ctx.mkBound(0, ctx.getIntSort()); + Expr f_x = ctx.mkApp(f, x); + Expr f_y = ctx.mkApp(f, y); + Expr g_y = ctx.mkApp(g, y); + @SuppressWarnings("unused") + Pattern[] pats = new Pattern[] { ctx.mkPattern(f_x, g_y) }; Expr[] no_pats = new Expr[] { f_y }; - Symbol[] names = new Symbol[] { ctx.MkSymbol("x"), - ctx.MkSymbol("y") }; - Sort[] sorts = new Sort[] { ctx.IntSort(), ctx.IntSort() }; - Expr body = ctx.MkAnd(new BoolExpr[] { ctx.MkEq(f_x, f_y), - ctx.MkEq(f_y, g_y) }); + Symbol[] names = new Symbol[] { ctx.mkSymbol("x"), + ctx.mkSymbol("y") }; + Sort[] sorts = new Sort[] { ctx.getIntSort(), ctx.getIntSort() }; + Expr body = ctx.mkAnd(ctx.mkEq(f_x, f_y), ctx.mkEq(f_y, g_y)); - q2 = ctx.MkForall(sorts, names, body, 1, null, // pats, - no_pats, ctx.MkSymbol("q"), ctx.MkSymbol("sk")); + q2 = ctx.mkForall(sorts, names, body, 1, null, // pats, + no_pats, ctx.mkSymbol("q"), ctx.mkSymbol("sk")); System.out.println(q2); } @@ -721,11 +694,11 @@ class JavaExample // / f is injective in the second argument. - public void QuantifierExample3(Context ctx) throws Z3Exception, + public void quantifierExample3(Context ctx) throws Z3Exception, TestFailedException { System.out.println("QuantifierExample3"); - Log.Append("QuantifierExample3"); + Log.append("QuantifierExample3"); /* * If quantified formulas are asserted in a logical context, then the @@ -733,40 +706,41 @@ class JavaExample */ /* declare function f */ - Sort I = ctx.IntSort(); - FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + Sort I = ctx.getIntSort(); + FuncDecl f = ctx.mkFuncDecl("f", new Sort[] { I, I }, I); /* f is injective in the second argument. */ - BoolExpr inj = InjAxiom(ctx, f, 1); + BoolExpr inj = injAxiom(ctx, f, 1); /* create x, y, v, w, fxy, fwv */ - Expr x = ctx.MkIntConst("x"); - Expr y = ctx.MkIntConst("y"); - Expr v = ctx.MkIntConst("v"); - Expr w = ctx.MkIntConst("w"); - Expr fxy = ctx.MkApp(f, new Expr[] { x, y }); - Expr fwv = ctx.MkApp(f, new Expr[] { w, v }); + Expr x = ctx.mkIntConst("x"); + Expr y = ctx.mkIntConst("y"); + Expr v = ctx.mkIntConst("v"); + Expr w = ctx.mkIntConst("w"); + Expr fxy = ctx.mkApp(f, x, y); + Expr fwv = ctx.mkApp(f, w, v); /* f(x, y) = f(w, v) */ - BoolExpr p1 = ctx.MkEq(fxy, fwv); + BoolExpr p1 = ctx.mkEq(fxy, fwv); /* prove f(x, y) = f(w, v) implies y = v */ - BoolExpr p2 = ctx.MkEq(y, v); - Prove(ctx, p2, false, new BoolExpr[] { inj, p1 }); + BoolExpr p2 = ctx.mkEq(y, v); + prove(ctx, p2, false, inj, p1); /* disprove f(x, y) = f(w, v) implies x = w */ - BoolExpr p3 = ctx.MkEq(x, w); - Disprove(ctx, p3, false, new BoolExpr[] { inj, p1 }); + BoolExpr p3 = ctx.mkEq(x, w); + disprove(ctx, p3, false, inj, p1); } // / Prove that f(x, y) = f(w, v) implies y = v when // / f is injective in the second argument. - public void QuantifierExample4(Context ctx) throws Z3Exception, TestFailedException + public void quantifierExample4(Context ctx) throws Z3Exception, + TestFailedException { System.out.println("QuantifierExample4"); - Log.Append("QuantifierExample4"); + Log.append("QuantifierExample4"); /* * If quantified formulas are asserted in a logical context, then the @@ -774,140 +748,140 @@ class JavaExample */ /* declare function f */ - Sort I = ctx.IntSort(); - FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + Sort I = ctx.getIntSort(); + FuncDecl f = ctx.mkFuncDecl("f", new Sort[] { I, I }, I); /* f is injective in the second argument. */ - BoolExpr inj = InjAxiomAbs(ctx, f, 1); + BoolExpr inj = injAxiomAbs(ctx, f, 1); /* create x, y, v, w, fxy, fwv */ - Expr x = ctx.MkIntConst("x"); - Expr y = ctx.MkIntConst("y"); - Expr v = ctx.MkIntConst("v"); - Expr w = ctx.MkIntConst("w"); - Expr fxy = ctx.MkApp(f, new Expr[] { x, y }); - Expr fwv = ctx.MkApp(f, new Expr[] { w, v }); + Expr x = ctx.mkIntConst("x"); + Expr y = ctx.mkIntConst("y"); + Expr v = ctx.mkIntConst("v"); + Expr w = ctx.mkIntConst("w"); + Expr fxy = ctx.mkApp(f, x, y); + Expr fwv = ctx.mkApp(f, w, v); /* f(x, y) = f(w, v) */ - BoolExpr p1 = ctx.MkEq(fxy, fwv); + BoolExpr p1 = ctx.mkEq(fxy, fwv); /* prove f(x, y) = f(w, v) implies y = v */ - BoolExpr p2 = ctx.MkEq(y, v); - Prove(ctx, p2, false, new BoolExpr[] { inj, p1 }); + BoolExpr p2 = ctx.mkEq(y, v); + prove(ctx, p2, false, inj, p1); /* disprove f(x, y) = f(w, v) implies x = w */ - BoolExpr p3 = ctx.MkEq(x, w); - Disprove(ctx, p3, false, new BoolExpr[] { inj, p1 }); + BoolExpr p3 = ctx.mkEq(x, w); + disprove(ctx, p3, false, inj, p1); } // / Some basic tests. - void BasicTests(Context ctx) throws Z3Exception, TestFailedException + void basicTests(Context ctx) throws Z3Exception, TestFailedException { System.out.println("BasicTests"); - Symbol fname = ctx.MkSymbol("f"); - Symbol x = ctx.MkSymbol("x"); - Symbol y = ctx.MkSymbol("y"); + Symbol fname = ctx.mkSymbol("f"); + Symbol x = ctx.mkSymbol("x"); + Symbol y = ctx.mkSymbol("y"); - Sort bs = ctx.MkBoolSort(); + Sort bs = ctx.mkBoolSort(); Sort[] domain = { bs, bs }; - FuncDecl f = ctx.MkFuncDecl(fname, domain, bs); - Expr fapp = ctx.MkApp(f, - new Expr[] { ctx.MkConst(x, bs), ctx.MkConst(y, bs) }); + FuncDecl f = ctx.mkFuncDecl(fname, domain, bs); + Expr fapp = ctx.mkApp(f, ctx.mkConst(x, bs), ctx.mkConst(y, bs)); - Expr[] fargs2 = { ctx.MkFreshConst("cp", bs) }; + Expr[] fargs2 = { ctx.mkFreshConst("cp", bs) }; Sort[] domain2 = { bs }; - Expr fapp2 = ctx.MkApp(ctx.MkFreshFuncDecl("fp", domain2, bs), fargs2); + Expr fapp2 = ctx.mkApp(ctx.mkFreshFuncDecl("fp", domain2, bs), fargs2); - BoolExpr trivial_eq = ctx.MkEq(fapp, fapp); - BoolExpr nontrivial_eq = ctx.MkEq(fapp, fapp2); + BoolExpr trivial_eq = ctx.mkEq(fapp, fapp); + BoolExpr nontrivial_eq = ctx.mkEq(fapp, fapp2); - Goal g = ctx.MkGoal(true, false, false); - g.Assert(trivial_eq); - g.Assert(nontrivial_eq); + Goal g = ctx.mkGoal(true, false, false); + g.assert_(trivial_eq); + g.assert_(nontrivial_eq); System.out.println("Goal: " + g); - Solver solver = ctx.MkSolver(); + Solver solver = ctx.mkSolver(); - for (BoolExpr a : g.Formulas()) - solver.Assert(a); + for (BoolExpr a : g.getFormulas()) + solver.assert_(a); - if (solver.Check() != Status.SATISFIABLE) + if (solver.check() != Status.SATISFIABLE) throw new TestFailedException(); - ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); - if (ar.NumSubgoals() == 1 - && (ar.Subgoals()[0].IsDecidedSat() || ar.Subgoals()[0] - .IsDecidedUnsat())) + ApplyResult ar = applyTactic(ctx, ctx.mkTactic("simplify"), g); + if (ar.getNumSubgoals() == 1 + && (ar.getSubgoals()[0].isDecidedSat() || ar.getSubgoals()[0] + .isDecidedUnsat())) throw new TestFailedException(); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); - if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + ar = applyTactic(ctx, ctx.mkTactic("smt"), g); + if (ar.getNumSubgoals() != 1 || !ar.getSubgoals()[0].isDecidedSat()) throw new TestFailedException(); - g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), - ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); - if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedUnsat()) + g.assert_(ctx.mkEq(ctx.mkNumeral(1, ctx.mkBitVecSort(32)), + ctx.mkNumeral(2, ctx.mkBitVecSort(32)))); + ar = applyTactic(ctx, ctx.mkTactic("smt"), g); + if (ar.getNumSubgoals() != 1 || !ar.getSubgoals()[0].isDecidedUnsat()) throw new TestFailedException(); - Goal g2 = ctx.MkGoal(true, true, false); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); - if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + Goal g2 = ctx.mkGoal(true, true, false); + ar = applyTactic(ctx, ctx.mkTactic("smt"), g2); + if (ar.getNumSubgoals() != 1 || !ar.getSubgoals()[0].isDecidedSat()) throw new TestFailedException(); - g2 = ctx.MkGoal(true, true, false); - g2.Assert(ctx.MkFalse()); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); - if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedUnsat()) + g2 = ctx.mkGoal(true, true, false); + g2.assert_(ctx.mkFalse()); + ar = applyTactic(ctx, ctx.mkTactic("smt"), g2); + if (ar.getNumSubgoals() != 1 || !ar.getSubgoals()[0].isDecidedUnsat()) throw new TestFailedException(); - Goal g3 = ctx.MkGoal(true, true, false); - Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort()); - Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort()); - g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort()))); - g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort()))); - BoolExpr constr = ctx.MkEq(xc, yc); - g3.Assert(constr); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); - if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedUnsat()) + Goal g3 = ctx.mkGoal(true, true, false); + Expr xc = ctx.mkConst(ctx.mkSymbol("x"), ctx.getIntSort()); + Expr yc = ctx.mkConst(ctx.mkSymbol("y"), ctx.getIntSort()); + g3.assert_(ctx.mkEq(xc, ctx.mkNumeral(1, ctx.getIntSort()))); + g3.assert_(ctx.mkEq(yc, ctx.mkNumeral(2, ctx.getIntSort()))); + BoolExpr constr = ctx.mkEq(xc, yc); + g3.assert_(constr); + ar = applyTactic(ctx, ctx.mkTactic("smt"), g3); + if (ar.getNumSubgoals() != 1 || !ar.getSubgoals()[0].isDecidedUnsat()) throw new TestFailedException(); - ModelConverterTest(ctx); + modelConverterTest(ctx); // Real num/den test. - RatNum rn = ctx.MkReal(42, 43); - Expr inum = rn.Numerator(); - Expr iden = rn.Denominator(); + RatNum rn = ctx.mkReal(42, 43); + Expr inum = rn.getNumerator(); + Expr iden = rn.getDenominator(); System.out.println("Numerator: " + inum + " Denominator: " + iden); if (!inum.toString().equals("42") || !iden.toString().equals("43")) throw new TestFailedException(); - if (!rn.ToDecimalString(3).toString().equals("0.976?")) + if (!rn.toDecimalString(3).toString().equals("0.976?")) throw new TestFailedException(); - BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); - BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); - BigIntCheck(ctx, ctx.MkReal("-234234333")); - BigIntCheck(ctx, ctx.MkReal("234234333/2")); + bigIntCheck(ctx, ctx.mkReal("-1231231232/234234333")); + bigIntCheck(ctx, ctx.mkReal("-123123234234234234231232/234234333")); + bigIntCheck(ctx, ctx.mkReal("-234234333")); + bigIntCheck(ctx, ctx.mkReal("234234333/2")); String bn = "1234567890987654321"; - if (!ctx.MkInt(bn).BigInteger().toString().equals(bn)) + if (!ctx.mkInt(bn).getBigInteger().toString().equals(bn)) throw new TestFailedException(); - if (!ctx.MkBV(bn, 128).BigInteger().toString().equals(bn)) + if (!ctx.mkBV(bn, 128).getBigInteger().toString().equals(bn)) throw new TestFailedException(); - if (ctx.MkBV(bn, 32).BigInteger().toString().equals(bn)) + if (ctx.mkBV(bn, 32).getBigInteger().toString().equals(bn)) throw new TestFailedException(); // Error handling test. try { - IntExpr i = ctx.MkInt("1/2"); + @SuppressWarnings("unused") + IntExpr i = ctx.mkInt("1/2"); throw new TestFailedException(); // unreachable } catch (Z3Exception e) { @@ -916,17 +890,19 @@ class JavaExample // / Some basic expression casting tests. - void CastingTest(Context ctx) throws Z3Exception, TestFailedException + void castingTest(Context ctx) throws Z3Exception, TestFailedException { System.out.println("CastingTest"); - Sort[] domain = { ctx.BoolSort(), ctx.BoolSort() }; - FuncDecl f = ctx.MkFuncDecl("f", domain, ctx.BoolSort()); + Sort[] domain = { ctx.getBoolSort(), ctx.getBoolSort() }; + FuncDecl f = ctx.mkFuncDecl("f", domain, ctx.getBoolSort()); - AST upcast = ctx.MkFuncDecl(ctx.MkSymbol("q"), domain, ctx.BoolSort()); + AST upcast = ctx.mkFuncDecl(ctx.mkSymbol("q"), domain, + ctx.getBoolSort()); try { + @SuppressWarnings("unused") FuncDecl downcast = (FuncDecl) f; // OK } catch (ClassCastException e) { @@ -935,31 +911,34 @@ class JavaExample try { + @SuppressWarnings("unused") Expr uc = (Expr) upcast; throw new TestFailedException(); // should not be reachable! } catch (ClassCastException e) { } - Symbol s = ctx.MkSymbol(42); + Symbol s = ctx.mkSymbol(42); IntSymbol si = (s.getClass() == IntSymbol.class) ? (IntSymbol) s : null; if (si == null) throw new TestFailedException(); try { + @SuppressWarnings("unused") IntSymbol si2 = (IntSymbol) s; } catch (ClassCastException e) { throw new TestFailedException(); } - s = ctx.MkSymbol("abc"); + s = ctx.mkSymbol("abc"); StringSymbol ss = (s.getClass() == StringSymbol.class) ? (StringSymbol) s : null; if (ss == null) throw new TestFailedException(); try { + @SuppressWarnings("unused") StringSymbol ss2 = (StringSymbol) s; } catch (ClassCastException e) { @@ -967,13 +946,14 @@ class JavaExample } try { + @SuppressWarnings("unused") IntSymbol si2 = (IntSymbol) s; throw new TestFailedException(); // unreachable } catch (Exception e) { } - Sort srt = ctx.MkBitVecSort(32); + Sort srt = ctx.mkBitVecSort(32); BitVecSort bvs = null; try { @@ -983,23 +963,24 @@ class JavaExample throw new TestFailedException(); } - if (bvs.Size() != 32) + if (bvs.getSize() != 32) throw new TestFailedException(); - Expr q = ctx.MkAdd(new ArithExpr[] { ctx.MkInt(1), ctx.MkInt(2) }); - Expr q2 = q.Args()[1]; - Sort qs = q2.Sort(); + Expr q = ctx.mkAdd(ctx.mkInt(1), ctx.mkInt(2)); + Expr q2 = q.getArgs()[1]; + Sort qs = q2.getSort(); if (qs.getClass() != IntSort.class) throw new TestFailedException(); try { + @SuppressWarnings("unused") IntSort isrt = (IntSort) qs; } catch (ClassCastException e) { throw new TestFailedException(); } - AST a = ctx.MkInt(42); + AST a = ctx.mkInt(42); try { @@ -1036,16 +1017,17 @@ class JavaExample Expr[][] earr = new Expr[2][]; earr[0] = new Expr[2]; earr[1] = new Expr[2]; - earr[0][0] = ctx.MkTrue(); - earr[0][1] = ctx.MkTrue(); - earr[1][0] = ctx.MkFalse(); - earr[1][1] = ctx.MkFalse(); + earr[0][0] = ctx.mkTrue(); + earr[0][1] = ctx.mkTrue(); + earr[1][0] = ctx.mkFalse(); + earr[1][1] = ctx.mkFalse(); for (Expr[] ea : earr) for (Expr e : ea) { try { - Expr ns = ctx.MkNot((BoolExpr) e); + Expr ns = ctx.mkNot((BoolExpr) e); + @SuppressWarnings("unused") BoolExpr ens = (BoolExpr) ns; } catch (ClassCastException ex) { @@ -1056,23 +1038,23 @@ class JavaExample // / Shows how to read an SMT1 file. - void SMT1FileTest(String filename) throws Z3Exception + void smt1FileTest(String filename) throws Z3Exception { System.out.print("SMT File test "); { HashMap cfg = new HashMap(); Context ctx = new Context(cfg); - ctx.ParseSMTLIBFile(filename, null, null, null, null); + ctx.parseSMTLIBFile(filename, null, null, null, null); - BoolExpr a = ctx.MkAnd(ctx.SMTLIBFormulas()); + BoolExpr a = ctx.mkAnd(ctx.getSMTLIBFormulas()); System.out.println("read formula: " + a); } } // / Shows how to read an SMT2 file. - void SMT2FileTest(String filename) throws Z3Exception + void smt2FileTest(String filename) throws Z3Exception { Date before = new Date(); @@ -1083,7 +1065,7 @@ class JavaExample HashMap cfg = new HashMap(); cfg.put("model", "true"); Context ctx = new Context(cfg); - Expr a = ctx.ParseSMTLIB2File(filename, null, null, null, null); + Expr a = ctx.parseSMTLIB2File(filename, null, null, null, null); long t_diff = ((new Date()).getTime() - before.getTime()) / 1000; @@ -1100,8 +1082,8 @@ class JavaExample cnt++; if (cur.getClass() == Expr.class) - if (!(cur.IsVar())) - for (Expr c : ((Expr) cur).Args()) + if (!(cur.isVar())) + for (Expr c : ((Expr) cur).getArgs()) q.add(c); } System.out.println(cnt + " ASTs"); @@ -1114,120 +1096,120 @@ class JavaExample // / Shows how to use Solver(logic) // / - void LogicExample(Context ctx) throws Z3Exception, TestFailedException + void logicExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("LogicTest"); - Log.Append("LogicTest"); + Log.append("LogicTest"); Context.ToggleWarningMessages(true); - BitVecSort bvs = ctx.MkBitVecSort(32); - Expr x = ctx.MkConst("x", bvs); - Expr y = ctx.MkConst("y", bvs); - BoolExpr eq = ctx.MkEq(x, y); + BitVecSort bvs = ctx.mkBitVecSort(32); + Expr x = ctx.mkConst("x", bvs); + Expr y = ctx.mkConst("y", bvs); + BoolExpr eq = ctx.mkEq(x, y); // Use a solver for QF_BV - Solver s = ctx.MkSolver("QF_BV"); - s.Assert(eq); - Status res = s.Check(); + Solver s = ctx.mkSolver("QF_BV"); + s.assert_(eq); + Status res = s.check(); System.out.println("solver result: " + res); // Or perhaps a tactic for QF_BV - Goal g = ctx.MkGoal(true, false, false); - g.Assert(eq); + Goal g = ctx.mkGoal(true, false, false); + g.assert_(eq); - Tactic t = ctx.MkTactic("qfbv"); - ApplyResult ar = t.Apply(g); + Tactic t = ctx.mkTactic("qfbv"); + ApplyResult ar = t.apply(g); System.out.println("tactic result: " + ar); - if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + if (ar.getNumSubgoals() != 1 || !ar.getSubgoals()[0].isDecidedSat()) throw new TestFailedException(); } // / Demonstrates how to use the ParOr tactic. - void ParOrExample(Context ctx) throws Z3Exception, TestFailedException + void parOrExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ParOrExample"); - Log.Append("ParOrExample"); + Log.append("ParOrExample"); - BitVecSort bvs = ctx.MkBitVecSort(32); - Expr x = ctx.MkConst("x", bvs); - Expr y = ctx.MkConst("y", bvs); - BoolExpr q = ctx.MkEq(x, y); + BitVecSort bvs = ctx.mkBitVecSort(32); + Expr x = ctx.mkConst("x", bvs); + Expr y = ctx.mkConst("y", bvs); + BoolExpr q = ctx.mkEq(x, y); - Goal g = ctx.MkGoal(true, false, false); - g.Assert(q); + Goal g = ctx.mkGoal(true, false, false); + g.assert_(q); - Tactic t1 = ctx.MkTactic("qfbv"); - Tactic t2 = ctx.MkTactic("qfbv"); - Tactic p = ctx.ParOr(new Tactic[] { t1, t2 }); + Tactic t1 = ctx.mkTactic("qfbv"); + Tactic t2 = ctx.mkTactic("qfbv"); + Tactic p = ctx.parOr(t1, t2); - ApplyResult ar = p.Apply(g); + ApplyResult ar = p.apply(g); - if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + if (ar.getNumSubgoals() != 1 || !ar.getSubgoals()[0].isDecidedSat()) throw new TestFailedException(); } - void BigIntCheck(Context ctx, RatNum r) throws Z3Exception + void bigIntCheck(Context ctx, RatNum r) throws Z3Exception { - System.out.println("Num: " + r.BigIntNumerator()); - System.out.println("Den: " + r.BigIntDenominator()); + System.out.println("Num: " + r.getBigIntNumerator()); + System.out.println("Den: " + r.getBigIntDenominator()); } // / Find a model for x xor y. - public void FindModelExample1(Context ctx) throws Z3Exception, + public void findModelExample1(Context ctx) throws Z3Exception, TestFailedException { System.out.println("FindModelExample1"); - Log.Append("FindModelExample1"); + Log.append("FindModelExample1"); - BoolExpr x = ctx.MkBoolConst("x"); - BoolExpr y = ctx.MkBoolConst("y"); - BoolExpr x_xor_y = ctx.MkXor(x, y); + BoolExpr x = ctx.mkBoolConst("x"); + BoolExpr y = ctx.mkBoolConst("y"); + BoolExpr x_xor_y = ctx.mkXor(x, y); - Model model = Check(ctx, x_xor_y, Status.SATISFIABLE); - System.out.println("x = " + model.Evaluate(x, false) + ", y = " - + model.Evaluate(y, false)); + Model model = check(ctx, x_xor_y, Status.SATISFIABLE); + System.out.println("x = " + model.evaluate(x, false) + ", y = " + + model.evaluate(y, false)); } // / Find a model for x < y + 1, x > 2. // / Then, assert not(x = y), and find another model. - public void FindModelExample2(Context ctx) throws Z3Exception, + public void findModelExample2(Context ctx) throws Z3Exception, TestFailedException { System.out.println("FindModelExample2"); - Log.Append("FindModelExample2"); + Log.append("FindModelExample2"); - IntExpr x = ctx.MkIntConst("x"); - IntExpr y = ctx.MkIntConst("y"); - IntExpr one = ctx.MkInt(1); - IntExpr two = ctx.MkInt(2); + IntExpr x = ctx.mkIntConst("x"); + IntExpr y = ctx.mkIntConst("y"); + IntExpr one = ctx.mkInt(1); + IntExpr two = ctx.mkInt(2); - ArithExpr y_plus_one = ctx.MkAdd(new ArithExpr[] { y, one }); + ArithExpr y_plus_one = ctx.mkAdd(y, one); - BoolExpr c1 = ctx.MkLt(x, y_plus_one); - BoolExpr c2 = ctx.MkGt(x, two); + BoolExpr c1 = ctx.mkLt(x, y_plus_one); + BoolExpr c2 = ctx.mkGt(x, two); - BoolExpr q = ctx.MkAnd(new BoolExpr[] { c1, c2 }); + BoolExpr q = ctx.mkAnd(c1, c2); System.out.println("model for: x < y + 1, x > 2"); - Model model = Check(ctx, q, Status.SATISFIABLE); - System.out.println("x = " + model.Evaluate(x, false) + ", y =" - + model.Evaluate(y, false)); + Model model = check(ctx, q, Status.SATISFIABLE); + System.out.println("x = " + model.evaluate(x, false) + ", y =" + + model.evaluate(y, false)); /* assert not(x = y) */ - BoolExpr x_eq_y = ctx.MkEq(x, y); - BoolExpr c3 = ctx.MkNot(x_eq_y); + BoolExpr x_eq_y = ctx.mkEq(x, y); + BoolExpr c3 = ctx.mkNot(x_eq_y); - q = ctx.MkAnd(new BoolExpr[] { q, c3 }); + q = ctx.mkAnd(q, c3); System.out.println("model for: x < y + 1, x > 2, not(x = y)"); - model = Check(ctx, q, Status.SATISFIABLE); - System.out.println("x = " + model.Evaluate(x, false) + ", y = " - + model.Evaluate(y, false)); + model = check(ctx, q, Status.SATISFIABLE); + System.out.println("x = " + model.evaluate(x, false) + ", y = " + + model.evaluate(y, false)); } // / Prove x = y implies g(x) = g(y), and @@ -1235,43 +1217,43 @@ class JavaExample // / This function demonstrates how to create uninterpreted // / types and functions. - public void ProveExample1(Context ctx) throws Z3Exception, + public void proveExample1(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ProveExample1"); - Log.Append("ProveExample1"); + Log.append("ProveExample1"); /* create uninterpreted type. */ - Sort U = ctx.MkUninterpretedSort(ctx.MkSymbol("U")); + Sort U = ctx.mkUninterpretedSort(ctx.mkSymbol("U")); /* declare function g */ - FuncDecl g = ctx.MkFuncDecl("g", U, U); + FuncDecl g = ctx.mkFuncDecl("g", U, U); /* create x and y */ - Expr x = ctx.MkConst("x", U); - Expr y = ctx.MkConst("y", U); + Expr x = ctx.mkConst("x", U); + Expr y = ctx.mkConst("y", U); /* create g(x), g(y) */ - Expr gx = g.Apply(x); - Expr gy = g.Apply(y); + Expr gx = g.apply(x); + Expr gy = g.apply(y); /* assert x = y */ - BoolExpr eq = ctx.MkEq(x, y); + BoolExpr eq = ctx.mkEq(x, y); /* prove g(x) = g(y) */ - BoolExpr f = ctx.MkEq(gx, gy); + BoolExpr f = ctx.mkEq(gx, gy); System.out.println("prove: x = y implies g(x) = g(y)"); - Prove(ctx, ctx.MkImplies(eq, f), false); + prove(ctx, ctx.mkImplies(eq, f), false); /* create g(g(x)) */ - Expr ggx = g.Apply(gx); + Expr ggx = g.apply(gx); /* disprove g(g(x)) = g(y) */ - f = ctx.MkEq(ggx, gy); + f = ctx.mkEq(ggx, gy); System.out.println("disprove: x = y implies g(g(x)) = g(y)"); - Disprove(ctx, ctx.MkImplies(eq, f), false); + disprove(ctx, ctx.mkImplies(eq, f), false); /* Print the model using the custom model printer */ - Model m = Check(ctx, ctx.MkNot(f), Status.SATISFIABLE); + Model m = check(ctx, ctx.mkNot(f), Status.SATISFIABLE); System.out.println(m); } @@ -1282,97 +1264,96 @@ class JavaExample // / This example demonstrates how to combine uninterpreted // functions // / and arithmetic. - public void ProveExample2(Context ctx) throws Z3Exception, + public void proveExample2(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ProveExample2"); - Log.Append("ProveExample2"); + Log.append("ProveExample2"); /* declare function g */ - Sort I = ctx.IntSort(); + Sort I = ctx.getIntSort(); - FuncDecl g = ctx.MkFuncDecl("g", I, I); + FuncDecl g = ctx.mkFuncDecl("g", I, I); /* create x, y, and z */ - IntExpr x = ctx.MkIntConst("x"); - IntExpr y = ctx.MkIntConst("y"); - IntExpr z = ctx.MkIntConst("z"); + IntExpr x = ctx.mkIntConst("x"); + IntExpr y = ctx.mkIntConst("y"); + IntExpr z = ctx.mkIntConst("z"); /* create gx, gy, gz */ - Expr gx = ctx.MkApp(g, x); - Expr gy = ctx.MkApp(g, y); - Expr gz = ctx.MkApp(g, z); + Expr gx = ctx.mkApp(g, x); + Expr gy = ctx.mkApp(g, y); + Expr gz = ctx.mkApp(g, z); /* create zero */ - IntExpr zero = ctx.MkInt(0); + IntExpr zero = ctx.mkInt(0); /* assert not(g(g(x) - g(y)) = g(z)) */ - ArithExpr gx_gy = ctx.MkSub(new ArithExpr[] { (IntExpr) gx, - (IntExpr) gy }); - Expr ggx_gy = ctx.MkApp(g, gx_gy); - BoolExpr eq = ctx.MkEq(ggx_gy, gz); - BoolExpr c1 = ctx.MkNot(eq); + ArithExpr gx_gy = ctx.mkSub((IntExpr) gx, (IntExpr) gy); + Expr ggx_gy = ctx.mkApp(g, gx_gy); + BoolExpr eq = ctx.mkEq(ggx_gy, gz); + BoolExpr c1 = ctx.mkNot(eq); /* assert x + z <= y */ - ArithExpr x_plus_z = ctx.MkAdd(new ArithExpr[] { x, z }); - BoolExpr c2 = ctx.MkLe(x_plus_z, y); + ArithExpr x_plus_z = ctx.mkAdd(x, z); + BoolExpr c2 = ctx.mkLe(x_plus_z, y); /* assert y <= x */ - BoolExpr c3 = ctx.MkLe(y, x); + BoolExpr c3 = ctx.mkLe(y, x); /* prove z < 0 */ - BoolExpr f = ctx.MkLt(z, zero); + BoolExpr f = ctx.mkLt(z, zero); System.out .println("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0"); - Prove(ctx, f, false, new BoolExpr[] { c1, c2, c3 }); + prove(ctx, f, false, c1, c2, c3); /* disprove z < -1 */ - IntExpr minus_one = ctx.MkInt(-1); - f = ctx.MkLt(z, minus_one); + IntExpr minus_one = ctx.mkInt(-1); + f = ctx.mkLt(z, minus_one); System.out .println("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1"); - Disprove(ctx, f, false, new BoolExpr[] { c1, c2, c3 }); + disprove(ctx, f, false, c1, c2, c3); } // / Show how push & pop can be used to create "backtracking" points. // / This example also demonstrates how big numbers can be // / created in ctx. - public void PushPopExample1(Context ctx) throws Z3Exception, + public void pushPopExample1(Context ctx) throws Z3Exception, TestFailedException { System.out.println("PushPopExample1"); - Log.Append("PushPopExample1"); + Log.append("PushPopExample1"); /* create a big number */ - IntSort int_type = ctx.IntSort(); + IntSort int_type = ctx.getIntSort(); IntExpr big_number = ctx - .MkInt("1000000000000000000000000000000000000000000000000000000"); + .mkInt("1000000000000000000000000000000000000000000000000000000"); /* create number 3 */ - IntExpr three = (IntExpr) ctx.MkNumeral("3", int_type); + IntExpr three = (IntExpr) ctx.mkNumeral("3", int_type); /* create x */ - IntExpr x = ctx.MkIntConst("x"); + IntExpr x = ctx.mkIntConst("x"); - Solver solver = ctx.MkSolver(); + Solver solver = ctx.mkSolver(); /* assert x >= "big number" */ - BoolExpr c1 = ctx.MkGe(x, big_number); + BoolExpr c1 = ctx.mkGe(x, big_number); System.out.println("assert: x >= 'big number'"); - solver.Assert(c1); + solver.assert_(c1); /* create a backtracking point */ System.out.println("push"); - solver.Push(); + solver.push(); /* assert x <= 3 */ - BoolExpr c2 = ctx.MkLe(x, three); + BoolExpr c2 = ctx.mkLe(x, three); System.out.println("assert: x <= 3"); - solver.Assert(c2); + solver.assert_(c2); /* context is inconsistent at this point */ - if (solver.Check() != Status.UNSATISFIABLE) + if (solver.check() != Status.UNSATISFIABLE) throw new TestFailedException(); /* @@ -1380,24 +1361,24 @@ class JavaExample * asserted after the last ctx.Push. */ System.out.println("pop"); - solver.Pop(1); + solver.pop(1); /* the context is consistent again. */ - if (solver.Check() != Status.SATISFIABLE) + if (solver.check() != Status.SATISFIABLE) throw new TestFailedException(); /* new constraints can be asserted... */ /* create y */ - IntExpr y = ctx.MkIntConst("y"); + IntExpr y = ctx.mkIntConst("y"); /* assert y > x */ - BoolExpr c3 = ctx.MkGt(y, x); + BoolExpr c3 = ctx.mkGt(y, x); System.out.println("assert: y > x"); - solver.Assert(c3); + solver.assert_(c3); /* the context is still consistent. */ - if (solver.Check() != Status.SATISFIABLE) + if (solver.check() != Status.SATISFIABLE) throw new TestFailedException(); } @@ -1405,33 +1386,34 @@ class JavaExample // / Check that the projection of a tuple // / returns the corresponding element. - public void TupleExample(Context ctx) throws Z3Exception, + public void tupleExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("TupleExample"); - Log.Append("TupleExample"); + Log.append("TupleExample"); - Sort int_type = ctx.IntSort(); - TupleSort tuple = ctx.MkTupleSort(ctx.MkSymbol("mk_tuple"), // name of + Sort int_type = ctx.getIntSort(); + TupleSort tuple = ctx.mkTupleSort(ctx.mkSymbol("mk_tuple"), // name of // tuple // constructor - new Symbol[] { ctx.MkSymbol("first"), ctx.MkSymbol("second") }, // names + new Symbol[] { ctx.mkSymbol("first"), ctx.mkSymbol("second") }, // names // of // projection // operators new Sort[] { int_type, int_type } // types of projection // operators ); - FuncDecl first = tuple.FieldDecls()[0]; // declarations are for - // projections - FuncDecl second = tuple.FieldDecls()[1]; - Expr x = ctx.MkConst("x", int_type); - Expr y = ctx.MkConst("y", int_type); - Expr n1 = tuple.MkDecl().Apply(new Expr[] { x, y }); - Expr n2 = first.Apply(n1); - BoolExpr n3 = ctx.MkEq(x, n2); + FuncDecl first = tuple.getFieldDecls()[0]; // declarations are for + // projections + @SuppressWarnings("unused") + FuncDecl second = tuple.getFieldDecls()[1]; + Expr x = ctx.mkConst("x", int_type); + Expr y = ctx.mkConst("y", int_type); + Expr n1 = tuple.mkDecl().apply(x, y); + Expr n2 = first.apply(n1); + BoolExpr n3 = ctx.mkEq(x, n2); System.out.println("Tuple example: " + n3); - Prove(ctx, n3, false); + prove(ctx, n3, false); } // / Simple bit-vector example. @@ -1440,132 +1422,133 @@ class JavaExample // / This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) // machine integers // / - public void BitvectorExample1(Context ctx) throws Z3Exception, + public void bitvectorExample1(Context ctx) throws Z3Exception, TestFailedException { System.out.println("BitvectorExample1"); - Log.Append("BitvectorExample1"); + Log.append("BitvectorExample1"); - Sort bv_type = ctx.MkBitVecSort(32); - BitVecExpr x = (BitVecExpr) ctx.MkConst("x", bv_type); - BitVecNum zero = (BitVecNum) ctx.MkNumeral("0", bv_type); - BitVecNum ten = ctx.MkBV(10, 32); - BitVecExpr x_minus_ten = ctx.MkBVSub(x, ten); + Sort bv_type = ctx.mkBitVecSort(32); + BitVecExpr x = (BitVecExpr) ctx.mkConst("x", bv_type); + BitVecNum zero = (BitVecNum) ctx.mkNumeral("0", bv_type); + BitVecNum ten = ctx.mkBV(10, 32); + BitVecExpr x_minus_ten = ctx.mkBVSub(x, ten); /* bvsle is signed less than or equal to */ - BoolExpr c1 = ctx.MkBVSLE(x, ten); - BoolExpr c2 = ctx.MkBVSLE(x_minus_ten, zero); - BoolExpr thm = ctx.MkIff(c1, c2); + BoolExpr c1 = ctx.mkBVSLE(x, ten); + BoolExpr c2 = ctx.mkBVSLE(x_minus_ten, zero); + BoolExpr thm = ctx.mkIff(c1, c2); System.out .println("disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers"); - Disprove(ctx, thm, false); + disprove(ctx, thm, false); } // / Find x and y such that: x ^ y - 103 == x * y - public void BitvectorExample2(Context ctx) throws Z3Exception, + public void bitvectorExample2(Context ctx) throws Z3Exception, TestFailedException { System.out.println("BitvectorExample2"); - Log.Append("BitvectorExample2"); + Log.append("BitvectorExample2"); /* construct x ^ y - 103 == x * y */ - Sort bv_type = ctx.MkBitVecSort(32); - BitVecExpr x = ctx.MkBVConst("x", 32); - BitVecExpr y = ctx.MkBVConst("y", 32); - BitVecExpr x_xor_y = ctx.MkBVXOR(x, y); - BitVecExpr c103 = (BitVecNum) ctx.MkNumeral("103", bv_type); - BitVecExpr lhs = ctx.MkBVSub(x_xor_y, c103); - BitVecExpr rhs = ctx.MkBVMul(x, y); - BoolExpr ctr = ctx.MkEq(lhs, rhs); + Sort bv_type = ctx.mkBitVecSort(32); + BitVecExpr x = ctx.mkBVConst("x", 32); + BitVecExpr y = ctx.mkBVConst("y", 32); + BitVecExpr x_xor_y = ctx.mkBVXOR(x, y); + BitVecExpr c103 = (BitVecNum) ctx.mkNumeral("103", bv_type); + BitVecExpr lhs = ctx.mkBVSub(x_xor_y, c103); + BitVecExpr rhs = ctx.mkBVMul(x, y); + BoolExpr ctr = ctx.mkEq(lhs, rhs); System.out .println("find values of x and y, such that x ^ y - 103 == x * y"); /* find a model (i.e., values for x an y that satisfy the constraint */ - Model m = Check(ctx, ctr, Status.SATISFIABLE); + Model m = check(ctx, ctr, Status.SATISFIABLE); System.out.println(m); } // / Demonstrates how to use the SMTLIB parser. - public void ParserExample1(Context ctx) throws Z3Exception, + public void parserExample1(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ParserExample1"); - Log.Append("ParserExample1"); + Log.append("ParserExample1"); - ctx.ParseSMTLIBString( + ctx.parseSMTLIBString( "(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))", null, null, null, null); - for (BoolExpr f : ctx.SMTLIBFormulas()) + for (BoolExpr f : ctx.getSMTLIBFormulas()) System.out.println("formula " + f); - Model m = Check(ctx, ctx.MkAnd(ctx.SMTLIBFormulas()), + @SuppressWarnings("unused") + Model m = check(ctx, ctx.mkAnd(ctx.getSMTLIBFormulas()), Status.SATISFIABLE); } // / Demonstrates how to initialize the parser symbol table. - public void ParserExample2(Context ctx) throws Z3Exception, + public void parserExample2(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ParserExample2"); - Log.Append("ParserExample2"); + Log.append("ParserExample2"); - Symbol[] declNames = { ctx.MkSymbol("a"), ctx.MkSymbol("b") }; - FuncDecl a = ctx.MkConstDecl(declNames[0], ctx.MkIntSort()); - FuncDecl b = ctx.MkConstDecl(declNames[1], ctx.MkIntSort()); + Symbol[] declNames = { ctx.mkSymbol("a"), ctx.mkSymbol("b") }; + FuncDecl a = ctx.mkConstDecl(declNames[0], ctx.mkIntSort()); + FuncDecl b = ctx.mkConstDecl(declNames[1], ctx.mkIntSort()); FuncDecl[] decls = new FuncDecl[] { a, b }; - ctx.ParseSMTLIBString("(benchmark tst :formula (> a b))", null, null, + ctx.parseSMTLIBString("(benchmark tst :formula (> a b))", null, null, declNames, decls); - BoolExpr f = ctx.SMTLIBFormulas()[0]; + BoolExpr f = ctx.getSMTLIBFormulas()[0]; System.out.println("formula: " + f); - Check(ctx, f, Status.SATISFIABLE); + check(ctx, f, Status.SATISFIABLE); } // / Demonstrates how to initialize the parser symbol table. - public void ParserExample3(Context ctx) throws Exception + public void parserExample3(Context ctx) throws Exception { System.out.println("ParserExample3"); - Log.Append("ParserExample3"); + Log.append("ParserExample3"); /* declare function g */ - Sort I = ctx.MkIntSort(); - FuncDecl g = ctx.MkFuncDecl("g", new Sort[] { I, I }, I); + Sort I = ctx.mkIntSort(); + FuncDecl g = ctx.mkFuncDecl("g", new Sort[] { I, I }, I); - BoolExpr ca = CommAxiom(ctx, g); + BoolExpr ca = commAxiom(ctx, g); - ctx.ParseSMTLIBString( + ctx.parseSMTLIBString( "(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (gg x 0) (gg 0 y)))))", - null, null, new Symbol[] { ctx.MkSymbol("gg") }, + null, null, new Symbol[] { ctx.mkSymbol("gg") }, new FuncDecl[] { g }); - BoolExpr thm = ctx.SMTLIBFormulas()[0]; + BoolExpr thm = ctx.getSMTLIBFormulas()[0]; System.out.println("formula: " + thm); - Prove(ctx, thm, false, ca); + prove(ctx, thm, false, ca); } // / Display the declarations, assumptions and formulas in a SMT-LIB string. - public void ParserExample4(Context ctx) throws Z3Exception + public void parserExample4(Context ctx) throws Z3Exception { System.out.println("ParserExample4"); - Log.Append("ParserExample4"); + Log.append("ParserExample4"); - ctx.ParseSMTLIBString( + ctx.parseSMTLIBString( "(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))", null, null, null, null); - for (FuncDecl decl : ctx.SMTLIBDecls()) + for (FuncDecl decl : ctx.getSMTLIBDecls()) { System.out.println("Declaration: " + decl); } - for (BoolExpr f : ctx.SMTLIBAssumptions()) + for (BoolExpr f : ctx.getSMTLIBAssumptions()) { System.out.println("Assumption: " + f); } - for (BoolExpr f : ctx.SMTLIBFormulas()) + for (BoolExpr f : ctx.getSMTLIBFormulas()) { System.out.println("Formula: " + f); } @@ -1575,13 +1558,13 @@ class JavaExample // support. // / - public void ParserExample5(Context ctx) + public void parserExample5(Context ctx) { System.out.println("ParserExample5"); try { - ctx.ParseSMTLIBString( + ctx.parseSMTLIBString( /* * the following string has a parsing error: missing * parenthesis @@ -1596,141 +1579,138 @@ class JavaExample // / Create an ite-Expr (if-then-else Exprs). - public void ITEExample(Context ctx) throws Z3Exception + public void iteExample(Context ctx) throws Z3Exception { System.out.println("ITEExample"); - Log.Append("ITEExample"); + Log.append("ITEExample"); - BoolExpr f = ctx.MkFalse(); - Expr one = ctx.MkInt(1); - Expr zero = ctx.MkInt(0); - Expr ite = ctx.MkITE(f, one, zero); + BoolExpr f = ctx.mkFalse(); + Expr one = ctx.mkInt(1); + Expr zero = ctx.mkInt(0); + Expr ite = ctx.mkITE(f, one, zero); System.out.println("Expr: " + ite); } // / Create an enumeration data type. - public void EnumExample(Context ctx) throws Z3Exception, + public void enumExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("EnumExample"); - Log.Append("EnumExample"); + Log.append("EnumExample"); - Symbol name = ctx.MkSymbol("fruit"); + Symbol name = ctx.mkSymbol("fruit"); - EnumSort fruit = ctx.MkEnumSort(name, - new Symbol[] { ctx.MkSymbol("apple"), ctx.MkSymbol("banana"), - ctx.MkSymbol("orange") }); + EnumSort fruit = ctx.mkEnumSort(name, ctx.mkSymbol("apple"), + ctx.mkSymbol("banana"), ctx.mkSymbol("orange")); - System.out.println((fruit.Consts()[0])); - System.out.println((fruit.Consts()[1])); - System.out.println((fruit.Consts()[2])); + System.out.println((fruit.getConsts()[0])); + System.out.println((fruit.getConsts()[1])); + System.out.println((fruit.getConsts()[2])); - System.out.println((fruit.TesterDecls()[0])); - System.out.println((fruit.TesterDecls()[1])); - System.out.println((fruit.TesterDecls()[2])); + System.out.println((fruit.getTesterDecls()[0])); + System.out.println((fruit.getTesterDecls()[1])); + System.out.println((fruit.getTesterDecls()[2])); - Expr apple = fruit.Consts()[0]; - Expr banana = fruit.Consts()[1]; - Expr orange = fruit.Consts()[2]; + Expr apple = fruit.getConsts()[0]; + Expr banana = fruit.getConsts()[1]; + Expr orange = fruit.getConsts()[2]; /* Apples are different from oranges */ - Prove(ctx, ctx.MkNot(ctx.MkEq(apple, orange)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(apple, orange)), false); /* Apples pass the apple test */ - Prove(ctx, (BoolExpr) ctx.MkApp(fruit.TesterDecls()[0], apple), false); + prove(ctx, (BoolExpr) ctx.mkApp(fruit.getTesterDecls()[0], apple), + false); /* Oranges fail the apple test */ - Disprove(ctx, (BoolExpr) ctx.MkApp(fruit.TesterDecls()[0], orange), + disprove(ctx, (BoolExpr) ctx.mkApp(fruit.getTesterDecls()[0], orange), false); - Prove(ctx, (BoolExpr) ctx.MkNot((BoolExpr) ctx.MkApp( - fruit.TesterDecls()[0], orange)), false); + prove(ctx, + (BoolExpr) ctx.mkNot((BoolExpr) ctx.mkApp( + fruit.getTesterDecls()[0], orange)), false); - Expr fruity = ctx.MkConst("fruity", fruit); + Expr fruity = ctx.mkConst("fruity", fruit); /* If something is fruity, then it is an apple, banana, or orange */ - Prove(ctx, - ctx.MkOr(new BoolExpr[] { ctx.MkEq(fruity, apple), - ctx.MkEq(fruity, banana), ctx.MkEq(fruity, orange) }), - false); + prove(ctx, + ctx.mkOr(ctx.mkEq(fruity, apple), ctx.mkEq(fruity, banana), + ctx.mkEq(fruity, orange)), false); } // / Create a list datatype. - public void ListExample(Context ctx) throws Z3Exception, + public void listExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ListExample"); - Log.Append("ListExample"); + Log.append("ListExample"); Sort int_ty; ListSort int_list; Expr nil, l1, l2, x, y, u, v; BoolExpr fml, fml1; - int_ty = ctx.MkIntSort(); + int_ty = ctx.mkIntSort(); - int_list = ctx.MkListSort(ctx.MkSymbol("int_list"), int_ty); + int_list = ctx.mkListSort(ctx.mkSymbol("int_list"), int_ty); - nil = ctx.MkConst(int_list.NilDecl()); - l1 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { ctx.MkInt(1), nil }); - l2 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { ctx.MkInt(2), nil }); + nil = ctx.mkConst(int_list.getNilDecl()); + l1 = ctx.mkApp(int_list.getConsDecl(), ctx.mkInt(1), nil); + l2 = ctx.mkApp(int_list.getConsDecl(), ctx.mkInt(2), nil); /* nil != cons(1, nil) */ - Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(nil, l1)), false); /* cons(2,nil) != cons(1, nil) */ - Prove(ctx, ctx.MkNot(ctx.MkEq(l1, l2)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(l1, l2)), false); /* cons(x,nil) = cons(y, nil) => x = y */ - x = ctx.MkConst("x", int_ty); - y = ctx.MkConst("y", int_ty); - l1 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { x, nil }); - l2 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { y, nil }); - Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + x = ctx.mkConst("x", int_ty); + y = ctx.mkConst("y", int_ty); + l1 = ctx.mkApp(int_list.getConsDecl(), x, nil); + l2 = ctx.mkApp(int_list.getConsDecl(), y, nil); + prove(ctx, ctx.mkImplies(ctx.mkEq(l1, l2), ctx.mkEq(x, y)), false); /* cons(x,u) = cons(x, v) => u = v */ - u = ctx.MkConst("u", int_list); - v = ctx.MkConst("v", int_list); - l1 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { x, u }); - l2 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { y, v }); - Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v)), false); - Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + u = ctx.mkConst("u", int_list); + v = ctx.mkConst("v", int_list); + l1 = ctx.mkApp(int_list.getConsDecl(), x, u); + l2 = ctx.mkApp(int_list.getConsDecl(), y, v); + prove(ctx, ctx.mkImplies(ctx.mkEq(l1, l2), ctx.mkEq(u, v)), false); + prove(ctx, ctx.mkImplies(ctx.mkEq(l1, l2), ctx.mkEq(x, y)), false); /* is_nil(u) or is_cons(u) */ - Prove(ctx, - ctx.MkOr(new BoolExpr[] { - (BoolExpr) ctx.MkApp(int_list.IsNilDecl(), - new Expr[] { u }), - (BoolExpr) ctx.MkApp(int_list.IsConsDecl(), - new Expr[] { u }) }), false); + prove(ctx, ctx.mkOr((BoolExpr) ctx.mkApp(int_list.getIsNilDecl(), u), + (BoolExpr) ctx.mkApp(int_list.getIsConsDecl(), u)), false); /* occurs check u != cons(x,u) */ - Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(u, l1)), false); /* destructors: is_cons(u) => u = cons(head(u),tail(u)) */ - fml1 = ctx.MkEq(u, ctx.MkApp(int_list.ConsDecl(), - new Expr[] { ctx.MkApp(int_list.HeadDecl(), new Expr[] { u }), - ctx.MkApp(int_list.TailDecl(), new Expr[] { u }) })); - fml = ctx.MkImplies( - (BoolExpr) ctx.MkApp(int_list.IsConsDecl(), new Expr[] { u }), + fml1 = ctx.mkEq( + u, + ctx.mkApp(int_list.getConsDecl(), + ctx.mkApp(int_list.getHeadDecl(), u), + ctx.mkApp(int_list.getTailDecl(), u))); + fml = ctx.mkImplies((BoolExpr) ctx.mkApp(int_list.getIsConsDecl(), u), fml1); System.out.println("Formula " + fml); - Prove(ctx, fml, false); + prove(ctx, fml, false); - Disprove(ctx, fml1, false); + disprove(ctx, fml1, false); } // / Create a binary tree datatype. - public void TreeExample(Context ctx) throws Z3Exception, + public void treeExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("TreeExample"); - Log.Append("TreeExample"); + Log.append("TreeExample"); Sort cell; FuncDecl nil_decl, is_nil_decl, cons_decl, is_cons_decl, car_decl, cdr_decl; @@ -1741,60 +1721,56 @@ class JavaExample int[] sort_refs = new int[] { 0, 0 }; Constructor nil_con, cons_con; - nil_con = ctx.MkConstructor("nil", "is_nil", null, null, null); - cons_con = ctx.MkConstructor("cons", "is_cons", head_tail, sorts, + nil_con = ctx.mkConstructor("nil", "is_nil", null, null, null); + cons_con = ctx.mkConstructor("cons", "is_cons", head_tail, sorts, sort_refs); Constructor[] constructors = new Constructor[] { nil_con, cons_con }; - cell = ctx.MkDatatypeSort("cell", constructors); + cell = ctx.mkDatatypeSort("cell", constructors); nil_decl = nil_con.ConstructorDecl(); - is_nil_decl = nil_con.TesterDecl(); + is_nil_decl = nil_con.getTesterDecl(); cons_decl = cons_con.ConstructorDecl(); - is_cons_decl = cons_con.TesterDecl(); - FuncDecl[] cons_accessors = cons_con.AccessorDecls(); + is_cons_decl = cons_con.getTesterDecl(); + FuncDecl[] cons_accessors = cons_con.getAccessorDecls(); car_decl = cons_accessors[0]; cdr_decl = cons_accessors[1]; - nil = ctx.MkConst(nil_decl); - l1 = ctx.MkApp(cons_decl, new Expr[] { nil, nil }); - l2 = ctx.MkApp(cons_decl, new Expr[] { l1, nil }); + nil = ctx.mkConst(nil_decl); + l1 = ctx.mkApp(cons_decl, nil, nil); + l2 = ctx.mkApp(cons_decl, l1, nil); /* nil != cons(nil, nil) */ - Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(nil, l1)), false); /* cons(x,u) = cons(x, v) => u = v */ - u = ctx.MkConst("u", cell); - v = ctx.MkConst("v", cell); - x = ctx.MkConst("x", cell); - y = ctx.MkConst("y", cell); - l1 = ctx.MkApp(cons_decl, new Expr[] { x, u }); - l2 = ctx.MkApp(cons_decl, new Expr[] { y, v }); - Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v)), false); - Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + u = ctx.mkConst("u", cell); + v = ctx.mkConst("v", cell); + x = ctx.mkConst("x", cell); + y = ctx.mkConst("y", cell); + l1 = ctx.mkApp(cons_decl, x, u); + l2 = ctx.mkApp(cons_decl, y, v); + prove(ctx, ctx.mkImplies(ctx.mkEq(l1, l2), ctx.mkEq(u, v)), false); + prove(ctx, ctx.mkImplies(ctx.mkEq(l1, l2), ctx.mkEq(x, y)), false); /* is_nil(u) or is_cons(u) */ - Prove(ctx, - ctx.MkOr(new BoolExpr[] { - (BoolExpr) ctx.MkApp(is_nil_decl, new Expr[] { u }), - (BoolExpr) ctx.MkApp(is_cons_decl, new Expr[] { u }) }), - false); + prove(ctx, + ctx.mkOr((BoolExpr) ctx.mkApp(is_nil_decl, u), + (BoolExpr) ctx.mkApp(is_cons_decl, u)), false); /* occurs check u != cons(x,u) */ - Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(u, l1)), false); /* destructors: is_cons(u) => u = cons(car(u),cdr(u)) */ - fml1 = ctx.MkEq( + fml1 = ctx.mkEq( u, - ctx.MkApp( - cons_decl, - new Expr[] { ctx.MkApp(car_decl, u), - ctx.MkApp(cdr_decl, u) })); - fml = ctx.MkImplies((BoolExpr) ctx.MkApp(is_cons_decl, u), fml1); + ctx.mkApp(cons_decl, ctx.mkApp(car_decl, u), + ctx.mkApp(cdr_decl, u))); + fml = ctx.mkImplies((BoolExpr) ctx.mkApp(is_cons_decl, u), fml1); System.out.println("Formula " + fml); - Prove(ctx, fml, false); + prove(ctx, fml, false); - Disprove(ctx, fml1, false); + disprove(ctx, fml1, false); } // / Create a forest of trees. @@ -1803,15 +1779,18 @@ class JavaExample // / forest ::= nil | cons(tree, forest) // / tree ::= nil | cons(forest, forest) // / - public void ForestExample(Context ctx) throws Z3Exception, + public void forestExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("ForestExample"); - Log.Append("ForestExample"); + Log.append("ForestExample"); Sort tree, forest; + @SuppressWarnings("unused") FuncDecl nil1_decl, is_nil1_decl, cons1_decl, is_cons1_decl, car1_decl, cdr1_decl; + @SuppressWarnings("unused") FuncDecl nil2_decl, is_nil2_decl, cons2_decl, is_cons2_decl, car2_decl, cdr2_decl; + @SuppressWarnings("unused") Expr nil1, nil2, t1, t2, t3, t4, f1, f2, f3, l1, l2, x, y, u, v; // @@ -1826,41 +1805,41 @@ class JavaExample // array // points to 'forest', which has index 0. // - Symbol[] head_tail1 = new Symbol[] { ctx.MkSymbol("head"), - ctx.MkSymbol("tail") }; + Symbol[] head_tail1 = new Symbol[] { ctx.mkSymbol("head"), + ctx.mkSymbol("tail") }; Sort[] sorts1 = new Sort[] { null, null }; int[] sort1_refs = new int[] { 1, 0 }; // the first item points to a // tree, the second to a forest - Symbol[] head_tail2 = new Symbol[] { ctx.MkSymbol("car"), - ctx.MkSymbol("cdr") }; + Symbol[] head_tail2 = new Symbol[] { ctx.mkSymbol("car"), + ctx.mkSymbol("cdr") }; Sort[] sorts2 = new Sort[] { null, null }; int[] sort2_refs = new int[] { 0, 0 }; // both items point to the forest // datatype. Constructor nil1_con, cons1_con, nil2_con, cons2_con; Constructor[] constructors1 = new Constructor[2], constructors2 = new Constructor[2]; - Symbol[] sort_names = { ctx.MkSymbol("forest"), ctx.MkSymbol("tree") }; + Symbol[] sort_names = { ctx.mkSymbol("forest"), ctx.mkSymbol("tree") }; /* build a forest */ - nil1_con = ctx.MkConstructor(ctx.MkSymbol("nil"), - ctx.MkSymbol("is_nil"), null, null, null); - cons1_con = ctx.MkConstructor(ctx.MkSymbol("cons1"), - ctx.MkSymbol("is_cons1"), head_tail1, sorts1, sort1_refs); + nil1_con = ctx.mkConstructor(ctx.mkSymbol("nil"), + ctx.mkSymbol("is_nil"), null, null, null); + cons1_con = ctx.mkConstructor(ctx.mkSymbol("cons1"), + ctx.mkSymbol("is_cons1"), head_tail1, sorts1, sort1_refs); constructors1[0] = nil1_con; constructors1[1] = cons1_con; /* build a tree */ - nil2_con = ctx.MkConstructor(ctx.MkSymbol("nil2"), - ctx.MkSymbol("is_nil2"), null, null, null); - cons2_con = ctx.MkConstructor(ctx.MkSymbol("cons2"), - ctx.MkSymbol("is_cons2"), head_tail2, sorts2, sort2_refs); + nil2_con = ctx.mkConstructor(ctx.mkSymbol("nil2"), + ctx.mkSymbol("is_nil2"), null, null, null); + cons2_con = ctx.mkConstructor(ctx.mkSymbol("cons2"), + ctx.mkSymbol("is_cons2"), head_tail2, sorts2, sort2_refs); constructors2[0] = nil2_con; constructors2[1] = cons2_con; Constructor[][] clists = new Constructor[][] { constructors1, constructors2 }; - Sort[] sorts = ctx.MkDatatypeSorts(sort_names, clists); + Sort[] sorts = ctx.mkDatatypeSorts(sort_names, clists); forest = sorts[0]; tree = sorts[1]; @@ -1870,81 +1849,81 @@ class JavaExample // functions, testers, and field accessors. // nil1_decl = nil1_con.ConstructorDecl(); - is_nil1_decl = nil1_con.TesterDecl(); + is_nil1_decl = nil1_con.getTesterDecl(); cons1_decl = cons1_con.ConstructorDecl(); - is_cons1_decl = cons1_con.TesterDecl(); - FuncDecl[] cons1_accessors = cons1_con.AccessorDecls(); + is_cons1_decl = cons1_con.getTesterDecl(); + FuncDecl[] cons1_accessors = cons1_con.getAccessorDecls(); car1_decl = cons1_accessors[0]; cdr1_decl = cons1_accessors[1]; nil2_decl = nil2_con.ConstructorDecl(); - is_nil2_decl = nil2_con.TesterDecl(); + is_nil2_decl = nil2_con.getTesterDecl(); cons2_decl = cons2_con.ConstructorDecl(); - is_cons2_decl = cons2_con.TesterDecl(); - FuncDecl[] cons2_accessors = cons2_con.AccessorDecls(); + is_cons2_decl = cons2_con.getTesterDecl(); + FuncDecl[] cons2_accessors = cons2_con.getAccessorDecls(); car2_decl = cons2_accessors[0]; cdr2_decl = cons2_accessors[1]; - nil1 = ctx.MkConst(nil1_decl); - nil2 = ctx.MkConst(nil2_decl); - f1 = ctx.MkApp(cons1_decl, new Expr[] { nil2, nil1 }); - t1 = ctx.MkApp(cons2_decl, new Expr[] { nil1, nil1 }); - t2 = ctx.MkApp(cons2_decl, new Expr[] { f1, nil1 }); - t3 = ctx.MkApp(cons2_decl, new Expr[] { f1, f1 }); - t4 = ctx.MkApp(cons2_decl, new Expr[] { nil1, f1 }); - f2 = ctx.MkApp(cons1_decl, new Expr[] { t1, nil1 }); - f3 = ctx.MkApp(cons1_decl, new Expr[] { t1, f1 }); + nil1 = ctx.mkConst(nil1_decl); + nil2 = ctx.mkConst(nil2_decl); + f1 = ctx.mkApp(cons1_decl, nil2, nil1); + t1 = ctx.mkApp(cons2_decl, nil1, nil1); + t2 = ctx.mkApp(cons2_decl, f1, nil1); + t3 = ctx.mkApp(cons2_decl, f1, f1); + t4 = ctx.mkApp(cons2_decl, nil1, f1); + f2 = ctx.mkApp(cons1_decl, t1, nil1); + f3 = ctx.mkApp(cons1_decl, t1, f1); /* nil != cons(nil,nil) */ - Prove(ctx, ctx.MkNot(ctx.MkEq(nil1, f1)), false); - Prove(ctx, ctx.MkNot(ctx.MkEq(nil2, t1)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(nil1, f1)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(nil2, t1)), false); /* cons(x,u) = cons(x, v) => u = v */ - u = ctx.MkConst("u", forest); - v = ctx.MkConst("v", forest); - x = ctx.MkConst("x", tree); - y = ctx.MkConst("y", tree); - l1 = ctx.MkApp(cons1_decl, new Expr[] { x, u }); - l2 = ctx.MkApp(cons1_decl, new Expr[] { y, v }); - Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v)), false); - Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + u = ctx.mkConst("u", forest); + v = ctx.mkConst("v", forest); + x = ctx.mkConst("x", tree); + y = ctx.mkConst("y", tree); + l1 = ctx.mkApp(cons1_decl, x, u); + l2 = ctx.mkApp(cons1_decl, y, v); + prove(ctx, ctx.mkImplies(ctx.mkEq(l1, l2), ctx.mkEq(u, v)), false); + prove(ctx, ctx.mkImplies(ctx.mkEq(l1, l2), ctx.mkEq(x, y)), false); /* is_nil(u) or is_cons(u) */ - Prove(ctx, ctx.MkOr(new BoolExpr[] { - (BoolExpr) ctx.MkApp(is_nil1_decl, new Expr[] { u }), - (BoolExpr) ctx.MkApp(is_cons1_decl, new Expr[] { u }) }), false); + prove(ctx, + ctx.mkOr((BoolExpr) ctx.mkApp(is_nil1_decl, u), + (BoolExpr) ctx.mkApp(is_cons1_decl, u)), false); /* occurs check u != cons(x,u) */ - Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1)), false); + prove(ctx, ctx.mkNot(ctx.mkEq(u, l1)), false); } // / Demonstrate how to use #Eval. - public void EvalExample1(Context ctx) throws Z3Exception + public void evalExample1(Context ctx) throws Z3Exception { System.out.println("EvalExample1"); - Log.Append("EvalExample1"); + Log.append("EvalExample1"); - IntExpr x = ctx.MkIntConst("x"); - IntExpr y = ctx.MkIntConst("y"); - IntExpr two = ctx.MkInt(2); + IntExpr x = ctx.mkIntConst("x"); + IntExpr y = ctx.mkIntConst("y"); + IntExpr two = ctx.mkInt(2); - Solver solver = ctx.MkSolver(); + Solver solver = ctx.mkSolver(); /* assert x < y */ - solver.Assert(ctx.MkLt(x, y)); + solver.assert_(ctx.mkLt(x, y)); /* assert x > 2 */ - solver.Assert(ctx.MkGt(x, two)); + solver.assert_(ctx.mkGt(x, two)); /* find model for the constraints above */ Model model = null; - if (Status.SATISFIABLE == solver.Check()) + if (Status.SATISFIABLE == solver.check()) { - model = solver.Model(); + model = solver.getModel(); System.out.println(model); System.out.println("\nevaluating x+y"); - Expr v = model.Evaluate(ctx.MkAdd(new ArithExpr[] { x, y }), false); + Expr v = model.evaluate(ctx.mkAdd(x, y), false); if (v != null) { System.out.println("result = " + (v)); @@ -1960,47 +1939,47 @@ class JavaExample // / Demonstrate how to use #Eval on tuples. - public void EvalExample2(Context ctx) throws Z3Exception + public void evalExample2(Context ctx) throws Z3Exception { System.out.println("EvalExample2"); - Log.Append("EvalExample2"); + Log.append("EvalExample2"); - Sort int_type = ctx.IntSort(); - TupleSort tuple = ctx.MkTupleSort(ctx.MkSymbol("mk_tuple"), // name of + Sort int_type = ctx.getIntSort(); + TupleSort tuple = ctx.mkTupleSort(ctx.mkSymbol("mk_tuple"), // name of // tuple // constructor - new Symbol[] { ctx.MkSymbol("first"), ctx.MkSymbol("second") }, // names + new Symbol[] { ctx.mkSymbol("first"), ctx.mkSymbol("second") }, // names // of // projection // operators new Sort[] { int_type, int_type } // types of projection // operators ); - FuncDecl first = tuple.FieldDecls()[0]; // declarations are for - // projections - FuncDecl second = tuple.FieldDecls()[1]; - Expr tup1 = ctx.MkConst("t1", tuple); - Expr tup2 = ctx.MkConst("t2", tuple); + FuncDecl first = tuple.getFieldDecls()[0]; // declarations are for + // projections + FuncDecl second = tuple.getFieldDecls()[1]; + Expr tup1 = ctx.mkConst("t1", tuple); + Expr tup2 = ctx.mkConst("t2", tuple); - Solver solver = ctx.MkSolver(); + Solver solver = ctx.mkSolver(); /* assert tup1 != tup2 */ - solver.Assert(ctx.MkNot(ctx.MkEq(tup1, tup2))); + solver.assert_(ctx.mkNot(ctx.mkEq(tup1, tup2))); /* assert first tup1 = first tup2 */ - solver.Assert(ctx.MkEq(ctx.MkApp(first, tup1), ctx.MkApp(first, tup2))); + solver.assert_(ctx.mkEq(ctx.mkApp(first, tup1), ctx.mkApp(first, tup2))); /* find model for the constraints above */ Model model = null; - if (Status.SATISFIABLE == solver.Check()) + if (Status.SATISFIABLE == solver.check()) { - model = solver.Model(); + model = solver.getModel(); System.out.println(model); System.out.println("evaluating tup1 " - + (model.Evaluate(tup1, false))); + + (model.evaluate(tup1, false))); System.out.println("evaluating tup2 " - + (model.Evaluate(tup2, false))); + + (model.evaluate(tup2, false))); System.out.println("evaluating second(tup2) " - + (model.Evaluate(ctx.MkApp(second, tup2), false))); + + (model.evaluate(ctx.mkApp(second, tup2), false))); } else { System.out.println("BUG, the constraints are satisfiable."); @@ -2011,8 +1990,8 @@ class JavaExample // / control the size of models. // / Note: this test is specialized to 32-bit bitvectors. - public void CheckSmall(Context ctx, Solver solver, BitVecExpr[] to_minimize) - throws Z3Exception + public void checkSmall(Context ctx, Solver solver, + BitVecExpr... to_minimize) throws Z3Exception { int num_Exprs = to_minimize.length; int[] upper = new int[num_Exprs]; @@ -2027,7 +2006,7 @@ class JavaExample int last_upper = 0; while (some_work) { - solver.Push(); + solver.push(); boolean check_is_sat = true; while (check_is_sat && some_work) @@ -2035,11 +2014,11 @@ class JavaExample // Assert all feasible bounds. for (int i = 0; i < num_Exprs; ++i) { - solver.Assert(ctx.MkBVULE(to_minimize[i], - ctx.MkBV(upper[i], 32))); + solver.assert_(ctx.mkBVULE(to_minimize[i], + ctx.mkBV(upper[i], 32))); } - check_is_sat = Status.SATISFIABLE == solver.Check(); + check_is_sat = Status.SATISFIABLE == solver.check(); if (!check_is_sat) { if (last_index != -1) @@ -2048,13 +2027,13 @@ class JavaExample } break; } - System.out.println(solver.Model()); + System.out.println(solver.getModel()); // narrow the bounds based on the current model. for (int i = 0; i < num_Exprs; ++i) { - Expr v = solver.Model().Evaluate(to_minimize[i], false); - int ui = ((BitVecNum) v).Int(); + Expr v = solver.getModel().evaluate(to_minimize[i], false); + int ui = ((BitVecNum) v).getInt(); if (ui < upper[i]) { upper[i] = (int) ui; @@ -2071,113 +2050,111 @@ class JavaExample { last_upper = (upper[i] + lower[i]) / 2; last_index = i; - solver.Assert(ctx.MkBVULE(to_minimize[i], - ctx.MkBV(last_upper, 32))); + solver.assert_(ctx.mkBVULE(to_minimize[i], + ctx.mkBV(last_upper, 32))); some_work = true; break; } } } - solver.Pop(); + solver.pop(); } } // / Reduced-size model generation example. - public void FindSmallModelExample(Context ctx) throws Z3Exception + public void findSmallModelExample(Context ctx) throws Z3Exception { System.out.println("FindSmallModelExample"); - Log.Append("FindSmallModelExample"); + Log.append("FindSmallModelExample"); - BitVecExpr x = ctx.MkBVConst("x", 32); - BitVecExpr y = ctx.MkBVConst("y", 32); - BitVecExpr z = ctx.MkBVConst("z", 32); + BitVecExpr x = ctx.mkBVConst("x", 32); + BitVecExpr y = ctx.mkBVConst("y", 32); + BitVecExpr z = ctx.mkBVConst("z", 32); - Solver solver = ctx.MkSolver(); + Solver solver = ctx.mkSolver(); - solver.Assert(ctx.MkBVULE(x, ctx.MkBVAdd(y, z))); - CheckSmall(ctx, solver, new BitVecExpr[] { x, y, z }); + solver.assert_(ctx.mkBVULE(x, ctx.mkBVAdd(y, z))); + checkSmall(ctx, solver, x, y, z); } // / Simplifier example. - public void SimplifierExample(Context ctx) throws Z3Exception + public void simplifierExample(Context ctx) throws Z3Exception { System.out.println("SimplifierExample"); - Log.Append("SimplifierExample"); + Log.append("SimplifierExample"); - IntExpr x = ctx.MkIntConst("x"); - IntExpr y = ctx.MkIntConst("y"); - IntExpr z = ctx.MkIntConst("z"); - IntExpr u = ctx.MkIntConst("u"); + IntExpr x = ctx.mkIntConst("x"); + IntExpr y = ctx.mkIntConst("y"); + IntExpr z = ctx.mkIntConst("z"); + @SuppressWarnings("unused") + IntExpr u = ctx.mkIntConst("u"); - Expr t1 = ctx.MkAdd(new ArithExpr[] { - x, - ctx.MkSub(new ArithExpr[] { y, - ctx.MkAdd(new ArithExpr[] { x, z }) }) }); - Expr t2 = t1.Simplify(); + Expr t1 = ctx.mkAdd(x, ctx.mkSub(y, ctx.mkAdd(x, z))); + Expr t2 = t1.simplify(); System.out.println((t1) + " -> " + (t2)); } // / Extract unsatisfiable core example - public void UnsatCoreAndProofExample(Context ctx) throws Z3Exception + public void unsatCoreAndProofExample(Context ctx) throws Z3Exception { System.out.println("UnsatCoreAndProofExample"); - Log.Append("UnsatCoreAndProofExample"); + Log.append("UnsatCoreAndProofExample"); - Solver solver = ctx.MkSolver(); + Solver solver = ctx.mkSolver(); - BoolExpr pa = ctx.MkBoolConst("PredA"); - BoolExpr pb = ctx.MkBoolConst("PredB"); - BoolExpr pc = ctx.MkBoolConst("PredC"); - BoolExpr pd = ctx.MkBoolConst("PredD"); - BoolExpr p1 = ctx.MkBoolConst("P1"); - BoolExpr p2 = ctx.MkBoolConst("P2"); - BoolExpr p3 = ctx.MkBoolConst("P3"); - BoolExpr p4 = ctx.MkBoolConst("P4"); - BoolExpr[] assumptions = new BoolExpr[] { ctx.MkNot(p1), ctx.MkNot(p2), - ctx.MkNot(p3), ctx.MkNot(p4) }; - BoolExpr f1 = ctx.MkAnd(new BoolExpr[] { pa, pb, pc }); - BoolExpr f2 = ctx.MkAnd(new BoolExpr[] { pa, ctx.MkNot(pb), pc }); - BoolExpr f3 = ctx.MkOr(new BoolExpr[] { ctx.MkNot(pa), ctx.MkNot(pc) }); + BoolExpr pa = ctx.mkBoolConst("PredA"); + BoolExpr pb = ctx.mkBoolConst("PredB"); + BoolExpr pc = ctx.mkBoolConst("PredC"); + BoolExpr pd = ctx.mkBoolConst("PredD"); + BoolExpr p1 = ctx.mkBoolConst("P1"); + BoolExpr p2 = ctx.mkBoolConst("P2"); + BoolExpr p3 = ctx.mkBoolConst("P3"); + BoolExpr p4 = ctx.mkBoolConst("P4"); + BoolExpr[] assumptions = new BoolExpr[] { ctx.mkNot(p1), ctx.mkNot(p2), + ctx.mkNot(p3), ctx.mkNot(p4) }; + BoolExpr f1 = ctx.mkAnd(pa, pb, pc); + BoolExpr f2 = ctx.mkAnd(pa, ctx.mkNot(pb), pc); + BoolExpr f3 = ctx.mkOr(ctx.mkNot(pa), ctx.mkNot(pc)); BoolExpr f4 = pd; - solver.Assert(ctx.MkOr(new BoolExpr[] { f1, p1 })); - solver.Assert(ctx.MkOr(new BoolExpr[] { f2, p2 })); - solver.Assert(ctx.MkOr(new BoolExpr[] { f3, p3 })); - solver.Assert(ctx.MkOr(new BoolExpr[] { f4, p4 })); - Status result = solver.Check(assumptions); + solver.assert_(ctx.mkOr(f1, p1)); + solver.assert_(ctx.mkOr(f2, p2)); + solver.assert_(ctx.mkOr(f3, p3)); + solver.assert_(ctx.mkOr(f4, p4)); + Status result = solver.check(assumptions); if (result == Status.UNSATISFIABLE) { System.out.println("unsat"); - System.out.println("proof: " + solver.Proof()); + System.out.println("proof: " + solver.getProof()); System.out.println("core: "); - for (Expr c : solver.UnsatCore()) + for (Expr c : solver.getUnsatCore()) { System.out.println(c); } } } - public void FiniteDomainExample(Context ctx) throws Z3Exception + public void finiteDomainExample(Context ctx) throws Z3Exception { System.out.println("FiniteDomainExample"); - Log.Append("FiniteDomainExample"); + Log.append("FiniteDomainExample"); - FiniteDomainSort s = ctx.MkFiniteDomainSort("S", 10); - FiniteDomainSort t = ctx.MkFiniteDomainSort("T", 10); - Expr s1 = ctx.MkNumeral(1, s); - Expr t1 = ctx.MkNumeral(1, t); + FiniteDomainSort s = ctx.mkFiniteDomainSort("S", 10); + FiniteDomainSort t = ctx.mkFiniteDomainSort("T", 10); + Expr s1 = ctx.mkNumeral(1, s); + Expr t1 = ctx.mkNumeral(1, t); System.out.println(s); System.out.println(t); System.out.println(s1); - System.out.println(ctx.MkNumeral(2, s)); + System.out.println(ctx.mkNumeral(2, s)); System.out.println(t1); // But you cannot mix numerals of different sorts // even if the size of their domains are the same: - // System.out.println(ctx.MkEq(s1, t1)); + // System.out.println(ctx.mkEq(s1, t1)); } public static void main(String[] args) @@ -2186,59 +2163,59 @@ class JavaExample try { Context.ToggleWarningMessages(true); - Log.Open("test.log"); + Log.open("test.log"); System.out.print("Z3 Major Version: "); - System.out.println(Version.Major()); + System.out.println(Version.getMajor()); System.out.print("Z3 Full Version: "); System.out.println(Version.getString()); - p.SimpleExample(); + p.simpleExample(); { // These examples need model generation turned on. HashMap cfg = new HashMap(); cfg.put("model", "true"); Context ctx = new Context(cfg); - p.BasicTests(ctx); - p.CastingTest(ctx); - p.SudokuExample(ctx); - p.QuantifierExample1(ctx); - p.QuantifierExample2(ctx); - p.LogicExample(ctx); - p.ParOrExample(ctx); - p.FindModelExample1(ctx); - p.FindModelExample2(ctx); - p.PushPopExample1(ctx); - p.ArrayExample1(ctx); - p.ArrayExample3(ctx); - p.BitvectorExample1(ctx); - p.BitvectorExample2(ctx); - p.ParserExample1(ctx); - p.ParserExample2(ctx); - p.ParserExample4(ctx); - p.ParserExample5(ctx); - p.ITEExample(ctx); - p.EvalExample1(ctx); - p.EvalExample2(ctx); - p.FindSmallModelExample(ctx); - p.SimplifierExample(ctx); - p.FiniteDomainExample(ctx); + p.basicTests(ctx); + p.castingTest(ctx); + p.sudokuExample(ctx); + p.quantifierExample1(ctx); + p.quantifierExample2(ctx); + p.logicExample(ctx); + p.parOrExample(ctx); + p.findModelExample1(ctx); + p.findModelExample2(ctx); + p.pushPopExample1(ctx); + p.arrayExample1(ctx); + p.arrayExample3(ctx); + p.bitvectorExample1(ctx); + p.bitvectorExample2(ctx); + p.parserExample1(ctx); + p.parserExample2(ctx); + p.parserExample4(ctx); + p.parserExample5(ctx); + p.iteExample(ctx); + p.evalExample1(ctx); + p.evalExample2(ctx); + p.findSmallModelExample(ctx); + p.simplifierExample(ctx); + p.finiteDomainExample(ctx); } { // These examples need proof generation turned on. HashMap cfg = new HashMap(); cfg.put("proof", "true"); Context ctx = new Context(cfg); - p.ProveExample1(ctx); - p.ProveExample2(ctx); - p.ArrayExample2(ctx); - p.TupleExample(ctx); - p.ParserExample3(ctx); - p.EnumExample(ctx); - p.ListExample(ctx); - p.TreeExample(ctx); - p.ForestExample(ctx); - p.UnsatCoreAndProofExample(ctx); + p.proveExample1(ctx); + p.proveExample2(ctx); + p.arrayExample2(ctx); + p.tupleExample(ctx); + p.parserExample3(ctx); + p.enumExample(ctx); + p.listExample(ctx); + p.treeExample(ctx); + p.forestExample(ctx); + p.unsatCoreAndProofExample(ctx); } { // These examples need proof generation turned on and auto-config @@ -2247,11 +2224,11 @@ class JavaExample cfg.put("proof", "true"); cfg.put("auto-config", "false"); Context ctx = new Context(cfg); - p.QuantifierExample3(ctx); - p.QuantifierExample4(ctx); + p.quantifierExample3(ctx); + p.quantifierExample4(ctx); } - Log.Close(); + Log.close(); if (Log.isOpen()) System.out.println("Log is still open!"); } catch (Z3Exception ex) diff --git a/src/api/java/AST.java b/src/api/java/AST.java index 60ff48ecb..fa5cd8284 100644 --- a/src/api/java/AST.java +++ b/src/api/java/AST.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_ast_kind; /** * The abstract syntax tree (AST) class. @@ -47,7 +47,7 @@ public class AST extends Z3Object return false; } - return this.NativeObject() == casted.NativeObject(); + return this.getNativeObject() == casted.getNativeObject(); } /** @@ -70,9 +70,9 @@ public class AST extends Z3Object return 1; } - if (Id() < oAST.Id()) + if (getId() < oAST.getId()) return -1; - else if (Id() > oAST.Id()) + else if (getId() > oAST.getId()) return +1; else return 0; @@ -83,17 +83,22 @@ public class AST extends Z3Object * * @return A hash code **/ - public int GetHashCode() throws Z3Exception + public int hashCode() { - return (int) Native.getAstHash(Context().nCtx(), NativeObject()); + int r = 0; + try { + Native.getAstHash(getContext().nCtx(), getNativeObject()); + } + catch (Z3Exception ex) {} + return r; } /** * A unique identifier for the AST (unique among all ASTs). **/ - public int Id() throws Z3Exception + public int getId() throws Z3Exception { - return Native.getAstId(Context().nCtx(), NativeObject()); + return Native.getAstId(getContext().nCtx(), getNativeObject()); } /** @@ -102,31 +107,31 @@ public class AST extends Z3Object * * @return A copy of the AST which is associated with **/ - public AST Translate(Context ctx) throws Z3Exception + public AST translate(Context ctx) throws Z3Exception { - if (Context() == ctx) + if (getContext() == ctx) return this; else - return new AST(ctx, Native.translate(Context().nCtx(), - NativeObject(), ctx.nCtx())); + return new AST(ctx, Native.translate(getContext().nCtx(), + getNativeObject(), ctx.nCtx())); } /** * The kind of the AST. **/ - public Z3_ast_kind ASTKind() throws Z3Exception + public Z3_ast_kind getASTKind() throws Z3Exception { - return Z3_ast_kind.fromInt(Native.getAstKind(Context().nCtx(), - NativeObject())); + return Z3_ast_kind.fromInt(Native.getAstKind(getContext().nCtx(), + getNativeObject())); } /** * Indicates whether the AST is an Expr **/ - public boolean IsExpr() throws Z3Exception + public boolean isExpr() throws Z3Exception { - switch (ASTKind()) + switch (getASTKind()) { case Z3_APP_AST: case Z3_NUMERAL_AST: @@ -141,41 +146,41 @@ public class AST extends Z3Object /** * Indicates whether the AST is an application **/ - public boolean IsApp() throws Z3Exception + public boolean isApp() throws Z3Exception { - return this.ASTKind() == Z3_ast_kind.Z3_APP_AST; + return this.getASTKind() == Z3_ast_kind.Z3_APP_AST; } /** * Indicates whether the AST is a BoundVariable **/ - public boolean IsVar() throws Z3Exception + public boolean isVar() throws Z3Exception { - return this.ASTKind() == Z3_ast_kind.Z3_VAR_AST; + return this.getASTKind() == Z3_ast_kind.Z3_VAR_AST; } /** * Indicates whether the AST is a Quantifier **/ - public boolean IsQuantifier() throws Z3Exception + public boolean isQuantifier() throws Z3Exception { - return this.ASTKind() == Z3_ast_kind.Z3_QUANTIFIER_AST; + return this.getASTKind() == Z3_ast_kind.Z3_QUANTIFIER_AST; } /** * Indicates whether the AST is a Sort **/ - public boolean IsSort() throws Z3Exception + public boolean isSort() throws Z3Exception { - return this.ASTKind() == Z3_ast_kind.Z3_SORT_AST; + return this.getASTKind() == Z3_ast_kind.Z3_SORT_AST; } /** * Indicates whether the AST is a FunctionDeclaration **/ - public boolean IsFuncDecl() throws Z3Exception + public boolean isFuncDecl() throws Z3Exception { - return this.ASTKind() == Z3_ast_kind.Z3_FUNC_DECL_AST; + return this.getASTKind() == Z3_ast_kind.Z3_FUNC_DECL_AST; } /** @@ -185,7 +190,7 @@ public class AST extends Z3Object { try { - return Native.astToString(Context().nCtx(), NativeObject()); + return Native.astToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -195,9 +200,9 @@ public class AST extends Z3Object /** * A string representation of the AST in s-expression notation. **/ - public String SExpr() throws Z3Exception + public String getSExpr() throws Z3Exception { - return Native.astToString(Context().nCtx(), NativeObject()); + return Native.astToString(getContext().nCtx(), getNativeObject()); } AST(Context ctx) @@ -210,29 +215,29 @@ public class AST extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { // Console.WriteLine("AST IncRef()"); - if (Context() == null) + if (getContext() == null) throw new Z3Exception("inc() called on null context"); if (o == 0) throw new Z3Exception("inc() called on null AST"); - Context().AST_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().ast_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { // Console.WriteLine("AST DecRef()"); - if (Context() == null) + if (getContext() == null) throw new Z3Exception("dec() called on null context"); if (o == 0) throw new Z3Exception("dec() called on null AST"); - Context().AST_DRQ().Add(o); - super.DecRef(o); + getContext().ast_DRQ().add(o); + super.decRef(o); } - static AST Create(Context ctx, long obj) throws Z3Exception + static AST create(Context ctx, long obj) throws Z3Exception { switch (Z3_ast_kind.fromInt(Native.getAstKind(ctx.nCtx(), obj))) { @@ -241,11 +246,11 @@ public class AST extends Z3Object case Z3_QUANTIFIER_AST: return new Quantifier(ctx, obj); case Z3_SORT_AST: - return Sort.Create(ctx, obj); + return Sort.create(ctx, obj); case Z3_APP_AST: case Z3_NUMERAL_AST: case Z3_VAR_AST: - return Expr.Create(ctx, obj); + return Expr.create(ctx, obj); default: throw new Z3Exception("Unknown AST kind"); } diff --git a/src/api/java/ASTDecRefQueue.java b/src/api/java/ASTDecRefQueue.java index f66c54006..e0711363d 100644 --- a/src/api/java/ASTDecRefQueue.java +++ b/src/api/java/ASTDecRefQueue.java @@ -5,9 +5,9 @@ package com.microsoft.z3; -public class ASTDecRefQueue extends IDecRefQueue +class ASTDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ public class ASTDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/ASTMap.java b/src/api/java/ASTMap.java index c40c4c6b8..dbe7fbd02 100644 --- a/src/api/java/ASTMap.java +++ b/src/api/java/ASTMap.java @@ -18,11 +18,11 @@ class ASTMap extends Z3Object * @return True if is a key in the map, false * otherwise. **/ - public boolean Contains(AST k) throws Z3Exception + public boolean contains(AST k) throws Z3Exception { - return Native.astMapContains(Context().nCtx(), NativeObject(), - k.NativeObject()); + return Native.astMapContains(getContext().nCtx(), getNativeObject(), + k.getNativeObject()); } /** @@ -32,47 +32,47 @@ class ASTMap extends Z3Object * * @throws Z3Exception **/ - public AST Find(AST k) throws Z3Exception + public AST find(AST k) throws Z3Exception { - return new AST(Context(), Native.astMapFind(Context().nCtx(), - NativeObject(), k.NativeObject())); + return new AST(getContext(), Native.astMapFind(getContext().nCtx(), + getNativeObject(), k.getNativeObject())); } /** * Stores or replaces a new key/value pair in the map. The * key AST The value AST **/ - public void Insert(AST k, AST v) throws Z3Exception + public void insert(AST k, AST v) throws Z3Exception { - Native.astMapInsert(Context().nCtx(), NativeObject(), k.NativeObject(), - v.NativeObject()); + Native.astMapInsert(getContext().nCtx(), getNativeObject(), k.getNativeObject(), + v.getNativeObject()); } /** * Erases the key from the map. An * AST **/ - public void Erase(AST k) throws Z3Exception + public void erase(AST k) throws Z3Exception { - Native.astMapErase(Context().nCtx(), NativeObject(), k.NativeObject()); + Native.astMapErase(getContext().nCtx(), getNativeObject(), k.getNativeObject()); } /** * Removes all keys from the map. **/ - public void Reset() throws Z3Exception + public void reset() throws Z3Exception { - Native.astMapReset(Context().nCtx(), NativeObject()); + Native.astMapReset(getContext().nCtx(), getNativeObject()); } /** * The size of the map **/ - public int Size() throws Z3Exception + public int size() throws Z3Exception { - return Native.astMapSize(Context().nCtx(), NativeObject()); + return Native.astMapSize(getContext().nCtx(), getNativeObject()); } /** @@ -80,10 +80,10 @@ class ASTMap extends Z3Object * * @throws Z3Exception **/ - public ASTVector Keys() throws Z3Exception + public ASTVector getKeys() throws Z3Exception { - return new ASTVector(Context(), Native.astMapKeys(Context().nCtx(), - NativeObject())); + return new ASTVector(getContext(), Native.astMapKeys(getContext().nCtx(), + getNativeObject())); } /** @@ -93,7 +93,7 @@ class ASTMap extends Z3Object { try { - return Native.astMapToString(Context().nCtx(), NativeObject()); + return Native.astMapToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -110,15 +110,15 @@ class ASTMap extends Z3Object super(ctx, Native.mkAstMap(ctx.nCtx())); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().ASTMap_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().astmap_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().ASTMap_DRQ().Add(o); - super.DecRef(o); + getContext().astmap_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/ASTVector.java b/src/api/java/ASTVector.java index 0e9cf1ae7..39e32f5d5 100644 --- a/src/api/java/ASTVector.java +++ b/src/api/java/ASTVector.java @@ -14,9 +14,9 @@ class ASTVector extends Z3Object /** * The size of the vector **/ - public int Size() throws Z3Exception + public int size() throws Z3Exception { - return Native.astVectorSize(Context().nCtx(), NativeObject()); + return Native.astVectorSize(getContext().nCtx(), getNativeObject()); } /** @@ -29,33 +29,33 @@ class ASTVector extends Z3Object **/ public AST get(int i) throws Z3Exception { - return new AST(Context(), Native.astVectorGet(Context().nCtx(), - NativeObject(), i)); + return new AST(getContext(), Native.astVectorGet(getContext().nCtx(), + getNativeObject(), i)); } public void set(int i, AST value) throws Z3Exception { - Native.astVectorSet(Context().nCtx(), NativeObject(), i, - value.NativeObject()); + Native.astVectorSet(getContext().nCtx(), getNativeObject(), i, + value.getNativeObject()); } /** * Resize the vector to . The new size of the vector. **/ - public void Resize(int newSize) throws Z3Exception + public void resize(int newSize) throws Z3Exception { - Native.astVectorResize(Context().nCtx(), NativeObject(), newSize); + Native.astVectorResize(getContext().nCtx(), getNativeObject(), newSize); } /** * Add the AST to the back of the vector. The size is * increased by 1. An AST **/ - public void Push(AST a) throws Z3Exception + public void push(AST a) throws Z3Exception { - Native.astVectorPush(Context().nCtx(), NativeObject(), a.NativeObject()); + Native.astVectorPush(getContext().nCtx(), getNativeObject(), a.getNativeObject()); } /** @@ -65,10 +65,10 @@ class ASTVector extends Z3Object * @return A new ASTVector * @throws Z3Exception **/ - public ASTVector Translate(Context ctx) throws Z3Exception + public ASTVector translate(Context ctx) throws Z3Exception { - return new ASTVector(Context(), Native.astVectorTranslate(Context() - .nCtx(), NativeObject(), ctx.nCtx())); + return new ASTVector(getContext(), Native.astVectorTranslate(getContext() + .nCtx(), getNativeObject(), ctx.nCtx())); } /** @@ -78,7 +78,7 @@ class ASTVector extends Z3Object { try { - return Native.astVectorToString(Context().nCtx(), NativeObject()); + return Native.astVectorToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -95,15 +95,15 @@ class ASTVector extends Z3Object super(ctx, Native.mkAstVector(ctx.nCtx())); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().ASTVector_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().astvector_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().ASTVector_DRQ().Add(o); - super.DecRef(o); + getContext().astvector_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/AlgebraicNum.java b/src/api/java/AlgebraicNum.java index 9aee64e65..eaeae933d 100644 --- a/src/api/java/AlgebraicNum.java +++ b/src/api/java/AlgebraicNum.java @@ -19,11 +19,11 @@ public class AlgebraicNum extends ArithExpr * * @return A numeral Expr of sort Real **/ - public RatNum ToUpper(int precision) throws Z3Exception + public RatNum toUpper(int precision) throws Z3Exception { - return new RatNum(Context(), Native.getAlgebraicNumberUpper(Context() - .nCtx(), NativeObject(), precision)); + return new RatNum(getContext(), Native.getAlgebraicNumberUpper(getContext() + .nCtx(), getNativeObject(), precision)); } /** @@ -33,21 +33,21 @@ public class AlgebraicNum extends ArithExpr * * @return A numeral Expr of sort Real **/ - public RatNum ToLower(int precision) throws Z3Exception + public RatNum toLower(int precision) throws Z3Exception { - return new RatNum(Context(), Native.getAlgebraicNumberLower(Context() - .nCtx(), NativeObject(), precision)); + return new RatNum(getContext(), Native.getAlgebraicNumberLower(getContext() + .nCtx(), getNativeObject(), precision)); } /** * Returns a string representation in decimal notation. The result * has at most decimal places. **/ - public String ToDecimal(int precision) throws Z3Exception + public String toDecimal(int precision) throws Z3Exception { - return Native.getNumeralDecimalString(Context().nCtx(), NativeObject(), + return Native.getNumeralDecimalString(getContext().nCtx(), getNativeObject(), precision); } diff --git a/src/api/java/ApplyResult.java b/src/api/java/ApplyResult.java index 31267b536..e6c6b89fd 100644 --- a/src/api/java/ApplyResult.java +++ b/src/api/java/ApplyResult.java @@ -15,10 +15,10 @@ public class ApplyResult extends Z3Object /** * The number of Subgoals. **/ - public int NumSubgoals() throws Z3Exception + public int getNumSubgoals() throws Z3Exception { - return Native.applyResultGetNumSubgoals(Context().nCtx(), - NativeObject()); + return Native.applyResultGetNumSubgoals(getContext().nCtx(), + getNativeObject()); } /** @@ -26,13 +26,13 @@ public class ApplyResult extends Z3Object * * @throws Z3Exception **/ - public Goal[] Subgoals() throws Z3Exception + public Goal[] getSubgoals() throws Z3Exception { - int n = NumSubgoals(); + int n = getNumSubgoals(); Goal[] res = new Goal[n]; for (int i = 0; i < n; i++) - res[i] = new Goal(Context(), Native.applyResultGetSubgoal(Context() - .nCtx(), NativeObject(), i)); + res[i] = new Goal(getContext(), + Native.applyResultGetSubgoal(getContext().nCtx(), getNativeObject(), i)); return res; } @@ -43,10 +43,10 @@ public class ApplyResult extends Z3Object * @return A model for g * @throws Z3Exception **/ - public Model ConvertModel(int i, Model m) throws Z3Exception + public Model convertModel(int i, Model m) throws Z3Exception { - return new Model(Context(), Native.applyResultConvertModel(Context() - .nCtx(), NativeObject(), i, m.NativeObject())); + return new Model(getContext(), + Native.applyResultConvertModel(getContext().nCtx(), getNativeObject(), i, m.getNativeObject())); } /** @@ -56,7 +56,7 @@ public class ApplyResult extends Z3Object { try { - return Native.applyResultToString(Context().nCtx(), NativeObject()); + return Native.applyResultToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -68,15 +68,15 @@ public class ApplyResult extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().ApplyResult_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().applyResult_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().ApplyResult_DRQ().Add(o); - super.DecRef(o); + getContext().applyResult_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/ApplyResultDecRefQueue.java b/src/api/java/ApplyResultDecRefQueue.java index c459e85aa..275f4b8f0 100644 --- a/src/api/java/ApplyResultDecRefQueue.java +++ b/src/api/java/ApplyResultDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class ApplyResultDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class ApplyResultDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/ArraySort.java b/src/api/java/ArraySort.java index cd126443c..2ab8a9750 100644 --- a/src/api/java/ArraySort.java +++ b/src/api/java/ArraySort.java @@ -15,20 +15,20 @@ public class ArraySort extends Sort * The domain of the array sort. * @throws Z3Exception **/ - public Sort Domain() throws Z3Exception + public Sort getDomain() throws Z3Exception { - return Sort.Create(Context(), - Native.getArraySortDomain(Context().nCtx(), NativeObject())); + return Sort.create(getContext(), + Native.getArraySortDomain(getContext().nCtx(), getNativeObject())); } /** * The range of the array sort. * @throws Z3Exception **/ - public Sort Range() throws Z3Exception + public Sort getRange() throws Z3Exception { - return Sort.Create(Context(), - Native.getArraySortRange(Context().nCtx(), NativeObject())); + return Sort.create(getContext(), + Native.getArraySortRange(getContext().nCtx(), getNativeObject())); } ArraySort(Context ctx, long obj) throws Z3Exception @@ -38,7 +38,7 @@ public class ArraySort extends Sort ArraySort(Context ctx, Sort domain, Sort range) throws Z3Exception { - super(ctx, Native.mkArraySort(ctx.nCtx(), domain.NativeObject(), - range.NativeObject())); + super(ctx, Native.mkArraySort(ctx.nCtx(), domain.getNativeObject(), + range.getNativeObject())); } }; diff --git a/src/api/java/AstMapDecRefQueue.java b/src/api/java/AstMapDecRefQueue.java index d59074cdb..f4c6b2ab5 100644 --- a/src/api/java/AstMapDecRefQueue.java +++ b/src/api/java/AstMapDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class ASTMapDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class ASTMapDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/AstVectorDecRefQueue.java b/src/api/java/AstVectorDecRefQueue.java index d4b508a54..bdabcdcb1 100644 --- a/src/api/java/AstVectorDecRefQueue.java +++ b/src/api/java/AstVectorDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class ASTVectorDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class ASTVectorDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/BitVecExpr.java b/src/api/java/BitVecExpr.java index fb0f4d72a..9602ea3a0 100644 --- a/src/api/java/BitVecExpr.java +++ b/src/api/java/BitVecExpr.java @@ -16,15 +16,15 @@ public class BitVecExpr extends Expr * The size of the sort of a bit-vector term. * @throws Z3Exception **/ - public int SortSize() throws Z3Exception + public int getSortSize() throws Z3Exception { - return ((BitVecSort) Sort()).Size(); + return ((BitVecSort) getSort()).getSize(); } /** * Constructor for BitVecExpr **/ - protected BitVecExpr(Context ctx) + BitVecExpr(Context ctx) { super(ctx); } diff --git a/src/api/java/BitVecNum.java b/src/api/java/BitVecNum.java index 3560d5efa..7615308b7 100644 --- a/src/api/java/BitVecNum.java +++ b/src/api/java/BitVecNum.java @@ -18,10 +18,10 @@ public class BitVecNum extends BitVecExpr * * @throws Z3Exception **/ - public int Int() throws Z3Exception + public int getInt() throws Z3Exception { Native.IntPtr res = new Native.IntPtr(); - if (Native.getNumeralInt(Context().nCtx(), NativeObject(), res) ^ true) + if (Native.getNumeralInt(getContext().nCtx(), getNativeObject(), res) ^ true) throw new Z3Exception("Numeral is not an int"); return res.value; } @@ -31,10 +31,10 @@ public class BitVecNum extends BitVecExpr * * @throws Z3Exception **/ - public long Long() throws Z3Exception + public long getLong() throws Z3Exception { Native.LongPtr res = new Native.LongPtr(); - if (Native.getNumeralInt64(Context().nCtx(), NativeObject(), res) ^ true) + if (Native.getNumeralInt64(getContext().nCtx(), getNativeObject(), res) ^ true) throw new Z3Exception("Numeral is not an int64"); return res.value; } @@ -42,7 +42,7 @@ public class BitVecNum extends BitVecExpr /** * Retrieve the BigInteger value. **/ - public BigInteger BigInteger() + public BigInteger getBigInteger() { return new BigInteger(this.toString()); } @@ -54,7 +54,7 @@ public class BitVecNum extends BitVecExpr { try { - return Native.getNumeralString(Context().nCtx(), NativeObject()); + return Native.getNumeralString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); diff --git a/src/api/java/BitVecSort.java b/src/api/java/BitVecSort.java index 58781302e..c2ec4c26e 100644 --- a/src/api/java/BitVecSort.java +++ b/src/api/java/BitVecSort.java @@ -13,9 +13,9 @@ public class BitVecSort extends Sort /** * The size of the bit-vector sort. **/ - public int Size() throws Z3Exception + public int getSize() throws Z3Exception { - return Native.getBvSortSize(Context().nCtx(), NativeObject()); + return Native.getBvSortSize(getContext().nCtx(), getNativeObject()); } BitVecSort(Context ctx, long obj) throws Z3Exception diff --git a/src/api/java/Constructor.java b/src/api/java/Constructor.java index e267998a0..c12521bc5 100644 --- a/src/api/java/Constructor.java +++ b/src/api/java/Constructor.java @@ -15,7 +15,7 @@ public class Constructor extends Z3Object * The number of fields of the constructor. * @throws Z3Exception **/ - public int NumFields() throws Z3Exception + public int getNumFields() throws Z3Exception { init(); return n; @@ -35,7 +35,7 @@ public class Constructor extends Z3Object * The function declaration of the tester. * @throws Z3Exception **/ - public FuncDecl TesterDecl() throws Z3Exception + public FuncDecl getTesterDecl() throws Z3Exception { init(); return m_testerDecl; @@ -45,7 +45,7 @@ public class Constructor extends Z3Object * The function declarations of the accessors * @throws Z3Exception **/ - public FuncDecl[] AccessorDecls() throws Z3Exception + public FuncDecl[] getAccessorDecls() throws Z3Exception { init(); return m_accessorDecls; @@ -56,7 +56,7 @@ public class Constructor extends Z3Object **/ protected void finalize() throws Z3Exception { - Native.delConstructor(Context().nCtx(), NativeObject()); + Native.delConstructor(getContext().nCtx(), getNativeObject()); } private int n = 0; @@ -70,9 +70,9 @@ public class Constructor extends Z3Object { super(ctx); - n = AST.ArrayLength(fieldNames); + n = AST.arrayLength(fieldNames); - if (n != AST.ArrayLength(sorts)) + if (n != AST.arrayLength(sorts)) throw new Z3Exception( "Number of field names does not match number of sorts"); if (sortRefs != null && sortRefs.length != n) @@ -82,9 +82,9 @@ public class Constructor extends Z3Object if (sortRefs == null) sortRefs = new int[n]; - setNativeObject(Native.mkConstructor(ctx.nCtx(), name.NativeObject(), - recognizer.NativeObject(), n, Symbol.ArrayToNative(fieldNames), - Sort.ArrayToNative(sorts), sortRefs)); + setNativeObject(Native.mkConstructor(ctx.nCtx(), name.getNativeObject(), + recognizer.getNativeObject(), n, Symbol.arrayToNative(fieldNames), + Sort.arrayToNative(sorts), sortRefs)); } @@ -95,13 +95,13 @@ public class Constructor extends Z3Object Native.LongPtr constructor = new Native.LongPtr(); Native.LongPtr tester = new Native.LongPtr(); long[] accessors = new long[n]; - Native.queryConstructor(Context().nCtx(), NativeObject(), n, + Native.queryConstructor(getContext().nCtx(), getNativeObject(), n, constructor, tester, accessors); - m_constructorDecl = new FuncDecl(Context(), constructor.value); - m_testerDecl = new FuncDecl(Context(), tester.value); + m_constructorDecl = new FuncDecl(getContext(), constructor.value); + m_testerDecl = new FuncDecl(getContext(), tester.value); m_accessorDecls = new FuncDecl[n]; for (int i = 0; i < n; i++) - m_accessorDecls[i] = new FuncDecl(Context(), accessors[i]); + m_accessorDecls[i] = new FuncDecl(getContext(), accessors[i]); } } diff --git a/src/api/java/ConstructorList.java b/src/api/java/ConstructorList.java index 87b6bd4fd..a33276ebb 100644 --- a/src/api/java/ConstructorList.java +++ b/src/api/java/ConstructorList.java @@ -16,7 +16,7 @@ public class ConstructorList extends Z3Object **/ protected void finalize() throws Z3Exception { - Native.delConstructorList(Context().nCtx(), NativeObject()); + Native.delConstructorList(getContext().nCtx(), getNativeObject()); } ConstructorList(Context ctx, long obj) throws Z3Exception @@ -28,8 +28,8 @@ public class ConstructorList extends Z3Object { super(ctx); - setNativeObject(Native.mkConstructorList(Context().nCtx(), + setNativeObject(Native.mkConstructorList(getContext().nCtx(), (int) constructors.length, - Constructor.ArrayToNative(constructors))); + Constructor.arrayToNative(constructors))); } } diff --git a/src/api/java/Context.java b/src/api/java/Context.java index d6076b5ee..7a1a404af 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -6,8 +6,9 @@ package com.microsoft.z3; -import java.util.*; -import com.microsoft.z3.enumerations.*; +import java.util.Map; + +import com.microsoft.z3.enumerations.Z3_ast_print_mode; /** * The main interaction with Z3 happens via the Context. @@ -21,7 +22,7 @@ public class Context extends IDisposable { super(); m_ctx = Native.mkContextRc(0); - InitContext(); + initContext(); } /** @@ -35,7 +36,7 @@ public class Context extends IDisposable Native.setParamValue(cfg, kv.getKey(), kv.getValue()); m_ctx = Native.mkContextRc(cfg); Native.delConfig(cfg); - InitContext(); + initContext(); } private Context(long ctx, long refCount) @@ -50,7 +51,7 @@ public class Context extends IDisposable * passed to this function. The legal range of unsigned integers is 0 to * 2^30-1. **/ - public IntSymbol MkSymbol(int i) throws Z3Exception + public IntSymbol mkSymbol(int i) throws Z3Exception { return new IntSymbol(this, i); } @@ -58,7 +59,7 @@ public class Context extends IDisposable /** * Create a symbol using a string. **/ - public StringSymbol MkSymbol(String name) throws Z3Exception + public StringSymbol mkSymbol(String name) throws Z3Exception { return new StringSymbol(this, name); } @@ -72,7 +73,7 @@ public class Context extends IDisposable return null; Symbol[] result = new Symbol[names.length]; for (int i = 0; i < names.length; ++i) - result[i] = MkSymbol(names[i]); + result[i] = mkSymbol(names[i]); return result; } @@ -83,7 +84,7 @@ public class Context extends IDisposable /** * Retrieves the Boolean sort of the context. **/ - public BoolSort BoolSort() throws Z3Exception + public BoolSort getBoolSort() throws Z3Exception { if (m_boolSort == null) m_boolSort = new BoolSort(this); @@ -93,7 +94,7 @@ public class Context extends IDisposable /** * Retrieves the Integer sort of the context. **/ - public IntSort IntSort() throws Z3Exception + public IntSort getIntSort() throws Z3Exception { if (m_intSort == null) m_intSort = new IntSort(this); @@ -103,7 +104,7 @@ public class Context extends IDisposable /** * Retrieves the Real sort of the context. **/ - public RealSort RealSort() throws Z3Exception + public RealSort getRealSort() throws Z3Exception { if (m_realSort == null) m_realSort = new RealSort(this); @@ -113,7 +114,7 @@ public class Context extends IDisposable /** * Create a new Boolean sort. **/ - public BoolSort MkBoolSort() throws Z3Exception + public BoolSort mkBoolSort() throws Z3Exception { return new BoolSort(this); @@ -122,26 +123,26 @@ public class Context extends IDisposable /** * Create a new uninterpreted sort. **/ - public UninterpretedSort MkUninterpretedSort(Symbol s) throws Z3Exception + public UninterpretedSort mkUninterpretedSort(Symbol s) throws Z3Exception { - CheckContextMatch(s); + checkContextMatch(s); return new UninterpretedSort(this, s); } /** * Create a new uninterpreted sort. **/ - public UninterpretedSort MkUninterpretedSort(String str) throws Z3Exception + public UninterpretedSort mkUninterpretedSort(String str) throws Z3Exception { - return MkUninterpretedSort(MkSymbol(str)); + return mkUninterpretedSort(mkSymbol(str)); } /** * Create a new integer sort. **/ - public IntSort MkIntSort() throws Z3Exception + public IntSort mkIntSort() throws Z3Exception { return new IntSort(this); @@ -150,7 +151,7 @@ public class Context extends IDisposable /** * Create a real sort. **/ - public RealSort MkRealSort() throws Z3Exception + public RealSort mkRealSort() throws Z3Exception { return new RealSort(this); @@ -159,7 +160,7 @@ public class Context extends IDisposable /** * Create a new bit-vector sort. **/ - public BitVecSort MkBitVecSort(int size) throws Z3Exception + public BitVecSort mkBitVecSort(int size) throws Z3Exception { return new BitVecSort(this, Native.mkBvSort(nCtx(), size)); @@ -168,24 +169,24 @@ public class Context extends IDisposable /** * Create a new array sort. **/ - public ArraySort MkArraySort(Sort domain, Sort range) throws Z3Exception + public ArraySort mkArraySort(Sort domain, Sort range) throws Z3Exception { - CheckContextMatch(domain); - CheckContextMatch(range); + checkContextMatch(domain); + checkContextMatch(range); return new ArraySort(this, domain, range); } /** * Create a new tuple sort. **/ - public TupleSort MkTupleSort(Symbol name, Symbol[] fieldNames, + public TupleSort mkTupleSort(Symbol name, Symbol[] fieldNames, Sort[] fieldSorts) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(fieldNames); - CheckContextMatch(fieldSorts); + checkContextMatch(name); + checkContextMatch(fieldNames); + checkContextMatch(fieldSorts); return new TupleSort(this, name, (int) fieldNames.length, fieldNames, fieldSorts); } @@ -193,65 +194,64 @@ public class Context extends IDisposable /** * Create a new enumeration sort. **/ - public EnumSort MkEnumSort(Symbol name, Symbol[] enumNames) + public EnumSort mkEnumSort(Symbol name, Symbol... enumNames) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(enumNames); + checkContextMatch(name); + checkContextMatch(enumNames); return new EnumSort(this, name, enumNames); } /** * Create a new enumeration sort. **/ - public EnumSort MkEnumSort(String name, String[] enumNames) + public EnumSort mkEnumSort(String name, String... enumNames) throws Z3Exception { - - return new EnumSort(this, MkSymbol(name), MkSymbols(enumNames)); + return new EnumSort(this, mkSymbol(name), MkSymbols(enumNames)); } /** * Create a new list sort. **/ - public ListSort MkListSort(Symbol name, Sort elemSort) throws Z3Exception + public ListSort mkListSort(Symbol name, Sort elemSort) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(elemSort); + checkContextMatch(name); + checkContextMatch(elemSort); return new ListSort(this, name, elemSort); } /** * Create a new list sort. **/ - public ListSort MkListSort(String name, Sort elemSort) throws Z3Exception + public ListSort mkListSort(String name, Sort elemSort) throws Z3Exception { - CheckContextMatch(elemSort); - return new ListSort(this, MkSymbol(name), elemSort); + checkContextMatch(elemSort); + return new ListSort(this, mkSymbol(name), elemSort); } /** * Create a new finite domain sort. **/ - public FiniteDomainSort MkFiniteDomainSort(Symbol name, long size) + public FiniteDomainSort mkFiniteDomainSort(Symbol name, long size) throws Z3Exception { - CheckContextMatch(name); + checkContextMatch(name); return new FiniteDomainSort(this, name, size); } /** * Create a new finite domain sort. **/ - public FiniteDomainSort MkFiniteDomainSort(String name, long size) + public FiniteDomainSort mkFiniteDomainSort(String name, long size) throws Z3Exception { - return new FiniteDomainSort(this, MkSymbol(name), size); + return new FiniteDomainSort(this, mkSymbol(name), size); } /** @@ -265,7 +265,7 @@ public class Context extends IDisposable * an index referring to one of the recursive datatypes that is * declared. **/ - public Constructor MkConstructor(Symbol name, Symbol recognizer, + public Constructor mkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames, Sort[] sorts, int[] sortRefs) throws Z3Exception { @@ -281,36 +281,36 @@ public class Context extends IDisposable * * @return **/ - public Constructor MkConstructor(String name, String recognizer, + public Constructor mkConstructor(String name, String recognizer, String[] fieldNames, Sort[] sorts, int[] sortRefs) throws Z3Exception { - return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), + return new Constructor(this, mkSymbol(name), mkSymbol(recognizer), MkSymbols(fieldNames), sorts, sortRefs); } /** * Create a new datatype sort. **/ - public DatatypeSort MkDatatypeSort(Symbol name, Constructor[] constructors) + public DatatypeSort mkDatatypeSort(Symbol name, Constructor[] constructors) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(constructors); + checkContextMatch(name); + checkContextMatch(constructors); return new DatatypeSort(this, name, constructors); } /** * Create a new datatype sort. **/ - public DatatypeSort MkDatatypeSort(String name, Constructor[] constructors) + public DatatypeSort mkDatatypeSort(String name, Constructor[] constructors) throws Z3Exception { - CheckContextMatch(constructors); - return new DatatypeSort(this, MkSymbol(name), constructors); + checkContextMatch(constructors); + return new DatatypeSort(this, mkSymbol(name), constructors); } /** @@ -318,11 +318,11 @@ public class Context extends IDisposable * datatype sorts list of constructors, one list per * sort. **/ - public DatatypeSort[] MkDatatypeSorts(Symbol[] names, Constructor[][] c) + public DatatypeSort[] mkDatatypeSorts(Symbol[] names, Constructor[][] c) throws Z3Exception { - CheckContextMatch(names); + checkContextMatch(names); int n = (int) names.length; ConstructorList[] cla = new ConstructorList[n]; long[] n_constr = new long[n]; @@ -330,12 +330,12 @@ public class Context extends IDisposable { Constructor[] constructor = c[i]; - CheckContextMatch(constructor); + checkContextMatch(constructor); cla[i] = new ConstructorList(this, constructor); - n_constr[i] = cla[i].NativeObject(); + n_constr[i] = cla[i].getNativeObject(); } long[] n_res = new long[n]; - Native.mkDatatypes(nCtx(), n, Symbol.ArrayToNative(names), n_res, + Native.mkDatatypes(nCtx(), n, Symbol.arrayToNative(names), n_res, n_constr); DatatypeSort[] res = new DatatypeSort[n]; for (int i = 0; i < n; i++) @@ -349,36 +349,36 @@ public class Context extends IDisposable * * @return **/ - public DatatypeSort[] MkDatatypeSorts(String[] names, Constructor[][] c) + public DatatypeSort[] mkDatatypeSorts(String[] names, Constructor[][] c) throws Z3Exception { - return MkDatatypeSorts(MkSymbols(names), c); + return mkDatatypeSorts(MkSymbols(names), c); } /** * Creates a new function declaration. **/ - public FuncDecl MkFuncDecl(Symbol name, Sort[] domain, Sort range) + public FuncDecl mkFuncDecl(Symbol name, Sort[] domain, Sort range) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); + checkContextMatch(name); + checkContextMatch(domain); + checkContextMatch(range); return new FuncDecl(this, name, domain, range); } /** * Creates a new function declaration. **/ - public FuncDecl MkFuncDecl(Symbol name, Sort domain, Sort range) + public FuncDecl mkFuncDecl(Symbol name, Sort domain, Sort range) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); + checkContextMatch(name); + checkContextMatch(domain); + checkContextMatch(range); Sort[] q = new Sort[] { domain }; return new FuncDecl(this, name, q, range); } @@ -386,26 +386,26 @@ public class Context extends IDisposable /** * Creates a new function declaration. **/ - public FuncDecl MkFuncDecl(String name, Sort[] domain, Sort range) + public FuncDecl mkFuncDecl(String name, Sort[] domain, Sort range) throws Z3Exception { - CheckContextMatch(domain); - CheckContextMatch(range); - return new FuncDecl(this, MkSymbol(name), domain, range); + checkContextMatch(domain); + checkContextMatch(range); + return new FuncDecl(this, mkSymbol(name), domain, range); } /** * Creates a new function declaration. **/ - public FuncDecl MkFuncDecl(String name, Sort domain, Sort range) + public FuncDecl mkFuncDecl(String name, Sort domain, Sort range) throws Z3Exception { - CheckContextMatch(domain); - CheckContextMatch(range); + checkContextMatch(domain); + checkContextMatch(range); Sort[] q = new Sort[] { domain }; - return new FuncDecl(this, MkSymbol(name), q, range); + return new FuncDecl(this, mkSymbol(name), q, range); } /** @@ -413,34 +413,34 @@ public class Context extends IDisposable * name="prefix"/>. **/ - public FuncDecl MkFreshFuncDecl(String prefix, Sort[] domain, Sort range) + public FuncDecl mkFreshFuncDecl(String prefix, Sort[] domain, Sort range) throws Z3Exception { - CheckContextMatch(domain); - CheckContextMatch(range); + checkContextMatch(domain); + checkContextMatch(range); return new FuncDecl(this, prefix, domain, range); } /** * Creates a new constant function declaration. **/ - public FuncDecl MkConstDecl(Symbol name, Sort range) throws Z3Exception + public FuncDecl mkConstDecl(Symbol name, Sort range) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(range); + checkContextMatch(name); + checkContextMatch(range); return new FuncDecl(this, name, null, range); } /** * Creates a new constant function declaration. **/ - public FuncDecl MkConstDecl(String name, Sort range) throws Z3Exception + public FuncDecl mkConstDecl(String name, Sort range) throws Z3Exception { - CheckContextMatch(range); - return new FuncDecl(this, MkSymbol(name), null, range); + checkContextMatch(range); + return new FuncDecl(this, mkSymbol(name), null, range); } /** @@ -448,11 +448,11 @@ public class Context extends IDisposable * . * **/ - public FuncDecl MkFreshConstDecl(String prefix, Sort range) + public FuncDecl mkFreshConstDecl(String prefix, Sort range) throws Z3Exception { - CheckContextMatch(range); + checkContextMatch(range); return new FuncDecl(this, prefix, null, range); } @@ -460,21 +460,21 @@ public class Context extends IDisposable * Creates a new bound variable. The de-Bruijn index of * the variable The sort of the variable **/ - public Expr MkBound(int index, Sort ty) throws Z3Exception + public Expr mkBound(int index, Sort ty) throws Z3Exception { - return Expr.Create(this, - Native.mkBound(nCtx(), index, ty.NativeObject())); + return Expr.create(this, + Native.mkBound(nCtx(), index, ty.getNativeObject())); } /** * Create a quantifier pattern. **/ - public Pattern MkPattern(Expr[] terms) throws Z3Exception + public Pattern mkPattern(Expr... terms) throws Z3Exception { if (terms.length == 0) throw new Z3Exception("Cannot create a pattern from zero terms"); - long[] termsNative = AST.ArrayToNative(terms); + long[] termsNative = AST.arrayToNative(terms); return new Pattern(this, Native.mkPattern(nCtx(), (int) terms.length, termsNative)); } @@ -483,148 +483,136 @@ public class Context extends IDisposable * Creates a new Constant of sort and named * . **/ - public Expr MkConst(Symbol name, Sort range) throws Z3Exception + public Expr mkConst(Symbol name, Sort range) throws Z3Exception { - CheckContextMatch(name); - CheckContextMatch(range); + checkContextMatch(name); + checkContextMatch(range); - return Expr.Create( + return Expr.create( this, - Native.mkConst(nCtx(), name.NativeObject(), - range.NativeObject())); + Native.mkConst(nCtx(), name.getNativeObject(), + range.getNativeObject())); } /** * Creates a new Constant of sort and named * . **/ - public Expr MkConst(String name, Sort range) throws Z3Exception + public Expr mkConst(String name, Sort range) throws Z3Exception { - return MkConst(MkSymbol(name), range); + return mkConst(mkSymbol(name), range); } /** * Creates a fresh Constant of sort and a name * prefixed with . **/ - public Expr MkFreshConst(String prefix, Sort range) throws Z3Exception + public Expr mkFreshConst(String prefix, Sort range) throws Z3Exception { - CheckContextMatch(range); - return Expr.Create(this, - Native.mkFreshConst(nCtx(), prefix, range.NativeObject())); + checkContextMatch(range); + return Expr.create(this, + Native.mkFreshConst(nCtx(), prefix, range.getNativeObject())); } /** * Creates a fresh constant from the FuncDecl . A decl of a 0-arity function **/ - public Expr MkConst(FuncDecl f) throws Z3Exception + public Expr mkConst(FuncDecl f) throws Z3Exception { - return MkApp(f, (Expr[]) null); + return mkApp(f, (Expr[]) null); } /** * Create a Boolean constant. **/ - public BoolExpr MkBoolConst(Symbol name) throws Z3Exception + public BoolExpr mkBoolConst(Symbol name) throws Z3Exception { - return (BoolExpr) MkConst(name, BoolSort()); + return (BoolExpr) mkConst(name, getBoolSort()); } /** * Create a Boolean constant. **/ - public BoolExpr MkBoolConst(String name) throws Z3Exception + public BoolExpr mkBoolConst(String name) throws Z3Exception { - return (BoolExpr) MkConst(MkSymbol(name), BoolSort()); + return (BoolExpr) mkConst(mkSymbol(name), getBoolSort()); } /** * Creates an integer constant. **/ - public IntExpr MkIntConst(Symbol name) throws Z3Exception + public IntExpr mkIntConst(Symbol name) throws Z3Exception { - return (IntExpr) MkConst(name, IntSort()); + return (IntExpr) mkConst(name, getIntSort()); } /** * Creates an integer constant. **/ - public IntExpr MkIntConst(String name) throws Z3Exception + public IntExpr mkIntConst(String name) throws Z3Exception { - return (IntExpr) MkConst(name, IntSort()); + return (IntExpr) mkConst(name, getIntSort()); } /** * Creates a real constant. **/ - public RealExpr MkRealConst(Symbol name) throws Z3Exception + public RealExpr mkRealConst(Symbol name) throws Z3Exception { - return (RealExpr) MkConst(name, RealSort()); + return (RealExpr) mkConst(name, getRealSort()); } /** * Creates a real constant. **/ - public RealExpr MkRealConst(String name) throws Z3Exception + public RealExpr mkRealConst(String name) throws Z3Exception { - return (RealExpr) MkConst(name, RealSort()); + return (RealExpr) mkConst(name, getRealSort()); } /** * Creates a bit-vector constant. **/ - public BitVecExpr MkBVConst(Symbol name, int size) throws Z3Exception + public BitVecExpr mkBVConst(Symbol name, int size) throws Z3Exception { - return (BitVecExpr) MkConst(name, MkBitVecSort(size)); + return (BitVecExpr) mkConst(name, mkBitVecSort(size)); } /** * Creates a bit-vector constant. **/ - public BitVecExpr MkBVConst(String name, int size) throws Z3Exception + public BitVecExpr mkBVConst(String name, int size) throws Z3Exception { - return (BitVecExpr) MkConst(name, MkBitVecSort(size)); + return (BitVecExpr) mkConst(name, mkBitVecSort(size)); } /** * Create a new function application. **/ - public Expr MkApp(FuncDecl f, Expr arg) throws Z3Exception + public Expr mkApp(FuncDecl f, Expr... args) throws Z3Exception { - CheckContextMatch(f); - CheckContextMatch(arg); - Expr[] args = { arg }; - return Expr.Create(this, f, args); - } - - /** - * Create a new function application. - **/ - public Expr MkApp(FuncDecl f, Expr[] args) throws Z3Exception - { - - CheckContextMatch(f); - CheckContextMatch(args); - return Expr.Create(this, f, args); + checkContextMatch(f); + checkContextMatch(args); + return Expr.create(this, f, args); } /** * The true Term. **/ - public BoolExpr MkTrue() throws Z3Exception + public BoolExpr mkTrue() throws Z3Exception { return new BoolExpr(this, Native.mkTrue(nCtx())); } @@ -632,7 +620,7 @@ public class Context extends IDisposable /** * The false Term. **/ - public BoolExpr MkFalse() throws Z3Exception + public BoolExpr mkFalse() throws Z3Exception { return new BoolExpr(this, Native.mkFalse(nCtx())); } @@ -640,40 +628,40 @@ public class Context extends IDisposable /** * Creates a Boolean value. **/ - public BoolExpr MkBool(boolean value) throws Z3Exception + public BoolExpr mkBool(boolean value) throws Z3Exception { - return value ? MkTrue() : MkFalse(); + return value ? mkTrue() : mkFalse(); } /** * Creates the equality = . **/ - public BoolExpr MkEq(Expr x, Expr y) throws Z3Exception + public BoolExpr mkEq(Expr x, Expr y) throws Z3Exception { - CheckContextMatch(x); - CheckContextMatch(y); - return new BoolExpr(this, Native.mkEq(nCtx(), x.NativeObject(), - y.NativeObject())); + checkContextMatch(x); + checkContextMatch(y); + return new BoolExpr(this, Native.mkEq(nCtx(), x.getNativeObject(), + y.getNativeObject())); } /** * Creates a distinct term. **/ - public BoolExpr MkDistinct(Expr[] args) throws Z3Exception + public BoolExpr mkDistinct(Expr... args) throws Z3Exception { - CheckContextMatch(args); + checkContextMatch(args); return new BoolExpr(this, Native.mkDistinct(nCtx(), (int) args.length, - AST.ArrayToNative(args))); + AST.arrayToNative(args))); } /** * Mk an expression representing not(a). **/ - public BoolExpr MkNot(BoolExpr a) throws Z3Exception + public BoolExpr mkNot(BoolExpr a) throws Z3Exception { - CheckContextMatch(a); - return new BoolExpr(this, Native.mkNot(nCtx(), a.NativeObject())); + checkContextMatch(a); + return new BoolExpr(this, Native.mkNot(nCtx(), a.getNativeObject())); } /** @@ -682,216 +670,216 @@ public class Context extends IDisposable * sort An expression An * expression with the same sort as **/ - public Expr MkITE(BoolExpr t1, Expr t2, Expr t3) throws Z3Exception + public Expr mkITE(BoolExpr t1, Expr t2, Expr t3) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(t3); - return Expr.Create( - this, - Native.mkIte(nCtx(), t1.NativeObject(), t2.NativeObject(), - t3.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + checkContextMatch(t3); + return Expr.create(this, Native.mkIte(nCtx(), t1.getNativeObject(), + t2.getNativeObject(), t3.getNativeObject())); } /** * Create an expression representing t1 iff t2. **/ - public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) throws Z3Exception + public BoolExpr mkIff(BoolExpr t1, BoolExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkIff(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkIff(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t1 -> t2. **/ - public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) throws Z3Exception + public BoolExpr mkImplies(BoolExpr t1, BoolExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkImplies(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkImplies(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Create an expression representing t1 xor t2. **/ - public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) throws Z3Exception + public BoolExpr mkXor(BoolExpr t1, BoolExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkXor(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkXor(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t[0] and t[1] and .... **/ - public BoolExpr MkAnd(BoolExpr[] t) throws Z3Exception + public BoolExpr mkAnd(BoolExpr... t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BoolExpr(this, Native.mkAnd(nCtx(), (int) t.length, - AST.ArrayToNative(t))); + AST.arrayToNative(t))); } /** * Create an expression representing t[0] or t[1] or .... **/ - public BoolExpr MkOr(BoolExpr[] t) throws Z3Exception + public BoolExpr mkOr(BoolExpr... t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BoolExpr(this, Native.mkOr(nCtx(), (int) t.length, - AST.ArrayToNative(t))); + AST.arrayToNative(t))); } /** * Create an expression representing t[0] + t[1] + .... **/ - public ArithExpr MkAdd(ArithExpr[] t) throws Z3Exception + public ArithExpr mkAdd(ArithExpr... t) throws Z3Exception { - CheckContextMatch(t); - return (ArithExpr) Expr.Create(this, - Native.mkAdd(nCtx(), (int) t.length, AST.ArrayToNative(t))); + checkContextMatch(t); + return (ArithExpr) Expr.create(this, + Native.mkAdd(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** * Create an expression representing t[0] * t[1] * .... **/ - public ArithExpr MkMul(ArithExpr[] t) throws Z3Exception + public ArithExpr mkMul(ArithExpr... t) throws Z3Exception { - CheckContextMatch(t); - return (ArithExpr) Expr.Create(this, - Native.mkMul(nCtx(), (int) t.length, AST.ArrayToNative(t))); + checkContextMatch(t); + return (ArithExpr) Expr.create(this, + Native.mkMul(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** * Create an expression representing t[0] - t[1] - .... **/ - public ArithExpr MkSub(ArithExpr[] t) throws Z3Exception + public ArithExpr mkSub(ArithExpr... t) throws Z3Exception { - CheckContextMatch(t); - return (ArithExpr) Expr.Create(this, - Native.mkSub(nCtx(), (int) t.length, AST.ArrayToNative(t))); + checkContextMatch(t); + return (ArithExpr) Expr.create(this, + Native.mkSub(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** * Create an expression representing -t. **/ - public ArithExpr MkUnaryMinus(ArithExpr t) throws Z3Exception + public ArithExpr mkUnaryMinus(ArithExpr t) throws Z3Exception { - CheckContextMatch(t); - return (ArithExpr) Expr.Create(this, - Native.mkUnaryMinus(nCtx(), t.NativeObject())); + checkContextMatch(t); + return (ArithExpr) Expr.create(this, + Native.mkUnaryMinus(nCtx(), t.getNativeObject())); } /** * Create an expression representing t1 / t2. **/ - public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) throws Z3Exception + public ArithExpr mkDiv(ArithExpr t1, ArithExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr) Expr.Create(this, - Native.mkDiv(nCtx(), t1.NativeObject(), t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return (ArithExpr) Expr.create(this, Native.mkDiv(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Create an expression representing t1 mod t2. The * arguments must have int type. **/ - public IntExpr MkMod(IntExpr t1, IntExpr t2) throws Z3Exception + public IntExpr mkMod(IntExpr t1, IntExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Native.mkMod(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new IntExpr(this, Native.mkMod(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t1 rem t2. The * arguments must have int type. **/ - public IntExpr MkRem(IntExpr t1, IntExpr t2) throws Z3Exception + public IntExpr mkRem(IntExpr t1, IntExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Native.mkRem(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new IntExpr(this, Native.mkRem(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t1 ^ t2. **/ - public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) throws Z3Exception + public ArithExpr mkPower(ArithExpr t1, ArithExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr) Expr.Create(this, - Native.mkPower(nCtx(), t1.NativeObject(), t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return (ArithExpr) Expr.create( + this, + Native.mkPower(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t1 < t2 **/ - public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) throws Z3Exception + public BoolExpr mkLt(ArithExpr t1, ArithExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkLt(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkLt(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t1 <= t2 **/ - public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) throws Z3Exception + public BoolExpr mkLe(ArithExpr t1, ArithExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkLe(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkLe(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t1 > t2 **/ - public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) throws Z3Exception + public BoolExpr mkGt(ArithExpr t1, ArithExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkGt(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkGt(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Create an expression representing t1 >= t2 **/ - public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) throws Z3Exception + public BoolExpr mkGe(ArithExpr t1, ArithExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkGe(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkGe(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** @@ -903,11 +891,12 @@ public class Context extends IDisposable * MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. The argument * must be of integer sort. **/ - public RealExpr MkInt2Real(IntExpr t) throws Z3Exception + public RealExpr mkInt2Real(IntExpr t) throws Z3Exception { - CheckContextMatch(t); - return new RealExpr(this, Native.mkInt2real(nCtx(), t.NativeObject())); + checkContextMatch(t); + return new RealExpr(this, + Native.mkInt2real(nCtx(), t.getNativeObject())); } /** @@ -915,182 +904,184 @@ public class Context extends IDisposable * follows the SMT-LIB standard for the function to_int. The argument must * be of real sort. **/ - public IntExpr MkReal2Int(RealExpr t) throws Z3Exception + public IntExpr mkReal2Int(RealExpr t) throws Z3Exception { - CheckContextMatch(t); - return new IntExpr(this, Native.mkReal2int(nCtx(), t.NativeObject())); + checkContextMatch(t); + return new IntExpr(this, Native.mkReal2int(nCtx(), t.getNativeObject())); } /** * Creates an expression that checks whether a real number is an integer. **/ - public BoolExpr MkIsInteger(RealExpr t) throws Z3Exception + public BoolExpr mkIsInteger(RealExpr t) throws Z3Exception { - CheckContextMatch(t); - return new BoolExpr(this, Native.mkIsInt(nCtx(), t.NativeObject())); + checkContextMatch(t); + return new BoolExpr(this, Native.mkIsInt(nCtx(), t.getNativeObject())); } /** * Bitwise negation. The argument must have a bit-vector * sort. **/ - public BitVecExpr MkBVNot(BitVecExpr t) throws Z3Exception + public BitVecExpr mkBVNot(BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvnot(nCtx(), t.NativeObject())); + checkContextMatch(t); + return new BitVecExpr(this, Native.mkBvnot(nCtx(), t.getNativeObject())); } /** * Take conjunction of bits in a vector, return vector of length 1. * The argument must have a bit-vector sort. **/ - public BitVecExpr MkBVRedAND(BitVecExpr t) throws Z3Exception + public BitVecExpr mkBVRedAND(BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvredand(nCtx(), t.NativeObject())); + checkContextMatch(t); + return new BitVecExpr(this, Native.mkBvredand(nCtx(), + t.getNativeObject())); } /** * Take disjunction of bits in a vector, return vector of length 1. * The argument must have a bit-vector sort. **/ - public BitVecExpr MkBVRedOR(BitVecExpr t) throws Z3Exception + public BitVecExpr mkBVRedOR(BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvredor(nCtx(), t.NativeObject())); + checkContextMatch(t); + return new BitVecExpr(this, Native.mkBvredor(nCtx(), + t.getNativeObject())); } /** * Bitwise conjunction. The arguments must have a bit-vector * sort. **/ - public BitVecExpr MkBVAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvand(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvand(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Bitwise disjunction. The arguments must have a bit-vector * sort. **/ - public BitVecExpr MkBVOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvor(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvor(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Bitwise XOR. The arguments must have a bit-vector * sort. **/ - public BitVecExpr MkBVXOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVXOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvxor(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvxor(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Bitwise NAND. The arguments must have a bit-vector * sort. **/ - public BitVecExpr MkBVNAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVNAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvnand(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvnand(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Bitwise NOR. The arguments must have a bit-vector * sort. **/ - public BitVecExpr MkBVNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvnor(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvnor(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Bitwise XNOR. The arguments must have a bit-vector * sort. **/ - public BitVecExpr MkBVXNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVXNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvxnor(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvxnor(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Standard two's complement unary minus. The arguments must have a * bit-vector sort. **/ - public BitVecExpr MkBVNeg(BitVecExpr t) throws Z3Exception + public BitVecExpr mkBVNeg(BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvneg(nCtx(), t.NativeObject())); + checkContextMatch(t); + return new BitVecExpr(this, Native.mkBvneg(nCtx(), t.getNativeObject())); } /** * Two's complement addition. The arguments must have the same * bit-vector sort. **/ - public BitVecExpr MkBVAdd(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVAdd(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvadd(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvadd(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Two's complement subtraction. The arguments must have the same * bit-vector sort. **/ - public BitVecExpr MkBVSub(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVSub(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsub(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsub(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Two's complement multiplication. The arguments must have the * same bit-vector sort. **/ - public BitVecExpr MkBVMul(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVMul(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvmul(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvmul(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1099,13 +1090,13 @@ public class Context extends IDisposable * zero, then the result is undefined. The arguments must have the same * bit-vector sort. **/ - public BitVecExpr MkBVUDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVUDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvudiv(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvudiv(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1120,13 +1111,13 @@ public class Context extends IDisposable * If t2 is zero, then the result is undefined. The arguments * must have the same bit-vector sort. **/ - public BitVecExpr MkBVSDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVSDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsdiv(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsdiv(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1135,13 +1126,13 @@ public class Context extends IDisposable * unsigned division. If t2 is zero, then the result is * undefined. The arguments must have the same bit-vector sort. **/ - public BitVecExpr MkBVURem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVURem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvurem(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvurem(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1153,13 +1144,13 @@ public class Context extends IDisposable * If t2 is zero, then the result is undefined. The arguments * must have the same bit-vector sort. **/ - public BitVecExpr MkBVSRem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVSRem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsrem(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsrem(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1167,117 +1158,117 @@ public class Context extends IDisposable * t2 is zero, then the result is undefined. The arguments must * have the same bit-vector sort. **/ - public BitVecExpr MkBVSMod(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVSMod(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsmod(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsmod(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Unsigned less-than The arguments must have the same bit-vector * sort. **/ - public BoolExpr MkBVULT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVULT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvult(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvult(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Two's complement signed less-than The arguments must have the * same bit-vector sort. **/ - public BoolExpr MkBVSLT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVSLT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvslt(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvslt(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Unsigned less-than or equal to. The arguments must have the * same bit-vector sort. **/ - public BoolExpr MkBVULE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVULE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvule(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvule(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Two's complement signed less-than or equal to. The arguments * must have the same bit-vector sort. **/ - public BoolExpr MkBVSLE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVSLE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsle(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvsle(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Unsigned greater than or equal to. The arguments must have the * same bit-vector sort. **/ - public BoolExpr MkBVUGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVUGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvuge(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvuge(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Two's complement signed greater than or equal to. The arguments * must have the same bit-vector sort. **/ - public BoolExpr MkBVSGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVSGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsge(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvsge(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Unsigned greater-than. The arguments must have the same * bit-vector sort. **/ - public BoolExpr MkBVUGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVUGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvugt(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvugt(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** * Two's complement signed greater-than. The arguments must have * the same bit-vector sort. **/ - public BoolExpr MkBVSGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BoolExpr mkBVSGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsgt(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvsgt(nCtx(), t1.getNativeObject(), + t2.getNativeObject())); } /** @@ -1289,13 +1280,13 @@ public class Context extends IDisposable * (t2). * **/ - public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkConcat(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkConcat(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkConcat(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1305,13 +1296,13 @@ public class Context extends IDisposable * n = high - low + 1. The argument must * have a bit-vector sort. **/ - public BitVecExpr MkExtract(int high, int low, BitVecExpr t) + public BitVecExpr mkExtract(int high, int low, BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BitVecExpr(this, Native.mkExtract(nCtx(), high, low, - t.NativeObject())); + t.getNativeObject())); } /** @@ -1320,12 +1311,12 @@ public class Context extends IDisposable * the size of the given bit-vector. The argument must * have a bit-vector sort. **/ - public BitVecExpr MkSignExt(int i, BitVecExpr t) throws Z3Exception + public BitVecExpr mkSignExt(int i, BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BitVecExpr(this, Native.mkSignExt(nCtx(), i, - t.NativeObject())); + t.getNativeObject())); } /** @@ -1334,24 +1325,24 @@ public class Context extends IDisposable * where \c m is the size of the given bit-vector. The argument must have a bit-vector sort. **/ - public BitVecExpr MkZeroExt(int i, BitVecExpr t) throws Z3Exception + public BitVecExpr mkZeroExt(int i, BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BitVecExpr(this, Native.mkZeroExt(nCtx(), i, - t.NativeObject())); + t.getNativeObject())); } /** * Bit-vector repetition. The argument must * have a bit-vector sort. **/ - public BitVecExpr MkRepeat(int i, BitVecExpr t) throws Z3Exception + public BitVecExpr mkRepeat(int i, BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); - return new BitVecExpr(this, - Native.mkRepeat(nCtx(), i, t.NativeObject())); + checkContextMatch(t); + return new BitVecExpr(this, Native.mkRepeat(nCtx(), i, + t.getNativeObject())); } /** @@ -1364,13 +1355,13 @@ public class Context extends IDisposable * * The arguments must have a bit-vector sort. **/ - public BitVecExpr MkBVSHL(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVSHL(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvshl(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvshl(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1383,13 +1374,13 @@ public class Context extends IDisposable * * The arguments must have a bit-vector sort. **/ - public BitVecExpr MkBVLSHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVLSHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvlshr(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvlshr(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1403,37 +1394,37 @@ public class Context extends IDisposable * * The arguments must have a bit-vector sort. **/ - public BitVecExpr MkBVASHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + public BitVecExpr mkBVASHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvashr(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new BitVecExpr(this, Native.mkBvashr(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** * Rotate Left. Rotate bits of \c t to the left \c i times. The * argument must have a bit-vector sort. **/ - public BitVecExpr MkBVRotateLeft(int i, BitVecExpr t) throws Z3Exception + public BitVecExpr mkBVRotateLeft(int i, BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BitVecExpr(this, Native.mkRotateLeft(nCtx(), i, - t.NativeObject())); + t.getNativeObject())); } /** * Rotate Right. Rotate bits of \c t to the right \c i times. The * argument must have a bit-vector sort. **/ - public BitVecExpr MkBVRotateRight(int i, BitVecExpr t) throws Z3Exception + public BitVecExpr mkBVRotateRight(int i, BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BitVecExpr(this, Native.mkRotateRight(nCtx(), i, - t.NativeObject())); + t.getNativeObject())); } /** @@ -1441,14 +1432,14 @@ public class Context extends IDisposable * times. The arguments must have the same bit-vector * sort. **/ - public BitVecExpr MkBVRotateLeft(BitVecExpr t1, BitVecExpr t2) + public BitVecExpr mkBVRotateLeft(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); + checkContextMatch(t1); + checkContextMatch(t2); return new BitVecExpr(this, Native.mkExtRotateLeft(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1456,14 +1447,14 @@ public class Context extends IDisposable * right times. The arguments must have the same * bit-vector sort. **/ - public BitVecExpr MkBVRotateRight(BitVecExpr t1, BitVecExpr t2) + public BitVecExpr mkBVRotateRight(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); + checkContextMatch(t1); + checkContextMatch(t2); return new BitVecExpr(this, Native.mkExtRotateRight(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -1474,12 +1465,12 @@ public class Context extends IDisposable * * The argument must be of integer sort. **/ - public BitVecExpr MkInt2BV(int n, IntExpr t) throws Z3Exception + public BitVecExpr mkInt2BV(int n, IntExpr t) throws Z3Exception { - CheckContextMatch(t); - return new BitVecExpr(this, - Native.mkInt2bv(nCtx(), n, t.NativeObject())); + checkContextMatch(t); + return new BitVecExpr(this, Native.mkInt2bv(nCtx(), n, + t.getNativeObject())); } /** @@ -1496,11 +1487,11 @@ public class Context extends IDisposable * * The argument must be of bit-vector sort. **/ - public IntExpr MkBV2Int(BitVecExpr t, boolean signed) throws Z3Exception + public IntExpr mkBV2Int(BitVecExpr t, boolean signed) throws Z3Exception { - CheckContextMatch(t); - return new IntExpr(this, Native.mkBv2int(nCtx(), t.NativeObject(), + checkContextMatch(t); + return new IntExpr(this, Native.mkBv2int(nCtx(), t.getNativeObject(), (signed) ? true : false)); } @@ -1508,133 +1499,133 @@ public class Context extends IDisposable * Create a predicate that checks that the bit-wise addition does not * overflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVAddNoOverflow(BitVecExpr t1, BitVecExpr t2, + public BoolExpr mkBVAddNoOverflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, - Native.mkBvaddNoOverflow(nCtx(), t1.NativeObject(), - t2.NativeObject(), (isSigned) ? true : false)); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvaddNoOverflow(nCtx(), t1 + .getNativeObject(), t2.getNativeObject(), (isSigned) ? true + : false)); } /** * Create a predicate that checks that the bit-wise addition does not * underflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) + public BoolExpr mkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); + checkContextMatch(t1); + checkContextMatch(t2); return new BoolExpr(this, Native.mkBvaddNoUnderflow(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** * Create a predicate that checks that the bit-wise subtraction does not * overflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVSubNoOverflow(BitVecExpr t1, BitVecExpr t2) + public BoolExpr mkBVSubNoOverflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); + checkContextMatch(t1); + checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsubNoOverflow(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** * Create a predicate that checks that the bit-wise subtraction does not * underflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, + public BoolExpr mkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, - Native.mkBvsubNoUnderflow(nCtx(), t1.NativeObject(), - t2.NativeObject(), (isSigned) ? true : false)); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvsubNoUnderflow(nCtx(), t1 + .getNativeObject(), t2.getNativeObject(), (isSigned) ? true + : false)); } /** * Create a predicate that checks that the bit-wise signed division does not * overflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) + public BoolExpr mkBVSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); + checkContextMatch(t1); + checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsdivNoOverflow(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** * Create a predicate that checks that the bit-wise negation does not * overflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVNegNoOverflow(BitVecExpr t) throws Z3Exception + public BoolExpr mkBVNegNoOverflow(BitVecExpr t) throws Z3Exception { - CheckContextMatch(t); + checkContextMatch(t); return new BoolExpr(this, Native.mkBvnegNoOverflow(nCtx(), - t.NativeObject())); + t.getNativeObject())); } /** * Create a predicate that checks that the bit-wise multiplication does not * overflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVMulNoOverflow(BitVecExpr t1, BitVecExpr t2, + public BoolExpr mkBVMulNoOverflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, - Native.mkBvmulNoOverflow(nCtx(), t1.NativeObject(), - t2.NativeObject(), (isSigned) ? true : false)); + checkContextMatch(t1); + checkContextMatch(t2); + return new BoolExpr(this, Native.mkBvmulNoOverflow(nCtx(), t1 + .getNativeObject(), t2.getNativeObject(), (isSigned) ? true + : false)); } /** * Create a predicate that checks that the bit-wise multiplication does not * underflow. The arguments must be of bit-vector sort. **/ - public BoolExpr MkBVMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) + public BoolExpr mkBVMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); + checkContextMatch(t1); + checkContextMatch(t2); return new BoolExpr(this, Native.mkBvmulNoUnderflow(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** * Create an array constant. **/ - public ArrayExpr MkArrayConst(Symbol name, Sort domain, Sort range) + public ArrayExpr mkArrayConst(Symbol name, Sort domain, Sort range) throws Z3Exception { - return (ArrayExpr) MkConst(name, MkArraySort(domain, range)); + return (ArrayExpr) mkConst(name, mkArraySort(domain, range)); } /** * Create an array constant. **/ - public ArrayExpr MkArrayConst(String name, Sort domain, Sort range) + public ArrayExpr mkArrayConst(String name, Sort domain, Sort range) throws Z3Exception { - return (ArrayExpr) MkConst(MkSymbol(name), MkArraySort(domain, range)); + return (ArrayExpr) mkConst(mkSymbol(name), mkArraySort(domain, range)); } /** @@ -1646,13 +1637,15 @@ public class Context extends IDisposable * domain. The sort of the result is range. * **/ - public Expr MkSelect(ArrayExpr a, Expr i) throws Z3Exception + public Expr mkSelect(ArrayExpr a, Expr i) throws Z3Exception { - CheckContextMatch(a); - CheckContextMatch(i); - return Expr.Create(this, - Native.mkSelect(nCtx(), a.NativeObject(), i.NativeObject())); + checkContextMatch(a); + checkContextMatch(i); + return Expr.create( + this, + Native.mkSelect(nCtx(), a.getNativeObject(), + i.getNativeObject())); } /** @@ -1668,14 +1661,14 @@ public class Context extends IDisposable * with respect to i may be a different value). **/ - public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) throws Z3Exception + public ArrayExpr mkStore(ArrayExpr a, Expr i, Expr v) throws Z3Exception { - CheckContextMatch(a); - CheckContextMatch(i); - CheckContextMatch(v); - return new ArrayExpr(this, Native.mkStore(nCtx(), a.NativeObject(), - i.NativeObject(), v.NativeObject())); + checkContextMatch(a); + checkContextMatch(i); + checkContextMatch(v); + return new ArrayExpr(this, Native.mkStore(nCtx(), a.getNativeObject(), + i.getNativeObject(), v.getNativeObject())); } /** @@ -1684,13 +1677,13 @@ public class Context extends IDisposable * v. * **/ - public ArrayExpr MkConstArray(Sort domain, Expr v) throws Z3Exception + public ArrayExpr mkConstArray(Sort domain, Expr v) throws Z3Exception { - CheckContextMatch(domain); - CheckContextMatch(v); + checkContextMatch(domain); + checkContextMatch(v); return new ArrayExpr(this, Native.mkConstArray(nCtx(), - domain.NativeObject(), v.NativeObject())); + domain.getNativeObject(), v.getNativeObject())); } /** @@ -1702,14 +1695,14 @@ public class Context extends IDisposable * [domain_i -> range]. **/ - public ArrayExpr MkMap(FuncDecl f, ArrayExpr[] args) throws Z3Exception + public ArrayExpr mkMap(FuncDecl f, ArrayExpr... args) throws Z3Exception { - CheckContextMatch(f); - CheckContextMatch(args); - return (ArrayExpr) Expr.Create(this, Native.mkMap(nCtx(), - f.NativeObject(), AST.ArrayLength(args), - AST.ArrayToNative(args))); + checkContextMatch(f); + checkContextMatch(args); + return (ArrayExpr) Expr.create(this, Native.mkMap(nCtx(), + f.getNativeObject(), AST.arrayLength(args), + AST.arrayToNative(args))); } /** @@ -1717,151 +1710,151 @@ public class Context extends IDisposable * value, for arrays that can be represented as finite maps with a default * range value. **/ - public Expr MkTermArray(ArrayExpr array) throws Z3Exception + public Expr mkTermArray(ArrayExpr array) throws Z3Exception { - CheckContextMatch(array); - return Expr.Create(this, - Native.mkArrayDefault(nCtx(), array.NativeObject())); + checkContextMatch(array); + return Expr.create(this, + Native.mkArrayDefault(nCtx(), array.getNativeObject())); } /** * Create a set type. **/ - public SetSort MkSetSort(Sort ty) throws Z3Exception + public SetSort mkSetSort(Sort ty) throws Z3Exception { - CheckContextMatch(ty); + checkContextMatch(ty); return new SetSort(this, ty); } /** * Create an empty set. **/ - public Expr MkEmptySet(Sort domain) throws Z3Exception + public Expr mkEmptySet(Sort domain) throws Z3Exception { - CheckContextMatch(domain); - return Expr.Create(this, - Native.mkEmptySet(nCtx(), domain.NativeObject())); + checkContextMatch(domain); + return Expr.create(this, + Native.mkEmptySet(nCtx(), domain.getNativeObject())); } /** * Create the full set. **/ - public Expr MkFullSet(Sort domain) throws Z3Exception + public Expr mkFullSet(Sort domain) throws Z3Exception { - CheckContextMatch(domain); - return Expr.Create(this, - Native.mkFullSet(nCtx(), domain.NativeObject())); + checkContextMatch(domain); + return Expr.create(this, + Native.mkFullSet(nCtx(), domain.getNativeObject())); } /** * Add an element to the set. **/ - public Expr MkSetAdd(Expr set, Expr element) throws Z3Exception + public Expr mkSetAdd(Expr set, Expr element) throws Z3Exception { - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create( + checkContextMatch(set); + checkContextMatch(element); + return Expr.create( this, - Native.mkSetAdd(nCtx(), set.NativeObject(), - element.NativeObject())); + Native.mkSetAdd(nCtx(), set.getNativeObject(), + element.getNativeObject())); } /** * Remove an element from a set. **/ - public Expr MkSetDel(Expr set, Expr element) throws Z3Exception + public Expr mkSetDel(Expr set, Expr element) throws Z3Exception { - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create( + checkContextMatch(set); + checkContextMatch(element); + return Expr.create( this, - Native.mkSetDel(nCtx(), set.NativeObject(), - element.NativeObject())); + Native.mkSetDel(nCtx(), set.getNativeObject(), + element.getNativeObject())); } /** * Take the union of a list of sets. **/ - public Expr MkSetUnion(Expr[] args) throws Z3Exception + public Expr mkSetUnion(Expr... args) throws Z3Exception { - CheckContextMatch(args); - return Expr.Create( + checkContextMatch(args); + return Expr.create( this, Native.mkSetUnion(nCtx(), (int) args.length, - AST.ArrayToNative(args))); + AST.arrayToNative(args))); } /** * Take the intersection of a list of sets. **/ - public Expr MkSetIntersection(Expr[] args) throws Z3Exception + public Expr mkSetIntersection(Expr... args) throws Z3Exception { - CheckContextMatch(args); - return Expr.Create( + checkContextMatch(args); + return Expr.create( this, Native.mkSetIntersect(nCtx(), (int) args.length, - AST.ArrayToNative(args))); + AST.arrayToNative(args))); } /** * Take the difference between two sets. **/ - public Expr MkSetDifference(Expr arg1, Expr arg2) throws Z3Exception + public Expr mkSetDifference(Expr arg1, Expr arg2) throws Z3Exception { - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create( + checkContextMatch(arg1); + checkContextMatch(arg2); + return Expr.create( this, - Native.mkSetDifference(nCtx(), arg1.NativeObject(), - arg2.NativeObject())); + Native.mkSetDifference(nCtx(), arg1.getNativeObject(), + arg2.getNativeObject())); } /** * Take the complement of a set. **/ - public Expr MkSetComplement(Expr arg) throws Z3Exception + public Expr mkSetComplement(Expr arg) throws Z3Exception { - CheckContextMatch(arg); - return Expr.Create(this, - Native.mkSetComplement(nCtx(), arg.NativeObject())); + checkContextMatch(arg); + return Expr.create(this, + Native.mkSetComplement(nCtx(), arg.getNativeObject())); } /** * Check for set membership. **/ - public Expr MkSetMembership(Expr elem, Expr set) throws Z3Exception + public Expr mkSetMembership(Expr elem, Expr set) throws Z3Exception { - CheckContextMatch(elem); - CheckContextMatch(set); - return Expr.Create( + checkContextMatch(elem); + checkContextMatch(set); + return Expr.create( this, - Native.mkSetMember(nCtx(), elem.NativeObject(), - set.NativeObject())); + Native.mkSetMember(nCtx(), elem.getNativeObject(), + set.getNativeObject())); } /** * Check for subsetness of sets. **/ - public Expr MkSetSubset(Expr arg1, Expr arg2) throws Z3Exception + public Expr mkSetSubset(Expr arg1, Expr arg2) throws Z3Exception { - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create( + checkContextMatch(arg1); + checkContextMatch(arg2); + return Expr.create( this, - Native.mkSetSubset(nCtx(), arg1.NativeObject(), - arg2.NativeObject())); + Native.mkSetSubset(nCtx(), arg1.getNativeObject(), + arg2.getNativeObject())); } /** @@ -1875,12 +1868,12 @@ public class Context extends IDisposable * @return A Term with value and sort **/ - public Expr MkNumeral(String v, Sort ty) throws Z3Exception + public Expr mkNumeral(String v, Sort ty) throws Z3Exception { - CheckContextMatch(ty); - return Expr - .Create(this, Native.mkNumeral(nCtx(), v, ty.NativeObject())); + checkContextMatch(ty); + return Expr.create(this, + Native.mkNumeral(nCtx(), v, ty.getNativeObject())); } /** @@ -1893,11 +1886,11 @@ public class Context extends IDisposable * @return A Term with value and type **/ - public Expr MkNumeral(int v, Sort ty) throws Z3Exception + public Expr mkNumeral(int v, Sort ty) throws Z3Exception { - CheckContextMatch(ty); - return Expr.Create(this, Native.mkInt(nCtx(), v, ty.NativeObject())); + checkContextMatch(ty); + return Expr.create(this, Native.mkInt(nCtx(), v, ty.getNativeObject())); } /** @@ -1910,11 +1903,12 @@ public class Context extends IDisposable * @return A Term with value and type **/ - public Expr MkNumeral(long v, Sort ty) throws Z3Exception + public Expr mkNumeral(long v, Sort ty) throws Z3Exception { - CheckContextMatch(ty); - return Expr.Create(this, Native.mkInt64(nCtx(), v, ty.NativeObject())); + checkContextMatch(ty); + return Expr.create(this, + Native.mkInt64(nCtx(), v, ty.getNativeObject())); } /** @@ -1924,7 +1918,7 @@ public class Context extends IDisposable * @return A Term with value / * and sort Real **/ - public RatNum MkReal(int num, int den) throws Z3Exception + public RatNum mkReal(int num, int den) throws Z3Exception { if (den == 0) throw new Z3Exception("Denominator is zero"); @@ -1938,11 +1932,11 @@ public class Context extends IDisposable * * @return A Term with value and sort Real **/ - public RatNum MkReal(String v) throws Z3Exception + public RatNum mkReal(String v) throws Z3Exception { - return new RatNum(this, Native.mkNumeral(nCtx(), v, RealSort() - .NativeObject())); + return new RatNum(this, Native.mkNumeral(nCtx(), v, getRealSort() + .getNativeObject())); } /** @@ -1950,11 +1944,11 @@ public class Context extends IDisposable * * @return A Term with value and sort Real **/ - public RatNum MkReal(int v) throws Z3Exception + public RatNum mkReal(int v) throws Z3Exception { - return new RatNum(this, Native.mkInt(nCtx(), v, RealSort() - .NativeObject())); + return new RatNum(this, Native.mkInt(nCtx(), v, getRealSort() + .getNativeObject())); } /** @@ -1962,22 +1956,22 @@ public class Context extends IDisposable * * @return A Term with value and sort Real **/ - public RatNum MkReal(long v) throws Z3Exception + public RatNum mkReal(long v) throws Z3Exception { - return new RatNum(this, Native.mkInt64(nCtx(), v, RealSort() - .NativeObject())); + return new RatNum(this, Native.mkInt64(nCtx(), v, getRealSort() + .getNativeObject())); } /** * Create an integer numeral. A string representing the Term * value in decimal notation. **/ - public IntNum MkInt(String v) throws Z3Exception + public IntNum mkInt(String v) throws Z3Exception { - return new IntNum(this, Native.mkNumeral(nCtx(), v, IntSort() - .NativeObject())); + return new IntNum(this, Native.mkNumeral(nCtx(), v, getIntSort() + .getNativeObject())); } /** @@ -1985,11 +1979,11 @@ public class Context extends IDisposable * * @return A Term with value and sort Integer **/ - public IntNum MkInt(int v) throws Z3Exception + public IntNum mkInt(int v) throws Z3Exception { - return new IntNum(this, Native.mkInt(nCtx(), v, IntSort() - .NativeObject())); + return new IntNum(this, Native.mkInt(nCtx(), v, getIntSort() + .getNativeObject())); } /** @@ -1997,11 +1991,11 @@ public class Context extends IDisposable * * @return A Term with value and sort Integer **/ - public IntNum MkInt(long v) throws Z3Exception + public IntNum mkInt(long v) throws Z3Exception { - return new IntNum(this, Native.mkInt64(nCtx(), v, IntSort() - .NativeObject())); + return new IntNum(this, Native.mkInt64(nCtx(), v, getIntSort() + .getNativeObject())); } /** @@ -2009,30 +2003,30 @@ public class Context extends IDisposable * value in decimal notation. the size of the * bit-vector **/ - public BitVecNum MkBV(String v, int size) throws Z3Exception + public BitVecNum mkBV(String v, int size) throws Z3Exception { - return (BitVecNum) MkNumeral(v, MkBitVecSort(size)); + return (BitVecNum) mkNumeral(v, mkBitVecSort(size)); } /** * Create a bit-vector numeral. value of the * numeral. the size of the bit-vector **/ - public BitVecNum MkBV(int v, int size) throws Z3Exception + public BitVecNum mkBV(int v, int size) throws Z3Exception { - return (BitVecNum) MkNumeral(v, MkBitVecSort(size)); + return (BitVecNum) mkNumeral(v, mkBitVecSort(size)); } /** * Create a bit-vector numeral. value of the * numeral. * the size of the bit-vector **/ - public BitVecNum MkBV(long v, int size) throws Z3Exception + public BitVecNum mkBV(long v, int size) throws Z3Exception { - return (BitVecNum) MkNumeral(v, MkBitVecSort(size)); + return (BitVecNum) mkNumeral(v, mkBitVecSort(size)); } /** @@ -2054,7 +2048,7 @@ public class Context extends IDisposable * name="quantifierID">optional symbol to track quantifier. optional symbol to track skolem constants. **/ - public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, + public Quantifier mkForall(Sort[] sorts, Symbol[] names, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { @@ -2066,7 +2060,7 @@ public class Context extends IDisposable /** * Create a universal Quantifier. **/ - public Quantifier MkForall(Expr[] boundConstants, Expr body, int weight, + public Quantifier mkForall(Expr[] boundConstants, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { @@ -2079,7 +2073,7 @@ public class Context extends IDisposable * Create an existential Quantifier. **/ - public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, + public Quantifier mkExists(Sort[] sorts, Symbol[] names, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { @@ -2091,7 +2085,7 @@ public class Context extends IDisposable /** * Create an existential Quantifier. **/ - public Quantifier MkExists(Expr[] boundConstants, Expr body, int weight, + public Quantifier mkExists(Expr[] boundConstants, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { @@ -2103,33 +2097,33 @@ public class Context extends IDisposable /** * Create a Quantifier. **/ - public Quantifier MkQuantifier(boolean universal, Sort[] sorts, + public Quantifier mkQuantifier(boolean universal, Sort[] sorts, Symbol[] names, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { if (universal) - return MkForall(sorts, names, body, weight, patterns, noPatterns, + return mkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); else - return MkExists(sorts, names, body, weight, patterns, noPatterns, + return mkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); } /** * Create a Quantifier. **/ - public Quantifier MkQuantifier(boolean universal, Expr[] boundConstants, + public Quantifier mkQuantifier(boolean universal, Expr[] boundConstants, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { if (universal) - return MkForall(boundConstants, body, weight, patterns, noPatterns, + return mkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); else - return MkExists(boundConstants, body, weight, patterns, noPatterns, + return mkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); } @@ -2161,14 +2155,14 @@ public class Context extends IDisposable * * @return A string representation of the benchmark. **/ - public String BenchmarkToSMTString(String name, String logic, + public String benchmarkToSMTString(String name, String logic, String status, String attributes, BoolExpr[] assumptions, BoolExpr formula) throws Z3Exception { return Native.benchmarkToSmtlibString(nCtx(), name, logic, status, attributes, (int) assumptions.length, - AST.ArrayToNative(assumptions), formula.NativeObject()); + AST.arrayToNative(assumptions), formula.getNativeObject()); } /** @@ -2180,46 +2174,46 @@ public class Context extends IDisposable * name="decls"/>. This is a useful feature since we can use arbitrary names * to reference sorts and declarations. **/ - public void ParseSMTLIBString(String str, Symbol[] sortNames, Sort[] sorts, + public void parseSMTLIBString(String str, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) throws Z3Exception { - int csn = Symbol.ArrayLength(sortNames); - int cs = Sort.ArrayLength(sorts); - int cdn = Symbol.ArrayLength(declNames); - int cd = AST.ArrayLength(decls); + int csn = Symbol.arrayLength(sortNames); + int cs = Sort.arrayLength(sorts); + int cdn = Symbol.arrayLength(declNames); + int cd = AST.arrayLength(decls); if (csn != cs || cdn != cd) throw new Z3Exception("Argument size mismatch"); - Native.parseSmtlibString(nCtx(), str, AST.ArrayLength(sorts), - Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), - AST.ArrayToNative(decls)); + Native.parseSmtlibString(nCtx(), str, AST.arrayLength(sorts), + Symbol.arrayToNative(sortNames), AST.arrayToNative(sorts), + AST.arrayLength(decls), Symbol.arrayToNative(declNames), + AST.arrayToNative(decls)); } /** * Parse the given file using the SMT-LIB parser. **/ - public void ParseSMTLIBFile(String fileName, Symbol[] sortNames, + public void parseSMTLIBFile(String fileName, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) throws Z3Exception { - int csn = Symbol.ArrayLength(sortNames); - int cs = Sort.ArrayLength(sorts); - int cdn = Symbol.ArrayLength(declNames); - int cd = AST.ArrayLength(decls); + int csn = Symbol.arrayLength(sortNames); + int cs = Sort.arrayLength(sorts); + int cdn = Symbol.arrayLength(declNames); + int cd = AST.arrayLength(decls); if (csn != cs || cdn != cd) throw new Z3Exception("Argument size mismatch"); - Native.parseSmtlibFile(nCtx(), fileName, AST.ArrayLength(sorts), - Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), - AST.ArrayToNative(decls)); + Native.parseSmtlibFile(nCtx(), fileName, AST.arrayLength(sorts), + Symbol.arrayToNative(sortNames), AST.arrayToNative(sorts), + AST.arrayLength(decls), Symbol.arrayToNative(declNames), + AST.arrayToNative(decls)); } /** * The number of SMTLIB formulas parsed by the last call to * ParseSMTLIBString or ParseSMTLIBFile. **/ - public int NumSMTLIBFormulas() throws Z3Exception + public int getNumSMTLIBFormulas() throws Z3Exception { return Native.getSmtlibNumFormulas(nCtx()); } @@ -2228,13 +2222,13 @@ public class Context extends IDisposable * The formulas parsed by the last call to ParseSMTLIBString or * ParseSMTLIBFile. **/ - public BoolExpr[] SMTLIBFormulas() throws Z3Exception + public BoolExpr[] getSMTLIBFormulas() throws Z3Exception { - int n = NumSMTLIBFormulas(); + int n = getNumSMTLIBFormulas(); BoolExpr[] res = new BoolExpr[n]; for (int i = 0; i < n; i++) - res[i] = (BoolExpr) Expr.Create(this, + res[i] = (BoolExpr) Expr.create(this, Native.getSmtlibFormula(nCtx(), i)); return res; } @@ -2243,7 +2237,7 @@ public class Context extends IDisposable * The number of SMTLIB assumptions parsed by the last call to * ParseSMTLIBString or ParseSMTLIBFile. **/ - public int NumSMTLIBAssumptions() throws Z3Exception + public int getNumSMTLIBAssumptions() throws Z3Exception { return Native.getSmtlibNumAssumptions(nCtx()); } @@ -2252,13 +2246,13 @@ public class Context extends IDisposable * The assumptions parsed by the last call to ParseSMTLIBString * or ParseSMTLIBFile. **/ - public BoolExpr[] SMTLIBAssumptions() throws Z3Exception + public BoolExpr[] getSMTLIBAssumptions() throws Z3Exception { - int n = NumSMTLIBAssumptions(); + int n = getNumSMTLIBAssumptions(); BoolExpr[] res = new BoolExpr[n]; for (int i = 0; i < n; i++) - res[i] = (BoolExpr) Expr.Create(this, + res[i] = (BoolExpr) Expr.create(this, Native.getSmtlibAssumption(nCtx(), i)); return res; } @@ -2267,7 +2261,7 @@ public class Context extends IDisposable * The number of SMTLIB declarations parsed by the last call to * ParseSMTLIBString or ParseSMTLIBFile. **/ - public int NumSMTLIBDecls() throws Z3Exception + public int getNumSMTLIBDecls() throws Z3Exception { return Native.getSmtlibNumDecls(nCtx()); } @@ -2276,10 +2270,10 @@ public class Context extends IDisposable * The declarations parsed by the last call to * ParseSMTLIBString or ParseSMTLIBFile. **/ - public FuncDecl[] SMTLIBDecls() throws Z3Exception + public FuncDecl[] getSMTLIBDecls() throws Z3Exception { - int n = NumSMTLIBDecls(); + int n = getNumSMTLIBDecls(); FuncDecl[] res = new FuncDecl[n]; for (int i = 0; i < n; i++) res[i] = new FuncDecl(this, Native.getSmtlibDecl(nCtx(), i)); @@ -2290,7 +2284,7 @@ public class Context extends IDisposable * The number of SMTLIB sorts parsed by the last call to * ParseSMTLIBString or ParseSMTLIBFile. **/ - public int NumSMTLIBSorts() throws Z3Exception + public int getNumSMTLIBSorts() throws Z3Exception { return Native.getSmtlibNumSorts(nCtx()); } @@ -2299,13 +2293,13 @@ public class Context extends IDisposable * The declarations parsed by the last call to * ParseSMTLIBString or ParseSMTLIBFile. **/ - public Sort[] SMTLIBSorts() throws Z3Exception + public Sort[] getSMTLIBSorts() throws Z3Exception { - int n = NumSMTLIBSorts(); + int n = getNumSMTLIBSorts(); Sort[] res = new Sort[n]; for (int i = 0; i < n; i++) - res[i] = Sort.Create(this, Native.getSmtlibSort(nCtx(), i)); + res[i] = Sort.create(this, Native.getSmtlibSort(nCtx(), i)); return res; } @@ -2316,43 +2310,43 @@ public class Context extends IDisposable * @return A conjunction of assertions in the scope (up to push/pop) at the * end of the string. **/ - public BoolExpr ParseSMTLIB2String(String str, Symbol[] sortNames, + public BoolExpr parseSMTLIB2String(String str, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) throws Z3Exception { - int csn = Symbol.ArrayLength(sortNames); - int cs = Sort.ArrayLength(sorts); - int cdn = Symbol.ArrayLength(declNames); - int cd = AST.ArrayLength(decls); + int csn = Symbol.arrayLength(sortNames); + int cs = Sort.arrayLength(sorts); + int cdn = Symbol.arrayLength(declNames); + int cd = AST.arrayLength(decls); if (csn != cs || cdn != cd) throw new Z3Exception("Argument size mismatch"); - return (BoolExpr) Expr.Create(this, Native.parseSmtlib2String(nCtx(), - str, AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), - AST.ArrayToNative(sorts), AST.ArrayLength(decls), - Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + return (BoolExpr) Expr.create(this, Native.parseSmtlib2String(nCtx(), + str, AST.arrayLength(sorts), Symbol.arrayToNative(sortNames), + AST.arrayToNative(sorts), AST.arrayLength(decls), + Symbol.arrayToNative(declNames), AST.arrayToNative(decls))); } /** * Parse the given file using the SMT-LIB2 parser. **/ - public BoolExpr ParseSMTLIB2File(String fileName, Symbol[] sortNames, + public BoolExpr parseSMTLIB2File(String fileName, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) throws Z3Exception { - int csn = Symbol.ArrayLength(sortNames); - int cs = Sort.ArrayLength(sorts); - int cdn = Symbol.ArrayLength(declNames); - int cd = AST.ArrayLength(decls); + int csn = Symbol.arrayLength(sortNames); + int cs = Sort.arrayLength(sorts); + int cdn = Symbol.arrayLength(declNames); + int cd = AST.arrayLength(decls); if (csn != cs || cdn != cd) throw new Z3Exception("Argument size mismatch"); - return (BoolExpr) Expr.Create(this, Native.parseSmtlib2File(nCtx(), - fileName, AST.ArrayLength(sorts), - Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), - AST.ArrayToNative(decls))); + return (BoolExpr) Expr.create(this, Native.parseSmtlib2File(nCtx(), + fileName, AST.arrayLength(sorts), + Symbol.arrayToNative(sortNames), AST.arrayToNative(sorts), + AST.arrayLength(decls), Symbol.arrayToNative(declNames), + AST.arrayToNative(decls))); } /** @@ -2364,7 +2358,7 @@ public class Context extends IDisposable * name="proofs">Indicates whether proof generation should be * enabled. **/ - public Goal MkGoal(boolean models, boolean unsatCores, boolean proofs) + public Goal mkGoal(boolean models, boolean unsatCores, boolean proofs) throws Z3Exception { @@ -2374,7 +2368,7 @@ public class Context extends IDisposable /** * Creates a new ParameterSet. **/ - public Params MkParams() throws Z3Exception + public Params mkParams() throws Z3Exception { return new Params(this); @@ -2383,7 +2377,7 @@ public class Context extends IDisposable /** * The number of supported tactics. **/ - public int NumTactics() throws Z3Exception + public int getNumTactics() throws Z3Exception { return Native.getNumTactics(nCtx()); } @@ -2391,10 +2385,10 @@ public class Context extends IDisposable /** * The names of all supported tactics. **/ - public String[] TacticNames() throws Z3Exception + public String[] getTacticNames() throws Z3Exception { - int n = NumTactics(); + int n = getNumTactics(); String[] res = new String[n]; for (int i = 0; i < n; i++) res[i] = Native.getTacticName(nCtx(), i); @@ -2405,7 +2399,7 @@ public class Context extends IDisposable * Returns a string containing a description of the tactic with the given * name. **/ - public String TacticDescription(String name) throws Z3Exception + public String getTacticDescription(String name) throws Z3Exception { return Native.tacticGetDescr(nCtx(), name); @@ -2414,7 +2408,7 @@ public class Context extends IDisposable /** * Creates a new Tactic. **/ - public Tactic MkTactic(String name) throws Z3Exception + public Tactic mkTactic(String name) throws Z3Exception { return new Tactic(this, name); @@ -2424,28 +2418,29 @@ public class Context extends IDisposable * Create a tactic that applies to a Goal and then * to every subgoal produced by . **/ - public Tactic AndThen(Tactic t1, Tactic t2, Tactic[] ts) throws Z3Exception + public Tactic andThen(Tactic t1, Tactic t2, Tactic... ts) + throws Z3Exception { - - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(ts); + checkContextMatch(t1); + checkContextMatch(t2); + checkContextMatch(ts); long last = 0; if (ts != null && ts.length > 0) { - last = ts[ts.length - 1].NativeObject(); + last = ts[ts.length - 1].getNativeObject(); for (int i = ts.length - 2; i >= 0; i--) - last = Native.tacticAndThen(nCtx(), ts[i].NativeObject(), last); + last = Native.tacticAndThen(nCtx(), ts[i].getNativeObject(), + last); } if (last != 0) { - last = Native.tacticAndThen(nCtx(), t2.NativeObject(), last); + last = Native.tacticAndThen(nCtx(), t2.getNativeObject(), last); return new Tactic(this, Native.tacticAndThen(nCtx(), - t1.NativeObject(), last)); + t1.getNativeObject(), last)); } else return new Tactic(this, Native.tacticAndThen(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -2453,10 +2448,9 @@ public class Context extends IDisposable * to every subgoal produced by . * Shorthand for AndThen. **/ - public Tactic Then(Tactic t1, Tactic t2, Tactic[] ts) throws Z3Exception + public Tactic then(Tactic t1, Tactic t2, Tactic... ts) throws Z3Exception { - - return AndThen(t1, t2, ts); + return andThen(t1, t2, ts); } /** @@ -2464,13 +2458,13 @@ public class Context extends IDisposable * it fails then returns the result of applied to the * Goal. **/ - public Tactic OrElse(Tactic t1, Tactic t2) throws Z3Exception + public Tactic orElse(Tactic t1, Tactic t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Native.tacticOrElse(nCtx(), t1.NativeObject(), - t2.NativeObject())); + checkContextMatch(t1); + checkContextMatch(t2); + return new Tactic(this, Native.tacticOrElse(nCtx(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -2479,12 +2473,12 @@ public class Context extends IDisposable * terminate within milliseconds, then it fails. * **/ - public Tactic TryFor(Tactic t, int ms) throws Z3Exception + public Tactic tryFor(Tactic t, int ms) throws Z3Exception { - CheckContextMatch(t); - return new Tactic(this, Native.tacticTryFor(nCtx(), t.NativeObject(), - ms)); + checkContextMatch(t); + return new Tactic(this, Native.tacticTryFor(nCtx(), + t.getNativeObject(), ms)); } /** @@ -2493,13 +2487,13 @@ public class Context extends IDisposable * name="p"/> evaluates to false, then the new tactic behaves like the * skip tactic. **/ - public Tactic When(Probe p, Tactic t) throws Z3Exception + public Tactic when(Probe p, Tactic t) throws Z3Exception { - CheckContextMatch(t); - CheckContextMatch(p); - return new Tactic(this, Native.tacticWhen(nCtx(), p.NativeObject(), - t.NativeObject())); + checkContextMatch(t); + checkContextMatch(p); + return new Tactic(this, Native.tacticWhen(nCtx(), p.getNativeObject(), + t.getNativeObject())); } /** @@ -2507,14 +2501,14 @@ public class Context extends IDisposable * probe evaluates to true and * otherwise. **/ - public Tactic Cond(Probe p, Tactic t1, Tactic t2) throws Z3Exception + public Tactic cond(Probe p, Tactic t1, Tactic t2) throws Z3Exception { - CheckContextMatch(p); - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Native.tacticCond(nCtx(), p.NativeObject(), - t1.NativeObject(), t2.NativeObject())); + checkContextMatch(p); + checkContextMatch(t1); + checkContextMatch(t2); + return new Tactic(this, Native.tacticCond(nCtx(), p.getNativeObject(), + t1.getNativeObject(), t2.getNativeObject())); } /** @@ -2522,18 +2516,18 @@ public class Context extends IDisposable * is not modified anymore or the maximum number of iterations is reached. **/ - public Tactic Repeat(Tactic t, int max) throws Z3Exception + public Tactic repeat(Tactic t, int max) throws Z3Exception { - CheckContextMatch(t); - return new Tactic(this, Native.tacticRepeat(nCtx(), t.NativeObject(), - max)); + checkContextMatch(t); + return new Tactic(this, Native.tacticRepeat(nCtx(), + t.getNativeObject(), max)); } /** * Create a tactic that just returns the given goal. **/ - public Tactic Skip() throws Z3Exception + public Tactic skip() throws Z3Exception { return new Tactic(this, Native.tacticSkip(nCtx())); @@ -2542,7 +2536,7 @@ public class Context extends IDisposable /** * Create a tactic always fails. **/ - public Tactic Fail() throws Z3Exception + public Tactic fail() throws Z3Exception { return new Tactic(this, Native.tacticFail(nCtx())); @@ -2552,20 +2546,20 @@ public class Context extends IDisposable * Create a tactic that fails if the probe evaluates to * false. **/ - public Tactic FailIf(Probe p) throws Z3Exception + public Tactic failIf(Probe p) throws Z3Exception { - CheckContextMatch(p); - return new Tactic(this, Native.tacticFailIf(nCtx(), p.NativeObject())); + checkContextMatch(p); + return new Tactic(this, + Native.tacticFailIf(nCtx(), p.getNativeObject())); } /** * Create a tactic that fails if the goal is not triviall satisfiable (i.e., * empty) or trivially unsatisfiable (i.e., contains `false'). **/ - public Tactic FailIfNotDecided() throws Z3Exception + public Tactic failIfNotDecided() throws Z3Exception { - return new Tactic(this, Native.tacticFailIfNotDecided(nCtx())); } @@ -2573,13 +2567,12 @@ public class Context extends IDisposable * Create a tactic that applies using the given set of * parameters . **/ - public Tactic UsingParams(Tactic t, Params p) throws Z3Exception + public Tactic usingParams(Tactic t, Params p) throws Z3Exception { - - CheckContextMatch(t); - CheckContextMatch(p); + checkContextMatch(t); + checkContextMatch(p); return new Tactic(this, Native.tacticUsingParams(nCtx(), - t.NativeObject(), p.NativeObject())); + t.getNativeObject(), p.getNativeObject())); } /** @@ -2587,21 +2580,19 @@ public class Context extends IDisposable * parameters . Alias for * UsingParams **/ - public Tactic With(Tactic t, Params p) throws Z3Exception + public Tactic with(Tactic t, Params p) throws Z3Exception { - - return UsingParams(t, p); + return usingParams(t, p); } /** * Create a tactic that applies the given tactics in parallel. **/ - public Tactic ParOr(Tactic[] t) throws Z3Exception + public Tactic parOr(Tactic... t) throws Z3Exception { - - CheckContextMatch(t); + checkContextMatch(t); return new Tactic(this, Native.tacticParOr(nCtx(), - Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); + Tactic.arrayLength(t), Tactic.arrayToNative(t))); } /** @@ -2609,20 +2600,20 @@ public class Context extends IDisposable * then to every subgoal produced by . The subgoals are processed in parallel. **/ - public Tactic ParAndThen(Tactic t1, Tactic t2) throws Z3Exception + public Tactic parAndThen(Tactic t1, Tactic t2) throws Z3Exception { - CheckContextMatch(t1); - CheckContextMatch(t2); + checkContextMatch(t1); + checkContextMatch(t2); return new Tactic(this, Native.tacticParAndThen(nCtx(), - t1.NativeObject(), t2.NativeObject())); + t1.getNativeObject(), t2.getNativeObject())); } /** * Interrupt the execution of a Z3 procedure. This procedure can be * used to interrupt: solvers, simplifiers and tactics. **/ - public void Interrupt() throws Z3Exception + public void interrupt() throws Z3Exception { Native.interrupt(nCtx()); } @@ -2630,7 +2621,7 @@ public class Context extends IDisposable /** * The number of supported Probes. **/ - public int NumProbes() throws Z3Exception + public int getNumProbes() throws Z3Exception { return Native.getNumProbes(nCtx()); } @@ -2638,10 +2629,10 @@ public class Context extends IDisposable /** * The names of all supported Probes. **/ - public String[] ProbeNames() throws Z3Exception + public String[] getProbeNames() throws Z3Exception { - int n = NumProbes(); + int n = getNumProbes(); String[] res = new String[n]; for (int i = 0; i < n; i++) res[i] = Native.getProbeName(nCtx(), i); @@ -2652,27 +2643,24 @@ public class Context extends IDisposable * Returns a string containing a description of the probe with the given * name. **/ - public String ProbeDescription(String name) throws Z3Exception + public String getProbeDescription(String name) throws Z3Exception { - return Native.probeGetDescr(nCtx(), name); } /** * Creates a new Probe. **/ - public Probe MkProbe(String name) throws Z3Exception + public Probe mkProbe(String name) throws Z3Exception { - return new Probe(this, name); } /** * Create a probe that always evaluates to . **/ - public Probe Const(double val) throws Z3Exception + public Probe constProbe(double val) throws Z3Exception { - return new Probe(this, Native.probeConst(nCtx(), val)); } @@ -2681,13 +2669,13 @@ public class Context extends IDisposable * is less than the value returned by **/ - public Probe Lt(Probe p1, Probe p2) throws Z3Exception + public Probe lt(Probe p1, Probe p2) throws Z3Exception { - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeLt(nCtx(), p1.NativeObject(), - p2.NativeObject())); + checkContextMatch(p1); + checkContextMatch(p2); + return new Probe(this, Native.probeLt(nCtx(), p1.getNativeObject(), + p2.getNativeObject())); } /** @@ -2695,13 +2683,13 @@ public class Context extends IDisposable * is greater than the value returned by **/ - public Probe Gt(Probe p1, Probe p2) throws Z3Exception + public Probe gt(Probe p1, Probe p2) throws Z3Exception { - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeGt(nCtx(), p1.NativeObject(), - p2.NativeObject())); + checkContextMatch(p1); + checkContextMatch(p2); + return new Probe(this, Native.probeGt(nCtx(), p1.getNativeObject(), + p2.getNativeObject())); } /** @@ -2709,13 +2697,13 @@ public class Context extends IDisposable * is less than or equal the value returned by * **/ - public Probe Le(Probe p1, Probe p2) throws Z3Exception + public Probe le(Probe p1, Probe p2) throws Z3Exception { - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeLe(nCtx(), p1.NativeObject(), - p2.NativeObject())); + checkContextMatch(p1); + checkContextMatch(p2); + return new Probe(this, Native.probeLe(nCtx(), p1.getNativeObject(), + p2.getNativeObject())); } /** @@ -2723,13 +2711,12 @@ public class Context extends IDisposable * is greater than or equal the value returned by * **/ - public Probe Ge(Probe p1, Probe p2) throws Z3Exception + public Probe ge(Probe p1, Probe p2) throws Z3Exception { - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeGe(nCtx(), p1.NativeObject(), - p2.NativeObject())); + checkContextMatch(p1); + checkContextMatch(p2); + return new Probe(this, Native.probeGe(nCtx(), p1.getNativeObject(), + p2.getNativeObject())); } /** @@ -2737,50 +2724,47 @@ public class Context extends IDisposable * is equal to the value returned by **/ - public Probe Eq(Probe p1, Probe p2) throws Z3Exception + public Probe eq(Probe p1, Probe p2) throws Z3Exception { - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeEq(nCtx(), p1.NativeObject(), - p2.NativeObject())); + checkContextMatch(p1); + checkContextMatch(p2); + return new Probe(this, Native.probeEq(nCtx(), p1.getNativeObject(), + p2.getNativeObject())); } /** * Create a probe that evaluates to "true" when the value and evaluate to "true". **/ - public Probe And(Probe p1, Probe p2) throws Z3Exception + public Probe and(Probe p1, Probe p2) throws Z3Exception { - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeAnd(nCtx(), p1.NativeObject(), - p2.NativeObject())); + checkContextMatch(p1); + checkContextMatch(p2); + return new Probe(this, Native.probeAnd(nCtx(), p1.getNativeObject(), + p2.getNativeObject())); } /** * Create a probe that evaluates to "true" when the value or evaluate to "true". **/ - public Probe Or(Probe p1, Probe p2) throws Z3Exception + public Probe or(Probe p1, Probe p2) throws Z3Exception { - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeOr(nCtx(), p1.NativeObject(), - p2.NativeObject())); + checkContextMatch(p1); + checkContextMatch(p2); + return new Probe(this, Native.probeOr(nCtx(), p1.getNativeObject(), + p2.getNativeObject())); } /** * Create a probe that evaluates to "true" when the value does not evaluate to "true". **/ - public Probe Not(Probe p) throws Z3Exception + public Probe not(Probe p) throws Z3Exception { - CheckContextMatch(p); - return new Probe(this, Native.probeNot(nCtx(), p.NativeObject())); + checkContextMatch(p); + return new Probe(this, Native.probeNot(nCtx(), p.getNativeObject())); } /** @@ -2789,9 +2773,9 @@ public class Context extends IDisposable * check-sat commands that take more than a given number of milliseconds to * be solved. **/ - public Solver MkSolver() throws Z3Exception + public Solver mkSolver() throws Z3Exception { - return MkSolver((Symbol) null); + return mkSolver((Symbol) null); } /** @@ -2800,29 +2784,29 @@ public class Context extends IDisposable * check-sat commands that take more than a given number of milliseconds to * be solved. **/ - public Solver MkSolver(Symbol logic) throws Z3Exception + public Solver mkSolver(Symbol logic) throws Z3Exception { if (logic == null) return new Solver(this, Native.mkSolver(nCtx())); else return new Solver(this, Native.mkSolverForLogic(nCtx(), - logic.NativeObject())); + logic.getNativeObject())); } /** * Creates a new (incremental) solver. **/ - public Solver MkSolver(String logic) throws Z3Exception + public Solver mkSolver(String logic) throws Z3Exception { - return MkSolver(MkSymbol(logic)); + return mkSolver(mkSymbol(logic)); } /** * Creates a new (incremental) solver. **/ - public Solver MkSimpleSolver() throws Z3Exception + public Solver mkSimpleSolver() throws Z3Exception { return new Solver(this, Native.mkSimpleSolver(nCtx())); @@ -2833,17 +2817,17 @@ public class Context extends IDisposable * The solver supports the commands Push and Pop, * but it will always solve each check from scratch. **/ - public Solver MkSolver(Tactic t) throws Z3Exception + public Solver mkSolver(Tactic t) throws Z3Exception { return new Solver(this, Native.mkSolverFromTactic(nCtx(), - t.NativeObject())); + t.getNativeObject())); } /** * Create a Fixedpoint context. **/ - public Fixedpoint MkFixedpoint() throws Z3Exception + public Fixedpoint mkFixedpoint() throws Z3Exception { return new Fixedpoint(this); @@ -2858,10 +2842,10 @@ public class Context extends IDisposable * cref="UnwrapAST"/> The native pointer to * wrap. **/ - public AST WrapAST(long nativeObject) throws Z3Exception + public AST wrapAST(long nativeObject) throws Z3Exception { - return AST.Create(this, nativeObject); + return AST.create(this, nativeObject); } /** @@ -2873,9 +2857,9 @@ public class Context extends IDisposable * e.g., ). The AST to unwrap. **/ - public long UnwrapAST(AST a) + public long unwrapAST(AST a) { - return a.NativeObject(); + return a.getNativeObject(); } /** @@ -2891,7 +2875,7 @@ public class Context extends IDisposable /** * Retrieves parameter descriptions for simplifier. **/ - public ParamDescrs SimplifyParameterDescriptions() throws Z3Exception + public ParamDescrs getSimplifyParameterDescriptions() throws Z3Exception { return new ParamDescrs(this, Native.simplifyGetParamDescrs(nCtx())); } @@ -2914,7 +2898,7 @@ public class Context extends IDisposable * once the context is created. An exception is thrown when trying to modify * an immutable parameter. **/ - public void UpdateParamValue(String id, String value) throws Z3Exception + public void updateParamValue(String id, String value) throws Z3Exception { Native.updateParamValue(nCtx(), id, value); } @@ -2923,7 +2907,7 @@ public class Context extends IDisposable * Get a configuration parameter. Returns null if the parameter * value does not exist. **/ - public String GetParamValue(String id) throws Z3Exception + public String getParamValue(String id) throws Z3Exception { Native.StringPtr res = new Native.StringPtr(); boolean r = Native.getParamValue(nCtx(), id, res); @@ -2940,23 +2924,23 @@ public class Context extends IDisposable return m_ctx; } - void InitContext() throws Z3Exception + void initContext() throws Z3Exception { setPrintMode(Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT); - Native.setInternalErrorHandler(nCtx()); + Native.setInternalErrorHandler(nCtx()); } - void CheckContextMatch(Z3Object other) throws Z3Exception + void checkContextMatch(Z3Object other) throws Z3Exception { - if (this != other.Context()) + if (this != other.getContext()) throw new Z3Exception("Context mismatch"); } - void CheckContextMatch(Z3Object[] arr) throws Z3Exception + void checkContextMatch(Z3Object[] arr) throws Z3Exception { if (arr != null) for (Z3Object a : arr) - CheckContextMatch(a); + checkContextMatch(a); } private ASTDecRefQueue m_AST_DRQ = new ASTDecRefQueue(); @@ -2975,77 +2959,77 @@ public class Context extends IDisposable private TacticDecRefQueue m_Tactic_DRQ = new TacticDecRefQueue(); private FixedpointDecRefQueue m_Fixedpoint_DRQ = new FixedpointDecRefQueue(); - ASTDecRefQueue AST_DRQ() + ASTDecRefQueue ast_DRQ() { return m_AST_DRQ; } - ASTMapDecRefQueue ASTMap_DRQ() + ASTMapDecRefQueue astmap_DRQ() { return m_ASTMap_DRQ; } - ASTVectorDecRefQueue ASTVector_DRQ() + ASTVectorDecRefQueue astvector_DRQ() { return m_ASTVector_DRQ; } - ApplyResultDecRefQueue ApplyResult_DRQ() + ApplyResultDecRefQueue applyResult_DRQ() { return m_ApplyResult_DRQ; } - FuncInterpEntryDecRefQueue FuncEntry_DRQ() + FuncInterpEntryDecRefQueue funcEntry_DRQ() { return m_FuncEntry_DRQ; } - FuncInterpDecRefQueue FuncInterp_DRQ() + FuncInterpDecRefQueue funcInterp_DRQ() { return m_FuncInterp_DRQ; } - GoalDecRefQueue Goal_DRQ() + GoalDecRefQueue goal_DRQ() { return m_Goal_DRQ; } - ModelDecRefQueue Model_DRQ() + ModelDecRefQueue model_DRQ() { return m_Model_DRQ; } - ParamsDecRefQueue Params_DRQ() + ParamsDecRefQueue params_DRQ() { return m_Params_DRQ; } - ParamDescrsDecRefQueue ParamDescrs_DRQ() + ParamDescrsDecRefQueue paramDescrs_DRQ() { return m_ParamDescrs_DRQ; } - ProbeDecRefQueue Probe_DRQ() + ProbeDecRefQueue probe_DRQ() { return m_Probe_DRQ; } - SolverDecRefQueue Solver_DRQ() + SolverDecRefQueue solver_DRQ() { return m_Solver_DRQ; } - StatisticsDecRefQueue Statistics_DRQ() + StatisticsDecRefQueue statistics_DRQ() { return m_Statistics_DRQ; } - TacticDecRefQueue Tactic_DRQ() + TacticDecRefQueue tactic_DRQ() { return m_Tactic_DRQ; } - FixedpointDecRefQueue Fixedpoint_DRQ() + FixedpointDecRefQueue fixedpoint_DRQ() { return m_Fixedpoint_DRQ; } @@ -3057,7 +3041,7 @@ public class Context extends IDisposable **/ protected void finalize() { - Dispose(); + dispose(); if (m_refCount == 0) { @@ -3078,22 +3062,22 @@ public class Context extends IDisposable /** * Disposes of the context. **/ - public void Dispose() + public void dispose() { - m_AST_DRQ.Clear(this); - m_ASTMap_DRQ.Clear(this); - m_ASTVector_DRQ.Clear(this); - m_ApplyResult_DRQ.Clear(this); - m_FuncEntry_DRQ.Clear(this); - m_FuncInterp_DRQ.Clear(this); - m_Goal_DRQ.Clear(this); - m_Model_DRQ.Clear(this); - m_Params_DRQ.Clear(this); - m_Probe_DRQ.Clear(this); - m_Solver_DRQ.Clear(this); - m_Statistics_DRQ.Clear(this); - m_Tactic_DRQ.Clear(this); - m_Fixedpoint_DRQ.Clear(this); + m_AST_DRQ.clear(this); + m_ASTMap_DRQ.clear(this); + m_ASTVector_DRQ.clear(this); + m_ApplyResult_DRQ.clear(this); + m_FuncEntry_DRQ.clear(this); + m_FuncInterp_DRQ.clear(this); + m_Goal_DRQ.clear(this); + m_Model_DRQ.clear(this); + m_Params_DRQ.clear(this); + m_Probe_DRQ.clear(this); + m_Solver_DRQ.clear(this); + m_Statistics_DRQ.clear(this); + m_Tactic_DRQ.clear(this); + m_Fixedpoint_DRQ.clear(this); m_boolSort = null; m_intSort = null; diff --git a/src/api/java/DatatypeSort.java b/src/api/java/DatatypeSort.java index 7e6d002aa..f7b2f7d32 100644 --- a/src/api/java/DatatypeSort.java +++ b/src/api/java/DatatypeSort.java @@ -14,10 +14,10 @@ public class DatatypeSort extends Sort /** * The number of constructors of the datatype sort. **/ - public int NumConstructors() throws Z3Exception + public int getNumConstructors() throws Z3Exception { - return Native.getDatatypeSortNumConstructors(Context().nCtx(), - NativeObject()); + return Native.getDatatypeSortNumConstructors(getContext().nCtx(), + getNativeObject()); } /** @@ -25,13 +25,13 @@ public class DatatypeSort extends Sort * * @throws Z3Exception **/ - public FuncDecl[] Constructors() throws Z3Exception + public FuncDecl[] getConstructors() throws Z3Exception { - int n = NumConstructors(); + int n = getNumConstructors(); FuncDecl[] res = new FuncDecl[n]; for (int i = 0; i < n; i++) - res[i] = new FuncDecl(Context(), Native.getDatatypeSortConstructor( - Context().nCtx(), NativeObject(), i)); + res[i] = new FuncDecl(getContext(), Native.getDatatypeSortConstructor( + getContext().nCtx(), getNativeObject(), i)); return res; } @@ -40,13 +40,13 @@ public class DatatypeSort extends Sort * * @throws Z3Exception **/ - public FuncDecl[] Recognizers() throws Z3Exception + public FuncDecl[] getRecognizers() throws Z3Exception { - int n = NumConstructors(); + int n = getNumConstructors(); FuncDecl[] res = new FuncDecl[n]; for (int i = 0; i < n; i++) - res[i] = new FuncDecl(Context(), Native.getDatatypeSortRecognizer( - Context().nCtx(), NativeObject(), i)); + res[i] = new FuncDecl(getContext(), Native.getDatatypeSortRecognizer( + getContext().nCtx(), getNativeObject(), i)); return res; } @@ -55,22 +55,22 @@ public class DatatypeSort extends Sort * * @throws Z3Exception **/ - public FuncDecl[][] Accessors() throws Z3Exception + public FuncDecl[][] getAccessors() throws Z3Exception { - int n = NumConstructors(); + int n = getNumConstructors(); FuncDecl[][] res = new FuncDecl[n][]; for (int i = 0; i < n; i++) { - FuncDecl fd = new FuncDecl(Context(), - Native.getDatatypeSortConstructor(Context().nCtx(), - NativeObject(), i)); - int ds = fd.DomainSize(); + FuncDecl fd = new FuncDecl(getContext(), + Native.getDatatypeSortConstructor(getContext().nCtx(), + getNativeObject(), i)); + int ds = fd.getDomainSize(); FuncDecl[] tmp = new FuncDecl[ds]; for (int j = 0; j < ds; j++) - tmp[j] = new FuncDecl(Context(), - Native.getDatatypeSortConstructorAccessor(Context() - .nCtx(), NativeObject(), i, j)); + tmp[j] = new FuncDecl(getContext(), + Native.getDatatypeSortConstructorAccessor(getContext() + .nCtx(), getNativeObject(), i, j)); res[i] = tmp; } return res; @@ -84,8 +84,8 @@ public class DatatypeSort extends Sort DatatypeSort(Context ctx, Symbol name, Constructor[] constructors) throws Z3Exception { - super(ctx, Native.mkDatatype(ctx.nCtx(), name.NativeObject(), - (int) constructors.length, ArrayToNative(constructors))); + super(ctx, Native.mkDatatype(ctx.nCtx(), name.getNativeObject(), + (int) constructors.length, arrayToNative(constructors))); } }; diff --git a/src/api/java/EnumSort.java b/src/api/java/EnumSort.java index 10f0f9764..f3cbda954 100644 --- a/src/api/java/EnumSort.java +++ b/src/api/java/EnumSort.java @@ -14,7 +14,7 @@ public class EnumSort extends Sort /** * The function declarations of the constants in the enumeration. **/ - public FuncDecl[] ConstDecls() + public FuncDecl[] getConstDecls() { return _constdecls; } @@ -22,7 +22,7 @@ public class EnumSort extends Sort /** * The constants in the enumeration. **/ - public Expr[] Consts() + public Expr[] getConsts() { return _consts; } @@ -30,7 +30,7 @@ public class EnumSort extends Sort /** * The test predicates for the constants in the enumeration. **/ - public FuncDecl[] TesterDecls() + public FuncDecl[] getTesterDecls() { return _testerdecls; } @@ -46,7 +46,7 @@ public class EnumSort extends Sort long[] n_constdecls = new long[n]; long[] n_testers = new long[n]; setNativeObject(Native.mkEnumerationSort(ctx.nCtx(), - name.NativeObject(), (int) n, Symbol.ArrayToNative(enumNames), + name.getNativeObject(), (int) n, Symbol.arrayToNative(enumNames), n_constdecls, n_testers)); _constdecls = new FuncDecl[n]; for (int i = 0; i < n; i++) @@ -56,6 +56,6 @@ public class EnumSort extends Sort _testerdecls[i] = new FuncDecl(ctx, n_testers[i]); _consts = new Expr[n]; for (int i = 0; i < n; i++) - _consts[i] = ctx.MkApp(_constdecls[i], (Expr[])null); + _consts[i] = ctx.mkApp(_constdecls[i], (Expr[])null); } }; diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index 09456307f..7793a16e5 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -6,7 +6,10 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_ast_kind; +import com.microsoft.z3.enumerations.Z3_decl_kind; +import com.microsoft.z3.enumerations.Z3_lbool; +import com.microsoft.z3.enumerations.Z3_sort_kind; /* using System; */ @@ -18,9 +21,9 @@ public class Expr extends AST /** * Returns a simplified version of the expression **/ - public Expr Simplify() throws Z3Exception + public Expr simplify() throws Z3Exception { - return Simplify(null); + return simplify(null); } /** @@ -29,59 +32,57 @@ public class Expr extends AST * parameters to configure the simplifier * **/ - public Expr Simplify(Params p) throws Z3Exception + public Expr simplify(Params p) throws Z3Exception { if (p == null) - return Expr.Create(Context(), - Native.simplify(Context().nCtx(), NativeObject())); + return Expr.create(getContext(), + Native.simplify(getContext().nCtx(), getNativeObject())); else - return Expr.Create( - Context(), - Native.simplifyEx(Context().nCtx(), NativeObject(), - p.NativeObject())); + return Expr.create( + getContext(), + Native.simplifyEx(getContext().nCtx(), getNativeObject(), + p.getNativeObject())); } /** * The function declaration of the function that is applied in this * expression. **/ - public FuncDecl FuncDecl() throws Z3Exception + public FuncDecl getFuncDecl() throws Z3Exception { - - return new FuncDecl(Context(), Native.getAppDecl(Context().nCtx(), - NativeObject())); + return new FuncDecl(getContext(), Native.getAppDecl(getContext().nCtx(), + getNativeObject())); } /** * Indicates whether the expression is the true or false expression or * something else (Z3_L_UNDEF). **/ - public Z3_lbool BoolValue() throws Z3Exception + public Z3_lbool getBoolValue() throws Z3Exception { - return Z3_lbool.fromInt(Native.getBoolValue(Context().nCtx(), - NativeObject())); + return Z3_lbool.fromInt(Native.getBoolValue(getContext().nCtx(), + getNativeObject())); } /** * The number of arguments of the expression. **/ - public int NumArgs() throws Z3Exception + public int getNumArgs() throws Z3Exception { - return Native.getAppNumArgs(Context().nCtx(), NativeObject()); + return Native.getAppNumArgs(getContext().nCtx(), getNativeObject()); } /** * The arguments of the expression. **/ - public Expr[] Args() throws Z3Exception + public Expr[] getArgs() throws Z3Exception { - - int n = NumArgs(); + int n = getNumArgs(); Expr[] res = new Expr[n]; for (int i = 0; i < n; i++) - res[i] = Expr.Create(Context(), - Native.getAppArg(Context().nCtx(), NativeObject(), i)); + res[i] = Expr.create(getContext(), + Native.getAppArg(getContext().nCtx(), getNativeObject(), i)); return res; } @@ -90,14 +91,13 @@ public class Expr extends AST * name="args"/> The number of new arguments should coincide with the * current number of arguments. **/ - public void Update(Expr[] args) throws Z3Exception + public void update(Expr[] args) throws Z3Exception { - - Context().CheckContextMatch(args); - if (args.length != NumArgs()) + getContext().checkContextMatch(args); + if (args.length != getNumArgs()) throw new Z3Exception("Number of arguments does not match"); - setNativeObject(Native.updateTerm(Context().nCtx(), NativeObject(), - (int) args.length, Expr.ArrayToNative(args))); + setNativeObject(Native.updateTerm(getContext().nCtx(), getNativeObject(), + (int) args.length, Expr.arrayToNative(args))); } /** @@ -109,26 +109,25 @@ public class Expr extends AST * num_exprs, we must have that sort of from[i] * must be equal to sort of to[i]. **/ - public Expr Substitute(Expr[] from, Expr[] to) throws Z3Exception + public Expr substitute(Expr[] from, Expr[] to) throws Z3Exception { - - Context().CheckContextMatch(from); - Context().CheckContextMatch(to); + getContext().checkContextMatch(from); + getContext().checkContextMatch(to); if (from.length != to.length) throw new Z3Exception("Argument sizes do not match"); - return Expr.Create(Context(), Native.substitute(Context().nCtx(), - NativeObject(), (int) from.length, Expr.ArrayToNative(from), - Expr.ArrayToNative(to))); + return Expr.create(getContext(), Native.substitute(getContext().nCtx(), + getNativeObject(), (int) from.length, Expr.arrayToNative(from), + Expr.arrayToNative(to))); } /** * Substitute every occurrence of from in the expression with * to. **/ - public Expr Substitute(Expr from, Expr to) throws Z3Exception + public Expr substitute(Expr from, Expr to) throws Z3Exception { - return Substitute(new Expr[] { from }, new Expr[] { to }); + return substitute(new Expr[] { from }, new Expr[] { to }); } /** @@ -137,12 +136,12 @@ public class Expr extends AST * num_exprs, the variable with de-Bruijn index i * is replaced with term to[i]. **/ - public Expr SubstituteVars(Expr[] to) throws Z3Exception + public Expr substituteVars(Expr[] to) throws Z3Exception { - Context().CheckContextMatch(to); - return Expr.Create(Context(), Native.substituteVars(Context().nCtx(), - NativeObject(), (int) to.length, Expr.ArrayToNative(to))); + getContext().checkContextMatch(to); + return Expr.create(getContext(), Native.substituteVars(getContext().nCtx(), + getNativeObject(), (int) to.length, Expr.arrayToNative(to))); } /** @@ -152,15 +151,15 @@ public class Expr extends AST * @return A copy of the term which is associated with **/ - public Expr Translate(Context ctx) throws Z3Exception + public Expr translate(Context ctx) throws Z3Exception { - if (Context() == ctx) + if (getContext() == ctx) return this; else - return Expr.Create( + return Expr.create( ctx, - Native.translate(Context().nCtx(), NativeObject(), + Native.translate(getContext().nCtx(), getNativeObject(), ctx.nCtx())); } @@ -175,9 +174,9 @@ public class Expr extends AST /** * Indicates whether the term is a numeral **/ - public boolean IsNumeral() throws Z3Exception + public boolean isNumeral() throws Z3Exception { - return Native.isNumeralAst(Context().nCtx(), NativeObject()); + return Native.isNumeralAst(getContext().nCtx(), getNativeObject()); } /** @@ -185,310 +184,310 @@ public class Expr extends AST * * @return True if the term is well-sorted, false otherwise. **/ - public boolean IsWellSorted() throws Z3Exception + public boolean isWellSorted() throws Z3Exception { - return Native.isWellSorted(Context().nCtx(), NativeObject()); + return Native.isWellSorted(getContext().nCtx(), getNativeObject()); } /** * The Sort of the term. **/ - public Sort Sort() throws Z3Exception + public Sort getSort() throws Z3Exception { - return Sort.Create(Context(), - Native.getSort(Context().nCtx(), NativeObject())); + return Sort.create(getContext(), + Native.getSort(getContext().nCtx(), getNativeObject())); } /** * Indicates whether the term represents a constant. **/ - public boolean IsConst() throws Z3Exception + public boolean isConst() throws Z3Exception { - return IsApp() && NumArgs() == 0 && FuncDecl().DomainSize() == 0; + return isApp() && getNumArgs() == 0 && getFuncDecl().getDomainSize() == 0; } /** * Indicates whether the term is an integer numeral. **/ - public boolean IsIntNum() throws Z3Exception + public boolean isIntNum() throws Z3Exception { - return IsNumeral() && IsInt(); + return isNumeral() && isInt(); } /** * Indicates whether the term is a real numeral. **/ - public boolean IsRatNum() throws Z3Exception + public boolean isRatNum() throws Z3Exception { - return IsNumeral() && IsReal(); + return isNumeral() && isReal(); } /** * Indicates whether the term is an algebraic number **/ - public boolean IsAlgebraicNumber() throws Z3Exception + public boolean isAlgebraicNumber() throws Z3Exception { - return Native.isAlgebraicNumber(Context().nCtx(), NativeObject()); + return Native.isAlgebraicNumber(getContext().nCtx(), getNativeObject()); } /** * Indicates whether the term has Boolean sort. **/ - public boolean IsBool() throws Z3Exception + public boolean isBool() throws Z3Exception { - return (IsExpr() && Native.isEqSort(Context().nCtx(), - Native.mkBoolSort(Context().nCtx()), - Native.getSort(Context().nCtx(), NativeObject()))); + return (isExpr() && Native.isEqSort(getContext().nCtx(), + Native.mkBoolSort(getContext().nCtx()), + Native.getSort(getContext().nCtx(), getNativeObject()))); } /** * Indicates whether the term is the constant true. **/ - public boolean IsTrue() throws Z3Exception + public boolean isTrue() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_TRUE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_TRUE; } /** * Indicates whether the term is the constant false. **/ - public boolean IsFalse() throws Z3Exception + public boolean isFalse() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_FALSE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FALSE; } /** * Indicates whether the term is an equality predicate. **/ - public boolean IsEq() throws Z3Exception + public boolean isEq() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_EQ; } /** * Indicates whether the term is an n-ary distinct predicate (every argument * is mutually distinct). **/ - public boolean IsDistinct() throws Z3Exception + public boolean isDistinct() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_DISTINCT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_DISTINCT; } /** * Indicates whether the term is a ternary if-then-else term **/ - public boolean IsITE() throws Z3Exception + public boolean isITE() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ITE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ITE; } /** * Indicates whether the term is an n-ary conjunction **/ - public boolean IsAnd() throws Z3Exception + public boolean isAnd() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_AND; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_AND; } /** * Indicates whether the term is an n-ary disjunction **/ - public boolean IsOr() throws Z3Exception + public boolean isOr() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_OR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_OR; } /** * Indicates whether the term is an if-and-only-if (Boolean equivalence, * binary) **/ - public boolean IsIff() throws Z3Exception + public boolean isIff() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IFF; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_IFF; } /** * Indicates whether the term is an exclusive or **/ - public boolean IsXor() throws Z3Exception + public boolean isXor() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_XOR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_XOR; } /** * Indicates whether the term is a negation **/ - public boolean IsNot() throws Z3Exception + public boolean isNot() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_NOT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_NOT; } /** * Indicates whether the term is an implication **/ - public boolean IsImplies() throws Z3Exception + public boolean isImplies() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IMPLIES; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_IMPLIES; } /** * Indicates whether the term is of integer sort. **/ - public boolean IsInt() throws Z3Exception + public boolean isInt() throws Z3Exception { - return (Native.isNumeralAst(Context().nCtx(), NativeObject()) && Native - .getSortKind(Context().nCtx(), - Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_INT_SORT + return (Native.isNumeralAst(getContext().nCtx(), getNativeObject()) && Native + .getSortKind(getContext().nCtx(), + Native.getSort(getContext().nCtx(), getNativeObject())) == Z3_sort_kind.Z3_INT_SORT .toInt()); } /** * Indicates whether the term is of sort real. **/ - public boolean IsReal() throws Z3Exception + public boolean isReal() throws Z3Exception { - return Native.getSortKind(Context().nCtx(), - Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_REAL_SORT + return Native.getSortKind(getContext().nCtx(), + Native.getSort(getContext().nCtx(), getNativeObject())) == Z3_sort_kind.Z3_REAL_SORT .toInt(); } /** * Indicates whether the term is an arithmetic numeral. **/ - public boolean IsArithmeticNumeral() throws Z3Exception + public boolean isArithmeticNumeral() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ANUM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ANUM; } /** * Indicates whether the term is a less-than-or-equal **/ - public boolean IsLE() throws Z3Exception + public boolean isLE() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_LE; } /** * Indicates whether the term is a greater-than-or-equal **/ - public boolean IsGE() throws Z3Exception + public boolean isGE() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_GE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_GE; } /** * Indicates whether the term is a less-than **/ - public boolean IsLT() throws Z3Exception + public boolean isLT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_LT; } /** * Indicates whether the term is a greater-than **/ - public boolean IsGT() throws Z3Exception + public boolean isGT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_GT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_GT; } /** * Indicates whether the term is addition (binary) **/ - public boolean IsAdd() throws Z3Exception + public boolean isAdd() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ADD; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ADD; } /** * Indicates whether the term is subtraction (binary) **/ - public boolean IsSub() throws Z3Exception + public boolean isSub() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SUB; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SUB; } /** * Indicates whether the term is a unary minus **/ - public boolean IsUMinus() throws Z3Exception + public boolean isUMinus() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_UMINUS; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_UMINUS; } /** * Indicates whether the term is multiplication (binary) **/ - public boolean IsMul() throws Z3Exception + public boolean isMul() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_MUL; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_MUL; } /** * Indicates whether the term is division (binary) **/ - public boolean IsDiv() throws Z3Exception + public boolean isDiv() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_DIV; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_DIV; } /** * Indicates whether the term is integer division (binary) **/ - public boolean IsIDiv() throws Z3Exception + public boolean isIDiv() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IDIV; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_IDIV; } /** * Indicates whether the term is remainder (binary) **/ - public boolean IsRemainder() throws Z3Exception + public boolean isRemainder() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_REM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_REM; } /** * Indicates whether the term is modulus (binary) **/ - public boolean IsModulus() throws Z3Exception + public boolean isModulus() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_MOD; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_MOD; } /** * Indicates whether the term is a coercion of integer to real (unary) **/ - public boolean IsIntToReal() throws Z3Exception + public boolean isIntToReal() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_TO_REAL; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_TO_REAL; } /** * Indicates whether the term is a coercion of real to integer (unary) **/ - public boolean IsRealToInt() throws Z3Exception + public boolean isRealToInt() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_TO_INT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_TO_INT; } /** * Indicates whether the term is a check that tests whether a real is * integral (unary) **/ - public boolean IsRealIsInt() throws Z3Exception + public boolean isRealIsInt() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IS_INT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_IS_INT; } /** * Indicates whether the term is of an array sort. **/ - public boolean IsArray() throws Z3Exception + public boolean isArray() throws Z3Exception { - return (Native.isApp(Context().nCtx(), NativeObject()) && Z3_sort_kind - .fromInt(Native.getSortKind(Context().nCtx(), - Native.getSort(Context().nCtx(), NativeObject()))) == Z3_sort_kind.Z3_ARRAY_SORT); + return (Native.isApp(getContext().nCtx(), getNativeObject()) && Z3_sort_kind + .fromInt(Native.getSortKind(getContext().nCtx(), + Native.getSort(getContext().nCtx(), getNativeObject()))) == Z3_sort_kind.Z3_ARRAY_SORT); } /** @@ -496,17 +495,17 @@ public class Expr extends AST * select(store(a,i,v),j) = if i = j then v else select(a,j). Array store * takes at least 3 arguments. **/ - public boolean IsStore() throws Z3Exception + public boolean isStore() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_STORE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_STORE; } /** * Indicates whether the term is an array select. **/ - public boolean IsSelect() throws Z3Exception + public boolean isSelect() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SELECT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SELECT; } /** @@ -514,27 +513,27 @@ public class Expr extends AST * select(const(v),i) = v holds for every v and i. The function is * unary. **/ - public boolean IsConstantArray() throws Z3Exception + public boolean isConstantArray() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_CONST_ARRAY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_CONST_ARRAY; } /** * Indicates whether the term is a default array. For example * default(const(v)) = v. The function is unary. **/ - public boolean IsDefaultArray() throws Z3Exception + public boolean isDefaultArray() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ARRAY_DEFAULT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ARRAY_DEFAULT; } /** * Indicates whether the term is an array map. It satisfies * map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. **/ - public boolean IsArrayMap() throws Z3Exception + public boolean isArrayMap() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ARRAY_MAP; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ARRAY_MAP; } /** @@ -542,155 +541,155 @@ public class Expr extends AST * is n array value that behaves as the function graph of the function * passed as parameter. **/ - public boolean IsAsArray() throws Z3Exception + public boolean isAsArray() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_AS_ARRAY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_AS_ARRAY; } /** * Indicates whether the term is set union **/ - public boolean IsSetUnion() throws Z3Exception + public boolean isSetUnion() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_UNION; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SET_UNION; } /** * Indicates whether the term is set intersection **/ - public boolean IsSetIntersect() throws Z3Exception + public boolean isSetIntersect() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_INTERSECT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SET_INTERSECT; } /** * Indicates whether the term is set difference **/ - public boolean IsSetDifference() throws Z3Exception + public boolean isSetDifference() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_DIFFERENCE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SET_DIFFERENCE; } /** * Indicates whether the term is set complement **/ - public boolean IsSetComplement() throws Z3Exception + public boolean isSetComplement() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_COMPLEMENT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SET_COMPLEMENT; } /** * Indicates whether the term is set subset **/ - public boolean IsSetSubset() throws Z3Exception + public boolean isSetSubset() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_SUBSET; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SET_SUBSET; } /** * Indicates whether the terms is of bit-vector sort. **/ - public boolean IsBV() throws Z3Exception + public boolean isBV() throws Z3Exception { - return Native.getSortKind(Context().nCtx(), - Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_BV_SORT + return Native.getSortKind(getContext().nCtx(), + Native.getSort(getContext().nCtx(), getNativeObject())) == Z3_sort_kind.Z3_BV_SORT .toInt(); } /** * Indicates whether the term is a bit-vector numeral **/ - public boolean IsBVNumeral() throws Z3Exception + public boolean isBVNumeral() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNUM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BNUM; } /** * Indicates whether the term is a one-bit bit-vector with value one **/ - public boolean IsBVBitOne() throws Z3Exception + public boolean isBVBitOne() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BIT1; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BIT1; } /** * Indicates whether the term is a one-bit bit-vector with value zero **/ - public boolean IsBVBitZero() throws Z3Exception + public boolean isBVBitZero() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BIT0; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BIT0; } /** * Indicates whether the term is a bit-vector unary minus **/ - public boolean IsBVUMinus() throws Z3Exception + public boolean isBVUMinus() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNEG; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BNEG; } /** * Indicates whether the term is a bit-vector addition (binary) **/ - public boolean IsBVAdd() throws Z3Exception + public boolean isBVAdd() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BADD; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BADD; } /** * Indicates whether the term is a bit-vector subtraction (binary) **/ - public boolean IsBVSub() throws Z3Exception + public boolean isBVSub() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSUB; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSUB; } /** * Indicates whether the term is a bit-vector multiplication (binary) **/ - public boolean IsBVMul() throws Z3Exception + public boolean isBVMul() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BMUL; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BMUL; } /** * Indicates whether the term is a bit-vector signed division (binary) **/ - public boolean IsBVSDiv() throws Z3Exception + public boolean isBVSDiv() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSDIV; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSDIV; } /** * Indicates whether the term is a bit-vector unsigned division (binary) **/ - public boolean IsBVUDiv() throws Z3Exception + public boolean isBVUDiv() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUDIV; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BUDIV; } /** * Indicates whether the term is a bit-vector signed remainder (binary) **/ - public boolean IsBVSRem() throws Z3Exception + public boolean isBVSRem() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSREM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSREM; } /** * Indicates whether the term is a bit-vector unsigned remainder (binary) **/ - public boolean IsBVURem() throws Z3Exception + public boolean isBVURem() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUREM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BUREM; } /** * Indicates whether the term is a bit-vector signed modulus **/ - public boolean IsBVSMod() throws Z3Exception + public boolean isBVSMod() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSMOD; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSMOD; } /** @@ -698,7 +697,7 @@ public class Expr extends AST **/ boolean IsBVSDiv0() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSDIV0; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSDIV0; } /** @@ -706,7 +705,7 @@ public class Expr extends AST **/ boolean IsBVUDiv0() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUDIV0; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BUDIV0; } /** @@ -714,7 +713,7 @@ public class Expr extends AST **/ boolean IsBVSRem0() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSREM0; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSREM0; } /** @@ -722,7 +721,7 @@ public class Expr extends AST **/ boolean IsBVURem0() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUREM0; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BUREM0; } /** @@ -730,232 +729,232 @@ public class Expr extends AST **/ boolean IsBVSMod0() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSMOD0; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSMOD0; } /** * Indicates whether the term is an unsigned bit-vector less-than-or-equal **/ - public boolean IsBVULE() throws Z3Exception + public boolean isBVULE() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ULEQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ULEQ; } /** * Indicates whether the term is a signed bit-vector less-than-or-equal **/ - public boolean IsBVSLE() throws Z3Exception + public boolean isBVSLE() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SLEQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SLEQ; } /** * Indicates whether the term is an unsigned bit-vector * greater-than-or-equal **/ - public boolean IsBVUGE() throws Z3Exception + public boolean isBVUGE() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_UGEQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_UGEQ; } /** * Indicates whether the term is a signed bit-vector greater-than-or-equal **/ - public boolean IsBVSGE() throws Z3Exception + public boolean isBVSGE() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SGEQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SGEQ; } /** * Indicates whether the term is an unsigned bit-vector less-than **/ - public boolean IsBVULT() throws Z3Exception + public boolean isBVULT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ULT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ULT; } /** * Indicates whether the term is a signed bit-vector less-than **/ - public boolean IsBVSLT() throws Z3Exception + public boolean isBVSLT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SLT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SLT; } /** * Indicates whether the term is an unsigned bit-vector greater-than **/ - public boolean IsBVUGT() throws Z3Exception + public boolean isBVUGT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_UGT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_UGT; } /** * Indicates whether the term is a signed bit-vector greater-than **/ - public boolean IsBVSGT() throws Z3Exception + public boolean isBVSGT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SGT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SGT; } /** * Indicates whether the term is a bit-wise AND **/ - public boolean IsBVAND() throws Z3Exception + public boolean isBVAND() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BAND; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BAND; } /** * Indicates whether the term is a bit-wise OR **/ - public boolean IsBVOR() throws Z3Exception + public boolean isBVOR() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BOR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BOR; } /** * Indicates whether the term is a bit-wise NOT **/ - public boolean IsBVNOT() throws Z3Exception + public boolean isBVNOT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNOT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BNOT; } /** * Indicates whether the term is a bit-wise XOR **/ - public boolean IsBVXOR() throws Z3Exception + public boolean isBVXOR() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BXOR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BXOR; } /** * Indicates whether the term is a bit-wise NAND **/ - public boolean IsBVNAND() throws Z3Exception + public boolean isBVNAND() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNAND; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BNAND; } /** * Indicates whether the term is a bit-wise NOR **/ - public boolean IsBVNOR() throws Z3Exception + public boolean isBVNOR() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNOR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BNOR; } /** * Indicates whether the term is a bit-wise XNOR **/ - public boolean IsBVXNOR() throws Z3Exception + public boolean isBVXNOR() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BXNOR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BXNOR; } /** * Indicates whether the term is a bit-vector concatenation (binary) **/ - public boolean IsBVConcat() throws Z3Exception + public boolean isBVConcat() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_CONCAT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_CONCAT; } /** * Indicates whether the term is a bit-vector sign extension **/ - public boolean IsBVSignExtension() throws Z3Exception + public boolean isBVSignExtension() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SIGN_EXT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SIGN_EXT; } /** * Indicates whether the term is a bit-vector zero extension **/ - public boolean IsBVZeroExtension() throws Z3Exception + public boolean isBVZeroExtension() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ZERO_EXT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ZERO_EXT; } /** * Indicates whether the term is a bit-vector extraction **/ - public boolean IsBVExtract() throws Z3Exception + public boolean isBVExtract() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EXTRACT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_EXTRACT; } /** * Indicates whether the term is a bit-vector repetition **/ - public boolean IsBVRepeat() throws Z3Exception + public boolean isBVRepeat() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_REPEAT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_REPEAT; } /** * Indicates whether the term is a bit-vector reduce OR **/ - public boolean IsBVReduceOR() throws Z3Exception + public boolean isBVReduceOR() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BREDOR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BREDOR; } /** * Indicates whether the term is a bit-vector reduce AND **/ - public boolean IsBVReduceAND() throws Z3Exception + public boolean isBVReduceAND() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BREDAND; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BREDAND; } /** * Indicates whether the term is a bit-vector comparison **/ - public boolean IsBVComp() throws Z3Exception + public boolean isBVComp() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BCOMP; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BCOMP; } /** * Indicates whether the term is a bit-vector shift left **/ - public boolean IsBVShiftLeft() throws Z3Exception + public boolean isBVShiftLeft() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSHL; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSHL; } /** * Indicates whether the term is a bit-vector logical shift right **/ - public boolean IsBVShiftRightLogical() throws Z3Exception + public boolean isBVShiftRightLogical() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BLSHR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BLSHR; } /** * Indicates whether the term is a bit-vector arithmetic shift left **/ - public boolean IsBVShiftRightArithmetic() throws Z3Exception + public boolean isBVShiftRightArithmetic() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BASHR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BASHR; } /** * Indicates whether the term is a bit-vector rotate left **/ - public boolean IsBVRotateLeft() throws Z3Exception + public boolean isBVRotateLeft() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ROTATE_LEFT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ROTATE_LEFT; } /** * Indicates whether the term is a bit-vector rotate right **/ - public boolean IsBVRotateRight() throws Z3Exception + public boolean isBVRotateRight() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ROTATE_RIGHT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_ROTATE_RIGHT; } /** @@ -963,9 +962,9 @@ public class Expr extends AST * Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator * instead of a parametric one. **/ - public boolean IsBVRotateLeftExtended() throws Z3Exception + public boolean isBVRotateLeftExtended() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT; } /** @@ -973,9 +972,9 @@ public class Expr extends AST * Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator * instead of a parametric one. **/ - public boolean IsBVRotateRightExtended() throws Z3Exception + public boolean isBVRotateRightExtended() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EXT_ROTATE_RIGHT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_EXT_ROTATE_RIGHT; } /** @@ -984,9 +983,9 @@ public class Expr extends AST * the most rudimentary simplification rules are applied to this * function. **/ - public boolean IsIntToBV() throws Z3Exception + public boolean isIntToBV() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_INT2BV; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_INT2BV; } /** @@ -995,9 +994,9 @@ public class Expr extends AST * the most rudimentary simplification rules are applied to this * function. **/ - public boolean IsBVToInt() throws Z3Exception + public boolean isBVToInt() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BV2INT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BV2INT; } /** @@ -1005,9 +1004,9 @@ public class Expr extends AST * carry bit in a full-adder. The meaning is given by the equivalence (carry * l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) **/ - public boolean IsBVCarry() throws Z3Exception + public boolean isBVCarry() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_CARRY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_CARRY; } /** @@ -1015,9 +1014,9 @@ public class Expr extends AST * meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor * l1 l2) l3) **/ - public boolean IsBVXOR3() throws Z3Exception + public boolean isBVXOR3() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_XOR3; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_XOR3; } /** @@ -1025,9 +1024,9 @@ public class Expr extends AST * condition generator). The label has two parameters, a string and * a Boolean polarity. It takes one argument, a formula. **/ - public boolean IsLabel() throws Z3Exception + public boolean isLabel() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LABEL; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_LABEL; } /** @@ -1035,9 +1034,9 @@ public class Expr extends AST * Verification condition generator). A label literal has a set of * string parameters. It takes no arguments. **/ - public boolean IsLabelLit() throws Z3Exception + public boolean isLabelLit() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LABEL_LIT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_LABEL_LIT; } /** @@ -1045,34 +1044,34 @@ public class Expr extends AST * This binary predicate is used in proof terms. It captures * equisatisfiability and equivalence modulo renamings. **/ - public boolean IsOEQ() throws Z3Exception + public boolean isOEQ() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_OEQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_OEQ; } /** * Indicates whether the term is a Proof for the expression 'true'. **/ - public boolean IsProofTrue() throws Z3Exception + public boolean isProofTrue() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TRUE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_TRUE; } /** * Indicates whether the term is a proof for a fact asserted by the user. **/ - public boolean IsProofAsserted() throws Z3Exception + public boolean isProofAsserted() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_ASSERTED; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_ASSERTED; } /** * Indicates whether the term is a proof for a fact (tagged as goal) * asserted by the user. **/ - public boolean IsProofGoal() throws Z3Exception + public boolean isProofGoal() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_GOAL; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_GOAL; } /** @@ -1081,9 +1080,9 @@ public class Expr extends AST * T2: (implies p q) [mp T1 T2]: q The second antecedents may also be a * proof for (iff p q). **/ - public boolean IsProofModusPonens() throws Z3Exception + public boolean isProofModusPonens() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS; } /** @@ -1093,9 +1092,9 @@ public class Expr extends AST * equality and equivalence. That is, R is either '~', '=' or * 'iff'. **/ - public boolean IsProofReflexivity() throws Z3Exception + public boolean isProofReflexivity() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_REFLEXIVITY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_REFLEXIVITY; } /** @@ -1104,9 +1103,9 @@ public class Expr extends AST * a proof for (R s t). T1: (R t s) [symmetry T1]: (R s t) T1 is the * antecedent of this proof object. **/ - public boolean IsProofSymmetry() throws Z3Exception + public boolean isProofSymmetry() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_SYMMETRY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_SYMMETRY; } /** @@ -1115,9 +1114,9 @@ public class Expr extends AST * u), produces a proof for (R t u). T1: (R t s) T2: (R s u) [trans T1 T2]: * (R t u) **/ - public boolean IsProofTransitivity() throws Z3Exception + public boolean isProofTransitivity() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY; } /** @@ -1133,9 +1132,9 @@ public class Expr extends AST * s to t, if we view every antecedent (R a b) as an edge between a and b. * **/ - public boolean IsProofTransitivityStar() throws Z3Exception + public boolean isProofTransitivityStar() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY_STAR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY_STAR; } /** @@ -1145,9 +1144,9 @@ public class Expr extends AST * suppressed. That is, reflexivity proofs are supressed to save space. * **/ - public boolean IsProofMonotonicity() throws Z3Exception + public boolean isProofMonotonicity() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_MONOTONICITY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_MONOTONICITY; } /** @@ -1155,9 +1154,9 @@ public class Expr extends AST * for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). T1: * (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) **/ - public boolean IsProofQuantIntro() throws Z3Exception + public boolean isProofQuantIntro() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_QUANT_INTRO; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_QUANT_INTRO; } /** @@ -1171,9 +1170,9 @@ public class Expr extends AST * This proof object has no antecedents. Remark. This rule is used by the * CNF conversion pass and instantiated by f = or, and g = and. **/ - public boolean IsProofDistributivity() throws Z3Exception + public boolean isProofDistributivity() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DISTRIBUTIVITY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_DISTRIBUTIVITY; } /** @@ -1181,9 +1180,9 @@ public class Expr extends AST * Given a proof for (and l_1 ... l_n), produces a proof for l_i T1: (and * l_1 ... l_n) [and-elim T1]: l_i **/ - public boolean IsProofAndElimination() throws Z3Exception + public boolean isProofAndElimination() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_AND_ELIM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_AND_ELIM; } /** @@ -1191,9 +1190,9 @@ public class Expr extends AST * Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). * T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) **/ - public boolean IsProofOrElimination() throws Z3Exception + public boolean isProofOrElimination() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NOT_OR_ELIM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_NOT_OR_ELIM; } /** @@ -1208,9 +1207,9 @@ public class Expr extends AST * Examples: (= (+ x 0) x) (= (+ x 1 2) (+ 3 x)) (iff (or x false) x) * **/ - public boolean IsProofRewrite() throws Z3Exception + public boolean isProofRewrite() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_REWRITE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_REWRITE; } /** @@ -1224,9 +1223,9 @@ public class Expr extends AST * Booleans (BIT2BOOL=true) - When pulling ite expression up * (PULL_CHEAP_ITE_TREES=true) **/ - public boolean IsProofRewriteStar() throws Z3Exception + public boolean isProofRewriteStar() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_REWRITE_STAR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_REWRITE_STAR; } /** @@ -1234,9 +1233,9 @@ public class Expr extends AST * A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) * r))). This proof object has no antecedents. **/ - public boolean IsProofPullQuant() throws Z3Exception + public boolean isProofPullQuant() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_PULL_QUANT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_PULL_QUANT; } /** @@ -1245,9 +1244,9 @@ public class Expr extends AST * proof object is only used if the parameter PROOF_MODE is 1. This proof * object has no antecedents **/ - public boolean IsProofPullQuantStar() throws Z3Exception + public boolean isProofPullQuantStar() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_PULL_QUANT_STAR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_PULL_QUANT_STAR; } /** @@ -1257,9 +1256,9 @@ public class Expr extends AST * (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) This proof object has no * antecedents **/ - public boolean IsProofPushQuant() throws Z3Exception + public boolean isProofPushQuant() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_PUSH_QUANT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_PUSH_QUANT; } /** @@ -1270,9 +1269,9 @@ public class Expr extends AST * It is used to justify the elimination of unused variables. This proof * object has no antecedents. **/ - public boolean IsProofElimUnusedVars() throws Z3Exception + public boolean isProofElimUnusedVars() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_ELIM_UNUSED_VARS; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_ELIM_UNUSED_VARS; } /** @@ -1284,27 +1283,27 @@ public class Expr extends AST * * Several variables can be eliminated simultaneously. **/ - public boolean IsProofDER() throws Z3Exception + public boolean isProofDER() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DER; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_DER; } /** * Indicates whether the term is a proof for quantifier instantiation * A proof of (or (not (forall (x) (P x))) (P a)) **/ - public boolean IsProofQuantInst() throws Z3Exception + public boolean isProofQuantInst() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_QUANT_INST; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_QUANT_INST; } /** * Indicates whether the term is a hypthesis marker. Mark a * hypothesis in a natural deduction style proof. **/ - public boolean IsProofHypothesis() throws Z3Exception + public boolean isProofHypothesis() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_HYPOTHESIS; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_HYPOTHESIS; } /** @@ -1315,9 +1314,9 @@ public class Expr extends AST * converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 * contains the hypotheses: l_1, ..., l_n. **/ - public boolean IsProofLemma() throws Z3Exception + public boolean isProofLemma() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_LEMMA; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_LEMMA; } /** @@ -1325,27 +1324,27 @@ public class Expr extends AST * (or l_1 ... l_n l_1' ... l_m') T2: (not l_1) ... T(n+1): (not l_n) * [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') **/ - public boolean IsProofUnitResolution() throws Z3Exception + public boolean isProofUnitResolution() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_UNIT_RESOLUTION; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_UNIT_RESOLUTION; } /** * Indicates whether the term is a proof by iff-true T1: p * [iff-true T1]: (iff p true) **/ - public boolean IsProofIFFTrue() throws Z3Exception + public boolean isProofIFFTrue() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_TRUE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_TRUE; } /** * Indicates whether the term is a proof by iff-false T1: (not p) * [iff-false T1]: (iff p false) **/ - public boolean IsProofIFFFalse() throws Z3Exception + public boolean isProofIFFFalse() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_FALSE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_FALSE; } /** @@ -1357,9 +1356,9 @@ public class Expr extends AST * This proof object has no antecedents. Remark: if f is bool, then = is * iff. **/ - public boolean IsProofCommutativity() throws Z3Exception + public boolean isProofCommutativity() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_COMMUTATIVITY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_COMMUTATIVITY; } /** @@ -1380,9 +1379,9 @@ public class Expr extends AST * connectives in the axioms a small bounded number of steps (=3). * **/ - public boolean IsProofDefAxiom() throws Z3Exception + public boolean isProofDefAxiom() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DEF_AXIOM; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_DEF_AXIOM; } /** @@ -1401,9 +1400,9 @@ public class Expr extends AST * * Otherwise: [def-intro]: (= n e) **/ - public boolean IsProofDefIntro() throws Z3Exception + public boolean isProofDefIntro() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DEF_INTRO; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_DEF_INTRO; } /** @@ -1411,18 +1410,18 @@ public class Expr extends AST * [apply-def T1]: F ~ n F is 'equivalent' to n, given that T1 is * a proof that n is a name for F. **/ - public boolean IsProofApplyDef() throws Z3Exception + public boolean isProofApplyDef() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_APPLY_DEF; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_APPLY_DEF; } /** * Indicates whether the term is a proof iff-oeq T1: (iff p q) * [iff~ T1]: (~ p q) **/ - public boolean IsProofIFFOEQ() throws Z3Exception + public boolean isProofIFFOEQ() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_OEQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_OEQ; } /** @@ -1445,9 +1444,9 @@ public class Expr extends AST * NNF_NEG furthermore handles the case where negation is pushed over * Boolean connectives 'and' and 'or'. **/ - public boolean IsProofNNFPos() throws Z3Exception + public boolean isProofNNFPos() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_POS; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_POS; } /** @@ -1461,9 +1460,9 @@ public class Expr extends AST * s_2 ~ r_2' [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 * r_2) (or r_1' r_2'))) **/ - public boolean IsProofNNFNeg() throws Z3Exception + public boolean isProofNNFNeg() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_NEG; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_NEG; } /** @@ -1476,9 +1475,9 @@ public class Expr extends AST * This proof object may have n antecedents. Each antecedent is a * PR_DEF_INTRO. **/ - public boolean IsProofNNFStar() throws Z3Exception + public boolean isProofNNFStar() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_STAR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_STAR; } /** @@ -1488,9 +1487,9 @@ public class Expr extends AST * PROOF_MODE is 1. This proof object may have n antecedents. Each * antecedent is a PR_DEF_INTRO. **/ - public boolean IsProofCNFStar() throws Z3Exception + public boolean isProofCNFStar() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_CNF_STAR; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_CNF_STAR; } /** @@ -1502,9 +1501,9 @@ public class Expr extends AST * * This proof object has no antecedents. **/ - public boolean IsProofSkolemize() throws Z3Exception + public boolean isProofSkolemize() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_SKOLEMIZE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_SKOLEMIZE; } /** @@ -1512,9 +1511,9 @@ public class Expr extends AST * equi-satisfiability. Modus ponens style rule for * equi-satisfiability. T1: p T2: (~ p q) [mp~ T1 T2]: q **/ - public boolean IsProofModusPonensOEQ() throws Z3Exception + public boolean isProofModusPonensOEQ() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS_OEQ; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS_OEQ; } /** @@ -1531,19 +1530,19 @@ public class Expr extends AST * t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear * arithmetic lemma that uses a gcd test. **/ - public boolean IsProofTheoryLemma() throws Z3Exception + public boolean isProofTheoryLemma() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TH_LEMMA; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_PR_TH_LEMMA; } /** * Indicates whether the term is of an array sort. **/ - public boolean IsRelation() throws Z3Exception + public boolean isRelation() throws Z3Exception { - return (Native.isApp(Context().nCtx(), NativeObject()) && Native - .getSortKind(Context().nCtx(), - Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_RELATION_SORT + return (Native.isApp(getContext().nCtx(), getNativeObject()) && Native + .getSortKind(getContext().nCtx(), + Native.getSort(getContext().nCtx(), getNativeObject())) == Z3_sort_kind.Z3_RELATION_SORT .toInt()); } @@ -1553,51 +1552,51 @@ public class Expr extends AST * first argument is the relation and the remaining n elements * correspond to the n columns of the relation. **/ - public boolean IsRelationStore() throws Z3Exception + public boolean isRelationStore() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_STORE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_STORE; } /** * Indicates whether the term is an empty relation **/ - public boolean IsEmptyRelation() throws Z3Exception + public boolean isEmptyRelation() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_EMPTY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_EMPTY; } /** * Indicates whether the term is a test for the emptiness of a relation **/ - public boolean IsIsEmptyRelation() throws Z3Exception + public boolean isIsEmptyRelation() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_IS_EMPTY; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_IS_EMPTY; } /** * Indicates whether the term is a relational join **/ - public boolean IsRelationalJoin() throws Z3Exception + public boolean isRelationalJoin() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_JOIN; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_JOIN; } /** * Indicates whether the term is the union or convex hull of two relations. * The function takes two arguments. **/ - public boolean IsRelationUnion() throws Z3Exception + public boolean isRelationUnion() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_UNION; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_UNION; } /** * Indicates whether the term is the widening of two relations The * function takes two arguments. **/ - public boolean IsRelationWiden() throws Z3Exception + public boolean isRelationWiden() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_WIDEN; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_WIDEN; } /** @@ -1605,9 +1604,9 @@ public class Expr extends AST * numbers in the parameters). The function takes one * argument. **/ - public boolean IsRelationProject() throws Z3Exception + public boolean isRelationProject() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_PROJECT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_PROJECT; } /** @@ -1617,9 +1616,9 @@ public class Expr extends AST * indices corresponding to the columns of the relation. So the first column * in the relation has index 0. **/ - public boolean IsRelationFilter() throws Z3Exception + public boolean isRelationFilter() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_FILTER; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_FILTER; } /** @@ -1634,9 +1633,9 @@ public class Expr extends AST * such that target are elements in x in pos, such that there is no y in neg * that agrees with x on the columns c1, d1, .., cN, dN. **/ - public boolean IsRelationNegationFilter() throws Z3Exception + public boolean isRelationNegationFilter() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_NEGATION_FILTER; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_NEGATION_FILTER; } /** @@ -1644,17 +1643,17 @@ public class Expr extends AST * The function takes one argument. The parameters contain the * renaming as a cycle. **/ - public boolean IsRelationRename() throws Z3Exception + public boolean isRelationRename() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_RENAME; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_RENAME; } /** * Indicates whether the term is the complement of a relation **/ - public boolean IsRelationComplement() throws Z3Exception + public boolean isRelationComplement() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_COMPLEMENT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_COMPLEMENT; } /** @@ -1663,9 +1662,9 @@ public class Expr extends AST * arguments, where the first argument is a relation, and the remaining * n arguments correspond to a record. **/ - public boolean IsRelationSelect() throws Z3Exception + public boolean isRelationSelect() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_SELECT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_SELECT; } /** @@ -1675,28 +1674,28 @@ public class Expr extends AST * kind to perform destructive updates to * the first argument. **/ - public boolean IsRelationClone() throws Z3Exception + public boolean isRelationClone() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_CLONE; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_RA_CLONE; } /** * Indicates whether the term is of an array sort. **/ - public boolean IsFiniteDomain() throws Z3Exception + public boolean isFiniteDomain() throws Z3Exception { - return (Native.isApp(Context().nCtx(), NativeObject()) && Native - .getSortKind(Context().nCtx(), - Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_FINITE_DOMAIN_SORT + return (Native.isApp(getContext().nCtx(), getNativeObject()) && Native + .getSortKind(getContext().nCtx(), + Native.getSort(getContext().nCtx(), getNativeObject())) == Z3_sort_kind.Z3_FINITE_DOMAIN_SORT .toInt()); } /** * Indicates whether the term is a less than predicate over a finite domain. **/ - public boolean IsFiniteDomainLT() throws Z3Exception + public boolean isFiniteDomainLT() throws Z3Exception { - return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_FD_LT; + return getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FD_LT; } /** @@ -1714,12 +1713,12 @@ public class Expr extends AST * different depending on the scope in which it appears. The deeper x * appears, the higher is its index. **/ - public int Index() throws Z3Exception + public int getIndex() throws Z3Exception { - if (!IsVar()) + if (!isVar()) throw new Z3Exception("Term is not a bound variable."); - return Native.getIndexValue(Context().nCtx(), NativeObject()); + return Native.getIndexValue(getContext().nCtx(), getNativeObject()); } /** @@ -1742,30 +1741,25 @@ public class Expr extends AST } } - void CheckNativeObject(long obj) throws Z3Exception + void checkNativeObject(long obj) throws Z3Exception { - if (Native.isApp(Context().nCtx(), obj) - ^ true - && Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_VAR_AST - .toInt() - && Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_QUANTIFIER_AST - .toInt()) - throw new Z3Exception("Underlying object is not a term"); - super.CheckNativeObject(obj); + if (!Native.isApp(getContext().nCtx(), obj) && + Native.getAstKind(getContext().nCtx(), obj) != Z3_ast_kind.Z3_VAR_AST.toInt() && + Native.getAstKind(getContext().nCtx(), obj) != Z3_ast_kind.Z3_QUANTIFIER_AST.toInt()) + throw new Z3Exception("Underlying object is not a term"); + super.checkNativeObject(obj); } - static Expr Create(Context ctx, FuncDecl f, Expr[] arguments) + static Expr create(Context ctx, FuncDecl f, Expr ... arguments) throws Z3Exception { - - long obj = Native.mkApp(ctx.nCtx(), f.NativeObject(), - AST.ArrayLength(arguments), AST.ArrayToNative(arguments)); - return Create(ctx, obj); + long obj = Native.mkApp(ctx.nCtx(), f.getNativeObject(), + AST.arrayLength(arguments), AST.arrayToNative(arguments)); + return create(ctx, obj); } - static Expr Create(Context ctx, long obj) throws Z3Exception + static Expr create(Context ctx, long obj) throws Z3Exception { - Z3_ast_kind k = Z3_ast_kind.fromInt(Native.getAstKind(ctx.nCtx(), obj)); if (k == Z3_ast_kind.Z3_QUANTIFIER_AST) return new Quantifier(ctx, obj); diff --git a/src/api/java/FiniteDomainSort.java b/src/api/java/FiniteDomainSort.java index 8c39320ad..a8ba0d8c3 100644 --- a/src/api/java/FiniteDomainSort.java +++ b/src/api/java/FiniteDomainSort.java @@ -14,10 +14,10 @@ public class FiniteDomainSort extends Sort /** * The size of the finite domain sort. **/ - public long Size() throws Z3Exception + public long getSize() throws Z3Exception { Native.LongPtr res = new Native.LongPtr(); - Native.getFiniteDomainSortSize(Context().nCtx(), NativeObject(), res); + Native.getFiniteDomainSortSize(getContext().nCtx(), getNativeObject(), res); return res.value; } @@ -28,7 +28,7 @@ public class FiniteDomainSort extends Sort FiniteDomainSort(Context ctx, Symbol name, long size) throws Z3Exception { - super(ctx, Native.mkFiniteDomainSort(ctx.nCtx(), name.NativeObject(), + super(ctx, Native.mkFiniteDomainSort(ctx.nCtx(), name.getNativeObject(), size)); } } diff --git a/src/api/java/Fixedpoint.java b/src/api/java/Fixedpoint.java index 375cb7b97..6a8cafae2 100644 --- a/src/api/java/Fixedpoint.java +++ b/src/api/java/Fixedpoint.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_lbool; /** * Object for managing fixedpoints @@ -17,9 +17,9 @@ public class Fixedpoint extends Z3Object /** * A string that describes all available fixedpoint solver parameters. **/ - public String Help() throws Z3Exception + public String getHelp() throws Z3Exception { - return Native.fixedpointGetHelp(Context().nCtx(), NativeObject()); + return Native.fixedpointGetHelp(getContext().nCtx(), getNativeObject()); } /** @@ -30,9 +30,9 @@ public class Fixedpoint extends Z3Object public void setParameters(Params value) throws Z3Exception { - Context().CheckContextMatch(value); - Native.fixedpointSetParams(Context().nCtx(), NativeObject(), - value.NativeObject()); + getContext().checkContextMatch(value); + Native.fixedpointSetParams(getContext().nCtx(), getNativeObject(), + value.getNativeObject()); } /** @@ -40,10 +40,10 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public ParamDescrs ParameterDescriptions() throws Z3Exception + public ParamDescrs getParameterDescriptions() throws Z3Exception { - return new ParamDescrs(Context(), Native.fixedpointGetParamDescrs( - Context().nCtx(), NativeObject())); + return new ParamDescrs(getContext(), Native.fixedpointGetParamDescrs( + getContext().nCtx(), getNativeObject())); } /** @@ -51,13 +51,13 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public void Assert(BoolExpr[] constraints) throws Z3Exception + public void assert_(BoolExpr ... constraints) throws Z3Exception { - Context().CheckContextMatch(constraints); + getContext().checkContextMatch(constraints); for (BoolExpr a : constraints) { - Native.fixedpointAssert(Context().nCtx(), NativeObject(), - a.NativeObject()); + Native.fixedpointAssert(getContext().nCtx(), getNativeObject(), + a.getNativeObject()); } } @@ -66,12 +66,12 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public void RegisterRelation(FuncDecl f) throws Z3Exception + public void registerRelation(FuncDecl f) throws Z3Exception { - Context().CheckContextMatch(f); - Native.fixedpointRegisterRelation(Context().nCtx(), NativeObject(), - f.NativeObject()); + getContext().checkContextMatch(f); + Native.fixedpointRegisterRelation(getContext().nCtx(), getNativeObject(), + f.getNativeObject()); } /** @@ -79,12 +79,12 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public void AddRule(BoolExpr rule, Symbol name) throws Z3Exception + public void addRule(BoolExpr rule, Symbol name) throws Z3Exception { - Context().CheckContextMatch(rule); - Native.fixedpointAddRule(Context().nCtx(), NativeObject(), - rule.NativeObject(), AST.GetNativeObject(name)); + getContext().checkContextMatch(rule); + Native.fixedpointAddRule(getContext().nCtx(), getNativeObject(), + rule.getNativeObject(), AST.getNativeObject(name)); } /** @@ -92,12 +92,11 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public void AddFact(FuncDecl pred, int[] args) throws Z3Exception + public void addFact(FuncDecl pred, int ... args) throws Z3Exception { - - Context().CheckContextMatch(pred); - Native.fixedpointAddFact(Context().nCtx(), NativeObject(), - pred.NativeObject(), (int) args.length, args); + getContext().checkContextMatch(pred); + Native.fixedpointAddFact(getContext().nCtx(), getNativeObject(), + pred.getNativeObject(), (int) args.length, args); } /** @@ -109,12 +108,12 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public Status Query(BoolExpr query) throws Z3Exception + public Status query(BoolExpr query) throws Z3Exception { - Context().CheckContextMatch(query); - Z3_lbool r = Z3_lbool.fromInt(Native.fixedpointQuery(Context().nCtx(), - NativeObject(), query.NativeObject())); + getContext().checkContextMatch(query); + Z3_lbool r = Z3_lbool.fromInt(Native.fixedpointQuery(getContext().nCtx(), + getNativeObject(), query.getNativeObject())); switch (r) { case Z3_L_TRUE: @@ -134,13 +133,13 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public Status Query(FuncDecl[] relations) throws Z3Exception + public Status query(FuncDecl[] relations) throws Z3Exception { - Context().CheckContextMatch(relations); - Z3_lbool r = Z3_lbool.fromInt(Native.fixedpointQueryRelations(Context() - .nCtx(), NativeObject(), AST.ArrayLength(relations), AST - .ArrayToNative(relations))); + getContext().checkContextMatch(relations); + Z3_lbool r = Z3_lbool.fromInt(Native.fixedpointQueryRelations(getContext() + .nCtx(), getNativeObject(), AST.arrayLength(relations), AST + .arrayToNative(relations))); switch (r) { case Z3_L_TRUE: @@ -155,9 +154,9 @@ public class Fixedpoint extends Z3Object /** * Creates a backtracking point. **/ - public void Push() throws Z3Exception + public void push() throws Z3Exception { - Native.fixedpointPush(Context().nCtx(), NativeObject()); + Native.fixedpointPush(getContext().nCtx(), getNativeObject()); } /** @@ -165,9 +164,9 @@ public class Fixedpoint extends Z3Object * thrown if Pop is called without a corresponding Push * **/ - public void Pop() throws Z3Exception + public void pop() throws Z3Exception { - Native.fixedpointPop(Context().nCtx(), NativeObject()); + Native.fixedpointPop(getContext().nCtx(), getNativeObject()); } /** @@ -175,12 +174,12 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public void UpdateRule(BoolExpr rule, Symbol name) throws Z3Exception + public void updateRule(BoolExpr rule, Symbol name) throws Z3Exception { - Context().CheckContextMatch(rule); - Native.fixedpointUpdateRule(Context().nCtx(), NativeObject(), - rule.NativeObject(), AST.GetNativeObject(name)); + getContext().checkContextMatch(rule); + Native.fixedpointUpdateRule(getContext().nCtx(), getNativeObject(), + rule.getNativeObject(), AST.getNativeObject(name)); } /** @@ -189,29 +188,29 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public Expr GetAnswer() throws Z3Exception + public Expr getAnswer() throws Z3Exception { - long ans = Native.fixedpointGetAnswer(Context().nCtx(), NativeObject()); - return (ans == 0) ? null : Expr.Create(Context(), ans); + long ans = Native.fixedpointGetAnswer(getContext().nCtx(), getNativeObject()); + return (ans == 0) ? null : Expr.create(getContext(), ans); } /** * Retrieve explanation why fixedpoint engine returned status Unknown. **/ - public String GetReasonUnknown() throws Z3Exception + public String getReasonUnknown() throws Z3Exception { - return Native.fixedpointGetReasonUnknown(Context().nCtx(), - NativeObject()); + return Native.fixedpointGetReasonUnknown(getContext().nCtx(), + getNativeObject()); } /** * Retrieve the number of levels explored for a given predicate. **/ - public int GetNumLevels(FuncDecl predicate) throws Z3Exception + public int getNumLevels(FuncDecl predicate) throws Z3Exception { - return Native.fixedpointGetNumLevels(Context().nCtx(), NativeObject(), - predicate.NativeObject()); + return Native.fixedpointGetNumLevels(getContext().nCtx(), getNativeObject(), + predicate.getNativeObject()); } /** @@ -219,22 +218,22 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public Expr GetCoverDelta(int level, FuncDecl predicate) throws Z3Exception + public Expr getCoverDelta(int level, FuncDecl predicate) throws Z3Exception { - long res = Native.fixedpointGetCoverDelta(Context().nCtx(), - NativeObject(), level, predicate.NativeObject()); - return (res == 0) ? null : Expr.Create(Context(), res); + long res = Native.fixedpointGetCoverDelta(getContext().nCtx(), + getNativeObject(), level, predicate.getNativeObject()); + return (res == 0) ? null : Expr.create(getContext(), res); } /** * Add property about the predicate. The property is added * at level. **/ - public void AddCover(int level, FuncDecl predicate, Expr property) + public void addCover(int level, FuncDecl predicate, Expr property) throws Z3Exception { - Native.fixedpointAddCover(Context().nCtx(), NativeObject(), level, - predicate.NativeObject(), property.NativeObject()); + Native.fixedpointAddCover(getContext().nCtx(), getNativeObject(), level, + predicate.getNativeObject(), property.getNativeObject()); } /** @@ -244,7 +243,7 @@ public class Fixedpoint extends Z3Object { try { - return Native.fixedpointToString(Context().nCtx(), NativeObject(), + return Native.fixedpointToString(getContext().nCtx(), getNativeObject(), 0, null); } catch (Z3Exception e) { @@ -256,12 +255,12 @@ public class Fixedpoint extends Z3Object * Instrument the Datalog engine on which table representation to use for * recursive predicate. **/ - public void SetPredicateRepresentation(FuncDecl f, Symbol[] kinds) throws Z3Exception + public void setPredicateRepresentation(FuncDecl f, Symbol[] kinds) throws Z3Exception { - Native.fixedpointSetPredicateRepresentation(Context().nCtx(), - NativeObject(), f.NativeObject(), AST.ArrayLength(kinds), - Symbol.ArrayToNative(kinds)); + Native.fixedpointSetPredicateRepresentation(getContext().nCtx(), + getNativeObject(), f.getNativeObject(), AST.arrayLength(kinds), + Symbol.arrayToNative(kinds)); } @@ -271,8 +270,8 @@ public class Fixedpoint extends Z3Object public String toString(BoolExpr[] queries) throws Z3Exception { - return Native.fixedpointToString(Context().nCtx(), NativeObject(), - AST.ArrayLength(queries), AST.ArrayToNative(queries)); + return Native.fixedpointToString(getContext().nCtx(), getNativeObject(), + AST.arrayLength(queries), AST.arrayToNative(queries)); } /** @@ -280,15 +279,15 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public BoolExpr[] Rules() throws Z3Exception + public BoolExpr[] getRules() throws Z3Exception { - ASTVector v = new ASTVector(Context(), Native.fixedpointGetRules( - Context().nCtx(), NativeObject())); - int n = v.Size(); + ASTVector v = new ASTVector(getContext(), Native.fixedpointGetRules( + getContext().nCtx(), getNativeObject())); + int n = v.size(); BoolExpr[] res = new BoolExpr[n]; for (int i = 0; i < n; i++) - res[i] = new BoolExpr(Context(), v.get(i).NativeObject()); + res[i] = new BoolExpr(getContext(), v.get(i).getNativeObject()); return res; } @@ -297,15 +296,15 @@ public class Fixedpoint extends Z3Object * * @throws Z3Exception **/ - public BoolExpr[] Assertions() throws Z3Exception + public BoolExpr[] getAssertions() throws Z3Exception { - ASTVector v = new ASTVector(Context(), Native.fixedpointGetAssertions( - Context().nCtx(), NativeObject())); - int n = v.Size(); + ASTVector v = new ASTVector(getContext(), Native.fixedpointGetAssertions( + getContext().nCtx(), getNativeObject())); + int n = v.size(); BoolExpr[] res = new BoolExpr[n]; for (int i = 0; i < n; i++) - res[i] = new BoolExpr(Context(), v.get(i).NativeObject()); + res[i] = new BoolExpr(getContext(), v.get(i).getNativeObject()); return res; } @@ -319,15 +318,15 @@ public class Fixedpoint extends Z3Object super(ctx, Native.mkFixedpoint(ctx.nCtx())); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Fixedpoint_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().fixedpoint_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Fixedpoint_DRQ().Add(o); - super.DecRef(o); + getContext().fixedpoint_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/FixedpointDecRefQueue.java b/src/api/java/FixedpointDecRefQueue.java index 677691db8..e52389b85 100644 --- a/src/api/java/FixedpointDecRefQueue.java +++ b/src/api/java/FixedpointDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class FixedpointDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class FixedpointDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/FuncDecl.java b/src/api/java/FuncDecl.java index a2bf28c5d..ada44bbd7 100644 --- a/src/api/java/FuncDecl.java +++ b/src/api/java/FuncDecl.java @@ -6,7 +6,9 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_ast_kind; +import com.microsoft.z3.enumerations.Z3_decl_kind; +import com.microsoft.z3.enumerations.Z3_parameter_kind; /** * Function declarations. @@ -32,7 +34,7 @@ public class FuncDecl extends AST /** * Object comparison. **/ - public boolean Equals(Object o) + public boolean equals(Object o) { FuncDecl casted = (FuncDecl) o; if (casted == null) @@ -43,9 +45,9 @@ public class FuncDecl extends AST /** * A hash code. **/ - public int GetHashCode() throws Z3Exception + public int hashCode() { - return super.GetHashCode(); + return super.hashCode(); } /** @@ -55,7 +57,7 @@ public class FuncDecl extends AST { try { - return Native.funcDeclToString(Context().nCtx(), NativeObject()); + return Native.funcDeclToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -65,125 +67,125 @@ public class FuncDecl extends AST /** * Returns a unique identifier for the function declaration. **/ - public int Id() throws Z3Exception + public int getId() throws Z3Exception { - return Native.getFuncDeclId(Context().nCtx(), NativeObject()); + return Native.getFuncDeclId(getContext().nCtx(), getNativeObject()); } /** * The arity of the function declaration **/ - public int Arity() throws Z3Exception + public int getArity() throws Z3Exception { - return Native.getArity(Context().nCtx(), NativeObject()); + return Native.getArity(getContext().nCtx(), getNativeObject()); } /** * The size of the domain of the function declaration **/ - public int DomainSize() throws Z3Exception + public int getDomainSize() throws Z3Exception { - return Native.getDomainSize(Context().nCtx(), NativeObject()); + return Native.getDomainSize(getContext().nCtx(), getNativeObject()); } /** * The domain of the function declaration **/ - public Sort[] Domain() throws Z3Exception + public Sort[] getDomain() throws Z3Exception { - int n = DomainSize(); + int n = getDomainSize(); Sort[] res = new Sort[n]; for (int i = 0; i < n; i++) - res[i] = Sort.Create(Context(), - Native.getDomain(Context().nCtx(), NativeObject(), i)); + res[i] = Sort.create(getContext(), + Native.getDomain(getContext().nCtx(), getNativeObject(), i)); return res; } /** * The range of the function declaration **/ - public Sort Range() throws Z3Exception + public Sort getRange() throws Z3Exception { - return Sort.Create(Context(), - Native.getRange(Context().nCtx(), NativeObject())); + return Sort.create(getContext(), + Native.getRange(getContext().nCtx(), getNativeObject())); } /** * The kind of the function declaration. **/ - public Z3_decl_kind DeclKind() throws Z3Exception + public Z3_decl_kind getDeclKind() throws Z3Exception { - return Z3_decl_kind.fromInt(Native.getDeclKind(Context().nCtx(), - NativeObject())); + return Z3_decl_kind.fromInt(Native.getDeclKind(getContext().nCtx(), + getNativeObject())); } /** * The name of the function declaration **/ - public Symbol Name() throws Z3Exception + public Symbol getName() throws Z3Exception { - return Symbol.Create(Context(), - Native.getDeclName(Context().nCtx(), NativeObject())); + return Symbol.create(getContext(), + Native.getDeclName(getContext().nCtx(), getNativeObject())); } /** * The number of parameters of the function declaration **/ - public int NumParameters() throws Z3Exception + public int getNumParameters() throws Z3Exception { - return Native.getDeclNumParameters(Context().nCtx(), NativeObject()); + return Native.getDeclNumParameters(getContext().nCtx(), getNativeObject()); } /** * The parameters of the function declaration **/ - public Parameter[] Parameters() throws Z3Exception + public Parameter[] getParameters() throws Z3Exception { - int num = NumParameters(); + int num = getNumParameters(); Parameter[] res = new Parameter[num]; for (int i = 0; i < num; i++) { Z3_parameter_kind k = Z3_parameter_kind.fromInt(Native - .getDeclParameterKind(Context().nCtx(), NativeObject(), i)); + .getDeclParameterKind(getContext().nCtx(), getNativeObject(), i)); switch (k) { case Z3_PARAMETER_INT: - res[i] = new Parameter(k, Native.getDeclIntParameter(Context() - .nCtx(), NativeObject(), i)); + res[i] = new Parameter(k, Native.getDeclIntParameter(getContext() + .nCtx(), getNativeObject(), i)); break; case Z3_PARAMETER_DOUBLE: res[i] = new Parameter(k, Native.getDeclDoubleParameter( - Context().nCtx(), NativeObject(), i)); + getContext().nCtx(), getNativeObject(), i)); break; case Z3_PARAMETER_SYMBOL: - res[i] = new Parameter(k, Symbol.Create(Context(), Native - .getDeclSymbolParameter(Context().nCtx(), - NativeObject(), i))); + res[i] = new Parameter(k, Symbol.create(getContext(), Native + .getDeclSymbolParameter(getContext().nCtx(), + getNativeObject(), i))); break; case Z3_PARAMETER_SORT: - res[i] = new Parameter(k, Sort.Create(Context(), Native - .getDeclSortParameter(Context().nCtx(), NativeObject(), + res[i] = new Parameter(k, Sort.create(getContext(), Native + .getDeclSortParameter(getContext().nCtx(), getNativeObject(), i))); break; case Z3_PARAMETER_AST: - res[i] = new Parameter(k, new AST(Context(), - Native.getDeclAstParameter(Context().nCtx(), - NativeObject(), i))); + res[i] = new Parameter(k, new AST(getContext(), + Native.getDeclAstParameter(getContext().nCtx(), + getNativeObject(), i))); break; case Z3_PARAMETER_FUNC_DECL: - res[i] = new Parameter(k, new FuncDecl(Context(), - Native.getDeclFuncDeclParameter(Context().nCtx(), - NativeObject(), i))); + res[i] = new Parameter(k, new FuncDecl(getContext(), + Native.getDeclFuncDeclParameter(getContext().nCtx(), + getNativeObject(), i))); break; case Z3_PARAMETER_RATIONAL: res[i] = new Parameter(k, Native.getDeclRationalParameter( - Context().nCtx(), NativeObject(), i)); + getContext().nCtx(), getNativeObject(), i)); break; default: throw new Z3Exception( @@ -210,9 +212,9 @@ public class FuncDecl extends AST /** * The int value of the parameter. **/ - public int Int() throws Z3Exception + public int getInt() throws Z3Exception { - if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_INT) + if (getParameterKind() != Z3_parameter_kind.Z3_PARAMETER_INT) throw new Z3Exception("parameter is not an int"); return i; } @@ -220,9 +222,9 @@ public class FuncDecl extends AST /** * The double value of the parameter. **/ - public double Double() throws Z3Exception + public double getDouble() throws Z3Exception { - if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_DOUBLE) + if (getParameterKind() != Z3_parameter_kind.Z3_PARAMETER_DOUBLE) throw new Z3Exception("parameter is not a double "); return d; } @@ -230,9 +232,9 @@ public class FuncDecl extends AST /** * The Symbol value of the parameter. **/ - public Symbol Symbol() throws Z3Exception + public Symbol getSymbol() throws Z3Exception { - if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_SYMBOL) + if (getParameterKind() != Z3_parameter_kind.Z3_PARAMETER_SYMBOL) throw new Z3Exception("parameter is not a Symbol"); return sym; } @@ -240,9 +242,9 @@ public class FuncDecl extends AST /** * The Sort value of the parameter. **/ - public Sort Sort() throws Z3Exception + public Sort getSort() throws Z3Exception { - if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_SORT) + if (getParameterKind() != Z3_parameter_kind.Z3_PARAMETER_SORT) throw new Z3Exception("parameter is not a Sort"); return srt; } @@ -250,9 +252,9 @@ public class FuncDecl extends AST /** * The AST value of the parameter. **/ - public AST AST() throws Z3Exception + public AST getAST() throws Z3Exception { - if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_AST) + if (getParameterKind() != Z3_parameter_kind.Z3_PARAMETER_AST) throw new Z3Exception("parameter is not an AST"); return ast; } @@ -260,9 +262,9 @@ public class FuncDecl extends AST /** * The FunctionDeclaration value of the parameter. **/ - public FuncDecl FuncDecl() throws Z3Exception + public FuncDecl getFuncDecl() throws Z3Exception { - if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL) + if (getParameterKind() != Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL) throw new Z3Exception("parameter is not a function declaration"); return fd; } @@ -270,9 +272,9 @@ public class FuncDecl extends AST /** * The rational string value of the parameter. **/ - public String Rational() throws Z3Exception + public String getRational() throws Z3Exception { - if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_RATIONAL) + if (getParameterKind() != Z3_parameter_kind.Z3_PARAMETER_RATIONAL) throw new Z3Exception("parameter is not a rational String"); return r; } @@ -280,7 +282,7 @@ public class FuncDecl extends AST /** * The kind of the parameter. **/ - public Z3_parameter_kind ParameterKind() throws Z3Exception + public Z3_parameter_kind getParameterKind() throws Z3Exception { return kind; } @@ -337,9 +339,9 @@ public class FuncDecl extends AST FuncDecl(Context ctx, Symbol name, Sort[] domain, Sort range) throws Z3Exception { - super(ctx, Native.mkFuncDecl(ctx.nCtx(), name.NativeObject(), - AST.ArrayLength(domain), AST.ArrayToNative(domain), - range.NativeObject())); + super(ctx, Native.mkFuncDecl(ctx.nCtx(), name.getNativeObject(), + AST.arrayLength(domain), AST.arrayToNative(domain), + range.getNativeObject())); } @@ -347,18 +349,18 @@ public class FuncDecl extends AST throws Z3Exception { super(ctx, Native.mkFreshFuncDecl(ctx.nCtx(), prefix, - AST.ArrayLength(domain), AST.ArrayToNative(domain), - range.NativeObject())); + AST.arrayLength(domain), AST.arrayToNative(domain), + range.getNativeObject())); } - void CheckNativeObject(long obj) throws Z3Exception + void checkNativeObject(long obj) throws Z3Exception { - if (Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_FUNC_DECL_AST + if (Native.getAstKind(getContext().nCtx(), obj) != Z3_ast_kind.Z3_FUNC_DECL_AST .toInt()) throw new Z3Exception( "Underlying object is not a function declaration"); - super.CheckNativeObject(obj); + super.checkNativeObject(obj); } /** @@ -367,31 +369,9 @@ public class FuncDecl extends AST * * @return **/ - /* operator this[] not translated */ - - /** - * Create expression that applies function to arguments. - * - * @return - **/ - public Expr Apply(Expr[] args) throws Z3Exception + public Expr apply(Expr ... args) throws Z3Exception { - Context().CheckContextMatch(args); - return Expr.Create(Context(), this, args); + getContext().checkContextMatch(args); + return Expr.create(getContext(), this, args); } - - /** - * Create expression that applies function to one argument. - * - * @return - **/ - public Expr Apply(Expr arg) throws Z3Exception - { - Context().CheckContextMatch(arg); - Expr[] a = { arg }; - return Expr.Create(Context(), this, a); - } - } diff --git a/src/api/java/FuncInterp.java b/src/api/java/FuncInterp.java index 261f433e7..b7fa118e9 100644 --- a/src/api/java/FuncInterp.java +++ b/src/api/java/FuncInterp.java @@ -24,18 +24,18 @@ public class FuncInterp extends Z3Object * * @throws Z3Exception **/ - public Expr Value() throws Z3Exception + public Expr getValue() throws Z3Exception { - return Expr.Create(Context(), - Native.funcEntryGetValue(Context().nCtx(), NativeObject())); + return Expr.create(getContext(), + Native.funcEntryGetValue(getContext().nCtx(), getNativeObject())); } /** * The number of arguments of the entry. **/ - public int NumArgs() throws Z3Exception + public int getNumArgs() throws Z3Exception { - return Native.funcEntryGetNumArgs(Context().nCtx(), NativeObject()); + return Native.funcEntryGetNumArgs(getContext().nCtx(), getNativeObject()); } /** @@ -43,13 +43,13 @@ public class FuncInterp extends Z3Object * * @throws Z3Exception **/ - public Expr[] Args() throws Z3Exception + public Expr[] getArgs() throws Z3Exception { - int n = NumArgs(); + int n = getNumArgs(); Expr[] res = new Expr[n]; for (int i = 0; i < n; i++) - res[i] = Expr.Create(Context(), Native.funcEntryGetArg( - Context().nCtx(), NativeObject(), i)); + res[i] = Expr.create(getContext(), Native.funcEntryGetArg( + getContext().nCtx(), getNativeObject(), i)); return res; } @@ -60,12 +60,12 @@ public class FuncInterp extends Z3Object { try { - int n = NumArgs(); + int n = getNumArgs(); String res = "["; - Expr[] args = Args(); + Expr[] args = getArgs(); for (int i = 0; i < n; i++) res += args[i] + ", "; - return res + Value() + "]"; + return res + getValue() + "]"; } catch (Z3Exception e) { return new String("Z3Exception: " + e.getMessage()); @@ -77,25 +77,25 @@ public class FuncInterp extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().FuncEntry_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().funcEntry_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().FuncEntry_DRQ().Add(o); - super.DecRef(o); + getContext().funcEntry_DRQ().add(o); + super.decRef(o); } }; /** * The number of entries in the function interpretation. **/ - public int NumEntries() throws Z3Exception + public int getNumEntries() throws Z3Exception { - return Native.funcInterpGetNumEntries(Context().nCtx(), NativeObject()); + return Native.funcInterpGetNumEntries(getContext().nCtx(), getNativeObject()); } /** @@ -103,13 +103,13 @@ public class FuncInterp extends Z3Object * * @throws Z3Exception **/ - public Entry[] Entries() throws Z3Exception + public Entry[] getEntries() throws Z3Exception { - int n = NumEntries(); + int n = getNumEntries(); Entry[] res = new Entry[n]; for (int i = 0; i < n; i++) - res[i] = new Entry(Context(), Native.funcInterpGetEntry(Context() - .nCtx(), NativeObject(), i)); + res[i] = new Entry(getContext(), Native.funcInterpGetEntry(getContext() + .nCtx(), getNativeObject(), i)); return res; } @@ -118,18 +118,18 @@ public class FuncInterp extends Z3Object * * @throws Z3Exception **/ - public Expr Else() throws Z3Exception + public Expr getElse() throws Z3Exception { - return Expr.Create(Context(), - Native.funcInterpGetElse(Context().nCtx(), NativeObject())); + return Expr.create(getContext(), + Native.funcInterpGetElse(getContext().nCtx(), getNativeObject())); } /** * The arity of the function interpretation **/ - public int Arity() throws Z3Exception + public int getArity() throws Z3Exception { - return Native.funcInterpGetArity(Context().nCtx(), NativeObject()); + return Native.funcInterpGetArity(getContext().nCtx(), getNativeObject()); } /** @@ -141,12 +141,12 @@ public class FuncInterp extends Z3Object { String res = ""; res += "["; - for (Entry e : Entries()) + for (Entry e : getEntries()) { - int n = e.NumArgs(); + int n = e.getNumArgs(); if (n > 1) res += "["; - Expr[] args = e.Args(); + Expr[] args = e.getArgs(); for (int i = 0; i < n; i++) { if (i != 0) @@ -155,9 +155,9 @@ public class FuncInterp extends Z3Object } if (n > 1) res += "]"; - res += " -> " + e.Value() + ", "; + res += " -> " + e.getValue() + ", "; } - res += "else -> " + Else(); + res += "else -> " + getElse(); res += "]"; return res; } catch (Z3Exception e) @@ -171,15 +171,15 @@ public class FuncInterp extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().FuncInterp_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().funcInterp_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().FuncInterp_DRQ().Add(o); - super.DecRef(o); + getContext().funcInterp_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/FuncInterpDecRefQueue.java b/src/api/java/FuncInterpDecRefQueue.java index d1b662cb2..e2814a9b8 100644 --- a/src/api/java/FuncInterpDecRefQueue.java +++ b/src/api/java/FuncInterpDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class FuncInterpDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class FuncInterpDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/FuncInterpEntryDecRefQueue.java b/src/api/java/FuncInterpEntryDecRefQueue.java index df2702020..61488ec74 100644 --- a/src/api/java/FuncInterpEntryDecRefQueue.java +++ b/src/api/java/FuncInterpEntryDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class FuncInterpEntryDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class FuncInterpEntryDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/Global.java b/src/api/java/Global.java index c08691ded..33a828fb8 100644 --- a/src/api/java/Global.java +++ b/src/api/java/Global.java @@ -30,7 +30,7 @@ public final class Global * will set the parameter "decimal" in the module "pp" to true. * **/ - public static void SetParameter(String id, String value) + public static void setParameter(String id, String value) { Native.globalParamSet(id, value); } @@ -44,7 +44,7 @@ public final class Global * The result string stored in param_value is stored in a shared location. * **/ - public static String GetParameter(String id) + public static String getParameter(String id) { Native.StringPtr res = new Native.StringPtr(); if (!Native.globalParamGet(id, res)) @@ -60,7 +60,7 @@ public final class Global * * @seealso SetParameter **/ - public static void ResetParameters() + public static void resetParameters() { Native.globalParamResetAll(); } diff --git a/src/api/java/Goal.java b/src/api/java/Goal.java index 61ac96d30..520a7af15 100644 --- a/src/api/java/Goal.java +++ b/src/api/java/Goal.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_goal_prec; /** * A goal (aka problem). A goal is essentially a set of formulas, that can be @@ -21,43 +21,43 @@ public class Goal extends Z3Object * applied when the objective is to find a proof for a given goal. * **/ - public Z3_goal_prec Precision() throws Z3Exception + public Z3_goal_prec getPrecision() throws Z3Exception { - return Z3_goal_prec.fromInt(Native.goalPrecision(Context().nCtx(), - NativeObject())); + return Z3_goal_prec.fromInt(Native.goalPrecision(getContext().nCtx(), + getNativeObject())); } /** * Indicates whether the goal is precise. **/ - public boolean IsPrecise() throws Z3Exception + public boolean isPrecise() throws Z3Exception { - return Precision() == Z3_goal_prec.Z3_GOAL_PRECISE; + return getPrecision() == Z3_goal_prec.Z3_GOAL_PRECISE; } /** * Indicates whether the goal is an under-approximation. **/ - public boolean IsUnderApproximation() throws Z3Exception + public boolean isUnderApproximation() throws Z3Exception { - return Precision() == Z3_goal_prec.Z3_GOAL_UNDER; + return getPrecision() == Z3_goal_prec.Z3_GOAL_UNDER; } /** * Indicates whether the goal is an over-approximation. **/ - public boolean IsOverApproximation() throws Z3Exception + public boolean isOverApproximation() throws Z3Exception { - return Precision() == Z3_goal_prec.Z3_GOAL_OVER; + return getPrecision() == Z3_goal_prec.Z3_GOAL_OVER; } /** * Indicates whether the goal is garbage (i.e., the product of over- and * under-approximations). **/ - public boolean IsGarbage() throws Z3Exception + public boolean isGarbage() throws Z3Exception { - return Precision() == Z3_goal_prec.Z3_GOAL_UNDER_OVER; + return getPrecision() == Z3_goal_prec.Z3_GOAL_UNDER_OVER; } /** @@ -65,59 +65,47 @@ public class Goal extends Z3Object * * @throws Z3Exception **/ - public void Assert(BoolExpr[] constraints) throws Z3Exception + public void assert_(BoolExpr ... constraints) throws Z3Exception { - Context().CheckContextMatch(constraints); + getContext().checkContextMatch(constraints); for (BoolExpr c : constraints) { - Native.goalAssert(Context().nCtx(), NativeObject(), - c.NativeObject()); + Native.goalAssert(getContext().nCtx(), getNativeObject(), + c.getNativeObject()); } } - /** - * Adds a to the given goal. - * - * @throws Z3Exception - **/ - public void Assert(BoolExpr constraint) throws Z3Exception - { - Context().CheckContextMatch(constraint); - Native.goalAssert(Context().nCtx(), NativeObject(), - constraint.NativeObject()); - } - /** * Indicates whether the goal contains `false'. **/ - public boolean Inconsistent() throws Z3Exception + public boolean inconsistent() throws Z3Exception { - return Native.goalInconsistent(Context().nCtx(), NativeObject()); + return Native.goalInconsistent(getContext().nCtx(), getNativeObject()); } /** * The depth of the goal. This tracks how many transformations * were applied to it. **/ - public int Depth() throws Z3Exception + public int getDepth() throws Z3Exception { - return Native.goalDepth(Context().nCtx(), NativeObject()); + return Native.goalDepth(getContext().nCtx(), getNativeObject()); } /** * Erases all formulas from the given goal. **/ - public void Reset() throws Z3Exception + public void reset() throws Z3Exception { - Native.goalReset(Context().nCtx(), NativeObject()); + Native.goalReset(getContext().nCtx(), getNativeObject()); } /** * The number of formulas in the goal. **/ - public int Size() throws Z3Exception + public int size() throws Z3Exception { - return Native.goalSize(Context().nCtx(), NativeObject()); + return Native.goalSize(getContext().nCtx(), getNativeObject()); } /** @@ -125,40 +113,41 @@ public class Goal extends Z3Object * * @throws Z3Exception **/ - public BoolExpr[] Formulas() throws Z3Exception + public BoolExpr[] getFormulas() throws Z3Exception { - int n = Size(); + int n = size(); BoolExpr[] res = new BoolExpr[n]; for (int i = 0; i < n; i++) - res[i] = new BoolExpr(Context(), Native.goalFormula(Context() - .nCtx(), NativeObject(), i)); + res[i] = new BoolExpr(getContext(), Native.goalFormula(getContext() + .nCtx(), getNativeObject(), i)); return res; } /** * The number of formulas, subformulas and terms in the goal. **/ - public int NumExprs() throws Z3Exception + public int getNumExprs() throws Z3Exception { - return Native.goalNumExprs(Context().nCtx(), NativeObject()); + return Native.goalNumExprs(getContext().nCtx(), getNativeObject()); } /** * Indicates whether the goal is empty, and it is precise or the product of * an under approximation. **/ - public boolean IsDecidedSat() throws Z3Exception + public boolean isDecidedSat() throws Z3Exception { - return Native.goalIsDecidedSat(Context().nCtx(), NativeObject()); + return Native.goalIsDecidedSat(getContext().nCtx(), getNativeObject()); } /** * Indicates whether the goal contains `false', and it is precise or the * product of an over approximation. **/ - public boolean IsDecidedUnsat() throws Z3Exception + public boolean isDecidedUnsat() throws Z3Exception { - return Native.goalIsDecidedUnsat(Context().nCtx(), NativeObject()); + return Native + .goalIsDecidedUnsat(getContext().nCtx(), getNativeObject()); } /** @@ -167,25 +156,40 @@ public class Goal extends Z3Object * * @throws Z3Exception **/ - public Goal Translate(Context ctx) throws Z3Exception + public Goal translate(Context ctx) throws Z3Exception { - return new Goal(ctx, Native.goalTranslate(Context().nCtx(), - NativeObject(), ctx.nCtx())); + return new Goal(ctx, Native.goalTranslate(getContext().nCtx(), + getNativeObject(), ctx.nCtx())); } /** * Simplifies the goal. Essentially invokes the `simplify' tactic * on the goal. **/ - public Goal Simplify(Params p) throws Z3Exception + public Goal simplify() throws Z3Exception { - Tactic t = Context().MkTactic("simplify"); - ApplyResult res = t.Apply(this, p); + Tactic t = getContext().mkTactic("simplify"); + ApplyResult res = t.apply(this); - if (res.NumSubgoals() == 0) + if (res.getNumSubgoals() == 0) throw new Z3Exception("No subgoals"); else - return res.Subgoals()[0]; + return res.getSubgoals()[0]; + } + + /** + * Simplifies the goal. Essentially invokes the `simplify' tactic + * on the goal. + **/ + public Goal simplify(Params p) throws Z3Exception + { + Tactic t = getContext().mkTactic("simplify"); + ApplyResult res = t.apply(this, p); + + if (res.getNumSubgoals() == 0) + throw new Z3Exception("No subgoals"); + else + return res.getSubgoals()[0]; } /** @@ -197,7 +201,7 @@ public class Goal extends Z3Object { try { - return Native.goalToString(Context().nCtx(), NativeObject()); + return Native.goalToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -216,16 +220,16 @@ public class Goal extends Z3Object (unsatCores) ? true : false, (proofs) ? true : false)); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Goal_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().goal_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Goal_DRQ().Add(o); - super.DecRef(o); + getContext().goal_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/GoalDecRefQueue.java b/src/api/java/GoalDecRefQueue.java index 7dd52285f..0c7b8f5d9 100644 --- a/src/api/java/GoalDecRefQueue.java +++ b/src/api/java/GoalDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class GoalDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class GoalDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/IDecRefQueue.java b/src/api/java/IDecRefQueue.java index e4eec7f4f..ddb679910 100644 --- a/src/api/java/IDecRefQueue.java +++ b/src/api/java/IDecRefQueue.java @@ -6,26 +6,26 @@ package com.microsoft.z3; -import java.util.*; +import java.util.LinkedList; abstract class IDecRefQueue { protected Object m_lock = new Object(); protected LinkedList m_queue = new LinkedList(); - final int m_move_limit = 1024; + protected final int m_move_limit = 1024; - public abstract void IncRef(Context ctx, long obj); + protected abstract void incRef(Context ctx, long obj); - public abstract void DecRef(Context ctx, long obj); + protected abstract void decRef(Context ctx, long obj); - public void IncAndClear(Context ctx, long o) + protected void incAndClear(Context ctx, long o) { - IncRef(ctx, o); + incRef(ctx, o); if (m_queue.size() >= m_move_limit) - Clear(ctx); + clear(ctx); } - public void Add(long o) + protected void add(long o) { if (o == 0) return; @@ -36,12 +36,12 @@ abstract class IDecRefQueue } } - public void Clear(Context ctx) + protected void clear(Context ctx) { synchronized (m_lock) { for (Long o : m_queue) - DecRef(ctx, o); + decRef(ctx, o); m_queue.clear(); } } diff --git a/src/api/java/IDisposable.java b/src/api/java/IDisposable.java index 02bbb0ad5..9092213e3 100644 --- a/src/api/java/IDisposable.java +++ b/src/api/java/IDisposable.java @@ -21,7 +21,7 @@ package com.microsoft.z3; public class IDisposable { - public void Dispose() throws Z3Exception + public void dispose() throws Z3Exception { } } diff --git a/src/api/java/IntNum.java b/src/api/java/IntNum.java index 1397616c6..ebf237a2e 100644 --- a/src/api/java/IntNum.java +++ b/src/api/java/IntNum.java @@ -22,10 +22,10 @@ public class IntNum extends IntExpr /** * Retrieve the int value. **/ - public int Int() throws Z3Exception + public int getInt() throws Z3Exception { Native.IntPtr res = new Native.IntPtr(); - if (Native.getNumeralInt(Context().nCtx(), NativeObject(), res) ^ true) + if (Native.getNumeralInt(getContext().nCtx(), getNativeObject(), res) ^ true) throw new Z3Exception("Numeral is not an int"); return res.value; } @@ -33,10 +33,10 @@ public class IntNum extends IntExpr /** * Retrieve the 64-bit int value. **/ - public long Int64() throws Z3Exception + public long getInt64() throws Z3Exception { Native.LongPtr res = new Native.LongPtr(); - if (Native.getNumeralInt64(Context().nCtx(), NativeObject(), res) ^ true) + if (Native.getNumeralInt64(getContext().nCtx(), getNativeObject(), res) ^ true) throw new Z3Exception("Numeral is not an int64"); return res.value; } @@ -44,7 +44,7 @@ public class IntNum extends IntExpr /** * Retrieve the BigInteger value. **/ - public BigInteger BigInteger() throws Z3Exception + public BigInteger getBigInteger() throws Z3Exception { return new BigInteger(this.toString()); } @@ -56,7 +56,7 @@ public class IntNum extends IntExpr { try { - return Native.getNumeralString(Context().nCtx(), NativeObject()); + return Native.getNumeralString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); diff --git a/src/api/java/IntSymbol.java b/src/api/java/IntSymbol.java index 3dbdfaf73..113b507c3 100644 --- a/src/api/java/IntSymbol.java +++ b/src/api/java/IntSymbol.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_symbol_kind; /** * Numbered symbols @@ -17,11 +17,11 @@ public class IntSymbol extends Symbol * The int value of the symbol. Throws an exception if the symbol * is not of int kind. **/ - public int Int() throws Z3Exception + public int getInt() throws Z3Exception { - if (!IsIntSymbol()) + if (!isIntSymbol()) throw new Z3Exception("Int requested from non-Int symbol"); - return Native.getSymbolInt(Context().nCtx(), NativeObject()); + return Native.getSymbolInt(getContext().nCtx(), getNativeObject()); } IntSymbol(Context ctx, long obj) throws Z3Exception @@ -34,11 +34,11 @@ public class IntSymbol extends Symbol super(ctx, Native.mkIntSymbol(ctx.nCtx(), i)); } - void CheckNativeObject(long obj) throws Z3Exception + void checkNativeObject(long obj) throws Z3Exception { - if (Native.getSymbolKind(Context().nCtx(), obj) != Z3_symbol_kind.Z3_INT_SYMBOL + if (Native.getSymbolKind(getContext().nCtx(), obj) != Z3_symbol_kind.Z3_INT_SYMBOL .toInt()) throw new Z3Exception("Symbol is not of integer kind"); - super.CheckNativeObject(obj); + super.checkNativeObject(obj); } } diff --git a/src/api/java/ListSort.java b/src/api/java/ListSort.java index 98292b6ae..df1c51a95 100644 --- a/src/api/java/ListSort.java +++ b/src/api/java/ListSort.java @@ -14,36 +14,32 @@ public class ListSort extends Sort /** * The declaration of the nil function of this list sort. **/ - public FuncDecl NilDecl() + public FuncDecl getNilDecl() { - return nilDecl; } /** * The empty list. **/ - public Expr Nil() + public Expr getNil() { - return nilConst; } /** * The declaration of the isNil function of this list sort. **/ - public FuncDecl IsNilDecl() + public FuncDecl getIsNilDecl() { - return isNilDecl; } /** * The declaration of the cons function of this list sort. **/ - public FuncDecl ConsDecl() + public FuncDecl getConsDecl() { - return consDecl; } @@ -51,27 +47,24 @@ public class ListSort extends Sort * The declaration of the isCons function of this list sort. * **/ - public FuncDecl IsConsDecl() + public FuncDecl getIsConsDecl() { - return isConsDecl; } /** * The declaration of the head function of this list sort. **/ - public FuncDecl HeadDecl() + public FuncDecl getHeadDecl() { - return headDecl; } /** * The declaration of the tail function of this list sort. **/ - public FuncDecl TailDecl() + public FuncDecl getTailDecl() { - return tailDecl; } @@ -87,8 +80,8 @@ public class ListSort extends Sort Native.LongPtr icons = new Native.LongPtr(), iiscons = new Native.LongPtr(); Native.LongPtr ihead = new Native.LongPtr(), itail = new Native.LongPtr(); - setNativeObject(Native.mkListSort(ctx.nCtx(), name.NativeObject(), - elemSort.NativeObject(), inil, iisnil, icons, iiscons, ihead, + setNativeObject(Native.mkListSort(ctx.nCtx(), name.getNativeObject(), + elemSort.getNativeObject(), inil, iisnil, icons, iiscons, ihead, itail)); nilDecl = new FuncDecl(ctx, inil.value); isNilDecl = new FuncDecl(ctx, iisnil.value); @@ -96,6 +89,6 @@ public class ListSort extends Sort isConsDecl = new FuncDecl(ctx, iiscons.value); headDecl = new FuncDecl(ctx, ihead.value); tailDecl = new FuncDecl(ctx, itail.value); - nilConst = ctx.MkConst(nilDecl); + nilConst = ctx.mkConst(nilDecl); } }; diff --git a/src/api/java/Log.java b/src/api/java/Log.java index cd62f82ac..99581cedb 100644 --- a/src/api/java/Log.java +++ b/src/api/java/Log.java @@ -21,7 +21,7 @@ public final class Log * * @return True if opening the log file succeeds, false otherwise. **/ - public static boolean Open(String filename) + public static boolean open(String filename) { m_is_open = true; return Native.openLog(filename) == 1; @@ -30,7 +30,7 @@ public final class Log /** * Closes the interaction log. **/ - public static void Close() + public static void close() { m_is_open = false; Native.closeLog(); @@ -41,7 +41,7 @@ public final class Log * log. * @throws Z3Exception **/ - public static void Append(String s) throws Z3Exception + public static void append(String s) throws Z3Exception { if (!m_is_open) throw new Z3Exception("Log cannot be closed."); diff --git a/src/api/java/Model.java b/src/api/java/Model.java index e38c260c4..32247eb4a 100644 --- a/src/api/java/Model.java +++ b/src/api/java/Model.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_sort_kind; /** * A Model contains interpretations (assignments) of constants and functions. @@ -21,10 +21,10 @@ public class Model extends Z3Object * null otherwise. * @throws Z3Exception **/ - public Expr ConstInterp(Expr a) throws Z3Exception + public Expr getConstInterp(Expr a) throws Z3Exception { - Context().CheckContextMatch(a); - return ConstInterp(a.FuncDecl()); + getContext().checkContextMatch(a); + return getConstInterp(a.getFuncDecl()); } /** @@ -35,22 +35,22 @@ public class Model extends Z3Object * null otherwise. * @throws Z3Exception **/ - public Expr ConstInterp(FuncDecl f) throws Z3Exception + public Expr getConstInterp(FuncDecl f) throws Z3Exception { - Context().CheckContextMatch(f); - if (f.Arity() != 0 - || Native.getSortKind(Context().nCtx(), - Native.getRange(Context().nCtx(), f.NativeObject())) == Z3_sort_kind.Z3_ARRAY_SORT + getContext().checkContextMatch(f); + if (f.getArity() != 0 + || Native.getSortKind(getContext().nCtx(), + Native.getRange(getContext().nCtx(), f.getNativeObject())) == Z3_sort_kind.Z3_ARRAY_SORT .toInt()) throw new Z3Exception( "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp."); - long n = Native.modelGetConstInterp(Context().nCtx(), NativeObject(), - f.NativeObject()); + long n = Native.modelGetConstInterp(getContext().nCtx(), getNativeObject(), + f.getNativeObject()); if (n == 0) return null; else - return Expr.Create(Context(), n); + return Expr.create(getContext(), n); } /** @@ -62,17 +62,17 @@ public class Model extends Z3Object * the model, null otherwise. * @throws Z3Exception **/ - public FuncInterp FuncInterp(FuncDecl f) throws Z3Exception + public FuncInterp getFuncInterp(FuncDecl f) throws Z3Exception { - Context().CheckContextMatch(f); + getContext().checkContextMatch(f); - Z3_sort_kind sk = Z3_sort_kind.fromInt(Native.getSortKind(Context() - .nCtx(), Native.getRange(Context().nCtx(), f.NativeObject()))); + Z3_sort_kind sk = Z3_sort_kind.fromInt(Native.getSortKind(getContext() + .nCtx(), Native.getRange(getContext().nCtx(), f.getNativeObject()))); - if (f.Arity() == 0) + if (f.getArity() == 0) { - long n = Native.modelGetConstInterp(Context().nCtx(), - NativeObject(), f.NativeObject()); + long n = Native.modelGetConstInterp(getContext().nCtx(), + getNativeObject(), f.getNativeObject()); if (sk == Z3_sort_kind.Z3_ARRAY_SORT) { @@ -80,11 +80,11 @@ public class Model extends Z3Object return null; else { - if (Native.isAsArray(Context().nCtx(), n) ^ true) + if (Native.isAsArray(getContext().nCtx(), n) ^ true) throw new Z3Exception( "Argument was not an array constant"); - long fd = Native.getAsArrayFuncDecl(Context().nCtx(), n); - return FuncInterp(new FuncDecl(Context(), fd)); + long fd = Native.getAsArrayFuncDecl(getContext().nCtx(), n); + return getFuncInterp(new FuncDecl(getContext(), fd)); } } else { @@ -93,21 +93,21 @@ public class Model extends Z3Object } } else { - long n = Native.modelGetFuncInterp(Context().nCtx(), - NativeObject(), f.NativeObject()); + long n = Native.modelGetFuncInterp(getContext().nCtx(), + getNativeObject(), f.getNativeObject()); if (n == 0) return null; else - return new FuncInterp(Context(), n); + return new FuncInterp(getContext(), n); } } /** * The number of constants that have an interpretation in the model. **/ - public int NumConsts() throws Z3Exception + public int getNumConsts() throws Z3Exception { - return Native.modelGetNumConsts(Context().nCtx(), NativeObject()); + return Native.modelGetNumConsts(getContext().nCtx(), getNativeObject()); } /** @@ -115,22 +115,22 @@ public class Model extends Z3Object * * @throws Z3Exception **/ - public FuncDecl[] ConstDecls() throws Z3Exception + public FuncDecl[] getConstDecls() throws Z3Exception { - int n = NumConsts(); + int n = getNumConsts(); FuncDecl[] res = new FuncDecl[n]; for (int i = 0; i < n; i++) - res[i] = new FuncDecl(Context(), Native.modelGetConstDecl(Context() - .nCtx(), NativeObject(), i)); + res[i] = new FuncDecl(getContext(), Native.modelGetConstDecl(getContext() + .nCtx(), getNativeObject(), i)); return res; } /** * The number of function interpretations in the model. **/ - public int NumFuncs() throws Z3Exception + public int getNumFuncs() throws Z3Exception { - return Native.modelGetNumFuncs(Context().nCtx(), NativeObject()); + return Native.modelGetNumFuncs(getContext().nCtx(), getNativeObject()); } /** @@ -138,13 +138,13 @@ public class Model extends Z3Object * * @throws Z3Exception **/ - public FuncDecl[] FuncDecls() throws Z3Exception + public FuncDecl[] getFuncDecls() throws Z3Exception { - int n = NumFuncs(); + int n = getNumFuncs(); FuncDecl[] res = new FuncDecl[n]; for (int i = 0; i < n; i++) - res[i] = new FuncDecl(Context(), Native.modelGetFuncDecl(Context() - .nCtx(), NativeObject(), i)); + res[i] = new FuncDecl(getContext(), Native.modelGetFuncDecl(getContext() + .nCtx(), getNativeObject(), i)); return res; } @@ -153,18 +153,18 @@ public class Model extends Z3Object * * @throws Z3Exception **/ - public FuncDecl[] Decls() throws Z3Exception + public FuncDecl[] getDecls() throws Z3Exception { - int nFuncs = NumFuncs(); - int nConsts = NumConsts(); + int nFuncs = getNumFuncs(); + int nConsts = getNumConsts(); int n = nFuncs + nConsts; FuncDecl[] res = new FuncDecl[n]; for (int i = 0; i < nConsts; i++) - res[i] = new FuncDecl(Context(), Native.modelGetConstDecl(Context() - .nCtx(), NativeObject(), i)); + res[i] = new FuncDecl(getContext(), Native.modelGetConstDecl(getContext() + .nCtx(), getNativeObject(), i)); for (int i = 0; i < nFuncs; i++) - res[nConsts + i] = new FuncDecl(Context(), Native.modelGetFuncDecl( - Context().nCtx(), NativeObject(), i)); + res[nConsts + i] = new FuncDecl(getContext(), Native.modelGetFuncDecl( + getContext().nCtx(), getNativeObject(), i)); return res; } @@ -197,14 +197,14 @@ public class Model extends Z3Object * @return The evaluation of in the model. * @throws Z3Exception **/ - public Expr Eval(Expr t, boolean completion) throws Z3Exception + public Expr eval(Expr t, boolean completion) throws Z3Exception { Native.LongPtr v = new Native.LongPtr(); - if (Native.modelEval(Context().nCtx(), NativeObject(), - t.NativeObject(), (completion) ? true : false, v) ^ true) + if (Native.modelEval(getContext().nCtx(), getNativeObject(), + t.getNativeObject(), (completion) ? true : false, v) ^ true) throw new ModelEvaluationFailedException(); else - return Expr.Create(Context(), v.value); + return Expr.create(getContext(), v.value); } /** @@ -212,18 +212,18 @@ public class Model extends Z3Object * * @throws Z3Exception **/ - public Expr Evaluate(Expr t, boolean completion) throws Z3Exception + public Expr evaluate(Expr t, boolean completion) throws Z3Exception { - return Eval(t, completion); + return eval(t, completion); } /** * The number of uninterpreted sorts that the model has an interpretation * for. **/ - public int NumSorts() throws Z3Exception + public int getNumSorts() throws Z3Exception { - return Native.modelGetNumSorts(Context().nCtx(), NativeObject()); + return Native.modelGetNumSorts(getContext().nCtx(), getNativeObject()); } /** @@ -235,14 +235,14 @@ public class Model extends Z3Object * * @throws Z3Exception **/ - public Sort[] Sorts() throws Z3Exception + public Sort[] getSorts() throws Z3Exception { - int n = NumSorts(); + int n = getNumSorts(); Sort[] res = new Sort[n]; for (int i = 0; i < n; i++) - res[i] = Sort.Create(Context(), - Native.modelGetSort(Context().nCtx(), NativeObject(), i)); + res[i] = Sort.create(getContext(), + Native.modelGetSort(getContext().nCtx(), getNativeObject(), i)); return res; } @@ -255,15 +255,15 @@ public class Model extends Z3Object * of * @throws Z3Exception **/ - public Expr[] SortUniverse(Sort s) throws Z3Exception + public Expr[] getSortUniverse(Sort s) throws Z3Exception { - ASTVector nUniv = new ASTVector(Context(), Native.modelGetSortUniverse( - Context().nCtx(), NativeObject(), s.NativeObject())); - int n = nUniv.Size(); + ASTVector nUniv = new ASTVector(getContext(), Native.modelGetSortUniverse( + getContext().nCtx(), getNativeObject(), s.getNativeObject())); + int n = nUniv.size(); Expr[] res = new Expr[n]; for (int i = 0; i < n; i++) - res[i] = Expr.Create(Context(), nUniv.get(i).NativeObject()); + res[i] = Expr.create(getContext(), nUniv.get(i).getNativeObject()); return res; } @@ -276,7 +276,7 @@ public class Model extends Z3Object { try { - return Native.modelToString(Context().nCtx(), NativeObject()); + return Native.modelToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -288,15 +288,15 @@ public class Model extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Model_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().model_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Model_DRQ().Add(o); - super.DecRef(o); + getContext().model_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/ModelDecRefQueue.java b/src/api/java/ModelDecRefQueue.java index 71fb939cf..a0542714e 100644 --- a/src/api/java/ModelDecRefQueue.java +++ b/src/api/java/ModelDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class ModelDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class ModelDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/ParamDescrs.java b/src/api/java/ParamDescrs.java index 09b70f5c7..3b3e76e51 100644 --- a/src/api/java/ParamDescrs.java +++ b/src/api/java/ParamDescrs.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_param_kind; /** * A ParamDescrs describes a set of parameters. @@ -16,21 +16,21 @@ public class ParamDescrs extends Z3Object /** * validate a set of parameters. **/ - public void Validate(Params p) throws Z3Exception + public void validate(Params p) throws Z3Exception { - Native.paramsValidate(Context().nCtx(), p.NativeObject(), - NativeObject()); + Native.paramsValidate(getContext().nCtx(), p.getNativeObject(), + getNativeObject()); } /** * Retrieve kind of parameter. **/ - public Z3_param_kind GetKind(Symbol name) throws Z3Exception + public Z3_param_kind getKind(Symbol name) throws Z3Exception { return Z3_param_kind.fromInt(Native.paramDescrsGetKind( - Context().nCtx(), NativeObject(), name.NativeObject())); + getContext().nCtx(), getNativeObject(), name.getNativeObject())); } /** @@ -38,14 +38,14 @@ public class ParamDescrs extends Z3Object * * @throws Z3Exception **/ - public Symbol[] Names() throws Z3Exception + public Symbol[] getNames() throws Z3Exception { - int sz = Native.paramDescrsSize(Context().nCtx(), NativeObject()); + int sz = Native.paramDescrsSize(getContext().nCtx(), getNativeObject()); Symbol[] names = new Symbol[sz]; for (int i = 0; i < sz; ++i) { - names[i] = Symbol.Create(Context(), Native.paramDescrsGetName( - Context().nCtx(), NativeObject(), i)); + names[i] = Symbol.create(getContext(), Native.paramDescrsGetName( + getContext().nCtx(), getNativeObject(), i)); } return names; } @@ -53,9 +53,9 @@ public class ParamDescrs extends Z3Object /** * The size of the ParamDescrs. **/ - public int Size() throws Z3Exception + public int size() throws Z3Exception { - return Native.paramDescrsSize(Context().nCtx(), NativeObject()); + return Native.paramDescrsSize(getContext().nCtx(), getNativeObject()); } /** @@ -65,7 +65,7 @@ public class ParamDescrs extends Z3Object { try { - return Native.paramDescrsToString(Context().nCtx(), NativeObject()); + return Native.paramDescrsToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -77,15 +77,15 @@ public class ParamDescrs extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().ParamDescrs_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().paramDescrs_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().ParamDescrs_DRQ().Add(o); - super.DecRef(o); + getContext().paramDescrs_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/ParamDescrsDecRefQueue.java b/src/api/java/ParamDescrsDecRefQueue.java index 75e2a2c7e..70806041d 100644 --- a/src/api/java/ParamDescrsDecRefQueue.java +++ b/src/api/java/ParamDescrsDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class ParamDescrsDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class ParamDescrsDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/Params.java b/src/api/java/Params.java index c954c50e5..68af4386b 100644 --- a/src/api/java/Params.java +++ b/src/api/java/Params.java @@ -14,65 +14,65 @@ public class Params extends Z3Object /** * Adds a parameter setting. **/ - public void Add(Symbol name, boolean value) throws Z3Exception + public void add(Symbol name, boolean value) throws Z3Exception { - Native.paramsSetBool(Context().nCtx(), NativeObject(), - name.NativeObject(), (value) ? true : false); + Native.paramsSetBool(getContext().nCtx(), getNativeObject(), + name.getNativeObject(), (value) ? true : false); } /** * Adds a parameter setting. **/ - public void Add(Symbol name, double value) throws Z3Exception + public void add(Symbol name, double value) throws Z3Exception { - Native.paramsSetDouble(Context().nCtx(), NativeObject(), - name.NativeObject(), value); + Native.paramsSetDouble(getContext().nCtx(), getNativeObject(), + name.getNativeObject(), value); } /** * Adds a parameter setting. **/ - public void Add(Symbol name, Symbol value) throws Z3Exception + public void add(Symbol name, Symbol value) throws Z3Exception { - Native.paramsSetSymbol(Context().nCtx(), NativeObject(), - name.NativeObject(), value.NativeObject()); + Native.paramsSetSymbol(getContext().nCtx(), getNativeObject(), + name.getNativeObject(), value.getNativeObject()); } /** * Adds a parameter setting. **/ - public void Add(String name, boolean value) throws Z3Exception + public void add(String name, boolean value) throws Z3Exception { - Native.paramsSetBool(Context().nCtx(), NativeObject(), - Context().MkSymbol(name).NativeObject(), value); + Native.paramsSetBool(getContext().nCtx(), getNativeObject(), + getContext().mkSymbol(name).getNativeObject(), value); } /** * Adds a parameter setting. **/ - public void Add(String name, int value) throws Z3Exception + public void add(String name, int value) throws Z3Exception { - Native.paramsSetUint(Context().nCtx(), NativeObject(), Context() - .MkSymbol(name).NativeObject(), value); + Native.paramsSetUint(getContext().nCtx(), getNativeObject(), getContext() + .mkSymbol(name).getNativeObject(), value); } /** * Adds a parameter setting. **/ - public void Add(String name, double value) throws Z3Exception + public void add(String name, double value) throws Z3Exception { - Native.paramsSetDouble(Context().nCtx(), NativeObject(), Context() - .MkSymbol(name).NativeObject(), value); + Native.paramsSetDouble(getContext().nCtx(), getNativeObject(), getContext() + .mkSymbol(name).getNativeObject(), value); } /** * Adds a parameter setting. **/ - public void Add(String name, Symbol value) throws Z3Exception + public void add(String name, Symbol value) throws Z3Exception { - Native.paramsSetSymbol(Context().nCtx(), NativeObject(), Context() - .MkSymbol(name).NativeObject(), value.NativeObject()); + Native.paramsSetSymbol(getContext().nCtx(), getNativeObject(), getContext() + .mkSymbol(name).getNativeObject(), value.getNativeObject()); } /** @@ -82,7 +82,7 @@ public class Params extends Z3Object { try { - return Native.paramsToString(Context().nCtx(), NativeObject()); + return Native.paramsToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -94,15 +94,15 @@ public class Params extends Z3Object super(ctx, Native.mkParams(ctx.nCtx())); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Params_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().params_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Params_DRQ().Add(o); - super.DecRef(o); + getContext().params_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/ParamsDecRefQueue.java b/src/api/java/ParamsDecRefQueue.java index 7c3ccbee8..361fdf133 100644 --- a/src/api/java/ParamsDecRefQueue.java +++ b/src/api/java/ParamsDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class ParamsDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class ParamsDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/Pattern.java b/src/api/java/Pattern.java index ed36ad0e7..cd9340c9d 100644 --- a/src/api/java/Pattern.java +++ b/src/api/java/Pattern.java @@ -15,9 +15,9 @@ public class Pattern extends AST /** * The number of terms in the pattern. **/ - public int NumTerms() throws Z3Exception + public int getNumTerms() throws Z3Exception { - return Native.getPatternNumTerms(Context().nCtx(), NativeObject()); + return Native.getPatternNumTerms(getContext().nCtx(), getNativeObject()); } /** @@ -25,14 +25,14 @@ public class Pattern extends AST * * @throws Z3Exception **/ - public Expr[] Terms() throws Z3Exception + public Expr[] getTerms() throws Z3Exception { - int n = NumTerms(); + int n = getNumTerms(); Expr[] res = new Expr[n]; for (int i = 0; i < n; i++) - res[i] = Expr.Create(Context(), - Native.getPattern(Context().nCtx(), NativeObject(), i)); + res[i] = Expr.create(getContext(), + Native.getPattern(getContext().nCtx(), getNativeObject(), i)); return res; } @@ -43,7 +43,7 @@ public class Pattern extends AST { try { - return Native.patternToString(Context().nCtx(), NativeObject()); + return Native.patternToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); diff --git a/src/api/java/Probe.java b/src/api/java/Probe.java index 80ac55b70..b68b0266f 100644 --- a/src/api/java/Probe.java +++ b/src/api/java/Probe.java @@ -23,20 +23,11 @@ public class Probe extends Z3Object * 0.0 for false, and a value different from 0.0 for true. * @throws Z3Exception **/ - public double Apply(Goal g) throws Z3Exception + public double apply(Goal g) throws Z3Exception { - Context().CheckContextMatch(g); - return Native.probeApply(Context().nCtx(), NativeObject(), - g.NativeObject()); - } - - /** - * Apply the probe to a goal. - * @throws Z3Exception - **/ - public double get(Goal g) throws Z3Exception - { - return Apply(g); + getContext().checkContextMatch(g); + return Native.probeApply(getContext().nCtx(), getNativeObject(), + g.getNativeObject()); } Probe(Context ctx, long obj) throws Z3Exception @@ -49,15 +40,15 @@ public class Probe extends Z3Object super(ctx, Native.mkProbe(ctx.nCtx(), name)); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Probe_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().probe_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Probe_DRQ().Add(o); - super.DecRef(o); + getContext().probe_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/ProbeDecRefQueue.java b/src/api/java/ProbeDecRefQueue.java index b368702df..0ae0b0e8e 100644 --- a/src/api/java/ProbeDecRefQueue.java +++ b/src/api/java/ProbeDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class ProbeDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class ProbeDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/Quantifier.java b/src/api/java/Quantifier.java index 6ee7e4412..78a0fc03f 100644 --- a/src/api/java/Quantifier.java +++ b/src/api/java/Quantifier.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_ast_kind; /** * Quantifier expressions. @@ -16,34 +16,34 @@ public class Quantifier extends BoolExpr /** * Indicates whether the quantifier is universal. **/ - public boolean IsUniversal() throws Z3Exception + public boolean isUniversal() throws Z3Exception { - return Native.isQuantifierForall(Context().nCtx(), NativeObject()); + return Native.isQuantifierForall(getContext().nCtx(), getNativeObject()); } /** * Indicates whether the quantifier is existential. **/ - public boolean IsExistential() throws Z3Exception + public boolean isExistential() throws Z3Exception { - return !IsUniversal(); + return !isUniversal(); } /** * The weight of the quantifier. **/ - public int Weight() throws Z3Exception + public int getWeight() throws Z3Exception { - return Native.getQuantifierWeight(Context().nCtx(), NativeObject()); + return Native.getQuantifierWeight(getContext().nCtx(), getNativeObject()); } /** * The number of patterns. **/ - public int NumPatterns() throws Z3Exception + public int getNumPatterns() throws Z3Exception { return Native - .getQuantifierNumPatterns(Context().nCtx(), NativeObject()); + .getQuantifierNumPatterns(getContext().nCtx(), getNativeObject()); } /** @@ -51,23 +51,23 @@ public class Quantifier extends BoolExpr * * @throws Z3Exception **/ - public Pattern[] Patterns() throws Z3Exception + public Pattern[] getPatterns() throws Z3Exception { - int n = NumPatterns(); + int n = getNumPatterns(); Pattern[] res = new Pattern[n]; for (int i = 0; i < n; i++) - res[i] = new Pattern(Context(), Native.getQuantifierPatternAst( - Context().nCtx(), NativeObject(), i)); + res[i] = new Pattern(getContext(), Native.getQuantifierPatternAst( + getContext().nCtx(), getNativeObject(), i)); return res; } /** * The number of no-patterns. **/ - public int NumNoPatterns() throws Z3Exception + public int getNumNoPatterns() throws Z3Exception { - return Native.getQuantifierNumNoPatterns(Context().nCtx(), - NativeObject()); + return Native.getQuantifierNumNoPatterns(getContext().nCtx(), + getNativeObject()); } /** @@ -75,22 +75,22 @@ public class Quantifier extends BoolExpr * * @throws Z3Exception **/ - public Pattern[] NoPatterns() throws Z3Exception + public Pattern[] getNoPatterns() throws Z3Exception { - int n = NumNoPatterns(); + int n = getNumNoPatterns(); Pattern[] res = new Pattern[n]; for (int i = 0; i < n; i++) - res[i] = new Pattern(Context(), Native.getQuantifierNoPatternAst( - Context().nCtx(), NativeObject(), i)); + res[i] = new Pattern(getContext(), Native.getQuantifierNoPatternAst( + getContext().nCtx(), getNativeObject(), i)); return res; } /** * The number of bound variables. **/ - public int NumBound() throws Z3Exception + public int getNumBound() throws Z3Exception { - return Native.getQuantifierNumBound(Context().nCtx(), NativeObject()); + return Native.getQuantifierNumBound(getContext().nCtx(), getNativeObject()); } /** @@ -98,13 +98,13 @@ public class Quantifier extends BoolExpr * * @throws Z3Exception **/ - public Symbol[] BoundVariableNames() throws Z3Exception + public Symbol[] getBoundVariableNames() throws Z3Exception { - int n = NumBound(); + int n = getNumBound(); Symbol[] res = new Symbol[n]; for (int i = 0; i < n; i++) - res[i] = Symbol.Create(Context(), Native.getQuantifierBoundName( - Context().nCtx(), NativeObject(), i)); + res[i] = Symbol.create(getContext(), Native.getQuantifierBoundName( + getContext().nCtx(), getNativeObject(), i)); return res; } @@ -113,13 +113,13 @@ public class Quantifier extends BoolExpr * * @throws Z3Exception **/ - public Sort[] BoundVariableSorts() throws Z3Exception + public Sort[] getBoundVariableSorts() throws Z3Exception { - int n = NumBound(); + int n = getNumBound(); Sort[] res = new Sort[n]; for (int i = 0; i < n; i++) - res[i] = Sort.Create(Context(), Native.getQuantifierBoundSort( - Context().nCtx(), NativeObject(), i)); + res[i] = Sort.create(getContext(), Native.getQuantifierBoundSort( + getContext().nCtx(), getNativeObject(), i)); return res; } @@ -128,10 +128,10 @@ public class Quantifier extends BoolExpr * * @throws Z3Exception **/ - public BoolExpr Body() throws Z3Exception + public BoolExpr getBody() throws Z3Exception { - return new BoolExpr(Context(), Native.getQuantifierBody(Context() - .nCtx(), NativeObject())); + return new BoolExpr(getContext(), Native.getQuantifierBody(getContext() + .nCtx(), getNativeObject())); } Quantifier(Context ctx, boolean isForall, Sort[] sorts, Symbol[] names, @@ -140,11 +140,11 @@ public class Quantifier extends BoolExpr { super(ctx); - Context().CheckContextMatch(patterns); - Context().CheckContextMatch(noPatterns); - Context().CheckContextMatch(sorts); - Context().CheckContextMatch(names); - Context().CheckContextMatch(body); + getContext().checkContextMatch(patterns); + getContext().checkContextMatch(noPatterns); + getContext().checkContextMatch(sorts); + getContext().checkContextMatch(names); + getContext().checkContextMatch(body); if (sorts.length != names.length) throw new Z3Exception( @@ -153,20 +153,20 @@ public class Quantifier extends BoolExpr if (noPatterns == null && quantifierID == null && skolemID == null) { setNativeObject(Native.mkQuantifier(ctx.nCtx(), (isForall) ? true - : false, weight, AST.ArrayLength(patterns), AST - .ArrayToNative(patterns), AST.ArrayLength(sorts), AST - .ArrayToNative(sorts), Symbol.ArrayToNative(names), body - .NativeObject())); + : false, weight, AST.arrayLength(patterns), AST + .arrayToNative(patterns), AST.arrayLength(sorts), AST + .arrayToNative(sorts), Symbol.arrayToNative(names), body + .getNativeObject())); } else { setNativeObject(Native.mkQuantifierEx(ctx.nCtx(), - (isForall) ? true : false, weight, AST.GetNativeObject(quantifierID), - AST.GetNativeObject(skolemID), - AST.ArrayLength(patterns), AST.ArrayToNative(patterns), - AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), - AST.ArrayLength(sorts), AST.ArrayToNative(sorts), - Symbol.ArrayToNative(names), - body.NativeObject())); + (isForall) ? true : false, weight, AST.getNativeObject(quantifierID), + AST.getNativeObject(skolemID), + AST.arrayLength(patterns), AST.arrayToNative(patterns), + AST.arrayLength(noPatterns), AST.arrayToNative(noPatterns), + AST.arrayLength(sorts), AST.arrayToNative(sorts), + Symbol.arrayToNative(names), + body.getNativeObject())); } } @@ -176,26 +176,26 @@ public class Quantifier extends BoolExpr { super(ctx); - Context().CheckContextMatch(noPatterns); - Context().CheckContextMatch(patterns); + getContext().checkContextMatch(noPatterns); + getContext().checkContextMatch(patterns); // Context().CheckContextMatch(bound); - Context().CheckContextMatch(body); + getContext().checkContextMatch(body); if (noPatterns == null && quantifierID == null && skolemID == null) { setNativeObject(Native.mkQuantifierConst(ctx.nCtx(), - (isForall) ? true : false, weight, AST.ArrayLength(bound), - AST.ArrayToNative(bound), AST.ArrayLength(patterns), - AST.ArrayToNative(patterns), body.NativeObject())); + (isForall) ? true : false, weight, AST.arrayLength(bound), + AST.arrayToNative(bound), AST.arrayLength(patterns), + AST.arrayToNative(patterns), body.getNativeObject())); } else { setNativeObject(Native.mkQuantifierConstEx(ctx.nCtx(), (isForall) ? true : false, weight, - AST.GetNativeObject(quantifierID), - AST.GetNativeObject(skolemID), AST.ArrayLength(bound), - AST.ArrayToNative(bound), AST.ArrayLength(patterns), - AST.ArrayToNative(patterns), AST.ArrayLength(noPatterns), - AST.ArrayToNative(noPatterns), body.NativeObject())); + AST.getNativeObject(quantifierID), + AST.getNativeObject(skolemID), AST.arrayLength(bound), + AST.arrayToNative(bound), AST.arrayLength(patterns), + AST.arrayToNative(patterns), AST.arrayLength(noPatterns), + AST.arrayToNative(noPatterns), body.getNativeObject())); } } @@ -204,11 +204,11 @@ public class Quantifier extends BoolExpr super(ctx, obj); } - void CheckNativeObject(long obj) throws Z3Exception + void checkNativeObject(long obj) throws Z3Exception { - if (Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_QUANTIFIER_AST + if (Native.getAstKind(getContext().nCtx(), obj) != Z3_ast_kind.Z3_QUANTIFIER_AST .toInt()) throw new Z3Exception("Underlying object is not a quantifier"); - super.CheckNativeObject(obj); + super.checkNativeObject(obj); } } diff --git a/src/api/java/RatNum.java b/src/api/java/RatNum.java index bdc57fbdb..e1cb5b346 100644 --- a/src/api/java/RatNum.java +++ b/src/api/java/RatNum.java @@ -16,36 +16,36 @@ public class RatNum extends RealExpr /** * The numerator of a rational numeral. **/ - public IntNum Numerator() throws Z3Exception + public IntNum getNumerator() throws Z3Exception { - return new IntNum(Context(), Native.getNumerator(Context().nCtx(), - NativeObject())); + return new IntNum(getContext(), Native.getNumerator(getContext().nCtx(), + getNativeObject())); } /** * The denominator of a rational numeral. **/ - public IntNum Denominator() throws Z3Exception + public IntNum getDenominator() throws Z3Exception { - return new IntNum(Context(), Native.getDenominator(Context().nCtx(), - NativeObject())); + return new IntNum(getContext(), Native.getDenominator(getContext().nCtx(), + getNativeObject())); } /** * Converts the numerator of the rational to a BigInteger **/ - public BigInteger BigIntNumerator() throws Z3Exception + public BigInteger getBigIntNumerator() throws Z3Exception { - IntNum n = Numerator(); + IntNum n = getNumerator(); return new BigInteger(n.toString()); } /** * Converts the denominator of the rational to a BigInteger **/ - public BigInteger BigIntDenominator() throws Z3Exception + public BigInteger getBigIntDenominator() throws Z3Exception { - IntNum n = Denominator(); + IntNum n = getDenominator(); return new BigInteger(n.toString()); } @@ -53,9 +53,9 @@ public class RatNum extends RealExpr * Returns a string representation in decimal notation. The result * has at most decimal places. **/ - public String ToDecimalString(int precision) throws Z3Exception + public String toDecimalString(int precision) throws Z3Exception { - return Native.getNumeralDecimalString(Context().nCtx(), NativeObject(), + return Native.getNumeralDecimalString(getContext().nCtx(), getNativeObject(), precision); } @@ -66,7 +66,7 @@ public class RatNum extends RealExpr { try { - return Native.getNumeralString(Context().nCtx(), NativeObject()); + return Native.getNumeralString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); diff --git a/src/api/java/RelationSort.java b/src/api/java/RelationSort.java index 820228e82..bdc4d7804 100644 --- a/src/api/java/RelationSort.java +++ b/src/api/java/RelationSort.java @@ -14,26 +14,26 @@ public class RelationSort extends Sort /** * The arity of the relation sort. **/ - public int Arity() throws Z3Exception + public int getArity() throws Z3Exception { - return Native.getRelationArity(Context().nCtx(), NativeObject()); + return Native.getRelationArity(getContext().nCtx(), getNativeObject()); } /** * The sorts of the columns of the relation sort. * @throws Z3Exception **/ - public Sort[] ColumnSorts() throws Z3Exception + public Sort[] getColumnSorts() throws Z3Exception { if (m_columnSorts != null) return m_columnSorts; - int n = Arity(); + int n = getArity(); Sort[] res = new Sort[n]; for (int i = 0; i < n; i++) - res[i] = Sort.Create(Context(), Native.getRelationColumn(Context() - .nCtx(), NativeObject(), i)); + res[i] = Sort.create(getContext(), Native.getRelationColumn(getContext() + .nCtx(), getNativeObject(), i)); return res; } diff --git a/src/api/java/SetSort.java b/src/api/java/SetSort.java index ffeebfd3d..a94a34b26 100644 --- a/src/api/java/SetSort.java +++ b/src/api/java/SetSort.java @@ -18,6 +18,6 @@ public class SetSort extends Sort SetSort(Context ctx, Sort ty) throws Z3Exception { - super(ctx, Native.mkSetSort(ctx.nCtx(), ty.NativeObject())); + super(ctx, Native.mkSetSort(ctx.nCtx(), ty.getNativeObject())); } } diff --git a/src/api/java/Solver.java b/src/api/java/Solver.java index 278427d49..c60d3f88c 100644 --- a/src/api/java/Solver.java +++ b/src/api/java/Solver.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_lbool; /** * Solvers. @@ -16,9 +16,9 @@ public class Solver extends Z3Object /** * A string that describes all available solver parameters. **/ - public String Help() throws Z3Exception + public String getHelp() throws Z3Exception { - return Native.solverGetHelp(Context().nCtx(), NativeObject()); + return Native.solverGetHelp(getContext().nCtx(), getNativeObject()); } /** @@ -28,9 +28,9 @@ public class Solver extends Z3Object **/ public void setParameters(Params value) throws Z3Exception { - Context().CheckContextMatch(value); - Native.solverSetParams(Context().nCtx(), NativeObject(), - value.NativeObject()); + getContext().checkContextMatch(value); + Native.solverSetParams(getContext().nCtx(), getNativeObject(), + value.getNativeObject()); } /** @@ -38,35 +38,36 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public ParamDescrs ParameterDescriptions() throws Z3Exception + public ParamDescrs getParameterDescriptions() throws Z3Exception { - return new ParamDescrs(Context(), Native.solverGetParamDescrs(Context() - .nCtx(), NativeObject())); + return new ParamDescrs(getContext(), Native.solverGetParamDescrs( + getContext().nCtx(), getNativeObject())); } /** * The current number of backtracking points (scopes). * **/ - public int NumScopes() throws Z3Exception + public int getNumScopes() throws Z3Exception { - return Native.solverGetNumScopes(Context().nCtx(), NativeObject()); + return Native + .solverGetNumScopes(getContext().nCtx(), getNativeObject()); } /** * Creates a backtracking point. **/ - public void Push() throws Z3Exception + public void push() throws Z3Exception { - Native.solverPush(Context().nCtx(), NativeObject()); + Native.solverPush(getContext().nCtx(), getNativeObject()); } /** * Backtracks one backtracking point. . **/ - public void Pop() throws Z3Exception + public void pop() throws Z3Exception { - Pop(1); + pop(1); } /** @@ -74,18 +75,18 @@ public class Solver extends Z3Object * an exception is thrown if is not smaller than * NumScopes **/ - public void Pop(int n) throws Z3Exception + public void pop(int n) throws Z3Exception { - Native.solverPop(Context().nCtx(), NativeObject(), n); + Native.solverPop(getContext().nCtx(), getNativeObject(), n); } /** * Resets the Solver. This removes all assertions from the * solver. **/ - public void Reset() throws Z3Exception + public void reset() throws Z3Exception { - Native.solverReset(Context().nCtx(), NativeObject()); + Native.solverReset(getContext().nCtx(), getNativeObject()); } /** @@ -93,26 +94,62 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public void Assert(BoolExpr[] constraints) throws Z3Exception + public void assert_(BoolExpr... constraints) throws Z3Exception { - Context().CheckContextMatch(constraints); + getContext().checkContextMatch(constraints); for (BoolExpr a : constraints) { - Native.solverAssert(Context().nCtx(), NativeObject(), - a.NativeObject()); + Native.solverAssert(getContext().nCtx(), getNativeObject(), + a.getNativeObject()); } } - /** - * Assert one constraint into the solver. - * - * @throws Z3Exception - **/ - public void Assert(BoolExpr constraint) throws Z3Exception + // / + // / Assert multiple constraints into the solver, and track them (in the + // unsat) core + // / using the Boolean constants in ps. + // / + // / + // / This API is an alternative to with assumptions for + // extracting unsat cores. + // / Both APIs can be used in the same solver. The unsat core will contain a + // combination + // / of the Boolean variables provided using + // and the Boolean literals + // / provided using with assumptions. + // / + public void assertAndTrack(BoolExpr[] constraints, BoolExpr[] ps) throws Z3Exception { - Context().CheckContextMatch(constraint); - Native.solverAssert(Context().nCtx(), NativeObject(), - constraint.NativeObject()); + getContext().checkContextMatch(constraints); + getContext().checkContextMatch(ps); + if (constraints.length != ps.length) + throw new Z3Exception("Argument size mismatch"); + + for (int i = 0; i < constraints.length; i++) + Native.solverAssertAndTrack(getContext().nCtx(), getNativeObject(), + constraints[i].getNativeObject(), ps[i].getNativeObject()); + } + + // / + // / Assert a constraint into the solver, and track it (in the unsat) core + // / using the Boolean constant p. + // / + // / + // / This API is an alternative to with assumptions for + // extracting unsat cores. + // / Both APIs can be used in the same solver. The unsat core will contain a + // combination + // / of the Boolean variables provided using + // and the Boolean literals + // / provided using with assumptions. + // / + public void assertAndTrack(BoolExpr constraint, BoolExpr p) throws Z3Exception + { + getContext().checkContextMatch(constraint); + getContext().checkContextMatch(p); + + Native.solverAssertAndTrack(getContext().nCtx(), getNativeObject(), + constraint.getNativeObject(), p.getNativeObject()); } /** @@ -120,11 +157,11 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public int NumAssertions() throws Z3Exception + public int getNumAssertions() throws Z3Exception { - ASTVector ass = new ASTVector(Context(), Native.solverGetAssertions( - Context().nCtx(), NativeObject())); - return ass.Size(); + ASTVector ass = new ASTVector(getContext(), Native.solverGetAssertions( + getContext().nCtx(), getNativeObject())); + return ass.size(); } /** @@ -132,14 +169,14 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public BoolExpr[] Assertions() throws Z3Exception + public BoolExpr[] getAssertions() throws Z3Exception { - ASTVector ass = new ASTVector(Context(), Native.solverGetAssertions( - Context().nCtx(), NativeObject())); - int n = ass.Size(); + ASTVector ass = new ASTVector(getContext(), Native.solverGetAssertions( + getContext().nCtx(), getNativeObject())); + int n = ass.size(); BoolExpr[] res = new BoolExpr[n]; for (int i = 0; i < n; i++) - res[i] = new BoolExpr(Context(), ass.get(i).NativeObject()); + res[i] = new BoolExpr(getContext(), ass.get(i).getNativeObject()); return res; } @@ -148,16 +185,16 @@ public class Solver extends Z3Object * **/ - public Status Check(Expr[] assumptions) throws Z3Exception + public Status check(Expr... assumptions) throws Z3Exception { Z3_lbool r; if (assumptions == null) - r = Z3_lbool.fromInt(Native.solverCheck(Context().nCtx(), - NativeObject())); + r = Z3_lbool.fromInt(Native.solverCheck(getContext().nCtx(), + getNativeObject())); else - r = Z3_lbool.fromInt(Native.solverCheckAssumptions( - Context().nCtx(), NativeObject(), (int) assumptions.length, - AST.ArrayToNative(assumptions))); + r = Z3_lbool.fromInt(Native.solverCheckAssumptions(getContext() + .nCtx(), getNativeObject(), (int) assumptions.length, AST + .arrayToNative(assumptions))); switch (r) { case Z3_L_TRUE: @@ -174,9 +211,9 @@ public class Solver extends Z3Object * **/ - public Status Check() throws Z3Exception + public Status check() throws Z3Exception { - return Check(null); + return check((Expr[]) null); } /** @@ -187,13 +224,13 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public Model Model() throws Z3Exception + public Model getModel() throws Z3Exception { - long x = Native.solverGetModel(Context().nCtx(), NativeObject()); + long x = Native.solverGetModel(getContext().nCtx(), getNativeObject()); if (x == 0) return null; else - return new Model(Context(), x); + return new Model(getContext(), x); } /** @@ -204,13 +241,13 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public Expr Proof() throws Z3Exception + public Expr getProof() throws Z3Exception { - long x = Native.solverGetProof(Context().nCtx(), NativeObject()); + long x = Native.solverGetProof(getContext().nCtx(), getNativeObject()); if (x == 0) return null; else - return Expr.Create(Context(), x); + return Expr.create(getContext(), x); } /** @@ -221,15 +258,15 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public Expr[] UnsatCore() throws Z3Exception + public Expr[] getUnsatCore() throws Z3Exception { - ASTVector core = new ASTVector(Context(), Native.solverGetUnsatCore( - Context().nCtx(), NativeObject())); - int n = core.Size(); + ASTVector core = new ASTVector(getContext(), Native.solverGetUnsatCore( + getContext().nCtx(), getNativeObject())); + int n = core.size(); Expr[] res = new Expr[n]; for (int i = 0; i < n; i++) - res[i] = Expr.Create(Context(), core.get(i).NativeObject()); + res[i] = Expr.create(getContext(), core.get(i).getNativeObject()); return res; } @@ -237,9 +274,10 @@ public class Solver extends Z3Object * A brief justification of why the last call to Check returned * UNKNOWN. **/ - public String ReasonUnknown() throws Z3Exception + public String getReasonUnknown() throws Z3Exception { - return Native.solverGetReasonUnknown(Context().nCtx(), NativeObject()); + return Native.solverGetReasonUnknown(getContext().nCtx(), + getNativeObject()); } /** @@ -247,10 +285,10 @@ public class Solver extends Z3Object * * @throws Z3Exception **/ - public Statistics Statistics() throws Z3Exception + public Statistics getStatistics() throws Z3Exception { - return new Statistics(Context(), Native.solverGetStatistics(Context() - .nCtx(), NativeObject())); + return new Statistics(getContext(), Native.solverGetStatistics( + getContext().nCtx(), getNativeObject())); } /** @@ -260,7 +298,8 @@ public class Solver extends Z3Object { try { - return Native.solverToString(Context().nCtx(), NativeObject()); + return Native + .solverToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -272,15 +311,15 @@ public class Solver extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Solver_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().solver_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Solver_DRQ().Add(o); - super.DecRef(o); + getContext().solver_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/SolverDecRefQueue.java b/src/api/java/SolverDecRefQueue.java index 2696f6ecc..1c715716a 100644 --- a/src/api/java/SolverDecRefQueue.java +++ b/src/api/java/SolverDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class SolverDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class SolverDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/Sort.java b/src/api/java/Sort.java index fcf6b117a..58f7638ba 100644 --- a/src/api/java/Sort.java +++ b/src/api/java/Sort.java @@ -6,7 +6,8 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_ast_kind; +import com.microsoft.z3.enumerations.Z3_sort_kind; /** * The Sort class implements type information for ASTs. @@ -47,7 +48,7 @@ public class Sort extends AST return false; } - return this.NativeObject() == casted.NativeObject(); + return this.getNativeObject() == casted.getNativeObject(); } /** @@ -55,35 +56,35 @@ public class Sort extends AST * * @return A hash code **/ - public int GetHashCode() throws Z3Exception + public int hashCode() { - return super.GetHashCode(); + return super.hashCode(); } /** * Returns a unique identifier for the sort. **/ - public int Id() throws Z3Exception + public int getId() throws Z3Exception { - return Native.getSortId(Context().nCtx(), NativeObject()); + return Native.getSortId(getContext().nCtx(), getNativeObject()); } /** * The kind of the sort. **/ - public Z3_sort_kind SortKind() throws Z3Exception + public Z3_sort_kind getSortKind() throws Z3Exception { - return Z3_sort_kind.fromInt(Native.getSortKind(Context().nCtx(), - NativeObject())); + return Z3_sort_kind.fromInt(Native.getSortKind(getContext().nCtx(), + getNativeObject())); } /** * The name of the sort **/ - public Symbol Name() throws Z3Exception + public Symbol getName() throws Z3Exception { - return Symbol.Create(Context(), - Native.getSortName(Context().nCtx(), NativeObject())); + return Symbol.create(getContext(), + Native.getSortName(getContext().nCtx(), getNativeObject())); } /** @@ -93,7 +94,7 @@ public class Sort extends AST { try { - return Native.sortToString(Context().nCtx(), NativeObject()); + return Native.sortToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -117,15 +118,15 @@ public class Sort extends AST } } - void CheckNativeObject(long obj) throws Z3Exception + void checkNativeObject(long obj) throws Z3Exception { - if (Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_SORT_AST + if (Native.getAstKind(getContext().nCtx(), obj) != Z3_ast_kind.Z3_SORT_AST .toInt()) throw new Z3Exception("Underlying object is not a sort"); - super.CheckNativeObject(obj); + super.checkNativeObject(obj); } - static Sort Create(Context ctx, long obj) throws Z3Exception + static Sort create(Context ctx, long obj) throws Z3Exception { switch (Z3_sort_kind.fromInt(Native.getSortKind(ctx.nCtx(), obj))) { diff --git a/src/api/java/Statistics.java b/src/api/java/Statistics.java index 3f6e31f96..c36020bd6 100644 --- a/src/api/java/Statistics.java +++ b/src/api/java/Statistics.java @@ -25,7 +25,7 @@ public class Statistics extends Z3Object /** * The uint-value of the entry. **/ - public int UIntValue() + public int getUIntValue() { return m_int; } @@ -33,7 +33,7 @@ public class Statistics extends Z3Object /** * The double-value of the entry. **/ - public double DoubleValue() + public double getDoubleValue() { return m_double; } @@ -41,7 +41,7 @@ public class Statistics extends Z3Object /** * True if the entry is uint-valued. **/ - public boolean IsUInt() + public boolean isUInt() { return m_is_int; } @@ -49,7 +49,7 @@ public class Statistics extends Z3Object /** * True if the entry is double-valued. **/ - public boolean IsDouble() + public boolean isDouble() { return m_is_double; } @@ -59,11 +59,11 @@ public class Statistics extends Z3Object * * @throws Z3Exception **/ - public String Value() throws Z3Exception + public String getValueString() throws Z3Exception { - if (IsUInt()) + if (isUInt()) return Integer.toString(m_int); - else if (IsDouble()) + else if (isDouble()) return Double.toString(m_double); else throw new Z3Exception("Unknown statistical entry type"); @@ -76,7 +76,7 @@ public class Statistics extends Z3Object { try { - return Key + ": " + Value(); + return Key + ": " + getValueString(); } catch (Z3Exception e) { return new String("Z3Exception: " + e.getMessage()); @@ -110,7 +110,7 @@ public class Statistics extends Z3Object { try { - return Native.statsToString(Context().nCtx(), NativeObject()); + return Native.statsToString(getContext().nCtx(), getNativeObject()); } catch (Z3Exception e) { return "Z3Exception: " + e.getMessage(); @@ -120,9 +120,9 @@ public class Statistics extends Z3Object /** * The number of statistical data. **/ - public int Size() throws Z3Exception + public int size() throws Z3Exception { - return Native.statsSize(Context().nCtx(), NativeObject()); + return Native.statsSize(getContext().nCtx(), getNativeObject()); } /** @@ -130,21 +130,21 @@ public class Statistics extends Z3Object * * @throws Z3Exception **/ - public Entry[] Entries() throws Z3Exception + public Entry[] getEntries() throws Z3Exception { - int n = Size(); + int n = size(); Entry[] res = new Entry[n]; for (int i = 0; i < n; i++) { Entry e; - String k = Native.statsGetKey(Context().nCtx(), NativeObject(), i); - if (Native.statsIsUint(Context().nCtx(), NativeObject(), i)) - e = new Entry(k, Native.statsGetUintValue(Context().nCtx(), - NativeObject(), i)); - else if (Native.statsIsDouble(Context().nCtx(), NativeObject(), i)) - e = new Entry(k, Native.statsGetDoubleValue(Context().nCtx(), - NativeObject(), i)); + String k = Native.statsGetKey(getContext().nCtx(), getNativeObject(), i); + if (Native.statsIsUint(getContext().nCtx(), getNativeObject(), i)) + e = new Entry(k, Native.statsGetUintValue(getContext().nCtx(), + getNativeObject(), i)); + else if (Native.statsIsDouble(getContext().nCtx(), getNativeObject(), i)) + e = new Entry(k, Native.statsGetDoubleValue(getContext().nCtx(), + getNativeObject(), i)); else throw new Z3Exception("Unknown data entry value"); res[i] = e; @@ -155,12 +155,12 @@ public class Statistics extends Z3Object /** * The statistical counters. **/ - public String[] Keys() throws Z3Exception + public String[] getKeys() throws Z3Exception { - int n = Size(); + int n = size(); String[] res = new String[n]; for (int i = 0; i < n; i++) - res[i] = Native.statsGetKey(Context().nCtx(), NativeObject(), i); + res[i] = Native.statsGetKey(getContext().nCtx(), getNativeObject(), i); return res; } @@ -172,8 +172,8 @@ public class Statistics extends Z3Object **/ public Entry get(String key) throws Z3Exception { - int n = Size(); - Entry[] es = Entries(); + int n = size(); + Entry[] es = getEntries(); for (int i = 0; i < n; i++) if (es[i].Key == key) return es[i]; @@ -185,15 +185,15 @@ public class Statistics extends Z3Object super(ctx, obj); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Statistics_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().statistics_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Statistics_DRQ().Add(o); - super.DecRef(o); + getContext().statistics_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/StatisticsDecRefQueue.java b/src/api/java/StatisticsDecRefQueue.java index 907cf8760..d16bf3710 100644 --- a/src/api/java/StatisticsDecRefQueue.java +++ b/src/api/java/StatisticsDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class StatisticsDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class StatisticsDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/StringSymbol.java b/src/api/java/StringSymbol.java index 81ada78a4..951051aa0 100644 --- a/src/api/java/StringSymbol.java +++ b/src/api/java/StringSymbol.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_symbol_kind; /** * Named symbols @@ -17,9 +17,9 @@ public class StringSymbol extends Symbol * The string value of the symbol. Throws an exception if the * symbol is not of string kind. **/ - public String String() throws Z3Exception + public String getString() throws Z3Exception { - return Native.getSymbolString(Context().nCtx(), NativeObject()); + return Native.getSymbolString(getContext().nCtx(), getNativeObject()); } StringSymbol(Context ctx, long obj) throws Z3Exception @@ -32,12 +32,12 @@ public class StringSymbol extends Symbol super(ctx, Native.mkStringSymbol(ctx.nCtx(), s)); } - void CheckNativeObject(long obj) throws Z3Exception + void checkNativeObject(long obj) throws Z3Exception { - if (Native.getSymbolKind(Context().nCtx(), obj) != Z3_symbol_kind.Z3_STRING_SYMBOL + if (Native.getSymbolKind(getContext().nCtx(), obj) != Z3_symbol_kind.Z3_STRING_SYMBOL .toInt()) throw new Z3Exception("Symbol is not of String kind"); - super.CheckNativeObject(obj); + super.checkNativeObject(obj); } } diff --git a/src/api/java/Symbol.java b/src/api/java/Symbol.java index cd987adf2..177409ec8 100644 --- a/src/api/java/Symbol.java +++ b/src/api/java/Symbol.java @@ -6,7 +6,7 @@ package com.microsoft.z3; -import com.microsoft.z3.enumerations.*; +import com.microsoft.z3.enumerations.Z3_symbol_kind; /** * Symbols are used to name several term and type constructors. @@ -16,26 +16,26 @@ public class Symbol extends Z3Object /** * The kind of the symbol (int or string) **/ - protected Z3_symbol_kind Kind() throws Z3Exception + protected Z3_symbol_kind getKind() throws Z3Exception { - return Z3_symbol_kind.fromInt(Native.getSymbolKind(Context().nCtx(), - NativeObject())); + return Z3_symbol_kind.fromInt(Native.getSymbolKind(getContext().nCtx(), + getNativeObject())); } /** * Indicates whether the symbol is of Int kind **/ - public boolean IsIntSymbol() throws Z3Exception + public boolean isIntSymbol() throws Z3Exception { - return Kind() == Z3_symbol_kind.Z3_INT_SYMBOL; + return getKind() == Z3_symbol_kind.Z3_INT_SYMBOL; } /** * Indicates whether the symbol is of string kind. **/ - public boolean IsStringSymbol() throws Z3Exception + public boolean isStringSymbol() throws Z3Exception { - return Kind() == Z3_symbol_kind.Z3_STRING_SYMBOL; + return getKind() == Z3_symbol_kind.Z3_STRING_SYMBOL; } /** @@ -45,10 +45,10 @@ public class Symbol extends Z3Object { try { - if (IsIntSymbol()) - return Integer.toString(((IntSymbol) this).Int()); - else if (IsStringSymbol()) - return ((StringSymbol) this).String(); + if (isIntSymbol()) + return Integer.toString(((IntSymbol) this).getInt()); + else if (isStringSymbol()) + return ((StringSymbol) this).getString(); else return new String( "Z3Exception: Unknown symbol kind encountered."); @@ -66,7 +66,7 @@ public class Symbol extends Z3Object super(ctx, obj); } - static Symbol Create(Context ctx, long obj) throws Z3Exception + static Symbol create(Context ctx, long obj) throws Z3Exception { switch (Z3_symbol_kind.fromInt(Native.getSymbolKind(ctx.nCtx(), obj))) { diff --git a/src/api/java/Tactic.java b/src/api/java/Tactic.java index 124db0ef2..e62096715 100644 --- a/src/api/java/Tactic.java +++ b/src/api/java/Tactic.java @@ -18,69 +18,57 @@ public class Tactic extends Z3Object /** * A string containing a description of parameters accepted by the tactic. **/ - public String Help() throws Z3Exception + public String getHelp() throws Z3Exception { - return Native.tacticGetHelp(Context().nCtx(), NativeObject()); + return Native.tacticGetHelp(getContext().nCtx(), getNativeObject()); } /** * Retrieves parameter descriptions for Tactics. * @throws Z3Exception **/ - public ParamDescrs ParameterDescriptions() throws Z3Exception + public ParamDescrs getParameterDescriptions() throws Z3Exception { - return new ParamDescrs(Context(), Native.tacticGetParamDescrs(Context() - .nCtx(), NativeObject())); + return new ParamDescrs(getContext(), Native.tacticGetParamDescrs(getContext() + .nCtx(), getNativeObject())); } /** * Execute the tactic over the goal. * @throws Z3Exception **/ - public ApplyResult Apply(Goal g) throws Z3Exception + public ApplyResult apply(Goal g) throws Z3Exception { - return Apply(g, null); + return apply(g, null); } /** * Execute the tactic over the goal. * @throws Z3Exception **/ - public ApplyResult Apply(Goal g, Params p) throws Z3Exception + public ApplyResult apply(Goal g, Params p) throws Z3Exception { - - Context().CheckContextMatch(g); + getContext().checkContextMatch(g); if (p == null) - return new ApplyResult(Context(), Native.tacticApply(Context() - .nCtx(), NativeObject(), g.NativeObject())); + return new ApplyResult(getContext(), Native.tacticApply(getContext() + .nCtx(), getNativeObject(), g.getNativeObject())); else { - Context().CheckContextMatch(p); - return new ApplyResult(Context(), - Native.tacticApplyEx(Context().nCtx(), NativeObject(), - g.NativeObject(), p.NativeObject())); + getContext().checkContextMatch(p); + return new ApplyResult(getContext(), + Native.tacticApplyEx(getContext().nCtx(), getNativeObject(), + g.getNativeObject(), p.getNativeObject())); } } - /** - * Apply the tactic to a goal. - * @throws Z3Exception - **/ - public ApplyResult get(Goal g) throws Z3Exception - { - - return Apply(g, null); - } - /** * Creates a solver that is implemented using the given tactic. * @throws Z3Exception **/ - public Solver Solver() throws Z3Exception + public Solver getSolver() throws Z3Exception { - - return Context().MkSolver(this); + return getContext().mkSolver(this); } Tactic(Context ctx, long obj) throws Z3Exception @@ -93,15 +81,15 @@ public class Tactic extends Z3Object super(ctx, Native.mkTactic(ctx.nCtx(), name)); } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { - Context().Tactic_DRQ().IncAndClear(Context(), o); - super.IncRef(o); + getContext().tactic_DRQ().incAndClear(getContext(), o); + super.incRef(o); } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { - Context().Tactic_DRQ().Add(o); - super.DecRef(o); + getContext().tactic_DRQ().add(o); + super.decRef(o); } } diff --git a/src/api/java/TacticDecRefQueue.java b/src/api/java/TacticDecRefQueue.java index c2ea2c079..50fba156e 100644 --- a/src/api/java/TacticDecRefQueue.java +++ b/src/api/java/TacticDecRefQueue.java @@ -7,7 +7,7 @@ package com.microsoft.z3; class TacticDecRefQueue extends IDecRefQueue { - public void IncRef(Context ctx, long obj) + protected void incRef(Context ctx, long obj) { try { @@ -18,7 +18,7 @@ class TacticDecRefQueue extends IDecRefQueue } } - public void DecRef(Context ctx, long obj) + protected void decRef(Context ctx, long obj) { try { diff --git a/src/api/java/TupleSort.java b/src/api/java/TupleSort.java index 3eb28b88e..554581d0f 100644 --- a/src/api/java/TupleSort.java +++ b/src/api/java/TupleSort.java @@ -15,33 +15,33 @@ public class TupleSort extends Sort * The constructor function of the tuple. * @throws Z3Exception **/ - public FuncDecl MkDecl() throws Z3Exception + public FuncDecl mkDecl() throws Z3Exception { - return new FuncDecl(Context(), Native.getTupleSortMkDecl(Context() - .nCtx(), NativeObject())); + return new FuncDecl(getContext(), Native.getTupleSortMkDecl(getContext() + .nCtx(), getNativeObject())); } /** * The number of fields in the tuple. **/ - public int NumFields() throws Z3Exception + public int getNumFields() throws Z3Exception { - return Native.getTupleSortNumFields(Context().nCtx(), NativeObject()); + return Native.getTupleSortNumFields(getContext().nCtx(), getNativeObject()); } /** * The field declarations. * @throws Z3Exception **/ - public FuncDecl[] FieldDecls() throws Z3Exception + public FuncDecl[] getFieldDecls() throws Z3Exception { - int n = NumFields(); + int n = getNumFields(); FuncDecl[] res = new FuncDecl[n]; for (int i = 0; i < n; i++) - res[i] = new FuncDecl(Context(), Native.getTupleSortFieldDecl( - Context().nCtx(), NativeObject(), i)); + res[i] = new FuncDecl(getContext(), Native.getTupleSortFieldDecl( + getContext().nCtx(), getNativeObject(), i)); return res; } @@ -51,8 +51,8 @@ public class TupleSort extends Sort super(ctx); Native.LongPtr t = new Native.LongPtr(); - setNativeObject(Native.mkTupleSort(ctx.nCtx(), name.NativeObject(), - numFields, Symbol.ArrayToNative(fieldNames), - AST.ArrayToNative(fieldSorts), t, new long[numFields])); + setNativeObject(Native.mkTupleSort(ctx.nCtx(), name.getNativeObject(), + numFields, Symbol.arrayToNative(fieldNames), + AST.arrayToNative(fieldSorts), t, new long[numFields])); } }; diff --git a/src/api/java/UninterpretedSort.java b/src/api/java/UninterpretedSort.java index bc062cb50..51df17543 100644 --- a/src/api/java/UninterpretedSort.java +++ b/src/api/java/UninterpretedSort.java @@ -18,6 +18,6 @@ public class UninterpretedSort extends Sort UninterpretedSort(Context ctx, Symbol s) throws Z3Exception { - super(ctx, Native.mkUninterpretedSort(ctx.nCtx(), s.NativeObject())); + super(ctx, Native.mkUninterpretedSort(ctx.nCtx(), s.getNativeObject())); } } diff --git a/src/api/java/Version.java b/src/api/java/Version.java index af5da39de..b96fb50f9 100644 --- a/src/api/java/Version.java +++ b/src/api/java/Version.java @@ -14,7 +14,7 @@ public class Version /** * The major version **/ - public static int Major() + public static int getMajor() { Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); Native.getVersion(major, minor, build, revision); @@ -24,7 +24,7 @@ public class Version /** * The minor version **/ - public static int Minor() + public static int getMinor() { Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); Native.getVersion(major, minor, build, revision); @@ -34,7 +34,7 @@ public class Version /** * The build version **/ - public static int Build() + public static int getBuild() { Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); Native.getVersion(major, minor, build, revision); @@ -44,7 +44,7 @@ public class Version /** * The revision **/ - public static int Revision() + public static int getRevision() { Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); Native.getVersion(major, minor, build, revision); diff --git a/src/api/java/Z3Exception.java b/src/api/java/Z3Exception.java index ae7046c90..24dc586d4 100644 --- a/src/api/java/Z3Exception.java +++ b/src/api/java/Z3Exception.java @@ -6,7 +6,6 @@ package com.microsoft.z3; -import java.lang.Exception; /** * The exception base class for error reporting from Z3 diff --git a/src/api/java/Z3Object.java b/src/api/java/Z3Object.java index 8aeb03ddf..6c2c11e25 100644 --- a/src/api/java/Z3Object.java +++ b/src/api/java/Z3Object.java @@ -17,17 +17,17 @@ public class Z3Object extends IDisposable **/ protected void finalize() throws Z3Exception { - Dispose(); + dispose(); } /** * Disposes of the underlying native Z3 object. **/ - public void Dispose() throws Z3Exception + public void dispose() throws Z3Exception { if (m_n_obj != 0) { - DecRef(m_n_obj); + decRef(m_n_obj); m_n_obj = 0; } @@ -51,23 +51,23 @@ public class Z3Object extends IDisposable { ctx.m_refCount++; m_ctx = ctx; - IncRef(obj); + incRef(obj); m_n_obj = obj; } - void IncRef(long o) throws Z3Exception + void incRef(long o) throws Z3Exception { } - void DecRef(long o) throws Z3Exception + void decRef(long o) throws Z3Exception { } - void CheckNativeObject(long obj) throws Z3Exception + void checkNativeObject(long obj) throws Z3Exception { } - long NativeObject() + long getNativeObject() { return m_n_obj; } @@ -76,39 +76,39 @@ public class Z3Object extends IDisposable { if (value != 0) { - CheckNativeObject(value); - IncRef(value); + checkNativeObject(value); + incRef(value); } if (m_n_obj != 0) { - DecRef(m_n_obj); + decRef(m_n_obj); } m_n_obj = value; } - static long GetNativeObject(Z3Object s) + static long getNativeObject(Z3Object s) { if (s == null) return 0; - return s.NativeObject(); + return s.getNativeObject(); } - Context Context() + Context getContext() { return m_ctx; } - static long[] ArrayToNative(Z3Object[] a) + static long[] arrayToNative(Z3Object[] a) { if (a == null) return null; long[] an = new long[a.length]; for (int i = 0; i < a.length; i++) - an[i] = (a[i] == null) ? 0 : a[i].NativeObject(); + an[i] = (a[i] == null) ? 0 : a[i].getNativeObject(); return an; } - static int ArrayLength(Z3Object[] a) + static int arrayLength(Z3Object[] a) { return (a == null) ? 0 : a.length; } From 8daf100c6502da11ff5eabe8d0981917a91ea530 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Jan 2013 18:03:34 -0800 Subject: [PATCH 022/101] working on tab Horn solver Signed-off-by: Nikolaj Bjorner --- src/ast/substitution/matcher.cpp | 4 + src/ast/substitution/matcher.h | 2 +- src/muz_qe/dl_mk_interp_tail_simplifier.cpp | 2 +- src/muz_qe/tab_context.cpp | 229 ++++++++++++++++++-- src/test/matcher.cpp | 3 + 5 files changed, 214 insertions(+), 26 deletions(-) diff --git a/src/ast/substitution/matcher.cpp b/src/ast/substitution/matcher.cpp index cf0eff6b4..a5560c6a2 100644 --- a/src/ast/substitution/matcher.cpp +++ b/src/ast/substitution/matcher.cpp @@ -49,6 +49,10 @@ bool matcher::operator()(expr * e1, expr * e2, substitution & s) { if (is_var(p.second)) return false; + if (!is_app(p.first)) + return false; + if (!is_app(p.second)) + return false; app * n1 = to_app(p.first); app * n2 = to_app(p.second); diff --git a/src/ast/substitution/matcher.h b/src/ast/substitution/matcher.h index 662cfd371..1a71a51ed 100644 --- a/src/ast/substitution/matcher.h +++ b/src/ast/substitution/matcher.h @@ -32,7 +32,7 @@ class matcher { ast_manager & m_manager; substitution * m_subst; - cache m_cache; + // cache m_cache; svector m_todo; void reset(); diff --git a/src/muz_qe/dl_mk_interp_tail_simplifier.cpp b/src/muz_qe/dl_mk_interp_tail_simplifier.cpp index 9861c48ca..d028c8751 100644 --- a/src/muz_qe/dl_mk_interp_tail_simplifier.cpp +++ b/src/muz_qe/dl_mk_interp_tail_simplifier.cpp @@ -518,7 +518,7 @@ namespace datalog { if (m.is_false(itail.get())) { //the tail member is never true, so we may delete the rule - TRACE("dl", r->display(m_context, tout << "rule in infeasible\n");); + TRACE("dl", r->display(m_context, tout << "rule is infeasible\n");); return false; } if (!m.is_true(itail.get())) { diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index c025a9ec5..f96fd9a1e 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -22,6 +22,8 @@ Revision History: #include "dl_rule_set.h" #include "dl_context.h" #include "dl_mk_rule_inliner.h" +#include "smt_kernel.h" +#include "matcher.h" namespace datalog { @@ -42,6 +44,129 @@ namespace datalog { } }; + // subsumption index structure. + class tab_index { + ast_manager& m; + rule_manager& rm; + context& m_ctx; + app_ref_vector m_preds; + expr_ref m_precond; + rule_ref_vector m_rules; + svector m_num_vars; + unsigned m_index; + matcher m_matcher; + substitution m_subst; + + public: + tab_index(ast_manager& m, rule_manager& rm, context& ctx): + m(m), + rm(rm), + m_ctx(ctx), + m_preds(m), + m_precond(m), + m_rules(rm), + m_matcher(m), + m_subst(m) {} + + void insert(rule* r) { + m_rules.push_back(r); + m_num_vars.push_back(1+rm.get_var_counter().get_max_var(*r)); + } + + void setup(rule const& r) { + m_preds.reset(); + m_index = 0; + expr_ref_vector fmls(m); + expr_ref_vector vars(m); + expr_ref fml(m); + ptr_vector sorts; + r.get_vars(sorts); + unsigned utsz = r.get_uninterpreted_tail_size(); + unsigned tsz = r.get_tail_size(); + var_subst vs(m, false); + for (unsigned i = 0; i < sorts.size(); ++i) { + if (!sorts[i]) { + sorts[i] = m.mk_bool_sort(); + } + vars.push_back(m.mk_const(symbol(i), sorts[i])); + } + for (unsigned i = 0; i < utsz; ++i) { + fml = r.get_tail(i); + vs(fml, vars.size(), vars.c_ptr(), fml); + m_preds.push_back(to_app(fml)); + } + for (unsigned i = utsz; i < tsz; ++i) { + fml = r.get_tail(i); + vs(fml, vars.size(), vars.c_ptr(), fml); + fmls.push_back(fml); + } + m_precond = m.mk_and(fmls.size(), fmls.c_ptr()); + IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "setup-match\n");); + } + + // extract pre_cond => post_cond validation obligation from match. + bool next_match(expr_ref& pre_cond, expr_ref& post_cond) { + for (; m_index < m_rules.size(); ++m_index) { + if (try_match(pre_cond, post_cond)) { + return true; + } + } + return false; + } + private: + // + // check that each predicate in r is matched by some predicate in premise. + // for now: skip multiple matches within the same rule (incomplete). + // + bool try_match(expr_ref& pre_cond, expr_ref& post_cond) { + rule const& r = *m_rules[m_index]; + unsigned num_vars = m_num_vars[m_index]; + m_subst.reset(); + m_subst.reserve(2, num_vars); + unsigned deltas[2] = {0, 0}; + expr_ref_vector fmls(m); + expr_ref q(m); + unsigned utsz = r.get_uninterpreted_tail_size(); + unsigned tsz = r.get_tail_size(); + + IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "try-match\n");); + + for (unsigned i = 0; i < utsz; ++i) { + m_subst.push_scope(); + if (!try_match(r.get_tail(i))) { + return false; + } + } + for (unsigned i = utsz; i < tsz; ++i) { + app* p = r.get_tail(i); + m_subst.apply(2, deltas, expr_offset(p, 0), q); + fmls.push_back(q); + } + + pre_cond = m_precond; + post_cond = m.mk_and(fmls.size(), fmls.c_ptr()); + IF_VERBOSE(1, verbose_stream() << "match: " << mk_pp(post_cond, m) << "\n";); + // TBD: + // - existential closure of post_cond + // - eliminate variables from post_cond + return true; + } + + bool try_match(expr* q) { + for (unsigned i = 0; i < m_preds.size(); ++i) { + if (m_matcher(q, m_preds[i].get(), m_subst)) { + return true; + } + else { + // undo effect of failed match attempt. + m_subst.pop_scope(); + m_subst.push_scope(); + } + } + return false; + } + }; + enum tab_instruction { SELECT_RULE, SELECT_PREDICATE, @@ -54,13 +179,13 @@ namespace datalog { std::ostream& operator<<(std::ostream& out, tab_instruction i) { switch(i) { - case SELECT_RULE: return out << "select-rule"; + case SELECT_RULE: return out << "select-rule"; case SELECT_PREDICATE: return out << "select-predicate"; - case BACKTRACK: return out << "backtrack"; - case NEXT_RULE: return out << "next-rule"; - case SATISFIABLE: return out << "sat"; - case UNSATISFIABLE: return out << "unsat"; - case CANCEL: return out << "cancel"; + case BACKTRACK: return out << "backtrack"; + case NEXT_RULE: return out << "next-rule"; + case SATISFIABLE: return out << "sat"; + case UNSATISFIABLE: return out << "unsat"; + case CANCEL: return out << "cancel"; } return out << "unmatched instruction"; } @@ -77,6 +202,9 @@ namespace datalog { context& m_ctx; ast_manager& m; rule_manager& rm; + tab_index m_subsumption_index; + smt_params m_fparams; + smt::kernel m_solver; rule_unifier m_unifier; rule_set m_rules; trail_stack m_trail; @@ -92,6 +220,8 @@ namespace datalog { m_ctx(ctx), m(ctx.get_manager()), rm(ctx.get_rule_manager()), + m_subsumption_index(m, rm, ctx), + m_solver(m, m_fparams), m_unifier(ctx), m_rules(ctx), m_trail(*this), @@ -101,7 +231,11 @@ namespace datalog { m_predicate_index(0), m_rule_index(0), m_cancel(false) - {} + { + // m_fparams.m_relevancy_lvl = 0; + m_fparams.m_mbqi = false; + m_fparams.m_soft_timeout = 1000; + } ~imp() {} @@ -148,13 +282,15 @@ namespace datalog { } else { m_instruction = SELECT_RULE; - m_predicate_index = 0; // TBD replace by better selection function. + m_predicate_index = 0; // TBD replace by better selection function. m_rule_index = 0; + IF_VERBOSE(1, verbose_stream() << mk_pp(m_query->get_tail(m_predicate_index), m) << "\n";); } } void apply_rule(rule const& r) { m_rule_index++; + IF_VERBOSE(1, r.display(m_ctx, verbose_stream());); bool can_unify = m_unifier.unify_rules(*m_query, m_predicate_index, r); if (can_unify) { m_stats.m_num_unfold++; @@ -162,18 +298,24 @@ namespace datalog { m_trail.push(value_trail(m_rule_index)); m_trail.push(value_trail(m_predicate_index)); rule_ref new_query(rm); - m_unifier.apply(*m_query, m_predicate_index, r, new_query); - m_trail.push(restore_rule(m_query_trail, m_query)); - m_query = new_query; - TRACE("dl", m_query->display(m_ctx, tout);); - if (l_false == query_is_sat()) { - m_instruction = BACKTRACK; - } - else if (l_true == query_is_subsumed()) { - NOT_IMPLEMENTED_YET(); + bool is_feasible = m_unifier.apply(*m_query, m_predicate_index, r, new_query); + if (is_feasible) { + TRACE("dl", m_query->display(m_ctx, tout);); + if (l_false == query_is_sat(*new_query.get())) { + m_instruction = BACKTRACK; + } + else if (l_true == query_is_subsumed(*new_query.get())) { + m_instruction = BACKTRACK; + } + else { + m_subsumption_index.insert(m_query.get()); + m_trail.push(restore_rule(m_query_trail, m_query)); + m_query = new_query; + m_instruction = SELECT_PREDICATE; + } } else { - m_instruction = SELECT_PREDICATE; + m_instruction = BACKTRACK; } } else { @@ -212,7 +354,7 @@ namespace datalog { lbool run() { m_instruction = SELECT_PREDICATE; while (true) { - IF_VERBOSE(1, verbose_stream() << "run " << m_instruction << "\n";); + IF_VERBOSE(1, verbose_stream() << "run " << m_trail.get_num_scopes() << " " << m_instruction << "\n";); if (m_cancel) { cleanup(); return l_undef; @@ -241,16 +383,55 @@ namespace datalog { } } - lbool query_is_sat() { + lbool query_is_sat(rule const& query) { expr_ref_vector fmls(m); + expr_ref fml(m); + unsigned utsz = query.get_uninterpreted_tail_size(); + unsigned tsz = query.get_tail_size(); + for (unsigned i = utsz; i < tsz; ++i) { + fmls.push_back(query.get_tail(i)); + } + ptr_vector sorts; + svector names; + query.get_vars(sorts); + sorts.reverse(); + for (unsigned i = 0; i < sorts.size(); ++i) { + if (!sorts[i]) { + sorts[i] = m.mk_bool_sort(); + } + names.push_back(symbol(i)); + } + fml = m.mk_and(fmls.size(), fmls.c_ptr()); + fml = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), fml); + m_solver.push(); + m_solver.assert_expr(fml); + lbool is_sat = m_solver.check(); + m_solver.pop(1); - return l_undef; + TRACE("dl", tout << is_sat << ":\n" << mk_pp(fml, m) << "\n";); + + return is_sat; } - lbool query_is_subsumed() { - return l_undef; + lbool query_is_subsumed(rule const& query) { + lbool is_subsumed = l_false; + m_subsumption_index.setup(query); + expr_ref precond(m), postcond(m); + while (m_subsumption_index.next_match(precond, postcond)) { + if (is_ground(postcond)) { + postcond = m.mk_not(postcond); + m_solver.push(); + m_solver.assert_expr(precond); + m_solver.assert_expr(postcond); + lbool is_sat = m_solver.check(); + m_solver.pop(1); + if (is_sat == l_false) { + return l_true; + } + } + } + return is_subsumed; } - }; tab::tab(context& ctx): diff --git a/src/test/matcher.cpp b/src/test/matcher.cpp index aaab9905c..cfbab2d3c 100644 --- a/src/test/matcher.cpp +++ b/src/test/matcher.cpp @@ -19,6 +19,8 @@ Revision History: #ifdef _WINDOWS #include"matcher.h" #include"ast_pp.h" +#include "reg_decl_plugins.h" + void tst_match(ast_manager & m, app * t, app * i) { substitution s(m); @@ -72,6 +74,7 @@ void tst_match(ast_manager & m, app * t, app * i) { void tst1() { ast_manager m; + reg_decl_plugins(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); From cab908bfef3192405666900c4bdd465541763835 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 18 Jan 2013 09:56:35 -0800 Subject: [PATCH 023/101] working on horn tab solver Signed-off-by: Nikolaj Bjorner --- src/muz_qe/tab_context.cpp | 73 +++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index f96fd9a1e..fd820fe8a 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -24,6 +24,8 @@ Revision History: #include "dl_mk_rule_inliner.h" #include "smt_kernel.h" #include "matcher.h" +#include "qe_lite.h" +#include "bool_rewriter.h" namespace datalog { @@ -46,16 +48,19 @@ namespace datalog { // subsumption index structure. class tab_index { - ast_manager& m; - rule_manager& rm; - context& m_ctx; - app_ref_vector m_preds; - expr_ref m_precond; - rule_ref_vector m_rules; - svector m_num_vars; - unsigned m_index; - matcher m_matcher; - substitution m_subst; + ast_manager& m; + rule_manager& rm; + context& m_ctx; + app_ref_vector m_preds; + expr_ref m_precond; + rule_ref_vector m_rules; + svector m_num_vars; + unsigned m_idx1; + matcher m_matcher; + substitution m_subst; + qe_lite m_qe; + uint_set m_empty_set; + bool_rewriter m_rw; public: tab_index(ast_manager& m, rule_manager& rm, context& ctx): @@ -66,7 +71,9 @@ namespace datalog { m_precond(m), m_rules(rm), m_matcher(m), - m_subst(m) {} + m_subst(m), + m_qe(m), + m_rw(m) {} void insert(rule* r) { m_rules.push_back(r); @@ -75,7 +82,7 @@ namespace datalog { void setup(rule const& r) { m_preds.reset(); - m_index = 0; + m_idx1 = 0; expr_ref_vector fmls(m); expr_ref_vector vars(m); expr_ref fml(m); @@ -104,10 +111,13 @@ namespace datalog { IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "setup-match\n");); } + expr* get_precond() { return m_precond; } + // extract pre_cond => post_cond validation obligation from match. - bool next_match(expr_ref& pre_cond, expr_ref& post_cond) { - for (; m_index < m_rules.size(); ++m_index) { - if (try_match(pre_cond, post_cond)) { + bool next_match(expr_ref& post_cond) { + for (; m_idx1 < m_rules.size(); ++m_idx1) { + if (try_match(post_cond)) { + ++m_idx1; return true; } } @@ -118,9 +128,9 @@ namespace datalog { // check that each predicate in r is matched by some predicate in premise. // for now: skip multiple matches within the same rule (incomplete). // - bool try_match(expr_ref& pre_cond, expr_ref& post_cond) { - rule const& r = *m_rules[m_index]; - unsigned num_vars = m_num_vars[m_index]; + bool try_match(expr_ref& post_cond) { + rule const& r = *m_rules[m_idx1]; + unsigned num_vars = m_num_vars[m_idx1]; m_subst.reset(); m_subst.reserve(2, num_vars); unsigned deltas[2] = {0, 0}; @@ -129,7 +139,7 @@ namespace datalog { unsigned utsz = r.get_uninterpreted_tail_size(); unsigned tsz = r.get_tail_size(); - IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "try-match\n");); + // IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "try-match\n");); for (unsigned i = 0; i < utsz; ++i) { m_subst.push_scope(); @@ -143,13 +153,15 @@ namespace datalog { fmls.push_back(q); } - pre_cond = m_precond; - post_cond = m.mk_and(fmls.size(), fmls.c_ptr()); - IF_VERBOSE(1, verbose_stream() << "match: " << mk_pp(post_cond, m) << "\n";); - // TBD: - // - existential closure of post_cond - // - eliminate variables from post_cond - return true; + m_qe(m_empty_set, false, fmls); + m_rw.mk_and(fmls.size(), fmls.c_ptr(), post_cond); + if (m.is_false(post_cond)) { + return false; + } + else { + IF_VERBOSE(1, verbose_stream() << "match: " << mk_pp(post_cond, m) << "\n";); + return true; + } } bool try_match(expr* q) { @@ -416,12 +428,12 @@ namespace datalog { lbool query_is_subsumed(rule const& query) { lbool is_subsumed = l_false; m_subsumption_index.setup(query); - expr_ref precond(m), postcond(m); - while (m_subsumption_index.next_match(precond, postcond)) { + expr_ref postcond(m); + while (m_subsumption_index.next_match(postcond)) { if (is_ground(postcond)) { postcond = m.mk_not(postcond); m_solver.push(); - m_solver.assert_expr(precond); + m_solver.assert_expr(m_subsumption_index.get_precond()); m_solver.assert_expr(postcond); lbool is_sat = m_solver.check(); m_solver.pop(1); @@ -429,6 +441,9 @@ namespace datalog { return l_true; } } + else { + IF_VERBOSE(1, verbose_stream() << "non-ground: " << mk_pp(postcond, m) << "\n";); + } } return is_subsumed; } From 99f5a5bddbc9e44e0369034e666533491cb57c78 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 18 Jan 2013 17:36:42 -0800 Subject: [PATCH 024/101] working on tab_context Signed-off-by: Nikolaj Bjorner --- src/muz_qe/tab_context.cpp | 311 +++++++++++++++++++++---------------- 1 file changed, 175 insertions(+), 136 deletions(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index fd820fe8a..0eb9331d2 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -29,22 +29,30 @@ Revision History: namespace datalog { - template - struct restore_rule : trail { - rule_ref_vector& m_rules; - rule_ref& m_rule; +#if 0 + // semantic matcher. + class tab_matcher { + typedef std::pair expr_pair; + svector m_todo; + + public: + matcher(ast_manager& m): m(m) {} - restore_rule(rule_ref_vector& rules, rule_ref& rule): - m_rules(rules), - m_rule(rule) { - m_rules.push_back(m_rule); + bool operator()(expr* pat, expr* term, substitution& s, expr_ref_vector& side_conds) { + m_todo.reset(); + m_todo.push_back(expr_pair(pat, term)); + while (!m_todo.empty()) { + expr_pair const& p = m_todo.back(); + pat = p.first; + term = p.second; + if (is_var(pat)) { + + } + } } - virtual void undo(Ctx & ctx) { - m_rule = m_rules.back(); - m_rules.pop_back(); - } }; +#endif // subsumption index structure. class tab_index { @@ -55,12 +63,13 @@ namespace datalog { expr_ref m_precond; rule_ref_vector m_rules; svector m_num_vars; - unsigned m_idx1; matcher m_matcher; substitution m_subst; qe_lite m_qe; uint_set m_empty_set; bool_rewriter m_rw; + smt_params m_fparams; + smt::kernel m_solver; public: tab_index(ast_manager& m, rule_manager& rm, context& ctx): @@ -73,16 +82,27 @@ namespace datalog { m_matcher(m), m_subst(m), m_qe(m), - m_rw(m) {} + m_rw(m), + m_solver(m, m_fparams) {} void insert(rule* r) { m_rules.push_back(r); m_num_vars.push_back(1+rm.get_var_counter().get_max_var(*r)); } + + bool is_subsumed(rule const& r) { + setup(r); + m_solver.push(); + m_solver.assert_expr(m_precond); + bool found = find_match(); + m_solver.pop(1); + return found; + } + + private: void setup(rule const& r) { m_preds.reset(); - m_idx1 = 0; expr_ref_vector fmls(m); expr_ref_vector vars(m); expr_ref fml(m); @@ -108,45 +128,56 @@ namespace datalog { fmls.push_back(fml); } m_precond = m.mk_and(fmls.size(), fmls.c_ptr()); - IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "setup-match\n");); } - expr* get_precond() { return m_precond; } // extract pre_cond => post_cond validation obligation from match. - bool next_match(expr_ref& post_cond) { - for (; m_idx1 < m_rules.size(); ++m_idx1) { - if (try_match(post_cond)) { - ++m_idx1; + bool find_match() { + for (unsigned i = 0; i < m_rules.size(); ++i) { + if (match_rule(i)) { return true; } } return false; } - private: // // check that each predicate in r is matched by some predicate in premise. // for now: skip multiple matches within the same rule (incomplete). // - bool try_match(expr_ref& post_cond) { - rule const& r = *m_rules[m_idx1]; - unsigned num_vars = m_num_vars[m_idx1]; + bool match_rule(unsigned rule_index) { + rule const& r = *m_rules[rule_index]; + unsigned num_vars = m_num_vars[rule_index]; m_subst.reset(); m_subst.reserve(2, num_vars); - unsigned deltas[2] = {0, 0}; - expr_ref_vector fmls(m); - expr_ref q(m); - unsigned utsz = r.get_uninterpreted_tail_size(); - unsigned tsz = r.get_tail_size(); // IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "try-match\n");); - for (unsigned i = 0; i < utsz; ++i) { - m_subst.push_scope(); - if (!try_match(r.get_tail(i))) { - return false; - } + return match_predicates(0, r); + } + + bool match_predicates(unsigned predicate_index, rule const& r) { + if (predicate_index == r.get_uninterpreted_tail_size()) { + return check_substitution(r); } + app* p = r.get_tail(predicate_index); + for (unsigned i = 0; i < m_preds.size(); ++i) { + m_subst.push_scope(); + if (m_matcher(p, m_preds[i].get(), m_subst) && + match_predicates(predicate_index + 1, r)) { + return true; + } + m_subst.pop_scope(); + } + return false; + } + + bool check_substitution(rule const& r) { + unsigned utsz = r.get_uninterpreted_tail_size(); + unsigned tsz = r.get_tail_size(); + unsigned deltas[2] = {0, 0}; + expr_ref_vector fmls(m); + expr_ref q(m), postcond(m); + for (unsigned i = utsz; i < tsz; ++i) { app* p = r.get_tail(i); m_subst.apply(2, deltas, expr_offset(p, 0), q); @@ -154,28 +185,23 @@ namespace datalog { } m_qe(m_empty_set, false, fmls); - m_rw.mk_and(fmls.size(), fmls.c_ptr(), post_cond); - if (m.is_false(post_cond)) { + m_rw.mk_and(fmls.size(), fmls.c_ptr(), postcond); + if (m.is_false(postcond)) { return false; } - else { - IF_VERBOSE(1, verbose_stream() << "match: " << mk_pp(post_cond, m) << "\n";); + if (m.is_true(postcond)) { return true; } - } - - bool try_match(expr* q) { - for (unsigned i = 0; i < m_preds.size(); ++i) { - if (m_matcher(q, m_preds[i].get(), m_subst)) { - return true; - } - else { - // undo effect of failed match attempt. - m_subst.pop_scope(); - m_subst.push_scope(); - } + if (!is_ground(postcond)) { + IF_VERBOSE(1, verbose_stream() << "TBD: non-ground\n" << mk_pp(postcond, m) << "\n";); + return false; } - return false; + postcond = m.mk_not(postcond); + m_solver.push(); + m_solver.assert_expr(postcond); + lbool is_sat = m_solver.check(); + m_solver.pop(1); + return is_sat == l_false; } }; @@ -183,7 +209,6 @@ namespace datalog { SELECT_RULE, SELECT_PREDICATE, BACKTRACK, - NEXT_RULE, SATISFIABLE, UNSATISFIABLE, CANCEL @@ -194,7 +219,6 @@ namespace datalog { case SELECT_RULE: return out << "select-rule"; case SELECT_PREDICATE: return out << "select-predicate"; case BACKTRACK: return out << "backtrack"; - case NEXT_RULE: return out << "next-rule"; case SATISFIABLE: return out << "sat"; case UNSATISFIABLE: return out << "unsat"; case CANCEL: return out << "cancel"; @@ -202,6 +226,8 @@ namespace datalog { return out << "unmatched instruction"; } + + class tab::imp { struct stats { stats() { reset(); } @@ -211,6 +237,44 @@ namespace datalog { unsigned m_num_subsume; }; + class goal { + public: + rule_ref m_goal; +// app_ref m_head; +// app_ref_vector m_predicates; +// expr_ref m_constraint; + unsigned m_index; + unsigned m_predicate_index; + unsigned m_rule_index; + + goal(rule_manager& rm): + m_goal(rm), +// m_head(m), +// m_predicates(m), +// m_constraint(m), + m_index(0), + m_predicate_index(0), + m_rule_index(0) { + } + +#if 0 + private: + void init() { + m_head = m_goal.get_head(); + unsigned utsz = m_goal->get_uninterpreted_tail_size(); + unsigned tsz = m_goal->get_tail_size(); + for (unsigned i = 0; i < utsz; ++i) { + m_predicates.push_back(m_goal->get_tail(i)); + } + expr_ref fmls(m); + for (unsigned i = utsz; i < tsz; ++i) { + fmls.push_back(m_goal->get_tail(i)); + } + bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); + } +#endif + }; + context& m_ctx; ast_manager& m; rule_manager& rm; @@ -219,12 +283,10 @@ namespace datalog { smt::kernel m_solver; rule_unifier m_unifier; rule_set m_rules; - trail_stack m_trail; + vector m_goals; + goal m_goal; tab_instruction m_instruction; - rule_ref m_query; - rule_ref_vector m_query_trail; - unsigned m_predicate_index; - unsigned m_rule_index; + unsigned m_goal_index; volatile bool m_cancel; stats m_stats; public: @@ -236,13 +298,10 @@ namespace datalog { m_solver(m, m_fparams), m_unifier(ctx), m_rules(ctx), - m_trail(*this), + m_goal(rm), m_instruction(SELECT_PREDICATE), - m_query(rm), - m_query_trail(rm), - m_predicate_index(0), - m_rule_index(0), - m_cancel(false) + m_cancel(false), + m_goal_index(0) { // m_fparams.m_relevancy_lvl = 0; m_fparams.m_mbqi = false; @@ -256,8 +315,11 @@ namespace datalog { m_rules.reset(); m_rules.add_rules(m_ctx.get_rules()); rule_ref_vector query_rules(rm); + rule_ref goal(rm); func_decl_ref query_pred(m); - rm.mk_query(query, query_pred, query_rules, m_query); + rm.mk_query(query, query_pred, query_rules, goal); + init_goal(goal); + IF_VERBOSE(1, display_goal(m_goal, verbose_stream());); return run(); } @@ -266,8 +328,7 @@ namespace datalog { } void cleanup() { m_cancel = false; - m_trail.reset(); - m_query_trail.reset(); + m_goals.reset(); } void reset_statistics() { m_stats.reset(); @@ -287,86 +348,70 @@ namespace datalog { private: void select_predicate() { - unsigned num_predicates = m_query->get_uninterpreted_tail_size(); + rule_ref& query = m_goal.m_goal; + unsigned num_predicates = query->get_uninterpreted_tail_size(); if (num_predicates == 0) { m_instruction = UNSATISFIABLE; - IF_VERBOSE(1, m_query->display(m_ctx, verbose_stream()); ); + IF_VERBOSE(2, query->display(m_ctx, verbose_stream()); ); } else { m_instruction = SELECT_RULE; - m_predicate_index = 0; // TBD replace by better selection function. - m_rule_index = 0; - IF_VERBOSE(1, verbose_stream() << mk_pp(m_query->get_tail(m_predicate_index), m) << "\n";); + unsigned pi = 0; // TBD replace by better selection function. + m_goal.m_predicate_index = pi; + m_goal.m_rule_index = 0; + IF_VERBOSE(2, verbose_stream() << mk_pp(query->get_tail(pi), m) << "\n";); } } void apply_rule(rule const& r) { - m_rule_index++; - IF_VERBOSE(1, r.display(m_ctx, verbose_stream());); - bool can_unify = m_unifier.unify_rules(*m_query, m_predicate_index, r); - if (can_unify) { + rule_ref& query = m_goal.m_goal; + rule_ref new_query(rm); + if (m_unifier.unify_rules(*query, m_goal.m_predicate_index, r) && + m_unifier.apply(*query, m_goal.m_predicate_index, r, new_query) && + l_false != query_is_sat(*new_query.get()) && + !query_is_subsumed(*new_query.get())) { m_stats.m_num_unfold++; - m_trail.push_scope(); - m_trail.push(value_trail(m_rule_index)); - m_trail.push(value_trail(m_predicate_index)); - rule_ref new_query(rm); - bool is_feasible = m_unifier.apply(*m_query, m_predicate_index, r, new_query); - if (is_feasible) { - TRACE("dl", m_query->display(m_ctx, tout);); - if (l_false == query_is_sat(*new_query.get())) { - m_instruction = BACKTRACK; - } - else if (l_true == query_is_subsumed(*new_query.get())) { - m_instruction = BACKTRACK; - } - else { - m_subsumption_index.insert(m_query.get()); - m_trail.push(restore_rule(m_query_trail, m_query)); - m_query = new_query; - m_instruction = SELECT_PREDICATE; - } - } - else { - m_instruction = BACKTRACK; - } + m_subsumption_index.insert(query.get()); + m_goals.push_back(m_goal); + init_goal(new_query); + IF_VERBOSE(1, + display_premise(m_goals.back(), verbose_stream()); + display_goal(m_goal, verbose_stream());); + m_instruction = SELECT_PREDICATE; } else { m_stats.m_num_no_unfold++; m_instruction = SELECT_RULE; } } + void select_rule() { - func_decl* p = m_query->get_decl(m_predicate_index); + + func_decl* p = m_goal.m_goal->get_decl(m_goal.m_predicate_index); rule_vector const& rules = m_rules.get_predicate_rules(p); - if (rules.size() <= m_rule_index) { + if (rules.size() <= m_goal.m_rule_index) { m_instruction = BACKTRACK; } else { - apply_rule(*rules[m_rule_index]); + apply_rule(*rules[m_goal.m_rule_index++]); } } void backtrack() { - if (m_trail.get_num_scopes() == 0) { + if (m_goals.empty()) { m_instruction = SATISFIABLE; } else { - m_trail.pop_scope(1); + m_goal = m_goals.back(); + m_goals.pop_back(); m_instruction = SELECT_RULE; } } - void next_rule() { - SASSERT(m_trail.get_num_scopes() > 0); - m_trail.pop_scope(1); - m_instruction = SELECT_RULE; - } - lbool run() { m_instruction = SELECT_PREDICATE; while (true) { - IF_VERBOSE(1, verbose_stream() << "run " << m_trail.get_num_scopes() << " " << m_instruction << "\n";); if (m_cancel) { cleanup(); return l_undef; @@ -381,9 +426,6 @@ namespace datalog { case BACKTRACK: backtrack(); break; - case NEXT_RULE: // just use BACTRACK? - next_rule(); - break; case SATISFIABLE: return l_false; case UNSATISFIABLE: @@ -425,27 +467,24 @@ namespace datalog { return is_sat; } - lbool query_is_subsumed(rule const& query) { - lbool is_subsumed = l_false; - m_subsumption_index.setup(query); - expr_ref postcond(m); - while (m_subsumption_index.next_match(postcond)) { - if (is_ground(postcond)) { - postcond = m.mk_not(postcond); - m_solver.push(); - m_solver.assert_expr(m_subsumption_index.get_precond()); - m_solver.assert_expr(postcond); - lbool is_sat = m_solver.check(); - m_solver.pop(1); - if (is_sat == l_false) { - return l_true; - } - } - else { - IF_VERBOSE(1, verbose_stream() << "non-ground: " << mk_pp(postcond, m) << "\n";); - } - } - return is_subsumed; + bool query_is_subsumed(rule const& query) { + return m_subsumption_index.is_subsumed(query); + } + + void init_goal(rule_ref& new_query) { + m_goal.m_goal = new_query; + m_goal.m_index = m_goal_index++; + m_goal.m_predicate_index = 0; + m_goal.m_rule_index = 0; + } + + + void display_premise(goal& p, std::ostream& out) { + out << "[" << p.m_index << "]: " << p.m_predicate_index << ":" << p.m_rule_index << "\n"; + } + void display_goal(goal& g, std::ostream& out) { + out << g.m_index << " "; + g.m_goal->display(m_ctx, out); } }; From 3344151acaad1ab449e770d642829abd9ec69900 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 20 Jan 2013 18:21:09 -0800 Subject: [PATCH 025/101] Replace # with x in the definition of algebraic elements Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index fc46c6d5c..a555486e0 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -5797,7 +5797,7 @@ namespace realclosure { struct display_free_var_proc { void operator()(std::ostream & out, bool compact) const { - out << "#"; + out << "x"; } }; From 5d938a5fe290a9f5643cf781a9fc6179d6e58fe9 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 20 Jan 2013 18:41:24 -0800 Subject: [PATCH 026/101] Fix bug Signed-off-by: Leonardo de Moura --- src/math/realclosure/realclosure.cpp | 68 ++++++++++++++++------------ 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index a555486e0..dac4c8e09 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -4236,45 +4236,53 @@ namespace realclosure { bool refine_algebraic_interval(algebraic * a, unsigned prec) { save_interval_if_too_small(a, prec); if (a->sdt() != 0) { - // we can't bisect the interval, since it contains more than one root. + // We don't bisect the interval, since it contains more than one root. + // To bisect this kind of interval we would have to use Tarski queries. return false; } else { mpbqi & a_i = a->interval(); - SASSERT(!a_i.lower_is_inf() && !a_i.upper_is_inf()); - int lower_sign = INT_MIN; - while (!check_precision(a_i, prec)) { - checkpoint(); - SASSERT(!bqm().eq(a_i.lower(), a_i.upper())); - scoped_mpbq m(bqm()); - bqm().add(a_i.lower(), a_i.upper(), m); - bqm().div2(m); - int mid_sign = eval_sign_at(a->p().size(), a->p().c_ptr(), m); - if (mid_sign == 0) { - // found the actual root - // set interval [m, m] - set_lower(a_i, m, false); - set_upper(a_i, m, false); - return true; - } - else { - SASSERT(mid_sign == 1 || mid_sign == -1); - if (lower_sign == INT_MIN) { - // initialize lower_sign - lower_sign = eval_sign_at(a->p().size(), a->p().c_ptr(), a_i.lower()); - } - SASSERT(lower_sign == 1 || lower_sign == -1); - if (mid_sign == lower_sign) { - // improved lower bound - set_lower(a_i, m); + if (a_i.lower_is_inf() || a_i.upper_is_inf()) { + // we can't bisect the infinite intervals + return false; + } + else { + mpbqi & a_i = a->interval(); + SASSERT(!a_i.lower_is_inf() && !a_i.upper_is_inf()); + int lower_sign = INT_MIN; + while (!check_precision(a_i, prec)) { + checkpoint(); + SASSERT(!bqm().eq(a_i.lower(), a_i.upper())); + scoped_mpbq m(bqm()); + bqm().add(a_i.lower(), a_i.upper(), m); + bqm().div2(m); + int mid_sign = eval_sign_at(a->p().size(), a->p().c_ptr(), m); + if (mid_sign == 0) { + // found the actual root + // set interval [m, m] + set_lower(a_i, m, false); + set_upper(a_i, m, false); + return true; } else { - // improved upper bound - set_upper(a_i, m); + SASSERT(mid_sign == 1 || mid_sign == -1); + if (lower_sign == INT_MIN) { + // initialize lower_sign + lower_sign = eval_sign_at(a->p().size(), a->p().c_ptr(), a_i.lower()); + } + SASSERT(lower_sign == 1 || lower_sign == -1); + if (mid_sign == lower_sign) { + // improved lower bound + set_lower(a_i, m); + } + else { + // improved upper bound + set_upper(a_i, m); + } } } + return true; } - return true; } } From 87e9015675c2e14ca35ad0853e4c8ece6641af21 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 20 Jan 2013 18:41:41 -0800 Subject: [PATCH 027/101] working on tab_context Signed-off-by: Nikolaj Bjorner --- src/ast/substitution/substitution.cpp | 1 + src/muz_qe/qe_lite.cpp | 210 ++++++-- src/muz_qe/tab_context.cpp | 680 +++++++++++++++++++------- 3 files changed, 662 insertions(+), 229 deletions(-) diff --git a/src/ast/substitution/substitution.cpp b/src/ast/substitution/substitution.cpp index 2420a4d3f..82d1fbfef 100644 --- a/src/ast/substitution/substitution.cpp +++ b/src/ast/substitution/substitution.cpp @@ -58,6 +58,7 @@ void substitution::pop_scope(unsigned num_scopes) { } m_vars.shrink(old_sz); m_scopes.shrink(new_lvl); + m_apply_cache.reset(); } inline void substitution::apply_visit(expr_offset const & n, bool & visited) { diff --git a/src/muz_qe/qe_lite.cpp b/src/muz_qe/qe_lite.cpp index 6949c4264..53702700e 100644 --- a/src/muz_qe/qe_lite.cpp +++ b/src/muz_qe/qe_lite.cpp @@ -36,6 +36,7 @@ Revision History: #include "for_each_expr.h" #include "expr_safe_replace.h" #include "cooperate.h" +#include "datatype_decl_plugin.h" class is_variable_proc { public: @@ -80,6 +81,7 @@ namespace eq { class der { ast_manager & m; arith_util a; + datatype_util dt; is_variable_proc* m_is_variable; var_subst m_subst; expr_ref_vector m_new_exprs; @@ -215,14 +217,15 @@ namespace eq { (not T) is used because this formula is equivalent to (not (iff (VAR 2) (not T))), and can be viewed as a disequality. */ - bool is_var_diseq(expr * e, var * & v, expr_ref & t) { + bool is_var_diseq(expr * e, ptr_vector& vs, expr_ref_vector& ts) { expr* e1; if (m.is_not(e, e1)) { - return is_var_eq(e, v, t); + return is_var_eq(e, vs, ts); } - else if (is_var_eq(e, v, t) && m.is_bool(v)) { - bool_rewriter(m).mk_not(t, t); - m_new_exprs.push_back(t); + else if (is_var_eq(e, vs, ts) && vs.size() == 1 && m.is_bool(vs[0])) { + expr_ref tmp(m); + bool_rewriter(m).mk_not(ts[0].get(), tmp); + ts[0] = tmp; return true; } else { @@ -230,11 +233,11 @@ namespace eq { } } - bool solve_arith_core(app * lhs, expr * rhs, expr * eq, var* & var, expr_ref & def) { + bool solve_arith_core(app * lhs, expr * rhs, expr * eq, ptr_vector& vs, expr_ref_vector& ts) { SASSERT(a.is_add(lhs)); bool is_int = a.is_int(lhs); - expr * a1; - expr * v; + expr * a1, *v; + expr_ref def(m); rational a_val; unsigned num = lhs->get_num_args(); unsigned i; @@ -255,7 +258,7 @@ namespace eq { } if (i == num) return false; - var = to_var(v); + vs.push_back(to_var(v)); expr_ref inv_a(m); if (!a_val.is_one()) { inv_a = a.mk_numeral(rational(1)/a_val, is_int); @@ -282,35 +285,48 @@ namespace eq { def = a.mk_sub(rhs, a.mk_add(other_args.size(), other_args.c_ptr())); break; } - m_new_exprs.push_back(def); + ts.push_back(def); return true; } + - bool arith_solve(expr * lhs, expr * rhs, expr * eq, var* & var, expr_ref & t) { + bool arith_solve(expr * lhs, expr * rhs, expr * eq, ptr_vector& vs, expr_ref_vector& ts) { return - (a.is_add(lhs) && solve_arith_core(to_app(lhs), rhs, eq, var, t)) || - (a.is_add(rhs) && solve_arith_core(to_app(rhs), lhs, eq, var, t)); + (a.is_add(lhs) && solve_arith_core(to_app(lhs), rhs, eq, vs, ts)) || + (a.is_add(rhs) && solve_arith_core(to_app(rhs), lhs, eq, vs, ts)); } - bool trival_solve(expr* lhs, expr* rhs, expr* eq, var* & v, expr_ref& t) { + bool trivial_solve(expr* lhs, expr* rhs, expr* eq, ptr_vector& vs, expr_ref_vector& ts) { if (!is_variable(lhs)) { std::swap(lhs, rhs); } if (!is_variable(lhs)) { return false; } - v = to_var(lhs); - t = rhs; - TRACE("der", tout << mk_pp(eq, m) << "\n";); + vs.push_back(to_var(lhs)); + ts.push_back(rhs); + TRACE("qe_lite", tout << mk_pp(eq, m) << "\n";); return true; } + bool same_vars(ptr_vector const& vs1, ptr_vector const& vs2) const { + if (vs1.size() != vs2.size()) { + return false; + } + for (unsigned i = 0; i < vs1.size(); ++i) { + if (vs1[i] != vs2[i]) { + return false; + } + } + return true; + } + /** \brief Return true if e can be viewed as a variable equality. */ - bool is_var_eq(expr * e, var * & v, expr_ref & t) { + bool is_var_eq(expr * e, ptr_vector& vs, expr_ref_vector & ts) { expr* lhs, *rhs; // (= VAR t), (iff VAR t), (iff (not VAR) t), (iff t (not VAR)) cases @@ -323,16 +339,15 @@ namespace eq { if (!is_neg_var(m, lhs)) { return false; } - v = to_var(lhs); - t = m.mk_not(rhs); - m_new_exprs.push_back(t); - TRACE("der", tout << mk_pp(e, m) << "\n";); + vs.push_back(to_var(lhs)); + ts.push_back(m.mk_not(rhs)); + TRACE("qe_lite", tout << mk_pp(e, m) << "\n";); return true; } - if (trival_solve(lhs, rhs, e, v, t)) { + if (trivial_solve(lhs, rhs, e, vs, ts)) { return true; } - if (arith_solve(lhs, rhs, e, v, t)) { + if (arith_solve(lhs, rhs, e, vs, ts)) { return true; } return false; @@ -341,12 +356,13 @@ namespace eq { // (ite cond (= VAR t) (= VAR t2)) case expr* cond, *e2, *e3; if (m.is_ite(e, cond, e2, e3)) { - if (is_var_eq(e2, v, t)) { - expr_ref t2(m); - var* v2; - if (is_var_eq(e3, v2, t2) && v2 == v) { - t = m.mk_ite(cond, t, t2); - m_new_exprs.push_back(t); + if (is_var_eq(e2, vs, ts)) { + expr_ref_vector ts2(m); + ptr_vector vs2; + if (is_var_eq(e3, vs2, ts2) && same_vars(vs, vs2)) { + for (unsigned i = 0; i < vs.size(); ++i) { + ts[i] = m.mk_ite(cond, ts[i].get(), ts2[i].get()); + } return true; } } @@ -355,17 +371,17 @@ namespace eq { // VAR = true case if (is_variable(e)) { - t = m.mk_true(); - v = to_var(e); - TRACE("der", tout << mk_pp(e, m) << "\n";); + ts.push_back(m.mk_true()); + vs.push_back(to_var(e)); + TRACE("qe_lite", tout << mk_pp(e, m) << "\n";); return true; } // VAR = false case if (is_neg_var(m, e)) { - t = m.mk_false(); - v = to_var(to_app(e)->get_arg(0)); - TRACE("der", tout << mk_pp(e, m) << "\n";); + ts.push_back(m.mk_false()); + vs.push_back(to_var(to_app(e)->get_arg(0))); + TRACE("qe_lite", tout << mk_pp(e, m) << "\n";); return true; } @@ -373,12 +389,12 @@ namespace eq { } - bool is_var_def(bool check_eq, expr* e, var*& v, expr_ref& t) { + bool is_var_def(bool check_eq, expr* e, ptr_vector& vs, expr_ref_vector& ts) { if (check_eq) { - return is_var_eq(e, v, t); + return is_var_eq(e, vs, ts); } else { - return is_var_diseq(e, v, t); + return is_var_diseq(e, vs, ts); } } @@ -393,7 +409,7 @@ namespace eq { der_sort_vars(m_inx2var, m_map, m_order); - TRACE("der", + TRACE("qe_lite", tout << "Elimination m_order:" << std::endl; for(unsigned i=0; iget_idx(); - if(m_map.get(idx, 0) == 0) { - m_map.reserve(idx + 1, 0); - m_inx2var.reserve(idx + 1, 0); - m_map[idx] = t; - m_inx2var[idx] = v; - m_pos2var[i] = idx; - def_count++; - largest_vinx = std::max(idx, largest_vinx); + ptr_vector vs; + expr_ref_vector ts(m); + if (is_var_def(is_exists, args[i], vs, ts)) { + for (unsigned j = 0; j < vs.size(); ++j) { + var* v = vs[j]; + expr* t = ts[j].get(); + unsigned idx = v->get_idx(); + if (m_map.get(idx, 0) == 0) { + m_map.reserve(idx + 1, 0); + m_inx2var.reserve(idx + 1, 0); + m_map[idx] = t; + m_inx2var[idx] = v; + m_pos2var[i] = idx; + def_count++; + largest_vinx = std::max(idx, largest_vinx); + m_new_exprs.push_back(t); + } } } } } + + void flatten_definitions(expr_ref_vector& conjs) { + TRACE("qe_lite", + expr_ref tmp(m); + tmp = m.mk_and(conjs.size(), conjs.c_ptr()); + tout << mk_pp(tmp, m) << "\n";); + for (unsigned i = 0; i < conjs.size(); ++i) { + expr* c = conjs[i].get(); + expr* l, *r; + if (m.is_false(c)) { + conjs[0] = c; + conjs.resize(1); + break; + } + if (is_ground(c)) { + continue; + } + if (!m.is_eq(c, l, r)) { + continue; + } + if (!is_app(l) || !is_app(r)) { + continue; + } + if (dt.is_constructor(to_app(l)->get_decl())) { + flatten_constructor(to_app(l), to_app(r), conjs); + conjs[i] = conjs.back(); + conjs.pop_back(); + --i; + continue; + } + if (dt.is_constructor(to_app(r)->get_decl())) { + flatten_constructor(to_app(r), to_app(l), conjs); + conjs[i] = conjs.back(); + conjs.pop_back(); + --i; + continue; + } + } + TRACE("qe_lite", + expr_ref tmp(m); + tmp = m.mk_and(conjs.size(), conjs.c_ptr()); + tout << "after flatten\n" << mk_pp(tmp, m) << "\n";); + } + + void flatten_constructor(app* c, app* r, expr_ref_vector& conjs) { + SASSERT(dt.is_constructor(c)); + + func_decl* d = c->get_decl(); + + if (dt.is_constructor(r->get_decl())) { + app* b = to_app(r); + if (d == b->get_decl()) { + for (unsigned j = 0; j < c->get_num_args(); ++j) { + conjs.push_back(m.mk_eq(c->get_arg(j), b->get_arg(j))); + } + } + else { + conjs.push_back(m.mk_false()); + } + } + else { + func_decl* rec = dt.get_constructor_recognizer(d); + conjs.push_back(m.mk_app(rec, r)); + ptr_vector const& acc = *dt.get_constructor_accessors(d); + for (unsigned i = 0; i < acc.size(); ++i) { + conjs.push_back(m.mk_eq(c->get_arg(i), m.mk_app(acc[i], r))); + } + } + } bool reduce_var_set(expr_ref_vector& conjs) { unsigned def_count = 0; unsigned largest_vinx = 0; + + flatten_definitions(conjs); find_definitions(conjs.size(), conjs.c_ptr(), true, def_count, largest_vinx); @@ -578,12 +670,22 @@ namespace eq { } public: - der(ast_manager & m): m(m), a(m), m_is_variable(0), m_subst(m), m_new_exprs(m), m_subst_map(m), m_new_args(m), m_rewriter(m), m_cancel(false) {} + der(ast_manager & m): + m(m), + a(m), + dt(m), + m_is_variable(0), + m_subst(m), + m_new_exprs(m), + m_subst_map(m), + m_new_args(m), + m_rewriter(m), + m_cancel(false) {} void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;} void operator()(quantifier * q, expr_ref & r, proof_ref & pr) { - TRACE("der", tout << mk_pp(q, m) << "\n";); + TRACE("qe_lite", tout << mk_pp(q, m) << "\n";); pr = 0; r = q; reduce_quantifier(q, r, pr); diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index 0eb9331d2..f4efe78f0 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -23,93 +23,324 @@ Revision History: #include "dl_context.h" #include "dl_mk_rule_inliner.h" #include "smt_kernel.h" -#include "matcher.h" #include "qe_lite.h" #include "bool_rewriter.h" +#include "th_rewriter.h" +#include "datatype_decl_plugin.h" -namespace datalog { +namespace tb { -#if 0 // semantic matcher. - class tab_matcher { + class matcher { typedef std::pair expr_pair; + ast_manager& m; svector m_todo; + datatype_util m_dt; + + lbool is_eq(expr* _s, expr* _t) { + if (_s == _t) { + return l_true; + } + if (!is_app(_s) || !is_app(_t)) { + return l_undef; + } + app* s = to_app(_s); + app* t = to_app(_t); + + if (m.is_value(s) && m.is_value(t)) { + IF_VERBOSE(2, verbose_stream() << "different:" << mk_pp(s, m) << " " << mk_pp(t, m) << "\n";); + return l_false; + } + + if (m_dt.is_constructor(s) && m_dt.is_constructor(t)) { + if (s->get_decl() == t->get_decl()) { + lbool state = l_true; + for (unsigned i = 0; i < s->get_num_args(); ++i) { + // move is_eq: decompose arguments to constraints. + switch (is_eq(s->get_arg(i), t->get_arg(i))) { + case l_undef: + state = l_undef; + break; + case l_false: + return l_false; + default: + break; + } + } + return state; + } + else { + IF_VERBOSE(2, verbose_stream() << "different constructors:" << mk_pp(s, m) << " " << mk_pp(t, m) << "\n";); + return l_false; + } + } + return l_undef; + } + + bool match_var(var* v, app* t, substitution& s, expr_ref_vector& conds) { + expr_offset r; + if (s.find(v, 0, r)) { + app* p = to_app(r.get_expr()); + switch (is_eq(p, t)) { + case l_true: + break; + case l_false: + return false; + default: + conds.push_back(m.mk_eq(p, t)); + break; + } + } + else { + s.insert(v, 0, expr_offset(t, 1)); + } + return true; + } + + bool match_app(app* p, app* t, substitution& s, expr_ref_vector& conds) { + if (p->get_decl() == t->get_decl() && + p->get_num_args() == t->get_num_args()) { + for (unsigned i = 0; i < p->get_num_args(); ++i) { + m_todo.push_back(expr_pair(p->get_arg(i), t->get_arg(i))); + } + return true; + } + else { + switch(is_eq(p, t)) { + case l_true: + return true; + case l_false: + return false; + default: + conds.push_back(m.mk_eq(p, t)); + return true; + } + } + } + public: - matcher(ast_manager& m): m(m) {} + matcher(ast_manager& m): m(m), m_dt(m) {} - bool operator()(expr* pat, expr* term, substitution& s, expr_ref_vector& side_conds) { + bool operator()(expr* pat, expr* term, substitution& s, expr_ref_vector& conds) { m_todo.reset(); m_todo.push_back(expr_pair(pat, term)); while (!m_todo.empty()) { expr_pair const& p = m_todo.back(); - pat = p.first; + pat = p.first; term = p.second; - if (is_var(pat)) { - + m_todo.pop_back(); + if (!is_app(term)) { + IF_VERBOSE(2, verbose_stream() << "term is not app\n";); + return false; + } + else if (is_var(pat) && match_var(to_var(pat), to_app(term), s, conds)) { + continue; + } + else if (!is_app(pat)) { + IF_VERBOSE(2, verbose_stream() << "pattern is not app\n";); + return false; + } + else if (!match_app(to_app(pat), to_app(term), s, conds)) { + return false; } } + return true; } }; -#endif + + class goal { + th_rewriter m_rw; + datalog::rule_ref m_goal; + app_ref m_head; + app_ref_vector m_predicates; + expr_ref m_constraint; + unsigned m_index; + unsigned m_num_vars; + unsigned m_predicate_index; + unsigned m_rule_index; + unsigned m_ref; + + public: + + goal(datalog::rule_manager& rm): + m_rw(rm.get_manager()), + m_goal(rm), + m_head(rm.get_manager()), + m_predicates(rm.get_manager()), + m_constraint(rm.get_manager()), + m_index(0), + m_num_vars(0), + m_predicate_index(0), + m_rule_index(0), + m_ref(0) { + } + + void set_rule_index(unsigned i) { m_rule_index = i; } + unsigned get_rule_index() const { return m_rule_index; } + void inc_rule_index() { m_rule_index++; } + unsigned get_predicate_index() const { return m_predicate_index; } + void set_predicate_index(unsigned i) { m_predicate_index = i; } + unsigned get_num_predicates() const { return m_predicates.size(); } + app* get_predicate(unsigned i) const { return m_predicates[i]; } + expr* get_constraint() const { return m_constraint; } + datalog::rule const& get_rule() const { return *m_goal; } + unsigned get_num_vars() const { return m_num_vars; } + unsigned get_index() const { return m_index; } + app* get_head() const { return m_head; } + + void init(datalog::rule_ref& g) { + m_goal = g; + m_index = 0; + m_predicate_index = 0; + m_rule_index = 0; + m_num_vars = 1 + g.get_manager().get_var_counter().get_max_var(*g); + init(); + + // IF_VERBOSE(1, display(verbose_stream());); + } + + void set_index(unsigned index) { + m_index = index; + } + + void inc_ref() { + m_ref++; + } + + void dec_ref() { + --m_ref; + if (m_ref == 0) { + dealloc(this); + } + } + + void display(std::ostream& out) const { + ast_manager& m = m_head.get_manager(); + expr_ref_vector fmls(m); + expr_ref fml(m); + for (unsigned i = 0; i < m_predicates.size(); ++i) { + fmls.push_back(m_predicates[i]); + } + fmls.push_back(m_constraint); + bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), fml); + out << mk_pp(fml, m) << "\n"; + } + + private: + // x = t[y], if x does not occur in t[y], then add t[y] to subst. + + void init() { + m_predicates.reset(); + ast_manager& m = m_head.get_manager(); + unsigned delta[1] = { 0 }; + datalog::rule_manager& rm = m_goal.m(); + unsigned num_vars = rm.get_var_counter().get_max_var(*m_goal); + substitution subst(m); + subst.reserve(1, num_vars+1); + expr_ref_vector fmls(m); + expr_ref tmp(m); + unsigned utsz = m_goal->get_uninterpreted_tail_size(); + unsigned tsz = m_goal->get_tail_size(); + for (unsigned i = utsz; i < tsz; ++i) { + fmls.push_back(m_goal->get_tail(i)); + } + datalog::flatten_and(fmls); + for (unsigned i = 0; i < fmls.size(); ++i) { + expr* e = fmls[i].get(); + expr* t, *v; + if ((m.is_eq(e, v, t) && is_var(v) && !subst.contains(to_var(v), 0)) || + (m.is_eq(e, t, v) && is_var(v) && !subst.contains(to_var(v), 0))) { + subst.push_scope(); + subst.insert(to_var(v)->get_idx(), 0, expr_offset(t, 0)); + if (!subst.acyclic()) { + subst.pop_scope(); + } + } + } + bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); + subst.apply(1, delta, expr_offset(m_constraint, 0), m_constraint); + subst.apply(1, delta, expr_offset(m_goal->get_head(), 0), tmp); + m_head = to_app(tmp); + m_rw(m_constraint); + for (unsigned i = 0; i < utsz; ++i) { + subst.apply(1, delta, expr_offset(m_goal->get_tail(i), 0), tmp); + m_predicates.push_back(to_app(tmp)); + } + } + }; // subsumption index structure. - class tab_index { - ast_manager& m; - rule_manager& rm; - context& m_ctx; - app_ref_vector m_preds; - expr_ref m_precond; - rule_ref_vector m_rules; - svector m_num_vars; - matcher m_matcher; - substitution m_subst; - qe_lite m_qe; - uint_set m_empty_set; - bool_rewriter m_rw; - smt_params m_fparams; - smt::kernel m_solver; + class index { + ast_manager& m; + datalog::rule_manager& rm; + datalog::context& m_ctx; + app_ref_vector m_preds; + expr_ref m_precond; + expr_ref_vector m_sideconds; + vector > m_index; + matcher m_matcher; + substitution m_subst; + qe_lite m_qe; + uint_set m_empty_set; + bool_rewriter m_rw; + smt_params m_fparams; + smt::kernel m_solver; + volatile bool m_cancel; public: - tab_index(ast_manager& m, rule_manager& rm, context& ctx): - m(m), - rm(rm), + index(datalog::context& ctx): + m(ctx.get_manager()), + rm(ctx.get_rule_manager()), m_ctx(ctx), m_preds(m), m_precond(m), - m_rules(rm), + m_sideconds(m), m_matcher(m), m_subst(m), m_qe(m), m_rw(m), - m_solver(m, m_fparams) {} + m_solver(m, m_fparams), + m_cancel(false) {} - void insert(rule* r) { - m_rules.push_back(r); - m_num_vars.push_back(1+rm.get_var_counter().get_max_var(*r)); + void insert(ref& g) { + m_index.push_back(g); } - bool is_subsumed(rule const& r) { - setup(r); + bool is_subsumed(goal const& g, unsigned& subsumer) { + setup(g); m_solver.push(); m_solver.assert_expr(m_precond); - bool found = find_match(); + bool found = find_match(subsumer); m_solver.pop(1); return found; } + void cancel() { + m_cancel = true; + m_solver.cancel(); + m_qe.set_cancel(true); + } + + void cleanup() { + m_solver.reset_cancel(); + m_qe.set_cancel(false); + m_cancel = false; + } + private: - void setup(rule const& r) { + void setup(goal const& g) { m_preds.reset(); expr_ref_vector fmls(m); expr_ref_vector vars(m); expr_ref fml(m); ptr_vector sorts; - r.get_vars(sorts); - unsigned utsz = r.get_uninterpreted_tail_size(); - unsigned tsz = r.get_tail_size(); + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + get_free_vars(g.get_predicate(i), sorts); + } + get_free_vars(g.get_constraint(), sorts); var_subst vs(m, false); for (unsigned i = 0; i < sorts.size(); ++i) { if (!sorts[i]) { @@ -117,24 +348,27 @@ namespace datalog { } vars.push_back(m.mk_const(symbol(i), sorts[i])); } - for (unsigned i = 0; i < utsz; ++i) { - fml = r.get_tail(i); - vs(fml, vars.size(), vars.c_ptr(), fml); + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + vs(g.get_predicate(i), vars.size(), vars.c_ptr(), fml); m_preds.push_back(to_app(fml)); } - for (unsigned i = utsz; i < tsz; ++i) { - fml = r.get_tail(i); - vs(fml, vars.size(), vars.c_ptr(), fml); - fmls.push_back(fml); - } + vs(g.get_constraint(), vars.size(), vars.c_ptr(), fml); + fmls.push_back(fml); m_precond = m.mk_and(fmls.size(), fmls.c_ptr()); + IF_VERBOSE(2, + verbose_stream() << "setup-match: "; + for (unsigned i = 0; i < m_preds.size(); ++i) { + verbose_stream() << mk_pp(m_preds[i].get(), m) << " "; + } + verbose_stream() << mk_pp(m_precond, m) << "\n";); } // extract pre_cond => post_cond validation obligation from match. - bool find_match() { - for (unsigned i = 0; i < m_rules.size(); ++i) { + bool find_match(unsigned& subsumer) { + for (unsigned i = 0; !m_cancel && i < m_index.size(); ++i) { if (match_rule(i)) { + subsumer = m_index[i]->get_index(); return true; } } @@ -145,44 +379,62 @@ namespace datalog { // for now: skip multiple matches within the same rule (incomplete). // bool match_rule(unsigned rule_index) { - rule const& r = *m_rules[rule_index]; - unsigned num_vars = m_num_vars[rule_index]; + goal const& g = *m_index[rule_index]; m_subst.reset(); - m_subst.reserve(2, num_vars); + m_subst.reserve(2, g.get_num_vars()); - // IF_VERBOSE(1, r.display(m_ctx, verbose_stream() << "try-match\n");); + IF_VERBOSE(2, g.display(verbose_stream() << "try-match\n");); - return match_predicates(0, r); + return match_predicates(0, g); } - bool match_predicates(unsigned predicate_index, rule const& r) { - if (predicate_index == r.get_uninterpreted_tail_size()) { - return check_substitution(r); + + bool match_predicates(unsigned predicate_index, goal const& g) { + if (predicate_index == g.get_num_predicates()) { + return check_substitution(g); } - app* p = r.get_tail(predicate_index); - for (unsigned i = 0; i < m_preds.size(); ++i) { + + app* q = g.get_predicate(predicate_index); + + for (unsigned i = 0; !m_cancel && i < m_preds.size(); ++i) { + app* p = m_preds[i].get(); m_subst.push_scope(); - if (m_matcher(p, m_preds[i].get(), m_subst) && - match_predicates(predicate_index + 1, r)) { + unsigned limit = m_sideconds.size(); + IF_VERBOSE(2, + for (unsigned j = 0; j < predicate_index; ++j) verbose_stream() << " "; + verbose_stream() << mk_pp(q, m) << " = " << mk_pp(p, m) << "\n"; + ); + + + if (q->get_decl() == p->get_decl() && + m_matcher(q, p, m_subst, m_sideconds) && + match_predicates(predicate_index + 1, g)) { return true; } - m_subst.pop_scope(); + m_subst.pop_scope(1); + m_sideconds.resize(limit); } return false; } - bool check_substitution(rule const& r) { - unsigned utsz = r.get_uninterpreted_tail_size(); - unsigned tsz = r.get_tail_size(); + bool check_substitution(goal const& g) { unsigned deltas[2] = {0, 0}; - expr_ref_vector fmls(m); expr_ref q(m), postcond(m); + expr_ref_vector fmls(m_sideconds); - for (unsigned i = utsz; i < tsz; ++i) { - app* p = r.get_tail(i); - m_subst.apply(2, deltas, expr_offset(p, 0), q); - fmls.push_back(q); + for (unsigned i = 0; i < fmls.size(); ++i) { + m_subst.apply(2, deltas, expr_offset(fmls[i].get(), 0), q); + fmls[i] = q; } + m_subst.apply(2, deltas, expr_offset(g.get_constraint(), 0), q); + fmls.push_back(q); + + IF_VERBOSE(2, + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + verbose_stream() << " "; + } + q = m.mk_and(fmls.size(), fmls.c_ptr()); + verbose_stream() << "check: " << mk_pp(q, m) << "\n";); m_qe(m_empty_set, false, fmls); m_rw.mk_and(fmls.size(), fmls.c_ptr(), postcond); @@ -205,7 +457,107 @@ namespace datalog { } }; - enum tab_instruction { + // predicate selection strategy. + class selection { + datalog::context& m_ctx; + ast_manager& m; + datalog::rule_manager& rm; + datatype_util dt; + obj_map m_scores; + unsigned_vector m_score_values; + + + public: + selection(datalog::context& ctx): + m_ctx(ctx), + m(ctx.get_manager()), + rm(ctx.get_rule_manager()), + dt(m) { + } + + void init(datalog::rule_set const& rules) { + m_scores.reset(); + goal g(rm); + datalog::rule_ref r(rm); + datalog::rule_set::iterator it = rules.begin(); + datalog::rule_set::iterator end = rules.end(); + for (; it != end; ++it) { + r = *it; + g.init(r); + app* p = g.get_head(); + unsigned_vector scores; + score_predicate(p, scores); + insert_score(p->get_decl(), scores); + } + } + + unsigned select(goal const& g) { + unsigned min_distance = UINT_MAX; + unsigned result = 0; + unsigned_vector& scores = m_score_values; + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + scores.reset(); + score_predicate(g.get_predicate(i), scores); + unsigned dist = compute_distance(g.get_predicate(i)->get_decl(), scores); + if (dist < min_distance) { + min_distance = dist; + result = i; + } + } + return result; + } + + private: + + unsigned compute_distance(func_decl* f, unsigned_vector const& scores) { + unsigned_vector f_scores; + unsigned dist = 0; + if (m_scores.find(f, f_scores)) { + SASSERT(f_scores.size() == scores.size()); + for (unsigned i = 0; i < scores.size(); ++i) { + unsigned d1 = scores[i] - f_scores[i]; + dist += d1*d1; + } + } + // else there is no rule. + return dist; + } + + void score_predicate(app* p, unsigned_vector& scores) { + for (unsigned i = 0; i < p->get_num_args(); ++i) { + scores.push_back(score_argument(p->get_arg(i))); + } + } + + unsigned score_argument(expr* arg) { + if (is_var(arg)) { + return 0; + } + if (m.is_value(arg)) { + return 3; + } + if (is_app(arg) && dt.is_constructor(to_app(arg)->get_decl())) { + return 2; + } + return 1; + } + + void insert_score(func_decl* f, unsigned_vector const& scores) { + obj_map::obj_map_entry* e = m_scores.find_core(f); + if (e) { + unsigned_vector & old_scores = e->get_data().m_value; + SASSERT(scores.size() == old_scores.size()); + for (unsigned i = 0; i < scores.size(); ++i) { + old_scores[i] += scores[i]; + } + } + else { + m_scores.insert(f, scores); + } + } + }; + + enum instruction { SELECT_RULE, SELECT_PREDICATE, BACKTRACK, @@ -214,7 +566,7 @@ namespace datalog { CANCEL }; - std::ostream& operator<<(std::ostream& out, tab_instruction i) { + std::ostream& operator<<(std::ostream& out, instruction i) { switch(i) { case SELECT_RULE: return out << "select-rule"; case SELECT_PREDICATE: return out << "select-predicate"; @@ -225,8 +577,9 @@ namespace datalog { } return out << "unmatched instruction"; } +}; - +namespace datalog { class tab::imp { struct stats { @@ -234,58 +587,20 @@ namespace datalog { void reset() { memset(this, 0, sizeof(*this)); } unsigned m_num_unfold; unsigned m_num_no_unfold; - unsigned m_num_subsume; + unsigned m_num_subsumed; }; - class goal { - public: - rule_ref m_goal; -// app_ref m_head; -// app_ref_vector m_predicates; -// expr_ref m_constraint; - unsigned m_index; - unsigned m_predicate_index; - unsigned m_rule_index; - - goal(rule_manager& rm): - m_goal(rm), -// m_head(m), -// m_predicates(m), -// m_constraint(m), - m_index(0), - m_predicate_index(0), - m_rule_index(0) { - } - -#if 0 - private: - void init() { - m_head = m_goal.get_head(); - unsigned utsz = m_goal->get_uninterpreted_tail_size(); - unsigned tsz = m_goal->get_tail_size(); - for (unsigned i = 0; i < utsz; ++i) { - m_predicates.push_back(m_goal->get_tail(i)); - } - expr_ref fmls(m); - for (unsigned i = utsz; i < tsz; ++i) { - fmls.push_back(m_goal->get_tail(i)); - } - bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); - } -#endif - }; - context& m_ctx; ast_manager& m; rule_manager& rm; - tab_index m_subsumption_index; + tb::index m_index; + tb::selection m_selection; smt_params m_fparams; smt::kernel m_solver; rule_unifier m_unifier; rule_set m_rules; - vector m_goals; - goal m_goal; - tab_instruction m_instruction; + vector > m_goals; + tb::instruction m_instruction; unsigned m_goal_index; volatile bool m_cancel; stats m_stats; @@ -294,12 +609,12 @@ namespace datalog { m_ctx(ctx), m(ctx.get_manager()), rm(ctx.get_rule_manager()), - m_subsumption_index(m, rm, ctx), + m_index(ctx), + m_selection(ctx), m_solver(m, m_fparams), m_unifier(ctx), m_rules(ctx), - m_goal(rm), - m_instruction(SELECT_PREDICATE), + m_instruction(tb::SELECT_PREDICATE), m_cancel(false), m_goal_index(0) { @@ -314,21 +629,27 @@ namespace datalog { m_ctx.ensure_opened(); m_rules.reset(); m_rules.add_rules(m_ctx.get_rules()); + m_selection.init(m_rules); rule_ref_vector query_rules(rm); rule_ref goal(rm); func_decl_ref query_pred(m); rm.mk_query(query, query_pred, query_rules, goal); init_goal(goal); - IF_VERBOSE(1, display_goal(m_goal, verbose_stream());); + IF_VERBOSE(1, display_goal(*get_goal(), verbose_stream() << "g" << get_goal()->get_index() << " ");); return run(); } void cancel() { m_cancel = true; + m_index.cleanup(); + m_solver.cancel(); } + void cleanup() { m_cancel = false; m_goals.reset(); + m_index.cleanup(); + m_solver.reset_cancel(); } void reset_statistics() { m_stats.reset(); @@ -336,7 +657,7 @@ namespace datalog { void collect_statistics(statistics& st) const { st.update("tab.num_unfold", m_stats.m_num_unfold); st.update("tab.num_unfold_fail", m_stats.m_num_no_unfold); - st.update("tab.num_subsume", m_stats.m_num_subsume); + st.update("tab.num_subsumed", m_stats.m_num_subsumed); } void display_certificate(std::ostream& out) const { // TBD @@ -348,90 +669,100 @@ namespace datalog { private: void select_predicate() { - rule_ref& query = m_goal.m_goal; - unsigned num_predicates = query->get_uninterpreted_tail_size(); + unsigned num_predicates = get_goal()->get_num_predicates(); if (num_predicates == 0) { - m_instruction = UNSATISFIABLE; - IF_VERBOSE(2, query->display(m_ctx, verbose_stream()); ); + m_instruction = tb::UNSATISFIABLE; + IF_VERBOSE(2, get_goal()->display(verbose_stream()); ); } else { - m_instruction = SELECT_RULE; - unsigned pi = 0; // TBD replace by better selection function. - m_goal.m_predicate_index = pi; - m_goal.m_rule_index = 0; - IF_VERBOSE(2, verbose_stream() << mk_pp(query->get_tail(pi), m) << "\n";); + m_instruction = tb::SELECT_RULE; + unsigned pi = m_selection.select(*get_goal()); + get_goal()->set_predicate_index(pi); + get_goal()->set_rule_index(0); + IF_VERBOSE(2, verbose_stream() << mk_pp(get_goal()->get_predicate(pi), m) << "\n";); } } void apply_rule(rule const& r) { - rule_ref& query = m_goal.m_goal; + ref goal = get_goal(); + rule const& query = goal->get_rule(); rule_ref new_query(rm); - if (m_unifier.unify_rules(*query, m_goal.m_predicate_index, r) && - m_unifier.apply(*query, m_goal.m_predicate_index, r, new_query) && - l_false != query_is_sat(*new_query.get()) && - !query_is_subsumed(*new_query.get())) { - m_stats.m_num_unfold++; - m_subsumption_index.insert(query.get()); - m_goals.push_back(m_goal); - init_goal(new_query); + if (m_unifier.unify_rules(query, goal->get_predicate_index(), r) && + m_unifier.apply(query, goal->get_predicate_index(), r, new_query) && + l_false != query_is_sat(*new_query.get())) { + ref next_goal = init_goal(new_query); + unsigned subsumer = 0; IF_VERBOSE(1, - display_premise(m_goals.back(), verbose_stream()); - display_goal(m_goal, verbose_stream());); - m_instruction = SELECT_PREDICATE; + display_premise(*goal, verbose_stream() << "g" << next_goal->get_index() << " "); + display_goal(*next_goal, verbose_stream());); + if (m_index.is_subsumed(*next_goal, subsumer)) { + IF_VERBOSE(1, verbose_stream() << "subsumed by " << subsumer << "\n";); + m_stats.m_num_subsumed++; + m_goals.pop_back(); + m_instruction = tb::SELECT_RULE; + } + else { + m_stats.m_num_unfold++; + m_index.insert(next_goal); + m_instruction = tb::SELECT_PREDICATE; + } } else { m_stats.m_num_no_unfold++; - m_instruction = SELECT_RULE; + m_instruction = tb::SELECT_RULE; } } void select_rule() { - func_decl* p = m_goal.m_goal->get_decl(m_goal.m_predicate_index); + func_decl* p = get_goal()->get_predicate(get_goal()->get_predicate_index())->get_decl(); rule_vector const& rules = m_rules.get_predicate_rules(p); - if (rules.size() <= m_goal.m_rule_index) { - m_instruction = BACKTRACK; + if (rules.size() <= get_goal()->get_rule_index()) { + m_instruction = tb::BACKTRACK; } else { - apply_rule(*rules[m_goal.m_rule_index++]); + unsigned index = get_goal()->get_rule_index(); + get_goal()->inc_rule_index(); + apply_rule(*rules[index]); } } void backtrack() { + SASSERT(!m_goals.empty()); + m_goals.pop_back(); if (m_goals.empty()) { - m_instruction = SATISFIABLE; + m_instruction = tb::SATISFIABLE; } else { - m_goal = m_goals.back(); - m_goals.pop_back(); - m_instruction = SELECT_RULE; + m_instruction = tb::SELECT_RULE; } } lbool run() { - m_instruction = SELECT_PREDICATE; + m_instruction = tb::SELECT_PREDICATE; while (true) { + IF_VERBOSE(2, verbose_stream() << m_instruction << "\n";); if (m_cancel) { cleanup(); return l_undef; } switch(m_instruction) { - case SELECT_PREDICATE: + case tb::SELECT_PREDICATE: select_predicate(); break; - case SELECT_RULE: + case tb::SELECT_RULE: select_rule(); break; - case BACKTRACK: + case tb::BACKTRACK: backtrack(); break; - case SATISFIABLE: + case tb::SATISFIABLE: return l_false; - case UNSATISFIABLE: + case tb::UNSATISFIABLE: return l_true; - case CANCEL: - m_cancel = false; + case tb::CANCEL: + cleanup(); return l_undef; } } @@ -456,7 +787,9 @@ namespace datalog { names.push_back(symbol(i)); } fml = m.mk_and(fmls.size(), fmls.c_ptr()); - fml = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), fml); + if (!sorts.empty()) { + fml = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), fml); + } m_solver.push(); m_solver.assert_expr(fml); lbool is_sat = m_solver.check(); @@ -467,24 +800,21 @@ namespace datalog { return is_sat; } - bool query_is_subsumed(rule const& query) { - return m_subsumption_index.is_subsumed(query); + ref init_goal(rule_ref& new_query) { + ref goal = alloc(tb::goal, rm); + goal->init(new_query); + goal->set_index(m_goal_index++); + m_goals.push_back(goal); + return goal; } - void init_goal(rule_ref& new_query) { - m_goal.m_goal = new_query; - m_goal.m_index = m_goal_index++; - m_goal.m_predicate_index = 0; - m_goal.m_rule_index = 0; - } + ref get_goal() const { return m_goals.back(); } - - void display_premise(goal& p, std::ostream& out) { - out << "[" << p.m_index << "]: " << p.m_predicate_index << ":" << p.m_rule_index << "\n"; + void display_premise(tb::goal& p, std::ostream& out) { + out << "{g" << p.get_index() << " p" << p.get_predicate_index() << " r" << p.get_rule_index() << "}\n"; } - void display_goal(goal& g, std::ostream& out) { - out << g.m_index << " "; - g.m_goal->display(m_ctx, out); + void display_goal(tb::goal& g, std::ostream& out) { + g.display(out); } }; From b9cc7080e7c7a34c368683d0ff3775b6a9ca04d6 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 21 Jan 2013 21:47:43 -0800 Subject: [PATCH 028/101] update substitution routines Signed-off-by: Nikolaj Bjorner --- scripts/mk_project.py | 2 +- src/ast/substitution/substitution.cpp | 66 +++++++++++++++++++++++---- src/ast/substitution/substitution.h | 23 +++++++++- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/scripts/mk_project.py b/scripts/mk_project.py index d11c5fd30..6ea794040 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -22,7 +22,7 @@ def init_project_def(): add_lib('normal_forms', ['rewriter'], 'ast/normal_forms') add_lib('model', ['rewriter']) add_lib('tactic', ['ast', 'model']) - add_lib('substitution', ['ast'], 'ast/substitution') + add_lib('substitution', ['ast', 'rewriter'], 'ast/substitution') add_lib('parser_util', ['ast'], 'parsers/util') add_lib('grobner', ['ast'], 'math/grobner') add_lib('euclid', ['util'], 'math/euclid') diff --git a/src/ast/substitution/substitution.cpp b/src/ast/substitution/substitution.cpp index 82d1fbfef..2427c9c25 100644 --- a/src/ast/substitution/substitution.cpp +++ b/src/ast/substitution/substitution.cpp @@ -20,22 +20,23 @@ Revision History: #include"substitution.h" #include"ast_pp.h" #include"ast_ll_pp.h" +#include"rewriter.h" substitution::substitution(ast_manager & m): m_manager(m), - m_new_exprs(m) { + m_refs(m), + m_new_exprs(m), + m_state(CLEAN) { } void substitution::reset() { - reset_subst(); + m_subst.reset(); + m_vars.reset(); + m_refs.reset(); + m_scopes.reset(); reset_cache(); } -void substitution::reset_subst() { - m_subst.reset(); - m_vars.reset(); - m_scopes.reset(); -} void substitution::reset_cache() { TRACE("subst_bug", tout << "substitution::reset_cache\n"; @@ -43,6 +44,7 @@ void substitution::reset_cache() { m_apply_cache.reset(); m_new_exprs.reset(); + m_state = CLEAN; } void substitution::pop_scope(unsigned num_scopes) { @@ -57,8 +59,9 @@ void substitution::pop_scope(unsigned num_scopes) { m_subst.erase(curr.first, curr.second); } m_vars.shrink(old_sz); + m_refs.shrink(old_sz); m_scopes.shrink(new_lvl); - m_apply_cache.reset(); + reset_cache(); } inline void substitution::apply_visit(expr_offset const & n, bool & visited) { @@ -73,11 +76,14 @@ void substitution::apply(unsigned num_actual_offsets, unsigned const * deltas, e TRACE("subst_bug", tout << "BEGIN substitution::apply\n";); + // It is incorrect to cache results between different calls if we are applying a substitution // modulo a substitution s -> t. - if (s != expr_offset(0,0)) + if (m_state == INSERT || s != expr_offset(0,0)) reset_cache(); + m_state = APPLY; + unsigned j; expr * e; unsigned off; @@ -161,6 +167,48 @@ void substitution::apply(unsigned num_actual_offsets, unsigned const * deltas, e } } break; + case AST_QUANTIFIER: { + quantifier* q = to_quantifier(e); + unsigned num_vars = q->get_num_decls(); + substitution subst(m_manager); + expr_ref er(m_manager); + subst.reserve(m_subst.offsets_capacity(), m_subst.vars_capacity()); + var_shifter var_sh(m_manager); + expr_offset r; + for (unsigned i = 0; i < m_subst.offsets_capacity(); i++) { + for (unsigned j = 0; j < m_subst.vars_capacity(); j++) { + if (find(j, i, r)) { + var_sh(r.get_expr(), num_vars, er); + subst.insert(j, i, expr_offset(er, r.get_offset())); + } + } + } + expr_offset body(q->get_expr(), off); + expr_ref s1_ref(m_manager), t1_ref(m_manager); + if (s.get_expr() != 0) { + var_sh(s.get_expr(), num_vars, s1_ref); + } + if (t.get_expr() != 0) { + var_sh(t.get_expr(), num_vars, t1_ref); + } + expr_offset s1(s1_ref, s.get_offset()); + expr_offset t1(t1_ref, t.get_offset()); + expr_ref_vector pats(m_manager), no_pats(m_manager); + for (unsigned i = 0; i < q->get_num_patterns(); ++i) { + subst.apply(num_actual_offsets, deltas, expr_offset(q->get_pattern(i), off), s1, t1, er); + pats.push_back(er); + } + for (unsigned i = 0; i < q->get_num_no_patterns(); ++i) { + subst.apply(num_actual_offsets, deltas, expr_offset(q->get_no_pattern(i), off), s1, t1, er); + no_pats.push_back(er); + } + subst.apply(num_actual_offsets, deltas, body, s1, t1, er); + er = m_manager.update_quantifier(q, pats.size(), pats.c_ptr(), no_pats.size(), no_pats.c_ptr(), er); + m_todo.pop_back(); + m_new_exprs.push_back(er); + m_apply_cache.insert(n, er); + break; + } default: UNREACHABLE(); } diff --git a/src/ast/substitution/substitution.h b/src/ast/substitution/substitution.h index 1d12dc278..3227a6fec 100644 --- a/src/ast/substitution/substitution.h +++ b/src/ast/substitution/substitution.h @@ -16,6 +16,19 @@ Author: Revision History: + nbjorner 2013-01-21: + - reset the apply cache on pop_scope to make sure that popped + substitutions are invalidated. + - reset_cache if a new binding was added after application + of a substitution. + - Add m_refs to make sure terms in the range of the + substitution have the same life-time as the substitution. + - Remove reset_subst() function. If called without resetting the cache, then + results of applying substitutions are incoherent. + - Replace UNREACHABLE segment for quantifiers by recursive invocation of substitution + that updates expressions within quantifiers. It shifts all variables in the domain + of the current substitution by the number of quantified variables. + --*/ #ifndef _SUBSTITUTION_H_ #define _SUBSTITUTION_H_ @@ -34,6 +47,7 @@ class substitution { // field for backtracking typedef std::pair var_offset; svector m_vars; + expr_ref_vector m_refs; unsigned_vector m_scopes; // fields for applying substitutions @@ -45,6 +59,11 @@ class substitution { enum color { White, Grey, Black }; expr_offset_map m_color; + + // keep track of how substitution state was last updated. + enum state { CLEAN, APPLY, INSERT }; + state m_state; + #ifdef Z3DEBUG unsigned m_max_offset_since_reset; #endif @@ -81,8 +100,6 @@ public: // reset everything void reset(); - // reset only the mapping from variables to expressions - void reset_subst(); // reset only the substitution application cache void reset_cache(); @@ -119,7 +136,9 @@ public: TRACE("subst_insert", tout << "inserting: #" << v_idx << ":" << offset << " --> " << mk_pp(t.get_expr(), m_manager) << ":" << t.get_offset() << "\n";); m_vars.push_back(var_offset(v_idx, offset)); + m_refs.push_back(t.get_expr()); m_subst.insert(v_idx, offset, t); + m_state = INSERT; } void insert(var * v, unsigned offset, expr_offset const & t) { insert(v->get_idx(), offset, t); } void insert(expr_offset v, expr_offset const & t) { From af4c09c8d3ae0b191aab25e9ecd5c2e1f33d00ec Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 21 Jan 2013 21:59:20 -0800 Subject: [PATCH 029/101] update substitution routines Signed-off-by: Nikolaj Bjorner --- src/ast/substitution/substitution.cpp | 4 ++-- src/test/substitution.cpp | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/ast/substitution/substitution.cpp b/src/ast/substitution/substitution.cpp index 2427c9c25..11bca0133 100644 --- a/src/ast/substitution/substitution.cpp +++ b/src/ast/substitution/substitution.cpp @@ -172,14 +172,14 @@ void substitution::apply(unsigned num_actual_offsets, unsigned const * deltas, e unsigned num_vars = q->get_num_decls(); substitution subst(m_manager); expr_ref er(m_manager); - subst.reserve(m_subst.offsets_capacity(), m_subst.vars_capacity()); + subst.reserve(m_subst.offsets_capacity(), m_subst.vars_capacity() + num_vars); var_shifter var_sh(m_manager); expr_offset r; for (unsigned i = 0; i < m_subst.offsets_capacity(); i++) { for (unsigned j = 0; j < m_subst.vars_capacity(); j++) { if (find(j, i, r)) { var_sh(r.get_expr(), num_vars, er); - subst.insert(j, i, expr_offset(er, r.get_offset())); + subst.insert(j + num_vars, i, expr_offset(er, r.get_offset())); } } } diff --git a/src/test/substitution.cpp b/src/test/substitution.cpp index 889666972..0d7fb5856 100644 --- a/src/test/substitution.cpp +++ b/src/test/substitution.cpp @@ -20,9 +20,11 @@ void tst_substitution() var_ref v1(m.mk_var(0, m.mk_bool_sort()), m); var_ref v2(m.mk_var(1, m.mk_bool_sort()), m); + var_ref v3(m.mk_var(2, m.mk_bool_sort()), m); + var_ref v4(m.mk_var(3, m.mk_bool_sort()), m); substitution subst(m); - subst.reserve(1,2); + subst.reserve(1,4); unifier unif(m); bool ok1 = unif(v1.get(), v2.get(), subst, false); @@ -34,4 +36,16 @@ void tst_substitution() TRACE("substitution", tout << ok1 << " " << ok2 << "\n";); subst.display(std::cout); subst.apply(v1.get(), res); + TRACE("substitution", tout << mk_pp(res, m) << "\n";); + + expr_ref q(m), body(m); + sort_ref_vector sorts(m); + svector names; + sorts.push_back(m.mk_bool_sort()); + names.push_back(symbol("dude")); + body = m.mk_and(m.mk_eq(v1,v2), m.mk_eq(v3,v4)); + q = m.mk_forall(sorts.size(), sorts.c_ptr(), names.c_ptr(), body); + subst.apply(q, res); + TRACE("substitution", tout << mk_pp(q, m) << "\n->\n" << mk_pp(res, m) << "\n";); + } From 085ccf5effa41ffcfa02ea2c51670671f18299d9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 21 Jan 2013 22:28:25 -0800 Subject: [PATCH 030/101] working on tab context Signed-off-by: Nikolaj Bjorner --- src/muz_qe/tab_context.cpp | 154 ++++++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 61 deletions(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index f4efe78f0..dd0874734 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -98,23 +98,14 @@ namespace tb { } bool match_app(app* p, app* t, substitution& s, expr_ref_vector& conds) { - if (p->get_decl() == t->get_decl() && - p->get_num_args() == t->get_num_args()) { - for (unsigned i = 0; i < p->get_num_args(); ++i) { - m_todo.push_back(expr_pair(p->get_arg(i), t->get_arg(i))); - } + switch(is_eq(p, t)) { + case l_true: + return true; + case l_false: + return false; + default: + conds.push_back(m.mk_eq(p, t)); return true; - } - else { - switch(is_eq(p, t)) { - case l_true: - return true; - case l_false: - return false; - default: - conds.push_back(m.mk_eq(p, t)); - return true; - } } } @@ -122,32 +113,38 @@ namespace tb { public: matcher(ast_manager& m): m(m), m_dt(m) {} - bool operator()(expr* pat, expr* term, substitution& s, expr_ref_vector& conds) { + bool operator()(app* pat, app* term, substitution& s, expr_ref_vector& conds) { + // top-most term to match is a predicate. The predicates should be the same. + if (pat->get_decl() != term->get_decl() || + pat->get_num_args() != term->get_num_args()) { + return false; + } m_todo.reset(); - m_todo.push_back(expr_pair(pat, term)); + for (unsigned i = 0; i < pat->get_num_args(); ++i) { + m_todo.push_back(expr_pair(pat->get_arg(i), term->get_arg(i))); + } while (!m_todo.empty()) { - expr_pair const& p = m_todo.back(); - pat = p.first; - term = p.second; + expr_pair const& pr = m_todo.back(); + expr* p = pr.first; + expr* t = pr.second; m_todo.pop_back(); - if (!is_app(term)) { + if (!is_app(t)) { IF_VERBOSE(2, verbose_stream() << "term is not app\n";); return false; } - else if (is_var(pat) && match_var(to_var(pat), to_app(term), s, conds)) { + else if (is_var(p) && match_var(to_var(p), to_app(t), s, conds)) { continue; } - else if (!is_app(pat)) { + else if (!is_app(p)) { IF_VERBOSE(2, verbose_stream() << "pattern is not app\n";); return false; } - else if (!match_app(to_app(pat), to_app(term), s, conds)) { + else if (!match_app(to_app(p), to_app(t), s, conds)) { return false; } } return true; - } - + } }; class goal { @@ -248,18 +245,28 @@ namespace tb { } datalog::flatten_and(fmls); for (unsigned i = 0; i < fmls.size(); ++i) { - expr* e = fmls[i].get(); + expr_ref e(m); expr* t, *v; - if ((m.is_eq(e, v, t) && is_var(v) && !subst.contains(to_var(v), 0)) || - (m.is_eq(e, t, v) && is_var(v) && !subst.contains(to_var(v), 0))) { + subst.apply(1, delta, expr_offset(fmls[i].get(), 0), e); + m_rw(e); + fmls[i] = e; + if (m.is_eq(e, v, t) && (is_var(v) || is_var(t))) { + if (!is_var(v)) { + std::swap(v, t); + } + SASSERT(!subst.contains(to_var(v), 0)); subst.push_scope(); subst.insert(to_var(v)->get_idx(), 0, expr_offset(t, 0)); - if (!subst.acyclic()) { + subst.reset_cache(); + if (subst.acyclic()) { + fmls[i] = m.mk_true(); + } + else { subst.pop_scope(); } } } - bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); + bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); subst.apply(1, delta, expr_offset(m_constraint, 0), m_constraint); subst.apply(1, delta, expr_offset(m_goal->get_head(), 0), tmp); m_head = to_app(tmp); @@ -380,6 +387,7 @@ namespace tb { // bool match_rule(unsigned rule_index) { goal const& g = *m_index[rule_index]; + m_sideconds.reset(); m_subst.reset(); m_subst.reserve(2, g.get_num_vars()); @@ -401,7 +409,9 @@ namespace tb { m_subst.push_scope(); unsigned limit = m_sideconds.size(); IF_VERBOSE(2, - for (unsigned j = 0; j < predicate_index; ++j) verbose_stream() << " "; + for (unsigned j = 0; j < predicate_index; ++j) { + verbose_stream() << " "; + } verbose_stream() << mk_pp(q, m) << " = " << mk_pp(p, m) << "\n"; ); @@ -421,6 +431,7 @@ namespace tb { unsigned deltas[2] = {0, 0}; expr_ref q(m), postcond(m); expr_ref_vector fmls(m_sideconds); + m_subst.reset_cache(); for (unsigned i = 0; i < fmls.size(); ++i) { m_subst.apply(2, deltas, expr_offset(fmls[i].get(), 0), q); @@ -445,7 +456,8 @@ namespace tb { return true; } if (!is_ground(postcond)) { - IF_VERBOSE(1, verbose_stream() << "TBD: non-ground\n" << mk_pp(postcond, m) << "\n";); + IF_VERBOSE(1, verbose_stream() << "TBD: non-ground\n" + << mk_pp(postcond, m) << "\n";); return false; } postcond = m.mk_not(postcond); @@ -492,35 +504,38 @@ namespace tb { } unsigned select(goal const& g) { - unsigned min_distance = UINT_MAX; + return 0; +#if 0 + unsigned max_score = 0; unsigned result = 0; unsigned_vector& scores = m_score_values; for (unsigned i = 0; i < g.get_num_predicates(); ++i) { scores.reset(); - score_predicate(g.get_predicate(i), scores); - unsigned dist = compute_distance(g.get_predicate(i)->get_decl(), scores); - if (dist < min_distance) { - min_distance = dist; + app* p = g.get_predicate(i); + score_predicate(p, scores); + unsigned score = compute_score(p->get_decl(), scores); + if (score > max_score) { + max_score = score; result = i; } } return result; +#endif } private: - unsigned compute_distance(func_decl* f, unsigned_vector const& scores) { + unsigned compute_score(func_decl* f, unsigned_vector const& scores) { unsigned_vector f_scores; - unsigned dist = 0; + unsigned score = 0; if (m_scores.find(f, f_scores)) { SASSERT(f_scores.size() == scores.size()); for (unsigned i = 0; i < scores.size(); ++i) { - unsigned d1 = scores[i] - f_scores[i]; - dist += d1*d1; + score += scores[i]*f_scores[i]; } } // else there is no rule. - return dist; + return score; } void score_predicate(app* p, unsigned_vector& scores) { @@ -543,7 +558,8 @@ namespace tb { } void insert_score(func_decl* f, unsigned_vector const& scores) { - obj_map::obj_map_entry* e = m_scores.find_core(f); + obj_map::obj_map_entry* e; + e = m_scores.find_core(f); if (e) { unsigned_vector & old_scores = e->get_data().m_value; SASSERT(scores.size() == old_scores.size()); @@ -669,17 +685,18 @@ namespace datalog { private: void select_predicate() { - unsigned num_predicates = get_goal()->get_num_predicates(); + tb::goal & g = *get_goal(); + unsigned num_predicates = g.get_num_predicates(); if (num_predicates == 0) { m_instruction = tb::UNSATISFIABLE; - IF_VERBOSE(2, get_goal()->display(verbose_stream()); ); + IF_VERBOSE(2, g.display(verbose_stream()); ); } else { m_instruction = tb::SELECT_RULE; - unsigned pi = m_selection.select(*get_goal()); - get_goal()->set_predicate_index(pi); - get_goal()->set_rule_index(0); - IF_VERBOSE(2, verbose_stream() << mk_pp(get_goal()->get_predicate(pi), m) << "\n";); + unsigned pi = m_selection.select(g); + g.set_predicate_index(pi); + g.set_rule_index(0); + IF_VERBOSE(2, verbose_stream() << mk_pp(g.get_predicate(pi), m) << "\n";); } } @@ -693,10 +710,12 @@ namespace datalog { ref next_goal = init_goal(new_query); unsigned subsumer = 0; IF_VERBOSE(1, - display_premise(*goal, verbose_stream() << "g" << next_goal->get_index() << " "); + display_rule(*goal, verbose_stream()); + display_premise(*goal, + verbose_stream() << "g" << next_goal->get_index() << " "); display_goal(*next_goal, verbose_stream());); if (m_index.is_subsumed(*next_goal, subsumer)) { - IF_VERBOSE(1, verbose_stream() << "subsumed by " << subsumer << "\n";); + IF_VERBOSE(1, verbose_stream() << "subsumed by g" << subsumer << "\n";); m_stats.m_num_subsumed++; m_goals.pop_back(); m_instruction = tb::SELECT_RULE; @@ -713,17 +732,17 @@ namespace datalog { } } - - void select_rule() { - - func_decl* p = get_goal()->get_predicate(get_goal()->get_predicate_index())->get_decl(); + void select_rule() { + tb::goal& g = *get_goal(); + unsigned pi = g.get_predicate_index(); + func_decl* p = g.get_predicate(pi)->get_decl(); rule_vector const& rules = m_rules.get_predicate_rules(p); - if (rules.size() <= get_goal()->get_rule_index()) { + if (rules.size() <= g.get_rule_index()) { m_instruction = tb::BACKTRACK; } else { - unsigned index = get_goal()->get_rule_index(); - get_goal()->inc_rule_index(); + unsigned index = g.get_rule_index(); + g.inc_rule_index(); apply_rule(*rules[index]); } } @@ -810,8 +829,21 @@ namespace datalog { ref get_goal() const { return m_goals.back(); } + hashtable m_displayed_rules; + + void display_rule(tb::goal const& p, std::ostream& out) { + func_decl* f = p.get_predicate(p.get_predicate_index())->get_decl(); + rule_vector const& rules = m_rules.get_predicate_rules(f); + rule* r = rules[p.get_rule_index()-1]; + if (!m_displayed_rules.contains(r)) { + m_displayed_rules.insert(r); + r->display(m_ctx, out << p.get_rule_index() << ":"); + } + } + void display_premise(tb::goal& p, std::ostream& out) { - out << "{g" << p.get_index() << " p" << p.get_predicate_index() << " r" << p.get_rule_index() << "}\n"; + func_decl* f = p.get_predicate(p.get_predicate_index())->get_decl(); + out << "{g" << p.get_index() << " " << f->get_name() << " pos: " << p.get_predicate_index() << " rule: " << p.get_rule_index() << "}\n"; } void display_goal(tb::goal& g, std::ostream& out) { g.display(out); From b61c1b0ded1818983b7835b6ebde2fc5fe1037e2 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Jan 2013 19:05:38 -0800 Subject: [PATCH 031/101] working on tab-context Signed-off-by: Nikolaj Bjorner --- src/muz_qe/dl_bmc_engine.cpp | 16 +- src/muz_qe/dl_mk_extract_quantifiers.cpp | 2 +- src/muz_qe/dl_mk_rule_inliner.cpp | 13 +- src/muz_qe/dl_util.cpp | 2 +- src/muz_qe/dl_util.h | 9 +- src/muz_qe/equiv_proof_converter.cpp | 2 +- src/muz_qe/pdr_context.cpp | 2 +- src/muz_qe/pdr_quantifiers.cpp | 2 +- src/muz_qe/qe_lite.cpp | 42 +- src/muz_qe/replace_proof_converter.h | 3 + src/muz_qe/tab_context.cpp | 680 ++++++++++++++++++----- 11 files changed, 597 insertions(+), 176 deletions(-) diff --git a/src/muz_qe/dl_bmc_engine.cpp b/src/muz_qe/dl_bmc_engine.cpp index 221c2d2a2..80fcdea4a 100644 --- a/src/muz_qe/dl_bmc_engine.cpp +++ b/src/muz_qe/dl_bmc_engine.cpp @@ -305,7 +305,7 @@ namespace datalog { apply_subst(sub, sub2); unifier.apply(*r0.get(), 0, *r2.get(), r1); r1->to_formula(concl); - scoped_coarse_proof _sp(m); + scoped_proof _sp(m); proof* p = m.mk_asserted(fml); proof* premises[2] = { pr, p }; @@ -319,7 +319,7 @@ namespace datalog { } else { r2->to_formula(concl); - scoped_coarse_proof _sp(m); + scoped_proof _sp(m); proof* p = m.mk_asserted(fml); if (sub.empty()) { pr = p; @@ -339,7 +339,7 @@ namespace datalog { SASSERT(r->get_uninterpreted_tail_size() == 1); pred = r->get_decl(0); } - scoped_coarse_proof _sp(m); + scoped_proof _sp(m); apply(m, b.m_pc.get(), pr); b.m_answer = pr; return l_true; @@ -531,7 +531,7 @@ namespace datalog { } void get_model(unsigned level) { - scoped_coarse_proof _sp(m); + scoped_proof _sp(m); expr_ref level_query = compile_query(b.m_query_pred, level); model_ref md; b.m_solver.get_model(md); @@ -1023,7 +1023,7 @@ namespace datalog { for (unsigned i = 0; i < cnstrs.size(); ++i) { if (trace->get_decl() == cnstrs[i]) { svector > positions; - scoped_coarse_proof _sc(m); + scoped_proof _sc(m); proof_ref_vector prs(m); expr_ref_vector sub(m); vector substs; @@ -1210,7 +1210,7 @@ namespace datalog { apply_subst(sub, sub2); unifier.apply(*r0.get(), 0, *r2.get(), r1); r1->to_formula(concl); - scoped_coarse_proof _sp(m); + scoped_proof _sp(m); proof* p = m.mk_asserted(fml); proof* premises[2] = { pr, p }; @@ -1224,7 +1224,7 @@ namespace datalog { } else { r2->to_formula(concl); - scoped_coarse_proof _sp(m); + scoped_proof _sp(m); proof* p = m.mk_asserted(fml); if (sub.empty()) { pr = p; @@ -1244,7 +1244,7 @@ namespace datalog { SASSERT(r->get_uninterpreted_tail_size() == 1); pred = r->get_decl(0); } - scoped_coarse_proof _sp(m); + scoped_proof _sp(m); apply(m, b.m_pc.get(), pr); b.m_answer = pr; } diff --git a/src/muz_qe/dl_mk_extract_quantifiers.cpp b/src/muz_qe/dl_mk_extract_quantifiers.cpp index 8a5aa52ec..35f7485d5 100644 --- a/src/muz_qe/dl_mk_extract_quantifiers.cpp +++ b/src/muz_qe/dl_mk_extract_quantifiers.cpp @@ -227,7 +227,7 @@ namespace datalog { obj_map& insts, expr_ref_vector& bindings) { - datalog::scoped_fine_proof _scp(m); + datalog::scoped_proof _scp(m); smt_params fparams; fparams.m_mbqi = true; // false fparams.m_soft_timeout = 1000; diff --git a/src/muz_qe/dl_mk_rule_inliner.cpp b/src/muz_qe/dl_mk_rule_inliner.cpp index 24ddd9ba5..0919e2ff0 100644 --- a/src/muz_qe/dl_mk_rule_inliner.cpp +++ b/src/muz_qe/dl_mk_rule_inliner.cpp @@ -118,6 +118,13 @@ namespace datalog { SASSERT(tail.size()==tail_neg.size()); res = m_rm.mk(new_head, tail.size(), tail.c_ptr(), tail_neg.c_ptr(), tgt.name(), m_normalize); res->set_accounting_parent_object(m_context, const_cast(&tgt)); + TRACE("dl", + tgt.display(m_context, tout << "tgt (" << tail_index << "): \n"); + src.display(m_context, tout << "src:\n"); + res->display(m_context, tout << "res\n"); + // m_unif.display(tout << "subst:\n"); + ); + if (m_normalize) { m_rm.fix_unbound_vars(res, true); if (m_interp_simplifier.transform_rule(res.get(), simpl_rule)) { @@ -174,12 +181,6 @@ namespace datalog { } if (m_unifier.apply(tgt, tail_index, src, res)) { - TRACE("dl", - tgt.display(m_context, tout << "tgt (" << tail_index << "): \n"); - src.display(m_context, tout << "src:\n"); - res->display(m_context, tout << "res\n"); - //m_unifier.display(tout << "subst:\n"); - ); if (m_pc) { expr_ref_vector s1 = m_unifier.get_rule_subst(tgt, true); expr_ref_vector s2 = m_unifier.get_rule_subst(src, false); diff --git a/src/muz_qe/dl_util.cpp b/src/muz_qe/dl_util.cpp index d29df7ef9..74b1a36dd 100644 --- a/src/muz_qe/dl_util.cpp +++ b/src/muz_qe/dl_util.cpp @@ -628,7 +628,7 @@ namespace datalog { substs.push_back(s1); substs.push_back(s2); - scoped_coarse_proof _sc(m); + scoped_proof _sc(m); proof_ref pr(m); proof_ref_vector premises(m); premises.push_back(m.mk_asserted(fml1)); diff --git a/src/muz_qe/dl_util.h b/src/muz_qe/dl_util.h index 99256e70a..69be7e9ac 100644 --- a/src/muz_qe/dl_util.h +++ b/src/muz_qe/dl_util.h @@ -188,14 +188,9 @@ namespace datalog { }; - class scoped_coarse_proof : public scoped_proof_mode { + class scoped_proof : public scoped_proof_mode { public: - scoped_coarse_proof(ast_manager& m): scoped_proof_mode(m, PGM_COARSE) {} - }; - - class scoped_fine_proof : public scoped_proof_mode { - public: - scoped_fine_proof(ast_manager& m): scoped_proof_mode(m, PGM_FINE) {} + scoped_proof(ast_manager& m): scoped_proof_mode(m, PGM_FINE) {} }; class scoped_no_proof : public scoped_proof_mode { diff --git a/src/muz_qe/equiv_proof_converter.cpp b/src/muz_qe/equiv_proof_converter.cpp index 8b821227b..53db01900 100644 --- a/src/muz_qe/equiv_proof_converter.cpp +++ b/src/muz_qe/equiv_proof_converter.cpp @@ -22,7 +22,7 @@ Revision History: #include "dl_util.h" void equiv_proof_converter::insert(expr* fml1, expr* fml2) { - datalog::scoped_fine_proof _sp(m); + datalog::scoped_proof _sp(m); proof_ref p1(m), p2(m), p3(m); p1 = m.mk_asserted(fml1); p2 = m.mk_rewrite(fml1, fml2); diff --git a/src/muz_qe/pdr_context.cpp b/src/muz_qe/pdr_context.cpp index 89562fd95..574d44fb5 100644 --- a/src/muz_qe/pdr_context.cpp +++ b/src/muz_qe/pdr_context.cpp @@ -1565,7 +1565,7 @@ namespace pdr { } proof_ref context::get_proof() const { - datalog::scoped_coarse_proof _sc(m); + datalog::scoped_proof _sc(m); proof_ref proof(m); SASSERT(m_last_result == l_true); proof = m_search.get_proof_trace(*this); diff --git a/src/muz_qe/pdr_quantifiers.cpp b/src/muz_qe/pdr_quantifiers.cpp index 23c204801..5cc97893a 100644 --- a/src/muz_qe/pdr_quantifiers.cpp +++ b/src/muz_qe/pdr_quantifiers.cpp @@ -207,7 +207,7 @@ namespace pdr { void quantifier_model_checker::find_instantiations_proof_based(quantifier_ref_vector const& qs, unsigned level) { bool found_instance = false; - datalog::scoped_fine_proof _scp(m); + datalog::scoped_proof _scp(m); expr_ref_vector fmls(m); smt_params fparams; diff --git a/src/muz_qe/qe_lite.cpp b/src/muz_qe/qe_lite.cpp index 53702700e..5f018895c 100644 --- a/src/muz_qe/qe_lite.cpp +++ b/src/muz_qe/qe_lite.cpp @@ -636,10 +636,43 @@ namespace eq { } } } + + bool is_unconstrained(var* x, expr* t, unsigned i, expr_ref_vector const& conjs) { + bool occ = occurs(x, t); + for (unsigned j = 0; !occ && j < conjs.size(); ++j) { + occ = (i != j) && occurs(x, conjs[j]); + } + return !occ; + } + + bool remove_unconstrained(expr_ref_vector& conjs) { + bool reduced = false, change = true; + expr* r, *l, *ne; + while (change) { + change = false; + for (unsigned i = 0; i < conjs.size(); ++i) { + if (m.is_not(conjs[i].get(), ne) && m.is_eq(ne, l, r)) { + TRACE("qe_lite", tout << mk_pp(conjs[i].get(), m) << " " << is_variable(l) << " " << is_variable(r) << "\n";); + if (is_variable(l) && ::is_var(l) && is_unconstrained(::to_var(l), r, i, conjs)) { + conjs[i] = m.mk_true(); + reduced = true; + change = true; + } + else if (is_variable(r) && ::is_var(r) && is_unconstrained(::to_var(r), l, i, conjs)) { + conjs[i] = m.mk_true(); + reduced = true; + change = true; + } + } + } + } + return reduced; + } bool reduce_var_set(expr_ref_vector& conjs) { unsigned def_count = 0; unsigned largest_vinx = 0; + bool reduced = false; flatten_definitions(conjs); @@ -657,10 +690,15 @@ namespace eq { m_rewriter(new_r); conjs.reset(); datalog::flatten_and(new_r, conjs); - return true; + reduced = true; } } - return false; + + if (remove_unconstrained(conjs)) { + reduced = true; + } + + return reduced; } void checkpoint() { diff --git a/src/muz_qe/replace_proof_converter.h b/src/muz_qe/replace_proof_converter.h index 8a96416db..cb97810f8 100644 --- a/src/muz_qe/replace_proof_converter.h +++ b/src/muz_qe/replace_proof_converter.h @@ -42,6 +42,9 @@ public: ast_manager& get_manager() { return m; } + // run the replacements the inverse direction. + void invert() { m_proofs.reverse(); } + }; #endif diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index dd0874734..3d7b6a71f 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -27,6 +27,7 @@ Revision History: #include "bool_rewriter.h" #include "th_rewriter.h" #include "datatype_decl_plugin.h" +#include "for_each_expr.h" namespace tb { @@ -148,35 +149,40 @@ namespace tb { }; class goal { - th_rewriter m_rw; - datalog::rule_ref m_goal; - app_ref m_head; - app_ref_vector m_predicates; - expr_ref m_constraint; - unsigned m_index; - unsigned m_num_vars; - unsigned m_predicate_index; - unsigned m_rule_index; - unsigned m_ref; + datalog::rule_ref m_goal; // goal as rule + app_ref m_head; // head predicate + app_ref_vector m_predicates; // predicates used in goal + expr_ref m_constraint; // side constraint + unsigned m_seqno; // sequence number of goal + unsigned m_index; // index of goal into set of goals + unsigned m_num_vars; // maximal free variable index+1 + unsigned m_predicate_index; // selected predicate + unsigned m_parent_rule; // rule used to produce goal + unsigned m_parent_index; // index of parent goal + unsigned m_next_rule; // next rule to expand goal on + unsigned m_ref; // reference count public: goal(datalog::rule_manager& rm): - m_rw(rm.get_manager()), m_goal(rm), m_head(rm.get_manager()), m_predicates(rm.get_manager()), m_constraint(rm.get_manager()), + m_seqno(0), m_index(0), m_num_vars(0), m_predicate_index(0), - m_rule_index(0), + m_next_rule(static_cast(-1)), + m_parent_rule(0), + m_parent_index(0), m_ref(0) { } - void set_rule_index(unsigned i) { m_rule_index = i; } - unsigned get_rule_index() const { return m_rule_index; } - void inc_rule_index() { m_rule_index++; } + void set_seqno(unsigned seqno) { m_seqno = seqno; } + unsigned get_seqno() const { return m_seqno; } + unsigned get_next_rule() const { return m_next_rule; } + void inc_next_rule() { m_next_rule++; } unsigned get_predicate_index() const { return m_predicate_index; } void set_predicate_index(unsigned i) { m_predicate_index = i; } unsigned get_num_predicates() const { return m_predicates.size(); } @@ -185,22 +191,58 @@ namespace tb { datalog::rule const& get_rule() const { return *m_goal; } unsigned get_num_vars() const { return m_num_vars; } unsigned get_index() const { return m_index; } + void set_index(unsigned index) { m_index = index; } app* get_head() const { return m_head; } + unsigned get_parent_index() const { return m_parent_index; } + unsigned get_parent_rule() const { return m_parent_rule; } + void set_parent(ref& parent) { + m_parent_index = parent->get_index(); + m_parent_rule = parent->get_next_rule(); + } + + expr_ref get_body() const { + ast_manager& m = get_manager(); + expr_ref_vector fmls(m); + for (unsigned i = 0; i < m_predicates.size(); ++i) { + fmls.push_back(m_predicates[i]); + } + fmls.push_back(m_constraint); + datalog::flatten_and(fmls); + return expr_ref(m.mk_and(fmls.size(), fmls.c_ptr()), m); + } + + void get_free_vars(ptr_vector& vars) const { + ::get_free_vars(m_head, vars); + for (unsigned i = 0; i < m_predicates.size(); ++i) { + ::get_free_vars(m_predicates[i], vars); + } + ::get_free_vars(m_constraint, vars); + } + + void init(app* head, app_ref_vector const& predicates, expr* constraint) { + m_goal = 0; + m_index = 0; + m_predicate_index = 0; + m_next_rule = static_cast(-1); + m_head = head; + m_predicates.reset(); + m_predicates.append(predicates); + m_constraint = constraint; + ptr_vector sorts; + get_free_vars(sorts); + m_num_vars = sorts.size(); + reduce_equalities(); + } void init(datalog::rule_ref& g) { m_goal = g; m_index = 0; m_predicate_index = 0; - m_rule_index = 0; - m_num_vars = 1 + g.get_manager().get_var_counter().get_max_var(*g); - init(); - + m_next_rule = static_cast(-1); + init_from_rule(g); + reduce_equalities(); // IF_VERBOSE(1, display(verbose_stream());); } - - void set_index(unsigned index) { - m_index = index; - } void inc_ref() { m_ref++; @@ -226,57 +268,177 @@ namespace tb { } private: - // x = t[y], if x does not occur in t[y], then add t[y] to subst. - - void init() { + + ast_manager& get_manager() const { return m_head.get_manager(); } + + // Given a rule, initialize fields: + // - m_num_vars - number of free variables in rule + // - m_head - head predicate + // - m_predicates - auxiliary predicates in body. + // - m_constraint - side constraint + // + void init_from_rule(datalog::rule_ref const& r) { + ast_manager& m = get_manager(); + expr_ref_vector fmls(m); + unsigned utsz = r->get_uninterpreted_tail_size(); + unsigned tsz = r->get_tail_size(); + for (unsigned i = utsz; i < tsz; ++i) { + fmls.push_back(r->get_tail(i)); + } + m_num_vars = 1 + r.get_manager().get_var_counter().get_max_var(*r); + m_head = r->get_head(); m_predicates.reset(); - ast_manager& m = m_head.get_manager(); + for (unsigned i = 0; i < utsz; ++i) { + m_predicates.push_back(r->get_tail(i)); + } + bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); + } + + // Simplify a goal by applying equalities as substitutions on predicates. + // x = t[y], if x does not occur in t[y], then add t[y] to subst. + void reduce_equalities() { + ast_manager& m = get_manager(); + th_rewriter rw(m); unsigned delta[1] = { 0 }; - datalog::rule_manager& rm = m_goal.m(); - unsigned num_vars = rm.get_var_counter().get_max_var(*m_goal); - substitution subst(m); - subst.reserve(1, num_vars+1); expr_ref_vector fmls(m); expr_ref tmp(m); - unsigned utsz = m_goal->get_uninterpreted_tail_size(); - unsigned tsz = m_goal->get_tail_size(); - for (unsigned i = utsz; i < tsz; ++i) { - fmls.push_back(m_goal->get_tail(i)); - } - datalog::flatten_and(fmls); - for (unsigned i = 0; i < fmls.size(); ++i) { - expr_ref e(m); - expr* t, *v; - subst.apply(1, delta, expr_offset(fmls[i].get(), 0), e); - m_rw(e); - fmls[i] = e; - if (m.is_eq(e, v, t) && (is_var(v) || is_var(t))) { - if (!is_var(v)) { - std::swap(v, t); - } - SASSERT(!subst.contains(to_var(v), 0)); - subst.push_scope(); - subst.insert(to_var(v)->get_idx(), 0, expr_offset(t, 0)); - subst.reset_cache(); - if (subst.acyclic()) { - fmls[i] = m.mk_true(); - } - else { - subst.pop_scope(); - } + substitution subst(m); + subst.reserve(1, get_num_vars()); + datalog::flatten_and(m_constraint, fmls); + unsigned num_fmls = fmls.size(); + for (unsigned i = 0; i < num_fmls; ++i) { + if (get_subst(rw, subst, i, fmls)) { + fmls[i] = m.mk_true(); } - } + } + subst.apply(1, delta, expr_offset(m_head, 0), tmp); + m_head = to_app(tmp); + for (unsigned i = 0; i < m_predicates.size(); ++i) { + subst.apply(1, delta, expr_offset(m_predicates[i].get(), 0), tmp); + m_predicates[i] = to_app(tmp); + } bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); subst.apply(1, delta, expr_offset(m_constraint, 0), m_constraint); - subst.apply(1, delta, expr_offset(m_goal->get_head(), 0), tmp); - m_head = to_app(tmp); - m_rw(m_constraint); - for (unsigned i = 0; i < utsz; ++i) { - subst.apply(1, delta, expr_offset(m_goal->get_tail(i), 0), tmp); - m_predicates.push_back(to_app(tmp)); + rw(m_constraint); + } + + bool get_subst(th_rewriter& rw, substitution& S, unsigned i, expr_ref_vector& fmls) { + ast_manager& m = get_manager(); + unsigned delta[1] = { 0 }; + expr* f = fmls[i].get(); + expr_ref e(m), tr(m); + expr* t, *v; + S.apply(1, delta, expr_offset(f, 0), e); + rw(e); + fmls[i] = e; + if (!m.is_eq(e, v, t)) { + return false; + } + if (!is_var(v)) { + std::swap(v, t); + } + if (!is_var(v)) { + return false; + } + if (!can_be_substituted(m, t)) { + return false; + } + SASSERT(!S.contains(to_var(v), 0)); + S.push_scope(); + S.insert(to_var(v)->get_idx(), 0, expr_offset(t, 0)); + if (!S.acyclic()) { + S.pop_scope(); + return false; + } + fmls[i] = m.mk_true(); + return true; + } + + struct non_constructor {}; + + struct constructor_test { + ast_manager& m; + datatype_util dt; + constructor_test(ast_manager& m): m(m), dt(m) {} + void operator()(app* e) { + if (!m.is_value(e) && + !dt.is_constructor(e->get_decl())) { + throw non_constructor(); + } + } + void operator()(var* v) { } + void operator()(quantifier* ) { + throw non_constructor(); + } + }; + + bool can_be_substituted(ast_manager& m, expr* t) { + constructor_test p(m); + try { + quick_for_each_expr(p, t); + } + catch (non_constructor) { + return false; + } + return true; + } + + }; + + // rules + class rules { + typedef obj_map map; + vector > m_rules; + map m_index; + public: + + typedef vector >::const_iterator iterator; + + iterator begin() const { return m_rules.begin(); } + iterator end() const { return m_rules.end(); } + + void init(datalog::rule_set const& rules) { + m_rules.reset(); + m_index.reset(); + datalog::rule_manager& rm = rules.get_rule_manager(); + datalog::rule_ref r(rm); + datalog::rule_set::iterator it = rules.begin(); + datalog::rule_set::iterator end = rules.end(); + for (; it != end; ++it) { + r = *it; + ref g = alloc(goal, rm); + g->init(r); + insert(g); } } - }; + + void insert(ref& g) { + unsigned idx = m_rules.size(); + m_rules.push_back(g); + func_decl* f = g->get_head()->get_decl(); + map::obj_map_entry* e = m_index.insert_if_not_there2(f, unsigned_vector()); + SASSERT(e); + e->get_data().m_value.push_back(idx); + } + + unsigned get_num_rules(func_decl* p) { + map::obj_map_entry* e = m_index.find_core(p); + if (p) { + return e->get_data().get_value().size(); + } + else { + return 0; + } + } + + ref get_rule(func_decl* p, unsigned idx) const { + map::obj_map_entry* e = m_index.find_core(p); + SASSERT(p); + unsigned rule_id = e->get_data().get_value()[idx]; + return m_rules[rule_id]; + } + }; + // subsumption index structure. class index { @@ -286,6 +448,7 @@ namespace tb { app_ref_vector m_preds; expr_ref m_precond; expr_ref_vector m_sideconds; + ref m_goal; vector > m_index; matcher m_matcher; substitution m_subst; @@ -315,8 +478,9 @@ namespace tb { m_index.push_back(g); } - bool is_subsumed(goal const& g, unsigned& subsumer) { - setup(g); + bool is_subsumed(ref& g, unsigned& subsumer) { + setup(*g); + m_goal = g; m_solver.push(); m_solver.assert_expr(m_precond); bool found = find_match(subsumer); @@ -336,6 +500,10 @@ namespace tb { m_cancel = false; } + void reset() { + m_index.reset(); + } + private: void setup(goal const& g) { @@ -344,10 +512,7 @@ namespace tb { expr_ref_vector vars(m); expr_ref fml(m); ptr_vector sorts; - for (unsigned i = 0; i < g.get_num_predicates(); ++i) { - get_free_vars(g.get_predicate(i), sorts); - } - get_free_vars(g.get_constraint(), sorts); + g.get_free_vars(sorts); var_subst vs(m, false); for (unsigned i = 0; i < sorts.size(); ++i) { if (!sorts[i]) { @@ -375,7 +540,7 @@ namespace tb { bool find_match(unsigned& subsumer) { for (unsigned i = 0; !m_cancel && i < m_index.size(); ++i) { if (match_rule(i)) { - subsumer = m_index[i]->get_index(); + subsumer = m_index[i]->get_seqno(); return true; } } @@ -433,7 +598,9 @@ namespace tb { expr_ref_vector fmls(m_sideconds); m_subst.reset_cache(); - for (unsigned i = 0; i < fmls.size(); ++i) { + + + for (unsigned i = 0; !m_cancel && i < fmls.size(); ++i) { m_subst.apply(2, deltas, expr_offset(fmls[i].get(), 0), q); fmls[i] = q; } @@ -449,6 +616,9 @@ namespace tb { m_qe(m_empty_set, false, fmls); m_rw.mk_and(fmls.size(), fmls.c_ptr(), postcond); + if (m_cancel) { + return false; + } if (m.is_false(postcond)) { return false; } @@ -457,7 +627,11 @@ namespace tb { } if (!is_ground(postcond)) { IF_VERBOSE(1, verbose_stream() << "TBD: non-ground\n" - << mk_pp(postcond, m) << "\n";); + << mk_pp(postcond, m) << "\n"; + m_goal->display(verbose_stream()); + verbose_stream() << "\n=>\n"; + g.display(verbose_stream()); + verbose_stream() << "\n";); return false; } postcond = m.mk_not(postcond); @@ -473,34 +647,27 @@ namespace tb { class selection { datalog::context& m_ctx; ast_manager& m; - datalog::rule_manager& rm; datatype_util dt; obj_map m_scores; unsigned_vector m_score_values; - public: selection(datalog::context& ctx): m_ctx(ctx), m(ctx.get_manager()), - rm(ctx.get_rule_manager()), dt(m) { } - void init(datalog::rule_set const& rules) { + void init(rules const& rs) { m_scores.reset(); - goal g(rm); - datalog::rule_ref r(rm); - datalog::rule_set::iterator it = rules.begin(); - datalog::rule_set::iterator end = rules.end(); + rules::iterator it = rs.begin(), end = rs.end(); for (; it != end; ++it) { - r = *it; - g.init(r); - app* p = g.get_head(); + ref g = *it; + app* p = g->get_head(); unsigned_vector scores; score_predicate(p, scores); insert_score(p->get_decl(), scores); - } + } } unsigned select(goal const& g) { @@ -523,6 +690,11 @@ namespace tb { #endif } + void reset() { + m_scores.reset(); + m_score_values.reset(); + } + private: unsigned compute_score(func_decl* f, unsigned_vector const& scores) { @@ -573,6 +745,137 @@ namespace tb { } }; + class unifier { + ast_manager& m; + datalog::context& m_ctx; + datalog::rule_unifier m_unif; + ::unifier m_unifier; + substitution m_subst; + ref m_tgt; + ref m_src; + public: + unifier(ast_manager& m, datalog::context& ctx): + m(m), + m_ctx(ctx), + m_unif(ctx), + m_unifier(m), + m_subst(m) {} + + bool operator()(ref& tgt, ref& src, bool compute_subst, ref& result) { + unsigned idx = tgt->get_predicate_index(); + datalog::rule_ref res(m_ctx.get_rule_manager()); + datalog::rule const& t = tgt->get_rule(); + datalog::rule const& s = src->get_rule(); + SASSERT(t.get_decl(idx) == s.get_decl()); + + m_src = src; + m_tgt = tgt; + (void) compute_subst; + + if (m_unif.unify_rules(t, idx, s) && + m_unif.apply(t, idx, s, res)) { + result = alloc(goal, m_ctx.get_rule_manager()); + result->init(res); + + { + ref result2; + new_unify(*tgt, *src, compute_subst, result2); + } + return true; + } + else { + return false; + } + } + + expr_ref_vector get_rule_subst(bool is_tgt) { + return m_unif.get_rule_subst(is_tgt?m_tgt->get_rule():m_src->get_rule(), is_tgt); + } + + + bool new_unify(goal const& tgt, goal const& src, bool compute_subst, ref& result) { + + reset(); + unsigned idx = tgt.get_predicate_index(); + unsigned var_cnt = std::max(tgt.get_num_vars(), src.get_num_vars()); + m_subst.reserve(2, var_cnt); + + if (!m_unifier(tgt.get_predicate(idx), src.get_head(), m_subst)) { + return false; + } + + app_ref_vector predicates(m); + expr_ref tmp(m), tmp2(m), constraint(m); + app_ref head(m); + result = alloc(goal, m_ctx.get_rule_manager()); + unsigned delta[2] = { 0, var_cnt }; + m_subst.apply(2, delta, expr_offset(tgt.get_head(), 0), tmp); + head = to_app(tmp); + for (unsigned i = 0; i < tgt.get_num_predicates(); ++i) { + if (i != idx) { + m_subst.apply(2, delta, expr_offset(tgt.get_predicate(i), 0), tmp); + predicates.push_back(to_app(tmp)); + } + } + for (unsigned i = 0; i < src.get_num_predicates(); ++i) { + m_subst.apply(2, delta, expr_offset(src.get_predicate(i), 1), tmp); + predicates.push_back(to_app(tmp)); + } + m_subst.apply(2, delta, expr_offset(tgt.get_constraint(), 0), tmp); + m_subst.apply(2, delta, expr_offset(src.get_constraint(), 1), tmp2); + constraint = m.mk_and(tmp, tmp2); + ptr_vector vars; + result->init(head, predicates, constraint); + result->get_free_vars(vars); + substitution S2(m); + S2.reserve(1, vars.size()); + bool change = false; + for (unsigned i = 0, j = 0; i < vars.size(); ++i) { + if (vars[i]) { + if (i != j) { + var_ref v(m), w(m); + v = m.mk_var(i, vars[i]); + w = m.mk_var(j, vars[i]); + S2.insert(v, 0, expr_offset(w, 0)); + change = true; + } + ++j; + } + } + if (change) { + S2.apply(1, delta, expr_offset(result->get_constraint(), 0), constraint); + for (unsigned i = 0; i < result->get_num_predicates(); ++i) { + S2.apply(1, delta, expr_offset(result->get_predicate(i), 0), tmp); + predicates[i] = to_app(tmp); + } + S2.apply(1, delta, expr_offset(result->get_head(), 0), tmp); + head = to_app(tmp); + result->init(head, predicates, constraint); + } + if (compute_subst) { + ptr_vector vars1; + tgt.get_free_vars(vars1); + for (unsigned i = 0; i < vars1.size(); ++i) { + // TBD: + // apply the two substitutions after each-other. + } + } + + IF_VERBOSE(1, + verbose_stream() << "New unify:\n"; + result->display(verbose_stream());); + + // init result using head, predicates, constraint + return true; + } + + + private: + void reset() { + m_subst.reset(); + } + }; + enum instruction { SELECT_RULE, SELECT_PREDICATE, @@ -606,20 +909,22 @@ namespace datalog { unsigned m_num_subsumed; }; - context& m_ctx; - ast_manager& m; - rule_manager& rm; - tb::index m_index; - tb::selection m_selection; - smt_params m_fparams; - smt::kernel m_solver; - rule_unifier m_unifier; - rule_set m_rules; + context& m_ctx; + ast_manager& m; + rule_manager& rm; + tb::index m_index; + tb::selection m_selection; + smt_params m_fparams; + smt::kernel m_solver; + mutable tb::unifier m_unifier; + tb::rules m_rules; vector > m_goals; + unsigned m_seqno; tb::instruction m_instruction; - unsigned m_goal_index; - volatile bool m_cancel; - stats m_stats; + lbool m_status; + volatile bool m_cancel; + stats m_stats; + uint_set m_displayed_rules; public: imp(context& ctx): m_ctx(ctx), @@ -628,11 +933,12 @@ namespace datalog { m_index(ctx), m_selection(ctx), m_solver(m, m_fparams), - m_unifier(ctx), - m_rules(ctx), + m_unifier(m, ctx), + m_rules(), + m_seqno(0), m_instruction(tb::SELECT_PREDICATE), - m_cancel(false), - m_goal_index(0) + m_status(l_undef), + m_cancel(false) { // m_fparams.m_relevancy_lvl = 0; m_fparams.m_mbqi = false; @@ -643,15 +949,31 @@ namespace datalog { lbool query(expr* query) { m_ctx.ensure_opened(); - m_rules.reset(); - m_rules.add_rules(m_ctx.get_rules()); + m_index.reset(); + m_selection.reset(); + m_displayed_rules.reset(); + m_rules.init(m_ctx.get_rules()); m_selection.init(m_rules); rule_ref_vector query_rules(rm); rule_ref goal(rm); func_decl_ref query_pred(m); rm.mk_query(query, query_pred, query_rules, goal); - init_goal(goal); - IF_VERBOSE(1, display_goal(*get_goal(), verbose_stream() << "g" << get_goal()->get_index() << " ");); + + // ensure goal predicate does not take free variables. + ptr_vector tail; + svector is_neg; + for (unsigned i = 0; i < goal->get_tail_size(); ++i) { + tail.push_back(goal->get_tail(i)); + is_neg.push_back(goal->is_neg_tail(i)); + } + app_ref query_app(m); + query_app = m.mk_const(symbol("query"), m.mk_bool_sort()); + m_ctx.register_predicate(query_app->get_decl()); + goal = rm.mk(query_app, tail.size(), tail.c_ptr(), is_neg.c_ptr()); + ref g = alloc(tb::goal, rm); + g->init(goal); + init_goal(g); + IF_VERBOSE(1, display_goal(*get_goal(), verbose_stream() << "g" << get_goal()->get_seqno() << " ");); return run(); } @@ -667,20 +989,37 @@ namespace datalog { m_index.cleanup(); m_solver.reset_cancel(); } + void reset_statistics() { m_stats.reset(); } + void collect_statistics(statistics& st) const { st.update("tab.num_unfold", m_stats.m_num_unfold); st.update("tab.num_unfold_fail", m_stats.m_num_no_unfold); st.update("tab.num_subsumed", m_stats.m_num_subsumed); } + void display_certificate(std::ostream& out) const { - // TBD + expr_ref ans = get_answer(); + out << mk_pp(ans, m) << "\n"; } - expr_ref get_answer() { - // TBD - return expr_ref(0, m); + + expr_ref get_answer() const { + switch(m_status) { + case l_undef: + UNREACHABLE(); + return expr_ref(m.mk_false(), m); + case l_true: { + proof_ref pr = get_proof(); + return expr_ref(pr.get(), m); + } + case l_false: + // NOT_IMPLEMENTED_YET(); + return expr_ref(m.mk_true(), m); + } + UNREACHABLE(); + return expr_ref(m.mk_true(), m); } private: @@ -695,26 +1034,24 @@ namespace datalog { m_instruction = tb::SELECT_RULE; unsigned pi = m_selection.select(g); g.set_predicate_index(pi); - g.set_rule_index(0); IF_VERBOSE(2, verbose_stream() << mk_pp(g.get_predicate(pi), m) << "\n";); } } - void apply_rule(rule const& r) { + void apply_rule(ref& r) { ref goal = get_goal(); - rule const& query = goal->get_rule(); - rule_ref new_query(rm); - if (m_unifier.unify_rules(query, goal->get_predicate_index(), r) && - m_unifier.apply(query, goal->get_predicate_index(), r, new_query) && - l_false != query_is_sat(*new_query.get())) { - ref next_goal = init_goal(new_query); + ref next_goal; + if (m_unifier(goal, r, false, next_goal) && + l_false != query_is_sat(*next_goal)) { + init_goal(next_goal); unsigned subsumer = 0; IF_VERBOSE(1, display_rule(*goal, verbose_stream()); display_premise(*goal, - verbose_stream() << "g" << next_goal->get_index() << " "); - display_goal(*next_goal, verbose_stream());); - if (m_index.is_subsumed(*next_goal, subsumer)) { + verbose_stream() << "g" << next_goal->get_seqno() << " "); + display_goal(*next_goal, verbose_stream()); + ); + if (m_index.is_subsumed(next_goal, subsumer)) { IF_VERBOSE(1, verbose_stream() << "subsumed by g" << subsumer << "\n";); m_stats.m_num_subsumed++; m_goals.pop_back(); @@ -722,6 +1059,7 @@ namespace datalog { } else { m_stats.m_num_unfold++; + next_goal->set_parent(goal); m_index.insert(next_goal); m_instruction = tb::SELECT_PREDICATE; } @@ -734,16 +1072,17 @@ namespace datalog { void select_rule() { tb::goal& g = *get_goal(); + g.inc_next_rule(); unsigned pi = g.get_predicate_index(); func_decl* p = g.get_predicate(pi)->get_decl(); - rule_vector const& rules = m_rules.get_predicate_rules(p); - if (rules.size() <= g.get_rule_index()) { + unsigned num_rules = m_rules.get_num_rules(p); + unsigned index = g.get_next_rule(); + if (num_rules <= index) { m_instruction = tb::BACKTRACK; } else { - unsigned index = g.get_rule_index(); - g.inc_rule_index(); - apply_rule(*rules[index]); + ref rl = m_rules.get_rule(p, index); + apply_rule(rl); } } @@ -760,6 +1099,7 @@ namespace datalog { lbool run() { m_instruction = tb::SELECT_PREDICATE; + m_status = l_undef; while (true) { IF_VERBOSE(2, verbose_stream() << m_instruction << "\n";); if (m_cancel) { @@ -777,27 +1117,25 @@ namespace datalog { backtrack(); break; case tb::SATISFIABLE: + m_status = l_false; return l_false; case tb::UNSATISFIABLE: + m_status = l_true; + IF_VERBOSE(1, display_certificate(verbose_stream());); return l_true; case tb::CANCEL: cleanup(); + m_status = l_undef; return l_undef; } } } - lbool query_is_sat(rule const& query) { - expr_ref_vector fmls(m); - expr_ref fml(m); - unsigned utsz = query.get_uninterpreted_tail_size(); - unsigned tsz = query.get_tail_size(); - for (unsigned i = utsz; i < tsz; ++i) { - fmls.push_back(query.get_tail(i)); - } + lbool query_is_sat(tb::goal const& g) { ptr_vector sorts; svector names; - query.get_vars(sorts); + expr_ref fml = g.get_body(); + get_free_vars(fml, sorts); sorts.reverse(); for (unsigned i = 0; i < sorts.size(); ++i) { if (!sorts[i]) { @@ -805,7 +1143,6 @@ namespace datalog { } names.push_back(symbol(i)); } - fml = m.mk_and(fmls.size(), fmls.c_ptr()); if (!sorts.empty()) { fml = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), fml); } @@ -819,35 +1156,82 @@ namespace datalog { return is_sat; } - ref init_goal(rule_ref& new_query) { - ref goal = alloc(tb::goal, rm); - goal->init(new_query); - goal->set_index(m_goal_index++); + + void init_goal(ref& goal) { + goal->set_index(m_goals.size()); + goal->set_seqno(m_seqno++); m_goals.push_back(goal); - return goal; } ref get_goal() const { return m_goals.back(); } - hashtable m_displayed_rules; void display_rule(tb::goal const& p, std::ostream& out) { func_decl* f = p.get_predicate(p.get_predicate_index())->get_decl(); - rule_vector const& rules = m_rules.get_predicate_rules(f); - rule* r = rules[p.get_rule_index()-1]; - if (!m_displayed_rules.contains(r)) { - m_displayed_rules.insert(r); - r->display(m_ctx, out << p.get_rule_index() << ":"); + ref rl = m_rules.get_rule(f, p.get_next_rule()); + unsigned idx = rl->get_index(); + if (!m_displayed_rules.contains(idx)) { + m_displayed_rules.insert(idx); + rl->display(out << p.get_next_rule() << ":"); } } void display_premise(tb::goal& p, std::ostream& out) { func_decl* f = p.get_predicate(p.get_predicate_index())->get_decl(); - out << "{g" << p.get_index() << " " << f->get_name() << " pos: " << p.get_predicate_index() << " rule: " << p.get_rule_index() << "}\n"; + out << "{g" << p.get_seqno() << " " << f->get_name() << " pos: " << p.get_predicate_index() << " rule: " << p.get_next_rule() << "}\n"; } + void display_goal(tb::goal& g, std::ostream& out) { g.display(out); } + + proof_ref get_proof() const { + scoped_proof sp(m); + expr_ref root(m); + proof_ref pr(m); + proof_ref_vector prs(m); + expr_ref_vector subst(m); + ref goal = get_goal(); + ref replayed_goal; + replace_proof_converter pc(m); + + // goal is a empty clause. + // Pretend it is asserted. + // It gets replaced by premises. + SASSERT(goal->get_num_predicates() == 0); + goal->get_rule().to_formula(root); + + while (0 != goal->get_index()) { + SASSERT(goal->get_parent_index() < goal->get_index()); + unsigned p_index = goal->get_parent_index(); + unsigned p_rule = goal->get_parent_rule(); + ref parent = m_goals[p_index]; + unsigned pi = parent->get_predicate_index(); + func_decl* pred = parent->get_predicate(pi)->get_decl(); + ref rl = m_rules.get_rule(pred, p_rule); + VERIFY(m_unifier(parent, rl, true, replayed_goal)); + expr_ref_vector s1(m_unifier.get_rule_subst(true)); + expr_ref_vector s2(m_unifier.get_rule_subst(false)); + resolve_rule(&pc, parent->get_rule(), rl->get_rule(), pi, s1, s2, goal->get_rule()); + goal = parent; + IF_VERBOSE(1000, + verbose_stream() << "substitution\n"; + for (unsigned i = 0; i < s1.size(); ++i) { + verbose_stream() << mk_pp(s1[i].get(), m) << "\n"; + }); + // apply_subst(subst, s1); + } + pc.invert(); + prs.push_back(m.mk_asserted(root)); + pc(m, 1, prs.c_ptr(), pr); + IF_VERBOSE(1000, + verbose_stream() << "substitution\n"; + for (unsigned i = 0; i < subst.size(); ++i) { + verbose_stream() << mk_pp(subst[i].get(), m) << "\n"; + }); + return pr; + } + }; tab::tab(context& ctx): From 2d1afa7ba47e2806317c1e8c8ebd827c99145b71 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Jan 2013 19:36:41 -0800 Subject: [PATCH 032/101] stash --- src/muz_qe/tab_context.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index dd0874734..e30ddb6ea 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -278,6 +278,7 @@ namespace tb { } }; + // subsumption index structure. class index { ast_manager& m; From c89531bcf8f266ecb3c6ae41000a8d8521389bfd Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Jan 2013 21:44:42 -0800 Subject: [PATCH 033/101] working on tab-context Signed-off-by: Nikolaj Bjorner --- src/muz_qe/dl_util.cpp | 1 - src/muz_qe/tab_context.cpp | 347 ++++++++++++++++++++++--------------- 2 files changed, 204 insertions(+), 144 deletions(-) diff --git a/src/muz_qe/dl_util.cpp b/src/muz_qe/dl_util.cpp index 74b1a36dd..4a406578c 100644 --- a/src/muz_qe/dl_util.cpp +++ b/src/muz_qe/dl_util.cpp @@ -618,7 +618,6 @@ namespace datalog { expr_ref_vector const& s1, expr_ref_vector const& s2, rule const& res) { if (!pc) return; ast_manager& m = s1.get_manager(); - dl_decl_util util(m); expr_ref fml1(m), fml2(m), fml3(m); r1.to_formula(fml1); r2.to_formula(fml2); diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index 3d7b6a71f..a2c7e6215 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -148,8 +148,7 @@ namespace tb { } }; - class goal { - datalog::rule_ref m_goal; // goal as rule + class clause { app_ref m_head; // head predicate app_ref_vector m_predicates; // predicates used in goal expr_ref m_constraint; // side constraint @@ -164,8 +163,7 @@ namespace tb { public: - goal(datalog::rule_manager& rm): - m_goal(rm), + clause(datalog::rule_manager& rm): m_head(rm.get_manager()), m_predicates(rm.get_manager()), m_constraint(rm.get_manager()), @@ -188,14 +186,13 @@ namespace tb { unsigned get_num_predicates() const { return m_predicates.size(); } app* get_predicate(unsigned i) const { return m_predicates[i]; } expr* get_constraint() const { return m_constraint; } - datalog::rule const& get_rule() const { return *m_goal; } unsigned get_num_vars() const { return m_num_vars; } unsigned get_index() const { return m_index; } void set_index(unsigned index) { m_index = index; } app* get_head() const { return m_head; } unsigned get_parent_index() const { return m_parent_index; } unsigned get_parent_rule() const { return m_parent_rule; } - void set_parent(ref& parent) { + void set_parent(ref& parent) { m_parent_index = parent->get_index(); m_parent_rule = parent->get_next_rule(); } @@ -219,8 +216,28 @@ namespace tb { ::get_free_vars(m_constraint, vars); } + expr_ref to_formula() const { + ast_manager& m = get_manager(); + expr_ref body = get_body(); + body = m.mk_implies(body, m_head); + ptr_vector vars; + svector names; + get_free_vars(vars); + mk_fresh_name fresh; + fresh.add(body); + vars.reverse(); + for (unsigned i = 0; i < vars.size(); ++i) { + names.push_back(fresh.next()); + if (!vars[i]) vars[i] = m.mk_bool_sort(); + } + vars.reverse(); + if (!vars.empty()) { + body = m.mk_forall(vars.size(), vars.c_ptr(), names.c_ptr(), body); + } + return body; + } + void init(app* head, app_ref_vector const& predicates, expr* constraint) { - m_goal = 0; m_index = 0; m_predicate_index = 0; m_next_rule = static_cast(-1); @@ -235,7 +252,6 @@ namespace tb { } void init(datalog::rule_ref& g) { - m_goal = g; m_index = 0; m_predicate_index = 0; m_next_rule = static_cast(-1); @@ -294,7 +310,7 @@ namespace tb { bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), m_constraint); } - // Simplify a goal by applying equalities as substitutions on predicates. + // Simplify a clause by applying equalities as substitutions on predicates. // x = t[y], if x does not occur in t[y], then add t[y] to subst. void reduce_equalities() { ast_manager& m = get_manager(); @@ -388,11 +404,11 @@ namespace tb { // rules class rules { typedef obj_map map; - vector > m_rules; + vector > m_rules; map m_index; public: - typedef vector >::const_iterator iterator; + typedef vector >::const_iterator iterator; iterator begin() const { return m_rules.begin(); } iterator end() const { return m_rules.end(); } @@ -406,13 +422,13 @@ namespace tb { datalog::rule_set::iterator end = rules.end(); for (; it != end; ++it) { r = *it; - ref g = alloc(goal, rm); + ref g = alloc(clause, rm); g->init(r); insert(g); } } - void insert(ref& g) { + void insert(ref& g) { unsigned idx = m_rules.size(); m_rules.push_back(g); func_decl* f = g->get_head()->get_decl(); @@ -431,7 +447,7 @@ namespace tb { } } - ref get_rule(func_decl* p, unsigned idx) const { + ref get_rule(func_decl* p, unsigned idx) const { map::obj_map_entry* e = m_index.find_core(p); SASSERT(p); unsigned rule_id = e->get_data().get_value()[idx]; @@ -448,8 +464,8 @@ namespace tb { app_ref_vector m_preds; expr_ref m_precond; expr_ref_vector m_sideconds; - ref m_goal; - vector > m_index; + ref m_clause; + vector > m_index; matcher m_matcher; substitution m_subst; qe_lite m_qe; @@ -474,13 +490,13 @@ namespace tb { m_solver(m, m_fparams), m_cancel(false) {} - void insert(ref& g) { + void insert(ref& g) { m_index.push_back(g); } - bool is_subsumed(ref& g, unsigned& subsumer) { + bool is_subsumed(ref& g, unsigned& subsumer) { setup(*g); - m_goal = g; + m_clause = g; m_solver.push(); m_solver.assert_expr(m_precond); bool found = find_match(subsumer); @@ -506,7 +522,7 @@ namespace tb { private: - void setup(goal const& g) { + void setup(clause const& g) { m_preds.reset(); expr_ref_vector fmls(m); expr_ref_vector vars(m); @@ -551,7 +567,7 @@ namespace tb { // for now: skip multiple matches within the same rule (incomplete). // bool match_rule(unsigned rule_index) { - goal const& g = *m_index[rule_index]; + clause const& g = *m_index[rule_index]; m_sideconds.reset(); m_subst.reset(); m_subst.reserve(2, g.get_num_vars()); @@ -562,7 +578,7 @@ namespace tb { } - bool match_predicates(unsigned predicate_index, goal const& g) { + bool match_predicates(unsigned predicate_index, clause const& g) { if (predicate_index == g.get_num_predicates()) { return check_substitution(g); } @@ -592,14 +608,12 @@ namespace tb { return false; } - bool check_substitution(goal const& g) { + bool check_substitution(clause const& g) { unsigned deltas[2] = {0, 0}; expr_ref q(m), postcond(m); expr_ref_vector fmls(m_sideconds); m_subst.reset_cache(); - - for (unsigned i = 0; !m_cancel && i < fmls.size(); ++i) { m_subst.apply(2, deltas, expr_offset(fmls[i].get(), 0), q); fmls[i] = q; @@ -628,7 +642,7 @@ namespace tb { if (!is_ground(postcond)) { IF_VERBOSE(1, verbose_stream() << "TBD: non-ground\n" << mk_pp(postcond, m) << "\n"; - m_goal->display(verbose_stream()); + m_clause->display(verbose_stream()); verbose_stream() << "\n=>\n"; g.display(verbose_stream()); verbose_stream() << "\n";); @@ -662,7 +676,7 @@ namespace tb { m_scores.reset(); rules::iterator it = rs.begin(), end = rs.end(); for (; it != end; ++it) { - ref g = *it; + ref g = *it; app* p = g->get_head(); unsigned_vector scores; score_predicate(p, scores); @@ -670,7 +684,7 @@ namespace tb { } } - unsigned select(goal const& g) { + unsigned select(clause const& g) { return 0; #if 0 unsigned max_score = 0; @@ -748,87 +762,89 @@ namespace tb { class unifier { ast_manager& m; datalog::context& m_ctx; - datalog::rule_unifier m_unif; ::unifier m_unifier; - substitution m_subst; - ref m_tgt; - ref m_src; + substitution m_S1; + substitution m_S2; + expr_ref_vector m_sub1; + expr_ref_vector m_sub2; public: unifier(ast_manager& m, datalog::context& ctx): m(m), m_ctx(ctx), - m_unif(ctx), m_unifier(m), - m_subst(m) {} + m_S1(m), + m_S2(m), + m_sub1(m), + m_sub2(m) {} - bool operator()(ref& tgt, ref& src, bool compute_subst, ref& result) { + bool operator()(ref& tgt, ref& src, bool compute_subst, ref& result) { unsigned idx = tgt->get_predicate_index(); - datalog::rule_ref res(m_ctx.get_rule_manager()); - datalog::rule const& t = tgt->get_rule(); - datalog::rule const& s = src->get_rule(); - SASSERT(t.get_decl(idx) == s.get_decl()); - - m_src = src; - m_tgt = tgt; - (void) compute_subst; - - if (m_unif.unify_rules(t, idx, s) && - m_unif.apply(t, idx, s, res)) { - result = alloc(goal, m_ctx.get_rule_manager()); - result->init(res); - - { - ref result2; - new_unify(*tgt, *src, compute_subst, result2); - } - return true; - } - else { - return false; - } + return new_unify(*tgt, *src, compute_subst, result); } expr_ref_vector get_rule_subst(bool is_tgt) { - return m_unif.get_rule_subst(is_tgt?m_tgt->get_rule():m_src->get_rule(), is_tgt); + if (is_tgt) { + return m_sub1; + } + else { + return m_sub2; + } } - - bool new_unify(goal const& tgt, goal const& src, bool compute_subst, ref& result) { + bool new_unify(clause const& tgt, clause const& src, bool compute_subst, ref& result) { + qe_lite qe(m); reset(); unsigned idx = tgt.get_predicate_index(); + SASSERT(tgt.get_predicate(idx)->get_decl() == src.get_head()->get_decl()); unsigned var_cnt = std::max(tgt.get_num_vars(), src.get_num_vars()); - m_subst.reserve(2, var_cnt); - - if (!m_unifier(tgt.get_predicate(idx), src.get_head(), m_subst)) { + m_S1.reserve(2, var_cnt); + if (!m_unifier(tgt.get_predicate(idx), src.get_head(), m_S1)) { return false; } - app_ref_vector predicates(m); expr_ref tmp(m), tmp2(m), constraint(m); app_ref head(m); - result = alloc(goal, m_ctx.get_rule_manager()); + result = alloc(clause, m_ctx.get_rule_manager()); unsigned delta[2] = { 0, var_cnt }; - m_subst.apply(2, delta, expr_offset(tgt.get_head(), 0), tmp); + m_S1.apply(2, delta, expr_offset(tgt.get_head(), 0), tmp); head = to_app(tmp); for (unsigned i = 0; i < tgt.get_num_predicates(); ++i) { if (i != idx) { - m_subst.apply(2, delta, expr_offset(tgt.get_predicate(i), 0), tmp); + m_S1.apply(2, delta, expr_offset(tgt.get_predicate(i), 0), tmp); predicates.push_back(to_app(tmp)); } } for (unsigned i = 0; i < src.get_num_predicates(); ++i) { - m_subst.apply(2, delta, expr_offset(src.get_predicate(i), 1), tmp); + m_S1.apply(2, delta, expr_offset(src.get_predicate(i), 1), tmp); predicates.push_back(to_app(tmp)); } - m_subst.apply(2, delta, expr_offset(tgt.get_constraint(), 0), tmp); - m_subst.apply(2, delta, expr_offset(src.get_constraint(), 1), tmp2); - constraint = m.mk_and(tmp, tmp2); + m_S1.apply(2, delta, expr_offset(tgt.get_constraint(), 0), tmp); + m_S1.apply(2, delta, expr_offset(src.get_constraint(), 1), tmp2); + constraint = m.mk_and(tmp, tmp2); ptr_vector vars; + + // perform trival quantifier-elimination: + uint_set index_set; + get_free_vars(head, vars); + for (unsigned i = 0; i < predicates.size(); ++i) { + get_free_vars(predicates[i].get(), vars); + } + for (unsigned i = 0; i < vars.size(); ++i) { + if (vars[i]) { + index_set.insert(i); + } + } + qe(index_set, false, constraint); + if (m.is_false(constraint)) { + return false; + } + + // initialize rule. result->init(head, predicates, constraint); + vars.reset(); result->get_free_vars(vars); - substitution S2(m); - S2.reserve(1, vars.size()); + m_S2.reserve(1, vars.size()); bool change = false; for (unsigned i = 0, j = 0; i < vars.size(); ++i) { if (vars[i]) { @@ -836,29 +852,25 @@ namespace tb { var_ref v(m), w(m); v = m.mk_var(i, vars[i]); w = m.mk_var(j, vars[i]); - S2.insert(v, 0, expr_offset(w, 0)); + m_S2.insert(v, 0, expr_offset(w, 0)); change = true; } ++j; } } if (change) { - S2.apply(1, delta, expr_offset(result->get_constraint(), 0), constraint); + m_S2.apply(1, delta, expr_offset(result->get_constraint(), 0), constraint); for (unsigned i = 0; i < result->get_num_predicates(); ++i) { - S2.apply(1, delta, expr_offset(result->get_predicate(i), 0), tmp); + m_S2.apply(1, delta, expr_offset(result->get_predicate(i), 0), tmp); predicates[i] = to_app(tmp); } - S2.apply(1, delta, expr_offset(result->get_head(), 0), tmp); + m_S2.apply(1, delta, expr_offset(result->get_head(), 0), tmp); head = to_app(tmp); result->init(head, predicates, constraint); } if (compute_subst) { - ptr_vector vars1; - tgt.get_free_vars(vars1); - for (unsigned i = 0; i < vars1.size(); ++i) { - // TBD: - // apply the two substitutions after each-other. - } + extract_subst(delta, tgt, 0); + extract_subst(delta, src, 1); } IF_VERBOSE(1, @@ -872,7 +884,37 @@ namespace tb { private: void reset() { - m_subst.reset(); + m_S1.reset(); + m_S2.reset(); + m_sub1.reset(); + m_sub2.reset(); + } + + void extract_subst(unsigned const* delta, clause const& g, unsigned offset) { + ptr_vector vars; + var_ref v(m); + expr_ref tmp(m); + g.get_free_vars(vars); + for (unsigned i = 0; i < vars.size(); ++i) { + if (vars[i]) { + v = m.mk_var(i, vars[i]); + m_S1.apply(2, delta, expr_offset(v, offset), tmp); + m_S2.apply(1, delta, expr_offset(tmp, 0), tmp); + insert_subst(offset, tmp); + } + else { + insert_subst(offset, m.mk_true()); + } + } + } + + void insert_subst(unsigned offset, expr* e) { + if (offset == 0) { + m_sub1.push_back(e); + } + else { + m_sub2.push_back(e); + } } }; @@ -918,7 +960,7 @@ namespace datalog { smt::kernel m_solver; mutable tb::unifier m_unifier; tb::rules m_rules; - vector > m_goals; + vector > m_clauses; unsigned m_seqno; tb::instruction m_instruction; lbool m_status; @@ -955,25 +997,25 @@ namespace datalog { m_rules.init(m_ctx.get_rules()); m_selection.init(m_rules); rule_ref_vector query_rules(rm); - rule_ref goal(rm); + rule_ref clause(rm); func_decl_ref query_pred(m); - rm.mk_query(query, query_pred, query_rules, goal); + rm.mk_query(query, query_pred, query_rules, clause); - // ensure goal predicate does not take free variables. + // ensure clause predicate does not take free variables. ptr_vector tail; svector is_neg; - for (unsigned i = 0; i < goal->get_tail_size(); ++i) { - tail.push_back(goal->get_tail(i)); - is_neg.push_back(goal->is_neg_tail(i)); + for (unsigned i = 0; i < clause->get_tail_size(); ++i) { + tail.push_back(clause->get_tail(i)); + is_neg.push_back(clause->is_neg_tail(i)); } app_ref query_app(m); query_app = m.mk_const(symbol("query"), m.mk_bool_sort()); m_ctx.register_predicate(query_app->get_decl()); - goal = rm.mk(query_app, tail.size(), tail.c_ptr(), is_neg.c_ptr()); - ref g = alloc(tb::goal, rm); - g->init(goal); - init_goal(g); - IF_VERBOSE(1, display_goal(*get_goal(), verbose_stream() << "g" << get_goal()->get_seqno() << " ");); + clause = rm.mk(query_app, tail.size(), tail.c_ptr(), is_neg.c_ptr()); + ref g = alloc(tb::clause, rm); + g->init(clause); + init_clause(g); + IF_VERBOSE(1, display_clause(*get_clause(), verbose_stream() << "g" << get_clause()->get_seqno() << " ");); return run(); } @@ -985,7 +1027,7 @@ namespace datalog { void cleanup() { m_cancel = false; - m_goals.reset(); + m_clauses.reset(); m_index.cleanup(); m_solver.reset_cancel(); } @@ -1024,7 +1066,7 @@ namespace datalog { private: void select_predicate() { - tb::goal & g = *get_goal(); + tb::clause & g = *get_clause(); unsigned num_predicates = g.get_num_predicates(); if (num_predicates == 0) { m_instruction = tb::UNSATISFIABLE; @@ -1038,29 +1080,29 @@ namespace datalog { } } - void apply_rule(ref& r) { - ref goal = get_goal(); - ref next_goal; - if (m_unifier(goal, r, false, next_goal) && - l_false != query_is_sat(*next_goal)) { - init_goal(next_goal); + void apply_rule(ref& r) { + ref clause = get_clause(); + ref next_clause; + if (m_unifier(clause, r, false, next_clause) && + l_false != query_is_sat(*next_clause)) { + init_clause(next_clause); unsigned subsumer = 0; IF_VERBOSE(1, - display_rule(*goal, verbose_stream()); - display_premise(*goal, - verbose_stream() << "g" << next_goal->get_seqno() << " "); - display_goal(*next_goal, verbose_stream()); + display_rule(*clause, verbose_stream()); + display_premise(*clause, + verbose_stream() << "g" << next_clause->get_seqno() << " "); + display_clause(*next_clause, verbose_stream()); ); - if (m_index.is_subsumed(next_goal, subsumer)) { + if (m_index.is_subsumed(next_clause, subsumer)) { IF_VERBOSE(1, verbose_stream() << "subsumed by g" << subsumer << "\n";); m_stats.m_num_subsumed++; - m_goals.pop_back(); + m_clauses.pop_back(); m_instruction = tb::SELECT_RULE; } else { m_stats.m_num_unfold++; - next_goal->set_parent(goal); - m_index.insert(next_goal); + next_clause->set_parent(clause); + m_index.insert(next_clause); m_instruction = tb::SELECT_PREDICATE; } } @@ -1071,7 +1113,7 @@ namespace datalog { } void select_rule() { - tb::goal& g = *get_goal(); + tb::clause& g = *get_clause(); g.inc_next_rule(); unsigned pi = g.get_predicate_index(); func_decl* p = g.get_predicate(pi)->get_decl(); @@ -1081,15 +1123,15 @@ namespace datalog { m_instruction = tb::BACKTRACK; } else { - ref rl = m_rules.get_rule(p, index); + ref rl = m_rules.get_rule(p, index); apply_rule(rl); } } void backtrack() { - SASSERT(!m_goals.empty()); - m_goals.pop_back(); - if (m_goals.empty()) { + SASSERT(!m_clauses.empty()); + m_clauses.pop_back(); + if (m_clauses.empty()) { m_instruction = tb::SATISFIABLE; } else { @@ -1131,7 +1173,7 @@ namespace datalog { } } - lbool query_is_sat(tb::goal const& g) { + lbool query_is_sat(tb::clause const& g) { ptr_vector sorts; svector names; expr_ref fml = g.get_body(); @@ -1157,18 +1199,18 @@ namespace datalog { } - void init_goal(ref& goal) { - goal->set_index(m_goals.size()); - goal->set_seqno(m_seqno++); - m_goals.push_back(goal); + void init_clause(ref& clause) { + clause->set_index(m_clauses.size()); + clause->set_seqno(m_seqno++); + m_clauses.push_back(clause); } - ref get_goal() const { return m_goals.back(); } + ref get_clause() const { return m_clauses.back(); } - void display_rule(tb::goal const& p, std::ostream& out) { + void display_rule(tb::clause const& p, std::ostream& out) { func_decl* f = p.get_predicate(p.get_predicate_index())->get_decl(); - ref rl = m_rules.get_rule(f, p.get_next_rule()); + ref rl = m_rules.get_rule(f, p.get_next_rule()); unsigned idx = rl->get_index(); if (!m_displayed_rules.contains(idx)) { m_displayed_rules.insert(idx); @@ -1176,44 +1218,43 @@ namespace datalog { } } - void display_premise(tb::goal& p, std::ostream& out) { + void display_premise(tb::clause& p, std::ostream& out) { func_decl* f = p.get_predicate(p.get_predicate_index())->get_decl(); out << "{g" << p.get_seqno() << " " << f->get_name() << " pos: " << p.get_predicate_index() << " rule: " << p.get_next_rule() << "}\n"; } - void display_goal(tb::goal& g, std::ostream& out) { + void display_clause(tb::clause& g, std::ostream& out) { g.display(out); } proof_ref get_proof() const { scoped_proof sp(m); - expr_ref root(m); proof_ref pr(m); proof_ref_vector prs(m); expr_ref_vector subst(m); - ref goal = get_goal(); - ref replayed_goal; + ref clause = get_clause(); + ref replayed_clause; replace_proof_converter pc(m); - // goal is a empty clause. + // clause is a empty clause. // Pretend it is asserted. // It gets replaced by premises. - SASSERT(goal->get_num_predicates() == 0); - goal->get_rule().to_formula(root); + SASSERT(clause->get_num_predicates() == 0); + expr_ref root = clause->to_formula(); - while (0 != goal->get_index()) { - SASSERT(goal->get_parent_index() < goal->get_index()); - unsigned p_index = goal->get_parent_index(); - unsigned p_rule = goal->get_parent_rule(); - ref parent = m_goals[p_index]; + while (0 != clause->get_index()) { + SASSERT(clause->get_parent_index() < clause->get_index()); + unsigned p_index = clause->get_parent_index(); + unsigned p_rule = clause->get_parent_rule(); + ref parent = m_clauses[p_index]; unsigned pi = parent->get_predicate_index(); func_decl* pred = parent->get_predicate(pi)->get_decl(); - ref rl = m_rules.get_rule(pred, p_rule); - VERIFY(m_unifier(parent, rl, true, replayed_goal)); + ref rl = m_rules.get_rule(pred, p_rule); + VERIFY(m_unifier(parent, rl, true, replayed_clause)); expr_ref_vector s1(m_unifier.get_rule_subst(true)); expr_ref_vector s2(m_unifier.get_rule_subst(false)); - resolve_rule(&pc, parent->get_rule(), rl->get_rule(), pi, s1, s2, goal->get_rule()); - goal = parent; + resolve_rule(pc, *parent, *rl, s1, s2, *clause); + clause = parent; IF_VERBOSE(1000, verbose_stream() << "substitution\n"; for (unsigned i = 0; i < s1.size(); ++i) { @@ -1231,6 +1272,26 @@ namespace datalog { }); return pr; } + + void resolve_rule(replace_proof_converter& pc, tb::clause const& r1, tb::clause const& r2, + expr_ref_vector const& s1, expr_ref_vector const& s2, tb::clause const& res) const { + unsigned idx = r1.get_predicate_index(); + expr_ref fml1 = r1.to_formula(); + expr_ref fml2 = r2.to_formula(); + expr_ref fml3 = res.to_formula(); + vector substs; + svector > positions; + substs.push_back(s1); + substs.push_back(s2); + scoped_proof _sc(m); + proof_ref pr(m); + proof_ref_vector premises(m); + premises.push_back(m.mk_asserted(fml1)); + premises.push_back(m.mk_asserted(fml2)); + positions.push_back(std::make_pair(idx+1, 0)); + pr = m.mk_hyper_resolve(2, premises.c_ptr(), fml3, positions, substs); + pc.insert(pr); + } }; From afaef63bfa3915c3b2cb41ab8798c124cecf976e Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 24 Jan 2013 12:38:37 -0800 Subject: [PATCH 034/101] Fix compilation error when using gcc. Signed-off-by: Leonardo de Moura --- src/muz_qe/tab_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index a2c7e6215..e8e524d6d 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -852,7 +852,7 @@ namespace tb { var_ref v(m), w(m); v = m.mk_var(i, vars[i]); w = m.mk_var(j, vars[i]); - m_S2.insert(v, 0, expr_offset(w, 0)); + m_S2.insert(v.get(), 0, expr_offset(w, 0)); change = true; } ++j; From d3025569c2fc3c04b1ce07d7901ec7d1c74ebcc1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 24 Jan 2013 12:45:58 -0800 Subject: [PATCH 035/101] working on tab-context Signed-off-by: Nikolaj Bjorner --- src/muz_qe/dl_context.cpp | 3 +- src/muz_qe/tab_context.cpp | 95 ++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/muz_qe/dl_context.cpp b/src/muz_qe/dl_context.cpp index 8ef2ffa22..da702d4e3 100644 --- a/src/muz_qe/dl_context.cpp +++ b/src/muz_qe/dl_context.cpp @@ -1012,8 +1012,7 @@ namespace datalog { for (; it != end; ++it) { r = *it; check_rule(r); - } - + } switch(get_engine()) { case DATALOG_ENGINE: return rel_query(query); diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index a2c7e6215..35b15ae1b 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -190,6 +190,7 @@ namespace tb { unsigned get_index() const { return m_index; } void set_index(unsigned index) { m_index = index; } app* get_head() const { return m_head; } + void set_head(app* h) { m_head = h; } unsigned get_parent_index() const { return m_parent_index; } unsigned get_parent_rule() const { return m_parent_rule; } void set_parent(ref& parent) { @@ -200,12 +201,14 @@ namespace tb { expr_ref get_body() const { ast_manager& m = get_manager(); expr_ref_vector fmls(m); + expr_ref fml(m); for (unsigned i = 0; i < m_predicates.size(); ++i) { fmls.push_back(m_predicates[i]); } fmls.push_back(m_constraint); datalog::flatten_and(fmls); - return expr_ref(m.mk_and(fmls.size(), fmls.c_ptr()), m); + bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), fml); + return fml; } void get_free_vars(ptr_vector& vars) const { @@ -219,7 +222,12 @@ namespace tb { expr_ref to_formula() const { ast_manager& m = get_manager(); expr_ref body = get_body(); - body = m.mk_implies(body, m_head); + if (m.is_true(body)) { + body = m_head; + } + else { + body = m.mk_implies(body, m_head); + } ptr_vector vars; svector names; get_free_vars(vars); @@ -233,7 +241,7 @@ namespace tb { vars.reverse(); if (!vars.empty()) { body = m.mk_forall(vars.size(), vars.c_ptr(), names.c_ptr(), body); - } + } return body; } @@ -280,6 +288,14 @@ namespace tb { } fmls.push_back(m_constraint); bool_rewriter(m).mk_and(fmls.size(), fmls.c_ptr(), fml); + if (!m.is_false(m_head)) { + if (m.is_true(fml)) { + fml = m_head; + } + else { + fml = m.mk_implies(fml, m_head); + } + } out << mk_pp(fml, m) << "\n"; } @@ -420,10 +436,11 @@ namespace tb { datalog::rule_ref r(rm); datalog::rule_set::iterator it = rules.begin(); datalog::rule_set::iterator end = rules.end(); - for (; it != end; ++it) { + for (unsigned i = 0; it != end; ++it) { r = *it; ref g = alloc(clause, rm); g->init(r); + g->set_index(i++); insert(g); } } @@ -764,7 +781,8 @@ namespace tb { datalog::context& m_ctx; ::unifier m_unifier; substitution m_S1; - substitution m_S2; + var_subst m_S2; + expr_ref_vector m_rename; expr_ref_vector m_sub1; expr_ref_vector m_sub2; public: @@ -773,7 +791,8 @@ namespace tb { m_ctx(ctx), m_unifier(m), m_S1(m), - m_S2(m), + m_S2(m, false), + m_rename(m), m_sub1(m), m_sub2(m) {} @@ -844,27 +863,26 @@ namespace tb { result->init(head, predicates, constraint); vars.reset(); result->get_free_vars(vars); - m_S2.reserve(1, vars.size()); bool change = false; + var_ref w(m); for (unsigned i = 0, j = 0; i < vars.size(); ++i) { if (vars[i]) { - if (i != j) { - var_ref v(m), w(m); - v = m.mk_var(i, vars[i]); - w = m.mk_var(j, vars[i]); - m_S2.insert(v, 0, expr_offset(w, 0)); - change = true; - } + w = m.mk_var(j, vars[i]); + m_rename.push_back(w); ++j; } + else { + change = true; + m_rename.push_back(0); + } } if (change) { - m_S2.apply(1, delta, expr_offset(result->get_constraint(), 0), constraint); + m_S2(result->get_constraint(), m_rename.size(), m_rename.c_ptr(), constraint); for (unsigned i = 0; i < result->get_num_predicates(); ++i) { - m_S2.apply(1, delta, expr_offset(result->get_predicate(i), 0), tmp); + m_S2(result->get_predicate(i), m_rename.size(), m_rename.c_ptr(), tmp); predicates[i] = to_app(tmp); } - m_S2.apply(1, delta, expr_offset(result->get_head(), 0), tmp); + m_S2(result->get_head(), m_rename.size(), m_rename.c_ptr(), tmp); head = to_app(tmp); result->init(head, predicates, constraint); } @@ -872,11 +890,6 @@ namespace tb { extract_subst(delta, tgt, 0); extract_subst(delta, src, 1); } - - IF_VERBOSE(1, - verbose_stream() << "New unify:\n"; - result->display(verbose_stream());); - // init result using head, predicates, constraint return true; } @@ -886,6 +899,7 @@ namespace tb { void reset() { m_S1.reset(); m_S2.reset(); + m_rename.reset(); m_sub1.reset(); m_sub2.reset(); } @@ -899,7 +913,7 @@ namespace tb { if (vars[i]) { v = m.mk_var(i, vars[i]); m_S1.apply(2, delta, expr_offset(v, offset), tmp); - m_S2.apply(1, delta, expr_offset(tmp, 0), tmp); + m_S2(tmp, m_rename.size(), m_rename.c_ptr(), tmp); insert_subst(offset, tmp); } else { @@ -1001,19 +1015,9 @@ namespace datalog { func_decl_ref query_pred(m); rm.mk_query(query, query_pred, query_rules, clause); - // ensure clause predicate does not take free variables. - ptr_vector tail; - svector is_neg; - for (unsigned i = 0; i < clause->get_tail_size(); ++i) { - tail.push_back(clause->get_tail(i)); - is_neg.push_back(clause->is_neg_tail(i)); - } - app_ref query_app(m); - query_app = m.mk_const(symbol("query"), m.mk_bool_sort()); - m_ctx.register_predicate(query_app->get_decl()); - clause = rm.mk(query_app, tail.size(), tail.c_ptr(), is_neg.c_ptr()); ref g = alloc(tb::clause, rm); g->init(clause); + g->set_head(m.mk_false()); init_clause(g); IF_VERBOSE(1, display_clause(*get_clause(), verbose_stream() << "g" << get_clause()->get_seqno() << " ");); return run(); @@ -1214,7 +1218,7 @@ namespace datalog { unsigned idx = rl->get_index(); if (!m_displayed_rules.contains(idx)) { m_displayed_rules.insert(idx); - rl->display(out << p.get_next_rule() << ":"); + rl->display(out << "r" << p.get_next_rule() << ": "); } } @@ -1242,6 +1246,7 @@ namespace datalog { SASSERT(clause->get_num_predicates() == 0); expr_ref root = clause->to_formula(); + vector substs; while (0 != clause->get_index()) { SASSERT(clause->get_parent_index() < clause->get_index()); unsigned p_index = clause->get_parent_index(); @@ -1255,21 +1260,19 @@ namespace datalog { expr_ref_vector s2(m_unifier.get_rule_subst(false)); resolve_rule(pc, *parent, *rl, s1, s2, *clause); clause = parent; - IF_VERBOSE(1000, - verbose_stream() << "substitution\n"; - for (unsigned i = 0; i < s1.size(); ++i) { - verbose_stream() << mk_pp(s1[i].get(), m) << "\n"; - }); - // apply_subst(subst, s1); + substs.push_back(s1); } + for (unsigned i = substs.size(); i > 0; ) { + --i; + apply_subst(subst, substs[i]); + } + expr_ref body = clause->get_body(); + var_subst vs(m, false); + vs(body, subst.size(), subst.c_ptr(), body); + IF_VERBOSE(1, verbose_stream() << mk_pp(body, m) << "\n";); pc.invert(); prs.push_back(m.mk_asserted(root)); pc(m, 1, prs.c_ptr(), pr); - IF_VERBOSE(1000, - verbose_stream() << "substitution\n"; - for (unsigned i = 0; i < subst.size(); ++i) { - verbose_stream() << mk_pp(subst[i].get(), m) << "\n"; - }); return pr; } From 7eaa5562d8a94452e5eaff2a25c5386e77cec723 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 24 Jan 2013 12:51:03 -0800 Subject: [PATCH 036/101] Fix http://z3.codeplex.com/workitem/19 Signed-off-by: Leonardo de Moura --- RELEASE_NOTES | 2 ++ src/cmd_context/check_logic.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index a2257c610..3145d3b62 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -55,6 +55,8 @@ Version 4.3.2 - Fixed bug reported at http://stackoverflow.com/questions/14307692/unknown-when-using-defs +- Relax check_logic procedure. Now, it accepts coercions (to_real) automatically introduced by Z3. (Thanks to Paul Jackson). This is a fix for http://z3.codeplex.com/workitem/19. + Version 4.3.1 ============= diff --git a/src/cmd_context/check_logic.cpp b/src/cmd_context/check_logic.cpp index 820ef59a4..dfee148b5 100644 --- a/src/cmd_context/check_logic.cpp +++ b/src/cmd_context/check_logic.cpp @@ -228,6 +228,9 @@ struct check_logic::imp { bool is_int(expr * t) { if (m_a_util.is_uminus(t)) t = to_app(t)->get_arg(0); + // Take care of coercions automatically added by Z3 + if (m_a_util.is_to_real(t)) + t = to_app(t)->get_arg(0); return m_a_util.is_numeral(t); } From 711abc75fbf7d0aaa0516f598663e0e0f176329b Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 24 Jan 2013 13:22:28 -0800 Subject: [PATCH 037/101] Fix issue reported at http://z3.codeplex.com/workitem/14 Signed-off-by: Leonardo de Moura --- src/api/api_ast.cpp | 4 ++-- src/api/api_config_params.cpp | 4 ++-- src/api/api_log.cpp | 2 +- src/api/api_numeral.cpp | 38 +++++++++++++++++------------------ src/api/z3_api.h | 6 +++--- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index 404d9d9ac..81a716b12 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -38,6 +38,8 @@ Revision History: #include"scoped_timer.h" #include"pp_params.hpp" +extern bool is_numeral_sort(Z3_context c, Z3_sort ty); + extern "C" { Z3_symbol Z3_API Z3_mk_int_symbol(Z3_context c, int i) { @@ -313,8 +315,6 @@ extern "C" { Z3_CATCH_RETURN(""); } - extern bool is_numeral_sort(Z3_context c, Z3_sort ty); - Z3_ast_kind Z3_API Z3_get_ast_kind(Z3_context c, Z3_ast a) { Z3_TRY; LOG_Z3_get_ast_kind(c, a); diff --git a/src/api/api_config_params.cpp b/src/api/api_config_params.cpp index aaaabb7b2..48c2df4a9 100644 --- a/src/api/api_config_params.cpp +++ b/src/api/api_config_params.cpp @@ -43,7 +43,7 @@ extern "C" { } } - void Z3_API Z3_global_param_reset_all() { + void Z3_API Z3_global_param_reset_all(void) { memory::initialize(UINT_MAX); LOG_Z3_global_param_reset_all(); gparams::reset(); @@ -71,7 +71,7 @@ extern "C" { } } - Z3_config Z3_API Z3_mk_config() { + Z3_config Z3_API Z3_mk_config(void) { memory::initialize(UINT_MAX); LOG_Z3_mk_config(); Z3_config r = reinterpret_cast(alloc(context_params)); diff --git a/src/api/api_log.cpp b/src/api/api_log.cpp index 84c262a96..4a1ae27e5 100644 --- a/src/api/api_log.cpp +++ b/src/api/api_log.cpp @@ -44,7 +44,7 @@ extern "C" { _Z3_append_log(static_cast(str)); } - void Z3_API Z3_close_log() { + void Z3_API Z3_close_log(void) { if (g_z3_log != 0) { dealloc(g_z3_log); g_z3_log_enabled = false; diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 2660d9a01..d4a6587bc 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -24,27 +24,27 @@ Revision History: #include"bv_decl_plugin.h" #include"algebraic_numbers.h" +bool is_numeral_sort(Z3_context c, Z3_sort ty) { + sort * _ty = to_sort(ty); + family_id fid = _ty->get_family_id(); + if (fid != mk_c(c)->get_arith_fid() && + fid != mk_c(c)->get_bv_fid() && + fid != mk_c(c)->get_datalog_fid()) { + return false; + } + return true; +} + +bool check_numeral_sort(Z3_context c, Z3_sort ty) { + bool is_num = is_numeral_sort(c, ty); + if (!is_num) { + SET_ERROR_CODE(Z3_INVALID_ARG); + } + return is_num; +} + extern "C" { - bool is_numeral_sort(Z3_context c, Z3_sort ty) { - sort * _ty = to_sort(ty); - family_id fid = _ty->get_family_id(); - if (fid != mk_c(c)->get_arith_fid() && - fid != mk_c(c)->get_bv_fid() && - fid != mk_c(c)->get_datalog_fid()) { - return false; - } - return true; - } - - bool check_numeral_sort(Z3_context c, Z3_sort ty) { - bool is_num = is_numeral_sort(c, ty); - if (!is_num) { - SET_ERROR_CODE(Z3_INVALID_ARG); - } - return is_num; - } - Z3_ast Z3_API Z3_mk_numeral(Z3_context c, const char* n, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_numeral(c, n, ty); diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 410945235..ea3b05e40 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -1274,7 +1274,7 @@ extern "C" { def_API('Z3_global_param_reset_all', VOID, ()) */ - void Z3_API Z3_global_param_reset_all(); + void Z3_API Z3_global_param_reset_all(void); /** \brief Get a global (or module) parameter. @@ -1335,7 +1335,7 @@ extern "C" { def_API('Z3_mk_config', CONFIG, ()) */ - Z3_config Z3_API Z3_mk_config(); + Z3_config Z3_API Z3_mk_config(void); /** \brief Delete the given configuration object. @@ -4765,7 +4765,7 @@ END_MLAPI_EXCLUDE extra_API('Z3_close_log', VOID, ()) */ - void Z3_API Z3_close_log(); + void Z3_API Z3_close_log(void); /** \brief Enable/disable printing warning messages to the console. From 6dd4cb832be160128c3143ddcc06224ae47fda70 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 24 Jan 2013 16:42:34 -0800 Subject: [PATCH 038/101] Fix problem reported by Alex Horn Signed-off-by: Leonardo de Moura --- src/api/c++/z3++.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 7875e6ef3..5c1e6ca0c 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1644,11 +1644,6 @@ namespace z3 { }; -template class z3::ast_vector_tpl; -template class z3::ast_vector_tpl; -template class z3::ast_vector_tpl; -template class z3::ast_vector_tpl; - /*@}*/ /*@}*/ From a6cf5281eb9aa6f8a1ce63adaa8a4cd0bf81ccf3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 24 Jan 2013 19:20:08 -0800 Subject: [PATCH 039/101] working on tab context Signed-off-by: Nikolaj Bjorner --- src/muz_qe/tab_context.cpp | 109 ++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 38 deletions(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index 92fb9f5d4..d6864c8cf 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -238,7 +238,6 @@ namespace tb { names.push_back(fresh.next()); if (!vars[i]) vars[i] = m.mk_bool_sort(); } - vars.reverse(); if (!vars.empty()) { body = m.mk_forall(vars.size(), vars.c_ptr(), names.c_ptr(), body); } @@ -478,19 +477,22 @@ namespace tb { ast_manager& m; datalog::rule_manager& rm; datalog::context& m_ctx; - app_ref_vector m_preds; - expr_ref m_precond; - expr_ref_vector m_sideconds; - ref m_clause; - vector > m_index; - matcher m_matcher; - substitution m_subst; - qe_lite m_qe; - uint_set m_empty_set; - bool_rewriter m_rw; - smt_params m_fparams; - smt::kernel m_solver; - volatile bool m_cancel; + app_ref_vector m_preds; + app_ref m_head; + expr_ref m_precond; + expr_ref_vector m_sideconds; + ref m_clause; + vector > m_index; + matcher m_matcher; + expr_ref_vector m_refs; + obj_hashtable m_sat_lits; + substitution m_subst; + qe_lite m_qe; + uint_set m_empty_set; + bool_rewriter m_rw; + smt_params m_fparams; + smt::kernel m_solver; + volatile bool m_cancel; public: index(datalog::context& ctx): @@ -498,9 +500,11 @@ namespace tb { rm(ctx.get_rule_manager()), m_ctx(ctx), m_preds(m), + m_head(m), m_precond(m), m_sideconds(m), m_matcher(m), + m_refs(m), m_subst(m), m_qe(m), m_rw(m), @@ -541,6 +545,8 @@ namespace tb { void setup(clause const& g) { m_preds.reset(); + m_refs.reset(); + m_sat_lits.reset(); expr_ref_vector fmls(m); expr_ref_vector vars(m); expr_ref fml(m); @@ -553,6 +559,8 @@ namespace tb { } vars.push_back(m.mk_const(symbol(i), sorts[i])); } + vs(g.get_head(), vars.size(), vars.c_ptr(), fml); + m_head = to_app(fml); for (unsigned i = 0; i < g.get_num_predicates(); ++i) { vs(g.get_predicate(i), vars.size(), vars.c_ptr(), fml); m_preds.push_back(to_app(fml)); @@ -591,9 +599,15 @@ namespace tb { IF_VERBOSE(2, g.display(verbose_stream() << "try-match\n");); - return match_predicates(0, g); + return match_head(g); } + bool match_head(clause const& g) { + return + m_head->get_decl() == g.get_head()->get_decl() && + m_matcher(m_head, g.get_head(), m_subst, m_sideconds) && + match_predicates(0, g); + } bool match_predicates(unsigned predicate_index, clause const& g) { if (predicate_index == g.get_num_predicates()) { @@ -638,14 +652,15 @@ namespace tb { m_subst.apply(2, deltas, expr_offset(g.get_constraint(), 0), q); fmls.push_back(q); - IF_VERBOSE(2, - for (unsigned i = 0; i < g.get_num_predicates(); ++i) { - verbose_stream() << " "; - } - q = m.mk_and(fmls.size(), fmls.c_ptr()); - verbose_stream() << "check: " << mk_pp(q, m) << "\n";); m_qe(m_empty_set, false, fmls); + datalog::flatten_and(fmls); + for (unsigned i = 0; i < fmls.size(); ++i) { + expr_ref n = normalize(fmls[i].get()); + if (m_sat_lits.contains(n)) { + return false; + } + } m_rw.mk_and(fmls.size(), fmls.c_ptr(), postcond); if (m_cancel) { return false; @@ -656,6 +671,12 @@ namespace tb { if (m.is_true(postcond)) { return true; } + IF_VERBOSE(2, + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + verbose_stream() << " "; + } + verbose_stream() << "check: " << mk_pp(postcond, m, 7 + g.get_num_predicates()) << "\n";); + if (!is_ground(postcond)) { IF_VERBOSE(1, verbose_stream() << "TBD: non-ground\n" << mk_pp(postcond, m) << "\n"; @@ -669,9 +690,32 @@ namespace tb { m_solver.push(); m_solver.assert_expr(postcond); lbool is_sat = m_solver.check(); + if (is_sat == l_true) { + expr_ref tmp(m); + expr* n; + model_ref mdl; + m_solver.get_model(mdl); + for (unsigned i = 0; i < fmls.size(); ++i) { + n = fmls[i].get(); + if (mdl->eval(n, tmp) && m.is_false(tmp)) { + m_refs.push_back(normalize(n)); + m_sat_lits.insert(m_refs.back()); + } + } + } m_solver.pop(1); return is_sat == l_false; } + + expr_ref normalize(expr* e) { + expr* x, *y; + if (m.is_eq(e, x, y) && x->get_id() > y->get_id()) { + return expr_ref(m.mk_eq(y, x), m); + } + else { + return expr_ref(e, m); + } + } }; // predicate selection strategy. @@ -1086,7 +1130,7 @@ namespace datalog { ref clause = get_clause(); ref next_clause; if (m_unifier(clause, r, false, next_clause) && - l_false != query_is_sat(*next_clause)) { + !query_is_tautology(*next_clause)) { init_clause(next_clause); unsigned subsumer = 0; IF_VERBOSE(1, @@ -1175,21 +1219,9 @@ namespace datalog { } } - lbool query_is_sat(tb::clause const& g) { - ptr_vector sorts; - svector names; - expr_ref fml = g.get_body(); - get_free_vars(fml, sorts); - sorts.reverse(); - for (unsigned i = 0; i < sorts.size(); ++i) { - if (!sorts[i]) { - sorts[i] = m.mk_bool_sort(); - } - names.push_back(symbol(i)); - } - if (!sorts.empty()) { - fml = m.mk_exists(sorts.size(), sorts.c_ptr(), names.c_ptr(), fml); - } + bool query_is_tautology(tb::clause const& g) { + expr_ref fml = g.to_formula(); + fml = m.mk_not(fml); m_solver.push(); m_solver.assert_expr(fml); lbool is_sat = m_solver.check(); @@ -1197,7 +1229,8 @@ namespace datalog { TRACE("dl", tout << is_sat << ":\n" << mk_pp(fml, m) << "\n";); - return is_sat; + return l_false == is_sat; + } From a895506dac7513de516068a7ead80b871096a7e7 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 25 Jan 2013 09:29:03 -0800 Subject: [PATCH 040/101] Fix issue reported at http://stackoverflow.com/questions/14524316/z3-4-3-get-complete-model Signed-off-by: Leonardo de Moura --- RELEASE_NOTES | 2 ++ src/api/api_model.cpp | 3 ++- src/model/model_evaluator.cpp | 17 ++++++++--------- src/model/model_evaluator_params.pyg | 8 ++++++++ src/model/model_params.pyg | 2 +- 5 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 src/model/model_evaluator_params.pyg diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 3145d3b62..27c52140f 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -57,6 +57,8 @@ Version 4.3.2 - Relax check_logic procedure. Now, it accepts coercions (to_real) automatically introduced by Z3. (Thanks to Paul Jackson). This is a fix for http://z3.codeplex.com/workitem/19. +- Fixed http://stackoverflow.com/questions/14524316/z3-4-3-get-complete-model. + Version 4.3.1 ============= diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index f26ffeeba..f17f7a586 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -26,6 +26,7 @@ Revision History: #include"model_v2_pp.h" #include"model_smt2_pp.h" #include"model_params.hpp" +#include"model_evaluator_params.hpp" extern "C" { @@ -489,7 +490,7 @@ extern "C" { Z3_model m, Z3_ast t, Z3_ast * v) { - model_params p; + model_evaluator_params p; return Z3_model_eval(c, m, t, p.completion(), v); } diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp index dc4c20aa8..41bca940d 100644 --- a/src/model/model_evaluator.cpp +++ b/src/model/model_evaluator.cpp @@ -17,6 +17,7 @@ Revision History: --*/ #include"model.h" +#include"model_evaluator_params.hpp" #include"rewriter_types.h" #include"model_evaluator.h" #include"bool_rewriter.h" @@ -59,11 +60,12 @@ struct evaluator_cfg : public default_rewriter_cfg { updt_params(p); } - void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); - m_max_steps = p.get_uint("max_steps", UINT_MAX); - m_model_completion = p.get_bool("model_completion", false); - m_cache = p.get_bool("cache", true); + void updt_params(params_ref const & _p) { + model_evaluator_params p(_p); + m_max_memory = megabytes_to_bytes(p.max_memory()); + m_max_steps = p.max_steps(); + m_model_completion = p.completion(); + m_cache = p.cache(); } ast_manager & m() const { return m_model.get_manager(); } @@ -230,10 +232,7 @@ void model_evaluator::updt_params(params_ref const & p) { } void model_evaluator::get_param_descrs(param_descrs & r) { - insert_max_memory(r); - insert_max_steps(r); - r.insert("model_completion", CPK_BOOL, "(default: false) assigns an interpretation to symbols that are not intepreted by the model."); - r.insert("cache", CPK_BOOL, "(default: true) cache intermediate results."); + model_evaluator_params::collect_param_descrs(r); } void model_evaluator::set_model_completion(bool f) { diff --git a/src/model/model_evaluator_params.pyg b/src/model/model_evaluator_params.pyg new file mode 100644 index 000000000..b68d5c3ad --- /dev/null +++ b/src/model/model_evaluator_params.pyg @@ -0,0 +1,8 @@ +def_module_params('model_evaluator', + export=True, + params=(max_memory_param(), + max_steps_param(), + ('completion', BOOL, False, 'assigns an interptetation to symbols that do not have one in the current model, when evaluating expressions in the current model'), + ('cache', BOOL, True, 'cache intermediate results in the model evaluator') + )) + diff --git a/src/model/model_params.pyg b/src/model/model_params.pyg index 977538163..14e83952c 100644 --- a/src/model/model_params.pyg +++ b/src/model/model_params.pyg @@ -4,5 +4,5 @@ def_module_params('model', ('v1', BOOL, False, 'use Z3 version 1.x pretty printer'), ('v2', BOOL, False, 'use Z3 version 2.x (x <= 16) pretty printer'), ('compact', BOOL, False, 'try to compact function graph (i.e., function interpretations that are lookup tables)'), - ('completion', BOOL, False, 'assigns an interptetation to symbols that do not have one in the current model, when evaluating expressions in the current model'))) + )) From 8e2298c3275fd7d66b1443bb9c659825f8eae1c0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 25 Jan 2013 19:24:48 -0800 Subject: [PATCH 041/101] fix extraction of statistics for horn tactic Signed-off-by: Nikolaj Bjorner --- src/muz_qe/dl_context.cpp | 34 +++++++++++----------------------- src/muz_qe/horn_tactic.cpp | 6 ++++-- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/muz_qe/dl_context.cpp b/src/muz_qe/dl_context.cpp index da702d4e3..7c9d2c965 100644 --- a/src/muz_qe/dl_context.cpp +++ b/src/muz_qe/dl_context.cpp @@ -1167,32 +1167,20 @@ namespace datalog { if (m_bmc) { m_bmc->reset_statistics(); } + if (m_tab) { + m_tab->reset_statistics(); + } } void context::collect_statistics(statistics& st) const { - - switch(m_engine) { - case DATALOG_ENGINE: - break; - case PDR_ENGINE: - case QPDR_ENGINE: - if (m_pdr) { - m_pdr->collect_statistics(st); - } - break; - case BMC_ENGINE: - case QBMC_ENGINE: - if (m_bmc) { - m_bmc->collect_statistics(st); - } - break; - case TAB_ENGINE: - if (m_tab) { - m_tab->collect_statistics(st); - } - break; - default: - break; + if (m_pdr) { + m_pdr->collect_statistics(st); + } + if (m_bmc) { + m_bmc->collect_statistics(st); + } + if (m_tab) { + m_tab->collect_statistics(st); } } diff --git a/src/muz_qe/horn_tactic.cpp b/src/muz_qe/horn_tactic.cpp index 98b6130b8..0637148d6 100644 --- a/src/muz_qe/horn_tactic.cpp +++ b/src/muz_qe/horn_tactic.cpp @@ -240,6 +240,7 @@ class horn_tactic : public tactic { }; params_ref m_params; + statistics m_stats; imp * m_imp; public: horn_tactic(ast_manager & m, params_ref const & p): @@ -272,20 +273,21 @@ public: expr_dependency_ref & core) { (*m_imp)(in, result, mc, pc, core); } - virtual void collect_statistics(statistics & st) const { m_imp->collect_statistics(st); + st.copy(m_stats); } virtual void reset_statistics() { + m_stats.reset(); m_imp->reset_statistics(); } - virtual void cleanup() { ast_manager & m = m_imp->m; imp * d = m_imp; + d->collect_statistics(m_stats); #pragma omp critical (tactic_cancel) { m_imp = 0; From 77f58269edcdc4ebe0041483601bbd1e843ae38a Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 27 Jan 2013 10:19:54 -0800 Subject: [PATCH 042/101] Add html pretty printing mode for RCF package Signed-off-by: Leonardo de Moura --- src/api/api_rcf.cpp | 12 +- src/api/python/z3rcf.py | 9 +- src/api/z3_rcf.h | 8 +- src/math/interval/interval.h | 1 + src/math/interval/interval_def.h | 9 ++ src/math/realclosure/realclosure.cpp | 193 ++++++++++++++++----------- src/math/realclosure/realclosure.h | 6 +- src/util/ext_numeral.h | 12 ++ 8 files changed, 156 insertions(+), 94 deletions(-) diff --git a/src/api/api_rcf.cpp b/src/api/api_rcf.cpp index b325c4397..42558ba9e 100644 --- a/src/api/api_rcf.cpp +++ b/src/api/api_rcf.cpp @@ -98,13 +98,13 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_rcf_num Z3_API Z3_rcf_mk_infinitesimal(Z3_context c, Z3_string name) { + Z3_rcf_num Z3_API Z3_rcf_mk_infinitesimal(Z3_context c) { Z3_TRY; - LOG_Z3_rcf_mk_infinitesimal(c, name); + LOG_Z3_rcf_mk_infinitesimal(c); RESET_ERROR_CODE(); reset_rcf_cancel(c); rcnumeral r; - rcfm(c).mk_infinitesimal(name, r); + rcfm(c).mk_infinitesimal(r); RETURN_Z3(from_rcnumeral(r)); Z3_CATCH_RETURN(0); } @@ -268,13 +268,13 @@ extern "C" { Z3_CATCH_RETURN(Z3_FALSE); } - Z3_string Z3_API Z3_rcf_num_to_string(Z3_context c, Z3_rcf_num a, Z3_bool compact) { + Z3_string Z3_API Z3_rcf_num_to_string(Z3_context c, Z3_rcf_num a, Z3_bool compact, Z3_bool html) { Z3_TRY; - LOG_Z3_rcf_num_to_string(c, a, compact); + LOG_Z3_rcf_num_to_string(c, a, compact, html); RESET_ERROR_CODE(); reset_rcf_cancel(c); std::ostringstream buffer; - rcfm(c).display(buffer, to_rcnumeral(a), compact != 0); + rcfm(c).display(buffer, to_rcnumeral(a), compact != 0, html != 0); return mk_c(c)->mk_external_string(buffer.str()); Z3_CATCH_RETURN(""); } diff --git a/src/api/python/z3rcf.py b/src/api/python/z3rcf.py index b9c947b9f..66a6890c3 100644 --- a/src/api/python/z3rcf.py +++ b/src/api/python/z3rcf.py @@ -29,8 +29,10 @@ def E(ctx=None): return RCFNum(Z3_rcf_mk_e(ctx.ref()), ctx) def MkInfinitesimal(name="eps", ctx=None): + # Todo: remove parameter name. + # For now, we keep it for backward compatibility. ctx = z3._get_ctx(ctx) - return RCFNum(Z3_rcf_mk_infinitesimal(ctx.ref(), name), ctx) + return RCFNum(Z3_rcf_mk_infinitesimal(ctx.ref()), ctx) def MkRoots(p, ctx=None): ctx = z3._get_ctx(ctx) @@ -49,6 +51,7 @@ def MkRoots(p, ctx=None): return r class RCFNum: + html = False def __init__(self, num, ctx=None): # TODO: add support for converting AST numeral values into RCFNum if isinstance(num, RCFNumObj): @@ -65,10 +68,10 @@ class RCFNum: return self.ctx.ref() def __repr__(self): - return Z3_rcf_num_to_string(self.ctx_ref(), self.num, False) + return Z3_rcf_num_to_string(self.ctx_ref(), self.num, False, RCFNum.html) def compact_str(self): - return Z3_rcf_num_to_string(self.ctx_ref(), self.num, True) + return Z3_rcf_num_to_string(self.ctx_ref(), self.num, True, RCFNum.html) def __add__(self, other): v = _to_rcfnum(other, self.ctx) diff --git a/src/api/z3_rcf.h b/src/api/z3_rcf.h index 305033690..e2b4b7e05 100644 --- a/src/api/z3_rcf.h +++ b/src/api/z3_rcf.h @@ -64,9 +64,9 @@ extern "C" { /** \brief Return a new infinitesimal that is smaller than all elements in the Z3 field. - def_API('Z3_rcf_mk_infinitesimal', RCF_NUM, (_in(CONTEXT), _in(STRING))) + def_API('Z3_rcf_mk_infinitesimal', RCF_NUM, (_in(CONTEXT),)) */ - Z3_rcf_num Z3_API Z3_rcf_mk_infinitesimal(__in Z3_context c, __in Z3_string name); + Z3_rcf_num Z3_API Z3_rcf_mk_infinitesimal(__in Z3_context c); /** \brief Store in roots the roots of the polynomial a[n-1]*x^{n-1} + ... + a[0]. @@ -173,9 +173,9 @@ extern "C" { /** \brief Convert the RCF numeral into a string. - def_API('Z3_rcf_num_to_string', STRING, (_in(CONTEXT), _in(RCF_NUM), _in(BOOL))) + def_API('Z3_rcf_num_to_string', STRING, (_in(CONTEXT), _in(RCF_NUM), _in(BOOL), _in(BOOL))) */ - Z3_string Z3_API Z3_rcf_num_to_string(__in Z3_context c, __in Z3_rcf_num a, __in Z3_bool compact); + Z3_string Z3_API Z3_rcf_num_to_string(__in Z3_context c, __in Z3_rcf_num a, __in Z3_bool compact, __in Z3_bool html); /** \brief Convert the RCF numeral into a string in decimal notation. diff --git a/src/math/interval/interval.h b/src/math/interval/interval.h index 1fe797861..ed7654f01 100644 --- a/src/math/interval/interval.h +++ b/src/math/interval/interval.h @@ -231,6 +231,7 @@ public: bool contains(interval const & n, numeral const & v) const; void display(std::ostream & out, interval const & n) const; + void display_pp(std::ostream & out, interval const & n) const; bool check_invariant(interval const & n) const; diff --git a/src/math/interval/interval_def.h b/src/math/interval/interval_def.h index 51c1652d7..89d699f1f 100644 --- a/src/math/interval/interval_def.h +++ b/src/math/interval/interval_def.h @@ -643,6 +643,15 @@ void interval_manager::display(std::ostream & out, interval const & n) const out << (upper_is_open(n) ? ")" : "]"); } +template +void interval_manager::display_pp(std::ostream & out, interval const & n) const { + out << (lower_is_open(n) ? "(" : "["); + ::display_pp(out, m(), lower(n), lower_kind(n)); + out << ", "; + ::display_pp(out, m(), upper(n), upper_kind(n)); + out << (upper_is_open(n) ? ")" : "]"); +} + template bool interval_manager::check_invariant(interval const & n) const { if (::eq(m(), lower(n), lower_kind(n), upper(n), upper_kind(n))) { diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index dac4c8e09..8c6a1d232 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -298,26 +298,41 @@ namespace realclosure { struct transcendental : public extension { symbol m_name; + symbol m_pp_name; unsigned m_k; mk_interval & m_proc; - transcendental(unsigned idx, symbol const & n, mk_interval & p):extension(TRANSCENDENTAL, idx), m_name(n), m_k(0), m_proc(p) {} + transcendental(unsigned idx, symbol const & n, symbol const & pp_n, mk_interval & p): + extension(TRANSCENDENTAL, idx), m_name(n), m_pp_name(pp_n), m_k(0), m_proc(p) {} - void display(std::ostream & out) const { - out << m_name; + void display(std::ostream & out, bool pp = false) const { + if (pp) + out << m_pp_name; + else + out << m_name; } }; struct infinitesimal : public extension { symbol m_name; + symbol m_pp_name; - infinitesimal(unsigned idx, symbol const & n):extension(INFINITESIMAL, idx), m_name(n) {} + infinitesimal(unsigned idx, symbol const & n, symbol const & pp_n):extension(INFINITESIMAL, idx), m_name(n), m_pp_name(pp_n) {} - void display(std::ostream & out) const { - if (m_name.is_numerical()) - out << "eps!" << m_name.get_num(); - else - out << m_name; + void display(std::ostream & out, bool pp = false) const { + if (pp) { + if (m_pp_name.is_numerical()) + out << "ε" << m_pp_name.get_num() << ""; + else + out << m_pp_name; + + } + else { + if (m_name.is_numerical()) + out << "eps!" << m_name.get_num(); + else + out << m_name; + } } }; @@ -1266,9 +1281,9 @@ namespace realclosure { /** \brief Create a new infinitesimal. */ - void mk_infinitesimal(symbol const & n, numeral & r) { + void mk_infinitesimal(symbol const & n, symbol const & pp_n, numeral & r) { unsigned idx = next_infinitesimal_idx(); - infinitesimal * eps = alloc(infinitesimal, idx, n); + infinitesimal * eps = alloc(infinitesimal, idx, n, pp_n); m_extensions[extension::INFINITESIMAL].push_back(eps); set_lower(eps->interval(), mpbq(0)); @@ -1280,12 +1295,12 @@ namespace realclosure { SASSERT(depends_on_infinitesimals(r)); } - void mk_infinitesimal(char const * n, numeral & r) { - mk_infinitesimal(symbol(n), r); + void mk_infinitesimal(char const * n, char const * pp_n, numeral & r) { + mk_infinitesimal(symbol(n), symbol(pp_n), r); } void mk_infinitesimal(numeral & r) { - mk_infinitesimal(symbol(next_infinitesimal_idx()), r); + mk_infinitesimal(symbol(next_infinitesimal_idx()), symbol(next_infinitesimal_idx()), r); } void refine_transcendental_interval(transcendental * t) { @@ -1318,9 +1333,9 @@ namespace realclosure { } } - void mk_transcendental(symbol const & n, mk_interval & proc, numeral & r) { + void mk_transcendental(symbol const & n, symbol const & pp_n, mk_interval & proc, numeral & r) { unsigned idx = next_transcendental_idx(); - transcendental * t = alloc(transcendental, idx, n, proc); + transcendental * t = alloc(transcendental, idx, n, pp_n, proc); m_extensions[extension::TRANSCENDENTAL].push_back(t); while (contains_zero(t->interval())) { @@ -1332,12 +1347,12 @@ namespace realclosure { SASSERT(!depends_on_infinitesimals(r)); } - void mk_transcendental(char const * p, mk_interval & proc, numeral & r) { - mk_transcendental(symbol(p), proc, r); + void mk_transcendental(char const * p, char const * pp_n, mk_interval & proc, numeral & r) { + mk_transcendental(symbol(p), symbol(pp_n), proc, r); } void mk_transcendental(mk_interval & proc, numeral & r) { - mk_transcendental(symbol(next_transcendental_idx()), proc, r); + mk_transcendental(symbol(next_transcendental_idx()), symbol(next_transcendental_idx()), proc, r); } void mk_pi(numeral & r) { @@ -1345,7 +1360,7 @@ namespace realclosure { set(r, m_pi); } else { - mk_transcendental(symbol("pi"), m_mk_pi_interval, r); + mk_transcendental(symbol("pi"), symbol("π"), m_mk_pi_interval, r); m_pi = r.m_value; inc_ref(m_pi); } @@ -1356,7 +1371,7 @@ namespace realclosure { set(r, m_e); } else { - mk_transcendental(symbol("e"), m_mk_e_interval, r); + mk_transcendental(symbol("e"), symbol("e"), m_mk_e_interval, r); m_e = r.m_value; inc_ref(m_e); } @@ -5762,7 +5777,7 @@ namespace realclosure { } template - void display_polynomial(std::ostream & out, unsigned sz, value * const * p, DisplayVar const & display_var, bool compact) const { + void display_polynomial(std::ostream & out, unsigned sz, value * const * p, DisplayVar const & display_var, bool compact, bool pp) const { if (sz == 0) { out << "0"; return; @@ -5778,33 +5793,44 @@ namespace realclosure { else out << " + "; if (i == 0) - display(out, p[i], compact); + display(out, p[i], compact, pp); else { if (!is_rational_one(p[i])) { if (use_parenthesis(p[i])) { out << "("; - display(out, p[i], compact); - out << ")*"; + display(out, p[i], compact, pp); + out << ")"; + if (pp) + out << " "; + else + out << "*"; } else { - display(out, p[i], compact); - out << "*"; + display(out, p[i], compact, pp); + if (pp) + out << " "; + else + out << "*"; } } - display_var(out, compact); - if (i > 1) - out << "^" << i; + display_var(out, compact, pp); + if (i > 1) { + if (pp) + out << "" << i << ""; + else + out << "^" << i; + } } } } template - void display_polynomial(std::ostream & out, polynomial const & p, DisplayVar const & display_var, bool compact) const { - display_polynomial(out, p.size(), p.c_ptr(), display_var, compact); + void display_polynomial(std::ostream & out, polynomial const & p, DisplayVar const & display_var, bool compact, bool pp) const { + display_polynomial(out, p.size(), p.c_ptr(), display_var, compact, pp); } struct display_free_var_proc { - void operator()(std::ostream & out, bool compact) const { + void operator()(std::ostream & out, bool compact, bool pp) const { out << "x"; } }; @@ -5813,13 +5839,13 @@ namespace realclosure { imp const & m; extension * m_ref; display_ext_proc(imp const & _m, extension * r):m(_m), m_ref(r) {} - void operator()(std::ostream & out, bool compact) const { - m.display_ext(out, m_ref, compact); + void operator()(std::ostream & out, bool compact, bool pp) const { + m.display_ext(out, m_ref, compact, pp); } }; - void display_polynomial_expr(std::ostream & out, polynomial const & p, extension * ext, bool compact) const { - display_polynomial(out, p, display_ext_proc(*this, ext), compact); + void display_polynomial_expr(std::ostream & out, polynomial const & p, extension * ext, bool compact, bool pp) const { + display_polynomial(out, p, display_ext_proc(*this, ext), compact, pp); } static void display_poly_sign(std::ostream & out, int s) { @@ -5846,7 +5872,7 @@ namespace realclosure { out << "}"; } - void display_sign_conditions(std::ostream & out, sign_condition * sc, array const & qs, bool compact) const { + void display_sign_conditions(std::ostream & out, sign_condition * sc, array const & qs, bool compact, bool pp) const { bool first = true; out << "{"; while (sc) { @@ -5854,21 +5880,28 @@ namespace realclosure { first = false; else out << ", "; - display_polynomial(out, qs[sc->qidx()], display_free_var_proc(), compact); + display_polynomial(out, qs[sc->qidx()], display_free_var_proc(), compact, pp); display_poly_sign(out, sc->sign()); sc = sc->prev(); } out << "}"; } - void display_algebraic_def(std::ostream & out, algebraic * a, bool compact) const { + void display_interval(std::ostream & out, mpbqi const & i, bool pp) const { + if (pp) + bqim().display_pp(out, i); + else + bqim().display(out, i); + } + + void display_algebraic_def(std::ostream & out, algebraic * a, bool compact, bool pp) const { out << "root("; - display_polynomial(out, a->p(), display_free_var_proc(), compact); + display_polynomial(out, a->p(), display_free_var_proc(), compact, pp); out << ", "; - bqim().display(out, a->iso_interval()); + display_interval(out, a->iso_interval(), pp); out << ", "; if (a->sdt() != 0) - display_sign_conditions(out, a->sdt()->sc(a->sc_idx()), a->sdt()->qs(), compact); + display_sign_conditions(out, a->sdt()->sc(a->sc_idx()), a->sdt()->qs(), compact, pp); else out << "{}"; out << ")"; @@ -5878,28 +5911,33 @@ namespace realclosure { collect_algebraic_refs c; for (unsigned i = 0; i < n; i++) c.mark(p[i]); - display_polynomial(out, n, p, display_free_var_proc(), true); + display_polynomial(out, n, p, display_free_var_proc(), true, false); std::sort(c.m_found.begin(), c.m_found.end(), rank_lt_proc()); for (unsigned i = 0; i < c.m_found.size(); i++) { algebraic * ext = c.m_found[i]; out << "\n r!" << ext->idx() << " := "; - display_algebraic_def(out, ext, true); + display_algebraic_def(out, ext, true, false); } } - void display_ext(std::ostream & out, extension * r, bool compact) const { + void display_ext(std::ostream & out, extension * r, bool compact, bool pp) const { switch (r->knd()) { - case extension::TRANSCENDENTAL: to_transcendental(r)->display(out); break; - case extension::INFINITESIMAL: to_infinitesimal(r)->display(out); break; + case extension::TRANSCENDENTAL: to_transcendental(r)->display(out, pp); break; + case extension::INFINITESIMAL: to_infinitesimal(r)->display(out, pp); break; case extension::ALGEBRAIC: - if (compact) - out << "r!" << r->idx(); - else - display_algebraic_def(out, to_algebraic(r), compact); + if (compact) { + if (pp) + out << "α" << r->idx() << ""; + else + out << "r!" << r->idx(); + } + else { + display_algebraic_def(out, to_algebraic(r), compact, pp); + } } } - void display(std::ostream & out, value * v, bool compact) const { + void display(std::ostream & out, value * v, bool compact, bool pp=false) const { if (v == 0) out << "0"; else if (is_nz_rational(v)) @@ -5907,51 +5945,50 @@ namespace realclosure { else { rational_function_value * rf = to_rational_function(v); if (is_denominator_one(rf)) { - display_polynomial_expr(out, rf->num(), rf->ext(), compact); + display_polynomial_expr(out, rf->num(), rf->ext(), compact, pp); } else if (is_rational_one(rf->num())) { out << "1/("; - display_polynomial_expr(out, rf->den(), rf->ext(), compact); + display_polynomial_expr(out, rf->den(), rf->ext(), compact, pp); out << ")"; } else { out << "("; - display_polynomial_expr(out, rf->num(), rf->ext(), compact); + display_polynomial_expr(out, rf->num(), rf->ext(), compact, pp); out << ")/("; - display_polynomial_expr(out, rf->den(), rf->ext(), compact); + display_polynomial_expr(out, rf->den(), rf->ext(), compact, pp); out << ")"; } } } - void display_compact(std::ostream & out, value * a) const { + void display_compact(std::ostream & out, value * a, bool pp=false) const { collect_algebraic_refs c; c.mark(a); if (c.m_found.empty()) { - display(out, a, true); + display(out, a, true, pp); } else { std::sort(c.m_found.begin(), c.m_found.end(), rank_lt_proc()); out << "["; - display(out, a, true); + display(out, a, true, pp); for (unsigned i = 0; i < c.m_found.size(); i++) { algebraic * ext = c.m_found[i]; - out << "; r!" << ext->idx() << " := "; - display_algebraic_def(out, ext, true); + if (pp) + out << "; α" << ext->idx() << " := "; + else + out << "; r!" << ext->idx() << " := "; + display_algebraic_def(out, ext, true, pp); } out << "]"; } } - void display_compact(std::ostream & out, numeral const & a) const { - display_compact(out, a.m_value); - } - - void display(std::ostream & out, numeral const & a, bool compact=false) const { + void display(std::ostream & out, numeral const & a, bool compact=false, bool pp=false) const { if (compact) - display_compact(out, a); + display_compact(out, a.m_value, pp); else - display(out, a.m_value, false); + display(out, a.m_value, false, pp); } void display_non_rational_in_decimal(std::ostream & out, numeral const & a, unsigned precision) { @@ -5989,7 +6026,7 @@ namespace realclosure { if (is_zero(a)) out << "[0, 0]"; else - bqim().display(out, interval(a.m_value)); + display_interval(out, interval(a.m_value), false); } }; @@ -6029,16 +6066,16 @@ namespace realclosure { m_imp->del(a); } - void manager::mk_infinitesimal(char const * n, numeral & r) { - m_imp->mk_infinitesimal(n, r); + void manager::mk_infinitesimal(char const * n, char const * pp_n, numeral & r) { + m_imp->mk_infinitesimal(n, pp_n, r); } void manager::mk_infinitesimal(numeral & r) { m_imp->mk_infinitesimal(r); } - void manager::mk_transcendental(char const * n, mk_interval & proc, numeral & r) { - m_imp->mk_transcendental(n, proc, r); + void manager::mk_transcendental(char const * n, char const * pp_n, mk_interval & proc, numeral & r) { + m_imp->mk_transcendental(n, pp_n, proc, r); } void manager::mk_transcendental(mk_interval & proc, numeral & r) { @@ -6212,9 +6249,9 @@ namespace realclosure { return gt(a, _b); } - void manager::display(std::ostream & out, numeral const & a, bool compact) const { + void manager::display(std::ostream & out, numeral const & a, bool compact, bool pp) const { save_interval_ctx ctx(this); - m_imp->display(out, a, compact); + m_imp->display(out, a, compact, pp); } void manager::display_decimal(std::ostream & out, numeral const & a, unsigned precision) const { @@ -6234,7 +6271,7 @@ namespace realclosure { }; void pp(realclosure::manager::imp * imp, realclosure::polynomial const & p, realclosure::extension * ext) { - imp->display_polynomial_expr(std::cout, p, ext, false); + imp->display_polynomial_expr(std::cout, p, ext, false, false); std::cout << std::endl; } @@ -6278,6 +6315,6 @@ void pp(realclosure::manager::imp * imp, mpq const & n) { } void pp(realclosure::manager::imp * imp, realclosure::extension * x) { - imp->display_ext(std::cout, x, false); + imp->display_ext(std::cout, x, false, false); std::cout << std::endl; } diff --git a/src/math/realclosure/realclosure.h b/src/math/realclosure/realclosure.h index 2b70d3be0..2a1b0dc20 100644 --- a/src/math/realclosure/realclosure.h +++ b/src/math/realclosure/realclosure.h @@ -70,7 +70,7 @@ namespace realclosure { /** \brief Add a new infinitesimal to the current field. The new infinitesimal is smaller than any positive element in the field. */ - void mk_infinitesimal(char const * name, numeral & r); + void mk_infinitesimal(char const * name, char const * pp_name, numeral & r); void mk_infinitesimal(numeral & r); /** @@ -83,7 +83,7 @@ namespace realclosure { Then, we extend the field F with 1 - Pi. 1 - Pi is transcendental with respect to algebraic real numbers, but it is NOT transcendental with respect to F, since F contains Pi. */ - void mk_transcendental(char const * name, mk_interval & proc, numeral & r); + void mk_transcendental(char const * name, char const * pp_name, mk_interval & proc, numeral & r); void mk_transcendental(mk_interval & proc, numeral & r); /** @@ -252,7 +252,7 @@ namespace realclosure { bool ge(numeral const & a, mpq const & b) { return !lt(a, b); } bool ge(numeral const & a, mpz const & b) { return !lt(a, b); } - void display(std::ostream & out, numeral const & a, bool compact=false) const; + void display(std::ostream & out, numeral const & a, bool compact=false, bool pp=false) const; /** \brief Display a real number in decimal notation. diff --git a/src/util/ext_numeral.h b/src/util/ext_numeral.h index af4b7ac10..83d326243 100644 --- a/src/util/ext_numeral.h +++ b/src/util/ext_numeral.h @@ -332,4 +332,16 @@ void display(std::ostream & out, } } +template +void display_pp(std::ostream & out, + numeral_manager & m, + typename numeral_manager::numeral const & a, + ext_numeral_kind ak) { + switch (ak) { + case EN_MINUS_INFINITY: out << "-∞"; break; + case EN_NUMERAL: m.display(out, a); break; + case EN_PLUS_INFINITY: out << "+∞"; break; + } +} + #endif From 4624919786acd5bff68fdedafe108e06246438cd Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 27 Jan 2013 11:24:23 -0800 Subject: [PATCH 043/101] Improve html pretty printer for RCF package Signed-off-by: Leonardo de Moura --- src/api/python/z3rcf.py | 5 ++--- src/math/realclosure/realclosure.cpp | 4 ++-- src/util/ext_numeral.h | 2 +- src/util/mpbq.cpp | 8 ++++++++ src/util/mpbq.h | 1 + src/util/mpff.h | 1 + src/util/mpfx.h | 1 + src/util/mpq.h | 1 + 8 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/api/python/z3rcf.py b/src/api/python/z3rcf.py index 66a6890c3..84c724910 100644 --- a/src/api/python/z3rcf.py +++ b/src/api/python/z3rcf.py @@ -51,7 +51,6 @@ def MkRoots(p, ctx=None): return r class RCFNum: - html = False def __init__(self, num, ctx=None): # TODO: add support for converting AST numeral values into RCFNum if isinstance(num, RCFNumObj): @@ -68,10 +67,10 @@ class RCFNum: return self.ctx.ref() def __repr__(self): - return Z3_rcf_num_to_string(self.ctx_ref(), self.num, False, RCFNum.html) + return Z3_rcf_num_to_string(self.ctx_ref(), self.num, False, in_html_mode()) def compact_str(self): - return Z3_rcf_num_to_string(self.ctx_ref(), self.num, True, RCFNum.html) + return Z3_rcf_num_to_string(self.ctx_ref(), self.num, True, in_html_mode()) def __add__(self, other): v = _to_rcfnum(other, self.ctx) diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 8c6a1d232..87b1ef8a4 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -1300,7 +1300,7 @@ namespace realclosure { } void mk_infinitesimal(numeral & r) { - mk_infinitesimal(symbol(next_infinitesimal_idx()), symbol(next_infinitesimal_idx()), r); + mk_infinitesimal(symbol(next_infinitesimal_idx()+1), symbol(next_infinitesimal_idx()+1), r); } void refine_transcendental_interval(transcendental * t) { @@ -1352,7 +1352,7 @@ namespace realclosure { } void mk_transcendental(mk_interval & proc, numeral & r) { - mk_transcendental(symbol(next_transcendental_idx()), symbol(next_transcendental_idx()), proc, r); + mk_transcendental(symbol(next_transcendental_idx()+1), symbol(next_transcendental_idx()+1), proc, r); } void mk_pi(numeral & r) { diff --git a/src/util/ext_numeral.h b/src/util/ext_numeral.h index 83d326243..03a364bdb 100644 --- a/src/util/ext_numeral.h +++ b/src/util/ext_numeral.h @@ -339,7 +339,7 @@ void display_pp(std::ostream & out, ext_numeral_kind ak) { switch (ak) { case EN_MINUS_INFINITY: out << "-∞"; break; - case EN_NUMERAL: m.display(out, a); break; + case EN_NUMERAL: m.display_pp(out, a); break; case EN_PLUS_INFINITY: out << "+∞"; break; } } diff --git a/src/util/mpbq.cpp b/src/util/mpbq.cpp index ad2eae770..1ff7fb04d 100644 --- a/src/util/mpbq.cpp +++ b/src/util/mpbq.cpp @@ -399,6 +399,14 @@ void mpbq_manager::display(std::ostream & out, mpbq const & a) { out << "^" << a.m_k; } +void mpbq_manager::display_pp(std::ostream & out, mpbq const & a) { + out << m_manager.to_string(a.m_num); + if (a.m_k > 0) + out << "/2"; + if (a.m_k > 1) + out << "" << a.m_k << ""; +} + void mpbq_manager::display_smt2(std::ostream & out, mpbq const & a, bool decimal) { if (a.m_k == 0) { m_manager.display_smt2(out, a.m_num, decimal); diff --git a/src/util/mpbq.h b/src/util/mpbq.h index 3427ab59f..85332d02f 100644 --- a/src/util/mpbq.h +++ b/src/util/mpbq.h @@ -260,6 +260,7 @@ public: void display(std::ostream & out, mpbq const & a); + void display_pp(std::ostream & out, mpbq const & a); void display_decimal(std::ostream & out, mpbq const & a, unsigned prec = 8); /** \brief Display a in decimal while its digits match b digits. diff --git a/src/util/mpff.h b/src/util/mpff.h index 0295901c4..de71ec75e 100644 --- a/src/util/mpff.h +++ b/src/util/mpff.h @@ -464,6 +464,7 @@ public: void display_raw(std::ostream & out, mpff const & n) const; void display(std::ostream & out, mpff const & n) const; + void display_pp(std::ostream & out, mpff const & n) const { display(out, n); } void display_decimal(std::ostream & out, mpff const & n, unsigned prec=32, unsigned max_power=128) const; void display_smt2(std::ostream & out, mpff const & n, bool decimal=true) const; diff --git a/src/util/mpfx.h b/src/util/mpfx.h index 476da79e3..b4eeaebe6 100644 --- a/src/util/mpfx.h +++ b/src/util/mpfx.h @@ -382,6 +382,7 @@ public: unsigned prev_power_of_two(mpfx const & a); void display(std::ostream & out, mpfx const & n) const; + void display_pp(std::ostream & out, mpfx const & n) const { display(out, n); } void display_smt2(std::ostream & out, mpfx const & n) const; void display_decimal(std::ostream & out, mpfx const & n, unsigned prec = UINT_MAX) const; void display_raw(std::ostream & out, mpfx const & n) const; diff --git a/src/util/mpq.h b/src/util/mpq.h index 26a34aff6..0c94936ba 100644 --- a/src/util/mpq.h +++ b/src/util/mpq.h @@ -259,6 +259,7 @@ public: void display(std::ostream & out, mpz const & a) const { return mpz_manager::display(out, a); } void display(std::ostream & out, mpq const & a) const; + void display_pp(std::ostream & out, mpq const & a) const { display(out, a); } void display_smt2(std::ostream & out, mpz const & a, bool decimal) const { return mpz_manager::display_smt2(out, a, decimal); } From c482ede7ffaacc7d62de672c143af9783a9d8025 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 28 Jan 2013 09:09:29 -0800 Subject: [PATCH 044/101] Fix bug introduced last week, and detected in nightly regression tests Signed-off-by: Leonardo de Moura --- src/cmd_context/cmd_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 043dc45e6..b511786bf 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1415,7 +1415,7 @@ void cmd_context::validate_model() { params_ref p; p.set_uint("max_degree", UINT_MAX); // evaluate algebraic numbers of any degree. p.set_uint("sort_store", true); - p.set_bool("model_completion", true); + p.set_bool("completion", true); model_evaluator evaluator(*(md.get()), p); contains_array_op_proc contains_array(m()); { From 0eea0bea9a7159a02d018dc26596e1c0639117ee Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Jan 2013 10:37:31 -0800 Subject: [PATCH 045/101] update scoring function for tab context Signed-off-by: Nikolaj Bjorner --- src/muz_qe/fixedpoint_params.pyg | 3 +- src/muz_qe/tab_context.cpp | 270 ++++++++++++++++++++++++------- 2 files changed, 216 insertions(+), 57 deletions(-) diff --git a/src/muz_qe/fixedpoint_params.pyg b/src/muz_qe/fixedpoint_params.pyg index 61f993c0a..25e513b78 100644 --- a/src/muz_qe/fixedpoint_params.pyg +++ b/src/muz_qe/fixedpoint_params.pyg @@ -54,8 +54,9 @@ def_module_params('fixedpoint', "if true, finite_product_relation will attempt to avoid creating inner relation with empty signature " "by putting in half of the table columns, if it would have been empty otherwise"), ('print_answer', BOOL, False, 'print answer instance(s) to query'), - ('print_certificate', BOOL, False, 'print certificate for reacahbility or non-reachability'), + ('print_certificate', BOOL, False, 'print certificate for reachability or non-reachability'), ('print_statistics', BOOL, False, 'print statistics'), + ('tab_selection', SYMBOL, 'weight', 'selection method for tabular strategy: weight (default), first, var-use'), )) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index d6864c8cf..1e83244d1 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -28,6 +28,7 @@ Revision History: #include "th_rewriter.h" #include "datatype_decl_plugin.h" #include "for_each_expr.h" +#include "matcher.h" namespace tb { @@ -420,17 +421,17 @@ namespace tb { class rules { typedef obj_map map; vector > m_rules; - map m_index; + map m_index; public: + typedef vector >::const_iterator iterator; iterator begin() const { return m_rules.begin(); } iterator end() const { return m_rules.end(); } void init(datalog::rule_set const& rules) { - m_rules.reset(); - m_index.reset(); + reset(); datalog::rule_manager& rm = rules.get_rule_manager(); datalog::rule_ref r(rm); datalog::rule_set::iterator it = rules.begin(); @@ -453,7 +454,7 @@ namespace tb { e->get_data().m_value.push_back(idx); } - unsigned get_num_rules(func_decl* p) { + unsigned get_num_rules(func_decl* p) const { map::obj_map_entry* e = m_index.find_core(p); if (p) { return e->get_data().get_value().size(); @@ -463,12 +464,25 @@ namespace tb { } } + void get_decls(ptr_vector& decls) const { + map::iterator it = m_index.begin(); + map::iterator end = m_index.end(); + for (; it != end; ++it) { + decls.push_back(it->m_key); + } + } + ref get_rule(func_decl* p, unsigned idx) const { map::obj_map_entry* e = m_index.find_core(p); SASSERT(p); unsigned rule_id = e->get_data().get_value()[idx]; return m_rules[rule_id]; } + private: + void reset() { + m_rules.reset(); + m_index.reset(); + } }; @@ -720,102 +734,240 @@ namespace tb { // predicate selection strategy. class selection { + enum strategy { + WEIGHT_SELECT, + FIRST_SELECT, + VAR_USE_SELECT + }; + typedef svector double_vector; + typedef obj_map score_map; datalog::context& m_ctx; ast_manager& m; datatype_util dt; - obj_map m_scores; - unsigned_vector m_score_values; + score_map m_score_map; + double_vector m_scores; + double_vector m_var_scores; + strategy m_strategy; public: selection(datalog::context& ctx): m_ctx(ctx), m(ctx.get_manager()), dt(m) { + set_strategy(ctx.get_params().tab_selection()); } void init(rules const& rs) { - m_scores.reset(); + reset(); + double_vector& scores = m_scores; rules::iterator it = rs.begin(), end = rs.end(); for (; it != end; ++it) { ref g = *it; app* p = g->get_head(); - unsigned_vector scores; + scores.reset(); score_predicate(p, scores); insert_score(p->get_decl(), scores); } + normalize_scores(rs); } unsigned select(clause const& g) { + switch(m_strategy) { + case WEIGHT_SELECT: + return weight_select(g); + case FIRST_SELECT: + return trivial_select(g); + case VAR_USE_SELECT: + return andrei_select(g); + default: + return weight_select(g); + + } + } + + + void reset() { + m_score_map.reset(); + m_scores.reset(); + m_var_scores.reset(); + } + + private: + + // determine if constructors in p are matches by rules. + bool is_reductive(app* p, double_vector const& p_scores) { + func_decl* f = p->get_decl(); + score_map::obj_map_entry* e = m_score_map.find_core(p->get_decl()); + if (!e) { + return false; + } + double_vector const& scores = e->get_data().m_value; + SASSERT(scores.size() == p->get_num_args()); + bool has_reductive = false; + bool is_red = true; + for (unsigned i = 0; is_red && i < scores.size(); ++i) { + if (scores[i] >= 1) { + has_reductive = true; + is_red &= p_scores[i] >= 1; + } + } + return has_reductive && is_red; + } + + void set_strategy(symbol const& str) { + if (str == symbol("weight")) { + m_strategy = WEIGHT_SELECT; + } + else if (str == symbol("first")) { + m_strategy = FIRST_SELECT; + } + else if (str == symbol("var-use")) { + m_strategy = VAR_USE_SELECT; + } + else { + m_strategy = WEIGHT_SELECT; + } + } + + unsigned trivial_select(clause const& g) { return 0; -#if 0 - unsigned max_score = 0; + } + + unsigned andrei_select(clause const& g) { + score_variables(g); + double_vector& scores = m_scores; + double max_score = 0; unsigned result = 0; - unsigned_vector& scores = m_score_values; for (unsigned i = 0; i < g.get_num_predicates(); ++i) { scores.reset(); + double_vector p_scores; + double score = 0; app* p = g.get_predicate(i); score_predicate(p, scores); - unsigned score = compute_score(p->get_decl(), scores); + m_score_map.find(p->get_decl(), p_scores); + SASSERT(p_scores.empty() || p->get_num_args() == p_scores.size()); + p_scores.resize(p->get_num_args()); + for (unsigned j = 0; j < p->get_num_args(); ++j) { + if (is_var(p->get_arg(j))) { + unsigned idx = to_var(p->get_arg(j))->get_idx(); + score += m_var_scores[idx]; + } + else { + IF_VERBOSE(1, verbose_stream() << p_scores[j] << " " << scores[j] << "\n";); + score += p_scores[j]*scores[j]; + } + } + IF_VERBOSE(1, verbose_stream() << "score: " << mk_pp(p, m) << " " << score << "\n";); if (score > max_score) { max_score = score; result = i; } } - return result; -#endif + IF_VERBOSE(1, verbose_stream() << "select:" << result << "\n";); + + return result; } - void reset() { - m_scores.reset(); - m_score_values.reset(); - } - - private: - - unsigned compute_score(func_decl* f, unsigned_vector const& scores) { - unsigned_vector f_scores; - unsigned score = 0; - if (m_scores.find(f, f_scores)) { - SASSERT(f_scores.size() == scores.size()); - for (unsigned i = 0; i < scores.size(); ++i) { - score += scores[i]*f_scores[i]; + unsigned weight_select(clause const& g) { + double_vector& scores = m_scores; + double max_score = 0; + unsigned result = 0; + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + scores.reset(); + double score = 0; + app* p = g.get_predicate(i); + score_predicate(p, scores); + for (unsigned j = 0; j < scores.size(); ++j) { + score += scores[j]; + } + IF_VERBOSE(1, verbose_stream() << "score: " << mk_pp(p, m) << " " << score << "\n";); + if (score > max_score) { + max_score = score; + result = i; } } - // else there is no rule. - return score; + IF_VERBOSE(1, verbose_stream() << "select " << result << "\n";); + return result; } + + + void score_variables(clause const& g) { + m_var_scores.reset(); + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + app* p = g.get_predicate(i); + score_variables(p); + } + } + + void score_variables(app* p) { + score_map::obj_map_entry* e = m_score_map.find_core(p->get_decl()); + if (!e) { + return; + } + double_vector& scores = e->get_data().m_value; + for (unsigned i = 0; i < p->get_num_args(); ++i) { + if (is_var(p->get_arg(i))) { + unsigned idx = to_var(p->get_arg(i))->get_idx(); + if (m_var_scores.size() <= idx) { + m_var_scores.resize(idx+1); + } + m_var_scores[idx] += scores[i]; + } + } + } + + void normalize_scores(rules const& rs) { + ptr_vector decls; + rs.get_decls(decls); + for (unsigned i = 0; i < decls.size(); ++i) { + unsigned nr = rs.get_num_rules(decls[i]); + score_map::obj_map_entry& e = *m_score_map.find_core(decls[i]); + double_vector& scores = e.get_data().m_value; + for (unsigned j = 0; j < scores.size(); ++j) { + scores[j] = scores[j]/nr; + } + } + } + - void score_predicate(app* p, unsigned_vector& scores) { + void score_predicate(app* p, double_vector& scores) { for (unsigned i = 0; i < p->get_num_args(); ++i) { scores.push_back(score_argument(p->get_arg(i))); } } unsigned score_argument(expr* arg) { - if (is_var(arg)) { - return 0; - } - if (m.is_value(arg)) { - return 3; - } - if (is_app(arg) && dt.is_constructor(to_app(arg)->get_decl())) { - return 2; - } - return 1; + unsigned score = 0; + score_argument(arg, score, 20); + return score; } - void insert_score(func_decl* f, unsigned_vector const& scores) { - obj_map::obj_map_entry* e; - e = m_scores.find_core(f); + void score_argument(expr* arg, unsigned& score, unsigned max_score) { + if (score < max_score && is_app(arg)) { + app* a = to_app(arg); + if (dt.is_constructor(a->get_decl())) { + score += 1; + for (unsigned i = 0; i < a->get_num_args(); ++i) { + score_argument(a->get_arg(i), score, max_score); + } + } + else if (m.is_value(a)) { + ++score; + } + } + } + + void insert_score(func_decl* f, double_vector const& scores) { + score_map::obj_map_entry* e = m_score_map.find_core(f); if (e) { - unsigned_vector & old_scores = e->get_data().m_value; + double_vector & old_scores = e->get_data().m_value; SASSERT(scores.size() == old_scores.size()); for (unsigned i = 0; i < scores.size(); ++i) { old_scores[i] += scores[i]; } } else { - m_scores.insert(f, scores); + m_score_map.insert(f, scores); } } }; @@ -1255,7 +1407,8 @@ namespace datalog { void display_premise(tb::clause& p, std::ostream& out) { func_decl* f = p.get_predicate(p.get_predicate_index())->get_decl(); - out << "{g" << p.get_seqno() << " " << f->get_name() << " pos: " << p.get_predicate_index() << " rule: " << p.get_next_rule() << "}\n"; + out << "{g" << p.get_seqno() << " " << f->get_name() << " pos: " + << p.get_predicate_index() << " rule: " << p.get_next_rule() << "}\n"; } void display_clause(tb::clause& g, std::ostream& out) { @@ -1266,7 +1419,6 @@ namespace datalog { scoped_proof sp(m); proof_ref pr(m); proof_ref_vector prs(m); - expr_ref_vector subst(m); ref clause = get_clause(); ref replayed_clause; replace_proof_converter pc(m); @@ -1293,20 +1445,26 @@ namespace datalog { clause = parent; substs.push_back(s1); } - for (unsigned i = substs.size(); i > 0; ) { - --i; - apply_subst(subst, substs[i]); - } - expr_ref body = clause->get_body(); - var_subst vs(m, false); - vs(body, subst.size(), subst.c_ptr(), body); - IF_VERBOSE(1, verbose_stream() << mk_pp(body, m) << "\n";); + IF_VERBOSE(1, display_body_insts(substs, *clause, verbose_stream());); + pc.invert(); prs.push_back(m.mk_asserted(root)); pc(m, 1, prs.c_ptr(), pr); return pr; } + void display_body_insts(vector const& substs, tb::clause const& clause, std::ostream& out) const { + expr_ref_vector subst(m); + for (unsigned i = substs.size(); i > 0; ) { + --i; + apply_subst(subst, substs[i]); + } + expr_ref body = clause.get_body(); + var_subst vs(m, false); + vs(body, subst.size(), subst.c_ptr(), body); + out << mk_pp(body, m) << "\n"; + } + void resolve_rule(replace_proof_converter& pc, tb::clause const& r1, tb::clause const& r2, expr_ref_vector const& s1, expr_ref_vector const& s2, tb::clause const& res) const { unsigned idx = r1.get_predicate_index(); From 4a570503808007f8f31a11b298d3d91fb8cd4a32 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 28 Jan 2013 15:26:48 -0800 Subject: [PATCH 046/101] Fix rcf test Signed-off-by: Leonardo de Moura --- src/test/rcf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/rcf.cpp b/src/test/rcf.cpp index 5bef0dfef..d6cfd8b86 100644 --- a/src/test/rcf.cpp +++ b/src/test/rcf.cpp @@ -32,7 +32,7 @@ static void tst1() { #endif scoped_rcnumeral eps(m); - m.mk_infinitesimal("eps", eps); + m.mk_infinitesimal(eps); mpq aux; qm.set(aux, 1, 3); m.set(a, aux); @@ -151,7 +151,7 @@ static void tst_denominators() { scoped_rcnumeral eps(m); m.mk_pi(a); m.inv(a); - m.mk_infinitesimal("eps", eps); + m.mk_infinitesimal(eps); t = (a - eps*2) / (a*eps + 1); // t = t + a * 2; scoped_rcnumeral n(m), d(m); From 3ae01cf619cbaf707446ac3fc13bde878beee411 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 28 Jan 2013 17:29:55 -0800 Subject: [PATCH 047/101] Fix cygwin (with python 2.6) compilation problems. Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 7 +++++-- src/math/realclosure/mpz_matrix.cpp | 12 ++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 205b8f948..875cf449f 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1617,8 +1617,11 @@ PYG_GLOBALS = { 'UINT' : UINT, 'BOOL' : BOOL, 'DOUBLE' : DOUBLE, 'STRING' : STRI 'def_module_params' : def_module_params } def _execfile(file, globals=globals(), locals=locals()): - with open(file, "r") as fh: - exec(fh.read()+"\n", globals, locals) + if sys.version < "2.7": + execfile(file, globals, locals) + else: + with open(file, "r") as fh: + exec(fh.read()+"\n", globals, locals) # Execute python auxiliary scripts that generate extra code for Z3. def exec_pyg_scripts(): diff --git a/src/math/realclosure/mpz_matrix.cpp b/src/math/realclosure/mpz_matrix.cpp index ba89dfb36..799a5817e 100644 --- a/src/math/realclosure/mpz_matrix.cpp +++ b/src/math/realclosure/mpz_matrix.cpp @@ -75,14 +75,14 @@ void mpz_matrix_manager::set(mpz_matrix & A, mpz_matrix const & B) { } void mpz_matrix_manager::tensor_product(mpz_matrix const & A, mpz_matrix const & B, mpz_matrix & C) { - scoped_mpz_matrix _C(*this); - mk(A.m * B.m, A.n * B.n, _C); - for (unsigned i = 0; i < _C.m(); i++) - for (unsigned j = 0; j < _C.n(); j++) + scoped_mpz_matrix CC(*this); + mk(A.m * B.m, A.n * B.n, CC); + for (unsigned i = 0; i < CC.m(); i++) + for (unsigned j = 0; j < CC.n(); j++) nm().mul(A(i / B.m, j / B.n), B(i % B.m, j % B.n), - _C(i, j)); - C.swap(_C); + CC(i, j)); + C.swap(CC); } void mpz_matrix_manager::swap_rows(mpz_matrix & A, unsigned i, unsigned j) { From b33e144699617b177ff1b13475530d9981d58e60 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 30 Jan 2013 08:32:14 -0800 Subject: [PATCH 048/101] Add parallel option to mk_win_dist Signed-off-by: Leonardo de Moura --- scripts/mk_win_dist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_win_dist.py b/scripts/mk_win_dist.py index dd50a3977..ac85a9c43 100644 --- a/scripts/mk_win_dist.py +++ b/scripts/mk_win_dist.py @@ -91,7 +91,7 @@ def check_build_dir(path): # Create a build directory using mk_make.py def mk_build_dir(path, x64): if not check_build_dir(path) or FORCE_MK: - opts = ["python", os.path.join('scripts', 'mk_make.py'), "-b", path] + opts = ["python", os.path.join('scripts', 'mk_make.py'), "--parallel=24", "-b", path] if JAVA_ENABLED: opts.append('--java') if x64: From 27b1f8d1b387df3f7068a529b544524e52098feb Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 30 Jan 2013 08:59:36 -0800 Subject: [PATCH 049/101] Add option --githash to mk_win_dist Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 10 ++++++++++ scripts/mk_win_dist.py | 30 ++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 875cf449f..a9b3af1cb 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -74,6 +74,16 @@ VS_PAR=False VS_PAR_NUM=8 GPROF=False +def git_hash(): + try: + r = subprocess.check_output(['git', 'show-ref', '--abbrev=12', 'HEAD'], shell=True).rstrip('\r\n') + except: + raise MKException("Failed to retrieve git hash") + ls = r.split(' ') + if len(ls) != 2: + raise MKException("Unexpected git output") + return ls[0] + def is_windows(): return IS_WINDOWS diff --git a/scripts/mk_win_dist.py b/scripts/mk_win_dist.py index ac85a9c43..a8c4fd3ba 100644 --- a/scripts/mk_win_dist.py +++ b/scripts/mk_win_dist.py @@ -25,6 +25,7 @@ VERBOSE=True DIST_DIR='dist' FORCE_MK=False JAVA_ENABLED=True +GIT_HASH=False def set_verbose(flag): global VERBOSE @@ -55,17 +56,19 @@ def display_help(): print " -b , --build= subdirectory where x86 and x64 Z3 versions will be built (default: build-dist)." print " -f, --force force script to regenerate Makefiles." print " --nojava do not include Java bindings in the binary distribution files." + print " --githash include git hash in the Zip file." exit(0) # Parse configuration option for mk_make script def parse_options(): - global FORCE_MK, JAVA_ENABLED + global FORCE_MK, JAVA_ENABLED, GIT_HASH path = BUILD_DIR options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=', 'help', 'silent', 'force', - 'nojava' + 'nojava', + 'githash' ]) for opt, arg in options: if opt in ('-b', '--build'): @@ -80,6 +83,8 @@ def parse_options(): FORCE_MK = True elif opt == '--nojava': JAVA_ENABLED = False + elif opt == '--githash': + GIT_HASH = True else: raise MKException("Invalid command line option '%s'" % opt) set_build_dir(path) @@ -147,15 +152,25 @@ def mk_z3(): mk_z3_core(False) mk_z3_core(True) -def mk_dist_dir_core(x64): +def get_z3_name(x64): major, minor, build, revision = get_version() + if x64: + platform = "x64" + else: + platform = "x86" + if GIT_HASH: + return 'z3-%s.%s.%s.%s-%s' % (major, minor, build, mk_util.git_hash(), platform) + else: + return 'z3-%s.%s.%s-%s' % (major, minor, build, platform) + +def mk_dist_dir_core(x64): if x64: platform = "x64" build_path = BUILD_X64_DIR else: platform = "x86" build_path = BUILD_X86_DIR - dist_path = os.path.join(DIST_DIR, 'z3-%s.%s.%s-%s' % (major, minor, build, platform)) + dist_path = os.path.join(DIST_DIR, get_z3_name(x64)) mk_dir(dist_path) if JAVA_ENABLED: # HACK: Propagate JAVA_ENABLED flag to mk_util @@ -179,12 +194,7 @@ def mk_zip_visitor(pattern, dir, files): ZIPOUT.write(fname) def get_dist_path(x64): - major, minor, build, revision = get_version() - if x64: - platform = "x64" - else: - platform = "x86" - return 'z3-%s.%s.%s-%s' % (major, minor, build, platform) + return get_z3_name(x64) def mk_zip_core(x64): global ZIPOUT From b0a4d3c00d3ef5a85e50c1a6fdc0a881e40a2316 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 30 Jan 2013 09:14:19 -0800 Subject: [PATCH 050/101] Add win to Z3 windows binary dist zip file Signed-off-by: Leonardo de Moura --- scripts/mk_win_dist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mk_win_dist.py b/scripts/mk_win_dist.py index a8c4fd3ba..961425101 100644 --- a/scripts/mk_win_dist.py +++ b/scripts/mk_win_dist.py @@ -159,9 +159,9 @@ def get_z3_name(x64): else: platform = "x86" if GIT_HASH: - return 'z3-%s.%s.%s.%s-%s' % (major, minor, build, mk_util.git_hash(), platform) + return 'z3-win-%s.%s.%s.%s-%s' % (major, minor, build, mk_util.git_hash(), platform) else: - return 'z3-%s.%s.%s-%s' % (major, minor, build, platform) + return 'z3-win-%s.%s.%s-%s' % (major, minor, build, platform) def mk_dist_dir_core(x64): if x64: From affea51c2196ceceaad05504929bdffdfb25b193 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 30 Jan 2013 11:12:40 -0800 Subject: [PATCH 051/101] fix compilation warning Signed-off-by: Nikolaj Bjorner --- src/muz_qe/tab_context.cpp | 127 +++++++++++++++++++++++++++++-------- 1 file changed, 100 insertions(+), 27 deletions(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index 1e83244d1..ee6692d6c 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -424,7 +424,6 @@ namespace tb { map m_index; public: - typedef vector >::const_iterator iterator; iterator begin() const { return m_rules.begin(); } @@ -489,8 +488,6 @@ namespace tb { // subsumption index structure. class index { ast_manager& m; - datalog::rule_manager& rm; - datalog::context& m_ctx; app_ref_vector m_preds; app_ref m_head; expr_ref m_precond; @@ -509,10 +506,8 @@ namespace tb { volatile bool m_cancel; public: - index(datalog::context& ctx): - m(ctx.get_manager()), - rm(ctx.get_rule_manager()), - m_ctx(ctx), + index(ast_manager& m): + m(m), m_preds(m), m_head(m), m_precond(m), @@ -736,11 +731,13 @@ namespace tb { class selection { enum strategy { WEIGHT_SELECT, + BASIC_WEIGHT_SELECT, FIRST_SELECT, VAR_USE_SELECT }; typedef svector double_vector; typedef obj_map score_map; + typedef obj_map pred_map; datalog::context& m_ctx; ast_manager& m; datatype_util dt; @@ -748,12 +745,24 @@ namespace tb { double_vector m_scores; double_vector m_var_scores; strategy m_strategy; + pred_map m_pred_map; + expr_ref_vector m_refs; + double m_weight_multiply; + unsigned m_num_invocations; + unsigned m_update_frequency; + unsigned m_next_update; + public: selection(datalog::context& ctx): m_ctx(ctx), m(ctx.get_manager()), - dt(m) { + dt(m), + m_refs(m), + m_weight_multiply(1.0), + m_num_invocations(0), + m_update_frequency(20), + m_next_update(20) { set_strategy(ctx.get_params().tab_selection()); } @@ -765,7 +774,7 @@ namespace tb { ref g = *it; app* p = g->get_head(); scores.reset(); - score_predicate(p, scores); + basic_score_predicate(p, scores); insert_score(p->get_decl(), scores); } normalize_scores(rs); @@ -775,6 +784,8 @@ namespace tb { switch(m_strategy) { case WEIGHT_SELECT: return weight_select(g); + case BASIC_WEIGHT_SELECT: + return basic_weight_select(g); case FIRST_SELECT: return trivial_select(g); case VAR_USE_SELECT: @@ -785,7 +796,6 @@ namespace tb { } } - void reset() { m_score_map.reset(); m_scores.reset(); @@ -797,7 +807,7 @@ namespace tb { // determine if constructors in p are matches by rules. bool is_reductive(app* p, double_vector const& p_scores) { func_decl* f = p->get_decl(); - score_map::obj_map_entry* e = m_score_map.find_core(p->get_decl()); + score_map::obj_map_entry* e = m_score_map.find_core(f); if (!e) { return false; } @@ -818,6 +828,9 @@ namespace tb { if (str == symbol("weight")) { m_strategy = WEIGHT_SELECT; } + if (str == symbol("basic-weight")) { + m_strategy = BASIC_WEIGHT_SELECT; + } else if (str == symbol("first")) { m_strategy = FIRST_SELECT; } @@ -843,7 +856,7 @@ namespace tb { double_vector p_scores; double score = 0; app* p = g.get_predicate(i); - score_predicate(p, scores); + basic_score_predicate(p, scores); m_score_map.find(p->get_decl(), p_scores); SASSERT(p_scores.empty() || p->get_num_args() == p_scores.size()); p_scores.resize(p->get_num_args()); @@ -853,11 +866,11 @@ namespace tb { score += m_var_scores[idx]; } else { - IF_VERBOSE(1, verbose_stream() << p_scores[j] << " " << scores[j] << "\n";); + IF_VERBOSE(2, verbose_stream() << p_scores[j] << " " << scores[j] << "\n";); score += p_scores[j]*scores[j]; } } - IF_VERBOSE(1, verbose_stream() << "score: " << mk_pp(p, m) << " " << score << "\n";); + IF_VERBOSE(2, verbose_stream() << "score: " << mk_pp(p, m) << " " << score << "\n";); if (score > max_score) { max_score = score; result = i; @@ -868,25 +881,36 @@ namespace tb { return result; } - unsigned weight_select(clause const& g) { - double_vector& scores = m_scores; + unsigned basic_weight_select(clause const& g) { double max_score = 0; unsigned result = 0; for (unsigned i = 0; i < g.get_num_predicates(); ++i) { - scores.reset(); - double score = 0; app* p = g.get_predicate(i); - score_predicate(p, scores); - for (unsigned j = 0; j < scores.size(); ++j) { - score += scores[j]; - } - IF_VERBOSE(1, verbose_stream() << "score: " << mk_pp(p, m) << " " << score << "\n";); + double score = basic_score_predicate(p); + IF_VERBOSE(2, verbose_stream() << "score: " << mk_pp(p, m) << " " << score << "\n";); if (score > max_score) { max_score = score; result = i; } } - IF_VERBOSE(1, verbose_stream() << "select " << result << "\n";); + IF_VERBOSE(2, verbose_stream() << "select " << result << "\n";); + return result; + } + + unsigned weight_select(clause const& g) { + prepare_weight_select(); + double max_score = 0; + unsigned result = 0; + for (unsigned i = 0; i < g.get_num_predicates(); ++i) { + app* p = g.get_predicate(i); + double score = score_predicate(p); + IF_VERBOSE(2, verbose_stream() << "score: " << mk_pp(p, m) << " " << score << "\n";); + if (score > max_score) { + max_score = score; + result = i; + } + } + IF_VERBOSE(2, verbose_stream() << "select " << result << "\n";); return result; } @@ -929,13 +953,34 @@ namespace tb { } } - - void score_predicate(app* p, double_vector& scores) { + double basic_score_predicate(app* p) { + double score = 1; + for (unsigned i = 0; i < p->get_num_args(); ++i) { + score += score_argument(p->get_arg(i)); + } + return score; + } + + void basic_score_predicate(app* p, double_vector& scores) { for (unsigned i = 0; i < p->get_num_args(); ++i) { scores.push_back(score_argument(p->get_arg(i))); } } + + double score_predicate(app* p) { + double score = 1; + if (find_score(p, score)) { + return score; + } + for (unsigned i = 0; i < p->get_num_args(); ++i) { + score += score_argument(p->get_arg(i)); + } + score = adjust_score(score); + insert_score(p, score); + return score; + } + unsigned score_argument(expr* arg) { unsigned score = 0; score_argument(arg, score, 20); @@ -957,6 +1002,34 @@ namespace tb { } } + void prepare_weight_select() { + SASSERT(m_next_update > 0); + --m_next_update; + if (m_next_update == 0) { + if (m_update_frequency >= (1 << 16)) { + m_update_frequency = 20; + m_weight_multiply = 1.0; + } + m_update_frequency *= 11; + m_update_frequency /= 10; + m_next_update = m_update_frequency; + m_weight_multiply *= 1.1; + } + } + + bool find_score(app* p, double& score) { + return m_pred_map.find(p, score); + } + + double adjust_score(double score) { + return score/m_weight_multiply; + } + + void insert_score(app* p, double score) { + m_pred_map.insert(p, score); + m_refs.push_back(p); + } + void insert_score(func_decl* f, double_vector const& scores) { score_map::obj_map_entry* e = m_score_map.find_core(f); if (e) { @@ -1180,7 +1253,7 @@ namespace datalog { m_ctx(ctx), m(ctx.get_manager()), rm(ctx.get_rule_manager()), - m_index(ctx), + m_index(m), m_selection(ctx), m_solver(m, m_fparams), m_unifier(m, ctx), From c051876e3f92058186459a61f00cb0ebaa75dee0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 31 Jan 2013 12:49:43 +0000 Subject: [PATCH 052/101] FPA bugfix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/fpa2bv_converter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tactic/fpa/fpa2bv_converter.cpp b/src/tactic/fpa/fpa2bv_converter.cpp index 41871f3e1..4afdc501f 100644 --- a/src/tactic/fpa/fpa2bv_converter.cpp +++ b/src/tactic/fpa/fpa2bv_converter.cpp @@ -1641,7 +1641,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref SASSERT(is_well_sorted(m, is_sig_zero)); SASSERT(is_well_sorted(m, lz)); SASSERT(is_well_sorted(m, shift)); - if (ebits > sbits) { + if (ebits < sbits) { expr_ref q(m); q = m_bv_util.mk_zero_extend(sbits-ebits, shift); denormal_sig = m_bv_util.mk_bv_shl(denormal_sig, q); From 3c9c7574f7f4b33baddbac6e31daa7df0b076c83 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 31 Jan 2013 17:32:07 -0800 Subject: [PATCH 053/101] add release mode to vs build, work on delta extraction Signed-off-by: Nikolaj Bjorner --- scripts/mk_util.py | 41 +++++++++++++++++ src/muz_qe/tab_context.cpp | 90 ++++++++++++++++++++++++++++++++++---- 2 files changed, 123 insertions(+), 8 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index a9b3af1cb..98d9ad6f8 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2298,6 +2298,10 @@ def mk_vs_proj(name, components): f.write(' Debug\n') f.write(' Win32\n') f.write(' \n') + f.write(' \n') + f.write(' Release\n') + f.write(' Win32\n') + f.write(' \n') f.write(' \n') f.write(' \n') f.write(' {%s}\n' % mk_gui_str(0)) @@ -2320,6 +2324,9 @@ def mk_vs_proj(name, components): f.write(' $(SolutionDir)$(Configuration)\\n') f.write(' %s\n' % name) f.write(' .exe\n') + f.write(' $(SolutionDir)$(Configuration)\\n') + f.write(' %s\n' % name) + f.write(' .exe\n') f.write(' \n') f.write(' \n') f.write(' \n') @@ -2355,6 +2362,40 @@ def mk_vs_proj(name, components): f.write('psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)\n') f.write(' \n') f.write(' \n') + f.write(' \n') + f.write(' \n') + f.write(' Disabled\n') + f.write(' WIN32;_NDEBUG;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)\n') + f.write(' true\n') + f.write(' EnableFastChecks\n') + f.write(' Level3\n') + f.write(' MultiThreadedDLL\n') + f.write(' true\n') + f.write(' ProgramDatabase\n') + f.write(' ') + deps = find_all_deps(name, components) + first = True + for dep in deps: + if first: + first = False + else: + f.write(';') + f.write(get_component(dep).to_src_dir) + f.write('\n') + f.write(' \n') + f.write(' \n') + f.write(' $(OutDir)%s.exe\n' % name) + f.write(' true\n') + f.write(' Console\n') + f.write(' 8388608\n') + f.write(' false\n') + f.write(' \n') + f.write(' \n') + f.write(' MachineX86\n') + f.write(' %(AdditionalLibraryDirectories)\n') + f.write('psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)\n') + f.write(' \n') + f.write(' \n') f.write(' \n') for dep in deps: dep = get_component(dep) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index ee6692d6c..333a96de0 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -164,10 +164,10 @@ namespace tb { public: - clause(datalog::rule_manager& rm): - m_head(rm.get_manager()), - m_predicates(rm.get_manager()), - m_constraint(rm.get_manager()), + clause(ast_manager& m): + m_head(m), + m_predicates(m), + m_constraint(m), m_seqno(0), m_index(0), m_num_vars(0), @@ -437,7 +437,7 @@ namespace tb { datalog::rule_set::iterator end = rules.end(); for (unsigned i = 0; it != end; ++it) { r = *it; - ref g = alloc(clause, rm); + ref g = alloc(clause, rm.get_manager()); g->init(r); g->set_index(i++); insert(g); @@ -455,7 +455,7 @@ namespace tb { unsigned get_num_rules(func_decl* p) const { map::obj_map_entry* e = m_index.find_core(p); - if (p) { + if (e) { return e->get_data().get_value().size(); } else { @@ -727,6 +727,7 @@ namespace tb { } }; + // predicate selection strategy. class selection { enum strategy { @@ -1091,7 +1092,7 @@ namespace tb { app_ref_vector predicates(m); expr_ref tmp(m), tmp2(m), constraint(m); app_ref head(m); - result = alloc(clause, m_ctx.get_rule_manager()); + result = alloc(clause, m); unsigned delta[2] = { 0, var_cnt }; m_S1.apply(2, delta, expr_offset(tgt.get_head(), 0), tmp); head = to_app(tmp); @@ -1199,6 +1200,79 @@ namespace tb { } }; + // + // Given a clause + // P(s) :- P(t), Phi(x). + // Compute the clauses: + // acc: P(s) :- Delta(z,t), P(z), Phi(x). + // delta1: Delta(z,z). + // delta2: Delta(z,s) :- Delta(z,t), Phi(x). + // + + class extract_delta { + ast_manager& m; + public: + extract_delta(ast_manager& m): + m(m) + {} + + void operator()(clause const& g, ref& acc, ref& delta1, ref& delta2) { + SASSERT(g.get_num_predicates() > 0); + app* p = g.get_head(); + app* q = g.get_predicate(0); + SASSERT(p->get_decl() == q->get_decl()); + expr_ref_vector zs = mk_fresh_vars(g); + expr_ref_vector zszs(m); + func_decl_ref delta(m); + sort_ref_vector dom(m); + for (unsigned j = 0; j < 1; ++j) { + for (unsigned i = 0; i < zs.size(); ++i) { + dom.push_back(m.get_sort(zs[i].get())); + zszs.push_back(zs[i].get()); + } + } + app_ref_vector preds(m); + delta = m.mk_fresh_func_decl("Delta", dom.size(), dom.c_ptr(), m.mk_bool_sort()); + acc = alloc(clause, m); + delta1 = alloc(clause, m); + delta2 = alloc(clause, m); + delta1->init(m.mk_app(delta, zszs.size(), zszs.c_ptr()), preds, m.mk_true()); + for (unsigned i = 0; i < zs.size(); ++i) { + zszs[i+zs.size()] = p->get_arg(i); + } + app_ref head(m), pred(m); + head = m.mk_app(delta, zszs.size(), zszs.c_ptr()); + for (unsigned i = 0; i < zs.size(); ++i) { + zszs[i+zs.size()] = q->get_arg(i); + } + pred = m.mk_app(delta, zszs.size(), zszs.c_ptr()); + preds.push_back(pred); + for (unsigned i = 1; i < g.get_num_predicates(); ++i) { + preds.push_back(g.get_predicate(i)); + } + delta2->init(head, preds, g.get_constraint()); + preds.push_back(m.mk_app(q->get_decl(), zs.size(), zs.c_ptr())); + acc->init(p, preds, g.get_constraint()); + + IF_VERBOSE(1, + delta1->display(verbose_stream() << "delta1:\n"); + delta2->display(verbose_stream() << "delta2:\n"); + acc->display(verbose_stream() << "acc:\n");); + } + + private: + + expr_ref_vector mk_fresh_vars(clause const& g) { + expr_ref_vector result(m); + app* p = g.get_head(); + unsigned num_vars = g.get_num_vars(); + for (unsigned i = 0; i < p->get_num_args(); ++i) { + result.push_back(m.mk_var(num_vars+i, m.get_sort(p->get_arg(i)))); + } + return result; + } + }; + enum instruction { SELECT_RULE, SELECT_PREDICATE, @@ -1282,7 +1356,7 @@ namespace datalog { func_decl_ref query_pred(m); rm.mk_query(query, query_pred, query_rules, clause); - ref g = alloc(tb::clause, rm); + ref g = alloc(tb::clause, m); g->init(clause); g->set_head(m.mk_false()); init_clause(g); From ca74b2d6cf05bdcef9daeea99c062762d523abbc Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 1 Feb 2013 10:36:23 -0800 Subject: [PATCH 054/101] towards acceleration Signed-off-by: Nikolaj Bjorner --- src/muz_qe/tab_context.cpp | 79 ++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/src/muz_qe/tab_context.cpp b/src/muz_qe/tab_context.cpp index 333a96de0..72727bea8 100644 --- a/src/muz_qe/tab_context.cpp +++ b/src/muz_qe/tab_context.cpp @@ -1048,7 +1048,6 @@ namespace tb { class unifier { ast_manager& m; - datalog::context& m_ctx; ::unifier m_unifier; substitution m_S1; var_subst m_S2; @@ -1056,9 +1055,8 @@ namespace tb { expr_ref_vector m_sub1; expr_ref_vector m_sub2; public: - unifier(ast_manager& m, datalog::context& ctx): + unifier(ast_manager& m): m(m), - m_ctx(ctx), m_unifier(m), m_S1(m), m_S2(m, false), @@ -1066,8 +1064,8 @@ namespace tb { m_sub1(m), m_sub2(m) {} - bool operator()(ref& tgt, ref& src, bool compute_subst, ref& result) { - return unify(*tgt, *src, compute_subst, result); + bool operator()(ref& tgt, unsigned idx, ref& src, bool compute_subst, ref& result) { + return unify(*tgt, idx, *src, compute_subst, result); } expr_ref_vector get_rule_subst(bool is_tgt) { @@ -1079,10 +1077,9 @@ namespace tb { } } - bool unify(clause const& tgt, clause const& src, bool compute_subst, ref& result) { + bool unify(clause const& tgt, unsigned idx, clause const& src, bool compute_subst, ref& result) { qe_lite qe(m); reset(); - unsigned idx = tgt.get_predicate_index(); SASSERT(tgt.get_predicate(idx)->get_decl() == src.get_head()->get_decl()); unsigned var_cnt = std::max(tgt.get_num_vars(), src.get_num_vars()); m_S1.reserve(2, var_cnt); @@ -1101,10 +1098,12 @@ namespace tb { m_S1.apply(2, delta, expr_offset(tgt.get_predicate(i), 0), tmp); predicates.push_back(to_app(tmp)); } - } - for (unsigned i = 0; i < src.get_num_predicates(); ++i) { - m_S1.apply(2, delta, expr_offset(src.get_predicate(i), 1), tmp); - predicates.push_back(to_app(tmp)); + else { + for (unsigned j = 0; j < src.get_num_predicates(); ++j) { + m_S1.apply(2, delta, expr_offset(src.get_predicate(j), 1), tmp); + predicates.push_back(to_app(tmp)); + } + } } m_S1.apply(2, delta, expr_offset(tgt.get_constraint(), 0), tmp); m_S1.apply(2, delta, expr_offset(src.get_constraint(), 1), tmp2); @@ -1200,23 +1199,28 @@ namespace tb { } }; - // - // Given a clause - // P(s) :- P(t), Phi(x). - // Compute the clauses: - // acc: P(s) :- Delta(z,t), P(z), Phi(x). - // delta1: Delta(z,z). - // delta2: Delta(z,s) :- Delta(z,t), Phi(x). - // + class extract_delta { ast_manager& m; + unifier m_unifier; public: extract_delta(ast_manager& m): - m(m) + m(m), + m_unifier(m) {} - void operator()(clause const& g, ref& acc, ref& delta1, ref& delta2) { + + // + // Given a clause + // P(s) :- P(t), Phi(x). + // Compute the clauses: + // acc: P(s) :- Delta(z,t), P(z), Phi(x). + // delta1: Delta(z,z). + // delta2: Delta(z,s) :- Delta(z,t), Phi(x). + // + + void mk_delta_clauses(clause const& g, ref& acc, ref& delta1, ref& delta2) { SASSERT(g.get_num_predicates() > 0); app* p = g.get_head(); app* q = g.get_predicate(0); @@ -1260,6 +1264,31 @@ namespace tb { acc->display(verbose_stream() << "acc:\n");); } + // + // Given a sequence of clauses and inference rules + // compute a super-predicate and auxiliary clauses. + // + // P1(x) :- P2(y), R(z) + // P2(y) :- P3(z), T(u) + // P3(z) :- P1(x), U(v) + // => + // P1(x) :- P1(x), R(z), T(u), U(v) + // + + ref resolve_rules(unsigned num_clauses, clause*const* clauses, unsigned const* positions) { + ref result = clauses[0]; + ref tmp; + unsigned offset = 0; + for (unsigned i = 0; i + 1 < num_clauses; ++i) { + clause const& cl = *clauses[i+1]; + offset += positions[i]; + VERIFY (m_unifier.unify(*result, offset, cl, false, tmp)); + result = tmp; + } + return result; + } + + private: expr_ref_vector mk_fresh_vars(clause const& g) { @@ -1330,7 +1359,7 @@ namespace datalog { m_index(m), m_selection(ctx), m_solver(m, m_fparams), - m_unifier(m, ctx), + m_unifier(m), m_rules(), m_seqno(0), m_instruction(tb::SELECT_PREDICATE), @@ -1427,8 +1456,8 @@ namespace datalog { void apply_rule(ref& r) { ref clause = get_clause(); - ref next_clause; - if (m_unifier(clause, r, false, next_clause) && + ref next_clause; + if (m_unifier(clause, clause->get_predicate_index(), r, false, next_clause) && !query_is_tautology(*next_clause)) { init_clause(next_clause); unsigned subsumer = 0; @@ -1585,7 +1614,7 @@ namespace datalog { unsigned pi = parent->get_predicate_index(); func_decl* pred = parent->get_predicate(pi)->get_decl(); ref rl = m_rules.get_rule(pred, p_rule); - VERIFY(m_unifier(parent, rl, true, replayed_clause)); + VERIFY(m_unifier(parent, parent->get_predicate_index(), rl, true, replayed_clause)); expr_ref_vector s1(m_unifier.get_rule_subst(true)); expr_ref_vector s2(m_unifier.get_rule_subst(false)); resolve_rule(pc, *parent, *rl, s1, s2, *clause); From 8480b273110bfb2b294143d4352b5806a9a4965f Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sat, 2 Feb 2013 08:58:59 -0800 Subject: [PATCH 055/101] Set :print-success to true, when SMTLIB2_COMPLIANT mode is set. Signed-off-by: Leonardo de Moura --- src/cmd_context/cmd_context.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index b511786bf..f94b2a5da 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -304,8 +304,8 @@ cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l): m_main_ctx(main_ctx), m_logic(l), m_interactive_mode(false), - m_global_decls(false), // :global-decls is false by default. - m_print_success(false), // params.m_smtlib2_compliant), + m_global_decls(false), + m_print_success(m_params.m_smtlib2_compliant), m_random_seed(0), m_produce_unsat_cores(false), m_produce_assignments(false), @@ -352,6 +352,8 @@ void cmd_context::set_cancel(bool f) { void cmd_context::global_params_updated() { m_params.updt_params(); + if (m_params.m_smtlib2_compliant) + m_print_success = true; if (m_solver) { params_ref p; if (!m_params.m_auto_config) From bc8277f10d1f12fc2a954ed8a49b5f46a3bc6257 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 3 Feb 2013 14:42:58 -0800 Subject: [PATCH 056/101] Add check bv size. Bit-vector size must be greater than zero (Thanks to David Cok) Signed-off-by: Leonardo de Moura --- src/ast/bv_decl_plugin.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index 9c5bccbc6..dcefe59c3 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -171,6 +171,9 @@ sort * bv_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter c m_manager->raise_exception("expecting one integer parameter to bit-vector sort"); } unsigned bv_size = parameters[0].get_int(); + if (bv_size == 0) { + m_manager->raise_exception("bit-vector size must be greater than zero"); + } mk_bv_sort(bv_size); return m_bv_sorts[bv_size]; } From 2292761a8100336a972eb2714a80019221912bee Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 3 Feb 2013 14:49:38 -0800 Subject: [PATCH 057/101] Fix typo (Thanks to David Cok) Signed-off-by: Leonardo de Moura --- src/cmd_context/basic_cmds.cpp | 4 +++- src/cmd_context/cmd_context.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index c1be7a69b..82f2dbc49 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -213,7 +213,9 @@ ATOMIC_CMD(labels_cmd, "labels", "retrieve Simplify-like labels", { ATOMIC_CMD(get_assertions_cmd, "get-assertions", "retrieve asserted terms when in interactive mode", ctx.display_assertions();); -UNARY_CMD(set_logic_cmd, "set-logic", "", "set the background logic.", CPK_SYMBOL, symbol const &, ctx.set_logic(arg); ctx.print_success();); +UNARY_CMD(set_logic_cmd, "set-logic", "", "set the background logic.", CPK_SYMBOL, symbol const &, + ctx.set_logic(arg); + ctx.print_success();); UNARY_CMD(pp_cmd, "display", "", "display the given term.", CPK_EXPR, expr *, { ctx.display(ctx.regular_stream(), arg); diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index f94b2a5da..8d48545e4 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -670,7 +670,7 @@ void cmd_context::insert(symbol const & s, func_decl * f) { msg += f->get_arity() == 0 ? "constant" : "function"; msg += " '"; msg += s.str(); - msg += "' (whith the given signature) already declared"; + msg += "' (with the given signature) already declared"; throw cmd_exception(msg.c_str()); } if (s != f->get_name()) { From 490905e320c93e4f6c85cc3553c9497ad113db32 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 3 Feb 2013 15:01:43 -0800 Subject: [PATCH 058/101] Set -,/,div as left-associative (Thanks to David Cok) Signed-off-by: Leonardo de Moura --- src/ast/arith_decl_plugin.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 752bad072..fc9b805d1 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -154,6 +154,14 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { m->inc_ref(FIELD); \ } +#define MK_LEFT_ASSOC_OP(FIELD, NAME, KIND, SORT) { \ + func_decl_info info(id, KIND); \ + info.set_left_associative(); \ + FIELD = m->mk_func_decl(symbol(NAME), SORT, SORT, SORT, info); \ + m->inc_ref(FIELD); \ + } + + #define MK_OP(FIELD, NAME, KIND, SORT) \ FIELD = m->mk_func_decl(symbol(NAME), SORT, SORT, SORT, func_decl_info(id, KIND)); \ m->inc_ref(FIELD) @@ -163,15 +171,15 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { m->inc_ref(FIELD) MK_AC_OP(m_r_add_decl, "+", OP_ADD, r); - MK_OP(m_r_sub_decl, "-", OP_SUB, r); + MK_LEFT_ASSOC_OP(m_r_sub_decl, "-", OP_SUB, r); MK_AC_OP(m_r_mul_decl, "*", OP_MUL, r); - MK_OP(m_r_div_decl, "/", OP_DIV, r); + MK_LEFT_ASSOC_OP(m_r_div_decl, "/", OP_DIV, r); MK_UNARY(m_r_uminus_decl, "-", OP_UMINUS, r); MK_AC_OP(m_i_add_decl, "+", OP_ADD, i); - MK_OP(m_i_sub_decl, "-", OP_SUB, i); + MK_LEFT_ASSOC_OP(m_i_sub_decl, "-", OP_SUB, i); MK_AC_OP(m_i_mul_decl, "*", OP_MUL, i); - MK_OP(m_i_div_decl, "div", OP_IDIV, i); + MK_LEFT_ASSOC_OP(m_i_div_decl, "div", OP_IDIV, i); MK_OP(m_i_rem_decl, "rem", OP_REM, i); MK_OP(m_i_mod_decl, "mod", OP_MOD, i); MK_UNARY(m_i_uminus_decl, "-", OP_UMINUS, i); From c4f762028fda16527ba46be0ce308789c3f6f890 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 3 Feb 2013 15:28:56 -0800 Subject: [PATCH 059/101] Add support for abs (absolute value) function in theory arith (it is part of the SMT-LIB 2.0 standard) Signed-off-by: Leonardo de Moura --- src/ast/arith_decl_plugin.cpp | 9 +++++++++ src/ast/arith_decl_plugin.h | 4 ++++ src/ast/rewriter/arith_rewriter.cpp | 6 ++++++ src/ast/rewriter/arith_rewriter.h | 2 ++ src/ast/simplifier/arith_simplifier_plugin.cpp | 9 +++++++++ src/ast/simplifier/arith_simplifier_plugin.h | 1 + 6 files changed, 31 insertions(+) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index fc9b805d1..9d1f4343f 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -194,6 +194,9 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { MK_OP(m_r_power_decl, "^", OP_POWER, r); MK_OP(m_i_power_decl, "^", OP_POWER, i); + MK_UNARY(m_i_abs_decl, "abs", OP_ABS, i); + MK_UNARY(m_r_abs_decl, "abs", OP_ABS, r); + MK_UNARY(m_sin_decl, "sin", OP_SIN, r); MK_UNARY(m_cos_decl, "cos", OP_COS, r); MK_UNARY(m_tan_decl, "tan", OP_TAN, r); @@ -263,6 +266,8 @@ arith_decl_plugin::arith_decl_plugin(): m_is_int_decl(0), m_r_power_decl(0), m_i_power_decl(0), + m_r_abs_decl(0), + m_i_abs_decl(0), m_sin_decl(0), m_cos_decl(0), m_tan_decl(0), @@ -320,6 +325,8 @@ void arith_decl_plugin::finalize() { DEC_REF(m_is_int_decl); DEC_REF(m_i_power_decl); DEC_REF(m_r_power_decl); + DEC_REF(m_i_abs_decl); + DEC_REF(m_r_abs_decl); DEC_REF(m_sin_decl); DEC_REF(m_cos_decl); DEC_REF(m_tan_decl); @@ -372,6 +379,7 @@ inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) { case OP_TO_INT: return m_to_int_decl; case OP_IS_INT: return m_is_int_decl; case OP_POWER: return is_real ? m_r_power_decl : m_i_power_decl; + case OP_ABS: return is_real ? m_r_abs_decl : m_i_abs_decl; case OP_SIN: return m_sin_decl; case OP_COS: return m_cos_decl; case OP_TAN: return m_tan_decl; @@ -538,6 +546,7 @@ void arith_decl_plugin::get_op_names(svector& op_names, symbol con op_names.push_back(builtin_name("to_real",OP_TO_REAL)); op_names.push_back(builtin_name("to_int",OP_TO_INT)); op_names.push_back(builtin_name("is_int",OP_IS_INT)); + op_names.push_back(builtin_name("abs", OP_ABS)); if (logic == symbol::null) { op_names.push_back(builtin_name("^", OP_POWER)); op_names.push_back(builtin_name("sin", OP_SIN)); diff --git a/src/ast/arith_decl_plugin.h b/src/ast/arith_decl_plugin.h index 53ab1881b..d048bb2f7 100644 --- a/src/ast/arith_decl_plugin.h +++ b/src/ast/arith_decl_plugin.h @@ -51,6 +51,7 @@ enum arith_op_kind { OP_TO_REAL, OP_TO_INT, OP_IS_INT, + OP_ABS, OP_POWER, // hyperbolic and trigonometric functions OP_SIN, @@ -121,6 +122,9 @@ protected: func_decl * m_r_power_decl; func_decl * m_i_power_decl; + func_decl * m_r_abs_decl; + func_decl * m_i_abs_decl; + func_decl * m_sin_decl; func_decl * m_cos_decl; func_decl * m_tan_decl; diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index a5dfda6e7..91d87cbfb 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -70,6 +70,7 @@ br_status arith_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c case OP_TO_INT: SASSERT(num_args == 1); st = mk_to_int_core(args[0], result); break; case OP_IS_INT: SASSERT(num_args == 1); st = mk_is_int(args[0], result); break; case OP_POWER: SASSERT(num_args == 2); st = mk_power_core(args[0], args[1], result); break; + case OP_ABS: SASSERT(num_args == 1); st = mk_abs_core(args[0], result); break; case OP_SIN: SASSERT(num_args == 1); st = mk_sin_core(args[0], result); break; case OP_COS: SASSERT(num_args == 1); st = mk_cos_core(args[0], result); break; case OP_TAN: SASSERT(num_args == 1); st = mk_tan_core(args[0], result); break; @@ -1024,6 +1025,11 @@ br_status arith_rewriter::mk_is_int(expr * arg, expr_ref & result) { } } +br_status arith_rewriter::mk_abs_core(expr * arg, expr_ref & result) { + result = m().mk_ite(m_util.mk_ge(arg, m_util.mk_numeral(rational(0), m_util.is_int(arg))), arg, m_util.mk_uminus(arg)); + return BR_REWRITE2; +} + void arith_rewriter::set_cancel(bool f) { m_util.set_cancel(f); } diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index 833cc2515..bce59657a 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -131,6 +131,8 @@ public: } void mk_gt(expr * arg1, expr * arg2, expr_ref & result) { mk_gt_core(arg1, arg2, result); } + br_status mk_abs_core(expr * arg, expr_ref & result); + br_status mk_div_core(expr * arg1, expr * arg2, expr_ref & result); br_status mk_idiv_core(expr * arg1, expr * arg2, expr_ref & result); br_status mk_mod_core(expr * arg1, expr * arg2, expr_ref & result); diff --git a/src/ast/simplifier/arith_simplifier_plugin.cpp b/src/ast/simplifier/arith_simplifier_plugin.cpp index b9e93a973..f7751782d 100644 --- a/src/ast/simplifier/arith_simplifier_plugin.cpp +++ b/src/ast/simplifier/arith_simplifier_plugin.cpp @@ -404,6 +404,7 @@ bool arith_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * co case OP_TO_INT: SASSERT(num_args == 1); mk_to_int(args[0], result); break; case OP_IS_INT: SASSERT(num_args == 1); mk_is_int(args[0], result); break; case OP_POWER: return false; + case OP_ABS: SASSERT(num_args == 1); mk_abs(args[0], result); break; case OP_IRRATIONAL_ALGEBRAIC_NUM: return false; default: UNREACHABLE(); @@ -413,6 +414,14 @@ bool arith_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * co return true; } +void arith_simplifier_plugin::mk_abs(expr * arg, expr_ref & result) { + expr_ref c(m_manager); + expr_ref m_arg(m_manager); + mk_uminus(arg, m_arg); + mk_ge(arg, m_util.mk_numeral(rational(0), m_util.is_int(arg)), c); + m_bsimp.mk_ite(c, arg, m_arg, result); +} + bool arith_simplifier_plugin::is_arith_term(expr * n) const { return n->get_kind() == AST_APP && to_app(n)->get_family_id() == m_fid; } diff --git a/src/ast/simplifier/arith_simplifier_plugin.h b/src/ast/simplifier/arith_simplifier_plugin.h index 4402fa8a1..4b8f579c0 100644 --- a/src/ast/simplifier/arith_simplifier_plugin.h +++ b/src/ast/simplifier/arith_simplifier_plugin.h @@ -82,6 +82,7 @@ public: void mk_to_real(expr * arg, expr_ref & result); void mk_to_int(expr * arg, expr_ref & result); void mk_is_int(expr * arg, expr_ref & result); + void mk_abs(expr * arg, expr_ref & result); virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); virtual bool reduce_eq(expr * lhs, expr * rhs, expr_ref & result); From 62c841c320582f6d28c31ee22ee2ab6116a92b50 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 3 Feb 2013 15:41:11 -0800 Subject: [PATCH 060/101] Change unknown set-logic behavior in SMTLIB2 compliant mode (Thanks to David Cok) Signed-off-by: Leonardo de Moura --- src/cmd_context/basic_cmds.cpp | 7 +++++-- src/cmd_context/cmd_context.cpp | 12 +++++++++--- src/cmd_context/cmd_context.h | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index 82f2dbc49..21a986fda 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -214,8 +214,11 @@ ATOMIC_CMD(labels_cmd, "labels", "retrieve Simplify-like labels", { ATOMIC_CMD(get_assertions_cmd, "get-assertions", "retrieve asserted terms when in interactive mode", ctx.display_assertions();); UNARY_CMD(set_logic_cmd, "set-logic", "", "set the background logic.", CPK_SYMBOL, symbol const &, - ctx.set_logic(arg); - ctx.print_success();); + if (ctx.set_logic(arg)) + ctx.print_success(); + else + ctx.print_unsupported(symbol::null); + ); UNARY_CMD(pp_cmd, "display", "", "display the given term.", CPK_EXPR, expr *, { ctx.display(ctx.regular_stream(), arg); diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 8d48545e4..261af3092 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -621,14 +621,19 @@ bool cmd_context::supported_logic(symbol const & s) const { s == "QF_FPA" || s == "QF_FPABV"; } -void cmd_context::set_logic(symbol const & s) { +bool cmd_context::set_logic(symbol const & s) { if (has_logic()) throw cmd_exception("the logic has already been set"); if (has_manager() && m_main_ctx) throw cmd_exception("logic must be set before initialization"); if (!supported_logic(s)) { - warning_msg("unknown logic, ignoring set-logic command"); - return; + if (m_params.m_smtlib2_compliant) { + return false; + } + else { + warning_msg("unknown logic, ignoring set-logic command"); + return true; + } } m_logic = s; if (is_logic("QF_RDL") || @@ -640,6 +645,7 @@ void cmd_context::set_logic(symbol const & s) { is_logic("QF_UFNRA") || is_logic("QF_UFLRA")) m_numeral_as_real = true; + return true; } std::string cmd_context::reason_unknown() const { diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index 07b0cf456..22b2ea046 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -254,7 +254,7 @@ public: void reset_cancel() { set_cancel(false); } context_params & params() { return m_params; } void global_params_updated(); // this method should be invoked when global (and module) params are updated. - void set_logic(symbol const & s); + bool set_logic(symbol const & s); bool has_logic() const { return m_logic != symbol::null; } symbol const & get_logic() const { return m_logic; } bool is_logic(char const * l_name) const { return has_logic() && strcmp(m_logic.bare_str(), l_name) == 0; } From 39a614559caed919cacc8d864775ed1fa8910b44 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Sun, 3 Feb 2013 15:55:36 -0800 Subject: [PATCH 061/101] Add partial solution for the uneeded disambiguation issue raised by David Cok Signed-off-by: Leonardo de Moura --- src/ast/arith_decl_plugin.cpp | 14 ++++++++++++++ src/ast/ast.cpp | 16 +++++++++++++++- src/ast/bv_decl_plugin.cpp | 18 ++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 9d1f4343f..5e346fc0d 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -492,6 +492,13 @@ static bool is_const_op(decl_kind k) { func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { + if (range != 0) { + if (is_sort_of(range, m_family_id, REAL_SORT) || is_sort_of(range, m_family_id, INT_SORT)) + m_manager->raise_exception("unneeded disambiguation"); + else + m_manager->raise_exception("incorrect disambiguation"); + return 0; + } if (k == OP_NUM) return mk_num_decl(num_parameters, parameters, arity); if (arity == 0 && !is_const_op(k)) { @@ -509,6 +516,13 @@ func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned num_args, expr * const * args, sort * range) { + if (range != 0) { + if (is_sort_of(range, m_family_id, REAL_SORT) || is_sort_of(range, m_family_id, INT_SORT)) + m_manager->raise_exception("unneeded disambiguation"); + else + m_manager->raise_exception("incorrect disambiguation"); + return 0; + } if (k == OP_NUM) return mk_num_decl(num_parameters, parameters, num_args); if (num_args == 0 && !is_const_op(k)) { diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 486aa9646..1ba468399 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1010,6 +1010,13 @@ func_decl * basic_decl_plugin::mk_ite_decl(sort * s) { func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { + if (range != 0) { + if (is_sort_of(range, m_family_id, BOOL_SORT)) + m_manager->raise_exception("unneeded disambiguation"); + else + m_manager->raise_exception("incorrect disambiguation"); + return 0; + } switch (static_cast(k)) { case OP_TRUE: return m_true_decl; case OP_FALSE: return m_false_decl; @@ -1044,7 +1051,14 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters } func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned num_args, expr * const * args, sort * range) { + unsigned num_args, expr * const * args, sort * range) { + if (range != 0) { + if (is_sort_of(range, m_family_id, BOOL_SORT)) + m_manager->raise_exception("unneeded disambiguation"); + else + m_manager->raise_exception("incorrect disambiguation"); + return 0; + } switch (static_cast(k)) { case OP_TRUE: return m_true_decl; case OP_FALSE: return m_false_decl; diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index dcefe59c3..823d9eaed 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -460,7 +460,14 @@ func_decl * bv_decl_plugin::mk_mkbv(unsigned arity, sort * const * domain) { } func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { + unsigned arity, sort * const * domain, sort * range) { + if (range != 0) { + if (is_sort_of(range, m_family_id, BV_SORT)) + m_manager->raise_exception("unneeded disambiguation"); + else + m_manager->raise_exception("incorrect disambiguation"); + return 0; + } int bv_size; if (k == OP_INT2BV && get_int2bv_size(num_parameters, parameters, bv_size)) { // bv_size is filled in. @@ -558,7 +565,14 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p } func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned num_args, expr * const * args, sort * range) { + unsigned num_args, expr * const * args, sort * range) { + if (range != 0) { + if (is_sort_of(range, m_family_id, BV_SORT)) + m_manager->raise_exception("unneeded disambiguation"); + else + m_manager->raise_exception("incorrect disambiguation"); + return 0; + } int bv_size; if (k == OP_INT2BV && get_int2bv_size(num_parameters, parameters, bv_size)) { // bv_size is filled in. From 8e5581b4fea2ec9b41355b23369f7401b04cf61d Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 4 Feb 2013 08:19:33 -0800 Subject: [PATCH 062/101] Retract changes in the commit 39a614559cae. The fix was affecting benchmarks using the array theory map construct. Signed-off-by: Leonardo de Moura --- src/ast/arith_decl_plugin.cpp | 14 -------------- src/ast/ast.cpp | 14 -------------- src/ast/bv_decl_plugin.cpp | 14 -------------- 3 files changed, 42 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 5e346fc0d..9d1f4343f 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -492,13 +492,6 @@ static bool is_const_op(decl_kind k) { func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { - if (range != 0) { - if (is_sort_of(range, m_family_id, REAL_SORT) || is_sort_of(range, m_family_id, INT_SORT)) - m_manager->raise_exception("unneeded disambiguation"); - else - m_manager->raise_exception("incorrect disambiguation"); - return 0; - } if (k == OP_NUM) return mk_num_decl(num_parameters, parameters, arity); if (arity == 0 && !is_const_op(k)) { @@ -516,13 +509,6 @@ func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned num_args, expr * const * args, sort * range) { - if (range != 0) { - if (is_sort_of(range, m_family_id, REAL_SORT) || is_sort_of(range, m_family_id, INT_SORT)) - m_manager->raise_exception("unneeded disambiguation"); - else - m_manager->raise_exception("incorrect disambiguation"); - return 0; - } if (k == OP_NUM) return mk_num_decl(num_parameters, parameters, num_args); if (num_args == 0 && !is_const_op(k)) { diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 1ba468399..63a450094 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1010,13 +1010,6 @@ func_decl * basic_decl_plugin::mk_ite_decl(sort * s) { func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { - if (range != 0) { - if (is_sort_of(range, m_family_id, BOOL_SORT)) - m_manager->raise_exception("unneeded disambiguation"); - else - m_manager->raise_exception("incorrect disambiguation"); - return 0; - } switch (static_cast(k)) { case OP_TRUE: return m_true_decl; case OP_FALSE: return m_false_decl; @@ -1052,13 +1045,6 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned num_args, expr * const * args, sort * range) { - if (range != 0) { - if (is_sort_of(range, m_family_id, BOOL_SORT)) - m_manager->raise_exception("unneeded disambiguation"); - else - m_manager->raise_exception("incorrect disambiguation"); - return 0; - } switch (static_cast(k)) { case OP_TRUE: return m_true_decl; case OP_FALSE: return m_false_decl; diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index 823d9eaed..0ef3b60d6 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -461,13 +461,6 @@ func_decl * bv_decl_plugin::mk_mkbv(unsigned arity, sort * const * domain) { func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { - if (range != 0) { - if (is_sort_of(range, m_family_id, BV_SORT)) - m_manager->raise_exception("unneeded disambiguation"); - else - m_manager->raise_exception("incorrect disambiguation"); - return 0; - } int bv_size; if (k == OP_INT2BV && get_int2bv_size(num_parameters, parameters, bv_size)) { // bv_size is filled in. @@ -566,13 +559,6 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned num_args, expr * const * args, sort * range) { - if (range != 0) { - if (is_sort_of(range, m_family_id, BV_SORT)) - m_manager->raise_exception("unneeded disambiguation"); - else - m_manager->raise_exception("incorrect disambiguation"); - return 0; - } int bv_size; if (k == OP_INT2BV && get_int2bv_size(num_parameters, parameters, bv_size)) { // bv_size is filled in. From 6022d14b0241ed85f8245a5730c08ba28b5a898e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Feb 2013 15:03:45 -0800 Subject: [PATCH 063/101] remove incorrect code for double loop with widening Signed-off-by: Nikolaj Bjorner --- src/muz_qe/dl_compiler.cpp | 68 +++++++------------------------------- 1 file changed, 12 insertions(+), 56 deletions(-) diff --git a/src/muz_qe/dl_compiler.cpp b/src/muz_qe/dl_compiler.cpp index d403b5b5c..44a449779 100644 --- a/src/muz_qe/dl_compiler.cpp +++ b/src/muz_qe/dl_compiler.cpp @@ -87,12 +87,12 @@ namespace datalog { acc.push_back(instruction::mk_clone(src, result)); } - void compiler::make_union(reg_idx src, reg_idx tgt, reg_idx delta, bool widening, + void compiler::make_union(reg_idx src, reg_idx tgt, reg_idx delta, bool use_widening, instruction_block & acc) { SASSERT(m_reg_signatures[src]==m_reg_signatures[tgt]); SASSERT(delta==execution_context::void_register || m_reg_signatures[src]==m_reg_signatures[delta]); - if(widening) { + if (use_widening) { acc.push_back(instruction::mk_widen(src, tgt, delta)); } else { @@ -129,8 +129,7 @@ namespace datalog { func_decl_set::iterator pend = preds.end(); for(; pit!=pend; ++pit) { func_decl * pred = *pit; - reg_idx reg; - TRUSTME( m_pred_regs.find(pred, reg) ); + reg_idx reg = m_pred_regs.find(pred); SASSERT(!regs.contains(pred)); relation_signature sig = m_reg_signatures[reg]; @@ -576,8 +575,7 @@ namespace datalog { } SASSERT(t_cols.size()==neg_cols.size()); - reg_idx neg_reg; - TRUSTME( m_pred_regs.find(neg_pred, neg_reg) ); + reg_idx neg_reg = m_pred_regs.find(neg_pred); acc.push_back(instruction::mk_filter_by_negation(filtered_res, neg_reg, t_cols.size(), t_cols.c_ptr(), neg_cols.c_ptr())); } @@ -762,15 +760,13 @@ namespace datalog { typedef svector tail_delta_infos; unsigned rule_len = r->get_uninterpreted_tail_size(); - reg_idx head_reg; - TRUSTME( m_pred_regs.find(r->get_head()->get_decl(), head_reg) ); + reg_idx head_reg = m_pred_regs.find(r->get_head()->get_decl()); svector tail_regs; tail_delta_infos tail_deltas; for(unsigned j=0;jget_tail(j)->get_decl(); - reg_idx tail_reg; - TRUSTME( m_pred_regs.find(tail_pred, tail_reg) ); + reg_idx tail_reg = m_pred_regs.find(tail_pred); tail_regs.push_back(tail_reg); if(input_deltas && !all_or_nothing_deltas()) { @@ -858,7 +854,7 @@ namespace datalog { rule_dependencies deps(m_rule_set.get_dependencies()); deps.restrict(preds); cycle_breaker(deps, global_deltas)(); - TRUSTME( deps.sort_deps(ordered_preds) ); + VERIFY( deps.sort_deps(ordered_preds) ); //the predicates that were removed to get acyclic induced subgraph are put last //so that all their local input deltas are already populated @@ -903,8 +899,7 @@ namespace datalog { for(; gdit!=gend; ++gdit) { func_decl * pred = gdit->m_key; reg_idx head_reg = gdit->m_value; - reg_idx tail_reg; - TRUSTME( global_tail_deltas.find(pred, tail_reg) ); + reg_idx tail_reg = global_tail_deltas.find(pred); acc.push_back(instruction::mk_move(head_reg, tail_reg)); } //empty local deltas @@ -939,7 +934,7 @@ namespace datalog { loop_body->set_observer(0); acc.push_back(instruction::mk_while_loop(loop_control_regs.size(), - loop_control_regs.c_ptr(),loop_body)); + loop_control_regs.c_ptr(), loop_body)); } void compiler::compile_dependent_rules(const func_decl_set & head_preds, @@ -985,50 +980,11 @@ namespace datalog { //generate code for the initial run compile_preds(preds_vector, empty_func_decl_set, input_deltas, d_global_src, acc); - if(!compile_with_widening()) { - compile_loop(preds_vector, empty_func_decl_set, d_global_tgt, d_global_src, - d_local, acc); + if (compile_with_widening()) { + compile_loop(preds_vector, global_deltas, d_global_tgt, d_global_src, d_local, acc); } else { - //do the part where we zero the global predicates and run the loop saturation loop again - if(global_deltas.size() Date: Tue, 5 Feb 2013 21:19:32 -0800 Subject: [PATCH 064/101] tidy verbose mode a bit, ackermannize special cases of arrays Signed-off-by: Nikolaj Bjorner --- src/muz_qe/dl_mk_array_blast.cpp | 100 +++++++++++++++++++++++++++++-- src/muz_qe/dl_mk_array_blast.h | 4 ++ src/muz_qe/pdr_context.cpp | 33 ++++++---- 3 files changed, 119 insertions(+), 18 deletions(-) diff --git a/src/muz_qe/dl_mk_array_blast.cpp b/src/muz_qe/dl_mk_array_blast.cpp index 880f196a2..b22fdf7ef 100644 --- a/src/muz_qe/dl_mk_array_blast.cpp +++ b/src/muz_qe/dl_mk_array_blast.cpp @@ -49,6 +49,94 @@ namespace datalog { } return false; } + + bool mk_array_blast::ackermanize(expr_ref& body, expr_ref& head) { + expr_ref_vector conjs(m); + flatten_and(body, conjs); + defs_t defs; + expr_safe_replace sub(m); + ptr_vector todo; + todo.push_back(head); + for (unsigned i = 0; i < conjs.size(); ++i) { + expr* e = conjs[i].get(); + expr* x, *y; + if (m.is_eq(e, x, y) || m.is_iff(e, x, y)) { + if (a.is_select(y)) { + std::swap(x,y); + } + if (a.is_select(x) && is_var(y)) { + // + // For the Ackermann reduction we would like the arrays + // to be variables, so that variables can be + // assumed to represent difference (alias) + // classes. + // + if (!is_var(to_app(x)->get_arg(0))) { + return false; + } + sub.insert(x, y); + defs.insert(to_app(x), to_var(y)); + } + } + todo.push_back(e); + } + // now check that all occurrences of select have been covered. + ast_mark mark; + while (!todo.empty()) { + expr* e = todo.back(); + todo.pop_back(); + if (mark.is_marked(e)) { + continue; + } + mark.mark(e, true); + if (is_var(e)) { + continue; + } + if (!is_app(e)) { + return false; + } + app* ap = to_app(e); + if (a.is_select(e) && !defs.contains(ap)) { + return false; + } + for (unsigned i = 0; i < ap->get_num_args(); ++i) { + todo.push_back(ap->get_arg(i)); + } + } + sub(body); + sub(head); + conjs.reset(); + + // perform the Ackermann reduction by creating implications + // i1 = i2 => val1 = val2 for each equality pair: + // (= val1 (select a_i i1)) + // (= val2 (select a_i i2)) + defs_t::iterator it1 = defs.begin(), end = defs.end(); + for (; it1 != end; ++it1) { + app* a1 = it1->m_key; + var* v1 = it1->m_value; + defs_t::iterator it2 = it1; + ++it2; + for (; it2 != end; ++it2) { + app* a2 = it2->m_key; + var* v2 = it2->m_value; + if (a1->get_arg(0) != a2->get_arg(0)) { + continue; + } + expr_ref_vector eqs(m); + for (unsigned j = 1; j < a1->get_num_args(); ++j) { + eqs.push_back(m.mk_eq(a1->get_arg(j), a2->get_arg(j))); + } + conjs.push_back(m.mk_implies(m.mk_and(eqs.size(), eqs.c_ptr()), m.mk_eq(v1, v2))); + } + } + if (!conjs.empty()) { + conjs.push_back(body); + body = m.mk_and(conjs.size(), conjs.c_ptr()); + } + m_rewriter(body); + return true; + } bool mk_array_blast::blast(rule& r, rule_set& rules) { unsigned utsz = r.get_uninterpreted_tail_size(); @@ -92,10 +180,6 @@ namespace datalog { new_conjs.push_back(tmp); } } - if (!inserted && !change) { - rules.add_rule(&r); - return false; - } rule_ref_vector new_rules(rm); expr_ref fml1(m), fml2(m), body(m), head(m); @@ -106,11 +190,17 @@ namespace datalog { m_rewriter(body); sub(head); m_rewriter(head); + change = ackermanize(body, head) || change; + if (!inserted && !change) { + rules.add_rule(&r); + return false; + } + fml2 = m.mk_implies(body, head); rm.mk_rule(fml2, new_rules, r.name()); SASSERT(new_rules.size() == 1); - TRACE("dl", tout << "new body " << mk_pp(fml2, m) << "\n";); + TRACE("dl", new_rules[0]->display(m_ctx, tout << "new rule\n");); rules.add_rule(new_rules[0].get()); if (m_pc) { diff --git a/src/muz_qe/dl_mk_array_blast.h b/src/muz_qe/dl_mk_array_blast.h index 858b9c778..1618e4fa8 100644 --- a/src/muz_qe/dl_mk_array_blast.h +++ b/src/muz_qe/dl_mk_array_blast.h @@ -39,10 +39,14 @@ namespace datalog { th_rewriter m_rewriter; equiv_proof_converter* m_pc; + typedef obj_map defs_t; + bool blast(rule& r, rule_set& new_rules); bool is_store_def(expr* e, expr*& x, expr*& y); + bool ackermanize(expr_ref& body, expr_ref& head); + public: /** \brief Create rule transformer that extracts universal quantifiers (over recursive predicates). diff --git a/src/muz_qe/pdr_context.cpp b/src/muz_qe/pdr_context.cpp index 574d44fb5..47655ac7b 100644 --- a/src/muz_qe/pdr_context.cpp +++ b/src/muz_qe/pdr_context.cpp @@ -52,6 +52,20 @@ namespace pdr { static bool is_infty_level(unsigned lvl) { return lvl == infty_level; } static unsigned next_level(unsigned lvl) { return is_infty_level(lvl)?lvl:(lvl+1); } + + struct pp_level { + unsigned m_level; + pp_level(unsigned l): m_level(l) {} + }; + + static std::ostream& operator<<(std::ostream& out, pp_level const& p) { + if (is_infty_level(p.m_level)) { + return out << "oo"; + } + else { + return out << p.m_level; + } + } // ---------------- // pred_tansformer @@ -263,7 +277,7 @@ namespace pdr { else if (is_invariant(tgt_level, curr, false, assumes_level)) { add_property(curr, assumes_level?tgt_level:infty_level); - TRACE("pdr", tout << "is invariant: "<< tgt_level << " " << mk_pp(curr, m) << "\n";); + TRACE("pdr", tout << "is invariant: "<< pp_level(tgt_level) << " " << mk_pp(curr, m) << "\n";); src[i] = src.back(); src.pop_back(); ++m_stats.m_num_propagations; @@ -273,14 +287,7 @@ namespace pdr { ++i; } } - IF_VERBOSE(2, verbose_stream() << "propagate: "; - if (is_infty_level(src_level)) { - verbose_stream() << "infty"; - } - else { - verbose_stream() << src_level; - } - verbose_stream() << "\n"; + IF_VERBOSE(3, verbose_stream() << "propagate: " << pp_level(src_level) << "\n"; for (unsigned i = 0; i < src.size(); ++i) { verbose_stream() << mk_pp(src[i].get(), m) << "\n"; }); @@ -304,14 +311,14 @@ namespace pdr { ensure_level(lvl); unsigned old_level; if (!m_prop2level.find(lemma, old_level) || old_level < lvl) { - TRACE("pdr", tout << "property1: " << lvl << " " << head()->get_name() << " " << mk_pp(lemma, m) << "\n";); + TRACE("pdr", tout << "property1: " << pp_level(lvl) << " " << head()->get_name() << " " << mk_pp(lemma, m) << "\n";); m_levels[lvl].push_back(lemma); m_prop2level.insert(lemma, lvl); m_solver.add_level_formula(lemma, lvl); return true; } else { - TRACE("pdr", tout << "old-level: " << old_level << " " << head()->get_name() << " " << mk_pp(lemma, m) << "\n";); + TRACE("pdr", tout << "old-level: " << pp_level(old_level) << " " << head()->get_name() << " " << mk_pp(lemma, m) << "\n";); return false; } } @@ -337,7 +344,7 @@ namespace pdr { for (unsigned i = 0; i < lemmas.size(); ++i) { expr* lemma_i = lemmas[i].get(); if (add_property1(lemma_i, lvl)) { - IF_VERBOSE(2, verbose_stream() << lvl << " " << mk_pp(lemma_i, m) << "\n";); + IF_VERBOSE(2, verbose_stream() << pp_level(lvl) << " " << mk_pp(lemma_i, m) << "\n";); for (unsigned j = 0; j < m_use.size(); ++j) { m_use[j]->add_child_property(*this, lemma_i, next_level(lvl)); } @@ -1914,7 +1921,7 @@ namespace pdr { model_node* child = alloc(model_node, &n, n_cube, pt, n.level()-1); ++m_stats.m_num_nodes; m_search.add_leaf(*child); - IF_VERBOSE(2, verbose_stream() << "Predecessor: " << mk_pp(o_cube, m) << "\n";); + IF_VERBOSE(3, verbose_stream() << "Predecessor: " << mk_pp(o_cube, m) << "\n";); m_stats.m_max_depth = std::max(m_stats.m_max_depth, child->depth()); } check_pre_closed(n); From 786f8029f18263d7e81e2b4615b8b13241f1e047 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 6 Feb 2013 09:26:10 -0800 Subject: [PATCH 065/101] Add missing DLLs for Java in Windows binary distribution package Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 98d9ad6f8..b5ec691cb 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1084,6 +1084,10 @@ class JavaDLLComponent(Component): mk_dir(os.path.join(dist_path, 'bin')) shutil.copy('%s.jar' % os.path.join(build_path, self.package_name), '%s.jar' % os.path.join(dist_path, 'bin', self.package_name)) + shutil.copy(os.path.join(build_path, 'libz3java.dll'), + os.path.join(dist_path, 'bin', 'libz3java.dll')) + shutil.copy(os.path.join(build_path, 'libz3java.lib'), + os.path.join(dist_path, 'bin', 'libz3java.lib')) class ExampleComponent(Component): def __init__(self, name, path): From 0fd1c00053aaf67bb622bfa8e4794eceab65bbba Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 6 Feb 2013 09:40:16 -0800 Subject: [PATCH 066/101] fix reference counting bug in qe Signed-off-by: Nikolaj Bjorner --- src/muz_qe/qe_arith_plugin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/muz_qe/qe_arith_plugin.cpp b/src/muz_qe/qe_arith_plugin.cpp index 4e158229b..1baee51fa 100644 --- a/src/muz_qe/qe_arith_plugin.cpp +++ b/src/muz_qe/qe_arith_plugin.cpp @@ -524,7 +524,8 @@ namespace qe { expr_ref as_bt_le_0(result, m), tmp2(m), tmp3(m), tmp4(m); // a*s + b*t + (a-1)(b-1) <= 0 - mk_le(m_arith.mk_add(as_bt, slack), result1); + tmp2 = m_arith.mk_add(as_bt, slack); + mk_le(tmp2, result1); rational a1 = a, b1 = b; if (abs_a < abs_b) { From 2e2fa84d40d252441cb4c8b5c1ed0d4c8779f2c3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 7 Feb 2013 19:21:52 -0800 Subject: [PATCH 067/101] experiment with arithmetic core generalizers Signed-off-by: Nikolaj Bjorner --- src/muz_qe/fixedpoint_params.pyg | 1 + src/muz_qe/pdr_context.cpp | 4 + src/muz_qe/pdr_generalizers.cpp | 159 ++++++++++++++++++++++++- src/muz_qe/pdr_generalizers.h | 31 +++++ src/muz_qe/pdr_smt_context_manager.cpp | 2 +- 5 files changed, 195 insertions(+), 2 deletions(-) diff --git a/src/muz_qe/fixedpoint_params.pyg b/src/muz_qe/fixedpoint_params.pyg index 25e513b78..c2cfadd14 100644 --- a/src/muz_qe/fixedpoint_params.pyg +++ b/src/muz_qe/fixedpoint_params.pyg @@ -44,6 +44,7 @@ def_module_params('fixedpoint', ('coalesce_rules', BOOL, False, "BMC: coalesce rules"), ('use_multicore_generalizer', BOOL, False, "PDR: extract multiple cores for blocking states"), ('use_inductive_generalizer', BOOL, True, "PDR: generalize lemmas using induction strengthening"), + ('use_arith_inductive_generalizer', BOOL, False, "PDR: generalize lemmas using arithmetic heuristics for induction strengthening"), ('cache_mode', UINT, 0, "PDR: use no (0), symbolic (1) or explicit cache (2) for model search"), ('inductive_reachability_check', BOOL, False, "PDR: assume negation of the cube on the previous level when " "checking for reachability (not only during cube weakening)"), diff --git a/src/muz_qe/pdr_context.cpp b/src/muz_qe/pdr_context.cpp index 47655ac7b..73bffd4e4 100644 --- a/src/muz_qe/pdr_context.cpp +++ b/src/muz_qe/pdr_context.cpp @@ -1477,6 +1477,10 @@ namespace pdr { if (m_params.inductive_reachability_check()) { m_core_generalizers.push_back(alloc(core_induction_generalizer, *this)); } + if (m_params.use_arith_inductive_generalizer()) { + m_core_generalizers.push_back(alloc(core_arith_inductive_generalizer, *this)); + } + } void context::get_level_property(unsigned lvl, expr_ref_vector& res, vector& rs) const { diff --git a/src/muz_qe/pdr_generalizers.cpp b/src/muz_qe/pdr_generalizers.cpp index 5a6ab4240..a02a1cb6e 100644 --- a/src/muz_qe/pdr_generalizers.cpp +++ b/src/muz_qe/pdr_generalizers.cpp @@ -28,7 +28,9 @@ Revision History: namespace pdr { - // + // ------------------------ + // core_bool_inductive_generalizer + // main propositional induction generalizer. // drop literals one by one from the core and check if the core is still inductive. // @@ -97,6 +99,9 @@ namespace pdr { } } + // ------------------------ + // core_farkas_generalizer + // // for each disjunct of core: // weaken predecessor. @@ -142,6 +147,158 @@ namespace pdr { } + // ----------------------------- + // core_arith_inductive_generalizer + + core_arith_inductive_generalizer::core_arith_inductive_generalizer(context& ctx): + core_generalizer(ctx), + m(ctx.get_manager()), + a(m), + m_refs(m) {} + + void core_arith_inductive_generalizer::operator()(model_node& n, expr_ref_vector& core, bool& uses_level) { + if (core.size() <= 1) { + return; + } + reset(); + expr_ref e(m), t1(m), t2(m), t3(m); + rational r; + + TRACE("pdr", for (unsigned i = 0; i < core.size(); ++i) { tout << mk_pp(core[i].get(), m) << "\n"; }); + + svector eqs; + get_eqs(core, eqs); + + for (unsigned eq = 0; eq < eqs.size(); ++eq) { + rational r = eqs[eq].m_value; + expr* x = eqs[eq].m_term; + unsigned k = eqs[eq].m_i; + unsigned l = eqs[eq].m_j; + + expr_ref_vector new_core(m); + for (unsigned i = 0; i < core.size(); ++i) { + if (i == k || k == l) { + new_core.push_back(m.mk_true()); + } + else { + if (!substitute_alias(r, x, core[i].get(), e)) { + e = core[i].get(); + } + new_core.push_back(e); + } + } + if (abs(r) >= rational(2) && a.is_int(x)) { + new_core[k] = m.mk_eq(a.mk_mod(x, a.mk_numeral(abs(r), true)), a.mk_numeral(rational(0), true)); + new_core[l] = a.mk_ge(x, a.mk_numeral(r, true)); + } + + bool inductive = n.pt().check_inductive(n.level(), new_core, uses_level); + + IF_VERBOSE(1, + verbose_stream() << (inductive?"":"non") << "inductive\n"; + for (unsigned j = 0; j < new_core.size(); ++j) { + verbose_stream() << mk_pp(new_core[j].get(), m) << "\n"; + }); + + if (inductive) { + core.reset(); + core.append(new_core); + } + } + } + + void core_arith_inductive_generalizer::insert_bound(bool is_lower, expr* x, rational const& r, unsigned i) { + if (r.is_neg()) { + expr_ref e(m); + e = a.mk_uminus(x); + m_refs.push_back(e); + x = e; + is_lower = !is_lower; + } + + if (is_lower) { + m_lb.insert(abs(r), std::make_pair(x, i)); + } + else { + m_ub.insert(abs(r), std::make_pair(x, i)); + } + } + + void core_arith_inductive_generalizer::reset() { + m_refs.reset(); + m_lb.reset(); + m_ub.reset(); + } + + void core_arith_inductive_generalizer::get_eqs(expr_ref_vector const& core, svector& eqs) { + expr* e1, *x, *y; + expr_ref e(m); + rational r; + + for (unsigned i = 0; i < core.size(); ++i) { + e = core[i]; + if (m.is_not(e, e1) && a.is_le(e1, x, y) && a.is_numeral(y, r) && a.is_int(x)) { + // not (<= x r) <=> x >= r + 1 + insert_bound(true, x, r + rational(1), i); + } + else if (m.is_not(e, e1) && a.is_ge(e1, x, y) && a.is_numeral(y, r) && a.is_int(x)) { + // not (>= x r) <=> x <= r - 1 + insert_bound(false, x, r - rational(1), i); + } + else if (a.is_le(e, x, y) && a.is_numeral(y, r)) { + insert_bound(false, x, r, i); + } + else if (a.is_ge(e, x, y) && a.is_numeral(y, r)) { + insert_bound(true, x, r, i); + } + } + bounds_t::iterator it = m_lb.begin(), end = m_lb.end(); + for (; it != end; ++it) { + rational r = it->m_key; + vector & terms1 = it->m_value; + vector terms2; + if (r >= rational(2) && m_ub.find(r, terms2)) { + bool done = false; + for (unsigned i = 0; !done && i < terms1.size(); ++i) { + for (unsigned j = 0; !done && j < terms2.size(); ++j) { + expr* t1 = terms1[i].first; + expr* t2 = terms2[j].first; + if (t1 == t2) { + eqs.push_back(eq(t1, r, terms1[i].second, terms2[j].second)); + done = true; + } + else { + e = m.mk_eq(t1, t2); + th_rewriter rw(m); + rw(e); + if (m.is_true(e)) { + eqs.push_back(eq(t1, r, terms1[i].second, terms2[j].second)); + done = true; + } + } + } + } + } + } + } + + bool core_arith_inductive_generalizer::substitute_alias(rational const& r, expr* x, expr* e, expr_ref& result) { + rational r2; + expr* y, *z, *e1; + if (m.is_not(e, e1) && substitute_alias(r, x, e1, result)) { + result = m.mk_not(result); + return true; + } + if (a.is_le(e, y, z) && a.is_numeral(z, r2) && r == r2) { + result = a.mk_le(y, x); + return true; + } + if (a.is_ge(e, y, z) && a.is_numeral(z, r2) && r == r2) { + result = a.mk_ge(y, x); + return true; + } + return false; + } // diff --git a/src/muz_qe/pdr_generalizers.h b/src/muz_qe/pdr_generalizers.h index 5f3393682..03bd89c4d 100644 --- a/src/muz_qe/pdr_generalizers.h +++ b/src/muz_qe/pdr_generalizers.h @@ -33,6 +33,37 @@ namespace pdr { virtual void operator()(model_node& n, expr_ref_vector& core, bool& uses_level); }; + template + class r_map : public map { + }; + + class core_arith_inductive_generalizer : public core_generalizer { + typedef std::pair term_loc_t; + typedef r_map > bounds_t; + + ast_manager& m; + arith_util a; + expr_ref_vector m_refs; + bounds_t m_lb; + bounds_t m_ub; + + struct eq { + expr* m_term; + rational m_value; + unsigned m_i; + unsigned m_j; + eq(expr* t, rational const& r, unsigned i, unsigned j): m_term(t), m_value(r), m_i(i), m_j(j) {} + }; + void reset(); + void insert_bound(bool is_lower, expr* x, rational const& r, unsigned i); + void get_eqs(expr_ref_vector const& core, svector& eqs); + bool substitute_alias(rational const&r, expr* x, expr* e, expr_ref& result); + public: + core_arith_inductive_generalizer(context& ctx); + virtual ~core_arith_inductive_generalizer() {} + virtual void operator()(model_node& n, expr_ref_vector& core, bool& uses_level); + }; + class core_farkas_generalizer : public core_generalizer { farkas_learner m_farkas_learner; public: diff --git a/src/muz_qe/pdr_smt_context_manager.cpp b/src/muz_qe/pdr_smt_context_manager.cpp index 42d4b4c20..49ae35423 100644 --- a/src/muz_qe/pdr_smt_context_manager.cpp +++ b/src/muz_qe/pdr_smt_context_manager.cpp @@ -88,7 +88,6 @@ namespace pdr { for (unsigned i = 0; i < assumptions.size(); ++i) { pp.add_assumption(assumptions[i].get()); } - pp.display_smt2(tout, m.mk_true()); static unsigned lemma_id = 0; std::ostringstream strm; @@ -97,6 +96,7 @@ namespace pdr { pp.display_smt2(out, m.mk_true()); out.close(); lemma_id++; + tout << "pdr_check: " << strm.str() << "\n"; }); lbool result = m_context.check(assumptions.size(), assumptions.c_ptr()); if (!m.is_true(m_pred)) { From 91402f2060d8c88ccbc724881a996fc0a72c659e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 8 Feb 2013 18:54:44 +0000 Subject: [PATCH 068/101] C API: fixed mk_context/mk_context_rc exception behaviour Adjusted .NET/Java APIs accordingly. Signed-off-by: Christoph M. Wintersteiger --- examples/java/JavaExample.java | 4 ++-- scripts/update_api.py | 35 +++++++++++++++++++++------------- src/api/api_context.cpp | 4 ++++ src/api/api_util.h | 1 + src/api/java/Context.java | 8 ++++---- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/examples/java/JavaExample.java b/examples/java/JavaExample.java index a26c21d65..c2743ece8 100644 --- a/examples/java/JavaExample.java +++ b/examples/java/JavaExample.java @@ -2155,7 +2155,7 @@ class JavaExample // But you cannot mix numerals of different sorts // even if the size of their domains are the same: // System.out.println(ctx.mkEq(s1, t1)); - } + } public static void main(String[] args) { @@ -2226,7 +2226,7 @@ class JavaExample Context ctx = new Context(cfg); p.quantifierExample3(ctx); p.quantifierExample4(ctx); - } + } Log.close(); if (Log.isOpen()) diff --git a/scripts/update_api.py b/scripts/update_api.py index 08dd012e3..fa6111482 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -395,8 +395,7 @@ def mk_dotnet(): dotnet.write(' public delegate void Z3_error_handler(Z3_context c, Z3_error_code e);\n\n') dotnet.write(' public unsafe class LIB\n') dotnet.write(' {\n') - dotnet.write(' ' - ' const string Z3_DLL_NAME = \"libz3.dll\";\n' + dotnet.write(' const string Z3_DLL_NAME = \"libz3.dll\";\n' ' \n'); dotnet.write(' [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n') dotnet.write(' public extern static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1);\n\n') @@ -420,7 +419,8 @@ def mk_dotnet(): dotnet.write(' }\n') -DotnetUnwrapped = [ 'Z3_del_context' ] +NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc' ] +Unwrapped = [ 'Z3_del_context' ] def mk_dotnet_wrappers(): global Type2Str @@ -469,11 +469,15 @@ def mk_dotnet_wrappers(): dotnet.write('a%d' % i) i = i + 1 dotnet.write(');\n'); - if name not in DotnetUnwrapped: - if len(params) > 0 and param_type(params[0]) == CONTEXT: - dotnet.write(" Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0);\n") - dotnet.write(" if (err != Z3_error_code.Z3_OK)\n") - dotnet.write(" throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err)));\n") + if name not in Unwrapped: + if name in NULLWrapped: + dotnet.write(" if (r == IntPtr.Zero)\n") + dotnet.write(" throw new Z3Exception(\"Object allocation failed.\");\n") + else: + if len(params) > 0 and param_type(params[0]) == CONTEXT: + dotnet.write(" Z3_error_code err = (Z3_error_code)LIB.Z3_get_error_code(a0);\n") + dotnet.write(" if (err != Z3_error_code.Z3_OK)\n") + dotnet.write(" throw new Z3Exception(Marshal.PtrToStringAnsi(LIB.Z3_get_error_msg_ex(a0, (uint)err)));\n") if result == STRING: dotnet.write(" return Marshal.PtrToStringAnsi(r);\n") elif result != VOID: @@ -550,7 +554,7 @@ def mk_java(): java_native.write('%s a%d' % (param2java(param), i)) i = i + 1 java_native.write(')') - if len(params) > 0 and param_type(params[0]) == CONTEXT: + if (len(params) > 0 and param_type(params[0]) == CONTEXT) or name in NULLWrapped: java_native.write(' throws Z3Exception') java_native.write('\n') java_native.write(' {\n') @@ -568,10 +572,15 @@ def mk_java(): java_native.write('a%d' % i) i = i + 1 java_native.write(');\n') - if len(params) > 0 and param_type(params[0]) == CONTEXT: - java_native.write(' Z3_error_code err = Z3_error_code.fromInt(INTERNALgetErrorCode(a0));\n') - java_native.write(' if (err != Z3_error_code.Z3_OK)\n') - java_native.write(' throw new Z3Exception(INTERNALgetErrorMsgEx(a0, err.toInt()));\n') + if name not in Unwrapped: + if name in NULLWrapped: + java_native.write(" if (res == 0)\n") + java_native.write(" throw new Z3Exception(\"Object allocation failed.\");\n") + else: + if len(params) > 0 and param_type(params[0]) == CONTEXT: + java_native.write(' Z3_error_code err = Z3_error_code.fromInt(INTERNALgetErrorCode(a0));\n') + java_native.write(' if (err != Z3_error_code.Z3_OK)\n') + java_native.write(' throw new Z3Exception(INTERNALgetErrorMsgEx(a0, err.toInt()));\n') if result != VOID: java_native.write(' return res;\n') java_native.write(' }\n\n') diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index 6106cb6c7..cf179332a 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -419,17 +419,21 @@ namespace api { extern "C" { Z3_context Z3_API Z3_mk_context(Z3_config c) { + Z3_TRY; LOG_Z3_mk_context(c); memory::initialize(UINT_MAX); Z3_context r = reinterpret_cast(alloc(api::context, reinterpret_cast(c), false)); RETURN_Z3(r); + Z3_CATCH_RETURN_NO_HANDLE(0); } Z3_context Z3_API Z3_mk_context_rc(Z3_config c) { + Z3_TRY; LOG_Z3_mk_context_rc(c); memory::initialize(UINT_MAX); Z3_context r = reinterpret_cast(alloc(api::context, reinterpret_cast(c), true)); RETURN_Z3(r); + Z3_CATCH_RETURN_NO_HANDLE(0); } void Z3_API Z3_del_context(Z3_context c) { diff --git a/src/api/api_util.h b/src/api/api_util.h index c81384f2f..58abf97bf 100644 --- a/src/api/api_util.h +++ b/src/api/api_util.h @@ -26,6 +26,7 @@ Revision History: #define Z3_CATCH_CORE(CODE) } catch (z3_exception & ex) { mk_c(c)->handle_exception(ex); CODE } #define Z3_CATCH Z3_CATCH_CORE(return;) #define Z3_CATCH_RETURN(VAL) Z3_CATCH_CORE(return VAL;) +#define Z3_CATCH_RETURN_NO_HANDLE(VAL) } catch (z3_exception &) { return VAL; } #define CHECK_REF_COUNT(a) (reinterpret_cast(a)->get_ref_count() > 0) #define VALIDATE(a) SASSERT(!a || CHECK_REF_COUNT(a)) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 7a1a404af..3ad136f12 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3053,10 +3053,10 @@ public class Context extends IDisposable // OK. } m_ctx = 0; - } else - /* re-queue the finalizer */ - /* BUG: DRQ's need to be taken over too! */ - new Context(m_ctx, m_refCount); + } + /* + else + CMW: re-queue the finalizer? */ } /** From 9e868cdef39bbd7a5b3faa3bf63978331ffa79e4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 8 Feb 2013 16:04:46 -0800 Subject: [PATCH 069/101] fix pretty printer bug found by ken Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt_pp.cpp | 8 +++++--- src/muz_qe/pdr_generalizers.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 3dc94d3b3..c6c9c7c0c 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -537,7 +537,7 @@ class smt_printer { } void print_bound(symbol const& name) { - if (name.is_numerical() || '?' != name.bare_str()[0]) { + if (!m_is_smt2 && (name.is_numerical() || '?' != name.bare_str()[0])) { m_out << "?"; } m_out << name; @@ -561,7 +561,7 @@ class smt_printer { m_out << "("; print_bound(m_renaming.get_symbol(q->get_decl_name(i))); m_out << " "; - visit_sort(s, true); + visit_sort(s, !m_is-smt2); m_out << ") "; } if (m_is_smt2) { @@ -642,7 +642,9 @@ class smt_printer { m_out << m_var_names[m_num_var_names - idx - 1]; } else { - m_out << "?" << idx; + if (!m_is_smt2) { + m_out << "?" << idx; + } } } diff --git a/src/muz_qe/pdr_generalizers.cpp b/src/muz_qe/pdr_generalizers.cpp index a02a1cb6e..c9141f23e 100644 --- a/src/muz_qe/pdr_generalizers.cpp +++ b/src/muz_qe/pdr_generalizers.cpp @@ -188,8 +188,8 @@ namespace pdr { } } if (abs(r) >= rational(2) && a.is_int(x)) { - new_core[k] = m.mk_eq(a.mk_mod(x, a.mk_numeral(abs(r), true)), a.mk_numeral(rational(0), true)); - new_core[l] = a.mk_ge(x, a.mk_numeral(r, true)); + new_core[k] = m.mk_eq(a.mk_mod(x, a.mk_numeral(rational(2), true)), a.mk_numeral(rational(0), true)); + new_core[l] = a.mk_le(x, a.mk_numeral(r, true)); } bool inductive = n.pt().check_inductive(n.level(), new_core, uses_level); @@ -258,8 +258,8 @@ namespace pdr { vector & terms1 = it->m_value; vector terms2; if (r >= rational(2) && m_ub.find(r, terms2)) { - bool done = false; - for (unsigned i = 0; !done && i < terms1.size(); ++i) { + for (unsigned i = 0; i < terms1.size(); ++i) { + bool done = false; for (unsigned j = 0; !done && j < terms2.size(); ++j) { expr* t1 = terms1[i].first; expr* t2 = terms2[j].first; From dd90667cc7173d9b449a692f06fbdb5017b509ed Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 8 Feb 2013 16:32:53 -0800 Subject: [PATCH 070/101] fix pretty printer bug found by ken Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt_pp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index c6c9c7c0c..420961b4e 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -537,7 +537,7 @@ class smt_printer { } void print_bound(symbol const& name) { - if (!m_is_smt2 && (name.is_numerical() || '?' != name.bare_str()[0])) { + if (!is_smt2 && (name.is_numerical() || '?' != name.bare_str()[0])) { m_out << "?"; } m_out << name; @@ -561,7 +561,7 @@ class smt_printer { m_out << "("; print_bound(m_renaming.get_symbol(q->get_decl_name(i))); m_out << " "; - visit_sort(s, !m_is-smt2); + visit_sort(s, true); m_out << ") "; } if (m_is_smt2) { From 3ad43c60a909908e496b8e55a78a24ee2d3596f0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 8 Feb 2013 16:54:05 -0800 Subject: [PATCH 071/101] working on pdr gen Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 17 +++--- src/ast/ast_ll_pp.cpp | 22 ++++++-- src/muz_qe/pdr_generalizers.cpp | 95 ++++++++++++++++++++++----------- 3 files changed, 93 insertions(+), 41 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 63a450094..a963ab7f7 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1836,14 +1836,17 @@ func_decl * ast_manager::mk_func_decl(symbol const & name, unsigned arity, sort } void ast_manager::check_sort(func_decl const * decl, unsigned num_args, expr * const * args) const { + ast_manager& m = const_cast(*this); if (decl->is_associative()) { sort * expected = decl->get_domain(0); for (unsigned i = 0; i < num_args; i++) { sort * given = get_sort(args[i]); if (!compatible_sorts(expected, given)) { - string_buffer<> buff; - buff << "invalid function application, sort mismatch on argument at position " << (i+1); - throw ast_exception(buff.c_str()); + std::ostringstream buff; + buff << "Invalid function application for " << decl->get_name() << ". "; + buff << "Sort mismatch on argument at position " << (i+1) << ". "; + buff << "Expected: " << mk_pp(expected, m) << " but given " << mk_pp(given, m); + throw ast_exception(buff.str().c_str()); } } } @@ -1855,9 +1858,11 @@ void ast_manager::check_sort(func_decl const * decl, unsigned num_args, expr * c sort * expected = decl->get_domain(i); sort * given = get_sort(args[i]); if (!compatible_sorts(expected, given)) { - string_buffer<> buff; - buff << "invalid function application, sort mismatch on argument at position " << (i+1); - throw ast_exception(buff.c_str()); + std::ostringstream buff; + buff << "Invalid function application for " << decl->get_name() << ". "; + buff << "Sort mismatch on argument at position " << (i+1) << ". "; + buff << "Expected: " << mk_pp(expected, m) << " but given " << mk_pp(given, m); + throw ast_exception(buff.str().c_str()); } } } diff --git a/src/ast/ast_ll_pp.cpp b/src/ast/ast_ll_pp.cpp index 23ae673c9..3dc660681 100644 --- a/src/ast/ast_ll_pp.cpp +++ b/src/ast/ast_ll_pp.cpp @@ -126,7 +126,21 @@ public: m_autil(m) { } - void operator()(sort * n) { + void pp(ast* n) { + ast_mark visited; + pp(n, visited); + } + + void pp(ast* n, ast_mark& visited) { + if (is_sort(n)) { + display_sort(to_sort(n)); + } + else { + for_each_ast(*this, visited, n, true); + } + } + + void operator()(sort* n) { } void operator()(func_decl * n) { @@ -296,17 +310,17 @@ public: void ast_ll_pp(std::ostream & out, ast_manager & m, ast * n, bool only_exprs, bool compact) { ll_printer p(out, m, n, only_exprs, compact); - for_each_ast(p, n, true); + p.pp(n); } void ast_ll_pp(std::ostream & out, ast_manager & m, ast * n, ast_mark & visited, bool only_exprs, bool compact) { ll_printer p(out, m, n, only_exprs, compact); - for_each_ast(p, visited, n, true); + p.pp(n, visited); } void ast_def_ll_pp(std::ostream & out, ast_manager & m, ast * n, ast_mark & visited, bool only_exprs, bool compact) { ll_printer p(out, m, 0, only_exprs, compact); - for_each_ast(p, visited, n, true); + p.pp(n, visited); } void ast_ll_bounded_pp(std::ostream & out, ast_manager & m, ast * n, unsigned depth) { diff --git a/src/muz_qe/pdr_generalizers.cpp b/src/muz_qe/pdr_generalizers.cpp index a02a1cb6e..644f60c90 100644 --- a/src/muz_qe/pdr_generalizers.cpp +++ b/src/muz_qe/pdr_generalizers.cpp @@ -147,8 +147,12 @@ namespace pdr { } - // ----------------------------- + // --------------------------------- // core_arith_inductive_generalizer + // NB. this is trying out some ideas for generalization in + // an ad hoc specialized way. arith_inductive_generalizer should + // not be used by default. It is a place-holder for a general purpose + // extrapolator of a lattice basis. core_arith_inductive_generalizer::core_arith_inductive_generalizer(context& ctx): core_generalizer(ctx), @@ -168,42 +172,50 @@ namespace pdr { svector eqs; get_eqs(core, eqs); - + + if (eqs.empty()) { + return; + } + + expr_ref_vector new_core(m); + new_core.append(core); + for (unsigned eq = 0; eq < eqs.size(); ++eq) { rational r = eqs[eq].m_value; expr* x = eqs[eq].m_term; unsigned k = eqs[eq].m_i; unsigned l = eqs[eq].m_j; - expr_ref_vector new_core(m); - for (unsigned i = 0; i < core.size(); ++i) { - if (i == k || k == l) { - new_core.push_back(m.mk_true()); - } - else { - if (!substitute_alias(r, x, core[i].get(), e)) { - e = core[i].get(); - } - new_core.push_back(e); + new_core[l] = m.mk_true(); + new_core[k] = m.mk_true(); + + for (unsigned i = 0; i < new_core.size(); ++i) { + if (substitute_alias(r, x, new_core[i].get(), e)) { + new_core[i] = e; } } if (abs(r) >= rational(2) && a.is_int(x)) { - new_core[k] = m.mk_eq(a.mk_mod(x, a.mk_numeral(abs(r), true)), a.mk_numeral(rational(0), true)); - new_core[l] = a.mk_ge(x, a.mk_numeral(r, true)); + new_core[k] = m.mk_eq(a.mk_mod(x, a.mk_numeral(rational(2), true)), a.mk_numeral(rational(0), true)); + new_core[l] = a.mk_le(x, a.mk_numeral(rational(0), true)); } + } - bool inductive = n.pt().check_inductive(n.level(), new_core, uses_level); + bool inductive = n.pt().check_inductive(n.level(), new_core, uses_level); - IF_VERBOSE(1, - verbose_stream() << (inductive?"":"non") << "inductive\n"; - for (unsigned j = 0; j < new_core.size(); ++j) { - verbose_stream() << mk_pp(new_core[j].get(), m) << "\n"; - }); - - if (inductive) { - core.reset(); - core.append(new_core); - } + IF_VERBOSE(1, + verbose_stream() << (inductive?"":"non") << "inductive\n"; + verbose_stream() << "old\n"; + for (unsigned j = 0; j < core.size(); ++j) { + verbose_stream() << mk_pp(core[j].get(), m) << "\n"; + } + verbose_stream() << "new\n"; + for (unsigned j = 0; j < new_core.size(); ++j) { + verbose_stream() << mk_pp(new_core[j].get(), m) << "\n"; + }); + + if (inductive) { + core.reset(); + core.append(new_core); } } @@ -289,13 +301,34 @@ namespace pdr { result = m.mk_not(result); return true; } - if (a.is_le(e, y, z) && a.is_numeral(z, r2) && r == r2) { - result = a.mk_le(y, x); - return true; + if (a.is_le(e, y, z) && a.is_numeral(z, r2)) { + if (r == r2) { + result = a.mk_le(y, x); + return true; + } + if (r == r2 + rational(1)) { + result = a.mk_lt(y, x); + return true; + } + if (r == r2 - rational(1)) { + result = a.mk_le(y, a.mk_sub(x, a.mk_numeral(rational(1), a.is_int(x)))); + return true; + } + } - if (a.is_ge(e, y, z) && a.is_numeral(z, r2) && r == r2) { - result = a.mk_ge(y, x); - return true; + if (a.is_ge(e, y, z) && a.is_numeral(z, r2)) { + if (r == r2) { + result = a.mk_ge(y, x); + return true; + } + if (r2 == r + rational(1)) { + result = a.mk_gt(y, x); + return true; + } + if (r2 == r - rational(1)) { + result = a.mk_ge(y, a.mk_sub(x, a.mk_numeral(rational(1), a.is_int(x)))); + return true; + } } return false; } From ef7bc637478743456bfaa65c3d340101d5d7949b Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 8 Feb 2013 19:22:43 -0800 Subject: [PATCH 072/101] Fix compilation error Signed-off-by: Leonardo de Moura --- src/ast/ast_smt_pp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 420961b4e..5bdc70dc2 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -537,7 +537,7 @@ class smt_printer { } void print_bound(symbol const& name) { - if (!is_smt2 && (name.is_numerical() || '?' != name.bare_str()[0])) { + if (!m_is_smt2 && (name.is_numerical() || '?' != name.bare_str()[0])) { m_out << "?"; } m_out << name; From 92695277ed4c0ec306b136533ebe75cd71252ff9 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 8 Feb 2013 19:29:57 -0800 Subject: [PATCH 073/101] Add new example Signed-off-by: Leonardo de Moura --- examples/python/complex/complex.py | 110 +++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 examples/python/complex/complex.py diff --git a/examples/python/complex/complex.py b/examples/python/complex/complex.py new file mode 100644 index 000000000..d90c01e93 --- /dev/null +++ b/examples/python/complex/complex.py @@ -0,0 +1,110 @@ +############################################ +# Copyright (c) 2012 Microsoft Corporation +# +# Complex numbers in Z3 +# See http://research.microsoft.com/en-us/um/people/leonardo/blog/2013/01/26/complex.html +# +# Author: Leonardo de Moura (leonardo) +############################################ +from z3 import * + +def _to_complex(a): + if isinstance(a, ComplexExpr): + return a + else: + return ComplexExpr(a, RealVal(0)) + +def _is_zero(a): + return (isinstance(a, int) and a == 0) or (is_rational_value(a) and a.numerator_as_long() == 0) + +class ComplexExpr: + def __init__(self, r, i): + self.r = r + self.i = i + + def __add__(self, other): + other = _to_complex(other) + return ComplexExpr(self.r + other.r, self.i + other.i) + + def __radd__(self, other): + other = _to_complex(other) + return ComplexExpr(other.r + self.r, other.i + self.i) + + def __sub__(self, other): + other = _to_complex(other) + return ComplexExpr(self.r - other.r, self.i - other.i) + + def __rsub__(self, other): + other = _to_complex(other) + return ComplexExpr(other.r - self.r, other.i - self.i) + + def __mul__(self, other): + other = _to_complex(other) + return ComplexExpr(self.r*other.r - self.i*other.i, self.r*other.i + self.i*other.r) + + def __mul__(self, other): + other = _to_complex(other) + return ComplexExpr(other.r*self.r - other.i*self.i, other.i*self.r + other.r*self.i) + + def inv(self): + den = self.r*self.r + self.i*self.i + return ComplexExpr(self.r/den, -self.i/den) + + def __div__(self, other): + inv_other = _to_complex(other).inv() + return self.__mul__(inv_other) + + def __rdiv__(self, other): + other = _to_complex(other) + return self.inv().__mul__(other) + + def __eq__(self, other): + other = _to_complex(other) + return And(self.r == other.r, self.i == other.i) + + def __neq__(self, other): + return Not(self.__eq__(other)) + + def __pow__(self, k): + + + def simplify(self): + return ComplexExpr(simplify(self.r), simplify(self.i)) + + def repr_i(self): + if is_rational_value(self.i): + return "%s*I" % self.i + else: + return "(%s)*I" % str(self.i) + + def __repr__(self): + if _is_zero(self.i): + return str(self.r) + elif _is_zero(self.r): + return self.repr_i() + else: + return "%s + %s" % (self.r, self.repr_i()) + +def Complex(a): + return ComplexExpr(Real('%s.r' % a), Real('%s.i' % a)) +I = ComplexExpr(RealVal(0), RealVal(1)) + +def evaluate_cexpr(m, e): + return ComplexExpr(m[e.r], m[e.i]) + +x = Complex("x") +s = Tactic('qfnra-nlsat').solver() +s.add(x*x == -2) +print(s) +print(s.check()) +m = s.model() +print('x = %s' % evaluate_cexpr(m, x)) +print((evaluate_cexpr(m,x)*evaluate_cexpr(m,x)).simplify()) +s.add(x.i != -1) +print(s) +print(s.check()) +print(s.model()) +s.add(x.i != 1) +print(s.check()) +# print(s.model()) +print (3 + I)^2/(5 - I) From 3a15db524403ffbb79a3765484fbcb2380710e43 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Tue, 12 Feb 2013 14:34:31 -0800 Subject: [PATCH 074/101] Fix uninterpreted sort definition. There was a mismatch in the behavior of the API and SMT front-ends. The SMT front-ends were using user_sorts to be able to support parametric uninterpreted sorts. After this fix, the API also creates user_sorts. Signed-off-by: Leonardo de Moura --- src/api/api_ast.cpp | 4 ++-- src/ast/ast.cpp | 8 +++++++- src/ast/ast.h | 6 ++++-- src/ast/ast_translation.cpp | 5 ++++- src/ast/seq_decl_plugin.cpp | 4 ++-- src/cmd_context/pdecl.cpp | 4 +--- src/parsers/smt/smtlib.cpp | 2 +- src/parsers/smt/smtparser.cpp | 4 ++-- 8 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index 81a716b12..e93e1a178 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -78,7 +78,7 @@ extern "C" { Z3_TRY; LOG_Z3_mk_uninterpreted_sort(c, name); RESET_ERROR_CODE(); - sort* ty = mk_c(c)->m().mk_sort(to_symbol(name)); + sort* ty = mk_c(c)->m().mk_uninterpreted_sort(to_symbol(name)); mk_c(c)->save_ast_trail(ty); RETURN_Z3(of_sort(ty)); Z3_CATCH_RETURN(0); @@ -620,7 +620,7 @@ extern "C" { CHECK_VALID_AST(t, Z3_UNKNOWN_SORT); family_id fid = to_sort(t)->get_family_id(); decl_kind k = to_sort(t)->get_decl_kind(); - if (fid == null_family_id) { + if (mk_c(c)->m().is_uninterp(to_sort(t))) { return Z3_UNINTERPRETED_SORT; } else if (fid == mk_c(c)->m().get_basic_family_id() && k == BOOL_SORT) { diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 63a450094..04268d1f5 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1816,6 +1816,12 @@ sort * ast_manager::mk_sort(symbol const & name, sort_info * info) { return register_node(new_node); } +sort * ast_manager::mk_uninterpreted_sort(symbol const & name, unsigned num_parameters, parameter const * parameters) { + user_sort_plugin * plugin = get_user_sort_plugin(); + decl_kind kind = plugin->register_name(name); + return plugin->mk_sort(kind, num_parameters, parameters); +} + func_decl * ast_manager::mk_func_decl(symbol const & name, unsigned arity, sort * const * domain, sort * range, bool assoc, bool comm, bool inj) { func_decl_info info(null_family_id, null_decl_kind); @@ -2058,7 +2064,7 @@ sort * ast_manager::mk_fresh_sort(char const * prefix) { string_buffer<32> buffer; buffer << prefix << "!" << m_fresh_id; m_fresh_id++; - return mk_sort(symbol(buffer.c_str())); + return mk_uninterpreted_sort(symbol(buffer.c_str())); } symbol ast_manager::mk_fresh_var_name(char const * prefix) { diff --git a/src/ast/ast.h b/src/ast/ast.h index 3f03b86b9..4c924691c 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -1622,11 +1622,13 @@ private: sort * mk_sort(symbol const & name, sort_info * info); public: - sort * mk_sort(symbol const & name) { return mk_sort(name, 0); } + sort * mk_uninterpreted_sort(symbol const & name, unsigned num_parameters, parameter const * parameters); + + sort * mk_uninterpreted_sort(symbol const & name) { return mk_uninterpreted_sort(name, 0, 0); } sort * mk_sort(symbol const & name, sort_info const & info) { if (info.get_family_id() == null_family_id) { - return mk_sort(name, 0); + return mk_uninterpreted_sort(name); } else { return mk_sort(name, &const_cast(info)); diff --git a/src/ast/ast_translation.cpp b/src/ast/ast_translation.cpp index 8dd6b2f3f..e49edb7ab 100644 --- a/src/ast/ast_translation.cpp +++ b/src/ast/ast_translation.cpp @@ -111,7 +111,10 @@ void ast_translation::mk_sort(sort * s, frame & fr) { sort_info * si = s->get_info(); sort * new_s; if (si == 0) { - new_s = m_to_manager.mk_sort(s->get_name()); + // TODO: investigate: this branch is probably unreachable. + // It became unreachable after we started using mk_uninterpreted_sort for creating uninterpreted sorts, + // and mk_uninterpreted_sort actually creates a user_sort. + new_s = m_to_manager.mk_uninterpreted_sort(s->get_name()); SASSERT(m_result_stack.size() == fr.m_rpos); } else { diff --git a/src/ast/seq_decl_plugin.cpp b/src/ast/seq_decl_plugin.cpp index 44511cd1f..330227193 100644 --- a/src/ast/seq_decl_plugin.cpp +++ b/src/ast/seq_decl_plugin.cpp @@ -117,8 +117,8 @@ void seq_decl_plugin::init() { if(m_init) return; ast_manager& m = *m_manager; m_init = true; - sort* A = m.mk_sort(symbol((unsigned)0)); - sort* B = m.mk_sort(symbol((unsigned)1)); + sort* A = m.mk_uninterpreted_sort(symbol((unsigned)0)); + sort* B = m.mk_uninterpreted_sort(symbol((unsigned)1)); parameter paramA(A); sort* seqA = m.mk_sort(m_family_id, SEQ_SORT, 1, ¶mA); sort* reA = m.mk_sort(m_family_id, RE_SORT, 1, ¶mA); diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index bafd76f0b..44ba2b4d2 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -303,12 +303,10 @@ sort * psort_user_decl::instantiate(pdecl_manager & m, unsigned n, sort * const if (r) return r; if (m_def == 0) { - user_sort_plugin * plugin = m.m().get_user_sort_plugin(); buffer ps; for (unsigned i = 0; i < n; i++) ps.push_back(parameter(s[i])); - decl_kind kind = plugin->register_name(m_name); - r = plugin->mk_sort(kind, ps.size(), ps.c_ptr()); + r = m.m().mk_uninterpreted_sort(m_name, ps.size(), ps.c_ptr()); } else { r = m_def->instantiate(m, s); diff --git a/src/parsers/smt/smtlib.cpp b/src/parsers/smt/smtlib.cpp index 3384e1ffd..d53d3cafa 100644 --- a/src/parsers/smt/smtlib.cpp +++ b/src/parsers/smt/smtlib.cpp @@ -193,7 +193,7 @@ func_decl * theory::declare_func(symbol const & id, sort_ref_buffer & domain, so sort * theory::declare_sort(symbol const & id) { - sort * decl = m_ast_manager.mk_sort(id); + sort * decl = m_ast_manager.mk_uninterpreted_sort(id); m_symtable.insert(id, decl); m_asts.push_back(decl); return decl; diff --git a/src/parsers/smt/smtparser.cpp b/src/parsers/smt/smtparser.cpp index c1ebd251b..b6b40c01a 100644 --- a/src/parsers/smt/smtparser.cpp +++ b/src/parsers/smt/smtparser.cpp @@ -880,8 +880,8 @@ private: if (name == symbol("QF_AX")) { // Hack for supporting new QF_AX theory... - sort * index = m_manager.mk_sort(symbol("Index")); - sort * element = m_manager.mk_sort(symbol("Element")); + sort * index = m_manager.mk_uninterpreted_sort(symbol("Index")); + sort * element = m_manager.mk_uninterpreted_sort(symbol("Element")); parameter params[2] = { parameter(index), parameter(element) }; sort * array = m_manager.mk_sort(m_array_fid, ARRAY_SORT, 2, params); smtlib::symtable* table = m_benchmark.get_symtable(); From a14f29a4eb5251b5c30faf37e4cdb56062ca2c8a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 12 Feb 2013 14:58:04 -0800 Subject: [PATCH 075/101] add hilbert basis utility for extracting auxiliary invariants Signed-off-by: Nikolaj Bjorner --- src/test/ast.cpp | 2 +- src/test/main.cpp | 1 + src/util/heap.h | 18 ++++++++++++++++++ src/util/vector.h | 3 +++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/test/ast.cpp b/src/test/ast.cpp index fce8dafc6..b59e2a612 100644 --- a/src/test/ast.cpp +++ b/src/test/ast.cpp @@ -62,7 +62,7 @@ static void tst1() { // SASSERT(foo_foo_x2 == foo_foo_x); } -void tst2() { +static void tst2() { // ast_manager m; // ast_vector m_nodes(m); diff --git a/src/test/main.cpp b/src/test/main.cpp index 31d71226c..dc253f36d 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -207,6 +207,7 @@ int main(int argc, char ** argv) { TST(horn_subsume_model_converter); TST(model2expr); TST(rcf); + TST(hilbert_basis); } void initialize_mam() {} diff --git a/src/util/heap.h b/src/util/heap.h index dfb741e13..75b41e329 100644 --- a/src/util/heap.h +++ b/src/util/heap.h @@ -238,6 +238,24 @@ public: m_values.swap(other.m_values); m_value2indices.swap(other.m_value2indices); } + + /** + \brief return set of values in heap that are less or equal to val. + */ + void find_le(int val, int_vector& result) { + int_vector todo; + todo.push_back(1); + while (!todo.empty()) { + int index = todo.back(); + todo.pop_back(); + if (index < static_cast(m_values.size()) && + !less_than(val, m_values[index])) { + result.push_back(m_values[index]); + todo.push_back(left(index)); + todo.push_back(right(index)); + } + } + } }; diff --git a/src/util/vector.h b/src/util/vector.h index 484c406c3..a9d36b202 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -179,6 +179,9 @@ public: } vector & operator=(vector const & source) { + if (this == &source) { + return *this; + } destroy(); if (source.m_data) { copy_core(source); From 0fc44a43e1924085b7864a1565caeca9b0d40966 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 12 Feb 2013 14:58:44 -0800 Subject: [PATCH 076/101] add hilbert basis utility for extracting auxiliary invariants Signed-off-by: Nikolaj Bjorner --- src/muz_qe/hilbert_basis.cpp | 782 +++++++++++++++++++++++++++++++++++ src/muz_qe/hilbert_basis.h | 177 ++++++++ src/test/hilbert_basis.cpp | 178 ++++++++ 3 files changed, 1137 insertions(+) create mode 100644 src/muz_qe/hilbert_basis.cpp create mode 100644 src/muz_qe/hilbert_basis.h create mode 100644 src/test/hilbert_basis.cpp diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp new file mode 100644 index 000000000..83bfbc05b --- /dev/null +++ b/src/muz_qe/hilbert_basis.cpp @@ -0,0 +1,782 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + hilbert_basis.cpp + +Abstract: + + Basic Hilbert Basis computation. + +Author: + + Nikolaj Bjorner (nbjorner) 2013-02-09. + +Revision History: + +--*/ + +#include "hilbert_basis.h" +#include "heap.h" +#include "map.h" + +typedef u_map offset_refs_t; + +template +class rational_map : public map {}; + +class rational_lt { + vector & m_values; +public: + rational_lt(vector & values): + m_values(values) { + } + bool operator()(int v1, int v2) const { + return m_values[v1] < m_values[v2]; + } +}; + + +class hilbert_basis::rational_heap { + vector m_u2r; // [index |-> weight] + rational_map m_r2u; // [weight |-> index] + rational_lt m_lt; // less_than on indices + heap m_heap; // binary heap over weights +public: + + rational_heap(): m_lt(m_u2r), m_heap(10, m_lt) {} + + vector& u2r() { return m_u2r; } + + void insert(unsigned v) { + m_heap.insert(v); + } + + void reset() { + m_u2r.reset(); + m_r2u.reset(); + m_heap.reset(); + } + + bool is_declared(numeral const& r, unsigned& val) const { + return m_r2u.find(r, val); + } + + unsigned declare(numeral const& r) { + SASSERT(!m_r2u.contains(r)); + unsigned val = m_u2r.size(); + m_u2r.push_back(r); + m_r2u.insert(r, val); + m_heap.set_bounds(val+1); + return val; + } + + void find_le(unsigned val, int_vector & result) { + m_heap.find_le(val, result); + } + + void find_le(numeral const& r, int_vector& result) { + find_le(m_r2u.find(r), result); + } +}; + +class hilbert_basis::weight_map { + rational_heap m_heap; + vector m_offsets; // [index |-> offset-list] + int_vector m_le; // recycled set of indices with lesser weights + + unsigned get_value(numeral const& w) { + unsigned val; + if (!m_heap.is_declared(w, val)) { + val = m_heap.declare(w); + SASSERT(val == m_offsets.size()); + if (w.is_nonneg()) { + m_heap.insert(val); + } + m_offsets.push_back(unsigned_vector()); + } + return val; + } +public: + weight_map() {} + + void insert(offset_t idx, numeral const& w) { + unsigned val = get_value(w); + m_offsets[val].push_back(idx.m_offset); + } + + void remove(offset_t idx, numeral const& w) { + unsigned val = get_value(w); + m_offsets[val].erase(idx.m_offset); + } + + void reset() { + m_offsets.reset(); + m_heap.reset(); + m_le.reset(); + } + + bool init_find(offset_refs_t& refs, numeral const& w, offset_t idx, offset_t& found_idx, unsigned& cost) { + //std::cout << "init find: " << w << "\n"; + m_le.reset(); + unsigned val = get_value(w); + // for positive values, the weights should be less or equal. + // for non-positive values, the weights have to be the same. + if (w.is_pos()) { + m_heap.find_le(val, m_le); + } + else { + m_le.push_back(val); + } + bool found = false; + for (unsigned i = 0; i < m_le.size(); ++i) { + if (m_heap.u2r()[m_le[i]].is_zero() && w.is_pos()) { + continue; + } + //std::cout << "insert init find: " << m_weights[m_le[i]] << "\n"; + unsigned_vector const& offsets = m_offsets[m_le[i]]; + for (unsigned j = 0; j < offsets.size(); ++j) { + unsigned offs = offsets[j]; + ++cost; + if (offs != idx.m_offset) { + refs.insert(offs, 0); + found_idx = offset_t(offs); + found = true; + } + } + } + return found; + } + + bool update_find(offset_refs_t& refs, unsigned round, numeral const& w, + offset_t idx, offset_t& found_idx, unsigned& cost) { + //std::cout << "update find: " << w << "\n"; + m_le.reset(); + m_heap.find_le(w, m_le); + bool found = false; + unsigned vl; + for (unsigned i = 0; i < m_le.size(); ++i) { + //std::cout << "insert update find: " << m_weights[m_le[i]] << "\n"; + unsigned_vector const& offsets = m_offsets[m_le[i]]; + for (unsigned j = 0; j < offsets.size(); ++j) { + unsigned offs = offsets[j]; + ++cost; + if (offs != idx.m_offset && refs.find(offs, vl) && vl == round) { + refs.insert(offs, round + 1); + found_idx = offset_t(offs); + found = true; + } + } + } + return found; + } +}; + + +class hilbert_basis::index { + // for each index, a heap of weights. + // for each weight a list of offsets + + struct stats { + unsigned m_num_comparisons; + unsigned m_num_find; + unsigned m_num_insert; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + ptr_vector m_values; + weight_map m_weight; + offset_refs_t m_refs; + stats m_stats; + +public: + + ~index() { + for (unsigned i = 0; i < m_values.size(); ++i) { + dealloc(m_values[i]); + } + } + + void init(unsigned num_vars) { + if (m_values.empty()) { + for (unsigned i = 0; i < num_vars; ++i) { + m_values.push_back(alloc(weight_map)); + } + } + SASSERT(m_values.size() == num_vars); + } + + void insert(offset_t idx, values vs, numeral const& weight) { + ++m_stats.m_num_insert; + for (unsigned i = 0; i < m_values.size(); ++i) { + m_values[i]->insert(idx, vs[i]); + } + m_weight.insert(idx, weight); + } + + void remove(offset_t idx, values vs, numeral const& weight) { + for (unsigned i = 0; i < m_values.size(); ++i) { + m_values[i]->remove(idx, vs[i]); + } + m_weight.remove(idx, weight); + } + + bool find(values vs, numeral const& weight, offset_t idx, offset_t& found_idx) { + ++m_stats.m_num_find; + bool found = m_weight.init_find(m_refs, weight, idx, found_idx, m_stats.m_num_comparisons); + for (unsigned i = 0; found && i < m_values.size(); ++i) { + found = m_values[i]->update_find(m_refs, i, vs[i], idx, found_idx, m_stats.m_num_comparisons); + } + m_refs.reset(); + return found; + } + + void reset() { + for (unsigned i = 0; i < m_values.size(); ++i) { + m_values[i]->reset(); + } + m_weight.reset(); + m_refs.reset(); + } + + void collect_statistics(statistics& st) const { + st.update("hb.index.num_comparisons", m_stats.m_num_comparisons); + st.update("hb.index.num_find", m_stats.m_num_find); + st.update("hb.index.num_insert", m_stats.m_num_insert); + } + + void reset_statistics() { + m_stats.reset(); + } + +#if 0 + // remains of a simpler index strucure: + if (eval(idx).is_zero()) { + for (unsigned i = 0; i < m_zero.size(); ++i) { + if (is_subsumed(idx, m_zero[i])) { + ++m_stats.m_num_subsumptions; + return true; + } + } + return false; + } + for (unsigned i = 0; i < m_active.size(); ++i) { + if (is_subsumed(idx, m_active[i])) { + ++m_stats.m_num_subsumptions; + return true; + } + } + passive::iterator it = m_passive->begin(); + passive::iterator end = m_passive->end(); + + for (; it != end; ++it) { + if (is_subsumed(idx, *it)) { + ++m_stats.m_num_subsumptions; + return true; + } + } +#endif + +}; + +/** + \brief priority queue for passive list. +*/ + +class hilbert_basis::passive { + hilbert_basis& hb; + svector m_passive; + vector m_weights; + unsigned_vector m_free_list; + rational_lt m_lt; // less_than on indices + heap m_heap; // binary heap over weights + + numeral get_weight(offset_t idx) { + numeral w(0); + unsigned nv = hb.get_num_vars(); + for (unsigned i = 0; i < nv; ++i) { + w += hb.vec(idx)[i]; + } + return w; + } + +public: + + passive(hilbert_basis& hb): + hb(hb) , + m_lt(m_weights), + m_heap(10, m_lt) + {} + + void reset() { + m_heap.reset(); + m_free_list.reset(); + m_weights.reset(); + m_passive.reset(); + } + + bool empty() const { + return m_heap.empty(); + } + + offset_t pop() { + SASSERT(!empty()); + unsigned val = static_cast(m_heap.erase_min()); + offset_t result = m_passive[val]; + m_free_list.push_back(val); + m_passive[val] = mk_invalid_offset(); + return result; + } + + void insert(offset_t idx) { + unsigned v; + if (m_free_list.empty()) { + v = m_passive.size(); + m_passive.push_back(idx); + m_weights.push_back(get_weight(idx)); + m_heap.set_bounds(v+1); + } + else { + v = m_free_list.back(); + m_free_list.pop_back(); + m_passive[v] = idx; + m_weights[v] = get_weight(idx); + } + m_heap.insert(v); + } + + class iterator { + passive& p; + unsigned m_idx; + void fwd() { + while (m_idx < p.m_passive.size() && + is_invalid_offset(p.m_passive[m_idx])) { + ++m_idx; + } + } + public: + iterator(passive& p, unsigned i): p(p), m_idx(i) { fwd(); } + offset_t operator*() const { return p.m_passive[m_idx]; } + iterator& operator++() { ++m_idx; fwd(); return *this; } + iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } + bool operator==(iterator const& it) const {return m_idx == it.m_idx; } + bool operator!=(iterator const& it) const {return m_idx != it.m_idx; } + + }; + + iterator begin() { + return iterator(*this, 0); + } + + iterator end() { + return iterator(*this, m_passive.size()); + } +}; + +hilbert_basis::hilbert_basis(): + m_cancel(false) +{ + m_index = alloc(index); + m_passive = alloc(passive, *this); +} + +hilbert_basis::~hilbert_basis() { + dealloc(m_index); + dealloc(m_passive); +} + +hilbert_basis::offset_t hilbert_basis::mk_invalid_offset() { + return offset_t(UINT_MAX); +} + +bool hilbert_basis::is_invalid_offset(offset_t offs) { + return offs.m_offset == UINT_MAX; +} + +void hilbert_basis::reset() { + m_ineqs.reset(); + m_basis.reset(); + m_store.reset(); + m_free_list.reset(); + m_eval.reset(); + m_active.reset(); + m_passive->reset(); + m_zero.reset(); + m_index->reset(); + m_cancel = false; +} + +void hilbert_basis::collect_statistics(statistics& st) const { + st.update("hb.num_subsumptions", m_stats.m_num_subsumptions); + st.update("hb.num_resolves", m_stats.m_num_resolves); + m_index->collect_statistics(st); +} + +void hilbert_basis::reset_statistics() { + m_stats.reset(); + m_index->reset_statistics(); +} + +void hilbert_basis::add_ge(num_vector const& v) { + SASSERT(m_ineqs.empty() || v.size() == get_num_vars()); + if (m_ineqs.empty()) { + m_index->init(v.size()); + } + m_ineqs.push_back(v); +} + +void hilbert_basis::add_le(num_vector const& v) { + num_vector w(v); + for (unsigned i = 0; i < w.size(); ++i) { + w[i].neg(); + } + add_ge(w); +} + +void hilbert_basis::add_eq(num_vector const& v) { + add_le(v); + add_ge(v); +} + +unsigned hilbert_basis::get_num_vars() const { + if (m_ineqs.empty()) { + return 0; + } + else { + return m_ineqs.back().size(); + } +} + +hilbert_basis::values hilbert_basis::vec(offset_t offs) const { + return m_store.c_ptr() + offs.m_offset; +} + +hilbert_basis::values_ref hilbert_basis::vec(offset_t offs) { + return m_store.c_ptr() + offs.m_offset; +} + +void hilbert_basis::init_basis() { + m_basis.reset(); + m_store.reset(); + m_eval.reset(); + m_free_list.reset(); + unsigned num_vars = get_num_vars(); + for (unsigned i = 0; i < num_vars; ++i) { + num_vector w(num_vars, numeral(0)); + w[i] = numeral(1); + offset_t idx = alloc_vector(); + set_value(idx, w.c_ptr()); + m_basis.push_back(idx); + } +} + +lbool hilbert_basis::saturate() { + init_basis(); + for (unsigned i = 0; !m_cancel && i < m_ineqs.size(); ++i) { + lbool r = saturate(m_ineqs[i]); + if (r != l_true) { + return r; + } + } + if (m_cancel) { + return l_undef; + } + return l_true; +} + +lbool hilbert_basis::saturate(num_vector const& ineq) { + m_active.reset(); + m_passive->reset(); + m_zero.reset(); + m_index->reset(); + TRACE("hilbert_basis", display_ineq(tout, ineq);); + bool has_non_negative = false; + iterator it = begin(); + for (; it != end(); ++it) { + numeral n = eval(vec(*it), ineq); + eval(*it) = n; + add_goal(*it); + if (n.is_nonneg()) { + has_non_negative = true; + } + } + TRACE("hilbert_basis", display(tout);); + if (!has_non_negative) { + return l_false; + } + // resolve passive into active + while (!m_passive->empty()) { + if (m_cancel) { + return l_undef; + } + offset_t idx = m_passive->pop(); + TRACE("hilbert_basis", display(tout);); + if (is_subsumed(idx)) { + recycle(idx); + continue; + } + for (unsigned i = 0; !m_cancel && i < m_active.size(); ++i) { + if (get_sign(idx) != get_sign(m_active[i])) { + offset_t j = alloc_vector(); + resolve(idx, m_active[i], j); + add_goal(j); + } + } + m_active.push_back(idx); + } + // Move positive from active and zeros to new basis. + m_basis.reset(); + m_basis.append(m_zero); + for (unsigned i = 0; i < m_active.size(); ++i) { + offset_t idx = m_active[i]; + if (eval(idx).is_pos()) { + m_basis.push_back(idx); + } + else { + m_free_list.push_back(idx); + } + } + m_active.reset(); + m_passive->reset(); + m_zero.reset(); + TRACE("hilbert_basis", display(tout);); + return l_true; +} + + +void hilbert_basis::set_value(offset_t offs, values v) { + unsigned nv = get_num_vars(); + for (unsigned i = 0; i < nv; ++i) { + m_store[offs.m_offset+i] = v[i]; + } +} + +void hilbert_basis::recycle(offset_t idx) { + m_index->remove(idx, vec(idx), eval(idx)); + m_free_list.push_back(idx); +} + +void hilbert_basis::resolve(offset_t i, offset_t j, offset_t r) { + ++m_stats.m_num_resolves; + values v = vec(i); + values w = vec(j); + values_ref u = vec(r); + unsigned nv = get_num_vars(); + for (unsigned k = 0; k < nv; ++k) { + u[k] = v[k] + w[k]; + } + eval(r) = eval(i) + eval(j); + TRACE("hilbert_basis_verbose", + display(tout, i); + display(tout, j); + display(tout, r); + ); + +} + +hilbert_basis::offset_t hilbert_basis::alloc_vector() { + if (m_free_list.empty()) { + unsigned num_vars = get_num_vars(); + unsigned idx = m_store.size(); + m_store.resize(idx + get_num_vars()); + m_eval.push_back(numeral(0)); + return offset_t(idx); + } + else { + offset_t result = m_free_list.back(); + m_free_list.pop_back(); + return result; + } +} + + +void hilbert_basis::add_goal(offset_t idx) { + m_index->insert(idx, vec(idx), eval(idx)); + if (eval(idx).is_zero()) { + if (!is_subsumed(idx)) { + m_zero.push_back(idx); + } + } + else { + m_passive->insert(idx); + } +} + +bool hilbert_basis::is_subsumed(offset_t idx) { + + offset_t found_idx; + if (m_index->find(vec(idx), eval(idx), idx, found_idx)) { + TRACE("hilbert_basis", + display(tout, idx); + tout << " <= \n"; + display(tout, found_idx); + tout << "\n";); + ++m_stats.m_num_subsumptions; + return true; + } + return false; +} + +/** + Vector v is subsumed by vector w if + + v[i] >= w[i] for each index i. + + a*v >= a*w for the evaluation of vectors with respect to a. + + a*v < 0 => a*v = a*w + + + Justification: + + let u := v - w, then + + u[i] >= 0 for each index i + + a*u = a*(v-w) >= 0 + + So v = u + w, where a*u >= 0, a*w >= 0. + + If a*v >= a*w >= 0 then v and w are linear + solutions of e_i, and also v-w is a solution. + + If a*v = a*w < 0, then a*(v-w) = 0, so v can be obtained from w + (v - w). + + */ + +bool hilbert_basis::is_subsumed(offset_t i, offset_t j) const { + values v = vec(i); + values w = vec(j); + numeral const& n = eval(i); + numeral const& m = eval(j); + bool r = + i.m_offset != j.m_offset && + n >= m && (!m.is_neg() || n == m) && + is_geq(v, w); + CTRACE("hilbert_basis", r, + display(tout, i); + tout << " <= \n"; + display(tout, j); + tout << "\n";); + return r; +} + +bool hilbert_basis::is_geq(values v, values w) const { + unsigned nv = get_num_vars(); + for (unsigned i = 0; i < nv; ++i) { + if (v[i] < w[i]) { + return false; + } + } + return true; +} + +hilbert_basis::sign_t hilbert_basis::get_sign(offset_t idx) const { + if (eval(idx).is_pos()) { + return pos; + } + if (eval(idx).is_neg()) { + return neg; + } + return zero; +} + +hilbert_basis::numeral hilbert_basis::eval(values val, num_vector const& ineq) const { + numeral result(0); + unsigned num_vars = get_num_vars(); + for (unsigned i = 0; i < num_vars; ++i) { + result += val[i]*ineq[i]; + } + return result; +} + +void hilbert_basis::display(std::ostream& out) const { + unsigned nv = get_num_vars(); + out << "inequalities:\n"; + for (unsigned i = 0; i < m_ineqs.size(); ++i) { + display_ineq(out, m_ineqs[i]); + } + if (!m_basis.empty()) { + out << "basis:\n"; + for (iterator it = begin(); it != end(); ++it) { + display(out, *it); + } + } + if (!m_active.empty()) { + out << "active:\n"; + for (unsigned i = 0; i < m_active.size(); ++i) { + display(out, m_active[i]); + } + } + if (!m_passive->empty()) { + passive::iterator it = m_passive->begin(); + passive::iterator end = m_passive->end(); + out << "passive:\n"; + for (; it != end; ++it) { + display(out, *it); + } + } + if (!m_zero.empty()) { + out << "zero:\n"; + for (unsigned i = 0; i < m_zero.size(); ++i) { + display(out, m_zero[i]); + } + } + +} + +void hilbert_basis::display(std::ostream& out, offset_t o) const { + display(out, vec(o)); + out << " -> " << eval(o) << "\n"; +} + +void hilbert_basis::display(std::ostream& out, values v) const { + unsigned nv = get_num_vars(); + for (unsigned j = 0; j < nv; ++j) { + out << v[j] << " "; + } +} + +void hilbert_basis::display_ineq(std::ostream& out, num_vector const& v) const { + unsigned nv = get_num_vars(); + for (unsigned j = 0; j < nv; ++j) { + if (!v[j].is_zero()) { + if (j > 0) { + if (v[j].is_pos()) { + out << " + "; + } + else { + out << " - "; + } + } + else if (j == 0 && v[0].is_neg()) { + out << "-"; + } + if (!v[j].is_one() && !v[j].is_minus_one()) { + out << abs(v[j]) << "*"; + } + out << "x" << j; + } + } + out << " >= 0\n"; +} + +void hilbert_sl_basis::add_le(num_vector const& v, numeral bound) { + num_vector w; + w.push_back(-bound); + w.append(v); + m_basis.add_le(w); +} + +void hilbert_isl_basis::add_le(num_vector const& v, numeral bound) { + unsigned sz = v.size(); + num_vector w; + for (unsigned i = 0; i < sz; ++i) { + w.push_back(v[i]); + w.push_back(-v[i]); + } + w.push_back(-bound); + w.push_back(bound); + m_basis.add_le(w); +} diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h new file mode 100644 index 000000000..542b680b0 --- /dev/null +++ b/src/muz_qe/hilbert_basis.h @@ -0,0 +1,177 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + hilbert_basis.h + +Abstract: + + Basic Hilbert Basis computation. + + hilbert_basis computes a Hilbert basis for linear + homogeneous inequalities over naturals. + hilbert_sl_basis computes a semi-linear set over naturals. + hilbert_isl_basis computes semi-linear sets over integers. + +Author: + + Nikolaj Bjorner (nbjorner) 2013-02-09. + +Revision History: + +--*/ + +#ifndef _HILBERT_BASIS_H_ +#define _HILBERT_BASIS_H_ + +#include "rational.h" +#include "lbool.h" +#include "statistics.h" + +class hilbert_basis { +public: + typedef rational numeral; + typedef vector num_vector; +private: + class rational_heap; + class index; + class passive; + class weight_map; + struct offset_t { + unsigned m_offset; + offset_t(unsigned o) : m_offset(o) {} + offset_t(): m_offset(0) {} + bool operator<(offset_t const& other) const { + return m_offset < other.m_offset; + } + }; + enum sign_t { pos, neg, zero }; + struct stats { + unsigned m_num_subsumptions; + unsigned m_num_resolves; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + typedef numeral const* values; + typedef numeral* values_ref; + + vector m_ineqs; + num_vector m_store; + num_vector m_eval; + svector m_basis; + svector m_free_list; + svector m_active; + svector m_zero; + volatile bool m_cancel; + stats m_stats; + index* m_index; + passive* m_passive; + class iterator { + hilbert_basis const& hb; + unsigned m_idx; + public: + iterator(hilbert_basis const& hb, unsigned idx): hb(hb), m_idx(idx) {} + offset_t operator*() const { return hb.m_basis[m_idx]; } + iterator& operator++() { ++m_idx; return *this; } + iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } + bool operator==(iterator const& it) const {return m_idx == it.m_idx; } + bool operator!=(iterator const& it) const {return m_idx != it.m_idx; } + }; + + static offset_t mk_invalid_offset(); + static bool is_invalid_offset(offset_t offs); + lbool saturate(num_vector const& ineq); + void init_basis(); + unsigned get_num_vars() const; + numeral eval(values val, num_vector const& ineq) const; + bool is_subsumed(offset_t idx); + bool is_subsumed(offset_t i, offset_t j) const; + bool is_geq(values v, values w) const; + void recycle(offset_t idx); + sign_t hilbert_basis::get_sign(offset_t idx) const; + void add_goal(offset_t idx); + offset_t alloc_vector(); + void resolve(offset_t i, offset_t j, offset_t r); + iterator begin() const { return iterator(*this,0); } + iterator end() const { return iterator(*this, m_basis.size()); } + + values vec(offset_t offs) const; + values_ref vec(offset_t offs); + numeral const& eval(offset_t o) const { + return m_eval[o.m_offset/get_num_vars()]; + } + numeral& eval(offset_t o) { + return m_eval[o.m_offset/get_num_vars()]; + } + + void set_value(offset_t offs, values v); + + void display(std::ostream& out, offset_t o) const; + void display(std::ostream& out, values v) const; + void display_ineq(std::ostream& out, num_vector const& v) const; + +public: + + hilbert_basis(); + ~hilbert_basis(); + + void reset(); + + // add inequality v*x <= 0 + // add inequality v*x >= 0 + // add equality v*x = 0 + + void add_le(num_vector const& v); + void add_ge(num_vector const& v); + void add_eq(num_vector const& v); + + lbool saturate(); + + void set_cancel(bool f) { m_cancel = f; } + + void display(std::ostream& out) const; + + void collect_statistics(statistics& st) const; + void reset_statistics(); + +}; + +class hilbert_sl_basis { +public: + typedef rational numeral; + typedef vector num_vector; +private: + hilbert_basis m_basis; +public: + hilbert_sl_basis() {} + void reset() { m_basis.reset(); } + + // add inequality v*x >= bound, x ranges over naturals + void add_le(num_vector const& v, numeral bound); + lbool saturate() { return m_basis.saturate(); } + void set_cancel(bool f) { m_basis.set_cancel(f); } + void display(std::ostream& out) const { m_basis.display(out); } + + void collect_statistics(statistics& st) const { m_basis.collect_statistics(st); } + void reset_statistics() { m_basis.reset_statistics(); } +}; + +class hilbert_isl_basis { +public: + typedef rational numeral; + typedef vector num_vector; +private: + hilbert_basis m_basis; +public: + hilbert_isl_basis() {} + void reset() { m_basis.reset(); } + + // add inequality v*x >= bound, x ranges over integers + void add_le(num_vector const& v, numeral bound); + lbool saturate() { return m_basis.saturate(); } + void set_cancel(bool f) { m_basis.set_cancel(f); } + void display(std::ostream& out) const { m_basis.display(out); } +}; + +#endif diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp new file mode 100644 index 000000000..267ad9ae5 --- /dev/null +++ b/src/test/hilbert_basis.cpp @@ -0,0 +1,178 @@ +#include "hilbert_basis.h" + + +static vector vec(int i, int j, int k) { + vector nv; + nv.resize(3); + nv[0] = rational(i); + nv[1] = rational(j); + nv[2] = rational(k); + return nv; +} + +static vector vec(int i, int j, int k, int l) { + vector nv; + nv.resize(4); + nv[0] = rational(i); + nv[1] = rational(j); + nv[2] = rational(k); + nv[3] = rational(l); + return nv; +} + +static vector vec(int i, int j, int k, int l, int x, int y, int z) { + vector nv; + nv.resize(7); + nv[0] = rational(i); + nv[1] = rational(j); + nv[2] = rational(k); + nv[3] = rational(l); + nv[4] = rational(x); + nv[5] = rational(y); + nv[6] = rational(z); + return nv; +} + +static void saturate_basis(hilbert_sl_basis& hb) { + lbool is_sat = hb.saturate(); + + switch(is_sat) { + case l_true: + std::cout << "sat\n"; + hb.display(std::cout); + break; + case l_false: + std::cout << "unsat\n"; + break; + case l_undef: + std::cout << "undef\n"; + break; + } + statistics st; + hb.collect_statistics(st); + st.display(std::cout); +} + + +static void saturate_basis(hilbert_basis& hb) { + lbool is_sat = hb.saturate(); + + switch(is_sat) { + case l_true: + std::cout << "sat\n"; + hb.display(std::cout); + break; + case l_false: + std::cout << "unsat\n"; + break; + case l_undef: + std::cout << "undef\n"; + break; + } + statistics st; + hb.collect_statistics(st); + st.display(std::cout); +} + + +// example 9, Ajili, Contenjean +// x + y - 2z = 0 +// x - z = 0 +// -y + z <= 0 + +static void tst1() { + hilbert_basis hb; + hb.add_eq(vec(1,1,-2)); + hb.add_eq(vec(1,0,-1)); + hb.add_le(vec(0,1,-1)); + saturate_basis(hb); +} + + +// example 10, Ajili, Contenjean +// 23x - 12y - 9z <= 0 +// x - 8y - 8z <= 0 +void tst2() { + hilbert_basis hb; + + hb.add_eq(vec(-23,12,9)); + hb.add_eq(vec(-1,8,8)); + + saturate_basis(hb); +} + +// example 6, Ajili, Contenjean +// 3x + 2y - z - 2u <= 0 +static void tst3() { + hilbert_basis hb; + hb.add_le(vec(3,2,-1,-2)); + saturate_basis(hb); +} + +#define R rational + +// Sigma_1, table 1, Ajili, Contejean +static void tst4() { + hilbert_sl_basis hb; + hb.add_le(vec( 0,-2, 1, 3, 2,-2, 3), R(3)); + hb.add_le(vec(-1, 7, 0, 1, 3, 5,-4), R(2)); + hb.add_le(vec( 0,-1, 1,-1,-1, 0, 0), R(2)); + hb.add_le(vec(-2, 0, 1, 4, 0, 0,-2), R(1)); + hb.add_le(vec(-3, 2,-2, 2,-4,-1, 0), R(8)); + hb.add_le(vec( 3,-2, 2,-2, 4, 1, 0), R(3)); + hb.add_le(vec( 1, 0, 0,-1, 0, 1, 0), R(4)); + hb.add_le(vec( 1,-2, 0, 0, 0, 0, 0), R(2)); + hb.add_le(vec( 1, 1, 0, 0,-1, 0, 1), R(4)); + hb.add_le(vec( 1, 0, 0, 0,-1, 0, 0), R(9)); + saturate_basis(hb); +} + +// Sigma_2 table 1, Ajili, Contejean +static void tst5() { + hilbert_sl_basis hb; + hb.add_le(vec( 1, 2,-1, 1), R(3)); + hb.add_le(vec( 2, 4, 1, 2), R(12)); + hb.add_le(vec( 1, 4, 2, 1), R(9)); + hb.add_le(vec( 1, 1, 0,-1), R(10)); + hb.add_le(vec( 1, 1,-1, 0), R(6)); + hb.add_le(vec( 1,-1, 0, 0), R(0)); + hb.add_le(vec( 0, 0, 1,-1), R(2)); + saturate_basis(hb); +} + +// Sigma_3 table 1, Ajili, Contejean +static void tst6() { + hilbert_sl_basis hb; + hb.add_le(vec( 4, 3, 0), R(6)); + hb.add_le(vec(-3,-4, 0), R(-1)); + hb.add_le(vec( 4, 0,-3), R(3)); + hb.add_le(vec(-3, 0, 4), R(7)); + hb.add_le(vec( 4, 0,-3), R(23)); + hb.add_le(vec( 0,-3, 4), R(11)); + saturate_basis(hb); +} + +// Sigma_4 table 1, Ajili, Contejean +static void tst7() { + hilbert_sl_basis hb; + hb.add_le(vec( 2, 1, 0, 1), R(6)); + hb.add_le(vec( 1, 2, 1, 1), R(7)); + hb.add_le(vec( 1, 3,-1, 2), R(8)); + hb.add_le(vec( 1, 2,-9,-12), R(-11)); + hb.add_le(vec( 0, 0,-1, 3), R(10)); + saturate_basis(hb); +} + + +void tst_hilbert_basis() { + std::cout << "hilbert basis test\n"; + tst1(); + tst2(); + tst3(); +#if 0 + tst4(); + tst5(); + tst6(); + tst7(); +#endif +} From 0879c6f0529ea2156497caf3c8fc710efe2b39c0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 12 Feb 2013 18:13:02 -0800 Subject: [PATCH 077/101] updating tests Signed-off-by: Nikolaj Bjorner --- src/test/hilbert_basis.cpp | 45 ++++++++++++++++++++++++++++++++++++++ src/test/matcher.cpp | 4 ++-- src/test/var_subst.cpp | 2 +- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index 267ad9ae5..5edc4cf99 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -20,6 +20,17 @@ static vector vec(int i, int j, int k, int l) { return nv; } +static vector vec(int i, int j, int k, int l, int m) { + vector nv; + nv.resize(5); + nv[0] = rational(i); + nv[1] = rational(j); + nv[2] = rational(k); + nv[3] = rational(l); + nv[4] = rational(m); + return nv; +} + static vector vec(int i, int j, int k, int l, int x, int y, int z) { vector nv; nv.resize(7); @@ -164,6 +175,40 @@ static void tst7() { } +// Sigma_5 table 1, Ajili, Contejean +static void tst8() { + hilbert_sl_basis hb; + hb.add_le(vec( 2, 1, 1), R(2)); + hb.add_le(vec( 1, 2, 3), R(5)); + hb.add_le(vec( 2, 2, 3), R(6)); + hb.add_le(vec( 1,-1,-3), R(-2)); + saturate_basis(hb); +} + +// Sigma_6 table 1, Ajili, Contejean +static void tst9() { + hilbert_sl_basis hb; + hb.add_le(vec( 1, 2, 3), R(11)); + hb.add_le(vec( 2, 2, 5), R(13)); + hb.add_le(vec( 1,-1,-11), R(3)); + saturate_basis(hb); +} + +// Sigma_7 table 1, Ajili, Contejean +static void tst10() { + hilbert_sl_basis hb; + hb.add_le(vec( 1,-1,-1,-3), R(2)); + hb.add_le(vec(-2, 3, 3, 5), R(3)); + saturate_basis(hb); +} + +// Sigma_8 table 1, Ajili, Contejean +static void tst11() { + hilbert_sl_basis hb; + hb.add_le(vec( 7,-2,11, 3, -5), R(5)); + saturate_basis(hb); +} + void tst_hilbert_basis() { std::cout << "hilbert basis test\n"; tst1(); diff --git a/src/test/matcher.cpp b/src/test/matcher.cpp index cfbab2d3c..05d971e24 100644 --- a/src/test/matcher.cpp +++ b/src/test/matcher.cpp @@ -52,7 +52,7 @@ void tst_match(ast_manager & m, app * t, app * i) { s.display(std::cout); // create some dummy term to test for applying the substitution. - sort_ref S( m.mk_sort(symbol("S")), m); + sort_ref S( m.mk_uninterpreted_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); @@ -75,7 +75,7 @@ void tst_match(ast_manager & m, app * t, app * i) { void tst1() { ast_manager m; reg_decl_plugins(m); - sort_ref s( m.mk_sort(symbol("S")), m); + sort_ref s( m.mk_uninterpreted_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}; diff --git a/src/test/var_subst.cpp b/src/test/var_subst.cpp index 3e75d1527..e82c09218 100644 --- a/src/test/var_subst.cpp +++ b/src/test/var_subst.cpp @@ -62,7 +62,7 @@ void tst_subst(ast_manager& m) { obj_ref x(m), y(m), z(m), u(m), v(m); expr_ref e1(m), e2(m), e3(m); expr_ref t1(m), t2(m), t3(m); - s = m.mk_sort(symbol("S")); + s = m.mk_uninterpreted_sort(symbol("S")); sort* ss[2] = { s.get(), s.get() }; symbol names[2] = { symbol("y"), symbol("x") }; p = m.mk_func_decl(symbol("p"), 2, ss, m.mk_bool_sort()); From 706cbd3872132c8c2f6b8b6a7b26a3df63e5c7d0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 12 Feb 2013 21:45:20 -0800 Subject: [PATCH 078/101] hilbert basis Signed-off-by: Nikolaj Bjorner --- src/muz_qe/hilbert_basis.cpp | 347 +++++++++++++++++++---------------- src/muz_qe/hilbert_basis.h | 63 +++---- src/test/hilbert_basis.cpp | 42 ++--- 3 files changed, 223 insertions(+), 229 deletions(-) diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index 83bfbc05b..09296f89d 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -82,10 +82,20 @@ public: }; class hilbert_basis::weight_map { + struct stats { + unsigned m_num_comparisons; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + rational_heap m_heap; vector m_offsets; // [index |-> offset-list] int_vector m_le; // recycled set of indices with lesser weights - + stats m_stats; + svector& m_found; + offset_refs_t& m_refs; + unsigned m_cost; + unsigned get_value(numeral const& w) { unsigned val; if (!m_heap.is_declared(w, val)) { @@ -99,7 +109,7 @@ class hilbert_basis::weight_map { return val; } public: - weight_map() {} + weight_map(svector& found, offset_refs_t& refs): m_found(found), m_refs(refs) {} void insert(offset_t idx, numeral const& w) { unsigned val = get_value(w); @@ -117,9 +127,12 @@ public: m_le.reset(); } - bool init_find(offset_refs_t& refs, numeral const& w, offset_t idx, offset_t& found_idx, unsigned& cost) { - //std::cout << "init find: " << w << "\n"; + unsigned get_cost() const { return m_cost; } + + bool init_find(numeral const& w, offset_t idx) { m_le.reset(); + m_found.reset(); + m_cost = 0; unsigned val = get_value(w); // for positive values, the weights should be less or equal. // for non-positive values, the weights have to be the same. @@ -129,48 +142,54 @@ public: else { m_le.push_back(val); } - bool found = false; for (unsigned i = 0; i < m_le.size(); ++i) { if (m_heap.u2r()[m_le[i]].is_zero() && w.is_pos()) { continue; } - //std::cout << "insert init find: " << m_weights[m_le[i]] << "\n"; unsigned_vector const& offsets = m_offsets[m_le[i]]; for (unsigned j = 0; j < offsets.size(); ++j) { unsigned offs = offsets[j]; - ++cost; + ++m_stats.m_num_comparisons; + ++m_cost; if (offs != idx.m_offset) { - refs.insert(offs, 0); - found_idx = offset_t(offs); - found = true; + m_refs.insert(offs, 0); + m_found.push_back(offset_t(offs)); } } } - return found; + return !m_found.empty(); } - bool update_find(offset_refs_t& refs, unsigned round, numeral const& w, - offset_t idx, offset_t& found_idx, unsigned& cost) { + bool update_find(unsigned round, numeral const& w, offset_t idx) { //std::cout << "update find: " << w << "\n"; + m_found.reset(); m_le.reset(); + m_cost = 0; m_heap.find_le(w, m_le); - bool found = false; unsigned vl; for (unsigned i = 0; i < m_le.size(); ++i) { //std::cout << "insert update find: " << m_weights[m_le[i]] << "\n"; unsigned_vector const& offsets = m_offsets[m_le[i]]; for (unsigned j = 0; j < offsets.size(); ++j) { unsigned offs = offsets[j]; - ++cost; - if (offs != idx.m_offset && refs.find(offs, vl) && vl == round) { - refs.insert(offs, round + 1); - found_idx = offset_t(offs); - found = true; + ++m_stats.m_num_comparisons; + ++m_cost; + if (offs != idx.m_offset && m_refs.find(offs, vl) && vl == round) { + m_refs.insert(offs, round + 1); + m_found.push_back(offset_t(offs)); } } } - return found; + return !m_found.empty(); } + + void collect_statistics(statistics& st) const { + st.update("hb.index.num_comparisons", m_stats.m_num_comparisons); + } + + void reset_statistics() { + m_stats.reset(); + } }; @@ -185,13 +204,18 @@ class hilbert_basis::index { stats() { reset(); } void reset() { memset(this, 0, sizeof(*this)); } }; + + hilbert_basis& hb; + offset_refs_t m_refs; + svector m_found; ptr_vector m_values; weight_map m_weight; - offset_refs_t m_refs; stats m_stats; public: + index(hilbert_basis& hb): hb(hb), m_weight(m_found, m_refs) {} + ~index() { for (unsigned i = 0; i < m_values.size(); ++i) { dealloc(m_values[i]); @@ -201,34 +225,53 @@ public: void init(unsigned num_vars) { if (m_values.empty()) { for (unsigned i = 0; i < num_vars; ++i) { - m_values.push_back(alloc(weight_map)); + m_values.push_back(alloc(weight_map, m_found, m_refs)); } } SASSERT(m_values.size() == num_vars); } - void insert(offset_t idx, values vs, numeral const& weight) { + void insert(offset_t idx, values const& vs) { ++m_stats.m_num_insert; +#if 0 for (unsigned i = 0; i < m_values.size(); ++i) { m_values[i]->insert(idx, vs[i]); } - m_weight.insert(idx, weight); +#endif + m_weight.insert(idx, vs.value()); } - void remove(offset_t idx, values vs, numeral const& weight) { + void remove(offset_t idx, values const& vs) { +#if 0 for (unsigned i = 0; i < m_values.size(); ++i) { m_values[i]->remove(idx, vs[i]); } - m_weight.remove(idx, weight); +#endif + m_weight.remove(idx, vs.value()); } - bool find(values vs, numeral const& weight, offset_t idx, offset_t& found_idx) { + bool find(values const& vs, offset_t idx, offset_t& found_idx) { ++m_stats.m_num_find; - bool found = m_weight.init_find(m_refs, weight, idx, found_idx, m_stats.m_num_comparisons); - for (unsigned i = 0; found && i < m_values.size(); ++i) { - found = m_values[i]->update_find(m_refs, i, vs[i], idx, found_idx, m_stats.m_num_comparisons); - } m_refs.reset(); + bool found = m_weight.init_find(vs.value(), idx); + TRACE("hilbert_basis", tout << "init: " << m_found.size() << " cost: " << m_weight.get_cost() << "\n";); +#if 0 + for (unsigned i = 0; found && i < m_values.size(); ++i) { + found = m_values[i]->update_find(i, vs[i], idx); + TRACE("hilbert_basis", tout << "update " << i << ": " << m_found.size() << " cost: " << m_values[i]->get_cost() << "\n";); + } +#else + for (unsigned i = 0; i < m_found.size(); ++i) { + if (is_subsumed(idx, m_found[i])) { + found_idx = m_found[i]; + return true; + } + } + return false; +#endif + if (found) { + found_idx = m_found[0]; + } return found; } @@ -241,42 +284,77 @@ public: } void collect_statistics(statistics& st) const { - st.update("hb.index.num_comparisons", m_stats.m_num_comparisons); + m_weight.collect_statistics(st); + for (unsigned i = 0; i < m_values.size(); ++i) { + m_values[i]->collect_statistics(st); + } st.update("hb.index.num_find", m_stats.m_num_find); st.update("hb.index.num_insert", m_stats.m_num_insert); } void reset_statistics() { m_stats.reset(); + m_weight.reset_statistics(); + for (unsigned i = 0; i < m_values.size(); ++i) { + m_values[i]->reset_statistics(); + } } -#if 0 - // remains of a simpler index strucure: - if (eval(idx).is_zero()) { - for (unsigned i = 0; i < m_zero.size(); ++i) { - if (is_subsumed(idx, m_zero[i])) { - ++m_stats.m_num_subsumptions; - return true; + + /** + Vector v is subsumed by vector w if + + v[i] >= w[i] for each index i. + + a*v >= a*w for the evaluation of vectors with respect to a. + + a*v < 0 => a*v = a*w + + + Justification: + + let u := v - w, then + + u[i] >= 0 for each index i + + a*u = a*(v-w) >= 0 + + So v = u + w, where a*u >= 0, a*w >= 0. + + If a*v >= a*w >= 0 then v and w are linear + solutions of e_i, and also v-w is a solution. + + If a*v = a*w < 0, then a*(v-w) = 0, so v can be obtained from w + (v - w). + + */ + + bool is_subsumed(offset_t i, offset_t j) const { + values v = hb.vec(i); + values w = hb.vec(j); + numeral const& n = v.value(); + numeral const& m = w.value(); + bool r = + i.m_offset != j.m_offset && + n >= m && (!m.is_neg() || n == m) && + is_geq(v, w); + CTRACE("hilbert_basis", r, + hb.display(tout, i); + tout << " <= \n"; + hb.display(tout, j); + tout << "\n";); + return r; + } + + bool is_geq(values v, values w) const { + unsigned nv = hb.get_num_vars(); + for (unsigned i = 0; i < nv; ++i) { + if (v[i] < w[i]) { + return false; } } - return false; + return true; } - for (unsigned i = 0; i < m_active.size(); ++i) { - if (is_subsumed(idx, m_active[i])) { - ++m_stats.m_num_subsumptions; - return true; - } - } - passive::iterator it = m_passive->begin(); - passive::iterator end = m_passive->end(); - for (; it != end; ++it) { - if (is_subsumed(idx, *it)) { - ++m_stats.m_num_subsumptions; - return true; - } - } -#endif }; @@ -377,7 +455,7 @@ public: hilbert_basis::hilbert_basis(): m_cancel(false) { - m_index = alloc(index); + m_index = alloc(index, *this); m_passive = alloc(passive, *this); } @@ -399,7 +477,6 @@ void hilbert_basis::reset() { m_basis.reset(); m_store.reset(); m_free_list.reset(); - m_eval.reset(); m_active.reset(); m_passive->reset(); m_zero.reset(); @@ -418,20 +495,36 @@ void hilbert_basis::reset_statistics() { m_index->reset_statistics(); } -void hilbert_basis::add_ge(num_vector const& v) { - SASSERT(m_ineqs.empty() || v.size() == get_num_vars()); +void hilbert_basis::add_ge(num_vector const& v, numeral const& b) { + SASSERT(m_ineqs.empty() || v.size() + 1 == get_num_vars()); + num_vector w; + w.push_back(-b); + w.append(v); if (m_ineqs.empty()) { - m_index->init(v.size()); + m_index->init(w.size()); } - m_ineqs.push_back(v); + m_ineqs.push_back(w); } -void hilbert_basis::add_le(num_vector const& v) { +void hilbert_basis::add_le(num_vector const& v, numeral const& b) { num_vector w(v); for (unsigned i = 0; i < w.size(); ++i) { w[i].neg(); } - add_ge(w); + add_ge(w, -b); +} + +void hilbert_basis::add_eq(num_vector const& v, numeral const& b) { + add_le(v, b); + add_ge(v, b); +} + +void hilbert_basis::add_ge(num_vector const& v) { + add_ge(v, numeral(0)); +} + +void hilbert_basis::add_le(num_vector const& v) { + add_le(v, numeral(0)); } void hilbert_basis::add_eq(num_vector const& v) { @@ -449,24 +542,22 @@ unsigned hilbert_basis::get_num_vars() const { } hilbert_basis::values hilbert_basis::vec(offset_t offs) const { - return m_store.c_ptr() + offs.m_offset; -} - -hilbert_basis::values_ref hilbert_basis::vec(offset_t offs) { - return m_store.c_ptr() + offs.m_offset; + return values(m_store.c_ptr() + offs.m_offset); } void hilbert_basis::init_basis() { m_basis.reset(); m_store.reset(); - m_eval.reset(); m_free_list.reset(); unsigned num_vars = get_num_vars(); for (unsigned i = 0; i < num_vars; ++i) { num_vector w(num_vars, numeral(0)); w[i] = numeral(1); offset_t idx = alloc_vector(); - set_value(idx, w.c_ptr()); + values v = vec(idx); + for (unsigned i = 0; i < num_vars; ++i) { + v[i] = w[i]; + } m_basis.push_back(idx); } } @@ -494,10 +585,10 @@ lbool hilbert_basis::saturate(num_vector const& ineq) { bool has_non_negative = false; iterator it = begin(); for (; it != end(); ++it) { - numeral n = eval(vec(*it), ineq); - eval(*it) = n; + values v = vec(*it); + set_eval(v, ineq); add_goal(*it); - if (n.is_nonneg()) { + if (v.value().is_nonneg()) { has_non_negative = true; } } @@ -517,7 +608,7 @@ lbool hilbert_basis::saturate(num_vector const& ineq) { continue; } for (unsigned i = 0; !m_cancel && i < m_active.size(); ++i) { - if (get_sign(idx) != get_sign(m_active[i])) { + if (can_resolve(idx, m_active[i])) { offset_t j = alloc_vector(); resolve(idx, m_active[i], j); add_goal(j); @@ -530,7 +621,7 @@ lbool hilbert_basis::saturate(num_vector const& ineq) { m_basis.append(m_zero); for (unsigned i = 0; i < m_active.size(); ++i) { offset_t idx = m_active[i]; - if (eval(idx).is_pos()) { + if (vec(idx).value().is_pos()) { m_basis.push_back(idx); } else { @@ -544,16 +635,8 @@ lbool hilbert_basis::saturate(num_vector const& ineq) { return l_true; } - -void hilbert_basis::set_value(offset_t offs, values v) { - unsigned nv = get_num_vars(); - for (unsigned i = 0; i < nv; ++i) { - m_store[offs.m_offset+i] = v[i]; - } -} - void hilbert_basis::recycle(offset_t idx) { - m_index->remove(idx, vec(idx), eval(idx)); + m_index->remove(idx, vec(idx)); m_free_list.push_back(idx); } @@ -561,26 +644,25 @@ void hilbert_basis::resolve(offset_t i, offset_t j, offset_t r) { ++m_stats.m_num_resolves; values v = vec(i); values w = vec(j); - values_ref u = vec(r); + values u = vec(r); unsigned nv = get_num_vars(); for (unsigned k = 0; k < nv; ++k) { u[k] = v[k] + w[k]; } - eval(r) = eval(i) + eval(j); + u.value() = v.value() + w.value(); TRACE("hilbert_basis_verbose", display(tout, i); display(tout, j); display(tout, r); ); - } + hilbert_basis::offset_t hilbert_basis::alloc_vector() { if (m_free_list.empty()) { unsigned num_vars = get_num_vars(); unsigned idx = m_store.size(); - m_store.resize(idx + get_num_vars()); - m_eval.push_back(numeral(0)); + m_store.resize(idx + 1 + get_num_vars()); return offset_t(idx); } else { @@ -590,10 +672,10 @@ hilbert_basis::offset_t hilbert_basis::alloc_vector() { } } - void hilbert_basis::add_goal(offset_t idx) { - m_index->insert(idx, vec(idx), eval(idx)); - if (eval(idx).is_zero()) { + values v = vec(idx); + m_index->insert(idx, v); + if (v.value().is_zero()) { if (!is_subsumed(idx)) { m_zero.push_back(idx); } @@ -606,7 +688,7 @@ void hilbert_basis::add_goal(offset_t idx) { bool hilbert_basis::is_subsumed(offset_t idx) { offset_t found_idx; - if (m_index->find(vec(idx), eval(idx), idx, found_idx)) { + if (m_index->find(vec(idx), idx, found_idx)) { TRACE("hilbert_basis", display(tout, idx); tout << " <= \n"; @@ -618,77 +700,30 @@ bool hilbert_basis::is_subsumed(offset_t idx) { return false; } -/** - Vector v is subsumed by vector w if - - v[i] >= w[i] for each index i. - - a*v >= a*w for the evaluation of vectors with respect to a. - - a*v < 0 => a*v = a*w - - - Justification: - - let u := v - w, then - - u[i] >= 0 for each index i - - a*u = a*(v-w) >= 0 - - So v = u + w, where a*u >= 0, a*w >= 0. - - If a*v >= a*w >= 0 then v and w are linear - solutions of e_i, and also v-w is a solution. - - If a*v = a*w < 0, then a*(v-w) = 0, so v can be obtained from w + (v - w). - - */ - -bool hilbert_basis::is_subsumed(offset_t i, offset_t j) const { - values v = vec(i); - values w = vec(j); - numeral const& n = eval(i); - numeral const& m = eval(j); - bool r = - i.m_offset != j.m_offset && - n >= m && (!m.is_neg() || n == m) && - is_geq(v, w); - CTRACE("hilbert_basis", r, - display(tout, i); - tout << " <= \n"; - display(tout, j); - tout << "\n";); - return r; -} - -bool hilbert_basis::is_geq(values v, values w) const { - unsigned nv = get_num_vars(); - for (unsigned i = 0; i < nv; ++i) { - if (v[i] < w[i]) { - return false; - } - } - return true; +bool hilbert_basis::can_resolve(offset_t i, offset_t j) const { + sign_t s1 = get_sign(i); + sign_t s2 = get_sign(j); + return s1 != s2 && abs(vec(i)[0] + vec(j)[0]) <= numeral(1); } hilbert_basis::sign_t hilbert_basis::get_sign(offset_t idx) const { - if (eval(idx).is_pos()) { + numeral val = vec(idx).value(); + if (val.is_pos()) { return pos; } - if (eval(idx).is_neg()) { + if (val.is_neg()) { return neg; } return zero; } -hilbert_basis::numeral hilbert_basis::eval(values val, num_vector const& ineq) const { +void hilbert_basis::set_eval(values& val, num_vector const& ineq) const { numeral result(0); unsigned num_vars = get_num_vars(); for (unsigned i = 0; i < num_vars; ++i) { result += val[i]*ineq[i]; } - return result; + val.value() = result; } void hilbert_basis::display(std::ostream& out) const { @@ -728,10 +763,10 @@ void hilbert_basis::display(std::ostream& out) const { void hilbert_basis::display(std::ostream& out, offset_t o) const { display(out, vec(o)); - out << " -> " << eval(o) << "\n"; + out << " -> " << vec(o).value() << "\n"; } -void hilbert_basis::display(std::ostream& out, values v) const { +void hilbert_basis::display(std::ostream& out, values const& v) const { unsigned nv = get_num_vars(); for (unsigned j = 0; j < nv; ++j) { out << v[j] << " "; @@ -762,21 +797,15 @@ void hilbert_basis::display_ineq(std::ostream& out, num_vector const& v) const { out << " >= 0\n"; } -void hilbert_sl_basis::add_le(num_vector const& v, numeral bound) { - num_vector w; - w.push_back(-bound); - w.append(v); - m_basis.add_le(w); -} void hilbert_isl_basis::add_le(num_vector const& v, numeral bound) { unsigned sz = v.size(); num_vector w; + w.push_back(-bound); + w.push_back(bound); for (unsigned i = 0; i < sz; ++i) { w.push_back(v[i]); w.push_back(-v[i]); } - w.push_back(-bound); - w.push_back(bound); m_basis.add_le(w); } diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index 542b680b0..73a9c89a5 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -53,12 +53,18 @@ private: stats() { reset(); } void reset() { memset(this, 0, sizeof(*this)); } }; - typedef numeral const* values; - typedef numeral* values_ref; + class values { + numeral* m_values; + public: + values(numeral* v):m_values(v) {} + numeral& value() { return m_values[0]; } // value of a*x + numeral& operator[](unsigned i) { return m_values[i+1]; } // value of x_i + numeral const& value() const { return m_values[0]; } // value of a*x + numeral const& operator[](unsigned i) const { return m_values[i+1]; } // value of x_i + }; vector m_ineqs; num_vector m_store; - num_vector m_eval; svector m_basis; svector m_free_list; svector m_active; @@ -84,12 +90,12 @@ private: lbool saturate(num_vector const& ineq); void init_basis(); unsigned get_num_vars() const; - numeral eval(values val, num_vector const& ineq) const; + void set_eval(values& val, num_vector const& ineq) const; bool is_subsumed(offset_t idx); bool is_subsumed(offset_t i, offset_t j) const; - bool is_geq(values v, values w) const; void recycle(offset_t idx); - sign_t hilbert_basis::get_sign(offset_t idx) const; + bool can_resolve(offset_t i, offset_t j) const; + sign_t get_sign(offset_t idx) const; void add_goal(offset_t idx); offset_t alloc_vector(); void resolve(offset_t i, offset_t j, offset_t r); @@ -97,18 +103,9 @@ private: iterator end() const { return iterator(*this, m_basis.size()); } values vec(offset_t offs) const; - values_ref vec(offset_t offs); - numeral const& eval(offset_t o) const { - return m_eval[o.m_offset/get_num_vars()]; - } - numeral& eval(offset_t o) { - return m_eval[o.m_offset/get_num_vars()]; - } - void set_value(offset_t offs, values v); - void display(std::ostream& out, offset_t o) const; - void display(std::ostream& out, values v) const; + void display(std::ostream& out, values const & v) const; void display_ineq(std::ostream& out, num_vector const& v) const; public: @@ -118,14 +115,20 @@ public: void reset(); - // add inequality v*x <= 0 // add inequality v*x >= 0 + // add inequality v*x <= 0 // add equality v*x = 0 - - void add_le(num_vector const& v); void add_ge(num_vector const& v); + void add_le(num_vector const& v); void add_eq(num_vector const& v); + // add inequality v*x >= b + // add inequality v*x <= b + // add equality v*x = b + void add_ge(num_vector const& v, numeral const& b); + void add_le(num_vector const& v, numeral const& b); + void add_eq(num_vector const& v, numeral const& b); + lbool saturate(); void set_cancel(bool f) { m_cancel = f; } @@ -133,29 +136,9 @@ public: void display(std::ostream& out) const; void collect_statistics(statistics& st) const; - void reset_statistics(); - + void reset_statistics(); }; -class hilbert_sl_basis { -public: - typedef rational numeral; - typedef vector num_vector; -private: - hilbert_basis m_basis; -public: - hilbert_sl_basis() {} - void reset() { m_basis.reset(); } - - // add inequality v*x >= bound, x ranges over naturals - void add_le(num_vector const& v, numeral bound); - lbool saturate() { return m_basis.saturate(); } - void set_cancel(bool f) { m_basis.set_cancel(f); } - void display(std::ostream& out) const { m_basis.display(out); } - - void collect_statistics(statistics& st) const { m_basis.collect_statistics(st); } - void reset_statistics() { m_basis.reset_statistics(); } -}; class hilbert_isl_basis { public: diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index 5edc4cf99..275aa486d 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -44,26 +44,6 @@ static vector vec(int i, int j, int k, int l, int x, int y, int z) { return nv; } -static void saturate_basis(hilbert_sl_basis& hb) { - lbool is_sat = hb.saturate(); - - switch(is_sat) { - case l_true: - std::cout << "sat\n"; - hb.display(std::cout); - break; - case l_false: - std::cout << "unsat\n"; - break; - case l_undef: - std::cout << "undef\n"; - break; - } - statistics st; - hb.collect_statistics(st); - st.display(std::cout); -} - static void saturate_basis(hilbert_basis& hb) { lbool is_sat = hb.saturate(); @@ -124,7 +104,7 @@ static void tst3() { // Sigma_1, table 1, Ajili, Contejean static void tst4() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 0,-2, 1, 3, 2,-2, 3), R(3)); hb.add_le(vec(-1, 7, 0, 1, 3, 5,-4), R(2)); hb.add_le(vec( 0,-1, 1,-1,-1, 0, 0), R(2)); @@ -140,7 +120,7 @@ static void tst4() { // Sigma_2 table 1, Ajili, Contejean static void tst5() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 1, 2,-1, 1), R(3)); hb.add_le(vec( 2, 4, 1, 2), R(12)); hb.add_le(vec( 1, 4, 2, 1), R(9)); @@ -153,7 +133,7 @@ static void tst5() { // Sigma_3 table 1, Ajili, Contejean static void tst6() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 4, 3, 0), R(6)); hb.add_le(vec(-3,-4, 0), R(-1)); hb.add_le(vec( 4, 0,-3), R(3)); @@ -165,7 +145,7 @@ static void tst6() { // Sigma_4 table 1, Ajili, Contejean static void tst7() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 2, 1, 0, 1), R(6)); hb.add_le(vec( 1, 2, 1, 1), R(7)); hb.add_le(vec( 1, 3,-1, 2), R(8)); @@ -177,7 +157,7 @@ static void tst7() { // Sigma_5 table 1, Ajili, Contejean static void tst8() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 2, 1, 1), R(2)); hb.add_le(vec( 1, 2, 3), R(5)); hb.add_le(vec( 2, 2, 3), R(6)); @@ -187,7 +167,7 @@ static void tst8() { // Sigma_6 table 1, Ajili, Contejean static void tst9() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 1, 2, 3), R(11)); hb.add_le(vec( 2, 2, 5), R(13)); hb.add_le(vec( 1,-1,-11), R(3)); @@ -196,7 +176,7 @@ static void tst9() { // Sigma_7 table 1, Ajili, Contejean static void tst10() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 1,-1,-1,-3), R(2)); hb.add_le(vec(-2, 3, 3, 5), R(3)); saturate_basis(hb); @@ -204,7 +184,7 @@ static void tst10() { // Sigma_8 table 1, Ajili, Contejean static void tst11() { - hilbert_sl_basis hb; + hilbert_basis hb; hb.add_le(vec( 7,-2,11, 3, -5), R(5)); saturate_basis(hb); } @@ -214,10 +194,12 @@ void tst_hilbert_basis() { tst1(); tst2(); tst3(); -#if 0 tst4(); tst5(); tst6(); tst7(); -#endif + tst8(); + tst9(); + tst10(); + tst11(); } From fa0bd4f78947ff66f25e2939aaa7e419aeb68666 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 13 Feb 2013 08:16:08 -0800 Subject: [PATCH 079/101] Fix git_hash function Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b5ec691cb..b3d843cc4 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -76,7 +76,8 @@ GPROF=False def git_hash(): try: - r = subprocess.check_output(['git', 'show-ref', '--abbrev=12', 'HEAD'], shell=True).rstrip('\r\n') + branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], shell=True).rstrip('\r\n') + r = subprocess.check_output(['git', 'show-ref', '--abbrev=12', 'refs/heads/%s' % branch], shell=True).rstrip('\r\n') except: raise MKException("Failed to retrieve git hash") ls = r.split(' ') From 5790115e40fa54aa937e1d021a40eacfaff801fe Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 13 Feb 2013 08:39:26 -0800 Subject: [PATCH 080/101] Include git hash in the binary Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 23 +++++++++++++++++------ scripts/mk_win_dist.py | 2 ++ src/shell/main.cpp | 9 +++++++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b3d843cc4..589fc1013 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -73,6 +73,7 @@ GMP=False VS_PAR=False VS_PAR_NUM=8 GPROF=False +GIT_HASH=False def git_hash(): try: @@ -372,6 +373,7 @@ def display_help(exit_code): else: print(" --parallel=num use cl option /MP with 'num' parallel processes") print(" -b , --build= subdirectory where Z3 will be built (default: build).") + print(" --githash=hash include the given hash in the binaries.") print(" -d, --debug compile Z3 in debug mode.") print(" -t, --trace enable tracing in release mode.") if IS_WINDOWS: @@ -402,12 +404,13 @@ def display_help(exit_code): # Parse configuration option for mk_make script def parse_options(): global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM - global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF + global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH try: options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:dsxhmcvtnp:gj', ['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', - 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof']) + 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof', + 'githash=']) except: print("ERROR: Invalid command line option") display_help(1) @@ -454,6 +457,8 @@ def parse_options(): JAVA_ENABLED = True elif opt == '--gprof': GPROF = True + elif opt == '--githash': + GIT_HASH=arg else: print("ERROR: Invalid command line option '%s'" % opt) display_help(1) @@ -1291,18 +1296,23 @@ def mk_config(): 'SO_EXT=.dll\n' 'SLINK=cl\n' 'SLINK_OUT_FLAG=/Fe\n') + extra_opt = '' + if GIT_HASH: + extra_opt = '%s /D Z3GITHASH="%s"' % (extra_opt, GIT_HASH) if DEBUG_MODE: config.write( 'LINK_FLAGS=/nologo /MDd\n' 'SLINK_FLAGS=/nologo /LDd\n') if not VS_X64: config.write( - 'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' + 'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt) + config.write( 'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n' 'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n') else: config.write( - 'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n' + 'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n' % extra_opt) + config.write( 'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n' 'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n') else: @@ -1310,9 +1320,8 @@ def mk_config(): config.write( 'LINK_FLAGS=/nologo /MD\n' 'SLINK_FLAGS=/nologo /LD\n') - extra_opt = '' if TRACE: - extra_opt = '/D _TRACE' + extra_opt = '%s /D _TRACE' % extra_opt if not VS_X64: config.write( 'CXXFLAGS=/nologo /c /Zi /openmp /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt) @@ -1351,6 +1360,8 @@ def mk_config(): SLIBEXTRAFLAGS = '%s -lgmp' % SLIBEXTRAFLAGS else: CPPFLAGS = '%s -D_MP_INTERNAL' % CPPFLAGS + if GIT_HASH: + CPPFLAGS = '%s -DZ3GITHASH="%s"' % (CPPFLAGS, GIT_HASH) CXXFLAGS = '%s -c' % CXXFLAGS HAS_OMP = test_openmp(CXX) if HAS_OMP: diff --git a/scripts/mk_win_dist.py b/scripts/mk_win_dist.py index 961425101..85c1dddfc 100644 --- a/scripts/mk_win_dist.py +++ b/scripts/mk_win_dist.py @@ -101,6 +101,8 @@ def mk_build_dir(path, x64): opts.append('--java') if x64: opts.append('-x') + if GIT_HASH: + opts.append('--githash=%s' % mk_util.git_hash()) if subprocess.call(opts) != 0: raise MKException("Failed to generate build directory at '%s'" % path) diff --git a/src/shell/main.cpp b/src/shell/main.cpp index d91038b39..7c69f66ba 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -51,13 +51,18 @@ void error(const char * msg) { } void display_usage() { - std::cout << "Z3 [version " << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER << " - "; + std::cout << "Z3 [version " << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER; + std::cout << " - "; #ifdef _AMD64_ std::cout << "64"; #else std::cout << "32"; #endif - std::cout << " bit]. (C) Copyright 2006 Microsoft Corp.\n"; + std::cout << " bit"; +#ifdef Z3GITHASH + std::cout << " - build hashcode " << Z3GITHASH; +#endif + std::cout << "]. (C) Copyright 2006-2013 Microsoft Corp.\n"; std::cout << "Usage: z3 [options] [-file:]file\n"; std::cout << "\nInput format:\n"; std::cout << " -smt use parser for SMT input format.\n"; From 60ce2a84cdb73caa2c39f4a582ae3c9bc069a22f Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 13 Feb 2013 09:16:38 -0800 Subject: [PATCH 081/101] Fix build hashcode Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 4 ++-- src/shell/main.cpp | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 589fc1013..7acbb2c94 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1298,7 +1298,7 @@ def mk_config(): 'SLINK_OUT_FLAG=/Fe\n') extra_opt = '' if GIT_HASH: - extra_opt = '%s /D Z3GITHASH="%s"' % (extra_opt, GIT_HASH) + extra_opt = '%s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH) if DEBUG_MODE: config.write( 'LINK_FLAGS=/nologo /MDd\n' @@ -1361,7 +1361,7 @@ def mk_config(): else: CPPFLAGS = '%s -D_MP_INTERNAL' % CPPFLAGS if GIT_HASH: - CPPFLAGS = '%s -DZ3GITHASH="%s"' % (CPPFLAGS, GIT_HASH) + CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH) CXXFLAGS = '%s -c' % CXXFLAGS HAS_OMP = test_openmp(CXX) if HAS_OMP: diff --git a/src/shell/main.cpp b/src/shell/main.cpp index 7c69f66ba..63e604719 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -50,6 +50,9 @@ void error(const char * msg) { exit(ERR_CMD_LINE); } +#define STRINGIZE(x) #x +#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) + void display_usage() { std::cout << "Z3 [version " << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER; std::cout << " - "; @@ -60,7 +63,7 @@ void display_usage() { #endif std::cout << " bit"; #ifdef Z3GITHASH - std::cout << " - build hashcode " << Z3GITHASH; + std::cout << " - build hashcode " << STRINGIZE_VALUE_OF(Z3GITHASH); #endif std::cout << "]. (C) Copyright 2006-2013 Microsoft Corp.\n"; std::cout << "Usage: z3 [options] [-file:]file\n"; From 92e7384bf565ea019d43dbdc5da5b5143b1203fa Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 13 Feb 2013 17:21:08 +0000 Subject: [PATCH 082/101] Java API: final adjustments Signed-off-by: Christoph M. Wintersteiger --- src/api/java/Context.java | 7 ------- src/api/java/Sort.java | 3 ++- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 3ad136f12..5277dab38 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -39,13 +39,6 @@ public class Context extends IDisposable initContext(); } - private Context(long ctx, long refCount) - { - super(); - this.m_ctx = ctx; - this.m_refCount = refCount; - } - /** * Creates a new symbol using an integer. Not all integers can be * passed to this function. The legal range of unsigned integers is 0 to diff --git a/src/api/java/Sort.java b/src/api/java/Sort.java index 58f7638ba..381b9b0ae 100644 --- a/src/api/java/Sort.java +++ b/src/api/java/Sort.java @@ -128,7 +128,8 @@ public class Sort extends AST static Sort create(Context ctx, long obj) throws Z3Exception { - switch (Z3_sort_kind.fromInt(Native.getSortKind(ctx.nCtx(), obj))) + Z3_sort_kind sk = Z3_sort_kind.fromInt(Native.getSortKind(ctx.nCtx(), obj)); + switch (sk) { case Z3_ARRAY_SORT: return new ArraySort(ctx, obj); From 3f692b565a94fa34a46196380fc3eecbbfd7a3d0 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 13 Feb 2013 10:32:43 -0800 Subject: [PATCH 083/101] Add script for building Linux/OSX/FreeBSD distributions Signed-off-by: Leonardo de Moura --- scripts/mk_unix_dist.py | 216 ++++++++++++++++++++++++++++++++++++++++ scripts/mk_util.py | 62 +++++++++++- 2 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 scripts/mk_unix_dist.py diff --git a/scripts/mk_unix_dist.py b/scripts/mk_unix_dist.py new file mode 100644 index 000000000..3b9511367 --- /dev/null +++ b/scripts/mk_unix_dist.py @@ -0,0 +1,216 @@ +############################################ +# Copyright (c) 2013 Microsoft Corporation +# +# Scripts for automatically generating +# Linux/OSX/BSD distribution zip files. +# +# Author: Leonardo de Moura (leonardo) +############################################ +import os +import glob +import re +import getopt +import sys +import shutil +import subprocess +import zipfile +from mk_exception import * +from mk_project import * +import mk_util + +BUILD_DIR='build-dist' +VERBOSE=True +DIST_DIR='dist' +FORCE_MK=False +JAVA_ENABLED=True +GIT_HASH=False + +def set_verbose(flag): + global VERBOSE + VERBOSE = flag + +def is_verbose(): + return VERBOSE + +def mk_dir(d): + if not os.path.exists(d): + os.makedirs(d) + +def set_build_dir(path): + global BUILD_DIR + BUILD_DIR = path + mk_dir(BUILD_DIR) + +def display_help(): + print "mk_unix_dist.py: Z3 Linux/OSX/BSD distribution generator\n" + print "This script generates the zip files containing executables, shared objects, header files for Linux/OSX/BSD." + print "It must be executed from the Z3 root directory." + print "\nOptions:" + print " -h, --help display this message." + print " -s, --silent do not print verbose messages." + print " -b , --build= subdirectory where x86 and x64 Z3 versions will be built (default: build-dist)." + print " -f, --force force script to regenerate Makefiles." + print " --nojava do not include Java bindings in the binary distribution files." + print " --githash include git hash in the Zip file." + exit(0) + +# Parse configuration option for mk_make script +def parse_options(): + global FORCE_MK, JAVA_ENABLED, GIT_HASH + path = BUILD_DIR + options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=', + 'help', + 'silent', + 'force', + 'nojava', + 'githash' + ]) + for opt, arg in options: + if opt in ('-b', '--build'): + if arg == 'src': + raise MKException('The src directory should not be used to host the Makefile') + path = arg + elif opt in ('-s', '--silent'): + set_verbose(False) + elif opt in ('-h', '--help'): + display_help() + elif opt in ('-f', '--force'): + FORCE_MK = True + elif opt == '--nojava': + JAVA_ENABLED = False + elif opt == '--githash': + GIT_HASH = True + else: + raise MKException("Invalid command line option '%s'" % opt) + set_build_dir(path) + +# Check whether build directory already exists or not +def check_build_dir(path): + return os.path.exists(path) and os.path.exists(os.path.join(path, 'Makefile')) + +# Create a build directory using mk_make.py +def mk_build_dir(path): + if not check_build_dir(path) or FORCE_MK: + opts = ["python", os.path.join('scripts', 'mk_make.py'), "-b", path, "--static"] + if JAVA_ENABLED: + opts.append('--java') + if GIT_HASH: + opts.append('--githash=%s' % mk_util.git_hash()) + if subprocess.call(opts) != 0: + raise MKException("Failed to generate build directory at '%s'" % path) + +# Create build directories +def mk_build_dirs(): + mk_build_dir(BUILD_DIR) + +class cd: + def __init__(self, newPath): + self.newPath = newPath + + def __enter__(self): + self.savedPath = os.getcwd() + os.chdir(self.newPath) + + def __exit__(self, etype, value, traceback): + os.chdir(self.savedPath) + +def mk_z3(): + with cd(BUILD_DIR): + try: + return subprocess.call(['make', '-j', '8']) + except: + return 1 + +def get_os_name(): + import platform + basic = os.uname()[0].lower() + if basic == 'linux': + dist = platform.linux_distribution() + if len(dist) == 3 and len(dist[0]) > 0 and len(dist[1]) > 0: + return '%s-%s' % (dist[0].lower(), dist[1].lower()) + else: + return basic + elif basic == 'darwin': + ver = platform.mac_ver() + if len(ver) == 3 and len(ver[0]) > 0: + return 'osx-%s' % ver[0] + else: + return 'osx' + elif basic == 'freebsd': + ver = platform.version() + idx1 = ver.find(' ') + idx2 = ver.find('-') + if idx1 < 0 or idx2 < 0 or idx1 >= idx2: + return basic + else: + return 'freebsd-%s' % ver[(idx1+1):idx2] + else: + return basic + +def get_z3_name(): + major, minor, build, revision = get_version() + if sys.maxsize >= 2**32: + platform = "x64" + else: + platform = "x86" + osname = get_os_name() + if GIT_HASH: + return 'z3-%s.%s.%s.%s-%s-%s' % (major, minor, build, mk_util.git_hash(), platform, osname) + else: + return 'z3-%s.%s.%s-%s-%s' % (major, minor, build, platform, osname) + +def mk_dist_dir(): + build_path = BUILD_DIR + dist_path = os.path.join(DIST_DIR, get_z3_name()) + mk_dir(dist_path) + if JAVA_ENABLED: + # HACK: Propagate JAVA_ENABLED flag to mk_util + # TODO: fix this hack + mk_util.JAVA_ENABLED = JAVA_ENABLED + mk_unix_dist(build_path, dist_path) + if is_verbose(): + print "Generated distribution folder at '%s'" % dist_path + +ZIPOUT = None + +def mk_zip_visitor(pattern, dir, files): + for filename in files: + if fnmatch(filename, pattern): + fname = os.path.join(dir, filename) + if not os.path.isdir(fname): + ZIPOUT.write(fname) + +def get_dist_path(): + return get_z3_name() + +def mk_zip(): + global ZIPOUT + dist_path = get_dist_path() + old = os.getcwd() + try: + os.chdir(DIST_DIR) + zfname = '%s.zip' % dist_path + ZIPOUT = zipfile.ZipFile(zfname, 'w') + os.path.walk(dist_path, mk_zip_visitor, '*') + if is_verbose(): + print "Generated '%s'" % zfname + except: + pass + ZIPOUT = None + os.chdir(old) + +def cp_license(): + shutil.copy("LICENSE.txt", os.path.join(DIST_DIR, get_dist_path())) + +# Entry point +def main(): + parse_options() + mk_build_dirs() + mk_z3() + init_project_def() + mk_dist_dir() + cp_license() + mk_zip() + +main() + diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 7acbb2c94..4e1a38af2 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -75,10 +75,16 @@ VS_PAR_NUM=8 GPROF=False GIT_HASH=False +def check_output(cmd): + try: + return subprocess.check_output(cmd, shell=True).rstrip('\r\n') + except: + return subprocess.check_output(cmd).rstrip('\r\n') + def git_hash(): try: - branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], shell=True).rstrip('\r\n') - r = subprocess.check_output(['git', 'show-ref', '--abbrev=12', 'refs/heads/%s' % branch], shell=True).rstrip('\r\n') + branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']) + r = check_output(['git', 'show-ref', '--abbrev=12', 'refs/heads/%s' % branch]) except: raise MKException("Failed to retrieve git hash") ls = r.split(' ') @@ -738,6 +744,8 @@ class Component: def mk_win_dist(self, build_path, dist_path): return + def mk_unix_dist(self, build_path, dist_path): + return class LibComponent(Component): def __init__(self, name, path, deps, includes2install): @@ -779,6 +787,9 @@ class LibComponent(Component): shutil.copy(os.path.join(self.src_dir, include), os.path.join(dist_path, 'include', include)) + def mk_unix_dist(self, build_path, dist_path): + self.mk_win_dist(build_path, dist_path) + # "Library" containing only .h files. This is just a placeholder for includes files to be installed. class HLibComponent(LibComponent): def __init__(self, name, path, includes2install): @@ -858,6 +869,12 @@ class ExeComponent(Component): shutil.copy('%s.exe' % os.path.join(build_path, self.exe_name), '%s.exe' % os.path.join(dist_path, 'bin', self.exe_name)) + def mk_unix_dist(self, build_path, dist_path): + if self.install: + mk_dir(os.path.join(dist_path, 'bin')) + shutil.copy(os.path.join(build_path, self.exe_name), + os.path.join(dist_path, 'bin', self.exe_name)) + class ExtraExeComponent(ExeComponent): def __init__(self, name, exe_name, path, deps, install): @@ -866,6 +883,18 @@ class ExtraExeComponent(ExeComponent): def main_component(self): return False +def get_so_ext(): + sysname = os.uname()[0] + if sysname == 'Darwin': + return 'dylib' + elif sysname == 'Linux' or sysname == 'FreeBSD': + return 'so' + elif sysname == 'CYGWIN': + return 'dll' + else: + assert(False) + return 'dll' + class DLLComponent(Component): def __init__(self, name, dll_name, path, deps, export_files, reexports, install, static): Component.__init__(self, name, path, deps) @@ -981,6 +1010,15 @@ class DLLComponent(Component): shutil.copy('%s.lib' % os.path.join(build_path, self.dll_name), '%s.lib' % os.path.join(dist_path, 'bin', self.dll_name)) + def mk_unix_dist(self, build_path, dist_path): + if self.install: + mk_dir(os.path.join(dist_path, 'bin')) + so = get_so_ext() + shutil.copy('%s.%s' % (os.path.join(build_path, self.dll_name), so), + '%s.%s' % (os.path.join(dist_path, 'bin', self.dll_name), so)) + shutil.copy('%s.a' % os.path.join(build_path, self.dll_name), + '%s.a' % os.path.join(dist_path, 'bin', self.dll_name)) + class DotNetDLLComponent(Component): def __init__(self, name, dll_name, path, deps, assembly_info_dir): Component.__init__(self, name, path, deps) @@ -1033,6 +1071,9 @@ class DotNetDLLComponent(Component): shutil.copy('%s.dll' % os.path.join(build_path, self.dll_name), '%s.dll' % os.path.join(dist_path, 'bin', self.dll_name)) + def mk_unix_dist(self, build_path, dist_path): + # Do nothing + return class JavaDLLComponent(Component): def __init__(self, name, dll_name, package_name, manifest_file, path, deps): @@ -1095,6 +1136,15 @@ class JavaDLLComponent(Component): shutil.copy(os.path.join(build_path, 'libz3java.lib'), os.path.join(dist_path, 'bin', 'libz3java.lib')) + def mk_unix_dist(self, build_path, dist_path): + if JAVA_ENABLED: + mk_dir(os.path.join(dist_path, 'bin')) + shutil.copy('%s.jar' % os.path.join(build_path, self.package_name), + '%s.jar' % os.path.join(dist_path, 'bin', self.package_name)) + so = get_so_ext() + shutil.copy(os.path.join(build_path, 'libz3java.%s' % so), + os.path.join(dist_path, 'bin', 'libz3java.%s' % so)) + class ExampleComponent(Component): def __init__(self, name, path): Component.__init__(self, name, path, []) @@ -2433,6 +2483,14 @@ def mk_win_dist(build_path, dist_path): shutil.copy(os.path.join(build_path, pyc), os.path.join(dist_path, 'bin', pyc)) +def mk_unix_dist(build_path, dist_path): + for c in get_components(): + c.mk_unix_dist(build_path, dist_path) + # Add Z3Py to lib directory + for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(build_path)): + shutil.copy(os.path.join(build_path, pyc), + os.path.join(dist_path, 'bin', pyc)) + if __name__ == '__main__': import doctest From c568c0908651ed4b3a8f8ec3fa97c52dc2aa6271 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 13 Feb 2013 10:46:00 -0800 Subject: [PATCH 084/101] Rename windows nightly build Signed-off-by: Leonardo de Moura --- scripts/mk_win_dist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mk_win_dist.py b/scripts/mk_win_dist.py index 85c1dddfc..137ea431c 100644 --- a/scripts/mk_win_dist.py +++ b/scripts/mk_win_dist.py @@ -161,9 +161,9 @@ def get_z3_name(x64): else: platform = "x86" if GIT_HASH: - return 'z3-win-%s.%s.%s.%s-%s' % (major, minor, build, mk_util.git_hash(), platform) + return 'z3-%s.%s.%s.%s-%s-win' % (major, minor, build, mk_util.git_hash(), platform) else: - return 'z3-win-%s.%s.%s-%s' % (major, minor, build, platform) + return 'z3-%s.%s.%s-%s-win' % (major, minor, build, platform) def mk_dist_dir_core(x64): if x64: From 0c641cdf9522533d2c647bb79da5d8d5da4c1492 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 13 Feb 2013 16:53:56 -0800 Subject: [PATCH 085/101] hilbert basis experiment Signed-off-by: Nikolaj Bjorner --- src/muz_qe/hilbert_basis.cpp | 81 +++++++++++++++++++--------- src/muz_qe/hilbert_basis.h | 1 + src/test/hilbert_basis.cpp | 100 ++++++++++++++++++++++++++++------- 3 files changed, 139 insertions(+), 43 deletions(-) diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index 09296f89d..59c9d5080 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -26,10 +26,10 @@ typedef u_map offset_refs_t; template class rational_map : public map {}; -class rational_lt { +class rational_abs_lt { vector & m_values; public: - rational_lt(vector & values): + rational_abs_lt(vector & values): m_values(values) { } bool operator()(int v1, int v2) const { @@ -41,8 +41,8 @@ public: class hilbert_basis::rational_heap { vector m_u2r; // [index |-> weight] rational_map m_r2u; // [weight |-> index] - rational_lt m_lt; // less_than on indices - heap m_heap; // binary heap over weights + rational_abs_lt m_lt; // less_than on indices + heap m_heap; // binary heap over weights public: rational_heap(): m_lt(m_u2r), m_heap(10, m_lt) {} @@ -76,9 +76,6 @@ public: m_heap.find_le(val, result); } - void find_le(numeral const& r, int_vector& result) { - find_le(m_r2u.find(r), result); - } }; class hilbert_basis::weight_map { @@ -97,11 +94,12 @@ class hilbert_basis::weight_map { unsigned m_cost; unsigned get_value(numeral const& w) { + numeral r = abs(w); unsigned val; - if (!m_heap.is_declared(w, val)) { - val = m_heap.declare(w); + if (!m_heap.is_declared(r, val)) { + val = m_heap.declare(r); SASSERT(val == m_offsets.size()); - if (w.is_nonneg()) { + if (r.is_nonneg()) { m_heap.insert(val); } m_offsets.push_back(unsigned_vector()); @@ -121,6 +119,14 @@ public: m_offsets[val].erase(idx.m_offset); } + unsigned get_size() const { + unsigned sz = 0; + for (unsigned i = 0; i < m_offsets.size(); ++i) { + sz += m_offsets[i].size(); + } + return sz; + } + void reset() { m_offsets.reset(); m_heap.reset(); @@ -129,6 +135,9 @@ public: unsigned get_cost() const { return m_cost; } + /** + retrieve + */ bool init_find(numeral const& w, offset_t idx) { m_le.reset(); m_found.reset(); @@ -143,7 +152,7 @@ public: m_le.push_back(val); } for (unsigned i = 0; i < m_le.size(); ++i) { - if (m_heap.u2r()[m_le[i]].is_zero() && w.is_pos()) { + if (m_heap.u2r()[m_le[i]].is_zero() && !w.is_zero()) { continue; } unsigned_vector const& offsets = m_offsets[m_le[i]]; @@ -159,16 +168,25 @@ public: } return !m_found.empty(); } + + unsigned get_find_cost(numeral const& w) { + m_le.reset(); + unsigned cost = 0; + unsigned val = get_value(w); + m_heap.find_le(val, m_le); + for (unsigned i = 0; i < m_le.size(); ++i) { + cost += m_offsets[m_le[i]].size(); + } + return cost; + } bool update_find(unsigned round, numeral const& w, offset_t idx) { - //std::cout << "update find: " << w << "\n"; m_found.reset(); m_le.reset(); m_cost = 0; - m_heap.find_le(w, m_le); - unsigned vl; + unsigned vl = get_value(w); + m_heap.find_le(vl, m_le); for (unsigned i = 0; i < m_le.size(); ++i) { - //std::cout << "insert update find: " << m_weights[m_le[i]] << "\n"; unsigned_vector const& offsets = m_offsets[m_le[i]]; for (unsigned j = 0; j < offsets.size(); ++j) { unsigned offs = offsets[j]; @@ -255,9 +273,17 @@ public: m_refs.reset(); bool found = m_weight.init_find(vs.value(), idx); TRACE("hilbert_basis", tout << "init: " << m_found.size() << " cost: " << m_weight.get_cost() << "\n";); +#if 0 + std::cout << vs.value() << " " << m_found.size() << " "; + for (unsigned i = 0; i < m_values.size(); ++i) { + std::cout << vs[i] << ": " << m_values[i]->get_find_cost(vs[i]) << " "; + } + std::cout << "\n"; +#endif #if 0 for (unsigned i = 0; found && i < m_values.size(); ++i) { found = m_values[i]->update_find(i, vs[i], idx); + std::cout << vs[i] << ": " << m_found.size() << " "; TRACE("hilbert_basis", tout << "update " << i << ": " << m_found.size() << " cost: " << m_values[i]->get_cost() << "\n";); } #else @@ -269,6 +295,7 @@ public: } return false; #endif + if (found) { found_idx = m_found[0]; } @@ -290,6 +317,7 @@ public: } st.update("hb.index.num_find", m_stats.m_num_find); st.update("hb.index.num_insert", m_stats.m_num_insert); + st.update("hb.index.size", m_weight.get_size()); } void reset_statistics() { @@ -363,12 +391,12 @@ public: */ class hilbert_basis::passive { - hilbert_basis& hb; - svector m_passive; - vector m_weights; - unsigned_vector m_free_list; - rational_lt m_lt; // less_than on indices - heap m_heap; // binary heap over weights + hilbert_basis& hb; + svector m_passive; + vector m_weights; + unsigned_vector m_free_list; + rational_abs_lt m_lt; // less_than on indices + heap m_heap; // binary heap over weights numeral get_weight(offset_t idx) { numeral w(0); @@ -487,6 +515,7 @@ void hilbert_basis::reset() { void hilbert_basis::collect_statistics(statistics& st) const { st.update("hb.num_subsumptions", m_stats.m_num_subsumptions); st.update("hb.num_resolves", m_stats.m_num_resolves); + st.update("hb.num_saturations", m_stats.m_num_saturations); m_index->collect_statistics(st); } @@ -566,9 +595,11 @@ lbool hilbert_basis::saturate() { init_basis(); for (unsigned i = 0; !m_cancel && i < m_ineqs.size(); ++i) { lbool r = saturate(m_ineqs[i]); + ++m_stats.m_num_saturations; if (r != l_true) { return r; } + } if (m_cancel) { return l_undef; @@ -650,6 +681,7 @@ void hilbert_basis::resolve(offset_t i, offset_t j, offset_t r) { u[k] = v[k] + w[k]; } u.value() = v.value() + w.value(); + // std::cout << "resolve: " << v.value() << " + " << w.value() << " = " << u.value() << "\n"; TRACE("hilbert_basis_verbose", display(tout, i); display(tout, j); @@ -674,11 +706,12 @@ hilbert_basis::offset_t hilbert_basis::alloc_vector() { void hilbert_basis::add_goal(offset_t idx) { values v = vec(idx); + if (is_subsumed(idx)) { + return; + } m_index->insert(idx, v); if (v.value().is_zero()) { - if (!is_subsumed(idx)) { - m_zero.push_back(idx); - } + m_zero.push_back(idx); } else { m_passive->insert(idx); diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index 73a9c89a5..f4529de85 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -50,6 +50,7 @@ private: struct stats { unsigned m_num_subsumptions; unsigned m_num_resolves; + unsigned m_num_saturations; stats() { reset(); } void reset() { memset(this, 0, sizeof(*this)); } }; diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index 275aa486d..86b0f1bad 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -1,5 +1,78 @@ #include "hilbert_basis.h" +#include +#include +hilbert_basis* g_hb = 0; +static double g_start_time; + +static void display_statistics(hilbert_basis& hb) { + double time = static_cast(clock()) - g_start_time; + statistics st; + hb.collect_statistics(st); + st.display(std::cout); + std::cout << "time: " << (time / CLOCKS_PER_SEC) << " secs\n"; +} + +static void on_ctrl_c(int) { + signal (SIGINT, SIG_DFL); + display_statistics(*g_hb); + raise(SIGINT); +} + +static void saturate_basis(hilbert_basis& hb) { + signal(SIGINT, on_ctrl_c); + g_hb = &hb; + g_start_time = static_cast(clock()); + lbool is_sat = hb.saturate(); + + switch(is_sat) { + case l_true: + std::cout << "sat\n"; + hb.display(std::cout); + break; + case l_false: + std::cout << "unsat\n"; + break; + case l_undef: + std::cout << "undef\n"; + break; + } + display_statistics(hb); +} + +/** + n - number of variables. + k - subset of variables to be non-zero + bound - numeric value of upper and lower bound + num_ineqs - number of inequalities to create +*/ +static void gorrila_test(unsigned seed, unsigned n, unsigned k, unsigned bound, unsigned num_ineqs) { + std::cout << "Gorrila test\n"; + random_gen rand(seed); + hilbert_basis hb; + SASSERT(0 < bound); + SASSERT(k <= n); + int ibound = static_cast(bound); + for (unsigned i = 0; i < num_ineqs; ++i) { + vector nv; + nv.resize(n); + rational a0; + unsigned num_selected = 0; + while (num_selected < k) { + unsigned s = rand(n); + if (nv[s].is_zero()) { + nv[s] = rational(ibound - static_cast(rand(2*bound+1))); + if (!nv[s].is_zero()) { + ++num_selected; + } + } + } + a0 = rational(ibound - static_cast(rand(2*bound+1))); + hb.add_ge(nv, a0); + } + hb.display(std::cout << "Saturate\n"); + saturate_basis(hb); +} static vector vec(int i, int j, int k) { vector nv; @@ -45,25 +118,6 @@ static vector vec(int i, int j, int k, int l, int x, int y, int z) { } -static void saturate_basis(hilbert_basis& hb) { - lbool is_sat = hb.saturate(); - - switch(is_sat) { - case l_true: - std::cout << "sat\n"; - hb.display(std::cout); - break; - case l_false: - std::cout << "unsat\n"; - break; - case l_undef: - std::cout << "undef\n"; - break; - } - statistics st; - hb.collect_statistics(st); - st.display(std::cout); -} // example 9, Ajili, Contenjean @@ -191,6 +245,7 @@ static void tst11() { void tst_hilbert_basis() { std::cout << "hilbert basis test\n"; +#if 0 tst1(); tst2(); tst3(); @@ -202,4 +257,11 @@ void tst_hilbert_basis() { tst9(); tst10(); tst11(); + gorrila_test(0, 4, 3, 20, 5); + gorrila_test(1, 4, 3, 20, 5); + gorrila_test(2, 4, 3, 20, 5); + gorrila_test(0, 4, 2, 20, 5); + gorrila_test(0, 4, 2, 20, 5); +#endif + gorrila_test(0, 10, 7, 20, 11); } From d2651f1afc4e9ca614a0a5332c46f6129a6fffc4 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 13 Feb 2013 18:53:37 -0800 Subject: [PATCH 086/101] Keep consistent error messages Signed-off-by: Leonardo de Moura --- src/ast/ast.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 704ae9fc8..8d643a348 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1849,9 +1849,9 @@ void ast_manager::check_sort(func_decl const * decl, unsigned num_args, expr * c sort * given = get_sort(args[i]); if (!compatible_sorts(expected, given)) { std::ostringstream buff; - buff << "Invalid function application for " << decl->get_name() << ". "; - buff << "Sort mismatch on argument at position " << (i+1) << ". "; - buff << "Expected: " << mk_pp(expected, m) << " but given " << mk_pp(given, m); + buff << "invalid function application for " << decl->get_name() << ", "; + buff << "sort mismatch on argument at position " << (i+1) << ", "; + buff << "expected " << mk_pp(expected, m) << " but given " << mk_pp(given, m); throw ast_exception(buff.str().c_str()); } } @@ -1865,9 +1865,9 @@ void ast_manager::check_sort(func_decl const * decl, unsigned num_args, expr * c sort * given = get_sort(args[i]); if (!compatible_sorts(expected, given)) { std::ostringstream buff; - buff << "Invalid function application for " << decl->get_name() << ". "; - buff << "Sort mismatch on argument at position " << (i+1) << ". "; - buff << "Expected: " << mk_pp(expected, m) << " but given " << mk_pp(given, m); + buff << "invalid function application for " << decl->get_name() << ", "; + buff << "sort mismatch on argument at position " << (i+1) << ", "; + buff << "expected " << mk_pp(expected, m) << " but given " << mk_pp(given, m); throw ast_exception(buff.str().c_str()); } } From 0c0fe40446b017ec20ff52a355dd2bcbf1a42dd6 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 13 Feb 2013 19:03:37 -0800 Subject: [PATCH 087/101] Fix Python 2.6 incompatibility at mk_util.py Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4e1a38af2..873c22b80 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -76,10 +76,7 @@ GPROF=False GIT_HASH=False def check_output(cmd): - try: - return subprocess.check_output(cmd, shell=True).rstrip('\r\n') - except: - return subprocess.check_output(cmd).rstrip('\r\n') + return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].rstrip('\r\n') def git_hash(): try: From 030aef5d5a0e75aff9ad92e3a4eafd511aa3d79a Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 14 Feb 2013 09:55:42 -0800 Subject: [PATCH 088/101] Fix bug reported by Andrey Kupriyanov Signed-off-by: Leonardo de Moura --- RELEASE_NOTES | 2 ++ src/api/c++/z3++.h | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 27c52140f..13957064e 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -59,6 +59,8 @@ Version 4.3.2 - Fixed http://stackoverflow.com/questions/14524316/z3-4-3-get-complete-model. +- Fixed bugs in the C++ API (Thanks to Andrey Kupriyanov). + Version 4.3.1 ============= diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 5c1e6ca0c..5af4bf60b 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -619,6 +619,8 @@ namespace z3 { a.check_error(); return expr(a.ctx(), r); } + friend expr implies(expr const & a, bool b) { return implies(a, a.ctx().bool_val(b)); } + friend expr implies(bool a, expr const & b) { return implies(b.ctx().bool_val(a), b); } /** \brief Create the if-then-else expression ite(c, t, e) @@ -758,7 +760,7 @@ namespace z3 { return expr(a.ctx(), r); } friend expr operator-(expr const & a, int b) { return a - a.ctx().num_val(b, a.get_sort()); } - friend expr operator-(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) - a; } + friend expr operator-(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) - b; } friend expr operator<=(expr const & a, expr const & b) { check_context(a, b); @@ -777,7 +779,7 @@ namespace z3 { return expr(a.ctx(), r); } friend expr operator<=(expr const & a, int b) { return a <= a.ctx().num_val(b, a.get_sort()); } - friend expr operator<=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) <= a; } + friend expr operator<=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) <= b; } friend expr operator>=(expr const & a, expr const & b) { check_context(a, b); @@ -796,7 +798,7 @@ namespace z3 { return expr(a.ctx(), r); } friend expr operator>=(expr const & a, int b) { return a >= a.ctx().num_val(b, a.get_sort()); } - friend expr operator>=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) >= a; } + friend expr operator>=(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) >= b; } friend expr operator<(expr const & a, expr const & b) { check_context(a, b); @@ -815,7 +817,7 @@ namespace z3 { return expr(a.ctx(), r); } friend expr operator<(expr const & a, int b) { return a < a.ctx().num_val(b, a.get_sort()); } - friend expr operator<(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) < a; } + friend expr operator<(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) < b; } friend expr operator>(expr const & a, expr const & b) { check_context(a, b); @@ -834,7 +836,7 @@ namespace z3 { return expr(a.ctx(), r); } friend expr operator>(expr const & a, int b) { return a > a.ctx().num_val(b, a.get_sort()); } - friend expr operator>(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) > a; } + friend expr operator>(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) > b; } friend expr operator&(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = Z3_mk_bvand(a.ctx(), a, b); return expr(a.ctx(), r); } friend expr operator&(expr const & a, int b) { return a & a.ctx().num_val(b, a.get_sort()); } @@ -888,31 +890,31 @@ namespace z3 { */ inline expr ule(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvule(a.ctx(), a, b)); } inline expr ule(expr const & a, int b) { return ule(a, a.ctx().num_val(b, a.get_sort())); } - inline expr ule(int a, expr const & b) { return ule(b.ctx().num_val(a, b.get_sort()), a); } + inline expr ule(int a, expr const & b) { return ule(b.ctx().num_val(a, b.get_sort()), b); } /** \brief unsigned less than operator for bitvectors. */ inline expr ult(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvult(a.ctx(), a, b)); } inline expr ult(expr const & a, int b) { return ult(a, a.ctx().num_val(b, a.get_sort())); } - inline expr ult(int a, expr const & b) { return ult(b.ctx().num_val(a, b.get_sort()), a); } + inline expr ult(int a, expr const & b) { return ult(b.ctx().num_val(a, b.get_sort()), b); } /** \brief unsigned greater than or equal to operator for bitvectors. */ inline expr uge(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvuge(a.ctx(), a, b)); } inline expr uge(expr const & a, int b) { return uge(a, a.ctx().num_val(b, a.get_sort())); } - inline expr uge(int a, expr const & b) { return uge(b.ctx().num_val(a, b.get_sort()), a); } + inline expr uge(int a, expr const & b) { return uge(b.ctx().num_val(a, b.get_sort()), b); } /** \brief unsigned greater than operator for bitvectors. */ inline expr ugt(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvugt(a.ctx(), a, b)); } inline expr ugt(expr const & a, int b) { return ugt(a, a.ctx().num_val(b, a.get_sort())); } - inline expr ugt(int a, expr const & b) { return ugt(b.ctx().num_val(a, b.get_sort()), a); } + inline expr ugt(int a, expr const & b) { return ugt(b.ctx().num_val(a, b.get_sort()), b); } /** \brief unsigned division operator for bitvectors. */ inline expr udiv(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvudiv(a.ctx(), a, b)); } inline expr udiv(expr const & a, int b) { return udiv(a, a.ctx().num_val(b, a.get_sort())); } - inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), a); } + inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), b); } // Basic functions for creating quantified formulas. // The C API should be used for creating quantifiers with patterns, weights, many variables, etc. From 9d45d872a78d092e276aa6243fb4017ab5735940 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 14 Feb 2013 10:26:15 -0800 Subject: [PATCH 089/101] Compress Z3 distribution zip files Signed-off-by: Leonardo de Moura --- scripts/mk_unix_dist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_unix_dist.py b/scripts/mk_unix_dist.py index 3b9511367..8256236cb 100644 --- a/scripts/mk_unix_dist.py +++ b/scripts/mk_unix_dist.py @@ -190,7 +190,7 @@ def mk_zip(): try: os.chdir(DIST_DIR) zfname = '%s.zip' % dist_path - ZIPOUT = zipfile.ZipFile(zfname, 'w') + ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED) os.path.walk(dist_path, mk_zip_visitor, '*') if is_verbose(): print "Generated '%s'" % zfname From 5e72cf0123f6c9c03ccab44d3aa1209603eb134f Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Thu, 14 Feb 2013 10:55:43 -0800 Subject: [PATCH 090/101] Compress windows distribution zip files Signed-off-by: Leonardo de Moura --- scripts/mk_win_dist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_win_dist.py b/scripts/mk_win_dist.py index 137ea431c..a52c8af43 100644 --- a/scripts/mk_win_dist.py +++ b/scripts/mk_win_dist.py @@ -205,7 +205,7 @@ def mk_zip_core(x64): try: os.chdir(DIST_DIR) zfname = '%s.zip' % dist_path - ZIPOUT = zipfile.ZipFile(zfname, 'w') + ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED) os.path.walk(dist_path, mk_zip_visitor, '*') if is_verbose(): print "Generated '%s'" % zfname From 6e7d04f94e1bcc05c0a72c5bf8c438caa7cd2ad2 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 14 Feb 2013 15:06:17 -0800 Subject: [PATCH 091/101] working on hilbert basis Signed-off-by: Nikolaj Bjorner --- src/muz_qe/hilbert_basis.cpp | 701 ++++++++++++++++++----------------- src/muz_qe/hilbert_basis.h | 37 +- src/test/hilbert_basis.cpp | 41 +- 3 files changed, 412 insertions(+), 367 deletions(-) diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index 59c9d5080..b452fbc77 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -26,364 +26,219 @@ typedef u_map offset_refs_t; template class rational_map : public map {}; -class rational_abs_lt { - vector & m_values; -public: - rational_abs_lt(vector & values): - m_values(values) { - } - bool operator()(int v1, int v2) const { - return m_values[v1] < m_values[v2]; - } -}; - -class hilbert_basis::rational_heap { - vector m_u2r; // [index |-> weight] - rational_map m_r2u; // [weight |-> index] - rational_abs_lt m_lt; // less_than on indices - heap m_heap; // binary heap over weights -public: - - rational_heap(): m_lt(m_u2r), m_heap(10, m_lt) {} - - vector& u2r() { return m_u2r; } - - void insert(unsigned v) { - m_heap.insert(v); - } - - void reset() { - m_u2r.reset(); - m_r2u.reset(); - m_heap.reset(); - } - - bool is_declared(numeral const& r, unsigned& val) const { - return m_r2u.find(r, val); - } - - unsigned declare(numeral const& r) { - SASSERT(!m_r2u.contains(r)); - unsigned val = m_u2r.size(); - m_u2r.push_back(r); - m_r2u.insert(r, val); - m_heap.set_bounds(val+1); - return val; - } - - void find_le(unsigned val, int_vector & result) { - m_heap.find_le(val, result); - } - -}; - -class hilbert_basis::weight_map { +class hilbert_basis::value_index { struct stats { unsigned m_num_comparisons; + unsigned m_num_hit; + unsigned m_num_miss; + stats() { reset(); } void reset() { memset(this, 0, sizeof(*this)); } }; - rational_heap m_heap; - vector m_offsets; // [index |-> offset-list] - int_vector m_le; // recycled set of indices with lesser weights - stats m_stats; - svector& m_found; - offset_refs_t& m_refs; - unsigned m_cost; + typedef int_hashtable > int_table; + hilbert_basis& hb; + int_table m_table; + stats m_stats; - unsigned get_value(numeral const& w) { - numeral r = abs(w); - unsigned val; - if (!m_heap.is_declared(r, val)) { - val = m_heap.declare(r); - SASSERT(val == m_offsets.size()); - if (r.is_nonneg()) { - m_heap.insert(val); - } - m_offsets.push_back(unsigned_vector()); - } - return val; - } public: - weight_map(svector& found, offset_refs_t& refs): m_found(found), m_refs(refs) {} - - void insert(offset_t idx, numeral const& w) { - unsigned val = get_value(w); - m_offsets[val].push_back(idx.m_offset); + value_index(hilbert_basis& hb): + hb(hb) + {} + + void insert(offset_t idx, values const& vs) { + m_table.insert(idx.m_offset); } - void remove(offset_t idx, numeral const& w) { - unsigned val = get_value(w); - m_offsets[val].erase(idx.m_offset); - } - - unsigned get_size() const { - unsigned sz = 0; - for (unsigned i = 0; i < m_offsets.size(); ++i) { - sz += m_offsets[i].size(); - } - return sz; + void remove(offset_t idx, values const& vs) { + m_table.remove(idx.m_offset); } void reset() { - m_offsets.reset(); - m_heap.reset(); - m_le.reset(); - } - - unsigned get_cost() const { return m_cost; } - - /** - retrieve - */ - bool init_find(numeral const& w, offset_t idx) { - m_le.reset(); - m_found.reset(); - m_cost = 0; - unsigned val = get_value(w); - // for positive values, the weights should be less or equal. - // for non-positive values, the weights have to be the same. - if (w.is_pos()) { - m_heap.find_le(val, m_le); - } - else { - m_le.push_back(val); - } - for (unsigned i = 0; i < m_le.size(); ++i) { - if (m_heap.u2r()[m_le[i]].is_zero() && !w.is_zero()) { - continue; - } - unsigned_vector const& offsets = m_offsets[m_le[i]]; - for (unsigned j = 0; j < offsets.size(); ++j) { - unsigned offs = offsets[j]; - ++m_stats.m_num_comparisons; - ++m_cost; - if (offs != idx.m_offset) { - m_refs.insert(offs, 0); - m_found.push_back(offset_t(offs)); - } - } - } - return !m_found.empty(); + m_table.reset(); } - unsigned get_find_cost(numeral const& w) { - m_le.reset(); - unsigned cost = 0; - unsigned val = get_value(w); - m_heap.find_le(val, m_le); - for (unsigned i = 0; i < m_le.size(); ++i) { - cost += m_offsets[m_le[i]].size(); - } - return cost; - } - - bool update_find(unsigned round, numeral const& w, offset_t idx) { - m_found.reset(); - m_le.reset(); - m_cost = 0; - unsigned vl = get_value(w); - m_heap.find_le(vl, m_le); - for (unsigned i = 0; i < m_le.size(); ++i) { - unsigned_vector const& offsets = m_offsets[m_le[i]]; - for (unsigned j = 0; j < offsets.size(); ++j) { - unsigned offs = offsets[j]; - ++m_stats.m_num_comparisons; - ++m_cost; - if (offs != idx.m_offset && m_refs.find(offs, vl) && vl == round) { - m_refs.insert(offs, round + 1); - m_found.push_back(offset_t(offs)); - } + bool find(offset_t idx, values const& vs, offset_t& found_idx) { + // display_profile(idx, std::cout); + int_table::iterator it = m_table.begin(), end = m_table.end(); + for (; it != end; ++it) { + offset_t offs(*it); + ++m_stats.m_num_comparisons; + if (*it != idx.m_offset && hb.is_subsumed(idx, offs)) { + found_idx = offs; + ++m_stats.m_num_hit; + return true; } } - return !m_found.empty(); - } + ++m_stats.m_num_miss; + return false; + } void collect_statistics(statistics& st) const { st.update("hb.index.num_comparisons", m_stats.m_num_comparisons); + st.update("hb.index.num_hit", m_stats.m_num_hit); + st.update("hb.index.num_miss", m_stats.m_num_miss); } void reset_statistics() { m_stats.reset(); } + + unsigned size() const { + return m_table.size(); + } +private: + void display_profile(offset_t idx, std::ostream& out) { + unsigned_vector leq; + unsigned nv = hb.get_num_vars(); + values const& vs = hb.vec(idx); + leq.resize(nv+1); + numeral maxw(0); + for (unsigned i = 0; i < nv; ++i) { + if (!hb.is_abs_geq(maxw, vs[i])) { + maxw = vs[i]; + } + } + unsigned num_below_max = 0; + int_table::iterator it = m_table.begin(), end = m_table.end(); + for (; it != end; ++it) { + offset_t offs(*it); + values const& ws = hb.vec(offs); + if (ws.weight() <= vs.weight()) { + leq[0]++; + } + bool filtered = false; + for (unsigned i = 0; i < nv; ++i) { + if (hb.is_abs_geq(vs[i], ws[i])) { + leq[i+1]++; + } + if (!hb.is_abs_geq(maxw, ws[i])) { + filtered = true; + } + } + if (!filtered) { + ++num_below_max; + } + } + out << vs.weight() << ":" << leq[0] << " "; + for (unsigned i = 0; i < nv; ++i) { + out << vs[i] << ":" << leq[i+1] << " "; + } + out << " max<= " << num_below_max; + out << "\n"; + } }; + + class hilbert_basis::index { - // for each index, a heap of weights. - // for each weight a list of offsets + // for each non-positive weight a separate index. + // for positive weights a shared value index. struct stats { - unsigned m_num_comparisons; unsigned m_num_find; unsigned m_num_insert; stats() { reset(); } void reset() { memset(this, 0, sizeof(*this)); } }; - - hilbert_basis& hb; - offset_refs_t m_refs; - svector m_found; - ptr_vector m_values; - weight_map m_weight; - stats m_stats; + typedef rational_map value_map; + hilbert_basis& hb; + value_map m_neg; + value_index m_pos; + value_index m_zero; + stats m_stats; public: - - index(hilbert_basis& hb): hb(hb), m_weight(m_found, m_refs) {} - - ~index() { - for (unsigned i = 0; i < m_values.size(); ++i) { - dealloc(m_values[i]); - } - } - - void init(unsigned num_vars) { - if (m_values.empty()) { - for (unsigned i = 0; i < num_vars; ++i) { - m_values.push_back(alloc(weight_map, m_found, m_refs)); - } - } - SASSERT(m_values.size() == num_vars); - } + index(hilbert_basis& hb): hb(hb), m_pos(hb), m_zero(hb) {} void insert(offset_t idx, values const& vs) { ++m_stats.m_num_insert; -#if 0 - for (unsigned i = 0; i < m_values.size(); ++i) { - m_values[i]->insert(idx, vs[i]); + if (vs.weight().is_pos()) { + m_pos.insert(idx, vs); + } + else if (vs.weight().is_zero()) { + m_zero.insert(idx, vs); + } + else { + value_index* map = 0; + if (!m_neg.find(vs.weight(), map)) { + map = alloc(value_index, hb); + m_neg.insert(vs.weight(), map); + } + map->insert(idx, vs); } -#endif - m_weight.insert(idx, vs.value()); } void remove(offset_t idx, values const& vs) { -#if 0 - for (unsigned i = 0; i < m_values.size(); ++i) { - m_values[i]->remove(idx, vs[i]); + if (vs.weight().is_pos()) { + m_pos.remove(idx, vs); } -#endif - m_weight.remove(idx, vs.value()); + else if (vs.weight().is_zero()) { + m_zero.remove(idx, vs); + } + else { + m_neg.find(vs.weight())->remove(idx, vs); + } } - bool find(values const& vs, offset_t idx, offset_t& found_idx) { + bool find(offset_t idx, values const& vs, offset_t& found_idx) { ++m_stats.m_num_find; - m_refs.reset(); - bool found = m_weight.init_find(vs.value(), idx); - TRACE("hilbert_basis", tout << "init: " << m_found.size() << " cost: " << m_weight.get_cost() << "\n";); -#if 0 - std::cout << vs.value() << " " << m_found.size() << " "; - for (unsigned i = 0; i < m_values.size(); ++i) { - std::cout << vs[i] << ": " << m_values[i]->get_find_cost(vs[i]) << " "; + if (vs.weight().is_pos()) { + return m_pos.find(idx, vs, found_idx); } - std::cout << "\n"; -#endif -#if 0 - for (unsigned i = 0; found && i < m_values.size(); ++i) { - found = m_values[i]->update_find(i, vs[i], idx); - std::cout << vs[i] << ": " << m_found.size() << " "; - TRACE("hilbert_basis", tout << "update " << i << ": " << m_found.size() << " cost: " << m_values[i]->get_cost() << "\n";); + else if (vs.weight().is_zero()) { + return m_zero.find(idx, vs, found_idx); } -#else - for (unsigned i = 0; i < m_found.size(); ++i) { - if (is_subsumed(idx, m_found[i])) { - found_idx = m_found[i]; - return true; - } - } - return false; -#endif - - if (found) { - found_idx = m_found[0]; - } - return found; - } + else { + value_index* map; + return + m_neg.find(vs.weight(), map) && + map->find(idx, vs, found_idx); + } + } void reset() { - for (unsigned i = 0; i < m_values.size(); ++i) { - m_values[i]->reset(); + m_pos.reset(); + m_neg.reset(); + value_map::iterator it = m_neg.begin(), end = m_neg.end(); + for (; it != end; ++it) { + it->m_value->reset(); } - m_weight.reset(); - m_refs.reset(); } void collect_statistics(statistics& st) const { - m_weight.collect_statistics(st); - for (unsigned i = 0; i < m_values.size(); ++i) { - m_values[i]->collect_statistics(st); - } - st.update("hb.index.num_find", m_stats.m_num_find); + m_pos.collect_statistics(st); + m_zero.collect_statistics(st); + value_map::iterator it = m_neg.begin(), end = m_neg.end(); + for (; it != end; ++it) { + it->m_value->collect_statistics(st); + } + st.update("hb.index.num_find", m_stats.m_num_find); st.update("hb.index.num_insert", m_stats.m_num_insert); - st.update("hb.index.size", m_weight.get_size()); + st.update("hb.index.size", size()); } void reset_statistics() { - m_stats.reset(); - m_weight.reset_statistics(); - for (unsigned i = 0; i < m_values.size(); ++i) { - m_values[i]->reset_statistics(); - } - } - - - /** - Vector v is subsumed by vector w if - - v[i] >= w[i] for each index i. - - a*v >= a*w for the evaluation of vectors with respect to a. - - a*v < 0 => a*v = a*w - - - Justification: - - let u := v - w, then - - u[i] >= 0 for each index i - - a*u = a*(v-w) >= 0 - - So v = u + w, where a*u >= 0, a*w >= 0. - - If a*v >= a*w >= 0 then v and w are linear - solutions of e_i, and also v-w is a solution. - - If a*v = a*w < 0, then a*(v-w) = 0, so v can be obtained from w + (v - w). - - */ - - bool is_subsumed(offset_t i, offset_t j) const { - values v = hb.vec(i); - values w = hb.vec(j); - numeral const& n = v.value(); - numeral const& m = w.value(); - bool r = - i.m_offset != j.m_offset && - n >= m && (!m.is_neg() || n == m) && - is_geq(v, w); - CTRACE("hilbert_basis", r, - hb.display(tout, i); - tout << " <= \n"; - hb.display(tout, j); - tout << "\n";); - return r; - } - - bool is_geq(values v, values w) const { - unsigned nv = hb.get_num_vars(); - for (unsigned i = 0; i < nv; ++i) { - if (v[i] < w[i]) { - return false; - } + m_pos.reset_statistics(); + m_zero.reset_statistics(); + value_map::iterator it = m_neg.begin(), end = m_neg.end(); + for (; it != end; ++it) { + it->m_value->reset_statistics(); } - return true; } - - + +private: + unsigned size() const { + unsigned sz = m_pos.size(); + sz += m_zero.size(); + value_map::iterator it = m_neg.begin(), end = m_neg.end(); + for (; it != end; ++it) { + sz += it->m_value->size(); + } + return sz; + } }; /** @@ -391,18 +246,25 @@ public: */ class hilbert_basis::passive { + struct lt { + passive& p; + lt(passive& p): p(p) {} + + bool operator()(int v1, int v2) const { + return p(v1, v2); + } + }; hilbert_basis& hb; svector m_passive; - vector m_weights; unsigned_vector m_free_list; - rational_abs_lt m_lt; // less_than on indices - heap m_heap; // binary heap over weights + lt m_lt; + heap m_heap; // binary heap over weights - numeral get_weight(offset_t idx) { + numeral get_value(offset_t idx) const { numeral w(0); unsigned nv = hb.get_num_vars(); for (unsigned i = 0; i < nv; ++i) { - w += hb.vec(idx)[i]; + w += abs(hb.vec(idx)[i]); } return w; } @@ -411,14 +273,13 @@ public: passive(hilbert_basis& hb): hb(hb) , - m_lt(m_weights), + m_lt(*this), m_heap(10, m_lt) {} void reset() { m_heap.reset(); m_free_list.reset(); - m_weights.reset(); m_passive.reset(); } @@ -440,14 +301,12 @@ public: if (m_free_list.empty()) { v = m_passive.size(); m_passive.push_back(idx); - m_weights.push_back(get_weight(idx)); m_heap.set_bounds(v+1); } else { v = m_free_list.back(); m_free_list.pop_back(); m_passive[v] = idx; - m_weights[v] = get_weight(idx); } m_heap.insert(v); } @@ -478,6 +337,43 @@ public: iterator end() { return iterator(*this, m_passive.size()); } + +public: + /** + Prefer positive weights to negative. + If both weights are positive, prefer the smallest weight. + If weights are the same, prefer the one that has smallest sum of values. + */ + bool operator()(int v1, int v2) const { + offset_t idx1 = m_passive[v1]; + offset_t idx2 = m_passive[v2]; + return get_value(idx1) < get_value(idx2); +#if 0 + values const& vec1 = hb.vec(idx1); + values const& vec2 = hb.vec(idx2); + numeral const& w1 = vec1.weight(); + numeral const& w2 = vec2.weight(); + SASSERT(!w1.is_zero()); + SASSERT(!w2.is_zero()); + + if (w1.is_pos()) { + if (w2.is_neg()) { + return true; + } + if (w1 != w2) { + return w1 < w2; + } + } + else { + if (w2.is_pos()) { + return false; + } + } + SASSERT(w1 == w2); + return get_value(idx1) < get_value(idx2); +#endif + } + }; hilbert_basis::hilbert_basis(): @@ -529,9 +425,6 @@ void hilbert_basis::add_ge(num_vector const& v, numeral const& b) { num_vector w; w.push_back(-b); w.append(v); - if (m_ineqs.empty()) { - m_index->init(w.size()); - } m_ineqs.push_back(w); } @@ -561,6 +454,14 @@ void hilbert_basis::add_eq(num_vector const& v) { add_ge(v); } +void hilbert_basis::set_is_int(unsigned var_index) { + // + // The 0't index is reserved for the constant + // coefficient. Shift indices by 1. + // + m_ints.push_back(var_index+1); +} + unsigned hilbert_basis::get_num_vars() const { if (m_ineqs.empty()) { return 0; @@ -580,26 +481,34 @@ void hilbert_basis::init_basis() { m_free_list.reset(); unsigned num_vars = get_num_vars(); for (unsigned i = 0; i < num_vars; ++i) { - num_vector w(num_vars, numeral(0)); - w[i] = numeral(1); - offset_t idx = alloc_vector(); - values v = vec(idx); - for (unsigned i = 0; i < num_vars; ++i) { - v[i] = w[i]; - } - m_basis.push_back(idx); + add_unit_vector(i, numeral(1)); } + for (unsigned i = 0; i < m_ints.size(); ++i) { + add_unit_vector(m_ints[i], numeral(-1)); + } +} + +void hilbert_basis::add_unit_vector(unsigned i, numeral const& e) { + unsigned num_vars = get_num_vars(); + num_vector w(num_vars, numeral(0)); + w[i] = e; + offset_t idx = alloc_vector(); + values v = vec(idx); + for (unsigned j = 0; j < num_vars; ++j) { + v[j] = w[j]; + } + m_basis.push_back(idx); } lbool hilbert_basis::saturate() { - init_basis(); + init_basis(); for (unsigned i = 0; !m_cancel && i < m_ineqs.size(); ++i) { + select_inequality(i); lbool r = saturate(m_ineqs[i]); ++m_stats.m_num_saturations; if (r != l_true) { return r; - } - + } } if (m_cancel) { return l_undef; @@ -619,7 +528,7 @@ lbool hilbert_basis::saturate(num_vector const& ineq) { values v = vec(*it); set_eval(v, ineq); add_goal(*it); - if (v.value().is_nonneg()) { + if (v.weight().is_nonneg()) { has_non_negative = true; } } @@ -652,7 +561,7 @@ lbool hilbert_basis::saturate(num_vector const& ineq) { m_basis.append(m_zero); for (unsigned i = 0; i < m_active.size(); ++i) { offset_t idx = m_active[i]; - if (vec(idx).value().is_pos()) { + if (vec(idx).weight().is_pos()) { m_basis.push_back(idx); } else { @@ -666,6 +575,51 @@ lbool hilbert_basis::saturate(num_vector const& ineq) { return l_true; } +void hilbert_basis::select_inequality(unsigned i) { + SASSERT(i < m_ineqs.size()); + unsigned best = i; + unsigned non_zeros = get_num_nonzeros(m_ineqs[i]); + unsigned prod = get_ineq_product(m_ineqs[i]); + for (unsigned j = i+1; prod != 0 && j < m_ineqs.size(); ++j) { + unsigned non_zeros2 = get_num_nonzeros(m_ineqs[j]); + unsigned prod2 = get_ineq_product(m_ineqs[j]); + if (prod2 < prod || (prod2 == prod && non_zeros2 < non_zeros)) { + prod = prod2; + non_zeros = non_zeros2; + best = j; + } + } + if (best != i) { + std::swap(m_ineqs[i], m_ineqs[best]); + } +} + +unsigned hilbert_basis::get_num_nonzeros(num_vector const& ineq) { + unsigned count = 0; + for (unsigned i = 0; i < ineq.size(); ++i) { + if (!ineq[i].is_zero()) { + ++count; + } + } + return count; +} + +unsigned hilbert_basis::get_ineq_product(num_vector const& ineq) { + unsigned num_pos = 0, num_neg = 0; + iterator it = begin(); + for (; it != end(); ++it) { + values v = vec(*it); + set_eval(v, ineq); + if (v.weight().is_pos()) { + ++num_pos; + } + else if (v.weight().is_neg()) { + ++num_neg; + } + } + return num_pos * num_neg; +} + void hilbert_basis::recycle(offset_t idx) { m_index->remove(idx, vec(idx)); m_free_list.push_back(idx); @@ -680,8 +634,8 @@ void hilbert_basis::resolve(offset_t i, offset_t j, offset_t r) { for (unsigned k = 0; k < nv; ++k) { u[k] = v[k] + w[k]; } - u.value() = v.value() + w.value(); - // std::cout << "resolve: " << v.value() << " + " << w.value() << " = " << u.value() << "\n"; + u.weight() = v.weight() + w.weight(); + // std::cout << "resolve: " << v.weight() << " + " << w.weight() << " = " << u.weight() << "\n"; TRACE("hilbert_basis_verbose", display(tout, i); display(tout, j); @@ -694,7 +648,7 @@ hilbert_basis::offset_t hilbert_basis::alloc_vector() { if (m_free_list.empty()) { unsigned num_vars = get_num_vars(); unsigned idx = m_store.size(); - m_store.resize(idx + 1 + get_num_vars()); + m_store.resize(idx + 1 + num_vars); return offset_t(idx); } else { @@ -710,7 +664,7 @@ void hilbert_basis::add_goal(offset_t idx) { return; } m_index->insert(idx, v); - if (v.value().is_zero()) { + if (v.weight().is_zero()) { m_zero.push_back(idx); } else { @@ -721,12 +675,7 @@ void hilbert_basis::add_goal(offset_t idx) { bool hilbert_basis::is_subsumed(offset_t idx) { offset_t found_idx; - if (m_index->find(vec(idx), idx, found_idx)) { - TRACE("hilbert_basis", - display(tout, idx); - tout << " <= \n"; - display(tout, found_idx); - tout << "\n";); + if (m_index->find(idx, vec(idx), found_idx)) { ++m_stats.m_num_subsumptions; return true; } @@ -734,13 +683,30 @@ bool hilbert_basis::is_subsumed(offset_t idx) { } bool hilbert_basis::can_resolve(offset_t i, offset_t j) const { - sign_t s1 = get_sign(i); - sign_t s2 = get_sign(j); - return s1 != s2 && abs(vec(i)[0] + vec(j)[0]) <= numeral(1); + if (get_sign(i) == get_sign(j)) { + return false; + } + values const& v1 = vec(i); + values const& v2 = vec(j); + // index 0 is reserved for the constant coefficient. + // The value of it should either be 0 or 1. + if (abs(v1[0] + v2[0]) > numeral(1)) { + return false; + } + for (unsigned i = 0; i < m_ints.size(); ++i) { + unsigned j = m_ints[i]; + if (v1[j].is_pos() && v2[j].is_neg()) { + return false; + } + if (v1[j].is_neg() && v2[j].is_pos()) { + return false; + } + } + return true; } hilbert_basis::sign_t hilbert_basis::get_sign(offset_t idx) const { - numeral val = vec(idx).value(); + numeral val = vec(idx).weight(); if (val.is_pos()) { return pos; } @@ -756,7 +722,7 @@ void hilbert_basis::set_eval(values& val, num_vector const& ineq) const { for (unsigned i = 0; i < num_vars; ++i) { result += val[i]*ineq[i]; } - val.value() = result; + val.weight() = result; } void hilbert_basis::display(std::ostream& out) const { @@ -796,7 +762,7 @@ void hilbert_basis::display(std::ostream& out) const { void hilbert_basis::display(std::ostream& out, offset_t o) const { display(out, vec(o)); - out << " -> " << vec(o).value() << "\n"; + out << " -> " << vec(o).weight() << "\n"; } void hilbert_basis::display(std::ostream& out, values const& v) const { @@ -842,3 +808,68 @@ void hilbert_isl_basis::add_le(num_vector const& v, numeral bound) { } m_basis.add_le(w); } + + +/** + Vector v is subsumed by vector w if + + v[i] >= w[i] for each index i. + + a*v >= a*w for the evaluation of vectors with respect to a. + + . a*v < 0 => a*v = a*w + . a*v > 0 => a*w > 0 + . a*v = 0 => a*w = 0 + + Justification: + + let u := v - w, then + + u[i] >= 0 for each index i + + a*u = a*(v-w) >= 0 + + So v = u + w, where a*u >= 0, a*w >= 0. + + If a*v >= a*w >= 0 then v and w are linear + solutions of e_i, and also v-w is a solution. + + If a*v = a*w < 0, then a*(v-w) = 0, so v can be obtained from w + (v - w). + +*/ + +bool hilbert_basis::is_subsumed(offset_t i, offset_t j) const { + values v = vec(i); + values w = vec(j); + numeral const& n = v.weight(); + numeral const& m = w.weight(); + bool r = + i.m_offset != j.m_offset && + n >= m && (!m.is_nonpos() || n == m) && + is_geq(v, w); + CTRACE("hilbert_basis", r, + display(tout, i); + tout << " <= \n"; + display(tout, j); + tout << "\n";); + return r; +} + +bool hilbert_basis::is_geq(values const& v, values const& w) const { + unsigned nv = get_num_vars(); + for (unsigned i = 0; i < nv; ++i) { + if (!is_abs_geq(v[i], w[i])) { + return false; + } + } + return true; +} + +bool hilbert_basis::is_abs_geq(numeral const& v, numeral const& w) const { + if (w.is_neg()) { + return v <= w; + } + else { + return v >= w; + } +} diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index f4529de85..000f27ec8 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -34,10 +34,9 @@ public: typedef rational numeral; typedef vector num_vector; private: - class rational_heap; + class value_index; class index; class passive; - class weight_map; struct offset_t { unsigned m_offset; offset_t(unsigned o) : m_offset(o) {} @@ -58,25 +57,26 @@ private: numeral* m_values; public: values(numeral* v):m_values(v) {} - numeral& value() { return m_values[0]; } // value of a*x + numeral& weight() { return m_values[0]; } // value of a*x numeral& operator[](unsigned i) { return m_values[i+1]; } // value of x_i - numeral const& value() const { return m_values[0]; } // value of a*x + numeral const& weight() const { return m_values[0]; } // value of a*x numeral const& operator[](unsigned i) const { return m_values[i+1]; } // value of x_i }; - vector m_ineqs; - num_vector m_store; - svector m_basis; - svector m_free_list; - svector m_active; - svector m_zero; - volatile bool m_cancel; + vector m_ineqs; // set of asserted inequalities + num_vector m_store; // store of vectors + svector m_basis; // vector of current basis + svector m_free_list; // free list of unused storage + svector m_active; // active set + svector m_zero; // zeros + passive* m_passive; // passive set + volatile bool m_cancel; stats m_stats; - index* m_index; - passive* m_passive; + index* m_index; // index of generated vectors + unsigned_vector m_ints; // indices that can be both positive and negative class iterator { hilbert_basis const& hb; - unsigned m_idx; + unsigned m_idx; public: iterator(hilbert_basis const& hb, unsigned idx): hb(hb), m_idx(idx) {} offset_t operator*() const { return hb.m_basis[m_idx]; } @@ -90,8 +90,15 @@ private: static bool is_invalid_offset(offset_t offs); lbool saturate(num_vector const& ineq); void init_basis(); + void select_inequality(unsigned i); + unsigned get_num_nonzeros(num_vector const& ineq); + unsigned get_ineq_product(num_vector const& ineq); + + void add_unit_vector(unsigned i, numeral const& e); unsigned get_num_vars() const; void set_eval(values& val, num_vector const& ineq) const; + bool is_geq(values const& v, values const& w) const; + bool is_abs_geq(numeral const& v, numeral const& w) const; bool is_subsumed(offset_t idx); bool is_subsumed(offset_t i, offset_t j) const; void recycle(offset_t idx); @@ -130,6 +137,8 @@ public: void add_le(num_vector const& v, numeral const& b); void add_eq(num_vector const& v, numeral const& b); + void set_is_int(unsigned var_index); + lbool saturate(); void set_cancel(bool f) { m_cancel = f; } diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index 86b0f1bad..8629e50be 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -245,23 +245,28 @@ static void tst11() { void tst_hilbert_basis() { std::cout << "hilbert basis test\n"; -#if 0 - tst1(); - tst2(); - tst3(); tst4(); - tst5(); - tst6(); - tst7(); - tst8(); - tst9(); - tst10(); - tst11(); - gorrila_test(0, 4, 3, 20, 5); - gorrila_test(1, 4, 3, 20, 5); - gorrila_test(2, 4, 3, 20, 5); - gorrila_test(0, 4, 2, 20, 5); - gorrila_test(0, 4, 2, 20, 5); -#endif - gorrila_test(0, 10, 7, 20, 11); + return; + + if (true) { + tst1(); + tst2(); + tst3(); + tst4(); + tst5(); + tst6(); + tst7(); + tst8(); + tst9(); + tst10(); + tst11(); + gorrila_test(0, 4, 3, 20, 5); + gorrila_test(1, 4, 3, 20, 5); + gorrila_test(2, 4, 3, 20, 5); + gorrila_test(0, 4, 2, 20, 5); + gorrila_test(0, 4, 2, 20, 5); + } + else { + gorrila_test(0, 10, 7, 20, 11); + } } From 3a68affb1b2bf867275e3cdfa747de1cfa230b27 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 14 Feb 2013 15:10:52 -0800 Subject: [PATCH 092/101] cal modifications --- src/muz_qe/hilbert_basis.cpp | 100 +++++++++++++++++++++++++---------- src/muz_qe/hilbert_basis.h | 1 + 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index 59c9d5080..70bd4b0dd 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -211,30 +211,17 @@ public: }; -class hilbert_basis::index { - // for each index, a heap of weights. - // for each weight a list of offsets - - struct stats { - unsigned m_num_comparisons; - unsigned m_num_find; - unsigned m_num_insert; - stats() { reset(); } - void reset() { memset(this, 0, sizeof(*this)); } - }; - - hilbert_basis& hb; - offset_refs_t m_refs; - svector m_found; +class hilbert_basis::value_index { + hilbert_basis& hb; ptr_vector m_values; - weight_map m_weight; - stats m_stats; + offset_refs_t m_refs; + svector m_found; + weight_map m_weight; public: + value_index(hilbert_basis& hb): hb(hb) {} - index(hilbert_basis& hb): hb(hb), m_weight(m_found, m_refs) {} - - ~index() { + ~value_index() { for (unsigned i = 0; i < m_values.size(); ++i) { dealloc(m_values[i]); } @@ -248,24 +235,81 @@ public: } SASSERT(m_values.size() == num_vars); } - + void insert(offset_t idx, values const& vs) { - ++m_stats.m_num_insert; -#if 0 for (unsigned i = 0; i < m_values.size(); ++i) { m_values[i]->insert(idx, vs[i]); } -#endif - m_weight.insert(idx, vs.value()); } void remove(offset_t idx, values const& vs) { -#if 0 for (unsigned i = 0; i < m_values.size(); ++i) { m_values[i]->remove(idx, vs[i]); } -#endif - m_weight.remove(idx, vs.value()); + } +}; + +class hilbert_basis::index { + // for each index, a heap of weights. + // for each weight a list of offsets + + struct stats { + unsigned m_num_comparisons; + unsigned m_num_find; + unsigned m_num_insert; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + + hilbert_basis& hb; + value_index m_values; + rational_map m_negative; + stats m_stats; + +public: + + index(hilbert_basis& hb): + hb(hb), + m_weight(m_found, m_refs), + m_values(hb) {} + + ~index() { + rational_map::iterator it = m_negative.begin(), end = m_negative.end(); + for (; it != end; ++it) { + dealloc(it->m_value); + } + } + + void init(unsigned num_vars) { + m_values.init(num_vars); + m_num_vars = num_vars; + SASSERT(m_negative.empty()); + } + + void insert(offset_t idx, values const& vs) { + ++m_stats.m_num_insert; + if (vs.value().is_neg()) { + weight_map* w = 0; + if (!m_negative.find(vs.value(), w)) { + w = alloc(weight_map, m_found, m_refs); + } + w->insert(idx, vs); + } + else { + m_weight.insert(idx, vs.value()); + m_values.insert(idx, vs); + } + } + + void remove(offset_t idx, values const& vs) { + if (vs.value().is_neg()) { + weight_map* w = m_negative.find(vs.value()); + w->remove(idx, vs); + } + else { + m_weight.remove(idx, vs.value()); + m_values.remove(idx, vs); + } } bool find(values const& vs, offset_t idx, offset_t& found_idx) { diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index f4529de85..4e3b76542 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -35,6 +35,7 @@ public: typedef vector num_vector; private: class rational_heap; + class value_index; class index; class passive; class weight_map; From a242ac46b6e88591c780cae3399acfc400a26124 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 15 Feb 2013 15:05:39 -0800 Subject: [PATCH 093/101] hilbert validation Signed-off-by: Nikolaj Bjorner --- src/muz_qe/hilbert_basis.cpp | 35 +++-- src/muz_qe/hilbert_basis.h | 27 ++-- src/muz_qe/hilbert_basis_validate.cpp | 178 ++++++++++++++++++++++++++ src/muz_qe/hilbert_basis_validate.h | 43 +++++++ src/test/hilbert_basis.cpp | 65 +++++++++- 5 files changed, 310 insertions(+), 38 deletions(-) create mode 100644 src/muz_qe/hilbert_basis_validate.cpp create mode 100644 src/muz_qe/hilbert_basis_validate.h diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index e89d7807b..bc31572ea 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -410,6 +410,7 @@ void hilbert_basis::collect_statistics(statistics& st) const { st.update("hb.num_subsumptions", m_stats.m_num_subsumptions); st.update("hb.num_resolves", m_stats.m_num_resolves); st.update("hb.num_saturations", m_stats.m_num_saturations); + st.update("hb.basis_size", get_basis_size()); m_index->collect_statistics(st); } @@ -464,6 +465,10 @@ void hilbert_basis::set_is_int(unsigned var_index) { m_ints.push_back(var_index+1); } +bool hilbert_basis::get_is_int(unsigned var_index) const { + return m_ints.contains(var_index+1); +} + unsigned hilbert_basis::get_num_vars() const { if (m_ineqs.empty()) { return 0; @@ -579,6 +584,23 @@ lbool hilbert_basis::saturate(num_vector const& ineq, bool is_eq) { return l_true; } +void hilbert_basis::get_basis_solution(unsigned i, num_vector& v, bool& is_initial) { + offset_t offs = m_basis[i]; + v.reset(); + for (unsigned i = 1; i < get_num_vars(); ++i) { + v.push_back(vec(offs)[i]); + } + is_initial = !vec(offs)[0].is_zero(); +} + +void hilbert_basis::get_ge(unsigned i, num_vector& v, numeral& b, bool& is_eq) { + v.reset(); + v.append(get_num_vars()-1, m_ineqs[i].c_ptr() + 1); + b = -m_ineqs[i][0]; + is_eq = m_iseq[i]; +} + + void hilbert_basis::select_inequality() { SASSERT(m_current_ineq < m_ineqs.size()); unsigned best = m_current_ineq; @@ -806,19 +828,6 @@ void hilbert_basis::display_ineq(std::ostream& out, num_vector const& v, bool is } -void hilbert_isl_basis::add_le(num_vector const& v, numeral bound) { - unsigned sz = v.size(); - num_vector w; - w.push_back(-bound); - w.push_back(bound); - for (unsigned i = 0; i < sz; ++i) { - w.push_back(v[i]); - w.push_back(-v[i]); - } - m_basis.add_le(w); -} - - /** Vector v is subsumed by vector w if diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index be136fbf9..00b854271 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -11,8 +11,6 @@ Abstract: hilbert_basis computes a Hilbert basis for linear homogeneous inequalities over naturals. - hilbert_sl_basis computes a semi-linear set over naturals. - hilbert_isl_basis computes semi-linear sets over integers. Author: @@ -140,33 +138,24 @@ public: void add_eq(num_vector const& v, numeral const& b); void set_is_int(unsigned var_index); + bool get_is_int(unsigned var_index) const; lbool saturate(); + unsigned get_basis_size() const { return m_basis.size(); } + void get_basis_solution(unsigned i, num_vector& v, bool& is_initial); + + unsigned get_num_ineqs() const { return m_ineqs.size(); } + void get_ge(unsigned i, num_vector& v, numeral& b, bool& is_eq); + void set_cancel(bool f) { m_cancel = f; } void display(std::ostream& out) const; void collect_statistics(statistics& st) const; void reset_statistics(); + }; -class hilbert_isl_basis { -public: - typedef rational numeral; - typedef vector num_vector; -private: - hilbert_basis m_basis; -public: - hilbert_isl_basis() {} - void reset() { m_basis.reset(); } - - // add inequality v*x >= bound, x ranges over integers - void add_le(num_vector const& v, numeral bound); - lbool saturate() { return m_basis.saturate(); } - void set_cancel(bool f) { m_basis.set_cancel(f); } - void display(std::ostream& out) const { m_basis.display(out); } -}; - #endif diff --git a/src/muz_qe/hilbert_basis_validate.cpp b/src/muz_qe/hilbert_basis_validate.cpp new file mode 100644 index 000000000..df65146f1 --- /dev/null +++ b/src/muz_qe/hilbert_basis_validate.cpp @@ -0,0 +1,178 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + hilbert_basis_validate.cpp + +Abstract: + + Basic Hilbert Basis validation. + + hilbert_basis computes a Hilbert basis for linear + homogeneous inequalities over naturals. + +Author: + + Nikolaj Bjorner (nbjorner) 2013-02-15. + +Revision History: + +--*/ + +#include "hilbert_basis_validate.h" +#include "arith_decl_plugin.h" +#include "ast_pp.h" +#include + + +hilbert_basis_validate::hilbert_basis_validate(ast_manager& m): + m(m) { +} + +void hilbert_basis_validate::validate_solution(hilbert_basis& hb, vector const& v, bool is_initial) { + unsigned sz = hb.get_num_ineqs(); + rational bound; + for (unsigned i = 0; i < sz; ++i) { + bool is_eq; + vector w; + hb.get_ge(i, w, bound, is_eq); + rational sum(0); + for (unsigned j = 0; j < v.size(); ++j) { + sum += w[j]*v[j]; + } + if (bound > sum || + (is_eq && bound != sum)) { + // validation failed. + std::cout << "validation failed for inequality\n"; + for (unsigned j = 0; j < v.size(); ++j) { + std::cout << v[j] << " "; + } + std::cout << "\n"; + for (unsigned j = 0; j < w.size(); ++j) { + std::cout << w[j] << " "; + } + std::cout << (is_eq?" = ":" >= ") << bound << "\n"; + std::cout << "is initial: " << (is_initial?"true":"false") << "\n"; + std::cout << "sum: " << sum << "\n"; + } + } +} + +expr_ref hilbert_basis_validate::mk_validate(hilbert_basis& hb) { + arith_util a(m); + unsigned sz = hb.get_basis_size(); + vector v; + bool is_initial; + + // check that claimed solution really satisfies inequalities: + for (unsigned i = 0; i < sz; ++i) { + hb.get_basis_solution(i, v, is_initial); + validate_solution(hb, v, is_initial); + } + + // check that solutions satisfying inequalities are in solution. + // build a formula that says solutions to linear inequalities + // coincide with linear combinations of basis. + vector offsets, increments; + expr_ref_vector xs(m), vars(m); + expr_ref var(m); + svector names; + sort_ref_vector sorts(m); + +#define mk_mul(_r,_x) (_r.is_one()?((expr*)_x):((expr*)a.mk_mul(a.mk_numeral(_r,true),_x))) + + + for (unsigned i = 0; i < sz; ++i) { + hb.get_basis_solution(i, v, is_initial); + + for (unsigned j = 0; xs.size() < v.size(); ++j) { + xs.push_back(m.mk_fresh_const("x", a.mk_int())); + } + + if (is_initial) { + expr_ref_vector tmp(m); + for (unsigned j = 0; j < v.size(); ++j) { + tmp.push_back(a.mk_numeral(v[j], true)); + } + offsets.push_back(tmp); + } + else { + var = m.mk_var(vars.size(), a.mk_int()); + expr_ref_vector tmp(m); + for (unsigned j = 0; j < v.size(); ++j) { + tmp.push_back(mk_mul(v[j], var)); + } + std::stringstream name; + name << "u" << i; + increments.push_back(tmp); + vars.push_back(var); + names.push_back(symbol(name.str().c_str())); + sorts.push_back(a.mk_int()); + } + } + + expr_ref_vector bounds(m); + for (unsigned i = 0; i < vars.size(); ++i) { + bounds.push_back(a.mk_ge(vars[i].get(), a.mk_numeral(rational(0), true))); + } + expr_ref_vector fmls(m); + expr_ref fml(m), fml1(m), fml2(m); + for (unsigned i = 0; i < offsets.size(); ++i) { + expr_ref_vector eqs(m); + eqs.append(bounds); + for (unsigned j = 0; j < xs.size(); ++j) { + expr_ref_vector sum(m); + sum.push_back(offsets[i][j].get()); + for (unsigned k = 0; k < increments.size(); ++k) { + sum.push_back(increments[k][j].get()); + } + eqs.push_back(m.mk_eq(xs[j].get(), a.mk_add(sum.size(), sum.c_ptr()))); + } + fml = m.mk_and(eqs.size(), eqs.c_ptr()); + if (!names.empty()) { + fml = m.mk_exists(names.size(), sorts.c_ptr(), names.c_ptr(), fml); + } + fmls.push_back(fml); + } + fml1 = m.mk_or(fmls.size(), fmls.c_ptr()); + fmls.reset(); + + sz = hb.get_num_ineqs(); + for (unsigned i = 0; i < sz; ++i) { + bool is_eq; + vector w; + rational bound; + hb.get_ge(i, w, bound, is_eq); + expr_ref_vector sum(m); + for (unsigned j = 0; j < w.size(); ++j) { + if (!w[j].is_zero()) { + sum.push_back(mk_mul(w[j], xs[j].get())); + } + } + expr_ref lhs(m), rhs(m); + lhs = a.mk_add(sum.size(), sum.c_ptr()); + rhs = a.mk_numeral(bound, true); + if (is_eq) { + fmls.push_back(a.mk_eq(lhs, rhs)); + } + else { + fmls.push_back(a.mk_ge(lhs, rhs)); + } + } + fml2 = m.mk_and(fmls.size(), fmls.c_ptr()); + fml = m.mk_eq(fml1, fml2); + + bounds.reset(); + for (unsigned i = 0; i < xs.size(); ++i) { + if (!hb.get_is_int(i)) { + bounds.push_back(a.mk_ge(xs[i].get(), a.mk_numeral(rational(0), true))); + } + } + if (!bounds.empty()) { + fml = m.mk_implies(m.mk_and(bounds.size(), bounds.c_ptr()), fml); + } + return fml; + +} + diff --git a/src/muz_qe/hilbert_basis_validate.h b/src/muz_qe/hilbert_basis_validate.h new file mode 100644 index 000000000..defa5805c --- /dev/null +++ b/src/muz_qe/hilbert_basis_validate.h @@ -0,0 +1,43 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + hilbert_basis_validate.h + +Abstract: + + Basic Hilbert Basis validation. + + hilbert_basis computes a Hilbert basis for linear + homogeneous inequalities over naturals. + +Author: + + Nikolaj Bjorner (nbjorner) 2013-02-15. + +Revision History: + +--*/ + +#ifndef _HILBERT_BASIS_VALIDATE_H_ +#define _HILBERT_BASIS_VALIDATE_H_ + +#include "hilbert_basis.h" +#include "ast.h" + +class hilbert_basis_validate { + ast_manager& m; + + void validate_solution(hilbert_basis& hb, vector const& v, bool is_initial); + +public: + + hilbert_basis_validate(ast_manager& m); + + expr_ref mk_validate(hilbert_basis& hb); + +}; + + +#endif diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index 4d401c4c2..11faad819 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -1,4 +1,12 @@ #include "hilbert_basis.h" +#include "hilbert_basis_validate.h" +#include "ast_pp.h" +#include "reg_decl_plugins.h" +#include "quant_tactics.h" +#include "tactic.h" +#include "tactic2solver.h" +#include "solver.h" + #include #include @@ -19,6 +27,24 @@ static void on_ctrl_c(int) { raise(SIGINT); } +static void validate_sat(hilbert_basis& hb) { + ast_manager m; + reg_decl_plugins(m); + hilbert_basis_validate val(m); + + expr_ref fml = val.mk_validate(hb); + + std::cout << mk_pp(fml, m) << "\n"; + + fml = m.mk_not(fml); + params_ref p; + tactic_ref tac = mk_lra_tactic(m, p); + ref sol = mk_tactic2solver(m, tac.get(), p); + sol->assert_expr(fml); + lbool r = sol->check_sat(0,0); + std::cout << r << "\n"; +} + static void saturate_basis(hilbert_basis& hb) { signal(SIGINT, on_ctrl_c); g_hb = &hb; @@ -29,6 +55,7 @@ static void saturate_basis(hilbert_basis& hb) { case l_true: std::cout << "sat\n"; hb.display(std::cout); + // validate_sat(hb); break; case l_false: std::cout << "unsat\n"; @@ -40,6 +67,7 @@ static void saturate_basis(hilbert_basis& hb) { display_statistics(hb); } + /** n - number of variables. k - subset of variables to be non-zero @@ -258,16 +286,37 @@ static void tst12() { saturate_basis(hb); } +// Sigma_9 table 1, Ajili, Contejean +static void tst13() { + hilbert_basis hb; + hb.add_eq(vec( 1,-2,-4,4), R(0)); + hb.add_le(vec(100,45,-78,-67), R(0)); + saturate_basis(hb); +} + +// Sigma_10 table 1, Ajili, Contejean +static void tst14() { + hilbert_basis hb; + hb.add_le(vec( 23, -56, -34, 12, 11), R(0)); + saturate_basis(hb); +} + +// Sigma_11 table 1, Ajili, Contejean +static void tst15() { +// hilbert_basis hb; +// hb.add_le(vec( 23, -56, -34, 12, 11), R(0)); +// saturate_basis(hb); +} + + void tst_hilbert_basis() { std::cout << "hilbert basis test\n"; - tst12(); - return; if (true) { tst1(); tst2(); tst3(); - tst4(); + // tst4(); tst5(); tst6(); tst7(); @@ -275,11 +324,15 @@ void tst_hilbert_basis() { tst9(); tst10(); tst11(); + tst12(); + tst13(); + tst14(); + tst15(); gorrila_test(0, 4, 3, 20, 5); gorrila_test(1, 4, 3, 20, 5); - gorrila_test(2, 4, 3, 20, 5); - gorrila_test(0, 4, 2, 20, 5); - gorrila_test(0, 4, 2, 20, 5); + //gorrila_test(2, 4, 3, 20, 5); + //gorrila_test(0, 4, 2, 20, 5); + //gorrila_test(0, 4, 2, 20, 5); } else { gorrila_test(0, 10, 7, 20, 11); From 943e142bfacdba4fafaaeb21c5a5861f8d8fbfd0 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 15 Feb 2013 16:27:55 -0800 Subject: [PATCH 094/101] Fix bug in ast_smt_pp.cpp. After user_sort_plugin was introduced, it is not that case that if a sort is uninterpreted, then sort->get_family_id() == null_family_id. Signed-off-by: Leonardo de Moura --- src/ast/ast_smt_pp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 5bdc70dc2..5819e3930 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -869,7 +869,7 @@ public: for (unsigned j = 0; j < f->get_arity(); ++j) { sort* s2 = f->get_domain(j); if (!mark.is_marked(s2)) { - if (s2->get_family_id() == null_family_id) { + if (m_manager.is_uninterp(s2)) { pp_sort_decl(mark, s2); } else if (!util.is_datatype(s2)) { From 0af4384882adfe52818a1064f41812823aa813de Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 15 Feb 2013 16:31:42 -0800 Subject: [PATCH 095/101] Fix more issues unintepreted sort tests. Signed-off-by: Leonardo de Moura --- src/ast/static_features.cpp | 45 +++++++++++++---------- src/smt/proto_model/proto_model.cpp | 57 ++++++++++++++++------------- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/ast/static_features.cpp b/src/ast/static_features.cpp index f40eb2c75..cba31665c 100644 --- a/src/ast/static_features.cpp +++ b/src/ast/static_features.cpp @@ -165,7 +165,8 @@ void static_features::update_core(expr * e) { // even if a benchmark does not contain any theory interpreted function decls, we still have to install // the theory if the benchmark contains constants or function applications of an interpreted sort. sort * s = m_manager.get_sort(e); - mark_theory(s->get_family_id()); + if (!m_manager.is_uninterp(s)) + mark_theory(s->get_family_id()); bool _is_gate = is_gate(e); bool _is_eq = m_manager.is_eq(e); @@ -255,9 +256,11 @@ void static_features::update_core(expr * e) { m_num_simple_eqs++; } sort * s = m_manager.get_sort(to_app(e)->get_arg(0)); - family_id fid = s->get_family_id(); - if (fid != null_family_id && fid != m_bfid) - inc_theory_eqs(fid); + if (!m_manager.is_uninterp(s)) { + family_id fid = s->get_family_id(); + if (fid != null_family_id && fid != m_bfid) + inc_theory_eqs(fid); + } } if (!m_has_int && m_autil.is_int(e)) m_has_int = true; @@ -295,9 +298,11 @@ void static_features::update_core(expr * e) { if (to_app(e)->get_num_args() == 0) { m_num_uninterpreted_constants++; sort * s = m_manager.get_sort(e); - family_id fid = s->get_family_id(); - if (fid != null_family_id && fid != m_bfid) - inc_theory_constants(fid); + if (!m_manager.is_uninterp(s)) { + family_id fid = s->get_family_id(); + if (fid != null_family_id && fid != m_bfid) + inc_theory_constants(fid); + } } } func_decl * d = to_app(e)->get_decl(); @@ -312,18 +317,20 @@ void static_features::update_core(expr * e) { for (unsigned i = 0; i < num_args; i++) { expr * arg = to_app(e)->get_arg(i); sort * arg_s = m_manager.get_sort(arg); - family_id fid_arg = arg_s->get_family_id(); - if (fid_arg != fid && fid_arg != null_family_id) { - m_num_aliens++; - inc_num_aliens(fid_arg); - if (fid_arg == m_afid) { - SASSERT(!_is_le_ge); - m_num_arith_terms++; - rational k; - TRACE("diff_term", tout << "diff_term: " << is_diff_term(arg, k) << "\n" << mk_pp(arg, m_manager) << "\n";); - if (is_diff_term(arg, k)) { - m_num_diff_terms++; - acc_num(k); + if (!m_manager.is_uninterp(arg_s)) { + family_id fid_arg = arg_s->get_family_id(); + if (fid_arg != fid && fid_arg != null_family_id) { + m_num_aliens++; + inc_num_aliens(fid_arg); + if (fid_arg == m_afid) { + SASSERT(!_is_le_ge); + m_num_arith_terms++; + rational k; + TRACE("diff_term", tout << "diff_term: " << is_diff_term(arg, k) << "\n" << mk_pp(arg, m_manager) << "\n";); + if (is_diff_term(arg, k)) { + m_num_diff_terms++; + acc_num(k); + } } } } diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index d7a06f14f..70287728e 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -526,49 +526,56 @@ bool proto_model::is_finite(sort * s) const { } expr * proto_model::get_some_value(sort * s) { - family_id fid = s->get_family_id(); - if (fid == null_family_id) { + if (m_manager.is_uninterp(s)) { + return m_user_sort_factory->get_some_value(s); + } + else { + family_id fid = s->get_family_id(); + value_factory * f = get_factory(fid); + if (f) + return f->get_some_value(s); + // there is no factory for the family id, then assume s is uninterpreted. return m_user_sort_factory->get_some_value(s); } - value_factory * f = get_factory(fid); - if (f) - return f->get_some_value(s); - // there is no factory for the family id, then assume s is uninterpreted. - return m_user_sort_factory->get_some_value(s); } bool proto_model::get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { - family_id fid = s->get_family_id(); - if (fid == null_family_id) { + if (m_manager.is_uninterp(s)) { return m_user_sort_factory->get_some_values(s, v1, v2); } - value_factory * f = get_factory(fid); - if (f) - return f->get_some_values(s, v1, v2); - else - return false; + else { + family_id fid = s->get_family_id(); + value_factory * f = get_factory(fid); + if (f) + return f->get_some_values(s, v1, v2); + else + return false; + } } expr * proto_model::get_fresh_value(sort * s) { - family_id fid = s->get_family_id(); - if (fid == null_family_id) - return m_user_sort_factory->get_fresh_value(s); - value_factory * f = get_factory(fid); - if (f) - return f->get_fresh_value(s); - else - // Use user_sort_factory if the theory has no support for model construnction. - // This is needed when dummy theories are used for arithmetic or arrays. + if (m_manager.is_uninterp(s)) { return m_user_sort_factory->get_fresh_value(s); + } + else { + family_id fid = s->get_family_id(); + value_factory * f = get_factory(fid); + if (f) + return f->get_fresh_value(s); + else + // Use user_sort_factory if the theory has no support for model construnction. + // This is needed when dummy theories are used for arithmetic or arrays. + return m_user_sort_factory->get_fresh_value(s); + } } void proto_model::register_value(expr * n) { sort * s = m_manager.get_sort(n); - family_id fid = s->get_family_id(); - if (fid == null_family_id) { + if (m_manager.is_uninterp(s)) { m_user_sort_factory->register_value(n); } else { + family_id fid = s->get_family_id(); value_factory * f = get_factory(fid); if (f) f->register_value(n); From f46c7f9bd9937468a86c587f9116d782cd622f96 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 15 Feb 2013 16:36:57 -0800 Subject: [PATCH 096/101] Fix the build on g++, Fix g++ warnings Signed-off-by: Leonardo de Moura --- src/muz_qe/hilbert_basis.cpp | 5 ++--- src/muz_qe/hilbert_basis.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index bc31572ea..dd0041fa9 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -63,7 +63,7 @@ public: for (; it != end; ++it) { offset_t offs(*it); ++m_stats.m_num_comparisons; - if (*it != idx.m_offset && hb.is_subsumed(idx, offs)) { + if (*it != static_cast(idx.m_offset) && hb.is_subsumed(idx, offs)) { found_idx = offs; ++m_stats.m_num_hit; return true; @@ -743,7 +743,7 @@ hilbert_basis::sign_t hilbert_basis::get_sign(offset_t idx) const { return zero; } -hilbert_basis::numeral hilbert_basis::get_weight(values& val, num_vector const& ineq) const { +hilbert_basis::numeral hilbert_basis::get_weight(values const & val, num_vector const& ineq) const { numeral result(0); unsigned num_vars = get_num_vars(); for (unsigned i = 0; i < num_vars; ++i) { @@ -753,7 +753,6 @@ hilbert_basis::numeral hilbert_basis::get_weight(values& val, num_vector const& } void hilbert_basis::display(std::ostream& out) const { - unsigned nv = get_num_vars(); out << "inequalities:\n"; for (unsigned i = 0; i < m_ineqs.size(); ++i) { display_ineq(out, m_ineqs[i], m_iseq[i]); diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index 00b854271..8dd5e97cf 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -96,7 +96,7 @@ private: void add_unit_vector(unsigned i, numeral const& e); unsigned get_num_vars() const; - numeral get_weight(values& val, num_vector const& ineq) const; + numeral get_weight(values const & val, num_vector const& ineq) const; bool is_geq(values const& v, values const& w) const; bool is_abs_geq(numeral const& v, numeral const& w) const; bool is_subsumed(offset_t idx); From 47342e5d0c615de524b965721d423b6e855dc4bc Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 15 Feb 2013 17:46:22 -0800 Subject: [PATCH 097/101] move validation code to unit test Signed-off-by: Nikolaj Bjorner --- src/muz_qe/hilbert_basis_validate.cpp | 178 ----------------------- src/muz_qe/hilbert_basis_validate.h | 43 ------ src/test/hilbert_basis.cpp | 201 ++++++++++++++++++++++++-- 3 files changed, 185 insertions(+), 237 deletions(-) delete mode 100644 src/muz_qe/hilbert_basis_validate.cpp delete mode 100644 src/muz_qe/hilbert_basis_validate.h diff --git a/src/muz_qe/hilbert_basis_validate.cpp b/src/muz_qe/hilbert_basis_validate.cpp deleted file mode 100644 index df65146f1..000000000 --- a/src/muz_qe/hilbert_basis_validate.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/*++ -Copyright (c) 2013 Microsoft Corporation - -Module Name: - - hilbert_basis_validate.cpp - -Abstract: - - Basic Hilbert Basis validation. - - hilbert_basis computes a Hilbert basis for linear - homogeneous inequalities over naturals. - -Author: - - Nikolaj Bjorner (nbjorner) 2013-02-15. - -Revision History: - ---*/ - -#include "hilbert_basis_validate.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" -#include - - -hilbert_basis_validate::hilbert_basis_validate(ast_manager& m): - m(m) { -} - -void hilbert_basis_validate::validate_solution(hilbert_basis& hb, vector const& v, bool is_initial) { - unsigned sz = hb.get_num_ineqs(); - rational bound; - for (unsigned i = 0; i < sz; ++i) { - bool is_eq; - vector w; - hb.get_ge(i, w, bound, is_eq); - rational sum(0); - for (unsigned j = 0; j < v.size(); ++j) { - sum += w[j]*v[j]; - } - if (bound > sum || - (is_eq && bound != sum)) { - // validation failed. - std::cout << "validation failed for inequality\n"; - for (unsigned j = 0; j < v.size(); ++j) { - std::cout << v[j] << " "; - } - std::cout << "\n"; - for (unsigned j = 0; j < w.size(); ++j) { - std::cout << w[j] << " "; - } - std::cout << (is_eq?" = ":" >= ") << bound << "\n"; - std::cout << "is initial: " << (is_initial?"true":"false") << "\n"; - std::cout << "sum: " << sum << "\n"; - } - } -} - -expr_ref hilbert_basis_validate::mk_validate(hilbert_basis& hb) { - arith_util a(m); - unsigned sz = hb.get_basis_size(); - vector v; - bool is_initial; - - // check that claimed solution really satisfies inequalities: - for (unsigned i = 0; i < sz; ++i) { - hb.get_basis_solution(i, v, is_initial); - validate_solution(hb, v, is_initial); - } - - // check that solutions satisfying inequalities are in solution. - // build a formula that says solutions to linear inequalities - // coincide with linear combinations of basis. - vector offsets, increments; - expr_ref_vector xs(m), vars(m); - expr_ref var(m); - svector names; - sort_ref_vector sorts(m); - -#define mk_mul(_r,_x) (_r.is_one()?((expr*)_x):((expr*)a.mk_mul(a.mk_numeral(_r,true),_x))) - - - for (unsigned i = 0; i < sz; ++i) { - hb.get_basis_solution(i, v, is_initial); - - for (unsigned j = 0; xs.size() < v.size(); ++j) { - xs.push_back(m.mk_fresh_const("x", a.mk_int())); - } - - if (is_initial) { - expr_ref_vector tmp(m); - for (unsigned j = 0; j < v.size(); ++j) { - tmp.push_back(a.mk_numeral(v[j], true)); - } - offsets.push_back(tmp); - } - else { - var = m.mk_var(vars.size(), a.mk_int()); - expr_ref_vector tmp(m); - for (unsigned j = 0; j < v.size(); ++j) { - tmp.push_back(mk_mul(v[j], var)); - } - std::stringstream name; - name << "u" << i; - increments.push_back(tmp); - vars.push_back(var); - names.push_back(symbol(name.str().c_str())); - sorts.push_back(a.mk_int()); - } - } - - expr_ref_vector bounds(m); - for (unsigned i = 0; i < vars.size(); ++i) { - bounds.push_back(a.mk_ge(vars[i].get(), a.mk_numeral(rational(0), true))); - } - expr_ref_vector fmls(m); - expr_ref fml(m), fml1(m), fml2(m); - for (unsigned i = 0; i < offsets.size(); ++i) { - expr_ref_vector eqs(m); - eqs.append(bounds); - for (unsigned j = 0; j < xs.size(); ++j) { - expr_ref_vector sum(m); - sum.push_back(offsets[i][j].get()); - for (unsigned k = 0; k < increments.size(); ++k) { - sum.push_back(increments[k][j].get()); - } - eqs.push_back(m.mk_eq(xs[j].get(), a.mk_add(sum.size(), sum.c_ptr()))); - } - fml = m.mk_and(eqs.size(), eqs.c_ptr()); - if (!names.empty()) { - fml = m.mk_exists(names.size(), sorts.c_ptr(), names.c_ptr(), fml); - } - fmls.push_back(fml); - } - fml1 = m.mk_or(fmls.size(), fmls.c_ptr()); - fmls.reset(); - - sz = hb.get_num_ineqs(); - for (unsigned i = 0; i < sz; ++i) { - bool is_eq; - vector w; - rational bound; - hb.get_ge(i, w, bound, is_eq); - expr_ref_vector sum(m); - for (unsigned j = 0; j < w.size(); ++j) { - if (!w[j].is_zero()) { - sum.push_back(mk_mul(w[j], xs[j].get())); - } - } - expr_ref lhs(m), rhs(m); - lhs = a.mk_add(sum.size(), sum.c_ptr()); - rhs = a.mk_numeral(bound, true); - if (is_eq) { - fmls.push_back(a.mk_eq(lhs, rhs)); - } - else { - fmls.push_back(a.mk_ge(lhs, rhs)); - } - } - fml2 = m.mk_and(fmls.size(), fmls.c_ptr()); - fml = m.mk_eq(fml1, fml2); - - bounds.reset(); - for (unsigned i = 0; i < xs.size(); ++i) { - if (!hb.get_is_int(i)) { - bounds.push_back(a.mk_ge(xs[i].get(), a.mk_numeral(rational(0), true))); - } - } - if (!bounds.empty()) { - fml = m.mk_implies(m.mk_and(bounds.size(), bounds.c_ptr()), fml); - } - return fml; - -} - diff --git a/src/muz_qe/hilbert_basis_validate.h b/src/muz_qe/hilbert_basis_validate.h deleted file mode 100644 index defa5805c..000000000 --- a/src/muz_qe/hilbert_basis_validate.h +++ /dev/null @@ -1,43 +0,0 @@ -/*++ -Copyright (c) 2013 Microsoft Corporation - -Module Name: - - hilbert_basis_validate.h - -Abstract: - - Basic Hilbert Basis validation. - - hilbert_basis computes a Hilbert basis for linear - homogeneous inequalities over naturals. - -Author: - - Nikolaj Bjorner (nbjorner) 2013-02-15. - -Revision History: - ---*/ - -#ifndef _HILBERT_BASIS_VALIDATE_H_ -#define _HILBERT_BASIS_VALIDATE_H_ - -#include "hilbert_basis.h" -#include "ast.h" - -class hilbert_basis_validate { - ast_manager& m; - - void validate_solution(hilbert_basis& hb, vector const& v, bool is_initial); - -public: - - hilbert_basis_validate(ast_manager& m); - - expr_ref mk_validate(hilbert_basis& hb); - -}; - - -#endif diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index 11faad819..7cf4d863b 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -1,14 +1,180 @@ #include "hilbert_basis.h" -#include "hilbert_basis_validate.h" #include "ast_pp.h" #include "reg_decl_plugins.h" +#include "arith_decl_plugin.h" #include "quant_tactics.h" #include "tactic.h" #include "tactic2solver.h" #include "solver.h" +#include +#include +#include + + +class hilbert_basis_validate { + ast_manager& m; + + void validate_solution(hilbert_basis& hb, vector const& v, bool is_initial); + +public: + + hilbert_basis_validate(ast_manager& m); + + expr_ref mk_validate(hilbert_basis& hb); + +}; + + +hilbert_basis_validate::hilbert_basis_validate(ast_manager& m): + m(m) { +} + +void hilbert_basis_validate::validate_solution(hilbert_basis& hb, vector const& v, bool is_initial) { + unsigned sz = hb.get_num_ineqs(); + rational bound; + for (unsigned i = 0; i < sz; ++i) { + bool is_eq; + vector w; + hb.get_ge(i, w, bound, is_eq); + rational sum(0); + for (unsigned j = 0; j < v.size(); ++j) { + sum += w[j]*v[j]; + } + if (bound > sum || + (is_eq && bound != sum)) { + // validation failed. + std::cout << "validation failed for inequality\n"; + for (unsigned j = 0; j < v.size(); ++j) { + std::cout << v[j] << " "; + } + std::cout << "\n"; + for (unsigned j = 0; j < w.size(); ++j) { + std::cout << w[j] << " "; + } + std::cout << (is_eq?" = ":" >= ") << bound << "\n"; + std::cout << "is initial: " << (is_initial?"true":"false") << "\n"; + std::cout << "sum: " << sum << "\n"; + } + } +} + +expr_ref hilbert_basis_validate::mk_validate(hilbert_basis& hb) { + arith_util a(m); + unsigned sz = hb.get_basis_size(); + vector v; + bool is_initial; + + // check that claimed solution really satisfies inequalities: + for (unsigned i = 0; i < sz; ++i) { + hb.get_basis_solution(i, v, is_initial); + validate_solution(hb, v, is_initial); + } + + // check that solutions satisfying inequalities are in solution. + // build a formula that says solutions to linear inequalities + // coincide with linear combinations of basis. + vector offsets, increments; + expr_ref_vector xs(m), vars(m); + expr_ref var(m); + svector names; + sort_ref_vector sorts(m); + +#define mk_mul(_r,_x) (_r.is_one()?((expr*)_x):((expr*)a.mk_mul(a.mk_numeral(_r,true),_x))) + + + for (unsigned i = 0; i < sz; ++i) { + hb.get_basis_solution(i, v, is_initial); + + for (unsigned j = 0; xs.size() < v.size(); ++j) { + xs.push_back(m.mk_fresh_const("x", a.mk_int())); + } + + if (is_initial) { + expr_ref_vector tmp(m); + for (unsigned j = 0; j < v.size(); ++j) { + tmp.push_back(a.mk_numeral(v[j], true)); + } + offsets.push_back(tmp); + } + else { + var = m.mk_var(vars.size(), a.mk_int()); + expr_ref_vector tmp(m); + for (unsigned j = 0; j < v.size(); ++j) { + tmp.push_back(mk_mul(v[j], var)); + } + std::stringstream name; + name << "u" << i; + increments.push_back(tmp); + vars.push_back(var); + names.push_back(symbol(name.str().c_str())); + sorts.push_back(a.mk_int()); + } + } + + expr_ref_vector bounds(m); + for (unsigned i = 0; i < vars.size(); ++i) { + bounds.push_back(a.mk_ge(vars[i].get(), a.mk_numeral(rational(0), true))); + } + expr_ref_vector fmls(m); + expr_ref fml(m), fml1(m), fml2(m); + for (unsigned i = 0; i < offsets.size(); ++i) { + expr_ref_vector eqs(m); + eqs.append(bounds); + for (unsigned j = 0; j < xs.size(); ++j) { + expr_ref_vector sum(m); + sum.push_back(offsets[i][j].get()); + for (unsigned k = 0; k < increments.size(); ++k) { + sum.push_back(increments[k][j].get()); + } + eqs.push_back(m.mk_eq(xs[j].get(), a.mk_add(sum.size(), sum.c_ptr()))); + } + fml = m.mk_and(eqs.size(), eqs.c_ptr()); + if (!names.empty()) { + fml = m.mk_exists(names.size(), sorts.c_ptr(), names.c_ptr(), fml); + } + fmls.push_back(fml); + } + fml1 = m.mk_or(fmls.size(), fmls.c_ptr()); + fmls.reset(); + + sz = hb.get_num_ineqs(); + for (unsigned i = 0; i < sz; ++i) { + bool is_eq; + vector w; + rational bound; + hb.get_ge(i, w, bound, is_eq); + expr_ref_vector sum(m); + for (unsigned j = 0; j < w.size(); ++j) { + if (!w[j].is_zero()) { + sum.push_back(mk_mul(w[j], xs[j].get())); + } + } + expr_ref lhs(m), rhs(m); + lhs = a.mk_add(sum.size(), sum.c_ptr()); + rhs = a.mk_numeral(bound, true); + if (is_eq) { + fmls.push_back(a.mk_eq(lhs, rhs)); + } + else { + fmls.push_back(a.mk_ge(lhs, rhs)); + } + } + fml2 = m.mk_and(fmls.size(), fmls.c_ptr()); + fml = m.mk_eq(fml1, fml2); + + bounds.reset(); + for (unsigned i = 0; i < xs.size(); ++i) { + if (!hb.get_is_int(i)) { + bounds.push_back(a.mk_ge(xs[i].get(), a.mk_numeral(rational(0), true))); + } + } + if (!bounds.empty()) { + fml = m.mk_implies(m.mk_and(bounds.size(), bounds.c_ptr()), fml); + } + return fml; + +} -#include -#include hilbert_basis* g_hb = 0; static double g_start_time; @@ -236,6 +402,7 @@ static void tst6() { // Sigma_4 table 1, Ajili, Contejean static void tst7() { hilbert_basis hb; + hb.add_eq(vec( 1, 1, 1, 0), R(5)); hb.add_le(vec( 2, 1, 0, 1), R(6)); hb.add_le(vec( 1, 2, 1, 1), R(7)); hb.add_le(vec( 1, 3,-1, 2), R(8)); @@ -268,7 +435,7 @@ static void tst9() { static void tst10() { hilbert_basis hb; hb.add_le(vec( 1,-1,-1,-3), R(2)); - hb.add_le(vec(-2, 3, 3, 5), R(3)); + hb.add_le(vec(-2, 3, 3,-5), R(3)); saturate_basis(hb); } @@ -279,15 +446,8 @@ static void tst11() { saturate_basis(hb); } -static void tst12() { - hilbert_basis hb; - hb.add_le(vec(1, 0), R(1)); - hb.add_le(vec(0, 1), R(1)); - saturate_basis(hb); -} - // Sigma_9 table 1, Ajili, Contejean -static void tst13() { +static void tst12() { hilbert_basis hb; hb.add_eq(vec( 1,-2,-4,4), R(0)); hb.add_le(vec(100,45,-78,-67), R(0)); @@ -295,17 +455,25 @@ static void tst13() { } // Sigma_10 table 1, Ajili, Contejean -static void tst14() { +static void tst13() { hilbert_basis hb; hb.add_le(vec( 23, -56, -34, 12, 11), R(0)); saturate_basis(hb); } // Sigma_11 table 1, Ajili, Contejean +static void tst14() { + hilbert_basis hb; + hb.add_eq(vec(1, 0, -4, 8), R(2)); + hb.add_le(vec(12,19,-11,7), R(-7)); + saturate_basis(hb); +} + static void tst15() { -// hilbert_basis hb; -// hb.add_le(vec( 23, -56, -34, 12, 11), R(0)); -// saturate_basis(hb); + hilbert_basis hb; + hb.add_le(vec(1, 0), R(1)); + hb.add_le(vec(0, 1), R(1)); + saturate_basis(hb); } @@ -336,5 +504,6 @@ void tst_hilbert_basis() { } else { gorrila_test(0, 10, 7, 20, 11); + tst4(); } } From 306855ba55dc901d6e3f5137f5d4447a3cd21f47 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 16 Feb 2013 22:45:37 -0800 Subject: [PATCH 098/101] fix hilbert_basis tests and add heap_trie index Signed-off-by: Nikolaj Bjorner --- src/muz_qe/heap_trie.h | 355 +++++++++++++++++++++++++++++++++++ src/muz_qe/hilbert_basis.cpp | 175 +++++++++++------ src/muz_qe/hilbert_basis.h | 4 +- src/test/heap_trie.cpp | 52 +++++ src/test/hilbert_basis.cpp | 66 +++++-- src/test/main.cpp | 1 + 6 files changed, 579 insertions(+), 74 deletions(-) create mode 100644 src/muz_qe/heap_trie.h create mode 100644 src/test/heap_trie.cpp diff --git a/src/muz_qe/heap_trie.h b/src/muz_qe/heap_trie.h new file mode 100644 index 000000000..04b7f08d2 --- /dev/null +++ b/src/muz_qe/heap_trie.h @@ -0,0 +1,355 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + heap_trie.h + +Abstract: + + Heap trie structure. + + Structure that lets you retrieve point-wise smaller entries + of a tuple. A lookup is to identify entries whose keys + are point-wise dominated by the lookup key. + +Author: + + Nikolaj Bjorner (nbjorner) 2013-02-15. + +Notes: + + tries are unordered vectors of keys. This could be enhanced to use either + heaps or sorting. The problem with using the heap implementation directly is that there is no way to + retrieve elements less or equal to a key that is not already in the heap. + If nodes have only a few elements, then this would also be a bloated data-structure to maintain. + + Nodes are not de-allocated. Their reference count indicates if they are valid. + Possibly, add garbage collection. + + Maintaining sorted ranges for larger domains is another option. + +--*/ + +#ifndef _HEAP_TRIE_H_ +#define _HEAP_TRIE_H_ + +#include "map.h" +#include "vector.h" +#include "statistics.h" + + +template +class heap_trie { + + struct stats { + unsigned m_num_inserts; + unsigned m_num_removes; + unsigned m_num_find_eq; + unsigned m_num_find_le; + unsigned m_num_find_le_nodes; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + + enum node_t { + trie_t, + leaf_t + }; + + class node { + node_t m_type; + unsigned m_ref; + public: + node(node_t t): m_type(t), m_ref(0) {} + virtual ~node() {} + node_t type() const { return m_type; } + void inc_ref() { ++m_ref; } + void dec_ref() { SASSERT(m_ref > 0); --m_ref; } + unsigned ref_count() const { return m_ref; } + virtual void display(std::ostream& out, unsigned indent) const = 0; + virtual unsigned size() const = 0; + }; + + class leaf : public node { + Value m_value; + public: + leaf(): node(leaf_t) {} + virtual ~leaf() {} + Value const& get_value() const { return m_value; } + void set_value(Value const& v) { m_value = v; } + virtual void display(std::ostream& out, unsigned indent) const { + out << " value: " << m_value; + } + virtual unsigned size() const { return 1; } + }; + + // lean trie node + class trie : public node { + vector > m_nodes; + public: + trie(): node(trie_t) {} + + virtual ~trie() { + for (unsigned i = 0; i < m_nodes.size(); ++i) { + dealloc(m_nodes[i].second); + } + } + + node* find_or_insert(Key k, node* n) { + for (unsigned i = 0; i < m_nodes.size(); ++i) { + if (m_nodes[i].first == k) { + return m_nodes[i].second; + } + } + m_nodes.push_back(std::make_pair(k, n)); + return n; + } + + bool find(Key k, node*& n) const { + for (unsigned i = 0; i < m_nodes.size(); ++i) { + if (m_nodes[i].first == k) { + n = m_nodes[i].second; + return n->ref_count() > 0; + } + } + return false; + } + + // push nodes whose keys are <= key into vector. + void find_le(Key key, ptr_vector& nodes) { + for (unsigned i = 0; i < m_nodes.size(); ++i) { + if (m_nodes[i].first <= key) { + node* n = m_nodes[i].second; + if (n->ref_count() > 0){ + nodes.push_back(n); + } + } + } + } + + virtual void display(std::ostream& out, unsigned indent) const { + for (unsigned j = 0; j < m_nodes.size(); ++j) { + out << "\n"; + for (unsigned i = 0; i < indent; ++i) { + out << " "; + } + node* n = m_nodes[j].second; + out << m_nodes[j].first << " count: " << n->ref_count(); + n->display(out, indent + 1); + } + } + + virtual unsigned size() const { + unsigned sz = 1; + for (unsigned j = 0; j < m_nodes.size(); ++j) { + sz += m_nodes[j].second->size(); + } + return sz; + } + + private: + bool contains(Key k) { + for (unsigned j = 0; j < m_nodes.size(); ++j) { + if (m_nodes[j].first == k) { + return true; + } + } + return false; + } + + }; + + unsigned m_num_keys; + node* m_root; + stats m_stats; + node* m_spare_leaf; + node* m_spare_trie; + vector > m_children; +public: + + heap_trie(): + m_num_keys(0), + m_root(0), + m_spare_leaf(0), + m_spare_trie(0) + {} + + ~heap_trie() { + dealloc(m_root); + dealloc(m_spare_leaf); + dealloc(m_spare_trie); + } + + unsigned size() const { + return m_root->size(); + } + + void reset(unsigned num_keys) { + dealloc(m_root); + dealloc(m_spare_leaf); + dealloc(m_spare_trie); + m_num_keys = num_keys; + m_root = mk_trie(); + m_spare_trie = mk_trie(); + m_spare_leaf = mk_leaf(); + } + + void insert(Key const* keys, Value const& val) { + ++m_stats.m_num_inserts; + insert(m_root, num_keys(), keys, val); + } + + bool find_eq(Key const* keys, Value& value) { + ++m_stats.m_num_find_eq; + node* n = m_root; + node* m; + for (unsigned i = 0; i < num_keys(); ++i) { + if (!to_trie(n)->find(keys[i], m)) { + return false; + } + n = m; + } + value = to_leaf(n)->get_value(); + return true; + } + + void find_le(Key const* keys, vector& values) { + ++m_stats.m_num_find_le; + ptr_vector todo[2]; + todo[0].push_back(m_root); + bool index = false; + for (unsigned i = 0; i < num_keys(); ++i) { + for (unsigned j = 0; j < todo[index].size(); ++j) { + ++m_stats.m_num_find_le_nodes; + to_trie(todo[index][j])->find_le(keys[i], todo[!index]); + } + todo[index].reset(); + index = !index; + } + for (unsigned j = 0; j < todo[index].size(); ++j) { + values.push_back(to_leaf(todo[index][j])->get_value()); + } + } + + + // callback based find function + class check_value { + public: + virtual bool operator()(Value const& v) = 0; + }; + + bool find_le(Key const* keys, check_value& check) { + ++m_stats.m_num_find_le; + if (m_children.size() < num_keys()) { + m_children.resize(num_keys()); + } + return find_le(m_root, 0, keys, check); + } + + bool find_le(node* n, unsigned index, Key const* keys, check_value& check) { + ++m_stats.m_num_find_le_nodes; + if (index == num_keys()) { + SASSERT(n->ref_count() > 0); + return check(to_leaf(n)->get_value()); + } + else { + m_children[index].reset(); + to_trie(n)->find_le(keys[index], m_children[index]); + for (unsigned i = 0; i < m_children[index].size(); ++i) { + if (find_le(m_children[index][i], index + 1, keys, check)) { + return true; + } + } + return false; + } + } + + void remove(Key const* keys) { + ++m_stats.m_num_removes; + // assumption: key is in table. + node* n = m_root; + node* m; + for (unsigned i = 0; i < num_keys(); ++i) { + n->dec_ref(); + VERIFY (to_trie(n)->find(keys[i], m)); + n = m; + } + n->dec_ref(); + } + + void reset_statistics() { + m_stats.reset(); + } + + void collect_statistics(statistics& st) const { + st.update("heap_trie.num_inserts", m_stats.m_num_inserts); + st.update("heap_trie.num_removes", m_stats.m_num_removes); + st.update("heap_trie.num_find_eq", m_stats.m_num_find_eq); + st.update("heap_trie.num_find_le", m_stats.m_num_find_le); + st.update("heap_trie.num_find_le_nodes", m_stats.m_num_find_le_nodes); + } + + void display(std::ostream& out) { + m_root->display(out, 0); + out << "\n"; + } + +private: + + unsigned num_keys() const { + return m_num_keys; + } + + void insert(node* n, unsigned num_keys, Key const* keys, Value const& val) { + // assumption: key is not in table. + + while (true) { + n->inc_ref(); + if (num_keys == 0) { + to_leaf(n)->set_value(val); + SASSERT(n->ref_count() == 1); + break; + } + else { + n = insert_key(to_trie(n), (num_keys == 1), keys[0]); + --num_keys; + ++keys; + } + } + } + + node* insert_key(trie* n, bool is_leaf, Key const& key) { + node* m1 = is_leaf?m_spare_leaf:m_spare_trie; + node* m2 = n->find_or_insert(key, m1); + if (m1 == m2) { + if (is_leaf) { + m_spare_leaf = mk_leaf(); + } + else { + m_spare_trie = mk_trie(); + } + } + return m2; + } + + leaf* mk_leaf() { + return alloc(leaf); + } + + trie* mk_trie() { + return alloc(trie); + } + + trie* to_trie(node* n) { + SASSERT(n->type() == trie_t); + return static_cast(n); + } + + leaf* to_leaf(node* n) { + SASSERT(n->type() == leaf_t); + return static_cast(n); + } +}; + +#endif diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index dd0041fa9..10e222fcf 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -20,12 +20,13 @@ Revision History: #include "hilbert_basis.h" #include "heap.h" #include "map.h" +#include "heap_trie.h" template class rational_map : public map {}; -class hilbert_basis::value_index { +class hilbert_basis::value_index1 { struct stats { unsigned m_num_comparisons; unsigned m_num_hit; @@ -41,7 +42,7 @@ class hilbert_basis::value_index { stats m_stats; public: - value_index(hilbert_basis& hb): + value_index1(hilbert_basis& hb): hb(hb) {} @@ -128,12 +129,112 @@ private: } }; +class hilbert_basis::value_index2 { + struct checker : public heap_trie::check_value { + hilbert_basis* hb; + offset_t m_value; + offset_t m_found; + checker(): hb(0) {} + virtual bool operator()(unsigned const& v) { + if (m_value.m_offset != v && hb->is_subsumed(m_value, offset_t(v))) { + m_found = offset_t(v); + return true; + } + else { + return false; + } + } + }; + hilbert_basis& hb; + heap_trie m_trie; + vector m_found; + bool m_init; + checker m_checker; + + +public: + value_index2(hilbert_basis& hb): hb(hb), m_init(false) { + m_checker.hb = &hb; + } + + void insert(offset_t idx, values const& vs) { + init(); + m_trie.insert(vs()-1, idx.m_offset); + } + + void remove(offset_t idx, values const& vs) { + m_trie.remove(vs()-1); + } + + void reset() { + m_trie.reset(hb.get_num_vars()); + } + + bool find(offset_t idx, values const& vs, offset_t& found_idx) { + init(); + m_found.reset(); + m_checker.m_value = idx; + if (!m_trie.find_le(vs()-1, m_checker)) { + return false; + } + else { + found_idx = m_checker.m_found; + return true; + } + } + + bool find_old(offset_t idx, values const& vs, offset_t& found_idx) { + init(); + m_found.reset(); + m_trie.find_le(vs()-1, m_found); + std::cout << m_found.size() << " - "; + for (unsigned i = 0; i < m_found.size(); ++i) { + found_idx = offset_t(m_found[i]); + std::cout << i << " "; + if (m_found[i] != idx.m_offset && hb.is_subsumed(idx, found_idx)) { + TRACE("hilbert_basis", + hb.display(tout << "found:" , idx); + hb.display(tout << "-> ", found_idx); + m_trie.display(tout);); + std::cout << "\n"; + return true; + } + } + std::cout << "\n"; + TRACE("hilbert_basis", tout << "not found: "; hb.display(tout, idx); ); + return false; + } + + void collect_statistics(statistics& st) const { + m_trie.collect_statistics(st); + } + + void reset_statistics() { + m_trie.reset_statistics(); + } + + unsigned size() const { + return m_trie.size(); + } + +private: + void init() { + if (!m_init) { + reset(); + m_init = true; + } + } +}; + class hilbert_basis::index { // for each non-positive weight a separate index. // for positive weights a shared value index. + typedef value_index1 value_index; + // typedef value_index2 value_index; + struct stats { unsigned m_num_find; unsigned m_num_insert; @@ -184,7 +285,7 @@ public: bool find(offset_t idx, values const& vs, offset_t& found_idx) { ++m_stats.m_num_find; if (vs.weight().is_pos()) { - return m_pos.find(idx, vs, found_idx); + return m_pos.find(idx, vs, found_idx); } else if (vs.weight().is_zero()) { return m_zero.find(idx, vs, found_idx); @@ -198,12 +299,13 @@ public: } void reset() { - m_pos.reset(); - m_neg.reset(); value_map::iterator it = m_neg.begin(), end = m_neg.end(); for (; it != end; ++it) { it->m_value->reset(); } + m_pos.reset(); + m_zero.reset(); + m_neg.reset(); } void collect_statistics(statistics& st) const { @@ -257,7 +359,7 @@ class hilbert_basis::passive { lt m_lt; heap m_heap; // binary heap over weights - numeral get_value(offset_t idx) const { + numeral sum_abs(offset_t idx) const { numeral w(0); unsigned nv = hb.get_num_vars(); for (unsigned i = 0; i < nv; ++i) { @@ -325,7 +427,6 @@ public: iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } bool operator==(iterator const& it) const {return m_idx == it.m_idx; } bool operator!=(iterator const& it) const {return m_idx != it.m_idx; } - }; iterator begin() { @@ -336,42 +437,11 @@ public: return iterator(*this, m_passive.size()); } -public: - /** - Prefer positive weights to negative. - If both weights are positive, prefer the smallest weight. - If weights are the same, prefer the one that has smallest sum of values. - */ bool operator()(int v1, int v2) const { offset_t idx1 = m_passive[v1]; offset_t idx2 = m_passive[v2]; - return get_value(idx1) < get_value(idx2); -#if 0 - values const& vec1 = hb.vec(idx1); - values const& vec2 = hb.vec(idx2); - numeral const& w1 = vec1.weight(); - numeral const& w2 = vec2.weight(); - SASSERT(!w1.is_zero()); - SASSERT(!w2.is_zero()); - - if (w1.is_pos()) { - if (w2.is_neg()) { - return true; - } - if (w1 != w2) { - return w1 < w2; - } - } - else { - if (w2.is_pos()) { - return false; - } - } - SASSERT(w1 == w2); - return get_value(idx1) < get_value(idx2); -#endif + return sum_abs(idx1) < sum_abs(idx2); } - }; hilbert_basis::hilbert_basis(): @@ -420,7 +490,7 @@ void hilbert_basis::reset_statistics() { } void hilbert_basis::add_ge(num_vector const& v, numeral const& b) { - SASSERT(m_ineqs.empty() || v.size() + 1 == get_num_vars()); + SASSERT(m_ineqs.empty() || v.size() + 1 == m_ineqs.back().size()); num_vector w; w.push_back(-b); w.append(v); @@ -437,7 +507,7 @@ void hilbert_basis::add_le(num_vector const& v, numeral const& b) { } void hilbert_basis::add_eq(num_vector const& v, numeral const& b) { - SASSERT(m_ineqs.empty() || v.size() + 1 == get_num_vars()); + SASSERT(m_ineqs.empty() || v.size() + 1 == m_ineqs.back().size()); num_vector w; w.push_back(-b); w.append(v); @@ -474,6 +544,7 @@ unsigned hilbert_basis::get_num_vars() const { return 0; } else { + SASSERT(m_ineqs.back().size() > 1); return m_ineqs.back().size(); } } @@ -486,8 +557,8 @@ void hilbert_basis::init_basis() { m_basis.reset(); m_store.reset(); m_free_list.reset(); - unsigned num_vars = get_num_vars(); - for (unsigned i = 0; i < num_vars; ++i) { + unsigned nv = get_num_vars(); + for (unsigned i = 0; i < nv; ++i) { add_unit_vector(i, numeral(1)); } for (unsigned i = 0; i < m_ints.size(); ++i) { @@ -595,7 +666,7 @@ void hilbert_basis::get_basis_solution(unsigned i, num_vector& v, bool& is_initi void hilbert_basis::get_ge(unsigned i, num_vector& v, numeral& b, bool& is_eq) { v.reset(); - v.append(get_num_vars()-1, m_ineqs[i].c_ptr() + 1); + v.append(m_ineqs[i].size() - 1, m_ineqs[i].c_ptr() + 1); b = -m_ineqs[i][0]; is_eq = m_iseq[i]; } @@ -715,9 +786,7 @@ bool hilbert_basis::can_resolve(offset_t i, offset_t j) const { } values const& v1 = vec(i); values const& v2 = vec(j); - // index 0 is reserved for the constant coefficient. - // The value of it should either be 0 or 1. - if (abs(v1[0] + v2[0]) > numeral(1)) { + if (v1[0].is_one() && v2[0].is_one()) { return false; } for (unsigned i = 0; i < m_ints.size(); ++i) { @@ -798,8 +867,8 @@ void hilbert_basis::display(std::ostream& out, values const& v) const { } void hilbert_basis::display_ineq(std::ostream& out, num_vector const& v, bool is_eq) const { - unsigned nv = get_num_vars(); - for (unsigned j = 0; j < nv; ++j) { + unsigned nv = v.size(); + for (unsigned j = 1; j < nv; ++j) { if (!v[j].is_zero()) { if (j > 0) { if (v[j].is_pos()) { @@ -815,14 +884,14 @@ void hilbert_basis::display_ineq(std::ostream& out, num_vector const& v, bool is if (!v[j].is_one() && !v[j].is_minus_one()) { out << abs(v[j]) << "*"; } - out << "x" << j; + out << "x" << j; } } if (is_eq) { - out << " = 0\n"; + out << " = " << -v[0] << "\n"; } else { - out << " >= 0\n"; + out << " >= " << -v[0] << "\n"; } } @@ -862,7 +931,7 @@ bool hilbert_basis::is_subsumed(offset_t i, offset_t j) const { numeral const& m = w.weight(); bool r = i.m_offset != j.m_offset && - n >= m && (!m.is_nonpos() || n == m) && + n >= m && (!m.is_neg() || n == m) && is_geq(v, w); for (unsigned k = 0; r && k < m_current_ineq; ++k) { r = get_weight(vec(i), m_ineqs[k]) >= get_weight(vec(j), m_ineqs[k]); diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index 8dd5e97cf..09839fc03 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -32,7 +32,8 @@ public: typedef rational numeral; typedef vector num_vector; private: - class value_index; + class value_index1; + class value_index2; class index; class passive; struct offset_t { @@ -59,6 +60,7 @@ private: numeral& operator[](unsigned i) { return m_values[i+1]; } // value of x_i numeral const& weight() const { return m_values[0]; } // value of a*x numeral const& operator[](unsigned i) const { return m_values[i+1]; } // value of x_i + numeral const* operator()() const { return m_values + 1; } }; vector m_ineqs; // set of asserted inequalities diff --git a/src/test/heap_trie.cpp b/src/test/heap_trie.cpp new file mode 100644 index 000000000..648a7662e --- /dev/null +++ b/src/test/heap_trie.cpp @@ -0,0 +1,52 @@ +#include "heap_trie.h" + + +typedef heap_trie heap_trie_t; + +static void find_le(heap_trie_t& ht, unsigned num_keys, unsigned const* keys) { + statistics st; + vector vals; + ht.find_le(keys, vals); + std::cout << "find_le: "; + for (unsigned i = 0; i < num_keys; ++i) { + std::cout << keys[i] << " "; + } + std::cout << " |-> "; + for (unsigned i = 0; i < vals.size(); ++i) { + std::cout << vals[i] << " "; + } + std::cout << "\n"; + ht.collect_statistics(st); + st.display(std::cout); + +} + +void tst_heap_trie() { + heap_trie_t ht; + + ht.reset(3); + unsigned keys1[3] = { 1, 2, 3}; + ht.insert(keys1, 1); + unsigned keys2[3] = { 2, 2, 3}; + ht.insert(keys2, 2); + unsigned keys3[3] = { 1, 1, 3}; + ht.insert(keys3, 3); + unsigned keys4[3] = { 2, 1, 3}; + unsigned keys5[3] = { 2, 3, 3}; + + unsigned val; + + VERIFY (ht.find_eq(keys1, val) && val == 1); + VERIFY (ht.find_eq(keys2, val) && val == 2); + VERIFY (ht.find_eq(keys3, val) && val == 3); + VERIFY (!ht.find_eq(keys4, val)); + + find_le(ht, 3, keys1); + find_le(ht, 3, keys2); + find_le(ht, 3, keys3); + find_le(ht, 3, keys4); + find_le(ht, 3, keys5); + + ht.display(std::cout); + +} diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index 7cf4d863b..d372572bd 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -16,6 +16,18 @@ class hilbert_basis_validate { void validate_solution(hilbert_basis& hb, vector const& v, bool is_initial); + rational eval_ineq(hilbert_basis& hb, unsigned idx, vector const& v, bool& is_eq) { + vector w; + rational bound; + hb.get_ge(idx, w, bound, is_eq); + rational sum(0); + for (unsigned j = 0; j < v.size(); ++j) { + sum += w[j]*v[j]; + } + sum -= bound; + return sum; + } + public: hilbert_basis_validate(ast_manager& m); @@ -35,37 +47,47 @@ void hilbert_basis_validate::validate_solution(hilbert_basis& hb, vector w; + rational bound; hb.get_ge(i, w, bound, is_eq); rational sum(0); for (unsigned j = 0; j < v.size(); ++j) { sum += w[j]*v[j]; } - if (bound > sum || - (is_eq && bound != sum)) { - // validation failed. - std::cout << "validation failed for inequality\n"; - for (unsigned j = 0; j < v.size(); ++j) { - std::cout << v[j] << " "; - } - std::cout << "\n"; - for (unsigned j = 0; j < w.size(); ++j) { - std::cout << w[j] << " "; - } - std::cout << (is_eq?" = ":" >= ") << bound << "\n"; - std::cout << "is initial: " << (is_initial?"true":"false") << "\n"; - std::cout << "sum: " << sum << "\n"; - } - } + if (sum >= bound && !is_eq) { + continue; + } + if (sum == bound && is_eq) { + continue; + } + // homogeneous solutions should be non-negative. + if (!is_initial && sum.is_nonneg()) { + continue; + } + + // validation failed. + std::cout << "validation failed\n"; + std::cout << "constraint: "; + for (unsigned j = 0; j < v.size(); ++j) { + std::cout << v[j] << " "; + } + std::cout << (is_eq?" = ":" >= ") << bound << "\n"; + std::cout << "vector: "; + for (unsigned j = 0; j < w.size(); ++j) { + std::cout << w[j] << " "; + } + std::cout << "\n"; + std::cout << "sum: " << sum << "\n"; + } } expr_ref hilbert_basis_validate::mk_validate(hilbert_basis& hb) { arith_util a(m); unsigned sz = hb.get_basis_size(); vector v; - bool is_initial; // check that claimed solution really satisfies inequalities: for (unsigned i = 0; i < sz; ++i) { + bool is_initial; hb.get_basis_solution(i, v, is_initial); validate_solution(hb, v, is_initial); } @@ -83,12 +105,14 @@ expr_ref hilbert_basis_validate::mk_validate(hilbert_basis& hb) { for (unsigned i = 0; i < sz; ++i) { + bool is_initial; hb.get_basis_solution(i, v, is_initial); for (unsigned j = 0; xs.size() < v.size(); ++j) { xs.push_back(m.mk_fresh_const("x", a.mk_int())); } + if (is_initial) { expr_ref_vector tmp(m); for (unsigned j = 0; j < v.size(); ++j) { @@ -200,6 +224,8 @@ static void validate_sat(hilbert_basis& hb) { expr_ref fml = val.mk_validate(hb); + return; + std::cout << mk_pp(fml, m) << "\n"; fml = m.mk_not(fml); @@ -221,7 +247,7 @@ static void saturate_basis(hilbert_basis& hb) { case l_true: std::cout << "sat\n"; hb.display(std::cout); - // validate_sat(hb); + validate_sat(hb); break; case l_false: std::cout << "unsat\n"; @@ -449,7 +475,7 @@ static void tst11() { // Sigma_9 table 1, Ajili, Contejean static void tst12() { hilbert_basis hb; - hb.add_eq(vec( 1,-2,-4,4), R(0)); + hb.add_eq(vec( 1,-2,-3,4), R(0)); hb.add_le(vec(100,45,-78,-67), R(0)); saturate_basis(hb); } @@ -465,7 +491,7 @@ static void tst13() { static void tst14() { hilbert_basis hb; hb.add_eq(vec(1, 0, -4, 8), R(2)); - hb.add_le(vec(12,19,-11,7), R(-7)); + hb.add_le(vec(12,19,-11,-7), R(-7)); saturate_basis(hb); } diff --git a/src/test/main.cpp b/src/test/main.cpp index dc253f36d..9dc12be1c 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -208,6 +208,7 @@ int main(int argc, char ** argv) { TST(model2expr); TST(rcf); TST(hilbert_basis); + TST(heap_trie); } void initialize_mam() {} From 0aa8df98a1240ee2963a6c9e0160b422b96c86ad Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 18 Feb 2013 18:58:43 -0800 Subject: [PATCH 099/101] optimizing hilbert basis Signed-off-by: Nikolaj Bjorner --- src/muz_qe/heap_trie.h | 198 ++++++++++++++++++++++++----------- src/muz_qe/hilbert_basis.cpp | 148 ++++++++++++++++---------- src/muz_qe/hilbert_basis.h | 2 +- src/test/heap_trie.cpp | 7 +- src/test/hilbert_basis.cpp | 3 +- 5 files changed, 238 insertions(+), 120 deletions(-) diff --git a/src/muz_qe/heap_trie.h b/src/muz_qe/heap_trie.h index 04b7f08d2..25689e930 100644 --- a/src/muz_qe/heap_trie.h +++ b/src/muz_qe/heap_trie.h @@ -29,6 +29,9 @@ Notes: Maintaining sorted ranges for larger domains is another option. + Another possible enhancement is to resplay the tree. + Keep current key index in the nodes. + --*/ #ifndef _HEAP_TRIE_H_ @@ -36,10 +39,12 @@ Notes: #include "map.h" #include "vector.h" +#include "buffer.h" #include "statistics.h" +#include "small_object_allocator.h" -template +template class heap_trie { struct stats { @@ -68,7 +73,8 @@ class heap_trie { void dec_ref() { SASSERT(m_ref > 0); --m_ref; } unsigned ref_count() const { return m_ref; } virtual void display(std::ostream& out, unsigned indent) const = 0; - virtual unsigned size() const = 0; + virtual unsigned num_nodes() const = 0; + virtual unsigned num_leaves() const = 0; }; class leaf : public node { @@ -81,19 +87,19 @@ class heap_trie { virtual void display(std::ostream& out, unsigned indent) const { out << " value: " << m_value; } - virtual unsigned size() const { return 1; } + virtual unsigned num_nodes() const { return 1; } + virtual unsigned num_leaves() const { return ref_count()>0?1:0; } }; + typedef buffer, true, 2> children_t; + // lean trie node class trie : public node { - vector > m_nodes; + children_t m_nodes; public: trie(): node(trie_t) {} virtual ~trie() { - for (unsigned i = 0; i < m_nodes.size(); ++i) { - dealloc(m_nodes[i].second); - } } node* find_or_insert(Key k, node* n) { @@ -119,7 +125,7 @@ class heap_trie { // push nodes whose keys are <= key into vector. void find_le(Key key, ptr_vector& nodes) { for (unsigned i = 0; i < m_nodes.size(); ++i) { - if (m_nodes[i].first <= key) { + if (KeyLE::le(m_nodes[i].first, key)) { node* n = m_nodes[i].second; if (n->ref_count() > 0){ nodes.push_back(n); @@ -128,22 +134,35 @@ class heap_trie { } } + children_t const& nodes() const { return m_nodes; } + children_t & nodes() { return m_nodes; } + virtual void display(std::ostream& out, unsigned indent) const { for (unsigned j = 0; j < m_nodes.size(); ++j) { - out << "\n"; + if (j != 0 || indent > 0) { + out << "\n"; + } for (unsigned i = 0; i < indent; ++i) { out << " "; } node* n = m_nodes[j].second; - out << m_nodes[j].first << " count: " << n->ref_count(); + out << m_nodes[j].first << " refs: " << n->ref_count(); n->display(out, indent + 1); } } - virtual unsigned size() const { + virtual unsigned num_nodes() const { unsigned sz = 1; for (unsigned j = 0; j < m_nodes.size(); ++j) { - sz += m_nodes[j].second->size(); + sz += m_nodes[j].second->num_nodes(); + } + return sz; + } + + virtual unsigned num_leaves() const { + unsigned sz = 0; + for (unsigned j = 0; j < m_nodes.size(); ++j) { + sz += m_nodes[j].second->num_leaves(); } return sz; } @@ -157,18 +176,19 @@ class heap_trie { } return false; } - }; + small_object_allocator m_alloc; unsigned m_num_keys; node* m_root; stats m_stats; node* m_spare_leaf; node* m_spare_trie; - vector > m_children; + public: - heap_trie(): + heap_trie(): + m_alloc("heap_trie"), m_num_keys(0), m_root(0), m_spare_leaf(0), @@ -176,19 +196,19 @@ public: {} ~heap_trie() { - dealloc(m_root); - dealloc(m_spare_leaf); - dealloc(m_spare_trie); + del_node(m_root); + del_node(m_spare_leaf); + del_node(m_spare_trie); } unsigned size() const { - return m_root->size(); + return m_root->num_leaves(); } void reset(unsigned num_keys) { - dealloc(m_root); - dealloc(m_spare_leaf); - dealloc(m_spare_trie); + del_node(m_root); + del_node(m_spare_leaf); + del_node(m_spare_trie); m_num_keys = num_keys; m_root = mk_trie(); m_spare_trie = mk_trie(); @@ -214,7 +234,7 @@ public: return true; } - void find_le(Key const* keys, vector& values) { + void find_all_le(Key const* keys, vector& values) { ++m_stats.m_num_find_le; ptr_vector todo[2]; todo[0].push_back(m_root); @@ -232,7 +252,6 @@ public: } } - // callback based find function class check_value { public: @@ -241,28 +260,8 @@ public: bool find_le(Key const* keys, check_value& check) { ++m_stats.m_num_find_le; - if (m_children.size() < num_keys()) { - m_children.resize(num_keys()); - } - return find_le(m_root, 0, keys, check); - } - - bool find_le(node* n, unsigned index, Key const* keys, check_value& check) { ++m_stats.m_num_find_le_nodes; - if (index == num_keys()) { - SASSERT(n->ref_count() > 0); - return check(to_leaf(n)->get_value()); - } - else { - m_children[index].reset(); - to_trie(n)->find_le(keys[index], m_children[index]); - for (unsigned i = 0; i < m_children[index].size(); ++i) { - if (find_le(m_children[index][i], index + 1, keys, check)) { - return true; - } - } - return false; - } + return find_le(m_root, 0, keys, check); } void remove(Key const* keys) { @@ -288,9 +287,49 @@ public: st.update("heap_trie.num_find_eq", m_stats.m_num_find_eq); st.update("heap_trie.num_find_le", m_stats.m_num_find_le); st.update("heap_trie.num_find_le_nodes", m_stats.m_num_find_le_nodes); + st.update("heap_trie.num_nodes", m_root->num_nodes()); + unsigned_vector nums; + ptr_vector todo; + todo.push_back(m_root); + while (!todo.empty()) { + node* n = todo.back(); + todo.pop_back(); + if (n->type() == trie_t) { + trie* t = to_trie(n); + unsigned sz = t->nodes().size(); + if (nums.size() <= sz) { + nums.resize(sz+1); + } + ++nums[sz]; + for (unsigned i = 0; i < sz; ++i) { + todo.push_back(t->nodes()[i].second); + } + } + } + if (nums.size() < 16) nums.resize(16); + st.update("heap_trie.num_1_children", nums[1]); + st.update("heap_trie.num_2_children", nums[2]); + st.update("heap_trie.num_3_children", nums[3]); + st.update("heap_trie.num_4_children", nums[4]); + st.update("heap_trie.num_5_children", nums[5]); + st.update("heap_trie.num_6_children", nums[6]); + st.update("heap_trie.num_7_children", nums[7]); + st.update("heap_trie.num_8_children", nums[8]); + st.update("heap_trie.num_9_children", nums[9]); + st.update("heap_trie.num_10_children", nums[10]); + st.update("heap_trie.num_11_children", nums[11]); + st.update("heap_trie.num_12_children", nums[12]); + st.update("heap_trie.num_13_children", nums[13]); + st.update("heap_trie.num_14_children", nums[14]); + st.update("heap_trie.num_15_children", nums[15]); + unsigned sz = 0; + for (unsigned i = 16; i < nums.size(); ++i) { + sz += nums[i]; + } + st.update("heap_trie.num_16+_children", sz); } - void display(std::ostream& out) { + void display(std::ostream& out) const { m_root->display(out, 0); out << "\n"; } @@ -300,23 +339,37 @@ private: unsigned num_keys() const { return m_num_keys; } + + bool find_le(node* n, unsigned index, Key const* keys, check_value& check) { + if (index == num_keys()) { + SASSERT(n->ref_count() > 0); + return check(to_leaf(n)->get_value()); + } + else { + Key key = keys[index]; + children_t const& nodes = to_trie(n)->nodes(); + for (unsigned i = 0; i < nodes.size(); ++i) { + ++m_stats.m_num_find_le_nodes; + if (KeyLE::le(nodes[i].first, key)) { + node* m = nodes[i].second; + if (m->ref_count() > 0 && find_le(m, index+1, keys, check)) { + return true; + } + } + } + return false; + } + } void insert(node* n, unsigned num_keys, Key const* keys, Value const& val) { // assumption: key is not in table. - - while (true) { + for (unsigned i = 0; i < num_keys; ++i) { n->inc_ref(); - if (num_keys == 0) { - to_leaf(n)->set_value(val); - SASSERT(n->ref_count() == 1); - break; - } - else { - n = insert_key(to_trie(n), (num_keys == 1), keys[0]); - --num_keys; - ++keys; - } + n = insert_key(to_trie(n), (i + 1 == num_keys), keys[i]); } + n->inc_ref(); + to_leaf(n)->set_value(val); + SASSERT(n->ref_count() == 1); } node* insert_key(trie* n, bool is_leaf, Key const& key) { @@ -334,19 +387,40 @@ private: } leaf* mk_leaf() { - return alloc(leaf); + void* mem = m_alloc.allocate(sizeof(leaf)); + return new (mem) leaf(); } trie* mk_trie() { - return alloc(trie); + void* mem = m_alloc.allocate(sizeof(trie)); + return new (mem) trie(); } - trie* to_trie(node* n) { + void del_node(node* n) { + if (!n) { + return; + } + if (n->type() == trie_t) { + trie* t = to_trie(n); + for (unsigned i = 0; i < t->nodes().size(); ++i) { + del_node(t->nodes()[i].second); + } + t->~trie(); + m_alloc.deallocate(sizeof(trie), t); + } + else { + leaf* l = to_leaf(n); + l->~leaf(); + m_alloc.deallocate(sizeof(leaf), l); + } + } + + trie* to_trie(node* n) const { SASSERT(n->type() == trie_t); return static_cast(n); } - leaf* to_leaf(node* n) { + leaf* to_leaf(node* n) const { SASSERT(n->type() == leaf_t); return static_cast(n); } diff --git a/src/muz_qe/hilbert_basis.cpp b/src/muz_qe/hilbert_basis.cpp index 10e222fcf..7d15a1958 100644 --- a/src/muz_qe/hilbert_basis.cpp +++ b/src/muz_qe/hilbert_basis.cpp @@ -87,7 +87,39 @@ public: unsigned size() const { return m_table.size(); } + + void display(std::ostream& out) const { + int_table::iterator it = m_table.begin(), end = m_table.end(); + for (; it != end; ++it) { + offset_t offs(*it); + hb.display(out, offs); + } + display_profile(out); + } + private: + + typedef hashtable numeral_set; + + void display_profile(std::ostream& out) const { + vector weights; + weights.resize(hb.get_num_vars()+1); + int_table::iterator it = m_table.begin(), end = m_table.end(); + for (; it != end; ++it) { + offset_t offs(*it); + values const& ws = hb.vec(offs); + weights[0].insert(ws.weight()); + for (unsigned i = 0; i < hb.get_num_vars(); ++i) { + weights[i+1].insert(ws[i]); + } + } + out << "profile: "; + for (unsigned i = 0; i < weights.size(); ++i) { + out << weights[i].size() << " "; + } + out << "\n"; + } + void display_profile(offset_t idx, std::ostream& out) { unsigned_vector leq; unsigned nv = hb.get_num_vars(); @@ -130,14 +162,19 @@ private: }; class hilbert_basis::value_index2 { - struct checker : public heap_trie::check_value { + struct key_le { + static bool le(numeral const& n1, numeral const& n2) { + return hilbert_basis::is_abs_geq(n2, n1); + } + }; + struct checker : public heap_trie::check_value { hilbert_basis* hb; - offset_t m_value; - offset_t m_found; - checker(): hb(0) {} + offset_t m_value; + offset_t* m_found; + checker(): hb(0), m_found(0) {} virtual bool operator()(unsigned const& v) { if (m_value.m_offset != v && hb->is_subsumed(m_value, offset_t(v))) { - m_found = offset_t(v); + *m_found = offset_t(v); return true; } else { @@ -146,11 +183,25 @@ class hilbert_basis::value_index2 { } }; hilbert_basis& hb; - heap_trie m_trie; + heap_trie m_trie; vector m_found; bool m_init; checker m_checker; - + vector m_keys; + +#if 1 + numeral const* get_keys(values const& vs) { + return vs()-1; + } +#else + numeral const* get_keys(values const& vs) { + unsigned sz = m_keys.size(); + for (unsigned i = 0; i < sz; ++i) { + m_keys[sz-i-1] = vs()[i-1]; + } + return m_keys.c_ptr(); + } +#endif public: value_index2(hilbert_basis& hb): hb(hb), m_init(false) { @@ -159,50 +210,23 @@ public: void insert(offset_t idx, values const& vs) { init(); - m_trie.insert(vs()-1, idx.m_offset); + m_trie.insert(get_keys(vs), idx.m_offset); } void remove(offset_t idx, values const& vs) { - m_trie.remove(vs()-1); + m_trie.remove(get_keys(vs)); } void reset() { - m_trie.reset(hb.get_num_vars()); + m_trie.reset(hb.get_num_vars()+1); + m_keys.resize(hb.get_num_vars()+1); } bool find(offset_t idx, values const& vs, offset_t& found_idx) { init(); - m_found.reset(); m_checker.m_value = idx; - if (!m_trie.find_le(vs()-1, m_checker)) { - return false; - } - else { - found_idx = m_checker.m_found; - return true; - } - } - - bool find_old(offset_t idx, values const& vs, offset_t& found_idx) { - init(); - m_found.reset(); - m_trie.find_le(vs()-1, m_found); - std::cout << m_found.size() << " - "; - for (unsigned i = 0; i < m_found.size(); ++i) { - found_idx = offset_t(m_found[i]); - std::cout << i << " "; - if (m_found[i] != idx.m_offset && hb.is_subsumed(idx, found_idx)) { - TRACE("hilbert_basis", - hb.display(tout << "found:" , idx); - hb.display(tout << "-> ", found_idx); - m_trie.display(tout);); - std::cout << "\n"; - return true; - } - } - std::cout << "\n"; - TRACE("hilbert_basis", tout << "not found: "; hb.display(tout, idx); ); - return false; + m_checker.m_found = &found_idx; + return m_trie.find_le(get_keys(vs), m_checker); } void collect_statistics(statistics& st) const { @@ -217,6 +241,10 @@ public: return m_trie.size(); } + void display(std::ostream& out) const { + // m_trie.display(out); + } + private: void init() { if (!m_init) { @@ -232,8 +260,8 @@ class hilbert_basis::index { // for each non-positive weight a separate index. // for positive weights a shared value index. - typedef value_index1 value_index; - // typedef value_index2 value_index; + // typedef value_index1 value_index; + typedef value_index2 value_index; struct stats { unsigned m_num_find; @@ -328,6 +356,15 @@ public: it->m_value->reset_statistics(); } } + + void display(std::ostream& out) const { + m_pos.display(out); + m_zero.display(out); + value_map::iterator it = m_neg.begin(), end = m_neg.end(); + for (; it != end; ++it) { + it->m_value->display(out); + } + } private: unsigned size() const { @@ -347,15 +384,16 @@ private: class hilbert_basis::passive { struct lt { - passive& p; - lt(passive& p): p(p) {} + passive** p; + lt(passive** p): p(p) {} bool operator()(int v1, int v2) const { - return p(v1, v2); + return (**p)(v1, v2); } }; hilbert_basis& hb; svector m_passive; unsigned_vector m_free_list; + passive* m_this; lt m_lt; heap m_heap; // binary heap over weights @@ -371,10 +409,11 @@ class hilbert_basis::passive { public: passive(hilbert_basis& hb): - hb(hb) , - m_lt(*this), + hb(hb), + m_lt(&m_this), m_heap(10, m_lt) { + m_this = this; } void reset() { @@ -529,7 +568,7 @@ void hilbert_basis::add_eq(num_vector const& v) { void hilbert_basis::set_is_int(unsigned var_index) { // - // The 0't index is reserved for the constant + // The 0'th index is reserved for the constant // coefficient. Shift indices by 1. // m_ints.push_back(var_index+1); @@ -550,7 +589,7 @@ unsigned hilbert_basis::get_num_vars() const { } hilbert_basis::values hilbert_basis::vec(offset_t offs) const { - return values(m_store.c_ptr() + offs.m_offset); + return values(m_store.c_ptr() + (get_num_vars() + 1)*offs.m_offset); } void hilbert_basis::init_basis() { @@ -680,7 +719,7 @@ void hilbert_basis::select_inequality() { for (unsigned j = best+1; prod != 0 && j < m_ineqs.size(); ++j) { unsigned non_zeros2 = get_num_nonzeros(m_ineqs[j]); unsigned prod2 = get_ineq_product(m_ineqs[j]); - if (prod2 < prod || (prod2 == prod && non_zeros2 < non_zeros)) { + if (non_zeros2 < non_zeros || (non_zeros2 == non_zeros && prod2 < prod)) { prod = prod2; non_zeros = non_zeros2; best = j; @@ -733,7 +772,6 @@ void hilbert_basis::resolve(offset_t i, offset_t j, offset_t r) { u[k] = v[k] + w[k]; } u.weight() = v.weight() + w.weight(); - // std::cout << "resolve: " << v.weight() << " + " << w.weight() << " = " << u.weight() << "\n"; TRACE("hilbert_basis_verbose", display(tout, i); display(tout, j); @@ -747,7 +785,7 @@ hilbert_basis::offset_t hilbert_basis::alloc_vector() { unsigned num_vars = get_num_vars(); unsigned idx = m_store.size(); m_store.resize(idx + 1 + num_vars); - return offset_t(idx); + return offset_t(idx/(1+num_vars)); } else { offset_t result = m_free_list.back(); @@ -757,6 +795,7 @@ hilbert_basis::offset_t hilbert_basis::alloc_vector() { } void hilbert_basis::add_goal(offset_t idx) { + TRACE("hilbert_basis", display(tout, idx);); values v = vec(idx); if (is_subsumed(idx)) { return; @@ -852,6 +891,9 @@ void hilbert_basis::display(std::ostream& out) const { display(out, m_zero[i]); } } + if (m_index) { + m_index->display(out); + } } void hilbert_basis::display(std::ostream& out, offset_t o) const { @@ -954,7 +996,7 @@ bool hilbert_basis::is_geq(values const& v, values const& w) const { return true; } -bool hilbert_basis::is_abs_geq(numeral const& v, numeral const& w) const { +bool hilbert_basis::is_abs_geq(numeral const& v, numeral const& w) { if (w.is_neg()) { return v <= w; } diff --git a/src/muz_qe/hilbert_basis.h b/src/muz_qe/hilbert_basis.h index 09839fc03..567d72fbc 100644 --- a/src/muz_qe/hilbert_basis.h +++ b/src/muz_qe/hilbert_basis.h @@ -100,7 +100,7 @@ private: unsigned get_num_vars() const; numeral get_weight(values const & val, num_vector const& ineq) const; bool is_geq(values const& v, values const& w) const; - bool is_abs_geq(numeral const& v, numeral const& w) const; + static bool is_abs_geq(numeral const& v, numeral const& w); bool is_subsumed(offset_t idx); bool is_subsumed(offset_t i, offset_t j) const; void recycle(offset_t idx); diff --git a/src/test/heap_trie.cpp b/src/test/heap_trie.cpp index 648a7662e..ad3cd0a8d 100644 --- a/src/test/heap_trie.cpp +++ b/src/test/heap_trie.cpp @@ -1,12 +1,15 @@ #include "heap_trie.h" +struct unsigned_le { + static bool le(unsigned i, unsigned j) { return i <= j; } +}; -typedef heap_trie heap_trie_t; +typedef heap_trie heap_trie_t; static void find_le(heap_trie_t& ht, unsigned num_keys, unsigned const* keys) { statistics st; vector vals; - ht.find_le(keys, vals); + ht.find_all_le(keys, vals); std::cout << "find_le: "; for (unsigned i = 0; i < num_keys; ++i) { std::cout << keys[i] << " "; diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index d372572bd..b02c8c90c 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -510,7 +510,7 @@ void tst_hilbert_basis() { tst1(); tst2(); tst3(); - // tst4(); + tst4(); tst5(); tst6(); tst7(); @@ -530,6 +530,5 @@ void tst_hilbert_basis() { } else { gorrila_test(0, 10, 7, 20, 11); - tst4(); } } From 0f9f01a3216e4488dbfce202a40bd231a2d52466 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 22:08:44 +0000 Subject: [PATCH 100/101] Fix for G++. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids this error: ../src/muz_qe/heap_trie.h: In member function ‘virtual unsigned int heap_trie::leaf::num_leaves() const’: ../src/muz_qe/heap_trie.h:91:64: error: there are no arguments to ‘ref_count’ that depend on a template parameter, so a declaration of ‘ref_count’ must be available [-fpermissive] ../src/muz_qe/heap_trie.h:91:64: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated) Signed-off-by: Christoph M. Wintersteiger --- src/muz_qe/heap_trie.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muz_qe/heap_trie.h b/src/muz_qe/heap_trie.h index 25689e930..de07423b6 100644 --- a/src/muz_qe/heap_trie.h +++ b/src/muz_qe/heap_trie.h @@ -88,7 +88,7 @@ class heap_trie { out << " value: " << m_value; } virtual unsigned num_nodes() const { return 1; } - virtual unsigned num_leaves() const { return ref_count()>0?1:0; } + virtual unsigned num_leaves() const { return this->ref_count()>0?1:0; } }; typedef buffer, true, 2> children_t; From 18bae817316bedec2e07475e0a81a4c51251a1a3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 22:48:41 +0000 Subject: [PATCH 101/101] Java Example: build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 873c22b80..25686f9a7 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1236,7 +1236,7 @@ class JavaExampleComponent(ExampleComponent): def mk_makefile(self, out): if JAVA_ENABLED: pkg = get_component(JAVA_COMPONENT).package_name + '.jar' - out.write('_ex_%s: %s' % (self.name, pkg)) + out.write('JavaExample.class: %s' % (pkg)) deps = '' for jfile in get_java_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, jfile)) @@ -1248,7 +1248,8 @@ class JavaExampleComponent(ExampleComponent): for javafile in get_java_files(self.ex_dir): out.write(' ') out.write(os.path.join(win_ex_dir, javafile)) - out.write(' -d .\n\n') + out.write(' -d .\n') + out.write('_ex_%s: JavaExample.class\n\n' % (self.name)) class PythonExampleComponent(ExampleComponent): def __init__(self, name, path):