From f1c0ac72e79ce6e16c383fe05d877f0b4c9e7b5b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 24 Jul 2017 20:54:29 +0100 Subject: [PATCH 001/488] Fix for fp.fma encoding. Relates to #872. --- src/ast/fpa/fpa2bv_converter.cpp | 117 ++++++++++++++++++------------- src/util/mpf.cpp | 2 +- 2 files changed, 70 insertions(+), 49 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 99b8c5ac8..5b71b2c2d 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1516,7 +1516,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, mul_sgn = m_bv_util.mk_bv_xor(2, signs); dbg_decouple("fpa2bv_fma_mul_sgn", mul_sgn); - mul_exp = m_bv_util.mk_bv_add(m_bv_util.mk_bv_sub(a_exp_ext, a_lz_ext), + mul_exp = m_bv_util.mk_bv_add( + m_bv_util.mk_bv_sub(a_exp_ext, a_lz_ext), m_bv_util.mk_bv_sub(b_exp_ext, b_lz_ext)); dbg_decouple("fpa2bv_fma_mul_exp", mul_exp); @@ -1529,11 +1530,14 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, // The product has the form [-1][0].[2*sbits - 2]. // Extend c - c_sig = m_bv_util.mk_zero_extend(1, m_bv_util.mk_concat(c_sig, m_bv_util.mk_numeral(0, sbits-1))); + expr_ref c_sig_ext(m); + c_sig_ext = m_bv_util.mk_zero_extend(1, m_bv_util.mk_concat(c_sig, m_bv_util.mk_numeral(0, sbits - 1))); c_exp_ext = m_bv_util.mk_bv_sub(c_exp_ext, c_lz_ext); SASSERT(m_bv_util.get_bv_size(mul_sig) == 2 * sbits); - SASSERT(m_bv_util.get_bv_size(c_sig) == 2 * sbits); + SASSERT(m_bv_util.get_bv_size(c_sig_ext) == 2 * sbits); + dbg_decouple("fpa2bv_fma_c_sig_ext", c_sig_ext); + dbg_decouple("fpa2bv_fma_c_exp_ext", c_exp_ext); expr_ref swap_cond(m); swap_cond = m_bv_util.mk_sle(mul_exp, c_exp_ext); @@ -1542,10 +1546,10 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref e_sgn(m), e_sig(m), e_exp(m), f_sgn(m), f_sig(m), f_exp(m); m_simp.mk_ite(swap_cond, c_sgn, mul_sgn, e_sgn); - m_simp.mk_ite(swap_cond, c_sig, mul_sig, e_sig); // has 2 * sbits + m_simp.mk_ite(swap_cond, c_sig_ext, mul_sig, e_sig); // has 2 * sbits m_simp.mk_ite(swap_cond, c_exp_ext, mul_exp, e_exp); // has ebits + 2 m_simp.mk_ite(swap_cond, mul_sgn, c_sgn, f_sgn); - m_simp.mk_ite(swap_cond, mul_sig, c_sig, f_sig); // has 2 * sbits + m_simp.mk_ite(swap_cond, mul_sig, c_sig_ext, f_sig); // has 2 * sbits m_simp.mk_ite(swap_cond, mul_exp, c_exp_ext, f_exp); // has ebits + 2 SASSERT(is_well_sorted(m, e_sgn)); @@ -1560,6 +1564,11 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(e_exp) == ebits + 2); SASSERT(m_bv_util.get_bv_size(f_exp) == ebits + 2); + dbg_decouple("fpa2bv_fma_e_sig", e_sig); + dbg_decouple("fpa2bv_fma_e_exp", e_exp); + dbg_decouple("fpa2bv_fma_f_sig", f_sig); + dbg_decouple("fpa2bv_fma_f_exp", f_exp); + expr_ref res_sgn(m), res_sig(m), res_exp(m); expr_ref exp_delta(m); @@ -1582,6 +1591,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, m_bv_util.mk_zero_extend((3*sbits)-(ebits+2), exp_delta)); shifted_f_sig = m_bv_util.mk_extract(3*sbits-1, sbits, shifted_big); sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); + dbg_decouple("fpa2bv_fma_shifted_f_sig", shifted_f_sig); SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2 * sbits); SASSERT(is_well_sorted(m, shifted_f_sig)); @@ -1594,14 +1604,16 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr * or_args[2] = { shifted_f_sig, sticky }; shifted_f_sig = m_bv_util.mk_bv_or(2, or_args); SASSERT(is_well_sorted(m, shifted_f_sig)); + dbg_decouple("fpa2bv_fma_f_sig_or_sticky", shifted_f_sig); // Significant addition. - // Two extra bits for catching the overflow. + // Two extra bits for the sign and for catching overflows. e_sig = m_bv_util.mk_zero_extend(2, e_sig); shifted_f_sig = m_bv_util.mk_zero_extend(2, shifted_f_sig); expr_ref eq_sgn(m); m_simp.mk_eq(e_sgn, f_sgn, eq_sgn); + dbg_decouple("fpa2bv_fma_eq_sgn", eq_sgn); SASSERT(m_bv_util.get_bv_size(e_sig) == 2*sbits + 2); SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2*sbits + 2); @@ -1611,27 +1623,24 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref sum(m), e_plus_f(m), e_minus_f(m); e_plus_f = m_bv_util.mk_bv_add(e_sig, shifted_f_sig); - e_minus_f = m_bv_util.mk_bv_sub(e_sig, shifted_f_sig), - m_simp.mk_ite(eq_sgn, e_plus_f, e_minus_f, sum); - + e_minus_f = m_bv_util.mk_bv_sub(e_sig, shifted_f_sig); + m_simp.mk_ite(eq_sgn, e_plus_f, e_minus_f, sum); + SASSERT(m_bv_util.get_bv_size(sum) == 2*sbits + 2); SASSERT(is_well_sorted(m, sum)); - dbg_decouple("fpa2bv_fma_add_sum", sum); expr_ref sign_bv(m), n_sum(m); sign_bv = m_bv_util.mk_extract(2*sbits+1, 2*sbits+1, sum); n_sum = m_bv_util.mk_bv_neg(sum); + dbg_decouple("fpa2bv_fma_add_sign_bv", sign_bv); + dbg_decouple("fpa2bv_fma_add_n_sum", n_sum); expr_ref res_sig_eq(m), sig_abs(m), one_1(m); one_1 = m_bv_util.mk_numeral(1, 1); m_simp.mk_eq(sign_bv, one_1, res_sig_eq); m_simp.mk_ite(res_sig_eq, n_sum, sum, sig_abs); - dbg_decouple("fpa2bv_fma_add_sign_bv", sign_bv); - dbg_decouple("fpa2bv_fma_add_n_sum", n_sum); dbg_decouple("fpa2bv_fma_add_sig_abs", sig_abs); - res_exp = e_exp; - family_id bvfid = m_bv_util.get_fid(); expr_ref res_sgn_c1(m), res_sgn_c2(m), res_sgn_c3(m); expr_ref not_e_sgn(m), not_f_sgn(m), not_sign_bv(m); @@ -1643,44 +1652,57 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, res_sgn_c3 = m.mk_app(bvfid, OP_BAND, e_sgn, f_sgn); expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 }; res_sgn = m_bv_util.mk_bv_or(3, res_sgn_or_args); + dbg_decouple("fpa2bv_fma_res_sgn", res_sgn); + + expr_ref is_sig_neg(m); + is_sig_neg = m.mk_eq(one_1, m_bv_util.mk_extract(2 * sbits + 1, 2 * sbits + 1, sig_abs)); + sig_abs = m.mk_ite(is_sig_neg, m_bv_util.mk_bv_neg(sig_abs), sig_abs); + dbg_decouple("fpa2bv_fma_is_sig_neg", is_sig_neg); // Result could have overflown into 4.xxx. SASSERT(m_bv_util.get_bv_size(sig_abs) == 2 * sbits + 2); - expr_ref ovfl_into_4(m); - ovfl_into_4 = m.mk_eq(m_bv_util.mk_extract(2 * sbits + 1, 2 * sbits, sig_abs), - m_bv_util.mk_numeral(1, 2)); - dbg_decouple("fpa2bv_fma_ovfl_into_4", ovfl_into_4); - if (sbits > 5) { - expr_ref sticky_raw(m), sig_upper(m), sticky_redd(m), res_sig_norm(m); - sticky_raw = m_bv_util.mk_extract(sbits - 4, 0, sig_abs); - sig_upper = m_bv_util.mk_extract(2 * sbits, sbits - 3, sig_abs); - SASSERT(m_bv_util.get_bv_size(sig_upper) == sbits + 4); - sticky_redd = m.mk_app(bvfid, OP_BREDOR, sticky_raw.get()); - sticky = m_bv_util.mk_zero_extend(sbits + 3, sticky_redd); - expr * res_or_args[2] = { sig_upper, sticky }; - res_sig_norm = m_bv_util.mk_bv_or(2, res_or_args); + expr_ref extra(m), extra_is_zero(m); + extra = m_bv_util.mk_extract(2 * sbits + 1, 2 * sbits, sig_abs); + extra_is_zero = m.mk_eq(extra, m_bv_util.mk_numeral(0, 2)); + dbg_decouple("fpa2bv_fma_extra", extra); - expr_ref sticky_raw_ovfl(m), sig_upper_ovfl(m), sticky_redd_ovfl(m), sticky_ovfl(m), res_sig_ovfl(m); - sticky_raw_ovfl = m_bv_util.mk_extract(sbits - 4, 0, sig_abs); - sig_upper_ovfl = m_bv_util.mk_extract(2 * sbits, sbits - 3, sig_abs); - SASSERT(m_bv_util.get_bv_size(sig_upper_ovfl) == sbits + 4); - sticky_redd_ovfl = m.mk_app(bvfid, OP_BREDOR, sticky_raw_ovfl.get()); - sticky_ovfl = m_bv_util.mk_zero_extend(sbits + 3, sticky_redd_ovfl); - expr * res_or_args_ovfl[2] = { sig_upper_ovfl, sticky_ovfl }; - res_sig_ovfl = m_bv_util.mk_bv_or(2, res_or_args_ovfl); - - res_sig = m.mk_ite(ovfl_into_4, res_sig_ovfl, res_sig_norm); - res_exp = m.mk_ite(ovfl_into_4, m_bv_util.mk_bv_add(res_exp, m_bv_util.mk_numeral(1, ebits+2)), - res_exp); - } - else { - unsigned too_short = 6 - sbits; + unsigned too_short = 0; + if (sbits < 5) { + too_short = 6 - sbits + 1; sig_abs = m_bv_util.mk_concat(sig_abs, m_bv_util.mk_numeral(0, too_short)); - res_sig = m_bv_util.mk_extract(sbits + 3, 0, sig_abs); } - dbg_decouple("fpa2bv_fma_add_sum_sticky", sticky); - dbg_decouple("fpa2bv_fma_sig_abs", sig_abs); + + expr_ref sig_abs_h1(m), sticky_h1(m), sticky_h1_red(m), sig_abs_h1_f(m), res_sig_1(m); + sticky_h1 = m_bv_util.mk_extract(sbits - 5 + too_short, 0, sig_abs); + sig_abs_h1 = m_bv_util.mk_extract(2 * sbits + 1 + too_short, sbits - 4 + too_short, sig_abs); + sticky_h1_red = m_bv_util.mk_zero_extend(sbits + 5, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); + expr * sticky_h1_red_args[2] = { sig_abs_h1, sticky_h1_red }; + sig_abs_h1_f = m_bv_util.mk_bv_or(2, sticky_h1_red_args); + res_sig_1 = m_bv_util.mk_extract(sbits + 3, 0, sig_abs_h1_f); + SASSERT(m_bv_util.get_bv_size(sticky_h1) == sbits - 4 + too_short); + SASSERT(m_bv_util.get_bv_size(sig_abs_h1) == sbits + 6); + SASSERT(m_bv_util.get_bv_size(sticky_h1_red) == sbits + 6); + SASSERT(m_bv_util.get_bv_size(sig_abs_h1_f) == sbits + 6); + SASSERT(m_bv_util.get_bv_size(res_sig_1) == sbits + 4); + + expr_ref sig_abs_h2(m), sticky_h2(m), sticky_h2_red(m), sig_abs_h2_f(m), res_sig_2(m); + sticky_h2 = m_bv_util.mk_extract(sbits - 4 + too_short, 0, sig_abs); + sig_abs_h2 = m_bv_util.mk_extract(2 * sbits + 1 + too_short, sbits - 3 + too_short, sig_abs); + sticky_h2_red = m_bv_util.mk_zero_extend(sbits + 4, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); + expr * sticky_h2_red_args[2] = { sig_abs_h2, sticky_h2_red }; + sig_abs_h2_f = m_bv_util.mk_zero_extend(1, m_bv_util.mk_bv_or(2, sticky_h2_red_args)); + res_sig_2 = m_bv_util.mk_extract(sbits + 3, 0, sig_abs_h2_f); + SASSERT(m_bv_util.get_bv_size(sticky_h2) == sbits - 3 + too_short); + SASSERT(m_bv_util.get_bv_size(sig_abs_h2) == sbits + 5); + SASSERT(m_bv_util.get_bv_size(sticky_h2_red) == sbits + 5); + SASSERT(m_bv_util.get_bv_size(sig_abs_h2_f) == sbits + 6); + SASSERT(m_bv_util.get_bv_size(res_sig_2) == sbits + 4); + + res_sig = m.mk_ite(extra_is_zero, res_sig_1, res_sig_2); + res_exp = m.mk_ite(extra_is_zero, e_exp, m_bv_util.mk_bv_add(e_exp, m_bv_util.mk_numeral(1, ebits + 2))); + dbg_decouple("fpa2bv_fma_res_sig", res_sig); + dbg_decouple("fpa2bv_fma_res_exp", res_exp); SASSERT(m_bv_util.get_bv_size(res_sig) == sbits + 4); expr_ref is_zero_sig(m), nil_sbits4(m); @@ -3889,8 +3911,8 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & mk_min_exp(ebits, e_min); mk_max_exp(ebits, e_max); - TRACE("fpa2bv_dbg", tout << "e_min = " << mk_ismt2_pp(e_min, m) << std::endl << - "e_max = " << mk_ismt2_pp(e_max, m) << std::endl;); + TRACE("fpa2bv_dbg", tout << "e_min = " << mk_ismt2_pp(e_min, m) << std::endl; + tout << "e_max = " << mk_ismt2_pp(e_max, m) << std::endl;); expr_ref OVF1(m), e_top_three(m), sigm1(m), e_eq_emax_and_sigm1(m), e_eq_emax(m); expr_ref e3(m), ne3(m), e2(m), e1(m), e21(m), one_1(m), h_exp(m), sh_exp(m), th_exp(m); @@ -4106,7 +4128,6 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & dbg_decouple("fpa2bv_rnd_rm_is_to_neg", rm_is_to_neg); dbg_decouple("fpa2bv_rnd_rm_is_to_pos", rm_is_to_pos); - expr_ref sgn_is_zero(m), zero1(m); zero1 = m_bv_util.mk_numeral(0, 1); m_simp.mk_eq(sgn, zero1, sgn_is_zero); diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index e9d108cec..7b5c8d62d 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -886,7 +886,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co unsigned extra = 0; // Result could overflow into 4.xxx ... SASSERT(m_mpz_manager.lt(o.significand, m_powers2(2 * x.sbits + 2))); - if(m_mpz_manager.ge(o.significand, m_powers2(2 * x.sbits + 1))) + if (m_mpz_manager.ge(o.significand, m_powers2(2 * x.sbits + 1))) { extra++; o.exponent++; From 75b533f050c4029ad2d1b85532614a8749f1d9aa Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 25 Jul 2017 20:26:17 +0100 Subject: [PATCH 002/488] Fixed normalization shift in MPF rounder. Relates to #872. --- src/util/mpf.cpp | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 7b5c8d62d..fac314837 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -1947,35 +1947,25 @@ void mpf_manager::round(mpf_rounding_mode rm, mpf & o) { TRACE("mpf_dbg", tout << "Shift distance: " << m_mpz_manager.to_string(sigma) << " " << ((m_mpz_manager.is_nonneg(sigma))?"(LEFT)":"(RIGHT)") << std::endl;); - bool sticky = !m_mpz_manager.is_even(o.significand); - m_mpz_manager.machine_div2k(o.significand, 1); // Let f' = f_r/2 - - if (!m_mpz_manager.is_zero(sigma)) { - if (m_mpz_manager.is_neg(sigma)) { // Right shift - unsigned sigma_uint = (unsigned) -m_mpz_manager.get_int64(sigma); // sigma is capped, this is safe. - if (sticky) - m_mpz_manager.machine_div2k(o.significand, sigma_uint); - else - { - scoped_mpz sticky_rem(m_mpz_manager); - m_mpz_manager.machine_div_rem(o.significand, m_powers2(sigma_uint), o.significand, sticky_rem); - sticky = !m_mpz_manager.is_zero(sticky_rem); - } - } - else { // Left shift - unsigned sh_m = static_cast(m_mpz_manager.get_int64(sigma)); - m_mpz_manager.mul2k(o.significand, sh_m, o.significand); - m_mpz_manager.set(sigma, 0); - } + if (m_mpz_manager.le(sigma, 0)) { // Right shift + scoped_mpz sticky_rem(m_mpz_manager); + unsigned sigma_uint = (unsigned)-m_mpz_manager.get_int64(sigma); // sigma is capped, this is safe. + sigma_uint += 2; + m_mpz_manager.machine_div_rem(o.significand, m_powers2(sigma_uint), o.significand, sticky_rem); + bool sticky = !m_mpz_manager.is_zero(sticky_rem); + if (sticky && m_mpz_manager.is_even(o.significand)) + m_mpz_manager.inc(o.significand); + } + else { // Left shift + unsigned sigma_uint = static_cast(m_mpz_manager.get_int64(sigma)); + m_mpz_manager.mul2k(o.significand, sigma_uint - 1, o.significand); + bool sticky = !m_mpz_manager.is_even(o.significand); + m_mpz_manager.machine_div2k(o.significand, 1); + if (sticky && m_mpz_manager.is_even(o.significand)) + m_mpz_manager.inc(o.significand); } - TRACE("mpf_dbg", tout << "Before sticky: " << to_string(o) << std::endl;); - - // Make sure o.significand is a [sbits+2] bit number (i.e. f1[0:sbits+1] == f1[0:sbits-1][round][sticky]) - sticky = sticky || !m_mpz_manager.is_even(o.significand); - m_mpz_manager.machine_div2k(o.significand, 1); - if (sticky && m_mpz_manager.is_even(o.significand)) - m_mpz_manager.inc(o.significand); + TRACE("mpf_dbg", tout << "After sticky: " << to_string(o) << std::endl;); if (OVF1 && OVFen) { o.exponent = beta; @@ -1997,7 +1987,7 @@ void mpf_manager::round(mpf_rounding_mode rm, mpf & o) { // Significand rounding (sigrd) - sticky = !m_mpz_manager.is_even(o.significand); // new sticky bit! + bool sticky = !m_mpz_manager.is_even(o.significand); // new sticky bit! m_mpz_manager.machine_div2k(o.significand, 1); bool round = !m_mpz_manager.is_even(o.significand); m_mpz_manager.machine_div2k(o.significand, 1); From 9f9c575451bc09dfb2f20ab7d79c9eb555f731e0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 25 Jul 2017 16:26:45 -0700 Subject: [PATCH 003/488] fix bug exposed when running test-z3.exe /a in debug mode, #1159. Add assertions to heap interaction Signed-off-by: Nikolaj Bjorner --- src/smt/smt_case_split_queue.cpp | 21 ++++++++++----------- src/smt/smt_context.cpp | 1 + src/smt/smt_context.h | 1 + src/util/heap.h | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/smt/smt_case_split_queue.cpp b/src/smt/smt_case_split_queue.cpp index 41a269820..c461b130b 100644 --- a/src/smt/smt_case_split_queue.cpp +++ b/src/smt/smt_case_split_queue.cpp @@ -51,9 +51,9 @@ namespace smt { if (!m_theory_var_priority.find(v2, p_v2)) { p_v2 = 0.0; } - // add clause activity - p_v1 += m_activity[v1]; - p_v2 += m_activity[v2]; + // add clause activity + p_v1 += m_activity[v1]; + p_v2 += m_activity[v2]; return p_v1 > p_v2; } }; @@ -82,6 +82,7 @@ namespace smt { virtual void mk_var_eh(bool_var v) { m_queue.reserve(v+1); + SASSERT(!m_queue.contains(v)); m_queue.insert(v); } @@ -130,10 +131,7 @@ namespace smt { virtual void display(std::ostream & out) { bool first = true; - bool_var_act_queue::const_iterator it = m_queue.begin(); - bool_var_act_queue::const_iterator end = m_queue.end(); - for (; it != end ; ++it) { - unsigned v = *it; + for (unsigned v : m_queue) { if (m_context.get_assignment(v) == l_undef) { if (first) { out << "remaining case-splits:\n"; @@ -143,8 +141,7 @@ namespace smt { } } if (!first) - out << "\n"; - + out << "\n"; } virtual ~act_case_split_queue() {}; @@ -166,11 +163,15 @@ namespace smt { act_case_split_queue::activity_increased_eh(v); if (m_queue.contains(v)) m_queue.decreased(v); + if (m_delayed_queue.contains(v)) + m_delayed_queue.decreased(v); } virtual void mk_var_eh(bool_var v) { m_queue.reserve(v+1); m_delayed_queue.reserve(v+1); + SASSERT(!m_delayed_queue.contains(v)); + SASSERT(!m_queue.contains(v)); if (m_context.is_searching()) m_delayed_queue.insert(v); else @@ -1099,8 +1100,6 @@ namespace smt { #endif GOAL_STOP(); - - //std::cout << "goal set, time " << m_goal_time.get_seconds() << "\n"; } void set_global_generation() diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 4e56d3004..b5789a597 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -1826,6 +1826,7 @@ namespace smt { } void context::rescale_bool_var_activity() { + TRACE("case_split", tout << "rescale\n";); svector::iterator it = m_activity.begin(); svector::iterator end = m_activity.end(); for (; it != end; ++it) diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index 9c70f5999..6b3129d91 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -1040,6 +1040,7 @@ namespace smt { if (act > ACTIVITY_LIMIT) rescale_bool_var_activity(); m_case_split_queue->activity_increased_eh(v); + TRACE("case_split", tout << "v" << v << " " << m_bvar_inc << " -> " << act << "\n";); } protected: diff --git a/src/util/heap.h b/src/util/heap.h index e8964a4f0..cde2451db 100644 --- a/src/util/heap.h +++ b/src/util/heap.h @@ -43,6 +43,15 @@ class heap : private LT { return i >> 1; } + void display(std::ostream& out, unsigned indent, int idx) const { + if (idx < static_cast(m_values.size())) { + for (unsigned i = 0; i < indent; ++i) out << " "; + out << m_values[idx] << "\n"; + display(out, indent + 1, left(idx)); + display(out, indent + 1, right(idx)); + } + } + #ifdef Z3DEBUG // Return true if the value can be inserted in the heap. That is, the vector m_value2indices is big enough to store this value. bool is_valid_value(int v) const { @@ -59,10 +68,13 @@ class heap : private LT { } return true; } + + public: bool check_invariant() const { return check_invariant_core(1); } + #endif private: @@ -219,6 +231,7 @@ public: void insert(int val) { CASSERT("heap", check_invariant()); + CASSERT("heap", !contains(val)); SASSERT(is_valid_value(val)); int idx = static_cast(m_values.size()); m_value2indices[val] = idx; @@ -272,6 +285,11 @@ public: } } } + + void display(std::ostream& out) const { + display(out, 0, 1); + } + }; From cbca609af424e91013dc0e7fef7cbb9640b36149 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 26 Jul 2017 08:57:46 +0100 Subject: [PATCH 004/488] [TravisCI] Fix running unit tests. Previously the `test-z3` executable was run without arguments which appears to run no tests. To fix this the `/a` argument is passed which will run all tests that don't require arguments. This was noticed in #1159 when @KarenHuang2016 reported a failing test. --- contrib/ci/scripts/test_z3_unit_tests_cmake.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contrib/ci/scripts/test_z3_unit_tests_cmake.sh b/contrib/ci/scripts/test_z3_unit_tests_cmake.sh index 0d8e59b0f..666673328 100755 --- a/contrib/ci/scripts/test_z3_unit_tests_cmake.sh +++ b/contrib/ci/scripts/test_z3_unit_tests_cmake.sh @@ -1,6 +1,7 @@ #!/bin/bash SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )" +. ${SCRIPT_DIR}/run_quiet.sh set -x set -e @@ -21,4 +22,5 @@ cd "${Z3_BUILD_DIR}" # Build and run internal tests cmake --build $(pwd) --target test-z3 "${GENERATOR_ARGS[@]}" -./test-z3 +# Run all tests that don't require arguments +run_quiet ./test-z3 /a From b06b9eeb351bb49d9af080192ecbf5e83a4b68ca Mon Sep 17 00:00:00 2001 From: Daniel Perelman Date: Mon, 24 Jul 2017 15:53:37 -0700 Subject: [PATCH 005/488] Adding ENABLE_CFI flag to CMake. --- CMakeLists.txt | 32 ++++++++++++++++++++++++++++++++ README-CMake.md | 2 ++ cmake/msvc_legacy_quirks.cmake | 7 ++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8ecb5295..a3bba73ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -411,6 +411,38 @@ endif() ################################################################################ include(${CMAKE_SOURCE_DIR}/cmake/compiler_lto.cmake) +################################################################################ +# Control flow integrity +################################################################################ +option(ENABLE_CFI "Enable control flow integrity checking" OFF) +if (ENABLE_CFI) + set(build_types_with_cfi "RELEASE" "RELWITHDEBINFO") + if (NOT LINK_TIME_OPTIMIZATION) + message(FATAL_ERROR "Cannot enable control flow integrity checking without link-time optimization." + "You should set LINK_TIME_OPTIMIZATION to ON or ENABLE_CFI to OFF.") + endif() + if (DEFINED CMAKE_CONFIGURATION_TYPES) + # Multi configuration generator + message(STATUS "Note CFI is only enabled for the following configurations: ${build_types_with_cfi}") + # No need for else because this is the same as the set that LTO requires. + endif() + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + z3_add_cxx_flag("-fsanitize=cfi" REQUIRED) + z3_add_cxx_flag("-fsanitize-cfi-cross-dso" REQUIRED) + elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") + z3_add_cxx_flag("/guard:cf" REQUIRED) + message(STATUS "Enabling CFI for MSVC") + foreach (_build_type ${build_types_with_cfi}) + message(STATUS "Enabling CFI for MSVC") + string(APPEND CMAKE_EXE_LINKER_FLAGS_${_build_type} " /GUARD:CF") + string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /GUARD:CF") + endforeach() + else() + message(FATAL_ERROR "Can't enable control flow integrity for compiler \"${CMAKE_CXX_COMPILER_ID}\"." + "You should set ENABLE_CFI to OFF or use Clang or MSVC to compile.") + endif() +endif() + ################################################################################ # MSVC specific flags inherited from old build system ################################################################################ diff --git a/README-CMake.md b/README-CMake.md index 715cacad2..605c14818 100644 --- a/README-CMake.md +++ b/README-CMake.md @@ -265,6 +265,8 @@ The following useful options can be passed to CMake whilst configuring. * ``ALWAYS_BUILD_DOCS`` - BOOL. If set to ``TRUE`` and ``BUILD_DOCUMENTATION`` is ``TRUE`` then documentation for API bindings will always be built. Disabling this is useful for faster incremental builds. The documentation can be manually built by invoking the ``api_docs`` target. * ``LINK_TIME_OPTIMIZATION`` - BOOL. If set to ``TRUE`` link time optimization will be enabled. +* ``ENABLE_CFI`` - BOOL. If set to ``TRUE`` will enable Control Flow Integrity security checks. This is only supported by MSVC and Clang and will + fail on other compilers. This requires LINK_TIME_OPTIMIZATION to also be enabled. * ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature. * ``WARNINGS_AS_ERRORS`` - STRING. If set to ``TRUE`` compiler warnings will be treated as errors. If set to ``False`` compiler warnings will not be treated as errors. If set to ``SERIOUS_ONLY`` a subset of compiler warnings will be treated as errors. diff --git a/cmake/msvc_legacy_quirks.cmake b/cmake/msvc_legacy_quirks.cmake index 2ca20277c..36fe82bb3 100644 --- a/cmake/msvc_legacy_quirks.cmake +++ b/cmake/msvc_legacy_quirks.cmake @@ -184,7 +184,12 @@ foreach (_build_type ${_build_types_as_upper}) # Address space layout randomization # See https://msdn.microsoft.com/en-us/library/bb384887.aspx string(APPEND CMAKE_EXE_LINKER_FLAGS_${_build_type} " /DYNAMICBASE") - string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /DYNAMICBASE:NO") + if(ENABLE_CFI) + # CFI requires /DYNAMICBASE to be enabled. + string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /DYNAMICBASE") + else() + string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /DYNAMICBASE:NO") + endif() # FIXME: This is not necessary. This is MSVC's default. # Indicate that the executable is compatible with DEP From bb7b3c510f59ec1502e90d2ab8f3b41b2c92bfa7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 26 Jul 2017 19:52:05 -0700 Subject: [PATCH 006/488] fix for #1161 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/tactic_cmds.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index 2b60486f7..119deec8c 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -308,6 +308,9 @@ public: } virtual void execute(cmd_context & ctx) { + if (!m_tactic) { + throw cmd_exception("apply needs a tactic argument"); + } params_ref p = ctx.params().merge_default_params(ps()); tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p); { From b1298d7bde84ab1790de7cb33eb859f4cacb3d50 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 26 Jul 2017 20:28:55 -0700 Subject: [PATCH 007/488] ensure that assertions within the unit tests are exercised in all build modes, remove special handling of SASSERT for release mode #1163 Signed-off-by: Nikolaj Bjorner --- src/test/algebraic.cpp | 24 +- src/test/api.cpp | 2 +- src/test/arith_rewriter.cpp | 2 +- src/test/ast.cpp | 52 ++--- src/test/bit_vector.cpp | 96 ++++---- src/test/bits.cpp | 14 +- src/test/buffer.cpp | 18 +- src/test/bv_simplifier_plugin.cpp | 22 +- src/test/chashtable.cpp | 86 ++++---- src/test/diff_logic.cpp | 46 ++-- src/test/dl_context.cpp | 10 +- src/test/dl_product_relation.cpp | 112 +++++----- src/test/dl_query.cpp | 12 +- src/test/dl_relation.cpp | 22 +- src/test/dl_table.cpp | 10 +- src/test/dl_util.cpp | 12 +- src/test/doc.cpp | 48 ++-- src/test/ext_numeral.cpp | 58 ++--- src/test/fixed_bit_vector.cpp | 28 +-- src/test/get_consequences.cpp | 2 +- src/test/get_implied_equalities.cpp | 44 ++-- src/test/hashtable.cpp | 38 ++-- src/test/heap.cpp | 22 +- src/test/hilbert_basis.cpp | 4 +- src/test/hwf.cpp | 22 +- src/test/inf_rational.cpp | 124 +++++------ src/test/interval.cpp | 2 +- src/test/karr.cpp | 2 +- src/test/list.cpp | 8 +- src/test/map.cpp | 28 +-- src/test/mpf.cpp | 38 ++-- src/test/mpff.cpp | 238 ++++++++++---------- src/test/mpfx.cpp | 2 +- src/test/mpq.cpp | 34 +-- src/test/mpz.cpp | 50 ++--- src/test/nlsat.cpp | 36 +-- src/test/no_overflow.cpp | 8 +- src/test/object_allocator.cpp | 10 +- src/test/old_interval.cpp | 166 +++++++------- src/test/optional.cpp | 26 +-- src/test/parray.cpp | 66 +++--- src/test/pb2bv.cpp | 4 +- src/test/permutation.cpp | 2 +- src/test/polynomial.cpp | 136 ++++++------ src/test/polynorm.cpp | 10 +- src/test/prime_generator.cpp | 2 +- src/test/qe_arith.cpp | 2 +- src/test/quant_solve.cpp | 6 +- src/test/rational.cpp | 326 ++++++++++++++-------------- src/test/rcf.cpp | 8 +- src/test/sat_user_scope.cpp | 2 +- src/test/simplex.cpp | 2 +- src/test/simplifier.cpp | 22 +- src/test/sorting_network.cpp | 22 +- src/test/stack.cpp | 12 +- src/test/string_buffer.cpp | 6 +- src/test/symbol.cpp | 46 ++-- src/test/symbol_table.cpp | 20 +- src/test/tbv.cpp | 24 +- src/test/theory_pb.cpp | 4 +- src/test/total_order.cpp | 28 +-- src/test/udoc_relation.cpp | 16 +- src/test/uint_set.cpp | 94 ++++---- src/test/upolynomial.cpp | 96 ++++---- src/test/var_subst.cpp | 4 +- src/test/vector.cpp | 20 +- src/util/debug.h | 4 - 67 files changed, 1277 insertions(+), 1285 deletions(-) diff --git a/src/test/algebraic.cpp b/src/test/algebraic.cpp index af7270825..076d7ec73 100644 --- a/src/test/algebraic.cpp +++ b/src/test/algebraic.cpp @@ -54,7 +54,7 @@ static void tst1() { std::cout << "p: " << p << "\n"; am.isolate_roots(p, rs1); display_anums(std::cout, rs1); - SASSERT(rs1.size() == 1); + ENSURE(rs1.size() == 1); std::cout.flush(); p = (x^2) - 2; @@ -62,7 +62,7 @@ static void tst1() { rs1.reset(); am.isolate_roots(p, rs1); display_anums(std::cout, rs1); - SASSERT(rs1.size() == 2); + ENSURE(rs1.size() == 2); scoped_anum sqrt2(am); am.set(sqrt2, rs1[1]); @@ -88,7 +88,7 @@ static void tst1() { rs1.reset(); am.isolate_roots(p, rs1); display_anums(std::cout, rs1); - SASSERT(rs1.size() == 3); + ENSURE(rs1.size() == 3); scoped_anum gauss(am); am.set(gauss, rs1[1]); @@ -104,7 +104,7 @@ static void tst1() { rs1.reset(); am.isolate_roots(p, rs1); display_anums(std::cout, rs1); - SASSERT(rs1.size() == 4); + ENSURE(rs1.size() == 4); scoped_anum hidden_sqrt2(am); am.set(hidden_sqrt2, rs1[2]); @@ -116,8 +116,8 @@ static void tst1() { std::cout << "sqrt(2)^4: " << (sqrt2^4) << "\n"; - SASSERT(is_int(power(sqrt2, 4))); - SASSERT(power(sqrt2, 4) == 4); + ENSURE(is_int(power(sqrt2, 4))); + ENSURE(power(sqrt2, 4) == 4); scoped_anum sqrt2_gauss(am); am.add(sqrt2, gauss, sqrt2_gauss); @@ -242,9 +242,9 @@ static void tst_wilkinson() { std::cout << "p: " << p << "\n"; am.isolate_roots(p, rs1); display_anums(std::cout, rs1); - SASSERT(rs1.size() == 20); + ENSURE(rs1.size() == 20); for (unsigned i = 0; i < rs1.size(); i++) { - SASSERT(am.is_int(rs1[i])); + ENSURE(am.is_int(rs1[i])); } } @@ -328,9 +328,9 @@ static void tst_eval_sign(polynomial_ref const & p, anum_manager & am, std::cout << "x1 -> "; am.display_root(std::cout, v1); std::cout << "\n"; std::cout << "x2 -> "; am.display_root(std::cout, v2); std::cout << "\n"; int s = am.eval_sign_at(p, x2v); - SASSERT((s == 0) == (expected == 0)); - SASSERT((s < 0) == (expected < 0)); - SASSERT((s > 0) == (expected > 0)); + ENSURE((s == 0) == (expected == 0)); + ENSURE((s < 0) == (expected < 0)); + ENSURE((s > 0) == (expected > 0)); std::cout << "sign: " << s << "\n"; } @@ -399,7 +399,7 @@ static void tst_isolate_roots(polynomial_ref const & p, anum_manager & am, scoped_anum_vector roots(am); svector signs; am.isolate_roots(p, x2v, roots, signs); - SASSERT(roots.size() + 1 == signs.size()); + ENSURE(roots.size() + 1 == signs.size()); std::cout << "roots:\n"; for (unsigned i = 0; i < roots.size(); i++) { am.display_root(std::cout, roots[i]); std::cout << " "; am.display_decimal(std::cout, roots[i]); std::cout << "\n"; diff --git a/src/test/api.cpp b/src/test/api.cpp index 667d10bc5..f691a8701 100644 --- a/src/test/api.cpp +++ b/src/test/api.cpp @@ -101,7 +101,7 @@ static void test_mk_distinct() { Z3_sort bv32 = Z3_mk_bv_sort(ctx, 32); Z3_ast args[] = { Z3_mk_int64(ctx, 0, bv8), Z3_mk_int64(ctx, 0, bv32) }; Z3_ast d = Z3_mk_distinct(ctx, 2, args); - SASSERT(cb_called); + ENSURE(cb_called); Z3_del_config(cfg); Z3_del_context(ctx); diff --git a/src/test/arith_rewriter.cpp b/src/test/arith_rewriter.cpp index 5ed7c3501..6bdb11d48 100644 --- a/src/test/arith_rewriter.cpp +++ b/src/test/arith_rewriter.cpp @@ -27,7 +27,7 @@ static expr_ref parse_fml(ast_manager& m, char const* str) { << "(assert " << str << ")\n"; std::istringstream is(buffer.str()); VERIFY(parse_smt2_commands(ctx, is)); - SASSERT(ctx.begin_assertions() != ctx.end_assertions()); + ENSURE(ctx.begin_assertions() != ctx.end_assertions()); result = *ctx.begin_assertions(); return result; } diff --git a/src/test/ast.cpp b/src/test/ast.cpp index b59e2a612..20a1007a4 100644 --- a/src/test/ast.cpp +++ b/src/test/ast.cpp @@ -29,21 +29,21 @@ static void tst1() { expr_ref i1(m.mk_app(fid, OP_AND, a.get(), c.get()), m); expr_ref i2(m.mk_app(fid, OP_AND, a.get(), c.get()), m); expr_ref i3(m.mk_app(fid, OP_OR, a.get(), c.get()), m); - SASSERT(i1.get() == i2.get()); - SASSERT(i1.get() != i3.get()); + ENSURE(i1.get() == i2.get()); + ENSURE(i1.get() != i3.get()); // TODO use smart pointers to track references // ast_manager m; // ast_ref n1(m.mk_numeral(rational(2,3)), m); // ast_ref n2(m.mk_numeral(rational(2,3)), m); -// SASSERT(n1 == n2); +// ENSURE(n1 == n2); // ast_ref n3(m.mk_numeral(rational(1,2)), m); -// SASSERT(n1 != n3); +// ENSURE(n1 != n3); // ast_ref v1 (m.mk_var(1), m); // ast_ref v2 (m.mk_var(2), m); // ast_ref v3 (m.mk_var(1), m); -// SASSERT(v1 != v2); -// SASSERT(v1 == v3); +// ENSURE(v1 != v2); +// ENSURE(v1 == v3); // TRACE("ast", tout << "reseting v1\n";); // v1.reset(); // TRACE("ast", tout << "overwriting v3\n";); @@ -59,7 +59,7 @@ static void tst1() { // ast_ref foo_x(m.mk_const(foo_decl.get(), x.get()), m); // ast_ref foo_foo_x(m.mk_const(foo_decl.get(), foo_x.get()), m); // ast_ref foo_foo_x2(m.mk_const(foo_decl.get(), m.mk_const(foo_decl.get(), m.mk_const(x_decl.get()))), m); -// SASSERT(foo_foo_x2 == foo_foo_x); +// ENSURE(foo_foo_x2 == foo_foo_x); } static void tst2() { @@ -70,13 +70,13 @@ static void tst2() { // m_nodes.push_back(m.mk_numeral(rational(1,2))); // m_nodes.push_back(m.mk_var(2)); // m_nodes[1] = m.mk_var(3); -// SASSERT(m_nodes[1]->kind() == AST_VAR); -// SASSERT(m_nodes.get(1)->kind() == AST_VAR); +// ENSURE(m_nodes[1]->kind() == AST_VAR); +// ENSURE(m_nodes.get(1)->kind() == AST_VAR); // m_nodes.pop_back(); -// SASSERT(m_nodes.size() == 2); -// SASSERT(!m_nodes.empty()); +// ENSURE(m_nodes.size() == 2); +// ENSURE(!m_nodes.empty()); // m_nodes.set(1, m.mk_var(4)); -// SASSERT(&(m_nodes.get_manager()) == &m); +// ENSURE(&(m_nodes.get_manager()) == &m); } static void tst3() { @@ -95,16 +95,16 @@ static void tst4() { // #ifdef Z3DEBUG // int r; // #endif -// SASSERT(!wm1.find(n1, r)); +// ENSURE(!wm1.find(n1, r)); // wm1.insert(n2, 10); -// SASSERT(!wm1.find(n1, r)); -// SASSERT(wm1.find(n2, r) && r == 10); +// ENSURE(!wm1.find(n1, r)); +// ENSURE(wm1.find(n2, r) && r == 10); // wm1.insert(n2, 20); -// SASSERT(!wm1.find(n1, r)); -// SASSERT(wm1.find(n2, r) && r == 20); +// ENSURE(!wm1.find(n1, r)); +// ENSURE(wm1.find(n2, r) && r == 20); // wm1.insert(n1, 0); -// SASSERT(wm1.find(n1, r) && r == 0); -// SASSERT(wm1.find(n2, r) && r == 20); +// ENSURE(wm1.find(n1, r) && r == 0); +// ENSURE(wm1.find(n2, r) && r == 20); } static void tst5() { @@ -119,13 +119,13 @@ static void tst5() { m.push_back(arr1, a2); m.pop_back(arr1, arr2); m.set(arr2, 0, a2, arr3); - SASSERT(m.size(arr1) == 2); - SASSERT(m.size(arr2) == 1); - SASSERT(m.size(arr3) == 1); - SASSERT(m.get(arr1, 0) == a1); - SASSERT(m.get(arr1, 1) == a2); - SASSERT(m.get(arr2, 0) == a1); - SASSERT(m.get(arr3, 0) == a2); + ENSURE(m.size(arr1) == 2); + ENSURE(m.size(arr2) == 1); + ENSURE(m.size(arr3) == 1); + ENSURE(m.get(arr1, 0) == a1); + ENSURE(m.get(arr1, 1) == a2); + ENSURE(m.get(arr2, 0) == a1); + ENSURE(m.get(arr3, 0) == a2); m.del(arr1); m.del(arr2); m.del(arr3); diff --git a/src/test/bit_vector.cpp b/src/test/bit_vector.cpp index 6f83bb328..46a39747d 100644 --- a/src/test/bit_vector.cpp +++ b/src/test/bit_vector.cpp @@ -31,30 +31,30 @@ static void tst1() { bool val = (rand()%2) != 0; v1.push_back(val); v2.push_back(val); - SASSERT(v1.size() == v2.size()); + ENSURE(v1.size() == v2.size()); } else if (op <= 3) { - SASSERT(v1.size() == v2.size()); + ENSURE(v1.size() == v2.size()); if (v1.size() > 0) { bool val = (rand()%2) != 0; unsigned idx = rand()%v1.size(); - SASSERT(v1.get(idx) == v2[idx]); + ENSURE(v1.get(idx) == v2[idx]); v1.set(idx, val); v2[idx] = val; - SASSERT(v1.get(idx) == v2[idx]); + ENSURE(v1.get(idx) == v2[idx]); } } else if (op <= 4) { - SASSERT(v1.size() == v2.size()); + ENSURE(v1.size() == v2.size()); if (v1.size() > 0) { unsigned idx = rand()%v1.size(); VERIFY(v1.get(idx) == v2[idx]); } } else if (op <= 5) { - SASSERT(v1.size() == v2.size()); + ENSURE(v1.size() == v2.size()); for (unsigned j = 0; j < v1.size(); j++) { - SASSERT(v1.get(j) == v2[j]); + ENSURE(v1.get(j) == v2[j]); } } } @@ -66,11 +66,11 @@ static void tst2() { b.push_back(false); b.push_back(true); b.resize(30); - SASSERT(b.get(0) == true); - SASSERT(b.get(1) == false); - SASSERT(b.get(2) == true); - SASSERT(b.get(3) == false); - SASSERT(b.get(29) == false); + ENSURE(b.get(0) == true); + ENSURE(b.get(1) == false); + ENSURE(b.get(2) == true); + ENSURE(b.get(3) == false); + ENSURE(b.get(29) == false); } static void tst_shift() { @@ -116,14 +116,14 @@ static void tst_or() { std::cout << b1 << "\n"; std::cout << b2 << "\n"; b1 |= b2; - SASSERT(b1.size() == 10); + ENSURE(b1.size() == 10); std::cout << b1 << "\n"; - SASSERT(b1 != b2); - SASSERT(b1 != b2); + ENSURE(b1 != b2); + ENSURE(b1 != b2); b1.unset(4); - SASSERT(b1 == b2); + ENSURE(b1 == b2); b1.unset(3); - SASSERT(b1 != b2); + ENSURE(b1 != b2); } { bit_vector b1; @@ -133,9 +133,9 @@ static void tst_or() { b1.set(0); b2.set(4); b1 |= b2; - SASSERT(b1 != b2); + ENSURE(b1 != b2); b2.set(0); - SASSERT(b1 == b2); + ENSURE(b1 == b2); std::cout << "-----\n"; std::cout << b1 << "\n"; } @@ -149,9 +149,9 @@ static void tst_or() { b2.set(3); b2.resize(5); b1 |= b2; - SASSERT(!b1.get(8)); - SASSERT(b1.get(5)); - SASSERT(b1.get(3)); + ENSURE(!b1.get(8)); + ENSURE(b1.get(5)); + ENSURE(b1.get(3)); } { bit_vector b1; @@ -166,17 +166,17 @@ static void tst_or() { b2.set(80); b1.set(4); b2.set(4); - SASSERT(b1!=b2); + ENSURE(b1!=b2); b2.resize(123); - SASSERT(b1!=b2); + ENSURE(b1!=b2); b1.resize(120); b2.resize(120); - SASSERT(b1==b2); + ENSURE(b1==b2); b1.unset(80); b1.unset(100); - SASSERT(b1!=b2); + ENSURE(b1!=b2); b1 |= b2; - SASSERT(b1 == b2); + ENSURE(b1 == b2); } { bit_vector b1; @@ -188,8 +188,8 @@ static void tst_or() { b2.set(1); b1.set(0); b1 |= b2; - SASSERT(b1.size() == 10); - SASSERT(b1.get(8) && b1.get(4) && b1.get(1) && b1.get(0) && !b1.get(9)); + ENSURE(b1.size() == 10); + ENSURE(b1.get(8) && b1.get(4) && b1.get(1) && b1.get(0) && !b1.get(9)); } { bit_vector b1; @@ -201,7 +201,7 @@ static void tst_or() { b2.set(8); b2.set(0); b1 |= b2; - SASSERT(b1.get(1) && b1.get(5) && b1.get(8) && b1.get(0) && !b1.get(11)); + ENSURE(b1.get(1) && b1.get(5) && b1.get(8) && b1.get(0) && !b1.get(11)); std::cout << "b1(size32): " << b1 << "\n"; } } @@ -218,8 +218,8 @@ static void tst_and() { std::cout << "------\nb1: " << b1 << "\n"; b1 &= b2; std::cout << "------\nb1: " << b1 << "\n"; - SASSERT(!b1.get(4)); - SASSERT(b1.get(2)); + ENSURE(!b1.get(4)); + ENSURE(b1.get(2)); } { bit_vector b1; @@ -234,7 +234,7 @@ static void tst_and() { b2.set(127); b2.set(5); b1 &= b2; - SASSERT(!b1.get(240) && !b1.get(232) && !b1.get(128) && b1.get(127) && !b1.get(8) && !b1.get(5)); + ENSURE(!b1.get(240) && !b1.get(232) && !b1.get(128) && b1.get(127) && !b1.get(8) && !b1.get(5)); } } @@ -243,17 +243,17 @@ static void tst_crash() { bit_vector b; b.push_back(true); b.resize(64); - SASSERT(!b.get(63)); - SASSERT(b.get(0)); - SASSERT(!b.get(1)); + ENSURE(!b.get(63)); + ENSURE(b.get(0)); + ENSURE(!b.get(1)); } { bit_vector b; b.push_back(false); b.resize(64, true); - SASSERT(b.get(63)); - SASSERT(!b.get(0)); - SASSERT(b.get(1)); + ENSURE(b.get(63)); + ENSURE(!b.get(0)); + ENSURE(b.get(1)); } } @@ -264,12 +264,12 @@ static void tst_bv_reset() { b.reset(); b.resize(sz, bit); for (unsigned i = 0; i < sz; ++i) { - SASSERT(bit == b.get(i)); + ENSURE(bit == b.get(i)); } for (unsigned sz2 = sz; sz2 < sz+10; ++sz2) { b.resize(sz2, !bit); for (unsigned i = sz; i < sz2; ++i) { - SASSERT(bit != b.get(i)); + ENSURE(bit != b.get(i)); } } bit = !bit; @@ -283,19 +283,19 @@ static void tst_eq() { b3.resize(32); b1.set(3, true); - SASSERT(b1 != b2); - SASSERT(!(b1 == b2)); - SASSERT(b2 == b3); + ENSURE(b1 != b2); + ENSURE(!(b1 == b2)); + ENSURE(b2 == b3); b3.set(3, true); - SASSERT(b1 == b3); - SASSERT(!(b1 != b3)); + ENSURE(b1 == b3); + ENSURE(!(b1 != b3)); b2.set(31, true); b3.set(31); b3.unset(3); - SASSERT(b2 == b3); - SASSERT(!(b2 != b3)); + ENSURE(b2 == b3); + ENSURE(!(b2 != b3)); } void tst_bit_vector() { diff --git a/src/test/bits.cpp b/src/test/bits.cpp index f32871a5a..ba75ea0b4 100644 --- a/src/test/bits.cpp +++ b/src/test/bits.cpp @@ -27,11 +27,11 @@ static void tst_shl(unsigned src_sz, unsigned const * src, unsigned k, if (trace) std::cout << " for sz = " << sz << std::endl; shl(src_sz, src, k, sz, actual_dst.c_ptr()); - SASSERT(!has_one_at_first_k_bits(sz, actual_dst.c_ptr(), k)); + ENSURE(!has_one_at_first_k_bits(sz, actual_dst.c_ptr(), k)); for (unsigned i = 0; i < sz; i++) { if (trace && dst[i] != actual_dst[i]) std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n"; - SASSERT(dst[i] == actual_dst[i]); + ENSURE(dst[i] == actual_dst[i]); } if (sz == src_sz) { unsigned nz1 = nlz(sz, src); @@ -52,7 +52,7 @@ static void tst_shl(unsigned src_sz, unsigned const * src, unsigned k, if (trace && src[i] != new_src[i]) { std::cout << "shr BUG, inverting shl, at bit[" << i << "], " << new_src[i] << ", expected: " << src[i] << std::endl; } - SASSERT(src[i] == new_src[i]); + ENSURE(src[i] == new_src[i]); } } } @@ -65,7 +65,7 @@ static void tst_shl(unsigned src_sz, unsigned const * src, unsigned k, for (unsigned i = 0; i < dst_sz; i++) { if (trace && dst[i] != actual_dst[i]) std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n"; - SASSERT(dst[i] == actual_dst[i]); + ENSURE(dst[i] == actual_dst[i]); } if (src_sz <= dst_sz) { if (trace) @@ -74,7 +74,7 @@ static void tst_shl(unsigned src_sz, unsigned const * src, unsigned k, for (unsigned i = 0; i < src_sz; i++) { if (trace && src[i] != dst[i]) std::cout << "UNEXPECTED RESULT at [" << i << "]: " << src[i] << ", expected: " << dst[i] << "\n"; - SASSERT(src[i] == actual_dst[i]); + ENSURE(src[i] == actual_dst[i]); } } } @@ -134,7 +134,7 @@ static void tst_shr(unsigned src_sz, unsigned const * src, unsigned k, for (unsigned i = 0; i < src_sz; i++) { if (trace && dst[i] != actual_dst[i]) std::cout << "UNEXPECTED RESULT at [" << i << "]: " << actual_dst[i] << ", expected: " << dst[i] << "\n"; - SASSERT(dst[i] == actual_dst[i]); + ENSURE(dst[i] == actual_dst[i]); } } @@ -172,7 +172,7 @@ static void tst_shl_rand(unsynch_mpz_manager & m, unsigned sz, unsigned k, bool m.mul2k(max, 32); while (!m.is_zero(_dst)) { m.mod(_dst, max, tmp); - SASSERT(m.is_uint64(tmp) && m.get_uint64(tmp) < UINT_MAX); + ENSURE(m.is_uint64(tmp) && m.get_uint64(tmp) < UINT_MAX); dst.push_back(static_cast(m.get_uint64(tmp))); m.div(_dst, max, _dst); } diff --git a/src/test/buffer.cpp b/src/test/buffer.cpp index a23fb3c74..f4b7f0c99 100644 --- a/src/test/buffer.cpp +++ b/src/test/buffer.cpp @@ -24,22 +24,22 @@ template class ptr_scoped_buffer; static void tst1() { ptr_scoped_buffer b; - SASSERT(b.empty()); + ENSURE(b.empty()); b.push_back(alloc(point, 10, 20)); - SASSERT(!b.empty()); + ENSURE(!b.empty()); point * p1 = alloc(point, 30, 20); b.push_back(p1); - SASSERT(b.get(1) == p1); + ENSURE(b.get(1) == p1); b.push_back(alloc(point, 40, 20)); - SASSERT(b.size() == 3); + ENSURE(b.size() == 3); b.pop_back(); - SASSERT(b.get(0) != p1); - SASSERT(b.get(1) == p1); + ENSURE(b.get(0) != p1); + ENSURE(b.get(1) == p1); point * p2 = alloc(point, 30, 20); - SASSERT(b.get(0) != p2); + ENSURE(b.get(0) != p2); b.set(0, p2); - SASSERT(b.get(0) == p2); - SASSERT(b.size() == 2); + ENSURE(b.get(0) == p2); + ENSURE(b.size() == 2); b.push_back(alloc(point, 40, 40)); } diff --git a/src/test/bv_simplifier_plugin.cpp b/src/test/bv_simplifier_plugin.cpp index 69b97a9cc..42952706b 100644 --- a/src/test/bv_simplifier_plugin.cpp +++ b/src/test/bv_simplifier_plugin.cpp @@ -30,7 +30,7 @@ class tst_bv_simplifier_plugin_cls { if (!m_bv_util.is_numeral(e, r, bv_size0)) { UNREACHABLE(); } - SASSERT(bv_size == bv_size0); + ENSURE(bv_size == bv_size0); } unsigned u32(expr* e) { @@ -109,26 +109,26 @@ public: ar = m_manager.mk_app(m_fid, OP_BNEG, e1.get()); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT((0-a) == u32(e.get())); + ENSURE((0-a) == u32(e.get())); ar = m_manager.mk_app(m_fid, OP_BNOT, e1.get()); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT((~a) == u32(e.get())); + ENSURE((~a) == u32(e.get())); parameter params[2] = { parameter(32), parameter(32) }; ar = m_manager.mk_app(m_fid, OP_SIGN_EXT, 1, params, 1, es); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT(((int64)(int)a) == i64(e.get())); + ENSURE(((int64)(int)a) == i64(e.get())); ar = m_manager.mk_app(m_fid, OP_ZERO_EXT, 1, params, 1, es); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT(((uint64)a) == u64(e.get())); + ENSURE(((uint64)a) == u64(e.get())); params[0] = parameter(7); params[1] = parameter(0); ar = m_manager.mk_app(m_fid, OP_EXTRACT, 2, params, 1, es); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT(((unsigned char)a) == u8(e.get())); + ENSURE(((unsigned char)a) == u8(e.get())); params[0] = parameter(2); ar = m_manager.mk_app(m_fid, OP_REPEAT, 1, params, 1, es); @@ -137,21 +137,21 @@ public: ar = m_manager.mk_app(m_fid, OP_BREDOR, e1.get()); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT((a != 0) == bit2bool(e.get())); + ENSURE((a != 0) == bit2bool(e.get())); ar = m_manager.mk_app(m_fid, OP_BREDAND, e1.get()); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT((a == 0xFFFFFFFF) == bit2bool(e.get())); + ENSURE((a == 0xFFFFFFFF) == bit2bool(e.get())); params[0] = parameter(8); ar = m_manager.mk_app(m_fid, OP_ROTATE_LEFT, 1, params, 1, es); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT(((a << 8) | (a >> 24)) == u32(e.get())); + ENSURE(((a << 8) | (a >> 24)) == u32(e.get())); ar = m_manager.mk_app(m_fid, OP_ROTATE_RIGHT, 1, params, 1, es); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT(((a >> 8) | (a << 24)) == u32(e.get())); + ENSURE(((a >> 8) | (a << 24)) == u32(e.get())); params[0] = parameter(m_manager.mk_sort(m_manager.mk_family_id("arith"), INT_SORT)); ar = m_manager.mk_app(m_fid, OP_BV2INT, 1, params, 1, es); @@ -159,7 +159,7 @@ public: params[0] = parameter(32); ar = m_manager.mk_app(m_fid, OP_INT2BV, 1, params, 1, es2); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - SASSERT(a == u32(e.get())); + ENSURE(a == u32(e.get())); ar = m_manager.mk_app(m_fid, OP_BIT0); m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); diff --git a/src/test/chashtable.cpp b/src/test/chashtable.cpp index 7d55fe01f..c9750b95e 100644 --- a/src/test/chashtable.cpp +++ b/src/test/chashtable.cpp @@ -37,16 +37,16 @@ static void display(T const & beg, T const & end) { static void tst1() { int_table t; t.insert(10); - SASSERT(t.contains(10)); + ENSURE(t.contains(10)); t.insert(20); - SASSERT(t.contains(20)); + ENSURE(t.contains(20)); t.insert(30); - SASSERT(t.contains(30)); - SASSERT(t.size() == 3); + ENSURE(t.contains(30)); + ENSURE(t.size() == 3); display(t.begin(), t.end()); t.erase(20); - SASSERT(!t.contains(20)); - SASSERT(t.size() == 2); + ENSURE(!t.contains(20)); + ENSURE(t.size() == 2); } struct dummy_hash { @@ -61,54 +61,54 @@ static void tst2() { dint_table t; t.insert(10); t.insert(12); - SASSERT(t.used_slots() == 1); + ENSURE(t.used_slots() == 1); display(t.begin(), t.end()); t.insert(13); display(t.begin(), t.end()); - SASSERT(t.used_slots() == 2); + ENSURE(t.used_slots() == 2); t.insert(14); - SASSERT(t.used_slots() == 2); - SASSERT(t.size() == 4); + ENSURE(t.used_slots() == 2); + ENSURE(t.size() == 4); display(t.begin(), t.end()); t.erase(12); - SASSERT(!t.contains(12)); - SASSERT(t.size() == 3); - SASSERT(t.contains(10)); - SASSERT(!t.contains(12)); - SASSERT(t.contains(14)); - SASSERT(t.contains(13)); + ENSURE(!t.contains(12)); + ENSURE(t.size() == 3); + ENSURE(t.contains(10)); + ENSURE(!t.contains(12)); + ENSURE(t.contains(14)); + ENSURE(t.contains(13)); t.insert(16); - SASSERT(t.size() == 4); + ENSURE(t.size() == 4); t.insert(18); - SASSERT(t.size() == 5); - SASSERT(t.used_slots() == 2); + ENSURE(t.size() == 5); + ENSURE(t.used_slots() == 2); display(t.begin(), t.end()); t.erase(10); display(t.begin(), t.end()); - SASSERT(!t.contains(10)); - SASSERT(!t.contains(12)); - SASSERT(t.contains(14)); - SASSERT(t.contains(13)); - SASSERT(t.contains(16)); - SASSERT(t.contains(18)); + ENSURE(!t.contains(10)); + ENSURE(!t.contains(12)); + ENSURE(t.contains(14)); + ENSURE(t.contains(13)); + ENSURE(t.contains(16)); + ENSURE(t.contains(18)); } static void tst3() { dint_table t; t.insert(10); t.insert(12); - SASSERT(t.used_slots() == 1); - SASSERT(t.contains(10)); - SASSERT(t.contains(12)); + ENSURE(t.used_slots() == 1); + ENSURE(t.contains(10)); + ENSURE(t.contains(12)); t.erase(12); t.erase(10); - SASSERT(t.size() == 0); - SASSERT(t.empty()); - SASSERT(t.used_slots() == 0); + ENSURE(t.size() == 0); + ENSURE(t.empty()); + ENSURE(t.used_slots() == 0); t.insert(10); - SASSERT(t.used_slots() == 1); - SASSERT(t.contains(10)); - SASSERT(t.size() == 1); + ENSURE(t.used_slots() == 1); + ENSURE(t.contains(10)); + ENSURE(t.size() == 1); } typedef int_hashtable > int_set; @@ -123,29 +123,29 @@ static void tst4(unsigned num, unsigned N) { TRACE("chashtable", tout << "erase " << v << "\n";); s.erase(v); t.erase(v); - SASSERT(!t.contains(v)); + ENSURE(!t.contains(v)); } else { TRACE("chashtable", tout << "insert " << v << "\n";); s.insert(v); t.insert(v); - SASSERT(t.contains(v)); + ENSURE(t.contains(v)); } - SASSERT(s.size() == t.size()); - SASSERT(s.empty() == t.empty()); + ENSURE(s.size() == t.size()); + ENSURE(s.empty() == t.empty()); } std::cout << "size: " << s.size() << " " << t.size() << "\n"; int_set::iterator it1 = s.begin(); int_set::iterator end1 = s.end(); for(; it1 != end1; ++it1) { - SASSERT(t.contains(*it1)); + ENSURE(t.contains(*it1)); } typename T::iterator it2 = t.begin(); typename T::iterator end2 = t.end(); for(; it2 != end2; ++it2) { - SASSERT(s.contains(*it2)); - SASSERT(t.contains(*it2)); + ENSURE(s.contains(*it2)); + ENSURE(t.contains(*it2)); } } @@ -164,10 +164,10 @@ static void tst5() { static void tst6() { int_map m; m.insert(10, 4); - SASSERT(m.contains(10)); + ENSURE(m.contains(10)); DEBUG_CODE({ int r; - SASSERT(m.find(10, r) && r == 4); + ENSURE(m.find(10, r) && r == 4); }); } diff --git a/src/test/diff_logic.cpp b/src/test/diff_logic.cpp index 70345c2d6..3a1ec198d 100644 --- a/src/test/diff_logic.cpp +++ b/src/test/diff_logic.cpp @@ -70,20 +70,20 @@ static void tst2() { g.init_var(3); g.init_var(4); smt::literal d; - SASSERT(g.enable_edge(g.add_edge(1, 2, rational(-1), l1))); - SASSERT(g.get_edge_weight(1, 2, w, d) && w == rational(-1)); - SASSERT(!g.get_edge_weight(2, 3, w, d)); - SASSERT(g.enable_edge(g.add_edge(2, 3, rational(-2), l2))); - SASSERT(g.enable_edge(g.add_edge(1, 4, rational(1), l3))); - SASSERT(g.get_edge_weight(1, 2, w, d) && w == rational(-1)); - SASSERT(g.get_edge_weight(1, 4, w, d) && w == rational(1)); - SASSERT(!g.get_edge_weight(1, 3, w, d)); - SASSERT(g.enable_edge(g.add_edge(2, 4, rational(10), l6))); - SASSERT(g.is_feasible()); + ENSURE(g.enable_edge(g.add_edge(1, 2, rational(-1), l1))); + ENSURE(g.get_edge_weight(1, 2, w, d) && w == rational(-1)); + ENSURE(!g.get_edge_weight(2, 3, w, d)); + ENSURE(g.enable_edge(g.add_edge(2, 3, rational(-2), l2))); + ENSURE(g.enable_edge(g.add_edge(1, 4, rational(1), l3))); + ENSURE(g.get_edge_weight(1, 2, w, d) && w == rational(-1)); + ENSURE(g.get_edge_weight(1, 4, w, d) && w == rational(1)); + ENSURE(!g.get_edge_weight(1, 3, w, d)); + ENSURE(g.enable_edge(g.add_edge(2, 4, rational(10), l6))); + ENSURE(g.is_feasible()); g.push(); - SASSERT(g.enable_edge(g.add_edge(3, 0, rational(2), l4))); - SASSERT(!g.enable_edge(g.add_edge(0, 1, rational(-1), l5))); - SASSERT(!g.is_feasible()); + ENSURE(g.enable_edge(g.add_edge(3, 0, rational(2), l4))); + ENSURE(!g.enable_edge(g.add_edge(0, 1, rational(-1), l5))); + ENSURE(!g.is_feasible()); TRACE("diff_logic", g.display(tout);); struct proc { svector found; @@ -96,22 +96,22 @@ static void tst2() { }; proc p; g.traverse_neg_cycle(true, p); - SASSERT(p.found[0] == false); - SASSERT(p.found[1] == true); - SASSERT(p.found[2] == true); - SASSERT(p.found[3] == false); - SASSERT(p.found[4] == true); - SASSERT(p.found[5] == true); - SASSERT(p.found[6] == false); + ENSURE(p.found[0] == false); + ENSURE(p.found[1] == true); + ENSURE(p.found[2] == true); + ENSURE(p.found[3] == false); + ENSURE(p.found[4] == true); + ENSURE(p.found[5] == true); + ENSURE(p.found[6] == false); g.pop(1); - SASSERT(g.is_feasible()); + ENSURE(g.is_feasible()); TRACE("diff_logic", g.display(tout);); } static int add_edge(dlg& g, dl_var src, dl_var dst, int weight, unsigned lit) { int id = g.add_edge(src, dst, rational(weight), smt::literal(lit)); bool ok = g.enable_edge(id); - SASSERT(ok); + ENSURE(ok); return id; } @@ -147,7 +147,7 @@ static void tst3() { for (unsigned i = 0; i < subsumed.size(); ++i) { std::cout << "subsumed: " << subsumed[i] << "\n"; - SASSERT(e38 == subsumed[i]); + ENSURE(e38 == subsumed[i]); tst_dl_functor tst_fn; diff --git a/src/test/dl_context.cpp b/src/test/dl_context.cpp index 8a62dcb7d..8d60cd883 100644 --- a/src/test/dl_context.cpp +++ b/src/test/dl_context.cpp @@ -51,12 +51,12 @@ static lbool dl_context_eval_unary_predicate(ast_manager & m, context & ctx, cha dealloc(p); func_decl * pred = ctx.try_get_predicate_decl(symbol(pred_name)); - SASSERT(pred); - SASSERT(pred->get_arity()==1); + ENSURE(pred); + ENSURE(pred->get_arity()==1); app_ref query_app(m.mk_app(pred, m.mk_var(0, pred->get_domain()[0])), m); lbool status = ctx.query(query_app); - SASSERT(status != l_undef); + ENSURE(status != l_undef); return status; } @@ -77,9 +77,9 @@ static void dl_context_simple_query_test(params_ref & params) { app_ref c_1(decl_util.mk_constant(1, res1->get_signature()[0]), m); relation_fact f(m); f.push_back(c_0); - SASSERT(res1->contains_fact(f)); + ENSURE(res1->contains_fact(f)); f[0]=c_1; - SASSERT(!res1->contains_fact(f)); + ENSURE(!res1->contains_fact(f)); #endif } diff --git a/src/test/dl_product_relation.cpp b/src/test/dl_product_relation.cpp index c375587fb..84ffd548a 100644 --- a/src/test/dl_product_relation.cpp +++ b/src/test/dl_product_relation.cpp @@ -37,12 +37,12 @@ namespace datalog { sparse_table_plugin & plugin = static_cast(*rctx.get_rmanager().get_table_plugin(symbol("sparse"))); - SASSERT(&plugin); + ENSURE(&plugin); table_signature sig2; sig2.push_back(2); sig2.push_back(2); sig2.set_functional_columns(1); - SASSERT(plugin.can_handle_signature(sig2)); + ENSURE(plugin.can_handle_signature(sig2)); table_fact f00; f00.push_back(0); @@ -56,32 +56,32 @@ namespace datalog { { table_aptr t0 = plugin.mk_empty(sig2); - SASSERT(t0->empty()); + ENSURE(t0->empty()); t0->add_fact(f00); - SASSERT(!t0->empty()); - SASSERT(t0->get_size_estimate_rows()==1); + ENSURE(!t0->empty()); + ENSURE(t0->get_size_estimate_rows()==1); t0->add_fact(f01); - SASSERT(t0->get_size_estimate_rows()==1); + ENSURE(t0->get_size_estimate_rows()==1); t0->add_fact(f11); - SASSERT(t0->get_size_estimate_rows()==2); + ENSURE(t0->get_size_estimate_rows()==2); unsigned rem_cols0[]={0}; scoped_ptr project0 = rmgr.mk_project_fn(*t0, 1, rem_cols0); table_aptr t1 = (*project0)(*t0); - SASSERT(t1->get_size_estimate_rows()==2); - SASSERT(t1->get_signature().functional_columns()==0); //project on non-functional column cancels functional + ENSURE(t1->get_size_estimate_rows()==2); + ENSURE(t1->get_signature().functional_columns()==0); //project on non-functional column cancels functional unsigned rem_cols1[]={1}; scoped_ptr project1 = rmgr.mk_project_fn(*t0, 1, rem_cols1); table_aptr t2 = (*project1)(*t0); - SASSERT(t2->get_size_estimate_rows()==2); + ENSURE(t2->get_size_estimate_rows()==2); idx_set acc; collector_of_reduced * reducer = alloc(collector_of_reduced, acc); scoped_ptr rproject = rmgr.mk_project_with_reduce_fn(*t0, 1, rem_cols0, reducer); table_aptr rt = (*rproject)(*t0); - SASSERT(acc.num_elems()==1); - SASSERT(rt->get_size_estimate_rows()==1); + ENSURE(acc.num_elems()==1); + ENSURE(rt->get_size_estimate_rows()==1); } { table_aptr t0 = plugin.mk_empty(sig2); @@ -90,44 +90,44 @@ namespace datalog { unsigned join_cols[]={1}; scoped_ptr join0 = rmgr.mk_join_fn(*t0, *t0, 1, join_cols, join_cols); table_aptr t1 = (*join0)(*t0, *t0); - SASSERT(t1->get_signature().size()==4); - SASSERT(t1->get_signature().functional_columns()==2); + ENSURE(t1->get_signature().size()==4); + ENSURE(t1->get_signature().functional_columns()==2); table_fact f0011; f0011.push_back(0); f0011.push_back(0); f0011.push_back(1); f0011.push_back(1); - SASSERT(t1->contains_fact(f0011)); + ENSURE(t1->contains_fact(f0011)); table_fact f0111 = f0011; f0111[1] = 1; - SASSERT(!t1->contains_fact(f0111)); + ENSURE(!t1->contains_fact(f0111)); } { table_aptr t0 = plugin.mk_empty(sig2); t0->display(std::cout<<"0:"); - SASSERT(t0->get_signature().functional_columns()==1); + ENSURE(t0->get_signature().functional_columns()==1); table_fact aux_fact; aux_fact = f01; TRUSTME( t0->suggest_fact(aux_fact) ); t0->display(std::cout<<"1:"); - SASSERT(t0->contains_fact(f01)); - SASSERT(aux_fact[1]==1); + ENSURE(t0->contains_fact(f01)); + ENSURE(aux_fact[1]==1); aux_fact = f00; TRUSTME( !t0->suggest_fact(aux_fact) ); t0->display(std::cout<<"2:"); - SASSERT(t0->contains_fact(f01)); - SASSERT(!t0->contains_fact(f00)); - SASSERT(aux_fact[1]==1); + ENSURE(t0->contains_fact(f01)); + ENSURE(!t0->contains_fact(f00)); + ENSURE(aux_fact[1]==1); t0->ensure_fact(f00); t0->display(std::cout<<"3:"); - SASSERT(t0->contains_fact(f00)); - SASSERT(!t0->contains_fact(f01)); + ENSURE(t0->contains_fact(f00)); + ENSURE(!t0->contains_fact(f01)); } } @@ -140,7 +140,7 @@ namespace datalog { relation_manager & rmgr = ctx.get_rel_context()->get_rmanager(); relation_plugin & rel_plugin = *rmgr.get_relation_plugin(params.get_sym("default_relation", symbol("sparse"))); - SASSERT(&rel_plugin); + ENSURE(&rel_plugin); finite_product_relation_plugin plg(rel_plugin, rmgr); sort_ref byte_srt_ref(dl_util.mk_sort(symbol("BYTE"), 256), m); @@ -194,9 +194,9 @@ namespace datalog { scoped_rel r2 = r1->clone(); scoped_rel r3 = r2->clone(); - SASSERT(!r1->contains_fact(f77)); + ENSURE(!r1->contains_fact(f77)); r1->add_fact(f77); - SASSERT(r1->contains_fact(f77)); + ENSURE(r1->contains_fact(f77)); r2->add_fact(f79); r3->add_fact(f99); @@ -207,34 +207,34 @@ namespace datalog { r2->display( std::cout << "r2 1\n"); r4->display( std::cout << "r4 0\n"); - SASSERT(!r4->contains_fact(f77)); - SASSERT(r4->contains_fact(f79)); + ENSURE(!r4->contains_fact(f77)); + ENSURE(r4->contains_fact(f79)); r4->add_fact(f77); r4->display( std::cout << "r4 1\n"); - SASSERT(r4->contains_fact(f77)); - SASSERT(r4->contains_fact(f79)); + ENSURE(r4->contains_fact(f77)); + ENSURE(r4->contains_fact(f79)); r4->add_fact(f99); r4->display( std::cout << "r4 2\n"); - SASSERT(r4->contains_fact(f99)); + ENSURE(r4->contains_fact(f99)); std::cout << "------ testing union ------\n"; r2->display( std::cout << "r2\n"); scoped_ptr union_op = rmgr.mk_union_fn(*r1, *r2, r3.get()); - SASSERT(union_op); + ENSURE(union_op); (*union_op)(*r1, *r2, r3.get()); r1->display( std::cout << "r1\n"); r2->display( std::cout << "r2\n"); r3->display( std::cout << "r3\n"); - SASSERT(r1->contains_fact(f77)); - SASSERT(r1->contains_fact(f79)); - SASSERT(!r1->contains_fact(f99)); + ENSURE(r1->contains_fact(f77)); + ENSURE(r1->contains_fact(f79)); + ENSURE(!r1->contains_fact(f99)); - SASSERT(!r3->contains_fact(f77)); - SASSERT(r3->contains_fact(f79)); - SASSERT(r3->contains_fact(f99)); + ENSURE(!r3->contains_fact(f77)); + ENSURE(r3->contains_fact(f79)); + ENSURE(r3->contains_fact(f99)); std::cout << "------ testing join ------\n"; @@ -264,9 +264,9 @@ namespace datalog { jr_rr->display( std::cout << "rr\n"); - SASSERT(!jr_tt->contains_fact(f7797)); - SASSERT(jr_tr->contains_fact(f7797)); - SASSERT(jr_rr->contains_fact(f7797)); + ENSURE(!jr_tt->contains_fact(f7797)); + ENSURE(jr_tr->contains_fact(f7797)); + ENSURE(jr_rr->contains_fact(f7797)); std::cout << "------ testing project ------\n"; @@ -288,17 +288,17 @@ namespace datalog { scoped_rel sr_2r = (*proj_2r)(*r31); scoped_rel sr_1t = (*proj_1t)(*r31); - SASSERT(sr_1r->contains_fact(f79)); - SASSERT(sr_1r->contains_fact(f97)); - SASSERT(!sr_1r->contains_fact(f77)); + ENSURE(sr_1r->contains_fact(f79)); + ENSURE(sr_1r->contains_fact(f97)); + ENSURE(!sr_1r->contains_fact(f77)); - SASSERT(sr_2r->contains_fact(f7)); - SASSERT(sr_2r->contains_fact(f9)); + ENSURE(sr_2r->contains_fact(f7)); + ENSURE(sr_2r->contains_fact(f9)); - SASSERT(sr_1t->contains_fact(f79)); - SASSERT(!sr_1t->contains_fact(f97)); - SASSERT(sr_1t->contains_fact(f77)); - SASSERT(sr_1t->contains_fact(f99)); + ENSURE(sr_1t->contains_fact(f79)); + ENSURE(!sr_1t->contains_fact(f97)); + ENSURE(sr_1t->contains_fact(f77)); + ENSURE(sr_1t->contains_fact(f99)); std::cout << "------ testing filter_interpreted ------\n"; @@ -314,8 +314,8 @@ namespace datalog { scoped_ptr i_filter = rmgr.mk_filter_interpreted_fn(*r41, cond); (*i_filter)(*r41); - SASSERT(r41->contains_fact(f7797)); - SASSERT(!r41->contains_fact(f7997)); + ENSURE(r41->contains_fact(f7797)); + ENSURE(!r41->contains_fact(f7997)); std::cout << "------ testing filter_by_negation ------\n"; @@ -334,9 +334,9 @@ namespace datalog { nf_r31_cols, nf_r1_cols); (*neg_filter)(*r31, *r1); - SASSERT(!r31->contains_fact(f779)); - SASSERT(r31->contains_fact(f977)); - SASSERT(r31->contains_fact(f799)); + ENSURE(!r31->contains_fact(f779)); + ENSURE(r31->contains_fact(f977)); + ENSURE(r31->contains_fact(f799)); } diff --git a/src/test/dl_query.cpp b/src/test/dl_query.cpp index e69f1fb13..eaa26cdbb 100644 --- a/src/test/dl_query.cpp +++ b/src/test/dl_query.cpp @@ -23,7 +23,7 @@ void dl_query_ask_ground_query(context & ctx, func_decl * pred, relation_fact & lbool is_sat = ctx.query(query); std::cerr << "@@ query should succeed: " << should_be_successful << "\n"; - SASSERT(is_sat != l_undef); + ENSURE(is_sat != l_undef); if((is_sat != l_true) == should_be_successful) { std::cerr<<"wrong ground query answer!\n"; UNREACHABLE(); @@ -80,13 +80,13 @@ void dl_query_test(ast_manager & m, smt_params & fparams, params_ref& params, func_decl * pred_b = *it; std::cerr << "Checking queries on relation " << pred_b->get_name() << "\n"; func_decl * pred_q = ctx_q.try_get_predicate_decl(symbol(pred_b->get_name().bare_str())); - SASSERT(pred_q); + ENSURE(pred_q); relation_base & rel_b = ctx_b.get_rel_context()->get_relation(pred_b); relation_signature sig_b = rel_b.get_signature(); relation_signature sig_q = ctx_q.get_rel_context()->get_relation(pred_q).get_signature(); - SASSERT(sig_b.size()==sig_q.size()); + ENSURE(sig_b.size()==sig_q.size()); std::cerr << "Queries on random facts...\n"; relation_fact f_b(m); @@ -164,7 +164,7 @@ void dl_query_test_wpa(smt_params & fparams, params_ref& params) { const unsigned attempts = 10; func_decl * v_pred = ctx.try_get_predicate_decl(symbol("V")); - SASSERT(v_pred); + ENSURE(v_pred); sort * var_sort = v_pred->get_domain(0); uint64 var_sz; @@ -180,7 +180,7 @@ void dl_query_test_wpa(smt_params & fparams, params_ref& params) { app_ref query_lit(m.mk_app(v_pred, q_args.c_ptr()), m); lbool is_sat = ctx.query(query_lit); - SASSERT(is_sat != l_undef); + ENSURE(is_sat != l_undef); bool found = is_sat == l_true; std::cerr<<"query finished: "<get_rmanager(); m.register_plugin(alloc(interval_relation_plugin, m)); interval_relation_plugin& ip = dynamic_cast(*m.get_relation_plugin(symbol("interval_relation"))); - SASSERT(&ip); + ENSURE(&ip); relation_signature sig; sort* int_sort = autil.mk_int(); @@ -38,8 +38,8 @@ namespace datalog { i1.display(std::cout); i2.display(std::cout); - SASSERT(i1.empty()); - SASSERT(!i2.empty()); + ENSURE(i1.empty()); + ENSURE(!i2.empty()); app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m); app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m); @@ -84,11 +84,11 @@ namespace datalog { fact1.push_back(autil.mk_numeral(rational(4), true)); fact1.push_back(autil.mk_numeral(rational(4), true)); fact1.push_back(autil.mk_numeral(rational(5), true)); - SASSERT(i2.contains_fact(fact1)); + ENSURE(i2.contains_fact(fact1)); fact1[0] = autil.mk_numeral(rational(-1), true); - SASSERT(i2.contains_fact(fact1)); + ENSURE(i2.contains_fact(fact1)); fact1[0] = autil.mk_numeral(rational(1), true); - SASSERT(!i2.contains_fact(fact1)); + ENSURE(!i2.contains_fact(fact1)); relation_base* i5 = (*ren1)(i2); i2.display(std::cout << "Orig\n"); @@ -97,7 +97,7 @@ namespace datalog { (*filterCond1)(i2); i2.display(std::cout); // empty - SASSERT(i2.empty()); + ENSURE(i2.empty()); relation_base* i4 = (*proj2)(*i3); i4->display(std::cout); @@ -128,7 +128,7 @@ namespace datalog { relation_manager & m = ctx.get_rel_context()->get_rmanager(); m.register_plugin(alloc(bound_relation_plugin, m)); bound_relation_plugin& br = dynamic_cast(*m.get_relation_plugin(symbol("bound_relation"))); - SASSERT(&br); + ENSURE(&br); relation_signature sig; sort* int_sort = autil.mk_int(); @@ -142,8 +142,8 @@ namespace datalog { i1.display(std::cout << "empty:\n"); i2.display(std::cout << "full:\n"); - SASSERT(i1.empty()); - SASSERT(!i2.empty()); + ENSURE(i1.empty()); + ENSURE(!i2.empty()); app_ref cond1(ast_m), cond2(ast_m), cond3(ast_m); app_ref cond4(ast_m), cond5(ast_m), cond6(ast_m); @@ -201,7 +201,7 @@ namespace datalog { relation_base* i5 = (*ren1)(i2); i5->display(std::cout); - //SASSERT(i2.empty()); + //ENSURE(i2.empty()); relation_base* i4 = (*proj2)(*i3); i4->display(std::cout); diff --git a/src/test/dl_table.cpp b/src/test/dl_table.cpp index 62eec34bc..f9ccb3116 100644 --- a/src/test/dl_table.cpp +++ b/src/test/dl_table.cpp @@ -12,7 +12,7 @@ typedef datalog::table_base* (*mk_table_fn)(datalog::relation_manager& m, datalo static datalog::table_base* mk_bv_table(datalog::relation_manager& m, datalog::table_signature& sig) { datalog::table_plugin * p = m.get_table_plugin(symbol("bitvector")); - SASSERT(p); + ENSURE(p); return p->mk_empty(sig); } @@ -57,12 +57,12 @@ static void test_table(mk_table_fn mk_table) { std::cout << "\n"; } - SASSERT(table.contains_fact(row1)); - SASSERT(table.contains_fact(row2)); - SASSERT(!table.contains_fact(row3)); + ENSURE(table.contains_fact(row1)); + ENSURE(table.contains_fact(row2)); + ENSURE(!table.contains_fact(row3)); #if 0 table.remove_facts(1, &row1); - SASSERT(!table.contains_fact(row1)); + ENSURE(!table.contains_fact(row1)); #endif table.add_fact(row1); diff --git a/src/test/dl_util.cpp b/src/test/dl_util.cpp index 02e40bbd9..44b95934e 100644 --- a/src/test/dl_util.cpp +++ b/src/test/dl_util.cpp @@ -22,7 +22,7 @@ void dl_util_two_array_sort() { datalog::sort_two_arrays(num, a1, a2); for(unsigned i=0; i result; // VERIFY(!m.intersect(*d1,*d0, result)); // m.subtract(*d1,*d0, result); - SASSERT(result.empty()); + ENSURE(result.empty()); dX = m.allocateX(); m.display(std::cout, *d0) << "\n"; m.display(std::cout, *dX) << "\n"; - SASSERT(m.contains(*dX,*d1)); - SASSERT(m.contains(*dX,*d0)); - SASSERT(!m.contains(*d0,*d1)); - SASSERT(!m.contains(*d1,*d0)); + ENSURE(m.contains(*dX,*d1)); + ENSURE(m.contains(*dX,*d0)); + ENSURE(!m.contains(*d0,*d1)); + ENSURE(!m.contains(*d1,*d0)); d1->neg().push_back(m.tbvm().allocate0()); @@ -88,14 +88,14 @@ static void tst_doc1(unsigned n) { doc_ref d1_2(m1, m1.allocate1()); m.display(std::cout, *d1) << " -> "; m1.display(std::cout, *d1_1) << "\n"; - SASSERT(m1.equals(*d1_1,*d1_2)); + ENSURE(m1.equals(*d1_1,*d1_2)); m.set(*d1,2,BIT_x); m.set(*d1,4,BIT_x); d1_1 = m.project(m1, to_delete, *d1); m.display(std::cout, *d1) << " -> "; m1.display(std::cout, *d1_1) << "\n"; d1->neg().push_back(m.tbvm().allocate1()); - SASSERT(m.well_formed(*d1)); + ENSURE(m.well_formed(*d1)); d1_1 = m.project(m1, to_delete, *d1); m.display(std::cout, *d1) << " -> "; m1.display(std::cout, *d1_1) << "\n"; @@ -146,11 +146,11 @@ class test_doc_cls { tbv_ref t(dm.tbvm()); t = mk_rand_tbv(); doc* result = dm.allocate(*t); - SASSERT(dm.tbvm().equals(*t, result->pos())); + ENSURE(dm.tbvm().equals(*t, result->pos())); for (unsigned i = 0; i < num_diff; ++i) { result->neg().push_back(mk_rand_tbv(result->pos())); } - SASSERT(dm.well_formed(*result)); + ENSURE(dm.well_formed(*result)); return result; } @@ -181,7 +181,7 @@ class test_doc_cls { expr_ref result(m); expr_ref_vector conjs(m); unsigned n = m2.num_tbits(); - SASSERT(n <= m_vars.size()); + ENSURE(n <= m_vars.size()); for (unsigned i = 0; i < n; ++i) { switch (t[i]) { case BIT_x: @@ -347,7 +347,7 @@ class test_doc_cls { tout << mk_pp(fml2, m) << "\n"; ); } - SASSERT(res == l_false); + ENSURE(res == l_false); } @@ -464,7 +464,7 @@ public: d2.display(dm, tout) << "\n";); d1.intersect(dm, d2); TRACE("doc", d1.display(dm, tout) << "\n";); - SASSERT(d1.well_formed(dm)); + ENSURE(d1.well_formed(dm)); fml3 = to_formula(d1, dm); fml1 = m.mk_and(fml1, fml2); check_equiv(fml1, fml3); diff --git a/src/test/ext_numeral.cpp b/src/test/ext_numeral.cpp index 6f92b1372..a35af1ba6 100644 --- a/src/test/ext_numeral.cpp +++ b/src/test/ext_numeral.cpp @@ -26,11 +26,11 @@ static void tst_ ## NAME(int a, ext_numeral_kind ak, int expected_c, ext_numeral scoped_mpq _a(m); \ m.set(_a, a); \ NAME(m, _a, ak); \ - SASSERT(ak == expected_ck); \ + ENSURE(ak == expected_ck); \ if (expected_ck == EN_NUMERAL) { \ scoped_mpq _expected_c(m); \ m.set(_expected_c, expected_c); \ - SASSERT(m.eq(_a, _expected_c)); \ + ENSURE(m.eq(_a, _expected_c)); \ } \ } @@ -45,11 +45,11 @@ static void FUN_NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, int m.set(_b, b); \ ext_numeral_kind ck; \ OP_NAME(m, _a, ak, _b, bk, _c, ck); \ - SASSERT(ck == expected_ck); \ + ENSURE(ck == expected_ck); \ if (expected_ck == EN_NUMERAL) { \ scoped_mpq _expected_c(m); \ m.set(_expected_c, expected_c); \ - SASSERT(m.eq(_c, _expected_c)); \ + ENSURE(m.eq(_c, _expected_c)); \ } \ } @@ -340,52 +340,52 @@ static void tst2() { static void tst3() { unsynch_mpq_manager m; scoped_mpq a(m); - SASSERT(is_zero(m, a, EN_NUMERAL)); - SASSERT(!is_zero(m, a, EN_PLUS_INFINITY)); - SASSERT(!is_zero(m, a, EN_MINUS_INFINITY)); - SASSERT(!is_pos(m, a, EN_NUMERAL)); - SASSERT(is_pos(m, a, EN_PLUS_INFINITY)); - SASSERT(!is_pos(m, a, EN_MINUS_INFINITY)); - SASSERT(!is_infinite(EN_NUMERAL)); - SASSERT(is_infinite(EN_PLUS_INFINITY)); - SASSERT(is_infinite(EN_MINUS_INFINITY)); - SASSERT(!is_neg(m, a, EN_NUMERAL)); - SASSERT(!is_neg(m, a, EN_PLUS_INFINITY)); - SASSERT(is_neg(m, a, EN_MINUS_INFINITY)); + ENSURE(is_zero(m, a, EN_NUMERAL)); + ENSURE(!is_zero(m, a, EN_PLUS_INFINITY)); + ENSURE(!is_zero(m, a, EN_MINUS_INFINITY)); + ENSURE(!is_pos(m, a, EN_NUMERAL)); + ENSURE(is_pos(m, a, EN_PLUS_INFINITY)); + ENSURE(!is_pos(m, a, EN_MINUS_INFINITY)); + ENSURE(!is_infinite(EN_NUMERAL)); + ENSURE(is_infinite(EN_PLUS_INFINITY)); + ENSURE(is_infinite(EN_MINUS_INFINITY)); + ENSURE(!is_neg(m, a, EN_NUMERAL)); + ENSURE(!is_neg(m, a, EN_PLUS_INFINITY)); + ENSURE(is_neg(m, a, EN_MINUS_INFINITY)); m.set(a, 10); - SASSERT(!is_zero(m, a, EN_NUMERAL)); - SASSERT(is_pos(m, a, EN_NUMERAL)); - SASSERT(!is_neg(m, a, EN_NUMERAL)); - SASSERT(!is_infinite(EN_NUMERAL)); + ENSURE(!is_zero(m, a, EN_NUMERAL)); + ENSURE(is_pos(m, a, EN_NUMERAL)); + ENSURE(!is_neg(m, a, EN_NUMERAL)); + ENSURE(!is_infinite(EN_NUMERAL)); m.set(a, -5); - SASSERT(!is_zero(m, a, EN_NUMERAL)); - SASSERT(!is_pos(m, a, EN_NUMERAL)); - SASSERT(is_neg(m, a, EN_NUMERAL)); - SASSERT(!is_infinite(EN_NUMERAL)); + ENSURE(!is_zero(m, a, EN_NUMERAL)); + ENSURE(!is_pos(m, a, EN_NUMERAL)); + ENSURE(is_neg(m, a, EN_NUMERAL)); + ENSURE(!is_infinite(EN_NUMERAL)); ext_numeral_kind ak; ak = EN_MINUS_INFINITY; reset(m, a, ak); - SASSERT(is_zero(m, a, EN_NUMERAL)); + ENSURE(is_zero(m, a, EN_NUMERAL)); { std::ostringstream buffer; display(buffer, m, a, ak); - SASSERT(buffer.str() == "0"); + ENSURE(buffer.str() == "0"); } { std::ostringstream buffer; m.set(a, -10); display(buffer, m, a, ak); - SASSERT(buffer.str() == "-10"); + ENSURE(buffer.str() == "-10"); } { std::ostringstream buffer; display(buffer, m, a, EN_PLUS_INFINITY); - SASSERT(buffer.str() == "+oo"); + ENSURE(buffer.str() == "+oo"); } { std::ostringstream buffer; display(buffer, m, a, EN_MINUS_INFINITY); - SASSERT(buffer.str() == "-oo"); + ENSURE(buffer.str() == "-oo"); } } diff --git a/src/test/fixed_bit_vector.cpp b/src/test/fixed_bit_vector.cpp index 7bd9e62c3..0160fe574 100644 --- a/src/test/fixed_bit_vector.cpp +++ b/src/test/fixed_bit_vector.cpp @@ -31,11 +31,11 @@ static void tst1() { m.set(*b, 0, true); m.set(*b, 1, false); m.set(*b, 2, true); - SASSERT(b->get(0) == true); - SASSERT(b->get(1) == false); - SASSERT(b->get(2) == true); - SASSERT(b->get(3) == false); - SASSERT(b->get(29) == false); + ENSURE(b->get(0) == true); + ENSURE(b->get(1) == false); + ENSURE(b->get(2) == true); + ENSURE(b->get(3) == false); + ENSURE(b->get(29) == false); m.deallocate(b); } @@ -55,11 +55,11 @@ static void tst_or() { m.display(std::cout, *b2) << "\n"; m.set_or(*b1, *b2); m.display(std::cout, *b1) << "\n"; - SASSERT(!m.equals(*b1, *b2)); + ENSURE(!m.equals(*b1, *b2)); m.unset(*b1, 4); - SASSERT(m.equals(*b1, *b2)); + ENSURE(m.equals(*b1, *b2)); m.unset(*b1, 3); - SASSERT(!m.equals(*b1, *b2)); + ENSURE(!m.equals(*b1, *b2)); m.deallocate(b1); m.deallocate(b2); } @@ -78,25 +78,25 @@ static void tst_eq(unsigned num_bits) { fixed_bit_vector* b3 = m.allocate0(); m.set(*b1, 3, true); - SASSERT(!m.equals(*b1, *b2)); - SASSERT(m.equals(*b2, *b3)); + ENSURE(!m.equals(*b1, *b2)); + ENSURE(m.equals(*b2, *b3)); m.set(*b3, 3, true); - SASSERT(m.equals(*b1, *b3)); + ENSURE(m.equals(*b1, *b3)); m.set(*b2, num_bits-1, true); m.set(*b3, num_bits-1); m.unset(*b3, 3); - SASSERT(m.equals(*b2, *b3)); + ENSURE(m.equals(*b2, *b3)); m.fill0(*b1); m.set_neg(*b1); m.fill1(*b2); - SASSERT(m.equals(*b1, *b2)); + ENSURE(m.equals(*b1, *b2)); m.fill0(*b1); for (unsigned i = 0; i < num_bits; ++i) { m.set(*b1, i, true); } - SASSERT(m.equals(*b1, *b2)); + ENSURE(m.equals(*b1, *b2)); m.deallocate(b1); m.deallocate(b2); m.deallocate(b3); diff --git a/src/test/get_consequences.cpp b/src/test/get_consequences.cpp index f7da4edd7..029a13881 100644 --- a/src/test/get_consequences.cpp +++ b/src/test/get_consequences.cpp @@ -104,7 +104,7 @@ void test2() { VERIFY(l_true == fd_solver->check_sat(0,0)); fd_solver->get_model(mr); - SASSERT(mr.get()); + ENSURE(mr.get()); model_smt2_pp(std::cout, m, *mr.get(), 0); } diff --git a/src/test/get_implied_equalities.cpp b/src/test/get_implied_equalities.cpp index 37fbe2004..8ddcdb1e9 100644 --- a/src/test/get_implied_equalities.cpp +++ b/src/test/get_implied_equalities.cpp @@ -47,13 +47,13 @@ static void tst_get_implied_equalities1() { for (i = 0; i < num_terms; ++i) { printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); } - SASSERT(class_ids[1] == class_ids[0]); - SASSERT(class_ids[2] != class_ids[0]); - SASSERT(class_ids[3] == class_ids[0]); - SASSERT(class_ids[4] != class_ids[0]); - SASSERT(class_ids[5] != class_ids[0]); - SASSERT(class_ids[6] != class_ids[0]); - SASSERT(class_ids[4] == class_ids[5]); + ENSURE(class_ids[1] == class_ids[0]); + ENSURE(class_ids[2] != class_ids[0]); + ENSURE(class_ids[3] == class_ids[0]); + ENSURE(class_ids[4] != class_ids[0]); + ENSURE(class_ids[5] != class_ids[0]); + ENSURE(class_ids[6] != class_ids[0]); + ENSURE(class_ids[4] == class_ids[5]); printf("asserting b <= f(a)\n"); Z3_solver_assert(ctx, solver, Z3_mk_le(ctx, b, fa)); @@ -61,12 +61,12 @@ static void tst_get_implied_equalities1() { for (i = 0; i < num_terms; ++i) { printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); } - SASSERT(class_ids[1] == class_ids[0]); - SASSERT(class_ids[2] != class_ids[0]); - SASSERT(class_ids[3] == class_ids[0]); - SASSERT(class_ids[4] == class_ids[0]); - SASSERT(class_ids[5] == class_ids[0]); - SASSERT(class_ids[6] == class_ids[0]); + ENSURE(class_ids[1] == class_ids[0]); + ENSURE(class_ids[2] != class_ids[0]); + ENSURE(class_ids[3] == class_ids[0]); + ENSURE(class_ids[4] == class_ids[0]); + ENSURE(class_ids[5] == class_ids[0]); + ENSURE(class_ids[6] == class_ids[0]); Z3_solver_dec_ref(ctx, solver); @@ -103,15 +103,15 @@ static void tst_get_implied_equalities2() { printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); } - SASSERT(class_ids[1] != class_ids[0]); - SASSERT(class_ids[2] != class_ids[0]); - SASSERT(class_ids[3] != class_ids[0]); - SASSERT(class_ids[4] != class_ids[0]); - SASSERT(class_ids[4] == class_ids[2]); - SASSERT(class_ids[2] != class_ids[1]); - SASSERT(class_ids[3] != class_ids[1]); - SASSERT(class_ids[4] != class_ids[1]); - SASSERT(class_ids[3] != class_ids[2]); + ENSURE(class_ids[1] != class_ids[0]); + ENSURE(class_ids[2] != class_ids[0]); + ENSURE(class_ids[3] != class_ids[0]); + ENSURE(class_ids[4] != class_ids[0]); + ENSURE(class_ids[4] == class_ids[2]); + ENSURE(class_ids[2] != class_ids[1]); + ENSURE(class_ids[3] != class_ids[1]); + ENSURE(class_ids[4] != class_ids[1]); + ENSURE(class_ids[3] != class_ids[2]); /* delete logical context */ Z3_solver_dec_ref(ctx, solver); diff --git a/src/test/hashtable.cpp b/src/test/hashtable.cpp index 47fae454a..0290ac161 100644 --- a/src/test/hashtable.cpp +++ b/src/test/hashtable.cpp @@ -23,10 +23,6 @@ Revision History: #include"hashtable.h" -#ifndef Z3DEBUG -#undef SASSERT -#define SASSERT(COND) { if (!(COND)) std::cerr << "ERROR: " << #COND << "\n"; } ((void) 0) -#endif struct int_hash_proc { unsigned operator()(int x) const { return x * 3; } }; typedef int_hashtable > int_set; @@ -48,16 +44,16 @@ static void tst1() { int v = rand() % (N / 2); h1.insert(v); vals[i] = v; - SASSERT(contains(h1, v)); + ENSURE(contains(h1, v)); } std::cout << "step1\n"; std::cout.flush(); for (int i = 1; i < N; i ++) { - SASSERT(contains(h1, vals[i])); + ENSURE(contains(h1, vals[i])); } std::cout << "step2\n"; std::cout.flush(); for (int i = 1; i < N; i += 2) { h1.erase(vals[i]); - SASSERT(!contains(h1, vals[i])); + ENSURE(!contains(h1, vals[i])); } std::cout << "step3\n"; std::cout.flush(); for (int i = 1; i < N; i += 2) { @@ -65,7 +61,7 @@ static void tst1() { } std::cout << "step4\n"; std::cout.flush(); for (int i = 1; i < N; i ++) { - SASSERT(contains(h1, vals[i])); + ENSURE(contains(h1, vals[i])); } } @@ -78,19 +74,19 @@ static void tst2() { if (rand() % 3 == 2) { h1.erase(v); h2.erase(v); - SASSERT(!contains(h1, v)); + ENSURE(!contains(h1, v)); } else { h1.insert(v); h2.insert(v); - SASSERT(contains(h1, v)); + ENSURE(contains(h1, v)); } } { safe_int_set::iterator it = h2.begin(); safe_int_set::iterator end = h2.end(); for(; it != end; ++it) { - SASSERT(contains(h1, *it)); + ENSURE(contains(h1, *it)); } } { @@ -98,12 +94,12 @@ static void tst2() { int_set::iterator end = h1.end(); int n = 0; for (; it != end; ++it) { - SASSERT(contains(h1, *it)); + ENSURE(contains(h1, *it)); n++; } - SASSERT(n == h1.size()); + ENSURE(n == h1.size()); } - SASSERT(h1.size() == h2.size()); + ENSURE(h1.size() == h2.size()); // std::cout << "size: " << h1.size() << ", capacity: " << h1.capacity() << "\n"; std::cout.flush(); } @@ -114,13 +110,13 @@ static void tst3() { h1.insert(30); h1.erase(20); int_set h2(h1); - SASSERT(h1.contains(10)); - SASSERT(!h1.contains(20)); - SASSERT(h1.contains(30)); - SASSERT(h2.contains(10)); - SASSERT(!h2.contains(20)); - SASSERT(h2.contains(30)); - SASSERT(h2.size() == 2); + ENSURE(h1.contains(10)); + ENSURE(!h1.contains(20)); + ENSURE(h1.contains(30)); + ENSURE(h2.contains(10)); + ENSURE(!h2.contains(20)); + ENSURE(h2.contains(30)); + ENSURE(h2.size() == 2); } void tst_hashtable() { diff --git a/src/test/heap.cpp b/src/test/heap.cpp index 17f9cfaa0..6f827b5e8 100644 --- a/src/test/heap.cpp +++ b/src/test/heap.cpp @@ -33,33 +33,33 @@ static void tst1() { for (int i = 0; i < N * 3; i++) { int val = rand() % N; if (!h.contains(val)) { - SASSERT(!t.contains(val)); + ENSURE(!t.contains(val)); h.insert(val); t.insert(val); } else { - SASSERT(t.contains(val)); + ENSURE(t.contains(val)); } } - SASSERT(h.check_invariant()); + ENSURE(h.check_invariant()); int_set::iterator it = t.begin(); int_set::iterator end = t.end(); for (; it != end; ++it) { - SASSERT(h.contains(*it)); + ENSURE(h.contains(*it)); } while (!h.empty()) { int m1 = h.min_value(); int m2 = h.erase_min(); (void)m1; (void)m2; - SASSERT(m1 == m2); - SASSERT(-1 < m2); + ENSURE(m1 == m2); + ENSURE(-1 < m2); } } int g_value[N]; -struct lt_proc2 { bool operator()(int v1, int v2) const { SASSERT(v1 < N && v2 < N); return g_value[v1] < g_value[v2]; } }; +struct lt_proc2 { bool operator()(int v1, int v2) const { ENSURE(v1 < N && v2 < N); return g_value[v1] < g_value[v2]; } }; typedef heap int_heap2; static void init_values() { @@ -89,7 +89,7 @@ static void tst2() { TRACE("heap", tout << "inserting: " << val << "\n";); h.insert(val); TRACE("heap", dump_heap(h, tout);); - SASSERT(h.contains(val)); + ENSURE(h.contains(val)); } } else if (cmd <= 6) { @@ -98,7 +98,7 @@ static void tst2() { TRACE("heap", tout << "removing: " << val << "\n";); h.erase(val); TRACE("heap", dump_heap(h, tout);); - SASSERT(!h.contains(val)); + ENSURE(!h.contains(val)); } } else if (cmd <= 8) { @@ -119,10 +119,10 @@ static void tst2() { } } else { - SASSERT(h.check_invariant()); + ENSURE(h.check_invariant()); } } - SASSERT(h.check_invariant()); + ENSURE(h.check_invariant()); } void tst_heap() { diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index b46ede849..f2ca8a375 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -286,8 +286,8 @@ static void gorrila_test(unsigned seed, unsigned n, unsigned k, unsigned bound, random_gen rand(seed); reslimit rl; hilbert_basis hb(rl); - SASSERT(0 < bound); - SASSERT(k <= n); + ENSURE(0 < bound); + ENSURE(k <= n); int ibound = static_cast(bound); for (unsigned i = 0; i < num_ineqs; ++i) { vector nv; diff --git a/src/test/hwf.cpp b/src/test/hwf.cpp index 7a030a452..310d69be2 100644 --- a/src/test/hwf.cpp +++ b/src/test/hwf.cpp @@ -25,16 +25,16 @@ static void bug_set_double() { hwf a; m.set(a, 0.1); - SASSERT(m.is_regular(a)); + ENSURE(m.is_regular(a)); m.set(a, 1.1); - SASSERT(m.is_regular(a)); + ENSURE(m.is_regular(a)); m.set(a, 11.3); - SASSERT(m.is_regular(a)); + ENSURE(m.is_regular(a)); m.set(a, 0.0); - SASSERT(m.is_regular(a)); + ENSURE(m.is_regular(a)); } static void bug_to_rational() { @@ -62,31 +62,31 @@ static void bug_to_rational() { m.to_rational(a, r); ad = m.to_double(a); rd = mq.get_double(r); - SASSERT(ad == rd); + ENSURE(ad == rd); m.set(a, 0.875); m.to_rational(a, r); ad = m.to_double(a); rd = mq.get_double(r); - SASSERT(ad == rd); + ENSURE(ad == rd); m.set(a, -1.0); m.to_rational(a, r); ad = m.to_double(a); rd = mq.get_double(r); - SASSERT(ad == rd); + ENSURE(ad == rd); m.set(a, -1.5); m.to_rational(a, r); ad = m.to_double(a); rd = mq.get_double(r); - SASSERT(ad == rd); + ENSURE(ad == rd); m.set(a, -0.875); m.to_rational(a, r); ad = m.to_double(a); rd = mq.get_double(r); - SASSERT(ad == rd); + ENSURE(ad == rd); m.set(a, 0.1); m.to_rational(a, r); @@ -96,7 +96,7 @@ static void bug_to_rational() { // CMW: This one depends on the rounding mode, // which is implicit in both hwf::set and in mpq::to_double. double diff = (ad-rd); - SASSERT(diff >= -DBL_EPSILON && diff <= DBL_EPSILON); + ENSURE(diff >= -DBL_EPSILON && diff <= DBL_EPSILON); #endif } @@ -107,7 +107,7 @@ static void bug_is_int() { hwf_manager m; hwf a; m.set(a, val); - SASSERT(!m.is_int(a)); + ENSURE(!m.is_int(a)); } void tst_hwf() { diff --git a/src/test/inf_rational.cpp b/src/test/inf_rational.cpp index 1b0a293ce..64d2ab921 100644 --- a/src/test/inf_rational.cpp +++ b/src/test/inf_rational.cpp @@ -23,8 +23,8 @@ Revision History: static void tst0() { inf_rational n(rational(0), false); TRACE("inf_rational", tout << n << "\n";); - SASSERT(n < inf_rational::zero()); - SASSERT(!(n >= inf_rational::zero())); + ENSURE(n < inf_rational::zero()); + ENSURE(!(n >= inf_rational::zero())); } void test_inc_dec( @@ -36,44 +36,44 @@ void test_inc_dec( ) { r += rational(1,5); - SASSERT (r == b_8_5); + ENSURE (r == b_8_5); r -= rational(1,5); - SASSERT (r == b_7_5); + ENSURE (r == b_7_5); r += inf_rational(1,5); - SASSERT (r == b_8_5); + ENSURE (r == b_8_5); r -= inf_rational(1,5); - SASSERT (r == b_7_5); + ENSURE (r == b_7_5); r /= rational(2,1); - SASSERT (r == b_7_10); + ENSURE (r == b_7_10); inf_rational r_pre = r++; - SASSERT (r_pre == b_7_10); - SASSERT (r == b_17_10); + ENSURE (r_pre == b_7_10); + ENSURE (r == b_17_10); inf_rational r_post = --r; - SASSERT (r_post == b_7_10); - SASSERT (r == b_7_10); + ENSURE (r_post == b_7_10); + ENSURE (r == b_7_10); r_post = ++r; - SASSERT (r_post == b_17_10); - SASSERT (r == b_17_10); + ENSURE (r_post == b_17_10); + ENSURE (r == b_17_10); r_pre = r--; - SASSERT (r_pre == b_17_10); - SASSERT (r == b_7_10); + ENSURE (r_pre == b_17_10); + ENSURE (r == b_7_10); r_pre = r; r_pre += inf_rational(1,2); r_post = r_pre; r_post -= inf_rational(1,2); - SASSERT(r == r_post); - SASSERT(r + inf_rational(1,2) == r_pre); + ENSURE(r == r_post); + ENSURE(r + inf_rational(1,2) == r_pre); r_pre = r; r_pre /= rational(2,1); r_post = r_pre; r_post /= rational(1,2); - SASSERT(r == r_post); - SASSERT(rational(1,2) * r == r_pre); - SASSERT(r == r_pre / rational(1,2)); + ENSURE(r == r_post); + ENSURE(rational(1,2) * r == r_pre); + ENSURE(r == r_pre / rational(1,2)); } @@ -84,27 +84,27 @@ tst_inf_rational() inf_rational r1; inf_rational r2(r1); - SASSERT (r1 == r2); + ENSURE (r1 == r2); inf_rational r3(1); inf_rational r4(0); - SASSERT (r4 == r1); - SASSERT (r3 != r4); + ENSURE (r4 == r1); + ENSURE (r3 != r4); inf_rational r5(0,1); inf_rational r6(1,1); inf_rational r7(2,2); inf_rational r8(7,5); - SASSERT (r1 == r5); - SASSERT (r6 == r3); - SASSERT (r7 == r3); + ENSURE (r1 == r5); + ENSURE (r6 == r3); + ENSURE (r7 == r3); inf_rational r9(rational(7,5)); - SASSERT (r8 == r9); + ENSURE (r8 == r9); r9.reset(); - SASSERT (r1 == r9); - SASSERT (r1.is_int()); - SASSERT (!r8.is_int()); - SASSERT (0 == r1.get_int64()); + ENSURE (r1 == r9); + ENSURE (r1.is_int()); + ENSURE (!r8.is_int()); + ENSURE (0 == r1.get_int64()); r9 = r8; - SASSERT (r8 == r9); + ENSURE (r8 == r9); inf_rational n = numerator(r7); inf_rational d = denominator(r7); @@ -130,50 +130,50 @@ tst_inf_rational() } - SASSERT(inf_rational(rational(1,2),true) > inf_rational(rational(1,2))); - SASSERT(inf_rational(rational(1,2),false) < inf_rational(rational(1,2))); - SASSERT(inf_rational(rational(1,2),true) >= inf_rational(rational(1,2))); - SASSERT(inf_rational(rational(1,2)) >= inf_rational(rational(1,2),false)); - SASSERT(inf_rational(rational(1,2),false) != inf_rational(rational(1,2))); - SASSERT(inf_rational(rational(1,2),true) != inf_rational(rational(1,2))); - SASSERT(inf_rational(rational(1,2),false) != inf_rational(rational(1,2),true)); + ENSURE(inf_rational(rational(1,2),true) > inf_rational(rational(1,2))); + ENSURE(inf_rational(rational(1,2),false) < inf_rational(rational(1,2))); + ENSURE(inf_rational(rational(1,2),true) >= inf_rational(rational(1,2))); + ENSURE(inf_rational(rational(1,2)) >= inf_rational(rational(1,2),false)); + ENSURE(inf_rational(rational(1,2),false) != inf_rational(rational(1,2))); + ENSURE(inf_rational(rational(1,2),true) != inf_rational(rational(1,2))); + ENSURE(inf_rational(rational(1,2),false) != inf_rational(rational(1,2),true)); inf_rational h_neg(rational(1,2),false); inf_rational h_pos(rational(1,2),true); h_neg.neg(); - SASSERT(h_neg == -inf_rational(rational(1,2),false)); + ENSURE(h_neg == -inf_rational(rational(1,2),false)); h_neg.neg(); - SASSERT(h_neg == inf_rational(rational(1,2),false)); + ENSURE(h_neg == inf_rational(rational(1,2),false)); - SASSERT(r1.is_zero() && !r1.is_one() && !r1.is_neg() && r1.is_nonneg() && r1.is_nonpos() && !r1.is_pos()); - SASSERT(!r3.is_zero() && r3.is_one() && !r3.is_neg() && r3.is_nonneg() && !r3.is_nonpos() && r3.is_pos()); + ENSURE(r1.is_zero() && !r1.is_one() && !r1.is_neg() && r1.is_nonneg() && r1.is_nonpos() && !r1.is_pos()); + ENSURE(!r3.is_zero() && r3.is_one() && !r3.is_neg() && r3.is_nonneg() && !r3.is_nonpos() && r3.is_pos()); - SASSERT(floor(inf_rational(rational(1,2),false)) == rational()); - SASSERT(floor(inf_rational(rational(1,2))) == rational()); - SASSERT(floor(inf_rational(rational(),false)) == rational(-1)); - SASSERT(floor(inf_rational(rational())) == rational()); - SASSERT(floor(inf_rational(rational(),true)) == rational()); - SASSERT(floor(inf_rational(rational(1),false)) == rational()); - SASSERT(floor(inf_rational(rational(1))) == rational(1)); - SASSERT(floor(inf_rational(rational(1),true)) == rational(1)); + ENSURE(floor(inf_rational(rational(1,2),false)) == rational()); + ENSURE(floor(inf_rational(rational(1,2))) == rational()); + ENSURE(floor(inf_rational(rational(),false)) == rational(-1)); + ENSURE(floor(inf_rational(rational())) == rational()); + ENSURE(floor(inf_rational(rational(),true)) == rational()); + ENSURE(floor(inf_rational(rational(1),false)) == rational()); + ENSURE(floor(inf_rational(rational(1))) == rational(1)); + ENSURE(floor(inf_rational(rational(1),true)) == rational(1)); - SASSERT(ceil(inf_rational(rational(1,2),false)) == rational(1)); - SASSERT(ceil(inf_rational(rational(1,2))) == rational(1)); - SASSERT(ceil(inf_rational(rational(),false)) == rational()); - SASSERT(ceil(inf_rational(rational())) == rational()); - SASSERT(ceil(inf_rational(rational(),true)) == rational(1)); - SASSERT(ceil(inf_rational(rational(1),false)) == rational(1)); - SASSERT(ceil(inf_rational(rational(1))) == rational(1)); - SASSERT(ceil(inf_rational(rational(1),true)) == rational(2)); + ENSURE(ceil(inf_rational(rational(1,2),false)) == rational(1)); + ENSURE(ceil(inf_rational(rational(1,2))) == rational(1)); + ENSURE(ceil(inf_rational(rational(),false)) == rational()); + ENSURE(ceil(inf_rational(rational())) == rational()); + ENSURE(ceil(inf_rational(rational(),true)) == rational(1)); + ENSURE(ceil(inf_rational(rational(1),false)) == rational(1)); + ENSURE(ceil(inf_rational(rational(1))) == rational(1)); + ENSURE(ceil(inf_rational(rational(1),true)) == rational(2)); inf_rational x(rational(1,2),true); inf_rational y(1,2); x.swap(y); - SASSERT (x == inf_rational(1,2)); - SASSERT (y == inf_rational(rational(1,2),true)); + ENSURE (x == inf_rational(1,2)); + ENSURE (y == inf_rational(rational(1,2),true)); - SASSERT(inf_rational(1,2) == abs(-inf_rational(1,2))); + ENSURE(inf_rational(1,2) == abs(-inf_rational(1,2))); } diff --git a/src/test/interval.cpp b/src/test/interval.cpp index ac242cc60..c22156988 100644 --- a/src/test/interval.cpp +++ b/src/test/interval.cpp @@ -438,7 +438,7 @@ void tst_pi() { im.pi(i, r); nm.display_decimal(std::cout, im.lower(r), 32); std::cout << " "; nm.display_decimal(std::cout, im.upper(r), 32); std::cout << "\n"; - SASSERT(nm.lt(im.lower(r), im.upper(r))); + ENSURE(nm.lt(im.lower(r), im.upper(r))); } del_interval(imc, r); } diff --git a/src/test/karr.cpp b/src/test/karr.cpp index c69932e22..11e7ae17f 100644 --- a/src/test/karr.cpp +++ b/src/test/karr.cpp @@ -131,7 +131,7 @@ namespace karr { matrix T; // length of rows in Ab are twice as long as // length of rows in src. - SASSERT(2*src.A[0].size() == Ab.A[0].size()); + ENSURE(2*src.A[0].size() == Ab.A[0].size()); vector zeros; for (unsigned i = 0; i < src.A[0].size(); ++i) { zeros.push_back(rational(0)); diff --git a/src/test/list.cpp b/src/test/list.cpp index a7ad76972..e377e7bbf 100644 --- a/src/test/list.cpp +++ b/src/test/list.cpp @@ -27,10 +27,10 @@ static void tst1() { list * l2 = new (r) list(20, l1); list * l3 = new (r) list(30); list * l4 = new (r) list(40, l3); - SASSERT(append(r, l1, static_cast *>(0)) == l1); - SASSERT(append(r, l2, static_cast *>(0)) == l2); - SASSERT(append(r, static_cast *>(0), l2) == l2); - SASSERT(append(r, static_cast *>(0), static_cast *>(0)) == 0); + ENSURE(append(r, l1, static_cast *>(0)) == l1); + ENSURE(append(r, l2, static_cast *>(0)) == l2); + ENSURE(append(r, static_cast *>(0), l2) == l2); + ENSURE(append(r, static_cast *>(0), static_cast *>(0)) == 0); TRACE("list", display(tout, l2->begin(), l2->end()); tout << "\n";); list * l5 = append(r, l4, l2); TRACE("list", display(tout, l5->begin(), l5->end()); tout << "\n";); diff --git a/src/test/map.cpp b/src/test/map.cpp index 7e2cc7e70..c0b084b73 100644 --- a/src/test/map.cpp +++ b/src/test/map.cpp @@ -22,22 +22,22 @@ Revision History: static void tst1() { map str2int; str2int.insert("foo", 35); - SASSERT(str2int.contains("foo")); - SASSERT(str2int.find_iterator("foo") != str2int.end()); - SASSERT((*(str2int.find_iterator("foo"))).m_value == 35); - SASSERT(str2int.size() == 1); + ENSURE(str2int.contains("foo")); + ENSURE(str2int.find_iterator("foo") != str2int.end()); + ENSURE((*(str2int.find_iterator("foo"))).m_value == 35); + ENSURE(str2int.size() == 1); str2int.insert("boo", 32); - SASSERT(str2int.contains("foo")); - SASSERT(str2int.find_iterator("foo") != str2int.end()); - SASSERT((*(str2int.find_iterator("foo"))).m_value == 35); - SASSERT(str2int.contains("boo")); - SASSERT(str2int.find_iterator("boo") != str2int.end()); - SASSERT((*(str2int.find_iterator("boo"))).m_value == 32); - SASSERT(str2int.size() == 2); + ENSURE(str2int.contains("foo")); + ENSURE(str2int.find_iterator("foo") != str2int.end()); + ENSURE((*(str2int.find_iterator("foo"))).m_value == 35); + ENSURE(str2int.contains("boo")); + ENSURE(str2int.find_iterator("boo") != str2int.end()); + ENSURE((*(str2int.find_iterator("boo"))).m_value == 32); + ENSURE(str2int.size() == 2); str2int.remove("boo"); - SASSERT(str2int.size() == 1); - SASSERT(!str2int.contains("boo")); - SASSERT(str2int.contains("foo")); + ENSURE(str2int.size() == 1); + ENSURE(!str2int.contains("boo")); + ENSURE(str2int.contains("foo")); } void tst_map() { diff --git a/src/test/mpf.cpp b/src/test/mpf.cpp index d12675b6d..f00152b09 100644 --- a/src/test/mpf.cpp +++ b/src/test/mpf.cpp @@ -24,38 +24,38 @@ static void bug_set_int() { scoped_mpf a(fm); fm.set(a, 11, 53, 3); - SASSERT(fm.to_double(a) == 3.0); + ENSURE(fm.to_double(a) == 3.0); fm.set(a, 11, 53, 0); - SASSERT(fm.to_double(a) == 0.0); + ENSURE(fm.to_double(a) == 0.0); fm.set(a, 11, 53, -1); - SASSERT(fm.to_double(a) == -1.0); + ENSURE(fm.to_double(a) == -1.0); fm.set(a, 11, 53, INT_MAX); - SASSERT(fm.to_double(a) == (double)INT_MAX); + ENSURE(fm.to_double(a) == (double)INT_MAX); fm.set(a, 11, 53, INT_MIN); - SASSERT(fm.to_double(a) == (double)INT_MIN); + ENSURE(fm.to_double(a) == (double)INT_MIN); fm.set(a, 8, 24, 3); - SASSERT(fm.to_float(a) == 3.0); - SASSERT(fm.to_double(a) == 3.0); + ENSURE(fm.to_float(a) == 3.0); + ENSURE(fm.to_double(a) == 3.0); fm.set(a, 8, 24, 0); - SASSERT(fm.to_float(a) == 0.0); - SASSERT(fm.to_double(a) == 0.0); + ENSURE(fm.to_float(a) == 0.0); + ENSURE(fm.to_double(a) == 0.0); fm.set(a, 8, 24, -1); - SASSERT(fm.to_float(a) == -1.0); - SASSERT(fm.to_double(a) == -1.0); + ENSURE(fm.to_float(a) == -1.0); + ENSURE(fm.to_double(a) == -1.0); fm.set(a, 8, 24, INT_MIN); - SASSERT(fm.to_float(a) == (float)INT_MIN); + ENSURE(fm.to_float(a) == (float)INT_MIN); // CMW: This one depends on the rounding mode, but fm.set(..., int) doesn't have one. // fm.set(a, 8, 24, INT_MAX); - // SASSERT(fm.to_float(a) == (float)INT_MAX); + // ENSURE(fm.to_float(a) == (float)INT_MAX); } static void bug_set_double() { @@ -63,22 +63,22 @@ static void bug_set_double() { scoped_mpf a(fm); fm.set(a, 11, 53, 2.5); - SASSERT(fm.to_double(a) == 2.5); + ENSURE(fm.to_double(a) == 2.5); fm.set(a, 11, 53, -42.25); - SASSERT(fm.to_double(a) == -42.25); + ENSURE(fm.to_double(a) == -42.25); fm.set(a, 8, 24, (double)2.5); - SASSERT(fm.to_double(a) == 2.5); + ENSURE(fm.to_double(a) == 2.5); fm.set(a, 8, 24, (double)-42.25); - SASSERT(fm.to_double(a) == -42.25); + ENSURE(fm.to_double(a) == -42.25); fm.set(a, 8, 24, (float)2.5); - SASSERT(fm.to_float(a) == 2.5); + ENSURE(fm.to_float(a) == 2.5); fm.set(a, 8, 24, (float)-42.25); - SASSERT(fm.to_float(a) == -42.25); + ENSURE(fm.to_float(a) == -42.25); } void tst_mpf() { diff --git a/src/test/mpff.cpp b/src/test/mpff.cpp index ca2354b8b..bb06846d5 100644 --- a/src/test/mpff.cpp +++ b/src/test/mpff.cpp @@ -77,10 +77,10 @@ static void tst5() { scoped_mpff a(m), b(m); m.set(a, static_cast(1) << 63); m.display_raw(std::cout, a); std::cout << "\n"; - SASSERT(m.is_zero(b)); - SASSERT(m.lt(b, a)); + ENSURE(m.is_zero(b)); + ENSURE(m.lt(b, a)); m.set(b, -1); - SASSERT(m.lt(b, a)); + ENSURE(m.lt(b, a)); } static void tst6() { @@ -90,10 +90,10 @@ static void tst6() { std::cout << "mpff(1/3) " << a << "\n"; b = a; m.next(b); - SASSERT(m.lt(a, b)); + ENSURE(m.lt(a, b)); std::cout << "b: " << b << "\n"; m.prev(b); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.ceil(b); std::cout << "b: " << b << "\n"; m.set(b, 4, 3); @@ -135,15 +135,15 @@ static void tst_ ## OP ## _core(int64 n1, uint64 d1, int64 n2, uint64 d2, unsign fm.round_to_plus_inf(); \ fm.OP(fa, fb, fc1); \ fm.to_mpq(fc1, qm, qt); \ - SASSERT(qm.le(qc, qt)); \ + ENSURE(qm.le(qc, qt)); \ } \ { \ fm.round_to_minus_inf(); \ fm.OP(fa, fb, fc2); \ fm.to_mpq(fc2, qm, qt); \ - SASSERT(qm.le(qt, qc)); \ + ENSURE(qm.le(qt, qc)); \ } \ - SASSERT(fm.le(fc2, fc1)); \ + ENSURE(fm.le(fc2, fc1)); \ } MK_BIN_OP(add); @@ -182,7 +182,7 @@ static void tst_bug() { scoped_mpq b(qm), c(qm); qm.set(b, 41, 36); fm.to_mpq(a, qm, c); - SASSERT(qm.le(b, c)); + ENSURE(qm.le(b, c)); } static void tst_bug2() { @@ -191,16 +191,16 @@ static void tst_bug2() { fm.set(b, 1); fm.sub(a, b, b); fm.set(a, -1); - SASSERT(fm.eq(a, b)); + ENSURE(fm.eq(a, b)); fm.set(a, 1); fm.set(b, 0); fm.sub(a, b, a); fm.set(b, 1); - SASSERT(fm.eq(a, b)); + ENSURE(fm.eq(a, b)); fm.set(a, 1); fm.set(b, 1); fm.sub(a, b, a); - SASSERT(fm.is_zero(a)); + ENSURE(fm.is_zero(a)); } static void tst_set64(unsigned N, unsigned prec) { @@ -208,69 +208,69 @@ static void tst_set64(unsigned N, unsigned prec) { scoped_mpff a(fm); fm.set(a, static_cast(INT64_MAX)); - SASSERT(fm.is_int64(a)); - SASSERT(fm.is_uint64(a)); + ENSURE(fm.is_int64(a)); + ENSURE(fm.is_uint64(a)); fm.inc(a); - SASSERT(!fm.is_int64(a)); - SASSERT(fm.is_uint64(a)); - SASSERT(fm.is_int(a)); + ENSURE(!fm.is_int64(a)); + ENSURE(fm.is_uint64(a)); + ENSURE(fm.is_int(a)); fm.dec(a); - SASSERT(fm.is_int64(a)); - SASSERT(fm.is_uint64(a)); + ENSURE(fm.is_int64(a)); + ENSURE(fm.is_uint64(a)); fm.dec(a); - SASSERT(fm.is_int64(a)); - SASSERT(fm.is_uint64(a)); + ENSURE(fm.is_int64(a)); + ENSURE(fm.is_uint64(a)); fm.set(a, static_cast(INT64_MIN)); - SASSERT(fm.is_int64(a)); - SASSERT(!fm.is_uint64(a)); + ENSURE(fm.is_int64(a)); + ENSURE(!fm.is_uint64(a)); fm.dec(a); - SASSERT(!fm.is_int64(a)); - SASSERT(!fm.is_uint64(a)); - SASSERT(fm.is_int(a)); + ENSURE(!fm.is_int64(a)); + ENSURE(!fm.is_uint64(a)); + ENSURE(fm.is_int(a)); fm.inc(a); - SASSERT(fm.is_int64(a)); - SASSERT(!fm.is_uint64(a)); + ENSURE(fm.is_int64(a)); + ENSURE(!fm.is_uint64(a)); fm.inc(a); - SASSERT(fm.is_int64(a)); - SASSERT(!fm.is_uint64(a)); + ENSURE(fm.is_int64(a)); + ENSURE(!fm.is_uint64(a)); fm.set(a, static_cast(UINT64_MAX)); - SASSERT(fm.is_uint64(a)); - SASSERT(!fm.is_int64(a)); + ENSURE(fm.is_uint64(a)); + ENSURE(!fm.is_int64(a)); fm.inc(a); - SASSERT(!fm.is_uint64(a)); - SASSERT(!fm.is_int64(a)); + ENSURE(!fm.is_uint64(a)); + ENSURE(!fm.is_int64(a)); fm.dec(a); - SASSERT(fm.is_uint64(a)); - SASSERT(!fm.is_int64(a)); + ENSURE(fm.is_uint64(a)); + ENSURE(!fm.is_int64(a)); fm.dec(a); - SASSERT(fm.is_uint64(a)); - SASSERT(!fm.is_int64(a)); + ENSURE(fm.is_uint64(a)); + ENSURE(!fm.is_int64(a)); for (unsigned i = 0; i < N; i++) { { uint64 v = (static_cast(rand()) << 32) + static_cast(rand()); fm.set(a, v); - SASSERT(fm.is_uint64(a)); + ENSURE(fm.is_uint64(a)); v = (static_cast(rand() % 3) << 32) + static_cast(rand()); fm.set(a, v); - SASSERT(fm.is_uint64(a)); + ENSURE(fm.is_uint64(a)); } { int64 v = (static_cast(rand() % INT_MAX) << 32) + static_cast(rand()); if (rand()%2 == 0) v = -v; fm.set(a, v); - SASSERT(fm.is_int64(a)); + ENSURE(fm.is_int64(a)); v = (static_cast(rand() % 3) << 32) + static_cast(rand()); if (rand()%2 == 0) v = -v; fm.set(a, v); - SASSERT(fm.is_int64(a)); + ENSURE(fm.is_int64(a)); } } } @@ -282,12 +282,12 @@ static void tst_capacity(unsigned prec = 2) { for (unsigned i = 0; i < 50000; i++) { m.set(a, i); v.push_back(a); - SASSERT(m.is_int(v.back())); - SASSERT(m.is_int64(v.back())); - SASSERT(m.is_uint64(v.back())); + ENSURE(m.is_int(v.back())); + ENSURE(m.is_int64(v.back())); + ENSURE(m.is_uint64(v.back())); } for (unsigned i = 0; i < 50000; i++) { - SASSERT(m.get_int64(v[i]) == i); + ENSURE(m.get_int64(v[i]) == i); } } @@ -296,140 +296,140 @@ static void tst_power(unsigned prec = 2) { scoped_mpff a(m), b(m); // 0^k == 0 - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); m.power(a, 10, a); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); // a != 0 ==> a^0 == 1 m.set(a, 33); m.power(a, 0, a); - SASSERT(m.is_one(a)); + ENSURE(m.is_one(a)); m.set(a, -33); m.power(a, 0, a); - SASSERT(m.is_one(a)); + ENSURE(m.is_one(a)); // a^1 == a m.set(a, 33); m.power(a, 1, b); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.set(a, -33); m.power(a, 1, b); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); // checking special support for powers of 2 #ifdef Z3DEBUG unsigned k; #endif m.set(a, 1); - SASSERT(m.is_power_of_two(a, k) && k == 0); + ENSURE(m.is_power_of_two(a, k) && k == 0); m.set(a, 2); - SASSERT(m.is_power_of_two(a, k) && k == 1); + ENSURE(m.is_power_of_two(a, k) && k == 1); m.set(a, 3); - SASSERT(!m.is_power_of_two(a, k)); + ENSURE(!m.is_power_of_two(a, k)); m.set(a, 4); - SASSERT(m.is_power_of_two(a, k) && k == 2); + ENSURE(m.is_power_of_two(a, k) && k == 2); m.set(a, -4); - SASSERT(!m.is_power_of_two(a, k)); + ENSURE(!m.is_power_of_two(a, k)); m.set(a, 8); - SASSERT(m.is_power_of_two(a, k) && k == 3); + ENSURE(m.is_power_of_two(a, k) && k == 3); m.set(a, 0); - SASSERT(!m.is_power_of_two(a)); + ENSURE(!m.is_power_of_two(a)); m.set(a, UINT_MAX); m.inc(a); - SASSERT(m.is_power_of_two(a, k) && k == 32); - SASSERT(m.get_uint64(a) == static_cast(UINT_MAX) + 1); + ENSURE(m.is_power_of_two(a, k) && k == 32); + ENSURE(m.get_uint64(a) == static_cast(UINT_MAX) + 1); m.power(a, 2, a); - SASSERT(m.is_power_of_two(a, k) && k == 64); + ENSURE(m.is_power_of_two(a, k) && k == 64); m.power(a, 4, a); - SASSERT(m.is_power_of_two(a, k) && k == 256); + ENSURE(m.is_power_of_two(a, k) && k == 256); m.round_to_plus_inf(); m.inc(a); - SASSERT(!m.is_power_of_two(a, k)); + ENSURE(!m.is_power_of_two(a, k)); m.set(a, -4); m.power(a, 3, a); m.set(b, -64); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.set(a, -4); m.power(a, 4, a); m.set(b, 256); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); // additional tests m.set(a, 5); m.power(a, 3, a); m.set(b, 5*5*5); - SASSERT(m.eq(a,b)); + ENSURE(m.eq(a,b)); m.set(a, -5); m.power(a, 3, a); m.set(b, -5*5*5); - SASSERT(m.eq(a,b)); + ENSURE(m.eq(a,b)); } static void tst_sgn(unsigned prec) { mpff_manager m(prec); scoped_mpff a(m), b(m); - SASSERT(m.is_zero(a) && !m.is_pos(a) && !m.is_neg(a) && m.is_nonpos(a) && m.is_nonneg(a)); + ENSURE(m.is_zero(a) && !m.is_pos(a) && !m.is_neg(a) && m.is_nonpos(a) && m.is_nonneg(a)); m.set(a, 3); - SASSERT(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a)); + ENSURE(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a)); m.set(a, -3); - SASSERT(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a)); + ENSURE(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a)); m.set(a, 8); m.power(a, 256, a); - SASSERT(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a)); + ENSURE(!m.is_zero(a) && m.is_pos(a) && !m.is_neg(a) && !m.is_nonpos(a) && m.is_nonneg(a)); b = a; m.neg(a); - SASSERT(m.neq(a, b)); - SASSERT(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a)); + ENSURE(m.neq(a, b)); + ENSURE(!m.is_zero(a) && !m.is_pos(a) && m.is_neg(a) && m.is_nonpos(a) && !m.is_nonneg(a)); m.neg(a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.set(a, 1); - SASSERT(m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a) && m.is_abs_one(a)); + ENSURE(m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a) && m.is_abs_one(a)); m.neg(a); - SASSERT(!m.is_one(a) && !m.is_zero(a) && m.is_minus_one(a) && m.is_abs_one(a)); + ENSURE(!m.is_one(a) && !m.is_zero(a) && m.is_minus_one(a) && m.is_abs_one(a)); m.set(a, 3); - SASSERT(!m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a)); + ENSURE(!m.is_one(a) && !m.is_zero(a) && !m.is_minus_one(a)); m.set(a, 3); b = a; m.abs(a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.set(a, -3); b = a; m.abs(a); - SASSERT(!m.eq(a,b) && m.is_pos(a)); + ENSURE(!m.eq(a,b) && m.is_pos(a)); m.set(a, 1); m.swap(a, a); - SASSERT(m.is_one(a)); + ENSURE(m.is_one(a)); m.set(b, -1); m.swap(a, b); - SASSERT(m.is_one(b) && m.is_minus_one(a)); + ENSURE(m.is_one(b) && m.is_minus_one(a)); m.neg(a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); } static void tst_limits(unsigned prec) { mpff_manager m(prec); scoped_mpff a(m), b(m), two(m); m.set_max(a); - SASSERT(m.is_pos(a)); + ENSURE(m.is_pos(a)); m.set_min(b); - SASSERT(m.is_neg(b)); + ENSURE(m.is_neg(b)); m.neg(a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.set_max(a); m.set_max(b); m.round_to_minus_inf(); m.inc(a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.dec(a); - SASSERT(m.lt(a, b)); + ENSURE(m.lt(a, b)); m.set_max(a); m.round_to_plus_inf(); bool overflow = false; @@ -438,99 +438,99 @@ static void tst_limits(unsigned prec) { VERIFY(overflow); m.set_max(a); m.dec(a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.set_min(a); m.set_min(b); m.round_to_minus_inf(); m.inc(a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); overflow = true; try { m.dec(a); } catch (mpff_manager::overflow_exception) { overflow = true; } - SASSERT(overflow); + ENSURE(overflow); m.round_to_plus_inf(); m.set_min(a); m.inc(a); - SASSERT(m.gt(a,b)); + ENSURE(m.gt(a,b)); m.set_min(a); m.dec(a); - SASSERT(m.eq(a,b)); + ENSURE(m.eq(a,b)); m.set_plus_epsilon(a); m.set_plus_epsilon(b); - SASSERT(!m.is_zero(a) && m.is_pos(a)); + ENSURE(!m.is_zero(a) && m.is_pos(a)); m.set(two, 2); m.round_to_plus_inf(); m.div(a, two, a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.round_to_minus_inf(); m.div(a, two, a); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); m.round_to_plus_inf(); m.set_plus_epsilon(a); m.add(a, a, a); - SASSERT(m.gt(a, b)); + ENSURE(m.gt(a, b)); m.round_to_minus_inf(); m.set_plus_epsilon(a); m.add(a, a, a); - SASSERT(m.gt(a, b)); + ENSURE(m.gt(a, b)); m.set_plus_epsilon(a); m.sub(a, a, a); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); m.set_plus_epsilon(a); - SASSERT(m.is_plus_epsilon(a)); - SASSERT(!m.is_minus_epsilon(a)); + ENSURE(m.is_plus_epsilon(a)); + ENSURE(!m.is_minus_epsilon(a)); m.neg(a); - SASSERT(!m.is_plus_epsilon(a)); - SASSERT(m.is_minus_epsilon(a)); + ENSURE(!m.is_plus_epsilon(a)); + ENSURE(m.is_minus_epsilon(a)); for (unsigned i = 0; i < 2; i++) { m.set_rounding(i == 0); m.set_plus_epsilon(a); m.floor(a); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); m.set_plus_epsilon(a); m.ceil(a); - SASSERT(m.is_one(a)); + ENSURE(m.is_one(a)); m.set_minus_epsilon(a); m.floor(a); - SASSERT(m.is_minus_one(a)); + ENSURE(m.is_minus_one(a)); m.set_minus_epsilon(a); m.ceil(a); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); } m.set_minus_epsilon(a); m.set_minus_epsilon(b); - SASSERT(!m.is_zero(a) && m.is_neg(a)); + ENSURE(!m.is_zero(a) && m.is_neg(a)); m.set(two, 2); m.round_to_minus_inf(); m.div(a, two, a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); m.round_to_plus_inf(); m.div(a, two, a); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); m.round_to_plus_inf(); m.set_minus_epsilon(a); m.add(a, a, a); - SASSERT(m.lt(a, b)); + ENSURE(m.lt(a, b)); m.round_to_minus_inf(); m.set_minus_epsilon(a); m.add(a, a, a); - SASSERT(m.lt(a, b)); + ENSURE(m.lt(a, b)); m.set_minus_epsilon(a); m.sub(a, a, a); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); m.set_minus_epsilon(a); - SASSERT(!m.is_plus_epsilon(a)); - SASSERT(m.is_minus_epsilon(a)); + ENSURE(!m.is_plus_epsilon(a)); + ENSURE(m.is_minus_epsilon(a)); m.neg(a); - SASSERT(m.is_plus_epsilon(a)); - SASSERT(!m.is_minus_epsilon(a)); + ENSURE(m.is_plus_epsilon(a)); + ENSURE(!m.is_minus_epsilon(a)); } #if 0 @@ -549,7 +549,7 @@ static void tst_decimal(int64 n, uint64 d, bool to_plus_inf, unsigned prec, char m.display_decimal(std::cout, a, decimal_places); std::cout << std::endl; std::ostringstream buffer; m.display_decimal(buffer, a, decimal_places); - SASSERT(strcmp(expected, buffer.str().c_str()) == 0); + ENSURE(strcmp(expected, buffer.str().c_str()) == 0); } static void tst_decimal() { @@ -573,7 +573,7 @@ static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) { mpff_manager m; scoped_mpff a(m); m.set(a, n, d); - SASSERT(m.prev_power_of_two(a) == expected); + ENSURE(m.prev_power_of_two(a) == expected); } static void tst_prev_power_2() { diff --git a/src/test/mpfx.cpp b/src/test/mpfx.cpp index 9e8882a26..c83f73bad 100644 --- a/src/test/mpfx.cpp +++ b/src/test/mpfx.cpp @@ -39,7 +39,7 @@ static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) { mpfx_manager m; scoped_mpfx a(m); m.set(a, n, d); - SASSERT(m.prev_power_of_two(a) == expected); + ENSURE(m.prev_power_of_two(a) == expected); } static void tst_prev_power_2() { diff --git a/src/test/mpq.cpp b/src/test/mpq.cpp index 68c7d8bb3..0da7a584a 100644 --- a/src/test/mpq.cpp +++ b/src/test/mpq.cpp @@ -27,7 +27,7 @@ static void tst0() { m.set(a, 2, 3); m.set(b, 4, 3); m.div(a, b, b); - SASSERT(m.eq(b, m.mk_q(1, 2))); + ENSURE(m.eq(b, m.mk_q(1, 2))); } static void tst1() { @@ -41,15 +41,15 @@ static void tst1() { std::cout << "*-2 = \n" << m.to_string(v2) << "\n"; m.add(v, v2, v3); m.neg(v3); - SASSERT(m.eq(v, v3)); - SASSERT(m.le(v, v3)); - SASSERT(m.ge(v, v3)); - SASSERT(m.lt(v2, v)); - SASSERT(m.le(v2, v)); - SASSERT(m.gt(v, v2)); - SASSERT(m.ge(v, v2)); - SASSERT(m.neq(v, v2)); - SASSERT(!m.neq(v, v3)); + ENSURE(m.eq(v, v3)); + ENSURE(m.le(v, v3)); + ENSURE(m.ge(v, v3)); + ENSURE(m.lt(v2, v)); + ENSURE(m.le(v2, v)); + ENSURE(m.gt(v, v2)); + ENSURE(m.ge(v, v2)); + ENSURE(m.neq(v, v2)); + ENSURE(!m.neq(v, v3)); m.del(v); m.del(v2); m.del(v3); @@ -68,7 +68,7 @@ static void mk_random_num_str(unsigned buffer_sz, char * buffer) { if (div_pos == 0) div_pos++; } - SASSERT(sz < buffer_sz); + ENSURE(sz < buffer_sz); for (unsigned i = 0; i < sz-1; i++) { if (i == div_pos && i < sz-2) { buffer[i] = '/'; @@ -90,7 +90,7 @@ static void bug1() { m.set(a, 2); m.set(b, 1, 2); m.inv(a, a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); } static void bug2() { @@ -100,7 +100,7 @@ static void bug2() { m.set(a, -2); m.set(b, -1, 2); m.inv(a, a); - SASSERT(m.eq(a, b)); + ENSURE(m.eq(a, b)); } static void tst2() { @@ -122,22 +122,22 @@ static void set_str_bug() { m.set(a, "1.0"); std::cout << a << "\n"; m.set(b, 1); - SASSERT(a == b); + ENSURE(a == b); m.set(a, "1.1"); std::cout << a << "\n"; m.set(b, 11, 10); - SASSERT(a == b); + ENSURE(a == b); m.set(a, "1/3"); m.set(b, 1, 3); std::cout << a << "\n"; - SASSERT(a == b); + ENSURE(a == b); } static void tst_prev_power_2(int64 n, uint64 d, unsigned expected) { unsynch_mpq_manager m; scoped_mpq a(m); m.set(a, n, d); - SASSERT(m.prev_power_of_two(a) == expected); + ENSURE(m.prev_power_of_two(a) == expected); } static void tst_prev_power_2() { diff --git a/src/test/mpz.cpp b/src/test/mpz.cpp index 02627e842..1c587f8e9 100644 --- a/src/test/mpz.cpp +++ b/src/test/mpz.cpp @@ -33,15 +33,15 @@ static void tst1() { std::cout << "*-2 = \n" << m.to_string(v2) << "\n"; m.add(v, v2, v3); m.neg(v3); - SASSERT(m.eq(v, v3)); - SASSERT(m.le(v, v3)); - SASSERT(m.ge(v, v3)); - SASSERT(m.lt(v2, v)); - SASSERT(m.le(v2, v)); - SASSERT(m.gt(v, v2)); - SASSERT(m.ge(v, v2)); - SASSERT(m.neq(v, v2)); - SASSERT(!m.neq(v, v3)); + ENSURE(m.eq(v, v3)); + ENSURE(m.le(v, v3)); + ENSURE(m.ge(v, v3)); + ENSURE(m.lt(v2, v)); + ENSURE(m.le(v2, v)); + ENSURE(m.gt(v, v2)); + ENSURE(m.ge(v, v2)); + ENSURE(m.neq(v, v2)); + ENSURE(!m.neq(v, v3)); m.del(v); m.del(v2); m.del(v3); @@ -80,7 +80,7 @@ static void tst2b() { #if 0 static void mk_random_num_str(unsigned buffer_sz, char * buffer) { unsigned sz = (rand() % (buffer_sz-2)) + 1; - SASSERT(sz < buffer_sz); + ENSURE(sz < buffer_sz); for (unsigned i = 0; i < sz-1; i++) { buffer[i] = '0' + (rand() % 10); } @@ -96,7 +96,7 @@ static void bug1() { m.set(v1, "1002043949858757875676767675747473"); mpz v2; m.sub(v1, v1, v2); - SASSERT(m.is_zero(v2)); + ENSURE(m.is_zero(v2)); m.del(v1); m.del(v2); } @@ -119,7 +119,7 @@ static void bug3() { m.set(v2, INT_MAX); m.add(v2, m.mk_z(1), v2); m.neg(v1); - SASSERT(m.eq(v1, v2)); + ENSURE(m.eq(v1, v2)); m.del(v1); m.del(v2); } @@ -137,7 +137,7 @@ static void bug4() { m.bitwise_or(result2, y, result2); std::cout << m.to_string(result1) << " " << m.to_string(result2) << "\n"; - SASSERT(m.eq(result1, result2)); + ENSURE(m.eq(result1, result2)); m.del(x); m.del(y); m.del(result1); m.del(result2); } @@ -149,7 +149,7 @@ void tst_div2k(synch_mpz_manager & m, mpz const & v, unsigned k) { bool is_eq = m.eq(x, y); (void)is_eq; CTRACE("mpz_2k", !is_eq, tout << "div: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";); - SASSERT(is_eq); + ENSURE(is_eq); m.del(x); m.del(y); m.del(pw); @@ -177,7 +177,7 @@ void tst_mul2k(synch_mpz_manager & m, mpz const & v, unsigned k) { bool is_eq = m.eq(x, y); (void)is_eq; CTRACE("mpz_2k", !is_eq, tout << "mul: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";); - SASSERT(is_eq); + ENSURE(is_eq); m.del(x); m.del(y); m.del(pw); @@ -286,7 +286,7 @@ void tst_int_min_bug() { m.set(expected, "18446744075857035263"); m.sub(big, intmin, r); std::cout << "r: " << m.to_string(r) << "\nexpected: " << m.to_string(expected) << "\n"; - SASSERT(m.eq(r, expected)); + ENSURE(m.eq(r, expected)); m.del(intmin); m.del(big); m.del(expected); @@ -396,9 +396,9 @@ void tst_log2(unsynch_mpz_manager & m, mpz const & a) { scoped_mpz b(m); unsigned k = m.log2(a); m.power(mpz(2), k, b); - SASSERT(m.is_zero(a) || m.le(b, a)); + ENSURE(m.is_zero(a) || m.le(b, a)); m.power(mpz(2), k+1, b); - SASSERT(m.le(a, b)); + ENSURE(m.le(a, b)); scoped_mpz neg_a(m); m.set(neg_a, a); @@ -406,10 +406,10 @@ void tst_log2(unsynch_mpz_manager & m, mpz const & a) { k = m.mlog2(neg_a); m.power(mpz(2), k, b); m.neg(b); - SASSERT(m.is_zero(neg_a) || m.le(neg_a, b)); + ENSURE(m.is_zero(neg_a) || m.le(neg_a, b)); m.power(mpz(2), k+1, b); m.neg(b); - SASSERT(m.le(b, neg_a)); + ENSURE(m.le(b, neg_a)); } void tst_log2() { @@ -432,20 +432,20 @@ void tst_root() { m.set(a, 213); VERIFY(!m.root(a, 5)); std::cout << "213^{1/5}: " << a << "\n"; - SASSERT(m.eq(a, mpz(3))); + ENSURE(m.eq(a, mpz(3))); m.set(a, -213); VERIFY(!m.root(a, 5)); std::cout << "-213^{1/5}: " << a << "\n"; - SASSERT(m.eq(a, mpz(-2))); + ENSURE(m.eq(a, mpz(-2))); m.set(a, 0); VERIFY(m.root(a, 3)); - SASSERT(m.is_zero(a)); + ENSURE(m.is_zero(a)); m.set(a, 8); VERIFY(m.root(a, 3)); - SASSERT(m.eq(a, mpz(2))); + ENSURE(m.eq(a, mpz(2))); m.set(a, -8); VERIFY(m.root(a, 3)); - SASSERT(m.eq(a, mpz(-2))); + ENSURE(m.eq(a, mpz(-2))); } void tst_gcd_bug() { diff --git a/src/test/nlsat.cpp b/src/test/nlsat.cpp index df25db927..ccb534214 100644 --- a/src/test/nlsat.cpp +++ b/src/test/nlsat.cpp @@ -35,25 +35,25 @@ nlsat::interval_set_ref tst_interval(nlsat::interval_set_ref const & s1, std::cout << "s2: " << s2 << "\n"; r = ism.mk_union(s1, s2); std::cout << "union(s1, s2): " << r << std::endl; - SASSERT(!check_num_intervals || ism.num_intervals(r) == expected_num_intervals); - SASSERT(ism.subset(s1, r)); - SASSERT(ism.subset(s2, r)); + ENSURE(!check_num_intervals || ism.num_intervals(r) == expected_num_intervals); + ENSURE(ism.subset(s1, r)); + ENSURE(ism.subset(s2, r)); if (ism.set_eq(s1, s2)) { - SASSERT(ism.set_eq(s1, r)); - SASSERT(ism.set_eq(s2, r)); + ENSURE(ism.set_eq(s1, r)); + ENSURE(ism.set_eq(s2, r)); } else { - SASSERT(ism.subset(s1, s2) || !ism.subset(r, s2)); - SASSERT(ism.subset(s2, s1) || !ism.subset(r, s1)); + ENSURE(ism.subset(s1, s2) || !ism.subset(r, s2)); + ENSURE(ism.subset(s2, s1) || !ism.subset(r, s1)); } nlsat::interval_set_ref r2(ism); r2 = ism.mk_union(s2, s1); - SASSERT(ism.set_eq(r, r2)); + ENSURE(ism.set_eq(r, r2)); anum zero; nlsat::interval_set_ref full(ism); nlsat::literal dummy(131, false); full = ism.mk(true, true, zero, true, true, zero, dummy); - SASSERT(ism.set_eq(r, full) == ism.is_full(r)); + ENSURE(ism.set_eq(r, full) == ism.is_full(r)); return r; } @@ -178,8 +178,8 @@ static void tst3() { static nlsat::interval_set_ref mk_random(nlsat::interval_set_manager & ism, anum_manager & am, int range, int space, int tries, bool minus_inf, bool plus_inf, nlsat::literal lit) { static random_gen gen; - SASSERT(range > 0); - SASSERT(space > 0); + ENSURE(range > 0); + ENSURE(space > 0); nlsat::interval_set_ref r(ism), curr(ism); scoped_anum lower(am); scoped_anum upper(am); @@ -227,17 +227,17 @@ static void check_subset_result(nlsat::interval_set_ref const & s1, unsigned num = ism.num_intervals(r); nlsat::literal_vector lits; ism.get_justifications(r, lits); - SASSERT(lits.size() <= 2); + ENSURE(lits.size() <= 2); for (unsigned i = 0; i < num; i++) { tmp = ism.get_interval(r, i); ism.get_justifications(tmp, lits); - SASSERT(lits.size() == 1); + ENSURE(lits.size() == 1); if (lits[0] == l1) { - SASSERT(ism.subset(tmp, s1)); + ENSURE(ism.subset(tmp, s1)); } else { - SASSERT(lits[0] == l2); - SASSERT(ism.subset(tmp, s2)); + ENSURE(lits[0] == l2); + ENSURE(ism.subset(tmp, s2)); } } } @@ -293,7 +293,7 @@ static void tst5() { bool is_even[1] = { false }; nlsat::bool_var b = s.mk_ineq_atom(nlsat::atom::GT, 1, _p, is_even); nlsat::atom * a = s.bool_var2atom(b); - SASSERT(a != 0); + ENSURE(a != 0); scoped_anum zero(am); am.set(zero, 0); as.set(0, zero); @@ -432,7 +432,7 @@ static void tst7() { litsv.reset(); litsv.append(2, lits.c_ptr()); res = s.check(litsv); - SASSERT(res == l_true); + ENSURE(res == l_true); s.display(std::cout); s.am().display(std::cout, s.value(x0)); std::cout << "\n"; s.am().display(std::cout, s.value(x1)); std::cout << "\n"; diff --git a/src/test/no_overflow.cpp b/src/test/no_overflow.cpp index d795bc1fd..c528b0dbe 100644 --- a/src/test/no_overflow.cpp +++ b/src/test/no_overflow.cpp @@ -28,12 +28,12 @@ Revision History: { \ Z3_solver_push(ctx, s); \ Z3_solver_assert(ctx, s, TEST_NAME); \ - SASSERT(Z3_solver_check(ctx, s) == TEST_OUTCOME); \ + ENSURE(Z3_solver_check(ctx, s) == TEST_OUTCOME); \ Z3_solver_pop(ctx, s, 1); \ \ Z3_solver_push(ctx, s); \ Z3_solver_assert(ctx, s, Z3_mk_not(ctx, TEST_NAME)); \ - SASSERT(Z3_solver_check(ctx, s) == NEG_TEST_OUTCOME); \ + ENSURE(Z3_solver_check(ctx, s) == NEG_TEST_OUTCOME); \ Z3_solver_pop(ctx, s, 1); \ } \ } while (0) @@ -630,7 +630,7 @@ void test_equiv(Equivalence_params params, unsigned bvsize, bool is_signed) { equiv = Z3_mk_implies(ctx, cond, equiv); } Z3_solver_assert(ctx, s, Z3_mk_not(ctx, equiv)); - SASSERT(Z3_solver_check(ctx, s) == Z3_L_FALSE); + ENSURE(Z3_solver_check(ctx, s) == Z3_L_FALSE); Z3_solver_pop(ctx, s, 1); Z3_solver_dec_ref(ctx, s); @@ -662,7 +662,7 @@ void test_equiv(Equivalence_params params, unsigned bvsize, bool is_signed) { // Z3_solver_assert(ctx, s, Z3_mk_eq(ctx, t2, Z3_mk_numeral(ctx, "1", bv))); // //TEST_NO_UNDERFLOW; // Z3_solver_assert(ctx, s, test_udfl); -// SASSERT(Z3_check(ctx) == Z3_TRUE); +// ENSURE(Z3_check(ctx) == Z3_TRUE); // Z3_solver_pop(ctx, s, 1); // // Z3_del_config(cfg); diff --git a/src/test/object_allocator.cpp b/src/test/object_allocator.cpp index cca42cf6f..3ea646c0c 100644 --- a/src/test/object_allocator.cpp +++ b/src/test/object_allocator.cpp @@ -62,12 +62,12 @@ static void tst1() { cell * c3 = m.allocate(); (void)c3; - SASSERT(c3->m_coeff.is_zero()); + ENSURE(c3->m_coeff.is_zero()); } static void tst2() { cell_allocator m; - SASSERT(m.capacity() >= 2); + ENSURE(m.capacity() >= 2); cell_allocator::worker_object_allocator m1 = m.get_worker_allocator(0); cell_allocator::worker_object_allocator m2 = m.get_worker_allocator(1); m.enable_concurrent(true); @@ -83,7 +83,7 @@ static void tst2() { c = m1.allocate(); else c = m2.allocate(); - SASSERT(c->m_coeff.is_zero()); + ENSURE(c->m_coeff.is_zero()); int val = rand(); c->m_coeff = rational(val); object_coeff_pairs.push_back(std::make_pair(c, val)); @@ -93,7 +93,7 @@ static void tst2() { unsigned idx = rand() % object_coeff_pairs.size(); cell * c = object_coeff_pairs[idx].first; CTRACE("object_allocator", c->m_coeff != rational(object_coeff_pairs[idx].second), tout << c->m_coeff << " != " << rational(object_coeff_pairs[idx].second) << "\n";); - SASSERT(c->m_coeff == rational(object_coeff_pairs[idx].second)); + ENSURE(c->m_coeff == rational(object_coeff_pairs[idx].second)); if (idx < 5) m1.recycle(c); else @@ -118,5 +118,5 @@ void tst_object_allocator() { tst2(); TRACE("object_allocator", tout << "num. allocated cells: " << cell::g_num_allocated_cells << "\nnum. deallocated cells: " << cell::g_num_deallocated_cells << "\nnum. recycled cells: " << cell::g_num_recycled_cells << "\n";); - SASSERT(cell::g_num_allocated_cells == cell::g_num_deallocated_cells); + ENSURE(cell::g_num_allocated_cells == cell::g_num_deallocated_cells); } diff --git a/src/test/old_interval.cpp b/src/test/old_interval.cpp index 12a45555d..da41d0d38 100644 --- a/src/test/old_interval.cpp +++ b/src/test/old_interval.cpp @@ -23,96 +23,96 @@ static void tst1() { ext_numeral minus_inf(false); ext_numeral zero(0); - SASSERT(ext_numeral(10) + ext_numeral(3) == ext_numeral(13)); - SASSERT(inf + zero == inf); - SASSERT(minus_inf + zero == minus_inf); - SASSERT(minus_inf + ext_numeral(3) == minus_inf); - SASSERT(inf + inf == inf); - SASSERT(minus_inf + minus_inf == minus_inf); - SASSERT(minus_inf + ext_numeral(10) == minus_inf); - SASSERT(minus_inf + ext_numeral(-10) == minus_inf); - SASSERT(inf + ext_numeral(10) == inf); - SASSERT(inf + ext_numeral(-10) == inf); + ENSURE(ext_numeral(10) + ext_numeral(3) == ext_numeral(13)); + ENSURE(inf + zero == inf); + ENSURE(minus_inf + zero == minus_inf); + ENSURE(minus_inf + ext_numeral(3) == minus_inf); + ENSURE(inf + inf == inf); + ENSURE(minus_inf + minus_inf == minus_inf); + ENSURE(minus_inf + ext_numeral(10) == minus_inf); + ENSURE(minus_inf + ext_numeral(-10) == minus_inf); + ENSURE(inf + ext_numeral(10) == inf); + ENSURE(inf + ext_numeral(-10) == inf); - SASSERT(ext_numeral(10) - ext_numeral(3) == ext_numeral(7)); - SASSERT(inf - zero == inf); - SASSERT(minus_inf - zero == minus_inf); - SASSERT(minus_inf - ext_numeral(3) == minus_inf); - SASSERT(inf - minus_inf == inf); - SASSERT(minus_inf - inf == minus_inf); - SASSERT(zero - minus_inf == inf); - SASSERT(zero - inf == minus_inf); - SASSERT(ext_numeral(-10) - minus_inf == inf); - SASSERT(ext_numeral(10) - minus_inf == inf); - SASSERT(ext_numeral(-10) - inf == minus_inf); - SASSERT(ext_numeral(10) - inf == minus_inf); + ENSURE(ext_numeral(10) - ext_numeral(3) == ext_numeral(7)); + ENSURE(inf - zero == inf); + ENSURE(minus_inf - zero == minus_inf); + ENSURE(minus_inf - ext_numeral(3) == minus_inf); + ENSURE(inf - minus_inf == inf); + ENSURE(minus_inf - inf == minus_inf); + ENSURE(zero - minus_inf == inf); + ENSURE(zero - inf == minus_inf); + ENSURE(ext_numeral(-10) - minus_inf == inf); + ENSURE(ext_numeral(10) - minus_inf == inf); + ENSURE(ext_numeral(-10) - inf == minus_inf); + ENSURE(ext_numeral(10) - inf == minus_inf); - SASSERT(ext_numeral(10) * inf == inf); - SASSERT(ext_numeral(-10) * inf == minus_inf); - SASSERT(zero * inf == zero); - SASSERT(zero * minus_inf == zero); - SASSERT(zero * ext_numeral(10) == zero); - SASSERT(ext_numeral(10) * ext_numeral(-20) == ext_numeral(-200)); - SASSERT(ext_numeral(3) * ext_numeral(2) == ext_numeral(6)); - SASSERT(inf * inf == inf); - SASSERT(inf * minus_inf == minus_inf); - SASSERT(minus_inf * minus_inf == inf); - SASSERT(minus_inf * inf == minus_inf); - SASSERT(minus_inf * ext_numeral(10) == minus_inf); - SASSERT(minus_inf * ext_numeral(-10) == inf); + ENSURE(ext_numeral(10) * inf == inf); + ENSURE(ext_numeral(-10) * inf == minus_inf); + ENSURE(zero * inf == zero); + ENSURE(zero * minus_inf == zero); + ENSURE(zero * ext_numeral(10) == zero); + ENSURE(ext_numeral(10) * ext_numeral(-20) == ext_numeral(-200)); + ENSURE(ext_numeral(3) * ext_numeral(2) == ext_numeral(6)); + ENSURE(inf * inf == inf); + ENSURE(inf * minus_inf == minus_inf); + ENSURE(minus_inf * minus_inf == inf); + ENSURE(minus_inf * inf == minus_inf); + ENSURE(minus_inf * ext_numeral(10) == minus_inf); + ENSURE(minus_inf * ext_numeral(-10) == inf); - SASSERT(minus_inf < inf); - SASSERT(!(inf < minus_inf)); - SASSERT(minus_inf < ext_numeral(10)); - SASSERT(ext_numeral(-3) < inf); - SASSERT(ext_numeral(-10) < ext_numeral(4)); - SASSERT(ext_numeral(2) < ext_numeral(10)); - SASSERT(!(inf < ext_numeral(30))); - SASSERT(!(ext_numeral(10) < minus_inf)); - SASSERT(!(inf < inf)); - SASSERT(!(minus_inf < minus_inf)); - SASSERT(!(zero < zero)); - SASSERT(!(ext_numeral(10) < ext_numeral(10))); - SASSERT(inf > minus_inf); - SASSERT(inf > zero); - SASSERT(inf > ext_numeral(10)); - SASSERT(ext_numeral(10) > minus_inf); - SASSERT(zero > minus_inf); - SASSERT(!(zero > inf)); - SASSERT(!(minus_inf > inf)); - SASSERT(inf >= minus_inf); - SASSERT(inf >= inf); - SASSERT(minus_inf >= minus_inf); - SASSERT(inf >= zero); - SASSERT(zero >= minus_inf); - SASSERT(inf <= inf); - SASSERT(minus_inf <= minus_inf); - SASSERT(zero <= inf); - SASSERT(minus_inf <= zero); + ENSURE(minus_inf < inf); + ENSURE(!(inf < minus_inf)); + ENSURE(minus_inf < ext_numeral(10)); + ENSURE(ext_numeral(-3) < inf); + ENSURE(ext_numeral(-10) < ext_numeral(4)); + ENSURE(ext_numeral(2) < ext_numeral(10)); + ENSURE(!(inf < ext_numeral(30))); + ENSURE(!(ext_numeral(10) < minus_inf)); + ENSURE(!(inf < inf)); + ENSURE(!(minus_inf < minus_inf)); + ENSURE(!(zero < zero)); + ENSURE(!(ext_numeral(10) < ext_numeral(10))); + ENSURE(inf > minus_inf); + ENSURE(inf > zero); + ENSURE(inf > ext_numeral(10)); + ENSURE(ext_numeral(10) > minus_inf); + ENSURE(zero > minus_inf); + ENSURE(!(zero > inf)); + ENSURE(!(minus_inf > inf)); + ENSURE(inf >= minus_inf); + ENSURE(inf >= inf); + ENSURE(minus_inf >= minus_inf); + ENSURE(inf >= zero); + ENSURE(zero >= minus_inf); + ENSURE(inf <= inf); + ENSURE(minus_inf <= minus_inf); + ENSURE(zero <= inf); + ENSURE(minus_inf <= zero); ext_numeral val(10); val.neg(); - SASSERT(val == ext_numeral(-10)); + ENSURE(val == ext_numeral(-10)); val = inf; val.neg(); - SASSERT(val == minus_inf); + ENSURE(val == minus_inf); val.neg(); - SASSERT(val == inf); + ENSURE(val == inf); - SASSERT(minus_inf.sign()); - SASSERT(!zero.sign()); - SASSERT(!inf.sign()); - SASSERT(ext_numeral(-10).sign()); - SASSERT(!ext_numeral(10).sign()); + ENSURE(minus_inf.sign()); + ENSURE(!zero.sign()); + ENSURE(!inf.sign()); + ENSURE(ext_numeral(-10).sign()); + ENSURE(!ext_numeral(10).sign()); - SASSERT(inf.is_infinite()); - SASSERT(minus_inf.is_infinite()); - SASSERT(!zero.is_infinite()); - SASSERT(!ext_numeral(10).is_infinite()); - SASSERT(!inf.is_zero()); - SASSERT(!minus_inf.is_zero()); - SASSERT(zero.is_zero()); - SASSERT(!ext_numeral(10).is_zero()); + ENSURE(inf.is_infinite()); + ENSURE(minus_inf.is_infinite()); + ENSURE(!zero.is_infinite()); + ENSURE(!ext_numeral(10).is_infinite()); + ENSURE(!inf.is_zero()); + ENSURE(!minus_inf.is_zero()); + ENSURE(zero.is_zero()); + ENSURE(!ext_numeral(10).is_zero()); } class interval_tester { @@ -182,12 +182,12 @@ static void tst2() { m.set(y, mpz(-2), mpz(3)); m.add(x, y, z); std::cout << "x: " << x << ", y: " << y << ", z: " << z << "\n"; - SASSERT(nm.eq(z.lower(), mpz(-1))); - SASSERT(nm.eq(z.upper(), mpz(5))); + ENSURE(nm.eq(z.lower(), mpz(-1))); + ENSURE(nm.eq(z.upper(), mpz(5))); m.mul(x, y, z); std::cout << "x: " << x << ", y: " << y << ", z: " << z << "\n"; - SASSERT(nm.eq(z.lower(), mpz(-4))); - SASSERT(nm.eq(z.upper(), mpz(6))); + ENSURE(nm.eq(z.lower(), mpz(-4))); + ENSURE(nm.eq(z.upper(), mpz(6))); } void tst_old_interval() { diff --git a/src/test/optional.cpp b/src/test/optional.cpp index 81b84cd59..40ca383a5 100644 --- a/src/test/optional.cpp +++ b/src/test/optional.cpp @@ -22,11 +22,11 @@ Revision History: static void tst1() { optional v; - SASSERT(!v); - SASSERT(v == false); + ENSURE(!v); + ENSURE(v == false); v = 10; - SASSERT(v); - SASSERT(*v == 10); + ENSURE(v); + ENSURE(*v == 10); TRACE("optional", tout << sizeof(v) << "\n";); } @@ -45,25 +45,25 @@ struct OptFoo { static void tst2() { optional v; - SASSERT(!v); + ENSURE(!v); v = OptFoo(10, 20); - SASSERT(v->m_x == 10); - SASSERT(v->m_y == 20); + ENSURE(v->m_x == 10); + ENSURE(v->m_y == 20); v = OptFoo(200, 300); - SASSERT(v->m_x == 200); - SASSERT(v->m_y == 300); + ENSURE(v->m_x == 200); + ENSURE(v->m_y == 300); TRACE("optional", tout << sizeof(v) << "\n";); } static void tst3() { optional v; - SASSERT(!v); + ENSURE(!v); int x = 10; v = &x; - SASSERT(v); - SASSERT(*v == &x); + ENSURE(v); + ENSURE(*v == &x); TRACE("optional", tout << sizeof(v) << "\n";); - SASSERT(*(*v) == 10); + ENSURE(*(*v) == 10); } void tst_optional() { diff --git a/src/test/parray.cpp b/src/test/parray.cpp index 7976971d8..df0fde516 100644 --- a/src/test/parray.cpp +++ b/src/test/parray.cpp @@ -46,36 +46,36 @@ static void tst1() { int_array a3; m.mk(a1); - SASSERT(m.size(a1) == 0); + ENSURE(m.size(a1) == 0); m.push_back(a1, 10, a2); TRACE("parray", m.display_info(tout, a1); tout << "\n"; m.display_info(tout, a2); tout << "\n";); - SASSERT(m.size(a1) == 0); - SASSERT(m.size(a2) == 1); + ENSURE(m.size(a1) == 0); + ENSURE(m.size(a2) == 1); m.push_back(a1, 20, a1); m.push_back(a1, 30, a1); TRACE("parray", m.display_info(tout, a1); tout << "\n"; m.display_info(tout, a2); tout << "\n";); - SASSERT(m.get(a1, 0) == 20); - SASSERT(m.get(a1, 1) == 30); - SASSERT(m.get(a2, 0) == 10); - SASSERT(m.size(a1) == 2); - SASSERT(m.size(a2) == 1); - SASSERT(m.size(a3) == 0); + ENSURE(m.get(a1, 0) == 20); + ENSURE(m.get(a1, 1) == 30); + ENSURE(m.get(a2, 0) == 10); + ENSURE(m.size(a1) == 2); + ENSURE(m.size(a2) == 1); + ENSURE(m.size(a3) == 0); m.push_back(a2, 100, a3); - SASSERT(m.size(a3) == 2); - SASSERT(m.get(a3, 0) == 10); - SASSERT(m.get(a3, 1) == 100); + ENSURE(m.size(a3) == 2); + ENSURE(m.get(a3, 0) == 10); + ENSURE(m.get(a3, 1) == 100); TRACE("parray", m.display_info(tout, a1); tout << "\n"; m.display_info(tout, a2); tout << "\n"; m.display_info(tout, a3); tout << "\n";); m.push_back(a2, 50); - SASSERT(m.get(a2, 0) == 10); - SASSERT(m.get(a2, 1) == 50); - SASSERT(m.size(a2) == 2); + ENSURE(m.get(a2, 0) == 10); + ENSURE(m.get(a2, 1) == 50); + ENSURE(m.size(a2) == 2); TRACE("parray", m.display_info(tout, a1); tout << "\n"; m.display_info(tout, a2); tout << "\n"; @@ -100,22 +100,22 @@ static void tst2() { for (unsigned i = 0; i < 100; i++) m.push_back(a1, i); - SASSERT(m.size(a1) == 100); + ENSURE(m.size(a1) == 100); m.push_back(a1, 100, a2); for (unsigned i = 0; i < 10; i++) m.push_back(a2, i+101); TRACE("parray", m.display_info(tout, a1); tout << "\n"; m.display_info(tout, a2); tout << "\n";); - SASSERT(m.get(a1, 0) == 0); + ENSURE(m.get(a1, 0) == 0); TRACE("parray", m.display_info(tout, a1); tout << "\n"; m.display_info(tout, a2); tout << "\n";); for (unsigned i = 0; i < m.size(a1); i++) { - SASSERT(static_cast(m.get(a1, i)) == i); + ENSURE(static_cast(m.get(a1, i)) == i); } for (unsigned i = 0; i < m.size(a2); i++) { - SASSERT(static_cast(m.get(a2, i)) == i); + ENSURE(static_cast(m.get(a2, i)) == i); } TRACE("parray", m.display_info(tout, a1); tout << "\n"; @@ -145,7 +145,7 @@ static void tst3() { for (unsigned i = 0; i < 20; i++) m.push_back(a1, i); - SASSERT(m.size(a1) == 20); + ENSURE(m.size(a1) == 20); m.set(a1, 0, 1, a2); for (unsigned i = 1; i < 20; i++) { if (i == 6) { @@ -161,7 +161,7 @@ static void tst3() { m.push_back(a4, 30); for (unsigned i = 0; i < 20; i++) { - SASSERT(static_cast(m.get(a2, i)) == i+1); + ENSURE(static_cast(m.get(a2, i)) == i+1); } TRACE("parray", m.display_info(tout, a1); tout << "\n"; @@ -169,7 +169,7 @@ static void tst3() { m.display_info(tout, a3); tout << "\n"; m.display_info(tout, a4); tout << "\n"; ); - SASSERT(m.get(a1, 10) == 10); + ENSURE(m.get(a1, 10) == 10); TRACE("parray", tout << "after rerooting...\n"; m.display_info(tout, a1); tout << "\n"; @@ -177,19 +177,19 @@ static void tst3() { m.display_info(tout, a3); tout << "\n"; m.display_info(tout, a4); tout << "\n"; ); - SASSERT(m.size(a1) == 20); - SASSERT(m.size(a2) == 20); - SASSERT(m.size(a3) == 19); - SASSERT(m.size(a4) == 19); + ENSURE(m.size(a1) == 20); + ENSURE(m.size(a2) == 20); + ENSURE(m.size(a3) == 19); + ENSURE(m.size(a4) == 19); for (unsigned i = 0; i < 20; i++) { - SASSERT(static_cast(m.get(a1, i)) == i); - SASSERT(static_cast(m.get(a2, i)) == i+1); - SASSERT(i >= 18 || static_cast(m.get(a4, i)) == i+1); - SASSERT(i >= 6 || static_cast(m.get(a3, i)) == i+1); - SASSERT(!(6 <= i && i <= 17) || static_cast(m.get(a3, i)) == i); + ENSURE(static_cast(m.get(a1, i)) == i); + ENSURE(static_cast(m.get(a2, i)) == i+1); + ENSURE(i >= 18 || static_cast(m.get(a4, i)) == i+1); + ENSURE(i >= 6 || static_cast(m.get(a3, i)) == i+1); + ENSURE(!(6 <= i && i <= 17) || static_cast(m.get(a3, i)) == i); } - SASSERT(m.get(a4, 18) == 30); - SASSERT(m.get(a3, 18) == 40); + ENSURE(m.get(a4, 18) == 30); + ENSURE(m.get(a3, 18) == 40); TRACE("parray", tout << "after many gets...\n"; m.display_info(tout, a1); tout << "\n"; diff --git a/src/test/pb2bv.cpp b/src/test/pb2bv.cpp index fcc309883..07cb047b3 100644 --- a/src/test/pb2bv.cpp +++ b/src/test/pb2bv.cpp @@ -81,7 +81,7 @@ static void test_semantics(ast_manager& m, expr_ref_vector const& vars, vectorcheck_sat(0,0); VERIFY(res == l_true); slv->assert_expr(m.is_true(result2) ? m.mk_not(result1) : result1.get()); diff --git a/src/test/permutation.cpp b/src/test/permutation.cpp index d5929b6c0..e0d208520 100644 --- a/src/test/permutation.cpp +++ b/src/test/permutation.cpp @@ -48,7 +48,7 @@ static void tst1(unsigned sz, unsigned num_tries, unsigned max = UINT_MAX) { apply_permutation(sz, data.c_ptr(), p.c_ptr()); // std::cout << "data: "; display(std::cout, data.begin(), data.end()); std::cout << "\n"; for (unsigned i = 0; i < 0; i++) - SASSERT(data[i] == new_data[i]); + ENSURE(data[i] == new_data[i]); } #endif } diff --git a/src/test/polynomial.cpp b/src/test/polynomial.cpp index 03eb321cd..0a6418a6c 100644 --- a/src/test/polynomial.cpp +++ b/src/test/polynomial.cpp @@ -39,7 +39,7 @@ static void tst1() { p = (x0^3) + x1*x0 + 2; std::cout << p << "\n"; std::cout << "max_var(p): " << max_var(p) << "\n"; - SASSERT(max_var(p) == 1); + ENSURE(max_var(p) == 1); std::cout << (2*x2 - x1*x0) << "\n"; std::cout << (p + (2*x2 - x1*x0)) << "\n"; std::cout << (p*p + 2*x2) << "\n"; @@ -79,7 +79,7 @@ static void tst_pseudo_div(polynomial_ref const & A, polynomial_ref const & B, p std::cout << "l_B^d: " << l_B_d << "\n"; std::cout << "Q * B + R: " << Q * B + R << "\n"; std::cout << "l_B_d * A: " << l_B_d * A << "\n"; - SASSERT(eq((Q * B + R), (l_B_d * A))); + ENSURE(eq((Q * B + R), (l_B_d * A))); } static void tst2() { @@ -329,13 +329,13 @@ static void tst11() { polynomial_ref d(m); d = exact_div(p, q); std::cout << "p: " << p << "\nq: " << q << "\nd: " << d << "\n"; - SASSERT(eq(q * d, p)); + ENSURE(eq(q * d, p)); q = ((x1^3) + x1 + 1)*((x2^2) + x2 + x2 + 1)*((x3^2) + 2); p = (x1 + (x3^2) + x3 + x2 + (x2^2) + 1)*((x1^3) + x1 + 1)*((x2^2) + x2 + x2 + 1)*((x3^2) + 2); d = exact_div(p, q); std::cout << "p: " << p << "\nq: " << q << "\nd: " << d << "\n"; - SASSERT(eq(q * d, p)); + ENSURE(eq(q * d, p)); } static void tst_discriminant(polynomial_ref const & p, polynomial::var x, polynomial_ref const & expected) { @@ -344,7 +344,7 @@ static void tst_discriminant(polynomial_ref const & p, polynomial::var x, polyno r = discriminant(p, x); std::cout << "r: " << r << "\n"; std::cout << "expected: " << expected << "\n"; - SASSERT(eq(r, expected)); + ENSURE(eq(r, expected)); m.lex_sort(r); std::cout << "r (sorted): " << r << "\n"; } @@ -463,7 +463,7 @@ static void tst_resultant(polynomial_ref const & p, polynomial_ref const & q, po std::cout << "expected: " << expected << "\n"; if (degree(p, x) > 0 && degree(q, x) > 0) std::cout << "quasi-resultant: " << quasi_resultant(p, q, x) << "\n"; - SASSERT(eq(r, expected)); + ENSURE(eq(r, expected)); m.lex_sort(r); std::cout << "r (sorted): " << r << "\n"; } @@ -570,8 +570,8 @@ static void tst_compose() { p = (x0^3) - x0 + 3; std::cout << "p: " << p << "\np(x - y): " << compose_x_minus_y(p, 1) << "\np(x + y): " << compose_x_plus_y(p, 1) << "\np(x - x): " << compose_x_minus_y(p, 0) << "\np(x + x): " << compose_x_plus_y(p, 0) << "\n"; - SASSERT(eq(compose_x_minus_y(p, 1), (x0^3) - 3*(x0^2)*x1 + 3*x0*(x1^2) - (x1^3) - x0 + x1 + 3)); - SASSERT(eq(compose_x_plus_y(p, 1), (x0^3) + 3*(x0^2)*x1 + 3*x0*(x1^2) + (x1^3) - x0 - x1 + 3)); + ENSURE(eq(compose_x_minus_y(p, 1), (x0^3) - 3*(x0^2)*x1 + 3*x0*(x1^2) - (x1^3) - x0 + x1 + 3)); + ENSURE(eq(compose_x_plus_y(p, 1), (x0^3) + 3*(x0^2)*x1 + 3*x0*(x1^2) + (x1^3) - x0 - x1 + 3)); } void tst_prem() { @@ -604,11 +604,11 @@ void tst_sqrt() { p = (4*x*y + 3*(x^2)*y + (y^2) + 3)^4; polynomial_ref q(m); VERIFY(sqrt(p, q)); - SASSERT(eq(p, q*q)); + ENSURE(eq(p, q*q)); std::cout << "p: " << p << "\n"; std::cout << "q: " << q << "\n"; p = p - 1; - SASSERT(!sqrt(p, q)); + ENSURE(!sqrt(p, q)); } static void tst_content(polynomial_ref const & p, polynomial::var x, polynomial_ref const & expected) { @@ -616,7 +616,7 @@ static void tst_content(polynomial_ref const & p, polynomial::var x, polynomial_ std::cout << "p: " << p << std::endl; std::cout << "content(p): " << content(p, x) << std::endl; std::cout << "expected: " << expected << std::endl; - SASSERT(eq(content(p, x), expected)); + ENSURE(eq(content(p, x), expected)); } static void tst_primitive(polynomial_ref const & p, polynomial::var x, polynomial_ref const & expected) { @@ -624,7 +624,7 @@ static void tst_primitive(polynomial_ref const & p, polynomial::var x, polynomia std::cout << "p: " << p << std::endl; std::cout << "primitive(p): " << primitive(p, x) << std::endl; std::cout << "expected: " << expected << std::endl; - SASSERT(eq(primitive(p, x), expected)); + ENSURE(eq(primitive(p, x), expected)); } static void tst_gcd(polynomial_ref const & p, polynomial_ref const & q, polynomial_ref const & expected) { @@ -635,7 +635,7 @@ static void tst_gcd(polynomial_ref const & p, polynomial_ref const & q, polynomi r = gcd(p, q); std::cout << "gcd(p, q): " << r << std::endl; std::cout << "expected: " << expected << std::endl; - SASSERT(eq(r, expected)); + ENSURE(eq(r, expected)); } static void tst_gcd() { @@ -711,15 +711,15 @@ static void tst_psc(polynomial_ref const & p, polynomial_ref const & q, polynomi std::cout << "S_" << i << ": " << polynomial_ref(S.get(i), m) << std::endl; } if (sz > 0) { - SASSERT(m.eq(S.get(0), first) || m.eq(S.get(0), neg(first))); + ENSURE(m.eq(S.get(0), first) || m.eq(S.get(0), neg(first))); } if (sz > 1) { - SASSERT(m.eq(S.get(1), second) || m.eq(S.get(1), neg(second))); + ENSURE(m.eq(S.get(1), second) || m.eq(S.get(1), neg(second))); } if (sz > 0) { polynomial_ref Res(m); Res = resultant(p, q, x); - SASSERT(m.eq(Res, S.get(0)) || m.eq(S.get(0), neg(Res))); + ENSURE(m.eq(Res, S.get(0)) || m.eq(S.get(0), neg(Res))); } } @@ -843,11 +843,11 @@ static void tst_vars(polynomial_ref const & p, unsigned sz, polynomial::var * xs std::cout << r[i] << " "; } std::cout << std::endl; - SASSERT(r.size() == sz); + ENSURE(r.size() == sz); std::sort(r.begin(), r.end()); std::sort(xs, xs + sz); for (unsigned i = 0; i < r.size(); i++) { - SASSERT(r[i] == xs[i]); + ENSURE(r[i] == xs[i]); } } @@ -886,9 +886,9 @@ static void tst_sqf(polynomial_ref const & p, polynomial_ref const & expected) { r = square_free(p); std::cout << "sqf(p): " << r << std::endl; std::cout << "expected: " << expected << std::endl; - SASSERT(is_square_free(r)); - SASSERT(!eq(r, p) || is_square_free(p)); - SASSERT(eq(expected, r)); + ENSURE(is_square_free(r)); + ENSURE(!eq(r, p) || is_square_free(p)); + ENSURE(eq(expected, r)); } static void tst_sqf() { @@ -931,7 +931,7 @@ static void tst_substitute(polynomial_ref const & p, r = p.m().substitute(p, 2, xs, vs.c_ptr()); std::cout << "r: " << r << std::endl; std::cout << "expected: " << expected << std::endl; - SASSERT(eq(r, expected)); + ENSURE(eq(r, expected)); p.m().lex_sort(r); std::cout << "r (sorted): " << r << std::endl; } @@ -972,7 +972,7 @@ static void tst_qsubstitute(polynomial_ref const & p, r = p.m().substitute(p, 2, xs, vs.c_ptr()); std::cout << "r: " << r << std::endl; std::cout << "expected (modulo a constant): " << expected << std::endl; - SASSERT(eq(r, normalize(expected))); + ENSURE(eq(r, normalize(expected))); p.m().lex_sort(r); std::cout << "r (sorted): " << r << std::endl; } @@ -1024,10 +1024,10 @@ void tst_mfact(polynomial_ref const & p, unsigned num_distinct_factors) { for (unsigned i = 0; i < fs.distinct_factors(); i++) { std::cout << "*(" << fs[i] << ")^" << fs.get_degree(i) << std::endl; } - SASSERT(fs.distinct_factors() == num_distinct_factors); + ENSURE(fs.distinct_factors() == num_distinct_factors); polynomial_ref p2(p.m()); fs.multiply(p2); - SASSERT(eq(p, p2)); + ENSURE(eq(p, p2)); } static void tst_mfact() { @@ -1247,7 +1247,7 @@ static void tst_translate(polynomial_ref const & p, polynomial::var x0, int v0, polynomial_ref r(p.m()); p.m().translate(p, 3, xs, vs, r); std::cout << "r: " << r << std::endl; - SASSERT(eq(expected, r)); + ENSURE(eq(expected, r)); } static void tst_translate() { @@ -1326,11 +1326,11 @@ static void tst_mm() { std::cout << "p1: " << p1 << "\n"; p2 = convert(pm1, p1, pm2); std::cout << "p2: " << p2 << "\n"; - SASSERT(pm1.get_monomial(p1, 0) == pm2.get_monomial(p2, 0)); + ENSURE(pm1.get_monomial(p1, 0) == pm2.get_monomial(p2, 0)); polynomial_ref p3(pm3); p3 = convert(pm1, p1, pm3); - SASSERT(pm1.get_monomial(p1, 0) != pm3.get_monomial(p3, 0)); + ENSURE(pm1.get_monomial(p1, 0) != pm3.get_monomial(p3, 0)); } dealloc(pm1_ptr); // p2 is still ok @@ -1351,7 +1351,7 @@ static void tst_eval(polynomial_ref const & p, polynomial::var x0, rational v0, std::cout << "r: " << r << "\nexpected: " << expected << "\n"; scoped_mpq ex(qm); qm.set(ex, expected.to_mpq()); - SASSERT(qm.eq(r, ex)); + ENSURE(qm.eq(r, ex)); } static void tst_eval() { @@ -1407,18 +1407,18 @@ static void tst_mk_unique() { std::cout << "p: " << p << "\n"; std::cout << "q: " << q << "\n"; std::cout << "r: " << r << "\n"; - SASSERT(m.eq(p, q)); - SASSERT(!m.eq(p, r)); - SASSERT(p.get() != q.get()); + ENSURE(m.eq(p, q)); + ENSURE(!m.eq(p, r)); + ENSURE(p.get() != q.get()); q = uniq.mk_unique(q); p = uniq.mk_unique(p); r = uniq.mk_unique(r); std::cout << "after mk_unique\np: " << p << "\n"; std::cout << "q: " << q << "\n"; std::cout << "r: " << r << "\n"; - SASSERT(m.eq(p, q)); - SASSERT(!m.eq(r, q)); - SASSERT(p.get() == q.get()); + ENSURE(m.eq(p, q)); + ENSURE(!m.eq(r, q)); + ENSURE(p.get() == q.get()); } struct dummy_del_eh : public polynomial::manager::del_eh { @@ -1442,24 +1442,24 @@ static void tst_del_eh() { m.add_del_eh(&eh1); x1 = 0; - SASSERT(eh1.m_counter == 1); + ENSURE(eh1.m_counter == 1); m.add_del_eh(&eh2); x1 = m.mk_polynomial(m.mk_var()); x1 = 0; - SASSERT(eh1.m_counter == 2); - SASSERT(eh2.m_counter == 1); + ENSURE(eh1.m_counter == 2); + ENSURE(eh2.m_counter == 1); m.remove_del_eh(&eh1); x0 = 0; x1 = m.mk_polynomial(m.mk_var()); x1 = 0; - SASSERT(eh1.m_counter == 2); - SASSERT(eh2.m_counter == 3); + ENSURE(eh1.m_counter == 2); + ENSURE(eh2.m_counter == 3); m.remove_del_eh(&eh2); x1 = m.mk_polynomial(m.mk_var()); x1 = 0; - SASSERT(eh1.m_counter == 2); - SASSERT(eh2.m_counter == 3); + ENSURE(eh1.m_counter == 2); + ENSURE(eh2.m_counter == 3); } static void tst_const_coeff() { @@ -1475,36 +1475,36 @@ static void tst_const_coeff() { polynomial_ref p(m); p = (x0^2)*x1 + 3*x0 + x1; - SASSERT(!m.const_coeff(p, 0, 2, c)); - SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); - SASSERT(!m.const_coeff(p, 0, 0, c)); + ENSURE(!m.const_coeff(p, 0, 2, c)); + ENSURE(m.const_coeff(p, 0, 1, c) && c == 3); + ENSURE(!m.const_coeff(p, 0, 0, c)); p = (x0^2)*x1 + 3*x0 + x1 + 1; - SASSERT(!m.const_coeff(p, 0, 2, c)); - SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); - SASSERT(!m.const_coeff(p, 0, 0, c)); + ENSURE(!m.const_coeff(p, 0, 2, c)); + ENSURE(m.const_coeff(p, 0, 1, c) && c == 3); + ENSURE(!m.const_coeff(p, 0, 0, c)); p = (x0^2)*x1 + 3*x0 + 1; - SASSERT(!m.const_coeff(p, 0, 2, c)); - SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); - SASSERT(m.const_coeff(p, 0, 0, c) && c == 1); + ENSURE(!m.const_coeff(p, 0, 2, c)); + ENSURE(m.const_coeff(p, 0, 1, c) && c == 3); + ENSURE(m.const_coeff(p, 0, 0, c) && c == 1); p = x1 + 3*x0 + 1; - SASSERT(m.const_coeff(p, 0, 2, c) && c == 0); - SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); - SASSERT(!m.const_coeff(p, 0, 0, c)); + ENSURE(m.const_coeff(p, 0, 2, c) && c == 0); + ENSURE(m.const_coeff(p, 0, 1, c) && c == 3); + ENSURE(!m.const_coeff(p, 0, 0, c)); p = 5*(x0^2) + 3*x0 + 7; - SASSERT(m.const_coeff(p, 0, 5, c) && c == 0); - SASSERT(m.const_coeff(p, 0, 2, c) && c == 5); - SASSERT(m.const_coeff(p, 0, 1, c) && c == 3); - SASSERT(m.const_coeff(p, 0, 0, c) && c == 7); + ENSURE(m.const_coeff(p, 0, 5, c) && c == 0); + ENSURE(m.const_coeff(p, 0, 2, c) && c == 5); + ENSURE(m.const_coeff(p, 0, 1, c) && c == 3); + ENSURE(m.const_coeff(p, 0, 0, c) && c == 7); p = 5*(x0^2) + 3*x0; - SASSERT(m.const_coeff(p, 0, 0, c) && c == 0); + ENSURE(m.const_coeff(p, 0, 0, c) && c == 0); p = - x0*x1 - x1 + 1; - SASSERT(!m.const_coeff(p, 0, 1, c)); + ENSURE(!m.const_coeff(p, 0, 1, c)); } static void tst_gcd2() { @@ -1669,7 +1669,7 @@ static void tst_newton_interpolation() { m.newton_interpolation(0, 2, ins.c_ptr(), outs, r); } std::cout << "interpolation result: " << r << "\n"; - SASSERT(m.eq((x^2)*y + 5*x*y + 41*x - 9*y - 21, r)); + ENSURE(m.eq((x^2)*y + 5*x*y + 41*x - 9*y - 21, r)); } static void tst_slow_mod_gcd() { @@ -1732,9 +1732,9 @@ void tst_linear_solver() { solver.add(2, as.c_ptr(), b); VERIFY(solver.solve(xs.c_ptr())); - SASSERT(qm.eq(xs[0], mpq(2))); - SASSERT(qm.eq(xs[1], mpq(3))); - SASSERT(qm.eq(xs[2], mpq(-1))); + ENSURE(qm.eq(xs[0], mpq(2))); + ENSURE(qm.eq(xs[1], mpq(3))); + ENSURE(qm.eq(xs[2], mpq(-1))); } static void tst_lex(polynomial_ref const & p1, polynomial_ref const & p2, int lex_expected, polynomial::var min, int lex2_expected) { @@ -1746,11 +1746,11 @@ static void tst_lex(polynomial_ref const & p1, polynomial_ref const & p2, int le std::cout << " "; std::cout.flush(); int r1 = lex_compare(m.get_monomial(p1, 0), m.get_monomial(p2, 0)); int r2 = lex_compare2(m.get_monomial(p1, 0), m.get_monomial(p2, 0), min); - SASSERT(r1 == lex_expected); - SASSERT(r2 == lex2_expected); + ENSURE(r1 == lex_expected); + ENSURE(r2 == lex2_expected); std::cout << r1 << " " << r2 << "\n"; - SASSERT(lex_compare(m.get_monomial(p2, 0), m.get_monomial(p1, 0)) == -r1); - SASSERT(lex_compare2(m.get_monomial(p2, 0), m.get_monomial(p1, 0), min) == -r2); + ENSURE(lex_compare(m.get_monomial(p2, 0), m.get_monomial(p1, 0)) == -r1); + ENSURE(lex_compare2(m.get_monomial(p2, 0), m.get_monomial(p1, 0), min) == -r2); } static void tst_lex() { diff --git a/src/test/polynorm.cpp b/src/test/polynorm.cpp index 987d8e13b..03735fef9 100644 --- a/src/test/polynorm.cpp +++ b/src/test/polynorm.cpp @@ -25,7 +25,7 @@ static expr_ref parse_fml(ast_manager& m, char const* str) { << "(assert " << str << ")\n"; std::istringstream is(buffer.str()); VERIFY(parse_smt2_commands(ctx, is)); - SASSERT(ctx.begin_assertions() != ctx.end_assertions()); + ENSURE(ctx.begin_assertions() != ctx.end_assertions()); result = *ctx.begin_assertions(); return result; } @@ -125,8 +125,8 @@ private: else if (m_arith.is_numeral(f, r)) { factors[i] = factors.back(); factors.pop_back(); - SASSERT(coefficient.is_zero()); - SASSERT(!r.is_zero()); + ENSURE(coefficient.is_zero()); + ENSURE(!r.is_zero()); coefficient = r; --i; // repeat examining 'i' } @@ -205,8 +205,8 @@ static void nf(expr_ref& term) { else if (arith.is_numeral(f, r)) { factors[i] = factors.back(); factors.pop_back(); - SASSERT(coefficient.is_zero()); - SASSERT(!r.is_zero()); + ENSURE(coefficient.is_zero()); + ENSURE(!r.is_zero()); coefficient = r; --i; // repeat examining 'i' } diff --git a/src/test/prime_generator.cpp b/src/test/prime_generator.cpp index a2610b35e..5af014e0a 100644 --- a/src/test/prime_generator.cpp +++ b/src/test/prime_generator.cpp @@ -35,7 +35,7 @@ void tst_prime_generator() { m.root(sqrt_p, 2); uint64 k = m.get_uint64(sqrt_p); for (uint64 i = 2; i <= k; i++) { - SASSERT(p % i != 0); + ENSURE(p % i != 0); } } std::cout << std::endl; diff --git a/src/test/qe_arith.cpp b/src/test/qe_arith.cpp index a52c02ecb..83b6e2620 100644 --- a/src/test/qe_arith.cpp +++ b/src/test/qe_arith.cpp @@ -37,7 +37,7 @@ static expr_ref parse_fml(ast_manager& m, char const* str) { << "(assert " << str << ")\n"; std::istringstream is(buffer.str()); VERIFY(parse_smt2_commands(ctx, is)); - SASSERT(ctx.begin_assertions() != ctx.end_assertions()); + ENSURE(ctx.begin_assertions() != ctx.end_assertions()); result = *ctx.begin_assertions(); return result; } diff --git a/src/test/quant_solve.cpp b/src/test/quant_solve.cpp index ed332ce26..2dc987d77 100644 --- a/src/test/quant_solve.cpp +++ b/src/test/quant_solve.cpp @@ -39,7 +39,7 @@ static void validate_quant_solution(ast_manager& m, expr* fml, expr* guard, qe:: smt::kernel solver(m, fp); solver.assert_expr(tmp); lbool res = solver.check(); - //SASSERT(res == l_false); + //ENSURE(res == l_false); if (res != l_false) { std::cout << "Validation failed: " << res << "\n"; std::cout << mk_pp(tmp, m) << "\n"; @@ -75,7 +75,7 @@ static void validate_quant_solutions(app* x, expr* fml, expr_ref_vector& guards) solver.assert_expr(tmp); lbool res = solver.check(); std::cout << "checked\n"; - SASSERT(res == l_false); + ENSURE(res == l_false); if (res != l_false) { std::cout << res << "\n"; fatal_error(0); @@ -131,7 +131,7 @@ static expr_ref parse_fml(ast_manager& m, char const* str) { << "(assert " << str << ")\n"; std::istringstream is(buffer.str()); VERIFY(parse_smt2_commands(ctx, is)); - SASSERT(ctx.begin_assertions() != ctx.end_assertions()); + ENSURE(ctx.begin_assertions() != ctx.end_assertions()); result = *ctx.begin_assertions(); return result; } diff --git a/src/test/rational.cpp b/src/test/rational.cpp index ac478af98..6fa1005b0 100644 --- a/src/test/rational.cpp +++ b/src/test/rational.cpp @@ -27,85 +27,85 @@ static void tst1() { rational r1(1); rational r2(1,2); rational r3(2,4); - SASSERT(r2 == r3); - SASSERT(r1 != r2); - SASSERT(r2 + r3 == r1); - SASSERT(r1.is_pos()); - SASSERT((r2 - r1).is_neg()); - SASSERT((r2 - r3).is_zero()); - SASSERT(floor(r2).is_zero()); - SASSERT(ceil(r2).is_one()); + ENSURE(r2 == r3); + ENSURE(r1 != r2); + ENSURE(r2 + r3 == r1); + ENSURE(r1.is_pos()); + ENSURE((r2 - r1).is_neg()); + ENSURE((r2 - r3).is_zero()); + ENSURE(floor(r2).is_zero()); + ENSURE(ceil(r2).is_one()); // std::cout << "-r2: " << (-r2) << ", floor(-r2):" << floor(-r2) << "\n"; - SASSERT(floor(-r2).is_minus_one()); - SASSERT(ceil(-r2).is_zero()); - SASSERT(floor(r1) == r1); - SASSERT(ceil(r1) == r1); + ENSURE(floor(-r2).is_minus_one()); + ENSURE(ceil(-r2).is_zero()); + ENSURE(floor(r1) == r1); + ENSURE(ceil(r1) == r1); rational r4(3,5); - SASSERT(r3 * r4 == rational(3, 10)); - SASSERT(r3 / r4 == rational(5, 6)); + ENSURE(r3 * r4 == rational(3, 10)); + ENSURE(r3 / r4 == rational(5, 6)); rational r5(2,3); - SASSERT(r4 * r5 == rational(2, 5)); + ENSURE(r4 * r5 == rational(2, 5)); --r2; - SASSERT(r2 == -r3); + ENSURE(r2 == -r3); r2.neg(); - SASSERT(r2 == r3); + ENSURE(r2 == r3); --r2; r2 = abs(r2); - SASSERT(r2 == r3); + ENSURE(r2 == r3); --r2; ++r2; - SASSERT(r2 == r3); - SASSERT(r2 == abs(r2)); - SASSERT(r4 * rational(1) == r4); - SASSERT((r4 * rational(0)).is_zero()); - SASSERT(r4 * rational(-1) == -r4); - SASSERT(rational(1) * r4 == r4); - SASSERT((rational(0) * r4).is_zero()); - SASSERT(rational(-1) * r4 == -r4); - SASSERT(r4 + rational(0) == r4); - SASSERT(ceil(r4).is_one()); + ENSURE(r2 == r3); + ENSURE(r2 == abs(r2)); + ENSURE(r4 * rational(1) == r4); + ENSURE((r4 * rational(0)).is_zero()); + ENSURE(r4 * rational(-1) == -r4); + ENSURE(rational(1) * r4 == r4); + ENSURE((rational(0) * r4).is_zero()); + ENSURE(rational(-1) * r4 == -r4); + ENSURE(r4 + rational(0) == r4); + ENSURE(ceil(r4).is_one()); // std::cout << "r3: " << r3 << ", r4: " << r4 << ", -r4: " << -r4 << ", r3 / (-r4): " << (r3 / (-r4)) << "\n"; - SASSERT(r3 / (-r4) == rational(5,-6)); - SASSERT(div(rational(7), rational(2)) == rational(3)); - SASSERT(rational(7) % rational(4) == rational(3)); - SASSERT(div(rational(7), rational(-2)) == rational(-3)); - SASSERT(rational(3) + rational(5) == rational(8)); - SASSERT(rational("13/10") + rational("7/10") == rational(2)); - SASSERT(rational("100/20") == rational(5)); - SASSERT(gcd(rational(12), rational(8)) == rational(4)); - SASSERT(ceil(rational(-3,2)) == rational(-1)); - SASSERT(floor(rational(-3,2)) == rational(-2)); - SASSERT(ceil(rational(3,2)) == rational(2)); - SASSERT(floor(rational(3,2)) == rational(1)); - SASSERT(rational(3).is_pos()); - SASSERT(rational(0).is_nonneg()); - SASSERT(rational(3).is_pos()); - SASSERT(rational(3).is_nonneg()); - SASSERT(rational(0).is_nonneg()); - SASSERT(!rational(3).is_zero()); - SASSERT(!rational(-3).is_zero()); - SASSERT(rational(0).is_zero()); - SASSERT(rational(1).is_one()); - SASSERT(!rational(2).is_one()); - SASSERT(rational(3,4) >= rational(2,8)); - SASSERT(rational(3,4) <= rational(7,8)); - SASSERT(rational(3,4) <= rational(3,4)); - SASSERT(rational(3,4) >= rational(3,4)); - SASSERT(rational(3,4) > rational(2,8)); - SASSERT(rational(3,4) < rational(7,8)); + ENSURE(r3 / (-r4) == rational(5,-6)); + ENSURE(div(rational(7), rational(2)) == rational(3)); + ENSURE(rational(7) % rational(4) == rational(3)); + ENSURE(div(rational(7), rational(-2)) == rational(-3)); + ENSURE(rational(3) + rational(5) == rational(8)); + ENSURE(rational("13/10") + rational("7/10") == rational(2)); + ENSURE(rational("100/20") == rational(5)); + ENSURE(gcd(rational(12), rational(8)) == rational(4)); + ENSURE(ceil(rational(-3,2)) == rational(-1)); + ENSURE(floor(rational(-3,2)) == rational(-2)); + ENSURE(ceil(rational(3,2)) == rational(2)); + ENSURE(floor(rational(3,2)) == rational(1)); + ENSURE(rational(3).is_pos()); + ENSURE(rational(0).is_nonneg()); + ENSURE(rational(3).is_pos()); + ENSURE(rational(3).is_nonneg()); + ENSURE(rational(0).is_nonneg()); + ENSURE(!rational(3).is_zero()); + ENSURE(!rational(-3).is_zero()); + ENSURE(rational(0).is_zero()); + ENSURE(rational(1).is_one()); + ENSURE(!rational(2).is_one()); + ENSURE(rational(3,4) >= rational(2,8)); + ENSURE(rational(3,4) <= rational(7,8)); + ENSURE(rational(3,4) <= rational(3,4)); + ENSURE(rational(3,4) >= rational(3,4)); + ENSURE(rational(3,4) > rational(2,8)); + ENSURE(rational(3,4) < rational(7,8)); TRACE("rational", tout << rational(3,4) << "\n";); TRACE("rational", tout << rational(7,9) << "\n";); TRACE("rational", tout << rational(-3,7) << "\n";); TRACE("rational", tout << rational(5,8) << "\n";); TRACE("rational", tout << rational(4,2) << "\n";); - SASSERT(rational(3) + rational(2) == rational(5)); - SASSERT(rational(3) - rational(2) == rational(1)); - SASSERT(rational(3) * rational(2) == rational(6)); - SASSERT(rational(6) / rational(2) == rational(3)); - SASSERT(rational(6) % rational(4) == rational(2)); - SASSERT(power(rational(2),0) == rational(1)); - SASSERT(power(rational(2),1) == rational(2)); - SASSERT(power(rational(2),3) == rational(8)); + ENSURE(rational(3) + rational(2) == rational(5)); + ENSURE(rational(3) - rational(2) == rational(1)); + ENSURE(rational(3) * rational(2) == rational(6)); + ENSURE(rational(6) / rational(2) == rational(3)); + ENSURE(rational(6) % rational(4) == rational(2)); + ENSURE(power(rational(2),0) == rational(1)); + ENSURE(power(rational(2),1) == rational(2)); + ENSURE(power(rational(2),3) == rational(8)); } static void tst2() { @@ -116,90 +116,90 @@ static void tst2() { TRACE("rational", tout << r2 << std::endl;); TRACE("rational", tout << r3 << std::endl;); - SASSERT(r2 == r3); - SASSERT(r1 != r2); - SASSERT(rational(2)*r2 + r3 == r1); - SASSERT(r1.is_pos()); - SASSERT((r2 - r1).is_neg()); - SASSERT((r2 - r3).is_zero()); + ENSURE(r2 == r3); + ENSURE(r1 != r2); + ENSURE(rational(2)*r2 + r3 == r1); + ENSURE(r1.is_pos()); + ENSURE((r2 - r1).is_neg()); + ENSURE((r2 - r3).is_zero()); // std::cout << "===> " << floor(r2) << "\n"; { rational r0("1/3000000000000000000000000"); - SASSERT(ceil(r0).is_one()); - SASSERT(floor(-r0).is_minus_one()); - SASSERT(ceil(-r0).is_zero()); + ENSURE(ceil(r0).is_one()); + ENSURE(floor(-r0).is_minus_one()); + ENSURE(ceil(-r0).is_zero()); } - SASSERT(floor(r1) == r1); - SASSERT(ceil(r1) == r1); + ENSURE(floor(r1) == r1); + ENSURE(ceil(r1) == r1); rational r4("300000000/5"); - SASSERT(rational(1,2) * r4 == rational("300000000/10")); - SASSERT(rational(1,2) / r4 == rational("5/600000000")); + ENSURE(rational(1,2) * r4 == rational("300000000/10")); + ENSURE(rational(1,2) / r4 == rational("5/600000000")); rational r5(2,3); - SASSERT(r4 * r5 == rational("200000000/5")); + ENSURE(r4 * r5 == rational("200000000/5")); rational r6("10000000000000000000000000000000003/3"); --r6; - SASSERT(r6 == r2); + ENSURE(r6 == r2); r6.neg(); - SASSERT(r6 != r2); - SASSERT(abs(r6) == r2); + ENSURE(r6 != r2); + ENSURE(abs(r6) == r2); --r2; ++r2; r2.neg(); - SASSERT(r2 == r6); - SASSERT(r6 * rational(1) == r6); - SASSERT((r6 * rational(0)).is_zero()); - SASSERT(r6 * rational(-1) == -r6); - SASSERT(rational(1) * r6 == r6); - SASSERT((rational(0) * r6).is_zero()); - SASSERT(rational(-1) * r6 == -r6); - SASSERT(r6 + rational(0) == r6); + ENSURE(r2 == r6); + ENSURE(r6 * rational(1) == r6); + ENSURE((r6 * rational(0)).is_zero()); + ENSURE(r6 * rational(-1) == -r6); + ENSURE(rational(1) * r6 == r6); + ENSURE((rational(0) * r6).is_zero()); + ENSURE(rational(-1) * r6 == -r6); + ENSURE(r6 + rational(0) == r6); - SASSERT(rational("300000000000000").is_pos()); - SASSERT(rational("0000000000000000000").is_nonneg()); - SASSERT(rational("0000000000000000000").is_nonpos()); - SASSERT(rational("3000000000000000000/2").is_pos()); - SASSERT(rational("3000000000000000000/2").is_nonneg()); - SASSERT((-rational("3000000000000000000/2")).is_neg()); - SASSERT(!rational("3000000000000000000/2").is_neg()); - SASSERT(!rational("3000000000000000000/2").is_zero()); - SASSERT(!rational("3000000000000000000/2").is_one()); - SASSERT(rational("99999999999/2") >= rational("23/2")); - SASSERT(rational("99999999999/2") > rational("23/2")); - SASSERT(rational("23/2") <= rational("99999999999/2")); - SASSERT(rational("23/2") < rational("99999999999/2")); - SASSERT(!(rational("99999999999/2") < rational("23/2"))); + ENSURE(rational("300000000000000").is_pos()); + ENSURE(rational("0000000000000000000").is_nonneg()); + ENSURE(rational("0000000000000000000").is_nonpos()); + ENSURE(rational("3000000000000000000/2").is_pos()); + ENSURE(rational("3000000000000000000/2").is_nonneg()); + ENSURE((-rational("3000000000000000000/2")).is_neg()); + ENSURE(!rational("3000000000000000000/2").is_neg()); + ENSURE(!rational("3000000000000000000/2").is_zero()); + ENSURE(!rational("3000000000000000000/2").is_one()); + ENSURE(rational("99999999999/2") >= rational("23/2")); + ENSURE(rational("99999999999/2") > rational("23/2")); + ENSURE(rational("23/2") <= rational("99999999999/2")); + ENSURE(rational("23/2") < rational("99999999999/2")); + ENSURE(!(rational("99999999999/2") < rational("23/2"))); rational int64_max("9223372036854775807"); rational int64_min((-int64_max) - rational(1)); // is_int64 - SASSERT(int64_max.is_int64()); - SASSERT(int64_min.is_int64()); - SASSERT(rational(0).is_int64()); - SASSERT(rational(1).is_int64()); - SASSERT(rational(-1).is_int64()); - SASSERT(!(int64_max + rational(1)).is_int64()); - SASSERT(!(int64_min - rational(1)).is_int64()); + ENSURE(int64_max.is_int64()); + ENSURE(int64_min.is_int64()); + ENSURE(rational(0).is_int64()); + ENSURE(rational(1).is_int64()); + ENSURE(rational(-1).is_int64()); + ENSURE(!(int64_max + rational(1)).is_int64()); + ENSURE(!(int64_min - rational(1)).is_int64()); // is_uint64 - SASSERT(int64_max.is_uint64()); - SASSERT(!int64_min.is_uint64()); - SASSERT(rational(0).is_uint64()); - SASSERT(rational(1).is_uint64()); - SASSERT(!rational(-1).is_uint64()); - SASSERT((int64_max + rational(1)).is_uint64()); - SASSERT(!(int64_min - rational(1)).is_uint64()); + ENSURE(int64_max.is_uint64()); + ENSURE(!int64_min.is_uint64()); + ENSURE(rational(0).is_uint64()); + ENSURE(rational(1).is_uint64()); + ENSURE(!rational(-1).is_uint64()); + ENSURE((int64_max + rational(1)).is_uint64()); + ENSURE(!(int64_min - rational(1)).is_uint64()); rational uint64_max(rational(1) + (rational(2) * int64_max)); - SASSERT(uint64_max.is_uint64()); + ENSURE(uint64_max.is_uint64()); // get_int64, get_uint64 uint64 u1 = uint64_max.get_uint64(); uint64 u2 = UINT64_MAX; VERIFY(u1 == u2); std::cout << "int64_max: " << int64_max << ", INT64_MAX: " << INT64_MAX << ", int64_max.get_int64(): " << int64_max.get_int64() << ", int64_max.get_uint64(): " << int64_max.get_uint64() << "\n"; - SASSERT(int64_max.get_int64() == INT64_MAX); - SASSERT(int64_min.get_int64() == INT64_MIN); + ENSURE(int64_max.get_int64() == INT64_MAX); + ENSURE(int64_min.get_int64() == INT64_MIN); // extended Euclid: @@ -219,7 +219,7 @@ void tst3() { TRACE("rational", tout << "n4: " << n4 << "\n"; tout << "n5: " << n5 << "\n";); - SASSERT(n5 == rational("2147483646")); + ENSURE(n5 == rational("2147483646")); } void tst4() { @@ -236,7 +236,7 @@ void tst5() { TRACE("rational", tout << n1 << " " << n2 << " " << n1.is_big() << " " << n2.is_big() << "\n";); n1 *= n2; TRACE("rational", tout << "after: " << n1 << " " << n2 << "\n";); - SASSERT(n1.is_minus_one()); + ENSURE(n1.is_minus_one()); } void tst6() { @@ -274,8 +274,8 @@ public: static void tst1() { rational n1(-1); rational n2(8); - SASSERT((n1 % n2).is_minus_one()); - SASSERT(mod(n1, n2) == rational(7)); + ENSURE((n1 % n2).is_minus_one()); + ENSURE(mod(n1, n2) == rational(7)); } static void tst_hash(int val) { @@ -283,7 +283,7 @@ public: rational n2("10203939394995449949494394932929"); rational n3(val); n2 = n3; - SASSERT(n1.hash() == n2.hash()); + ENSURE(n1.hash() == n2.hash()); } static void tst2() { @@ -306,47 +306,47 @@ static void tst7() { rational gcd; extended_gcd(n, p, gcd, x, y); TRACE("gcd", tout << n << " " << p << ": " << gcd << " " << x << " " << y << "\n";); - SASSERT(!mod(n, rational(2)).is_one() || mod(n * x, p).is_one()); + ENSURE(!mod(n, rational(2)).is_one() || mod(n * x, p).is_one()); } } static void tst8() { rational r; - SASSERT(!rational(-4).is_int_perfect_square(r) && r.is_zero()); - SASSERT(!rational(-3).is_int_perfect_square(r) && r.is_zero()); - SASSERT(!rational(-2).is_int_perfect_square(r) && r.is_zero()); - SASSERT(!rational(-1).is_int_perfect_square(r) && r.is_zero()); - SASSERT(rational(0).is_int_perfect_square(r) && r.is_zero()); - SASSERT(rational(1).is_int_perfect_square(r) && r.is_one()); - SASSERT(!rational(2).is_int_perfect_square(r) && r == rational(2)); - SASSERT(!rational(3).is_int_perfect_square(r) && r == rational(2)); - SASSERT(rational(4).is_int_perfect_square(r) && r == rational(2)); - SASSERT(!rational(5).is_int_perfect_square(r) && r == rational(3)); - SASSERT(!rational(6).is_int_perfect_square(r) && r == rational(3)); - SASSERT(!rational(7).is_int_perfect_square(r) && r == rational(3)); - SASSERT(!rational(8).is_int_perfect_square(r) && r == rational(3)); - SASSERT(rational(9).is_int_perfect_square(r) && r == rational(3)); - SASSERT(!rational(10).is_int_perfect_square(r) && r == rational(4)); - SASSERT(!rational(11).is_int_perfect_square(r) && r == rational(4)); - SASSERT(!rational(12).is_int_perfect_square(r) && r == rational(4)); - SASSERT(!rational(13).is_int_perfect_square(r) && r == rational(4)); - SASSERT(!rational(14).is_int_perfect_square(r) && r == rational(4)); - SASSERT(!rational(15).is_int_perfect_square(r) && r == rational(4)); - SASSERT(rational(16).is_int_perfect_square(r) && r == rational(4)); - SASSERT(!rational(17).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(18).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(19).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(20).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(21).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(22).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(23).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(24).is_int_perfect_square(r) && r == rational(5)); - SASSERT(rational(25).is_int_perfect_square(r) && r == rational(5)); - SASSERT(!rational(26).is_int_perfect_square(r) && r == rational(6)); - SASSERT(rational(36).is_int_perfect_square(r) && r == rational(6)); + ENSURE(!rational(-4).is_int_perfect_square(r) && r.is_zero()); + ENSURE(!rational(-3).is_int_perfect_square(r) && r.is_zero()); + ENSURE(!rational(-2).is_int_perfect_square(r) && r.is_zero()); + ENSURE(!rational(-1).is_int_perfect_square(r) && r.is_zero()); + ENSURE(rational(0).is_int_perfect_square(r) && r.is_zero()); + ENSURE(rational(1).is_int_perfect_square(r) && r.is_one()); + ENSURE(!rational(2).is_int_perfect_square(r) && r == rational(2)); + ENSURE(!rational(3).is_int_perfect_square(r) && r == rational(2)); + ENSURE(rational(4).is_int_perfect_square(r) && r == rational(2)); + ENSURE(!rational(5).is_int_perfect_square(r) && r == rational(3)); + ENSURE(!rational(6).is_int_perfect_square(r) && r == rational(3)); + ENSURE(!rational(7).is_int_perfect_square(r) && r == rational(3)); + ENSURE(!rational(8).is_int_perfect_square(r) && r == rational(3)); + ENSURE(rational(9).is_int_perfect_square(r) && r == rational(3)); + ENSURE(!rational(10).is_int_perfect_square(r) && r == rational(4)); + ENSURE(!rational(11).is_int_perfect_square(r) && r == rational(4)); + ENSURE(!rational(12).is_int_perfect_square(r) && r == rational(4)); + ENSURE(!rational(13).is_int_perfect_square(r) && r == rational(4)); + ENSURE(!rational(14).is_int_perfect_square(r) && r == rational(4)); + ENSURE(!rational(15).is_int_perfect_square(r) && r == rational(4)); + ENSURE(rational(16).is_int_perfect_square(r) && r == rational(4)); + ENSURE(!rational(17).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(18).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(19).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(20).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(21).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(22).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(23).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(24).is_int_perfect_square(r) && r == rational(5)); + ENSURE(rational(25).is_int_perfect_square(r) && r == rational(5)); + ENSURE(!rational(26).is_int_perfect_square(r) && r == rational(6)); + ENSURE(rational(36).is_int_perfect_square(r) && r == rational(6)); - SASSERT(rational(1,9).is_perfect_square(r) && r == rational(1,3)); - SASSERT(rational(4,9).is_perfect_square(r) && r == rational(2,3)); + ENSURE(rational(1,9).is_perfect_square(r) && r == rational(1,3)); + ENSURE(rational(4,9).is_perfect_square(r) && r == rational(2,3)); } @@ -363,9 +363,9 @@ static void tstmod(rational const& m, rational const& n) { std::cout << m << " " << n << " " << q << " " << r << "\n"; std::cout << m << " == " << n*q+r << "\n"; - SASSERT(m == (n * q) + r); - SASSERT(rational::zero() <= r); - SASSERT(r < abs(n)); + ENSURE(m == (n * q) + r); + ENSURE(rational::zero() <= r); + ENSURE(r < abs(n)); } diff --git a/src/test/rcf.cpp b/src/test/rcf.cpp index 170c053f1..082147190 100644 --- a/src/test/rcf.cpp +++ b/src/test/rcf.cpp @@ -116,13 +116,13 @@ static void tst_solve(unsigned n, int _A[], int _b[], int _c[], bool solved) { svector b; b.resize(n, 0); if (mm.solve(A, b.c_ptr(), _c)) { - SASSERT(solved); + ENSURE(solved); for (unsigned i = 0; i < n; i++) { - SASSERT(b[i] == _b[i]); + ENSURE(b[i] == _b[i]); } } else { - SASSERT(!solved); + ENSURE(!solved); } } @@ -140,7 +140,7 @@ static void tst_lin_indep(unsigned m, unsigned n, int _A[], unsigned ex_sz, unsi scoped_mpz_matrix B(mm); mm.linear_independent_rows(A, r.c_ptr(), B); for (unsigned i = 0; i < ex_sz; i++) { - SASSERT(r[i] == ex_r[i]); + ENSURE(r[i] == ex_r[i]); } } diff --git a/src/test/sat_user_scope.cpp b/src/test/sat_user_scope.cpp index a271ce6bb..7e3d50e8d 100644 --- a/src/test/sat_user_scope.cpp +++ b/src/test/sat_user_scope.cpp @@ -73,7 +73,7 @@ static void check_coherence(sat::solver& s1, trail_t& t) { s2.display(std::cout); } std::cout << is_sat1 << "\n"; - SASSERT(is_sat1 == is_sat2); + ENSURE(is_sat1 == is_sat2); } void tst_sat_user_scope() { diff --git a/src/test/simplex.cpp b/src/test/simplex.cpp index 6f08bd04d..8e57f6110 100644 --- a/src/test/simplex.cpp +++ b/src/test/simplex.cpp @@ -84,7 +84,7 @@ void add_row(Simplex& S, vector const& _v, R const& _b, bool is_eq = false) { coeffs.push_back(b.to_mpq().numerator()); mpq_inf one(mpq(1),mpq(0)); mpq_inf zero(mpq(0),mpq(0)); - SASSERT(vars.size() == coeffs.size()); + ENSURE(vars.size() == coeffs.size()); S.set_lower(nv, zero); if (is_eq) S.set_upper(nv, zero); S.set_lower(nv+1, one); diff --git a/src/test/simplifier.cpp b/src/test/simplifier.cpp index 2e8f434e1..5a05ab30f 100644 --- a/src/test/simplifier.cpp +++ b/src/test/simplifier.cpp @@ -18,7 +18,7 @@ static void ev_const(Z3_context ctx, Z3_ast e) { tout << Z3_ast_to_string(ctx, e) << " -> "; tout << Z3_ast_to_string(ctx, r) << "\n";); Z3_ast_kind k = Z3_get_ast_kind(ctx, r); - SASSERT(k == Z3_NUMERAL_AST || + ENSURE(k == Z3_NUMERAL_AST || (k == Z3_APP_AST && (Z3_OP_TRUE == Z3_get_decl_kind(ctx,Z3_get_app_decl(ctx, Z3_to_app(ctx, r))) || Z3_OP_FALSE == Z3_get_decl_kind(ctx,Z3_get_app_decl(ctx, Z3_to_app(ctx, r)))))); @@ -34,7 +34,7 @@ static void test_bv() { Z3_ast bit3_2 = Z3_mk_numeral(ctx, "3", bv2); Z3_ast e = Z3_mk_eq(ctx, bit3_2, Z3_mk_sign_ext(ctx, 1, bit1_1)); - SASSERT(Z3_simplify(ctx, e) == Z3_mk_true(ctx)); + ENSURE(Z3_simplify(ctx, e) == Z3_mk_true(ctx)); TRACE("simplifier", tout << Z3_ast_to_string(ctx, e) << "\n";); Z3_ast b12 = Z3_mk_numeral(ctx, "12", bv72); @@ -97,18 +97,18 @@ static void test_datatypes() { nil = Z3_mk_app(ctx, nil_decl, 0, 0); Z3_ast a = Z3_simplify(ctx, Z3_mk_app(ctx, is_nil_decl, 1, &nil)); - SASSERT(a == Z3_mk_true(ctx)); + ENSURE(a == Z3_mk_true(ctx)); a = Z3_simplify(ctx, Z3_mk_app(ctx, is_cons_decl, 1, &nil)); - SASSERT(a == Z3_mk_false(ctx)); + ENSURE(a == Z3_mk_false(ctx)); Z3_ast one = Z3_mk_numeral(ctx, "1", int_ty); Z3_ast args[2] = { one, nil }; l1 = Z3_mk_app(ctx, cons_decl, 2, args); - SASSERT(nil == Z3_simplify(ctx, Z3_mk_app(ctx, tail_decl, 1, &l1))); - SASSERT(one == Z3_simplify(ctx, Z3_mk_app(ctx, head_decl, 1, &l1))); + ENSURE(nil == Z3_simplify(ctx, Z3_mk_app(ctx, tail_decl, 1, &l1))); + ENSURE(one == Z3_simplify(ctx, Z3_mk_app(ctx, head_decl, 1, &l1))); - SASSERT(Z3_mk_false(ctx) == Z3_simplify(ctx, Z3_mk_eq(ctx, nil, l1))); + ENSURE(Z3_mk_false(ctx) == Z3_simplify(ctx, Z3_mk_eq(ctx, nil, l1))); Z3_del_config(cfg); Z3_del_context(ctx); @@ -147,8 +147,8 @@ static void test_bool() { Z3_ast a = Z3_simplify(ctx, Z3_mk_not(ctx, Z3_mk_eq(ctx, Z3_mk_false(ctx), Z3_mk_true(ctx)))); Z3_ast b = Z3_simplify(ctx, Z3_mk_not(ctx, Z3_mk_iff(ctx, Z3_mk_false(ctx), Z3_mk_true(ctx)))); - SASSERT(Z3_mk_true(ctx) == a); - SASSERT(Z3_mk_true(ctx) == b); + ENSURE(Z3_mk_true(ctx) == a); + ENSURE(Z3_mk_true(ctx) == b); TRACE("simplifier", tout << Z3_ast_to_string(ctx, a) << "\n";); TRACE("simplifier", tout << Z3_ast_to_string(ctx, b) << "\n";); @@ -179,8 +179,8 @@ static void test_array() { TRACE("simplifier", tout << Z3_ast_to_string(ctx, rxy) << "\n";); TRACE("simplifier", tout << Z3_ast_to_string(ctx, Z3_simplify(ctx, Z3_mk_eq(ctx, x2, x3))) << "\n";); - // SASSERT(rxy == Z3_mk_true(ctx)); - // SASSERT(Z3_simplify(ctx, Z3_mk_eq(ctx, x2, x3)) == Z3_mk_false(ctx)); + // ENSURE(rxy == Z3_mk_true(ctx)); + // ENSURE(Z3_simplify(ctx, Z3_mk_eq(ctx, x2, x3)) == Z3_mk_false(ctx)); for (unsigned i = 0; i < 4; ++i) { for (unsigned j = 0; j < 4; ++j) { diff --git a/src/test/sorting_network.cpp b/src/test/sorting_network.cpp index 87cc05375..9836bc04d 100644 --- a/src/test/sorting_network.cpp +++ b/src/test/sorting_network.cpp @@ -57,7 +57,7 @@ struct unsigned_ext { static void is_sorted(svector const& v) { for (unsigned i = 0; i + 1 < v.size(); ++i) { - SASSERT(v[i] <= v[i+1]); + ENSURE(v[i] <= v[i+1]); } } @@ -184,7 +184,7 @@ struct ast_ext2 { static void test_sorting_eq(unsigned n, unsigned k) { - SASSERT(k < n); + ENSURE(k < n); ast_manager m; reg_decl_plugins(m); ast_ext2 ext(m); @@ -206,14 +206,14 @@ static void test_sorting_eq(unsigned n, unsigned k) { solver.assert_expr(ext.m_clauses[i].get()); } lbool res = solver.check(); - SASSERT(res == l_true); + ENSURE(res == l_true); solver.push(); for (unsigned i = 0; i < k; ++i) { solver.assert_expr(in[i].get()); } res = solver.check(); - SASSERT(res == l_true); + ENSURE(res == l_true); solver.assert_expr(in[k].get()); res = solver.check(); if (res == l_true) { @@ -227,7 +227,7 @@ static void test_sorting_eq(unsigned n, unsigned k) { model_smt2_pp(std::cout, m, *model, 0); TRACE("pb", model_smt2_pp(tout, m, *model, 0);); } - SASSERT(res == l_false); + ENSURE(res == l_false); solver.pop(1); ext.m_clauses.reset(); } @@ -253,13 +253,13 @@ static void test_sorting_le(unsigned n, unsigned k) { solver.assert_expr(ext.m_clauses[i].get()); } lbool res = solver.check(); - SASSERT(res == l_true); + ENSURE(res == l_true); for (unsigned i = 0; i < k; ++i) { solver.assert_expr(in[i].get()); } res = solver.check(); - SASSERT(res == l_true); + ENSURE(res == l_true); solver.assert_expr(in[k].get()); res = solver.check(); if (res == l_true) { @@ -273,7 +273,7 @@ static void test_sorting_le(unsigned n, unsigned k) { model_smt2_pp(std::cout, m, *model, 0); TRACE("pb", model_smt2_pp(tout, m, *model, 0);); } - SASSERT(res == l_false); + ENSURE(res == l_false); solver.pop(1); ext.m_clauses.reset(); } @@ -300,14 +300,14 @@ void test_sorting_ge(unsigned n, unsigned k) { solver.assert_expr(ext.m_clauses[i].get()); } lbool res = solver.check(); - SASSERT(res == l_true); + ENSURE(res == l_true); solver.push(); for (unsigned i = 0; i < n - k; ++i) { solver.assert_expr(m.mk_not(in[i].get())); } res = solver.check(); - SASSERT(res == l_true); + ENSURE(res == l_true); solver.assert_expr(m.mk_not(in[n - k].get())); res = solver.check(); if (res == l_true) { @@ -321,7 +321,7 @@ void test_sorting_ge(unsigned n, unsigned k) { model_smt2_pp(std::cout, m, *model, 0); TRACE("pb", model_smt2_pp(tout, m, *model, 0);); } - SASSERT(res == l_false); + ENSURE(res == l_false); solver.pop(1); } diff --git a/src/test/stack.cpp b/src/test/stack.cpp index 6a4dd3cd8..c8f3d88a6 100644 --- a/src/test/stack.cpp +++ b/src/test/stack.cpp @@ -27,8 +27,8 @@ static void tst1() { point * p1 = new (s) point(10, 20); point * p2 = new (s) point(30, 40); void * ptr = s.allocate(16000); - SASSERT(p2->first == 30 && p2->second == 40); - SASSERT(p1->first == 10 && p1->second == 20); + ENSURE(p2->first == 30 && p2->second == 40); + ENSURE(p1->first == 10 && p1->second == 20); s.deallocate(static_cast(ptr)); s.deallocate(p2); s.deallocate(p1); @@ -38,8 +38,8 @@ static void tst2(unsigned num, unsigned del_rate) { ptr_vector ptrs; stack s; for (unsigned i = 0; i < num; i++) { - SASSERT(ptrs.empty() == s.empty()); - SASSERT(s.empty() || ptrs.back() == s.top()); + ENSURE(ptrs.empty() == s.empty()); + ENSURE(s.empty() || ptrs.back() == s.top()); if (!ptrs.empty() && rand() % del_rate == 0) { s.deallocate(); ptrs.pop_back(); @@ -57,8 +57,8 @@ static void tst2(unsigned num, unsigned del_rate) { } } while (s.empty()) { - SASSERT(ptrs.empty() == s.empty()); - SASSERT(s.empty() || ptrs.back() == s.top()); + ENSURE(ptrs.empty() == s.empty()); + ENSURE(s.empty() || ptrs.back() == s.top()); s.deallocate(); ptrs.pop_back(); } diff --git a/src/test/string_buffer.cpp b/src/test/string_buffer.cpp index 67d60528c..7d7854a9c 100644 --- a/src/test/string_buffer.cpp +++ b/src/test/string_buffer.cpp @@ -24,7 +24,7 @@ Revision History: static void tst1() { string_buffer<> b; b << "Testing" << 10 << true; - SASSERT(strcmp(b.c_str(), "Testing10true") == 0); + ENSURE(strcmp(b.c_str(), "Testing10true") == 0); } static void tst2() { @@ -34,7 +34,7 @@ static void tst2() { b << r; } TRACE("string_buffer", tout << b.c_str() << "\n";); - SASSERT(strlen(b.c_str()) == 10000); + ENSURE(strlen(b.c_str()) == 10000); } static void tst3() { @@ -42,7 +42,7 @@ static void tst3() { string_buffer<128> b2; b2 << "World"; b << "Hello" << " " << b2; - SASSERT(strcmp(b.c_str(), "Hello World") == 0); + ENSURE(strcmp(b.c_str(), "Hello World") == 0); } void tst_string_buffer() { diff --git a/src/test/symbol.cpp b/src/test/symbol.cpp index c87955116..e91332285 100644 --- a/src/test/symbol.cpp +++ b/src/test/symbol.cpp @@ -24,31 +24,31 @@ static void tst1() { symbol s1("foo"); symbol s2("boo"); symbol s3("foo"); - SASSERT(s1 != s2); - SASSERT(s1 == s3); + ENSURE(s1 != s2); + ENSURE(s1 == s3); std::cout << s1 << " " << s2 << " " << s3 << "\n"; - SASSERT(s1 == "foo"); - SASSERT(s1 != "boo"); - SASSERT(s2 != "foo"); - SASSERT(s3 == "foo"); - SASSERT(s2 == "boo"); + ENSURE(s1 == "foo"); + ENSURE(s1 != "boo"); + ENSURE(s2 != "foo"); + ENSURE(s3 == "foo"); + ENSURE(s2 == "boo"); - SASSERT(lt(s2, s1)); - SASSERT(!lt(s1, s2)); - SASSERT(!lt(s1, s3)); - SASSERT(lt(symbol("abcc"), symbol("abcd"))); - SASSERT(!lt(symbol("abcd"), symbol("abcc"))); - SASSERT(lt(symbol("abc"), symbol("abcc"))); - SASSERT(!lt(symbol("abcd"), symbol("abc"))); - SASSERT(lt(symbol(10), s1)); - SASSERT(!lt(s1, symbol(10))); - SASSERT(lt(symbol(10), symbol(20))); - SASSERT(!lt(symbol(20), symbol(10))); - SASSERT(!lt(symbol(10), symbol(10))); - SASSERT(lt(symbol("a"), symbol("b"))); - SASSERT(!lt(symbol("z"), symbol("b"))); - SASSERT(!lt(symbol("zzz"), symbol("b"))); - SASSERT(lt(symbol("zzz"), symbol("zzzb"))); + ENSURE(lt(s2, s1)); + ENSURE(!lt(s1, s2)); + ENSURE(!lt(s1, s3)); + ENSURE(lt(symbol("abcc"), symbol("abcd"))); + ENSURE(!lt(symbol("abcd"), symbol("abcc"))); + ENSURE(lt(symbol("abc"), symbol("abcc"))); + ENSURE(!lt(symbol("abcd"), symbol("abc"))); + ENSURE(lt(symbol(10), s1)); + ENSURE(!lt(s1, symbol(10))); + ENSURE(lt(symbol(10), symbol(20))); + ENSURE(!lt(symbol(20), symbol(10))); + ENSURE(!lt(symbol(10), symbol(10))); + ENSURE(lt(symbol("a"), symbol("b"))); + ENSURE(!lt(symbol("z"), symbol("b"))); + ENSURE(!lt(symbol("zzz"), symbol("b"))); + ENSURE(lt(symbol("zzz"), symbol("zzzb"))); } void tst_symbol() { diff --git a/src/test/symbol_table.cpp b/src/test/symbol_table.cpp index f67ef6f66..8c3c55c9d 100644 --- a/src/test/symbol_table.cpp +++ b/src/test/symbol_table.cpp @@ -21,24 +21,24 @@ Revision History: static void tst1() { symbol_table t; t.insert(symbol("foo"), 35); - SASSERT(t.contains(symbol("foo"))); - SASSERT(!t.contains(symbol("boo"))); + ENSURE(t.contains(symbol("foo"))); + ENSURE(!t.contains(symbol("boo"))); t.begin_scope(); t.insert(symbol("boo"), 20); - SASSERT(t.contains(symbol("boo"))); + ENSURE(t.contains(symbol("boo"))); #ifdef Z3DEBUG int tmp; #endif - SASSERT(t.find(symbol("boo"), tmp) && tmp == 20); - SASSERT(t.find(symbol("foo"), tmp) && tmp == 35); + ENSURE(t.find(symbol("boo"), tmp) && tmp == 20); + ENSURE(t.find(symbol("foo"), tmp) && tmp == 35); t.insert(symbol("foo"), 100); - SASSERT(t.find(symbol("foo"), tmp) && tmp == 100); + ENSURE(t.find(symbol("foo"), tmp) && tmp == 100); t.end_scope(); - SASSERT(t.find(symbol("foo"), tmp) && tmp == 35); - SASSERT(!t.contains(symbol("boo"))); + ENSURE(t.find(symbol("foo"), tmp) && tmp == 35); + ENSURE(!t.contains(symbol("boo"))); t.reset(); - SASSERT(!t.contains(symbol("boo"))); - SASSERT(!t.contains(symbol("foo"))); + ENSURE(!t.contains(symbol("boo"))); + ENSURE(!t.contains(symbol("foo"))); } void tst_symbol_table() { diff --git a/src/test/tbv.cpp b/src/test/tbv.cpp index 7637c7e83..00f7e0960 100644 --- a/src/test/tbv.cpp +++ b/src/test/tbv.cpp @@ -17,18 +17,18 @@ static void tst1(unsigned num_bits) { m.display(std::cout, *b1) << "\n"; m.display(std::cout, *bX) << "\n"; m.display(std::cout, *bN) << "\n"; - SASSERT(!m.equals(*b1,*b0)); - SASSERT(!m.equals(*b1,*bX)); - SASSERT(!m.equals(*b0,*bX)); + ENSURE(!m.equals(*b1,*b0)); + ENSURE(!m.equals(*b1,*bX)); + ENSURE(!m.equals(*b0,*bX)); m.set_and(*bX,*b0); - SASSERT(m.equals(*b0,*bX)); - SASSERT(!m.equals(*b1,*bX)); + ENSURE(m.equals(*b0,*bX)); + ENSURE(!m.equals(*b1,*bX)); m.copy(*bX,*b1); - SASSERT(m.equals(*b1,*bX)); - SASSERT(!m.equals(*b0,*bX)); + ENSURE(m.equals(*b1,*bX)); + ENSURE(!m.equals(*b0,*bX)); m.fillX(*bX); VERIFY(m.intersect(*bX,*b0,*bN)); - SASSERT(m.equals(*b0, *bN)); + ENSURE(m.equals(*b0, *bN)); VERIFY(!m.intersect(*b0,*b1,*bN)); m.fill1(*b1); bit_vector to_delete; @@ -58,8 +58,8 @@ static void tst0() { m.display(std::cout, *t1) << "\n"; m.display(std::cout, *t2) << "\n"; m.display(std::cout, *t3) << "\n"; - SASSERT(m.equals(*t1, *t2)); - SASSERT(m.equals(*t1, *t3)); + ENSURE(m.equals(*t1, *t2)); + ENSURE(m.equals(*t1, *t3)); } static void tst2(unsigned num_bits) { @@ -67,10 +67,10 @@ static void tst2(unsigned num_bits) { tbv_ref t(m), t2(m); for (unsigned i = 0; i < 55; ++i) { t = m.allocate(i); - SASSERT(m.is_well_formed(*t)); + ENSURE(m.is_well_formed(*t)); t2 = m.allocate(i+1); VERIFY(!m.set_and(*t2, *t)); - SASSERT(!m.is_well_formed(*t2)); + ENSURE(!m.is_well_formed(*t2)); } } diff --git a/src/test/theory_pb.cpp b/src/test/theory_pb.cpp index 3a229d951..42a03f619 100644 --- a/src/test/theory_pb.cpp +++ b/src/test/theory_pb.cpp @@ -12,7 +12,7 @@ Copyright (c) 2015 Microsoft Corporation #include "th_rewriter.h" unsigned populate_literals(unsigned k, smt::literal_vector& lits) { - SASSERT(k < (1u << lits.size())); + ENSURE(k < (1u << lits.size())); unsigned t = 0; for (unsigned i = 0; i < lits.size(); ++i) { if (k & (1 << i)) { @@ -159,7 +159,7 @@ void tst_theory_pb() { smt::context ctx(m, params); ctx.push(); smt::literal l = smt::theory_pb::assert_ge(ctx, k, lits.size(), lits.c_ptr()); - SASSERT(l != smt::false_literal); + ENSURE(l != smt::false_literal); ctx.assign(l, 0, false); TRACE("pb", ctx.display(tout);); VERIFY(l_true == ctx.check()); diff --git a/src/test/total_order.cpp b/src/test/total_order.cpp index 2fa22065f..12bb4d977 100644 --- a/src/test/total_order.cpp +++ b/src/test/total_order.cpp @@ -25,12 +25,12 @@ static void tst1() { to.insert(1); to.insert_after(1, 2); to.insert_after(1, 3); - SASSERT(to.lt(1, 2)); - SASSERT(to.lt(3, 2)); - SASSERT(to.lt(1, 3)); - SASSERT(!to.lt(2, 3)); - SASSERT(!to.lt(3, 1)); - SASSERT(!to.lt(2, 2)); + ENSURE(to.lt(1, 2)); + ENSURE(to.lt(3, 2)); + ENSURE(to.lt(1, 3)); + ENSURE(!to.lt(2, 3)); + ENSURE(!to.lt(3, 1)); + ENSURE(!to.lt(2, 2)); std::cout << to << "\n"; } @@ -43,8 +43,8 @@ static void tst2() { to.move_after(3, 1); to.move_after(1, 2); to.move_after(2, 3); - SASSERT(to.lt(1,2)); - SASSERT(to.lt(2,3)); + ENSURE(to.lt(1,2)); + ENSURE(to.lt(2,3)); } } @@ -75,7 +75,7 @@ void move_after(unsigned_vector & v, unsigned_vector & inv_v, unsigned a, unsign // std::cout << "move_after(" << a << ", " << b << ")\n"; unsigned pos_a = inv_v[a]; unsigned pos_b = inv_v[b]; - SASSERT(pos_a != pos_b); + ENSURE(pos_a != pos_b); if (pos_b < pos_a) { for (unsigned i = pos_b; i < pos_a; i++) { v[i] = v[i+1]; @@ -83,17 +83,17 @@ void move_after(unsigned_vector & v, unsigned_vector & inv_v, unsigned a, unsign } v[pos_a] = b; inv_v[b] = pos_a; - SASSERT(inv_v[b] == inv_v[a] + 1); + ENSURE(inv_v[b] == inv_v[a] + 1); } else { - SASSERT(pos_b > pos_a); + ENSURE(pos_b > pos_a); for (unsigned i = pos_b; i > pos_a + 1; i--) { v[i] = v[i-1]; inv_v[v[i-1]] = i; } v[pos_a+1] = b; inv_v[b] = pos_a+1; - SASSERT(inv_v[b] == inv_v[a] + 1); + ENSURE(inv_v[b] == inv_v[a] + 1); } // display(std::cout, v.begin(), v.end()); std::cout << std::endl; } @@ -118,8 +118,8 @@ static void tst4(unsigned sz, unsigned num_rounds) { move_after(v, inv_v, v1, v2); } for (unsigned k = 0; k < sz - 1; k++) { - SASSERT(inv_v[v[k]] == k); - SASSERT(to.lt(v[k], v[k+1])); + ENSURE(inv_v[v[k]] == k); + ENSURE(to.lt(v[k], v[k+1])); } if (i % 1000 == 0) { std::cout << "*"; diff --git a/src/test/udoc_relation.cpp b/src/test/udoc_relation.cpp index dc88e20af..57866c3ac 100644 --- a/src/test/udoc_relation.cpp +++ b/src/test/udoc_relation.cpp @@ -85,7 +85,7 @@ class udoc_tester { doc_ref result(dm); t = mk_rand_tbv(dm); result = dm.allocate(*t); - SASSERT(dm.tbvm().equals(*t, result->pos())); + ENSURE(dm.tbvm().equals(*t, result->pos())); for (unsigned i = 0; i < num_diff; ++i) { t = mk_rand_tbv(dm, result->pos()); if (dm.tbvm().equals(*t, result->pos())) { @@ -97,7 +97,7 @@ class udoc_tester { } result->neg().push_back(t.detach()); } - SASSERT(dm.well_formed(*result)); + ENSURE(dm.well_formed(*result)); return result.detach(); } @@ -121,7 +121,7 @@ public: } udoc_relation* mk_empty(relation_signature const& sig) { - SASSERT(p.can_handle_signature(sig)); + ENSURE(p.can_handle_signature(sig)); relation_base* empty = p.mk_empty(sig); return dynamic_cast(empty); } @@ -210,7 +210,7 @@ public: jc1.push_back(1); jc2.push_back(1); datalog::relation_join_fn* join_fn = p.mk_join_fn(*t1, *t2, jc1.size(), jc1.c_ptr(), jc2.c_ptr()); - SASSERT(join_fn); + ENSURE(join_fn); t = (*join_fn)(*t1, *t2); cr.verify_join(*t1, *t2, *t, jc1, jc2); t->display(std::cout); std::cout << "\n"; @@ -218,13 +218,13 @@ public: t = (*join_fn)(*t1, *t3); cr.verify_join(*t1, *t3, *t, jc1, jc2); - SASSERT(t->empty()); + ENSURE(t->empty()); t->display(std::cout); std::cout << "\n"; t->deallocate(); t = (*join_fn)(*t3, *t3); cr.verify_join(*t3, *t3, *t, jc1, jc2); - SASSERT(t->empty()); + ENSURE(t->empty()); t->display(std::cout); std::cout << "\n"; t->deallocate(); @@ -843,9 +843,9 @@ public: rel_union union_fn = p.mk_union_fn(r, r, 0); (*union_fn)(r, *full); doc_manager& dm = r.get_dm(); - SASSERT(r.get_udoc().size() == 1); + ENSURE(r.get_udoc().size() == 1); doc& d0 = r.get_udoc()[0]; - SASSERT(dm.is_full(d0)); + ENSURE(dm.is_full(d0)); for (unsigned i = 0; i < num_vals; ++i) { unsigned idx = m_rand(num_bits); unsigned val = m_rand(2); diff --git a/src/test/uint_set.cpp b/src/test/uint_set.cpp index fcbbd5c48..3134ada7b 100644 --- a/src/test/uint_set.cpp +++ b/src/test/uint_set.cpp @@ -44,91 +44,91 @@ static void tst1(unsigned n) { s2[idx] = false; s1.remove(idx); } - SASSERT(s1.num_elems() == size); - SASSERT((size == 0) == s1.empty()); + ENSURE(s1.num_elems() == size); + ENSURE((size == 0) == s1.empty()); for (unsigned idx = 0; idx < n; idx++) { - SASSERT(s2[idx] == s1.contains(idx)); + ENSURE(s2[idx] == s1.contains(idx)); } } } static void tst2(unsigned n) { uint_set s; - SASSERT(s.empty()); + ENSURE(s.empty()); unsigned val = rand()%n; s.insert(val); - SASSERT(!s.empty()); - SASSERT(s.num_elems() == 1); + ENSURE(!s.empty()); + ENSURE(s.num_elems() == 1); for (unsigned i = 0; i < 100; i++) { unsigned val2 = rand()%n; if (val != val2) { - SASSERT(!s.contains(val2)); + ENSURE(!s.contains(val2)); } } s.remove(val); - SASSERT(s.num_elems() == 0); - SASSERT(s.empty()); + ENSURE(s.num_elems() == 0); + ENSURE(s.empty()); } static void tst3(unsigned n) { - SASSERT(n > 10); + ENSURE(n > 10); uint_set s1; uint_set s2; - SASSERT(s1 == s2); + ENSURE(s1 == s2); s1.insert(3); - SASSERT(s1.num_elems() == 1); - SASSERT(s2.num_elems() == 0); - SASSERT(s1 != s2); + ENSURE(s1.num_elems() == 1); + ENSURE(s2.num_elems() == 0); + ENSURE(s1 != s2); s2.insert(5); - SASSERT(s2.num_elems() == 1); - SASSERT(s1 != s2); - SASSERT(!s1.subset_of(s2)); + ENSURE(s2.num_elems() == 1); + ENSURE(s1 != s2); + ENSURE(!s1.subset_of(s2)); s2 |= s1; - SASSERT(s1.subset_of(s2)); - SASSERT(s2.num_elems() == 2); - SASSERT(s1 != s2); + ENSURE(s1.subset_of(s2)); + ENSURE(s2.num_elems() == 2); + ENSURE(s1 != s2); s1 |= s2; - SASSERT(s1.subset_of(s2)); - SASSERT(s2.subset_of(s1)); - SASSERT(s1.num_elems() == 2); - SASSERT(s2.num_elems() == 2); - SASSERT(s1 == s2); + ENSURE(s1.subset_of(s2)); + ENSURE(s2.subset_of(s1)); + ENSURE(s1.num_elems() == 2); + ENSURE(s2.num_elems() == 2); + ENSURE(s1 == s2); s1.insert(9); - SASSERT(s1.num_elems() == 3); - SASSERT(s2.num_elems() == 2); + ENSURE(s1.num_elems() == 3); + ENSURE(s2.num_elems() == 2); s1.insert(9); - SASSERT(s1.num_elems() == 3); - SASSERT(s2.num_elems() == 2); - SASSERT(s2.subset_of(s1)); - SASSERT(!s1.subset_of(s2)); - SASSERT(s1 != s2); + ENSURE(s1.num_elems() == 3); + ENSURE(s2.num_elems() == 2); + ENSURE(s2.subset_of(s1)); + ENSURE(!s1.subset_of(s2)); + ENSURE(s1 != s2); uint_set s3(s1); - SASSERT(s1 == s3); - SASSERT(s1.subset_of(s3)); - SASSERT(s3.subset_of(s1)); - SASSERT(s2 != s3); + ENSURE(s1 == s3); + ENSURE(s1.subset_of(s3)); + ENSURE(s3.subset_of(s1)); + ENSURE(s2 != s3); uint_set s4(s2); - SASSERT(s2 == s4); - SASSERT(s2.subset_of(s4)); - SASSERT(s4.subset_of(s2)); - SASSERT(s2 != s3); + ENSURE(s2 == s4); + ENSURE(s2.subset_of(s4)); + ENSURE(s4.subset_of(s2)); + ENSURE(s2 != s3); for (unsigned i = 0; i < n; i++) { uint_set s5; s5.insert(i); - SASSERT(s1.contains(i) == s5.subset_of(s1)); + ENSURE(s1.contains(i) == s5.subset_of(s1)); } } static void tst4() { uint_set s; s.insert(32); - SASSERT(s.contains(32)); - SASSERT(!s.contains(31)); - SASSERT(!s.contains(0)); + ENSURE(s.contains(32)); + ENSURE(!s.contains(31)); + ENSURE(!s.contains(0)); s.remove(32); - SASSERT(!s.contains(32)); - SASSERT(!s.contains(31)); - SASSERT(!s.contains(0)); + ENSURE(!s.contains(32)); + ENSURE(!s.contains(31)); + ENSURE(!s.contains(0)); } #include "map.h" diff --git a/src/test/upolynomial.cpp b/src/test/upolynomial.cpp index 43aefed99..4c8358b3a 100644 --- a/src/test/upolynomial.cpp +++ b/src/test/upolynomial.cpp @@ -101,10 +101,10 @@ static void tst_isolate_roots(polynomial_ref const & p, unsigned prec, mpbq_mana std::cout << "num. roots: " << roots.size() + lowers.size() << "\n"; std::cout << "sign var(-oo): " << um.sign_variations_at_minus_inf(sseq) << "\n"; std::cout << "sign var(+oo): " << um.sign_variations_at_plus_inf(sseq) << "\n"; - SASSERT(roots.size() + lowers.size() == um.sign_variations_at_minus_inf(sseq) - um.sign_variations_at_plus_inf(sseq)); + ENSURE(roots.size() + lowers.size() == um.sign_variations_at_minus_inf(sseq) - um.sign_variations_at_plus_inf(sseq)); std::cout << "roots:"; for (unsigned i = 0; i < roots.size(); i++) { - SASSERT(um.eval_sign_at(q.size(), q.c_ptr(), roots[i]) == 0); + ENSURE(um.eval_sign_at(q.size(), q.c_ptr(), roots[i]) == 0); std::cout << " "; bqm.display_decimal(std::cout, roots[i], prec); } { @@ -118,7 +118,7 @@ static void tst_isolate_roots(polynomial_ref const & p, unsigned prec, mpbq_mana bqm.display_decimal(std::cout, uppers[i], prec); std::cout << ")"; // Check interval with Sturm sequence. Small detail: Sturm sequence is for close intervals. - SASSERT(um.eval_sign_at(q.size(), q.c_ptr(), lowers[i]) == 0 || + ENSURE(um.eval_sign_at(q.size(), q.c_ptr(), lowers[i]) == 0 || um.eval_sign_at(q.size(), q.c_ptr(), uppers[i]) == 0 || um.sign_variations_at(sseq, lowers[i]) - um.sign_variations_at(sseq, uppers[i]) == 1); // Fourier sequence may also be used to check if the interval is isolating @@ -155,7 +155,7 @@ static void tst_isolate_roots(polynomial_ref const & p, unsigned prec = 5) { } static void check_roots(mpbq_vector const & roots, mpbq_vector const & lowers, mpbq_vector const & uppers, unsigned expected_sz, rational const * expected_roots) { - SASSERT(expected_sz == roots.size() + lowers.size()); + ENSURE(expected_sz == roots.size() + lowers.size()); svector visited; visited.resize(expected_sz, false); for (unsigned i = 0; i < expected_sz; i++) { @@ -163,7 +163,7 @@ static void check_roots(mpbq_vector const & roots, mpbq_vector const & lowers, m bool found = false; for (unsigned j = 0; j < roots.size(); j++) { if (to_rational(roots[j]) == r) { - SASSERT(!visited[j]); + ENSURE(!visited[j]); VERIFY(!found); found = true; visited[j] = true; @@ -173,12 +173,12 @@ static void check_roots(mpbq_vector const & roots, mpbq_vector const & lowers, m unsigned j_prime = j + roots.size(); if (to_rational(lowers[j]) < r && r < to_rational(uppers[j])) { VERIFY(!found); - SASSERT(!visited[j_prime]); + ENSURE(!visited[j_prime]); found = true; visited[j_prime] = true; } } - SASSERT(found); + ENSURE(found); } } @@ -292,21 +292,21 @@ static void tst_remove_one_half() { upolynomial::scoped_numeral_vector _p(um), _q(um), _r(um); um.to_numeral_vector(p, _p); um.to_numeral_vector(r, _r); - SASSERT(um.has_one_half_root(_p.size(), _p.c_ptr())); + ENSURE(um.has_one_half_root(_p.size(), _p.c_ptr())); um.remove_one_half_root(_p.size(), _p.c_ptr(), _q); - SASSERT(!um.has_one_half_root(_q.size(), _q.c_ptr())); + ENSURE(!um.has_one_half_root(_q.size(), _q.c_ptr())); std::cout << "_p: "; um.display(std::cout, _p); std::cout << "\n"; std::cout << "_r: "; um.display(std::cout, _r); std::cout << "\n"; std::cout << "_q: "; um.display(std::cout, _q); std::cout << "\n"; - SASSERT(um.eq(_q, _r)); + ENSURE(um.eq(_q, _r)); p = (((x^5) - 1000000000)^3)*((3*x - 10000000)^2)*((10*x - 632)^2); um.to_numeral_vector(p, _p); - SASSERT(!um.has_one_half_root(_p.size(), _p.c_ptr())); + ENSURE(!um.has_one_half_root(_p.size(), _p.c_ptr())); p = (x - 2)*(x - 4)*(x - 8)*(x - 16)*(x - 32)*(x - 64)*(2*x - 1)*(4*x - 1)*(8*x - 1)*(16*x - 1)*(32*x - 1); um.to_numeral_vector(p, _p); - SASSERT(um.has_one_half_root(_p.size(), _p.c_ptr())); + ENSURE(um.has_one_half_root(_p.size(), _p.c_ptr())); } template @@ -503,7 +503,7 @@ static void tst_refinable(polynomial_ref const & p, mpbq_manager & bqm, mpbq & a } else { std::cout << "new root: " << bqm.to_string(a) << "\n"; - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), a) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), a) == 0); } } @@ -608,13 +608,13 @@ static void tst_translate_q() { upolynomial::manager um(rl, nm); upolynomial::scoped_numeral_vector _p(um), _q(um); um.to_numeral_vector(p, _p); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(1)) == 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(2)) == 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(3)) == 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(4)) == 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(-1)) != 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(5)) != 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(-2)) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(1)) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(2)) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(3)) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(4)) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(-1)) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(5)) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(-2)) != 0); scoped_mpq c(nm); nm.set(c, 1, 3); scoped_mpq r1(nm); @@ -623,32 +623,32 @@ static void tst_translate_q() { scoped_mpq r2(nm); r2 = 3; r2 -= c; - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), r1) != 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), r2) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), r1) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), r2) != 0); std::cout << "p: "; um.display(std::cout, _p); std::cout << "\n"; um.translate_q(_p.size(), _p.c_ptr(), c, _q); std::cout << "q: "; um.display(std::cout, _q); std::cout << "\n"; - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(1)) != 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(2)) != 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(3)) != 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(4)) != 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(-1)) != 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(5)) != 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(-2)) != 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), r1) == 0); - SASSERT(um.eval_sign_at(_q.size(), _q.c_ptr(), r2) == 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(1)) != 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(2)) != 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(3)) != 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(4)) != 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(-1)) != 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(5)) != 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), mpq(-2)) != 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), r1) == 0); + ENSURE(um.eval_sign_at(_q.size(), _q.c_ptr(), r2) == 0); um.p_1_div_x(_p.size(), _p.c_ptr()); std::cout << "p: "; um.display(std::cout, _p); std::cout << "\n"; - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(1)) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(1)) == 0); nm.set(c, 1, 2); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); nm.set(c, 1, 3); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); nm.set(c, 1, 4); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(2)) != 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(3)) != 0); - SASSERT(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(4)) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), c) == 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(2)) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(3)) != 0); + ENSURE(um.eval_sign_at(_p.size(), _p.c_ptr(), mpq(4)) != 0); } static void tst_convert_q2bq(unsynch_mpq_manager & m, polynomial_ref const & p, mpq const & a, mpq const & b) { @@ -848,9 +848,9 @@ static void tst_exact_div(polynomial_ref const & p1, polynomial_ref const & p2, std::cout << "expected: "; um.display(std::cout, _q); std::cout << "\n"; } std::cout.flush(); - SASSERT(res == expected); - SASSERT(expected == um.divides(_p1.size(), _p1.c_ptr(), _p2.size(), _p2.c_ptr())); - SASSERT(!expected || um.eq(_r, _q)); + ENSURE(res == expected); + ENSURE(expected == um.divides(_p1.size(), _p1.c_ptr(), _p2.size(), _p2.c_ptr())); + ENSURE(!expected || um.eq(_r, _q)); } static void tst_exact_div() { @@ -878,7 +878,7 @@ static void tst_exact_div() { } static void tst_fact(polynomial_ref const & p, unsigned num_distinct_factors, upolynomial::factor_params const & params = upolynomial::factor_params()) { - SASSERT(is_univariate(p)); + ENSURE(is_univariate(p)); std::cout << "---------------\n"; std::cout << "p: " << p << std::endl; reslimit rl; upolynomial::manager um(rl, p.m().m()); @@ -891,11 +891,11 @@ static void tst_fact(polynomial_ref const & p, unsigned num_distinct_factors, up for (unsigned i = 0; i < fs.distinct_factors(); i++) { std::cout << "*("; um.display(std::cout, fs[i]); std::cout << ")^" << fs.get_degree(i) << std::endl; } - SASSERT(fs.distinct_factors() == num_distinct_factors); + ENSURE(fs.distinct_factors() == num_distinct_factors); upolynomial::scoped_numeral_vector _r(um); fs.multiply(_r); TRACE("upolynomial", tout << "_r: "; um.display(tout, _r); tout << "\n_p: "; um.display(tout, _p); tout << "\n";); - SASSERT(um.eq(_p, _r)); + ENSURE(um.eq(_p, _r)); } static void tst_fact() { @@ -992,8 +992,8 @@ static void tst_fact() { } static void tst_rem(polynomial_ref const & p, polynomial_ref const & q, polynomial_ref const & expected) { - SASSERT(is_univariate(p)); - SASSERT(is_univariate(q)); + ENSURE(is_univariate(p)); + ENSURE(is_univariate(q)); std::cout << "---------------\n"; std::cout << "p: " << p << std::endl; std::cout << "q: " << q << std::endl; @@ -1005,7 +1005,7 @@ static void tst_rem(polynomial_ref const & p, polynomial_ref const & q, polynomi polynomial_ref r(p.m()); r = p.m().to_polynomial(_r.size(), _r.c_ptr(), 0); std::cout << "r: " << r << std::endl; - SASSERT(eq(expected, r)); + ENSURE(eq(expected, r)); } static void tst_rem() { @@ -1022,7 +1022,7 @@ static void tst_rem() { } static void tst_lower_bound(polynomial_ref const & p) { - SASSERT(is_univariate(p)); + ENSURE(is_univariate(p)); std::cout << "---------------\n"; std::cout << "p: " << p << std::endl; reslimit rl; upolynomial::manager um(rl, p.m().m()); diff --git a/src/test/var_subst.cpp b/src/test/var_subst.cpp index e82c09218..f90292d11 100644 --- a/src/test/var_subst.cpp +++ b/src/test/var_subst.cpp @@ -87,7 +87,7 @@ void tst_subst(ast_manager& m) { std::cout << mk_pp(e2, m) << "\n"; std::cout << mk_pp(e3, m) << "\n"; std::cout << mk_pp(t1, m) << "\n"; - SASSERT(e3.get() == t1.get()); + ENSURE(e3.get() == t1.get()); // replace #2 -> #3, #3 -> #2 e2 = m.mk_forall(2, ss, names, e1); @@ -95,7 +95,7 @@ void tst_subst(ast_manager& m) { std::cout << mk_pp(e2, m) << "\n"; std::cout << mk_pp(e3, m) << "\n"; std::cout << mk_pp(t2, m) << "\n"; - SASSERT(e3.get() == t2.get()); + ENSURE(e3.get() == t2.get()); } diff --git a/src/test/vector.cpp b/src/test/vector.cpp index 86ae997ca..f7d70a87b 100644 --- a/src/test/vector.cpp +++ b/src/test/vector.cpp @@ -20,28 +20,28 @@ Revision History: static void tst1() { svector v1; - SASSERT(v1.empty()); + ENSURE(v1.empty()); for (unsigned i = 0; i < 1000; i++) { v1.push_back(i + 3); - SASSERT(static_cast(v1[i]) == i + 3); - SASSERT(v1.capacity() >= v1.size()); - SASSERT(!v1.empty()); + ENSURE(static_cast(v1[i]) == i + 3); + ENSURE(v1.capacity() >= v1.size()); + ENSURE(!v1.empty()); } for (unsigned i = 0; i < 1000; i++) { - SASSERT(static_cast(v1[i]) == i + 3); + ENSURE(static_cast(v1[i]) == i + 3); } svector::iterator it = v1.begin(); svector::iterator end = v1.end(); for (int i = 0; it != end; ++it, ++i) { - SASSERT(*it == i + 3); + ENSURE(*it == i + 3); } for (unsigned i = 0; i < 1000; i++) { - SASSERT(static_cast(v1.back()) == 1000 - i - 1 + 3); - SASSERT(v1.size() == 1000 - i); + ENSURE(static_cast(v1.back()) == 1000 - i - 1 + 3); + ENSURE(v1.size() == 1000 - i); v1.pop_back(); } - SASSERT(v1.empty()); - SASSERT(v1.size() == 0); + ENSURE(v1.empty()); + ENSURE(v1.size() == 0); unsigned i = 1000000000; while (true) { std::cout << "resize " << i << "\n"; diff --git a/src/util/debug.h b/src/util/debug.h index 6e295dcaa..ec0f600b5 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -79,14 +79,10 @@ bool is_debug_enabled(const char * tag); #define NOT_IMPLEMENTED_YET() { std::cerr << "NOT IMPLEMENTED YET!\n"; UNREACHABLE(); exit(ERR_NOT_IMPLEMENTED_YET); } ((void) 0) -#ifdef Z3DEBUG #define VERIFY(_x_) if (!(_x_)) { \ std::cerr << "Failed to verify: " << #_x_ << "\n"; \ UNREACHABLE(); \ } -#else -#define VERIFY(_x_) (void)(_x_) -#endif #define ENSURE(_x_) \ if (!(_x_)) { \ From 1a07c6c18803ba7165e1c11461ed1193da556cbd Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 26 Jul 2017 20:48:49 -0700 Subject: [PATCH 008/488] address ASAN bug report #1160 Signed-off-by: Nikolaj Bjorner --- src/math/simplex/model_based_opt.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/math/simplex/model_based_opt.cpp b/src/math/simplex/model_based_opt.cpp index c31eabb62..561f4c47a 100644 --- a/src/math/simplex/model_based_opt.cpp +++ b/src/math/simplex/model_based_opt.cpp @@ -954,7 +954,8 @@ namespace opt { row& r1 = m_rows[row_id1]; vector coeffs; mk_coeffs_without(coeffs, r1.m_vars, x); - add_divides(coeffs, r1.m_coeff, abs(a)); + rational c = r1.m_coeff; + add_divides(coeffs, c, abs(a)); } unsigned_vector const& row_ids = m_var2row_ids[x]; uint_set visited; From 2cc6baede55baa7b1051d950e2d97bb6d6e17bcf Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 07:44:08 -0700 Subject: [PATCH 009/488] address #1167 Signed-off-by: Nikolaj Bjorner --- src/parsers/smt2/smt2parser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 08bb6bbee..113039639 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -2238,6 +2238,9 @@ namespace smt2 { m_assert_expr = m_scanner.cached_str(0, m_cache_end); m_scanner.stop_caching(); } + if (expr_stack().empty()) { + throw cmd_exception("invalid assert command, expression required as argument"); + } expr * f = expr_stack().back(); if (!m().is_bool(f)) throw cmd_exception("invalid assert command, term is not Boolean"); From d3e1d250a787107b16aaa1006459bfa6338029b8 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 07:50:16 -0700 Subject: [PATCH 010/488] fixes #1168 Signed-off-by: Nikolaj Bjorner --- src/parsers/smt2/smt2parser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 113039639..c948389ee 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -1656,7 +1656,9 @@ namespace smt2 { fr->m_in_decls = false; SASSERT(symbol_stack().size() >= fr->m_sym_spos); SASSERT(expr_stack().size() >= fr->m_expr_spos); - SASSERT(symbol_stack().size() - fr->m_sym_spos == expr_stack().size() - fr->m_expr_spos); + if (symbol_stack().size() - fr->m_sym_spos != expr_stack().size() - fr->m_expr_spos) { + throw parser_exception("malformed let expression"); + } unsigned num_decls = expr_stack().size() - fr->m_expr_spos; symbol * sym_it = symbol_stack().c_ptr() + fr->m_sym_spos; expr ** expr_it = expr_stack().c_ptr() + fr->m_expr_spos; From 6558999cef58427b0d044194557d800093e5216a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 08:46:20 -0700 Subject: [PATCH 011/488] fixes #1171 Signed-off-by: Nikolaj Bjorner --- src/math/simplex/model_based_opt.cpp | 8 ++++++-- src/qe/qe_arith.cpp | 10 +++++----- src/test/mpff.cpp | 2 -- src/test/symbol_table.cpp | 2 -- src/util/heap.h | 2 -- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/math/simplex/model_based_opt.cpp b/src/math/simplex/model_based_opt.cpp index 561f4c47a..f12918bfe 100644 --- a/src/math/simplex/model_based_opt.cpp +++ b/src/math/simplex/model_based_opt.cpp @@ -18,8 +18,9 @@ Revision History: --*/ -#include "model_based_opt.h" -#include "uint_set.h" +#include "math/simplex/model_based_opt.h" +#include "util/uint_set.h" +#include "util/z3_exception.h" std::ostream& operator<<(std::ostream& out, opt::ineq_type ie) { switch (ie) { @@ -868,6 +869,9 @@ namespace opt { for (unsigned i = 0; i < mod_rows.size(); ++i) { D = lcm(D, m_rows[mod_rows[i]].m_mod); } + if (D.is_zero()) { + throw default_exception("modulo 0 is not defined"); + } TRACE("opt", display(tout << "lcm: " << D << " tableau\n");); rational val_x = m_var2value[x]; rational u = mod(val_x, D); diff --git a/src/qe/qe_arith.cpp b/src/qe/qe_arith.cpp index d98f36d7d..4490d83db 100644 --- a/src/qe/qe_arith.cpp +++ b/src/qe/qe_arith.cpp @@ -90,8 +90,8 @@ namespace qe { rational r1, r2; expr_ref val1 = eval(e1); expr_ref val2 = eval(e2); - VERIFY(a.is_numeral(val1, r1)); - VERIFY(a.is_numeral(val2, r2)); + if (!a.is_numeral(val1, r1)) return false; + if (!a.is_numeral(val2, r2)) return false; SASSERT(r1 != r2); if (r1 < r2) { std::swap(e1, e2); @@ -107,7 +107,7 @@ namespace qe { vector > nums; for (unsigned i = 0; i < alit->get_num_args(); ++i) { val = eval(alit->get_arg(i)); - VERIFY(a.is_numeral(val, r)); + if (!a.is_numeral(val, r)) return false; nums.push_back(std::make_pair(alit->get_arg(i), r)); } std::sort(nums.begin(), nums.end(), compare_second()); @@ -129,7 +129,7 @@ namespace qe { expr* arg1 = to_app(lit)->get_arg(i), *arg2 = 0; rational r; expr_ref val = eval(arg1); - VERIFY(a.is_numeral(val, r)); + if (!a.is_numeral(val, r)) return false; if (values.find(r, arg2)) { ty = opt::t_eq; linearize(mbo, eval, mul, arg1, c, fmls, ts, tids); @@ -196,7 +196,7 @@ namespace qe { linearize(mbo, eval, mul, t3, c, fmls, ts, tids); } } - else if (a.is_mod(t, t1, t2) && is_numeral(t2, mul1)) { + else if (a.is_mod(t, t1, t2) && is_numeral(t2, mul1) && !mul1.is_zero()) { rational r; val = eval(t); VERIFY(a.is_numeral(val, r)); diff --git a/src/test/mpff.cpp b/src/test/mpff.cpp index bb06846d5..af67d9ff5 100644 --- a/src/test/mpff.cpp +++ b/src/test/mpff.cpp @@ -317,9 +317,7 @@ static void tst_power(unsigned prec = 2) { ENSURE(m.eq(a, b)); // checking special support for powers of 2 -#ifdef Z3DEBUG unsigned k; -#endif m.set(a, 1); ENSURE(m.is_power_of_two(a, k) && k == 0); m.set(a, 2); diff --git a/src/test/symbol_table.cpp b/src/test/symbol_table.cpp index 8c3c55c9d..626e2a72f 100644 --- a/src/test/symbol_table.cpp +++ b/src/test/symbol_table.cpp @@ -26,9 +26,7 @@ static void tst1() { t.begin_scope(); t.insert(symbol("boo"), 20); ENSURE(t.contains(symbol("boo"))); -#ifdef Z3DEBUG int tmp; -#endif ENSURE(t.find(symbol("boo"), tmp) && tmp == 20); ENSURE(t.find(symbol("foo"), tmp) && tmp == 35); t.insert(symbol("foo"), 100); diff --git a/src/util/heap.h b/src/util/heap.h index cde2451db..14e902648 100644 --- a/src/util/heap.h +++ b/src/util/heap.h @@ -52,7 +52,6 @@ class heap : private LT { } } -#ifdef Z3DEBUG // Return true if the value can be inserted in the heap. That is, the vector m_value2indices is big enough to store this value. bool is_valid_value(int v) const { SASSERT(v >= 0 && v < static_cast(m_value2indices.size())); @@ -75,7 +74,6 @@ public: return check_invariant_core(1); } -#endif private: void move_up(int idx) { From 21759e5eb27fdf1dbdceca27b00dcf0b3683ce88 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 08:59:12 -0700 Subject: [PATCH 012/488] fixes #1172 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/interpolant_cmds.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cmd_context/interpolant_cmds.cpp b/src/cmd_context/interpolant_cmds.cpp index 53da91d1e..de79dbc52 100644 --- a/src/cmd_context/interpolant_cmds.cpp +++ b/src/cmd_context/interpolant_cmds.cpp @@ -46,20 +46,20 @@ static void show_interpolant_and_maybe_check(cmd_context & ctx, m_params.set_bool("flat", true); th_rewriter s(ctx.m(), m_params); + expr_ref_vector exprs(ctx.m()); + sort_ref_vector domain(ctx.m()); for(unsigned i = 0; i < interps.size(); i++){ - expr_ref r(ctx.m()); proof_ref pr(ctx.m()); s(to_expr(interps[i]),r,pr); - - ctx.regular_stream() << mk_pp(r.get(), ctx.m()) << std::endl; -#if 0 - ast_smt_pp pp(ctx.m()); - pp.set_logic(ctx.get_logic().str().c_str()); - pp.display_smt2(ctx.regular_stream(), to_expr(interps[i])); - ctx.regular_stream() << std::endl; -#endif + exprs.push_back(r); + domain.push_back(ctx.m().mk_bool_sort()); } + func_decl_ref fn(ctx.m()); + fn = ctx.m().mk_func_decl(symbol("interpolants"), domain.size(), domain.c_ptr(), ctx.m().mk_bool_sort()); + expr_ref tmp(ctx.m()); + tmp = ctx.m().mk_app(fn, exprs.size(), exprs.c_ptr()); + ctx.regular_stream() << tmp << "\n"; s.cleanup(); From 18e9e4f4ac4ad9d0dccb8769bd016600a14195c0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 09:25:01 -0700 Subject: [PATCH 013/488] fixes #1169 Signed-off-by: Nikolaj Bjorner --- src/muz/fp/dl_cmds.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/muz/fp/dl_cmds.cpp b/src/muz/fp/dl_cmds.cpp index 49632b39c..a98143aed 100644 --- a/src/muz/fp/dl_cmds.cpp +++ b/src/muz/fp/dl_cmds.cpp @@ -374,12 +374,9 @@ class dl_declare_rel_cmd : public cmd { unsigned m_arg_idx; mutable unsigned m_query_arg_idx; symbol m_rel_name; - scoped_ptr m_domain; + ptr_vector m_domain; svector m_kinds; - void ensure_domain(cmd_context& ctx) { - if (!m_domain) m_domain = alloc(sort_ref_vector, ctx.m()); - } public: dl_declare_rel_cmd(dl_context * dl_ctx): @@ -395,7 +392,7 @@ public: ctx.m(); // ensure manager is initialized. m_arg_idx = 0; m_query_arg_idx = 0; - m_domain = 0; + m_domain.reset(); m_kinds.reset(); } virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { @@ -406,8 +403,8 @@ public: } } virtual void set_next_arg(cmd_context & ctx, unsigned num, sort * const * slist) { - ensure_domain(ctx); - m_domain->append(num, slist); + m_domain.reset(); + m_domain.append(num, slist); m_arg_idx++; } virtual void set_next_arg(cmd_context & ctx, symbol const & s) { @@ -424,14 +421,12 @@ public: if(m_arg_idx<2) { throw cmd_exception("at least 2 arguments expected"); } - ensure_domain(ctx); ast_manager& m = ctx.m(); func_decl_ref pred( - m.mk_func_decl(m_rel_name, m_domain->size(), m_domain->c_ptr(), m.mk_bool_sort()), m); + m.mk_func_decl(m_rel_name, m_domain.size(), m_domain.c_ptr(), m.mk_bool_sort()), m); ctx.insert(pred); m_dl_ctx->register_predicate(pred, m_kinds.size(), m_kinds.c_ptr()); - m_domain = 0; } }; From 2e3a5a206003ac509577bafced0916e427545528 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 11:03:18 -0700 Subject: [PATCH 014/488] attempt at addressing #989 by referencing _lib directly instead of over lib() in function calls Signed-off-by: Nikolaj Bjorner --- scripts/update_api.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index cc96bd425..1567a03fa 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -322,15 +322,15 @@ def mk_py_wrappers(): display_args(num) core_py.write("):\n") if result != VOID: - core_py.write(" r = lib().%s(" % name) + core_py.write(" r = _lib.%s(" % name) else: - core_py.write(" lib().%s(" % name) + core_py.write(" _lib.%s(" % name) display_args_to_z3(params) core_py.write(")\n") if len(params) > 0 and param_type(params[0]) == CONTEXT: - core_py.write(" err = lib().Z3_get_error_code(a0)\n") + core_py.write(" err = _lib.Z3_get_error_code(a0)\n") core_py.write(" if err != Z3_OK:\n") - core_py.write(" raise Z3Exception(lib().Z3_get_error_msg(a0, err))\n") + core_py.write(" raise Z3Exception(_lib.Z3_get_error_msg(a0, err))\n") if result == STRING: core_py.write(" return _to_pystr(r)\n") elif result != VOID: @@ -1600,6 +1600,20 @@ def write_exe_c_preamble(exe_c): # exe_c.write('void Z3_replayer_error_handler(Z3_context ctx, Z3_error_code c) { printf("[REPLAYER ERROR HANDLER]: %s\\n", Z3_get_error_msg(ctx, c)); }\n') +def write_core_py_post(core_py): + core_py.write(""" +_dirs = ['.', os.path.dirname(os.path.abspath(__file__)), pkg_resources.resource_filename('z3', 'lib'), os.path.join(sys.prefix, 'lib'), None] + +for _dir in _dirs: + try: + init(_dir) + break + except: + pass +if _lib is None: + raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python") +""") + def write_core_py_preamble(core_py): core_py.write('# Automatically generated file\n') core_py.write('import sys, os\n') @@ -1612,18 +1626,9 @@ def write_core_py_preamble(core_py): _ext = 'dll' if sys.platform in ('win32', 'cygwin') else 'dylib' if sys.platform == 'darwin' else 'so' _lib = None + def lib(): global _lib - if _lib is None: - _dirs = ['.', os.path.dirname(os.path.abspath(__file__)), pkg_resources.resource_filename('z3', 'lib'), os.path.join(sys.prefix, 'lib'), None] - for _dir in _dirs: - try: - init(_dir) - break - except: - pass - if _lib is None: - raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python") return _lib def _to_ascii(s): @@ -1728,6 +1733,7 @@ def generate_files(api_files, def_APIs(api_files) mk_bindings(exe_c) mk_py_wrappers() + write_core_py_post(core_py) if mk_util.is_verbose(): print("Generated '{}'".format(log_h.name)) From c8b5be48de0ea38a26effc0a71b003af77d91a52 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 11:44:52 -0700 Subject: [PATCH 015/488] unexpressing interpolants #1172 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/interpolant_cmds.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/cmd_context/interpolant_cmds.cpp b/src/cmd_context/interpolant_cmds.cpp index de79dbc52..2bfdd9848 100644 --- a/src/cmd_context/interpolant_cmds.cpp +++ b/src/cmd_context/interpolant_cmds.cpp @@ -46,20 +46,14 @@ static void show_interpolant_and_maybe_check(cmd_context & ctx, m_params.set_bool("flat", true); th_rewriter s(ctx.m(), m_params); - expr_ref_vector exprs(ctx.m()); - sort_ref_vector domain(ctx.m()); + ctx.regular_stream() << "(interpolants"; for(unsigned i = 0; i < interps.size(); i++){ expr_ref r(ctx.m()); proof_ref pr(ctx.m()); s(to_expr(interps[i]),r,pr); - exprs.push_back(r); - domain.push_back(ctx.m().mk_bool_sort()); + ctx.regular_stream() << "\n " << r; } - func_decl_ref fn(ctx.m()); - fn = ctx.m().mk_func_decl(symbol("interpolants"), domain.size(), domain.c_ptr(), ctx.m().mk_bool_sort()); - expr_ref tmp(ctx.m()); - tmp = ctx.m().mk_app(fn, exprs.size(), exprs.c_ptr()); - ctx.regular_stream() << tmp << "\n"; + ctx.regular_stream() << ")\n"; s.cleanup(); From b90201837382b1faa7579d42192491df09706443 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 11:56:01 -0700 Subject: [PATCH 016/488] add suspenders for #989 Signed-off-by: Nikolaj Bjorner --- scripts/update_api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/update_api.py b/scripts/update_api.py index 1567a03fa..cbc4d9bbb 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -321,6 +321,8 @@ def mk_py_wrappers(): core_py.write("def %s(" % name) display_args(num) core_py.write("):\n") + core_py.write(" if _lib is None:\n") + core_py.write(" return\n") if result != VOID: core_py.write(" r = _lib.%s(" % name) else: From af47aa0120302a19a6bb27b4d03011fa661104e0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 12:32:44 -0700 Subject: [PATCH 017/488] updated suspenders for #989 Signed-off-by: Nikolaj Bjorner --- scripts/update_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index cbc4d9bbb..e97c32be8 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -321,7 +321,7 @@ def mk_py_wrappers(): core_py.write("def %s(" % name) display_args(num) core_py.write("):\n") - core_py.write(" if _lib is None:\n") + core_py.write(" if _lib.%s is None:\n" % name) core_py.write(" return\n") if result != VOID: core_py.write(" r = _lib.%s(" % name) From ca672745199049474dae24ffde417c0672771752 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 27 Jul 2017 12:59:34 -0700 Subject: [PATCH 018/488] another round of fix for #989 to avoid problems with doxygen generation (TravisCI build failure) Signed-off-by: Nikolaj Bjorner --- scripts/update_api.py | 20 +++++++++++--------- src/smt/theory_str.cpp | 8 +++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index e97c32be8..3c1e1cc07 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -321,6 +321,7 @@ def mk_py_wrappers(): core_py.write("def %s(" % name) display_args(num) core_py.write("):\n") + core_py.write(" _lib = lib()\n") core_py.write(" if _lib.%s is None:\n" % name) core_py.write(" return\n") if result != VOID: @@ -1604,16 +1605,7 @@ def write_exe_c_preamble(exe_c): def write_core_py_post(core_py): core_py.write(""" -_dirs = ['.', os.path.dirname(os.path.abspath(__file__)), pkg_resources.resource_filename('z3', 'lib'), os.path.join(sys.prefix, 'lib'), None] -for _dir in _dirs: - try: - init(_dir) - break - except: - pass -if _lib is None: - raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python") """) def write_core_py_preamble(core_py): @@ -1631,6 +1623,16 @@ _lib = None def lib(): global _lib + if _lib is None: + _dirs = ['.', os.path.dirname(os.path.abspath(__file__)), pkg_resources.resource_filename('z3', 'lib'), os.path.join(sys.prefix, 'lib'), None] + for _dir in _dirs: + try: + init(_dir) + break + except: + pass + if _lib is None: + raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python") return _lib def _to_ascii(s): diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 89e0123a8..13f8ab282 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -1549,14 +1549,12 @@ namespace smt { expr_ref elseBranch(ctx.mk_eq_atom(result, expr->get_arg(0)), m); expr_ref breakdownAssert(m.mk_ite(condAst, m.mk_and(thenItems.size(), thenItems.c_ptr()), elseBranch), m); + assert_axiom(breakdownAssert); + SASSERT(breakdownAssert); expr_ref reduceToResult(ctx.mk_eq_atom(expr, result), m); - SASSERT(reduceToResult); - - expr_ref finalAxiom(m.mk_and(breakdownAssert, reduceToResult), m); - SASSERT(finalAxiom); - assert_axiom(finalAxiom); + assert_axiom(reduceToResult); } void theory_str::instantiate_axiom_str_to_int(enode * e) { From 33ebdc8adc0ac55ef2e071a15bdb3236ff0d01d7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Jul 2017 23:08:35 +0100 Subject: [PATCH 019/488] Cleaned up mpf rounder. Rewrote mpf fma. Relates to #872. --- src/ast/fpa/fpa2bv_converter.cpp | 4 - src/util/mpf.cpp | 348 ++++++++++++++++--------------- src/util/mpf.h | 3 +- 3 files changed, 184 insertions(+), 171 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 5b71b2c2d..0e83d7fea 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3904,9 +3904,6 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & SASSERT(m_bv_util.get_bv_size(sig) == sbits+4); SASSERT(m_bv_util.get_bv_size(exp) == ebits+2); - // bool UNFen = false; - // bool OVFen = false; - expr_ref e_min(m), e_max(m); mk_min_exp(ebits, e_min); mk_max_exp(ebits, e_max); @@ -4025,7 +4022,6 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & SASSERT(is_well_sorted(m, sig)); SASSERT(m_bv_util.get_bv_size(sig) == sbits+2); - // CMW: The (OVF1 && OVFen) and (TINY && UNFen) cases are never taken. expr_ref ext_emin(m); ext_emin = m_bv_util.mk_zero_extend(2, e_min); m_simp.mk_ite(TINY, ext_emin, beta, exp); diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index fac314837..36d9e49f1 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -805,7 +805,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co o.ebits = x.ebits; o.sbits = x.sbits; - scoped_mpf mul_res(*this, x.ebits+2, 2*x.sbits); + scoped_mpf mul_res(*this, x.ebits+2, 2*x.sbits-1); scoped_mpf a(*this, x.ebits, x.sbits), b(*this, x.ebits, x.sbits), c(*this, x.ebits, x.sbits); set(a, x); set(b, y); @@ -814,9 +814,12 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co unpack(b, true); unpack(c, true); - TRACE("mpf_dbg", tout << "A = " << to_string(a) << std::endl;); - TRACE("mpf_dbg", tout << "B = " << to_string(b) << std::endl;); - TRACE("mpf_dbg", tout << "C = " << to_string(c) << std::endl;); + TRACE("mpf_dbg", tout << "A = " << to_string(a) << std::endl; + tout << "B = " << to_string(b) << std::endl; + tout << "C = " << to_string(c) << std::endl; + tout << "A = " << to_string_binary(a, 1, 0) << std::endl; + tout << "B = " << to_string_binary(b, 1, 0) << std::endl; + tout << "C = " << to_string_binary(c, 1, 0) << std::endl;); SASSERT(m_mpz_manager.lt(a.significand(), m_powers2(x.sbits))); SASSERT(m_mpz_manager.lt(b.significand(), m_powers2(x.sbits))); @@ -824,98 +827,114 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co SASSERT(m_mpz_manager.ge(a.significand(), m_powers2(x.sbits-1))); SASSERT(m_mpz_manager.ge(b.significand(), m_powers2(x.sbits-1))); + // A/B in _1.[sbits-1]. mul_res.get().sign = (a.sign() != b.sign()); mul_res.get().exponent = a.exponent() + b.exponent(); - m_mpz_manager.mul(a.significand(), b.significand(), mul_res.get().significand); + m_mpz_manager.mul(a.significand(), b.significand(), mul_res.significand()); - TRACE("mpf_dbg", tout << "PRODUCT = " << to_string(mul_res) << std::endl;); + TRACE("mpf_dbg", tout << "M = " << to_string(mul_res) << std::endl; + tout << "M = " << to_string_binary(mul_res, 1, 0) << std::endl;); - // mul_res is [-1][0].[2*sbits - 2], i.e., between 2*sbits-1 and 2*sbits. + // mul_res is [-1][0].[2*sbits - 2], i.e., >= 2^(2*sbits-2) and < 2^(2*sbits). SASSERT(m_mpz_manager.lt(mul_res.significand(), m_powers2(2*x.sbits))); SASSERT(m_mpz_manager.ge(mul_res.significand(), m_powers2(2*x.sbits - 2))); - // Introduce extra bits into c. - m_mpz_manager.mul2k(c.significand(), x.sbits-1, c.significand()); + // Introduce extra bits into c in _[0].[sbits-1] s.t. c in _[0].[2*sbits-2] + c.get().ebits = x.ebits + 2; + c.get().sbits = 2 * x.sbits - 1; + m_mpz_manager.mul2k(c.significand(), x.sbits - 1); - SASSERT(m_mpz_manager.lt(c.significand(), m_powers2(2 * x.sbits - 1))); + TRACE("mpf_dbg", tout << "C_= " << to_string(c) << std::endl; + tout << "C_= " << to_string_binary(c, 1, 0) << std::endl;); + + SASSERT(m_mpz_manager.lt(c.significand(), m_powers2(2*x.sbits))); SASSERT(m_mpz_manager.is_zero(c.significand()) || - m_mpz_manager.ge(c.significand(), m_powers2(2 * x.sbits - 2))); + m_mpz_manager.ge(c.significand(), m_powers2(2*x.sbits - 2))); - TRACE("mpf_dbg", tout << "C = " << to_string(c) << std::endl;); - - if (exp(c) > exp(mul_res)) + if (exp(c) > exp(mul_res)) { + TRACE("mpf_dbg", tout << "Swap!" << std::endl;); mul_res.swap(c); + } - mpf_exp_t exp_delta = exp(mul_res) - exp(c); + mpf_exp_t exp_delta_w = exp(mul_res) - exp(c); - SASSERT(exp(mul_res) >= exp(c) && exp_delta >= 0); + SASSERT(exp(mul_res) >= exp(c) && exp_delta_w >= 0); - if (exp_delta > 2 * x.sbits) - exp_delta = 2 * x.sbits; + if (exp_delta_w > 2 * x.sbits) + exp_delta_w = 2 * x.sbits; + unsigned exp_delta = (unsigned)exp_delta_w; TRACE("mpf_dbg", tout << "exp_delta = " << exp_delta << std::endl;); // Alignment shift with sticky bit computation. scoped_mpz sticky_rem(m_mpz_manager); - m_mpz_manager.machine_div_rem(c.significand(), m_powers2((int)exp_delta), c.significand(), sticky_rem); + m_mpz_manager.machine_div_rem(c.significand(), m_powers2(exp_delta), c.significand(), sticky_rem); TRACE("mpf_dbg", tout << "alignment shift -> sig = " << m_mpz_manager.to_string(c.significand()) << " sticky_rem = " << m_mpz_manager.to_string(sticky_rem) << std::endl;); if (!m_mpz_manager.is_zero(sticky_rem) && m_mpz_manager.is_even(c.significand())) m_mpz_manager.inc(c.significand()); - TRACE("mpf_dbg", tout << "M' = " << m_mpz_manager.to_string(mul_res.significand()) << std::endl;); - TRACE("mpf_dbg", tout << "C' = " << m_mpz_manager.to_string(c.significand()) << std::endl;); + TRACE("mpf_dbg", tout << "M'= " << m_mpz_manager.to_string(mul_res.significand()) << std::endl; + tout << "M'= " << to_string_binary(mul_res, 1, 0) << std::endl; ); + TRACE("mpf_dbg", tout << "C'= " << m_mpz_manager.to_string(c.significand()) << std::endl; + tout << "C'= " << to_string_binary(c, 1, 0) << std::endl; ); + + scoped_mpf res(c); + + res.get().sign = mul_res.sign(); + res.get().exponent = mul_res.exponent(); // Significand addition + if (sgn(mul_res) != sgn(c)) { TRACE("mpf_dbg", tout << "SUBTRACTING" << std::endl;); - m_mpz_manager.sub(mul_res.significand(), c.significand(), o.significand); + m_mpz_manager.sub(mul_res.significand(), c.significand(), res.significand()); + + if (m_mpz_manager.is_neg(res.significand())) { + m_mpz_manager.abs(res.significand()); + res.get().sign |= !mul_res.sign() && c.sign(); + } } else { TRACE("mpf_dbg", tout << "ADDING" << std::endl;); - m_mpz_manager.add(mul_res.significand(), c.significand(), o.significand); + m_mpz_manager.add(mul_res.significand(), c.significand(), res.significand()); } - TRACE("mpf_dbg", tout << "sum[-1:] = " << m_mpz_manager.to_string(o.significand) << std::endl;); + TRACE("mpf_dbg", tout << "S'= " << m_mpz_manager.to_string(res.significand()) << std::endl; + tout << "S'= " << to_string_binary(res, 1, 0) << std::endl; ); - bool neg = m_mpz_manager.is_neg(o.significand); - TRACE("mpf_dbg", tout << "NEG=" << neg << std::endl;); - if (neg) m_mpz_manager.abs(o.significand); - - o.exponent = mul_res.exponent(); - - unsigned extra = 0; - // Result could overflow into 4.xxx ... - SASSERT(m_mpz_manager.lt(o.significand, m_powers2(2 * x.sbits + 2))); - if (m_mpz_manager.ge(o.significand, m_powers2(2 * x.sbits + 1))) + SASSERT(m_mpz_manager.lt(res.significand(), m_powers2(2 * x.sbits + 1))); + if (m_mpz_manager.ge(res.significand(), m_powers2(2 * x.sbits))) { - extra++; - o.exponent++; - TRACE("mpf_dbg", tout << "Addition overflew!" << std::endl;); + SASSERT(exp(res) < mk_max_exp(x.ebits)); // NYI. + + res.get().exponent++; + bool sticky = !m_mpz_manager.is_even(res.significand()); + m_mpz_manager.machine_div2k(res.significand(), 1); + if (sticky && m_mpz_manager.is_even(res.significand())) + m_mpz_manager.inc(res.significand()); + TRACE("mpf_dbg", tout << "Add/Sub overflew into 4.xxx!" << std::endl; + tout << "S*= " << to_string_binary(res, 2, 0) << std::endl;); } - // Remove the extra bits, keeping a sticky bit. - m_mpz_manager.set(sticky_rem, 0); - unsigned minbits = (4 + extra); - if (o.sbits >= minbits) - m_mpz_manager.machine_div_rem(o.significand, m_powers2(o.sbits - minbits), o.significand, sticky_rem); - else - m_mpz_manager.mul2k(o.significand, minbits - o.sbits, o.significand); + set(o, x.ebits, x.sbits, res.sign(), res.exponent(), mpz(0)); - if (!m_mpz_manager.is_zero(sticky_rem) && m_mpz_manager.is_even(o.significand)) - m_mpz_manager.inc(o.significand); + if (x.sbits >= 4) { + m_mpz_manager.set(sticky_rem, 0); + m_mpz_manager.machine_div_rem(res.significand(), m_powers2(x.sbits - 4), o.significand, sticky_rem); + if (!m_mpz_manager.is_zero(sticky_rem) && m_mpz_manager.is_even(o.significand)) + m_mpz_manager.inc(o.significand); + } + else { + m_mpz_manager.mul2k(res.significand(), 4 - x.sbits, o.significand); + } - TRACE("mpf_dbg", tout << "sum[-1:sbits+2] = " << m_mpz_manager.to_string(o.significand) << std::endl;); + TRACE("mpf_dbg", tout << "sum[-1:sbits+2] = " << m_mpz_manager.to_string(o.significand) << std::endl; + tout << "R = " << to_string_binary(o, 2, 3) << std::endl;); if (m_mpz_manager.is_zero(o.significand)) mk_zero(x.ebits, x.sbits, rm == MPF_ROUND_TOWARD_NEGATIVE, o); - else { - o.sign = ((!mul_res.sign() && c.sign() && neg) || - ( mul_res.sign() && !c.sign() && !neg) || - ( mul_res.sign() && c.sign())); - TRACE("mpf_dbg", tout << "before round = " << to_string(o) << std::endl << - "fs[-1:sbits+2] = " << m_mpz_manager.to_string(o.significand) << std::endl;); + else round(rm, o); - } } } @@ -1596,6 +1615,64 @@ std::string mpf_manager::to_string_hexfloat(mpf const & x) { return ss.str(); } +std::string mpf_manager::to_string_binary(mpf const & x, unsigned upper_extra, unsigned lower_extra) { + std::string res; + + if (is_nan(x)) + res = std::string("") + "#b0 " + + "#b" + std::string(x.ebits, '1') + " " + + "#b" + std::string(x.sbits-2, '0') + "1 " + + "(NaN)"; + else if (is_inf(x)) + res = std::string("") + "#b" + (sgn(x)?"1":"0") + " " + + "#b" + std::string(x.ebits, '1') + " " + + "#b" + std::string(x.sbits - 1, '0') + "1 " + + "(" + (sgn(x)?"-":"+") + "oo)"; + else if (is_zero(x)) + res = std::string("") + "#b" + (sgn(x) ? "1" : "0") + " " + + "#b" + std::string(x.ebits, '0') + " " + + "#b" + std::string(x.sbits - 1, '0') + " " + + "(" + (sgn(x) ? "-" : "+") + "zero)"; + else { + res = std::string("") + "#b" + (sgn(x) ? "1" : "0") + " "; + + scoped_mpz tmp(m_mpz_manager); + + if (is_denormal(x)) + m_mpz_manager.set(tmp, bias_exp(x.ebits, mk_min_exp(x.ebits))); + else { + m_mpz_manager.set(tmp, bias_exp(x.ebits, exp(x))); + } + + std::string tmp_str = ""; + for (unsigned i = 0; i < x.ebits; i++) { + tmp_str += m_mpz_manager.is_odd(tmp) ? "1" : "0"; + tmp /= 2; + } + std::reverse(tmp_str.begin(), tmp_str.end()); + res += "#b" + tmp_str + " "; + + tmp_str = ""; + m_mpz_manager.set(tmp, sig(x)); + unsigned num_bits = upper_extra + x.sbits + lower_extra; + for (unsigned i = 0; i < num_bits || !tmp.is_zero(); i++) { + tmp_str += m_mpz_manager.is_odd(tmp) ? "1" : "0"; + tmp /= 2; + if (i == lower_extra - 1) + tmp_str += ","; + if (i == x.sbits + lower_extra - 2) { + tmp_str += "."; + if (i == num_bits - 1) + tmp_str += " "; + } + } + std::reverse(tmp_str.begin(), tmp_str.end()); + res += "#b" + tmp_str; + } + + return res; +} + void mpf_manager::to_rational(mpf const & x, unsynch_mpq_manager & qm, mpq & o) { scoped_mpf a(*this); scoped_mpz n(m_mpq_manager), d(m_mpq_manager); @@ -1865,129 +1942,76 @@ void mpf_manager::mk_round_inf(mpf_rounding_mode rm, mpf & o) { } void mpf_manager::round(mpf_rounding_mode rm, mpf & o) { - // Assumptions: o.significand is of the form f[-1:0] . f[1:sbits-1] [guard,round,sticky], + // Assumptions: o.significand is of the form f[-1:0] . f[1:sbits-1] [round,extra,sticky], // i.e., it has 2 + (sbits-1) + 3 = sbits + 4 bits. - TRACE("mpf_dbg", tout << "RND: " << to_string(o) << std::endl;); + TRACE("mpf_dbg", tout << "RND: " << to_string(o) << std::endl; + tout << to_string_binary(o, 1, 3) << std::endl;); DEBUG_CODE({ - const mpz & p_m3 = m_powers2(o.sbits+5); + const mpz & p_m3 = m_powers2(o.sbits+4); SASSERT(m_mpz_manager.lt(o.significand, p_m3)); }); - // Structure of the rounder: - // (s, e_out, f_out) == (s, exprd(s, post(e, sigrd(s, f)))). + mpf_exp_t e_max = mk_max_exp(o.ebits); + mpf_exp_t e_min = mk_min_exp(o.ebits); - bool UNFen = false; // Are these supposed to be persistent flags accross calls? - bool OVFen = false; + unsigned sig_width = m_mpz_manager.prev_power_of_two(o.significand) + 1; + mpf_exp_t lz = o.sbits + 4 - sig_width; + mpf_exp_t beta = o.exponent - lz + 1; - mpf_exp_t e_max_norm = mk_max_exp(o.ebits); - mpf_exp_t e_min_norm = mk_min_exp(o.ebits); - scoped_mpz temporary(m_mpq_manager); + scoped_mpz sigma(m_mpz_manager); - TRACE("mpf_dbg", tout << "e_min_norm = " << e_min_norm << std::endl << - "e_max_norm = " << e_max_norm << std::endl;); - - const mpz & p_m1 = m_powers2(o.sbits+2); - const mpz & p_m2 = m_powers2(o.sbits+3); - (void)p_m1; - - TRACE("mpf_dbg", tout << "p_m1 = " << m_mpz_manager.to_string(p_m1) << std::endl << - "p_m2 = " << m_mpz_manager.to_string(p_m2) << std::endl;); - - bool OVF1 = o.exponent > e_max_norm || // Exponent OVF - (o.exponent == e_max_norm && m_mpz_manager.ge(o.significand, p_m2)); - - TRACE("mpf_dbg", tout << "OVF1 = " << OVF1 << std::endl;); - - int lz = 0; - scoped_mpz t(m_mpq_manager); - m_mpz_manager.set(t, p_m2); - while (m_mpz_manager.gt(t, o.significand)) { - m_mpz_manager.machine_div2k(t, 1); - lz++; + if (beta < e_min) { + // denormal significand/TINY + m_mpz_manager.set(sigma, o.exponent - e_min); + o.exponent = e_min; + } + else { + m_mpz_manager.set(sigma, lz - 1); + o.exponent = beta; } - TRACE("mpf_dbg", tout << "LZ = " << lz << std::endl;); + scoped_mpz sigma_cap(m_mpz_manager); + sigma_cap = o.sbits + 2; + m_mpz_manager.neg(sigma_cap); + if (m_mpz_manager.lt(sigma, sigma_cap)) + m_mpz_manager.set(sigma, sigma_cap); - m_mpz_manager.set(t, o.exponent); - m_mpz_manager.inc(t); - m_mpz_manager.sub(t, lz, t); - m_mpz_manager.set(temporary, e_min_norm); - m_mpz_manager.sub(t, temporary, t); - bool TINY = m_mpz_manager.is_neg(t); - - TRACE("mpf_dbg", tout << "TINY = " << TINY << std::endl;); - - mpf_exp_t alpha = 3 << (o.ebits-2); - mpf_exp_t beta = o.exponent - lz + 1; - - TRACE("mpf_dbg", tout << "alpha = " << alpha << std::endl << - "beta = " << beta << std::endl; ); - - scoped_mpz sigma(m_mpq_manager); - sigma = 0; - - if (TINY && !UNFen) { - m_mpz_manager.set(sigma, o.exponent); - m_mpz_manager.sub(sigma, temporary, sigma); - m_mpz_manager.inc(sigma); - } - else - m_mpz_manager.set(sigma, lz); - - scoped_mpz limit(m_mpq_manager); - limit = o.sbits + 2; - m_mpz_manager.neg(limit); - if (m_mpz_manager.lt(sigma, limit)) { - m_mpz_manager.set(sigma, limit); - } + TRACE("mpf_dbg", tout << "e_min_norm = " << e_min << std::endl; + tout << "e_max_norm = " << e_max << std::endl; + tout << "beta = " << beta << ", (beta < e_min) = " << (beta < e_min) << std::endl; + tout << "LZ = " << lz << std::endl; + tout << "sigma = " << m_mpz_manager.to_string(sigma) << std::endl; + tout << "sigma_cap = " << m_mpz_manager.to_string(sigma_cap) << std::endl;); // Normalization shift TRACE("mpf_dbg", tout << "Shift distance: " << m_mpz_manager.to_string(sigma) << " " << ((m_mpz_manager.is_nonneg(sigma))?"(LEFT)":"(RIGHT)") << std::endl;); - if (m_mpz_manager.le(sigma, 0)) { // Right shift + if (m_mpz_manager.le(sigma, -1)) { + // Right shift scoped_mpz sticky_rem(m_mpz_manager); - unsigned sigma_uint = (unsigned)-m_mpz_manager.get_int64(sigma); // sigma is capped, this is safe. - sigma_uint += 2; - m_mpz_manager.machine_div_rem(o.significand, m_powers2(sigma_uint), o.significand, sticky_rem); + unsigned nsigma_uint = (unsigned)-m_mpz_manager.get_int64(sigma); // sigma is capped, this is safe. + m_mpz_manager.machine_div_rem(o.significand, m_powers2(nsigma_uint), o.significand, sticky_rem); bool sticky = !m_mpz_manager.is_zero(sticky_rem); if (sticky && m_mpz_manager.is_even(o.significand)) m_mpz_manager.inc(o.significand); } - else { // Left shift + else { + // Left shift unsigned sigma_uint = static_cast(m_mpz_manager.get_int64(sigma)); - m_mpz_manager.mul2k(o.significand, sigma_uint - 1, o.significand); - bool sticky = !m_mpz_manager.is_even(o.significand); - m_mpz_manager.machine_div2k(o.significand, 1); - if (sticky && m_mpz_manager.is_even(o.significand)) - m_mpz_manager.inc(o.significand); + m_mpz_manager.mul2k(o.significand, sigma_uint, o.significand); } - TRACE("mpf_dbg", tout << "After sticky: " << to_string(o) << std::endl;); - - if (OVF1 && OVFen) { - o.exponent = beta; - o.exponent -= alpha; - } - else if (TINY && UNFen) { - o.exponent = beta; - o.exponent += alpha; - } - else if (TINY && !UNFen) - o.exponent = e_min_norm; - else - o.exponent = beta; - - TRACE("mpf_dbg", tout << "Shifted: " << to_string(o) << std::endl;); - - const mpz & p_sig = m_powers2(o.sbits); - SASSERT(TINY || (m_mpz_manager.ge(o.significand, p_sig))); + TRACE("mpf_dbg", tout << "Shifted: " << to_string(o) << std::endl; + tout << to_string_binary(o, 1, 3) << std::endl;); // Significand rounding (sigrd) - bool sticky = !m_mpz_manager.is_even(o.significand); // new sticky bit! + bool sticky = !m_mpz_manager.is_even(o.significand); + m_mpz_manager.machine_div2k(o.significand, 1); + sticky = sticky || !m_mpz_manager.is_even(o.significand); m_mpz_manager.machine_div2k(o.significand, 1); bool round = !m_mpz_manager.is_even(o.significand); m_mpz_manager.machine_div2k(o.significand, 1); @@ -2002,56 +2026,47 @@ void mpf_manager::round(mpf_rounding_mode rm, mpf & o) { bool inc = false; switch (rm) { case MPF_ROUND_NEAREST_TEVEN: inc = round && (last || sticky); break; - // case MPF_ROUND_NEAREST_TAWAY: inc = round; break; // CMW: Check - case MPF_ROUND_NEAREST_TAWAY: inc = round && (!last || sticky); break; // CMW: Fix ok? + case MPF_ROUND_NEAREST_TAWAY: inc = round && (!last || sticky); break; case MPF_ROUND_TOWARD_POSITIVE: inc = (!o.sign && (round || sticky)); break; case MPF_ROUND_TOWARD_NEGATIVE: inc = (o.sign && (round || sticky)); break; case MPF_ROUND_TOWARD_ZERO: inc = false; break; default: UNREACHABLE(); } - if (inc) { - TRACE("mpf_dbg", tout << "Rounding increment -> significand +1" << std::endl;); + TRACE("mpf_dbg", tout << "Rounding increment -> significand +" << (int)inc << std::endl;); + if (inc) m_mpz_manager.inc(o.significand); - } - else - TRACE("mpf_dbg", tout << "Rounding increment -> significand +0" << std::endl;); TRACE("mpf_dbg", tout << "Rounded significand: " << to_string(o) << std::endl;); - bool SIGovf = false; - // Post normalization (post) + const mpz & p_sig = m_powers2(o.sbits); if (m_mpz_manager.ge(o.significand, p_sig)) { m_mpz_manager.machine_div2k(o.significand, 1); o.exponent++; } - if (o.exponent > e_max_norm) - SIGovf = true; - + bool SIGovf = o.exponent > e_max; TRACE("mpf_dbg", tout << "Post-normalized: " << to_string(o) << std::endl;); - TRACE("mpf_dbg", tout << "SIGovf = " << SIGovf << std::endl;); // Exponent rounding (exprd) - bool o_has_max_exp = (o.exponent > e_max_norm); + bool o_has_max_exp = (o.exponent > e_max); bool OVF2 = SIGovf && o_has_max_exp; TRACE("mpf_dbg", tout << "OVF2 = " << OVF2 << std::endl;); TRACE("mpf_dbg", tout << "o_has_max_exp = " << o_has_max_exp << std::endl;); - if (!OVFen && OVF2) + if (OVF2) mk_round_inf(rm, o); else { const mpz & p = m_powers2(o.sbits-1); - TRACE("mpf_dbg", tout << "P: " << m_mpz_manager.to_string(p_m1) << std::endl;); if (m_mpz_manager.ge(o.significand, p)) { TRACE("mpf_dbg", tout << "NORMAL: " << m_mpz_manager.to_string(o.significand) << std::endl;); - m_mpz_manager.sub(o.significand, p, o.significand); + m_mpz_manager.sub(o.significand, p, o.significand); // Strips the hidden bit. } else { TRACE("mpf_dbg", tout << "DENORMAL: " << m_mpz_manager.to_string(o.significand) << std::endl;); @@ -2059,7 +2074,8 @@ void mpf_manager::round(mpf_rounding_mode rm, mpf & o) { } } - TRACE("mpf_dbg", tout << "ROUNDED = " << to_string(o) << std::endl;); + TRACE("mpf_dbg", tout << "ROUNDED = " << to_string(o) << std::endl; + tout << to_string_binary(o, -1, 0) << " (hidden bit, unbiased exp)." << std::endl;); } void mpf_manager::round_sqrt(mpf_rounding_mode rm, mpf & o) { diff --git a/src/util/mpf.h b/src/util/mpf.h index 31523c3ed..72c03f447 100644 --- a/src/util/mpf.h +++ b/src/util/mpf.h @@ -285,8 +285,9 @@ protected: }; std::string to_string_raw(mpf const & a); - std::string to_string_hexfloat(mpf const & a); + std::string to_string_hexfloat(mpf const & a); std::string to_string_hexfloat(bool sgn, mpf_exp_t exp, scoped_mpz const & sig, unsigned ebits, unsigned sbits, unsigned rbits); + std::string to_string_binary(mpf const & x, unsigned upper_extra, unsigned lower_extra); public: powers2 m_powers2; }; From 64233034cc0a415fc7b1b6d63110857b2c364d78 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 28 Jul 2017 08:26:52 -0700 Subject: [PATCH 020/488] fix #1173 Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.cpp | 48 +++++++++++++++++++++++++++++++++++ src/ast/arith_decl_plugin.h | 1 + 2 files changed, 49 insertions(+) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 1c01496cf..66580a1dd 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -403,9 +403,57 @@ inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) { } } +void arith_decl_plugin::check_arity(unsigned arity, unsigned expected_arity) { + if (arity != expected_arity) { + m_manager->raise_exception("invalid number of arguments passed to function"); + } +} + inline decl_kind arith_decl_plugin::fix_kind(decl_kind k, unsigned arity) { if (k == OP_SUB && arity == 1) { return OP_UMINUS; + } + switch (k) { + case OP_LE: check_arity(arity, 2); break; + case OP_GE: check_arity(arity, 2); break; + case OP_LT: check_arity(arity, 2); break; + case OP_GT: check_arity(arity, 2); break; + case OP_ADD: break; + case OP_SUB: break; + case OP_UMINUS: check_arity(arity, 1); break; + case OP_MUL: break; + case OP_DIV: check_arity(arity, 2); break; + case OP_IDIV: check_arity(arity, 2); break; + case OP_REM: check_arity(arity, 2); break; + case OP_MOD: check_arity(arity, 2); break; + case OP_TO_REAL: check_arity(arity, 1); break; + case OP_TO_INT: check_arity(arity, 1); break; + case OP_IS_INT: check_arity(arity, 1); break; + case OP_POWER: check_arity(arity, 2); break; + case OP_ABS: check_arity(arity, 1); break; + case OP_SIN: check_arity(arity, 1); break; + case OP_COS: check_arity(arity, 1); break; + case OP_TAN: check_arity(arity, 1); break; + case OP_ASIN: check_arity(arity, 1); break; + case OP_ACOS: check_arity(arity, 1); break; + case OP_ATAN: check_arity(arity, 1); break; + case OP_SINH: check_arity(arity, 1); break; + case OP_COSH: check_arity(arity, 1); break; + case OP_TANH: check_arity(arity, 1); break; + case OP_ASINH: check_arity(arity, 1); break; + case OP_ACOSH: check_arity(arity, 1); break; + case OP_ATANH: check_arity(arity, 1); break; + case OP_PI: break; + case OP_E: break; + case OP_0_PW_0_INT: break; + case OP_0_PW_0_REAL: break; + case OP_NEG_ROOT: break; + case OP_DIV_0: check_arity(arity, 1); break; + case OP_IDIV_0: check_arity(arity, 1); break; + case OP_MOD_0: check_arity(arity, 1); break; + case OP_U_ASIN: break; + case OP_U_ACOS: break; + } return k; } diff --git a/src/ast/arith_decl_plugin.h b/src/ast/arith_decl_plugin.h index 6d6da9ed5..43bf4be65 100644 --- a/src/ast/arith_decl_plugin.h +++ b/src/ast/arith_decl_plugin.h @@ -157,6 +157,7 @@ protected: func_decl * mk_func_decl(decl_kind k, bool is_real); virtual void set_manager(ast_manager * m, family_id id); decl_kind fix_kind(decl_kind k, unsigned arity); + void check_arity(unsigned arity, unsigned expected_arity); func_decl * mk_num_decl(unsigned num_parameters, parameter const * parameters, unsigned arity); public: From e9b9a29339622e94d5542a53c377f7952ae1ea33 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 28 Jul 2017 08:44:19 -0700 Subject: [PATCH 021/488] revert first fix for #1173, replace by handling single arity chainables Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.cpp | 8 ++++---- src/ast/ast.cpp | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 66580a1dd..2eb0f4d90 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -414,10 +414,10 @@ inline decl_kind arith_decl_plugin::fix_kind(decl_kind k, unsigned arity) { return OP_UMINUS; } switch (k) { - case OP_LE: check_arity(arity, 2); break; - case OP_GE: check_arity(arity, 2); break; - case OP_LT: check_arity(arity, 2); break; - case OP_GT: check_arity(arity, 2); break; + case OP_LE: break; + case OP_GE: break; + case OP_LT: break; + case OP_GT: break; case OP_ADD: break; case OP_SUB: break; case OP_UMINUS: check_arity(arity, 1); break; diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 5f2de5170..1c3be5e68 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -2178,7 +2178,10 @@ app * ast_manager::mk_app(func_decl * decl, unsigned num_args, expr * const * ar throw ast_exception(buffer.str().c_str()); } app * r = 0; - if (num_args > 2 && !decl->is_flat_associative()) { + if (num_args == 1 && decl->is_chainable() && decl->get_arity() == 2) { + r = mk_true(); + } + else if (num_args > 2 && !decl->is_flat_associative()) { if (decl->is_right_associative()) { unsigned j = num_args - 1; r = mk_app_core(decl, args[j-1], args[j]); From 31d6abcfe8d2551198b0794e67642659f6d4b90b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 28 Jul 2017 08:55:41 -0700 Subject: [PATCH 022/488] remove arity check Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.cpp | 42 ----------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 2eb0f4d90..12d1a4307 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -412,48 +412,6 @@ void arith_decl_plugin::check_arity(unsigned arity, unsigned expected_arity) { inline decl_kind arith_decl_plugin::fix_kind(decl_kind k, unsigned arity) { if (k == OP_SUB && arity == 1) { return OP_UMINUS; - } - switch (k) { - case OP_LE: break; - case OP_GE: break; - case OP_LT: break; - case OP_GT: break; - case OP_ADD: break; - case OP_SUB: break; - case OP_UMINUS: check_arity(arity, 1); break; - case OP_MUL: break; - case OP_DIV: check_arity(arity, 2); break; - case OP_IDIV: check_arity(arity, 2); break; - case OP_REM: check_arity(arity, 2); break; - case OP_MOD: check_arity(arity, 2); break; - case OP_TO_REAL: check_arity(arity, 1); break; - case OP_TO_INT: check_arity(arity, 1); break; - case OP_IS_INT: check_arity(arity, 1); break; - case OP_POWER: check_arity(arity, 2); break; - case OP_ABS: check_arity(arity, 1); break; - case OP_SIN: check_arity(arity, 1); break; - case OP_COS: check_arity(arity, 1); break; - case OP_TAN: check_arity(arity, 1); break; - case OP_ASIN: check_arity(arity, 1); break; - case OP_ACOS: check_arity(arity, 1); break; - case OP_ATAN: check_arity(arity, 1); break; - case OP_SINH: check_arity(arity, 1); break; - case OP_COSH: check_arity(arity, 1); break; - case OP_TANH: check_arity(arity, 1); break; - case OP_ASINH: check_arity(arity, 1); break; - case OP_ACOSH: check_arity(arity, 1); break; - case OP_ATANH: check_arity(arity, 1); break; - case OP_PI: break; - case OP_E: break; - case OP_0_PW_0_INT: break; - case OP_0_PW_0_REAL: break; - case OP_NEG_ROOT: break; - case OP_DIV_0: check_arity(arity, 1); break; - case OP_IDIV_0: check_arity(arity, 1); break; - case OP_MOD_0: check_arity(arity, 1); break; - case OP_U_ASIN: break; - case OP_U_ACOS: break; - } return k; } From 78467077f64950ba97472913da56ec1212ac75d2 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Fri, 28 Jul 2017 12:18:12 -0400 Subject: [PATCH 023/488] fixing a build error --- src/cmd_context/extra_cmds/dbg_cmds.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cmd_context/extra_cmds/dbg_cmds.cpp b/src/cmd_context/extra_cmds/dbg_cmds.cpp index 7ee1c0aeb..16815ccb6 100644 --- a/src/cmd_context/extra_cmds/dbg_cmds.cpp +++ b/src/cmd_context/extra_cmds/dbg_cmds.cpp @@ -106,7 +106,7 @@ class subst_cmd : public cmd { public: subst_cmd():cmd("dbg-subst") {} virtual char const * get_usage() const { return " (*) "; } - virtual char const * get_descr() const { return "substitute the free variables in the AST referenced by using the ASTs referenced by *"; } + virtual char const * get_descr(cmd_context & ctx) const { return "substitute the free variables in the AST referenced by using the ASTs referenced by *"; } virtual unsigned get_arity() const { return 3; } virtual void prepare(cmd_context & ctx) { m_idx = 0; m_source = 0; } virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { @@ -285,7 +285,7 @@ protected: public: instantiate_cmd_core(char const * name):cmd(name) {} virtual char const * get_usage() const { return " (*)"; } - virtual char const * get_descr() const { return "instantiate the quantifier using the given expressions."; } + virtual char const * get_descr(cmd_context & ctx) const { return "instantiate the quantifier using the given expressions."; } virtual unsigned get_arity() const { return 2; } virtual void prepare(cmd_context & ctx) { m_q = 0; m_args.reset(); } @@ -333,7 +333,7 @@ class instantiate_nested_cmd : public instantiate_cmd_core { public: instantiate_nested_cmd():instantiate_cmd_core("dbg-instantiate-nested") {} - virtual char const * get_descr() const { return "instantiate the quantifier nested in the outermost quantifier, this command is used to test the instantiation procedure with quantifiers that contain free variables."; } + virtual char const * get_descr(cmd_context & ctx) const { return "instantiate the quantifier nested in the outermost quantifier, this command is used to test the instantiation procedure with quantifiers that contain free variables."; } virtual void set_next_arg(cmd_context & ctx, expr * s) { instantiate_cmd_core::set_next_arg(ctx, s); From 45e31b0db3ce1437a2901e17e471ee2e8d6258ce Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 28 Jul 2017 10:17:46 -0700 Subject: [PATCH 024/488] add dummy initialization to unused variables to avoid compiler warnings Signed-off-by: Nikolaj Bjorner --- scripts/update_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 3c1e1cc07..8cc80e50e 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -768,11 +768,11 @@ def mk_log_macro(file, name, params): cap = param_array_capacity_pos(p) if cap not in auxs: auxs.add(cap) - file.write("unsigned _Z3_UNUSED Z3ARG%s; " % cap) + file.write("unsigned _Z3_UNUSED Z3ARG%s = 0; " % cap) sz = param_array_size_pos(p) if sz not in auxs: auxs.add(sz) - file.write("unsigned * _Z3_UNUSED Z3ARG%s; " % sz) + file.write("unsigned * _Z3_UNUSED Z3ARG%s = 0; " % sz) file.write("%s _Z3_UNUSED Z3ARG%s; " % (param2str(p), i)) i = i + 1 file.write("if (_LOG_CTX.enabled()) { log_%s(" % name) From 0610392a054f3e3ebed3a9a073c26b1ef961e406 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Jul 2017 20:16:13 +0100 Subject: [PATCH 025/488] Bugfix for fp.fma. Fixes #872. --- src/ast/fpa/fpa2bv_converter.cpp | 38 ++++++++------ src/util/mpf.cpp | 85 +++++++++++++++++--------------- src/util/mpf.h | 13 +++++ 3 files changed, 79 insertions(+), 57 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 0e83d7fea..979fed78e 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1476,6 +1476,10 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, mk_ite(c71, zero_cond, z, v7); // else comes the fused multiplication. + expr_ref one_1(m), zero_1(m); + one_1 = m_bv_util.mk_numeral(1, 1); + zero_1 = m_bv_util.mk_numeral(0, 1); + unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); @@ -1585,27 +1589,20 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_add_exp_delta_capped", exp_delta); // Alignment shift with sticky bit computation. - expr_ref shifted_big(m), shifted_f_sig(m), sticky_raw(m); + expr_ref shifted_big(m), shifted_f_sig(m); + expr_ref alignment_sticky_raw(m), alignment_sticky(m); shifted_big = m_bv_util.mk_bv_lshr( m_bv_util.mk_concat(f_sig, m_bv_util.mk_numeral(0, sbits)), m_bv_util.mk_zero_extend((3*sbits)-(ebits+2), exp_delta)); shifted_f_sig = m_bv_util.mk_extract(3*sbits-1, sbits, shifted_big); - sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); + alignment_sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); + alignment_sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, alignment_sticky_raw.get()); dbg_decouple("fpa2bv_fma_shifted_f_sig", shifted_f_sig); + dbg_decouple("fpa2bv_fma_f_sig_alignment_stickyw", alignment_sticky); + SASSERT(is_well_sorted(m, alignment_sticky)); SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2 * sbits); SASSERT(is_well_sorted(m, shifted_f_sig)); - expr_ref sticky(m); - sticky = m_bv_util.mk_zero_extend(2*sbits-1, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_raw.get())); - SASSERT(is_well_sorted(m, sticky)); - dbg_decouple("fpa2bv_fma_f_sig_sticky_raw", sticky_raw); - dbg_decouple("fpa2bv_fma_f_sig_sticky", sticky); - - expr * or_args[2] = { shifted_f_sig, sticky }; - shifted_f_sig = m_bv_util.mk_bv_or(2, or_args); - SASSERT(is_well_sorted(m, shifted_f_sig)); - dbg_decouple("fpa2bv_fma_f_sig_or_sticky", shifted_f_sig); - // Significant addition. // Two extra bits for the sign and for catching overflows. e_sig = m_bv_util.mk_zero_extend(2, e_sig); @@ -1621,9 +1618,19 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_add_e_sig", e_sig); dbg_decouple("fpa2bv_fma_add_shifted_f_sig", shifted_f_sig); - expr_ref sum(m), e_plus_f(m), e_minus_f(m); + expr_ref sum(m), e_plus_f(m), e_minus_f(m), sticky_wide(m); + sticky_wide = m_bv_util.mk_zero_extend(2*sbits+1, alignment_sticky); e_plus_f = m_bv_util.mk_bv_add(e_sig, shifted_f_sig); + e_plus_f = m.mk_ite(m.mk_eq(m_bv_util.mk_extract(0, 0, e_plus_f), zero_1), + m_bv_util.mk_bv_add(e_plus_f, sticky_wide), + e_plus_f); e_minus_f = m_bv_util.mk_bv_sub(e_sig, shifted_f_sig); + e_minus_f = m.mk_ite(m.mk_eq(m_bv_util.mk_extract(0, 0, e_minus_f), zero_1), + m_bv_util.mk_bv_sub(e_minus_f, sticky_wide), + e_minus_f); + SASSERT(is_well_sorted(m, shifted_f_sig)); + dbg_decouple("fpa2bv_fma_f_sig_or_sticky", shifted_f_sig); + m_simp.mk_ite(eq_sgn, e_plus_f, e_minus_f, sum); SASSERT(m_bv_util.get_bv_size(sum) == 2*sbits + 2); SASSERT(is_well_sorted(m, sum)); @@ -1635,8 +1642,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_add_sign_bv", sign_bv); dbg_decouple("fpa2bv_fma_add_n_sum", n_sum); - expr_ref res_sig_eq(m), sig_abs(m), one_1(m); - one_1 = m_bv_util.mk_numeral(1, 1); + expr_ref res_sig_eq(m), sig_abs(m); m_simp.mk_eq(sign_bv, one_1, res_sig_eq); m_simp.mk_ite(res_sig_eq, n_sum, sum, sig_abs); dbg_decouple("fpa2bv_fma_add_sig_abs", sig_abs); diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 36d9e49f1..245186f52 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -556,8 +556,6 @@ void mpf_manager::add_sub(mpf_rounding_mode rm, mpf const & x, mpf const & y, mp SASSERT(exp_delta <= INT_MAX); scoped_mpz sticky_rem(m_mpz_manager); m_mpz_manager.machine_div_rem(b.significand(), m_powers2((int)exp_delta), b.significand(), sticky_rem); - if (!m_mpz_manager.is_zero(sticky_rem) && m_mpz_manager.is_even(b.significand())) - m_mpz_manager.inc(b.significand()); TRACE("mpf_dbg", tout << "A' = " << m_mpz_manager.to_string(a.significand()) << std::endl;); TRACE("mpf_dbg", tout << "B' = " << m_mpz_manager.to_string(b.significand()) << std::endl;); @@ -566,10 +564,14 @@ void mpf_manager::add_sub(mpf_rounding_mode rm, mpf const & x, mpf const & y, mp if (sgn(a) != sgn(b)) { TRACE("mpf_dbg", tout << "SUBTRACTING" << std::endl;); m_mpz_manager.sub(a.significand(), b.significand(), o.significand); + if (!sticky_rem.is_zero() && m_mpz_manager.is_even(o.significand)) + m_mpz_manager.dec(o.significand); } else { TRACE("mpf_dbg", tout << "ADDING" << std::endl;); m_mpz_manager.add(a.significand(), b.significand(), o.significand); + if (!sticky_rem.is_zero() && m_mpz_manager.is_even(o.significand)) + m_mpz_manager.inc(o.significand); } TRACE("mpf_dbg", tout << "sum[-2:sbits+2] = " << m_mpz_manager.to_string(o.significand) << std::endl;); @@ -805,7 +807,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co o.ebits = x.ebits; o.sbits = x.sbits; - scoped_mpf mul_res(*this, x.ebits+2, 2*x.sbits-1); + scoped_mpf mr(*this); scoped_mpf a(*this, x.ebits, x.sbits), b(*this, x.ebits, x.sbits), c(*this, x.ebits, x.sbits); set(a, x); set(b, y); @@ -828,20 +830,18 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co SASSERT(m_mpz_manager.ge(b.significand(), m_powers2(x.sbits-1))); // A/B in _1.[sbits-1]. - mul_res.get().sign = (a.sign() != b.sign()); - mul_res.get().exponent = a.exponent() + b.exponent(); - m_mpz_manager.mul(a.significand(), b.significand(), mul_res.significand()); + mr.set(x.ebits+2, 2*x.sbits-1, a.sign() != b.sign(), a.exponent() + b.exponent()); + m_mpz_manager.mul(a.significand(), b.significand(), mr.significand()); - TRACE("mpf_dbg", tout << "M = " << to_string(mul_res) << std::endl; - tout << "M = " << to_string_binary(mul_res, 1, 0) << std::endl;); + TRACE("mpf_dbg", tout << "M = " << to_string(mr) << std::endl; + tout << "M = " << to_string_binary(mr, 1, 0) << std::endl;); // mul_res is [-1][0].[2*sbits - 2], i.e., >= 2^(2*sbits-2) and < 2^(2*sbits). - SASSERT(m_mpz_manager.lt(mul_res.significand(), m_powers2(2*x.sbits))); - SASSERT(m_mpz_manager.ge(mul_res.significand(), m_powers2(2*x.sbits - 2))); + SASSERT(m_mpz_manager.lt(mr.significand(), m_powers2(2*x.sbits))); + SASSERT(m_mpz_manager.ge(mr.significand(), m_powers2(2*x.sbits - 2))); // Introduce extra bits into c in _[0].[sbits-1] s.t. c in _[0].[2*sbits-2] - c.get().ebits = x.ebits + 2; - c.get().sbits = 2 * x.sbits - 1; + c.set(x.ebits + 2, 2 * x.sbits - 1, c.sign(), c.exponent(), c.significand()); m_mpz_manager.mul2k(c.significand(), x.sbits - 1); TRACE("mpf_dbg", tout << "C_= " << to_string(c) << std::endl; @@ -851,67 +851,67 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co SASSERT(m_mpz_manager.is_zero(c.significand()) || m_mpz_manager.ge(c.significand(), m_powers2(2*x.sbits - 2))); - if (exp(c) > exp(mul_res)) { + if (exp(c) > exp(mr)) { TRACE("mpf_dbg", tout << "Swap!" << std::endl;); - mul_res.swap(c); + mr.swap(c); } - mpf_exp_t exp_delta_w = exp(mul_res) - exp(c); - - SASSERT(exp(mul_res) >= exp(c) && exp_delta_w >= 0); + // Alignment shift with sticky bit computation. + mpf_exp_t exp_delta_w = exp(mr) - exp(c); + SASSERT(exp(mr) >= exp(c) && exp_delta_w >= 0); if (exp_delta_w > 2 * x.sbits) exp_delta_w = 2 * x.sbits; - unsigned exp_delta = (unsigned)exp_delta_w; - TRACE("mpf_dbg", tout << "exp_delta = " << exp_delta << std::endl;); - // Alignment shift with sticky bit computation. + unsigned exp_delta = (unsigned)exp_delta_w; + scoped_mpz sticky_rem(m_mpz_manager); m_mpz_manager.machine_div_rem(c.significand(), m_powers2(exp_delta), c.significand(), sticky_rem); - TRACE("mpf_dbg", tout << "alignment shift -> sig = " << m_mpz_manager.to_string(c.significand()) << + TRACE("mpf_dbg", tout << "alignment shift by delta=" << exp_delta << " -> sig = " << m_mpz_manager.to_string(c.significand()) << " sticky_rem = " << m_mpz_manager.to_string(sticky_rem) << std::endl;); - if (!m_mpz_manager.is_zero(sticky_rem) && m_mpz_manager.is_even(c.significand())) - m_mpz_manager.inc(c.significand()); + bool alignment_sticky = !m_mpz_manager.is_zero(sticky_rem); - TRACE("mpf_dbg", tout << "M'= " << m_mpz_manager.to_string(mul_res.significand()) << std::endl; - tout << "M'= " << to_string_binary(mul_res, 1, 0) << std::endl; ); + TRACE("mpf_dbg", tout << "M'= " << m_mpz_manager.to_string(mr.significand()) << std::endl; + tout << "M'= " << to_string_binary(mr, 1, 0) << std::endl; ); TRACE("mpf_dbg", tout << "C'= " << m_mpz_manager.to_string(c.significand()) << std::endl; tout << "C'= " << to_string_binary(c, 1, 0) << std::endl; ); - scoped_mpf res(c); - - res.get().sign = mul_res.sign(); - res.get().exponent = mul_res.exponent(); - // Significand addition + scoped_mpf res(mr); - if (sgn(mul_res) != sgn(c)) { + if (sgn(mr) != sgn(c)) { TRACE("mpf_dbg", tout << "SUBTRACTING" << std::endl;); - m_mpz_manager.sub(mul_res.significand(), c.significand(), res.significand()); + m_mpz_manager.sub(mr.significand(), c.significand(), res.significand()); + + if (alignment_sticky && m_mpz_manager.is_even(res.significand())) + m_mpz_manager.dec(res.get().significand); if (m_mpz_manager.is_neg(res.significand())) { m_mpz_manager.abs(res.significand()); - res.get().sign |= !mul_res.sign() && c.sign(); + res.get().sign |= c.sign(); } } else { TRACE("mpf_dbg", tout << "ADDING" << std::endl;); - m_mpz_manager.add(mul_res.significand(), c.significand(), res.significand()); + m_mpz_manager.add(mr.significand(), c.significand(), res.significand()); + + if (alignment_sticky && m_mpz_manager.is_even(res.significand())) + m_mpz_manager.inc(res.get().significand); } TRACE("mpf_dbg", tout << "S'= " << m_mpz_manager.to_string(res.significand()) << std::endl; tout << "S'= " << to_string_binary(res, 1, 0) << std::endl; ); + bool renorm_sticky = false; + SASSERT(m_mpz_manager.lt(res.significand(), m_powers2(2 * x.sbits + 1))); if (m_mpz_manager.ge(res.significand(), m_powers2(2 * x.sbits))) { SASSERT(exp(res) < mk_max_exp(x.ebits)); // NYI. res.get().exponent++; - bool sticky = !m_mpz_manager.is_even(res.significand()); + renorm_sticky = !m_mpz_manager.is_even(res.significand()); m_mpz_manager.machine_div2k(res.significand(), 1); - if (sticky && m_mpz_manager.is_even(res.significand())) - m_mpz_manager.inc(res.significand()); TRACE("mpf_dbg", tout << "Add/Sub overflew into 4.xxx!" << std::endl; tout << "S*= " << to_string_binary(res, 2, 0) << std::endl;); } @@ -919,17 +919,18 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co set(o, x.ebits, x.sbits, res.sign(), res.exponent(), mpz(0)); if (x.sbits >= 4) { - m_mpz_manager.set(sticky_rem, 0); m_mpz_manager.machine_div_rem(res.significand(), m_powers2(x.sbits - 4), o.significand, sticky_rem); - if (!m_mpz_manager.is_zero(sticky_rem) && m_mpz_manager.is_even(o.significand)) - m_mpz_manager.inc(o.significand); + renorm_sticky |= !m_mpz_manager.is_zero(sticky_rem); } else { m_mpz_manager.mul2k(res.significand(), 4 - x.sbits, o.significand); } + if (renorm_sticky && m_mpz_manager.is_even(o.significand)) + m_mpz_manager.inc(o.significand); + TRACE("mpf_dbg", tout << "sum[-1:sbits+2] = " << m_mpz_manager.to_string(o.significand) << std::endl; - tout << "R = " << to_string_binary(o, 2, 3) << std::endl;); + tout << "R = " << to_string_binary(o, 1, 3) << std::endl;); if (m_mpz_manager.is_zero(o.significand)) mk_zero(x.ebits, x.sbits, rm == MPF_ROUND_TOWARD_NEGATIVE, o); @@ -1634,6 +1635,8 @@ std::string mpf_manager::to_string_binary(mpf const & x, unsigned upper_extra, u "#b" + std::string(x.sbits - 1, '0') + " " + "(" + (sgn(x) ? "-" : "+") + "zero)"; else { + SASSERT(m_mpz_manager.is_nonneg(sig(x))); + res = std::string("") + "#b" + (sgn(x) ? "1" : "0") + " "; scoped_mpz tmp(m_mpz_manager); diff --git a/src/util/mpf.h b/src/util/mpf.h index 72c03f447..07755e314 100644 --- a/src/util/mpf.h +++ b/src/util/mpf.h @@ -300,6 +300,19 @@ class scoped_mpf : public _scoped_numeral { mpf_exp_t exponent() const { return get().exponent; } unsigned sbits() const { return get().sbits; } void set(unsigned ebits, unsigned sbits) { get().set(ebits, sbits); } + void set(unsigned ebits, unsigned sbits, bool sign, mpf_exp_t exp, mpz & significand) { + get().set(ebits, sbits); + get().exponent = exp; + get().sign = sign; + if (&get().significand != &significand) + m().mpz_manager().set(get().significand, significand); + } + void set(unsigned ebits, unsigned sbits, bool sign, mpf_exp_t exp) { + get().set(ebits, sbits); + get().exponent = exp; + get().sign = sign; + m().mpz_manager().set(get().significand, 0); + } public: scoped_mpf(mpf_manager & m):_scoped_numeral(m) {} scoped_mpf(scoped_mpf const & n):_scoped_numeral(n) {} From e677030b7469933a14c02376a7935a307a919482 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Jul 2017 21:39:44 +0100 Subject: [PATCH 026/488] Fixed sign bug in mpf fp.fma. Relates to #872. --- src/util/mpf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 245186f52..be19cbb9b 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -841,7 +841,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co SASSERT(m_mpz_manager.ge(mr.significand(), m_powers2(2*x.sbits - 2))); // Introduce extra bits into c in _[0].[sbits-1] s.t. c in _[0].[2*sbits-2] - c.set(x.ebits + 2, 2 * x.sbits - 1, c.sign(), c.exponent(), c.significand()); + c.set(x.ebits+2, 2*x.sbits-1, c.sign(), c.exponent(), c.significand()); m_mpz_manager.mul2k(c.significand(), x.sbits - 1); TRACE("mpf_dbg", tout << "C_= " << to_string(c) << std::endl; @@ -888,7 +888,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co if (m_mpz_manager.is_neg(res.significand())) { m_mpz_manager.abs(res.significand()); - res.get().sign |= c.sign(); + res.get().sign = !res.sign(); } } else { From 175f042db88bcbd8f2ce21316fb5c321355d601a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Jul 2017 23:01:01 +0100 Subject: [PATCH 027/488] Fixed renormalization in fp.fma. Relates to #872. --- src/ast/fpa/fpa2bv_converter.cpp | 17 ++++++++++++++++- src/util/mpf.cpp | 11 +++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 979fed78e..0c9a1c866 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1672,6 +1672,22 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, extra_is_zero = m.mk_eq(extra, m_bv_util.mk_numeral(0, 2)); dbg_decouple("fpa2bv_fma_extra", extra); + res_exp = m.mk_ite(extra_is_zero, e_exp, m_bv_util.mk_bv_add(e_exp, m_bv_util.mk_numeral(1, ebits + 2))); + + // Renormalize + expr_ref zero_e2(m), min_exp(m), sig_lz(m), max_exp_delta(m), sig_lz_capped(m), renorm_delta(m); + zero_e2 = m_bv_util.mk_numeral(0, ebits + 2); + mk_min_exp(ebits+2, min_exp); + mk_leading_zeros(sig_abs, ebits+2, sig_lz); + sig_lz = m_bv_util.mk_bv_sub(sig_lz, m_bv_util.mk_numeral(2, ebits+2)); + max_exp_delta = m_bv_util.mk_bv_sub(res_exp, min_exp); + sig_lz_capped = m.mk_ite(m_bv_util.mk_sle(sig_lz, max_exp_delta), sig_lz, max_exp_delta); + renorm_delta = m.mk_ite(m_bv_util.mk_sle(zero_e2, sig_lz_capped), sig_lz_capped, zero_e2); + res_exp = m_bv_util.mk_bv_sub(res_exp, renorm_delta); + sig_abs = m_bv_util.mk_bv_shl(sig_abs, m_bv_util.mk_zero_extend(2*sbits-ebits, renorm_delta)); + dbg_decouple("fpa2bv_fma_sig_lz", sig_lz); + dbg_decouple("fpa2bv_fma_renorm_delta", renorm_delta); + unsigned too_short = 0; if (sbits < 5) { too_short = 6 - sbits + 1; @@ -1705,7 +1721,6 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(res_sig_2) == sbits + 4); res_sig = m.mk_ite(extra_is_zero, res_sig_1, res_sig_2); - res_exp = m.mk_ite(extra_is_zero, e_exp, m_bv_util.mk_bv_add(e_exp, m_bv_util.mk_numeral(1, ebits + 2))); dbg_decouple("fpa2bv_fma_res_sig", res_sig); dbg_decouple("fpa2bv_fma_res_exp", res_exp); diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index be19cbb9b..a2bf12a30 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -902,6 +902,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co TRACE("mpf_dbg", tout << "S'= " << m_mpz_manager.to_string(res.significand()) << std::endl; tout << "S'= " << to_string_binary(res, 1, 0) << std::endl; ); + // Renormalize bool renorm_sticky = false; SASSERT(m_mpz_manager.lt(res.significand(), m_powers2(2 * x.sbits + 1))); @@ -916,6 +917,16 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co tout << "S*= " << to_string_binary(res, 2, 0) << std::endl;); } + mpf_exp_t min_exp = mk_min_exp(x.ebits); + unsigned sig_width = m_mpz_manager.prev_power_of_two(res.get().significand) + 1; + mpf_exp_t sig_lz = 2 * x.sbits - sig_width; // want << lz + mpf_exp_t max_exp_delta = res.exponent() - min_exp; + unsigned renorm_delta = (unsigned) std::max((mpf_exp_t)0, std::min(sig_lz, max_exp_delta)); + res.get().exponent -= renorm_delta; + m_mpz_manager.mul2k(res.significand(), renorm_delta); + + TRACE("mpf_dbg", tout << "R*= " << to_string_binary(res, 2, 0) << " (renormalized, delta=" << renorm_delta << ")" << std::endl;); + set(o, x.ebits, x.sbits, res.sign(), res.exponent(), mpz(0)); if (x.sbits >= 4) { From 8bd0407adfc00b8f1b1b3f8b79319285d39df824 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 09:13:50 -0700 Subject: [PATCH 028/488] fix #1177 Signed-off-by: Nikolaj Bjorner --- src/smt/smt_context.cpp | 11 ++++++----- src/smt/smt_justification.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index b5789a597..1b428520e 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -2406,7 +2406,7 @@ namespace smt { if (m_manager.has_trace_stream()) m_manager.trace_stream() << "[pop] " << num_scopes << " " << m_scope_lvl << "\n"; - TRACE("context", tout << "backtracking: " << num_scopes << "\n";); + TRACE("context", tout << "backtracking: " << num_scopes << " from " << m_scope_lvl << "\n";); TRACE("pop_scope_detail", display(tout);); SASSERT(num_scopes > 0); SASSERT(num_scopes <= m_scope_lvl); @@ -2901,10 +2901,10 @@ namespace smt { } push_scope(); m_base_scopes.push_back(base_scope()); - base_scope & bs = m_base_scopes.back(); - bs.m_lemmas_lim = m_lemmas.size(); - bs.m_inconsistent = inconsistent(); - bs.m_simp_qhead_lim = m_simp_qhead; + base_scope & bs = m_base_scopes.back(); + bs.m_lemmas_lim = m_lemmas.size(); + bs.m_inconsistent = inconsistent(); + bs.m_simp_qhead_lim = m_simp_qhead; m_base_lvl++; m_search_lvl++; // Not really necessary. But, it is useful to enforce the invariant m_search_lvl >= m_base_lvl SASSERT(m_base_lvl <= m_scope_lvl); @@ -2912,6 +2912,7 @@ namespace smt { void context::pop(unsigned num_scopes) { SASSERT (num_scopes > 0); + if (num_scopes > m_scope_lvl) return; pop_to_base_lvl(); pop_scope(num_scopes); } diff --git a/src/smt/smt_justification.h b/src/smt/smt_justification.h index ea969d1db..5bfa8bbf0 100644 --- a/src/smt/smt_justification.h +++ b/src/smt/smt_justification.h @@ -148,6 +148,7 @@ namespace smt { m_node1(n1), m_node2(n2), m_js(js) { + SASSERT(n1 != n2); } virtual void get_antecedents(conflict_resolution & cr); From ceca9fbef0a35e3b554a267f82f2cb105ec25e6f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 09:23:55 -0700 Subject: [PATCH 029/488] fixes #1176 Signed-off-by: Nikolaj Bjorner --- src/smt/smt_justification.h | 1 - src/smt/smt_model_finder.cpp | 15 +++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/smt/smt_justification.h b/src/smt/smt_justification.h index 5bfa8bbf0..ea969d1db 100644 --- a/src/smt/smt_justification.h +++ b/src/smt/smt_justification.h @@ -148,7 +148,6 @@ namespace smt { m_node1(n1), m_node2(n2), m_js(js) { - SASSERT(n1 != n2); } virtual void get_antecedents(conflict_resolution & cr); diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index ff84992e1..eb113b484 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -760,7 +760,7 @@ namespace smt { ptr_vector const & exceptions = n->get_exceptions(); ptr_vector const & avoid_set = n->get_avoid_set(); obj_map const & elems = s->get_elems(); - SASSERT(!elems.empty()); + if (elems.empty()) return; if (!exceptions.empty() || !avoid_set.empty()) { ptr_buffer ex_vals; collect_exceptions_values(n, ex_vals); @@ -927,15 +927,14 @@ namespace smt { ptr_buffer values; get_instantiation_set_values(n, values); sort * s = n->get_sort(); - expr * else_val = eval(n->get_else(), true); - func_decl * p = m_manager.mk_fresh_func_decl(1, &s, s); + func_decl * p = m_manager.mk_fresh_func_decl(1, &s, s); func_interp * pi = alloc(func_interp, m_manager, 1); - pi->set_else(else_val); m_model->register_aux_decl(p, pi); - ptr_buffer::const_iterator it = values.begin(); - ptr_buffer::const_iterator end = values.end(); - for (; it != end; ++it) { - expr * v = *it; + if (n->get_else()) { + expr * else_val = eval(n->get_else(), true); + pi->set_else(else_val); + } + for (expr * v : values) { pi->insert_new_entry(&v, v); } n->set_proj(p); From 74890ca1c8fe625e6a45d4e45fc6e7a6940fad58 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 09:37:25 -0700 Subject: [PATCH 030/488] fixes #1180 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/eval_cmd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cmd_context/eval_cmd.cpp b/src/cmd_context/eval_cmd.cpp index 86078a13c..3b00179c6 100644 --- a/src/cmd_context/eval_cmd.cpp +++ b/src/cmd_context/eval_cmd.cpp @@ -58,6 +58,8 @@ public: virtual void execute(cmd_context & ctx) { if (!ctx.is_model_available()) throw cmd_exception("model is not available"); + if (!m_target) + throw cmd_exception("no arguments passed to eval"); model_ref md; unsigned index = m_params.get_uint("model_index", 0); check_sat_result * last_result = ctx.get_check_sat_result(); From 62b8394bdd6fdb4dcdb634aa2055692095265786 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 09:52:45 -0700 Subject: [PATCH 031/488] fixes #1179 Signed-off-by: Nikolaj Bjorner --- src/smt/smt_justification.h | 1 + src/smt/theory_seq.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/smt/smt_justification.h b/src/smt/smt_justification.h index ea969d1db..f4b3ecb12 100644 --- a/src/smt/smt_justification.h +++ b/src/smt/smt_justification.h @@ -181,6 +181,7 @@ namespace smt { enode * m_node2; public: eq_propagation_justification(enode * n1, enode * n2):m_node1(n1), m_node2(n2) { + SASSERT(n1 != n2); } virtual void get_antecedents(conflict_resolution & cr); diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 832995994..76d8a5a74 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -1891,7 +1891,7 @@ bool theory_seq::solve_ne(unsigned idx) { new_ls.push_back(ls); new_rs.push_back(rs); } - else { + else if (nl != nr) { literal lit(mk_eq(nl, nr, false)); ctx.mark_as_relevant(lit); new_lits.push_back(lit); From a59907170d10385ad382b95d2bf9c713db1a3c0d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 31 Jul 2017 18:34:46 +0100 Subject: [PATCH 032/488] Fixed renormalization in fp.mul. Relates to #872. --- src/ast/fpa/fpa2bv_converter.cpp | 8 ++++++-- src/util/mpf.cpp | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 0c9a1c866..864293380 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1598,7 +1598,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, alignment_sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); alignment_sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, alignment_sticky_raw.get()); dbg_decouple("fpa2bv_fma_shifted_f_sig", shifted_f_sig); - dbg_decouple("fpa2bv_fma_f_sig_alignment_stickyw", alignment_sticky); + dbg_decouple("fpa2bv_fma_f_sig_alignment_sticky", alignment_sticky); SASSERT(is_well_sorted(m, alignment_sticky)); SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2 * sbits); SASSERT(is_well_sorted(m, shifted_f_sig)); @@ -1677,7 +1677,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, // Renormalize expr_ref zero_e2(m), min_exp(m), sig_lz(m), max_exp_delta(m), sig_lz_capped(m), renorm_delta(m); zero_e2 = m_bv_util.mk_numeral(0, ebits + 2); - mk_min_exp(ebits+2, min_exp); + mk_min_exp(ebits, min_exp); + min_exp = m_bv_util.mk_sign_extend(2, min_exp); mk_leading_zeros(sig_abs, ebits+2, sig_lz); sig_lz = m_bv_util.mk_bv_sub(sig_lz, m_bv_util.mk_numeral(2, ebits+2)); max_exp_delta = m_bv_util.mk_bv_sub(res_exp, min_exp); @@ -1685,7 +1686,10 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, renorm_delta = m.mk_ite(m_bv_util.mk_sle(zero_e2, sig_lz_capped), sig_lz_capped, zero_e2); res_exp = m_bv_util.mk_bv_sub(res_exp, renorm_delta); sig_abs = m_bv_util.mk_bv_shl(sig_abs, m_bv_util.mk_zero_extend(2*sbits-ebits, renorm_delta)); + dbg_decouple("fpa2bv_fma_min_exp", min_exp); + dbg_decouple("fpa2bv_fma_max_exp_delta", max_exp_delta); dbg_decouple("fpa2bv_fma_sig_lz", sig_lz); + dbg_decouple("fpa2bv_fma_sig_lz_capped", sig_lz_capped); dbg_decouple("fpa2bv_fma_renorm_delta", renorm_delta); unsigned too_short = 0; diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index a2bf12a30..6f61a78e9 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -919,7 +919,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co mpf_exp_t min_exp = mk_min_exp(x.ebits); unsigned sig_width = m_mpz_manager.prev_power_of_two(res.get().significand) + 1; - mpf_exp_t sig_lz = 2 * x.sbits - sig_width; // want << lz + mpf_exp_t sig_lz = 2 * x.sbits - sig_width; mpf_exp_t max_exp_delta = res.exponent() - min_exp; unsigned renorm_delta = (unsigned) std::max((mpf_exp_t)0, std::min(sig_lz, max_exp_delta)); res.get().exponent -= renorm_delta; From be1df279ecac4bb3a9a07008368540d1b860faba Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 14:11:07 -0400 Subject: [PATCH 033/488] make proof_checker less verbose --- src/ast/proof_checker/proof_checker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/proof_checker/proof_checker.cpp b/src/ast/proof_checker/proof_checker.cpp index 45223cdb7..df4a8e344 100644 --- a/src/ast/proof_checker/proof_checker.cpp +++ b/src/ast/proof_checker/proof_checker.cpp @@ -1299,7 +1299,7 @@ bool proof_checker::check_arith_literal(bool is_pos, app* lit0, rational const& is_pos = !is_pos; } if (!a.is_le(lit) && !a.is_lt(lit) && !a.is_ge(lit) && !a.is_gt(lit) && !m.is_eq(lit)) { - IF_VERBOSE(0, verbose_stream() << mk_pp(lit, m) << "\n";); + IF_VERBOSE(2, verbose_stream() << "Not arith literal: " << mk_pp(lit, m) << "\n";); return false; } SASSERT(lit->get_num_args() == 2); @@ -1363,7 +1363,7 @@ bool proof_checker::check_arith_literal(bool is_pos, app* lit0, rational const& rw(sum); } - IF_VERBOSE(0, verbose_stream() << coeff << "\n" << mk_pp(lit0, m) << "\n" << mk_pp(sum, m) << "\n";); + IF_VERBOSE(2, verbose_stream() << "coeff,lit,sum " << coeff << "\n" << mk_pp(lit0, m) << "\n" << mk_pp(sum, m) << "\n";); #endif return true; From 15451ae8580a8bf230ce2d1257bc7f0a64b19d80 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 14:13:08 -0400 Subject: [PATCH 034/488] extra flags to control quant_hoist --- src/ast/rewriter/quant_hoist.cpp | 80 ++++++++++++++++++-------------- src/ast/rewriter/quant_hoist.h | 8 ++-- 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/ast/rewriter/quant_hoist.cpp b/src/ast/rewriter/quant_hoist.cpp index e59a079e7..9c345851a 100644 --- a/src/ast/rewriter/quant_hoist.cpp +++ b/src/ast/rewriter/quant_hoist.cpp @@ -41,9 +41,9 @@ public: m_rewriter(m) {} - void operator()(expr* fml, app_ref_vector& vars, bool& is_fa, expr_ref& result) { + void operator()(expr* fml, app_ref_vector& vars, bool& is_fa, expr_ref& result, bool use_fresh, bool rewrite_ok) { quantifier_type qt = Q_none_pos; - pull_quantifier(fml, qt, vars, result); + pull_quantifier(fml, qt, vars, result, use_fresh, rewrite_ok); TRACE("qe_verbose", tout << mk_pp(fml, m) << "\n"; tout << mk_pp(result, m) << "\n";); @@ -51,36 +51,38 @@ public: is_fa = (Q_forall_pos == qt); } - void pull_exists(expr* fml, app_ref_vector& vars, expr_ref& result) { + void pull_exists(expr* fml, app_ref_vector& vars, expr_ref& result, bool use_fresh, bool rewrite_ok) { quantifier_type qt = Q_exists_pos; - pull_quantifier(fml, qt, vars, result); + pull_quantifier(fml, qt, vars, result, use_fresh, rewrite_ok); TRACE("qe_verbose", tout << mk_pp(fml, m) << "\n"; tout << mk_pp(result, m) << "\n";); } - void pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars) { + void pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars, bool use_fresh, bool rewrite_ok) { quantifier_type qt = is_forall?Q_forall_pos:Q_exists_pos; expr_ref result(m); - pull_quantifier(fml, qt, vars, result); + pull_quantifier(fml, qt, vars, result, use_fresh, rewrite_ok); TRACE("qe_verbose", tout << mk_pp(fml, m) << "\n"; tout << mk_pp(result, m) << "\n";); fml = result; } - void extract_quantifier(quantifier* q, app_ref_vector& vars, expr_ref& result) { + void extract_quantifier(quantifier* q, app_ref_vector& vars, expr_ref& result, bool use_fresh) { unsigned nd = q->get_num_decls(); for (unsigned i = 0; i < nd; ++i) { sort* s = q->get_decl_sort(i); - app* a = m.mk_fresh_const(q->get_decl_name(i).str().c_str(), s); + symbol const& sym = q->get_decl_name (i); + app* a = use_fresh ? m.mk_fresh_const(sym.str ().c_str (), s) + : m.mk_const (sym, s); vars.push_back(a); } expr * const * exprs = (expr* const*) (vars.c_ptr() + vars.size()- nd); instantiate(m, q, exprs, result); } - unsigned pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector* sorts, svector* names) { + unsigned pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector* sorts, svector* names, bool use_fresh, bool rewrite_ok) { unsigned index = var_counter().get_next_var(fml); while (is_quantifier(fml) && (is_forall == to_quantifier(fml)->is_forall())) { quantifier* q = to_quantifier(fml); @@ -97,7 +99,7 @@ public: return index; } app_ref_vector vars(m); - pull_quantifier(is_forall, fml, vars); + pull_quantifier(is_forall, fml, vars, use_fresh, rewrite_ok); if (vars.empty()) { return index; } @@ -192,7 +194,7 @@ private: } - void pull_quantifier(expr* fml, quantifier_type& qt, app_ref_vector& vars, expr_ref& result) { + void pull_quantifier(expr* fml, quantifier_type& qt, app_ref_vector& vars, expr_ref& result, bool use_fresh, bool rewrite_ok) { if (!has_quantifiers(fml)) { result = fml; @@ -209,38 +211,48 @@ private: if (m.is_and(fml)) { num_args = a->get_num_args(); for (unsigned i = 0; i < num_args; ++i) { - pull_quantifier(a->get_arg(i), qt, vars, tmp); + pull_quantifier(a->get_arg(i), qt, vars, tmp, use_fresh, rewrite_ok); args.push_back(tmp); } + if (rewrite_ok) { m_rewriter.mk_and(args.size(), args.c_ptr(), result); + } + else { + result = m.mk_and (args.size (), args.c_ptr ()); + } } else if (m.is_or(fml)) { num_args = to_app(fml)->get_num_args(); for (unsigned i = 0; i < num_args; ++i) { - pull_quantifier(to_app(fml)->get_arg(i), qt, vars, tmp); + pull_quantifier(to_app(fml)->get_arg(i), qt, vars, tmp, use_fresh, rewrite_ok); args.push_back(tmp); } + if (rewrite_ok) { m_rewriter.mk_or(args.size(), args.c_ptr(), result); + } + else { + result = m.mk_or (args.size (), args.c_ptr ()); + } } else if (m.is_not(fml)) { - pull_quantifier(to_app(fml)->get_arg(0), negate(qt), vars, tmp); + pull_quantifier(to_app(fml)->get_arg(0), negate(qt), vars, tmp, use_fresh, rewrite_ok); negate(qt); result = m.mk_not(tmp); } else if (m.is_implies(fml, t1, t2)) { - pull_quantifier(t1, negate(qt), vars, tmp); + pull_quantifier(t1, negate(qt), vars, tmp, use_fresh, rewrite_ok); negate(qt); - pull_quantifier(t2, qt, vars, result); + pull_quantifier(t2, qt, vars, result, use_fresh, rewrite_ok); result = m.mk_implies(tmp, result); } else if (m.is_ite(fml, t1, t2, t3)) { expr_ref tt1(m), tt2(m), tt3(m), ntt1(m), nt1(m); - pull_quantifier(t2, qt, vars, tt2); - pull_quantifier(t3, qt, vars, tt3); + pull_quantifier(t2, qt, vars, tt2, use_fresh, rewrite_ok); + pull_quantifier(t3, qt, vars, tt3, use_fresh, rewrite_ok); if (has_quantifiers(t1)) { - pull_quantifier(t1, qt, vars, tt1); + pull_quantifier(t1, qt, vars, tt1, use_fresh, rewrite_ok); nt1 = m.mk_not(t1); - pull_quantifier(nt1, qt, vars, ntt1); + pull_quantifier(nt1, qt, vars, ntt1, use_fresh, rewrite_ok); result = m.mk_and(m.mk_or(ntt1, tt2), m.mk_or(tt1, tt3)); } else { @@ -249,12 +261,12 @@ private: } else if ((m.is_eq(fml, t1, t2) && m.is_bool(t1)) || m.is_iff(fml, t1, t2)) { expr_ref tt1(m), tt2(m), ntt1(m), ntt2(m), nt1(m), nt2(m); - pull_quantifier(t1, qt, vars, tt1); - pull_quantifier(t2, qt, vars, tt2); + pull_quantifier(t1, qt, vars, tt1, use_fresh, rewrite_ok); + pull_quantifier(t2, qt, vars, tt2, use_fresh, rewrite_ok); nt1 = m.mk_not(t1); nt2 = m.mk_not(t2); - pull_quantifier(nt1, qt, vars, ntt1); - pull_quantifier(nt2, qt, vars, ntt2); + pull_quantifier(nt1, qt, vars, ntt1, use_fresh, rewrite_ok); + pull_quantifier(nt2, qt, vars, ntt2, use_fresh, rewrite_ok); result = m.mk_and(m.mk_or(ntt1, tt2), m.mk_or(ntt2, tt1)); } else { @@ -271,8 +283,8 @@ private: break; } set_quantifier_type(qt, q->is_forall()); - extract_quantifier(q, vars, tmp); - pull_quantifier(tmp, qt, vars, result); + extract_quantifier(q, vars, tmp, use_fresh); + pull_quantifier(tmp, qt, vars, result, use_fresh, rewrite_ok); break; } case AST_VAR: @@ -295,18 +307,18 @@ quantifier_hoister::~quantifier_hoister() { dealloc(m_impl); } -void quantifier_hoister::operator()(expr* fml, app_ref_vector& vars, bool& is_fa, expr_ref& result) { - (*m_impl)(fml, vars, is_fa, result); +void quantifier_hoister::operator()(expr* fml, app_ref_vector& vars, bool& is_fa, expr_ref& result, bool use_fresh, bool rewrite_ok) { + (*m_impl)(fml, vars, is_fa, result, use_fresh, rewrite_ok); } -void quantifier_hoister::pull_exists(expr* fml, app_ref_vector& vars, expr_ref& result) { - m_impl->pull_exists(fml, vars, result); +void quantifier_hoister::pull_exists(expr* fml, app_ref_vector& vars, expr_ref& result, bool use_fresh, bool rewrite_ok) { + m_impl->pull_exists(fml, vars, result, use_fresh, rewrite_ok); } -void quantifier_hoister::pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars) { - m_impl->pull_quantifier(is_forall, fml, vars); +void quantifier_hoister::pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars, bool use_fresh, bool rewrite_ok) { + m_impl->pull_quantifier(is_forall, fml, vars, use_fresh, rewrite_ok); } -unsigned quantifier_hoister::pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector* sorts, svector* names) { - return m_impl->pull_quantifier(is_forall, fml, sorts, names); +unsigned quantifier_hoister::pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector* sorts, svector* names, bool use_fresh, bool rewrite_ok) { + return m_impl->pull_quantifier(is_forall, fml, sorts, names, use_fresh, rewrite_ok); } diff --git a/src/ast/rewriter/quant_hoist.h b/src/ast/rewriter/quant_hoist.h index 90e6ec7ad..52a2fcda1 100644 --- a/src/ast/rewriter/quant_hoist.h +++ b/src/ast/rewriter/quant_hoist.h @@ -43,14 +43,14 @@ public: or, and, implies, ite (then and else branch only). */ - void operator()(expr* fml, app_ref_vector& vars, bool& is_fa, expr_ref& result); + void operator()(expr* fml, app_ref_vector& vars, bool& is_fa, expr_ref& result, bool use_fresh = true, bool rewrite_ok = true); /** \brief Pull top-most existential quantifier up. The list of variables is empty if there are no top-level existential quantifier. */ - void pull_exists(expr* fml, app_ref_vector& vars, expr_ref& result); + void pull_exists(expr* fml, app_ref_vector& vars, expr_ref& result, bool use_fresh = true, bool rewrite_ok = true); /** @@ -58,7 +58,7 @@ public: The list of variables is empty if there are no top-level universal/existential quantifier. */ - void pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars); + void pull_quantifier(bool is_forall, expr_ref& fml, app_ref_vector& vars, bool use_fresh = true, bool rewrite_ok = true); /** \brief Pull top-most universal (is_forall true) or existential (is_forall=false) quantifier up. @@ -66,7 +66,7 @@ public: Return index of maximal variable. */ - unsigned pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector* sorts, svector* names); + unsigned pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector* sorts, svector* names, bool use_fresh = true, bool rewrite_ok = true); }; From 7670b49ada29df98776a15fdebf2a85be4de3631 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 14:14:35 -0400 Subject: [PATCH 035/488] mark mk_true() and mk_false() const --- src/ast/ast.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/ast.h b/src/ast/ast.h index f71d5135c..75d3eb0f2 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -2021,8 +2021,8 @@ public: app * mk_not(expr * n) { return mk_app(m_basic_family_id, OP_NOT, n); } app * mk_distinct(unsigned num_args, expr * const * args); app * mk_distinct_expanded(unsigned num_args, expr * const * args); - app * mk_true() { return m_true; } - app * mk_false() { return m_false; } + app * mk_true() const { return m_true; } + app * mk_false() const { return m_false; } app * mk_bool_val(bool b) { return b?m_true:m_false; } app * mk_interp(expr * arg) { return mk_app(m_basic_family_id, OP_INTERP, arg); } From 331eec8a05e857773e196dcbafbd4aff589c87a2 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 14:19:16 -0400 Subject: [PATCH 036/488] option to control array_der in qe_lite --- src/qe/qe_lite.cpp | 15 +++++++++------ src/qe/qe_lite.h | 5 ++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/qe/qe_lite.cpp b/src/qe/qe_lite.cpp index ce182a97b..ff2abde75 100644 --- a/src/qe/qe_lite.cpp +++ b/src/qe/qe_lite.cpp @@ -2342,6 +2342,7 @@ private: elim_star m_elim_star; th_rewriter m_rewriter; + bool m_use_array_der; bool has_unique_non_ground(expr_ref_vector const& fmls, unsigned& index) { index = fmls.size(); if (index <= 1) { @@ -2359,13 +2360,14 @@ private: } public: - impl(ast_manager & m, params_ref const & p): + impl(ast_manager & m, params_ref const & p, bool use_array_der): m(m), m_der(m, p), m_fm(m), m_array_der(m), m_elim_star(*this), - m_rewriter(m) {} + m_rewriter(m), + m_use_array_der(use_array_der) {} void operator()(app_ref_vector& vars, expr_ref& fml) { if (vars.empty()) { @@ -2445,14 +2447,15 @@ public: m_array_der.set_is_variable_proc(is_var); m_der(fmls); m_fm(fmls); - m_array_der(fmls); + // AG: disalble m_array_der() since it interferes with other array handling + if (m_use_array_der) m_array_der(fmls); TRACE("qe_lite", for (unsigned i = 0; i < fmls.size(); ++i) tout << mk_pp(fmls[i].get(), m) << "\n";); } }; -qe_lite::qe_lite(ast_manager & m, params_ref const & p) { - m_impl = alloc(impl, m, p); +qe_lite::qe_lite(ast_manager & m, params_ref const & p, bool use_array_der) { + m_impl = alloc(impl, m, p, use_array_der); } qe_lite::~qe_lite() { @@ -2484,7 +2487,7 @@ class qe_lite_tactic : public tactic { imp(ast_manager& m, params_ref const & p): m(m), - m_qe(m, p) + m_qe(m, p, true) {} void checkpoint() { diff --git a/src/qe/qe_lite.h b/src/qe/qe_lite.h index cff547f36..a918ab33d 100644 --- a/src/qe/qe_lite.h +++ b/src/qe/qe_lite.h @@ -31,7 +31,10 @@ class qe_lite { class impl; impl * m_impl; public: - qe_lite(ast_manager & m, params_ref const & p); + /** + use_array_der controls whether equalities over array reads are simplified + */ + qe_lite(ast_manager& m, params_ref const & p, bool use_array_der = true); ~qe_lite(); From 1d5713c3764a6f9fb62f2fff39d5dc727c4d2321 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 14:21:30 -0400 Subject: [PATCH 037/488] move semantics for ref --- src/util/ref.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/util/ref.h b/src/util/ref.h index d9663f9a4..811aba9af 100644 --- a/src/util/ref.h +++ b/src/util/ref.h @@ -50,6 +50,7 @@ public: inc_ref(); } + ref (ref && r): m_ptr (r.detach ()) {} ~ref() { dec_ref(); } @@ -89,6 +90,14 @@ public: return *this; } + ref & operator=(ref &&r) { + if (this != &r) { + dec_ref (); + m_ptr = r.detach (); + } + return *this; + } + void reset() { dec_ref(); m_ptr = 0; @@ -107,6 +116,11 @@ public: friend bool operator!=(const ref & r1, const ref & r2) { return r1.m_ptr != r2.m_ptr; } + friend void swap (ref &r1, ref &r2) { + T* tmp = r1.m_ptr; + r1.m_ptr = r2.m_ptr; + r2.m_ptr = tmp; + } }; /** From ecfd241e19fd2a6c5459dd69011a106e6f87587c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 31 Jul 2017 19:44:36 +0100 Subject: [PATCH 038/488] Injected 3 missing bits of precision into fp.rem. Relates to #872. --- src/ast/fpa/fpa2bv_converter.cpp | 53 ++++++++++++++++---------------- src/util/mpf.cpp | 27 ++++++++-------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 864293380..7e56df405 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1535,11 +1535,12 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, // Extend c expr_ref c_sig_ext(m); - c_sig_ext = m_bv_util.mk_zero_extend(1, m_bv_util.mk_concat(c_sig, m_bv_util.mk_numeral(0, sbits - 1))); + c_sig_ext = m_bv_util.mk_zero_extend(1, m_bv_util.mk_concat(c_sig, m_bv_util.mk_numeral(0, sbits - 1 + 3))); c_exp_ext = m_bv_util.mk_bv_sub(c_exp_ext, c_lz_ext); + mul_sig = m_bv_util.mk_concat(mul_sig, m_bv_util.mk_numeral(0, 3)); - SASSERT(m_bv_util.get_bv_size(mul_sig) == 2 * sbits); - SASSERT(m_bv_util.get_bv_size(c_sig_ext) == 2 * sbits); + SASSERT(m_bv_util.get_bv_size(mul_sig) == 2 * sbits + 3); + SASSERT(m_bv_util.get_bv_size(c_sig_ext) == 2 * sbits + 3); dbg_decouple("fpa2bv_fma_c_sig_ext", c_sig_ext); dbg_decouple("fpa2bv_fma_c_exp_ext", c_exp_ext); @@ -1550,10 +1551,10 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref e_sgn(m), e_sig(m), e_exp(m), f_sgn(m), f_sig(m), f_exp(m); m_simp.mk_ite(swap_cond, c_sgn, mul_sgn, e_sgn); - m_simp.mk_ite(swap_cond, c_sig_ext, mul_sig, e_sig); // has 2 * sbits + m_simp.mk_ite(swap_cond, c_sig_ext, mul_sig, e_sig); // has 2 * sbits + 3 m_simp.mk_ite(swap_cond, c_exp_ext, mul_exp, e_exp); // has ebits + 2 m_simp.mk_ite(swap_cond, mul_sgn, c_sgn, f_sgn); - m_simp.mk_ite(swap_cond, mul_sig, c_sig_ext, f_sig); // has 2 * sbits + m_simp.mk_ite(swap_cond, mul_sig, c_sig_ext, f_sig); // has 2 * sbits + 3 m_simp.mk_ite(swap_cond, mul_exp, c_exp_ext, f_exp); // has ebits + 2 SASSERT(is_well_sorted(m, e_sgn)); @@ -1563,8 +1564,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(is_well_sorted(m, f_sig)); SASSERT(is_well_sorted(m, f_exp)); - SASSERT(m_bv_util.get_bv_size(e_sig) == 2 * sbits); - SASSERT(m_bv_util.get_bv_size(f_sig) == 2 * sbits); + SASSERT(m_bv_util.get_bv_size(e_sig) == 2 * sbits + 3); + SASSERT(m_bv_util.get_bv_size(f_sig) == 2 * sbits + 3); SASSERT(m_bv_util.get_bv_size(e_exp) == ebits + 2); SASSERT(m_bv_util.get_bv_size(f_exp) == ebits + 2); @@ -1581,7 +1582,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, // cap the delta expr_ref cap(m), cap_le_delta(m); - cap = m_bv_util.mk_numeral(2*sbits, ebits+2); + cap = m_bv_util.mk_numeral(2*sbits+3, ebits+2); cap_le_delta = m_bv_util.mk_ule(cap, exp_delta); m_simp.mk_ite(cap_le_delta, cap, exp_delta, exp_delta); SASSERT(m_bv_util.get_bv_size(exp_delta) == ebits+2); @@ -1593,14 +1594,14 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref alignment_sticky_raw(m), alignment_sticky(m); shifted_big = m_bv_util.mk_bv_lshr( m_bv_util.mk_concat(f_sig, m_bv_util.mk_numeral(0, sbits)), - m_bv_util.mk_zero_extend((3*sbits)-(ebits+2), exp_delta)); - shifted_f_sig = m_bv_util.mk_extract(3*sbits-1, sbits, shifted_big); + m_bv_util.mk_zero_extend((3*sbits+3)-(ebits+2), exp_delta)); + shifted_f_sig = m_bv_util.mk_extract(3*sbits-1+3, sbits, shifted_big); alignment_sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); alignment_sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, alignment_sticky_raw.get()); dbg_decouple("fpa2bv_fma_shifted_f_sig", shifted_f_sig); dbg_decouple("fpa2bv_fma_f_sig_alignment_sticky", alignment_sticky); SASSERT(is_well_sorted(m, alignment_sticky)); - SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2 * sbits); + SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2*sbits+3); SASSERT(is_well_sorted(m, shifted_f_sig)); // Significant addition. @@ -1612,14 +1613,14 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, m_simp.mk_eq(e_sgn, f_sgn, eq_sgn); dbg_decouple("fpa2bv_fma_eq_sgn", eq_sgn); - SASSERT(m_bv_util.get_bv_size(e_sig) == 2*sbits + 2); - SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2*sbits + 2); + SASSERT(m_bv_util.get_bv_size(e_sig) == 2*sbits+2+3); + SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2*sbits+2+3); dbg_decouple("fpa2bv_fma_add_e_sig", e_sig); dbg_decouple("fpa2bv_fma_add_shifted_f_sig", shifted_f_sig); expr_ref sum(m), e_plus_f(m), e_minus_f(m), sticky_wide(m); - sticky_wide = m_bv_util.mk_zero_extend(2*sbits+1, alignment_sticky); + sticky_wide = m_bv_util.mk_zero_extend(2*sbits+1+3, alignment_sticky); e_plus_f = m_bv_util.mk_bv_add(e_sig, shifted_f_sig); e_plus_f = m.mk_ite(m.mk_eq(m_bv_util.mk_extract(0, 0, e_plus_f), zero_1), m_bv_util.mk_bv_add(e_plus_f, sticky_wide), @@ -1632,12 +1633,12 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_f_sig_or_sticky", shifted_f_sig); m_simp.mk_ite(eq_sgn, e_plus_f, e_minus_f, sum); - SASSERT(m_bv_util.get_bv_size(sum) == 2*sbits + 2); + SASSERT(m_bv_util.get_bv_size(sum) == 2*sbits+2+3); SASSERT(is_well_sorted(m, sum)); dbg_decouple("fpa2bv_fma_add_sum", sum); expr_ref sign_bv(m), n_sum(m); - sign_bv = m_bv_util.mk_extract(2*sbits+1, 2*sbits+1, sum); + sign_bv = m_bv_util.mk_extract(2*sbits+1+3, 2*sbits+1+3, sum); n_sum = m_bv_util.mk_bv_neg(sum); dbg_decouple("fpa2bv_fma_add_sign_bv", sign_bv); dbg_decouple("fpa2bv_fma_add_n_sum", n_sum); @@ -1661,14 +1662,14 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_res_sgn", res_sgn); expr_ref is_sig_neg(m); - is_sig_neg = m.mk_eq(one_1, m_bv_util.mk_extract(2 * sbits + 1, 2 * sbits + 1, sig_abs)); + is_sig_neg = m.mk_eq(one_1, m_bv_util.mk_extract(2*sbits+1+3, 2*sbits+1+3, sig_abs)); sig_abs = m.mk_ite(is_sig_neg, m_bv_util.mk_bv_neg(sig_abs), sig_abs); dbg_decouple("fpa2bv_fma_is_sig_neg", is_sig_neg); // Result could have overflown into 4.xxx. - SASSERT(m_bv_util.get_bv_size(sig_abs) == 2 * sbits + 2); + SASSERT(m_bv_util.get_bv_size(sig_abs) == 2*sbits+2+3); expr_ref extra(m), extra_is_zero(m); - extra = m_bv_util.mk_extract(2 * sbits + 1, 2 * sbits, sig_abs); + extra = m_bv_util.mk_extract(2*sbits+1+3, 2*sbits+3, sig_abs); extra_is_zero = m.mk_eq(extra, m_bv_util.mk_numeral(0, 2)); dbg_decouple("fpa2bv_fma_extra", extra); @@ -1685,7 +1686,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, sig_lz_capped = m.mk_ite(m_bv_util.mk_sle(sig_lz, max_exp_delta), sig_lz, max_exp_delta); renorm_delta = m.mk_ite(m_bv_util.mk_sle(zero_e2, sig_lz_capped), sig_lz_capped, zero_e2); res_exp = m_bv_util.mk_bv_sub(res_exp, renorm_delta); - sig_abs = m_bv_util.mk_bv_shl(sig_abs, m_bv_util.mk_zero_extend(2*sbits-ebits, renorm_delta)); + sig_abs = m_bv_util.mk_bv_shl(sig_abs, m_bv_util.mk_zero_extend(2*sbits+3-ebits, renorm_delta)); dbg_decouple("fpa2bv_fma_min_exp", min_exp); dbg_decouple("fpa2bv_fma_max_exp_delta", max_exp_delta); dbg_decouple("fpa2bv_fma_sig_lz", sig_lz); @@ -1699,26 +1700,26 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, } expr_ref sig_abs_h1(m), sticky_h1(m), sticky_h1_red(m), sig_abs_h1_f(m), res_sig_1(m); - sticky_h1 = m_bv_util.mk_extract(sbits - 5 + too_short, 0, sig_abs); - sig_abs_h1 = m_bv_util.mk_extract(2 * sbits + 1 + too_short, sbits - 4 + too_short, sig_abs); + sticky_h1 = m_bv_util.mk_extract(sbits - 5 + too_short + 3, 0, sig_abs); + sig_abs_h1 = m_bv_util.mk_extract(2 * sbits + 1 + too_short + 3, sbits - 4 + too_short + 3, sig_abs); sticky_h1_red = m_bv_util.mk_zero_extend(sbits + 5, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); expr * sticky_h1_red_args[2] = { sig_abs_h1, sticky_h1_red }; sig_abs_h1_f = m_bv_util.mk_bv_or(2, sticky_h1_red_args); res_sig_1 = m_bv_util.mk_extract(sbits + 3, 0, sig_abs_h1_f); - SASSERT(m_bv_util.get_bv_size(sticky_h1) == sbits - 4 + too_short); + SASSERT(m_bv_util.get_bv_size(sticky_h1) == sbits - 4 + too_short + 3); SASSERT(m_bv_util.get_bv_size(sig_abs_h1) == sbits + 6); SASSERT(m_bv_util.get_bv_size(sticky_h1_red) == sbits + 6); SASSERT(m_bv_util.get_bv_size(sig_abs_h1_f) == sbits + 6); SASSERT(m_bv_util.get_bv_size(res_sig_1) == sbits + 4); expr_ref sig_abs_h2(m), sticky_h2(m), sticky_h2_red(m), sig_abs_h2_f(m), res_sig_2(m); - sticky_h2 = m_bv_util.mk_extract(sbits - 4 + too_short, 0, sig_abs); - sig_abs_h2 = m_bv_util.mk_extract(2 * sbits + 1 + too_short, sbits - 3 + too_short, sig_abs); + sticky_h2 = m_bv_util.mk_extract(sbits - 4 + too_short + 3, 0, sig_abs); + sig_abs_h2 = m_bv_util.mk_extract(2 * sbits + 1 + too_short + 3, sbits - 3 + too_short + 3, sig_abs); sticky_h2_red = m_bv_util.mk_zero_extend(sbits + 4, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); expr * sticky_h2_red_args[2] = { sig_abs_h2, sticky_h2_red }; sig_abs_h2_f = m_bv_util.mk_zero_extend(1, m_bv_util.mk_bv_or(2, sticky_h2_red_args)); res_sig_2 = m_bv_util.mk_extract(sbits + 3, 0, sig_abs_h2_f); - SASSERT(m_bv_util.get_bv_size(sticky_h2) == sbits - 3 + too_short); + SASSERT(m_bv_util.get_bv_size(sticky_h2) == sbits - 3 + too_short + 3); SASSERT(m_bv_util.get_bv_size(sig_abs_h2) == sbits + 5); SASSERT(m_bv_util.get_bv_size(sticky_h2_red) == sbits + 5); SASSERT(m_bv_util.get_bv_size(sig_abs_h2_f) == sbits + 6); diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 6f61a78e9..ed97db721 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -840,16 +840,19 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co SASSERT(m_mpz_manager.lt(mr.significand(), m_powers2(2*x.sbits))); SASSERT(m_mpz_manager.ge(mr.significand(), m_powers2(2*x.sbits - 2))); - // Introduce extra bits into c in _[0].[sbits-1] s.t. c in _[0].[2*sbits-2] - c.set(x.ebits+2, 2*x.sbits-1, c.sign(), c.exponent(), c.significand()); - m_mpz_manager.mul2k(c.significand(), x.sbits - 1); + // Introduce (sbits+3) extra bits into c in _[0].[sbits-1] s.t. c in _[0].[2*sbits-2] + c.set(x.ebits+2, 2*x.sbits-1+3, c.sign(), c.exponent(), c.significand()); + m_mpz_manager.mul2k(c.significand(), x.sbits - 1 + 3); + // And + 3 bits into mr as well. + mr.set(x.ebits + 2, 2 * x.sbits - 1 + 3, mr.sign(), mr.exponent(), mr.significand()); + m_mpz_manager.mul2k(mr.significand(), 3); TRACE("mpf_dbg", tout << "C_= " << to_string(c) << std::endl; tout << "C_= " << to_string_binary(c, 1, 0) << std::endl;); - SASSERT(m_mpz_manager.lt(c.significand(), m_powers2(2*x.sbits))); + SASSERT(m_mpz_manager.lt(c.significand(), m_powers2(2*x.sbits + 3))); SASSERT(m_mpz_manager.is_zero(c.significand()) || - m_mpz_manager.ge(c.significand(), m_powers2(2*x.sbits - 2))); + m_mpz_manager.ge(c.significand(), m_powers2(2*x.sbits - 2 + 3))); if (exp(c) > exp(mr)) { TRACE("mpf_dbg", tout << "Swap!" << std::endl;); @@ -860,8 +863,8 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co mpf_exp_t exp_delta_w = exp(mr) - exp(c); SASSERT(exp(mr) >= exp(c) && exp_delta_w >= 0); - if (exp_delta_w > 2 * x.sbits) - exp_delta_w = 2 * x.sbits; + if (exp_delta_w > 2 * x.sbits + 3) + exp_delta_w = 2 * x.sbits + 3; unsigned exp_delta = (unsigned)exp_delta_w; @@ -905,8 +908,8 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co // Renormalize bool renorm_sticky = false; - SASSERT(m_mpz_manager.lt(res.significand(), m_powers2(2 * x.sbits + 1))); - if (m_mpz_manager.ge(res.significand(), m_powers2(2 * x.sbits))) + SASSERT(m_mpz_manager.lt(res.significand(), m_powers2(2 * x.sbits + 1 + 3))); + if (m_mpz_manager.ge(res.significand(), m_powers2(2 * x.sbits + 3))) { SASSERT(exp(res) < mk_max_exp(x.ebits)); // NYI. @@ -919,7 +922,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co mpf_exp_t min_exp = mk_min_exp(x.ebits); unsigned sig_width = m_mpz_manager.prev_power_of_two(res.get().significand) + 1; - mpf_exp_t sig_lz = 2 * x.sbits - sig_width; + mpf_exp_t sig_lz = 2 * x.sbits + 3 - sig_width; mpf_exp_t max_exp_delta = res.exponent() - min_exp; unsigned renorm_delta = (unsigned) std::max((mpf_exp_t)0, std::min(sig_lz, max_exp_delta)); res.get().exponent -= renorm_delta; @@ -930,11 +933,11 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co set(o, x.ebits, x.sbits, res.sign(), res.exponent(), mpz(0)); if (x.sbits >= 4) { - m_mpz_manager.machine_div_rem(res.significand(), m_powers2(x.sbits - 4), o.significand, sticky_rem); + m_mpz_manager.machine_div_rem(res.significand(), m_powers2(x.sbits - 4 + 3), o.significand, sticky_rem); renorm_sticky |= !m_mpz_manager.is_zero(sticky_rem); } else { - m_mpz_manager.mul2k(res.significand(), 4 - x.sbits, o.significand); + m_mpz_manager.mul2k(res.significand(), 4 - x.sbits + 3, o.significand); } if (renorm_sticky && m_mpz_manager.is_even(o.significand)) From 52cf80d63722ec6c322daa01c01fd7755306d9f8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 31 Jul 2017 19:53:55 +0100 Subject: [PATCH 039/488] Simplified bit-vector bounds in fp.rem. Relates to #872. --- src/ast/fpa/fpa2bv_converter.cpp | 64 ++++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 7e56df405..0f4d26739 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1535,12 +1535,12 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, // Extend c expr_ref c_sig_ext(m); - c_sig_ext = m_bv_util.mk_zero_extend(1, m_bv_util.mk_concat(c_sig, m_bv_util.mk_numeral(0, sbits - 1 + 3))); + c_sig_ext = m_bv_util.mk_zero_extend(1, m_bv_util.mk_concat(c_sig, m_bv_util.mk_numeral(0, sbits+2))); c_exp_ext = m_bv_util.mk_bv_sub(c_exp_ext, c_lz_ext); mul_sig = m_bv_util.mk_concat(mul_sig, m_bv_util.mk_numeral(0, 3)); - SASSERT(m_bv_util.get_bv_size(mul_sig) == 2 * sbits + 3); - SASSERT(m_bv_util.get_bv_size(c_sig_ext) == 2 * sbits + 3); + SASSERT(m_bv_util.get_bv_size(mul_sig) == 2*sbits+3); + SASSERT(m_bv_util.get_bv_size(c_sig_ext) == 2*sbits+3); dbg_decouple("fpa2bv_fma_c_sig_ext", c_sig_ext); dbg_decouple("fpa2bv_fma_c_exp_ext", c_exp_ext); @@ -1564,8 +1564,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(is_well_sorted(m, f_sig)); SASSERT(is_well_sorted(m, f_exp)); - SASSERT(m_bv_util.get_bv_size(e_sig) == 2 * sbits + 3); - SASSERT(m_bv_util.get_bv_size(f_sig) == 2 * sbits + 3); + SASSERT(m_bv_util.get_bv_size(e_sig) == 2*sbits+3); + SASSERT(m_bv_util.get_bv_size(f_sig) == 2*sbits+3); SASSERT(m_bv_util.get_bv_size(e_exp) == ebits + 2); SASSERT(m_bv_util.get_bv_size(f_exp) == ebits + 2); @@ -1595,7 +1595,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, shifted_big = m_bv_util.mk_bv_lshr( m_bv_util.mk_concat(f_sig, m_bv_util.mk_numeral(0, sbits)), m_bv_util.mk_zero_extend((3*sbits+3)-(ebits+2), exp_delta)); - shifted_f_sig = m_bv_util.mk_extract(3*sbits-1+3, sbits, shifted_big); + shifted_f_sig = m_bv_util.mk_extract(3*sbits+2, sbits, shifted_big); alignment_sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); alignment_sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, alignment_sticky_raw.get()); dbg_decouple("fpa2bv_fma_shifted_f_sig", shifted_f_sig); @@ -1613,14 +1613,14 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, m_simp.mk_eq(e_sgn, f_sgn, eq_sgn); dbg_decouple("fpa2bv_fma_eq_sgn", eq_sgn); - SASSERT(m_bv_util.get_bv_size(e_sig) == 2*sbits+2+3); - SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2*sbits+2+3); + SASSERT(m_bv_util.get_bv_size(e_sig) == 2*sbits+5); + SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2*sbits+5); dbg_decouple("fpa2bv_fma_add_e_sig", e_sig); dbg_decouple("fpa2bv_fma_add_shifted_f_sig", shifted_f_sig); expr_ref sum(m), e_plus_f(m), e_minus_f(m), sticky_wide(m); - sticky_wide = m_bv_util.mk_zero_extend(2*sbits+1+3, alignment_sticky); + sticky_wide = m_bv_util.mk_zero_extend(2*sbits+4, alignment_sticky); e_plus_f = m_bv_util.mk_bv_add(e_sig, shifted_f_sig); e_plus_f = m.mk_ite(m.mk_eq(m_bv_util.mk_extract(0, 0, e_plus_f), zero_1), m_bv_util.mk_bv_add(e_plus_f, sticky_wide), @@ -1633,12 +1633,12 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_f_sig_or_sticky", shifted_f_sig); m_simp.mk_ite(eq_sgn, e_plus_f, e_minus_f, sum); - SASSERT(m_bv_util.get_bv_size(sum) == 2*sbits+2+3); + SASSERT(m_bv_util.get_bv_size(sum) == 2*sbits+5); SASSERT(is_well_sorted(m, sum)); dbg_decouple("fpa2bv_fma_add_sum", sum); expr_ref sign_bv(m), n_sum(m); - sign_bv = m_bv_util.mk_extract(2*sbits+1+3, 2*sbits+1+3, sum); + sign_bv = m_bv_util.mk_extract(2*sbits+4, 2*sbits+4, sum); n_sum = m_bv_util.mk_bv_neg(sum); dbg_decouple("fpa2bv_fma_add_sign_bv", sign_bv); dbg_decouple("fpa2bv_fma_add_n_sum", n_sum); @@ -1662,14 +1662,14 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_res_sgn", res_sgn); expr_ref is_sig_neg(m); - is_sig_neg = m.mk_eq(one_1, m_bv_util.mk_extract(2*sbits+1+3, 2*sbits+1+3, sig_abs)); + is_sig_neg = m.mk_eq(one_1, m_bv_util.mk_extract(2*sbits+4, 2*sbits+4, sig_abs)); sig_abs = m.mk_ite(is_sig_neg, m_bv_util.mk_bv_neg(sig_abs), sig_abs); dbg_decouple("fpa2bv_fma_is_sig_neg", is_sig_neg); // Result could have overflown into 4.xxx. - SASSERT(m_bv_util.get_bv_size(sig_abs) == 2*sbits+2+3); + SASSERT(m_bv_util.get_bv_size(sig_abs) == 2*sbits+4); expr_ref extra(m), extra_is_zero(m); - extra = m_bv_util.mk_extract(2*sbits+1+3, 2*sbits+3, sig_abs); + extra = m_bv_util.mk_extract(2*sbits+4, 2*sbits+3, sig_abs); extra_is_zero = m.mk_eq(extra, m_bv_util.mk_numeral(0, 2)); dbg_decouple("fpa2bv_fma_extra", extra); @@ -1700,30 +1700,30 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, } expr_ref sig_abs_h1(m), sticky_h1(m), sticky_h1_red(m), sig_abs_h1_f(m), res_sig_1(m); - sticky_h1 = m_bv_util.mk_extract(sbits - 5 + too_short + 3, 0, sig_abs); - sig_abs_h1 = m_bv_util.mk_extract(2 * sbits + 1 + too_short + 3, sbits - 4 + too_short + 3, sig_abs); - sticky_h1_red = m_bv_util.mk_zero_extend(sbits + 5, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); + sticky_h1 = m_bv_util.mk_extract(sbits+too_short-2, 0, sig_abs); + sig_abs_h1 = m_bv_util.mk_extract(2*sbits+too_short+4, sbits-1+too_short, sig_abs); + sticky_h1_red = m_bv_util.mk_zero_extend(sbits+5, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); expr * sticky_h1_red_args[2] = { sig_abs_h1, sticky_h1_red }; sig_abs_h1_f = m_bv_util.mk_bv_or(2, sticky_h1_red_args); - res_sig_1 = m_bv_util.mk_extract(sbits + 3, 0, sig_abs_h1_f); - SASSERT(m_bv_util.get_bv_size(sticky_h1) == sbits - 4 + too_short + 3); - SASSERT(m_bv_util.get_bv_size(sig_abs_h1) == sbits + 6); - SASSERT(m_bv_util.get_bv_size(sticky_h1_red) == sbits + 6); - SASSERT(m_bv_util.get_bv_size(sig_abs_h1_f) == sbits + 6); - SASSERT(m_bv_util.get_bv_size(res_sig_1) == sbits + 4); + res_sig_1 = m_bv_util.mk_extract(sbits+3, 0, sig_abs_h1_f); + SASSERT(m_bv_util.get_bv_size(sticky_h1) == sbits+too_short-1); + SASSERT(m_bv_util.get_bv_size(sig_abs_h1) == sbits+6); + SASSERT(m_bv_util.get_bv_size(sticky_h1_red) == sbits+6); + SASSERT(m_bv_util.get_bv_size(sig_abs_h1_f) == sbits+6); + SASSERT(m_bv_util.get_bv_size(res_sig_1) == sbits+4); expr_ref sig_abs_h2(m), sticky_h2(m), sticky_h2_red(m), sig_abs_h2_f(m), res_sig_2(m); - sticky_h2 = m_bv_util.mk_extract(sbits - 4 + too_short + 3, 0, sig_abs); - sig_abs_h2 = m_bv_util.mk_extract(2 * sbits + 1 + too_short + 3, sbits - 3 + too_short + 3, sig_abs); - sticky_h2_red = m_bv_util.mk_zero_extend(sbits + 4, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); + sticky_h2 = m_bv_util.mk_extract(sbits+too_short-1, 0, sig_abs); + sig_abs_h2 = m_bv_util.mk_extract(2*sbits+too_short+4, sbits+too_short, sig_abs); + sticky_h2_red = m_bv_util.mk_zero_extend(sbits+4, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_h1.get())); expr * sticky_h2_red_args[2] = { sig_abs_h2, sticky_h2_red }; sig_abs_h2_f = m_bv_util.mk_zero_extend(1, m_bv_util.mk_bv_or(2, sticky_h2_red_args)); - res_sig_2 = m_bv_util.mk_extract(sbits + 3, 0, sig_abs_h2_f); - SASSERT(m_bv_util.get_bv_size(sticky_h2) == sbits - 3 + too_short + 3); - SASSERT(m_bv_util.get_bv_size(sig_abs_h2) == sbits + 5); - SASSERT(m_bv_util.get_bv_size(sticky_h2_red) == sbits + 5); - SASSERT(m_bv_util.get_bv_size(sig_abs_h2_f) == sbits + 6); - SASSERT(m_bv_util.get_bv_size(res_sig_2) == sbits + 4); + res_sig_2 = m_bv_util.mk_extract(sbits+3, 0, sig_abs_h2_f); + SASSERT(m_bv_util.get_bv_size(sticky_h2) == sbits+too_short); + SASSERT(m_bv_util.get_bv_size(sig_abs_h2) == sbits+5); + SASSERT(m_bv_util.get_bv_size(sticky_h2_red) == sbits+5); + SASSERT(m_bv_util.get_bv_size(sig_abs_h2_f) == sbits+6); + SASSERT(m_bv_util.get_bv_size(res_sig_2) == sbits+4); res_sig = m.mk_ite(extra_is_zero, res_sig_1, res_sig_2); From 71d80ab47f21a07a54cdf61366a7028df82488d3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 11:54:11 -0700 Subject: [PATCH 040/488] fix build break based on new assertion in smt-eq-justification Signed-off-by: Nikolaj Bjorner --- src/smt/theory_seq.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 76d8a5a74..e72cd3f6d 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -1681,6 +1681,7 @@ bool theory_seq::solve_binary_eq(expr_ref_vector const& ls, expr_ref_vector cons bool has_conflict = false; for (unsigned j = 0; !has_conflict && j < sz; ++j) { unsigned j1 = (offset + j) % sz; + if (xs[j] == ys[j1]) continue; literal eq = mk_eq(xs[j], ys[j1], false); switch (ctx.get_assignment(eq)) { case l_false: From 507356c7bf6aa472abb1625a9a24465aeb9c9667 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 31 Jul 2017 20:18:39 +0100 Subject: [PATCH 041/488] Fixed bug in fpa2bv converter. Fixes #1178. --- src/ast/fpa/fpa2bv_converter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 0f4d26739..c84b2a691 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2714,12 +2714,12 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con SASSERT(m_util.is_bv2rm(args[0])); expr * bv_rm = to_app(args[0])->get_arg(0); - rational e; - if (!m_arith_util.is_numeral(args[1], e)) + rational q; + if (!m_arith_util.is_numeral(args[1], q)) UNREACHABLE(); - rational q; - if (!m_arith_util.is_numeral(args[2], q)) + rational e; + if (!m_arith_util.is_numeral(args[2], e)) UNREACHABLE(); SASSERT(e.is_int64()); From b19f94ae5b6066ec8e007f868c814b14b86ccf91 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 13:24:11 -0700 Subject: [PATCH 042/488] make include paths uniformly use path relative to src. #534 Signed-off-by: Nikolaj Bjorner --- scripts/update_include.py | 63 +++++++++++++++++++ .../ackermannize_bv_model_converter.cpp | 4 +- .../ackermannize_bv_model_converter.h | 4 +- .../ackermannize_bv_tactic.cpp | 10 +-- src/ackermannization/ackermannize_bv_tactic.h | 2 +- src/ackermannization/ackr_bound_probe.cpp | 6 +- src/ackermannization/ackr_bound_probe.h | 2 +- src/ackermannization/ackr_helper.cpp | 2 +- src/ackermannization/ackr_helper.h | 2 +- src/ackermannization/ackr_info.h | 10 +-- src/ackermannization/ackr_model_converter.cpp | 8 +-- src/ackermannization/ackr_model_converter.h | 4 +- src/ackermannization/lackr.cpp | 12 ++-- src/ackermannization/lackr.h | 22 +++---- .../lackr_model_constructor.cpp | 14 ++--- .../lackr_model_constructor.h | 8 +-- .../lackr_model_converter_lazy.cpp | 10 +-- .../lackr_model_converter_lazy.h | 4 +- src/api/api_algebraic.cpp | 14 ++--- src/api/api_arith.cpp | 10 +-- src/api/api_array.cpp | 8 +-- src/api/api_ast.cpp | 40 ++++++------ src/api/api_ast_map.cpp | 12 ++-- src/api/api_ast_map.h | 4 +- src/api/api_ast_vector.cpp | 10 +-- src/api/api_ast_vector.h | 2 +- src/api/api_bv.cpp | 8 +-- src/api/api_config_params.cpp | 18 +++--- src/api/api_context.cpp | 14 ++--- src/api/api_context.h | 32 +++++----- src/api/api_datalog.cpp | 34 +++++----- src/api/api_datalog.h | 10 +-- src/api/api_datatype.cpp | 8 +-- src/api/api_fpa.cpp | 6 +- src/api/api_goal.cpp | 8 +-- src/api/api_goal.h | 4 +- src/api/api_interp.cpp | 40 ++++++------ src/api/api_log.cpp | 4 +- src/api/api_model.cpp | 16 ++--- src/api/api_model.h | 4 +- src/api/api_numeral.cpp | 14 ++--- src/api/api_opt.cpp | 22 +++---- src/api/api_params.cpp | 8 +-- src/api/api_parsers.cpp | 14 ++--- src/api/api_pb.cpp | 8 +-- src/api/api_polynomial.cpp | 16 ++--- src/api/api_polynomial.h | 2 +- src/api/api_quant.cpp | 10 +-- src/api/api_rcf.cpp | 6 +- src/api/api_seq.cpp | 8 +-- src/api/api_solver.cpp | 30 ++++----- src/api/api_solver.h | 4 +- src/api/api_stats.cpp | 6 +- src/api/api_stats.h | 4 +- src/api/api_tactic.cpp | 14 ++--- src/api/api_tactic.h | 4 +- src/api/api_util.h | 6 +- src/api/z3.h | 20 +++--- src/api/z3_logger.h | 2 +- src/api/z3_private.h | 4 +- src/api/z3_replayer.cpp | 12 ++-- src/api/z3_replayer.h | 4 +- src/api/z3_v1.h | 2 +- src/ast/act_cache.cpp | 2 +- src/ast/act_cache.h | 6 +- src/ast/arith_decl_plugin.cpp | 10 +-- src/ast/arith_decl_plugin.h | 2 +- src/ast/array_decl_plugin.cpp | 8 +-- src/ast/array_decl_plugin.h | 2 +- src/ast/ast.cpp | 16 ++--- src/ast/ast.h | 52 +++++++-------- src/ast/ast_ll_pp.cpp | 4 +- src/ast/ast_ll_pp.h | 2 +- src/ast/ast_lt.cpp | 2 +- src/ast/ast_pp.h | 2 +- src/ast/ast_pp_util.cpp | 6 +- src/ast/ast_pp_util.h | 2 +- src/ast/ast_printer.cpp | 4 +- src/ast/ast_printer.h | 4 +- src/ast/ast_smt2_pp.cpp | 12 ++-- src/ast/ast_smt2_pp.h | 20 +++--- src/ast/ast_smt_pp.cpp | 22 +++---- src/ast/ast_smt_pp.h | 4 +- src/ast/ast_trail.h | 4 +- src/ast/ast_translation.cpp | 14 ++--- src/ast/ast_translation.h | 2 +- src/ast/ast_util.cpp | 2 +- src/ast/ast_util.h | 4 +- src/ast/bv_decl_plugin.cpp | 10 +-- src/ast/bv_decl_plugin.h | 2 +- src/ast/datatype_decl_plugin.cpp | 6 +- src/ast/datatype_decl_plugin.h | 8 +-- src/ast/decl_collector.cpp | 2 +- src/ast/decl_collector.h | 4 +- src/ast/dl_decl_plugin.cpp | 12 ++-- src/ast/dl_decl_plugin.h | 6 +- src/ast/expr2polynomial.cpp | 14 ++--- src/ast/expr2polynomial.h | 4 +- src/ast/expr2var.cpp | 6 +- src/ast/expr2var.h | 4 +- src/ast/expr_abstract.cpp | 4 +- src/ast/expr_abstract.h | 2 +- src/ast/expr_functors.cpp | 2 +- src/ast/expr_functors.h | 4 +- src/ast/expr_map.cpp | 4 +- src/ast/expr_map.h | 4 +- src/ast/expr_stat.cpp | 4 +- src/ast/expr_substitution.cpp | 4 +- src/ast/expr_substitution.h | 2 +- src/ast/for_each_ast.cpp | 2 +- src/ast/for_each_ast.h | 6 +- src/ast/for_each_expr.cpp | 2 +- src/ast/for_each_expr.h | 4 +- src/ast/format.cpp | 4 +- src/ast/format.h | 2 +- src/ast/fpa/bv2fpa_converter.cpp | 10 +-- src/ast/fpa/bv2fpa_converter.h | 10 +-- src/ast/fpa/fpa2bv_converter.cpp | 10 +-- src/ast/fpa/fpa2bv_converter.h | 22 +++---- src/ast/fpa/fpa2bv_rewriter.cpp | 6 +- src/ast/fpa/fpa2bv_rewriter.h | 6 +- src/ast/fpa_decl_plugin.cpp | 6 +- src/ast/fpa_decl_plugin.h | 10 +-- src/ast/func_decl_dependencies.cpp | 6 +- src/ast/func_decl_dependencies.h | 4 +- src/ast/has_free_vars.cpp | 6 +- src/ast/macro_substitution.cpp | 4 +- src/ast/macro_substitution.h | 2 +- src/ast/macros/macro_finder.cpp | 8 +-- src/ast/macros/macro_finder.h | 4 +- src/ast/macros/macro_manager.cpp | 10 +-- src/ast/macros/macro_manager.h | 12 ++-- src/ast/macros/macro_util.cpp | 22 +++---- src/ast/macros/macro_util.h | 6 +- src/ast/macros/quasi_macros.cpp | 10 +-- src/ast/macros/quasi_macros.h | 6 +- src/ast/normal_forms/defined_names.cpp | 12 ++-- src/ast/normal_forms/defined_names.h | 2 +- src/ast/normal_forms/name_exprs.cpp | 6 +- src/ast/normal_forms/name_exprs.h | 4 +- src/ast/normal_forms/nnf.cpp | 18 +++--- src/ast/normal_forms/nnf.h | 6 +- src/ast/normal_forms/pull_quant.cpp | 8 +-- src/ast/normal_forms/pull_quant.h | 2 +- src/ast/num_occurs.cpp | 2 +- src/ast/num_occurs.h | 4 +- src/ast/occurs.cpp | 4 +- src/ast/pattern/expr_pattern_match.cpp | 14 ++--- src/ast/pattern/expr_pattern_match.h | 4 +- src/ast/pattern/pattern_inference.cpp | 20 +++--- src/ast/pattern/pattern_inference.h | 20 +++--- src/ast/pattern/pattern_inference_params.cpp | 2 +- src/ast/pattern/pattern_inference_params.h | 2 +- src/ast/pb_decl_plugin.cpp | 4 +- src/ast/pb_decl_plugin.h | 2 +- src/ast/pp.cpp | 2 +- src/ast/pp.h | 4 +- src/ast/proof_checker/proof_checker.cpp | 14 ++--- src/ast/proof_checker/proof_checker.h | 4 +- src/ast/recurse_expr.h | 4 +- src/ast/recurse_expr_def.h | 2 +- src/ast/reg_decl_plugins.cpp | 18 +++--- src/ast/rewriter/arith_rewriter.cpp | 8 +-- src/ast/rewriter/arith_rewriter.h | 4 +- src/ast/rewriter/array_rewriter.cpp | 6 +- src/ast/rewriter/array_rewriter.h | 8 +-- src/ast/rewriter/ast_counter.cpp | 2 +- src/ast/rewriter/ast_counter.h | 8 +-- src/ast/rewriter/bit_blaster/bit_blaster.cpp | 8 +-- src/ast/rewriter/bit_blaster/bit_blaster.h | 10 +-- .../bit_blaster/bit_blaster_rewriter.cpp | 14 ++--- .../bit_blaster/bit_blaster_rewriter.h | 6 +- .../rewriter/bit_blaster/bit_blaster_tpl.h | 2 +- .../bit_blaster/bit_blaster_tpl_def.h | 12 ++-- src/ast/rewriter/bool_rewriter.cpp | 4 +- src/ast/rewriter/bool_rewriter.h | 6 +- src/ast/rewriter/bv_bounds.cpp | 4 +- src/ast/rewriter/bv_bounds.h | 6 +- src/ast/rewriter/bv_rewriter.cpp | 8 +-- src/ast/rewriter/bv_rewriter.h | 10 +-- src/ast/rewriter/bv_trailing.cpp | 6 +- src/ast/rewriter/bv_trailing.h | 6 +- src/ast/rewriter/datatype_rewriter.cpp | 2 +- src/ast/rewriter/datatype_rewriter.h | 4 +- src/ast/rewriter/der.cpp | 14 ++--- src/ast/rewriter/der.h | 4 +- src/ast/rewriter/distribute_forall.cpp | 10 +-- src/ast/rewriter/distribute_forall.h | 4 +- src/ast/rewriter/dl_rewriter.cpp | 2 +- src/ast/rewriter/dl_rewriter.h | 4 +- src/ast/rewriter/enum2bv_rewriter.cpp | 10 +-- src/ast/rewriter/enum2bv_rewriter.h | 6 +- src/ast/rewriter/expr_replacer.cpp | 8 +-- src/ast/rewriter/expr_replacer.h | 6 +- src/ast/rewriter/expr_safe_replace.cpp | 6 +- src/ast/rewriter/expr_safe_replace.h | 2 +- src/ast/rewriter/factor_rewriter.cpp | 6 +- src/ast/rewriter/factor_rewriter.h | 6 +- src/ast/rewriter/fpa_rewriter.cpp | 4 +- src/ast/rewriter/fpa_rewriter.h | 10 +-- src/ast/rewriter/label_rewriter.cpp | 6 +- src/ast/rewriter/label_rewriter.h | 4 +- src/ast/rewriter/mk_extract_proc.cpp | 2 +- src/ast/rewriter/mk_extract_proc.h | 4 +- src/ast/rewriter/mk_simplified_app.cpp | 14 ++--- src/ast/rewriter/mk_simplified_app.h | 6 +- src/ast/rewriter/pb2bv_rewriter.cpp | 16 ++--- src/ast/rewriter/pb2bv_rewriter.h | 6 +- src/ast/rewriter/pb_rewriter.cpp | 10 +-- src/ast/rewriter/pb_rewriter.h | 8 +-- src/ast/rewriter/pb_rewriter_def.h | 2 +- src/ast/rewriter/poly_rewriter.h | 8 +-- src/ast/rewriter/poly_rewriter_def.h | 8 +-- src/ast/rewriter/quant_hoist.cpp | 16 ++--- src/ast/rewriter/quant_hoist.h | 2 +- src/ast/rewriter/rewriter.cpp | 6 +- src/ast/rewriter/rewriter.h | 6 +- src/ast/rewriter/rewriter_def.h | 4 +- src/ast/rewriter/rewriter_types.h | 4 +- src/ast/rewriter/seq_rewriter.cpp | 18 +++--- src/ast/rewriter/seq_rewriter.h | 14 ++--- src/ast/rewriter/th_rewriter.cpp | 34 +++++----- src/ast/rewriter/th_rewriter.h | 6 +- src/ast/rewriter/var_subst.cpp | 12 ++-- src/ast/rewriter/var_subst.h | 6 +- src/ast/scoped_proof.h | 2 +- src/ast/seq_decl_plugin.cpp | 8 +-- src/ast/seq_decl_plugin.h | 4 +- src/ast/shared_occs.cpp | 6 +- src/ast/shared_occs.h | 4 +- .../simplifier/arith_simplifier_params.cpp | 2 +- src/ast/simplifier/arith_simplifier_params.h | 2 +- .../simplifier/arith_simplifier_plugin.cpp | 8 +-- src/ast/simplifier/arith_simplifier_plugin.h | 8 +-- .../simplifier/array_simplifier_params.cpp | 2 +- src/ast/simplifier/array_simplifier_params.h | 2 +- .../simplifier/array_simplifier_plugin.cpp | 6 +- src/ast/simplifier/array_simplifier_plugin.h | 18 +++--- src/ast/simplifier/base_simplifier.h | 4 +- .../simplifier/basic_simplifier_plugin.cpp | 6 +- src/ast/simplifier/basic_simplifier_plugin.h | 2 +- src/ast/simplifier/bit2int.cpp | 8 +-- src/ast/simplifier/bit2int.h | 10 +-- src/ast/simplifier/bv_elim.cpp | 6 +- src/ast/simplifier/bv_elim.h | 4 +- src/ast/simplifier/bv_simplifier_params.cpp | 2 +- src/ast/simplifier/bv_simplifier_params.h | 2 +- src/ast/simplifier/bv_simplifier_plugin.cpp | 12 ++-- src/ast/simplifier/bv_simplifier_plugin.h | 12 ++-- .../simplifier/datatype_simplifier_plugin.cpp | 2 +- .../simplifier/datatype_simplifier_plugin.h | 4 +- src/ast/simplifier/elim_bounds.cpp | 10 +-- src/ast/simplifier/elim_bounds.h | 6 +- src/ast/simplifier/fpa_simplifier_plugin.cpp | 2 +- src/ast/simplifier/fpa_simplifier_plugin.h | 6 +- src/ast/simplifier/inj_axiom.cpp | 10 +-- src/ast/simplifier/inj_axiom.h | 2 +- src/ast/simplifier/maximise_ac_sharing.cpp | 6 +- src/ast/simplifier/maximise_ac_sharing.h | 8 +-- src/ast/simplifier/poly_simplifier_plugin.cpp | 10 +-- src/ast/simplifier/poly_simplifier_plugin.h | 2 +- src/ast/simplifier/pull_ite_tree.cpp | 8 +-- src/ast/simplifier/pull_ite_tree.h | 10 +-- src/ast/simplifier/push_app_ite.cpp | 4 +- src/ast/simplifier/push_app_ite.h | 4 +- src/ast/simplifier/seq_simplifier_plugin.cpp | 2 +- src/ast/simplifier/seq_simplifier_plugin.h | 6 +- src/ast/simplifier/simplifier.cpp | 12 ++-- src/ast/simplifier/simplifier.h | 10 +-- src/ast/simplifier/simplifier_plugin.cpp | 2 +- src/ast/simplifier/simplifier_plugin.h | 2 +- src/ast/static_features.cpp | 4 +- src/ast/static_features.h | 14 ++--- src/ast/substitution/expr_offset.h | 2 +- src/ast/substitution/expr_offset_map.h | 4 +- src/ast/substitution/matcher.cpp | 2 +- src/ast/substitution/matcher.h | 4 +- src/ast/substitution/substitution.cpp | 8 +-- src/ast/substitution/substitution.h | 6 +- src/ast/substitution/substitution_tree.cpp | 6 +- src/ast/substitution/substitution_tree.h | 4 +- src/ast/substitution/unifier.cpp | 4 +- src/ast/substitution/unifier.h | 4 +- src/ast/substitution/var_offset_map.h | 4 +- src/ast/used_symbols.h | 6 +- src/ast/used_vars.cpp | 2 +- src/ast/used_vars.h | 4 +- src/ast/well_sorted.cpp | 12 ++-- src/cmd_context/basic_cmds.cpp | 26 ++++---- src/cmd_context/check_logic.cpp | 18 +++--- src/cmd_context/check_logic.h | 2 +- src/cmd_context/cmd_context.cpp | 58 ++++++++--------- src/cmd_context/cmd_context.h | 30 ++++----- src/cmd_context/cmd_context_to_goal.cpp | 4 +- src/cmd_context/cmd_util.cpp | 2 +- src/cmd_context/context_params.cpp | 10 +-- src/cmd_context/context_params.h | 2 +- src/cmd_context/echo_tactic.cpp | 6 +- src/cmd_context/eval_cmd.cpp | 12 ++-- src/cmd_context/extra_cmds/dbg_cmds.cpp | 28 ++++----- .../extra_cmds/polynomial_cmds.cpp | 26 ++++---- src/cmd_context/extra_cmds/subpaving_cmds.cpp | 12 ++-- src/cmd_context/interpolant_cmds.cpp | 32 +++++----- src/cmd_context/parametric_cmd.cpp | 4 +- src/cmd_context/parametric_cmd.h | 8 +-- src/cmd_context/pdecl.cpp | 4 +- src/cmd_context/pdecl.h | 8 +-- src/cmd_context/simplify_cmd.cpp | 20 +++--- src/cmd_context/tactic_cmds.cpp | 30 ++++----- src/cmd_context/tactic_cmds.h | 6 +- src/cmd_context/tactic_manager.cpp | 2 +- src/cmd_context/tactic_manager.h | 4 +- src/duality/duality.h | 2 +- src/duality/duality_profiling.cpp | 4 +- src/duality/duality_rpfp.cpp | 4 +- src/duality/duality_solver.cpp | 4 +- src/duality/duality_wrapper.cpp | 16 ++--- src/duality/duality_wrapper.h | 42 ++++++------- src/interp/iz3base.cpp | 4 +- src/interp/iz3base.h | 4 +- src/interp/iz3checker.cpp | 4 +- src/interp/iz3checker.h | 4 +- src/interp/iz3exception.h | 4 +- src/interp/iz3hash.h | 2 +- src/interp/iz3interp.cpp | 12 ++-- src/interp/iz3interp.h | 6 +- src/interp/iz3mgr.cpp | 6 +- src/interp/iz3mgr.h | 38 +++++------ src/interp/iz3pp.cpp | 16 ++--- src/interp/iz3pp.h | 2 +- src/interp/iz3profiling.cpp | 4 +- src/interp/iz3proof.cpp | 4 +- src/interp/iz3proof.h | 4 +- src/interp/iz3proof_itp.cpp | 2 +- src/interp/iz3proof_itp.h | 4 +- src/interp/iz3scopes.cpp | 2 +- src/interp/iz3scopes.h | 2 +- src/interp/iz3secondary.h | 2 +- src/interp/iz3translate.cpp | 10 +-- src/interp/iz3translate.h | 4 +- src/interp/iz3translate_direct.cpp | 8 +-- src/math/automata/automaton.cpp | 2 +- src/math/automata/automaton.h | 6 +- src/math/automata/boolean_algebra.h | 2 +- src/math/automata/symbolic_automata.h | 4 +- src/math/automata/symbolic_automata_def.h | 4 +- src/math/euclid/euclidean_solver.cpp | 6 +- src/math/euclid/euclidean_solver.h | 4 +- src/math/grobner/grobner.cpp | 6 +- src/math/grobner/grobner.h | 12 ++-- src/math/hilbert/heap_trie.h | 10 +-- src/math/hilbert/hilbert_basis.cpp | 10 +-- src/math/hilbert/hilbert_basis.h | 10 +-- src/math/interval/interval.h | 6 +- src/math/interval/interval_def.h | 12 ++-- src/math/interval/interval_mpq.cpp | 2 +- src/math/polynomial/algebraic_numbers.cpp | 20 +++--- src/math/polynomial/algebraic_numbers.h | 20 +++--- src/math/polynomial/polynomial.cpp | 36 +++++------ src/math/polynomial/polynomial.h | 20 +++--- src/math/polynomial/polynomial_cache.cpp | 4 +- src/math/polynomial/polynomial_cache.h | 2 +- src/math/polynomial/polynomial_var2value.h | 4 +- src/math/polynomial/rpolynomial.cpp | 6 +- src/math/polynomial/rpolynomial.h | 12 ++-- src/math/polynomial/sexpr2upolynomial.cpp | 4 +- src/math/polynomial/sexpr2upolynomial.h | 4 +- src/math/polynomial/upolynomial.cpp | 12 ++-- src/math/polynomial/upolynomial.h | 12 ++-- .../polynomial/upolynomial_factorization.cpp | 8 +-- .../polynomial/upolynomial_factorization.h | 8 +-- .../upolynomial_factorization_int.h | 2 +- src/math/realclosure/mpz_matrix.cpp | 4 +- src/math/realclosure/mpz_matrix.h | 2 +- src/math/realclosure/realclosure.cpp | 20 +++--- src/math/realclosure/realclosure.h | 14 ++--- src/math/simplex/model_based_opt.h | 6 +- src/math/simplex/network_flow.h | 6 +- src/math/simplex/network_flow_def.h | 6 +- src/math/simplex/simplex.cpp | 6 +- src/math/simplex/simplex.h | 10 +-- src/math/simplex/sparse_matrix.h | 4 +- src/math/simplex/sparse_matrix_def.h | 4 +- src/math/subpaving/subpaving.cpp | 14 ++--- src/math/subpaving/subpaving.h | 8 +-- src/math/subpaving/subpaving_hwf.cpp | 4 +- src/math/subpaving/subpaving_hwf.h | 6 +- src/math/subpaving/subpaving_mpf.cpp | 4 +- src/math/subpaving/subpaving_mpf.h | 6 +- src/math/subpaving/subpaving_mpff.cpp | 4 +- src/math/subpaving/subpaving_mpff.h | 4 +- src/math/subpaving/subpaving_mpfx.cpp | 4 +- src/math/subpaving/subpaving_mpfx.h | 4 +- src/math/subpaving/subpaving_mpq.cpp | 4 +- src/math/subpaving/subpaving_mpq.h | 4 +- src/math/subpaving/subpaving_t.h | 24 +++---- src/math/subpaving/subpaving_t_def.h | 12 ++-- src/math/subpaving/tactic/expr2subpaving.cpp | 16 ++--- src/math/subpaving/tactic/expr2subpaving.h | 4 +- .../subpaving/tactic/subpaving_tactic.cpp | 20 +++--- src/math/subpaving/tactic/subpaving_tactic.h | 2 +- src/model/func_interp.cpp | 10 +-- src/model/func_interp.h | 4 +- src/model/model.cpp | 16 ++--- src/model/model.h | 6 +- src/model/model2expr.cpp | 8 +-- src/model/model2expr.h | 2 +- src/model/model_core.cpp | 2 +- src/model/model_core.h | 6 +- src/model/model_evaluator.cpp | 32 +++++----- src/model/model_evaluator.h | 6 +- src/model/model_implicant.cpp | 34 +++++----- src/model/model_implicant.h | 16 ++--- src/model/model_pp.cpp | 12 ++-- src/model/model_smt2_pp.cpp | 8 +-- src/model/model_smt2_pp.h | 4 +- src/model/model_v2_pp.cpp | 6 +- src/muz/base/bind_variables.cpp | 2 +- src/muz/base/bind_variables.h | 2 +- src/muz/base/dl_boogie_proof.cpp | 10 +-- src/muz/base/dl_boogie_proof.h | 4 +- src/muz/base/dl_context.cpp | 18 +++--- src/muz/base/dl_context.h | 40 ++++++------ src/muz/base/dl_costs.cpp | 10 +-- src/muz/base/dl_costs.h | 2 +- src/muz/base/dl_engine_base.h | 2 +- src/muz/base/dl_rule.cpp | 40 ++++++------ src/muz/base/dl_rule.h | 26 ++++---- src/muz/base/dl_rule_set.cpp | 6 +- src/muz/base/dl_rule_set.h | 4 +- src/muz/base/dl_rule_subsumption_index.cpp | 4 +- src/muz/base/dl_rule_subsumption_index.h | 2 +- src/muz/base/dl_rule_transformer.cpp | 6 +- src/muz/base/dl_rule_transformer.h | 8 +-- src/muz/base/dl_util.cpp | 16 ++--- src/muz/base/dl_util.h | 22 +++---- src/muz/base/hnf.cpp | 28 ++++----- src/muz/base/hnf.h | 8 +-- src/muz/base/proof_utils.cpp | 8 +-- src/muz/base/rule_properties.cpp | 10 +-- src/muz/base/rule_properties.h | 8 +-- src/muz/bmc/dl_bmc_engine.cpp | 30 ++++----- src/muz/bmc/dl_bmc_engine.h | 10 +-- src/muz/clp/clp_context.cpp | 14 ++--- src/muz/clp/clp_context.h | 8 +-- src/muz/dataflow/dataflow.cpp | 4 +- src/muz/dataflow/dataflow.h | 8 +-- src/muz/dataflow/reachability.h | 2 +- src/muz/ddnf/ddnf.cpp | 12 ++-- src/muz/ddnf/ddnf.h | 8 +-- src/muz/duality/duality_dl_interface.cpp | 42 ++++++------- src/muz/duality/duality_dl_interface.h | 10 +-- src/muz/fp/datalog_parser.cpp | 14 ++--- src/muz/fp/datalog_parser.h | 4 +- src/muz/fp/dl_cmds.cpp | 30 ++++----- src/muz/fp/dl_cmds.h | 2 +- src/muz/fp/dl_register_engine.cpp | 16 ++--- src/muz/fp/dl_register_engine.h | 2 +- src/muz/fp/horn_tactic.cpp | 26 ++++---- src/muz/fp/horn_tactic.h | 2 +- src/muz/pdr/pdr_closure.cpp | 8 +-- src/muz/pdr/pdr_closure.h | 2 +- src/muz/pdr/pdr_context.cpp | 50 +++++++-------- src/muz/pdr/pdr_context.h | 6 +- src/muz/pdr/pdr_dl_interface.cpp | 26 ++++---- src/muz/pdr/pdr_dl_interface.h | 12 ++-- src/muz/pdr/pdr_farkas_learner.cpp | 30 ++++----- src/muz/pdr/pdr_farkas_learner.h | 16 ++--- src/muz/pdr/pdr_generalizers.cpp | 14 ++--- src/muz/pdr/pdr_generalizers.h | 6 +- src/muz/pdr/pdr_manager.cpp | 18 +++--- src/muz/pdr/pdr_manager.h | 22 +++---- src/muz/pdr/pdr_prop_solver.cpp | 24 +++---- src/muz/pdr/pdr_prop_solver.h | 14 ++--- src/muz/pdr/pdr_reachable_cache.cpp | 2 +- src/muz/pdr/pdr_reachable_cache.h | 8 +-- src/muz/pdr/pdr_smt_context_manager.cpp | 10 +-- src/muz/pdr/pdr_smt_context_manager.h | 6 +- src/muz/pdr/pdr_sym_mux.cpp | 14 ++--- src/muz/pdr/pdr_sym_mux.h | 6 +- src/muz/pdr/pdr_util.cpp | 46 +++++++------- src/muz/pdr/pdr_util.h | 20 +++--- src/muz/rel/aig_exporter.cpp | 4 +- src/muz/rel/aig_exporter.h | 6 +- src/muz/rel/check_relation.cpp | 8 +-- src/muz/rel/check_relation.h | 4 +- src/muz/rel/dl_base.cpp | 14 ++--- src/muz/rel/dl_base.h | 12 ++-- src/muz/rel/dl_bound_relation.cpp | 6 +- src/muz/rel/dl_bound_relation.h | 16 ++--- src/muz/rel/dl_check_table.cpp | 4 +- src/muz/rel/dl_check_table.h | 6 +- src/muz/rel/dl_compiler.cpp | 16 ++--- src/muz/rel/dl_compiler.h | 18 +++--- src/muz/rel/dl_external_relation.cpp | 10 +-- src/muz/rel/dl_external_relation.h | 2 +- src/muz/rel/dl_finite_product_relation.cpp | 10 +-- src/muz/rel/dl_finite_product_relation.h | 6 +- src/muz/rel/dl_instruction.cpp | 16 ++--- src/muz/rel/dl_instruction.h | 10 +-- src/muz/rel/dl_interval_relation.cpp | 12 ++-- src/muz/rel/dl_interval_relation.h | 14 ++--- src/muz/rel/dl_lazy_table.cpp | 4 +- src/muz/rel/dl_lazy_table.h | 4 +- src/muz/rel/dl_mk_explanations.cpp | 12 ++-- src/muz/rel/dl_mk_explanations.h | 4 +- src/muz/rel/dl_mk_similarity_compressor.cpp | 4 +- src/muz/rel/dl_mk_similarity_compressor.h | 10 +-- src/muz/rel/dl_mk_simple_joins.cpp | 8 +-- src/muz/rel/dl_mk_simple_joins.h | 10 +-- src/muz/rel/dl_product_relation.cpp | 10 +-- src/muz/rel/dl_product_relation.h | 4 +- src/muz/rel/dl_relation_manager.cpp | 16 ++--- src/muz/rel/dl_relation_manager.h | 6 +- src/muz/rel/dl_sieve_relation.cpp | 4 +- src/muz/rel/dl_sieve_relation.h | 4 +- src/muz/rel/dl_sparse_table.cpp | 6 +- src/muz/rel/dl_sparse_table.h | 16 ++--- src/muz/rel/dl_table.cpp | 8 +-- src/muz/rel/dl_table.h | 22 +++---- src/muz/rel/dl_table_plugin.h | 6 +- src/muz/rel/dl_table_relation.cpp | 6 +- src/muz/rel/dl_table_relation.h | 4 +- src/muz/rel/dl_vector_relation.h | 6 +- src/muz/rel/doc.cpp | 12 ++-- src/muz/rel/doc.h | 6 +- src/muz/rel/karr_relation.cpp | 6 +- src/muz/rel/karr_relation.h | 4 +- src/muz/rel/rel_context.cpp | 60 +++++++++--------- src/muz/rel/rel_context.h | 12 ++-- src/muz/rel/tbv.cpp | 6 +- src/muz/rel/tbv.h | 6 +- src/muz/rel/udoc_relation.cpp | 8 +-- src/muz/rel/udoc_relation.h | 4 +- src/muz/tab/tab_context.cpp | 28 ++++----- src/muz/tab/tab_context.h | 8 +-- src/muz/transforms/dl_mk_array_blast.cpp | 6 +- src/muz/transforms/dl_mk_array_blast.h | 14 ++--- src/muz/transforms/dl_mk_backwards.cpp | 4 +- src/muz/transforms/dl_mk_backwards.h | 2 +- src/muz/transforms/dl_mk_bit_blast.cpp | 18 +++--- src/muz/transforms/dl_mk_bit_blast.h | 2 +- src/muz/transforms/dl_mk_coalesce.cpp | 4 +- src/muz/transforms/dl_mk_coalesce.h | 10 +-- src/muz/transforms/dl_mk_coi_filter.cpp | 10 +-- src/muz/transforms/dl_mk_coi_filter.h | 4 +- src/muz/transforms/dl_mk_different.h | 2 +- src/muz/transforms/dl_mk_filter_rules.cpp | 8 +-- src/muz/transforms/dl_mk_filter_rules.h | 6 +- .../dl_mk_interp_tail_simplifier.cpp | 14 ++--- .../transforms/dl_mk_interp_tail_simplifier.h | 10 +-- src/muz/transforms/dl_mk_karr_invariants.cpp | 12 ++-- src/muz/transforms/dl_mk_karr_invariants.h | 10 +-- src/muz/transforms/dl_mk_loop_counter.cpp | 4 +- src/muz/transforms/dl_mk_loop_counter.h | 4 +- src/muz/transforms/dl_mk_magic_sets.cpp | 4 +- src/muz/transforms/dl_mk_magic_sets.h | 10 +-- src/muz/transforms/dl_mk_magic_symbolic.cpp | 4 +- src/muz/transforms/dl_mk_magic_symbolic.h | 2 +- .../dl_mk_quantifier_abstraction.cpp | 8 +-- .../transforms/dl_mk_quantifier_abstraction.h | 4 +- .../dl_mk_quantifier_instantiation.cpp | 6 +- .../dl_mk_quantifier_instantiation.h | 6 +- src/muz/transforms/dl_mk_rule_inliner.cpp | 8 +-- src/muz/transforms/dl_mk_rule_inliner.h | 12 ++-- src/muz/transforms/dl_mk_scale.cpp | 4 +- src/muz/transforms/dl_mk_scale.h | 4 +- .../dl_mk_separate_negated_tails.cpp | 4 +- .../transforms/dl_mk_separate_negated_tails.h | 4 +- src/muz/transforms/dl_mk_slice.cpp | 12 ++-- src/muz/transforms/dl_mk_slice.h | 8 +-- .../transforms/dl_mk_subsumption_checker.cpp | 8 +-- .../transforms/dl_mk_subsumption_checker.h | 6 +- .../transforms/dl_mk_unbound_compressor.cpp | 2 +- src/muz/transforms/dl_mk_unbound_compressor.h | 10 +-- src/muz/transforms/dl_mk_unfold.cpp | 2 +- src/muz/transforms/dl_mk_unfold.h | 10 +-- src/muz/transforms/dl_transforms.cpp | 28 ++++----- src/muz/transforms/dl_transforms.h | 2 +- src/nlsat/nlsat_assignment.h | 4 +- src/nlsat/nlsat_clause.cpp | 2 +- src/nlsat/nlsat_clause.h | 4 +- src/nlsat/nlsat_evaluator.cpp | 4 +- src/nlsat/nlsat_evaluator.h | 6 +- src/nlsat/nlsat_explain.cpp | 10 +-- src/nlsat/nlsat_explain.h | 8 +-- src/nlsat/nlsat_interval_set.cpp | 6 +- src/nlsat/nlsat_interval_set.h | 2 +- src/nlsat/nlsat_justification.h | 4 +- src/nlsat/nlsat_scoped_literal_vector.h | 2 +- src/nlsat/nlsat_solver.cpp | 26 ++++---- src/nlsat/nlsat_solver.h | 8 +-- src/nlsat/nlsat_types.cpp | 8 +-- src/nlsat/nlsat_types.h | 8 +-- src/nlsat/tactic/goal2nlsat.cpp | 22 +++---- src/nlsat/tactic/goal2nlsat.h | 4 +- src/nlsat/tactic/nlsat_tactic.cpp | 20 +++--- src/nlsat/tactic/nlsat_tactic.h | 2 +- src/nlsat/tactic/qfnra_nlsat_tactic.cpp | 22 +++---- src/nlsat/tactic/qfnra_nlsat_tactic.h | 2 +- src/opt/maxres.cpp | 22 +++---- src/opt/maxsmt.cpp | 20 +++--- src/opt/maxsmt.h | 18 +++--- src/opt/mss.cpp | 8 +-- src/opt/opt_cmds.cpp | 18 +++--- src/opt/opt_cmds.h | 4 +- src/opt/opt_context.cpp | 50 +++++++-------- src/opt/opt_context.h | 22 +++---- src/opt/opt_pareto.cpp | 6 +- src/opt/opt_pareto.h | 4 +- src/opt/opt_sls_solver.h | 10 +-- src/opt/opt_solver.cpp | 24 +++---- src/opt/opt_solver.h | 20 +++--- src/opt/optsmt.cpp | 16 ++--- src/opt/optsmt.h | 2 +- src/opt/pb_sls.cpp | 10 +-- src/opt/pb_sls.h | 10 +-- src/opt/sortmax.cpp | 18 +++--- src/opt/wmax.cpp | 16 ++--- src/opt/wmax.h | 2 +- src/parsers/smt/smtlib.cpp | 6 +- src/parsers/smt/smtlib.h | 8 +-- src/parsers/smt/smtlib_solver.cpp | 22 +++---- src/parsers/smt/smtlib_solver.h | 6 +- src/parsers/smt/smtparser.cpp | 34 +++++----- src/parsers/smt/smtparser.h | 6 +- src/parsers/smt2/smt2parser.cpp | 26 ++++---- src/parsers/smt2/smt2parser.h | 2 +- src/parsers/smt2/smt2scanner.cpp | 2 +- src/parsers/smt2/smt2scanner.h | 8 +-- src/parsers/util/cost_parser.cpp | 2 +- src/parsers/util/cost_parser.h | 4 +- src/parsers/util/pattern_validation.cpp | 8 +-- src/parsers/util/pattern_validation.h | 6 +- src/parsers/util/scanner.cpp | 2 +- src/parsers/util/scanner.h | 2 +- src/parsers/util/simple_parser.cpp | 6 +- src/parsers/util/simple_parser.h | 4 +- src/qe/nlarith_util.cpp | 18 +++--- src/qe/nlarith_util.h | 4 +- src/qe/nlqsat.cpp | 32 +++++----- src/qe/nlqsat.h | 2 +- src/qe/qe.cpp | 54 ++++++++-------- src/qe/qe.h | 18 +++--- src/qe/qe_arith.cpp | 22 +++---- src/qe/qe_arith.h | 6 +- src/qe/qe_arith_plugin.cpp | 30 ++++----- src/qe/qe_array_plugin.cpp | 10 +-- src/qe/qe_arrays.cpp | 14 ++--- src/qe/qe_arrays.h | 4 +- src/qe/qe_bool_plugin.cpp | 8 +-- src/qe/qe_bv_plugin.cpp | 8 +-- src/qe/qe_cmd.cpp | 8 +-- src/qe/qe_datatype_plugin.cpp | 14 ++--- src/qe/qe_datatypes.cpp | 16 ++--- src/qe/qe_datatypes.h | 4 +- src/qe/qe_dl_plugin.cpp | 10 +-- src/qe/qe_lite.cpp | 38 +++++------ src/qe/qe_lite.h | 6 +- src/qe/qe_mbp.cpp | 24 +++---- src/qe/qe_mbp.h | 8 +-- src/qe/qe_sat_tactic.cpp | 20 +++--- src/qe/qe_sat_tactic.h | 2 +- src/qe/qe_tactic.cpp | 8 +-- src/qe/qe_tactic.h | 2 +- src/qe/qe_vartest.h | 4 +- src/qe/qsat.cpp | 34 +++++----- src/qe/qsat.h | 6 +- src/qe/vsubst_tactic.cpp | 12 ++-- src/qe/vsubst_tactic.h | 2 +- src/sat/dimacs.cpp | 4 +- src/sat/dimacs.h | 2 +- src/sat/sat_asymm_branch.cpp | 8 +-- src/sat/sat_asymm_branch.h | 6 +- src/sat/sat_clause.cpp | 6 +- src/sat/sat_clause.h | 8 +-- src/sat/sat_clause_set.cpp | 2 +- src/sat/sat_clause_set.h | 2 +- src/sat/sat_clause_use_list.cpp | 4 +- src/sat/sat_clause_use_list.h | 4 +- src/sat/sat_cleaner.cpp | 8 +-- src/sat/sat_cleaner.h | 4 +- src/sat/sat_config.cpp | 4 +- src/sat/sat_config.h | 2 +- src/sat/sat_elim_eqs.cpp | 6 +- src/sat/sat_elim_eqs.h | 2 +- src/sat/sat_extension.h | 4 +- src/sat/sat_iff3_finder.cpp | 4 +- src/sat/sat_iff3_finder.h | 2 +- src/sat/sat_integrity_checker.cpp | 6 +- src/sat/sat_integrity_checker.h | 2 +- src/sat/sat_model_converter.cpp | 6 +- src/sat/sat_model_converter.h | 2 +- src/sat/sat_mus.cpp | 4 +- src/sat/sat_par.cpp | 2 +- src/sat/sat_par.h | 6 +- src/sat/sat_probing.cpp | 4 +- src/sat/sat_probing.h | 6 +- src/sat/sat_scc.cpp | 10 +-- src/sat/sat_scc.h | 6 +- src/sat/sat_simplifier.cpp | 8 +-- src/sat/sat_simplifier.h | 18 +++--- src/sat/sat_solver.cpp | 10 +-- src/sat/sat_solver.h | 40 ++++++------ src/sat/sat_solver/inc_sat_solver.cpp | 36 +++++------ src/sat/sat_solver/inc_sat_solver.h | 2 +- src/sat/sat_types.h | 12 ++-- src/sat/sat_var_queue.h | 4 +- src/sat/sat_watched.cpp | 4 +- src/sat/sat_watched.h | 4 +- src/sat/tactic/atom2bool_var.cpp | 8 +-- src/sat/tactic/atom2bool_var.h | 4 +- src/sat/tactic/goal2sat.cpp | 20 +++--- src/sat/tactic/goal2sat.h | 8 +-- src/sat/tactic/sat_tactic.cpp | 12 ++-- src/sat/tactic/sat_tactic.h | 2 +- src/shell/datalog_frontend.cpp | 24 +++---- src/shell/dimacs_frontend.cpp | 10 +-- src/shell/lp_frontend.cpp | 10 +-- src/shell/main.cpp | 34 +++++----- src/shell/opt_frontend.cpp | 12 ++-- src/shell/smtlib_frontend.cpp | 22 +++---- src/shell/z3_log_frontend.cpp | 6 +- src/smt/arith_eq_adapter.cpp | 14 ++--- src/smt/arith_eq_adapter.h | 10 +-- src/smt/arith_eq_solver.cpp | 2 +- src/smt/arith_eq_solver.h | 4 +- src/smt/asserted_formulas.cpp | 50 +++++++-------- src/smt/asserted_formulas.h | 22 +++---- src/smt/cached_var_subst.cpp | 2 +- src/smt/cached_var_subst.h | 6 +- src/smt/cost_evaluator.cpp | 4 +- src/smt/cost_evaluator.h | 4 +- src/smt/diff_logic.h | 12 ++-- src/smt/dyn_ack.cpp | 6 +- src/smt/dyn_ack.h | 12 ++-- src/smt/elim_term_ite.cpp | 4 +- src/smt/elim_term_ite.h | 4 +- src/smt/expr_context_simplifier.cpp | 10 +-- src/smt/expr_context_simplifier.h | 12 ++-- src/smt/fingerprints.cpp | 2 +- src/smt/fingerprints.h | 2 +- src/smt/mam.cpp | 16 ++--- src/smt/mam.h | 4 +- src/smt/old_interval.cpp | 2 +- src/smt/old_interval.h | 4 +- src/smt/params/dyn_ack_params.cpp | 2 +- src/smt/params/dyn_ack_params.h | 2 +- src/smt/params/preprocessor_params.cpp | 2 +- src/smt/params/preprocessor_params.h | 8 +-- src/smt/params/qi_params.cpp | 2 +- src/smt/params/qi_params.h | 4 +- src/smt/params/smt_params.cpp | 4 +- src/smt/params/smt_params.h | 22 +++---- src/smt/params/theory_arith_params.cpp | 2 +- src/smt/params/theory_arith_params.h | 2 +- src/smt/params/theory_array_params.cpp | 2 +- src/smt/params/theory_array_params.h | 2 +- src/smt/params/theory_bv_params.cpp | 2 +- src/smt/params/theory_bv_params.h | 2 +- src/smt/params/theory_pb_params.cpp | 2 +- src/smt/params/theory_pb_params.h | 2 +- src/smt/params/theory_str_params.cpp | 2 +- src/smt/params/theory_str_params.h | 2 +- src/smt/proto_model/array_factory.cpp | 10 +-- src/smt/proto_model/array_factory.h | 2 +- src/smt/proto_model/datatype_factory.cpp | 10 +-- src/smt/proto_model/datatype_factory.h | 4 +- src/smt/proto_model/numeral_factory.cpp | 4 +- src/smt/proto_model/numeral_factory.h | 6 +- src/smt/proto_model/proto_model.cpp | 20 +++--- src/smt/proto_model/proto_model.h | 18 +++--- src/smt/proto_model/struct_factory.cpp | 4 +- src/smt/proto_model/struct_factory.h | 4 +- src/smt/proto_model/value_factory.cpp | 2 +- src/smt/proto_model/value_factory.h | 4 +- src/smt/qi_queue.cpp | 14 ++--- src/smt/qi_queue.h | 20 +++--- src/smt/smt2_extra_cmds.cpp | 6 +- src/smt/smt_almost_cg_table.cpp | 2 +- src/smt/smt_almost_cg_table.h | 4 +- src/smt/smt_b_justification.h | 4 +- src/smt/smt_bool_var_data.h | 2 +- src/smt/smt_case_split_queue.cpp | 16 ++--- src/smt/smt_case_split_queue.h | 6 +- src/smt/smt_cg_table.cpp | 6 +- src/smt/smt_cg_table.h | 6 +- src/smt/smt_checker.cpp | 6 +- src/smt/smt_checker.h | 4 +- src/smt/smt_clause.cpp | 6 +- src/smt/smt_clause.h | 10 +-- src/smt/smt_conflict_resolution.cpp | 8 +-- src/smt/smt_conflict_resolution.h | 22 +++---- src/smt/smt_consequences.cpp | 12 ++-- src/smt/smt_context.cpp | 40 ++++++------ src/smt/smt_context.h | 60 +++++++++--------- src/smt/smt_context_inv.cpp | 8 +-- src/smt/smt_context_pp.cpp | 10 +-- src/smt/smt_context_stat.cpp | 4 +- src/smt/smt_enode.cpp | 4 +- src/smt/smt_enode.h | 10 +-- src/smt/smt_eq_justification.h | 4 +- src/smt/smt_farkas_util.cpp | 8 +-- src/smt/smt_farkas_util.h | 2 +- src/smt/smt_for_each_relevant_expr.cpp | 8 +-- src/smt/smt_for_each_relevant_expr.h | 6 +- src/smt/smt_implied_equalities.cpp | 20 +++--- src/smt/smt_implied_equalities.h | 6 +- src/smt/smt_internalizer.cpp | 14 ++--- src/smt/smt_justification.cpp | 8 +-- src/smt/smt_justification.h | 8 +-- src/smt/smt_kernel.cpp | 6 +- src/smt/smt_kernel.h | 12 ++-- src/smt/smt_literal.cpp | 6 +- src/smt/smt_literal.h | 6 +- src/smt/smt_model_checker.cpp | 20 +++--- src/smt/smt_model_checker.h | 10 +-- src/smt/smt_model_finder.cpp | 40 ++++++------ src/smt/smt_model_finder.h | 12 ++-- src/smt/smt_model_generator.cpp | 16 ++--- src/smt/smt_model_generator.h | 8 +-- src/smt/smt_quantifier.cpp | 18 +++--- src/smt/smt_quantifier.h | 8 +-- src/smt/smt_quantifier_stat.cpp | 2 +- src/smt/smt_quantifier_stat.h | 8 +-- src/smt/smt_quick_checker.cpp | 6 +- src/smt/smt_quick_checker.h | 6 +- src/smt/smt_relevancy.cpp | 10 +-- src/smt/smt_relevancy.h | 2 +- src/smt/smt_setup.cpp | 38 +++++------ src/smt/smt_setup.h | 4 +- src/smt/smt_solver.cpp | 18 +++--- src/smt/smt_solver.h | 4 +- src/smt/smt_statistics.cpp | 2 +- src/smt/smt_theory.cpp | 6 +- src/smt/smt_theory.h | 6 +- src/smt/smt_theory_var_list.h | 2 +- src/smt/smt_types.h | 6 +- src/smt/smt_value_sort.cpp | 8 +-- src/smt/smt_value_sort.h | 2 +- src/smt/spanning_tree.h | 4 +- src/smt/spanning_tree_base.h | 4 +- src/smt/spanning_tree_def.h | 2 +- src/smt/tactic/ctx_solver_simplify_tactic.cpp | 14 ++--- src/smt/tactic/ctx_solver_simplify_tactic.h | 2 +- src/smt/tactic/smt_tactic.cpp | 22 +++---- src/smt/tactic/smt_tactic.h | 8 +-- src/smt/tactic/unit_subsumption_tactic.cpp | 4 +- src/smt/tactic/unit_subsumption_tactic.h | 2 +- src/smt/theory_arith.cpp | 2 +- src/smt/theory_arith.h | 36 +++++------ src/smt/theory_arith_aux.h | 10 +-- src/smt/theory_arith_core.h | 12 ++-- src/smt/theory_arith_def.h | 16 ++--- src/smt/theory_arith_eq.h | 2 +- src/smt/theory_arith_int.h | 12 ++-- src/smt/theory_arith_inv.h | 4 +- src/smt/theory_arith_nl.h | 2 +- src/smt/theory_arith_pp.h | 6 +- src/smt/theory_array.cpp | 8 +-- src/smt/theory_array.h | 6 +- src/smt/theory_array_base.cpp | 14 ++--- src/smt/theory_array_base.h | 6 +- src/smt/theory_array_full.cpp | 12 ++-- src/smt/theory_array_full.h | 6 +- src/smt/theory_bv.cpp | 12 ++-- src/smt/theory_bv.h | 20 +++--- src/smt/theory_datatype.cpp | 14 ++--- src/smt/theory_datatype.h | 10 +-- src/smt/theory_dense_diff_logic.cpp | 2 +- src/smt/theory_dense_diff_logic.h | 10 +-- src/smt/theory_dense_diff_logic_def.h | 12 ++-- src/smt/theory_diff_logic.cpp | 8 +-- src/smt/theory_diff_logic.h | 36 +++++------ src/smt/theory_diff_logic_def.h | 14 ++--- src/smt/theory_dl.cpp | 16 ++--- src/smt/theory_dummy.cpp | 4 +- src/smt/theory_dummy.h | 2 +- src/smt/theory_fpa.cpp | 12 ++-- src/smt/theory_fpa.h | 14 ++--- src/smt/theory_lra.h | 2 +- src/smt/theory_opt.cpp | 8 +-- src/smt/theory_opt.h | 6 +- src/smt/theory_pb.cpp | 18 +++--- src/smt/theory_pb.h | 10 +-- src/smt/theory_seq.cpp | 14 ++--- src/smt/theory_seq.h | 20 +++--- src/smt/theory_seq_empty.h | 4 +- src/smt/theory_str.cpp | 18 +++--- src/smt/theory_str.h | 18 +++--- src/smt/theory_utvpi.cpp | 4 +- src/smt/theory_utvpi.h | 2 +- src/smt/theory_utvpi_def.h | 8 +-- src/smt/theory_wmaxsat.cpp | 8 +-- src/smt/theory_wmaxsat.h | 6 +- src/smt/uses_theory.cpp | 4 +- src/smt/uses_theory.h | 2 +- src/smt/watch_list.cpp | 2 +- src/smt/watch_list.h | 4 +- src/solver/check_sat_result.cpp | 2 +- src/solver/check_sat_result.h | 6 +- src/solver/combined_solver.cpp | 6 +- src/solver/combined_solver.h | 2 +- src/solver/mus.cpp | 10 +-- src/solver/smt_logics.cpp | 4 +- src/solver/solver.cpp | 12 ++-- src/solver/solver.h | 6 +- src/solver/solver2tactic.cpp | 10 +-- src/solver/solver2tactic.h | 4 +- src/solver/solver_na2as.cpp | 4 +- src/solver/solver_na2as.h | 2 +- src/solver/tactic2solver.cpp | 8 +-- src/solver/tactic2solver.h | 2 +- src/tactic/aig/aig.cpp | 8 +-- src/tactic/aig/aig.h | 4 +- src/tactic/aig/aig_tactic.cpp | 4 +- src/tactic/aig/aig_tactic.h | 2 +- src/tactic/arith/add_bounds_tactic.cpp | 8 +-- src/tactic/arith/add_bounds_tactic.h | 2 +- src/tactic/arith/arith_bounds_tactic.cpp | 4 +- src/tactic/arith/arith_bounds_tactic.h | 2 +- src/tactic/arith/bound_manager.cpp | 6 +- src/tactic/arith/bound_manager.h | 4 +- src/tactic/arith/bound_propagator.cpp | 2 +- src/tactic/arith/bound_propagator.h | 12 ++-- src/tactic/arith/bv2int_rewriter.cpp | 8 +-- src/tactic/arith/bv2int_rewriter.h | 12 ++-- src/tactic/arith/bv2real_rewriter.cpp | 8 +-- src/tactic/arith/bv2real_rewriter.h | 8 +-- src/tactic/arith/card2bv_tactic.cpp | 16 ++--- src/tactic/arith/card2bv_tactic.h | 10 +-- src/tactic/arith/degree_shift_tactic.cpp | 16 ++--- src/tactic/arith/degree_shift_tactic.h | 2 +- src/tactic/arith/diff_neq_tactic.cpp | 8 +-- src/tactic/arith/diff_neq_tactic.h | 2 +- src/tactic/arith/elim01_tactic.cpp | 18 +++--- src/tactic/arith/elim01_tactic.h | 2 +- src/tactic/arith/eq2bv_tactic.cpp | 18 +++--- src/tactic/arith/eq2bv_tactic.h | 2 +- src/tactic/arith/factor_tactic.cpp | 6 +- src/tactic/arith/factor_tactic.h | 2 +- src/tactic/arith/fix_dl_var_tactic.cpp | 12 ++-- src/tactic/arith/fix_dl_var_tactic.h | 2 +- src/tactic/arith/fm_tactic.cpp | 22 +++---- src/tactic/arith/fm_tactic.h | 2 +- src/tactic/arith/lia2card_tactic.cpp | 18 +++--- src/tactic/arith/lia2card_tactic.h | 2 +- src/tactic/arith/lia2pb_tactic.cpp | 18 +++--- src/tactic/arith/lia2pb_tactic.h | 2 +- src/tactic/arith/linear_equation.cpp | 2 +- src/tactic/arith/linear_equation.h | 8 +-- src/tactic/arith/nla2bv_tactic.cpp | 26 ++++---- src/tactic/arith/nla2bv_tactic.h | 2 +- src/tactic/arith/normalize_bounds_tactic.cpp | 16 ++--- src/tactic/arith/normalize_bounds_tactic.h | 2 +- src/tactic/arith/pb2bv_model_converter.cpp | 8 +-- src/tactic/arith/pb2bv_model_converter.h | 4 +- src/tactic/arith/pb2bv_tactic.cpp | 28 ++++----- src/tactic/arith/pb2bv_tactic.h | 2 +- src/tactic/arith/probe_arith.cpp | 10 +-- src/tactic/arith/propagate_ineqs_tactic.cpp | 10 +-- src/tactic/arith/propagate_ineqs_tactic.h | 2 +- src/tactic/arith/purify_arith_tactic.cpp | 22 +++---- src/tactic/arith/purify_arith_tactic.h | 2 +- src/tactic/arith/recover_01_tactic.cpp | 16 ++--- src/tactic/arith/recover_01_tactic.h | 2 +- src/tactic/bv/bit_blaster_model_converter.cpp | 10 +-- src/tactic/bv/bit_blaster_model_converter.h | 2 +- src/tactic/bv/bit_blaster_tactic.cpp | 12 ++-- src/tactic/bv/bit_blaster_tactic.h | 4 +- src/tactic/bv/bv1_blaster_tactic.cpp | 14 ++--- src/tactic/bv/bv1_blaster_tactic.h | 2 +- src/tactic/bv/bv_bound_chk_tactic.cpp | 14 ++--- src/tactic/bv/bv_bound_chk_tactic.h | 6 +- src/tactic/bv/bv_bounds_tactic.cpp | 8 +-- src/tactic/bv/bv_bounds_tactic.h | 2 +- src/tactic/bv/bv_size_reduction_tactic.cpp | 12 ++-- src/tactic/bv/bv_size_reduction_tactic.h | 2 +- src/tactic/bv/bvarray2uf_rewriter.cpp | 16 ++--- src/tactic/bv/bvarray2uf_rewriter.h | 6 +- src/tactic/bv/bvarray2uf_tactic.cpp | 16 ++--- src/tactic/bv/bvarray2uf_tactic.h | 2 +- src/tactic/bv/dt2bv_tactic.cpp | 24 +++---- src/tactic/bv/dt2bv_tactic.h | 4 +- src/tactic/bv/elim_small_bv_tactic.cpp | 24 +++---- src/tactic/bv/elim_small_bv_tactic.h | 2 +- src/tactic/bv/max_bv_sharing_tactic.cpp | 12 ++-- src/tactic/bv/max_bv_sharing_tactic.h | 2 +- src/tactic/converter.h | 6 +- src/tactic/core/blast_term_ite_tactic.cpp | 12 ++-- src/tactic/core/blast_term_ite_tactic.h | 2 +- src/tactic/core/cofactor_elim_term_ite.cpp | 16 ++--- src/tactic/core/cofactor_elim_term_ite.h | 4 +- src/tactic/core/cofactor_term_ite_tactic.cpp | 4 +- src/tactic/core/cofactor_term_ite_tactic.h | 2 +- src/tactic/core/collect_occs.cpp | 8 +-- src/tactic/core/collect_statistics_tactic.cpp | 20 +++--- src/tactic/core/collect_statistics_tactic.h | 2 +- src/tactic/core/ctx_simplify_tactic.cpp | 10 +-- src/tactic/core/ctx_simplify_tactic.h | 4 +- src/tactic/core/der_tactic.cpp | 4 +- src/tactic/core/distribute_forall_tactic.cpp | 6 +- src/tactic/core/distribute_forall_tactic.h | 2 +- src/tactic/core/elim_term_ite_tactic.cpp | 10 +-- src/tactic/core/elim_term_ite_tactic.h | 2 +- src/tactic/core/elim_uncnstr_tactic.cpp | 24 +++---- src/tactic/core/elim_uncnstr_tactic.h | 2 +- src/tactic/core/nnf_tactic.cpp | 6 +- src/tactic/core/nnf_tactic.h | 2 +- src/tactic/core/occf_tactic.cpp | 8 +-- src/tactic/core/occf_tactic.h | 2 +- src/tactic/core/pb_preprocess_tactic.cpp | 14 ++--- src/tactic/core/pb_preprocess_tactic.h | 2 +- src/tactic/core/propagate_values_tactic.cpp | 12 ++-- src/tactic/core/propagate_values_tactic.h | 2 +- src/tactic/core/reduce_args_tactic.cpp | 16 ++--- src/tactic/core/reduce_args_tactic.h | 2 +- src/tactic/core/simplify_tactic.cpp | 6 +- src/tactic/core/simplify_tactic.h | 4 +- src/tactic/core/solve_eqs_tactic.cpp | 14 ++--- src/tactic/core/solve_eqs_tactic.h | 2 +- src/tactic/core/split_clause_tactic.cpp | 4 +- src/tactic/core/split_clause_tactic.h | 2 +- src/tactic/core/symmetry_reduce_tactic.cpp | 12 ++-- src/tactic/core/symmetry_reduce_tactic.h | 2 +- src/tactic/core/tseitin_cnf_tactic.cpp | 12 ++-- src/tactic/core/tseitin_cnf_tactic.h | 2 +- src/tactic/equiv_proof_converter.cpp | 6 +- src/tactic/equiv_proof_converter.h | 2 +- src/tactic/extension_model_converter.cpp | 10 +-- src/tactic/extension_model_converter.h | 4 +- src/tactic/filter_model_converter.cpp | 4 +- src/tactic/filter_model_converter.h | 2 +- src/tactic/fpa/fpa2bv_model_converter.cpp | 6 +- src/tactic/fpa/fpa2bv_model_converter.h | 6 +- src/tactic/fpa/fpa2bv_tactic.cpp | 10 +-- src/tactic/fpa/fpa2bv_tactic.h | 2 +- src/tactic/fpa/qffp_tactic.cpp | 22 +++---- src/tactic/fpa/qffp_tactic.h | 2 +- src/tactic/goal.cpp | 10 +-- src/tactic/goal.h | 14 ++--- src/tactic/goal_num_occurs.cpp | 4 +- src/tactic/goal_num_occurs.h | 2 +- src/tactic/goal_shared_occs.cpp | 2 +- src/tactic/goal_shared_occs.h | 4 +- src/tactic/goal_util.cpp | 4 +- src/tactic/horn_subsume_model_converter.cpp | 16 ++--- src/tactic/horn_subsume_model_converter.h | 4 +- src/tactic/model_converter.cpp | 4 +- src/tactic/model_converter.h | 6 +- src/tactic/nlsat_smt/nl_purify_tactic.cpp | 32 +++++----- src/tactic/nlsat_smt/nl_purify_tactic.h | 2 +- .../portfolio/bounded_int2bv_solver.cpp | 26 ++++---- src/tactic/portfolio/bounded_int2bv_solver.h | 4 +- src/tactic/portfolio/default_tactic.cpp | 30 ++++----- src/tactic/portfolio/default_tactic.h | 2 +- src/tactic/portfolio/enum2bv_solver.cpp | 20 +++--- src/tactic/portfolio/enum2bv_solver.h | 4 +- src/tactic/portfolio/fd_solver.cpp | 12 ++-- src/tactic/portfolio/fd_solver.h | 4 +- src/tactic/portfolio/pb2bv_solver.cpp | 14 ++--- src/tactic/portfolio/pb2bv_solver.h | 4 +- src/tactic/portfolio/smt_strategic_solver.cpp | 48 +++++++------- src/tactic/probe.cpp | 10 +-- src/tactic/probe.h | 2 +- src/tactic/proof_converter.cpp | 4 +- src/tactic/proof_converter.h | 6 +- src/tactic/replace_proof_converter.cpp | 8 +-- src/tactic/replace_proof_converter.h | 2 +- src/tactic/sine_filter.cpp | 22 +++---- src/tactic/sine_filter.h | 2 +- src/tactic/sls/bvsls_opt_engine.cpp | 4 +- src/tactic/sls/bvsls_opt_engine.h | 2 +- src/tactic/sls/sls_engine.cpp | 18 +++--- src/tactic/sls/sls_engine.h | 14 ++--- src/tactic/sls/sls_evaluator.h | 6 +- src/tactic/sls/sls_powers.h | 2 +- src/tactic/sls/sls_tactic.cpp | 24 +++---- src/tactic/sls/sls_tactic.h | 2 +- src/tactic/sls/sls_tracker.h | 10 +-- src/tactic/smtlogics/nra_tactic.cpp | 20 +++--- src/tactic/smtlogics/qfaufbv_tactic.cpp | 20 +++--- src/tactic/smtlogics/qfaufbv_tactic.h | 2 +- src/tactic/smtlogics/qfauflia_tactic.cpp | 14 ++--- src/tactic/smtlogics/qfauflia_tactic.h | 2 +- src/tactic/smtlogics/qfbv_tactic.cpp | 26 ++++---- src/tactic/smtlogics/qfbv_tactic.h | 2 +- src/tactic/smtlogics/qfidl_tactic.cpp | 32 +++++----- src/tactic/smtlogics/qfidl_tactic.h | 2 +- src/tactic/smtlogics/qflia_tactic.cpp | 36 +++++------ src/tactic/smtlogics/qflia_tactic.h | 2 +- src/tactic/smtlogics/qflra_tactic.cpp | 18 +++--- src/tactic/smtlogics/qflra_tactic.h | 2 +- src/tactic/smtlogics/qfnia_tactic.cpp | 24 +++---- src/tactic/smtlogics/qfnia_tactic.h | 2 +- src/tactic/smtlogics/qfnra_tactic.cpp | 12 ++-- src/tactic/smtlogics/qfnra_tactic.h | 2 +- src/tactic/smtlogics/qfuf_tactic.cpp | 12 ++-- src/tactic/smtlogics/qfuf_tactic.h | 2 +- .../smtlogics/qfufbv_ackr_model_converter.cpp | 4 +- .../smtlogics/qfufbv_ackr_model_converter.h | 4 +- src/tactic/smtlogics/qfufbv_tactic.cpp | 38 +++++------ src/tactic/smtlogics/qfufbv_tactic.h | 2 +- src/tactic/smtlogics/qfufnra_tactic.cpp | 24 +++---- src/tactic/smtlogics/qfufnra_tactic.h | 2 +- src/tactic/smtlogics/quant_tactics.cpp | 26 ++++---- src/tactic/smtlogics/quant_tactics.h | 2 +- src/tactic/tactic.cpp | 8 +-- src/tactic/tactic.h | 14 ++--- src/tactic/tactic_exception.h | 4 +- src/tactic/tactical.cpp | 12 ++-- src/tactic/tactical.h | 4 +- src/tactic/ufbv/macro_finder_tactic.cpp | 18 +++--- src/tactic/ufbv/macro_finder_tactic.h | 2 +- src/tactic/ufbv/quasi_macros_tactic.cpp | 20 +++--- src/tactic/ufbv/quasi_macros_tactic.h | 2 +- src/tactic/ufbv/ufbv_rewriter.cpp | 10 +-- src/tactic/ufbv/ufbv_rewriter.h | 12 ++-- src/tactic/ufbv/ufbv_rewriter_tactic.cpp | 10 +-- src/tactic/ufbv/ufbv_rewriter_tactic.h | 2 +- src/tactic/ufbv/ufbv_tactic.cpp | 26 ++++---- src/tactic/ufbv/ufbv_tactic.h | 2 +- src/test/algebraic.cpp | 8 +-- src/test/api.cpp | 10 +-- src/test/api_bug.cpp | 2 +- src/test/arith_rewriter.cpp | 16 ++--- src/test/arith_simplifier_plugin.cpp | 4 +- src/test/ast.cpp | 2 +- src/test/bit_blaster.cpp | 6 +- src/test/bit_vector.cpp | 4 +- src/test/bits.cpp | 10 +-- src/test/buffer.cpp | 2 +- src/test/bv_simplifier_plugin.cpp | 8 +-- src/test/chashtable.cpp | 8 +-- src/test/check_assumptions.cpp | 14 ++--- src/test/cnf_backbones.cpp | 10 +-- src/test/datalog_parser.cpp | 14 ++--- src/test/ddnf.cpp | 4 +- src/test/diff_logic.cpp | 10 +-- src/test/dl_context.cpp | 12 ++-- src/test/dl_product_relation.cpp | 10 +-- src/test/dl_query.cpp | 18 +++--- src/test/dl_relation.cpp | 14 ++--- src/test/dl_table.cpp | 8 +-- src/test/dl_util.cpp | 2 +- src/test/doc.cpp | 26 ++++---- src/test/escaped.cpp | 2 +- src/test/ex.cpp | 2 +- src/test/expr_rand.cpp | 14 ++--- src/test/expr_substitution.cpp | 18 +++--- src/test/ext_numeral.cpp | 4 +- src/test/f2n.cpp | 6 +- src/test/factor_rewriter.cpp | 8 +-- src/test/fixed_bit_vector.cpp | 4 +- src/test/for_each_file.cpp | 2 +- src/test/fuzzing/expr_delta.cpp | 4 +- src/test/fuzzing/expr_delta.h | 2 +- src/test/fuzzing/expr_rand.cpp | 10 +-- src/test/fuzzing/expr_rand.h | 4 +- src/test/get_consequences.cpp | 18 +++--- src/test/get_implied_equalities.cpp | 6 +- src/test/hashtable.cpp | 2 +- src/test/heap.cpp | 6 +- src/test/heap_trie.cpp | 2 +- src/test/hilbert_basis.cpp | 18 +++--- src/test/horn_subsume_model_converter.cpp | 8 +-- src/test/hwf.cpp | 6 +- src/test/im_float_config.h | 6 +- src/test/inf_rational.cpp | 2 +- src/test/interval.cpp | 14 ++--- src/test/karr.cpp | 4 +- src/test/list.cpp | 8 +-- src/test/lp.cpp | 6 +- src/test/main.cpp | 14 ++--- src/test/map.cpp | 4 +- src/test/matcher.cpp | 6 +- src/test/memory.cpp | 8 +-- src/test/model2expr.cpp | 10 +-- src/test/model_based_opt.cpp | 6 +- src/test/model_evaluator.cpp | 12 ++-- src/test/model_retrieval.cpp | 16 ++--- src/test/mpbq.cpp | 2 +- src/test/mpf.cpp | 4 +- src/test/mpff.cpp | 6 +- src/test/mpfx.cpp | 2 +- src/test/mpq.cpp | 6 +- src/test/mpz.cpp | 8 +-- src/test/nlarith_util.cpp | 8 +-- src/test/nlsat.cpp | 16 ++--- src/test/no_overflow.cpp | 6 +- src/test/object_allocator.cpp | 4 +- src/test/old_interval.cpp | 8 +-- src/test/optional.cpp | 6 +- src/test/parray.cpp | 6 +- src/test/pb2bv.cpp | 30 ++++----- src/test/pdr.cpp | 4 +- src/test/permutation.cpp | 6 +- src/test/polynomial.cpp | 10 +-- src/test/polynorm.cpp | 12 ++-- src/test/prime_generator.cpp | 4 +- src/test/proof_checker.cpp | 4 +- src/test/qe_arith.cpp | 22 +++---- src/test/quant_elim.cpp | 26 ++++---- src/test/quant_solve.cpp | 26 ++++---- src/test/random.cpp | 4 +- src/test/rational.cpp | 10 +-- src/test/rcf.cpp | 6 +- src/test/region.cpp | 2 +- src/test/sat_user_scope.cpp | 4 +- src/test/simple_parser.cpp | 14 ++--- src/test/simplex.cpp | 16 ++--- src/test/simplifier.cpp | 8 +-- src/test/small_object_allocator.cpp | 6 +- src/test/smt2print_parse.cpp | 2 +- src/test/smt_context.cpp | 4 +- src/test/sorting_network.cpp | 20 +++--- src/test/stack.cpp | 4 +- src/test/string_buffer.cpp | 6 +- src/test/substitution.cpp | 16 ++--- src/test/symbol.cpp | 4 +- src/test/symbol_table.cpp | 2 +- src/test/tbv.cpp | 2 +- src/test/test_util.h | 2 +- src/test/theory_dl.cpp | 10 +-- src/test/theory_pb.cpp | 12 ++-- src/test/timeout.cpp | 4 +- src/test/total_order.cpp | 4 +- src/test/trigo.cpp | 14 ++--- src/test/udoc_relation.cpp | 36 +++++------ src/test/uint_set.cpp | 6 +- src/test/upolynomial.cpp | 6 +- src/test/var_subst.cpp | 14 ++--- src/test/vector.cpp | 2 +- src/util/approx_nat.cpp | 2 +- src/util/approx_set.cpp | 2 +- src/util/approx_set.h | 2 +- src/util/array_map.h | 4 +- src/util/backtrackable_set.h | 2 +- src/util/bit_util.cpp | 6 +- src/util/bit_vector.cpp | 4 +- src/util/bit_vector.h | 6 +- src/util/buffer.h | 2 +- src/util/cancel_eh.h | 2 +- src/util/chashtable.h | 8 +-- src/util/checked_int64.h | 4 +- src/util/cmd_context_types.cpp | 2 +- src/util/cmd_context_types.h | 4 +- src/util/common_msgs.cpp | 2 +- src/util/cooperate.cpp | 8 +-- src/util/debug.cpp | 4 +- src/util/debug.h | 4 +- src/util/dependency.h | 4 +- src/util/dictionary.h | 4 +- src/util/double_manager.h | 8 +-- src/util/env_params.cpp | 10 +-- src/util/ext_numeral.h | 2 +- src/util/f2n.h | 2 +- src/util/fixed_bit_vector.cpp | 6 +- src/util/fixed_bit_vector.h | 4 +- src/util/gparams.cpp | 6 +- src/util/gparams.h | 2 +- src/util/hash.cpp | 4 +- src/util/hash.h | 2 +- src/util/hashtable.h | 8 +-- src/util/heap.h | 4 +- src/util/hwf.cpp | 2 +- src/util/hwf.h | 6 +- src/util/id_gen.h | 4 +- src/util/inf_eps_rational.h | 8 +-- src/util/inf_int_rational.cpp | 2 +- src/util/inf_int_rational.h | 6 +- src/util/inf_rational.cpp | 2 +- src/util/inf_rational.h | 6 +- src/util/inf_s_integer.cpp | 2 +- src/util/inf_s_integer.h | 4 +- src/util/lbool.cpp | 2 +- src/util/lbool.h | 2 +- src/util/list.h | 4 +- src/util/lp/bound_analyzer_on_row.h | 4 +- src/util/map.h | 2 +- src/util/max_cliques.h | 4 +- src/util/memory_manager.cpp | 8 +-- src/util/memory_manager.h | 2 +- src/util/mpbq.cpp | 2 +- src/util/mpbq.h | 6 +- src/util/mpbqi.h | 4 +- src/util/mpf.cpp | 2 +- src/util/mpf.h | 12 ++-- src/util/mpff.cpp | 12 ++-- src/util/mpff.h | 14 ++--- src/util/mpfx.cpp | 12 ++-- src/util/mpfx.h | 14 ++--- src/util/mpn.cpp | 8 +-- src/util/mpn.h | 6 +- src/util/mpq.cpp | 6 +- src/util/mpq.h | 4 +- src/util/mpq_inf.cpp | 2 +- src/util/mpq_inf.h | 4 +- src/util/mpz.cpp | 12 ++-- src/util/mpz.h | 14 ++--- src/util/mpzzp.h | 2 +- src/util/nat_set.h | 2 +- src/util/numeral_buffer.h | 2 +- src/util/obj_hashtable.h | 4 +- src/util/obj_mark.h | 2 +- src/util/obj_pair_hashtable.h | 4 +- src/util/obj_pair_set.h | 2 +- src/util/obj_triple_hashtable.h | 2 +- src/util/object_allocator.h | 4 +- src/util/page.cpp | 4 +- src/util/page.h | 2 +- src/util/params.cpp | 8 +-- src/util/params.h | 4 +- src/util/parray.h | 4 +- src/util/permutation.cpp | 2 +- src/util/permutation.h | 2 +- src/util/plugin_manager.h | 2 +- src/util/pool.h | 4 +- src/util/prime_generator.cpp | 2 +- src/util/prime_generator.h | 6 +- src/util/ptr_scoped_buffer.h | 6 +- src/util/rational.cpp | 4 +- src/util/rational.h | 2 +- src/util/ref_buffer.h | 6 +- src/util/ref_vector.h | 4 +- src/util/region.cpp | 10 +-- src/util/region.h | 2 +- src/util/rlimit.cpp | 4 +- src/util/rlimit.h | 2 +- src/util/s_integer.cpp | 2 +- src/util/s_integer.h | 2 +- src/util/scoped_ctrl_c.cpp | 2 +- src/util/scoped_ctrl_c.h | 4 +- src/util/scoped_numeral_buffer.h | 2 +- src/util/scoped_numeral_vector.h | 2 +- src/util/scoped_ptr_vector.h | 4 +- src/util/scoped_timer.cpp | 10 +-- src/util/scoped_timer.h | 2 +- src/util/scoped_vector.h | 2 +- src/util/sexpr.cpp | 6 +- src/util/sexpr.h | 8 +-- src/util/small_object_allocator.cpp | 10 +-- src/util/small_object_allocator.h | 4 +- src/util/smt2_util.cpp | 2 +- src/util/smt2_util.h | 2 +- src/util/sorting_network.h | 2 +- src/util/stack.cpp | 6 +- src/util/stack.h | 4 +- src/util/statistics.cpp | 10 +-- src/util/statistics.h | 4 +- src/util/str_hashtable.h | 4 +- src/util/string_buffer.h | 4 +- src/util/symbol.cpp | 10 +-- src/util/symbol.h | 6 +- src/util/symbol_table.h | 8 +-- src/util/timeit.cpp | 6 +- src/util/timeout.cpp | 12 ++-- src/util/timer.cpp | 8 +-- src/util/total_order.h | 10 +-- src/util/tptr.h | 2 +- src/util/trace.cpp | 4 +- src/util/trail.h | 6 +- src/util/uint_map.h | 2 +- src/util/uint_set.h | 4 +- src/util/union_find.h | 4 +- src/util/util.cpp | 2 +- src/util/util.h | 4 +- src/util/vector.h | 8 +-- src/util/warning.cpp | 8 +-- src/util/z3_exception.cpp | 8 +-- 1370 files changed, 5964 insertions(+), 5901 deletions(-) create mode 100644 scripts/update_include.py diff --git a/scripts/update_include.py b/scripts/update_include.py new file mode 100644 index 000000000..555d9f094 --- /dev/null +++ b/scripts/update_include.py @@ -0,0 +1,63 @@ +# Copyright (c) 2017 Microsoft Corporation + +import os +import re + +is_include = re.compile("#include \"(.*)\"") +is_include2 = re.compile("#include\"(.*)\"") + + +def fix_include(file, paths): + print(file) + tmp = "%s.tmp" % file + ins = open(file) + ous = open(tmp,'w') + line = ins.readline() + found = False + while line: + m = is_include.search(line) + if m and m.group(1) in paths: + ous.write("#include \"") + ous.write(paths[m.group(1)]) + ous.write("\"\n") + found = True + line = ins.readline() + continue + m = is_include2.search(line) + if m and m.group(1) in paths: + ous.write("#include \"") + ous.write(paths[m.group(1)]) + ous.write("\"\n") + found = True + line = ins.readline() + continue + ous.write(line) + line = ins.readline() + ins.close() + ous.close() + if found: + os.system("move %s %s" % (tmp, file)) + else: + os.system("del %s" % tmp) + +def find_paths(dir): + paths = {} + for root, dirs, files in os.walk(dir): + root1 = root.replace("\\","/")[4:] + for f in files: + if f.endswith('.h'): + path = "%s/%s" % (root1, f) + paths[f] = path + return paths + +paths = find_paths('src') + +def fixup(dir): + for root, dirs, files in os.walk(dir): + for f in files: + if f.endswith('.h') or f.endswith('.cpp'): + path = "%s\\%s" % (root, f) + fix_include(path, paths) + + +fixup('src') diff --git a/src/ackermannization/ackermannize_bv_model_converter.cpp b/src/ackermannization/ackermannize_bv_model_converter.cpp index d47735a56..360714c8b 100644 --- a/src/ackermannization/ackermannize_bv_model_converter.cpp +++ b/src/ackermannization/ackermannize_bv_model_converter.cpp @@ -14,8 +14,8 @@ Revision History: --*/ -#include"ackr_model_converter.h" -#include"ackermannize_bv_model_converter.h" +#include "ackermannization/ackr_model_converter.h" +#include "ackermannization/ackermannize_bv_model_converter.h" model_converter * mk_ackermannize_bv_model_converter(ast_manager & m, const ackr_info_ref& info) { return mk_ackr_model_converter(m, info); diff --git a/src/ackermannization/ackermannize_bv_model_converter.h b/src/ackermannization/ackermannize_bv_model_converter.h index e51792bad..d0255a0d4 100644 --- a/src/ackermannization/ackermannize_bv_model_converter.h +++ b/src/ackermannization/ackermannize_bv_model_converter.h @@ -17,8 +17,8 @@ #ifndef ACKERMANNIZE_BV_MODEL_CONVERTER_H_ #define ACKERMANNIZE_BV_MODEL_CONVERTER_H_ -#include"model_converter.h" -#include"ackr_info.h" +#include "tactic/model_converter.h" +#include "ackermannization/ackr_info.h" model_converter * mk_ackermannize_bv_model_converter(ast_manager & m, const ackr_info_ref& info); diff --git a/src/ackermannization/ackermannize_bv_tactic.cpp b/src/ackermannization/ackermannize_bv_tactic.cpp index 70230e346..82ac50a95 100644 --- a/src/ackermannization/ackermannize_bv_tactic.cpp +++ b/src/ackermannization/ackermannize_bv_tactic.cpp @@ -13,12 +13,12 @@ Mikolas Janota Revision History: --*/ -#include"ackermannize_bv_tactic.h" -#include"tactical.h" -#include"lackr.h" -#include"model_smt2_pp.h" +#include "ackermannization/ackermannize_bv_tactic.h" +#include "tactic/tactical.h" +#include "ackermannization/lackr.h" +#include "model/model_smt2_pp.h" #include"ackermannize_bv_tactic_params.hpp" -#include"ackermannize_bv_model_converter.h" +#include "ackermannization/ackermannize_bv_model_converter.h" class ackermannize_bv_tactic : public tactic { diff --git a/src/ackermannization/ackermannize_bv_tactic.h b/src/ackermannization/ackermannize_bv_tactic.h index 3e3d5636c..803defb06 100644 --- a/src/ackermannization/ackermannize_bv_tactic.h +++ b/src/ackermannization/ackermannize_bv_tactic.h @@ -16,7 +16,7 @@ Revision History: #ifndef _ACKERMANNIZE_TACTIC_H_ #define _ACKERMANNIZE_TACTIC_H_ -#include"tactical.h" +#include "tactic/tactical.h" tactic * mk_ackermannize_bv_tactic(ast_manager & m, params_ref const & p); diff --git a/src/ackermannization/ackr_bound_probe.cpp b/src/ackermannization/ackr_bound_probe.cpp index 5cb8e9448..50b9cc092 100644 --- a/src/ackermannization/ackr_bound_probe.cpp +++ b/src/ackermannization/ackr_bound_probe.cpp @@ -14,9 +14,9 @@ Revision History: --*/ -#include"ackr_helper.h" -#include"ackr_bound_probe.h" -#include"ast_smt2_pp.h" +#include "ackermannization/ackr_helper.h" +#include "ackermannization/ackr_bound_probe.h" +#include "ast/ast_smt2_pp.h" /* For each function f, calculate the number of its occurrences o_f and compute "o_f choose 2". diff --git a/src/ackermannization/ackr_bound_probe.h b/src/ackermannization/ackr_bound_probe.h index 6c0a66605..169b3068e 100644 --- a/src/ackermannization/ackr_bound_probe.h +++ b/src/ackermannization/ackr_bound_probe.h @@ -18,7 +18,7 @@ #ifndef ACKR_BOUND_PROBE_H_ #define ACKR_BOUND_PROBE_H_ -#include"probe.h" +#include "tactic/probe.h" probe * mk_ackr_bound_probe(); diff --git a/src/ackermannization/ackr_helper.cpp b/src/ackermannization/ackr_helper.cpp index 803fc3c54..2e0fda687 100644 --- a/src/ackermannization/ackr_helper.cpp +++ b/src/ackermannization/ackr_helper.cpp @@ -14,7 +14,7 @@ Revision History: --*/ -#include"ackr_helper.h" +#include "ackermannization/ackr_helper.h" double ackr_helper::calculate_lemma_bound(ackr_helper::fun2terms_map& occurrences) { fun2terms_map::iterator it = occurrences.begin(); diff --git a/src/ackermannization/ackr_helper.h b/src/ackermannization/ackr_helper.h index 327763da4..651b25b12 100644 --- a/src/ackermannization/ackr_helper.h +++ b/src/ackermannization/ackr_helper.h @@ -17,7 +17,7 @@ #ifndef ACKR_HELPER_H_ #define ACKR_HELPER_H_ -#include"bv_decl_plugin.h" +#include "ast/bv_decl_plugin.h" class ackr_helper { public: diff --git a/src/ackermannization/ackr_info.h b/src/ackermannization/ackr_info.h index 76be45e2b..0b67e144f 100644 --- a/src/ackermannization/ackr_info.h +++ b/src/ackermannization/ackr_info.h @@ -16,11 +16,11 @@ Revision History: #ifndef ACKR_INFO_H_ #define ACKR_INFO_H_ -#include"obj_hashtable.h" -#include"ast.h" -#include"ref.h" -#include"expr_replacer.h" -#include"ast_translation.h" +#include "util/obj_hashtable.h" +#include "ast/ast.h" +#include "util/ref.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/ast_translation.h" /** \brief Information about how a formula is being converted into diff --git a/src/ackermannization/ackr_model_converter.cpp b/src/ackermannization/ackr_model_converter.cpp index ea4f858ad..0697686eb 100644 --- a/src/ackermannization/ackr_model_converter.cpp +++ b/src/ackermannization/ackr_model_converter.cpp @@ -13,10 +13,10 @@ Mikolas Janota Revision History: --*/ -#include"ackr_model_converter.h" -#include"model_evaluator.h" -#include"ast_smt2_pp.h" -#include"ackr_info.h" +#include "ackermannization/ackr_model_converter.h" +#include "model/model_evaluator.h" +#include "ast/ast_smt2_pp.h" +#include "ackermannization/ackr_info.h" class ackr_model_converter : public model_converter { diff --git a/src/ackermannization/ackr_model_converter.h b/src/ackermannization/ackr_model_converter.h index 2c1f0c78c..cee7472aa 100644 --- a/src/ackermannization/ackr_model_converter.h +++ b/src/ackermannization/ackr_model_converter.h @@ -16,8 +16,8 @@ Revision History: #ifndef ACKR_MODEL_CONVERTER_H_ #define ACKR_MODEL_CONVERTER_H_ -#include"model_converter.h" -#include"ackr_info.h" +#include "tactic/model_converter.h" +#include "ackermannization/ackr_info.h" model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model); model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info); diff --git a/src/ackermannization/lackr.cpp b/src/ackermannization/lackr.cpp index 461d2080f..76fbe0617 100644 --- a/src/ackermannization/lackr.cpp +++ b/src/ackermannization/lackr.cpp @@ -15,13 +15,13 @@ Revision History: --*/ -#include"lackr.h" +#include "ackermannization/lackr.h" #include"ackermannization_params.hpp" -#include"tactic.h" -#include"lackr_model_constructor.h" -#include"ackr_info.h" -#include"for_each_expr.h" -#include"model_smt2_pp.h" +#include "tactic/tactic.h" +#include "ackermannization/lackr_model_constructor.h" +#include "ackermannization/ackr_info.h" +#include "ast/for_each_expr.h" +#include "model/model_smt2_pp.h" lackr::lackr(ast_manager& m, params_ref p, lackr_stats& st, expr_ref_vector& formulas, solver * uffree_solver) diff --git a/src/ackermannization/lackr.h b/src/ackermannization/lackr.h index 4bf1d6965..554ad6ef8 100644 --- a/src/ackermannization/lackr.h +++ b/src/ackermannization/lackr.h @@ -17,17 +17,17 @@ #ifndef LACKR_H_ #define LACKR_H_ -#include"ackr_info.h" -#include"ackr_helper.h" -#include"th_rewriter.h" -#include"cooperate.h" -#include"bv_decl_plugin.h" -#include"lbool.h" -#include"model.h" -#include"solver.h" -#include"util.h" -#include"tactic_exception.h" -#include"goal.h" +#include "ackermannization/ackr_info.h" +#include "ackermannization/ackr_helper.h" +#include "ast/rewriter/th_rewriter.h" +#include "util/cooperate.h" +#include "ast/bv_decl_plugin.h" +#include "util/lbool.h" +#include "model/model.h" +#include "solver/solver.h" +#include "util/util.h" +#include "tactic/tactic_exception.h" +#include "tactic/goal.h" struct lackr_stats { lackr_stats() : m_it(0), m_ackrs_sz(0) {} diff --git a/src/ackermannization/lackr_model_constructor.cpp b/src/ackermannization/lackr_model_constructor.cpp index 8e99fe2a2..641c70cbc 100644 --- a/src/ackermannization/lackr_model_constructor.cpp +++ b/src/ackermannization/lackr_model_constructor.cpp @@ -14,13 +14,13 @@ Revision History: --*/ -#include"lackr_model_constructor.h" -#include"model_evaluator.h" -#include"ast_smt2_pp.h" -#include"ackr_info.h" -#include"for_each_expr.h" -#include"bv_rewriter.h" -#include"bool_rewriter.h" +#include "ackermannization/lackr_model_constructor.h" +#include "model/model_evaluator.h" +#include "ast/ast_smt2_pp.h" +#include "ackermannization/ackr_info.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/bv_rewriter.h" +#include "ast/rewriter/bool_rewriter.h" struct lackr_model_constructor::imp { public: diff --git a/src/ackermannization/lackr_model_constructor.h b/src/ackermannization/lackr_model_constructor.h index 71c9c0710..d5847a24c 100644 --- a/src/ackermannization/lackr_model_constructor.h +++ b/src/ackermannization/lackr_model_constructor.h @@ -18,10 +18,10 @@ #ifndef LACKR_MODEL_CONSTRUCTOR_H_ #define LACKR_MODEL_CONSTRUCTOR_H_ -#include"ast.h" -#include"ackr_info.h" -#include"ackr_helper.h" -#include"model.h" +#include "ast/ast.h" +#include "ackermannization/ackr_info.h" +#include "ackermannization/ackr_helper.h" +#include "model/model.h" class lackr_model_constructor { public: diff --git a/src/ackermannization/lackr_model_converter_lazy.cpp b/src/ackermannization/lackr_model_converter_lazy.cpp index 5a0d1c4be..2a7adb839 100644 --- a/src/ackermannization/lackr_model_converter_lazy.cpp +++ b/src/ackermannization/lackr_model_converter_lazy.cpp @@ -14,11 +14,11 @@ Revision History: --*/ -#include"lackr_model_converter_lazy.h" -#include"model_evaluator.h" -#include"ast_smt2_pp.h" -#include"ackr_info.h" -#include"lackr_model_constructor.h" +#include "ackermannization/lackr_model_converter_lazy.h" +#include "model/model_evaluator.h" +#include "ast/ast_smt2_pp.h" +#include "ackermannization/ackr_info.h" +#include "ackermannization/lackr_model_constructor.h" class lackr_model_converter_lazy : public model_converter { public: diff --git a/src/ackermannization/lackr_model_converter_lazy.h b/src/ackermannization/lackr_model_converter_lazy.h index c9b3eac80..0581976a9 100644 --- a/src/ackermannization/lackr_model_converter_lazy.h +++ b/src/ackermannization/lackr_model_converter_lazy.h @@ -17,8 +17,8 @@ #ifndef LACKR_MODEL_CONVERTER_LAZY_H_ #define LACKR_MODEL_CONVERTER_LAZY_H_ -#include"model_converter.h" -#include"ackr_info.h" +#include "tactic/model_converter.h" +#include "ackermannization/ackr_info.h" model_converter * mk_lackr_model_converter_lazy(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model); diff --git a/src/api/api_algebraic.cpp b/src/api/api_algebraic.cpp index c4e4dac5d..40e8c846b 100644 --- a/src/api/api_algebraic.cpp +++ b/src/api/api_algebraic.cpp @@ -17,14 +17,14 @@ Author: Notes: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_ast_vector.h" -#include"algebraic_numbers.h" -#include"expr2polynomial.h" -#include"cancel_eh.h" -#include"scoped_timer.h" +#include "api/api_context.h" +#include "api/api_ast_vector.h" +#include "math/polynomial/algebraic_numbers.h" +#include "ast/expr2polynomial.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" #define CHECK_IS_ALGEBRAIC(ARG, RET) { \ diff --git a/src/api/api_arith.cpp b/src/api/api_arith.cpp index 51aea9676..80eb261ad 100644 --- a/src/api/api_arith.cpp +++ b/src/api/api_arith.cpp @@ -15,12 +15,12 @@ Author: Revision History: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"arith_decl_plugin.h" -#include"algebraic_numbers.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/arith_decl_plugin.h" +#include "math/polynomial/algebraic_numbers.h" #define MK_ARITH_OP(NAME, OP) MK_NARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP) #define MK_BINARY_ARITH_OP(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP) diff --git a/src/api/api_array.cpp b/src/api/api_array.cpp index ed431882e..f4682ea8f 100644 --- a/src/api/api_array.cpp +++ b/src/api/api_array.cpp @@ -15,11 +15,11 @@ Author: Revision History: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"array_decl_plugin.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/array_decl_plugin.h" extern "C" { diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index d34cad2f4..6ae10b8f9 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -17,26 +17,26 @@ Revision History: --*/ #include #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"well_sorted.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"array_decl_plugin.h" -#include"pb_decl_plugin.h" -#include"ast_translation.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt_pp.h" -#include"ast_smt2_pp.h" -#include"th_rewriter.h" -#include"var_subst.h" -#include"expr_safe_replace.h" -#include"pp.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"scoped_timer.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/well_sorted.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/pb_decl_plugin.h" +#include "ast/ast_translation.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/pp.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" #include"pp_params.hpp" extern bool is_numeral_sort(Z3_context c, Z3_sort ty); diff --git a/src/api/api_ast_map.cpp b/src/api/api_ast_map.cpp index aa52faa98..fc593c1f5 100644 --- a/src/api/api_ast_map.cpp +++ b/src/api/api_ast_map.cpp @@ -16,13 +16,13 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_ast_map.h" -#include"api_ast_vector.h" -#include"ast_smt2_pp.h" -#include"dec_ref_util.h" +#include "api/api_context.h" +#include "api/api_ast_map.h" +#include "api/api_ast_vector.h" +#include "ast/ast_smt2_pp.h" +#include "util/dec_ref_util.h" Z3_ast_map_ref::~Z3_ast_map_ref() { dec_ref_key_values(m, m_map); diff --git a/src/api/api_ast_map.h b/src/api/api_ast_map.h index dc1cf90ad..3dacc54f1 100644 --- a/src/api/api_ast_map.h +++ b/src/api/api_ast_map.h @@ -18,8 +18,8 @@ Revision History: #ifndef API_AST_MAP_H_ #define API_AST_MAP_H_ -#include"api_util.h" -#include"obj_hashtable.h" +#include "api/api_util.h" +#include "util/obj_hashtable.h" struct Z3_ast_map_ref : public api::object { ast_manager & m; diff --git a/src/api/api_ast_vector.cpp b/src/api/api_ast_vector.cpp index 40df13708..04802cba5 100644 --- a/src/api/api_ast_vector.cpp +++ b/src/api/api_ast_vector.cpp @@ -16,12 +16,12 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_ast_vector.h" -#include"ast_translation.h" -#include"ast_smt2_pp.h" +#include "api/api_context.h" +#include "api/api_ast_vector.h" +#include "ast/ast_translation.h" +#include "ast/ast_smt2_pp.h" extern "C" { diff --git a/src/api/api_ast_vector.h b/src/api/api_ast_vector.h index 4fcf8ffb8..ced20481e 100644 --- a/src/api/api_ast_vector.h +++ b/src/api/api_ast_vector.h @@ -18,7 +18,7 @@ Revision History: #ifndef API_AST_VECTOR_H_ #define API_AST_VECTOR_H_ -#include"api_util.h" +#include "api/api_util.h" namespace api { class context; diff --git a/src/api/api_bv.cpp b/src/api/api_bv.cpp index ff090ef54..52fcb867c 100644 --- a/src/api/api_bv.cpp +++ b/src/api/api_bv.cpp @@ -15,11 +15,11 @@ Author: Revision History: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"bv_decl_plugin.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/bv_decl_plugin.h" extern "C" { diff --git a/src/api/api_config_params.cpp b/src/api/api_config_params.cpp index a04a9f12c..d35297f59 100644 --- a/src/api/api_config_params.cpp +++ b/src/api/api_config_params.cpp @@ -15,16 +15,16 @@ Author: Revision History: --*/ -#include"z3.h" -#include"api_context.h" -#include"pp.h" +#include "api/z3.h" +#include "api/api_context.h" +#include "ast/pp.h" #include"api_log_macros.h" -#include"api_util.h" -#include"cmd_context.h" -#include"symbol.h" -#include"gparams.h" -#include"env_params.h" -#include"context_params.h" +#include "api/api_util.h" +#include "cmd_context/cmd_context.h" +#include "util/symbol.h" +#include "util/gparams.h" +#include "util/env_params.h" +#include "cmd_context/context_params.h" extern "C" { void Z3_API Z3_global_param_set(Z3_string param_id, Z3_string param_value) { diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index bcd3c60f2..2c93ee85d 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -18,15 +18,15 @@ Revision History: --*/ #include -#include"api_context.h" -#include"smtparser.h" +#include "api/api_context.h" +#include "parsers/smt/smtparser.h" #include"version.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" #include"api_log_macros.h" -#include"api_util.h" -#include"reg_decl_plugins.h" -#include"realclosure.h" +#include "api/api_util.h" +#include "ast/reg_decl_plugins.h" +#include "math/realclosure/realclosure.h" // The install_tactics procedure is automatically generated void install_tactics(tactic_manager & ctx); diff --git a/src/api/api_context.h b/src/api/api_context.h index 4685fd04e..6f8dc43f6 100644 --- a/src/api/api_context.h +++ b/src/api/api_context.h @@ -20,22 +20,22 @@ Revision History: #ifndef API_CONTEXT_H_ #define API_CONTEXT_H_ -#include"z3.h" -#include"ast.h" -#include"api_util.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"dl_decl_plugin.h" -#include"fpa_decl_plugin.h" -#include"smt_kernel.h" -#include"smt_params.h" -#include"event_handler.h" -#include"tactic_manager.h" -#include"context_params.h" -#include"api_polynomial.h" -#include"hashtable.h" +#include "api/z3.h" +#include "ast/ast.h" +#include "api/api_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/dl_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "smt/smt_kernel.h" +#include "smt/params/smt_params.h" +#include "util/event_handler.h" +#include "cmd_context/tactic_manager.h" +#include "cmd_context/context_params.h" +#include "api/api_polynomial.h" +#include "util/hashtable.h" namespace smtlib { class parser; diff --git a/src/api/api_datalog.cpp b/src/api/api_datalog.cpp index 8843256c6..b57247fb1 100644 --- a/src/api/api_datalog.cpp +++ b/src/api/api_datalog.cpp @@ -15,24 +15,24 @@ Author: Revision History: --*/ -#include"api_datalog.h" -#include"api_context.h" -#include"api_util.h" -#include"ast_pp.h" -#include"api_ast_vector.h" +#include "api/api_datalog.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/ast_pp.h" +#include "api/api_ast_vector.h" #include"api_log_macros.h" -#include"api_stats.h" -#include"datalog_parser.h" -#include"cancel_eh.h" -#include"scoped_timer.h" -#include"dl_cmds.h" -#include"cmd_context.h" -#include"smt2parser.h" -#include"dl_context.h" -#include"dl_register_engine.h" -#include"dl_external_relation.h" -#include"dl_decl_plugin.h" -#include"rel_context.h" +#include "api/api_stats.h" +#include "muz/fp/datalog_parser.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" +#include "muz/fp/dl_cmds.h" +#include "cmd_context/cmd_context.h" +#include "parsers/smt2/smt2parser.h" +#include "muz/base/dl_context.h" +#include "muz/fp/dl_register_engine.h" +#include "muz/rel/dl_external_relation.h" +#include "ast/dl_decl_plugin.h" +#include "muz/rel/rel_context.h" namespace api { diff --git a/src/api/api_datalog.h b/src/api/api_datalog.h index 8c095d546..c8dbc4180 100644 --- a/src/api/api_datalog.h +++ b/src/api/api_datalog.h @@ -19,11 +19,11 @@ Revision History: #ifndef API_DATALOG_H_ #define API_DATALOG_H_ -#include"z3.h" -#include"ast.h" -#include"smt_params.h" -#include"smt_kernel.h" -#include"api_util.h" +#include "api/z3.h" +#include "ast/ast.h" +#include "smt/params/smt_params.h" +#include "smt/smt_kernel.h" +#include "api/api_util.h" typedef void (*reduce_app_callback_fptr)(void*, func_decl*, unsigned, expr*const*, expr**); typedef void (*reduce_assign_callback_fptr)(void*, func_decl*, unsigned, expr*const*, unsigned, expr*const*); diff --git a/src/api/api_datatype.cpp b/src/api/api_datatype.cpp index 647cdc581..7e9758a04 100644 --- a/src/api/api_datatype.cpp +++ b/src/api/api_datatype.cpp @@ -15,11 +15,11 @@ Author: Revision History: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"datatype_decl_plugin.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/datatype_decl_plugin.h" extern "C" { diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 6dad5048f..8e4d13af4 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -17,10 +17,10 @@ Notes: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"fpa_decl_plugin.h" +#include "api/api_context.h" +#include "ast/fpa_decl_plugin.h" bool is_fp_sort(Z3_context c, Z3_sort s) { return mk_c(c)->fpautil().is_float(to_sort(s)); diff --git a/src/api/api_goal.cpp b/src/api/api_goal.cpp index 295e1d939..3fe23828d 100644 --- a/src/api/api_goal.cpp +++ b/src/api/api_goal.cpp @@ -16,11 +16,11 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_goal.h" -#include"ast_translation.h" +#include "api/api_context.h" +#include "api/api_goal.h" +#include "ast/ast_translation.h" extern "C" { diff --git a/src/api/api_goal.h b/src/api/api_goal.h index 1e47b832a..4e9729df5 100644 --- a/src/api/api_goal.h +++ b/src/api/api_goal.h @@ -18,8 +18,8 @@ Revision History: #ifndef API_GOAL_H_ #define API_GOAL_H_ -#include"api_util.h" -#include"goal.h" +#include "api/api_util.h" +#include "tactic/goal.h" struct Z3_goal_ref : public api::object { goal_ref m_goal; diff --git a/src/api/api_interp.cpp b/src/api/api_interp.cpp index 10aa06568..276e56989 100644 --- a/src/api/api_interp.cpp +++ b/src/api/api_interp.cpp @@ -17,27 +17,27 @@ --*/ #include #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_tactic.h" -#include"api_solver.h" -#include"api_model.h" -#include"api_stats.h" -#include"api_ast_vector.h" -#include"tactic2solver.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"scoped_timer.h" -#include"smt_strategic_solver.h" -#include"smt_solver.h" -#include"smt_implied_equalities.h" -#include"iz3interp.h" -#include"iz3profiling.h" -#include"iz3hash.h" -#include"iz3pp.h" -#include"iz3checker.h" -#include"scoped_proof.h" +#include "api/api_context.h" +#include "api/api_tactic.h" +#include "api/api_solver.h" +#include "api/api_model.h" +#include "api/api_stats.h" +#include "api/api_ast_vector.h" +#include "solver/tactic2solver.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" +#include "tactic/portfolio/smt_strategic_solver.h" +#include "smt/smt_solver.h" +#include "smt/smt_implied_equalities.h" +#include "interp/iz3interp.h" +#include "interp/iz3profiling.h" +#include "interp/iz3hash.h" +#include "interp/iz3pp.h" +#include "interp/iz3checker.h" +#include "ast/scoped_proof.h" using namespace stl_ext; diff --git a/src/api/api_log.cpp b/src/api/api_log.cpp index 43ed98986..aa00de424 100644 --- a/src/api/api_log.cpp +++ b/src/api/api_log.cpp @@ -16,9 +16,9 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"util.h" +#include "util/util.h" #include"version.h" std::ostream * g_z3_log = 0; diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index 67c0f2f08..ccd70e79e 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -16,15 +16,15 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_model.h" -#include"api_ast_vector.h" -#include"array_decl_plugin.h" -#include"model.h" -#include"model_v2_pp.h" -#include"model_smt2_pp.h" +#include "api/api_context.h" +#include "api/api_model.h" +#include "api/api_ast_vector.h" +#include "ast/array_decl_plugin.h" +#include "model/model.h" +#include "model/model_v2_pp.h" +#include "model/model_smt2_pp.h" #include"model_params.hpp" #include"model_evaluator_params.hpp" diff --git a/src/api/api_model.h b/src/api/api_model.h index 9a53b59bc..64427cfb8 100644 --- a/src/api/api_model.h +++ b/src/api/api_model.h @@ -18,8 +18,8 @@ Revision History: #ifndef API_MODEL_H_ #define API_MODEL_H_ -#include"api_util.h" -#include"model.h" +#include "api/api_util.h" +#include "model/model.h" struct Z3_model_ref : public api::object { model_ref m_model; diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 40ebcf652..c3717b5d2 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -16,14 +16,14 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"algebraic_numbers.h" -#include"fpa_decl_plugin.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "math/polynomial/algebraic_numbers.h" +#include "ast/fpa_decl_plugin.h" bool is_numeral_sort(Z3_context c, Z3_sort ty) { sort * _ty = to_sort(ty); diff --git a/src/api/api_opt.cpp b/src/api/api_opt.cpp index 0d1b4ef8d..8c49b526e 100644 --- a/src/api/api_opt.cpp +++ b/src/api/api_opt.cpp @@ -16,18 +16,18 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_stats.h" -#include"api_context.h" -#include"api_util.h" -#include"api_model.h" -#include"opt_context.h" -#include"opt_cmds.h" -#include"cancel_eh.h" -#include"scoped_timer.h" -#include"smt2parser.h" -#include"api_ast_vector.h" +#include "api/api_stats.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "api/api_model.h" +#include "opt/opt_context.h" +#include "opt/opt_cmds.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" +#include "parsers/smt2/smt2parser.h" +#include "api/api_ast_vector.h" extern "C" { diff --git a/src/api/api_params.cpp b/src/api/api_params.cpp index 1efaffca8..86dfe9a93 100644 --- a/src/api/api_params.cpp +++ b/src/api/api_params.cpp @@ -18,11 +18,11 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"params.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "util/params.h" extern "C" { diff --git a/src/api/api_parsers.cpp b/src/api/api_parsers.cpp index 8f6eb1125..8c2723e9a 100644 --- a/src/api/api_parsers.cpp +++ b/src/api/api_parsers.cpp @@ -16,14 +16,14 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"cmd_context.h" -#include"smt2parser.h" -#include"smtparser.h" -#include"solver_na2as.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "cmd_context/cmd_context.h" +#include "parsers/smt2/smt2parser.h" +#include "parsers/smt/smtparser.h" +#include "solver/solver_na2as.h" extern "C" { diff --git a/src/api/api_pb.cpp b/src/api/api_pb.cpp index bb4a40c9a..97e627ec0 100644 --- a/src/api/api_pb.cpp +++ b/src/api/api_pb.cpp @@ -15,11 +15,11 @@ Author: Revision History: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"pb_decl_plugin.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/pb_decl_plugin.h" extern "C" { diff --git a/src/api/api_polynomial.cpp b/src/api/api_polynomial.cpp index eebe36717..398fdeb3a 100644 --- a/src/api/api_polynomial.cpp +++ b/src/api/api_polynomial.cpp @@ -16,15 +16,15 @@ Author: Notes: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_polynomial.h" -#include"api_ast_vector.h" -#include"expr2polynomial.h" -#include"cancel_eh.h" -#include"scoped_timer.h" -#include"expr2var.h" +#include "api/api_context.h" +#include "api/api_polynomial.h" +#include "api/api_ast_vector.h" +#include "ast/expr2polynomial.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" +#include "ast/expr2var.h" namespace api { diff --git a/src/api/api_polynomial.h b/src/api/api_polynomial.h index b93372ca9..fbb1e7e13 100644 --- a/src/api/api_polynomial.h +++ b/src/api/api_polynomial.h @@ -19,7 +19,7 @@ Notes: #ifndef API_POLYNOMIAL_H_ #define API_POLYNOMIAL_H_ -#include"polynomial.h" +#include "math/polynomial/polynomial.h" namespace api { diff --git a/src/api/api_quant.cpp b/src/api/api_quant.cpp index e87b9446f..f7d5bf13a 100644 --- a/src/api/api_quant.cpp +++ b/src/api/api_quant.cpp @@ -15,12 +15,12 @@ Author: Revision History: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"pattern_validation.h" -#include"expr_abstract.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "parsers/util/pattern_validation.h" +#include "ast/expr_abstract.h" extern "C" { diff --git a/src/api/api_rcf.cpp b/src/api/api_rcf.cpp index a4770c56c..377e83a44 100644 --- a/src/api/api_rcf.cpp +++ b/src/api/api_rcf.cpp @@ -20,10 +20,10 @@ Notes: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"realclosure.h" +#include "api/api_context.h" +#include "math/realclosure/realclosure.h" static rcmanager & rcfm(Z3_context c) { return mk_c(c)->rcfm(); diff --git a/src/api/api_seq.cpp b/src/api/api_seq.cpp index 986e6f497..a652fd912 100644 --- a/src/api/api_seq.cpp +++ b/src/api/api_seq.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_util.h" -#include"ast_pp.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "ast/ast_pp.h" extern "C" { diff --git a/src/api/api_solver.cpp b/src/api/api_solver.cpp index 6dc41efb2..6435b8288 100644 --- a/src/api/api_solver.cpp +++ b/src/api/api_solver.cpp @@ -17,22 +17,22 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_tactic.h" -#include"api_solver.h" -#include"api_model.h" -#include"api_stats.h" -#include"api_ast_vector.h" -#include"tactic2solver.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"scoped_timer.h" -#include"smt_strategic_solver.h" -#include"smt_solver.h" -#include"smt_implied_equalities.h" -#include"smt_logics.h" +#include "api/api_context.h" +#include "api/api_tactic.h" +#include "api/api_solver.h" +#include "api/api_model.h" +#include "api/api_stats.h" +#include "api/api_ast_vector.h" +#include "solver/tactic2solver.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" +#include "tactic/portfolio/smt_strategic_solver.h" +#include "smt/smt_solver.h" +#include "smt/smt_implied_equalities.h" +#include "solver/smt_logics.h" extern "C" { diff --git a/src/api/api_solver.h b/src/api/api_solver.h index ea59ccf33..4f344a00d 100644 --- a/src/api/api_solver.h +++ b/src/api/api_solver.h @@ -18,8 +18,8 @@ Revision History: #ifndef API_SOLVER_H_ #define API_SOLVER_H_ -#include"api_util.h" -#include"solver.h" +#include "api/api_util.h" +#include "solver/solver.h" struct Z3_solver_ref : public api::object { scoped_ptr m_solver_factory; diff --git a/src/api/api_stats.cpp b/src/api/api_stats.cpp index b39c8368a..440aec22d 100644 --- a/src/api/api_stats.cpp +++ b/src/api/api_stats.cpp @@ -16,10 +16,10 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_stats.h" +#include "api/api_context.h" +#include "api/api_stats.h" extern "C" { diff --git a/src/api/api_stats.h b/src/api/api_stats.h index 1c0c0c82e..5ce616084 100644 --- a/src/api/api_stats.h +++ b/src/api/api_stats.h @@ -18,8 +18,8 @@ Revision History: #ifndef API_STATS_H_ #define API_STATS_H_ -#include"api_util.h" -#include"statistics.h" +#include "api/api_util.h" +#include "util/statistics.h" struct Z3_stats_ref : public api::object { statistics m_stats; diff --git a/src/api/api_tactic.cpp b/src/api/api_tactic.cpp index 7068619c1..661660a63 100644 --- a/src/api/api_tactic.cpp +++ b/src/api/api_tactic.cpp @@ -16,14 +16,14 @@ Revision History: --*/ #include -#include"z3.h" +#include "api/z3.h" #include"api_log_macros.h" -#include"api_context.h" -#include"api_tactic.h" -#include"api_model.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"scoped_timer.h" +#include "api/api_context.h" +#include "api/api_tactic.h" +#include "api/api_model.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" Z3_apply_result_ref::Z3_apply_result_ref(api::context& c, ast_manager & m): api::object(c), m_core(m) { } diff --git a/src/api/api_tactic.h b/src/api/api_tactic.h index 373b85b39..fd2f05185 100644 --- a/src/api/api_tactic.h +++ b/src/api/api_tactic.h @@ -18,8 +18,8 @@ Revision History: #ifndef API_TACTIC_H_ #define API_TACTIC_H_ -#include"api_goal.h" -#include"tactical.h" +#include "api/api_goal.h" +#include "tactic/tactical.h" namespace api { class context; diff --git a/src/api/api_util.h b/src/api/api_util.h index 7857e7c38..bc6781c2c 100644 --- a/src/api/api_util.h +++ b/src/api/api_util.h @@ -18,9 +18,9 @@ Revision History: #ifndef API_UTIL_H_ #define API_UTIL_H_ -#include"params.h" -#include"lbool.h" -#include"ast.h" +#include "util/params.h" +#include "util/lbool.h" +#include "ast/ast.h" #define Z3_TRY try { #define Z3_CATCH_CORE(CODE) } catch (z3_exception & ex) { mk_c(c)->handle_exception(ex); CODE } diff --git a/src/api/z3.h b/src/api/z3.h index ffa200807..22a1b9b5d 100644 --- a/src/api/z3.h +++ b/src/api/z3.h @@ -22,16 +22,16 @@ Notes: #define Z3_H_ #include -#include"z3_macros.h" -#include"z3_api.h" -#include"z3_ast_containers.h" -#include"z3_algebraic.h" -#include"z3_polynomial.h" -#include"z3_rcf.h" -#include"z3_fixedpoint.h" -#include"z3_optimization.h" -#include"z3_interp.h" -#include"z3_fpa.h" +#include "api/z3_macros.h" +#include "api/z3_api.h" +#include "api/z3_ast_containers.h" +#include "api/z3_algebraic.h" +#include "api/z3_polynomial.h" +#include "api/z3_rcf.h" +#include "api/z3_fixedpoint.h" +#include "api/z3_optimization.h" +#include "api/z3_interp.h" +#include "api/z3_fpa.h" #endif diff --git a/src/api/z3_logger.h b/src/api/z3_logger.h index 4d83f90c2..dd2816bff 100644 --- a/src/api/z3_logger.h +++ b/src/api/z3_logger.h @@ -17,7 +17,7 @@ Notes: --*/ #include -#include"symbol.h" +#include "util/symbol.h" struct ll_escaped { char const * m_str; ll_escaped(char const * str):m_str(str) {} }; static std::ostream & operator<<(std::ostream & out, ll_escaped const & d); diff --git a/src/api/z3_private.h b/src/api/z3_private.h index e5fe4b521..7b60a6ab9 100644 --- a/src/api/z3_private.h +++ b/src/api/z3_private.h @@ -19,8 +19,8 @@ Notes: --*/ #include -#include"rational.h" -#include"z3_macros.h" +#include "util/rational.h" +#include "api/z3_macros.h" #ifndef Z3_PRIVATE_H_ #define Z3_PRIVATE_H_ diff --git a/src/api/z3_replayer.cpp b/src/api/z3_replayer.cpp index 68f279e3d..84dcfc363 100644 --- a/src/api/z3_replayer.cpp +++ b/src/api/z3_replayer.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"vector.h" -#include"map.h" -#include"z3_replayer.h" -#include"stream_buffer.h" -#include"symbol.h" -#include"trace.h" +#include "util/vector.h" +#include "util/map.h" +#include "api/z3_replayer.h" +#include "util/stream_buffer.h" +#include "util/symbol.h" +#include "util/trace.h" #include #include diff --git a/src/api/z3_replayer.h b/src/api/z3_replayer.h index 88654363d..e1b32af75 100644 --- a/src/api/z3_replayer.h +++ b/src/api/z3_replayer.h @@ -20,8 +20,8 @@ Notes: #define Z3_REPLAYER_H_ #include -#include"z3.h" -#include"z3_exception.h" +#include "api/z3.h" +#include "util/z3_exception.h" class z3_replayer; diff --git a/src/api/z3_v1.h b/src/api/z3_v1.h index 11f492d88..66de943c2 100644 --- a/src/api/z3_v1.h +++ b/src/api/z3_v1.h @@ -21,7 +21,7 @@ Notes: #ifndef Z3_V1_H_ #define Z3_V1_H_ -#include"z3.h" +#include "api/z3.h" // Backwards compatibility #define Z3_type_ast Z3_sort diff --git a/src/ast/act_cache.cpp b/src/ast/act_cache.cpp index 1d1341184..74a7d6fca 100644 --- a/src/ast/act_cache.cpp +++ b/src/ast/act_cache.cpp @@ -17,7 +17,7 @@ Author: Notes: --*/ -#include"act_cache.h" +#include "ast/act_cache.h" #define MIN_MAX_UNUSED 1024 #define INITIAL_CAPACITY 128 diff --git a/src/ast/act_cache.h b/src/ast/act_cache.h index b3567dec2..67c5cf050 100644 --- a/src/ast/act_cache.h +++ b/src/ast/act_cache.h @@ -20,9 +20,9 @@ Notes: #ifndef ACT_CACHE_H_ #define ACT_CACHE_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"chashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "util/chashtable.h" class act_cache { ast_manager & m_manager; diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 12d1a4307..fa169316b 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"arith_decl_plugin.h" -#include"warning.h" -#include"algebraic_numbers.h" -#include"id_gen.h" -#include"ast_smt2_pp.h" +#include "ast/arith_decl_plugin.h" +#include "util/warning.h" +#include "math/polynomial/algebraic_numbers.h" +#include "util/id_gen.h" +#include "ast/ast_smt2_pp.h" struct arith_decl_plugin::algebraic_numbers_wrapper { unsynch_mpq_manager m_qmanager; diff --git a/src/ast/arith_decl_plugin.h b/src/ast/arith_decl_plugin.h index 43bf4be65..a66ddd967 100644 --- a/src/ast/arith_decl_plugin.h +++ b/src/ast/arith_decl_plugin.h @@ -19,7 +19,7 @@ Revision History: #ifndef ARITH_DECL_PLUGIN_H_ #define ARITH_DECL_PLUGIN_H_ -#include"ast.h" +#include "ast/ast.h" class sexpr; namespace algebraic_numbers { diff --git a/src/ast/array_decl_plugin.cpp b/src/ast/array_decl_plugin.cpp index ab21c4c88..efcad1d5e 100644 --- a/src/ast/array_decl_plugin.cpp +++ b/src/ast/array_decl_plugin.cpp @@ -17,10 +17,10 @@ Revision History: --*/ #include -#include"array_decl_plugin.h" -#include"warning.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "ast/array_decl_plugin.h" +#include "util/warning.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" array_decl_plugin::array_decl_plugin(): m_store_sym("store"), diff --git a/src/ast/array_decl_plugin.h b/src/ast/array_decl_plugin.h index 36a8d50a5..e06cb3065 100644 --- a/src/ast/array_decl_plugin.h +++ b/src/ast/array_decl_plugin.h @@ -19,7 +19,7 @@ Revision History: #ifndef ARRAY_DECL_PLUGIN_H_ #define ARRAY_DECL_PLUGIN_H_ -#include"ast.h" +#include "ast/ast.h" inline sort* get_array_range(sort const * s) { diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 1c3be5e68..88055d73b 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -18,14 +18,14 @@ Revision History: --*/ #include #include -#include"ast.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"buffer.h" -#include"warning.h" -#include"string_buffer.h" -#include"ast_util.h" -#include"ast_smt2_pp.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "util/buffer.h" +#include "util/warning.h" +#include "util/string_buffer.h" +#include "ast/ast_util.h" +#include "ast/ast_smt2_pp.h" // ----------------------------------- // diff --git a/src/ast/ast.h b/src/ast/ast.h index f71d5135c..277cdfca9 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -19,32 +19,32 @@ Revision History: #ifndef AST_H_ #define AST_H_ -#include"vector.h" -#include"hashtable.h" -#include"buffer.h" -#include"symbol.h" -#include"rational.h" -#include"hash.h" -#include"optional.h" -#include"trace.h" -#include"bit_vector.h" -#include"symbol_table.h" -#include"tptr.h" -#include"memory_manager.h" -#include"small_object_allocator.h" -#include"obj_ref.h" -#include"ref_vector.h" -#include"ref_buffer.h" -#include"obj_mark.h" -#include"obj_hashtable.h" -#include"id_gen.h" -#include"map.h" -#include"parray.h" -#include"dictionary.h" -#include"chashtable.h" -#include"z3_exception.h" -#include"dependency.h" -#include"rlimit.h" +#include "util/vector.h" +#include "util/hashtable.h" +#include "util/buffer.h" +#include "util/symbol.h" +#include "util/rational.h" +#include "util/hash.h" +#include "util/optional.h" +#include "util/trace.h" +#include "util/bit_vector.h" +#include "util/symbol_table.h" +#include "util/tptr.h" +#include "util/memory_manager.h" +#include "util/small_object_allocator.h" +#include "util/obj_ref.h" +#include "util/ref_vector.h" +#include "util/ref_buffer.h" +#include "util/obj_mark.h" +#include "util/obj_hashtable.h" +#include "util/id_gen.h" +#include "util/map.h" +#include "util/parray.h" +#include "util/dictionary.h" +#include "util/chashtable.h" +#include "util/z3_exception.h" +#include "util/dependency.h" +#include "util/rlimit.h" #define RECYCLE_FREE_AST_INDICES diff --git a/src/ast/ast_ll_pp.cpp b/src/ast/ast_ll_pp.cpp index 3dc660681..c00053780 100644 --- a/src/ast/ast_ll_pp.cpp +++ b/src/ast/ast_ll_pp.cpp @@ -18,8 +18,8 @@ Revision History: --*/ #include -#include"for_each_ast.h" -#include"arith_decl_plugin.h" +#include "ast/for_each_ast.h" +#include "ast/arith_decl_plugin.h" // #define AST_LL_PP_SHOW_FAMILY_NAME diff --git a/src/ast/ast_ll_pp.h b/src/ast/ast_ll_pp.h index 7fc527833..19d5679b6 100644 --- a/src/ast/ast_ll_pp.h +++ b/src/ast/ast_ll_pp.h @@ -19,7 +19,7 @@ Revision History: #ifndef AST_LL_PP_H_ #define AST_LL_PP_H_ -#include"ast.h" +#include "ast/ast.h" #include void ast_ll_pp(std::ostream & out, ast_manager & m, ast * n, bool only_exprs=true, bool compact=true); diff --git a/src/ast/ast_lt.cpp b/src/ast/ast_lt.cpp index 2fba4f7a6..b6b52966e 100644 --- a/src/ast/ast_lt.cpp +++ b/src/ast/ast_lt.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"ast.h" +#include "ast/ast.h" #define check_symbol(S1,S2) if (S1 != S2) return lt(S1,S2) #define check_value(V1,V2) if (V1 != V2) return V1 < V2 diff --git a/src/ast/ast_pp.h b/src/ast/ast_pp.h index ecd7e3b13..997b1a6e0 100644 --- a/src/ast/ast_pp.h +++ b/src/ast/ast_pp.h @@ -21,7 +21,7 @@ Revision History: #ifndef AST_PP_H_ #define AST_PP_H_ -#include"ast_smt2_pp.h" +#include "ast/ast_smt2_pp.h" struct mk_pp : public mk_ismt2_pp { mk_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0): diff --git a/src/ast/ast_pp_util.cpp b/src/ast/ast_pp_util.cpp index 3021b702b..677422b8a 100644 --- a/src/ast/ast_pp_util.cpp +++ b/src/ast/ast_pp_util.cpp @@ -17,9 +17,9 @@ Revision History: --*/ -#include "ast_pp_util.h" -#include "ast_smt2_pp.h" -#include "ast_smt_pp.h" +#include "ast/ast_pp_util.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_smt_pp.h" void ast_pp_util::collect(expr* e) { coll.visit(e); diff --git a/src/ast/ast_pp_util.h b/src/ast/ast_pp_util.h index a5aac2136..964a862a2 100644 --- a/src/ast/ast_pp_util.h +++ b/src/ast/ast_pp_util.h @@ -19,7 +19,7 @@ Revision History: #ifndef AST_PP_UTIL_H_ #define AST_PP_UTIL_H_ -#include "decl_collector.h" +#include "ast/decl_collector.h" class ast_pp_util { ast_manager& m; diff --git a/src/ast/ast_printer.cpp b/src/ast/ast_printer.cpp index 8d6ed91f7..b5cf60ee9 100644 --- a/src/ast/ast_printer.cpp +++ b/src/ast/ast_printer.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"ast_printer.h" -#include"pp.h" +#include "ast/ast_printer.h" +#include "ast/pp.h" class simple_ast_printer_context : public ast_printer_context { ast_manager & m_manager; diff --git a/src/ast/ast_printer.h b/src/ast/ast_printer.h index 78fe822f6..87fa8ef3d 100644 --- a/src/ast/ast_printer.h +++ b/src/ast/ast_printer.h @@ -19,8 +19,8 @@ Revision History: #ifndef AST_PRINTER_H_ #define AST_PRINTER_H_ -#include"ast.h" -#include"ast_smt2_pp.h" +#include "ast/ast.h" +#include "ast/ast_smt2_pp.h" class ast_printer { public: diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index f97397108..89cab9de4 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -18,12 +18,12 @@ Author: Revision History: --*/ -#include"ast_smt2_pp.h" -#include"shared_occs.h" -#include"pp.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"algebraic_numbers.h" +#include "ast/ast_smt2_pp.h" +#include "ast/shared_occs.h" +#include "ast/pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "math/polynomial/algebraic_numbers.h" #include"pp_params.hpp" using namespace format_ns; diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h index c3e72f7bc..3e8b1aa39 100644 --- a/src/ast/ast_smt2_pp.h +++ b/src/ast/ast_smt2_pp.h @@ -22,16 +22,16 @@ Revision History: #ifndef AST_SMT2_PP_H_ #define AST_SMT2_PP_H_ -#include"format.h" -#include"params.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"fpa_decl_plugin.h" -#include"dl_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"smt2_util.h" +#include "ast/format.h" +#include "util/params.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "ast/dl_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "util/smt2_util.h" class smt2_pp_environment { protected: diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index fe02f24a0..9ebfdfbef 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -21,17 +21,17 @@ Revision History: #include #include -#include"ast_smt_pp.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"fpa_decl_plugin.h" -#include"vector.h" -#include"for_each_ast.h" -#include"decl_collector.h" -#include"smt2_util.h" -#include"seq_decl_plugin.h" +#include "ast/ast_smt_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "util/vector.h" +#include "ast/for_each_ast.h" +#include "ast/decl_collector.h" +#include "util/smt2_util.h" +#include "ast/seq_decl_plugin.h" // --------------------------------------- // smt_renaming diff --git a/src/ast/ast_smt_pp.h b/src/ast/ast_smt_pp.h index e88465828..dd2a6d753 100644 --- a/src/ast/ast_smt_pp.h +++ b/src/ast/ast_smt_pp.h @@ -19,9 +19,9 @@ Revision History: #ifndef AST_SMT_PP_H_ #define AST_SMT_PP_H_ -#include"ast.h" +#include "ast/ast.h" #include -#include"map.h" +#include "util/map.h" class smt_renaming { typedef map symbol2symbol; diff --git a/src/ast/ast_trail.h b/src/ast/ast_trail.h index 4e2c542fd..d5245bd77 100644 --- a/src/ast/ast_trail.h +++ b/src/ast/ast_trail.h @@ -22,8 +22,8 @@ Revision History: #ifndef AST_TRAIL_H_ #define AST_TRAIL_H_ -#include"ast.h" -#include"trail.h" +#include "ast/ast.h" +#include "util/trail.h" template diff --git a/src/ast/ast_translation.cpp b/src/ast/ast_translation.cpp index 4b1a80908..0c56b6de6 100644 --- a/src/ast/ast_translation.cpp +++ b/src/ast/ast_translation.cpp @@ -16,13 +16,13 @@ Author: Revision History: --*/ -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "datatype_decl_plugin.h" -#include "array_decl_plugin.h" -#include "format.h" -#include "ast_translation.h" -#include "ast_ll_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/format.h" +#include "ast/ast_translation.h" +#include "ast/ast_ll_pp.h" ast_translation::~ast_translation() { reset_cache(); diff --git a/src/ast/ast_translation.h b/src/ast/ast_translation.h index ec187110b..b278791d7 100644 --- a/src/ast/ast_translation.h +++ b/src/ast/ast_translation.h @@ -21,7 +21,7 @@ Revision History: #ifndef AST_TRANSLATION_H_ #define AST_TRANSLATION_H_ -#include"ast.h" +#include "ast/ast.h" class ast_translation { struct frame { diff --git a/src/ast/ast_util.cpp b/src/ast/ast_util.cpp index 0129a88d5..68f5b2486 100644 --- a/src/ast/ast_util.cpp +++ b/src/ast/ast_util.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include "ast_util.h" +#include "ast/ast_util.h" app * mk_list_assoc_app(ast_manager & m, func_decl * f, unsigned num_args, expr * const * args) { SASSERT(f->is_associative()); diff --git a/src/ast/ast_util.h b/src/ast/ast_util.h index 6244e16b9..446854f5e 100644 --- a/src/ast/ast_util.h +++ b/src/ast/ast_util.h @@ -19,8 +19,8 @@ Revision History: #ifndef AST_UTIL_H_ #define AST_UTIL_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" template void remove_duplicates(C & v) { diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index 321943c72..4632b6604 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -17,11 +17,11 @@ Revision History: --*/ #include -#include"bv_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"warning.h" -#include"ast_pp.h" -#include"ast_smt2_pp.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "util/warning.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" bv_decl_plugin::bv_decl_plugin(): m_bv_sym("bv"), diff --git a/src/ast/bv_decl_plugin.h b/src/ast/bv_decl_plugin.h index 33cf094b9..5e533cd98 100644 --- a/src/ast/bv_decl_plugin.h +++ b/src/ast/bv_decl_plugin.h @@ -19,7 +19,7 @@ Revision History: #ifndef BV_DECL_PLUGIN_H_ #define BV_DECL_PLUGIN_H_ -#include"ast.h" +#include "ast/ast.h" enum bv_sort_kind { BV_SORT diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index 34b092ee9..b4f30767f 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"datatype_decl_plugin.h" -#include"warning.h" -#include"ast_smt2_pp.h" +#include "ast/datatype_decl_plugin.h" +#include "util/warning.h" +#include "ast/ast_smt2_pp.h" /** diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index b2bcf3ab0..3d008ad9c 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -19,10 +19,10 @@ Revision History: #ifndef DATATYPE_DECL_PLUGIN_H_ #define DATATYPE_DECL_PLUGIN_H_ -#include"ast.h" -#include"tptr.h" -#include"buffer.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/tptr.h" +#include "util/buffer.h" +#include "util/obj_hashtable.h" enum datatype_sort_kind { DATATYPE_SORT diff --git a/src/ast/decl_collector.cpp b/src/ast/decl_collector.cpp index 773ebefc7..e000f43df 100644 --- a/src/ast/decl_collector.cpp +++ b/src/ast/decl_collector.cpp @@ -17,7 +17,7 @@ Author: Revision History: --*/ -#include"decl_collector.h" +#include "ast/decl_collector.h" void decl_collector::visit_sort(sort * n) { family_id fid = n->get_family_id(); diff --git a/src/ast/decl_collector.h b/src/ast/decl_collector.h index 0067d18eb..053d6df41 100644 --- a/src/ast/decl_collector.h +++ b/src/ast/decl_collector.h @@ -20,8 +20,8 @@ Revision History: #ifndef SMT_DECL_COLLECTOR_H_ #define SMT_DECL_COLLECTOR_H_ -#include"ast.h" -#include"datatype_decl_plugin.h" +#include "ast/ast.h" +#include "ast/datatype_decl_plugin.h" class decl_collector { ast_manager & m_manager; diff --git a/src/ast/dl_decl_plugin.cpp b/src/ast/dl_decl_plugin.cpp index f7d6d9d1c..1be3c4756 100644 --- a/src/ast/dl_decl_plugin.cpp +++ b/src/ast/dl_decl_plugin.cpp @@ -18,12 +18,12 @@ Revision History: --*/ #include -#include "ast_pp.h" -#include "array_decl_plugin.h" -#include "datatype_decl_plugin.h" -#include "dl_decl_plugin.h" -#include "warning.h" -#include "reg_decl_plugins.h" +#include "ast/ast_pp.h" +#include "ast/array_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/dl_decl_plugin.h" +#include "util/warning.h" +#include "ast/reg_decl_plugins.h" namespace datalog { diff --git a/src/ast/dl_decl_plugin.h b/src/ast/dl_decl_plugin.h index 66ce45c3c..75969d385 100644 --- a/src/ast/dl_decl_plugin.h +++ b/src/ast/dl_decl_plugin.h @@ -19,9 +19,9 @@ Revision History: #ifndef DL_DECL_PLUGIN_H_ #define DL_DECL_PLUGIN_H_ -#include"ast.h" -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" namespace datalog { diff --git a/src/ast/expr2polynomial.cpp b/src/ast/expr2polynomial.cpp index a06ce7e2a..7413624cd 100644 --- a/src/ast/expr2polynomial.cpp +++ b/src/ast/expr2polynomial.cpp @@ -17,13 +17,13 @@ Author: Notes: --*/ -#include"expr2polynomial.h" -#include"expr2var.h" -#include"arith_decl_plugin.h" -#include"ast_smt2_pp.h" -#include"z3_exception.h" -#include"cooperate.h" -#include"common_msgs.h" +#include "ast/expr2polynomial.h" +#include "ast/expr2var.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_smt2_pp.h" +#include "util/z3_exception.h" +#include "util/cooperate.h" +#include "util/common_msgs.h" struct expr2polynomial::imp { struct frame { diff --git a/src/ast/expr2polynomial.h b/src/ast/expr2polynomial.h index 6b2fd6116..e7cbac6e5 100644 --- a/src/ast/expr2polynomial.h +++ b/src/ast/expr2polynomial.h @@ -20,8 +20,8 @@ Notes: #ifndef EXPR2POLYNOMIAL_H_ #define EXPR2POLYNOMIAL_H_ -#include"ast.h" -#include"polynomial.h" +#include "ast/ast.h" +#include "math/polynomial/polynomial.h" class expr2var; diff --git a/src/ast/expr2var.cpp b/src/ast/expr2var.cpp index a0d93a620..2f850d645 100644 --- a/src/ast/expr2var.cpp +++ b/src/ast/expr2var.cpp @@ -20,9 +20,9 @@ Author: Notes: --*/ -#include"expr2var.h" -#include"ast_smt2_pp.h" -#include"ref_util.h" +#include "ast/expr2var.h" +#include "ast/ast_smt2_pp.h" +#include "util/ref_util.h" void expr2var::insert(expr * n, var v) { if (!is_uninterp_const(n)) { diff --git a/src/ast/expr2var.h b/src/ast/expr2var.h index 43d9c31f4..2b4d8c3fe 100644 --- a/src/ast/expr2var.h +++ b/src/ast/expr2var.h @@ -23,8 +23,8 @@ Notes: #ifndef EXPR2VAR_H_ #define EXPR2VAR_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" /** \brief The mapping between Z3 expressions and (low level) variables. diff --git a/src/ast/expr_abstract.cpp b/src/ast/expr_abstract.cpp index 513162043..46682eed6 100644 --- a/src/ast/expr_abstract.cpp +++ b/src/ast/expr_abstract.cpp @@ -17,8 +17,8 @@ Notes: --*/ -#include "expr_abstract.h" -#include "map.h" +#include "ast/expr_abstract.h" +#include "util/map.h" void expr_abstractor::operator()(unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) { diff --git a/src/ast/expr_abstract.h b/src/ast/expr_abstract.h index 5c91a914e..84fb8c2b0 100644 --- a/src/ast/expr_abstract.h +++ b/src/ast/expr_abstract.h @@ -19,7 +19,7 @@ Notes: #ifndef EXPR_ABSTRACT_H_ #define EXPR_ABSTRACT_H_ -#include"ast.h" +#include "ast/ast.h" class expr_abstractor { ast_manager& m; diff --git a/src/ast/expr_functors.cpp b/src/ast/expr_functors.cpp index 592d96a68..4906ed3d7 100644 --- a/src/ast/expr_functors.cpp +++ b/src/ast/expr_functors.cpp @@ -19,7 +19,7 @@ Revision History: --*/ -#include "expr_functors.h" +#include "ast/expr_functors.h" // ---------- // check_pred diff --git a/src/ast/expr_functors.h b/src/ast/expr_functors.h index da2b43dea..322b9402a 100644 --- a/src/ast/expr_functors.h +++ b/src/ast/expr_functors.h @@ -22,8 +22,8 @@ Revision History: #ifndef EXPR_FUNCTORS_H_ #define EXPR_FUNCTORS_H_ -#include "ast.h" -#include "expr_map.h" +#include "ast/ast.h" +#include "ast/expr_map.h" class i_expr_pred { public: diff --git a/src/ast/expr_map.cpp b/src/ast/expr_map.cpp index 87db2186b..89fcccb00 100644 --- a/src/ast/expr_map.cpp +++ b/src/ast/expr_map.cpp @@ -18,8 +18,8 @@ Author: Notes: --*/ -#include"expr_map.h" -#include"dec_ref_util.h" +#include "ast/expr_map.h" +#include "util/dec_ref_util.h" expr_map::expr_map(ast_manager & m): m_manager(m), diff --git a/src/ast/expr_map.h b/src/ast/expr_map.h index 2b49a4a30..b32d52092 100644 --- a/src/ast/expr_map.h +++ b/src/ast/expr_map.h @@ -21,8 +21,8 @@ Notes: #ifndef EXPR_MAP_H_ #define EXPR_MAP_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" /** \brief Map from expressions to expressions+proofs. diff --git a/src/ast/expr_stat.cpp b/src/ast/expr_stat.cpp index 8ac259afa..689edc263 100644 --- a/src/ast/expr_stat.cpp +++ b/src/ast/expr_stat.cpp @@ -19,8 +19,8 @@ Author: Revision History: --*/ -#include"for_each_expr.h" -#include"expr_stat.h" +#include "ast/for_each_expr.h" +#include "ast/expr_stat.h" void get_expr_stat(expr * n, expr_stat & r) { typedef std::pair pair; diff --git a/src/ast/expr_substitution.cpp b/src/ast/expr_substitution.cpp index 8d6f0319c..149a59ce5 100644 --- a/src/ast/expr_substitution.cpp +++ b/src/ast/expr_substitution.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"expr_substitution.h" -#include"ref_util.h" +#include "ast/expr_substitution.h" +#include "util/ref_util.h" typedef obj_map expr2proof; typedef obj_map expr2expr_dependency; diff --git a/src/ast/expr_substitution.h b/src/ast/expr_substitution.h index 073b56110..d209ab6b4 100644 --- a/src/ast/expr_substitution.h +++ b/src/ast/expr_substitution.h @@ -19,7 +19,7 @@ Notes: #ifndef EXPR_SUBSTITUTION_H_ #define EXPR_SUBSTITUTION_H_ -#include"ast.h" +#include "ast/ast.h" class expr_substitution { ast_manager & m_manager; diff --git a/src/ast/for_each_ast.cpp b/src/ast/for_each_ast.cpp index f5b8218ae..77e975b98 100644 --- a/src/ast/for_each_ast.cpp +++ b/src/ast/for_each_ast.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"for_each_ast.h" +#include "ast/for_each_ast.h" struct ast_counter_proc { unsigned m_num; diff --git a/src/ast/for_each_ast.h b/src/ast/for_each_ast.h index a254ed058..0b70eb1a1 100644 --- a/src/ast/for_each_ast.h +++ b/src/ast/for_each_ast.h @@ -19,9 +19,9 @@ Revision History: #ifndef FOR_EACH_AST_H_ #define FOR_EACH_AST_H_ -#include"ast.h" -#include"trace.h" -#include"map.h" +#include "ast/ast.h" +#include "util/trace.h" +#include "util/map.h" template bool for_each_ast_args(ptr_vector & stack, ast_mark & visited, unsigned num_args, T * const * args) { diff --git a/src/ast/for_each_expr.cpp b/src/ast/for_each_expr.cpp index cca42b01c..d46388801 100644 --- a/src/ast/for_each_expr.cpp +++ b/src/ast/for_each_expr.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"for_each_expr.h" +#include "ast/for_each_expr.h" struct expr_counter_proc { unsigned m_num; diff --git a/src/ast/for_each_expr.h b/src/ast/for_each_expr.h index 3f5dbaac7..50a4089dc 100644 --- a/src/ast/for_each_expr.h +++ b/src/ast/for_each_expr.h @@ -19,8 +19,8 @@ Revision History: #ifndef FOR_EACH_EXPR_H_ #define FOR_EACH_EXPR_H_ -#include"ast.h" -#include"trace.h" +#include "ast/ast.h" +#include "util/trace.h" template void for_each_expr_core(ForEachProc & proc, ExprMark & visited, expr * n) { diff --git a/src/ast/format.cpp b/src/ast/format.cpp index 1a36ca8ae..835892121 100644 --- a/src/ast/format.cpp +++ b/src/ast/format.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"format.h" -#include"recurse_expr_def.h" +#include "ast/format.h" +#include "ast/recurse_expr_def.h" namespace format_ns { diff --git a/src/ast/format.h b/src/ast/format.h index a41ed9bd9..827f9bc1c 100644 --- a/src/ast/format.h +++ b/src/ast/format.h @@ -19,7 +19,7 @@ Revision History: #ifndef FORMAT_H_ #define FORMAT_H_ -#include"ast.h" +#include "ast/ast.h" namespace format_ns { typedef app format; diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index c113627f9..7e4f2f133 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -18,12 +18,12 @@ Notes: --*/ #include -#include"ast_smt2_pp.h" -#include"well_sorted.h" -#include"th_rewriter.h" -#include"fpa_rewriter.h" +#include "ast/ast_smt2_pp.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/fpa_rewriter.h" -#include"bv2fpa_converter.h" +#include "ast/fpa/bv2fpa_converter.h" bv2fpa_converter::bv2fpa_converter(ast_manager & m) : diff --git a/src/ast/fpa/bv2fpa_converter.h b/src/ast/fpa/bv2fpa_converter.h index 5150056c4..943f544ca 100644 --- a/src/ast/fpa/bv2fpa_converter.h +++ b/src/ast/fpa/bv2fpa_converter.h @@ -19,11 +19,11 @@ Notes: #ifndef BV2FPA_CONVERTER_H_ #define BV2FPA_CONVERTER_H_ -#include"fpa_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"th_rewriter.h" -#include"model_core.h" -#include"fpa2bv_converter.h" +#include "ast/fpa_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/th_rewriter.h" +#include "model/model_core.h" +#include "ast/fpa/fpa2bv_converter.h" class bv2fpa_converter { diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 864293380..228795c41 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -18,12 +18,12 @@ Notes: --*/ #include -#include"ast_smt2_pp.h" -#include"well_sorted.h" -#include"th_rewriter.h" +#include "ast/ast_smt2_pp.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/th_rewriter.h" -#include"fpa2bv_converter.h" -#include"fpa_rewriter.h" +#include "ast/fpa/fpa2bv_converter.h" +#include "ast/rewriter/fpa_rewriter.h" #define BVULT(X,Y,R) { expr_ref bvult_eq(m), bvult_not(m); m_simp.mk_eq(X, Y, bvult_eq); m_simp.mk_not(bvult_eq, bvult_not); expr_ref t(m); t = m_bv_util.mk_ule(X,Y); m_simp.mk_and(t, bvult_not, R); } diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 34417b7fc..19a52dd23 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -19,17 +19,17 @@ Notes: #ifndef FPA2BV_CONVERTER_H_ #define FPA2BV_CONVERTER_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"ref_util.h" -#include"fpa_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"dl_decl_plugin.h" -#include"pb_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"basic_simplifier_plugin.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "util/ref_util.h" +#include "ast/fpa_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/dl_decl_plugin.h" +#include "ast/pb_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/simplifier/basic_simplifier_plugin.h" class fpa2bv_converter { public: diff --git a/src/ast/fpa/fpa2bv_rewriter.cpp b/src/ast/fpa/fpa2bv_rewriter.cpp index 32b62342b..57cd9facc 100644 --- a/src/ast/fpa/fpa2bv_rewriter.cpp +++ b/src/ast/fpa/fpa2bv_rewriter.cpp @@ -18,9 +18,9 @@ Notes: --*/ -#include"rewriter_def.h" -#include"fpa2bv_rewriter.h" -#include"cooperate.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/fpa/fpa2bv_rewriter.h" +#include "util/cooperate.h" #include"fpa2bv_rewriter_params.hpp" diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index a130c445b..ab87a3d68 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -20,9 +20,9 @@ Notes: #ifndef FPA2BV_REWRITER_H_ #define FPA2BV_REWRITER_H_ -#include"rewriter.h" -#include"bv_decl_plugin.h" -#include"fpa2bv_converter.h" +#include "ast/rewriter/rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/fpa/fpa2bv_converter.h" struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { ast_manager & m_manager; diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index e039bcbd9..fc69c5f89 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"fpa_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" fpa_decl_plugin::fpa_decl_plugin(): m_values(m_fm), diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index cf341a07b..0cba3ae62 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -19,11 +19,11 @@ Revision History: #ifndef fpa_decl_plugin_H_ #define fpa_decl_plugin_H_ -#include"ast.h" -#include"id_gen.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"mpf.h" +#include "ast/ast.h" +#include "util/id_gen.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "util/mpf.h" enum fpa_sort_kind { FLOATING_POINT_SORT, diff --git a/src/ast/func_decl_dependencies.cpp b/src/ast/func_decl_dependencies.cpp index d53c2d9b1..a5412f206 100644 --- a/src/ast/func_decl_dependencies.cpp +++ b/src/ast/func_decl_dependencies.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"func_decl_dependencies.h" -#include"for_each_expr.h" -#include"ast_util.h" +#include "ast/func_decl_dependencies.h" +#include "ast/for_each_expr.h" +#include "ast/ast_util.h" struct collect_dependencies_proc { ast_manager & m_manager; diff --git a/src/ast/func_decl_dependencies.h b/src/ast/func_decl_dependencies.h index e354540c2..0a3c1892f 100644 --- a/src/ast/func_decl_dependencies.h +++ b/src/ast/func_decl_dependencies.h @@ -19,8 +19,8 @@ Revision History: #ifndef FUNC_DECL_DEPENDENCIES_H_ #define FUNC_DECL_DEPENDENCIES_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" // Set of dependencies typedef obj_hashtable func_decl_set; diff --git a/src/ast/has_free_vars.cpp b/src/ast/has_free_vars.cpp index ba2c9eeb8..09d6d7740 100644 --- a/src/ast/has_free_vars.cpp +++ b/src/ast/has_free_vars.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"ast.h" -#include"expr_delta_pair.h" -#include"hashtable.h" +#include "ast/ast.h" +#include "ast/expr_delta_pair.h" +#include "util/hashtable.h" class contains_vars { typedef hashtable, default_eq > cache; diff --git a/src/ast/macro_substitution.cpp b/src/ast/macro_substitution.cpp index 9cf337d21..7b4cd6244 100644 --- a/src/ast/macro_substitution.cpp +++ b/src/ast/macro_substitution.cpp @@ -18,8 +18,8 @@ Author: Notes: --*/ -#include"macro_substitution.h" -#include"ref_util.h" +#include "ast/macro_substitution.h" +#include "util/ref_util.h" typedef obj_map func_decl2proof; typedef obj_map func_decl2expr_dependency; diff --git a/src/ast/macro_substitution.h b/src/ast/macro_substitution.h index 356449590..7c65421fd 100644 --- a/src/ast/macro_substitution.h +++ b/src/ast/macro_substitution.h @@ -21,7 +21,7 @@ Notes: #ifndef MACRO_SUBSTITUTION_H_ #define MACRO_SUBSTITUTION_H_ -#include"ast.h" +#include "ast/ast.h" class macro_substitution { ast_manager & m_manager; diff --git a/src/ast/macros/macro_finder.cpp b/src/ast/macros/macro_finder.cpp index ee211c44f..285c0e5fb 100644 --- a/src/ast/macros/macro_finder.cpp +++ b/src/ast/macros/macro_finder.cpp @@ -17,10 +17,10 @@ Revision History: --*/ -#include"macro_finder.h" -#include"occurs.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "ast/macros/macro_finder.h" +#include "ast/occurs.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) diff --git a/src/ast/macros/macro_finder.h b/src/ast/macros/macro_finder.h index 04ec11939..7f1b27f0e 100644 --- a/src/ast/macros/macro_finder.h +++ b/src/ast/macros/macro_finder.h @@ -19,8 +19,8 @@ Revision History: #ifndef MACRO_FINDER_H_ #define MACRO_FINDER_H_ -#include"macro_manager.h" -#include"arith_simplifier_plugin.h" +#include "ast/macros/macro_manager.h" +#include "ast/simplifier/arith_simplifier_plugin.h" bool is_macro_head(expr * n, unsigned num_decls); diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index b17e1ce28..bd330a2de 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -19,11 +19,11 @@ Revision History: Leonardo de Moura (leonardo) 2010-12-15: Moved dependency management to func_decl_dependencies.h --*/ -#include"macro_manager.h" -#include"for_each_expr.h" -#include"var_subst.h" -#include"ast_pp.h" -#include"recurse_expr_def.h" +#include "ast/macros/macro_manager.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_pp.h" +#include "ast/recurse_expr_def.h" macro_manager::macro_manager(ast_manager & m, simplifier & s): m_manager(m), diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index bc015de41..a0a42b790 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -19,12 +19,12 @@ Revision History: #ifndef MACRO_MANAGER_H_ #define MACRO_MANAGER_H_ -#include"ast_util.h" -#include"obj_hashtable.h" -#include"simplifier.h" -#include"recurse_expr.h" -#include"func_decl_dependencies.h" -#include"macro_util.h" +#include "ast/ast_util.h" +#include "util/obj_hashtable.h" +#include "ast/simplifier/simplifier.h" +#include "ast/recurse_expr.h" +#include "ast/func_decl_dependencies.h" +#include "ast/macros/macro_util.h" /** \brief Macros are universally quantified formulas of the form: diff --git a/src/ast/macros/macro_util.cpp b/src/ast/macros/macro_util.cpp index fce6f1b28..35f2fbcfb 100644 --- a/src/ast/macros/macro_util.cpp +++ b/src/ast/macros/macro_util.cpp @@ -17,17 +17,17 @@ Author: Revision History: --*/ -#include"macro_util.h" -#include"occurs.h" -#include"ast_util.h" -#include"arith_simplifier_plugin.h" -#include"bv_simplifier_plugin.h" -#include"var_subst.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"for_each_expr.h" -#include"well_sorted.h" -#include"bool_rewriter.h" +#include "ast/macros/macro_util.h" +#include "ast/occurs.h" +#include "ast/ast_util.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/for_each_expr.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/bool_rewriter.h" macro_util::macro_util(ast_manager & m, simplifier & s): m_manager(m), diff --git a/src/ast/macros/macro_util.h b/src/ast/macros/macro_util.h index 8aa8e550e..d76f2f0d3 100644 --- a/src/ast/macros/macro_util.h +++ b/src/ast/macros/macro_util.h @@ -20,9 +20,9 @@ Revision History: #ifndef MACRO_UTIL_H_ #define MACRO_UTIL_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"simplifier.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "ast/simplifier/simplifier.h" class poly_simplifier_plugin; class arith_simplifier_plugin; diff --git a/src/ast/macros/quasi_macros.cpp b/src/ast/macros/quasi_macros.cpp index b26b7faba..b39adde03 100644 --- a/src/ast/macros/quasi_macros.cpp +++ b/src/ast/macros/quasi_macros.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"quasi_macros.h" -#include"for_each_expr.h" -#include"ast_pp.h" -#include"uint_set.h" -#include"var_subst.h" +#include "ast/macros/quasi_macros.h" +#include "ast/for_each_expr.h" +#include "ast/ast_pp.h" +#include "util/uint_set.h" +#include "ast/rewriter/var_subst.h" quasi_macros::quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s) : m_manager(m), diff --git a/src/ast/macros/quasi_macros.h b/src/ast/macros/quasi_macros.h index 5640fad30..3a9b6074e 100644 --- a/src/ast/macros/quasi_macros.h +++ b/src/ast/macros/quasi_macros.h @@ -20,9 +20,9 @@ Revision History: #define QUASI_MACROS_H_ #include -#include"macro_manager.h" -#include"basic_simplifier_plugin.h" -#include"simplifier.h" +#include "ast/macros/macro_manager.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/simplifier.h" /** \brief Finds quasi macros and applies them. diff --git a/src/ast/normal_forms/defined_names.cpp b/src/ast/normal_forms/defined_names.cpp index 1ac2049ac..12085b992 100644 --- a/src/ast/normal_forms/defined_names.cpp +++ b/src/ast/normal_forms/defined_names.cpp @@ -16,12 +16,12 @@ Author: Revision History: --*/ -#include"defined_names.h" -#include"obj_hashtable.h" -#include"used_vars.h" -#include"var_subst.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" +#include "ast/normal_forms/defined_names.h" +#include "util/obj_hashtable.h" +#include "ast/used_vars.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_pp.h" struct defined_names::impl { typedef obj_map expr2name; diff --git a/src/ast/normal_forms/defined_names.h b/src/ast/normal_forms/defined_names.h index 69e365f3d..764822f66 100644 --- a/src/ast/normal_forms/defined_names.h +++ b/src/ast/normal_forms/defined_names.h @@ -20,7 +20,7 @@ Revision History: #ifndef DEFINED_NAMES_H_ #define DEFINED_NAMES_H_ -#include"ast.h" +#include "ast/ast.h" /** \brief Mapping from expressions to skolem functions that are used to name them. diff --git a/src/ast/normal_forms/name_exprs.cpp b/src/ast/normal_forms/name_exprs.cpp index 5a2e1659d..7cc2719c9 100644 --- a/src/ast/normal_forms/name_exprs.cpp +++ b/src/ast/normal_forms/name_exprs.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"name_exprs.h" -#include"rewriter_def.h" -#include"ast_smt2_pp.h" +#include "ast/normal_forms/name_exprs.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_smt2_pp.h" class name_exprs_core : public name_exprs { struct cfg : public default_rewriter_cfg { diff --git a/src/ast/normal_forms/name_exprs.h b/src/ast/normal_forms/name_exprs.h index 9403f3d12..9f896190f 100644 --- a/src/ast/normal_forms/name_exprs.h +++ b/src/ast/normal_forms/name_exprs.h @@ -19,8 +19,8 @@ Notes: #ifndef NAME_EXPRS_H_ #define NAME_EXPRS_H_ -#include"ast.h" -#include"defined_names.h" +#include "ast/ast.h" +#include "ast/normal_forms/defined_names.h" class expr_predicate { public: diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index e15e26bf2..cca9c2c93 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -17,18 +17,18 @@ Notes: Major revision on 2011-10-06 --*/ -#include"nnf.h" +#include "ast/normal_forms/nnf.h" #include"nnf_params.hpp" -#include"warning.h" -#include"used_vars.h" -#include"well_sorted.h" -#include"var_subst.h" +#include "util/warning.h" +#include "ast/used_vars.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/var_subst.h" -#include"name_exprs.h" -#include"act_cache.h" -#include"cooperate.h" +#include "ast/normal_forms/name_exprs.h" +#include "ast/act_cache.h" +#include "util/cooperate.h" -#include"ast_smt2_pp.h" +#include "ast/ast_smt2_pp.h" /** \brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and diff --git a/src/ast/normal_forms/nnf.h b/src/ast/normal_forms/nnf.h index 60d50e3b6..073cc91e4 100644 --- a/src/ast/normal_forms/nnf.h +++ b/src/ast/normal_forms/nnf.h @@ -20,9 +20,9 @@ Notes: #ifndef NNF_H_ #define NNF_H_ -#include"ast.h" -#include"params.h" -#include"defined_names.h" +#include "ast/ast.h" +#include "util/params.h" +#include "ast/normal_forms/defined_names.h" class nnf { struct imp; diff --git a/src/ast/normal_forms/pull_quant.cpp b/src/ast/normal_forms/pull_quant.cpp index 74c7cafde..56bada7c1 100644 --- a/src/ast/normal_forms/pull_quant.cpp +++ b/src/ast/normal_forms/pull_quant.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"pull_quant.h" -#include"var_subst.h" -#include"rewriter_def.h" -#include"ast_pp.h" +#include "ast/normal_forms/pull_quant.h" +#include "ast/rewriter/var_subst.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" struct pull_quant::imp { diff --git a/src/ast/normal_forms/pull_quant.h b/src/ast/normal_forms/pull_quant.h index dcdae056b..aadbad651 100644 --- a/src/ast/normal_forms/pull_quant.h +++ b/src/ast/normal_forms/pull_quant.h @@ -19,7 +19,7 @@ Notes: #ifndef PULL_QUANT_H_ #define PULL_QUANT_H_ -#include"ast.h" +#include "ast/ast.h" /** \brief Pull nested quantifiers in a formula. diff --git a/src/ast/num_occurs.cpp b/src/ast/num_occurs.cpp index c5d50475e..2448dd081 100644 --- a/src/ast/num_occurs.cpp +++ b/src/ast/num_occurs.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"num_occurs.h" +#include "ast/num_occurs.h" void num_occurs::process(expr * t, expr_fast_mark1 & visited) { ptr_buffer stack; diff --git a/src/ast/num_occurs.h b/src/ast/num_occurs.h index 3c51dbe5c..92215f440 100644 --- a/src/ast/num_occurs.h +++ b/src/ast/num_occurs.h @@ -19,8 +19,8 @@ Revision History: #ifndef NUM_OCCURS_H_ #define NUM_OCCURS_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" /** \brief Functor for computing the number of occurrences of each sub-expression in a expression F. diff --git a/src/ast/occurs.cpp b/src/ast/occurs.cpp index 9d2360351..c76e73748 100644 --- a/src/ast/occurs.cpp +++ b/src/ast/occurs.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"occurs.h" +#include "ast/occurs.h" -#include"for_each_expr.h" +#include "ast/for_each_expr.h" // ----------------------------------- // diff --git a/src/ast/pattern/expr_pattern_match.cpp b/src/ast/pattern/expr_pattern_match.cpp index e18831650..770832d1f 100644 --- a/src/ast/pattern/expr_pattern_match.cpp +++ b/src/ast/pattern/expr_pattern_match.cpp @@ -29,13 +29,13 @@ Notes: --*/ -#include"ast.h" -#include"expr_pattern_match.h" -#include"for_each_ast.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"cmd_context.h" -#include"smt2parser.h" +#include "ast/ast.h" +#include "ast/pattern/expr_pattern_match.h" +#include "ast/for_each_ast.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "cmd_context/cmd_context.h" +#include "parsers/smt2/smt2parser.h" expr_pattern_match::expr_pattern_match(ast_manager & manager): m_manager(manager), m_precompiled(manager) { diff --git a/src/ast/pattern/expr_pattern_match.h b/src/ast/pattern/expr_pattern_match.h index 245edd877..6d9d47e1e 100644 --- a/src/ast/pattern/expr_pattern_match.h +++ b/src/ast/pattern/expr_pattern_match.h @@ -20,8 +20,8 @@ Notes: #ifndef EXPR_PATTERN_MATCH_H_ #define EXPR_PATTERN_MATCH_H_ -#include"ast.h" -#include"map.h" +#include "ast/ast.h" +#include "util/map.h" class expr_pattern_match { diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index 64ec064a8..25feaed26 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -16,15 +16,15 @@ Author: Revision History: --*/ -#include"pattern_inference.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"ast_util.h" -#include"warning.h" -#include"arith_decl_plugin.h" -#include"pull_quant.h" -#include"well_sorted.h" -#include"for_each_expr.h" +#include "ast/pattern/pattern_inference.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "util/warning.h" +#include "ast/arith_decl_plugin.h" +#include "ast/normal_forms/pull_quant.h" +#include "ast/well_sorted.h" +#include "ast/for_each_expr.h" void smaller_pattern::save(expr * p1, expr * p2) { expr_pair e(p1, p2); @@ -576,7 +576,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings, m_candidates.reset(); } -#include"database.h" // defines g_pattern_database +#include "smt/database.h" void pattern_inference::reduce1_quantifier(quantifier * q) { TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";); diff --git a/src/ast/pattern/pattern_inference.h b/src/ast/pattern/pattern_inference.h index d4ab708e9..a138d1033 100644 --- a/src/ast/pattern/pattern_inference.h +++ b/src/ast/pattern/pattern_inference.h @@ -19,16 +19,16 @@ Revision History: #ifndef PATTERN_INFERENCE_H_ #define PATTERN_INFERENCE_H_ -#include"ast.h" -#include"simplifier.h" -#include"pattern_inference_params.h" -#include"vector.h" -#include"uint_set.h" -#include"nat_set.h" -#include"obj_hashtable.h" -#include"obj_pair_hashtable.h" -#include"map.h" -#include"expr_pattern_match.h" +#include "ast/ast.h" +#include "ast/simplifier/simplifier.h" +#include "ast/pattern/pattern_inference_params.h" +#include "util/vector.h" +#include "util/uint_set.h" +#include "util/nat_set.h" +#include "util/obj_hashtable.h" +#include "util/obj_pair_hashtable.h" +#include "util/map.h" +#include "ast/pattern/expr_pattern_match.h" /** \brief A pattern p_1 is smaller than a pattern p_2 iff diff --git a/src/ast/pattern/pattern_inference_params.cpp b/src/ast/pattern/pattern_inference_params.cpp index b36d372f5..8d978e09c 100644 --- a/src/ast/pattern/pattern_inference_params.cpp +++ b/src/ast/pattern/pattern_inference_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"pattern_inference_params.h" +#include "ast/pattern/pattern_inference_params.h" #include"pattern_inference_params_helper.hpp" void pattern_inference_params::updt_params(params_ref const & _p) { diff --git a/src/ast/pattern/pattern_inference_params.h b/src/ast/pattern/pattern_inference_params.h index 0dc413399..fde64a8eb 100644 --- a/src/ast/pattern/pattern_inference_params.h +++ b/src/ast/pattern/pattern_inference_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef PATTERN_INFERENCE_PARAMS_H_ #define PATTERN_INFERENCE_PARAMS_H_ -#include"params.h" +#include "util/params.h" enum arith_pattern_inference_kind { AP_NO, // do not infer patterns with arithmetic terms diff --git a/src/ast/pb_decl_plugin.cpp b/src/ast/pb_decl_plugin.cpp index 28f889739..06c6aac48 100644 --- a/src/ast/pb_decl_plugin.cpp +++ b/src/ast/pb_decl_plugin.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include "pb_decl_plugin.h" -#include "ast_util.h" +#include "ast/pb_decl_plugin.h" +#include "ast/ast_util.h" pb_decl_plugin::pb_decl_plugin(): m_at_most_sym("at-most"), diff --git a/src/ast/pb_decl_plugin.h b/src/ast/pb_decl_plugin.h index 36b1a9512..7fdb592aa 100644 --- a/src/ast/pb_decl_plugin.h +++ b/src/ast/pb_decl_plugin.h @@ -27,7 +27,7 @@ hence: #ifndef PB_DECL_PLUGIN_H_ #define PB_DECL_PLUGIN_H_ -#include"ast.h" +#include "ast/ast.h" enum pb_op_kind { OP_AT_MOST_K, // at most K Booleans are true. diff --git a/src/ast/pp.cpp b/src/ast/pp.cpp index 13247127d..522d3eca6 100644 --- a/src/ast/pp.cpp +++ b/src/ast/pp.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"pp.h" +#include "ast/pp.h" #include"pp_params.hpp" using namespace format_ns; diff --git a/src/ast/pp.h b/src/ast/pp.h index bfb907552..e702d298a 100644 --- a/src/ast/pp.h +++ b/src/ast/pp.h @@ -19,8 +19,8 @@ Revision History: #ifndef PP_H_ #define PP_H_ -#include"format.h" -#include"params.h" +#include "ast/format.h" +#include "util/params.h" void pp(std::ostream & out, format_ns::format * f, ast_manager & m, params_ref const & p = params_ref()); diff --git a/src/ast/proof_checker/proof_checker.cpp b/src/ast/proof_checker/proof_checker.cpp index 45223cdb7..70eee5920 100644 --- a/src/ast/proof_checker/proof_checker.cpp +++ b/src/ast/proof_checker/proof_checker.cpp @@ -4,14 +4,14 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "proof_checker.h" -#include "ast_ll_pp.h" -#include "ast_pp.h" +#include "ast/proof_checker/proof_checker.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" // include "spc_decl_plugin.h" -#include "ast_smt_pp.h" -#include "arith_decl_plugin.h" -#include "th_rewriter.h" -#include "var_subst.h" +#include "ast/ast_smt_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/var_subst.h" #define IS_EQUIV(_e_) (m.is_eq(_e_) || m.is_iff(_e_)) diff --git a/src/ast/proof_checker/proof_checker.h b/src/ast/proof_checker/proof_checker.h index 5e1a170ee..ce2684c51 100644 --- a/src/ast/proof_checker/proof_checker.h +++ b/src/ast/proof_checker/proof_checker.h @@ -19,8 +19,8 @@ Revision History: #ifndef PROOF_CHECKER_H_ #define PROOF_CHECKER_H_ -#include "ast.h" -#include "map.h" +#include "ast/ast.h" +#include "util/map.h" class proof_checker { ast_manager& m; diff --git a/src/ast/recurse_expr.h b/src/ast/recurse_expr.h index 46375d955..866e39d3f 100644 --- a/src/ast/recurse_expr.h +++ b/src/ast/recurse_expr.h @@ -19,8 +19,8 @@ Revision History: #ifndef RECURSE_EXPR_H_ #define RECURSE_EXPR_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" template class recurse_expr : public Visitor { diff --git a/src/ast/recurse_expr_def.h b/src/ast/recurse_expr_def.h index 5149baa93..d4f608c5a 100644 --- a/src/ast/recurse_expr_def.h +++ b/src/ast/recurse_expr_def.h @@ -19,7 +19,7 @@ Revision History: #ifndef RECURSE_EXPR_DEF_H_ #define RECURSE_EXPR_DEF_H_ -#include"recurse_expr.h" +#include "ast/recurse_expr.h" template inline void recurse_expr::visit(expr * n, bool & visited) { diff --git a/src/ast/reg_decl_plugins.cpp b/src/ast/reg_decl_plugins.cpp index b4ff63ede..985ecee9e 100644 --- a/src/ast/reg_decl_plugins.cpp +++ b/src/ast/reg_decl_plugins.cpp @@ -17,15 +17,15 @@ Author: Revision History: --*/ -#include"ast.h" -#include"arith_decl_plugin.h" -#include"array_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"dl_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"pb_decl_plugin.h" -#include"fpa_decl_plugin.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/dl_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/pb_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" void reg_decl_plugins(ast_manager & m) { if (!m.get_plugin(m.mk_family_id(symbol("arith")))) { diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 258c28369..4b91ad789 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"arith_rewriter.h" +#include "ast/rewriter/arith_rewriter.h" #include"arith_rewriter_params.hpp" -#include"poly_rewriter_def.h" -#include"algebraic_numbers.h" -#include"ast_pp.h" +#include "ast/rewriter/poly_rewriter_def.h" +#include "math/polynomial/algebraic_numbers.h" +#include "ast/ast_pp.h" void arith_rewriter::updt_local_params(params_ref const & _p) { arith_rewriter_params p(_p); diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index 68a60e1f0..de849dbd7 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -19,8 +19,8 @@ Notes: #ifndef ARITH_REWRITER_H_ #define ARITH_REWRITER_H_ -#include"poly_rewriter.h" -#include"arith_decl_plugin.h" +#include "ast/rewriter/poly_rewriter.h" +#include "ast/arith_decl_plugin.h" class arith_rewriter_core { protected: diff --git a/src/ast/rewriter/array_rewriter.cpp b/src/ast/rewriter/array_rewriter.cpp index 6f6b5b62e..85f639bc9 100644 --- a/src/ast/rewriter/array_rewriter.cpp +++ b/src/ast/rewriter/array_rewriter.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"array_rewriter.h" +#include "ast/rewriter/array_rewriter.h" #include"array_rewriter_params.hpp" -#include"ast_lt.h" -#include"ast_pp.h" +#include "ast/ast_lt.h" +#include "ast/ast_pp.h" void array_rewriter::updt_params(params_ref const & _p) { array_rewriter_params p(_p); diff --git a/src/ast/rewriter/array_rewriter.h b/src/ast/rewriter/array_rewriter.h index 4ff48d496..90b3b6f34 100644 --- a/src/ast/rewriter/array_rewriter.h +++ b/src/ast/rewriter/array_rewriter.h @@ -19,10 +19,10 @@ Notes: #ifndef ARRAY_REWRITER_H_ #define ARRAY_REWRITER_H_ -#include"array_decl_plugin.h" -#include"rewriter_types.h" -#include"lbool.h" -#include"params.h" +#include "ast/array_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" +#include "util/lbool.h" +#include "util/params.h" /** \brief Cheap rewrite rules for Arrays diff --git a/src/ast/rewriter/ast_counter.cpp b/src/ast/rewriter/ast_counter.cpp index f2c8cabf7..bc11e4fb0 100644 --- a/src/ast/rewriter/ast_counter.cpp +++ b/src/ast/rewriter/ast_counter.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include "ast_counter.h" +#include "ast/rewriter/ast_counter.h" void counter::update(unsigned el, int delta) { int & counter = get(el); diff --git a/src/ast/rewriter/ast_counter.h b/src/ast/rewriter/ast_counter.h index 4509d2549..a2d1c239b 100644 --- a/src/ast/rewriter/ast_counter.h +++ b/src/ast/rewriter/ast_counter.h @@ -24,10 +24,10 @@ Revision History: #ifndef AST_COUNTER_H_ #define AST_COUNTER_H_ -#include "ast.h" -#include "map.h" -#include "uint_set.h" -#include "var_subst.h" +#include "ast/ast.h" +#include "util/map.h" +#include "util/uint_set.h" +#include "ast/rewriter/var_subst.h" class counter { protected: diff --git a/src/ast/rewriter/bit_blaster/bit_blaster.cpp b/src/ast/rewriter/bit_blaster/bit_blaster.cpp index 1055ceb58..6632fe811 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster.cpp +++ b/src/ast/rewriter/bit_blaster/bit_blaster.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"bit_blaster.h" -#include"bit_blaster_tpl_def.h" -#include"ast_pp.h" -#include"bv_decl_plugin.h" +#include "ast/rewriter/bit_blaster/bit_blaster.h" +#include "ast/rewriter/bit_blaster/bit_blaster_tpl_def.h" +#include "ast/ast_pp.h" +#include "ast/bv_decl_plugin.h" bit_blaster_cfg::bit_blaster_cfg(bv_util & u, bit_blaster_params const & p, bool_rewriter& rw): m_util(u), diff --git a/src/ast/rewriter/bit_blaster/bit_blaster.h b/src/ast/rewriter/bit_blaster/bit_blaster.h index 6221eeaf9..ffaa69e12 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster.h +++ b/src/ast/rewriter/bit_blaster/bit_blaster.h @@ -19,11 +19,11 @@ Revision History: #ifndef BIT_BLASTER_H_ #define BIT_BLASTER_H_ -#include"bool_rewriter.h" -#include"bit_blaster_params.h" -#include"bit_blaster_tpl.h" -#include"bv_decl_plugin.h" -#include"rational.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/bit_blaster/bit_blaster_params.h" +#include "ast/rewriter/bit_blaster/bit_blaster_tpl.h" +#include "ast/bv_decl_plugin.h" +#include "util/rational.h" class bit_blaster_cfg { public: diff --git a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp index 68f2a2b8e..c47dacc96 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp +++ b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp @@ -16,13 +16,13 @@ Author: Notes: --*/ -#include"bit_blaster_rewriter.h" -#include"bv_decl_plugin.h" -#include"bit_blaster_tpl_def.h" -#include"rewriter_def.h" -#include"bool_rewriter.h" -#include"ref_util.h" -#include"ast_smt2_pp.h" +#include "ast/rewriter/bit_blaster/bit_blaster_rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/bit_blaster/bit_blaster_tpl_def.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/bool_rewriter.h" +#include "util/ref_util.h" +#include "ast/ast_smt2_pp.h" struct blaster_cfg { typedef rational numeral; diff --git a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.h b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.h index 8db328ec8..6ffed00ae 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.h +++ b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.h @@ -19,9 +19,9 @@ Notes: #ifndef BIT_BLASTER_REWRITER_H_ #define BIT_BLASTER_REWRITER_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"params.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "util/params.h" class bit_blaster_rewriter { struct imp; diff --git a/src/ast/rewriter/bit_blaster/bit_blaster_tpl.h b/src/ast/rewriter/bit_blaster/bit_blaster_tpl.h index b812de941..8407b0791 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster_tpl.h +++ b/src/ast/rewriter/bit_blaster/bit_blaster_tpl.h @@ -19,7 +19,7 @@ Revision History: #ifndef BIT_BLASTER_TPL_H_ #define BIT_BLASTER_TPL_H_ -#include"rational.h" +#include "util/rational.h" template class bit_blaster_tpl : public Cfg { diff --git a/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h b/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h index 15b87697f..cd66a5124 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h +++ b/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h @@ -16,12 +16,12 @@ Author: Revision History: --*/ -#include"bit_blaster_tpl.h" -#include"rational.h" -#include"ast_pp.h" -#include"cooperate.h" -#include"common_msgs.h" -#include"rewriter_types.h" +#include "ast/rewriter/bit_blaster/bit_blaster_tpl.h" +#include "util/rational.h" +#include "ast/ast_pp.h" +#include "util/cooperate.h" +#include "util/common_msgs.h" +#include "ast/rewriter/rewriter_types.h" template diff --git a/src/ast/rewriter/bool_rewriter.cpp b/src/ast/rewriter/bool_rewriter.cpp index f6597fbc5..511e7607d 100644 --- a/src/ast/rewriter/bool_rewriter.cpp +++ b/src/ast/rewriter/bool_rewriter.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"bool_rewriter.h" +#include "ast/rewriter/bool_rewriter.h" #include"bool_rewriter_params.hpp" -#include"rewriter_def.h" +#include "ast/rewriter/rewriter_def.h" void bool_rewriter::updt_params(params_ref const & _p) { bool_rewriter_params p(_p); diff --git a/src/ast/rewriter/bool_rewriter.h b/src/ast/rewriter/bool_rewriter.h index b1d2dec53..be9799c13 100644 --- a/src/ast/rewriter/bool_rewriter.h +++ b/src/ast/rewriter/bool_rewriter.h @@ -19,9 +19,9 @@ Notes: #ifndef BOOL_REWRITER_H_ #define BOOL_REWRITER_H_ -#include"ast.h" -#include"rewriter.h" -#include"params.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter.h" +#include "util/params.h" /** \brief Apply basic Boolean rewriting operations. diff --git a/src/ast/rewriter/bv_bounds.cpp b/src/ast/rewriter/bv_bounds.cpp index 76cdfbdbe..fd263efb2 100644 --- a/src/ast/rewriter/bv_bounds.cpp +++ b/src/ast/rewriter/bv_bounds.cpp @@ -14,8 +14,8 @@ Revision History: --*/ -#include"bv_bounds.h" -#include"ast_smt2_pp.h" +#include "ast/rewriter/bv_bounds.h" +#include "ast/ast_smt2_pp.h" bv_bounds::~bv_bounds() { reset(); diff --git a/src/ast/rewriter/bv_bounds.h b/src/ast/rewriter/bv_bounds.h index eeefc2c11..3d8ec9ebb 100644 --- a/src/ast/rewriter/bv_bounds.h +++ b/src/ast/rewriter/bv_bounds.h @@ -19,9 +19,9 @@ --*/ #ifndef BV_BOUNDS_H_23754 #define BV_BOUNDS_H_23754 -#include"ast.h" -#include"bv_decl_plugin.h" -#include"rewriter_types.h" +#include "ast/ast.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" /* \brief A class to analyze constraints on bit vectors. diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index 0246f2b16..d176c8008 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"bv_rewriter.h" +#include "ast/rewriter/bv_rewriter.h" #include"bv_rewriter_params.hpp" -#include"poly_rewriter_def.h" -#include"ast_smt2_pp.h" +#include "ast/rewriter/poly_rewriter_def.h" +#include "ast/ast_smt2_pp.h" void bv_rewriter::updt_local_params(params_ref const & _p) { @@ -2314,7 +2314,7 @@ void bv_rewriter::mk_t1_add_t2_eq_c(expr * t1, expr * t2, expr * c, expr_ref & r result = m().mk_eq(t1, m_util.mk_bv_sub(c, t2)); } -#include "ast_pp.h" +#include "ast/ast_pp.h" bool bv_rewriter::isolate_term(expr* lhs, expr* rhs, expr_ref& result) { if (!m_util.is_numeral(lhs) || !is_add(rhs)) { diff --git a/src/ast/rewriter/bv_rewriter.h b/src/ast/rewriter/bv_rewriter.h index b5482e5fa..1109251e0 100644 --- a/src/ast/rewriter/bv_rewriter.h +++ b/src/ast/rewriter/bv_rewriter.h @@ -19,11 +19,11 @@ Notes: #ifndef BV_REWRITER_H_ #define BV_REWRITER_H_ -#include"poly_rewriter.h" -#include"bv_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"mk_extract_proc.h" -#include"bv_trailing.h" +#include "ast/rewriter/poly_rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/mk_extract_proc.h" +#include "ast/rewriter/bv_trailing.h" class bv_rewriter_core { protected: diff --git a/src/ast/rewriter/bv_trailing.cpp b/src/ast/rewriter/bv_trailing.cpp index f0b96a91f..5cdf27574 100644 --- a/src/ast/rewriter/bv_trailing.cpp +++ b/src/ast/rewriter/bv_trailing.cpp @@ -14,9 +14,9 @@ Revision History: --*/ -#include"bv_trailing.h" -#include"bv_decl_plugin.h" -#include"ast_smt2_pp.h" +#include "ast/rewriter/bv_trailing.h" +#include "ast/bv_decl_plugin.h" +#include "ast/ast_smt2_pp.h" // The analyzer gives up analysis after going TRAILING_DEPTH deep. // This number shouldn't be too big. diff --git a/src/ast/rewriter/bv_trailing.h b/src/ast/rewriter/bv_trailing.h index 862a1bea6..3ad46cb5d 100644 --- a/src/ast/rewriter/bv_trailing.h +++ b/src/ast/rewriter/bv_trailing.h @@ -18,9 +18,9 @@ --*/ #ifndef BV_TRAILING_H_ #define BV_TRAILING_H_ -#include"ast.h" -#include"rewriter_types.h" -#include"mk_extract_proc.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter_types.h" +#include "ast/rewriter/mk_extract_proc.h" class bv_trailing { public: bv_trailing(mk_extract_proc& ep); diff --git a/src/ast/rewriter/datatype_rewriter.cpp b/src/ast/rewriter/datatype_rewriter.cpp index be198c3d9..d38c9e476 100644 --- a/src/ast/rewriter/datatype_rewriter.cpp +++ b/src/ast/rewriter/datatype_rewriter.cpp @@ -16,7 +16,7 @@ Author: Notes: --*/ -#include"datatype_rewriter.h" +#include "ast/rewriter/datatype_rewriter.h" br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(f->get_family_id() == get_fid()); diff --git a/src/ast/rewriter/datatype_rewriter.h b/src/ast/rewriter/datatype_rewriter.h index 43fbc46d9..8aae29b3a 100644 --- a/src/ast/rewriter/datatype_rewriter.h +++ b/src/ast/rewriter/datatype_rewriter.h @@ -19,8 +19,8 @@ Notes: #ifndef DATATYPE_REWRITER_H_ #define DATATYPE_REWRITER_H_ -#include"datatype_decl_plugin.h" -#include"rewriter_types.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" class datatype_rewriter { datatype_util m_util; diff --git a/src/ast/rewriter/der.cpp b/src/ast/rewriter/der.cpp index aef5d8ddd..56f895b8a 100644 --- a/src/ast/rewriter/der.cpp +++ b/src/ast/rewriter/der.cpp @@ -18,13 +18,13 @@ Revision History: Christoph Wintersteiger, 2010-03-30: Added Destr. Multi-Equality Resolution --*/ -#include"der.h" -#include"occurs.h" -#include"for_each_expr.h" -#include"rewriter_def.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" +#include "ast/rewriter/der.h" +#include "ast/occurs.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" static bool is_var(expr * e, unsigned num_decls) { return is_var(e) && to_var(e)->get_idx() < num_decls; diff --git a/src/ast/rewriter/der.h b/src/ast/rewriter/der.h index 9de028be8..47e57c4fb 100644 --- a/src/ast/rewriter/der.h +++ b/src/ast/rewriter/der.h @@ -21,8 +21,8 @@ Revision History: #ifndef DER_H_ #define DER_H_ -#include"ast.h" -#include"var_subst.h" +#include "ast/ast.h" +#include "ast/rewriter/var_subst.h" /* New DER: the class DER (above) eliminates variables one by one. diff --git a/src/ast/rewriter/distribute_forall.cpp b/src/ast/rewriter/distribute_forall.cpp index c64c0f089..77db3bc28 100644 --- a/src/ast/rewriter/distribute_forall.cpp +++ b/src/ast/rewriter/distribute_forall.cpp @@ -18,11 +18,11 @@ Revision History: Christoph Wintersteiger 2010-04-06: Added implementation. --*/ -#include"var_subst.h" -#include"ast_ll_pp.h" -#include"ast_util.h" -#include"distribute_forall.h" -#include"bool_rewriter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_util.h" +#include "ast/rewriter/distribute_forall.h" +#include "ast/rewriter/bool_rewriter.h" distribute_forall::distribute_forall(ast_manager & m) : m_manager(m), diff --git a/src/ast/rewriter/distribute_forall.h b/src/ast/rewriter/distribute_forall.h index b2c239239..ab0976945 100644 --- a/src/ast/rewriter/distribute_forall.h +++ b/src/ast/rewriter/distribute_forall.h @@ -21,8 +21,8 @@ Revision History: #ifndef DISTRIBUTE_FORALL_H_ #define DISTRIBUTE_FORALL_H_ -#include"ast.h" -#include"act_cache.h" +#include "ast/ast.h" +#include "ast/act_cache.h" /** \brief Apply the following transformation diff --git a/src/ast/rewriter/dl_rewriter.cpp b/src/ast/rewriter/dl_rewriter.cpp index ddae6c9eb..74ea7814e 100644 --- a/src/ast/rewriter/dl_rewriter.cpp +++ b/src/ast/rewriter/dl_rewriter.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"dl_rewriter.h" +#include "ast/rewriter/dl_rewriter.h" br_status dl_rewriter::mk_app_core( func_decl * f, unsigned num_args, expr* const* args, expr_ref& result) { diff --git a/src/ast/rewriter/dl_rewriter.h b/src/ast/rewriter/dl_rewriter.h index ecb3f0944..dca2f26dd 100644 --- a/src/ast/rewriter/dl_rewriter.h +++ b/src/ast/rewriter/dl_rewriter.h @@ -19,8 +19,8 @@ Notes: #ifndef DL_REWRITER_H_ #define DL_REWRITER_H_ -#include"dl_decl_plugin.h" -#include"rewriter_types.h" +#include "ast/dl_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" class dl_rewriter { datalog::dl_decl_util m_util; diff --git a/src/ast/rewriter/enum2bv_rewriter.cpp b/src/ast/rewriter/enum2bv_rewriter.cpp index 08e7b0f69..eb6b195f0 100644 --- a/src/ast/rewriter/enum2bv_rewriter.cpp +++ b/src/ast/rewriter/enum2bv_rewriter.cpp @@ -17,11 +17,11 @@ Notes: --*/ -#include"rewriter.h" -#include"rewriter_def.h" -#include"enum2bv_rewriter.h" -#include"ast_util.h" -#include"ast_pp.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/enum2bv_rewriter.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" struct enum2bv_rewriter::imp { ast_manager& m; diff --git a/src/ast/rewriter/enum2bv_rewriter.h b/src/ast/rewriter/enum2bv_rewriter.h index 1b2c6160f..934271071 100644 --- a/src/ast/rewriter/enum2bv_rewriter.h +++ b/src/ast/rewriter/enum2bv_rewriter.h @@ -19,9 +19,9 @@ Notes: #ifndef ENUM_REWRITER_H_ #define ENUM_REWRITER_H_ -#include"datatype_decl_plugin.h" -#include"rewriter_types.h" -#include"expr_functors.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" +#include "ast/expr_functors.h" class enum2bv_rewriter { struct imp; diff --git a/src/ast/rewriter/expr_replacer.cpp b/src/ast/rewriter/expr_replacer.cpp index 3552c7d49..70e12dced 100644 --- a/src/ast/rewriter/expr_replacer.cpp +++ b/src/ast/rewriter/expr_replacer.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"expr_replacer.h" -#include"rewriter_def.h" -#include"th_rewriter.h" -#include"cooperate.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/th_rewriter.h" +#include "util/cooperate.h" void expr_replacer::operator()(expr * t, expr_ref & result, proof_ref & result_pr) { expr_dependency_ref result_dep(m()); diff --git a/src/ast/rewriter/expr_replacer.h b/src/ast/rewriter/expr_replacer.h index 2e445eadc..811cd1f23 100644 --- a/src/ast/rewriter/expr_replacer.h +++ b/src/ast/rewriter/expr_replacer.h @@ -19,9 +19,9 @@ Notes: #ifndef EXPR_REPLACER_H_ #define EXPR_REPLACER_H_ -#include"ast.h" -#include"expr_substitution.h" -#include"params.h" +#include "ast/ast.h" +#include "ast/expr_substitution.h" +#include "util/params.h" /** \brief Abstract interface for functors that replace constants with expressions. diff --git a/src/ast/rewriter/expr_safe_replace.cpp b/src/ast/rewriter/expr_safe_replace.cpp index 2655ac00d..31453691e 100644 --- a/src/ast/rewriter/expr_safe_replace.cpp +++ b/src/ast/rewriter/expr_safe_replace.cpp @@ -18,9 +18,9 @@ Revision History: --*/ -#include "expr_safe_replace.h" -#include "rewriter.h" -#include "ast_pp.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/rewriter/rewriter.h" +#include "ast/ast_pp.h" void expr_safe_replace::insert(expr* src, expr* dst) { diff --git a/src/ast/rewriter/expr_safe_replace.h b/src/ast/rewriter/expr_safe_replace.h index 84a74ccaa..fb66661af 100644 --- a/src/ast/rewriter/expr_safe_replace.h +++ b/src/ast/rewriter/expr_safe_replace.h @@ -22,7 +22,7 @@ Revision History: #ifndef EXPR_SAFE_REPLACE_H_ #define EXPR_SAFE_REPLACE_H_ -#include "ast.h" +#include "ast/ast.h" class expr_safe_replace { ast_manager& m; diff --git a/src/ast/rewriter/factor_rewriter.cpp b/src/ast/rewriter/factor_rewriter.cpp index 9e988caf7..abcdabc9c 100644 --- a/src/ast/rewriter/factor_rewriter.cpp +++ b/src/ast/rewriter/factor_rewriter.cpp @@ -18,9 +18,9 @@ Notes: --*/ -#include"factor_rewriter.h" -#include"ast_pp.h" -#include"rewriter_def.h" +#include "ast/rewriter/factor_rewriter.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/rewriter_def.h" factor_rewriter::factor_rewriter(ast_manager & m): m_manager(m), m_arith(m), m_factors(m) { } diff --git a/src/ast/rewriter/factor_rewriter.h b/src/ast/rewriter/factor_rewriter.h index 389eacd87..aae9b05b3 100644 --- a/src/ast/rewriter/factor_rewriter.h +++ b/src/ast/rewriter/factor_rewriter.h @@ -20,9 +20,9 @@ Notes: #ifndef FACTOR_REWRITER_H_ #define FACTOR_REWRITER_H_ -#include"ast.h" -#include"rewriter.h" -#include"arith_decl_plugin.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter.h" +#include "ast/arith_decl_plugin.h" class factor_rewriter { typedef obj_map powers_t; diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 26487c5a4..f82d6df3e 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"fpa_rewriter.h" +#include "ast/rewriter/fpa_rewriter.h" #include"fpa_rewriter_params.hpp" -#include"ast_smt2_pp.h" +#include "ast/ast_smt2_pp.h" fpa_rewriter::fpa_rewriter(ast_manager & m, params_ref const & p) : m_util(m), diff --git a/src/ast/rewriter/fpa_rewriter.h b/src/ast/rewriter/fpa_rewriter.h index 0d9c6a380..45710122c 100644 --- a/src/ast/rewriter/fpa_rewriter.h +++ b/src/ast/rewriter/fpa_rewriter.h @@ -19,11 +19,11 @@ Notes: #ifndef FLOAT_REWRITER_H_ #define FLOAT_REWRITER_H_ -#include"ast.h" -#include"rewriter.h" -#include"params.h" -#include"fpa_decl_plugin.h" -#include"mpf.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter.h" +#include "util/params.h" +#include "ast/fpa_decl_plugin.h" +#include "util/mpf.h" class fpa_rewriter { fpa_util m_util; diff --git a/src/ast/rewriter/label_rewriter.cpp b/src/ast/rewriter/label_rewriter.cpp index 3017f413c..8adefb896 100644 --- a/src/ast/rewriter/label_rewriter.cpp +++ b/src/ast/rewriter/label_rewriter.cpp @@ -17,9 +17,9 @@ Notes: --*/ -#include"rewriter.h" -#include"rewriter_def.h" -#include"label_rewriter.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/label_rewriter.h" label_rewriter::label_rewriter(ast_manager & m) : diff --git a/src/ast/rewriter/label_rewriter.h b/src/ast/rewriter/label_rewriter.h index 6400aa442..f2f578fbb 100644 --- a/src/ast/rewriter/label_rewriter.h +++ b/src/ast/rewriter/label_rewriter.h @@ -19,8 +19,8 @@ Notes: #ifndef LABEL_REWRITER_H_ #define LABEL_REWRITER_H_ -#include"ast.h" -#include"rewriter_types.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter_types.h" class label_rewriter : public default_rewriter_cfg { diff --git a/src/ast/rewriter/mk_extract_proc.cpp b/src/ast/rewriter/mk_extract_proc.cpp index 5f470acd3..da22c3b80 100644 --- a/src/ast/rewriter/mk_extract_proc.cpp +++ b/src/ast/rewriter/mk_extract_proc.cpp @@ -14,7 +14,7 @@ Revision History: --*/ -#include"mk_extract_proc.h" +#include "ast/rewriter/mk_extract_proc.h" mk_extract_proc::mk_extract_proc(bv_util & u): m_util(u), m_high(0), diff --git a/src/ast/rewriter/mk_extract_proc.h b/src/ast/rewriter/mk_extract_proc.h index 2b242d0f5..4e7b1d1b7 100644 --- a/src/ast/rewriter/mk_extract_proc.h +++ b/src/ast/rewriter/mk_extract_proc.h @@ -16,8 +16,8 @@ --*/ #ifndef MK_EXTRACT_PROC_H_ #define MK_EXTRACT_PROC_H_ -#include"ast.h" -#include"bv_decl_plugin.h" +#include "ast/ast.h" +#include "ast/bv_decl_plugin.h" class mk_extract_proc { bv_util & m_util; unsigned m_high; diff --git a/src/ast/rewriter/mk_simplified_app.cpp b/src/ast/rewriter/mk_simplified_app.cpp index 45245ce1b..eac26ddc3 100644 --- a/src/ast/rewriter/mk_simplified_app.cpp +++ b/src/ast/rewriter/mk_simplified_app.cpp @@ -16,13 +16,13 @@ Author: Notes: --*/ -#include"mk_simplified_app.h" -#include"bool_rewriter.h" -#include"arith_rewriter.h" -#include"bv_rewriter.h" -#include"datatype_rewriter.h" -#include"array_rewriter.h" -#include"fpa_rewriter.h" +#include "ast/rewriter/mk_simplified_app.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/rewriter/bv_rewriter.h" +#include "ast/rewriter/datatype_rewriter.h" +#include "ast/rewriter/array_rewriter.h" +#include "ast/rewriter/fpa_rewriter.h" struct mk_simplified_app::imp { ast_manager & m; diff --git a/src/ast/rewriter/mk_simplified_app.h b/src/ast/rewriter/mk_simplified_app.h index 40e6f993d..d979637d2 100644 --- a/src/ast/rewriter/mk_simplified_app.h +++ b/src/ast/rewriter/mk_simplified_app.h @@ -19,9 +19,9 @@ Notes: #ifndef MK_SIMPLIFIED_APP_H_ #define MK_SIMPLIFIED_APP_H_ -#include"ast.h" -#include"params.h" -#include"rewriter_types.h" +#include "ast/ast.h" +#include "util/params.h" +#include "ast/rewriter/rewriter_types.h" class mk_simplified_app { struct imp; diff --git a/src/ast/rewriter/pb2bv_rewriter.cpp b/src/ast/rewriter/pb2bv_rewriter.cpp index 37c87cd5b..39d6e2143 100644 --- a/src/ast/rewriter/pb2bv_rewriter.cpp +++ b/src/ast/rewriter/pb2bv_rewriter.cpp @@ -17,14 +17,14 @@ Notes: --*/ -#include"rewriter.h" -#include"rewriter_def.h" -#include"statistics.h" -#include"pb2bv_rewriter.h" -#include"sorting_network.h" -#include"ast_util.h" -#include"ast_pp.h" -#include"lbool.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/statistics.h" +#include "ast/rewriter/pb2bv_rewriter.h" +#include "util/sorting_network.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" +#include "util/lbool.h" struct pb2bv_rewriter::imp { diff --git a/src/ast/rewriter/pb2bv_rewriter.h b/src/ast/rewriter/pb2bv_rewriter.h index 47d8361cb..a4176922a 100644 --- a/src/ast/rewriter/pb2bv_rewriter.h +++ b/src/ast/rewriter/pb2bv_rewriter.h @@ -19,9 +19,9 @@ Notes: #ifndef PB2BV_REWRITER_H_ #define PB2BV_REWRITER_H_ -#include"pb_decl_plugin.h" -#include"rewriter_types.h" -#include"expr_functors.h" +#include "ast/pb_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" +#include "ast/expr_functors.h" class pb2bv_rewriter { struct imp; diff --git a/src/ast/rewriter/pb_rewriter.cpp b/src/ast/rewriter/pb_rewriter.cpp index b14d350b1..5660f9d65 100644 --- a/src/ast/rewriter/pb_rewriter.cpp +++ b/src/ast/rewriter/pb_rewriter.cpp @@ -17,11 +17,11 @@ Notes: --*/ -#include "pb_rewriter.h" -#include "pb_rewriter_def.h" -#include "ast_pp.h" -#include "ast_util.h" -#include "ast_smt_pp.h" +#include "ast/rewriter/pb_rewriter.h" +#include "ast/rewriter/pb_rewriter_def.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "ast/ast_smt_pp.h" class pb_ast_rewriter_util { diff --git a/src/ast/rewriter/pb_rewriter.h b/src/ast/rewriter/pb_rewriter.h index ba98d774e..f52aea12b 100644 --- a/src/ast/rewriter/pb_rewriter.h +++ b/src/ast/rewriter/pb_rewriter.h @@ -19,10 +19,10 @@ Notes: #ifndef PB_REWRITER_H_ #define PB_REWRITER_H_ -#include"pb_decl_plugin.h" -#include"rewriter_types.h" -#include"params.h" -#include"lbool.h" +#include "ast/pb_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" +#include "util/params.h" +#include "util/lbool.h" template diff --git a/src/ast/rewriter/pb_rewriter_def.h b/src/ast/rewriter/pb_rewriter_def.h index a713a05a7..aa2c2a61f 100644 --- a/src/ast/rewriter/pb_rewriter_def.h +++ b/src/ast/rewriter/pb_rewriter_def.h @@ -19,7 +19,7 @@ Notes: #ifndef PB_REWRITER_DEF_H_ #define PB_REWRITER_DEF_H_ -#include"pb_rewriter.h" +#include "ast/rewriter/pb_rewriter.h" template diff --git a/src/ast/rewriter/poly_rewriter.h b/src/ast/rewriter/poly_rewriter.h index ea0b9e85a..5d38e4b10 100644 --- a/src/ast/rewriter/poly_rewriter.h +++ b/src/ast/rewriter/poly_rewriter.h @@ -19,10 +19,10 @@ Notes: #ifndef POLY_REWRITER_H_ #define POLY_REWRITER_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"rewriter_types.h" -#include"params.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "ast/rewriter/rewriter_types.h" +#include "util/params.h" template class poly_rewriter : public Config { diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 962c9660e..81d3aec9f 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"poly_rewriter.h" +#include "ast/rewriter/poly_rewriter.h" #include"poly_rewriter_params.hpp" -#include"ast_lt.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" +#include "ast/ast_lt.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" template diff --git a/src/ast/rewriter/quant_hoist.cpp b/src/ast/rewriter/quant_hoist.cpp index e59a079e7..2059139e4 100644 --- a/src/ast/rewriter/quant_hoist.cpp +++ b/src/ast/rewriter/quant_hoist.cpp @@ -19,14 +19,14 @@ Revision History: --*/ -#include "quant_hoist.h" -#include "expr_functors.h" -#include "ast_smt_pp.h" -#include "bool_rewriter.h" -#include "var_subst.h" -#include "ast_pp.h" -#include "ast_counter.h" -#include "expr_safe_replace.h" +#include "ast/rewriter/quant_hoist.h" +#include "ast/expr_functors.h" +#include "ast/ast_smt_pp.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/ast_counter.h" +#include "ast/rewriter/expr_safe_replace.h" // // Bring quantifiers of common type into prenex form. diff --git a/src/ast/rewriter/quant_hoist.h b/src/ast/rewriter/quant_hoist.h index 90e6ec7ad..c94e0fde3 100644 --- a/src/ast/rewriter/quant_hoist.h +++ b/src/ast/rewriter/quant_hoist.h @@ -22,7 +22,7 @@ Revision History: #ifndef QUANTIFIER_HOISTER_H_ #define QUANTIFIER_HOISTER_H_ -#include "ast.h" +#include "ast/ast.h" class quantifier_hoister { class impl; diff --git a/src/ast/rewriter/rewriter.cpp b/src/ast/rewriter/rewriter.cpp index c7b110dff..36ad2dec4 100644 --- a/src/ast/rewriter/rewriter.cpp +++ b/src/ast/rewriter/rewriter.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"rewriter_def.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" void rewriter_core::init_cache_stack() { SASSERT(m_cache_stack.empty()); diff --git a/src/ast/rewriter/rewriter.h b/src/ast/rewriter/rewriter.h index 2b4f4b14e..17742f670 100644 --- a/src/ast/rewriter/rewriter.h +++ b/src/ast/rewriter/rewriter.h @@ -19,9 +19,9 @@ Notes: #ifndef REWRITER_H_ #define REWRITER_H_ -#include"ast.h" -#include"rewriter_types.h" -#include"act_cache.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter_types.h" +#include "ast/act_cache.h" /** \brief Common infrastructure for AST rewriters. diff --git a/src/ast/rewriter/rewriter_def.h b/src/ast/rewriter/rewriter_def.h index 76f149df7..163118d17 100644 --- a/src/ast/rewriter/rewriter_def.h +++ b/src/ast/rewriter/rewriter_def.h @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"rewriter.h" -#include"ast_smt2_pp.h" +#include "ast/rewriter/rewriter.h" +#include "ast/ast_smt2_pp.h" template template diff --git a/src/ast/rewriter/rewriter_types.h b/src/ast/rewriter/rewriter_types.h index f5947eb92..094357fed 100644 --- a/src/ast/rewriter/rewriter_types.h +++ b/src/ast/rewriter/rewriter_types.h @@ -19,8 +19,8 @@ Notes: #ifndef REWRITER_TYPES_H_ #define REWRITER_TYPES_H_ -#include"z3_exception.h" -#include"common_msgs.h" +#include "util/z3_exception.h" +#include "util/common_msgs.h" /** \brief Builtin rewrite result status diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index ce707b108..90792ad64 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -18,15 +18,15 @@ Notes: --*/ -#include"seq_rewriter.h" -#include"arith_decl_plugin.h" -#include"ast_pp.h" -#include"ast_util.h" -#include"uint_set.h" -#include"automaton.h" -#include"well_sorted.h" -#include"var_subst.h" -#include"symbolic_automata_def.h" +#include "ast/rewriter/seq_rewriter.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "util/uint_set.h" +#include "math/automata/automaton.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/var_subst.h" +#include "math/automata/symbolic_automata_def.h" expr_ref sym_expr::accept(expr* e) { diff --git a/src/ast/rewriter/seq_rewriter.h b/src/ast/rewriter/seq_rewriter.h index 210b2d72c..add941ddb 100644 --- a/src/ast/rewriter/seq_rewriter.h +++ b/src/ast/rewriter/seq_rewriter.h @@ -19,13 +19,13 @@ Notes: #ifndef SEQ_REWRITER_H_ #define SEQ_REWRITER_H_ -#include"seq_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"rewriter_types.h" -#include"params.h" -#include"lbool.h" -#include"automaton.h" -#include"symbolic_automata.h" +#include "ast/seq_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/rewriter_types.h" +#include "util/params.h" +#include "util/lbool.h" +#include "math/automata/automaton.h" +#include "math/automata/symbolic_automata.h" class sym_expr { enum ty { diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index b561e02fc..240b43b30 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -16,24 +16,24 @@ Author: Notes: --*/ -#include"th_rewriter.h" +#include "ast/rewriter/th_rewriter.h" #include"rewriter_params.hpp" -#include"bool_rewriter.h" -#include"arith_rewriter.h" -#include"bv_rewriter.h" -#include"datatype_rewriter.h" -#include"array_rewriter.h" -#include"fpa_rewriter.h" -#include"dl_rewriter.h" -#include"pb_rewriter.h" -#include"seq_rewriter.h" -#include"rewriter_def.h" -#include"expr_substitution.h" -#include"ast_smt2_pp.h" -#include"cooperate.h" -#include"var_subst.h" -#include"ast_util.h" -#include"well_sorted.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/rewriter/bv_rewriter.h" +#include "ast/rewriter/datatype_rewriter.h" +#include "ast/rewriter/array_rewriter.h" +#include "ast/rewriter/fpa_rewriter.h" +#include "ast/rewriter/dl_rewriter.h" +#include "ast/rewriter/pb_rewriter.h" +#include "ast/rewriter/seq_rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/expr_substitution.h" +#include "ast/ast_smt2_pp.h" +#include "util/cooperate.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_util.h" +#include "ast/well_sorted.h" struct th_rewriter_cfg : public default_rewriter_cfg { bool_rewriter m_b_rw; diff --git a/src/ast/rewriter/th_rewriter.h b/src/ast/rewriter/th_rewriter.h index 6aa4bb3da..db495e8da 100644 --- a/src/ast/rewriter/th_rewriter.h +++ b/src/ast/rewriter/th_rewriter.h @@ -19,9 +19,9 @@ Notes: #ifndef TH_REWRITER_H_ #define TH_REWRITER_H_ -#include"ast.h" -#include"rewriter_types.h" -#include"params.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter_types.h" +#include "util/params.h" class expr_substitution; diff --git a/src/ast/rewriter/var_subst.cpp b/src/ast/rewriter/var_subst.cpp index fd290c8fe..756e62a5f 100644 --- a/src/ast/rewriter/var_subst.cpp +++ b/src/ast/rewriter/var_subst.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"var_subst.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"ast_smt2_pp.h" -#include"well_sorted.h" -#include"for_each_expr.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/well_sorted.h" +#include "ast/for_each_expr.h" void var_subst::operator()(expr * n, unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(is_well_sorted(result.m(), n)); diff --git a/src/ast/rewriter/var_subst.h b/src/ast/rewriter/var_subst.h index 21aa58399..b6a25cfdb 100644 --- a/src/ast/rewriter/var_subst.h +++ b/src/ast/rewriter/var_subst.h @@ -19,9 +19,9 @@ Notes: #ifndef VAR_SUBST_H_ #define VAR_SUBST_H_ -#include"rewriter.h" -#include"used_vars.h" -#include"params.h" +#include "ast/rewriter/rewriter.h" +#include "ast/used_vars.h" +#include "util/params.h" /** \brief Alias for var_shifter class. diff --git a/src/ast/scoped_proof.h b/src/ast/scoped_proof.h index 2bbba5122..0a650ceb7 100644 --- a/src/ast/scoped_proof.h +++ b/src/ast/scoped_proof.h @@ -19,7 +19,7 @@ Revision History: #ifndef SCOPED_PROOF_H_ #define SCOPED_PROOF_H_ -#include "ast.h" +#include "ast/ast.h" class scoped_proof_mode { ast_manager& m; diff --git a/src/ast/seq_decl_plugin.cpp b/src/ast/seq_decl_plugin.cpp index 750fe0f9d..7cc0ccb12 100644 --- a/src/ast/seq_decl_plugin.cpp +++ b/src/ast/seq_decl_plugin.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include "seq_decl_plugin.h" -#include "arith_decl_plugin.h" -#include "array_decl_plugin.h" -#include "ast_pp.h" +#include "ast/seq_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/ast_pp.h" #include static bool is_hex_digit(char ch, unsigned& d) { diff --git a/src/ast/seq_decl_plugin.h b/src/ast/seq_decl_plugin.h index e2722aa9a..17fa50423 100644 --- a/src/ast/seq_decl_plugin.h +++ b/src/ast/seq_decl_plugin.h @@ -21,8 +21,8 @@ Revision History: #ifndef SEQ_DECL_PLUGIN_H_ #define SEQ_DECL_PLUGIN_H_ -#include "ast.h" -#include "bv_decl_plugin.h" +#include "ast/ast.h" +#include "ast/bv_decl_plugin.h" enum seq_sort_kind { diff --git a/src/ast/shared_occs.cpp b/src/ast/shared_occs.cpp index 5f624e1ac..89867e8c1 100644 --- a/src/ast/shared_occs.cpp +++ b/src/ast/shared_occs.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"shared_occs.h" -#include"ast_smt2_pp.h" -#include"ref_util.h" +#include "ast/shared_occs.h" +#include "ast/ast_smt2_pp.h" +#include "util/ref_util.h" inline void shared_occs::insert(expr * t) { obj_hashtable::entry * dummy; diff --git a/src/ast/shared_occs.h b/src/ast/shared_occs.h index 1566098aa..40921922a 100644 --- a/src/ast/shared_occs.h +++ b/src/ast/shared_occs.h @@ -19,8 +19,8 @@ Revision History: #ifndef SHARED_OCCS_H_ #define SHARED_OCCS_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" class shared_occs_mark { ptr_buffer m_to_unmark; diff --git a/src/ast/simplifier/arith_simplifier_params.cpp b/src/ast/simplifier/arith_simplifier_params.cpp index 8584cdae0..efe21c43d 100644 --- a/src/ast/simplifier/arith_simplifier_params.cpp +++ b/src/ast/simplifier/arith_simplifier_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"arith_simplifier_params.h" +#include "ast/simplifier/arith_simplifier_params.h" #include"arith_simplifier_params_helper.hpp" void arith_simplifier_params::updt_params(params_ref const & _p) { diff --git a/src/ast/simplifier/arith_simplifier_params.h b/src/ast/simplifier/arith_simplifier_params.h index 6186ee4a2..8a4150099 100644 --- a/src/ast/simplifier/arith_simplifier_params.h +++ b/src/ast/simplifier/arith_simplifier_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef ARITH_SIMPLIFIER_PARAMS_H_ #define ARITH_SIMPLIFIER_PARAMS_H_ -#include"params.h" +#include "util/params.h" struct arith_simplifier_params { bool m_arith_expand_eqs; diff --git a/src/ast/simplifier/arith_simplifier_plugin.cpp b/src/ast/simplifier/arith_simplifier_plugin.cpp index ef320578a..8410ce143 100644 --- a/src/ast/simplifier/arith_simplifier_plugin.cpp +++ b/src/ast/simplifier/arith_simplifier_plugin.cpp @@ -14,10 +14,10 @@ Author: Leonardo (leonardo) 2008-01-08 --*/ -#include"arith_simplifier_plugin.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" arith_simplifier_plugin::~arith_simplifier_plugin() { } diff --git a/src/ast/simplifier/arith_simplifier_plugin.h b/src/ast/simplifier/arith_simplifier_plugin.h index e6181e211..21ab8f6b4 100644 --- a/src/ast/simplifier/arith_simplifier_plugin.h +++ b/src/ast/simplifier/arith_simplifier_plugin.h @@ -17,10 +17,10 @@ Author: #ifndef ARITH_SIMPLIFIER_PLUGIN_H_ #define ARITH_SIMPLIFIER_PLUGIN_H_ -#include"basic_simplifier_plugin.h" -#include"poly_simplifier_plugin.h" -#include"arith_decl_plugin.h" -#include"arith_simplifier_params.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/poly_simplifier_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/simplifier/arith_simplifier_params.h" /** \brief Simplifier for the arith family. diff --git a/src/ast/simplifier/array_simplifier_params.cpp b/src/ast/simplifier/array_simplifier_params.cpp index bffff44d9..94a858ac6 100644 --- a/src/ast/simplifier/array_simplifier_params.cpp +++ b/src/ast/simplifier/array_simplifier_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"array_simplifier_params.h" +#include "ast/simplifier/array_simplifier_params.h" #include"array_simplifier_params_helper.hpp" void array_simplifier_params::updt_params(params_ref const & _p) { diff --git a/src/ast/simplifier/array_simplifier_params.h b/src/ast/simplifier/array_simplifier_params.h index c62b990b9..559e3de54 100644 --- a/src/ast/simplifier/array_simplifier_params.h +++ b/src/ast/simplifier/array_simplifier_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef ARRAY_SIMPLIFIER_PARAMS_H_ #define ARRAY_SIMPLIFIER_PARAMS_H_ -#include"params.h" +#include "util/params.h" struct array_simplifier_params { bool m_array_canonize_simplify; diff --git a/src/ast/simplifier/array_simplifier_plugin.cpp b/src/ast/simplifier/array_simplifier_plugin.cpp index 85ef2e92f..754daab69 100644 --- a/src/ast/simplifier/array_simplifier_plugin.cpp +++ b/src/ast/simplifier/array_simplifier_plugin.cpp @@ -24,9 +24,9 @@ Notes TODO: --*/ -#include "array_simplifier_plugin.h" -#include "ast_ll_pp.h" -#include "ast_pp.h" +#include "ast/simplifier/array_simplifier_plugin.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" array_simplifier_plugin::array_simplifier_plugin( diff --git a/src/ast/simplifier/array_simplifier_plugin.h b/src/ast/simplifier/array_simplifier_plugin.h index 34db04b67..62eb5e5ff 100644 --- a/src/ast/simplifier/array_simplifier_plugin.h +++ b/src/ast/simplifier/array_simplifier_plugin.h @@ -19,15 +19,15 @@ Revision History: #ifndef ARRAY_SIMPLIFIER_PLUGIN_H_ #define ARRAY_SIMPLIFIER_PLUGIN_H_ -#include"ast.h" -#include"map.h" -#include"array_decl_plugin.h" -#include"simplifier_plugin.h" -#include"basic_simplifier_plugin.h" -#include"array_simplifier_params.h" -#include"simplifier.h" -#include"obj_hashtable.h" -#include"lbool.h" +#include "ast/ast.h" +#include "util/map.h" +#include "ast/array_decl_plugin.h" +#include "ast/simplifier/simplifier_plugin.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/array_simplifier_params.h" +#include "ast/simplifier/simplifier.h" +#include "util/obj_hashtable.h" +#include "util/lbool.h" class array_simplifier_plugin : public simplifier_plugin { diff --git a/src/ast/simplifier/base_simplifier.h b/src/ast/simplifier/base_simplifier.h index cb630cb7f..73a04d605 100644 --- a/src/ast/simplifier/base_simplifier.h +++ b/src/ast/simplifier/base_simplifier.h @@ -19,8 +19,8 @@ Notes: #ifndef BASE_SIMPLIFIER_H_ #define BASE_SIMPLIFIER_H_ -#include"expr_map.h" -#include"ast_pp.h" +#include "ast/expr_map.h" +#include "ast/ast_pp.h" /** \brief Implements basic functionality used by expression simplifiers. diff --git a/src/ast/simplifier/basic_simplifier_plugin.cpp b/src/ast/simplifier/basic_simplifier_plugin.cpp index 6c713bb10..25998d832 100644 --- a/src/ast/simplifier/basic_simplifier_plugin.cpp +++ b/src/ast/simplifier/basic_simplifier_plugin.cpp @@ -14,9 +14,9 @@ Author: Leonardo (leonardo) 2008-01-07 --*/ -#include"basic_simplifier_plugin.h" -#include"ast_ll_pp.h" -#include"bool_rewriter.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/ast_ll_pp.h" +#include "ast/rewriter/bool_rewriter.h" basic_simplifier_plugin::basic_simplifier_plugin(ast_manager & m): simplifier_plugin(symbol("basic"), m), diff --git a/src/ast/simplifier/basic_simplifier_plugin.h b/src/ast/simplifier/basic_simplifier_plugin.h index d39d6badb..f28a19b56 100644 --- a/src/ast/simplifier/basic_simplifier_plugin.h +++ b/src/ast/simplifier/basic_simplifier_plugin.h @@ -17,7 +17,7 @@ Author: #ifndef BASIC_SIMPLIFIER_PLUGIN_H_ #define BASIC_SIMPLIFIER_PLUGIN_H_ -#include"simplifier_plugin.h" +#include "ast/simplifier/simplifier_plugin.h" class bool_rewriter; diff --git a/src/ast/simplifier/bit2int.cpp b/src/ast/simplifier/bit2int.cpp index 08c3da774..6f7dd1cbe 100644 --- a/src/ast/simplifier/bit2int.cpp +++ b/src/ast/simplifier/bit2int.cpp @@ -19,10 +19,10 @@ Revision History: --*/ -#include "bit2int.h" -#include "ast_pp.h" -#include "ast_ll_pp.h" -#include "for_each_ast.h" +#include "ast/simplifier/bit2int.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/for_each_ast.h" #define CHECK(_x_) if (!(_x_)) { UNREACHABLE(); } diff --git a/src/ast/simplifier/bit2int.h b/src/ast/simplifier/bit2int.h index 6277a83ae..84ae1f4a4 100644 --- a/src/ast/simplifier/bit2int.h +++ b/src/ast/simplifier/bit2int.h @@ -19,11 +19,11 @@ Revision History: #ifndef BIT2INT_H_ #define BIT2INT_H_ -#include"bv_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"act_cache.h" -#include"basic_simplifier_plugin.h" -#include"bv_simplifier_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/act_cache.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" class bit2int { diff --git a/src/ast/simplifier/bv_elim.cpp b/src/ast/simplifier/bv_elim.cpp index 8dc2671ca..1875e333b 100644 --- a/src/ast/simplifier/bv_elim.cpp +++ b/src/ast/simplifier/bv_elim.cpp @@ -4,9 +4,9 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "bv_elim.h" -#include "bv_decl_plugin.h" -#include "var_subst.h" +#include "ast/simplifier/bv_elim.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/var_subst.h" #include void bv_elim::elim(quantifier* q, quantifier_ref& r) { diff --git a/src/ast/simplifier/bv_elim.h b/src/ast/simplifier/bv_elim.h index 3bebcfef1..2b8a4778a 100644 --- a/src/ast/simplifier/bv_elim.h +++ b/src/ast/simplifier/bv_elim.h @@ -20,8 +20,8 @@ Revision History: #ifndef BV_ELIM_H_ #define BV_ELIM_H_ -#include "ast.h" -#include "simplifier.h" +#include "ast/ast.h" +#include "ast/simplifier/simplifier.h" class bv_elim { ast_manager& m_manager; diff --git a/src/ast/simplifier/bv_simplifier_params.cpp b/src/ast/simplifier/bv_simplifier_params.cpp index 1ed263aa6..2639b230c 100644 --- a/src/ast/simplifier/bv_simplifier_params.cpp +++ b/src/ast/simplifier/bv_simplifier_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"bv_simplifier_params.h" +#include "ast/simplifier/bv_simplifier_params.h" #include"bv_simplifier_params_helper.hpp" #include"bv_rewriter_params.hpp" diff --git a/src/ast/simplifier/bv_simplifier_params.h b/src/ast/simplifier/bv_simplifier_params.h index dafa99065..8c0792203 100644 --- a/src/ast/simplifier/bv_simplifier_params.h +++ b/src/ast/simplifier/bv_simplifier_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef BV_SIMPLIFIER_PARAMS_H_ #define BV_SIMPLIFIER_PARAMS_H_ -#include"params.h" +#include "util/params.h" struct bv_simplifier_params { bool m_hi_div0; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted. diff --git a/src/ast/simplifier/bv_simplifier_plugin.cpp b/src/ast/simplifier/bv_simplifier_plugin.cpp index a72e7e117..c23d2e748 100644 --- a/src/ast/simplifier/bv_simplifier_plugin.cpp +++ b/src/ast/simplifier/bv_simplifier_plugin.cpp @@ -15,12 +15,12 @@ Author: Nikolaj Bjorner (nbjorner) 2008-01-05 --*/ -#include"bv_simplifier_plugin.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"arith_decl_plugin.h" -#include"obj_hashtable.h" -#include"ast_util.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "util/obj_hashtable.h" +#include "ast/ast_util.h" bv_simplifier_plugin::~bv_simplifier_plugin() { flush_caches(); diff --git a/src/ast/simplifier/bv_simplifier_plugin.h b/src/ast/simplifier/bv_simplifier_plugin.h index 484edca95..7208b6dc8 100644 --- a/src/ast/simplifier/bv_simplifier_plugin.h +++ b/src/ast/simplifier/bv_simplifier_plugin.h @@ -17,12 +17,12 @@ Author: #ifndef BV_SIMPLIFIER_PLUGIN_H_ #define BV_SIMPLIFIER_PLUGIN_H_ -#include"basic_simplifier_plugin.h" -#include"poly_simplifier_plugin.h" -#include"bv_decl_plugin.h" -#include"map.h" -#include"bv_simplifier_params.h" -#include"arith_decl_plugin.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/poly_simplifier_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "util/map.h" +#include "ast/simplifier/bv_simplifier_params.h" +#include "ast/arith_decl_plugin.h" /** \brief Simplifier for the bv family. diff --git a/src/ast/simplifier/datatype_simplifier_plugin.cpp b/src/ast/simplifier/datatype_simplifier_plugin.cpp index b434a8bd0..b665ed101 100644 --- a/src/ast/simplifier/datatype_simplifier_plugin.cpp +++ b/src/ast/simplifier/datatype_simplifier_plugin.cpp @@ -15,7 +15,7 @@ Author: --*/ -#include"datatype_simplifier_plugin.h" +#include "ast/simplifier/datatype_simplifier_plugin.h" datatype_simplifier_plugin::datatype_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b): simplifier_plugin(symbol("datatype"), m), diff --git a/src/ast/simplifier/datatype_simplifier_plugin.h b/src/ast/simplifier/datatype_simplifier_plugin.h index b675bf92e..e976beba7 100644 --- a/src/ast/simplifier/datatype_simplifier_plugin.h +++ b/src/ast/simplifier/datatype_simplifier_plugin.h @@ -17,8 +17,8 @@ Author: #ifndef DATATYPE_SIMPLIFIER_PLUGIN_H_ #define DATATYPE_SIMPLIFIER_PLUGIN_H_ -#include"basic_simplifier_plugin.h" -#include"datatype_decl_plugin.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/datatype_decl_plugin.h" /** \brief Simplifier for the arith family. diff --git a/src/ast/simplifier/elim_bounds.cpp b/src/ast/simplifier/elim_bounds.cpp index 7a40b8602..738fc3012 100644 --- a/src/ast/simplifier/elim_bounds.cpp +++ b/src/ast/simplifier/elim_bounds.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"elim_bounds.h" -#include"used_vars.h" -#include"obj_hashtable.h" -#include"var_subst.h" -#include"ast_pp.h" +#include "ast/simplifier/elim_bounds.h" +#include "ast/used_vars.h" +#include "util/obj_hashtable.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_pp.h" elim_bounds::elim_bounds(ast_manager & m): m_manager(m), diff --git a/src/ast/simplifier/elim_bounds.h b/src/ast/simplifier/elim_bounds.h index f8276c150..d4da953a8 100644 --- a/src/ast/simplifier/elim_bounds.h +++ b/src/ast/simplifier/elim_bounds.h @@ -19,9 +19,9 @@ Revision History: #ifndef ELIM_BOUNDS_H_ #define ELIM_BOUNDS_H_ -#include"ast.h" -#include"arith_decl_plugin.h" -#include"simplifier.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "ast/simplifier/simplifier.h" /** \brief Functor for eliminating irrelevant bounds in quantified formulas. diff --git a/src/ast/simplifier/fpa_simplifier_plugin.cpp b/src/ast/simplifier/fpa_simplifier_plugin.cpp index 5775f1af0..2d333c872 100644 --- a/src/ast/simplifier/fpa_simplifier_plugin.cpp +++ b/src/ast/simplifier/fpa_simplifier_plugin.cpp @@ -14,7 +14,7 @@ Author: Christoph (cwinter) 2015-01-14 --*/ -#include"fpa_simplifier_plugin.h" +#include "ast/simplifier/fpa_simplifier_plugin.h" fpa_simplifier_plugin::fpa_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b) : simplifier_plugin(symbol("fpa"), m), diff --git a/src/ast/simplifier/fpa_simplifier_plugin.h b/src/ast/simplifier/fpa_simplifier_plugin.h index 0ee8debf2..8c9f8de4e 100644 --- a/src/ast/simplifier/fpa_simplifier_plugin.h +++ b/src/ast/simplifier/fpa_simplifier_plugin.h @@ -17,9 +17,9 @@ Author: #ifndef FPA_SIMPLIFIER_PLUGIN_H_ #define FPA_SIMPLIFIER_PLUGIN_H_ -#include"basic_simplifier_plugin.h" -#include"fpa_decl_plugin.h" -#include"fpa_rewriter.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "ast/rewriter/fpa_rewriter.h" class fpa_simplifier_plugin : public simplifier_plugin { fpa_util m_util; diff --git a/src/ast/simplifier/inj_axiom.cpp b/src/ast/simplifier/inj_axiom.cpp index 5925e23ac..2aa828ffa 100644 --- a/src/ast/simplifier/inj_axiom.cpp +++ b/src/ast/simplifier/inj_axiom.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"inj_axiom.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"has_free_vars.h" -#include"well_sorted.h" +#include "ast/simplifier/inj_axiom.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/has_free_vars.h" +#include "ast/well_sorted.h" /** \brief Little HACK for simplifying injectivity axioms diff --git a/src/ast/simplifier/inj_axiom.h b/src/ast/simplifier/inj_axiom.h index da441c15b..a6df16515 100644 --- a/src/ast/simplifier/inj_axiom.h +++ b/src/ast/simplifier/inj_axiom.h @@ -19,7 +19,7 @@ Revision History: #ifndef INJ_AXIOM_H_ #define INJ_AXIOM_H_ -#include"ast.h" +#include "ast/ast.h" bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result); diff --git a/src/ast/simplifier/maximise_ac_sharing.cpp b/src/ast/simplifier/maximise_ac_sharing.cpp index d5cf69a72..93e5a43f0 100644 --- a/src/ast/simplifier/maximise_ac_sharing.cpp +++ b/src/ast/simplifier/maximise_ac_sharing.cpp @@ -17,9 +17,9 @@ Revision History: --*/ -#include"maximise_ac_sharing.h" -#include"ast_pp.h" -#include"basic_simplifier_plugin.h" +#include "ast/simplifier/maximise_ac_sharing.h" +#include "ast/ast_pp.h" +#include "ast/simplifier/basic_simplifier_plugin.h" maximise_ac_sharing::ac_plugin::ac_plugin(symbol const & fname, ast_manager & m, maximise_ac_sharing & owner): simplifier_plugin(fname, m), diff --git a/src/ast/simplifier/maximise_ac_sharing.h b/src/ast/simplifier/maximise_ac_sharing.h index bd369387c..cf488e20d 100644 --- a/src/ast/simplifier/maximise_ac_sharing.h +++ b/src/ast/simplifier/maximise_ac_sharing.h @@ -19,10 +19,10 @@ Revision History: #ifndef MAXIMISE_AC_SHARING_H_ #define MAXIMISE_AC_SHARING_H_ -#include"simplifier.h" -#include"hashtable.h" -#include"bv_decl_plugin.h" -#include"region.h" +#include "ast/simplifier/simplifier.h" +#include "util/hashtable.h" +#include "ast/bv_decl_plugin.h" +#include "util/region.h" /** \brief Functor used to maximise the amount of shared terms in an expression. diff --git a/src/ast/simplifier/poly_simplifier_plugin.cpp b/src/ast/simplifier/poly_simplifier_plugin.cpp index e5e74ca56..88637d694 100644 --- a/src/ast/simplifier/poly_simplifier_plugin.cpp +++ b/src/ast/simplifier/poly_simplifier_plugin.cpp @@ -14,11 +14,11 @@ Author: Leonardo (leonardo) 2008-01-08 --*/ -#include"poly_simplifier_plugin.h" -#include"ast_pp.h" -#include"ast_util.h" -#include"ast_smt2_pp.h" -#include"ast_ll_pp.h" +#include "ast/simplifier/poly_simplifier_plugin.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_ll_pp.h" poly_simplifier_plugin::poly_simplifier_plugin(symbol const & fname, ast_manager & m, decl_kind add, decl_kind mul, decl_kind uminus, decl_kind sub, decl_kind num): diff --git a/src/ast/simplifier/poly_simplifier_plugin.h b/src/ast/simplifier/poly_simplifier_plugin.h index ed6d506c5..fe5572b20 100644 --- a/src/ast/simplifier/poly_simplifier_plugin.h +++ b/src/ast/simplifier/poly_simplifier_plugin.h @@ -17,7 +17,7 @@ Author: #ifndef POLY_SIMPLIFIER_PLUGIN_H_ #define POLY_SIMPLIFIER_PLUGIN_H_ -#include "simplifier_plugin.h" +#include "ast/simplifier/simplifier_plugin.h" /** \brief Abstract class that provides simplification functions for polynomials. diff --git a/src/ast/simplifier/pull_ite_tree.cpp b/src/ast/simplifier/pull_ite_tree.cpp index 05bb3d885..072bbd12c 100644 --- a/src/ast/simplifier/pull_ite_tree.cpp +++ b/src/ast/simplifier/pull_ite_tree.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"pull_ite_tree.h" -#include"recurse_expr_def.h" -#include"for_each_expr.h" -#include"ast_pp.h" +#include "ast/simplifier/pull_ite_tree.h" +#include "ast/recurse_expr_def.h" +#include "ast/for_each_expr.h" +#include "ast/ast_pp.h" pull_ite_tree::pull_ite_tree(ast_manager & m, simplifier & s): m_manager(m), diff --git a/src/ast/simplifier/pull_ite_tree.h b/src/ast/simplifier/pull_ite_tree.h index 14c447697..bc4a0bb68 100644 --- a/src/ast/simplifier/pull_ite_tree.h +++ b/src/ast/simplifier/pull_ite_tree.h @@ -19,11 +19,11 @@ Revision History: #ifndef PULL_ITE_TREE_H_ #define PULL_ITE_TREE_H_ -#include"ast.h" -#include"simplifier.h" -#include"recurse_expr.h" -#include"obj_hashtable.h" -#include"expr_map.h" +#include "ast/ast.h" +#include "ast/simplifier/simplifier.h" +#include "ast/recurse_expr.h" +#include "util/obj_hashtable.h" +#include "ast/expr_map.h" /** \brief Functor for applying the following transformation diff --git a/src/ast/simplifier/push_app_ite.cpp b/src/ast/simplifier/push_app_ite.cpp index e33f0d094..8b56dcd85 100644 --- a/src/ast/simplifier/push_app_ite.cpp +++ b/src/ast/simplifier/push_app_ite.cpp @@ -17,8 +17,8 @@ Author: Revision History: --*/ -#include"push_app_ite.h" -#include"ast_pp.h" +#include "ast/simplifier/push_app_ite.h" +#include "ast/ast_pp.h" push_app_ite::push_app_ite(simplifier & s, bool conservative): simplifier(s.get_manager()), diff --git a/src/ast/simplifier/push_app_ite.h b/src/ast/simplifier/push_app_ite.h index 104a7ea74..96400b1af 100644 --- a/src/ast/simplifier/push_app_ite.h +++ b/src/ast/simplifier/push_app_ite.h @@ -19,8 +19,8 @@ Revision History: #ifndef PUSH_APP_ITE_H_ #define PUSH_APP_ITE_H_ -#include"ast.h" -#include"simplifier.h" +#include "ast/ast.h" +#include "ast/simplifier/simplifier.h" /** \brief Functor for applying the following transformation: diff --git a/src/ast/simplifier/seq_simplifier_plugin.cpp b/src/ast/simplifier/seq_simplifier_plugin.cpp index 0b7bddf0a..2125c4f4c 100644 --- a/src/ast/simplifier/seq_simplifier_plugin.cpp +++ b/src/ast/simplifier/seq_simplifier_plugin.cpp @@ -14,7 +14,7 @@ Author: Nikolaj Bjorner (nbjorner) 2016-02-05 --*/ -#include"seq_simplifier_plugin.h" +#include "ast/simplifier/seq_simplifier_plugin.h" seq_simplifier_plugin::seq_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b) : simplifier_plugin(symbol("seq"), m), diff --git a/src/ast/simplifier/seq_simplifier_plugin.h b/src/ast/simplifier/seq_simplifier_plugin.h index 45668678c..a37a2209f 100644 --- a/src/ast/simplifier/seq_simplifier_plugin.h +++ b/src/ast/simplifier/seq_simplifier_plugin.h @@ -17,9 +17,9 @@ Author: #ifndef SEQ_SIMPLIFIER_PLUGIN_H_ #define SEQ_SIMPLIFIER_PLUGIN_H_ -#include"basic_simplifier_plugin.h" -#include"seq_decl_plugin.h" -#include"seq_rewriter.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/rewriter/seq_rewriter.h" class seq_simplifier_plugin : public simplifier_plugin { seq_util m_util; diff --git a/src/ast/simplifier/simplifier.cpp b/src/ast/simplifier/simplifier.cpp index 498244919..c02753440 100644 --- a/src/ast/simplifier/simplifier.cpp +++ b/src/ast/simplifier/simplifier.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"simplifier.h" -#include"var_subst.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"well_sorted.h" -#include"ast_smt_pp.h" +#include "ast/simplifier/simplifier.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/well_sorted.h" +#include "ast/ast_smt_pp.h" simplifier::simplifier(ast_manager & m): base_simplifier(m), diff --git a/src/ast/simplifier/simplifier.h b/src/ast/simplifier/simplifier.h index 899b25810..5148721f1 100644 --- a/src/ast/simplifier/simplifier.h +++ b/src/ast/simplifier/simplifier.h @@ -19,11 +19,11 @@ Notes: #ifndef SIMPLIFIER_H_ #define SIMPLIFIER_H_ -#include"base_simplifier.h" -#include"simplifier_plugin.h" -#include"plugin_manager.h" -#include"ast_util.h" -#include"obj_hashtable.h" +#include "ast/simplifier/base_simplifier.h" +#include "ast/simplifier/simplifier_plugin.h" +#include "util/plugin_manager.h" +#include "ast/ast_util.h" +#include "util/obj_hashtable.h" /** \brief Local simplifier. diff --git a/src/ast/simplifier/simplifier_plugin.cpp b/src/ast/simplifier/simplifier_plugin.cpp index 1cdaadf8a..a62b15131 100644 --- a/src/ast/simplifier/simplifier_plugin.cpp +++ b/src/ast/simplifier/simplifier_plugin.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"simplifier_plugin.h" +#include "ast/simplifier/simplifier_plugin.h" /** \brief Copy every args[i] mult[i] times to new_args. diff --git a/src/ast/simplifier/simplifier_plugin.h b/src/ast/simplifier/simplifier_plugin.h index b018dc731..26b5bcd59 100644 --- a/src/ast/simplifier/simplifier_plugin.h +++ b/src/ast/simplifier/simplifier_plugin.h @@ -18,7 +18,7 @@ Author: #ifndef SIMPLIFIER_PLUGIN_H_ #define SIMPLIFIER_PLUGIN_H_ -#include"ast.h" +#include "ast/ast.h" class simplifier; diff --git a/src/ast/static_features.cpp b/src/ast/static_features.cpp index a3ad7fd07..3c8333d02 100644 --- a/src/ast/static_features.cpp +++ b/src/ast/static_features.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"static_features.h" -#include"ast_pp.h" +#include "ast/static_features.h" +#include "ast/ast_pp.h" static_features::static_features(ast_manager & m): m_manager(m), diff --git a/src/ast/static_features.h b/src/ast/static_features.h index e7f69e041..5473ba0ff 100644 --- a/src/ast/static_features.h +++ b/src/ast/static_features.h @@ -19,13 +19,13 @@ Revision History: #ifndef STATIC_FEATURES_H_ #define STATIC_FEATURES_H_ -#include"ast.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"fpa_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"map.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "util/map.h" struct static_features { ast_manager & m_manager; diff --git a/src/ast/substitution/expr_offset.h b/src/ast/substitution/expr_offset.h index ea4f36206..1f27f222a 100644 --- a/src/ast/substitution/expr_offset.h +++ b/src/ast/substitution/expr_offset.h @@ -24,7 +24,7 @@ Revision History: #ifndef EXPR_OFFSET_H_ #define EXPR_OFFSET_H_ -#include"ast.h" +#include "ast/ast.h" class expr_offset { expr * m_expr; diff --git a/src/ast/substitution/expr_offset_map.h b/src/ast/substitution/expr_offset_map.h index 83e22493b..371c7500e 100644 --- a/src/ast/substitution/expr_offset_map.h +++ b/src/ast/substitution/expr_offset_map.h @@ -19,8 +19,8 @@ Revision History: #ifndef EXPR_OFFSET_MAP_H_ #define EXPR_OFFSET_MAP_H_ -#include"expr_offset.h" -#include"vector.h" +#include "ast/substitution/expr_offset.h" +#include "util/vector.h" /** \brief A mapping from expr_offset to some value of type T. diff --git a/src/ast/substitution/matcher.cpp b/src/ast/substitution/matcher.cpp index ce9bdcb3e..a0786e5b4 100644 --- a/src/ast/substitution/matcher.cpp +++ b/src/ast/substitution/matcher.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"matcher.h" +#include "ast/substitution/matcher.h" bool matcher::operator()(expr * e1, expr * e2, substitution & s) { reset(); diff --git a/src/ast/substitution/matcher.h b/src/ast/substitution/matcher.h index c4936579e..1e8c3005a 100644 --- a/src/ast/substitution/matcher.h +++ b/src/ast/substitution/matcher.h @@ -19,8 +19,8 @@ Revision History: #ifndef MATCHER_H_ #define MATCHER_H_ -#include"substitution.h" -#include"hashtable.h" +#include "ast/substitution/substitution.h" +#include "util/hashtable.h" /** \brief Functor for matching expressions. diff --git a/src/ast/substitution/substitution.cpp b/src/ast/substitution/substitution.cpp index f741d3fd4..d54a8e057 100644 --- a/src/ast/substitution/substitution.cpp +++ b/src/ast/substitution/substitution.cpp @@ -17,10 +17,10 @@ Author: Revision History: --*/ -#include"substitution.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"rewriter.h" +#include "ast/substitution/substitution.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/rewriter/rewriter.h" substitution::substitution(ast_manager & m): m_manager(m), diff --git a/src/ast/substitution/substitution.h b/src/ast/substitution/substitution.h index ebd12ef3a..0d318e4fb 100644 --- a/src/ast/substitution/substitution.h +++ b/src/ast/substitution/substitution.h @@ -33,9 +33,9 @@ Revision History: #ifndef SUBSTITUTION_H_ #define SUBSTITUTION_H_ -#include"expr_offset_map.h" -#include"var_offset_map.h" -#include"ast_pp.h" +#include "ast/substitution/expr_offset_map.h" +#include "ast/substitution/var_offset_map.h" +#include "ast/ast_pp.h" /** \brief A mapping from (variable,offset) to expr_offset. diff --git a/src/ast/substitution/substitution_tree.cpp b/src/ast/substitution/substitution_tree.cpp index 6aaa2da66..9befb582f 100644 --- a/src/ast/substitution/substitution_tree.cpp +++ b/src/ast/substitution/substitution_tree.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"substitution_tree.h" -#include"ast_pp.h" -#include"ast_smt2_pp.h" +#include "ast/substitution/substitution_tree.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" /** \brief Return the next available register. diff --git a/src/ast/substitution/substitution_tree.h b/src/ast/substitution/substitution_tree.h index 167d08183..7a8c30a63 100644 --- a/src/ast/substitution/substitution_tree.h +++ b/src/ast/substitution/substitution_tree.h @@ -19,8 +19,8 @@ Revision History: #ifndef SUBSTITUTION_TREE_H_ #define SUBSTITUTION_TREE_H_ -#include"ast.h" -#include"substitution.h" +#include "ast/ast.h" +#include "ast/substitution/substitution.h" /** \brief Substitution tree visitor. diff --git a/src/ast/substitution/unifier.cpp b/src/ast/substitution/unifier.cpp index a5bd4d155..4942b5498 100644 --- a/src/ast/substitution/unifier.cpp +++ b/src/ast/substitution/unifier.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"unifier.h" -#include"ast_pp.h" +#include "ast/substitution/unifier.h" +#include "ast/ast_pp.h" void unifier::reset(unsigned num_offsets) { m_todo.reset(); diff --git a/src/ast/substitution/unifier.h b/src/ast/substitution/unifier.h index 24735117c..171b880e2 100644 --- a/src/ast/substitution/unifier.h +++ b/src/ast/substitution/unifier.h @@ -19,8 +19,8 @@ Revision History: #ifndef UNIFIER_H_ #define UNIFIER_H_ -#include"ast.h" -#include"substitution.h" +#include "ast/ast.h" +#include "ast/substitution/substitution.h" /** \brief Functor for unifying expressions. diff --git a/src/ast/substitution/var_offset_map.h b/src/ast/substitution/var_offset_map.h index f03b80aed..f5488483a 100644 --- a/src/ast/substitution/var_offset_map.h +++ b/src/ast/substitution/var_offset_map.h @@ -19,8 +19,8 @@ Revision History: #ifndef VAR_OFFSET_MAP_H_ #define VAR_OFFSET_MAP_H_ -#include"ast.h" -#include"vector.h" +#include "ast/ast.h" +#include "util/vector.h" /** \brief A mapping from variable-id + offset to some value of type T. diff --git a/src/ast/used_symbols.h b/src/ast/used_symbols.h index 994e3321a..2fd4830fe 100644 --- a/src/ast/used_symbols.h +++ b/src/ast/used_symbols.h @@ -19,9 +19,9 @@ Revision History: #ifndef USED_SYMBOLS_H_ #define USED_SYMBOLS_H_ -#include"ast.h" -#include"hashtable.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/hashtable.h" +#include "util/obj_hashtable.h" struct do_nothing_rename_proc { symbol operator()(symbol const & s) const { return s; } diff --git a/src/ast/used_vars.cpp b/src/ast/used_vars.cpp index f33c5cb50..a1cd65feb 100644 --- a/src/ast/used_vars.cpp +++ b/src/ast/used_vars.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"used_vars.h" +#include "ast/used_vars.h" void used_vars::process(expr * n, unsigned delta) { unsigned j, idx; diff --git a/src/ast/used_vars.h b/src/ast/used_vars.h index b14798e7d..56d633997 100644 --- a/src/ast/used_vars.h +++ b/src/ast/used_vars.h @@ -19,8 +19,8 @@ Revision History: #ifndef USED_VARS_H_ #define USED_VARS_H_ -#include"ast.h" -#include"expr_delta_pair.h" +#include "ast/ast.h" +#include "ast/expr_delta_pair.h" class used_vars { ptr_vector m_found_vars; diff --git a/src/ast/well_sorted.cpp b/src/ast/well_sorted.cpp index b0afe566b..f78cd9121 100644 --- a/src/ast/well_sorted.cpp +++ b/src/ast/well_sorted.cpp @@ -18,12 +18,12 @@ Revision History: --*/ #include -#include"for_each_expr.h" -#include"well_sorted.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"warning.h" -#include"ast_smt2_pp.h" +#include "ast/for_each_expr.h" +#include "ast/well_sorted.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "util/warning.h" +#include "ast/ast_smt2_pp.h" struct well_sorted_proc { ast_manager & m_manager; diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index ea6d1c232..ace4b6a55 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -15,20 +15,20 @@ Author: Notes: --*/ -#include"cmd_context.h" +#include "cmd_context/cmd_context.h" #include"version.h" -#include"ast_smt_pp.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"model_smt2_pp.h" -#include"array_decl_plugin.h" -#include"pp.h" -#include"cmd_util.h" -#include"simplify_cmd.h" -#include"eval_cmd.h" -#include"gparams.h" -#include"env_params.h" -#include"well_sorted.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" +#include "ast/array_decl_plugin.h" +#include "ast/pp.h" +#include "cmd_context/cmd_util.h" +#include "cmd_context/simplify_cmd.h" +#include "cmd_context/eval_cmd.h" +#include "util/gparams.h" +#include "util/env_params.h" +#include "ast/well_sorted.h" #include"pp_params.hpp" class help_cmd : public cmd { diff --git a/src/cmd_context/check_logic.cpp b/src/cmd_context/check_logic.cpp index 0faddce73..1aace7716 100644 --- a/src/cmd_context/check_logic.cpp +++ b/src/cmd_context/check_logic.cpp @@ -16,15 +16,15 @@ Author: Revision History: --*/ -#include"check_logic.h" -#include"arith_decl_plugin.h" -#include"array_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"pb_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"ast_pp.h" -#include"for_each_expr.h" +#include "cmd_context/check_logic.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/pb_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/for_each_expr.h" #include struct check_logic::imp { diff --git a/src/cmd_context/check_logic.h b/src/cmd_context/check_logic.h index 888c6ed9f..b9050fc14 100644 --- a/src/cmd_context/check_logic.h +++ b/src/cmd_context/check_logic.h @@ -19,7 +19,7 @@ Revision History: #ifndef CHECK_LOGIC_H_ #define CHECK_LOGIC_H_ -#include"ast.h" +#include "ast/ast.h" class check_logic { struct imp; diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 45ad08a78..1c9372228 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -17,36 +17,36 @@ Notes: --*/ #include -#include"tptr.h" -#include"cmd_context.h" -#include"func_decl_dependencies.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"pb_decl_plugin.h" -#include"fpa_decl_plugin.h" -#include"ast_pp.h" -#include"var_subst.h" -#include"pp.h" -#include"ast_smt2_pp.h" -#include"basic_cmds.h" -#include"cancel_eh.h" -#include"scoped_ctrl_c.h" -#include"dec_ref_util.h" -#include"decl_collector.h" -#include"well_sorted.h" -#include"model_evaluator.h" -#include"for_each_expr.h" -#include"scoped_timer.h" -#include"interpolant_cmds.h" -#include"model_smt2_pp.h" -#include"model_v2_pp.h" +#include "util/tptr.h" +#include "cmd_context/cmd_context.h" +#include "ast/func_decl_dependencies.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/pb_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/var_subst.h" +#include "ast/pp.h" +#include "ast/ast_smt2_pp.h" +#include "cmd_context/basic_cmds.h" +#include "util/cancel_eh.h" +#include "util/scoped_ctrl_c.h" +#include "util/dec_ref_util.h" +#include "ast/decl_collector.h" +#include "ast/well_sorted.h" +#include "model/model_evaluator.h" +#include "ast/for_each_expr.h" +#include "util/scoped_timer.h" +#include "cmd_context/interpolant_cmds.h" +#include "model/model_smt2_pp.h" +#include "model/model_v2_pp.h" #include"model_params.hpp" -#include"th_rewriter.h" -#include"tactic_exception.h" -#include"smt_logics.h" +#include "ast/rewriter/th_rewriter.h" +#include "tactic/tactic_exception.h" +#include "solver/smt_logics.h" func_decls::func_decls(ast_manager & m, func_decl * f): m_decls(TAG(func_decl*, f, 0)) { diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index 171d59a21..ca4883e74 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -23,21 +23,21 @@ Notes: #include #include -#include"ast.h" -#include"ast_printer.h" -#include"pdecl.h" -#include"dictionary.h" -#include"solver.h" -#include"datatype_decl_plugin.h" -#include"stopwatch.h" -#include"cmd_context_types.h" -#include"event_handler.h" -#include"sexpr.h" -#include"tactic_manager.h" -#include"check_logic.h" -#include"progress_callback.h" -#include"scoped_ptr_vector.h" -#include"context_params.h" +#include "ast/ast.h" +#include "ast/ast_printer.h" +#include "cmd_context/pdecl.h" +#include "util/dictionary.h" +#include "solver/solver.h" +#include "ast/datatype_decl_plugin.h" +#include "util/stopwatch.h" +#include "util/cmd_context_types.h" +#include "util/event_handler.h" +#include "util/sexpr.h" +#include "cmd_context/tactic_manager.h" +#include "cmd_context/check_logic.h" +#include "solver/progress_callback.h" +#include "util/scoped_ptr_vector.h" +#include "cmd_context/context_params.h" class func_decls { diff --git a/src/cmd_context/cmd_context_to_goal.cpp b/src/cmd_context/cmd_context_to_goal.cpp index c0b4379aa..beff9a7bd 100644 --- a/src/cmd_context/cmd_context_to_goal.cpp +++ b/src/cmd_context/cmd_context_to_goal.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"cmd_context.h" -#include"goal.h" +#include "cmd_context/cmd_context.h" +#include "tactic/goal.h" /** \brief Assert expressions from ctx into t. diff --git a/src/cmd_context/cmd_util.cpp b/src/cmd_context/cmd_util.cpp index 9774c75ff..ae626118c 100644 --- a/src/cmd_context/cmd_util.cpp +++ b/src/cmd_context/cmd_util.cpp @@ -15,7 +15,7 @@ Author: Notes: --*/ -#include"cmd_context.h" +#include "cmd_context/cmd_context.h" ast * get_ast_ref(cmd_context & ctx, symbol const & v) { object_ref * r = ctx.find_object_ref(v); diff --git a/src/cmd_context/context_params.cpp b/src/cmd_context/context_params.cpp index ff8b50c60..9a3339b84 100644 --- a/src/cmd_context/context_params.cpp +++ b/src/cmd_context/context_params.cpp @@ -17,11 +17,11 @@ Author: Notes: --*/ -#include"context_params.h" -#include"gparams.h" -#include"params.h" -#include"ast.h" -#include"solver.h" +#include "cmd_context/context_params.h" +#include "util/gparams.h" +#include "util/params.h" +#include "ast/ast.h" +#include "solver/solver.h" context_params::context_params() { m_unsat_core = false; diff --git a/src/cmd_context/context_params.h b/src/cmd_context/context_params.h index 40b6c9482..c238af556 100644 --- a/src/cmd_context/context_params.h +++ b/src/cmd_context/context_params.h @@ -20,7 +20,7 @@ Notes: #ifndef CONTEXT_PARAMS_H_ #define CONTEXT_PARAMS_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class context_params { diff --git a/src/cmd_context/echo_tactic.cpp b/src/cmd_context/echo_tactic.cpp index 218d9c196..848ae5429 100644 --- a/src/cmd_context/echo_tactic.cpp +++ b/src/cmd_context/echo_tactic.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"tactic.h" -#include"probe.h" -#include"cmd_context.h" +#include "tactic/tactic.h" +#include "tactic/probe.h" +#include "cmd_context/cmd_context.h" class echo_tactic : public skip_tactic { cmd_context & m_ctx; diff --git a/src/cmd_context/eval_cmd.cpp b/src/cmd_context/eval_cmd.cpp index 3b00179c6..9d3c1ced3 100644 --- a/src/cmd_context/eval_cmd.cpp +++ b/src/cmd_context/eval_cmd.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"cmd_context.h" -#include"model_evaluator.h" -#include"parametric_cmd.h" -#include"scoped_timer.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" +#include "cmd_context/cmd_context.h" +#include "model/model_evaluator.h" +#include "cmd_context/parametric_cmd.h" +#include "util/scoped_timer.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" class eval_cmd : public parametric_cmd { expr * m_target; diff --git a/src/cmd_context/extra_cmds/dbg_cmds.cpp b/src/cmd_context/extra_cmds/dbg_cmds.cpp index 16815ccb6..7d20685ac 100644 --- a/src/cmd_context/extra_cmds/dbg_cmds.cpp +++ b/src/cmd_context/extra_cmds/dbg_cmds.cpp @@ -16,20 +16,20 @@ Notes: --*/ #include -#include"cmd_context.h" -#include"cmd_util.h" -#include"rewriter.h" -#include"shared_occs.h" -#include"for_each_expr.h" -#include"rewriter.h" -#include"bool_rewriter.h" -#include"ast_lt.h" -#include"simplify_cmd.h" -#include"ast_smt2_pp.h" -#include"bound_manager.h" -#include"used_vars.h" -#include"var_subst.h" -#include"gparams.h" +#include "cmd_context/cmd_context.h" +#include "cmd_context/cmd_util.h" +#include "ast/rewriter/rewriter.h" +#include "ast/shared_occs.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/ast_lt.h" +#include "cmd_context/simplify_cmd.h" +#include "ast/ast_smt2_pp.h" +#include "tactic/arith/bound_manager.h" +#include "ast/used_vars.h" +#include "ast/rewriter/var_subst.h" +#include "util/gparams.h" #ifndef _EXTERNAL_RELEASE diff --git a/src/cmd_context/extra_cmds/polynomial_cmds.cpp b/src/cmd_context/extra_cmds/polynomial_cmds.cpp index afd4713bd..33f252a64 100644 --- a/src/cmd_context/extra_cmds/polynomial_cmds.cpp +++ b/src/cmd_context/extra_cmds/polynomial_cmds.cpp @@ -16,19 +16,19 @@ Notes: --*/ #include -#include"cmd_context.h" -#include"cmd_util.h" -#include"scoped_timer.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"ast_smt2_pp.h" -#include"expr2polynomial.h" -#include"parametric_cmd.h" -#include"mpq.h" -#include"algebraic_numbers.h" -#include"polynomial_var2value.h" -#include"expr2var.h" -#include"pp.h" +#include "cmd_context/cmd_context.h" +#include "cmd_context/cmd_util.h" +#include "util/scoped_timer.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "ast/ast_smt2_pp.h" +#include "ast/expr2polynomial.h" +#include "cmd_context/parametric_cmd.h" +#include "util/mpq.h" +#include "math/polynomial/algebraic_numbers.h" +#include "math/polynomial/polynomial_var2value.h" +#include "ast/expr2var.h" +#include "ast/pp.h" #include"pp_params.hpp" static void to_poly(cmd_context & ctx, expr * t) { diff --git a/src/cmd_context/extra_cmds/subpaving_cmds.cpp b/src/cmd_context/extra_cmds/subpaving_cmds.cpp index d6496bccc..3c8a657ac 100644 --- a/src/cmd_context/extra_cmds/subpaving_cmds.cpp +++ b/src/cmd_context/extra_cmds/subpaving_cmds.cpp @@ -16,12 +16,12 @@ Notes: --*/ #include -#include"cmd_context.h" -#include"cmd_util.h" -#include"expr2subpaving.h" -#include"th_rewriter.h" -#include"ast_smt2_pp.h" -#include"expr2var.h" +#include "cmd_context/cmd_context.h" +#include "cmd_context/cmd_util.h" +#include "math/subpaving/tactic/expr2subpaving.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/ast_smt2_pp.h" +#include "ast/expr2var.h" static void to_subpaving(cmd_context & ctx, expr * t) { ast_manager & m = ctx.m(); diff --git a/src/cmd_context/interpolant_cmds.cpp b/src/cmd_context/interpolant_cmds.cpp index 2bfdd9848..65e7a17d8 100644 --- a/src/cmd_context/interpolant_cmds.cpp +++ b/src/cmd_context/interpolant_cmds.cpp @@ -16,23 +16,23 @@ --*/ #include -#include"cmd_context.h" -#include"cmd_util.h" -#include"scoped_timer.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"ast_pp.h" -#include"ast_smt_pp.h" -#include"ast_smt2_pp.h" -#include"parametric_cmd.h" -#include"mpq.h" -#include"expr2var.h" -#include"pp.h" -#include"iz3interp.h" -#include"iz3checker.h" -#include"iz3profiling.h" +#include "cmd_context/cmd_context.h" +#include "cmd_context/cmd_util.h" +#include "util/scoped_timer.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_smt2_pp.h" +#include "cmd_context/parametric_cmd.h" +#include "util/mpq.h" +#include "ast/expr2var.h" +#include "ast/pp.h" +#include "interp/iz3interp.h" +#include "interp/iz3checker.h" +#include "interp/iz3profiling.h" #include"interp_params.hpp" -#include"scoped_proof.h" +#include "ast/scoped_proof.h" static void show_interpolant_and_maybe_check(cmd_context & ctx, ptr_vector &cnsts, diff --git a/src/cmd_context/parametric_cmd.cpp b/src/cmd_context/parametric_cmd.cpp index c229bc29c..4a85821b2 100644 --- a/src/cmd_context/parametric_cmd.cpp +++ b/src/cmd_context/parametric_cmd.cpp @@ -16,8 +16,8 @@ Notes: --*/ #include -#include"cmd_context.h" -#include"parametric_cmd.h" +#include "cmd_context/cmd_context.h" +#include "cmd_context/parametric_cmd.h" char const * parametric_cmd::get_descr(cmd_context & ctx) const { if (m_descr == 0) { diff --git a/src/cmd_context/parametric_cmd.h b/src/cmd_context/parametric_cmd.h index cac5fe38e..6d676d6f9 100644 --- a/src/cmd_context/parametric_cmd.h +++ b/src/cmd_context/parametric_cmd.h @@ -18,10 +18,10 @@ Notes: #ifndef PARAMETRIC_CMD_H_ #define PARAMETRIC_CMD_H_ -#include"params.h" -#include"symbol.h" -#include"string_buffer.h" -#include"cmd_context_types.h" +#include "util/params.h" +#include "util/symbol.h" +#include "util/string_buffer.h" +#include "util/cmd_context_types.h" class parametric_cmd : public cmd { public: diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index bd2ef849a..983dbbc78 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"pdecl.h" -#include"datatype_decl_plugin.h" +#include "cmd_context/pdecl.h" +#include "ast/datatype_decl_plugin.h" using namespace format_ns; class psort_inst_cache { diff --git a/src/cmd_context/pdecl.h b/src/cmd_context/pdecl.h index 31005fe0d..2dfbb93ae 100644 --- a/src/cmd_context/pdecl.h +++ b/src/cmd_context/pdecl.h @@ -19,10 +19,10 @@ Revision History: #ifndef PDECL_H_ #define PDECL_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"dictionary.h" -#include"format.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "util/dictionary.h" +#include "ast/format.h" class pdecl_manager; diff --git a/src/cmd_context/simplify_cmd.cpp b/src/cmd_context/simplify_cmd.cpp index 8b354c8b7..5112a6ea2 100644 --- a/src/cmd_context/simplify_cmd.cpp +++ b/src/cmd_context/simplify_cmd.cpp @@ -15,16 +15,16 @@ Author: Notes: --*/ -#include"cmd_context.h" -#include"th_rewriter.h" -#include"shared_occs.h" -#include"ast_smt_pp.h" -#include"for_each_expr.h" -#include"parametric_cmd.h" -#include"scoped_timer.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"seq_rewriter.h" +#include "cmd_context/cmd_context.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/shared_occs.h" +#include "ast/ast_smt_pp.h" +#include "ast/for_each_expr.h" +#include "cmd_context/parametric_cmd.h" +#include "util/scoped_timer.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "ast/rewriter/seq_rewriter.h" #include class simplify_cmd : public parametric_cmd { diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index 119deec8c..b5ad0707d 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -16,21 +16,21 @@ Notes: --*/ #include -#include"tactic_cmds.h" -#include"cmd_context.h" -#include"cmd_util.h" -#include"parametric_cmd.h" -#include"scoped_timer.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"model_smt2_pp.h" -#include"ast_smt2_pp.h" -#include"tactic.h" -#include"tactical.h" -#include"probe.h" -#include"check_sat_result.h" -#include"cmd_context_to_goal.h" -#include"echo_tactic.h" +#include "cmd_context/tactic_cmds.h" +#include "cmd_context/cmd_context.h" +#include "cmd_context/cmd_util.h" +#include "cmd_context/parametric_cmd.h" +#include "util/scoped_timer.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "model/model_smt2_pp.h" +#include "ast/ast_smt2_pp.h" +#include "tactic/tactic.h" +#include "tactic/tactical.h" +#include "tactic/probe.h" +#include "solver/check_sat_result.h" +#include "cmd_context/cmd_context_to_goal.h" +#include "cmd_context/echo_tactic.h" tactic_cmd::~tactic_cmd() { dealloc(m_factory); diff --git a/src/cmd_context/tactic_cmds.h b/src/cmd_context/tactic_cmds.h index e21d818bb..fc15c795b 100644 --- a/src/cmd_context/tactic_cmds.h +++ b/src/cmd_context/tactic_cmds.h @@ -18,9 +18,9 @@ Notes: #ifndef TACTIC_CMDS_H_ #define TACTIC_CMDS_H_ -#include"ast.h" -#include"cmd_context_types.h" -#include"ref.h" +#include "ast/ast.h" +#include "util/cmd_context_types.h" +#include "util/ref.h" class tactic; class probe; diff --git a/src/cmd_context/tactic_manager.cpp b/src/cmd_context/tactic_manager.cpp index 3442dd9b9..94b5e35ab 100644 --- a/src/cmd_context/tactic_manager.cpp +++ b/src/cmd_context/tactic_manager.cpp @@ -16,7 +16,7 @@ Author: Notes: --*/ -#include"tactic_manager.h" +#include "cmd_context/tactic_manager.h" tactic_manager::~tactic_manager() { finalize_tactic_cmds(); diff --git a/src/cmd_context/tactic_manager.h b/src/cmd_context/tactic_manager.h index 44a25f01e..276c756ba 100644 --- a/src/cmd_context/tactic_manager.h +++ b/src/cmd_context/tactic_manager.h @@ -18,8 +18,8 @@ Notes: #ifndef TACTIC_MANAGER_H_ #define TACTIC_MANAGER_H_ -#include"tactic_cmds.h" -#include"dictionary.h" +#include "cmd_context/tactic_cmds.h" +#include "util/dictionary.h" class tactic_manager { protected: diff --git a/src/duality/duality.h b/src/duality/duality.h index 72d72ac6b..0ef6be30e 100644 --- a/src/duality/duality.h +++ b/src/duality/duality.h @@ -20,7 +20,7 @@ #pragma once -#include "duality_wrapper.h" +#include "duality/duality_wrapper.h" #include #include diff --git a/src/duality/duality_profiling.cpp b/src/duality/duality_profiling.cpp index e841f674b..2e659f0a1 100755 --- a/src/duality/duality_profiling.cpp +++ b/src/duality/duality_profiling.cpp @@ -31,8 +31,8 @@ #pragma warning(disable:4267) #endif -#include "duality_wrapper.h" -#include "iz3profiling.h" +#include "duality/duality_wrapper.h" +#include "interp/iz3profiling.h" namespace Duality { diff --git a/src/duality/duality_rpfp.cpp b/src/duality/duality_rpfp.cpp index c86ff9f62..c9ad8fd56 100755 --- a/src/duality/duality_rpfp.cpp +++ b/src/duality/duality_rpfp.cpp @@ -33,8 +33,8 @@ #include -#include "duality.h" -#include "duality_profiling.h" +#include "duality/duality.h" +#include "duality/duality_profiling.h" // TODO: do we need these? #ifdef Z3OPS diff --git a/src/duality/duality_solver.cpp b/src/duality/duality_solver.cpp index 1869b74ce..1711b65ad 100644 --- a/src/duality/duality_solver.cpp +++ b/src/duality/duality_solver.cpp @@ -25,8 +25,8 @@ #pragma warning(disable:4267) #endif -#include "duality.h" -#include "duality_profiling.h" +#include "duality/duality.h" +#include "duality/duality_profiling.h" #include #include diff --git a/src/duality/duality_wrapper.cpp b/src/duality/duality_wrapper.cpp index 35033f739..4493beddf 100755 --- a/src/duality/duality_wrapper.cpp +++ b/src/duality/duality_wrapper.cpp @@ -25,15 +25,15 @@ #pragma warning(disable:4101) #endif -#include "duality_wrapper.h" +#include "duality/duality_wrapper.h" #include -#include "smt_solver.h" -#include "iz3interp.h" -#include "statistics.h" -#include "expr_abstract.h" -#include "stopwatch.h" -#include "model_smt2_pp.h" -#include "qe_lite.h" +#include "smt/smt_solver.h" +#include "interp/iz3interp.h" +#include "util/statistics.h" +#include "ast/expr_abstract.h" +#include "util/stopwatch.h" +#include "model/model_smt2_pp.h" +#include "qe/qe_lite.h" namespace Duality { diff --git a/src/duality/duality_wrapper.h b/src/duality/duality_wrapper.h index e5e55efed..8e2d70ea6 100644 --- a/src/duality/duality_wrapper.h +++ b/src/duality/duality_wrapper.h @@ -30,28 +30,28 @@ #include"version.h" #include -#include "iz3hash.h" -#include "model.h" -#include "solver.h" +#include "interp/iz3hash.h" +#include "model/model.h" +#include "solver/solver.h" -#include"well_sorted.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"array_decl_plugin.h" -#include"ast_translation.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt_pp.h" -#include"ast_smt2_pp.h" -#include"th_rewriter.h" -#include"var_subst.h" -#include"expr_substitution.h" -#include"pp.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"scoped_timer.h" -#include"scoped_proof.h" +#include "ast/well_sorted.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/ast_translation.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/expr_substitution.h" +#include "ast/pp.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" +#include "ast/scoped_proof.h" namespace Duality { diff --git a/src/interp/iz3base.cpp b/src/interp/iz3base.cpp index d0f8c3a75..b9284b869 100755 --- a/src/interp/iz3base.cpp +++ b/src/interp/iz3base.cpp @@ -25,12 +25,12 @@ #pragma warning(disable:4101) #endif -#include "iz3base.h" +#include "interp/iz3base.h" #include #include #include #include -#include "solver.h" +#include "solver/solver.h" #include "../smt/smt_solver.h" diff --git a/src/interp/iz3base.h b/src/interp/iz3base.h index 59cbf3a61..ac171aa9e 100755 --- a/src/interp/iz3base.h +++ b/src/interp/iz3base.h @@ -21,8 +21,8 @@ #ifndef IZ3BASE_H #define IZ3BASE_H -#include "iz3mgr.h" -#include "iz3scopes.h" +#include "interp/iz3mgr.h" +#include "interp/iz3scopes.h" namespace hash_space { template <> diff --git a/src/interp/iz3checker.cpp b/src/interp/iz3checker.cpp index 69cfea8b8..8fa99fe10 100755 --- a/src/interp/iz3checker.cpp +++ b/src/interp/iz3checker.cpp @@ -24,8 +24,8 @@ #pragma warning(disable:4101) #endif -#include "iz3base.h" -#include "iz3checker.h" +#include "interp/iz3base.h" +#include "interp/iz3checker.h" #include #include diff --git a/src/interp/iz3checker.h b/src/interp/iz3checker.h index 6028e60db..175b5a43a 100644 --- a/src/interp/iz3checker.h +++ b/src/interp/iz3checker.h @@ -20,8 +20,8 @@ #ifndef IZ3_CHECKER_H #define IZ3_CHECKER_H -#include "iz3mgr.h" -#include "solver.h" +#include "interp/iz3mgr.h" +#include "solver/solver.h" bool iz3check(ast_manager &_m_manager, solver *s, diff --git a/src/interp/iz3exception.h b/src/interp/iz3exception.h index 134c049cf..b3f841565 100644 --- a/src/interp/iz3exception.h +++ b/src/interp/iz3exception.h @@ -17,8 +17,8 @@ Notes: #ifndef _IZ3EXCEPTION_H_ #define _IZ3EXCEPTION_H_ -#include "z3_exception.h" -#include "error_codes.h" +#include "util/z3_exception.h" +#include "util/error_codes.h" class iz3_exception: public default_exception { public: diff --git a/src/interp/iz3hash.h b/src/interp/iz3hash.h index 9cf03b53d..483c7ca49 100644 --- a/src/interp/iz3hash.h +++ b/src/interp/iz3hash.h @@ -36,7 +36,7 @@ #include #include #include -#include "hash.h" +#include "util/hash.h" #define stl_ext hash_space diff --git a/src/interp/iz3interp.cpp b/src/interp/iz3interp.cpp index bb83349da..f9bf03951 100755 --- a/src/interp/iz3interp.cpp +++ b/src/interp/iz3interp.cpp @@ -33,13 +33,13 @@ #include #include -#include "iz3profiling.h" -#include "iz3translate.h" -#include "iz3proof.h" -#include "iz3hash.h" -#include "iz3interp.h" +#include "interp/iz3profiling.h" +#include "interp/iz3translate.h" +#include "interp/iz3proof.h" +#include "interp/iz3hash.h" +#include "interp/iz3interp.h" -#include"scoped_proof.h" +#include "ast/scoped_proof.h" using namespace stl_ext; diff --git a/src/interp/iz3interp.h b/src/interp/iz3interp.h index 601c8c3f5..9763208f1 100644 --- a/src/interp/iz3interp.h +++ b/src/interp/iz3interp.h @@ -20,9 +20,9 @@ #ifndef IZ3_INTERP_H #define IZ3_INTERP_H -#include "iz3hash.h" -#include "iz3exception.h" -#include "solver.h" +#include "interp/iz3hash.h" +#include "interp/iz3exception.h" +#include "solver/solver.h" class iz3base; diff --git a/src/interp/iz3mgr.cpp b/src/interp/iz3mgr.cpp index 2e55d7040..306807f1f 100755 --- a/src/interp/iz3mgr.cpp +++ b/src/interp/iz3mgr.cpp @@ -27,15 +27,15 @@ #pragma warning(disable:4800) #endif -#include "iz3mgr.h" +#include "interp/iz3mgr.h" #include #include #include #include -#include "expr_abstract.h" -#include "params.h" +#include "ast/expr_abstract.h" +#include "util/params.h" using namespace stl_ext; diff --git a/src/interp/iz3mgr.h b/src/interp/iz3mgr.h index 424b95359..e6e08f84d 100755 --- a/src/interp/iz3mgr.h +++ b/src/interp/iz3mgr.h @@ -25,26 +25,26 @@ #include #include -#include "iz3hash.h" -#include "iz3exception.h" +#include "interp/iz3hash.h" +#include "interp/iz3exception.h" -#include"well_sorted.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"array_decl_plugin.h" -#include"ast_translation.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt_pp.h" -#include"ast_smt2_pp.h" -#include"th_rewriter.h" -#include"var_subst.h" -#include"expr_substitution.h" -#include"pp.h" -#include"scoped_ctrl_c.h" -#include"cancel_eh.h" -#include"scoped_timer.h" +#include "ast/well_sorted.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/ast_translation.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/expr_substitution.h" +#include "ast/pp.h" +#include "util/scoped_ctrl_c.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" /* A wrapper around an ast manager, providing convenience methods. */ diff --git a/src/interp/iz3pp.cpp b/src/interp/iz3pp.cpp index 066e04e83..787fa4ec7 100644 --- a/src/interp/iz3pp.cpp +++ b/src/interp/iz3pp.cpp @@ -26,14 +26,14 @@ #include #include -#include "iz3mgr.h" -#include "iz3pp.h" -#include "func_decl_dependencies.h" -#include"for_each_expr.h" -#include"ast_smt_pp.h" -#include"ast_smt2_pp.h" -#include"expr_functors.h" -#include"expr_abstract.h" +#include "interp/iz3mgr.h" +#include "interp/iz3pp.h" +#include "ast/func_decl_dependencies.h" +#include "ast/for_each_expr.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/expr_functors.h" +#include "ast/expr_abstract.h" using namespace stl_ext; diff --git a/src/interp/iz3pp.h b/src/interp/iz3pp.h index c66b4a4fa..eec88d35e 100644 --- a/src/interp/iz3pp.h +++ b/src/interp/iz3pp.h @@ -20,7 +20,7 @@ #ifndef IZ3_PP_H #define IZ3_PP_H -#include "iz3mgr.h" +#include "interp/iz3mgr.h" /** Exception thrown in case of mal-formed tree interpoloation specification */ diff --git a/src/interp/iz3profiling.cpp b/src/interp/iz3profiling.cpp index f3b3d0efc..df3126e4f 100755 --- a/src/interp/iz3profiling.cpp +++ b/src/interp/iz3profiling.cpp @@ -24,14 +24,14 @@ #pragma warning(disable:4101) #endif -#include "iz3profiling.h" +#include "interp/iz3profiling.h" #include #include #include #include #include -#include "stopwatch.h" +#include "util/stopwatch.h" // FIXME fill in these stubs diff --git a/src/interp/iz3proof.cpp b/src/interp/iz3proof.cpp index 9adcce3c3..bc046ceff 100755 --- a/src/interp/iz3proof.cpp +++ b/src/interp/iz3proof.cpp @@ -25,8 +25,8 @@ #pragma warning(disable:4101) #endif -#include "iz3proof.h" -#include "iz3profiling.h" +#include "interp/iz3proof.h" +#include "interp/iz3profiling.h" #include #include diff --git a/src/interp/iz3proof.h b/src/interp/iz3proof.h index 213afce5e..ba4507ba2 100755 --- a/src/interp/iz3proof.h +++ b/src/interp/iz3proof.h @@ -22,8 +22,8 @@ #include -#include "iz3base.h" -#include "iz3secondary.h" +#include "interp/iz3base.h" +#include "interp/iz3secondary.h" // #define CHECK_PROOFS diff --git a/src/interp/iz3proof_itp.cpp b/src/interp/iz3proof_itp.cpp index 26ef7386c..eb7f8e325 100755 --- a/src/interp/iz3proof_itp.cpp +++ b/src/interp/iz3proof_itp.cpp @@ -24,7 +24,7 @@ #pragma warning(disable:4101) #endif -#include "iz3proof_itp.h" +#include "interp/iz3proof_itp.h" using namespace stl_ext; diff --git a/src/interp/iz3proof_itp.h b/src/interp/iz3proof_itp.h index bd9eca441..c9a36e9b1 100644 --- a/src/interp/iz3proof_itp.h +++ b/src/interp/iz3proof_itp.h @@ -22,8 +22,8 @@ #include -#include "iz3base.h" -#include "iz3secondary.h" +#include "interp/iz3base.h" +#include "interp/iz3secondary.h" // #define CHECK_PROOFS diff --git a/src/interp/iz3scopes.cpp b/src/interp/iz3scopes.cpp index b70f37a06..e3a28abdd 100755 --- a/src/interp/iz3scopes.cpp +++ b/src/interp/iz3scopes.cpp @@ -21,7 +21,7 @@ #include -#include "iz3scopes.h" +#include "interp/iz3scopes.h" /** computes the least common ancestor of two nodes in the tree, or SHRT_MAX if none */ diff --git a/src/interp/iz3scopes.h b/src/interp/iz3scopes.h index 38f9e2292..745256e57 100755 --- a/src/interp/iz3scopes.h +++ b/src/interp/iz3scopes.h @@ -23,7 +23,7 @@ #include #include -#include "iz3hash.h" +#include "interp/iz3hash.h" class scopes { diff --git a/src/interp/iz3secondary.h b/src/interp/iz3secondary.h index 46d080595..a5a949b54 100755 --- a/src/interp/iz3secondary.h +++ b/src/interp/iz3secondary.h @@ -23,7 +23,7 @@ /** Interface class for secondary provers. */ -#include "iz3base.h" +#include "interp/iz3base.h" #include class iz3secondary : public iz3mgr { diff --git a/src/interp/iz3translate.cpp b/src/interp/iz3translate.cpp index 4f6741989..ebbee46ca 100755 --- a/src/interp/iz3translate.cpp +++ b/src/interp/iz3translate.cpp @@ -24,11 +24,11 @@ #pragma warning(disable:4101) #endif -#include "iz3translate.h" -#include "iz3proof.h" -#include "iz3profiling.h" -#include "iz3interp.h" -#include "iz3proof_itp.h" +#include "interp/iz3translate.h" +#include "interp/iz3proof.h" +#include "interp/iz3profiling.h" +#include "interp/iz3interp.h" +#include "interp/iz3proof_itp.h" #include #include diff --git a/src/interp/iz3translate.h b/src/interp/iz3translate.h index 15e836cd8..3430d11b3 100755 --- a/src/interp/iz3translate.h +++ b/src/interp/iz3translate.h @@ -22,8 +22,8 @@ #ifndef IZ3TRANSLATION_H #define IZ3TRANSLATION_H -#include "iz3proof.h" -#include "iz3secondary.h" +#include "interp/iz3proof.h" +#include "interp/iz3secondary.h" // This is a interface class for translation from Z3 proof terms to // an interpolatable proof diff --git a/src/interp/iz3translate_direct.cpp b/src/interp/iz3translate_direct.cpp index de1da6ce6..b88e488b4 100755 --- a/src/interp/iz3translate_direct.cpp +++ b/src/interp/iz3translate_direct.cpp @@ -28,10 +28,10 @@ #pragma warning(disable:4390) #endif -#include "iz3translate.h" -#include "iz3proof.h" -#include "iz3profiling.h" -#include "iz3interp.h" +#include "interp/iz3translate.h" +#include "interp/iz3proof.h" +#include "interp/iz3profiling.h" +#include "interp/iz3interp.h" #include #include diff --git a/src/math/automata/automaton.cpp b/src/math/automata/automaton.cpp index ab908525e..20cfc3a84 100644 --- a/src/math/automata/automaton.cpp +++ b/src/math/automata/automaton.cpp @@ -18,6 +18,6 @@ Revision History: --*/ -#include "automaton.h" +#include "math/automata/automaton.h" template class automaton; diff --git a/src/math/automata/automaton.h b/src/math/automata/automaton.h index 2a68cba08..cf4dcbfc6 100644 --- a/src/math/automata/automaton.h +++ b/src/math/automata/automaton.h @@ -22,9 +22,9 @@ Revision History: #define AUTOMATON_H_ -#include "util.h" -#include "vector.h" -#include "uint_set.h" +#include "util/util.h" +#include "util/vector.h" +#include "util/uint_set.h" template class default_value_manager { diff --git a/src/math/automata/boolean_algebra.h b/src/math/automata/boolean_algebra.h index 4f5527f5e..e49d414c4 100644 --- a/src/math/automata/boolean_algebra.h +++ b/src/math/automata/boolean_algebra.h @@ -21,7 +21,7 @@ Revision History: #ifndef BOOLEAN_ALGEBRA_H_ #define BOOLEAN_ALGEBRA_H_ -#include "util.h" +#include "util/util.h" template class positive_boolean_algebra { diff --git a/src/math/automata/symbolic_automata.h b/src/math/automata/symbolic_automata.h index 5c2b4a2a4..4a8e7a74d 100644 --- a/src/math/automata/symbolic_automata.h +++ b/src/math/automata/symbolic_automata.h @@ -22,8 +22,8 @@ Revision History: #define SYMBOLIC_AUTOMATA_H_ -#include "automaton.h" -#include "boolean_algebra.h" +#include "math/automata/automaton.h" +#include "math/automata/boolean_algebra.h" template > diff --git a/src/math/automata/symbolic_automata_def.h b/src/math/automata/symbolic_automata_def.h index 01476eb53..c1ee53214 100644 --- a/src/math/automata/symbolic_automata_def.h +++ b/src/math/automata/symbolic_automata_def.h @@ -22,8 +22,8 @@ Revision History: #define SYMBOLIC_AUTOMATA_DEF_H_ -#include "symbolic_automata.h" -#include "hashtable.h" +#include "math/automata/symbolic_automata.h" +#include "util/hashtable.h" diff --git a/src/math/euclid/euclidean_solver.cpp b/src/math/euclid/euclidean_solver.cpp index b33dbf3aa..1be239c36 100644 --- a/src/math/euclid/euclidean_solver.cpp +++ b/src/math/euclid/euclidean_solver.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"euclidean_solver.h" -#include"numeral_buffer.h" -#include"heap.h" +#include "math/euclid/euclidean_solver.h" +#include "util/numeral_buffer.h" +#include "util/heap.h" struct euclidean_solver::imp { typedef unsigned var; diff --git a/src/math/euclid/euclidean_solver.h b/src/math/euclid/euclidean_solver.h index 98a202e5e..74d0d7fa4 100644 --- a/src/math/euclid/euclidean_solver.h +++ b/src/math/euclid/euclidean_solver.h @@ -19,8 +19,8 @@ Revision History: #ifndef EUCLIDEAN_SOLVER_H_ #define EUCLIDEAN_SOLVER_H_ -#include"mpq.h" -#include"vector.h" +#include "util/mpq.h" +#include "util/vector.h" class euclidean_solver { struct imp; diff --git a/src/math/grobner/grobner.cpp b/src/math/grobner/grobner.cpp index baa16b405..3295c4eae 100644 --- a/src/math/grobner/grobner.cpp +++ b/src/math/grobner/grobner.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"grobner.h" -#include"ast_pp.h" -#include"ref_util.h" +#include "math/grobner/grobner.h" +#include "ast/ast_pp.h" +#include "util/ref_util.h" // #define PROFILE_GB diff --git a/src/math/grobner/grobner.h b/src/math/grobner/grobner.h index 770f0a538..f024a33e4 100644 --- a/src/math/grobner/grobner.h +++ b/src/math/grobner/grobner.h @@ -19,12 +19,12 @@ Revision History: #ifndef GROBNER_H_ #define GROBNER_H_ -#include"ast.h" -#include"arith_decl_plugin.h" -#include"heap.h" -#include"obj_hashtable.h" -#include"region.h" -#include"dependency.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "util/heap.h" +#include "util/obj_hashtable.h" +#include "util/region.h" +#include "util/dependency.h" struct grobner_stats { diff --git a/src/math/hilbert/heap_trie.h b/src/math/hilbert/heap_trie.h index e288bb076..ace5381b8 100644 --- a/src/math/hilbert/heap_trie.h +++ b/src/math/hilbert/heap_trie.h @@ -37,11 +37,11 @@ Notes: #ifndef HEAP_TRIE_H_ #define HEAP_TRIE_H_ -#include "map.h" -#include "vector.h" -#include "buffer.h" -#include "statistics.h" -#include "small_object_allocator.h" +#include "util/map.h" +#include "util/vector.h" +#include "util/buffer.h" +#include "util/statistics.h" +#include "util/small_object_allocator.h" template diff --git a/src/math/hilbert/hilbert_basis.cpp b/src/math/hilbert/hilbert_basis.cpp index adac63e5c..9baa0beac 100644 --- a/src/math/hilbert/hilbert_basis.cpp +++ b/src/math/hilbert/hilbert_basis.cpp @@ -17,11 +17,11 @@ Revision History: --*/ -#include "hilbert_basis.h" -#include "heap.h" -#include "map.h" -#include "heap_trie.h" -#include "stopwatch.h" +#include "math/hilbert/hilbert_basis.h" +#include "util/heap.h" +#include "util/map.h" +#include "math/hilbert/heap_trie.h" +#include "util/stopwatch.h" typedef int_hashtable > int_table; diff --git a/src/math/hilbert/hilbert_basis.h b/src/math/hilbert/hilbert_basis.h index 2cfb4e36f..a0350492a 100644 --- a/src/math/hilbert/hilbert_basis.h +++ b/src/math/hilbert/hilbert_basis.h @@ -28,11 +28,11 @@ Revision History: #ifndef HILBERT_BASIS_H_ #define HILBERT_BASIS_H_ -#include "rational.h" -#include "lbool.h" -#include "statistics.h" -#include "checked_int64.h" -#include "rlimit.h" +#include "util/rational.h" +#include "util/lbool.h" +#include "util/statistics.h" +#include "util/checked_int64.h" +#include "util/rlimit.h" typedef vector rational_vector; diff --git a/src/math/interval/interval.h b/src/math/interval/interval.h index 4c0204604..bae644fac 100644 --- a/src/math/interval/interval.h +++ b/src/math/interval/interval.h @@ -19,9 +19,9 @@ Revision History: #ifndef INTERVAL_H_ #define INTERVAL_H_ -#include"mpq.h" -#include"ext_numeral.h" -#include"rlimit.h" +#include "util/mpq.h" +#include "util/ext_numeral.h" +#include "util/rlimit.h" /** \brief Default configuration for interval manager. diff --git a/src/math/interval/interval_def.h b/src/math/interval/interval_def.h index 43bf9f91a..e18d9edda 100644 --- a/src/math/interval/interval_def.h +++ b/src/math/interval/interval_def.h @@ -19,12 +19,12 @@ Revision History: #ifndef INTERVAL_DEF_H_ #define INTERVAL_DEF_H_ -#include"interval.h" -#include"debug.h" -#include"trace.h" -#include"scoped_numeral.h" -#include"cooperate.h" -#include"common_msgs.h" +#include "math/interval/interval.h" +#include "util/debug.h" +#include "util/trace.h" +#include "util/scoped_numeral.h" +#include "util/cooperate.h" +#include "util/common_msgs.h" #define DEFAULT_PI_PRECISION 2 diff --git a/src/math/interval/interval_mpq.cpp b/src/math/interval/interval_mpq.cpp index fa7cec853..7d3de6379 100644 --- a/src/math/interval/interval_mpq.cpp +++ b/src/math/interval/interval_mpq.cpp @@ -16,6 +16,6 @@ Author: Revision History: --*/ -#include"interval_def.h" +#include "math/interval/interval_def.h" template class interval_manager; diff --git a/src/math/polynomial/algebraic_numbers.cpp b/src/math/polynomial/algebraic_numbers.cpp index 986c17664..353a8c107 100644 --- a/src/math/polynomial/algebraic_numbers.cpp +++ b/src/math/polynomial/algebraic_numbers.cpp @@ -16,17 +16,17 @@ Author: Notes: --*/ -#include"algebraic_numbers.h" -#include"upolynomial.h" -#include"mpbq.h" -#include"basic_interval.h" -#include"cooperate.h" -#include"sexpr2upolynomial.h" -#include"scoped_ptr_vector.h" -#include"mpbqi.h" -#include"timeit.h" +#include "math/polynomial/algebraic_numbers.h" +#include "math/polynomial/upolynomial.h" +#include "util/mpbq.h" +#include "util/basic_interval.h" +#include "util/cooperate.h" +#include "math/polynomial/sexpr2upolynomial.h" +#include "util/scoped_ptr_vector.h" +#include "util/mpbqi.h" +#include "util/timeit.h" #include"algebraic_params.hpp" -#include"common_msgs.h" +#include "util/common_msgs.h" namespace algebraic_numbers { diff --git a/src/math/polynomial/algebraic_numbers.h b/src/math/polynomial/algebraic_numbers.h index e86be7752..3a8ee766b 100644 --- a/src/math/polynomial/algebraic_numbers.h +++ b/src/math/polynomial/algebraic_numbers.h @@ -19,16 +19,16 @@ Notes: #ifndef ALGEBRAIC_NUMBERS_H_ #define ALGEBRAIC_NUMBERS_H_ -#include"rational.h" -#include"mpq.h" -#include"polynomial.h" -#include"z3_exception.h" -#include"scoped_numeral.h" -#include"scoped_numeral_vector.h" -#include"tptr.h" -#include"statistics.h" -#include"params.h" -#include"rlimit.h" +#include "util/rational.h" +#include "util/mpq.h" +#include "math/polynomial/polynomial.h" +#include "util/z3_exception.h" +#include "util/scoped_numeral.h" +#include "util/scoped_numeral_vector.h" +#include "util/tptr.h" +#include "util/statistics.h" +#include "util/params.h" +#include "util/rlimit.h" class small_object_allocator; class mpbq_manager; diff --git a/src/math/polynomial/polynomial.cpp b/src/math/polynomial/polynomial.cpp index 1a4aa8304..80669648e 100644 --- a/src/math/polynomial/polynomial.cpp +++ b/src/math/polynomial/polynomial.cpp @@ -16,24 +16,24 @@ Author: Notes: --*/ -#include"polynomial.h" -#include"vector.h" -#include"chashtable.h" -#include"small_object_allocator.h" -#include"id_gen.h" -#include"buffer.h" -#include"scoped_ptr_vector.h" -#include"cooperate.h" -#include"upolynomial_factorization.h" -#include"polynomial_primes.h" -#include"permutation.h" -#include"algebraic_numbers.h" -#include"mpzzp.h" -#include"timeit.h" -#include"linear_eq_solver.h" -#include"scoped_numeral_buffer.h" -#include"ref_buffer.h" -#include"common_msgs.h" +#include "math/polynomial/polynomial.h" +#include "util/vector.h" +#include "util/chashtable.h" +#include "util/small_object_allocator.h" +#include "util/id_gen.h" +#include "util/buffer.h" +#include "util/scoped_ptr_vector.h" +#include "util/cooperate.h" +#include "math/polynomial/upolynomial_factorization.h" +#include "math/polynomial/polynomial_primes.h" +#include "util/permutation.h" +#include "math/polynomial/algebraic_numbers.h" +#include "util/mpzzp.h" +#include "util/timeit.h" +#include "math/polynomial/linear_eq_solver.h" +#include "util/scoped_numeral_buffer.h" +#include "util/ref_buffer.h" +#include "util/common_msgs.h" namespace polynomial { diff --git a/src/math/polynomial/polynomial.h b/src/math/polynomial/polynomial.h index cb1880495..138331ef3 100644 --- a/src/math/polynomial/polynomial.h +++ b/src/math/polynomial/polynomial.h @@ -19,16 +19,16 @@ Notes: #ifndef POLYNOMIAL_H_ #define POLYNOMIAL_H_ -#include"mpz.h" -#include"rational.h" -#include"obj_ref.h" -#include"ref_vector.h" -#include"z3_exception.h" -#include"scoped_numeral.h" -#include"scoped_numeral_vector.h" -#include"params.h" -#include"mpbqi.h" -#include"rlimit.h" +#include "util/mpz.h" +#include "util/rational.h" +#include "util/obj_ref.h" +#include "util/ref_vector.h" +#include "util/z3_exception.h" +#include "util/scoped_numeral.h" +#include "util/scoped_numeral_vector.h" +#include "util/params.h" +#include "util/mpbqi.h" +#include "util/rlimit.h" class small_object_allocator; diff --git a/src/math/polynomial/polynomial_cache.cpp b/src/math/polynomial/polynomial_cache.cpp index dee0e722d..9a021ce36 100644 --- a/src/math/polynomial/polynomial_cache.cpp +++ b/src/math/polynomial/polynomial_cache.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"polynomial_cache.h" -#include"chashtable.h" +#include "math/polynomial/polynomial_cache.h" +#include "util/chashtable.h" namespace polynomial { diff --git a/src/math/polynomial/polynomial_cache.h b/src/math/polynomial/polynomial_cache.h index 538a08b5c..4ebb05b04 100644 --- a/src/math/polynomial/polynomial_cache.h +++ b/src/math/polynomial/polynomial_cache.h @@ -19,7 +19,7 @@ Notes: #ifndef POLYNOMIAL_CACHE_H_ #define POLYNOMIAL_CACHE_H_ -#include"polynomial.h" +#include "math/polynomial/polynomial.h" namespace polynomial { diff --git a/src/math/polynomial/polynomial_var2value.h b/src/math/polynomial/polynomial_var2value.h index 7da2e5980..c4aa16dfa 100644 --- a/src/math/polynomial/polynomial_var2value.h +++ b/src/math/polynomial/polynomial_var2value.h @@ -19,8 +19,8 @@ Notes: #ifndef POLYNOMIAL_VAR2VALUE_H_ #define POLYNOMIAL_VAR2VALUE_H_ -#include"polynomial.h" -#include"scoped_numeral_vector.h" +#include "math/polynomial/polynomial.h" +#include "util/scoped_numeral_vector.h" namespace polynomial { diff --git a/src/math/polynomial/rpolynomial.cpp b/src/math/polynomial/rpolynomial.cpp index 03cfac8c8..5e7a829f6 100644 --- a/src/math/polynomial/rpolynomial.cpp +++ b/src/math/polynomial/rpolynomial.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"rpolynomial.h" -#include"tptr.h" -#include"buffer.h" +#include "math/polynomial/rpolynomial.h" +#include "util/tptr.h" +#include "util/buffer.h" namespace rpolynomial { diff --git a/src/math/polynomial/rpolynomial.h b/src/math/polynomial/rpolynomial.h index b84dcca95..f2ba78894 100644 --- a/src/math/polynomial/rpolynomial.h +++ b/src/math/polynomial/rpolynomial.h @@ -19,12 +19,12 @@ Notes: #ifndef RPOLYNOMIAL_H_ #define RPOLYNOMIAL_H_ -#include"mpz.h" -#include"rational.h" -#include"obj_ref.h" -#include"ref_vector.h" -#include"z3_exception.h" -#include"polynomial.h" +#include "util/mpz.h" +#include "util/rational.h" +#include "util/obj_ref.h" +#include "util/ref_vector.h" +#include "util/z3_exception.h" +#include "math/polynomial/polynomial.h" namespace rpolynomial { diff --git a/src/math/polynomial/sexpr2upolynomial.cpp b/src/math/polynomial/sexpr2upolynomial.cpp index ea3de77da..790fefeb8 100644 --- a/src/math/polynomial/sexpr2upolynomial.cpp +++ b/src/math/polynomial/sexpr2upolynomial.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"sexpr2upolynomial.h" -#include"sexpr.h" +#include "math/polynomial/sexpr2upolynomial.h" +#include "util/sexpr.h" sexpr2upolynomial_exception::sexpr2upolynomial_exception(char const * msg, sexpr const * s): cmd_exception(msg, s->get_line(), s->get_pos()) { diff --git a/src/math/polynomial/sexpr2upolynomial.h b/src/math/polynomial/sexpr2upolynomial.h index 64488b0f4..0b849ad36 100644 --- a/src/math/polynomial/sexpr2upolynomial.h +++ b/src/math/polynomial/sexpr2upolynomial.h @@ -19,8 +19,8 @@ Notes: #ifndef SEXPR2UPOLYNOMIAL_H_ #define SEXPR2UPOLYNOMIAL_H_ -#include"upolynomial.h" -#include"cmd_context_types.h" +#include "math/polynomial/upolynomial.h" +#include "util/cmd_context_types.h" class sexpr; class sexpr2upolynomial_exception : public cmd_exception { diff --git a/src/math/polynomial/upolynomial.cpp b/src/math/polynomial/upolynomial.cpp index aa26ccf4c..fe890b040 100644 --- a/src/math/polynomial/upolynomial.cpp +++ b/src/math/polynomial/upolynomial.cpp @@ -21,12 +21,12 @@ Author: Notes: --*/ -#include"upolynomial.h" -#include"upolynomial_factorization.h" -#include"polynomial_primes.h" -#include"buffer.h" -#include"cooperate.h" -#include"common_msgs.h" +#include "math/polynomial/upolynomial.h" +#include "math/polynomial/upolynomial_factorization.h" +#include "math/polynomial/polynomial_primes.h" +#include "util/buffer.h" +#include "util/cooperate.h" +#include "util/common_msgs.h" namespace upolynomial { diff --git a/src/math/polynomial/upolynomial.h b/src/math/polynomial/upolynomial.h index 789759dc6..e0df0dd31 100644 --- a/src/math/polynomial/upolynomial.h +++ b/src/math/polynomial/upolynomial.h @@ -24,12 +24,12 @@ Notes: #ifndef UPOLYNOMIAL_H_ #define UPOLYNOMIAL_H_ -#include"mpzzp.h" -#include"rational.h" -#include"polynomial.h" -#include"z3_exception.h" -#include"mpbq.h" -#include"rlimit.h" +#include "util/mpzzp.h" +#include "util/rational.h" +#include "math/polynomial/polynomial.h" +#include "util/z3_exception.h" +#include "util/mpbq.h" +#include "util/rlimit.h" #define FACTOR_VERBOSE_LVL 1000 namespace upolynomial { diff --git a/src/math/polynomial/upolynomial_factorization.cpp b/src/math/polynomial/upolynomial_factorization.cpp index 5a7aefa18..11a37648a 100644 --- a/src/math/polynomial/upolynomial_factorization.cpp +++ b/src/math/polynomial/upolynomial_factorization.cpp @@ -22,10 +22,10 @@ Notes: [3] Henri Cohen. A Course in Computational Algebraic Number Theory. Springer Verlag, 1993. --*/ -#include"trace.h" -#include"util.h" -#include"upolynomial_factorization_int.h" -#include"prime_generator.h" +#include "util/trace.h" +#include "util/util.h" +#include "math/polynomial/upolynomial_factorization_int.h" +#include "util/prime_generator.h" using namespace std; diff --git a/src/math/polynomial/upolynomial_factorization.h b/src/math/polynomial/upolynomial_factorization.h index ba184d613..6fe0f2be6 100644 --- a/src/math/polynomial/upolynomial_factorization.h +++ b/src/math/polynomial/upolynomial_factorization.h @@ -25,10 +25,10 @@ Notes: #ifndef UPOLYNOMIAL_FACTORIZATION_H_ #define UPOLYNOMIAL_FACTORIZATION_H_ -#include"upolynomial.h" -#include"polynomial.h" -#include"bit_vector.h" -#include"z3_exception.h" +#include "math/polynomial/upolynomial.h" +#include "math/polynomial/polynomial.h" +#include "util/bit_vector.h" +#include "util/z3_exception.h" namespace upolynomial { typedef manager::scoped_numeral scoped_numeral; diff --git a/src/math/polynomial/upolynomial_factorization_int.h b/src/math/polynomial/upolynomial_factorization_int.h index 86fe52b03..640c5ad5c 100644 --- a/src/math/polynomial/upolynomial_factorization_int.h +++ b/src/math/polynomial/upolynomial_factorization_int.h @@ -26,7 +26,7 @@ Notes: #ifndef UPOLYNOMIAL_FACTORIZATION_INT_H_ #define UPOLYNOMIAL_FACTORIZATION_INT_H_ -#include"upolynomial_factorization.h" +#include "math/polynomial/upolynomial_factorization.h" namespace upolynomial { // copy p from some manager to zp_p in Z_p[x] diff --git a/src/math/realclosure/mpz_matrix.cpp b/src/math/realclosure/mpz_matrix.cpp index 799a5817e..62a328b8d 100644 --- a/src/math/realclosure/mpz_matrix.cpp +++ b/src/math/realclosure/mpz_matrix.cpp @@ -28,8 +28,8 @@ Author: Notes: --*/ -#include"mpz_matrix.h" -#include"buffer.h" +#include "math/realclosure/mpz_matrix.h" +#include "util/buffer.h" mpz_matrix_manager::mpz_matrix_manager(unsynch_mpz_manager & nm, small_object_allocator & a): m_nm(nm), diff --git a/src/math/realclosure/mpz_matrix.h b/src/math/realclosure/mpz_matrix.h index bd9c1bd45..f5d7358da 100644 --- a/src/math/realclosure/mpz_matrix.h +++ b/src/math/realclosure/mpz_matrix.h @@ -31,7 +31,7 @@ Notes: #ifndef MPZ_MATRIX_H_ #define MPZ_MATRIX_H_ -#include"mpz.h" +#include "util/mpz.h" /** \brief A mxn matrix. diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 0268470f7..93cfc98f4 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -19,17 +19,17 @@ Author: Notes: --*/ -#include"realclosure.h" +#include "math/realclosure/realclosure.h" #include"rcf_params.hpp" -#include"array.h" -#include"mpbq.h" -#include"mpz_matrix.h" -#include"interval_def.h" -#include"obj_ref.h" -#include"ref_vector.h" -#include"ref_buffer.h" -#include"cooperate.h" -#include"common_msgs.h" +#include "util/array.h" +#include "util/mpbq.h" +#include "math/realclosure/mpz_matrix.h" +#include "math/interval/interval_def.h" +#include "util/obj_ref.h" +#include "util/ref_vector.h" +#include "util/ref_buffer.h" +#include "util/cooperate.h" +#include "util/common_msgs.h" #ifndef REALCLOSURE_INI_BUFFER_SIZE #define REALCLOSURE_INI_BUFFER_SIZE 32 diff --git a/src/math/realclosure/realclosure.h b/src/math/realclosure/realclosure.h index 10d35f58d..c18f626a3 100644 --- a/src/math/realclosure/realclosure.h +++ b/src/math/realclosure/realclosure.h @@ -22,13 +22,13 @@ Notes: #ifndef REALCLOSURE_H_ #define REALCLOSURE_H_ -#include"mpq.h" -#include"params.h" -#include"scoped_numeral.h" -#include"scoped_numeral_vector.h" -#include"interval.h" -#include"z3_exception.h" -#include"rlimit.h" +#include "util/mpq.h" +#include "util/params.h" +#include "util/scoped_numeral.h" +#include "util/scoped_numeral_vector.h" +#include "math/interval/interval.h" +#include "util/z3_exception.h" +#include "util/rlimit.h" namespace realclosure { class num; diff --git a/src/math/simplex/model_based_opt.h b/src/math/simplex/model_based_opt.h index eb0bc2570..54360d0ac 100644 --- a/src/math/simplex/model_based_opt.h +++ b/src/math/simplex/model_based_opt.h @@ -21,9 +21,9 @@ Revision History: #ifndef __MODEL_BASED_OPT_H__ #define __MODEL_BASED_OPT_H__ -#include "util.h" -#include "rational.h" -#include"inf_eps_rational.h" +#include "util/util.h" +#include "util/rational.h" +#include "util/inf_eps_rational.h" namespace opt { diff --git a/src/math/simplex/network_flow.h b/src/math/simplex/network_flow.h index 13aff5089..d4c7df77f 100644 --- a/src/math/simplex/network_flow.h +++ b/src/math/simplex/network_flow.h @@ -28,9 +28,9 @@ Notes: #ifndef NETWORK_FLOW_H_ #define NETWORK_FLOW_H_ -#include"inf_rational.h" -#include"diff_logic.h" -#include"spanning_tree.h" +#include "util/inf_rational.h" +#include "smt/diff_logic.h" +#include "smt/spanning_tree.h" namespace smt { diff --git a/src/math/simplex/network_flow_def.h b/src/math/simplex/network_flow_def.h index a4a6246ce..4a7d00a23 100644 --- a/src/math/simplex/network_flow_def.h +++ b/src/math/simplex/network_flow_def.h @@ -20,9 +20,9 @@ Notes: #ifndef NETWORK_FLOW_DEF_H_ #define NETWORK_FLOW_DEF_H_ -#include"network_flow.h" -#include"uint_set.h" -#include"spanning_tree_def.h" +#include "math/simplex/network_flow.h" +#include "util/uint_set.h" +#include "smt/spanning_tree_def.h" namespace smt { diff --git a/src/math/simplex/simplex.cpp b/src/math/simplex/simplex.cpp index 494c0b6bb..42bb46eef 100644 --- a/src/math/simplex/simplex.cpp +++ b/src/math/simplex/simplex.cpp @@ -17,9 +17,9 @@ Notes: --*/ -#include"simplex.h" -#include"sparse_matrix_def.h" -#include"simplex_def.h" +#include "math/simplex/simplex.h" +#include "math/simplex/sparse_matrix_def.h" +#include "math/simplex/simplex_def.h" namespace simplex { template class simplex; template class simplex; diff --git a/src/math/simplex/simplex.h b/src/math/simplex/simplex.h index 277179507..5c412e356 100644 --- a/src/math/simplex/simplex.h +++ b/src/math/simplex/simplex.h @@ -32,11 +32,11 @@ Notes: #ifndef SIMPLEX_H_ #define SIMPLEX_H_ -#include "sparse_matrix.h" -#include "mpq_inf.h" -#include "heap.h" -#include "lbool.h" -#include "uint_set.h" +#include "math/simplex/sparse_matrix.h" +#include "util/mpq_inf.h" +#include "util/heap.h" +#include "util/lbool.h" +#include "util/uint_set.h" namespace simplex { diff --git a/src/math/simplex/sparse_matrix.h b/src/math/simplex/sparse_matrix.h index 803d27fde..dc4ce8695 100644 --- a/src/math/simplex/sparse_matrix.h +++ b/src/math/simplex/sparse_matrix.h @@ -19,8 +19,8 @@ Notes: #ifndef SPARSE_MATRIX_H_ #define SPARSE_MATRIX_H_ -#include "mpq_inf.h" -#include "statistics.h" +#include "util/mpq_inf.h" +#include "util/statistics.h" namespace simplex { diff --git a/src/math/simplex/sparse_matrix_def.h b/src/math/simplex/sparse_matrix_def.h index b050e45e1..be18a8702 100644 --- a/src/math/simplex/sparse_matrix_def.h +++ b/src/math/simplex/sparse_matrix_def.h @@ -21,8 +21,8 @@ Notes: #ifndef SPARSE_MATRIX_DEF_H_ #define SPARSE_MATRIX_DEF_H_ -#include "sparse_matrix.h" -#include "uint_set.h" +#include "math/simplex/sparse_matrix.h" +#include "util/uint_set.h" namespace simplex { diff --git a/src/math/subpaving/subpaving.cpp b/src/math/subpaving/subpaving.cpp index 8aa394abe..96fc5b6d7 100644 --- a/src/math/subpaving/subpaving.cpp +++ b/src/math/subpaving/subpaving.cpp @@ -22,13 +22,13 @@ Author: Revision History: --*/ -#include"subpaving.h" -#include"subpaving_types.h" -#include"subpaving_mpq.h" -#include"subpaving_mpf.h" -#include"subpaving_hwf.h" -#include"subpaving_mpff.h" -#include"subpaving_mpfx.h" +#include "math/subpaving/subpaving.h" +#include "math/subpaving/subpaving_types.h" +#include "math/subpaving/subpaving_mpq.h" +#include "math/subpaving/subpaving_mpf.h" +#include "math/subpaving/subpaving_hwf.h" +#include "math/subpaving/subpaving_mpff.h" +#include "math/subpaving/subpaving_mpfx.h" namespace subpaving { diff --git a/src/math/subpaving/subpaving.h b/src/math/subpaving/subpaving.h index c6daca5cc..2c2c9978f 100644 --- a/src/math/subpaving/subpaving.h +++ b/src/math/subpaving/subpaving.h @@ -25,10 +25,10 @@ Revision History: #ifndef SUBPAVING_H_ #define SUBPAVING_H_ -#include"mpq.h" -#include"subpaving_types.h" -#include"params.h" -#include"statistics.h" +#include "util/mpq.h" +#include "math/subpaving/subpaving_types.h" +#include "util/params.h" +#include "util/statistics.h" template class f2n; class mpf_manager; diff --git a/src/math/subpaving/subpaving_hwf.cpp b/src/math/subpaving/subpaving_hwf.cpp index 142db72f6..7279a6273 100644 --- a/src/math/subpaving/subpaving_hwf.cpp +++ b/src/math/subpaving/subpaving_hwf.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"subpaving_hwf.h" -#include"subpaving_t_def.h" +#include "math/subpaving/subpaving_hwf.h" +#include "math/subpaving/subpaving_t_def.h" // force template instantiation template class subpaving::context_t; diff --git a/src/math/subpaving/subpaving_hwf.h b/src/math/subpaving/subpaving_hwf.h index f57035b01..52594e050 100644 --- a/src/math/subpaving/subpaving_hwf.h +++ b/src/math/subpaving/subpaving_hwf.h @@ -19,9 +19,9 @@ Revision History: #ifndef SUBPAVING_HWF_H_ #define SUBPAVING_HWF_H_ -#include"subpaving_t.h" -#include"f2n.h" -#include"hwf.h" +#include "math/subpaving/subpaving_t.h" +#include "util/f2n.h" +#include "util/hwf.h" namespace subpaving { diff --git a/src/math/subpaving/subpaving_mpf.cpp b/src/math/subpaving/subpaving_mpf.cpp index 96ada040b..ef8b5903c 100644 --- a/src/math/subpaving/subpaving_mpf.cpp +++ b/src/math/subpaving/subpaving_mpf.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"subpaving_mpf.h" -#include"subpaving_t_def.h" +#include "math/subpaving/subpaving_mpf.h" +#include "math/subpaving/subpaving_t_def.h" // force template instantiation template class subpaving::context_t; diff --git a/src/math/subpaving/subpaving_mpf.h b/src/math/subpaving/subpaving_mpf.h index 16e4b38cc..8e0d4cfc7 100644 --- a/src/math/subpaving/subpaving_mpf.h +++ b/src/math/subpaving/subpaving_mpf.h @@ -19,9 +19,9 @@ Revision History: #ifndef SUBPAVING_MPF_H_ #define SUBPAVING_MPF_H_ -#include"subpaving_t.h" -#include"mpf.h" -#include"f2n.h" +#include "math/subpaving/subpaving_t.h" +#include "util/mpf.h" +#include "util/f2n.h" namespace subpaving { diff --git a/src/math/subpaving/subpaving_mpff.cpp b/src/math/subpaving/subpaving_mpff.cpp index f5be655ba..18dcd4e6e 100644 --- a/src/math/subpaving/subpaving_mpff.cpp +++ b/src/math/subpaving/subpaving_mpff.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"subpaving_mpff.h" -#include"subpaving_t_def.h" +#include "math/subpaving/subpaving_mpff.h" +#include "math/subpaving/subpaving_t_def.h" // force template instantiation template class subpaving::context_t; diff --git a/src/math/subpaving/subpaving_mpff.h b/src/math/subpaving/subpaving_mpff.h index c0ddb019d..8e5c7f3ea 100644 --- a/src/math/subpaving/subpaving_mpff.h +++ b/src/math/subpaving/subpaving_mpff.h @@ -19,8 +19,8 @@ Revision History: #ifndef SUBPAVING_MPFF_H_ #define SUBPAVING_MPFF_H_ -#include"subpaving_t.h" -#include"mpff.h" +#include "math/subpaving/subpaving_t.h" +#include "util/mpff.h" namespace subpaving { diff --git a/src/math/subpaving/subpaving_mpfx.cpp b/src/math/subpaving/subpaving_mpfx.cpp index b8a1e048f..23902dce3 100644 --- a/src/math/subpaving/subpaving_mpfx.cpp +++ b/src/math/subpaving/subpaving_mpfx.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"subpaving_mpfx.h" -#include"subpaving_t_def.h" +#include "math/subpaving/subpaving_mpfx.h" +#include "math/subpaving/subpaving_t_def.h" // force template instantiation template class subpaving::context_t; diff --git a/src/math/subpaving/subpaving_mpfx.h b/src/math/subpaving/subpaving_mpfx.h index 6213df1e5..5802b1abf 100644 --- a/src/math/subpaving/subpaving_mpfx.h +++ b/src/math/subpaving/subpaving_mpfx.h @@ -19,8 +19,8 @@ Revision History: #ifndef SUBPAVING_MPFX_H_ #define SUBPAVING_MPFX_H_ -#include"subpaving_t.h" -#include"mpfx.h" +#include "math/subpaving/subpaving_t.h" +#include "util/mpfx.h" namespace subpaving { diff --git a/src/math/subpaving/subpaving_mpq.cpp b/src/math/subpaving/subpaving_mpq.cpp index b7b76a5e3..77b1405a7 100644 --- a/src/math/subpaving/subpaving_mpq.cpp +++ b/src/math/subpaving/subpaving_mpq.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"subpaving_mpq.h" -#include"subpaving_t_def.h" +#include "math/subpaving/subpaving_mpq.h" +#include "math/subpaving/subpaving_t_def.h" // force template instantiation template class subpaving::context_t; diff --git a/src/math/subpaving/subpaving_mpq.h b/src/math/subpaving/subpaving_mpq.h index 04bcd6059..b08eb9ccd 100644 --- a/src/math/subpaving/subpaving_mpq.h +++ b/src/math/subpaving/subpaving_mpq.h @@ -19,8 +19,8 @@ Revision History: #ifndef SUBPAVING_MPQ_H_ #define SUBPAVING_MPQ_H_ -#include"subpaving_t.h" -#include"mpq.h" +#include "math/subpaving/subpaving_t.h" +#include "util/mpq.h" namespace subpaving { diff --git a/src/math/subpaving/subpaving_t.h b/src/math/subpaving/subpaving_t.h index ccef1a318..a4bc02ff6 100644 --- a/src/math/subpaving/subpaving_t.h +++ b/src/math/subpaving/subpaving_t.h @@ -20,18 +20,18 @@ Revision History: #define SUBPAVING_T_H_ #include -#include"tptr.h" -#include"small_object_allocator.h" -#include"chashtable.h" -#include"parray.h" -#include"interval.h" -#include"scoped_numeral_vector.h" -#include"subpaving_types.h" -#include"params.h" -#include"statistics.h" -#include"lbool.h" -#include"id_gen.h" -#include"rlimit.h" +#include "util/tptr.h" +#include "util/small_object_allocator.h" +#include "util/chashtable.h" +#include "util/parray.h" +#include "math/interval/interval.h" +#include "util/scoped_numeral_vector.h" +#include "math/subpaving/subpaving_types.h" +#include "util/params.h" +#include "util/statistics.h" +#include "util/lbool.h" +#include "util/id_gen.h" +#include "util/rlimit.h" #ifdef _MSC_VER #pragma warning(disable : 4200) #pragma warning(disable : 4355) diff --git a/src/math/subpaving/subpaving_t_def.h b/src/math/subpaving/subpaving_t_def.h index 6ae7d97b1..108b6aac3 100644 --- a/src/math/subpaving/subpaving_t_def.h +++ b/src/math/subpaving/subpaving_t_def.h @@ -16,12 +16,12 @@ Author: Revision History: --*/ -#include"subpaving_t.h" -#include"interval_def.h" -#include"buffer.h" -#include"cooperate.h" -#include"z3_exception.h" -#include"common_msgs.h" +#include "math/subpaving/subpaving_t.h" +#include "math/interval/interval_def.h" +#include "util/buffer.h" +#include "util/cooperate.h" +#include "util/z3_exception.h" +#include "util/common_msgs.h" namespace subpaving { diff --git a/src/math/subpaving/tactic/expr2subpaving.cpp b/src/math/subpaving/tactic/expr2subpaving.cpp index 267a04b9a..b00c0007f 100644 --- a/src/math/subpaving/tactic/expr2subpaving.cpp +++ b/src/math/subpaving/tactic/expr2subpaving.cpp @@ -17,14 +17,14 @@ Author: Notes: --*/ -#include"expr2subpaving.h" -#include"expr2var.h" -#include"ref_util.h" -#include"z3_exception.h" -#include"cooperate.h" -#include"arith_decl_plugin.h" -#include"scoped_numeral_buffer.h" -#include"common_msgs.h" +#include "math/subpaving/tactic/expr2subpaving.h" +#include "ast/expr2var.h" +#include "util/ref_util.h" +#include "util/z3_exception.h" +#include "util/cooperate.h" +#include "ast/arith_decl_plugin.h" +#include "util/scoped_numeral_buffer.h" +#include "util/common_msgs.h" struct expr2subpaving::imp { struct frame { diff --git a/src/math/subpaving/tactic/expr2subpaving.h b/src/math/subpaving/tactic/expr2subpaving.h index 8e6e69332..d95699759 100644 --- a/src/math/subpaving/tactic/expr2subpaving.h +++ b/src/math/subpaving/tactic/expr2subpaving.h @@ -20,8 +20,8 @@ Notes: #ifndef EXPR2SUBPAVING_H_ #define EXPR2SUBPAVING_H_ -#include"ast.h" -#include"subpaving.h" +#include "ast/ast.h" +#include "math/subpaving/subpaving.h" class expr2var; diff --git a/src/math/subpaving/tactic/subpaving_tactic.cpp b/src/math/subpaving/tactic/subpaving_tactic.cpp index 2d0199223..6a7bc11e8 100644 --- a/src/math/subpaving/tactic/subpaving_tactic.cpp +++ b/src/math/subpaving/tactic/subpaving_tactic.cpp @@ -16,16 +16,16 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"expr2subpaving.h" -#include"expr2var.h" -#include"arith_decl_plugin.h" -#include"ast_smt2_pp.h" -#include"hwf.h" -#include"mpff.h" -#include"mpfx.h" -#include"f2n.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "math/subpaving/tactic/expr2subpaving.h" +#include "ast/expr2var.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_smt2_pp.h" +#include "util/hwf.h" +#include "util/mpff.h" +#include "util/mpfx.h" +#include "util/f2n.h" class subpaving_tactic : public tactic { diff --git a/src/math/subpaving/tactic/subpaving_tactic.h b/src/math/subpaving/tactic/subpaving_tactic.h index 30a72b888..208f762de 100644 --- a/src/math/subpaving/tactic/subpaving_tactic.h +++ b/src/math/subpaving/tactic/subpaving_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef SUBPAVING_TACTIC_H_ #define SUBPAVING_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/model/func_interp.cpp b/src/model/func_interp.cpp index 01e160eb0..2ead63e0a 100644 --- a/src/model/func_interp.cpp +++ b/src/model/func_interp.cpp @@ -15,11 +15,11 @@ Author: Revision History: --*/ -#include"func_interp.h" -#include"var_subst.h" -#include"obj_hashtable.h" -#include"ast_pp.h" -#include"ast_smt2_pp.h" +#include "model/func_interp.h" +#include "ast/rewriter/var_subst.h" +#include "util/obj_hashtable.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" func_entry::func_entry(ast_manager & m, unsigned arity, expr * const * args, expr * result): m_args_are_values(true), diff --git a/src/model/func_interp.h b/src/model/func_interp.h index d0d61546e..47eb0e82c 100644 --- a/src/model/func_interp.h +++ b/src/model/func_interp.h @@ -30,8 +30,8 @@ Revision History: #ifndef FUNC_INTERP_H_ #define FUNC_INTERP_H_ -#include"ast.h" -#include"ast_translation.h" +#include "ast/ast.h" +#include "ast/ast_translation.h" class func_interp; diff --git a/src/model/model.cpp b/src/model/model.cpp index 951c7f744..7ac1300de 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -16,14 +16,14 @@ Author: Revision History: --*/ -#include"model.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"var_subst.h" -#include"array_decl_plugin.h" -#include"well_sorted.h" -#include"used_symbols.h" -#include"model_evaluator.h" +#include "model/model.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/rewriter/var_subst.h" +#include "ast/array_decl_plugin.h" +#include "ast/well_sorted.h" +#include "ast/used_symbols.h" +#include "model/model_evaluator.h" model::model(ast_manager & m): model_core(m) { diff --git a/src/model/model.h b/src/model/model.h index 338b6ad74..f6de8ce0e 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -19,9 +19,9 @@ Revision History: #ifndef MODEL_H_ #define MODEL_H_ -#include"model_core.h" -#include"ref.h" -#include"ast_translation.h" +#include "model/model_core.h" +#include "util/ref.h" +#include "ast/ast_translation.h" class model : public model_core { protected: diff --git a/src/model/model2expr.cpp b/src/model/model2expr.cpp index 05aea6ee7..990f9df0f 100644 --- a/src/model/model2expr.cpp +++ b/src/model/model2expr.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include "model2expr.h" -#include "for_each_ast.h" -#include "bool_rewriter.h" -#include "var_subst.h" +#include "model/model2expr.h" +#include "ast/for_each_ast.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/var_subst.h" struct for_each_symbol_proc { symbol_set& m_symbols; diff --git a/src/model/model2expr.h b/src/model/model2expr.h index 272ba20b6..d55e31bba 100644 --- a/src/model/model2expr.h +++ b/src/model/model2expr.h @@ -19,7 +19,7 @@ Revision History: #ifndef MODEL2EXPR_H_ #define MODEL2EXPR_H_ -#include"model.h" +#include "model/model.h" void model2expr(model& m, expr_ref& result); diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 503abac2f..9da1e76f9 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"model_core.h" +#include "model/model_core.h" model_core::~model_core() { decl2expr::iterator it1 = m_interp.begin(); diff --git a/src/model/model_core.h b/src/model/model_core.h index c42451c5a..ec128c796 100644 --- a/src/model/model_core.h +++ b/src/model/model_core.h @@ -19,9 +19,9 @@ Revision History: #ifndef MODEL_CORE_H_ #define MODEL_CORE_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"func_interp.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "model/func_interp.h" class model_core { protected: diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp index 805ed8e5d..5020fb98b 100644 --- a/src/model/model_evaluator.cpp +++ b/src/model/model_evaluator.cpp @@ -16,23 +16,23 @@ Author: Revision History: --*/ -#include"model.h" +#include "model/model.h" #include"model_evaluator_params.hpp" -#include"rewriter_types.h" -#include"model_evaluator.h" -#include"bool_rewriter.h" -#include"arith_rewriter.h" -#include"bv_rewriter.h" -#include"pb_rewriter.h" -#include"seq_rewriter.h" -#include"datatype_rewriter.h" -#include"array_rewriter.h" -#include"fpa_rewriter.h" -#include"rewriter_def.h" -#include"cooperate.h" -#include"ast_pp.h" -#include"ast_util.h" -#include"model_smt2_pp.h" +#include "ast/rewriter/rewriter_types.h" +#include "model/model_evaluator.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/rewriter/bv_rewriter.h" +#include "ast/rewriter/pb_rewriter.h" +#include "ast/rewriter/seq_rewriter.h" +#include "ast/rewriter/datatype_rewriter.h" +#include "ast/rewriter/array_rewriter.h" +#include "ast/rewriter/fpa_rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/cooperate.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "model/model_smt2_pp.h" struct evaluator_cfg : public default_rewriter_cfg { diff --git a/src/model/model_evaluator.h b/src/model/model_evaluator.h index ba55e96ba..2497ec927 100644 --- a/src/model/model_evaluator.h +++ b/src/model/model_evaluator.h @@ -19,9 +19,9 @@ Revision History: #ifndef MODEL_EVALUATOR_H_ #define MODEL_EVALUATOR_H_ -#include"ast.h" -#include"rewriter_types.h" -#include"params.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter_types.h" +#include "util/params.h" class model; typedef rewriter_exception model_evaluator_exception; diff --git a/src/model/model_implicant.cpp b/src/model/model_implicant.cpp index 0d37a04df..6abdacfba 100644 --- a/src/model/model_implicant.cpp +++ b/src/model/model_implicant.cpp @@ -22,23 +22,23 @@ Notes: --*/ #include -#include "array_decl_plugin.h" -#include "ast_pp.h" -#include "bool_rewriter.h" -#include "for_each_expr.h" -#include "model.h" -#include "ref_vector.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "util.h" -#include "model_implicant.h" -#include "arith_decl_plugin.h" -#include "expr_replacer.h" -#include "model_smt2_pp.h" -#include "poly_rewriter.h" -#include "poly_rewriter_def.h" -#include "arith_rewriter.h" -#include "scoped_proof.h" +#include "ast/array_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/for_each_expr.h" +#include "model/model.h" +#include "util/ref_vector.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/util.h" +#include "model/model_implicant.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/expr_replacer.h" +#include "model/model_smt2_pp.h" +#include "ast/rewriter/poly_rewriter.h" +#include "ast/rewriter/poly_rewriter_def.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/scoped_proof.h" diff --git a/src/model/model_implicant.h b/src/model/model_implicant.h index 91bfe9894..c34a4b810 100644 --- a/src/model/model_implicant.h +++ b/src/model/model_implicant.h @@ -20,14 +20,14 @@ Revision History: #ifndef MODEL_IMPLICANT_H_ #define MODEL_IMPLICANT_H_ -#include "ast.h" -#include "ast_pp.h" -#include "obj_hashtable.h" -#include "ref_vector.h" -#include "trace.h" -#include "vector.h" -#include "arith_decl_plugin.h" -#include "array_decl_plugin.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "util/obj_hashtable.h" +#include "util/ref_vector.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" class model; class model_core; diff --git a/src/model/model_pp.cpp b/src/model/model_pp.cpp index b968c7184..2f9b114bb 100644 --- a/src/model/model_pp.cpp +++ b/src/model/model_pp.cpp @@ -17,12 +17,12 @@ Revision History: --*/ -#include"model_pp.h" -#include"model_core.h" -#include"ast_pp.h" -#include"ast_smt2_pp.h" -#include"used_symbols.h" -#include"pp.h" +#include "model/model_pp.h" +#include "model/model_core.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/used_symbols.h" +#include "ast/pp.h" static void display_uninterp_sorts(std::ostream & out, model_core const & md) { ast_manager & m = md.get_manager(); diff --git a/src/model/model_smt2_pp.cpp b/src/model/model_smt2_pp.cpp index 929668638..152cbc8d3 100644 --- a/src/model/model_smt2_pp.cpp +++ b/src/model/model_smt2_pp.cpp @@ -18,10 +18,10 @@ Revision History: --*/ #include -#include"model_smt2_pp.h" -#include"ast_smt2_pp.h" -#include"func_decl_dependencies.h" -#include"pp.h" +#include "model/model_smt2_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/func_decl_dependencies.h" +#include "ast/pp.h" using namespace format_ns; static void pp_indent(std::ostream & out, unsigned indent) { diff --git a/src/model/model_smt2_pp.h b/src/model/model_smt2_pp.h index c123bfb24..c43e26ca6 100644 --- a/src/model/model_smt2_pp.h +++ b/src/model/model_smt2_pp.h @@ -20,8 +20,8 @@ Revision History: #ifndef MODEL_SMT2_PP_H_ #define MODEL_SMT2_PP_H_ -#include"ast_printer.h" -#include"model_core.h" +#include "ast/ast_printer.h" +#include "model/model_core.h" void model_smt2_pp(std::ostream & out, ast_printer_context & ctx, model_core const & m, unsigned indent); void model_smt2_pp(std::ostream & out, ast_manager & m, model_core const & md, unsigned indent); diff --git a/src/model/model_v2_pp.cpp b/src/model/model_v2_pp.cpp index 4600ccc9e..dae9b2104 100644 --- a/src/model/model_v2_pp.cpp +++ b/src/model/model_v2_pp.cpp @@ -15,9 +15,9 @@ Author: Revision History: --*/ -#include"model_v2_pp.h" -#include"model_core.h" -#include"ast_pp.h" +#include "model/model_v2_pp.h" +#include "model/model_core.h" +#include "ast/ast_pp.h" static void display_function(std::ostream & out, model_core const & md, func_decl * f, bool partial) { ast_manager & m = md.get_manager(); diff --git a/src/muz/base/bind_variables.cpp b/src/muz/base/bind_variables.cpp index 0cc50625e..2ba7d1473 100644 --- a/src/muz/base/bind_variables.cpp +++ b/src/muz/base/bind_variables.cpp @@ -18,7 +18,7 @@ Notes: --*/ -#include "bind_variables.h" +#include "muz/base/bind_variables.h" bind_variables::bind_variables(ast_manager & m): m(m), diff --git a/src/muz/base/bind_variables.h b/src/muz/base/bind_variables.h index 18af319f8..693010132 100644 --- a/src/muz/base/bind_variables.h +++ b/src/muz/base/bind_variables.h @@ -21,7 +21,7 @@ Notes: #ifndef BIND_VARIABLES_H_ #define BIND_VARIABLES_H_ -#include"ast.h" +#include "ast/ast.h" class bind_variables { typedef obj_map var2bound; diff --git a/src/muz/base/dl_boogie_proof.cpp b/src/muz/base/dl_boogie_proof.cpp index 75579323c..ec999c05e 100644 --- a/src/muz/base/dl_boogie_proof.cpp +++ b/src/muz/base/dl_boogie_proof.cpp @@ -51,11 +51,11 @@ Example from Boogie: ") */ -#include "dl_boogie_proof.h" -#include "model_pp.h" -#include "proof_utils.h" -#include "ast_pp.h" -#include "ast_util.h" +#include "muz/base/dl_boogie_proof.h" +#include "model/model_pp.h" +#include "muz/base/proof_utils.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" namespace datalog { diff --git a/src/muz/base/dl_boogie_proof.h b/src/muz/base/dl_boogie_proof.h index 0f829dbdf..f335159b6 100644 --- a/src/muz/base/dl_boogie_proof.h +++ b/src/muz/base/dl_boogie_proof.h @@ -48,8 +48,8 @@ define-fun) when Boogie supports this. */ -#include "ast.h" -#include "model.h" +#include "ast/ast.h" +#include "model/model.h" namespace datalog { class boogie_proof { diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 2ca74a73b..28a456b22 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -19,16 +19,16 @@ Revision History: #include #include -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"dl_context.h" -#include"for_each_expr.h" -#include"ast_smt_pp.h" -#include"ast_smt2_pp.h" -#include"datatype_decl_plugin.h" -#include"scoped_proof.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "muz/base/dl_context.h" +#include "ast/for_each_expr.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/scoped_proof.h" #include"fixedpoint_params.hpp" -#include"ast_pp_util.h" +#include "ast/ast_pp_util.h" namespace datalog { diff --git a/src/muz/base/dl_context.h b/src/muz/base/dl_context.h index ba841c84f..0e1d47609 100644 --- a/src/muz/base/dl_context.h +++ b/src/muz/base/dl_context.h @@ -23,26 +23,26 @@ Revision History: #undef min #undef max #endif -#include"arith_decl_plugin.h" -#include"map.h" -#include"th_rewriter.h" -#include"str_hashtable.h" -#include"var_subst.h" -#include"dl_costs.h" -#include"dl_decl_plugin.h" -#include"dl_rule_set.h" -#include"lbool.h" -#include"statistics.h" -#include"params.h" -#include"trail.h" -#include"model_converter.h" -#include"model2expr.h" -#include"smt_params.h" -#include"dl_rule_transformer.h" -#include"expr_functors.h" -#include"dl_engine_base.h" -#include"bind_variables.h" -#include"rule_properties.h" +#include "ast/arith_decl_plugin.h" +#include "util/map.h" +#include "ast/rewriter/th_rewriter.h" +#include "util/str_hashtable.h" +#include "ast/rewriter/var_subst.h" +#include "muz/base/dl_costs.h" +#include "ast/dl_decl_plugin.h" +#include "muz/base/dl_rule_set.h" +#include "util/lbool.h" +#include "util/statistics.h" +#include "util/params.h" +#include "util/trail.h" +#include "tactic/model_converter.h" +#include "model/model2expr.h" +#include "smt/params/smt_params.h" +#include "muz/base/dl_rule_transformer.h" +#include "ast/expr_functors.h" +#include "muz/base/dl_engine_base.h" +#include "muz/base/bind_variables.h" +#include "muz/base/rule_properties.h" struct fixedpoint_params; diff --git a/src/muz/base/dl_costs.cpp b/src/muz/base/dl_costs.cpp index fe085d7f7..f97a4d451 100644 --- a/src/muz/base/dl_costs.cpp +++ b/src/muz/base/dl_costs.cpp @@ -17,11 +17,11 @@ Revision History: --*/ -#include "debug.h" -#include "stopwatch.h" -#include "dl_context.h" -#include "dl_rule.h" -#include "dl_costs.h" +#include "util/debug.h" +#include "util/stopwatch.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_costs.h" namespace datalog { diff --git a/src/muz/base/dl_costs.h b/src/muz/base/dl_costs.h index f3f97f6fd..fd5a99f15 100644 --- a/src/muz/base/dl_costs.h +++ b/src/muz/base/dl_costs.h @@ -22,7 +22,7 @@ Revision History: #include -#include "ast.h" +#include "ast/ast.h" class stopwatch; diff --git a/src/muz/base/dl_engine_base.h b/src/muz/base/dl_engine_base.h index 9878f3a9e..b2bb3dc63 100644 --- a/src/muz/base/dl_engine_base.h +++ b/src/muz/base/dl_engine_base.h @@ -19,7 +19,7 @@ Revision History: #ifndef DL_ENGINE_BASE_H_ #define DL_ENGINE_BASE_H_ -#include "model.h" +#include "model/model.h" namespace datalog { enum DL_ENGINE { diff --git a/src/muz/base/dl_rule.cpp b/src/muz/base/dl_rule.cpp index 27d62538e..4581c8aac 100644 --- a/src/muz/base/dl_rule.cpp +++ b/src/muz/base/dl_rule.cpp @@ -24,26 +24,26 @@ Revision History: #include #include -#include"ast_pp.h" -#include"dl_context.h" -#include"map.h" -#include"recurse_expr_def.h" -#include"dl_rule.h" -#include"qe.h" -#include"for_each_expr.h" -#include"used_vars.h" -#include"var_subst.h" -#include"rewriter_def.h" -#include"th_rewriter.h" -#include"ast_smt2_pp.h" -#include"used_symbols.h" -#include"quant_hoist.h" -#include"expr_replacer.h" -#include"bool_rewriter.h" -#include"expr_safe_replace.h" -#include"filter_model_converter.h" -#include"scoped_proof.h" -#include"datatype_decl_plugin.h" +#include "ast/ast_pp.h" +#include "muz/base/dl_context.h" +#include "util/map.h" +#include "ast/recurse_expr_def.h" +#include "muz/base/dl_rule.h" +#include "qe/qe.h" +#include "ast/for_each_expr.h" +#include "ast/used_vars.h" +#include "ast/rewriter/var_subst.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/ast_smt2_pp.h" +#include "ast/used_symbols.h" +#include "ast/rewriter/quant_hoist.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "tactic/filter_model_converter.h" +#include "ast/scoped_proof.h" +#include "ast/datatype_decl_plugin.h" namespace datalog { diff --git a/src/muz/base/dl_rule.h b/src/muz/base/dl_rule.h index 856814531..ea0e64e4f 100644 --- a/src/muz/base/dl_rule.h +++ b/src/muz/base/dl_rule.h @@ -20,19 +20,19 @@ Revision History: #ifndef DL_RULE_H_ #define DL_RULE_H_ -#include"ast.h" -#include"dl_costs.h" -#include"dl_util.h" -#include"used_vars.h" -#include"proof_converter.h" -#include"model_converter.h" -#include"ast_counter.h" -#include"rewriter.h" -#include"hnf.h" -#include"qe_lite.h" -#include"var_subst.h" -#include"datatype_decl_plugin.h" -#include"label_rewriter.h" +#include "ast/ast.h" +#include "muz/base/dl_costs.h" +#include "muz/base/dl_util.h" +#include "ast/used_vars.h" +#include "tactic/proof_converter.h" +#include "tactic/model_converter.h" +#include "ast/rewriter/ast_counter.h" +#include "ast/rewriter/rewriter.h" +#include "muz/base/hnf.h" +#include "qe/qe_lite.h" +#include "ast/rewriter/var_subst.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/rewriter/label_rewriter.h" namespace datalog { diff --git a/src/muz/base/dl_rule_set.cpp b/src/muz/base/dl_rule_set.cpp index 229db4d27..65c940091 100644 --- a/src/muz/base/dl_rule_set.cpp +++ b/src/muz/base/dl_rule_set.cpp @@ -19,9 +19,9 @@ Revision History: #include #include -#include"dl_context.h" -#include"dl_rule_set.h" -#include"ast_pp.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "ast/ast_pp.h" namespace datalog { diff --git a/src/muz/base/dl_rule_set.h b/src/muz/base/dl_rule_set.h index 2e7401fea..748574d96 100644 --- a/src/muz/base/dl_rule_set.h +++ b/src/muz/base/dl_rule_set.h @@ -19,8 +19,8 @@ Revision History: #ifndef DL_RULE_SET_H_ #define DL_RULE_SET_H_ -#include"obj_hashtable.h" -#include"dl_rule.h" +#include "util/obj_hashtable.h" +#include "muz/base/dl_rule.h" namespace datalog { diff --git a/src/muz/base/dl_rule_subsumption_index.cpp b/src/muz/base/dl_rule_subsumption_index.cpp index 43f801bbf..f3fb545b6 100644 --- a/src/muz/base/dl_rule_subsumption_index.cpp +++ b/src/muz/base/dl_rule_subsumption_index.cpp @@ -20,9 +20,9 @@ Revision History: #include -#include "ast_pp.h" +#include "ast/ast_pp.h" -#include "dl_rule_subsumption_index.h" +#include "muz/base/dl_rule_subsumption_index.h" namespace datalog { diff --git a/src/muz/base/dl_rule_subsumption_index.h b/src/muz/base/dl_rule_subsumption_index.h index 89f7d44b7..2d09200f1 100644 --- a/src/muz/base/dl_rule_subsumption_index.h +++ b/src/muz/base/dl_rule_subsumption_index.h @@ -21,7 +21,7 @@ Revision History: #ifndef DL_RULE_SUBSUMPTION_INDEX_H_ #define DL_RULE_SUBSUMPTION_INDEX_H_ -#include "dl_context.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/base/dl_rule_transformer.cpp b/src/muz/base/dl_rule_transformer.cpp index 2df8b9453..9206efef6 100644 --- a/src/muz/base/dl_rule_transformer.cpp +++ b/src/muz/base/dl_rule_transformer.cpp @@ -20,9 +20,9 @@ Revision History: #include #include -#include"dl_context.h" -#include"dl_rule_transformer.h" -#include"stopwatch.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_transformer.h" +#include "util/stopwatch.h" namespace datalog { diff --git a/src/muz/base/dl_rule_transformer.h b/src/muz/base/dl_rule_transformer.h index d166acdd0..dc930ae2b 100644 --- a/src/muz/base/dl_rule_transformer.h +++ b/src/muz/base/dl_rule_transformer.h @@ -19,10 +19,10 @@ Revision History: #ifndef DL_RULE_TRANSFORMER_H_ #define DL_RULE_TRANSFORMER_H_ -#include"map.h" -#include"vector.h" -#include"dl_rule.h" -#include"dl_rule_set.h" +#include "util/map.h" +#include "util/vector.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_set.h" namespace datalog { diff --git a/src/muz/base/dl_util.cpp b/src/muz/base/dl_util.cpp index 0f254ee0a..f0439a55c 100644 --- a/src/muz/base/dl_util.cpp +++ b/src/muz/base/dl_util.cpp @@ -23,14 +23,14 @@ Revision History: #ifdef _WINDOWS #include #endif -#include"ast_pp.h" -#include"bool_rewriter.h" -#include"for_each_expr.h" -#include"scoped_proof.h" -#include"dl_context.h" -#include"dl_rule.h" -#include"dl_util.h" -#include"stopwatch.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/for_each_expr.h" +#include "ast/scoped_proof.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_util.h" +#include "util/stopwatch.h" namespace datalog { diff --git a/src/muz/base/dl_util.h b/src/muz/base/dl_util.h index a4e9f192e..48d420bfb 100644 --- a/src/muz/base/dl_util.h +++ b/src/muz/base/dl_util.h @@ -20,17 +20,17 @@ Revision History: #define DL_UTIL_H_ #include -#include"ast.h" -#include"hashtable.h" -#include"obj_hashtable.h" -#include"uint_set.h" -#include"horn_subsume_model_converter.h" -#include"replace_proof_converter.h" -#include"substitution.h" -#include"ast_counter.h" -#include"statistics.h" -#include"stopwatch.h" -#include"lbool.h" +#include "ast/ast.h" +#include "util/hashtable.h" +#include "util/obj_hashtable.h" +#include "util/uint_set.h" +#include "tactic/horn_subsume_model_converter.h" +#include "tactic/replace_proof_converter.h" +#include "ast/substitution/substitution.h" +#include "ast/rewriter/ast_counter.h" +#include "util/statistics.h" +#include "util/stopwatch.h" +#include "util/lbool.h" namespace datalog { diff --git a/src/muz/base/hnf.cpp b/src/muz/base/hnf.cpp index 6d1c19a13..7db30a9f0 100644 --- a/src/muz/base/hnf.cpp +++ b/src/muz/base/hnf.cpp @@ -43,20 +43,20 @@ Notes: --*/ -#include"hnf.h" -#include"warning.h" -#include"used_vars.h" -#include"well_sorted.h" -#include"var_subst.h" -#include"name_exprs.h" -#include"act_cache.h" -#include"cooperate.h" -#include"ast_pp.h" -#include"quant_hoist.h" -#include"ast_util.h" -#include"dl_util.h" -#include"for_each_ast.h" -#include"for_each_expr.h" +#include "muz/base/hnf.h" +#include "util/warning.h" +#include "ast/used_vars.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/var_subst.h" +#include "ast/normal_forms/name_exprs.h" +#include "ast/act_cache.h" +#include "util/cooperate.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/quant_hoist.h" +#include "ast/ast_util.h" +#include "muz/base/dl_util.h" +#include "ast/for_each_ast.h" +#include "ast/for_each_expr.h" class hnf::imp { diff --git a/src/muz/base/hnf.h b/src/muz/base/hnf.h index 23b379d4d..330dfab70 100644 --- a/src/muz/base/hnf.h +++ b/src/muz/base/hnf.h @@ -25,10 +25,10 @@ Copyright (c) 2015 Microsoft Corporation #ifndef HNF_H_ #define HNF_H_ -#include"ast.h" -#include"params.h" -#include"defined_names.h" -#include"proof_converter.h" +#include "ast/ast.h" +#include "util/params.h" +#include "ast/normal_forms/defined_names.h" +#include "tactic/proof_converter.h" class hnf { class imp; diff --git a/src/muz/base/proof_utils.cpp b/src/muz/base/proof_utils.cpp index 59856c160..bbf9da0a4 100644 --- a/src/muz/base/proof_utils.cpp +++ b/src/muz/base/proof_utils.cpp @@ -4,10 +4,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "dl_util.h" -#include "proof_utils.h" -#include "ast_smt2_pp.h" -#include "var_subst.h" +#include "muz/base/dl_util.h" +#include "muz/base/proof_utils.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/var_subst.h" class reduce_hypotheses { typedef obj_hashtable expr_set; diff --git a/src/muz/base/rule_properties.cpp b/src/muz/base/rule_properties.cpp index 247519d63..21317a07c 100644 --- a/src/muz/base/rule_properties.cpp +++ b/src/muz/base/rule_properties.cpp @@ -18,11 +18,11 @@ Notes: --*/ -#include"expr_functors.h" -#include"rule_properties.h" -#include"dl_rule_set.h" -#include"for_each_expr.h" -#include"dl_context.h" +#include "ast/expr_functors.h" +#include "muz/base/rule_properties.h" +#include "muz/base/dl_rule_set.h" +#include "ast/for_each_expr.h" +#include "muz/base/dl_context.h" using namespace datalog; rule_properties::rule_properties(ast_manager & m, rule_manager& rm, context& ctx, i_expr_pred& p): diff --git a/src/muz/base/rule_properties.h b/src/muz/base/rule_properties.h index f53ad3841..197633aff 100644 --- a/src/muz/base/rule_properties.h +++ b/src/muz/base/rule_properties.h @@ -21,10 +21,10 @@ Notes: #ifndef RULE_PROPERTIES_H_ #define RULE_PROPERTIES_H_ -#include"ast.h" -#include"datatype_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"dl_rule.h" +#include "ast/ast.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "muz/base/dl_rule.h" namespace datalog { class rule_properties { diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index 8cc5c4f60..186a021da 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -17,21 +17,21 @@ Revision History: --*/ -#include "dl_context.h" -#include "dl_rule_transformer.h" -#include "dl_bmc_engine.h" -#include "dl_mk_slice.h" -#include "smt_kernel.h" -#include "datatype_decl_plugin.h" -#include "dl_decl_plugin.h" -#include "bool_rewriter.h" -#include "model_smt2_pp.h" -#include "ast_smt_pp.h" -#include "well_sorted.h" -#include "rewriter_def.h" -#include "dl_transforms.h" -#include "dl_mk_rule_inliner.h" -#include "scoped_proof.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/bmc/dl_bmc_engine.h" +#include "muz/transforms/dl_mk_slice.h" +#include "smt/smt_kernel.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/dl_decl_plugin.h" +#include "ast/rewriter/bool_rewriter.h" +#include "model/model_smt2_pp.h" +#include "ast/ast_smt_pp.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/rewriter_def.h" +#include "muz/transforms/dl_transforms.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "ast/scoped_proof.h" namespace datalog { diff --git a/src/muz/bmc/dl_bmc_engine.h b/src/muz/bmc/dl_bmc_engine.h index a9ef44066..39bdd1fbe 100644 --- a/src/muz/bmc/dl_bmc_engine.h +++ b/src/muz/bmc/dl_bmc_engine.h @@ -20,11 +20,11 @@ Revision History: #ifndef DL_BMC_ENGINE_H_ #define DL_BMC_ENGINE_H_ -#include "params.h" -#include "statistics.h" -#include "smt_kernel.h" -#include "bv_decl_plugin.h" -#include "smt_params.h" +#include "util/params.h" +#include "util/statistics.h" +#include "smt/smt_kernel.h" +#include "ast/bv_decl_plugin.h" +#include "smt/params/smt_params.h" namespace datalog { diff --git a/src/muz/clp/clp_context.cpp b/src/muz/clp/clp_context.cpp index 7dec835a9..d1ce80e12 100644 --- a/src/muz/clp/clp_context.cpp +++ b/src/muz/clp/clp_context.cpp @@ -17,13 +17,13 @@ Revision History: --*/ -#include "clp_context.h" -#include "dl_context.h" -#include "unifier.h" -#include "var_subst.h" -#include "substitution.h" -#include "smt_kernel.h" -#include "dl_transforms.h" +#include "muz/clp/clp_context.h" +#include "muz/base/dl_context.h" +#include "ast/substitution/unifier.h" +#include "ast/rewriter/var_subst.h" +#include "ast/substitution/substitution.h" +#include "smt/smt_kernel.h" +#include "muz/transforms/dl_transforms.h" namespace datalog { diff --git a/src/muz/clp/clp_context.h b/src/muz/clp/clp_context.h index 214dd891a..44f99d564 100644 --- a/src/muz/clp/clp_context.h +++ b/src/muz/clp/clp_context.h @@ -19,10 +19,10 @@ Revision History: #ifndef CLP_CONTEXT_H_ #define CLP_CONTEXT_H_ -#include "ast.h" -#include "lbool.h" -#include "statistics.h" -#include "dl_engine_base.h" +#include "ast/ast.h" +#include "util/lbool.h" +#include "util/statistics.h" +#include "muz/base/dl_engine_base.h" namespace datalog { class context; diff --git a/src/muz/dataflow/dataflow.cpp b/src/muz/dataflow/dataflow.cpp index 73e152ad7..7908231c5 100644 --- a/src/muz/dataflow/dataflow.cpp +++ b/src/muz/dataflow/dataflow.cpp @@ -15,8 +15,8 @@ Author: --*/ -#include "dataflow.h" -#include "reachability.h" +#include "muz/dataflow/dataflow.h" +#include "muz/dataflow/reachability.h" namespace datalog { diff --git a/src/muz/dataflow/dataflow.h b/src/muz/dataflow/dataflow.h index d2be194eb..5e91a0149 100644 --- a/src/muz/dataflow/dataflow.h +++ b/src/muz/dataflow/dataflow.h @@ -18,10 +18,10 @@ Author: #ifndef DATAFLOW_H_ #define DATAFLOW_H_ -#include "dl_rule.h" -#include "dl_rule_set.h" -#include "hashtable.h" -#include "vector.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_set.h" +#include "util/hashtable.h" +#include "util/vector.h" namespace datalog { template class fact_reader; diff --git a/src/muz/dataflow/reachability.h b/src/muz/dataflow/reachability.h index 54da04967..da593a794 100644 --- a/src/muz/dataflow/reachability.h +++ b/src/muz/dataflow/reachability.h @@ -17,7 +17,7 @@ Author: #ifndef REACHABILITY_H_ #define REACHABILITY_H_ -#include "dataflow.h" +#include "muz/dataflow/dataflow.h" namespace datalog { class reachability_info { diff --git a/src/muz/ddnf/ddnf.cpp b/src/muz/ddnf/ddnf.cpp index 6863a908f..0e2f6b35f 100644 --- a/src/muz/ddnf/ddnf.cpp +++ b/src/muz/ddnf/ddnf.cpp @@ -20,12 +20,12 @@ Revision History: --*/ -#include "ddnf.h" -#include "dl_rule_set.h" -#include "dl_context.h" -#include "scoped_proof.h" -#include "bv_decl_plugin.h" -#include "tbv.h" +#include "muz/ddnf/ddnf.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_context.h" +#include "ast/scoped_proof.h" +#include "ast/bv_decl_plugin.h" +#include "muz/rel/tbv.h" namespace datalog { diff --git a/src/muz/ddnf/ddnf.h b/src/muz/ddnf/ddnf.h index 997009026..29e9b1555 100644 --- a/src/muz/ddnf/ddnf.h +++ b/src/muz/ddnf/ddnf.h @@ -19,10 +19,10 @@ Revision History: #ifndef DDNF_H_ #define DDNF_H_ -#include "ast.h" -#include "lbool.h" -#include "statistics.h" -#include "dl_engine_base.h" +#include "ast/ast.h" +#include "util/lbool.h" +#include "util/statistics.h" +#include "muz/base/dl_engine_base.h" class tbv; class tbv_manager; diff --git a/src/muz/duality/duality_dl_interface.cpp b/src/muz/duality/duality_dl_interface.cpp index 978391ad2..30f8a7dfa 100755 --- a/src/muz/duality/duality_dl_interface.cpp +++ b/src/muz/duality/duality_dl_interface.cpp @@ -18,26 +18,26 @@ --*/ -#include "dl_context.h" -#include "dl_mk_coi_filter.h" -#include "dl_mk_interp_tail_simplifier.h" -#include "dl_mk_subsumption_checker.h" -#include "dl_mk_rule_inliner.h" -#include "dl_rule.h" -#include "dl_rule_transformer.h" -#include "smt2parser.h" -#include "duality_dl_interface.h" -#include "dl_rule_set.h" -#include "dl_mk_slice.h" -#include "dl_mk_unfold.h" -#include "dl_mk_coalesce.h" -#include "expr_abstract.h" -#include "model_smt2_pp.h" -#include "model_v2_pp.h" +#include "muz/base/dl_context.h" +#include "muz/transforms/dl_mk_coi_filter.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" +#include "muz/transforms/dl_mk_subsumption_checker.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_transformer.h" +#include "parsers/smt2/smt2parser.h" +#include "muz/duality/duality_dl_interface.h" +#include "muz/base/dl_rule_set.h" +#include "muz/transforms/dl_mk_slice.h" +#include "muz/transforms/dl_mk_unfold.h" +#include "muz/transforms/dl_mk_coalesce.h" +#include "ast/expr_abstract.h" +#include "model/model_smt2_pp.h" +#include "model/model_v2_pp.h" #include "fixedpoint_params.hpp" -#include "used_vars.h" -#include "func_decl_dependencies.h" -#include "dl_transforms.h" +#include "ast/used_vars.h" +#include "ast/func_decl_dependencies.h" +#include "muz/transforms/dl_transforms.h" // template class symbol_table; @@ -48,8 +48,8 @@ #pragma warning(disable:4101) #endif -#include "duality.h" -#include "duality_profiling.h" +#include "duality/duality.h" +#include "duality/duality_profiling.h" // using namespace Duality; diff --git a/src/muz/duality/duality_dl_interface.h b/src/muz/duality/duality_dl_interface.h index a7c186074..21291a45b 100644 --- a/src/muz/duality/duality_dl_interface.h +++ b/src/muz/duality/duality_dl_interface.h @@ -21,11 +21,11 @@ #ifndef DUALITY_DL_INTERFACE_H_ #define DUALITY_DL_INTERFACE_H_ -#include "lbool.h" -#include "dl_rule.h" -#include "dl_rule_set.h" -#include "dl_engine_base.h" -#include "statistics.h" +#include "util/lbool.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_engine_base.h" +#include "util/statistics.h" namespace datalog { class context; diff --git a/src/muz/fp/datalog_parser.cpp b/src/muz/fp/datalog_parser.cpp index b51af7d53..7191f1931 100644 --- a/src/muz/fp/datalog_parser.cpp +++ b/src/muz/fp/datalog_parser.cpp @@ -5,13 +5,13 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include"datalog_parser.h" -#include"string_buffer.h" -#include"str_hashtable.h" -#include"ast_pp.h" -#include"arith_decl_plugin.h" -#include"region.h" -#include"warning.h" +#include "muz/fp/datalog_parser.h" +#include "util/string_buffer.h" +#include "util/str_hashtable.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "util/region.h" +#include "util/warning.h" #include #include #include diff --git a/src/muz/fp/datalog_parser.h b/src/muz/fp/datalog_parser.h index 70b251585..c52fc6589 100644 --- a/src/muz/fp/datalog_parser.h +++ b/src/muz/fp/datalog_parser.h @@ -19,8 +19,8 @@ Revision History: #ifndef DATALOG_PARSER_H_ #define DATALOG_PARSER_H_ -#include "ast.h" -#include "dl_context.h" +#include "ast/ast.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/fp/dl_cmds.cpp b/src/muz/fp/dl_cmds.cpp index a98143aed..a82737b78 100644 --- a/src/muz/fp/dl_cmds.cpp +++ b/src/muz/fp/dl_cmds.cpp @@ -15,21 +15,21 @@ Author: Notes: --*/ -#include"cmd_context.h" -#include"dl_cmds.h" -#include"dl_external_relation.h" -#include"dl_context.h" -#include"dl_register_engine.h" -#include"dl_decl_plugin.h" -#include"dl_instruction.h" -#include"dl_compiler.h" -#include"dl_rule.h" -#include"ast_pp.h" -#include"parametric_cmd.h" -#include"cancel_eh.h" -#include"scoped_ctrl_c.h" -#include"scoped_timer.h" -#include"trail.h" +#include "cmd_context/cmd_context.h" +#include "muz/fp/dl_cmds.h" +#include "muz/rel/dl_external_relation.h" +#include "muz/base/dl_context.h" +#include "muz/fp/dl_register_engine.h" +#include "ast/dl_decl_plugin.h" +#include "muz/rel/dl_instruction.h" +#include "muz/rel/dl_compiler.h" +#include "muz/base/dl_rule.h" +#include "ast/ast_pp.h" +#include "cmd_context/parametric_cmd.h" +#include "util/cancel_eh.h" +#include "util/scoped_ctrl_c.h" +#include "util/scoped_timer.h" +#include "util/trail.h" #include"fixedpoint_params.hpp" #include diff --git a/src/muz/fp/dl_cmds.h b/src/muz/fp/dl_cmds.h index a06e6140e..326ff2413 100644 --- a/src/muz/fp/dl_cmds.h +++ b/src/muz/fp/dl_cmds.h @@ -18,7 +18,7 @@ Notes: #ifndef DL_CMDS_H_ #define DL_CMDS_H_ -#include "ast.h" +#include "ast/ast.h" class cmd_context; diff --git a/src/muz/fp/dl_register_engine.cpp b/src/muz/fp/dl_register_engine.cpp index 6e1ba40ce..4d32cb543 100644 --- a/src/muz/fp/dl_register_engine.cpp +++ b/src/muz/fp/dl_register_engine.cpp @@ -16,14 +16,14 @@ Author: Revision History: --*/ -#include "dl_register_engine.h" -#include "dl_bmc_engine.h" -#include "clp_context.h" -#include "tab_context.h" -#include "rel_context.h" -#include "pdr_dl_interface.h" -#include "ddnf.h" -#include "duality_dl_interface.h" +#include "muz/fp/dl_register_engine.h" +#include "muz/bmc/dl_bmc_engine.h" +#include "muz/clp/clp_context.h" +#include "muz/tab/tab_context.h" +#include "muz/rel/rel_context.h" +#include "muz/pdr/pdr_dl_interface.h" +#include "muz/ddnf/ddnf.h" +#include "muz/duality/duality_dl_interface.h" namespace datalog { register_engine::register_engine(): m_ctx(0) {} diff --git a/src/muz/fp/dl_register_engine.h b/src/muz/fp/dl_register_engine.h index 4d5076b75..11f778346 100644 --- a/src/muz/fp/dl_register_engine.h +++ b/src/muz/fp/dl_register_engine.h @@ -19,7 +19,7 @@ Revision History: #ifndef DL_REGISTER_ENGINE_H_ #define DL_REGISTER_ENGINE_H_ -#include "dl_context.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/fp/horn_tactic.cpp b/src/muz/fp/horn_tactic.cpp index b3e7eeb67..8a9f13144 100644 --- a/src/muz/fp/horn_tactic.cpp +++ b/src/muz/fp/horn_tactic.cpp @@ -16,20 +16,20 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"model_converter.h" -#include"proof_converter.h" -#include"horn_tactic.h" -#include"dl_context.h" -#include"dl_register_engine.h" -#include"expr_replacer.h" -#include"dl_rule_transformer.h" -#include"dl_mk_slice.h" -#include"filter_model_converter.h" -#include"dl_transforms.h" +#include "tactic/tactical.h" +#include "tactic/model_converter.h" +#include "tactic/proof_converter.h" +#include "muz/fp/horn_tactic.h" +#include "muz/base/dl_context.h" +#include "muz/fp/dl_register_engine.h" +#include "ast/rewriter/expr_replacer.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/transforms/dl_mk_slice.h" +#include "tactic/filter_model_converter.h" +#include "muz/transforms/dl_transforms.h" #include"fixedpoint_params.hpp" -#include"ast_util.h" -#include"var_subst.h" +#include "ast/ast_util.h" +#include "ast/rewriter/var_subst.h" class horn_tactic : public tactic { struct imp { diff --git a/src/muz/fp/horn_tactic.h b/src/muz/fp/horn_tactic.h index 72432b4e2..b48585ee2 100644 --- a/src/muz/fp/horn_tactic.h +++ b/src/muz/fp/horn_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef HORN_TACTIC_H_ #define HORN_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/muz/pdr/pdr_closure.cpp b/src/muz/pdr/pdr_closure.cpp index 746b12416..82caf285b 100644 --- a/src/muz/pdr/pdr_closure.cpp +++ b/src/muz/pdr/pdr_closure.cpp @@ -17,10 +17,10 @@ Revision History: --*/ -#include "pdr_closure.h" -#include "pdr_context.h" -#include "expr_safe_replace.h" -#include "ast_util.h" +#include "muz/pdr/pdr_closure.h" +#include "muz/pdr/pdr_context.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/ast_util.h" namespace pdr { diff --git a/src/muz/pdr/pdr_closure.h b/src/muz/pdr/pdr_closure.h index ab417e90e..8af53376b 100644 --- a/src/muz/pdr/pdr_closure.h +++ b/src/muz/pdr/pdr_closure.h @@ -20,7 +20,7 @@ Revision History: #ifndef PDR_CLOSURE_H_ #define PDR_CLOSURE_H_ -#include "arith_decl_plugin.h" +#include "ast/arith_decl_plugin.h" namespace pdr { diff --git a/src/muz/pdr/pdr_context.cpp b/src/muz/pdr/pdr_context.cpp index 05bb5489a..0190044b1 100644 --- a/src/muz/pdr/pdr_context.cpp +++ b/src/muz/pdr/pdr_context.cpp @@ -25,31 +25,31 @@ Notes: #include -#include "dl_util.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "var_subst.h" -#include "util.h" -#include "pdr_prop_solver.h" -#include "pdr_context.h" -#include "pdr_generalizers.h" -#include "for_each_expr.h" -#include "dl_rule_set.h" -#include "unit_subsumption_tactic.h" -#include "model_smt2_pp.h" -#include "dl_mk_rule_inliner.h" -#include "ast_smt2_pp.h" -#include "qe_lite.h" -#include "ast_ll_pp.h" -#include "proof_checker.h" -#include "smt_value_sort.h" -#include "proof_utils.h" -#include "dl_boogie_proof.h" -#include "scoped_proof.h" -#include "blast_term_ite_tactic.h" -#include "model_implicant.h" -#include "expr_safe_replace.h" -#include "ast_util.h" +#include "muz/base/dl_util.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/var_subst.h" +#include "util/util.h" +#include "muz/pdr/pdr_prop_solver.h" +#include "muz/pdr/pdr_context.h" +#include "muz/pdr/pdr_generalizers.h" +#include "ast/for_each_expr.h" +#include "muz/base/dl_rule_set.h" +#include "smt/tactic/unit_subsumption_tactic.h" +#include "model/model_smt2_pp.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "ast/ast_smt2_pp.h" +#include "qe/qe_lite.h" +#include "ast/ast_ll_pp.h" +#include "ast/proof_checker/proof_checker.h" +#include "smt/smt_value_sort.h" +#include "muz/base/proof_utils.h" +#include "muz/base/dl_boogie_proof.h" +#include "ast/scoped_proof.h" +#include "tactic/core/blast_term_ite_tactic.h" +#include "model/model_implicant.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/ast_util.h" namespace pdr { diff --git a/src/muz/pdr/pdr_context.h b/src/muz/pdr/pdr_context.h index a32a65c48..087f77f9e 100644 --- a/src/muz/pdr/pdr_context.h +++ b/src/muz/pdr/pdr_context.h @@ -25,9 +25,9 @@ Revision History: #undef max #endif #include -#include "pdr_manager.h" -#include "pdr_prop_solver.h" -#include "pdr_reachable_cache.h" +#include "muz/pdr/pdr_manager.h" +#include "muz/pdr/pdr_prop_solver.h" +#include "muz/pdr/pdr_reachable_cache.h" #include "fixedpoint_params.hpp" diff --git a/src/muz/pdr/pdr_dl_interface.cpp b/src/muz/pdr/pdr_dl_interface.cpp index 5f4a200fc..87bc68bd9 100644 --- a/src/muz/pdr/pdr_dl_interface.cpp +++ b/src/muz/pdr/pdr_dl_interface.cpp @@ -17,19 +17,19 @@ Revision History: --*/ -#include "dl_context.h" -#include "dl_mk_coi_filter.h" -#include "dl_rule.h" -#include "dl_rule_transformer.h" -#include "pdr_context.h" -#include "pdr_dl_interface.h" -#include "dl_rule_set.h" -#include "dl_mk_slice.h" -#include "dl_mk_unfold.h" -#include "dl_mk_coalesce.h" -#include "dl_transforms.h" -#include "scoped_proof.h" -#include "model_smt2_pp.h" +#include "muz/base/dl_context.h" +#include "muz/transforms/dl_mk_coi_filter.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/pdr/pdr_context.h" +#include "muz/pdr/pdr_dl_interface.h" +#include "muz/base/dl_rule_set.h" +#include "muz/transforms/dl_mk_slice.h" +#include "muz/transforms/dl_mk_unfold.h" +#include "muz/transforms/dl_mk_coalesce.h" +#include "muz/transforms/dl_transforms.h" +#include "ast/scoped_proof.h" +#include "model/model_smt2_pp.h" using namespace pdr; diff --git a/src/muz/pdr/pdr_dl_interface.h b/src/muz/pdr/pdr_dl_interface.h index 008655a0b..884f89e4b 100644 --- a/src/muz/pdr/pdr_dl_interface.h +++ b/src/muz/pdr/pdr_dl_interface.h @@ -20,12 +20,12 @@ Revision History: #ifndef PDR_DL_INTERFACE_H_ #define PDR_DL_INTERFACE_H_ -#include "lbool.h" -#include "dl_rule.h" -#include "dl_rule_set.h" -#include "dl_util.h" -#include "dl_engine_base.h" -#include "statistics.h" +#include "util/lbool.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_util.h" +#include "muz/base/dl_engine_base.h" +#include "util/statistics.h" namespace datalog { class context; diff --git a/src/muz/pdr/pdr_farkas_learner.cpp b/src/muz/pdr/pdr_farkas_learner.cpp index 54d9ada89..29037f180 100644 --- a/src/muz/pdr/pdr_farkas_learner.cpp +++ b/src/muz/pdr/pdr_farkas_learner.cpp @@ -18,21 +18,21 @@ Revision History: --*/ -#include "ast_smt2_pp.h" -#include "array_decl_plugin.h" -#include "bool_rewriter.h" -#include "dl_decl_plugin.h" -#include "for_each_expr.h" -#include "dl_util.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "pdr_util.h" -#include "pdr_farkas_learner.h" -#include "th_rewriter.h" -#include "ast_ll_pp.h" -#include "arith_bounds_tactic.h" -#include "proof_utils.h" -#include "reg_decl_plugins.h" +#include "ast/ast_smt2_pp.h" +#include "ast/array_decl_plugin.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/dl_decl_plugin.h" +#include "ast/for_each_expr.h" +#include "muz/base/dl_util.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "muz/pdr/pdr_util.h" +#include "muz/pdr/pdr_farkas_learner.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/ast_ll_pp.h" +#include "tactic/arith/arith_bounds_tactic.h" +#include "muz/base/proof_utils.h" +#include "ast/reg_decl_plugins.h" namespace pdr { diff --git a/src/muz/pdr/pdr_farkas_learner.h b/src/muz/pdr/pdr_farkas_learner.h index 3a4d81f96..a5f3482e6 100644 --- a/src/muz/pdr/pdr_farkas_learner.h +++ b/src/muz/pdr/pdr_farkas_learner.h @@ -20,14 +20,14 @@ Revision History: #ifndef PDR_FARKAS_LEARNER_H_ #define PDR_FARKAS_LEARNER_H_ -#include "arith_decl_plugin.h" -#include "ast_translation.h" -#include "bv_decl_plugin.h" -#include "smt_kernel.h" -#include "bool_rewriter.h" -#include "pdr_util.h" -#include "smt_params.h" -#include "tactic.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_translation.h" +#include "ast/bv_decl_plugin.h" +#include "smt/smt_kernel.h" +#include "ast/rewriter/bool_rewriter.h" +#include "muz/pdr/pdr_util.h" +#include "smt/params/smt_params.h" +#include "tactic/tactic.h" namespace pdr { diff --git a/src/muz/pdr/pdr_generalizers.cpp b/src/muz/pdr/pdr_generalizers.cpp index 5b7e11877..b17d3f8b6 100644 --- a/src/muz/pdr/pdr_generalizers.cpp +++ b/src/muz/pdr/pdr_generalizers.cpp @@ -18,13 +18,13 @@ Revision History: --*/ -#include "pdr_context.h" -#include "pdr_farkas_learner.h" -#include "pdr_generalizers.h" -#include "expr_abstract.h" -#include "var_subst.h" -#include "expr_safe_replace.h" -#include "model_smt2_pp.h" +#include "muz/pdr/pdr_context.h" +#include "muz/pdr/pdr_farkas_learner.h" +#include "muz/pdr/pdr_generalizers.h" +#include "ast/expr_abstract.h" +#include "ast/rewriter/var_subst.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "model/model_smt2_pp.h" namespace pdr { diff --git a/src/muz/pdr/pdr_generalizers.h b/src/muz/pdr/pdr_generalizers.h index 3e4576fa1..3d0fe6ccd 100644 --- a/src/muz/pdr/pdr_generalizers.h +++ b/src/muz/pdr/pdr_generalizers.h @@ -20,9 +20,9 @@ Revision History: #ifndef PDR_GENERALIZERS_H_ #define PDR_GENERALIZERS_H_ -#include "pdr_context.h" -#include "pdr_closure.h" -#include "arith_decl_plugin.h" +#include "muz/pdr/pdr_context.h" +#include "muz/pdr/pdr_closure.h" +#include "ast/arith_decl_plugin.h" namespace pdr { diff --git a/src/muz/pdr/pdr_manager.cpp b/src/muz/pdr/pdr_manager.cpp index 319f38255..077d27427 100644 --- a/src/muz/pdr/pdr_manager.cpp +++ b/src/muz/pdr/pdr_manager.cpp @@ -19,15 +19,15 @@ Revision History: --*/ #include -#include "pdr_manager.h" -#include "ast_smt2_pp.h" -#include "for_each_expr.h" -#include "has_free_vars.h" -#include "expr_replacer.h" -#include "expr_abstract.h" -#include "model2expr.h" -#include "model_smt2_pp.h" -#include "model_converter.h" +#include "muz/pdr/pdr_manager.h" +#include "ast/ast_smt2_pp.h" +#include "ast/for_each_expr.h" +#include "ast/has_free_vars.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/expr_abstract.h" +#include "model/model2expr.h" +#include "model/model_smt2_pp.h" +#include "tactic/model_converter.h" namespace pdr { diff --git a/src/muz/pdr/pdr_manager.h b/src/muz/pdr/pdr_manager.h index 790e2465d..9fc98940d 100644 --- a/src/muz/pdr/pdr_manager.h +++ b/src/muz/pdr/pdr_manager.h @@ -23,17 +23,17 @@ Revision History: #include #include -#include "bool_rewriter.h" -#include "expr_replacer.h" -#include "expr_substitution.h" -#include "map.h" -#include "ref_vector.h" -#include "smt_kernel.h" -#include "pdr_util.h" -#include "pdr_sym_mux.h" -#include "pdr_farkas_learner.h" -#include "pdr_smt_context_manager.h" -#include "dl_rule.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/expr_substitution.h" +#include "util/map.h" +#include "util/ref_vector.h" +#include "smt/smt_kernel.h" +#include "muz/pdr/pdr_util.h" +#include "muz/pdr/pdr_sym_mux.h" +#include "muz/pdr/pdr_farkas_learner.h" +#include "muz/pdr/pdr_smt_context_manager.h" +#include "muz/base/dl_rule.h" namespace smt { diff --git a/src/muz/pdr/pdr_prop_solver.cpp b/src/muz/pdr/pdr_prop_solver.cpp index 8c407161e..3055985f4 100644 --- a/src/muz/pdr/pdr_prop_solver.cpp +++ b/src/muz/pdr/pdr_prop_solver.cpp @@ -18,18 +18,18 @@ Revision History: --*/ #include -#include "model.h" -#include "pdr_util.h" -#include "pdr_prop_solver.h" -#include "ast_smt2_pp.h" -#include "dl_util.h" -#include "model_pp.h" -#include "smt_params.h" -#include "datatype_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "pdr_farkas_learner.h" -#include "ast_smt2_pp.h" -#include "expr_replacer.h" +#include "model/model.h" +#include "muz/pdr/pdr_util.h" +#include "muz/pdr/pdr_prop_solver.h" +#include "ast/ast_smt2_pp.h" +#include "muz/base/dl_util.h" +#include "model/model_pp.h" +#include "smt/params/smt_params.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "muz/pdr/pdr_farkas_learner.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/expr_replacer.h" // // Auxiliary structure to introduce propositional names for assumptions that are not diff --git a/src/muz/pdr/pdr_prop_solver.h b/src/muz/pdr/pdr_prop_solver.h index ad7e1fd9a..463163fbd 100644 --- a/src/muz/pdr/pdr_prop_solver.h +++ b/src/muz/pdr/pdr_prop_solver.h @@ -23,13 +23,13 @@ Revision History: #include #include #include -#include "ast.h" -#include "obj_hashtable.h" -#include "smt_kernel.h" -#include "util.h" -#include "vector.h" -#include "pdr_manager.h" -#include "pdr_smt_context_manager.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "smt/smt_kernel.h" +#include "util/util.h" +#include "util/vector.h" +#include "muz/pdr/pdr_manager.h" +#include "muz/pdr/pdr_smt_context_manager.h" namespace pdr { diff --git a/src/muz/pdr/pdr_reachable_cache.cpp b/src/muz/pdr/pdr_reachable_cache.cpp index 2bedc1393..d28c1415b 100644 --- a/src/muz/pdr/pdr_reachable_cache.cpp +++ b/src/muz/pdr/pdr_reachable_cache.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include "pdr_reachable_cache.h" +#include "muz/pdr/pdr_reachable_cache.h" namespace pdr { diff --git a/src/muz/pdr/pdr_reachable_cache.h b/src/muz/pdr/pdr_reachable_cache.h index 66832ba42..0833541ba 100644 --- a/src/muz/pdr/pdr_reachable_cache.h +++ b/src/muz/pdr/pdr_reachable_cache.h @@ -20,10 +20,10 @@ Revision History: #ifndef REACHABLE_CACHE_H_ #define REACHABLE_CACHE_H_ -#include "ast.h" -#include "ref_vector.h" -#include "pdr_manager.h" -#include "pdr_smt_context_manager.h" +#include "ast/ast.h" +#include "util/ref_vector.h" +#include "muz/pdr/pdr_manager.h" +#include "muz/pdr/pdr_smt_context_manager.h" namespace pdr { class reachable_cache { diff --git a/src/muz/pdr/pdr_smt_context_manager.cpp b/src/muz/pdr/pdr_smt_context_manager.cpp index b6aa8411d..e912bd658 100644 --- a/src/muz/pdr/pdr_smt_context_manager.cpp +++ b/src/muz/pdr/pdr_smt_context_manager.cpp @@ -17,12 +17,12 @@ Revision History: --*/ -#include "pdr_smt_context_manager.h" -#include "has_free_vars.h" -#include "ast_pp.h" -#include "ast_smt_pp.h" +#include "muz/pdr/pdr_smt_context_manager.h" +#include "ast/has_free_vars.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt_pp.h" #include -#include "smt_params.h" +#include "smt/params/smt_params.h" namespace pdr { diff --git a/src/muz/pdr/pdr_smt_context_manager.h b/src/muz/pdr/pdr_smt_context_manager.h index 173367a41..735b2cd62 100644 --- a/src/muz/pdr/pdr_smt_context_manager.h +++ b/src/muz/pdr/pdr_smt_context_manager.h @@ -20,9 +20,9 @@ Revision History: #ifndef PDR_SMT_CONTEXT_MANAGER_H_ #define PDR_SMT_CONTEXT_MANAGER_H_ -#include "smt_kernel.h" -#include "func_decl_dependencies.h" -#include "dl_util.h" +#include "smt/smt_kernel.h" +#include "ast/func_decl_dependencies.h" +#include "muz/base/dl_util.h" namespace pdr { diff --git a/src/muz/pdr/pdr_sym_mux.cpp b/src/muz/pdr/pdr_sym_mux.cpp index 47edb35ac..72549f2d6 100644 --- a/src/muz/pdr/pdr_sym_mux.cpp +++ b/src/muz/pdr/pdr_sym_mux.cpp @@ -18,13 +18,13 @@ Revision History: --*/ #include -#include "ast_pp.h" -#include "for_each_expr.h" -#include "model.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "pdr_util.h" -#include "pdr_sym_mux.h" +#include "ast/ast_pp.h" +#include "ast/for_each_expr.h" +#include "model/model.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "muz/pdr/pdr_util.h" +#include "muz/pdr/pdr_sym_mux.h" using namespace pdr; diff --git a/src/muz/pdr/pdr_sym_mux.h b/src/muz/pdr/pdr_sym_mux.h index 13bdb71ec..981dc9615 100644 --- a/src/muz/pdr/pdr_sym_mux.h +++ b/src/muz/pdr/pdr_sym_mux.h @@ -20,9 +20,9 @@ Revision History: #ifndef SYM_MUX_H_ #define SYM_MUX_H_ -#include "ast.h" -#include "map.h" -#include "vector.h" +#include "ast/ast.h" +#include "util/map.h" +#include "util/vector.h" #include class model_core; diff --git a/src/muz/pdr/pdr_util.cpp b/src/muz/pdr/pdr_util.cpp index 934be5c63..42a57214a 100644 --- a/src/muz/pdr/pdr_util.cpp +++ b/src/muz/pdr/pdr_util.cpp @@ -22,29 +22,29 @@ Notes: --*/ #include -#include "arith_simplifier_plugin.h" -#include "array_decl_plugin.h" -#include "ast_pp.h" -#include "basic_simplifier_plugin.h" -#include "bv_simplifier_plugin.h" -#include "bool_rewriter.h" -#include "dl_util.h" -#include "for_each_expr.h" -#include "smt_params.h" -#include "model.h" -#include "ref_vector.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "util.h" -#include "pdr_manager.h" -#include "pdr_util.h" -#include "arith_decl_plugin.h" -#include "expr_replacer.h" -#include "model_smt2_pp.h" -#include "poly_rewriter.h" -#include "poly_rewriter_def.h" -#include "arith_rewriter.h" -#include "scoped_proof.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/rewriter/bool_rewriter.h" +#include "muz/base/dl_util.h" +#include "ast/for_each_expr.h" +#include "smt/params/smt_params.h" +#include "model/model.h" +#include "util/ref_vector.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/util.h" +#include "muz/pdr/pdr_manager.h" +#include "muz/pdr/pdr_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/expr_replacer.h" +#include "model/model_smt2_pp.h" +#include "ast/rewriter/poly_rewriter.h" +#include "ast/rewriter/poly_rewriter_def.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/scoped_proof.h" diff --git a/src/muz/pdr/pdr_util.h b/src/muz/pdr/pdr_util.h index 09fad8a30..fccb0c40f 100644 --- a/src/muz/pdr/pdr_util.h +++ b/src/muz/pdr/pdr_util.h @@ -20,16 +20,16 @@ Revision History: #ifndef PDR_UTIL_H_ #define PDR_UTIL_H_ -#include "ast.h" -#include "ast_pp.h" -#include "obj_hashtable.h" -#include "ref_vector.h" -#include "simplifier.h" -#include "trace.h" -#include "vector.h" -#include "arith_decl_plugin.h" -#include "array_decl_plugin.h" -#include "bv_decl_plugin.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "util/obj_hashtable.h" +#include "util/ref_vector.h" +#include "ast/simplifier/simplifier.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/bv_decl_plugin.h" class model; diff --git a/src/muz/rel/aig_exporter.cpp b/src/muz/rel/aig_exporter.cpp index ca0030fc3..bc98ab1f8 100644 --- a/src/muz/rel/aig_exporter.cpp +++ b/src/muz/rel/aig_exporter.cpp @@ -11,8 +11,8 @@ Abstract: --*/ -#include "aig_exporter.h" -#include "dl_context.h" +#include "muz/rel/aig_exporter.h" +#include "muz/base/dl_context.h" #include namespace datalog { diff --git a/src/muz/rel/aig_exporter.h b/src/muz/rel/aig_exporter.h index 71af6fb35..ea241fe2b 100644 --- a/src/muz/rel/aig_exporter.h +++ b/src/muz/rel/aig_exporter.h @@ -14,11 +14,11 @@ Abstract: #ifndef AIG_EXPORTER_H_ #define AIG_EXPORTER_H_ -#include "aig.h" -#include "dl_rule_set.h" +#include "tactic/aig/aig.h" +#include "muz/base/dl_rule_set.h" #include #include -#include "rel_context.h" +#include "muz/rel/rel_context.h" namespace datalog { class aig_exporter { diff --git a/src/muz/rel/check_relation.cpp b/src/muz/rel/check_relation.cpp index e630d7083..ddda295cd 100644 --- a/src/muz/rel/check_relation.cpp +++ b/src/muz/rel/check_relation.cpp @@ -4,10 +4,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "check_relation.h" -#include "dl_relation_manager.h" -#include "ast_util.h" -#include "smt_kernel.h" +#include "muz/rel/check_relation.h" +#include "muz/rel/dl_relation_manager.h" +#include "ast/ast_util.h" +#include "smt/smt_kernel.h" #include diff --git a/src/muz/rel/check_relation.h b/src/muz/rel/check_relation.h index c91567553..0fbb2a269 100644 --- a/src/muz/rel/check_relation.h +++ b/src/muz/rel/check_relation.h @@ -22,8 +22,8 @@ Revision History: #ifndef CHECK_RELATION_H_ #define CHECK_RELATION_H_ -#include "doc.h" -#include "dl_base.h" +#include "muz/rel/doc.h" +#include "muz/rel/dl_base.h" namespace datalog { class check_relation_plugin; diff --git a/src/muz/rel/dl_base.cpp b/src/muz/rel/dl_base.cpp index f79f6c8eb..904faf71f 100644 --- a/src/muz/rel/dl_base.cpp +++ b/src/muz/rel/dl_base.cpp @@ -18,13 +18,13 @@ Revision History: --*/ -#include"ast_pp.h" -#include"union_find.h" -#include"vector.h" -#include"dl_context.h" -#include"dl_base.h" -#include"bool_rewriter.h" -#include"dl_relation_manager.h" +#include "ast/ast_pp.h" +#include "util/union_find.h" +#include "util/vector.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_base.h" +#include "ast/rewriter/bool_rewriter.h" +#include "muz/rel/dl_relation_manager.h" #include diff --git a/src/muz/rel/dl_base.h b/src/muz/rel/dl_base.h index d3422f882..4e59e9258 100644 --- a/src/muz/rel/dl_base.h +++ b/src/muz/rel/dl_base.h @@ -23,12 +23,12 @@ Revision History: #include -#include"ast.h" -#include"map.h" -#include"vector.h" -#include"ref.h" -#include"dl_util.h" -#include"dl_context.h" +#include "ast/ast.h" +#include "util/map.h" +#include "util/vector.h" +#include "util/ref.h" +#include "muz/base/dl_util.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/rel/dl_bound_relation.cpp b/src/muz/rel/dl_bound_relation.cpp index 182046c1e..de6c76456 100644 --- a/src/muz/rel/dl_bound_relation.cpp +++ b/src/muz/rel/dl_bound_relation.cpp @@ -17,9 +17,9 @@ Revision History: --*/ -#include "dl_bound_relation.h" -#include "debug.h" -#include "ast_pp.h" +#include "muz/rel/dl_bound_relation.h" +#include "util/debug.h" +#include "ast/ast_pp.h" namespace datalog { diff --git a/src/muz/rel/dl_bound_relation.h b/src/muz/rel/dl_bound_relation.h index 485dfbafa..456df737b 100644 --- a/src/muz/rel/dl_bound_relation.h +++ b/src/muz/rel/dl_bound_relation.h @@ -19,14 +19,14 @@ Revision History: #ifndef DL_BOUND_RELATION_H_ #define DL_BOUND_RELATION_H_ -#include "dl_context.h" -#include "dl_relation_manager.h" -#include "dl_base.h" -#include "uint_set.h" -#include "dl_vector_relation.h" -#include "dl_interval_relation.h" -#include "arith_decl_plugin.h" -#include "basic_simplifier_plugin.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/rel/dl_base.h" +#include "util/uint_set.h" +#include "muz/rel/dl_vector_relation.h" +#include "muz/rel/dl_interval_relation.h" +#include "ast/arith_decl_plugin.h" +#include "ast/simplifier/basic_simplifier_plugin.h" namespace datalog { diff --git a/src/muz/rel/dl_check_table.cpp b/src/muz/rel/dl_check_table.cpp index ea4003e5f..0c4be18f1 100644 --- a/src/muz/rel/dl_check_table.cpp +++ b/src/muz/rel/dl_check_table.cpp @@ -19,8 +19,8 @@ Revision History: --*/ -#include "dl_check_table.h" -#include "dl_table.h" +#include "muz/rel/dl_check_table.h" +#include "muz/rel/dl_table.h" namespace datalog { diff --git a/src/muz/rel/dl_check_table.h b/src/muz/rel/dl_check_table.h index 35f399452..412dd2dbc 100644 --- a/src/muz/rel/dl_check_table.h +++ b/src/muz/rel/dl_check_table.h @@ -21,9 +21,9 @@ Revision History: #ifndef DL_CHECK_TABLE_H_ #define DL_CHECK_TABLE_H_ -#include "dl_base.h" -#include "dl_decl_plugin.h" -#include "dl_relation_manager.h" +#include "muz/rel/dl_base.h" +#include "ast/dl_decl_plugin.h" +#include "muz/rel/dl_relation_manager.h" namespace datalog { class check_table; diff --git a/src/muz/rel/dl_compiler.cpp b/src/muz/rel/dl_compiler.cpp index 0d4507971..32bcfed50 100644 --- a/src/muz/rel/dl_compiler.cpp +++ b/src/muz/rel/dl_compiler.cpp @@ -19,15 +19,15 @@ Revision History: #include -#include"ref_vector.h" -#include"dl_context.h" -#include"rel_context.h" -#include"dl_rule.h" -#include"dl_util.h" -#include"dl_compiler.h" -#include"ast_pp.h" +#include "util/ref_vector.h" +#include "muz/base/dl_context.h" +#include "muz/rel/rel_context.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_util.h" +#include "muz/rel/dl_compiler.h" +#include "ast/ast_pp.h" // include"ast_smt2_pp.h" -#include"ast_util.h" +#include "ast/ast_util.h" namespace datalog { diff --git a/src/muz/rel/dl_compiler.h b/src/muz/rel/dl_compiler.h index 33d92d805..9aedf141a 100644 --- a/src/muz/rel/dl_compiler.h +++ b/src/muz/rel/dl_compiler.h @@ -23,16 +23,16 @@ Revision History: #include #include -#include "ast.h" -#include "hashtable.h" -#include "map.h" -#include "obj_pair_hashtable.h" -#include "ref_vector.h" -#include "vector.h" +#include "ast/ast.h" +#include "util/hashtable.h" +#include "util/map.h" +#include "util/obj_pair_hashtable.h" +#include "util/ref_vector.h" +#include "util/vector.h" -#include "dl_base.h" -#include "dl_context.h" -#include "dl_instruction.h" +#include "muz/rel/dl_base.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_instruction.h" namespace datalog { diff --git a/src/muz/rel/dl_external_relation.cpp b/src/muz/rel/dl_external_relation.cpp index e9c24abd3..ff9bef40e 100644 --- a/src/muz/rel/dl_external_relation.cpp +++ b/src/muz/rel/dl_external_relation.cpp @@ -17,11 +17,11 @@ Revision History: --*/ -#include "debug.h" -#include "ast_pp.h" -#include "dl_context.h" -#include "dl_external_relation.h" -#include "dl_decl_plugin.h" +#include "util/debug.h" +#include "ast/ast_pp.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_external_relation.h" +#include "ast/dl_decl_plugin.h" namespace datalog { diff --git a/src/muz/rel/dl_external_relation.h b/src/muz/rel/dl_external_relation.h index 0bd78b776..0dfb4a7f2 100644 --- a/src/muz/rel/dl_external_relation.h +++ b/src/muz/rel/dl_external_relation.h @@ -19,7 +19,7 @@ Revision History: #ifndef DL_EXTERNAL_RELATION_H_ #define DL_EXTERNAL_RELATION_H_ -#include "dl_base.h" +#include "muz/rel/dl_base.h" namespace datalog { diff --git a/src/muz/rel/dl_finite_product_relation.cpp b/src/muz/rel/dl_finite_product_relation.cpp index 879e29699..c036d3cfd 100644 --- a/src/muz/rel/dl_finite_product_relation.cpp +++ b/src/muz/rel/dl_finite_product_relation.cpp @@ -19,11 +19,11 @@ Revision History: #include -#include"dl_context.h" -#include"dl_relation_manager.h" -#include"dl_table_relation.h" -#include"dl_finite_product_relation.h" -#include"bool_rewriter.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/rel/dl_table_relation.h" +#include "muz/rel/dl_finite_product_relation.h" +#include "ast/rewriter/bool_rewriter.h" namespace datalog { diff --git a/src/muz/rel/dl_finite_product_relation.h b/src/muz/rel/dl_finite_product_relation.h index e91ab4a17..946296df1 100644 --- a/src/muz/rel/dl_finite_product_relation.h +++ b/src/muz/rel/dl_finite_product_relation.h @@ -20,9 +20,9 @@ Revision History: #define DL_FINITE_PRODUCT_RELATION_H_ -#include "dl_base.h" -#include "dl_relation_manager.h" -#include "dl_table_relation.h" +#include "muz/rel/dl_base.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/rel/dl_table_relation.h" namespace datalog { diff --git a/src/muz/rel/dl_instruction.cpp b/src/muz/rel/dl_instruction.cpp index f0b88cae1..fb718d8b8 100644 --- a/src/muz/rel/dl_instruction.cpp +++ b/src/muz/rel/dl_instruction.cpp @@ -17,14 +17,14 @@ Revision History: --*/ -#include"ast_pp.h" -#include"stopwatch.h" -#include"dl_context.h" -#include"dl_util.h" -#include"dl_instruction.h" -#include"rel_context.h" -#include"debug.h" -#include"warning.h" +#include "ast/ast_pp.h" +#include "util/stopwatch.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_util.h" +#include "muz/rel/dl_instruction.h" +#include "muz/rel/rel_context.h" +#include "util/debug.h" +#include "util/warning.h" namespace datalog { diff --git a/src/muz/rel/dl_instruction.h b/src/muz/rel/dl_instruction.h index 196f5268c..c29681f37 100644 --- a/src/muz/rel/dl_instruction.h +++ b/src/muz/rel/dl_instruction.h @@ -22,11 +22,11 @@ Revision History: #include #include #include -#include "ast.h" -#include "vector.h" -#include "dl_base.h" -#include "dl_costs.h" -#include "dl_context.h" +#include "ast/ast.h" +#include "util/vector.h" +#include "muz/rel/dl_base.h" +#include "muz/base/dl_costs.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/rel/dl_interval_relation.cpp b/src/muz/rel/dl_interval_relation.cpp index 88c262cbe..ccb7b728b 100644 --- a/src/muz/rel/dl_interval_relation.cpp +++ b/src/muz/rel/dl_interval_relation.cpp @@ -17,12 +17,12 @@ Revision History: --*/ -#include "debug.h" -#include "optional.h" -#include "ast_pp.h" -#include "dl_interval_relation.h" -#include "dl_relation_manager.h" -#include "bool_rewriter.h" +#include "util/debug.h" +#include "util/optional.h" +#include "ast/ast_pp.h" +#include "muz/rel/dl_interval_relation.h" +#include "muz/rel/dl_relation_manager.h" +#include "ast/rewriter/bool_rewriter.h" namespace datalog { diff --git a/src/muz/rel/dl_interval_relation.h b/src/muz/rel/dl_interval_relation.h index a8239ef24..05334624f 100644 --- a/src/muz/rel/dl_interval_relation.h +++ b/src/muz/rel/dl_interval_relation.h @@ -20,13 +20,13 @@ Revision History: #define DL_INTERVAL_RELATION_H_ -#include "dl_context.h" -#include "dl_relation_manager.h" -#include "dl_base.h" -#include "old_interval.h" -#include "dl_vector_relation.h" -#include "arith_decl_plugin.h" -#include "basic_simplifier_plugin.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/rel/dl_base.h" +#include "smt/old_interval.h" +#include "muz/rel/dl_vector_relation.h" +#include "ast/arith_decl_plugin.h" +#include "ast/simplifier/basic_simplifier_plugin.h" namespace datalog { diff --git a/src/muz/rel/dl_lazy_table.cpp b/src/muz/rel/dl_lazy_table.cpp index ec97a4bf5..54105891a 100644 --- a/src/muz/rel/dl_lazy_table.cpp +++ b/src/muz/rel/dl_lazy_table.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include "dl_lazy_table.h" -#include "dl_relation_manager.h" +#include "muz/rel/dl_lazy_table.h" +#include "muz/rel/dl_relation_manager.h" #include namespace datalog { diff --git a/src/muz/rel/dl_lazy_table.h b/src/muz/rel/dl_lazy_table.h index 28360c95f..6752e5a5a 100644 --- a/src/muz/rel/dl_lazy_table.h +++ b/src/muz/rel/dl_lazy_table.h @@ -21,8 +21,8 @@ Revision History: #ifndef DL_LAZY_TABLE_H_ #define DL_LAZY_TABLE_H_ -#include "dl_base.h" -#include "ref.h" +#include "muz/rel/dl_base.h" +#include "util/ref.h" namespace datalog { diff --git a/src/muz/rel/dl_mk_explanations.cpp b/src/muz/rel/dl_mk_explanations.cpp index 7fcbdaaff..fd13978d2 100644 --- a/src/muz/rel/dl_mk_explanations.cpp +++ b/src/muz/rel/dl_mk_explanations.cpp @@ -19,12 +19,12 @@ Revision History: #include -#include"ast_pp.h" -#include"ast_smt_pp.h" -#include"dl_finite_product_relation.h" -#include"dl_product_relation.h" -#include"dl_sieve_relation.h" -#include"dl_mk_explanations.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt_pp.h" +#include "muz/rel/dl_finite_product_relation.h" +#include "muz/rel/dl_product_relation.h" +#include "muz/rel/dl_sieve_relation.h" +#include "muz/rel/dl_mk_explanations.h" namespace datalog { diff --git a/src/muz/rel/dl_mk_explanations.h b/src/muz/rel/dl_mk_explanations.h index 54e56bbe8..6142b61d6 100644 --- a/src/muz/rel/dl_mk_explanations.h +++ b/src/muz/rel/dl_mk_explanations.h @@ -20,8 +20,8 @@ Revision History: #ifndef DL_MK_EXPLANATIONS_H_ #define DL_MK_EXPLANATIONS_H_ -#include "dl_context.h" -#include "dl_rule_transformer.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/rel/dl_mk_similarity_compressor.cpp b/src/muz/rel/dl_mk_similarity_compressor.cpp index b65ed455c..c4abf326a 100644 --- a/src/muz/rel/dl_mk_similarity_compressor.cpp +++ b/src/muz/rel/dl_mk_similarity_compressor.cpp @@ -19,8 +19,8 @@ Revision History: #include #include -#include"dl_mk_similarity_compressor.h" -#include"dl_relation_manager.h" +#include "muz/rel/dl_mk_similarity_compressor.h" +#include "muz/rel/dl_relation_manager.h" namespace datalog { diff --git a/src/muz/rel/dl_mk_similarity_compressor.h b/src/muz/rel/dl_mk_similarity_compressor.h index 9ecbf7bfb..68410831c 100644 --- a/src/muz/rel/dl_mk_similarity_compressor.h +++ b/src/muz/rel/dl_mk_similarity_compressor.h @@ -21,12 +21,12 @@ Revision History: #include -#include"map.h" -#include"obj_pair_hashtable.h" +#include "util/map.h" +#include "util/obj_pair_hashtable.h" -#include"dl_context.h" -#include"dl_rule_set.h" -#include"dl_rule_transformer.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/rel/dl_mk_simple_joins.cpp b/src/muz/rel/dl_mk_simple_joins.cpp index a8e54085d..60eea2e53 100644 --- a/src/muz/rel/dl_mk_simple_joins.cpp +++ b/src/muz/rel/dl_mk_simple_joins.cpp @@ -20,10 +20,10 @@ Revision History: #include #include #include -#include"dl_mk_simple_joins.h" -#include"dl_relation_manager.h" -#include"ast_pp.h" -#include"trace.h" +#include "muz/rel/dl_mk_simple_joins.h" +#include "muz/rel/dl_relation_manager.h" +#include "ast/ast_pp.h" +#include "util/trace.h" namespace datalog { diff --git a/src/muz/rel/dl_mk_simple_joins.h b/src/muz/rel/dl_mk_simple_joins.h index 1289e7831..4d422e651 100644 --- a/src/muz/rel/dl_mk_simple_joins.h +++ b/src/muz/rel/dl_mk_simple_joins.h @@ -19,12 +19,12 @@ Revision History: #ifndef DL_MK_SIMPLE_JOINS_H_ #define DL_MK_SIMPLE_JOINS_H_ -#include"map.h" -#include"obj_pair_hashtable.h" +#include "util/map.h" +#include "util/obj_pair_hashtable.h" -#include"dl_context.h" -#include"dl_rule_set.h" -#include"dl_rule_transformer.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/rel/dl_product_relation.cpp b/src/muz/rel/dl_product_relation.cpp index 817ff194c..8a2029748 100644 --- a/src/muz/rel/dl_product_relation.cpp +++ b/src/muz/rel/dl_product_relation.cpp @@ -42,11 +42,11 @@ Notes: --*/ -#include "dl_sieve_relation.h" -#include "dl_table_relation.h" -#include "dl_product_relation.h" -#include "bool_rewriter.h" -#include "ast_pp.h" +#include "muz/rel/dl_sieve_relation.h" +#include "muz/rel/dl_table_relation.h" +#include "muz/rel/dl_product_relation.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/ast_pp.h" namespace datalog { diff --git a/src/muz/rel/dl_product_relation.h b/src/muz/rel/dl_product_relation.h index 6381fcf37..002fe5289 100644 --- a/src/muz/rel/dl_product_relation.h +++ b/src/muz/rel/dl_product_relation.h @@ -20,8 +20,8 @@ Revision History: #define DL_PRODUCT_RELATION_H_ -#include "dl_context.h" -#include "dl_relation_manager.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_relation_manager.h" namespace datalog { diff --git a/src/muz/rel/dl_relation_manager.cpp b/src/muz/rel/dl_relation_manager.cpp index 5bb47c5c3..1eb973776 100644 --- a/src/muz/rel/dl_relation_manager.cpp +++ b/src/muz/rel/dl_relation_manager.cpp @@ -19,14 +19,14 @@ Revision History: #include -#include"ast_pp.h" -#include"dl_check_table.h" -#include"dl_context.h" -#include"dl_finite_product_relation.h" -#include"dl_product_relation.h" -#include"dl_sieve_relation.h" -#include"dl_table_relation.h" -#include"dl_relation_manager.h" +#include "ast/ast_pp.h" +#include "muz/rel/dl_check_table.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_finite_product_relation.h" +#include "muz/rel/dl_product_relation.h" +#include "muz/rel/dl_sieve_relation.h" +#include "muz/rel/dl_table_relation.h" +#include "muz/rel/dl_relation_manager.h" namespace datalog { diff --git a/src/muz/rel/dl_relation_manager.h b/src/muz/rel/dl_relation_manager.h index a641a5fd2..c77127eb7 100644 --- a/src/muz/rel/dl_relation_manager.h +++ b/src/muz/rel/dl_relation_manager.h @@ -20,9 +20,9 @@ Revision History: #define DL_RELATION_MANAGER_H_ -#include"map.h" -#include"vector.h" -#include"dl_base.h" +#include "util/map.h" +#include "util/vector.h" +#include "muz/rel/dl_base.h" namespace datalog { diff --git a/src/muz/rel/dl_sieve_relation.cpp b/src/muz/rel/dl_sieve_relation.cpp index 7729ec2eb..0d70212e2 100644 --- a/src/muz/rel/dl_sieve_relation.cpp +++ b/src/muz/rel/dl_sieve_relation.cpp @@ -18,8 +18,8 @@ Revision History: --*/ #include -#include"ast_pp.h" -#include"dl_sieve_relation.h" +#include "ast/ast_pp.h" +#include "muz/rel/dl_sieve_relation.h" namespace datalog { diff --git a/src/muz/rel/dl_sieve_relation.h b/src/muz/rel/dl_sieve_relation.h index 4d89a66ae..021c9d8df 100644 --- a/src/muz/rel/dl_sieve_relation.h +++ b/src/muz/rel/dl_sieve_relation.h @@ -20,8 +20,8 @@ Revision History: #ifndef DL_SIEVE_RELATION_H_ #define DL_SIEVE_RELATION_H_ -#include "dl_context.h" -#include "dl_relation_manager.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_relation_manager.h" namespace datalog { diff --git a/src/muz/rel/dl_sparse_table.cpp b/src/muz/rel/dl_sparse_table.cpp index f045bee4b..6048f358b 100644 --- a/src/muz/rel/dl_sparse_table.cpp +++ b/src/muz/rel/dl_sparse_table.cpp @@ -18,9 +18,9 @@ Revision History: --*/ #include -#include"dl_context.h" -#include"dl_util.h" -#include"dl_sparse_table.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_util.h" +#include "muz/rel/dl_sparse_table.h" namespace datalog { diff --git a/src/muz/rel/dl_sparse_table.h b/src/muz/rel/dl_sparse_table.h index a45f4e6c6..a699cf165 100644 --- a/src/muz/rel/dl_sparse_table.h +++ b/src/muz/rel/dl_sparse_table.h @@ -24,15 +24,15 @@ Revision History: #include #include -#include "ast.h" -#include "bit_vector.h" -#include "buffer.h" -#include "hashtable.h" -#include "map.h" -#include "ref_vector.h" -#include "vector.h" +#include "ast/ast.h" +#include "util/bit_vector.h" +#include "util/buffer.h" +#include "util/hashtable.h" +#include "util/map.h" +#include "util/ref_vector.h" +#include "util/vector.h" -#include "dl_base.h" +#include "muz/rel/dl_base.h" namespace datalog { diff --git a/src/muz/rel/dl_table.cpp b/src/muz/rel/dl_table.cpp index 9df9dde5e..1c068a878 100644 --- a/src/muz/rel/dl_table.cpp +++ b/src/muz/rel/dl_table.cpp @@ -17,10 +17,10 @@ Revision History: --*/ -#include"dl_context.h" -#include"dl_util.h" -#include"dl_table.h" -#include"dl_relation_manager.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_util.h" +#include "muz/rel/dl_table.h" +#include "muz/rel/dl_relation_manager.h" namespace datalog { diff --git a/src/muz/rel/dl_table.h b/src/muz/rel/dl_table.h index d25aa31bc..c428191af 100644 --- a/src/muz/rel/dl_table.h +++ b/src/muz/rel/dl_table.h @@ -23,17 +23,17 @@ Revision History: #include #include -#include "ast.h" -#include "bit_vector.h" -#include "buffer.h" -#include "hashtable.h" -#include "map.h" -#include "ref_vector.h" -#include "vector.h" -#include "union_find.h" -#include "dl_base.h" -#include "dl_util.h" -#include "bit_vector.h" +#include "ast/ast.h" +#include "util/bit_vector.h" +#include "util/buffer.h" +#include "util/hashtable.h" +#include "util/map.h" +#include "util/ref_vector.h" +#include "util/vector.h" +#include "util/union_find.h" +#include "muz/rel/dl_base.h" +#include "muz/base/dl_util.h" +#include "util/bit_vector.h" namespace datalog { diff --git a/src/muz/rel/dl_table_plugin.h b/src/muz/rel/dl_table_plugin.h index 7765f54d3..9becc1773 100644 --- a/src/muz/rel/dl_table_plugin.h +++ b/src/muz/rel/dl_table_plugin.h @@ -19,9 +19,9 @@ Revision History: #ifndef DL_TABLE_PLUGIN_H_ #define DL_TABLE_PLUGIN_H_ -#include"ast.h" -#include"map.h" -#include"vector.h" +#include "ast/ast.h" +#include "util/map.h" +#include "util/vector.h" #include"dl_table_ops.h" diff --git a/src/muz/rel/dl_table_relation.cpp b/src/muz/rel/dl_table_relation.cpp index 00a25d169..d8f1c7314 100644 --- a/src/muz/rel/dl_table_relation.cpp +++ b/src/muz/rel/dl_table_relation.cpp @@ -19,9 +19,9 @@ Revision History: #include -#include"dl_context.h" -#include"dl_relation_manager.h" -#include"dl_table_relation.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/rel/dl_table_relation.h" namespace datalog { diff --git a/src/muz/rel/dl_table_relation.h b/src/muz/rel/dl_table_relation.h index 56ca509fa..16ff8c482 100644 --- a/src/muz/rel/dl_table_relation.h +++ b/src/muz/rel/dl_table_relation.h @@ -20,8 +20,8 @@ Revision History: #define DL_TABLE_RELATION_H_ -#include "dl_base.h" -#include "dl_util.h" +#include "muz/rel/dl_base.h" +#include "muz/base/dl_util.h" namespace datalog { diff --git a/src/muz/rel/dl_vector_relation.h b/src/muz/rel/dl_vector_relation.h index 040d23300..85e7a78d1 100644 --- a/src/muz/rel/dl_vector_relation.h +++ b/src/muz/rel/dl_vector_relation.h @@ -19,9 +19,9 @@ Revision History: #ifndef DL_VECTOR_RELATION_H_ #define DL_VECTOR_RELATION_H_ -#include "ast_pp.h" -#include "dl_context.h" -#include "union_find.h" +#include "ast/ast_pp.h" +#include "muz/base/dl_context.h" +#include "util/union_find.h" namespace datalog { diff --git a/src/muz/rel/doc.cpp b/src/muz/rel/doc.cpp index e73395bc9..23d24dfc3 100644 --- a/src/muz/rel/doc.cpp +++ b/src/muz/rel/doc.cpp @@ -20,12 +20,12 @@ Revision History: --*/ -#include "doc.h" -#include "smt_kernel.h" -#include "expr_safe_replace.h" -#include "smt_params.h" -#include "ast_util.h" -#include "ast_pp.h" +#include "muz/rel/doc.h" +#include "smt/smt_kernel.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "smt/params/smt_params.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" doc_manager::doc_manager(unsigned n): m(n), m_alloc("doc") { m_full = m.allocateX(); diff --git a/src/muz/rel/doc.h b/src/muz/rel/doc.h index 23b636cf9..419081892 100644 --- a/src/muz/rel/doc.h +++ b/src/muz/rel/doc.h @@ -23,9 +23,9 @@ Revision History: #ifndef DOC_H_ #define DOC_H_ -#include "tbv.h" -#include "union_find.h" -#include "buffer.h" +#include "muz/rel/tbv.h" +#include "util/union_find.h" +#include "util/buffer.h" class doc; diff --git a/src/muz/rel/karr_relation.cpp b/src/muz/rel/karr_relation.cpp index 0baa297bc..572d5e8d5 100644 --- a/src/muz/rel/karr_relation.cpp +++ b/src/muz/rel/karr_relation.cpp @@ -4,9 +4,9 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "karr_relation.h" -#include "bool_rewriter.h" -#include "ast_util.h" +#include "muz/rel/karr_relation.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/ast_util.h" namespace datalog { class karr_relation : public relation_base { diff --git a/src/muz/rel/karr_relation.h b/src/muz/rel/karr_relation.h index 8e5c09156..47e10f09e 100644 --- a/src/muz/rel/karr_relation.h +++ b/src/muz/rel/karr_relation.h @@ -19,8 +19,8 @@ Revision History: #ifndef KARR_RELATION_H_ #define KARR_RELATION_H_ -#include"dl_mk_karr_invariants.h" -#include"dl_relation_manager.h" +#include "muz/transforms/dl_mk_karr_invariants.h" +#include "muz/rel/dl_relation_manager.h" namespace datalog { diff --git a/src/muz/rel/rel_context.cpp b/src/muz/rel/rel_context.cpp index abaf88f32..9fb1e89e0 100644 --- a/src/muz/rel/rel_context.cpp +++ b/src/muz/rel/rel_context.cpp @@ -20,36 +20,36 @@ Revision History: --*/ -#include"rel_context.h" -#include"stopwatch.h" -#include"dl_context.h" -#include"dl_compiler.h" -#include"dl_instruction.h" -#include"dl_mk_explanations.h" -#include"dl_mk_magic_sets.h" -#include"dl_product_relation.h" -#include"dl_bound_relation.h" -#include"dl_interval_relation.h" -#include"karr_relation.h" -#include"dl_finite_product_relation.h" -#include"udoc_relation.h" -#include"check_relation.h" -#include"dl_lazy_table.h" -#include"dl_sparse_table.h" -#include"dl_table.h" -#include"dl_table_relation.h" -#include"aig_exporter.h" -#include"dl_mk_simple_joins.h" -#include"dl_mk_similarity_compressor.h" -#include"dl_mk_unbound_compressor.h" -#include"dl_mk_subsumption_checker.h" -#include"dl_mk_coi_filter.h" -#include"dl_mk_filter_rules.h" -#include"dl_mk_rule_inliner.h" -#include"dl_mk_interp_tail_simplifier.h" -#include"dl_mk_bit_blast.h" -#include"dl_mk_separate_negated_tails.h" -#include"ast_util.h" +#include "muz/rel/rel_context.h" +#include "util/stopwatch.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_compiler.h" +#include "muz/rel/dl_instruction.h" +#include "muz/rel/dl_mk_explanations.h" +#include "muz/transforms/dl_mk_magic_sets.h" +#include "muz/rel/dl_product_relation.h" +#include "muz/rel/dl_bound_relation.h" +#include "muz/rel/dl_interval_relation.h" +#include "muz/rel/karr_relation.h" +#include "muz/rel/dl_finite_product_relation.h" +#include "muz/rel/udoc_relation.h" +#include "muz/rel/check_relation.h" +#include "muz/rel/dl_lazy_table.h" +#include "muz/rel/dl_sparse_table.h" +#include "muz/rel/dl_table.h" +#include "muz/rel/dl_table_relation.h" +#include "muz/rel/aig_exporter.h" +#include "muz/rel/dl_mk_simple_joins.h" +#include "muz/rel/dl_mk_similarity_compressor.h" +#include "muz/transforms/dl_mk_unbound_compressor.h" +#include "muz/transforms/dl_mk_subsumption_checker.h" +#include "muz/transforms/dl_mk_coi_filter.h" +#include "muz/transforms/dl_mk_filter_rules.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" +#include "muz/transforms/dl_mk_bit_blast.h" +#include "muz/transforms/dl_mk_separate_negated_tails.h" +#include "ast/ast_util.h" namespace datalog { diff --git a/src/muz/rel/rel_context.h b/src/muz/rel/rel_context.h index c263ddc03..f4a87d496 100644 --- a/src/muz/rel/rel_context.h +++ b/src/muz/rel/rel_context.h @@ -20,12 +20,12 @@ Revision History: --*/ #ifndef REL_CONTEXT_H_ #define REL_CONTEXT_H_ -#include "ast.h" -#include "dl_relation_manager.h" -#include "dl_instruction.h" -#include "dl_engine_base.h" -#include "dl_context.h" -#include "lbool.h" +#include "ast/ast.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/rel/dl_instruction.h" +#include "muz/base/dl_engine_base.h" +#include "muz/base/dl_context.h" +#include "util/lbool.h" namespace datalog { diff --git a/src/muz/rel/tbv.cpp b/src/muz/rel/tbv.cpp index 568f63f51..7475750db 100644 --- a/src/muz/rel/tbv.cpp +++ b/src/muz/rel/tbv.cpp @@ -18,9 +18,9 @@ Revision History: --*/ -#include "tbv.h" -#include "hashtable.h" -#include "ast_util.h" +#include "muz/rel/tbv.h" +#include "util/hashtable.h" +#include "ast/ast_util.h" static bool s_debug_alloc = false; diff --git a/src/muz/rel/tbv.h b/src/muz/rel/tbv.h index e2e09d691..1839700d6 100644 --- a/src/muz/rel/tbv.h +++ b/src/muz/rel/tbv.h @@ -21,9 +21,9 @@ Revision History: #ifndef TBV_H_ #define TBV_H_ -#include "fixed_bit_vector.h" -#include "rational.h" -#include "ast.h" +#include "util/fixed_bit_vector.h" +#include "util/rational.h" +#include "ast/ast.h" class tbv; diff --git a/src/muz/rel/udoc_relation.cpp b/src/muz/rel/udoc_relation.cpp index 22e70a367..febabb36d 100644 --- a/src/muz/rel/udoc_relation.cpp +++ b/src/muz/rel/udoc_relation.cpp @@ -21,10 +21,10 @@ Revision History: Notes: --*/ -#include "udoc_relation.h" -#include "dl_relation_manager.h" -#include "ast_util.h" -#include "smt_kernel.h" +#include "muz/rel/udoc_relation.h" +#include "muz/rel/dl_relation_manager.h" +#include "ast/ast_util.h" +#include "smt/smt_kernel.h" namespace datalog { diff --git a/src/muz/rel/udoc_relation.h b/src/muz/rel/udoc_relation.h index 026abfab0..15918d80d 100644 --- a/src/muz/rel/udoc_relation.h +++ b/src/muz/rel/udoc_relation.h @@ -22,8 +22,8 @@ Revision History: #ifndef UDOC_RELATION_H_ #define UDOC_RELATION_H_ -#include "doc.h" -#include "dl_base.h" +#include "muz/rel/doc.h" +#include "muz/rel/dl_base.h" namespace datalog { class udoc_plugin; diff --git a/src/muz/tab/tab_context.cpp b/src/muz/tab/tab_context.cpp index 35eb5d936..8309f812e 100644 --- a/src/muz/tab/tab_context.cpp +++ b/src/muz/tab/tab_context.cpp @@ -17,21 +17,21 @@ Revision History: --*/ -#include "tab_context.h" -#include "trail.h" -#include "dl_rule_set.h" -#include "dl_context.h" -#include "dl_mk_rule_inliner.h" -#include "smt_kernel.h" -#include "qe_lite.h" -#include "bool_rewriter.h" -#include "th_rewriter.h" -#include "datatype_decl_plugin.h" -#include "for_each_expr.h" -#include "matcher.h" -#include "scoped_proof.h" +#include "muz/tab/tab_context.h" +#include "util/trail.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_context.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "smt/smt_kernel.h" +#include "qe/qe_lite.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/for_each_expr.h" +#include "ast/substitution/matcher.h" +#include "ast/scoped_proof.h" #include "fixedpoint_params.hpp" -#include "ast_util.h" +#include "ast/ast_util.h" namespace tb { diff --git a/src/muz/tab/tab_context.h b/src/muz/tab/tab_context.h index 703109475..329234524 100644 --- a/src/muz/tab/tab_context.h +++ b/src/muz/tab/tab_context.h @@ -19,10 +19,10 @@ Revision History: #ifndef TAB_CONTEXT_H_ #define TAB_CONTEXT_H_ -#include "ast.h" -#include "lbool.h" -#include "statistics.h" -#include "dl_engine_base.h" +#include "ast/ast.h" +#include "util/lbool.h" +#include "util/statistics.h" +#include "muz/base/dl_engine_base.h" namespace datalog { class context; diff --git a/src/muz/transforms/dl_mk_array_blast.cpp b/src/muz/transforms/dl_mk_array_blast.cpp index 031c5098e..373edcd4b 100644 --- a/src/muz/transforms/dl_mk_array_blast.cpp +++ b/src/muz/transforms/dl_mk_array_blast.cpp @@ -17,9 +17,9 @@ Revision History: --*/ -#include "dl_mk_array_blast.h" -#include "ast_util.h" -#include "scoped_proof.h" +#include "muz/transforms/dl_mk_array_blast.h" +#include "ast/ast_util.h" +#include "ast/scoped_proof.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_array_blast.h b/src/muz/transforms/dl_mk_array_blast.h index 0bec9ae14..e7b951168 100644 --- a/src/muz/transforms/dl_mk_array_blast.h +++ b/src/muz/transforms/dl_mk_array_blast.h @@ -19,13 +19,13 @@ Revision History: #ifndef DL_MK_ARRAY_BLAST_H_ #define DL_MK_ARRAY_BLAST_H_ -#include"dl_context.h" -#include"dl_rule_set.h" -#include"dl_rule_transformer.h" -#include"dl_mk_interp_tail_simplifier.h" -#include "equiv_proof_converter.h" -#include "array_decl_plugin.h" -#include "expr_safe_replace.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" +#include "tactic/equiv_proof_converter.h" +#include "ast/array_decl_plugin.h" +#include "ast/rewriter/expr_safe_replace.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_backwards.cpp b/src/muz/transforms/dl_mk_backwards.cpp index 771de0dc3..986367337 100644 --- a/src/muz/transforms/dl_mk_backwards.cpp +++ b/src/muz/transforms/dl_mk_backwards.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"dl_mk_backwards.h" -#include"dl_context.h" +#include "muz/transforms/dl_mk_backwards.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_backwards.h b/src/muz/transforms/dl_mk_backwards.h index 135f89a18..ca441fd0a 100644 --- a/src/muz/transforms/dl_mk_backwards.h +++ b/src/muz/transforms/dl_mk_backwards.h @@ -19,7 +19,7 @@ Revision History: #ifndef DL_MK_BACKWARDS_H_ #define DL_MK_BACKWARDS_H_ -#include"dl_rule_transformer.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_bit_blast.cpp b/src/muz/transforms/dl_mk_bit_blast.cpp index 98172f041..20baf66b6 100644 --- a/src/muz/transforms/dl_mk_bit_blast.cpp +++ b/src/muz/transforms/dl_mk_bit_blast.cpp @@ -17,16 +17,16 @@ Revision History: --*/ -#include "dl_mk_bit_blast.h" -#include "bit_blaster_rewriter.h" -#include "rewriter_def.h" -#include "ast_pp.h" -#include "expr_safe_replace.h" -#include "filter_model_converter.h" -#include "dl_mk_interp_tail_simplifier.h" +#include "muz/transforms/dl_mk_bit_blast.h" +#include "ast/rewriter/bit_blaster/bit_blaster_rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "tactic/filter_model_converter.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" #include "fixedpoint_params.hpp" -#include "scoped_proof.h" -#include "model_v2_pp.h" +#include "ast/scoped_proof.h" +#include "model/model_v2_pp.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_bit_blast.h b/src/muz/transforms/dl_mk_bit_blast.h index 8111e8849..31df57567 100644 --- a/src/muz/transforms/dl_mk_bit_blast.h +++ b/src/muz/transforms/dl_mk_bit_blast.h @@ -19,7 +19,7 @@ Revision History: #ifndef DL_MK_BIT_BLAST_H_ #define DL_MK_BIT_BLAST_H_ -#include"dl_rule_transformer.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_coalesce.cpp b/src/muz/transforms/dl_mk_coalesce.cpp index 7476a5655..670a65e21 100644 --- a/src/muz/transforms/dl_mk_coalesce.cpp +++ b/src/muz/transforms/dl_mk_coalesce.cpp @@ -26,8 +26,8 @@ Notes: --*/ -#include "dl_mk_coalesce.h" -#include "bool_rewriter.h" +#include "muz/transforms/dl_mk_coalesce.h" +#include "ast/rewriter/bool_rewriter.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_coalesce.h b/src/muz/transforms/dl_mk_coalesce.h index 9b4d009ae..47d702fbb 100644 --- a/src/muz/transforms/dl_mk_coalesce.h +++ b/src/muz/transforms/dl_mk_coalesce.h @@ -20,11 +20,11 @@ Revision History: #ifndef DL_MK_COALESCE_H_ #define DL_MK_COALESCE_H_ -#include"dl_context.h" -#include"dl_rule_set.h" -#include"uint_set.h" -#include"dl_rule_transformer.h" -#include"dl_mk_rule_inliner.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "util/uint_set.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/transforms/dl_mk_rule_inliner.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_coi_filter.cpp b/src/muz/transforms/dl_mk_coi_filter.cpp index 0f155f65b..31188bf43 100644 --- a/src/muz/transforms/dl_mk_coi_filter.cpp +++ b/src/muz/transforms/dl_mk_coi_filter.cpp @@ -17,11 +17,11 @@ Author: --*/ -#include "dl_mk_coi_filter.h" -#include "dataflow.h" -#include "reachability.h" -#include "ast_pp.h" -#include "extension_model_converter.h" +#include "muz/transforms/dl_mk_coi_filter.h" +#include "muz/dataflow/dataflow.h" +#include "muz/dataflow/reachability.h" +#include "ast/ast_pp.h" +#include "tactic/extension_model_converter.h" namespace datalog { rule_set * mk_coi_filter::operator()(rule_set const & source) { diff --git a/src/muz/transforms/dl_mk_coi_filter.h b/src/muz/transforms/dl_mk_coi_filter.h index 16abe2f52..c03308b6a 100644 --- a/src/muz/transforms/dl_mk_coi_filter.h +++ b/src/muz/transforms/dl_mk_coi_filter.h @@ -20,8 +20,8 @@ Author: #ifndef DL_MK_COI_FILTER_H_ #define DL_MK_COI_FILTER_H_ -#include "dl_rule_transformer.h" -#include "dl_context.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_different.h b/src/muz/transforms/dl_mk_different.h index 47a00edc0..2190d38cd 100644 --- a/src/muz/transforms/dl_mk_different.h +++ b/src/muz/transforms/dl_mk_different.h @@ -19,7 +19,7 @@ Revision History: #ifndef DL_MK_DIFFERENT_SYMBOLIC_H_ #define DL_MK_DIFFERENT_SYMBOLIC_H_ -#include"dl_rule_transformer.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_filter_rules.cpp b/src/muz/transforms/dl_mk_filter_rules.cpp index 0d118a589..a8c13fc17 100644 --- a/src/muz/transforms/dl_mk_filter_rules.cpp +++ b/src/muz/transforms/dl_mk_filter_rules.cpp @@ -17,10 +17,10 @@ Revision History: --*/ -#include"dl_mk_filter_rules.h" -#include"dl_context.h" -#include"for_each_expr.h" -#include"ast_pp.h" +#include "muz/transforms/dl_mk_filter_rules.h" +#include "muz/base/dl_context.h" +#include "ast/for_each_expr.h" +#include "ast/ast_pp.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_filter_rules.h b/src/muz/transforms/dl_mk_filter_rules.h index 60ee80e90..b81921d59 100644 --- a/src/muz/transforms/dl_mk_filter_rules.h +++ b/src/muz/transforms/dl_mk_filter_rules.h @@ -19,10 +19,10 @@ Revision History: #ifndef DL_MK_FILTER_RULES_H_ #define DL_MK_FILTER_RULES_H_ -#include"map.h" +#include "util/map.h" -#include"dl_rule_set.h" -#include"dl_rule_transformer.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp index 1ed847e89..64a2a2aca 100644 --- a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp +++ b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp @@ -19,13 +19,13 @@ Revision History: #include -#include"ast_pp.h" -#include"bool_rewriter.h" -#include"rewriter.h" -#include"rewriter_def.h" -#include"dl_mk_rule_inliner.h" -#include"dl_mk_interp_tail_simplifier.h" -#include"ast_util.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" +#include "ast/ast_util.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_interp_tail_simplifier.h b/src/muz/transforms/dl_mk_interp_tail_simplifier.h index 568fcff3f..a8a7393cd 100644 --- a/src/muz/transforms/dl_mk_interp_tail_simplifier.h +++ b/src/muz/transforms/dl_mk_interp_tail_simplifier.h @@ -20,11 +20,11 @@ Revision History: #ifndef DL_MK_INTERP_TAIL_SIMPLIFIER_H_ #define DL_MK_INTERP_TAIL_SIMPLIFIER_H_ -#include "dl_context.h" -#include "dl_rule_transformer.h" -#include "unifier.h" -#include "substitution.h" -#include "arith_decl_plugin.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_transformer.h" +#include "ast/substitution/unifier.h" +#include "ast/substitution/substitution.h" +#include "ast/arith_decl_plugin.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_karr_invariants.cpp b/src/muz/transforms/dl_mk_karr_invariants.cpp index 99b1c0aea..48219eeb9 100644 --- a/src/muz/transforms/dl_mk_karr_invariants.cpp +++ b/src/muz/transforms/dl_mk_karr_invariants.cpp @@ -32,13 +32,13 @@ Revision History: --*/ -#include"expr_safe_replace.h" -#include"bool_rewriter.h" -#include"for_each_expr.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/for_each_expr.h" -#include"dl_mk_karr_invariants.h" -#include"dl_mk_backwards.h" -#include"dl_mk_loop_counter.h" +#include "muz/transforms/dl_mk_karr_invariants.h" +#include "muz/transforms/dl_mk_backwards.h" +#include "muz/transforms/dl_mk_loop_counter.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_karr_invariants.h b/src/muz/transforms/dl_mk_karr_invariants.h index bf0ba9021..b31f1f8d9 100644 --- a/src/muz/transforms/dl_mk_karr_invariants.h +++ b/src/muz/transforms/dl_mk_karr_invariants.h @@ -19,11 +19,11 @@ Revision History: #ifndef DL_MK_KARR_INVARIANTS_H_ #define DL_MK_KARR_INVARIANTS_H_ -#include"dl_context.h" -#include"dl_rule_set.h" -#include"dl_rule_transformer.h" -#include"arith_decl_plugin.h" -#include"hilbert_basis.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_rule_transformer.h" +#include "ast/arith_decl_plugin.h" +#include "math/hilbert/hilbert_basis.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_loop_counter.cpp b/src/muz/transforms/dl_mk_loop_counter.cpp index f97670ad0..62568640c 100644 --- a/src/muz/transforms/dl_mk_loop_counter.cpp +++ b/src/muz/transforms/dl_mk_loop_counter.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"dl_mk_loop_counter.h" -#include"dl_context.h" +#include "muz/transforms/dl_mk_loop_counter.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_loop_counter.h b/src/muz/transforms/dl_mk_loop_counter.h index 6694ffb52..fb4b6d704 100644 --- a/src/muz/transforms/dl_mk_loop_counter.h +++ b/src/muz/transforms/dl_mk_loop_counter.h @@ -19,8 +19,8 @@ Revision History: #ifndef DL_MK_LOOP_COUNTER_H_ #define DL_MK_LOOP_COUNTER_H_ -#include"dl_rule_transformer.h" -#include"arith_decl_plugin.h" +#include "muz/base/dl_rule_transformer.h" +#include "ast/arith_decl_plugin.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_magic_sets.cpp b/src/muz/transforms/dl_mk_magic_sets.cpp index 19dccf417..15a4c1093 100644 --- a/src/muz/transforms/dl_mk_magic_sets.cpp +++ b/src/muz/transforms/dl_mk_magic_sets.cpp @@ -19,8 +19,8 @@ Revision History: #include #include -#include"ast_pp.h" -#include"dl_mk_magic_sets.h" +#include "ast/ast_pp.h" +#include "muz/transforms/dl_mk_magic_sets.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_magic_sets.h b/src/muz/transforms/dl_mk_magic_sets.h index f71af3649..eef40fd71 100644 --- a/src/muz/transforms/dl_mk_magic_sets.h +++ b/src/muz/transforms/dl_mk_magic_sets.h @@ -21,12 +21,12 @@ Revision History: #include -#include"map.h" -#include"obj_pair_hashtable.h" +#include "util/map.h" +#include "util/obj_pair_hashtable.h" -#include"dl_context.h" -#include"dl_rule_set.h" -#include"dl_rule_transformer.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_magic_symbolic.cpp b/src/muz/transforms/dl_mk_magic_symbolic.cpp index 1d269cff0..2edc57375 100644 --- a/src/muz/transforms/dl_mk_magic_symbolic.cpp +++ b/src/muz/transforms/dl_mk_magic_symbolic.cpp @@ -52,8 +52,8 @@ Revision History: --*/ -#include"dl_mk_magic_symbolic.h" -#include"dl_context.h" +#include "muz/transforms/dl_mk_magic_symbolic.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_magic_symbolic.h b/src/muz/transforms/dl_mk_magic_symbolic.h index db3137c90..9c51a5287 100644 --- a/src/muz/transforms/dl_mk_magic_symbolic.h +++ b/src/muz/transforms/dl_mk_magic_symbolic.h @@ -19,7 +19,7 @@ Revision History: #ifndef DL_MK_MAGIC_SYMBOLIC_H_ #define DL_MK_MAGIC_SYMBOLIC_H_ -#include"dl_rule_transformer.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp index a22a67416..d2195a8d9 100644 --- a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp +++ b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp @@ -19,10 +19,10 @@ Revision History: --*/ -#include "dl_mk_quantifier_abstraction.h" -#include "dl_context.h" -#include "expr_safe_replace.h" -#include "expr_abstract.h" +#include "muz/transforms/dl_mk_quantifier_abstraction.h" +#include "muz/base/dl_context.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/expr_abstract.h" #include"fixedpoint_params.hpp" diff --git a/src/muz/transforms/dl_mk_quantifier_abstraction.h b/src/muz/transforms/dl_mk_quantifier_abstraction.h index d4a588127..593e458b9 100644 --- a/src/muz/transforms/dl_mk_quantifier_abstraction.h +++ b/src/muz/transforms/dl_mk_quantifier_abstraction.h @@ -26,8 +26,8 @@ Revision History: #define DL_MK_QUANTIFIER_ABSTRACTION_H_ -#include"dl_rule_transformer.h" -#include"array_decl_plugin.h" +#include "muz/base/dl_rule_transformer.h" +#include "ast/array_decl_plugin.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp index 586c52cd6..7eb2284c0 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp @@ -23,9 +23,9 @@ Revision History: --*/ -#include "dl_mk_quantifier_instantiation.h" -#include "dl_context.h" -#include "pattern_inference.h" +#include "muz/transforms/dl_mk_quantifier_instantiation.h" +#include "muz/base/dl_context.h" +#include "ast/pattern/pattern_inference.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.h b/src/muz/transforms/dl_mk_quantifier_instantiation.h index b9ef5189e..4f1626ec6 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.h +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.h @@ -26,9 +26,9 @@ Revision History: #define DL_MK_QUANTIFIER_INSTANTIATION_H_ -#include "dl_rule_transformer.h" -#include "expr_safe_replace.h" -#include "union_find.h" +#include "muz/base/dl_rule_transformer.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "util/union_find.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_rule_inliner.cpp b/src/muz/transforms/dl_mk_rule_inliner.cpp index c6b3e8be7..1c7a6b219 100644 --- a/src/muz/transforms/dl_mk_rule_inliner.cpp +++ b/src/muz/transforms/dl_mk_rule_inliner.cpp @@ -48,10 +48,10 @@ Subsumption transformation (remove rule): #include -#include "ast_pp.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "dl_mk_rule_inliner.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "muz/transforms/dl_mk_rule_inliner.h" #include "fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_mk_rule_inliner.h b/src/muz/transforms/dl_mk_rule_inliner.h index 66d17fdc8..55b9b9487 100644 --- a/src/muz/transforms/dl_mk_rule_inliner.h +++ b/src/muz/transforms/dl_mk_rule_inliner.h @@ -20,12 +20,12 @@ Revision History: #ifndef DL_MK_RULE_INLINER_H_ #define DL_MK_RULE_INLINER_H_ -#include "dl_context.h" -#include "dl_rule_transformer.h" -#include "dl_mk_interp_tail_simplifier.h" -#include "unifier.h" -#include "substitution.h" -#include "substitution_tree.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" +#include "ast/substitution/unifier.h" +#include "ast/substitution/substitution.h" +#include "ast/substitution/substitution_tree.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_scale.cpp b/src/muz/transforms/dl_mk_scale.cpp index 271bf5f62..cc6321b31 100644 --- a/src/muz/transforms/dl_mk_scale.cpp +++ b/src/muz/transforms/dl_mk_scale.cpp @@ -16,8 +16,8 @@ Revision History: --*/ -#include"dl_mk_scale.h" -#include"dl_context.h" +#include "muz/transforms/dl_mk_scale.h" +#include "muz/base/dl_context.h" #include"fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_mk_scale.h b/src/muz/transforms/dl_mk_scale.h index 0e4ccf7ea..10a5ea8b2 100644 --- a/src/muz/transforms/dl_mk_scale.h +++ b/src/muz/transforms/dl_mk_scale.h @@ -21,8 +21,8 @@ Revision History: #ifndef DL_MK_SCALE_H_ #define DL_MK_SCALE_H_ -#include"dl_rule_transformer.h" -#include"arith_decl_plugin.h" +#include "muz/base/dl_rule_transformer.h" +#include "ast/arith_decl_plugin.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_separate_negated_tails.cpp b/src/muz/transforms/dl_mk_separate_negated_tails.cpp index 9a78c0d4d..3da759f9b 100644 --- a/src/muz/transforms/dl_mk_separate_negated_tails.cpp +++ b/src/muz/transforms/dl_mk_separate_negated_tails.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include "dl_mk_separate_negated_tails.h" -#include "dl_context.h" +#include "muz/transforms/dl_mk_separate_negated_tails.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_separate_negated_tails.h b/src/muz/transforms/dl_mk_separate_negated_tails.h index 1d2e57e2c..a5cdda003 100644 --- a/src/muz/transforms/dl_mk_separate_negated_tails.h +++ b/src/muz/transforms/dl_mk_separate_negated_tails.h @@ -32,8 +32,8 @@ Revision History: #ifndef DL_MK_SEPARAT_NEGATED_TAILS_H_ #define DL_MK_SEPARAT_NEGATED_TAILS_H_ -#include "dl_rule_transformer.h" -#include "dl_context.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/base/dl_context.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_slice.cpp b/src/muz/transforms/dl_mk_slice.cpp index cefda74e8..c094e5520 100644 --- a/src/muz/transforms/dl_mk_slice.cpp +++ b/src/muz/transforms/dl_mk_slice.cpp @@ -50,12 +50,12 @@ Revision History: --*/ -#include "dl_mk_slice.h" -#include "ast_pp.h" -#include "ast_util.h" -#include "expr_functors.h" -#include "dl_mk_rule_inliner.h" -#include "model_smt2_pp.h" +#include "muz/transforms/dl_mk_slice.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "ast/expr_functors.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "model/model_smt2_pp.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_slice.h b/src/muz/transforms/dl_mk_slice.h index b1b9cb46e..4a7d4a81a 100644 --- a/src/muz/transforms/dl_mk_slice.h +++ b/src/muz/transforms/dl_mk_slice.h @@ -19,10 +19,10 @@ Revision History: #ifndef DL_MK_SLICE_H_ #define DL_MK_SLICE_H_ -#include"dl_context.h" -#include"dl_rule_set.h" -#include"uint_set.h" -#include"dl_rule_transformer.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "util/uint_set.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_subsumption_checker.cpp b/src/muz/transforms/dl_mk_subsumption_checker.cpp index 8fae4ee35..6a3ea8735 100644 --- a/src/muz/transforms/dl_mk_subsumption_checker.cpp +++ b/src/muz/transforms/dl_mk_subsumption_checker.cpp @@ -20,10 +20,10 @@ Revision History: #include -#include"ast_pp.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include"dl_mk_subsumption_checker.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "muz/transforms/dl_mk_subsumption_checker.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_subsumption_checker.h b/src/muz/transforms/dl_mk_subsumption_checker.h index 270418508..01d828d6e 100644 --- a/src/muz/transforms/dl_mk_subsumption_checker.h +++ b/src/muz/transforms/dl_mk_subsumption_checker.h @@ -21,9 +21,9 @@ Revision History: #ifndef DL_MK_SUBSUMPTION_CHECKER_H_ #define DL_MK_SUBSUMPTION_CHECKER_H_ -#include "dl_context.h" -#include "dl_rule_transformer.h" -#include "dl_rule_subsumption_index.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/base/dl_rule_subsumption_index.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_unbound_compressor.cpp b/src/muz/transforms/dl_mk_unbound_compressor.cpp index 78133aab7..47ce20a76 100644 --- a/src/muz/transforms/dl_mk_unbound_compressor.cpp +++ b/src/muz/transforms/dl_mk_unbound_compressor.cpp @@ -19,7 +19,7 @@ Revision History: #include #include -#include"dl_mk_unbound_compressor.h" +#include "muz/transforms/dl_mk_unbound_compressor.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_unbound_compressor.h b/src/muz/transforms/dl_mk_unbound_compressor.h index 51ac1fda8..febb4bd46 100644 --- a/src/muz/transforms/dl_mk_unbound_compressor.h +++ b/src/muz/transforms/dl_mk_unbound_compressor.h @@ -21,12 +21,12 @@ Revision History: #include -#include"map.h" -#include"obj_pair_hashtable.h" +#include "util/map.h" +#include "util/obj_pair_hashtable.h" -#include"dl_context.h" -#include"dl_rule_set.h" -#include"dl_rule_transformer.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_rule_transformer.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_unfold.cpp b/src/muz/transforms/dl_mk_unfold.cpp index cc460bca1..c9b8becde 100644 --- a/src/muz/transforms/dl_mk_unfold.cpp +++ b/src/muz/transforms/dl_mk_unfold.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include "dl_mk_unfold.h" +#include "muz/transforms/dl_mk_unfold.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_unfold.h b/src/muz/transforms/dl_mk_unfold.h index 554ed69e0..8ebe2d328 100644 --- a/src/muz/transforms/dl_mk_unfold.h +++ b/src/muz/transforms/dl_mk_unfold.h @@ -19,11 +19,11 @@ Revision History: #ifndef DL_MK_UNFOLD_H_ #define DL_MK_UNFOLD_H_ -#include"dl_context.h" -#include"dl_rule_set.h" -#include"uint_set.h" -#include"dl_rule_transformer.h" -#include"dl_mk_rule_inliner.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_rule_set.h" +#include "util/uint_set.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/transforms/dl_mk_rule_inliner.h" namespace datalog { diff --git a/src/muz/transforms/dl_transforms.cpp b/src/muz/transforms/dl_transforms.cpp index 81f9d6f64..48e956979 100644 --- a/src/muz/transforms/dl_transforms.cpp +++ b/src/muz/transforms/dl_transforms.cpp @@ -19,20 +19,20 @@ Revision History: --*/ -#include"dl_transforms.h" -#include"dl_rule_transformer.h" -#include"dl_mk_coi_filter.h" -#include"dl_mk_filter_rules.h" -#include"dl_mk_interp_tail_simplifier.h" -#include"dl_mk_rule_inliner.h" -#include"dl_mk_bit_blast.h" -#include"dl_mk_array_blast.h" -#include"dl_mk_karr_invariants.h" -#include"dl_mk_magic_symbolic.h" -#include"dl_mk_quantifier_abstraction.h" -#include"dl_mk_quantifier_instantiation.h" -#include"dl_mk_subsumption_checker.h" -#include"dl_mk_scale.h" +#include "muz/transforms/dl_transforms.h" +#include "muz/base/dl_rule_transformer.h" +#include "muz/transforms/dl_mk_coi_filter.h" +#include "muz/transforms/dl_mk_filter_rules.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "muz/transforms/dl_mk_bit_blast.h" +#include "muz/transforms/dl_mk_array_blast.h" +#include "muz/transforms/dl_mk_karr_invariants.h" +#include "muz/transforms/dl_mk_magic_symbolic.h" +#include "muz/transforms/dl_mk_quantifier_abstraction.h" +#include "muz/transforms/dl_mk_quantifier_instantiation.h" +#include "muz/transforms/dl_mk_subsumption_checker.h" +#include "muz/transforms/dl_mk_scale.h" #include"fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_transforms.h b/src/muz/transforms/dl_transforms.h index 71131c99f..df34d2c1d 100644 --- a/src/muz/transforms/dl_transforms.h +++ b/src/muz/transforms/dl_transforms.h @@ -21,7 +21,7 @@ Revision History: #ifndef DL_TRANSFORMS_H_ #define DL_TRANSFORMS_H_ -#include "dl_context.h" +#include "muz/base/dl_context.h" namespace datalog { void apply_default_transformation(context& ctx); diff --git a/src/nlsat/nlsat_assignment.h b/src/nlsat/nlsat_assignment.h index a52a84f3b..097ad76b6 100644 --- a/src/nlsat/nlsat_assignment.h +++ b/src/nlsat/nlsat_assignment.h @@ -19,8 +19,8 @@ Revision History: #ifndef NLSAT_ASSIGNMENT_H_ #define NLSAT_ASSIGNMENT_H_ -#include"nlsat_types.h" -#include"algebraic_numbers.h" +#include "nlsat/nlsat_types.h" +#include "math/polynomial/algebraic_numbers.h" namespace nlsat { diff --git a/src/nlsat/nlsat_clause.cpp b/src/nlsat/nlsat_clause.cpp index b83485ba3..a64ec2856 100644 --- a/src/nlsat/nlsat_clause.cpp +++ b/src/nlsat/nlsat_clause.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"nlsat_clause.h" +#include "nlsat/nlsat_clause.h" namespace nlsat { diff --git a/src/nlsat/nlsat_clause.h b/src/nlsat/nlsat_clause.h index 95928eb1a..898c32449 100644 --- a/src/nlsat/nlsat_clause.h +++ b/src/nlsat/nlsat_clause.h @@ -19,8 +19,8 @@ Revision History: #ifndef NLSAT_CLAUSE_H_ #define NLSAT_CLAUSE_H_ -#include"nlsat_types.h" -#include"vector.h" +#include "nlsat/nlsat_types.h" +#include "util/vector.h" namespace nlsat { diff --git a/src/nlsat/nlsat_evaluator.cpp b/src/nlsat/nlsat_evaluator.cpp index db18d8854..a93c4fb3e 100644 --- a/src/nlsat/nlsat_evaluator.cpp +++ b/src/nlsat/nlsat_evaluator.cpp @@ -17,8 +17,8 @@ Author: Revision History: --*/ -#include"nlsat_evaluator.h" -#include"nlsat_solver.h" +#include "nlsat/nlsat_evaluator.h" +#include "nlsat/nlsat_solver.h" namespace nlsat { diff --git a/src/nlsat/nlsat_evaluator.h b/src/nlsat/nlsat_evaluator.h index a82ce79fb..e43eec80a 100644 --- a/src/nlsat/nlsat_evaluator.h +++ b/src/nlsat/nlsat_evaluator.h @@ -20,9 +20,9 @@ Revision History: #ifndef NLSAT_EVALUATOR_H_ #define NLSAT_EVALUATOR_H_ -#include"nlsat_types.h" -#include"nlsat_assignment.h" -#include"nlsat_interval_set.h" +#include "nlsat/nlsat_types.h" +#include "nlsat/nlsat_assignment.h" +#include "nlsat/nlsat_interval_set.h" namespace nlsat { diff --git a/src/nlsat/nlsat_explain.cpp b/src/nlsat/nlsat_explain.cpp index 5d9491da2..3a6c3f067 100644 --- a/src/nlsat/nlsat_explain.cpp +++ b/src/nlsat/nlsat_explain.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"nlsat_explain.h" -#include"nlsat_assignment.h" -#include"nlsat_evaluator.h" -#include"algebraic_numbers.h" -#include"ref_buffer.h" +#include "nlsat/nlsat_explain.h" +#include "nlsat/nlsat_assignment.h" +#include "nlsat/nlsat_evaluator.h" +#include "math/polynomial/algebraic_numbers.h" +#include "util/ref_buffer.h" namespace nlsat { diff --git a/src/nlsat/nlsat_explain.h b/src/nlsat/nlsat_explain.h index 4309a0090..37580e7bc 100644 --- a/src/nlsat/nlsat_explain.h +++ b/src/nlsat/nlsat_explain.h @@ -19,10 +19,10 @@ Revision History: #ifndef NLSAT_EXPLAIN_H_ #define NLSAT_EXPLAIN_H_ -#include"nlsat_solver.h" -#include"nlsat_scoped_literal_vector.h" -#include"polynomial_cache.h" -#include"algebraic_numbers.h" +#include "nlsat/nlsat_solver.h" +#include "nlsat/nlsat_scoped_literal_vector.h" +#include "math/polynomial/polynomial_cache.h" +#include "math/polynomial/algebraic_numbers.h" namespace nlsat { class evaluator; diff --git a/src/nlsat/nlsat_interval_set.cpp b/src/nlsat/nlsat_interval_set.cpp index 44e1128d1..2028095f4 100644 --- a/src/nlsat/nlsat_interval_set.cpp +++ b/src/nlsat/nlsat_interval_set.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"nlsat_interval_set.h" -#include"algebraic_numbers.h" -#include"buffer.h" +#include "nlsat/nlsat_interval_set.h" +#include "math/polynomial/algebraic_numbers.h" +#include "util/buffer.h" namespace nlsat { diff --git a/src/nlsat/nlsat_interval_set.h b/src/nlsat/nlsat_interval_set.h index a308c8637..24b2ab37f 100644 --- a/src/nlsat/nlsat_interval_set.h +++ b/src/nlsat/nlsat_interval_set.h @@ -19,7 +19,7 @@ Revision History: #ifndef NLSAT_INTERVAL_SET_H_ #define NLSAT_INTERVAL_SET_H_ -#include"nlsat_types.h" +#include "nlsat/nlsat_types.h" namespace nlsat { diff --git a/src/nlsat/nlsat_justification.h b/src/nlsat/nlsat_justification.h index b226dc522..13759e035 100644 --- a/src/nlsat/nlsat_justification.h +++ b/src/nlsat/nlsat_justification.h @@ -20,8 +20,8 @@ Revision History: #ifndef NLSAT_JUSTIFICATION_H_ #define NLSAT_JUSTIFICATION_H_ -#include"nlsat_types.h" -#include"tptr.h" +#include "nlsat/nlsat_types.h" +#include "util/tptr.h" namespace nlsat { diff --git a/src/nlsat/nlsat_scoped_literal_vector.h b/src/nlsat/nlsat_scoped_literal_vector.h index 442853377..61760f06d 100644 --- a/src/nlsat/nlsat_scoped_literal_vector.h +++ b/src/nlsat/nlsat_scoped_literal_vector.h @@ -20,7 +20,7 @@ Revision History: #ifndef NLSAT_SCOPED_LITERAL_VECTOR_H_ #define NLSAT_SCOPED_LITERAL_VECTOR_H_ -#include"nlsat_solver.h" +#include "nlsat/nlsat_solver.h" namespace nlsat { diff --git a/src/nlsat/nlsat_solver.cpp b/src/nlsat/nlsat_solver.cpp index 7582c8389..2e32e2fbd 100644 --- a/src/nlsat/nlsat_solver.cpp +++ b/src/nlsat/nlsat_solver.cpp @@ -18,19 +18,19 @@ Author: Revision History: --*/ -#include"nlsat_solver.h" -#include"nlsat_clause.h" -#include"nlsat_assignment.h" -#include"nlsat_justification.h" -#include"nlsat_evaluator.h" -#include"nlsat_explain.h" -#include"algebraic_numbers.h" -#include"z3_exception.h" -#include"chashtable.h" -#include"id_gen.h" -#include"dependency.h" -#include"polynomial_cache.h" -#include"permutation.h" +#include "nlsat/nlsat_solver.h" +#include "nlsat/nlsat_clause.h" +#include "nlsat/nlsat_assignment.h" +#include "nlsat/nlsat_justification.h" +#include "nlsat/nlsat_evaluator.h" +#include "nlsat/nlsat_explain.h" +#include "math/polynomial/algebraic_numbers.h" +#include "util/z3_exception.h" +#include "util/chashtable.h" +#include "util/id_gen.h" +#include "util/dependency.h" +#include "math/polynomial/polynomial_cache.h" +#include "util/permutation.h" #include"nlsat_params.hpp" #define NLSAT_EXTRA_VERBOSE diff --git a/src/nlsat/nlsat_solver.h b/src/nlsat/nlsat_solver.h index 3668629cd..ac503c603 100644 --- a/src/nlsat/nlsat_solver.h +++ b/src/nlsat/nlsat_solver.h @@ -21,10 +21,10 @@ Revision History: #ifndef NLSAT_SOLVER_H_ #define NLSAT_SOLVER_H_ -#include"nlsat_types.h" -#include"params.h" -#include"statistics.h" -#include"rlimit.h" +#include "nlsat/nlsat_types.h" +#include "util/params.h" +#include "util/statistics.h" +#include "util/rlimit.h" namespace nlsat { diff --git a/src/nlsat/nlsat_types.cpp b/src/nlsat/nlsat_types.cpp index 956be4c5e..dbf7ab360 100644 --- a/src/nlsat/nlsat_types.cpp +++ b/src/nlsat/nlsat_types.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"nlsat_types.h" -#include"debug.h" -#include"hash.h" -#include"polynomial.h" +#include "nlsat/nlsat_types.h" +#include "util/debug.h" +#include "util/hash.h" +#include "math/polynomial/polynomial.h" namespace nlsat { diff --git a/src/nlsat/nlsat_types.h b/src/nlsat/nlsat_types.h index 11e063a17..8704f4444 100644 --- a/src/nlsat/nlsat_types.h +++ b/src/nlsat/nlsat_types.h @@ -19,10 +19,10 @@ Revision History: #ifndef NLSAT_TYPES_H_ #define NLSAT_TYPES_H_ -#include"polynomial.h" -#include"buffer.h" -#include"sat_types.h" -#include"z3_exception.h" +#include "math/polynomial/polynomial.h" +#include "util/buffer.h" +#include "sat/sat_types.h" +#include "util/z3_exception.h" namespace algebraic_numbers { class anum; diff --git a/src/nlsat/tactic/goal2nlsat.cpp b/src/nlsat/tactic/goal2nlsat.cpp index a76cd1213..6d7e1c767 100644 --- a/src/nlsat/tactic/goal2nlsat.cpp +++ b/src/nlsat/tactic/goal2nlsat.cpp @@ -21,17 +21,17 @@ Author: Notes: --*/ -#include"goal2nlsat.h" -#include"goal.h" -#include"goal_util.h" -#include"nlsat_solver.h" -#include"expr2polynomial.h" -#include"expr2var.h" -#include"arith_decl_plugin.h" -#include"tactic.h" -#include"ast_pp.h" -#include"polynomial.h" -#include"algebraic_numbers.h" +#include "nlsat/tactic/goal2nlsat.h" +#include "tactic/goal.h" +#include "tactic/goal_util.h" +#include "nlsat/nlsat_solver.h" +#include "ast/expr2polynomial.h" +#include "ast/expr2var.h" +#include "ast/arith_decl_plugin.h" +#include "tactic/tactic.h" +#include "ast/ast_pp.h" +#include "math/polynomial/polynomial.h" +#include "math/polynomial/algebraic_numbers.h" struct goal2nlsat::imp { struct nlsat_expr2polynomial : public expr2polynomial { diff --git a/src/nlsat/tactic/goal2nlsat.h b/src/nlsat/tactic/goal2nlsat.h index bdb71a6a3..58d85946e 100644 --- a/src/nlsat/tactic/goal2nlsat.h +++ b/src/nlsat/tactic/goal2nlsat.h @@ -24,8 +24,8 @@ Notes: #ifndef GOAL2NLSAT_H_ #define GOAL2NLSAT_H_ -#include"nlsat_types.h" -#include"model_converter.h" +#include "nlsat/nlsat_types.h" +#include "tactic/model_converter.h" class goal; class expr2var; diff --git a/src/nlsat/tactic/nlsat_tactic.cpp b/src/nlsat/tactic/nlsat_tactic.cpp index 4ecdade38..510f503e7 100644 --- a/src/nlsat/tactic/nlsat_tactic.cpp +++ b/src/nlsat/tactic/nlsat_tactic.cpp @@ -16,16 +16,16 @@ Author: Notes: --*/ -#include"tactical.h" -#include"goal2nlsat.h" -#include"nlsat_solver.h" -#include"model.h" -#include"expr2var.h" -#include"arith_decl_plugin.h" -#include"ast_smt2_pp.h" -#include"z3_exception.h" -#include"algebraic_numbers.h" -#include"ast_pp.h" +#include "tactic/tactical.h" +#include "nlsat/tactic/goal2nlsat.h" +#include "nlsat/nlsat_solver.h" +#include "model/model.h" +#include "ast/expr2var.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_smt2_pp.h" +#include "util/z3_exception.h" +#include "math/polynomial/algebraic_numbers.h" +#include "ast/ast_pp.h" class nlsat_tactic : public tactic { struct expr_display_var_proc : public nlsat::display_var_proc { diff --git a/src/nlsat/tactic/nlsat_tactic.h b/src/nlsat/tactic/nlsat_tactic.h index 5f0022026..fe7737c4b 100644 --- a/src/nlsat/tactic/nlsat_tactic.h +++ b/src/nlsat/tactic/nlsat_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef NLSAT_TACTIC_H_ #define NLSAT_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/nlsat/tactic/qfnra_nlsat_tactic.cpp b/src/nlsat/tactic/qfnra_nlsat_tactic.cpp index b05636541..22f64af47 100644 --- a/src/nlsat/tactic/qfnra_nlsat_tactic.cpp +++ b/src/nlsat/tactic/qfnra_nlsat_tactic.cpp @@ -16,18 +16,18 @@ Author: Notes: --*/ -#include"tactical.h" +#include "tactic/tactical.h" -#include"tseitin_cnf_tactic.h" -#include"degree_shift_tactic.h" -#include"purify_arith_tactic.h" -#include"nlsat_tactic.h" -#include"factor_tactic.h" -#include"simplify_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"propagate_values_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_term_ite_tactic.h" +#include "tactic/core/tseitin_cnf_tactic.h" +#include "tactic/arith/degree_shift_tactic.h" +#include "tactic/arith/purify_arith_tactic.h" +#include "nlsat/tactic/nlsat_tactic.h" +#include "tactic/arith/factor_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_term_ite_tactic.h" tactic * mk_qfnra_nlsat_tactic(ast_manager & m, params_ref const & p) { params_ref main_p = p; diff --git a/src/nlsat/tactic/qfnra_nlsat_tactic.h b/src/nlsat/tactic/qfnra_nlsat_tactic.h index fa106ca93..b1a4d8392 100644 --- a/src/nlsat/tactic/qfnra_nlsat_tactic.h +++ b/src/nlsat/tactic/qfnra_nlsat_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFNRA_NLSAT_TACTIC_H_ #define QFNRA_NLSAT_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/opt/maxres.cpp b/src/opt/maxres.cpp index 7e9381e1d..cbde02009 100644 --- a/src/opt/maxres.cpp +++ b/src/opt/maxres.cpp @@ -52,18 +52,18 @@ Notes: --*/ -#include "solver.h" -#include "maxsmt.h" -#include "maxres.h" -#include "ast_pp.h" -#include "mus.h" -#include "mss.h" -#include "inc_sat_solver.h" -#include "opt_context.h" -#include "pb_decl_plugin.h" +#include "solver/solver.h" +#include "opt/maxsmt.h" +#include "opt/maxres.h" +#include "ast/ast_pp.h" +#include "solver/mus.h" +#include "opt/mss.h" +#include "sat/sat_solver/inc_sat_solver.h" +#include "opt/opt_context.h" +#include "ast/pb_decl_plugin.h" #include "opt_params.hpp" -#include "ast_util.h" -#include "smt_solver.h" +#include "ast/ast_util.h" +#include "smt/smt_solver.h" using namespace opt; diff --git a/src/opt/maxsmt.cpp b/src/opt/maxsmt.cpp index f93291599..8df6c04a6 100644 --- a/src/opt/maxsmt.cpp +++ b/src/opt/maxsmt.cpp @@ -18,16 +18,16 @@ Notes: --*/ #include -#include "maxsmt.h" -#include "maxres.h" -#include "wmax.h" -#include "ast_pp.h" -#include "uint_set.h" -#include "opt_context.h" -#include "theory_wmaxsat.h" -#include "theory_pb.h" -#include "ast_util.h" -#include "pb_decl_plugin.h" +#include "opt/maxsmt.h" +#include "opt/maxres.h" +#include "opt/wmax.h" +#include "ast/ast_pp.h" +#include "util/uint_set.h" +#include "opt/opt_context.h" +#include "smt/theory_wmaxsat.h" +#include "smt/theory_pb.h" +#include "ast/ast_util.h" +#include "ast/pb_decl_plugin.h" namespace opt { diff --git a/src/opt/maxsmt.h b/src/opt/maxsmt.h index 358ff4995..0541a9a88 100644 --- a/src/opt/maxsmt.h +++ b/src/opt/maxsmt.h @@ -19,15 +19,15 @@ Notes: #ifndef OPT_MAXSMT_H_ #define OPT_MAXSMT_H_ -#include"ast.h" -#include"params.h" -#include"solver.h" -#include"filter_model_converter.h" -#include"statistics.h" -#include"smt_context.h" -#include"smt_theory.h" -#include"theory_wmaxsat.h" -#include"opt_solver.h" +#include "ast/ast.h" +#include "util/params.h" +#include "solver/solver.h" +#include "tactic/filter_model_converter.h" +#include "util/statistics.h" +#include "smt/smt_context.h" +#include "smt/smt_theory.h" +#include "smt/theory_wmaxsat.h" +#include "opt/opt_solver.h" namespace opt { diff --git a/src/opt/mss.cpp b/src/opt/mss.cpp index 863834b85..cc0fa8d7d 100644 --- a/src/opt/mss.cpp +++ b/src/opt/mss.cpp @@ -18,10 +18,10 @@ Notes: --*/ -#include "solver.h" -#include "mss.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" +#include "solver/solver.h" +#include "opt/mss.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" namespace opt { diff --git a/src/opt/opt_cmds.cpp b/src/opt/opt_cmds.cpp index 0264a6a24..d88b0a406 100644 --- a/src/opt/opt_cmds.cpp +++ b/src/opt/opt_cmds.cpp @@ -21,16 +21,16 @@ Notes: - Deal with push/pop (later) --*/ -#include "opt_cmds.h" -#include "cmd_context.h" -#include "ast_pp.h" -#include "opt_context.h" -#include "cancel_eh.h" -#include "scoped_ctrl_c.h" -#include "scoped_timer.h" -#include "parametric_cmd.h" +#include "opt/opt_cmds.h" +#include "cmd_context/cmd_context.h" +#include "ast/ast_pp.h" +#include "opt/opt_context.h" +#include "util/cancel_eh.h" +#include "util/scoped_ctrl_c.h" +#include "util/scoped_timer.h" +#include "cmd_context/parametric_cmd.h" #include "opt_params.hpp" -#include "model_smt2_pp.h" +#include "model/model_smt2_pp.h" static opt::context& get_opt(cmd_context& cmd, opt::context* opt) { if (opt) { diff --git a/src/opt/opt_cmds.h b/src/opt/opt_cmds.h index f0da778df..60f83d201 100644 --- a/src/opt/opt_cmds.h +++ b/src/opt/opt_cmds.h @@ -18,8 +18,8 @@ Notes: #ifndef OPT_CMDS_H_ #define OPT_CMDS_H_ -#include "ast.h" -#include "opt_context.h" +#include "ast/ast.h" +#include "opt/opt_context.h" class cmd_context; diff --git a/src/opt/opt_context.cpp b/src/opt/opt_context.cpp index 0e1c150c0..beba8a60b 100644 --- a/src/opt/opt_context.cpp +++ b/src/opt/opt_context.cpp @@ -17,32 +17,32 @@ Notes: --*/ -#include "opt_context.h" -#include "ast_pp.h" -#include "opt_solver.h" +#include "opt/opt_context.h" +#include "ast/ast_pp.h" +#include "opt/opt_solver.h" #include "opt_params.hpp" -#include "for_each_expr.h" -#include "goal.h" -#include "tactic.h" -#include "lia2card_tactic.h" -#include "elim01_tactic.h" -#include "solve_eqs_tactic.h" -#include "simplify_tactic.h" -#include "propagate_values_tactic.h" -#include "solve_eqs_tactic.h" -#include "elim_uncnstr_tactic.h" -#include "tactical.h" -#include "model_smt2_pp.h" -#include "card2bv_tactic.h" -#include "eq2bv_tactic.h" -#include "dt2bv_tactic.h" -#include "inc_sat_solver.h" -#include "bv_decl_plugin.h" -#include "pb_decl_plugin.h" -#include "ast_smt_pp.h" -#include "filter_model_converter.h" -#include "ast_pp_util.h" -#include "qsat.h" +#include "ast/for_each_expr.h" +#include "tactic/goal.h" +#include "tactic/tactic.h" +#include "tactic/arith/lia2card_tactic.h" +#include "tactic/arith/elim01_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "tactic/tactical.h" +#include "model/model_smt2_pp.h" +#include "tactic/arith/card2bv_tactic.h" +#include "tactic/arith/eq2bv_tactic.h" +#include "tactic/bv/dt2bv_tactic.h" +#include "sat/sat_solver/inc_sat_solver.h" +#include "ast/bv_decl_plugin.h" +#include "ast/pb_decl_plugin.h" +#include "ast/ast_smt_pp.h" +#include "tactic/filter_model_converter.h" +#include "ast/ast_pp_util.h" +#include "qe/qsat.h" namespace opt { diff --git a/src/opt/opt_context.h b/src/opt/opt_context.h index 66f0ef015..ad40db074 100644 --- a/src/opt/opt_context.h +++ b/src/opt/opt_context.h @@ -18,17 +18,17 @@ Notes: #ifndef OPT_CONTEXT_H_ #define OPT_CONTEXT_H_ -#include "ast.h" -#include "opt_solver.h" -#include "opt_pareto.h" -#include "optsmt.h" -#include "maxsmt.h" -#include "model_converter.h" -#include "tactic.h" -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "cmd_context.h" -#include "qsat.h" +#include "ast/ast.h" +#include "opt/opt_solver.h" +#include "opt/opt_pareto.h" +#include "opt/optsmt.h" +#include "opt/maxsmt.h" +#include "tactic/model_converter.h" +#include "tactic/tactic.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "cmd_context/cmd_context.h" +#include "qe/qsat.h" namespace opt { diff --git a/src/opt/opt_pareto.cpp b/src/opt/opt_pareto.cpp index 1418eb0f9..026d10abc 100644 --- a/src/opt/opt_pareto.cpp +++ b/src/opt/opt_pareto.cpp @@ -18,9 +18,9 @@ Notes: --*/ -#include "opt_pareto.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" +#include "opt/opt_pareto.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" namespace opt { diff --git a/src/opt/opt_pareto.h b/src/opt/opt_pareto.h index 25b327045..c0ccc93da 100644 --- a/src/opt/opt_pareto.h +++ b/src/opt/opt_pareto.h @@ -20,8 +20,8 @@ Notes: #ifndef OPT_PARETO_H_ #define OPT_PARETO_H_ -#include "solver.h" -#include "model.h" +#include "solver/solver.h" +#include "model/model.h" namespace opt { diff --git a/src/opt/opt_sls_solver.h b/src/opt/opt_sls_solver.h index 5b7f630b4..a736c77a2 100644 --- a/src/opt/opt_sls_solver.h +++ b/src/opt/opt_sls_solver.h @@ -20,11 +20,11 @@ Notes: #ifndef OPT_SLS_SOLVER_H_ #define OPT_SLS_SOLVER_H_ -#include "solver_na2as.h" -#include "card2bv_tactic.h" -#include "nnf_tactic.h" -#include "pb_sls.h" -#include "bvsls_opt_engine.h" +#include "solver/solver_na2as.h" +#include "tactic/arith/card2bv_tactic.h" +#include "tactic/core/nnf_tactic.h" +#include "opt/pb_sls.h" +#include "tactic/sls/bvsls_opt_engine.h" namespace opt { diff --git a/src/opt/opt_solver.cpp b/src/opt/opt_solver.cpp index 458a5c540..0c7a14065 100644 --- a/src/opt/opt_solver.cpp +++ b/src/opt/opt_solver.cpp @@ -19,20 +19,20 @@ Notes: --*/ #include -#include "reg_decl_plugins.h" -#include "opt_solver.h" -#include "smt_context.h" -#include "theory_arith.h" -#include "theory_diff_logic.h" -#include "theory_dense_diff_logic.h" -#include "theory_pb.h" -#include "theory_lra.h" -#include "ast_pp.h" -#include "ast_smt_pp.h" +#include "ast/reg_decl_plugins.h" +#include "opt/opt_solver.h" +#include "smt/smt_context.h" +#include "smt/theory_arith.h" +#include "smt/theory_diff_logic.h" +#include "smt/theory_dense_diff_logic.h" +#include "smt/theory_pb.h" +#include "smt/theory_lra.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt_pp.h" #include "pp_params.hpp" #include "opt_params.hpp" -#include "model_smt2_pp.h" -#include "stopwatch.h" +#include "model/model_smt2_pp.h" +#include "util/stopwatch.h" namespace opt { diff --git a/src/opt/opt_solver.h b/src/opt/opt_solver.h index 27168e2ca..4bd23c120 100644 --- a/src/opt/opt_solver.h +++ b/src/opt/opt_solver.h @@ -21,16 +21,16 @@ Notes: #ifndef OPT_SOLVER_H_ #define OPT_SOLVER_H_ -#include"inf_rational.h" -#include"inf_eps_rational.h" -#include"ast.h" -#include"params.h" -#include"solver_na2as.h" -#include"smt_kernel.h" -#include"smt_params.h" -#include"smt_types.h" -#include"theory_opt.h" -#include"filter_model_converter.h" +#include "util/inf_rational.h" +#include "util/inf_eps_rational.h" +#include "ast/ast.h" +#include "util/params.h" +#include "solver/solver_na2as.h" +#include "smt/smt_kernel.h" +#include "smt/params/smt_params.h" +#include "smt/smt_types.h" +#include "smt/theory_opt.h" +#include "tactic/filter_model_converter.h" namespace opt { diff --git a/src/opt/optsmt.cpp b/src/opt/optsmt.cpp index d2363b36e..3c8e31e59 100644 --- a/src/opt/optsmt.cpp +++ b/src/opt/optsmt.cpp @@ -29,14 +29,14 @@ Notes: --*/ #include -#include "optsmt.h" -#include "opt_solver.h" -#include "arith_decl_plugin.h" -#include "theory_arith.h" -#include "ast_pp.h" -#include "ast_util.h" -#include "model_pp.h" -#include "th_rewriter.h" +#include "opt/optsmt.h" +#include "opt/opt_solver.h" +#include "ast/arith_decl_plugin.h" +#include "smt/theory_arith.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "model/model_pp.h" +#include "ast/rewriter/th_rewriter.h" #include "opt_params.hpp" namespace opt { diff --git a/src/opt/optsmt.h b/src/opt/optsmt.h index f90bd1c81..921352898 100644 --- a/src/opt/optsmt.h +++ b/src/opt/optsmt.h @@ -19,7 +19,7 @@ Notes: #ifndef OPTSMT_H_ #define OPTSMT_H_ -#include "opt_solver.h" +#include "opt/opt_solver.h" namespace opt { /** diff --git a/src/opt/pb_sls.cpp b/src/opt/pb_sls.cpp index 32c144652..e28c3cd3d 100644 --- a/src/opt/pb_sls.cpp +++ b/src/opt/pb_sls.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include "pb_sls.h" -#include "smt_literal.h" -#include "ast_pp.h" -#include "th_rewriter.h" -#include "sat_types.h" +#include "opt/pb_sls.h" +#include "smt/smt_literal.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "sat/sat_types.h" namespace smt { diff --git a/src/opt/pb_sls.h b/src/opt/pb_sls.h index 0ed7e30cc..f83057ce5 100644 --- a/src/opt/pb_sls.h +++ b/src/opt/pb_sls.h @@ -19,11 +19,11 @@ Notes: #ifndef PB_SLS_H_ #define PB_SLS_H_ -#include "pb_decl_plugin.h" -#include "model.h" -#include "lbool.h" -#include "params.h" -#include "statistics.h" +#include "ast/pb_decl_plugin.h" +#include "model/model.h" +#include "util/lbool.h" +#include "util/params.h" +#include "util/statistics.h" namespace smt { diff --git a/src/opt/sortmax.cpp b/src/opt/sortmax.cpp index e3cf59de4..00cab488c 100644 --- a/src/opt/sortmax.cpp +++ b/src/opt/sortmax.cpp @@ -16,15 +16,15 @@ Author: Notes: --*/ -#include "maxsmt.h" -#include "uint_set.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" -#include "smt_theory.h" -#include "smt_context.h" -#include "opt_context.h" -#include "sorting_network.h" -#include "filter_model_converter.h" +#include "opt/maxsmt.h" +#include "util/uint_set.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" +#include "smt/smt_theory.h" +#include "smt/smt_context.h" +#include "opt/opt_context.h" +#include "util/sorting_network.h" +#include "tactic/filter_model_converter.h" namespace opt { diff --git a/src/opt/wmax.cpp b/src/opt/wmax.cpp index 15b723c8c..afc0334eb 100644 --- a/src/opt/wmax.cpp +++ b/src/opt/wmax.cpp @@ -16,14 +16,14 @@ Author: Notes: --*/ -#include "wmax.h" -#include "uint_set.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" -#include "smt_theory.h" -#include "smt_context.h" -#include "theory_wmaxsat.h" -#include "opt_context.h" +#include "opt/wmax.h" +#include "util/uint_set.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" +#include "smt/smt_theory.h" +#include "smt/smt_context.h" +#include "smt/theory_wmaxsat.h" +#include "opt/opt_context.h" namespace opt { // ---------------------------------------------------------- diff --git a/src/opt/wmax.h b/src/opt/wmax.h index 3d9d206ad..aabbe3a64 100644 --- a/src/opt/wmax.h +++ b/src/opt/wmax.h @@ -20,7 +20,7 @@ Notes: #ifndef WMAX_H_ #define WMAX_H_ -#include "maxsmt.h" +#include "opt/maxsmt.h" namespace opt { maxsmt_solver_base* mk_wmax(maxsat_context& c, weights_t & ws, expr_ref_vector const& soft); diff --git a/src/parsers/smt/smtlib.cpp b/src/parsers/smt/smtlib.cpp index b743b5b0f..71dd48156 100644 --- a/src/parsers/smt/smtlib.cpp +++ b/src/parsers/smt/smtlib.cpp @@ -5,9 +5,9 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include"smtlib.h" -#include"ast_pp.h" -#include"ast_smt2_pp.h" +#include "parsers/smt/smtlib.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" #ifdef _WINDOWS #ifdef ARRAYSIZE diff --git a/src/parsers/smt/smtlib.h b/src/parsers/smt/smtlib.h index 62799ea25..f037e3d74 100644 --- a/src/parsers/smt/smtlib.h +++ b/src/parsers/smt/smtlib.h @@ -19,10 +19,10 @@ Revision History: #ifndef SMTLIB_H_ #define SMTLIB_H_ -#include "ast.h" -#include "symbol_table.h" -#include "map.h" -#include "arith_decl_plugin.h" +#include "ast/ast.h" +#include "util/symbol_table.h" +#include "util/map.h" +#include "ast/arith_decl_plugin.h" namespace smtlib { diff --git a/src/parsers/smt/smtlib_solver.cpp b/src/parsers/smt/smtlib_solver.cpp index 7c8572ad8..128b9de88 100644 --- a/src/parsers/smt/smtlib_solver.cpp +++ b/src/parsers/smt/smtlib_solver.cpp @@ -17,17 +17,17 @@ Revision History: --*/ -#include"smtparser.h" -#include"smtlib_solver.h" -#include"warning.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"well_sorted.h" -#include"model.h" -#include"model_v2_pp.h" -#include"solver.h" -#include"smt_strategic_solver.h" -#include"cmd_context.h" +#include "parsers/smt/smtparser.h" +#include "parsers/smt/smtlib_solver.h" +#include "util/warning.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/well_sorted.h" +#include "model/model.h" +#include "model/model_v2_pp.h" +#include "solver/solver.h" +#include "tactic/portfolio/smt_strategic_solver.h" +#include "cmd_context/cmd_context.h" #include"model_params.hpp" #include"parser_params.hpp" diff --git a/src/parsers/smt/smtlib_solver.h b/src/parsers/smt/smtlib_solver.h index fce5ff67f..6288c360b 100644 --- a/src/parsers/smt/smtlib_solver.h +++ b/src/parsers/smt/smtlib_solver.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMTLIB_SOLVER_H_ #define SMTLIB_SOLVER_H_ -#include"smtparser.h" -#include"context_params.h" -#include"lbool.h" +#include "parsers/smt/smtparser.h" +#include "cmd_context/context_params.h" +#include "util/lbool.h" class cmd_context; diff --git a/src/parsers/smt/smtparser.cpp b/src/parsers/smt/smtparser.cpp index c9b20850c..15f094e33 100644 --- a/src/parsers/smt/smtparser.cpp +++ b/src/parsers/smt/smtparser.cpp @@ -21,23 +21,23 @@ Revision History: #include #include #include -#include"region.h" -#include"scanner.h" -#include"symbol.h" -#include"vector.h" -#include"symbol_table.h" -#include"smtlib.h" -#include"smtparser.h" -#include"ast_pp.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"warning.h" -#include"error_codes.h" -#include"pattern_validation.h" -#include"var_subst.h" -#include"well_sorted.h" -#include"str_hashtable.h" -#include"stopwatch.h" +#include "util/region.h" +#include "parsers/util/scanner.h" +#include "util/symbol.h" +#include "util/vector.h" +#include "util/symbol_table.h" +#include "parsers/smt/smtlib.h" +#include "parsers/smt/smtparser.h" +#include "ast/ast_pp.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "util/warning.h" +#include "util/error_codes.h" +#include "parsers/util/pattern_validation.h" +#include "ast/rewriter/var_subst.h" +#include "ast/well_sorted.h" +#include "util/str_hashtable.h" +#include "util/stopwatch.h" class id_param_info { symbol m_string; diff --git a/src/parsers/smt/smtparser.h b/src/parsers/smt/smtparser.h index 9a09d1f4f..d8999e8ab 100644 --- a/src/parsers/smt/smtparser.h +++ b/src/parsers/smt/smtparser.h @@ -20,9 +20,9 @@ Revision History: #define SMT_PARSER_H_ #include -#include"ast.h" -#include"vector.h" -#include"smtlib.h" +#include "ast/ast.h" +#include "util/vector.h" +#include "parsers/smt/smtlib.h" namespace smtlib { class parser { diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index c948389ee..46c719487 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -16,19 +16,19 @@ Author: Revision History: --*/ -#include"smt2parser.h" -#include"smt2scanner.h" -#include"stack.h" -#include"datatype_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"seq_decl_plugin.h" -#include"ast_pp.h" -#include"well_sorted.h" -#include"pattern_validation.h" -#include"rewriter.h" -#include"has_free_vars.h" -#include"ast_smt2_pp.h" +#include "parsers/smt2/smt2parser.h" +#include "parsers/smt2/smt2scanner.h" +#include "util/stack.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/seq_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/well_sorted.h" +#include "parsers/util/pattern_validation.h" +#include "ast/rewriter/rewriter.h" +#include "ast/has_free_vars.h" +#include "ast/ast_smt2_pp.h" #include"parser_params.hpp" #include diff --git a/src/parsers/smt2/smt2parser.h b/src/parsers/smt2/smt2parser.h index 77fd41d5d..0976fc5f4 100644 --- a/src/parsers/smt2/smt2parser.h +++ b/src/parsers/smt2/smt2parser.h @@ -19,7 +19,7 @@ Revision History: #ifndef SMT2_PARSER_H_ #define SMT2_PARSER_H_ -#include"cmd_context.h" +#include "cmd_context/cmd_context.h" bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive = false, params_ref const & p = params_ref(), char const * filename = 0); diff --git a/src/parsers/smt2/smt2scanner.cpp b/src/parsers/smt2/smt2scanner.cpp index 1763a4fa5..b31440faf 100644 --- a/src/parsers/smt2/smt2scanner.cpp +++ b/src/parsers/smt2/smt2scanner.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"smt2scanner.h" +#include "parsers/smt2/smt2scanner.h" #include"parser_params.hpp" namespace smt2 { diff --git a/src/parsers/smt2/smt2scanner.h b/src/parsers/smt2/smt2scanner.h index 3ad47dfb1..5283c57cf 100644 --- a/src/parsers/smt2/smt2scanner.h +++ b/src/parsers/smt2/smt2scanner.h @@ -20,10 +20,10 @@ Revision History: #define SMT2SCANNER_H_ #include -#include"symbol.h" -#include"vector.h" -#include"rational.h" -#include"cmd_context.h" +#include "util/symbol.h" +#include "util/vector.h" +#include "util/rational.h" +#include "cmd_context/cmd_context.h" namespace smt2 { diff --git a/src/parsers/util/cost_parser.cpp b/src/parsers/util/cost_parser.cpp index a13e9b107..765b8ade9 100644 --- a/src/parsers/util/cost_parser.cpp +++ b/src/parsers/util/cost_parser.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"cost_parser.h" +#include "parsers/util/cost_parser.h" cost_parser::cost_parser(ast_manager & m): simple_parser(m), diff --git a/src/parsers/util/cost_parser.h b/src/parsers/util/cost_parser.h index 37e9ea3a1..f0330d824 100644 --- a/src/parsers/util/cost_parser.h +++ b/src/parsers/util/cost_parser.h @@ -19,8 +19,8 @@ Revision History: #ifndef COST_PARSER_H_ #define COST_PARSER_H_ -#include"simple_parser.h" -#include"arith_decl_plugin.h" +#include "parsers/util/simple_parser.h" +#include "ast/arith_decl_plugin.h" class cost_parser : public simple_parser { arith_util m_util; diff --git a/src/parsers/util/pattern_validation.cpp b/src/parsers/util/pattern_validation.cpp index 0e90e8126..0d076aadd 100644 --- a/src/parsers/util/pattern_validation.cpp +++ b/src/parsers/util/pattern_validation.cpp @@ -17,11 +17,11 @@ Revision History: --*/ -#include"pattern_validation.h" -#include"for_each_expr.h" -#include"warning.h" +#include "parsers/util/pattern_validation.h" +#include "ast/for_each_expr.h" +#include "util/warning.h" -#include"ast_pp.h" +#include "ast/ast_pp.h" struct pattern_validation_functor { uint_set & m_found_vars; diff --git a/src/parsers/util/pattern_validation.h b/src/parsers/util/pattern_validation.h index 939781936..11656e1df 100644 --- a/src/parsers/util/pattern_validation.h +++ b/src/parsers/util/pattern_validation.h @@ -19,9 +19,9 @@ Revision History: #ifndef PATTERN_VALIDATION_H_ #define PATTERN_VALIDATION_H_ -#include"ast.h" -#include"uint_set.h" -#include"vector.h" +#include "ast/ast.h" +#include "util/uint_set.h" +#include "util/vector.h" class pattern_validator { family_id m_bfid; diff --git a/src/parsers/util/scanner.cpp b/src/parsers/util/scanner.cpp index 690c068e4..4ed47e81f 100644 --- a/src/parsers/util/scanner.cpp +++ b/src/parsers/util/scanner.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"scanner.h" +#include "parsers/util/scanner.h" inline char scanner::read_char() { if (m_is_interactive) { diff --git a/src/parsers/util/scanner.h b/src/parsers/util/scanner.h index f434da164..cd074479c 100644 --- a/src/parsers/util/scanner.h +++ b/src/parsers/util/scanner.h @@ -19,7 +19,7 @@ Revision History: #ifndef SCANNER_H_ #define SCANNER_H_ -#include"ast.h" +#include "ast/ast.h" class scanner { public: diff --git a/src/parsers/util/simple_parser.cpp b/src/parsers/util/simple_parser.cpp index 045a45b24..770da9dbb 100644 --- a/src/parsers/util/simple_parser.cpp +++ b/src/parsers/util/simple_parser.cpp @@ -18,9 +18,9 @@ Revision History: --*/ #include #include -#include"simple_parser.h" -#include"warning.h" -#include"scanner.h" +#include "parsers/util/simple_parser.h" +#include "util/warning.h" +#include "parsers/util/scanner.h" simple_parser::simple_parser(ast_manager & m): m_manager(m), diff --git a/src/parsers/util/simple_parser.h b/src/parsers/util/simple_parser.h index 8589f140b..671412579 100644 --- a/src/parsers/util/simple_parser.h +++ b/src/parsers/util/simple_parser.h @@ -19,8 +19,8 @@ Revision History: #ifndef SIMPLE_PARSER_H_ #define SIMPLE_PARSER_H_ -#include"ast.h" -#include"map.h" +#include "ast/ast.h" +#include "util/map.h" class scanner; diff --git a/src/qe/nlarith_util.cpp b/src/qe/nlarith_util.cpp index b7c1aef5d..1da5ef52a 100644 --- a/src/qe/nlarith_util.cpp +++ b/src/qe/nlarith_util.cpp @@ -4,15 +4,15 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ast.h" -#include "nlarith_util.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" -#include "qe.h" -#include "expr_replacer.h" -#include "arith_rewriter.h" -#include "arith_simplifier_plugin.h" -#include "expr_functors.h" +#include "ast/ast.h" +#include "qe/nlarith_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "qe/qe.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/expr_functors.h" namespace nlarith { diff --git a/src/qe/nlarith_util.h b/src/qe/nlarith_util.h index 5854088ab..7106d2a27 100644 --- a/src/qe/nlarith_util.h +++ b/src/qe/nlarith_util.h @@ -20,8 +20,8 @@ Notes: #ifndef NLARITH_UTIL_H_ #define NLARITH_UTIL_H_ -#include "ast.h" -#include "lbool.h" +#include "ast/ast.h" +#include "util/lbool.h" namespace nlarith { diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index fbff2e583..a10971165 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -18,22 +18,22 @@ Revision History: --*/ -#include "nlqsat.h" -#include "nlsat_solver.h" -#include "nlsat_explain.h" -#include "nlsat_assignment.h" -#include "qsat.h" -#include "quant_hoist.h" -#include "goal2nlsat.h" -#include "expr2var.h" -#include "uint_set.h" -#include "ast_util.h" -#include "tseitin_cnf_tactic.h" -#include "expr_safe_replace.h" -#include "ast_pp.h" -#include "for_each_expr.h" -#include "rewriter.h" -#include "rewriter_def.h" +#include "qe/nlqsat.h" +#include "nlsat/nlsat_solver.h" +#include "nlsat/nlsat_explain.h" +#include "nlsat/nlsat_assignment.h" +#include "qe/qsat.h" +#include "ast/rewriter/quant_hoist.h" +#include "nlsat/tactic/goal2nlsat.h" +#include "ast/expr2var.h" +#include "util/uint_set.h" +#include "ast/ast_util.h" +#include "tactic/core/tseitin_cnf_tactic.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/ast_pp.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" namespace qe { diff --git a/src/qe/nlqsat.h b/src/qe/nlqsat.h index 9d0cb6af4..25cee55e3 100644 --- a/src/qe/nlqsat.h +++ b/src/qe/nlqsat.h @@ -21,7 +21,7 @@ Revision History: #ifndef QE_NLQSAT_H__ #define QE_NLQSAT_H__ -#include "tactic.h" +#include "tactic/tactic.h" tactic * mk_nlqsat_tactic(ast_manager & m, params_ref const& p = params_ref()); diff --git a/src/qe/qe.cpp b/src/qe/qe.cpp index 4bf3c1580..7c7250c40 100644 --- a/src/qe/qe.cpp +++ b/src/qe/qe.cpp @@ -18,33 +18,33 @@ Revision History: --*/ -#include "qe.h" -#include "smt_theory.h" -#include "bv_decl_plugin.h" -#include "smt_context.h" -#include "theory_bv.h" -#include "ast_ll_pp.h" -#include "ast_pp.h" -#include "ast_smt_pp.h" -#include "expr_abstract.h" -#include "var_subst.h" -#include "for_each_expr.h" -#include "dl_decl_plugin.h" -#include "nlarith_util.h" -#include "expr_replacer.h" -#include "factor_rewriter.h" -#include "expr_functors.h" -#include "quant_hoist.h" -#include "bool_rewriter.h" -#include "th_rewriter.h" -#include "smt_kernel.h" -#include "model_evaluator.h" -#include "has_free_vars.h" -#include "rewriter_def.h" -#include "cooperate.h" -#include "tactical.h" -#include "model_v2_pp.h" -#include "obj_hashtable.h" +#include "qe/qe.h" +#include "smt/smt_theory.h" +#include "ast/bv_decl_plugin.h" +#include "smt/smt_context.h" +#include "smt/theory_bv.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt_pp.h" +#include "ast/expr_abstract.h" +#include "ast/rewriter/var_subst.h" +#include "ast/for_each_expr.h" +#include "ast/dl_decl_plugin.h" +#include "qe/nlarith_util.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/factor_rewriter.h" +#include "ast/expr_functors.h" +#include "ast/rewriter/quant_hoist.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/th_rewriter.h" +#include "smt/smt_kernel.h" +#include "model/model_evaluator.h" +#include "ast/has_free_vars.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/cooperate.h" +#include "tactic/tactical.h" +#include "model/model_v2_pp.h" +#include "util/obj_hashtable.h" namespace qe { diff --git a/src/qe/qe.h b/src/qe/qe.h index a75af19c5..392bfb03b 100644 --- a/src/qe/qe.h +++ b/src/qe/qe.h @@ -21,15 +21,15 @@ Revision History: #ifndef QE_H_ #define QE_H_ -#include "ast.h" -#include "smt_params.h" -#include "statistics.h" -#include "lbool.h" -#include "expr_functors.h" -#include "simplifier.h" -#include "rewriter.h" -#include "model.h" -#include "params.h" +#include "ast/ast.h" +#include "smt/params/smt_params.h" +#include "util/statistics.h" +#include "util/lbool.h" +#include "ast/expr_functors.h" +#include "ast/simplifier/simplifier.h" +#include "ast/rewriter/rewriter.h" +#include "model/model.h" +#include "util/params.h" namespace qe { diff --git a/src/qe/qe_arith.cpp b/src/qe/qe_arith.cpp index 4490d83db..9b3033397 100644 --- a/src/qe/qe_arith.cpp +++ b/src/qe/qe_arith.cpp @@ -19,17 +19,17 @@ Revision History: --*/ -#include "qe_arith.h" -#include "qe_mbp.h" -#include "ast_util.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" -#include "model_v2_pp.h" -#include "th_rewriter.h" -#include "expr_functors.h" -#include "expr_safe_replace.h" -#include "model_based_opt.h" -#include "model_evaluator.h" +#include "qe/qe_arith.h" +#include "qe/qe_mbp.h" +#include "ast/ast_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "model/model_v2_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/expr_functors.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "math/simplex/model_based_opt.h" +#include "model/model_evaluator.h" namespace qe { diff --git a/src/qe/qe_arith.h b/src/qe/qe_arith.h index 616d1a8d0..88675d5a4 100644 --- a/src/qe/qe_arith.h +++ b/src/qe/qe_arith.h @@ -8,9 +8,9 @@ Copyright (c) 2015 Microsoft Corporation #ifndef QE_ARITH_H_ #define QE_ARITH_H_ -#include "model.h" -#include "arith_decl_plugin.h" -#include "qe_mbp.h" +#include "model/model.h" +#include "ast/arith_decl_plugin.h" +#include "qe/qe_mbp.h" namespace qe { diff --git a/src/qe/qe_arith_plugin.cpp b/src/qe/qe_arith_plugin.cpp index d8ae75256..1085ec3c2 100644 --- a/src/qe/qe_arith_plugin.cpp +++ b/src/qe/qe_arith_plugin.cpp @@ -18,21 +18,21 @@ Revision History: --*/ -#include "qe.h" -#include "ast_pp.h" -#include "expr_safe_replace.h" -#include "bool_rewriter.h" -#include "bv_decl_plugin.h" -#include "arith_decl_plugin.h" -#include "arith_eq_solver.h" -#include "arith_rewriter.h" -#include "th_rewriter.h" -#include "factor_rewriter.h" -#include "obj_pair_hashtable.h" -#include "nlarith_util.h" -#include "model_evaluator.h" -#include "smt_kernel.h" -#include "qe_arith.h" +#include "qe/qe.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "smt/arith_eq_solver.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/factor_rewriter.h" +#include "util/obj_pair_hashtable.h" +#include "qe/nlarith_util.h" +#include "model/model_evaluator.h" +#include "smt/smt_kernel.h" +#include "qe/qe_arith.h" namespace qe { diff --git a/src/qe/qe_array_plugin.cpp b/src/qe/qe_array_plugin.cpp index e7cbe65b9..9eeccd6a4 100644 --- a/src/qe/qe_array_plugin.cpp +++ b/src/qe/qe_array_plugin.cpp @@ -5,11 +5,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "qe.h" -#include "array_decl_plugin.h" -#include "expr_safe_replace.h" -#include "ast_pp.h" -#include "arith_decl_plugin.h" +#include "qe/qe.h" +#include "ast/array_decl_plugin.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" namespace qe { // --------------------- diff --git a/src/qe/qe_arrays.cpp b/src/qe/qe_arrays.cpp index a010c4ae4..6d0bf82bf 100644 --- a/src/qe/qe_arrays.cpp +++ b/src/qe/qe_arrays.cpp @@ -18,13 +18,13 @@ Revision History: --*/ -#include "qe_arrays.h" -#include "rewriter_def.h" -#include "expr_functors.h" -#include "expr_safe_replace.h" -#include "lbool.h" -#include "ast_util.h" -#include "ast_pp.h" +#include "qe/qe_arrays.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/expr_functors.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "util/lbool.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" namespace qe { diff --git a/src/qe/qe_arrays.h b/src/qe/qe_arrays.h index 182d82255..e100ebce4 100644 --- a/src/qe/qe_arrays.h +++ b/src/qe/qe_arrays.h @@ -21,8 +21,8 @@ Revision History: #ifndef __QE_ARRAYS_H_ #define __QE_ARRAYS_H_ -#include "array_decl_plugin.h" -#include "qe_mbp.h" +#include "ast/array_decl_plugin.h" +#include "qe/qe_mbp.h" namespace qe { diff --git a/src/qe/qe_bool_plugin.cpp b/src/qe/qe_bool_plugin.cpp index 39a46ae55..82e09bbed 100644 --- a/src/qe/qe_bool_plugin.cpp +++ b/src/qe/qe_bool_plugin.cpp @@ -24,10 +24,10 @@ Notes: --*/ -#include "qe.h" -#include "expr_safe_replace.h" -#include "ast_pp.h" -#include "model_evaluator.h" +#include "qe/qe.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/ast_pp.h" +#include "model/model_evaluator.h" namespace qe { diff --git a/src/qe/qe_bv_plugin.cpp b/src/qe/qe_bv_plugin.cpp index df1f8c619..6678d6fcf 100644 --- a/src/qe/qe_bv_plugin.cpp +++ b/src/qe/qe_bv_plugin.cpp @@ -20,10 +20,10 @@ Notes: --*/ -#include "qe.h" -#include "expr_safe_replace.h" -#include "bv_decl_plugin.h" -#include "model_evaluator.h" +#include "qe/qe.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/bv_decl_plugin.h" +#include "model/model_evaluator.h" namespace qe { diff --git a/src/qe/qe_cmd.cpp b/src/qe/qe_cmd.cpp index 9144c708c..553cf4471 100644 --- a/src/qe/qe_cmd.cpp +++ b/src/qe/qe_cmd.cpp @@ -4,10 +4,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "qe_cmd.h" -#include "qe.h" -#include "cmd_context.h" -#include "parametric_cmd.h" +#include "qe/qe_cmd.h" +#include "qe/qe.h" +#include "cmd_context/cmd_context.h" +#include "cmd_context/parametric_cmd.h" class qe_cmd : public parametric_cmd { expr * m_target; diff --git a/src/qe/qe_datatype_plugin.cpp b/src/qe/qe_datatype_plugin.cpp index 78562cf00..4178c3af3 100644 --- a/src/qe/qe_datatype_plugin.cpp +++ b/src/qe/qe_datatype_plugin.cpp @@ -99,13 +99,13 @@ Copyright (c) 2015 Microsoft Corporation // maintain set of equations and disequations with x. // -#include "qe.h" -#include "datatype_decl_plugin.h" -#include "expr_safe_replace.h" -#include "obj_pair_hashtable.h" -#include "for_each_expr.h" -#include "ast_pp.h" -#include "ast_ll_pp.h" +#include "qe/qe.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "util/obj_pair_hashtable.h" +#include "ast/for_each_expr.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" namespace qe { diff --git a/src/qe/qe_datatypes.cpp b/src/qe/qe_datatypes.cpp index 8536e337f..db1e6ec85 100644 --- a/src/qe/qe_datatypes.cpp +++ b/src/qe/qe_datatypes.cpp @@ -17,14 +17,14 @@ Revision History: --*/ -#include "qe_arith.h" -#include "ast_pp.h" -#include "th_rewriter.h" -#include "expr_functors.h" -#include "model_v2_pp.h" -#include "expr_safe_replace.h" -#include "obj_pair_hashtable.h" -#include "qe_datatypes.h" +#include "qe/qe_arith.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/expr_functors.h" +#include "model/model_v2_pp.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "util/obj_pair_hashtable.h" +#include "qe/qe_datatypes.h" namespace qe { diff --git a/src/qe/qe_datatypes.h b/src/qe/qe_datatypes.h index f616e7f2e..7352b4ca7 100644 --- a/src/qe/qe_datatypes.h +++ b/src/qe/qe_datatypes.h @@ -21,8 +21,8 @@ Revision History: #ifndef __QE_DATATYPES_H_ #define __QE_DATATYPES_H_ -#include "datatype_decl_plugin.h" -#include "qe_mbp.h" +#include "ast/datatype_decl_plugin.h" +#include "qe/qe_mbp.h" namespace qe { diff --git a/src/qe/qe_dl_plugin.cpp b/src/qe/qe_dl_plugin.cpp index e04f4cbde..7ff7bc11e 100644 --- a/src/qe/qe_dl_plugin.cpp +++ b/src/qe/qe_dl_plugin.cpp @@ -5,11 +5,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "qe.h" -#include "expr_safe_replace.h" -#include "dl_decl_plugin.h" -#include "obj_pair_hashtable.h" -#include "ast_pp.h" +#include "qe/qe.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/dl_decl_plugin.h" +#include "util/obj_pair_hashtable.h" +#include "ast/ast_pp.h" namespace qe { diff --git a/src/qe/qe_lite.cpp b/src/qe/qe_lite.cpp index ce182a97b..3f84ca98c 100644 --- a/src/qe/qe_lite.cpp +++ b/src/qe/qe_lite.cpp @@ -17,26 +17,26 @@ Revision History: --*/ -#include "qe_lite.h" -#include "expr_abstract.h" -#include "used_vars.h" -#include "occurs.h" -#include "rewriter_def.h" -#include "ast_pp.h" -#include "ast_ll_pp.h" -#include "ast_smt2_pp.h" -#include "tactical.h" -#include "bool_rewriter.h" -#include "var_subst.h" -#include "uint_set.h" -#include "ast_util.h" -#include "th_rewriter.h" -#include "for_each_expr.h" -#include "expr_safe_replace.h" -#include "cooperate.h" -#include "datatype_decl_plugin.h" +#include "qe/qe_lite.h" +#include "ast/expr_abstract.h" +#include "ast/used_vars.h" +#include "ast/occurs.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/var_subst.h" +#include "util/uint_set.h" +#include "ast/ast_util.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "util/cooperate.h" +#include "ast/datatype_decl_plugin.h" -#include "qe_vartest.h" +#include "qe/qe_vartest.h" namespace eq { class der { diff --git a/src/qe/qe_lite.h b/src/qe/qe_lite.h index cff547f36..9f0829a03 100644 --- a/src/qe/qe_lite.h +++ b/src/qe/qe_lite.h @@ -21,9 +21,9 @@ Revision History: #ifndef QE_LITE_H_ #define QE_LITE_H_ -#include "ast.h" -#include "uint_set.h" -#include "params.h" +#include "ast/ast.h" +#include "util/uint_set.h" +#include "util/params.h" class tactic; diff --git a/src/qe/qe_mbp.cpp b/src/qe/qe_mbp.cpp index f4c0c9339..329687a36 100644 --- a/src/qe/qe_mbp.cpp +++ b/src/qe/qe_mbp.cpp @@ -18,18 +18,18 @@ Revision History: --*/ -#include "qe_mbp.h" -#include "qe_arith.h" -#include "qe_arrays.h" -#include "qe_datatypes.h" -#include "expr_safe_replace.h" -#include "ast_pp.h" -#include "ast_util.h" -#include "th_rewriter.h" -#include "model_v2_pp.h" -#include "expr_functors.h" -#include "for_each_expr.h" -#include "model_evaluator.h" +#include "qe/qe_mbp.h" +#include "qe/qe_arith.h" +#include "qe/qe_arrays.h" +#include "qe/qe_datatypes.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "ast/rewriter/th_rewriter.h" +#include "model/model_v2_pp.h" +#include "ast/expr_functors.h" +#include "ast/for_each_expr.h" +#include "model/model_evaluator.h" using namespace qe; diff --git a/src/qe/qe_mbp.h b/src/qe/qe_mbp.h index b195d3a35..d1695843c 100644 --- a/src/qe/qe_mbp.h +++ b/src/qe/qe_mbp.h @@ -21,10 +21,10 @@ Revision History: #ifndef __QE_MBP_H__ #define __QE_MBP_H__ -#include "ast.h" -#include "params.h" -#include "model.h" -#include "model_based_opt.h" +#include "ast/ast.h" +#include "util/params.h" +#include "model/model.h" +#include "math/simplex/model_based_opt.h" namespace qe { diff --git a/src/qe/qe_sat_tactic.cpp b/src/qe/qe_sat_tactic.cpp index c2912692c..69ebc1a42 100644 --- a/src/qe/qe_sat_tactic.cpp +++ b/src/qe/qe_sat_tactic.cpp @@ -20,16 +20,16 @@ Revision History: --*/ -#include "qe_sat_tactic.h" -#include "quant_hoist.h" -#include "ast_pp.h" -#include "smt_kernel.h" -#include "qe.h" -#include "cooperate.h" -#include "model_v2_pp.h" -#include "expr_replacer.h" -#include "th_rewriter.h" -#include "expr_context_simplifier.h" +#include "qe/qe_sat_tactic.h" +#include "ast/rewriter/quant_hoist.h" +#include "ast/ast_pp.h" +#include "smt/smt_kernel.h" +#include "qe/qe.h" +#include "util/cooperate.h" +#include "model/model_v2_pp.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/th_rewriter.h" +#include "smt/expr_context_simplifier.h" // plugin registration. // solver specific projection operators. diff --git a/src/qe/qe_sat_tactic.h b/src/qe/qe_sat_tactic.h index 0b276fe8d..57279ed05 100644 --- a/src/qe/qe_sat_tactic.h +++ b/src/qe/qe_sat_tactic.h @@ -22,7 +22,7 @@ Revision History: #ifndef QE_SAT_H_ #define QE_SAT_H_ -#include"tactic.h" +#include "tactic/tactic.h" namespace qe { diff --git a/src/qe/qe_tactic.cpp b/src/qe/qe_tactic.cpp index 935af8550..5d1a74813 100644 --- a/src/qe/qe_tactic.cpp +++ b/src/qe/qe_tactic.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"filter_model_converter.h" -#include"cooperate.h" -#include"qe.h" +#include "tactic/tactical.h" +#include "tactic/filter_model_converter.h" +#include "util/cooperate.h" +#include "qe/qe.h" class qe_tactic : public tactic { statistics m_st; diff --git a/src/qe/qe_tactic.h b/src/qe/qe_tactic.h index 68860f488..c50cc84de 100644 --- a/src/qe/qe_tactic.h +++ b/src/qe/qe_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef QE_TACTIC_H_ #define QE_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/qe/qe_vartest.h b/src/qe/qe_vartest.h index b2b4be649..047964825 100644 --- a/src/qe/qe_vartest.h +++ b/src/qe/qe_vartest.h @@ -19,8 +19,8 @@ Revision History: #ifndef QE_VARTEST_H_ #define QE_VARTEST_H_ -#include "ast.h" -#include "uint_set.h" +#include "ast/ast.h" +#include "util/uint_set.h" class is_variable_proc { public: diff --git a/src/qe/qsat.cpp b/src/qe/qsat.cpp index 841bdde9b..abd396818 100644 --- a/src/qe/qsat.cpp +++ b/src/qe/qsat.cpp @@ -20,23 +20,23 @@ Notes: --*/ -#include "smt_kernel.h" -#include "qe_mbp.h" -#include "smt_params.h" -#include "ast_util.h" -#include "quant_hoist.h" -#include "ast_pp.h" -#include "model_v2_pp.h" -#include "qsat.h" -#include "expr_abstract.h" -#include "qe.h" -#include "label_rewriter.h" -#include "expr_replacer.h" -#include "th_rewriter.h" -#include "model_evaluator.h" -#include "smt_solver.h" -#include "solver.h" -#include "mus.h" +#include "smt/smt_kernel.h" +#include "qe/qe_mbp.h" +#include "smt/params/smt_params.h" +#include "ast/ast_util.h" +#include "ast/rewriter/quant_hoist.h" +#include "ast/ast_pp.h" +#include "model/model_v2_pp.h" +#include "qe/qsat.h" +#include "ast/expr_abstract.h" +#include "qe/qe.h" +#include "ast/rewriter/label_rewriter.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/th_rewriter.h" +#include "model/model_evaluator.h" +#include "smt/smt_solver.h" +#include "solver/solver.h" +#include "solver/mus.h" namespace qe { diff --git a/src/qe/qsat.h b/src/qe/qsat.h index b6d21db1e..85a8181d6 100644 --- a/src/qe/qsat.h +++ b/src/qe/qsat.h @@ -21,9 +21,9 @@ Revision History: #ifndef QE_QSAT_H__ #define QE_QSAT_H__ -#include "tactic.h" -#include "filter_model_converter.h" -#include "qe_mbp.h" +#include "tactic/tactic.h" +#include "tactic/filter_model_converter.h" +#include "qe/qe_mbp.h" namespace qe { diff --git a/src/qe/vsubst_tactic.cpp b/src/qe/vsubst_tactic.cpp index c389d9a66..6bd8213d6 100644 --- a/src/qe/vsubst_tactic.cpp +++ b/src/qe/vsubst_tactic.cpp @@ -40,12 +40,12 @@ Notes: a*a + b*b + c < 0 => c < 0 --*/ -#include"tactic.h" -#include"qe.h" -#include"arith_decl_plugin.h" -#include"for_each_expr.h" -#include"extension_model_converter.h" -#include"ast_smt2_pp.h" +#include "tactic/tactic.h" +#include "qe/qe.h" +#include "ast/arith_decl_plugin.h" +#include "ast/for_each_expr.h" +#include "tactic/extension_model_converter.h" +#include "ast/ast_smt2_pp.h" class vsubst_tactic : public tactic { params_ref m_params; diff --git a/src/qe/vsubst_tactic.h b/src/qe/vsubst_tactic.h index 8c0cb682f..2f28bda71 100644 --- a/src/qe/vsubst_tactic.h +++ b/src/qe/vsubst_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef VSUBST_TACTIC_H_ #define VSUBST_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/sat/dimacs.cpp b/src/sat/dimacs.cpp index 3aa8591f9..512be5f4b 100644 --- a/src/sat/dimacs.cpp +++ b/src/sat/dimacs.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"dimacs.h" +#include "sat/dimacs.h" #undef max #undef min -#include"sat_solver.h" +#include "sat/sat_solver.h" class stream_buffer { std::istream & m_stream; diff --git a/src/sat/dimacs.h b/src/sat/dimacs.h index 9d7bb0679..50ebec0c8 100644 --- a/src/sat/dimacs.h +++ b/src/sat/dimacs.h @@ -19,7 +19,7 @@ Revision History: #ifndef DIMACS_H_ #define DIMACS_H_ -#include"sat_types.h" +#include "sat/sat_types.h" void parse_dimacs(std::istream & s, sat::solver & solver); diff --git a/src/sat/sat_asymm_branch.cpp b/src/sat/sat_asymm_branch.cpp index cca0c5c1b..6d8fa05a0 100644 --- a/src/sat/sat_asymm_branch.cpp +++ b/src/sat/sat_asymm_branch.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"sat_asymm_branch.h" +#include "sat/sat_asymm_branch.h" #include"sat_asymm_branch_params.hpp" -#include"sat_solver.h" -#include"stopwatch.h" -#include"trace.h" +#include "sat/sat_solver.h" +#include "util/stopwatch.h" +#include "util/trace.h" namespace sat { diff --git a/src/sat/sat_asymm_branch.h b/src/sat/sat_asymm_branch.h index 4ad702c5c..9e28d1600 100644 --- a/src/sat/sat_asymm_branch.h +++ b/src/sat/sat_asymm_branch.h @@ -19,9 +19,9 @@ Revision History: #ifndef SAT_ASYMM_BRANCH_H_ #define SAT_ASYMM_BRANCH_H_ -#include"sat_types.h" -#include"statistics.h" -#include"params.h" +#include "sat/sat_types.h" +#include "util/statistics.h" +#include "util/params.h" namespace sat { class solver; diff --git a/src/sat/sat_clause.cpp b/src/sat/sat_clause.cpp index 1efbd6758..c5829ae4e 100644 --- a/src/sat/sat_clause.cpp +++ b/src/sat/sat_clause.cpp @@ -17,9 +17,9 @@ Revision History: --*/ #include -#include"sat_clause.h" -#include"z3_exception.h" -#include"trace.h" +#include "sat/sat_clause.h" +#include "util/z3_exception.h" +#include "util/trace.h" namespace sat { diff --git a/src/sat/sat_clause.h b/src/sat/sat_clause.h index 27a0ed739..5ad08e52a 100644 --- a/src/sat/sat_clause.h +++ b/src/sat/sat_clause.h @@ -19,10 +19,10 @@ Revision History: #ifndef SAT_CLAUSE_H_ #define SAT_CLAUSE_H_ -#include"sat_types.h" -#include"small_object_allocator.h" -#include"id_gen.h" -#include"map.h" +#include "sat/sat_types.h" +#include "util/small_object_allocator.h" +#include "util/id_gen.h" +#include "util/map.h" #ifdef _MSC_VER #pragma warning(disable : 4200) diff --git a/src/sat/sat_clause_set.cpp b/src/sat/sat_clause_set.cpp index 1c424cce3..c223009d6 100644 --- a/src/sat/sat_clause_set.cpp +++ b/src/sat/sat_clause_set.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"sat_clause_set.h" +#include "sat/sat_clause_set.h" namespace sat { diff --git a/src/sat/sat_clause_set.h b/src/sat/sat_clause_set.h index e63c92d08..f9da6a00d 100644 --- a/src/sat/sat_clause_set.h +++ b/src/sat/sat_clause_set.h @@ -19,7 +19,7 @@ Revision History: #ifndef SAT_CLAUSE_SET_H_ #define SAT_CLAUSE_SET_H_ -#include"sat_clause.h" +#include "sat/sat_clause.h" namespace sat { diff --git a/src/sat/sat_clause_use_list.cpp b/src/sat/sat_clause_use_list.cpp index f22e6a822..5ee5b4cda 100644 --- a/src/sat/sat_clause_use_list.cpp +++ b/src/sat/sat_clause_use_list.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"sat_clause.h" -#include"sat_clause_use_list.h" +#include "sat/sat_clause.h" +#include "sat/sat_clause_use_list.h" namespace sat { diff --git a/src/sat/sat_clause_use_list.h b/src/sat/sat_clause_use_list.h index ec283f4c4..121345f21 100644 --- a/src/sat/sat_clause_use_list.h +++ b/src/sat/sat_clause_use_list.h @@ -19,8 +19,8 @@ Revision History: #ifndef SAT_CLAUSE_USE_LIST_H_ #define SAT_CLAUSE_USE_LIST_H_ -#include"sat_types.h" -#include"trace.h" +#include "sat/sat_types.h" +#include "util/trace.h" namespace sat { diff --git a/src/sat/sat_cleaner.cpp b/src/sat/sat_cleaner.cpp index 959f5e94f..9dd53d8f6 100644 --- a/src/sat/sat_cleaner.cpp +++ b/src/sat/sat_cleaner.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"sat_cleaner.h" -#include"sat_solver.h" -#include"trace.h" -#include"stopwatch.h" +#include "sat/sat_cleaner.h" +#include "sat/sat_solver.h" +#include "util/trace.h" +#include "util/stopwatch.h" namespace sat { diff --git a/src/sat/sat_cleaner.h b/src/sat/sat_cleaner.h index d886453df..4ffc0be10 100644 --- a/src/sat/sat_cleaner.h +++ b/src/sat/sat_cleaner.h @@ -19,8 +19,8 @@ Revision History: #ifndef SAT_CLEANER_H_ #define SAT_CLEANER_H_ -#include"sat_types.h" -#include"statistics.h" +#include "sat/sat_types.h" +#include "util/statistics.h" namespace sat { diff --git a/src/sat/sat_config.cpp b/src/sat/sat_config.cpp index 9206ea8bc..00ee0f48e 100644 --- a/src/sat/sat_config.cpp +++ b/src/sat/sat_config.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"sat_config.h" -#include"sat_types.h" +#include "sat/sat_config.h" +#include "sat/sat_types.h" #include"sat_params.hpp" namespace sat { diff --git a/src/sat/sat_config.h b/src/sat/sat_config.h index 405cbd092..edd9f0bfc 100644 --- a/src/sat/sat_config.h +++ b/src/sat/sat_config.h @@ -20,7 +20,7 @@ Revision History: #ifndef SAT_CONFIG_H_ #define SAT_CONFIG_H_ -#include"params.h" +#include "util/params.h" namespace sat { diff --git a/src/sat/sat_elim_eqs.cpp b/src/sat/sat_elim_eqs.cpp index b7f83df6c..4cb2fa8ae 100644 --- a/src/sat/sat_elim_eqs.cpp +++ b/src/sat/sat_elim_eqs.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"sat_elim_eqs.h" -#include"sat_solver.h" -#include"trace.h" +#include "sat/sat_elim_eqs.h" +#include "sat/sat_solver.h" +#include "util/trace.h" namespace sat { diff --git a/src/sat/sat_elim_eqs.h b/src/sat/sat_elim_eqs.h index 6f81d6ecb..0422b60df 100644 --- a/src/sat/sat_elim_eqs.h +++ b/src/sat/sat_elim_eqs.h @@ -19,7 +19,7 @@ Revision History: #ifndef SAT_ELIM_EQS_H_ #define SAT_ELIM_EQS_H_ -#include"sat_types.h" +#include "sat/sat_types.h" namespace sat { class solver; diff --git a/src/sat/sat_extension.h b/src/sat/sat_extension.h index b0b1c5d96..80144e00d 100644 --- a/src/sat/sat_extension.h +++ b/src/sat/sat_extension.h @@ -19,8 +19,8 @@ Revision History: #ifndef SAT_EXTENSION_H_ #define SAT_EXTENSION_H_ -#include"sat_types.h" -#include"params.h" +#include "sat/sat_types.h" +#include "util/params.h" namespace sat { diff --git a/src/sat/sat_iff3_finder.cpp b/src/sat/sat_iff3_finder.cpp index 789f5dec0..e889af164 100644 --- a/src/sat/sat_iff3_finder.cpp +++ b/src/sat/sat_iff3_finder.cpp @@ -29,8 +29,8 @@ Author: Revision History: --*/ -#include"sat_iff3_finder.h" -#include"sat_solver.h" +#include "sat/sat_iff3_finder.h" +#include "sat/sat_solver.h" namespace sat { diff --git a/src/sat/sat_iff3_finder.h b/src/sat/sat_iff3_finder.h index a74ad1eb1..27cd6de05 100644 --- a/src/sat/sat_iff3_finder.h +++ b/src/sat/sat_iff3_finder.h @@ -29,7 +29,7 @@ Revision History: #ifndef SAT_IFF3_FINDER_H_ #define SAT_IFF3_FINDER_H_ -#include"sat_types.h" +#include "sat/sat_types.h" namespace sat { diff --git a/src/sat/sat_integrity_checker.cpp b/src/sat/sat_integrity_checker.cpp index f7cd371f8..08a6072b6 100644 --- a/src/sat/sat_integrity_checker.cpp +++ b/src/sat/sat_integrity_checker.cpp @@ -17,9 +17,9 @@ Author: Revision History: --*/ -#include"sat_integrity_checker.h" -#include"sat_solver.h" -#include"trace.h" +#include "sat/sat_integrity_checker.h" +#include "sat/sat_solver.h" +#include "util/trace.h" namespace sat { diff --git a/src/sat/sat_integrity_checker.h b/src/sat/sat_integrity_checker.h index 5eef1748e..640fce068 100644 --- a/src/sat/sat_integrity_checker.h +++ b/src/sat/sat_integrity_checker.h @@ -20,7 +20,7 @@ Revision History: #ifndef SAT_INTEGRITY_CHECKER_H_ #define SAT_INTEGRITY_CHECKER_H_ -#include"sat_types.h" +#include "sat/sat_types.h" namespace sat { class integrity_checker { diff --git a/src/sat/sat_model_converter.cpp b/src/sat/sat_model_converter.cpp index 525d084dc..1a881618a 100644 --- a/src/sat/sat_model_converter.cpp +++ b/src/sat/sat_model_converter.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"sat_model_converter.h" -#include"sat_clause.h" -#include"trace.h" +#include "sat/sat_model_converter.h" +#include "sat/sat_clause.h" +#include "util/trace.h" namespace sat { diff --git a/src/sat/sat_model_converter.h b/src/sat/sat_model_converter.h index eb2237707..9a5ebc0ff 100644 --- a/src/sat/sat_model_converter.h +++ b/src/sat/sat_model_converter.h @@ -19,7 +19,7 @@ Revision History: #ifndef SAT_MODEL_CONVERTER_H_ #define SAT_MODEL_CONVERTER_H_ -#include"sat_types.h" +#include "sat/sat_types.h" namespace sat { /** diff --git a/src/sat/sat_mus.cpp b/src/sat/sat_mus.cpp index 06851d10d..9c455a219 100644 --- a/src/sat/sat_mus.cpp +++ b/src/sat/sat_mus.cpp @@ -18,8 +18,8 @@ Notes: --*/ -#include "sat_solver.h" -#include "sat_mus.h" +#include "sat/sat_solver.h" +#include "sat/sat_mus.h" namespace sat { diff --git a/src/sat/sat_par.cpp b/src/sat/sat_par.cpp index 7a185a3b5..e3d5727ed 100644 --- a/src/sat/sat_par.cpp +++ b/src/sat/sat_par.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include "sat_par.h" +#include "sat/sat_par.h" namespace sat { diff --git a/src/sat/sat_par.h b/src/sat/sat_par.h index 2b2592de7..001036a98 100644 --- a/src/sat/sat_par.h +++ b/src/sat/sat_par.h @@ -19,9 +19,9 @@ Revision History: #ifndef SAT_PAR_H_ #define SAT_PAR_H_ -#include"sat_types.h" -#include"hashtable.h" -#include"map.h" +#include "sat/sat_types.h" +#include "util/hashtable.h" +#include "util/map.h" namespace sat { diff --git a/src/sat/sat_probing.cpp b/src/sat/sat_probing.cpp index f54ee9f89..b23d57164 100644 --- a/src/sat/sat_probing.cpp +++ b/src/sat/sat_probing.cpp @@ -17,8 +17,8 @@ Author: Revision History: --*/ -#include"sat_probing.h" -#include"sat_solver.h" +#include "sat/sat_probing.h" +#include "sat/sat_solver.h" namespace sat { probing::probing(solver & _s, params_ref const & p): diff --git a/src/sat/sat_probing.h b/src/sat/sat_probing.h index cce165a34..391098ef7 100644 --- a/src/sat/sat_probing.h +++ b/src/sat/sat_probing.h @@ -20,9 +20,9 @@ Revision History: #ifndef SAT_PROBING_H_ #define SAT_PROBING_H_ -#include"sat_types.h" -#include"params.h" -#include"statistics.h" +#include "sat/sat_types.h" +#include "util/params.h" +#include "util/statistics.h" namespace sat { diff --git a/src/sat/sat_scc.cpp b/src/sat/sat_scc.cpp index ffbdb31c6..5ab0bbd38 100644 --- a/src/sat/sat_scc.cpp +++ b/src/sat/sat_scc.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"sat_scc.h" -#include"sat_solver.h" -#include"sat_elim_eqs.h" -#include"stopwatch.h" -#include"trace.h" +#include "sat/sat_scc.h" +#include "sat/sat_solver.h" +#include "sat/sat_elim_eqs.h" +#include "util/stopwatch.h" +#include "util/trace.h" #include"sat_scc_params.hpp" namespace sat { diff --git a/src/sat/sat_scc.h b/src/sat/sat_scc.h index f44c39742..c8392685e 100644 --- a/src/sat/sat_scc.h +++ b/src/sat/sat_scc.h @@ -19,9 +19,9 @@ Revision History: #ifndef SAT_SCC_H_ #define SAT_SCC_H_ -#include"sat_types.h" -#include"statistics.h" -#include"params.h" +#include "sat/sat_types.h" +#include "util/statistics.h" +#include "util/params.h" namespace sat { class solver; diff --git a/src/sat/sat_simplifier.cpp b/src/sat/sat_simplifier.cpp index 923f5ae49..ef74a58f4 100644 --- a/src/sat/sat_simplifier.cpp +++ b/src/sat/sat_simplifier.cpp @@ -18,11 +18,11 @@ Author: Revision History: --*/ -#include"sat_simplifier.h" +#include "sat/sat_simplifier.h" #include"sat_simplifier_params.hpp" -#include"sat_solver.h" -#include"stopwatch.h" -#include"trace.h" +#include "sat/sat_solver.h" +#include "util/stopwatch.h" +#include "util/trace.h" namespace sat { diff --git a/src/sat/sat_simplifier.h b/src/sat/sat_simplifier.h index d26d0041f..44e4276e0 100644 --- a/src/sat/sat_simplifier.h +++ b/src/sat/sat_simplifier.h @@ -21,15 +21,15 @@ Revision History: #ifndef SAT_SIMPLIFIER_H_ #define SAT_SIMPLIFIER_H_ -#include"sat_types.h" -#include"sat_clause.h" -#include"sat_clause_set.h" -#include"sat_clause_use_list.h" -#include"sat_watched.h" -#include"sat_model_converter.h" -#include"heap.h" -#include"statistics.h" -#include"params.h" +#include "sat/sat_types.h" +#include "sat/sat_clause.h" +#include "sat/sat_clause_set.h" +#include "sat/sat_clause_use_list.h" +#include "sat/sat_watched.h" +#include "sat/sat_model_converter.h" +#include "util/heap.h" +#include "util/statistics.h" +#include "util/params.h" namespace sat { class solver; diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index fbfa0ec6b..77bd2283d 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"sat_solver.h" -#include"sat_integrity_checker.h" -#include"luby.h" -#include"trace.h" -#include"max_cliques.h" +#include "sat/sat_solver.h" +#include "sat/sat_integrity_checker.h" +#include "util/luby.h" +#include "util/trace.h" +#include "util/max_cliques.h" // define to update glue during propagation #define UPDATE_GLUE diff --git a/src/sat/sat_solver.h b/src/sat/sat_solver.h index a26abe1e0..c011eb46d 100644 --- a/src/sat/sat_solver.h +++ b/src/sat/sat_solver.h @@ -19,26 +19,26 @@ Revision History: #ifndef SAT_SOLVER_H_ #define SAT_SOLVER_H_ -#include"sat_types.h" -#include"sat_clause.h" -#include"sat_watched.h" -#include"sat_justification.h" -#include"sat_var_queue.h" -#include"sat_extension.h" -#include"sat_config.h" -#include"sat_cleaner.h" -#include"sat_simplifier.h" -#include"sat_scc.h" -#include"sat_asymm_branch.h" -#include"sat_iff3_finder.h" -#include"sat_probing.h" -#include"sat_mus.h" -#include"sat_par.h" -#include"params.h" -#include"statistics.h" -#include"stopwatch.h" -#include"trace.h" -#include"rlimit.h" +#include "sat/sat_types.h" +#include "sat/sat_clause.h" +#include "sat/sat_watched.h" +#include "sat/sat_justification.h" +#include "sat/sat_var_queue.h" +#include "sat/sat_extension.h" +#include "sat/sat_config.h" +#include "sat/sat_cleaner.h" +#include "sat/sat_simplifier.h" +#include "sat/sat_scc.h" +#include "sat/sat_asymm_branch.h" +#include "sat/sat_iff3_finder.h" +#include "sat/sat_probing.h" +#include "sat/sat_mus.h" +#include "sat/sat_par.h" +#include "util/params.h" +#include "util/statistics.h" +#include "util/stopwatch.h" +#include "util/trace.h" +#include "util/rlimit.h" namespace sat { diff --git a/src/sat/sat_solver/inc_sat_solver.cpp b/src/sat/sat_solver/inc_sat_solver.cpp index baac9f37b..521aa5e71 100644 --- a/src/sat/sat_solver/inc_sat_solver.cpp +++ b/src/sat/sat_solver/inc_sat_solver.cpp @@ -17,24 +17,24 @@ Notes: --*/ -#include "solver.h" -#include "tactical.h" -#include "sat_solver.h" -#include "tactic2solver.h" -#include "aig_tactic.h" -#include "propagate_values_tactic.h" -#include "max_bv_sharing_tactic.h" -#include "card2bv_tactic.h" -#include "bit_blaster_tactic.h" -#include "simplify_tactic.h" -#include "goal2sat.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" -#include "filter_model_converter.h" -#include "bit_blaster_model_converter.h" -#include "ast_translation.h" -#include "ast_util.h" -#include "propagate_values_tactic.h" +#include "solver/solver.h" +#include "tactic/tactical.h" +#include "sat/sat_solver.h" +#include "solver/tactic2solver.h" +#include "tactic/aig/aig_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "tactic/arith/card2bv_tactic.h" +#include "tactic/bv/bit_blaster_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "sat/tactic/goal2sat.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" +#include "tactic/filter_model_converter.h" +#include "tactic/bv/bit_blaster_model_converter.h" +#include "ast/ast_translation.h" +#include "ast/ast_util.h" +#include "tactic/core/propagate_values_tactic.h" // incremental SAT solver. class inc_sat_solver : public solver { diff --git a/src/sat/sat_solver/inc_sat_solver.h b/src/sat/sat_solver/inc_sat_solver.h index 4b0bea50e..658c0583d 100644 --- a/src/sat/sat_solver/inc_sat_solver.h +++ b/src/sat/sat_solver/inc_sat_solver.h @@ -20,7 +20,7 @@ Notes: #ifndef HS_INC_SAT_SOLVER_H_ #define HS_INC_SAT_SOLVER_H_ -#include "solver.h" +#include "solver/solver.h" solver* mk_inc_sat_solver(ast_manager& m, params_ref const& p); diff --git a/src/sat/sat_types.h b/src/sat/sat_types.h index 28d8d761a..6652fb3b0 100644 --- a/src/sat/sat_types.h +++ b/src/sat/sat_types.h @@ -19,12 +19,12 @@ Revision History: #ifndef SAT_TYPES_H_ #define SAT_TYPES_H_ -#include"debug.h" -#include"approx_set.h" -#include"lbool.h" -#include"z3_exception.h" -#include"common_msgs.h" -#include"vector.h" +#include "util/debug.h" +#include "util/approx_set.h" +#include "util/lbool.h" +#include "util/z3_exception.h" +#include "util/common_msgs.h" +#include "util/vector.h" #include namespace sat { diff --git a/src/sat/sat_var_queue.h b/src/sat/sat_var_queue.h index f008fbb88..a14eb4cff 100644 --- a/src/sat/sat_var_queue.h +++ b/src/sat/sat_var_queue.h @@ -19,8 +19,8 @@ Revision History: #ifndef SAT_VAR_QUEUE_H_ #define SAT_VAR_QUEUE_H_ -#include"heap.h" -#include"sat_types.h" +#include "util/heap.h" +#include "sat/sat_types.h" namespace sat { diff --git a/src/sat/sat_watched.cpp b/src/sat/sat_watched.cpp index cc442571c..6335d37fc 100644 --- a/src/sat/sat_watched.cpp +++ b/src/sat/sat_watched.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"sat_watched.h" -#include"sat_clause.h" +#include "sat/sat_watched.h" +#include "sat/sat_clause.h" namespace sat { diff --git a/src/sat/sat_watched.h b/src/sat/sat_watched.h index 2c48b6c9b..e5a02953b 100644 --- a/src/sat/sat_watched.h +++ b/src/sat/sat_watched.h @@ -19,8 +19,8 @@ Revision History: #ifndef SAT_WATCHED_H_ #define SAT_WATCHED_H_ -#include"sat_types.h" -#include"vector.h" +#include "sat/sat_types.h" +#include "util/vector.h" namespace sat { /** diff --git a/src/sat/tactic/atom2bool_var.cpp b/src/sat/tactic/atom2bool_var.cpp index 48ad85152..26f3448d3 100644 --- a/src/sat/tactic/atom2bool_var.cpp +++ b/src/sat/tactic/atom2bool_var.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"atom2bool_var.h" -#include"ast_smt2_pp.h" -#include"ref_util.h" -#include"goal.h" +#include "sat/tactic/atom2bool_var.h" +#include "ast/ast_smt2_pp.h" +#include "util/ref_util.h" +#include "tactic/goal.h" void atom2bool_var::mk_inv(expr_ref_vector & lit2expr) const { obj_map::iterator it = m_mapping.begin(); diff --git a/src/sat/tactic/atom2bool_var.h b/src/sat/tactic/atom2bool_var.h index 3435a1e2c..d360d3fe0 100644 --- a/src/sat/tactic/atom2bool_var.h +++ b/src/sat/tactic/atom2bool_var.h @@ -19,8 +19,8 @@ Notes: #ifndef ATOM2BOOL_VAR_H_ #define ATOM2BOOL_VAR_H_ -#include"expr2var.h" -#include"sat_types.h" +#include "ast/expr2var.h" +#include "sat/sat_types.h" /** \brief Mapping from atoms into SAT boolean variables. diff --git a/src/sat/tactic/goal2sat.cpp b/src/sat/tactic/goal2sat.cpp index 742a4fb1d..0b6ad2c82 100644 --- a/src/sat/tactic/goal2sat.cpp +++ b/src/sat/tactic/goal2sat.cpp @@ -26,16 +26,16 @@ Author: Notes: --*/ -#include"goal2sat.h" -#include"ast_smt2_pp.h" -#include"ref_util.h" -#include"cooperate.h" -#include"filter_model_converter.h" -#include"model_evaluator.h" -#include"for_each_expr.h" -#include"model_v2_pp.h" -#include"tactic.h" -#include"ast_pp.h" +#include "sat/tactic/goal2sat.h" +#include "ast/ast_smt2_pp.h" +#include "util/ref_util.h" +#include "util/cooperate.h" +#include "tactic/filter_model_converter.h" +#include "model/model_evaluator.h" +#include "ast/for_each_expr.h" +#include "model/model_v2_pp.h" +#include "tactic/tactic.h" +#include "ast/ast_pp.h" #include struct goal2sat::imp { diff --git a/src/sat/tactic/goal2sat.h b/src/sat/tactic/goal2sat.h index cd63cd497..199d79f9d 100644 --- a/src/sat/tactic/goal2sat.h +++ b/src/sat/tactic/goal2sat.h @@ -29,10 +29,10 @@ Notes: #ifndef GOAL2SAT_H_ #define GOAL2SAT_H_ -#include"goal.h" -#include"sat_solver.h" -#include"model_converter.h" -#include"atom2bool_var.h" +#include "tactic/goal.h" +#include "sat/sat_solver.h" +#include "tactic/model_converter.h" +#include "sat/tactic/atom2bool_var.h" class goal2sat { struct imp; diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index f99e46851..9b706597d 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"goal2sat.h" -#include"sat_solver.h" -#include"filter_model_converter.h" -#include"ast_smt2_pp.h" -#include"model_v2_pp.h" +#include "tactic/tactical.h" +#include "sat/tactic/goal2sat.h" +#include "sat/sat_solver.h" +#include "tactic/filter_model_converter.h" +#include "ast/ast_smt2_pp.h" +#include "model/model_v2_pp.h" class sat_tactic : public tactic { diff --git a/src/sat/tactic/sat_tactic.h b/src/sat/tactic/sat_tactic.h index 115b01a71..8525f1179 100644 --- a/src/sat/tactic/sat_tactic.h +++ b/src/sat/tactic/sat_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef SAT_TACTIC_H_ #define SAT_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/shell/datalog_frontend.cpp b/src/shell/datalog_frontend.cpp index 83b900c5c..b2b181977 100644 --- a/src/shell/datalog_frontend.cpp +++ b/src/shell/datalog_frontend.cpp @@ -20,22 +20,22 @@ Revision History: #include #include #include -#include"stopwatch.h" +#include "util/stopwatch.h" #ifdef _CYGWIN #undef min #undef max #endif -#include"smt_params.h" -#include"arith_decl_plugin.h" -#include"dl_compiler.h" -#include"dl_mk_filter_rules.h" -#include"dl_finite_product_relation.h" -#include"dl_context.h" -#include"rel_context.h" -#include"dl_register_engine.h" -#include"datalog_parser.h" -#include"datalog_frontend.h" -#include"timeout.h" +#include "smt/params/smt_params.h" +#include "ast/arith_decl_plugin.h" +#include "muz/rel/dl_compiler.h" +#include "muz/transforms/dl_mk_filter_rules.h" +#include "muz/rel/dl_finite_product_relation.h" +#include "muz/base/dl_context.h" +#include "muz/rel/rel_context.h" +#include "muz/fp/dl_register_engine.h" +#include "muz/fp/datalog_parser.h" +#include "shell/datalog_frontend.h" +#include "util/timeout.h" static stopwatch g_overall_time; static stopwatch g_piece_timer; diff --git a/src/shell/dimacs_frontend.cpp b/src/shell/dimacs_frontend.cpp index 09645a25a..999574f1e 100644 --- a/src/shell/dimacs_frontend.cpp +++ b/src/shell/dimacs_frontend.cpp @@ -19,11 +19,11 @@ Revision History: #include #include #include -#include"timeout.h" -#include"rlimit.h" -#include"dimacs.h" -#include"sat_solver.h" -#include"gparams.h" +#include "util/timeout.h" +#include "util/rlimit.h" +#include "sat/dimacs.h" +#include "sat/sat_solver.h" +#include "util/gparams.h" extern bool g_display_statistics; static sat::solver * g_solver = 0; diff --git a/src/shell/lp_frontend.cpp b/src/shell/lp_frontend.cpp index 8acbd28ff..950b4a628 100644 --- a/src/shell/lp_frontend.cpp +++ b/src/shell/lp_frontend.cpp @@ -10,11 +10,11 @@ Author: #include "lp_params.hpp" #include "util/lp/lp_settings.h" #include "util/lp/mps_reader.h" -#include "timeout.h" -#include "cancel_eh.h" -#include "scoped_timer.h" -#include "rlimit.h" -#include "gparams.h" +#include "util/timeout.h" +#include "util/cancel_eh.h" +#include "util/scoped_timer.h" +#include "util/rlimit.h" +#include "util/gparams.h" #include static lean::lp_solver* g_solver = 0; diff --git a/src/shell/main.cpp b/src/shell/main.cpp index b29586f8d..3f3ba5182 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -18,24 +18,24 @@ Revision History: --*/ #include -#include"memory_manager.h" -#include"trace.h" -#include"debug.h" -#include"util.h" -#include"pp.h" -#include"smtlib_frontend.h" -#include"z3_log_frontend.h" -#include"warning.h" +#include "util/memory_manager.h" +#include "util/trace.h" +#include "util/debug.h" +#include "util/util.h" +#include "ast/pp.h" +#include "shell/smtlib_frontend.h" +#include "shell/z3_log_frontend.h" +#include "util/warning.h" #include"version.h" -#include"dimacs_frontend.h" -#include"datalog_frontend.h" -#include"opt_frontend.h" -#include"timeout.h" -#include"z3_exception.h" -#include"error_codes.h" -#include"gparams.h" -#include"env_params.h" -#include "lp_frontend.h" +#include "shell/dimacs_frontend.h" +#include "shell/datalog_frontend.h" +#include "shell/opt_frontend.h" +#include "util/timeout.h" +#include "util/z3_exception.h" +#include "util/error_codes.h" +#include "util/gparams.h" +#include "util/env_params.h" +#include "shell/lp_frontend.h" typedef enum { IN_UNSPECIFIED, IN_SMTLIB, IN_SMTLIB_2, IN_DATALOG, IN_DIMACS, IN_WCNF, IN_OPB, IN_Z3_LOG, IN_MPS } input_kind; diff --git a/src/shell/opt_frontend.cpp b/src/shell/opt_frontend.cpp index 278dad287..e1aff8669 100644 --- a/src/shell/opt_frontend.cpp +++ b/src/shell/opt_frontend.cpp @@ -7,12 +7,12 @@ Copyright (c) 2015 Microsoft Corporation #include #include #include -#include"opt_context.h" -#include"ast_util.h" -#include"arith_decl_plugin.h" -#include"gparams.h" -#include"timeout.h" -#include"reg_decl_plugins.h" +#include "opt/opt_context.h" +#include "ast/ast_util.h" +#include "ast/arith_decl_plugin.h" +#include "util/gparams.h" +#include "util/timeout.h" +#include "ast/reg_decl_plugins.h" extern bool g_display_statistics; static bool g_first_interrupt = true; diff --git a/src/shell/smtlib_frontend.cpp b/src/shell/smtlib_frontend.cpp index c9fa69221..666a1e1fe 100644 --- a/src/shell/smtlib_frontend.cpp +++ b/src/shell/smtlib_frontend.cpp @@ -21,17 +21,17 @@ Revision History: #include #include #include -#include"smtlib_solver.h" -#include"timeout.h" -#include"smt2parser.h" -#include"dl_cmds.h" -#include"dbg_cmds.h" -#include"opt_cmds.h" -#include"polynomial_cmds.h" -#include"subpaving_cmds.h" -#include"smt2_extra_cmds.h" -#include"smt_strategic_solver.h" -#include"smt_solver.h" +#include "parsers/smt/smtlib_solver.h" +#include "util/timeout.h" +#include "parsers/smt2/smt2parser.h" +#include "muz/fp/dl_cmds.h" +#include "cmd_context/extra_cmds/dbg_cmds.h" +#include "opt/opt_cmds.h" +#include "cmd_context/extra_cmds/polynomial_cmds.h" +#include "cmd_context/extra_cmds/subpaving_cmds.h" +#include "smt/smt2_extra_cmds.h" +#include "tactic/portfolio/smt_strategic_solver.h" +#include "smt/smt_solver.h" extern bool g_display_statistics; static clock_t g_start_time; diff --git a/src/shell/z3_log_frontend.cpp b/src/shell/z3_log_frontend.cpp index 0b5686c66..4a0ce2c3e 100644 --- a/src/shell/z3_log_frontend.cpp +++ b/src/shell/z3_log_frontend.cpp @@ -20,9 +20,9 @@ Revision History: #include #include #include -#include"util.h" -#include"error_codes.h" -#include"z3_replayer.h" +#include "util/util.h" +#include "util/error_codes.h" +#include "api/z3_replayer.h" static void solve(char const * stream_name, std::istream & in) { clock_t start_time = clock(); diff --git a/src/smt/arith_eq_adapter.cpp b/src/smt/arith_eq_adapter.cpp index ce831f9ae..60c109cff 100644 --- a/src/smt/arith_eq_adapter.cpp +++ b/src/smt/arith_eq_adapter.cpp @@ -17,13 +17,13 @@ Revision History: --*/ -#include"smt_context.h" -#include"arith_eq_adapter.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"stats.h" -#include"simplifier.h" -#include"ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/arith_eq_adapter.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "util/stats.h" +#include "ast/simplifier/simplifier.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/arith_eq_adapter.h b/src/smt/arith_eq_adapter.h index 7e9a645e6..f18b2999f 100644 --- a/src/smt/arith_eq_adapter.h +++ b/src/smt/arith_eq_adapter.h @@ -19,11 +19,11 @@ Revision History: #ifndef ARITH_EQ_ADAPTER_H_ #define ARITH_EQ_ADAPTER_H_ -#include"smt_theory.h" -#include"obj_pair_hashtable.h" -#include"arith_decl_plugin.h" -#include"statistics.h" -#include"arith_simplifier_plugin.h" +#include "smt/smt_theory.h" +#include "util/obj_pair_hashtable.h" +#include "ast/arith_decl_plugin.h" +#include "util/statistics.h" +#include "ast/simplifier/arith_simplifier_plugin.h" namespace smt { diff --git a/src/smt/arith_eq_solver.cpp b/src/smt/arith_eq_solver.cpp index de88d37bb..128b35dd1 100644 --- a/src/smt/arith_eq_solver.cpp +++ b/src/smt/arith_eq_solver.cpp @@ -14,7 +14,7 @@ Author: Nikolaj Bjorner (nbjorner) 2012-02-25 --*/ -#include"arith_eq_solver.h" +#include "smt/arith_eq_solver.h" arith_eq_solver::~arith_eq_solver() { diff --git a/src/smt/arith_eq_solver.h b/src/smt/arith_eq_solver.h index 8b7e99fcc..b2db35ee1 100644 --- a/src/smt/arith_eq_solver.h +++ b/src/smt/arith_eq_solver.h @@ -17,8 +17,8 @@ Author: #ifndef ARITH_EQ_SOLVER_H_ #define ARITH_EQ_SOLVER_H_ -#include"arith_decl_plugin.h" -#include"arith_rewriter.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/arith_rewriter.h" /** \brief Simplifier for the arith family. diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 5c7ed33f8..9753adc5b 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -16,31 +16,31 @@ Author: Revision History: --*/ -#include"asserted_formulas.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"arith_simplifier_plugin.h" -#include"array_simplifier_plugin.h" -#include"datatype_simplifier_plugin.h" -#include"fpa_simplifier_plugin.h" -#include"seq_simplifier_plugin.h" -#include"bv_simplifier_plugin.h" -#include"for_each_expr.h" -#include"well_sorted.h" -#include"pull_quant.h" -#include"pull_ite_tree.h" -#include"push_app_ite.h" -#include"elim_term_ite.h" -#include"pattern_inference.h" -#include"nnf.h" -#include"bv_elim.h" -#include"inj_axiom.h" -#include"der.h" -#include"elim_bounds.h" -#include"warning.h" -#include"bit2int.h" -#include"distribute_forall.h" -#include"quasi_macros.h" +#include "smt/asserted_formulas.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/array_simplifier_plugin.h" +#include "ast/simplifier/datatype_simplifier_plugin.h" +#include "ast/simplifier/fpa_simplifier_plugin.h" +#include "ast/simplifier/seq_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/for_each_expr.h" +#include "ast/well_sorted.h" +#include "ast/normal_forms/pull_quant.h" +#include "ast/simplifier/pull_ite_tree.h" +#include "ast/simplifier/push_app_ite.h" +#include "smt/elim_term_ite.h" +#include "ast/pattern/pattern_inference.h" +#include "ast/normal_forms/nnf.h" +#include "ast/simplifier/bv_elim.h" +#include "ast/simplifier/inj_axiom.h" +#include "ast/rewriter/der.h" +#include "ast/simplifier/elim_bounds.h" +#include "util/warning.h" +#include "ast/simplifier/bit2int.h" +#include "ast/rewriter/distribute_forall.h" +#include "ast/macros/quasi_macros.h" asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m(m), diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h index 6ad36cc70..093680fd9 100644 --- a/src/smt/asserted_formulas.h +++ b/src/smt/asserted_formulas.h @@ -19,17 +19,17 @@ Revision History: #ifndef ASSERTED_FORMULAS_H_ #define ASSERTED_FORMULAS_H_ -#include"smt_params.h" -#include"simplifier.h" -#include"basic_simplifier_plugin.h" -#include"static_features.h" -#include"macro_manager.h" -#include"macro_finder.h" -#include"defined_names.h" -#include"maximise_ac_sharing.h" -#include"bit2int.h" -#include"statistics.h" -#include"pattern_inference.h" +#include "smt/params/smt_params.h" +#include "ast/simplifier/simplifier.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/static_features.h" +#include "ast/macros/macro_manager.h" +#include "ast/macros/macro_finder.h" +#include "ast/normal_forms/defined_names.h" +#include "ast/simplifier/maximise_ac_sharing.h" +#include "ast/simplifier/bit2int.h" +#include "util/statistics.h" +#include "ast/pattern/pattern_inference.h" class arith_simplifier_plugin; class bv_simplifier_plugin; diff --git a/src/smt/cached_var_subst.cpp b/src/smt/cached_var_subst.cpp index c36eb6dd2..7c0997bc5 100644 --- a/src/smt/cached_var_subst.cpp +++ b/src/smt/cached_var_subst.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"cached_var_subst.h" +#include "smt/cached_var_subst.h" bool cached_var_subst::key_eq_proc::operator()(cached_var_subst::key * k1, cached_var_subst::key * k2) const { if (k1->m_qa != k2->m_qa) diff --git a/src/smt/cached_var_subst.h b/src/smt/cached_var_subst.h index f9a08a810..6f39841b6 100644 --- a/src/smt/cached_var_subst.h +++ b/src/smt/cached_var_subst.h @@ -19,9 +19,9 @@ Revision History: #ifndef CACHED_VAR_SUBST_H_ #define CACHED_VAR_SUBST_H_ -#include"var_subst.h" -#include"map.h" -#include"smt_enode.h" +#include "ast/rewriter/var_subst.h" +#include "util/map.h" +#include "smt/smt_enode.h" class cached_var_subst { struct key { diff --git a/src/smt/cost_evaluator.cpp b/src/smt/cost_evaluator.cpp index fe30f9261..94151f2b3 100644 --- a/src/smt/cost_evaluator.cpp +++ b/src/smt/cost_evaluator.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"cost_evaluator.h" -#include"warning.h" +#include "smt/cost_evaluator.h" +#include "util/warning.h" cost_evaluator::cost_evaluator(ast_manager & m): m_manager(m), diff --git a/src/smt/cost_evaluator.h b/src/smt/cost_evaluator.h index e6f7fa6e0..73b307fbe 100644 --- a/src/smt/cost_evaluator.h +++ b/src/smt/cost_evaluator.h @@ -19,8 +19,8 @@ Revision History: #ifndef COST_EVALUATOR_H_ #define COST_EVALUATOR_H_ -#include"ast.h" -#include"arith_decl_plugin.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" class cost_evaluator { ast_manager & m_manager; diff --git a/src/smt/diff_logic.h b/src/smt/diff_logic.h index f55945ce4..67d1f045d 100644 --- a/src/smt/diff_logic.h +++ b/src/smt/diff_logic.h @@ -19,12 +19,12 @@ Revision History: #ifndef DIFF_LOGIC_H_ #define DIFF_LOGIC_H_ -#include"vector.h" -#include"heap.h" -#include"statistics.h" -#include"trace.h" -#include"warning.h" -#include"uint_set.h" +#include "util/vector.h" +#include "util/heap.h" +#include "util/statistics.h" +#include "util/trace.h" +#include "util/warning.h" +#include "util/uint_set.h" #include typedef int dl_var; diff --git a/src/smt/dyn_ack.cpp b/src/smt/dyn_ack.cpp index 533d143c3..baa8129bb 100644 --- a/src/smt/dyn_ack.cpp +++ b/src/smt/dyn_ack.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"dyn_ack.h" -#include"ast_pp.h" +#include "smt/smt_context.h" +#include "smt/dyn_ack.h" +#include "ast/ast_pp.h" namespace smt { diff --git a/src/smt/dyn_ack.h b/src/smt/dyn_ack.h index 0c390f0ba..9986dd498 100644 --- a/src/smt/dyn_ack.h +++ b/src/smt/dyn_ack.h @@ -19,12 +19,12 @@ Revision History: #ifndef DYN_ACK_H_ #define DYN_ACK_H_ -#include"ast.h" -#include"dyn_ack_params.h" -#include"obj_hashtable.h" -#include"obj_pair_hashtable.h" -#include"obj_triple_hashtable.h" -#include"smt_clause.h" +#include "ast/ast.h" +#include "smt/params/dyn_ack_params.h" +#include "util/obj_hashtable.h" +#include "util/obj_pair_hashtable.h" +#include "util/obj_triple_hashtable.h" +#include "smt/smt_clause.h" namespace smt { diff --git a/src/smt/elim_term_ite.cpp b/src/smt/elim_term_ite.cpp index 74b804c21..b750e6bf5 100644 --- a/src/smt/elim_term_ite.cpp +++ b/src/smt/elim_term_ite.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"elim_term_ite.h" -#include"ast_smt2_pp.h" +#include "smt/elim_term_ite.h" +#include "ast/ast_smt2_pp.h" void elim_term_ite::operator()(expr * n, expr_ref_vector & new_defs, diff --git a/src/smt/elim_term_ite.h b/src/smt/elim_term_ite.h index fc682b39a..2b9c66a64 100644 --- a/src/smt/elim_term_ite.h +++ b/src/smt/elim_term_ite.h @@ -19,8 +19,8 @@ Revision History: #ifndef ELIM_TERM_ITE_H_ #define ELIM_TERM_ITE_H_ -#include"simplifier.h" -#include"defined_names.h" +#include "ast/simplifier/simplifier.h" +#include "ast/normal_forms/defined_names.h" class elim_term_ite : public simplifier { defined_names & m_defined_names; diff --git a/src/smt/expr_context_simplifier.cpp b/src/smt/expr_context_simplifier.cpp index 66252c3cf..c420543e1 100644 --- a/src/smt/expr_context_simplifier.cpp +++ b/src/smt/expr_context_simplifier.cpp @@ -17,11 +17,11 @@ Revision History: --*/ -#include "expr_context_simplifier.h" -#include "ast_pp.h" -#include "obj_hashtable.h" -#include "smt_kernel.h" -#include "for_each_expr.h" +#include "smt/expr_context_simplifier.h" +#include "ast/ast_pp.h" +#include "util/obj_hashtable.h" +#include "smt/smt_kernel.h" +#include "ast/for_each_expr.h" // table lookup before/after simplification. diff --git a/src/smt/expr_context_simplifier.h b/src/smt/expr_context_simplifier.h index 7745bffff..ed15044e7 100644 --- a/src/smt/expr_context_simplifier.h +++ b/src/smt/expr_context_simplifier.h @@ -19,12 +19,12 @@ Revision History: #ifndef EXPR_CONTEXT_SIMPLIFIER_H_ #define EXPR_CONTEXT_SIMPLIFIER_H_ -#include "ast.h" -#include "obj_hashtable.h" -#include "basic_simplifier_plugin.h" -#include "smt_params.h" -#include "smt_kernel.h" -#include "arith_decl_plugin.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "smt/params/smt_params.h" +#include "smt/smt_kernel.h" +#include "ast/arith_decl_plugin.h" class expr_context_simplifier { typedef obj_map context_map; diff --git a/src/smt/fingerprints.cpp b/src/smt/fingerprints.cpp index 6cb0bfd2a..435350396 100644 --- a/src/smt/fingerprints.cpp +++ b/src/smt/fingerprints.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"fingerprints.h" +#include "smt/fingerprints.h" namespace smt { diff --git a/src/smt/fingerprints.h b/src/smt/fingerprints.h index 80905f8be..fc3259ca7 100644 --- a/src/smt/fingerprints.h +++ b/src/smt/fingerprints.h @@ -19,7 +19,7 @@ Revision History: #ifndef FINGERPRINTS_H_ #define FINGERPRINTS_H_ -#include"smt_enode.h" +#include "smt/smt_enode.h" namespace smt { diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index ba9f970a2..f59a57bf3 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -16,14 +16,14 @@ Author: Revision History: --*/ -#include"mam.h" -#include"smt_context.h" -#include"pool.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"trail.h" -#include"stopwatch.h" -#include"ast_smt2_pp.h" +#include "smt/mam.h" +#include "smt/smt_context.h" +#include "util/pool.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "util/trail.h" +#include "util/stopwatch.h" +#include "ast/ast_smt2_pp.h" #include // #define _PROFILE_MAM diff --git a/src/smt/mam.h b/src/smt/mam.h index dd56d7984..635cb30e7 100644 --- a/src/smt/mam.h +++ b/src/smt/mam.h @@ -19,8 +19,8 @@ Revision History: #ifndef MAM_H_ #define MAM_H_ -#include"ast.h" -#include"smt_types.h" +#include "ast/ast.h" +#include "smt/smt_types.h" namespace smt { /** diff --git a/src/smt/old_interval.cpp b/src/smt/old_interval.cpp index da03bc03e..d126c2f32 100644 --- a/src/smt/old_interval.cpp +++ b/src/smt/old_interval.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"old_interval.h" +#include "smt/old_interval.h" void ext_numeral::neg() { switch (m_kind) { diff --git a/src/smt/old_interval.h b/src/smt/old_interval.h index b2f1d8fbd..e9cb73b8f 100644 --- a/src/smt/old_interval.h +++ b/src/smt/old_interval.h @@ -19,8 +19,8 @@ Revision History: #ifndef OLD_INTERVAL_H_ #define OLD_INTERVAL_H_ -#include"rational.h" -#include"dependency.h" +#include "util/rational.h" +#include "util/dependency.h" class ext_numeral { public: diff --git a/src/smt/params/dyn_ack_params.cpp b/src/smt/params/dyn_ack_params.cpp index b62530fbf..1a51b45bd 100644 --- a/src/smt/params/dyn_ack_params.cpp +++ b/src/smt/params/dyn_ack_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"dyn_ack_params.h" +#include "smt/params/dyn_ack_params.h" #include"smt_params_helper.hpp" void dyn_ack_params::updt_params(params_ref const & _p) { diff --git a/src/smt/params/dyn_ack_params.h b/src/smt/params/dyn_ack_params.h index 017b7fe94..223242788 100644 --- a/src/smt/params/dyn_ack_params.h +++ b/src/smt/params/dyn_ack_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef DYN_ACK_PARAMS_H_ #define DYN_ACK_PARAMS_H_ -#include"params.h" +#include "util/params.h" enum dyn_ack_strategy { DACK_DISABLED, diff --git a/src/smt/params/preprocessor_params.cpp b/src/smt/params/preprocessor_params.cpp index 7a0e96248..599400c0c 100644 --- a/src/smt/params/preprocessor_params.cpp +++ b/src/smt/params/preprocessor_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"preprocessor_params.h" +#include "smt/params/preprocessor_params.h" #include"smt_params_helper.hpp" void preprocessor_params::updt_local_params(params_ref const & _p) { diff --git a/src/smt/params/preprocessor_params.h b/src/smt/params/preprocessor_params.h index 4ffad48a2..c343c55fa 100644 --- a/src/smt/params/preprocessor_params.h +++ b/src/smt/params/preprocessor_params.h @@ -19,10 +19,10 @@ Revision History: #ifndef PREPROCESSOR_PARAMS_H_ #define PREPROCESSOR_PARAMS_H_ -#include"pattern_inference_params.h" -#include"bit_blaster_params.h" -#include"bv_simplifier_params.h" -#include"arith_simplifier_params.h" +#include "ast/pattern/pattern_inference_params.h" +#include "ast/rewriter/bit_blaster/bit_blaster_params.h" +#include "ast/simplifier/bv_simplifier_params.h" +#include "ast/simplifier/arith_simplifier_params.h" enum lift_ite_kind { LI_NONE, diff --git a/src/smt/params/qi_params.cpp b/src/smt/params/qi_params.cpp index 8182222e4..34a58c14e 100644 --- a/src/smt/params/qi_params.cpp +++ b/src/smt/params/qi_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"qi_params.h" +#include "smt/params/qi_params.h" #include"smt_params_helper.hpp" void qi_params::updt_params(params_ref const & _p) { diff --git a/src/smt/params/qi_params.h b/src/smt/params/qi_params.h index c9736909a..2cee6dc72 100644 --- a/src/smt/params/qi_params.h +++ b/src/smt/params/qi_params.h @@ -19,8 +19,8 @@ Revision History: #ifndef QI_PARAMS_H_ #define QI_PARAMS_H_ -#include"util.h" -#include"params.h" +#include "util/util.h" +#include "util/params.h" enum quick_checker_mode { MC_NO, // do not use (cheap) model checking based instantiation diff --git a/src/smt/params/smt_params.cpp b/src/smt/params/smt_params.cpp index 92ff1de90..453fb3e8e 100644 --- a/src/smt/params/smt_params.cpp +++ b/src/smt/params/smt_params.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"smt_params.h" +#include "smt/params/smt_params.h" #include"smt_params_helper.hpp" #include"model_params.hpp" -#include"gparams.h" +#include "util/gparams.h" void smt_params::updt_local_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/smt_params.h b/src/smt/params/smt_params.h index 4b7c924e4..5f93276a1 100644 --- a/src/smt/params/smt_params.h +++ b/src/smt/params/smt_params.h @@ -19,17 +19,17 @@ Revision History: #ifndef SMT_PARAMS_H_ #define SMT_PARAMS_H_ -#include"ast.h" -#include"dyn_ack_params.h" -#include"qi_params.h" -#include"theory_arith_params.h" -#include"theory_array_params.h" -#include"theory_bv_params.h" -#include"theory_str_params.h" -#include"theory_pb_params.h" -#include"theory_datatype_params.h" -#include"preprocessor_params.h" -#include"context_params.h" +#include "ast/ast.h" +#include "smt/params/dyn_ack_params.h" +#include "smt/params/qi_params.h" +#include "smt/params/theory_arith_params.h" +#include "smt/params/theory_array_params.h" +#include "smt/params/theory_bv_params.h" +#include "smt/params/theory_str_params.h" +#include "smt/params/theory_pb_params.h" +#include "smt/params/theory_datatype_params.h" +#include "smt/params/preprocessor_params.h" +#include "cmd_context/context_params.h" enum phase_selection { PS_ALWAYS_FALSE, diff --git a/src/smt/params/theory_arith_params.cpp b/src/smt/params/theory_arith_params.cpp index 944911f9b..e6ecd50b8 100644 --- a/src/smt/params/theory_arith_params.cpp +++ b/src/smt/params/theory_arith_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"theory_arith_params.h" +#include "smt/params/theory_arith_params.h" #include"smt_params_helper.hpp" void theory_arith_params::updt_params(params_ref const & _p) { diff --git a/src/smt/params/theory_arith_params.h b/src/smt/params/theory_arith_params.h index 943bd711e..d73a67985 100644 --- a/src/smt/params/theory_arith_params.h +++ b/src/smt/params/theory_arith_params.h @@ -20,7 +20,7 @@ Revision History: #define THEORY_ARITH_PARAMS_H_ #include -#include"params.h" +#include "util/params.h" enum arith_solver_id { AS_NO_ARITH, diff --git a/src/smt/params/theory_array_params.cpp b/src/smt/params/theory_array_params.cpp index c0015bf2c..a73411c7f 100644 --- a/src/smt/params/theory_array_params.cpp +++ b/src/smt/params/theory_array_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"theory_array_params.h" +#include "smt/params/theory_array_params.h" #include"smt_params_helper.hpp" void theory_array_params::updt_params(params_ref const & _p) { diff --git a/src/smt/params/theory_array_params.h b/src/smt/params/theory_array_params.h index af51427c4..af3fdebeb 100644 --- a/src/smt/params/theory_array_params.h +++ b/src/smt/params/theory_array_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef THEORY_ARRAY_PARAMS_H_ #define THEORY_ARRAY_PARAMS_H_ -#include"array_simplifier_params.h" +#include "ast/simplifier/array_simplifier_params.h" enum array_solver_id { AR_NO_ARRAY, diff --git a/src/smt/params/theory_bv_params.cpp b/src/smt/params/theory_bv_params.cpp index 631c5765b..48ad07047 100644 --- a/src/smt/params/theory_bv_params.cpp +++ b/src/smt/params/theory_bv_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"theory_bv_params.h" +#include "smt/params/theory_bv_params.h" #include"smt_params_helper.hpp" void theory_bv_params::updt_params(params_ref const & _p) { diff --git a/src/smt/params/theory_bv_params.h b/src/smt/params/theory_bv_params.h index 5830e5176..52aaa4c9c 100644 --- a/src/smt/params/theory_bv_params.h +++ b/src/smt/params/theory_bv_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef THEORY_BV_PARAMS_H_ #define THEORY_BV_PARAMS_H_ -#include"params.h" +#include "util/params.h" enum bv_solver_id { BS_NO_BV, diff --git a/src/smt/params/theory_pb_params.cpp b/src/smt/params/theory_pb_params.cpp index a1e13a6e7..be1cc681b 100644 --- a/src/smt/params/theory_pb_params.cpp +++ b/src/smt/params/theory_pb_params.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"theory_pb_params.h" +#include "smt/params/theory_pb_params.h" #include"smt_params_helper.hpp" void theory_pb_params::updt_params(params_ref const & _p) { diff --git a/src/smt/params/theory_pb_params.h b/src/smt/params/theory_pb_params.h index 6a129e601..9bfd262c4 100644 --- a/src/smt/params/theory_pb_params.h +++ b/src/smt/params/theory_pb_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef THEORY_PB_PARAMS_H_ #define THEORY_PB_PARAMS_H_ -#include"params.h" +#include "util/params.h" struct theory_pb_params { diff --git a/src/smt/params/theory_str_params.cpp b/src/smt/params/theory_str_params.cpp index 6090086b8..62dc881d8 100644 --- a/src/smt/params/theory_str_params.cpp +++ b/src/smt/params/theory_str_params.cpp @@ -15,7 +15,7 @@ Revision History: --*/ -#include"theory_str_params.h" +#include "smt/params/theory_str_params.h" #include"smt_params_helper.hpp" void theory_str_params::updt_params(params_ref const & _p) { diff --git a/src/smt/params/theory_str_params.h b/src/smt/params/theory_str_params.h index 207b635d7..c841609db 100644 --- a/src/smt/params/theory_str_params.h +++ b/src/smt/params/theory_str_params.h @@ -18,7 +18,7 @@ Revision History: #ifndef THEORY_STR_PARAMS_H #define THEORY_STR_PARAMS_H -#include"params.h" +#include "util/params.h" struct theory_str_params { /* diff --git a/src/smt/proto_model/array_factory.cpp b/src/smt/proto_model/array_factory.cpp index a929f6d9a..d112331f0 100644 --- a/src/smt/proto_model/array_factory.cpp +++ b/src/smt/proto_model/array_factory.cpp @@ -17,11 +17,11 @@ Revision History: --*/ -#include"array_factory.h" -#include"array_decl_plugin.h" -#include"proto_model.h" -#include"func_interp.h" -#include"ast_pp.h" +#include "smt/proto_model/array_factory.h" +#include "ast/array_decl_plugin.h" +#include "smt/proto_model/proto_model.h" +#include "model/func_interp.h" +#include "ast/ast_pp.h" func_decl * mk_aux_decl_for_array_sort(ast_manager & m, sort * s) { ptr_buffer domain; diff --git a/src/smt/proto_model/array_factory.h b/src/smt/proto_model/array_factory.h index 6801ae081..4d4f52944 100644 --- a/src/smt/proto_model/array_factory.h +++ b/src/smt/proto_model/array_factory.h @@ -19,7 +19,7 @@ Revision History: #ifndef ARRAY_FACTORY_H_ #define ARRAY_FACTORY_H_ -#include"struct_factory.h" +#include "smt/proto_model/struct_factory.h" class func_interp; diff --git a/src/smt/proto_model/datatype_factory.cpp b/src/smt/proto_model/datatype_factory.cpp index 3b0ec8e5f..f5079b0e5 100644 --- a/src/smt/proto_model/datatype_factory.cpp +++ b/src/smt/proto_model/datatype_factory.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"datatype_factory.h" -#include"proto_model.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"expr_functors.h" +#include "smt/proto_model/datatype_factory.h" +#include "smt/proto_model/proto_model.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/expr_functors.h" datatype_factory::datatype_factory(ast_manager & m, proto_model & md): struct_factory(m, m.mk_family_id("datatype"), md), diff --git a/src/smt/proto_model/datatype_factory.h b/src/smt/proto_model/datatype_factory.h index 3dddb843d..9f64b8daa 100644 --- a/src/smt/proto_model/datatype_factory.h +++ b/src/smt/proto_model/datatype_factory.h @@ -19,8 +19,8 @@ Revision History: #ifndef DATATYPE_FACTORY_H_ #define DATATYPE_FACTORY_H_ -#include"struct_factory.h" -#include"datatype_decl_plugin.h" +#include "smt/proto_model/struct_factory.h" +#include "ast/datatype_decl_plugin.h" class datatype_factory : public struct_factory { datatype_util m_util; diff --git a/src/smt/proto_model/numeral_factory.cpp b/src/smt/proto_model/numeral_factory.cpp index 49ff15167..a5d5ac18a 100644 --- a/src/smt/proto_model/numeral_factory.cpp +++ b/src/smt/proto_model/numeral_factory.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"numeral_factory.h" -#include"ast_pp.h" +#include "smt/proto_model/numeral_factory.h" +#include "ast/ast_pp.h" app * arith_factory::mk_value_core(rational const & val, sort * s) { return m_util.mk_numeral(val, s); diff --git a/src/smt/proto_model/numeral_factory.h b/src/smt/proto_model/numeral_factory.h index 9b1ff6a81..f1b68223b 100644 --- a/src/smt/proto_model/numeral_factory.h +++ b/src/smt/proto_model/numeral_factory.h @@ -19,9 +19,9 @@ Revision History: #ifndef NUMERAL_FACTORY_H_ #define NUMERAL_FACTORY_H_ -#include"value_factory.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" +#include "smt/proto_model/value_factory.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" class numeral_factory : public simple_factory { public: diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index 129bed87e..c69fa6edc 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -16,15 +16,15 @@ Author: Revision History: --*/ -#include"proto_model.h" +#include "smt/proto_model/proto_model.h" #include"model_params.hpp" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"var_subst.h" -#include"array_decl_plugin.h" -#include"well_sorted.h" -#include"used_symbols.h" -#include"model_v2_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/rewriter/var_subst.h" +#include "ast/array_decl_plugin.h" +#include "ast/well_sorted.h" +#include "ast/used_symbols.h" +#include "model/model_v2_pp.h" proto_model::proto_model(ast_manager & m, params_ref const & p): model_core(m), @@ -441,8 +441,8 @@ model * proto_model::mk_model() { #if 0 -#include"simplifier.h" -#include"basic_simplifier_plugin.h" +#include "ast/simplifier/simplifier.h" +#include "ast/simplifier/basic_simplifier_plugin.h" // Auxiliary function for computing fi(args[0], ..., args[fi.get_arity() - 1]). // The result is stored in result. diff --git a/src/smt/proto_model/proto_model.h b/src/smt/proto_model/proto_model.h index 78dc457f5..1cee04650 100644 --- a/src/smt/proto_model/proto_model.h +++ b/src/smt/proto_model/proto_model.h @@ -28,15 +28,15 @@ Revision History: #ifndef PROTO_MODEL_H_ #define PROTO_MODEL_H_ -#include"model_core.h" -#include"model_evaluator.h" -#include"value_factory.h" -#include"plugin_manager.h" -#include"arith_decl_plugin.h" -#include"func_decl_dependencies.h" -#include"model.h" -#include"params.h" -#include"th_rewriter.h" +#include "model/model_core.h" +#include "model/model_evaluator.h" +#include "smt/proto_model/value_factory.h" +#include "util/plugin_manager.h" +#include "ast/arith_decl_plugin.h" +#include "ast/func_decl_dependencies.h" +#include "model/model.h" +#include "util/params.h" +#include "ast/rewriter/th_rewriter.h" class proto_model : public model_core { plugin_manager m_factories; diff --git a/src/smt/proto_model/struct_factory.cpp b/src/smt/proto_model/struct_factory.cpp index 173554b83..8d85c6485 100644 --- a/src/smt/proto_model/struct_factory.cpp +++ b/src/smt/proto_model/struct_factory.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"struct_factory.h" -#include"proto_model.h" +#include "smt/proto_model/struct_factory.h" +#include "smt/proto_model/proto_model.h" struct_factory::value_set * struct_factory::get_value_set(sort * s) { value_set * set = 0; diff --git a/src/smt/proto_model/struct_factory.h b/src/smt/proto_model/struct_factory.h index f18121af8..bfbd90ede 100644 --- a/src/smt/proto_model/struct_factory.h +++ b/src/smt/proto_model/struct_factory.h @@ -19,8 +19,8 @@ Revision History: #ifndef STRUCT_FACTORY_H_ #define STRUCT_FACTORY_H_ -#include"value_factory.h" -#include"obj_hashtable.h" +#include "smt/proto_model/value_factory.h" +#include "util/obj_hashtable.h" class proto_model; diff --git a/src/smt/proto_model/value_factory.cpp b/src/smt/proto_model/value_factory.cpp index 93294d898..e41696165 100644 --- a/src/smt/proto_model/value_factory.cpp +++ b/src/smt/proto_model/value_factory.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"value_factory.h" +#include "smt/proto_model/value_factory.h" value_factory::value_factory(ast_manager & m, family_id fid): m_manager(m), diff --git a/src/smt/proto_model/value_factory.h b/src/smt/proto_model/value_factory.h index f841e18ea..e81c63306 100644 --- a/src/smt/proto_model/value_factory.h +++ b/src/smt/proto_model/value_factory.h @@ -19,8 +19,8 @@ Revision History: #ifndef VALUE_FACTORY_H_ #define VALUE_FACTORY_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" /** \brief Auxiliary object used during model construction. diff --git a/src/smt/qi_queue.cpp b/src/smt/qi_queue.cpp index 70a3041d2..36a2ce834 100644 --- a/src/smt/qi_queue.cpp +++ b/src/smt/qi_queue.cpp @@ -16,13 +16,13 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"qi_queue.h" -#include"warning.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"var_subst.h" -#include"stats.h" +#include "smt/smt_context.h" +#include "smt/qi_queue.h" +#include "util/warning.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/rewriter/var_subst.h" +#include "util/stats.h" namespace smt { diff --git a/src/smt/qi_queue.h b/src/smt/qi_queue.h index 0db12d537..171466e42 100644 --- a/src/smt/qi_queue.h +++ b/src/smt/qi_queue.h @@ -19,16 +19,16 @@ Revision History: #ifndef QI_QUEUE_H_ #define QI_QUEUE_H_ -#include"ast.h" -#include"smt_quantifier_stat.h" -#include"smt_checker.h" -#include"smt_quantifier.h" -#include"qi_params.h" -#include"fingerprints.h" -#include"cost_parser.h" -#include"cost_evaluator.h" -#include"cached_var_subst.h" -#include"statistics.h" +#include "ast/ast.h" +#include "smt/smt_quantifier_stat.h" +#include "smt/smt_checker.h" +#include "smt/smt_quantifier.h" +#include "smt/params/qi_params.h" +#include "smt/fingerprints.h" +#include "parsers/util/cost_parser.h" +#include "smt/cost_evaluator.h" +#include "smt/cached_var_subst.h" +#include "util/statistics.h" namespace smt { class context; diff --git a/src/smt/smt2_extra_cmds.cpp b/src/smt/smt2_extra_cmds.cpp index 61b247207..136805e43 100644 --- a/src/smt/smt2_extra_cmds.cpp +++ b/src/smt/smt2_extra_cmds.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"cmd_context.h" -#include"smt2parser.h" -#include"smt2_extra_cmds.h" +#include "cmd_context/cmd_context.h" +#include "parsers/smt2/smt2parser.h" +#include "smt/smt2_extra_cmds.h" class include_cmd : public cmd { char const * m_filename; diff --git a/src/smt/smt_almost_cg_table.cpp b/src/smt/smt_almost_cg_table.cpp index 66eb8c533..4d24ea0d0 100644 --- a/src/smt/smt_almost_cg_table.cpp +++ b/src/smt/smt_almost_cg_table.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"smt_almost_cg_table.h" +#include "smt/smt_almost_cg_table.h" namespace smt { diff --git a/src/smt/smt_almost_cg_table.h b/src/smt/smt_almost_cg_table.h index aee36c2a0..7807f705a 100644 --- a/src/smt/smt_almost_cg_table.h +++ b/src/smt/smt_almost_cg_table.h @@ -19,8 +19,8 @@ Revision History: #ifndef SMT_ALMOST_CG_TABLE_H_ #define SMT_ALMOST_CG_TABLE_H_ -#include"smt_enode.h" -#include"map.h" +#include "smt/smt_enode.h" +#include "util/map.h" namespace smt { diff --git a/src/smt/smt_b_justification.h b/src/smt/smt_b_justification.h index 7e77d301b..700c41807 100644 --- a/src/smt/smt_b_justification.h +++ b/src/smt/smt_b_justification.h @@ -19,8 +19,8 @@ Revision History: #ifndef SMT_B_JUSTIFICATION_H_ #define SMT_B_JUSTIFICATION_H_ -#include"smt_literal.h" -#include"smt_clause.h" +#include "smt/smt_literal.h" +#include "smt/smt_clause.h" namespace smt { diff --git a/src/smt/smt_bool_var_data.h b/src/smt/smt_bool_var_data.h index af0b7f9d2..4f83ece49 100644 --- a/src/smt/smt_bool_var_data.h +++ b/src/smt/smt_bool_var_data.h @@ -19,7 +19,7 @@ Revision History: #ifndef SMT_BOOL_VAR_DATA_H_ #define SMT_BOOL_VAR_DATA_H_ -#include"smt_b_justification.h" +#include "smt/smt_b_justification.h" namespace smt { diff --git a/src/smt/smt_case_split_queue.cpp b/src/smt/smt_case_split_queue.cpp index c461b130b..6aef5f0a9 100644 --- a/src/smt/smt_case_split_queue.cpp +++ b/src/smt/smt_case_split_queue.cpp @@ -16,14 +16,14 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_case_split_queue.h" -#include"warning.h" -#include"stopwatch.h" -#include"for_each_expr.h" -#include"ast_pp.h" -#include"map.h" -#include"hashtable.h" +#include "smt/smt_context.h" +#include "smt/smt_case_split_queue.h" +#include "util/warning.h" +#include "util/stopwatch.h" +#include "ast/for_each_expr.h" +#include "ast/ast_pp.h" +#include "util/map.h" +#include "util/hashtable.h" namespace smt { diff --git a/src/smt/smt_case_split_queue.h b/src/smt/smt_case_split_queue.h index 9a3a93cc6..cfa33bfe2 100644 --- a/src/smt/smt_case_split_queue.h +++ b/src/smt/smt_case_split_queue.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMT_CASE_SPLIT_QUEUE_H_ #define SMT_CASE_SPLIT_QUEUE_H_ -#include"smt_types.h" -#include"heap.h" -#include"smt_params.h" +#include "smt/smt_types.h" +#include "util/heap.h" +#include "smt/params/smt_params.h" namespace smt { class context; diff --git a/src/smt/smt_cg_table.cpp b/src/smt/smt_cg_table.cpp index 83d137ff0..ad15fd819 100644 --- a/src/smt/smt_cg_table.cpp +++ b/src/smt/smt_cg_table.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_cg_table.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "smt/smt_cg_table.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" namespace smt { diff --git a/src/smt/smt_cg_table.h b/src/smt/smt_cg_table.h index c4674034a..1e3fd8b83 100644 --- a/src/smt/smt_cg_table.h +++ b/src/smt/smt_cg_table.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMT_CG_TABLE_H_ #define SMT_CG_TABLE_H_ -#include"smt_enode.h" -#include"hashtable.h" -#include"chashtable.h" +#include "smt/smt_enode.h" +#include "util/hashtable.h" +#include "util/chashtable.h" namespace smt { diff --git a/src/smt/smt_checker.cpp b/src/smt/smt_checker.cpp index 176769d77..a7a25037c 100644 --- a/src/smt/smt_checker.cpp +++ b/src/smt/smt_checker.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_checker.h" -#include"ast_ll_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_checker.h" +#include "ast/ast_ll_pp.h" namespace smt { diff --git a/src/smt/smt_checker.h b/src/smt/smt_checker.h index f6df63c59..5e841f572 100644 --- a/src/smt/smt_checker.h +++ b/src/smt/smt_checker.h @@ -19,8 +19,8 @@ Revision History: #ifndef SMT_CHECKER_H_ #define SMT_CHECKER_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" namespace smt { diff --git a/src/smt/smt_clause.cpp b/src/smt/smt_clause.cpp index d0f6bdeaa..ccb336941 100644 --- a/src/smt/smt_clause.cpp +++ b/src/smt/smt_clause.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_clause.h" -#include"smt_justification.h" -#include"ast_ll_pp.h" +#include "smt/smt_clause.h" +#include "smt/smt_justification.h" +#include "ast/ast_ll_pp.h" namespace smt { /** diff --git a/src/smt/smt_clause.h b/src/smt/smt_clause.h index 17d13a1dc..d4b9ee02f 100644 --- a/src/smt/smt_clause.h +++ b/src/smt/smt_clause.h @@ -19,11 +19,11 @@ Revision History: #ifndef SMT_CLAUSE_H_ #define SMT_CLAUSE_H_ -#include"ast.h" -#include"smt_literal.h" -#include"tptr.h" -#include"obj_hashtable.h" -#include"smt_justification.h" +#include "ast/ast.h" +#include "smt/smt_literal.h" +#include "util/tptr.h" +#include "util/obj_hashtable.h" +#include "smt/smt_justification.h" namespace smt { diff --git a/src/smt/smt_conflict_resolution.cpp b/src/smt/smt_conflict_resolution.cpp index ade667e34..79a1f0416 100644 --- a/src/smt/smt_conflict_resolution.cpp +++ b/src/smt/smt_conflict_resolution.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_conflict_resolution.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_conflict_resolution.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" namespace smt { diff --git a/src/smt/smt_conflict_resolution.h b/src/smt/smt_conflict_resolution.h index fad3ab50d..b5b857184 100644 --- a/src/smt/smt_conflict_resolution.h +++ b/src/smt/smt_conflict_resolution.h @@ -19,17 +19,17 @@ Revision History: #ifndef SMT_CONFLICT_RESOLUTION_H_ #define SMT_CONFLICT_RESOLUTION_H_ -#include"smt_literal.h" -#include"smt_bool_var_data.h" -#include"smt_justification.h" -#include"smt_enode.h" -#include"dyn_ack.h" -#include"obj_pair_hashtable.h" -#include"smt_params.h" -#include"obj_pair_hashtable.h" -#include"map.h" -#include"watch_list.h" -#include"obj_pair_set.h" +#include "smt/smt_literal.h" +#include "smt/smt_bool_var_data.h" +#include "smt/smt_justification.h" +#include "smt/smt_enode.h" +#include "smt/dyn_ack.h" +#include "util/obj_pair_hashtable.h" +#include "smt/params/smt_params.h" +#include "util/obj_pair_hashtable.h" +#include "util/map.h" +#include "smt/watch_list.h" +#include "util/obj_pair_set.h" typedef approx_set_tpl level_approx_set; diff --git a/src/smt/smt_consequences.cpp b/src/smt/smt_consequences.cpp index 20813602e..65af3c0bd 100644 --- a/src/smt/smt_consequences.cpp +++ b/src/smt/smt_consequences.cpp @@ -16,12 +16,12 @@ Author: Revision History: --*/ -#include "smt_context.h" -#include "ast_util.h" -#include "datatype_decl_plugin.h" -#include "model_pp.h" -#include "max_cliques.h" -#include "stopwatch.h" +#include "smt/smt_context.h" +#include "ast/ast_util.h" +#include "ast/datatype_decl_plugin.h" +#include "model/model_pp.h" +#include "util/max_cliques.h" +#include "util/stopwatch.h" namespace smt { diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 1b428520e..ff64be64b 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -17,26 +17,26 @@ Revision History: --*/ #include -#include"smt_context.h" -#include"luby.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"warning.h" -#include"smt_quick_checker.h" -#include"proof_checker.h" -#include"ast_util.h" -#include"uses_theory.h" -#include"model.h" -#include"smt_for_each_relevant_expr.h" -#include"timeit.h" -#include"well_sorted.h" -#include"union_find.h" -#include"smt_model_generator.h" -#include"smt_model_checker.h" -#include"smt_model_finder.h" -#include"model_pp.h" -#include"ast_smt2_pp.h" -#include"ast_translation.h" +#include "smt/smt_context.h" +#include "util/luby.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "util/warning.h" +#include "smt/smt_quick_checker.h" +#include "ast/proof_checker/proof_checker.h" +#include "ast/ast_util.h" +#include "smt/uses_theory.h" +#include "model/model.h" +#include "smt/smt_for_each_relevant_expr.h" +#include "util/timeit.h" +#include "ast/well_sorted.h" +#include "util/union_find.h" +#include "smt/smt_model_generator.h" +#include "smt/smt_model_checker.h" +#include "smt/smt_model_finder.h" +#include "model/model_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_translation.h" namespace smt { diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index 6b3129d91..84bf9f62a 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -19,36 +19,36 @@ Revision History: #ifndef SMT_CONTEXT_H_ #define SMT_CONTEXT_H_ -#include"smt_clause.h" -#include"smt_setup.h" -#include"smt_enode.h" -#include"smt_cg_table.h" -#include"smt_b_justification.h" -#include"smt_eq_justification.h" -#include"smt_justification.h" -#include"smt_bool_var_data.h" -#include"smt_theory.h" -#include"smt_quantifier.h" -#include"smt_quantifier_stat.h" -#include"smt_statistics.h" -#include"smt_conflict_resolution.h" -#include"smt_relevancy.h" -#include"smt_case_split_queue.h" -#include"smt_almost_cg_table.h" -#include"smt_failure.h" -#include"asserted_formulas.h" -#include"smt_types.h" -#include"dyn_ack.h" -#include"ast_smt_pp.h" -#include"watch_list.h" -#include"trail.h" -#include"fingerprints.h" -#include"ref.h" -#include"proto_model.h" -#include"model.h" -#include"timer.h" -#include"statistics.h" -#include"progress_callback.h" +#include "smt/smt_clause.h" +#include "smt/smt_setup.h" +#include "smt/smt_enode.h" +#include "smt/smt_cg_table.h" +#include "smt/smt_b_justification.h" +#include "smt/smt_eq_justification.h" +#include "smt/smt_justification.h" +#include "smt/smt_bool_var_data.h" +#include "smt/smt_theory.h" +#include "smt/smt_quantifier.h" +#include "smt/smt_quantifier_stat.h" +#include "smt/smt_statistics.h" +#include "smt/smt_conflict_resolution.h" +#include "smt/smt_relevancy.h" +#include "smt/smt_case_split_queue.h" +#include "smt/smt_almost_cg_table.h" +#include "smt/smt_failure.h" +#include "smt/asserted_formulas.h" +#include "smt/smt_types.h" +#include "smt/dyn_ack.h" +#include "ast/ast_smt_pp.h" +#include "smt/watch_list.h" +#include "util/trail.h" +#include "smt/fingerprints.h" +#include "util/ref.h" +#include "smt/proto_model/proto_model.h" +#include "model/model.h" +#include "util/timer.h" +#include "util/statistics.h" +#include "solver/progress_callback.h" // there is a significant space overhead with allocating 1000+ contexts in // the case that each context only references a few expressions. diff --git a/src/smt/smt_context_inv.cpp b/src/smt/smt_context_inv.cpp index e6551b8da..cf09c996a 100644 --- a/src/smt/smt_context_inv.cpp +++ b/src/smt/smt_context_inv.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/smt_context_pp.cpp b/src/smt/smt_context_pp.cpp index 73d822fb4..6d66368ff 100644 --- a/src/smt/smt_context_pp.cpp +++ b/src/smt/smt_context_pp.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"ast_smt_pp.h" -#include"stats.h" +#include "smt/smt_context.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt_pp.h" +#include "util/stats.h" namespace smt { diff --git a/src/smt/smt_context_stat.cpp b/src/smt/smt_context_stat.cpp index 3838a88b5..968d84b73 100644 --- a/src/smt/smt_context_stat.cpp +++ b/src/smt/smt_context_stat.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"ast_pp.h" +#include "smt/smt_context.h" +#include "ast/ast_pp.h" namespace smt { diff --git a/src/smt/smt_enode.cpp b/src/smt/smt_enode.cpp index 679c46720..1452dc610 100644 --- a/src/smt/smt_enode.cpp +++ b/src/smt/smt_enode.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_enode.h" +#include "smt/smt_context.h" +#include "smt/smt_enode.h" namespace smt { diff --git a/src/smt/smt_enode.h b/src/smt/smt_enode.h index 69a882c99..4b3a64d90 100644 --- a/src/smt/smt_enode.h +++ b/src/smt/smt_enode.h @@ -19,11 +19,11 @@ Revision History: #ifndef SMT_ENODE_H_ #define SMT_ENODE_H_ -#include"ast.h" -#include"smt_types.h" -#include"smt_eq_justification.h" -#include"smt_theory_var_list.h" -#include"approx_set.h" +#include "ast/ast.h" +#include "smt/smt_types.h" +#include "smt/smt_eq_justification.h" +#include "smt/smt_theory_var_list.h" +#include "util/approx_set.h" namespace smt { /** diff --git a/src/smt/smt_eq_justification.h b/src/smt/smt_eq_justification.h index b12eda192..af538a130 100644 --- a/src/smt/smt_eq_justification.h +++ b/src/smt/smt_eq_justification.h @@ -19,8 +19,8 @@ Revision History: #ifndef SMT_EQ_JUSTIFICATION_H_ #define SMT_EQ_JUSTIFICATION_H_ -#include"smt_literal.h" -#include"tptr.h" +#include "smt/smt_literal.h" +#include "util/tptr.h" namespace smt { diff --git a/src/smt/smt_farkas_util.cpp b/src/smt/smt_farkas_util.cpp index c5ff42e3e..ff415ad0c 100644 --- a/src/smt/smt_farkas_util.cpp +++ b/src/smt/smt_farkas_util.cpp @@ -19,10 +19,10 @@ Revision History: --*/ -#include "smt_farkas_util.h" -#include "ast_pp.h" -#include "th_rewriter.h" -#include "bool_rewriter.h" +#include "smt/smt_farkas_util.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/bool_rewriter.h" namespace smt { diff --git a/src/smt/smt_farkas_util.h b/src/smt/smt_farkas_util.h index 575df45ee..1fc6a3681 100644 --- a/src/smt/smt_farkas_util.h +++ b/src/smt/smt_farkas_util.h @@ -22,7 +22,7 @@ Revision History: #ifndef FARKAS_UTIL_H_ #define FARKAS_UTIL_H_ -#include "arith_decl_plugin.h" +#include "ast/arith_decl_plugin.h" namespace smt { diff --git a/src/smt/smt_for_each_relevant_expr.cpp b/src/smt/smt_for_each_relevant_expr.cpp index 84f93dd33..30b69a149 100644 --- a/src/smt/smt_for_each_relevant_expr.cpp +++ b/src/smt/smt_for_each_relevant_expr.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_for_each_relevant_expr.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_for_each_relevant_expr.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" namespace smt { diff --git a/src/smt/smt_for_each_relevant_expr.h b/src/smt/smt_for_each_relevant_expr.h index abbc1894d..b81023349 100644 --- a/src/smt/smt_for_each_relevant_expr.h +++ b/src/smt/smt_for_each_relevant_expr.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMT_FOR_EACH_RELEVANT_EXPR_H_ #define SMT_FOR_EACH_RELEVANT_EXPR_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"vector.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "util/vector.h" namespace smt { diff --git a/src/smt/smt_implied_equalities.cpp b/src/smt/smt_implied_equalities.cpp index 888827754..7d54e714e 100644 --- a/src/smt/smt_implied_equalities.cpp +++ b/src/smt/smt_implied_equalities.cpp @@ -19,16 +19,16 @@ Revision History: --*/ -#include "smt_implied_equalities.h" -#include "union_find.h" -#include "ast_pp.h" -#include "array_decl_plugin.h" -#include "uint_set.h" -#include "smt_value_sort.h" -#include "model_smt2_pp.h" -#include "stopwatch.h" -#include "model.h" -#include "solver.h" +#include "smt/smt_implied_equalities.h" +#include "util/union_find.h" +#include "ast/ast_pp.h" +#include "ast/array_decl_plugin.h" +#include "util/uint_set.h" +#include "smt/smt_value_sort.h" +#include "model/model_smt2_pp.h" +#include "util/stopwatch.h" +#include "model/model.h" +#include "solver/solver.h" namespace smt { diff --git a/src/smt/smt_implied_equalities.h b/src/smt/smt_implied_equalities.h index 0dd76e439..cc7acf22b 100644 --- a/src/smt/smt_implied_equalities.h +++ b/src/smt/smt_implied_equalities.h @@ -23,9 +23,9 @@ Revision History: #ifndef SMT_IMPLIED_EQUALITIES_H_ #define SMT_IMPLIED_EQUALITIES_H_ -#include"smt_solver.h" -#include"lbool.h" -#include"ast.h" +#include "smt/smt_solver.h" +#include "util/lbool.h" +#include "ast/ast.h" namespace smt { diff --git a/src/smt/smt_internalizer.cpp b/src/smt/smt_internalizer.cpp index 5fbdb2477..58b391ac2 100644 --- a/src/smt/smt_internalizer.cpp +++ b/src/smt/smt_internalizer.cpp @@ -16,13 +16,13 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"expr_stat.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" -#include"smt_model_finder.h" -#include"for_each_expr.h" +#include "smt/smt_context.h" +#include "ast/expr_stat.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" +#include "smt/smt_model_finder.h" +#include "ast/for_each_expr.h" namespace smt { diff --git a/src/smt/smt_justification.cpp b/src/smt/smt_justification.cpp index 7a9938cd0..c8de45644 100644 --- a/src/smt/smt_justification.cpp +++ b/src/smt/smt_justification.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_conflict_resolution.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_conflict_resolution.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" namespace smt { diff --git a/src/smt/smt_justification.h b/src/smt/smt_justification.h index f4b3ecb12..0af8e61ff 100644 --- a/src/smt/smt_justification.h +++ b/src/smt/smt_justification.h @@ -19,10 +19,10 @@ Revision History: #ifndef SMT_JUSTIFICATION_H_ #define SMT_JUSTIFICATION_H_ -#include"ast.h" -#include"smt_types.h" -#include"smt_literal.h" -#include"smt_eq_justification.h" +#include "ast/ast.h" +#include "smt/smt_types.h" +#include "smt/smt_literal.h" +#include "smt/smt_eq_justification.h" namespace smt { diff --git a/src/smt/smt_kernel.cpp b/src/smt/smt_kernel.cpp index 9bdf962ec..d870d9b9a 100644 --- a/src/smt/smt_kernel.cpp +++ b/src/smt/smt_kernel.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_kernel.h" -#include"smt_context.h" -#include"ast_smt2_pp.h" +#include "smt/smt_kernel.h" +#include "smt/smt_context.h" +#include "ast/ast_smt2_pp.h" #include"smt_params_helper.hpp" namespace smt { diff --git a/src/smt/smt_kernel.h b/src/smt/smt_kernel.h index 264fae011..6ebb8546f 100644 --- a/src/smt/smt_kernel.h +++ b/src/smt/smt_kernel.h @@ -27,12 +27,12 @@ Revision History: #ifndef SMT_KERNEL_H_ #define SMT_KERNEL_H_ -#include"ast.h" -#include"params.h" -#include"model.h" -#include"lbool.h" -#include"statistics.h" -#include"smt_failure.h" +#include "ast/ast.h" +#include "util/params.h" +#include "model/model.h" +#include "util/lbool.h" +#include "util/statistics.h" +#include "smt/smt_failure.h" struct smt_params; class progress_callback; diff --git a/src/smt/smt_literal.cpp b/src/smt/smt_literal.cpp index e6e795ed4..86a9f0b0c 100644 --- a/src/smt/smt_literal.cpp +++ b/src/smt/smt_literal.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_literal.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "smt/smt_literal.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" namespace smt { diff --git a/src/smt/smt_literal.h b/src/smt/smt_literal.h index 3dbd6911e..7f554d740 100644 --- a/src/smt/smt_literal.h +++ b/src/smt/smt_literal.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMT_LITERAL_H_ #define SMT_LITERAL_H_ -#include"ast.h" -#include"smt_types.h" -#include"approx_set.h" +#include "ast/ast.h" +#include "smt/smt_types.h" +#include "util/approx_set.h" namespace smt { /** diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index b50527acf..d5b8415c3 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -17,16 +17,16 @@ Revision History: --*/ -#include"smt_model_checker.h" -#include"smt_context.h" -#include"smt_model_finder.h" -#include"pull_quant.h" -#include"for_each_expr.h" -#include"var_subst.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"model_pp.h" -#include"ast_smt2_pp.h" +#include "smt/smt_model_checker.h" +#include "smt/smt_context.h" +#include "smt/smt_model_finder.h" +#include "ast/normal_forms/pull_quant.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "model/model_pp.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/smt_model_checker.h b/src/smt/smt_model_checker.h index 1b7713d59..7f2ed8ca7 100644 --- a/src/smt/smt_model_checker.h +++ b/src/smt/smt_model_checker.h @@ -21,11 +21,11 @@ Revision History: #ifndef SMT_MODEL_CHECKER_H_ #define SMT_MODEL_CHECKER_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"qi_params.h" -#include"smt_params.h" -#include"region.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "smt/params/qi_params.h" +#include "smt/params/smt_params.h" +#include "util/region.h" class proto_model; class model; diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index eb113b484..35a98aa01 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -16,26 +16,26 @@ Author: Revision History: --*/ -#include"smt_model_finder.h" -#include"smt_context.h" -#include"ast_util.h" -#include"macro_util.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"arith_simplifier_plugin.h" -#include"bv_simplifier_plugin.h" -#include"pull_quant.h" -#include"var_subst.h" -#include"backtrackable_set.h" -#include"for_each_expr.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"well_sorted.h" -#include"model_pp.h" -#include"ast_smt2_pp.h" -#include"cooperate.h" -#include"tactic_exception.h" +#include "smt/smt_model_finder.h" +#include "smt/smt_context.h" +#include "ast/ast_util.h" +#include "ast/macros/macro_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/normal_forms/pull_quant.h" +#include "ast/rewriter/var_subst.h" +#include "util/backtrackable_set.h" +#include "ast/for_each_expr.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/well_sorted.h" +#include "model/model_pp.h" +#include "ast/ast_smt2_pp.h" +#include "util/cooperate.h" +#include "tactic/tactic_exception.h" namespace smt { diff --git a/src/smt/smt_model_finder.h b/src/smt/smt_model_finder.h index 0694b008b..f02640659 100644 --- a/src/smt/smt_model_finder.h +++ b/src/smt/smt_model_finder.h @@ -46,12 +46,12 @@ Revision History: #ifndef SMT_MODEL_FINDER_H_ #define SMT_MODEL_FINDER_H_ -#include"ast.h" -#include"func_decl_dependencies.h" -#include"simplifier.h" -#include"proto_model.h" -#include"cooperate.h" -#include"tactic_exception.h" +#include "ast/ast.h" +#include "ast/func_decl_dependencies.h" +#include "ast/simplifier/simplifier.h" +#include "smt/proto_model/proto_model.h" +#include "util/cooperate.h" +#include "tactic/tactic_exception.h" namespace smt { class context; diff --git a/src/smt/smt_model_generator.cpp b/src/smt/smt_model_generator.cpp index b9c1ac453..49e9083f2 100644 --- a/src/smt/smt_model_generator.cpp +++ b/src/smt/smt_model_generator.cpp @@ -17,14 +17,14 @@ Revision History: --*/ -#include"smt_context.h" -#include"smt_model_generator.h" -#include"proto_model.h" -#include"ref_util.h" -#include"for_each_expr.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_model_generator.h" +#include "smt/proto_model/proto_model.h" +#include "util/ref_util.h" +#include "ast/for_each_expr.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/smt_model_generator.h b/src/smt/smt_model_generator.h index f360dbd7e..ee133482d 100644 --- a/src/smt/smt_model_generator.h +++ b/src/smt/smt_model_generator.h @@ -28,10 +28,10 @@ Revision History: #ifndef SMT_MODEL_GENERATOR_H_ #define SMT_MODEL_GENERATOR_H_ -#include"ast.h" -#include"smt_types.h" -#include"obj_hashtable.h" -#include"map.h" +#include "ast/ast.h" +#include "smt/smt_types.h" +#include "util/obj_hashtable.h" +#include "util/map.h" class value_factory; class proto_model; diff --git a/src/smt/smt_quantifier.cpp b/src/smt/smt_quantifier.cpp index 1c8f94edf..84ed7c8cd 100644 --- a/src/smt/smt_quantifier.cpp +++ b/src/smt/smt_quantifier.cpp @@ -16,15 +16,15 @@ Author: Revision History: --*/ -#include"smt_quantifier.h" -#include"smt_context.h" -#include"smt_quantifier_stat.h" -#include"smt_model_finder.h" -#include"smt_model_checker.h" -#include"smt_quick_checker.h" -#include"mam.h" -#include"qi_queue.h" -#include"ast_smt2_pp.h" +#include "smt/smt_quantifier.h" +#include "smt/smt_context.h" +#include "smt/smt_quantifier_stat.h" +#include "smt/smt_model_finder.h" +#include "smt/smt_model_checker.h" +#include "smt/smt_quick_checker.h" +#include "smt/mam.h" +#include "smt/qi_queue.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/smt_quantifier.h b/src/smt/smt_quantifier.h index 96af9909a..a55c895e6 100644 --- a/src/smt/smt_quantifier.h +++ b/src/smt/smt_quantifier.h @@ -19,10 +19,10 @@ Revision History: #ifndef SMT_QUANTIFIER_H_ #define SMT_QUANTIFIER_H_ -#include"ast.h" -#include"statistics.h" -#include"params.h" -#include"smt_types.h" +#include "ast/ast.h" +#include "util/statistics.h" +#include "util/params.h" +#include "smt/smt_types.h" class proto_model; struct smt_params; diff --git a/src/smt/smt_quantifier_stat.cpp b/src/smt/smt_quantifier_stat.cpp index d34a7c0ac..7d73ea27c 100644 --- a/src/smt/smt_quantifier_stat.cpp +++ b/src/smt/smt_quantifier_stat.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"smt_quantifier_stat.h" +#include "smt/smt_quantifier_stat.h" namespace smt { diff --git a/src/smt/smt_quantifier_stat.h b/src/smt/smt_quantifier_stat.h index 1d5919433..308534833 100644 --- a/src/smt/smt_quantifier_stat.h +++ b/src/smt/smt_quantifier_stat.h @@ -19,10 +19,10 @@ Revision History: #ifndef SMT_QUANTIFIER_STAT_H_ #define SMT_QUANTIFIER_STAT_H_ -#include"ast.h" -#include"obj_hashtable.h" -#include"approx_nat.h" -#include"region.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "util/approx_nat.h" +#include "util/region.h" namespace smt { diff --git a/src/smt/smt_quick_checker.cpp b/src/smt/smt_quick_checker.cpp index 462f784bd..f8744318a 100644 --- a/src/smt/smt_quick_checker.cpp +++ b/src/smt/smt_quick_checker.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_quick_checker.h" -#include"ast_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_quick_checker.h" +#include "ast/ast_pp.h" namespace smt { diff --git a/src/smt/smt_quick_checker.h b/src/smt/smt_quick_checker.h index 0963874a0..eb07880f1 100644 --- a/src/smt/smt_quick_checker.h +++ b/src/smt/smt_quick_checker.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMT_QUICK_CHECKER_H_ #define SMT_QUICK_CHECKER_H_ -#include"ast.h" -#include"simplifier.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "ast/simplifier/simplifier.h" +#include "util/obj_hashtable.h" namespace smt { class context; diff --git a/src/smt/smt_relevancy.cpp b/src/smt/smt_relevancy.cpp index 176314ae1..00457c643 100644 --- a/src/smt/smt_relevancy.cpp +++ b/src/smt/smt_relevancy.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_relevancy.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_relevancy.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/smt_relevancy.h b/src/smt/smt_relevancy.h index e81989044..75019b110 100644 --- a/src/smt/smt_relevancy.h +++ b/src/smt/smt_relevancy.h @@ -19,7 +19,7 @@ Revision History: #ifndef SMT_RELEVANCY_H_ #define SMT_RELEVANCY_H_ -#include"ast.h" +#include "ast/ast.h" namespace smt { class context; diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 4dd1e2510..361448316 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -16,25 +16,25 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"smt_setup.h" -#include"static_features.h" -#include"theory_arith.h" -#include"theory_lra.h" -#include"theory_dense_diff_logic.h" -#include"theory_diff_logic.h" -#include"theory_utvpi.h" -#include"theory_array.h" -#include"theory_array_full.h" -#include"theory_bv.h" -#include"theory_datatype.h" -#include"theory_dummy.h" -#include"theory_dl.h" -#include"theory_seq_empty.h" -#include"theory_seq.h" -#include"theory_pb.h" -#include"theory_fpa.h" -#include"theory_str.h" +#include "smt/smt_context.h" +#include "smt/smt_setup.h" +#include "ast/static_features.h" +#include "smt/theory_arith.h" +#include "smt/theory_lra.h" +#include "smt/theory_dense_diff_logic.h" +#include "smt/theory_diff_logic.h" +#include "smt/theory_utvpi.h" +#include "smt/theory_array.h" +#include "smt/theory_array_full.h" +#include "smt/theory_bv.h" +#include "smt/theory_datatype.h" +#include "smt/theory_dummy.h" +#include "smt/theory_dl.h" +#include "smt/theory_seq_empty.h" +#include "smt/theory_seq.h" +#include "smt/theory_pb.h" +#include "smt/theory_fpa.h" +#include "smt/theory_str.h" namespace smt { diff --git a/src/smt/smt_setup.h b/src/smt/smt_setup.h index f12cc5e09..a3bb29195 100644 --- a/src/smt/smt_setup.h +++ b/src/smt/smt_setup.h @@ -19,8 +19,8 @@ Revision History: #ifndef SMT_SETUP_H_ #define SMT_SETUP_H_ -#include"ast.h" -#include"smt_params.h" +#include "ast/ast.h" +#include "smt/params/smt_params.h" struct static_features; namespace smt { diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index cd912b72e..1a4cc00d1 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -16,16 +16,16 @@ Author: Notes: --*/ -#include"solver_na2as.h" -#include"smt_kernel.h" -#include"reg_decl_plugins.h" -#include"smt_params.h" +#include "solver/solver_na2as.h" +#include "smt/smt_kernel.h" +#include "ast/reg_decl_plugins.h" +#include "smt/params/smt_params.h" #include"smt_params_helper.hpp" -#include"mus.h" -#include"for_each_expr.h" -#include"ast_smt2_pp.h" -#include"func_decl_dependencies.h" -#include"dec_ref_util.h" +#include "solver/mus.h" +#include "ast/for_each_expr.h" +#include "ast/ast_smt2_pp.h" +#include "ast/func_decl_dependencies.h" +#include "util/dec_ref_util.h" namespace smt { diff --git a/src/smt/smt_solver.h b/src/smt/smt_solver.h index 6ec83810e..7d2677b35 100644 --- a/src/smt/smt_solver.h +++ b/src/smt/smt_solver.h @@ -21,8 +21,8 @@ Notes: #ifndef SMT_SOLVER_H_ #define SMT_SOLVER_H_ -#include"ast.h" -#include"params.h" +#include "ast/ast.h" +#include "util/params.h" class solver; class solver_factory; diff --git a/src/smt/smt_statistics.cpp b/src/smt/smt_statistics.cpp index 5201e48b3..95acd4819 100644 --- a/src/smt/smt_statistics.cpp +++ b/src/smt/smt_statistics.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include -#include"smt_statistics.h" +#include "smt/smt_statistics.h" namespace smt { diff --git a/src/smt/smt_theory.cpp b/src/smt/smt_theory.cpp index 2263699f9..515503d41 100644 --- a/src/smt/smt_theory.cpp +++ b/src/smt/smt_theory.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"buffer.h" -#include"ast_ll_pp.h" +#include "smt/smt_context.h" +#include "util/buffer.h" +#include "ast/ast_ll_pp.h" namespace smt { diff --git a/src/smt/smt_theory.h b/src/smt/smt_theory.h index c943a85d8..71eedc1a7 100644 --- a/src/smt/smt_theory.h +++ b/src/smt/smt_theory.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMT_THEORY_H_ #define SMT_THEORY_H_ -#include"smt_enode.h" -#include"obj_hashtable.h" -#include"statistics.h" +#include "smt/smt_enode.h" +#include "util/obj_hashtable.h" +#include "util/statistics.h" #include namespace smt { diff --git a/src/smt/smt_theory_var_list.h b/src/smt/smt_theory_var_list.h index 5f963102b..d7e246824 100644 --- a/src/smt/smt_theory_var_list.h +++ b/src/smt/smt_theory_var_list.h @@ -19,7 +19,7 @@ Revision History: #ifndef SMT_THEORY_VAR_LIST_H_ #define SMT_THEORY_VAR_LIST_H_ -#include"smt_types.h" +#include "smt/smt_types.h" namespace smt { diff --git a/src/smt/smt_types.h b/src/smt/smt_types.h index 7f2076045..6300bd43c 100644 --- a/src/smt/smt_types.h +++ b/src/smt/smt_types.h @@ -19,9 +19,9 @@ Revision History: #ifndef SMT_TYPES_H_ #define SMT_TYPES_H_ -#include"list.h" -#include"vector.h" -#include"lbool.h" +#include "util/list.h" +#include "util/vector.h" +#include "util/lbool.h" class model; diff --git a/src/smt/smt_value_sort.cpp b/src/smt/smt_value_sort.cpp index a840b77b7..56768b91a 100644 --- a/src/smt/smt_value_sort.cpp +++ b/src/smt/smt_value_sort.cpp @@ -18,10 +18,10 @@ Revision History: --*/ -#include "smt_value_sort.h" -#include "bv_decl_plugin.h" -#include "arith_decl_plugin.h" -#include "datatype_decl_plugin.h" +#include "smt/smt_value_sort.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" namespace smt { diff --git a/src/smt/smt_value_sort.h b/src/smt/smt_value_sort.h index e9327fca6..d7228f21c 100644 --- a/src/smt/smt_value_sort.h +++ b/src/smt/smt_value_sort.h @@ -22,7 +22,7 @@ Revision History: #ifndef SMT_VALUE_SORT_H_ #define SMT_VALUE_SORT_H_ -#include "ast.h" +#include "ast/ast.h" namespace smt { diff --git a/src/smt/spanning_tree.h b/src/smt/spanning_tree.h index fd5e68d54..78b556130 100644 --- a/src/smt/spanning_tree.h +++ b/src/smt/spanning_tree.h @@ -19,8 +19,8 @@ Notes: #ifndef SPANNING_TREE_H_ #define SPANNING_TREE_H_ -#include "diff_logic.h" -#include "spanning_tree_base.h" +#include "smt/diff_logic.h" +#include "smt/spanning_tree_base.h" namespace smt { diff --git a/src/smt/spanning_tree_base.h b/src/smt/spanning_tree_base.h index b86e5caa2..1ad98b79c 100644 --- a/src/smt/spanning_tree_base.h +++ b/src/smt/spanning_tree_base.h @@ -20,8 +20,8 @@ Notes: #ifndef SPANNING_TREE_BASE_H_ #define SPANNING_TREE_BASE_H_ -#include "util.h" -#include "vector.h" +#include "util/util.h" +#include "util/vector.h" namespace smt { template diff --git a/src/smt/spanning_tree_def.h b/src/smt/spanning_tree_def.h index ca7607119..c49ffcd3c 100644 --- a/src/smt/spanning_tree_def.h +++ b/src/smt/spanning_tree_def.h @@ -19,7 +19,7 @@ Notes: #ifndef SPANNING_TREE_DEF_H_ #define SPANNING_TREE_DEF_H_ -#include "spanning_tree.h" +#include "smt/spanning_tree.h" namespace smt { diff --git a/src/smt/tactic/ctx_solver_simplify_tactic.cpp b/src/smt/tactic/ctx_solver_simplify_tactic.cpp index d59ef5254..edc4b4ff5 100644 --- a/src/smt/tactic/ctx_solver_simplify_tactic.cpp +++ b/src/smt/tactic/ctx_solver_simplify_tactic.cpp @@ -17,13 +17,13 @@ Notes: --*/ -#include"ctx_solver_simplify_tactic.h" -#include"arith_decl_plugin.h" -#include"smt_params.h" -#include"smt_kernel.h" -#include"ast_pp.h" -#include"mk_simplified_app.h" -#include"ast_util.h" +#include "smt/tactic/ctx_solver_simplify_tactic.h" +#include "ast/arith_decl_plugin.h" +#include "smt/params/smt_params.h" +#include "smt/smt_kernel.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/mk_simplified_app.h" +#include "ast/ast_util.h" class ctx_solver_simplify_tactic : public tactic { ast_manager& m; diff --git a/src/smt/tactic/ctx_solver_simplify_tactic.h b/src/smt/tactic/ctx_solver_simplify_tactic.h index 51b81603d..28006cefc 100644 --- a/src/smt/tactic/ctx_solver_simplify_tactic.h +++ b/src/smt/tactic/ctx_solver_simplify_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef CTX_SOLVER_SIMPLIFY_TACTIC_H_ #define CTX_SOLVER_SIMPLIFY_TACTIC_H_ -#include"tactical.h" +#include "tactic/tactical.h" tactic * mk_ctx_solver_simplify_tactic(ast_manager & m, params_ref const & p = params_ref()); /* diff --git a/src/smt/tactic/smt_tactic.cpp b/src/smt/tactic/smt_tactic.cpp index 64bae0a48..3328d6030 100644 --- a/src/smt/tactic/smt_tactic.cpp +++ b/src/smt/tactic/smt_tactic.cpp @@ -16,19 +16,19 @@ Author: Notes: --*/ -#include"tactic.h" -#include"tactical.h" -#include"smt_kernel.h" -#include"smt_params.h" +#include "tactic/tactic.h" +#include "tactic/tactical.h" +#include "smt/smt_kernel.h" +#include "smt/params/smt_params.h" #include"smt_params_helper.hpp" #include"lp_params.hpp" -#include"rewriter_types.h" -#include"filter_model_converter.h" -#include"ast_util.h" -#include"solver2tactic.h" -#include"smt_solver.h" -#include"solver.h" -#include"mus.h" +#include "ast/rewriter/rewriter_types.h" +#include "tactic/filter_model_converter.h" +#include "ast/ast_util.h" +#include "solver/solver2tactic.h" +#include "smt/smt_solver.h" +#include "solver/solver.h" +#include "solver/mus.h" typedef obj_map expr2expr_map; diff --git a/src/smt/tactic/smt_tactic.h b/src/smt/tactic/smt_tactic.h index a23695fd1..c7b91d032 100644 --- a/src/smt/tactic/smt_tactic.h +++ b/src/smt/tactic/smt_tactic.h @@ -19,10 +19,10 @@ Notes: #ifndef SMT_TACTIC_H_ #define SMT_TACTIC_H_ -#include"params.h" -#include"ast.h" -#include"obj_hashtable.h" -#include"goal.h" +#include "util/params.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "tactic/goal.h" class tactic; class filter_model_converter; diff --git a/src/smt/tactic/unit_subsumption_tactic.cpp b/src/smt/tactic/unit_subsumption_tactic.cpp index 745bfa2de..68a34cea8 100644 --- a/src/smt/tactic/unit_subsumption_tactic.cpp +++ b/src/smt/tactic/unit_subsumption_tactic.cpp @@ -15,8 +15,8 @@ Author: --*/ -#include "unit_subsumption_tactic.h" -#include "smt_context.h" +#include "smt/tactic/unit_subsumption_tactic.h" +#include "smt/smt_context.h" struct unit_subsumption_tactic : public tactic { ast_manager& m; diff --git a/src/smt/tactic/unit_subsumption_tactic.h b/src/smt/tactic/unit_subsumption_tactic.h index 499bb44c6..09db59295 100644 --- a/src/smt/tactic/unit_subsumption_tactic.h +++ b/src/smt/tactic/unit_subsumption_tactic.h @@ -23,7 +23,7 @@ Notes: --*/ #ifndef UNIT_SUBSUMPTION_TACTIC_H_ #define UNIT_SUBSUMPTION_TACTIC_H_ -#include "tactic.h" +#include "tactic/tactic.h" tactic * mk_unit_subsumption_tactic(ast_manager & m, params_ref const & p = params_ref()); /* diff --git a/src/smt/theory_arith.cpp b/src/smt/theory_arith.cpp index 9a7d08151..6aee87408 100644 --- a/src/smt/theory_arith.cpp +++ b/src/smt/theory_arith.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"theory_arith_def.h" +#include "smt/theory_arith_def.h" namespace smt { diff --git a/src/smt/theory_arith.h b/src/smt/theory_arith.h index cdc1a3933..26b970d30 100644 --- a/src/smt/theory_arith.h +++ b/src/smt/theory_arith.h @@ -20,24 +20,24 @@ Revision History: #ifndef THEORY_ARITH_H_ #define THEORY_ARITH_H_ -#include"smt_theory.h" -#include"map.h" -#include"heap.h" -#include"nat_set.h" -#include"inf_rational.h" -#include"s_integer.h" -#include"inf_s_integer.h" -#include"arith_decl_plugin.h" -#include"theory_arith_params.h" -#include"arith_eq_adapter.h" -#include"numeral_factory.h" -#include"obj_pair_hashtable.h" -#include"old_interval.h" -#include"grobner.h" -#include"arith_simplifier_plugin.h" -#include"arith_eq_solver.h" -#include"theory_opt.h" -#include"uint_set.h" +#include "smt/smt_theory.h" +#include "util/map.h" +#include "util/heap.h" +#include "util/nat_set.h" +#include "util/inf_rational.h" +#include "util/s_integer.h" +#include "util/inf_s_integer.h" +#include "ast/arith_decl_plugin.h" +#include "smt/params/theory_arith_params.h" +#include "smt/arith_eq_adapter.h" +#include "smt/proto_model/numeral_factory.h" +#include "util/obj_pair_hashtable.h" +#include "smt/old_interval.h" +#include "math/grobner/grobner.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "smt/arith_eq_solver.h" +#include "smt/theory_opt.h" +#include "util/uint_set.h" namespace smt { diff --git a/src/smt/theory_arith_aux.h b/src/smt/theory_arith_aux.h index f94de7eba..f0f80b4ec 100644 --- a/src/smt/theory_arith_aux.h +++ b/src/smt/theory_arith_aux.h @@ -19,11 +19,11 @@ Revision History: #ifndef THEORY_ARITH_AUX_H_ #define THEORY_ARITH_AUX_H_ -#include"inf_eps_rational.h" -#include"theory_arith.h" -#include"smt_farkas_util.h" -#include"th_rewriter.h" -#include"filter_model_converter.h" +#include "util/inf_eps_rational.h" +#include "smt/theory_arith.h" +#include "smt/smt_farkas_util.h" +#include "ast/rewriter/th_rewriter.h" +#include "tactic/filter_model_converter.h" namespace smt { diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index bee744c34..6b8abcdbc 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -19,12 +19,12 @@ Revision History: #ifndef THEORY_ARITH_CORE_H_ #define THEORY_ARITH_CORE_H_ -#include"smt_context.h" -#include"theory_arith.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"smt_model_generator.h" -#include"ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/theory_arith.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "smt/smt_model_generator.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/theory_arith_def.h b/src/smt/theory_arith_def.h index 531a03bd3..962f55f02 100644 --- a/src/smt/theory_arith_def.h +++ b/src/smt/theory_arith_def.h @@ -19,14 +19,14 @@ Revision History: #ifndef THEORY_ARITH_DEF_H_ #define THEORY_ARITH_DEF_H_ -#include"theory_arith.h" -#include"theory_arith_core.h" -#include"theory_arith_aux.h" -#include"theory_arith_inv.h" -#include"theory_arith_pp.h" -#include"theory_arith_int.h" -#include"theory_arith_eq.h" -#include"theory_arith_nl.h" +#include "smt/theory_arith.h" +#include "smt/theory_arith_core.h" +#include "smt/theory_arith_aux.h" +#include "smt/theory_arith_inv.h" +#include "smt/theory_arith_pp.h" +#include "smt/theory_arith_int.h" +#include "smt/theory_arith_eq.h" +#include "smt/theory_arith_nl.h" #endif /* THEORY_ARITH_DEF_H_ */ diff --git a/src/smt/theory_arith_eq.h b/src/smt/theory_arith_eq.h index ae0f17757..a7f7fae59 100644 --- a/src/smt/theory_arith_eq.h +++ b/src/smt/theory_arith_eq.h @@ -22,7 +22,7 @@ Revision History: // #define PROFILE_OFFSET_ROW #ifdef PROFILE_OFFSET_ROW -#include"stopwatch.h" +#include "util/stopwatch.h" #undef max #undef min #endif diff --git a/src/smt/theory_arith_int.h b/src/smt/theory_arith_int.h index e6e9e863c..4150ecc1c 100644 --- a/src/smt/theory_arith_int.h +++ b/src/smt/theory_arith_int.h @@ -19,12 +19,12 @@ Revision History: #ifndef THEORY_ARITH_INT_H_ #define THEORY_ARITH_INT_H_ -#include"ast_ll_pp.h" -#include"arith_simplifier_plugin.h" -#include"well_sorted.h" -#include"euclidean_solver.h" -#include"numeral_buffer.h" -#include"ast_smt2_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/well_sorted.h" +#include "math/euclid/euclidean_solver.h" +#include "util/numeral_buffer.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/theory_arith_inv.h b/src/smt/theory_arith_inv.h index b547168e0..987d075c3 100644 --- a/src/smt/theory_arith_inv.h +++ b/src/smt/theory_arith_inv.h @@ -19,8 +19,8 @@ Revision History: #ifndef THEORY_ARITH_INV_H_ #define THEORY_ARITH_INV_H_ -#include"theory_arith.h" -#include"ast_pp.h" +#include "smt/theory_arith.h" +#include "ast/ast_pp.h" namespace smt { diff --git a/src/smt/theory_arith_nl.h b/src/smt/theory_arith_nl.h index 8a632cf48..b4d30d639 100644 --- a/src/smt/theory_arith_nl.h +++ b/src/smt/theory_arith_nl.h @@ -19,7 +19,7 @@ Revision History: #ifndef THEORY_ARITH_NL_H_ #define THEORY_ARITH_NL_H_ -#include"ast_smt2_pp.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/theory_arith_pp.h b/src/smt/theory_arith_pp.h index 7b657d9c2..67fe5a572 100644 --- a/src/smt/theory_arith_pp.h +++ b/src/smt/theory_arith_pp.h @@ -19,9 +19,9 @@ Revision History: #ifndef THEORY_ARITH_PP_H_ #define THEORY_ARITH_PP_H_ -#include"theory_arith.h" -#include"ast_smt_pp.h" -#include"stats.h" +#include "smt/theory_arith.h" +#include "ast/ast_smt_pp.h" +#include "util/stats.h" namespace smt { template diff --git a/src/smt/theory_array.cpp b/src/smt/theory_array.cpp index b06e50d2a..17eefb361 100644 --- a/src/smt/theory_array.cpp +++ b/src/smt/theory_array.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"theory_array.h" -#include"ast_ll_pp.h" -#include"stats.h" +#include "smt/smt_context.h" +#include "smt/theory_array.h" +#include "ast/ast_ll_pp.h" +#include "util/stats.h" namespace smt { diff --git a/src/smt/theory_array.h b/src/smt/theory_array.h index 4e45f77f2..3a013cf73 100644 --- a/src/smt/theory_array.h +++ b/src/smt/theory_array.h @@ -19,9 +19,9 @@ Revision History: #ifndef THEORY_ARRAY_H_ #define THEORY_ARRAY_H_ -#include"theory_array_base.h" -#include"theory_array_params.h" -#include"union_find.h" +#include "smt/theory_array_base.h" +#include "smt/params/theory_array_params.h" +#include "util/union_find.h" namespace smt { diff --git a/src/smt/theory_array_base.cpp b/src/smt/theory_array_base.cpp index 6c47bf855..1f519dfda 100644 --- a/src/smt/theory_array_base.cpp +++ b/src/smt/theory_array_base.cpp @@ -16,13 +16,13 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"theory_array_base.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"smt_model_generator.h" -#include"func_interp.h" -#include"ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/theory_array_base.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "smt/smt_model_generator.h" +#include "model/func_interp.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/theory_array_base.h b/src/smt/theory_array_base.h index e0d16f0f2..197ad9d2f 100644 --- a/src/smt/theory_array_base.h +++ b/src/smt/theory_array_base.h @@ -19,9 +19,9 @@ Revision History: #ifndef THEORY_ARRAY_BASE_H_ #define THEORY_ARRAY_BASE_H_ -#include"smt_theory.h" -#include"array_decl_plugin.h" -#include"array_factory.h" +#include "smt/smt_theory.h" +#include "ast/array_decl_plugin.h" +#include "smt/proto_model/array_factory.h" namespace smt { diff --git a/src/smt/theory_array_full.cpp b/src/smt/theory_array_full.cpp index a9dc657dd..d5660e325 100644 --- a/src/smt/theory_array_full.cpp +++ b/src/smt/theory_array_full.cpp @@ -17,12 +17,12 @@ Revision History: --*/ -#include "smt_context.h" -#include "theory_array_full.h" -#include "ast_ll_pp.h" -#include "ast_pp.h" -#include "ast_smt2_pp.h" -#include "stats.h" +#include "smt/smt_context.h" +#include "smt/theory_array_full.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" +#include "util/stats.h" namespace smt { diff --git a/src/smt/theory_array_full.h b/src/smt/theory_array_full.h index 1200275a2..e22d1d0e2 100644 --- a/src/smt/theory_array_full.h +++ b/src/smt/theory_array_full.h @@ -19,9 +19,9 @@ Revision History: #ifndef THEORY_ARRAY_FULL_H_ #define THEORY_ARRAY_FULL_H_ -#include "theory_array.h" -#include "simplifier.h" -#include "ast_trail.h" +#include "smt/theory_array.h" +#include "ast/simplifier/simplifier.h" +#include "ast/ast_trail.h" namespace smt { diff --git a/src/smt/theory_bv.cpp b/src/smt/theory_bv.cpp index 255e2044f..0981ccdbf 100644 --- a/src/smt/theory_bv.cpp +++ b/src/smt/theory_bv.cpp @@ -16,12 +16,12 @@ Author: Revision History: --*/ -#include"smt_context.h" -#include"theory_bv.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" -#include"smt_model_generator.h" -#include"stats.h" +#include "smt/smt_context.h" +#include "smt/theory_bv.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "smt/smt_model_generator.h" +#include "util/stats.h" namespace smt { diff --git a/src/smt/theory_bv.h b/src/smt/theory_bv.h index 50e4f9c30..5d2ea8da5 100644 --- a/src/smt/theory_bv.h +++ b/src/smt/theory_bv.h @@ -19,16 +19,16 @@ Revision History: #ifndef THEORY_BV_H_ #define THEORY_BV_H_ -#include"smt_theory.h" -#include"theory_bv_params.h" -#include"bit_blaster.h" -#include"trail.h" -#include"union_find.h" -#include"simplifier.h" -#include"bv_simplifier_plugin.h" -#include"arith_decl_plugin.h" -#include"arith_simplifier_plugin.h" -#include"numeral_factory.h" +#include "smt/smt_theory.h" +#include "smt/params/theory_bv_params.h" +#include "ast/rewriter/bit_blaster/bit_blaster.h" +#include "util/trail.h" +#include "util/union_find.h" +#include "ast/simplifier/simplifier.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "smt/proto_model/numeral_factory.h" namespace smt { diff --git a/src/smt/theory_datatype.cpp b/src/smt/theory_datatype.cpp index 8e140661b..806d6706b 100644 --- a/src/smt/theory_datatype.cpp +++ b/src/smt/theory_datatype.cpp @@ -17,13 +17,13 @@ Revision History: --*/ -#include"smt_context.h" -#include"theory_datatype.h" -#include"smt_model_generator.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" -#include"stats.h" -#include"ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/theory_datatype.h" +#include "smt/smt_model_generator.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "util/stats.h" +#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/theory_datatype.h b/src/smt/theory_datatype.h index b97adacfe..20fa371fa 100644 --- a/src/smt/theory_datatype.h +++ b/src/smt/theory_datatype.h @@ -19,11 +19,11 @@ Revision History: #ifndef THEORY_DATATYPE_H_ #define THEORY_DATATYPE_H_ -#include"smt_theory.h" -#include"union_find.h" -#include"theory_datatype_params.h" -#include"datatype_decl_plugin.h" -#include"datatype_factory.h" +#include "smt/smt_theory.h" +#include "util/union_find.h" +#include "smt/params/theory_datatype_params.h" +#include "ast/datatype_decl_plugin.h" +#include "smt/proto_model/datatype_factory.h" namespace smt { diff --git a/src/smt/theory_dense_diff_logic.cpp b/src/smt/theory_dense_diff_logic.cpp index db2ffd38b..3d352ee84 100644 --- a/src/smt/theory_dense_diff_logic.cpp +++ b/src/smt/theory_dense_diff_logic.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"theory_dense_diff_logic_def.h" +#include "smt/theory_dense_diff_logic_def.h" namespace smt { template class theory_dense_diff_logic; diff --git a/src/smt/theory_dense_diff_logic.h b/src/smt/theory_dense_diff_logic.h index c2be89bc3..980830447 100644 --- a/src/smt/theory_dense_diff_logic.h +++ b/src/smt/theory_dense_diff_logic.h @@ -21,11 +21,11 @@ TODO: eager equality propagation #ifndef THEORY_DENSE_DIFF_LOGIC_H_ #define THEORY_DENSE_DIFF_LOGIC_H_ -#include"theory_arith.h" -#include"theory_arith_params.h" -#include"arith_decl_plugin.h" -#include"arith_eq_adapter.h" -#include"theory_opt.h" +#include "smt/theory_arith.h" +#include "smt/params/theory_arith_params.h" +#include "ast/arith_decl_plugin.h" +#include "smt/arith_eq_adapter.h" +#include "smt/theory_opt.h" namespace smt { diff --git a/src/smt/theory_dense_diff_logic_def.h b/src/smt/theory_dense_diff_logic_def.h index addb5d92b..342766c04 100644 --- a/src/smt/theory_dense_diff_logic_def.h +++ b/src/smt/theory_dense_diff_logic_def.h @@ -19,12 +19,12 @@ Revision History: #ifndef THEORY_DENSE_DIFF_LOGIC_DEF_H_ #define THEORY_DENSE_DIFF_LOGIC_DEF_H_ -#include"smt_context.h" -#include"theory_dense_diff_logic.h" -#include"ast_pp.h" -#include"smt_model_generator.h" -#include"simplex.h" -#include"simplex_def.h" +#include "smt/smt_context.h" +#include "smt/theory_dense_diff_logic.h" +#include "ast/ast_pp.h" +#include "smt/smt_model_generator.h" +#include "math/simplex/simplex.h" +#include "math/simplex/simplex_def.h" namespace smt { diff --git a/src/smt/theory_diff_logic.cpp b/src/smt/theory_diff_logic.cpp index f1f00833b..1664dbfe2 100644 --- a/src/smt/theory_diff_logic.cpp +++ b/src/smt/theory_diff_logic.cpp @@ -17,11 +17,11 @@ Author: Revision History: --*/ -#include "theory_diff_logic.h" +#include "smt/theory_diff_logic.h" -#include"rational.h" -#include"theory_diff_logic_def.h" -#include"sparse_matrix_def.h" +#include "util/rational.h" +#include "smt/theory_diff_logic_def.h" +#include "math/simplex/sparse_matrix_def.h" namespace smt { diff --git a/src/smt/theory_diff_logic.h b/src/smt/theory_diff_logic.h index f47e61548..1ad239e58 100644 --- a/src/smt/theory_diff_logic.h +++ b/src/smt/theory_diff_logic.h @@ -22,24 +22,24 @@ Revision History: #ifndef THEORY_DIFF_LOGIC_H_ #define THEORY_DIFF_LOGIC_H_ -#include"rational.h" -#include"inf_rational.h" -#include"inf_int_rational.h" -#include"s_integer.h" -#include"inf_s_integer.h" -#include"smt_theory.h" -#include"diff_logic.h" -#include"arith_decl_plugin.h" -#include"smt_justification.h" -#include"map.h" -#include"smt_params.h" -#include"arith_eq_adapter.h" -#include"smt_model_generator.h" -#include"numeral_factory.h" -#include"smt_clause.h" -#include"theory_opt.h" -#include"simplex.h" -#include"simplex_def.h" +#include "util/rational.h" +#include "util/inf_rational.h" +#include "util/inf_int_rational.h" +#include "util/s_integer.h" +#include "util/inf_s_integer.h" +#include "smt/smt_theory.h" +#include "smt/diff_logic.h" +#include "ast/arith_decl_plugin.h" +#include "smt/smt_justification.h" +#include "util/map.h" +#include "smt/params/smt_params.h" +#include "smt/arith_eq_adapter.h" +#include "smt/smt_model_generator.h" +#include "smt/proto_model/numeral_factory.h" +#include "smt/smt_clause.h" +#include "smt/theory_opt.h" +#include "math/simplex/simplex.h" +#include "math/simplex/simplex_def.h" // The DL theory can represent term such as n + k, where n is an enode and k is a numeral. namespace smt { diff --git a/src/smt/theory_diff_logic_def.h b/src/smt/theory_diff_logic_def.h index 372786c01..02cc8860f 100644 --- a/src/smt/theory_diff_logic_def.h +++ b/src/smt/theory_diff_logic_def.h @@ -22,13 +22,13 @@ Revision History: #ifndef THEORY_DIFF_LOGIC_DEF_H_ #define THEORY_DIFF_LOGIC_DEF_H_ -#include"theory_diff_logic.h" -#include"smt_context.h" -#include"map.h" -#include"ast_pp.h" -#include"warning.h" -#include"smt_model_generator.h" -#include"model_implicant.h" +#include "smt/theory_diff_logic.h" +#include "smt/smt_context.h" +#include "util/map.h" +#include "ast/ast_pp.h" +#include "util/warning.h" +#include "smt/smt_model_generator.h" +#include "model/model_implicant.h" using namespace smt; diff --git a/src/smt/theory_dl.cpp b/src/smt/theory_dl.cpp index 588b134b7..ea02121d9 100644 --- a/src/smt/theory_dl.cpp +++ b/src/smt/theory_dl.cpp @@ -22,14 +22,14 @@ Revision History: --*/ -#include "smt_theory.h" -#include "dl_decl_plugin.h" -#include "value_factory.h" -#include "smt_model_generator.h" -#include "bv_decl_plugin.h" -#include "theory_bv.h" -#include "smt_context.h" -#include "ast_pp.h" +#include "smt/smt_theory.h" +#include "ast/dl_decl_plugin.h" +#include "smt/proto_model/value_factory.h" +#include "smt/smt_model_generator.h" +#include "ast/bv_decl_plugin.h" +#include "smt/theory_bv.h" +#include "smt/smt_context.h" +#include "ast/ast_pp.h" // Basic approach: reduce theory to bit-vectors: // diff --git a/src/smt/theory_dummy.cpp b/src/smt/theory_dummy.cpp index c8b9c3b0a..d1695134e 100644 --- a/src/smt/theory_dummy.cpp +++ b/src/smt/theory_dummy.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"smt_context.h" -#include"theory_dummy.h" +#include "smt/smt_context.h" +#include "smt/theory_dummy.h" namespace smt { diff --git a/src/smt/theory_dummy.h b/src/smt/theory_dummy.h index fc25fc0b7..b20d86270 100644 --- a/src/smt/theory_dummy.h +++ b/src/smt/theory_dummy.h @@ -19,7 +19,7 @@ Revision History: #ifndef THEORY_DUMMY_H_ #define THEORY_DUMMY_H_ -#include"smt_theory.h" +#include "smt/smt_theory.h" namespace smt { diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index a3bf77180..17349ead6 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -16,12 +16,12 @@ Author: Revision History: --*/ -#include"ast_smt2_pp.h" -#include"smt_context.h" -#include"theory_fpa.h" -#include"theory_bv.h" -#include"smt_model_generator.h" -#include"bv2fpa_converter.h" +#include "ast/ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/theory_fpa.h" +#include "smt/theory_bv.h" +#include "smt/smt_model_generator.h" +#include "ast/fpa/bv2fpa_converter.h" namespace smt { diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 998f2be3c..5fcb8637c 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -19,13 +19,13 @@ Revision History: #ifndef THEORY_FPA_H_ #define THEORY_FPA_H_ -#include"smt_theory.h" -#include"trail.h" -#include"fpa2bv_converter.h" -#include"fpa2bv_rewriter.h" -#include"th_rewriter.h" -#include"value_factory.h" -#include"smt_model_generator.h" +#include "smt/smt_theory.h" +#include "util/trail.h" +#include "ast/fpa/fpa2bv_converter.h" +#include "ast/fpa/fpa2bv_rewriter.h" +#include "ast/rewriter/th_rewriter.h" +#include "smt/proto_model/value_factory.h" +#include "smt/smt_model_generator.h" namespace smt { diff --git a/src/smt/theory_lra.h b/src/smt/theory_lra.h index beb5c8387..774ec15ad 100644 --- a/src/smt/theory_lra.h +++ b/src/smt/theory_lra.h @@ -20,7 +20,7 @@ Revision History: --*/ #pragma once -#include "theory_opt.h" +#include "smt/theory_opt.h" namespace smt { class theory_lra : public theory, public theory_opt { diff --git a/src/smt/theory_opt.cpp b/src/smt/theory_opt.cpp index 9e6fa452c..365315bf2 100644 --- a/src/smt/theory_opt.cpp +++ b/src/smt/theory_opt.cpp @@ -18,10 +18,10 @@ Notes: --*/ -#include "arith_decl_plugin.h" -#include "smt_types.h" -#include "smt_theory.h" -#include "theory_opt.h" +#include "ast/arith_decl_plugin.h" +#include "smt/smt_types.h" +#include "smt/smt_theory.h" +#include "smt/theory_opt.h" namespace smt { bool theory_opt::is_linear(ast_manager& m, expr* term) { diff --git a/src/smt/theory_opt.h b/src/smt/theory_opt.h index 421e6feca..49f436ea5 100644 --- a/src/smt/theory_opt.h +++ b/src/smt/theory_opt.h @@ -18,9 +18,9 @@ Notes: --*/ -#include "inf_rational.h" -#include "inf_eps_rational.h" -#include "arith_decl_plugin.h" +#include "util/inf_rational.h" +#include "util/inf_eps_rational.h" +#include "ast/arith_decl_plugin.h" #ifndef THEORY_OPT_H_ #define THEORY_OPT_H_ diff --git a/src/smt/theory_pb.cpp b/src/smt/theory_pb.cpp index 507cb6d43..4b52d7950 100644 --- a/src/smt/theory_pb.cpp +++ b/src/smt/theory_pb.cpp @@ -19,15 +19,15 @@ Notes: --*/ #include -#include "theory_pb.h" -#include "smt_context.h" -#include "ast_pp.h" -#include "sorting_network.h" -#include "uint_set.h" -#include "smt_model_generator.h" -#include "pb_rewriter_def.h" -#include "sparse_matrix_def.h" -#include "simplex_def.h" +#include "smt/theory_pb.h" +#include "smt/smt_context.h" +#include "ast/ast_pp.h" +#include "util/sorting_network.h" +#include "util/uint_set.h" +#include "smt/smt_model_generator.h" +#include "ast/rewriter/pb_rewriter_def.h" +#include "math/simplex/sparse_matrix_def.h" +#include "math/simplex/simplex_def.h" namespace smt { diff --git a/src/smt/theory_pb.h b/src/smt/theory_pb.h index ee68bd26e..7f530e5b0 100644 --- a/src/smt/theory_pb.h +++ b/src/smt/theory_pb.h @@ -20,11 +20,11 @@ Notes: sorting circuits if it keeps having to propagate (create new clauses). --*/ -#include "smt_theory.h" -#include "pb_decl_plugin.h" -#include "smt_clause.h" -#include "theory_pb_params.h" -#include "simplex.h" +#include "smt/smt_theory.h" +#include "ast/pb_decl_plugin.h" +#include "smt/smt_clause.h" +#include "smt/params/theory_pb_params.h" +#include "math/simplex/simplex.h" namespace smt { class theory_pb : public theory { diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index e72cd3f6d..14ee3b073 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -18,13 +18,13 @@ Revision History: --*/ -#include "value_factory.h" -#include "smt_context.h" -#include "smt_model_generator.h" -#include "theory_seq.h" -#include "ast_trail.h" -#include "theory_arith.h" -#include "smt_kernel.h" +#include "smt/proto_model/value_factory.h" +#include "smt/smt_context.h" +#include "smt/smt_model_generator.h" +#include "smt/theory_seq.h" +#include "ast/ast_trail.h" +#include "smt/theory_arith.h" +#include "smt/smt_kernel.h" using namespace smt; diff --git a/src/smt/theory_seq.h b/src/smt/theory_seq.h index f7212e608..b5a53e8e4 100644 --- a/src/smt/theory_seq.h +++ b/src/smt/theory_seq.h @@ -19,16 +19,16 @@ Revision History: #ifndef THEORY_SEQ_H_ #define THEORY_SEQ_H_ -#include "smt_theory.h" -#include "seq_decl_plugin.h" -#include "theory_seq_empty.h" -#include "th_rewriter.h" -#include "ast_trail.h" -#include "scoped_vector.h" -#include "scoped_ptr_vector.h" -#include "automaton.h" -#include "seq_rewriter.h" -#include "union_find.h" +#include "smt/smt_theory.h" +#include "ast/seq_decl_plugin.h" +#include "smt/theory_seq_empty.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/ast_trail.h" +#include "util/scoped_vector.h" +#include "util/scoped_ptr_vector.h" +#include "math/automata/automaton.h" +#include "ast/rewriter/seq_rewriter.h" +#include "util/union_find.h" namespace smt { diff --git a/src/smt/theory_seq_empty.h b/src/smt/theory_seq_empty.h index 3f6c7f3e2..85408f7e5 100644 --- a/src/smt/theory_seq_empty.h +++ b/src/smt/theory_seq_empty.h @@ -19,8 +19,8 @@ Revision History: #ifndef THEORY_SEQ_EMPTY_H_ #define THEORY_SEQ_EMPTY_H_ -#include "smt_theory.h" -#include "seq_decl_plugin.h" +#include "smt/smt_theory.h" +#include "ast/seq_decl_plugin.h" namespace smt { class seq_factory : public value_factory { diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 13f8ab282..6f3dabe2e 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -14,17 +14,17 @@ Revision History: --*/ -#include"ast_smt2_pp.h" -#include"smt_context.h" -#include"theory_str.h" -#include"smt_model_generator.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/theory_str.h" +#include "smt/smt_model_generator.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" #include #include -#include"theory_seq_empty.h" -#include"theory_arith.h" -#include"ast_util.h" +#include "smt/theory_seq_empty.h" +#include "smt/theory_arith.h" +#include "ast/ast_util.h" namespace smt { diff --git a/src/smt/theory_str.h b/src/smt/theory_str.h index 7f39efa70..5837980df 100644 --- a/src/smt/theory_str.h +++ b/src/smt/theory_str.h @@ -17,19 +17,19 @@ #ifndef _THEORY_STR_H_ #define _THEORY_STR_H_ -#include"smt_theory.h" -#include"theory_str_params.h" -#include"trail.h" -#include"th_rewriter.h" -#include"value_factory.h" -#include"smt_model_generator.h" -#include"arith_decl_plugin.h" +#include "smt/smt_theory.h" +#include "smt/params/theory_str_params.h" +#include "util/trail.h" +#include "ast/rewriter/th_rewriter.h" +#include "smt/proto_model/value_factory.h" +#include "smt/smt_model_generator.h" +#include "ast/arith_decl_plugin.h" #include #include #include #include -#include"seq_decl_plugin.h" -#include"union_find.h" +#include "ast/seq_decl_plugin.h" +#include "util/union_find.h" namespace smt { diff --git a/src/smt/theory_utvpi.cpp b/src/smt/theory_utvpi.cpp index 9da82c9e6..1f56b748b 100644 --- a/src/smt/theory_utvpi.cpp +++ b/src/smt/theory_utvpi.cpp @@ -14,8 +14,8 @@ Revision History: The implementaton is derived from theory_diff_logic. --*/ -#include "theory_utvpi.h" -#include "theory_utvpi_def.h" +#include "smt/theory_utvpi.h" +#include "smt/theory_utvpi_def.h" namespace smt { diff --git a/src/smt/theory_utvpi.h b/src/smt/theory_utvpi.h index 35ebd440b..55bbb9838 100644 --- a/src/smt/theory_utvpi.h +++ b/src/smt/theory_utvpi.h @@ -22,7 +22,7 @@ Revision History: #ifndef THEORY_UTVPI_H_ #define THEORY_UTVPI_H_ -#include"theory_diff_logic.h" +#include "smt/theory_diff_logic.h" namespace smt { diff --git a/src/smt/theory_utvpi_def.h b/src/smt/theory_utvpi_def.h index 5f370c29c..7c1edb585 100644 --- a/src/smt/theory_utvpi_def.h +++ b/src/smt/theory_utvpi_def.h @@ -49,10 +49,10 @@ Revision History: #ifndef THEORY_UTVPI_DEF_H_ #define THEORY_UTVPI_DEF_H_ -#include "theory_utvpi.h" -#include "heap.h" -#include "ast_pp.h" -#include "smt_context.h" +#include "smt/theory_utvpi.h" +#include "util/heap.h" +#include "ast/ast_pp.h" +#include "smt/smt_context.h" namespace smt { diff --git a/src/smt/theory_wmaxsat.cpp b/src/smt/theory_wmaxsat.cpp index 3f153f500..88ba89610 100644 --- a/src/smt/theory_wmaxsat.cpp +++ b/src/smt/theory_wmaxsat.cpp @@ -18,10 +18,10 @@ Notes: --*/ #include -#include "smt_context.h" -#include "ast_pp.h" -#include "theory_wmaxsat.h" -#include "smt_justification.h" +#include "smt/smt_context.h" +#include "ast/ast_pp.h" +#include "smt/theory_wmaxsat.h" +#include "smt/smt_justification.h" namespace smt { diff --git a/src/smt/theory_wmaxsat.h b/src/smt/theory_wmaxsat.h index 0f711b9f8..739a22c71 100644 --- a/src/smt/theory_wmaxsat.h +++ b/src/smt/theory_wmaxsat.h @@ -20,9 +20,9 @@ Notes: #ifndef THEORY_WMAXSAT_H_ #define THEORY_WMAXSAT_H_ -#include "smt_theory.h" -#include "smt_clause.h" -#include "filter_model_converter.h" +#include "smt/smt_theory.h" +#include "smt/smt_clause.h" +#include "tactic/filter_model_converter.h" namespace smt { class theory_wmaxsat : public theory { diff --git a/src/smt/uses_theory.cpp b/src/smt/uses_theory.cpp index 5b736f75a..517951a7b 100644 --- a/src/smt/uses_theory.cpp +++ b/src/smt/uses_theory.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"uses_theory.h" -#include"for_each_expr.h" +#include "smt/uses_theory.h" +#include "ast/for_each_expr.h" bool uses_theory(expr * n, family_id fid) { expr_mark visited; diff --git a/src/smt/uses_theory.h b/src/smt/uses_theory.h index 8f3760e3e..948d05f77 100644 --- a/src/smt/uses_theory.h +++ b/src/smt/uses_theory.h @@ -19,7 +19,7 @@ Revision History: #ifndef USES_THEORY_H_ #define USES_THEORY_H_ -#include"ast.h" +#include "ast/ast.h" /** \brief Return true if the given expression contains a symbol of the given theory. diff --git a/src/smt/watch_list.cpp b/src/smt/watch_list.cpp index ed73b9ed5..2ff75c418 100644 --- a/src/smt/watch_list.cpp +++ b/src/smt/watch_list.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"watch_list.h" +#include "smt/watch_list.h" namespace smt { diff --git a/src/smt/watch_list.h b/src/smt/watch_list.h index 2af26695f..19d3f20a8 100644 --- a/src/smt/watch_list.h +++ b/src/smt/watch_list.h @@ -19,8 +19,8 @@ Revision History: #ifndef WATCH_LIST_H_ #define WATCH_LIST_H_ -#include"smt_clause.h" -#include"memory_manager.h" +#include "smt/smt_clause.h" +#include "util/memory_manager.h" namespace smt { diff --git a/src/solver/check_sat_result.cpp b/src/solver/check_sat_result.cpp index 7a248e8b1..5a7733071 100644 --- a/src/solver/check_sat_result.cpp +++ b/src/solver/check_sat_result.cpp @@ -16,7 +16,7 @@ Author: Notes: --*/ -#include"check_sat_result.h" +#include "solver/check_sat_result.h" simple_check_sat_result::simple_check_sat_result(ast_manager & m): m_core(m), diff --git a/src/solver/check_sat_result.h b/src/solver/check_sat_result.h index 36eadd97d..3079433b5 100644 --- a/src/solver/check_sat_result.h +++ b/src/solver/check_sat_result.h @@ -19,9 +19,9 @@ Notes: #ifndef CHECK_SAT_RESULT_H_ #define CHECK_SAT_RESULT_H_ -#include"model.h" -#include"lbool.h" -#include"statistics.h" +#include "model/model.h" +#include "util/lbool.h" +#include "util/statistics.h" /** \brief Abstract interface for the result of a (check-sat) like command. diff --git a/src/solver/combined_solver.cpp b/src/solver/combined_solver.cpp index d67643edf..cbe6373c2 100644 --- a/src/solver/combined_solver.cpp +++ b/src/solver/combined_solver.cpp @@ -18,10 +18,10 @@ Author: Notes: --*/ -#include"solver.h" -#include"scoped_timer.h" +#include "solver/solver.h" +#include "util/scoped_timer.h" #include"combined_solver_params.hpp" -#include"common_msgs.h" +#include "util/common_msgs.h" #define PS_VB_LVL 15 /** diff --git a/src/solver/combined_solver.h b/src/solver/combined_solver.h index a10bf343f..70637070c 100644 --- a/src/solver/combined_solver.h +++ b/src/solver/combined_solver.h @@ -21,7 +21,7 @@ Notes: #ifndef COMBINED_SOLVER_H_ #define COMBINED_SOLVER_H_ -#include"params.h" +#include "util/params.h" class solver; class solver_factory; diff --git a/src/solver/mus.cpp b/src/solver/mus.cpp index d536a191b..7eb692567 100644 --- a/src/solver/mus.cpp +++ b/src/solver/mus.cpp @@ -18,11 +18,11 @@ Notes: --*/ -#include "solver.h" -#include "mus.h" -#include "ast_pp.h" -#include "ast_util.h" -#include "model_evaluator.h" +#include "solver/solver.h" +#include "solver/mus.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" +#include "model/model_evaluator.h" struct mus::imp { diff --git a/src/solver/smt_logics.cpp b/src/solver/smt_logics.cpp index 2bb364b6a..75cd0f2bb 100644 --- a/src/solver/smt_logics.cpp +++ b/src/solver/smt_logics.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include "symbol.h" -#include "smt_logics.h" +#include "util/symbol.h" +#include "solver/smt_logics.h" diff --git a/src/solver/solver.cpp b/src/solver/solver.cpp index 9163cfeda..cb7864268 100644 --- a/src/solver/solver.cpp +++ b/src/solver/solver.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"solver.h" -#include"model_evaluator.h" -#include"ast_util.h" -#include"ast_pp.h" -#include"ast_pp_util.h" -#include "common_msgs.h" +#include "solver/solver.h" +#include "model/model_evaluator.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" +#include "ast/ast_pp_util.h" +#include "util/common_msgs.h" unsigned solver::get_num_assertions() const { diff --git a/src/solver/solver.h b/src/solver/solver.h index 6b9d38f29..00e3cf8e9 100644 --- a/src/solver/solver.h +++ b/src/solver/solver.h @@ -19,9 +19,9 @@ Notes: #ifndef SOLVER_H_ #define SOLVER_H_ -#include"check_sat_result.h" -#include"progress_callback.h" -#include"params.h" +#include "solver/check_sat_result.h" +#include "solver/progress_callback.h" +#include "util/params.h" class solver; diff --git a/src/solver/solver2tactic.cpp b/src/solver/solver2tactic.cpp index 1a02c97e6..fa0711d70 100644 --- a/src/solver/solver2tactic.cpp +++ b/src/solver/solver2tactic.cpp @@ -17,11 +17,11 @@ Notes: --*/ -#include "solver.h" -#include "tactic.h" -#include"filter_model_converter.h" -#include "solver2tactic.h" -#include "ast_util.h" +#include "solver/solver.h" +#include "tactic/tactic.h" +#include "tactic/filter_model_converter.h" +#include "solver/solver2tactic.h" +#include "ast/ast_util.h" typedef obj_map expr2expr_map; diff --git a/src/solver/solver2tactic.h b/src/solver/solver2tactic.h index 65fbd37b1..647a1cee4 100644 --- a/src/solver/solver2tactic.h +++ b/src/solver/solver2tactic.h @@ -19,8 +19,8 @@ Notes: #ifndef SOLVER2TACTIC_H_ #define SOLVER2TACTIC_H_ -#include "tactic.h" -#include "filter_model_converter.h" +#include "tactic/tactic.h" +#include "tactic/filter_model_converter.h" class solver; tactic * mk_solver2tactic(solver* s); diff --git a/src/solver/solver_na2as.cpp b/src/solver/solver_na2as.cpp index 31895b8ef..2628380c5 100644 --- a/src/solver/solver_na2as.cpp +++ b/src/solver/solver_na2as.cpp @@ -19,8 +19,8 @@ Author: Notes: --*/ -#include"solver_na2as.h" -#include"ast_smt2_pp.h" +#include "solver/solver_na2as.h" +#include "ast/ast_smt2_pp.h" solver_na2as::solver_na2as(ast_manager & m): diff --git a/src/solver/solver_na2as.h b/src/solver/solver_na2as.h index aaa48efe7..3e726be12 100644 --- a/src/solver/solver_na2as.h +++ b/src/solver/solver_na2as.h @@ -22,7 +22,7 @@ Notes: #ifndef SOLVER_NA2AS_H_ #define SOLVER_NA2AS_H_ -#include"solver.h" +#include "solver/solver.h" class solver_na2as : public solver { protected: diff --git a/src/solver/tactic2solver.cpp b/src/solver/tactic2solver.cpp index e451f57d4..d7e7fbb6e 100644 --- a/src/solver/tactic2solver.cpp +++ b/src/solver/tactic2solver.cpp @@ -19,10 +19,10 @@ Author: Notes: --*/ -#include"solver_na2as.h" -#include"tactic.h" -#include"ast_translation.h" -#include"mus.h" +#include "solver/solver_na2as.h" +#include "tactic/tactic.h" +#include "ast/ast_translation.h" +#include "solver/mus.h" /** \brief Simulates the incremental solver interface using a tactic. diff --git a/src/solver/tactic2solver.h b/src/solver/tactic2solver.h index 9158a00b7..2da0f69eb 100644 --- a/src/solver/tactic2solver.h +++ b/src/solver/tactic2solver.h @@ -22,7 +22,7 @@ Notes: #ifndef TACTIC2SOLVER_H_ #define TACTIC2SOLVER_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; class tactic_factory; diff --git a/src/tactic/aig/aig.cpp b/src/tactic/aig/aig.cpp index 6e289d969..e8226e159 100644 --- a/src/tactic/aig/aig.cpp +++ b/src/tactic/aig/aig.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"aig.h" -#include"goal.h" -#include"ast_smt2_pp.h" -#include"cooperate.h" +#include "tactic/aig/aig.h" +#include "tactic/goal.h" +#include "ast/ast_smt2_pp.h" +#include "util/cooperate.h" #define USE_TWO_LEVEL_RULES #define FIRST_NODE_ID (UINT_MAX/2) diff --git a/src/tactic/aig/aig.h b/src/tactic/aig/aig.h index fbbde7de6..5e0add752 100644 --- a/src/tactic/aig/aig.h +++ b/src/tactic/aig/aig.h @@ -19,8 +19,8 @@ Notes: #ifndef AIG_H_ #define AIG_H_ -#include"ast.h" -#include"tactic_exception.h" +#include "ast/ast.h" +#include "tactic/tactic_exception.h" class goal; class aig_lit; diff --git a/src/tactic/aig/aig_tactic.cpp b/src/tactic/aig/aig_tactic.cpp index 59d114ed6..37ffc6124 100644 --- a/src/tactic/aig/aig_tactic.cpp +++ b/src/tactic/aig/aig_tactic.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"tactical.h" -#include"aig.h" +#include "tactic/tactical.h" +#include "tactic/aig/aig.h" class aig_manager; diff --git a/src/tactic/aig/aig_tactic.h b/src/tactic/aig/aig_tactic.h index d9584ad02..2ba97e3b4 100644 --- a/src/tactic/aig/aig_tactic.h +++ b/src/tactic/aig/aig_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef AIG_TACTIC_H_ #define AIG_TACTIC_H_ -#include"params.h" +#include "util/params.h" class tactic; tactic * mk_aig_tactic(params_ref const & p = params_ref()); diff --git a/src/tactic/arith/add_bounds_tactic.cpp b/src/tactic/arith/add_bounds_tactic.cpp index 8ff82af17..ac105eb06 100644 --- a/src/tactic/arith/add_bounds_tactic.cpp +++ b/src/tactic/arith/add_bounds_tactic.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"arith_decl_plugin.h" -#include"ast_smt2_pp.h" -#include"bound_manager.h" +#include "tactic/tactical.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_smt2_pp.h" +#include "tactic/arith/bound_manager.h" struct is_unbounded_proc { struct found {}; diff --git a/src/tactic/arith/add_bounds_tactic.h b/src/tactic/arith/add_bounds_tactic.h index 7cb146fc7..b7b8f419c 100644 --- a/src/tactic/arith/add_bounds_tactic.h +++ b/src/tactic/arith/add_bounds_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef ADD_BOUNDS_H_ #define ADD_BOUNDS_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class goal; diff --git a/src/tactic/arith/arith_bounds_tactic.cpp b/src/tactic/arith/arith_bounds_tactic.cpp index fe054aaea..b750689b1 100644 --- a/src/tactic/arith/arith_bounds_tactic.cpp +++ b/src/tactic/arith/arith_bounds_tactic.cpp @@ -6,8 +6,8 @@ Copyright (c) 2015 Microsoft Corporation -#include"arith_bounds_tactic.h" -#include"arith_decl_plugin.h" +#include "tactic/arith/arith_bounds_tactic.h" +#include "ast/arith_decl_plugin.h" struct arith_bounds_tactic : public tactic { diff --git a/src/tactic/arith/arith_bounds_tactic.h b/src/tactic/arith/arith_bounds_tactic.h index 78da93867..92bc85564 100644 --- a/src/tactic/arith/arith_bounds_tactic.h +++ b/src/tactic/arith/arith_bounds_tactic.h @@ -30,7 +30,7 @@ Notes: --*/ #ifndef ARITH_BOUNDS_TACTIC_H_ #define ARITH_BOUNDS_TACTIC_H_ -#include "tactic.h" +#include "tactic/tactic.h" tactic * mk_arith_bounds_tactic(ast_manager & m, params_ref const & p = params_ref()); diff --git a/src/tactic/arith/bound_manager.cpp b/src/tactic/arith/bound_manager.cpp index 97d93658c..da507ea10 100644 --- a/src/tactic/arith/bound_manager.cpp +++ b/src/tactic/arith/bound_manager.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"bound_manager.h" -#include"ast_smt2_pp.h" -#include"goal.h" +#include "tactic/arith/bound_manager.h" +#include "ast/ast_smt2_pp.h" +#include "tactic/goal.h" bound_manager::bound_manager(ast_manager & m): m_util(m) { diff --git a/src/tactic/arith/bound_manager.h b/src/tactic/arith/bound_manager.h index 6a4dc2c96..a08a53614 100644 --- a/src/tactic/arith/bound_manager.h +++ b/src/tactic/arith/bound_manager.h @@ -19,8 +19,8 @@ Notes: #ifndef BOUND_MANAGER_H_ #define BOUND_MANAGER_H_ -#include"ast.h" -#include"arith_decl_plugin.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" class goal; diff --git a/src/tactic/arith/bound_propagator.cpp b/src/tactic/arith/bound_propagator.cpp index dbd7c5f69..51499674b 100644 --- a/src/tactic/arith/bound_propagator.cpp +++ b/src/tactic/arith/bound_propagator.cpp @@ -17,7 +17,7 @@ Author: Revision History: --*/ -#include"bound_propagator.h" +#include "tactic/arith/bound_propagator.h" #include // ------------------------------- diff --git a/src/tactic/arith/bound_propagator.h b/src/tactic/arith/bound_propagator.h index 2781bed55..042e39e5f 100644 --- a/src/tactic/arith/bound_propagator.h +++ b/src/tactic/arith/bound_propagator.h @@ -20,12 +20,12 @@ Revision History: #ifndef BOUND_PROPAGATOR_H_ #define BOUND_PROPAGATOR_H_ -#include"mpq.h" -#include"vector.h" -#include"params.h" -#include"statistics.h" -#include"numeral_buffer.h" -#include"linear_equation.h" +#include "util/mpq.h" +#include "util/vector.h" +#include "util/params.h" +#include "util/statistics.h" +#include "util/numeral_buffer.h" +#include "tactic/arith/linear_equation.h" class bound_propagator { public: diff --git a/src/tactic/arith/bv2int_rewriter.cpp b/src/tactic/arith/bv2int_rewriter.cpp index 098e04a8d..4315b0f5f 100644 --- a/src/tactic/arith/bv2int_rewriter.cpp +++ b/src/tactic/arith/bv2int_rewriter.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include "bv2int_rewriter.h" -#include "rewriter_def.h" -#include "ast_pp.h" -#include "ast_util.h" +#include "tactic/arith/bv2int_rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" +#include "ast/ast_util.h" void bv2int_rewriter_ctx::update_params(params_ref const& p) { m_max_size = p.get_uint("max_bv_size", UINT_MAX); diff --git a/src/tactic/arith/bv2int_rewriter.h b/src/tactic/arith/bv2int_rewriter.h index 15a425857..9ef256197 100644 --- a/src/tactic/arith/bv2int_rewriter.h +++ b/src/tactic/arith/bv2int_rewriter.h @@ -19,12 +19,12 @@ Notes: #ifndef BV2INT_REWRITER_H_ #define BV2INT_REWRITER_H_ -#include"ast.h" -#include"rewriter.h" -#include"bv_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"params.h" -#include"goal.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "util/params.h" +#include "tactic/goal.h" class bv2int_rewriter_ctx { unsigned m_max_size; diff --git a/src/tactic/arith/bv2real_rewriter.cpp b/src/tactic/arith/bv2real_rewriter.cpp index 4f952b697..5839ff7a2 100644 --- a/src/tactic/arith/bv2real_rewriter.cpp +++ b/src/tactic/arith/bv2real_rewriter.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"bv2real_rewriter.h" -#include"rewriter_def.h" -#include"ast_pp.h" -#include"for_each_expr.h" +#include "tactic/arith/bv2real_rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" +#include "ast/for_each_expr.h" bv2real_util::bv2real_util(ast_manager& m, rational const& default_root, rational const& default_divisor, unsigned max_num_bits) : diff --git a/src/tactic/arith/bv2real_rewriter.h b/src/tactic/arith/bv2real_rewriter.h index 5f80db4a3..f020f9f1e 100644 --- a/src/tactic/arith/bv2real_rewriter.h +++ b/src/tactic/arith/bv2real_rewriter.h @@ -19,10 +19,10 @@ Notes: #ifndef BV2REAL_REWRITER_H_ #define BV2REAL_REWRITER_H_ -#include"ast.h" -#include"rewriter.h" -#include"bv_decl_plugin.h" -#include"arith_decl_plugin.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" // // bv2real[d,r](n,m) has interpretation: diff --git a/src/tactic/arith/card2bv_tactic.cpp b/src/tactic/arith/card2bv_tactic.cpp index 096e52981..d2453eba2 100644 --- a/src/tactic/arith/card2bv_tactic.cpp +++ b/src/tactic/arith/card2bv_tactic.cpp @@ -16,14 +16,14 @@ Author: Notes: --*/ -#include"tactical.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"card2bv_tactic.h" -#include"pb2bv_rewriter.h" -#include"ast_util.h" -#include"ast_pp.h" -#include"filter_model_converter.h" +#include "tactic/tactical.h" +#include "util/cooperate.h" +#include "ast/ast_smt2_pp.h" +#include "tactic/arith/card2bv_tactic.h" +#include "ast/rewriter/pb2bv_rewriter.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" +#include "tactic/filter_model_converter.h" class card2bv_tactic : public tactic { ast_manager & m; diff --git a/src/tactic/arith/card2bv_tactic.h b/src/tactic/arith/card2bv_tactic.h index 9bf21d2c3..287dfa27e 100644 --- a/src/tactic/arith/card2bv_tactic.h +++ b/src/tactic/arith/card2bv_tactic.h @@ -19,12 +19,12 @@ Notes: #ifndef CARD2BV_TACTIC_H_ #define CARD2BV_TACTIC_H_ -#include"params.h" -#include"pb_decl_plugin.h" -#include"th_rewriter.h" -#include"rewriter.h" +#include "util/params.h" +#include "ast/pb_decl_plugin.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/rewriter.h" #include -#include"sorting_network.h" +#include "util/sorting_network.h" class ast_manager; diff --git a/src/tactic/arith/degree_shift_tactic.cpp b/src/tactic/arith/degree_shift_tactic.cpp index 6c5527d12..6344c4c51 100644 --- a/src/tactic/arith/degree_shift_tactic.cpp +++ b/src/tactic/arith/degree_shift_tactic.cpp @@ -19,14 +19,14 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"filter_model_converter.h" -#include"extension_model_converter.h" -#include"cooperate.h" -#include"arith_decl_plugin.h" -#include"simplify_tactic.h" -#include"ast_smt2_pp.h" -#include"rewriter_def.h" +#include "tactic/tactical.h" +#include "tactic/filter_model_converter.h" +#include "tactic/extension_model_converter.h" +#include "util/cooperate.h" +#include "ast/arith_decl_plugin.h" +#include "tactic/core/simplify_tactic.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/rewriter_def.h" class degree_shift_tactic : public tactic { struct imp { diff --git a/src/tactic/arith/degree_shift_tactic.h b/src/tactic/arith/degree_shift_tactic.h index efc0d442e..3456e19e5 100644 --- a/src/tactic/arith/degree_shift_tactic.h +++ b/src/tactic/arith/degree_shift_tactic.h @@ -22,7 +22,7 @@ Revision History: #ifndef DEGREE_SHIFT_TACTIC_H_ #define DEGREE_SHIFT_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/diff_neq_tactic.cpp b/src/tactic/arith/diff_neq_tactic.cpp index d63c2fcf4..651000297 100644 --- a/src/tactic/arith/diff_neq_tactic.cpp +++ b/src/tactic/arith/diff_neq_tactic.cpp @@ -20,10 +20,10 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"arith_decl_plugin.h" -#include"ast_smt2_pp.h" -#include"model.h" +#include "tactic/tactical.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_smt2_pp.h" +#include "model/model.h" class diff_neq_tactic : public tactic { struct imp { diff --git a/src/tactic/arith/diff_neq_tactic.h b/src/tactic/arith/diff_neq_tactic.h index 205fb7bb5..3fbe616dc 100644 --- a/src/tactic/arith/diff_neq_tactic.h +++ b/src/tactic/arith/diff_neq_tactic.h @@ -23,7 +23,7 @@ Revision History: #ifndef DIFF_NEQ_TACTIC_H_ #define DIFF_NEQ_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/elim01_tactic.cpp b/src/tactic/arith/elim01_tactic.cpp index e00b1e9c0..b6fd5eee7 100644 --- a/src/tactic/arith/elim01_tactic.cpp +++ b/src/tactic/arith/elim01_tactic.cpp @@ -16,15 +16,15 @@ Author: Notes: --*/ -#include"tactical.h" -#include"cooperate.h" -#include"bound_manager.h" -#include"ast_pp.h" -#include"expr_safe_replace.h" // NB: should use proof-producing expr_substitute in polished version. -#include"arith_decl_plugin.h" -#include"elim01_tactic.h" -#include"model_smt2_pp.h" -#include"th_rewriter.h" +#include "tactic/tactical.h" +#include "util/cooperate.h" +#include "tactic/arith/bound_manager.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/arith_decl_plugin.h" +#include "tactic/arith/elim01_tactic.h" +#include "model/model_smt2_pp.h" +#include "ast/rewriter/th_rewriter.h" class bool2int_model_converter : public model_converter { ast_manager& m; diff --git a/src/tactic/arith/elim01_tactic.h b/src/tactic/arith/elim01_tactic.h index 210f2b9fc..d9cd3a2ed 100644 --- a/src/tactic/arith/elim01_tactic.h +++ b/src/tactic/arith/elim01_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef ELIM01_TACTIC_H_ #define ELIM01_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/eq2bv_tactic.cpp b/src/tactic/arith/eq2bv_tactic.cpp index ac1ee9afd..255665b56 100644 --- a/src/tactic/arith/eq2bv_tactic.cpp +++ b/src/tactic/arith/eq2bv_tactic.cpp @@ -17,15 +17,15 @@ Author: Notes: --*/ -#include"tactical.h" -#include"cooperate.h" -#include"bound_manager.h" -#include"ast_pp.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"rewriter_def.h" -#include"ast_util.h" -#include"ast_pp_util.h" +#include "tactic/tactical.h" +#include "util/cooperate.h" +#include "tactic/arith/bound_manager.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_util.h" +#include "ast/ast_pp_util.h" class eq2bv_tactic : public tactic { struct eq_rewriter_cfg : public default_rewriter_cfg { diff --git a/src/tactic/arith/eq2bv_tactic.h b/src/tactic/arith/eq2bv_tactic.h index e336b1e0a..9441bfed3 100644 --- a/src/tactic/arith/eq2bv_tactic.h +++ b/src/tactic/arith/eq2bv_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef EQ2BV_TACTIC_H_ #define EQ2BV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/factor_tactic.cpp b/src/tactic/arith/factor_tactic.cpp index 70bff2610..d187c0078 100644 --- a/src/tactic/arith/factor_tactic.cpp +++ b/src/tactic/arith/factor_tactic.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"expr2polynomial.h" -#include"rewriter_def.h" +#include "tactic/tactical.h" +#include "ast/expr2polynomial.h" +#include "ast/rewriter/rewriter_def.h" class factor_tactic : public tactic { diff --git a/src/tactic/arith/factor_tactic.h b/src/tactic/arith/factor_tactic.h index 0948606e0..3b48f9f6d 100644 --- a/src/tactic/arith/factor_tactic.h +++ b/src/tactic/arith/factor_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef FACTOR_TACTIC_H_ #define FACTOR_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/fix_dl_var_tactic.cpp b/src/tactic/arith/fix_dl_var_tactic.cpp index 1a9a18c44..7ff7bd835 100644 --- a/src/tactic/arith/fix_dl_var_tactic.cpp +++ b/src/tactic/arith/fix_dl_var_tactic.cpp @@ -21,12 +21,12 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"th_rewriter.h" -#include"extension_model_converter.h" -#include"arith_decl_plugin.h" -#include"expr_substitution.h" -#include"ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "ast/rewriter/th_rewriter.h" +#include "tactic/extension_model_converter.h" +#include "ast/arith_decl_plugin.h" +#include "ast/expr_substitution.h" +#include "ast/ast_smt2_pp.h" class fix_dl_var_tactic : public tactic { diff --git a/src/tactic/arith/fix_dl_var_tactic.h b/src/tactic/arith/fix_dl_var_tactic.h index 3cee418cb..9e204bf1b 100644 --- a/src/tactic/arith/fix_dl_var_tactic.h +++ b/src/tactic/arith/fix_dl_var_tactic.h @@ -24,7 +24,7 @@ Notes: #ifndef FIX_DL_VAR_TACTIC_H_ #define FIX_DL_VAR_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/fm_tactic.cpp b/src/tactic/arith/fm_tactic.cpp index 6db0f5ad3..48f584169 100644 --- a/src/tactic/arith/fm_tactic.cpp +++ b/src/tactic/arith/fm_tactic.cpp @@ -21,17 +21,17 @@ Author: Revision History: --*/ -#include"fm_tactic.h" -#include"tactical.h" -#include"arith_decl_plugin.h" -#include"for_each_expr.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"id_gen.h" -#include"model_evaluator.h" -#include"model_v2_pp.h" -#include"simplify_tactic.h" +#include "tactic/arith/fm_tactic.h" +#include "tactic/tactical.h" +#include "ast/arith_decl_plugin.h" +#include "ast/for_each_expr.h" +#include "util/cooperate.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_pp.h" +#include "util/id_gen.h" +#include "model/model_evaluator.h" +#include "model/model_v2_pp.h" +#include "tactic/core/simplify_tactic.h" class fm_tactic : public tactic { typedef ptr_vector clauses; diff --git a/src/tactic/arith/fm_tactic.h b/src/tactic/arith/fm_tactic.h index f45ab2475..0b59ab98f 100644 --- a/src/tactic/arith/fm_tactic.h +++ b/src/tactic/arith/fm_tactic.h @@ -24,7 +24,7 @@ Revision History: #ifndef FM_TACTIC_H_ #define FM_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/lia2card_tactic.cpp b/src/tactic/arith/lia2card_tactic.cpp index 8f37a8d5e..ec41f5845 100644 --- a/src/tactic/arith/lia2card_tactic.cpp +++ b/src/tactic/arith/lia2card_tactic.cpp @@ -34,15 +34,15 @@ Author: Notes: --*/ -#include"tactical.h" -#include"cooperate.h" -#include"bound_manager.h" -#include"ast_pp.h" -#include"pb_decl_plugin.h" -#include"arith_decl_plugin.h" -#include"rewriter_def.h" -#include"ast_util.h" -#include"ast_pp_util.h" +#include "tactic/tactical.h" +#include "util/cooperate.h" +#include "tactic/arith/bound_manager.h" +#include "ast/ast_pp.h" +#include "ast/pb_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_util.h" +#include "ast/ast_pp_util.h" class lia2card_tactic : public tactic { struct lia_rewriter_cfg : public default_rewriter_cfg { diff --git a/src/tactic/arith/lia2card_tactic.h b/src/tactic/arith/lia2card_tactic.h index 93adb6f46..4a8334f10 100644 --- a/src/tactic/arith/lia2card_tactic.h +++ b/src/tactic/arith/lia2card_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef LIA2CARD_TACTIC_H_ #define LIA2CARD_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/lia2pb_tactic.cpp b/src/tactic/arith/lia2pb_tactic.cpp index 2b54dd463..d303463db 100644 --- a/src/tactic/arith/lia2pb_tactic.cpp +++ b/src/tactic/arith/lia2pb_tactic.cpp @@ -16,15 +16,15 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"bound_manager.h" -#include"th_rewriter.h" -#include"for_each_expr.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" -#include"arith_decl_plugin.h" -#include"expr_substitution.h" -#include"ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "tactic/arith/bound_manager.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/for_each_expr.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "ast/arith_decl_plugin.h" +#include "ast/expr_substitution.h" +#include "ast/ast_smt2_pp.h" class lia2pb_tactic : public tactic { struct imp { diff --git a/src/tactic/arith/lia2pb_tactic.h b/src/tactic/arith/lia2pb_tactic.h index 273949825..29c05d52a 100644 --- a/src/tactic/arith/lia2pb_tactic.h +++ b/src/tactic/arith/lia2pb_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef LIA2PB_TACTIC_H_ #define LIA2PB_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/linear_equation.cpp b/src/tactic/arith/linear_equation.cpp index 0b8828674..ed158b778 100644 --- a/src/tactic/arith/linear_equation.cpp +++ b/src/tactic/arith/linear_equation.cpp @@ -18,7 +18,7 @@ Author: Revision History: --*/ -#include"linear_equation.h" +#include "tactic/arith/linear_equation.h" /** \brief Return the position of variable x_i in the linear equation. diff --git a/src/tactic/arith/linear_equation.h b/src/tactic/arith/linear_equation.h index 1de3969ca..1bfa94d1a 100644 --- a/src/tactic/arith/linear_equation.h +++ b/src/tactic/arith/linear_equation.h @@ -21,10 +21,10 @@ Revision History: #ifndef LINEAR_EQUATION_H_ #define LINEAR_EQUATION_H_ -#include"mpq.h" -#include"small_object_allocator.h" -#include"numeral_buffer.h" -#include"double_manager.h" +#include "util/mpq.h" +#include "util/small_object_allocator.h" +#include "util/numeral_buffer.h" +#include "util/double_manager.h" class linear_equation { public: diff --git a/src/tactic/arith/nla2bv_tactic.cpp b/src/tactic/arith/nla2bv_tactic.cpp index 1399d6549..6f5f49aee 100644 --- a/src/tactic/arith/nla2bv_tactic.cpp +++ b/src/tactic/arith/nla2bv_tactic.cpp @@ -18,19 +18,19 @@ Notes: The original file was called qfnla2bv.cpp --*/ -#include "tactical.h" -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "for_each_expr.h" -#include "expr_replacer.h" -#include "optional.h" -#include "bv2int_rewriter.h" -#include "bv2real_rewriter.h" -#include "extension_model_converter.h" -#include "filter_model_converter.h" -#include "bound_manager.h" -#include "obj_pair_hashtable.h" -#include "ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/expr_replacer.h" +#include "util/optional.h" +#include "tactic/arith/bv2int_rewriter.h" +#include "tactic/arith/bv2real_rewriter.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "tactic/arith/bound_manager.h" +#include "util/obj_pair_hashtable.h" +#include "ast/ast_smt2_pp.h" // // diff --git a/src/tactic/arith/nla2bv_tactic.h b/src/tactic/arith/nla2bv_tactic.h index e2d207520..c6be722a3 100644 --- a/src/tactic/arith/nla2bv_tactic.h +++ b/src/tactic/arith/nla2bv_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef NLA2BV_TACTIC_H_ #define NLA2BV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/normalize_bounds_tactic.cpp b/src/tactic/arith/normalize_bounds_tactic.cpp index 06f1368a2..2b3ff5ab0 100644 --- a/src/tactic/arith/normalize_bounds_tactic.cpp +++ b/src/tactic/arith/normalize_bounds_tactic.cpp @@ -18,14 +18,14 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"bound_manager.h" -#include"th_rewriter.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" -#include"arith_decl_plugin.h" -#include"expr_substitution.h" -#include"ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "tactic/arith/bound_manager.h" +#include "ast/rewriter/th_rewriter.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "ast/arith_decl_plugin.h" +#include "ast/expr_substitution.h" +#include "ast/ast_smt2_pp.h" class normalize_bounds_tactic : public tactic { struct imp { diff --git a/src/tactic/arith/normalize_bounds_tactic.h b/src/tactic/arith/normalize_bounds_tactic.h index 1ecbf88d8..f8473842f 100644 --- a/src/tactic/arith/normalize_bounds_tactic.h +++ b/src/tactic/arith/normalize_bounds_tactic.h @@ -21,7 +21,7 @@ Revision History: #ifndef NORMALIZE_BOUNDS_TACTIC_H_ #define NORMALIZE_BOUNDS_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/pb2bv_model_converter.cpp b/src/tactic/arith/pb2bv_model_converter.cpp index 8dbacc6cd..df5bd5745 100644 --- a/src/tactic/arith/pb2bv_model_converter.cpp +++ b/src/tactic/arith/pb2bv_model_converter.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"trace.h" -#include"arith_decl_plugin.h" -#include"model_v2_pp.h" -#include"pb2bv_model_converter.h" +#include "util/trace.h" +#include "ast/arith_decl_plugin.h" +#include "model/model_v2_pp.h" +#include "tactic/arith/pb2bv_model_converter.h" pb2bv_model_converter::pb2bv_model_converter(ast_manager & _m) : m(_m) { diff --git a/src/tactic/arith/pb2bv_model_converter.h b/src/tactic/arith/pb2bv_model_converter.h index 8b6256ccc..0c2826573 100644 --- a/src/tactic/arith/pb2bv_model_converter.h +++ b/src/tactic/arith/pb2bv_model_converter.h @@ -19,8 +19,8 @@ Notes: #ifndef PB2BV_MODEL_CONVERTER_H_ #define PB2BV_MODEL_CONVERTER_H_ -#include"model_converter.h" -#include"bound_manager.h" +#include "tactic/model_converter.h" +#include "tactic/arith/bound_manager.h" class pb2bv_model_converter : public model_converter { typedef std::pair func_decl_pair; diff --git a/src/tactic/arith/pb2bv_tactic.cpp b/src/tactic/arith/pb2bv_tactic.cpp index 3931a1ea4..259cbc0c8 100644 --- a/src/tactic/arith/pb2bv_tactic.cpp +++ b/src/tactic/arith/pb2bv_tactic.cpp @@ -16,20 +16,20 @@ Author: Notes: --*/ -#include"tactical.h" -#include"cooperate.h" -#include"bound_manager.h" -#include"bool_rewriter.h" -#include"rewriter_def.h" -#include"ref_util.h" -#include"arith_decl_plugin.h" -#include"trace.h" -#include"ast_smt2_pp.h" -#include"expr_substitution.h" -#include"filter_model_converter.h" -#include"pb2bv_model_converter.h" -#include"pb2bv_tactic.h" -#include"ast_pp.h" +#include "tactic/tactical.h" +#include "util/cooperate.h" +#include "tactic/arith/bound_manager.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/ref_util.h" +#include "ast/arith_decl_plugin.h" +#include "util/trace.h" +#include "ast/ast_smt2_pp.h" +#include "ast/expr_substitution.h" +#include "tactic/filter_model_converter.h" +#include "tactic/arith/pb2bv_model_converter.h" +#include "tactic/arith/pb2bv_tactic.h" +#include "ast/ast_pp.h" class pb2bv_tactic : public tactic { public: diff --git a/src/tactic/arith/pb2bv_tactic.h b/src/tactic/arith/pb2bv_tactic.h index 7d7e8919c..49e87a8f7 100644 --- a/src/tactic/arith/pb2bv_tactic.h +++ b/src/tactic/arith/pb2bv_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef PB2BV_TACTIC_H_ #define PB2BV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/probe_arith.cpp b/src/tactic/arith/probe_arith.cpp index 5d5590263..c2de64484 100644 --- a/src/tactic/arith/probe_arith.cpp +++ b/src/tactic/arith/probe_arith.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"probe.h" -#include"expr2polynomial.h" -#include"for_each_expr.h" -#include"arith_decl_plugin.h" -#include"goal_util.h" +#include "tactic/probe.h" +#include "ast/expr2polynomial.h" +#include "ast/for_each_expr.h" +#include "ast/arith_decl_plugin.h" +#include "tactic/goal_util.h" class arith_degree_probe : public probe { struct proc { diff --git a/src/tactic/arith/propagate_ineqs_tactic.cpp b/src/tactic/arith/propagate_ineqs_tactic.cpp index 1a3447f38..d7209740f 100644 --- a/src/tactic/arith/propagate_ineqs_tactic.cpp +++ b/src/tactic/arith/propagate_ineqs_tactic.cpp @@ -30,11 +30,11 @@ Author: Notes: --*/ -#include"tactical.h" -#include"bound_propagator.h" -#include"arith_decl_plugin.h" -#include"simplify_tactic.h" -#include"ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "tactic/arith/bound_propagator.h" +#include "ast/arith_decl_plugin.h" +#include "tactic/core/simplify_tactic.h" +#include "ast/ast_smt2_pp.h" class propagate_ineqs_tactic : public tactic { struct imp; diff --git a/src/tactic/arith/propagate_ineqs_tactic.h b/src/tactic/arith/propagate_ineqs_tactic.h index 1027bd09f..fb5e370c6 100644 --- a/src/tactic/arith/propagate_ineqs_tactic.h +++ b/src/tactic/arith/propagate_ineqs_tactic.h @@ -33,7 +33,7 @@ Notes: #ifndef PROPAGATE_INEQS_TACTIC_H_ #define PROPAGATE_INEQS_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/purify_arith_tactic.cpp b/src/tactic/arith/purify_arith_tactic.cpp index 463e1a9e8..0443a51ed 100644 --- a/src/tactic/arith/purify_arith_tactic.cpp +++ b/src/tactic/arith/purify_arith_tactic.cpp @@ -20,17 +20,17 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"rewriter_def.h" -#include"arith_decl_plugin.h" -#include"algebraic_numbers.h" -#include"nnf_tactic.h" -#include"simplify_tactic.h" -#include"th_rewriter.h" -#include"filter_model_converter.h" -#include"extension_model_converter.h" -#include"ast_smt2_pp.h" -#include"expr_replacer.h" +#include "tactic/tactical.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/arith_decl_plugin.h" +#include "math/polynomial/algebraic_numbers.h" +#include "tactic/core/nnf_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "ast/rewriter/th_rewriter.h" +#include "tactic/filter_model_converter.h" +#include "tactic/extension_model_converter.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/expr_replacer.h" /* ---- diff --git a/src/tactic/arith/purify_arith_tactic.h b/src/tactic/arith/purify_arith_tactic.h index 9d4c927ff..bbb62710c 100644 --- a/src/tactic/arith/purify_arith_tactic.h +++ b/src/tactic/arith/purify_arith_tactic.h @@ -48,7 +48,7 @@ Revision History: #ifndef PURIFY_ARITH_TACTIC_H_ #define PURIFY_ARITH_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/arith/recover_01_tactic.cpp b/src/tactic/arith/recover_01_tactic.cpp index 393d30b58..d3b9ecc3e 100644 --- a/src/tactic/arith/recover_01_tactic.cpp +++ b/src/tactic/arith/recover_01_tactic.cpp @@ -30,14 +30,14 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"th_rewriter.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" -#include"arith_decl_plugin.h" -#include"expr_substitution.h" -#include"dec_ref_util.h" -#include"ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "ast/rewriter/th_rewriter.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "ast/arith_decl_plugin.h" +#include "ast/expr_substitution.h" +#include "util/dec_ref_util.h" +#include "ast/ast_smt2_pp.h" class recover_01_tactic : public tactic { struct imp { diff --git a/src/tactic/arith/recover_01_tactic.h b/src/tactic/arith/recover_01_tactic.h index baa8ae06f..898586481 100644 --- a/src/tactic/arith/recover_01_tactic.h +++ b/src/tactic/arith/recover_01_tactic.h @@ -33,7 +33,7 @@ Revision History: #ifndef RECOVER_01_TACTIC_H_ #define RECOVER_01_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/bv/bit_blaster_model_converter.cpp b/src/tactic/bv/bit_blaster_model_converter.cpp index a18862ee8..373cf3113 100644 --- a/src/tactic/bv/bit_blaster_model_converter.cpp +++ b/src/tactic/bv/bit_blaster_model_converter.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"model.h" -#include"model_pp.h" -#include"model_converter.h" -#include"bv_decl_plugin.h" -#include"ast_smt2_pp.h" +#include "model/model.h" +#include "model/model_pp.h" +#include "tactic/model_converter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/ast_smt2_pp.h" /** If TO_BOOL == true, then bit-vectors of size n were blasted into n-tuples of Booleans. diff --git a/src/tactic/bv/bit_blaster_model_converter.h b/src/tactic/bv/bit_blaster_model_converter.h index 87a12a89e..f7dd254b4 100644 --- a/src/tactic/bv/bit_blaster_model_converter.h +++ b/src/tactic/bv/bit_blaster_model_converter.h @@ -19,7 +19,7 @@ Notes: #ifndef BIT_BLASTER_MODEL_CONVERTER_H_ #define BIT_BLASTER_MODEL_CONVERTER_H_ -#include"model_converter.h" +#include "tactic/model_converter.h" model_converter * mk_bit_blaster_model_converter(ast_manager & m, obj_map const & const2bits); model_converter * mk_bv1_blaster_model_converter(ast_manager & m, obj_map const & const2bits); diff --git a/src/tactic/bv/bit_blaster_tactic.cpp b/src/tactic/bv/bit_blaster_tactic.cpp index 7e19585d9..5c6c43778 100644 --- a/src/tactic/bv/bit_blaster_tactic.cpp +++ b/src/tactic/bv/bit_blaster_tactic.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"bit_blaster_model_converter.h" -#include"bit_blaster_rewriter.h" -#include"ast_pp.h" -#include"model_pp.h" -#include"rewriter_types.h" +#include "tactic/tactical.h" +#include "tactic/bv/bit_blaster_model_converter.h" +#include "ast/rewriter/bit_blaster/bit_blaster_rewriter.h" +#include "ast/ast_pp.h" +#include "model/model_pp.h" +#include "ast/rewriter/rewriter_types.h" class bit_blaster_tactic : public tactic { diff --git a/src/tactic/bv/bit_blaster_tactic.h b/src/tactic/bv/bit_blaster_tactic.h index d840154b9..2dccafb6d 100644 --- a/src/tactic/bv/bit_blaster_tactic.h +++ b/src/tactic/bv/bit_blaster_tactic.h @@ -19,8 +19,8 @@ Copyright (c) 2011 Microsoft Corporation #ifndef BIT_BLASTER_TACTIC_H_ #define BIT_BLASTER_TACTIC_H_ - #include"params.h" - #include"bit_blaster_rewriter.h" +#include "util/params.h" +#include "ast/rewriter/bit_blaster/bit_blaster_rewriter.h" class ast_manager; class tactic; diff --git a/src/tactic/bv/bv1_blaster_tactic.cpp b/src/tactic/bv/bv1_blaster_tactic.cpp index e7327e7a9..e7e374184 100644 --- a/src/tactic/bv/bv1_blaster_tactic.cpp +++ b/src/tactic/bv/bv1_blaster_tactic.cpp @@ -22,13 +22,13 @@ Author: Notes: --*/ -#include"tactical.h" -#include"bit_blaster_model_converter.h" -#include"bv_decl_plugin.h" -#include"rewriter_def.h" -#include"for_each_expr.h" -#include"cooperate.h" -#include"bv_rewriter.h" +#include "tactic/tactical.h" +#include "tactic/bv/bit_blaster_model_converter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/for_each_expr.h" +#include "util/cooperate.h" +#include "ast/rewriter/bv_rewriter.h" class bv1_blaster_tactic : public tactic { diff --git a/src/tactic/bv/bv1_blaster_tactic.h b/src/tactic/bv/bv1_blaster_tactic.h index cad1d59b6..5c8632fbc 100644 --- a/src/tactic/bv/bv1_blaster_tactic.h +++ b/src/tactic/bv/bv1_blaster_tactic.h @@ -25,7 +25,7 @@ Notes: #ifndef BV1_BLASTER_TACTIC_H_ #define BV1_BLASTER_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/bv/bv_bound_chk_tactic.cpp b/src/tactic/bv/bv_bound_chk_tactic.cpp index 1b90e05b1..ee7cb1ded 100644 --- a/src/tactic/bv/bv_bound_chk_tactic.cpp +++ b/src/tactic/bv/bv_bound_chk_tactic.cpp @@ -14,14 +14,14 @@ Revision History: --*/ -#include"bv_bound_chk_tactic.h" -#include"ast.h" -#include"rewriter.h" -#include"rewriter_def.h" -#include"bv_bounds.h" +#include "tactic/bv/bv_bound_chk_tactic.h" +#include "ast/ast.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/bv_bounds.h" #include"rewriter_params.hpp" -#include"bool_rewriter.h" -#include"cooperate.h" +#include "ast/rewriter/bool_rewriter.h" +#include "util/cooperate.h" struct bv_bound_chk_stats { unsigned m_unsats; diff --git a/src/tactic/bv/bv_bound_chk_tactic.h b/src/tactic/bv/bv_bound_chk_tactic.h index f134d42ab..0cdadb0de 100644 --- a/src/tactic/bv/bv_bound_chk_tactic.h +++ b/src/tactic/bv/bv_bound_chk_tactic.h @@ -17,9 +17,9 @@ #ifndef BV_BOUND_CHK_TACTIC_H_ #define BV_BOUND_CHK_TACTIC_H_ -#include"tactical.h" -#include"params.h" -#include"ast.h" +#include "tactic/tactical.h" +#include "util/params.h" +#include "ast/ast.h" tactic* mk_bv_bound_chk_tactic(ast_manager & m, params_ref const & p = params_ref()); diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp index 94c9935b9..d2cd0d66c 100644 --- a/src/tactic/bv/bv_bounds_tactic.cpp +++ b/src/tactic/bv/bv_bounds_tactic.cpp @@ -16,10 +16,10 @@ Author: --*/ -#include "bv_bounds_tactic.h" -#include "ctx_simplify_tactic.h" -#include "bv_decl_plugin.h" -#include "ast_pp.h" +#include "tactic/bv/bv_bounds_tactic.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "ast/bv_decl_plugin.h" +#include "ast/ast_pp.h" #include static uint64 uMaxInt(unsigned sz) { diff --git a/src/tactic/bv/bv_bounds_tactic.h b/src/tactic/bv/bv_bounds_tactic.h index 4793f474f..6c2ce60ed 100644 --- a/src/tactic/bv/bv_bounds_tactic.h +++ b/src/tactic/bv/bv_bounds_tactic.h @@ -17,7 +17,7 @@ Author: --*/ #ifndef BV_BOUNDS_TACTIC_H_ #define BV_BOUNDS_TACTIC_H_ -#include "tactic.h" +#include "tactic/tactic.h" tactic * mk_bv_bounds_tactic(ast_manager & m, params_ref const & p = params_ref()); diff --git a/src/tactic/bv/bv_size_reduction_tactic.cpp b/src/tactic/bv/bv_size_reduction_tactic.cpp index c010ed0af..9401f74c1 100644 --- a/src/tactic/bv/bv_size_reduction_tactic.cpp +++ b/src/tactic/bv/bv_size_reduction_tactic.cpp @@ -21,12 +21,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"bv_decl_plugin.h" -#include"expr_replacer.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" -#include"ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/expr_replacer.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "ast/ast_smt2_pp.h" class bv_size_reduction_tactic : public tactic { struct imp; diff --git a/src/tactic/bv/bv_size_reduction_tactic.h b/src/tactic/bv/bv_size_reduction_tactic.h index 619794fc0..4a24a1d78 100644 --- a/src/tactic/bv/bv_size_reduction_tactic.h +++ b/src/tactic/bv/bv_size_reduction_tactic.h @@ -24,7 +24,7 @@ Notes: #ifndef BV_SIZE_REDUCTION_TACTIC_H_ #define BV_SIZE_REDUCTION_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/bv/bvarray2uf_rewriter.cpp b/src/tactic/bv/bvarray2uf_rewriter.cpp index db60f3fcd..9b67e7011 100644 --- a/src/tactic/bv/bvarray2uf_rewriter.cpp +++ b/src/tactic/bv/bvarray2uf_rewriter.cpp @@ -18,14 +18,14 @@ Notes: --*/ -#include"cooperate.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"params.h" -#include"ast_pp.h" -#include"bvarray2uf_rewriter.h" -#include"rewriter_def.h" -#include"ref_util.h" +#include "util/cooperate.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "util/params.h" +#include "ast/ast_pp.h" +#include "tactic/bv/bvarray2uf_rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/ref_util.h" // [1] C. M. Wintersteiger, Y. Hamadi, and L. de Moura: Efficiently Solving // Quantified Bit-Vector Formulas, in Formal Methods in System Design, diff --git a/src/tactic/bv/bvarray2uf_rewriter.h b/src/tactic/bv/bvarray2uf_rewriter.h index 81b53ddd7..bc4014b5b 100644 --- a/src/tactic/bv/bvarray2uf_rewriter.h +++ b/src/tactic/bv/bvarray2uf_rewriter.h @@ -20,9 +20,9 @@ Notes: #ifndef BVARRAY2UF_REWRITER_H_ #define BVARRAY2UF_REWRITER_H_ -#include"rewriter.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" +#include "ast/rewriter/rewriter.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" class bvarray2uf_rewriter_cfg : public default_rewriter_cfg { ast_manager & m_manager; diff --git a/src/tactic/bv/bvarray2uf_tactic.cpp b/src/tactic/bv/bvarray2uf_tactic.cpp index ecf1889a2..87f43ae8d 100644 --- a/src/tactic/bv/bvarray2uf_tactic.cpp +++ b/src/tactic/bv/bvarray2uf_tactic.cpp @@ -17,15 +17,15 @@ Author: Notes: --*/ -#include"tactical.h" -#include"bv_decl_plugin.h" -#include"expr_replacer.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" -#include"ast_smt2_pp.h" +#include "tactic/tactical.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/expr_replacer.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "ast/ast_smt2_pp.h" -#include"bvarray2uf_tactic.h" -#include"bvarray2uf_rewriter.h" +#include "tactic/bv/bvarray2uf_tactic.h" +#include "tactic/bv/bvarray2uf_rewriter.h" class bvarray2uf_tactic : public tactic { diff --git a/src/tactic/bv/bvarray2uf_tactic.h b/src/tactic/bv/bvarray2uf_tactic.h index 336911bf7..84ad413f6 100644 --- a/src/tactic/bv/bvarray2uf_tactic.h +++ b/src/tactic/bv/bvarray2uf_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef BV_ARRAY2UF_TACTIC_H_ #define BV_ARRAY2UF_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/bv/dt2bv_tactic.cpp b/src/tactic/bv/dt2bv_tactic.cpp index 3ae72215f..fe59480e7 100644 --- a/src/tactic/bv/dt2bv_tactic.cpp +++ b/src/tactic/bv/dt2bv_tactic.cpp @@ -19,18 +19,18 @@ Revision History: --*/ -#include "dt2bv_tactic.h" -#include "tactical.h" -#include "filter_model_converter.h" -#include "datatype_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "rewriter_def.h" -#include "filter_model_converter.h" -#include "extension_model_converter.h" -#include "var_subst.h" -#include "ast_util.h" -#include "enum2bv_rewriter.h" -#include "ast_pp.h" +#include "tactic/bv/dt2bv_tactic.h" +#include "tactic/tactical.h" +#include "tactic/filter_model_converter.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/rewriter_def.h" +#include "tactic/filter_model_converter.h" +#include "tactic/extension_model_converter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_util.h" +#include "ast/rewriter/enum2bv_rewriter.h" +#include "ast/ast_pp.h" class dt2bv_tactic : public tactic { diff --git a/src/tactic/bv/dt2bv_tactic.h b/src/tactic/bv/dt2bv_tactic.h index 10ce0724f..1e6567995 100644 --- a/src/tactic/bv/dt2bv_tactic.h +++ b/src/tactic/bv/dt2bv_tactic.h @@ -19,8 +19,8 @@ Revision History: #ifndef DT2BV_TACTIC_H_ #define DT2BV_TACTIC_H_ -#include"params.h" -#include"obj_hashtable.h" +#include "util/params.h" +#include "util/obj_hashtable.h" class ast_manager; class tactic; diff --git a/src/tactic/bv/elim_small_bv_tactic.cpp b/src/tactic/bv/elim_small_bv_tactic.cpp index 8cfc27950..d24ae4f49 100644 --- a/src/tactic/bv/elim_small_bv_tactic.cpp +++ b/src/tactic/bv/elim_small_bv_tactic.cpp @@ -16,19 +16,19 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"rewriter_def.h" -#include"filter_model_converter.h" -#include"cooperate.h" -#include"bv_decl_plugin.h" -#include"used_vars.h" -#include"well_sorted.h" -#include"var_subst.h" -#include"simplifier.h" -#include"basic_simplifier_plugin.h" -#include"bv_simplifier_plugin.h" +#include "tactic/tactical.h" +#include "ast/rewriter/rewriter_def.h" +#include "tactic/filter_model_converter.h" +#include "util/cooperate.h" +#include "ast/bv_decl_plugin.h" +#include "ast/used_vars.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/var_subst.h" +#include "ast/simplifier/simplifier.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" -#include"elim_small_bv_tactic.h" +#include "tactic/bv/elim_small_bv_tactic.h" class elim_small_bv_tactic : public tactic { diff --git a/src/tactic/bv/elim_small_bv_tactic.h b/src/tactic/bv/elim_small_bv_tactic.h index bcdd8aad6..675ec3de7 100644 --- a/src/tactic/bv/elim_small_bv_tactic.h +++ b/src/tactic/bv/elim_small_bv_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef ELIM_SMALL_BV_H_ #define ELIM_SMALL_BV_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/bv/max_bv_sharing_tactic.cpp b/src/tactic/bv/max_bv_sharing_tactic.cpp index 675f26ace..b0affeb4b 100644 --- a/src/tactic/bv/max_bv_sharing_tactic.cpp +++ b/src/tactic/bv/max_bv_sharing_tactic.cpp @@ -19,12 +19,12 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"bv_decl_plugin.h" -#include"rewriter_def.h" -#include"obj_pair_hashtable.h" -#include"ast_lt.h" -#include"cooperate.h" +#include "tactic/tactical.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/obj_pair_hashtable.h" +#include "ast/ast_lt.h" +#include "util/cooperate.h" class max_bv_sharing_tactic : public tactic { diff --git a/src/tactic/bv/max_bv_sharing_tactic.h b/src/tactic/bv/max_bv_sharing_tactic.h index ffe5b025c..b8bc0753d 100644 --- a/src/tactic/bv/max_bv_sharing_tactic.h +++ b/src/tactic/bv/max_bv_sharing_tactic.h @@ -22,7 +22,7 @@ Revision History: #ifndef MAX_BV_SHARING_TACTIC_H_ #define MAX_BV_SHARING_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/converter.h b/src/tactic/converter.h index bed191bc2..9de8218c3 100644 --- a/src/tactic/converter.h +++ b/src/tactic/converter.h @@ -19,9 +19,9 @@ Notes: #ifndef CONVERTER_H_ #define CONVERTER_H_ -#include"vector.h" -#include"ref.h" -#include"ast_translation.h" +#include "util/vector.h" +#include "util/ref.h" +#include "ast/ast_translation.h" class converter { unsigned m_ref_count; diff --git a/src/tactic/core/blast_term_ite_tactic.cpp b/src/tactic/core/blast_term_ite_tactic.cpp index 483b59776..ae0ea019b 100644 --- a/src/tactic/core/blast_term_ite_tactic.cpp +++ b/src/tactic/core/blast_term_ite_tactic.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"defined_names.h" -#include"rewriter_def.h" -#include"filter_model_converter.h" -#include"cooperate.h" -#include"scoped_proof.h" +#include "tactic/tactical.h" +#include "ast/normal_forms/defined_names.h" +#include "ast/rewriter/rewriter_def.h" +#include "tactic/filter_model_converter.h" +#include "util/cooperate.h" +#include "ast/scoped_proof.h" diff --git a/src/tactic/core/blast_term_ite_tactic.h b/src/tactic/core/blast_term_ite_tactic.h index ac94723d8..1ecab98be 100644 --- a/src/tactic/core/blast_term_ite_tactic.h +++ b/src/tactic/core/blast_term_ite_tactic.h @@ -23,7 +23,7 @@ Notes: #ifndef BLAST_TERM_ITE_TACTIC_H_ #define BLAST_TERM_ITE_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/cofactor_elim_term_ite.cpp b/src/tactic/core/cofactor_elim_term_ite.cpp index 15f0e06ea..b90be82b5 100644 --- a/src/tactic/core/cofactor_elim_term_ite.cpp +++ b/src/tactic/core/cofactor_elim_term_ite.cpp @@ -16,14 +16,14 @@ Author: Revision History: --*/ -#include"cofactor_elim_term_ite.h" -#include"mk_simplified_app.h" -#include"rewriter_def.h" -#include"cooperate.h" -#include"for_each_expr.h" -#include"ast_smt2_pp.h" -#include"ast_ll_pp.h" -#include"tactic.h" +#include "tactic/core/cofactor_elim_term_ite.h" +#include "ast/rewriter/mk_simplified_app.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/cooperate.h" +#include "ast/for_each_expr.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_ll_pp.h" +#include "tactic/tactic.h" struct cofactor_elim_term_ite::imp { ast_manager & m; diff --git a/src/tactic/core/cofactor_elim_term_ite.h b/src/tactic/core/cofactor_elim_term_ite.h index 98142837c..dfbb66a63 100644 --- a/src/tactic/core/cofactor_elim_term_ite.h +++ b/src/tactic/core/cofactor_elim_term_ite.h @@ -19,8 +19,8 @@ Revision History: #ifndef COFACTOR_ELIM_TERM_ITE_H_ #define COFACTOR_ELIM_TERM_ITE_H_ -#include"ast.h" -#include"params.h" +#include "ast/ast.h" +#include "util/params.h" class cofactor_elim_term_ite { struct imp; diff --git a/src/tactic/core/cofactor_term_ite_tactic.cpp b/src/tactic/core/cofactor_term_ite_tactic.cpp index 2286281f4..65cdef147 100644 --- a/src/tactic/core/cofactor_term_ite_tactic.cpp +++ b/src/tactic/core/cofactor_term_ite_tactic.cpp @@ -17,8 +17,8 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"cofactor_elim_term_ite.h" +#include "tactic/tactical.h" +#include "tactic/core/cofactor_elim_term_ite.h" /** \brief Wrapper for applying cofactor_elim_term_ite in an assertion set. diff --git a/src/tactic/core/cofactor_term_ite_tactic.h b/src/tactic/core/cofactor_term_ite_tactic.h index 4e0342853..c6e2dfff2 100644 --- a/src/tactic/core/cofactor_term_ite_tactic.h +++ b/src/tactic/core/cofactor_term_ite_tactic.h @@ -20,7 +20,7 @@ Revision History: #ifndef COFACTOR_TERM_ITE_TACTIC_H_ #define COFACTOR_TERM_ITE_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/collect_occs.cpp b/src/tactic/core/collect_occs.cpp index 69c538db6..27de476f7 100644 --- a/src/tactic/core/collect_occs.cpp +++ b/src/tactic/core/collect_occs.cpp @@ -17,10 +17,10 @@ Notes: --*/ -#include "ast.h" -#include "goal.h" -#include "hashtable.h" -#include "collect_occs.h" +#include "ast/ast.h" +#include "tactic/goal.h" +#include "util/hashtable.h" +#include "tactic/core/collect_occs.h" bool collect_occs::visit(expr * t) { if (m_visited.is_marked(t)) { diff --git a/src/tactic/core/collect_statistics_tactic.cpp b/src/tactic/core/collect_statistics_tactic.cpp index 3b820de7a..26f6842e3 100644 --- a/src/tactic/core/collect_statistics_tactic.cpp +++ b/src/tactic/core/collect_statistics_tactic.cpp @@ -20,17 +20,17 @@ Notes: #include #include -#include"ast.h" -#include"params.h" -#include"arith_decl_plugin.h" -#include"array_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"fpa_decl_plugin.h" -#include"tactical.h" -#include"stats.h" +#include "ast/ast.h" +#include "util/params.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/fpa_decl_plugin.h" +#include "tactic/tactical.h" +#include "util/stats.h" -#include"collect_statistics_tactic.h" +#include "tactic/core/collect_statistics_tactic.h" class collect_statistics_tactic : public tactic { ast_manager & m; diff --git a/src/tactic/core/collect_statistics_tactic.h b/src/tactic/core/collect_statistics_tactic.h index 5734af3c7..a71ddc376 100644 --- a/src/tactic/core/collect_statistics_tactic.h +++ b/src/tactic/core/collect_statistics_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef COLLECT_STATISTICS_H_ #define COLLECT_STATISTICS_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/ctx_simplify_tactic.cpp b/src/tactic/core/ctx_simplify_tactic.cpp index 3e2790fe3..5bb54073d 100644 --- a/src/tactic/core/ctx_simplify_tactic.cpp +++ b/src/tactic/core/ctx_simplify_tactic.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"ctx_simplify_tactic.h" -#include"mk_simplified_app.h" -#include"cooperate.h" -#include"ast_ll_pp.h" -#include"ast_pp.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "ast/rewriter/mk_simplified_app.h" +#include "util/cooperate.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" class ctx_propagate_assertions : public ctx_simplify_tactic::simplifier { diff --git a/src/tactic/core/ctx_simplify_tactic.h b/src/tactic/core/ctx_simplify_tactic.h index d6ebf5cbd..9efa7e7db 100644 --- a/src/tactic/core/ctx_simplify_tactic.h +++ b/src/tactic/core/ctx_simplify_tactic.h @@ -19,8 +19,8 @@ Notes: #ifndef CTX_SIMPLIFY_TACTIC_H_ #define CTX_SIMPLIFY_TACTIC_H_ -#include"tactical.h" -#include"goal_num_occurs.h" +#include "tactic/tactical.h" +#include "tactic/goal_num_occurs.h" class ctx_simplify_tactic : public tactic { public: diff --git a/src/tactic/core/der_tactic.cpp b/src/tactic/core/der_tactic.cpp index ece1ec42f..5df009969 100644 --- a/src/tactic/core/der_tactic.cpp +++ b/src/tactic/core/der_tactic.cpp @@ -14,8 +14,8 @@ Author: Leonardo de Moura (leonardo) 2012-10-20 --*/ -#include"der.h" -#include"tactical.h" +#include "ast/rewriter/der.h" +#include "tactic/tactical.h" class der_tactic : public tactic { struct imp { diff --git a/src/tactic/core/distribute_forall_tactic.cpp b/src/tactic/core/distribute_forall_tactic.cpp index 5d525a836..3ee2697c4 100644 --- a/src/tactic/core/distribute_forall_tactic.cpp +++ b/src/tactic/core/distribute_forall_tactic.cpp @@ -14,9 +14,9 @@ Author: Leonardo de Moura (leonardo) 2012-02-18. --*/ -#include"tactical.h" -#include"rewriter_def.h" -#include"var_subst.h" +#include "tactic/tactical.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/var_subst.h" class distribute_forall_tactic : public tactic { diff --git a/src/tactic/core/distribute_forall_tactic.h b/src/tactic/core/distribute_forall_tactic.h index 6c781c7df..a58a53d4e 100644 --- a/src/tactic/core/distribute_forall_tactic.h +++ b/src/tactic/core/distribute_forall_tactic.h @@ -17,7 +17,7 @@ Author: #ifndef DISTRIBUTE_FORALL_TACTIC_H_ #define DISTRIBUTE_FORALL_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/elim_term_ite_tactic.cpp b/src/tactic/core/elim_term_ite_tactic.cpp index 6cc989d0f..91f1d9020 100644 --- a/src/tactic/core/elim_term_ite_tactic.cpp +++ b/src/tactic/core/elim_term_ite_tactic.cpp @@ -17,11 +17,11 @@ Author: Notes: --*/ -#include"tactical.h" -#include"defined_names.h" -#include"rewriter_def.h" -#include"filter_model_converter.h" -#include"cooperate.h" +#include "tactic/tactical.h" +#include "ast/normal_forms/defined_names.h" +#include "ast/rewriter/rewriter_def.h" +#include "tactic/filter_model_converter.h" +#include "util/cooperate.h" class elim_term_ite_tactic : public tactic { diff --git a/src/tactic/core/elim_term_ite_tactic.h b/src/tactic/core/elim_term_ite_tactic.h index 3a89edaa9..4a98947c9 100644 --- a/src/tactic/core/elim_term_ite_tactic.h +++ b/src/tactic/core/elim_term_ite_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef ELIM_TERM_ITE_TACTIC_H_ #define ELIM_TERM_ITE_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/elim_uncnstr_tactic.cpp b/src/tactic/core/elim_uncnstr_tactic.cpp index df3b9f0f5..73adabb6f 100644 --- a/src/tactic/core/elim_uncnstr_tactic.cpp +++ b/src/tactic/core/elim_uncnstr_tactic.cpp @@ -16,18 +16,18 @@ Author: Notes: --*/ -#include"tactical.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" -#include"rewriter_def.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"datatype_decl_plugin.h" -#include"collect_occs.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"ast_ll_pp.h" +#include "tactic/tactical.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "tactic/core/collect_occs.h" +#include "util/cooperate.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_ll_pp.h" class elim_uncnstr_tactic : public tactic { diff --git a/src/tactic/core/elim_uncnstr_tactic.h b/src/tactic/core/elim_uncnstr_tactic.h index 46bcdca16..19f9021ac 100644 --- a/src/tactic/core/elim_uncnstr_tactic.h +++ b/src/tactic/core/elim_uncnstr_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef ELIM_UNCNSTR_TACTIC_H_ #define ELIM_UNCNSTR_TACTIC_H_ -#include"params.h" +#include "util/params.h" class tactic; class ast_manager; diff --git a/src/tactic/core/nnf_tactic.cpp b/src/tactic/core/nnf_tactic.cpp index f9244f8e7..6b360e711 100644 --- a/src/tactic/core/nnf_tactic.cpp +++ b/src/tactic/core/nnf_tactic.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"nnf.h" -#include"tactical.h" -#include"filter_model_converter.h" +#include "ast/normal_forms/nnf.h" +#include "tactic/tactical.h" +#include "tactic/filter_model_converter.h" class nnf_tactic : public tactic { params_ref m_params; diff --git a/src/tactic/core/nnf_tactic.h b/src/tactic/core/nnf_tactic.h index b5363f830..2070db32e 100644 --- a/src/tactic/core/nnf_tactic.h +++ b/src/tactic/core/nnf_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef NNF_TACTIC_H_ #define NNF_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/occf_tactic.cpp b/src/tactic/core/occf_tactic.cpp index c080ee915..6d9d63971 100644 --- a/src/tactic/core/occf_tactic.cpp +++ b/src/tactic/core/occf_tactic.cpp @@ -21,10 +21,10 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"occf_tactic.h" -#include"filter_model_converter.h" -#include"cooperate.h" +#include "tactic/tactical.h" +#include "tactic/core/occf_tactic.h" +#include "tactic/filter_model_converter.h" +#include "util/cooperate.h" class occf_tactic : public tactic { struct imp { diff --git a/src/tactic/core/occf_tactic.h b/src/tactic/core/occf_tactic.h index f876f638f..80f8f6042 100644 --- a/src/tactic/core/occf_tactic.h +++ b/src/tactic/core/occf_tactic.h @@ -24,7 +24,7 @@ Revision History: #ifndef OCCF_TACTIC_H_ #define OCCF_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/pb_preprocess_tactic.cpp b/src/tactic/core/pb_preprocess_tactic.cpp index a7e381576..6a0d7205b 100644 --- a/src/tactic/core/pb_preprocess_tactic.cpp +++ b/src/tactic/core/pb_preprocess_tactic.cpp @@ -31,13 +31,13 @@ Notes: --*/ -#include "pb_preprocess_tactic.h" -#include "tactical.h" -#include "for_each_expr.h" -#include "pb_decl_plugin.h" -#include "th_rewriter.h" -#include "expr_substitution.h" -#include "ast_pp.h" +#include "tactic/core/pb_preprocess_tactic.h" +#include "tactic/tactical.h" +#include "ast/for_each_expr.h" +#include "ast/pb_decl_plugin.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/expr_substitution.h" +#include "ast/ast_pp.h" class pb_preproc_model_converter : public model_converter { ast_manager& m; diff --git a/src/tactic/core/pb_preprocess_tactic.h b/src/tactic/core/pb_preprocess_tactic.h index 8b70437a4..765fc1545 100644 --- a/src/tactic/core/pb_preprocess_tactic.h +++ b/src/tactic/core/pb_preprocess_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef PB_PREPROCESS_TACTIC_H_ #define PB_PREPROCESS_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/propagate_values_tactic.cpp b/src/tactic/core/propagate_values_tactic.cpp index 90beabf24..7baac0b99 100644 --- a/src/tactic/core/propagate_values_tactic.cpp +++ b/src/tactic/core/propagate_values_tactic.cpp @@ -17,12 +17,12 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"propagate_values_tactic.h" -#include"th_rewriter.h" -#include"ast_smt2_pp.h" -#include"expr_substitution.h" -#include"goal_shared_occs.h" +#include "tactic/tactical.h" +#include "tactic/core/propagate_values_tactic.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/ast_smt2_pp.h" +#include "ast/expr_substitution.h" +#include "tactic/goal_shared_occs.h" class propagate_values_tactic : public tactic { struct imp { diff --git a/src/tactic/core/propagate_values_tactic.h b/src/tactic/core/propagate_values_tactic.h index 2d1d311b2..635b0a36f 100644 --- a/src/tactic/core/propagate_values_tactic.h +++ b/src/tactic/core/propagate_values_tactic.h @@ -20,7 +20,7 @@ Revision History: #ifndef PROPAGATE_VALUES_TACTIC_H_ #define PROPAGATE_VALUES_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/reduce_args_tactic.cpp b/src/tactic/core/reduce_args_tactic.cpp index ec7353044..a4b9825cc 100644 --- a/src/tactic/core/reduce_args_tactic.cpp +++ b/src/tactic/core/reduce_args_tactic.cpp @@ -16,14 +16,14 @@ Author: Notes: --*/ -#include"tactical.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"has_free_vars.h" -#include"map.h" -#include"rewriter_def.h" -#include"extension_model_converter.h" -#include"filter_model_converter.h" +#include "tactic/tactical.h" +#include "util/cooperate.h" +#include "ast/ast_smt2_pp.h" +#include "ast/has_free_vars.h" +#include "util/map.h" +#include "ast/rewriter/rewriter_def.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" /** \brief Reduce the number of arguments in function applications. diff --git a/src/tactic/core/reduce_args_tactic.h b/src/tactic/core/reduce_args_tactic.h index c22e0c675..394d7d4ab 100644 --- a/src/tactic/core/reduce_args_tactic.h +++ b/src/tactic/core/reduce_args_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef REDUCE_ARGS_TACTIC_H_ #define REDUCE_ARGS_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/simplify_tactic.cpp b/src/tactic/core/simplify_tactic.cpp index be89d356a..9deff968e 100644 --- a/src/tactic/core/simplify_tactic.cpp +++ b/src/tactic/core/simplify_tactic.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"simplify_tactic.h" -#include"th_rewriter.h" -#include"ast_pp.h" +#include "tactic/core/simplify_tactic.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/ast_pp.h" struct simplify_tactic::imp { ast_manager & m_manager; diff --git a/src/tactic/core/simplify_tactic.h b/src/tactic/core/simplify_tactic.h index ec72404dd..1e8420c62 100644 --- a/src/tactic/core/simplify_tactic.h +++ b/src/tactic/core/simplify_tactic.h @@ -19,8 +19,8 @@ Notes: #ifndef SIMPLIFY_TACTIC_H_ #define SIMPLIFY_TACTIC_H_ -#include"tactic.h" -#include"tactical.h" +#include "tactic/tactic.h" +#include "tactic/tactical.h" class simplify_tactic : public tactic { struct imp; diff --git a/src/tactic/core/solve_eqs_tactic.cpp b/src/tactic/core/solve_eqs_tactic.cpp index f23d874a6..65d474182 100644 --- a/src/tactic/core/solve_eqs_tactic.cpp +++ b/src/tactic/core/solve_eqs_tactic.cpp @@ -16,13 +16,13 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"expr_replacer.h" -#include"extension_model_converter.h" -#include"occurs.h" -#include"cooperate.h" -#include"goal_shared_occs.h" -#include"ast_pp.h" +#include "tactic/tactical.h" +#include "ast/rewriter/expr_replacer.h" +#include "tactic/extension_model_converter.h" +#include "ast/occurs.h" +#include "util/cooperate.h" +#include "tactic/goal_shared_occs.h" +#include "ast/ast_pp.h" class solve_eqs_tactic : public tactic { struct imp { diff --git a/src/tactic/core/solve_eqs_tactic.h b/src/tactic/core/solve_eqs_tactic.h index 8d543da42..084942ed2 100644 --- a/src/tactic/core/solve_eqs_tactic.h +++ b/src/tactic/core/solve_eqs_tactic.h @@ -19,7 +19,7 @@ Revision History: #ifndef SOLVE_EQS_TACTIC_H_ #define SOLVE_EQS_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; class expr_replacer; diff --git a/src/tactic/core/split_clause_tactic.cpp b/src/tactic/core/split_clause_tactic.cpp index 5699aa178..7a2df81b5 100644 --- a/src/tactic/core/split_clause_tactic.cpp +++ b/src/tactic/core/split_clause_tactic.cpp @@ -17,8 +17,8 @@ Author: Notes: --*/ -#include"tactical.h" -#include"split_clause_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/split_clause_tactic.h" class split_clause_tactic : public tactic { bool m_largest_clause; diff --git a/src/tactic/core/split_clause_tactic.h b/src/tactic/core/split_clause_tactic.h index 34d1eb497..fcbdbf857 100644 --- a/src/tactic/core/split_clause_tactic.h +++ b/src/tactic/core/split_clause_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef SPLIT_CLAUSE_TACTIC_H_ #define SPLIT_CLAUSE_TACTIC_H_ -#include"params.h" +#include "util/params.h" class tactic; tactic * mk_split_clause_tactic(params_ref const & p = params_ref()); diff --git a/src/tactic/core/symmetry_reduce_tactic.cpp b/src/tactic/core/symmetry_reduce_tactic.cpp index 873dc55bc..8e87a6741 100644 --- a/src/tactic/core/symmetry_reduce_tactic.cpp +++ b/src/tactic/core/symmetry_reduce_tactic.cpp @@ -19,12 +19,12 @@ Notes: adaption of the algorithms proposed for veriT. --*/ -#include"tactical.h" -#include"for_each_expr.h" -#include"map.h" -#include"expr_replacer.h" -#include"rewriter_def.h" -#include"ast_pp.h" +#include "tactic/tactical.h" +#include "ast/for_each_expr.h" +#include "util/map.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" class symmetry_reduce_tactic : public tactic { class imp; diff --git a/src/tactic/core/symmetry_reduce_tactic.h b/src/tactic/core/symmetry_reduce_tactic.h index 552baa7f1..0e92b5e29 100644 --- a/src/tactic/core/symmetry_reduce_tactic.h +++ b/src/tactic/core/symmetry_reduce_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef SYMMETRY_REDUCE_TACTIC_H_ #define SYMMETRY_REDUCE_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/core/tseitin_cnf_tactic.cpp b/src/tactic/core/tseitin_cnf_tactic.cpp index 03e9ce7fa..dbfc748b0 100644 --- a/src/tactic/core/tseitin_cnf_tactic.cpp +++ b/src/tactic/core/tseitin_cnf_tactic.cpp @@ -49,12 +49,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"goal_shared_occs.h" -#include"filter_model_converter.h" -#include"bool_rewriter.h" -#include"simplify_tactic.h" -#include"cooperate.h" +#include "tactic/tactical.h" +#include "tactic/goal_shared_occs.h" +#include "tactic/filter_model_converter.h" +#include "ast/rewriter/bool_rewriter.h" +#include "tactic/core/simplify_tactic.h" +#include "util/cooperate.h" static void swap_if_gt(expr * & n1, expr * & n2) { if (n1->get_id() > n2->get_id()) diff --git a/src/tactic/core/tseitin_cnf_tactic.h b/src/tactic/core/tseitin_cnf_tactic.h index 76eeae283..5dd4f6c02 100644 --- a/src/tactic/core/tseitin_cnf_tactic.h +++ b/src/tactic/core/tseitin_cnf_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef TSEITIN_CNF_TACTIC_H_ #define TSEITIN_CNF_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/equiv_proof_converter.cpp b/src/tactic/equiv_proof_converter.cpp index 13b759f7e..8bec082d3 100644 --- a/src/tactic/equiv_proof_converter.cpp +++ b/src/tactic/equiv_proof_converter.cpp @@ -17,9 +17,9 @@ Revision History: --*/ -#include "equiv_proof_converter.h" -#include "ast_pp.h" -#include "scoped_proof.h" +#include "tactic/equiv_proof_converter.h" +#include "ast/ast_pp.h" +#include "ast/scoped_proof.h" void equiv_proof_converter::insert(expr* fml1, expr* fml2) { if (fml1 != fml2) { diff --git a/src/tactic/equiv_proof_converter.h b/src/tactic/equiv_proof_converter.h index 7571ae9d4..79f5142b2 100644 --- a/src/tactic/equiv_proof_converter.h +++ b/src/tactic/equiv_proof_converter.h @@ -24,7 +24,7 @@ Revision History: #ifndef EQUIV_PROOF_CONVERTER_H_ #define EQUIV_PROOF_CONVERTER_H_ -#include "replace_proof_converter.h" +#include "tactic/replace_proof_converter.h" class equiv_proof_converter : public proof_converter { ast_manager& m; diff --git a/src/tactic/extension_model_converter.cpp b/src/tactic/extension_model_converter.cpp index 18b5b6288..38f0100ee 100644 --- a/src/tactic/extension_model_converter.cpp +++ b/src/tactic/extension_model_converter.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"extension_model_converter.h" -#include"model_evaluator.h" -#include"ast_smt2_pp.h" -#include"model_v2_pp.h" -#include"ast_pp.h" +#include "tactic/extension_model_converter.h" +#include "model/model_evaluator.h" +#include "ast/ast_smt2_pp.h" +#include "model/model_v2_pp.h" +#include "ast/ast_pp.h" extension_model_converter::~extension_model_converter() { } diff --git a/src/tactic/extension_model_converter.h b/src/tactic/extension_model_converter.h index 46644eec2..dbd7a7e3b 100644 --- a/src/tactic/extension_model_converter.h +++ b/src/tactic/extension_model_converter.h @@ -20,8 +20,8 @@ Notes: #ifndef EXTENSION_MODEL_CONVERTER_H_ #define EXTENSION_MODEL_CONVERTER_H_ -#include"ast.h" -#include"model_converter.h" +#include "ast/ast.h" +#include "tactic/model_converter.h" class extension_model_converter : public model_converter { diff --git a/src/tactic/filter_model_converter.cpp b/src/tactic/filter_model_converter.cpp index 247f2e91d..46328186d 100644 --- a/src/tactic/filter_model_converter.cpp +++ b/src/tactic/filter_model_converter.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"filter_model_converter.h" -#include"model_v2_pp.h" +#include "tactic/filter_model_converter.h" +#include "model/model_v2_pp.h" filter_model_converter::~filter_model_converter() { } diff --git a/src/tactic/filter_model_converter.h b/src/tactic/filter_model_converter.h index 0b67a6c5a..b5d6b86f4 100644 --- a/src/tactic/filter_model_converter.h +++ b/src/tactic/filter_model_converter.h @@ -19,7 +19,7 @@ Notes: #ifndef FILTER_MODEL_CONVERTER_H_ #define FILTER_MODEL_CONVERTER_H_ -#include"model_converter.h" +#include "tactic/model_converter.h" class filter_model_converter : public model_converter { func_decl_ref_vector m_decls; diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 88224d2f2..8ebb3375d 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"ast_smt2_pp.h" -#include"fpa_rewriter.h" -#include"fpa2bv_model_converter.h" +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/fpa_rewriter.h" +#include "tactic/fpa/fpa2bv_model_converter.h" void fpa2bv_model_converter::display(std::ostream & out) { out << "(fpa2bv-model-converter"; diff --git a/src/tactic/fpa/fpa2bv_model_converter.h b/src/tactic/fpa/fpa2bv_model_converter.h index 1f482478b..465aaa1e4 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.h +++ b/src/tactic/fpa/fpa2bv_model_converter.h @@ -19,9 +19,9 @@ Notes: #ifndef FPA2BV_MODEL_CONVERTER_H_ #define FPA2BV_MODEL_CONVERTER_H_ -#include"fpa2bv_converter.h" -#include"model_converter.h" -#include"bv2fpa_converter.h" +#include "ast/fpa/fpa2bv_converter.h" +#include "tactic/model_converter.h" +#include "ast/fpa/bv2fpa_converter.h" class fpa2bv_model_converter : public model_converter { ast_manager & m; diff --git a/src/tactic/fpa/fpa2bv_tactic.cpp b/src/tactic/fpa/fpa2bv_tactic.cpp index d55a2e25c..6d90b46ea 100644 --- a/src/tactic/fpa/fpa2bv_tactic.cpp +++ b/src/tactic/fpa/fpa2bv_tactic.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"tactical.h" -#include"fpa2bv_rewriter.h" -#include"simplify_tactic.h" -#include"fpa2bv_tactic.h" -#include"fpa2bv_model_converter.h" +#include "tactic/tactical.h" +#include "ast/fpa/fpa2bv_rewriter.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/fpa/fpa2bv_tactic.h" +#include "tactic/fpa/fpa2bv_model_converter.h" class fpa2bv_tactic : public tactic { struct imp { diff --git a/src/tactic/fpa/fpa2bv_tactic.h b/src/tactic/fpa/fpa2bv_tactic.h index 633009d59..e7e472d8d 100644 --- a/src/tactic/fpa/fpa2bv_tactic.h +++ b/src/tactic/fpa/fpa2bv_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef FPA2BV_TACTIC_H_ #define FPA2BV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/fpa/qffp_tactic.cpp b/src/tactic/fpa/qffp_tactic.cpp index f839110f0..cdc363453 100644 --- a/src/tactic/fpa/qffp_tactic.cpp +++ b/src/tactic/fpa/qffp_tactic.cpp @@ -16,18 +16,18 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"bit_blaster_tactic.h" -#include"sat_tactic.h" -#include"fpa2bv_tactic.h" -#include"smt_tactic.h" -#include"propagate_values_tactic.h" -#include"ackermannize_bv_tactic.h" -#include"probe_arith.h" -#include"qfnra_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/bv/bit_blaster_tactic.h" +#include "sat/tactic/sat_tactic.h" +#include "tactic/fpa/fpa2bv_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "ackermannization/ackermannize_bv_tactic.h" +#include "tactic/arith/probe_arith.h" +#include "tactic/smtlogics/qfnra_tactic.h" -#include"qffp_tactic.h" +#include "tactic/fpa/qffp_tactic.h" struct is_non_fp_qfnra_predicate { diff --git a/src/tactic/fpa/qffp_tactic.h b/src/tactic/fpa/qffp_tactic.h index 42e4f94e7..f696ba2d6 100644 --- a/src/tactic/fpa/qffp_tactic.h +++ b/src/tactic/fpa/qffp_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef QFFP_TACTIC_H_ #define QFFP_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/goal.cpp b/src/tactic/goal.cpp index a3cac9e2e..ea8d14bd0 100644 --- a/src/tactic/goal.cpp +++ b/src/tactic/goal.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"goal.h" -#include"ast_ll_pp.h" -#include"ast_smt2_pp.h" -#include"for_each_expr.h" -#include"well_sorted.h" +#include "tactic/goal.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" +#include "ast/for_each_expr.h" +#include "ast/well_sorted.h" goal::precision goal::mk_union(precision p1, precision p2) { if (p1 == PRECISE) return p2; diff --git a/src/tactic/goal.h b/src/tactic/goal.h index ea02dfa17..c9de9c037 100644 --- a/src/tactic/goal.h +++ b/src/tactic/goal.h @@ -28,13 +28,13 @@ Revision History: #ifndef GOAL_H_ #define GOAL_H_ -#include"ast.h" -#include"ast_translation.h" -#include"ast_printer.h" -#include"for_each_expr.h" -#include"ref.h" -#include"ref_vector.h" -#include"ref_buffer.h" +#include "ast/ast.h" +#include "ast/ast_translation.h" +#include "ast/ast_printer.h" +#include "ast/for_each_expr.h" +#include "util/ref.h" +#include "util/ref_vector.h" +#include "util/ref_buffer.h" class goal { public: diff --git a/src/tactic/goal_num_occurs.cpp b/src/tactic/goal_num_occurs.cpp index 6c94e307c..4c7006d75 100644 --- a/src/tactic/goal_num_occurs.cpp +++ b/src/tactic/goal_num_occurs.cpp @@ -15,8 +15,8 @@ Author: Revision History: --*/ -#include"goal_num_occurs.h" -#include"goal.h" +#include "tactic/goal_num_occurs.h" +#include "tactic/goal.h" void goal_num_occurs::operator()(goal const & g) { expr_fast_mark1 visited; diff --git a/src/tactic/goal_num_occurs.h b/src/tactic/goal_num_occurs.h index e5f97f8cd..14c92e468 100644 --- a/src/tactic/goal_num_occurs.h +++ b/src/tactic/goal_num_occurs.h @@ -18,7 +18,7 @@ Revision History: #ifndef GOAL_NUM_OCCURS_H_ #define GOAL_NUM_OCCURS_H_ -#include"num_occurs.h" +#include "ast/num_occurs.h" class goal; diff --git a/src/tactic/goal_shared_occs.cpp b/src/tactic/goal_shared_occs.cpp index 48c79f739..0048e642a 100644 --- a/src/tactic/goal_shared_occs.cpp +++ b/src/tactic/goal_shared_occs.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"goal_shared_occs.h" +#include "tactic/goal_shared_occs.h" void goal_shared_occs::operator()(goal const & g) { m_occs.reset(); diff --git a/src/tactic/goal_shared_occs.h b/src/tactic/goal_shared_occs.h index 902d1d027..8280cef43 100644 --- a/src/tactic/goal_shared_occs.h +++ b/src/tactic/goal_shared_occs.h @@ -19,8 +19,8 @@ Revision History: #ifndef GOAL_SHARED_OCCS_H_ #define GOAL_SHARED_OCCS_H_ -#include"goal.h" -#include"shared_occs.h" +#include "tactic/goal.h" +#include "ast/shared_occs.h" /** \brief Functor for computing the set of shared occurrences in a goal. diff --git a/src/tactic/goal_util.cpp b/src/tactic/goal_util.cpp index d0dfc11f6..965860cf9 100644 --- a/src/tactic/goal_util.cpp +++ b/src/tactic/goal_util.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"goal_util.h" -#include"goal.h" +#include "tactic/goal_util.h" +#include "tactic/goal.h" struct has_term_ite_functor { struct found {}; diff --git a/src/tactic/horn_subsume_model_converter.cpp b/src/tactic/horn_subsume_model_converter.cpp index 25da094fa..cb56f9b7b 100644 --- a/src/tactic/horn_subsume_model_converter.cpp +++ b/src/tactic/horn_subsume_model_converter.cpp @@ -18,14 +18,14 @@ Revision History: --*/ -#include "horn_subsume_model_converter.h" -#include "var_subst.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" -#include "bool_rewriter.h" -#include "th_rewriter.h" -#include "for_each_expr.h" -#include "well_sorted.h" +#include "tactic/horn_subsume_model_converter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/for_each_expr.h" +#include "ast/well_sorted.h" void horn_subsume_model_converter::insert(app* head, expr* body) { m_delay_head.push_back(head); diff --git a/src/tactic/horn_subsume_model_converter.h b/src/tactic/horn_subsume_model_converter.h index d56802349..1c1ae9feb 100644 --- a/src/tactic/horn_subsume_model_converter.h +++ b/src/tactic/horn_subsume_model_converter.h @@ -35,8 +35,8 @@ Subsumption transformation (remove Horn clause): #ifndef HORN_SUBSUME_MODEL_CONVERTER_H_ #define HORN_SUBSUME_MODEL_CONVERTER_H_ -#include "model_converter.h" -#include "th_rewriter.h" +#include "tactic/model_converter.h" +#include "ast/rewriter/th_rewriter.h" class horn_subsume_model_converter : public model_converter { ast_manager& m; diff --git a/src/tactic/model_converter.cpp b/src/tactic/model_converter.cpp index 6f6dd3da1..4269946a1 100644 --- a/src/tactic/model_converter.cpp +++ b/src/tactic/model_converter.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"model_converter.h" -#include"model_v2_pp.h" +#include "tactic/model_converter.h" +#include "model/model_v2_pp.h" class concat_model_converter : public concat_converter { public: diff --git a/src/tactic/model_converter.h b/src/tactic/model_converter.h index e2bc3cf83..5e549344e 100644 --- a/src/tactic/model_converter.h +++ b/src/tactic/model_converter.h @@ -19,9 +19,9 @@ Notes: #ifndef MODEL_CONVERTER_H_ #define MODEL_CONVERTER_H_ -#include"model.h" -#include"converter.h" -#include"ref.h" +#include "model/model.h" +#include "tactic/converter.h" +#include "util/ref.h" class labels_vec : public svector {}; diff --git a/src/tactic/nlsat_smt/nl_purify_tactic.cpp b/src/tactic/nlsat_smt/nl_purify_tactic.cpp index 46b5a51b0..c99ea545a 100644 --- a/src/tactic/nlsat_smt/nl_purify_tactic.cpp +++ b/src/tactic/nlsat_smt/nl_purify_tactic.cpp @@ -44,22 +44,22 @@ Author: Revision History: --*/ -#include "tactical.h" -#include "nl_purify_tactic.h" -#include "smt_tactic.h" -#include "rewriter.h" -#include "nlsat_tactic.h" -#include "filter_model_converter.h" -#include "obj_pair_hashtable.h" -#include "rewriter_def.h" -#include "ast_pp.h" -#include "trace.h" -#include "smt_solver.h" -#include "solver.h" -#include "model_smt2_pp.h" -#include "expr_safe_replace.h" -#include "ast_util.h" -#include "solver2tactic.h" +#include "tactic/tactical.h" +#include "tactic/nlsat_smt/nl_purify_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "ast/rewriter/rewriter.h" +#include "nlsat/tactic/nlsat_tactic.h" +#include "tactic/filter_model_converter.h" +#include "util/obj_pair_hashtable.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/ast_pp.h" +#include "util/trace.h" +#include "smt/smt_solver.h" +#include "solver/solver.h" +#include "model/model_smt2_pp.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/ast_util.h" +#include "solver/solver2tactic.h" class nl_purify_tactic : public tactic { diff --git a/src/tactic/nlsat_smt/nl_purify_tactic.h b/src/tactic/nlsat_smt/nl_purify_tactic.h index 87e37b4ad..85d033921 100644 --- a/src/tactic/nlsat_smt/nl_purify_tactic.h +++ b/src/tactic/nlsat_smt/nl_purify_tactic.h @@ -21,7 +21,7 @@ Revision History: #ifndef NL_PURIFY_TACTIC_H_ #define NL_PURIFY_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/portfolio/bounded_int2bv_solver.cpp b/src/tactic/portfolio/bounded_int2bv_solver.cpp index e293ade17..2f66d7a53 100644 --- a/src/tactic/portfolio/bounded_int2bv_solver.cpp +++ b/src/tactic/portfolio/bounded_int2bv_solver.cpp @@ -17,19 +17,19 @@ Notes: --*/ -#include "bounded_int2bv_solver.h" -#include "solver_na2as.h" -#include "tactic.h" -#include "pb2bv_rewriter.h" -#include "filter_model_converter.h" -#include "extension_model_converter.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" -#include "bound_manager.h" -#include "bv2int_rewriter.h" -#include "expr_safe_replace.h" -#include "bv_decl_plugin.h" -#include "arith_decl_plugin.h" +#include "tactic/portfolio/bounded_int2bv_solver.h" +#include "solver/solver_na2as.h" +#include "tactic/tactic.h" +#include "ast/rewriter/pb2bv_rewriter.h" +#include "tactic/filter_model_converter.h" +#include "tactic/extension_model_converter.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" +#include "tactic/arith/bound_manager.h" +#include "tactic/arith/bv2int_rewriter.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/bv_decl_plugin.h" +#include "ast/arith_decl_plugin.h" class bounded_int2bv_solver : public solver_na2as { ast_manager& m; diff --git a/src/tactic/portfolio/bounded_int2bv_solver.h b/src/tactic/portfolio/bounded_int2bv_solver.h index 5fcf2cd65..1d048d54e 100644 --- a/src/tactic/portfolio/bounded_int2bv_solver.h +++ b/src/tactic/portfolio/bounded_int2bv_solver.h @@ -19,8 +19,8 @@ Notes: #ifndef BOUNDED_INT2BV_SOLVER_H_ #define BOUNDED_INT2BV_SOLVER_H_ -#include"ast.h" -#include"params.h" +#include "ast/ast.h" +#include "util/params.h" class solver; diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 4f5eb5ed0..420cb961a 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -16,21 +16,21 @@ Author: Notes: --*/ -#include"default_tactic.h" -#include"simplify_tactic.h" -#include"qfbv_tactic.h" -#include"smt_tactic.h" -#include"qflia_tactic.h" -#include"qflra_tactic.h" -#include"qfnia_tactic.h" -#include"qfnra_tactic.h" -#include"nra_tactic.h" -#include"probe_arith.h" -#include"quant_tactics.h" -#include"qffp_tactic.h" -#include"qfaufbv_tactic.h" -#include"qfauflia_tactic.h" -#include"qfufnra_tactic.h" +#include "tactic/portfolio/default_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/smtlogics/qfbv_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/smtlogics/qflia_tactic.h" +#include "tactic/smtlogics/qflra_tactic.h" +#include "tactic/smtlogics/qfnia_tactic.h" +#include "tactic/smtlogics/qfnra_tactic.h" +#include "tactic/smtlogics/nra_tactic.h" +#include "tactic/arith/probe_arith.h" +#include "tactic/smtlogics/quant_tactics.h" +#include "tactic/fpa/qffp_tactic.h" +#include "tactic/smtlogics/qfaufbv_tactic.h" +#include "tactic/smtlogics/qfauflia_tactic.h" +#include "tactic/smtlogics/qfufnra_tactic.h" tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), diff --git a/src/tactic/portfolio/default_tactic.h b/src/tactic/portfolio/default_tactic.h index 2f40fa145..8992cfee3 100644 --- a/src/tactic/portfolio/default_tactic.h +++ b/src/tactic/portfolio/default_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef DEFAULT_TACTIC_H_ #define DEFAULT_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/portfolio/enum2bv_solver.cpp b/src/tactic/portfolio/enum2bv_solver.cpp index 8c9ff122d..36a178c41 100644 --- a/src/tactic/portfolio/enum2bv_solver.cpp +++ b/src/tactic/portfolio/enum2bv_solver.cpp @@ -20,16 +20,16 @@ Notes: --*/ -#include "solver_na2as.h" -#include "tactic.h" -#include "bv_decl_plugin.h" -#include "datatype_decl_plugin.h" -#include "enum2bv_rewriter.h" -#include "extension_model_converter.h" -#include "filter_model_converter.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" -#include "enum2bv_solver.h" +#include "solver/solver_na2as.h" +#include "tactic/tactic.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/rewriter/enum2bv_rewriter.h" +#include "tactic/extension_model_converter.h" +#include "tactic/filter_model_converter.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" +#include "tactic/portfolio/enum2bv_solver.h" class enum2bv_solver : public solver_na2as { ast_manager& m; diff --git a/src/tactic/portfolio/enum2bv_solver.h b/src/tactic/portfolio/enum2bv_solver.h index b113c6747..08f753cc5 100644 --- a/src/tactic/portfolio/enum2bv_solver.h +++ b/src/tactic/portfolio/enum2bv_solver.h @@ -19,8 +19,8 @@ Notes: #ifndef ENUM2BV_SOLVER_H_ #define ENUM2BV_SOLVER_H_ -#include"ast.h" -#include"params.h" +#include "ast/ast.h" +#include "util/params.h" class solver; diff --git a/src/tactic/portfolio/fd_solver.cpp b/src/tactic/portfolio/fd_solver.cpp index a534337bc..b29fb20c1 100644 --- a/src/tactic/portfolio/fd_solver.cpp +++ b/src/tactic/portfolio/fd_solver.cpp @@ -17,12 +17,12 @@ Notes: --*/ -#include "fd_solver.h" -#include "tactic.h" -#include "inc_sat_solver.h" -#include "enum2bv_solver.h" -#include "pb2bv_solver.h" -#include "bounded_int2bv_solver.h" +#include "tactic/portfolio/fd_solver.h" +#include "tactic/tactic.h" +#include "sat/sat_solver/inc_sat_solver.h" +#include "tactic/portfolio/enum2bv_solver.h" +#include "tactic/portfolio/pb2bv_solver.h" +#include "tactic/portfolio/bounded_int2bv_solver.h" solver * mk_fd_solver(ast_manager & m, params_ref const & p) { solver* s = mk_inc_sat_solver(m, p); diff --git a/src/tactic/portfolio/fd_solver.h b/src/tactic/portfolio/fd_solver.h index 51abb087f..53cae16d1 100644 --- a/src/tactic/portfolio/fd_solver.h +++ b/src/tactic/portfolio/fd_solver.h @@ -19,8 +19,8 @@ Notes: #ifndef FD_SOLVER_H_ #define FD_SOLVER_H_ -#include"ast.h" -#include"params.h" +#include "ast/ast.h" +#include "util/params.h" class solver; diff --git a/src/tactic/portfolio/pb2bv_solver.cpp b/src/tactic/portfolio/pb2bv_solver.cpp index 090ea9f76..81cc43685 100644 --- a/src/tactic/portfolio/pb2bv_solver.cpp +++ b/src/tactic/portfolio/pb2bv_solver.cpp @@ -16,13 +16,13 @@ Notes: --*/ -#include "pb2bv_solver.h" -#include "solver_na2as.h" -#include "tactic.h" -#include "pb2bv_rewriter.h" -#include "filter_model_converter.h" -#include "ast_pp.h" -#include "model_smt2_pp.h" +#include "tactic/portfolio/pb2bv_solver.h" +#include "solver/solver_na2as.h" +#include "tactic/tactic.h" +#include "ast/rewriter/pb2bv_rewriter.h" +#include "tactic/filter_model_converter.h" +#include "ast/ast_pp.h" +#include "model/model_smt2_pp.h" class pb2bv_solver : public solver_na2as { ast_manager& m; diff --git a/src/tactic/portfolio/pb2bv_solver.h b/src/tactic/portfolio/pb2bv_solver.h index e861e769b..ea53d8d89 100644 --- a/src/tactic/portfolio/pb2bv_solver.h +++ b/src/tactic/portfolio/pb2bv_solver.h @@ -19,8 +19,8 @@ Notes: #ifndef PB2BV_SOLVER_H_ #define PB2BV_SOLVER_H_ -#include"ast.h" -#include"params.h" +#include "ast/ast.h" +#include "util/params.h" class solver; diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index a4a579ddd..fe1cf5260 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -17,30 +17,30 @@ Author: Notes: --*/ -#include"cmd_context.h" -#include"combined_solver.h" -#include"tactic2solver.h" -#include"qfbv_tactic.h" -#include"qflia_tactic.h" -#include"qfnia_tactic.h" -#include"qfnra_tactic.h" -#include"qfuf_tactic.h" -#include"qflra_tactic.h" -#include"quant_tactics.h" -#include"qfauflia_tactic.h" -#include"qfaufbv_tactic.h" -#include"qfufbv_tactic.h" -#include"qfidl_tactic.h" -#include"default_tactic.h" -#include"ufbv_tactic.h" -#include"qffp_tactic.h" -#include"qfufnra_tactic.h" -#include"horn_tactic.h" -#include"smt_solver.h" -#include"inc_sat_solver.h" -#include"fd_solver.h" -#include"bv_rewriter.h" -#include"solver2tactic.h" +#include "cmd_context/cmd_context.h" +#include "solver/combined_solver.h" +#include "solver/tactic2solver.h" +#include "tactic/smtlogics/qfbv_tactic.h" +#include "tactic/smtlogics/qflia_tactic.h" +#include "tactic/smtlogics/qfnia_tactic.h" +#include "tactic/smtlogics/qfnra_tactic.h" +#include "tactic/smtlogics/qfuf_tactic.h" +#include "tactic/smtlogics/qflra_tactic.h" +#include "tactic/smtlogics/quant_tactics.h" +#include "tactic/smtlogics/qfauflia_tactic.h" +#include "tactic/smtlogics/qfaufbv_tactic.h" +#include "tactic/smtlogics/qfufbv_tactic.h" +#include "tactic/smtlogics/qfidl_tactic.h" +#include "tactic/portfolio/default_tactic.h" +#include "tactic/ufbv/ufbv_tactic.h" +#include "tactic/fpa/qffp_tactic.h" +#include "tactic/smtlogics/qfufnra_tactic.h" +#include "muz/fp/horn_tactic.h" +#include "smt/smt_solver.h" +#include "sat/sat_solver/inc_sat_solver.h" +#include "tactic/portfolio/fd_solver.h" +#include "ast/rewriter/bv_rewriter.h" +#include "solver/solver2tactic.h" tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) { diff --git a/src/tactic/probe.cpp b/src/tactic/probe.cpp index 677438cdf..072b866b1 100644 --- a/src/tactic/probe.cpp +++ b/src/tactic/probe.cpp @@ -19,11 +19,11 @@ Author: Revision History: --*/ -#include"probe.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"goal_util.h" -#include"bv_rewriter.h" +#include "tactic/probe.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "tactic/goal_util.h" +#include "ast/rewriter/bv_rewriter.h" class memory_probe : public probe { public: diff --git a/src/tactic/probe.h b/src/tactic/probe.h index 3f7229d36..294a6cbd0 100644 --- a/src/tactic/probe.h +++ b/src/tactic/probe.h @@ -24,7 +24,7 @@ Revision History: #ifndef PROBE_H_ #define PROBE_H_ -#include"goal.h" +#include "tactic/goal.h" class probe { public: diff --git a/src/tactic/proof_converter.cpp b/src/tactic/proof_converter.cpp index fa58d5208..095488415 100644 --- a/src/tactic/proof_converter.cpp +++ b/src/tactic/proof_converter.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"proof_converter.h" -#include"ast_smt2_pp.h" +#include "tactic/proof_converter.h" +#include "ast/ast_smt2_pp.h" class concat_proof_converter : public concat_converter { public: diff --git a/src/tactic/proof_converter.h b/src/tactic/proof_converter.h index 44928e046..e925436d2 100644 --- a/src/tactic/proof_converter.h +++ b/src/tactic/proof_converter.h @@ -19,9 +19,9 @@ Notes: #ifndef PROOF_CONVERTER_H_ #define PROOF_CONVERTER_H_ -#include"ast.h" -#include"converter.h" -#include"ref.h" +#include "ast/ast.h" +#include "tactic/converter.h" +#include "util/ref.h" class proof_converter : public converter { public: diff --git a/src/tactic/replace_proof_converter.cpp b/src/tactic/replace_proof_converter.cpp index 45ec6fc2e..98f28bb1b 100644 --- a/src/tactic/replace_proof_converter.cpp +++ b/src/tactic/replace_proof_converter.cpp @@ -17,10 +17,10 @@ Revision History: --*/ -#include "replace_proof_converter.h" -#include "expr_functors.h" -#include "ast_pp.h" -#include "for_each_expr.h" +#include "tactic/replace_proof_converter.h" +#include "ast/expr_functors.h" +#include "ast/ast_pp.h" +#include "ast/for_each_expr.h" /** \brief Replace expressions by other expressions. diff --git a/src/tactic/replace_proof_converter.h b/src/tactic/replace_proof_converter.h index 96f25aab4..b768a18a0 100644 --- a/src/tactic/replace_proof_converter.h +++ b/src/tactic/replace_proof_converter.h @@ -23,7 +23,7 @@ Revision History: #ifndef REPLACE_PROOF_CONVERTER_H_ #define REPLACE_PROOF_CONVERTER_H_ -#include "proof_converter.h" +#include "tactic/proof_converter.h" class replace_proof_converter : public proof_converter { ast_manager& m; diff --git a/src/tactic/sine_filter.cpp b/src/tactic/sine_filter.cpp index f2d6a9653..ba35bac84 100644 --- a/src/tactic/sine_filter.cpp +++ b/src/tactic/sine_filter.cpp @@ -16,17 +16,17 @@ Author: Revision History: --*/ -#include "sine_filter.h" -#include "tactical.h" -#include "filter_model_converter.h" -#include "datatype_decl_plugin.h" -#include "rewriter_def.h" -#include "filter_model_converter.h" -#include "extension_model_converter.h" -#include "var_subst.h" -#include "ast_util.h" -#include "obj_pair_hashtable.h" -#include "ast_pp.h" +#include "tactic/sine_filter.h" +#include "tactic/tactical.h" +#include "tactic/filter_model_converter.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/rewriter/rewriter_def.h" +#include "tactic/filter_model_converter.h" +#include "tactic/extension_model_converter.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_util.h" +#include "util/obj_pair_hashtable.h" +#include "ast/ast_pp.h" class sine_tactic : public tactic { diff --git a/src/tactic/sine_filter.h b/src/tactic/sine_filter.h index 769ef474f..72964219e 100644 --- a/src/tactic/sine_filter.h +++ b/src/tactic/sine_filter.h @@ -19,7 +19,7 @@ Revision History: #ifndef SINE_TACTIC_H_ #define SINE_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/sls/bvsls_opt_engine.cpp b/src/tactic/sls/bvsls_opt_engine.cpp index 96fad9a5a..e8547fdfd 100644 --- a/src/tactic/sls/bvsls_opt_engine.cpp +++ b/src/tactic/sls/bvsls_opt_engine.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include "nnf.h" -#include "bvsls_opt_engine.h" +#include "ast/normal_forms/nnf.h" +#include "tactic/sls/bvsls_opt_engine.h" bvsls_opt_engine::bvsls_opt_engine(ast_manager & m, params_ref const & p) : sls_engine(m, p), diff --git a/src/tactic/sls/bvsls_opt_engine.h b/src/tactic/sls/bvsls_opt_engine.h index 8ea666ed0..67d9a5d02 100644 --- a/src/tactic/sls/bvsls_opt_engine.h +++ b/src/tactic/sls/bvsls_opt_engine.h @@ -19,7 +19,7 @@ Notes: #ifndef BVSLS_OPT_ENGINE_H_ #define BVSLS_OPT_ENGINE_H_ -#include "sls_engine.h" +#include "tactic/sls/sls_engine.h" class bvsls_opt_engine : public sls_engine { sls_tracker & m_hard_tracker; diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 4418808dd..b89a05231 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -18,17 +18,17 @@ Notes: --*/ #include // Need DBL_MAX -#include"map.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"var_subst.h" -#include"model_pp.h" -#include"tactic.h" -#include"cooperate.h" -#include"luby.h" +#include "util/map.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/var_subst.h" +#include "model/model_pp.h" +#include "tactic/tactic.h" +#include "util/cooperate.h" +#include "util/luby.h" #include"sls_params.hpp" -#include"sls_engine.h" +#include "tactic/sls/sls_engine.h" sls_engine::sls_engine(ast_manager & m, params_ref const & p) : diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index ccd4f5b5a..0c4fb4d39 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -19,14 +19,14 @@ Notes: #ifndef SLS_ENGINE_H_ #define SLS_ENGINE_H_ -#include"stopwatch.h" -#include"lbool.h" -#include"model_converter.h" -#include"goal.h" +#include "util/stopwatch.h" +#include "util/lbool.h" +#include "tactic/model_converter.h" +#include "tactic/goal.h" -#include"sls_tracker.h" -#include"sls_evaluator.h" -#include"statistics.h" +#include "tactic/sls/sls_tracker.h" +#include "tactic/sls/sls_evaluator.h" +#include "util/statistics.h" class sls_engine { public: diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 59b9fd7a5..4e006d219 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -20,10 +20,10 @@ Notes: #ifndef SLS_EVALUATOR_H_ #define SLS_EVALUATOR_H_ -#include"model_evaluator.h" +#include "model/model_evaluator.h" -#include"sls_powers.h" -#include"sls_tracker.h" +#include "tactic/sls/sls_powers.h" +#include "tactic/sls/sls_tracker.h" class sls_evaluator { ast_manager & m_manager; diff --git a/src/tactic/sls/sls_powers.h b/src/tactic/sls/sls_powers.h index b632e7100..81e9540a0 100644 --- a/src/tactic/sls/sls_powers.h +++ b/src/tactic/sls/sls_powers.h @@ -20,7 +20,7 @@ Notes: #ifndef SLS_POWERS_H_ #define SLS_POWERS_H_ -#include"mpz.h" +#include "util/mpz.h" class powers : public u_map { unsynch_mpz_manager & m; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index f4ef300e4..2bbef288e 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,19 +16,19 @@ Author: Notes: --*/ -#include"nnf.h" -#include"solve_eqs_tactic.h" -#include"bv_size_reduction_tactic.h" -#include"max_bv_sharing_tactic.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"ctx_simplify_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"nnf_tactic.h" -#include"stopwatch.h" -#include"sls_tactic.h" +#include "ast/normal_forms/nnf.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/bv/bv_size_reduction_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "tactic/core/nnf_tactic.h" +#include "util/stopwatch.h" +#include "tactic/sls/sls_tactic.h" #include"sls_params.hpp" -#include"sls_engine.h" +#include "tactic/sls/sls_engine.h" class sls_tactic : public tactic { ast_manager & m; diff --git a/src/tactic/sls/sls_tactic.h b/src/tactic/sls/sls_tactic.h index ba415d547..ab79bfc0f 100644 --- a/src/tactic/sls/sls_tactic.h +++ b/src/tactic/sls/sls_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef SLS_TACTIC_H_ #define SLS_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index dfdbd4685..d5ce8ee3c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -21,13 +21,13 @@ Notes: #define SLS_TRACKER_H_ #include -#include"for_each_expr.h" -#include"ast_smt2_pp.h" -#include"bv_decl_plugin.h" -#include"model.h" +#include "ast/for_each_expr.h" +#include "ast/ast_smt2_pp.h" +#include "ast/bv_decl_plugin.h" +#include "model/model.h" #include"sls_params.hpp" -#include"sls_powers.h" +#include "tactic/sls/sls_powers.h" class sls_tracker { ast_manager & m_manager; diff --git a/src/tactic/smtlogics/nra_tactic.cpp b/src/tactic/smtlogics/nra_tactic.cpp index 063e0775a..381bc4bb6 100644 --- a/src/tactic/smtlogics/nra_tactic.cpp +++ b/src/tactic/smtlogics/nra_tactic.cpp @@ -16,16 +16,16 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"smt_tactic.h" -#include"nnf_tactic.h" -#include"qe_tactic.h" -#include"nlqsat.h" -#include"qfnra_nlsat_tactic.h" -#include"qe_lite.h" -#include"probe_arith.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/core/nnf_tactic.h" +#include "qe/qe_tactic.h" +#include "qe/nlqsat.h" +#include "nlsat/tactic/qfnra_nlsat_tactic.h" +#include "qe/qe_lite.h" +#include "tactic/arith/probe_arith.h" tactic * mk_nra_tactic(ast_manager & m, params_ref const& p) { params_ref p1 = p; diff --git a/src/tactic/smtlogics/qfaufbv_tactic.cpp b/src/tactic/smtlogics/qfaufbv_tactic.cpp index cb14fa778..601f872aa 100644 --- a/src/tactic/smtlogics/qfaufbv_tactic.cpp +++ b/src/tactic/smtlogics/qfaufbv_tactic.cpp @@ -16,16 +16,16 @@ Author: Notes: --*/ -#include"solve_eqs_tactic.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"bit_blaster_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"max_bv_sharing_tactic.h" -#include"bv_size_reduction_tactic.h" -#include"ctx_simplify_tactic.h" -#include"sat_tactic.h" -#include"smt_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/bv/bit_blaster_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "tactic/bv/bv_size_reduction_tactic.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "sat/tactic/sat_tactic.h" +#include "smt/tactic/smt_tactic.h" tactic * mk_qfaufbv_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; diff --git a/src/tactic/smtlogics/qfaufbv_tactic.h b/src/tactic/smtlogics/qfaufbv_tactic.h index 1e4a7419f..06b046bd3 100644 --- a/src/tactic/smtlogics/qfaufbv_tactic.h +++ b/src/tactic/smtlogics/qfaufbv_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFAUFBV_TACTIC_H_ #define QFAUFBV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfauflia_tactic.cpp b/src/tactic/smtlogics/qfauflia_tactic.cpp index 89f96d354..4a0e9eb34 100644 --- a/src/tactic/smtlogics/qfauflia_tactic.cpp +++ b/src/tactic/smtlogics/qfauflia_tactic.cpp @@ -16,13 +16,13 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"propagate_ineqs_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"smt_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/arith/propagate_ineqs_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "smt/tactic/smt_tactic.h" tactic * mk_qfauflia_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; diff --git a/src/tactic/smtlogics/qfauflia_tactic.h b/src/tactic/smtlogics/qfauflia_tactic.h index fbf19fec0..f1b3c74e0 100644 --- a/src/tactic/smtlogics/qfauflia_tactic.h +++ b/src/tactic/smtlogics/qfauflia_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFAUFLIA_TACTIC_H_ #define QFAUFLIA_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfbv_tactic.cpp b/src/tactic/smtlogics/qfbv_tactic.cpp index ca6390c9c..b69069864 100644 --- a/src/tactic/smtlogics/qfbv_tactic.cpp +++ b/src/tactic/smtlogics/qfbv_tactic.cpp @@ -16,19 +16,19 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"smt_tactic.h" -#include"bit_blaster_tactic.h" -#include"bv1_blaster_tactic.h" -#include"max_bv_sharing_tactic.h" -#include"bv_size_reduction_tactic.h" -#include"aig_tactic.h" -#include"sat_tactic.h" -#include"ackermannize_bv_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/bv/bit_blaster_tactic.h" +#include "tactic/bv/bv1_blaster_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "tactic/bv/bv_size_reduction_tactic.h" +#include "tactic/aig/aig_tactic.h" +#include "sat/tactic/sat_tactic.h" +#include "ackermannization/ackermannize_bv_tactic.h" #define MEMLIMIT 300 diff --git a/src/tactic/smtlogics/qfbv_tactic.h b/src/tactic/smtlogics/qfbv_tactic.h index 4de623e0f..52f07f2a6 100644 --- a/src/tactic/smtlogics/qfbv_tactic.h +++ b/src/tactic/smtlogics/qfbv_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFBV_TACTIC_H_ #define QFBV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfidl_tactic.cpp b/src/tactic/smtlogics/qfidl_tactic.cpp index de05797e8..a34a25e67 100644 --- a/src/tactic/smtlogics/qfidl_tactic.cpp +++ b/src/tactic/smtlogics/qfidl_tactic.cpp @@ -16,22 +16,22 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"propagate_ineqs_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"normalize_bounds_tactic.h" -#include"fix_dl_var_tactic.h" -#include"smt_tactic.h" -#include"lia2pb_tactic.h" -#include"pb2bv_tactic.h" -#include"diff_neq_tactic.h" -#include"bit_blaster_tactic.h" -#include"max_bv_sharing_tactic.h" -#include"aig_tactic.h" -#include"sat_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/arith/propagate_ineqs_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "tactic/arith/normalize_bounds_tactic.h" +#include "tactic/arith/fix_dl_var_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/arith/lia2pb_tactic.h" +#include "tactic/arith/pb2bv_tactic.h" +#include "tactic/arith/diff_neq_tactic.h" +#include "tactic/bv/bit_blaster_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "tactic/aig/aig_tactic.h" +#include "sat/tactic/sat_tactic.h" #define BIG_PROBLEM 5000 diff --git a/src/tactic/smtlogics/qfidl_tactic.h b/src/tactic/smtlogics/qfidl_tactic.h index f892bb8a5..c36b857d4 100644 --- a/src/tactic/smtlogics/qfidl_tactic.h +++ b/src/tactic/smtlogics/qfidl_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFIDL_TACTIC_H_ #define QFIDL_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qflia_tactic.cpp b/src/tactic/smtlogics/qflia_tactic.cpp index fd10d8ecb..248829c49 100644 --- a/src/tactic/smtlogics/qflia_tactic.cpp +++ b/src/tactic/smtlogics/qflia_tactic.cpp @@ -16,25 +16,25 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"propagate_ineqs_tactic.h" -#include"normalize_bounds_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"smt_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/arith/propagate_ineqs_tactic.h" +#include "tactic/arith/normalize_bounds_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "smt/tactic/smt_tactic.h" // include"mip_tactic.h" -#include"add_bounds_tactic.h" -#include"pb2bv_tactic.h" -#include"lia2pb_tactic.h" -#include"ctx_simplify_tactic.h" -#include"bit_blaster_tactic.h" -#include"max_bv_sharing_tactic.h" -#include"aig_tactic.h" -#include"sat_tactic.h" -#include"bound_manager.h" -#include"probe_arith.h" +#include "tactic/arith/add_bounds_tactic.h" +#include "tactic/arith/pb2bv_tactic.h" +#include "tactic/arith/lia2pb_tactic.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "tactic/bv/bit_blaster_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "tactic/aig/aig_tactic.h" +#include "sat/tactic/sat_tactic.h" +#include "tactic/arith/bound_manager.h" +#include "tactic/arith/probe_arith.h" struct quasi_pb_probe : public probe { virtual result operator()(goal const & g) { diff --git a/src/tactic/smtlogics/qflia_tactic.h b/src/tactic/smtlogics/qflia_tactic.h index 36e7cf9f9..ee9b859ae 100644 --- a/src/tactic/smtlogics/qflia_tactic.h +++ b/src/tactic/smtlogics/qflia_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFLIA_TACTIC_H_ #define QFLIA_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qflra_tactic.cpp b/src/tactic/smtlogics/qflra_tactic.cpp index 0865f3b47..b44ace7b1 100644 --- a/src/tactic/smtlogics/qflra_tactic.cpp +++ b/src/tactic/smtlogics/qflra_tactic.cpp @@ -16,15 +16,15 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"smt_tactic.h" -#include"recover_01_tactic.h" -#include"ctx_simplify_tactic.h" -#include"probe_arith.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/arith/recover_01_tactic.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "tactic/arith/probe_arith.h" tactic * mk_qflra_tactic(ast_manager & m, params_ref const & p) { params_ref pivot_p; diff --git a/src/tactic/smtlogics/qflra_tactic.h b/src/tactic/smtlogics/qflra_tactic.h index f8b311aba..42829e390 100644 --- a/src/tactic/smtlogics/qflra_tactic.h +++ b/src/tactic/smtlogics/qflra_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFLRA_TACTIC_H_ #define QFLRA_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfnia_tactic.cpp b/src/tactic/smtlogics/qfnia_tactic.cpp index 5a71281fb..3fb733ca4 100644 --- a/src/tactic/smtlogics/qfnia_tactic.cpp +++ b/src/tactic/smtlogics/qfnia_tactic.cpp @@ -16,18 +16,18 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"smt_tactic.h" -#include"bit_blaster_tactic.h" -#include"max_bv_sharing_tactic.h" -#include"sat_tactic.h" -#include"nla2bv_tactic.h" -#include"ctx_simplify_tactic.h" -#include"cofactor_term_ite_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/bv/bit_blaster_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "sat/tactic/sat_tactic.h" +#include "tactic/arith/nla2bv_tactic.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "tactic/core/cofactor_term_ite_tactic.h" static tactic * mk_qfnia_bv_solver(ast_manager & m, params_ref const & p_ref) { params_ref p = p_ref; diff --git a/src/tactic/smtlogics/qfnia_tactic.h b/src/tactic/smtlogics/qfnia_tactic.h index 0770b4eee..84a35e6ec 100644 --- a/src/tactic/smtlogics/qfnia_tactic.h +++ b/src/tactic/smtlogics/qfnia_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFNIA_TACTIC_H_ #define QFNIA_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfnra_tactic.cpp b/src/tactic/smtlogics/qfnra_tactic.cpp index 716b4868b..63c09c19c 100644 --- a/src/tactic/smtlogics/qfnra_tactic.cpp +++ b/src/tactic/smtlogics/qfnra_tactic.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"nla2bv_tactic.h" -#include"smt_tactic.h" -#include"qfnra_nlsat_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/arith/nla2bv_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "nlsat/tactic/qfnra_nlsat_tactic.h" static tactic * mk_qfnra_sat_solver(ast_manager& m, params_ref const& p, unsigned bv_size) { params_ref nra2sat_p = p; diff --git a/src/tactic/smtlogics/qfnra_tactic.h b/src/tactic/smtlogics/qfnra_tactic.h index cae314553..34381d47a 100644 --- a/src/tactic/smtlogics/qfnra_tactic.h +++ b/src/tactic/smtlogics/qfnra_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFNRA_TACTIC_H_ #define QFNRA_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfuf_tactic.cpp b/src/tactic/smtlogics/qfuf_tactic.cpp index 7648e20fe..2de9612c6 100644 --- a/src/tactic/smtlogics/qfuf_tactic.cpp +++ b/src/tactic/smtlogics/qfuf_tactic.cpp @@ -17,12 +17,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"symmetry_reduce_tactic.h" -#include"solve_eqs_tactic.h" -#include"propagate_values_tactic.h" -#include"smt_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/symmetry_reduce_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "smt/tactic/smt_tactic.h" tactic * mk_qfuf_tactic(ast_manager & m, params_ref const & p) { params_ref s2_p; diff --git a/src/tactic/smtlogics/qfuf_tactic.h b/src/tactic/smtlogics/qfuf_tactic.h index 0c81ad57b..98ddd3422 100644 --- a/src/tactic/smtlogics/qfuf_tactic.h +++ b/src/tactic/smtlogics/qfuf_tactic.h @@ -20,7 +20,7 @@ Notes: #ifndef QFUF_TACTIC_H_ #define QFUF_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfufbv_ackr_model_converter.cpp b/src/tactic/smtlogics/qfufbv_ackr_model_converter.cpp index 4d20631b1..50c9b6a46 100644 --- a/src/tactic/smtlogics/qfufbv_ackr_model_converter.cpp +++ b/src/tactic/smtlogics/qfufbv_ackr_model_converter.cpp @@ -14,8 +14,8 @@ Revision History: --*/ -#include"qfufbv_ackr_model_converter.h" -#include"ackr_model_converter.h" +#include "tactic/smtlogics/qfufbv_ackr_model_converter.h" +#include "ackermannization/ackr_model_converter.h" model_converter * mk_qfufbv_ackr_model_converter(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model) { return mk_ackr_model_converter(m, info, abstr_model); diff --git a/src/tactic/smtlogics/qfufbv_ackr_model_converter.h b/src/tactic/smtlogics/qfufbv_ackr_model_converter.h index a361a78e0..efc039560 100644 --- a/src/tactic/smtlogics/qfufbv_ackr_model_converter.h +++ b/src/tactic/smtlogics/qfufbv_ackr_model_converter.h @@ -17,8 +17,8 @@ #ifndef QFUFBV_ACKR_MODEL_CONVERTER_H_ #define QFUFBV_ACKR_MODEL_CONVERTER_H_ -#include"model_converter.h" -#include"ackr_info.h" +#include "tactic/model_converter.h" +#include "ackermannization/ackr_info.h" model_converter * mk_qfufbv_ackr_model_converter(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model); diff --git a/src/tactic/smtlogics/qfufbv_tactic.cpp b/src/tactic/smtlogics/qfufbv_tactic.cpp index e0e1a60e4..2e64d1e0a 100644 --- a/src/tactic/smtlogics/qfufbv_tactic.cpp +++ b/src/tactic/smtlogics/qfufbv_tactic.cpp @@ -17,29 +17,29 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"smt_tactic.h" -#include"max_bv_sharing_tactic.h" -#include"bv_size_reduction_tactic.h" -#include"reduce_args_tactic.h" -#include"qfbv_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/bv/max_bv_sharing_tactic.h" +#include "tactic/bv/bv_size_reduction_tactic.h" +#include "tactic/core/reduce_args_tactic.h" +#include "tactic/smtlogics/qfbv_tactic.h" #include"qfufbv_tactic_params.hpp" /////////////// -#include"model_smt2_pp.h" -#include"cooperate.h" -#include"lackr.h" +#include "model/model_smt2_pp.h" +#include "util/cooperate.h" +#include "ackermannization/lackr.h" #include"ackermannization_params.hpp" -#include"qfufbv_ackr_model_converter.h" +#include "tactic/smtlogics/qfufbv_ackr_model_converter.h" /////////////// -#include"inc_sat_solver.h" -#include"qfaufbv_tactic.h" -#include"qfbv_tactic.h" -#include"tactic2solver.h" -#include"bv_bound_chk_tactic.h" +#include "sat/sat_solver/inc_sat_solver.h" +#include "tactic/smtlogics/qfaufbv_tactic.h" +#include "tactic/smtlogics/qfbv_tactic.h" +#include "solver/tactic2solver.h" +#include "tactic/bv/bv_bound_chk_tactic.h" /////////////// class qfufbv_ackr_tactic : public tactic { diff --git a/src/tactic/smtlogics/qfufbv_tactic.h b/src/tactic/smtlogics/qfufbv_tactic.h index 1f1431d70..3e6d9d817 100644 --- a/src/tactic/smtlogics/qfufbv_tactic.h +++ b/src/tactic/smtlogics/qfufbv_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFUFBV_TACTIC_H_ #define QFUFBV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/qfufnra_tactic.cpp b/src/tactic/smtlogics/qfufnra_tactic.cpp index 4ca241e19..e031b0f52 100644 --- a/src/tactic/smtlogics/qfufnra_tactic.cpp +++ b/src/tactic/smtlogics/qfufnra_tactic.cpp @@ -16,18 +16,18 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"nl_purify_tactic.h" -#include"qfufnra_tactic.h" -#include"purify_arith_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_term_ite_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"simplify_tactic.h" -#include"nnf_tactic.h" -#include"tseitin_cnf_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/nlsat_smt/nl_purify_tactic.h" +#include "tactic/smtlogics/qfufnra_tactic.h" +#include "tactic/arith/purify_arith_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_term_ite_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/nnf_tactic.h" +#include "tactic/core/tseitin_cnf_tactic.h" tactic * mk_qfufnra_tactic(ast_manager & m, params_ref const& p) { params_ref main_p = p; diff --git a/src/tactic/smtlogics/qfufnra_tactic.h b/src/tactic/smtlogics/qfufnra_tactic.h index 4cc2b372d..026ab5c5c 100644 --- a/src/tactic/smtlogics/qfufnra_tactic.h +++ b/src/tactic/smtlogics/qfufnra_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QFUFNRA_TACTIC_H_ #define QFUFNRA_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/smtlogics/quant_tactics.cpp b/src/tactic/smtlogics/quant_tactics.cpp index 7d428b369..400089a0c 100644 --- a/src/tactic/smtlogics/quant_tactics.cpp +++ b/src/tactic/smtlogics/quant_tactics.cpp @@ -16,19 +16,19 @@ Author: Revision History: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"qe_tactic.h" -#include"qe_lite.h" -#include"qsat.h" -#include"nlqsat.h" -#include"ctx_simplify_tactic.h" -#include"smt_tactic.h" -#include"elim_term_ite_tactic.h" -#include"probe_arith.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/elim_uncnstr_tactic.h" +#include "qe/qe_tactic.h" +#include "qe/qe_lite.h" +#include "qe/qsat.h" +#include "qe/nlqsat.h" +#include "tactic/core/ctx_simplify_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/core/elim_term_ite_tactic.h" +#include "tactic/arith/probe_arith.h" static tactic * mk_quant_preprocessor(ast_manager & m, bool disable_gaussian = false) { params_ref pull_ite_p; diff --git a/src/tactic/smtlogics/quant_tactics.h b/src/tactic/smtlogics/quant_tactics.h index b78730236..da3594500 100644 --- a/src/tactic/smtlogics/quant_tactics.h +++ b/src/tactic/smtlogics/quant_tactics.h @@ -19,7 +19,7 @@ Revision History: #ifndef QUANT_TACTICS_H_ #define QUANT_TACTICS_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/tactic.cpp b/src/tactic/tactic.cpp index ac63a2d24..6c4ca7476 100644 --- a/src/tactic/tactic.cpp +++ b/src/tactic/tactic.cpp @@ -17,10 +17,10 @@ Notes: --*/ #include -#include"tactic.h" -#include"probe.h" -#include"stopwatch.h" -#include"model_v2_pp.h" +#include "tactic/tactic.h" +#include "tactic/probe.h" +#include "util/stopwatch.h" +#include "model/model_v2_pp.h" struct tactic_report::imp { diff --git a/src/tactic/tactic.h b/src/tactic/tactic.h index 645b53681..0e4c61611 100644 --- a/src/tactic/tactic.h +++ b/src/tactic/tactic.h @@ -21,13 +21,13 @@ Notes: #ifndef TACTIC_H_ #define TACTIC_H_ -#include"goal.h" -#include"params.h" -#include"statistics.h" -#include"model_converter.h" -#include"proof_converter.h" -#include"tactic_exception.h" -#include"lbool.h" +#include "tactic/goal.h" +#include "util/params.h" +#include "util/statistics.h" +#include "tactic/model_converter.h" +#include "tactic/proof_converter.h" +#include "tactic/tactic_exception.h" +#include "util/lbool.h" class progress_callback; diff --git a/src/tactic/tactic_exception.h b/src/tactic/tactic_exception.h index 6dbd39ff9..e989ed2bf 100644 --- a/src/tactic/tactic_exception.h +++ b/src/tactic/tactic_exception.h @@ -19,8 +19,8 @@ Notes: #ifndef TACTIC_EXCEPTION_H_ #define TACTIC_EXCEPTION_H_ -#include"z3_exception.h" -#include"common_msgs.h" +#include "util/z3_exception.h" +#include "util/common_msgs.h" class tactic_exception : public z3_exception { protected: diff --git a/src/tactic/tactical.cpp b/src/tactic/tactical.cpp index 33f8325fb..c5a70c0db 100644 --- a/src/tactic/tactical.cpp +++ b/src/tactic/tactical.cpp @@ -16,12 +16,12 @@ Author: Notes: --*/ -#include"tactical.h" -#include"scoped_timer.h" -#include"cancel_eh.h" -#include"cooperate.h" -#include"scoped_ptr_vector.h" -#include"z3_omp.h" +#include "tactic/tactical.h" +#include "util/scoped_timer.h" +#include "util/cancel_eh.h" +#include "util/cooperate.h" +#include "util/scoped_ptr_vector.h" +#include "util/z3_omp.h" class binary_tactical : public tactic { protected: diff --git a/src/tactic/tactical.h b/src/tactic/tactical.h index 4b4274b0c..169566f39 100644 --- a/src/tactic/tactical.h +++ b/src/tactic/tactical.h @@ -19,8 +19,8 @@ Notes: #ifndef TACTICAL_H_ #define TACTICAL_H_ -#include"tactic.h" -#include"probe.h" +#include "tactic/tactic.h" +#include "tactic/probe.h" tactic * and_then(unsigned num, tactic * const * ts); tactic * and_then(tactic * t1, tactic * t2); diff --git a/src/tactic/ufbv/macro_finder_tactic.cpp b/src/tactic/ufbv/macro_finder_tactic.cpp index e31682cd0..9b1835ff3 100644 --- a/src/tactic/ufbv/macro_finder_tactic.cpp +++ b/src/tactic/ufbv/macro_finder_tactic.cpp @@ -16,15 +16,15 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplifier.h" -#include"basic_simplifier_plugin.h" -#include"arith_simplifier_plugin.h" -#include"bv_simplifier_plugin.h" -#include"macro_manager.h" -#include"macro_finder.h" -#include"extension_model_converter.h" -#include"macro_finder_tactic.h" +#include "tactic/tactical.h" +#include "ast/simplifier/simplifier.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/macros/macro_manager.h" +#include "ast/macros/macro_finder.h" +#include "tactic/extension_model_converter.h" +#include "tactic/ufbv/macro_finder_tactic.h" class macro_finder_tactic : public tactic { diff --git a/src/tactic/ufbv/macro_finder_tactic.h b/src/tactic/ufbv/macro_finder_tactic.h index d763d4567..659748dec 100644 --- a/src/tactic/ufbv/macro_finder_tactic.h +++ b/src/tactic/ufbv/macro_finder_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef MACRO_FINDER_TACTIC_H_ #define MACRO_FINDER_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/ufbv/quasi_macros_tactic.cpp b/src/tactic/ufbv/quasi_macros_tactic.cpp index d1320bc0d..ab68a2b63 100644 --- a/src/tactic/ufbv/quasi_macros_tactic.cpp +++ b/src/tactic/ufbv/quasi_macros_tactic.cpp @@ -16,16 +16,16 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplifier.h" -#include"basic_simplifier_plugin.h" -#include"arith_simplifier_plugin.h" -#include"bv_simplifier_plugin.h" -#include"macro_manager.h" -#include"macro_finder.h" -#include"extension_model_converter.h" -#include"quasi_macros.h" -#include"quasi_macros_tactic.h" +#include "tactic/tactical.h" +#include "ast/simplifier/simplifier.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/macros/macro_manager.h" +#include "ast/macros/macro_finder.h" +#include "tactic/extension_model_converter.h" +#include "ast/macros/quasi_macros.h" +#include "tactic/ufbv/quasi_macros_tactic.h" class quasi_macros_tactic : public tactic { diff --git a/src/tactic/ufbv/quasi_macros_tactic.h b/src/tactic/ufbv/quasi_macros_tactic.h index 2dff246a1..55fc5fcfb 100644 --- a/src/tactic/ufbv/quasi_macros_tactic.h +++ b/src/tactic/ufbv/quasi_macros_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef QUASI_MACROS_TACTIC_H_ #define QUASI_MACROS_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/ufbv/ufbv_rewriter.cpp b/src/tactic/ufbv/ufbv_rewriter.cpp index f5f18d234..4f0f5e548 100644 --- a/src/tactic/ufbv/ufbv_rewriter.cpp +++ b/src/tactic/ufbv/ufbv_rewriter.cpp @@ -20,11 +20,11 @@ Revision History: --*/ -#include"ast_pp.h" -#include"ufbv_rewriter.h" -#include"for_each_expr.h" -#include"var_subst.h" -#include"uint_set.h" +#include "ast/ast_pp.h" +#include "tactic/ufbv/ufbv_rewriter.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/var_subst.h" +#include "util/uint_set.h" ufbv_rewriter::ufbv_rewriter(ast_manager & m, basic_simplifier_plugin & p): m_manager(m), diff --git a/src/tactic/ufbv/ufbv_rewriter.h b/src/tactic/ufbv/ufbv_rewriter.h index 13234799e..d11453836 100644 --- a/src/tactic/ufbv/ufbv_rewriter.h +++ b/src/tactic/ufbv/ufbv_rewriter.h @@ -21,12 +21,12 @@ Revision History: #ifndef UFBV_REWRITER_H_ #define UFBV_REWRITER_H_ -#include"ast.h" -#include"substitution.h" -#include"obj_hashtable.h" -#include"obj_pair_hashtable.h" -#include"array_map.h" -#include"basic_simplifier_plugin.h" +#include "ast/ast.h" +#include "ast/substitution/substitution.h" +#include "util/obj_hashtable.h" +#include "util/obj_pair_hashtable.h" +#include "util/array_map.h" +#include "ast/simplifier/basic_simplifier_plugin.h" /** \brief Apply demodulators as a preprocessing technique. diff --git a/src/tactic/ufbv/ufbv_rewriter_tactic.cpp b/src/tactic/ufbv/ufbv_rewriter_tactic.cpp index 37ad9c73c..b4bfabf65 100644 --- a/src/tactic/ufbv/ufbv_rewriter_tactic.cpp +++ b/src/tactic/ufbv/ufbv_rewriter_tactic.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplifier.h" -#include"basic_simplifier_plugin.h" -#include"ufbv_rewriter.h" -#include"ufbv_rewriter_tactic.h" +#include "tactic/tactical.h" +#include "ast/simplifier/simplifier.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "tactic/ufbv/ufbv_rewriter.h" +#include "tactic/ufbv/ufbv_rewriter_tactic.h" class ufbv_rewriter_tactic : public tactic { diff --git a/src/tactic/ufbv/ufbv_rewriter_tactic.h b/src/tactic/ufbv/ufbv_rewriter_tactic.h index 78e34bae2..d0bdcd021 100644 --- a/src/tactic/ufbv/ufbv_rewriter_tactic.h +++ b/src/tactic/ufbv/ufbv_rewriter_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef UFBV_REWRITER_TACTIC_H_ #define UFBV_REWRITER_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/tactic/ufbv/ufbv_tactic.cpp b/src/tactic/ufbv/ufbv_tactic.cpp index 19d41be68..1fb4486ec 100644 --- a/src/tactic/ufbv/ufbv_tactic.cpp +++ b/src/tactic/ufbv/ufbv_tactic.cpp @@ -16,19 +16,19 @@ Author: Notes: --*/ -#include"tactical.h" -#include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"solve_eqs_tactic.h" -#include"distribute_forall_tactic.h" -#include"der_tactic.h" -#include"reduce_args_tactic.h" -#include"smt_tactic.h" -#include"nnf_tactic.h" -#include"macro_finder_tactic.h" -#include"ufbv_rewriter_tactic.h" -#include"quasi_macros_tactic.h" -#include"ufbv_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/simplify_tactic.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/core/solve_eqs_tactic.h" +#include "tactic/core/distribute_forall_tactic.h" +#include "tactic/core/der_tactic.h" +#include "tactic/core/reduce_args_tactic.h" +#include "smt/tactic/smt_tactic.h" +#include "tactic/core/nnf_tactic.h" +#include "tactic/ufbv/macro_finder_tactic.h" +#include "tactic/ufbv/ufbv_rewriter_tactic.h" +#include "tactic/ufbv/quasi_macros_tactic.h" +#include "tactic/ufbv/ufbv_tactic.h" static tactic * mk_der_fp_tactic(ast_manager & m, params_ref const & p) { diff --git a/src/tactic/ufbv/ufbv_tactic.h b/src/tactic/ufbv/ufbv_tactic.h index 300fdd84a..ee97cd35e 100644 --- a/src/tactic/ufbv/ufbv_tactic.h +++ b/src/tactic/ufbv/ufbv_tactic.h @@ -19,7 +19,7 @@ Notes: #ifndef UFBV_TACTIC_H_ #define UFBV_TACTIC_H_ -#include"params.h" +#include "util/params.h" class ast_manager; class tactic; diff --git a/src/test/algebraic.cpp b/src/test/algebraic.cpp index 076d7ec73..b893b5ee2 100644 --- a/src/test/algebraic.cpp +++ b/src/test/algebraic.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"algebraic_numbers.h" -#include"polynomial_var2value.h" -#include"mpbq.h" -#include"rlimit.h" +#include "math/polynomial/algebraic_numbers.h" +#include "math/polynomial/polynomial_var2value.h" +#include "util/mpbq.h" +#include "util/rlimit.h" static void display_anums(std::ostream & out, scoped_anum_vector const & rs) { out << "numbers in decimal:\n"; diff --git a/src/test/api.cpp b/src/test/api.cpp index f691a8701..2b6cda0ea 100644 --- a/src/test/api.cpp +++ b/src/test/api.cpp @@ -5,13 +5,13 @@ Copyright (c) 2015 Microsoft Corporation --*/ #ifdef _WINDOWS -#include "z3.h" -#include "z3_private.h" +#include "api/z3.h" +#include "api/z3_private.h" #include -#include "util.h" -#include "trace.h" +#include "util/util.h" +#include "util/trace.h" #include -#include "trace.h" +#include "util/trace.h" void test_apps() { Z3_config cfg = Z3_mk_config(); diff --git a/src/test/api_bug.cpp b/src/test/api_bug.cpp index cd7feec56..44721700b 100644 --- a/src/test/api_bug.cpp +++ b/src/test/api_bug.cpp @@ -5,7 +5,7 @@ Copyright (c) 2015 Microsoft Corporation --*/ #include -#include"z3.h" +#include "api/z3.h" void tst_api_bug() { unsigned vmajor, vminor, vbuild, vrevision; diff --git a/src/test/arith_rewriter.cpp b/src/test/arith_rewriter.cpp index 6bdb11d48..a279d58b2 100644 --- a/src/test/arith_rewriter.cpp +++ b/src/test/arith_rewriter.cpp @@ -4,14 +4,14 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "arith_rewriter.h" -#include "bv_decl_plugin.h" -#include "ast_pp.h" -#include "reg_decl_plugins.h" -#include "th_rewriter.h" -#include "model.h" -#include "pdr_util.h" -#include "smt2parser.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" +#include "ast/rewriter/th_rewriter.h" +#include "model/model.h" +#include "muz/pdr/pdr_util.h" +#include "parsers/smt2/smt2parser.h" static expr_ref parse_fml(ast_manager& m, char const* str) { diff --git a/src/test/arith_simplifier_plugin.cpp b/src/test/arith_simplifier_plugin.cpp index 8464fd830..63a6838d4 100644 --- a/src/test/arith_simplifier_plugin.cpp +++ b/src/test/arith_simplifier_plugin.cpp @@ -4,8 +4,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "arith_eq_solver.h" -#include "smt_params.h" +#include "smt/arith_eq_solver.h" +#include "smt/params/smt_params.h" typedef rational numeral; typedef vector row; diff --git a/src/test/ast.cpp b/src/test/ast.cpp index 20a1007a4..59bdfc8e4 100644 --- a/src/test/ast.cpp +++ b/src/test/ast.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include "ast.h" +#include "ast/ast.h" static void tst1() { ast_manager m; diff --git a/src/test/bit_blaster.cpp b/src/test/bit_blaster.cpp index d864032f5..c6853ae1e 100644 --- a/src/test/bit_blaster.cpp +++ b/src/test/bit_blaster.cpp @@ -17,9 +17,9 @@ Revision History: --*/ -#include"bit_blaster.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" +#include "ast/rewriter/bit_blaster/bit_blaster.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" void mk_bits(ast_manager & m, char const * prefix, unsigned sz, expr_ref_vector & r) { sort_ref b(m); diff --git a/src/test/bit_vector.cpp b/src/test/bit_vector.cpp index 46a39747d..e920fadee 100644 --- a/src/test/bit_vector.cpp +++ b/src/test/bit_vector.cpp @@ -18,8 +18,8 @@ Revision History: --*/ #include #include -#include"bit_vector.h" -#include"vector.h" +#include "util/bit_vector.h" +#include "util/vector.h" static void tst1() { bit_vector v1; diff --git a/src/test/bits.cpp b/src/test/bits.cpp index ba75ea0b4..f0f04f661 100644 --- a/src/test/bits.cpp +++ b/src/test/bits.cpp @@ -5,11 +5,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ // Test some bit hacks -#include"util.h" -#include"debug.h" -#include"vector.h" -#include"mpz.h" -#include"bit_util.h" +#include "util/util.h" +#include "util/debug.h" +#include "util/vector.h" +#include "util/mpz.h" +#include "util/bit_util.h" static void tst_shl(unsigned src_sz, unsigned const * src, unsigned k, unsigned dst_sz, unsigned const * dst, bool trace = true) { diff --git a/src/test/buffer.cpp b/src/test/buffer.cpp index f4b7f0c99..4ab9754c2 100644 --- a/src/test/buffer.cpp +++ b/src/test/buffer.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"ptr_scoped_buffer.h" +#include "util/ptr_scoped_buffer.h" typedef std::pair point; diff --git a/src/test/bv_simplifier_plugin.cpp b/src/test/bv_simplifier_plugin.cpp index 42952706b..15ca9fac5 100644 --- a/src/test/bv_simplifier_plugin.cpp +++ b/src/test/bv_simplifier_plugin.cpp @@ -4,10 +4,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "bv_simplifier_plugin.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" -#include "reg_decl_plugins.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" class tst_bv_simplifier_plugin_cls { class mgr { diff --git a/src/test/chashtable.cpp b/src/test/chashtable.cpp index c9750b95e..0ccf2c177 100644 --- a/src/test/chashtable.cpp +++ b/src/test/chashtable.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"chashtable.h" -#include"hashtable.h" -#include"hash.h" -#include"util.h" +#include "util/chashtable.h" +#include "util/hashtable.h" +#include "util/hash.h" +#include "util/util.h" typedef chashtable > int_table; typedef cmap > int_map; diff --git a/src/test/check_assumptions.cpp b/src/test/check_assumptions.cpp index 918513ca0..020b3e277 100644 --- a/src/test/check_assumptions.cpp +++ b/src/test/check_assumptions.cpp @@ -4,13 +4,13 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "memory_manager.h" -#include "smt_params.h" -#include "ast.h" -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "smt_context.h" -#include "reg_decl_plugins.h" +#include "util/memory_manager.h" +#include "smt/params/smt_params.h" +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "smt/smt_context.h" +#include "ast/reg_decl_plugins.h" void tst_check_assumptions() { diff --git a/src/test/cnf_backbones.cpp b/src/test/cnf_backbones.cpp index 3fdf96f87..3e9a106b5 100644 --- a/src/test/cnf_backbones.cpp +++ b/src/test/cnf_backbones.cpp @@ -5,11 +5,11 @@ Copyright (c) 2017 Microsoft Corporation #include #include #include -#include"timeout.h" -#include"rlimit.h" -#include"dimacs.h" -#include"sat_solver.h" -#include"gparams.h" +#include "util/timeout.h" +#include "util/rlimit.h" +#include "sat/dimacs.h" +#include "sat/sat_solver.h" +#include "util/gparams.h" static sat::solver * g_solver = 0; static clock_t g_start_time; diff --git a/src/test/datalog_parser.cpp b/src/test/datalog_parser.cpp index 800f21717..ca5e94f75 100644 --- a/src/test/datalog_parser.cpp +++ b/src/test/datalog_parser.cpp @@ -4,13 +4,13 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "datalog_parser.h" -#include "ast_pp.h" -#include "arith_decl_plugin.h" -#include "dl_context.h" -#include "dl_register_engine.h" -#include "smt_params.h" -#include "reg_decl_plugins.h" +#include "muz/fp/datalog_parser.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "muz/base/dl_context.h" +#include "muz/fp/dl_register_engine.h" +#include "smt/params/smt_params.h" +#include "ast/reg_decl_plugins.h" using namespace datalog; diff --git a/src/test/ddnf.cpp b/src/test/ddnf.cpp index 31503842d..3f8e748be 100644 --- a/src/test/ddnf.cpp +++ b/src/test/ddnf.cpp @@ -3,8 +3,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ddnf.h" -#include "tbv.h" +#include "muz/ddnf/ddnf.h" +#include "muz/rel/tbv.h" #include #include #include diff --git a/src/test/diff_logic.cpp b/src/test/diff_logic.cpp index 3a1ec198d..e79c93cf2 100644 --- a/src/test/diff_logic.cpp +++ b/src/test/diff_logic.cpp @@ -17,11 +17,11 @@ Revision History: --*/ #ifdef _WINDOWS -#include"rational.h" -#include"diff_logic.h" -#include"smt_literal.h" -#include"util.h" -#include"debug.h" +#include "util/rational.h" +#include "smt/diff_logic.h" +#include "smt/smt_literal.h" +#include "util/util.h" +#include "util/debug.h" struct diff_logic_ext { typedef rational numeral; diff --git a/src/test/dl_context.cpp b/src/test/dl_context.cpp index 8d60cd883..e44c92f30 100644 --- a/src/test/dl_context.cpp +++ b/src/test/dl_context.cpp @@ -4,12 +4,12 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "datalog_parser.h" -#include "ast_pp.h" -#include "arith_decl_plugin.h" -#include "dl_context.h" -#include "smt_params.h" -#include "dl_register_engine.h" +#include "muz/fp/datalog_parser.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "muz/base/dl_context.h" +#include "smt/params/smt_params.h" +#include "muz/fp/dl_register_engine.h" using namespace datalog; diff --git a/src/test/dl_product_relation.cpp b/src/test/dl_product_relation.cpp index 84ffd548a..7cbbde450 100644 --- a/src/test/dl_product_relation.cpp +++ b/src/test/dl_product_relation.cpp @@ -5,11 +5,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ #ifdef _WINDOWS -#include "dl_context.h" -#include "dl_register_engine.h" -#include "dl_finite_product_relation.h" -#include "dl_sparse_table.h" -#include "rel_context.h" +#include "muz/base/dl_context.h" +#include "muz/fp/dl_register_engine.h" +#include "muz/rel/dl_finite_product_relation.h" +#include "muz/rel/dl_sparse_table.h" +#include "muz/rel/rel_context.h" namespace datalog { diff --git a/src/test/dl_query.cpp b/src/test/dl_query.cpp index eaa26cdbb..c5765bd6b 100644 --- a/src/test/dl_query.cpp +++ b/src/test/dl_query.cpp @@ -4,15 +4,15 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "datalog_parser.h" -#include "ast_pp.h" -#include "dl_table_relation.h" -#include "dl_context.h" -#include "dl_register_engine.h" -#include "smt_params.h" -#include "stopwatch.h" -#include "reg_decl_plugins.h" -#include "dl_relation_manager.h" +#include "muz/fp/datalog_parser.h" +#include "ast/ast_pp.h" +#include "muz/rel/dl_table_relation.h" +#include "muz/base/dl_context.h" +#include "muz/fp/dl_register_engine.h" +#include "smt/params/smt_params.h" +#include "util/stopwatch.h" +#include "ast/reg_decl_plugins.h" +#include "muz/rel/dl_relation_manager.h" using namespace datalog; diff --git a/src/test/dl_relation.cpp b/src/test/dl_relation.cpp index f0feed3a9..3abd60ce2 100644 --- a/src/test/dl_relation.cpp +++ b/src/test/dl_relation.cpp @@ -5,13 +5,13 @@ Copyright (c) 2015 Microsoft Corporation --*/ #ifdef _WINDOWS -#include "dl_context.h" -#include "dl_register_engine.h" -#include "dl_relation_manager.h" -#include "dl_interval_relation.h" -#include "dl_bound_relation.h" -#include "dl_product_relation.h" -#include "util.h" +#include "muz/base/dl_context.h" +#include "muz/fp/dl_register_engine.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/rel/dl_interval_relation.h" +#include "muz/rel/dl_bound_relation.h" +#include "muz/rel/dl_product_relation.h" +#include "util/util.h" namespace datalog { diff --git a/src/test/dl_table.cpp b/src/test/dl_table.cpp index f9ccb3116..326be5d04 100644 --- a/src/test/dl_table.cpp +++ b/src/test/dl_table.cpp @@ -3,10 +3,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ #if defined(_WINDOWS) || defined(_CYGWIN) -#include "dl_context.h" -#include "dl_table.h" -#include "dl_register_engine.h" -#include "dl_relation_manager.h" +#include "muz/base/dl_context.h" +#include "muz/rel/dl_table.h" +#include "muz/fp/dl_register_engine.h" +#include "muz/rel/dl_relation_manager.h" typedef datalog::table_base* (*mk_table_fn)(datalog::relation_manager& m, datalog::table_signature& sig); diff --git a/src/test/dl_util.cpp b/src/test/dl_util.cpp index 44b95934e..d30b23e47 100644 --- a/src/test/dl_util.cpp +++ b/src/test/dl_util.cpp @@ -4,7 +4,7 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "dl_util.h" +#include "muz/base/dl_util.h" using namespace datalog; diff --git a/src/test/doc.cpp b/src/test/doc.cpp index 4d9b9b7e6..aaa69fa92 100644 --- a/src/test/doc.cpp +++ b/src/test/doc.cpp @@ -4,19 +4,19 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "doc.h" -#include "trace.h" -#include "vector.h" -#include "ast.h" -#include "ast_pp.h" -#include "reg_decl_plugins.h" -#include "sorting_network.h" -#include "smt_kernel.h" -#include "model_smt2_pp.h" -#include "smt_params.h" -#include "ast_util.h" -#include "expr_safe_replace.h" -#include "th_rewriter.h" +#include "muz/rel/doc.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" +#include "util/sorting_network.h" +#include "smt/smt_kernel.h" +#include "model/model_smt2_pp.h" +#include "smt/params/smt_params.h" +#include "ast/ast_util.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/rewriter/th_rewriter.h" static void tst_doc1(unsigned n) { diff --git a/src/test/escaped.cpp b/src/test/escaped.cpp index c776bd600..fe8f733bf 100644 --- a/src/test/escaped.cpp +++ b/src/test/escaped.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"util.h" +#include "util/util.h" void tst_escaped() { std::cout << "[" << escaped("\"hello\"\"world\"\n\n") << "]\n"; diff --git a/src/test/ex.cpp b/src/test/ex.cpp index e9243dd5b..591813814 100644 --- a/src/test/ex.cpp +++ b/src/test/ex.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include -#include"z3_exception.h" +#include "util/z3_exception.h" class ex { public: diff --git a/src/test/expr_rand.cpp b/src/test/expr_rand.cpp index 96d21a44c..388a178f4 100644 --- a/src/test/expr_rand.cpp +++ b/src/test/expr_rand.cpp @@ -4,15 +4,15 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "expr_rand.h" -#include "ast_pp.h" -#include "bv_decl_plugin.h" -#include "array_decl_plugin.h" -#include "arith_decl_plugin.h" -#include "ast_smt_pp.h" +#include "test/fuzzing/expr_rand.h" +#include "ast/ast_pp.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_smt_pp.h" #include #include -#include "reg_decl_plugins.h" +#include "ast/reg_decl_plugins.h" static unsigned rand_seed = 1; diff --git a/src/test/expr_substitution.cpp b/src/test/expr_substitution.cpp index fdf1d6dc2..3b74535e7 100644 --- a/src/test/expr_substitution.cpp +++ b/src/test/expr_substitution.cpp @@ -4,15 +4,15 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "expr_substitution.h" -#include "smt_params.h" -#include "substitution.h" -#include "unifier.h" -#include "bv_decl_plugin.h" -#include "ast_pp.h" -#include "arith_decl_plugin.h" -#include "reg_decl_plugins.h" -#include "th_rewriter.h" +#include "ast/expr_substitution.h" +#include "smt/params/smt_params.h" +#include "ast/substitution/substitution.h" +#include "ast/substitution/unifier.h" +#include "ast/bv_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/reg_decl_plugins.h" +#include "ast/rewriter/th_rewriter.h" expr* mk_bv_xor(bv_util& bv, expr* a, expr* b) { expr* args[2]; diff --git a/src/test/ext_numeral.cpp b/src/test/ext_numeral.cpp index a35af1ba6..4c82617c9 100644 --- a/src/test/ext_numeral.cpp +++ b/src/test/ext_numeral.cpp @@ -17,8 +17,8 @@ Notes: --*/ #include -#include"mpq.h" -#include"ext_numeral.h" +#include "util/mpq.h" +#include "util/ext_numeral.h" #define MK_TST_UNARY(NAME) \ static void tst_ ## NAME(int a, ext_numeral_kind ak, int expected_c, ext_numeral_kind expected_ck) { \ diff --git a/src/test/f2n.cpp b/src/test/f2n.cpp index 0ae9ea1dd..7831a31cf 100644 --- a/src/test/f2n.cpp +++ b/src/test/f2n.cpp @@ -15,9 +15,9 @@ Author: Revision History: --*/ -#include"f2n.h" -#include"hwf.h" -#include"mpf.h" +#include "util/f2n.h" +#include "util/hwf.h" +#include "util/mpf.h" static void tst1() { hwf_manager hm; diff --git a/src/test/factor_rewriter.cpp b/src/test/factor_rewriter.cpp index 3bcdcd9e9..486221e5b 100644 --- a/src/test/factor_rewriter.cpp +++ b/src/test/factor_rewriter.cpp @@ -4,10 +4,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "factor_rewriter.h" -#include "bv_decl_plugin.h" -#include "ast_pp.h" -#include "reg_decl_plugins.h" +#include "ast/rewriter/factor_rewriter.h" +#include "ast/bv_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" void tst_factor_rewriter() { ast_manager m; diff --git a/src/test/fixed_bit_vector.cpp b/src/test/fixed_bit_vector.cpp index 0160fe574..f1c52a6a8 100644 --- a/src/test/fixed_bit_vector.cpp +++ b/src/test/fixed_bit_vector.cpp @@ -20,8 +20,8 @@ Revision History: --*/ #include #include -#include"fixed_bit_vector.h" -#include"vector.h" +#include "util/fixed_bit_vector.h" +#include "util/vector.h" static void tst1() { diff --git a/src/test/for_each_file.cpp b/src/test/for_each_file.cpp index d217aa5f1..eeec69156 100644 --- a/src/test/for_each_file.cpp +++ b/src/test/for_each_file.cpp @@ -21,7 +21,7 @@ Revision History: #include #include #include -#include "for_each_file.h" +#include "test/for_each_file.h" bool for_each_file(for_each_file_proc& proc, const char* base, const char* suffix) { diff --git a/src/test/fuzzing/expr_delta.cpp b/src/test/fuzzing/expr_delta.cpp index fd5117a74..8e94a84ce 100644 --- a/src/test/fuzzing/expr_delta.cpp +++ b/src/test/fuzzing/expr_delta.cpp @@ -4,8 +4,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "expr_delta.h" -#include "ast_pp.h" +#include "test/fuzzing/expr_delta.h" +#include "ast/ast_pp.h" expr_delta::expr_delta(ast_manager& m) : m_manager(m), m_exprs(m) {} diff --git a/src/test/fuzzing/expr_delta.h b/src/test/fuzzing/expr_delta.h index 2c68efb40..d69ed33f1 100644 --- a/src/test/fuzzing/expr_delta.h +++ b/src/test/fuzzing/expr_delta.h @@ -20,7 +20,7 @@ Revision History: #ifndef EXPR_DELTA_H_ #define EXPR_DELTA_H_ -#include "ast.h" +#include "ast/ast.h" class expr_delta { ast_manager& m_manager; diff --git a/src/test/fuzzing/expr_rand.cpp b/src/test/fuzzing/expr_rand.cpp index ccc4a9e5c..1d425e9e1 100644 --- a/src/test/fuzzing/expr_rand.cpp +++ b/src/test/fuzzing/expr_rand.cpp @@ -4,11 +4,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "expr_rand.h" -#include "bv_decl_plugin.h" -#include "array_decl_plugin.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" +#include "test/fuzzing/expr_rand.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" expr_rand::expr_rand(ast_manager& m): diff --git a/src/test/fuzzing/expr_rand.h b/src/test/fuzzing/expr_rand.h index bbadd587e..4cdee81fd 100644 --- a/src/test/fuzzing/expr_rand.h +++ b/src/test/fuzzing/expr_rand.h @@ -19,8 +19,8 @@ Revision History: #ifndef EXPR_RAND_H_ #define EXPR_RAND_H_ -#include"ast.h" -#include"obj_hashtable.h" +#include "ast/ast.h" +#include "util/obj_hashtable.h" class expr_rand { ast_manager& m_manager; diff --git a/src/test/get_consequences.cpp b/src/test/get_consequences.cpp index 029a13881..9337dcee3 100644 --- a/src/test/get_consequences.cpp +++ b/src/test/get_consequences.cpp @@ -3,15 +3,15 @@ Copyright (c) 2016 Microsoft Corporation --*/ -#include "inc_sat_solver.h" -#include "bv_decl_plugin.h" -#include "datatype_decl_plugin.h" -#include "reg_decl_plugins.h" -#include "ast_pp.h" -#include "dt2bv_tactic.h" -#include "tactic.h" -#include "model_smt2_pp.h" -#include "fd_solver.h" +#include "sat/sat_solver/inc_sat_solver.h" +#include "ast/bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/reg_decl_plugins.h" +#include "ast/ast_pp.h" +#include "tactic/bv/dt2bv_tactic.h" +#include "tactic/tactic.h" +#include "model/model_smt2_pp.h" +#include "tactic/portfolio/fd_solver.h" static expr_ref mk_const(ast_manager& m, char const* name, sort* s) { return expr_ref(m.mk_const(symbol(name), s), m); diff --git a/src/test/get_implied_equalities.cpp b/src/test/get_implied_equalities.cpp index 8ddcdb1e9..952fb121a 100644 --- a/src/test/get_implied_equalities.cpp +++ b/src/test/get_implied_equalities.cpp @@ -4,9 +4,9 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "z3.h" -#include "trace.h" -#include "debug.h" +#include "api/z3.h" +#include "util/trace.h" +#include "util/debug.h" static Z3_ast mk_var(Z3_context ctx, char const* name, Z3_sort s) { return Z3_mk_const(ctx, Z3_mk_string_symbol(ctx, name), s); diff --git a/src/test/hashtable.cpp b/src/test/hashtable.cpp index 0290ac161..befd0b8e9 100644 --- a/src/test/hashtable.cpp +++ b/src/test/hashtable.cpp @@ -21,7 +21,7 @@ Revision History: #include #include -#include"hashtable.h" +#include "util/hashtable.h" struct int_hash_proc { unsigned operator()(int x) const { return x * 3; } }; diff --git a/src/test/heap.cpp b/src/test/heap.cpp index 6f827b5e8..117b6abef 100644 --- a/src/test/heap.cpp +++ b/src/test/heap.cpp @@ -17,9 +17,9 @@ Revision History: --*/ #include -#include"heap.h" -#include"hashtable.h" -#include"trace.h" +#include "util/heap.h" +#include "util/hashtable.h" +#include "util/trace.h" struct lt_proc { bool operator()(int v1, int v2) const { return v1 < v2; } }; typedef heap int_heap; diff --git a/src/test/heap_trie.cpp b/src/test/heap_trie.cpp index 5b0047e82..b6f651633 100644 --- a/src/test/heap_trie.cpp +++ b/src/test/heap_trie.cpp @@ -4,7 +4,7 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "heap_trie.h" +#include "math/hilbert/heap_trie.h" struct unsigned_le { static bool le(unsigned i, unsigned j) { return i <= j; } diff --git a/src/test/hilbert_basis.cpp b/src/test/hilbert_basis.cpp index f2ca8a375..7329b1d3d 100644 --- a/src/test/hilbert_basis.cpp +++ b/src/test/hilbert_basis.cpp @@ -4,15 +4,15 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "hilbert_basis.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 "rlimit.h" +#include "math/hilbert/hilbert_basis.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" +#include "ast/arith_decl_plugin.h" +#include "tactic/smtlogics/quant_tactics.h" +#include "tactic/tactic.h" +#include "solver/tactic2solver.h" +#include "solver/solver.h" +#include "util/rlimit.h" #include #include #include diff --git a/src/test/horn_subsume_model_converter.cpp b/src/test/horn_subsume_model_converter.cpp index 4b653e3a8..a361cfb2a 100644 --- a/src/test/horn_subsume_model_converter.cpp +++ b/src/test/horn_subsume_model_converter.cpp @@ -5,10 +5,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "horn_subsume_model_converter.h" -#include "arith_decl_plugin.h" -#include "model_smt2_pp.h" -#include "reg_decl_plugins.h" +#include "tactic/horn_subsume_model_converter.h" +#include "ast/arith_decl_plugin.h" +#include "model/model_smt2_pp.h" +#include "ast/reg_decl_plugins.h" void tst_horn_subsume_model_converter() { ast_manager m; diff --git a/src/test/hwf.cpp b/src/test/hwf.cpp index 310d69be2..697673473 100644 --- a/src/test/hwf.cpp +++ b/src/test/hwf.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"hwf.h" -#include"f2n.h" -#include"rational.h" +#include "util/hwf.h" +#include "util/f2n.h" +#include "util/rational.h" static void bug_set_double() { hwf_manager m; diff --git a/src/test/im_float_config.h b/src/test/im_float_config.h index 2f33172a1..436d9ecaf 100644 --- a/src/test/im_float_config.h +++ b/src/test/im_float_config.h @@ -19,9 +19,9 @@ Revision History: #ifndef IM_FLOAT_CONFIG_H_ #define IM_FLOAT_CONFIG_H_ -#include"f2n.h" -#include"mpf.h" -#include"hwf.h" +#include "util/f2n.h" +#include "util/mpf.h" +#include "util/hwf.h" template class im_float_config { diff --git a/src/test/inf_rational.cpp b/src/test/inf_rational.cpp index 64d2ab921..634bae7c1 100644 --- a/src/test/inf_rational.cpp +++ b/src/test/inf_rational.cpp @@ -18,7 +18,7 @@ Revision History: --*/ -#include"inf_rational.h" +#include "util/inf_rational.h" static void tst0() { inf_rational n(rational(0), false); diff --git a/src/test/interval.cpp b/src/test/interval.cpp index c22156988..ba218c010 100644 --- a/src/test/interval.cpp +++ b/src/test/interval.cpp @@ -17,12 +17,12 @@ Revision History: --*/ #include -#include"interval_def.h" -#include"dependency.h" -#include"mpq.h" -#include"ast.h" -#include"debug.h" -#include"rlimit.h" +#include "math/interval/interval_def.h" +#include "util/dependency.h" +#include "util/mpq.h" +#include "ast/ast.h" +#include "util/debug.h" +#include "util/rlimit.h" template class interval_manager; typedef im_default_config::interval interval; @@ -390,7 +390,7 @@ static void tst_div(unsigned N, unsigned magnitude) { del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); } -#include"im_float_config.h" +#include "test/im_float_config.h" #if 0 static void tst_float() { diff --git a/src/test/karr.cpp b/src/test/karr.cpp index 11e7ae17f..dc18f7e19 100644 --- a/src/test/karr.cpp +++ b/src/test/karr.cpp @@ -3,8 +3,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include"rlimit.h" -#include "hilbert_basis.h" +#include "util/rlimit.h" +#include "math/hilbert/hilbert_basis.h" /* Test generation of linear congruences a la Karr. diff --git a/src/test/list.cpp b/src/test/list.cpp index e377e7bbf..4cfa16801 100644 --- a/src/test/list.cpp +++ b/src/test/list.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"trace.h" -#include"util.h" -#include"region.h" -#include"list.h" +#include "util/trace.h" +#include "util/util.h" +#include "util/region.h" +#include "util/list.h" static void tst1() { region r; diff --git a/src/test/lp.cpp b/src/test/lp.cpp index 9e05112f5..f76850e38 100644 --- a/src/test/lp.cpp +++ b/src/test/lp.cpp @@ -19,10 +19,10 @@ Author: Lev Nachmanson #include "util/lp/lp_utils.h" #include "util/lp/lp_primal_simplex.h" #include "util/lp/mps_reader.h" -#include "smt_reader.h" +#include "test/smt_reader.h" #include "util/lp/binary_heap_priority_queue.h" -#include "argument_parser.h" -#include "test_file_reader.h" +#include "test/argument_parser.h" +#include "test/test_file_reader.h" #include "util/lp/indexed_value.h" #include "util/lp/lar_solver.h" #include "util/lp/numeric_pair.h" diff --git a/src/test/main.cpp b/src/test/main.cpp index c05488370..17ac720dc 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -2,13 +2,13 @@ #include #include #include -#include"util.h" -#include"trace.h" -#include"debug.h" -#include"timeit.h" -#include"warning.h" -#include "memory_manager.h" -#include"gparams.h" +#include "util/util.h" +#include "util/trace.h" +#include "util/debug.h" +#include "util/timeit.h" +#include "util/warning.h" +#include "util/memory_manager.h" +#include "util/gparams.h" // // Unit tests fail by asserting. diff --git a/src/test/map.cpp b/src/test/map.cpp index c0b084b73..5d59e1e2f 100644 --- a/src/test/map.cpp +++ b/src/test/map.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"map.h" -#include"str_hashtable.h" +#include "util/map.h" +#include "util/str_hashtable.h" static void tst1() { map str2int; diff --git a/src/test/matcher.cpp b/src/test/matcher.cpp index 598a82ae3..cd220a9c6 100644 --- a/src/test/matcher.cpp +++ b/src/test/matcher.cpp @@ -17,9 +17,9 @@ Revision History: --*/ #ifdef _WINDOWS -#include"matcher.h" -#include"ast_pp.h" -#include "reg_decl_plugins.h" +#include "ast/substitution/matcher.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" void tst_match(ast_manager & m, app * t, app * i) { diff --git a/src/test/memory.cpp b/src/test/memory.cpp index 340a1929c..48ba35b78 100644 --- a/src/test/memory.cpp +++ b/src/test/memory.cpp @@ -5,11 +5,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ #ifdef _WINDOWS -#include "z3.h" -#include "z3_private.h" +#include "api/z3.h" +#include "api/z3_private.h" #include -#include "util.h" -#include "trace.h" +#include "util/util.h" +#include "util/trace.h" static bool oom = false; diff --git a/src/test/model2expr.cpp b/src/test/model2expr.cpp index f96cee55f..457fc1751 100644 --- a/src/test/model2expr.cpp +++ b/src/test/model2expr.cpp @@ -4,11 +4,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "model2expr.h" -#include "ast_pp.h" -#include "arith_decl_plugin.h" -#include "model_smt2_pp.h" -#include "reg_decl_plugins.h" +#include "model/model2expr.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "model/model_smt2_pp.h" +#include "ast/reg_decl_plugins.h" void tst_model2expr() { ast_manager m; diff --git a/src/test/model_based_opt.cpp b/src/test/model_based_opt.cpp index 5ee671a4a..2f8cf9941 100644 --- a/src/test/model_based_opt.cpp +++ b/src/test/model_based_opt.cpp @@ -1,6 +1,6 @@ -#include "model_based_opt.h" -#include "util.h" -#include "uint_set.h" +#include "math/simplex/model_based_opt.h" +#include "util/util.h" +#include "util/uint_set.h" typedef opt::model_based_opt::var var; diff --git a/src/test/model_evaluator.cpp b/src/test/model_evaluator.cpp index 00048b230..68a24e792 100644 --- a/src/test/model_evaluator.cpp +++ b/src/test/model_evaluator.cpp @@ -1,9 +1,9 @@ -#include "model.h" -#include "model_evaluator.h" -#include "model_pp.h" -#include "arith_decl_plugin.h" -#include "reg_decl_plugins.h" -#include "ast_pp.h" +#include "model/model.h" +#include "model/model_evaluator.h" +#include "model/model_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/reg_decl_plugins.h" +#include "ast/ast_pp.h" void tst_model_evaluator() { diff --git a/src/test/model_retrieval.cpp b/src/test/model_retrieval.cpp index e42e22539..e0fd28088 100644 --- a/src/test/model_retrieval.cpp +++ b/src/test/model_retrieval.cpp @@ -5,14 +5,14 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ast.h" -#include "smt_params.h" -#include "smt_context.h" -#include "arith_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "array_decl_plugin.h" -#include "model_v2_pp.h" -#include "reg_decl_plugins.h" +#include "ast/ast.h" +#include "smt/params/smt_params.h" +#include "smt/smt_context.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "model/model_v2_pp.h" +#include "ast/reg_decl_plugins.h" void tst_model_retrieval() { diff --git a/src/test/mpbq.cpp b/src/test/mpbq.cpp index 97f8822a9..4dc92d80d 100644 --- a/src/test/mpbq.cpp +++ b/src/test/mpbq.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include "mpbq.h" +#include "util/mpbq.h" static void tst1() { unsynch_mpz_manager zm; diff --git a/src/test/mpf.cpp b/src/test/mpf.cpp index f00152b09..6e3dfb67f 100644 --- a/src/test/mpf.cpp +++ b/src/test/mpf.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"mpf.h" -#include"f2n.h" +#include "util/mpf.h" +#include "util/f2n.h" static void bug_set_int() { mpf_manager fm; diff --git a/src/test/mpff.cpp b/src/test/mpff.cpp index af67d9ff5..73ed114a7 100644 --- a/src/test/mpff.cpp +++ b/src/test/mpff.cpp @@ -17,9 +17,9 @@ Revision History: --*/ #include -#include"mpff.h" -#include"mpz.h" -#include"mpq.h" +#include "util/mpff.h" +#include "util/mpz.h" +#include "util/mpq.h" static void tst1() { try { diff --git a/src/test/mpfx.cpp b/src/test/mpfx.cpp index c83f73bad..f9dc123f5 100644 --- a/src/test/mpfx.cpp +++ b/src/test/mpfx.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"mpfx.h" +#include "util/mpfx.h" static void tst1() { mpfx_manager m; diff --git a/src/test/mpq.cpp b/src/test/mpq.cpp index 0da7a584a..7b60d9dcb 100644 --- a/src/test/mpq.cpp +++ b/src/test/mpq.cpp @@ -17,9 +17,9 @@ Revision History: --*/ -#include"mpq.h" -#include"rational.h" -#include"timeit.h" +#include "util/mpq.h" +#include "util/rational.h" +#include "util/timeit.h" static void tst0() { synch_mpq_manager m; diff --git a/src/test/mpz.cpp b/src/test/mpz.cpp index 1c587f8e9..7926388df 100644 --- a/src/test/mpz.cpp +++ b/src/test/mpz.cpp @@ -17,10 +17,10 @@ Revision History: --*/ -#include"mpz.h" -#include"rational.h" -#include"timeit.h" -#include"scoped_numeral.h" +#include "util/mpz.h" +#include "util/rational.h" +#include "util/timeit.h" +#include "util/scoped_numeral.h" static void tst1() { synch_mpz_manager m; diff --git a/src/test/nlarith_util.cpp b/src/test/nlarith_util.cpp index 2def66b38..4769c1591 100644 --- a/src/test/nlarith_util.cpp +++ b/src/test/nlarith_util.cpp @@ -4,10 +4,10 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "nlarith_util.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" -#include "reg_decl_plugins.h" +#include "qe/nlarith_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" void tst_nlarith_util() { ast_manager M; diff --git a/src/test/nlsat.cpp b/src/test/nlsat.cpp index ccb534214..4d9d4579e 100644 --- a/src/test/nlsat.cpp +++ b/src/test/nlsat.cpp @@ -16,14 +16,14 @@ Author: Notes: --*/ -#include"nlsat_assignment.h" -#include"nlsat_interval_set.h" -#include"nlsat_evaluator.h" -#include"nlsat_solver.h" -#include"util.h" -#include"nlsat_explain.h" -#include"polynomial_cache.h" -#include"rlimit.h" +#include "nlsat/nlsat_assignment.h" +#include "nlsat/nlsat_interval_set.h" +#include "nlsat/nlsat_evaluator.h" +#include "nlsat/nlsat_solver.h" +#include "util/util.h" +#include "nlsat/nlsat_explain.h" +#include "math/polynomial/polynomial_cache.h" +#include "util/rlimit.h" nlsat::interval_set_ref tst_interval(nlsat::interval_set_ref const & s1, nlsat::interval_set_ref const & s2, diff --git a/src/test/no_overflow.cpp b/src/test/no_overflow.cpp index c528b0dbe..bb87b1d30 100644 --- a/src/test/no_overflow.cpp +++ b/src/test/no_overflow.cpp @@ -18,9 +18,9 @@ Revision History: --*/ #ifdef _WINDOWS -#include "z3.h" -#include "trace.h" -#include "rational.h" +#include "api/z3.h" +#include "util/trace.h" +#include "util/rational.h" #define TEST(TEST_NAME, TEST_OUTCOME, NEG_TEST_OUTCOME) \ do { \ diff --git a/src/test/object_allocator.cpp b/src/test/object_allocator.cpp index 3ea646c0c..ce2ae124c 100644 --- a/src/test/object_allocator.cpp +++ b/src/test/object_allocator.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"rational.h" -#include"object_allocator.h" +#include "util/rational.h" +#include "util/object_allocator.h" struct cell { rational m_coeff; diff --git a/src/test/old_interval.cpp b/src/test/old_interval.cpp index da41d0d38..4ab8b0dd0 100644 --- a/src/test/old_interval.cpp +++ b/src/test/old_interval.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"old_interval.h" +#include "smt/old_interval.h" static void tst1() { ext_numeral inf(true); @@ -166,9 +166,9 @@ public: } }; -#include"basic_interval.h" -#include"mpz.h" -#include"scoped_numeral.h" +#include "util/basic_interval.h" +#include "util/mpz.h" +#include "util/scoped_numeral.h" static void tst2() { typedef basic_interval_manager mpzi_manager; diff --git a/src/test/optional.cpp b/src/test/optional.cpp index 40ca383a5..46dfef82c 100644 --- a/src/test/optional.cpp +++ b/src/test/optional.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"trace.h" -#include"debug.h" -#include"optional.h" +#include "util/trace.h" +#include "util/debug.h" +#include "util/optional.h" static void tst1() { optional v; diff --git a/src/test/parray.cpp b/src/test/parray.cpp index df0fde516..6aef4f359 100644 --- a/src/test/parray.cpp +++ b/src/test/parray.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"parray.h" -#include"small_object_allocator.h" -#include"ast.h" +#include "util/parray.h" +#include "util/small_object_allocator.h" +#include "ast/ast.h" template struct int_parray_config { diff --git a/src/test/pb2bv.cpp b/src/test/pb2bv.cpp index 07cb047b3..632b2d642 100644 --- a/src/test/pb2bv.cpp +++ b/src/test/pb2bv.cpp @@ -3,21 +3,21 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "trace.h" -#include "vector.h" -#include "ast.h" -#include "ast_pp.h" -#include "statistics.h" -#include "reg_decl_plugins.h" -#include "pb2bv_rewriter.h" -#include "smt_kernel.h" -#include "model_smt2_pp.h" -#include "smt_params.h" -#include "ast_util.h" -#include "pb_decl_plugin.h" -#include "th_rewriter.h" -#include "fd_solver.h" -#include "solver.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "util/statistics.h" +#include "ast/reg_decl_plugins.h" +#include "ast/rewriter/pb2bv_rewriter.h" +#include "smt/smt_kernel.h" +#include "model/model_smt2_pp.h" +#include "smt/params/smt_params.h" +#include "ast/ast_util.h" +#include "ast/pb_decl_plugin.h" +#include "ast/rewriter/th_rewriter.h" +#include "tactic/portfolio/fd_solver.h" +#include "solver/solver.h" static void test1() { ast_manager m; diff --git a/src/test/pdr.cpp b/src/test/pdr.cpp index d95a55a24..7e2f1a5ad 100644 --- a/src/test/pdr.cpp +++ b/src/test/pdr.cpp @@ -4,8 +4,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "pdr_context.h" -#include "reg_decl_plugins.h" +#include "muz/pdr/pdr_context.h" +#include "ast/reg_decl_plugins.h" using namespace pdr; diff --git a/src/test/permutation.cpp b/src/test/permutation.cpp index e0d208520..74b97a365 100644 --- a/src/test/permutation.cpp +++ b/src/test/permutation.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"permutation.h" -#include"util.h" -#include"vector.h" +#include "util/permutation.h" +#include "util/util.h" +#include "util/vector.h" void apply_permutation_copy(unsigned sz, unsigned const * src, unsigned const * p, unsigned * target) { for (unsigned i = 0; i < sz; i++) { diff --git a/src/test/polynomial.cpp b/src/test/polynomial.cpp index 0a6418a6c..00998a181 100644 --- a/src/test/polynomial.cpp +++ b/src/test/polynomial.cpp @@ -17,11 +17,11 @@ Notes: --*/ #if !defined(__clang__) -#include"polynomial.h" -#include"polynomial_var2value.h" -#include"polynomial_cache.h" -#include"linear_eq_solver.h" -#include"rlimit.h" +#include "math/polynomial/polynomial.h" +#include "math/polynomial/polynomial_var2value.h" +#include "math/polynomial/polynomial_cache.h" +#include "math/polynomial/linear_eq_solver.h" +#include "util/rlimit.h" static void tst1() { std::cout << "\n----- Basic testing -------\n"; diff --git a/src/test/polynorm.cpp b/src/test/polynorm.cpp index 03735fef9..22df91b45 100644 --- a/src/test/polynorm.cpp +++ b/src/test/polynorm.cpp @@ -4,12 +4,12 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "th_rewriter.h" -#include "smt2parser.h" -#include "arith_decl_plugin.h" -#include "reg_decl_plugins.h" -#include "arith_rewriter.h" -#include "ast_pp.h" +#include "ast/rewriter/th_rewriter.h" +#include "parsers/smt2/smt2parser.h" +#include "ast/arith_decl_plugin.h" +#include "ast/reg_decl_plugins.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/ast_pp.h" static expr_ref parse_fml(ast_manager& m, char const* str) { diff --git a/src/test/prime_generator.cpp b/src/test/prime_generator.cpp index 5af014e0a..12c38ef78 100644 --- a/src/test/prime_generator.cpp +++ b/src/test/prime_generator.cpp @@ -16,8 +16,8 @@ Author: Notes: --*/ -#include"mpz.h" -#include"prime_generator.h" +#include "util/mpz.h" +#include "util/prime_generator.h" void tst_prime_generator() { unsynch_mpz_manager m; diff --git a/src/test/proof_checker.cpp b/src/test/proof_checker.cpp index 035326b26..adf77e12e 100644 --- a/src/test/proof_checker.cpp +++ b/src/test/proof_checker.cpp @@ -4,8 +4,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "proof_checker.h" -#include "ast_ll_pp.h" +#include "ast/proof_checker/proof_checker.h" +#include "ast/ast_ll_pp.h" void tst_checker1() { ast_manager m(PGM_FINE); diff --git a/src/test/qe_arith.cpp b/src/test/qe_arith.cpp index 83b6e2620..d18e0f717 100644 --- a/src/test/qe_arith.cpp +++ b/src/test/qe_arith.cpp @@ -4,17 +4,17 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "qe_arith.h" -#include "qe.h" -#include "th_rewriter.h" -#include "smt2parser.h" -#include "arith_decl_plugin.h" -#include "reg_decl_plugins.h" -#include "arith_rewriter.h" -#include "ast_pp.h" -#include "smt_context.h" -#include "expr_abstract.h" -#include "expr_safe_replace.h" +#include "qe/qe_arith.h" +#include "qe/qe.h" +#include "ast/rewriter/th_rewriter.h" +#include "parsers/smt2/smt2parser.h" +#include "ast/arith_decl_plugin.h" +#include "ast/reg_decl_plugins.h" +#include "ast/rewriter/arith_rewriter.h" +#include "ast/ast_pp.h" +#include "smt/smt_context.h" +#include "ast/expr_abstract.h" +#include "ast/rewriter/expr_safe_replace.h" static expr_ref parse_fml(ast_manager& m, char const* str) { expr_ref result(m); diff --git a/src/test/quant_elim.cpp b/src/test/quant_elim.cpp index 0fe7f8eec..fec86d164 100644 --- a/src/test/quant_elim.cpp +++ b/src/test/quant_elim.cpp @@ -4,20 +4,20 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ast.h" -#include "smt_params.h" -#include "simplifier.h" -#include "qe.h" -#include "basic_simplifier_plugin.h" -#include "arith_simplifier_plugin.h" -#include "array_simplifier_plugin.h" -#include "bv_simplifier_plugin.h" -#include "ast_pp.h" -#include "smtlib.h" -#include "smtparser.h" -#include "lbool.h" +#include "ast/ast.h" +#include "smt/params/smt_params.h" +#include "ast/simplifier/simplifier.h" +#include "qe/qe.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/array_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/ast_pp.h" +#include "parsers/smt/smtlib.h" +#include "parsers/smt/smtparser.h" +#include "util/lbool.h" #include -#include "reg_decl_plugins.h" +#include "ast/reg_decl_plugins.h" static void test_qe(ast_manager& m, lbool expected_outcome, expr* fml, char const* option) { diff --git a/src/test/quant_solve.cpp b/src/test/quant_solve.cpp index 2dc987d77..ac334c718 100644 --- a/src/test/quant_solve.cpp +++ b/src/test/quant_solve.cpp @@ -4,20 +4,20 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ast.h" -#include "smt_params.h" -#include "qe.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" -#include "lbool.h" +#include "ast/ast.h" +#include "smt/params/smt_params.h" +#include "qe/qe.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "util/lbool.h" #include -#include "expr_replacer.h" -#include "smt_kernel.h" -#include "reg_decl_plugins.h" -#include "expr_abstract.h" -#include "model_smt2_pp.h" -#include "smt2parser.h" -#include "var_subst.h" +#include "ast/rewriter/expr_replacer.h" +#include "smt/smt_kernel.h" +#include "ast/reg_decl_plugins.h" +#include "ast/expr_abstract.h" +#include "model/model_smt2_pp.h" +#include "parsers/smt2/smt2parser.h" +#include "ast/rewriter/var_subst.h" static void validate_quant_solution(ast_manager& m, expr* fml, expr* guard, qe::def_vector const& defs) { // verify: diff --git a/src/test/random.cpp b/src/test/random.cpp index a813b0f08..89d5a24cf 100644 --- a/src/test/random.cpp +++ b/src/test/random.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"util.h" -#include"trace.h" +#include "util/util.h" +#include "util/trace.h" static void tst1() { random_gen r(0); diff --git a/src/test/rational.cpp b/src/test/rational.cpp index 6fa1005b0..7b5e474f0 100644 --- a/src/test/rational.cpp +++ b/src/test/rational.cpp @@ -17,11 +17,11 @@ Revision History: --*/ #include -#include"vector.h" -#include"rational.h" -#include"trace.h" -#include"ext_gcd.h" -#include"timeit.h" +#include "util/vector.h" +#include "util/rational.h" +#include "util/trace.h" +#include "util/ext_gcd.h" +#include "util/timeit.h" static void tst1() { rational r1(1); diff --git a/src/test/rcf.cpp b/src/test/rcf.cpp index 082147190..2f97d49d2 100644 --- a/src/test/rcf.cpp +++ b/src/test/rcf.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"realclosure.h" -#include"mpz_matrix.h" -#include"rlimit.h" +#include "math/realclosure/realclosure.h" +#include "math/realclosure/mpz_matrix.h" +#include "util/rlimit.h" static void tst1() { unsynch_mpq_manager qm; diff --git a/src/test/region.cpp b/src/test/region.cpp index 83127d552..9cd2e504d 100644 --- a/src/test/region.cpp +++ b/src/test/region.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include -#include"region.h" +#include "util/region.h" static void tst1() { // TODO diff --git a/src/test/sat_user_scope.cpp b/src/test/sat_user_scope.cpp index 7e3d50e8d..10abb44c3 100644 --- a/src/test/sat_user_scope.cpp +++ b/src/test/sat_user_scope.cpp @@ -4,8 +4,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "sat_solver.h" -#include "util.h" +#include "sat/sat_solver.h" +#include "util/util.h" typedef sat::literal_vector clause_t; typedef vector clauses_t; diff --git a/src/test/simple_parser.cpp b/src/test/simple_parser.cpp index 934552711..1ba0d4b62 100644 --- a/src/test/simple_parser.cpp +++ b/src/test/simple_parser.cpp @@ -16,13 +16,13 @@ Author: Revision History: --*/ -#include"cost_parser.h" -#include"cost_evaluator.h" -#include"arith_decl_plugin.h" -#include"ast_pp.h" -#include"well_sorted.h" -#include"warning.h" -#include"reg_decl_plugins.h" +#include "parsers/util/cost_parser.h" +#include "smt/cost_evaluator.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/well_sorted.h" +#include "util/warning.h" +#include "ast/reg_decl_plugins.h" void tst_simple_parser() { ast_manager m; diff --git a/src/test/simplex.cpp b/src/test/simplex.cpp index 8e57f6110..6620dc83b 100644 --- a/src/test/simplex.cpp +++ b/src/test/simplex.cpp @@ -4,14 +4,14 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "sparse_matrix.h" -#include "sparse_matrix_def.h" -#include "simplex.h" -#include "simplex_def.h" -#include "mpq_inf.h" -#include "vector.h" -#include "rational.h" -#include "rlimit.h" +#include "util/lp/sparse_matrix.h" +#include "math/simplex/sparse_matrix_def.h" +#include "math/simplex/simplex.h" +#include "math/simplex/simplex_def.h" +#include "util/mpq_inf.h" +#include "util/vector.h" +#include "util/rational.h" +#include "util/rlimit.h" #define R rational typedef simplex::simplex Simplex; diff --git a/src/test/simplifier.cpp b/src/test/simplifier.cpp index 5a05ab30f..a42ed86b1 100644 --- a/src/test/simplifier.cpp +++ b/src/test/simplifier.cpp @@ -5,11 +5,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ #ifdef _WINDOWS -#include "z3.h" -#include "z3_private.h" +#include "api/z3.h" +#include "api/z3_private.h" #include -#include "util.h" -#include "trace.h" +#include "util/util.h" +#include "util/trace.h" static void ev_const(Z3_context ctx, Z3_ast e) { diff --git a/src/test/small_object_allocator.cpp b/src/test/small_object_allocator.cpp index 5ae2836d0..cdac0370d 100644 --- a/src/test/small_object_allocator.cpp +++ b/src/test/small_object_allocator.cpp @@ -5,9 +5,9 @@ Copyright (c) 2015 Microsoft Corporation --*/ #include -#include"util.h" -#include"trace.h" -#include"small_object_allocator.h" +#include "util/util.h" +#include "util/trace.h" +#include "util/small_object_allocator.h" void tst_small_object_allocator() { small_object_allocator soa; diff --git a/src/test/smt2print_parse.cpp b/src/test/smt2print_parse.cpp index c79a80ae5..80a57c7d5 100644 --- a/src/test/smt2print_parse.cpp +++ b/src/test/smt2print_parse.cpp @@ -7,7 +7,7 @@ Copyright (c) 2015 Microsoft Corporation // This is to test the print-parse facilities over the API // for SMT-LIB2. -#include "z3.h" +#include "api/z3.h" #include void test_print(Z3_context ctx, Z3_ast a) { diff --git a/src/test/smt_context.cpp b/src/test/smt_context.cpp index 6c44b8b1d..d2ee858e5 100644 --- a/src/test/smt_context.cpp +++ b/src/test/smt_context.cpp @@ -4,8 +4,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "smt_context.h" -#include "reg_decl_plugins.h" +#include "smt/smt_context.h" +#include "ast/reg_decl_plugins.h" void tst_smt_context() { diff --git a/src/test/sorting_network.cpp b/src/test/sorting_network.cpp index 9836bc04d..909ea594e 100644 --- a/src/test/sorting_network.cpp +++ b/src/test/sorting_network.cpp @@ -4,16 +4,16 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "trace.h" -#include "vector.h" -#include "ast.h" -#include "ast_pp.h" -#include "reg_decl_plugins.h" -#include "sorting_network.h" -#include "smt_kernel.h" -#include "model_smt2_pp.h" -#include "smt_params.h" -#include "ast_util.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" +#include "util/sorting_network.h" +#include "smt/smt_kernel.h" +#include "model/model_smt2_pp.h" +#include "smt/params/smt_params.h" +#include "ast/ast_util.h" diff --git a/src/test/stack.cpp b/src/test/stack.cpp index c8f3d88a6..ddd2f85e9 100644 --- a/src/test/stack.cpp +++ b/src/test/stack.cpp @@ -16,8 +16,8 @@ Notes: --*/ #include -#include"stack.h" -#include"vector.h" +#include "util/stack.h" +#include "util/vector.h" typedef std::pair point; diff --git a/src/test/string_buffer.cpp b/src/test/string_buffer.cpp index 7d7854a9c..b3e3ce79d 100644 --- a/src/test/string_buffer.cpp +++ b/src/test/string_buffer.cpp @@ -17,9 +17,9 @@ Revision History: --*/ #include -#include"debug.h" -#include"string_buffer.h" -#include"trace.h" +#include "util/debug.h" +#include "util/string_buffer.h" +#include "util/trace.h" static void tst1() { string_buffer<> b; diff --git a/src/test/substitution.cpp b/src/test/substitution.cpp index 5609225c6..b713dfcfe 100644 --- a/src/test/substitution.cpp +++ b/src/test/substitution.cpp @@ -4,14 +4,14 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "expr_substitution.h" -#include "smt_params.h" -#include "substitution.h" -#include "unifier.h" -#include "bv_decl_plugin.h" -#include "ast_pp.h" -#include "arith_decl_plugin.h" -#include "reg_decl_plugins.h" +#include "ast/expr_substitution.h" +#include "smt/params/smt_params.h" +#include "ast/substitution/substitution.h" +#include "ast/substitution/unifier.h" +#include "ast/bv_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/reg_decl_plugins.h" void tst_substitution() { diff --git a/src/test/symbol.cpp b/src/test/symbol.cpp index e91332285..88dd02d73 100644 --- a/src/test/symbol.cpp +++ b/src/test/symbol.cpp @@ -17,8 +17,8 @@ Revision History: --*/ #include -#include"symbol.h" -#include"debug.h" +#include "util/symbol.h" +#include "util/debug.h" static void tst1() { symbol s1("foo"); diff --git a/src/test/symbol_table.cpp b/src/test/symbol_table.cpp index 626e2a72f..da1830ceb 100644 --- a/src/test/symbol_table.cpp +++ b/src/test/symbol_table.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"symbol_table.h" +#include "util/symbol_table.h" static void tst1() { symbol_table t; diff --git a/src/test/tbv.cpp b/src/test/tbv.cpp index 00f7e0960..2bfd14047 100644 --- a/src/test/tbv.cpp +++ b/src/test/tbv.cpp @@ -4,7 +4,7 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "tbv.h" +#include "muz/rel/tbv.h" static void tst1(unsigned num_bits) { tbv_manager m(num_bits); diff --git a/src/test/test_util.h b/src/test/test_util.h index c81524b0e..f04af761f 100644 --- a/src/test/test_util.h +++ b/src/test/test_util.h @@ -6,7 +6,7 @@ Copyright (c) 2015 Microsoft Corporation #pragma once -#include "stopwatch.h" +#include "util/stopwatch.h" struct test_context { bool test_ok; diff --git a/src/test/theory_dl.cpp b/src/test/theory_dl.cpp index 463625c88..9a28f3653 100644 --- a/src/test/theory_dl.cpp +++ b/src/test/theory_dl.cpp @@ -4,11 +4,11 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "smt_context.h" -#include "dl_decl_plugin.h" -#include "ast_pp.h" -#include "model_v2_pp.h" -#include "reg_decl_plugins.h" +#include "smt/smt_context.h" +#include "ast/dl_decl_plugin.h" +#include "ast/ast_pp.h" +#include "model/model_v2_pp.h" +#include "ast/reg_decl_plugins.h" void tst_theory_dl() { ast_manager m; diff --git a/src/test/theory_pb.cpp b/src/test/theory_pb.cpp index 42a03f619..8fcbde706 100644 --- a/src/test/theory_pb.cpp +++ b/src/test/theory_pb.cpp @@ -4,12 +4,12 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "smt_context.h" -#include "ast_pp.h" -#include "model_v2_pp.h" -#include "reg_decl_plugins.h" -#include "theory_pb.h" -#include "th_rewriter.h" +#include "smt/smt_context.h" +#include "ast/ast_pp.h" +#include "model/model_v2_pp.h" +#include "ast/reg_decl_plugins.h" +#include "smt/theory_pb.h" +#include "ast/rewriter/th_rewriter.h" unsigned populate_literals(unsigned k, smt::literal_vector& lits) { ENSURE(k < (1u << lits.size())); diff --git a/src/test/timeout.cpp b/src/test/timeout.cpp index 320006928..80b28a691 100644 --- a/src/test/timeout.cpp +++ b/src/test/timeout.cpp @@ -5,8 +5,8 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "timeout.h" -#include "trace.h" +#include "util/timeout.h" +#include "util/trace.h" #ifdef _WINDOWS diff --git a/src/test/total_order.cpp b/src/test/total_order.cpp index 12bb4d977..a2ee234db 100644 --- a/src/test/total_order.cpp +++ b/src/test/total_order.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"total_order.h" -#include"timeit.h" +#include "util/total_order.h" +#include "util/timeit.h" static void tst1() { uint_total_order to; diff --git a/src/test/trigo.cpp b/src/test/trigo.cpp index 809d94fc2..c1b73c423 100644 --- a/src/test/trigo.cpp +++ b/src/test/trigo.cpp @@ -17,13 +17,13 @@ Revision History: --*/ #include -#include"interval_def.h" -#include"dependency.h" -#include"mpq.h" -#include"ast.h" -#include"debug.h" -#include"im_float_config.h" -#include"rlimit.h" +#include "math/interval/interval_def.h" +#include "util/dependency.h" +#include "util/mpq.h" +#include "ast/ast.h" +#include "util/debug.h" +#include "test/im_float_config.h" +#include "util/rlimit.h" #define PREC 100000 diff --git a/src/test/udoc_relation.cpp b/src/test/udoc_relation.cpp index 57866c3ac..5f1bd7b36 100644 --- a/src/test/udoc_relation.cpp +++ b/src/test/udoc_relation.cpp @@ -4,24 +4,24 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "udoc_relation.h" -#include "trace.h" -#include "vector.h" -#include "ast.h" -#include "ast_pp.h" -#include "reg_decl_plugins.h" -#include "sorting_network.h" -#include "smt_kernel.h" -#include "model_smt2_pp.h" -#include "smt_params.h" -#include "ast_util.h" -#include "expr_safe_replace.h" -#include "th_rewriter.h" -#include "dl_relation_manager.h" -#include "dl_register_engine.h" -#include "rel_context.h" -#include "bv_decl_plugin.h" -#include "check_relation.h" +#include "muz/rel/udoc_relation.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "ast/reg_decl_plugins.h" +#include "util/sorting_network.h" +#include "smt/smt_kernel.h" +#include "model/model_smt2_pp.h" +#include "smt/params/smt_params.h" +#include "ast/ast_util.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/rewriter/th_rewriter.h" +#include "muz/rel/dl_relation_manager.h" +#include "muz/fp/dl_register_engine.h" +#include "muz/rel/rel_context.h" +#include "ast/bv_decl_plugin.h" +#include "muz/rel/check_relation.h" class udoc_tester { diff --git a/src/test/uint_set.cpp b/src/test/uint_set.cpp index 3134ada7b..bcab106cc 100644 --- a/src/test/uint_set.cpp +++ b/src/test/uint_set.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"uint_set.h" -#include"vector.h" +#include "util/uint_set.h" +#include "util/vector.h" static void tst1(unsigned n) { uint_set s1; @@ -131,7 +131,7 @@ static void tst4() { ENSURE(!s.contains(0)); } -#include "map.h" +#include "util/map.h" template struct uint_map : public map {}; diff --git a/src/test/upolynomial.cpp b/src/test/upolynomial.cpp index 4c8358b3a..fa106fe3f 100644 --- a/src/test/upolynomial.cpp +++ b/src/test/upolynomial.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"upolynomial.h" -#include"timeit.h" -#include"rlimit.h" +#include "math/polynomial/upolynomial.h" +#include "util/timeit.h" +#include "util/rlimit.h" static void tst1() { reslimit rl; diff --git a/src/test/var_subst.cpp b/src/test/var_subst.cpp index f90292d11..169b1e131 100644 --- a/src/test/var_subst.cpp +++ b/src/test/var_subst.cpp @@ -16,13 +16,13 @@ Author: Revision History: --*/ -#include"var_subst.h" -#include"ast_pp.h" -#include"arith_decl_plugin.h" -#include"bv_decl_plugin.h" -#include"array_decl_plugin.h" -#include"for_each_expr.h" -#include"reg_decl_plugins.h" +#include "ast/rewriter/var_subst.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/for_each_expr.h" +#include "ast/reg_decl_plugins.h" namespace find_q { struct proc { diff --git a/src/test/vector.cpp b/src/test/vector.cpp index f7d70a87b..4632a9c29 100644 --- a/src/test/vector.cpp +++ b/src/test/vector.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"vector.h" +#include "util/vector.h" static void tst1() { svector v1; diff --git a/src/util/approx_nat.cpp b/src/util/approx_nat.cpp index 0739a65aa..cf0c17029 100644 --- a/src/util/approx_nat.cpp +++ b/src/util/approx_nat.cpp @@ -17,7 +17,7 @@ Author: Notes: --*/ -#include"approx_nat.h" +#include "util/approx_nat.h" approx_nat::approx_nat(unsigned val) { m_value = val > m_limit ? UINT_MAX : val; diff --git a/src/util/approx_set.cpp b/src/util/approx_set.cpp index e6757cf05..521197137 100644 --- a/src/util/approx_set.cpp +++ b/src/util/approx_set.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"approx_set.h" +#include "util/approx_set.h" void approx_set::display(std::ostream & out) const { out << "{"; diff --git a/src/util/approx_set.h b/src/util/approx_set.h index c0f3d39dd..e696d52ee 100644 --- a/src/util/approx_set.h +++ b/src/util/approx_set.h @@ -19,7 +19,7 @@ Revision History: #ifndef APPROX_SET_H_ #define APPROX_SET_H_ #include -#include"debug.h" +#include "util/debug.h" template class approx_set_traits; diff --git a/src/util/array_map.h b/src/util/array_map.h index 14d404e9d..c5163715e 100644 --- a/src/util/array_map.h +++ b/src/util/array_map.h @@ -19,8 +19,8 @@ Revision History: #ifndef ARRAY_MAP_H_ #define ARRAY_MAP_H_ -#include"vector.h" -#include"optional.h" +#include "util/vector.h" +#include "util/optional.h" /** \brief Implements a mapping from Key to Data. diff --git a/src/util/backtrackable_set.h b/src/util/backtrackable_set.h index ea82a5c81..13a741cff 100644 --- a/src/util/backtrackable_set.h +++ b/src/util/backtrackable_set.h @@ -19,7 +19,7 @@ Revision History: #ifndef BACKTRACKABLE_SET_H_ #define BACKTRACKABLE_SET_H_ -#include"vector.h" +#include "util/vector.h" template struct default_eh { diff --git a/src/util/bit_util.cpp b/src/util/bit_util.cpp index fde66b054..a38f42fdd 100644 --- a/src/util/bit_util.cpp +++ b/src/util/bit_util.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"bit_util.h" -#include"util.h" -#include"debug.h" +#include "util/bit_util.h" +#include "util/util.h" +#include "util/debug.h" #include /** diff --git a/src/util/bit_vector.cpp b/src/util/bit_vector.cpp index c15a743a9..f9f0a0797 100644 --- a/src/util/bit_vector.cpp +++ b/src/util/bit_vector.cpp @@ -17,8 +17,8 @@ Revision History: --*/ #include -#include"bit_vector.h" -#include"trace.h" +#include "util/bit_vector.h" +#include "util/trace.h" #define DEFAULT_CAPACITY 2 diff --git a/src/util/bit_vector.h b/src/util/bit_vector.h index a8c348aeb..6a254e399 100644 --- a/src/util/bit_vector.h +++ b/src/util/bit_vector.h @@ -20,9 +20,9 @@ Revision History: #define BIT_VECTOR_H_ #include -#include"debug.h" -#include"vector.h" -#include"memory_manager.h" +#include "util/debug.h" +#include "util/vector.h" +#include "util/memory_manager.h" COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); #define BV_DEFAULT_CAPACITY 2 diff --git a/src/util/buffer.h b/src/util/buffer.h index 422db07aa..503788fa0 100644 --- a/src/util/buffer.h +++ b/src/util/buffer.h @@ -20,7 +20,7 @@ Revision History: #define BUFFER_H_ #include -#include"memory_manager.h" +#include "util/memory_manager.h" template class buffer { diff --git a/src/util/cancel_eh.h b/src/util/cancel_eh.h index d23e5f544..4347a5b52 100644 --- a/src/util/cancel_eh.h +++ b/src/util/cancel_eh.h @@ -19,7 +19,7 @@ Revision History: #ifndef CANCEL_EH_H_ #define CANCEL_EH_H_ -#include"event_handler.h" +#include "util/event_handler.h" /** \brief Generic event handler for invoking cancel method. diff --git a/src/util/chashtable.h b/src/util/chashtable.h index cdc6e6295..69c48207a 100644 --- a/src/util/chashtable.h +++ b/src/util/chashtable.h @@ -28,11 +28,11 @@ Revision History: #ifndef CHASHTABLE_H_ #define CHASHTABLE_H_ -#include"memory_manager.h" -#include"debug.h" -#include"trace.h" +#include "util/memory_manager.h" +#include "util/debug.h" +#include "util/trace.h" #ifdef Z3DEBUG -#include"hashtable.h" +#include "util/hashtable.h" #endif #define CH_STATISTICS diff --git a/src/util/checked_int64.h b/src/util/checked_int64.h index db1dd2521..a9087e1c2 100644 --- a/src/util/checked_int64.h +++ b/src/util/checked_int64.h @@ -24,8 +24,8 @@ Revision History: #ifndef CHECKED_INT64_H_ #define CHECKED_INT64_H_ -#include"z3_exception.h" -#include"rational.h" +#include "util/z3_exception.h" +#include "util/rational.h" template class checked_int64 { diff --git a/src/util/cmd_context_types.cpp b/src/util/cmd_context_types.cpp index 3d631c28e..61a7bd755 100644 --- a/src/util/cmd_context_types.cpp +++ b/src/util/cmd_context_types.cpp @@ -15,7 +15,7 @@ Notes: --*/ #include -#include"cmd_context_types.h" +#include "util/cmd_context_types.h" std::ostream & operator<<(std::ostream & out, cmd_arg_kind k) { switch (k) { diff --git a/src/util/cmd_context_types.h b/src/util/cmd_context_types.h index 29ac56a49..ae64e2de6 100644 --- a/src/util/cmd_context_types.h +++ b/src/util/cmd_context_types.h @@ -17,8 +17,8 @@ Notes: #ifndef CMD_CONTEXT_TYPES_H_ #define CMD_CONTEXT_TYPES_H_ -#include"symbol.h" -#include"z3_exception.h" +#include "util/symbol.h" +#include "util/z3_exception.h" #include class rational; class expr; diff --git a/src/util/common_msgs.cpp b/src/util/common_msgs.cpp index 412116bb9..f55591b43 100644 --- a/src/util/common_msgs.cpp +++ b/src/util/common_msgs.cpp @@ -16,7 +16,7 @@ Author: Notes: --*/ -#include"common_msgs.h" +#include "util/common_msgs.h" char const * common_msgs::g_canceled_msg = "canceled"; char const * common_msgs::g_max_memory_msg = "max. memory exceeded"; diff --git a/src/util/cooperate.cpp b/src/util/cooperate.cpp index cdd91bfdd..2ae250206 100644 --- a/src/util/cooperate.cpp +++ b/src/util/cooperate.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"cooperate.h" -#include"trace.h" -#include"debug.h" -#include"z3_omp.h" +#include "util/cooperate.h" +#include "util/trace.h" +#include "util/debug.h" +#include "util/z3_omp.h" struct cooperation_lock { omp_nest_lock_t m_lock; diff --git a/src/util/debug.cpp b/src/util/debug.cpp index 66676c619..5d39e7c02 100644 --- a/src/util/debug.cpp +++ b/src/util/debug.cpp @@ -21,8 +21,8 @@ Revision History: #include #endif #include -#include"str_hashtable.h" -#include"z3_exception.h" +#include "util/str_hashtable.h" +#include "util/z3_exception.h" static volatile bool g_enable_assertions = true; diff --git a/src/util/debug.h b/src/util/debug.h index ec0f600b5..adc9fc6b7 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -35,8 +35,8 @@ bool assertions_enabled(); # define __has_builtin(x) 0 #endif -#include"error_codes.h" -#include"warning.h" +#include "util/error_codes.h" +#include "util/warning.h" #ifdef Z3DEBUG #define DEBUG_CODE(CODE) { CODE } ((void) 0) diff --git a/src/util/dependency.h b/src/util/dependency.h index 4c438e520..d6df6d7bf 100644 --- a/src/util/dependency.h +++ b/src/util/dependency.h @@ -19,8 +19,8 @@ Revision History: #ifndef DEPENDENCY_H_ #define DEPENDENCY_H_ -#include"vector.h" -#include"region.h" +#include "util/vector.h" +#include "util/region.h" template class dependency_manager { diff --git a/src/util/dictionary.h b/src/util/dictionary.h index e319e6a27..7dd55bc16 100644 --- a/src/util/dictionary.h +++ b/src/util/dictionary.h @@ -17,8 +17,8 @@ Notes: #ifndef DICTIONARY_H_ #define DICTIONARY_H_ -#include"map.h" -#include"symbol.h" +#include "util/map.h" +#include "util/symbol.h" template class dictionary : public map { diff --git a/src/util/double_manager.h b/src/util/double_manager.h index a426e9b1b..33cccf2af 100644 --- a/src/util/double_manager.h +++ b/src/util/double_manager.h @@ -23,10 +23,10 @@ Revision History: #include #include #include -#include"util.h" -#include"debug.h" -#include"hash.h" -#include"params.h" +#include "util/util.h" +#include "util/debug.h" +#include "util/hash.h" +#include "util/params.h" /** \brief Create an interface for manipulating double numbers compatible with the one for mpq. diff --git a/src/util/env_params.cpp b/src/util/env_params.cpp index 6748598bf..c2b5f7974 100644 --- a/src/util/env_params.cpp +++ b/src/util/env_params.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"env_params.h" -#include"params.h" -#include"gparams.h" -#include"util.h" -#include"memory_manager.h" +#include "util/env_params.h" +#include "util/params.h" +#include "util/gparams.h" +#include "util/util.h" +#include "util/memory_manager.h" void env_params::updt_params() { params_ref p = gparams::get(); diff --git a/src/util/ext_numeral.h b/src/util/ext_numeral.h index a37ec6aee..9cb5a1f09 100644 --- a/src/util/ext_numeral.h +++ b/src/util/ext_numeral.h @@ -21,7 +21,7 @@ Revision History: #define EXT_NUMERAL_H_ #include -#include"debug.h" +#include "util/debug.h" enum ext_numeral_kind { EN_MINUS_INFINITY, EN_NUMERAL, EN_PLUS_INFINITY }; diff --git a/src/util/f2n.h b/src/util/f2n.h index 0f453911d..e5e84f6f0 100644 --- a/src/util/f2n.h +++ b/src/util/f2n.h @@ -20,7 +20,7 @@ Revision History: #ifndef F2N_H_ #define F2N_H_ -#include"mpf.h" +#include "util/mpf.h" template class f2n { diff --git a/src/util/fixed_bit_vector.cpp b/src/util/fixed_bit_vector.cpp index 8843db736..aafc58404 100644 --- a/src/util/fixed_bit_vector.cpp +++ b/src/util/fixed_bit_vector.cpp @@ -20,9 +20,9 @@ Revision History: --*/ #include -#include"fixed_bit_vector.h" -#include"trace.h" -#include"hash.h" +#include "util/fixed_bit_vector.h" +#include "util/trace.h" +#include "util/hash.h" void fixed_bit_vector::set(fixed_bit_vector const& other, unsigned hi, unsigned lo) { if ((lo % 32) == 0) { diff --git a/src/util/fixed_bit_vector.h b/src/util/fixed_bit_vector.h index be840204c..3bbc73248 100644 --- a/src/util/fixed_bit_vector.h +++ b/src/util/fixed_bit_vector.h @@ -22,8 +22,8 @@ Revision History: #define FIXED_BIT_VECTOR_H_ #include -#include"debug.h" -#include"small_object_allocator.h" +#include "util/debug.h" +#include "util/small_object_allocator.h" class fixed_bit_vector { friend class fixed_bit_vector_manager; diff --git a/src/util/gparams.cpp b/src/util/gparams.cpp index 97f84af6a..e71594810 100644 --- a/src/util/gparams.cpp +++ b/src/util/gparams.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"gparams.h" -#include"dictionary.h" -#include"trace.h" +#include "util/gparams.h" +#include "util/dictionary.h" +#include "util/trace.h" extern void gparams_register_modules(); diff --git a/src/util/gparams.h b/src/util/gparams.h index 139640c78..894732890 100644 --- a/src/util/gparams.h +++ b/src/util/gparams.h @@ -19,7 +19,7 @@ Notes: #ifndef GPARAMS_H_ #define GPARAMS_H_ -#include"params.h" +#include "util/params.h" class gparams { struct imp; diff --git a/src/util/hash.cpp b/src/util/hash.cpp index a54f993af..cacf0a220 100644 --- a/src/util/hash.cpp +++ b/src/util/hash.cpp @@ -17,8 +17,8 @@ Revision History: --*/ -#include"debug.h" -#include"hash.h" +#include "util/debug.h" +#include "util/hash.h" #include static unsigned read_unsigned(const char *s) { diff --git a/src/util/hash.h b/src/util/hash.h index 82d343661..7fce04ca8 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -20,7 +20,7 @@ Revision History: #define HASH_H_ #include -#include"util.h" +#include "util/util.h" #define mix(a,b,c) \ { \ diff --git a/src/util/hashtable.h b/src/util/hashtable.h index 44e05319d..020c47b2b 100644 --- a/src/util/hashtable.h +++ b/src/util/hashtable.h @@ -18,12 +18,12 @@ Revision History: --*/ #ifndef HASHTABLE_H_ #define HASHTABLE_H_ -#include"debug.h" +#include "util/debug.h" #include -#include"util.h" +#include "util/util.h" #include -#include"memory_manager.h" -#include"hash.h" +#include "util/memory_manager.h" +#include "util/hash.h" #define DEFAULT_HASHTABLE_INITIAL_CAPACITY 8 #define SMALL_TABLE_CAPACITY 64 diff --git a/src/util/heap.h b/src/util/heap.h index 14e902648..02e30bf04 100644 --- a/src/util/heap.h +++ b/src/util/heap.h @@ -19,8 +19,8 @@ Revision History: #ifndef HEAP_H_ #define HEAP_H_ -#include"vector.h" -#include"debug.h" +#include "util/vector.h" +#include "util/debug.h" template class heap : private LT { diff --git a/src/util/hwf.cpp b/src/util/hwf.cpp index a522c9a41..014e62625 100644 --- a/src/util/hwf.cpp +++ b/src/util/hwf.cpp @@ -34,7 +34,7 @@ Revision History: #define USE_INTRINSICS #endif -#include"hwf.h" +#include "util/hwf.h" // Note: // Which FPU will be used is determined by compiler settings. On x64 it's always SSE2, diff --git a/src/util/hwf.h b/src/util/hwf.h index 8816e5b37..5f7692204 100644 --- a/src/util/hwf.h +++ b/src/util/hwf.h @@ -20,9 +20,9 @@ Revision History: #define HWF_H_ #include -#include"mpz.h" -#include"mpq.h" -#include"mpf.h" // we use the same rounding modes as mpf's +#include "util/mpz.h" +#include "util/mpq.h" +#include "util/mpf.h" class hwf { friend class hwf_manager; diff --git a/src/util/id_gen.h b/src/util/id_gen.h index b119a88ac..951ab3f52 100644 --- a/src/util/id_gen.h +++ b/src/util/id_gen.h @@ -19,8 +19,8 @@ Revision History: #ifndef ID_GEN_H_ #define ID_GEN_H_ -#include"vector.h" -#include"util.h" +#include "util/vector.h" +#include "util/util.h" class id_gen { unsigned m_next_id; diff --git a/src/util/inf_eps_rational.h b/src/util/inf_eps_rational.h index 048b6f383..72212d33c 100644 --- a/src/util/inf_eps_rational.h +++ b/src/util/inf_eps_rational.h @@ -20,10 +20,10 @@ Revision History: #define INF_EPS_RATIONAL_H_ #include #include -#include"debug.h" -#include"vector.h" -#include"rational.h" -#include"inf_rational.h" +#include "util/debug.h" +#include "util/vector.h" +#include "util/rational.h" +#include "util/inf_rational.h" template class inf_eps_rational { diff --git a/src/util/inf_int_rational.cpp b/src/util/inf_int_rational.cpp index 7bc68e641..c12c939fd 100644 --- a/src/util/inf_int_rational.cpp +++ b/src/util/inf_int_rational.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include -#include"inf_int_rational.h" +#include "util/inf_int_rational.h" inf_int_rational inf_int_rational::m_zero; inf_int_rational inf_int_rational::m_one; diff --git a/src/util/inf_int_rational.h b/src/util/inf_int_rational.h index a7c920295..ce871b0d5 100644 --- a/src/util/inf_int_rational.h +++ b/src/util/inf_int_rational.h @@ -21,9 +21,9 @@ Revision History: #define INF_INT_RATIONAL_H_ #include #include -#include"debug.h" -#include"vector.h" -#include"rational.h" +#include "util/debug.h" +#include "util/vector.h" +#include "util/rational.h" class inf_int_rational { diff --git a/src/util/inf_rational.cpp b/src/util/inf_rational.cpp index 0b043e94d..78bf61038 100644 --- a/src/util/inf_rational.cpp +++ b/src/util/inf_rational.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"inf_rational.h" +#include "util/inf_rational.h" inf_rational inf_rational::m_zero; inf_rational inf_rational::m_one; diff --git a/src/util/inf_rational.h b/src/util/inf_rational.h index 0488d5fd3..c17c4312b 100644 --- a/src/util/inf_rational.h +++ b/src/util/inf_rational.h @@ -21,9 +21,9 @@ Revision History: #define INF_RATIONAL_H_ #include #include -#include"debug.h" -#include"vector.h" -#include"rational.h" +#include "util/debug.h" +#include "util/vector.h" +#include "util/rational.h" class inf_rational { diff --git a/src/util/inf_s_integer.cpp b/src/util/inf_s_integer.cpp index 602dc14ac..26b226e15 100644 --- a/src/util/inf_s_integer.cpp +++ b/src/util/inf_s_integer.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"inf_s_integer.h" +#include "util/inf_s_integer.h" inf_s_integer inf_s_integer::m_zero(0); inf_s_integer inf_s_integer::m_one(1); diff --git a/src/util/inf_s_integer.h b/src/util/inf_s_integer.h index 80c81350f..6cf1d4225 100644 --- a/src/util/inf_s_integer.h +++ b/src/util/inf_s_integer.h @@ -19,8 +19,8 @@ Revision History: #ifndef INF_S_INTEGER_H_ #define INF_S_INTEGER_H_ -#include"s_integer.h" -#include"rational.h" +#include "util/s_integer.h" +#include "util/rational.h" class inf_s_integer { static inf_s_integer m_zero; diff --git a/src/util/lbool.cpp b/src/util/lbool.cpp index b77a9b892..08f08163a 100644 --- a/src/util/lbool.cpp +++ b/src/util/lbool.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"lbool.h" +#include "util/lbool.h" std::ostream & operator<<(std::ostream & out, lbool b) { switch(b) { diff --git a/src/util/lbool.h b/src/util/lbool.h index ff2466eca..dfc28926d 100644 --- a/src/util/lbool.h +++ b/src/util/lbool.h @@ -19,7 +19,7 @@ Revision History: #ifndef LBOOL_H_ #define LBOOL_H_ -#include"util.h" +#include "util/util.h" typedef enum { l_false = -1, l_undef, l_true } lbool; diff --git a/src/util/list.h b/src/util/list.h index 8d5ff40f2..efde5ada1 100644 --- a/src/util/list.h +++ b/src/util/list.h @@ -19,8 +19,8 @@ Revision History: #ifndef LIST_H_ #define LIST_H_ -#include"buffer.h" -#include"region.h" +#include "util/buffer.h" +#include "util/region.h" template class list { diff --git a/src/util/lp/bound_analyzer_on_row.h b/src/util/lp/bound_analyzer_on_row.h index 508692e5a..2a9dccb5f 100644 --- a/src/util/lp/bound_analyzer_on_row.h +++ b/src/util/lp/bound_analyzer_on_row.h @@ -5,8 +5,8 @@ #pragma once #include "util/vector.h" #include "util/lp/linear_combination_iterator.h" -#include "implied_bound.h" -#include "test_bound_analyzer.h" +#include "util/lp/implied_bound.h" +#include "util/lp/test_bound_analyzer.h" #include #include "util/lp/bound_propagator.h" // We have an equality : sum by j of row[j]*x[j] = rs diff --git a/src/util/map.h b/src/util/map.h index d9dc4463c..0d2acf11b 100644 --- a/src/util/map.h +++ b/src/util/map.h @@ -19,7 +19,7 @@ Revision History: #ifndef MAP_H_ #define MAP_H_ -#include"hashtable.h" +#include "util/hashtable.h" template struct _key_data { diff --git a/src/util/max_cliques.h b/src/util/max_cliques.h index ec888c84b..09e40dee1 100644 --- a/src/util/max_cliques.h +++ b/src/util/max_cliques.h @@ -18,8 +18,8 @@ Notes: --*/ -#include "vector.h" -#include "uint_set.h" +#include "util/vector.h" +#include "util/uint_set.h" template diff --git a/src/util/memory_manager.cpp b/src/util/memory_manager.cpp index 76069ce44..44157aa65 100644 --- a/src/util/memory_manager.cpp +++ b/src/util/memory_manager.cpp @@ -7,10 +7,10 @@ Copyright (c) 2015 Microsoft Corporation #include #include #include -#include"trace.h" -#include"memory_manager.h" -#include"error_codes.h" -#include"z3_omp.h" +#include "util/trace.h" +#include "util/memory_manager.h" +#include "util/error_codes.h" +#include "util/z3_omp.h" // The following two function are automatically generated by the mk_make.py script. // The script collects ADD_INITIALIZER and ADD_FINALIZER commands in the .h files. // For example, rational.h contains diff --git a/src/util/memory_manager.h b/src/util/memory_manager.h index aac61ea2a..5aa512018 100644 --- a/src/util/memory_manager.h +++ b/src/util/memory_manager.h @@ -21,7 +21,7 @@ Revision History: #include #include -#include"z3_exception.h" +#include "util/z3_exception.h" #ifndef __has_builtin # define __has_builtin(x) 0 diff --git a/src/util/mpbq.cpp b/src/util/mpbq.cpp index 1ff7fb04d..9fcd1b58f 100644 --- a/src/util/mpbq.cpp +++ b/src/util/mpbq.cpp @@ -25,7 +25,7 @@ Revision History: --*/ #include -#include"mpbq.h" +#include "util/mpbq.h" #ifdef Z3DEBUG #define MPBQ_DEBUG diff --git a/src/util/mpbq.h b/src/util/mpbq.h index a6c7ddbfa..61ef2b0e2 100644 --- a/src/util/mpbq.h +++ b/src/util/mpbq.h @@ -27,9 +27,9 @@ Revision History: #ifndef MPBQ_H_ #define MPBQ_H_ -#include"mpq.h" -#include"rational.h" -#include"vector.h" +#include "util/mpq.h" +#include "util/rational.h" +#include "util/vector.h" class mpbq { mpz m_num; diff --git a/src/util/mpbqi.h b/src/util/mpbqi.h index 0dc569525..924e1e121 100644 --- a/src/util/mpbqi.h +++ b/src/util/mpbqi.h @@ -19,8 +19,8 @@ Revision History: #ifndef MPBQI_H_ #define MPBQI_H_ -#include"mpbq.h" -#include"basic_interval.h" +#include "util/mpbq.h" +#include "util/basic_interval.h" class mpbqi_manager : public basic_interval_manager { typedef basic_interval_manager super; diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 6f61a78e9..5bccd22aa 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -18,7 +18,7 @@ Revision History: --*/ #include #include -#include"mpf.h" +#include "util/mpf.h" mpf::mpf() : ebits(0), diff --git a/src/util/mpf.h b/src/util/mpf.h index 07755e314..8070768b2 100644 --- a/src/util/mpf.h +++ b/src/util/mpf.h @@ -20,12 +20,12 @@ Revision History: #define MPF_H_ #include -#include"mpz.h" -#include"mpq.h" -#include"map.h" -#include"scoped_numeral.h" -#include"scoped_numeral_vector.h" -#include"hash.h" +#include "util/mpz.h" +#include "util/mpq.h" +#include "util/map.h" +#include "util/scoped_numeral.h" +#include "util/scoped_numeral_vector.h" +#include "util/hash.h" typedef enum { MPF_ROUND_NEAREST_TEVEN, diff --git a/src/util/mpff.cpp b/src/util/mpff.cpp index d26b3743c..459b0691c 100644 --- a/src/util/mpff.cpp +++ b/src/util/mpff.cpp @@ -20,12 +20,12 @@ Revision History: --*/ #include #include -#include"mpff.h" -#include"mpn.h" -#include"mpz.h" -#include"mpq.h" -#include"bit_util.h" -#include"trace.h" +#include "util/mpff.h" +#include "util/mpn.h" +#include "util/mpz.h" +#include "util/mpq.h" +#include "util/bit_util.h" +#include "util/trace.h" COMPILE_TIME_ASSERT(sizeof(mpn_digit) == sizeof(unsigned)); COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); diff --git a/src/util/mpff.h b/src/util/mpff.h index eadfa0390..4fdd0baef 100644 --- a/src/util/mpff.h +++ b/src/util/mpff.h @@ -23,13 +23,13 @@ Revision History: #ifndef MPFF_H_ #define MPFF_H_ -#include"id_gen.h" -#include"util.h" -#include"vector.h" -#include"z3_exception.h" -#include"scoped_numeral.h" -#include"scoped_numeral_vector.h" -#include"mpn.h" +#include "util/id_gen.h" +#include "util/util.h" +#include "util/vector.h" +#include "util/z3_exception.h" +#include "util/scoped_numeral.h" +#include "util/scoped_numeral_vector.h" +#include "util/mpn.h" class mpff_manager; diff --git a/src/util/mpfx.cpp b/src/util/mpfx.cpp index 41ed93617..24ef4dc73 100644 --- a/src/util/mpfx.cpp +++ b/src/util/mpfx.cpp @@ -18,12 +18,12 @@ Revision History: --*/ #include #include -#include"mpfx.h" -#include"mpn.h" -#include"mpz.h" -#include"mpq.h" -#include"bit_util.h" -#include"trace.h" +#include "util/mpfx.h" +#include "util/mpn.h" +#include "util/mpz.h" +#include "util/mpq.h" +#include "util/bit_util.h" +#include "util/trace.h" mpfx_manager::mpfx_manager(unsigned int_sz, unsigned frac_sz, unsigned initial_capacity) { SASSERT(initial_capacity > 0); diff --git a/src/util/mpfx.h b/src/util/mpfx.h index 55242bdf8..98f9bb322 100644 --- a/src/util/mpfx.h +++ b/src/util/mpfx.h @@ -19,13 +19,13 @@ Revision History: #ifndef MPFX_H_ #define MPFX_H_ -#include"id_gen.h" -#include"util.h" -#include"vector.h" -#include"z3_exception.h" -#include"scoped_numeral.h" -#include"scoped_numeral_vector.h" -#include"mpn.h" +#include "util/id_gen.h" +#include "util/util.h" +#include "util/vector.h" +#include "util/z3_exception.h" +#include "util/scoped_numeral.h" +#include "util/scoped_numeral_vector.h" +#include "util/mpn.h" class mpfx_manager; diff --git a/src/util/mpn.cpp b/src/util/mpn.cpp index df69ce76d..65223133f 100644 --- a/src/util/mpn.cpp +++ b/src/util/mpn.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"debug.h" -#include"trace.h" -#include"buffer.h" -#include"mpn.h" +#include "util/debug.h" +#include "util/trace.h" +#include "util/buffer.h" +#include "util/mpn.h" #define max(a,b) (((a) > (b)) ? (a) : (b)) diff --git a/src/util/mpn.h b/src/util/mpn.h index 1f0e2acab..a5d3c30d8 100644 --- a/src/util/mpn.h +++ b/src/util/mpn.h @@ -20,9 +20,9 @@ Revision History: #define MPN_H_ #include -#include"util.h" -#include"buffer.h" -#include"z3_omp.h" +#include "util/util.h" +#include "util/buffer.h" +#include "util/z3_omp.h" typedef unsigned int mpn_digit; diff --git a/src/util/mpq.cpp b/src/util/mpq.cpp index feb051033..bc6f99213 100644 --- a/src/util/mpq.cpp +++ b/src/util/mpq.cpp @@ -16,9 +16,9 @@ Author: Revision History: --*/ -#include"mpq.h" -#include"warning.h" -#include"z3_exception.h" +#include "util/mpq.h" +#include "util/warning.h" +#include "util/z3_exception.h" template mpq_manager::mpq_manager() { diff --git a/src/util/mpq.h b/src/util/mpq.h index 11e17bbf9..5aa3ca083 100644 --- a/src/util/mpq.h +++ b/src/util/mpq.h @@ -19,8 +19,8 @@ Revision History: #ifndef MPQ_H_ #define MPQ_H_ -#include"mpz.h" -#include"trace.h" +#include "util/mpz.h" +#include "util/trace.h" class mpq { mpz m_num; diff --git a/src/util/mpq_inf.cpp b/src/util/mpq_inf.cpp index 19289b737..c6c160941 100644 --- a/src/util/mpq_inf.cpp +++ b/src/util/mpq_inf.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"mpq_inf.h" +#include "util/mpq_inf.h" template std::string mpq_inf_manager::to_string(mpq_inf const & a) { diff --git a/src/util/mpq_inf.h b/src/util/mpq_inf.h index b041b6d4f..7b866994d 100644 --- a/src/util/mpq_inf.h +++ b/src/util/mpq_inf.h @@ -19,8 +19,8 @@ Revision History: #ifndef MPQ_INF_H_ #define MPQ_INF_H_ -#include"mpq.h" -#include"hash.h" +#include "util/mpq.h" +#include "util/hash.h" typedef std::pair mpq_inf; diff --git a/src/util/mpz.cpp b/src/util/mpz.cpp index 7dca14bfa..9569ac280 100644 --- a/src/util/mpz.cpp +++ b/src/util/mpz.cpp @@ -17,14 +17,14 @@ Revision History: --*/ #include -#include"mpz.h" -#include"buffer.h" -#include"trace.h" -#include"hash.h" -#include"bit_util.h" +#include "util/mpz.h" +#include "util/buffer.h" +#include "util/trace.h" +#include "util/hash.h" +#include "util/bit_util.h" #if defined(_MP_INTERNAL) -#include"mpn.h" +#include "util/mpn.h" #elif defined(_MP_GMP) #include #else diff --git a/src/util/mpz.h b/src/util/mpz.h index c02ac7c36..7001b9a42 100644 --- a/src/util/mpz.h +++ b/src/util/mpz.h @@ -21,13 +21,13 @@ Revision History: #include #include -#include"util.h" -#include"small_object_allocator.h" -#include"trace.h" -#include"scoped_numeral.h" -#include"scoped_numeral_vector.h" -#include"z3_omp.h" -#include"mpn.h" +#include "util/util.h" +#include "util/small_object_allocator.h" +#include "util/trace.h" +#include "util/scoped_numeral.h" +#include "util/scoped_numeral_vector.h" +#include "util/z3_omp.h" +#include "util/mpn.h" unsigned u_gcd(unsigned u, unsigned v); uint64 u64_gcd(uint64 u, uint64 v); diff --git a/src/util/mpzzp.h b/src/util/mpzzp.h index 812b6e1bc..a30eff7b6 100644 --- a/src/util/mpzzp.h +++ b/src/util/mpzzp.h @@ -26,7 +26,7 @@ Revision History: #ifndef MPZZP_H_ #define MPZZP_H_ -#include "mpz.h" +#include "util/mpz.h" class mpzzp_manager { typedef unsynch_mpz_manager numeral_manager; diff --git a/src/util/nat_set.h b/src/util/nat_set.h index dcde26034..6e9ab1b6d 100644 --- a/src/util/nat_set.h +++ b/src/util/nat_set.h @@ -20,7 +20,7 @@ Revision History: #define NAT_SET_H_ #include -#include"vector.h" +#include "util/vector.h" class nat_set { unsigned m_curr_timestamp; diff --git a/src/util/numeral_buffer.h b/src/util/numeral_buffer.h index 3c2ea0f05..eee415efb 100644 --- a/src/util/numeral_buffer.h +++ b/src/util/numeral_buffer.h @@ -19,7 +19,7 @@ Revision History: #ifndef NUMERAL_BUFFER_H_ #define NUMERAL_BUFFER_H_ -#include"vector.h" +#include "util/vector.h" template class numeral_buffer { diff --git a/src/util/obj_hashtable.h b/src/util/obj_hashtable.h index 2720f1b00..9c3473e3d 100644 --- a/src/util/obj_hashtable.h +++ b/src/util/obj_hashtable.h @@ -19,8 +19,8 @@ Revision History: #ifndef OBJ_HASHTABLE_H_ #define OBJ_HASHTABLE_H_ -#include"hash.h" -#include"hashtable.h" +#include "util/hash.h" +#include "util/hashtable.h" /** diff --git a/src/util/obj_mark.h b/src/util/obj_mark.h index 749122b8f..d2fa65d32 100644 --- a/src/util/obj_mark.h +++ b/src/util/obj_mark.h @@ -19,7 +19,7 @@ Revision History: #ifndef OBJ_MARK_H_ #define OBJ_MARK_H_ -#include"bit_vector.h" +#include "util/bit_vector.h" template struct default_t2uint { diff --git a/src/util/obj_pair_hashtable.h b/src/util/obj_pair_hashtable.h index 8e7365909..2addc3902 100644 --- a/src/util/obj_pair_hashtable.h +++ b/src/util/obj_pair_hashtable.h @@ -19,8 +19,8 @@ Revision History: #ifndef OBJ_PAIR_HASHTABLE_H_ #define OBJ_PAIR_HASHTABLE_H_ -#include"hash.h" -#include"hashtable.h" +#include "util/hash.h" +#include "util/hashtable.h" /** \brief Special entry for a hashtable of pairs of obj pointers (i.e., diff --git a/src/util/obj_pair_set.h b/src/util/obj_pair_set.h index c4212977c..d565d31b9 100644 --- a/src/util/obj_pair_set.h +++ b/src/util/obj_pair_set.h @@ -19,7 +19,7 @@ Revision History: #ifndef OBJ_PAIR_SET_H_ #define OBJ_PAIR_SET_H_ -#include"chashtable.h" +#include "util/chashtable.h" template class obj_pair_set { diff --git a/src/util/obj_triple_hashtable.h b/src/util/obj_triple_hashtable.h index 4fda9e655..316b63b93 100644 --- a/src/util/obj_triple_hashtable.h +++ b/src/util/obj_triple_hashtable.h @@ -19,7 +19,7 @@ Revision History: #ifndef OBJ_TRIPLE_HASHTABLE_H_ #define OBJ_TRIPLE_HASHTABLE_H_ -#include"hashtable.h" +#include "util/hashtable.h" /** \brief Special entry for a hashtable of pairs of obj pointers (i.e., diff --git a/src/util/object_allocator.h b/src/util/object_allocator.h index 901ec46ec..e51f7a438 100644 --- a/src/util/object_allocator.h +++ b/src/util/object_allocator.h @@ -20,8 +20,8 @@ Revision History: #ifndef OBJECT_ALLOCATOR_H_ #define OBJECT_ALLOCATOR_H_ -#include"util.h" -#include"vector.h" +#include "util/util.h" +#include "util/vector.h" #define DEFAULT_NUM_WORKERS 8 #define NUM_OBJECTS_PER_PAGE 1024 diff --git a/src/util/page.cpp b/src/util/page.cpp index 8fddcc075..4f6cea83c 100644 --- a/src/util/page.cpp +++ b/src/util/page.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"page.h" -#include"debug.h" +#include "util/page.h" +#include "util/debug.h" inline void set_page_header(char * page, char * prev, bool default_page) { size_t header = reinterpret_cast(prev) | static_cast(default_page); diff --git a/src/util/page.h b/src/util/page.h index 4ccfb6cab..0f44d6794 100644 --- a/src/util/page.h +++ b/src/util/page.h @@ -19,7 +19,7 @@ Revision History: #ifndef PAGE_H_ #define PAGE_H_ -#include"memory_manager.h" +#include "util/memory_manager.h" #define PAGE_HEADER_SZ sizeof(size_t) #define DEFAULT_PAGE_SIZE (8192 - PAGE_HEADER_SZ) diff --git a/src/util/params.cpp b/src/util/params.cpp index b869f8e3d..ee6ce6627 100644 --- a/src/util/params.cpp +++ b/src/util/params.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"params.h" -#include"rational.h" -#include"symbol.h" -#include"dictionary.h" +#include "util/params.h" +#include "util/rational.h" +#include "util/symbol.h" +#include "util/dictionary.h" params_ref params_ref::g_empty_params_ref; diff --git a/src/util/params.h b/src/util/params.h index 8d95c200c..bad70a318 100644 --- a/src/util/params.h +++ b/src/util/params.h @@ -19,8 +19,8 @@ Notes: #ifndef PARAMS_H_ #define PARAMS_H_ -#include"cmd_context_types.h" -#include"vector.h" +#include "util/cmd_context_types.h" +#include "util/vector.h" std::string norm_param_name(char const * n); std::string norm_param_name(symbol const & n); diff --git a/src/util/parray.h b/src/util/parray.h index 1802f6ade..44b075db9 100644 --- a/src/util/parray.h +++ b/src/util/parray.h @@ -19,8 +19,8 @@ Revision History: #ifndef PARRAY_H_ #define PARRAY_H_ -#include"vector.h" -#include"trace.h" +#include "util/vector.h" +#include "util/trace.h" template class parray_manager { diff --git a/src/util/permutation.cpp b/src/util/permutation.cpp index a5c1b2e8b..5b20580eb 100644 --- a/src/util/permutation.cpp +++ b/src/util/permutation.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"permutation.h" +#include "util/permutation.h" permutation::permutation(unsigned size) { reset(size); diff --git a/src/util/permutation.h b/src/util/permutation.h index 45759fc01..77205bb1d 100644 --- a/src/util/permutation.h +++ b/src/util/permutation.h @@ -20,7 +20,7 @@ Revision History: #define PERMUTATION_H_ #include -#include"vector.h" +#include "util/vector.h" class permutation { unsigned_vector m_p; diff --git a/src/util/plugin_manager.h b/src/util/plugin_manager.h index 5e82c190c..da7017aa1 100644 --- a/src/util/plugin_manager.h +++ b/src/util/plugin_manager.h @@ -19,7 +19,7 @@ Revision History: #ifndef PLUGIN_MANAGER_H_ #define PLUGIN_MANAGER_H_ -#include"util.h" +#include "util/util.h" template class plugin_manager { diff --git a/src/util/pool.h b/src/util/pool.h index 3ea9dca9d..184f6470e 100644 --- a/src/util/pool.h +++ b/src/util/pool.h @@ -19,8 +19,8 @@ Revision History: #ifndef POOL_H_ #define POOL_H_ -#include"util.h" -#include"vector.h" +#include "util/util.h" +#include "util/vector.h" template class pool { diff --git a/src/util/prime_generator.cpp b/src/util/prime_generator.cpp index 6aef1305b..eac47f61b 100644 --- a/src/util/prime_generator.cpp +++ b/src/util/prime_generator.cpp @@ -16,7 +16,7 @@ Author: Notes: --*/ -#include"prime_generator.h" +#include "util/prime_generator.h" #define PRIME_LIST_MAX_SIZE 1<<20 diff --git a/src/util/prime_generator.h b/src/util/prime_generator.h index 44306cec5..6a284c57c 100644 --- a/src/util/prime_generator.h +++ b/src/util/prime_generator.h @@ -19,9 +19,9 @@ Notes: #ifndef PRIME_GENERATOR_H_ #define PRIME_GENERATOR_H_ -#include"vector.h" -#include"z3_exception.h" -#include"util.h" +#include "util/vector.h" +#include "util/z3_exception.h" +#include "util/util.h" class prime_generator_exception : public default_exception { public: diff --git a/src/util/ptr_scoped_buffer.h b/src/util/ptr_scoped_buffer.h index aa66a0398..d6b4c6563 100644 --- a/src/util/ptr_scoped_buffer.h +++ b/src/util/ptr_scoped_buffer.h @@ -19,9 +19,9 @@ Revision History: #ifndef PTR_SCOPED_BUFFER_H_ #define PTR_SCOPED_BUFFER_H_ -#include"util.h" -#include"debug.h" -#include"buffer.h" +#include "util/util.h" +#include "util/debug.h" +#include "util/buffer.h" template > class ptr_scoped_buffer : private ptr_buffer { diff --git a/src/util/rational.cpp b/src/util/rational.cpp index 43dc9110a..ce38bcaa7 100644 --- a/src/util/rational.cpp +++ b/src/util/rational.cpp @@ -17,8 +17,8 @@ Revision History: --*/ #include -#include"util.h" -#include"rational.h" +#include "util/util.h" +#include "util/rational.h" #ifdef _WINDOWS #include #endif diff --git a/src/util/rational.h b/src/util/rational.h index 26ef7dbb1..ca294e234 100644 --- a/src/util/rational.h +++ b/src/util/rational.h @@ -19,7 +19,7 @@ Revision History: #ifndef RATIONAL_H_ #define RATIONAL_H_ -#include"mpq.h" +#include "util/mpq.h" class rational { mpq m_val; diff --git a/src/util/ref_buffer.h b/src/util/ref_buffer.h index cd4e0c5ba..612dde2da 100644 --- a/src/util/ref_buffer.h +++ b/src/util/ref_buffer.h @@ -19,9 +19,9 @@ Revision History: #ifndef REF_BUFFER_H_ #define REF_BUFFER_H_ -#include"buffer.h" -#include"obj_ref.h" -#include"ref_vector.h" +#include "util/buffer.h" +#include "util/obj_ref.h" +#include "util/ref_vector.h" /** diff --git a/src/util/ref_vector.h b/src/util/ref_vector.h index fdfb94d93..469183b76 100644 --- a/src/util/ref_vector.h +++ b/src/util/ref_vector.h @@ -19,8 +19,8 @@ Revision History: #ifndef REF_VECTOR_H_ #define REF_VECTOR_H_ -#include"vector.h" -#include"obj_ref.h" +#include "util/vector.h" +#include "util/obj_ref.h" /** \brief Vector of smart pointers. diff --git a/src/util/region.cpp b/src/util/region.cpp index 0100c60f3..4e5b5f2f2 100644 --- a/src/util/region.cpp +++ b/src/util/region.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include"region.h" +#include "util/region.h" #ifdef Z3DEBUG @@ -26,10 +26,10 @@ void region::display_mem_stats(std::ostream & out) const { #else -#include"tptr.h" -#include"debug.h" -#include"memory_manager.h" -#include"page.h" +#include "util/tptr.h" +#include "util/debug.h" +#include "util/memory_manager.h" +#include "util/page.h" inline void region::allocate_page() { m_curr_page = allocate_default_page(m_curr_page, m_free_pages); diff --git a/src/util/region.h b/src/util/region.h index 2c43e26d4..60c5378e1 100644 --- a/src/util/region.h +++ b/src/util/region.h @@ -23,7 +23,7 @@ Revision History: #ifdef Z3DEBUG -#include"vector.h" +#include "util/vector.h" class region { ptr_vector m_chuncks; diff --git a/src/util/rlimit.cpp b/src/util/rlimit.cpp index bda06157d..f3f45c654 100644 --- a/src/util/rlimit.cpp +++ b/src/util/rlimit.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include "rlimit.h" -#include "common_msgs.h" +#include "util/rlimit.h" +#include "util/common_msgs.h" reslimit::reslimit(): m_cancel(0), diff --git a/src/util/rlimit.h b/src/util/rlimit.h index 283d7613d..3b278d132 100644 --- a/src/util/rlimit.h +++ b/src/util/rlimit.h @@ -19,7 +19,7 @@ Revision History: #ifndef RLIMIT_H_ #define RLIMIT_H_ -#include "vector.h" +#include "util/vector.h" class reslimit { volatile unsigned m_cancel; diff --git a/src/util/s_integer.cpp b/src/util/s_integer.cpp index f55e77487..cfaf34fff 100644 --- a/src/util/s_integer.cpp +++ b/src/util/s_integer.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"s_integer.h" +#include "util/s_integer.h" s_integer s_integer::m_zero(0); s_integer s_integer::m_one(1); diff --git a/src/util/s_integer.h b/src/util/s_integer.h index c215505ea..658ae8eea 100644 --- a/src/util/s_integer.h +++ b/src/util/s_integer.h @@ -19,7 +19,7 @@ Revision History: #ifndef S_INTEGER_H_ #define S_INTEGER_H_ -#include"rational.h" +#include "util/rational.h" class s_integer { int m_val; diff --git a/src/util/scoped_ctrl_c.cpp b/src/util/scoped_ctrl_c.cpp index feaceea8d..739eca295 100644 --- a/src/util/scoped_ctrl_c.cpp +++ b/src/util/scoped_ctrl_c.cpp @@ -18,7 +18,7 @@ Revision History: --*/ #include #include -#include"scoped_ctrl_c.h" +#include "util/scoped_ctrl_c.h" scoped_ctrl_c * scoped_ctrl_c::g_obj = 0; diff --git a/src/util/scoped_ctrl_c.h b/src/util/scoped_ctrl_c.h index b79db28fe..b3abf0e26 100644 --- a/src/util/scoped_ctrl_c.h +++ b/src/util/scoped_ctrl_c.h @@ -19,8 +19,8 @@ Revision History: #ifndef SCOPED_CTRL_C_H_ #define SCOPED_CTRL_C_H_ -#include"event_handler.h" -#include"util.h" +#include "util/event_handler.h" +#include "util/util.h" struct scoped_ctrl_c { event_handler & m_cancel_eh; diff --git a/src/util/scoped_numeral_buffer.h b/src/util/scoped_numeral_buffer.h index 6da287dd2..1f294cee0 100644 --- a/src/util/scoped_numeral_buffer.h +++ b/src/util/scoped_numeral_buffer.h @@ -19,7 +19,7 @@ Revision History: #ifndef SCOPED_NUMERAL_BUFFER_H_ #define SCOPED_NUMERAL_BUFFER_H_ -#include"buffer.h" +#include "util/buffer.h" template class _scoped_numeral_buffer : public sbuffer { diff --git a/src/util/scoped_numeral_vector.h b/src/util/scoped_numeral_vector.h index bbd06f898..fdf63bf35 100644 --- a/src/util/scoped_numeral_vector.h +++ b/src/util/scoped_numeral_vector.h @@ -19,7 +19,7 @@ Revision History: #ifndef SCOPED_NUMERAL_VECTOR_H_ #define SCOPED_NUMERAL_VECTOR_H_ -#include"vector.h" +#include "util/vector.h" template class _scoped_numeral_vector : public svector { diff --git a/src/util/scoped_ptr_vector.h b/src/util/scoped_ptr_vector.h index d1ff89733..a9ef92766 100644 --- a/src/util/scoped_ptr_vector.h +++ b/src/util/scoped_ptr_vector.h @@ -20,8 +20,8 @@ Notes: #ifndef SCOPED_PTR_VECTOR_H_ #define SCOPED_PTR_VECTOR_H_ -#include"vector.h" -#include"util.h" +#include "util/vector.h" +#include "util/util.h" template class scoped_ptr_vector { diff --git a/src/util/scoped_timer.cpp b/src/util/scoped_timer.cpp index f6b0429d9..741523291 100644 --- a/src/util/scoped_timer.cpp +++ b/src/util/scoped_timer.cpp @@ -21,8 +21,8 @@ Revision History: #define _WIN32_WINNT 0x0600 #endif -#include"z3_exception.h" -#include"z3_omp.h" +#include "util/z3_exception.h" +#include "util/z3_omp.h" #if defined(_WINDOWS) || defined(_CYGWIN) // Windows #include @@ -44,14 +44,14 @@ Revision History: // Other platforms #endif -#include"scoped_timer.h" +#include "util/scoped_timer.h" #ifdef _CYGWIN #undef min #undef max #endif -#include"util.h" +#include "util/util.h" #include -#include"z3_omp.h" +#include "util/z3_omp.h" struct scoped_timer::imp { event_handler * m_eh; diff --git a/src/util/scoped_timer.h b/src/util/scoped_timer.h index a3e2568f9..cfce957f3 100644 --- a/src/util/scoped_timer.h +++ b/src/util/scoped_timer.h @@ -19,7 +19,7 @@ Revision History: #ifndef SCOPED_TIMER_H_ #define SCOPED_TIMER_H_ -#include"event_handler.h" +#include "util/event_handler.h" class scoped_timer { struct imp; diff --git a/src/util/scoped_vector.h b/src/util/scoped_vector.h index f62fbc8a6..d4c5301e6 100644 --- a/src/util/scoped_vector.h +++ b/src/util/scoped_vector.h @@ -19,7 +19,7 @@ Revision History: #ifndef SCOPED_VECTOR_H_ #define SCOPED_VECTOR_H_ -#include"vector.h" +#include "util/vector.h" template class scoped_vector { diff --git a/src/util/sexpr.cpp b/src/util/sexpr.cpp index c5d4a976f..4757330c2 100644 --- a/src/util/sexpr.cpp +++ b/src/util/sexpr.cpp @@ -16,9 +16,9 @@ Author: Notes: --*/ -#include"sexpr.h" -#include"vector.h" -#include"buffer.h" +#include "util/sexpr.h" +#include "util/vector.h" +#include "util/buffer.h" #ifdef _MSC_VER #pragma warning(disable : 4200) diff --git a/src/util/sexpr.h b/src/util/sexpr.h index 350c1ffec..7f5fdc67d 100644 --- a/src/util/sexpr.h +++ b/src/util/sexpr.h @@ -19,10 +19,10 @@ Notes: #ifndef SEXPR_H_ #define SEXPR_H_ -#include"rational.h" -#include"symbol.h" -#include"obj_ref.h" -#include"ref_vector.h" +#include "util/rational.h" +#include "util/symbol.h" +#include "util/obj_ref.h" +#include "util/ref_vector.h" class sexpr_manager; diff --git a/src/util/small_object_allocator.cpp b/src/util/small_object_allocator.cpp index ac2f64482..0eb7b9ec3 100644 --- a/src/util/small_object_allocator.cpp +++ b/src/util/small_object_allocator.cpp @@ -18,11 +18,11 @@ Revision History: Rewrote/Simplified the allocator --*/ -#include"memory_manager.h" -#include"small_object_allocator.h" -#include"debug.h" -#include"util.h" -#include"vector.h" +#include "util/memory_manager.h" +#include "util/small_object_allocator.h" +#include "util/debug.h" +#include "util/util.h" +#include "util/vector.h" #include small_object_allocator::small_object_allocator(char const * id) { diff --git a/src/util/small_object_allocator.h b/src/util/small_object_allocator.h index 9433b093e..740218242 100644 --- a/src/util/small_object_allocator.h +++ b/src/util/small_object_allocator.h @@ -20,8 +20,8 @@ Revision History: #ifndef SMALL_OBJECT_ALLOCATOR_H_ #define SMALL_OBJECT_ALLOCATOR_H_ -#include"machine.h" -#include"debug.h" +#include "util/machine.h" +#include "util/debug.h" class small_object_allocator { static const unsigned CHUNK_SIZE = (8192 - sizeof(void*)*2); diff --git a/src/util/smt2_util.cpp b/src/util/smt2_util.cpp index 70979cc01..731c91848 100644 --- a/src/util/smt2_util.cpp +++ b/src/util/smt2_util.cpp @@ -16,7 +16,7 @@ Author: Notes: --*/ -#include"smt2_util.h" +#include "util/smt2_util.h" bool is_smt2_simple_symbol_char(char s) { return diff --git a/src/util/smt2_util.h b/src/util/smt2_util.h index bddef03fb..5338daed9 100644 --- a/src/util/smt2_util.h +++ b/src/util/smt2_util.h @@ -19,7 +19,7 @@ Notes: #ifndef SMT2_UTIL_H_ #define SMT2_UTIL_H_ -#include"symbol.h" +#include "util/symbol.h" bool is_smt2_simple_symbol_char(char c); bool is_smt2_quoted_symbol(char const * s); diff --git a/src/util/sorting_network.h b/src/util/sorting_network.h index b0efbd346..17808ea48 100644 --- a/src/util/sorting_network.h +++ b/src/util/sorting_network.h @@ -19,7 +19,7 @@ Notes: --*/ -#include "vector.h" +#include "util/vector.h" #ifndef SORTING_NETWORK_H_ #define SORTING_NETWORK_H_ diff --git a/src/util/stack.cpp b/src/util/stack.cpp index 3c442d74b..81383e2fe 100644 --- a/src/util/stack.cpp +++ b/src/util/stack.cpp @@ -15,9 +15,9 @@ Author: Notes: --*/ -#include"stack.h" -#include"page.h" -#include"tptr.h" +#include "util/stack.h" +#include "util/page.h" +#include "util/tptr.h" inline void stack::store_mark(size_t m) { reinterpret_cast(m_curr_ptr)[0] = m; diff --git a/src/util/stack.h b/src/util/stack.h index a2605edcc..e29a09fcd 100644 --- a/src/util/stack.h +++ b/src/util/stack.h @@ -18,8 +18,8 @@ Notes: #ifndef STACK_H_ #define STACK_H_ -#include"page.h" -#include"debug.h" +#include "util/page.h" +#include "util/debug.h" class stack { char * m_curr_page; diff --git a/src/util/statistics.cpp b/src/util/statistics.cpp index 99cc4f3a4..9c8d1fd99 100644 --- a/src/util/statistics.cpp +++ b/src/util/statistics.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ -#include"statistics.h" -#include"map.h" -#include"str_hashtable.h" -#include"buffer.h" -#include"smt2_util.h" +#include "util/statistics.h" +#include "util/map.h" +#include "util/str_hashtable.h" +#include "util/buffer.h" +#include "util/smt2_util.h" #include void statistics::update(char const * key, unsigned inc) { diff --git a/src/util/statistics.h b/src/util/statistics.h index 041c2cf99..249c0ccc3 100644 --- a/src/util/statistics.h +++ b/src/util/statistics.h @@ -20,8 +20,8 @@ Notes: #define STATISTICS_H_ #include -#include"vector.h" -#include"rlimit.h" +#include "util/vector.h" +#include "util/rlimit.h" class statistics { typedef std::pair key_val_pair; diff --git a/src/util/str_hashtable.h b/src/util/str_hashtable.h index 2cfc2856c..e12cdc7a7 100644 --- a/src/util/str_hashtable.h +++ b/src/util/str_hashtable.h @@ -21,8 +21,8 @@ Revision History: #include -#include"hashtable.h" -#include"hash.h" +#include "util/hashtable.h" +#include "util/hash.h" struct str_hash_proc { unsigned operator()(char const * s) const { return string_hash(s, static_cast(strlen(s)), 17); } diff --git a/src/util/string_buffer.h b/src/util/string_buffer.h index a1607f5c4..28ce84fc4 100644 --- a/src/util/string_buffer.h +++ b/src/util/string_buffer.h @@ -22,8 +22,8 @@ #include #include #include -#include"util.h" -#include"memory_manager.h" +#include "util/util.h" +#include "util/memory_manager.h" // This string buffer will not use the heap if the data consumes less than INITIAL_SIZE bytes. template diff --git a/src/util/symbol.cpp b/src/util/symbol.cpp index 895c26b67..8f46272f0 100644 --- a/src/util/symbol.cpp +++ b/src/util/symbol.cpp @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"symbol.h" -#include"str_hashtable.h" -#include"region.h" -#include"string_buffer.h" -#include"z3_omp.h" +#include "util/symbol.h" +#include "util/str_hashtable.h" +#include "util/region.h" +#include "util/string_buffer.h" +#include "util/z3_omp.h" symbol symbol::m_dummy(TAG(void*, static_cast(0), 2)); const symbol symbol::null; diff --git a/src/util/symbol.h b/src/util/symbol.h index d0eef4f3b..874b258e9 100644 --- a/src/util/symbol.h +++ b/src/util/symbol.h @@ -21,9 +21,9 @@ Revision History: #include #include -#include"util.h" -#include"tptr.h" -#include"string_buffer.h" +#include "util/util.h" +#include "util/tptr.h" +#include "util/string_buffer.h" template class symbol_table; diff --git a/src/util/symbol_table.h b/src/util/symbol_table.h index d3be2cb9c..ea848d991 100644 --- a/src/util/symbol_table.h +++ b/src/util/symbol_table.h @@ -18,10 +18,10 @@ Revision History: --*/ #ifndef SYMBOL_TABLE_H_ #define SYMBOL_TABLE_H_ -#include"vector.h" -#include"hashtable.h" -#include"hash.h" -#include"symbol.h" +#include "util/vector.h" +#include "util/hashtable.h" +#include "util/hash.h" +#include "util/symbol.h" /** \brief Quick & Dirty symbol table. diff --git a/src/util/timeit.cpp b/src/util/timeit.cpp index 5246beced..97df87ecd 100644 --- a/src/util/timeit.cpp +++ b/src/util/timeit.cpp @@ -17,9 +17,9 @@ Revision History: --*/ #include -#include"timeit.h" -#include"memory_manager.h" -#include"stopwatch.h" +#include "util/timeit.h" +#include "util/memory_manager.h" +#include "util/stopwatch.h" #include struct timeit::imp { diff --git a/src/util/timeout.cpp b/src/util/timeout.cpp index 75621995c..a82d1ec25 100644 --- a/src/util/timeout.cpp +++ b/src/util/timeout.cpp @@ -19,13 +19,13 @@ Revision History: --*/ #include -#include"z3_omp.h" -#include"util.h" -#include"timeout.h" -#include"error_codes.h" +#include "util/z3_omp.h" +#include "util/util.h" +#include "util/timeout.h" +#include "util/error_codes.h" -#include"event_handler.h" -#include"scoped_timer.h" +#include "util/event_handler.h" +#include "util/scoped_timer.h" scoped_timer * g_timeout = 0; void (* g_on_timeout)() = 0; diff --git a/src/util/timer.cpp b/src/util/timer.cpp index ace67ead8..2d80b732c 100644 --- a/src/util/timer.cpp +++ b/src/util/timer.cpp @@ -16,10 +16,10 @@ Author: Revision History: --*/ -#include"util.h" -#include"memory_manager.h" -#include"stopwatch.h" -#include"timer.h" +#include "util/util.h" +#include "util/memory_manager.h" +#include "util/stopwatch.h" +#include "util/timer.h" timer::timer(){ m_watch = alloc(stopwatch); diff --git a/src/util/total_order.h b/src/util/total_order.h index 6fda88110..a309b63a1 100644 --- a/src/util/total_order.h +++ b/src/util/total_order.h @@ -19,11 +19,11 @@ Revision History: #ifndef TOTAL_ORDER_H_ #define TOTAL_ORDER_H_ -#include"util.h" -#include"small_object_allocator.h" -#include"map.h" -#include"uint_map.h" -#include"trace.h" +#include "util/util.h" +#include "util/small_object_allocator.h" +#include "util/map.h" +#include "util/uint_map.h" +#include "util/trace.h" /** \brief An object for maintaining a total-order on sets of T values. diff --git a/src/util/tptr.h b/src/util/tptr.h index 23c28078b..d7319954d 100644 --- a/src/util/tptr.h +++ b/src/util/tptr.h @@ -20,7 +20,7 @@ Revision History: #ifndef TPTR_H_ #define TPTR_H_ -#include"machine.h" +#include "util/machine.h" #define TAG_SHIFT PTR_ALIGNMENT #define ALIGNMENT_VALUE (1 << PTR_ALIGNMENT) diff --git a/src/util/trace.cpp b/src/util/trace.cpp index 05a3e49bd..d993ebd11 100644 --- a/src/util/trace.cpp +++ b/src/util/trace.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include"trace.h" -#include"str_hashtable.h" +#include "util/trace.h" +#include "util/str_hashtable.h" #ifdef _TRACE std::ofstream tout(".z3-trace"); diff --git a/src/util/trail.h b/src/util/trail.h index 56c3d805f..1b8f36206 100644 --- a/src/util/trail.h +++ b/src/util/trail.h @@ -19,9 +19,9 @@ Revision History: #ifndef TRAIL_H_ #define TRAIL_H_ -#include"obj_hashtable.h" -#include"region.h" -#include"obj_ref.h" +#include "util/obj_hashtable.h" +#include "util/region.h" +#include "util/obj_ref.h" template class trail { diff --git a/src/util/uint_map.h b/src/util/uint_map.h index 0344de322..b7dec8676 100644 --- a/src/util/uint_map.h +++ b/src/util/uint_map.h @@ -19,7 +19,7 @@ Revision History: #ifndef UINT_MAP_H_ #define UINT_MAP_H_ -#include"vector.h" +#include "util/vector.h" /** \brief Implement a map from unsigned to T * using vectors diff --git a/src/util/uint_set.h b/src/util/uint_set.h index e78a4b0b6..33c39eeb2 100644 --- a/src/util/uint_set.h +++ b/src/util/uint_set.h @@ -19,8 +19,8 @@ Revision History: #ifndef UINT_SET_H_ #define UINT_SET_H_ -#include"util.h" -#include"vector.h" +#include "util/util.h" +#include "util/vector.h" COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); diff --git a/src/util/union_find.h b/src/util/union_find.h index 6f6cc7a3b..7a99b149e 100644 --- a/src/util/union_find.h +++ b/src/util/union_find.h @@ -19,8 +19,8 @@ Revision History: #ifndef UNION_FIND_H_ #define UNION_FIND_H_ -#include "trail.h" -#include "trace.h" +#include "util/trail.h" +#include "util/trace.h" class union_find_default_ctx { public: diff --git a/src/util/util.cpp b/src/util/util.cpp index bfd4923a8..b16dbe292 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -17,7 +17,7 @@ Revision History: --*/ -#include"util.h" +#include "util/util.h" static unsigned g_verbosity_level = 0; diff --git a/src/util/util.h b/src/util/util.h index a040a79ae..440877619 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -19,8 +19,8 @@ Revision History: #ifndef UTIL_H_ #define UTIL_H_ -#include"debug.h" -#include"memory_manager.h" +#include "util/debug.h" +#include "util/memory_manager.h" #include #include #include diff --git a/src/util/vector.h b/src/util/vector.h index 7e89a773c..2d499a900 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -24,12 +24,12 @@ Revision History: #ifndef VECTOR_H_ #define VECTOR_H_ -#include"debug.h" +#include "util/debug.h" #include #include -#include"memory_manager.h" -#include"hash.h" -#include"z3_exception.h" +#include "util/memory_manager.h" +#include "util/hash.h" +#include "util/z3_exception.h" // disable warning for constant 'if' expressions. // these are used heavily in templates. diff --git a/src/util/warning.cpp b/src/util/warning.cpp index 9c6a285b9..a794b064a 100644 --- a/src/util/warning.cpp +++ b/src/util/warning.cpp @@ -19,10 +19,10 @@ Revision History: #include #include -#include "error_codes.h" -#include "util.h" -#include "buffer.h" -#include "vector.h" +#include "util/error_codes.h" +#include "util/util.h" +#include "util/buffer.h" +#include "util/vector.h" #ifdef _WINDOWS #define PRF sprintf_s diff --git a/src/util/z3_exception.cpp b/src/util/z3_exception.cpp index ee225ba48..d028a688a 100644 --- a/src/util/z3_exception.cpp +++ b/src/util/z3_exception.cpp @@ -19,10 +19,10 @@ Notes: #include #include #include -#include"z3_exception.h" -#include"warning.h" -#include"error_codes.h" -#include"debug.h" +#include "util/z3_exception.h" +#include "util/warning.h" +#include "util/error_codes.h" +#include "util/debug.h" unsigned z3_exception::error_code() const { return ERR_OK; From 013127e9475af0f08dda8be2f79b0f8770cbf86b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 14:01:39 -0700 Subject: [PATCH 043/488] fix build break based on ambiguous path resolution Signed-off-by: Nikolaj Bjorner --- src/ast/pattern/pattern_inference.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index 25feaed26..d55c20c1c 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -576,7 +576,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings, m_candidates.reset(); } -#include "smt/database.h" +#include "database.h" void pattern_inference::reduce1_quantifier(quantifier * q) { TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";); From b269e6b35bba4fc09d3177024cde8424a7c18073 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:11:46 -0400 Subject: [PATCH 044/488] comments on proof_utils --- src/muz/base/proof_utils.cpp | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/muz/base/proof_utils.cpp b/src/muz/base/proof_utils.cpp index bbf9da0a4..3b2d50fdc 100644 --- a/src/muz/base/proof_utils.cpp +++ b/src/muz/base/proof_utils.cpp @@ -12,12 +12,19 @@ Copyright (c) 2015 Microsoft Corporation class reduce_hypotheses { typedef obj_hashtable expr_set; ast_manager& m; + // reference for any expression created by the tranformation expr_ref_vector m_refs; + // currently computed result obj_map m_cache; + // map conclusions to closed proofs that derive them obj_map m_units; + // currently active units ptr_vector m_units_trail; + // size of m_units_trail at the last push unsigned_vector m_limits; + // map from proofs to active hypotheses obj_map m_hypmap; + // refernce train for hypotheses sets ptr_vector m_hyprefs; ptr_vector m_literals; @@ -151,19 +158,33 @@ public: p = result; return; } + //SASSERT (p.get () == result); switch(p->get_decl_kind()) { case PR_HYPOTHESIS: + // replace result by m_units[m.get_fact (p)] if defined + // AG: This is the main step. Replace a hypothesis by a derivation of its consequence if (!m_units.find(m.get_fact(p), result)) { + // restore ther result back to p result = p.get(); } + // compute hypothesis of the result + // not clear what 'result' is at this point. + // probably the proof at the top of the call + // XXX not clear why this is re-computed each time + // XXX moreover, m_units are guaranteed to be closed! + // XXX so no hypotheses are needed for them add_hypotheses(result); break; case PR_LEMMA: { SASSERT(m.get_num_parents(p) == 1); tmp = m.get_parent(p, 0); + // eliminate hypothesis recursively in the proof of the lemma elim(tmp); expr_set* hyps = m_hypmap.find(tmp); expr_set* new_hyps = 0; + // XXX if the proof is correct, the hypotheses of the tmp + // XXX should be exactly those of the consequence of the lemma + // XXX but if this code actually eliminates hypotheses, the set might be a subset if (hyps) { new_hyps = alloc(expr_set, *hyps); } @@ -178,13 +199,19 @@ public: get_literals(fact); } + // go over all the literals in the consequence of the lemma for (unsigned i = 0; i < m_literals.size(); ++i) { expr* e = m_literals[i]; + // if the literal is not in hypothesis, skip it if (!in_hypotheses(e, hyps)) { m_literals[i] = m_literals.back(); m_literals.pop_back(); --i; } + // if the literal is in hypothesis remove it because + // it is not in hypothesis set of the lemma + // XXX but we assume that lemmas have empty hypothesis set. + // XXX eventually every element of new_hyps must be removed! else { SASSERT(new_hyps); expr_ref not_e = complement_lit(e); @@ -192,10 +219,13 @@ public: new_hyps->remove(not_e); } } + // killed all hypotheses, so can stop at the lemma since + // we have a closed pf of false if (m_literals.empty()) { result = tmp; } else { + // create a new lemma, but might be re-creating existing one expr_ref clause(m); if (m_literals.size() == 1) { clause = m_literals[0]; @@ -212,6 +242,7 @@ public: new_hyps = 0; } m_hypmap.insert(result, new_hyps); + // might push 0 into m_hyprefs. No reason for that m_hyprefs.push_back(new_hyps); TRACE("proof_utils", tout << "New lemma: " << mk_pp(m.get_fact(p), m) @@ -229,19 +260,27 @@ public: } case PR_UNIT_RESOLUTION: { proof_ref_vector parents(m); + // get the clause being resolved with parents.push_back(m.get_parent(p, 0)); + // save state push(); bool found_false = false; + // for every derivation of a unit literal for (unsigned i = 1; i < m.get_num_parents(p); ++i) { + // see if it derives false tmp = m.get_parent(p, i); elim(tmp); if (m.is_false(m.get_fact(tmp))) { + // if derived false, the whole pf is false and we can bail out result = tmp; found_false = true; break; } + // -- otherwise, the fact has not changed. nothing to simplify SASSERT(m.get_fact(tmp) == m.get_fact(m.get_parent(p, i))); parents.push_back(tmp); + // remember that we have this derivation while we have not poped the trail + // but only if the proof is closed (i.e., a real unit) if (is_closed(tmp) && !m_units.contains(m.get_fact(tmp))) { m_units.insert(m.get_fact(tmp), tmp); m_units_trail.push_back(m.get_fact(tmp)); @@ -251,10 +290,15 @@ public: pop(); break; } + // look at the clause being resolved with tmp = m.get_parent(p, 0); + // remember its fact expr* old_clause = m.get_fact(tmp); + // attempt to reduce its fact elim(tmp); + // update parents parents[0] = tmp; + // if the new fact is false, bail out expr* clause = m.get_fact(tmp); if (m.is_false(clause)) { m_refs.push_back(tmp); @@ -264,8 +308,10 @@ public: } // // case where clause is a literal in the old clause. + // i.e., reduce multi-literal clause to a unit // if (is_literal_in_clause(clause, old_clause)) { + // if the resulting literal was resolved, get a pf of false and bail out bool found = false; for (unsigned i = 1; !found && i < parents.size(); ++i) { if (m.is_complement(clause, m.get_fact(parents[i].get()))) { @@ -277,6 +323,7 @@ public: found = true; } } + // else if the resulting literal is not resolved, it is the new consequence if (!found) { result = parents[0].get(); } @@ -508,6 +555,11 @@ static void permute_unit_resolution(expr_ref_vector& refs, obj_map SASSERT(params[0].is_symbol()); family_id tid = m.mk_family_id(params[0].get_symbol()); SASSERT(tid != null_family_id); + // AG: This can break a theory lemma. In particular, for Farkas lemmas the coefficients + // AG: for the literals propagated from the unit resolution are missing. + // AG: Why is this a good thing to do? + // AG: This can lead to merging of the units with other terms in interpolation, + // AG: but without farkas coefficients this does not make sense prNew = m.mk_th_lemma(tid, m.get_fact(pr), premises.size(), premises.c_ptr(), num_params-1, params+1); } From ba6594b24176f5eb07bfabed4af90b6095ae5acd Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:14:22 -0400 Subject: [PATCH 045/488] extra smt params used by spacer --- src/smt/params/smt_params.cpp | 3 +++ src/smt/params/smt_params.h | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/src/smt/params/smt_params.cpp b/src/smt/params/smt_params.cpp index 453fb3e8e..8a8fac952 100644 --- a/src/smt/params/smt_params.cpp +++ b/src/smt/params/smt_params.cpp @@ -49,6 +49,9 @@ void smt_params::updt_local_params(params_ref const & _p) { else if (_p.get_bool("arith.least_error_pivot", false)) m_arith_pivot_strategy = ARITH_PIVOT_LEAST_ERROR; theory_array_params::updt_params(_p); + m_dump_benchmarks = false; + m_dump_min_time = 0.5; + m_dump_recheck = false; } void smt_params::updt_params(params_ref const & p) { diff --git a/src/smt/params/smt_params.h b/src/smt/params/smt_params.h index 5f93276a1..4539ebe58 100644 --- a/src/smt/params/smt_params.h +++ b/src/smt/params/smt_params.h @@ -217,6 +217,15 @@ struct smt_params : public preprocessor_params, bool m_dump_goal_as_smt; bool m_auto_config; + // ----------------------------------- + // + // Spacer hacking + // + // ----------------------------------- + bool m_dump_benchmarks; + double m_dump_min_time; + bool m_dump_recheck; + // ----------------------------------- // // Solver selection From 9f9dc5e19fb59fe912314d775106d37227447d33 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:15:37 -0400 Subject: [PATCH 046/488] increased verbosity level of smt_context --- src/smt/smt_context.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index ff64be64b..52b21dd80 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -3548,7 +3548,7 @@ namespace smt { return false; } if (cmr == quantifier_manager::UNKNOWN) { - IF_VERBOSE(1, verbose_stream() << "(smt.giveup quantifiers)\n";); + IF_VERBOSE(2, verbose_stream() << "(smt.giveup quantifiers)\n";); // giving up m_last_search_failure = QUANTIFIERS; status = l_undef; @@ -3558,7 +3558,7 @@ namespace smt { inc_limits(); if (status == l_true || !m_fparams.m_restart_adaptive || m_agility < m_fparams.m_restart_agility_threshold) { SASSERT(!inconsistent()); - IF_VERBOSE(1, verbose_stream() << "(smt.restarting :propagations " << m_stats.m_num_propagations + IF_VERBOSE(2, verbose_stream() << "(smt.restarting :propagations " << m_stats.m_num_propagations << " :decisions " << m_stats.m_num_decisions << " :conflicts " << m_stats.m_num_conflicts << " :restart " << m_restart_threshold; if (m_fparams.m_restart_strategy == RS_IN_OUT_GEOMETRIC) { From 5b9bf747873b42ece73636e8d0aae9c3dee012c3 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:33:41 -0400 Subject: [PATCH 047/488] Spacer engine for HORN logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The algorithms implemented in the engine are described in the following papers Anvesh Komuravelli, Nikolaj Bjørner, Arie Gurfinkel, Kenneth L. McMillan: Compositional Verification of Procedural Programs using Horn Clauses over Integers and Arrays. FMCAD 2015: 89-96 Nikolaj Bjørner, Arie Gurfinkel: Property Directed Polyhedral Abstraction. VMCAI 2015: 263-281 Anvesh Komuravelli, Arie Gurfinkel, Sagar Chaki: SMT-Based Model Checking for Recursive Programs. CAV 2014: 17-34 --- scripts/mk_project.py | 5 +- src/CMakeLists.txt | 1 + src/muz/base/dl_engine_base.h | 1 + src/muz/base/fixedpoint_params.pyg | 58 +- src/muz/fp/CMakeLists.txt | 1 + src/muz/fp/dl_register_engine.cpp | 3 + src/muz/spacer/CMakeLists.txt | 33 + src/muz/spacer/obj_equiv_class.h | 250 ++ src/muz/spacer/spacer_antiunify.cpp | 459 +++ src/muz/spacer/spacer_antiunify.h | 67 + src/muz/spacer/spacer_context.cpp | 3504 +++++++++++++++++ src/muz/spacer/spacer_context.h | 840 ++++ src/muz/spacer/spacer_dl_interface.cpp | 354 ++ src/muz/spacer/spacer_dl_interface.h | 86 + src/muz/spacer/spacer_farkas_learner.cpp | 440 +++ src/muz/spacer/spacer_farkas_learner.h | 66 + src/muz/spacer/spacer_generalizers.cpp | 294 ++ src/muz/spacer/spacer_generalizers.h | 99 + src/muz/spacer/spacer_itp_solver.cpp | 355 ++ src/muz/spacer/spacer_itp_solver.h | 177 + src/muz/spacer/spacer_legacy_frames.cpp | 170 + src/muz/spacer/spacer_legacy_frames.h | 47 + src/muz/spacer/spacer_legacy_mbp.cpp | 116 + src/muz/spacer/spacer_legacy_mev.cpp | 837 ++++ src/muz/spacer/spacer_legacy_mev.h | 117 + src/muz/spacer/spacer_manager.cpp | 386 ++ src/muz/spacer/spacer_manager.h | 345 ++ src/muz/spacer/spacer_marshal.cpp | 55 + src/muz/spacer/spacer_marshal.h | 29 + src/muz/spacer/spacer_matrix.cpp | 159 + src/muz/spacer/spacer_matrix.h | 46 + src/muz/spacer/spacer_mev_array.cpp | 217 + src/muz/spacer/spacer_mev_array.h | 52 + src/muz/spacer/spacer_min_cut.cpp | 289 ++ src/muz/spacer/spacer_min_cut.h | 52 + src/muz/spacer/spacer_notes.txt | 231 ++ src/muz/spacer/spacer_proof_utils.cpp | 332 ++ src/muz/spacer/spacer_proof_utils.h | 43 + src/muz/spacer/spacer_prop_solver.cpp | 298 ++ src/muz/spacer/spacer_prop_solver.h | 143 + src/muz/spacer/spacer_qe_project.cpp | 2333 +++++++++++ src/muz/spacer/spacer_qe_project.h | 49 + src/muz/spacer/spacer_smt_context_manager.cpp | 79 + src/muz/spacer/spacer_smt_context_manager.h | 68 + src/muz/spacer/spacer_sym_mux.cpp | 608 +++ src/muz/spacer/spacer_sym_mux.h | 256 ++ src/muz/spacer/spacer_unsat_core_learner.cpp | 360 ++ src/muz/spacer/spacer_unsat_core_learner.h | 107 + src/muz/spacer/spacer_unsat_core_plugin.cpp | 776 ++++ src/muz/spacer/spacer_unsat_core_plugin.h | 115 + src/muz/spacer/spacer_util.cpp | 1393 +++++++ src/muz/spacer/spacer_util.h | 180 + src/muz/spacer/spacer_virtual_solver.cpp | 519 +++ src/muz/spacer/spacer_virtual_solver.h | 153 + 54 files changed, 18050 insertions(+), 3 deletions(-) create mode 100644 src/muz/spacer/CMakeLists.txt create mode 100644 src/muz/spacer/obj_equiv_class.h create mode 100644 src/muz/spacer/spacer_antiunify.cpp create mode 100644 src/muz/spacer/spacer_antiunify.h create mode 100644 src/muz/spacer/spacer_context.cpp create mode 100644 src/muz/spacer/spacer_context.h create mode 100644 src/muz/spacer/spacer_dl_interface.cpp create mode 100644 src/muz/spacer/spacer_dl_interface.h create mode 100644 src/muz/spacer/spacer_farkas_learner.cpp create mode 100644 src/muz/spacer/spacer_farkas_learner.h create mode 100644 src/muz/spacer/spacer_generalizers.cpp create mode 100644 src/muz/spacer/spacer_generalizers.h create mode 100644 src/muz/spacer/spacer_itp_solver.cpp create mode 100644 src/muz/spacer/spacer_itp_solver.h create mode 100644 src/muz/spacer/spacer_legacy_frames.cpp create mode 100644 src/muz/spacer/spacer_legacy_frames.h create mode 100644 src/muz/spacer/spacer_legacy_mbp.cpp create mode 100644 src/muz/spacer/spacer_legacy_mev.cpp create mode 100644 src/muz/spacer/spacer_legacy_mev.h create mode 100644 src/muz/spacer/spacer_manager.cpp create mode 100644 src/muz/spacer/spacer_manager.h create mode 100644 src/muz/spacer/spacer_marshal.cpp create mode 100644 src/muz/spacer/spacer_marshal.h create mode 100644 src/muz/spacer/spacer_matrix.cpp create mode 100644 src/muz/spacer/spacer_matrix.h create mode 100644 src/muz/spacer/spacer_mev_array.cpp create mode 100644 src/muz/spacer/spacer_mev_array.h create mode 100644 src/muz/spacer/spacer_min_cut.cpp create mode 100644 src/muz/spacer/spacer_min_cut.h create mode 100644 src/muz/spacer/spacer_notes.txt create mode 100644 src/muz/spacer/spacer_proof_utils.cpp create mode 100644 src/muz/spacer/spacer_proof_utils.h create mode 100644 src/muz/spacer/spacer_prop_solver.cpp create mode 100644 src/muz/spacer/spacer_prop_solver.h create mode 100644 src/muz/spacer/spacer_qe_project.cpp create mode 100644 src/muz/spacer/spacer_qe_project.h create mode 100644 src/muz/spacer/spacer_smt_context_manager.cpp create mode 100644 src/muz/spacer/spacer_smt_context_manager.h create mode 100644 src/muz/spacer/spacer_sym_mux.cpp create mode 100644 src/muz/spacer/spacer_sym_mux.h create mode 100644 src/muz/spacer/spacer_unsat_core_learner.cpp create mode 100644 src/muz/spacer/spacer_unsat_core_learner.h create mode 100644 src/muz/spacer/spacer_unsat_core_plugin.cpp create mode 100644 src/muz/spacer/spacer_unsat_core_plugin.h create mode 100644 src/muz/spacer/spacer_util.cpp create mode 100644 src/muz/spacer/spacer_util.h create mode 100644 src/muz/spacer/spacer_virtual_solver.cpp create mode 100644 src/muz/spacer/spacer_virtual_solver.h diff --git a/scripts/mk_project.py b/scripts/mk_project.py index 8655346f2..b40205445 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -65,12 +65,13 @@ def init_project_def(): add_lib('transforms', ['muz', 'hilbert', 'dataflow'], 'muz/transforms') add_lib('rel', ['muz', 'transforms'], 'muz/rel') add_lib('pdr', ['muz', 'transforms', 'arith_tactics', 'core_tactics', 'smt_tactic'], 'muz/pdr') + add_lib('spacer', ['muz', 'transforms', 'arith_tactics', 'smt_tactic'], 'muz/spacer') add_lib('clp', ['muz', 'transforms'], 'muz/clp') add_lib('tab', ['muz', 'transforms'], 'muz/tab') add_lib('bmc', ['muz', 'transforms'], 'muz/bmc') add_lib('ddnf', ['muz', 'transforms', 'rel'], 'muz/ddnf') add_lib('duality_intf', ['muz', 'transforms', 'duality'], 'muz/duality') - add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf'], 'muz/fp') + add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf', 'spacer'], 'muz/fp') add_lib('nlsat_smt_tactic', ['nlsat_tactic', 'smt_tactic'], 'tactic/nlsat_smt') add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv') add_lib('sat_solver', ['solver', 'core_tactics', 'aig_tactic', 'bv_tactics', 'arith_tactics', 'sat_tactic'], 'sat/sat_solver') @@ -79,7 +80,7 @@ def init_project_def(): add_lib('portfolio', ['smtlogic_tactics', 'sat_solver', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio') add_lib('smtparser', ['portfolio'], 'parsers/smt') add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic', 'sat_solver'], 'opt') - API_files = ['z3_api.h', 'z3_ast_containers.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fixedpoint.h', 'z3_optimization.h', 'z3_interp.h', 'z3_fpa.h'] + API_files = ['z3_api.h', 'z3_ast_containers.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fixedpoint.h', 'z3_optimization.h', 'z3_interp.h', 'z3_fpa.h', 'z3_spacer.h'] add_lib('api', ['portfolio', 'smtparser', 'realclosure', 'interp', 'opt'], includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files) add_exe('shell', ['api', 'sat', 'extra_cmds','opt'], exe_name='z3') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dd440b34d..fe9fa2a82 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,7 @@ add_subdirectory(muz/tab) add_subdirectory(muz/bmc) add_subdirectory(muz/ddnf) add_subdirectory(muz/duality) +add_subdirectory(muz/spacer) add_subdirectory(muz/fp) add_subdirectory(tactic/nlsat_smt) add_subdirectory(tactic/ufbv) diff --git a/src/muz/base/dl_engine_base.h b/src/muz/base/dl_engine_base.h index b2bb3dc63..380ae6e07 100644 --- a/src/muz/base/dl_engine_base.h +++ b/src/muz/base/dl_engine_base.h @@ -25,6 +25,7 @@ namespace datalog { enum DL_ENGINE { DATALOG_ENGINE, PDR_ENGINE, + SPACER_ENGINE, QPDR_ENGINE, BMC_ENGINE, QBMC_ENGINE, diff --git a/src/muz/base/fixedpoint_params.pyg b/src/muz/base/fixedpoint_params.pyg index 8e7d6a7cb..110f081b0 100644 --- a/src/muz/base/fixedpoint_params.pyg +++ b/src/muz/base/fixedpoint_params.pyg @@ -3,7 +3,7 @@ def_module_params('fixedpoint', export=True, params=(('timeout', UINT, UINT_MAX, 'set timeout'), ('engine', SYMBOL, 'auto-config', - 'Select: auto-config, datalog, duality, pdr, bmc'), + 'Select: auto-config, datalog, duality, pdr, bmc, spacer'), ('datalog.default_table', SYMBOL, 'sparse', 'default table implementation: sparse, hashtable, bitvector, interval'), ('datalog.default_relation', SYMBOL, 'pentagon', @@ -54,6 +54,8 @@ 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"), + ('datalog.subsumption', BOOL, True, + "if true, removes/filters predicates with total transitions"), ('duality.full_expand', BOOL, False, 'Fully expand derivation trees'), ('duality.no_conj', BOOL, False, 'No forced covering (conjectures)'), ('duality.feasible_edges', BOOL, True, @@ -74,6 +76,8 @@ def_module_params('fixedpoint', ('pdr.flexible_trace', BOOL, False, "allow PDR generate long counter-examples " + "by extending candidate trace within search area"), + ('pdr.flexible_trace_depth', UINT, UINT_MAX, + 'Controls the depth (below the current level) at which flexible trace can be applied'), ('pdr.use_model_generalizer', BOOL, False, "use model for backwards propagation (instead of symbolic simulation)"), ('pdr.validate_result', BOOL, False, @@ -138,13 +142,65 @@ def_module_params('fixedpoint', ('xform.slice', BOOL, True, "simplify clause set using slicing"), ('xform.karr', BOOL, False, "Add linear invariants to clauses using Karr's method"), + ('spacer.use_eqclass', BOOL, False, "Generalizes equalities to equivalence classes"), + ('xform.transform_arrays', BOOL, False, + "Rewrites arrays equalities and applies select over store"), + ('xform.instantiate_arrays', BOOL, False, + "Transforms P(a) into P(i, a[i] a)"), + ('xform.instantiate_arrays.enforce', BOOL, False, + "Transforms P(a) into P(i, a[i]), discards a from predicate"), + ('xform.instantiate_arrays.nb_quantifier', UINT, 1, + "Gives the number of quantifiers per array"), + ('xform.instantiate_arrays.slice_technique', SYMBOL, "no-slicing", + "=> GetId(i) = i, => GetId(i) = true"), ('xform.quantify_arrays', BOOL, False, "create quantified Horn clauses from clauses with arrays"), ('xform.instantiate_quantifiers', BOOL, False, "instantiate quantified Horn clauses using E-matching heuristic"), ('xform.coalesce_rules', BOOL, False, "coalesce rules"), + ('xform.tail_simplifier_pve', BOOL, True, "propagate_variable_equivalences"), + ('xform.subsumption_checker', BOOL, True, "Enable subsumption checker (no support for model conversion)"), ('xform.coi', BOOL, True, "use cone of influence simplificaiton"), ('duality.enable_restarts', BOOL, False, 'DUALITY: enable restarts'), + ('spacer.order_children', UINT, 0, 'SPACER: order of enqueuing children in non-linear rules : 0 (original), 1 (reverse)'), + ('spacer.eager_reach_check', BOOL, True, 'SPACER: eagerly check if a query is reachable using reachability facts of predecessors'), + ('spacer.use_lemma_as_cti', BOOL, False, 'SPACER: use a lemma instead of a CTI in flexible_trace'), + ('spacer.reset_obligation_queue', BOOL, True, 'SPACER: reset obligation queue when entering a new level'), + ('spacer.init_reach_facts', BOOL, True, 'SPACER: initialize reachability facts with false'), + ('spacer.use_array_eq_generalizer', BOOL, True, 'SPACER: attempt to generalize lemmas with array equalities'), + ('spacer.use_derivations', BOOL, True, 'SPACER: using derivation mechanism to cache intermediate results for non-linear rules'), + ('xform.array_blast', BOOL, False, "try to eliminate local array terms using Ackermannization -- some array terms may remain"), + ('xform.array_blast_full', BOOL, False, "eliminate all local array variables by QE"), + ('spacer.skip_propagate', BOOL, False, "Skip propagate/pushing phase. Turns PDR into a BMC that returns either reachable or unknown"), + ('spacer.max_level', UINT, UINT_MAX, "Maximum level to explore"), + ('spacer.elim_aux', BOOL, True, "Eliminate auxiliary variables in reachability facts"), + ('spacer.reach_as_init', BOOL, True, "Extend initial rules with computed reachability facts"), + ('spacer.blast_term_ite', BOOL, True, "Expand non-Boolean ite-terms"), + ('spacer.nondet_tie_break', BOOL, False, "Break ties in obligation queue non-deterministicly"), + ('spacer.reach_dnf', BOOL, True, "Restrict reachability facts to DNF"), + ('bmc.linear_unrolling_depth', UINT, UINT_MAX, "Maximal level to explore"), + ('spacer.split_farkas_literals', BOOL, False, "Split Farkas literals"), + ('spacer.native_mbp', BOOL, False, "Use native mbp of Z3"), + ('spacer.eq_prop', BOOL, True, "Enable equality and bound propagation in arithmetic"), + ('spacer.weak_abs', BOOL, True, "Weak abstraction"), + ('spacer.restarts', BOOL, False, "Enable reseting obligation queue"), + ('spacer.restart_initial_threshold', UINT, 10, "Intial threshold for restarts"), + ('spacer.random_seed', UINT, 0, "Random seed to be used by SMT solver"), + ('spacer.ground_cti', BOOL, True, "Require CTI to be ground"), + ('spacer.vs.dump_benchmarks', BOOL, False, 'dump benchmarks in virtual solver'), + ('spacer.vs.dump_min_time', DOUBLE, 5.0, 'min time to dump benchmark'), + ('spacer.vs.recheck', BOOL, False, 're-check locally during benchmark dumping'), + ('spacer.mbqi', BOOL, True, 'use model-based quantifier instantiation'), + ('spacer.keep_proxy', BOOL, True, 'keep proxy variables (internal parameter)'), + ('spacer.instantiate', BOOL, True, 'instantiate quantified lemmas'), + ('spacer.qlemmas', BOOL, True, 'allow quantified lemmas in frames'), + ('spacer.new_unsat_core', BOOL, True, 'use the new implementation of unsat-core-generation'), + ('spacer.minimize_unsat_core', BOOL, False, 'compute unsat-core by min-cut'), + ('spacer.farkas_optimized', BOOL, True, 'use the optimized farkas plugin, which performs gaussian elimination'), + ('spacer.farkas_a_const', BOOL, True, 'if the unoptimized farkas plugin is used, use the constants from A while constructing unsat_cores'), + ('spacer.lemma_sanity_check', BOOL, False, 'check during generalization whether lemma is actually correct'), + ('spacer.reuse_pobs', BOOL, True, 'reuse POBs'), + ('spacer.simplify_pob', BOOL, False, 'simplify POBs by removing redundant constraints') )) diff --git a/src/muz/fp/CMakeLists.txt b/src/muz/fp/CMakeLists.txt index 4a7c4d018..0c5f5e915 100644 --- a/src/muz/fp/CMakeLists.txt +++ b/src/muz/fp/CMakeLists.txt @@ -12,6 +12,7 @@ z3_add_component(fp muz pdr rel + spacer tab TACTIC_HEADERS horn_tactic.h diff --git a/src/muz/fp/dl_register_engine.cpp b/src/muz/fp/dl_register_engine.cpp index 4d32cb543..b56a07a7c 100644 --- a/src/muz/fp/dl_register_engine.cpp +++ b/src/muz/fp/dl_register_engine.cpp @@ -24,6 +24,7 @@ Revision History: #include "muz/pdr/pdr_dl_interface.h" #include "muz/ddnf/ddnf.h" #include "muz/duality/duality_dl_interface.h" +#include "muz/spacer/spacer_dl_interface.h" namespace datalog { register_engine::register_engine(): m_ctx(0) {} @@ -33,6 +34,8 @@ namespace datalog { case PDR_ENGINE: case QPDR_ENGINE: return alloc(pdr::dl_interface, *m_ctx); + case SPACER_ENGINE: + return alloc(spacer::dl_interface, *m_ctx); case DATALOG_ENGINE: return alloc(rel_context, *m_ctx); case BMC_ENGINE: diff --git a/src/muz/spacer/CMakeLists.txt b/src/muz/spacer/CMakeLists.txt new file mode 100644 index 000000000..bc2f45b43 --- /dev/null +++ b/src/muz/spacer/CMakeLists.txt @@ -0,0 +1,33 @@ +z3_add_component(spacer + SOURCES + spacer_legacy_mev.cpp + spacer_legacy_frames.cpp + spacer_context.cpp + spacer_dl_interface.cpp + spacer_farkas_learner.cpp + spacer_generalizers.cpp + spacer_manager.cpp + spacer_marshal.cpp + spacer_prop_solver.cpp + spacer_smt_context_manager.cpp + spacer_sym_mux.cpp + spacer_util.cpp + spacer_itp_solver.cpp + spacer_virtual_solver.cpp + spacer_legacy_mbp.cpp + spacer_proof_utils.cpp + spacer_unsat_core_learner.cpp + spacer_unsat_core_plugin.cpp + spacer_matrix.cpp + spacer_min_cut.cpp + spacer_antiunify.cpp + spacer_mev_array.cpp + spacer_qe_project.cpp + COMPONENT_DEPENDENCIES + arith_tactics + core_tactics + muz + qe + smt_tactic + transforms + ) diff --git a/src/muz/spacer/obj_equiv_class.h b/src/muz/spacer/obj_equiv_class.h new file mode 100644 index 000000000..b3184655c --- /dev/null +++ b/src/muz/spacer/obj_equiv_class.h @@ -0,0 +1,250 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + obj_equiv_class.h + +Abstract: + "Equivalence class structure" for objs. Uses a union_find structure internally. + Operations are : + -Declare a new equivalence class with a single element + -Merge two equivalence classes + -Retrieve whether two elements are in the same equivalence class + -Iterate on all the elements of the equivalence class of a given element + -Iterate on all equivalence classes (and then within them) + +Author: + + Julien Braine + +Revision History: + +*/ + +#ifndef OBJ_EQUIV_CLASS_H_ +#define OBJ_EQUIV_CLASS_H_ + +#include "union_find.h" +#include "ast_util.h" + +namespace spacer { +//All functions naturally add their parameters to the union_find class +template +class obj_equiv_class { + basic_union_find m_uf; + obj_map m_to_int; + ref_vector m_to_obj; + + unsigned add_elem_impl(OBJ*o) { + unsigned id = m_to_obj.size(); + m_to_int.insert(o, id); + m_to_obj.push_back(o); + return id; + } + unsigned add_if_not_there(OBJ*o) { + unsigned id; + if(!m_to_int.find(o, id)) { + id = add_elem_impl(o); + } + return id; + } + +public: + class iterator; + class equiv_iterator; + friend class iterator; + friend class equiv_iterator; + + obj_equiv_class(Manager& m) : m_to_obj(m) {} + + void add_elem(OBJ*o) { + SASSERT(!m_to_int.find(o)); + add_elem_impl(o); + } + + //Invalidates all iterators + void merge(OBJ* a, OBJ* b) { + unsigned v1 = add_if_not_there(a); + unsigned v2 = add_if_not_there(b); + unsigned tmp1 = m_uf.find(v1); + unsigned tmp2 = m_uf.find(v2); + m_uf.merge(tmp1, tmp2); + } + + void reset() { + m_uf.reset(); + m_to_int.reset(); + m_to_obj.reset(); + } + + bool are_equiv(OBJ*a, OBJ*b) { + unsigned id1 = add_if_not_there(a); + unsigned id2 = add_if_not_there(b); + return m_uf.find(id1) == m_uf.find(id2); + } + + class iterator { + friend class obj_equiv_class; + private : + const obj_equiv_class& m_ouf; + unsigned m_curr_id; + bool m_first; + iterator(const obj_equiv_class& uf, unsigned id, bool f) : + m_ouf(uf), m_curr_id(id), m_first(f) {} + public : + OBJ*operator*() {return m_ouf.m_to_obj[m_curr_id];} + + iterator& operator++() { + m_curr_id = m_ouf.m_uf.next(m_curr_id); + m_first = false; + return *this; + } + bool operator==(const iterator& o) { + SASSERT(&m_ouf == &o.m_ouf); + return m_first == o.m_first && m_curr_id == o.m_curr_id; + } + bool operator!=(const iterator& o) {return !(*this == o);} + }; + + iterator begin(OBJ*o) { + unsigned id = add_if_not_there(o); + return iterator(*this, id, true); + } + iterator end(OBJ*o) { + unsigned id = add_if_not_there(o); + return iterator(*this, id, false); + } + + class eq_class { + private : + iterator m_begin; + iterator m_end; + public : + eq_class(const iterator& a, const iterator& b) : m_begin(a), m_end(b) {} + iterator begin() {return m_begin;} + iterator end() {return m_end;} + }; + + class equiv_iterator { + friend class obj_equiv_class; + private : + const obj_equiv_class& m_ouf; + unsigned m_rootnb; + equiv_iterator(const obj_equiv_class& uf, unsigned nb) : + m_ouf(uf), m_rootnb(nb) { + while(m_rootnb != m_ouf.m_to_obj.size() && + m_ouf.m_uf.is_root(m_rootnb) != true) + { m_rootnb++; } + } + public : + eq_class operator*() { + return eq_class(iterator(m_ouf, m_rootnb, true), + iterator(m_ouf, m_rootnb, false)); + } + equiv_iterator& operator++() { + do { + m_rootnb++; + } while(m_rootnb != m_ouf.m_to_obj.size() && + m_ouf.m_uf.is_root(m_rootnb) != true); + return *this; + } + bool operator==(const equiv_iterator& o) { + SASSERT(&m_ouf == &o.m_ouf); + return m_rootnb == o.m_rootnb; + } + bool operator!=(const equiv_iterator& o) {return !(*this == o);} + }; + + equiv_iterator begin() {return equiv_iterator(*this, 0);} + equiv_iterator end() {return equiv_iterator(*this, m_to_obj.size());} +}; + +typedef obj_equiv_class expr_equiv_class; + + +/** + Factors input vector v into equivalence classes and the rest + */ +inline void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv) { + ast_manager &m = v.get_manager(); + arith_util arith(m); + expr *e1, *e2; + + flatten_and(v); + unsigned j = 0; + for (unsigned i = 0; i < v.size(); ++i) { + if (m.is_eq(v.get(i), e1, e2)) { + if (arith.is_zero(e1)) { + expr* t; + t = e1; e1 = e2; e2 = t; + } + + // y + -1*x == 0 + if (arith.is_zero(e2) && arith.is_add(e1) && + to_app(e1)->get_num_args() == 2) { + expr *a0, *a1, *x; + + a0 = to_app(e1)->get_arg(0); + a1 = to_app(e1)->get_arg(1); + + if (arith.is_times_minus_one(a1, x)) { + e1 = a0; + e2 = x; + } + else if (arith.is_times_minus_one(a0, x)) { + e1 = a1; + e2 = x; + } + } + equiv.merge(e1, e2); + } + else { + if (j < i) {v[j] = v.get(i);} + j++; + } + } + v.shrink(j); +} + +/** + * converts equivalence classes to equalities + */ +inline void equiv_to_expr(expr_equiv_class &equiv, expr_ref_vector &out) { + ast_manager &m = out.get_manager(); + for (auto eq_class : equiv) { + expr *rep = nullptr; + for (expr *elem : eq_class) { + if (!m.is_value (elem)) { + rep = elem; + break; + } + } + SASSERT(rep); + for (expr *elem : eq_class) { + if (rep != elem) {out.push_back (m.mk_eq (rep, elem));} + } + } +} + +/** + * expands equivalence classes to all derivable equalities + */ +inline bool equiv_to_expr_full(expr_equiv_class &equiv, expr_ref_vector &out) { + ast_manager &m = out.get_manager(); + bool dirty = false; + for (auto eq_class : equiv) { + for (auto a = eq_class.begin(), end = eq_class.end(); a != end; ++a) { + expr_equiv_class::iterator b(a); + for (++b; b != end; ++b) { + out.push_back(m.mk_eq(*a, *b)); + dirty = true; + } + } + } + return dirty; +} + +} + +#endif diff --git a/src/muz/spacer/spacer_antiunify.cpp b/src/muz/spacer/spacer_antiunify.cpp new file mode 100644 index 000000000..56fbbb8f0 --- /dev/null +++ b/src/muz/spacer/spacer_antiunify.cpp @@ -0,0 +1,459 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_antiunify.cpp + +Abstract: + + Antiunification utilities + +Author: + + Bernhard Gleiss + Arie Gurfinkel + +Revision History: + +--*/ + +#include"spacer_antiunify.h" +#include"ast.h" +#include"rewriter.h" +#include"rewriter_def.h" +#include"arith_decl_plugin.h" +#include"ast_util.h" +#include"expr_abstract.h" + +namespace spacer { + +// Abstracts numeric values by variables +struct var_abs_rewriter : public default_rewriter_cfg { + ast_manager &m; + arith_util m_util; + ast_mark m_seen; + ast_mark m_has_num; + unsigned m_var_index; + expr_ref_vector m_pinned; + obj_map& m_substitution; + ptr_vector m_stack; + + var_abs_rewriter (ast_manager &manager, obj_map& substitution, + unsigned k = 0) : + m(manager), m_util(m), m_var_index(k), + m_pinned(m), m_substitution(substitution) {} + + void reset(unsigned k = 0) { + m_pinned.reset(); + m_var_index = k; + } + + bool pre_visit(expr * t) { + bool r = (!m_seen.is_marked(t) || m_has_num.is_marked(t)); + // only unify if convex closure will not contain non-linear multiplication + if (m_util.is_mul(t)) + { + bool contains_const_child = false; + app* a = to_app(t); + for (unsigned i=0, sz = a->get_num_args(); i < sz; ++i) { + if (m_util.is_numeral(a->get_arg(i))) { + contains_const_child = true; + } + } + if (!contains_const_child) {r = false;} + } + if (r) {m_stack.push_back (t);} + return r; + } + + + br_status reduce_app (func_decl * f, unsigned num, expr * const * args, + expr_ref & result, proof_ref & result_pr) { + expr *s; + s = m_stack.back(); + m_stack.pop_back(); + if (is_app(s)) { + app *a = to_app(s); + for (unsigned i=0, sz = a->get_num_args(); i < sz; ++i) { + if (m_has_num.is_marked(a->get_arg(i))) { + m_has_num.mark(a,true); + return BR_FAILED; + } + } + } + return BR_FAILED; + } + + bool cache_all_results() const { return false; } + bool cache_results() const { return false; } + + bool get_subst(expr * s, expr * & t, proof * & t_pr) { + if (m_util.is_numeral(s)) { + t = m.mk_var(m_var_index++, m.get_sort(s)); + m_substitution.insert(t, s); + m_pinned.push_back(t); + m_has_num.mark(s, true); + m_seen.mark(t, true); + return true; + } + return false; + } + +}; + +/* +* construct m_g, which is a generalization of t, where every constant +* is replaced by a variable for any variable in m_g, remember the +* substitution to get back t and save it in m_substitutions +*/ +anti_unifier::anti_unifier(expr* t, ast_manager& man) : m(man), m_pinned(m), m_g(m) +{ + m_pinned.push_back(t); + + obj_map substitution; + + var_abs_rewriter var_abs_cfg(m, substitution); + rewriter_tpl var_abs_rw (m, false, var_abs_cfg); + var_abs_rw (t, m_g); + + m_substitutions.push_back(substitution); //TODO: refactor into vector, remove k +} + +/* traverses m_g and t in parallel. if they only differ in constants + * (i.e. m_g contains a variable, where t contains a constant), then + * add the substitutions, which need to be applied to m_g to get t, to + * m_substitutions. +*/ +bool anti_unifier::add_term(expr* t) { + m_pinned.push_back(t); + + ptr_vector todo; + ptr_vector todo2; + todo.push_back(m_g); + todo2.push_back(t); + + ast_mark visited; + + arith_util util(m); + + obj_map substitution; + + while (!todo.empty()) { + expr* current = todo.back(); + todo.pop_back(); + expr* current2 = todo2.back(); + todo2.pop_back(); + + if (!visited.is_marked(current)) { + visited.mark(current, true); + + if (is_var(current)) { + // TODO: for now we don't allow variables in the terms we want to antiunify + SASSERT(m_substitutions[0].contains(current)); + if (util.is_numeral(current2)) { + substitution.insert(current, current2); + } + else {return false;} + } + else { + SASSERT(is_app(current)); + + if (is_app(current2) && + to_app(current)->get_decl() == to_app(current2)->get_decl() && + to_app(current)->get_num_args() == to_app(current2)->get_num_args()) { + // TODO: what to do for numerals here? E.g. if we + // have 1 and 2, do they have the same decl or are + // the decls already different? + SASSERT (!util.is_numeral(current) || current == current2); + for (unsigned i = 0, num_args = to_app(current)->get_num_args(); + i < num_args; ++i) { + todo.push_back(to_app(current)->get_arg(i)); + todo2.push_back(to_app(current2)->get_arg(i)); + } + } + else { + return false; + } + } + } + } + + // we now know that the terms can be anti-unified, so add the cached substitution + m_substitutions.push_back(substitution); + return true; +} + +/* +* returns m_g, where additionally any variable, which has only equal +* substitutions, is substituted with that substitution +*/ +void anti_unifier::finalize() { + ptr_vector todo; + todo.push_back(m_g); + + ast_mark visited; + + obj_map generalization; + + arith_util util(m); + + // post-order traversel which ignores constants and handles them + // directly when the enclosing term of the constant is handled + while (!todo.empty()) { + expr* current = todo.back(); + SASSERT(is_app(current)); + + // if we haven't already visited current + if (!visited.is_marked(current)) { + bool existsUnvisitedParent = false; + + for (unsigned i = 0, sz = to_app(current)->get_num_args(); i < sz; ++i) { + expr* argument = to_app(current)->get_arg(i); + + if (!is_var(argument)) { + SASSERT(is_app(argument)); + // if we haven't visited the current parent yet + if(!visited.is_marked(argument)) { + // add it to the stack + todo.push_back(argument); + existsUnvisitedParent = true; + } + } + } + + // if we already visited all parents, we can visit current too + if (!existsUnvisitedParent) { + visited.mark(current, true); + todo.pop_back(); + + ptr_buffer arg_list; + for (unsigned i = 0, num_args = to_app(current)->get_num_args(); + i < num_args; ++i) { + expr* argument = to_app(current)->get_arg(i); + + if (is_var(argument)) { + // compute whether there are different + // substitutions for argument + bool containsDifferentSubstitutions = false; + + for (unsigned i=0, sz = m_substitutions.size(); i+1 < sz; ++i) { + SASSERT(m_substitutions[i].contains(argument)); + SASSERT(m_substitutions[i+1].contains(argument)); + + // TODO: how to check equality? + if (m_substitutions[i][argument] != + m_substitutions[i+1][argument]) + { + containsDifferentSubstitutions = true; + break; + } + } + + // if yes, use the variable + if (containsDifferentSubstitutions) { + arg_list.push_back(argument); + } + // otherwise use the concrete value instead + // and remove the substitutions + else + { + arg_list.push_back(m_substitutions[0][argument]); + + for (unsigned i=0, sz = m_substitutions.size(); i < sz; ++i) { + SASSERT(m_substitutions[i].contains(argument)); + m_substitutions[i].remove(argument); + } + } + } + else { + SASSERT(generalization.contains(argument)); + arg_list.push_back(generalization[argument]); + } + } + + SASSERT(to_app(current)->get_num_args() == arg_list.size()); + expr_ref application(m.mk_app(to_app(current)->get_decl(), + to_app(current)->get_num_args(), + arg_list.c_ptr()), m); + m_pinned.push_back(application); + generalization.insert(current, application); + } + } + else { + todo.pop_back(); + } + } + + m_g = generalization[m_g]; +} + + +class ncc_less_than_key +{ +public: + ncc_less_than_key(arith_util& util) : m_util(util) {} + + bool operator() (const expr*& e1, const expr*& e2) { + rational val1; + rational val2; + + if (m_util.is_numeral(e1, val1) && m_util.is_numeral(e2, val2)) + { + return val1 < val2; + } + else + { + SASSERT(false); + return false; + } + } + arith_util m_util; +}; + +/* + * if there is a single interval which exactly captures each of the + * substitutions, return the corresponding closure, otherwise do + * nothing + */ +bool naive_convex_closure::compute_closure(anti_unifier& au, ast_manager& m, + expr_ref& result) { + arith_util util(m); + + SASSERT(au.get_num_substitutions() > 0); + if (au.get_substitution(0).size() == 0) { + result = au.get_generalization(); + return true; + } + + // check that all substitutions have the same size + for (unsigned i=0, sz = au.get_num_substitutions(); i+1 < sz; ++i) { + if (au.get_substitution(i).size() != au.get_substitution(i+1).size()) { + return false; + } + } + + // for each substitution entry + bool is_first_key = true; + unsigned lower_bound; + unsigned upper_bound; + for (const auto& pair : au.get_substitution(0)) { + // construct vector + expr* key = &pair.get_key(); + vector entries; + + rational val; + for (unsigned i=0, sz = au.get_num_substitutions(); i < sz; ++i) + { + if (util.is_numeral(au.get_substitution(i)[key], val) && + val.is_unsigned()) { + entries.push_back(val.get_unsigned()); + } + else { + return false; + } + } + + // check whether vector represents interval + unsigned current_lower_bound; + unsigned current_upper_bound; + + // if vector represents interval + if (get_range(entries, current_lower_bound, current_upper_bound)) { + // if interval is the same as previous interval + if (is_first_key) { + is_first_key = false; + lower_bound = current_lower_bound; + upper_bound = current_upper_bound; + } + else { + if (current_lower_bound != lower_bound || + current_upper_bound != upper_bound) { + return false; + } + } + } + // otherwise we don't do a convex closure + else { + return false; + } + } + + // we finally know that we can express the substitutions using a + // single interval, so build the expression 1. construct const + expr_ref const_ref(m.mk_const(symbol("scti!0"), util.mk_int()), m); + + // 2. construct body with const + expr_ref lit1(util.mk_le(util.mk_int(lower_bound), const_ref), m); + expr_ref lit2(util.mk_le(const_ref, util.mk_int(upper_bound)), m); + expr_ref lit3(m); + substitute_vars_by_const(m, au.get_generalization(), const_ref, lit3); + + expr_ref_vector args(m); + args.push_back(lit1); + args.push_back(lit2); + args.push_back(lit3); + expr_ref body_with_consts = mk_and(args); + + // 3. replace const by var + ptr_vector vars; + vars.push_back(const_ref); + + expr_ref body(m); + expr_abstract(m, 0, vars.size(), (expr*const*)vars.c_ptr(), body_with_consts, body); + + // 4. introduce quantifier + ptr_vector sorts; + sorts.push_back(util.mk_int()); + svector names; + names.push_back(symbol("scti!0")); + + result = expr_ref(m.mk_exists(vars.size(), sorts.c_ptr(), names.c_ptr(), body),m); + + return true; +} + +bool naive_convex_closure::get_range(vector& v, + unsigned int& lower_bound, unsigned int& upper_bound) +{ + // sort substitutions + std::sort(v.begin(), v.end()); + + // check that numbers are consecutive + for (unsigned i=0; i+1 < v.size(); ++i) { + if (v[i] + 1 != v[i+1]) { + return false; + } + } + + SASSERT(v.size() > 0); + lower_bound = v[0]; + upper_bound = v.back(); + + return true; +} + +struct subs_rewriter_cfg : public default_rewriter_cfg { + ast_manager &m; + expr_ref m_c; + + subs_rewriter_cfg (ast_manager &manager, expr* c) : m(manager), m_c(c, m) {} + + bool reduce_var(var * t, expr_ref & result, proof_ref & result_pr) { + result = m_c; + result_pr = 0; + return true; + } +}; + +void naive_convex_closure::substitute_vars_by_const(ast_manager& m, expr* t, + expr* c, expr_ref& res) { + subs_rewriter_cfg subs_cfg(m, c); + rewriter_tpl subs_rw (m, false, subs_cfg); + subs_rw (t, res); +} + +} + +template class rewriter_tpl; +template class rewriter_tpl; diff --git a/src/muz/spacer/spacer_antiunify.h b/src/muz/spacer/spacer_antiunify.h new file mode 100644 index 000000000..690bc4678 --- /dev/null +++ b/src/muz/spacer/spacer_antiunify.h @@ -0,0 +1,67 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_antiunify.h + +Abstract: + + Antiunification utilities + +Author: + + Bernhard Gleiss + Arie Gurfinkel + +Revision History: + +--*/ + +#ifndef _SPACER_ANTIUNIFY_H_ +#define _SPACER_ANTIUNIFY_H_ + +#include "ast.h" + +namespace spacer { +class anti_unifier +{ +public: + anti_unifier(expr* t, ast_manager& m); + ~anti_unifier() {} + + bool add_term(expr* t); + void finalize(); + + expr* get_generalization() {return m_g;} + unsigned get_num_substitutions() {return m_substitutions.size();} + obj_map get_substitution(unsigned index){ + SASSERT(index < m_substitutions.size()); + return m_substitutions[index]; + } + +private: + ast_manager& m; + // tracking all created expressions + expr_ref_vector m_pinned; + + expr_ref m_g; + + vector> m_substitutions; +}; + +class naive_convex_closure +{ +public: + static bool compute_closure(anti_unifier& au, ast_manager& m, + expr_ref& result); + +private: + static bool get_range(vector& v, unsigned& lower_bound, + unsigned& upper_bound); + static void substitute_vars_by_const(ast_manager& m, expr* t, expr* c, + expr_ref& res); +}; + +} +#endif diff --git a/src/muz/spacer/spacer_context.cpp b/src/muz/spacer/spacer_context.cpp new file mode 100644 index 000000000..40709de7f --- /dev/null +++ b/src/muz/spacer/spacer_context.cpp @@ -0,0 +1,3504 @@ +/** +Copyright (c) 2017 Microsoft Corporation and Arie Gurfinkel + +Module Name: + + spacer_context.cpp + +Abstract: + + SPACER predicate transformers and search context. + +Author: + + Arie Gurfinkel + Anvesh Komuravelli + + Based on muz/pdr/pdr_context.cpp by Nikolaj Bjorner (nbjorner) + +Notes: + +--*/ + + +#include +#include + +#include "dl_util.h" +#include "rewriter.h" +#include "rewriter_def.h" +#include "var_subst.h" +#include "util.h" +#include "spacer_prop_solver.h" +#include "spacer_context.h" +#include "spacer_generalizers.h" +#include "for_each_expr.h" +#include "dl_rule_set.h" +#include "unit_subsumption_tactic.h" +#include "model_smt2_pp.h" +#include "dl_mk_rule_inliner.h" +#include "ast_smt2_pp.h" +#include "ast_ll_pp.h" +#include "ast_util.h" +#include "proof_checker.h" +#include "smt_value_sort.h" +#include "proof_utils.h" +#include "scoped_proof.h" +#include "spacer_qe_project.h" +#include "blast_term_ite_tactic.h" + +#include "timeit.h" +#include "luby.h" +#include "expr_safe_replace.h" +#include "expr_abstract.h" +#include "obj_equiv_class.h" + +namespace spacer { + +// ---------------- +// pred_tansformer + +pred_transformer::pred_transformer(context& ctx, manager& pm, func_decl* head): + pm(pm), m(pm.get_manager()), + ctx(ctx), m_head(head, m), + m_sig(m), m_solver(pm, ctx.get_params(), head->get_name()), + m_reach_ctx (pm.mk_fresh3 ()), + m_pobs(*this), + m_frames(*this), + m_reach_facts(), m_rf_init_sz(0), + m_transition(m), m_initial_state(m), m_extend_lit(m), + m_all_init(false), + m_reach_case_vars(m) +{ + init_sig (); + app_ref v(m); + std::stringstream name; + name << m_head->get_name () << "_ext0"; + v = m.mk_const (symbol(name.str().c_str()), m.mk_bool_sort()); + m_extend_lit = m.mk_not (m.mk_const (pm.get_n_pred (v->get_decl ()))); +} + +pred_transformer::~pred_transformer() +{ + rule2inst::iterator it2 = m_rule2inst.begin(), end2 = m_rule2inst.end(); + for (; it2 != end2; ++it2) { + dealloc(it2->m_value); + } + rule2expr::iterator it3 = m_rule2transition.begin(), end3 = m_rule2transition.end(); + for (; it3 != end3; ++it3) { + m.dec_ref(it3->m_value); + } +} + +std::ostream& pred_transformer::display(std::ostream& out) const +{ + if (!rules().empty()) { out << "rules\n"; } + datalog::rule_manager& rm = ctx.get_datalog_context().get_rule_manager(); + for (unsigned i = 0; i < rules().size(); ++i) { + rm.display_smt2(*rules()[i], out) << "\n"; + } + out << "transition\n" << mk_pp(transition(), m) << "\n"; + return out; +} + +void pred_transformer::collect_statistics(statistics& st) const +{ + m_solver.collect_statistics(st); + st.update("SPACER num propagations", m_stats.m_num_propagations); + st.update("SPACER num properties", m_frames.lemma_size ()); + st.update("SPACER num invariants", m_stats.m_num_invariants); + + st.update ("time.spacer.init_rules.pt.init", m_initialize_watch.get_seconds ()); + st.update ("time.spacer.solve.pt.must_reachable", + m_must_reachable_watch.get_seconds ()); +} + +void pred_transformer::reset_statistics() +{ + m_solver.reset_statistics(); + //m_reachable.reset_statistics(); + m_stats.reset(); + m_initialize_watch.reset (); + m_must_reachable_watch.reset (); +} + +void pred_transformer::init_sig() +{ + for (unsigned i = 0; i < m_head->get_arity(); ++i) { + sort * arg_sort = m_head->get_domain(i); + std::stringstream name_stm; + name_stm << m_head->get_name() << '_' << i; + func_decl_ref stm(m); + stm = m.mk_func_decl(symbol(name_stm.str().c_str()), 0, (sort*const*)0, arg_sort); + m_sig.push_back(pm.get_o_pred(stm, 0)); + } +} + +void pred_transformer::ensure_level(unsigned level) +{ + if (is_infty_level(level)) { return; } + + while (m_frames.size() <= level) { + m_frames.add_frame (); + m_solver.add_level (); + } +} + +bool pred_transformer::is_must_reachable(expr* state, model_ref* model) +{ + scoped_watch _t_(m_must_reachable_watch); + SASSERT (state); + // XXX This seems to mis-handle the case when state is + // reachable using the init rule of the current transformer + if (m_reach_facts.empty()) { return false; } + + m_reach_ctx->push (); + m_reach_ctx->assert_expr (state); + m_reach_ctx->assert_expr (m.mk_not (m_reach_case_vars.back ())); + lbool res = m_reach_ctx->check_sat (0, NULL); + if (model) { m_reach_ctx->get_model(*model); } + m_reach_ctx->pop (1); + return (res == l_true); +} + + + + +reach_fact* pred_transformer::get_used_reach_fact (model_evaluator_util& mev, + bool all) +{ + expr_ref v (m); + + for (unsigned i = all ? 0 : m_rf_init_sz, sz = m_reach_case_vars.size (); + i < sz; i++) { + VERIFY (mev.eval (m_reach_case_vars.get (i), v, false)); + if (m.is_false (v)) { + return m_reach_facts.get (i); + } + } + + UNREACHABLE (); + return NULL; +} + +reach_fact *pred_transformer::get_used_origin_reach_fact (model_evaluator_util& mev, + unsigned oidx) +{ + expr_ref b(m), v(m); + reach_fact *res = NULL; + + for (unsigned i = 0, sz = m_reach_case_vars.size (); i < sz; i++) { + pm.formula_n2o (m_reach_case_vars.get (i), v, oidx); + VERIFY(mev.eval (v, b, false)); + + if (m.is_false (b)) { + res = m_reach_facts.get (i); + break; + } + } + SASSERT (res); + return res; +} + +datalog::rule const* pred_transformer::find_rule(model &model, + bool& is_concrete, + vector& reach_pred_used, + unsigned& num_reuse_reach) +{ + typedef obj_map tag2rule; + TRACE ("spacer_verbose", + datalog::rule_manager& rm = ctx.get_datalog_context().get_rule_manager(); + tag2rule::iterator it = m_tag2rule.begin(); + tag2rule::iterator end = m_tag2rule.end(); + for (; it != end; ++it) { + expr* pred = it->m_key; + tout << mk_pp(pred, m) << ":\n"; + if (it->m_value) { rm.display_smt2(*(it->m_value), tout) << "\n"; } + } + ); + + // find a rule whose tag is true in the model; + // prefer a rule where the model intersects with reach facts of all predecessors; + // also find how many predecessors' reach facts are true in the model + expr_ref vl(m); + datalog::rule const* r = ((datalog::rule*)0); + tag2rule::iterator it = m_tag2rule.begin(), end = m_tag2rule.end(); + for (; it != end; ++it) { + expr* tag = it->m_key; + if (model.eval(to_app(tag)->get_decl(), vl) && m.is_true(vl)) { + r = it->m_value; + is_concrete = true; + num_reuse_reach = 0; + reach_pred_used.reset (); + unsigned tail_sz = r->get_uninterpreted_tail_size (); + for (unsigned i = 0; i < tail_sz; i++) { + bool used = false; + func_decl* d = r->get_tail(i)->get_decl(); + pred_transformer const& pt = ctx.get_pred_transformer (d); + if (!pt.has_reach_facts()) { is_concrete = false; } + else { + expr_ref v(m); + pm.formula_n2o (pt.get_last_reach_case_var (), v, i); + model.eval (to_app (v.get ())->get_decl (), vl); + used = m.is_false (vl); + is_concrete = is_concrete && used; + } + + reach_pred_used.push_back (used); + if (used) { num_reuse_reach++; } + } + if (is_concrete) { break; } + } + } + // SASSERT (r); + // reached by a reachability fact + if (!r) { is_concrete = true; } + return r; +} + +void pred_transformer::find_predecessors(datalog::rule const& r, ptr_vector& preds) const +{ + preds.reset(); + unsigned tail_sz = r.get_uninterpreted_tail_size(); + for (unsigned ti = 0; ti < tail_sz; ti++) { + preds.push_back(r.get_tail(ti)->get_decl()); + } +} + +void pred_transformer::find_predecessors(vector >& preds) const +{ + preds.reset(); + obj_map::iterator it = m_tag2rule.begin(), end = m_tag2rule.end(); + for (; it != end; it++) { + datalog::rule const& r = *it->m_value; + unsigned tail_sz = r.get_uninterpreted_tail_size(); + for (unsigned ti = 0; ti < tail_sz; ti++) { + preds.push_back(std::make_pair (r.get_tail(ti)->get_decl(), ti)); + } + } +} + + +void pred_transformer::remove_predecessors(expr_ref_vector& literals) +{ + // remove tags + for (unsigned i = 0; i < literals.size(); ) { + expr* l = literals[i].get(); + m.is_not(l, l); + if (m_tag2rule.contains(l)) { + literals[i] = literals.back(); + literals.pop_back(); + } else { + ++i; + } + } +} + +void pred_transformer::simplify_formulas() +{ + m_frames.simplify_formulas (); +} + + +expr_ref pred_transformer::get_formulas(unsigned level, bool add_axioms) +{ + expr_ref_vector res(m); + if (add_axioms) { + res.push_back(pm.get_background()); + res.push_back((level == 0)?initial_state():transition()); + } + m_frames.get_frame_geq_lemmas (level, res); + return pm.mk_and(res); +} + +bool pred_transformer::propagate_to_next_level (unsigned src_level) +{return m_frames.propagate_to_next_level (src_level);} + + +/// \brief adds a lema to the solver and to child solvers +void pred_transformer::add_lemma_core(lemma* lemma) +{ + unsigned lvl = lemma->level(); + expr* l = lemma->get_expr(); + SASSERT(!lemma->is_ground() || is_clause(m, l)); + SASSERT(!is_quantifier(l) || is_clause(m, to_quantifier(l)->get_expr())); + + TRACE("spacer", tout << "add-lemma-core: " << pp_level (lvl) + << " " << head ()->get_name () + << " " << mk_pp (l, m) << "\n";); + + TRACE("core_array_eq", tout << "add-lemma-core: " << pp_level (lvl) + << " " << head ()->get_name () + << " " << mk_pp (l, m) << "\n";); + + STRACE ("spacer.expand-add", + tout << "add-lemma: " << pp_level (lvl) << " " + << head ()->get_name () << " " + << mk_epp (l, m) << "\n\n";); + + + if (is_infty_level(lvl)) { m_stats.m_num_invariants++; } + + if (lemma->is_ground()) { + if (is_infty_level(lvl)) { m_solver.assert_expr(l); } + else { + ensure_level (lvl); + m_solver.assert_expr (l, lvl); + } + } + + for (unsigned i = 0, sz = m_use.size (); i < sz; ++i) + { m_use [i]->add_lemma_from_child(*this, lemma, next_level(lvl)); } +} + +bool pred_transformer::add_lemma (expr *e, unsigned lvl) { + lemma_ref lem = alloc(lemma, m, e, lvl); + return m_frames.add_lemma(lem.get()); +} + +void pred_transformer::add_lemma_from_child (pred_transformer& child, + lemma* lemma, unsigned lvl) +{ + ensure_level(lvl); + expr_ref_vector fmls(m); + mk_assumptions(child.head(), lemma->get_expr(), fmls); + + for (unsigned i = 0; i < fmls.size(); ++i) { + expr_ref_vector inst(m); + expr* a = to_app(fmls.get(i))->get_arg(0); + expr* l = to_app(fmls.get(i))->get_arg(1); + if (get_context().use_instantiate()) + { lemma->mk_insts(inst, l); } + for (unsigned j=0; j < inst.size(); j++) { + inst.set(j, m.mk_implies(a, inst.get(j))); + } + if (lemma->is_ground() || get_context().use_qlemmas()) + { inst.push_back(fmls.get(i)); } + SASSERT (!inst.empty ()); + for (unsigned j = 0; j < inst.size(); ++j) { + TRACE("spacer_detail", tout << "child property: " + << mk_pp(inst.get (j), m) << "\n";); + if (is_infty_level(lvl)) + { m_solver.assert_expr(inst.get(j)); } + else + { m_solver.assert_expr(inst.get(j), lvl); } + } + } + +} + +expr* pred_transformer::mk_fresh_reach_case_var () +{ + std::stringstream name; + func_decl_ref decl(m); + + name << head ()->get_name () << "#reach_case_" << m_reach_case_vars.size (); + decl = m.mk_func_decl (symbol (name.str ().c_str ()), 0, + (sort*const*)0, m.mk_bool_sort ()); + m_reach_case_vars.push_back (m.mk_const (pm.get_n_pred (decl))); + return m_reach_case_vars.back (); +} + +expr* pred_transformer::get_reach_case_var (unsigned idx) const +{return m_reach_case_vars.get (idx);} + + +void pred_transformer::add_reach_fact (reach_fact *fact) +{ + timeit _timer (is_trace_enabled("spacer_timeit"), + "spacer::pred_transformer::add_reach_fact", + verbose_stream ()); + + TRACE ("spacer", + tout << "add_reach_fact: " << head()->get_name() << " " + << (fact->is_init () ? "INIT " : "") + << mk_pp(fact->get (), m) << "\n";); + + // -- avoid duplicates + if (fact == nullptr || get_reach_fact(fact->get())) { return; } + + // all initial facts are grouped together + SASSERT (!fact->is_init () || m_reach_facts.empty () || + m_reach_facts.back ()->is_init ()); + + m_reach_facts.push_back (fact); + if (fact->is_init()) { m_rf_init_sz++; } + + + // update m_reach_ctx + expr_ref last_var (m); + expr_ref new_var (m); + expr_ref fml (m); + + if (!m_reach_case_vars.empty()) { last_var = m_reach_case_vars.back(); } + if (fact->is_init () || !ctx.get_params ().spacer_reach_as_init ()) + { new_var = mk_fresh_reach_case_var(); } + else { + new_var = extend_initial (fact->get ())->get_arg (0); + m_reach_case_vars.push_back (new_var); + } + + SASSERT (m_reach_facts.size () == m_reach_case_vars.size ()); + + if (last_var) + { fml = m.mk_or(m.mk_not(last_var), fact->get(), new_var); } + else + { fml = m.mk_or(fact->get(), new_var); } + + m_reach_ctx->assert_expr (fml); + TRACE ("spacer", + tout << "updating reach ctx: " << mk_pp(fml, m) << "\n";); + + lemma lem(m, fml, infty_level()); + // update users; reach facts are independent of levels + for (unsigned i = 0; i < m_use.size(); ++i) { + m_use[i]->add_lemma_from_child (*this, &lem, infty_level ()); + } +} + +expr_ref pred_transformer::get_reachable() +{ + expr_ref res(m); + res = m.mk_false(); + + if (!m_reach_facts.empty()) { + expr_substitution sub(m); + expr_ref c(m), v(m); + for (unsigned i = 0, sz = sig_size(); i < sz; ++i) { + c = m.mk_const(pm.o2n(sig(i), 0)); + v = m.mk_var(i, sig(i)->get_range()); + sub.insert(c, v); + } + scoped_ptr rep = mk_expr_simp_replacer(m); + rep->set_substitution(&sub); + + expr_ref_vector args(m); + for (unsigned i = 0, sz = m_reach_facts.size (); i < sz; ++i) { + reach_fact *f; + f = m_reach_facts.get(i); + expr_ref r(m); + r = f->get(); + const ptr_vector &aux = f->aux_vars(); + if (!aux.empty()) { + // -- existentially quantify auxiliary variables + r = mk_exists (m, aux.size(), aux.c_ptr(), r); + // XXX not sure how this interacts with variable renaming later on. + // XXX For now, simply dissallow existentially quantified auxiliaries + NOT_IMPLEMENTED_YET(); + } + (*rep)(r); + + args.push_back (r); + } + res = mk_or(args); + } + return res; +} + +expr* pred_transformer::get_last_reach_case_var () const +{ + return m_reach_case_vars.empty () ? NULL : m_reach_case_vars.back (); +} + +expr_ref pred_transformer::get_cover_delta(func_decl* p_orig, int level) +{ + expr_ref result(m.mk_true(), m), v(m), c(m); + + expr_ref_vector lemmas (m); + m_frames.get_frame_lemmas (level == -1 ? infty_level() : level, lemmas); + if (!lemmas.empty()) { result = pm.mk_and(lemmas); } + + // replace local constants by bound variables. + expr_substitution sub(m); + for (unsigned i = 0; i < sig_size(); ++i) { + c = m.mk_const(pm.o2n(sig(i), 0)); + v = m.mk_var(i, sig(i)->get_range()); + sub.insert(c, v); + } + scoped_ptr rep = mk_default_expr_replacer(m); + rep->set_substitution(&sub); + (*rep)(result); + + // adjust result according to model converter. + unsigned arity = m_head->get_arity(); + model_ref md = alloc(model, m); + if (arity == 0) { + md->register_decl(m_head, result); + } else { + func_interp* fi = alloc(func_interp, m, arity); + fi->set_else(result); + md->register_decl(m_head, fi); + } + model_converter_ref mc = ctx.get_model_converter(); + apply(mc, md, 0); + if (p_orig->get_arity() == 0) { + result = md->get_const_interp(p_orig); + } else { + result = md->get_func_interp(p_orig)->get_interp(); + } + return result; +} + +/** + * get an origin summary used by this transformer in the given model + * level is the level at which may summaries are obtained + * oidx is the origin index of this predicate in the model + * must indicates whether a must or a may summary is requested + * + * returns an implicant of the summary + */ +expr_ref pred_transformer::get_origin_summary (model_evaluator_util &mev, + unsigned level, + unsigned oidx, + bool must, + const ptr_vector **aux) +{ + expr_ref_vector summary (m); + expr_ref v(m); + + if (!must) { // use may summary + summary.push_back (get_formulas (level, false)); + // -- no auxiliary variables in lemmas + *aux = NULL; + } else { // find must summary to use + reach_fact *f = get_used_origin_reach_fact (mev, oidx); + summary.push_back (f->get ()); + *aux = &f->aux_vars (); + } + + SASSERT (!summary.empty ()); + + // -- convert to origin + for (unsigned i = 0; i < summary.size(); ++i) { + pm.formula_n2o (summary.get (i), v, oidx); + summary[i] = v; + } + + // -- pick an implicant + expr_ref_vector literals (m); + compute_implicant_literals (mev, summary, literals); + + return get_manager ().mk_and (literals); +} + + +void pred_transformer::add_cover(unsigned level, expr* property) +{ + // replace bound variables by local constants. + expr_ref result(property, m), v(m), c(m); + expr_substitution sub(m); + for (unsigned i = 0; i < sig_size(); ++i) { + c = m.mk_const(pm.o2n(sig(i), 0)); + v = m.mk_var(i, sig(i)->get_range()); + sub.insert(v, c); + } + scoped_ptr rep = mk_default_expr_replacer(m); + rep->set_substitution(&sub); + (*rep)(result); + TRACE("spacer", tout << "cover:\n" << mk_pp(result, m) << "\n";); + + // add the property. + expr_ref_vector lemmas(m); + flatten_and(result, lemmas); + for (unsigned i = 0, sz = lemmas.size(); i < sz; ++i) { + add_lemma(lemmas.get(i), level); + } +} + +void pred_transformer::propagate_to_infinity (unsigned level) +{m_frames.propagate_to_infinity (level);} + + + +/// \brief Returns true if the obligation is already blocked by current lemmas +bool pred_transformer::is_blocked (pob &n, unsigned &uses_level) +{ + ensure_level (n.level ()); + prop_solver::scoped_level _sl (m_solver, n.level ()); + m_solver.set_core (NULL); + m_solver.set_model (NULL); + + expr_ref_vector post(m), aux(m); + post.push_back (n.post ()); + lbool res = m_solver.check_assumptions (post, aux, 0, NULL, 0); + if (res == l_false) { uses_level = m_solver.uses_level(); } + return res == l_false; +} + +bool pred_transformer::is_qblocked (pob &n) +{ + // XXX Trivial implementation to get us started + smt::kernel solver (m, get_manager ().fparams2()); + expr_ref_vector frame_lemmas(m); + m_frames.get_frame_geq_lemmas (n.level (), frame_lemmas); + + // assert all lemmas + for (unsigned i = 0, sz = frame_lemmas.size (); i < sz; ++i) + { solver.assert_expr(frame_lemmas.get(i)); } + // assert cti + solver.assert_expr (n.post ()); + lbool res = solver.check (); + + return res == l_false; +} + +// +// check if predicate transformer has a satisfiable predecessor state. +// returns either a satisfiable predecessor state or +// return a property that blocks state and is implied by the +// predicate transformer (or some unfolding of it). +// +lbool pred_transformer::is_reachable(pob& n, expr_ref_vector* core, + model_ref* model, unsigned& uses_level, + bool& is_concrete, datalog::rule const*& r, + vector& reach_pred_used, + unsigned& num_reuse_reach) +{ + TRACE("spacer", + tout << "is-reachable: " << head()->get_name() << " level: " + << n.level() << " depth: " << n.depth () << "\n"; + tout << mk_pp(n.post(), m) << "\n";); + timeit _timer (is_trace_enabled("spacer_timeit"), + "spacer::pred_transformer::is_reachable", + verbose_stream ()); + + ensure_level(n.level()); + + // prepare the solver + prop_solver::scoped_level _sl(m_solver, n.level()); + prop_solver::scoped_subset_core _sc (m_solver, !n.use_farkas_generalizer ()); + m_solver.set_core(core); + m_solver.set_model(model); + + expr_ref_vector post (m), reach_assumps (m); + post.push_back (n.post ()); + + // populate reach_assumps + + // XXX eager_reach_check must always be + // XXX enabled. Otherwise, we can get into an infinite loop in + // XXX which a model is consistent with a must-summary, but the + // XXX appropriate assumption is not set correctly by the model. + // XXX Original code handled reachability-events differently. + if (/* ctx.get_params ().eager_reach_check () && */ + n.level () > 0 && !m_all_init) { + obj_map::iterator it = m_tag2rule.begin (), + end = m_tag2rule.end (); + for (; it != end; ++it) { + datalog::rule const* r = it->m_value; + if (!r) { continue; } + find_predecessors(*r, m_predicates); + if (m_predicates.empty()) { continue; } + for (unsigned i = 0; i < m_predicates.size(); i++) { + const pred_transformer &pt = + ctx.get_pred_transformer (m_predicates [i]); + if (pt.has_reach_facts()) { + expr_ref a(m); + pm.formula_n2o (pt.get_last_reach_case_var (), a, i); + reach_assumps.push_back (m.mk_not (a)); + } else if (ctx.get_params().spacer_init_reach_facts()) { + reach_assumps.push_back (m.mk_not (it->m_key)); + break; + } + } + } + } + + TRACE ("spacer", + if (!reach_assumps.empty ()) { + tout << "reach assumptions\n"; + for (unsigned i = 0; i < reach_assumps.size (); i++) { + tout << mk_pp (reach_assumps.get (i), m) << "\n"; + } + } + ); + + // check local reachability; + // result is either sat (with some reach assumps) or + // unsat (even with no reach assumps) + expr *bg = m_extend_lit.get (); + lbool is_sat = m_solver.check_assumptions (post, reach_assumps, 1, &bg, 0); + + TRACE ("spacer", + if (!reach_assumps.empty ()) { + tout << "reach assumptions used\n"; + for (unsigned i = 0; i < reach_assumps.size (); i++) { + tout << mk_pp (reach_assumps.get (i), m) << "\n"; + } + } + ); + + if (is_sat == l_true || is_sat == l_undef) { + if (core) { core->reset(); } + if (model) { + r = find_rule (**model, is_concrete, reach_pred_used, num_reuse_reach); + TRACE ("spacer", tout << "reachable " + << "is_concrete " << is_concrete << " rused: "; + for (unsigned i = 0, sz = reach_pred_used.size (); i < sz; ++i) + tout << reach_pred_used [i]; + tout << "\n";); + } + + return is_sat; + } + if (is_sat == l_false) { + SASSERT (reach_assumps.empty ()); + TRACE ("spacer", tout << "unreachable with lemmas\n"; + if (core) { + tout << "Core:\n"; + for (unsigned i = 0; i < core->size (); i++) { + tout << mk_pp (core->get(i), m) << "\n"; + } + } + ); + uses_level = m_solver.uses_level(); + return l_false; + } + UNREACHABLE(); + return l_undef; +} + +bool pred_transformer::is_invariant(unsigned level, expr* lemma, + unsigned& solver_level, expr_ref_vector* core) +{ + expr_ref_vector conj(m), aux(m); + expr_ref glemma(m); + + if (false && is_quantifier(lemma)) { + SASSERT(is_forall(lemma)); + app_ref_vector tmp(m); + ground_expr(to_quantifier(lemma)->get_expr (), glemma, tmp); + lemma = glemma.get(); + } + + conj.push_back(mk_not(m, lemma)); + flatten_and (conj); + + prop_solver::scoped_level _sl(m_solver, level); + prop_solver::scoped_subset_core _sc (m_solver, true); + m_solver.set_core(core); + m_solver.set_model(0); + expr * bg = m_extend_lit.get (); + lbool r = m_solver.check_assumptions (conj, aux, 1, &bg, 1); + if (r == l_false) { + solver_level = m_solver.uses_level (); + CTRACE ("spacer", level < m_solver.uses_level (), + tout << "Checking at level " << level + << " but only using " << m_solver.uses_level () << "\n";); + SASSERT (level <= solver_level); + } + return r == l_false; +} + +bool pred_transformer::check_inductive(unsigned level, expr_ref_vector& state, + unsigned& uses_level) +{ + manager& pm = get_manager(); + expr_ref_vector conj(m), core(m); + expr_ref states(m); + states = m.mk_not(pm.mk_and(state)); + mk_assumptions(head(), states, conj); + prop_solver::scoped_level _sl(m_solver, level); + prop_solver::scoped_subset_core _sc (m_solver, true); + m_solver.set_core(&core); + m_solver.set_model (0); + expr_ref_vector aux (m); + conj.push_back (m_extend_lit); + lbool res = m_solver.check_assumptions (state, aux, conj.size (), conj.c_ptr (), 1); + if (res == l_false) { + state.reset(); + state.append(core); + uses_level = m_solver.uses_level(); + } + TRACE ("core_array_eq", + tout << "check_inductive: " + << "states: " << mk_pp (states, m) + << " is: " << res << "\n" + << "with transition: " << mk_pp (m_transition, m) << "\n";); + return res == l_false; +} + +void pred_transformer::mk_assumptions(func_decl* head, expr* fml, + expr_ref_vector& result) +{ + expr_ref tmp1(m), tmp2(m); + expr_substitution sub (m); + proof_ref pr (m.mk_asserted (m.mk_true ()), m); + obj_map::iterator it = m_tag2rule.begin(), + end = m_tag2rule.end(); + for (; it != end; ++it) { + expr* tag = it->m_key; + datalog::rule const* r = it->m_value; + if (!r) { continue; } + find_predecessors(*r, m_predicates); + for (unsigned i = 0; i < m_predicates.size(); i++) { + func_decl* d = m_predicates[i]; + if (d == head) { + tmp1 = m.mk_implies(tag, fml); + pm.formula_n2o(tmp1, tmp2, i); + result.push_back(tmp2); + } + } + } +} + +void pred_transformer::initialize(decl2rel const& pts) +{ + m_initial_state = m.mk_false(); + m_transition = m.mk_true(); + init_rules(pts, m_initial_state, m_transition); + th_rewriter rw(m); + rw(m_transition); + rw(m_initial_state); + + m_solver.assert_expr (m_transition); + m_solver.assert_expr (m_initial_state, 0); + TRACE("spacer", + tout << "Initial state: " << mk_pp(m_initial_state, m) << "\n"; + tout << "Transition: " << mk_pp(m_transition, m) << "\n";); + SASSERT(is_app(m_initial_state)); + //m_reachable.add_init(to_app(m_initial_state)); + + +} + +void pred_transformer::init_reach_facts () +{ + expr_ref_vector v(m); + reach_fact_ref fact; + + rule2expr::iterator it = m_rule2tag.begin (), end = m_rule2tag.end (); + for (; it != end; ++it) { + const datalog::rule* r = it->m_key; + if (r->get_uninterpreted_tail_size() == 0) { + fact = alloc (reach_fact, m, *r, m_rule2transition.find (r), + get_aux_vars (*r), true); + add_reach_fact (fact.get ()); + } + } +} + +void pred_transformer::init_rules(decl2rel const& pts, expr_ref& init, expr_ref& transition) +{ + expr_ref_vector transitions(m); + ptr_vector tr_rules; + datalog::rule const* rule; + expr_ref_vector disj(m), init_conds (m); + app_ref pred(m); + vector is_init; + for (unsigned i = 0; i < rules().size(); ++i) { + init_rule(pts, *rules()[i], is_init, tr_rules, transitions); + } + SASSERT (is_init.size () == transitions.size ()); + switch(transitions.size()) { + case 0: + transition = m.mk_false(); + break; + case 1: { + std::stringstream name; + // create a dummy tag. + name << head()->get_name() << "_dummy"; + pred = m.mk_const(symbol(name.str().c_str()), m.mk_bool_sort()); + rule = tr_rules[0]; + m_tag2rule.insert(pred, rule); + m_rule2tag.insert(rule, pred.get()); + transitions [0] = m.mk_implies (pred, transitions.get (0)); + transitions.push_back (m.mk_or (pred, m_extend_lit->get_arg (0))); + if (!is_init [0]) { init_conds.push_back(m.mk_not(pred)); } + + transition = pm.mk_and(transitions); + break; + } + default: + disj.push_back (m_extend_lit->get_arg (0)); + for (unsigned i = 0; i < transitions.size(); ++i) { + std::stringstream name; + name << head()->get_name() << "_tr" << i; + pred = m.mk_const(symbol(name.str().c_str()), m.mk_bool_sort()); + rule = tr_rules[i]; + m_tag2rule.insert(pred, rule); + m_rule2tag.insert(rule, pred); + disj.push_back(pred); + transitions[i] = m.mk_implies(pred, transitions[i].get()); + // update init conds + if (!is_init[i]) { + init_conds.push_back (m.mk_not (pred)); + } + } + transitions.push_back(m.mk_or(disj.size(), disj.c_ptr())); + transition = pm.mk_and(transitions); + break; + } + // mk init condition + init = pm.mk_and (init_conds); + if (init_conds.empty ()) { // no rule has uninterpreted tail + m_all_init = true; + } +} + +void pred_transformer::init_rule( + decl2rel const& pts, + datalog::rule const& rule, + vector& is_init, + ptr_vector& rules, + expr_ref_vector& transitions) +{ + scoped_watch _t_(m_initialize_watch); + + // Predicates that are variable representatives. Other predicates at + // positions the variables occur are made equivalent with these. + expr_ref_vector conj(m); + app_ref_vector& var_reprs = *(alloc(app_ref_vector, m)); + ptr_vector aux_vars; + + unsigned ut_size = rule.get_uninterpreted_tail_size(); + unsigned t_size = rule.get_tail_size(); + SASSERT(ut_size <= t_size); + init_atom(pts, rule.get_head(), var_reprs, conj, UINT_MAX); + for (unsigned i = 0; i < ut_size; ++i) { + if (rule.is_neg_tail(i)) { + throw default_exception("SPACER does not support negated predicates in rule tails"); + } + init_atom(pts, rule.get_tail(i), var_reprs, conj, i); + } + // -- substitute free variables + expr_ref fml(m); + { + expr_ref_vector tail(m); + for (unsigned i = ut_size; i < t_size; ++i) + { tail.push_back(rule.get_tail(i)); } + fml = mk_and (tail); + + ground_free_vars (fml, var_reprs, aux_vars, ut_size == 0); + SASSERT(check_filled(var_reprs)); + + expr_ref tmp(m); + var_subst (m, false)(fml, + var_reprs.size (), (expr*const*)var_reprs.c_ptr(), tmp); + flatten_and (tmp, conj); + fml = mk_and(conj); + conj.reset (); + } + + th_rewriter rw(m); + rw(fml); + if (ctx.get_params().spacer_blast_term_ite()) { + blast_term_ite (fml); + rw(fml); + } + TRACE("spacer", tout << mk_pp(fml, m) << "\n";); + + // allow quantifiers in init rule + SASSERT(ut_size == 0 || is_ground(fml)); + if (m.is_false(fml)) { + // no-op. + } else { + is_init.push_back (ut_size == 0); + transitions.push_back(fml); + m.inc_ref(fml); + m_rule2transition.insert(&rule, fml.get()); + rules.push_back(&rule); + } + m_rule2inst.insert(&rule,&var_reprs); + m_rule2vars.insert(&rule, aux_vars); + TRACE("spacer", + tout << rule.get_decl()->get_name() << "\n"; + for (unsigned i = 0; i < var_reprs.size(); ++i) { + tout << mk_pp(var_reprs[i].get(), m) << " "; + } + tout << "\n";); +} + +bool pred_transformer::check_filled(app_ref_vector const& v) const +{ + for (unsigned i = 0; i < v.size(); ++i) { + if (!v[i]) { return false; } + } + return true; +} + +// create constants for free variables in tail. +void pred_transformer::ground_free_vars(expr* e, app_ref_vector& vars, + ptr_vector& aux_vars, bool is_init) +{ + expr_free_vars fv; + fv(e); + + while (vars.size() < fv.size()) { + vars.push_back(0); + } + for (unsigned i = 0; i < fv.size(); ++i) { + if (fv[i] && !vars[i].get()) { + vars[i] = m.mk_fresh_const("aux", fv[i]); + vars[i] = m.mk_const (pm.get_n_pred (vars.get (i)->get_decl ())); + aux_vars.push_back(vars[i].get()); + } + } + +} + +// create names for variables used in relations. +void pred_transformer::init_atom( + decl2rel const& pts, + app * atom, + app_ref_vector& var_reprs, + expr_ref_vector& conj, + unsigned tail_idx + ) +{ + unsigned arity = atom->get_num_args(); + func_decl* head = atom->get_decl(); + pred_transformer& pt = *pts.find(head); + for (unsigned i = 0; i < arity; i++) { + app_ref rep(m); + + if (tail_idx == UINT_MAX) { + rep = m.mk_const(pm.o2n(pt.sig(i), 0)); + } else { + rep = m.mk_const(pm.o2o(pt.sig(i), 0, tail_idx)); + } + + expr * arg = atom->get_arg(i); + if (is_var(arg)) { + var * v = to_var(arg); + unsigned var_idx = v->get_idx(); + if (var_idx >= var_reprs.size()) { + var_reprs.resize(var_idx+1); + } + expr * repr = var_reprs[var_idx].get(); + if (repr) { + conj.push_back(m.mk_eq(rep, repr)); + } else { + var_reprs[var_idx] = rep; + } + } else { + SASSERT(is_app(arg)); + conj.push_back(m.mk_eq(rep, arg)); + } + } +} + +void pred_transformer::add_premises(decl2rel const& pts, unsigned lvl, expr_ref_vector& r) +{ + r.push_back(pm.get_background()); + r.push_back((lvl == 0)?initial_state():transition()); + for (unsigned i = 0; i < rules().size(); ++i) { + add_premises(pts, lvl, *rules()[i], r); + } +} + +void pred_transformer::add_premises(decl2rel const& pts, unsigned lvl, datalog::rule& rule, expr_ref_vector& r) +{ + find_predecessors(rule, m_predicates); + for (unsigned i = 0; i < m_predicates.size(); ++i) { + expr_ref tmp(m); + func_decl* head = m_predicates[i]; + pred_transformer& pt = *pts.find(head); + expr_ref inv = pt.get_formulas(lvl, false); + if (!m.is_true(inv)) { + pm.formula_n2o(inv, tmp, i, true); + r.push_back(tmp); + } + } +} + +void pred_transformer::inherit_properties(pred_transformer& other) +{ + m_frames.inherit_frames (other.m_frames); +} + + +lemma::lemma (ast_manager &manager, expr * body, unsigned lvl) : + m_ref_count(0), m(manager), + m_body(body, m), m_cube(m), + m_bindings(m), m_lvl(lvl), + m_pob(0), m_new_pob(false) { + SASSERT(m_body); + normalize(m_body, m_body); +} + +lemma::lemma(pob_ref const &p) : + m_ref_count(0), m(p->get_ast_manager()), + m_body(m), m_cube(m), + m_bindings(m), m_lvl(p->level()), + m_pob(p), m_new_pob(m_pob) {SASSERT(m_pob);} + +lemma::lemma(pob_ref const &p, expr_ref_vector &cube, unsigned lvl) : lemma(p) { + update_cube(p, cube); + set_level(lvl); +} + +void lemma::mk_expr_core() { + if (m_body) return; + + if (m_pob) { + mk_cube_core(); + + // make a clause by negating the cube + m_body = ::push_not(::mk_and(m_cube)); + normalize(m_body, m_body); + + if (!m_pob->is_ground() && has_zk_const(m_body)) { + app_ref_vector zks(m); + m_pob->get_skolems(zks); + zks.reverse(); + expr_abstract(m, 0, + zks.size(), (expr* const*)zks.c_ptr(), m_body, + m_body); + ptr_buffer sorts; + svector names; + for (unsigned i=0, sz=zks.size(); i < sz; ++i) { + sorts.push_back(get_sort(zks.get(i))); + names.push_back(zks.get(i)->get_decl()->get_name()); + } + m_body = m.mk_quantifier(true, zks.size(), + sorts.c_ptr(), + names.c_ptr(), + m_body, 0, symbol(m_body->get_id())); + if (m_new_pob) { + add_binding(m_pob->get_binding()); + } + } + m_new_pob = false; + return; + } + else if (!m_cube.empty()) { + m_body = ::push_not(::mk_and(m_cube)); + normalize(m_body, m_body); + return; + } + else { + UNREACHABLE(); + } + SASSERT(m_body); +} +void lemma::mk_cube_core() { + if (!m_cube.empty()) {return;} + expr_ref cube(m); + if (m_pob || m_body) { + if(m_pob) { + cube = m_pob->post(); + } + else if (m_body) { + // no quantifiers for now + SASSERT(!is_quantifier(m_body)); + cube = m_body; + cube = ::push_not(cube); + } + flatten_and(cube, m_cube); + if (m_cube.empty()) { + m_cube.push_back(m.mk_true()); + } + else { + std::sort(m_cube.c_ptr(), m_cube.c_ptr() + m_cube.size(), ast_lt_proc()); + } + } + else { + UNREACHABLE(); + } +} +bool lemma::is_false() { + // a lemma is false if + // 1. it is defined by a cube, and the cube contains a single literal 'true' + // 2. it is defined by a body, and the body is a single literal false + // 3. it is defined by a pob, and the pob post is false + if (m_cube.size() == 1) {return m.is_true(m_cube.get(0));} + else if (m_body) {return m.is_false(m_body);} + else if (m_pob) {return m.is_true(m_pob->post());} + + return false; +} +expr* lemma::get_expr() { + mk_expr_core(); + return m_body; +} +expr_ref_vector const &lemma::get_cube() { + mk_cube_core(); + return m_cube; +} + +void lemma::update_cube (pob_ref const &p, expr_ref_vector &cube) { + SASSERT(m_pob); + SASSERT(m_pob.get() == p.get()); + m_cube.reset(); + m_body.reset(); + m_cube.append(cube); + if (m_cube.empty()) {m_cube.push_back(m.mk_true());} +} + +void lemma::mk_insts(expr_ref_vector &out, expr* e) +{ + expr *lem = e == nullptr ? get_expr() : e; + if (!is_quantifier (lem) || m_bindings.empty()) {return;} + + expr *body = to_quantifier(lem)->get_expr(); + unsigned num_decls = to_quantifier(lem)->get_num_decls(); + expr_ref inst(m); + var_subst vs(m, false); + for (unsigned i = 0, + sz = m_bindings.size() / num_decls, + off = 0; + i < sz; + ++i, off += num_decls) { + inst.reset(); + vs.reset(); + vs(body, num_decls, (expr**) m_bindings.c_ptr() + off, inst); + out.push_back(inst); + } +} + +bool pred_transformer::frames::add_lemma(lemma *lem) +{ + TRACE("spacer", tout << "add-lemma: " << pp_level(lem->level()) << " " + << m_pt.head()->get_name() << " " + << mk_pp(lem->get_expr(), m_pt.get_ast_manager()) << "\n";); + + for (unsigned i = 0, sz = m_lemmas.size(); i < sz; ++i) { + if (m_lemmas [i]->get_expr() == lem->get_expr()) { + // extend bindings if needed + if (!lem->get_bindings().empty()) { + m_lemmas [i]->add_binding(lem->get_bindings()); + } + // if the lemma is at a higher level, skip it + // XXX if there are new bindings, we need to assert new instances + if (m_lemmas [i]->level() >= lem->level()) { + TRACE("spacer", tout << "Already at a higher level: " + << pp_level(m_lemmas [i]->level()) << "\n";); + return false; + } + + // update level of the existing lemma + m_lemmas [i]->set_level(lem->level()); + // assert lemma in the solver + m_pt.add_lemma_core(m_lemmas[i]); + // move the lemma to its new place to maintain sortedness + for (unsigned j = i; (j + 1) < sz && m_lt(m_lemmas [j + 1], m_lemmas[j]); ++j) { + m_lemmas.swap (j, j+1); + } + + return true; + } + } + + // did not find, create new lemma + m_lemmas.push_back(lem); + m_sorted = false; + m_pt.add_lemma_core(lem); + return true; +} + + +void pred_transformer::frames::propagate_to_infinity (unsigned level) +{ + for (unsigned i = 0, sz = m_lemmas.size (); i < sz; ++i) + if (m_lemmas[i]->level() >= level && !is_infty_level(m_lemmas [i]->level())) { + m_lemmas [i]->set_level (infty_level ()); + m_pt.add_lemma_core (m_lemmas [i]); + m_sorted = false; + } +} + +void pred_transformer::frames::sort () +{ + if (m_sorted) { return; } + + m_sorted = true; + std::sort(m_lemmas.c_ptr(), m_lemmas.c_ptr() + m_lemmas.size (), m_lt); +} + +bool pred_transformer::frames::propagate_to_next_level (unsigned level) +{ + sort (); + bool all = true; + + + if (m_lemmas.empty()) { return all; } + + unsigned tgt_level = next_level (level); + m_pt.ensure_level (tgt_level); + + for (unsigned i = 0, sz = m_lemmas.size(); i < sz && m_lemmas [i]->level() <= level;) { + if (m_lemmas [i]->level () < level) + {++i; continue;} + + + unsigned solver_level; + expr * curr = m_lemmas [i]->get_expr (); + if (m_pt.is_invariant(tgt_level, curr, solver_level)) { + m_lemmas [i]->set_level (solver_level); + m_pt.add_lemma_core (m_lemmas [i]); + + // percolate the lemma up to its new place + for (unsigned j = i; (j+1) < sz && m_lt (m_lemmas[j+1], m_lemmas[j]); ++j) { + m_lemmas.swap(j, j + 1); + } + } else { + all = false; + ++i; + } + } + + return all; +} + +void pred_transformer::frames::simplify_formulas () +{ + // number of subsumed lemmas + unsigned num_sumbsumed = 0; + + // ensure that the lemmas are sorted + sort(); + ast_manager &m = m_pt.get_ast_manager (); + + tactic_ref simplifier = mk_unit_subsumption_tactic (m); + lemma_ref_vector new_lemmas; + + unsigned lemmas_size = m_lemmas.size (); + goal_ref g (alloc (goal, m, false, false, false)); + + unsigned j = 0; + // for every frame + infinity frame + for (unsigned i = 0; i <= m_size; ++i) { + g->reset_all (); + // normalize level + unsigned level = i < m_size ? i : infty_level (); + + model_converter_ref mc; + proof_converter_ref pc; + expr_dependency_ref core(m); + goal_ref_buffer result; + + // simplify lemmas of the current level + // XXX lemmas of higher levels can be assumed in background + // XXX decide what to do with non-ground lemmas! + unsigned begin = j; + for (; j < lemmas_size && m_lemmas[j]->level() <= level; ++j) { + if (m_lemmas[j]->level() == level) { + g->assert_expr(m_lemmas[j]->get_expr()); + } + } + unsigned end = j; + + unsigned sz = end - begin; + // no lemmas at current level, move to next level + if (sz <= 0) {continue;} + + // exactly one lemma at current level, nothing to + // simplify. move to next level + if (sz == 1) { + new_lemmas.push_back(m_lemmas[begin]); + continue; + } + + // more than one lemma at current level. simplify. + (*simplifier)(g, result, mc, pc, core); + SASSERT(result.size () == 1); + goal *r = result[0]; + + // no simplification happened, copy all the lemmas + if (r->size () == sz) { + for (unsigned n = begin; n < end; ++n) { + new_lemmas.push_back (m_lemmas[n]); + } + } + // something got simplified, find out which lemmas remain + else { + num_sumbsumed += (sz - r->size()); + // For every expression in the result, copy corresponding + // lemma into new_lemmas + // XXX linear search. optimize if needed. + for (unsigned k = 0; k < r->size(); ++k) { + bool found = false; + for (unsigned n = begin; n < end; ++n) { + if (m_lemmas[n]->get_expr() == r->form(k)) { + new_lemmas.push_back(m_lemmas[n]); + found = true; + break; + } + } + if (!found) { + verbose_stream() << "Failed to find a lemma for: " + << mk_pp(r->form(k), m) << "\n"; + verbose_stream() << "Available lemmas are: "; + for (unsigned n = begin; n < end; ++n) { + verbose_stream() << n << ": " + << mk_pp(m_lemmas[n]->get_expr(), m) + << "\n"; + } + } + ENSURE(found); + SASSERT(found); + } + } + } + + SASSERT(new_lemmas.size() + num_sumbsumed == m_lemmas.size()); + ENSURE(new_lemmas.size() + num_sumbsumed == m_lemmas.size()); + if (new_lemmas.size() < m_lemmas.size()) { + m_lemmas.reset(); + m_lemmas.append(new_lemmas); + m_sorted = false; + sort(); + } +} + +pob* pred_transformer::pobs::mk_pob(pob *parent, + unsigned level, unsigned depth, + expr *post, app_ref_vector const &b) { + + if (!m_pt.ctx.get_params().spacer_reuse_pobs()) { + pob* n = alloc(pob, parent, m_pt, level, depth); + n->set_post(post, b); + return n; + } + + // create a new pob and set its post to normalize it + pob p(parent, m_pt, level, depth, false); + p.set_post(post, b); + + if (m_pobs.contains(p.post())) { + auto &buf = m_pobs[p.post()]; + for (unsigned i = 0, sz = buf.size(); i < sz; ++i) { + pob *f = buf.get(i); + if (f->parent() == parent) { + f->inherit(p); + return f; + } + } + } + + pob* n = alloc(pob, parent, m_pt, level, depth); + n->set_post(post, b); + m_pinned.push_back(n); + + if (m_pobs.contains(n->post())) { + m_pobs[n->post()].push_back(n); + } + else { + pob_buffer buf; + buf.push_back(n); + m_pobs.insert(n->post(), buf); + } + return n; +} + +app* pred_transformer::extend_initial (expr *e) +{ + // create fresh extend literal + app_ref v(m); + std::stringstream name; + name << m_head->get_name() << "_ext"; + v = m.mk_fresh_const (name.str ().c_str (), + m.mk_bool_sort ()); + v = m.mk_const (pm.get_n_pred (v->get_decl ())); + + expr_ref ic(m); + + // -- extend the initial condition + ic = m.mk_or (m_extend_lit, e, v); + m_solver.assert_expr (ic); + + // -- remember the new extend literal + m_extend_lit = m.mk_not (v); + + return m_extend_lit; +} + + +// ---------------- +// derivation + +derivation::derivation (pob& parent, datalog::rule const& rule, + expr *trans, app_ref_vector const &evars) : + m_parent (parent), + m_rule (rule), + m_premises (), + m_active (0), + m_trans (trans, m_parent.get_ast_manager ()), + m_evars (evars) {} + +derivation::premise::premise (pred_transformer &pt, unsigned oidx, + expr *summary, bool must, + const ptr_vector *aux_vars) : + m_pt (pt), m_oidx (oidx), + m_summary (summary, pt.get_ast_manager ()), m_must (must), + m_ovars (pt.get_ast_manager ()) +{ + + ast_manager &m = m_pt.get_ast_manager (); + manager &sm = m_pt.get_manager (); + + unsigned sig_sz = m_pt.head ()->get_arity (); + for (unsigned i = 0; i < sig_sz; ++i) + { m_ovars.push_back(m.mk_const(sm.o2o(pt.sig(i), 0, m_oidx))); } + + if (aux_vars) + for (unsigned i = 0, sz = aux_vars->size (); i < sz; ++i) + { m_ovars.push_back(m.mk_const(sm.n2o(aux_vars->get(i)->get_decl(), m_oidx))); } +} + +derivation::premise::premise (const derivation::premise &p) : + m_pt (p.m_pt), m_oidx (p.m_oidx), m_summary (p.m_summary), m_must (p.m_must), + m_ovars (p.m_ovars) {} + +/// \brief Updated the summary. +/// The new summary is over n-variables. +void derivation::premise::set_summary (expr * summary, bool must, + const ptr_vector *aux_vars) +{ + ast_manager &m = m_pt.get_ast_manager (); + manager &sm = m_pt.get_manager (); + unsigned sig_sz = m_pt.head ()->get_arity (); + + m_must = must; + sm.formula_n2o (summary, m_summary, m_oidx); + + m_ovars.reset (); + for (unsigned i = 0; i < sig_sz; ++i) + { m_ovars.push_back(m.mk_const(sm.o2o(m_pt.sig(i), 0, m_oidx))); } + + if (aux_vars) + for (unsigned i = 0, sz = aux_vars->size (); i < sz; ++i) + m_ovars.push_back (m.mk_const (sm.n2o (aux_vars->get (i)->get_decl (), + m_oidx))); +} + + +void derivation::add_premise (pred_transformer &pt, + unsigned oidx, + expr* summary, + bool must, + const ptr_vector *aux_vars) +{m_premises.push_back (premise (pt, oidx, summary, must, aux_vars));} + + + +pob *derivation::create_first_child (model_evaluator_util &mev) +{ + if (m_premises.empty()) { return NULL; } + m_active = 0; + return create_next_child(mev); +} + +pob *derivation::create_next_child (model_evaluator_util &mev) +{ + timeit _timer (is_trace_enabled("spacer_timeit"), + "spacer::derivation::create_next_child", + verbose_stream ()); + + ast_manager &m = get_ast_manager (); + expr_ref_vector summaries (m); + app_ref_vector vars (m); + + bool use_native_mbp = get_context ().use_native_mbp (); + bool ground = get_context ().use_ground_cti (); + // -- find first may premise + while (m_active < m_premises.size() && m_premises[m_active].is_must()) { + summaries.push_back (m_premises[m_active].get_summary ()); + vars.append (m_premises[m_active].get_ovars ()); + ++m_active; + } + if (m_active >= m_premises.size()) { return NULL; } + + // -- update m_trans with the pre-image of m_trans over the must summaries + summaries.push_back (m_trans); + m_trans = get_manager ().mk_and (summaries); + summaries.reset (); + + if (!vars.empty()) { + timeit _timer1 (is_trace_enabled("spacer_timeit"), + "create_next_child::qproject1", + verbose_stream ()); + qe_project (m, vars, m_trans, mev.get_model (), true, use_native_mbp, !ground); + //qe::reduce_array_selects (*mev.get_model (), m_trans); + // remember variables that need to be existentially quantified + m_evars.append (vars); + } + + if (!mev.is_true (m_premises[m_active].get_summary())) { + IF_VERBOSE(1, verbose_stream() << "Summary unexpectendly not true\n";); + return NULL; + } + + + // create the post condition by compute post-image over summaries + // that precede currently active premise + vars.reset (); + for (unsigned i = m_active + 1; i < m_premises.size(); ++i) { + summaries.push_back (m_premises [i].get_summary ()); + vars.append (m_premises [i].get_ovars ()); + } + summaries.push_back (m_trans); + + expr_ref post(m); + post = get_manager ().mk_and (summaries); + summaries.reset (); + if (!vars.empty()) { + timeit _timer2 (is_trace_enabled("spacer_timeit"), + "create_next_child::qproject2", + verbose_stream ()); + qe_project (m, vars, post, mev.get_model (), true, use_native_mbp, !ground); + //qe::reduce_array_selects (*mev.get_model (), post); + + // remember variables that need to be existentially quantified + m_evars.append (vars); + } + + get_manager ().formula_o2n (post.get (), post, + m_premises [m_active].get_oidx (), m_evars.empty()); + + + /* The level and depth are taken from the parent, not the sibling. + The reasoning is that the sibling has not been checked before, + and lower level is a better starting point. */ + pob *n = m_premises[m_active].pt().mk_pob(&m_parent, + prev_level (m_parent.level ()), + m_parent.depth (), post, m_evars); + + IF_VERBOSE (1, verbose_stream () + << "\n\tcreate_child: " << n->pt ().head ()->get_name () + << " (" << n->level () << ", " << n->depth () << ") " + << (n->use_farkas_generalizer () ? "FAR " : "SUB ") + << n->post ()->get_id (); + verbose_stream().flush ();); + return n; +} + +pob *derivation::create_next_child () +{ + if (m_active + 1 >= m_premises.size()) { return NULL; } + + bool use_native_mbp = get_context ().use_native_mbp (); + bool ground = get_context ().use_ground_cti (); + + // update the summary of the active node to some must summary + + // construct a new model consistent with the must summary of m_active premise + pred_transformer &pt = m_premises[m_active].pt (); + model_ref model; + + ast_manager &m = get_ast_manager (); + manager &pm = get_manager (); + + expr_ref_vector summaries (m); + + for (unsigned i = m_active + 1; i < m_premises.size (); ++i) + { summaries.push_back(m_premises [i].get_summary()); } + + // -- orient transition relation towards m_active premise + expr_ref active_trans (m); + pm.formula_o2n (m_trans, active_trans, + m_premises[m_active].get_oidx (), false); + summaries.push_back (active_trans); + + // if not true, bail out, the must summary of m_active is not strong enough + // this is possible if m_post was weakened for some reason + if (!pt.is_must_reachable(pm.mk_and(summaries), &model)) { return NULL; } + + model_evaluator_util mev (m); + mev.set_model (*model); + // find must summary used + + reach_fact *rf = pt.get_used_reach_fact (mev, true); + + // get an implicant of the summary + expr_ref_vector u(m), lits (m); + u.push_back (rf->get ()); + compute_implicant_literals (mev, u, lits); + expr_ref v(m); + v = pm.mk_and (lits); + + // XXX The summary is not used by anyone after this point + m_premises[m_active].set_summary (v, true, &(rf->aux_vars ())); + + + /** HACK: needs a rewrite + * compute post over the new must summary this must be done here + * because the must summary is currently described over new + * variables. However, we store it over old-variables, but we do + * not update the model. So we must get rid of all of the + * new-variables at this point. + */ + { + pred_transformer &pt = m_premises[m_active].pt (); + app_ref_vector vars (m); + + summaries.reset (); + summaries.push_back (v); + summaries.push_back (active_trans); + m_trans = pm.mk_and (summaries); + + // variables to eliminate + vars.append (rf->aux_vars ().size (), rf->aux_vars ().c_ptr ()); + for (unsigned i = 0, sz = pt.head ()->get_arity (); i < sz; ++i) + { vars.push_back(m.mk_const(pm.o2n(pt.sig(i), 0))); } + + if (!vars.empty ()) { + qe_project (m, vars, m_trans, mev.get_model (), true, use_native_mbp, + !ground); + // keep track of implicitly quantified variables + m_evars.append (vars); + } + } + + m_active++; + + return create_next_child (mev); +} + +pob::pob (pob* parent, pred_transformer& pt, + unsigned level, unsigned depth, bool add_to_parent): + m_ref_count (0), + m_parent (parent), m_pt (pt), + m_post (m_pt.get_ast_manager ()), + m_binding(m_pt.get_ast_manager()), + m_new_post (m_pt.get_ast_manager ()), + m_level (level), m_depth (depth), + m_open (true), m_use_farkas (true), m_weakness(0) { + if(add_to_parent && m_parent) { + m_parent->add_child(*this); + } +} + + +void pob::set_post(expr* post) { + app_ref_vector b(get_ast_manager()); + set_post(post, b); +} + +void pob::set_post(expr* post, app_ref_vector const &b) { + normalize(post, m_post, + m_pt.get_context().get_params().spacer_simplify_pob(), + m_pt.get_context().get_params().spacer_use_eqclass()); + + m_binding.reset(); + if (b.empty()) return; + + m_binding.append(b); + + std::sort (m_binding.c_ptr(), m_binding.c_ptr() + m_binding.size(), ast_lt_proc()); + + // skolemize implicit existential quantifier + ast_manager &m = get_ast_manager(); + app_ref_vector pinned(m); + + expr_safe_replace sub(m); + for (unsigned i = 0, sz = m_binding.size(); i < sz; ++i) { + expr* e; + + e = m_binding.get(i); + pinned.push_back (mk_zk_const (m, i, get_sort(e))); + sub.insert (e, pinned.back()); + } + sub(m_post); +} + +void pob::inherit(pob const &p) { + SASSERT(m_parent == p.m_parent); + SASSERT(&m_pt == &p.m_pt); + SASSERT(m_post == p.m_post); + SASSERT(!m_new_post); + + m_binding.reset(); + m_binding.append(p.m_binding); + + m_level = p.m_level; + m_depth = p.m_depth; + m_open = p.m_open; + m_use_farkas = p.m_use_farkas; + m_weakness = p.m_weakness; + + m_derivation = nullptr; +} + +void pob::clean () { + if(m_new_post) { + m_post = m_new_post; + m_new_post.reset(); + } +} + +void pob::close () { + if(!m_open) { return; } + + reset (); + m_open = false; + for (unsigned i = 0, sz = m_kids.size (); i < sz; ++i) + { m_kids [i]->close(); } +} + +void pob::get_skolems(app_ref_vector &v) { + for (unsigned i = 0, sz = m_binding.size(); i < sz; ++i) { + expr* e; + + e = m_binding.get(i); + v.push_back (mk_zk_const (get_ast_manager(), i, get_sort(e))); + } +} + + + +// ---------------- +// pob_queue + +pob* pob_queue::top () +{ + /// nothing in the queue + if (m_obligations.empty()) { return NULL; } + /// top queue element is above max level + if (m_obligations.top()->level() > m_max_level) { return NULL; } + /// top queue element is at the max level, but at a higher than base depth + if (m_obligations.top ()->level () == m_max_level && + m_obligations.top()->depth() > m_min_depth) { return NULL; } + + /// there is something good in the queue + return m_obligations.top ().get (); +} + +void pob_queue::set_root(pob& root) +{ + m_root = &root; + m_max_level = root.level (); + m_min_depth = root.depth (); + reset(); +} + +pob_queue::~pob_queue() {} + +void pob_queue::reset() +{ + while (!m_obligations.empty()) { m_obligations.pop(); } + if (m_root) { m_obligations.push(m_root); } +} + +// ---------------- +// context + +context::context(fixedpoint_params const& params, + ast_manager& m) : + m_params(params), + m(m), + m_context(0), + m_pm(params.pdr_max_num_contexts(), m), + m_query_pred(m), + m_query(0), + m_pob_queue(), + m_last_result(l_undef), + m_inductive_lvl(0), + m_expanded_lvl(0), + m_use_native_mbp(params.spacer_native_mbp ()), + m_ground_cti (params.spacer_ground_cti ()), + m_instantiate (params.spacer_instantiate ()), + m_use_qlemmas (params.spacer_qlemmas ()), + m_weak_abs(params.spacer_weak_abs()), + m_use_restarts(params.spacer_restarts()), + m_restart_initial_threshold(params.spacer_restart_initial_threshold()) +{} + +context::~context() +{ + reset_lemma_generalizers(); + reset(); +} + +void context::reset() +{ + TRACE("spacer", tout << "\n";); + m_pob_queue.reset(); + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (; it != end; ++it) { + dealloc(it->m_value); + } + m_rels.reset(); + m_query = 0; + m_last_result = l_undef; + m_inductive_lvl = 0; +} + +void context::init_rules(datalog::rule_set& rules, decl2rel& rels) +{ + scoped_watch _t_(m_init_rules_watch); + m_context = &rules.get_context(); + // Allocate collection of predicate transformers + datalog::rule_set::decl2rules::iterator dit = rules.begin_grouped_rules(), dend = rules.end_grouped_rules(); + decl2rel::obj_map_entry* e; + for (; dit != dend; ++dit) { + func_decl* pred = dit->m_key; + TRACE("spacer", tout << mk_pp(pred, m) << "\n";); + SASSERT(!rels.contains(pred)); + e = rels.insert_if_not_there2(pred, alloc(pred_transformer, *this, + get_manager(), pred)); + datalog::rule_vector const& pred_rules = *dit->m_value; + for (unsigned i = 0; i < pred_rules.size(); ++i) { + e->get_data().m_value->add_rule(pred_rules[i]); + } + } + datalog::rule_set::iterator rit = rules.begin(), rend = rules.end(); + for (; rit != rend; ++rit) { + datalog::rule* r = *rit; + pred_transformer* pt; + unsigned utz = r->get_uninterpreted_tail_size(); + for (unsigned i = 0; i < utz; ++i) { + func_decl* pred = r->get_decl(i); + if (!rels.find(pred, pt)) { + pt = alloc(pred_transformer, *this, get_manager(), pred); + rels.insert(pred, pt); + } + } + } + // Initialize use list dependencies + decl2rel::iterator it = rels.begin(), end = rels.end(); + for (; it != end; ++it) { + func_decl* pred = it->m_key; + pred_transformer* pt = it->m_value, *pt_user; + obj_hashtable const& deps = rules.get_dependencies().get_deps(pred); + obj_hashtable::iterator itf = deps.begin(), endf = deps.end(); + for (; itf != endf; ++itf) { + TRACE("spacer", tout << mk_pp(pred, m) << " " << mk_pp(*itf, m) << "\n";); + pt_user = rels.find(*itf); + pt_user->add_use(pt); + } + } + + // Initialize the predicate transformers. + it = rels.begin(), end = rels.end(); + for (; it != end; ++it) { + pred_transformer& rel = *it->m_value; + rel.initialize(rels); + TRACE("spacer", rel.display(tout); ); + } + + // initialize reach facts + it = rels.begin (), end = rels.end (); + for (; it != end; ++it) + { it->m_value->init_reach_facts(); } +} + +void context::update_rules(datalog::rule_set& rules) +{ + decl2rel rels; + init_lemma_generalizers(rules); + init_rules(rules, rels); + decl2rel::iterator it = rels.begin(), end = rels.end(); + for (; it != end; ++it) { + pred_transformer* pt = 0; + if (m_rels.find(it->m_key, pt)) { + it->m_value->inherit_properties(*pt); + } + } + reset(); + it = rels.begin(), end = rels.end(); + for (; it != end; ++it) { + m_rels.insert(it->m_key, it->m_value); + } +} + +unsigned context::get_num_levels(func_decl* p) +{ + pred_transformer* pt = 0; + if (m_rels.find(p, pt)) { + return pt->get_num_levels(); + } else { + IF_VERBOSE(10, verbose_stream() << "did not find predicate " << p->get_name() << "\n";); + return 0; + } +} + +expr_ref context::get_cover_delta(int level, func_decl* p_orig, func_decl* p) +{ + pred_transformer* pt = 0; + if (m_rels.find(p, pt)) { + return pt->get_cover_delta(p_orig, level); + } else { + IF_VERBOSE(10, verbose_stream() << "did not find predicate " << p->get_name() << "\n";); + return expr_ref(m.mk_true(), m); + } +} + +void context::add_cover(int level, func_decl* p, expr* property) +{ + pred_transformer* pt = 0; + if (!m_rels.find(p, pt)) { + pt = alloc(pred_transformer, *this, get_manager(), p); + m_rels.insert(p, pt); + IF_VERBOSE(10, verbose_stream() << "did not find predicate " << p->get_name() << "\n";); + } + unsigned lvl = (level == -1)?infty_level():((unsigned)level); + pt->add_cover(lvl, property); +} + +void context::add_invariant (func_decl *p, expr *property) +{add_cover (infty_level(), p, property);} + +expr_ref context::get_reachable(func_decl *p) +{ + pred_transformer* pt = 0; + if (!m_rels.find(p, pt)) + { return expr_ref(m.mk_false(), m); } + return pt->get_reachable(); +} + +bool context::validate() +{ + if (!m_params.pdr_validate_result()) { return true; } + + std::stringstream msg; + + switch(m_last_result) { + case l_true: { + expr_ref cex(m); + cex = get_ground_sat_answer(); + if (!cex.get()) { + IF_VERBOSE(0, verbose_stream() << "Cex validation failed\n";); + throw default_exception("Cex validation failed\n"); + return false; + } + break; + } + case l_false: { + expr_ref_vector refs(m); + expr_ref tmp(m); + model_ref model; + vector rs; + model_converter_ref mc; + get_level_property(m_inductive_lvl, refs, rs); + inductive_property ex(m, mc, rs); + ex.to_model(model); + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + var_subst vs(m, false); + for (; it != end; ++it) { + ptr_vector const& rules = it->m_value->rules(); + TRACE ("spacer", tout << "PT: " << it->m_value->head ()->get_name ().str () + << "\n";); + for (unsigned i = 0; i < rules.size(); ++i) { + datalog::rule& r = *rules[i]; + + TRACE ("spacer", + get_datalog_context (). + get_rule_manager (). + display_smt2(r, tout) << "\n";); + + model->eval(r.get_head(), tmp); + expr_ref_vector fmls(m); + fmls.push_back(m.mk_not(tmp)); + unsigned utsz = r.get_uninterpreted_tail_size(); + unsigned tsz = r.get_tail_size(); + for (unsigned j = 0; j < utsz; ++j) { + model->eval(r.get_tail(j), tmp); + fmls.push_back(tmp); + } + for (unsigned j = utsz; j < tsz; ++j) { + fmls.push_back(r.get_tail(j)); + } + tmp = m.mk_and(fmls.size(), fmls.c_ptr()); + svector names; + expr_free_vars fv; + fv (tmp); + fv.set_default_sort (m.mk_bool_sort ()); + + for (unsigned i = 0; i < fv.size(); ++i) { + names.push_back(symbol(fv.size () - i - 1)); + } + if (!fv.empty()) { + fv.reverse (); + tmp = m.mk_exists(fv.size(), fv.c_ptr(), names.c_ptr(), tmp); + } + smt::kernel solver(m, m_pm.fparams2()); + solver.assert_expr(tmp); + lbool res = solver.check(); + if (res != l_false) { + msg << "rule validation failed when checking: " + << mk_pp(tmp, m); + IF_VERBOSE(0, verbose_stream() << msg.str() << "\n";); + throw default_exception(msg.str()); + return false; + } + } + } + TRACE ("spacer", tout << "Validation Succeeded\n";); + break; + } + default: + break; + } + return true; +} + + +void context::reset_lemma_generalizers() +{ + std::for_each(m_lemma_generalizers.begin(), m_lemma_generalizers.end(), + delete_proc()); + m_lemma_generalizers.reset(); +} + +void context::init_lemma_generalizers(datalog::rule_set& rules) +{ + reset_lemma_generalizers(); + m.toggle_proof_mode(PGM_FINE); + smt_params &fparams = m_pm.fparams (); + if (!m_params.spacer_eq_prop ()) { + fparams.m_arith_bound_prop = BP_NONE; + fparams.m_arith_auto_config_simplex = true; + fparams.m_arith_propagate_eqs = false; + fparams.m_arith_eager_eq_axioms = false; + } + fparams.m_random_seed = m_params.spacer_random_seed (); + + fparams.m_dump_benchmarks = m_params.spacer_vs_dump_benchmarks(); + fparams.m_dump_min_time = m_params.spacer_vs_dump_min_time(); + fparams.m_dump_recheck = m_params.spacer_vs_recheck(); + + fparams.m_mbqi = m_params.spacer_mbqi(); + + if (get_params().spacer_use_eqclass()) { + m_lemma_generalizers.push_back (alloc(lemma_eq_generalizer, *this)); + } + + // -- AG: commented out because it is causing performance issues at the moment + //m_lemma_generalizers.push_back (alloc (unsat_core_generalizer, *this)); + + if (m_params.pdr_use_inductive_generalizer()) { + m_lemma_generalizers.push_back(alloc(lemma_bool_inductive_generalizer, *this, 0)); + } + + if (m_params.spacer_use_array_eq_generalizer()) { + m_lemma_generalizers.push_back(alloc(lemma_array_eq_generalizer, *this)); + } + + if (get_params().spacer_lemma_sanity_check()) { + m_lemma_generalizers.push_back(alloc(lemma_sanity_checker, *this)); + } + +} + +void context::get_level_property(unsigned lvl, expr_ref_vector& res, + vector& rs) const +{ + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (; it != end; ++it) { + pred_transformer* r = it->m_value; + if (r->head() == m_query_pred) { + continue; + } + expr_ref conj = r->get_formulas(lvl, false); + m_pm.formula_n2o(0, false, conj); + res.push_back(conj); + ptr_vector sig(r->head()->get_arity(), r->sig()); + rs.push_back(relation_info(m, r->head(), sig, conj)); + } +} + +void context::simplify_formulas() +{ + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (; it != end; ++it) { + pred_transformer* r = it->m_value; + r->simplify_formulas(); + } +} + +lbool context::solve(unsigned from_lvl) +{ + m_last_result = l_undef; + try { + m_last_result = solve_core (from_lvl); + if (m_last_result == l_false) { + simplify_formulas(); + m_last_result = l_false; + IF_VERBOSE(1, { + expr_ref_vector refs(m); + vector rs; + get_level_property(m_inductive_lvl, refs, rs); + model_converter_ref mc; + inductive_property ex(m, mc, rs); + verbose_stream() << ex.to_string(); + }); + + // upgrade invariants that are known to be inductive. + // decl2rel::iterator it = m_rels.begin (), end = m_rels.end (); + // for (; m_inductive_lvl > 0 && it != end; ++it) { + // if (it->m_value->head() != m_query_pred) { + // it->m_value->propagate_to_infinity (m_inductive_lvl); + // } + // } + } + VERIFY (validate ()); + } catch (unknown_exception) + {} + + if (m_last_result == l_true) { + m_stats.m_cex_depth = get_cex_depth (); + } + + if (m_params.print_statistics ()) { + statistics st; + collect_statistics (st); + st.display_smt2 (verbose_stream ()); + } + + return m_last_result; +} + + +void context::checkpoint() +{ + if (m.canceled ()) { + throw default_exception("spacer canceled"); + } +} + +unsigned context::get_cex_depth() +{ + if (m_last_result != l_true) { + IF_VERBOSE(1, + verbose_stream () + << "Trace unavailable when result is false\n";); + return 0; + } + + // treat the following as queues: read from left to right and insert at right + ptr_vector preds; + ptr_vector pts; + reach_fact_ref_vector facts; + + // temporary + reach_fact* fact; + datalog::rule const* r; + pred_transformer* pt; + + // get and discard query rule + fact = m_query->get_last_reach_fact (); + r = &fact->get_rule (); + + unsigned cex_depth = 0; + + // initialize queues + // assume that the query is only on a single predicate + // (i.e. disallow fancy queries for now) + facts.append (fact->get_justifications ()); + if (facts.size() != 1) { + // XXX AG: Escape if an assertion is about to fail + IF_VERBOSE(1, + verbose_stream () << + "Warning: counterexample is trivial or non-existent\n";); + return cex_depth; + } + SASSERT (facts.size () == 1); + m_query->find_predecessors (*r, preds); + SASSERT (preds.size () == 1); + pts.push_back (&(get_pred_transformer (preds[0]))); + + pts.push_back (NULL); // cex depth marker + + // bfs traversal of the query derivation tree + for (unsigned curr = 0; curr < pts.size (); curr++) { + // get current pt and fact + pt = pts.get (curr); + // check for depth marker + if (pt == NULL) { + ++cex_depth; + // insert new marker if there are pts at higher depth + if (curr + 1 < pts.size()) { pts.push_back(NULL); } + continue; + } + fact = facts.get (curr - cex_depth); // discount the number of markers + // get rule justifying the derivation of fact at pt + r = &fact->get_rule (); + TRACE ("spacer", + tout << "next rule: " << r->name ().str () << "\n"; + ); + // add child facts and pts + facts.append (fact->get_justifications ()); + pt->find_predecessors (*r, preds); + for (unsigned j = 0; j < preds.size (); j++) { + pts.push_back (&(get_pred_transformer (preds[j]))); + } + } + + return cex_depth; +} + +/** + \brief retrieve answer. +*/ + +void context::get_rules_along_trace(datalog::rule_ref_vector& rules) +{ + if (m_last_result != l_true) { + IF_VERBOSE(1, + verbose_stream () + << "Trace unavailable when result is false\n";); + return; + } + + // treat the following as queues: read from left to right and insert at right + ptr_vector preds; + ptr_vector pts; + reach_fact_ref_vector facts; + + // temporary + reach_fact* fact; + datalog::rule const* r; + pred_transformer* pt; + + // get query rule + fact = m_query->get_last_reach_fact (); + r = &fact->get_rule (); + rules.push_back (const_cast (r)); + TRACE ("spacer", + tout << "Initial rule: " << r->name().str() << "\n"; + ); + + // initialize queues + // assume that the query is only on a single predicate + // (i.e. disallow fancy queries for now) + facts.append (fact->get_justifications ()); + if (facts.size() != 1) { + // XXX AG: Escape if an assertion is about to fail + IF_VERBOSE(1, + verbose_stream () << + "Warning: counterexample is trivial or non-existent\n";); + return; + } + SASSERT (facts.size () == 1); + m_query->find_predecessors (*r, preds); + SASSERT (preds.size () == 1); + pts.push_back (&(get_pred_transformer (preds[0]))); + + // populate rules according to a preorder traversal of the query derivation tree + for (unsigned curr = 0; curr < pts.size (); curr++) { + // get current pt and fact + pt = pts.get (curr); + fact = facts.get (curr); + // get rule justifying the derivation of fact at pt + r = &fact->get_rule (); + rules.push_back (const_cast (r)); + TRACE ("spacer", + tout << "next rule: " << r->name ().str () << "\n"; + ); + // add child facts and pts + facts.append (fact->get_justifications ()); + pt->find_predecessors (*r, preds); + for (unsigned j = 0; j < preds.size (); j++) { + pts.push_back (&(get_pred_transformer (preds[j]))); + } + } +} + +model_ref context::get_model() +{ + model_ref model; + expr_ref_vector refs(m); + vector rs; + get_level_property(m_inductive_lvl, refs, rs); + inductive_property ex(m, const_cast(m_mc), rs); + ex.to_model (model); + return model; +} + +proof_ref context::get_proof() const +{ + return proof_ref (m); +} + +expr_ref context::get_answer() +{ + switch(m_last_result) { + case l_true: + return mk_sat_answer(); + case l_false: + return mk_unsat_answer(); + default: + return expr_ref(m.mk_true(), m); + } +} + +/** + \brief Retrieve satisfying assignment with explanation. +*/ +expr_ref context::mk_sat_answer() {return get_ground_sat_answer();} + + +expr_ref context::mk_unsat_answer() const +{ + expr_ref_vector refs(m); + vector rs; + get_level_property(m_inductive_lvl, refs, rs); + inductive_property ex(m, const_cast(m_mc), rs); + return ex.to_expr(); +} + +expr_ref context::get_ground_sat_answer() +{ + if (m_last_result != l_true) { + verbose_stream () << "Sat answer unavailable when result is false\n"; + return expr_ref (m); + } + + // treat the following as queues: read from left to right and insert at the right + reach_fact_ref_vector reach_facts; + ptr_vector preds; + ptr_vector pts; + expr_ref_vector cex (m), // pre-order list of ground instances of predicates + cex_facts (m); // equalities for the ground cex using signature constants + + // temporary + reach_fact *reach_fact; + pred_transformer* pt; + expr_ref cex_fact (m); + datalog::rule const* r; + + // get and discard query rule + reach_fact = m_query->get_last_reach_fact (); + r = &reach_fact->get_rule (); + + // initialize queues + reach_facts.append (reach_fact->get_justifications ()); + if (reach_facts.size() != 1) { + // XXX Escape if an assertion is about to fail + IF_VERBOSE(1, + verbose_stream () << + "Warning: counterexample is trivial or non-existent\n";); + return expr_ref(m.mk_true(), m); + } + m_query->find_predecessors (*r, preds); + SASSERT (preds.size () == 1); + pts.push_back (&(get_pred_transformer (preds[0]))); + cex_facts.push_back (m.mk_true ()); + + // XXX a hack to avoid assertion when query predicate is not nullary + if (preds[0]->get_arity () == 0) + { cex.push_back(m.mk_const(preds[0])); } + + // smt context to obtain local cexes + scoped_ptr cex_ctx = alloc (smt::kernel, m, m_pm.fparams2 ()); + model_evaluator_util mev (m); + + // preorder traversal of the query derivation tree + for (unsigned curr = 0; curr < pts.size (); curr++) { + // pick next pt, fact, and cex_fact + pt = pts.get (curr); + reach_fact = reach_facts[curr]; + + cex_fact = cex_facts.get (curr); + + ptr_vector child_pts; + + // get justifying rule and child facts for the derivation of reach_fact at pt + r = &reach_fact->get_rule (); + const reach_fact_ref_vector &child_reach_facts = + reach_fact->get_justifications (); + // get child pts + preds.reset(); + pt->find_predecessors(*r, preds); + for (unsigned j = 0; j < preds.size (); j++) { + child_pts.push_back (&(get_pred_transformer (preds[j]))); + } + // update the queues + reach_facts.append (child_reach_facts); + pts.append (child_pts); + + // update cex and cex_facts by making a local sat check: + // check consistency of reach facts of children, rule body, and cex_fact + cex_ctx->push (); + cex_ctx->assert_expr (cex_fact); + unsigned u_tail_sz = r->get_uninterpreted_tail_size (); + SASSERT (child_reach_facts.size () == u_tail_sz); + for (unsigned i = 0; i < u_tail_sz; i++) { + expr_ref ofml (m); + child_pts.get (i)->get_manager ().formula_n2o + (child_reach_facts[i]->get (), ofml, i); + cex_ctx->assert_expr (ofml); + } + cex_ctx->assert_expr (pt->transition ()); + cex_ctx->assert_expr (pt->rule2tag (r)); + lbool res = cex_ctx->check (); + CTRACE("cex", res == l_false, + tout << "Cex fact: " << mk_pp(cex_fact, m) << "\n"; + for (unsigned i = 0; i < u_tail_sz; i++) + tout << "Pre" << i << " " + << mk_pp(child_reach_facts[i]->get(), m) << "\n"; + tout << "Rule: "; + get_datalog_context().get_rule_manager().display_smt2(*r, tout) << "\n"; + ); + VERIFY (res == l_true); + model_ref local_mdl; + cex_ctx->get_model (local_mdl); + cex_ctx->pop (1); + + model_evaluator_util mev (m); + mev.set_model (*local_mdl); + for (unsigned i = 0; i < child_pts.size (); i++) { + pred_transformer& ch_pt = *(child_pts.get (i)); + unsigned sig_size = ch_pt.sig_size (); + expr_ref_vector ground_fact_conjs (m); + expr_ref_vector ground_arg_vals (m); + for (unsigned j = 0; j < sig_size; j++) { + expr_ref sig_arg (m), sig_val (m); + sig_arg = m.mk_const (ch_pt.get_manager ().o2o (ch_pt.sig (j), 0, i)); + VERIFY(mev.eval (sig_arg, sig_val, true)); + ground_fact_conjs.push_back (m.mk_eq (sig_arg, sig_val)); + ground_arg_vals.push_back (sig_val); + } + if (ground_fact_conjs.size () > 0) { + expr_ref ground_fact (m); + ground_fact = m.mk_and (ground_fact_conjs.size (), ground_fact_conjs.c_ptr ()); + ch_pt.get_manager ().formula_o2n (ground_fact, ground_fact, i); + cex_facts.push_back (ground_fact); + } else { + cex_facts.push_back (m.mk_true ()); + } + cex.push_back (m.mk_app (ch_pt.head (), sig_size, ground_arg_vals.c_ptr ())); + } + } + + TRACE ("spacer", + tout << "ground cex\n"; + for (unsigned i = 0; i < cex.size (); i++) { + tout << mk_pp (cex.get (i), m) << "\n"; + } + ); + + return expr_ref (m.mk_and (cex.size (), cex.c_ptr ()), m); +} + +///this is where everything starts +lbool context::solve_core (unsigned from_lvl) +{ + scoped_watch _w_(m_solve_watch); + //if there is no query predicate, abort + if (!m_rels.find(m_query_pred, m_query)) { return l_false; } + + unsigned lvl = from_lvl; + + pob *root = m_query->mk_pob(nullptr,from_lvl,0,m.mk_true()); + m_pob_queue.set_root (*root); + + unsigned max_level = get_params ().spacer_max_level (); + + for (unsigned i = 0; i < max_level; ++i) { + checkpoint(); + m_expanded_lvl = infty_level (); + m_stats.m_max_query_lvl = lvl; + + if (check_reachability()) { return l_true; } + + if (lvl > 0 && !get_params ().spacer_skip_propagate ()) + if (propagate(m_expanded_lvl, lvl, UINT_MAX)) { return l_false; } + + m_pob_queue.inc_level (); + lvl = m_pob_queue.max_level (); + m_stats.m_max_depth = std::max(m_stats.m_max_depth, lvl); + IF_VERBOSE(1,verbose_stream() << "Entering level "<< lvl << "\n";); + + STRACE("spacer.expand-add", tout << "\n* LEVEL " << lvl << "\n";); + + IF_VERBOSE(1, + if (m_params.print_statistics ()) { + statistics st; + collect_statistics (st); + }; + ); + } + // communicate failure to datalog::context + if (m_context) { m_context->set_status(datalog::BOUNDED); } + return l_undef; +} + + +// +bool context::check_reachability () +{ + scoped_watch _w_(m_reach_watch); + + timeit _timer (get_verbosity_level () >= 1, + "spacer::context::check_reachability", + verbose_stream ()); + + pob_ref last_reachable; + + if (get_params().spacer_reset_obligation_queue()) { m_pob_queue.reset(); } + + unsigned initial_size = m_stats.m_num_lemmas; + unsigned threshold = m_restart_initial_threshold; + unsigned luby_idx = 1; + + while (m_pob_queue.top()) { + pob_ref node; + checkpoint (); + + while (last_reachable) { + checkpoint (); + node = last_reachable; + last_reachable = NULL; + if (m_pob_queue.is_root(*node)) { return true; } + if (is_reachable (*node->parent())) { + last_reachable = node->parent (); + SASSERT(last_reachable->is_closed()); + last_reachable->close (); + } else if (!node->parent()->is_closed()) { + /* bump node->parent */ + node->parent ()->bump_weakness(); + } + } + + SASSERT (m_pob_queue.top ()); + // -- remove all closed nodes and updated all dirty nodes + // -- this is necessary because there is no easy way to + // -- remove nodes from the priority queue. + while (m_pob_queue.top ()->is_closed () || + m_pob_queue.top()->is_dirty()) { + pob_ref n = m_pob_queue.top (); + m_pob_queue.pop (); + if (n->is_closed()) { + IF_VERBOSE (1, + verbose_stream () << "Deleting closed node: " + << n->pt ().head ()->get_name () + << "(" << n->level () << ", " << n->depth () << ")" + << " " << n->post ()->get_id () << "\n";); + if (m_pob_queue.is_root(*n)) { return true; } + SASSERT (m_pob_queue.top ()); + } else if (n->is_dirty()) { + n->clean (); + // -- the node n might not be at the top after it is cleaned + m_pob_queue.push (*n); + } else + { UNREACHABLE(); } + } + + SASSERT (m_pob_queue.top ()); + + if (m_use_restarts && m_stats.m_num_lemmas - initial_size > threshold) { + luby_idx++; + m_stats.m_num_restarts++; + threshold = + static_cast(get_luby(luby_idx)) * m_restart_initial_threshold; + IF_VERBOSE (1, verbose_stream () + << "(restarting :lemmas " << m_stats.m_num_lemmas + << " :restart_threshold " << threshold + << ")\n";); + // -- clear obligation queue up to the root + while (!m_pob_queue.is_root(*m_pob_queue.top())) { m_pob_queue.pop(); } + initial_size = m_stats.m_num_lemmas; + } + + node = m_pob_queue.top (); + SASSERT (node->level () <= m_pob_queue.max_level ()); + switch (expand_node(*node)) { + case l_true: + SASSERT (m_pob_queue.top () == node.get ()); + m_pob_queue.pop (); + last_reachable = node; + last_reachable->close (); + if (m_pob_queue.is_root(*node)) { return true; } + break; + case l_false: + SASSERT (m_pob_queue.top () == node.get ()); + m_pob_queue.pop (); + + if (node->is_dirty()) { node->clean(); } + + node->inc_level (); + if (get_params ().pdr_flexible_trace () && + (node->level () >= m_pob_queue.max_level () || + m_pob_queue.max_level () - node->level () + <= get_params ().pdr_flexible_trace_depth ())) + { m_pob_queue.push(*node); } + + if (m_pob_queue.is_root(*node)) { return false; } + break; + case l_undef: + // SASSERT (m_pob_queue.top () != node.get ()); + break; + } + } + + UNREACHABLE(); + return false; +} + +/// check whether node n is concretely reachable +bool context::is_reachable(pob &n) +{ + scoped_watch _w_(m_is_reach_watch); + // XXX hold a reference for n during this call. + // XXX Should convert is_reachable() to accept pob_ref as argument + pob_ref nref(&n); + + TRACE ("spacer", + tout << "is-reachable: " << n.pt().head()->get_name() + << " level: " << n.level() + << " depth: " << (n.depth () - m_pob_queue.min_depth ()) << "\n" + << mk_pp(n.post(), m) << "\n";); + + stopwatch watch; + IF_VERBOSE (1, verbose_stream () << "is-reachable: " << n.pt ().head ()->get_name () + << " (" << n.level () << ", " + << (n.depth () - m_pob_queue.min_depth ()) << ") " + << (n.use_farkas_generalizer () ? "FAR " : "SUB ") + << n.post ()->get_id (); + verbose_stream().flush (); + watch.start ();); + + // used in case n is unreachable + unsigned uses_level = infty_level (); + model_ref model; + + // used in case n is reachable + bool is_concrete; + const datalog::rule * r = NULL; + // denotes which predecessor's (along r) reach facts are used + vector reach_pred_used; + unsigned num_reuse_reach = 0; + + unsigned saved = n.level (); + n.m_level = infty_level (); + lbool res = n.pt().is_reachable(n, NULL, &model, + uses_level, is_concrete, r, + reach_pred_used, num_reuse_reach); + n.m_level = saved; + + if (res != l_true || !is_concrete) { + IF_VERBOSE(1, verbose_stream () << " F " + << std::fixed << std::setprecision(2) + << watch.get_seconds () << "\n";); + return false; + } + SASSERT(res == l_true); + SASSERT(is_concrete); + + model_evaluator_util mev (m); + mev.set_model(*model); + // -- update must summary + if (r && r->get_uninterpreted_tail_size () > 0) { + reach_fact_ref rf = mk_reach_fact (n, mev, *r); + n.pt ().add_reach_fact (rf.get ()); + } + + // if n has a derivation, create a new child and report l_undef + // otherwise if n has no derivation or no new children, report l_true + pob *next = NULL; + scoped_ptr deriv; + if (n.has_derivation()) {deriv = n.detach_derivation();} + + // -- close n, it is reachable + // -- don't worry about removing n from the obligation queue + n.close (); + + if (deriv) { + next = deriv->create_next_child (); + if (next) { + SASSERT(!next->is_closed()); + // move derivation over to the next obligation + next->set_derivation(deriv.detach()); + + // remove the current node from the queue if it is at the top + if (m_pob_queue.top() == &n) { m_pob_queue.pop(); } + + m_pob_queue.push(*next); + } + } + + // either deriv was a nullptr or it was moved into next + SASSERT(!next || !deriv); + + + IF_VERBOSE(1, verbose_stream () << (next ? " X " : " T ") + << std::fixed << std::setprecision(2) + << watch.get_seconds () << "\n";); + + // recurse on the new proof obligation + return next ? is_reachable(*next) : true; +} + +//this processes a goal and creates sub-goal +lbool context::expand_node(pob& n) +{ + TRACE ("spacer", + tout << "expand-node: " << n.pt().head()->get_name() + << " level: " << n.level() + << " depth: " << (n.depth () - m_pob_queue.min_depth ()) << "\n" + << mk_pp(n.post(), m) << "\n";); + + STRACE ("spacer.expand-add", + tout << "expand-node: " << n.pt().head()->get_name() + << " level: " << n.level() + << " depth: " << (n.depth () - m_pob_queue.min_depth ()) << "\n" + << mk_epp(n.post(), m) << "\n\n";); + + TRACE ("core_array_eq", + tout << "expand-node: " << n.pt().head()->get_name() + << " level: " << n.level() + << " depth: " << (n.depth () - m_pob_queue.min_depth ()) << "\n" + << mk_pp(n.post(), m) << "\n";); + + stopwatch watch; + IF_VERBOSE (1, verbose_stream () << "expand: " << n.pt ().head ()->get_name () + << " (" << n.level () << ", " + << (n.depth () - m_pob_queue.min_depth ()) << ") " + << (n.use_farkas_generalizer () ? "FAR " : "SUB ") + << " w(" << n.weakness() << ") " + << n.post ()->get_id (); + verbose_stream().flush (); + watch.start ();); + + // used in case n is unreachable + unsigned uses_level = infty_level (); + expr_ref_vector cube(m); + model_ref model; + + // used in case n is reachable + bool is_concrete; + const datalog::rule * r = NULL; + // denotes which predecessor's (along r) reach facts are used + vector reach_pred_used; + unsigned num_reuse_reach = 0; + + + if (get_params().pdr_flexible_trace() && n.pt().is_blocked(n, uses_level)) { + // if (!m_pob_queue.is_root (n)) n.close (); + IF_VERBOSE (1, verbose_stream () << " K " + << std::fixed << std::setprecision(2) + << watch.get_seconds () << "\n";); + + return l_false; + } + + smt_params &fparams = m_pm.fparams(); + flet _arith_ignore_int_(fparams.m_arith_ignore_int, + m_weak_abs && n.weakness() < 1); + flet _array_weak_(fparams.m_array_weak, + m_weak_abs && n.weakness() < 2); + + lbool res = n.pt ().is_reachable (n, &cube, &model, uses_level, is_concrete, r, + reach_pred_used, num_reuse_reach); + checkpoint (); + IF_VERBOSE (1, verbose_stream () << "." << std::flush;); + switch (res) { + //reachable but don't know if this is purely using UA + case l_true: { + // update stats + m_stats.m_num_reuse_reach += num_reuse_reach; + + model_evaluator_util mev (m); + mev.set_model (*model); + // must-reachable + if (is_concrete) { + // -- update must summary + if (r && r->get_uninterpreted_tail_size() > 0) { + reach_fact_ref rf = mk_reach_fact (n, mev, *r); + checkpoint (); + n.pt ().add_reach_fact (rf.get ()); + checkpoint (); + } + + // if n has a derivation, create a new child and report l_undef + // otherwise if n has no derivation or no new children, report l_true + pob *next = NULL; + scoped_ptr deriv; + if (n.has_derivation()) {deriv = n.detach_derivation();} + + // -- close n, it is reachable + // -- don't worry about removing n from the obligation queue + n.close (); + + if (deriv) { + next = deriv->create_next_child (); + checkpoint (); + if (next) { + // move derivation over to the next obligation + next->set_derivation (deriv.detach()); + + // remove the current node from the queue if it is at the top + if (m_pob_queue.top() == &n) { m_pob_queue.pop(); } + + m_pob_queue.push (*next); + } + } + + + IF_VERBOSE(1, verbose_stream () << (next ? " X " : " T ") + << std::fixed << std::setprecision(2) + << watch.get_seconds () << "\n";); + return next ? l_undef : l_true; + } + + // create a child of n + VERIFY(create_children (n, *r, mev, reach_pred_used)); + IF_VERBOSE(1, verbose_stream () << " U " + << std::fixed << std::setprecision(2) + << watch.get_seconds () << "\n";); + return l_undef; + + } + // n is unreachable, create new summary facts + case l_false: { + timeit _timer (is_trace_enabled("spacer_timeit"), + "spacer::expand_node::false", + verbose_stream ()); + + // -- only update expanded level when new lemmas are generated at it. + if (n.level() < m_expanded_lvl) { m_expanded_lvl = n.level(); } + + TRACE("spacer", tout << "cube:\n"; + for (unsigned j = 0; j < cube.size(); ++j) + tout << mk_pp(cube[j].get(), m) << "\n";); + + + pob_ref nref(&n); + // -- create lemma from a pob and last unsat core + lemma_ref lemma = alloc(class lemma, pob_ref(&n), cube, uses_level); + + // -- run all lemma generalizers + for (unsigned i = 0; + // -- only generalize if lemma was constructed using farkas + n.use_farkas_generalizer () && !lemma->is_false() && + i < m_lemma_generalizers.size(); ++i) { + checkpoint (); + (*m_lemma_generalizers[i])(lemma); + } + + TRACE("spacer", tout << "invariant state: " + << (is_infty_level(lemma->level())?"(inductive)":"") + << mk_pp(lemma->get_expr(), m) << "\n";); + + bool v = n.pt().add_lemma (lemma.get()); + if (v) { m_stats.m_num_lemmas++; } + + // Optionally update the node to be the negation of the lemma + if (v && get_params().spacer_use_lemma_as_cti()) { + n.new_post (mk_and(lemma->get_cube())); + n.set_farkas_generalizer (false); + } + CASSERT("spacer", n.level() == 0 || check_invariant(n.level()-1)); + + + IF_VERBOSE(1, verbose_stream () << " F " + << std::fixed << std::setprecision(2) + << watch.get_seconds () << "\n";); + + return l_false; + } + case l_undef: + // something went wrong + if (n.weakness() < 100 /* MAX_WEAKENSS */) { + bool has_new_child = false; + SASSERT(m_weak_abs); + m_stats.m_expand_node_undef++; + if (r && r->get_uninterpreted_tail_size() > 0) { + model_evaluator_util mev(m); + mev.set_model(*model); + // do not trust reach_pred_used + for (unsigned i = 0, sz = reach_pred_used.size(); i < sz; ++i) + { reach_pred_used[i] = false; } + has_new_child = create_children(n,*r,mev,reach_pred_used); + } + IF_VERBOSE(1, verbose_stream() << " UNDEF " + << std::fixed << std::setprecision(2) + << watch.get_seconds () << "\n";); + if (has_new_child) { return l_undef; } + + // -- failed to create a child, bump weakness and repeat + // -- the recursion is bounded by the levels of weakness supported + n.bump_weakness(); + return expand_node(n); + } + TRACE("spacer", tout << "unknown state: " + << mk_pp(m_pm.mk_and(cube), m) << "\n";); + throw unknown_exception(); + } + UNREACHABLE(); + throw unknown_exception(); +} + +// +// check if predicate transformer has a satisfiable predecessor state. +// returns either a satisfiable predecessor state or +// return a property that blocks state and is implied by the +// predicate transformer (or some unfolding of it). +// + +bool context::propagate(unsigned min_prop_lvl, + unsigned max_prop_lvl, unsigned full_prop_lvl) +{ + scoped_watch _w_(m_propagate_watch); + + if (min_prop_lvl == infty_level()) { return false; } + + timeit _timer (get_verbosity_level() >= 1, + "spacer::context::propagate", + verbose_stream ()); + + if (full_prop_lvl < max_prop_lvl) { full_prop_lvl = max_prop_lvl; } + + if (m_params.pdr_simplify_formulas_pre()) { + simplify_formulas(); + } + IF_VERBOSE (1, verbose_stream () << "Propagating: " << std::flush;); + + for (unsigned lvl = min_prop_lvl; lvl <= full_prop_lvl; lvl++) { + IF_VERBOSE (1, + if (lvl > max_prop_lvl && lvl == max_prop_lvl + 1) + verbose_stream () << " ! "; + verbose_stream () << lvl << " " << std::flush;); + + checkpoint(); + CTRACE ("spacer", lvl > max_prop_lvl && lvl == max_prop_lvl + 1, + tout << "In full propagation\n";); + + bool all_propagated = true; + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (; it != end; ++it) { + checkpoint(); + pred_transformer& r = *it->m_value; + all_propagated = r.propagate_to_next_level(lvl) && all_propagated; + } + //CASSERT("spacer", check_invariant(lvl)); + + if (all_propagated) { + for (it = m_rels.begin(); it != end; ++it) { + checkpoint (); + pred_transformer& r = *it->m_value; + r.propagate_to_infinity (lvl); + } + if (lvl <= max_prop_lvl) { + m_inductive_lvl = lvl; + IF_VERBOSE(1, verbose_stream () << "\n";); + return true; + } + break; + } + + if (all_propagated && lvl == max_prop_lvl) { + m_inductive_lvl = lvl; + return true; + } else if (all_propagated && lvl > max_prop_lvl) { break; } + } + if (m_params.pdr_simplify_formulas_post()) { + simplify_formulas(); + } + + IF_VERBOSE(1, verbose_stream () << "\n";); + return false; +} + +reach_fact *context::mk_reach_fact (pob& n, model_evaluator_util &mev, + const datalog::rule& r) +{ + timeit _timer1 (is_trace_enabled("spacer_timeit"), + "mk_reach_fact", + verbose_stream ()); + expr_ref res(m); + reach_fact_ref_vector child_reach_facts; + + pred_transformer& pt = n.pt (); + + ptr_vector preds; + pt.find_predecessors (r, preds); + + expr_ref_vector path_cons (m); + path_cons.push_back (pt.get_transition (r)); + app_ref_vector vars (m); + + for (unsigned i = 0; i < preds.size (); i++) { + func_decl* pred = preds[i]; + pred_transformer& ch_pt = get_pred_transformer (pred); + // get a reach fact of body preds used in the model + expr_ref o_ch_reach (m); + reach_fact *kid = ch_pt.get_used_origin_reach_fact (mev, i); + child_reach_facts.push_back (kid); + m_pm.formula_n2o (kid->get (), o_ch_reach, i); + path_cons.push_back (o_ch_reach); + // collect o-vars to eliminate + for (unsigned j = 0; j < pred->get_arity (); j++) + { vars.push_back(m.mk_const(m_pm.o2o(ch_pt.sig(j), 0, i))); } + + const ptr_vector &v = kid->aux_vars (); + for (unsigned j = 0, sz = v.size (); j < sz; ++j) + { vars.push_back(m.mk_const(m_pm.n2o(v [j]->get_decl(), i))); } + } + // collect aux vars to eliminate + ptr_vector& aux_vars = pt.get_aux_vars (r); + bool elim_aux = get_params ().spacer_elim_aux (); + if (elim_aux) { vars.append(aux_vars.size(), aux_vars.c_ptr()); } + + res = m_pm.mk_and (path_cons); + + // -- pick an implicant from the path condition + if (get_params().spacer_reach_dnf()) { + expr_ref_vector u(m), lits(m); + u.push_back (res); + compute_implicant_literals (mev, u, lits); + res = m_pm.mk_and (lits); + } + + + TRACE ("spacer", + tout << "Reach fact, before QE:\n"; + tout << mk_pp (res, m) << "\n"; + tout << "Vars:\n"; + for (unsigned i = 0; i < vars.size(); ++i) { + tout << mk_pp(vars.get (i), m) << "\n"; + } + ); + + { + timeit _timer1 (is_trace_enabled("spacer_timeit"), + "mk_reach_fact::qe_project", + verbose_stream ()); + qe_project (m, vars, res, mev.get_model (), false, m_use_native_mbp); + } + + + TRACE ("spacer", + tout << "Reach fact, after QE project:\n"; + tout << mk_pp (res, m) << "\n"; + tout << "Vars:\n"; + for (unsigned i = 0; i < vars.size(); ++i) { + tout << mk_pp(vars.get (i), m) << "\n"; + } + ); + + SASSERT (vars.empty ()); + + m_stats.m_num_reach_queries++; + ptr_vector empty; + reach_fact *f = alloc(reach_fact, m, r, res, elim_aux ? empty : aux_vars); + for (unsigned i = 0, sz = child_reach_facts.size (); i < sz; ++i) + { f->add_justification(child_reach_facts.get(i)); } + return f; +} + + +/** + \brief create children states from model cube. +*/ +bool context::create_children(pob& n, datalog::rule const& r, + model_evaluator_util &mev, + const vector &reach_pred_used) +{ + + scoped_watch _w_ (m_create_children_watch); + pred_transformer& pt = n.pt(); + expr* const T = pt.get_transition(r); + expr* const phi = n.post(); + + TRACE("spacer", + tout << "Model:\n"; + model_smt2_pp(tout, m, *mev.get_model (), 0); + tout << "\n"; + tout << "Transition:\n" << mk_pp(T, m) << "\n"; + tout << "Phi:\n" << mk_pp(phi, m) << "\n";); + + SASSERT (r.get_uninterpreted_tail_size () > 0); + + ptr_vector preds; + pt.find_predecessors(r, preds); + + ptr_vector pred_pts; + + for (ptr_vector::iterator it = preds.begin (); + it != preds.end (); it++) { + pred_pts.push_back (&get_pred_transformer (*it)); + } + + expr_ref_vector forms(m), Phi(m); + + // obtain all formulas to consider for model generalization + forms.push_back(T); + forms.push_back(phi); + + compute_implicant_literals (mev, forms, Phi); + + //pt.remove_predecessors (Phi); + + app_ref_vector vars(m); + unsigned sig_size = pt.head()->get_arity(); + for (unsigned i = 0; i < sig_size; ++i) { + vars.push_back(m.mk_const(m_pm.o2n(pt.sig(i), 0))); + } + ptr_vector& aux_vars = pt.get_aux_vars(r); + vars.append(aux_vars.size(), aux_vars.c_ptr()); + + n.get_skolems(vars); + + expr_ref phi1 = m_pm.mk_and (Phi); + qe_project (m, vars, phi1, mev.get_model (), true, + m_use_native_mbp, !m_ground_cti); + //qe::reduce_array_selects (*mev.get_model (), phi1); + SASSERT (!m_ground_cti || vars.empty ()); + + TRACE ("spacer", + tout << "Implicant\n"; + tout << mk_pp (m_pm.mk_and (Phi), m) << "\n"; + tout << "Projected Implicant\n" << mk_pp (phi1, m) << "\n"; + ); + + // expand literals. Ideally, we do not want to split aliasing + // equalities. Unfortunately, the interface does not allow for + // that yet. + // XXX This mixes up with derivation. Needs more thought. + // Phi.reset (); + // flatten_and (phi1, Phi); + // if (!Phi.empty ()) + // { + // expand_literals (m, Phi); + // phi1 = m_pm.mk_and (Phi); + // } + + + derivation *deriv = alloc (derivation, n, r, phi1, vars); + for (unsigned i = 0, sz = preds.size(); i < sz; ++i) { + unsigned j; + if (get_params ().spacer_order_children () == 1) + // -- reverse order + { j = sz - i - 1; } + else + // -- default order + { j = i; } + + pred_transformer &pt = get_pred_transformer (preds [j]); + + const ptr_vector *aux = NULL; + expr_ref sum(m); + // XXX This is a bit confusing. The summary is returned over + // XXX o-variables. But it is simpler if it is returned over n-variables instead. + sum = pt.get_origin_summary (mev, prev_level (n.level ()), + j, reach_pred_used [j], &aux); + deriv->add_premise (pt, j, sum, reach_pred_used [j], aux); + } + + // create post for the first child and add to queue + pob* kid = deriv->create_first_child (mev); + + // -- failed to create derivation, cleanup and bail out + if (!kid) { + dealloc(deriv); + return false; + } + SASSERT (kid); + kid->set_derivation (deriv); + + // Optionally disable derivation optimization + if (!get_params().spacer_use_derivations()) { kid->reset_derivation(); } + + // -- deriviation is abstract if the current weak model does + // -- not satisfy 'T && phi'. It is possible to recover from + // -- that more gracefully. For now, we just remove the + // -- derivation completely forcing it to be recomputed + if (m_weak_abs && (!mev.is_true(T) || !mev.is_true(phi))) + { kid->reset_derivation(); } + + m_pob_queue.push (*kid); + m_stats.m_num_queries++; + return true; +} + + + + +void context::collect_statistics(statistics& st) const +{ + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (it = m_rels.begin(); it != end; ++it) { + it->m_value->collect_statistics(st); + } + st.update("SPACER num queries", m_stats.m_num_queries); + st.update("SPACER num reach queries", m_stats.m_num_reach_queries); + st.update("SPACER num reuse reach facts", m_stats.m_num_reuse_reach); + st.update("SPACER max query lvl", m_stats.m_max_query_lvl); + st.update("SPACER max depth", m_stats.m_max_depth); + st.update("SPACER inductive level", m_inductive_lvl); + st.update("SPACER cex depth", m_stats.m_cex_depth); + st.update("SPACER expand node undef", m_stats.m_expand_node_undef); + st.update("SPACER num lemmas", m_stats.m_num_lemmas); + st.update("SPACER restarts", m_stats.m_num_restarts); + + st.update ("time.spacer.init_rules", m_init_rules_watch.get_seconds ()); + st.update ("time.spacer.solve", m_solve_watch.get_seconds ()); + st.update ("time.spacer.solve.propagate", m_propagate_watch.get_seconds ()); + st.update ("time.spacer.solve.reach", m_reach_watch.get_seconds ()); + st.update ("time.spacer.solve.reach.is-reach", m_is_reach_watch.get_seconds ()); + st.update ("time.spacer.solve.reach.children", + m_create_children_watch.get_seconds ()); + m_pm.collect_statistics(st); + + for (unsigned i = 0; i < m_lemma_generalizers.size(); ++i) { + m_lemma_generalizers[i]->collect_statistics(st); + } + + // brunch out + verbose_stream () << "BRUNCH_STAT max_query_lvl " << m_stats.m_max_query_lvl << "\n"; + verbose_stream () << "BRUNCH_STAT num_queries " << m_stats.m_num_queries << "\n"; + verbose_stream () << "BRUNCH_STAT num_reach_queries " << m_stats.m_num_reach_queries << "\n"; + verbose_stream () << "BRUNCH_STAT num_reach_reuse " << m_stats.m_num_reuse_reach << "\n"; + verbose_stream () << "BRUNCH_STAT inductive_lvl " << m_inductive_lvl << "\n"; + verbose_stream () << "BRUNCH_STAT max_depth " << m_stats.m_max_depth << "\n"; + verbose_stream () << "BRUNCH_STAT cex_depth " << m_stats.m_cex_depth << "\n"; +} + +void context::reset_statistics() +{ + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (it = m_rels.begin(); it != end; ++it) { + it->m_value->reset_statistics(); + } + m_stats.reset(); + m_pm.reset_statistics(); + + for (unsigned i = 0; i < m_lemma_generalizers.size(); ++i) { + m_lemma_generalizers[i]->reset_statistics(); + } + + m_init_rules_watch.reset (); + m_solve_watch.reset (); + m_propagate_watch.reset (); + m_reach_watch.reset (); + m_is_reach_watch.reset (); + m_create_children_watch.reset (); +} + +bool context::check_invariant(unsigned lvl) +{ + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (; it != end; ++it) { + checkpoint(); + if (!check_invariant(lvl, it->m_key)) { + return false; + } + } + return true; +} + +bool context::check_invariant(unsigned lvl, func_decl* fn) +{ + smt::kernel ctx(m, m_pm.fparams2()); + pred_transformer& pt = *m_rels.find(fn); + expr_ref_vector conj(m); + expr_ref inv = pt.get_formulas(next_level(lvl), false); + if (m.is_true(inv)) { return true; } + pt.add_premises(m_rels, lvl, conj); + conj.push_back(m.mk_not(inv)); + expr_ref fml(m.mk_and(conj.size(), conj.c_ptr()), m); + ctx.assert_expr(fml); + lbool result = ctx.check(); + TRACE("spacer", tout << "Check invariant level: " << lvl << " " << result << "\n" << mk_pp(fml, m) << "\n";); + return result == l_false; +} + +expr_ref context::get_constraints (unsigned level) +{ + expr_ref res(m); + expr_ref_vector constraints(m); + + decl2rel::iterator it = m_rels.begin(), end = m_rels.end(); + for (; it != end; ++it) { + pred_transformer& r = *it->m_value; + expr_ref c = r.get_formulas(level, false); + + if (m.is_true(c)) { continue; } + + // replace local constants by bound variables. + expr_ref_vector args(m); + for (unsigned i = 0; i < r.sig_size(); ++i) + { args.push_back(m.mk_const(m_pm.o2n(r.sig(i), 0))); } + + expr_ref pred(m); + pred = m.mk_app(r.head (), r.sig_size(), args.c_ptr()); + + constraints.push_back(m.mk_implies(pred, c)); + } + + if (constraints.empty()) { return expr_ref(m.mk_true(), m); } + return m_pm.mk_and (constraints); +} + +void context::add_constraints (unsigned level, expr_ref c) +{ + if (!c.get()) { return; } + if (m.is_true(c)) { return; } + + expr_ref_vector constraints (m); + constraints.push_back (c); + flatten_and (constraints); + + for (unsigned i = 0, sz = constraints.size(); i < sz; ++i) { + expr *c = constraints.get (i); + expr *e1, *e2; + if (m.is_implies(c, e1, e2)) { + SASSERT (is_app (e1)); + pred_transformer *r = 0; + if (m_rels.find (to_app (e1)->get_decl (), r)) + { r->add_lemma(e2, level); } + } + } +} + +inline bool pob_lt::operator() (const pob *pn1, const pob *pn2) const +{ + SASSERT (pn1); + SASSERT (pn2); + const pob& n1 = *pn1; + const pob& n2 = *pn2; + + if (n1.level() != n2.level()) { return n1.level() < n2.level(); } + + if (n1.depth() != n2.depth()) { return n1.depth() < n2.depth(); } + + // -- a more deterministic order of proof obligations in a queue + // if (!n1.get_context ().get_params ().spacer_nondet_tie_break ()) + { + const expr* p1 = n1.post (); + const expr* p2 = n2.post (); + ast_manager &m = n1.get_ast_manager (); + + + // -- order by size. Less conjunctions is a proxy for + // -- generality. Currently, this takes precedence over + // -- predicates which might not be the best choice + unsigned sz1 = 1; + unsigned sz2 = 1; + + if (m.is_and(p1)) { sz1 = to_app(p1)->get_num_args(); } + if (m.is_and(p2)) { sz2 = to_app(p2)->get_num_args(); } + if (sz1 != sz2) { return sz1 < sz2; } + + // -- when all else fails, order by identifiers of the + // -- expressions. This roughly means that expressions created + // -- earlier are preferred. Note that variables in post are + // -- based on names of the predicates. Hence this guarantees an + // -- order over predicates as well. That is, two expressions + // -- are equal if and only if they correspond to the same proof + // -- obligation of the same predicate. + if (p1->get_id() != p2->get_id()) { return p1->get_id() < p2->get_id(); } + + if (n1.pt().head()->get_id() == n2.pt().head()->get_id()) { + IF_VERBOSE (1, + verbose_stream () + << "dup: " << n1.pt ().head ()->get_name () + << "(" << n1.level () << ", " << n1.depth () << ") " + << p1->get_id () << "\n"; + //<< " p1: " << mk_pp (const_cast(p1), m) << "\n" + ); + } + + // XXX see comment below on identical nodes + // SASSERT (n1.pt ().head ()->get_id () != n2.pt ().head ()->get_id ()); + // -- if expression comparison fails, compare by predicate id + if (n1.pt().head ()->get_id () != n2.pt ().head ()->get_id ()) + { return n1.pt().head()->get_id() < n2.pt().head()->get_id(); } + + /** XXX Identical nodes. This should not happen. However, + * currently, when propagating reachability, we might call + * expand_node() twice on the same node, causing it to generate + * the same proof obligation multiple times */ + return &n1 < &n2; + } + // else + // return &n1 < &n2; +} + + + +} diff --git a/src/muz/spacer/spacer_context.h b/src/muz/spacer/spacer_context.h new file mode 100644 index 000000000..f27ece97c --- /dev/null +++ b/src/muz/spacer/spacer_context.h @@ -0,0 +1,840 @@ +/**++ +Copyright (c) 2017 Microsoft Corporation and Arie Gurfinkel + +Module Name: + + spacer_context.h + +Abstract: + + SPACER predicate transformers and search context. + +Author: + + Arie Gurfinkel + Anvesh Komuravelli + + Based on muz/pdr/pdr_context.h by Nikolaj Bjorner (nbjorner) + +Notes: + +--*/ + +#ifndef _SPACER_CONTEXT_H_ +#define _SPACER_CONTEXT_H_ + +#ifdef _CYGWIN +#undef min +#undef max +#endif +#include +#include "spacer_manager.h" +#include "spacer_prop_solver.h" +#include "fixedpoint_params.hpp" + +namespace datalog { + class rule_set; + class context; +}; + +namespace spacer { + +class pred_transformer; +class derivation; +class pob_queue; +class context; + +typedef obj_map rule2inst; +typedef obj_map decl2rel; + +class pob; +typedef ref pob_ref; +typedef sref_vector pob_ref_vector; + +class reach_fact; +typedef ref reach_fact_ref; +typedef sref_vector reach_fact_ref_vector; + +class reach_fact { + unsigned m_ref_count; + + expr_ref m_fact; + ptr_vector m_aux_vars; + + const datalog::rule &m_rule; + reach_fact_ref_vector m_justification; + + bool m_init; + +public: + reach_fact (ast_manager &m, const datalog::rule &rule, + expr* fact, const ptr_vector &aux_vars, + bool init = false) : + m_ref_count (0), m_fact (fact, m), m_aux_vars (aux_vars), + m_rule(rule), m_init (init) {} + reach_fact (ast_manager &m, const datalog::rule &rule, + expr* fact, bool init = false) : + m_ref_count (0), m_fact (fact, m), m_rule(rule), m_init (init) {} + + bool is_init () {return m_init;} + const datalog::rule& get_rule () {return m_rule;} + + void add_justification (reach_fact *f) {m_justification.push_back (f);} + const reach_fact_ref_vector& get_justifications () {return m_justification;} + + expr *get () {return m_fact.get ();} + const ptr_vector &aux_vars () {return m_aux_vars;} + + void inc_ref () {++m_ref_count;} + void dec_ref () + { + SASSERT (m_ref_count > 0); + --m_ref_count; + if(m_ref_count == 0) { dealloc(this); } + } +}; + + +class lemma; +typedef ref lemma_ref; +typedef sref_vector lemma_ref_vector; + +typedef pob pob; + +// a lemma +class lemma { + unsigned m_ref_count; + + ast_manager &m; + expr_ref m_body; + expr_ref_vector m_cube; + app_ref_vector m_bindings; + unsigned m_lvl; + pob_ref m_pob; + bool m_new_pob; + + void mk_expr_core(); + void mk_cube_core(); +public: + lemma(ast_manager &manager, expr * fml, unsigned lvl); + lemma(pob_ref const &p); + lemma(pob_ref const &p, expr_ref_vector &cube, unsigned lvl); + lemma(const lemma &other) = delete; + + ast_manager &get_ast_manager() {return m;} + expr *get_expr(); + bool is_false(); + expr_ref_vector const &get_cube(); + void update_cube(pob_ref const &p, expr_ref_vector &cube); + + bool has_pob() {return m_pob;} + pob_ref &get_pob() {return m_pob;} + + unsigned level () const {return m_lvl;} + void set_level (unsigned lvl) {m_lvl = lvl;} + app_ref_vector& get_bindings() {return m_bindings;} + void add_binding(app_ref_vector const &binding) {m_bindings.append(binding);} + void mk_insts(expr_ref_vector& inst, expr* e = nullptr); + bool is_ground () {return !is_quantifier (get_expr());} + + void inc_ref () {++m_ref_count;} + void dec_ref () + { + SASSERT (m_ref_count > 0); + --m_ref_count; + if(m_ref_count == 0) { dealloc(this); } + } +}; + +struct lemma_lt_proc : public std::binary_function { + bool operator() (lemma *a, lemma *b) { + return (a->level () < b->level ()) || + (a->level () == b->level () && + ast_lt_proc() (a->get_expr (), b->get_expr ())); + } +}; + + + +// +// Predicate transformer state. +// A predicate transformer corresponds to the +// set of rules that have the same head predicates. +// + +class pred_transformer { + + struct stats { + unsigned m_num_propagations; + unsigned m_num_invariants; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + + /// manager of the lemmas in all the frames +#include "spacer_legacy_frames.h" + class frames { + private: + pred_transformer &m_pt; + lemma_ref_vector m_lemmas; + unsigned m_size; + + bool m_sorted; + lemma_lt_proc m_lt; + + void sort (); + + public: + frames (pred_transformer &pt) : m_pt (pt), m_size(0), m_sorted (true) {} + ~frames() {} + void simplify_formulas (); + + pred_transformer& pt () {return m_pt;} + + + void get_frame_lemmas (unsigned level, expr_ref_vector &out) { + for (unsigned i = 0, sz = m_lemmas.size (); i < sz; ++i) + if(m_lemmas[i]->level() == level) { + out.push_back(m_lemmas[i]->get_expr()); + } + } + void get_frame_geq_lemmas (unsigned level, expr_ref_vector &out) { + for (unsigned i = 0, sz = m_lemmas.size (); i < sz; ++i) + if(m_lemmas [i]->level() >= level) { + out.push_back(m_lemmas[i]->get_expr()); + } + } + + + unsigned size () const {return m_size;} + unsigned lemma_size () const {return m_lemmas.size ();} + void add_frame () {m_size++;} + void inherit_frames (frames &other) { + for (unsigned i = 0, sz = other.m_lemmas.size (); i < sz; ++i) { + lemma_ref lem = alloc(lemma, m_pt.get_ast_manager(), + other.m_lemmas[i]->get_expr (), + other.m_lemmas[i]->level()); + lem->add_binding(other.m_lemmas[i]->get_bindings()); + add_lemma(lem.get()); + } + m_sorted = false; + } + + bool add_lemma (lemma *lem); + void propagate_to_infinity (unsigned level); + bool propagate_to_next_level (unsigned level); + + + }; + + /** + manager of proof-obligations (pobs) + */ + class pobs { + typedef ptr_buffer pob_buffer; + typedef obj_map expr2pob_buffer; + + pred_transformer &m_pt; + + expr2pob_buffer m_pobs; + pob_ref_vector m_pinned; + public: + pobs(pred_transformer &pt) : m_pt(pt) {} + pob* mk_pob(pob *parent, unsigned level, unsigned depth, + expr *post, app_ref_vector const &b); + + pob* mk_pob(pob *parent, unsigned level, unsigned depth, + expr *post) { + app_ref_vector b(m_pt.get_ast_manager()); + return mk_pob (parent, level, depth, post, b); + } + + }; + + typedef obj_map rule2expr; + typedef obj_map > rule2apps; + + manager& pm; // spacer-manager + ast_manager& m; // manager + context& ctx; + + func_decl_ref m_head; // predicate + func_decl_ref_vector m_sig; // signature + ptr_vector m_use; // places where 'this' is referenced. + ptr_vector m_rules; // rules used to derive transformer + prop_solver m_solver; // solver context + solver* m_reach_ctx; // context for reachability facts + pobs m_pobs; + frames m_frames; + reach_fact_ref_vector m_reach_facts; // reach facts + /// Number of initial reachability facts + unsigned m_rf_init_sz; + obj_map m_tag2rule; // map tag predicate to rule. + rule2expr m_rule2tag; // map rule to predicate tag. + rule2inst m_rule2inst; // map rules to instantiations of indices + rule2expr m_rule2transition; // map rules to transition + rule2apps m_rule2vars; // map rule to auxiliary variables + expr_ref m_transition; // transition relation. + expr_ref m_initial_state; // initial state. + app_ref m_extend_lit; // literal to extend initial state + bool m_all_init; // true if the pt has no uninterpreted body in any rule + ptr_vector m_predicates; + stats m_stats; + stopwatch m_initialize_watch; + stopwatch m_must_reachable_watch; + + + + /// Auxiliary variables to represent different disjunctive + /// cases of must summaries. Stored over 'n' (a.k.a. new) + /// versions of the variables + expr_ref_vector m_reach_case_vars; + + void init_sig(); + void ensure_level(unsigned level); + void add_lemma_core (lemma *lemma); + void add_lemma_from_child (pred_transformer &child, lemma *lemma, unsigned lvl); + + void mk_assumptions(func_decl* head, expr* fml, expr_ref_vector& result); + + // Initialization + void init_rules(decl2rel const& pts, expr_ref& init, expr_ref& transition); + void init_rule(decl2rel const& pts, datalog::rule const& rule, vector& is_init, + ptr_vector& rules, expr_ref_vector& transition); + void init_atom(decl2rel const& pts, app * atom, app_ref_vector& var_reprs, expr_ref_vector& conj, unsigned tail_idx); + + void simplify_formulas(tactic& tac, expr_ref_vector& fmls); + + // Debugging + bool check_filled(app_ref_vector const& v) const; + + void add_premises(decl2rel const& pts, unsigned lvl, datalog::rule& rule, expr_ref_vector& r); + + expr* mk_fresh_reach_case_var (); + +public: + pred_transformer(context& ctx, manager& pm, func_decl* head); + ~pred_transformer(); + + inline bool use_native_mbp (); + reach_fact *get_reach_fact (expr *v) + { + for (unsigned i = 0, sz = m_reach_facts.size (); i < sz; ++i) + if(v == m_reach_facts [i]->get()) { return m_reach_facts[i]; } + return NULL; + } + + void add_rule(datalog::rule* r) { m_rules.push_back(r); } + void add_use(pred_transformer* pt) { if(!m_use.contains(pt)) { m_use.insert(pt); } } + void initialize(decl2rel const& pts); + + func_decl* head() const { return m_head; } + ptr_vector const& rules() const { return m_rules; } + func_decl* sig(unsigned i) const { return m_sig[i]; } // signature + func_decl* const* sig() { return m_sig.c_ptr(); } + unsigned sig_size() const { return m_sig.size(); } + expr* transition() const { return m_transition; } + expr* initial_state() const { return m_initial_state; } + expr* rule2tag(datalog::rule const* r) { return m_rule2tag.find(r); } + unsigned get_num_levels() { return m_frames.size (); } + expr_ref get_cover_delta(func_decl* p_orig, int level); + void add_cover(unsigned level, expr* property); + expr_ref get_reachable (); + + std::ostream& display(std::ostream& strm) const; + + void collect_statistics(statistics& st) const; + void reset_statistics(); + + bool is_must_reachable (expr* state, model_ref* model = 0); + /// \brief Returns reachability fact active in the given model + /// all determines whether initial reachability facts are included as well + reach_fact *get_used_reach_fact (model_evaluator_util& mev, bool all = true); + /// \brief Returns reachability fact active in the origin of the given model + reach_fact* get_used_origin_reach_fact (model_evaluator_util &mev, unsigned oidx); + expr_ref get_origin_summary (model_evaluator_util &mev, + unsigned level, unsigned oidx, bool must, + const ptr_vector **aux); + + void remove_predecessors(expr_ref_vector& literals); + void find_predecessors(datalog::rule const& r, ptr_vector& predicates) const; + void find_predecessors(vector >& predicates) const; + datalog::rule const* find_rule(model &mev, bool& is_concrete, + vector& reach_pred_used, + unsigned& num_reuse_reach); + expr* get_transition(datalog::rule const& r) { return m_rule2transition.find(&r); } + ptr_vector& get_aux_vars(datalog::rule const& r) { return m_rule2vars.find(&r); } + + bool propagate_to_next_level(unsigned level); + void propagate_to_infinity(unsigned level); + /// \brief Add a lemma to the current context and all users + bool add_lemma(expr * lemma, unsigned lvl); + bool add_lemma(lemma* lem) {return m_frames.add_lemma(lem);} + expr* get_reach_case_var (unsigned idx) const; + bool has_reach_facts () const { return !m_reach_facts.empty () ;} + + /// initialize reachability facts using initial rules + void init_reach_facts (); + void add_reach_fact (reach_fact *fact); // add reachability fact + reach_fact* get_last_reach_fact () const { return m_reach_facts.back (); } + expr* get_last_reach_case_var () const; + + pob* mk_pob(pob *parent, unsigned level, unsigned depth, + expr *post, app_ref_vector const &b){ + return m_pobs.mk_pob(parent, level, depth, post, b); + } + + pob* mk_pob(pob *parent, unsigned level, unsigned depth, + expr *post) { + return m_pobs.mk_pob(parent, level, depth, post); + } + + lbool is_reachable(pob& n, expr_ref_vector* core, model_ref *model, + unsigned& uses_level, bool& is_concrete, + datalog::rule const*& r, + vector& reach_pred_used, + unsigned& num_reuse_reach); + bool is_invariant(unsigned level, expr* lemma, + unsigned& solver_level, expr_ref_vector* core = 0); + bool check_inductive(unsigned level, expr_ref_vector& state, + unsigned& assumes_level); + + expr_ref get_formulas(unsigned level, bool add_axioms); + + void simplify_formulas(); + + context& get_context () const {return ctx;} + manager& get_manager() const { return pm; } + ast_manager& get_ast_manager() const { return m; } + + void add_premises(decl2rel const& pts, unsigned lvl, expr_ref_vector& r); + + void inherit_properties(pred_transformer& other); + + void ground_free_vars(expr* e, app_ref_vector& vars, ptr_vector& aux_vars, + bool is_init); + + /// \brief Adds a given expression to the set of initial rules + app* extend_initial (expr *e); + + /// \brief Returns true if the obligation is already blocked by current lemmas + bool is_blocked (pob &n, unsigned &uses_level); + /// \brief Returns true if the obligation is already blocked by current quantified lemmas + bool is_qblocked (pob &n); + +}; + + +/** + * A proof obligation. + */ +class pob { + friend class context; + unsigned m_ref_count; + /// parent node + pob_ref m_parent; + /// predicate transformer + pred_transformer& m_pt; + /// post-condition decided by this node + expr_ref m_post; + // if m_post is not ground, then m_binding is an instantiation for + // all quantified variables + app_ref_vector m_binding; + /// new post to be swapped in for m_post + expr_ref m_new_post; + /// level at which to decide the post + unsigned m_level; + + unsigned m_depth; + + /// whether a concrete answer to the post is found + bool m_open; + /// whether to use farkas generalizer to construct a lemma blocking this node + bool m_use_farkas; + + unsigned m_weakness; + /// derivation representing the position of this node in the parent's rule + scoped_ptr m_derivation; + + ptr_vector m_kids; +public: + pob (pob* parent, pred_transformer& pt, + unsigned level, unsigned depth=0, bool add_to_parent=true); + + ~pob() {if(m_parent) { m_parent->erase_child(*this); }} + + unsigned weakness() {return m_weakness;} + void bump_weakness() {m_weakness++;} + void reset_weakness() {m_weakness=0;} + + void inc_level () {m_level++; m_depth++;reset_weakness();} + + void inherit(pob const &p); + void set_derivation (derivation *d) {m_derivation = d;} + bool has_derivation () const {return (bool)m_derivation;} + derivation &get_derivation() const {return *m_derivation.get ();} + void reset_derivation () {set_derivation (NULL);} + /// detaches derivation from the node without deallocating + derivation* detach_derivation () {return m_derivation.detach ();} + + pob* parent () const { return m_parent.get (); } + + pred_transformer& pt () const { return m_pt; } + ast_manager& get_ast_manager () const { return m_pt.get_ast_manager (); } + manager& get_manager () const { return m_pt.get_manager (); } + context& get_context () const {return m_pt.get_context ();} + + unsigned level () const { return m_level; } + unsigned depth () const {return m_depth;} + + bool use_farkas_generalizer () const {return m_use_farkas;} + void set_farkas_generalizer (bool v) {m_use_farkas = v;} + + expr* post() const { return m_post.get (); } + void set_post(expr *post); + void set_post(expr *post, app_ref_vector const &b); + + /// indicate that a new post should be set for the node + void new_post(expr *post) {if(post != m_post) {m_new_post = post;}} + /// true if the node needs to be updated outside of the priority queue + bool is_dirty () {return m_new_post;} + /// clean a dirty node + void clean(); + + void reset () {clean (); m_derivation = NULL; m_open = true;} + + bool is_closed () const { return !m_open; } + void close(); + + void add_child (pob &v) {m_kids.push_back (&v);} + void erase_child (pob &v) {m_kids.erase (&v);} + + bool is_ground () { return m_binding.empty (); } + app_ref_vector const &get_binding() const {return m_binding;} + /* + * Return skolem variables that appear in post + */ + void get_skolems(app_ref_vector& v); + + void inc_ref () {++m_ref_count;} + void dec_ref () + { + --m_ref_count; + if(m_ref_count == 0) { dealloc(this); } + } + +}; + + +struct pob_lt : + public std::binary_function +{bool operator() (const pob *pn1, const pob *pn2) const;}; + +struct pob_gt : + public std::binary_function { + pob_lt lt; + bool operator() (const pob *n1, const pob *n2) const + {return lt(n2, n1);} +}; + +struct pob_ref_gt : + public std::binary_function { + pob_gt gt; + bool operator() (const pob_ref &n1, const pob_ref &n2) const + {return gt (n1.get (), n2.get ());} +}; + + +/** + */ +class derivation { + /// a single premise of a derivation + class premise { + pred_transformer &m_pt; + /// origin order in the rule + unsigned m_oidx; + /// summary fact corresponding to the premise + expr_ref m_summary; + /// whether this is a must or may premise + bool m_must; + app_ref_vector m_ovars; + + public: + premise (pred_transformer &pt, unsigned oidx, expr *summary, bool must, + const ptr_vector *aux_vars = NULL); + premise (const premise &p); + + bool is_must () {return m_must;} + expr * get_summary () {return m_summary.get ();} + app_ref_vector &get_ovars () {return m_ovars;} + unsigned get_oidx () {return m_oidx;} + pred_transformer &pt () {return m_pt;} + + /// \brief Updated the summary. + /// The new summary is over n-variables. + void set_summary (expr * summary, bool must, + const ptr_vector *aux_vars = NULL); + }; + + + /// parent model node + pob& m_parent; + + /// the rule corresponding to this derivation + const datalog::rule &m_rule; + + /// the premises + vector m_premises; + /// pointer to the active premise + unsigned m_active; + // transition relation over origin variables + expr_ref m_trans; + // implicitly existentially quantified variables in m_trans + app_ref_vector m_evars; + /// -- create next child using given model as the guide + /// -- returns NULL if there is no next child + pob* create_next_child (model_evaluator_util &mev); +public: + derivation (pob& parent, datalog::rule const& rule, + expr *trans, app_ref_vector const &evars); + void add_premise (pred_transformer &pt, unsigned oidx, + expr * summary, bool must, const ptr_vector *aux_vars = NULL); + + /// creates the first child. Must be called after all the premises + /// are added. The model must be valid for the premises + /// Returns NULL if no child exits + pob *create_first_child (model_evaluator_util &mev); + + /// Create the next child. Must summary of the currently active + /// premise must be consistent with the transition relation + pob *create_next_child (); + + datalog::rule const& get_rule () const { return m_rule; } + pob& get_parent () const { return m_parent; } + ast_manager &get_ast_manager () const {return m_parent.get_ast_manager ();} + manager &get_manager () const {return m_parent.get_manager ();} + context &get_context() const {return m_parent.get_context();} +}; + + +class pob_queue { + pob_ref m_root; + unsigned m_max_level; + unsigned m_min_depth; + + std::priority_queue, + pob_ref_gt> m_obligations; + +public: + pob_queue(): m_root(NULL), m_max_level(0), m_min_depth(0) {} + ~pob_queue(); + + void reset(); + pob * top (); + void pop () {m_obligations.pop ();} + void push (pob &n) {m_obligations.push (&n);} + + void inc_level () + { + SASSERT (!m_obligations.empty () || m_root); + m_max_level++; + m_min_depth++; + if(m_root && m_obligations.empty()) { m_obligations.push(m_root); } + } + + pob& get_root() const { return *m_root.get (); } + void set_root(pob& n); + bool is_root (pob& n) const {return m_root.get () == &n;} + + unsigned max_level () {return m_max_level;} + unsigned min_depth () {return m_min_depth;} + unsigned size () {return m_obligations.size ();} + +}; + + +/** + * Generalizers (strengthens) a lemma + */ +class lemma_generalizer { +protected: + context& m_ctx; +public: + lemma_generalizer(context& ctx): m_ctx(ctx) {} + virtual ~lemma_generalizer() {} + virtual void operator()(lemma_ref &lemma) = 0; + virtual void collect_statistics(statistics& st) const {} + virtual void reset_statistics() {} +}; + + +class context { + + struct stats { + unsigned m_num_queries; + unsigned m_num_reach_queries; + unsigned m_num_reuse_reach; + unsigned m_max_query_lvl; + unsigned m_max_depth; + unsigned m_cex_depth; + unsigned m_expand_node_undef; + unsigned m_num_lemmas; + unsigned m_num_restarts; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + + // stat watches + stopwatch m_solve_watch; + stopwatch m_propagate_watch; + stopwatch m_reach_watch; + stopwatch m_is_reach_watch; + stopwatch m_create_children_watch; + stopwatch m_init_rules_watch; + + fixedpoint_params const& m_params; + ast_manager& m; + datalog::context* m_context; + manager m_pm; + decl2rel m_rels; // Map from relation predicate to fp-operator. + func_decl_ref m_query_pred; + pred_transformer* m_query; + mutable pob_queue m_pob_queue; + lbool m_last_result; + unsigned m_inductive_lvl; + unsigned m_expanded_lvl; + ptr_buffer m_lemma_generalizers; + stats m_stats; + model_converter_ref m_mc; + proof_converter_ref m_pc; + bool m_use_native_mbp; + bool m_ground_cti; + bool m_instantiate; + bool m_use_qlemmas; + bool m_weak_abs; + bool m_use_restarts; + unsigned m_restart_initial_threshold; + + // Functions used by search. + lbool solve_core (unsigned from_lvl = 0); + bool check_reachability (); + bool propagate(unsigned min_prop_lvl, unsigned max_prop_lvl, + unsigned full_prop_lvl); + bool is_reachable(pob &n); + lbool expand_node(pob& n); + reach_fact *mk_reach_fact (pob& n, model_evaluator_util &mev, + datalog::rule const& r); + bool create_children(pob& n, datalog::rule const& r, + model_evaluator_util &model, + const vector& reach_pred_used); + expr_ref mk_sat_answer(); + expr_ref mk_unsat_answer() const; + + // Generate inductive property + void get_level_property(unsigned lvl, expr_ref_vector& res, + vector & rs) const; + + + // Initialization + void init_lemma_generalizers(datalog::rule_set& rules); + + bool check_invariant(unsigned lvl); + bool check_invariant(unsigned lvl, func_decl* fn); + + void checkpoint(); + + void init_rules(datalog::rule_set& rules, decl2rel& transformers); + + void simplify_formulas(); + + void reset_lemma_generalizers(); + + bool validate(); + + unsigned get_cex_depth (); + +public: + /** + Initial values of predicates are stored in corresponding relations in dctx. + + We check whether there is some reachable state of the relation checked_relation. + */ + context( + fixedpoint_params const& params, + ast_manager& m); + + ~context(); + + fixedpoint_params const& get_params() const { return m_params; } + bool use_native_mbp () {return m_use_native_mbp;} + bool use_ground_cti () {return m_ground_cti;} + bool use_instantiate () { return m_instantiate; } + bool use_qlemmas () {return m_use_qlemmas; } + + ast_manager& get_ast_manager() const { return m; } + manager& get_manager() { return m_pm; } + decl2rel const& get_pred_transformers() const { return m_rels; } + pred_transformer& get_pred_transformer(func_decl* p) const + { return *m_rels.find(p); } + datalog::context& get_datalog_context() const + { SASSERT(m_context); return *m_context; } + expr_ref get_answer(); + /** + * get bottom-up (from query) sequence of ground predicate instances + * (for e.g. P(0,1,0,0,3)) that together form a ground derivation to query + */ + expr_ref get_ground_sat_answer (); + + void collect_statistics(statistics& st) const; + void reset_statistics(); + + std::ostream& display(std::ostream& strm) const; + + void display_certificate(std::ostream& strm) const {} + + lbool solve(unsigned from_lvl = 0); + + lbool solve_from_lvl (unsigned from_lvl); + + void reset(); + + void set_query(func_decl* q) { m_query_pred = q; } + + void set_unsat() { m_last_result = l_false; } + + void set_model_converter(model_converter_ref& mc) { m_mc = mc; } + + void get_rules_along_trace (datalog::rule_ref_vector& rules); + + model_converter_ref get_model_converter() { return m_mc; } + + void set_proof_converter(proof_converter_ref& pc) { m_pc = pc; } + + void update_rules(datalog::rule_set& rules); + + void set_axioms(expr* axioms) { m_pm.set_background(axioms); } + + unsigned get_num_levels(func_decl* p); + + expr_ref get_cover_delta(int level, func_decl* p_orig, func_decl* p); + + void add_cover(int level, func_decl* pred, expr* property); + + expr_ref get_reachable (func_decl* p); + + void add_invariant (func_decl *pred, expr* property); + + model_ref get_model(); + + proof_ref get_proof() const; + + pob& get_root() const { return m_pob_queue.get_root(); } + + expr_ref get_constraints (unsigned lvl); + void add_constraints (unsigned lvl, expr_ref c); +}; + +inline bool pred_transformer::use_native_mbp () {return ctx.use_native_mbp ();} +} + +#endif diff --git a/src/muz/spacer/spacer_dl_interface.cpp b/src/muz/spacer/spacer_dl_interface.cpp new file mode 100644 index 000000000..264809f72 --- /dev/null +++ b/src/muz/spacer/spacer_dl_interface.cpp @@ -0,0 +1,354 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation and Arie Gurfinkel + +Module Name: + + spacer_dl.cpp + +Abstract: + + SMT2 interface for the datalog SPACER + +Author: + + Arie Gurfinkel + +Revision History: + +--*/ + +#include "dl_context.h" +#include "dl_mk_coi_filter.h" +#include "dl_mk_interp_tail_simplifier.h" +#include "dl_mk_subsumption_checker.h" +#include "dl_mk_rule_inliner.h" +#include "dl_rule.h" +#include "dl_rule_transformer.h" +#include "smt2parser.h" +#include "spacer_context.h" +#include "spacer_dl_interface.h" +#include "dl_rule_set.h" +#include "dl_mk_slice.h" +#include "dl_mk_unfold.h" +#include "dl_mk_coalesce.h" +#include "model_smt2_pp.h" +#include "scoped_proof.h" +#include "dl_transforms.h" + +using namespace spacer; + +dl_interface::dl_interface(datalog::context& ctx) : + engine_base(ctx.get_manager(), "spacer"), + m_ctx(ctx), + m_spacer_rules(ctx), + m_old_rules(ctx), + m_context(0), + m_refs(ctx.get_manager()) +{ + m_context = alloc(spacer::context, ctx.get_params(), ctx.get_manager()); +} + + +dl_interface::~dl_interface() +{ + dealloc(m_context); +} + + +// +// Check if the new rules are weaker so that we can +// re-use existing context. +// +void dl_interface::check_reset() +{ + datalog::rule_set const& new_rules = m_ctx.get_rules(); + datalog::rule_ref_vector const& old_rules = m_old_rules.get_rules(); + bool is_subsumed = !old_rules.empty(); + for (unsigned i = 0; is_subsumed && i < new_rules.get_num_rules(); ++i) { + is_subsumed = false; + for (unsigned j = 0; !is_subsumed && j < old_rules.size(); ++j) { + if (m_ctx.check_subsumes(*old_rules[j], *new_rules.get_rule(i))) { + is_subsumed = true; + } + } + if (!is_subsumed) { + TRACE("spacer", new_rules.get_rule(i)->display(m_ctx, tout << "Fresh rule ");); + m_context->reset(); + } + } + m_old_rules.replace_rules(new_rules); +} + + +lbool dl_interface::query(expr * query) +{ + //we restore the initial state in the datalog context + m_ctx.ensure_opened(); + m_refs.reset(); + m_pred2slice.reset(); + ast_manager& m = m_ctx.get_manager(); + datalog::rule_manager& rm = m_ctx.get_rule_manager(); + datalog::rule_set& rules0 = m_ctx.get_rules(); + datalog::rule_set old_rules(rules0); + func_decl_ref query_pred(m); + rm.mk_query(query, m_ctx.get_rules()); + expr_ref bg_assertion = m_ctx.get_background_assertion(); + + check_reset(); + + TRACE("spacer", + if (!m.is_true(bg_assertion)) { + tout << "axioms:\n"; + tout << mk_pp(bg_assertion, m) << "\n"; + } + tout << "query: " << mk_pp(query, m) << "\n"; + tout << "rules:\n"; + m_ctx.display_rules(tout); + ); + + + apply_default_transformation(m_ctx); + + if (m_ctx.get_params().xform_slice()) { + datalog::rule_transformer transformer(m_ctx); + datalog::mk_slice* slice = alloc(datalog::mk_slice, m_ctx); + transformer.register_plugin(slice); + m_ctx.transform_rules(transformer); + + // track sliced predicates. + obj_map const& preds = slice->get_predicates(); + obj_map::iterator it = preds.begin(); + obj_map::iterator end = preds.end(); + for (; it != end; ++it) { + m_pred2slice.insert(it->m_key, it->m_value); + m_refs.push_back(it->m_key); + m_refs.push_back(it->m_value); + } + } + + if (m_ctx.get_params().xform_unfold_rules() > 0) { + unsigned num_unfolds = m_ctx.get_params().xform_unfold_rules(); + datalog::rule_transformer transf1(m_ctx), transf2(m_ctx); + transf1.register_plugin(alloc(datalog::mk_coalesce, m_ctx)); + transf2.register_plugin(alloc(datalog::mk_unfold, m_ctx)); + if (m_ctx.get_params().xform_coalesce_rules()) { + m_ctx.transform_rules(transf1); + } + while (num_unfolds > 0) { + m_ctx.transform_rules(transf2); + --num_unfolds; + } + } + + const datalog::rule_set& rules = m_ctx.get_rules(); + if (rules.get_output_predicates().empty()) { + m_context->set_unsat(); + return l_false; + } + + query_pred = rules.get_output_predicate(); + + IF_VERBOSE(2, m_ctx.display_rules(verbose_stream());); + m_spacer_rules.replace_rules(rules); + m_spacer_rules.close(); + m_ctx.record_transformed_rules(); + m_ctx.reopen(); + m_ctx.replace_rules(old_rules); + + scoped_restore_proof _sc(m); // update_rules may overwrite the proof mode. + + m_context->set_proof_converter(m_ctx.get_proof_converter()); + m_context->set_model_converter(m_ctx.get_model_converter()); + m_context->set_query(query_pred); + m_context->set_axioms(bg_assertion); + m_context->update_rules(m_spacer_rules); + + if (m_spacer_rules.get_rules().empty()) { + m_context->set_unsat(); + IF_VERBOSE(2, model_smt2_pp(verbose_stream(), m, *m_context->get_model(), 0);); + return l_false; + } + + return m_context->solve(); + +} + +lbool dl_interface::query_from_lvl(expr * query, unsigned lvl) +{ + //we restore the initial state in the datalog context + m_ctx.ensure_opened(); + m_refs.reset(); + m_pred2slice.reset(); + ast_manager& m = m_ctx.get_manager(); + datalog::rule_manager& rm = m_ctx.get_rule_manager(); + datalog::rule_set& rules0 = m_ctx.get_rules(); + datalog::rule_set old_rules(rules0); + func_decl_ref query_pred(m); + rm.mk_query(query, m_ctx.get_rules()); + expr_ref bg_assertion = m_ctx.get_background_assertion(); + + check_reset(); + + TRACE("spacer", + if (!m.is_true(bg_assertion)) { + tout << "axioms:\n"; + tout << mk_pp(bg_assertion, m) << "\n"; + } + tout << "query: " << mk_pp(query, m) << "\n"; + tout << "rules:\n"; + m_ctx.display_rules(tout); + ); + + + apply_default_transformation(m_ctx); + + if (m_ctx.get_params().xform_slice()) { + datalog::rule_transformer transformer(m_ctx); + datalog::mk_slice* slice = alloc(datalog::mk_slice, m_ctx); + transformer.register_plugin(slice); + m_ctx.transform_rules(transformer); + + // track sliced predicates. + obj_map const& preds = slice->get_predicates(); + obj_map::iterator it = preds.begin(); + obj_map::iterator end = preds.end(); + for (; it != end; ++it) { + m_pred2slice.insert(it->m_key, it->m_value); + m_refs.push_back(it->m_key); + m_refs.push_back(it->m_value); + } + } + + if (m_ctx.get_params().xform_unfold_rules() > 0) { + unsigned num_unfolds = m_ctx.get_params().xform_unfold_rules(); + datalog::rule_transformer transf1(m_ctx), transf2(m_ctx); + transf1.register_plugin(alloc(datalog::mk_coalesce, m_ctx)); + transf2.register_plugin(alloc(datalog::mk_unfold, m_ctx)); + if (m_ctx.get_params().xform_coalesce_rules()) { + m_ctx.transform_rules(transf1); + } + while (num_unfolds > 0) { + m_ctx.transform_rules(transf2); + --num_unfolds; + } + } + + const datalog::rule_set& rules = m_ctx.get_rules(); + if (rules.get_output_predicates().empty()) { + + m_context->set_unsat(); + return l_false; + } + + query_pred = rules.get_output_predicate(); + + IF_VERBOSE(2, m_ctx.display_rules(verbose_stream());); + m_spacer_rules.replace_rules(rules); + m_spacer_rules.close(); + m_ctx.record_transformed_rules(); + m_ctx.reopen(); + m_ctx.replace_rules(old_rules); + + scoped_restore_proof _sc(m); // update_rules may overwrite the proof mode. + + m_context->set_proof_converter(m_ctx.get_proof_converter()); + m_context->set_model_converter(m_ctx.get_model_converter()); + m_context->set_query(query_pred); + m_context->set_axioms(bg_assertion); + m_context->update_rules(m_spacer_rules); + + if (m_spacer_rules.get_rules().empty()) { + m_context->set_unsat(); + IF_VERBOSE(1, model_smt2_pp(verbose_stream(), m, *m_context->get_model(), 0);); + return l_false; + } + + return m_context->solve(lvl); + +} + +expr_ref dl_interface::get_cover_delta(int level, func_decl* pred_orig) +{ + func_decl* pred = pred_orig; + m_pred2slice.find(pred_orig, pred); + SASSERT(pred); + return m_context->get_cover_delta(level, pred_orig, pred); +} + +void dl_interface::add_cover(int level, func_decl* pred, expr* property) +{ + if (m_ctx.get_params().xform_slice()) { + throw default_exception("Covers are incompatible with slicing. Disable slicing before using covers"); + } + m_context->add_cover(level, pred, property); +} + +void dl_interface::add_invariant(func_decl* pred, expr* property) +{ + if (m_ctx.get_params().xform_slice()) { + throw default_exception("Invariants are incompatible with slicing. Disable slicing before using invariants"); + } + m_context->add_invariant(pred, property); +} + +expr_ref dl_interface::get_reachable(func_decl* pred) +{ + if (m_ctx.get_params().xform_slice()) { + throw default_exception("Invariants are incompatible with slicing. " + "Disable slicing before using invariants"); + } + return m_context->get_reachable(pred); +} + +unsigned dl_interface::get_num_levels(func_decl* pred) +{ + m_pred2slice.find(pred, pred); + SASSERT(pred); + return m_context->get_num_levels(pred); +} + +void dl_interface::collect_statistics(statistics& st) const +{ + m_context->collect_statistics(st); +} + +void dl_interface::reset_statistics() +{ + m_context->reset_statistics(); +} + +void dl_interface::display_certificate(std::ostream& out) const +{ + m_context->display_certificate(out); +} + +expr_ref dl_interface::get_answer() +{ + return m_context->get_answer(); +} + +expr_ref dl_interface::get_ground_sat_answer() +{ + return m_context->get_ground_sat_answer(); +} + +void dl_interface::get_rules_along_trace(datalog::rule_ref_vector& rules) +{ + m_context->get_rules_along_trace(rules); +} + +void dl_interface::updt_params() +{ + dealloc(m_context); + m_context = alloc(spacer::context, m_ctx.get_params(), m_ctx.get_manager()); +} + +model_ref dl_interface::get_model() +{ + return m_context->get_model(); +} + +proof_ref dl_interface::get_proof() +{ + return m_context->get_proof(); +} diff --git a/src/muz/spacer/spacer_dl_interface.h b/src/muz/spacer/spacer_dl_interface.h new file mode 100644 index 000000000..809f6fc83 --- /dev/null +++ b/src/muz/spacer/spacer_dl_interface.h @@ -0,0 +1,86 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation and Arie Gurfinkel + +Module Name: + + spacer_dl_interface.h + +Abstract: + + SMT2 interface for the datalog SPACER + +Author: + + +Revision History: + +--*/ + +#ifndef _SPACER_DL_INTERFACE_H_ +#define _SPACER_DL_INTERFACE_H_ + +#include "lbool.h" +#include "dl_rule.h" +#include "dl_rule_set.h" +#include "dl_engine_base.h" +#include "statistics.h" + +namespace datalog { +class context; +} + +namespace spacer { + +class context; + +class dl_interface : public datalog::engine_base { + datalog::context& m_ctx; + datalog::rule_set m_spacer_rules; + datalog::rule_set m_old_rules; + context* m_context; + obj_map m_pred2slice; + ast_ref_vector m_refs; + + void check_reset(); + +public: + dl_interface(datalog::context& ctx); + ~dl_interface(); + + lbool query(expr* query); + + lbool query_from_lvl(expr* query, unsigned lvl); + + void display_certificate(std::ostream& out) const; + + void collect_statistics(statistics& st) const; + + void reset_statistics(); + + expr_ref get_answer(); + + expr_ref get_ground_sat_answer(); + + void get_rules_along_trace(datalog::rule_ref_vector& rules); + + unsigned get_num_levels(func_decl* pred); + + expr_ref get_cover_delta(int level, func_decl* pred); + + void add_cover(int level, func_decl* pred, expr* property); + + void add_invariant(func_decl* pred, expr* property); + + expr_ref get_reachable(func_decl *pred); + + void updt_params(); + + model_ref get_model(); + + proof_ref get_proof(); + +}; +} + + +#endif diff --git a/src/muz/spacer/spacer_farkas_learner.cpp b/src/muz/spacer/spacer_farkas_learner.cpp new file mode 100644 index 000000000..edee8ba6f --- /dev/null +++ b/src/muz/spacer/spacer_farkas_learner.cpp @@ -0,0 +1,440 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_farkas_learner.cpp + +Abstract: + + Proviced abstract interface and some inplementations of algorithms + for strenghtning lemmas + +Author: + + Krystof Hoder (t-khoder) 2011-11-1. + +Revision History: +// TODO: what to write here +--*/ + +//TODO: reorder, delete unnecessary includes +#include "ast_smt2_pp.h" +#include "array_decl_plugin.h" +#include "bool_rewriter.h" +#include "dl_decl_plugin.h" +#include "for_each_expr.h" +#include "dl_util.h" +#include "rewriter.h" +#include "rewriter_def.h" +#include "spacer_util.h" +#include "spacer_farkas_learner.h" +#include "th_rewriter.h" +#include "ast_ll_pp.h" +#include "proof_utils.h" +#include "reg_decl_plugins.h" +#include "smt_farkas_util.h" + +namespace spacer { + +class collect_pure_proc { + func_decl_set& m_symbs; +public: + collect_pure_proc(func_decl_set& s): m_symbs(s) {} + + void operator()(app* a) + { + if (a->get_family_id() == null_family_id) { + m_symbs.insert(a->get_decl()); + } + } + void operator()(var*) {} + void operator()(quantifier*) {} +}; + +void farkas_learner::combine_constraints(unsigned n, app * const * lits, rational const * coeffs, expr_ref& res) +{ + ast_manager& m = res.get_manager(); + smt::farkas_util res_c(m); + res_c.set_split_literals(m_split_literals); + for (unsigned i = 0; i < n; ++i) { + res_c.add(coeffs[i], lits[i]); + } + res = res_c.get(); +} + +// every uninterpreted symbol is in symbs +class is_pure_expr_proc { + func_decl_set const& m_symbs; + array_util m_au; +public: + struct non_pure {}; + + is_pure_expr_proc(func_decl_set const& s, ast_manager& m): + m_symbs(s), + m_au(m) + {} + + void operator()(app* a) + { + if (a->get_family_id() == null_family_id) { + if (!m_symbs.contains(a->get_decl())) { + throw non_pure(); + } + } else if (a->get_family_id() == m_au.get_family_id() && + a->is_app_of(a->get_family_id(), OP_ARRAY_EXT)) { + throw non_pure(); + } + } + void operator()(var*) {} + void operator()(quantifier*) {} +}; + +bool farkas_learner::is_pure_expr(func_decl_set const& symbs, expr* e, ast_manager& m) const +{ + is_pure_expr_proc proc(symbs, m); + try { + for_each_expr(proc, e); + } catch (is_pure_expr_proc::non_pure) { + return false; + } + return true; +}; + + +/** + Revised version of Farkas strengthener. + 1. Mark B-pure nodes as derivations that depend only on B. + 2. Collect B-influenced nodes + 3. (optional) Permute B-pure units over resolution steps to narrow dependencies on B. + 4. Weaken B-pure units for resolution with Farkas Clauses. + 5. Add B-pure units elsewhere. + + Rules: + - hypothesis h |- h + + H |- false + - lemma ---------- + |- not H + + Th |- L \/ C H |- not L + - th-lemma ------------------------- + H |- C + + Note: C is false for theory axioms, C is unit literal for propagation. + + - rewrite |- t = s + + H |- t = s + - monotonicity ---------------- + H |- f(t) = f(s) + + H |- t = s H' |- s = u + - trans ---------------------- + H, H' |- t = u + + H |- C \/ L H' |- not L + - unit_resolve ------------------------ + H, H' |- C + + H |- a ~ b H' |- a + - mp -------------------- + H, H' |- b + + - def-axiom |- C + + - asserted |- f + + Mark nodes by: + - Hypotheses + - Dependency on bs + - Dependency on A + + A node is unit derivable from bs if: + - It has no hypotheses. + - It depends on bs. + - It does not depend on A. + + NB: currently unit derivable is not symmetric: A clause can be + unit derivable, but a unit literal with hypotheses is not. + This is clearly wrong, because hypotheses are just additional literals + in a clausal version. + + NB: the routine is not interpolating, though an interpolating variant would + be preferrable because then we can also use it for model propagation. + + We collect the unit derivable nodes from bs. + These are the weakenings of bs, besides the + units under Farkas. + +*/ + +#define INSERT(_x_) if (!lemma_set.contains(_x_)) { lemma_set.insert(_x_); lemmas.push_back(_x_); } + +void farkas_learner::get_lemmas(proof* root, expr_set const& bs, expr_ref_vector& lemmas) +{ + ast_manager& m = lemmas.get_manager(); + bool_rewriter brwr(m); + func_decl_set Bsymbs; + collect_pure_proc collect_proc(Bsymbs); + expr_set::iterator it = bs.begin(), end = bs.end(); + for (; it != end; ++it) { + for_each_expr(collect_proc, *it); + } + + proof_ref pr(root, m); + proof_utils::reduce_hypotheses(pr); + proof_utils::permute_unit_resolution(pr); + IF_VERBOSE(3, verbose_stream() << "Reduced proof:\n" << mk_ismt2_pp(pr, m) << "\n";); + + ptr_vector hyprefs; + obj_map hypmap; + obj_hashtable lemma_set; + ast_mark b_depend, a_depend, visited, b_closed; + expr_set* empty_set = alloc(expr_set); + hyprefs.push_back(empty_set); + ptr_vector todo; + TRACE("spacer_verbose", tout << mk_pp(pr, m) << "\n";); + todo.push_back(pr); + while (!todo.empty()) { + proof* p = todo.back(); + SASSERT(m.is_proof(p)); + if (visited.is_marked(p)) { + todo.pop_back(); + continue; + } + bool all_visit = true; + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + expr* arg = p->get_arg(i); + SASSERT(m.is_proof(arg)); + if (!visited.is_marked(arg)) { + all_visit = false; + todo.push_back(to_app(arg)); + } + } + if (!all_visit) { + continue; + } + visited.mark(p, true); + todo.pop_back(); + + // retrieve hypotheses and dependencies on A, bs. + bool b_dep = false, a_dep = false; + expr_set* hyps = empty_set; + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + expr* arg = p->get_arg(i); + a_dep = a_dep || a_depend.is_marked(arg); + b_dep = b_dep || b_depend.is_marked(arg); + expr_set* hyps2 = hypmap.find(arg); + if (hyps != hyps2 && !hyps2->empty()) { + if (hyps->empty()) { + hyps = hyps2; + } else { + expr_set* hyps3 = alloc(expr_set); + datalog::set_union(*hyps3, *hyps); + datalog::set_union(*hyps3, *hyps2); + hyps = hyps3; + hyprefs.push_back(hyps); + } + } + } + hypmap.insert(p, hyps); + a_depend.mark(p, a_dep); + b_depend.mark(p, b_dep); + +#define IS_B_PURE(_p) (b_depend.is_marked(_p) && !a_depend.is_marked(_p) && hypmap.find(_p)->empty()) + + + // Add lemmas that depend on bs, have no hypotheses, don't depend on A. + if ((!hyps->empty() || a_depend.is_marked(p)) && + b_depend.is_marked(p) && !is_farkas_lemma(m, p)) { + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + app* arg = to_app(p->get_arg(i)); + if (IS_B_PURE(arg)) { + expr* fact = m.get_fact(arg); + if (is_pure_expr(Bsymbs, fact, m)) { + TRACE("farkas_learner2", + tout << "Add: " << mk_pp(m.get_fact(arg), m) << "\n"; + tout << mk_pp(arg, m) << "\n"; + ); + INSERT(fact); + } else { + get_asserted(p, bs, b_closed, lemma_set, lemmas); + b_closed.mark(p, true); + } + } + } + } + + switch (p->get_decl_kind()) { + case PR_ASSERTED: + if (bs.contains(m.get_fact(p))) { + b_depend.mark(p, true); + } else { + a_depend.mark(p, true); + } + break; + case PR_HYPOTHESIS: { + SASSERT(hyps == empty_set); + hyps = alloc(expr_set); + hyps->insert(m.get_fact(p)); + hyprefs.push_back(hyps); + hypmap.insert(p, hyps); + break; + } + case PR_DEF_AXIOM: { + if (!is_pure_expr(Bsymbs, m.get_fact(p), m)) { + a_depend.mark(p, true); + } + break; + } + case PR_LEMMA: { + expr_set* hyps2 = alloc(expr_set); + hyprefs.push_back(hyps2); + datalog::set_union(*hyps2, *hyps); + hyps = hyps2; + expr* fml = m.get_fact(p); + hyps->remove(fml); + if (m.is_or(fml)) { + for (unsigned i = 0; i < to_app(fml)->get_num_args(); ++i) { + expr* f = to_app(fml)->get_arg(i); + expr_ref hyp(m); + brwr.mk_not(f, hyp); + hyps->remove(hyp); + } + } + hypmap.insert(p, hyps); + break; + } + case PR_TH_LEMMA: { + if (!is_farkas_lemma(m, p)) { break; } + + SASSERT(m.has_fact(p)); + unsigned prem_cnt = m.get_num_parents(p); + func_decl * d = p->get_decl(); + SASSERT(d->get_num_parameters() >= prem_cnt + 2); + SASSERT(d->get_parameter(0).get_symbol() == "arith"); + SASSERT(d->get_parameter(1).get_symbol() == "farkas"); + parameter const* params = d->get_parameters() + 2; + + app_ref_vector lits(m); + expr_ref tmp(m); + unsigned num_b_pures = 0; + rational coef; + vector coeffs; + + TRACE("farkas_learner2", + for (unsigned i = 0; i < prem_cnt; ++i) { + VERIFY(params[i].is_rational(coef)); + proof* prem = to_app(p->get_arg(i)); + bool b_pure = IS_B_PURE(prem); + tout << (b_pure ? "B" : "A") << " " << coef << " " << mk_pp(m.get_fact(prem), m) << "\n"; + } + tout << mk_pp(m.get_fact(p), m) << "\n"; + ); + + // NB. Taking 'abs' of coefficients is a workaround. + // The Farkas coefficient extraction in arith_core must be wrong. + // The coefficients would be always positive relative to the theory lemma. + + for (unsigned i = 0; i < prem_cnt; ++i) { + expr * prem_e = p->get_arg(i); + SASSERT(is_app(prem_e)); + proof * prem = to_app(prem_e); + + if (IS_B_PURE(prem)) { + ++num_b_pures; + } else { + VERIFY(params[i].is_rational(coef)); + lits.push_back(to_app(m.get_fact(prem))); + coeffs.push_back(abs(coef)); + } + } + params += prem_cnt; + if (prem_cnt + 2 < d->get_num_parameters()) { + unsigned num_args = 1; + expr* fact = m.get_fact(p); + expr* const* args = &fact; + if (m.is_or(fact)) { + app* _or = to_app(fact); + num_args = _or->get_num_args(); + args = _or->get_args(); + } + SASSERT(prem_cnt + 2 + num_args == d->get_num_parameters()); + for (unsigned i = 0; i < num_args; ++i) { + expr* prem_e = args[i]; + brwr.mk_not(prem_e, tmp); + VERIFY(params[i].is_rational(coef)); + SASSERT(is_app(tmp)); + lits.push_back(to_app(tmp)); + coeffs.push_back(abs(coef)); + } + + } + SASSERT(coeffs.size() == lits.size()); + if (num_b_pures > 0) { + expr_ref res(m); + combine_constraints(coeffs.size(), lits.c_ptr(), coeffs.c_ptr(), res); + TRACE("farkas_learner2", tout << "Add: " << mk_pp(res, m) << "\n";); + INSERT(res); + b_closed.mark(p, true); + } + } + default: + break; + } + } + + std::for_each(hyprefs.begin(), hyprefs.end(), delete_proc()); + simplify_bounds(lemmas); +} + +void farkas_learner::get_asserted(proof* p, expr_set const& bs, ast_mark& b_closed, obj_hashtable& lemma_set, expr_ref_vector& lemmas) +{ + ast_manager& m = lemmas.get_manager(); + ast_mark visited; + proof* p0 = p; + ptr_vector todo; + todo.push_back(p); + + while (!todo.empty()) { + p = todo.back(); + todo.pop_back(); + if (visited.is_marked(p) || b_closed.is_marked(p)) { + continue; + } + visited.mark(p, true); + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + expr* arg = p->get_arg(i); + SASSERT(m.is_proof(arg)); + todo.push_back(to_app(arg)); + } + if (p->get_decl_kind() == PR_ASSERTED && + bs.contains(m.get_fact(p))) { + expr* fact = m.get_fact(p); + TRACE("farkas_learner2", + tout << mk_ll_pp(p0, m) << "\n"; + tout << "Add: " << mk_pp(p, m) << "\n";); + INSERT(fact); + b_closed.mark(p, true); + } + } +} + + +bool farkas_learner::is_farkas_lemma(ast_manager& m, expr* e) +{ + app * a; + func_decl* d; + symbol sym; + return + is_app(e) && + (a = to_app(e), d = a->get_decl(), true) && + PR_TH_LEMMA == a->get_decl_kind() && + d->get_num_parameters() >= 2 && + d->get_parameter(0).is_symbol(sym) && sym == "arith" && + d->get_parameter(1).is_symbol(sym) && sym == "farkas" && + d->get_num_parameters() >= m.get_num_parents(to_app(e)) + 2; +} +} + diff --git a/src/muz/spacer/spacer_farkas_learner.h b/src/muz/spacer/spacer_farkas_learner.h new file mode 100644 index 000000000..7a0abf6f5 --- /dev/null +++ b/src/muz/spacer/spacer_farkas_learner.h @@ -0,0 +1,66 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_farkas_learner.h + +Abstract: + + SMT2 interface for the datalog SPACER + +Author: + + Krystof Hoder (t-khoder) 2011-11-1. + +Revision History: + +--*/ + +#ifndef _SPACER_FARKAS_LEARNER_H_ +#define _SPACER_FARKAS_LEARNER_H_ + +#include "ast.h" + +namespace spacer { + + + + + + + +class farkas_learner { + typedef obj_hashtable expr_set; + + bool m_split_literals; + + void combine_constraints(unsigned cnt, app * const * constrs, rational const * coeffs, expr_ref& res); + + bool is_farkas_lemma(ast_manager& m, expr* e); + + void get_asserted(proof* p, expr_set const& bs, ast_mark& b_closed, obj_hashtable& lemma_set, expr_ref_vector& lemmas); + + bool is_pure_expr(func_decl_set const& symbs, expr* e, ast_manager& m) const; + +public: + farkas_learner(): m_split_literals(false) {} + + /** + Traverse a proof and retrieve lemmas using the vocabulary from bs. + */ + void get_lemmas(proof* root, expr_set const& bs, expr_ref_vector& lemmas); + + void collect_statistics(statistics& st) const {} + void reset_statistics() {} + + + /** \brief see smt::farkas_util::set_split_literals */ + void set_split_literals(bool v) {m_split_literals = v;} + +}; + + +} + +#endif diff --git a/src/muz/spacer/spacer_generalizers.cpp b/src/muz/spacer/spacer_generalizers.cpp new file mode 100644 index 000000000..f36983077 --- /dev/null +++ b/src/muz/spacer/spacer_generalizers.cpp @@ -0,0 +1,294 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation and Arie Gurfinkel + +Module Name: + + spacer_generalizers.cpp + +Abstract: + + Lemma generalizers. + +Author: + + Nikolaj Bjorner (nbjorner) 2011-11-20. + Arie Gurfinkel + +Revision History: + +--*/ + + +#include "spacer_context.h" +#include "spacer_generalizers.h" +#include "expr_abstract.h" +#include "var_subst.h" +#include "for_each_expr.h" +#include "obj_equiv_class.h" + + +namespace spacer { +void lemma_sanity_checker::operator()(lemma_ref &lemma) { + unsigned uses_level; + expr_ref_vector cube(lemma->get_ast_manager()); + cube.append(lemma->get_cube()); + ENSURE(lemma->get_pob()->pt().check_inductive(lemma->level(), + cube, uses_level)); +} + + +// ------------------------ +// lemma_bool_inductive_generalizer +/// Inductive generalization by dropping and expanding literals +void lemma_bool_inductive_generalizer::operator()(lemma_ref &lemma) { + if (lemma->get_cube().empty()) return; + + m_st.count++; + scoped_watch _w_(m_st.watch); + + unsigned uses_level; + pred_transformer &pt = lemma->get_pob()->pt(); + ast_manager &m = pt.get_ast_manager(); + + expr_ref_vector cube(m); + cube.append(lemma->get_cube()); + + bool dirty = false; + expr_ref true_expr(m.mk_true(), m); + ptr_vector processed; + expr_ref_vector extra_lits(m); + + unsigned i = 0, num_failures = 0; + while (i < cube.size() && + (!m_failure_limit || num_failures < m_failure_limit)) { + expr_ref lit(m); + lit = cube.get(i); + cube[i] = true_expr; + if (cube.size() > 1 && + pt.check_inductive(lemma->level(), cube, uses_level)) { + num_failures = 0; + dirty = true; + for (i = 0; i < cube.size() && + processed.contains(cube.get(i)); ++i); + } else { + // check if the literal can be expanded and any single + // literal in the expansion can replace it + extra_lits.reset(); + extra_lits.push_back(lit); + expand_literals(m, extra_lits); + SASSERT(extra_lits.size() > 0); + bool found = false; + if (extra_lits.get(0) != lit) { + SASSERT(extra_lits.size() > 1); + for (unsigned j = 0, sz = extra_lits.size(); !found && j < sz; ++j) { + cube[i] = extra_lits.get(j); + if (pt.check_inductive(lemma->level(), cube, uses_level)) { + num_failures = 0; + dirty = true; + found = true; + processed.push_back(extra_lits.get(j)); + for (i = 0; i < cube.size() && + processed.contains(cube.get(i)); ++i); + } + } + } + if (!found) { + cube[i] = lit; + processed.push_back(lit); + ++num_failures; + ++m_st.num_failures; + ++i; + } + } + } + + if (dirty) { + TRACE("spacer", + tout << "Generalized from:\n" << mk_and(lemma->get_cube()) + << "\ninto\n" << mk_and(cube) << "\n";); + + lemma->update_cube(lemma->get_pob(), cube); + SASSERT(uses_level >= lemma->level()); + lemma->set_level(uses_level); + } +} + +void lemma_bool_inductive_generalizer::collect_statistics(statistics &st) const +{ + st.update("time.spacer.solve.reach.gen.bool_ind", m_st.watch.get_seconds()); + st.update("bool inductive gen", m_st.count); + st.update("bool inductive gen failures", m_st.num_failures); +} + +void unsat_core_generalizer::operator()(lemma_ref &lemma) +{ + m_st.count++; + scoped_watch _w_(m_st.watch); + ast_manager &m = lemma->get_ast_manager(); + + pred_transformer &pt = lemma->get_pob()->pt(); + + unsigned old_sz = lemma->get_cube().size(); + unsigned old_level = lemma->level(); + + unsigned uses_level; + expr_ref_vector core(m); + bool r; + r = pt.is_invariant(lemma->level(), lemma->get_expr(), uses_level, &core); + SASSERT(r); + + CTRACE("spacer", old_sz > core.size(), + tout << "unsat core reduced lemma from: " + << old_sz << " to " << core.size() << "\n";); + CTRACE("spacer", old_level < uses_level, + tout << "unsat core moved lemma up from: " + << old_level << " to " << uses_level << "\n";); + if (old_sz > core.size()) { + lemma->update_cube(lemma->get_pob(), core); + lemma->set_level(uses_level); + } +} + +void unsat_core_generalizer::collect_statistics(statistics &st) const +{ + st.update("time.spacer.solve.reach.gen.unsat_core", m_st.watch.get_seconds()); + st.update("gen.unsat_core.cnt", m_st.count); + st.update("gen.unsat_core.fail", m_st.num_failures); +} + +namespace { +class collect_array_proc { + array_util m_au; + func_decl_set &m_symbs; + sort *m_sort; +public: + collect_array_proc(ast_manager &m, func_decl_set& s) : + m_au(m), m_symbs(s), m_sort(NULL) {} + + void operator()(app* a) + { + if (a->get_family_id() == null_family_id && m_au.is_array(a)) { + if (m_sort && m_sort != get_sort(a)) { return; } + if (!m_sort) { m_sort = get_sort(a); } + m_symbs.insert(a->get_decl()); + } + } + void operator()(var*) {} + void operator()(quantifier*) {} +}; +} + +void lemma_array_eq_generalizer::operator() (lemma_ref &lemma) +{ + TRACE("core_array_eq", tout << "Looking for equalities\n";); + + // -- find array constants + ast_manager &m = lemma->get_ast_manager(); + manager &pm = m_ctx.get_manager(); + + expr_ref_vector core(m); + expr_ref v(m); + func_decl_set symb; + collect_array_proc cap(m, symb); + + core.append (lemma->get_cube()); + v = mk_and(core); + for_each_expr(cap, v); + + TRACE("core_array_eq", + tout << "found " << symb.size() << " array variables in: \n" + << mk_pp(v, m) << "\n";); + + // too few constants + if (symb.size() <= 1) { return; } + // too many constants, skip this + if (symb.size() >= 8) { return; } + + + // -- for every pair of variables, try an equality + typedef func_decl_set::iterator iterator; + ptr_vector vsymbs; + for (iterator it = symb.begin(), end = symb.end(); + it != end; ++it) + { vsymbs.push_back(*it); } + + expr_ref_vector eqs(m); + + for (unsigned i = 0, sz = vsymbs.size(); i < sz; ++i) + for (unsigned j = i + 1; j < sz; ++j) + { eqs.push_back(m.mk_eq(m.mk_const(vsymbs.get(i)), + m.mk_const(vsymbs.get(j)))); } + + smt::kernel solver(m, m_ctx.get_manager().fparams2()); + expr_ref_vector lits(m); + for (unsigned i = 0, core_sz = core.size(); i < core_sz; ++i) { + SASSERT(lits.size() == i); + solver.push(); + solver.assert_expr(core.get(i)); + for (unsigned j = 0, eqs_sz = eqs.size(); j < eqs_sz; ++j) { + solver.push(); + solver.assert_expr(eqs.get(j)); + lbool res = solver.check(); + solver.pop(1); + + if (res == l_false) { + TRACE("core_array_eq", + tout << "strengthened " << mk_pp(core.get(i), m) + << " with " << mk_pp(m.mk_not(eqs.get(j)), m) << "\n";); + lits.push_back(m.mk_not(eqs.get(j))); + break; + } + } + solver.pop(1); + if (lits.size() == i) { lits.push_back(core.get(i)); } + } + + /** + HACK: if the first 3 arguments of pt are boolean, assume + they correspond to SeaHorn encoding and condition the equality on them. + */ + // pred_transformer &pt = n.pt (); + // if (pt.sig_size () >= 3 && + // m.is_bool (pt.sig (0)->get_range ()) && + // m.is_bool (pt.sig (1)->get_range ()) && + // m.is_bool (pt.sig (2)->get_range ())) + // { + // lits.push_back (m.mk_const (pm.o2n(pt.sig (0), 0))); + // lits.push_back (m.mk_not (m.mk_const (pm.o2n(pt.sig (1), 0)))); + // lits.push_back (m.mk_not (m.mk_const (pm.o2n(pt.sig (2), 0)))); + // } + + TRACE("core_array_eq", tout << "new possible core " + << mk_pp(pm.mk_and(lits), m) << "\n";); + + + pred_transformer &pt = lemma->get_pob()->pt(); + // -- check if it is consistent with the transition relation + unsigned uses_level1; + if (pt.check_inductive(lemma->level(), lits, uses_level1)) { + TRACE("core_array_eq", tout << "Inductive!\n";); + lemma->update_cube(lemma->get_pob(),lits); + lemma->set_level(uses_level1); + return; + } else + { TRACE("core_array_eq", tout << "Not-Inductive!\n";);} +} + +void lemma_eq_generalizer::operator() (lemma_ref &lemma) +{ + TRACE("core_eq", tout << "Transforming equivalence classes\n";); + + ast_manager &m = m_ctx.get_ast_manager(); + expr_ref_vector core(m); + core.append (lemma->get_cube()); + + bool dirty; + expr_equiv_class eq_classes(m); + factor_eqs(core, eq_classes); + // create all possible equalities to allow for simple inductive generalization + dirty = equiv_to_expr_full(eq_classes, core); + if (dirty) { + lemma->update_cube(lemma->get_pob(), core); + } +} +}; diff --git a/src/muz/spacer/spacer_generalizers.h b/src/muz/spacer/spacer_generalizers.h new file mode 100644 index 000000000..8634f0828 --- /dev/null +++ b/src/muz/spacer/spacer_generalizers.h @@ -0,0 +1,99 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation and Arie Gurfinkel + +Module Name: + + spacer_generalizers.h + +Abstract: + + Generalizer plugins. + +Author: + + Nikolaj Bjorner (nbjorner) 2011-11-22. + Arie Gurfinkel +Revision History: + +--*/ + +#ifndef _SPACER_GENERALIZERS_H_ +#define _SPACER_GENERALIZERS_H_ + +#include "spacer_context.h" +#include "arith_decl_plugin.h" + +namespace spacer { + +// can be used to check whether produced core is really implied by +// frame and therefore valid TODO: or negation? +class lemma_sanity_checker : public lemma_generalizer { +public: + lemma_sanity_checker(context& ctx) : lemma_generalizer(ctx) {} + virtual ~lemma_sanity_checker() {} + virtual void operator()(lemma_ref &lemma); +}; + +/** + * Boolean inductive generalization by dropping literals + */ +class lemma_bool_inductive_generalizer : public lemma_generalizer { + + struct stats { + unsigned count; + unsigned num_failures; + stopwatch watch; + stats() {reset();} + void reset() {count = 0; num_failures = 0; watch.reset();} + }; + + unsigned m_failure_limit; + stats m_st; + +public: + lemma_bool_inductive_generalizer(context& ctx, unsigned failure_limit) : + lemma_generalizer(ctx), m_failure_limit(failure_limit) {} + virtual ~lemma_bool_inductive_generalizer() {} + virtual void operator()(lemma_ref &lemma); + + virtual void collect_statistics(statistics& st) const; + virtual void reset_statistics() {m_st.reset();} +}; + +class unsat_core_generalizer : public lemma_generalizer { + struct stats { + unsigned count; + unsigned num_failures; + stopwatch watch; + stats() { reset(); } + void reset() {count = 0; num_failures = 0; watch.reset();} + }; + + stats m_st; +public: + unsat_core_generalizer(context &ctx) : lemma_generalizer(ctx) {} + virtual ~unsat_core_generalizer() {} + virtual void operator()(lemma_ref &lemma); + + virtual void collect_statistics(statistics &st) const; + virtual void reset_statistics() {m_st.reset();} +}; + +class lemma_array_eq_generalizer : public lemma_generalizer { +public: + lemma_array_eq_generalizer(context &ctx) : lemma_generalizer(ctx) {} + virtual ~lemma_array_eq_generalizer() {} + virtual void operator()(lemma_ref &lemma); + +}; + +class lemma_eq_generalizer : public lemma_generalizer { +public: + lemma_eq_generalizer(context &ctx) : lemma_generalizer(ctx) {} + virtual ~lemma_eq_generalizer() {} + virtual void operator()(lemma_ref &lemma); +}; + + +}; +#endif diff --git a/src/muz/spacer/spacer_itp_solver.cpp b/src/muz/spacer/spacer_itp_solver.cpp new file mode 100644 index 000000000..7571352b3 --- /dev/null +++ b/src/muz/spacer/spacer_itp_solver.cpp @@ -0,0 +1,355 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_itp_solver.cpp + +Abstract: + + A solver that produces interpolated unsat cores + +Author: + + Arie Gurfinkel + +Notes: + +--*/ +#include"spacer_itp_solver.h" +#include"ast.h" +#include"spacer_util.h" +#include"spacer_farkas_learner.h" +#include"expr_replacer.h" +#include "spacer_unsat_core_learner.h" +#include "spacer_unsat_core_plugin.h" + +namespace spacer { +void itp_solver::push () +{ + m_defs.push_back (def_manager (*this)); + m_solver.push (); +} + +void itp_solver::pop (unsigned n) +{ + m_solver.pop (n); + unsigned lvl = m_defs.size (); + SASSERT (n <= lvl); + unsigned new_lvl = lvl-n; + while (m_defs.size() > new_lvl) { + m_num_proxies -= m_defs.back ().m_defs.size (); + m_defs.pop_back (); + } +} + +app* itp_solver::fresh_proxy () +{ + if (m_num_proxies == m_proxies.size()) { + std::stringstream name; + name << "spacer_proxy!" << m_proxies.size (); + app_ref res(m); + res = m.mk_const (symbol (name.str ().c_str ()), + m.mk_bool_sort ()); + m_proxies.push_back (res); + + // -- add the new proxy to proxy eliminator + proof_ref pr(m); + pr = m.mk_asserted (m.mk_true ()); + m_elim_proxies_sub.insert (res, m.mk_true (), pr); + + } + return m_proxies.get (m_num_proxies++); +} + +app* itp_solver::mk_proxy (expr *v) +{ + { + expr *e = v; + m.is_not (v, e); + if (is_uninterp_const(e)) { return to_app(v); } + } + + def_manager &def = m_defs.size () > 0 ? m_defs.back () : m_base_defs; + return def.mk_proxy (v); +} + +bool itp_solver::mk_proxies (expr_ref_vector &v, unsigned from) +{ + bool dirty = false; + for (unsigned i = from, sz = v.size(); i < sz; ++i) { + app *p = mk_proxy (v.get (i)); + dirty |= (v.get (i) != p); + v[i] = p; + } + return dirty; +} + +void itp_solver::push_bg (expr *e) +{ + if (m_assumptions.size () > m_first_assumption) + { m_assumptions.shrink(m_first_assumption); } + m_assumptions.push_back (e); + m_first_assumption = m_assumptions.size (); +} + +void itp_solver::pop_bg (unsigned n) +{ + if (n == 0) { return; } + + if (m_assumptions.size () > m_first_assumption) + { m_assumptions.shrink(m_first_assumption); } + m_first_assumption = m_first_assumption > n ? m_first_assumption - n : 0; + m_assumptions.shrink (m_first_assumption); +} + +unsigned itp_solver::get_num_bg () {return m_first_assumption;} + +lbool itp_solver::check_sat (unsigned num_assumptions, expr * const *assumptions) +{ + // -- remove any old assumptions + if (m_assumptions.size () > m_first_assumption) + { m_assumptions.shrink(m_first_assumption); } + + // -- replace theory literals in background assumptions with proxies + mk_proxies (m_assumptions); + // -- in case mk_proxies added new literals, they are all background + m_first_assumption = m_assumptions.size (); + + m_assumptions.append (num_assumptions, assumptions); + m_is_proxied = mk_proxies (m_assumptions, m_first_assumption); + + lbool res; + res = m_solver.check_sat (m_assumptions.size (), m_assumptions.c_ptr ()); + set_status (res); + return res; +} + + +app* itp_solver::def_manager::mk_proxy (expr *v) +{ + app* r; + if (m_expr2proxy.find(v, r)) { return r; } + + ast_manager &m = m_parent.m; + app_ref proxy(m); + app_ref def(m); + proxy = m_parent.fresh_proxy (); + def = m.mk_or (m.mk_not (proxy), v); + m_defs.push_back (def); + m_expr2proxy.insert (v, proxy); + m_proxy2def.insert (proxy, def); + + m_parent.assert_expr (def.get ()); + return proxy; +} + +bool itp_solver::def_manager::is_proxy (app *k, app_ref &def) +{ + app *r = NULL; + bool found = m_proxy2def.find (k, r); + def = r; + return found; +} + +void itp_solver::def_manager::reset () +{ + m_expr2proxy.reset (); + m_proxy2def.reset (); + m_defs.reset (); +} + +bool itp_solver::def_manager::is_proxy_def (expr *v) +{ + // XXX This might not be the most robust way to check + return m_defs.contains (v); +} + +bool itp_solver::is_proxy(expr *e, app_ref &def) +{ + if (!is_uninterp_const(e)) { return false; } + + app *a = to_app (e); + + for (int i = m_defs.size (); i > 0; --i) + if (m_defs[i-1].is_proxy (a, def)) + { return true; } + + if (m_base_defs.is_proxy (a, def)) + { return true; } + + return false; +} + +void itp_solver::collect_statistics (statistics &st) const +{ + m_solver.collect_statistics (st); + st.update ("time.itp_solver.itp_core", m_itp_watch.get_seconds ()); +} + +void itp_solver::reset_statistics () +{ + m_itp_watch.reset (); +} + +void itp_solver::get_unsat_core (ptr_vector &core) +{ + m_solver.get_unsat_core (core); + undo_proxies_in_core (core); +} +void itp_solver::undo_proxies_in_core (ptr_vector &r) +{ + app_ref e(m); + expr_fast_mark1 bg; + for (unsigned i = 0; i < m_first_assumption; ++i) + { bg.mark(m_assumptions.get(i)); } + + // expand proxies + unsigned j = 0; + for (unsigned i = 0, sz = r.size(); i < sz; ++i) { + // skip background assumptions + if (bg.is_marked(r[i])) { continue; } + + // -- undo proxies, but only if they were introduced in check_sat + if (m_is_proxied && is_proxy(r[i], e)) { + SASSERT (m.is_or (e)); + r[j] = e->get_arg (1); + } else if (i != j) { r[j] = r[i]; } + j++; + } + r.shrink (j); +} + +void itp_solver::undo_proxies (expr_ref_vector &r) +{ + app_ref e(m); + // expand proxies + for (unsigned i = 0, sz = r.size (); i < sz; ++i) + if (is_proxy(r.get(i), e)) { + SASSERT (m.is_or (e)); + r[i] = e->get_arg (1); + } +} + +void itp_solver::get_unsat_core (expr_ref_vector &_core) +{ + ptr_vector core; + get_unsat_core (core); + _core.append (core.size (), core.c_ptr ()); +} + +void itp_solver::elim_proxies (expr_ref_vector &v) +{ + expr_ref f = mk_and (v); + scoped_ptr rep = mk_expr_simp_replacer (m); + rep->set_substitution (&m_elim_proxies_sub); + (*rep) (f); + v.reset (); + flatten_and (f, v); +} + +void itp_solver::get_itp_core (expr_ref_vector &core) +{ + scoped_watch _t_ (m_itp_watch); + + typedef obj_hashtable expr_set; + expr_set B; + for (unsigned i = m_first_assumption, sz = m_assumptions.size(); i < sz; ++i) { + expr *a = m_assumptions.get (i); + app_ref def(m); + if (is_proxy(a, def)) { B.insert(def.get()); } + B.insert (a); + } + + proof_ref pr(m); + pr = get_proof (); + + if (!m_new_unsat_core) { + // old code + farkas_learner learner_old; + learner_old.set_split_literals(m_split_literals); + + learner_old.get_lemmas (pr, B, core); + elim_proxies (core); + simplify_bounds (core); // XXX potentially redundant + } else { + // new code + unsat_core_learner learner(m); + + if (m_farkas_optimized) { + if (true) // TODO: proper options + { + unsat_core_plugin_farkas_lemma_optimized* plugin_farkas_lemma_optimized = alloc(unsat_core_plugin_farkas_lemma_optimized, learner,m); + learner.register_plugin(plugin_farkas_lemma_optimized); + } + else + { + unsat_core_plugin_farkas_lemma_bounded* plugin_farkas_lemma_bounded = alloc(unsat_core_plugin_farkas_lemma_bounded, learner,m); + learner.register_plugin(plugin_farkas_lemma_bounded); + } + + } else { + unsat_core_plugin_farkas_lemma* plugin_farkas_lemma = alloc(unsat_core_plugin_farkas_lemma, learner, m_split_literals, m_farkas_a_const); + learner.register_plugin(plugin_farkas_lemma); + } + + if (m_minimize_unsat_core) { + unsat_core_plugin_min_cut* plugin_min_cut = alloc(unsat_core_plugin_min_cut, learner, m); + learner.register_plugin(plugin_min_cut); + } else { + unsat_core_plugin_lemma* plugin_lemma = alloc(unsat_core_plugin_lemma, learner); + learner.register_plugin(plugin_lemma); + } + + learner.compute_unsat_core(pr, B, core); + + elim_proxies (core); + simplify_bounds (core); // XXX potentially redundant + +// // debug +// expr_ref_vector core2(m); +// unsat_core_learner learner2(m); +// +// unsat_core_plugin_farkas_lemma* plugin_farkas_lemma2 = alloc(unsat_core_plugin_farkas_lemma, learner2, m_split_literals); +// learner2.register_plugin(plugin_farkas_lemma2); +// unsat_core_plugin_lemma* plugin_lemma2 = alloc(unsat_core_plugin_lemma, learner2); +// learner2.register_plugin(plugin_lemma2); +// learner2.compute_unsat_core(pr, B, core2); +// +// elim_proxies (core2); +// simplify_bounds (core2); +// +// IF_VERBOSE(2, +// verbose_stream () << "Itp Core:\n" +// << mk_pp (mk_and (core), m) << "\n";); +// IF_VERBOSE(2, +// verbose_stream () << "Itp Core2:\n" +// << mk_pp (mk_and (core2), m) << "\n";); + //SASSERT(mk_and (core) == mk_and (core2)); + } + + IF_VERBOSE(2, + verbose_stream () << "Itp Core:\n" + << mk_pp (mk_and (core), m) << "\n";); + +} + +void itp_solver::refresh () +{ + // only refresh in non-pushed state + SASSERT (m_defs.size () == 0); + expr_ref_vector assertions (m); + for (unsigned i = 0, e = m_solver.get_num_assertions(); i < e; ++i) { + expr* a = m_solver.get_assertion (i); + if (!m_base_defs.is_proxy_def(a)) { assertions.push_back(a); } + + } + m_base_defs.reset (); + NOT_IMPLEMENTED_YET (); + // solver interface does not have a reset method. need to introduce it somewhere. + // m_solver.reset (); + for (unsigned i = 0, e = assertions.size (); i < e; ++i) + { m_solver.assert_expr(assertions.get(i)); } +} + +} diff --git a/src/muz/spacer/spacer_itp_solver.h b/src/muz/spacer/spacer_itp_solver.h new file mode 100644 index 000000000..bf5a00751 --- /dev/null +++ b/src/muz/spacer/spacer_itp_solver.h @@ -0,0 +1,177 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_itp_solver.h + +Abstract: + + A solver that produces interpolated unsat cores + +Author: + + Arie Gurfinkel + +Notes: + +--*/ +#ifndef SPACER_ITP_SOLVER_H_ +#define SPACER_ITP_SOLVER_H_ + +#include "solver.h" +#include "expr_substitution.h" +#include"stopwatch.h" +namespace spacer { +class itp_solver : public solver { +private: + struct def_manager { + itp_solver &m_parent; + obj_map m_expr2proxy; + obj_map m_proxy2def; + + expr_ref_vector m_defs; + + def_manager(itp_solver &parent) : + m_parent(parent), m_defs(m_parent.m) + {} + + bool is_proxy(app *k, app_ref &v); + app* mk_proxy(expr *v); + void reset(); + bool is_proxy_def(expr *v); + + }; + + friend struct def_manager; + ast_manager &m; + solver &m_solver; + app_ref_vector m_proxies; + unsigned m_num_proxies; + vector m_defs; + def_manager m_base_defs; + expr_ref_vector m_assumptions; + unsigned m_first_assumption; + bool m_is_proxied; + + stopwatch m_itp_watch; + + expr_substitution m_elim_proxies_sub; + bool m_split_literals; + bool m_new_unsat_core; + bool m_minimize_unsat_core; + bool m_farkas_optimized; + bool m_farkas_a_const; + + bool is_proxy(expr *e, app_ref &def); + void undo_proxies_in_core(ptr_vector &v); + app* mk_proxy(expr *v); + app* fresh_proxy(); + void elim_proxies(expr_ref_vector &v); +public: + itp_solver(solver &solver, bool new_unsat_core, bool minimize_unsat_core, bool farkas_optimized, bool farkas_a_const, bool split_literals = false) : + m(solver.get_manager()), + m_solver(solver), + m_proxies(m), + m_num_proxies(0), + m_base_defs(*this), + m_assumptions(m), + m_first_assumption(0), + m_is_proxied(false), + m_elim_proxies_sub(m, false, true), + m_split_literals(split_literals), + m_new_unsat_core(new_unsat_core), + m_minimize_unsat_core(minimize_unsat_core), + m_farkas_optimized(farkas_optimized), + m_farkas_a_const(farkas_a_const) + {} + + virtual ~itp_solver() {} + + /* itp solver specific */ + virtual void get_unsat_core(expr_ref_vector &core); + virtual void get_itp_core(expr_ref_vector &core); + void set_split_literals(bool v) {m_split_literals = v;} + bool mk_proxies(expr_ref_vector &v, unsigned from = 0); + void undo_proxies(expr_ref_vector &v); + + void push_bg(expr *e); + void pop_bg(unsigned n); + unsigned get_num_bg(); + + void get_full_unsat_core(ptr_vector &core) + {m_solver.get_unsat_core(core);} + + /* solver interface */ + + virtual solver* translate(ast_manager &m, params_ref const &p) + {return m_solver.translate(m, p);} + virtual void updt_params(params_ref const &p) + {m_solver.updt_params(p);} + virtual void collect_param_descrs(param_descrs &r) + {m_solver.collect_param_descrs(r);} + virtual void set_produce_models(bool f) + {m_solver.set_produce_models(f);} + virtual void assert_expr(expr *t) + {m_solver.assert_expr(t);} + + virtual void assert_expr(expr *t, expr *a) + {NOT_IMPLEMENTED_YET();} + + virtual void push(); + virtual void pop(unsigned n); + virtual unsigned get_scope_level() const + {return m_solver.get_scope_level();} + + virtual lbool check_sat(unsigned num_assumptions, expr * const *assumptions); + virtual void set_progress_callback(progress_callback *callback) + {m_solver.set_progress_callback(callback);} + virtual unsigned get_num_assertions() const + {return m_solver.get_num_assertions();} + virtual expr * get_assertion(unsigned idx) const + {return m_solver.get_assertion(idx);} + virtual unsigned get_num_assumptions() const + {return m_solver.get_num_assumptions();} + virtual expr * get_assumption(unsigned idx) const + {return m_solver.get_assumption(idx);} + virtual std::ostream &display(std::ostream &out) const + {m_solver.display(out); return out;} + + /* check_sat_result interface */ + + virtual void collect_statistics(statistics &st) const ; + virtual void reset_statistics(); + virtual void get_unsat_core(ptr_vector &r); + virtual void get_model(model_ref &m) {m_solver.get_model(m);} + virtual proof *get_proof() {return m_solver.get_proof();} + virtual std::string reason_unknown() const + {return m_solver.reason_unknown();} + virtual void set_reason_unknown(char const* msg) + {m_solver.set_reason_unknown(msg);} + virtual void get_labels(svector &r) + {m_solver.get_labels(r);} + virtual ast_manager &get_manager() const {return m;} + + virtual void refresh(); + + class scoped_mk_proxy { + itp_solver &m_s; + expr_ref_vector &m_v; + public: + scoped_mk_proxy(itp_solver &s, expr_ref_vector &v) : m_s(s), m_v(v) + {m_s.mk_proxies(m_v);} + ~scoped_mk_proxy() + {m_s.undo_proxies(m_v);} + }; + + class scoped_bg { + itp_solver &m_s; + unsigned m_bg_sz; + public: + scoped_bg(itp_solver &s) : m_s(s), m_bg_sz(m_s.get_num_bg()) {} + ~scoped_bg() + {if(m_s.get_num_bg() > m_bg_sz) { m_s.pop_bg(m_s.get_num_bg() - m_bg_sz); }} + }; +}; +} +#endif diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp new file mode 100644 index 000000000..c998121c6 --- /dev/null +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -0,0 +1,170 @@ +/* + Copyright (c) 2017 Arie Gurfinkel + + Legacy implementations of frames. To be removed. + */ +#include "spacer_context.h" +#include +#include + +#include "dl_util.h" +#include "rewriter.h" +#include "rewriter_def.h" +#include "var_subst.h" +#include "util.h" +#include "spacer_prop_solver.h" +#include "spacer_context.h" +#include "spacer_generalizers.h" +#include "for_each_expr.h" +#include "dl_rule_set.h" +#include "unit_subsumption_tactic.h" +#include "model_smt2_pp.h" +#include "dl_mk_rule_inliner.h" +#include "ast_smt2_pp.h" +#include "ast_ll_pp.h" +#include "ast_util.h" +#include "proof_checker.h" +#include "smt_value_sort.h" +#include "proof_utils.h" +#include "scoped_proof.h" +#include "spacer_qe_project.h" +#include "blast_term_ite_tactic.h" + +#include "timeit.h" +#include "luby.h" +#include "expr_safe_replace.h" +#include "expr_abstract.h" +#include "obj_equiv_class.h" + + +namespace spacer { +// ------------------ +// legacy_frames +void pred_transformer::legacy_frames::simplify_formulas(tactic& tac, + expr_ref_vector& v) +{ + ast_manager &m = m_pt.get_ast_manager(); + goal_ref g(alloc(goal, m, false, false, false)); + for (unsigned j = 0; j < v.size(); ++j) { g->assert_expr(v[j].get()); } + model_converter_ref mc; + proof_converter_ref pc; + expr_dependency_ref core(m); + goal_ref_buffer result; + tac(g, result, mc, pc, core); + SASSERT(result.size() == 1); + goal* r = result[0]; + v.reset(); + for (unsigned j = 0; j < r->size(); ++j) { v.push_back(r->form(j)); } +} + +void pred_transformer::legacy_frames::simplify_formulas() +{ + ast_manager &m = m_pt.get_ast_manager(); + tactic_ref us = mk_unit_subsumption_tactic(m); + simplify_formulas(*us, m_invariants); + for (unsigned i = 0; i < m_levels.size(); ++i) { + simplify_formulas(*us, m_levels[i]); + } +} + +void pred_transformer::legacy_frames::get_frame_geq_lemmas(unsigned lvl, + expr_ref_vector &out) +{ + get_frame_lemmas(infty_level(), out); + for (unsigned i = lvl, sz = m_levels.size(); i < sz; ++i) + { get_frame_lemmas(i, out); } +} + +bool pred_transformer::legacy_frames::propagate_to_next_level(unsigned src_level) +{ + + ast_manager &m = m_pt.get_ast_manager(); + if (m_levels.size() <= src_level) { return true; } + if (m_levels [src_level].empty()) { return true; } + + unsigned tgt_level = next_level(src_level); + m_pt.ensure_level(next_level(tgt_level)); + + TRACE("spacer", + tout << "propagating " << src_level << " to " << tgt_level; + tout << " for relation " << m_pt.head()->get_name() << "\n";); + + for (unsigned i = 0; i < m_levels[src_level].size();) { + expr_ref_vector &src = m_levels[src_level]; + expr * curr = src[i].get(); + unsigned stored_lvl; + VERIFY(m_prop2level.find(curr, stored_lvl)); + SASSERT(stored_lvl >= src_level); + unsigned solver_level; + if (stored_lvl > src_level) { + TRACE("spacer", tout << "at level: " << stored_lvl << " " << mk_pp(curr, m) << "\n";); + src[i] = src.back(); + src.pop_back(); + } else if (m_pt.is_invariant(tgt_level, curr, solver_level)) { + // -- might invalidate src reference + add_lemma(curr, solver_level); + TRACE("spacer", tout << "is invariant: " << pp_level(solver_level) << " " << mk_pp(curr, m) << "\n";); + // shadow higher-level src + expr_ref_vector &src = m_levels[src_level]; + src[i] = src.back(); + src.pop_back(); + ++m_pt.m_stats.m_num_propagations; + } else { + TRACE("spacer", tout << "not propagated: " << mk_pp(curr, m) << "\n";); + ++i; + } + } + + CTRACE("spacer", m_levels[src_level].empty(), + tout << "Fully propagated level " + << src_level << " of " << m_pt.head()->get_name() << "\n";); + + return m_levels[src_level].empty(); +} + +bool pred_transformer::legacy_frames::add_lemma(expr * lemma, unsigned lvl) +{ + if (is_infty_level(lvl)) { + if (!m_invariants.contains(lemma)) { + m_invariants.push_back(lemma); + m_prop2level.insert(lemma, lvl); + //m_pt.add_lemma_core (lemma, lvl); + return true; + } + return false; + } + + unsigned old_level; + if (!m_prop2level.find(lemma, old_level) || old_level < lvl) { + m_levels[lvl].push_back(lemma); + m_prop2level.insert(lemma, lvl); + //m_pt.add_lemma_core (lemma, lvl); + return true; + } + return false; +} + +void pred_transformer::legacy_frames::propagate_to_infinity(unsigned level) +{ + TRACE("spacer", tout << "propagating to oo from lvl " << level + << " of " << m_pt.m_head->get_name() << "\n";); + + if (m_levels.empty()) { return; } + + for (unsigned i = m_levels.size(); i > level; --i) { + expr_ref_vector &lemmas = m_levels [i - 1]; + for (unsigned j = 0; j < lemmas.size(); ++j) + { add_lemma(lemmas.get(j), infty_level()); } + lemmas.reset(); + } +} + +void pred_transformer::legacy_frames::inherit_frames(legacy_frames& other) +{ + + SASSERT(m_pt.m_head == other.m_pt.m_head); + obj_map::iterator it = other.m_prop2level.begin(); + obj_map::iterator end = other.m_prop2level.end(); + for (; it != end; ++it) { add_lemma(it->m_key, it->m_value); } +} +} diff --git a/src/muz/spacer/spacer_legacy_frames.h b/src/muz/spacer/spacer_legacy_frames.h new file mode 100644 index 000000000..7ff4b6fad --- /dev/null +++ b/src/muz/spacer/spacer_legacy_frames.h @@ -0,0 +1,47 @@ +/**++ + Copyright (c) 2017 Arie Gurfinkel + + Legacy implementations of frames. To be removed. + + Notes: this file is included from the middle of spacer_context.h +*/ + +class legacy_frames +{ + pred_transformer &m_pt; + + /// level formulas + vector m_levels; + /// map property to level where it occurs. + obj_map m_prop2level; + /// properties that are invariant. + expr_ref_vector m_invariants; + + void simplify_formulas (tactic& tac, expr_ref_vector& v); + +public: + legacy_frames (pred_transformer &pt) : + m_pt(pt), m_invariants (m_pt.get_ast_manager ()) {} + pred_transformer& pt () const {return m_pt;} + bool add_lemma (expr * lemma, unsigned level); + void get_frame_lemmas (unsigned level, expr_ref_vector &out) + { + if(is_infty_level(level)) { out.append(m_invariants); } + else if(level < m_levels.size()) { out.append(m_levels [level]); } + } + + void get_frame_geq_lemmas (unsigned level, expr_ref_vector &out); + void add_frame () {m_levels.push_back (expr_ref_vector (m_pt.get_ast_manager ()));} + + unsigned size () const {return m_levels.size ();} + unsigned lemma_size () const {return m_prop2level.size ();} + + + void propagate_to_infinity (unsigned level); + bool propagate_to_next_level (unsigned level); + + void simplify_formulas (); + + void inherit_frames (legacy_frames& other); + +}; diff --git a/src/muz/spacer/spacer_legacy_mbp.cpp b/src/muz/spacer/spacer_legacy_mbp.cpp new file mode 100644 index 000000000..a9569004c --- /dev/null +++ b/src/muz/spacer/spacer_legacy_mbp.cpp @@ -0,0 +1,116 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_legacy_mbp.cpp + +Abstract: + + Legacy Model Based Projection. Used by Grigory Fedyukovich + +Author: + + Arie Gurfinkel + Anvesh Komuravelli +Notes: + +--*/ +#include +#include "arith_simplifier_plugin.h" +#include "array_decl_plugin.h" +#include "ast_pp.h" +#include "basic_simplifier_plugin.h" +#include "bv_simplifier_plugin.h" +#include "bool_rewriter.h" +#include "dl_util.h" +#include "for_each_expr.h" +#include "smt_params.h" +#include "model.h" +#include "ref_vector.h" +#include "rewriter.h" +#include "rewriter_def.h" +#include "util.h" +#include "spacer_manager.h" +#include "spacer_util.h" +#include "arith_decl_plugin.h" +#include "expr_replacer.h" +#include "model_smt2_pp.h" +#include "scoped_proof.h" +#include "qe_lite.h" +#include "spacer_qe_project.h" +#include "model_pp.h" +#include "expr_safe_replace.h" + +#include "datatype_decl_plugin.h" +#include "bv_decl_plugin.h" + +#include "spacer_legacy_mev.h" + +namespace spacer { +void qe_project(ast_manager& m, app_ref_vector& vars, expr_ref& fml, model_ref& M, expr_map& map) +{ + th_rewriter rw(m); + // qe-lite; TODO: use qe_lite aggressively + params_ref p; + qe_lite qe(m, p, true); + qe(vars, fml); + rw(fml); + + TRACE("spacer", + tout << "After qe_lite:\n"; + tout << mk_pp(fml, m) << "\n"; + tout << "Vars:\n"; + for (unsigned i = 0; i < vars.size(); ++i) { + tout << mk_pp(vars.get(i), m) << "\n"; + } + ); + + // substitute model values for booleans and + // use LW projection for arithmetic variables + if (!vars.empty()) { + app_ref_vector arith_vars(m); + expr_substitution sub(m); + proof_ref pr(m.mk_asserted(m.mk_true()), m); + expr_ref bval(m); + for (unsigned i = 0; i < vars.size(); i++) { + if (m.is_bool(vars.get(i))) { + // obtain the interpretation of the ith var using model completion + VERIFY(M->eval(vars.get(i), bval, true)); + sub.insert(vars.get(i), bval, pr); + } else { + arith_vars.push_back(vars.get(i)); + } + } + if (!sub.empty()) { + scoped_ptr rep = mk_expr_simp_replacer(m); + rep->set_substitution(&sub); + (*rep)(fml); + rw(fml); + TRACE("spacer", + tout << "Projected Boolean vars:\n" << mk_pp(fml, m) << "\n"; + ); + } + // model based projection + if (!arith_vars.empty()) { + TRACE("spacer", + tout << "Arith vars:\n"; + for (unsigned i = 0; i < arith_vars.size(); ++i) { + tout << mk_pp(arith_vars.get(i), m) << "\n"; + } + ); + { + scoped_no_proof _sp(m); + qe::arith_project(*M, arith_vars, fml, map); + } + SASSERT(arith_vars.empty()); + TRACE("spacer", + tout << "Projected arith vars:\n" << mk_pp(fml, m) << "\n"; + ); + } + SASSERT(M->eval(fml, bval, true) && m.is_true(bval)); // M |= fml + vars.reset(); + vars.append(arith_vars); + } +} +} diff --git a/src/muz/spacer/spacer_legacy_mev.cpp b/src/muz/spacer/spacer_legacy_mev.cpp new file mode 100644 index 000000000..0ab33c693 --- /dev/null +++ b/src/muz/spacer/spacer_legacy_mev.cpp @@ -0,0 +1,837 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + + Deprecated implementation of model evaluator. To be removed. +*/ + +#include +#include "arith_simplifier_plugin.h" +#include "array_decl_plugin.h" +#include "ast_pp.h" +#include "basic_simplifier_plugin.h" +#include "bv_simplifier_plugin.h" +#include "bool_rewriter.h" +#include "dl_util.h" +#include "for_each_expr.h" +#include "smt_params.h" +#include "model.h" +#include "ref_vector.h" +#include "rewriter.h" +#include "rewriter_def.h" +#include "util.h" +#include "spacer_manager.h" +#include "spacer_legacy_mev.h" +#include "spacer_util.h" +#include "arith_decl_plugin.h" +#include "expr_replacer.h" +#include "model_smt2_pp.h" +#include "scoped_proof.h" +#include "qe_lite.h" +#include "spacer_qe_project.h" +#include "model_pp.h" +#include "expr_safe_replace.h" + +#include "datatype_decl_plugin.h" +#include "bv_decl_plugin.h" + +namespace old { + +///////////////////////// +// model_evaluator +// + + +void model_evaluator::assign_value(expr* e, expr* val) +{ + rational r; + if (m.is_true(val)) { + set_true(e); + } else if (m.is_false(val)) { + set_false(e); + } else if (m_arith.is_numeral(val, r)) { + set_number(e, r); + } else if (m.is_value(val)) { + set_value(e, val); + } else { + IF_VERBOSE(3, verbose_stream() << "Not evaluated " << mk_pp(e, m) << "\n";); + TRACE("old_spacer", tout << "Variable is not tracked: " << mk_pp(e, m) << "\n";); + set_x(e); + } +} + +void model_evaluator::setup_model(const model_ref& model) +{ + m_numbers.reset(); + m_values.reset(); + m_model = model.get(); + rational r; + unsigned sz = model->get_num_constants(); + for (unsigned i = 0; i < sz; i++) { + func_decl * d = model->get_constant(i); + expr* val = model->get_const_interp(d); + expr* e = m.mk_const(d); + m_refs.push_back(e); + assign_value(e, val); + } +} + +void model_evaluator::reset() +{ + m1.reset(); + m2.reset(); + m_values.reset(); + m_visited.reset(); + m_numbers.reset(); + m_refs.reset(); + m_model = 0; +} + + +void model_evaluator::minimize_literals(ptr_vector const& formulas, + const model_ref& mdl, expr_ref_vector& result) +{ + + TRACE("old_spacer", + tout << "formulas:\n"; + for (unsigned i = 0; i < formulas.size(); ++i) tout << mk_pp(formulas[i], m) << "\n"; + ); + + expr_ref tmp(m); + ptr_vector tocollect; + + setup_model(mdl); + collect(formulas, tocollect); + for (unsigned i = 0; i < tocollect.size(); ++i) { + expr* e = tocollect[i]; + expr* e1, *e2; + SASSERT(m.is_bool(e)); + SASSERT(is_true(e) || is_false(e)); + if (is_true(e)) { + result.push_back(e); + } + // hack to break disequalities for arithmetic variables. + else if (m.is_eq(e, e1, e2) && m_arith.is_int_real(e1)) { + if (get_number(e1) < get_number(e2)) { + result.push_back(m_arith.mk_lt(e1, e2)); + } else { + result.push_back(m_arith.mk_lt(e2, e1)); + } + } else { + result.push_back(m.mk_not(e)); + } + } + reset(); + TRACE("old_spacer", + tout << "minimized model:\n"; + for (unsigned i = 0; i < result.size(); ++i) tout << mk_pp(result[i].get(), m) << "\n"; + ); +} + +void model_evaluator::process_formula(app* e, ptr_vector& todo, ptr_vector& tocollect) +{ + SASSERT(m.is_bool(e)); + SASSERT(is_true(e) || is_false(e)); + unsigned v = is_true(e); + unsigned sz = e->get_num_args(); + expr* const* args = e->get_args(); + if (e->get_family_id() == m.get_basic_family_id()) { + switch (e->get_decl_kind()) { + case OP_TRUE: + break; + case OP_FALSE: + break; + case OP_EQ: + case OP_IFF: + if (args[0] == args[1]) { + SASSERT(v); + // no-op + } else if (m.is_bool(args[0])) { + todo.append(sz, args); + } else { + tocollect.push_back(e); + } + break; + case OP_DISTINCT: + tocollect.push_back(e); + break; + case OP_ITE: + if (args[1] == args[2]) { + tocollect.push_back(args[1]); + } else if (is_true(args[1]) && is_true(args[2])) { + todo.append(2, args + 1); + } else if (is_false(args[1]) && is_false(args[2])) { + todo.append(2, args + 1); + } else if (is_true(args[0])) { + todo.append(2, args); + } else { + SASSERT(is_false(args[0])); + todo.push_back(args[0]); + todo.push_back(args[2]); + } + break; + case OP_AND: + if (v) { + todo.append(sz, args); + } else { + unsigned i = 0; + for (; !is_false(args[i]) && i < sz; ++i); + if (i == sz) { + fatal_error(1); + } + VERIFY(i < sz); + todo.push_back(args[i]); + } + break; + case OP_OR: + if (v) { + unsigned i = 0; + for (; !is_true(args[i]) && i < sz; ++i); + if (i == sz) { + fatal_error(1); + } + VERIFY(i < sz); + todo.push_back(args[i]); + } else { + todo.append(sz, args); + } + break; + case OP_XOR: + case OP_NOT: + todo.append(sz, args); + break; + case OP_IMPLIES: + if (v) { + if (is_true(args[1])) { + todo.push_back(args[1]); + } else if (is_false(args[0])) { + todo.push_back(args[0]); + } else { + IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); + UNREACHABLE(); + } + } else { + todo.append(sz, args); + } + break; + default: + IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); + UNREACHABLE(); + } + } else { + tocollect.push_back(e); + } +} + +void model_evaluator::collect(ptr_vector const& formulas, ptr_vector& tocollect) +{ + ptr_vector todo; + todo.append(formulas); + m_visited.reset(); + + VERIFY(check_model(formulas)); + + while (!todo.empty()) { + app* e = to_app(todo.back()); + todo.pop_back(); + if (!m_visited.is_marked(e)) { + process_formula(e, todo, tocollect); + m_visited.mark(e, true); + } + } + m_visited.reset(); +} + +void model_evaluator::eval_arith(app* e) +{ + rational r, r2; + +#define ARG1 e->get_arg(0) +#define ARG2 e->get_arg(1) + + unsigned arity = e->get_num_args(); + for (unsigned i = 0; i < arity; ++i) { + expr* arg = e->get_arg(i); + if (is_x(arg)) { + set_x(e); + return; + } + SASSERT(!is_unknown(arg)); + } + switch (e->get_decl_kind()) { + case OP_NUM: + VERIFY(m_arith.is_numeral(e, r)); + set_number(e, r); + break; + case OP_IRRATIONAL_ALGEBRAIC_NUM: + set_x(e); + break; + case OP_LE: + set_bool(e, get_number(ARG1) <= get_number(ARG2)); + break; + case OP_GE: + set_bool(e, get_number(ARG1) >= get_number(ARG2)); + break; + case OP_LT: + set_bool(e, get_number(ARG1) < get_number(ARG2)); + break; + case OP_GT: + set_bool(e, get_number(ARG1) > get_number(ARG2)); + break; + case OP_ADD: + r = rational::zero(); + for (unsigned i = 0; i < arity; ++i) { + r += get_number(e->get_arg(i)); + } + set_number(e, r); + break; + case OP_SUB: + r = get_number(e->get_arg(0)); + for (unsigned i = 1; i < arity; ++i) { + r -= get_number(e->get_arg(i)); + } + set_number(e, r); + break; + case OP_UMINUS: + SASSERT(arity == 1); + set_number(e, -get_number(e->get_arg(0))); + break; + case OP_MUL: + r = rational::one(); + for (unsigned i = 0; i < arity; ++i) { + r *= get_number(e->get_arg(i)); + } + set_number(e, r); + break; + case OP_DIV: + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } else { + set_number(e, get_number(ARG1) / r); + } + break; + case OP_IDIV: + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } else { + set_number(e, div(get_number(ARG1), r)); + } + break; + case OP_REM: + // rem(v1,v2) = if v2 >= 0 then mod(v1,v2) else -mod(v1,v2) + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } else { + r2 = mod(get_number(ARG1), r); + if (r.is_neg()) { r2.neg(); } + set_number(e, r2); + } + break; + case OP_MOD: + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } else { + set_number(e, mod(get_number(ARG1), r)); + } + break; + case OP_TO_REAL: + SASSERT(arity == 1); + set_number(e, get_number(ARG1)); + break; + case OP_TO_INT: + SASSERT(arity == 1); + set_number(e, floor(get_number(ARG1))); + break; + case OP_IS_INT: + SASSERT(arity == 1); + set_bool(e, get_number(ARG1).is_int()); + break; + case OP_POWER: + set_x(e); + break; + default: + IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); + UNREACHABLE(); + break; + } +} + +void model_evaluator::inherit_value(expr* e, expr* v) +{ + expr* w; + SASSERT(!is_unknown(v)); + SASSERT(m.get_sort(e) == m.get_sort(v)); + if (is_x(v)) { + set_x(e); + } else if (m.is_bool(e)) { + SASSERT(m.is_bool(v)); + if (is_true(v)) { set_true(e); } + else if (is_false(v)) { set_false(e); } + else { + TRACE("old_spacer", tout << "not inherited:\n" << mk_pp(e, m) << "\n" << mk_pp(v, m) << "\n";); + set_x(e); + } + } else if (m_arith.is_int_real(e)) { + set_number(e, get_number(v)); + } else if (m.is_value(v)) { + set_value(e, v); + } else if (m_values.find(v, w)) { + set_value(e, w); + } else { + TRACE("old_spacer", tout << "not inherited:\n" << mk_pp(e, m) << "\n" << mk_pp(v, m) << "\n";); + set_x(e); + } +} + +void model_evaluator::eval_exprs(expr_ref_vector& es) +{ + model_ref mr(m_model); + for (unsigned j = 0; j < es.size(); ++j) { + if (m_array.is_as_array(es[j].get())) { + es[j] = eval(mr, es[j].get()); + } + } +} + +bool model_evaluator::extract_array_func_interp(expr* a, vector& stores, expr_ref& else_case) +{ + SASSERT(m_array.is_array(a)); + + TRACE("old_spacer", tout << mk_pp(a, m) << "\n";); + while (m_array.is_store(a)) { + expr_ref_vector store(m); + store.append(to_app(a)->get_num_args() - 1, to_app(a)->get_args() + 1); + eval_exprs(store); + stores.push_back(store); + a = to_app(a)->get_arg(0); + } + + if (m_array.is_const(a)) { + else_case = to_app(a)->get_arg(0); + return true; + } + + while (m_array.is_as_array(a)) { + func_decl* f = m_array.get_as_array_func_decl(to_app(a)); + func_interp* g = m_model->get_func_interp(f); + unsigned sz = g->num_entries(); + unsigned arity = f->get_arity(); + for (unsigned i = 0; i < sz; ++i) { + expr_ref_vector store(m); + func_entry const* fe = g->get_entry(i); + store.append(arity, fe->get_args()); + store.push_back(fe->get_result()); + for (unsigned j = 0; j < store.size(); ++j) { + if (!is_ground(store[j].get())) { + TRACE("old_spacer", tout << "could not extract array interpretation: " << mk_pp(a, m) << "\n" << mk_pp(store[j].get(), m) << "\n";); + return false; + } + } + eval_exprs(store); + stores.push_back(store); + } + else_case = g->get_else(); + if (!else_case) { + TRACE("old_spacer", tout << "no else case " << mk_pp(a, m) << "\n";); + return false; + } + if (!is_ground(else_case)) { + TRACE("old_spacer", tout << "non-ground else case " << mk_pp(a, m) << "\n" << mk_pp(else_case, m) << "\n";); + return false; + } + if (m_array.is_as_array(else_case)) { + model_ref mr(m_model); + else_case = eval(mr, else_case); + } + TRACE("old_spacer", tout << "else case: " << mk_pp(else_case, m) << "\n";); + return true; + } + TRACE("old_spacer", tout << "no translation: " << mk_pp(a, m) << "\n";); + + return false; +} + +/** + best effort evaluator of extensional array equality. +*/ +void model_evaluator::eval_array_eq(app* e, expr* arg1, expr* arg2) +{ + TRACE("old_spacer", tout << "array equality: " << mk_pp(e, m) << "\n";); + expr_ref v1(m), v2(m); + m_model->eval(arg1, v1); + m_model->eval(arg2, v2); + if (v1 == v2) { + set_true(e); + return; + } + sort* s = m.get_sort(arg1); + sort* r = get_array_range(s); + // give up evaluating finite domain/range arrays + if (!r->is_infinite() && !r->is_very_big() && !s->is_infinite() && !s->is_very_big()) { + TRACE("old_spacer", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); + return; + } + vector store; + expr_ref else1(m), else2(m); + if (!extract_array_func_interp(v1, store, else1) || + !extract_array_func_interp(v2, store, else2)) { + TRACE("old_spacer", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); + return; + } + + if (else1 != else2) { + if (m.is_value(else1) && m.is_value(else2)) { + TRACE("old_spacer", tout + << "defaults are different: " << mk_pp(e, m) << " " + << mk_pp(else1, m) << " " << mk_pp(else2, m) << "\n";); + set_false(e); + } else if (m_array.is_array(else1)) { + eval_array_eq(e, else1, else2); + } else { + TRACE("old_spacer", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); + } + return; + } + + expr_ref s1(m), s2(m), w1(m), w2(m); + expr_ref_vector args1(m), args2(m); + args1.push_back(v1); + args2.push_back(v2); + for (unsigned i = 0; i < store.size(); ++i) { + args1.resize(1); + args2.resize(1); + args1.append(store[i].size() - 1, store[i].c_ptr()); + args2.append(store[i].size() - 1, store[i].c_ptr()); + s1 = m_array.mk_select(args1.size(), args1.c_ptr()); + s2 = m_array.mk_select(args2.size(), args2.c_ptr()); + m_model->eval(s1, w1); + m_model->eval(s2, w2); + if (w1 == w2) { + continue; + } + if (m.is_value(w1) && m.is_value(w2)) { + TRACE("old_spacer", tout << "Equality evaluation: " << mk_pp(e, m) << "\n"; + tout << mk_pp(s1, m) << " |-> " << mk_pp(w1, m) << "\n"; + tout << mk_pp(s2, m) << " |-> " << mk_pp(w2, m) << "\n";); + set_false(e); + } else if (m_array.is_array(w1)) { + eval_array_eq(e, w1, w2); + if (is_true(e)) { + continue; + } + } else { + TRACE("old_spacer", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); + } + return; + } + set_true(e); +} + +void model_evaluator::eval_eq(app* e, expr* arg1, expr* arg2) +{ + if (arg1 == arg2) { + set_true(e); + } else if (m_array.is_array(arg1)) { + eval_array_eq(e, arg1, arg2); + } else if (is_x(arg1) || is_x(arg2)) { + set_x(e); + } else if (m.is_bool(arg1)) { + bool val = is_true(arg1) == is_true(arg2); + SASSERT(val == (is_false(arg1) == is_false(arg2))); + if (val) { + set_true(e); + } else { + set_false(e); + } + } else if (m_arith.is_int_real(arg1)) { + set_bool(e, get_number(arg1) == get_number(arg2)); + } else { + expr* e1 = get_value(arg1); + expr* e2 = get_value(arg2); + if (m.is_value(e1) && m.is_value(e2)) { + set_bool(e, e1 == e2); + } else if (e1 == e2) { + set_bool(e, true); + } else { + TRACE("old_spacer", tout << "not value equal:\n" << mk_pp(e1, m) << "\n" << mk_pp(e2, m) << "\n";); + set_x(e); + } + } +} + +void model_evaluator::eval_basic(app* e) +{ + expr* arg1, *arg2; + expr *argCond, *argThen, *argElse, *arg; + bool has_x = false; + unsigned arity = e->get_num_args(); + switch (e->get_decl_kind()) { + case OP_AND: + for (unsigned j = 0; j < arity; ++j) { + expr * arg = e->get_arg(j); + if (is_false(arg)) { + set_false(e); + return; + } else if (is_x(arg)) { + has_x = true; + } else { + SASSERT(is_true(arg)); + } + } + if (has_x) { + set_x(e); + } else { + set_true(e); + } + break; + case OP_OR: + for (unsigned j = 0; j < arity; ++j) { + expr * arg = e->get_arg(j); + if (is_true(arg)) { + set_true(e); + return; + } else if (is_x(arg)) { + has_x = true; + } else { + SASSERT(is_false(arg)); + } + } + if (has_x) { + set_x(e); + } else { + set_false(e); + } + break; + case OP_NOT: + VERIFY(m.is_not(e, arg)); + if (is_true(arg)) { + set_false(e); + } else if (is_false(arg)) { + set_true(e); + } else { + SASSERT(is_x(arg)); + set_x(e); + } + break; + case OP_IMPLIES: + VERIFY(m.is_implies(e, arg1, arg2)); + if (is_false(arg1) || is_true(arg2)) { + set_true(e); + } else if (arg1 == arg2) { + set_true(e); + } else if (is_true(arg1) && is_false(arg2)) { + set_false(e); + } else { + SASSERT(is_x(arg1) || is_x(arg2)); + set_x(e); + } + break; + case OP_IFF: + VERIFY(m.is_iff(e, arg1, arg2)); + eval_eq(e, arg1, arg2); + break; + case OP_XOR: + VERIFY(m.is_xor(e, arg1, arg2)); + eval_eq(e, arg1, arg2); + if (is_false(e)) { set_true(e); } + else if (is_true(e)) { set_false(e); } + break; + case OP_ITE: + VERIFY(m.is_ite(e, argCond, argThen, argElse)); + if (is_true(argCond)) { + inherit_value(e, argThen); + } else if (is_false(argCond)) { + inherit_value(e, argElse); + } else if (argThen == argElse) { + inherit_value(e, argThen); + } else if (m.is_bool(e)) { + SASSERT(is_x(argCond)); + if (is_x(argThen) || is_x(argElse)) { + set_x(e); + } else if (is_true(argThen) == is_true(argElse)) { + inherit_value(e, argThen); + } else { + set_x(e); + } + } else { + set_x(e); + } + break; + case OP_TRUE: + set_true(e); + break; + case OP_FALSE: + set_false(e); + break; + case OP_EQ: + VERIFY(m.is_eq(e, arg1, arg2)); + eval_eq(e, arg1, arg2); + break; + case OP_DISTINCT: { + vector values; + for (unsigned i = 0; i < arity; ++i) { + expr* arg = e->get_arg(i); + if (is_x(arg)) { + set_x(e); + return; + } + values.push_back(get_number(arg)); + } + std::sort(values.begin(), values.end()); + for (unsigned i = 0; i + 1 < values.size(); ++i) { + if (values[i] == values[i + 1]) { + set_false(e); + return; + } + } + set_true(e); + break; + } + default: + IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); + UNREACHABLE(); + } +} + +void model_evaluator::eval_fmls(ptr_vector const& formulas) +{ + ptr_vector todo(formulas); + + while (!todo.empty()) { + expr * curr_e = todo.back(); + + if (!is_app(curr_e)) { + todo.pop_back(); + continue; + } + app * curr = to_app(curr_e); + + if (!is_unknown(curr)) { + todo.pop_back(); + continue; + } + unsigned arity = curr->get_num_args(); + for (unsigned i = 0; i < arity; ++i) { + if (is_unknown(curr->get_arg(i))) { + todo.push_back(curr->get_arg(i)); + } + } + if (todo.back() != curr) { + continue; + } + todo.pop_back(); + if (curr->get_family_id() == m_arith.get_family_id()) { + eval_arith(curr); + } else if (curr->get_family_id() == m.get_basic_family_id()) { + eval_basic(curr); + } else { + expr_ref vl(m); + m_model->eval(curr, vl); + assign_value(curr, vl); + } + + IF_VERBOSE(35, verbose_stream() << "assigned " << mk_pp(curr_e, m) + << (is_true(curr_e) ? "true" : is_false(curr_e) ? "false" : "unknown") << "\n";); + SASSERT(!is_unknown(curr)); + } +} + +bool model_evaluator::check_model(ptr_vector const& formulas) +{ + eval_fmls(formulas); + bool has_x = false; + for (unsigned i = 0; i < formulas.size(); ++i) { + expr * form = formulas[i]; + SASSERT(!is_unknown(form)); + TRACE("spacer_verbose", + tout << "formula is " << (is_true(form) ? "true" : is_false(form) ? "false" : "unknown") << "\n" << mk_pp(form, m) << "\n";); + + if (is_false(form)) { + IF_VERBOSE(0, verbose_stream() << "formula false in model: " << mk_pp(form, m) << "\n";); + UNREACHABLE(); + } + if (is_x(form)) { + IF_VERBOSE(0, verbose_stream() << "formula undetermined in model: " << mk_pp(form, m) << "\n";); + TRACE("old_spacer", model_smt2_pp(tout, m, *m_model, 0);); + has_x = true; + } + } + return !has_x; +} + +expr_ref model_evaluator::eval_heavy(const model_ref& model, expr* fml) +{ + expr_ref result(model->get_manager()); + + setup_model(model); + ptr_vector fmls; + fmls.push_back(fml); + eval_fmls(fmls); + if (is_false(fml)) { + result = m.mk_false(); + } else if (is_true(fml) || is_x(fml)) { + result = m.mk_true(); + } else if (m_arith.is_int_real(fml)) { + result = m_arith.mk_numeral(get_number(fml), m_arith.is_int(fml)); + } else { + result = get_value(fml); + } + reset(); + + return result; +} + +expr_ref model_evaluator::eval(const model_ref& model, func_decl* d) +{ + SASSERT(d->get_arity() == 0); + expr_ref result(m); + if (m_array.is_array(d->get_range())) { + expr_ref e(m); + e = m.mk_const(d); + result = eval(model, e); + } else { + result = model->get_const_interp(d); + } + return result; +} + +expr_ref model_evaluator::eval(const model_ref& model, expr* e) +{ + expr_ref result(m); + m_model = model.get(); + VERIFY(m_model->eval(e, result, true)); + if (m_array.is_array(e)) { + vector stores; + expr_ref_vector args(m); + expr_ref else_case(m); + if (extract_array_func_interp(result, stores, else_case)) { + result = m_array.mk_const_array(m.get_sort(e), else_case); + while (!stores.empty() && stores.back().back() == else_case) { + stores.pop_back(); + } + for (unsigned i = stores.size(); i > 0;) { + --i; + args.resize(1); + args[0] = result; + args.append(stores[i]); + result = m_array.mk_store(args.size(), args.c_ptr()); + } + return result; + } + } + return result; +} + + +} diff --git a/src/muz/spacer/spacer_legacy_mev.h b/src/muz/spacer/spacer_legacy_mev.h new file mode 100644 index 000000000..21790f022 --- /dev/null +++ b/src/muz/spacer/spacer_legacy_mev.h @@ -0,0 +1,117 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + + Deprecated implementation of model evaluator. To be removed. +*/ +#ifndef OLD_MEV_H +#define OLD_MEV_H + +#include "ast.h" +#include "ast_pp.h" +#include "obj_hashtable.h" +#include "ref_vector.h" +#include "simplifier.h" +#include "trace.h" +#include "vector.h" +#include "arith_decl_plugin.h" +#include "array_decl_plugin.h" +#include "bv_decl_plugin.h" + +namespace old { +class model_evaluator { + ast_manager& m; + arith_util m_arith; + array_util m_array; + obj_map m_numbers; + expr_ref_vector m_refs; + obj_map m_values; + model_ref m_model; + + //00 -- non-visited + //01 -- X + //10 -- false + //11 -- true + expr_mark m1; + expr_mark m2; + + /// used by collect() + expr_mark m_visited; + + + + void reset(); + + /// caches the values of all constants in the given model + void setup_model(const model_ref& model); + /// caches the value of an expression + void assign_value(expr* e, expr* v); + + /// extracts an implicant of the conjunction of formulas + void collect(ptr_vector const& formulas, ptr_vector& tocollect); + + /// one-round of extracting an implicant of e. The implicant + /// literals are stored in tocollect. The worklist is stored in todo + void process_formula(app* e, ptr_vector& todo, ptr_vector& tocollect); + void eval_arith(app* e); + void eval_basic(app* e); + void eval_eq(app* e, expr* arg1, expr* arg2); + void eval_array_eq(app* e, expr* arg1, expr* arg2); + void inherit_value(expr* e, expr* v); + + bool is_unknown(expr* x) { return !m1.is_marked(x) && !m2.is_marked(x); } + void set_unknown(expr* x) { m1.mark(x, false); m2.mark(x, false); } + bool is_x(expr* x) { return !m1.is_marked(x) && m2.is_marked(x); } + bool is_false(expr* x) { return m1.is_marked(x) && !m2.is_marked(x); } + bool is_true(expr* x) { return m1.is_marked(x) && m2.is_marked(x); } + void set_x(expr* x) { SASSERT(is_unknown(x)); m2.mark(x); } + void set_v(expr* x) { SASSERT(is_unknown(x)); m1.mark(x); } + void set_false(expr* x) { SASSERT(is_unknown(x)); m1.mark(x); } + void set_true(expr* x) { SASSERT(is_unknown(x)); m1.mark(x); m2.mark(x); } + void set_bool(expr* x, bool v) { if(v) { set_true(x); } else { set_false(x); } } + rational const& get_number(expr* x) const { return m_numbers.find(x); } + void set_number(expr* x, rational const& v) + { + set_v(x); + m_numbers.insert(x, v); + TRACE("spacer_verbose", tout << mk_pp(x, m) << " " << v << "\n";); + } + expr* get_value(expr* x) { return m_values.find(x); } + void set_value(expr* x, expr* v) + { set_v(x); m_refs.push_back(v); m_values.insert(x, v); } + + + /// evaluates all sub-formulas and terms of the input in the current model. + /// Caches the result + void eval_fmls(ptr_vector const & formulas); + + /// calls eval_fmls(). Then checks whether all formulas are + /// TRUE. Returns false if at lest one formula is unknown (X) + bool check_model(ptr_vector const & formulas); + + bool extract_array_func_interp(expr* a, vector& stores, + expr_ref& else_case); + + void eval_exprs(expr_ref_vector& es); + +public: + model_evaluator(ast_manager& m) : m(m), m_arith(m), m_array(m), m_refs(m) {} + + + /** + \brief extract literals from formulas that satisfy formulas. + + \pre model satisfies formulas + */ + void minimize_literals(ptr_vector const & formulas, const model_ref& mdl, + expr_ref_vector& result); + + expr_ref eval_heavy(const model_ref& mdl, expr* fml); + + expr_ref eval(const model_ref& mdl, expr* e); + expr_ref eval(const model_ref& mdl, func_decl* d); +}; +} + + + +#endif /* OLD_MEV_H */ diff --git a/src/muz/spacer/spacer_manager.cpp b/src/muz/spacer/spacer_manager.cpp new file mode 100644 index 000000000..077874488 --- /dev/null +++ b/src/muz/spacer/spacer_manager.cpp @@ -0,0 +1,386 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_manager.cpp + +Abstract: + + A manager class for SPACER, taking care of creating of AST + objects and conversions between them. + +Author: + + Krystof Hoder (t-khoder) 2011-8-25. + +Revision History: + +--*/ + +#include +#include "spacer_manager.h" +#include "ast_smt2_pp.h" +#include "for_each_expr.h" +#include "has_free_vars.h" +#include "expr_replacer.h" +#include "expr_abstract.h" +#include "model2expr.h" +#include "model_smt2_pp.h" +#include "model_converter.h" + +namespace spacer { + +class collect_decls_proc { + func_decl_set& m_bound_decls; + func_decl_set& m_aux_decls; +public: + collect_decls_proc(func_decl_set& bound_decls, func_decl_set& aux_decls): + m_bound_decls(bound_decls), + m_aux_decls(aux_decls) + { + } + + void operator()(app* a) + { + if (a->get_family_id() == null_family_id) { + func_decl* f = a->get_decl(); + if (!m_bound_decls.contains(f)) { + m_aux_decls.insert(f); + } + } + } + void operator()(var* v) {} + void operator()(quantifier* q) {} +}; + +typedef hashtable symbol_set; + +expr_ref inductive_property::fixup_clause(expr* fml) const +{ + expr_ref_vector disjs(m); + flatten_or(fml, disjs); + expr_ref result(m); + bool_rewriter(m).mk_or(disjs.size(), disjs.c_ptr(), result); + return result; +} + +expr_ref inductive_property::fixup_clauses(expr* fml) const +{ + expr_ref_vector conjs(m); + expr_ref result(m); + flatten_and(fml, conjs); + for (unsigned i = 0; i < conjs.size(); ++i) { + conjs[i] = fixup_clause(conjs[i].get()); + } + bool_rewriter(m).mk_and(conjs.size(), conjs.c_ptr(), result); + return result; +} + +std::string inductive_property::to_string() const +{ + std::stringstream stm; + model_ref md; + expr_ref result(m); + to_model(md); + model_smt2_pp(stm, m, *md.get(), 0); + return stm.str(); +} + +void inductive_property::to_model(model_ref& md) const +{ + md = alloc(model, m); + vector const& rs = m_relation_info; + expr_ref_vector conjs(m); + for (unsigned i = 0; i < rs.size(); ++i) { + relation_info ri(rs[i]); + func_decl * pred = ri.m_pred; + expr_ref prop = fixup_clauses(ri.m_body); + func_decl_ref_vector const& sig = ri.m_vars; + expr_ref q(m); + expr_ref_vector sig_vars(m); + for (unsigned j = 0; j < sig.size(); ++j) { + sig_vars.push_back(m.mk_const(sig[sig.size() - j - 1])); + } + expr_abstract(m, 0, sig_vars.size(), sig_vars.c_ptr(), prop, q); + if (sig.empty()) { + md->register_decl(pred, q); + } else { + func_interp* fi = alloc(func_interp, m, sig.size()); + fi->set_else(q); + md->register_decl(pred, fi); + } + } + TRACE("spacer", model_smt2_pp(tout, m, *md, 0);); + apply(const_cast(m_mc), md, 0); +} + +expr_ref inductive_property::to_expr() const +{ + model_ref md; + expr_ref result(m); + to_model(md); + model2expr(md, result); + return result; +} + + +void inductive_property::display(datalog::rule_manager& rm, ptr_vector const& rules, std::ostream& out) const +{ + func_decl_set bound_decls, aux_decls; + collect_decls_proc collect_decls(bound_decls, aux_decls); + + for (unsigned i = 0; i < m_relation_info.size(); ++i) { + bound_decls.insert(m_relation_info[i].m_pred); + func_decl_ref_vector const& sig = m_relation_info[i].m_vars; + for (unsigned j = 0; j < sig.size(); ++j) { + bound_decls.insert(sig[j]); + } + for_each_expr(collect_decls, m_relation_info[i].m_body); + } + for (unsigned i = 0; i < rules.size(); ++i) { + bound_decls.insert(rules[i]->get_decl()); + } + for (unsigned i = 0; i < rules.size(); ++i) { + unsigned u_sz = rules[i]->get_uninterpreted_tail_size(); + unsigned t_sz = rules[i]->get_tail_size(); + for (unsigned j = u_sz; j < t_sz; ++j) { + for_each_expr(collect_decls, rules[i]->get_tail(j)); + } + } + smt2_pp_environment_dbg env(m); + func_decl_set::iterator it = aux_decls.begin(), end = aux_decls.end(); + for (; it != end; ++it) { + func_decl* f = *it; + ast_smt2_pp(out, f, env); + out << "\n"; + } + + out << to_string() << "\n"; + for (unsigned i = 0; i < rules.size(); ++i) { + out << "(push)\n"; + out << "(assert (not\n"; + rm.display_smt2(*rules[i], out); + out << "))\n"; + out << "(check-sat)\n"; + out << "(pop)\n"; + } +} + +std::vector manager::get_state_suffixes() +{ + std::vector res; + res.push_back("_n"); + return res; +} + +manager::manager(unsigned max_num_contexts, ast_manager& manager) : + m(manager), + m_brwr(m), + m_mux(m, get_state_suffixes()), + m_background(m.mk_true(), m), + m_contexts(m, max_num_contexts), + m_contexts2(m, max_num_contexts), + m_contexts3(m, max_num_contexts), + m_next_unique_num(0) +{ +} + + +void manager::add_new_state(func_decl * s) +{ + SASSERT(s->get_arity() == 0); //we currently don't support non-constant states + decl_vector vect; + + SASSERT(o_index(0) == 1); //we assume this in the number of retrieved symbols + m_mux.create_tuple(s, s->get_arity(), s->get_domain(), s->get_range(), 2, vect); + m_o0_preds.push_back(vect[o_index(0)]); +} + +func_decl * manager::get_o_pred(func_decl* s, unsigned idx) +{ + func_decl * res = m_mux.try_get_by_prefix(s, o_index(idx)); + if (res) { return res; } + add_new_state(s); + res = m_mux.try_get_by_prefix(s, o_index(idx)); + SASSERT(res); + return res; +} + +func_decl * manager::get_n_pred(func_decl* s) +{ + func_decl * res = m_mux.try_get_by_prefix(s, n_index()); + if (res) { return res; } + add_new_state(s); + res = m_mux.try_get_by_prefix(s, n_index()); + SASSERT(res); + return res; +} + +void manager::mk_model_into_cube(const expr_ref_vector & mdl, expr_ref & res) +{ + m_brwr.mk_and(mdl.size(), mdl.c_ptr(), res); +} + +void manager::mk_core_into_cube(const expr_ref_vector & core, expr_ref & res) +{ + m_brwr.mk_and(core.size(), core.c_ptr(), res); +} + +void manager::mk_cube_into_lemma(expr * cube, expr_ref & res) +{ + m_brwr.mk_not(cube, res); +} + +void manager::mk_lemma_into_cube(expr * lemma, expr_ref & res) +{ + m_brwr.mk_not(lemma, res); +} + +expr_ref manager::mk_and(unsigned sz, expr* const* exprs) +{ + expr_ref result(m); + m_brwr.mk_and(sz, exprs, result); + return result; +} + +expr_ref manager::mk_or(unsigned sz, expr* const* exprs) +{ + expr_ref result(m); + m_brwr.mk_or(sz, exprs, result); + return result; +} + +expr_ref manager::mk_not_and(expr_ref_vector const& conjs) +{ + expr_ref result(m), e(m); + expr_ref_vector es(conjs); + flatten_and(es); + for (unsigned i = 0; i < es.size(); ++i) { + m_brwr.mk_not(es[i].get(), e); + es[i] = e; + } + m_brwr.mk_or(es.size(), es.c_ptr(), result); + return result; +} + +void manager::get_or(expr* e, expr_ref_vector& result) +{ + result.push_back(e); + for (unsigned i = 0; i < result.size();) { + e = result[i].get(); + if (m.is_or(e)) { + result.append(to_app(e)->get_num_args(), to_app(e)->get_args()); + result[i] = result.back(); + result.pop_back(); + } else { + ++i; + } + } +} + +bool manager::try_get_state_and_value_from_atom(expr * atom0, app *& state, app_ref& value) +{ + if (!is_app(atom0)) { + return false; + } + app * atom = to_app(atom0); + expr * arg1; + expr * arg2; + app * candidate_state; + app_ref candidate_value(m); + if (m.is_not(atom, arg1)) { + if (!is_app(arg1)) { + return false; + } + candidate_state = to_app(arg1); + candidate_value = m.mk_false(); + } else if (m.is_eq(atom, arg1, arg2)) { + if (!is_app(arg1) || !is_app(arg2)) { + return false; + } + if (!m_mux.is_muxed(to_app(arg1)->get_decl())) { + std::swap(arg1, arg2); + } + candidate_state = to_app(arg1); + candidate_value = to_app(arg2); + } else { + candidate_state = atom; + candidate_value = m.mk_true(); + } + if (!m_mux.is_muxed(candidate_state->get_decl())) { + return false; + } + state = candidate_state; + value = candidate_value; + return true; +} + +bool manager::try_get_state_decl_from_atom(expr * atom, func_decl *& state) +{ + app_ref dummy_value_holder(m); + app * s; + if (try_get_state_and_value_from_atom(atom, s, dummy_value_holder)) { + state = s->get_decl(); + return true; + } else { + return false; + } +} + +/** + * Create a new skolem constant + */ +app* mk_zk_const(ast_manager &m, unsigned idx, sort *s) { + std::stringstream name; + name << "sk!" << idx; + return m.mk_const(symbol(name.str().c_str()), s); +} + +namespace find_zk_const_ns { +struct proc { + app_ref_vector &m_out; + proc (app_ref_vector &out) : m_out(out) {} + void operator() (var const * n) const {} + void operator() (app *n) const { + if (is_uninterp_const(n) && + n->get_decl()->get_name().str().compare (0, 3, "sk!") == 0) { + m_out.push_back (n); + } + } + void operator() (quantifier const *n) const {} +}; +} + +void find_zk_const(expr *e, app_ref_vector &res) { + find_zk_const_ns::proc p(res); + for_each_expr (p, e); +} + +namespace has_zk_const_ns { +struct found {}; +struct proc { + void operator() (var const *n) const {} + void operator() (app const *n) const { + if (is_uninterp_const(n) && + n->get_decl()->get_name().str().compare(0, 3, "sk!") == 0) { + throw found(); + } + } + void operator() (quantifier const *n) const {} +}; +} + + +bool has_zk_const(expr *e){ + has_zk_const_ns::proc p; + try { + for_each_expr(p, e); + } + catch (has_zk_const_ns::found) { + return true; + } + return false; +} + +} diff --git a/src/muz/spacer/spacer_manager.h b/src/muz/spacer/spacer_manager.h new file mode 100644 index 000000000..360c4ceb2 --- /dev/null +++ b/src/muz/spacer/spacer_manager.h @@ -0,0 +1,345 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_manager.h + +Abstract: + + A manager class for SPACER, taking care of creating of AST + objects and conversions between them. + +Author: + + Krystof Hoder (t-khoder) 2011-8-25. + +Revision History: + +--*/ + +#ifndef _SPACER_MANAGER_H_ +#define _SPACER_MANAGER_H_ + +#include +#include +#include "bool_rewriter.h" +#include "expr_replacer.h" +#include "expr_substitution.h" +#include "map.h" +#include "ref_vector.h" +#include "smt_kernel.h" +#include "spacer_util.h" +#include "spacer_sym_mux.h" +#include "spacer_farkas_learner.h" +#include "spacer_smt_context_manager.h" +#include "dl_rule.h" +#include + +namespace smt { +class context; +} + +namespace spacer { + +struct relation_info { + func_decl_ref m_pred; + func_decl_ref_vector m_vars; + expr_ref m_body; + relation_info(ast_manager& m, func_decl* pred, ptr_vector const& vars, expr* b): + m_pred(pred, m), m_vars(m, vars.size(), vars.c_ptr()), m_body(b, m) {} + relation_info(relation_info const& other): m_pred(other.m_pred), m_vars(other.m_vars), m_body(other.m_body) {} +}; + +class unknown_exception {}; + +class inductive_property { + ast_manager& m; + model_converter_ref m_mc; + vector m_relation_info; + expr_ref fixup_clauses(expr* property) const; + expr_ref fixup_clause(expr* clause) const; +public: + inductive_property(ast_manager& m, model_converter_ref& mc, vector const& relations): + m(m), + m_mc(mc), + m_relation_info(relations) {} + + std::string to_string() const; + + expr_ref to_expr() const; + + void to_model(model_ref& md) const; + + void display(datalog::rule_manager& rm, ptr_vector const& rules, std::ostream& out) const; +}; + +class manager { + ast_manager& m; + + mutable bool_rewriter m_brwr; + + sym_mux m_mux; + expr_ref m_background; + decl_vector m_o0_preds; + spacer::smt_context_manager m_contexts; + spacer::smt_context_manager m_contexts2; + spacer::smt_context_manager m_contexts3; + + /** whenever we need an unique number, we get this one and increase */ + unsigned m_next_unique_num; + + + static std::vector get_state_suffixes(); + + unsigned n_index() const { return 0; } + unsigned o_index(unsigned i) const { return i + 1; } + + void add_new_state(func_decl * s); + +public: + manager(unsigned max_num_contexts, ast_manager & manager); + + ast_manager& get_manager() const { return m; } + bool_rewriter& get_brwr() const { return m_brwr; } + + expr_ref mk_and(unsigned sz, expr* const* exprs); + expr_ref mk_and(expr_ref_vector const& exprs) + { + return mk_and(exprs.size(), exprs.c_ptr()); + } + expr_ref mk_and(expr* a, expr* b) + { + expr* args[2] = { a, b }; + return mk_and(2, args); + } + expr_ref mk_or(unsigned sz, expr* const* exprs); + expr_ref mk_or(expr_ref_vector const& exprs) + { + return mk_or(exprs.size(), exprs.c_ptr()); + } + + expr_ref mk_not_and(expr_ref_vector const& exprs); + + void get_or(expr* e, expr_ref_vector& result); + + //"o" predicates stand for the old states and "n" for the new states + func_decl * get_o_pred(func_decl * s, unsigned idx); + func_decl * get_n_pred(func_decl * s); + + /** + Marks symbol as non-model which means it will not appear in models collected by + get_state_cube_from_model function. + This is to take care of auxiliary symbols introduced by the disjunction relations + to relativize lemmas coming from disjuncts. + */ + void mark_as_non_model(func_decl * p) + { + m_mux.mark_as_non_model(p); + } + + + func_decl * const * begin_o0_preds() const { return m_o0_preds.begin(); } + func_decl * const * end_o0_preds() const { return m_o0_preds.end(); } + + bool is_state_pred(func_decl * p) const { return m_mux.is_muxed(p); } + func_decl * to_o0(func_decl * p) { return m_mux.conv(m_mux.get_primary(p), 0, o_index(0)); } + + bool is_o(func_decl * p, unsigned idx) const + { + return m_mux.has_index(p, o_index(idx)); + } + void get_o_index(func_decl* p, unsigned& idx) const + { + m_mux.try_get_index(p, idx); + SASSERT(idx != n_index()); + idx--; // m_mux has indices starting at 1 + } + bool is_o(expr* e, unsigned idx) const + { + return is_app(e) && is_o(to_app(e)->get_decl(), idx); + } + bool is_o(func_decl * p) const + { + unsigned idx; + return m_mux.try_get_index(p, idx) && idx != n_index(); + } + bool is_o(expr* e) const + { + return is_app(e) && is_o(to_app(e)->get_decl()); + } + bool is_n(func_decl * p) const + { + return m_mux.has_index(p, n_index()); + } + bool is_n(expr* e) const + { + return is_app(e) && is_n(to_app(e)->get_decl()); + } + + /** true if p should not appead in models propagates into child relations */ + bool is_non_model_sym(func_decl * p) const + { return m_mux.is_non_model_sym(p); } + + + /** true if f doesn't contain any n predicates */ + bool is_o_formula(expr * f) const + { + return !m_mux.contains(f, n_index()); + } + + /** true if f contains only o state preds of index o_idx */ + bool is_o_formula(expr * f, unsigned o_idx) const + { + return m_mux.is_homogenous_formula(f, o_index(o_idx)); + } + /** true if f doesn't contain any o predicates */ + bool is_n_formula(expr * f) const + { + return m_mux.is_homogenous_formula(f, n_index()); + } + + func_decl * o2n(func_decl * p, unsigned o_idx) const + { + return m_mux.conv(p, o_index(o_idx), n_index()); + } + func_decl * o2o(func_decl * p, unsigned src_idx, unsigned tgt_idx) const + { + return m_mux.conv(p, o_index(src_idx), o_index(tgt_idx)); + } + func_decl * n2o(func_decl * p, unsigned o_idx) const + { + return m_mux.conv(p, n_index(), o_index(o_idx)); + } + + void formula_o2n(expr * f, expr_ref & result, unsigned o_idx, bool homogenous = true) const + { m_mux.conv_formula(f, o_index(o_idx), n_index(), result, homogenous); } + + void formula_n2o(expr * f, expr_ref & result, unsigned o_idx, bool homogenous = true) const + { m_mux.conv_formula(f, n_index(), o_index(o_idx), result, homogenous); } + + void formula_n2o(unsigned o_idx, bool homogenous, expr_ref & result) const + { m_mux.conv_formula(result.get(), n_index(), o_index(o_idx), result, homogenous); } + + void formula_o2o(expr * src, expr_ref & tgt, unsigned src_idx, unsigned tgt_idx, bool homogenous = true) const + { m_mux.conv_formula(src, o_index(src_idx), o_index(tgt_idx), tgt, homogenous); } + + /** + Return true if all state symbols which e contains are of one kind (either "n" or one of "o"). + */ + bool is_homogenous_formula(expr * e) const + { + return m_mux.is_homogenous_formula(e); + } + + /** + Collect indices used in expression. + */ + void collect_indices(expr* e, unsigned_vector& indices) const + { + m_mux.collect_indices(e, indices); + } + + /** + Collect used variables of each index. + */ + void collect_variables(expr* e, vector >& vars) const + { + m_mux.collect_variables(e, vars); + } + + /** + Return true iff both s1 and s2 are either "n" or "o" of the same index. + If one (or both) of them are not state symbol, return false. + */ + bool have_different_state_kinds(func_decl * s1, func_decl * s2) const + { + unsigned i1, i2; + return m_mux.try_get_index(s1, i1) && m_mux.try_get_index(s2, i2) && i1 != i2; + } + + /** + Increase indexes of state symbols in formula by dist. + The 'N' index becomes 'O' index with number dist-1. + */ + void formula_shift(expr * src, expr_ref & tgt, unsigned dist) const + { + SASSERT(n_index() == 0); + SASSERT(o_index(0) == 1); + m_mux.shift_formula(src, dist, tgt); + } + + void mk_model_into_cube(const expr_ref_vector & mdl, expr_ref & res); + void mk_core_into_cube(const expr_ref_vector & core, expr_ref & res); + void mk_cube_into_lemma(expr * cube, expr_ref & res); + void mk_lemma_into_cube(expr * lemma, expr_ref & res); + + /** + Remove from vec all atoms that do not have an "o" state. + The order of elements in vec may change. + An assumption is that atoms having "o" state of given index + do not have "o" states of other indexes or "n" states. + */ + void filter_o_atoms(expr_ref_vector& vec, unsigned o_idx) const + { m_mux.filter_idx(vec, o_index(o_idx)); } + void filter_n_atoms(expr_ref_vector& vec) const + { m_mux.filter_idx(vec, n_index()); } + + /** + Partition literals into o_lits and others. + */ + void partition_o_atoms(expr_ref_vector const& lits, + expr_ref_vector& o_lits, + expr_ref_vector& other, + unsigned o_idx) const + { + m_mux.partition_o_idx(lits, o_lits, other, o_index(o_idx)); + } + + void filter_out_non_model_atoms(expr_ref_vector& vec) const + { m_mux.filter_non_model_lits(vec); } + + bool try_get_state_and_value_from_atom(expr * atom, app *& state, app_ref& value); + bool try_get_state_decl_from_atom(expr * atom, func_decl *& state); + + + std::string pp_model(const model_core & mdl) const + { return m_mux.pp_model(mdl); } + + + void set_background(expr* b) { m_background = b; } + + expr* get_background() const { return m_background; } + + unsigned get_unique_num() { return m_next_unique_num++; } + + solver* mk_fresh() {return m_contexts.mk_fresh();} + smt_params& fparams() { return m_contexts.fparams(); } + solver* mk_fresh2() {return m_contexts2.mk_fresh();} + smt_params &fparams2() { return m_contexts2.fparams(); } + solver* mk_fresh3() {return m_contexts3.mk_fresh();} + smt_params &fparams3() {return m_contexts3.fparams();} + + + + void collect_statistics(statistics& st) const + { + m_contexts.collect_statistics(st); + m_contexts2.collect_statistics(st); + m_contexts3.collect_statistics(st); + } + + void reset_statistics() + { + m_contexts.reset_statistics(); + m_contexts2.reset_statistics(); + m_contexts3.reset_statistics(); + } +}; + +app* mk_zk_const (ast_manager &m, unsigned idx, sort *s); +void find_zk_const(expr* e, app_ref_vector &out); +bool has_zk_const(expr* e); +} + +#endif diff --git a/src/muz/spacer/spacer_marshal.cpp b/src/muz/spacer/spacer_marshal.cpp new file mode 100644 index 000000000..fce0d6a34 --- /dev/null +++ b/src/muz/spacer/spacer_marshal.cpp @@ -0,0 +1,55 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel +Module Name: + + spacer_marshal.cpp + +Abstract: + + marshaling and unmarshaling of expressions + + --*/ +#include "spacer_marshal.h" + +#include +#include "cmd_context.h" +#include "smt2parser.h" +#include "vector.h" +#include "ast_smt_pp.h" +#include "ast_pp.h" + +namespace spacer { +std::ostream &marshal(std::ostream &os, expr_ref e, ast_manager &m) +{ + ast_smt_pp pp(m); + pp.display_smt2(os, e); + return os; +} + +std::string marshal(expr_ref e, ast_manager &m) +{ + std::stringstream ss; + marshal(ss, e, m); + return ss.str(); +} + + +expr_ref unmarshal(std::istream &is, ast_manager &m) +{ + cmd_context ctx(false, &m); + ctx.set_ignore_check(true); + if (!parse_smt2_commands(ctx, is)) { return expr_ref(0, m); } + + ptr_vector::const_iterator it = ctx.begin_assertions(); + ptr_vector::const_iterator end = ctx.end_assertions(); + if (it == end) { return expr_ref(m.mk_true(), m); } + unsigned size = static_cast(end - it); + return expr_ref(m.mk_and(size, it), m); +} + +expr_ref unmarshal(std::string s, ast_manager &m) +{ + std::istringstream is(s); + return unmarshal(is, m); +} +} diff --git a/src/muz/spacer/spacer_marshal.h b/src/muz/spacer/spacer_marshal.h new file mode 100644 index 000000000..e4c59628f --- /dev/null +++ b/src/muz/spacer/spacer_marshal.h @@ -0,0 +1,29 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel +Module Name: + + spacer_marshal.h + +Abstract: + + marshaling and unmarshaling of expressions + + --*/ +#ifndef _SPACER_MARSHAL_H_ +#define _SPACER_MARSHAL_H_ + +#include +#include "ast.h" +#include + +namespace spacer { +std::ostream &marshal(std::ostream &os, expr_ref e, ast_manager &m); +std::string marshal(expr_ref e, ast_manager &m); +expr_ref unmarshal(std::string s, ast_manager &m); +expr_ref unmarshal(std::istream &is, ast_manager &m); + + +} + + +#endif diff --git a/src/muz/spacer/spacer_matrix.cpp b/src/muz/spacer/spacer_matrix.cpp new file mode 100644 index 000000000..b7d03d453 --- /dev/null +++ b/src/muz/spacer/spacer_matrix.cpp @@ -0,0 +1,159 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_matrix.cpp + +Abstract: + a matrix + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#include "spacer_matrix.h" + +namespace spacer +{ + spacer_matrix::spacer_matrix(unsigned m, unsigned n) : m_num_rows(m), m_num_cols(n) + { + for (unsigned i=0; i < m; ++i) + { + vector v; + for (unsigned j=0; j < n; ++j) + { + v.push_back(rational(0)); + } + m_matrix.push_back(v); + } + } + + unsigned spacer_matrix::num_rows() + { + return m_num_rows; + } + + unsigned spacer_matrix::num_cols() + { + return m_num_cols; + } + + rational spacer_matrix::get(unsigned int i, unsigned int j) + { + SASSERT(i < m_num_rows); + SASSERT(j < m_num_cols); + + return m_matrix[i][j]; + } + + void spacer_matrix::set(unsigned int i, unsigned int j, rational v) + { + SASSERT(i < m_num_rows); + SASSERT(j < m_num_cols); + + m_matrix[i][j] = v; + } + + unsigned spacer_matrix::perform_gaussian_elimination() + { + unsigned i=0; + unsigned j=0; + while(i < m_matrix.size() && j < m_matrix[0].size()) + { + // find maximal element in column with row index bigger or equal i + rational max = m_matrix[i][j]; + unsigned max_index = i; + + for (unsigned k=i+1; k < m_matrix.size(); ++k) + { + if (max < m_matrix[k][j]) + { + max = m_matrix[k][j]; + max_index = k; + } + } + + if (max.is_zero()) // skip this column + { + ++j; + } + else + { + // reorder rows if necessary + vector tmp = m_matrix[i]; + m_matrix[i] = m_matrix[max_index]; + m_matrix[max_index] = m_matrix[i]; + + // normalize row + rational pivot = m_matrix[i][j]; + if (!pivot.is_one()) + { + for (unsigned k=0; k < m_matrix[i].size(); ++k) + { + m_matrix[i][k] = m_matrix[i][k] / pivot; + } + } + + // subtract row from all other rows + for (unsigned k=1; k < m_matrix.size(); ++k) + { + if (k != i) + { + rational factor = m_matrix[k][j]; + for (unsigned l=0; l < m_matrix[k].size(); ++l) + { + m_matrix[k][l] = m_matrix[k][l] - (factor * m_matrix[i][l]); + } + } + } + + ++i; + ++j; + } + } + + if (get_verbosity_level() >= 1) + { + SASSERT(m_matrix.size() > 0); + } + + return i; //i points to the row after the last row which is non-zero + } + + void spacer_matrix::print_matrix() + { + verbose_stream() << "\nMatrix\n"; + for (const auto& row : m_matrix) + { + for (const auto& element : row) + { + verbose_stream() << element << ", "; + } + verbose_stream() << "\n"; + } + verbose_stream() << "\n"; + } + void spacer_matrix::normalize() + { + rational den = rational::one(); + for (unsigned i=0; i < m_num_rows; ++i) + { + for (unsigned j=0; j < m_num_cols; ++j) + { + den = lcm(den, denominator(m_matrix[i][j])); + } + } + for (unsigned i=0; i < m_num_rows; ++i) + { + for (unsigned j=0; j < m_num_cols; ++j) + { + m_matrix[i][j] = den * m_matrix[i][j]; + SASSERT(m_matrix[i][j].is_int()); + } + } + } +} diff --git a/src/muz/spacer/spacer_matrix.h b/src/muz/spacer/spacer_matrix.h new file mode 100644 index 000000000..def194793 --- /dev/null +++ b/src/muz/spacer/spacer_matrix.h @@ -0,0 +1,46 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_matrix.h + +Abstract: + a matrix + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#ifndef _SPACER_MATRIX_H_ +#define _SPACER_MATRIX_H_ + +#include "ast.h" + +namespace spacer { + + class spacer_matrix { + public: + spacer_matrix(unsigned m, unsigned n); // m rows, n colums + + unsigned num_rows(); + unsigned num_cols(); + + rational get(unsigned i, unsigned j); + void set(unsigned i, unsigned j, rational v); + + unsigned perform_gaussian_elimination(); + + void print_matrix(); + void normalize(); + private: + unsigned m_num_rows; + unsigned m_num_cols; + vector> m_matrix; + }; +} + +#endif diff --git a/src/muz/spacer/spacer_mev_array.cpp b/src/muz/spacer/spacer_mev_array.cpp new file mode 100644 index 000000000..7a69eeab5 --- /dev/null +++ b/src/muz/spacer/spacer_mev_array.cpp @@ -0,0 +1,217 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + model_mev_array.cpp + +Abstract: + + Evaluate array expressions in a given model. + +Author: + +Revision History: + +--*/ +#include"model.h" +#include"model_evaluator_params.hpp" +#include"rewriter_types.h" +#include"model_evaluator.h" +#include"spacer_mev_array.h" +#include"bool_rewriter.h" +#include"arith_rewriter.h" +#include"bv_rewriter.h" +#include"datatype_rewriter.h" +#include"array_rewriter.h" +#include"rewriter_def.h" +#include"cooperate.h" +#include"ast_pp.h" +#include"func_interp.h" + + + +// model_evaluator_array_util + + +void model_evaluator_array_util::eval_exprs(model& mdl, expr_ref_vector& es) { + for (unsigned j = 0; j < es.size(); ++j) { + if (m_array.is_as_array(es.get (j))) { + expr_ref r (m); + eval(mdl, es.get (j), r); + es.set (j, r); + } + } +} + +bool model_evaluator_array_util::extract_array_func_interp(model& mdl, expr* a, vector& stores, expr_ref& else_case) { + SASSERT(m_array.is_array(a)); + + TRACE("model_evaluator", tout << mk_pp(a, m) << "\n";); + while (m_array.is_store(a)) { + expr_ref_vector store(m); + store.append(to_app(a)->get_num_args()-1, to_app(a)->get_args()+1); + eval_exprs(mdl, store); + stores.push_back(store); + a = to_app(a)->get_arg(0); + } + + if (m_array.is_const(a)) { + else_case = to_app(a)->get_arg(0); + return true; + } + + while (m_array.is_as_array(a)) { + func_decl* f = m_array.get_as_array_func_decl(to_app(a)); + func_interp* g = mdl.get_func_interp(f); + unsigned sz = g->num_entries(); + unsigned arity = f->get_arity(); + for (unsigned i = 0; i < sz; ++i) { + expr_ref_vector store(m); + func_entry const* fe = g->get_entry(i); + store.append(arity, fe->get_args()); + store.push_back(fe->get_result()); + for (unsigned j = 0; j < store.size(); ++j) { + if (!is_ground(store[j].get())) { + TRACE("model_evaluator", tout << "could not extract array interpretation: " << mk_pp(a, m) << "\n" << mk_pp(store[j].get(), m) << "\n";); + return false; + } + } + eval_exprs(mdl, store); + stores.push_back(store); + } + else_case = g->get_else(); + if (!else_case) { + TRACE("model_evaluator", tout << "no else case " << mk_pp(a, m) << "\n";); + return false; + } + if (!is_ground(else_case)) { + TRACE("model_evaluator", tout << "non-ground else case " << mk_pp(a, m) << "\n" << mk_pp(else_case, m) << "\n";); + return false; + } + if (m_array.is_as_array(else_case)) { + expr_ref r (m); + eval(mdl, else_case, r); + else_case = r; + } + TRACE("model_evaluator", tout << "else case: " << mk_pp(else_case, m) << "\n";); + return true; + } + TRACE("model_evaluator", tout << "no translation: " << mk_pp(a, m) << "\n";); + + return false; +} + +void model_evaluator_array_util::eval_array_eq(model& mdl, app* e, expr* arg1, expr* arg2, expr_ref& res) { + TRACE("model_evaluator", tout << "array equality: " << mk_pp(e, m) << "\n";); + expr_ref v1(m), v2(m); + eval (mdl, arg1, v1); + eval (mdl, arg2, v2); + if (v1 == v2) { + res = m.mk_true (); + return; + } + sort* s = m.get_sort(arg1); + sort* r = get_array_range(s); + // give up evaluating finite domain/range arrays + if (!r->is_infinite() && !r->is_very_big() && !s->is_infinite() && !s->is_very_big()) { + TRACE("model_evaluator", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + res.reset (); + return; + } + vector store; + expr_ref else1(m), else2(m); + if (!extract_array_func_interp(mdl, v1, store, else1) || + !extract_array_func_interp(mdl, v2, store, else2)) { + TRACE("model_evaluator", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + res.reset (); + return; + } + + if (else1 != else2) { + if (m.is_value(else1) && m.is_value(else2)) { + TRACE("model_evaluator", tout + << "defaults are different: " << mk_pp(e, m) << " " + << mk_pp(else1, m) << " " << mk_pp(else2, m) << "\n";); + res = m.mk_false (); + } + else if (m_array.is_array(else1)) { + eval_array_eq(mdl, e, else1, else2, res); + } + else { + TRACE("model_evaluator", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + res.reset (); + } + return; + } + + expr_ref s1(m), s2(m), w1(m), w2(m); + expr_ref_vector args1(m), args2(m); + args1.push_back(v1); + args2.push_back(v2); + for (unsigned i = 0; i < store.size(); ++i) { + args1.resize(1); + args2.resize(1); + args1.append(store[i].size()-1, store[i].c_ptr()); + args2.append(store[i].size()-1, store[i].c_ptr()); + s1 = m_array.mk_select(args1.size(), args1.c_ptr()); + s2 = m_array.mk_select(args2.size(), args2.c_ptr()); + eval (mdl, s1, w1); + eval (mdl, s2, w2); + if (w1 == w2) { + continue; + } + if (m.is_value(w1) && m.is_value(w2)) { + TRACE("model_evaluator", tout << "Equality evaluation: " << mk_pp(e, m) << "\n"; + tout << mk_pp(s1, m) << " |-> " << mk_pp(w1, m) << "\n"; + tout << mk_pp(s2, m) << " |-> " << mk_pp(w2, m) << "\n";); + res = m.mk_false (); + } + else if (m_array.is_array(w1)) { + eval_array_eq(mdl, e, w1, w2, res); + if (m.is_true (res)) { + continue; + } + } + else { + TRACE("model_evaluator", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + res.reset (); + } + return; + } + res = m.mk_true (); +} + +void model_evaluator_array_util::eval(model& mdl, expr* e, expr_ref& r, bool model_completion) { + model_evaluator mev (mdl); + mev.set_model_completion (model_completion); + bool eval_result = true; + try { + mev (e, r); + } + catch (model_evaluator_exception &) { + eval_result = false; + } + VERIFY(eval_result); + + if (m_array.is_array(e)) { + vector stores; + expr_ref_vector args(m); + expr_ref else_case(m); + if (extract_array_func_interp(mdl, r, stores, else_case)) { + r = m_array.mk_const_array(m.get_sort(e), else_case); + while (!stores.empty() && stores.back().back() == else_case) { + stores.pop_back(); + } + for (unsigned i = stores.size(); i > 0; ) { + --i; + args.resize(1); + args[0] = r; + args.append(stores[i]); + r = m_array.mk_store(args.size(), args.c_ptr()); + } + return; + } + } + return; +} diff --git a/src/muz/spacer/spacer_mev_array.h b/src/muz/spacer/spacer_mev_array.h new file mode 100644 index 000000000..d7904d677 --- /dev/null +++ b/src/muz/spacer/spacer_mev_array.h @@ -0,0 +1,52 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_mev_array.h + +Abstract: + + Utilities to evaluate arrays in the model. + +Author: + based on model_evaluator in muz/pdr/pdr_util.h + +Revision History: + +--*/ +#ifndef _SPACER_MEV_ARRAY_H_ +#define _SPACER_MEV_ARRAY_H_ + +#include"ast.h" +#include"rewriter_types.h" +#include"params.h" +#include "array_decl_plugin.h" + +/** + * based on model_evaluator in muz/pdr/pdr_util.h + */ +class model_evaluator_array_util { + ast_manager& m; + array_util m_array; + + void eval_exprs(model& mdl, expr_ref_vector& es); + + bool extract_array_func_interp(model& mdl, expr* a, vector& stores, expr_ref& else_case); + +public: + + model_evaluator_array_util (ast_manager& m): + m (m), + m_array (m) + {} + + /** + * best effort evaluator of extensional array equality. + */ + void eval_array_eq(model& mdl, app* e, expr* arg1, expr* arg2, expr_ref& res); + + void eval(model& mdl, expr* e, expr_ref& r, bool model_completion = true); +}; + +#endif diff --git a/src/muz/spacer/spacer_min_cut.cpp b/src/muz/spacer/spacer_min_cut.cpp new file mode 100644 index 000000000..c56ddbd66 --- /dev/null +++ b/src/muz/spacer/spacer_min_cut.cpp @@ -0,0 +1,289 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_min_cut.cpp + +Abstract: + min cut solver + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#include "spacer_min_cut.h" + +namespace spacer { + + spacer_min_cut::spacer_min_cut() + { + m_n = 2; + + // push back two empty vectors for source and sink + m_edges.push_back(vector>()); + m_edges.push_back(vector>()); + } + + unsigned spacer_min_cut::new_node() + { + return m_n++; + } + + void spacer_min_cut::add_edge(unsigned int i, unsigned int j, unsigned int capacity) + { + if (i >= m_edges.size()) + { + m_edges.resize(i + 1); + } + m_edges[i].insert(std::make_pair(j, 1)); + STRACE("spacer.mincut", + verbose_stream() << "adding edge (" << i << "," << j << ")\n"; + ); + + } + + void spacer_min_cut::compute_min_cut(vector& cut_nodes) + { + if (m_n == 2) + { + return; + } + + m_d.resize(m_n); + m_pred.resize(m_n); + + // compute initial distances and number of nodes + compute_initial_distances(); + + unsigned i = 0; + + while (m_d[0] < m_n) + { + unsigned j = get_admissible_edge(i); + + if (j < m_n) + { + // advance(i) + m_pred[j] = i; + i = j; + + // if i is the sink, augment path + if (i == 1) + { + augment_path(); + i = 0; + } + } + else + { + // retreat + compute_distance(i); + if (i != 0) + { + i = m_pred[i]; + } + } + } + + // split nodes into reachable and unreachable ones + vector reachable(m_n); + compute_reachable_nodes(reachable); + + // find all edges between reachable and unreachable nodes and for each such edge, add corresponding lemma to unsat-core + compute_cut_and_add_lemmas(reachable, cut_nodes); + } + + void spacer_min_cut::compute_initial_distances() + { + vector todo; + vector visited(m_n); + + todo.push_back(0); // start at the source, since we do postorder traversel + + while (!todo.empty()) + { + unsigned current = todo.back(); + + // if we haven't already visited current + if (!visited[current]) { + bool existsUnvisitedParent = false; + + // add unprocessed parents to stack for DFS. If there is at least one unprocessed parent, don't compute the result + // for current now, but wait until those unprocessed parents are processed. + for (unsigned i = 0, sz = m_edges[current].size(); i < sz; ++i) + { + unsigned parent = m_edges[current][i].first; + + // if we haven't visited the current parent yet + if(!visited[parent]) + { + // add it to the stack + todo.push_back(parent); + existsUnvisitedParent = true; + } + } + + // if we already visited all parents, we can visit current too + if (!existsUnvisitedParent) { + visited[current] = true; + todo.pop_back(); + + compute_distance(current); // I.H. all parent distances are already computed + } + } + else { + todo.pop_back(); + } + } + } + + unsigned spacer_min_cut::get_admissible_edge(unsigned i) + { + for (const auto& pair : m_edges[i]) + { + if (pair.second > 0 && m_d[i] == m_d[pair.first] + 1) + { + return pair.first; + } + } + return m_n; // no element found + } + + void spacer_min_cut::augment_path() + { + // find bottleneck capacity + unsigned max = std::numeric_limits::max(); + unsigned k = 1; + while (k != 0) + { + unsigned l = m_pred[k]; + for (const auto& pair : m_edges[l]) + { + if (pair.first == k) + { + if (max > pair.second) + { + max = pair.second; + } + } + } + k = l; + } + + k = 1; + while (k != 0) + { + unsigned l = m_pred[k]; + + // decrease capacity + for (auto& pair : m_edges[l]) + { + if (pair.first == k) + { + pair.second -= max; + } + } + // increase reverse flow + bool already_exists = false; + for (auto& pair : m_edges[k]) + { + if (pair.first == l) + { + already_exists = true; + pair.second += max; + } + } + if (!already_exists) + { + m_edges[k].insert(std::make_pair(l, max)); + } + k = l; + } + } + + void spacer_min_cut::compute_distance(unsigned i) + { + if (i == 1) // sink node + { + m_d[1] = 0; + } + else + { + unsigned min = std::numeric_limits::max(); + + // find edge (i,j) with positive residual capacity and smallest distance + for (const auto& pair : m_edges[i]) + { + if (pair.second > 0) + { + unsigned tmp = m_d[pair.first] + 1; + if (tmp < min) + { + min = tmp; + } + } + } + m_d[i] = min; + } + } + + void spacer_min_cut::compute_reachable_nodes(vector& reachable) + { + vector todo; + + todo.push_back(0); + while (!todo.empty()) + { + unsigned current = todo.back(); + todo.pop_back(); + + if (!reachable[current]) + { + reachable[current] = true; + + for (const auto& pair : m_edges[current]) + { + if (pair.second > 0) + { + todo.push_back(pair.first); + } + } + } + } + } + + void spacer_min_cut::compute_cut_and_add_lemmas(vector& reachable, vector& cut_nodes) + { + vector todo; + vector visited(m_n); + + todo.push_back(0); + while (!todo.empty()) + { + unsigned current = todo.back(); + todo.pop_back(); + + if (!visited[current]) + { + visited[current] = true; + + for (const auto& pair : m_edges[current]) + { + unsigned successor = pair.first; + if (reachable[successor]) + { + todo.push_back(successor); + } + else + { + cut_nodes.push_back(successor); + } + } + } + } + } +} diff --git a/src/muz/spacer/spacer_min_cut.h b/src/muz/spacer/spacer_min_cut.h new file mode 100644 index 000000000..ae285b9bb --- /dev/null +++ b/src/muz/spacer/spacer_min_cut.h @@ -0,0 +1,52 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_min_cut.h + +Abstract: + min cut solver + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ + +#ifndef _SPACER_MIN_CUT_H_ +#define _SPACER_MIN_CUT_H_ + +#include "ast.h" + +namespace spacer { + + class spacer_min_cut { + public: + spacer_min_cut(); + + unsigned new_node(); + void add_edge(unsigned i, unsigned j, unsigned capacity); + void compute_min_cut(vector& cut_nodes); + + private: + + unsigned m_n; // number of vertices in the graph + + vector > > m_edges; // map from node to all outgoing edges together with their weights (also contains "reverse edges") + vector m_d; // approximation of distance from node to sink in residual graph + vector m_pred; // predecessor-information for reconstruction of augmenting path + vector m_node_to_formula; // maps each node to the corresponding formula in the original proof + + void compute_initial_distances(); + unsigned get_admissible_edge(unsigned i); + void augment_path(); + void compute_distance(unsigned i); + void compute_reachable_nodes(vector& reachable); + void compute_cut_and_add_lemmas(vector& reachable, vector& cut_nodes); + }; +} + +#endif diff --git a/src/muz/spacer/spacer_notes.txt b/src/muz/spacer/spacer_notes.txt new file mode 100644 index 000000000..4211bc1ce --- /dev/null +++ b/src/muz/spacer/spacer_notes.txt @@ -0,0 +1,231 @@ +a queue contains a model_node + +let n = leaves.pop_top () + +if (!n.has_derivation ()) + + if n.pt ().must_reach (n.post ()) + add parent of n to the leaves + return + + check abstract reachability of n + + if must reachable then + create new reachability fact for n.pt () + add parent of n to the leaves + else if may reachable then + create derivation d for n + create model_node kid for the top of d + add kid to the leaves + + else /* unreachable */ + create a lemma for n.pt () + p = parent of n + p.reset_derivation() + add p to the leaves + +else if (n.has_derivation ()) + + create next model_node kid for n.get_derivation () + + if (kid != NULL) + add kid to leaves + else /* done with the derivation, no more kids */ + // the derivation is reachable, otherwise it was reset in another branch + p = parent of n + p.reset_derivation () + add p to the leaves + + +================================================================================= +create derivation for the top of d +input: + model M, + transition relation formula trans with auxiliary variables quantified out + sequence of pedicates P_i, + may and must summaries of P_i +================================================================================= + +create first derivation child: + input: model + + +create next derivation child: + create new model + update trans by computing pre-image over new reachability facts + call create next derivation child + +private: +create next derivation child using a given model, and starting index + +========================================================= + +create a next model for a derivation + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +// an obligation +model_node + // NULL means root + model_node_ref parent + model_node_ref_vector kids + + pred_transformer &predicate + expr* condition + unsigned level + unsigned depth + // monotonically increasing + unsigned id + + bool open; + + +model_node::close () + open = false + for k : kids do k.close () + +model_search + + model_node_ref root; + + // proof obligations + priority_queue m_obligations; + model_node_ref m_last_reachable; + + +bool model_node::operator< (model_node& other) + lexicographic order based on + level<, depth<, id> + + + +assert (!m_last_reachable); +while (!m_obligations.empty ()) +{ + // propagate reachability as much as possible + while (m_last_reachable) + { + obl = m_last_reachable + m_last_reachable.reset (); + if (is_root (obl)) return true; + if (discharge_obligation (obl.get_parent ()) == l_true) + m_last_reachable = obl.get_parent (); + } + + // at least one obligation is not closed, ow root was reachable + while (m_obligations.top ().is_closed ()) m_obligations.pop (); + assert (!m_obligations.empty ()); + + // process an obligation + assert (!m_last_reachable) + obl = m_obligations.top (); + switch (discharge_obligation (obl)) + { + case l_true: + // if reachable, schedule a reachability round + m_last_reachable = m_obligations.top (); + m_obligations.pop (); + break; + case l_false: + // if unreachable removed from the queue + m_obligations.pop (); + /// bump level + obl.inc_level (); + /// optionally insert back into the queue + if (is_active (obl)) m_obligations.push (obl); + break; + default: + assert (m_obligations.top () != obl); + } +} +return false + +/// with priority queue +bool is_active (model_node obl) { return level <= m_search.max_level (); } +/// with out priority queue. Discharged obligations are dropped +bool is_active (model_node obl) { return false; } + +discharge_obligation (model_node obl) +{ + assert (!obl.is_closed ()); + switch (check_reachability (obl)) + { + case l_true: + obl.close () + update reachability facts + return l_true; + case l_false: + update lemmas + return l_false + case l_unknown: + create children + populate m_obligations queue + return l_unknown + } +} + + +============================================================= + +a node keeps a derivation object + +if a node is sat, a new node is constructed and inherits the derivation object +if a node is sat and the derivation is done, this is reported to the parent + +expand_node(n): + process node ignoring derivation + if sat: + if concrete: + if has derivation and has next child + close current node and push new node + return l_undef + else + return l_true + else + create_child (creates a new node and optionally sets derivation) + else if unsat + generate lemmas + derivation remains unchanged to be used at a higher level + return +====================================================================== +1. open disjunction for transition relation + - a fresh literal to open the disjunction of the transition relation + - expr* expand_init (expr *e) -- add e to initial state and return + new disj var + - close the disjunction by passing the negation of the literal + during various calls + - store the literal negated to have access to both positive and + negative versions + - with this, can do an optional check whether the lemmas alone are + strong enough to discharge the counterexample. Easiest is to + implement it as a separate pre-check. + +2. auxiliary variables in lemmas and reach-facts. + - store and expect auxiliary variables + - quantify them out when necessary + +3. initial rules as reach-facts + - add initial rules of a predicate to its reach-facts. Propagate them to uses. + - this way, the checks at level 0 will include initial rules of + immediate predecessors +====================================================================== + +reach_fact_ref_vector m_reach_facts +app_ref_vector m_reach_case_vars + +bool is_must_reachable (expr *state, model_ref *model) +reach_fact* get_used_reach_fact (model_evaluator &mev) +app* mk_fresh_reach_case_var () +expr* get_reach () +expr* get_last_reach_case_var () +app* get_reach_case_var (unsigned idx) + +get_used_origin_reach_fact(): + + +====================================================================== +4. track relationship between an obligation and lemmas. Attempt to + generalize an obligation into the exact lemma that worked + before. Perhaps pick one lemma with highest level? Implement as + core-generalizer. Will require reworking how legacy_frames is implemented. diff --git a/src/muz/spacer/spacer_proof_utils.cpp b/src/muz/spacer/spacer_proof_utils.cpp new file mode 100644 index 000000000..ff020dee4 --- /dev/null +++ b/src/muz/spacer/spacer_proof_utils.cpp @@ -0,0 +1,332 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_proof_utils.cpp + +Abstract: + Utilities to traverse and manipulate proofs + +Author: + Bernhard Gleiss + Arie Gurfinkel + +Revision History: + +--*/ + +#include "spacer_proof_utils.h" +#include "ast_util.h" +#include "ast_pp.h" + +#include "proof_checker.h" + +namespace spacer { + +ProofIteratorPostOrder::ProofIteratorPostOrder(proof* root, ast_manager& manager) : m(manager) +{m_todo.push_back(root);} + +bool ProofIteratorPostOrder::hasNext() +{return !m_todo.empty();} + +/* + * iterative post-order depth-first search (DFS) through the proof DAG + */ +proof* ProofIteratorPostOrder::next() +{ + while (!m_todo.empty()) { + proof* currentNode = m_todo.back(); + + // if we haven't already visited the current unit + if (!m_visited.is_marked(currentNode)) { + bool existsUnvisitedParent = false; + + // add unprocessed premises to stack for DFS. If there is at least one unprocessed premise, don't compute the result + // for currentProof now, but wait until those unprocessed premises are processed. + for (unsigned i = 0; i < m.get_num_parents(currentNode); ++i) { + SASSERT(m.is_proof(currentNode->get_arg(i))); + proof* premise = to_app(currentNode->get_arg(i)); + + // if we haven't visited the current premise yet + if (!m_visited.is_marked(premise)) { + // add it to the stack + m_todo.push_back(premise); + existsUnvisitedParent = true; + } + } + + // if we already visited all parent-inferences, we can visit the inference too + if (!existsUnvisitedParent) { + m_visited.mark(currentNode, true); + m_todo.pop_back(); + return currentNode; + } + } else { + m_todo.pop_back(); + } + } + // we have already iterated through all inferences + return NULL; +} + + +class reduce_hypotheses { + ast_manager &m; + // tracking all created expressions + expr_ref_vector m_pinned; + + // cache for the transformation + obj_map m_cache; + + // map from unit literals to their hypotheses-free derivations + obj_map m_units; + + // -- all hypotheses in the the proof + obj_hashtable m_hyps; + + // marks hypothetical proofs + ast_mark m_hypmark; + + + // stack + ptr_vector m_todo; + + void reset() + { + m_cache.reset(); + m_units.reset(); + m_hyps.reset(); + m_hypmark.reset(); + m_pinned.reset(); + } + + bool compute_mark1(proof *pr) + { + bool hyp_mark = false; + // lemmas clear all hypotheses + if (!m.is_lemma(pr)) { + for (unsigned i = 0, sz = m.get_num_parents(pr); i < sz; ++i) { + if (m_hypmark.is_marked(m.get_parent(pr, i))) { + hyp_mark = true; + break; + } + } + } + m_hypmark.mark(pr, hyp_mark); + return hyp_mark; + } + + void compute_marks(proof* pr) + { + proof *p; + ProofIteratorPostOrder pit(pr, m); + while (pit.hasNext()) { + p = pit.next(); + if (m.is_hypothesis(p)) { + m_hypmark.mark(p, true); + m_hyps.insert(m.get_fact(p)); + } else { + bool hyp_mark = compute_mark1(p); + // collect units that are hyp-free and are used as hypotheses somewhere + if (!hyp_mark && m.has_fact(p) && m_hyps.contains(m.get_fact(p))) + { m_units.insert(m.get_fact(p), p); } + } + } + } + void find_units(proof *pr) + { + // optional. not implemented yet. + } + + void reduce(proof* pf, proof_ref &out) + { + proof *res = NULL; + + m_todo.reset(); + m_todo.push_back(pf); + ptr_buffer args; + bool dirty = false; + + while (!m_todo.empty()) { + proof *p, *tmp, *pp; + unsigned todo_sz; + + p = m_todo.back(); + if (m_cache.find(p, tmp)) { + res = tmp; + m_todo.pop_back(); + continue; + } + + dirty = false; + args.reset(); + todo_sz = m_todo.size(); + for (unsigned i = 0, sz = m.get_num_parents(p); i < sz; ++i) { + pp = m.get_parent(p, i); + if (m_cache.find(pp, tmp)) { + args.push_back(tmp); + dirty = dirty || pp != tmp; + } else { + m_todo.push_back(pp); + } + } + + if (todo_sz < m_todo.size()) { continue; } + else { m_todo.pop_back(); } + + if (m.is_hypothesis(p)) { + // hyp: replace by a corresponding unit + if (m_units.find(m.get_fact(p), tmp)) { + res = tmp; + } else { res = p; } + } + + else if (!dirty) { res = p; } + + else if (m.is_lemma(p)) { + //lemma: reduce the premise; remove reduced consequences from conclusion + SASSERT(args.size() == 1); + res = mk_lemma_core(args.get(0), m.get_fact(p)); + compute_mark1(res); + } else if (m.is_unit_resolution(p)) { + // unit: reduce untis; reduce the first premise; rebuild unit resolution + res = mk_unit_resolution_core(args.size(), args.c_ptr()); + compute_mark1(res); + } else { + // other: reduce all premises; reapply + if (m.has_fact(p)) { args.push_back(to_app(m.get_fact(p))); } + SASSERT(p->get_decl()->get_arity() == args.size()); + res = m.mk_app(p->get_decl(), args.size(), (expr * const*)args.c_ptr()); + m_pinned.push_back(res); + compute_mark1(res); + } + + SASSERT(res); + m_cache.insert(p, res); + + if (m.has_fact(res) && m.is_false(m.get_fact(res))) { break; } + } + + out = res; + } + + // returns true if (hypothesis (not a)) would be reduced + bool is_reduced(expr *a) + { + expr_ref e(m); + if (m.is_not(a)) { e = to_app(a)->get_arg(0); } + else { e = m.mk_not(a); } + + return m_units.contains(e); + } + proof *mk_lemma_core(proof *pf, expr *fact) + { + ptr_buffer args; + expr_ref lemma(m); + + if (m.is_or(fact)) { + for (unsigned i = 0, sz = to_app(fact)->get_num_args(); i < sz; ++i) { + expr *a = to_app(fact)->get_arg(i); + if (!is_reduced(a)) + { args.push_back(a); } + } + } else if (!is_reduced(fact)) + { args.push_back(fact); } + + + if (args.size() == 0) { return pf; } + else if (args.size() == 1) { + lemma = args.get(0); + } else { + lemma = m.mk_or(args.size(), args.c_ptr()); + } + proof* res = m.mk_lemma(pf, lemma); + m_pinned.push_back(res); + + if (m_hyps.contains(lemma)) + { m_units.insert(lemma, res); } + return res; + } + + proof *mk_unit_resolution_core(unsigned num_args, proof* const *args) + { + + ptr_buffer pf_args; + pf_args.push_back(args [0]); + + app *cls_fact = to_app(m.get_fact(args[0])); + ptr_buffer cls; + if (m.is_or(cls_fact)) { + for (unsigned i = 0, sz = cls_fact->get_num_args(); i < sz; ++i) + { cls.push_back(cls_fact->get_arg(i)); } + } else { cls.push_back(cls_fact); } + + // construct new resovent + ptr_buffer new_fact_cls; + bool found; + // XXX quadratic + for (unsigned i = 0, sz = cls.size(); i < sz; ++i) { + found = false; + for (unsigned j = 1; j < num_args; ++j) { + if (m.is_complement(cls.get(i), m.get_fact(args [j]))) { + found = true; + pf_args.push_back(args [j]); + break; + } + } + if (!found) { + new_fact_cls.push_back(cls.get(i)); + } + } + + SASSERT(new_fact_cls.size() + pf_args.size() - 1 == cls.size()); + expr_ref new_fact(m); + new_fact = mk_or(m, new_fact_cls.size(), new_fact_cls.c_ptr()); + + // create new proof step + proof *res = m.mk_unit_resolution(pf_args.size(), pf_args.c_ptr(), new_fact); + m_pinned.push_back(res); + return res; + } + + // reduce all units, if any unit reduces to false return true and put its proof into out + bool reduce_units(proof_ref &out) + { + proof_ref res(m); + for (auto entry : m_units) { + reduce(entry.get_value(), res); + if (m.is_false(m.get_fact(res))) { + out = res; + return true; + } + res.reset(); + } + return false; + } + + +public: + reduce_hypotheses(ast_manager &m) : m(m), m_pinned(m) {} + + + void operator()(proof_ref &pr) + { + compute_marks(pr); + if (!reduce_units(pr)) { + reduce(pr.get(), pr); + } + reset(); + } +}; +void reduce_hypotheses(proof_ref &pr) +{ + ast_manager &m = pr.get_manager(); + class reduce_hypotheses hypred(m); + hypred(pr); + DEBUG_CODE(proof_checker pc(m); + expr_ref_vector side(m); + SASSERT(pc.check(pr, side)); + ); +} +} diff --git a/src/muz/spacer/spacer_proof_utils.h b/src/muz/spacer/spacer_proof_utils.h new file mode 100644 index 000000000..7973c673b --- /dev/null +++ b/src/muz/spacer/spacer_proof_utils.h @@ -0,0 +1,43 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_proof_utils.cpp + +Abstract: + Utilities to traverse and manipulate proofs + +Author: + Bernhard Gleiss + Arie Gurfinkel + +Revision History: + +--*/ + +#ifndef _SPACER_PROOF_UTILS_H_ +#define _SPACER_PROOF_UTILS_H_ +#include "ast.h" + +namespace spacer { +/* + * iterator, which traverses the proof in depth-first post-order. + */ +class ProofIteratorPostOrder { +public: + ProofIteratorPostOrder(proof* refutation, ast_manager& manager); + bool hasNext(); + proof* next(); + +private: + ptr_vector m_todo; + ast_mark m_visited; // the proof nodes we have already visited + + ast_manager& m; +}; + + +void reduce_hypotheses(proof_ref &pr); +} +#endif diff --git a/src/muz/spacer/spacer_prop_solver.cpp b/src/muz/spacer/spacer_prop_solver.cpp new file mode 100644 index 000000000..4f5ad86f2 --- /dev/null +++ b/src/muz/spacer/spacer_prop_solver.cpp @@ -0,0 +1,298 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_prop_solver.cpp + +Abstract: + + SAT solver abstraction for SPACER. + +Author: + + Arie Gurfinkel + Anvesh Komuravelli + +Revision History: + +--*/ + +#include +#include "model.h" +#include "spacer_util.h" +#include "spacer_prop_solver.h" +#include "ast_smt2_pp.h" +#include "dl_util.h" +#include "model_pp.h" +#include "smt_params.h" +#include "datatype_decl_plugin.h" +#include "bv_decl_plugin.h" +#include "spacer_farkas_learner.h" +#include "ast_smt2_pp.h" +#include "expr_replacer.h" +#include "fixedpoint_params.hpp" + +namespace spacer { + +prop_solver::prop_solver(manager& pm, fixedpoint_params const& p, symbol const& name) : + m(pm.get_manager()), + m_pm(pm), + m_name(name), + m_ctx(NULL), + m_pos_level_atoms(m), + m_neg_level_atoms(m), + m_core(0), + m_subset_based_core(false), + m_uses_level(infty_level()), + m_delta_level(false), + m_in_level(false), + m_use_push_bg(p.spacer_keep_proxy()) +{ + + m_solvers[0] = pm.mk_fresh(); + m_fparams[0] = &pm.fparams(); + + m_solvers[1] = pm.mk_fresh2(); + m_fparams[1] = &pm.fparams2(); + + m_contexts[0] = alloc(spacer::itp_solver, *(m_solvers[0]), p.spacer_new_unsat_core(), p.spacer_minimize_unsat_core(), p.spacer_farkas_optimized(), p.spacer_farkas_a_const(), p.spacer_split_farkas_literals()); + m_contexts[1] = alloc(spacer::itp_solver, *(m_solvers[1]), p.spacer_new_unsat_core(), p.spacer_minimize_unsat_core(), p.spacer_farkas_optimized(), p.spacer_farkas_a_const(), p.spacer_split_farkas_literals()); + + for (unsigned i = 0; i < 2; ++i) + { m_contexts[i]->assert_expr(m_pm.get_background()); } +} + +void prop_solver::add_level() +{ + unsigned idx = level_cnt(); + std::stringstream name; + name << m_name << "#level_" << idx; + func_decl * lev_pred = m.mk_fresh_func_decl(name.str().c_str(), 0, 0, m.mk_bool_sort()); + m_level_preds.push_back(lev_pred); + + app_ref pos_la(m.mk_const(lev_pred), m); + app_ref neg_la(m.mk_not(pos_la.get()), m); + + m_pos_level_atoms.push_back(pos_la); + m_neg_level_atoms.push_back(neg_la); + + m_level_atoms_set.insert(pos_la.get()); + m_level_atoms_set.insert(neg_la.get()); +} + +void prop_solver::ensure_level(unsigned lvl) +{ + while (lvl >= level_cnt()) { + add_level(); + } +} + +unsigned prop_solver::level_cnt() const +{ + return m_level_preds.size(); +} + +void prop_solver::assert_level_atoms(unsigned level) +{ + unsigned lev_cnt = level_cnt(); + for (unsigned i = 0; i < lev_cnt; i++) { + bool active = m_delta_level ? i == level : i >= level; + app * lev_atom = + active ? m_neg_level_atoms.get(i) : m_pos_level_atoms.get(i); + m_ctx->push_bg(lev_atom); + } +} + +void prop_solver::assert_expr(expr * form) +{ + SASSERT(!m_in_level); + m_contexts[0]->assert_expr(form); + m_contexts[1]->assert_expr(form); + IF_VERBOSE(21, verbose_stream() << "$ asserted " << mk_pp(form, m) << "\n";); + TRACE("spacer", tout << "add_formula: " << mk_pp(form, m) << "\n";); +} + +void prop_solver::assert_expr(expr * form, unsigned level) +{ + ensure_level(level); + app * lev_atom = m_pos_level_atoms[level].get(); + app_ref lform(m.mk_or(form, lev_atom), m); + assert_expr(lform); +} + + +/// Poor man's maxsat. No guarantees of maximum solution +/// Runs maxsat loop on m_ctx Returns l_false if hard is unsat, +/// otherwise reduces soft such that hard & soft is sat. +lbool prop_solver::maxsmt(expr_ref_vector &hard, expr_ref_vector &soft) +{ + // replace expressions by assumption literals + itp_solver::scoped_mk_proxy _p_(*m_ctx, hard); + unsigned hard_sz = hard.size(); + // assume soft constraints are propositional literals (no need to proxy) + hard.append(soft); + + lbool res = m_ctx->check_sat(hard.size(), hard.c_ptr()); + // if hard constraints alone are unsat or there are no soft + // constraints, we are done + if (res != l_false || soft.empty()) { return res; } + + // clear soft constraints, we will recompute them later + soft.reset(); + + expr_ref saved(m); + ptr_vector core; + m_ctx->get_unsat_core(core); + + // while there are soft constraints + while (hard.size() > hard_sz) { + bool found = false; + // look for a soft constraint that is in the unsat core + for (unsigned i = hard_sz, sz = hard.size(); i < sz; ++i) + if (core.contains(hard.get(i))) { + found = true; + // AG: not sure why we are saving it + saved = hard.get(i); + hard[i] = hard.back(); + hard.pop_back(); + break; + } + // if no soft constraints in the core, return this should + // not happen because it implies that hard alone is unsat + // and that is taken care of earlier + if (!found) { + hard.resize(hard_sz); + return l_false; + } + + // check that the NEW constraints became sat + res = m_ctx->check_sat(hard.size(), hard.c_ptr()); + if (res != l_false) { break; } + // still unsat, update the core and repeat + core.reset(); + m_ctx->get_unsat_core(core); + } + + // update soft with found soft constraints + if (res == l_true) { + for (unsigned i = hard_sz, sz = hard.size(); i < sz; ++i) + { soft.push_back(hard.get(i)); } + } + // revert hard back to the right size + // proxies are undone on exit via scoped_mk_proxy + hard.resize(hard_sz); + return res; +} + +lbool prop_solver::internal_check_assumptions( + expr_ref_vector& hard_atoms, + expr_ref_vector& soft_atoms) +{ + // XXX Turn model generation if m_model != 0 + SASSERT(m_ctx); + SASSERT(m_ctx_fparams); + flet _model(m_ctx_fparams->m_model, m_model != 0); + + if (m_in_level) { assert_level_atoms(m_current_level); } + lbool result = maxsmt(hard_atoms, soft_atoms); + if (result != l_false && m_model) { m_ctx->get_model(*m_model); } + + SASSERT(result != l_false || soft_atoms.empty()); + + /// compute level used in the core + // XXX this is a poor approximation because the core will get minimized further + if (result == l_false) { + ptr_vector core; + m_ctx->get_full_unsat_core(core); + unsigned core_size = core.size(); + m_uses_level = infty_level(); + + for (unsigned i = 0; i < core_size; ++i) { + if (m_level_atoms_set.contains(core[i])) { + unsigned sz = std::min(m_uses_level, m_neg_level_atoms.size()); + for (unsigned j = 0; j < sz; ++j) + if (m_neg_level_atoms [j].get() == core[i]) { + m_uses_level = j; + break; + } + SASSERT(!is_infty_level(m_uses_level)); + } + } + } + + if (result == l_false && m_core && m.proofs_enabled() && !m_subset_based_core) { + TRACE("spacer", tout << "theory core\n";); + m_core->reset(); + m_ctx->get_itp_core(*m_core); + } else if (result == l_false && m_core) { + m_core->reset(); + m_ctx->get_unsat_core(*m_core); + // manually undo proxies because maxsmt() call above manually adds proxies + m_ctx->undo_proxies(*m_core); + } + return result; +} + + + +lbool prop_solver::check_assumptions(const expr_ref_vector & _hard, + expr_ref_vector& soft, + unsigned num_bg, expr * const * bg, + unsigned solver_id) +{ + // current clients expect that flattening of HARD is + // done implicitly during check_assumptions + expr_ref_vector hard(m); + hard.append(_hard.size(), _hard.c_ptr()); + flatten_and(hard); + + m_ctx = m_contexts [solver_id == 0 ? 0 : 0 /* 1 */].get(); + m_ctx_fparams = m_fparams [solver_id == 0 ? 0 : 0 /* 1 */]; + + // can be disabled if use_push_bg == true + // solver::scoped_push _s_(*m_ctx); + if (!m_use_push_bg) { m_ctx->push(); } + itp_solver::scoped_bg _b_(*m_ctx); + + for (unsigned i = 0; i < num_bg; ++i) + if (m_use_push_bg) { m_ctx->push_bg(bg [i]); } + else { m_ctx->assert_expr(bg[i]); } + + unsigned soft_sz = soft.size(); +#pragma unused(soft_sz) + lbool res = internal_check_assumptions(hard, soft); + if (!m_use_push_bg) { m_ctx->pop(1); } + + TRACE("psolve_verbose", + tout << "sat: " << mk_pp(mk_and(hard), m) << "\n" + << mk_pp(mk_and(soft), m) << "\n"; + for (unsigned i = 0; i < num_bg; ++i) + tout << "bg" << i << ": " << mk_pp(bg[i], m) << "\n"; + tout << "res: " << res << "\n";); + CTRACE("psolve", m_core, + tout << "core is: " << mk_pp(mk_and(*m_core), m) << "\n";); + + SASSERT(soft_sz >= soft.size()); + + // -- reset all parameters + m_core = 0; + m_model = 0; + m_subset_based_core = false; + return res; +} + +void prop_solver::collect_statistics(statistics& st) const +{ + m_contexts[0]->collect_statistics(st); + m_contexts[1]->collect_statistics(st); +} + +void prop_solver::reset_statistics() +{ +} + + + + +} diff --git a/src/muz/spacer/spacer_prop_solver.h b/src/muz/spacer/spacer_prop_solver.h new file mode 100644 index 000000000..4f5df819b --- /dev/null +++ b/src/muz/spacer/spacer_prop_solver.h @@ -0,0 +1,143 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_prop_solver.h + +Abstract: + + SAT solver abstraction for SPACER. + +Author: + + Arie Gurfinkel + +Revision History: + +--*/ + +#ifndef _PROP_SOLVER_H_ +#define _PROP_SOLVER_H_ + +#include +#include +#include +#include "ast.h" +#include "obj_hashtable.h" +#include "smt_kernel.h" +#include "util.h" +#include "vector.h" +#include "spacer_manager.h" +#include "spacer_smt_context_manager.h" +#include "spacer_itp_solver.h" + +struct fixedpoint_params; + +namespace spacer { + +class prop_solver { + +private: + ast_manager& m; + manager& m_pm; + symbol m_name; + smt_params* m_fparams[2]; + solver* m_solvers[2]; + scoped_ptr m_contexts[2]; + itp_solver * m_ctx; + smt_params * m_ctx_fparams; + decl_vector m_level_preds; + app_ref_vector m_pos_level_atoms; // atoms used to identify level + app_ref_vector m_neg_level_atoms; // + obj_hashtable m_level_atoms_set; + expr_ref_vector* m_core; + model_ref* m_model; + bool m_subset_based_core; + unsigned m_uses_level; + /// if true sets the solver into a delta level, enabling only + /// atoms explicitly asserted in m_current_level + bool m_delta_level; + bool m_in_level; + bool m_use_push_bg; + unsigned m_current_level; // set when m_in_level + + void assert_level_atoms(unsigned level); + + void ensure_level(unsigned lvl); + + lbool internal_check_assumptions(expr_ref_vector &hard, + expr_ref_vector &soft); + + lbool maxsmt(expr_ref_vector &hard, expr_ref_vector &soft); + + +public: + prop_solver(spacer::manager& pm, fixedpoint_params const& p, symbol const& name); + + + void set_core(expr_ref_vector* core) { m_core = core; } + void set_model(model_ref* mdl) { m_model = mdl; } + void set_subset_based_core(bool f) { m_subset_based_core = f; } + bool assumes_level() const { return !is_infty_level(m_uses_level); } + unsigned uses_level() const {return m_uses_level;} + + + void add_level(); + unsigned level_cnt() const; + + + void assert_expr(expr * form); + void assert_expr(expr * form, unsigned level); + + /** + * check assumptions with a background formula + */ + lbool check_assumptions(const expr_ref_vector & hard, + expr_ref_vector & soft, + unsigned num_bg = 0, + expr * const *bg = NULL, + unsigned solver_id = 0); + + void collect_statistics(statistics& st) const; + void reset_statistics(); + + class scoped_level { + bool& m_lev; + public: + scoped_level(prop_solver& ps, unsigned lvl): m_lev(ps.m_in_level) + { + SASSERT(!m_lev); + m_lev = true; + ps.m_current_level = lvl; + } + ~scoped_level() { m_lev = false; } + }; + + class scoped_subset_core { + prop_solver &m_ps; + bool m_subset_based_core; + + public: + scoped_subset_core(prop_solver &ps, bool subset_core) : + m_ps(ps), m_subset_based_core(ps.m_subset_based_core) + {m_ps.set_subset_based_core(subset_core);} + + ~scoped_subset_core() + {m_ps.set_subset_based_core(m_subset_based_core);} + }; + + class scoped_delta_level : public scoped_level { + bool &m_delta; + public: + scoped_delta_level(prop_solver &ps, unsigned lvl) : + scoped_level(ps, lvl), m_delta(ps.m_delta_level) {m_delta = true;} + ~scoped_delta_level() {m_delta = false;} + }; + + +}; +} + + +#endif diff --git a/src/muz/spacer/spacer_qe_project.cpp b/src/muz/spacer/spacer_qe_project.cpp new file mode 100644 index 000000000..cfc5d6449 --- /dev/null +++ b/src/muz/spacer/spacer_qe_project.cpp @@ -0,0 +1,2333 @@ +/*++ +Copyright (c) 2010 Microsoft Corporation and Arie Gurfinkel + +Module Name: + + spacer_qe_project.cpp + +Abstract: + + Simple projection function for real arithmetic based on Loos-W. + Projection functions for arrays based on MBP + +Author: + + Nikolaj Bjorner (nbjorner) 2013-09-12 + Anvesh Komuravelli + Arie Gurfinkel + +Revision History: + + +--*/ + +#include "spacer_qe_project.h" +#include "qe_vartest.h" +#include "qe.h" +#include "arith_decl_plugin.h" +#include "ast_pp.h" +#include "th_rewriter.h" +#include "expr_functors.h" +#include "expr_substitution.h" +#include "expr_replacer.h" +#include "model_pp.h" +#include "expr_safe_replace.h" +#include "model_evaluator.h" +#include "qe_lite.h" +#include "spacer_mev_array.h" + +namespace +{ +bool is_partial_eq (app* a); + +/** + * \brief utility class for partial equalities + * + * A partial equality (a ==I b), for two arrays a,b and a finite set of indices I holds + * iff (Forall i. i \not\in I => a[i] == b[i]); in other words, it is a + * restricted form of the extensionality axiom + * + * using this class, we denote (a =I b) as f(a,b,i0,i1,...) + * where f is an uninterpreted predicate with name PARTIAL_EQ and + * I = {i0,i1,...} + */ +class peq { + ast_manager& m; + expr_ref m_lhs; + expr_ref m_rhs; + unsigned m_num_indices; + expr_ref_vector m_diff_indices; + func_decl_ref m_decl; // the partial equality declaration + app_ref m_peq; // partial equality application + app_ref m_eq; // equivalent std equality using def. of partial eq + array_util m_arr_u; + ast_eq_proc m_eq_proc; // for checking if two asts are equal + +public: + static const char* PARTIAL_EQ; + + peq (app* p, ast_manager& m); + + peq (expr* lhs, expr* rhs, unsigned num_indices, expr * const * diff_indices, ast_manager& m); + + void lhs (expr_ref& result); + + void rhs (expr_ref& result); + + void get_diff_indices (expr_ref_vector& result); + + void mk_peq (app_ref& result); + + void mk_eq (app_ref_vector& aux_consts, app_ref& result, bool stores_on_rhs = true); +}; + +const char* peq::PARTIAL_EQ = "partial_eq"; + +peq::peq (app* p, ast_manager& m): + m (m), + m_lhs (p->get_arg (0), m), + m_rhs (p->get_arg (1), m), + m_num_indices (p->get_num_args ()-2), + m_diff_indices (m), + m_decl (p->get_decl (), m), + m_peq (p, m), + m_eq (m), + m_arr_u (m) +{ + SASSERT (is_partial_eq (p)); + SASSERT (m_arr_u.is_array (m_lhs) && + m_arr_u.is_array (m_rhs) && + m_eq_proc (m.get_sort (m_lhs), m.get_sort (m_rhs))); + for (unsigned i = 2; i < p->get_num_args (); i++) { + m_diff_indices.push_back (p->get_arg (i)); + } +} + +peq::peq (expr* lhs, expr* rhs, unsigned num_indices, expr * const * diff_indices, ast_manager& m): + m (m), + m_lhs (lhs, m), + m_rhs (rhs, m), + m_num_indices (num_indices), + m_diff_indices (m), + m_decl (m), + m_peq (m), + m_eq (m), + m_arr_u (m) +{ + SASSERT (m_arr_u.is_array (lhs) && + m_arr_u.is_array (rhs) && + m_eq_proc (m.get_sort (lhs), m.get_sort (rhs))); + ptr_vector sorts; + sorts.push_back (m.get_sort (m_lhs)); + sorts.push_back (m.get_sort (m_rhs)); + for (unsigned i = 0; i < num_indices; i++) { + sorts.push_back (m.get_sort (diff_indices [i])); + m_diff_indices.push_back (diff_indices [i]); + } + m_decl = m.mk_func_decl (symbol (PARTIAL_EQ), sorts.size (), sorts.c_ptr (), m.mk_bool_sort ()); +} + +void peq::lhs (expr_ref& result) { result = m_lhs; } + +void peq::rhs (expr_ref& result) { result = m_rhs; } + +void peq::get_diff_indices (expr_ref_vector& result) { + for (unsigned i = 0; i < m_diff_indices.size (); i++) { + result.push_back (m_diff_indices.get (i)); + } +} + +void peq::mk_peq (app_ref& result) { + if (!m_peq) { + ptr_vector args; + args.push_back (m_lhs); + args.push_back (m_rhs); + for (unsigned i = 0; i < m_num_indices; i++) { + args.push_back (m_diff_indices.get (i)); + } + m_peq = m.mk_app (m_decl, args.size (), args.c_ptr ()); + } + result = m_peq; +} + +void peq::mk_eq (app_ref_vector& aux_consts, app_ref& result, bool stores_on_rhs) { + if (!m_eq) { + expr_ref lhs (m_lhs, m), rhs (m_rhs, m); + if (!stores_on_rhs) { + std::swap (lhs, rhs); + } + // lhs = (...(store (store rhs i0 v0) i1 v1)...) + sort* val_sort = get_array_range (m.get_sort (lhs)); + expr_ref_vector::iterator end = m_diff_indices.end (); + for (expr_ref_vector::iterator it = m_diff_indices.begin (); + it != end; it++) { + app* val = m.mk_fresh_const ("diff", val_sort); + ptr_vector store_args; + store_args.push_back (rhs); + store_args.push_back (*it); + store_args.push_back (val); + rhs = m_arr_u.mk_store (store_args.size (), store_args.c_ptr ()); + aux_consts.push_back (val); + } + m_eq = m.mk_eq (lhs, rhs); + } + result = m_eq; +} + + +bool is_partial_eq (app* a) { + return a->get_decl ()->get_name () == peq::PARTIAL_EQ; +} + +} + + +namespace qe { + + class is_relevant_default : public i_expr_pred { + public: + bool operator()(expr* e) { + return true; + } + }; + + class mk_atom_default : public i_nnf_atom { + public: + virtual void operator()(expr* e, bool pol, expr_ref& result) { + if (pol) result = e; + else result = result.get_manager().mk_not(e); + } + }; + + class arith_project_util { + ast_manager& m; + arith_util a; + th_rewriter m_rw; + expr_ref_vector m_lits; + expr_ref_vector m_terms; + vector m_coeffs; + vector m_divs; + svector m_strict; + svector m_eq; + scoped_ptr m_var; + + bool is_linear(rational const& mul, expr* t, rational& c, expr_ref_vector& ts) { + expr* t1, *t2; + rational mul1; + bool res = true; + if (t == m_var->x()) { + c += mul; + } + else if (a.is_mul(t, t1, t2) && a.is_numeral(t1, mul1)) { + res = is_linear(mul* mul1, t2, c, ts); + } + else if (a.is_mul(t, t1, t2) && a.is_numeral(t2, mul1)) { + res = is_linear(mul* mul1, t1, c, ts); + } + else if (a.is_add(t)) { + app* ap = to_app(t); + for (unsigned i = 0; res && i < ap->get_num_args(); ++i) { + res = is_linear(mul, ap->get_arg(i), c, ts); + } + } + else if (a.is_sub(t, t1, t2)) { + res = is_linear(mul, t1, c, ts) && is_linear(-mul, t2, c, ts); + } + else if (a.is_uminus(t, t1)) { + res = is_linear(-mul, t1, c, ts); + } + else if (a.is_numeral(t, mul1)) { + ts.push_back(a.mk_numeral(mul*mul1, m.get_sort(t))); + } + else if ((*m_var)(t)) { + IF_VERBOSE(2, verbose_stream() << "can't project:" << mk_pp(t, m) << "\n";); + TRACE ("qe", tout << "Failed to project: " << mk_pp (t, m) << "\n";); + res = false; + } + else if (mul.is_one()) { + ts.push_back(t); + } + else { + ts.push_back(a.mk_mul(a.mk_numeral(mul, m.get_sort(t)), t)); + } + return res; + } + + // either an equality (cx + t = 0) or an inequality (cx + t <= 0) or a divisibility literal (d | cx + t) + bool is_linear(expr* lit, rational& c, expr_ref& t, rational& d, bool& is_strict, bool& is_eq, bool& is_diseq) { + SASSERT ((*m_var)(lit)); + expr* e1, *e2; + c.reset(); + sort* s; + expr_ref_vector ts(m); + bool is_not = m.is_not(lit, lit); + rational mul(1); + if (is_not) { + mul.neg(); + } + SASSERT(!m.is_not(lit)); + if (a.is_le(lit, e1, e2) || a.is_ge(lit, e2, e1)) { + if (!is_linear( mul, e1, c, ts) || !is_linear(-mul, e2, c, ts)) + return false; + s = m.get_sort(e1); + is_strict = is_not; + } + else if (a.is_lt(lit, e1, e2) || a.is_gt(lit, e2, e1)) { + if (!is_linear( mul, e1, c, ts) || !is_linear(-mul, e2, c, ts)) + return false; + s = m.get_sort(e1); + is_strict = !is_not; + } + else if (m.is_eq(lit, e1, e2) && a.is_int_real (e1)) { + expr *t, *num; + rational num_val, d_val, z; + bool is_int; + if (a.is_mod (e1, t, num) && a.is_numeral (num, num_val, is_int) && is_int && + a.is_numeral (e2, z) && z.is_zero ()) { + // divsibility constraint: t % num == 0 <=> num | t + if (num_val.is_zero ()) { + IF_VERBOSE(1, verbose_stream() << "div by zero" << mk_pp(lit, m) << "\n";); + return false; + } + d = num_val; + if (!is_linear (mul, t, c, ts)) return false; + } else if (a.is_mod (e2, t, num) && a.is_numeral (num, num_val, is_int) && is_int && + a.is_numeral (e1, z) && z.is_zero ()) { + // divsibility constraint: 0 == t % num <=> num | t + if (num_val.is_zero ()) { + IF_VERBOSE(1, verbose_stream() << "div by zero" << mk_pp(lit, m) << "\n";); + return false; + } + d = num_val; + if (!is_linear (mul, t, c, ts)) return false; + } else { + // equality or disequality + if (!is_linear( mul, e1, c, ts) || !is_linear(-mul, e2, c, ts)) + return false; + if (is_not) is_diseq = true; + else is_eq = true; + } + s = m.get_sort(e1); + } + else { + IF_VERBOSE(2, verbose_stream() << "can't project:" << mk_pp(lit, m) << "\n";); + TRACE ("qe", tout << "Failed to project: " << mk_pp (lit, m) << "\n";); + return false; + } + + if (ts.empty()) { + t = a.mk_numeral(rational(0), s); + } + else if (ts.size () == 1) { + t = ts.get (0); + } + else { + t = a.mk_add(ts.size(), ts.c_ptr()); + } + + return true; + } + + bool project(model& mdl, expr_ref_vector& lits) { + unsigned num_pos = 0; + unsigned num_neg = 0; + bool use_eq = false; + expr_ref_vector new_lits(m); + expr_ref eq_term (m); + + m_lits.reset (); + m_terms.reset(); + m_coeffs.reset(); + m_strict.reset(); + m_eq.reset (); + + for (unsigned i = 0; i < lits.size(); ++i) { + rational c(0), d(0); + expr_ref t(m); + bool is_strict = false; + bool is_eq = false; + bool is_diseq = false; + if (!(*m_var)(lits.get (i))) { + new_lits.push_back(lits.get (i)); + continue; + } + if (is_linear(lits.get (i), c, t, d, is_strict, is_eq, is_diseq)) { + if (c.is_zero()) { + m_rw(lits.get (i), t); + new_lits.push_back(t); + } else if (is_eq) { + if (!use_eq) { + // c*x + t = 0 <=> x = -t/c + eq_term = mk_mul (-(rational::one ()/c), t); + use_eq = true; + } + m_lits.push_back (lits.get (i)); + m_coeffs.push_back(c); + m_terms.push_back(t); + m_strict.push_back(false); + m_eq.push_back (true); + } else { + if (is_diseq) { + // c*x + t != 0 + // find out whether c*x + t < 0, or c*x + t > 0 + expr_ref cx (m), cxt (m), val (m); + rational r; + cx = mk_mul (c, m_var->x()); + cxt = mk_add (cx, t); + VERIFY(mdl.eval(cxt, val, true)); + VERIFY(a.is_numeral(val, r)); + SASSERT (r > rational::zero () || r < rational::zero ()); + if (r > rational::zero ()) { + c = -c; + t = mk_mul (-(rational::one()), t); + } + is_strict = true; + } + m_lits.push_back (lits.get (i)); + m_coeffs.push_back(c); + m_terms.push_back(t); + m_strict.push_back(is_strict); + m_eq.push_back (false); + if (c.is_pos()) { + ++num_pos; + } + else { + ++num_neg; + } + } + } + else return false; + } + if (use_eq) { + TRACE ("qe", + tout << "Using equality term: " << mk_pp (eq_term, m) << "\n"; + ); + // substitute eq_term for x everywhere + for (unsigned i = 0; i < m_lits.size(); ++i) { + expr_ref cx (m), cxt (m), z (m), result (m); + cx = mk_mul (m_coeffs[i], eq_term); + cxt = mk_add (cx, m_terms.get(i)); + z = a.mk_numeral(rational(0), m.get_sort(eq_term)); + if (m_eq[i]) { + // c*x + t = 0 + result = a.mk_eq (cxt, z); + } else if (m_strict[i]) { + // c*x + t < 0 + result = a.mk_lt (cxt, z); + } else { + // c*x + t <= 0 + result = a.mk_le (cxt, z); + } + m_rw (result); + new_lits.push_back (result); + } + } + lits.reset(); + lits.append(new_lits); + if (use_eq || num_pos == 0 || num_neg == 0) { + return true; + } + bool use_pos = num_pos < num_neg; + unsigned max_t = find_max(mdl, use_pos); + + expr_ref new_lit (m); + for (unsigned i = 0; i < m_lits.size(); ++i) { + if (i != max_t) { + if (m_coeffs[i].is_pos() == use_pos) { + new_lit = mk_le(i, max_t); + } + else { + new_lit = mk_lt(i, max_t); + } + lits.push_back(new_lit); + TRACE ("qe", + tout << "Old literal: " << mk_pp (m_lits.get (i), m) << "\n"; + tout << "New literal: " << mk_pp (new_lit, m) << "\n"; + ); + } + } + return true; + } + + bool project(model& mdl, app_ref_vector const& lits, expr_map& map, app_ref& div_lit) { + unsigned num_pos = 0; // number of positive literals true in the model + unsigned num_neg = 0; // number of negative literals true in the model + + m_lits.reset (); + m_terms.reset(); + m_coeffs.reset(); + m_divs.reset (); + m_strict.reset(); + m_eq.reset (); + + expr_ref var_val (m); + VERIFY (mdl.eval (m_var->x(), var_val, true)); + + unsigned eq_idx = lits.size (); + for (unsigned i = 0; i < lits.size(); ++i) { + rational c(0), d(0); + expr_ref t(m); + bool is_strict = false; + bool is_eq = false; + bool is_diseq = false; + if (!(*m_var)(lits.get (i))) continue; + if (is_linear(lits.get (i), c, t, d, is_strict, is_eq, is_diseq)) { + TRACE ("qe", + tout << "Literal: " << mk_pp (lits.get (i), m) << "\n"; + ); + + if (c.is_zero()) { + TRACE ("qe", + tout << "independent of variable\n"; + ); + continue; + } + + // evaluate c*x + t in the model + expr_ref cx (m), cxt (m), val (m); + rational r; + cx = mk_mul (c, m_var->x()); + cxt = mk_add (cx, t); + VERIFY(mdl.eval(cxt, val, true)); + VERIFY(a.is_numeral(val, r)); + + if (is_eq) { + TRACE ("qe", + tout << "equality term\n"; + ); + // check if the equality is true in the mdl + if (eq_idx == lits.size () && r == rational::zero ()) { + eq_idx = m_lits.size (); + } + m_lits.push_back (lits.get (i)); + m_coeffs.push_back(c); + m_terms.push_back(t); + m_strict.push_back(false); + m_eq.push_back (true); + m_divs.push_back (d); + } else { + TRACE ("qe", + tout << "not an equality term\n"; + ); + if (is_diseq) { + // c*x + t != 0 + // find out whether c*x + t < 0, or c*x + t > 0 + if (r > rational::zero ()) { + c = -c; + t = mk_mul (-(rational::one()), t); + r = -r; + } + // note: if the disequality is false in the model, + // r==0 and we end up choosing c*x + t < 0 + is_strict = true; + } + m_lits.push_back (lits.get (i)); + m_coeffs.push_back(c); + m_terms.push_back(t); + m_strict.push_back(is_strict); + m_eq.push_back (false); + m_divs.push_back (d); + if (d.is_zero ()) { // not a div term + if ((is_strict && r < rational::zero ()) || + (!is_strict && r <= rational::zero ())) { // literal true in the model + if (c.is_pos()) { + ++num_pos; + } + else { + ++num_neg; + } + } + } + } + TRACE ("qe", + tout << "c: " << c << "\n"; + tout << "t: " << mk_pp (t, m) << "\n"; + tout << "d: " << d << "\n"; + ); + } + else return false; + } + + rational lcm_coeffs (1), lcm_divs (1); + if (a.is_int (m_var->x())) { + // lcm of (absolute values of) coeffs + for (unsigned i = 0; i < m_lits.size (); i++) { + lcm_coeffs = lcm (lcm_coeffs, abs (m_coeffs[i])); + } + // normalize coeffs of x to +/-lcm_coeffs and scale terms and divs appropriately; + // find lcm of scaled-up divs + for (unsigned i = 0; i < m_lits.size (); i++) { + rational factor (lcm_coeffs / abs(m_coeffs[i])); + if (!factor.is_one () && !a.is_zero (m_terms.get (i))) + m_terms[i] = a.mk_mul (a.mk_numeral (factor, a.mk_int ()), + m_terms.get (i)); + m_coeffs[i] = (m_coeffs[i].is_pos () ? lcm_coeffs : -lcm_coeffs); + if (!m_divs[i].is_zero ()) { + m_divs[i] *= factor; + lcm_divs = lcm (lcm_divs, m_divs[i]); + } + TRACE ("qe", + tout << "normalized coeff: " << m_coeffs[i] << "\n"; + tout << "normalized term: " << mk_pp (m_terms.get (i), m) << "\n"; + tout << "normalized div: " << m_divs[i] << "\n"; + ); + } + + // consider new divisibility literal (lcm_coeffs | (lcm_coeffs * x)) + lcm_divs = lcm (lcm_divs, lcm_coeffs); + + TRACE ("qe", + tout << "lcm of coeffs: " << lcm_coeffs << "\n"; + tout << "lcm of divs: " << lcm_divs << "\n"; + ); + } + + expr_ref z (a.mk_numeral (rational::zero (), a.mk_int ()), m); + expr_ref x_term_val (m); + + // use equality term + if (eq_idx < lits.size ()) { + if (a.is_real (m_var->x ())) { + // c*x + t = 0 <=> x = -t/c + expr_ref eq_term (mk_mul (-(rational::one ()/m_coeffs[eq_idx]), m_terms.get (eq_idx)), m); + m_rw (eq_term); + map.insert (m_var->x (), eq_term, 0); + TRACE ("qe", + tout << "Using equality term: " << mk_pp (eq_term, m) << "\n"; + ); + } + else { + // find substitution term for (lcm_coeffs * x) + if (m_coeffs[eq_idx].is_pos ()) { + x_term_val = a.mk_uminus (m_terms.get (eq_idx)); + } else { + x_term_val = m_terms.get (eq_idx); + } + m_rw (x_term_val); + TRACE ("qe", + tout << "Using equality literal: " << mk_pp (m_lits.get (eq_idx), m) << "\n"; + tout << "substitution for (lcm_coeffs * x): " << mk_pp (x_term_val, m) << "\n"; + ); + // can't simply substitute for x; need to explicitly substitute the lits + mk_lit_substitutes (x_term_val, map, eq_idx); + + if (!lcm_coeffs.is_one ()) { + // new div constraint: lcm_coeffs | x_term_val + div_lit = m.mk_eq (a.mk_mod (x_term_val, + a.mk_numeral (lcm_coeffs, a.mk_int ())), + z); + } + } + + return true; + } + + expr_ref new_lit (m); + + if (num_pos == 0 || num_neg == 0) { + TRACE ("qe", + if (num_pos == 0) { + tout << "virtual substitution with +infinity\n"; + } else { + tout << "virtual substitution with -infinity\n"; + } + ); + + /** + * make all equalities false; + * if num_pos = 0 (num_neg = 0), make all positive (negative) inequalities false; + * make the rest inequalities true; + * substitute value of x under given model for the rest (div terms) + */ + + if (a.is_int (m_var->x())) { + // to substitute for (lcm_coeffs * x), it suffices to pick + // some element in the congruence class of (lcm_coeffs * x) mod lcm_divs; + // simply substituting var_val for x in the literals does this job; + // but to keep constants small, we use (lcm_coeffs * var_val) % lcm_divs instead + rational var_val_num; + VERIFY (a.is_numeral (var_val, var_val_num)); + x_term_val = a.mk_numeral (mod (lcm_coeffs * var_val_num, lcm_divs), + a.mk_int ()); + TRACE ("qe", + tout << "Substitution for (lcm_coeffs * x): " + << mk_pp (x_term_val, m) << "\n"; + ); + } + for (unsigned i = 0; i < m_lits.size (); i++) { + if (!m_divs[i].is_zero ()) { + // m_divs[i] | (x_term_val + m_terms[i]) + + // -- x_term_val is the absolute value, negate it if needed + if (m_coeffs.get (i).is_pos ()) + new_lit = a.mk_add (m_terms.get (i), x_term_val); + else + new_lit = a.mk_add (m_terms.get (i), a.mk_uminus (x_term_val)); + + // XXX Our handling of divisibility constraints is very fragile. + // XXX Rewrite before applying divisibility to preserve syntactic structure + m_rw(new_lit); + new_lit = m.mk_eq (a.mk_mod (new_lit, + a.mk_numeral (m_divs[i], a.mk_int ())), z); + } else if (m_eq[i] || + (num_pos == 0 && m_coeffs[i].is_pos ()) || + (num_neg == 0 && m_coeffs[i].is_neg ())) { + new_lit = m.mk_false (); + } else { + new_lit = m.mk_true (); + } + map.insert (m_lits.get (i), new_lit, 0); + TRACE ("qe", + tout << "Old literal: " << mk_pp (m_lits.get (i), m) << "\n"; + tout << "New literal: " << mk_pp (new_lit, m) << "\n"; + ); + } + return true; + } + + bool use_pos = num_pos < num_neg; // pick a side; both are sound + + unsigned max_t = find_max(mdl, use_pos); + + TRACE ("qe", + if (use_pos) { + tout << "virtual substitution with upper bound:\n"; + } else { + tout << "virtual substitution with lower bound:\n"; + } + tout << "test point: " << mk_pp (m_lits.get (max_t), m) << "\n"; + tout << "coeff: " << m_coeffs[max_t] << "\n"; + tout << "term: " << mk_pp (m_terms.get (max_t), m) << "\n"; + tout << "is_strict: " << m_strict[max_t] << "\n"; + ); + + if (a.is_real (m_var->x ())) { + for (unsigned i = 0; i < m_lits.size(); ++i) { + if (i != max_t) { + if (m_eq[i]) { + if (!m_strict[max_t]) { + new_lit = mk_eq (i, max_t); + } else { + new_lit = m.mk_false (); + } + } else if (m_coeffs[i].is_pos() == use_pos) { + new_lit = mk_le (i, max_t); + } else { + new_lit = mk_lt (i, max_t); + } + } else { + new_lit = m.mk_true (); + } + map.insert (m_lits.get (i), new_lit, 0); + TRACE ("qe", + tout << "Old literal: " << mk_pp (m_lits.get (i), m) << "\n"; + tout << "New literal: " << mk_pp (new_lit, m) << "\n"; + ); + } + } else { + SASSERT (a.is_int (m_var->x ())); + + // mk substitution term for (lcm_coeffs * x) + + // evaluate c*x + t for the literal at max_t + expr_ref cx (m), cxt (m), val (m); + rational r; + cx = mk_mul (m_coeffs[max_t], m_var->x()); + cxt = mk_add (cx, m_terms.get (max_t)); + VERIFY(mdl.eval(cxt, val, true)); + VERIFY(a.is_numeral(val, r)); + + // get the offset from the smallest/largest possible value for x + // literal smallest/largest val of x + // ------- -------------------------- + // l < x l+1 + // l <= x l + // x < u u-1 + // x <= u u + rational offset; + if (m_strict[max_t]) { + offset = abs(r) - rational::one (); + } else { + offset = abs(r); + } + // obtain the offset modulo lcm_divs + offset %= lcm_divs; + + // for strict negative literal (i.e. strict lower bound), + // substitution term is (t+1+offset); for non-strict, it's (t+offset) + // + // for positive term, subtract from 0 + x_term_val = mk_add (m_terms.get (max_t), a.mk_numeral (offset, a.mk_int ())); + if (m_strict[max_t]) { + x_term_val = a.mk_add (x_term_val, a.mk_numeral (rational::one(), a.mk_int ())); + } + if (m_coeffs[max_t].is_pos ()) { + x_term_val = a.mk_uminus (x_term_val); + } + m_rw (x_term_val); + + TRACE ("qe", + tout << "substitution for (lcm_coeffs * x): " << mk_pp (x_term_val, m) << "\n"; + ); + + // obtain substitutions for all literals in map + mk_lit_substitutes (x_term_val, map, max_t); + + if (!lcm_coeffs.is_one ()) { + // new div constraint: lcm_coeffs | x_term_val + div_lit = m.mk_eq (a.mk_mod (x_term_val, + a.mk_numeral (lcm_coeffs, a.mk_int ())), + z); + } + } + return true; + } + + unsigned find_max(model& mdl, bool do_pos) { + unsigned result; + bool found = false; + bool found_strict = false; + rational found_val (0), r, r_plus_x, found_c; + expr_ref val(m); + + // evaluate x in mdl + rational r_x; + VERIFY(mdl.eval(m_var->x (), val, true)); + VERIFY(a.is_numeral (val, r_x)); + + for (unsigned i = 0; i < m_terms.size(); ++i) { + rational const& ac = m_coeffs[i]; + if (!m_eq[i] && ac.is_pos() == do_pos) { + VERIFY(mdl.eval(m_terms.get (i), val, true)); + VERIFY(a.is_numeral(val, r)); + r /= abs(ac); + // skip the literal if false in the model + if (do_pos) { r_plus_x = r + r_x; } + else { r_plus_x = r - r_x; } + if (!((m_strict[i] && r_plus_x < rational::zero ()) || + (!m_strict[i] && r_plus_x <= rational::zero ()))) { + continue; + } + IF_VERBOSE(2, verbose_stream() << "max: " << mk_pp(m_terms.get (i), m) << " " << r << " " << + (!found || r > found_val || (r == found_val && !found_strict && m_strict[i])) << "\n";); + if (!found || r > found_val || (r == found_val && !found_strict && m_strict[i])) { + result = i; + found_val = r; + found_c = ac; + found = true; + found_strict = m_strict[i]; + } + } + } + SASSERT(found); + return result; + } + + // ax + t <= 0 + // bx + s <= 0 + // a and b have different signs. + // Infer: a|b|x + |b|t + |a|bx + |a|s <= 0 + // e.g. |b|t + |a|s <= 0 + expr_ref mk_lt(unsigned i, unsigned j) { + rational const& ac = m_coeffs[i]; + rational const& bc = m_coeffs[j]; + SASSERT(ac.is_pos() != bc.is_pos()); + SASSERT(ac.is_neg() != bc.is_neg()); + expr_ref bt (m), as (m), ts (m), z (m); + expr* t = m_terms.get (i); + expr* s = m_terms.get (j); + bt = mk_mul(abs(bc), t); + as = mk_mul(abs(ac), s); + ts = mk_add(bt, as); + z = a.mk_numeral(rational(0), m.get_sort(t)); + expr_ref result1(m), result2(m); + if (m_strict[i] || m_strict[j]) { + result1 = a.mk_lt(ts, z); + } + else { + result1 = a.mk_le(ts, z); + } + m_rw(result1, result2); + return result2; + } + + // ax + t <= 0 + // bx + s <= 0 + // a and b have same signs. + // encode:// t/|a| <= s/|b| + // e.g. |b|t <= |a|s + expr_ref mk_le(unsigned i, unsigned j) { + rational const& ac = m_coeffs[i]; + rational const& bc = m_coeffs[j]; + SASSERT(ac.is_pos() == bc.is_pos()); + SASSERT(ac.is_neg() == bc.is_neg()); + expr_ref bt (m), as (m); + expr* t = m_terms.get (i); + expr* s = m_terms.get (j); + bt = mk_mul(abs(bc), t); + as = mk_mul(abs(ac), s); + expr_ref result1(m), result2(m); + if (!m_strict[j] && m_strict[i]) { + result1 = a.mk_lt(bt, as); + } + else { + result1 = a.mk_le(bt, as); + } + m_rw(result1, result2); + return result2; + } + + // ax + t = 0 + // bx + s <= 0 + // replace equality by (-t/a == -s/b), or, as = bt + expr_ref mk_eq (unsigned i, unsigned j) { + expr_ref as (m), bt (m); + as = mk_mul (m_coeffs[i], m_terms.get (j)); + bt = mk_mul (m_coeffs[j], m_terms.get (i)); + expr_ref result (m); + result = m.mk_eq (as, bt); + m_rw (result); + return result; + } + + + expr* mk_add(expr* t1, expr* t2) { + return a.mk_add(t1, t2); + } + expr* mk_mul(rational const& r, expr* t2) { + expr* t1 = a.mk_numeral(r, m.get_sort(t2)); + return a.mk_mul(t1, t2); + } + + /** + * walk the ast of fml and introduce a fresh variable for every mod term + * (updating the mdl accordingly) + */ + void factor_mod_terms (expr_ref& fml, app_ref_vector& vars, model& mdl) { + expr_ref_vector todo (m), eqs (m); + expr_map factored_terms (m); + ast_mark done; + + todo.push_back (fml); + while (!todo.empty ()) { + expr* e = todo.back (); + if (!is_app (e) || done.is_marked (e)) { + todo.pop_back (); + continue; + } + app* ap = to_app (e); + unsigned num_args = ap->get_num_args (); + bool all_done = true, changed = false; + expr_ref_vector args (m); + for (unsigned i = 0; i < num_args; i++) { + expr* old_arg = ap->get_arg (i); + if (!done.is_marked (old_arg)) { + todo.push_back (old_arg); + all_done = false; + } + if (!all_done) continue; + // all args so far have been processed + // get the correct arg to use + proof* pr = 0; expr* new_arg = 0; + factored_terms.get (old_arg, new_arg, pr); + if (new_arg) { + // changed + args.push_back (new_arg); + changed = true; + } + else { + // not changed + args.push_back (old_arg); + } + } + if (all_done) { + // all args processed; make new term + func_decl* d = ap->get_decl (); + expr_ref new_term (m); + new_term = m.mk_app (d, args.size (), args.c_ptr ()); + // check for mod and introduce new var + if (a.is_mod (ap)) { + app_ref new_var (m); + new_var = m.mk_fresh_const ("mod_var", d->get_range ()); + eqs.push_back (m.mk_eq (new_var, new_term)); + // obtain value of new_term in mdl + expr_ref val (m); + mdl.eval (new_term, val, true); + // use the variable from now on + new_term = new_var; + changed = true; + // update vars and mdl + vars.push_back (new_var); + mdl.register_decl (new_var->get_decl (), val); + } + if (changed) { + factored_terms.insert (e, new_term, 0); + } + done.mark (e, true); + todo.pop_back (); + } + } + + // mk new fml + proof* pr = 0; expr* new_fml = 0; + factored_terms.get (fml, new_fml, pr); + if (new_fml) { + fml = new_fml; + // add in eqs + fml = m.mk_and (fml, m.mk_and (eqs.size (), eqs.c_ptr ())); + } + else { + // unchanged + SASSERT (eqs.empty ()); + } + } + + /** + * factor out mod terms by using divisibility terms; + * + * for now, only handle mod equalities of the form (t1 % num == t2), + * replacing it by the equivalent (num | (t1-t2)) /\ (0 <= t2 < abs(num)); + * the divisibility atom is a special mod term ((t1-t2) % num == 0) + */ + void mod2div (expr_ref& fml, expr_map& map) { + expr* new_fml = 0; + + proof *pr = 0; + map.get (fml, new_fml, pr); + if (new_fml) { + fml = new_fml; + return; + } + + expr_ref z (a.mk_numeral (rational::zero (), a.mk_int ()), m); + bool is_mod_eq = false; + + expr *e1, *e2, *num; + expr_ref t1 (m), t2 (m); + rational num_val; + bool is_int; + // check if fml is a mod equality (t1 % num) == t2 + if (m.is_eq (fml, e1, e2)) { + expr* t; + if (a.is_mod (e1, t, num) && a.is_numeral (num, num_val, is_int) && is_int) { + t1 = t; + t2 = e2; + is_mod_eq = true; + } else if (a.is_mod (e2, t, num) && a.is_numeral (num, num_val, is_int) && is_int) { + t1 = t; + t2 = e1; + is_mod_eq = true; + } + } + + if (is_mod_eq) { + // recursively mod2div for t1 and t2 + mod2div (t1, map); + mod2div (t2, map); + + rational t2_num; + if (a.is_numeral (t2, t2_num) && t2_num.is_zero ()) { + // already in the desired form; + // new_fml is (num_val | t1) + new_fml = m.mk_eq (a.mk_mod (t1, a.mk_numeral (num_val, a.mk_int ())), + z); + } + else { + expr_ref_vector lits (m); + // num_val | (t1 - t2) + lits.push_back (m.mk_eq (a.mk_mod (a.mk_sub (t1, t2), + a.mk_numeral (num_val, a.mk_int ())), + z)); + // 0 <= t2 + lits.push_back (a.mk_le (z, t2)); + // t2 < abs (num_val) + lits.push_back (a.mk_lt (t2, a.mk_numeral (abs (num_val), a.mk_int ()))); + + new_fml = m.mk_and (lits.size (), lits.c_ptr ()); + } + } + else if (!is_app (fml)) { + new_fml = fml; + } + else { + app* a = to_app (fml); + expr_ref_vector children (m); + expr_ref ch (m); + for (unsigned i = 0; i < a->get_num_args (); i++) { + ch = a->get_arg (i); + mod2div (ch, map); + children.push_back (ch); + } + new_fml = m.mk_app (a->get_decl (), children.size (), children.c_ptr ()); + } + + map.insert (fml, new_fml, 0); + fml = new_fml; + } + + void collect_lits (expr* fml, app_ref_vector& lits) { + expr_ref_vector todo (m); + ast_mark visited; + todo.push_back(fml); + while (!todo.empty()) { + expr* e = todo.back(); + todo.pop_back(); + if (visited.is_marked(e)) { + continue; + } + visited.mark(e, true); + if (!is_app(e)) { + continue; + } + app* a = to_app(e); + if (m.is_and(a) || m.is_or(a)) { + for (unsigned i = 0; i < a->get_num_args(); ++i) { + todo.push_back(a->get_arg(i)); + } + } else { + lits.push_back (a); + } + } + SASSERT(todo.empty()); + visited.reset(); + } + + /** + * assume that all coeffs of x are the same, say c + * substitute x_term_val for (c*x) in all lits and update map + * make the literal at idx true + */ + void mk_lit_substitutes (expr_ref const& x_term_val, expr_map& map, unsigned idx) { + expr_ref z (a.mk_numeral (rational::zero (), a.mk_int ()), m); + expr_ref cxt (m), new_lit (m); + for (unsigned i = 0; i < m_lits.size(); ++i) { + if (i == idx) { + new_lit = m.mk_true (); + } else { + // cxt + if (m_coeffs[i].is_neg ()) { + cxt = a.mk_sub (m_terms.get (i), x_term_val); + } else { + cxt = a.mk_add (m_terms.get (i), x_term_val); + } + + if (m_divs[i].is_zero ()) { + if (m_eq[i]) { + new_lit = m.mk_eq (cxt, z); + } else if (m_strict[i]) { + new_lit = a.mk_lt (cxt, z); + } else { + new_lit = a.mk_le (cxt, z); + } + m_rw(new_lit); + } else { + // div term + // XXX rewrite before applying mod to ensure mod is the top-level operator + m_rw(cxt); + new_lit = m.mk_eq (a.mk_mod (cxt, + a.mk_numeral (m_divs[i], a.mk_int ())), + z); + } + } + map.insert (m_lits.get (i), new_lit, 0); + TRACE ("qe", + tout << "Old literal: " << mk_pp (m_lits.get (i), m) << "\n"; + tout << "New literal: " << mk_pp (new_lit, m) << "\n"; + ); + } + } + + void substitute (expr_ref& fml, app_ref_vector& lits, expr_map& map) { + expr_substitution sub (m); + // literals + for (unsigned i = 0; i < lits.size (); i++) { + expr* new_lit = 0; proof* pr = 0; + app* old_lit = lits.get (i); + map.get (old_lit, new_lit, pr); + if (new_lit) { + sub.insert (old_lit, new_lit); + TRACE ("qe", + tout << "old lit " << mk_pp (old_lit, m) << "\n"; + tout << "new lit " << mk_pp (new_lit, m) << "\n"; + ); + } + } + // substitute for x, if any + expr* x_term = 0; proof* pr = 0; + map.get (m_var->x (), x_term, pr); + if (x_term) { + sub.insert (m_var->x (), x_term); + TRACE ("qe", + tout << "substituting " << mk_pp (m_var->x (), m) << " by " << mk_pp (x_term, m) << "\n"; + ); + } + scoped_ptr rep = mk_default_expr_replacer (m); + rep->set_substitution (&sub); + (*rep)(fml); + } + + public: + arith_project_util(ast_manager& m): + m(m), a(m), m_rw(m), m_lits (m), m_terms (m) {} + + // OLD AND UNUSED INTERFACE + expr_ref operator()(model& mdl, app_ref_vector& vars, expr_ref_vector const& lits) { + app_ref_vector new_vars(m); + expr_ref_vector result(lits); + for (unsigned i = 0; i < vars.size(); ++i) { + app* v = vars.get (i); + m_var = alloc(contains_app, m, v); + bool fail = a.is_int (v) || !project (mdl, result); + if (fail) new_vars.push_back (v); + + IF_VERBOSE(2, + if (fail) { + verbose_stream() << "can't project:" << mk_pp(v, m) << "\n"; + } + ); + TRACE("qe", + if (!fail) { + tout << "projected: " << mk_pp(v, m) << "\n"; + for (unsigned i = 0; i < result.size(); ++i) { + tout << mk_pp(result.get (i), m) << "\n"; + } + } + else { + tout << "Failed to project: " << mk_pp (v, m) << "\n"; + } + ); + } + vars.reset(); + vars.append(new_vars); + return mk_and(result); + } + + void operator()(model& mdl, app_ref_vector& vars, expr_ref& fml) { + expr_map map (m); + operator()(mdl, vars, fml, map); + } + + void operator()(model& mdl, app_ref_vector& vars, expr_ref& fml, expr_map& map) { + app_ref_vector new_vars(m); + + // factor out mod terms by introducing new variables + TRACE ("qe", + tout << "before factoring out mod terms:" << "\n"; + tout << mk_pp (fml, m) << "\n"; + tout << "mdl:\n"; + model_pp (tout, mdl); + tout << "\n"; + ); + + factor_mod_terms (fml, vars, mdl); + + TRACE ("qe", + tout << "after factoring out mod terms:" << "\n"; + tout << mk_pp (fml, m) << "\n"; + tout << "updated mdl:\n"; + model_pp (tout, mdl); + tout << "\n"; + ); + + app_ref_vector lits (m); +// expr_map map (m); + for (unsigned i = 0; i < vars.size(); ++i) { + app* v = vars.get (i); + TRACE ("qe", + tout << "projecting variable: " << mk_pp (v, m) << "\n"; + ); + m_var = alloc(contains_app, m, v); + map.reset (); + lits.reset (); + if (a.is_int (v)) { + // factor out mod terms using div terms + expr_map mod_map (m); + mod2div (fml, mod_map); + TRACE ("qe", + tout << "after mod2div:" << "\n"; + tout << mk_pp (fml, m) << "\n"; + ); + } + collect_lits (fml, lits); + app_ref div_lit (m); + if (project (mdl, lits, map, div_lit)) { + substitute (fml, lits, map); + if (div_lit) { + fml = m.mk_and (fml, div_lit); + } + TRACE("qe", + tout << "projected: " << mk_pp(v, m) << " " + << mk_pp(fml, m) << "\n"; + ); + } + else { + IF_VERBOSE(2, verbose_stream() << "can't project:" << mk_pp(v, m) << "\n";); + TRACE ("qe", tout << "Failed to project: " << mk_pp (v, m) << "\n";); + new_vars.push_back(v); + } + } + vars.reset(); + vars.append(new_vars); + m_rw (fml); + } + }; + + + class array_project_eqs_util { + ast_manager& m; + array_util m_arr_u; + model_ref M; + app_ref m_v; // array var to eliminate + ast_mark m_has_stores_v; // has stores for m_v + expr_ref m_subst_term_v; // subst term for m_v + expr_safe_replace m_true_sub_v; // subst for true equalities + expr_safe_replace m_false_sub_v; // subst for false equalities + expr_ref_vector m_aux_lits_v; + expr_ref_vector m_idx_lits_v; + app_ref_vector m_aux_vars; + model_evaluator_array_util m_mev; + + void reset_v () { + m_v = 0; + m_has_stores_v.reset (); + m_subst_term_v = 0; + m_true_sub_v.reset (); + m_false_sub_v.reset (); + m_aux_lits_v.reset (); + m_idx_lits_v.reset (); + } + + void reset () { + M = 0; + reset_v (); + m_aux_vars.reset (); + } + + /** + * find all array equalities on m_v or containing stores on/of m_v + * + * also mark terms containing stores on/of m_v + */ + void find_arr_eqs (expr_ref const& fml, expr_ref_vector& eqs) { + if (!is_app (fml)) return; + ast_mark done; + ptr_vector todo; + todo.push_back (to_app (fml)); + while (!todo.empty ()) { + app* a = todo.back (); + if (done.is_marked (a)) { + todo.pop_back (); + continue; + } + bool all_done = true; + bool args_have_stores = false; + unsigned num_args = a->get_num_args (); + for (unsigned i = 0; i < num_args; i++) { + expr* arg = a->get_arg (i); + if (!is_app (arg)) continue; + if (!done.is_marked (arg)) { + all_done = false; + todo.push_back (to_app (arg)); + } + else if (!args_have_stores && m_has_stores_v.is_marked (arg)) { + args_have_stores = true; + } + } + if (!all_done) continue; + todo.pop_back (); + + // mark if a has stores + if ((!m_arr_u.is_select (a) && args_have_stores) || + (m_arr_u.is_store (a) && (a->get_arg (0) == m_v))) { + m_has_stores_v.mark (a, true); + + TRACE ("qe", + tout << "has stores:\n"; + tout << mk_pp (a, m) << "\n"; + ); + } + + // check if a is a relevant array equality + if (m.is_eq (a)) { + expr* a0 = to_app (a)->get_arg (0); + expr* a1 = to_app (a)->get_arg (1); + if (a0 == m_v || a1 == m_v || + (m_arr_u.is_array (a0) && m_has_stores_v.is_marked (a))) { + eqs.push_back (a); + } + } + // else, we can check for disequalities and handle them using extensionality, + // but it's not necessary + + done.mark (a, true); + } + } + + /** + * factor out select terms on m_v using fresh consts + */ + void factor_selects (app_ref& fml) { + expr_map sel_cache (m); + ast_mark done; + ptr_vector todo; + expr_ref_vector pinned (m); // to ensure a reference + + todo.push_back (fml); + while (!todo.empty ()) { + app* a = todo.back (); + if (done.is_marked (a)) { + todo.pop_back (); + continue; + } + expr_ref_vector args (m); + bool all_done = true; + for (unsigned i = 0; i < a->get_num_args (); i++) { + expr* arg = a->get_arg (i); + if (!is_app (arg)) continue; + if (!done.is_marked (arg)) { + all_done = false; + todo.push_back (to_app (arg)); + } + else if (all_done) { // all done so far.. + expr* arg_new = 0; proof* pr; + sel_cache.get (arg, arg_new, pr); + if (!arg_new) { + arg_new = arg; + } + args.push_back (arg_new); + } + } + if (!all_done) continue; + todo.pop_back (); + + expr_ref a_new (m.mk_app (a->get_decl (), args.size (), args.c_ptr ()), m); + + // if a_new is select on m_v, introduce new constant + if (m_arr_u.is_select (a) && + (args.get (0) == m_v || m_has_stores_v.is_marked (args.get (0)))) { + sort* val_sort = get_array_range (m.get_sort (m_v)); + app_ref val_const (m.mk_fresh_const ("sel", val_sort), m); + m_aux_vars.push_back (val_const); + // extend M to include val_const + expr_ref val (m); + m_mev.eval (*M, a_new, val); + M->register_decl (val_const->get_decl (), val); + // add equality + m_aux_lits_v.push_back (m.mk_eq (val_const, a_new)); + // replace select by const + a_new = val_const; + } + + if (a != a_new) { + sel_cache.insert (a, a_new, 0); + pinned.push_back (a_new); + } + done.mark (a, true); + } + expr* res = 0; proof* pr; + sel_cache.get (fml, res, pr); + if (res) { + fml = to_app (res); + } + } + + /** + * convert partial equality expression p_exp to an equality by + * recursively adding stores on diff indices + * + * add stores on lhs or rhs depending on whether stores_on_rhs is false/true + */ + void convert_peq_to_eq (expr* p_exp, app_ref& eq, bool stores_on_rhs = true) { + peq p (to_app (p_exp), m); + app_ref_vector diff_val_consts (m); + p.mk_eq (diff_val_consts, eq, stores_on_rhs); + m_aux_vars.append (diff_val_consts); + // extend M to include diff_val_consts + expr_ref arr (m); + expr_ref_vector I (m); + p.lhs (arr); + p.get_diff_indices (I); + expr_ref val (m); + unsigned num_diff = diff_val_consts.size (); + SASSERT (num_diff == I.size ()); + for (unsigned i = 0; i < num_diff; i++) { + // mk val term + ptr_vector sel_args; + sel_args.push_back (arr); + sel_args.push_back (I.get (i)); + expr_ref val_term (m_arr_u.mk_select (sel_args.size (), sel_args.c_ptr ()), m); + // evaluate and assign to ith diff_val_const + m_mev.eval (*M, val_term, val); + M->register_decl (diff_val_consts.get (i)->get_decl (), val); + } + } + + /** + * mk (e0 ==indices e1) + * + * result has stores if either e0 or e1 or an index term has stores + */ + void mk_peq (expr* e0, expr* e1, unsigned num_indices, expr* const* indices, app_ref& result) { + peq p (e0, e1, num_indices, indices, m); + p.mk_peq (result); + } + + void find_subst_term (app* eq) { + app_ref p_exp (m); + mk_peq (eq->get_arg (0), eq->get_arg (1), 0, 0, p_exp); + bool subst_eq_found = false; + while (true) { + TRACE ("qe", + tout << "processing peq:\n"; + tout << mk_pp (p_exp, m) << "\n"; + ); + + peq p (p_exp, m); + expr_ref lhs (m), rhs (m); + p.lhs (lhs); p.rhs (rhs); + if (!m_has_stores_v.is_marked (lhs)) { + std::swap (lhs, rhs); + } + if (m_has_stores_v.is_marked (lhs)) { + /** project using the equivalence: + * + * (store(arr0,idx,x) ==I arr1) <-> + * + * (idx \in I => (arr0 ==I arr1)) /\ + * (idx \not\in I => (arr0 ==I+idx arr1) /\ (arr1[idx] == x))) + */ + expr_ref_vector I (m); + p.get_diff_indices (I); + app* a_lhs = to_app (lhs); + expr* arr0 = a_lhs->get_arg (0); + expr* idx = a_lhs->get_arg (1); + expr* x = a_lhs->get_arg (2); + expr* arr1 = rhs; + // check if (idx \in I) in M + bool idx_in_I = false; + expr_ref_vector idx_diseq (m); + if (!I.empty ()) { + expr_ref val (m); + m_mev.eval (*M, idx, val); + for (unsigned i = 0; i < I.size () && !idx_in_I; i++) { + if (idx == I.get (i)) { + idx_in_I = true; + } + else { + expr_ref val1 (m); + expr* idx1 = I.get (i); + expr_ref idx_eq (m.mk_eq (idx, idx1), m); + m_mev.eval (*M, idx1, val1); + if (val == val1) { + idx_in_I = true; + m_idx_lits_v.push_back (idx_eq); + } + else { + idx_diseq.push_back (m.mk_not (idx_eq)); + } + } + } + } + if (idx_in_I) { + TRACE ("qe", + tout << "store index in diff indices:\n"; + tout << mk_pp (m_idx_lits_v.back (), m) << "\n"; + ); + + // arr0 ==I arr1 + mk_peq (arr0, arr1, I.size (), I.c_ptr (), p_exp); + + TRACE ("qe", + tout << "new peq:\n"; + tout << mk_pp (p_exp, m) << "\n"; + ); + } + else { + m_idx_lits_v.append (idx_diseq); + // arr0 ==I+idx arr1 + I.push_back (idx); + mk_peq (arr0, arr1, I.size (), I.c_ptr (), p_exp); + + TRACE ("qe", + tout << "new peq:\n"; + tout << mk_pp (p_exp, m) << "\n"; + ); + + // arr1[idx] == x + ptr_vector sel_args; + sel_args.push_back (arr1); + sel_args.push_back (idx); + expr_ref arr1_idx (m_arr_u.mk_select (sel_args.size (), sel_args.c_ptr ()), m); + expr_ref eq (m.mk_eq (arr1_idx, x), m); + m_aux_lits_v.push_back (eq); + + TRACE ("qe", + tout << "new eq:\n"; + tout << mk_pp (eq, m) << "\n"; + ); + } + } + else if (lhs == rhs) { // trivial peq (a ==I a) + break; + } + else if (lhs == m_v || rhs == m_v) { + subst_eq_found = true; + TRACE ("qe", + tout << "subst eq found!\n"; + ); + break; + } + else { + UNREACHABLE (); + } + } + + // factor out select terms on m_v from p_exp using fresh constants + if (subst_eq_found) { + factor_selects (p_exp); + + TRACE ("qe", + tout << "after factoring selects:\n"; + tout << mk_pp (p_exp, m) << "\n"; + for (unsigned i = m_aux_lits_v.size () - m_aux_vars.size (); i < m_aux_lits_v.size (); i++) { + tout << mk_pp (m_aux_lits_v.get (i), m) << "\n"; + } + ); + + // find subst_term + bool stores_on_rhs = true; + app* a = to_app (p_exp); + if (a->get_arg (1) == m_v) { + stores_on_rhs = false; + } + app_ref eq (m); + convert_peq_to_eq (p_exp, eq, stores_on_rhs); + m_subst_term_v = eq->get_arg (1); + + TRACE ("qe", + tout << "subst term found:\n"; + tout << mk_pp (m_subst_term_v, m) << "\n"; + ); + } + } + + /** + * try to substitute for m_v, using array equalities + * + * compute substitution term and aux lits + */ + bool project (expr_ref const& fml) { + expr_ref_vector eqs (m); + ptr_vector true_eqs; // subset of eqs; eqs ensures references + + find_arr_eqs (fml, eqs); + TRACE ("qe", + tout << "array equalities:\n"; + for (unsigned i = 0; i < eqs.size (); i++) { + tout << mk_pp (eqs.get (i), m) << "\n"; + } + ); + + // evaluate eqs in M + for (unsigned i = 0; i < eqs.size (); i++) { + TRACE ("qe", + tout << "array equality:\n"; + tout << mk_pp (eqs.get (i), m) << "\n"; + ); + + expr* eq = eqs.get (i); + + // evaluate eq in M + app* a = to_app (eq); + expr_ref val (m); + m_mev.eval_array_eq (*M, a, a->get_arg (0), a->get_arg (1), val); + if (!val) { + // XXX HACK: unable to evaluate. set to true? + val = m.mk_true (); + } + SASSERT (m.is_true (val) || m.is_false (val)); + + if (m.is_false (val)) { + m_false_sub_v.insert (eq, m.mk_false ()); + } + else { + true_eqs.push_back (to_app (eq)); + } + } + + // compute nesting depths of stores on m_v in true_eqs, as follows: + // 0 if m_v appears on both sides of equality + // 1 if equality is (m_v=t) + // 2 if equality is (store(m_v,i,v)=t) + // ... + unsigned num_true_eqs = true_eqs.size (); + vector nds (num_true_eqs); + for (unsigned i = 0; i < num_true_eqs; i++) { + app* eq = true_eqs.get (i); + expr* lhs = eq->get_arg (0); + expr* rhs = eq->get_arg (1); + bool lhs_has_v = (lhs == m_v || m_has_stores_v.is_marked (lhs)); + bool rhs_has_v = (rhs == m_v || m_has_stores_v.is_marked (rhs)); + app* store = 0; + + SASSERT (lhs_has_v || rhs_has_v); + + if (!lhs_has_v) { + store = to_app (rhs); + } + else if (!rhs_has_v) { + store = to_app (lhs); + } + // else v appears on both sides -- trivial equality + // put it in the beginning to simplify it away + + unsigned nd = 0; // nesting depth + if (store) { + for (nd = 1; m_arr_u.is_store (store); + nd++, store = to_app (store->get_arg (0))) + /* empty */ ; + SASSERT (store == m_v); + } + nds[i] = nd; + } + + SASSERT (true_eqs.size () == nds.size ()); + + // sort true_eqs according to nesting depth + // use insertion sort + for (unsigned i = 1; i < num_true_eqs; i++) { + app_ref eq(m); + eq = true_eqs.get (i); + unsigned nd = nds.get (i); + unsigned j = i; + for (; j >= 1 && nds.get (j-1) > nd; j--) { + true_eqs.set (j, true_eqs.get (j-1)); + nds.set (j, nds.get (j-1)); + } + if (j < i) { + true_eqs.set (j, eq); + nds.set (j, nd); + TRACE ("qe", + tout << "changing eq order!\n"; + ); + } + } + + // search for subst term + for (unsigned i = 0; !m_subst_term_v && i < num_true_eqs; i++) { + app* eq = true_eqs.get (i); + m_true_sub_v.insert (eq, m.mk_true ()); + // try to find subst term + find_subst_term (eq); + } + + return true; + } + + void mk_result (expr_ref& fml) { + th_rewriter rw(m); + rw (fml); + // add in aux_lits and idx_lits + expr_ref_vector lits (m); + // TODO: eliminate possible duplicates, especially in idx_lits + // theory rewriting is a possibility, but not sure if it + // introduces unwanted terms such as ite's + lits.append (m_idx_lits_v); + lits.append (m_aux_lits_v); + lits.push_back (fml); + fml = m.mk_and (lits.size (), lits.c_ptr ()); + + if (m_subst_term_v) { + m_true_sub_v.insert (m_v, m_subst_term_v); + m_true_sub_v (fml); + } + else { + m_true_sub_v (fml); + m_false_sub_v (fml); + } + rw(fml); + SASSERT (!m.is_false (fml)); + } + + public: + + array_project_eqs_util (ast_manager& m): + m (m), + m_arr_u (m), + m_v (m), + m_subst_term_v (m), + m_true_sub_v (m), + m_false_sub_v (m), + m_aux_lits_v (m), + m_idx_lits_v (m), + m_aux_vars (m), + m_mev (m) + {} + + void operator () (model& mdl, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars) { + reset (); + app_ref_vector rem_arr_vars (m); // remaining arr vars + M = &mdl; + + for (unsigned i = 0; i < arr_vars.size (); i++) { + reset_v (); + m_v = arr_vars.get (i); + if (!m_arr_u.is_array (m_v)) { + TRACE ("qe", + tout << "not an array variable: " << mk_pp (m_v, m) << "\n"; + ); + aux_vars.push_back (m_v); + continue; + } + TRACE ("qe", + tout << "projecting equalities on variable: " << mk_pp (m_v, m) << "\n"; + ); + + if (project (fml)) { + mk_result (fml); + + contains_app contains_v (m, m_v); + if (!m_subst_term_v || contains_v (m_subst_term_v)) { + rem_arr_vars.push_back (m_v); + } + TRACE ("qe", + tout << "after projection: \n"; + tout << mk_pp (fml, m) << "\n"; + ); + } + else { + IF_VERBOSE(2, verbose_stream() << "can't project:" << mk_pp(m_v, m) << "\n";); + TRACE ("qe", tout << "Failed to project: " << mk_pp (m_v, m) << "\n";); + rem_arr_vars.push_back(m_v); + } + } + arr_vars.reset (); + arr_vars.append (rem_arr_vars); + aux_vars.append (m_aux_vars); + } + }; + + + class array_select_reducer { + ast_manager& m; + array_util m_arr_u; + obj_map m_cache; + expr_ref_vector m_pinned; // to ensure a reference + expr_ref_vector m_idx_lits; + model_ref M; + model_evaluator_array_util m_mev; + th_rewriter m_rw; + ast_mark m_arr_test; + ast_mark m_has_stores; + bool m_reduce_all_selects; + + void reset () { + m_cache.reset (); + m_pinned.reset (); + m_idx_lits.reset (); + M = 0; + m_arr_test.reset (); + m_has_stores.reset (); + m_reduce_all_selects = false; + } + + bool is_equals (expr *e1, expr *e2) { + if (e1 == e2) return true; + expr_ref val1 (m), val2 (m); + m_mev.eval (*M, e1, val1); + m_mev.eval (*M, e2, val2); + return (val1 == val2); + } + + void add_idx_cond (expr_ref& cond) { + m_rw (cond); + if (!m.is_true (cond)) m_idx_lits.push_back (cond); + } + + bool has_stores (expr* e) { + if (m_reduce_all_selects) return true; + return m_has_stores.is_marked (e); + } + + void mark_stores (app* a, bool args_have_stores) { + if (m_reduce_all_selects) return; + if (args_have_stores || + (m_arr_u.is_store (a) && m_arr_test.is_marked (a->get_arg (0)))) { + m_has_stores.mark (a, true); + } + } + + bool reduce (expr_ref& e) { + if (!is_app (e)) return true; + + expr *r = 0; + if (m_cache.find (e, r)) { + e = r; + return true; + } + + ptr_vector todo; + todo.push_back (to_app (e)); + + while (!todo.empty ()) { + app *a = todo.back (); + unsigned sz = todo.size (); + expr_ref_vector args (m); + bool dirty = false; + bool args_have_stores = false; + + for (unsigned i = 0; i < a->get_num_args (); ++i) { + expr *arg = a->get_arg (i); + expr *narg = 0; + + if (!is_app (arg)) args.push_back (arg); + else if (m_cache.find (arg, narg)) { + args.push_back (narg); + dirty |= (arg != narg); + if (!args_have_stores && has_stores (narg)) { + args_have_stores = true; + } + } + else { + todo.push_back (to_app (arg)); + } + } + + if (todo.size () > sz) continue; + todo.pop_back (); + + if (dirty) { + r = m.mk_app (a->get_decl (), args.size (), args.c_ptr ()); + m_pinned.push_back (r); + } + else r = a; + + if (m_arr_u.is_select (r) && has_stores (to_app (r)->get_arg (0))) { + r = reduce_core (to_app(r)); + } + else { + mark_stores (to_app (r), args_have_stores); + } + + m_cache.insert (a, r); + } + + SASSERT (r); + e = r; + return true; + } + + expr* reduce_core (app *a) { + if (!m_arr_u.is_store (a->get_arg (0))) return a; + + SASSERT (a->get_num_args () == 2 && "Multi-dimensional arrays are not supported"); + expr* array = a->get_arg (0); + expr* j = a->get_arg (1); + + while (m_arr_u.is_store (array)) { + a = to_app (array); + expr* idx = a->get_arg (1); + expr_ref cond (m); + + if (is_equals (idx, j)) { + cond = m.mk_eq (idx, j); + add_idx_cond (cond); + return a->get_arg (2); + } + else { + cond = m.mk_not (m.mk_eq (idx, j)); + add_idx_cond (cond); + array = a->get_arg (0); + } + } + + expr* args[2] = {array, j}; + expr* r = m_arr_u.mk_select (2, args); + m_pinned.push_back (r); + return r; + } + + void mk_result (expr_ref& fml) { + // conjoin idx lits + expr_ref_vector lits (m); + lits.append (m_idx_lits); + lits.push_back (fml); + fml = m.mk_and (lits.size (), lits.c_ptr ()); + // simplify all trivial expressions introduced + m_rw (fml); + + TRACE ("qe", + tout << "after reducing selects:\n"; + tout << mk_pp (fml, m) << "\n"; + ); + } + + public: + + array_select_reducer (ast_manager& m): + m (m), + m_arr_u (m), + m_pinned (m), + m_idx_lits (m), + m_mev (m), + m_rw (m), + m_reduce_all_selects (false) + {} + + void operator () (model& mdl, app_ref_vector const& arr_vars, expr_ref& fml, bool reduce_all_selects = false) { + if (!reduce_all_selects && arr_vars.empty ()) return; + + reset (); + M = &mdl; + m_reduce_all_selects = reduce_all_selects; + + // mark vars to eliminate + for (unsigned i = 0; i < arr_vars.size (); i++) { + m_arr_test.mark (arr_vars.get (i), true); + } + + // assume all arr_vars are of array sort + // and assume no store equalities on arr_vars + if (reduce (fml)) { + mk_result (fml); + } + else { + IF_VERBOSE(2, verbose_stream() << "can't project arrays:" << "\n";); + TRACE ("qe", tout << "Failed to project arrays\n";); + } + } + }; + + class array_project_selects_util { + typedef obj_map*> sel_map; + + ast_manager& m; + array_util m_arr_u; + arith_util m_ari_u; + sel_map m_sel_terms; + // representative indices for eliminating selects + expr_ref_vector m_idx_reprs; + expr_ref_vector m_idx_vals; + app_ref_vector m_sel_consts; + expr_ref_vector m_idx_lits; + model_ref M; + model_evaluator_array_util m_mev; + expr_safe_replace m_sub; + ast_mark m_arr_test; + + void reset () { + m_sel_terms.reset (); + m_idx_reprs.reset (); + m_idx_vals.reset (); + m_sel_consts.reset (); + m_idx_lits.reset (); + M = 0; + m_sub.reset (); + m_arr_test.reset (); + } + + /** + * collect sel terms on array vars as given by m_arr_test + */ + void collect_selects (expr* fml) { + if (!is_app (fml)) return; + ast_mark done; + ptr_vector todo; + todo.push_back (to_app (fml)); + while (!todo.empty ()) { + app* a = todo.back (); + if (done.is_marked (a)) { + todo.pop_back (); + continue; + } + unsigned num_args = a->get_num_args (); + bool all_done = true; + for (unsigned i = 0; i < num_args; i++) { + expr* arg = a->get_arg (i); + if (!done.is_marked (arg) && is_app (arg)) { + todo.push_back (to_app (arg)); + all_done = false; + } + } + if (!all_done) continue; + todo.pop_back (); + if (m_arr_u.is_select (a)) { + expr* arr = a->get_arg (0); + if (m_arr_test.is_marked (arr)) { + ptr_vector* lst = m_sel_terms.find (to_app (arr));; + lst->push_back (a); + } + } + done.mark (a, true); + } + } + + /** + * model based ackermannization for sel terms of some array + * + * update sub with val consts for sel terms + */ + void ackermann (ptr_vector const& sel_terms) { + if (sel_terms.empty ()) return; + + expr* v = sel_terms.get (0)->get_arg (0); // array variable + sort* v_sort = m.get_sort (v); + sort* val_sort = get_array_range (v_sort); + sort* idx_sort = get_array_domain (v_sort, 0); + + unsigned start = m_idx_reprs.size (); // append at the end + + for (unsigned i = 0; i < sel_terms.size (); i++) { + app* a = sel_terms.get (i); + expr* idx = a->get_arg (1); + expr_ref val (m); + m_mev.eval (*M, idx, val); + + bool is_new = true; + for (unsigned j = start; j < m_idx_vals.size (); j++) { + if (m_idx_vals.get (j) == val) { + // idx belongs to the jth equivalence class; + // substitute sel term with ith sel const + expr* c = m_sel_consts.get (j); + m_sub.insert (a, c); + // add equality (idx == repr) + expr* repr = m_idx_reprs.get (j); + m_idx_lits.push_back (m.mk_eq (idx, repr)); + + is_new = false; + break; + } + } + if (is_new) { + // new repr, val, and sel const + m_idx_reprs.push_back (idx); + m_idx_vals.push_back (val); + app_ref c (m.mk_fresh_const ("sel", val_sort), m); + m_sel_consts.push_back (c); + // substitute sel term with new const + m_sub.insert (a, c); + // extend M to include c + m_mev.eval (*M, a, val); + M->register_decl (c->get_decl (), val); + } + } + + // sort reprs by their value and add a chain of strict inequalities + + unsigned num_reprs = m_idx_reprs.size () - start; + if (num_reprs == 0) return; + + SASSERT ((m_ari_u.is_real (idx_sort) || m_ari_u.is_int (idx_sort)) + && "Unsupported index sort: neither real nor int"); + + // using insertion sort + unsigned end = start + num_reprs; + for (unsigned i = start+1; i < end; i++) { + expr_ref repr(m), val(m); + repr = m_idx_reprs.get (i); + val = m_idx_vals.get (i); + unsigned j = i; + for (; j > start; j--) { + rational j_val, jm1_val; + VERIFY (m_ari_u.is_numeral (val, j_val)); + VERIFY (m_ari_u.is_numeral (m_idx_vals.get (j-1), jm1_val)); + if (j_val >= jm1_val) break; + m_idx_reprs[j] = m_idx_reprs.get (j-1); + m_idx_vals[j] = m_idx_vals.get (j-1); + } + m_idx_reprs[j] = repr; + m_idx_vals[j] = val; + } + + for (unsigned i = start; i < end-1; i++) { + m_idx_lits.push_back (m_ari_u.mk_lt (m_idx_reprs.get (i), + m_idx_reprs.get (i+1))); + } + } + + void mk_result (expr_ref& fml) { + // conjoin idx lits + expr_ref_vector lits (m); + lits.append (m_idx_lits); + lits.push_back (fml); + fml = m.mk_and (lits.size (), lits.c_ptr ()); + + // substitute for sel terms + m_sub (fml); + + TRACE ("qe", + tout << "after projection of selects:\n"; + tout << mk_pp (fml, m) << "\n"; + ); + } + + /** + * project selects + * populates idx lits and obtains substitution for sel terms + */ + bool project (expr_ref& fml) { + // collect sel terms -- populate the map m_sel_terms + collect_selects (fml); + + // model based ackermannization + sel_map::iterator begin = m_sel_terms.begin (), + end = m_sel_terms.end (); + for (sel_map::iterator it = begin; it != end; it++) { + TRACE ("qe", + tout << "ackermann for var: " << mk_pp (it->m_key, m) << "\n"; + ); + ackermann (*(it->m_value)); + } + + TRACE ("qe", + tout << "idx lits:\n"; + for (unsigned i = 0; i < m_idx_lits.size (); i++) { + tout << mk_pp (m_idx_lits.get (i), m) << "\n"; + } + ); + + return true; + } + + public: + + array_project_selects_util (ast_manager& m): + m (m), + m_arr_u (m), + m_ari_u (m), + m_idx_reprs (m), + m_idx_vals (m), + m_sel_consts (m), + m_idx_lits (m), + m_mev (m), + m_sub (m) + {} + + void operator () (model& mdl, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars) { + reset (); + M = &mdl; + + // mark vars to eliminate + for (unsigned i = 0; i < arr_vars.size (); i++) { + m_arr_test.mark (arr_vars.get (i), true); + } + + // alloc empty map from array var to sel terms over it + for (unsigned i = 0; i < arr_vars.size (); i++) { + ptr_vector* lst = alloc (ptr_vector); + m_sel_terms.insert (arr_vars.get (i), lst); + } + + // assume all arr_vars are of array sort + // and they only appear in select terms + if (project (fml)) { + mk_result (fml); + aux_vars.append (m_sel_consts); + arr_vars.reset (); + } + else { + IF_VERBOSE(2, verbose_stream() << "can't project arrays:" << "\n";); + TRACE ("qe", tout << "Failed to project arrays\n";); + } + + // dealloc + sel_map::iterator begin = m_sel_terms.begin (), + end = m_sel_terms.end (); + for (sel_map::iterator it = begin; it != end; it++) { + dealloc (it->m_value); + } + m_sel_terms.reset (); + } + }; + + expr_ref arith_project(model& mdl, app_ref_vector& vars, expr_ref_vector const& lits) { + ast_manager& m = vars.get_manager(); + arith_project_util ap(m); + return ap(mdl, vars, lits); + } + + void arith_project(model& mdl, app_ref_vector& vars, expr_ref& fml) { + ast_manager& m = vars.get_manager(); + arith_project_util ap(m); + atom_set pos_lits, neg_lits; + is_relevant_default is_relevant; + mk_atom_default mk_atom; + get_nnf (fml, is_relevant, mk_atom, pos_lits, neg_lits); + ap(mdl, vars, fml); + } + + void arith_project(model& mdl, app_ref_vector& vars, expr_ref& fml, expr_map& map) { + ast_manager& m = vars.get_manager(); + arith_project_util ap(m); + atom_set pos_lits, neg_lits; + is_relevant_default is_relevant; + mk_atom_default mk_atom; + get_nnf (fml, is_relevant, mk_atom, pos_lits, neg_lits); + ap(mdl, vars, fml, map); + } + + void array_project_eqs (model& mdl, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars) { + ast_manager& m = arr_vars.get_manager (); + array_project_eqs_util ap (m); + ap (mdl, arr_vars, fml, aux_vars); + } + + void reduce_array_selects (model& mdl, app_ref_vector const& arr_vars, expr_ref& fml, bool reduce_all_selects) { + ast_manager& m = arr_vars.get_manager (); + array_select_reducer ap (m); + ap (mdl, arr_vars, fml, reduce_all_selects); + } + + void reduce_array_selects (model& mdl, expr_ref& fml) { + ast_manager& m = fml.get_manager (); + app_ref_vector _tmp (m); + reduce_array_selects (mdl, _tmp, fml, true); + } + + void array_project_selects (model& mdl, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars) { + ast_manager& m = arr_vars.get_manager (); + array_project_selects_util ap (m); + ap (mdl, arr_vars, fml, aux_vars); + } + + void array_project (model& mdl, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars, bool reduce_all_selects) { + // 1. project array equalities + array_project_eqs (mdl, arr_vars, fml, aux_vars); + TRACE ("qe", + ast_manager& m = fml.get_manager (); + tout << "Projected array eqs:\n" << mk_pp (fml, m) << "\n"; + tout << "Remaining array vars:\n"; + for (unsigned i = 0; i < arr_vars.size (); i++) { + tout << mk_pp (arr_vars.get (i), m) << "\n"; + } + tout << "Aux vars:\n"; + for (unsigned i = 0; i < aux_vars.size (); i++) { + tout << mk_pp (aux_vars.get (i), m) << "\n"; + } + ); + + // 2. reduce selects + if (reduce_all_selects) { + reduce_array_selects (mdl, fml); + } + else { + reduce_array_selects (mdl, arr_vars, fml); + } + TRACE ("qe", + ast_manager& m = fml.get_manager (); + tout << "Reduced selects:\n" << mk_pp (fml, m) << "\n"; + ); + + // 3. project selects using model based ackermannization + array_project_selects (mdl, arr_vars, fml, aux_vars); + TRACE ("qe", + ast_manager& m = fml.get_manager (); + tout << "Projected array selects:\n" << mk_pp (fml, m) << "\n"; + tout << "All aux vars:\n"; + for (unsigned i = 0; i < aux_vars.size (); i++) { + tout << mk_pp (aux_vars.get (i), m) << "\n"; + } + ); + } + +} diff --git a/src/muz/spacer/spacer_qe_project.h b/src/muz/spacer/spacer_qe_project.h new file mode 100644 index 000000000..6074f0d91 --- /dev/null +++ b/src/muz/spacer/spacer_qe_project.h @@ -0,0 +1,49 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_qe_project.h + +Abstract: + + Model-based projection + +Author: + + Anvesh Komuravelli + Arie Gurfinkel (arie) + +Notes: + +--*/ +#ifndef SPACER_QE_PROJECT_H_ +#define SPACER_QE_PROJECT_H_ + +#include "model.h" +#include "expr_map.h" + +namespace qe { + /** + Loos-Weispfenning model-based projection for a basic conjunction. + Lits is a vector of literals. + return vector of variables that could not be projected. + */ + expr_ref arith_project(model& model, app_ref_vector& vars, expr_ref_vector const& lits); + + void arith_project(model& model, app_ref_vector& vars, expr_ref& fml); + + void arith_project(model& model, app_ref_vector& vars, expr_ref& fml, expr_map& map); + + void array_project_eqs (model& model, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars); + + void reduce_array_selects (model& mdl, app_ref_vector const& arr_vars, expr_ref& fml, bool reduce_all_selects = false); + + void reduce_array_selects (model& mdl, expr_ref& fml); + + void array_project_selects (model& model, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars); + + void array_project (model& model, app_ref_vector& arr_vars, expr_ref& fml, app_ref_vector& aux_vars, bool reduce_all_selects = false); +}; + +#endif diff --git a/src/muz/spacer/spacer_smt_context_manager.cpp b/src/muz/spacer/spacer_smt_context_manager.cpp new file mode 100644 index 000000000..f5e5ba9c1 --- /dev/null +++ b/src/muz/spacer/spacer_smt_context_manager.cpp @@ -0,0 +1,79 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_smt_context_manager.cpp + +Abstract: + + Manager of smt contexts + +Author: + + Nikolaj Bjorner (nbjorner) 2011-11-26. + Arie Gurfinkel +Revision History: + +--*/ + +#include "spacer_smt_context_manager.h" +#include "has_free_vars.h" +#include "ast_pp.h" +#include "ast_smt_pp.h" +#include +#include "smt_params.h" + +#include "ast_pp_util.h" +#include "smt_context.h" +#include "spacer_util.h" +namespace spacer { + + + + +smt_context_manager::smt_context_manager(ast_manager &m, + unsigned max_num_contexts, + const params_ref &p) : + m_fparams(p), + m(m), + m_max_num_contexts(max_num_contexts), + m_num_contexts(0) { m_stats.reset();} + + +smt_context_manager::~smt_context_manager() +{ + std::for_each(m_solvers.begin(), m_solvers.end(), + delete_proc()); +} + +virtual_solver* smt_context_manager::mk_fresh() +{ + ++m_num_contexts; + virtual_solver_factory *solver_factory = 0; + + if (m_max_num_contexts == 0 || m_solvers.size() < m_max_num_contexts) { + m_solvers.push_back(alloc(spacer::virtual_solver_factory, m, m_fparams)); + solver_factory = m_solvers.back(); + } else + { solver_factory = m_solvers[(m_num_contexts - 1) % m_max_num_contexts]; } + + return solver_factory->mk_solver(); +} + +void smt_context_manager::collect_statistics(statistics& st) const +{ + for (unsigned i = 0; i < m_solvers.size(); ++i) { + m_solvers[i]->collect_statistics(st); + } +} + +void smt_context_manager::reset_statistics() +{ + for (unsigned i = 0; i < m_solvers.size(); ++i) { + m_solvers[i]->reset_statistics(); + } +} + + +}; diff --git a/src/muz/spacer/spacer_smt_context_manager.h b/src/muz/spacer/spacer_smt_context_manager.h new file mode 100644 index 000000000..fd04eaf4e --- /dev/null +++ b/src/muz/spacer/spacer_smt_context_manager.h @@ -0,0 +1,68 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_smt_context_manager.h + +Abstract: + + Manager of smt contexts + +Author: + + Nikolaj Bjorner (nbjorner) 2011-11-26. + Arie Gurfinkel +Revision History: + +--*/ + +#ifndef _SPACER_SMT_CONTEXT_MANAGER_H_ +#define _SPACER_SMT_CONTEXT_MANAGER_H_ + +#include "smt_kernel.h" +#include "func_decl_dependencies.h" +#include "dl_util.h" +#include "spacer_virtual_solver.h" +#include "stopwatch.h" + +namespace spacer { + +class smt_context_manager { + + struct stats { + unsigned m_num_smt_checks; + unsigned m_num_sat_smt_checks; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + + smt_params m_fparams; + ast_manager& m; + unsigned m_max_num_contexts; + ptr_vector m_solvers; + unsigned m_num_contexts; + + + stats m_stats; + stopwatch m_check_watch; + stopwatch m_check_sat_watch; + +public: + smt_context_manager(ast_manager& m, unsigned max_num_contexts = 1, + const params_ref &p = params_ref::get_empty()); + + ~smt_context_manager(); + virtual_solver* mk_fresh(); + + void collect_statistics(statistics& st) const; + void reset_statistics(); + + void updt_params(params_ref const &p) { m_fparams.updt_params(p); } + smt_params& fparams() {return m_fparams;} + +}; + +}; + +#endif diff --git a/src/muz/spacer/spacer_sym_mux.cpp b/src/muz/spacer/spacer_sym_mux.cpp new file mode 100644 index 000000000..659aea2cc --- /dev/null +++ b/src/muz/spacer/spacer_sym_mux.cpp @@ -0,0 +1,608 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + sym_mux.cpp + +Abstract: + + A symbol multiplexer that helps with having multiple versions of each of a set of symbols. + +Author: + + Krystof Hoder (t-khoder) 2011-9-8. + +Revision History: + +--*/ + +#include +#include "ast_pp.h" +#include "for_each_expr.h" +#include "model.h" +#include "rewriter.h" +#include "rewriter_def.h" +#include "spacer_util.h" +#include "spacer_sym_mux.h" + +using namespace spacer; + +sym_mux::sym_mux(ast_manager & m, const std::vector & suffixes) + : m(m), m_ref_holder(m), m_next_sym_suffix_idx(0), m_suffixes(suffixes) +{ + unsigned suf_sz = m_suffixes.size(); + for (unsigned i = 0; i < suf_sz; ++i) { + symbol suff_sym = symbol(m_suffixes[i].c_str()); + m_used_suffixes.insert(suff_sym); + } +} + +std::string sym_mux::get_suffix(unsigned i) const +{ + while (m_suffixes.size() <= i) { + std::string new_suffix; + symbol new_syffix_sym; + do { + std::stringstream stm; + stm << '_' << m_next_sym_suffix_idx; + m_next_sym_suffix_idx++; + new_suffix = stm.str(); + new_syffix_sym = symbol(new_suffix.c_str()); + } while (m_used_suffixes.contains(new_syffix_sym)); + m_used_suffixes.insert(new_syffix_sym); + m_suffixes.push_back(new_suffix); + } + return m_suffixes[i]; +} + +void sym_mux::create_tuple(func_decl* prefix, unsigned arity, sort * const * domain, sort * range, + unsigned tuple_length, decl_vector & tuple) +{ + SASSERT(tuple_length > 0); + while (tuple.size() < tuple_length) { + tuple.push_back(0); + } + SASSERT(tuple.size() == tuple_length); + std::string pre = prefix->get_name().str(); + for (unsigned i = 0; i < tuple_length; i++) { + + if (tuple[i] != 0) { + SASSERT(tuple[i]->get_arity() == arity); + SASSERT(tuple[i]->get_range() == range); + //domain should match as well, but we won't bother checking an array equality + } else { + std::string name = pre + get_suffix(i); + tuple[i] = m.mk_func_decl(symbol(name.c_str()), arity, domain, range); + } + m_ref_holder.push_back(tuple[i]); + m_sym2idx.insert(tuple[i], i); + m_sym2prim.insert(tuple[i], tuple[0]); + } + + m_prim2all.insert(tuple[0], tuple); + m_prefix2prim.insert(prefix, tuple[0]); + m_prim2prefix.insert(tuple[0], prefix); + m_prim_preds.push_back(tuple[0]); + m_ref_holder.push_back(prefix); +} + +void sym_mux::ensure_tuple_size(func_decl * prim, unsigned sz) const +{ + SASSERT(m_prim2all.contains(prim)); + decl_vector& tuple = m_prim2all.find_core(prim)->get_data().m_value; + SASSERT(tuple[0] == prim); + + if (sz <= tuple.size()) { return; } + + func_decl * prefix; + TRUSTME(m_prim2prefix.find(prim, prefix)); + std::string prefix_name = prefix->get_name().bare_str(); + for (unsigned i = tuple.size(); i < sz; ++i) { + std::string name = prefix_name + get_suffix(i); + func_decl * new_sym = m.mk_func_decl(symbol(name.c_str()), prefix->get_arity(), + prefix->get_domain(), prefix->get_range()); + + tuple.push_back(new_sym); + m_ref_holder.push_back(new_sym); + m_sym2idx.insert(new_sym, i); + m_sym2prim.insert(new_sym, prim); + } +} + +func_decl * sym_mux::conv(func_decl * sym, unsigned src_idx, unsigned tgt_idx) const +{ + if (src_idx == tgt_idx) { return sym; } + func_decl * prim = (src_idx == 0) ? sym : get_primary(sym); + if (tgt_idx > src_idx) { + ensure_tuple_size(prim, tgt_idx + 1); + } + decl_vector & sym_vect = m_prim2all.find_core(prim)->get_data().m_value; + SASSERT(sym_vect[src_idx] == sym); + return sym_vect[tgt_idx]; +} + + +func_decl * sym_mux::get_or_create_symbol_by_prefix(func_decl* prefix, unsigned idx, + unsigned arity, sort * const * domain, sort * range) +{ + func_decl * prim = try_get_primary_by_prefix(prefix); + if (prim) { + SASSERT(prim->get_arity() == arity); + SASSERT(prim->get_range() == range); + //domain should match as well, but we won't bother checking an array equality + + return conv(prim, 0, idx); + } + + decl_vector syms; + create_tuple(prefix, arity, domain, range, idx + 1, syms); + return syms[idx]; +} + +bool sym_mux::is_muxed_lit(expr * e, unsigned idx) const +{ + if (!is_app(e)) { return false; } + app * a = to_app(e); + if (m.is_not(a) && is_app(a->get_arg(0))) { + a = to_app(a->get_arg(0)); + } + return is_muxed(a->get_decl()); +} + + +struct sym_mux::formula_checker { + formula_checker(const sym_mux & parent, bool all, unsigned idx) : + m_parent(parent), m_all(all), m_idx(idx), + m_found_what_needed(false) + { + } + + void operator()(expr * e) + { + if (m_found_what_needed || !is_app(e)) { return; } + + func_decl * sym = to_app(e)->get_decl(); + unsigned sym_idx; + if (!m_parent.try_get_index(sym, sym_idx)) { return; } + + bool have_idx = sym_idx == m_idx; + + if (m_all ? (!have_idx) : have_idx) { + m_found_what_needed = true; + } + + } + + bool all_have_idx() const + { + SASSERT(m_all); //we were looking for the queried property + return !m_found_what_needed; + } + + bool some_with_idx() const + { + SASSERT(!m_all); //we were looking for the queried property + return m_found_what_needed; + } + +private: + const sym_mux & m_parent; + bool m_all; + unsigned m_idx; + + /** + If we check whether all muxed symbols are of given index, we look for + counter-examples, checking whether form contains a muxed symbol of an index, + we look for symbol of index m_idx. + */ + bool m_found_what_needed; +}; + +bool sym_mux::contains(expr * e, unsigned idx) const +{ + formula_checker chck(*this, false, idx); + for_each_expr(chck, m_visited, e); + m_visited.reset(); + return chck.some_with_idx(); +} + +bool sym_mux::is_homogenous_formula(expr * e, unsigned idx) const +{ + formula_checker chck(*this, true, idx); + for_each_expr(chck, m_visited, e); + m_visited.reset(); + return chck.all_have_idx(); +} + +bool sym_mux::is_homogenous(const expr_ref_vector & vect, unsigned idx) const +{ + expr * const * begin = vect.c_ptr(); + expr * const * end = begin + vect.size(); + for (expr * const * it = begin; it != end; it++) { + if (!is_homogenous_formula(*it, idx)) { + return false; + } + } + return true; +} + +class sym_mux::index_collector { + sym_mux const& m_parent; + svector m_indices; +public: + index_collector(sym_mux const& s): + m_parent(s) {} + + void operator()(expr * e) + { + if (is_app(e)) { + func_decl * sym = to_app(e)->get_decl(); + unsigned idx; + if (m_parent.try_get_index(sym, idx)) { + SASSERT(idx > 0); + --idx; + if (m_indices.size() <= idx) { + m_indices.resize(idx + 1, false); + } + m_indices[idx] = true; + } + } + } + + void extract(unsigned_vector& indices) + { + for (unsigned i = 0; i < m_indices.size(); ++i) { + if (m_indices[i]) { + indices.push_back(i); + } + } + } +}; + + + +void sym_mux::collect_indices(expr* e, unsigned_vector& indices) const +{ + indices.reset(); + index_collector collector(*this); + for_each_expr(collector, m_visited, e); + m_visited.reset(); + collector.extract(indices); +} + +class sym_mux::variable_collector { + sym_mux const& m_parent; + vector >& m_vars; +public: + variable_collector(sym_mux const& s, vector >& vars): + m_parent(s), m_vars(vars) {} + + void operator()(expr * e) + { + if (is_app(e)) { + func_decl * sym = to_app(e)->get_decl(); + unsigned idx; + if (m_parent.try_get_index(sym, idx)) { + SASSERT(idx > 0); + --idx; + if (m_vars.size() <= idx) { + m_vars.resize(idx + 1, ptr_vector()); + } + m_vars[idx].push_back(to_app(e)); + } + } + } +}; + +void sym_mux::collect_variables(expr* e, vector >& vars) const +{ + vars.reset(); + variable_collector collector(*this, vars); + for_each_expr(collector, m_visited, e); + m_visited.reset(); +} + +class sym_mux::hmg_checker { + const sym_mux & m_parent; + + bool m_found_idx; + unsigned m_idx; + bool m_multiple_indexes; + +public: + hmg_checker(const sym_mux & parent) : + m_parent(parent), m_found_idx(false), m_multiple_indexes(false) + { + } + + void operator()(expr * e) + { + if (m_multiple_indexes || !is_app(e)) { return; } + + func_decl * sym = to_app(e)->get_decl(); + unsigned sym_idx; + if (!m_parent.try_get_index(sym, sym_idx)) { return; } + + if (!m_found_idx) { + m_found_idx = true; + m_idx = sym_idx; + return; + } + if (m_idx == sym_idx) { return; } + m_multiple_indexes = true; + } + + bool has_multiple_indexes() const + { + return m_multiple_indexes; + } +}; + +bool sym_mux::is_homogenous_formula(expr * e) const +{ + hmg_checker chck(*this); + for_each_expr(chck, m_visited, e); + m_visited.reset(); + return !chck.has_multiple_indexes(); +} + + +struct sym_mux::conv_rewriter_cfg : public default_rewriter_cfg { +private: + ast_manager & m; + const sym_mux & m_parent; + unsigned m_from_idx; + unsigned m_to_idx; + bool m_homogenous; +public: + conv_rewriter_cfg(const sym_mux & parent, unsigned from_idx, unsigned to_idx, bool homogenous) + : m(parent.get_manager()), + m_parent(parent), + m_from_idx(from_idx), + m_to_idx(to_idx), + m_homogenous(homogenous) {} + + bool get_subst(expr * s, expr * & t, proof * & t_pr) + { + if (!is_app(s)) { return false; } + app * a = to_app(s); + func_decl * sym = a->get_decl(); + if (!m_parent.has_index(sym, m_from_idx)) { + SASSERT(!m_homogenous || !m_parent.is_muxed(sym)); + return false; + } + func_decl * tgt = m_parent.conv(sym, m_from_idx, m_to_idx); + + t = m.mk_app(tgt, a->get_args()); + return true; + } +}; + +void sym_mux::conv_formula(expr * f, unsigned src_idx, unsigned tgt_idx, expr_ref & res, bool homogenous) const +{ + if (src_idx == tgt_idx) { + res = f; + return; + } + conv_rewriter_cfg r_cfg(*this, src_idx, tgt_idx, homogenous); + rewriter_tpl rwr(m, false, r_cfg); + rwr(f, res); +} + +struct sym_mux::shifting_rewriter_cfg : public default_rewriter_cfg { +private: + ast_manager & m; + const sym_mux & m_parent; + int m_shift; +public: + shifting_rewriter_cfg(const sym_mux & parent, int shift) + : m(parent.get_manager()), + m_parent(parent), + m_shift(shift) {} + + bool get_subst(expr * s, expr * & t, proof * & t_pr) + { + if (!is_app(s)) { return false; } + app * a = to_app(s); + func_decl * sym = a->get_decl(); + + unsigned idx; + if (!m_parent.try_get_index(sym, idx)) { + return false; + } + SASSERT(static_cast(idx) + m_shift >= 0); + func_decl * tgt = m_parent.conv(sym, idx, idx + m_shift); + t = m.mk_app(tgt, a->get_args()); + return true; + } +}; + +void sym_mux::shift_formula(expr * f, int dist, expr_ref & res) const +{ + if (dist == 0) { + res = f; + return; + } + shifting_rewriter_cfg r_cfg(*this, dist); + rewriter_tpl rwr(m, false, r_cfg); + rwr(f, res); +} + +void sym_mux::conv_formula_vector(const expr_ref_vector & vect, unsigned src_idx, unsigned tgt_idx, + expr_ref_vector & res) const +{ + res.reset(); + expr * const * begin = vect.c_ptr(); + expr * const * end = begin + vect.size(); + for (expr * const * it = begin; it != end; it++) { + expr_ref converted(m); + conv_formula(*it, src_idx, tgt_idx, converted); + res.push_back(converted); + } +} + +void sym_mux::filter_idx(expr_ref_vector & vect, unsigned idx) const +{ + unsigned i = 0; + while (i < vect.size()) { + expr* e = vect[i].get(); + if (contains(e, idx) && is_homogenous_formula(e, idx)) { + i++; + } else { + //we don't allow mixing states inside vector elements + SASSERT(!contains(e, idx)); + vect[i] = vect.back(); + vect.pop_back(); + } + } +} + +void sym_mux::partition_o_idx( + expr_ref_vector const& lits, + expr_ref_vector& o_lits, + expr_ref_vector& other, unsigned idx) const +{ + + for (unsigned i = 0; i < lits.size(); ++i) { + if (contains(lits[i], idx) && is_homogenous_formula(lits[i], idx)) { + o_lits.push_back(lits[i]); + } else { + other.push_back(lits[i]); + } + } +} + + + +class sym_mux::nonmodel_sym_checker { + const sym_mux & m_parent; + + bool m_found; +public: + nonmodel_sym_checker(const sym_mux & parent) : + m_parent(parent), m_found(false) + { + } + + void operator()(expr * e) + { + if (m_found || !is_app(e)) { return; } + + func_decl * sym = to_app(e)->get_decl(); + + if (m_parent.is_non_model_sym(sym)) { + m_found = true; + } + } + + bool found() const + { + return m_found; + } +}; + +bool sym_mux::has_nonmodel_symbol(expr * e) const +{ + nonmodel_sym_checker chck(*this); + for_each_expr(chck, e); + return chck.found(); +} + +void sym_mux::filter_non_model_lits(expr_ref_vector & vect) const +{ + unsigned i = 0; + while (i < vect.size()) { + if (!has_nonmodel_symbol(vect[i].get())) { + i++; + continue; + } + vect[i] = vect.back(); + vect.pop_back(); + } +} + +class sym_mux::decl_idx_comparator { + const sym_mux & m_parent; +public: + decl_idx_comparator(const sym_mux & parent) + : m_parent(parent) + { } + + bool operator()(func_decl * sym1, func_decl * sym2) + { + unsigned idx1, idx2; + if (!m_parent.try_get_index(sym1, idx1)) { idx1 = UINT_MAX; } + if (!m_parent.try_get_index(sym2, idx2)) { idx2 = UINT_MAX; } + + if (idx1 != idx2) { return idx1 < idx2; } + return lt(sym1->get_name(), sym2->get_name()); + } +}; + +std::string sym_mux::pp_model(const model_core & mdl) const +{ + decl_vector consts; + unsigned sz = mdl.get_num_constants(); + for (unsigned i = 0; i < sz; i++) { + func_decl * d = mdl.get_constant(i); + consts.push_back(d); + } + + std::sort(consts.begin(), consts.end(), decl_idx_comparator(*this)); + + std::stringstream res; + + decl_vector::iterator end = consts.end(); + for (decl_vector::iterator it = consts.begin(); it != end; it++) { + func_decl * d = *it; + std::string name = d->get_name().str(); + const char * arrow = " -> "; + res << name << arrow; + unsigned indent = static_cast(name.length() + strlen(arrow)); + res << mk_pp(mdl.get_const_interp(d), m, indent) << "\n"; + + if (it + 1 != end) { + unsigned idx1, idx2; + if (!try_get_index(*it, idx1)) { idx1 = UINT_MAX; } + if (!try_get_index(*(it + 1), idx2)) { idx2 = UINT_MAX; } + if (idx1 != idx2) { res << "\n"; } + } + } + return res.str(); +} + + +#if 0 + +class sym_mux::index_renamer_cfg : public default_rewriter_cfg { + const sym_mux & m_parent; + unsigned m_idx; + +public: + index_renamer_cfg(const sym_mux & p, unsigned idx) : m_parent(p), m_idx(idx) {} + + bool get_subst(expr * s, expr * & t, proof * & t_pr) + { + if (!is_app(s)) { return false; } + app * a = to_app(s); + if (a->get_family_id() != null_family_id) { + return false; + } + func_decl * sym = a->get_decl(); + unsigned idx; + if (!m_parent.try_get_index(sym, idx)) { + return false; + } + if (m_idx == idx) { + return false; + } + ast_manager& m = m_parent.get_manager(); + symbol name = symbol((sym->get_name().str() + "!").c_str()); + func_decl * tgt = m.mk_func_decl(name, sym->get_arity(), sym->get_domain(), sym->get_range()); + t = m.mk_app(tgt, a->get_num_args(), a->get_args()); + return true; + } +}; + +#endif diff --git a/src/muz/spacer/spacer_sym_mux.h b/src/muz/spacer/spacer_sym_mux.h new file mode 100644 index 000000000..d9bae95a3 --- /dev/null +++ b/src/muz/spacer/spacer_sym_mux.h @@ -0,0 +1,256 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + sym_mux.h + +Abstract: + + A symbol multiplexer that helps with having multiple versions of each of a set of symbols. + +Author: + + Krystof Hoder (t-khoder) 2011-9-8. + +Revision History: + +--*/ + +#ifndef _SYM_MUX_H_ +#define _SYM_MUX_H_ + +#include "ast.h" +#include "map.h" +#include "vector.h" +#include + +class model_core; + +namespace spacer { +class sym_mux { +public: + typedef ptr_vector app_vector; + typedef ptr_vector decl_vector; +private: + typedef obj_map sym2u; + typedef obj_map sym2dv; + typedef obj_map sym2sym; + typedef obj_map sym2pred; + typedef hashtable symbols; + + ast_manager & m; + mutable ast_ref_vector m_ref_holder; + mutable expr_mark m_visited; + + mutable unsigned m_next_sym_suffix_idx; + mutable symbols m_used_suffixes; + /** Here we have default suffixes for each of the variants */ + mutable std::vector m_suffixes; + + + /** + Primary symbol is the 0-th variant. This member maps from primary symbol + to vector of all its variants (including the primary variant). + */ + sym2dv m_prim2all; + + /** + For each symbol contains its variant index + */ + mutable sym2u m_sym2idx; + /** + For each symbol contains its primary variant + */ + mutable sym2sym m_sym2prim; + + /** + Maps prefixes passed to the create_tuple to + the primary symbol created from it. + */ + sym2pred m_prefix2prim; + + /** + Maps pripary symbols to prefixes that were used to create them. + */ + sym2sym m_prim2prefix; + + decl_vector m_prim_preds; + + obj_hashtable m_non_model_syms; + + struct formula_checker; + struct conv_rewriter_cfg; + struct shifting_rewriter_cfg; + class decl_idx_comparator; + class hmg_checker; + class nonmodel_sym_checker; + class index_renamer_cfg; + class index_collector; + class variable_collector; + + std::string get_suffix(unsigned i) const; + void ensure_tuple_size(func_decl * prim, unsigned sz) const; + + expr_ref isolate_o_idx(expr* e, unsigned idx) const; +public: + sym_mux(ast_manager & m, const std::vector & suffixes); + + ast_manager & get_manager() const { return m; } + + bool is_muxed(func_decl * sym) const { return m_sym2idx.contains(sym); } + + bool try_get_index(func_decl * sym, unsigned & idx) const + { + return m_sym2idx.find(sym, idx); + } + + bool has_index(func_decl * sym, unsigned idx) const + { + unsigned actual_idx; + return try_get_index(sym, actual_idx) && idx == actual_idx; + } + + /** Return primary symbol. sym must be muxed. */ + func_decl * get_primary(func_decl * sym) const + { + func_decl * prim; + TRUSTME(m_sym2prim.find(sym, prim)); + return prim; + } + + /** + Return primary symbol created from prefix, or 0 if the prefix was never used. + */ + func_decl * try_get_primary_by_prefix(func_decl* prefix) const + { + func_decl * res; + if(!m_prefix2prim.find(prefix, res)) { + return 0; + } + return res; + } + + /** + Return symbol created from prefix, or 0 if the prefix was never used. + */ + func_decl * try_get_by_prefix(func_decl* prefix, unsigned idx) const + { + func_decl * prim = try_get_primary_by_prefix(prefix); + if(!prim) { + return 0; + } + return conv(prim, 0, idx); + } + + /** + Marks symbol as non-model which means it will not appear in models collected by + get_muxed_cube_from_model function. + This is to take care of auxiliary symbols introduced by the disjunction relations + to relativize lemmas coming from disjuncts. + */ + void mark_as_non_model(func_decl * sym) + { + SASSERT(is_muxed(sym)); + m_non_model_syms.insert(get_primary(sym)); + } + + func_decl * get_or_create_symbol_by_prefix(func_decl* prefix, unsigned idx, + unsigned arity, sort * const * domain, sort * range); + + + + bool is_muxed_lit(expr * e, unsigned idx) const; + + bool is_non_model_sym(func_decl * s) const + { + return is_muxed(s) && m_non_model_syms.contains(get_primary(s)); + } + + /** + Create a multiplexed tuple of propositional constants. + Symbols may be suplied in the tuple vector, + those beyond the size of the array and those with corresponding positions + assigned to zero will be created using prefix. + Tuple length must be at least one. + */ + void create_tuple(func_decl* prefix, unsigned arity, sort * const * domain, sort * range, + unsigned tuple_length, decl_vector & tuple); + + /** + Return true if the only multiplexed symbols which e contains are of index idx. + */ + bool is_homogenous_formula(expr * e, unsigned idx) const; + bool is_homogenous(const expr_ref_vector & vect, unsigned idx) const; + + /** + Return true if all multiplexed symbols which e contains are of one index. + */ + bool is_homogenous_formula(expr * e) const; + + /** + Return true if expression e contains a muxed symbol of index idx. + */ + bool contains(expr * e, unsigned idx) const; + + /** + Collect indices used in expression. + */ + void collect_indices(expr* e, unsigned_vector& indices) const; + + /** + Collect used variables of each index. + */ + void collect_variables(expr* e, vector >& vars) const; + + /** + Convert symbol sym which has to be of src_idx variant into variant tgt_idx. + */ + func_decl * conv(func_decl * sym, unsigned src_idx, unsigned tgt_idx) const; + + + /** + Convert src_idx symbols in formula f variant into tgt_idx. + If homogenous is true, formula cannot contain symbols of other variants. + */ + void conv_formula(expr * f, unsigned src_idx, unsigned tgt_idx, expr_ref & res, bool homogenous = true) const; + void conv_formula_vector(const expr_ref_vector & vect, unsigned src_idx, unsigned tgt_idx, + expr_ref_vector & res) const; + + /** + Shifts the muxed symbols in f by dist. Dist can be negative, but it should never shift + symbol index to a negative value. + */ + void shift_formula(expr * f, int dist, expr_ref & res) const; + + /** + Remove from vect literals (atoms or negations of atoms) of symbols + that contain multiplexed symbols with indexes other than idx. + + Each of the literals can contain only symbols multiplexed with one index + (this trivially holds if the literals are propositional). + + Order of elements in vect may be modified by this function + */ + void filter_idx(expr_ref_vector & vect, unsigned idx) const; + + /** + Partition literals into o_literals and others. + */ + void partition_o_idx(expr_ref_vector const& lits, + expr_ref_vector& o_lits, + expr_ref_vector& other, unsigned idx) const; + + bool has_nonmodel_symbol(expr * e) const; + void filter_non_model_lits(expr_ref_vector & vect) const; + + func_decl * const * begin_prim_preds() const { return m_prim_preds.begin(); } + func_decl * const * end_prim_preds() const { return m_prim_preds.end(); } + + void get_muxed_cube_from_model(const model_core & model, expr_ref_vector & res) const; + + std::string pp_model(const model_core & mdl) const; +}; +} + +#endif diff --git a/src/muz/spacer/spacer_unsat_core_learner.cpp b/src/muz/spacer/spacer_unsat_core_learner.cpp new file mode 100644 index 000000000..1e4dc522f --- /dev/null +++ b/src/muz/spacer/spacer_unsat_core_learner.cpp @@ -0,0 +1,360 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_unsat_core_learner.cpp + +Abstract: + itp cores + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#include "spacer_unsat_core_learner.h" + +#include "spacer_unsat_core_plugin.h" + +#include "proof_utils.h" +#include "for_each_expr.h" +#include +namespace spacer +{ + +#pragma mark - proof iterators + +# pragma mark - main methods +unsat_core_learner::~unsat_core_learner() +{ + std::for_each(m_plugins.begin(), m_plugins.end(), delete_proc()); + +} + +void unsat_core_learner::register_plugin(unsat_core_plugin* plugin) +{ + m_plugins.push_back(plugin); +} + +void unsat_core_learner::compute_unsat_core(proof *root, expr_set& asserted_b, expr_ref_vector& unsat_core) +{ + // transform proof in order to get a proof which is better suited for unsat-core-extraction + proof_ref pr(root, m); + + spacer::reduce_hypotheses(pr); + STRACE("spacer.unsat_core_learner", + verbose_stream() << "Reduced proof:\n" << mk_ismt2_pp(pr, m) << "\n"; + ); + + // compute symbols occuring in B + collect_symbols_b(asserted_b); + + // traverse proof + ProofIteratorPostOrder it(root, m); + while (it.hasNext()) + { + proof* currentNode = it.next(); + + if (m.get_num_parents(currentNode) == 0) + { + switch(currentNode->get_decl_kind()) + { + + case PR_ASSERTED: // currentNode is an axiom + { + if (asserted_b.contains(m.get_fact(currentNode))) + { + m_b_mark.mark(currentNode, true); + } + else + { + m_a_mark.mark(currentNode, true); + } + break; + } + // currentNode is a hypothesis: + case PR_HYPOTHESIS: + { + m_h_mark.mark(currentNode, true); + break; + } + default: + { + break; + } + } + } + else + { + // collect from parents whether derivation of current node contains A-axioms, B-axioms and hypothesis + bool need_to_mark_a = false; + bool need_to_mark_b = false; + bool need_to_mark_h = false; + bool need_to_mark_closed = true; + + for (unsigned i = 0; i < m.get_num_parents(currentNode); ++i) + { + SASSERT(m.is_proof(currentNode->get_arg(i))); + proof* premise = to_app(currentNode->get_arg(i)); + + need_to_mark_a = need_to_mark_a || m_a_mark.is_marked(premise); + need_to_mark_b = need_to_mark_b || m_b_mark.is_marked(premise); + need_to_mark_h = need_to_mark_h || m_h_mark.is_marked(premise); + need_to_mark_closed = need_to_mark_closed && (!m_b_mark.is_marked(premise) || m_closed.is_marked(premise)); + } + + // if current node is application of lemma, we know that all hypothesis are removed + if(currentNode->get_decl_kind() == PR_LEMMA) + { + need_to_mark_h = false; + } + + // save results + m_a_mark.mark(currentNode, need_to_mark_a); + m_b_mark.mark(currentNode, need_to_mark_b); + m_h_mark.mark(currentNode, need_to_mark_h); + m_closed.mark(currentNode, need_to_mark_closed); + } + + // we have now collected all necessary information, so we can visit the node + // if the node mixes A-reasoning and B-reasoning and contains non-closed premises + if (m_a_mark.is_marked(currentNode) && m_b_mark.is_marked(currentNode) && !m_closed.is_marked(currentNode)) + { + compute_partial_core(currentNode); // then we need to compute a partial core + // SASSERT(!(m_a_mark.is_marked(currentNode) && m_b_mark.is_marked(currentNode)) || m_closed.is_marked(currentNode)); TODO: doesn't hold anymore if we do the mincut-thing! + } + } + + // give plugins chance to finalize their unsat-core-computation + finalize(); + + // TODO: remove duplicates from unsat core? + + bool debug_proof = false; + if(debug_proof) + { + // print proof for debugging + verbose_stream() << "\n\nProof:\n"; + std::unordered_map id_to_small_id; + unsigned counter = 0; + + ProofIteratorPostOrder it2(root, m); + while (it2.hasNext()) + { + proof* currentNode = it2.next(); + + SASSERT(id_to_small_id.find(currentNode->get_id()) == id_to_small_id.end()); + id_to_small_id.insert(std::make_pair(currentNode->get_id(), counter)); + + verbose_stream() << counter << " "; + verbose_stream() << "["; + if (is_a_marked(currentNode)) + { + verbose_stream() << "a"; + } + if (is_b_marked(currentNode)) + { + verbose_stream() << "b"; + } + if (is_h_marked(currentNode)) + { + verbose_stream() << "h"; + } + if (is_closed(currentNode)) + { + verbose_stream() << "c"; + } + verbose_stream() << "] "; + + if (m.get_num_parents(currentNode) == 0) + { + switch (currentNode->get_decl_kind()) + { + case PR_ASSERTED: + verbose_stream() << "asserted"; + break; + case PR_HYPOTHESIS: + verbose_stream() << "hypothesis"; + break; + default: + verbose_stream() << "unknown axiom-type"; + break; + } + } + else + { + if (currentNode->get_decl_kind() == PR_LEMMA) + { + verbose_stream() << "lemma"; + } + else if (currentNode->get_decl_kind() == PR_TH_LEMMA) + { + verbose_stream() << "th_lemma"; + func_decl* d = currentNode->get_decl(); + symbol sym; + if (d->get_num_parameters() >= 2 && // the Farkas coefficients are saved in the parameters of step + d->get_parameter(0).is_symbol(sym) && sym == "arith" && // the first two parameters are "arith", "farkas", + d->get_parameter(1).is_symbol(sym) && sym == "farkas") + { + verbose_stream() << "(farkas)"; + } + else + { + verbose_stream() << "(other)"; + } + } + else + { + verbose_stream() << "step"; + } + verbose_stream() << " from "; + for (int i = m.get_num_parents(currentNode) - 1; i >= 0 ; --i) + { + proof* premise = to_app(currentNode->get_arg(i)); + unsigned premise_small_id = id_to_small_id[premise->get_id()]; + if (i > 0) + { + verbose_stream() << premise_small_id << ", "; + } + else + { + verbose_stream() << premise_small_id; + } + + } + } + if (currentNode->get_decl_kind() == PR_TH_LEMMA || (is_a_marked(currentNode) && is_b_marked(currentNode)) || is_h_marked(currentNode) || (!is_a_marked(currentNode) && !is_b_marked(currentNode))) + { + verbose_stream() << std::endl; + } + else + { + verbose_stream() << ": " << mk_pp(m.get_fact(currentNode), m) << std::endl; + } + ++counter; + } + } + // move all lemmas into vector + for (expr* const* it = m_unsat_core.begin(); it != m_unsat_core.end(); ++it) + { + unsat_core.push_back(*it); + } +} + +void unsat_core_learner::compute_partial_core(proof* step) +{ + for (unsat_core_plugin** it=m_plugins.begin(), **end = m_plugins.end (); it != end && !m_closed.is_marked(step); ++it) + { + unsat_core_plugin* plugin = *it; + plugin->compute_partial_core(step); + } +} + +void unsat_core_learner::finalize() +{ + for (unsat_core_plugin** it=m_plugins.begin(); it != m_plugins.end(); ++it) + { + unsat_core_plugin* plugin = *it; + plugin->finalize(); + } +} + +#pragma mark - API + +bool unsat_core_learner::is_a_marked(proof* p) +{ + return m_a_mark.is_marked(p); +} +bool unsat_core_learner::is_b_marked(proof* p) +{ + return m_b_mark.is_marked(p); +} +bool unsat_core_learner::is_h_marked(proof* p) +{ + return m_h_mark.is_marked(p); +} +bool unsat_core_learner::is_closed(proof*p) +{ + return m_closed.is_marked(p); +} +void unsat_core_learner::set_closed(proof* p, bool value) +{ + m_closed.mark(p, value); +} + + void unsat_core_learner::add_lemma_to_core(expr* lemma) + { + m_unsat_core.push_back(lemma); + } + +# pragma mark - checking for b_symbols + +class collect_pure_proc { + func_decl_set& m_symbs; +public: + collect_pure_proc(func_decl_set& s):m_symbs(s) {} + + void operator()(app* a) { + if (a->get_family_id() == null_family_id) { + m_symbs.insert(a->get_decl()); + } + } + void operator()(var*) {} + void operator()(quantifier*) {} +}; + +void unsat_core_learner::collect_symbols_b(expr_set axioms_b) +{ + expr_mark visited; + collect_pure_proc proc(m_symbols_b); + for (expr_set::iterator it = axioms_b.begin(); it != axioms_b.end(); ++it) + { + for_each_expr(proc, visited, *it); + } +} + +class is_pure_expr_proc { + func_decl_set const& m_symbs; + array_util m_au; +public: + struct non_pure {}; + + is_pure_expr_proc(func_decl_set const& s, ast_manager& m): + m_symbs(s), + m_au (m) + {} + + void operator()(app* a) { + if (a->get_family_id() == null_family_id) { + if (!m_symbs.contains(a->get_decl())) { + throw non_pure(); + } + } + else if (a->get_family_id () == m_au.get_family_id () && + a->is_app_of (a->get_family_id (), OP_ARRAY_EXT)) { + throw non_pure(); + } + } + void operator()(var*) {} + void operator()(quantifier*) {} +}; + +bool unsat_core_learner::only_contains_symbols_b(expr* expr) const +{ + is_pure_expr_proc proc(m_symbols_b, m); + try { + for_each_expr(proc, expr); + } + catch (is_pure_expr_proc::non_pure) + { + return false; + } + return true; +} + + + +} diff --git a/src/muz/spacer/spacer_unsat_core_learner.h b/src/muz/spacer/spacer_unsat_core_learner.h new file mode 100644 index 000000000..91ae01292 --- /dev/null +++ b/src/muz/spacer/spacer_unsat_core_learner.h @@ -0,0 +1,107 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_unsat_core_learner.h + +Abstract: + itp cores + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#ifndef _SPACER_UNSAT_CORE_LEARNER_H_ +#define _SPACER_UNSAT_CORE_LEARNER_H_ + +#include "ast.h" +#include "spacer_util.h" +#include "spacer_proof_utils.h" + +namespace spacer { + + + class unsat_core_plugin; + class unsat_core_learner + { + typedef obj_hashtable expr_set; + + public: + unsat_core_learner(ast_manager& m) : m(m), m_unsat_core(m) {}; + virtual ~unsat_core_learner(); + + ast_manager& m; + + /* + * register a plugin for computation of partial unsat cores + * currently plugins are called in the order they have been registered + */ + void register_plugin(unsat_core_plugin* plugin); + + /* + * compute unsat core using the registered unsat-core-plugins + */ + void compute_unsat_core(proof* root, expr_set& asserted_b, expr_ref_vector& unsat_core); + + /* + * getter/setter methods for data structures exposed to plugins + * the following invariants can be assumed and need to be maintained by the plugins: + * - a node is a-marked iff it is derived using at least one asserted proof step from A. + * - a node is b-marked iff its derivation contains no asserted proof steps from A and + * no hypothesis (with the additional complication that lemmas conceptually remove hypothesis) + * - a node is h-marked, iff it is derived using at least one hypothesis + * - a node is closed, iff it has already been interpolated, i.e. its contribution is + * already covered by the unsat-core. + */ + bool is_a_marked(proof* p); + bool is_b_marked(proof* p); + bool is_h_marked(proof* p); + bool is_closed(proof* p); + void set_closed(proof* p, bool value); + + /* + * adds a lemma to the unsat core + */ + void add_lemma_to_core(expr* lemma); + + /* + * helper method, which can be used by plugins + * returns true iff all symbols of expr occur in some b-asserted formula. + * must only be called after a call to collect_symbols_b. + */ + bool only_contains_symbols_b(expr* expr) const; + bool is_b_pure (proof *p) + {return !is_h_marked (p) && only_contains_symbols_b (m.get_fact (p));} + bool is_b_open (proof *p) + { return is_b_marked (p) && !is_closed (p); } + + private: + ptr_vector m_plugins; + func_decl_set m_symbols_b; // symbols, which occur in any b-asserted formula + void collect_symbols_b(expr_set axioms_b); + + ast_mark m_a_mark; + ast_mark m_b_mark; + ast_mark m_h_mark; + ast_mark m_closed; + + expr_ref_vector m_unsat_core; // collects the lemmas of the unsat-core, will at the end be inserted into unsat_core. + + /* + * computes partial core for step by delegating computation to plugins + */ + void compute_partial_core(proof* step); + + /* + * finalize computation of unsat-core + */ + void finalize(); + }; + +} + +#endif diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp new file mode 100644 index 000000000..d0d443528 --- /dev/null +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -0,0 +1,776 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_unsat_core_plugin.cpp + +Abstract: + plugin for itp cores + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#include "spacer_unsat_core_plugin.h" + +#include "spacer_unsat_core_learner.h" + +#include "smt_farkas_util.h" +#include "bool_rewriter.h" +#include "arith_decl_plugin.h" +#include +#include "smt_solver.h" +#include "solver.h" +#include +#include "spacer_proof_utils.h" +#include "spacer_matrix.h" + +namespace spacer +{ + +#pragma mark - unsat_core_plugin_lemma + +void unsat_core_plugin_lemma::compute_partial_core(proof* step) +{ + SASSERT(m_learner.is_a_marked(step)); + SASSERT(m_learner.is_b_marked(step)); + + for (unsigned i = 0; i < m_learner.m.get_num_parents(step); ++i) + { + SASSERT(m_learner.m.is_proof(step->get_arg(i))); + proof* premise = to_app(step->get_arg(i)); + + if (m_learner.is_b_open (premise)) + { + // by IH, premises that are AB marked are already closed + SASSERT(!m_learner.is_a_marked(premise)); + add_lowest_split_to_core(premise); + } + } + m_learner.set_closed(step, true); +} + +void unsat_core_plugin_lemma::add_lowest_split_to_core(proof* step) const +{ + SASSERT(m_learner.is_b_open(step)); + ast_manager &m = m_learner.m; + + ptr_vector todo; + todo.push_back(step); + + while (!todo.empty()) + { + proof* pf = todo.back(); + todo.pop_back(); + + // if current step hasn't been processed, + if (!m_learner.is_closed(pf)) + { + m_learner.set_closed(pf, true); + // the step is b-marked and not closed. + // by I.H. the step must be already visited + // so if it is also a-marked, it must be closed + SASSERT(m_learner.is_b_marked(pf)); + SASSERT(!m_learner.is_a_marked(pf)); + + // the current step needs to be interpolated: + expr* fact = m_learner.m.get_fact(pf); + // if we trust the current step and we are able to use it + if (m_learner.is_b_pure (pf) && + (m.is_asserted(pf) || is_literal(m, fact))) + { + // just add it to the core + m_learner.add_lemma_to_core(fact); + } + // otherwise recurse on premises + else + { + for (unsigned i = 0, sz = m_learner.m.get_num_parents(pf); + i < sz; ++i) + { + SASSERT(m_learner.m.is_proof(pf->get_arg(i))); + proof* premise = m.get_parent (pf, i); + if (m_learner.is_b_open(premise)) { + todo.push_back(premise); + } + } + } + + } + } +} + + +#pragma mark - unsat_core_plugin_farkas_lemma +void unsat_core_plugin_farkas_lemma::compute_partial_core(proof* step) +{ + ast_manager &m = m_learner.m; + SASSERT(m_learner.is_a_marked(step)); + SASSERT(m_learner.is_b_marked(step)); + // XXX this assertion should be true so there is no need to check for it + SASSERT (!m_learner.is_closed (step)); + func_decl* d = step->get_decl(); + symbol sym; + if(!m_learner.is_closed(step) && // if step is not already interpolated + step->get_decl_kind() == PR_TH_LEMMA && // and step is a Farkas lemma + d->get_num_parameters() >= 2 && // the Farkas coefficients are saved in the parameters of step + d->get_parameter(0).is_symbol(sym) && sym == "arith" && // the first two parameters are "arith", "farkas", + d->get_parameter(1).is_symbol(sym) && sym == "farkas" && + d->get_num_parameters() >= m_learner.m.get_num_parents(step) + 2) // the following parameters are the Farkas coefficients + { + SASSERT(m_learner.m.has_fact(step)); + + ptr_vector literals; + vector coefficients; + + /* The farkas lemma represents a subproof starting from premise(-set)s A, BNP and BP(ure) and + * ending in a disjunction D. We need to compute the contribution of BP, i.e. a formula, which + * is entailed by BP and together with A and BNP entails D. + * + * Let Fark(F) be the farkas coefficient for F. We can use the fact that + * (A*Fark(A) + BNP*Fark(BNP) + BP*Fark(BP) + (neg D)*Fark(D)) => false. (E1) + * We further have that A+B => C implies (A \land B) => C. (E2) + * + * Alternative 1: + * From (E1) immediately get that BP*Fark(BP) is a solution. + * + * Alternative 2: + * We can rewrite (E2) to rewrite (E1) to + * (BP*Fark(BP)) => (neg(A*Fark(A) + BNP*Fark(BNP) + (neg D)*Fark(D))) (E3) + * and since we can derive (A*Fark(A) + BNP*Fark(BNP) + (neg D)*Fark(D)) from + * A, BNP and D, we also know that it is inconsisent. Therefore + * neg(A*Fark(A) + BNP*Fark(BNP) + (neg D)*Fark(D)) is a solution. + * + * Finally we also need the following workaround: + * 1) Although we know from theory, that the Farkas coefficients are always nonnegative, + * the Farkas coefficients provided by arith_core are sometimes negative (must be a bug) + * as workaround we take the absolute value of the provided coefficients. + */ + parameter const* params = d->get_parameters() + 2; // point to the first Farkas coefficient + + STRACE("spacer.farkas", + verbose_stream() << "Farkas input: "<< "\n"; + for (unsigned i = 0; i < m_learner.m.get_num_parents(step); ++i) + { + SASSERT(m_learner.m.is_proof(step->get_arg(i))); + proof *prem = m.get_parent (step, i); + + rational coef; + VERIFY(params[i].is_rational(coef)); + + bool b_pure = m_learner.is_b_pure (prem); + verbose_stream() << (b_pure?"B":"A") << " " << coef << " " << mk_pp(m_learner.m.get_fact(prem), m_learner.m) << "\n"; + } + ); + + bool can_be_closed = true; + + for(unsigned i = 0; i < m.get_num_parents(step); ++i) + { + SASSERT(m_learner.m.is_proof(step->get_arg(i))); + proof * premise = m.get_parent (step, i); + + if (m_learner.is_b_open (premise)) + { + SASSERT(!m_learner.is_a_marked(premise)); + + if (m_learner.is_b_pure (step)) + { + if (!m_use_constant_from_a) + { + rational coefficient; + VERIFY(params[i].is_rational(coefficient)); + literals.push_back(to_app(m_learner.m.get_fact(premise))); + coefficients.push_back(abs(coefficient)); + } + } + else + { + can_be_closed = false; + + if (m_use_constant_from_a) + { + rational coefficient; + VERIFY(params[i].is_rational(coefficient)); + literals.push_back(to_app(m_learner.m.get_fact(premise))); + coefficients.push_back(abs(coefficient)); + } + } + } + else + { + if (m_use_constant_from_a) + { + rational coefficient; + VERIFY(params[i].is_rational(coefficient)); + literals.push_back(to_app(m_learner.m.get_fact(premise))); + coefficients.push_back(abs(coefficient)); + } + } + } + + if (m_use_constant_from_a) + { + params += m_learner.m.get_num_parents(step); // point to the first Farkas coefficient, which corresponds to a formula in the conclusion + + // the conclusion can either be a single formula or a disjunction of several formulas, we have to deal with both situations + if (m_learner.m.get_num_parents(step) + 2 < d->get_num_parameters()) + { + unsigned num_args = 1; + expr* conclusion = m_learner.m.get_fact(step); + expr* const* args = &conclusion; + if (m_learner.m.is_or(conclusion)) + { + app* _or = to_app(conclusion); + num_args = _or->get_num_args(); + args = _or->get_args(); + } + SASSERT(m_learner.m.get_num_parents(step) + 2 + num_args == d->get_num_parameters()); + + bool_rewriter brw(m_learner.m); + for (unsigned i = 0; i < num_args; ++i) + { + expr* premise = args[i]; + + expr_ref negatedPremise(m_learner.m); + brw.mk_not(premise, negatedPremise); + literals.push_back(to_app(negatedPremise)); + + rational coefficient; + VERIFY(params[i].is_rational(coefficient)); + coefficients.push_back(abs(coefficient)); + } + } + } + + // only if all b-premises can be used directly, add the farkas core and close the step + if (can_be_closed) + { + m_learner.set_closed(step, true); + + expr_ref res(m_learner.m); + compute_linear_combination(coefficients, literals, res); + + m_learner.add_lemma_to_core(res); + } + } +} + +void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector& coefficients, const ptr_vector& literals, expr_ref& res) +{ + SASSERT(literals.size() == coefficients.size()); + + ast_manager& m = res.get_manager(); + smt::farkas_util util(m); + if (m_use_constant_from_a) + { + util.set_split_literals (m_split_literals); // small optimization: if flag m_split_literals is set, then preserve diff constraints + } + for(unsigned i = 0; i < literals.size(); ++i) + { + util.add(coefficients[i], literals[i]); + } + if (m_use_constant_from_a) + { + res = util.get(); + } + else + { + expr_ref negated_linear_combination = util.get(); + res = mk_not(m, negated_linear_combination); + } +} + +#pragma mark - unsat_core_plugin_farkas_optimized + void unsat_core_plugin_farkas_lemma_optimized::compute_partial_core(proof* step) + { + SASSERT(m_learner.is_a_marked(step)); + SASSERT(m_learner.is_b_marked(step)); + + func_decl* d = step->get_decl(); + symbol sym; + if(!m_learner.is_closed(step) && // if step is not already interpolated + step->get_decl_kind() == PR_TH_LEMMA && // and step is a Farkas lemma + d->get_num_parameters() >= 2 && // the Farkas coefficients are saved in the parameters of step + d->get_parameter(0).is_symbol(sym) && sym == "arith" && // the first two parameters are "arith", "farkas", + d->get_parameter(1).is_symbol(sym) && sym == "farkas" && + d->get_num_parameters() >= m_learner.m.get_num_parents(step) + 2) // the following parameters are the Farkas coefficients + { + SASSERT(m_learner.m.has_fact(step)); + + vector > linear_combination; // collects all summands of the linear combination + + parameter const* params = d->get_parameters() + 2; // point to the first Farkas coefficient + + STRACE("spacer.farkas", + verbose_stream() << "Farkas input: "<< "\n"; + for (unsigned i = 0; i < m_learner.m.get_num_parents(step); ++i) + { + SASSERT(m_learner.m.is_proof(step->get_arg(i))); + proof *prem = m.get_parent (step, i); + + rational coef; + VERIFY(params[i].is_rational(coef)); + + bool b_pure = m_learner.is_b_pure (prem); + verbose_stream() << (b_pure?"B":"A") << " " << coef << " " << mk_pp(m_learner.m.get_fact(prem), m_learner.m) << "\n"; + } + ); + + bool can_be_closed = true; + for(unsigned i = 0; i < m_learner.m.get_num_parents(step); ++i) + { + SASSERT(m_learner.m.is_proof(step->get_arg(i))); + proof * premise = m.get_parent (step, i); + + if (m_learner.is_b_marked(premise) && !m_learner.is_closed(premise)) + { + SASSERT(!m_learner.is_a_marked(premise)); + + // XXX AG: why is this condition is based on step and not on premise? + if (m_learner.only_contains_symbols_b(m_learner.m.get_fact(step)) && !m_learner.is_h_marked(step)) + { + rational coefficient; + VERIFY(params[i].is_rational(coefficient)); + linear_combination.push_back(std::make_pair(to_app(m_learner.m.get_fact(premise)), abs(coefficient))); + } + else + { + can_be_closed = false; + } + } + } + + // only if all b-premises can be used directly, close the step and add linear combinations for later processing + if (can_be_closed) + { + m_learner.set_closed(step, true); + if (!linear_combination.empty()) + { + m_linear_combinations.push_back(linear_combination); + } + } + } + } + + struct farkas_optimized_less_than_pairs + { + inline bool operator() (const std::pair& pair1, const std::pair& pair2) const + { + return (pair1.first->get_id() < pair2.first->get_id()); + } + }; + + void unsat_core_plugin_farkas_lemma_optimized::finalize() + { + if(m_linear_combinations.empty()) + { + return; + } + DEBUG_CODE( + for (auto& linear_combination : m_linear_combinations) { + SASSERT(linear_combination.size() > 0); + }); + + // 1. construct ordered basis + ptr_vector ordered_basis; + obj_map map; + unsigned counter = 0; + for (const auto& linear_combination : m_linear_combinations) + { + for (const auto& pair : linear_combination) + { + if (!map.contains(pair.first)) + { + ordered_basis.push_back(pair.first); + map.insert(pair.first, counter++); + } + } + } + + // 2. populate matrix + spacer_matrix matrix(m_linear_combinations.size(), ordered_basis.size()); + + for (unsigned i=0; i < m_linear_combinations.size(); ++i) + { + auto linear_combination = m_linear_combinations[i]; + for (const auto& pair : linear_combination) + { + matrix.set(i, map[pair.first], pair.second); + } + } + + // 3. perform gaussian elimination + unsigned i = matrix.perform_gaussian_elimination(); + + // 4. extract linear combinations from matrix and add result to core + for (unsigned k=0; k < i; k++)// i points to the row after the last row which is non-zero + { + ptr_vector literals; + vector coefficients; + for (unsigned l=0; l < matrix.num_cols(); ++l) + { + if (!matrix.get(k,l).is_zero()) + { + literals.push_back(ordered_basis[l]); + coefficients.push_back(matrix.get(k,l)); + } + } + SASSERT(literals.size() > 0); + expr_ref linear_combination(m); + compute_linear_combination(coefficients, literals, linear_combination); + + m_learner.add_lemma_to_core(linear_combination); + } + + } + + void unsat_core_plugin_farkas_lemma_optimized::compute_linear_combination(const vector& coefficients, const ptr_vector& literals, expr_ref& res) + { + SASSERT(literals.size() == coefficients.size()); + + ast_manager& m = res.get_manager(); + smt::farkas_util util(m); + for(unsigned i = 0; i < literals.size(); ++i) + { + util.add(coefficients[i], literals[i]); + } + expr_ref negated_linear_combination = util.get(); + SASSERT(m.is_not(negated_linear_combination)); + res = mk_not(m, negated_linear_combination); //TODO: rewrite the get-method to return nonnegated stuff? + } + +#pragma mark - unsat_core_plugin_farkas_bounded + + void unsat_core_plugin_farkas_lemma_bounded::finalize() + { + if(m_linear_combinations.empty()) + {return;} + DEBUG_CODE( + for (auto& linear_combination : m_linear_combinations) { + SASSERT(linear_combination.size() > 0); + }); + + // 1. construct ordered basis + ptr_vector ordered_basis; + obj_map map; + unsigned counter = 0; + for (const auto& linear_combination : m_linear_combinations) + { + for (const auto& pair : linear_combination) + { + if (!map.contains(pair.first)) + { + ordered_basis.push_back(pair.first); + map.insert(pair.first, counter++); + } + } + } + + // 2. populate matrix + spacer_matrix matrix(m_linear_combinations.size(), ordered_basis.size()); + + for (unsigned i=0; i < m_linear_combinations.size(); ++i) + { + auto linear_combination = m_linear_combinations[i]; + for (const auto& pair : linear_combination) + { + matrix.set(i, map[pair.first], pair.second); + } + } + matrix.print_matrix(); + + // 3. normalize matrix to integer values + matrix.normalize(); + + + arith_util util(m); + + vector coeffs; + for (unsigned i=0; i < matrix.num_rows(); ++i) + { + coeffs.push_back(expr_ref_vector(m)); + } + + vector bounded_vectors; + for (unsigned j=0; j < matrix.num_cols(); ++j) + { + bounded_vectors.push_back(expr_ref_vector(m)); + } + + // 4. find smallest n using guess and check algorithm + for(unsigned n = 1; true; ++n) + { + params_ref p; + p.set_bool("model", true); + scoped_ptr s = mk_smt_solver(m, p, symbol::null); // TODO: incremental version? + + // add new variables w_in, + for (unsigned i=0; i < matrix.num_rows(); ++i) + { + std::string name = "w_" + std::to_string(i) + std::to_string(n); + + func_decl_ref decl(m); + decl = m.mk_func_decl(symbol(name.c_str()), 0, (sort*const*)0, util.mk_int()); + coeffs[i].push_back(m.mk_const(decl)); + } + + // we need s_jn + for (unsigned j=0; j < matrix.num_cols(); ++j) + { + std::string name = "s_" + std::to_string(j) + std::to_string(n); + + func_decl_ref decl(m); + decl = m.mk_func_decl(symbol(name.c_str()), 0, (sort*const*)0, util.mk_int()); + + expr_ref s_jn(m); + s_jn = m.mk_const(decl); + + bounded_vectors[j].push_back(s_jn); + } + + // assert bounds for all s_jn + for (unsigned l=0; l < n; ++l) + { + for (unsigned j=0; j < matrix.num_cols(); ++j) + { + expr* s_jn = bounded_vectors[j][l].get(); + + expr_ref lb(util.mk_le(util.mk_int(0), s_jn), m); + expr_ref ub(util.mk_le(s_jn, util.mk_int(1)), m); + s->assert_expr(lb); + s->assert_expr(ub); + } + } + + // assert: forall i,j: a_ij = sum_k w_ik * s_jk + for (unsigned i=0; i < matrix.num_rows(); ++i) + { + for (unsigned j=0; j < matrix.num_cols(); ++j) + { + SASSERT(matrix.get(i, j).is_int()); + app_ref a_ij(util.mk_numeral(matrix.get(i,j), true),m); + + app_ref sum(m); + sum = util.mk_int(0); + for (int k=0; k < n; ++k) + { + sum = util.mk_add(sum, util.mk_mul(coeffs[i][k].get(), bounded_vectors[j][k].get())); + } + expr_ref eq(m.mk_eq(a_ij, sum),m); + s->assert_expr(eq); + } + } + + // check result + lbool res = s->check_sat(0,0); + + // if sat extract model and add corresponding linear combinations to core + if (res == lbool::l_true) + { + model_ref model; + s->get_model(model); + + for (int k=0; k < n; ++k) + { + ptr_vector literals; + vector coefficients; + for (int j=0; j < matrix.num_cols(); ++j) + { + expr_ref evaluation(m); + + model.get()->eval(bounded_vectors[j][k].get(), evaluation, false); + if (!util.is_zero(evaluation)) + { + literals.push_back(ordered_basis[j]); + coefficients.push_back(rational(1)); + } + } + SASSERT(!literals.empty()); // since then previous outer loop would have found solution already + expr_ref linear_combination(m); + compute_linear_combination(coefficients, literals, linear_combination); + + m_learner.add_lemma_to_core(linear_combination); + } + return; + } + } + } + +#pragma mark - unsat_core_plugin_min_cut + unsat_core_plugin_min_cut::unsat_core_plugin_min_cut(unsat_core_learner& learner, ast_manager& m) : unsat_core_plugin(learner), m(m){} + + void unsat_core_plugin_min_cut::compute_partial_core(proof* step) + { + ptr_vector todo; + + SASSERT(m_learner.is_a_marked(step)); + SASSERT(m_learner.is_b_marked(step)); + SASSERT(m.get_num_parents(step) > 0); + SASSERT(!m_learner.is_closed(step)); + todo.push_back(step); + + while (!todo.empty()) + { + proof* current = todo.back(); + todo.pop_back(); + + if (!m_learner.is_closed(current) && !m_visited.is_marked(current)) + { + m_visited.mark(current, true); + advance_to_lowest_partial_cut(current, todo); + } + } + m_learner.set_closed(step, true); + } + + void unsat_core_plugin_min_cut::advance_to_lowest_partial_cut(proof* step, ptr_vector& todo2) + { + bool is_sink = true; + + ast_manager &m = m_learner.m; + ptr_vector todo; + + for (unsigned i = 0, sz = m.get_num_parents(step); i < sz; ++i) + { + proof* premise = m.get_parent (step, i); + { + if (m_learner.is_b_marked(premise)) + { + todo.push_back(premise); + } + } + } + while (!todo.empty()) + { + proof* current = todo.back(); + todo.pop_back(); + + // if current step hasn't been processed, + if (!m_learner.is_closed(current)) + { + SASSERT(!m_learner.is_a_marked(current)); // by I.H. the step must be already visited + + // and the current step needs to be interpolated: + if (m_learner.is_b_marked(current)) + { + // if we trust the current step and we are able to use it + if (m_learner.is_b_pure (current) && + (m.is_asserted(current) || + is_literal(m, m.get_fact(current)))) + { + // add corresponding edges and continue original traversel + if (m_learner.is_a_marked(step)) + { + add_edge(nullptr, current); // current is sink + } + else + { + add_edge(step, current); + } + todo2.push_back(current); + is_sink = false; + } + // otherwise recurse on premises + else + { + for (unsigned i = 0; i < m_learner.m.get_num_parents(current); ++i) + { + SASSERT(m_learner.m.is_proof(current->get_arg(i))); + proof* premise = m.get_parent (current, i); + todo.push_back(premise); + } + } + } + } + } + + if (is_sink) + { + add_edge(step, nullptr); + } + } + + void unsat_core_plugin_min_cut::add_edge(proof* i, proof* j) + { + unsigned node_i; + unsigned node_j; + if (i == nullptr) + { + node_i = 0; + } + else + { + unsigned tmp; + if (m_proof_to_node_plus.find(i, tmp)) + { + node_i = tmp; + } + else + { + unsigned node_other = m_min_cut.new_node(); + node_i = m_min_cut.new_node(); + + m_proof_to_node_minus.insert(i, node_other); + m_proof_to_node_plus.insert(i, node_i); + + if (node_i >= m_node_to_formula.size()) + { + m_node_to_formula.resize(node_i + 1); + } + m_node_to_formula[node_other] = m.get_fact(i); + m_node_to_formula[node_i] = m.get_fact(i); + + m_min_cut.add_edge(node_other, node_i, 1); + } + } + + if (j == nullptr) + { + node_j = 1; + } + else + { + unsigned tmp; + if (m_proof_to_node_minus.find(j, tmp)) + { + node_j = tmp; + } + else + { + node_j = m_min_cut.new_node(); + unsigned node_other = m_min_cut.new_node(); + + m_proof_to_node_minus.insert(j, node_j); + m_proof_to_node_plus.insert(j, node_other); + + if (node_other >= m_node_to_formula.size()) + { + m_node_to_formula.resize(node_other + 1); + } + m_node_to_formula[node_j] = m.get_fact(j); + m_node_to_formula[node_other] = m.get_fact(j); + + m_min_cut.add_edge(node_j, node_other, 1); + } + } + + // finally connect nodes + m_min_cut.add_edge(node_i, node_j, 1); + } + + void unsat_core_plugin_min_cut::finalize() + { + vector cut_nodes; + m_min_cut.compute_min_cut(cut_nodes); + + for (unsigned cut_node : cut_nodes) + { + m_learner.add_lemma_to_core(m_node_to_formula[cut_node]); + } + } +} diff --git a/src/muz/spacer/spacer_unsat_core_plugin.h b/src/muz/spacer/spacer_unsat_core_plugin.h new file mode 100644 index 000000000..6e1f383c1 --- /dev/null +++ b/src/muz/spacer/spacer_unsat_core_plugin.h @@ -0,0 +1,115 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_unsat_core_plugin.h + +Abstract: + plugin for itp cores + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#ifndef _SPACER_UNSAT_CORE_PLUGIN_H_ +#define _SPACER_UNSAT_CORE_PLUGIN_H_ + +#include "ast.h" +#include "spacer_min_cut.h" + +namespace spacer { + +class unsat_core_learner; + + +class unsat_core_plugin { + +public: + unsat_core_plugin(unsat_core_learner& learner) : m_learner(learner){}; + virtual ~unsat_core_plugin(){}; + virtual void compute_partial_core(proof* step) = 0; + virtual void finalize(){}; + + unsat_core_learner& m_learner; +}; + + +class unsat_core_plugin_lemma : public unsat_core_plugin { + +public: + unsat_core_plugin_lemma(unsat_core_learner& learner) : unsat_core_plugin(learner){}; + + virtual void compute_partial_core(proof* step) override; + +private: + void add_lowest_split_to_core(proof* step) const; +}; + + +class unsat_core_plugin_farkas_lemma : public unsat_core_plugin { + +public: + unsat_core_plugin_farkas_lemma(unsat_core_learner& learner, bool split_literals, bool use_constant_from_a=true) : unsat_core_plugin(learner), m_split_literals(split_literals), m_use_constant_from_a(use_constant_from_a) {}; + + virtual void compute_partial_core(proof* step) override; + +private: + bool m_split_literals; + bool m_use_constant_from_a; + /* + * compute linear combination of literals 'literals' having coefficients 'coefficients' and save result in res + */ + void compute_linear_combination(const vector& coefficients, const ptr_vector& literals, expr_ref& res); +}; + + class unsat_core_plugin_farkas_lemma_optimized : public unsat_core_plugin { + + public: + unsat_core_plugin_farkas_lemma_optimized(unsat_core_learner& learner, ast_manager& m) : unsat_core_plugin(learner), m(m) {}; + + virtual void compute_partial_core(proof* step) override; + virtual void finalize() override; + + protected: + vector > > m_linear_combinations; + ast_manager& m; + /* + * compute linear combination of literals 'literals' having coefficients 'coefficients' and save result in res + */ + void compute_linear_combination(const vector& coefficients, const ptr_vector& literals, expr_ref& res); + }; + + class unsat_core_plugin_farkas_lemma_bounded : public unsat_core_plugin_farkas_lemma_optimized { + + public: + unsat_core_plugin_farkas_lemma_bounded(unsat_core_learner& learner, ast_manager& m) : unsat_core_plugin_farkas_lemma_optimized(learner, m) {}; + + virtual void finalize() override; + }; + + class unsat_core_plugin_min_cut : public unsat_core_plugin { + + public: + unsat_core_plugin_min_cut(unsat_core_learner& learner, ast_manager& m); + + virtual void compute_partial_core(proof* step) override; + virtual void finalize() override; + private: + ast_manager& m; + + ast_mark m_visited; // saves for each node i whether the subproof with root i has already been added to the min-cut-problem + obj_map m_proof_to_node_minus; // maps proof-steps to the corresponding minus-nodes (the ones which are closer to source) + obj_map m_proof_to_node_plus; // maps proof-steps to the corresponding plus-nodes (the ones which are closer to sink) + void advance_to_lowest_partial_cut(proof* step, ptr_vector& todo2); + void add_edge(proof* i, proof* j); + + vector m_node_to_formula; // maps each node to the corresponding formula in the original proof + + spacer_min_cut m_min_cut; + }; +} +#endif diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp new file mode 100644 index 000000000..a2cf4101f --- /dev/null +++ b/src/muz/spacer/spacer_util.cpp @@ -0,0 +1,1393 @@ +/** +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_util.cpp + +Abstract: + + Utility functions for SPACER. + +Author: + + Krystof Hoder (t-khoder) 2011-8-19. + Arie Gurfinkel + Anvesh Komuravelli + +Revision History: + + Modified by Anvesh Komuravelli + +Notes: + + +--*/ + +#include +#include + +#include "ast.h" +#include "occurs.h" +#include "array_decl_plugin.h" +#include "ast_pp.h" +#include "bool_rewriter.h" +#include "dl_util.h" +#include "for_each_expr.h" +#include "smt_params.h" +#include "model.h" +#include "model_evaluator.h" +#include "ref_vector.h" +#include "rewriter.h" +#include "rewriter_def.h" +#include "util.h" +#include "spacer_manager.h" +#include "spacer_util.h" +#include "arith_decl_plugin.h" +#include "expr_replacer.h" +#include "model_smt2_pp.h" +#include "scoped_proof.h" +#include "qe_lite.h" +#include "spacer_qe_project.h" +#include "model_pp.h" +#include "expr_safe_replace.h" + +#include "datatype_decl_plugin.h" +#include "bv_decl_plugin.h" + +#include "spacer_legacy_mev.h" +#include "qe_mbp.h" + +#include "tactical.h" +#include "propagate_values_tactic.h" +#include "propagate_ineqs_tactic.h" +#include "arith_bounds_tactic.h" + +#include "obj_equiv_class.h" + +namespace spacer { + + ///////////////////////// + // model_evaluator_util + // + + model_evaluator_util::model_evaluator_util(ast_manager& m) : + m(m), m_mev(NULL) + { reset (NULL); } + + model_evaluator_util::~model_evaluator_util() {reset (NULL);} + + +void model_evaluator_util::reset(model* model) +{ + if (m_mev) { + dealloc(m_mev); + m_mev = NULL; + } + m_model = model; + if (!m_model) { return; } + m_mev = alloc(model_evaluator, *m_model); + } + +bool model_evaluator_util::eval(expr *e, expr_ref &result, bool model_completion) +{ + m_mev->set_model_completion (model_completion); + try { + m_mev->operator() (e, result); + return true; + } catch (model_evaluator_exception &ex) { + (void)ex; + TRACE("spacer_model_evaluator", tout << ex.msg () << "\n";); + return false; + } + } + + bool model_evaluator_util::eval(const expr_ref_vector &v, + expr_ref& res, bool model_completion) +{ + expr_ref e(m); + e = mk_and (v); + return eval(e, res, model_completion); + } + + +bool model_evaluator_util::is_true(const expr_ref_vector &v) +{ + expr_ref res(m); + return eval (v, res, false) && m.is_true (res); + } + +bool model_evaluator_util::is_false(expr *x) +{ + expr_ref res(m); + return eval(x, res, false) && m.is_false (res); + } +bool model_evaluator_util::is_true(expr *x) +{ + expr_ref res(m); + return eval(x, res, false) && m.is_true (res); + } + + +void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) +{ + ast_manager& m = fml.get_manager(); + expr_ref_vector conjs(m); + flatten_and(fml, conjs); + obj_map diseqs; + expr* n, *lhs, *rhs; + for (unsigned i = 0; i < conjs.size(); ++i) { + if (m.is_not(conjs[i].get(), n) && + m.is_eq(n, lhs, rhs)) { + if (!m.is_value(rhs)) { + std::swap(lhs, rhs); + } + if (!m.is_value(rhs)) { + continue; + } + diseqs.insert_if_not_there2(lhs, 0)->get_data().m_value++; + } + } + expr_substitution sub(m); + + unsigned orig_size = conjs.size(); + unsigned num_deleted = 0; + expr_ref val(m), tmp(m); + proof_ref pr(m); + pr = m.mk_asserted(m.mk_true()); + obj_map::iterator it = diseqs.begin(); + obj_map::iterator end = diseqs.end(); + for (; it != end; ++it) { + if (it->m_value >= threshold) { + model.eval(it->m_key, val); + sub.insert(it->m_key, val, pr); + conjs.push_back(m.mk_eq(it->m_key, val)); + num_deleted += it->m_value; + } + } + if (orig_size < conjs.size()) { + scoped_ptr rep = mk_expr_simp_replacer(m); + rep->set_substitution(&sub); + for (unsigned i = 0; i < orig_size; ++i) { + tmp = conjs[i].get(); + (*rep)(tmp); + if (m.is_true(tmp)) { + conjs[i] = conjs.back(); + SASSERT(orig_size <= conjs.size()); + conjs.pop_back(); + SASSERT(orig_size <= 1 + conjs.size()); + if (i + 1 == orig_size) { + // no-op. + } else if (orig_size <= conjs.size()) { + // no-op + } else { + SASSERT(orig_size == 1 + conjs.size()); + --orig_size; + --i; + } + } else { + conjs[i] = tmp; + } + } + IF_VERBOSE(2, verbose_stream() << "Deleted " << num_deleted << " disequalities " << conjs.size() << " conjuncts\n";); + } + fml = m.mk_and(conjs.size(), conjs.c_ptr()); + } + + // + // (f (if c1 (if c2 e1 e2) e3) b c) -> + // (if c1 (if c2 (f e1 b c) + + class ite_hoister { + ast_manager& m; + public: + ite_hoister(ast_manager& m): m(m) {} + + br_status mk_app_core(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result) + { + if (m.is_ite(f)) { + return BR_FAILED; + } + for (unsigned i = 0; i < num_args; ++i) { + expr* c, *t, *e; + if (!m.is_bool(args[i]) && m.is_ite(args[i], c, t, e)) { + expr_ref e1(m), e2(m); + ptr_vector args1(num_args, args); + args1[i] = t; + e1 = m.mk_app(f, num_args, args1.c_ptr()); + if (t == e) { + result = e1; + return BR_REWRITE1; + } + args1[i] = e; + e2 = m.mk_app(f, num_args, args1.c_ptr()); + result = m.mk_app(f, num_args, args); + result = m.mk_ite(c, e1, e2); + return BR_REWRITE3; + } + } + return BR_FAILED; + } + }; + + struct ite_hoister_cfg: public default_rewriter_cfg { + ite_hoister m_r; + bool rewrite_patterns() const { return false; } + br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) + { + return m_r.mk_app_core(f, num, args, result); + } + ite_hoister_cfg(ast_manager & m, params_ref const & p):m_r(m) {} + }; + + class ite_hoister_star : public rewriter_tpl { + ite_hoister_cfg m_cfg; + public: + ite_hoister_star(ast_manager & m, params_ref const & p): + rewriter_tpl(m, false, m_cfg), + m_cfg(m, p) {} + }; + +void hoist_non_bool_if(expr_ref& fml) +{ + ast_manager& m = fml.get_manager(); + scoped_no_proof _sp(m); + params_ref p; + ite_hoister_star ite_rw(m, p); + expr_ref tmp(m); + ite_rw(fml, tmp); + fml = tmp; + } + + class test_diff_logic { + ast_manager& m; + arith_util a; + bv_util bv; + bool m_is_dl; + bool m_test_for_utvpi; + + bool is_numeric(expr* e) const + { + if (a.is_numeral(e)) { + return true; + } + expr* cond, *th, *el; + if (m.is_ite(e, cond, th, el)) { + return is_numeric(th) && is_numeric(el); + } + return false; + } + + bool is_arith_expr(expr *e) const + { + return is_app(e) && a.get_family_id() == to_app(e)->get_family_id(); + } + + bool is_offset(expr* e) const + { + if (a.is_numeral(e)) { + return true; + } + expr* cond, *th, *el, *e1, *e2; + if (m.is_ite(e, cond, th, el)) { + return is_offset(th) && is_offset(el); + } + // recognize offsets. + if (a.is_add(e, e1, e2)) { + if (is_numeric(e1)) { + return is_offset(e2); + } + if (is_numeric(e2)) { + return is_offset(e1); + } + return false; + } + if (m_test_for_utvpi) { + if (a.is_mul(e, e1, e2)) { + if (is_minus_one(e1)) { + return is_offset(e2); + } + if (is_minus_one(e2)) { + return is_offset(e1); + } + } + } + return !is_arith_expr(e); + } + + bool is_minus_one(expr const * e) const + { + rational r; + return a.is_numeral(e, r) && r.is_minus_one(); + } + + bool test_ineq(expr* e) const + { + SASSERT(a.is_le(e) || a.is_ge(e) || m.is_eq(e)); + SASSERT(to_app(e)->get_num_args() == 2); + expr * lhs = to_app(e)->get_arg(0); + expr * rhs = to_app(e)->get_arg(1); + if (is_offset(lhs) && is_offset(rhs)) + { return true; } + if (!is_numeric(rhs)) + { std::swap(lhs, rhs); } + if (!is_numeric(rhs)) + { return false; } + // lhs can be 'x' or '(+ x (* -1 y))' + if (is_offset(lhs)) + { return true; } + expr* arg1, *arg2; + if (!a.is_add(lhs, arg1, arg2)) + { return false; } + // x + if (m_test_for_utvpi) { + return is_offset(arg1) && is_offset(arg2); + } + if (is_arith_expr(arg1)) + { std::swap(arg1, arg2); } + if (is_arith_expr(arg1)) + { return false; } + // arg2: (* -1 y) + expr* m1, *m2; + if (!a.is_mul(arg2, m1, m2)) + { return false; } + return is_minus_one(m1) && is_offset(m2); + } + + bool test_eq(expr* e) const + { + expr* lhs, *rhs; + VERIFY(m.is_eq(e, lhs, rhs)); + if (!a.is_int_real(lhs)) { + return true; + } + if (a.is_numeral(lhs) || a.is_numeral(rhs)) { + return test_ineq(e); + } + return + test_term(lhs) && + test_term(rhs) && + !a.is_mul(lhs) && + !a.is_mul(rhs); + } + + bool test_term(expr* e) const + { + if (m.is_bool(e)) { + return true; + } + if (a.is_numeral(e)) { + return true; + } + if (is_offset(e)) { + return true; + } + expr* lhs, *rhs; + if (a.is_add(e, lhs, rhs)) { + if (!a.is_numeral(lhs)) { + std::swap(lhs, rhs); + } + return a.is_numeral(lhs) && is_offset(rhs); + } + if (a.is_mul(e, lhs, rhs)) { + return is_minus_one(lhs) || is_minus_one(rhs); + } + return false; + } + + bool is_non_arith_or_basic(expr* e) + { + if (!is_app(e)) { + return false; + } + family_id fid = to_app(e)->get_family_id(); + + if (fid == null_family_id && + !m.is_bool(e) && + to_app(e)->get_num_args() > 0) { + return true; + } + return + fid != m.get_basic_family_id() && + fid != null_family_id && + fid != a.get_family_id() && + fid != bv.get_family_id(); + } + + public: + test_diff_logic(ast_manager& m): m(m), a(m), bv(m), m_is_dl(true), m_test_for_utvpi(false) {} + + void test_for_utvpi() { m_test_for_utvpi = true; } + + void operator()(expr* e) + { + if (!m_is_dl) { + return; + } + if (a.is_le(e) || a.is_ge(e)) { + m_is_dl = test_ineq(e); + } else if (m.is_eq(e)) { + m_is_dl = test_eq(e); + } else if (is_non_arith_or_basic(e)) { + m_is_dl = false; + } else if (is_app(e)) { + app* a = to_app(e); + for (unsigned i = 0; m_is_dl && i < a->get_num_args(); ++i) { + m_is_dl = test_term(a->get_arg(i)); + } + } + + if (!m_is_dl) { + char const* msg = "non-diff: "; + if (m_test_for_utvpi) { + msg = "non-utvpi: "; + } + IF_VERBOSE(1, verbose_stream() << msg << mk_pp(e, m) << "\n";); + } + } + + bool is_dl() const { return m_is_dl; } + }; + +bool is_difference_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) +{ + test_diff_logic test(m); + expr_fast_mark1 mark; + for (unsigned i = 0; i < num_fmls; ++i) { + quick_for_each_expr(test, mark, fmls[i]); + } + return test.is_dl(); + } + +bool is_utvpi_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) +{ + test_diff_logic test(m); + test.test_for_utvpi(); + expr_fast_mark1 mark; + for (unsigned i = 0; i < num_fmls; ++i) { + quick_for_each_expr(test, mark, fmls[i]); + } + return test.is_dl(); + } + + + void subst_vars (ast_manager& m, app_ref_vector const& vars, + model* M, expr_ref& fml) +{ + expr_safe_replace sub (m); + model_evaluator_util mev (m); + mev.set_model(*M); + for (unsigned i = 0; i < vars.size (); i++) { + app* v = vars.get (i); + expr_ref val (m); + VERIFY(mev.eval (v, val, true)); + sub.insert (v, val); + } + sub (fml); + } + + /* + * eliminate simple equalities using qe_lite + * then, MBP for Booleans (substitute), reals (based on LW), ints (based on Cooper), and arrays + */ + void qe_project (ast_manager& m, app_ref_vector& vars, expr_ref& fml, + const model_ref& M, bool reduce_all_selects, bool use_native_mbp, + bool dont_sub) +{ + th_rewriter rw (m); + TRACE ("spacer_mbp", + tout << "Before projection:\n"; + tout << mk_pp (fml, m) << "\n"; + tout << "Vars:\n"; + for (unsigned i = 0; i < vars.size(); ++i) { + tout << mk_pp(vars.get (i), m) << "\n"; + } + ); + + { + // Ensure that top-level AND of fml is flat + expr_ref_vector flat(m); + flatten_and (fml, flat); + if (flat.size () == 1) + { fml = flat.get(0); } + else if (flat.size () > 1) + { fml = m.mk_and(flat.size(), flat.c_ptr()); } + } + + app_ref_vector arith_vars (m); + app_ref_vector array_vars (m); + array_util arr_u (m); + arith_util ari_u (m); + expr_safe_replace bool_sub (m); + expr_ref bval (m); + + while (true) { + params_ref p; + qe_lite qe(m, p, false); + qe (vars, fml); + rw (fml); + + TRACE ("spacer_mbp", + tout << "After qe_lite:\n"; + tout << mk_pp (fml, m) << "\n"; + tout << "Vars:\n"; + for (unsigned i = 0; i < vars.size(); ++i) { + tout << mk_pp(vars.get (i), m) << "\n"; + } + ); + SASSERT (!m.is_false (fml)); + + bool has_bool_vars = false; + + // sort out vars into bools, arith (int/real), and arrays + for (unsigned i = 0; i < vars.size (); i++) { + if (m.is_bool (vars.get (i))) { + // obtain the interpretation of the ith var using model completion + VERIFY (M->eval (vars.get (i), bval, true)); + bool_sub.insert (vars.get (i), bval); + has_bool_vars = true; + } else if (arr_u.is_array(vars.get(i))) { + array_vars.push_back (vars.get (i)); + } else { + SASSERT (ari_u.is_int (vars.get (i)) || ari_u.is_real (vars.get (i))); + arith_vars.push_back (vars.get (i)); + } + } + + // substitute Booleans + if (has_bool_vars) { + bool_sub (fml); + // -- bool_sub is not simplifying + rw (fml); + SASSERT (!m.is_false (fml)); + TRACE ("spacer_mbp", + tout << "Projected Booleans:\n" << mk_pp (fml, m) << "\n"; + ); + bool_sub.reset (); + } + + TRACE ("spacer_mbp", + tout << "Array vars:\n"; + for (unsigned i = 0; i < array_vars.size (); ++i) { + tout << mk_pp (array_vars.get (i), m) << "\n"; + } + ); + + vars.reset (); + + // project arrays + { + scoped_no_proof _sp (m); + // -- local rewriter that is aware of current proof mode + th_rewriter srw(m); + qe::array_project (*M.get (), array_vars, fml, vars, reduce_all_selects); + SASSERT (array_vars.empty ()); + srw (fml); + SASSERT (!m.is_false (fml)); + } + + TRACE ("spacer_mbp", + tout << "extended model:\n"; + model_pp (tout, *M); + tout << "Auxiliary variables of index and value sorts:\n"; + for (unsigned i = 0; i < vars.size (); i++) { + tout << mk_pp (vars.get (i), m) << "\n"; + } + ); + + if (vars.empty()) { break; } + } + + // project reals and ints + if (!arith_vars.empty ()) { + TRACE ("spacer_mbp", + tout << "Arith vars:\n"; + for (unsigned i = 0; i < arith_vars.size (); ++i) { + tout << mk_pp (arith_vars.get (i), m) << "\n"; + } + ); + + // XXX Does not seem to have an effect + // qe_lite qe(m); + // qe (arith_vars, fml); + // TRACE ("spacer_mbp", + // tout << "After second qelite: " << + // mk_pp (fml, m) << "\n";); + + if (use_native_mbp) { + qe::mbp mbp (m); + expr_ref_vector fmls(m); + flatten_and (fml, fmls); + + mbp (true, arith_vars, *M.get (), fmls); + fml = mk_and (fmls); + SASSERT (arith_vars.empty ()); + } else { + scoped_no_proof _sp (m); + qe::arith_project (*M.get (), arith_vars, fml); + } + + TRACE ("spacer_mbp", + tout << "Projected arith vars:\n" << mk_pp (fml, m) << "\n"; + tout << "Remaining arith vars:\n"; + for (unsigned i = 0; i < arith_vars.size (); i++) { + tout << mk_pp (arith_vars.get (i), m) << "\n"; + } + ); + SASSERT (!m.is_false (fml)); + } + + if (!arith_vars.empty ()) { + mbqi_project (*M.get(), arith_vars, fml); + } + + // substitute any remaining arith vars + if (!dont_sub && !arith_vars.empty ()) { + subst_vars (m, arith_vars, M.get(), fml); + TRACE ("spacer_mbp", + tout << "After substituting remaining arith vars:\n"; + tout << mk_pp (fml, m) << "\n"; + ); + // an extra round of simplification because subst_vars is not simplifying + rw(fml); + } + + DEBUG_CODE ( + model_evaluator_util mev (m); + expr_ref v(m); + mev.set_model(*M.get()); + SASSERT (mev.eval (fml, v, false)); + SASSERT (m.is_true (v)); + ); + + vars.reset (); + if (dont_sub && !arith_vars.empty ()) + { vars.append(arith_vars); } + } + + + static expr* apply_accessor(ast_manager &m, + ptr_vector const& acc, + unsigned j, + func_decl* f, + expr* c) +{ + if (is_app(c) && to_app(c)->get_decl() == f) { + return to_app(c)->get_arg(j); + } else { + return m.mk_app(acc[j], c); + } + } + +void expand_literals(ast_manager &m, expr_ref_vector& conjs) +{ + if (conjs.empty()) { return; } + arith_util arith(m); + datatype_util dt(m); + bv_util bv(m); + expr* e1, *e2, *c, *val; + rational r; + unsigned bv_size; + + TRACE("spacer_expand", + tout << "begin expand\n"; + for (unsigned i = 0; i < conjs.size(); ++i) { + tout << mk_pp(conjs[i].get(), m) << "\n"; + }); + + for (unsigned i = 0; i < conjs.size(); ++i) { + expr* e = conjs[i].get(); + if (m.is_eq(e, e1, e2) && arith.is_int_real(e1)) { + conjs[i] = arith.mk_le(e1,e2); + if (i+1 == conjs.size()) { + conjs.push_back(arith.mk_ge(e1, e2)); + } else { + conjs.push_back(conjs[i+1].get()); + conjs[i+1] = arith.mk_ge(e1, e2); + } + ++i; + } else if ((m.is_eq(e, c, val) && is_app(val) && dt.is_constructor(to_app(val))) || + (m.is_eq(e, val, c) && is_app(val) && dt.is_constructor(to_app(val)))){ + func_decl* f = to_app(val)->get_decl(); + func_decl* r = dt.get_constructor_recognizer(f); + conjs[i] = m.mk_app(r, c); + ptr_vector const& acc = *dt.get_constructor_accessors(f); + for (unsigned j = 0; j < acc.size(); ++j) { + conjs.push_back(m.mk_eq(apply_accessor(m, acc, j, f, c), to_app(val)->get_arg(j))); + } + } else if ((m.is_eq(e, c, val) && bv.is_numeral(val, r, bv_size)) || + (m.is_eq(e, val, c) && bv.is_numeral(val, r, bv_size))) { + rational two(2); + for (unsigned j = 0; j < bv_size; ++j) { + parameter p(j); + //expr* e = m.mk_app(bv.get_family_id(), OP_BIT2BOOL, 1, &p, 1, &c); + expr* e = m.mk_eq(m.mk_app(bv.get_family_id(), OP_BIT1), bv.mk_extract(j, j, c)); + if ((r % two).is_zero()) { + e = m.mk_not(e); + } + r = div(r, two); + if (j == 0) { + conjs[i] = e; + } else { + conjs.push_back(e); + } + } + } + } + TRACE("spacer_expand", + tout << "end expand\n"; + for (unsigned i = 0; i < conjs.size(); ++i) { + tout << mk_pp(conjs[i].get(), m) << "\n"; + }); + } + +namespace { +class implicant_picker { + model_evaluator_util &m_mev; + ast_manager &m; + arith_util m_arith; + + expr_ref_vector m_todo; + expr_mark m_visited; + + + void add_literal (expr *e, expr_ref_vector &out) + { + SASSERT (m.is_bool (e)); + + expr_ref res (m), v(m); + m_mev.eval (e, v, false); + SASSERT (m.is_true (v) || m.is_false (v)); + + res = m.is_false (v) ? m.mk_not (e) : e; + + if (m.is_distinct (res)) { + // -- (distinct a b) == (not (= a b)) + if (to_app(res)->get_num_args() == 2) { + res = m.mk_eq (to_app(res)->get_arg(0), to_app(res)->get_arg(1)); + res = m.mk_not (res); + } + } + + expr *nres, *f1, *f2; + if (m.is_not(res, nres)) { + // -- (not (xor a b)) == (= a b) + if (m.is_xor(nres, f1, f2)) + { res = m.mk_eq(f1, f2); } + + // -- split arithmetic inequality + else if (m.is_eq (nres, f1, f2) && m_arith.is_int_real (f1)) { + expr_ref u(m); + u = m_arith.mk_lt(f1, f2); + if (m_mev.eval (u, v, false) && m.is_true (v)) + { res = u; } + else + { res = m_arith.mk_lt(f2, f1); } + } + } + + if (!m_mev.is_true (res)) + { verbose_stream() << "Bad literal: " << mk_pp(res, m) << "\n"; } + SASSERT (m_mev.is_true (res)); + out.push_back (res); + } + + void process_app(app *a, expr_ref_vector &out) + { + if (m_visited.is_marked(a)) { return; } + SASSERT (m.is_bool (a)); + expr_ref v(m); + m_mev.eval (a, v, false); + + if (!m.is_true(v) && !m.is_false(v)) { return; } + + expr *na, *f1, *f2, *f3; + + if (a->get_family_id() != m.get_basic_family_id()) + { add_literal(a, out); } + else if (is_uninterp_const(a)) + { add_literal(a, out); } + else if (m.is_not(a, na) && m.is_not(na, na)) + { m_todo.push_back(na); } + else if (m.is_not(a, na)) + { m_todo.push_back(na); } + else if (m.is_distinct(a)) { + if (m.is_false(v)) + m_todo.push_back + (qe::project_plugin::pick_equality(m, *m_mev.get_model(), a)); + else if (a->get_num_args() == 2) + { add_literal(a, out); } + else + m_todo.push_back(m.mk_distinct_expanded(a->get_num_args(), + a->get_args())); + } else if (m.is_and(a)) { + if (m.is_true(v)) + { m_todo.append(a->get_num_args(), a->get_args()); } + else if (m.is_false(v)) { + for (unsigned i = 0, sz = a->get_num_args (); i < sz; ++i) { + if (m_mev.is_false(a->get_arg(i))) { + m_todo.push_back(a->get_arg(i)); + break; + } + } + } + } else if (m.is_or(a)) { + if (m.is_false(v)) + { m_todo.append(a->get_num_args(), a->get_args()); } + else if (m.is_true(v)) { + for (unsigned i = 0, sz = a->get_num_args(); i < sz; ++i) { + if (m_mev.is_true(a->get_arg(i))) { + m_todo.push_back(a->get_arg(i)); + break; + } + } + } + } else if (m.is_iff(a, f1, f2) || m.is_eq(a, f1, f2) || + (m.is_true(v) && m.is_not(a, na) && m.is_xor (na, f1, f2))) { + if (!m.are_equal(f1, f2) && !m.are_distinct(f1, f2)) { + if (m.is_bool(f1) && + (!is_uninterp_const(f1) || !is_uninterp_const(f2))) + { m_todo.append(a->get_num_args(), a->get_args()); } + else + { add_literal(a, out); } + } + } else if (m.is_ite(a, f1, f2, f3)) { + if (m.are_equal(f2, f3)) { m_todo.push_back(f2); } + else if (m_mev.is_true (f2) && m_mev.is_true (f3)) { + m_todo.push_back(f2); + m_todo.push_back(f3); + } else if (m_mev.is_false(f2) && m_mev.is_false(f3)) { + m_todo.push_back(f2); + m_todo.push_back(f3); + } else if (m_mev.is_true(f1)) { + m_todo.push_back(f1); + m_todo.push_back(f2); + } else if (m_mev.is_false(f1)) { + m_todo.push_back(f1); + m_todo.push_back(f3); + } + } else if (m.is_xor(a, f1, f2)) + { m_todo.append(a->get_num_args(), a->get_args()); } + else if (m.is_implies(a, f1, f2)) { + if (m.is_true (v)) { + if (m_mev.is_true(f2)) { m_todo.push_back(f2); } + else if (m_mev.is_false(f1)) { m_todo.push_back(f1); } + } else if (m.is_false(v)) + { m_todo.append(a->get_num_args(), a->get_args()); } + } else if (m.is_true(a) || m.is_false(a)) { /* nothing */ } + else { + verbose_stream () << "Unexpected expression: " + << mk_pp(a, m) << "\n"; + UNREACHABLE(); + } + } + + void pick_literals(expr *e, expr_ref_vector &out) + { + SASSERT(m_todo.empty()); + if (m_visited.is_marked(e)) { return; } + SASSERT(is_app(e)); + + m_todo.push_back(e); + do { + app *a = to_app(m_todo.back()); + m_todo.pop_back(); + process_app(a, out); + m_visited.mark(a, true); + } while (!m_todo.empty()); + } + + bool pick_implicant(const expr_ref_vector &in, expr_ref_vector &out) + { + m_visited.reset(); + expr_ref e(m); + e = mk_and (in); + bool is_true = m_mev.is_true (e); + + for (unsigned i = 0, sz = in.size (); i < sz; ++i) { + if (is_true || m_mev.is_true(in.get(i))) + { pick_literals(in.get(i), out); } + } + + m_visited.reset (); + return is_true; + } + + public: + implicant_picker (model_evaluator_util &mev) : + m_mev (mev), m (m_mev.get_ast_manager ()), m_arith(m), m_todo(m) {} + + void operator() (expr_ref_vector &in, expr_ref_vector& out) + {pick_implicant (in, out);} + }; + } + + void compute_implicant_literals (model_evaluator_util &mev, expr_ref_vector &formula, + expr_ref_vector &res) + { + // XXX what is the point of flattening? + flatten_and (formula); + if (formula.empty()) { return; } + + implicant_picker ipick (mev); + ipick (formula, res); + } + +void simplify_bounds_old(expr_ref_vector& cube) { + ast_manager& m = cube.m(); + + scoped_no_proof _no_pf_(m); + goal_ref g(alloc(goal, m, false, false, false)); + + for (unsigned i = 0; i < cube.size(); ++i) { + g->assert_expr(cube.get(i)); + } + + expr_ref tmp(m); + model_converter_ref mc; + proof_converter_ref pc; + expr_dependency_ref core(m); + goal_ref_buffer result; + tactic_ref simplifier = mk_arith_bounds_tactic(m); + (*simplifier)(g, result, mc, pc, core); + SASSERT(result.size() == 1); + goal* r = result[0]; + + cube.reset(); + for (unsigned i = 0; i < r->size(); ++i) { + cube.push_back(r->form(i)); + } +} + +void simplify_bounds_new (expr_ref_vector &cube) { + ast_manager &m = cube.m(); + + + scoped_no_proof _no_pf_(m); + + goal_ref g(alloc(goal, m, false, false, false)); + for (unsigned i = 0, sz = cube.size(); i < sz; ++i) { + g->assert_expr(cube.get(i)); + } + + model_converter_ref mc; + proof_converter_ref pc; + expr_dependency_ref dep(m); + goal_ref_buffer goals; + tactic_ref prop_values = mk_propagate_values_tactic(m); + tactic_ref prop_bounds = mk_propagate_ineqs_tactic(m); + tactic_ref t = and_then(prop_values.get(), prop_bounds.get()); + + (*t)(g, goals, mc, pc, dep); + SASSERT(goals.size() == 1); + + g = goals[0]; + cube.reset(); + for (unsigned i = 0; i < g->size(); ++i) { + cube.push_back(g->form(i)); + } +} + +void simplify_bounds(expr_ref_vector &cube) { + simplify_bounds_new(cube); +} + +/// Adhoc rewriting of arithmetic expressions +struct adhoc_rewriter_cfg : public default_rewriter_cfg { + ast_manager &m; + arith_util m_util; + + adhoc_rewriter_cfg (ast_manager &manager) : m(manager), m_util(m) {} + + bool is_le(func_decl const * n) const + { return is_decl_of(n, m_util.get_family_id (), OP_LE); } + bool is_ge(func_decl const * n) const + { return is_decl_of(n, m_util.get_family_id (), OP_GE); } + + br_status reduce_app (func_decl * f, unsigned num, expr * const * args, + expr_ref & result, proof_ref & result_pr) + { + expr * e; + br_status st = BR_FAILED; + if (is_le(f)) { + st = mk_le_core (args[0], args[1], result); + } else if (is_ge(f)) { + st = mk_ge_core (args[0], args[1], result); + } else if (m.is_not(f)) { + if (m.is_not (args[0], e)) { + result = e; + st = BR_DONE; + } + } + + return st; + } + + br_status mk_le_core (expr *arg1, expr * arg2, expr_ref & result) + { + // t <= -1 ==> t < 0 ==> ! (t >= 0) + if (m_util.is_int (arg1) && m_util.is_minus_one (arg2)) { + result = m.mk_not (m_util.mk_ge (arg1, mk_zero ())); + return BR_DONE; + } + return BR_FAILED; + } + br_status mk_ge_core (expr * arg1, expr * arg2, expr_ref & result) + { + // t >= 1 ==> t > 0 ==> ! (t <= 0) + if (m_util.is_int (arg1) && is_one (arg2)) { + + result = m.mk_not (m_util.mk_le (arg1, mk_zero ())); + return BR_DONE; + } + return BR_FAILED; + } + expr * mk_zero () {return m_util.mk_numeral (rational (0), true);} + bool is_one (expr const * n) const + {rational val; return m_util.is_numeral (n, val) && val.is_one ();} +}; + +void normalize (expr *e, expr_ref &out, + bool use_simplify_bounds, + bool use_factor_eqs) +{ + + params_ref params; + // arith_rewriter + params.set_bool ("sort_sums", true); + params.set_bool ("gcd_rounding", true); + params.set_bool ("arith_lhs", true); + // poly_rewriter + params.set_bool ("som", true); + params.set_bool ("flat", true); + + // apply rewriter + th_rewriter rw(out.m(), params); + rw (e, out); + + adhoc_rewriter_cfg adhoc_cfg(out.m ()); + rewriter_tpl adhoc_rw (out.m (), false, adhoc_cfg); + adhoc_rw (out.get (), out); + + if (out.m().is_and(out)) { + expr_ref_vector v(out.m()); + flatten_and (out, v); + + if (v.size() > 1) { + // sort arguments of the top-level and + std::stable_sort (v.c_ptr(), v.c_ptr () + v.size (), ast_lt_proc()); + + if (use_simplify_bounds) { + // remove redundant inequalities + simplify_bounds (v); + } + if (use_factor_eqs) { + // pick non-constant value representative for + // equivalence classes + expr_equiv_class eq_classes(out.m()); + factor_eqs(v, eq_classes); + equiv_to_expr(eq_classes, v); + } + + out = mk_and (v); + } + } +} + +// rewrite term such that the pretty printing is easier to read +struct adhoc_rewriter_rpp : public default_rewriter_cfg { + ast_manager &m; + arith_util m_arith; + + adhoc_rewriter_rpp (ast_manager &manager) : m(manager), m_arith(m) {} + + bool is_le(func_decl const * n) const + { return is_decl_of(n, m_arith.get_family_id (), OP_LE); } + bool is_ge(func_decl const * n) const + { return is_decl_of(n, m_arith.get_family_id (), OP_GE); } + bool is_lt(func_decl const * n) const + { return is_decl_of(n, m_arith.get_family_id (), OP_LT); } + bool is_gt(func_decl const * n) const + { return is_decl_of(n, m_arith.get_family_id (), OP_GT); } + bool is_zero (expr const * n) const + {rational val; return m_arith.is_numeral(n, val) && val.is_zero();} + + br_status reduce_app (func_decl * f, unsigned num, expr * const * args, + expr_ref & result, proof_ref & result_pr) + { + br_status st = BR_FAILED; + expr *e1, *e2, *e3, *e4; + + // rewrites (= (+ A (* -1 B)) 0) into (= A B) + if (m.is_eq (f) && is_zero (args [1]) && + m_arith.is_add (args[0], e1, e2) && + m_arith.is_mul (e2, e3, e4) && m_arith.is_minus_one (e3)) { + result = m.mk_eq (e1, e4); + return BR_DONE; + } + // simplify normalized leq, where right side is different from 0 + // rewrites (<= (+ A (* -1 B)) C) into (<= A B+C) + else if ((is_le(f) || is_lt(f) || is_ge(f) || is_gt(f)) && + m_arith.is_add (args[0], e1, e2) && + m_arith.is_mul (e2, e3, e4) && m_arith.is_minus_one (e3)) { + expr_ref rhs(m); + rhs = is_zero (args[1]) ? e4 : m_arith.mk_add(e4, args[1]); + + if (is_le(f)) { + result = m_arith.mk_le(e1, rhs); + st = BR_DONE; + } else if (is_lt(f)) { + result = m_arith.mk_lt(e1, rhs); + st = BR_DONE; + } else if (is_ge(f)) { + result = m_arith.mk_ge(e1, rhs); + st = BR_DONE; + } else if (is_gt(f)) { + result = m_arith.mk_gt(e1, rhs); + st = BR_DONE; + } else + { UNREACHABLE(); } + } + // simplify negation of ordering predicate + else if (m.is_not (f)) { + if (m_arith.is_lt(args[0], e1, e2)) { + result = m_arith.mk_ge(e1, e2); + st = BR_DONE; + } else if (m_arith.is_le(args[0], e1, e2)) { + result = m_arith.mk_gt(e1, e2); + st = BR_DONE; + } else if (m_arith.is_gt(args[0], e1, e2)) { + result = m_arith.mk_le(e1, e2); + st = BR_DONE; + } else if (m_arith.is_ge(args[0], e1, e2)) { + result = m_arith.mk_lt(e1, e2); + st = BR_DONE; + } + } + return st; + } + +}; +mk_epp::mk_epp(ast *t, ast_manager &m, unsigned indent, + unsigned num_vars, char const * var_prefix) : + mk_pp (t, m, m_epp_params, indent, num_vars, var_prefix), m_epp_expr(m) { + m_epp_params.set_uint("min_alias_size", UINT_MAX); + m_epp_params.set_uint("max_depth", UINT_MAX); + + if (is_expr (m_ast)) { + rw(to_expr(m_ast), m_epp_expr); + m_ast = m_epp_expr; + } +} + +void mk_epp::rw(expr *e, expr_ref &out) +{ + adhoc_rewriter_rpp cfg(out.m()); + rewriter_tpl arw(out.m(), false, cfg); + arw(e, out); +} + + void ground_expr (expr *e, expr_ref &out, app_ref_vector &vars) + { + expr_free_vars fv; + ast_manager &m = out.get_manager (); + fv (e); + if (vars.size () < fv.size ()) + { vars.resize(fv.size()); } + for (unsigned i = 0, sz = fv.size (); i < sz; ++i) { + SASSERT (fv[i]); + std::string str = "zk!" + datalog::to_string(sz - 1 - i); + vars [i] = m.mk_const (symbol(str.c_str()), fv [i]); + } + var_subst vs(m); + vs (e, vars.size (), (expr**) vars.c_ptr (), out); + } + + + struct index_term_finder { + ast_manager &m; + array_util m_array; + app_ref m_var; + expr_ref_vector &m_res; + + index_term_finder (ast_manager &mgr, app* v, expr_ref_vector &res) : m(mgr), m_array (m), m_var (v, m), m_res (res) {} + void operator() (var *n) {} + void operator() (quantifier *n) {} + void operator() (app *n) + { + expr *e1, *e2; + if (m_array.is_select (n) && n->get_arg (1) != m_var) { + m_res.push_back (n->get_arg (1)); + } else if (m.is_eq(n, e1, e2)) { + if (e1 == m_var) { m_res.push_back(e2); } + else if (e2 == m_var) { m_res.push_back(e1); } + } + } + }; + + bool mbqi_project_var (model_evaluator_util &mev, app* var, expr_ref &fml) + { + ast_manager &m = fml.get_manager (); + + expr_ref val(m); + mev.eval (var, val, false); + + TRACE ("mbqi_project_verbose", + tout << "MBQI: var: " << mk_pp (var, m) << "\n" + << "fml: " << mk_pp (fml, m) << "\n";); + expr_ref_vector terms (m); + index_term_finder finder (m, var, terms); + for_each_expr (finder, fml); + + + TRACE ("mbqi_project_verbose", + tout << "terms:\n"; + for (unsigned i = 0, e = terms.size (); i < e; ++i) + tout << i << ": " << mk_pp (terms.get (i), m) << "\n"; + ); + + for (unsigned i = 0, e = terms.size(); i < e; ++i) { + expr* term = terms.get (i); + expr_ref tval (m); + mev.eval (term, tval, false); + + TRACE ("mbqi_project_verbose", + tout << "term: " << mk_pp (term, m) + << " tval: " << mk_pp (tval, m) + << " val: " << mk_pp (val, m) << "\n";); + + // -- if the term does not contain an occurrence of var + // -- and is in the same equivalence class in the model + if (tval == val && !occurs (var, term)) { + TRACE ("mbqi_project", + tout << "MBQI: replacing " << mk_pp (var, m) << " with " << mk_pp (term, m) << "\n";); + expr_safe_replace sub(m); + sub.insert (var, term); + sub (fml); + return true; + } + } + + TRACE ("mbqi_project", + tout << "MBQI: failed to eliminate " << mk_pp (var, m) << " from " << mk_pp (fml, m) << "\n";); + + return false; + } + + void mbqi_project (model &M, app_ref_vector &vars, expr_ref &fml) + { + ast_manager &m = fml.get_manager (); + model_evaluator_util mev(m); + mev.set_model (M); + expr_ref tmp(m); + // -- evaluate to initialize mev cache + mev.eval (fml, tmp, false); + tmp.reset (); + + for (unsigned idx = 0; idx < vars.size (); ) { + if (mbqi_project_var (mev, vars.get (idx), fml)) { + vars[idx] = vars.back (); + vars.pop_back (); + } else { + idx++; + } + } + } + +bool contains_selects(expr* fml, ast_manager& m) +{ + array_util a_util(m); + if (!is_app(fml)) { return false; } + ast_mark done; + ptr_vector todo; + todo.push_back (to_app (fml)); + while (!todo.empty ()) { + app* a = todo.back (); + if (done.is_marked (a)) { + todo.pop_back (); + continue; + } + unsigned num_args = a->get_num_args (); + bool all_done = true; + for (unsigned i = 0; i < num_args; i++) { + expr* arg = a->get_arg (i); + if (!done.is_marked (arg) && is_app (arg)) { + todo.push_back (to_app (arg)); + all_done = false; + } + } + if (!all_done) { continue; } + todo.pop_back (); + if (a_util.is_select (a)) + { return true; } + done.mark (a, true); + } + return false; + } + +void get_select_indices(expr* fml, app_ref_vector& indices, ast_manager& m) +{ + array_util a_util(m); + if (!is_app(fml)) { return; } + ast_mark done; + ptr_vector todo; + todo.push_back (to_app (fml)); + while (!todo.empty ()) { + app* a = todo.back (); + if (done.is_marked (a)) { + todo.pop_back (); + continue; + } + unsigned num_args = a->get_num_args (); + bool all_done = true; + for (unsigned i = 0; i < num_args; i++) { + expr* arg = a->get_arg (i); + if (!done.is_marked (arg) && is_app (arg)) { + todo.push_back (to_app (arg)); + all_done = false; + } + } + if (!all_done) { continue; } + todo.pop_back (); + if (a_util.is_select (a)) { + SASSERT(a->get_num_args() == 2); + indices.push_back(to_app(a->get_arg(1))); + } + done.mark (a, true); + } + } + +void find_decls(expr* fml, app_ref_vector& decls, std::string& prefix) +{ + if (!is_app(fml)) { return; } + ast_mark done; + ptr_vector todo; + todo.push_back (to_app (fml)); + while (!todo.empty ()) { + app* a = todo.back (); + if (done.is_marked (a)) { + todo.pop_back (); + continue; + } + unsigned num_args = a->get_num_args (); + bool all_done = true; + for (unsigned i = 0; i < num_args; i++) { + expr* arg = a->get_arg (i); + if (!done.is_marked (arg) && is_app (arg)) { + todo.push_back (to_app (arg)); + all_done = false; + } + } + if (!all_done) { continue; } + todo.pop_back (); + if (a->get_decl()->get_name().str().find(prefix) != std::string::npos) + { decls.push_back(a); } + done.mark (a, true); + } + return; +} + +} +template class rewriter_tpl; +template class rewriter_tpl; +template class rewriter_tpl; diff --git a/src/muz/spacer/spacer_util.h b/src/muz/spacer/spacer_util.h new file mode 100644 index 000000000..f51df7a7b --- /dev/null +++ b/src/muz/spacer/spacer_util.h @@ -0,0 +1,180 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + spacer_util.h + +Abstract: + + Utility functions for SPACER. + +Author: + + Krystof Hoder (t-khoder) 2011-8-19. + Arie Gurfinkel + Anvesh Komuravelli + +Revision History: + +--*/ + +#ifndef _SPACER_UTIL_H_ +#define _SPACER_UTIL_H_ + +#include "ast.h" +#include "ast_pp.h" +#include "obj_hashtable.h" +#include "ref_vector.h" +#include "simplifier.h" +#include "trace.h" +#include "vector.h" +#include "arith_decl_plugin.h" +#include "array_decl_plugin.h" +#include "bv_decl_plugin.h" +#include "model.h" + +#include "stopwatch.h" +#include "spacer_antiunify.h" + +class model; +class model_core; +class model_evaluator; + +namespace spacer { + +inline unsigned infty_level () {return UINT_MAX;} + +inline bool is_infty_level(unsigned lvl) +{ return lvl == infty_level (); } + +inline unsigned next_level(unsigned lvl) +{ return is_infty_level(lvl)?lvl:(lvl+1); } + +inline unsigned prev_level (unsigned lvl) +{ + if(is_infty_level(lvl)) { return infty_level(); } + if(lvl == 0) { return 0; } + return lvl -1; +} + +struct pp_level { + unsigned m_level; + pp_level(unsigned l): m_level(l) {} +}; + +inline 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; + } +} + + +struct scoped_watch { + stopwatch &m_sw; + scoped_watch (stopwatch &sw, bool reset=false): m_sw(sw) + { + if(reset) { m_sw.reset(); } + m_sw.start (); + } + ~scoped_watch () {m_sw.stop ();} +}; + + +typedef ptr_vector app_vector; +typedef ptr_vector decl_vector; +typedef obj_hashtable func_decl_set; + + +class model_evaluator_util { + ast_manager& m; + model_ref m_model; + model_evaluator* m_mev; + + /// initialize with a given model. All previous state is lost. model can be NULL + void reset (model *model); +public: + model_evaluator_util(ast_manager& m); + ~model_evaluator_util(); + + void set_model(model &model) {reset (&model);} + model_ref &get_model() {return m_model;} + ast_manager& get_ast_manager() const {return m;} + +public: + bool is_true (const expr_ref_vector &v); + bool is_false(expr* x); + bool is_true(expr* x); + + bool eval (const expr_ref_vector &v, expr_ref &result, bool model_completion); + /// evaluates an expression + bool eval (expr *e, expr_ref &result, bool model_completion); + // expr_ref eval(expr* e, bool complete=true); +}; + + +/** + \brief replace variables that are used in many disequalities by + an equality using the model. + + Assumption: the model satisfies the conjunctions. +*/ +void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml); + +/** + \brief hoist non-boolean if expressions. +*/ +void hoist_non_bool_if(expr_ref& fml); + +bool is_difference_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls); + +bool is_utvpi_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls); + +/** + * do the following in sequence + * 1. use qe_lite to cheaply eliminate vars + * 2. for remaining boolean vars, substitute using M + * 3. use MBP for remaining array and arith variables + * 4. for any remaining arith variables, substitute using M + */ +void qe_project (ast_manager& m, app_ref_vector& vars, expr_ref& fml, + const model_ref& M, bool reduce_all_selects=false, bool native_mbp=false, + bool dont_sub=false); + +void qe_project (ast_manager& m, app_ref_vector& vars, expr_ref& fml, model_ref& M, expr_map& map); + +void expand_literals(ast_manager &m, expr_ref_vector& conjs); +void compute_implicant_literals (model_evaluator_util &mev, + expr_ref_vector &formula, expr_ref_vector &res); +void simplify_bounds (expr_ref_vector &lemmas); +void normalize(expr *e, expr_ref &out, bool use_simplify_bounds = true, bool factor_eqs = false); + +/** ground expression by replacing all free variables by skolem constants */ +void ground_expr (expr *e, expr_ref &out, app_ref_vector &vars); + + +void mbqi_project (model &M, app_ref_vector &vars, expr_ref &fml); + +bool contains_selects (expr* fml, ast_manager& m); +void get_select_indices (expr* fml, app_ref_vector& indices, ast_manager& m); + +void find_decls (expr* fml, app_ref_vector& decls, std::string& prefix); + +/** extended pretty-printer + * used for debugging + * disables aliasing of common sub-expressions +*/ +struct mk_epp : public mk_pp { + params_ref m_epp_params; + expr_ref m_epp_expr; + mk_epp(ast *t, ast_manager &m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0); + void rw(expr *e, expr_ref &out); + +}; + +} + +#endif diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp new file mode 100644 index 000000000..c6b85a3ea --- /dev/null +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -0,0 +1,519 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_virtual_solver.cpp + +Abstract: + + multi-solver view of a single smt::kernel + +Author: + + Arie Gurfinkel + +Notes: + +--*/ + +#include "spacer_virtual_solver.h" +#include "ast_util.h" +#include "ast_pp_util.h" +#include "spacer_util.h" +#include "bool_rewriter.h" + +#include "proof_checker.h" + +#include "scoped_proof.h" + +namespace spacer { +virtual_solver::virtual_solver(virtual_solver_factory &factory, + smt::kernel &context, app* pred) : + solver_na2as(context.m()), + m_factory(factory), + m(context.m()), + m_context(context), + m_pred(pred, m), + m_virtual(!m.is_true(pred)), + m_assertions(m), + m_head(0), + m_flat(m), + m_pushed(false), + m_in_delay_scope(false), + m_dump_benchmarks(factory.fparams().m_dump_benchmarks), + m_dump_counter(0), + m_proof(m) +{ + // -- insert m_pred->true background assumption this will not + // -- change m_context, but will add m_pred to + // -- the private field solver_na2as::m_assumptions + if (m_virtual) + { solver_na2as::assert_expr(m.mk_true(), m_pred); } +} + +virtual_solver::~virtual_solver() +{ + SASSERT(!m_pushed || get_scope_level() > 0); + if (m_pushed) { pop(get_scope_level()); } + + if (m_virtual) { + m_pred = m.mk_not(m_pred); + m_context.assert_expr(m_pred); + } +} + +namespace { +static bool matches_fact(expr_ref_vector &args, expr* &match) +{ + ast_manager &m = args.get_manager(); + expr *fact = args.back(); + for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i) { + expr *arg = args.get(i); + if (m.is_proof(arg) && + m.has_fact(to_app(arg)) && + m.get_fact(to_app(arg)) == fact) { + match = arg; + return true; + } + } + return false; +} + + +class elim_aux_assertions { + app_ref m_aux; +public: + elim_aux_assertions(app_ref aux) : m_aux(aux) {} + + void mk_or_core(expr_ref_vector &args, expr_ref &res) + { + ast_manager &m = args.get_manager(); + unsigned j = 0; + for (unsigned i = 0, sz = args.size(); i < sz; ++i) { + if (m.is_false(args.get(i))) { continue; } + if (i != j) { args [j] = args.get(i); } + ++j; + } + SASSERT(j >= 1); + res = j > 1 ? m.mk_or(j, args.c_ptr()) : args.get(0); + } + + void mk_app(func_decl *decl, expr_ref_vector &args, expr_ref &res) + { + ast_manager &m = args.get_manager(); + bool_rewriter brwr(m); + + if (m.is_or(decl)) + { mk_or_core(args, res); } + else if (m.is_iff(decl) && args.size() == 2) + // avoiding simplifying equalities. In particular, + // we don't want (= (not a) (not b)) to be reduced to (= a b) + { res = m.mk_iff(args.get(0), args.get(1)); } + else + { brwr.mk_app(decl, args.size(), args.c_ptr(), res); } + } + + void operator()(ast_manager &m, proof *pr, proof_ref &res) + { + DEBUG_CODE(proof_checker pc(m); + expr_ref_vector side(m); + SASSERT(pc.check(pr, side)); + ); + obj_map cache; + bool_rewriter brwr(m); + + // for reference counting of new proofs + app_ref_vector pinned(m); + + ptr_vector todo; + todo.push_back(pr); + + expr_ref not_aux(m); + not_aux = m.mk_not(m_aux); + + expr_ref_vector args(m); + + while (!todo.empty()) { + app *p, *r; + expr *a; + + p = todo.back(); + if (cache.find(pr, r)) { + todo.pop_back(); + continue; + } + + SASSERT(!todo.empty() || pr == p); + bool dirty = false; + unsigned todo_sz = todo.size(); + args.reset(); + for (unsigned i = 0, sz = p->get_num_args(); i < sz; ++i) { + expr* arg = p->get_arg(i); + if (arg == m_aux.get()) { + dirty = true; + args.push_back(m.mk_true()); + } else if (arg == not_aux.get()) { + dirty = true; + args.push_back(m.mk_false()); + } + // skip (asserted m_aux) + else if (m.is_asserted(arg, a) && a == m_aux.get()) { + dirty = true; + } + // skip (hypothesis m_aux) + else if (m.is_hypothesis(arg, a) && a == m_aux.get()) { + dirty = true; + } else if (is_app(arg) && cache.find(to_app(arg), r)) { + dirty |= (arg != r); + args.push_back(r); + } else if (is_app(arg)) + { todo.push_back(to_app(arg)); } + else + // -- not an app + { args.push_back(arg); } + + } + if (todo_sz < todo.size()) { + // -- process parents + args.reset(); + continue; + } + + // ready to re-create + app_ref newp(m); + if (!dirty) { newp = p; } + else if (m.is_unit_resolution(p)) { + if (args.size() == 2) + // unit resolution with m_aux that got collapsed to nothing + { newp = to_app(args.get(0)); } + else { + ptr_vector parents; + for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i) + { parents.push_back(to_app(args.get(i))); } + SASSERT(parents.size() == args.size() - 1); + newp = m.mk_unit_resolution(parents.size(), parents.c_ptr()); + // XXX the old and new facts should be + // equivalent. The test here is much + // stronger. It might need to be relaxed. + SASSERT(m.get_fact(newp) == args.back()); + pinned.push_back(newp); + } + } else if (matches_fact(args, a)) { + newp = to_app(a); + } else { + expr_ref papp(m); + mk_app(p->get_decl(), args, papp); + newp = to_app(papp.get()); + pinned.push_back(newp); + } + cache.insert(p, newp); + todo.pop_back(); + CTRACE("virtual", + p->get_decl_kind() == PR_TH_LEMMA && + p->get_decl()->get_parameter(0).get_symbol() == "arith" && + p->get_decl()->get_num_parameters() > 1 && + p->get_decl()->get_parameter(1).get_symbol() == "farkas", + tout << "Old pf: " << mk_pp(p, m) << "\n" + << "New pf: " << mk_pp(newp, m) << "\n";); + } + + proof *r; + VERIFY(cache.find(pr, r)); + + DEBUG_CODE( + proof_checker pc(m); + expr_ref_vector side(m); + SASSERT(pc.check(r, side)); + ); + + res = r ; + } +}; +} + +proof *virtual_solver::get_proof() +{ + scoped_watch _t_(m_factory.m_proof_watch); + + if (!m_proof.get()) { + elim_aux_assertions pc(m_pred); + m_proof = m_context.get_proof(); + pc(m, m_proof.get(), m_proof); + } + return m_proof.get(); +} + +bool virtual_solver::is_aux_predicate(expr *p) +{return is_app(p) && to_app(p) == m_pred.get();} + +lbool virtual_solver::check_sat_core(unsigned num_assumptions, + expr *const * assumptions) +{ + SASSERT(!m_pushed || get_scope_level() > 0); + m_proof.reset(); + scoped_watch _t_(m_factory.m_check_watch); + m_factory.m_stats.m_num_smt_checks++; + + stopwatch sw; + sw.start(); + internalize_assertions(); + if (false) { + std::stringstream file_name; + file_name << "virt_solver"; + if (m_virtual) { file_name << "_" << m_pred->get_decl()->get_name(); } + file_name << "_" << (m_dump_counter++) << ".smt2"; + + verbose_stream() << "Dumping SMT2 benchmark: " << file_name.str() << "\n"; + + std::ofstream out(file_name.str().c_str()); + + to_smt2_benchmark(out, m_context, num_assumptions, assumptions, + "virt_solver"); + + out << "(exit)\n"; + out.close(); + } + lbool res = m_context.check(num_assumptions, assumptions); + sw.stop(); + if (res == l_true) { + m_factory.m_check_sat_watch.add(sw); + m_factory.m_stats.m_num_sat_smt_checks++; + } else if (res == l_undef) { + m_factory.m_check_undef_watch.add(sw); + m_factory.m_stats.m_num_undef_smt_checks++; + } + set_status(res); + + if (m_dump_benchmarks && + sw.get_seconds() >= m_factory.fparams().m_dump_min_time) { + std::stringstream file_name; + file_name << "virt_solver"; + if (m_virtual) { file_name << "_" << m_pred->get_decl()->get_name(); } + file_name << "_" << (m_dump_counter++) << ".smt2"; + + std::ofstream out(file_name.str().c_str()); + + + out << "(set-info :status "; + if (res == l_true) { out << "sat"; } + else if (res == l_false) { out << "unsat"; } + else { out << "unknown"; } + out << ")\n"; + + to_smt2_benchmark(out, m_context, num_assumptions, assumptions, + "virt_solver"); + + out << "(exit)\n"; + ::statistics st; + m_context.collect_statistics(st); + st.update("time", sw.get_seconds()); + st.display_smt2(out); + + out.close(); + + if (m_factory.fparams().m_dump_recheck) { + scoped_no_proof _no_proof_(m); + smt_params p; + stopwatch sw2; + smt::kernel kernel(m, p); + for (unsigned i = 0, sz = m_context.size(); i < sz; ++i) + { kernel.assert_expr(m_context.get_formulas()[i]); } + sw2.start(); + kernel.check(num_assumptions, assumptions); + sw2.stop(); + verbose_stream() << file_name.str() << " :orig " + << sw.get_seconds() << " :new " << sw2.get_seconds(); + } + } + + + return res; +} + +void virtual_solver::push_core() +{ + SASSERT(!m_pushed || get_scope_level() > 0); + if (m_in_delay_scope) { + // second push + internalize_assertions(); + m_context.push(); + m_pushed = true; + m_in_delay_scope = false; + } + + if (!m_pushed) { m_in_delay_scope = true; } + else { + SASSERT(m_pushed); + SASSERT(!m_in_delay_scope); + m_context.push(); + } +} +void virtual_solver::pop_core(unsigned n) +{ + SASSERT(!m_pushed || get_scope_level() > 0); + if (m_pushed) { + SASSERT(!m_in_delay_scope); + m_context.pop(n); + m_pushed = get_scope_level() - n > 0; + } else + { m_in_delay_scope = get_scope_level() - n > 0; } +} + +void virtual_solver::get_unsat_core(ptr_vector &r) +{ + for (unsigned i = 0, sz = m_context.get_unsat_core_size(); i < sz; ++i) { + expr *core = m_context.get_unsat_core_expr(i); + if (is_aux_predicate(core)) { continue; } + r.push_back(core); + } +} + +void virtual_solver::assert_expr(expr *e) +{ + SASSERT(!m_pushed || get_scope_level() > 0); + if (m.is_true(e)) { return; } + if (m_in_delay_scope) { + internalize_assertions(); + m_context.push(); + m_pushed = true; + m_in_delay_scope = false; + } + + if (m_pushed) + { m_context.assert_expr(e); } + else { + m_flat.push_back(e); + flatten_and(m_flat); + m_assertions.append(m_flat); + m_flat.reset(); + } +} +void virtual_solver::internalize_assertions() +{ + SASSERT(!m_pushed || m_head == m_assertions.size()); + for (unsigned sz = m_assertions.size(); m_head < sz; ++m_head) { + expr_ref f(m); + f = m.mk_implies(m_pred, (m_assertions.get(m_head))); + m_context.assert_expr(f); + } +} +void virtual_solver::refresh() +{ + SASSERT(!m_pushed); + m_head = 0; +} + +void virtual_solver::reset() +{ + SASSERT(!m_pushed); + m_head = 0; + m_assertions.reset(); + m_factory.refresh(); +} + +void virtual_solver::get_labels(svector &r) +{ + r.reset(); + buffer tmp; + m_context.get_relevant_labels(0, tmp); + r.append(tmp.size(), tmp.c_ptr()); +} + +solver* virtual_solver::translate(ast_manager& m, params_ref const& p) +{ + UNREACHABLE(); + return 0; +} +void virtual_solver::updt_params(params_ref const &p) +{ m_factory.updt_params(p); } +void virtual_solver::collect_param_descrs(param_descrs &r) +{ m_factory.collect_param_descrs(r); } +void virtual_solver::set_produce_models(bool f) +{ m_factory.set_produce_models(f); } +bool virtual_solver::get_produce_models() +{return m_factory.get_produce_models(); } +smt_params &virtual_solver::fparams() +{return m_factory.fparams();} + +void virtual_solver::to_smt2_benchmark(std::ostream &out, + smt::kernel &context, + unsigned num_assumptions, + expr * const * assumptions, + char const * name, + symbol const &logic, + char const * status, + char const * attributes) +{ + ast_pp_util pp(m); + expr_ref_vector asserts(m); + + + for (unsigned i = 0, sz = context.size(); i < sz; ++i) { + asserts.push_back(context.get_formulas()[i]); + pp.collect(asserts.back()); + } + pp.collect(num_assumptions, assumptions); + pp.display_decls(out); + pp.display_asserts(out, asserts); + out << "(check-sat "; + for (unsigned i = 0; i < num_assumptions; ++i) + { out << mk_pp(assumptions[i], m) << " "; } + out << ")\n"; +} + + +virtual_solver_factory::virtual_solver_factory(ast_manager &mgr, smt_params &fparams) : + m_fparams(fparams), m(mgr), m_context(m, m_fparams) +{ + m_stats.reset(); +} + +virtual_solver* virtual_solver_factory::mk_solver() +{ + std::stringstream name; + name << "vsolver#" << m_solvers.size(); + app_ref pred(m); + pred = m.mk_const(symbol(name.str().c_str()), m.mk_bool_sort()); + SASSERT(m_context.get_scope_level() == 0); + m_solvers.push_back(alloc(virtual_solver, *this, m_context, pred)); + return m_solvers.back(); +} + +void virtual_solver_factory::collect_statistics(statistics &st) const +{ + m_context.collect_statistics(st); + st.update("time.virtual_solver.smt.total", m_check_watch.get_seconds()); + st.update("time.virtual_solver.smt.total.sat", m_check_sat_watch.get_seconds()); + st.update("time.virtual_solver.smt.total.undef", m_check_undef_watch.get_seconds()); + st.update("time.virtual_solver.proof", m_proof_watch.get_seconds()); + st.update("virtual_solver.checks", m_stats.m_num_smt_checks); + st.update("virtual_solver.checks.sat", m_stats.m_num_sat_smt_checks); + st.update("virtual_solver.checks.undef", m_stats.m_num_undef_smt_checks); +} +void virtual_solver_factory::reset_statistics() +{ + m_context.reset_statistics(); + m_stats.reset(); + m_check_sat_watch.reset(); + m_check_undef_watch.reset(); + m_check_watch.reset(); + m_proof_watch.reset(); +} + +void virtual_solver_factory::refresh() +{ + m_context.reset(); + for (unsigned i = 0, e = m_solvers.size(); i < e; ++i) + { m_solvers [i]->refresh(); } +} + +virtual_solver_factory::~virtual_solver_factory() +{ + for (unsigned i = 0, e = m_solvers.size(); i < e; ++i) + { dealloc(m_solvers [i]); } +} + + + +} diff --git a/src/muz/spacer/spacer_virtual_solver.h b/src/muz/spacer/spacer_virtual_solver.h new file mode 100644 index 000000000..b5e97dce0 --- /dev/null +++ b/src/muz/spacer/spacer_virtual_solver.h @@ -0,0 +1,153 @@ +/** +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + spacer_virtual_solver.h + +Abstract: + + multi-solver view of a single smt::kernel + +Author: + + Arie Gurfinkel + +Notes: + +--*/ +#ifndef SPACER_VIRTUAL_SOLVER_H_ +#define SPACER_VIRTUAL_SOLVER_H_ +#include"ast.h" +#include"params.h" +#include"solver_na2as.h" +#include"smt_kernel.h" +#include"smt_params.h" +#include"stopwatch.h" +namespace spacer { +class virtual_solver_factory; + +class virtual_solver : public solver_na2as { + friend class virtual_solver_factory; + +private: + virtual_solver_factory &m_factory; + ast_manager &m; + smt::kernel &m_context; + app_ref m_pred; + + bool m_virtual; + expr_ref_vector m_assertions; + unsigned m_head; + // temporary to flatten conjunction + expr_ref_vector m_flat; + + bool m_pushed; + bool m_in_delay_scope; + bool m_dump_benchmarks; + unsigned m_dump_counter; + + proof_ref m_proof; + + virtual_solver(virtual_solver_factory &factory, smt::kernel &context, app* pred); + + bool is_aux_predicate(expr *p); + void internalize_assertions(); + void to_smt2_benchmark(std::ostream &out, + smt::kernel &context, + unsigned num_assumptions, + expr * const * assumptions, + char const * name = "benchmarks", + symbol const &logic = symbol::null, + char const * status = "unknown", + char const * attributes = ""); + + void refresh(); + +public: + virtual ~virtual_solver(); + virtual unsigned get_num_assumptions() const + { + unsigned sz = solver_na2as::get_num_assumptions(); + return m_virtual ? sz - 1 : sz; + } + virtual expr* get_assumption(unsigned idx) const + { + if(m_virtual) { idx++; } + return solver_na2as::get_assumption(idx); + } + + virtual void get_unsat_core(ptr_vector &r); + virtual void assert_expr(expr *e); + virtual void collect_statistics(statistics &st) const {} + virtual void get_model(model_ref &m) {m_context.get_model(m);} + virtual proof* get_proof(); + virtual std::string reason_unknown() const + {return m_context.last_failure_as_string();} + virtual void set_reason_unknown(char const *msg) + {m_context.set_reason_unknown(msg);} + virtual ast_manager& get_manager() const {return m;} + virtual void get_labels(svector &r); + virtual void set_produce_models(bool f); + virtual bool get_produce_models(); + virtual smt_params &fparams(); + virtual void reset(); + + virtual void set_progress_callback(progress_callback *callback) + {UNREACHABLE();} + + virtual solver *translate(ast_manager &m, params_ref const &p); + + virtual void updt_params(params_ref const &p); + virtual void collect_param_descrs(param_descrs &r); + + +protected: + virtual lbool check_sat_core(unsigned num_assumptions, expr *const * assumptions); + virtual void push_core(); + virtual void pop_core(unsigned n); +}; + +/// multi-solver abstraction on top of a single smt::kernel +class virtual_solver_factory { + friend class virtual_solver; +private: + smt_params &m_fparams; + ast_manager &m; + smt::kernel m_context; + /// solvers managed by this factory + ptr_vector m_solvers; + + struct stats { + unsigned m_num_smt_checks; + unsigned m_num_sat_smt_checks; + unsigned m_num_undef_smt_checks; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + + stats m_stats; + stopwatch m_check_watch; + stopwatch m_check_sat_watch; + stopwatch m_check_undef_watch; + stopwatch m_proof_watch; + + + void refresh(); +public: + virtual_solver_factory(ast_manager &mgr, smt_params &fparams); + virtual ~virtual_solver_factory(); + virtual_solver* mk_solver(); + void collect_statistics(statistics &st) const; + void reset_statistics(); + void updt_params(params_ref const &p) { m_fparams.updt_params(p); } + void collect_param_descrs(param_descrs &r) { /* empty */ } + void set_produce_models(bool f) { m_fparams.m_model = f; } + bool get_produce_models() { return m_fparams.m_model; } + smt_params &fparams() { return m_fparams; } +}; + +} + + +#endif From a73023da97426cea00168657af3bd0ab4b315559 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:38:48 -0400 Subject: [PATCH 048/488] preserve rule names when changing rules --- src/muz/base/dl_rule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muz/base/dl_rule.cpp b/src/muz/base/dl_rule.cpp index 4581c8aac..af48d0f8b 100644 --- a/src/muz/base/dl_rule.cpp +++ b/src/muz/base/dl_rule.cpp @@ -639,7 +639,7 @@ namespace datalog { tail.push_back(ensure_app(conjs[i].get())); } tail_neg.resize(tail.size(), false); - r = mk(r->get_head(), tail.size(), tail.c_ptr(), tail_neg.c_ptr()); + r = mk(r->get_head(), tail.size(), tail.c_ptr(), tail_neg.c_ptr(), r->name()); TRACE("dl", r->display(m_ctx, tout << "reduced rule\n");); } } From ffa495736243cacd3d3e57af8e609864973285f9 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:39:16 -0400 Subject: [PATCH 049/488] do not use array_der when simplifying rules --- src/muz/base/dl_rule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muz/base/dl_rule.cpp b/src/muz/base/dl_rule.cpp index af48d0f8b..26a5b748e 100644 --- a/src/muz/base/dl_rule.cpp +++ b/src/muz/base/dl_rule.cpp @@ -54,7 +54,7 @@ namespace datalog { m_head(m), m_args(m), m_hnf(m), - m_qe(m, params_ref()), + m_qe(m, params_ref(), false), m_rwr(m), m_ufproc(m) {} From 1530a39a9648e0380532f8909cba1ad70c58d34e Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:42:44 -0400 Subject: [PATCH 050/488] stubs for spacer-specific API --- src/muz/base/dl_engine_base.h | 16 ++++++++++++++++ src/muz/base/dl_util.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/muz/base/dl_engine_base.h b/src/muz/base/dl_engine_base.h index 380ae6e07..9c20c712d 100644 --- a/src/muz/base/dl_engine_base.h +++ b/src/muz/base/dl_engine_base.h @@ -20,6 +20,7 @@ Revision History: #define DL_ENGINE_BASE_H_ #include "model/model.h" +#include "muz/base/dl_util.h" namespace datalog { enum DL_ENGINE { @@ -44,6 +45,9 @@ namespace datalog { virtual ~engine_base() {} virtual expr_ref get_answer() = 0; + virtual expr_ref get_ground_sat_answer () { + throw default_exception(std::string("operation is not supported for ") + m_name); + } virtual lbool query(expr* q) = 0; virtual lbool query(unsigned num_rels, func_decl*const* rels) { if (num_rels != 1) return l_undef; @@ -65,6 +69,9 @@ namespace datalog { } return query(q); } + virtual lbool query_from_lvl (expr* q, unsigned lvl) { + throw default_exception(std::string("operation is not supported for ") + m_name); + } virtual void reset_statistics() {} virtual void display_profile(std::ostream& out) {} @@ -72,18 +79,27 @@ namespace datalog { virtual unsigned get_num_levels(func_decl* pred) { throw default_exception(std::string("get_num_levels is not supported for ") + m_name); } + virtual expr_ref get_reachable(func_decl* pred) { + throw default_exception(std::string("operation is not supported for ") + m_name); + } virtual expr_ref get_cover_delta(int level, func_decl* pred) { throw default_exception(std::string("operation is not supported for ") + m_name); } virtual void add_cover(int level, func_decl* pred, expr* property) { throw default_exception(std::string("operation is not supported for ") + m_name); } + virtual void add_invariant (func_decl *pred, expr *property) { + throw default_exception(std::string("operation is not supported for ") + m_name); + } virtual void display_certificate(std::ostream& out) const { throw default_exception(std::string("certificates are not supported for ") + m_name); } virtual model_ref get_model() { return model_ref(alloc(model, m)); } + virtual void get_rules_along_trace (rule_ref_vector& rules) { + throw default_exception(std::string("get_rules_along_trace is not supported for ") + m_name); + } virtual proof_ref get_proof() { return proof_ref(m.mk_asserted(m.mk_true()), m); } diff --git a/src/muz/base/dl_util.h b/src/muz/base/dl_util.h index 48d420bfb..d04e4037c 100644 --- a/src/muz/base/dl_util.h +++ b/src/muz/base/dl_util.h @@ -52,6 +52,7 @@ namespace datalog { ~verbose_action(); }; + typedef ref_vector rule_ref_vector; enum PDR_CACHE_MODE { NO_CACHE, HASH_CACHE, From c3d433ede0deacc278e53eeaa7de4f5fc593f3d7 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:46:59 -0400 Subject: [PATCH 051/488] implemented spacer-specic muz API --- src/muz/base/dl_context.cpp | 77 +++++++++++++++++++++++++++++++++++++ src/muz/base/dl_context.h | 25 ++++++++++++ 2 files changed, 102 insertions(+) diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 28a456b22..7be434477 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -229,6 +229,7 @@ namespace datalog { m_enable_bind_variables(true), m_last_status(OK), m_last_answer(m), + m_last_ground_answer(m), m_engine_type(LAST_ENGINE) { re.set_context(this); updt_params(pa); @@ -306,6 +307,8 @@ namespace datalog { bool context::compress_unbound() const { return m_params->xform_compress_unbound(); } bool context::quantify_arrays() const { return m_params->xform_quantify_arrays(); } bool context::instantiate_quantifiers() const { return m_params->xform_instantiate_quantifiers(); } + bool context::array_blast() const { return m_params->xform_array_blast(); } + bool context::array_blast_full() const { return m_params->xform_array_blast_full(); } void context::register_finite_sort(sort * s, sort_kind k) { @@ -546,10 +549,20 @@ namespace datalog { return m_engine->get_cover_delta(level, pred); } + expr_ref context::get_reachable(func_decl *pred) { + ensure_engine(); + return m_engine->get_reachable(pred); + } void context::add_cover(int level, func_decl* pred, expr* property) { ensure_engine(); m_engine->add_cover(level, pred, property); } + + void context::add_invariant(func_decl* pred, expr *property) + { + ensure_engine(); + m_engine->add_invariant(pred, property); + } void context::check_rules(rule_set& r) { m_rule_properties.set_generate_proof(generate_proof_trace()); @@ -561,6 +574,7 @@ namespace datalog { m_rule_properties.check_nested_free(); m_rule_properties.check_infinite_sorts(); break; + case SPACER_ENGINE: case PDR_ENGINE: m_rule_properties.collect(r); m_rule_properties.check_existential_tail(); @@ -792,6 +806,9 @@ namespace datalog { if (e == symbol("datalog")) { m_engine_type = DATALOG_ENGINE; } + else if (e == symbol("spacer")) { + m_engine_type = SPACER_ENGINE; + } else if (e == symbol("pdr")) { m_engine_type = PDR_ENGINE; } @@ -844,8 +861,10 @@ namespace datalog { m_mc = mk_skip_model_converter(); m_last_status = OK; m_last_answer = 0; + m_last_ground_answer = 0; switch (get_engine()) { case DATALOG_ENGINE: + case SPACER_ENGINE: case PDR_ENGINE: case QPDR_ENGINE: case BMC_ENGINE: @@ -867,6 +886,28 @@ namespace datalog { return m_engine->query(query); } + lbool context::query_from_lvl (expr* query, unsigned lvl) { + m_mc = mk_skip_model_converter(); + m_last_status = OK; + m_last_answer = 0; + m_last_ground_answer = 0; + switch (get_engine()) { + case DATALOG_ENGINE: + case SPACER_ENGINE: + case PDR_ENGINE: + case QPDR_ENGINE: + case BMC_ENGINE: + case QBMC_ENGINE: + case TAB_ENGINE: + case CLP_ENGINE: + flush_add_rules(); + break; + default: + UNREACHABLE(); + } + ensure_engine(); + return m_engine->query_from_lvl (query, lvl); + } model_ref context::get_model() { ensure_engine(); return m_engine->get_model(); @@ -905,6 +946,42 @@ namespace datalog { return m_last_answer.get(); } + expr* context::get_ground_sat_answer () { + if (m_last_ground_answer) { + return m_last_ground_answer; + } + ensure_engine (); + m_last_ground_answer = m_engine->get_ground_sat_answer (); + return m_last_ground_answer; + } + + void context::get_rules_along_trace (rule_ref_vector& rules) { + ensure_engine (); + m_engine->get_rules_along_trace (rules); + } + + void context::get_rules_along_trace_as_formulas (expr_ref_vector& rules, svector& names) { + rule_manager& rm = get_rule_manager (); + rule_ref_vector rv (rm); + get_rules_along_trace (rv); + expr_ref fml (m); + rule_ref_vector::iterator it = rv.begin (), end = rv.end (); + for (; it != end; it++) { + m_rule_manager.to_formula (**it, fml); + rules.push_back (fml); + // The concatenated names are already stored last-first, so do not need to be reversed here + const symbol& rule_name = (*it)->name(); + names.push_back (rule_name); + + TRACE ("dl", + if (rule_name == symbol::null) { + tout << "Encountered unnamed rule: "; + (*it)->display(*this, tout); + tout << "\n"; + }); + } + } + void context::display_certificate(std::ostream& out) { ensure_engine(); m_engine->display_certificate(out); diff --git a/src/muz/base/dl_context.h b/src/muz/base/dl_context.h index 0e1d47609..738c2559e 100644 --- a/src/muz/base/dl_context.h +++ b/src/muz/base/dl_context.h @@ -207,6 +207,7 @@ namespace datalog { bool m_enable_bind_variables; execution_result m_last_status; expr_ref m_last_answer; + expr_ref m_last_ground_answer; DL_ENGINE m_engine_type; @@ -277,6 +278,8 @@ namespace datalog { bool xform_bit_blast() const; bool xform_slice() const; bool xform_coi() const; + bool array_blast() const; + bool array_blast_full() const; void register_finite_sort(sort * s, sort_kind k); @@ -407,6 +410,10 @@ namespace datalog { */ unsigned get_num_levels(func_decl* pred); + /** + Retrieve reachable facts of 'pred'. + */ + expr_ref get_reachable(func_decl *pred); /** Retrieve the current cover of 'pred' up to 'level' unfoldings. Return just the delta that is known at 'level'. To @@ -421,6 +428,11 @@ namespace datalog { */ void add_cover(int level, func_decl* pred, expr* property); + /** + Add an invariant of predicate 'pred'. + */ + void add_invariant (func_decl *pred, expr *property); + /** \brief Check rule subsumption. */ @@ -509,6 +521,7 @@ namespace datalog { lbool query(expr* q); + lbool query_from_lvl (expr* q, unsigned lvl); /** \brief retrieve model from inductive invariant that shows query is unsat. @@ -545,6 +558,18 @@ namespace datalog { in the query that are derivable. */ expr* get_answer_as_formula(); + /** + * get bottom-up (from query) sequence of ground predicate instances + * (for e.g. P(0,1,0,0,3)) that together form a ground derivation to query + */ + expr* get_ground_sat_answer (); + + /** + * \brief obtain the sequence of rules along the counterexample trace + */ + void get_rules_along_trace (rule_ref_vector& rules); + + void get_rules_along_trace_as_formulas (expr_ref_vector& rules, svector& names); void collect_statistics(statistics& st) const; From d080c146a2152ced1bbd9d164e4f6a57f8d0dea9 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:50:17 -0400 Subject: [PATCH 052/488] public API for spacer --- src/CMakeLists.txt | 2 + src/api/CMakeLists.txt | 1 + src/api/api_datalog.cpp | 1 + src/api/api_datalog_spacer.inc | 113 +++++++++++++++++++++ src/api/api_qe.cpp | 179 +++++++++++++++++++++++++++++++++ src/api/z3.h | 1 + src/api/z3_spacer.h | 143 ++++++++++++++++++++++++++ 7 files changed, 440 insertions(+) create mode 100644 src/api/api_datalog_spacer.inc create mode 100644 src/api/api_qe.cpp create mode 100644 src/api/z3_spacer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fe9fa2a82..3df33aac9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ set(Z3_API_HEADER_FILES_TO_SCAN z3_optimization.h z3_interp.h z3_fpa.h + z3_spacer.h ) set(Z3_FULL_PATH_API_HEADER_FILES_TO_SCAN "") foreach (header_file ${Z3_API_HEADER_FILES_TO_SCAN}) @@ -169,6 +170,7 @@ set (libz3_public_headers z3_polynomial.h z3_rcf.h z3_v1.h + z3_spacer.h ) foreach (header ${libz3_public_headers}) set_property(TARGET libz3 APPEND PROPERTY diff --git a/src/api/CMakeLists.txt b/src/api/CMakeLists.txt index 79c5fc1c9..a413376ac 100644 --- a/src/api/CMakeLists.txt +++ b/src/api/CMakeLists.txt @@ -57,6 +57,7 @@ z3_add_component(api api_parsers.cpp api_pb.cpp api_polynomial.cpp + api_qe.cpp api_quant.cpp api_rcf.cpp api_seq.cpp diff --git a/src/api/api_datalog.cpp b/src/api/api_datalog.cpp index b57247fb1..8f863ed42 100644 --- a/src/api/api_datalog.cpp +++ b/src/api/api_datalog.cpp @@ -605,5 +605,6 @@ extern "C" { } +#include "api_datalog_spacer.inc" }; diff --git a/src/api/api_datalog_spacer.inc b/src/api/api_datalog_spacer.inc new file mode 100644 index 000000000..871d2be63 --- /dev/null +++ b/src/api/api_datalog_spacer.inc @@ -0,0 +1,113 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + api_datalog_spacer.inc + +Abstract: + + Spacer-specific datalog API + +Author: + + Arie Gurfinkel (arie) + +Notes: + this file is included at the bottom of api_datalog.cpp + +--*/ + Z3_lbool Z3_API Z3_fixedpoint_query_from_lvl (Z3_context c, Z3_fixedpoint d, Z3_ast q, unsigned lvl) { + Z3_TRY; + LOG_Z3_fixedpoint_query_from_lvl (c, d, q, lvl); + RESET_ERROR_CODE(); + lbool r = l_undef; + unsigned timeout = to_fixedpoint(d)->m_params.get_uint("timeout", mk_c(c)->get_timeout()); + unsigned rlimit = to_fixedpoint(d)->m_params.get_uint("rlimit", mk_c(c)->get_rlimit()); + { + scoped_rlimit _rlimit(mk_c(c)->m().limit(), rlimit); + cancel_eh eh(mk_c(c)->m().limit()); + api::context::set_interruptable si(*(mk_c(c)), eh); + scoped_timer timer(timeout, &eh); + try { + r = to_fixedpoint_ref(d)->ctx().query_from_lvl (to_expr(q), lvl); + } + catch (z3_exception& ex) { + mk_c(c)->handle_exception(ex); + r = l_undef; + } + to_fixedpoint_ref(d)->ctx().cleanup(); + } + return of_lbool(r); + Z3_CATCH_RETURN(Z3_L_UNDEF); + } + + Z3_ast Z3_API Z3_fixedpoint_get_ground_sat_answer(Z3_context c, Z3_fixedpoint d) { + Z3_TRY; + LOG_Z3_fixedpoint_get_ground_sat_answer(c, d); + RESET_ERROR_CODE(); + expr* e = to_fixedpoint_ref(d)->ctx().get_ground_sat_answer(); + mk_c(c)->save_ast_trail(e); + RETURN_Z3(of_expr(e)); + Z3_CATCH_RETURN(0); + } + + Z3_ast_vector Z3_API Z3_fixedpoint_get_rules_along_trace( + Z3_context c, + Z3_fixedpoint d) + { + Z3_TRY; + LOG_Z3_fixedpoint_get_rules_along_trace(c, d); + ast_manager& m = mk_c(c)->m(); + Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m); + mk_c(c)->save_object(v); + expr_ref_vector rules(m); + svector names; + + to_fixedpoint_ref(d)->ctx().get_rules_along_trace_as_formulas(rules, names); + for (unsigned i = 0; i < rules.size(); ++i) { + v->m_ast_vector.push_back(rules[i].get()); + } + RETURN_Z3(of_ast_vector(v)); + Z3_CATCH_RETURN(0); + } + + Z3_symbol Z3_API Z3_fixedpoint_get_rule_names_along_trace( + Z3_context c, + Z3_fixedpoint d) + { + Z3_TRY; + LOG_Z3_fixedpoint_get_rule_names_along_trace(c, d); + ast_manager& m = mk_c(c)->m(); + Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m); + mk_c(c)->save_object(v); + expr_ref_vector rules(m); + svector names; + std::stringstream ss; + + to_fixedpoint_ref(d)->ctx().get_rules_along_trace_as_formulas(rules, names); + for (unsigned i = 0; i < names.size(); ++i) { + ss << ";" << names[i].str(); + } + RETURN_Z3(of_symbol(symbol(ss.str().substr(1).c_str()))); + Z3_CATCH_RETURN(0); + } + + void Z3_API Z3_fixedpoint_add_invariant(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred, Z3_ast property) { + Z3_TRY; + LOG_Z3_fixedpoint_add_invariant(c, d, pred, property); + RESET_ERROR_CODE(); + to_fixedpoint_ref(d)->ctx ().add_invariant(to_func_decl(pred), to_expr(property)); + Z3_CATCH; + } + + Z3_ast Z3_API Z3_fixedpoint_get_reachable(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred) { + Z3_TRY; + LOG_Z3_fixedpoint_get_reachable(c, d, pred); + RESET_ERROR_CODE(); + expr_ref r = to_fixedpoint_ref(d)->ctx().get_reachable(to_func_decl(pred)); + mk_c(c)->save_ast_trail(r); + RETURN_Z3(of_expr(r.get())); + Z3_CATCH_RETURN(0); + } + diff --git a/src/api/api_qe.cpp b/src/api/api_qe.cpp new file mode 100644 index 000000000..ee49acc2a --- /dev/null +++ b/src/api/api_qe.cpp @@ -0,0 +1,179 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + api_qe.cpp + +Abstract: + + Model-based Projection (MBP) and Quantifier Elimination (QE) API + +Author: + + Arie Gurfinkel (arie) + +Notes: + +--*/ + +#include +#include "z3.h" +#include "api_log_macros.h" +#include "api_context.h" +#include "api_util.h" +#include "api_model.h" +#include "api_ast_map.h" +#include "api_ast_vector.h" + +#include "qe_vartest.h" +#include "qe_lite.h" +#include "spacer_util.h" + +#include "expr_map.h" + +extern "C" +{ + Z3_ast Z3_API Z3_qe_model_project (Z3_context c, + Z3_model m, + unsigned num_bounds, + Z3_app const bound[], + Z3_ast body) + { + Z3_TRY; + LOG_Z3_qe_model_project (c, m, num_bounds, bound, body); + RESET_ERROR_CODE(); + + app_ref_vector vars(mk_c(c)->m ()); + for (unsigned i = 0; i < num_bounds; ++i) + { + app *a = to_app (bound [i]); + if (a->get_kind () != AST_APP) + { + SET_ERROR_CODE (Z3_INVALID_ARG); + RETURN_Z3(0); + } + vars.push_back (a); + } + + expr_ref result (mk_c(c)->m ()); + result = to_expr (body); + model_ref model (to_model_ref (m)); + spacer::qe_project (mk_c(c)->m (), vars, result, model); + mk_c(c)->save_ast_trail (result.get ()); + + return of_expr (result.get ()); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_qe_model_project_skolem (Z3_context c, + Z3_model m, + unsigned num_bounds, + Z3_app const bound[], + Z3_ast body, + Z3_ast_map map) + { + Z3_TRY; + LOG_Z3_qe_model_project_skolem (c, m, num_bounds, bound, body, map); + RESET_ERROR_CODE(); + + ast_manager& man = mk_c(c)->m (); + app_ref_vector vars(man); + for (unsigned i = 0; i < num_bounds; ++i) + { + app *a = to_app (bound [i]); + if (a->get_kind () != AST_APP) + { + SET_ERROR_CODE (Z3_INVALID_ARG); + RETURN_Z3(0); + } + vars.push_back (a); + } + + expr_ref result (mk_c(c)->m ()); + result = to_expr (body); + model_ref model (to_model_ref (m)); + expr_map emap (man); + + spacer::qe_project (mk_c(c)->m (), vars, result, model, emap); + mk_c(c)->save_ast_trail (result.get ()); + + obj_map &map_z3 = to_ast_map_ref(map); + + for (expr_map::iterator it = emap.begin(), end = emap.end(); it != end; ++it){ + man.inc_ref(&(it->get_key())); + man.inc_ref(it->get_value()); + map_z3.insert(&(it->get_key()), it->get_value()); + } + + return of_expr (result.get ()); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_model_extrapolate (Z3_context c, + Z3_model m, + Z3_ast fml) + { + Z3_TRY; + LOG_Z3_model_extrapolate (c, m, fml); + RESET_ERROR_CODE(); + + model_ref model (to_model_ref (m)); + expr_ref_vector facts (mk_c(c)->m ()); + facts.push_back (to_expr (fml)); + flatten_and (facts); + + spacer::model_evaluator_util mev (mk_c(c)->m()); + mev.set_model (*model); + + expr_ref_vector lits (mk_c(c)->m()); + spacer::compute_implicant_literals (mev, facts, lits); + + expr_ref result (mk_c(c)->m ()); + result = mk_and (lits); + mk_c(c)->save_ast_trail (result.get ()); + + return of_expr (result.get ()); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_qe_lite (Z3_context c, Z3_ast_vector vars, Z3_ast body) + { + Z3_TRY; + LOG_Z3_qe_lite (c, vars, body); + RESET_ERROR_CODE(); + ast_ref_vector &vVars = to_ast_vector_ref (vars); + + app_ref_vector vApps (mk_c(c)->m()); + for (unsigned i = 0; i < vVars.size (); ++i) + { + app *a = to_app (vVars.get (i)); + if (a->get_kind () != AST_APP) + { + SET_ERROR_CODE (Z3_INVALID_ARG); + RETURN_Z3(0); + } + vApps.push_back (a); + } + + expr_ref result (mk_c(c)->m ()); + result = to_expr (body); + + params_ref p; + qe_lite qe (mk_c(c)->m (), p); + qe (vApps, result); + + // -- copy back variables that were not eliminated + if (vApps.size () < vVars.size ()) + { + vVars.reset (); + for (unsigned i = 0; i < vApps.size (); ++i) + vVars.push_back (vApps.get (i)); + } + + mk_c(c)->save_ast_trail (result.get ()); + return of_expr (result); + Z3_CATCH_RETURN(0); + } + +} diff --git a/src/api/z3.h b/src/api/z3.h index 22a1b9b5d..3dd3d11cb 100644 --- a/src/api/z3.h +++ b/src/api/z3.h @@ -33,5 +33,6 @@ Notes: #include "api/z3_interp.h" #include "api/z3_fpa.h" +#include"z3_spacer.h" #endif diff --git a/src/api/z3_spacer.h b/src/api/z3_spacer.h new file mode 100644 index 000000000..c01ee4a4d --- /dev/null +++ b/src/api/z3_spacer.h @@ -0,0 +1,143 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + z3_spacer.h + +Abstract: + + Spacer API + +Author: + + Arie Gurfinkel (arie) + +Notes: + +--*/ +#ifndef Z3_SPACER_H_ +#define Z3_SPACER_H_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + /** \defgroup capi C API */ + /*@{*/ + + /** @name Spacer facilities */ + /*@{*/ + /** + \brief Pose a query against the asserted rules at the given level. + + \code + query ::= (exists (bound-vars) query) + | literals + \endcode + + query returns + - Z3_L_FALSE if the query is unsatisfiable. + - Z3_L_TRUE if the query is satisfiable. Obtain the answer by calling #Z3_fixedpoint_get_answer. + - Z3_L_UNDEF if the query was interrupted, timed out or otherwise failed. + + def_API('Z3_fixedpoint_query_from_lvl', INT, (_in(CONTEXT), _in(FIXEDPOINT), _in(AST), _in(UINT))) + */ + Z3_lbool Z3_API Z3_fixedpoint_query_from_lvl (Z3_context c,Z3_fixedpoint d, Z3_ast query, unsigned lvl); + + /** + \brief Retrieve a bottom-up (from query) sequence of ground facts + + The previous call to Z3_fixedpoint_query must have returned Z3_L_TRUE. + + def_API('Z3_fixedpoint_get_ground_sat_answer', AST, (_in(CONTEXT), _in(FIXEDPOINT))) + */ + Z3_ast Z3_API Z3_fixedpoint_get_ground_sat_answer(Z3_context c,Z3_fixedpoint d); + + /** + \brief Obtain the list of rules along the counterexample trace. + + def_API('Z3_fixedpoint_get_rules_along_trace', AST_VECTOR, (_in(CONTEXT), _in(FIXEDPOINT))) + */ + Z3_ast_vector Z3_API Z3_fixedpoint_get_rules_along_trace(Z3_context c,Z3_fixedpoint d); + + /** + \brief Obtain the list of rules along the counterexample trace. + + def_API('Z3_fixedpoint_get_rule_names_along_trace', SYMBOL, (_in(CONTEXT), _in(FIXEDPOINT))) + */ + Z3_symbol Z3_API Z3_fixedpoint_get_rule_names_along_trace(Z3_context c,Z3_fixedpoint d); + + /** + \brief Add an invariant for the predicate \c pred. + Add an assumed invariant of predicate \c pred. + + Note: this functionality is Spacer specific. + + def_API('Z3_fixedpoint_add_invariant', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL), _in(AST))) + */ + void Z3_API Z3_fixedpoint_add_invariant(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred, Z3_ast property); + + + /** + Retrieve reachable states of a predicate. + Note: this functionality is Spacer specific. + + def_API('Z3_fixedpoint_get_reachable', AST, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL))) + */ + Z3_ast Z3_API Z3_fixedpoint_get_reachable(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred); + + /** + \brief Project variables given a model + + def_API('Z3_qe_model_project', AST, (_in(CONTEXT), _in(MODEL), _in(UINT), _in_array(2, APP), _in(AST))) + */ + Z3_ast Z3_API Z3_qe_model_project + (Z3_context c, + Z3_model m, + unsigned num_bounds, + Z3_app const bound[], + Z3_ast body); + + + /** + \brief Project variables given a model + + def_API('Z3_qe_model_project_skolem', AST, (_in(CONTEXT), _in(MODEL), _in(UINT), _in_array(2, APP), _in(AST), _in(AST_MAP))) + */ + Z3_ast Z3_API Z3_qe_model_project_skolem + (Z3_context c, + Z3_model m, + unsigned num_bounds, + Z3_app const bound[], + Z3_ast body, + Z3_ast_map map); + + /** + \brief Extrapolates a model of a formula + + def_API('Z3_model_extrapolate', AST, (_in(CONTEXT), _in(MODEL), _in(AST))) + */ + Z3_ast Z3_API Z3_model_extrapolate + (Z3_context c, + Z3_model m, + Z3_ast fml); + + /** + \brief Best-effort quantifier elimination + + def_API ('Z3_qe_lite', AST, (_in(CONTEXT), _in(AST_VECTOR), _in(AST))) + */ + Z3_ast Z3_qe_lite + (Z3_context c, + Z3_ast_vector vars, + Z3_ast body); + + /*@}*/ + /*@}*/ + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif From 86db446afa1514ed63682cf9b5dcfe7222a4cb4d Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:52:31 -0400 Subject: [PATCH 053/488] python spacer-specific API --- src/api/python/z3/z3.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index a16c1b92b..1452a037e 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -6536,6 +6536,22 @@ class Fixedpoint(Z3PPObject): r = Z3_fixedpoint_query(self.ctx.ref(), self.fixedpoint, query.as_ast()) return CheckSatResult(r) + def query_from_lvl (self, lvl, *query): + """Query the fixedpoint engine whether formula is derivable starting at the given query level. + """ + query = _get_args(query) + sz = len(query) + if sz >= 1 and isinstance(query[0], FuncDecl): + _z3_assert (False, "unsupported") + else: + if sz == 1: + query = query[0] + else: + query = And(query) + query = self.abstract(query, False) + r = Z3_fixedpoint_query_from_lvl (self.ctx.ref(), self.fixedpoint, query.as_ast(), lvl) + return CheckSatResult(r) + def push(self): """create a backtracking point for added rules, facts and assertions""" Z3_fixedpoint_push(self.ctx.ref(), self.fixedpoint) @@ -6558,6 +6574,23 @@ class Fixedpoint(Z3PPObject): r = Z3_fixedpoint_get_answer(self.ctx.ref(), self.fixedpoint) return _to_expr_ref(r, self.ctx) + def get_ground_sat_answer(self): + """Retrieve a ground cex from last query call.""" + r = Z3_fixedpoint_get_ground_sat_answer(self.ctx.ref(), self.fixedpoint) + return _to_expr_ref(r, self.ctx) + + def get_rules_along_trace(self): + """retrieve rules along the counterexample trace""" + return AstVector(Z3_fixedpoint_get_rules_along_trace(self.ctx.ref(), self.fixedpoint), self.ctx) + + def get_rule_names_along_trace(self): + """retrieve rule names along the counterexample trace""" + # this is a hack as I don't know how to return a list of symbols from C++; + # obtain names as a single string separated by semicolons + names = _symbol2py (self.ctx, Z3_fixedpoint_get_rule_names_along_trace(self.ctx.ref(), self.fixedpoint)) + # split into individual names + return names.split (';') + def get_num_levels(self, predicate): """Retrieve number of levels used for predicate in PDR engine""" return Z3_fixedpoint_get_num_levels(self.ctx.ref(), self.fixedpoint, predicate.ast) From 33c81524d2290eda1b55a1a3dfb7af2a28bb03a3 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:57:29 -0400 Subject: [PATCH 054/488] optionally disable propagate variable equivalences in interp_tail_simplifier --- src/muz/transforms/dl_mk_interp_tail_simplifier.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp index 64a2a2aca..1559f4f65 100644 --- a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp +++ b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp @@ -27,6 +27,7 @@ Revision History: #include "muz/transforms/dl_mk_interp_tail_simplifier.h" #include "ast/ast_util.h" +#include "fixedpoint_params.hpp" namespace datalog { // ----------------------------------- @@ -397,6 +398,8 @@ namespace datalog { } bool mk_interp_tail_simplifier::propagate_variable_equivalences(rule * r, rule_ref& res) { + if (!m_context.get_params ().xform_tail_simplifier_pve ()) + return false; unsigned u_len = r->get_uninterpreted_tail_size(); unsigned len = r->get_tail_size(); if (u_len == len) { From f5fa6b0bcb80b2ee16930ec1df6445b230d8c6e0 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 15:58:00 -0400 Subject: [PATCH 055/488] optionally disable subsumption checker --- src/muz/transforms/dl_mk_subsumption_checker.cpp | 3 +++ src/muz/transforms/dl_transforms.cpp | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/src/muz/transforms/dl_mk_subsumption_checker.cpp b/src/muz/transforms/dl_mk_subsumption_checker.cpp index 6a3ea8735..d3b959792 100644 --- a/src/muz/transforms/dl_mk_subsumption_checker.cpp +++ b/src/muz/transforms/dl_mk_subsumption_checker.cpp @@ -25,6 +25,7 @@ Revision History: #include "ast/rewriter/rewriter_def.h" #include "muz/transforms/dl_mk_subsumption_checker.h" +#include "fixedpoint_params.hpp" namespace datalog { @@ -328,6 +329,8 @@ namespace datalog { rule_set * mk_subsumption_checker::operator()(rule_set const & source) { // TODO mc + if (!m_context.get_params ().xform_subsumption_checker()) + return 0; m_have_new_total_rule = false; collect_ground_unconditional_rule_heads(source); diff --git a/src/muz/transforms/dl_transforms.cpp b/src/muz/transforms/dl_transforms.cpp index 48e956979..c727a29d4 100644 --- a/src/muz/transforms/dl_transforms.cpp +++ b/src/muz/transforms/dl_transforms.cpp @@ -51,17 +51,22 @@ namespace datalog { } transf.register_plugin(alloc(datalog::mk_quantifier_instantiation, ctx, 37000)); + if (ctx.get_params().datalog_subsumption()) { transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 35005)); + } transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 35000)); transf.register_plugin(alloc(datalog::mk_coi_filter, ctx, 34990)); transf.register_plugin(alloc(datalog::mk_interp_tail_simplifier, ctx, 34980)); //and another round of inlining + if (ctx.get_params().datalog_subsumption()) { transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 34975)); + } transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 34970)); transf.register_plugin(alloc(datalog::mk_coi_filter, ctx, 34960)); transf.register_plugin(alloc(datalog::mk_interp_tail_simplifier, ctx, 34950)); + if (ctx.get_params().datalog_subsumption()) { transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 34940)); transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 34930)); transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 34920)); @@ -69,6 +74,10 @@ namespace datalog { transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 34900)); transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 34890)); transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 34880)); + } + else { + transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 34930)); + } transf.register_plugin(alloc(datalog::mk_bit_blast, ctx, 35000)); transf.register_plugin(alloc(datalog::mk_karr_invariants, ctx, 36010)); From 2c7a39d580194d2f63cfea4b828be22c0c73ec7a Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 16:00:36 -0400 Subject: [PATCH 056/488] Optionally blast arrays This changes the default behavior of always blasting arrays. The old behavior can be restored using fixedpoint.xform.array_blast=true --- src/muz/transforms/dl_mk_array_blast.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/muz/transforms/dl_mk_array_blast.cpp b/src/muz/transforms/dl_mk_array_blast.cpp index 373edcd4b..8fe3f0e43 100644 --- a/src/muz/transforms/dl_mk_array_blast.cpp +++ b/src/muz/transforms/dl_mk_array_blast.cpp @@ -319,6 +319,9 @@ namespace datalog { rule_set * mk_array_blast::operator()(rule_set const & source) { + if (!m_ctx.array_blast ()) { + return 0; + } rule_set* rules = alloc(rule_set, m_ctx); rules->inherit_predicates(source); rule_set::iterator it = source.begin(), end = source.end(); From 7168451201b4989ba6a426ec3e2754c43752748a Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 16:05:06 -0400 Subject: [PATCH 057/488] eager quantifier instantiation for quantified array properties --- src/muz/transforms/CMakeLists.txt | 2 + src/muz/transforms/dl_mk_array_eq_rewrite.cpp | 140 ++++++++ src/muz/transforms/dl_mk_array_eq_rewrite.h | 54 +++ .../transforms/dl_mk_array_instantiation.cpp | 324 ++++++++++++++++++ .../transforms/dl_mk_array_instantiation.h | 123 +++++++ src/muz/transforms/dl_transforms.cpp | 10 +- 6 files changed, 651 insertions(+), 2 deletions(-) create mode 100644 src/muz/transforms/dl_mk_array_eq_rewrite.cpp create mode 100644 src/muz/transforms/dl_mk_array_eq_rewrite.h create mode 100644 src/muz/transforms/dl_mk_array_instantiation.cpp create mode 100644 src/muz/transforms/dl_mk_array_instantiation.h diff --git a/src/muz/transforms/CMakeLists.txt b/src/muz/transforms/CMakeLists.txt index 6a0a1ac9c..5e8829d42 100644 --- a/src/muz/transforms/CMakeLists.txt +++ b/src/muz/transforms/CMakeLists.txt @@ -21,6 +21,8 @@ z3_add_component(transforms dl_mk_unbound_compressor.cpp dl_mk_unfold.cpp dl_transforms.cpp + dl_mk_array_eq_rewrite.cpp + dl_mk_array_instantiation.cpp COMPONENT_DEPENDENCIES dataflow hilbert diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.cpp b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp new file mode 100644 index 000000000..c9caa6148 --- /dev/null +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp @@ -0,0 +1,140 @@ +/*++ + +Module Name: + + dl_mk_array_eq_rewrite.h + +Abstract: + Selects a representative for array equivalence classes. + +Author: + + Julien Braine + +Revision History: + +--*/ + + +#include "dl_mk_array_eq_rewrite.h" +#include "dl_context.h" +#include "pattern_inference.h" +#include "dl_context.h" +#include "expr_safe_replace.h" +#include "expr_abstract.h" +#include"fixedpoint_params.hpp" +#include "../spacer/obj_equiv_class.h" + +namespace datalog { + + mk_array_eq_rewrite::mk_array_eq_rewrite( + context & ctx, unsigned priority): + plugin(priority), + m(ctx.get_manager()), + m_ctx(ctx), + m_a(m) + { + } + + rule_set * mk_array_eq_rewrite::operator()(rule_set const & source) + { + src_set = &source; + rule_set * result = alloc(rule_set, m_ctx); + result->inherit_predicates(source); + dst=result; + unsigned nbrules = source.get_num_rules(); + src_manager = &source.get_rule_manager(); + for(unsigned i =0;iget_counter().get_max_rule_var(r)+1; + + + expr_ref_vector new_tail(m); + unsigned nb_predicates = r.get_uninterpreted_tail_size(); + unsigned tail_size = r.get_tail_size(); + for(unsigned i=0;imk_rule(m.mk_implies(m.mk_and(res_conjs.size(), res_conjs.c_ptr()), r.get_head()), pr, dest, r.name()); + } + + expr* mk_array_eq_rewrite::replace(expr* e, expr* new_val, expr* old_val) + { + if(e==old_val) + return new_val; + else if(!is_app(e)) + { + return e; + } + app*f = to_app(e); + ptr_vector n_args; + for(unsigned i=0;iget_num_args();i++) + { + n_args.push_back(replace(f->get_arg(i), new_val, old_val)); + } + return m.mk_app(f->get_decl(), n_args.size(), n_args.c_ptr()); + } + +} diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.h b/src/muz/transforms/dl_mk_array_eq_rewrite.h new file mode 100644 index 000000000..0229ff487 --- /dev/null +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.h @@ -0,0 +1,54 @@ +/*++ + +Module Name: + + dl_mk_array_eq_rewrite.h + +Abstract: + Selects a representative for array equivalence classes. + +Author: + + Julien Braine + +Revision History: + +--*/ + +#ifndef DL_MK_ARRAY_EQ_REWRITE_H_ +#define DL_MK_ARRAY_EQ_REWRITE_H_ + + +#include "dl_rule_transformer.h" +#include "../spacer/obj_equiv_class.h" + +namespace datalog { + + class context; + class mk_array_eq_rewrite : public rule_transformer::plugin { + //Context objects + ast_manager& m; + context& m_ctx; + array_util m_a; + + //Rule set context + const rule_set*src_set; + rule_set*dst; + rule_manager* src_manager; + unsigned cnt;//Index for new variables + + expr* replace(expr* e, expr* new_val, expr* old_val); + void instantiate_rule(const rule& r, rule_set & dest); + + public: + mk_array_eq_rewrite(context & ctx, unsigned priority); + rule_set * operator()(rule_set const & source); + virtual ~mk_array_eq_rewrite(){} + }; + + + +}; + +#endif /* DL_MK_ARRAY_EQ_REWRITE_H_ */ + diff --git a/src/muz/transforms/dl_mk_array_instantiation.cpp b/src/muz/transforms/dl_mk_array_instantiation.cpp new file mode 100644 index 000000000..762884545 --- /dev/null +++ b/src/muz/transforms/dl_mk_array_instantiation.cpp @@ -0,0 +1,324 @@ +/*++ + +Module Name: + + dl_mk_array_instantiation.h + +Abstract: + + Does array instantiation + +Author: + + Julien Braine + +Revision History: + +--*/ + + +#include "dl_mk_array_instantiation.h" +#include "dl_context.h" +#include "pattern_inference.h" +#include "dl_context.h" +#include "expr_safe_replace.h" +#include "expr_abstract.h" +#include"fixedpoint_params.hpp" +#include "../spacer/obj_equiv_class.h" + +namespace datalog { + + mk_array_instantiation::mk_array_instantiation( + context & ctx, unsigned priority): + plugin(priority), + m(ctx.get_manager()), + m_ctx(ctx), + m_a(m), + eq_classes(m), + ownership(m) + { + } + + rule_set * mk_array_instantiation::operator()(rule_set const & source) + { + std::cout<<"Array Instantiation called with parameters :" + <<" enforce="<display(std::cout); + return result; + } + + void mk_array_instantiation::instantiate_rule(const rule& r, rule_set & dest) + { + //Reset everything + selects.reset(); + eq_classes.reset(); + cnt = src_manager->get_counter().get_max_rule_var(r)+1; + done_selects.reset(); + ownership.reset(); + + expr_ref_vector phi(m); + expr_ref_vector preds(m); + expr_ref new_head = create_head(to_app(r.get_head())); + unsigned nb_predicates = r.get_uninterpreted_tail_size(); + unsigned tail_size = r.get_tail_size(); + for(unsigned i=0;i::iterator it = done_selects.begin(); it!=done_selects.end(); ++it) + { + expr_ref tmp(m); + tmp = &it->get_key(); + new_tail.push_back(m.mk_eq(it->get_value(), tmp)); + } + proof_ref pr(m); + src_manager->mk_rule(m.mk_implies(m.mk_and(new_tail.size(), new_tail.c_ptr()), new_head), pr, dest, r.name()); + } + + expr_ref mk_array_instantiation::create_head(app* old_head) + { + expr_ref_vector new_args(m); + for(unsigned i=0;iget_num_args();i++) + { + expr*arg = old_head->get_arg(i); + if(m_a.is_array(get_sort(arg))) + { + for(unsigned k=0; k< m_ctx.get_params().xform_instantiate_arrays_nb_quantifier();k++) + { + expr_ref_vector dummy_args(m); + dummy_args.push_back(arg); + for(unsigned i=0;i()); + selects[arg].push_back(select); + } + if(!m_ctx.get_params().xform_instantiate_arrays_enforce()) + new_args.push_back(arg); + } + else + new_args.push_back(arg); + } + return create_pred(old_head, new_args); + } + + + void mk_array_instantiation::retrieve_selects(expr* e) + { + //If the expression is not a function application, we ignore it + if (!is_app(e)) { + return; + } + app*f=to_app(e); + //Call the function recursively on all arguments + unsigned nbargs = f->get_num_args(); + for(unsigned i=0;iget_arg(i)); + } + //If it is a select, then add it to selects + if(m_a.is_select(f)) + { + SASSERT(!m_a.is_array(get_sort(e))); + selects.insert_if_not_there(f->get_arg(0), ptr_vector()); + selects[f->get_arg(0)].push_back(e); + } + //If it is a condition between arrays, for example the result of a store, then add it to the equiv_classes + if(m_a.is_store(f)) + { + eq_classes.merge(e, f->get_arg(0)); + } + else if(m.is_eq(f) && m_a.is_array(get_sort(f->get_arg(0)))) + { + eq_classes.merge(f->get_arg(0), f->get_arg(1)); + } + } + + + expr_ref_vector mk_array_instantiation::getId(app*old_pred, const expr_ref_vector& n_args) + { + expr_ref_vector res(m); + for(unsigned i=0;iget_num_args();j++) + { + res.push_back(select->get_arg(j)); + } + } + } + return res; + } + + expr_ref mk_array_instantiation::create_pred(app*old_pred, expr_ref_vector& n_args) + { + expr_ref_vector new_args(m); + new_args.append(n_args); + new_args.append(getId(old_pred, n_args)); + for(unsigned i=0;iget_decl()->get_name().str()+"!inst").c_str()), new_sorts.size(), new_sorts.c_ptr(), old_pred->get_decl()->get_range()); + m_ctx.register_predicate(fun_decl, false); + if(src_set->is_output_predicate(old_pred->get_decl())) + dst->set_output_predicate(fun_decl); + res=m.mk_app(fun_decl,new_args.size(), new_args.c_ptr()); + return res; + } + + var * mk_array_instantiation::mk_select_var(expr* select) + { + var*result; + if(!done_selects.find(select, result)) + { + ownership.push_back(select); + result = m.mk_var(cnt, get_sort(select)); + cnt++; + done_selects.insert(select, result); + } + return result; + } + + expr_ref mk_array_instantiation::rewrite_select(expr*array, expr*select) + { + app*s = to_app(select); + expr_ref res(m); + expr_ref_vector args(m); + args.push_back(array); + for(unsigned i=1; iget_num_args();i++) + { + args.push_back(s->get_arg(i)); + } + res = m_a.mk_select(args.size(), args.c_ptr()); + return res; + } + + expr_ref_vector mk_array_instantiation::retrieve_all_selects(expr*array) + { + expr_ref_vector all_selects(m); + for(spacer::expr_equiv_class::iterator it = eq_classes.begin(array); + it != eq_classes.end(array); ++it) + { + selects.insert_if_not_there(*it, ptr_vector()); + ptr_vector& select_ops = selects[*it]; + for(unsigned i=0;iget_num_args(); + //Stores, for each old position, the list of a new possible arguments + vector arg_correspondance; + for(unsigned i=0;iget_arg(i), m); + if(m_a.is_array(get_sort(arg))) + { + vector arg_possibilities(m_ctx.get_params().xform_instantiate_arrays_nb_quantifier(), retrieve_all_selects(arg)); + arg_correspondance.append(arg_possibilities); + if(!m_ctx.get_params().xform_instantiate_arrays_enforce()) + { + expr_ref_vector tmp(m); + tmp.push_back(arg); + arg_correspondance.push_back(tmp); + } + } + else + { + expr_ref_vector tmp(m); + tmp.push_back(arg); + arg_correspondance.push_back(tmp); + } + } + //Now, we need to deal with every combination + + expr_ref_vector res(m); + + svector chosen(arg_correspondance.size(), 0u); + while(1) + { + expr_ref_vector new_args(m); + for(unsigned i=0;i=arg_correspondance[pos].size()); + chosen[pos]++; + } + } +} diff --git a/src/muz/transforms/dl_mk_array_instantiation.h b/src/muz/transforms/dl_mk_array_instantiation.h new file mode 100644 index 000000000..0af57ee84 --- /dev/null +++ b/src/muz/transforms/dl_mk_array_instantiation.h @@ -0,0 +1,123 @@ +/*++ + +Module Name: + + dl_mk_array_instantiation.h + +Abstract: + Transforms predicates so that array invariants can be discovered. + + Motivation : Given a predicate P(a), no quantifier-free solution can express that P(a) <=> forall i, P(a[i]) = 0 + + Solution : Introduce a fresh variable i, and transform P(a) into P!inst(i, a). + Now, (P!inst(i,a) := a[i] = 0) <=> P(a) := forall i, a[i] = 0. + + Transformation on Horn rules: + P(a, args) /\ phi(a, args, args') => P'(args') (for simplicity, assume there are no arrays in args'). + Is transformed into: + (/\_r in read_indices(phi) P!inst(r, a, args)) /\ phi(a, args, args') => P'(args') + + Limitations : This technique can only discover invariants on arrays that depend on one quantifier. + Related work : Techniques relying on adding quantifiers and eliminating them. See dl_mk_quantifier_abstraction and dl_mk_quantifier_instantiation + +Implementation: + The implementation follows the solution suggested above, with more options. The addition of options implies that in the simple + case described above, we in fact have P(a) transformed into P(i, a[i], a). + + 1) Dealing with multiple quantifiers -> The options fixedpoint.xform.instantiate_arrays.nb_quantifier gives the number of quantifiers per array. + + 2) Inforcing the instantiation -> We suggest an option (enforce_instantiation) to enforce this abstraction. This transforms + P(a) into P(i, a[i]). This enforces the solver to limit the space search at the cost of imprecise results. This option + corresponds to fixedpoint.xform.instantiate_arrays.enforce + + 3) Adding slices in the mix -> We wish to have the possibility to further restrict the search space: we want to smash cells, given a smashing rule. + For example, in for loops j=0; j P'(...) is transformed into + (/\_r in read_indices(phi) P!inst(id_r, a[r], a) /\ GetId(r) = id_r) /\ phi(a, ...) => P'(...). + Note : when no slicing is done, GetId(i) = i. + This option corresponds to fixedpoint.xform.instantiate_arrays.slice_technique + + Although we described GetId as returning integers, there is no reason to restrict the type of ids to integers. A more direct method, + for the 0<=i > selects; + spacer::expr_equiv_class eq_classes; + unsigned cnt;//Index for new variables + obj_map done_selects; + expr_ref_vector ownership; + + //Helper functions + void instantiate_rule(const rule& r, rule_set & dest);//Instantiates the rule + void retrieve_selects(expr* e);//Retrieves all selects (fills the selects and eq_classes members) + expr_ref rewrite_select(expr*array, expr*select);//Rewrites select(a, args) to select(array, args) + expr_ref_vector retrieve_all_selects(expr*array);//Retrieves all selects linked to a given array (using eq classes and selects) + expr_ref_vector instantiate_pred(app*old_pred);//Returns all the instantiation of a given predicate + expr_ref create_pred(app*old_pred, expr_ref_vector& new_args);//Creates a predicate + expr_ref create_head(app* old_head);//Creates the new head + var * mk_select_var(expr* select); + + /*Given the old predicate, and the new arguments for the new predicate, returns the new setId arguments. + By default getId(P(x, y, a, b), (x, y, a[i], a[j], a, b[k], b[l], b)) (nb_quantifier=2, enforce=false) + returns (i,j,k,l) + So that the final created predicate is P!inst(x, y, a[i], a[j], a, b[k], b[l], b, i, j, k, l) + */ + expr_ref_vector getId(app*old_pred, const expr_ref_vector& new_args); + public: + mk_array_instantiation(context & ctx, unsigned priority); + rule_set * operator()(rule_set const & source); + virtual ~mk_array_instantiation(){} + }; + + + +}; + +#endif /* DL_MK_ARRAY_INSTANTIATION_H_ */ diff --git a/src/muz/transforms/dl_transforms.cpp b/src/muz/transforms/dl_transforms.cpp index c727a29d4..4569cb572 100644 --- a/src/muz/transforms/dl_transforms.cpp +++ b/src/muz/transforms/dl_transforms.cpp @@ -33,7 +33,8 @@ Revision History: #include "muz/transforms/dl_mk_quantifier_instantiation.h" #include "muz/transforms/dl_mk_subsumption_checker.h" #include "muz/transforms/dl_mk_scale.h" -#include"fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" +#include "muz/transforms/dl_mk_array_eq_rewrite.h" namespace datalog { @@ -46,6 +47,11 @@ namespace datalog { transf.register_plugin(alloc(datalog::mk_coi_filter, ctx)); transf.register_plugin(alloc(datalog::mk_interp_tail_simplifier, ctx)); + if (ctx.get_params().xform_instantiate_arrays()) { + transf.register_plugin(alloc(datalog::mk_array_instantiation, ctx, 34999)); + } + if(ctx.get_params().xform_transform_arrays()) + transf.register_plugin(alloc(datalog::mk_array_eq_rewrite, ctx, 34998)); if (ctx.get_params().xform_quantify_arrays()) { transf.register_plugin(alloc(datalog::mk_quantifier_abstraction, ctx, 38000)); } @@ -83,7 +89,7 @@ namespace datalog { transf.register_plugin(alloc(datalog::mk_karr_invariants, ctx, 36010)); transf.register_plugin(alloc(datalog::mk_scale, ctx, 36030)); if (!ctx.get_params().xform_quantify_arrays()) { - transf.register_plugin(alloc(datalog::mk_array_blast, ctx, 36000)); + transf.register_plugin(alloc(datalog::mk_array_blast, ctx, 35999)); } if (ctx.get_params().xform_magic()) { transf.register_plugin(alloc(datalog::mk_magic_symbolic, ctx, 36020)); From 97c5ab30d5e54c56172d63062615b2c990e33149 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 16:07:16 -0400 Subject: [PATCH 058/488] small improvements to bmc engine courtesy of Marc Brockschmidt --- src/muz/bmc/dl_bmc_engine.cpp | 20 ++++++++++++++++++-- src/muz/bmc/dl_bmc_engine.h | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index 186a021da..e78fb4331 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -32,6 +32,7 @@ Revision History: #include "muz/transforms/dl_transforms.h" #include "muz/transforms/dl_mk_rule_inliner.h" #include "ast/scoped_proof.h" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { @@ -143,6 +144,7 @@ namespace datalog { b.m_fparams.m_model = true; b.m_fparams.m_model_compact = true; b.m_fparams.m_mbqi = true; + b.m_rule_trace.reset(); } void mk_qrule_vars(datalog::rule const& r, unsigned rule_id, expr_ref_vector& sub) { @@ -279,6 +281,7 @@ namespace datalog { } SASSERT(r); mk_qrule_vars(*r, i, sub); + b.m_rule_trace.push_back(r); // we have rule, we have variable names of rule. // extract values for the variables in the rule. @@ -470,6 +473,7 @@ namespace datalog { b.m_fparams.m_model_compact = true; // b.m_fparams.m_mbqi = true; b.m_fparams.m_relevancy_lvl = 2; + b.m_rule_trace.reset(); } lbool check(unsigned level) { @@ -507,6 +511,7 @@ namespace datalog { } } SASSERT(r); + b.m_rule_trace.push_back(r); rm.to_formula(*r, fml); IF_VERBOSE(1, verbose_stream() << mk_pp(fml, m) << "\n";); prs.push_back(r->get_proof()); @@ -760,6 +765,7 @@ namespace datalog { b.m_fparams.m_model_compact = true; b.m_fparams.m_mbqi = false; b.m_fparams.m_relevancy_lvl = 2; + b.m_rule_trace.reset(); } func_decl_ref mk_predicate(func_decl* pred) { @@ -1078,6 +1084,7 @@ namespace datalog { } head = rl->get_head(); pr = m.mk_hyper_resolve(sz+1, prs.c_ptr(), head, positions, substs); + b.m_rule_trace.push_back(rl.get()); return pr; } } @@ -1154,7 +1161,8 @@ namespace datalog { lbool check() { setup(); - for (unsigned i = 0; ; ++i) { + unsigned max_depth = b.m_ctx.get_params().bmc_linear_unrolling_depth(); + for (unsigned i = 0; i < max_depth; ++i) { IF_VERBOSE(1, verbose_stream() << "level: " << i << "\n";); b.checkpoint(); compile(i); @@ -1167,6 +1175,7 @@ namespace datalog { return res; } } + return l_undef; } private: @@ -1202,6 +1211,7 @@ namespace datalog { } } SASSERT(r); + b.m_rule_trace.push_back(r); mk_rule_vars(*r, level, i, sub); // we have rule, we have variable names of rule. @@ -1284,6 +1294,7 @@ namespace datalog { b.m_fparams.m_model_compact = true; b.m_fparams.m_mbqi = false; // m_fparams.m_auto_config = false; + b.m_rule_trace.reset(); } @@ -1426,7 +1437,8 @@ namespace datalog { m_solver(m, m_fparams), m_rules(ctx), m_query_pred(m), - m_answer(m) { + m_answer(m), + m_rule_trace(ctx.get_rule_manager()) { } bmc::~bmc() {} @@ -1530,6 +1542,10 @@ namespace datalog { return m_answer; } + void bmc::get_rules_along_trace(datalog::rule_ref_vector& rules) { + rules.append(m_rule_trace); + } + void bmc::compile(rule_set const& rules, expr_ref_vector& fmls, unsigned level) { nonlinear nl(*this); nl.compile(rules, fmls, level); diff --git a/src/muz/bmc/dl_bmc_engine.h b/src/muz/bmc/dl_bmc_engine.h index 39bdd1fbe..fd5ce92e6 100644 --- a/src/muz/bmc/dl_bmc_engine.h +++ b/src/muz/bmc/dl_bmc_engine.h @@ -38,6 +38,7 @@ namespace datalog { rule_set m_rules; func_decl_ref m_query_pred; expr_ref m_answer; + rule_ref_vector m_rule_trace; void checkpoint(); @@ -63,6 +64,7 @@ namespace datalog { void collect_statistics(statistics& st) const; void reset_statistics(); + void get_rules_along_trace(datalog::rule_ref_vector& rules); expr_ref get_answer(); From 8fdf3177da2ad94837d1da3ef2a34d2306b094c8 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 14:06:29 -0700 Subject: [PATCH 059/488] add initialization to unused parameters Signed-off-by: Nikolaj Bjorner --- scripts/update_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 8cc80e50e..7c9f553cb 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -773,7 +773,7 @@ def mk_log_macro(file, name, params): if sz not in auxs: auxs.add(sz) file.write("unsigned * _Z3_UNUSED Z3ARG%s = 0; " % sz) - file.write("%s _Z3_UNUSED Z3ARG%s; " % (param2str(p), i)) + file.write("%s _Z3_UNUSED Z3ARG%s = 0; " % (param2str(p), i)) i = i + 1 file.write("if (_LOG_CTX.enabled()) { log_%s(" % name) i = 0 From 9601761a6febf5f59094610ddabf06f4e5cc589d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 31 Jul 2017 22:12:15 +0100 Subject: [PATCH 060/488] Added missing float conversion in fpa2bv converter. Relates to #1178. --- src/ast/fpa/fpa2bv_converter.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index c84b2a691..c45625513 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2714,13 +2714,21 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con SASSERT(m_util.is_bv2rm(args[0])); expr * bv_rm = to_app(args[0])->get_arg(0); - rational q; - if (!m_arith_util.is_numeral(args[1], q)) - UNREACHABLE(); + SASSERT((m_arith_util.is_int(args[1]) && m_arith_util.is_real(args[2])) || + (m_arith_util.is_real(args[1]) && m_arith_util.is_int(args[2]))); - rational e; - if (!m_arith_util.is_numeral(args[2], e)) - UNREACHABLE(); + rational q, e; + + if (m_arith_util.is_int(args[1]) && m_arith_util.is_real(args[2])) { + if (!m_arith_util.is_numeral(args[1], e) || + !m_arith_util.is_numeral(args[2], q)) + UNREACHABLE(); + } + else { + if (!m_arith_util.is_numeral(args[2], e) || + !m_arith_util.is_numeral(args[1], q)) + UNREACHABLE(); + } SASSERT(e.is_int64()); SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1)); From f465a2225aa3223a6c31403f94d33b27f3edb99f Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 17:14:43 -0400 Subject: [PATCH 061/488] fixing include paths --- src/muz/bmc/dl_bmc_engine.cpp | 3 ++- src/muz/transforms/dl_transforms.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index e78fb4331..fc5067355 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -32,7 +32,8 @@ Revision History: #include "muz/transforms/dl_transforms.h" #include "muz/transforms/dl_mk_rule_inliner.h" #include "ast/scoped_proof.h" -#include "muz/base/fixedpoint_params.hpp" + +#include "fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_transforms.cpp b/src/muz/transforms/dl_transforms.cpp index 4569cb572..b684139f6 100644 --- a/src/muz/transforms/dl_transforms.cpp +++ b/src/muz/transforms/dl_transforms.cpp @@ -33,8 +33,9 @@ Revision History: #include "muz/transforms/dl_mk_quantifier_instantiation.h" #include "muz/transforms/dl_mk_subsumption_checker.h" #include "muz/transforms/dl_mk_scale.h" -#include "muz/base/fixedpoint_params.hpp" #include "muz/transforms/dl_mk_array_eq_rewrite.h" +#include "muz/transforms/dl_mk_array_instantiation.h" +#include "fixedpoint_params.hpp" namespace datalog { From ffff16632d18e11d68224fc8d756930237774449 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 17:30:11 -0400 Subject: [PATCH 062/488] updating includes --- src/muz/spacer/obj_equiv_class.h | 4 +- src/muz/spacer/spacer_antiunify.cpp | 14 +++---- src/muz/spacer/spacer_antiunify.h | 2 +- src/muz/spacer/spacer_context.cpp | 53 ++++++++++++------------ src/muz/spacer/spacer_dl_interface.cpp | 34 +++++++-------- src/muz/spacer/spacer_dl_interface.h | 10 ++--- src/muz/spacer/spacer_farkas_learner.cpp | 31 +++++++------- src/muz/spacer/spacer_farkas_learner.h | 2 +- src/muz/spacer/spacer_generalizers.cpp | 12 +++--- src/muz/spacer/spacer_generalizers.h | 4 +- 10 files changed, 82 insertions(+), 84 deletions(-) diff --git a/src/muz/spacer/obj_equiv_class.h b/src/muz/spacer/obj_equiv_class.h index b3184655c..7f58efa7d 100644 --- a/src/muz/spacer/obj_equiv_class.h +++ b/src/muz/spacer/obj_equiv_class.h @@ -25,8 +25,8 @@ Revision History: #ifndef OBJ_EQUIV_CLASS_H_ #define OBJ_EQUIV_CLASS_H_ -#include "union_find.h" -#include "ast_util.h" +#include "util/union_find.h" +#include "ast/ast_util.h" namespace spacer { //All functions naturally add their parameters to the union_find class diff --git a/src/muz/spacer/spacer_antiunify.cpp b/src/muz/spacer/spacer_antiunify.cpp index 56fbbb8f0..6c382a723 100644 --- a/src/muz/spacer/spacer_antiunify.cpp +++ b/src/muz/spacer/spacer_antiunify.cpp @@ -18,13 +18,13 @@ Revision History: --*/ -#include"spacer_antiunify.h" -#include"ast.h" -#include"rewriter.h" -#include"rewriter_def.h" -#include"arith_decl_plugin.h" -#include"ast_util.h" -#include"expr_abstract.h" +#include"muz/spacer/spacer_antiunify.h" +#include"ast/ast.h" +#include"ast/rewriter/rewriter.h" +#include"ast/rewriter/rewriter_def.h" +#include"ast/arith_decl_plugin.h" +#include"ast/ast_util.h" +#include"ast/expr_abstract.h" namespace spacer { diff --git a/src/muz/spacer/spacer_antiunify.h b/src/muz/spacer/spacer_antiunify.h index 690bc4678..2b86f67ec 100644 --- a/src/muz/spacer/spacer_antiunify.h +++ b/src/muz/spacer/spacer_antiunify.h @@ -21,7 +21,7 @@ Revision History: #ifndef _SPACER_ANTIUNIFY_H_ #define _SPACER_ANTIUNIFY_H_ -#include "ast.h" +#include "ast/ast.h" namespace spacer { class anti_unifier diff --git a/src/muz/spacer/spacer_context.cpp b/src/muz/spacer/spacer_context.cpp index 40709de7f..a8ee01cff 100644 --- a/src/muz/spacer/spacer_context.cpp +++ b/src/muz/spacer/spacer_context.cpp @@ -24,34 +24,33 @@ Notes: #include #include -#include "dl_util.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "var_subst.h" -#include "util.h" -#include "spacer_prop_solver.h" -#include "spacer_context.h" -#include "spacer_generalizers.h" -#include "for_each_expr.h" -#include "dl_rule_set.h" -#include "unit_subsumption_tactic.h" -#include "model_smt2_pp.h" -#include "dl_mk_rule_inliner.h" -#include "ast_smt2_pp.h" -#include "ast_ll_pp.h" -#include "ast_util.h" -#include "proof_checker.h" -#include "smt_value_sort.h" -#include "proof_utils.h" -#include "scoped_proof.h" -#include "spacer_qe_project.h" -#include "blast_term_ite_tactic.h" +#include "muz/base/dl_util.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/var_subst.h" +#include "util/util.h" +#include "muz/spacer/spacer_prop_solver.h" +#include "muz/spacer/spacer_context.h" +#include "muz/spacer/spacer_generalizers.h" +#include "ast/for_each_expr.h" +#include "muz/base/dl_rule_set.h" +#include "smt/tactic/unit_subsumption_tactic.h" +#include "model/model_smt2_pp.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_util.h" +#include "ast/proof_checker/proof_checker.h" +#include "smt/smt_value_sort.h" +#include "ast/scoped_proof.h" +#include "muz/spacer/spacer_qe_project.h" +#include "tactic/core/blast_term_ite_tactic.h" -#include "timeit.h" -#include "luby.h" -#include "expr_safe_replace.h" -#include "expr_abstract.h" -#include "obj_equiv_class.h" +#include "util/timeit.h" +#include "util/luby.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/expr_abstract.h" +#include "muz/spacer/obj_equiv_class.h" namespace spacer { diff --git a/src/muz/spacer/spacer_dl_interface.cpp b/src/muz/spacer/spacer_dl_interface.cpp index 264809f72..78776e074 100644 --- a/src/muz/spacer/spacer_dl_interface.cpp +++ b/src/muz/spacer/spacer_dl_interface.cpp @@ -17,23 +17,23 @@ Revision History: --*/ -#include "dl_context.h" -#include "dl_mk_coi_filter.h" -#include "dl_mk_interp_tail_simplifier.h" -#include "dl_mk_subsumption_checker.h" -#include "dl_mk_rule_inliner.h" -#include "dl_rule.h" -#include "dl_rule_transformer.h" -#include "smt2parser.h" -#include "spacer_context.h" -#include "spacer_dl_interface.h" -#include "dl_rule_set.h" -#include "dl_mk_slice.h" -#include "dl_mk_unfold.h" -#include "dl_mk_coalesce.h" -#include "model_smt2_pp.h" -#include "scoped_proof.h" -#include "dl_transforms.h" +#include "muz/base/dl_context.h" +#include "muz/transforms/dl_mk_coi_filter.h" +#include "muz/transforms/dl_mk_interp_tail_simplifier.h" +#include "muz/transforms/dl_mk_subsumption_checker.h" +#include "muz/transforms/dl_mk_rule_inliner.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_transformer.h" +#include "parsers/smt2/smt2parser.h" +#include "muz/spacer/spacer_context.h" +#include "muz/spacer/spacer_dl_interface.h" +#include "muz/base/dl_rule_set.h" +#include "muz/transforms/dl_mk_slice.h" +#include "muz/transforms/dl_mk_unfold.h" +#include "muz/transforms/dl_mk_coalesce.h" +#include "model/model_smt2_pp.h" +#include "ast/scoped_proof.h" +#include "muz/transforms/dl_transforms.h" using namespace spacer; diff --git a/src/muz/spacer/spacer_dl_interface.h b/src/muz/spacer/spacer_dl_interface.h index 809f6fc83..1581762d5 100644 --- a/src/muz/spacer/spacer_dl_interface.h +++ b/src/muz/spacer/spacer_dl_interface.h @@ -19,11 +19,11 @@ Revision History: #ifndef _SPACER_DL_INTERFACE_H_ #define _SPACER_DL_INTERFACE_H_ -#include "lbool.h" -#include "dl_rule.h" -#include "dl_rule_set.h" -#include "dl_engine_base.h" -#include "statistics.h" +#include "util/lbool.h" +#include "muz/base/dl_rule.h" +#include "muz/base/dl_rule_set.h" +#include "muz/base/dl_engine_base.h" +#include "util/statistics.h" namespace datalog { class context; diff --git a/src/muz/spacer/spacer_farkas_learner.cpp b/src/muz/spacer/spacer_farkas_learner.cpp index edee8ba6f..29d238cc9 100644 --- a/src/muz/spacer/spacer_farkas_learner.cpp +++ b/src/muz/spacer/spacer_farkas_learner.cpp @@ -19,21 +19,21 @@ Revision History: --*/ //TODO: reorder, delete unnecessary includes -#include "ast_smt2_pp.h" -#include "array_decl_plugin.h" -#include "bool_rewriter.h" -#include "dl_decl_plugin.h" -#include "for_each_expr.h" -#include "dl_util.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "spacer_util.h" -#include "spacer_farkas_learner.h" -#include "th_rewriter.h" -#include "ast_ll_pp.h" -#include "proof_utils.h" -#include "reg_decl_plugins.h" -#include "smt_farkas_util.h" +#include "ast/ast_smt2_pp.h" +#include "ast/array_decl_plugin.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/dl_decl_plugin.h" +#include "ast/for_each_expr.h" +#include "muz/base/dl_util.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "muz/spacer/spacer_util.h" +#include "muz/spacer/spacer_farkas_learner.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/ast_ll_pp.h" +#include "muz/base/proof_utils.h" +#include "ast/reg_decl_plugins.h" +#include "smt/smt_farkas_util.h" namespace spacer { @@ -437,4 +437,3 @@ bool farkas_learner::is_farkas_lemma(ast_manager& m, expr* e) d->get_num_parameters() >= m.get_num_parents(to_app(e)) + 2; } } - diff --git a/src/muz/spacer/spacer_farkas_learner.h b/src/muz/spacer/spacer_farkas_learner.h index 7a0abf6f5..724b18b73 100644 --- a/src/muz/spacer/spacer_farkas_learner.h +++ b/src/muz/spacer/spacer_farkas_learner.h @@ -20,7 +20,7 @@ Revision History: #ifndef _SPACER_FARKAS_LEARNER_H_ #define _SPACER_FARKAS_LEARNER_H_ -#include "ast.h" +#include "ast/ast.h" namespace spacer { diff --git a/src/muz/spacer/spacer_generalizers.cpp b/src/muz/spacer/spacer_generalizers.cpp index f36983077..9f8757024 100644 --- a/src/muz/spacer/spacer_generalizers.cpp +++ b/src/muz/spacer/spacer_generalizers.cpp @@ -19,12 +19,12 @@ Revision History: --*/ -#include "spacer_context.h" -#include "spacer_generalizers.h" -#include "expr_abstract.h" -#include "var_subst.h" -#include "for_each_expr.h" -#include "obj_equiv_class.h" +#include "muz/spacer/spacer_context.h" +#include "muz/spacer/spacer_generalizers.h" +#include "ast/expr_abstract.h" +#include "ast/rewriter/var_subst.h" +#include "ast/for_each_expr.h" +#include "muz/spacer/obj_equiv_class.h" namespace spacer { diff --git a/src/muz/spacer/spacer_generalizers.h b/src/muz/spacer/spacer_generalizers.h index 8634f0828..aa542ec04 100644 --- a/src/muz/spacer/spacer_generalizers.h +++ b/src/muz/spacer/spacer_generalizers.h @@ -20,8 +20,8 @@ Revision History: #ifndef _SPACER_GENERALIZERS_H_ #define _SPACER_GENERALIZERS_H_ -#include "spacer_context.h" -#include "arith_decl_plugin.h" +#include "muz/spacer/spacer_context.h" +#include "ast/arith_decl_plugin.h" namespace spacer { From e8cdc34219befa3d583d82ec534ce16e733a865f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 31 Jul 2017 22:34:26 +0100 Subject: [PATCH 063/488] Debug fix in fpa2bv converter. Relates to #872. --- src/ast/fpa/fpa2bv_converter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 1217d365c..1a4698fa4 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1667,7 +1667,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_is_sig_neg", is_sig_neg); // Result could have overflown into 4.xxx. - SASSERT(m_bv_util.get_bv_size(sig_abs) == 2*sbits+4); + SASSERT(m_bv_util.get_bv_size(sig_abs) == 2*sbits+5); expr_ref extra(m), extra_is_zero(m); extra = m_bv_util.mk_extract(2*sbits+4, 2*sbits+3, sig_abs); extra_is_zero = m.mk_eq(extra, m_bv_util.mk_numeral(0, 2)); From 5cda9504f1e4a9aae49a3e657a31b82e492510fb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 16:32:26 -0700 Subject: [PATCH 064/488] remove relative include from API Signed-off-by: Nikolaj Bjorner --- src/api/z3.h | 20 ++++++++++---------- src/smt/smt_setup.cpp | 7 ++++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/api/z3.h b/src/api/z3.h index 22a1b9b5d..c9f0fe6e2 100644 --- a/src/api/z3.h +++ b/src/api/z3.h @@ -22,16 +22,16 @@ Notes: #define Z3_H_ #include -#include "api/z3_macros.h" -#include "api/z3_api.h" -#include "api/z3_ast_containers.h" -#include "api/z3_algebraic.h" -#include "api/z3_polynomial.h" -#include "api/z3_rcf.h" -#include "api/z3_fixedpoint.h" -#include "api/z3_optimization.h" -#include "api/z3_interp.h" -#include "api/z3_fpa.h" +#include "z3_macros.h" +#include "z3_api.h" +#include "z3_ast_containers.h" +#include "z3_algebraic.h" +#include "z3_polynomial.h" +#include "z3_rcf.h" +#include "z3_fixedpoint.h" +#include "z3_optimization.h" +#include "z3_interp.h" +#include "z3_fpa.h" #endif diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 361448316..1be1bca17 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -720,7 +720,12 @@ namespace smt { } void setup::setup_i_arith() { - m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); + if (m_params.m_arith_mode == AS_OPTINF) { + m_context.register_plugin(alloc(smt::theory_lra, m_manager, m_params)); + } + else { + m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); + } } void setup::setup_r_arith() { From 49cf8992079d4ca6dd82bef10951723d5509095e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 16:33:48 -0700 Subject: [PATCH 065/488] remove local change Signed-off-by: Nikolaj Bjorner --- src/smt/smt_setup.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 1be1bca17..392802d5d 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -720,12 +720,7 @@ namespace smt { } void setup::setup_i_arith() { - if (m_params.m_arith_mode == AS_OPTINF) { - m_context.register_plugin(alloc(smt::theory_lra, m_manager, m_params)); - } - else { - m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); - } + m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); } void setup::setup_r_arith() { From c506f3ddc987f9f98440cad58f542180009de5e4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 18:39:35 -0700 Subject: [PATCH 066/488] fix build errors Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/spacer_context.cpp | 8 +++++++- src/muz/spacer/spacer_context.h | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/muz/spacer/spacer_context.cpp b/src/muz/spacer/spacer_context.cpp index a8ee01cff..8d0a4f627 100644 --- a/src/muz/spacer/spacer_context.cpp +++ b/src/muz/spacer/spacer_context.cpp @@ -1122,7 +1122,13 @@ lemma::lemma(pob_ref const &p) : m_bindings(m), m_lvl(p->level()), m_pob(p), m_new_pob(m_pob) {SASSERT(m_pob);} -lemma::lemma(pob_ref const &p, expr_ref_vector &cube, unsigned lvl) : lemma(p) { +lemma::lemma(pob_ref const &p, expr_ref_vector &cube, unsigned lvl) : + m_ref_count(0), + m(p->get_ast_manager()), + m_body(m), m_cube(m), + m_bindings(m), m_lvl(p->level()), + m_pob(p), m_new_pob(m_pob) +{ update_cube(p, cube); set_level(lvl); } diff --git a/src/muz/spacer/spacer_context.h b/src/muz/spacer/spacer_context.h index f27ece97c..78541130c 100644 --- a/src/muz/spacer/spacer_context.h +++ b/src/muz/spacer/spacer_context.h @@ -119,7 +119,7 @@ public: lemma(ast_manager &manager, expr * fml, unsigned lvl); lemma(pob_ref const &p); lemma(pob_ref const &p, expr_ref_vector &cube, unsigned lvl); - lemma(const lemma &other) = delete; +// lemma(const lemma &other) = delete; ast_manager &get_ast_manager() {return m;} expr *get_expr(); @@ -648,7 +648,7 @@ public: unsigned max_level () {return m_max_level;} unsigned min_depth () {return m_min_depth;} - unsigned size () {return m_obligations.size ();} + size_t size () {return m_obligations.size ();} }; From 66108085fad2f05aa64dc21e73ae26eb098589d8 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 22:28:41 -0400 Subject: [PATCH 067/488] removing pragmas to make travis happy --- src/muz/spacer/spacer_prop_solver.cpp | 1 - src/muz/spacer/spacer_unsat_core_learner.cpp | 4 ---- src/muz/spacer/spacer_unsat_core_plugin.cpp | 9 ++------- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/muz/spacer/spacer_prop_solver.cpp b/src/muz/spacer/spacer_prop_solver.cpp index 4f5ad86f2..29b34b799 100644 --- a/src/muz/spacer/spacer_prop_solver.cpp +++ b/src/muz/spacer/spacer_prop_solver.cpp @@ -260,7 +260,6 @@ lbool prop_solver::check_assumptions(const expr_ref_vector & _hard, else { m_ctx->assert_expr(bg[i]); } unsigned soft_sz = soft.size(); -#pragma unused(soft_sz) lbool res = internal_check_assumptions(hard, soft); if (!m_use_push_bg) { m_ctx->pop(1); } diff --git a/src/muz/spacer/spacer_unsat_core_learner.cpp b/src/muz/spacer/spacer_unsat_core_learner.cpp index 1e4dc522f..557858ca4 100644 --- a/src/muz/spacer/spacer_unsat_core_learner.cpp +++ b/src/muz/spacer/spacer_unsat_core_learner.cpp @@ -25,9 +25,7 @@ Revision History: namespace spacer { -#pragma mark - proof iterators -# pragma mark - main methods unsat_core_learner::~unsat_core_learner() { std::for_each(m_plugins.begin(), m_plugins.end(), delete_proc()); @@ -262,7 +260,6 @@ void unsat_core_learner::finalize() } } -#pragma mark - API bool unsat_core_learner::is_a_marked(proof* p) { @@ -290,7 +287,6 @@ void unsat_core_learner::set_closed(proof* p, bool value) m_unsat_core.push_back(lemma); } -# pragma mark - checking for b_symbols class collect_pure_proc { func_decl_set& m_symbs; diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index d0d443528..58c700dae 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -32,7 +32,6 @@ Revision History: namespace spacer { -#pragma mark - unsat_core_plugin_lemma void unsat_core_plugin_lemma::compute_partial_core(proof* step) { @@ -105,7 +104,6 @@ void unsat_core_plugin_lemma::add_lowest_split_to_core(proof* step) const } -#pragma mark - unsat_core_plugin_farkas_lemma void unsat_core_plugin_farkas_lemma::compute_partial_core(proof* step) { ast_manager &m = m_learner.m; @@ -285,7 +283,6 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector literals; vector coefficients; - for (int j=0; j < matrix.num_cols(); ++j) + for (unsigned j=0; j < matrix.num_cols(); ++j) { expr_ref evaluation(m); @@ -601,7 +597,6 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector Date: Mon, 31 Jul 2017 17:57:21 -0400 Subject: [PATCH 068/488] more includes --- src/muz/spacer/spacer_itp_solver.cpp | 14 +++---- src/muz/spacer/spacer_itp_solver.h | 6 +-- src/muz/spacer/spacer_legacy_frames.cpp | 54 ++++++++++++------------ src/muz/spacer/spacer_legacy_mbp.cpp | 55 +++++++++++++------------ src/muz/spacer/spacer_legacy_mev.cpp | 52 +++++++++++------------ src/muz/spacer/spacer_legacy_mev.h | 20 ++++----- src/muz/spacer/spacer_manager.cpp | 19 +++++---- src/muz/spacer/spacer_manager.h | 23 ++++++----- src/muz/spacer/spacer_marshal.cpp | 13 +++--- src/muz/spacer/spacer_marshal.h | 3 +- src/muz/spacer/spacer_matrix.cpp | 2 +- src/muz/spacer/spacer_matrix.h | 3 +- src/muz/spacer/spacer_mev_array.cpp | 26 ++++++------ src/muz/spacer/spacer_mev_array.h | 8 ++-- 14 files changed, 152 insertions(+), 146 deletions(-) diff --git a/src/muz/spacer/spacer_itp_solver.cpp b/src/muz/spacer/spacer_itp_solver.cpp index 7571352b3..bcf6b07ae 100644 --- a/src/muz/spacer/spacer_itp_solver.cpp +++ b/src/muz/spacer/spacer_itp_solver.cpp @@ -16,13 +16,13 @@ Author: Notes: --*/ -#include"spacer_itp_solver.h" -#include"ast.h" -#include"spacer_util.h" -#include"spacer_farkas_learner.h" -#include"expr_replacer.h" -#include "spacer_unsat_core_learner.h" -#include "spacer_unsat_core_plugin.h" +#include"muz/spacer/spacer_itp_solver.h" +#include"ast/ast.h" +#include"muz/spacer/spacer_util.h" +#include"muz/spacer/spacer_farkas_learner.h" +#include"ast/rewriter/expr_replacer.h" +#include"muz/spacer/spacer_unsat_core_learner.h" +#include"muz/spacer/spacer_unsat_core_plugin.h" namespace spacer { void itp_solver::push () diff --git a/src/muz/spacer/spacer_itp_solver.h b/src/muz/spacer/spacer_itp_solver.h index bf5a00751..fce2c4a9c 100644 --- a/src/muz/spacer/spacer_itp_solver.h +++ b/src/muz/spacer/spacer_itp_solver.h @@ -19,9 +19,9 @@ Notes: #ifndef SPACER_ITP_SOLVER_H_ #define SPACER_ITP_SOLVER_H_ -#include "solver.h" -#include "expr_substitution.h" -#include"stopwatch.h" +#include"solver/solver.h" +#include"ast/expr_substitution.h" +#include"util/stopwatch.h" namespace spacer { class itp_solver : public solver { private: diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp index c998121c6..77e6f5650 100644 --- a/src/muz/spacer/spacer_legacy_frames.cpp +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -3,38 +3,38 @@ Legacy implementations of frames. To be removed. */ -#include "spacer_context.h" #include #include -#include "dl_util.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "var_subst.h" -#include "util.h" -#include "spacer_prop_solver.h" -#include "spacer_context.h" -#include "spacer_generalizers.h" -#include "for_each_expr.h" -#include "dl_rule_set.h" -#include "unit_subsumption_tactic.h" -#include "model_smt2_pp.h" +#include "muz/spacer/spacer_context.h" +#include "muz/base/dl_util.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/var_subst.h" +#include "util/util.h" +#include "muz/spacer/spacer_prop_solver.h" +#include "muz/spacer/spacer_context.h" +#include "muz/spacer/spacer_generalizers.h" +#include "ast/for_each_expr.h" +#include "muz/base/dl_rule_set.h" +#include "smt/tactic/unit_subsumption_tactic.h" +#include "model/model_smt2_pp.h" #include "dl_mk_rule_inliner.h" -#include "ast_smt2_pp.h" -#include "ast_ll_pp.h" -#include "ast_util.h" -#include "proof_checker.h" -#include "smt_value_sort.h" -#include "proof_utils.h" -#include "scoped_proof.h" -#include "spacer_qe_project.h" -#include "blast_term_ite_tactic.h" +#include "ast/ast_smt2_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_util.h" +#include "ast/proof_checker/proof_checker.h" +#include "smt/smt_value_sort.h" +#include "muz/base/proof_utils.h" +#include "ast/scoped_proof.h" +#include "muz/spacer/spacer_qe_project.h" +#include "tactic/core/blast_term_ite_tactic.h" -#include "timeit.h" -#include "luby.h" -#include "expr_safe_replace.h" -#include "expr_abstract.h" -#include "obj_equiv_class.h" +#include "util/timeit.h" +#include "util/luby.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/expr_abstract.h" +#include "muz/spacer/obj_equiv_class.h" namespace spacer { diff --git a/src/muz/spacer/spacer_legacy_mbp.cpp b/src/muz/spacer/spacer_legacy_mbp.cpp index a9569004c..fc2fd1fdd 100644 --- a/src/muz/spacer/spacer_legacy_mbp.cpp +++ b/src/muz/spacer/spacer_legacy_mbp.cpp @@ -17,35 +17,36 @@ Notes: --*/ #include -#include "arith_simplifier_plugin.h" -#include "array_decl_plugin.h" -#include "ast_pp.h" -#include "basic_simplifier_plugin.h" -#include "bv_simplifier_plugin.h" -#include "bool_rewriter.h" -#include "dl_util.h" -#include "for_each_expr.h" -#include "smt_params.h" -#include "model.h" -#include "ref_vector.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "util.h" -#include "spacer_manager.h" -#include "spacer_util.h" -#include "arith_decl_plugin.h" -#include "expr_replacer.h" -#include "model_smt2_pp.h" -#include "scoped_proof.h" -#include "qe_lite.h" -#include "spacer_qe_project.h" -#include "model_pp.h" -#include "expr_safe_replace.h" -#include "datatype_decl_plugin.h" -#include "bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/rewriter/bool_rewriter.h" +#include "muz/base/dl_util.h" +#include "ast/for_each_expr.h" +#include "smt/params/smt_params.h" +#include "model/model.h" +#include "util/ref_vector.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/util.h" +#include "muz/spacer/spacer_manager.h" +#include "muz/spacer/spacer_util.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/expr_replacer.h" +#include "model/model_smt2_pp.h" +#include "ast/scoped_proof.h" +#include "qe/qe_lite.h" +#include "muz/spacer/spacer_qe_project.h" +#include "model/model_pp.h" +#include "ast/rewriter/expr_safe_replace.h" -#include "spacer_legacy_mev.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" + +#include "muz/spacer/spacer_legacy_mev.h" namespace spacer { void qe_project(ast_manager& m, app_ref_vector& vars, expr_ref& fml, model_ref& M, expr_map& map) diff --git a/src/muz/spacer/spacer_legacy_mev.cpp b/src/muz/spacer/spacer_legacy_mev.cpp index 0ab33c693..8b53410b1 100644 --- a/src/muz/spacer/spacer_legacy_mev.cpp +++ b/src/muz/spacer/spacer_legacy_mev.cpp @@ -5,34 +5,34 @@ Copyright (c) 2017 Arie Gurfinkel */ #include -#include "arith_simplifier_plugin.h" -#include "array_decl_plugin.h" -#include "ast_pp.h" -#include "basic_simplifier_plugin.h" -#include "bv_simplifier_plugin.h" -#include "bool_rewriter.h" -#include "dl_util.h" -#include "for_each_expr.h" -#include "smt_params.h" -#include "model.h" -#include "ref_vector.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "util.h" -#include "spacer_manager.h" -#include "spacer_legacy_mev.h" -#include "spacer_util.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/rewriter/bool_rewriter.h" +#include "muz/base/dl_util.h" +#include "ast/for_each_expr.h" +#include "smt/params/smt_params.h" +#include "model/model.h" +#include "util/ref_vector.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/util.h" +#include "muz/spacer/spacer_manager.h" +#include "muz/spacer/spacer_legacy_mev.h" +#include "muz/spacer/spacer_util.h" #include "arith_decl_plugin.h" -#include "expr_replacer.h" -#include "model_smt2_pp.h" -#include "scoped_proof.h" -#include "qe_lite.h" -#include "spacer_qe_project.h" -#include "model_pp.h" -#include "expr_safe_replace.h" +#include "ast/rewriter/expr_replacer.h" +#include "model/model_smt2_pp.h" +#include "ast/scoped_proof.h" +#include "qe/qe_lite.h" +#include "muz/spacer/spacer_qe_project.h" +#include "model/model_pp.h" +#include "ast/rewriter/expr_safe_replace.h" -#include "datatype_decl_plugin.h" -#include "bv_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" namespace old { diff --git a/src/muz/spacer/spacer_legacy_mev.h b/src/muz/spacer/spacer_legacy_mev.h index 21790f022..bebf1d0db 100644 --- a/src/muz/spacer/spacer_legacy_mev.h +++ b/src/muz/spacer/spacer_legacy_mev.h @@ -6,16 +6,16 @@ Copyright (c) 2017 Arie Gurfinkel #ifndef OLD_MEV_H #define OLD_MEV_H -#include "ast.h" -#include "ast_pp.h" -#include "obj_hashtable.h" -#include "ref_vector.h" -#include "simplifier.h" -#include "trace.h" -#include "vector.h" -#include "arith_decl_plugin.h" -#include "array_decl_plugin.h" -#include "bv_decl_plugin.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "util/obj_hashtable.h" +#include "util/ref_vector.h" +#include "ast/simplifier/simplifier.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/bv_decl_plugin.h" namespace old { class model_evaluator { diff --git a/src/muz/spacer/spacer_manager.cpp b/src/muz/spacer/spacer_manager.cpp index 077874488..4ad3e0d7f 100644 --- a/src/muz/spacer/spacer_manager.cpp +++ b/src/muz/spacer/spacer_manager.cpp @@ -19,15 +19,16 @@ Revision History: --*/ #include -#include "spacer_manager.h" -#include "ast_smt2_pp.h" -#include "for_each_expr.h" -#include "has_free_vars.h" -#include "expr_replacer.h" -#include "expr_abstract.h" -#include "model2expr.h" -#include "model_smt2_pp.h" -#include "model_converter.h" + +#include "muz/spacer/spacer_manager.h" +#include "ast/ast_smt2_pp.h" +#include "ast/for_each_expr.h" +#include "ast/has_free_vars.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/expr_abstract.h" +#include "model/model2expr.h" +#include "model/model_smt2_pp.h" +#include "tactic/model_converter.h" namespace spacer { diff --git a/src/muz/spacer/spacer_manager.h b/src/muz/spacer/spacer_manager.h index 360c4ceb2..f2382c15d 100644 --- a/src/muz/spacer/spacer_manager.h +++ b/src/muz/spacer/spacer_manager.h @@ -23,19 +23,20 @@ Revision History: #include #include -#include "bool_rewriter.h" -#include "expr_replacer.h" -#include "expr_substitution.h" -#include "map.h" -#include "ref_vector.h" -#include "smt_kernel.h" -#include "spacer_util.h" -#include "spacer_sym_mux.h" -#include "spacer_farkas_learner.h" -#include "spacer_smt_context_manager.h" -#include "dl_rule.h" #include +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/expr_replacer.h" +#include "ast/expr_substitution.h" +#include "util/map.h" +#include "util/ref_vector.h" +#include "smt/smt_kernel.h" +#include "muz/spacer/spacer_util.h" +#include "muz/spacer/spacer_sym_mux.h" +#include "muz/spacer/spacer_farkas_learner.h" +#include "muz/spacer/spacer_smt_context_manager.h" +#include "muz/base/dl_rule.h" + namespace smt { class context; } diff --git a/src/muz/spacer/spacer_marshal.cpp b/src/muz/spacer/spacer_marshal.cpp index fce0d6a34..68c90bd33 100644 --- a/src/muz/spacer/spacer_marshal.cpp +++ b/src/muz/spacer/spacer_marshal.cpp @@ -9,14 +9,15 @@ Abstract: marshaling and unmarshaling of expressions --*/ -#include "spacer_marshal.h" +#include "muz/spacer/spacer_marshal.h" #include -#include "cmd_context.h" -#include "smt2parser.h" -#include "vector.h" -#include "ast_smt_pp.h" -#include "ast_pp.h" + +#include "cmd_context/cmd_context.h" +#include "parsers/smt2/smt2parser.h" +#include "util/vector.h" +#include "ast/ast_smt_pp.h" +#include "ast/ast_pp.h" namespace spacer { std::ostream &marshal(std::ostream &os, expr_ref e, ast_manager &m) diff --git a/src/muz/spacer/spacer_marshal.h b/src/muz/spacer/spacer_marshal.h index e4c59628f..95cb8f26a 100644 --- a/src/muz/spacer/spacer_marshal.h +++ b/src/muz/spacer/spacer_marshal.h @@ -13,9 +13,10 @@ Abstract: #define _SPACER_MARSHAL_H_ #include -#include "ast.h" #include +#include "ast/ast.h" + namespace spacer { std::ostream &marshal(std::ostream &os, expr_ref e, ast_manager &m); std::string marshal(expr_ref e, ast_manager &m); diff --git a/src/muz/spacer/spacer_matrix.cpp b/src/muz/spacer/spacer_matrix.cpp index b7d03d453..3cc83996c 100644 --- a/src/muz/spacer/spacer_matrix.cpp +++ b/src/muz/spacer/spacer_matrix.cpp @@ -15,7 +15,7 @@ Revision History: --*/ -#include "spacer_matrix.h" +#include "muz/spacer/spacer_matrix.h" namespace spacer { diff --git a/src/muz/spacer/spacer_matrix.h b/src/muz/spacer/spacer_matrix.h index def194793..4fc418f2b 100644 --- a/src/muz/spacer/spacer_matrix.h +++ b/src/muz/spacer/spacer_matrix.h @@ -18,7 +18,8 @@ Revision History: #ifndef _SPACER_MATRIX_H_ #define _SPACER_MATRIX_H_ -#include "ast.h" +#include "util/rational.h" +#include "util/vector.h" namespace spacer { diff --git a/src/muz/spacer/spacer_mev_array.cpp b/src/muz/spacer/spacer_mev_array.cpp index 7a69eeab5..9e04b457e 100644 --- a/src/muz/spacer/spacer_mev_array.cpp +++ b/src/muz/spacer/spacer_mev_array.cpp @@ -14,20 +14,20 @@ Author: Revision History: --*/ -#include"model.h" +#include"model/model.h" #include"model_evaluator_params.hpp" -#include"rewriter_types.h" -#include"model_evaluator.h" -#include"spacer_mev_array.h" -#include"bool_rewriter.h" -#include"arith_rewriter.h" -#include"bv_rewriter.h" -#include"datatype_rewriter.h" -#include"array_rewriter.h" -#include"rewriter_def.h" -#include"cooperate.h" -#include"ast_pp.h" -#include"func_interp.h" +#include"ast/rewriter/rewriter_types.h" +#include"model/model_evaluator.h" +#include"muz/spacer/spacer_mev_array.h" +#include"ast/rewriter/bool_rewriter.h" +#include"ast/rewriter/arith_rewriter.h" +#include"ast/rewriter/bv_rewriter.h" +#include"ast/rewriter/datatype_rewriter.h" +#include"ast/rewriter/array_rewriter.h" +#include"ast/rewriter/rewriter_def.h" +#include"util/cooperate.h" +#include"ast/ast_pp.h" +#include"model/func_interp.h" diff --git a/src/muz/spacer/spacer_mev_array.h b/src/muz/spacer/spacer_mev_array.h index d7904d677..078925865 100644 --- a/src/muz/spacer/spacer_mev_array.h +++ b/src/muz/spacer/spacer_mev_array.h @@ -18,10 +18,10 @@ Revision History: #ifndef _SPACER_MEV_ARRAY_H_ #define _SPACER_MEV_ARRAY_H_ -#include"ast.h" -#include"rewriter_types.h" -#include"params.h" -#include "array_decl_plugin.h" +#include"ast/ast.h" +#include"ast/rewriter/rewriter_types.h" +#include"util/params.h" +#include"ast/array_decl_plugin.h" /** * based on model_evaluator in muz/pdr/pdr_util.h From 25c6480e6eabab36c766e72f8429991398208071 Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Mon, 31 Jul 2017 23:16:42 -0400 Subject: [PATCH 069/488] updated include directives --- src/model/model_evaluator.h | 4 +- src/muz/spacer/spacer_context.h | 6 +- src/muz/spacer/spacer_min_cut.cpp | 2 +- src/muz/spacer/spacer_min_cut.h | 3 +- src/muz/spacer/spacer_proof_utils.cpp | 8 +-- src/muz/spacer/spacer_proof_utils.h | 2 +- src/muz/spacer/spacer_prop_solver.cpp | 30 +++++---- src/muz/spacer/spacer_prop_solver.h | 17 ++--- src/muz/spacer/spacer_qe_project.cpp | 32 +++++---- src/muz/spacer/spacer_qe_project.h | 4 +- src/muz/spacer/spacer_smt_context_manager.cpp | 18 ++--- src/muz/spacer/spacer_smt_context_manager.h | 10 +-- src/muz/spacer/spacer_sym_mux.cpp | 17 ++--- src/muz/spacer/spacer_sym_mux.h | 6 +- src/muz/spacer/spacer_unsat_core_learner.cpp | 11 ++-- src/muz/spacer/spacer_unsat_core_learner.h | 6 +- src/muz/spacer/spacer_unsat_core_plugin.cpp | 24 +++---- src/muz/spacer/spacer_unsat_core_plugin.h | 4 +- src/muz/spacer/spacer_util.cpp | 66 +++++++++---------- src/muz/spacer/spacer_util.h | 26 ++++---- src/muz/spacer/spacer_virtual_solver.cpp | 14 ++-- src/muz/spacer/spacer_virtual_solver.h | 12 ++-- 22 files changed, 169 insertions(+), 153 deletions(-) diff --git a/src/model/model_evaluator.h b/src/model/model_evaluator.h index 2497ec927..bd2b2d664 100644 --- a/src/model/model_evaluator.h +++ b/src/model/model_evaluator.h @@ -22,7 +22,9 @@ Revision History: #include "ast/ast.h" #include "ast/rewriter/rewriter_types.h" #include "util/params.h" + class model; +class model_core; typedef rewriter_exception model_evaluator_exception; @@ -46,7 +48,7 @@ public: void cleanup(params_ref const & p = params_ref()); void reset(params_ref const & p = params_ref()); - + unsigned get_num_steps() const; }; diff --git a/src/muz/spacer/spacer_context.h b/src/muz/spacer/spacer_context.h index 78541130c..b6cfaff0c 100644 --- a/src/muz/spacer/spacer_context.h +++ b/src/muz/spacer/spacer_context.h @@ -28,8 +28,10 @@ Notes: #undef max #endif #include -#include "spacer_manager.h" -#include "spacer_prop_solver.h" + +#include "muz/spacer/spacer_manager.h" +#include "muz/spacer/spacer_prop_solver.h" + #include "fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/spacer/spacer_min_cut.cpp b/src/muz/spacer/spacer_min_cut.cpp index c56ddbd66..22ff81a80 100644 --- a/src/muz/spacer/spacer_min_cut.cpp +++ b/src/muz/spacer/spacer_min_cut.cpp @@ -15,7 +15,7 @@ Revision History: --*/ -#include "spacer_min_cut.h" +#include "muz/spacer/spacer_min_cut.h" namespace spacer { diff --git a/src/muz/spacer/spacer_min_cut.h b/src/muz/spacer/spacer_min_cut.h index ae285b9bb..c73a8d3d3 100644 --- a/src/muz/spacer/spacer_min_cut.h +++ b/src/muz/spacer/spacer_min_cut.h @@ -19,7 +19,8 @@ Revision History: #ifndef _SPACER_MIN_CUT_H_ #define _SPACER_MIN_CUT_H_ -#include "ast.h" +#include "ast/ast.h" +#include "util/vector.h" namespace spacer { diff --git a/src/muz/spacer/spacer_proof_utils.cpp b/src/muz/spacer/spacer_proof_utils.cpp index ff020dee4..6edb29881 100644 --- a/src/muz/spacer/spacer_proof_utils.cpp +++ b/src/muz/spacer/spacer_proof_utils.cpp @@ -16,11 +16,11 @@ Revision History: --*/ -#include "spacer_proof_utils.h" -#include "ast_util.h" -#include "ast_pp.h" +#include "muz/spacer/spacer_proof_utils.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" -#include "proof_checker.h" +#include "ast/proof_checker/proof_checker.h" namespace spacer { diff --git a/src/muz/spacer/spacer_proof_utils.h b/src/muz/spacer/spacer_proof_utils.h index 7973c673b..f2897f7ec 100644 --- a/src/muz/spacer/spacer_proof_utils.h +++ b/src/muz/spacer/spacer_proof_utils.h @@ -18,7 +18,7 @@ Revision History: #ifndef _SPACER_PROOF_UTILS_H_ #define _SPACER_PROOF_UTILS_H_ -#include "ast.h" +#include "ast/ast.h" namespace spacer { /* diff --git a/src/muz/spacer/spacer_prop_solver.cpp b/src/muz/spacer/spacer_prop_solver.cpp index 29b34b799..27225315c 100644 --- a/src/muz/spacer/spacer_prop_solver.cpp +++ b/src/muz/spacer/spacer_prop_solver.cpp @@ -18,19 +18,23 @@ Revision History: --*/ -#include -#include "model.h" -#include "spacer_util.h" -#include "spacer_prop_solver.h" -#include "ast_smt2_pp.h" -#include "dl_util.h" -#include "model_pp.h" -#include "smt_params.h" -#include "datatype_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "spacer_farkas_learner.h" -#include "ast_smt2_pp.h" -#include "expr_replacer.h" +#include "ast/ast_smt2_pp.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" + +#include "ast/rewriter/expr_replacer.h" + +#include "smt/params/smt_params.h" + +#include "model/model.h" +#include "model/model_pp.h" + +#include "muz/base/dl_util.h" + +#include "muz/spacer/spacer_util.h" +#include "muz/spacer/spacer_farkas_learner.h" +#include "muz/spacer/spacer_prop_solver.h" + #include "fixedpoint_params.hpp" namespace spacer { diff --git a/src/muz/spacer/spacer_prop_solver.h b/src/muz/spacer/spacer_prop_solver.h index 4f5df819b..1ddec91c6 100644 --- a/src/muz/spacer/spacer_prop_solver.h +++ b/src/muz/spacer/spacer_prop_solver.h @@ -23,14 +23,15 @@ Revision History: #include #include #include -#include "ast.h" -#include "obj_hashtable.h" -#include "smt_kernel.h" -#include "util.h" -#include "vector.h" -#include "spacer_manager.h" -#include "spacer_smt_context_manager.h" -#include "spacer_itp_solver.h" + +#include "ast/ast.h" +#include "util/obj_hashtable.h" +#include "smt/smt_kernel.h" +#include "util/util.h" +#include "util/vector.h" +#include "muz/spacer/spacer_manager.h" +#include "muz/spacer/spacer_smt_context_manager.h" +#include "muz/spacer/spacer_itp_solver.h" struct fixedpoint_params; diff --git a/src/muz/spacer/spacer_qe_project.cpp b/src/muz/spacer/spacer_qe_project.cpp index cfc5d6449..62c9c2643 100644 --- a/src/muz/spacer/spacer_qe_project.cpp +++ b/src/muz/spacer/spacer_qe_project.cpp @@ -21,20 +21,24 @@ Revision History: --*/ -#include "spacer_qe_project.h" -#include "qe_vartest.h" -#include "qe.h" -#include "arith_decl_plugin.h" -#include "ast_pp.h" -#include "th_rewriter.h" -#include "expr_functors.h" -#include "expr_substitution.h" -#include "expr_replacer.h" -#include "model_pp.h" -#include "expr_safe_replace.h" -#include "model_evaluator.h" -#include "qe_lite.h" -#include "spacer_mev_array.h" +#include "ast/arith_decl_plugin.h" +#include "ast/ast_pp.h" +#include "ast/expr_functors.h" +#include "ast/expr_substitution.h" + +#include "ast/rewriter/expr_replacer.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/rewriter/th_rewriter.h" + +#include "model/model_evaluator.h" +#include "model/model_pp.h" + +#include "qe/qe.h" +#include "qe/qe_vartest.h" +#include "qe/qe_lite.h" + +#include "muz/spacer/spacer_mev_array.h" +#include "muz/spacer/spacer_qe_project.h" namespace { diff --git a/src/muz/spacer/spacer_qe_project.h b/src/muz/spacer/spacer_qe_project.h index 6074f0d91..b923dc3c7 100644 --- a/src/muz/spacer/spacer_qe_project.h +++ b/src/muz/spacer/spacer_qe_project.h @@ -20,8 +20,8 @@ Notes: #ifndef SPACER_QE_PROJECT_H_ #define SPACER_QE_PROJECT_H_ -#include "model.h" -#include "expr_map.h" +#include "model/model.h" +#include "ast/expr_map.h" namespace qe { /** diff --git a/src/muz/spacer/spacer_smt_context_manager.cpp b/src/muz/spacer/spacer_smt_context_manager.cpp index f5e5ba9c1..e6ab2c883 100644 --- a/src/muz/spacer/spacer_smt_context_manager.cpp +++ b/src/muz/spacer/spacer_smt_context_manager.cpp @@ -17,16 +17,16 @@ Revision History: --*/ -#include "spacer_smt_context_manager.h" -#include "has_free_vars.h" -#include "ast_pp.h" -#include "ast_smt_pp.h" -#include -#include "smt_params.h" -#include "ast_pp_util.h" -#include "smt_context.h" -#include "spacer_util.h" +#include "ast/ast_pp.h" +#include "ast/ast_pp_util.h" +#include "ast/ast_smt_pp.h" + +#include "smt/smt_context.h" +#include "smt/params/smt_params.h" + +#include "muz/spacer/spacer_util.h" +#include "muz/spacer/spacer_smt_context_manager.h" namespace spacer { diff --git a/src/muz/spacer/spacer_smt_context_manager.h b/src/muz/spacer/spacer_smt_context_manager.h index fd04eaf4e..0df9bc77b 100644 --- a/src/muz/spacer/spacer_smt_context_manager.h +++ b/src/muz/spacer/spacer_smt_context_manager.h @@ -20,11 +20,11 @@ Revision History: #ifndef _SPACER_SMT_CONTEXT_MANAGER_H_ #define _SPACER_SMT_CONTEXT_MANAGER_H_ -#include "smt_kernel.h" -#include "func_decl_dependencies.h" -#include "dl_util.h" -#include "spacer_virtual_solver.h" -#include "stopwatch.h" +#include "util/stopwatch.h" + +#include "smt/smt_kernel.h" +#include "muz/base/dl_util.h" +#include "muz/spacer/spacer_virtual_solver.h" namespace spacer { diff --git a/src/muz/spacer/spacer_sym_mux.cpp b/src/muz/spacer/spacer_sym_mux.cpp index 659aea2cc..da8f8eeca 100644 --- a/src/muz/spacer/spacer_sym_mux.cpp +++ b/src/muz/spacer/spacer_sym_mux.cpp @@ -17,14 +17,15 @@ Revision History: --*/ -#include -#include "ast_pp.h" -#include "for_each_expr.h" -#include "model.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "spacer_util.h" -#include "spacer_sym_mux.h" +#include "ast/ast_pp.h" +#include "ast/for_each_expr.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" + +#include "model/model.h" + +#include "muz/spacer/spacer_util.h" +#include "muz/spacer/spacer_sym_mux.h" using namespace spacer; diff --git a/src/muz/spacer/spacer_sym_mux.h b/src/muz/spacer/spacer_sym_mux.h index d9bae95a3..892542557 100644 --- a/src/muz/spacer/spacer_sym_mux.h +++ b/src/muz/spacer/spacer_sym_mux.h @@ -20,9 +20,9 @@ Revision History: #ifndef _SYM_MUX_H_ #define _SYM_MUX_H_ -#include "ast.h" -#include "map.h" -#include "vector.h" +#include "ast/ast.h" +#include "util/map.h" +#include "util/vector.h" #include class model_core; diff --git a/src/muz/spacer/spacer_unsat_core_learner.cpp b/src/muz/spacer/spacer_unsat_core_learner.cpp index 557858ca4..222ca146c 100644 --- a/src/muz/spacer/spacer_unsat_core_learner.cpp +++ b/src/muz/spacer/spacer_unsat_core_learner.cpp @@ -15,13 +15,12 @@ Revision History: --*/ -#include "spacer_unsat_core_learner.h" - -#include "spacer_unsat_core_plugin.h" - -#include "proof_utils.h" -#include "for_each_expr.h" #include + +#include "muz/spacer/spacer_unsat_core_learner.h" +#include "muz/spacer/spacer_unsat_core_plugin.h" +#include "ast/for_each_expr.h" + namespace spacer { diff --git a/src/muz/spacer/spacer_unsat_core_learner.h b/src/muz/spacer/spacer_unsat_core_learner.h index 91ae01292..6ee7c3b37 100644 --- a/src/muz/spacer/spacer_unsat_core_learner.h +++ b/src/muz/spacer/spacer_unsat_core_learner.h @@ -18,9 +18,9 @@ Revision History: #ifndef _SPACER_UNSAT_CORE_LEARNER_H_ #define _SPACER_UNSAT_CORE_LEARNER_H_ -#include "ast.h" -#include "spacer_util.h" -#include "spacer_proof_utils.h" +#include "ast/ast.h" +#include "muz/spacer/spacer_util.h" +#include "muz/spacer/spacer_proof_utils.h" namespace spacer { diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index 58c700dae..a352a2460 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -15,19 +15,21 @@ Revision History: --*/ -#include "spacer_unsat_core_plugin.h" - -#include "spacer_unsat_core_learner.h" - -#include "smt_farkas_util.h" -#include "bool_rewriter.h" -#include "arith_decl_plugin.h" #include -#include "smt_solver.h" -#include "solver.h" #include -#include "spacer_proof_utils.h" -#include "spacer_matrix.h" + +#include "ast/rewriter/bool_rewriter.h" +#include "ast/arith_decl_plugin.h" + +#include "solver/solver.h" + +#include "smt/smt_farkas_util.h" +#include "smt/smt_solver.h" + +#include "muz/spacer/spacer_proof_utils.h" +#include "muz/spacer/spacer_matrix.h" +#include "muz/spacer/spacer_unsat_core_plugin.h" +#include "muz/spacer/spacer_unsat_core_learner.h" namespace spacer { diff --git a/src/muz/spacer/spacer_unsat_core_plugin.h b/src/muz/spacer/spacer_unsat_core_plugin.h index 6e1f383c1..388a2bd38 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.h +++ b/src/muz/spacer/spacer_unsat_core_plugin.h @@ -18,8 +18,8 @@ Revision History: #ifndef _SPACER_UNSAT_CORE_PLUGIN_H_ #define _SPACER_UNSAT_CORE_PLUGIN_H_ -#include "ast.h" -#include "spacer_min_cut.h" +#include "ast/ast.h" +#include "muz/spacer/spacer_min_cut.h" namespace spacer { diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp index a2cf4101f..be6b12cd0 100644 --- a/src/muz/spacer/spacer_util.cpp +++ b/src/muz/spacer/spacer_util.cpp @@ -27,43 +27,43 @@ Notes: #include #include -#include "ast.h" -#include "occurs.h" -#include "array_decl_plugin.h" -#include "ast_pp.h" -#include "bool_rewriter.h" -#include "dl_util.h" -#include "for_each_expr.h" -#include "smt_params.h" -#include "model.h" -#include "model_evaluator.h" -#include "ref_vector.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "util.h" -#include "spacer_manager.h" -#include "spacer_util.h" -#include "arith_decl_plugin.h" -#include "expr_replacer.h" -#include "model_smt2_pp.h" -#include "scoped_proof.h" -#include "qe_lite.h" -#include "spacer_qe_project.h" -#include "model_pp.h" -#include "expr_safe_replace.h" +#include "ast/ast.h" +#include "ast/occurs.h" +#include "ast/ast_pp.h" +#include "ast/rewriter/bool_rewriter.h" +#include "muz/base/dl_util.h" +#include "ast/for_each_expr.h" +#include "smt/params/smt_params.h" +#include "model/model.h" +#include "model/model_evaluator.h" +#include "util/ref_vector.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "util/util.h" +#include "muz/spacer/spacer_manager.h" +#include "muz/spacer/spacer_util.h" +#include "ast/rewriter/expr_replacer.h" +#include "model/model_smt2_pp.h" +#include "ast/scoped_proof.h" +#include "qe/qe_lite.h" +#include "muz/spacer/spacer_qe_project.h" +#include "model/model_pp.h" +#include "ast/rewriter/expr_safe_replace.h" -#include "datatype_decl_plugin.h" -#include "bv_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" +#include "ast/bv_decl_plugin.h" -#include "spacer_legacy_mev.h" -#include "qe_mbp.h" +#include "muz/spacer/spacer_legacy_mev.h" +#include "qe/qe_mbp.h" -#include "tactical.h" -#include "propagate_values_tactic.h" -#include "propagate_ineqs_tactic.h" -#include "arith_bounds_tactic.h" +#include "tactic/tactical.h" +#include "tactic/core/propagate_values_tactic.h" +#include "tactic/arith/propagate_ineqs_tactic.h" +#include "tactic/arith/arith_bounds_tactic.h" -#include "obj_equiv_class.h" +#include "muz/spacer/obj_equiv_class.h" namespace spacer { diff --git a/src/muz/spacer/spacer_util.h b/src/muz/spacer/spacer_util.h index f51df7a7b..5bbb84bfb 100644 --- a/src/muz/spacer/spacer_util.h +++ b/src/muz/spacer/spacer_util.h @@ -22,20 +22,20 @@ Revision History: #ifndef _SPACER_UTIL_H_ #define _SPACER_UTIL_H_ -#include "ast.h" -#include "ast_pp.h" -#include "obj_hashtable.h" -#include "ref_vector.h" -#include "simplifier.h" -#include "trace.h" -#include "vector.h" -#include "arith_decl_plugin.h" -#include "array_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "model.h" +#include "ast/ast.h" +#include "ast/ast_pp.h" +#include "util/obj_hashtable.h" +#include "util/ref_vector.h" +#include "ast/simplifier/simplifier.h" +#include "util/trace.h" +#include "util/vector.h" +#include "ast/arith_decl_plugin.h" +#include "ast/array_decl_plugin.h" +#include "ast/bv_decl_plugin.h" +#include "model/model.h" -#include "stopwatch.h" -#include "spacer_antiunify.h" +#include "util/stopwatch.h" +#include "muz/spacer/spacer_antiunify.h" class model; class model_core; diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp index c6b85a3ea..c080fa2c4 100644 --- a/src/muz/spacer/spacer_virtual_solver.cpp +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -17,15 +17,15 @@ Notes: --*/ -#include "spacer_virtual_solver.h" -#include "ast_util.h" -#include "ast_pp_util.h" -#include "spacer_util.h" -#include "bool_rewriter.h" +#include "muz/spacer/spacer_virtual_solver.h" +#include "ast/ast_util.h" +#include "ast/ast_pp_util.h" +#include "muz/spacer/spacer_util.h" +#include "ast/rewriter/bool_rewriter.h" -#include "proof_checker.h" +#include "ast/proof_checker/proof_checker.h" -#include "scoped_proof.h" +#include "ast/scoped_proof.h" namespace spacer { virtual_solver::virtual_solver(virtual_solver_factory &factory, diff --git a/src/muz/spacer/spacer_virtual_solver.h b/src/muz/spacer/spacer_virtual_solver.h index b5e97dce0..14e05302e 100644 --- a/src/muz/spacer/spacer_virtual_solver.h +++ b/src/muz/spacer/spacer_virtual_solver.h @@ -18,12 +18,12 @@ Notes: --*/ #ifndef SPACER_VIRTUAL_SOLVER_H_ #define SPACER_VIRTUAL_SOLVER_H_ -#include"ast.h" -#include"params.h" -#include"solver_na2as.h" -#include"smt_kernel.h" -#include"smt_params.h" -#include"stopwatch.h" +#include"ast/ast.h" +#include"util/params.h" +#include"solver/solver_na2as.h" +#include"smt/smt_kernel.h" +#include"smt/params/smt_params.h" +#include"util/stopwatch.h" namespace spacer { class virtual_solver_factory; From b12882d94a52c2eb1e3c9b38c6285f725d96dad5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 21:56:13 -0700 Subject: [PATCH 070/488] a few more spacer related warning messages Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/spacer_antiunify.cpp | 8 +-- src/muz/spacer/spacer_farkas_learner.cpp | 4 +- src/muz/spacer/spacer_generalizers.cpp | 5 +- src/muz/spacer/spacer_legacy_frames.cpp | 1 + src/muz/spacer/spacer_prop_solver.cpp | 1 + src/muz/spacer/spacer_qe_project.cpp | 3 +- src/muz/spacer/spacer_unsat_core_plugin.cpp | 76 +++++++++------------ 7 files changed, 44 insertions(+), 54 deletions(-) diff --git a/src/muz/spacer/spacer_antiunify.cpp b/src/muz/spacer/spacer_antiunify.cpp index 6c382a723..7dae59b6a 100644 --- a/src/muz/spacer/spacer_antiunify.cpp +++ b/src/muz/spacer/spacer_antiunify.cpp @@ -335,8 +335,8 @@ bool naive_convex_closure::compute_closure(anti_unifier& au, ast_manager& m, // for each substitution entry bool is_first_key = true; - unsigned lower_bound; - unsigned upper_bound; + unsigned lower_bound = 0; + unsigned upper_bound = 0; for (const auto& pair : au.get_substitution(0)) { // construct vector expr* key = &pair.get_key(); @@ -355,8 +355,8 @@ bool naive_convex_closure::compute_closure(anti_unifier& au, ast_manager& m, } // check whether vector represents interval - unsigned current_lower_bound; - unsigned current_upper_bound; + unsigned current_lower_bound = 0; + unsigned current_upper_bound = 0; // if vector represents interval if (get_range(entries, current_lower_bound, current_upper_bound)) { diff --git a/src/muz/spacer/spacer_farkas_learner.cpp b/src/muz/spacer/spacer_farkas_learner.cpp index 29d238cc9..47bc474ef 100644 --- a/src/muz/spacer/spacer_farkas_learner.cpp +++ b/src/muz/spacer/spacer_farkas_learner.cpp @@ -389,11 +389,11 @@ void farkas_learner::get_lemmas(proof* root, expr_set const& bs, expr_ref_vector simplify_bounds(lemmas); } -void farkas_learner::get_asserted(proof* p, expr_set const& bs, ast_mark& b_closed, obj_hashtable& lemma_set, expr_ref_vector& lemmas) +void farkas_learner::get_asserted(proof* p0, expr_set const& bs, ast_mark& b_closed, obj_hashtable& lemma_set, expr_ref_vector& lemmas) { ast_manager& m = lemmas.get_manager(); ast_mark visited; - proof* p0 = p; + proof* p = p0; ptr_vector todo; todo.push_back(p); diff --git a/src/muz/spacer/spacer_generalizers.cpp b/src/muz/spacer/spacer_generalizers.cpp index 9f8757024..40e5c2c4d 100644 --- a/src/muz/spacer/spacer_generalizers.cpp +++ b/src/muz/spacer/spacer_generalizers.cpp @@ -133,9 +133,7 @@ void unsat_core_generalizer::operator()(lemma_ref &lemma) unsigned uses_level; expr_ref_vector core(m); - bool r; - r = pt.is_invariant(lemma->level(), lemma->get_expr(), uses_level, &core); - SASSERT(r); + VERIFY(pt.is_invariant(lemma->level(), lemma->get_expr(), uses_level, &core)); CTRACE("spacer", old_sz > core.size(), tout << "unsat core reduced lemma from: " @@ -185,6 +183,7 @@ void lemma_array_eq_generalizer::operator() (lemma_ref &lemma) // -- find array constants ast_manager &m = lemma->get_ast_manager(); manager &pm = m_ctx.get_manager(); + (void)pm; expr_ref_vector core(m); expr_ref v(m); diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp index 77e6f5650..6c732ecc0 100644 --- a/src/muz/spacer/spacer_legacy_frames.cpp +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -79,6 +79,7 @@ bool pred_transformer::legacy_frames::propagate_to_next_level(unsigned src_level { ast_manager &m = m_pt.get_ast_manager(); + (void) m; if (m_levels.size() <= src_level) { return true; } if (m_levels [src_level].empty()) { return true; } diff --git a/src/muz/spacer/spacer_prop_solver.cpp b/src/muz/spacer/spacer_prop_solver.cpp index 27225315c..719443457 100644 --- a/src/muz/spacer/spacer_prop_solver.cpp +++ b/src/muz/spacer/spacer_prop_solver.cpp @@ -264,6 +264,7 @@ lbool prop_solver::check_assumptions(const expr_ref_vector & _hard, else { m_ctx->assert_expr(bg[i]); } unsigned soft_sz = soft.size(); + (void) soft_sz; lbool res = internal_check_assumptions(hard, soft); if (!m_use_push_bg) { m_ctx->pop(1); } diff --git a/src/muz/spacer/spacer_qe_project.cpp b/src/muz/spacer/spacer_qe_project.cpp index 62c9c2643..c06854cb0 100644 --- a/src/muz/spacer/spacer_qe_project.cpp +++ b/src/muz/spacer/spacer_qe_project.cpp @@ -788,7 +788,7 @@ namespace qe { } unsigned find_max(model& mdl, bool do_pos) { - unsigned result; + unsigned result = UINT_MAX; bool found = false; bool found_strict = false; rational found_val (0), r, r_plus_x, found_c; @@ -2078,6 +2078,7 @@ namespace qe { sort* v_sort = m.get_sort (v); sort* val_sort = get_array_range (v_sort); sort* idx_sort = get_array_domain (v_sort, 0); + (void) idx_sort; unsigned start = m_idx_reprs.size (); // append at the end diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index a352a2460..66abb32c6 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -444,10 +444,10 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector 0); @@ -457,12 +457,9 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector ordered_basis; obj_map map; unsigned counter = 0; - for (const auto& linear_combination : m_linear_combinations) - { - for (const auto& pair : linear_combination) - { - if (!map.contains(pair.first)) - { + for (const auto& linear_combination : m_linear_combinations) { + for (const auto& pair : linear_combination) { + if (!map.contains(pair.first)) { ordered_basis.push_back(pair.first); map.insert(pair.first, counter++); } @@ -472,14 +469,12 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector coeffs; - for (unsigned i=0; i < matrix.num_rows(); ++i) - { + for (unsigned i=0; i < matrix.num_rows(); ++i) { coeffs.push_back(expr_ref_vector(m)); } @@ -532,19 +526,17 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vectorassert_expr(lb); s->assert_expr(ub); - } } - + } + // assert: forall i,j: a_ij = sum_k w_ik * s_jk for (unsigned i=0; i < matrix.num_rows(); ++i) { @@ -568,34 +560,30 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vectorcheck_sat(0,0); // if sat extract model and add corresponding linear combinations to core - if (res == lbool::l_true) - { + if (res == lbool::l_true) { model_ref model; s->get_model(model); - - for (int k=0; k < n; ++k) - { - ptr_vector literals; - vector coefficients; - for (unsigned j=0; j < matrix.num_cols(); ++j) - { + + for (unsigned k=0; k < n; ++k) { + ptr_vector literals; + vector coefficients; + for (unsigned j=0; j < matrix.num_cols(); ++j) { expr_ref evaluation(m); - + model.get()->eval(bounded_vectors[j][k].get(), evaluation, false); - if (!util.is_zero(evaluation)) - { + if (!util.is_zero(evaluation)) { literals.push_back(ordered_basis[j]); coefficients.push_back(rational(1)); - } - } + } + } SASSERT(!literals.empty()); // since then previous outer loop would have found solution already - expr_ref linear_combination(m); - compute_linear_combination(coefficients, literals, linear_combination); - - m_learner.add_lemma_to_core(linear_combination); - } + expr_ref linear_combination(m); + compute_linear_combination(coefficients, literals, linear_combination); + + m_learner.add_lemma_to_core(linear_combination); + } return; - } + } } } From 1820ccd49123b20a9d3ed5f4de2b58c21411f803 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 22:15:57 -0700 Subject: [PATCH 071/488] z3-qe-lite? Signed-off-by: Nikolaj Bjorner --- src/api/z3.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/api/z3.h b/src/api/z3.h index fcab174a8..99929f33b 100644 --- a/src/api/z3.h +++ b/src/api/z3.h @@ -32,7 +32,6 @@ Notes: #include "z3_optimization.h" #include "z3_interp.h" #include "z3_fpa.h" - -#include"z3_spacer.h" +#include "z3_spacer.h" #endif From 72c478078e53276404f2c54336570f356c2ff337 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 31 Jul 2017 23:14:53 -0700 Subject: [PATCH 072/488] adding cdecl directive to Z3_qe_lite to address build failure for Java bindings Signed-off-by: Nikolaj Bjorner --- src/api/z3_spacer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/z3_spacer.h b/src/api/z3_spacer.h index c01ee4a4d..88129d095 100644 --- a/src/api/z3_spacer.h +++ b/src/api/z3_spacer.h @@ -128,7 +128,7 @@ extern "C" { def_API ('Z3_qe_lite', AST, (_in(CONTEXT), _in(AST_VECTOR), _in(AST))) */ - Z3_ast Z3_qe_lite + Z3_ast Z3_API Z3_qe_lite (Z3_context c, Z3_ast_vector vars, Z3_ast body); From 6bc5209e268176aa5baa1a24caa6653167f0e797 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 1 Aug 2017 15:53:55 +0100 Subject: [PATCH 073/488] Fixed build problems with .vcxproj --- scripts/mk_util.py | 1 + src/util/lp/bound_analyzer_on_row.h | 2 +- src/util/lp/{bound_propagator.cpp => lp_bound_propagator.cpp} | 0 src/util/lp/{bound_propagator.h => lp_bound_propagator.h} | 0 4 files changed, 2 insertions(+), 1 deletion(-) rename src/util/lp/{bound_propagator.cpp => lp_bound_propagator.cpp} (100%) rename src/util/lp/{bound_propagator.h => lp_bound_propagator.h} (100%) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index a5f75fd1c..d2e3d6b4c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -3046,6 +3046,7 @@ def mk_vs_proj_cl_compile(f, name, components, debug): else: f.write(';') f.write(get_component(dep).to_src_dir) + f.write(';%s\n' % os.path.join(REV_BUILD_DIR, SRC_DIR)) f.write('\n') f.write(' \n') diff --git a/src/util/lp/bound_analyzer_on_row.h b/src/util/lp/bound_analyzer_on_row.h index 2a9dccb5f..add25d389 100644 --- a/src/util/lp/bound_analyzer_on_row.h +++ b/src/util/lp/bound_analyzer_on_row.h @@ -8,7 +8,7 @@ #include "util/lp/implied_bound.h" #include "util/lp/test_bound_analyzer.h" #include -#include "util/lp/bound_propagator.h" +#include "util/lp/lp_bound_propagator.h" // We have an equality : sum by j of row[j]*x[j] = rs // We try to pin a var by pushing the total by using the variable bounds // In a loop we drive the partial sum down, denoting the variables of this process by _u. diff --git a/src/util/lp/bound_propagator.cpp b/src/util/lp/lp_bound_propagator.cpp similarity index 100% rename from src/util/lp/bound_propagator.cpp rename to src/util/lp/lp_bound_propagator.cpp diff --git a/src/util/lp/bound_propagator.h b/src/util/lp/lp_bound_propagator.h similarity index 100% rename from src/util/lp/bound_propagator.h rename to src/util/lp/lp_bound_propagator.h From e315d063c5c0988d511ff00a60f966c29350f5e1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 1 Aug 2017 16:07:51 +0100 Subject: [PATCH 074/488] renamed LP bound propagator to avoid linker name clashes --- src/smt/theory_lra.cpp | 354 ++++++++++++++-------------- src/util/lp/bound_analyzer_on_row.h | 32 +-- src/util/lp/lar_solver.h | 168 ++++++------- src/util/lp/lp_bound_propagator.cpp | 12 +- src/util/lp/lp_bound_propagator.h | 4 +- 5 files changed, 285 insertions(+), 285 deletions(-) diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index 9e4f544c1..e55ac16e8 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -48,7 +48,7 @@ namespace lp { return out; } - class bound { + class bound { smt::bool_var m_bv; smt::theory_var m_var; rational m_value; @@ -66,11 +66,11 @@ namespace lp { smt::bool_var get_bv() const { return m_bv; } bound_kind get_bound_kind() const { return m_bound_kind; } rational const& get_value() const { return m_value; } - inf_rational get_value(bool is_true) const { + inf_rational get_value(bool is_true) const { if (is_true) return inf_rational(m_value); // v >= value or v <= value if (m_bound_kind == lower_t) return inf_rational(m_value, false); // v <= value - epsilon return inf_rational(m_value, true); // v >= value + epsilon - } + } virtual std::ostream& display(std::ostream& out) const { return out << "v" << get_var() << " " << get_bound_kind() << " " << m_value; } @@ -111,12 +111,12 @@ namespace lp { namespace smt { typedef ptr_vector lp_bounds; - - class theory_lra::imp { + + class theory_lra::imp { struct scope { unsigned m_bounds_lim; - unsigned m_asserted_qhead; + unsigned m_asserted_qhead; unsigned m_asserted_atoms_lim; unsigned m_delayed_terms_lim; unsigned m_delayed_equalities_lim; @@ -150,7 +150,7 @@ namespace smt { vector m_columns; // temporary values kept during internalization struct internalize_state { - expr_ref_vector m_terms; + expr_ref_vector m_terms; vector m_coeffs; svector m_vars; rational m_coeff; @@ -182,21 +182,21 @@ namespace smt { public: scoped_internalize_state(imp& i): m_imp(i), m_st(push_internalize(i)) {} ~scoped_internalize_state() { --m_imp.m_internalize_head; } - expr_ref_vector& terms() { return m_st.m_terms; } + expr_ref_vector& terms() { return m_st.m_terms; } vector& coeffs() { return m_st.m_coeffs; } svector& vars() { return m_st.m_vars; } rational& coeff() { return m_st.m_coeff; } - ptr_vector& terms_to_internalize() { return m_st.m_terms_to_internalize; } + ptr_vector& terms_to_internalize() { return m_st.m_terms_to_internalize; } void push(expr* e, rational c) { m_st.m_terms.push_back(e); m_st.m_coeffs.push_back(c); } - void set_back(unsigned i) { + void set_back(unsigned i) { if (terms().size() == i + 1) return; - terms()[i] = terms().back(); + terms()[i] = terms().back(); coeffs()[i] = coeffs().back(); terms().pop_back(); coeffs().pop_back(); } }; - + typedef vector> var_coeffs; struct delayed_def { vector m_coeffs; @@ -208,8 +208,8 @@ namespace smt { }; svector m_theory_var2var_index; // translate from theory variables to lar vars - svector m_var_index2theory_var; // reverse map from lp_solver variables to theory variables - svector m_term_index2theory_var; // reverse map from lp_solver variables to theory variables + svector m_var_index2theory_var; // reverse map from lp_solver variables to theory variables + svector m_term_index2theory_var; // reverse map from lp_solver variables to theory variables var_coeffs m_left_side; // constraint left side mutable std::unordered_map m_variable_values; // current model @@ -225,8 +225,8 @@ namespace smt { svector m_definitions; // asserted rows corresponding to definitions bool m_delay_constraints; // configuration - svector m_asserted_atoms; - app_ref_vector m_delayed_terms; + svector m_asserted_atoms; + app_ref_vector m_delayed_terms; svector> m_delayed_equalities; vector m_delayed_defs; expr* m_not_handled; @@ -243,7 +243,7 @@ namespace smt { svector m_to_check; // rows that should be checked for theory propagation - svector > m_assume_eq_candidates; + svector > m_assume_eq_candidates; unsigned m_assume_eq_head; unsigned m_num_conflicts; @@ -264,7 +264,7 @@ namespace smt { svector m_scopes; lp::stats m_stats; - arith_factory* m_factory; + arith_factory* m_factory; scoped_ptr m_solver; resource_limit m_resource_limit; lp_bounds m_new_bounds; @@ -276,12 +276,12 @@ namespace smt { bool is_int(enode* n) const { return a.is_int(n->get_owner()); } enode* get_enode(theory_var v) const { return th.get_enode(v); } enode* get_enode(expr* e) const { return ctx().get_enode(e); } - expr* get_owner(theory_var v) const { return get_enode(v)->get_owner(); } + expr* get_owner(theory_var v) const { return get_enode(v)->get_owner(); } void init_solver() { if (m_solver) return; lp_params lp(ctx().get_params()); - m_solver = alloc(lean::lar_solver); + m_solver = alloc(lean::lar_solver); m_theory_var2var_index.reset(); m_solver->settings().set_resource_limit(m_resource_limit); m_solver->settings().simplex_strategy() = static_cast(lp.simplex_strategy()); @@ -315,7 +315,7 @@ namespace smt { } if (a.is_to_real(term, term)) { continue; - } + } return false; } while (false); @@ -325,15 +325,15 @@ namespace smt { void linearize_term(expr* term, scoped_internalize_state& st) { st.push(term, rational::one()); linearize(st); - } - + } + void linearize_ineq(expr* lhs, expr* rhs, scoped_internalize_state& st) { st.push(lhs, rational::one()); st.push(rhs, rational::minus_one()); linearize(st); } - - void linearize(scoped_internalize_state& st) { + + void linearize(scoped_internalize_state& st) { expr_ref_vector & terms = st.terms(); svector& vars = st.vars(); vector& coeffs = st.coeffs(); @@ -354,7 +354,7 @@ namespace smt { } else if (a.is_sub(n)) { unsigned sz = to_app(n)->get_num_args(); - terms[index] = to_app(n)->get_arg(0); + terms[index] = to_app(n)->get_arg(0); for (unsigned i = 1; i < sz; ++i) { st.push(to_app(n)->get_arg(i), -coeffs[index]); } @@ -423,7 +423,7 @@ namespace smt { return get_enode(n); } else { - return ctx().mk_enode(n, !reflect(n), false, enable_cgc_for(n)); + return ctx().mk_enode(n, !reflect(n), false, enable_cgc_for(n)); } } @@ -459,12 +459,12 @@ namespace smt { } bool reflect(app* n) const { - return m_arith_params.m_arith_reflect || is_underspecified(n); + return m_arith_params.m_arith_reflect || is_underspecified(n); } theory_var mk_var(expr* n, bool internalize = true) { if (!ctx().e_internalized(n)) { - ctx().internalize(n, false); + ctx().internalize(n, false); } enode* e = get_enode(n); theory_var v; @@ -478,12 +478,12 @@ namespace smt { ctx().attach_th_var(e, &th, v); } else { - v = e->get_th_var(get_id()); + v = e->get_th_var(get_id()); } SASSERT(null_theory_var != v); return v; } - + lean::var_index get_var_index(theory_var v) { lean::var_index result = UINT_MAX; if (m_theory_var2var_index.size() > static_cast(v)) { @@ -497,7 +497,7 @@ namespace smt { } return result; } - + void init_left_side(scoped_internalize_state& st) { SASSERT(all_zeros(m_columns)); svector const& vars = st.vars(); @@ -510,7 +510,7 @@ namespace smt { } else { m_columns[var] += coeff; - } + } } m_left_side.clear(); // reset the coefficients after they have been used. @@ -519,12 +519,12 @@ namespace smt { rational const& r = m_columns[var]; if (!r.is_zero()) { m_left_side.push_back(std::make_pair(r, get_var_index(var))); - m_columns[var].reset(); + m_columns[var].reset(); } } SASSERT(all_zeros(m_columns)); } - + bool all_zeros(vector const& v) const { for (unsigned i = 0; i < v.size(); ++i) { if (!v[i].is_zero()) { @@ -533,20 +533,20 @@ namespace smt { } return true; } - + void add_eq_constraint(lean::constraint_index index, enode* n1, enode* n2) { m_constraint_sources.setx(index, equality_source, null_source); m_equalities.setx(index, enode_pair(n1, n2), enode_pair(0, 0)); ++m_stats.m_add_rows; } - + void add_ineq_constraint(lean::constraint_index index, literal lit) { m_constraint_sources.setx(index, inequality_source, null_source); m_inequalities.setx(index, lit, null_literal); ++m_stats.m_add_rows; TRACE("arith", m_solver->print_constraint(index, tout); tout << "\n";); } - + void add_def_constraint(lean::constraint_index index, theory_var v) { m_constraint_sources.setx(index, definition_source, null_source); m_definitions.setx(index, v, null_theory_var); @@ -556,12 +556,12 @@ namespace smt { void internalize_eq(delayed_def const& d) { scoped_internalize_state st(*this); st.vars().append(d.m_vars); - st.coeffs().append(d.m_coeffs); + st.coeffs().append(d.m_coeffs); init_left_side(st); add_def_constraint(m_solver->add_constraint(m_left_side, lean::EQ, -d.m_coeff), d.m_var); } - - void internalize_eq(theory_var v1, theory_var v2) { + + void internalize_eq(theory_var v1, theory_var v2) { enode* n1 = get_enode(v1); enode* n2 = get_enode(v2); scoped_internalize_state st(*this); @@ -571,7 +571,7 @@ namespace smt { st.coeffs().push_back(rational::minus_one()); init_left_side(st); add_eq_constraint(m_solver->add_constraint(m_left_side, lean::EQ, rational::zero()), n1, n2); - TRACE("arith", + TRACE("arith", tout << "v" << v1 << " = " << "v" << v2 << ": " << mk_pp(n1->get_owner(), m) << " = " << mk_pp(n2->get_owner(), m) << "\n";); } @@ -583,7 +583,7 @@ namespace smt { lp::bound* b = m_bounds[v].back(); // del_use_lists(b); dealloc(b); - m_bounds[v].pop_back(); + m_bounds[v].pop_back(); } m_bounds_trail.shrink(old_size); } @@ -591,9 +591,9 @@ namespace smt { void updt_unassigned_bounds(theory_var v, int inc) { TRACE("arith", tout << "v" << v << " " << m_unassigned_bounds[v] << " += " << inc << "\n";); ctx().push_trail(vector_value_trail(m_unassigned_bounds, v)); - m_unassigned_bounds[v] += inc; + m_unassigned_bounds[v] += inc; } - + bool is_unit_var(scoped_internalize_state& st) { return st.coeff().is_zero() && st.vars().size() == 1 && st.coeffs()[0].is_one(); } @@ -644,26 +644,26 @@ namespace smt { return v; } } - + public: - imp(theory_lra& th, ast_manager& m, theory_arith_params& ap): - th(th), m(m), - m_arith_params(ap), - a(m), - m_arith_eq_adapter(th, ap, a), + imp(theory_lra& th, ast_manager& m, theory_arith_params& ap): + th(th), m(m), + m_arith_params(ap), + a(m), + m_arith_eq_adapter(th, ap, a), m_internalize_head(0), - m_delay_constraints(false), + m_delay_constraints(false), m_delayed_terms(m), m_not_handled(0), - m_asserted_qhead(0), + m_asserted_qhead(0), m_assume_eq_head(0), m_num_conflicts(0), m_model_eqs(DEFAULT_HASHTABLE_INITIAL_CAPACITY, var_value_hash(*this), var_value_eq(*this)), m_solver(0), m_resource_limit(*this) { } - + ~imp() { del_bounds(0); std::for_each(m_internalize_states.begin(), m_internalize_states.end(), delete_proc()); @@ -672,7 +672,7 @@ namespace smt { void init(context* ctx) { init_solver(); } - + bool internalize_atom(app * atom, bool gate_ctx) { if (m_delay_constraints) { return internalize_atom_lazy(atom, gate_ctx); @@ -697,7 +697,7 @@ namespace smt { else if (a.is_ge(atom, n1, n2) && is_numeral(n2, r) && is_app(n1)) { v = internalize_def(to_app(n1)); k = lp::lower_t; - } + } else { TRACE("arith", tout << "Could not internalize " << mk_pp(atom, m) << "\n";); found_not_handled(atom); @@ -730,7 +730,7 @@ namespace smt { else if (a.is_ge(atom, n1, n2) && is_numeral(n2, r) && is_app(n1)) { v = internalize_def(to_app(n1), st); k = lp::lower_t; - } + } else { TRACE("arith", tout << "Could not internalize " << mk_pp(atom, m) << "\n";); found_not_handled(atom); @@ -743,11 +743,11 @@ namespace smt { m_bool_var2bound.insert(bv, b); TRACE("arith", tout << "Internalized " << mk_pp(atom, m) << "\n";); if (!is_unit_var(st) && m_bounds[v].size() == 1) { - m_delayed_defs.push_back(delayed_def(st.vars(), st.coeffs(), st.coeff(), v)); + m_delayed_defs.push_back(delayed_def(st.vars(), st.coeffs(), st.coeff(), v)); } return true; } - + bool internalize_term(app * term) { if (ctx().e_internalized(term) && th.is_attached_to_var(ctx().get_enode(term))) { // skip @@ -766,7 +766,7 @@ namespace smt { } return true; } - + void internalize_eq_eh(app * atom, bool_var) { expr* lhs = 0, *rhs = 0; VERIFY(m.is_eq(atom, lhs, rhs)); @@ -845,7 +845,7 @@ namespace smt { m_underspecified.shrink(m_scopes[old_size].m_underspecified_lim); m_var_trail.shrink(m_scopes[old_size].m_var_trail_lim); m_not_handled = m_scopes[old_size].m_not_handled; - m_scopes.resize(old_size); + m_scopes.resize(old_size); if (!m_delay_constraints) m_solver->pop(num_scopes); // VERIFY(l_false != make_feasible()); m_new_bounds.reset(); @@ -860,16 +860,16 @@ namespace smt { void relevant_eh(app* n) { TRACE("arith", tout << mk_pp(n, m) << "\n";); expr* n1, *n2; - if (a.is_mod(n, n1, n2)) + if (a.is_mod(n, n1, n2)) mk_idiv_mod_axioms(n1, n2); else if (a.is_rem(n, n1, n2)) mk_rem_axiom(n1, n2); - else if (a.is_div(n, n1, n2)) + else if (a.is_div(n, n1, n2)) mk_div_axiom(n1, n2); - else if (a.is_to_int(n)) + else if (a.is_to_int(n)) mk_to_int_axiom(n); else if (a.is_is_int(n)) - mk_is_int_axiom(n); + mk_is_int_axiom(n); } // n < 0 || rem(a, n) = mod(a, n) @@ -881,7 +881,7 @@ namespace smt { expr_ref mmod(a.mk_uminus(mod), m); literal dgez = mk_literal(a.mk_ge(divisor, zero)); mk_axiom(~dgez, th.mk_eq(rem, mod, false)); - mk_axiom( dgez, th.mk_eq(rem, mmod, false)); + mk_axiom( dgez, th.mk_eq(rem, mmod, false)); } // q = 0 or q * (p div q) = p @@ -896,7 +896,7 @@ namespace smt { // to_real(to_int(x)) <= x < to_real(to_int(x)) + 1 void mk_to_int_axiom(app* n) { expr* x = 0, *y = 0; - VERIFY (a.is_to_int(n, x)); + VERIFY (a.is_to_int(n, x)); if (a.is_to_real(x, y)) { mk_axiom(th.mk_eq(y, n, false)); } @@ -945,7 +945,7 @@ namespace smt { mk_axiom(q_le_0, ~mk_literal(a.mk_ge(a.mk_sub(mod, q), zero))); mk_axiom(q_ge_0, ~mk_literal(a.mk_ge(a.mk_add(mod, q), zero))); rational k; - if (m_arith_params.m_arith_enum_const_mod && a.is_numeral(q, k) && + if (m_arith_params.m_arith_enum_const_mod && a.is_numeral(q, k) && k.is_pos() && k < rational(8)) { unsigned _k = k.get_unsigned(); literal_buffer lits; @@ -954,8 +954,8 @@ namespace smt { lits.push_back(mod_j); ctx().mark_as_relevant(mod_j); } - ctx().mk_th_axiom(get_id(), lits.size(), lits.begin()); - } + ctx().mk_th_axiom(get_id(), lits.size(), lits.begin()); + } } void mk_axiom(literal l) { @@ -1006,14 +1006,14 @@ namespace smt { } bool can_get_value(theory_var v) const { - return + return (v != null_theory_var) && - (v < static_cast(m_theory_var2var_index.size())) && - (UINT_MAX != m_theory_var2var_index[v]) && + (v < static_cast(m_theory_var2var_index.size())) && + (UINT_MAX != m_theory_var2var_index[v]) && (m_solver->is_term(m_theory_var2var_index[v]) || m_variable_values.count(m_theory_var2var_index[v]) > 0); } - + bool can_get_ivalue(theory_var v) const { if (v == null_theory_var || (v >= static_cast(m_theory_var2var_index.size()))) return false; @@ -1034,7 +1034,7 @@ namespace smt { return result; } - + rational get_value(theory_var v) const { if (!can_get_value(v)) return rational::zero(); lean::var_index vi = m_theory_var2var_index[v]; @@ -1051,7 +1051,7 @@ namespace smt { return result; } UNREACHABLE(); - return m_variable_values[vi]; + return m_variable_values[vi]; } void init_variable_values() { @@ -1064,20 +1064,20 @@ namespace smt { m_variable_values.clear(); } - bool assume_eqs() { + bool assume_eqs() { svector vars; theory_var sz = static_cast(th.get_num_vars()); for (theory_var v = 0; v < sz; ++v) { - if (th.is_relevant_and_shared(get_enode(v))) { + if (th.is_relevant_and_shared(get_enode(v))) { vars.push_back(m_theory_var2var_index[v]); } } if (vars.empty()) { return false; } - TRACE("arith", + TRACE("arith", for (theory_var v = 0; v < sz; ++v) { - if (th.is_relevant_and_shared(get_enode(v))) { + if (th.is_relevant_and_shared(get_enode(v))) { tout << "v" << v << " " << m_theory_var2var_index[v] << " "; } } @@ -1086,14 +1086,14 @@ namespace smt { m_solver->random_update(vars.size(), vars.c_ptr()); m_model_eqs.reset(); TRACE("arith", display(tout);); - + unsigned old_sz = m_assume_eq_candidates.size(); bool result = false; int start = ctx().get_random_value(); for (theory_var i = 0; i < sz; ++i) { theory_var v = (i + start) % sz; enode* n1 = get_enode(v); - if (!th.is_relevant_and_shared(n1)) { + if (!th.is_relevant_and_shared(n1)) { continue; } if (!can_get_ivalue(v)) { @@ -1112,7 +1112,7 @@ namespace smt { result = true; } } - + if (result) { ctx().push_trail(restore_size_trail, false>(m_assume_eq_candidates, old_sz)); } @@ -1123,7 +1123,7 @@ namespace smt { bool delayed_assume_eqs() { if (m_assume_eq_head == m_assume_eq_candidates.size()) return false; - + ctx().push_trail(value_trail(m_assume_eq_head)); while (m_assume_eq_head < m_assume_eq_candidates.size()) { std::pair const & p = m_assume_eq_candidates[m_assume_eq_head]; @@ -1132,7 +1132,7 @@ namespace smt { enode* n1 = get_enode(v1); enode* n2 = get_enode(v2); m_assume_eq_head++; - CTRACE("arith", + CTRACE("arith", get_ivalue(v1) == get_ivalue(v2) && n1->get_root() != n2->get_root(), tout << "assuming eq: v" << v1 << " = v" << v2 << "\n";); if (get_ivalue(v1) == get_ivalue(v2) && n1->get_root() != n2->get_root() && th.assume_eq(n1, n2)) { @@ -1177,7 +1177,7 @@ namespace smt { if (assume_eqs()) { return FC_CONTINUE; } - if (m_not_handled != 0) { + if (m_not_handled != 0) { return FC_GIVEUP; } return FC_DONE; @@ -1201,7 +1201,7 @@ namespace smt { Thus, 'a' must be considered a shared var if it is the child of an underspecified operator. if merge(a / b, x + y) and a / b is root, then x + y become shared and all z + u in equivalence class of x + y. - + TBD: when the set of underspecified subterms is small, compute the shared variables below it. Recompute the set if there are merges that invalidate it. @@ -1256,7 +1256,7 @@ namespace smt { while (m_asserted_qhead < m_asserted_atoms.size() && !ctx().inconsistent()) { bool_var bv = m_asserted_atoms[m_asserted_qhead].m_bv; bool is_true = m_asserted_atoms[m_asserted_qhead].m_is_true; - + #if 1 m_to_check.push_back(bv); #else @@ -1281,7 +1281,7 @@ namespace smt { }*/ lbool lbl = make_feasible(); - + switch(lbl) { case l_false: TRACE("arith", tout << "propagation conflict\n";); @@ -1294,7 +1294,7 @@ namespace smt { case l_undef: break; } - + } void propagate_bounds_with_lp_solver() { @@ -1351,9 +1351,9 @@ namespace smt { return false; } - struct local_bound_propagator: public lean::bound_propagator { + struct local_bound_propagator: public lean::lp_bound_propagator { imp & m_imp; - local_bound_propagator(imp& i) : bound_propagator(*i.m_solver), m_imp(i) {} + local_bound_propagator(imp& i) : lp_bound_propagator(*i.m_solver), m_imp(i) {} bool bound_is_interesting(unsigned j, lean::lconstraint_kind kind, const rational & v) { return m_imp.bound_is_interesting(j, kind, v); @@ -1364,7 +1364,7 @@ namespace smt { } }; - + void propagate_lp_solver_bound(lean::implied_bound& be) { theory_var v; @@ -1381,7 +1381,7 @@ namespace smt { // if (m_unassigned_bounds[v] == 0) m_solver->print_bound_evidence(be, tout); ); - + if (m_unassigned_bounds[v] == 0 || m_bounds.size() <= static_cast(v)) { TRACE("arith", tout << "return\n";); return; @@ -1447,18 +1447,18 @@ namespace smt { ctx().assign( lit, ctx().mk_justification( ext_theory_propagation_justification( - get_id(), ctx().get_region(), m_core.size(), m_core.c_ptr(), - m_eqs.size(), m_eqs.c_ptr(), lit, m_params.size(), m_params.c_ptr()))); + get_id(), ctx().get_region(), m_core.size(), m_core.c_ptr(), + m_eqs.size(), m_eqs.c_ptr(), lit, m_params.size(), m_params.c_ptr()))); } } literal is_bound_implied(lean::lconstraint_kind k, rational const& value, lp::bound const& b) const { if ((k == lean::LE || k == lean::LT) && b.get_bound_kind() == lp::upper_t && value <= b.get_value()) { - // v <= value <= b.get_value() => v <= b.get_value() + // v <= value <= b.get_value() => v <= b.get_value() return literal(b.get_bv(), false); } if ((k == lean::GE || k == lean::GT) && b.get_bound_kind() == lp::lower_t && b.get_value() <= value) { - // b.get_value() <= value <= v => b.get_value() <= v + // b.get_value() <= value <= v => b.get_value() <= v return literal(b.get_bv(), false); } if (k == lean::LE && b.get_bound_kind() == lp::lower_t && value < b.get_value()) { @@ -1484,8 +1484,8 @@ namespace smt { void mk_bound_axioms(lp::bound& b) { if (!ctx().is_searching()) { // - // NB. We make an assumption that user push calls propagation - // before internal scopes are pushed. This flushes all newly + // NB. We make an assumption that user push calls propagation + // before internal scopes are pushed. This flushes all newly // asserted atoms into the right context. // m_new_bounds.push_back(&b); @@ -1499,7 +1499,7 @@ namespace smt { lp::bound* end = 0; lp::bound* lo_inf = end, *lo_sup = end; lp::bound* hi_inf = end, *hi_sup = end; - + for (unsigned i = 0; i < bounds.size(); ++i) { lp::bound& other = *bounds[i]; if (&other == &b) continue; @@ -1530,7 +1530,7 @@ namespace smt { else if (hi_sup == end || k2 < hi_sup->get_value()) { hi_sup = &other; } - } + } if (lo_inf != end) mk_bound_axiom(b, *lo_inf); if (lo_sup != end) mk_bound_axiom(b, *lo_sup); if (hi_inf != end) mk_bound_axiom(b, *hi_inf); @@ -1550,9 +1550,9 @@ namespace smt { SASSERT(v == b2.get_var()); if (k1 == k2 && kind1 == kind2) return; SASSERT(k1 != k2 || kind1 != kind2); - parameter coeffs[3] = { parameter(symbol("farkas")), + parameter coeffs[3] = { parameter(symbol("farkas")), parameter(rational(1)), parameter(rational(1)) }; - + if (kind1 == lp::lower_t) { if (kind2 == lp::lower_t) { if (k2 <= k1) { @@ -1582,12 +1582,12 @@ namespace smt { } else { // k1 < k2, k2 <= x => ~(x <= k1) - mk_clause(~l1, ~l2, 3, coeffs); + mk_clause(~l1, ~l2, 3, coeffs); if (v_is_int && k1 == k2 - rational(1)) { // x <= k1 or k1+l <= x mk_clause(l1, l2, 3, coeffs); } - + } } else { @@ -1600,7 +1600,7 @@ namespace smt { // k1 <= hi_sup , x <= k1 => x <= hi_sup mk_clause(~l1, l2, 3, coeffs); } - } + } } typedef lp_bounds::iterator iterator; @@ -1609,7 +1609,7 @@ namespace smt { CTRACE("arith", !m_new_bounds.empty(), tout << "flush bound axioms\n";); while (!m_new_bounds.empty()) { - lp_bounds atoms; + lp_bounds atoms; atoms.push_back(m_new_bounds.back()); m_new_bounds.pop_back(); theory_var v = atoms.back()->get_var(); @@ -1620,22 +1620,22 @@ namespace smt { m_new_bounds.pop_back(); --i; } - } - CTRACE("arith_verbose", !atoms.empty(), + } + CTRACE("arith_verbose", !atoms.empty(), for (unsigned i = 0; i < atoms.size(); ++i) { atoms[i]->display(tout); tout << "\n"; }); lp_bounds occs(m_bounds[v]); - + std::sort(atoms.begin(), atoms.end(), compare_bounds()); std::sort(occs.begin(), occs.end(), compare_bounds()); - + iterator begin1 = occs.begin(); iterator begin2 = occs.begin(); iterator end = occs.end(); begin1 = first(lp::lower_t, begin1, end); begin2 = first(lp::upper_t, begin2, end); - + iterator lo_inf = begin1, lo_sup = begin1; iterator hi_inf = begin2, hi_sup = begin2; iterator lo_inf1 = begin1, lo_sup1 = begin1; @@ -1648,10 +1648,10 @@ namespace smt { hi_inf1 = next_inf(a1, lp::upper_t, hi_inf, end, fhi_inf); lo_sup1 = next_sup(a1, lp::lower_t, lo_sup, end, flo_sup); hi_sup1 = next_sup(a1, lp::upper_t, hi_sup, end, fhi_sup); - if (lo_inf1 != end) lo_inf = lo_inf1; - if (lo_sup1 != end) lo_sup = lo_sup1; - if (hi_inf1 != end) hi_inf = hi_inf1; - if (hi_sup1 != end) hi_sup = hi_sup1; + if (lo_inf1 != end) lo_inf = lo_inf1; + if (lo_sup1 != end) lo_sup = lo_sup1; + if (hi_inf1 != end) hi_inf = hi_inf1; + if (hi_sup1 != end) hi_sup = hi_sup1; if (!flo_inf) lo_inf = end; if (!fhi_inf) hi_inf = end; if (!flo_sup) lo_sup = end; @@ -1661,7 +1661,7 @@ namespace smt { if (lo_sup1 != end && lo_sup != end && !visited.contains(*lo_sup)) mk_bound_axiom(*a1, **lo_sup); if (hi_inf1 != end && hi_inf != end && !visited.contains(*hi_inf)) mk_bound_axiom(*a1, **hi_inf); if (hi_sup1 != end && hi_sup != end && !visited.contains(*hi_sup)) mk_bound_axiom(*a1, **hi_sup); - } + } } } @@ -1671,8 +1671,8 @@ namespace smt { lp_bounds::iterator first( - lp::bound_kind kind, - iterator it, + lp::bound_kind kind, + iterator it, iterator end) { for (; it != end; ++it) { lp::bound* a = *it; @@ -1682,16 +1682,16 @@ namespace smt { } lp_bounds::iterator next_inf( - lp::bound* a1, - lp::bound_kind kind, - iterator it, + lp::bound* a1, + lp::bound_kind kind, + iterator it, iterator end, bool& found_compatible) { rational const & k1(a1->get_value()); iterator result = end; found_compatible = false; for (; it != end; ++it) { - lp::bound * a2 = *it; + lp::bound * a2 = *it; if (a1 == a2) continue; if (a2->get_bound_kind() != kind) continue; rational const & k2(a2->get_value()); @@ -1707,15 +1707,15 @@ namespace smt { } lp_bounds::iterator next_sup( - lp::bound* a1, - lp::bound_kind kind, - iterator it, + lp::bound* a1, + lp::bound_kind kind, + iterator it, iterator end, bool& found_compatible) { rational const & k1(a1->get_value()); found_compatible = false; for (; it != end; ++it) { - lp::bound * a2 = *it; + lp::bound * a2 = *it; if (a1 == a2) continue; if (a2->get_bound_kind() != kind) continue; rational const & k2(a2->get_value()); @@ -1728,7 +1728,7 @@ namespace smt { } void propagate_basic_bounds() { - for (auto const& bv : m_to_check) { + for (auto const& bv : m_to_check) { lp::bound& b = *m_bool_var2bound.find(bv); propagate_bound(bv, ctx().get_assignment(bv) == l_true, b); if (ctx().inconsistent()) break; @@ -1736,9 +1736,9 @@ namespace smt { } m_to_check.reset(); } - + // for glb lo': lo' < lo: - // lo <= x -> lo' <= x + // lo <= x -> lo' <= x // lo <= x -> ~(x <= lo') // for lub hi': hi' > hi // x <= hi -> x <= hi' @@ -1773,7 +1773,7 @@ namespace smt { } if (!lb) return; bool sign = lb->get_bound_kind() != lp::lower_t; - lit2 = literal(lb->get_bv(), sign); + lit2 = literal(lb->get_bv(), sign); } else { rational lub; @@ -1791,7 +1791,7 @@ namespace smt { bool sign = ub->get_bound_kind() != lp::upper_t; lit2 = literal(ub->get_bv(), sign); } - TRACE("arith", + TRACE("arith", ctx().display_literal_verbose(tout, lit1); ctx().display_literal_verbose(tout << " => ", lit2); tout << "\n";); @@ -1841,7 +1841,7 @@ namespace smt { // The idea is that if bounds on all variables in an inequality ax + by + cz >= k // have been assigned we may know the truth value of the inequality by using simple // bounds propagation. - // + // void propagate_bound_compound(bool_var bv, bool is_true, lp::bound& b) { theory_var v = b.get_var(); TRACE("arith", tout << mk_pp(get_owner(v), m) << "\n";); @@ -1866,15 +1866,15 @@ namespace smt { lit = literal(vb->get_bv(), true); } } - else { + else { if (get_glb(*vb, r) && r > vb->get_value()) { // VB <= value < val(VB) lit = literal(vb->get_bv(), true); } else if (get_lub(*vb, r) && r <= vb->get_value()) { // val(VB) <= value lit = literal(vb->get_bv(), false); } - } - + } + if (lit != null_literal) { TRACE("arith", ctx().display_literals_verbose(tout, m_core); @@ -1882,7 +1882,7 @@ namespace smt { ctx().display_literal_verbose(tout, lit); tout << "\n"; ); - + assign(lit); } @@ -1934,9 +1934,9 @@ namespace smt { if (is_strict) { r += inf_rational(rational::zero(), coeff.second.is_pos()); } - } + } r += value * coeff.second; - set_evidence(ci); + set_evidence(ci); } TRACE("arith_verbose", tout << (is_lub?"lub":"glb") << " is " << r << "\n";); return true; @@ -1958,7 +1958,7 @@ namespace smt { case lp::upper_t: k = is_true ? lean::LE : lean::GT; break; - } + } if (k == lean::LT || k == lean::LE) { ++m_stats.m_assert_lower; } @@ -1978,7 +1978,7 @@ namespace smt { // A fixed equality is inferred if there are two variables v1, v2 whose // upper and lower bounds coincide. // Then the equality v1 == v2 is propagated to the core. - // + // typedef std::pair constraint_bound; vector m_lower_terms; @@ -2043,11 +2043,11 @@ namespace smt { bool has_upper_bound(lean::var_index vi, lean::constraint_index& ci, rational const& bound) { return has_bound(vi, ci, bound, false); } bool has_lower_bound(lean::var_index vi, lean::constraint_index& ci, rational const& bound) { return has_bound(vi, ci, bound, true); } - + bool has_bound(lean::var_index vi, lean::constraint_index& ci, rational const& bound, bool is_lower) { if (m_solver->is_term(vi)) { - + lean::var_index ti = m_solver->adjust_term_index(vi); theory_var v = m_term_index2theory_var.get(ti, null_theory_var); rational val; @@ -2105,7 +2105,7 @@ namespace smt { set_evidence(ci4); enode* x = get_enode(v1); enode* y = get_enode(v2); - justification* js = + justification* js = ctx().mk_justification( ext_theory_eq_propagation_justification( get_id(), ctx().get_region(), m_core.size(), m_core.c_ptr(), m_eqs.size(), m_eqs.c_ptr(), x, y, 0, 0)); @@ -2114,10 +2114,10 @@ namespace smt { for (unsigned i = 0; i < m_core.size(); ++i) { ctx().display_detailed_literal(tout, m_core[i]); tout << "\n"; - } + } for (unsigned i = 0; i < m_eqs.size(); ++i) { tout << mk_pp(m_eqs[i].first->get_owner(), m) << " = " << mk_pp(m_eqs[i].second->get_owner(), m) << "\n"; - } + } tout << " ==> "; tout << mk_pp(x->get_owner(), m) << " = " << mk_pp(y->get_owner(), m) << "\n"; ); @@ -2158,15 +2158,15 @@ namespace smt { // SASSERT(m_solver->all_constraints_hold()); return l_true; case lean::lp_status::TIME_EXHAUSTED: - + default: TRACE("arith", tout << "status treated as inconclusive: " << status << "\n";); - // TENTATIVE_UNBOUNDED, UNBOUNDED, TENTATIVE_DUAL_UNBOUNDED, DUAL_UNBOUNDED, + // TENTATIVE_UNBOUNDED, UNBOUNDED, TENTATIVE_DUAL_UNBOUNDED, DUAL_UNBOUNDED, // FLOATING_POINT_ERROR, TIME_EXAUSTED, ITERATIONS_EXHAUSTED, EMPTY, UNSTABLE return l_undef; } } - + vector> m_explanation; literal_vector m_core; svector m_eqs; @@ -2188,7 +2188,7 @@ namespace smt { case equality_source: { SASSERT(m_equalities[idx].first != nullptr); SASSERT(m_equalities[idx].second != nullptr); - m_eqs.push_back(m_equalities[idx]); + m_eqs.push_back(m_equalities[idx]); break; } case definition_source: { @@ -2219,7 +2219,7 @@ namespace smt { TRACE("arith", tout << "scope: " << ctx().get_scope_level() << "\n"; display_evidence(tout, m_explanation); ); TRACE("arith", display(tout);); for (auto const& ev : m_explanation) { - if (!ev.first.is_zero()) { + if (!ev.first.is_zero()) { set_evidence(ev.second); } } @@ -2227,8 +2227,8 @@ namespace smt { ctx().set_conflict( ctx().mk_justification( ext_theory_conflict_justification( - get_id(), ctx().get_region(), - m_core.size(), m_core.c_ptr(), + get_id(), ctx().get_region(), + m_core.size(), m_core.c_ptr(), m_eqs.size(), m_eqs.c_ptr(), m_params.size(), m_params.c_ptr()))); } @@ -2261,7 +2261,7 @@ namespace smt { } bool get_value(enode* n, expr_ref& r) { - theory_var v = n->get_th_var(get_id()); + theory_var v = n->get_th_var(get_id()); if (can_get_value(v)) { r = a.mk_numeral(get_value(v), is_int(n)); return true; @@ -2269,7 +2269,7 @@ namespace smt { else { return false; } - } + } bool validate_eq_in_model(theory_var v1, theory_var v2, bool is_true) const { SASSERT(v1 != null_theory_var); @@ -2287,12 +2287,12 @@ namespace smt { add_background(nctx); bool result = l_true != nctx.check(); CTRACE("arith", !result, ctx().display_lemma_as_smt_problem(tout, m_core.size(), m_core.c_ptr(), m_eqs.size(), m_eqs.c_ptr(), false_literal); - display(tout);); + display(tout);); return result; } bool validate_assign(literal lit) { - if (dump_lemmas()) { + if (dump_lemmas()) { ctx().display_lemma_as_smt_problem(m_core.size(), m_core.c_ptr(), m_eqs.size(), m_eqs.c_ptr(), lit); } context nctx(m, ctx().get_fparams(), ctx().get_params()); @@ -2301,7 +2301,7 @@ namespace smt { m_core.pop_back(); bool result = l_true != nctx.check(); CTRACE("arith", !result, ctx().display_lemma_as_smt_problem(tout, m_core.size(), m_core.c_ptr(), m_eqs.size(), m_eqs.c_ptr(), lit); - display(tout);); + display(tout);); return result; } @@ -2321,7 +2321,7 @@ namespace smt { for (unsigned i = 0; i < m_eqs.size(); ++i) { nctx.assert_expr(m.mk_eq(m_eqs[i].first->get_owner(), m_eqs[i].second->get_owner())); } - } + } theory_lra::inf_eps value(theory_var v) { lean::impq ival = get_ivalue(v); @@ -2392,7 +2392,7 @@ namespace smt { app_ref mk_obj(theory_var v) { lean::var_index vi = m_theory_var2var_index[v]; bool is_int = a.is_int(get_enode(v)->get_owner()); - if (m_solver->is_term(vi)) { + if (m_solver->is_term(vi)) { expr_ref_vector args(m); const lean::lar_term& term = m_solver->get_term(vi); for (auto & ti : term.m_coeffs) { @@ -2440,7 +2440,7 @@ namespace smt { } TRACE("arith", tout << b << "\n";); return expr_ref(b, m); - + } @@ -2452,9 +2452,9 @@ namespace smt { unsigned nv = th.get_num_vars(); for (unsigned v = 0; v < nv; ++v) { out << "v" << v; - if (can_get_value(v)) out << ", value: " << get_value(v); - out << ", shared: " << ctx().is_shared(get_enode(v)) - << ", rel: " << ctx().is_relevant(get_enode(v)) + if (can_get_value(v)) out << ", value: " << get_value(v); + out << ", shared: " << ctx().is_shared(get_enode(v)) + << ", rel: " << ctx().is_relevant(get_enode(v)) << ", def: "; th.display_var_flat_def(out, v) << "\n"; } } @@ -2462,8 +2462,8 @@ namespace smt { void display_evidence(std::ostream& out, vector> const& evidence) { for (auto const& ev : evidence) { expr_ref e(m); - SASSERT(!ev.first.is_zero()); - if (ev.first.is_zero()) { + SASSERT(!ev.first.is_zero()); + if (ev.first.is_zero()) { continue; } unsigned idx = ev.second; @@ -2474,23 +2474,23 @@ namespace smt { out << e << " " << ctx().get_assignment(lit) << "\n"; break; } - case equality_source: - out << mk_pp(m_equalities[idx].first->get_owner(), m) << " = " - << mk_pp(m_equalities[idx].second->get_owner(), m) << "\n"; + case equality_source: + out << mk_pp(m_equalities[idx].first->get_owner(), m) << " = " + << mk_pp(m_equalities[idx].second->get_owner(), m) << "\n"; break; case definition_source: { theory_var v = m_definitions[idx]; out << "def: v" << v << " := " << mk_pp(th.get_enode(v)->get_owner(), m) << "\n"; break; } - case null_source: + case null_source: default: UNREACHABLE(); - break; + break; } } for (auto const& ev : evidence) { - m_solver->print_constraint(ev.second, out << ev.first << ": "); + m_solver->print_constraint(ev.second, out << ev.first << ": "); } } @@ -2512,16 +2512,16 @@ namespace smt { st.update("arith-make-feasible", m_stats.m_make_feasible); st.update("arith-max-columns", m_stats.m_max_cols); st.update("arith-max-rows", m_stats.m_max_rows); - } + } }; - + theory_lra::theory_lra(ast_manager& m, theory_arith_params& ap): theory(m.get_family_id("arith")) { m_imp = alloc(imp, *this, m, ap); - } + } theory_lra::~theory_lra() { dealloc(m_imp); - } + } theory* theory_lra::mk_fresh(context* new_ctx) { return alloc(theory_lra, new_ctx->get_manager(), new_ctx->get_fparams()); } diff --git a/src/util/lp/bound_analyzer_on_row.h b/src/util/lp/bound_analyzer_on_row.h index add25d389..4c6c43464 100644 --- a/src/util/lp/bound_analyzer_on_row.h +++ b/src/util/lp/bound_analyzer_on_row.h @@ -16,9 +16,9 @@ namespace lean { class bound_analyzer_on_row { - + linear_combination_iterator & m_it; - bound_propagator & m_bp; + lp_bound_propagator & m_bp; unsigned m_row_or_term_index; int m_column_of_u; // index of an unlimited from above monoid // -1 means that such a value is not found, -2 means that at least two of such monoids were found @@ -31,7 +31,7 @@ public : linear_combination_iterator &it, const numeric_pair& rs, unsigned row_or_term_index, - bound_propagator & bp + lp_bound_propagator & bp ) : m_it(it), @@ -45,7 +45,7 @@ public : unsigned j; void analyze() { - + mpq a; unsigned j; while (((m_column_of_l != -2) || (m_column_of_u != -2)) && m_it.next(a, j)) analyze_bound_on_var_on_coeff(j, a); @@ -136,7 +136,7 @@ public : strict = !is_zero(ub(j).y); return a * ub(j).x; } - + strict = !is_zero(lb(j).y); return a * lb(j).x; } @@ -145,10 +145,10 @@ public : if (is_neg(a)) { return a * ub(j).x; } - + return a * lb(j).x; } - + void limit_all_monoids_from_above() { int strict = 0; @@ -194,7 +194,7 @@ public : bool str; bool a_is_pos = is_pos(a); mpq bound = total / a + monoid_max_no_mult(a_is_pos, j, str); - bool astrict = strict - static_cast(str) > 0; + bool astrict = strict - static_cast(str) > 0; if (a_is_pos) { limit_j(j, bound, true, true, astrict); } @@ -204,7 +204,7 @@ public : } } - + void limit_monoid_u_from_below() { // we are going to limit from below the monoid m_column_of_u, // every other monoid is impossible to limit from below @@ -225,7 +225,7 @@ public : } bound /= u_coeff; - + if (numeric_traits::is_pos(u_coeff)) { limit_j(m_column_of_u, bound, true, true, strict); } else { @@ -260,7 +260,7 @@ public : limit_j(m_column_of_l, bound, false, true, strict); } } - + // // it is the coefficent before the bounded column // void provide_evidence(bool coeff_is_pos) { // /* @@ -284,27 +284,27 @@ public : m_bp.try_add_bound(u, j, is_low_bound, coeff_before_j_is_pos, m_row_or_term_index, strict); } - + void advance_u(unsigned j) { if (m_column_of_u == -1) m_column_of_u = j; else m_column_of_u = -2; } - + void advance_l(unsigned j) { if (m_column_of_l == -1) m_column_of_l = j; else m_column_of_l = -2; } - + void analyze_bound_on_var_on_coeff(int j, const mpq &a) { switch (m_bp.get_column_type(j)) { case column_type::low_bound: if (numeric_traits::is_pos(a)) advance_u(j); - else + else advance_l(j); break; case column_type::upper_bound: @@ -325,7 +325,7 @@ public : static void analyze_row(linear_combination_iterator &it, const numeric_pair& rs, unsigned row_or_term_index, - bound_propagator & bp + lp_bound_propagator & bp ) { bound_analyzer_on_row a(it, rs, row_or_term_index, bp); a.analyze(); diff --git a/src/util/lp/lar_solver.h b/src/util/lp/lar_solver.h index b74515566..7c1817c26 100644 --- a/src/util/lp/lar_solver.h +++ b/src/util/lp/lar_solver.h @@ -51,7 +51,7 @@ class lar_solver : public column_namer { vector m_terms; vector m_orig_terms; const var_index m_terms_start_index; - indexed_vector m_column_buffer; + indexed_vector m_column_buffer; public: lar_core_solver m_mpq_lar_core_solver; unsigned constraint_count() const { @@ -66,7 +66,7 @@ public: static_matrix> const & A_r() const { return m_mpq_lar_core_solver.m_r_A;} static_matrix & A_d() { return m_mpq_lar_core_solver.m_d_A;} static_matrix const & A_d() const { return m_mpq_lar_core_solver.m_d_A;} - + static bool valid_index(unsigned j){ return static_cast(j) >= 0;} @@ -84,7 +84,7 @@ public: m_terms_start_index(1000000), m_mpq_lar_core_solver(m_settings, *this) {} - + void set_propagate_bounds_on_pivoted_rows_mode(bool v) { m_mpq_lar_core_solver.m_r_solver.m_pivoted_rows = v? (& m_rows_with_changed_bounds) : nullptr; } @@ -99,7 +99,7 @@ public: } #include "util/lp/init_lar_solver.h" - + numeric_pair const& get_value(var_index vi) const { return m_mpq_lar_core_solver.m_r_x[vi]; } bool is_term(var_index j) const { @@ -113,7 +113,7 @@ public: bool use_lu() const { return m_settings.simplex_strategy() == simplex_strategy_enum::lu; } - + bool sizes_are_correct() const { lean_assert(strategy_is_undecided() || !m_mpq_lar_core_solver.need_to_presolve_with_double_solver() || A_r().column_count() == A_d().column_count()); lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_column_types.size()); @@ -121,8 +121,8 @@ public: lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_x.size()); return true; } - - + + void print_implied_bound(const implied_bound& be, std::ostream & out) const { out << "implied bound\n"; unsigned v = be.m_j; @@ -138,11 +138,11 @@ public: // out << p.first << " : "; // print_constraint(p.second, out); // } - + // m_mpq_lar_core_solver.m_r_solver.print_column_info(be.m_j< m_terms_start_index? be.m_j : adjust_term_index(be.m_j), out); out << "end of implied bound" << std::endl; } - + bool implied_bound_is_correctly_explained(implied_bound const & be, const vector> & explanation) const { std::unordered_map coeff_map; auto rs_of_evidence = zero_of_type(); @@ -164,7 +164,7 @@ public: lconstraint_kind kind = n_of_G ? GE : (n_of_L ? LE : EQ); if (strict) kind = static_cast((static_cast(kind) / 2)); - + if (!is_term(be.m_j)) { if (coeff_map.size() != 1) return false; @@ -200,13 +200,13 @@ public: return kind == be.kind() && rs_of_evidence == be.m_bound; } - + void analyze_new_bounds_on_row( unsigned row_index, - bound_propagator & bp) { + lp_bound_propagator & bp) { lean_assert(!use_tableau()); iterator_on_pivot_row it(m_mpq_lar_core_solver.get_pivot_row(), m_mpq_lar_core_solver.m_r_basis[row_index]); - + bound_analyzer_on_row ra_pos(it, zero_of_type>(), row_index, @@ -217,7 +217,7 @@ public: void analyze_new_bounds_on_row_tableau( unsigned row_index, - bound_propagator & bp + lp_bound_propagator & bp ) { if (A_r().m_rows[row_index].size() > settings().max_row_length_for_bound_propagation) @@ -231,20 +231,20 @@ public: ); } - + void substitute_basis_var_in_terms_for_row(unsigned i) { // todo : create a map from term basic vars to the rows where they are used unsigned basis_j = m_mpq_lar_core_solver.m_r_solver.m_basis[i]; for (unsigned k = 0; k < m_terms.size(); k++) { if (term_is_used_as_row(k)) continue; - if (!m_terms[k]->contains(basis_j)) + if (!m_terms[k]->contains(basis_j)) continue; m_terms[k]->subst(basis_j, m_mpq_lar_core_solver.m_r_solver.m_pivot_row); } } - - void calculate_implied_bounds_for_row(unsigned i, bound_propagator & bp) { + + void calculate_implied_bounds_for_row(unsigned i, lp_bound_propagator & bp) { if(use_tableau()) { analyze_new_bounds_on_row_tableau(i, bp); } else { @@ -269,7 +269,7 @@ public: bound_evidences.push_back(fill_bound_evidence(implied_evidence)); } } - + void fill_bound_evidence_on_term(implied_bound & ie, implied_bound& be) { lean_assert(false); } @@ -282,7 +282,7 @@ public: while (it.next(a, j)) { if (j == ie.m_j) continue; const ul_pair & ul = m_vars_to_ul_pairs[j]; - + if (is_neg(a)) { // so the monoid has a positive coeff on the right side constraint_index witness = toggle ? ul.m_low_bound_witness : ul.m_upper_bound_witness; lean_assert(is_valid(witness)); @@ -305,7 +305,7 @@ public: implied_bound fill_implied_bound_for_upper_bound(implied_bound& implied_evidence) { lean_assert(false); - + be.m_j = implied_evidence.m_j; be.m_bound = implied_evidence.m_bound.x; be.m_kind = implied_evidence.m_bound.y.is_zero() ? LE : LT; @@ -315,12 +315,12 @@ public: lean_assert(is_valid(witness)); be.m_explanation.emplace_back(t.m_coeff, witness); } - + } */ /* void process_new_implied_evidence_for_upper_bound( - implied_bound& implied_evidence, + implied_bound& implied_evidence, vector & implied_bounds, std::unordered_map & improved_upper_bounds) { unsigned existing_index; @@ -336,7 +336,7 @@ public: } */ // implied_bound * get_existing_ - + linear_combination_iterator * create_new_iter_from_term(unsigned term_index) const { lean_assert(false); // not implemented return nullptr; @@ -347,13 +347,13 @@ public: unsigned ext_var_or_term = m_columns_to_ext_vars_or_term_indices[j]; return ext_var_or_term < m_terms_start_index ? j : ext_var_or_term; } - - void propagate_bounds_on_a_term(const lar_term& t, bound_propagator & bp, unsigned term_offset) { + + void propagate_bounds_on_a_term(const lar_term& t, lp_bound_propagator & bp, unsigned term_offset) { lean_assert(false); // not implemented } - void explain_implied_bound(implied_bound & ib, bound_propagator & bp) { + void explain_implied_bound(implied_bound & ib, lp_bound_propagator & bp) { unsigned i = ib.m_row_or_term_index; int bound_sign = ib.m_is_low_bound? 1: -1; int j_sign = (ib.m_coeff_before_j_is_pos ? 1 :-1) * bound_sign; @@ -367,7 +367,7 @@ public: if (j == m_j) continue; if (is_term(j)) { j = m_ext_vars_to_columns[j]; - } + } int a_sign = is_pos(a)? 1: -1; int sign = j_sign * a_sign; const ul_pair & ul = m_vars_to_ul_pairs[j]; @@ -383,8 +383,8 @@ public: lean_assert(is_term(term)); return contains(m_ext_vars_to_columns, term); } - - void propagate_bounds_on_terms(bound_propagator & bp) { + + void propagate_bounds_on_terms(lp_bound_propagator & bp) { for (unsigned i = 0; i < m_terms.size(); i++) { if (term_is_used_as_row(i + m_terms_start_index)) continue; // this term is used a left side of a constraint, @@ -395,7 +395,7 @@ public: // goes over touched rows and tries to induce bounds - void propagate_bounds_for_touched_rows(bound_propagator & bp) { + void propagate_bounds_for_touched_rows(lp_bound_propagator & bp) { if (!use_tableau()) return; // ! todo : enable bound propagaion here. The current bug is that after the pop // the changed terms become incorrect! @@ -420,7 +420,7 @@ public: m_mpq_lar_core_solver.m_r_solver.m_look_for_feasible_solution_only = true; return solve(); } - + lp_status solve() { if (m_status == INFEASIBLE) { return m_status; @@ -430,7 +430,7 @@ public: if (m_settings.bound_propagation()) detect_rows_with_changed_bounds(); } - + m_columns_with_changed_bound.clear(); return m_status; } @@ -443,7 +443,7 @@ public: evidence.push_back(std::make_pair(-numeric_traits::one(), ul.low_bound_witness())); } - + unsigned get_total_iterations() const { return m_mpq_lar_core_solver.m_r_solver.total_iterations(); } // see http://research.microsoft.com/projects/z3/smt07.pdf // This method searches for a feasible solution with as many different values of variables, reverenced in vars, as it can find @@ -481,7 +481,7 @@ public: set.resize(n); } - + void pop(unsigned k) { int n_was = static_cast(m_ext_vars_to_columns.size()); m_status.pop(k); @@ -502,14 +502,14 @@ public: clean_inf_set_of_r_solver_after_pop(); lean_assert(m_settings.simplex_strategy() == simplex_strategy_enum::undecided || (!use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); - - + + lean_assert(ax_is_correct()); lean_assert(m_mpq_lar_core_solver.m_r_solver.inf_set_is_correct()); m_constraint_count.pop(k); for (unsigned i = m_constraint_count; i < m_constraints.size(); i++) delete m_constraints[i]; - + m_constraints.resize(m_constraint_count); m_term_count.pop(k); for (unsigned i = m_term_count; i < m_terms.size(); i++) { @@ -523,7 +523,7 @@ public: lean_assert(sizes_are_correct()); lean_assert((!m_settings.use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); } - + vector get_all_constraint_indices() const { vector ret; constraint_index i = 0; @@ -536,7 +536,7 @@ public: impq &term_max) { if (settings().simplex_strategy() == simplex_strategy_enum::undecided) decide_on_strategy_and_adjust_initial_state(); - + m_mpq_lar_core_solver.solve(); if (m_mpq_lar_core_solver.m_r_solver.get_status() == UNBOUNDED) return false; @@ -560,12 +560,12 @@ public: } return true; } - + void set_costs_to_zero(const vector> & term) { auto & rslv = m_mpq_lar_core_solver.m_r_solver; auto & jset = m_mpq_lar_core_solver.m_r_solver.m_inf_set; // hijack this set that should be empty right now lean_assert(jset.m_index.size()==0); - + for (auto & p : term) { unsigned j = p.second; rslv.m_costs[j] = zero_of_type(); @@ -582,13 +582,13 @@ public: rslv.m_d[j] = zero_of_type(); jset.clear(); - + lean_assert(reduced_costs_are_zeroes_for_r_solver()); lean_assert(costs_are_zeros_for_r_solver()); } void prepare_costs_for_r_solver(const vector> & term) { - + auto & rslv = m_mpq_lar_core_solver.m_r_solver; rslv.m_using_infeas_costs = false; lean_assert(costs_are_zeros_for_r_solver()); @@ -604,7 +604,7 @@ public: } lean_assert(rslv.reduced_costs_are_correct_tableau()); } - + bool maximize_term_on_corrected_r_solver(const vector> & term, impq &term_max) { settings().backup_costs = false; @@ -627,7 +627,7 @@ public: m_mpq_lar_core_solver.m_r_solver.set_status(OPTIMAL); return ret; } - + case simplex_strategy_enum::lu: lean_assert(false); // not implemented return false; @@ -635,7 +635,7 @@ public: lean_unreachable(); // wrong mode } return false; - } + } // starting from a given feasible state look for the maximum of the term // return true if found and false if unbounded bool maximize_term(const vector> & term, @@ -644,9 +644,9 @@ public: m_mpq_lar_core_solver.m_r_solver.m_look_for_feasible_solution_only = false; return maximize_term_on_corrected_r_solver(term, term_max); } - - + + const lar_term & get_term(unsigned j) const { lean_assert(j >= m_terms_start_index); return *m_terms[j - m_terms_start_index]; @@ -697,14 +697,14 @@ public: else m_column_buffer.clear(); lean_assert(m_column_buffer.size() == 0 && m_column_buffer.is_OK()); - + m_mpq_lar_core_solver.m_r_solver.solve_Bd(j, m_column_buffer); for (unsigned i : m_column_buffer.m_index) m_rows_with_changed_bounds.insert(i); } - + void detect_rows_of_bound_change_column_for_nbasic_column_tableau(unsigned j) { for (auto & rc : m_mpq_lar_core_solver.m_r_A.m_columns[j]) m_rows_with_changed_bounds.insert(rc.m_i); @@ -715,7 +715,7 @@ public: bool use_tableau_costs() const { return m_settings.simplex_strategy() == simplex_strategy_enum::tableau_costs; } - + void detect_rows_of_column_with_bound_change(unsigned j) { if (m_mpq_lar_core_solver.m_r_heading[j] >= 0) { // it is a basic column // just mark the row at touched and exit @@ -739,7 +739,7 @@ public: r += c.m_value * m_mpq_lar_core_solver.m_r_x[c.m_j]; return is_zero(r); } - + bool ax_is_correct() const { for (unsigned i = 0; i < A_r().row_count(); i++) { if (!row_is_correct(i)) @@ -755,7 +755,7 @@ public: bool costs_are_used() const { return m_settings.simplex_strategy() != simplex_strategy_enum::tableau_rows; } - + void change_basic_x_by_delta_on_column(unsigned j, const numeric_pair & delta) { if (use_tableau()) { for (const auto & c : A_r().m_columns[j]) { @@ -795,7 +795,7 @@ public: } } - + void detect_rows_with_changed_bounds_for_column(unsigned j) { if (m_mpq_lar_core_solver.m_r_heading[j] >= 0) { m_rows_with_changed_bounds.insert(m_mpq_lar_core_solver.m_r_heading[j]); @@ -804,10 +804,10 @@ public: if (use_tableau()) detect_rows_of_bound_change_column_for_nbasic_column_tableau(j); - else + else detect_rows_of_bound_change_column_for_nbasic_column(j); } - + void detect_rows_with_changed_bounds() { for (auto j : m_columns_with_changed_bound.m_index) detect_rows_with_changed_bounds_for_column(j); @@ -830,7 +830,7 @@ public: } } - + void solve_with_core_solver() { if (!use_tableau()) add_last_rows_to_lu(m_mpq_lar_core_solver.m_r_solver); @@ -844,34 +844,34 @@ public: } if (use_tableau()) update_x_and_inf_costs_for_columns_with_changed_bounds_tableau(); - else + else update_x_and_inf_costs_for_columns_with_changed_bounds(); m_mpq_lar_core_solver.solve(); set_status(m_mpq_lar_core_solver.m_r_solver.get_status()); lean_assert(m_status != OPTIMAL || all_constraints_hold()); } - + numeric_pair get_basic_var_value_from_row_directly(unsigned i) { numeric_pair r = zero_of_type>(); - + unsigned bj = m_mpq_lar_core_solver.m_r_solver.m_basis[i]; for (const auto & c: A_r().m_rows[i]) { if (c.m_j == bj) continue; const auto & x = m_mpq_lar_core_solver.m_r_x[c.m_j]; - if (!is_zero(x)) + if (!is_zero(x)) r -= c.m_value * x; } return r; } - - - + + + numeric_pair get_basic_var_value_from_row(unsigned i) { if (settings().use_tableau()) { return get_basic_var_value_from_row_directly(i); } - + numeric_pair r = zero_of_type>(); m_mpq_lar_core_solver.calculate_pivot_row(i); for (unsigned j : m_mpq_lar_core_solver.m_r_solver.m_pivot_row.m_index) { @@ -900,9 +900,9 @@ public: f = nullptr; } } - + } - + bool x_is_correct() const { if (m_mpq_lar_core_solver.m_r_x.size() != A_r().column_count()) { // std::cout << "the size is off " << m_r_solver.m_x.size() << ", " << A().column_count() << std::endl; @@ -921,7 +921,7 @@ public: } } return true;; - + } bool var_is_registered(var_index vj) const { @@ -938,7 +938,7 @@ public: return m_constraint_count.stack_size(); } - void fill_last_row_of_A_r(static_matrix> & A, const lar_term * ls) { + void fill_last_row_of_A_r(static_matrix> & A, const lar_term * ls) { lean_assert(A.row_count() > 0); lean_assert(A.column_count() > 0); unsigned last_row = A.row_count() - 1; @@ -995,7 +995,7 @@ public: } std::string get_column_name(unsigned j) const { - if (j >= m_terms_start_index) + if (j >= m_terms_start_index) return std::string("_t") + T_to_string(j); if (j >= m_columns_to_ext_vars_or_term_indices.size()) return std::string("_s") + T_to_string(j); @@ -1039,7 +1039,7 @@ public: return true; std::unordered_map var_map; get_model(var_map); - + for (unsigned i = 0; i < m_constraints.size(); i++) { if (!constraint_holds(*m_constraints[i], var_map)) { print_constraint(i, std::cout); @@ -1201,7 +1201,7 @@ public: return false; } } - + bool has_upper_bound(var_index var, constraint_index& ci, mpq& value, bool& is_strict) { if (var >= m_vars_to_ul_pairs.size()) { @@ -1253,7 +1253,7 @@ public: constraint_index bound_constr_i = adj_sign < 0 ? ul.upper_bound_witness() : ul.low_bound_witness(); lean_assert(bound_constr_i < m_constraints.size()); explanation.push_back(std::make_pair(coeff, bound_constr_i)); - } + } } @@ -1263,9 +1263,9 @@ public: lean_assert(m_status == OPTIMAL); unsigned i; do { - + // different pairs have to produce different singleton values - std::unordered_set set_of_different_pairs; + std::unordered_set set_of_different_pairs; std::unordered_set set_of_different_singles; delta = m_mpq_lar_core_solver.find_delta_for_strict_bounds(delta); for (i = 0; i < m_mpq_lar_core_solver.m_r_x.size(); i++ ) { @@ -1278,7 +1278,7 @@ public: delta /= mpq(2); break; } - + variable_values[i] = x; } } while (i != m_mpq_lar_core_solver.m_r_x.size()); @@ -1318,7 +1318,7 @@ public: mpq free_coeff = c->get_free_coeff_of_left_side(); if (!is_zero(free_coeff)) out << " + " << free_coeff; - + } void print_term(lar_term const& term, std::ostream & out) const { @@ -1345,7 +1345,7 @@ public: } void fill_var_set_for_random_update(unsigned sz, var_index const * vars, vector& column_list) { - for (unsigned i = 0; i < sz; i++) { + for (unsigned i = 0; i < sz; i++) { var_index var = vars[i]; if (var >= m_terms_start_index) { // handle the term for (auto & it : m_terms[var - m_terms_start_index]->m_coeffs) { @@ -1412,7 +1412,7 @@ public: if (cost_is_nz) { m_mpq_lar_core_solver.m_r_solver.m_d[rc.m_j] += cost_j*rc.get_val(); } - + A_r().remove_element(last_row, rc); } lean_assert(last_row.size() == 0); @@ -1484,7 +1484,7 @@ public: lean_assert(m_mpq_lar_core_solver.m_r_solver.m_basis.size() == A_r().row_count()); lean_assert(m_mpq_lar_core_solver.m_r_solver.basis_heading_is_correct()); - // We remove last variables starting from m_column_names.size() to m_vec_of_canonic_left_sides.size(). + // We remove last variables starting from m_column_names.size() to m_vec_of_canonic_left_sides.size(). // At this moment m_column_names is already popped for (unsigned j = A_r().column_count(); j-- > m_columns_to_ext_vars_or_term_indices.size();) remove_column_from_tableau(j); @@ -1526,8 +1526,8 @@ public: } for (unsigned j : became_feas) m_mpq_lar_core_solver.m_r_solver.m_inf_set.erase(j); - - + + if (use_tableau_costs()) { for (unsigned j : became_feas) m_mpq_lar_core_solver.m_r_solver.update_inf_cost_for_column_tableau(j); @@ -1544,6 +1544,6 @@ public: lean_assert(this->explanation_is_correct(explanation)); } - + }; } diff --git a/src/util/lp/lp_bound_propagator.cpp b/src/util/lp/lp_bound_propagator.cpp index 0d58ec2be..cbd4f28f2 100644 --- a/src/util/lp/lp_bound_propagator.cpp +++ b/src/util/lp/lp_bound_propagator.cpp @@ -4,23 +4,23 @@ */ #include "util/lp/lar_solver.h" namespace lean { -bound_propagator::bound_propagator(lar_solver & ls): + lp_bound_propagator::lp_bound_propagator(lar_solver & ls): m_lar_solver(ls) {} -column_type bound_propagator::get_column_type(unsigned j) const { +column_type lp_bound_propagator::get_column_type(unsigned j) const { return m_lar_solver.m_mpq_lar_core_solver.m_column_types()[j]; } -const impq & bound_propagator::get_low_bound(unsigned j) const { +const impq & lp_bound_propagator::get_low_bound(unsigned j) const { return m_lar_solver.m_mpq_lar_core_solver.m_r_low_bounds()[j]; } -const impq & bound_propagator::get_upper_bound(unsigned j) const { +const impq & lp_bound_propagator::get_upper_bound(unsigned j) const { return m_lar_solver.m_mpq_lar_core_solver.m_r_upper_bounds()[j]; } -void bound_propagator::try_add_bound(const mpq & v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict) { +void lp_bound_propagator::try_add_bound(const mpq & v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict) { j = m_lar_solver.adjust_column_index_to_term_index(j); lconstraint_kind kind = is_low? GE : LE; if (strict) kind = static_cast(kind / 2); - + if (!bound_is_interesting(j, kind, v)) return; unsigned k; // index to ibounds diff --git a/src/util/lp/lp_bound_propagator.h b/src/util/lp/lp_bound_propagator.h index 92523d75f..f1e0d486e 100644 --- a/src/util/lp/lp_bound_propagator.h +++ b/src/util/lp/lp_bound_propagator.h @@ -6,14 +6,14 @@ #include "util/lp/lp_settings.h" namespace lean { class lar_solver; -class bound_propagator { +class lp_bound_propagator { std::unordered_map m_improved_low_bounds; // these maps map a column index to the corresponding index in ibounds std::unordered_map m_improved_upper_bounds; lar_solver & m_lar_solver; public: vector m_ibounds; public: - bound_propagator(lar_solver & ls); + lp_bound_propagator(lar_solver & ls); column_type get_column_type(unsigned) const; const impq & get_low_bound(unsigned) const; const impq & get_upper_bound(unsigned) const; From 79ab8a5a5acf40abb93abeabd705fbff45276493 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 1 Aug 2017 16:16:17 +0100 Subject: [PATCH 075/488] Fixed cmake build --- src/util/lp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/lp/CMakeLists.txt b/src/util/lp/CMakeLists.txt index 57ebecc8d..ca8683434 100644 --- a/src/util/lp/CMakeLists.txt +++ b/src/util/lp/CMakeLists.txt @@ -3,7 +3,7 @@ z3_add_component(lp lp_utils.cpp binary_heap_priority_queue_instances.cpp binary_heap_upair_queue_instances.cpp - bound_propagator.cpp + lp_bound_propagator.cpp core_solver_pretty_printer_instances.cpp dense_matrix_instances.cpp eta_matrix_instances.cpp From bc3d8580c9bf0c28e7aa2b4b9eadac59480dd0bd Mon Sep 17 00:00:00 2001 From: Bernhard Gleiss Date: Tue, 1 Aug 2017 10:12:29 +0200 Subject: [PATCH 076/488] fixed typo in optimized unsat core plugin code --- src/muz/spacer/spacer_unsat_core_plugin.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index 66abb32c6..5383fdc12 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -330,8 +330,7 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector Date: Tue, 1 Aug 2017 11:06:17 +0200 Subject: [PATCH 077/488] refactored variable names and added comments to min_cut-related methods for unsat-core-computation --- src/muz/spacer/spacer_unsat_core_plugin.cpp | 56 ++++++++++++++++----- src/muz/spacer/spacer_unsat_core_plugin.h | 2 +- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index 5383fdc12..0d90d2653 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -588,6 +588,17 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector todo; @@ -603,21 +614,28 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector& todo2) + + void unsat_core_plugin_min_cut::advance_to_lowest_partial_cut(proof* step, ptr_vector& todo) { bool is_sink = true; ast_manager &m = m_learner.m; - ptr_vector todo; + ptr_vector todo_subproof; for (unsigned i = 0, sz = m.get_num_parents(step); i < sz; ++i) { @@ -625,16 +643,16 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vectorget_arg(i))); proof* premise = m.get_parent (current, i); - todo.push_back(premise); + todo_subproof.push_back(premise); } } } @@ -679,6 +699,12 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector cut_nodes; diff --git a/src/muz/spacer/spacer_unsat_core_plugin.h b/src/muz/spacer/spacer_unsat_core_plugin.h index 388a2bd38..743d7af4a 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.h +++ b/src/muz/spacer/spacer_unsat_core_plugin.h @@ -104,7 +104,7 @@ private: ast_mark m_visited; // saves for each node i whether the subproof with root i has already been added to the min-cut-problem obj_map m_proof_to_node_minus; // maps proof-steps to the corresponding minus-nodes (the ones which are closer to source) obj_map m_proof_to_node_plus; // maps proof-steps to the corresponding plus-nodes (the ones which are closer to sink) - void advance_to_lowest_partial_cut(proof* step, ptr_vector& todo2); + void advance_to_lowest_partial_cut(proof* step, ptr_vector& todo); void add_edge(proof* i, proof* j); vector m_node_to_formula; // maps each node to the corresponding formula in the original proof From 4ff938f2c1a0f7e629c2c44bc822ef06565169c1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 1 Aug 2017 16:46:10 +0100 Subject: [PATCH 078/488] Fixed MPF fp.rem(0,0,0). Relates to #872. --- src/util/mpf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 584e01642..7287b69cf 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -797,9 +797,9 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co set(o, z); } else if (is_zero(x) || is_zero(y)) { - bool xy_sgn = is_neg(x) ^ is_neg(y); - if (is_zero(z) && xy_sgn ^ is_neg(z)) - mk_zero(x.ebits, x.sbits, rm != MPF_ROUND_TOWARD_NEGATIVE, o); + bool xy_sgn = sgn(x) ^ sgn(y); + if (is_zero(z) && (xy_sgn ^ sgn(z))) + mk_zero(x.ebits, x.sbits, rm == MPF_ROUND_TOWARD_NEGATIVE, o); else set(o, z); } From ce01895ab397c986e812fd4f942515e7f4afc4fe Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 1 Aug 2017 16:54:27 +0100 Subject: [PATCH 079/488] Fixed ML API build. --- src/api/ml/z3native_stubs.c.pre | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/api/ml/z3native_stubs.c.pre b/src/api/ml/z3native_stubs.c.pre index 5960d5095..cbc0ffda6 100644 --- a/src/api/ml/z3native_stubs.c.pre +++ b/src/api/ml/z3native_stubs.c.pre @@ -34,6 +34,9 @@ extern "C" { CAMLlocal5(X1,X2,X3,X4,X5); \ CAMLlocal3(X6,X7,X8) +#define CAMLparam6(X1,X2,X3,X4,X5,X6,X7) \ + CAMLparam5(X1,X2,X3,X4,X5); \ + CAMLxparam1(X6) #define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \ CAMLparam5(X1,X2,X3,X4,X5); \ CAMLxparam2(X6,X7) From aefed78f1a599e1ac172332f96b70fb91db74cff Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 1 Aug 2017 17:02:04 +0100 Subject: [PATCH 080/488] Fixed ML API build again --- src/api/ml/z3native_stubs.c.pre | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3native_stubs.c.pre b/src/api/ml/z3native_stubs.c.pre index cbc0ffda6..1b1ea3fde 100644 --- a/src/api/ml/z3native_stubs.c.pre +++ b/src/api/ml/z3native_stubs.c.pre @@ -34,7 +34,7 @@ extern "C" { CAMLlocal5(X1,X2,X3,X4,X5); \ CAMLlocal3(X6,X7,X8) -#define CAMLparam6(X1,X2,X3,X4,X5,X6,X7) \ +#define CAMLparam6(X1,X2,X3,X4,X5,X6) \ CAMLparam5(X1,X2,X3,X4,X5); \ CAMLxparam1(X6) #define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \ From 81a7f37acc4013f8ee82f24a2ff3b4918ed53608 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 1 Aug 2017 18:33:40 +0100 Subject: [PATCH 081/488] Fixed LP tests --- src/test/lp.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/lp.cpp b/src/test/lp.cpp index f76850e38..695a31cf4 100644 --- a/src/test/lp.cpp +++ b/src/test/lp.cpp @@ -2779,7 +2779,7 @@ If b becomes basic variable, then it is likely the old solver ends up with a row vector ev; ls.add_var_bound(a, LE, mpq(1)); ls.solve(); - bound_propagator bp(ls); + lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); std::cout << " bound ev from test_bound_propagation_one_small_sample1" << std::endl; for (auto & be : bp.m_ibounds) { @@ -2832,7 +2832,7 @@ void test_bound_propagation_one_row() { vector ev; ls.add_var_bound(x0, LE, mpq(1)); ls.solve(); - bound_propagator bp(ls); + lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); } void test_bound_propagation_one_row_with_bounded_vars() { @@ -2848,7 +2848,7 @@ void test_bound_propagation_one_row_with_bounded_vars() { ls.add_var_bound(x0, LE, mpq(3)); ls.add_var_bound(x0, LE, mpq(1)); ls.solve(); - bound_propagator bp(ls); + lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); } void test_bound_propagation_one_row_mixed() { @@ -2862,7 +2862,7 @@ void test_bound_propagation_one_row_mixed() { vector ev; ls.add_var_bound(x1, LE, mpq(1)); ls.solve(); - bound_propagator bp(ls); + lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); } @@ -2885,7 +2885,7 @@ void test_bound_propagation_two_rows() { vector ev; ls.add_var_bound(y, LE, mpq(1)); ls.solve(); - bound_propagator bp(ls); + lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); } @@ -2905,7 +2905,7 @@ void test_total_case_u() { vector ev; ls.add_var_bound(z, GE, zero_of_type()); ls.solve(); - bound_propagator bp(ls); + lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); } bool contains_j_kind(unsigned j, lconstraint_kind kind, const mpq & rs, const vector & ev) { @@ -2932,7 +2932,7 @@ void test_total_case_l(){ vector ev; ls.add_var_bound(z, LE, zero_of_type()); ls.solve(); - bound_propagator bp(ls); + lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); lean_assert(ev.size() == 4); lean_assert(contains_j_kind(x, GE, - one_of_type(), ev)); From 2b82fd5d0cc6c275e54979a1a135a196ad782f6e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 1 Aug 2017 10:51:47 -0700 Subject: [PATCH 082/488] updated include directives Signed-off-by: Nikolaj Bjorner --- CMakeLists.txt | 6 +- scripts/update_include.py | 8 +- .../ackermannize_bv_tactic.cpp | 2 +- src/ackermannization/lackr.cpp | 2 +- src/api/api_ast.cpp | 2 +- src/api/api_model.cpp | 4 +- src/api/api_qe.cpp | 20 +- src/ast/ast_smt2_pp.cpp | 2 +- src/ast/fpa/fpa2bv_rewriter.cpp | 2 +- src/ast/normal_forms/nnf.cpp | 2 +- src/ast/pattern/pattern_inference.cpp | 2 +- src/ast/pattern/pattern_inference_params.cpp | 2 +- src/ast/pp.cpp | 2 +- src/ast/rewriter/arith_rewriter.cpp | 2 +- src/ast/rewriter/array_rewriter.cpp | 2 +- src/ast/rewriter/bool_rewriter.cpp | 2 +- src/ast/rewriter/bv_rewriter.cpp | 2 +- src/ast/rewriter/fpa_rewriter.cpp | 2 +- src/ast/rewriter/poly_rewriter_def.h | 2 +- src/ast/rewriter/th_rewriter.cpp | 2 +- .../simplifier/arith_simplifier_params.cpp | 2 +- .../simplifier/array_simplifier_params.cpp | 2 +- src/ast/simplifier/bv_simplifier_params.cpp | 4 +- src/cmd_context/basic_cmds.cpp | 2 +- src/cmd_context/cmd_context.cpp | 2 +- .../extra_cmds/polynomial_cmds.cpp | 2 +- src/cmd_context/interpolant_cmds.cpp | 2 +- src/math/polynomial/algebraic_numbers.cpp | 2 +- src/math/realclosure/realclosure.cpp | 2 +- src/model/model_evaluator.cpp | 2 +- src/muz/base/dl_context.cpp | 2 +- src/muz/bmc/dl_bmc_engine.cpp | 2 +- src/muz/duality/duality_dl_interface.cpp | 2 +- src/muz/fp/dl_cmds.cpp | 2 +- src/muz/fp/horn_tactic.cpp | 2 +- src/muz/pdr/pdr_context.h | 2 +- src/muz/spacer/spacer_context.h | 4 +- src/muz/spacer/spacer_legacy_frames.cpp | 2 +- src/muz/spacer/spacer_legacy_mev.cpp | 2 +- src/muz/spacer/spacer_mev_array.cpp | 2 +- src/muz/spacer/spacer_prop_solver.cpp | 2 +- src/muz/tab/tab_context.cpp | 2 +- src/muz/transforms/dl_mk_array_eq_rewrite.cpp | 187 ++++++++---------- src/muz/transforms/dl_mk_array_eq_rewrite.h | 12 +- .../transforms/dl_mk_array_instantiation.cpp | 14 +- .../transforms/dl_mk_array_instantiation.h | 2 +- src/muz/transforms/dl_mk_bit_blast.cpp | 2 +- .../dl_mk_interp_tail_simplifier.cpp | 2 +- .../dl_mk_quantifier_abstraction.cpp | 2 +- src/muz/transforms/dl_mk_rule_inliner.cpp | 2 +- src/muz/transforms/dl_mk_scale.cpp | 2 +- .../transforms/dl_mk_subsumption_checker.cpp | 2 +- src/muz/transforms/dl_transforms.cpp | 2 +- src/nlsat/nlsat_solver.cpp | 2 +- src/opt/maxres.cpp | 2 +- src/opt/opt_cmds.cpp | 2 +- src/opt/opt_context.cpp | 2 +- src/opt/opt_solver.cpp | 4 +- src/opt/optsmt.cpp | 2 +- src/parsers/smt/smtlib_solver.cpp | 4 +- src/parsers/smt2/smt2parser.cpp | 2 +- src/parsers/smt2/smt2scanner.cpp | 2 +- src/sat/sat_asymm_branch.cpp | 2 +- src/sat/sat_config.cpp | 2 +- src/sat/sat_scc.cpp | 2 +- src/sat/sat_simplifier.cpp | 2 +- src/shell/lp_frontend.cpp | 2 +- src/smt/params/dyn_ack_params.cpp | 2 +- src/smt/params/preprocessor_params.cpp | 2 +- src/smt/params/qi_params.cpp | 2 +- src/smt/params/smt_params.cpp | 4 +- src/smt/params/theory_arith_params.cpp | 2 +- src/smt/params/theory_array_params.cpp | 2 +- src/smt/params/theory_bv_params.cpp | 2 +- src/smt/params/theory_pb_params.cpp | 2 +- src/smt/params/theory_str_params.cpp | 2 +- src/smt/proto_model/proto_model.cpp | 2 +- src/smt/smt_kernel.cpp | 2 +- src/smt/smt_solver.cpp | 2 +- src/smt/tactic/smt_tactic.cpp | 4 +- src/smt/theory_lra.cpp | 2 +- src/solver/combined_solver.cpp | 2 +- src/tactic/bv/bv_bound_chk_tactic.cpp | 2 +- src/tactic/sls/sls_engine.cpp | 2 +- src/tactic/sls/sls_tactic.cpp | 2 +- src/tactic/sls/sls_tracker.h | 2 +- src/tactic/smtlogics/qfufbv_tactic.cpp | 4 +- 87 files changed, 209 insertions(+), 216 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3bba73ba..8845786f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,8 +257,10 @@ else() message(FATAL_ERROR "Platform \"${CMAKE_SYSTEM_NAME}\" not recognised") endif() -list(APPEND Z3_COMPONENT_EXTRA_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/src") - +list(APPEND Z3_COMPONENT_EXTRA_INCLUDE_DIRS + "${CMAKE_BINARY_DIR}/src" + "${CMAKE_SOURCE_DIR}/src" +) ################################################################################ # GNU multiple precision library support ################################################################################ diff --git a/scripts/update_include.py b/scripts/update_include.py index 555d9f094..c7a33f73f 100644 --- a/scripts/update_include.py +++ b/scripts/update_include.py @@ -8,7 +8,6 @@ is_include2 = re.compile("#include\"(.*)\"") def fix_include(file, paths): - print(file) tmp = "%s.tmp" % file ins = open(file) ous = open(tmp,'w') @@ -36,6 +35,7 @@ def fix_include(file, paths): ins.close() ous.close() if found: + print(file) os.system("move %s %s" % (tmp, file)) else: os.system("del %s" % tmp) @@ -48,6 +48,10 @@ def find_paths(dir): if f.endswith('.h'): path = "%s/%s" % (root1, f) paths[f] = path + if f.endswith('.pyg'): + f = f.replace("pyg","hpp") + path = "%s/%s" % (root1, f) + paths[f] = path return paths paths = find_paths('src') @@ -55,6 +59,8 @@ paths = find_paths('src') def fixup(dir): for root, dirs, files in os.walk(dir): for f in files: + if f == "z3.h": + continue if f.endswith('.h') or f.endswith('.cpp'): path = "%s\\%s" % (root, f) fix_include(path, paths) diff --git a/src/ackermannization/ackermannize_bv_tactic.cpp b/src/ackermannization/ackermannize_bv_tactic.cpp index 82ac50a95..82ef19274 100644 --- a/src/ackermannization/ackermannize_bv_tactic.cpp +++ b/src/ackermannization/ackermannize_bv_tactic.cpp @@ -17,7 +17,7 @@ Revision History: #include "tactic/tactical.h" #include "ackermannization/lackr.h" #include "model/model_smt2_pp.h" -#include"ackermannize_bv_tactic_params.hpp" +#include "ackermannization/ackermannize_bv_tactic_params.hpp" #include "ackermannization/ackermannize_bv_model_converter.h" diff --git a/src/ackermannization/lackr.cpp b/src/ackermannization/lackr.cpp index 76fbe0617..aac98d7dc 100644 --- a/src/ackermannization/lackr.cpp +++ b/src/ackermannization/lackr.cpp @@ -16,7 +16,7 @@ --*/ #include "ackermannization/lackr.h" -#include"ackermannization_params.hpp" +#include "ackermannization/ackermannization_params.hpp" #include "tactic/tactic.h" #include "ackermannization/lackr_model_constructor.h" #include "ackermannization/ackr_info.h" diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index 6ae10b8f9..c14a24df1 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -37,7 +37,7 @@ Revision History: #include "util/scoped_ctrl_c.h" #include "util/cancel_eh.h" #include "util/scoped_timer.h" -#include"pp_params.hpp" +#include "ast/pp_params.hpp" extern bool is_numeral_sort(Z3_context c, Z3_sort ty); diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index ccd70e79e..73428a3d7 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -25,8 +25,8 @@ Revision History: #include "model/model.h" #include "model/model_v2_pp.h" #include "model/model_smt2_pp.h" -#include"model_params.hpp" -#include"model_evaluator_params.hpp" +#include "model/model_params.hpp" +#include "model/model_evaluator_params.hpp" extern "C" { diff --git a/src/api/api_qe.cpp b/src/api/api_qe.cpp index ee49acc2a..343855a1a 100644 --- a/src/api/api_qe.cpp +++ b/src/api/api_qe.cpp @@ -18,19 +18,19 @@ Notes: --*/ #include -#include "z3.h" +#include "api/z3.h" #include "api_log_macros.h" -#include "api_context.h" -#include "api_util.h" -#include "api_model.h" -#include "api_ast_map.h" -#include "api_ast_vector.h" +#include "api/api_context.h" +#include "api/api_util.h" +#include "api/api_model.h" +#include "api/api_ast_map.h" +#include "api/api_ast_vector.h" -#include "qe_vartest.h" -#include "qe_lite.h" -#include "spacer_util.h" +#include "qe/qe_vartest.h" +#include "qe/qe_lite.h" +#include "muz/spacer/spacer_util.h" -#include "expr_map.h" +#include "ast/expr_map.h" extern "C" { diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index 89cab9de4..5c3eb93c2 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -24,7 +24,7 @@ Revision History: #include "ast/ast_ll_pp.h" #include "ast/ast_pp.h" #include "math/polynomial/algebraic_numbers.h" -#include"pp_params.hpp" +#include "ast/pp_params.hpp" using namespace format_ns; #define ALIAS_PREFIX "a" diff --git a/src/ast/fpa/fpa2bv_rewriter.cpp b/src/ast/fpa/fpa2bv_rewriter.cpp index 57cd9facc..0e3899c53 100644 --- a/src/ast/fpa/fpa2bv_rewriter.cpp +++ b/src/ast/fpa/fpa2bv_rewriter.cpp @@ -21,7 +21,7 @@ Notes: #include "ast/rewriter/rewriter_def.h" #include "ast/fpa/fpa2bv_rewriter.h" #include "util/cooperate.h" -#include"fpa2bv_rewriter_params.hpp" +#include "ast/fpa/fpa2bv_rewriter_params.hpp" fpa2bv_rewriter_cfg::fpa2bv_rewriter_cfg(ast_manager & m, fpa2bv_converter & c, params_ref const & p) : diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index cca9c2c93..247e9dea1 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -18,7 +18,7 @@ Notes: --*/ #include "ast/normal_forms/nnf.h" -#include"nnf_params.hpp" +#include "ast/normal_forms/nnf_params.hpp" #include "util/warning.h" #include "ast/used_vars.h" #include "ast/well_sorted.h" diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index d55c20c1c..c8247e409 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -576,7 +576,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings, m_candidates.reset(); } -#include "database.h" +#include "ast/pattern/database.h" void pattern_inference::reduce1_quantifier(quantifier * q) { TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";); diff --git a/src/ast/pattern/pattern_inference_params.cpp b/src/ast/pattern/pattern_inference_params.cpp index 8d978e09c..1f1118a02 100644 --- a/src/ast/pattern/pattern_inference_params.cpp +++ b/src/ast/pattern/pattern_inference_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "ast/pattern/pattern_inference_params.h" -#include"pattern_inference_params_helper.hpp" +#include "ast/pattern/pattern_inference_params_helper.hpp" void pattern_inference_params::updt_params(params_ref const & _p) { pattern_inference_params_helper p(_p); diff --git a/src/ast/pp.cpp b/src/ast/pp.cpp index 522d3eca6..39f1986ee 100644 --- a/src/ast/pp.cpp +++ b/src/ast/pp.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "ast/pp.h" -#include"pp_params.hpp" +#include "ast/pp_params.hpp" using namespace format_ns; static std::pair space_upto_line_break(ast_manager & m, format * f) { diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 4b91ad789..6d2e9dae1 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "ast/rewriter/arith_rewriter.h" -#include"arith_rewriter_params.hpp" +#include "ast/rewriter/arith_rewriter_params.hpp" #include "ast/rewriter/poly_rewriter_def.h" #include "math/polynomial/algebraic_numbers.h" #include "ast/ast_pp.h" diff --git a/src/ast/rewriter/array_rewriter.cpp b/src/ast/rewriter/array_rewriter.cpp index 85f639bc9..fb7783fe9 100644 --- a/src/ast/rewriter/array_rewriter.cpp +++ b/src/ast/rewriter/array_rewriter.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "ast/rewriter/array_rewriter.h" -#include"array_rewriter_params.hpp" +#include "ast/rewriter/array_rewriter_params.hpp" #include "ast/ast_lt.h" #include "ast/ast_pp.h" diff --git a/src/ast/rewriter/bool_rewriter.cpp b/src/ast/rewriter/bool_rewriter.cpp index 511e7607d..44fccb49e 100644 --- a/src/ast/rewriter/bool_rewriter.cpp +++ b/src/ast/rewriter/bool_rewriter.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "ast/rewriter/bool_rewriter.h" -#include"bool_rewriter_params.hpp" +#include "ast/rewriter/bool_rewriter_params.hpp" #include "ast/rewriter/rewriter_def.h" void bool_rewriter::updt_params(params_ref const & _p) { diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index d176c8008..edd601c9c 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "ast/rewriter/bv_rewriter.h" -#include"bv_rewriter_params.hpp" +#include "ast/rewriter/bv_rewriter_params.hpp" #include "ast/rewriter/poly_rewriter_def.h" #include "ast/ast_smt2_pp.h" diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index f82d6df3e..563437b99 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "ast/rewriter/fpa_rewriter.h" -#include"fpa_rewriter_params.hpp" +#include "ast/rewriter/fpa_rewriter_params.hpp" #include "ast/ast_smt2_pp.h" fpa_rewriter::fpa_rewriter(ast_manager & m, params_ref const & p) : diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 81d3aec9f..5e2e39722 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -17,7 +17,7 @@ Notes: --*/ #include "ast/rewriter/poly_rewriter.h" -#include"poly_rewriter_params.hpp" +#include "ast/rewriter/poly_rewriter_params.hpp" #include "ast/ast_lt.h" #include "ast/ast_ll_pp.h" #include "ast/ast_smt2_pp.h" diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index 240b43b30..764fa8eef 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "ast/rewriter/th_rewriter.h" -#include"rewriter_params.hpp" +#include "ast/rewriter/rewriter_params.hpp" #include "ast/rewriter/bool_rewriter.h" #include "ast/rewriter/arith_rewriter.h" #include "ast/rewriter/bv_rewriter.h" diff --git a/src/ast/simplifier/arith_simplifier_params.cpp b/src/ast/simplifier/arith_simplifier_params.cpp index efe21c43d..73bbbaa1a 100644 --- a/src/ast/simplifier/arith_simplifier_params.cpp +++ b/src/ast/simplifier/arith_simplifier_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "ast/simplifier/arith_simplifier_params.h" -#include"arith_simplifier_params_helper.hpp" +#include "ast/simplifier/arith_simplifier_params_helper.hpp" void arith_simplifier_params::updt_params(params_ref const & _p) { arith_simplifier_params_helper p(_p); diff --git a/src/ast/simplifier/array_simplifier_params.cpp b/src/ast/simplifier/array_simplifier_params.cpp index 94a858ac6..ff7dba25f 100644 --- a/src/ast/simplifier/array_simplifier_params.cpp +++ b/src/ast/simplifier/array_simplifier_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "ast/simplifier/array_simplifier_params.h" -#include"array_simplifier_params_helper.hpp" +#include "ast/simplifier/array_simplifier_params_helper.hpp" void array_simplifier_params::updt_params(params_ref const & _p) { array_simplifier_params_helper p(_p); diff --git a/src/ast/simplifier/bv_simplifier_params.cpp b/src/ast/simplifier/bv_simplifier_params.cpp index 2639b230c..4c6b4a5fa 100644 --- a/src/ast/simplifier/bv_simplifier_params.cpp +++ b/src/ast/simplifier/bv_simplifier_params.cpp @@ -17,8 +17,8 @@ Revision History: --*/ #include "ast/simplifier/bv_simplifier_params.h" -#include"bv_simplifier_params_helper.hpp" -#include"bv_rewriter_params.hpp" +#include "ast/simplifier/bv_simplifier_params_helper.hpp" +#include "ast/rewriter/bv_rewriter_params.hpp" void bv_simplifier_params::updt_params(params_ref const & _p) { bv_simplifier_params_helper p(_p); diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index ace4b6a55..8830358af 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -29,7 +29,7 @@ Notes: #include "util/gparams.h" #include "util/env_params.h" #include "ast/well_sorted.h" -#include"pp_params.hpp" +#include "ast/pp_params.hpp" class help_cmd : public cmd { svector m_cmds; diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 1c9372228..a893a1637 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -43,7 +43,7 @@ Notes: #include "cmd_context/interpolant_cmds.h" #include "model/model_smt2_pp.h" #include "model/model_v2_pp.h" -#include"model_params.hpp" +#include "model/model_params.hpp" #include "ast/rewriter/th_rewriter.h" #include "tactic/tactic_exception.h" #include "solver/smt_logics.h" diff --git a/src/cmd_context/extra_cmds/polynomial_cmds.cpp b/src/cmd_context/extra_cmds/polynomial_cmds.cpp index 33f252a64..7a748ac66 100644 --- a/src/cmd_context/extra_cmds/polynomial_cmds.cpp +++ b/src/cmd_context/extra_cmds/polynomial_cmds.cpp @@ -29,7 +29,7 @@ Notes: #include "math/polynomial/polynomial_var2value.h" #include "ast/expr2var.h" #include "ast/pp.h" -#include"pp_params.hpp" +#include "ast/pp_params.hpp" static void to_poly(cmd_context & ctx, expr * t) { polynomial::numeral_manager nm; diff --git a/src/cmd_context/interpolant_cmds.cpp b/src/cmd_context/interpolant_cmds.cpp index 65e7a17d8..b5bbea18c 100644 --- a/src/cmd_context/interpolant_cmds.cpp +++ b/src/cmd_context/interpolant_cmds.cpp @@ -31,7 +31,7 @@ #include "interp/iz3interp.h" #include "interp/iz3checker.h" #include "interp/iz3profiling.h" -#include"interp_params.hpp" +#include "interp/interp_params.hpp" #include "ast/scoped_proof.h" static void show_interpolant_and_maybe_check(cmd_context & ctx, diff --git a/src/math/polynomial/algebraic_numbers.cpp b/src/math/polynomial/algebraic_numbers.cpp index 353a8c107..22b50326b 100644 --- a/src/math/polynomial/algebraic_numbers.cpp +++ b/src/math/polynomial/algebraic_numbers.cpp @@ -25,7 +25,7 @@ Notes: #include "util/scoped_ptr_vector.h" #include "util/mpbqi.h" #include "util/timeit.h" -#include"algebraic_params.hpp" +#include "math/polynomial/algebraic_params.hpp" #include "util/common_msgs.h" namespace algebraic_numbers { diff --git a/src/math/realclosure/realclosure.cpp b/src/math/realclosure/realclosure.cpp index 93cfc98f4..8f2d933e2 100644 --- a/src/math/realclosure/realclosure.cpp +++ b/src/math/realclosure/realclosure.cpp @@ -20,7 +20,7 @@ Notes: --*/ #include "math/realclosure/realclosure.h" -#include"rcf_params.hpp" +#include "math/realclosure/rcf_params.hpp" #include "util/array.h" #include "util/mpbq.h" #include "math/realclosure/mpz_matrix.h" diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp index 5020fb98b..2b8f8abd6 100644 --- a/src/model/model_evaluator.cpp +++ b/src/model/model_evaluator.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "model/model.h" -#include"model_evaluator_params.hpp" +#include "model/model_evaluator_params.hpp" #include "ast/rewriter/rewriter_types.h" #include "model/model_evaluator.h" #include "ast/rewriter/bool_rewriter.h" diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 7be434477..97a2c841a 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -27,7 +27,7 @@ Revision History: #include "ast/ast_smt2_pp.h" #include "ast/datatype_decl_plugin.h" #include "ast/scoped_proof.h" -#include"fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" #include "ast/ast_pp_util.h" diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index fc5067355..0f7914e0c 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -33,7 +33,7 @@ Revision History: #include "muz/transforms/dl_mk_rule_inliner.h" #include "ast/scoped_proof.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/duality/duality_dl_interface.cpp b/src/muz/duality/duality_dl_interface.cpp index 30f8a7dfa..5ce4ef957 100755 --- a/src/muz/duality/duality_dl_interface.cpp +++ b/src/muz/duality/duality_dl_interface.cpp @@ -34,7 +34,7 @@ #include "ast/expr_abstract.h" #include "model/model_smt2_pp.h" #include "model/model_v2_pp.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" #include "ast/used_vars.h" #include "ast/func_decl_dependencies.h" #include "muz/transforms/dl_transforms.h" diff --git a/src/muz/fp/dl_cmds.cpp b/src/muz/fp/dl_cmds.cpp index a82737b78..42c614912 100644 --- a/src/muz/fp/dl_cmds.cpp +++ b/src/muz/fp/dl_cmds.cpp @@ -30,7 +30,7 @@ Notes: #include "util/scoped_ctrl_c.h" #include "util/scoped_timer.h" #include "util/trail.h" -#include"fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" #include diff --git a/src/muz/fp/horn_tactic.cpp b/src/muz/fp/horn_tactic.cpp index 8a9f13144..5db57a12c 100644 --- a/src/muz/fp/horn_tactic.cpp +++ b/src/muz/fp/horn_tactic.cpp @@ -27,7 +27,7 @@ Revision History: #include "muz/transforms/dl_mk_slice.h" #include "tactic/filter_model_converter.h" #include "muz/transforms/dl_transforms.h" -#include"fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" #include "ast/ast_util.h" #include "ast/rewriter/var_subst.h" diff --git a/src/muz/pdr/pdr_context.h b/src/muz/pdr/pdr_context.h index 087f77f9e..f160cff6a 100644 --- a/src/muz/pdr/pdr_context.h +++ b/src/muz/pdr/pdr_context.h @@ -28,7 +28,7 @@ Revision History: #include "muz/pdr/pdr_manager.h" #include "muz/pdr/pdr_prop_solver.h" #include "muz/pdr/pdr_reachable_cache.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/spacer/spacer_context.h b/src/muz/spacer/spacer_context.h index b6cfaff0c..cb422d08f 100644 --- a/src/muz/spacer/spacer_context.h +++ b/src/muz/spacer/spacer_context.h @@ -32,7 +32,7 @@ Notes: #include "muz/spacer/spacer_manager.h" #include "muz/spacer/spacer_prop_solver.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { class rule_set; @@ -174,7 +174,7 @@ class pred_transformer { }; /// manager of the lemmas in all the frames -#include "spacer_legacy_frames.h" +#include "muz/spacer/spacer_legacy_frames.h" class frames { private: pred_transformer &m_pt; diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp index 6c732ecc0..d3e01a585 100644 --- a/src/muz/spacer/spacer_legacy_frames.cpp +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -19,7 +19,7 @@ #include "muz/base/dl_rule_set.h" #include "smt/tactic/unit_subsumption_tactic.h" #include "model/model_smt2_pp.h" -#include "dl_mk_rule_inliner.h" +#include "muz/transforms/dl_mk_rule_inliner.h" #include "ast/ast_smt2_pp.h" #include "ast/ast_ll_pp.h" #include "ast/ast_util.h" diff --git a/src/muz/spacer/spacer_legacy_mev.cpp b/src/muz/spacer/spacer_legacy_mev.cpp index 8b53410b1..69f479836 100644 --- a/src/muz/spacer/spacer_legacy_mev.cpp +++ b/src/muz/spacer/spacer_legacy_mev.cpp @@ -22,7 +22,7 @@ Copyright (c) 2017 Arie Gurfinkel #include "muz/spacer/spacer_manager.h" #include "muz/spacer/spacer_legacy_mev.h" #include "muz/spacer/spacer_util.h" -#include "arith_decl_plugin.h" +#include "ast/arith_decl_plugin.h" #include "ast/rewriter/expr_replacer.h" #include "model/model_smt2_pp.h" #include "ast/scoped_proof.h" diff --git a/src/muz/spacer/spacer_mev_array.cpp b/src/muz/spacer/spacer_mev_array.cpp index 9e04b457e..7a4bc321b 100644 --- a/src/muz/spacer/spacer_mev_array.cpp +++ b/src/muz/spacer/spacer_mev_array.cpp @@ -15,7 +15,7 @@ Revision History: --*/ #include"model/model.h" -#include"model_evaluator_params.hpp" +#include "model/model_evaluator_params.hpp" #include"ast/rewriter/rewriter_types.h" #include"model/model_evaluator.h" #include"muz/spacer/spacer_mev_array.h" diff --git a/src/muz/spacer/spacer_prop_solver.cpp b/src/muz/spacer/spacer_prop_solver.cpp index 719443457..19c5c3aa3 100644 --- a/src/muz/spacer/spacer_prop_solver.cpp +++ b/src/muz/spacer/spacer_prop_solver.cpp @@ -35,7 +35,7 @@ Revision History: #include "muz/spacer/spacer_farkas_learner.h" #include "muz/spacer/spacer_prop_solver.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace spacer { diff --git a/src/muz/tab/tab_context.cpp b/src/muz/tab/tab_context.cpp index 8309f812e..8809c0dc7 100644 --- a/src/muz/tab/tab_context.cpp +++ b/src/muz/tab/tab_context.cpp @@ -30,7 +30,7 @@ Revision History: #include "ast/for_each_expr.h" #include "ast/substitution/matcher.h" #include "ast/scoped_proof.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" #include "ast/ast_util.h" namespace tb { diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.cpp b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp index c9caa6148..2001cb01b 100644 --- a/src/muz/transforms/dl_mk_array_eq_rewrite.cpp +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp @@ -15,126 +15,111 @@ Revision History: --*/ - -#include "dl_mk_array_eq_rewrite.h" -#include "dl_context.h" -#include "pattern_inference.h" -#include "dl_context.h" -#include "expr_safe_replace.h" -#include "expr_abstract.h" -#include"fixedpoint_params.hpp" +#include "ast/pattern/pattern_inference.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/expr_abstract.h" +#include "muz/base/dl_context.h" +#include "muz/base/dl_context.h" +#include "muz/base/fixedpoint_params.hpp" +#include "muz/transforms/dl_mk_array_eq_rewrite.h" #include "../spacer/obj_equiv_class.h" +// NSB code review: avoid dependency on spacer inside this directory. +// The python build system will rightfully complain if you include +// "muz/spacer/obj_equiv_class.h". + namespace datalog { - mk_array_eq_rewrite::mk_array_eq_rewrite( + mk_array_eq_rewrite::mk_array_eq_rewrite( context & ctx, unsigned priority): plugin(priority), m(ctx.get_manager()), m_ctx(ctx), m_a(m) - { - } - - rule_set * mk_array_eq_rewrite::operator()(rule_set const & source) - { - src_set = &source; - rule_set * result = alloc(rule_set, m_ctx); - result->inherit_predicates(source); - dst=result; - unsigned nbrules = source.get_num_rules(); - src_manager = &source.get_rule_manager(); - for(unsigned i =0;iget_counter().get_max_rule_var(r)+1; - - - expr_ref_vector new_tail(m); - unsigned nb_predicates = r.get_uninterpreted_tail_size(); - unsigned tail_size = r.get_tail_size(); - for(unsigned i=0;iinherit_predicates(source); + m_dst = result; + m_src_manager = &source.get_rule_manager(); + for (rule * rp : source) { + instantiate_rule(*rp, *result); } - } - for(spacer::expr_equiv_class::iterator it = (*c_eq).begin(); - it!=(*c_eq).end(); ++it) - { - for(unsigned i=0;imk_rule(m.mk_implies(m.mk_and(res_conjs.size(), res_conjs.c_ptr()), r.get_head()), pr, dest, r.name()); - } - expr* mk_array_eq_rewrite::replace(expr* e, expr* new_val, expr* old_val) - { - if(e==old_val) - return new_val; - else if(!is_app(e)) + void mk_array_eq_rewrite::instantiate_rule(const rule& r, rule_set & dest) { - return e; + //Reset everything + m_cnt = m_src_manager->get_counter().get_max_rule_var(r)+1; + + + expr_ref_vector new_tail(m); + unsigned nb_predicates = r.get_uninterpreted_tail_size(); + unsigned tail_size = r.get_tail_size(); + for (unsigned i = 0; i < nb_predicates; i++) { + new_tail.push_back(r.get_tail(i)); + } + + spacer::expr_equiv_class array_eq_classes(m); + for(unsigned i = nb_predicates; i < tail_size; i++) { + expr* cond = r.get_tail(i); + expr* e1, *e2; + if (m.is_eq(cond, e1, e2) && m_a.is_array(get_sort(e1))) { + array_eq_classes.merge(e1, e2); + } + else { + new_tail.push_back(cond); + } + } + + for (auto & c_eq : array_eq_classes) { + expr* representative = *(c_eq.begin()); + for (expr * v : c_eq) { + if (!is_var(v)) { + representative = v; + break; + } + } + for (expr * v : c_eq) { + for (unsigned i = 0; i < new_tail.size(); i++) + new_tail[i] = replace(new_tail[i].get(), representative, v); + } + for (expr * v : c_eq) { + new_tail.push_back(m.mk_eq(v, representative)); + } + } + params_ref select_over_store; + select_over_store.set_bool("expand_select_store", true); + th_rewriter t(m, select_over_store); + expr_ref_vector res_conjs(m); + for (expr* e : new_tail) { + expr_ref tmp(m); + t(e, tmp); + res_conjs.push_back(tmp); + } + proof_ref pr(m); + m_src_manager->mk_rule(m.mk_implies(m.mk_and(res_conjs.size(), res_conjs.c_ptr()), r.get_head()), pr, dest, r.name()); } - app*f = to_app(e); - ptr_vector n_args; - for(unsigned i=0;iget_num_args();i++) + + // NSB Code review: use substitution facility, such as expr_safe_replace or expr_replacer. + expr* mk_array_eq_rewrite::replace(expr* e, expr* new_val, expr* old_val) { - n_args.push_back(replace(f->get_arg(i), new_val, old_val)); + if (e == old_val) + return new_val; + else if (!is_app(e)) { + return e; + } + app* f = to_app(e); + ptr_vector n_args; + for (expr * arg : *f) { + n_args.push_back(replace(arg, new_val, old_val)); + } + return m.mk_app(f->get_decl(), n_args.size(), n_args.c_ptr()); } - return m.mk_app(f->get_decl(), n_args.size(), n_args.c_ptr()); - } } diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.h b/src/muz/transforms/dl_mk_array_eq_rewrite.h index 0229ff487..cfdca990f 100644 --- a/src/muz/transforms/dl_mk_array_eq_rewrite.h +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.h @@ -19,7 +19,7 @@ Revision History: #define DL_MK_ARRAY_EQ_REWRITE_H_ -#include "dl_rule_transformer.h" +#include "muz/base/dl_rule_transformer.h" #include "../spacer/obj_equiv_class.h" namespace datalog { @@ -29,13 +29,13 @@ namespace datalog { //Context objects ast_manager& m; context& m_ctx; - array_util m_a; + array_util m_a; //Rule set context - const rule_set*src_set; - rule_set*dst; - rule_manager* src_manager; - unsigned cnt;//Index for new variables + const rule_set* m_src_set; + rule_set* m_dst; + rule_manager* m_src_manager; + unsigned m_cnt;//Index for new variables expr* replace(expr* e, expr* new_val, expr* old_val); void instantiate_rule(const rule& r, rule_set & dest); diff --git a/src/muz/transforms/dl_mk_array_instantiation.cpp b/src/muz/transforms/dl_mk_array_instantiation.cpp index 762884545..9d983abd2 100644 --- a/src/muz/transforms/dl_mk_array_instantiation.cpp +++ b/src/muz/transforms/dl_mk_array_instantiation.cpp @@ -17,13 +17,13 @@ Revision History: --*/ -#include "dl_mk_array_instantiation.h" -#include "dl_context.h" -#include "pattern_inference.h" -#include "dl_context.h" -#include "expr_safe_replace.h" -#include "expr_abstract.h" -#include"fixedpoint_params.hpp" +#include "muz/transforms/dl_mk_array_instantiation.h" +#include "muz/base/dl_context.h" +#include "ast/pattern/pattern_inference.h" +#include "muz/base/dl_context.h" +#include "ast/rewriter/expr_safe_replace.h" +#include "ast/expr_abstract.h" +#include "muz/base/fixedpoint_params.hpp" #include "../spacer/obj_equiv_class.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_array_instantiation.h b/src/muz/transforms/dl_mk_array_instantiation.h index 0af57ee84..2ef9873f4 100644 --- a/src/muz/transforms/dl_mk_array_instantiation.h +++ b/src/muz/transforms/dl_mk_array_instantiation.h @@ -70,7 +70,7 @@ Revision History: #define DL_MK_ARRAY_INSTANTIATION_H_ -#include "dl_rule_transformer.h" +#include "muz/base/dl_rule_transformer.h" #include "../spacer/obj_equiv_class.h" namespace datalog { diff --git a/src/muz/transforms/dl_mk_bit_blast.cpp b/src/muz/transforms/dl_mk_bit_blast.cpp index 20baf66b6..3c8045e34 100644 --- a/src/muz/transforms/dl_mk_bit_blast.cpp +++ b/src/muz/transforms/dl_mk_bit_blast.cpp @@ -24,7 +24,7 @@ Revision History: #include "ast/rewriter/expr_safe_replace.h" #include "tactic/filter_model_converter.h" #include "muz/transforms/dl_mk_interp_tail_simplifier.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" #include "ast/scoped_proof.h" #include "model/model_v2_pp.h" diff --git a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp index 1559f4f65..30505a5e8 100644 --- a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp +++ b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp @@ -27,7 +27,7 @@ Revision History: #include "muz/transforms/dl_mk_interp_tail_simplifier.h" #include "ast/ast_util.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { // ----------------------------------- diff --git a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp index d2195a8d9..b171aaa7c 100644 --- a/src/muz/transforms/dl_mk_quantifier_abstraction.cpp +++ b/src/muz/transforms/dl_mk_quantifier_abstraction.cpp @@ -23,7 +23,7 @@ Revision History: #include "muz/base/dl_context.h" #include "ast/rewriter/expr_safe_replace.h" #include "ast/expr_abstract.h" -#include"fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_mk_rule_inliner.cpp b/src/muz/transforms/dl_mk_rule_inliner.cpp index 1c7a6b219..30ff330ab 100644 --- a/src/muz/transforms/dl_mk_rule_inliner.cpp +++ b/src/muz/transforms/dl_mk_rule_inliner.cpp @@ -52,7 +52,7 @@ Subsumption transformation (remove rule): #include "ast/rewriter/rewriter.h" #include "ast/rewriter/rewriter_def.h" #include "muz/transforms/dl_mk_rule_inliner.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_mk_scale.cpp b/src/muz/transforms/dl_mk_scale.cpp index cc6321b31..5bc10b957 100644 --- a/src/muz/transforms/dl_mk_scale.cpp +++ b/src/muz/transforms/dl_mk_scale.cpp @@ -18,7 +18,7 @@ Revision History: #include "muz/transforms/dl_mk_scale.h" #include "muz/base/dl_context.h" -#include"fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_mk_subsumption_checker.cpp b/src/muz/transforms/dl_mk_subsumption_checker.cpp index d3b959792..e26f105c6 100644 --- a/src/muz/transforms/dl_mk_subsumption_checker.cpp +++ b/src/muz/transforms/dl_mk_subsumption_checker.cpp @@ -25,7 +25,7 @@ Revision History: #include "ast/rewriter/rewriter_def.h" #include "muz/transforms/dl_mk_subsumption_checker.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { diff --git a/src/muz/transforms/dl_transforms.cpp b/src/muz/transforms/dl_transforms.cpp index b684139f6..95b0f6cd6 100644 --- a/src/muz/transforms/dl_transforms.cpp +++ b/src/muz/transforms/dl_transforms.cpp @@ -35,7 +35,7 @@ Revision History: #include "muz/transforms/dl_mk_scale.h" #include "muz/transforms/dl_mk_array_eq_rewrite.h" #include "muz/transforms/dl_mk_array_instantiation.h" -#include "fixedpoint_params.hpp" +#include "muz/base/fixedpoint_params.hpp" namespace datalog { diff --git a/src/nlsat/nlsat_solver.cpp b/src/nlsat/nlsat_solver.cpp index 2e32e2fbd..c5e9babae 100644 --- a/src/nlsat/nlsat_solver.cpp +++ b/src/nlsat/nlsat_solver.cpp @@ -31,7 +31,7 @@ Revision History: #include "util/dependency.h" #include "math/polynomial/polynomial_cache.h" #include "util/permutation.h" -#include"nlsat_params.hpp" +#include "nlsat/nlsat_params.hpp" #define NLSAT_EXTRA_VERBOSE diff --git a/src/opt/maxres.cpp b/src/opt/maxres.cpp index cbde02009..e708788f6 100644 --- a/src/opt/maxres.cpp +++ b/src/opt/maxres.cpp @@ -61,7 +61,7 @@ Notes: #include "sat/sat_solver/inc_sat_solver.h" #include "opt/opt_context.h" #include "ast/pb_decl_plugin.h" -#include "opt_params.hpp" +#include "opt/opt_params.hpp" #include "ast/ast_util.h" #include "smt/smt_solver.h" diff --git a/src/opt/opt_cmds.cpp b/src/opt/opt_cmds.cpp index d88b0a406..7ca2be4aa 100644 --- a/src/opt/opt_cmds.cpp +++ b/src/opt/opt_cmds.cpp @@ -29,7 +29,7 @@ Notes: #include "util/scoped_ctrl_c.h" #include "util/scoped_timer.h" #include "cmd_context/parametric_cmd.h" -#include "opt_params.hpp" +#include "opt/opt_params.hpp" #include "model/model_smt2_pp.h" static opt::context& get_opt(cmd_context& cmd, opt::context* opt) { diff --git a/src/opt/opt_context.cpp b/src/opt/opt_context.cpp index beba8a60b..2b31e243c 100644 --- a/src/opt/opt_context.cpp +++ b/src/opt/opt_context.cpp @@ -20,7 +20,7 @@ Notes: #include "opt/opt_context.h" #include "ast/ast_pp.h" #include "opt/opt_solver.h" -#include "opt_params.hpp" +#include "opt/opt_params.hpp" #include "ast/for_each_expr.h" #include "tactic/goal.h" #include "tactic/tactic.h" diff --git a/src/opt/opt_solver.cpp b/src/opt/opt_solver.cpp index 0c7a14065..f453d9fe2 100644 --- a/src/opt/opt_solver.cpp +++ b/src/opt/opt_solver.cpp @@ -29,8 +29,8 @@ Notes: #include "smt/theory_lra.h" #include "ast/ast_pp.h" #include "ast/ast_smt_pp.h" -#include "pp_params.hpp" -#include "opt_params.hpp" +#include "ast/pp_params.hpp" +#include "opt/opt_params.hpp" #include "model/model_smt2_pp.h" #include "util/stopwatch.h" diff --git a/src/opt/optsmt.cpp b/src/opt/optsmt.cpp index 3c8e31e59..f8f75fbfd 100644 --- a/src/opt/optsmt.cpp +++ b/src/opt/optsmt.cpp @@ -37,7 +37,7 @@ Notes: #include "ast/ast_util.h" #include "model/model_pp.h" #include "ast/rewriter/th_rewriter.h" -#include "opt_params.hpp" +#include "opt/opt_params.hpp" namespace opt { diff --git a/src/parsers/smt/smtlib_solver.cpp b/src/parsers/smt/smtlib_solver.cpp index 128b9de88..b4487cbc5 100644 --- a/src/parsers/smt/smtlib_solver.cpp +++ b/src/parsers/smt/smtlib_solver.cpp @@ -28,8 +28,8 @@ Revision History: #include "solver/solver.h" #include "tactic/portfolio/smt_strategic_solver.h" #include "cmd_context/cmd_context.h" -#include"model_params.hpp" -#include"parser_params.hpp" +#include "model/model_params.hpp" +#include "parsers/util/parser_params.hpp" namespace smtlib { diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 46c719487..b86a663a7 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -29,7 +29,7 @@ Revision History: #include "ast/rewriter/rewriter.h" #include "ast/has_free_vars.h" #include "ast/ast_smt2_pp.h" -#include"parser_params.hpp" +#include "parsers/util/parser_params.hpp" #include namespace smt2 { diff --git a/src/parsers/smt2/smt2scanner.cpp b/src/parsers/smt2/smt2scanner.cpp index b31440faf..c1cc40b2b 100644 --- a/src/parsers/smt2/smt2scanner.cpp +++ b/src/parsers/smt2/smt2scanner.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "parsers/smt2/smt2scanner.h" -#include"parser_params.hpp" +#include "parsers/util/parser_params.hpp" namespace smt2 { diff --git a/src/sat/sat_asymm_branch.cpp b/src/sat/sat_asymm_branch.cpp index 6d8fa05a0..8d5778f0b 100644 --- a/src/sat/sat_asymm_branch.cpp +++ b/src/sat/sat_asymm_branch.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "sat/sat_asymm_branch.h" -#include"sat_asymm_branch_params.hpp" +#include "sat/sat_asymm_branch_params.hpp" #include "sat/sat_solver.h" #include "util/stopwatch.h" #include "util/trace.h" diff --git a/src/sat/sat_config.cpp b/src/sat/sat_config.cpp index 00ee0f48e..9cd343bd3 100644 --- a/src/sat/sat_config.cpp +++ b/src/sat/sat_config.cpp @@ -18,7 +18,7 @@ Revision History: --*/ #include "sat/sat_config.h" #include "sat/sat_types.h" -#include"sat_params.hpp" +#include "sat/sat_params.hpp" namespace sat { diff --git a/src/sat/sat_scc.cpp b/src/sat/sat_scc.cpp index 5ab0bbd38..9682da4e8 100644 --- a/src/sat/sat_scc.cpp +++ b/src/sat/sat_scc.cpp @@ -21,7 +21,7 @@ Revision History: #include "sat/sat_elim_eqs.h" #include "util/stopwatch.h" #include "util/trace.h" -#include"sat_scc_params.hpp" +#include "sat/sat_scc_params.hpp" namespace sat { diff --git a/src/sat/sat_simplifier.cpp b/src/sat/sat_simplifier.cpp index ef74a58f4..67101b4d8 100644 --- a/src/sat/sat_simplifier.cpp +++ b/src/sat/sat_simplifier.cpp @@ -19,7 +19,7 @@ Revision History: --*/ #include "sat/sat_simplifier.h" -#include"sat_simplifier_params.hpp" +#include "sat/sat_simplifier_params.hpp" #include "sat/sat_solver.h" #include "util/stopwatch.h" #include "util/trace.h" diff --git a/src/shell/lp_frontend.cpp b/src/shell/lp_frontend.cpp index 950b4a628..61015c860 100644 --- a/src/shell/lp_frontend.cpp +++ b/src/shell/lp_frontend.cpp @@ -7,7 +7,7 @@ Author: --*/ -#include "lp_params.hpp" +#include "util/lp/lp_params.hpp" #include "util/lp/lp_settings.h" #include "util/lp/mps_reader.h" #include "util/timeout.h" diff --git a/src/smt/params/dyn_ack_params.cpp b/src/smt/params/dyn_ack_params.cpp index 1a51b45bd..4ba230a47 100644 --- a/src/smt/params/dyn_ack_params.cpp +++ b/src/smt/params/dyn_ack_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/params/dyn_ack_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void dyn_ack_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/preprocessor_params.cpp b/src/smt/params/preprocessor_params.cpp index 599400c0c..9267dbeba 100644 --- a/src/smt/params/preprocessor_params.cpp +++ b/src/smt/params/preprocessor_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/params/preprocessor_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void preprocessor_params::updt_local_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/qi_params.cpp b/src/smt/params/qi_params.cpp index 34a58c14e..a9cff6e8c 100644 --- a/src/smt/params/qi_params.cpp +++ b/src/smt/params/qi_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/params/qi_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void qi_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/smt_params.cpp b/src/smt/params/smt_params.cpp index 8a8fac952..a8eb81a2e 100644 --- a/src/smt/params/smt_params.cpp +++ b/src/smt/params/smt_params.cpp @@ -17,8 +17,8 @@ Revision History: --*/ #include "smt/params/smt_params.h" -#include"smt_params_helper.hpp" -#include"model_params.hpp" +#include "smt/params/smt_params_helper.hpp" +#include "model/model_params.hpp" #include "util/gparams.h" void smt_params::updt_local_params(params_ref const & _p) { diff --git a/src/smt/params/theory_arith_params.cpp b/src/smt/params/theory_arith_params.cpp index e6ecd50b8..2b5a14493 100644 --- a/src/smt/params/theory_arith_params.cpp +++ b/src/smt/params/theory_arith_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/params/theory_arith_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void theory_arith_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/theory_array_params.cpp b/src/smt/params/theory_array_params.cpp index a73411c7f..9a9e5aa7b 100644 --- a/src/smt/params/theory_array_params.cpp +++ b/src/smt/params/theory_array_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/params/theory_array_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void theory_array_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/theory_bv_params.cpp b/src/smt/params/theory_bv_params.cpp index 48ad07047..4b4808a1f 100644 --- a/src/smt/params/theory_bv_params.cpp +++ b/src/smt/params/theory_bv_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/params/theory_bv_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void theory_bv_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/theory_pb_params.cpp b/src/smt/params/theory_pb_params.cpp index be1cc681b..b285429d9 100644 --- a/src/smt/params/theory_pb_params.cpp +++ b/src/smt/params/theory_pb_params.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/params/theory_pb_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void theory_pb_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/params/theory_str_params.cpp b/src/smt/params/theory_str_params.cpp index 62dc881d8..afbfc33fc 100644 --- a/src/smt/params/theory_str_params.cpp +++ b/src/smt/params/theory_str_params.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include "smt/params/theory_str_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" void theory_str_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index c69fa6edc..f14034601 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "smt/proto_model/proto_model.h" -#include"model_params.hpp" +#include "model/model_params.hpp" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" #include "ast/rewriter/var_subst.h" diff --git a/src/smt/smt_kernel.cpp b/src/smt/smt_kernel.cpp index d870d9b9a..e4ce30f91 100644 --- a/src/smt/smt_kernel.cpp +++ b/src/smt/smt_kernel.cpp @@ -19,7 +19,7 @@ Revision History: #include "smt/smt_kernel.h" #include "smt/smt_context.h" #include "ast/ast_smt2_pp.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" namespace smt { diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index 1a4cc00d1..ba86f017a 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -20,7 +20,7 @@ Notes: #include "smt/smt_kernel.h" #include "ast/reg_decl_plugins.h" #include "smt/params/smt_params.h" -#include"smt_params_helper.hpp" +#include "smt/params/smt_params_helper.hpp" #include "solver/mus.h" #include "ast/for_each_expr.h" #include "ast/ast_smt2_pp.h" diff --git a/src/smt/tactic/smt_tactic.cpp b/src/smt/tactic/smt_tactic.cpp index 3328d6030..f2dc83cfe 100644 --- a/src/smt/tactic/smt_tactic.cpp +++ b/src/smt/tactic/smt_tactic.cpp @@ -20,8 +20,8 @@ Notes: #include "tactic/tactical.h" #include "smt/smt_kernel.h" #include "smt/params/smt_params.h" -#include"smt_params_helper.hpp" -#include"lp_params.hpp" +#include "smt/params/smt_params_helper.hpp" +#include "util/lp/lp_params.hpp" #include "ast/rewriter/rewriter_types.h" #include "tactic/filter_model_converter.h" #include "ast/ast_util.h" diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index e55ac16e8..124fea910 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -26,7 +26,7 @@ Revision History: #include "util/lp/lar_solver.h" #include "util/nat_set.h" #include "util/optional.h" -#include "lp_params.hpp" +#include "util/lp/lp_params.hpp" #include "util/inf_rational.h" #include "smt/smt_theory.h" #include "smt/smt_context.h" diff --git a/src/solver/combined_solver.cpp b/src/solver/combined_solver.cpp index cbe6373c2..744ac494a 100644 --- a/src/solver/combined_solver.cpp +++ b/src/solver/combined_solver.cpp @@ -20,7 +20,7 @@ Notes: --*/ #include "solver/solver.h" #include "util/scoped_timer.h" -#include"combined_solver_params.hpp" +#include "solver/combined_solver_params.hpp" #include "util/common_msgs.h" #define PS_VB_LVL 15 diff --git a/src/tactic/bv/bv_bound_chk_tactic.cpp b/src/tactic/bv/bv_bound_chk_tactic.cpp index ee7cb1ded..b71b44bd0 100644 --- a/src/tactic/bv/bv_bound_chk_tactic.cpp +++ b/src/tactic/bv/bv_bound_chk_tactic.cpp @@ -19,7 +19,7 @@ #include "ast/rewriter/rewriter.h" #include "ast/rewriter/rewriter_def.h" #include "ast/rewriter/bv_bounds.h" -#include"rewriter_params.hpp" +#include "ast/rewriter/rewriter_params.hpp" #include "ast/rewriter/bool_rewriter.h" #include "util/cooperate.h" diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index b89a05231..4e1c6a693 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -27,7 +27,7 @@ Notes: #include "util/cooperate.h" #include "util/luby.h" -#include"sls_params.hpp" +#include "tactic/sls/sls_params.hpp" #include "tactic/sls/sls_engine.h" diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 2bbef288e..19937e8b0 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -27,7 +27,7 @@ Notes: #include "tactic/core/nnf_tactic.h" #include "util/stopwatch.h" #include "tactic/sls/sls_tactic.h" -#include"sls_params.hpp" +#include "tactic/sls/sls_params.hpp" #include "tactic/sls/sls_engine.h" class sls_tactic : public tactic { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index d5ce8ee3c..651e4ef14 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -26,7 +26,7 @@ Notes: #include "ast/bv_decl_plugin.h" #include "model/model.h" -#include"sls_params.hpp" +#include "tactic/sls/sls_params.hpp" #include "tactic/sls/sls_powers.h" class sls_tracker { diff --git a/src/tactic/smtlogics/qfufbv_tactic.cpp b/src/tactic/smtlogics/qfufbv_tactic.cpp index 2e64d1e0a..e89da3631 100644 --- a/src/tactic/smtlogics/qfufbv_tactic.cpp +++ b/src/tactic/smtlogics/qfufbv_tactic.cpp @@ -27,12 +27,12 @@ Notes: #include "tactic/bv/bv_size_reduction_tactic.h" #include "tactic/core/reduce_args_tactic.h" #include "tactic/smtlogics/qfbv_tactic.h" -#include"qfufbv_tactic_params.hpp" +#include "tactic/smtlogics/qfufbv_tactic_params.hpp" /////////////// #include "model/model_smt2_pp.h" #include "util/cooperate.h" #include "ackermannization/lackr.h" -#include"ackermannization_params.hpp" +#include "ackermannization/ackermannization_params.hpp" #include "tactic/smtlogics/qfufbv_ackr_model_converter.h" /////////////// #include "sat/sat_solver/inc_sat_solver.h" From 22a2aae486a1c7e8dea0baec771d8db43a5816cd Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 1 Aug 2017 11:47:55 -0700 Subject: [PATCH 083/488] trying to fix build break on use of iterator Signed-off-by: Nikolaj Bjorner --- src/muz/transforms/dl_mk_array_eq_rewrite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.cpp b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp index 2001cb01b..85dc1eee4 100644 --- a/src/muz/transforms/dl_mk_array_eq_rewrite.cpp +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp @@ -77,7 +77,7 @@ namespace datalog { } } - for (auto & c_eq : array_eq_classes) { + for (auto c_eq : array_eq_classes) { expr* representative = *(c_eq.begin()); for (expr * v : c_eq) { if (!is_var(v)) { From be8add44e9a8c54f4ccef9b87a83021135c067a4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 1 Aug 2017 12:42:08 -0700 Subject: [PATCH 084/488] instrument unit test to use reproducible random number generator Signed-off-by: Nikolaj Bjorner --- src/test/heap.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/test/heap.cpp b/src/test/heap.cpp index 117b6abef..53b6a198e 100644 --- a/src/test/heap.cpp +++ b/src/test/heap.cpp @@ -17,6 +17,7 @@ Revision History: --*/ #include +#include "util/util.h" #include "util/heap.h" #include "util/hashtable.h" #include "util/trace.h" @@ -27,11 +28,13 @@ struct int_hash_proc { unsigned operator()(int v) const { return v * 17; }}; typedef int_hashtable > int_set; #define N 10000 +static random_gen heap_rand(1); + static void tst1() { int_heap h(N); int_set t; for (int i = 0; i < N * 3; i++) { - int val = rand() % N; + int val = heap_rand() % N; if (!h.contains(val)) { ENSURE(!t.contains(val)); h.insert(val); @@ -64,9 +67,10 @@ typedef heap int_heap2; static void init_values() { for (unsigned i = 0; i < N; i++) - g_value[i] = rand(); + g_value[i] = heap_rand(); } +#if _TRACE static void dump_heap(const int_heap2 & h, std::ostream & out) { // int_heap2::const_iterator it = h.begin(); // int_heap2::const_iterator end = h.end(); @@ -75,16 +79,16 @@ static void dump_heap(const int_heap2 & h, std::ostream & out) { // } // out << "\n"; } +#endif static void tst2() { - (void)dump_heap; int_heap2 h(N); for (int i = 0; i < N * 10; i++) { if (i % 1000 == 0) std::cout << "i: " << i << std::endl; - int cmd = rand() % 10; + int cmd = heap_rand() % 10; if (cmd <= 3) { // insert - int val = rand() % N; + int val = heap_rand() % N; if (!h.contains(val)) { TRACE("heap", tout << "inserting: " << val << "\n";); h.insert(val); @@ -93,7 +97,7 @@ static void tst2() { } } else if (cmd <= 6) { - int val = rand() % N; + int val = heap_rand() % N; if (h.contains(val)) { TRACE("heap", tout << "removing: " << val << "\n";); h.erase(val); @@ -103,9 +107,9 @@ static void tst2() { } else if (cmd <= 8) { // increased & decreased - int val = rand() % N; + int val = heap_rand() % N; int old_v = g_value[val]; - int new_v = rand(); + int new_v = heap_rand(); if (h.contains(val)) { g_value[val] = new_v; if (old_v < new_v) { @@ -128,8 +132,12 @@ static void tst2() { void tst_heap() { // enable_debug("heap"); enable_trace("heap"); - tst1(); - init_values(); - tst2(); + unsigned i = 0; + while (i < 3) { + heap_rand.set_seed(i++); + tst1(); + init_values(); + tst2(); + } } From 4d07fa5db3eb52bcadb0ab618699d2de3fb4addb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 1 Aug 2017 12:46:38 -0700 Subject: [PATCH 085/488] use ifdef instead of if for _TRACE Signed-off-by: Nikolaj Bjorner --- src/test/heap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/heap.cpp b/src/test/heap.cpp index 53b6a198e..39353af76 100644 --- a/src/test/heap.cpp +++ b/src/test/heap.cpp @@ -70,7 +70,7 @@ static void init_values() { g_value[i] = heap_rand(); } -#if _TRACE +#ifdef _TRACE static void dump_heap(const int_heap2 & h, std::ostream & out) { // int_heap2::const_iterator it = h.begin(); // int_heap2::const_iterator end = h.end(); From 88a35119b969668869b17fb015c6b5a4d7c6ef0d Mon Sep 17 00:00:00 2001 From: Arie Gurfinkel Date: Tue, 1 Aug 2017 14:17:27 -0400 Subject: [PATCH 086/488] moved obj_equiv_class to ast --- src/ast/CMakeLists.txt | 1 + src/ast/factor_equivs.cpp | 111 ++++++++++++++++++ .../obj_equiv_class.h => ast/factor_equivs.h} | 89 ++------------ src/muz/spacer/spacer_context.cpp | 3 +- src/muz/spacer/spacer_generalizers.cpp | 2 +- src/muz/spacer/spacer_legacy_frames.cpp | 2 +- src/muz/spacer/spacer_util.cpp | 2 +- src/muz/transforms/dl_mk_array_eq_rewrite.cpp | 8 +- src/muz/transforms/dl_mk_array_eq_rewrite.h | 7 +- .../transforms/dl_mk_array_instantiation.cpp | 3 +- .../transforms/dl_mk_array_instantiation.h | 4 +- src/util/trail.h | 60 +++++----- 12 files changed, 164 insertions(+), 128 deletions(-) create mode 100644 src/ast/factor_equivs.cpp rename src/{muz/spacer/obj_equiv_class.h => ast/factor_equivs.h} (66%) diff --git a/src/ast/CMakeLists.txt b/src/ast/CMakeLists.txt index de0e4bdaf..0a14d9473 100644 --- a/src/ast/CMakeLists.txt +++ b/src/ast/CMakeLists.txt @@ -23,6 +23,7 @@ z3_add_component(ast expr_map.cpp expr_stat.cpp expr_substitution.cpp + factor_equivs.cpp for_each_ast.cpp for_each_expr.cpp format.cpp diff --git a/src/ast/factor_equivs.cpp b/src/ast/factor_equivs.cpp new file mode 100644 index 000000000..853f52921 --- /dev/null +++ b/src/ast/factor_equivs.cpp @@ -0,0 +1,111 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + factor_equivs.cpp + +Abstract: + Factor equivalence classes out of an expression. + + "Equivalence class structure" for objs. Uses a union_find structure internally. + Operations are : + -Declare a new equivalence class with a single element + -Merge two equivalence classes + -Retrieve whether two elements are in the same equivalence class + -Iterate on all the elements of the equivalence class of a given element + -Iterate on all equivalence classes (and then within them) + +Author: + + Julien Braine + Arie Gurfinkel + +Revision History: + +*/ + +#include "ast/factor_equivs.h" +#include "ast/arith_decl_plugin.h" + +/** + Factors input vector v into equivalence classes and the rest + */ +void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv) { + ast_manager &m = v.get_manager(); + arith_util arith(m); + expr *e1, *e2; + + flatten_and(v); + unsigned j = 0; + for (unsigned i = 0; i < v.size(); ++i) { + if (m.is_eq(v.get(i), e1, e2)) { + if (arith.is_zero(e1)) { + expr* t; + t = e1; e1 = e2; e2 = t; + } + + // y + -1*x == 0 + if (arith.is_zero(e2) && arith.is_add(e1) && + to_app(e1)->get_num_args() == 2) { + expr *a0, *a1, *x; + + a0 = to_app(e1)->get_arg(0); + a1 = to_app(e1)->get_arg(1); + + if (arith.is_times_minus_one(a1, x)) { + e1 = a0; + e2 = x; + } + else if (arith.is_times_minus_one(a0, x)) { + e1 = a1; + e2 = x; + } + } + equiv.merge(e1, e2); + } + else { + if (j < i) {v[j] = v.get(i);} + j++; + } + } + v.shrink(j); +} + +/** + * converts equivalence classes to equalities + */ +void equiv_to_expr(expr_equiv_class &equiv, expr_ref_vector &out) { + ast_manager &m = out.get_manager(); + for (auto eq_class : equiv) { + expr *rep = nullptr; + for (expr *elem : eq_class) { + if (!m.is_value (elem)) { + rep = elem; + break; + } + } + SASSERT(rep); + for (expr *elem : eq_class) { + if (rep != elem) {out.push_back (m.mk_eq (rep, elem));} + } + } +} + +/** + * expands equivalence classes to all derivable equalities + */ +bool equiv_to_expr_full(expr_equiv_class &equiv, expr_ref_vector &out) { + ast_manager &m = out.get_manager(); + bool dirty = false; + for (auto eq_class : equiv) { + for (auto a = eq_class.begin(), end = eq_class.end(); a != end; ++a) { + expr_equiv_class::iterator b(a); + for (++b; b != end; ++b) { + out.push_back(m.mk_eq(*a, *b)); + dirty = true; + } + } + } + return dirty; +} diff --git a/src/muz/spacer/obj_equiv_class.h b/src/ast/factor_equivs.h similarity index 66% rename from src/muz/spacer/obj_equiv_class.h rename to src/ast/factor_equivs.h index 7f58efa7d..f0ce1608d 100644 --- a/src/muz/spacer/obj_equiv_class.h +++ b/src/ast/factor_equivs.h @@ -3,9 +3,11 @@ Copyright (c) 2017 Arie Gurfinkel Module Name: - obj_equiv_class.h + factor_equivs.h Abstract: + Factor equivalence classes out of an expression. + "Equivalence class structure" for objs. Uses a union_find structure internally. Operations are : -Declare a new equivalence class with a single element @@ -17,19 +19,19 @@ Abstract: Author: Julien Braine + Arie Gurfinkel Revision History: */ -#ifndef OBJ_EQUIV_CLASS_H_ -#define OBJ_EQUIV_CLASS_H_ +#ifndef FACTOR_EQUIVS_H_ +#define FACTOR_EQUIVS_H_ #include "util/union_find.h" #include "ast/ast_util.h" -namespace spacer { -//All functions naturally add their parameters to the union_find class +///All functions naturally add their parameters to the union_find class template class obj_equiv_class { basic_union_find m_uf; @@ -164,87 +166,18 @@ typedef obj_equiv_class expr_equiv_class; /** - Factors input vector v into equivalence classes and the rest + * Factors input vector v into equivalence classes and the rest */ -inline void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv) { - ast_manager &m = v.get_manager(); - arith_util arith(m); - expr *e1, *e2; - - flatten_and(v); - unsigned j = 0; - for (unsigned i = 0; i < v.size(); ++i) { - if (m.is_eq(v.get(i), e1, e2)) { - if (arith.is_zero(e1)) { - expr* t; - t = e1; e1 = e2; e2 = t; - } - - // y + -1*x == 0 - if (arith.is_zero(e2) && arith.is_add(e1) && - to_app(e1)->get_num_args() == 2) { - expr *a0, *a1, *x; - - a0 = to_app(e1)->get_arg(0); - a1 = to_app(e1)->get_arg(1); - - if (arith.is_times_minus_one(a1, x)) { - e1 = a0; - e2 = x; - } - else if (arith.is_times_minus_one(a0, x)) { - e1 = a1; - e2 = x; - } - } - equiv.merge(e1, e2); - } - else { - if (j < i) {v[j] = v.get(i);} - j++; - } - } - v.shrink(j); -} - +void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv); /** * converts equivalence classes to equalities */ -inline void equiv_to_expr(expr_equiv_class &equiv, expr_ref_vector &out) { - ast_manager &m = out.get_manager(); - for (auto eq_class : equiv) { - expr *rep = nullptr; - for (expr *elem : eq_class) { - if (!m.is_value (elem)) { - rep = elem; - break; - } - } - SASSERT(rep); - for (expr *elem : eq_class) { - if (rep != elem) {out.push_back (m.mk_eq (rep, elem));} - } - } -} +void equiv_to_expr(expr_equiv_class &equiv, expr_ref_vector &out); /** * expands equivalence classes to all derivable equalities */ -inline bool equiv_to_expr_full(expr_equiv_class &equiv, expr_ref_vector &out) { - ast_manager &m = out.get_manager(); - bool dirty = false; - for (auto eq_class : equiv) { - for (auto a = eq_class.begin(), end = eq_class.end(); a != end; ++a) { - expr_equiv_class::iterator b(a); - for (++b; b != end; ++b) { - out.push_back(m.mk_eq(*a, *b)); - dirty = true; - } - } - } - return dirty; -} +bool equiv_to_expr_full(expr_equiv_class &equiv, expr_ref_vector &out); -} #endif diff --git a/src/muz/spacer/spacer_context.cpp b/src/muz/spacer/spacer_context.cpp index 8d0a4f627..f549205c3 100644 --- a/src/muz/spacer/spacer_context.cpp +++ b/src/muz/spacer/spacer_context.cpp @@ -50,7 +50,6 @@ Notes: #include "util/luby.h" #include "ast/rewriter/expr_safe_replace.h" #include "ast/expr_abstract.h" -#include "muz/spacer/obj_equiv_class.h" namespace spacer { @@ -1123,7 +1122,7 @@ lemma::lemma(pob_ref const &p) : m_pob(p), m_new_pob(m_pob) {SASSERT(m_pob);} lemma::lemma(pob_ref const &p, expr_ref_vector &cube, unsigned lvl) : - m_ref_count(0), + m_ref_count(0), m(p->get_ast_manager()), m_body(m), m_cube(m), m_bindings(m), m_lvl(p->level()), diff --git a/src/muz/spacer/spacer_generalizers.cpp b/src/muz/spacer/spacer_generalizers.cpp index 40e5c2c4d..f16fb10e1 100644 --- a/src/muz/spacer/spacer_generalizers.cpp +++ b/src/muz/spacer/spacer_generalizers.cpp @@ -24,7 +24,7 @@ Revision History: #include "ast/expr_abstract.h" #include "ast/rewriter/var_subst.h" #include "ast/for_each_expr.h" -#include "muz/spacer/obj_equiv_class.h" +#include "ast/factor_equivs.h" namespace spacer { diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp index d3e01a585..9c302e5fd 100644 --- a/src/muz/spacer/spacer_legacy_frames.cpp +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -34,7 +34,7 @@ #include "util/luby.h" #include "ast/rewriter/expr_safe_replace.h" #include "ast/expr_abstract.h" -#include "muz/spacer/obj_equiv_class.h" +#include "ast/factor_equivs.h" namespace spacer { diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp index be6b12cd0..a277c9ed6 100644 --- a/src/muz/spacer/spacer_util.cpp +++ b/src/muz/spacer/spacer_util.cpp @@ -63,7 +63,7 @@ Notes: #include "tactic/arith/propagate_ineqs_tactic.h" #include "tactic/arith/arith_bounds_tactic.h" -#include "muz/spacer/obj_equiv_class.h" +#include "ast/factor_equivs.h" namespace spacer { diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.cpp b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp index 85dc1eee4..c33cecda9 100644 --- a/src/muz/transforms/dl_mk_array_eq_rewrite.cpp +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.cpp @@ -22,11 +22,7 @@ Revision History: #include "muz/base/dl_context.h" #include "muz/base/fixedpoint_params.hpp" #include "muz/transforms/dl_mk_array_eq_rewrite.h" -#include "../spacer/obj_equiv_class.h" - -// NSB code review: avoid dependency on spacer inside this directory. -// The python build system will rightfully complain if you include -// "muz/spacer/obj_equiv_class.h". +#include "ast/factor_equivs.h" namespace datalog { @@ -65,7 +61,7 @@ namespace datalog { new_tail.push_back(r.get_tail(i)); } - spacer::expr_equiv_class array_eq_classes(m); + expr_equiv_class array_eq_classes(m); for(unsigned i = nb_predicates; i < tail_size; i++) { expr* cond = r.get_tail(i); expr* e1, *e2; diff --git a/src/muz/transforms/dl_mk_array_eq_rewrite.h b/src/muz/transforms/dl_mk_array_eq_rewrite.h index cfdca990f..166c01142 100644 --- a/src/muz/transforms/dl_mk_array_eq_rewrite.h +++ b/src/muz/transforms/dl_mk_array_eq_rewrite.h @@ -11,16 +11,14 @@ Author: Julien Braine -Revision History: +Revision History: --*/ #ifndef DL_MK_ARRAY_EQ_REWRITE_H_ #define DL_MK_ARRAY_EQ_REWRITE_H_ - #include "muz/base/dl_rule_transformer.h" -#include "../spacer/obj_equiv_class.h" namespace datalog { @@ -30,7 +28,7 @@ namespace datalog { ast_manager& m; context& m_ctx; array_util m_a; - + //Rule set context const rule_set* m_src_set; rule_set* m_dst; @@ -51,4 +49,3 @@ namespace datalog { }; #endif /* DL_MK_ARRAY_EQ_REWRITE_H_ */ - diff --git a/src/muz/transforms/dl_mk_array_instantiation.cpp b/src/muz/transforms/dl_mk_array_instantiation.cpp index 9d983abd2..362d83865 100644 --- a/src/muz/transforms/dl_mk_array_instantiation.cpp +++ b/src/muz/transforms/dl_mk_array_instantiation.cpp @@ -24,7 +24,6 @@ Revision History: #include "ast/rewriter/expr_safe_replace.h" #include "ast/expr_abstract.h" #include "muz/base/fixedpoint_params.hpp" -#include "../spacer/obj_equiv_class.h" namespace datalog { @@ -244,7 +243,7 @@ namespace datalog { expr_ref_vector mk_array_instantiation::retrieve_all_selects(expr*array) { expr_ref_vector all_selects(m); - for(spacer::expr_equiv_class::iterator it = eq_classes.begin(array); + for(expr_equiv_class::iterator it = eq_classes.begin(array); it != eq_classes.end(array); ++it) { selects.insert_if_not_there(*it, ptr_vector()); diff --git a/src/muz/transforms/dl_mk_array_instantiation.h b/src/muz/transforms/dl_mk_array_instantiation.h index 2ef9873f4..b87f679fc 100644 --- a/src/muz/transforms/dl_mk_array_instantiation.h +++ b/src/muz/transforms/dl_mk_array_instantiation.h @@ -70,8 +70,8 @@ Revision History: #define DL_MK_ARRAY_INSTANTIATION_H_ +#include "ast/factor_equivs.h" #include "muz/base/dl_rule_transformer.h" -#include "../spacer/obj_equiv_class.h" namespace datalog { @@ -89,7 +89,7 @@ namespace datalog { //Rule context obj_map > selects; - spacer::expr_equiv_class eq_classes; + expr_equiv_class eq_classes; unsigned cnt;//Index for new variables obj_map done_selects; expr_ref_vector ownership; diff --git a/src/util/trail.h b/src/util/trail.h index 1b8f36206..bba71fb00 100644 --- a/src/util/trail.h +++ b/src/util/trail.h @@ -22,6 +22,7 @@ Revision History: #include "util/obj_hashtable.h" #include "util/region.h" #include "util/obj_ref.h" +#include "util/vector.h" template class trail { @@ -35,16 +36,16 @@ template class value_trail : public trail { T & m_value; T m_old_value; - + public: value_trail(T & value): m_value(value), m_old_value(value) { } - + virtual ~value_trail() { } - + virtual void undo(Ctx & ctx) { m_value = m_old_value; } @@ -57,10 +58,10 @@ public: reset_flag_trail(bool & value): m_value(value) { } - + virtual ~reset_flag_trail() { } - + virtual void undo(Ctx & ctx) { m_value = false; } @@ -74,7 +75,7 @@ public: m_ptr(ptr) { SASSERT(m_ptr == 0); } - + virtual void undo(Ctx & ctx) { m_ptr = 0; } @@ -98,8 +99,8 @@ public: virtual void undo(Ctx & ctx) { m_vector.shrink(m_old_size); } -}; - +}; + template class vector_value_trail : public trail { vector & m_vector; @@ -111,10 +112,10 @@ public: m_idx(idx), m_old_value(v[idx]) { } - + virtual ~vector_value_trail() { } - + virtual void undo(Ctx & ctx) { m_vector[m_idx] = m_old_value; } @@ -150,7 +151,7 @@ public: push_back_vector(V & v): m_vector(v) { } - + virtual void undo(Ctx & ctx) { m_vector.pop_back(); } @@ -165,15 +166,15 @@ public: m_vector(v), m_idx(idx) { } - + virtual ~set_vector_idx_trail() { } - + virtual void undo(Ctx & ctx) { m_vector[m_idx] = 0; } }; - + template class pop_back_trail : public trail { vector & m_vector; @@ -183,7 +184,7 @@ public: m_vector(v), m_value(m_vector.back()) { } - + virtual void undo(Ctx & ctx) { m_vector.push_back(m_value); } @@ -201,7 +202,7 @@ public: m_index(index), m_value(m_vector[index].back()) { } - + virtual void undo(Ctx & ctx) { m_vector[m_index].push_back(m_value); } @@ -216,7 +217,7 @@ public: push_back_trail(vector & v): m_vector(v) { } - + virtual void undo(Ctx & ctx) { m_vector.pop_back(); } @@ -228,11 +229,11 @@ class push_back2_trail : public trail { vector_t & m_vector; unsigned m_index; public: - push_back2_trail(vector_t & v, unsigned index) : + push_back2_trail(vector_t & v, unsigned index) : m_vector(v), m_index(index) { } - + virtual void undo(Ctx & ctx) { m_vector[m_index].pop_back(); } @@ -249,12 +250,12 @@ public: SASSERT(m_vector[m_idx] == false); m_vector[m_idx] = true; } - + virtual void undo(Ctx & ctx) { m_vector[m_idx] = false; } }; - + template class new_obj_trail : public trail { T * m_obj; @@ -262,7 +263,7 @@ public: new_obj_trail(T * obj): m_obj(obj) { } - + virtual void undo(Ctx & ctx) { dealloc(m_obj); } @@ -275,7 +276,7 @@ public: obj_ref_trail(obj_ref& obj): m_obj(obj) { } - + virtual void undo(Ctx & ctx) { m_obj.reset(); } @@ -300,7 +301,7 @@ class remove_obj_trail : public trail { public: remove_obj_trail(obj_hashtable& t, T* o) : m_table(t), m_obj(o) {} virtual ~remove_obj_trail() {} - virtual void undo(Ctx & ctx) { m_table.insert(m_obj); } + virtual void undo(Ctx & ctx) { m_table.insert(m_obj); } }; @@ -326,13 +327,13 @@ public: trail_stack(Ctx & c):m_ctx(c) {} ~trail_stack() {} - + region & get_region() { return m_region; } - - void reset() { - pop_scope(m_scopes.size()); + + void reset() { + pop_scope(m_scopes.size()); // Undo trail objects stored at lvl 0 (avoid memory leaks if lvl 0 contains new_obj_trail objects). - undo_trail_stack(m_ctx, m_trail_stack, 0); + undo_trail_stack(m_ctx, m_trail_stack, 0); } void push_ptr(trail * t) { m_trail_stack.push_back(t); } @@ -357,4 +358,3 @@ public: }; #endif /* TRAIL_H_ */ - From ce3fd22f3b9a55e8a18fb2794138c5dcd953899e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 1 Aug 2017 21:07:20 -0700 Subject: [PATCH 087/488] use common idioms for factor-equivalence code Signed-off-by: Nikolaj Bjorner --- src/ast/factor_equivs.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/ast/factor_equivs.cpp b/src/ast/factor_equivs.cpp index 853f52921..bbb21c1b2 100644 --- a/src/ast/factor_equivs.cpp +++ b/src/ast/factor_equivs.cpp @@ -34,25 +34,19 @@ Revision History: void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv) { ast_manager &m = v.get_manager(); arith_util arith(m); - expr *e1, *e2; + expr *e1 = 0, *e2 = 0; flatten_and(v); unsigned j = 0; for (unsigned i = 0; i < v.size(); ++i) { if (m.is_eq(v.get(i), e1, e2)) { if (arith.is_zero(e1)) { - expr* t; - t = e1; e1 = e2; e2 = t; + std::swap(e1, e2); } // y + -1*x == 0 - if (arith.is_zero(e2) && arith.is_add(e1) && - to_app(e1)->get_num_args() == 2) { - expr *a0, *a1, *x; - - a0 = to_app(e1)->get_arg(0); - a1 = to_app(e1)->get_arg(1); - + expr* a0 = 0, *a1 = 0, *x = 0; + if (arith.is_zero(e2) && arith.is_add(e1, a0, a1)) { if (arith.is_times_minus_one(a1, x)) { e1 = a0; e2 = x; @@ -65,7 +59,9 @@ void factor_eqs(expr_ref_vector &v, expr_equiv_class &equiv) { equiv.merge(e1, e2); } else { - if (j < i) {v[j] = v.get(i);} + if (j < i) { + v[j] = v.get(i); + } j++; } } @@ -80,14 +76,16 @@ void equiv_to_expr(expr_equiv_class &equiv, expr_ref_vector &out) { for (auto eq_class : equiv) { expr *rep = nullptr; for (expr *elem : eq_class) { - if (!m.is_value (elem)) { + if (!m.is_value(elem)) { rep = elem; break; } } SASSERT(rep); for (expr *elem : eq_class) { - if (rep != elem) {out.push_back (m.mk_eq (rep, elem));} + if (rep != elem) { + out.push_back (m.mk_eq (rep, elem)); + } } } } From c2f69ae9fbdcad143557309dd021aa7cafb21d36 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 2 Aug 2017 11:58:47 +0100 Subject: [PATCH 088/488] [TravisCI] Try to make the LTO build more reliable. TravisCI kills builds that don't show output for over 10 minutes [1]. This sometimes causes LTO builds to fail because gcc shows no output during linking which can take many minutes to complete. To workaround this we use the `travis_wait` command to allow at most 45 minutes for the build to run. This command will force output to appear at regular intervals. The change is made in the top-level `.travis.yml` file rather than the other scripts because I don't want to pollute them with TravisCI specific details. [1] https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e8e207466..b179c5bfe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,4 +65,7 @@ env: # - os: osx # osx_image: xcode 8.2 script: - - contrib/ci/scripts/travis_ci_entry_point.sh + # Use `travis_wait` to handle commands that don't show output for a long period of time. + # Currently this is the LTO build which can be very slow. + # Allow at most 45 minutes for the build. + - travis_wait 45 contrib/ci/scripts/travis_ci_entry_point.sh From 4b3251dec1064a607423d9b763e9e717a94c987a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 2 Aug 2017 16:56:43 -0700 Subject: [PATCH 089/488] update API functions Signed-off-by: Nikolaj Bjorner --- src/api/api_qe.cpp | 244 ++++++++++++++++++++++----------------------- 1 file changed, 119 insertions(+), 125 deletions(-) diff --git a/src/api/api_qe.cpp b/src/api/api_qe.cpp index 343855a1a..0c2948ce5 100644 --- a/src/api/api_qe.cpp +++ b/src/api/api_qe.cpp @@ -25,155 +25,149 @@ Notes: #include "api/api_model.h" #include "api/api_ast_map.h" #include "api/api_ast_vector.h" - #include "qe/qe_vartest.h" #include "qe/qe_lite.h" #include "muz/spacer/spacer_util.h" - #include "ast/expr_map.h" extern "C" { - Z3_ast Z3_API Z3_qe_model_project (Z3_context c, - Z3_model m, - unsigned num_bounds, - Z3_app const bound[], - Z3_ast body) - { - Z3_TRY; - LOG_Z3_qe_model_project (c, m, num_bounds, bound, body); - RESET_ERROR_CODE(); - app_ref_vector vars(mk_c(c)->m ()); - for (unsigned i = 0; i < num_bounds; ++i) - { - app *a = to_app (bound [i]); - if (a->get_kind () != AST_APP) - { - SET_ERROR_CODE (Z3_INVALID_ARG); - RETURN_Z3(0); - } - vars.push_back (a); + static bool to_apps(unsigned n, Z3_app const es[], app_ref_vector& result) { + for (unsigned i = 0; i < n; ++i) { + if (!is_app(to_app(es[i]))) { + return false; + } + result.push_back (to_app (es [i])); + } + return true; } - expr_ref result (mk_c(c)->m ()); - result = to_expr (body); - model_ref model (to_model_ref (m)); - spacer::qe_project (mk_c(c)->m (), vars, result, model); - mk_c(c)->save_ast_trail (result.get ()); - - return of_expr (result.get ()); - Z3_CATCH_RETURN(0); - } - - Z3_ast Z3_API Z3_qe_model_project_skolem (Z3_context c, + Z3_ast Z3_API Z3_qe_model_project (Z3_context c, Z3_model m, unsigned num_bounds, Z3_app const bound[], - Z3_ast body, - Z3_ast_map map) + Z3_ast body) { - Z3_TRY; - LOG_Z3_qe_model_project_skolem (c, m, num_bounds, bound, body, map); - RESET_ERROR_CODE(); - - ast_manager& man = mk_c(c)->m (); - app_ref_vector vars(man); - for (unsigned i = 0; i < num_bounds; ++i) - { - app *a = to_app (bound [i]); - if (a->get_kind () != AST_APP) - { - SET_ERROR_CODE (Z3_INVALID_ARG); - RETURN_Z3(0); + Z3_TRY; + LOG_Z3_qe_model_project (c, m, num_bounds, bound, body); + RESET_ERROR_CODE(); + + app_ref_vector vars(mk_c(c)->m ()); + if (!to_apps(num_bounds, bound, vars)) { + SET_ERROR_CODE (Z3_INVALID_ARG); + RETURN_Z3(0); } - vars.push_back (a); - } - expr_ref result (mk_c(c)->m ()); - result = to_expr (body); - model_ref model (to_model_ref (m)); - expr_map emap (man); + expr_ref result (mk_c(c)->m ()); + result = to_expr (body); + model_ref model (to_model_ref (m)); + spacer::qe_project (mk_c(c)->m (), vars, result, model); + mk_c(c)->save_ast_trail (result.get ()); - spacer::qe_project (mk_c(c)->m (), vars, result, model, emap); - mk_c(c)->save_ast_trail (result.get ()); - - obj_map &map_z3 = to_ast_map_ref(map); - - for (expr_map::iterator it = emap.begin(), end = emap.end(); it != end; ++it){ - man.inc_ref(&(it->get_key())); - man.inc_ref(it->get_value()); - map_z3.insert(&(it->get_key()), it->get_value()); - } - - return of_expr (result.get ()); - Z3_CATCH_RETURN(0); + return of_expr (result.get ()); + Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_model_extrapolate (Z3_context c, - Z3_model m, - Z3_ast fml) - { - Z3_TRY; - LOG_Z3_model_extrapolate (c, m, fml); - RESET_ERROR_CODE(); - - model_ref model (to_model_ref (m)); - expr_ref_vector facts (mk_c(c)->m ()); - facts.push_back (to_expr (fml)); - flatten_and (facts); - - spacer::model_evaluator_util mev (mk_c(c)->m()); - mev.set_model (*model); - - expr_ref_vector lits (mk_c(c)->m()); - spacer::compute_implicant_literals (mev, facts, lits); - - expr_ref result (mk_c(c)->m ()); - result = mk_and (lits); - mk_c(c)->save_ast_trail (result.get ()); - - return of_expr (result.get ()); - Z3_CATCH_RETURN(0); - } - - Z3_ast Z3_API Z3_qe_lite (Z3_context c, Z3_ast_vector vars, Z3_ast body) - { - Z3_TRY; - LOG_Z3_qe_lite (c, vars, body); - RESET_ERROR_CODE(); - ast_ref_vector &vVars = to_ast_vector_ref (vars); - - app_ref_vector vApps (mk_c(c)->m()); - for (unsigned i = 0; i < vVars.size (); ++i) + Z3_ast Z3_API Z3_qe_model_project_skolem (Z3_context c, + Z3_model m, + unsigned num_bounds, + Z3_app const bound[], + Z3_ast body, + Z3_ast_map map) { - app *a = to_app (vVars.get (i)); - if (a->get_kind () != AST_APP) - { - SET_ERROR_CODE (Z3_INVALID_ARG); - RETURN_Z3(0); - } - vApps.push_back (a); + Z3_TRY; + LOG_Z3_qe_model_project_skolem (c, m, num_bounds, bound, body, map); + RESET_ERROR_CODE(); + + ast_manager& man = mk_c(c)->m (); + app_ref_vector vars(man); + if (!to_apps(num_bounds, bound, vars)) { + RETURN_Z3(0); + } + + expr_ref result (mk_c(c)->m ()); + result = to_expr (body); + model_ref model (to_model_ref (m)); + expr_map emap (man); + + spacer::qe_project (mk_c(c)->m (), vars, result, model, emap); + mk_c(c)->save_ast_trail (result.get ()); + + obj_map &map_z3 = to_ast_map_ref(map); + + for (expr_map::iterator it = emap.begin(), end = emap.end(); it != end; ++it){ + man.inc_ref(&(it->get_key())); + man.inc_ref(it->get_value()); + map_z3.insert(&(it->get_key()), it->get_value()); + } + + return of_expr (result.get ()); + Z3_CATCH_RETURN(0); } - expr_ref result (mk_c(c)->m ()); - result = to_expr (body); - - params_ref p; - qe_lite qe (mk_c(c)->m (), p); - qe (vApps, result); - - // -- copy back variables that were not eliminated - if (vApps.size () < vVars.size ()) + Z3_ast Z3_API Z3_model_extrapolate (Z3_context c, + Z3_model m, + Z3_ast fml) { - vVars.reset (); - for (unsigned i = 0; i < vApps.size (); ++i) - vVars.push_back (vApps.get (i)); + Z3_TRY; + LOG_Z3_model_extrapolate (c, m, fml); + RESET_ERROR_CODE(); + + model_ref model (to_model_ref (m)); + expr_ref_vector facts (mk_c(c)->m ()); + facts.push_back (to_expr (fml)); + flatten_and (facts); + + spacer::model_evaluator_util mev (mk_c(c)->m()); + mev.set_model (*model); + + expr_ref_vector lits (mk_c(c)->m()); + spacer::compute_implicant_literals (mev, facts, lits); + + expr_ref result (mk_c(c)->m ()); + result = mk_and (lits); + mk_c(c)->save_ast_trail (result.get ()); + + return of_expr (result.get ()); + Z3_CATCH_RETURN(0); } - mk_c(c)->save_ast_trail (result.get ()); - return of_expr (result); - Z3_CATCH_RETURN(0); - } + Z3_ast Z3_API Z3_qe_lite (Z3_context c, Z3_ast_vector vars, Z3_ast body) + { + Z3_TRY; + LOG_Z3_qe_lite (c, vars, body); + RESET_ERROR_CODE(); + ast_ref_vector &vVars = to_ast_vector_ref (vars); + + app_ref_vector vApps (mk_c(c)->m()); + for (unsigned i = 0; i < vVars.size (); ++i) { + app *a = to_app (vVars.get (i)); + if (a->get_kind () != AST_APP) { + SET_ERROR_CODE (Z3_INVALID_ARG); + RETURN_Z3(0); + } + vApps.push_back (a); + } + + expr_ref result (mk_c(c)->m ()); + result = to_expr (body); + + params_ref p; + qe_lite qe (mk_c(c)->m (), p); + qe (vApps, result); + + // -- copy back variables that were not eliminated + if (vApps.size () < vVars.size ()) { + vVars.reset (); + for (app* v : vApps) { + vVars.push_back (v); + } + } + + mk_c(c)->save_ast_trail (result.get ()); + return of_expr (result); + Z3_CATCH_RETURN(0); + } } From 8844112418936f62495e3fb641d1521894a345ff Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 3 Aug 2017 08:50:04 -0700 Subject: [PATCH 090/488] update header include generation to use relative paths #534 Signed-off-by: Nikolaj Bjorner --- scripts/mk_genfile_common.py | 36 ++++++++++++++++++++++-------------- scripts/update_include.py | 2 +- src/ast/ast.cpp | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/scripts/mk_genfile_common.py b/scripts/mk_genfile_common.py index 21771cc04..678bc93c7 100644 --- a/scripts/mk_genfile_common.py +++ b/scripts/mk_genfile_common.py @@ -587,6 +587,14 @@ def mk_def_file_internal(defname, dll_name, export_header_files): ############################################################################### # Functions for generating ``gparams_register_modules.cpp`` ############################################################################### + +def path_after_src(h_file): + h_file = h_file.replace("\\","/") + idx = h_file.index("src/") + if idx == -1: + return h_file + return h_file[idx + 4:] + def mk_gparams_register_modules_internal(h_files_full_path, path): """ Generate a ``gparams_register_modules.cpp`` file in the directory ``path``. @@ -608,7 +616,7 @@ def mk_gparams_register_modules_internal(h_files_full_path, path): fullname = os.path.join(path, 'gparams_register_modules.cpp') fout = open(fullname, 'w') fout.write('// Automatically generated file.\n') - fout.write('#include"gparams.h"\n') + fout.write('#include "util/gparams.h"\n') reg_pat = re.compile('[ \t]*REG_PARAMS\(\'([^\']*)\'\)') reg_mod_pat = re.compile('[ \t]*REG_MODULE_PARAMS\(\'([^\']*)\', *\'([^\']*)\'\)') reg_mod_descr_pat = re.compile('[ \t]*REG_MODULE_DESCRIPTION\(\'([^\']*)\', *\'([^\']*)\'\)') @@ -620,13 +628,13 @@ def mk_gparams_register_modules_internal(h_files_full_path, path): if m: if not added_include: added_include = True - fout.write('#include"%s"\n' % os.path.basename(h_file)) + fout.write('#include "%s"\n' % path_after_src(h_file)) cmds.append((m.group(1))) m = reg_mod_pat.match(line) if m: if not added_include: added_include = True - fout.write('#include"%s"\n' % os.path.basename(h_file)) + fout.write('#include "%s"\n' % path_after_src(h_file)) mod_cmds.append((m.group(1), m.group(2))) m = reg_mod_descr_pat.match(line) if m: @@ -680,9 +688,9 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path): fullname = os.path.join(path, 'install_tactic.cpp') fout = open(fullname, 'w') fout.write('// Automatically generated file.\n') - fout.write('#include"tactic.h"\n') - fout.write('#include"tactic_cmds.h"\n') - fout.write('#include"cmd_context.h"\n') + fout.write('#include "tactic/tactic.h"\n') + fout.write('#include "cmd_context/tactic_cmds.h"\n') + fout.write('#include "cmd_context/cmd_context.h"\n') tactic_pat = re.compile('[ \t]*ADD_TACTIC\(.*\)') probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)') for h_file in sorted_headers_by_component(h_files_full_path): @@ -691,8 +699,8 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path): for line in fin: if tactic_pat.match(line): if not added_include: - added_include = True - fout.write('#include"%s"\n' % os.path.basename(h_file)) + added_include = True + fout.write('#include "%s"\n' % path_after_src(h_file)) try: eval(line.strip('\n '), eval_globals, None) except Exception as e: @@ -702,7 +710,7 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path): if probe_pat.match(line): if not added_include: added_include = True - fout.write('#include"%s"\n' % os.path.basename(h_file)) + fout.write('#include "%s"\n' % path_after_src(h_file)) try: eval(line.strip('\n '), eval_globals, None) except Exception as e: @@ -764,19 +772,19 @@ def mk_mem_initializer_cpp_internal(h_files_full_path, path): if m: if not added_include: added_include = True - fout.write('#include"%s"\n' % os.path.basename(h_file)) + fout.write('#include "%s"\n' % path_after_src(h_file)) initializer_cmds.append((m.group(1), 0)) m = initializer_prio_pat.match(line) if m: if not added_include: added_include = True - fout.write('#include"%s"\n' % os.path.basename(h_file)) + fout.write('#include "%s"\n' % path_after_src(h_file)) initializer_cmds.append((m.group(1), int(m.group(2)))) m = finalizer_pat.match(line) if m: if not added_include: added_include = True - fout.write('#include"%s"\n' % os.path.basename(h_file)) + fout.write('#include "%s"\n' % path_after_src(h_file)) finalizer_cmds.append(m.group(1)) initializer_cmds.sort(key=lambda tup: tup[1]) fout.write('void mem_initialize() {\n') @@ -881,9 +889,9 @@ def mk_hpp_from_pyg(pyg_file, output_dir): out.write('// Automatically generated file\n') out.write('#ifndef __%s_HPP_\n' % class_name.upper()) out.write('#define __%s_HPP_\n' % class_name.upper()) - out.write('#include"params.h"\n') + out.write('#include "util/params.h"\n') if export: - out.write('#include"gparams.h"\n') + out.write('#include "util/gparams.h"\n') out.write('struct %s {\n' % class_name) out.write(' params_ref const & p;\n') if export: diff --git a/scripts/update_include.py b/scripts/update_include.py index c7a33f73f..15e510041 100644 --- a/scripts/update_include.py +++ b/scripts/update_include.py @@ -45,7 +45,7 @@ def find_paths(dir): for root, dirs, files in os.walk(dir): root1 = root.replace("\\","/")[4:] for f in files: - if f.endswith('.h'): + if f.endswith('.h') or f.endswith('.hpp') or f.endswith('.cpp'): path = "%s/%s" % (root1, f) paths[f] = path if f.endswith('.pyg'): diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 88055d73b..a1efed19e 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -2210,7 +2210,7 @@ app * ast_manager::mk_app(func_decl * decl, unsigned num_args, expr * const * ar r = mk_app_core(decl, num_args, args); } SASSERT(r != 0); - TRACE("app_ground", tout << "ground: " << r->is_ground() << "\n" << mk_ll_pp(r, *this) << "\n";); + TRACE("app_ground", tout << "ground: " << r->is_ground() << " id: " << r->get_id() << "\n" << mk_ll_pp(r, *this) << "\n";); return r; } From 712619a9cf902a40e77800b2091e5249515fedef Mon Sep 17 00:00:00 2001 From: Lev Nachmanson Date: Thu, 3 Aug 2017 10:09:00 -0700 Subject: [PATCH 091/488] fix a but in adjusting term indices for implied_bounds --- src/util/lp/column_namer.h | 2 +- src/util/lp/lar_solver.h | 2 -- src/util/lp/lp_bound_propagator.cpp | 21 +++++++++++++-------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/util/lp/column_namer.h b/src/util/lp/column_namer.h index 1a10a5a23..a3fe05dd0 100644 --- a/src/util/lp/column_namer.h +++ b/src/util/lp/column_namer.h @@ -15,7 +15,7 @@ public: T a; unsigned i; while (it->next(a, i)) { - coeff.emplace_back(a, i); + coeff.push_back(std::make_pair(a, i)); } print_linear_combination_of_column_indices(coeff, out); } diff --git a/src/util/lp/lar_solver.h b/src/util/lp/lar_solver.h index 7c1817c26..bded5dc26 100644 --- a/src/util/lp/lar_solver.h +++ b/src/util/lp/lar_solver.h @@ -1543,7 +1543,5 @@ public: quick_xplain::run(explanation, *this); lean_assert(this->explanation_is_correct(explanation)); } - - }; } diff --git a/src/util/lp/lp_bound_propagator.cpp b/src/util/lp/lp_bound_propagator.cpp index cbd4f28f2..8b42f24a0 100644 --- a/src/util/lp/lp_bound_propagator.cpp +++ b/src/util/lp/lp_bound_propagator.cpp @@ -16,31 +16,36 @@ const impq & lp_bound_propagator::get_upper_bound(unsigned j) const { return m_lar_solver.m_mpq_lar_core_solver.m_r_upper_bounds()[j]; } void lp_bound_propagator::try_add_bound(const mpq & v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict) { - j = m_lar_solver.adjust_column_index_to_term_index(j); + unsigned term_j = m_lar_solver.adjust_column_index_to_term_index(j); + mpq w = v; + if (term_j != j) { + j = term_j; + w += m_lar_solver.get_term(term_j).m_v; // when terms are turned into the columns they "lose" the right side, at this moment they aquire it back + } lconstraint_kind kind = is_low? GE : LE; if (strict) kind = static_cast(kind / 2); - if (!bound_is_interesting(j, kind, v)) + if (!bound_is_interesting(j, kind, w)) return; unsigned k; // index to ibounds if (is_low) { if (try_get_val(m_improved_low_bounds, j, k)) { auto & found_bound = m_ibounds[k]; - if (v > found_bound.m_bound || (v == found_bound.m_bound && found_bound.m_strict == false && strict)) - found_bound = implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict); + if (w > found_bound.m_bound || (w == found_bound.m_bound && found_bound.m_strict == false && strict)) + found_bound = implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict); } else { m_improved_low_bounds[j] = m_ibounds.size(); - m_ibounds.push_back(implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict)); + m_ibounds.push_back(implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict)); } } else { // the upper bound case if (try_get_val(m_improved_upper_bounds, j, k)) { auto & found_bound = m_ibounds[k]; - if (v < found_bound.m_bound || (v == found_bound.m_bound && found_bound.m_strict == false && strict)) - found_bound = implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict); + if (w < found_bound.m_bound || (w == found_bound.m_bound && found_bound.m_strict == false && strict)) + found_bound = implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict); } else { m_improved_upper_bounds[j] = m_ibounds.size(); - m_ibounds.push_back(implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict)); + m_ibounds.push_back(implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict)); } } } From 5fdea2cb18b3d5f721e68de3d9217aa0efb6f2f3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 3 Aug 2017 10:19:07 -0700 Subject: [PATCH 092/488] use rfind instead of index to avoid prefix clashes #534 Signed-off-by: Nikolaj Bjorner --- scripts/mk_genfile_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_genfile_common.py b/scripts/mk_genfile_common.py index 678bc93c7..2e0bbe2ca 100644 --- a/scripts/mk_genfile_common.py +++ b/scripts/mk_genfile_common.py @@ -590,7 +590,7 @@ def mk_def_file_internal(defname, dll_name, export_header_files): def path_after_src(h_file): h_file = h_file.replace("\\","/") - idx = h_file.index("src/") + idx = h_file.rfind("src/") if idx == -1: return h_file return h_file[idx + 4:] From 95f86ae2c0533231880c49ba00b56bc1800cda0a Mon Sep 17 00:00:00 2001 From: Lev Nachmanson Date: Thu, 3 Aug 2017 11:03:52 -0700 Subject: [PATCH 093/488] more efficient lar_solver::get_model Signed-off-by: Lev Nachmanson --- src/util/lp/lar_solver.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/util/lp/lar_solver.h b/src/util/lp/lar_solver.h index bded5dc26..c8048a550 100644 --- a/src/util/lp/lar_solver.h +++ b/src/util/lp/lar_solver.h @@ -1259,7 +1259,7 @@ public: void get_model(std::unordered_map & variable_values) const { - mpq delta = mpq(1, 2); // start from 0.5 to have less clashes + mpq delta = m_mpq_lar_core_solver.find_delta_for_strict_bounds(mpq(1, 2)); // start from 0.5 to have less clashes lean_assert(m_status == OPTIMAL); unsigned i; do { @@ -1267,7 +1267,6 @@ public: // different pairs have to produce different singleton values std::unordered_set set_of_different_pairs; std::unordered_set set_of_different_singles; - delta = m_mpq_lar_core_solver.find_delta_for_strict_bounds(delta); for (i = 0; i < m_mpq_lar_core_solver.m_r_x.size(); i++ ) { const numeric_pair & rp = m_mpq_lar_core_solver.m_r_x[i]; set_of_different_pairs.insert(rp); From 91ee52e549482bdb71eb32df0e0ae4db85d1079a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 3 Aug 2017 13:53:38 -0700 Subject: [PATCH 094/488] fix #1195 Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.cpp | 3 ++- src/smt/theory_arith_core.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index fa169316b..01b671c99 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -81,8 +81,9 @@ app * arith_decl_plugin::mk_numeral(algebraic_numbers::anum const & val, bool is return mk_numeral(rval, is_int); } else { - if (is_int) + if (is_int) { m_manager->raise_exception("invalid irrational value passed as an integer"); + } unsigned idx = aw().mk_id(val); parameter p(idx, true); SASSERT(p.is_external()); diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index 6b8abcdbc..e10395d31 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -1224,7 +1224,9 @@ namespace smt { app * rhs = to_app(n->get_arg(1)); expr * rhs2; if (m_util.is_to_real(rhs, rhs2) && is_app(rhs2)) { rhs = to_app(rhs2); } - SASSERT(m_util.is_numeral(rhs)); + if (!m_util.is_numeral(rhs)) { + throw default_exception("malformed atomic constraint"); + } theory_var v = internalize_term_core(lhs); if (v == null_theory_var) { TRACE("arith_internalize", tout << "failed to internalize: #" << n->get_id() << "\n";); From f4c0e0b28d1e9aa4fc6452506112222dd270eb70 Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Sun, 6 Aug 2017 17:17:04 -0400 Subject: [PATCH 095/488] fix regex bug in theory_str for empty string match. need to fix indents --- src/smt/theory_str.cpp | 48 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 89e0123a8..b869abb0a 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -6189,27 +6189,33 @@ namespace smt { expr * arg_str = a->get_arg(0); zstring str; if (u.str.is_string(arg_str, str)) { - TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); - /* - * For an n-character string, we make (n-1) intermediate states, - * labelled i_(0) through i_(n-2). - * Then we construct the following transitions: - * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final - */ - unsigned last = start; - for (int i = 0; i <= ((int)str.length()) - 2; ++i) { - unsigned i_state = next_id(); - make_transition(last, str[i], i_state); - TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); - last = i_state; - } - make_transition(last, str[(str.length() - 1)], end); - TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); - } else { - TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); - m_valid = false; - return; - } + if (str.length() == 0) { + // transitioning on the empty string is handled specially + TRACE("str", tout << "empty string epsilon-move " << start << " --> " << end << std::endl;); + make_epsilon_move(start, end); + } else { + TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); + /* + * For an n-character string, we make (n-1) intermediate states, + * labelled i_(0) through i_(n-2). + * Then we construct the following transitions: + * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final + */ + unsigned last = start; + for (int i = 0; i <= ((int)str.length()) - 2; ++i) { + unsigned i_state = next_id(); + make_transition(last, str[i], i_state); + TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); + last = i_state; + } + make_transition(last, str[(str.length() - 1)], end); + TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); + } + } else { // ! u.str.is_string(arg_str, str) + TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); + m_valid = false; + return; + } } else if (u.re.is_concat(e)){ app * a = to_app(e); expr * re1 = a->get_arg(0); From cadde94017b235ef4c18b3164261be75be1dc626 Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Mon, 7 Aug 2017 23:02:55 -0400 Subject: [PATCH 096/488] fix indentation and add support for re.allchar --- src/smt/theory_str.cpp | 70 ++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index b869abb0a..727e7e131 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -1685,6 +1685,8 @@ namespace smt { u.str.is_string(range1, range1val); u.str.is_string(range2, range2val); return zstring("[") + range1val + zstring("-") + range2val + zstring("]"); + } else if (u.re.is_full(a_regex)) { + return zstring("."); } else { TRACE("str", tout << "BUG: unrecognized regex term " << mk_pp(regex, get_manager()) << std::endl;); UNREACHABLE(); return zstring(""); @@ -1794,6 +1796,13 @@ namespace smt { expr_ref finalAxiom(m.mk_iff(ex, rhs), m); SASSERT(finalAxiom); assert_axiom(finalAxiom); + } else if (u.re.is_full(regex)) { + // equivalent to regex "." operator, match any one character. + // we rewrite to expr IFF len(str) == 1 + expr_ref rhs(ctx.mk_eq_atom(mk_strlen(str), m_autil.mk_numeral(rational::one(), true)), m); + expr_ref finalAxiom(m.mk_iff(ex, rhs), m); + SASSERT(finalAxiom); + assert_axiom(finalAxiom); } else { TRACE("str", tout << "ERROR: unknown regex expression " << mk_pp(regex, m) << "!" << std::endl;); NOT_IMPLEMENTED_YET(); @@ -6190,32 +6199,32 @@ namespace smt { zstring str; if (u.str.is_string(arg_str, str)) { if (str.length() == 0) { - // transitioning on the empty string is handled specially - TRACE("str", tout << "empty string epsilon-move " << start << " --> " << end << std::endl;); - make_epsilon_move(start, end); - } else { - TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); - /* - * For an n-character string, we make (n-1) intermediate states, - * labelled i_(0) through i_(n-2). - * Then we construct the following transitions: - * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final - */ - unsigned last = start; - for (int i = 0; i <= ((int)str.length()) - 2; ++i) { - unsigned i_state = next_id(); - make_transition(last, str[i], i_state); - TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); - last = i_state; - } - make_transition(last, str[(str.length() - 1)], end); - TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); - } - } else { // ! u.str.is_string(arg_str, str) - TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); - m_valid = false; - return; - } + // transitioning on the empty string is handled specially + TRACE("str", tout << "empty string epsilon-move " << start << " --> " << end << std::endl;); + make_epsilon_move(start, end); + } else { + TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); + /* + * For an n-character string, we make (n-1) intermediate states, + * labelled i_(0) through i_(n-2). + * Then we construct the following transitions: + * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final + */ + unsigned last = start; + for (int i = 0; i <= ((int)str.length()) - 2; ++i) { + unsigned i_state = next_id(); + make_transition(last, str[i], i_state); + TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); + last = i_state; + } + make_transition(last, str[(str.length() - 1)], end); + TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); + } + } else { // ! u.str.is_string(arg_str, str) + TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); + m_valid = false; + return; + } } else if (u.re.is_concat(e)){ app * a = to_app(e); expr * re1 = a->get_arg(0); @@ -6284,6 +6293,15 @@ namespace smt { } TRACE("str", tout << "range NFA: start = " << start << ", end = " << end << std::endl;); + } else if (u.re.is_full(e)) { + // equivalent to "transition on each character in the alphabet" + + // TODO this hard-codes something about theory_str's char set here + + for (unsigned i = 1; i <= 255; ++i) { + char ch = (char)i; + make_transition(start, ch, end); + } } else { TRACE("str", tout << "invalid regular expression" << std::endl;); m_valid = false; From 082936bca6fbd6d363cf09c20f60d113691c2ed8 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 8 Aug 2017 09:21:06 +0200 Subject: [PATCH 097/488] enable overloading resolution on define-fun declarations, fix #1199 Signed-off-by: Nikolaj Bjorner --- .../simplifier/basic_simplifier_plugin.cpp | 7 +- src/cmd_context/basic_cmds.cpp | 40 ++-- src/cmd_context/cmd_context.cpp | 178 +++++++++++++----- src/cmd_context/cmd_context.h | 44 ++++- src/parsers/smt2/smt2parser.cpp | 6 +- src/smt/smt_context.h | 10 +- 6 files changed, 205 insertions(+), 80 deletions(-) diff --git a/src/ast/simplifier/basic_simplifier_plugin.cpp b/src/ast/simplifier/basic_simplifier_plugin.cpp index 25998d832..be51bc291 100644 --- a/src/ast/simplifier/basic_simplifier_plugin.cpp +++ b/src/ast/simplifier/basic_simplifier_plugin.cpp @@ -59,7 +59,12 @@ bool basic_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * co mk_iff(args[0], args[1], result); return true; case OP_XOR: - mk_xor(args[0], args[1], result); + switch (num_args) { + case 0: result = m_manager.mk_true(); break; + case 1: result = args[0]; break; + case 2: mk_xor(args[0], args[1], result); break; + default: UNREACHABLE(); break; + } return true; case OP_NOT: SASSERT(num_args == 1); diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index 8830358af..db522b82b 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -135,28 +135,30 @@ ATOMIC_CMD(get_assignment_cmd, "get-assignment", "retrieve assignment", { model_ref m; ctx.get_check_sat_result()->get_model(m); ctx.regular_stream() << "("; - dictionary const & macros = ctx.get_macros(); - dictionary::iterator it = macros.begin(); - dictionary::iterator end = macros.end(); + dictionary const & macros = ctx.get_macros(); + dictionary::iterator it = macros.begin(); + dictionary::iterator end = macros.end(); for (bool first = true; it != end; ++it) { symbol const & name = (*it).m_key; - cmd_context::macro const & _m = (*it).m_value; - if (_m.first == 0 && ctx.m().is_bool(_m.second)) { - expr_ref val(ctx.m()); - m->eval(_m.second, val, true); - if (ctx.m().is_true(val) || ctx.m().is_false(val)) { - if (first) - first = false; - else - ctx.regular_stream() << " "; - ctx.regular_stream() << "("; - if (is_smt2_quoted_symbol(name)) { - ctx.regular_stream() << mk_smt2_quoted_symbol(name); + macro_decls const & _m = (*it).m_value; + for (auto md : _m) { + if (md.m_domain.size() == 0 && ctx.m().is_bool(md.m_body)) { + expr_ref val(ctx.m()); + m->eval(md.m_body, val, true); + if (ctx.m().is_true(val) || ctx.m().is_false(val)) { + if (first) + first = false; + else + ctx.regular_stream() << " "; + ctx.regular_stream() << "("; + if (is_smt2_quoted_symbol(name)) { + ctx.regular_stream() << mk_smt2_quoted_symbol(name); + } + else { + ctx.regular_stream() << name; + } + ctx.regular_stream() << " " << (ctx.m().is_true(val) ? "true" : "false") << ")"; } - else { - ctx.regular_stream() << name; - } - ctx.regular_stream() << " " << (ctx.m().is_true(val) ? "true" : "false") << ")"; } } } diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index a893a1637..f172e5e93 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -76,6 +76,15 @@ bool func_decls::signatures_collide(func_decl* f, func_decl* g) const { return f == g; } +bool func_decls::signatures_collide(unsigned n, sort* const* domain, sort* range, func_decl* g) const { + if (g->get_range() != range) return false; + if (n != g->get_arity()) return false; + for (unsigned i = 0; i < n; ++i) { + if (domain[i] != g->get_domain(i)) return false; + } + return true; +} + bool func_decls::contains(func_decl * f) const { if (GET_TAG(m_decls) == 0) { func_decl* g = UNTAG(func_decl*, m_decls); @@ -90,6 +99,21 @@ bool func_decls::contains(func_decl * f) const { return false; } + +bool func_decls::contains(unsigned n, sort* const* domain, sort* range) const { + if (GET_TAG(m_decls) == 0) { + func_decl* g = UNTAG(func_decl*, m_decls); + return g && signatures_collide(n, domain, range, g); + } + else { + func_decl_set * fs = UNTAG(func_decl_set *, m_decls); + for (func_decl* g : *fs) { + if (signatures_collide(n, domain, range, g)) return true; + } + } + return false; +} + bool func_decls::insert(ast_manager & m, func_decl * f) { if (contains(f)) return false; @@ -205,6 +229,94 @@ func_decl * func_decls::find(ast_manager & m, unsigned num_args, expr * const * return find(num_args, sorts.c_ptr(), range); } +void macro_decls::finalize(ast_manager& m) { + for (auto v : *m_decls) m.dec_ref(v.m_body); + dealloc(m_decls); +} + +bool macro_decls::insert(ast_manager& m, unsigned arity, sort *const* domain, expr* body) { + if (find(arity, domain)) return false; + m.inc_ref(body); + if (!m_decls) m_decls = alloc(vector); + m_decls->push_back(macro_decl(arity, domain, body)); + return true; +} + +expr* macro_decls::find(unsigned arity, sort *const* domain) const { + if (!m_decls) return 0; + for (auto v : *m_decls) { + if (v.m_domain.size() != arity) continue; + bool eq = true; + for (unsigned i = 0; eq && i < arity; ++i) { + eq = domain[i] == v.m_domain[i]; + } + if (eq) return v.m_body; + } + return 0; +} + +void macro_decls::erase_last(ast_manager& m) { + SASSERT(m_decls); + SASSERT(!m_decls->empty()); + m.dec_ref(m_decls->back().m_body); + m_decls->pop_back(); +} + +bool cmd_context::contains_func_decl(symbol const& s, unsigned n, sort* const* domain, sort* range) const { + func_decls fs; + return m_func_decls.find(s, fs) && fs.contains(n, domain, range); +} + +bool cmd_context::contains_macro(symbol const& s) const { + return m_macros.contains(s); +} + +bool cmd_context::contains_macro(symbol const& s, func_decl* f) const { + return contains_macro(s, f->get_arity(), f->get_domain()); +} + +bool cmd_context::contains_macro(symbol const& s, unsigned arity, sort *const* domain) const { + macro_decls decls; + return m_macros.find(s, decls) && 0 != decls.find(arity, domain); +} + +void cmd_context::insert_macro(symbol const& s, unsigned arity, sort*const* domain, expr* t) { + macro_decls decls; + if (!m_macros.find(s, decls)) { + VERIFY(decls.insert(m(), arity, domain, t)); + m_macros.insert(s, decls); + } + else { + VERIFY(decls.insert(m(), arity, domain, t)); + } +} + +void cmd_context::erase_macro(symbol const& s) { + macro_decls decls; + VERIFY(m_macros.find(s, decls)); + decls.erase_last(m()); +} + +bool cmd_context::macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const { + macro_decls decls; + if (!m_macros.find(s, decls)) { + return false; + } + for (macro_decl const& d : decls) { + if (d.m_domain.size() != n) continue; + bool eq = true; + for (unsigned i = 0; eq && i < n; ++i) { + eq = d.m_domain[i] == m().get_sort(args[i]); + } + if (eq) { + t = d.m_body; + return true; + } + } + return false; +} + + ast_object_ref::ast_object_ref(cmd_context & ctx, ast * a):m_ast(a) { ctx.m().inc_ref(a); } @@ -658,7 +770,7 @@ void cmd_context::insert(symbol const & s, func_decl * f) { if (!m_check_logic(f)) { throw cmd_exception(m_check_logic.get_last_error()); } - if (m_macros.contains(s)) { + if (contains_macro(s, f)) { throw cmd_exception("invalid declaration, named expression already defined with this name ", s); } if (m_builtin_decls.contains(s)) { @@ -697,20 +809,20 @@ void cmd_context::insert(symbol const & s, psort_decl * p) { TRACE("cmd_context", tout << "new sort decl\n"; p->display(tout); tout << "\n";); } -void cmd_context::insert(symbol const & s, unsigned arity, expr * t) { +void cmd_context::insert(symbol const & s, unsigned arity, sort *const* domain, expr * t) { + expr_ref _t(t, m()); m_check_sat_result = 0; if (m_builtin_decls.contains(s)) { throw cmd_exception("invalid macro/named expression, builtin symbol ", s); } - if (m_macros.contains(s)) { + if (contains_macro(s, arity, domain)) { throw cmd_exception("named expression already defined"); } - if (m_func_decls.contains(s)) { + if (contains_func_decl(s, arity, domain, m().get_sort(t))) { throw cmd_exception("invalid named expression, declaration already defined with this name ", s); } - m().inc_ref(t); TRACE("insert_macro", tout << "new macro " << arity << "\n" << mk_pp(t, m()) << "\n";); - m_macros.insert(s, macro(arity, t)); + insert_macro(s, arity, domain, t); if (!m_global_decls) { m_macros_stack.push_back(s); } @@ -783,8 +895,9 @@ func_decl * cmd_context::find_func_decl(symbol const & s) const { } throw cmd_exception("invalid function declaration reference, must provide signature for builtin symbol ", s); } - if (m_macros.contains(s)) + if (contains_macro(s)) { throw cmd_exception("invalid function declaration reference, named expressions (aka macros) cannot be referenced ", s); + } func_decls fs; if (m_func_decls.find(s, fs)) { if (fs.more_than_one()) @@ -840,7 +953,7 @@ func_decl * cmd_context::find_func_decl(symbol const & s, unsigned num_indices, return f; } - if (m_macros.contains(s)) + if (contains_macro(s, arity, domain)) throw cmd_exception("invalid function declaration reference, named expressions (aka macros) cannot be referenced ", s); if (num_indices > 0) @@ -862,11 +975,6 @@ psort_decl * cmd_context::find_psort_decl(symbol const & s) const { return p; } -cmd_context::macro cmd_context::find_macro(symbol const & s) const { - macro m; - m_macros.find(s, m); - return m; -} cmd * cmd_context::find_cmd(symbol const & s) const { cmd * c = 0; @@ -918,21 +1026,14 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg } if (num_indices > 0) throw cmd_exception("invalid use of indexed indentifier, unknown builtin function ", s); - macro _m; - if (m_macros.find(s, _m)) { - if (num_args != _m.first) - throw cmd_exception("invalid defined function application, incorrect number of arguments ", s); - if (num_args == 0) { - result = _m.second; - return; - } - SASSERT(num_args > 0); + expr* _t; + if (macros_find(s, num_args, args, _t)) { TRACE("macro_bug", tout << "well_sorted_check_enabled(): " << well_sorted_check_enabled() << "\n"; tout << "s: " << s << "\n"; - tout << "body:\n" << mk_ismt2_pp(_m.second, m()) << "\n"; + tout << "body:\n" << mk_ismt2_pp(_t, m()) << "\n"; tout << "args:\n"; for (unsigned i = 0; i < num_args; i++) tout << mk_ismt2_pp(args[i], m()) << "\n" << mk_pp(m().get_sort(args[i]), m()) << "\n";); var_subst subst(m()); - subst(_m.second, num_args, args, result); + subst(_t, num_args, args, result); if (well_sorted_check_enabled() && !is_well_sorted(m(), result)) throw cmd_exception("invalid macro application, sort mismatch ", s); return; @@ -956,7 +1057,6 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg if (f->get_arity() != 0) throw cmd_exception("invalid function application, missing arguments ", s); result = m().mk_const(f); - return; } else { func_decl * f = fs.find(m(), num_args, args, range); @@ -965,7 +1065,6 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg if (well_sorted_check_enabled()) m().check_sort(f, num_args, args); result = m().mk_app(f, num_args, args); - return; } } @@ -1023,21 +1122,6 @@ void cmd_context::erase_psort_decl(symbol const & s) { erase_psort_decl_core(s); } -void cmd_context::erase_macro_core(symbol const & s) { - macro _m; - if (m_macros.find(s, _m)) { - m().dec_ref(_m.second); - m_macros.erase(s); - } -} - -void cmd_context::erase_macro(symbol const & s) { - if (!global_decls()) { - throw cmd_exception("macros (aka named expressions) can only be erased when global (instead of scoped) declarations are used"); - } - erase_macro_core(s); -} - void cmd_context::erase_cmd(symbol const & s) { cmd * c; if (m_cmds.find(s, c)) { @@ -1087,11 +1171,8 @@ void cmd_context::reset_psort_decls() { } void cmd_context::reset_macros() { - dictionary::iterator it = m_macros.begin(); - dictionary::iterator end = m_macros.end(); - for (; it != end; ++it) { - expr * t = (*it).m_value.second; - m().dec_ref(t); + for (auto & kv : m_macros) { + kv.m_value.finalize(m()); } m_macros.reset(); m_macros_stack.reset(); @@ -1274,10 +1355,7 @@ void cmd_context::restore_macros(unsigned old_sz) { svector::iterator end = m_macros_stack.end(); for (; it != end; ++it) { symbol const & s = *it; - macro _m; - VERIFY (m_macros.find(s, _m)); - m().dec_ref(_m.second); - m_macros.erase(s); + erase_macro(s); } m_macros_stack.shrink(old_sz); } diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index ca4883e74..189863e58 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -43,11 +43,13 @@ Notes: class func_decls { func_decl * m_decls; bool signatures_collide(func_decl* f, func_decl* g) const; + bool signatures_collide(unsigned n, sort*const* domain, sort* range, func_decl* g) const; public: func_decls():m_decls(0) {} func_decls(ast_manager & m, func_decl * f); void finalize(ast_manager & m); bool contains(func_decl * f) const; + bool contains(unsigned n, sort* const* domain, sort* range) const; bool insert(ast_manager & m, func_decl * f); void erase(ast_manager & m, func_decl * f); bool more_than_one() const; @@ -58,6 +60,29 @@ public: func_decl * find(ast_manager & m, unsigned num_args, expr * const * args, sort * range) const; }; +struct macro_decl { + ptr_vector m_domain; + expr* m_body; + + macro_decl(unsigned arity, sort *const* domain, expr* body): + m_domain(arity, domain), m_body(body) {} + + void dec_ref(ast_manager& m) { m.dec_ref(m_body); } + +}; + +class macro_decls { + vector* m_decls; +public: + macro_decls() { m_decls = 0; } + void finalize(ast_manager& m); + bool insert(ast_manager& m, unsigned arity, sort *const* domain, expr* body); + expr* find(unsigned arity, sort *const* domain) const; + void erase_last(ast_manager& m); + vector::iterator begin() const { return m_decls->begin(); } + vector::iterator end() const { return m_decls->end(); } +}; + /** \brief Generic wrapper. */ @@ -184,7 +209,7 @@ protected: dictionary m_func_decls; obj_map m_func_decl2alias; dictionary m_psort_decls; - dictionary m_macros; + dictionary m_macros; // the following fields m_func_decls_stack, m_psort_decls_stack and m_exprs_stack are used when m_global_decls == false typedef std::pair sf_pair; svector m_func_decls_stack; @@ -253,7 +278,6 @@ protected: void erase_func_decl_core(symbol const & s, func_decl * f); void erase_psort_decl_core(symbol const & s); - void erase_macro_core(symbol const & s); bool logic_has_arith() const; bool logic_has_bv() const; @@ -268,6 +292,16 @@ protected: void mk_solver(); + bool contains_func_decl(symbol const& s, unsigned n, sort* const* domain, sort* range) const; + + bool contains_macro(symbol const& s) const; + bool contains_macro(symbol const& s, func_decl* f) const; + bool contains_macro(symbol const& s, unsigned arity, sort *const* domain) const; + void insert_macro(symbol const& s, unsigned arity, sort*const* domain, expr* t); + void erase_macro(symbol const& s); + bool macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const; + + public: cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null); ~cmd_context(); @@ -337,7 +371,7 @@ public: void insert(func_decl * f) { insert(f->get_name(), f); } void insert(symbol const & s, psort_decl * p); void insert(psort_decl * p) { insert(p->get_name(), p); } - void insert(symbol const & s, unsigned arity, expr * t); + void insert(symbol const & s, unsigned arity, sort *const* domain, expr * t); void insert(symbol const & s, object_ref *); void insert(tactic_cmd * c) { tactic_manager::insert(c); } void insert(probe_info * p) { tactic_manager::insert(p); } @@ -348,7 +382,6 @@ public: func_decl * find_func_decl(symbol const & s, unsigned num_indices, unsigned const * indices, unsigned arity, sort * const * domain, sort * range) const; psort_decl * find_psort_decl(symbol const & s) const; - macro find_macro(symbol const & s) const; cmd * find_cmd(symbol const & s) const; sexpr * find_user_tactic(symbol const & s) const; object_ref * find_object_ref(symbol const & s) const; @@ -360,7 +393,6 @@ public: void erase_func_decl(symbol const & s, func_decl * f); void erase_func_decl(func_decl * f) { erase_func_decl(f->get_name(), f); } void erase_psort_decl(symbol const & s); - void erase_macro(symbol const & s); void erase_object_ref(symbol const & s); void erase_user_tactic(symbol const & s); void reset_func_decls(); @@ -400,7 +432,7 @@ public: void validate_check_sat_result(lbool r); unsigned num_scopes() const { return m_scopes.size(); } - dictionary const & get_macros() const { return m_macros; } + dictionary const & get_macros() const { return m_macros; } bool is_model_available() const; diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index b86a663a7..3d895668b 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -992,7 +992,7 @@ namespace smt2 { TRACE("name_expr", tout << "naming: " << s << " ->\n" << mk_pp(n, m()) << "\n";); if (!is_ground(n) && has_free_vars(n)) throw parser_exception("invalid named expression, expression contains free variables"); - m_ctx.insert(s, 0, n); + m_ctx.insert(s, 0, 0, n); m_last_named_expr.first = s; m_last_named_expr.second = n; } @@ -1984,7 +1984,7 @@ namespace smt2 { parse_expr(); if (m().get_sort(expr_stack().back()) != sort_stack().back()) throw parser_exception("invalid function/constant definition, sort mismatch"); - m_ctx.insert(id, num_vars, expr_stack().back()); + m_ctx.insert(id, num_vars, sort_stack().c_ptr() + sort_spos, expr_stack().back()); check_rparen("invalid function/constant definition, ')' expected"); // restore stacks & env symbol_stack().shrink(sym_spos); @@ -2135,7 +2135,7 @@ namespace smt2 { parse_expr(); if (m().get_sort(expr_stack().back()) != sort_stack().back()) throw parser_exception("invalid constant definition, sort mismatch"); - m_ctx.insert(id, 0, expr_stack().back()); + m_ctx.insert(id, 0, 0, expr_stack().back()); check_rparen("invalid constant definition, ')' expected"); expr_stack().pop_back(); sort_stack().pop_back(); diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index 84bf9f62a..1aa3b385b 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -257,7 +257,15 @@ namespace smt { return m_params; } - bool get_cancel_flag() { return !m_manager.limit().inc(); } + bool get_cancel_flag() { + if (m_manager.limit().inc()) { + // get_simplifier().reset(); + return false; + } + else { + return true; + } + } region & get_region() { return m_region; From fce35fdb611c9018a32855a2e46b9ea05161c26c Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Wed, 9 Aug 2017 15:37:52 -0400 Subject: [PATCH 098/488] Revert "fix indentation and add support for re.allchar" This reverts commit cadde94017b235ef4c18b3164261be75be1dc626. --- src/smt/theory_str.cpp | 70 ++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 727e7e131..b869abb0a 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -1685,8 +1685,6 @@ namespace smt { u.str.is_string(range1, range1val); u.str.is_string(range2, range2val); return zstring("[") + range1val + zstring("-") + range2val + zstring("]"); - } else if (u.re.is_full(a_regex)) { - return zstring("."); } else { TRACE("str", tout << "BUG: unrecognized regex term " << mk_pp(regex, get_manager()) << std::endl;); UNREACHABLE(); return zstring(""); @@ -1796,13 +1794,6 @@ namespace smt { expr_ref finalAxiom(m.mk_iff(ex, rhs), m); SASSERT(finalAxiom); assert_axiom(finalAxiom); - } else if (u.re.is_full(regex)) { - // equivalent to regex "." operator, match any one character. - // we rewrite to expr IFF len(str) == 1 - expr_ref rhs(ctx.mk_eq_atom(mk_strlen(str), m_autil.mk_numeral(rational::one(), true)), m); - expr_ref finalAxiom(m.mk_iff(ex, rhs), m); - SASSERT(finalAxiom); - assert_axiom(finalAxiom); } else { TRACE("str", tout << "ERROR: unknown regex expression " << mk_pp(regex, m) << "!" << std::endl;); NOT_IMPLEMENTED_YET(); @@ -6199,32 +6190,32 @@ namespace smt { zstring str; if (u.str.is_string(arg_str, str)) { if (str.length() == 0) { - // transitioning on the empty string is handled specially - TRACE("str", tout << "empty string epsilon-move " << start << " --> " << end << std::endl;); - make_epsilon_move(start, end); - } else { - TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); - /* - * For an n-character string, we make (n-1) intermediate states, - * labelled i_(0) through i_(n-2). - * Then we construct the following transitions: - * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final - */ - unsigned last = start; - for (int i = 0; i <= ((int)str.length()) - 2; ++i) { - unsigned i_state = next_id(); - make_transition(last, str[i], i_state); - TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); - last = i_state; - } - make_transition(last, str[(str.length() - 1)], end); - TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); - } - } else { // ! u.str.is_string(arg_str, str) - TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); - m_valid = false; - return; - } + // transitioning on the empty string is handled specially + TRACE("str", tout << "empty string epsilon-move " << start << " --> " << end << std::endl;); + make_epsilon_move(start, end); + } else { + TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); + /* + * For an n-character string, we make (n-1) intermediate states, + * labelled i_(0) through i_(n-2). + * Then we construct the following transitions: + * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final + */ + unsigned last = start; + for (int i = 0; i <= ((int)str.length()) - 2; ++i) { + unsigned i_state = next_id(); + make_transition(last, str[i], i_state); + TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); + last = i_state; + } + make_transition(last, str[(str.length() - 1)], end); + TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); + } + } else { // ! u.str.is_string(arg_str, str) + TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); + m_valid = false; + return; + } } else if (u.re.is_concat(e)){ app * a = to_app(e); expr * re1 = a->get_arg(0); @@ -6293,15 +6284,6 @@ namespace smt { } TRACE("str", tout << "range NFA: start = " << start << ", end = " << end << std::endl;); - } else if (u.re.is_full(e)) { - // equivalent to "transition on each character in the alphabet" - - // TODO this hard-codes something about theory_str's char set here - - for (unsigned i = 1; i <= 255; ++i) { - char ch = (char)i; - make_transition(start, ch, end); - } } else { TRACE("str", tout << "invalid regular expression" << std::endl;); m_valid = false; From 84abdae5f755e0e703bf8e4d378712b843140627 Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Wed, 9 Aug 2017 15:38:56 -0400 Subject: [PATCH 099/488] fix indentation --- src/smt/theory_str.cpp | 52 +++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index b869abb0a..2016a6501 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -6190,32 +6190,32 @@ namespace smt { zstring str; if (u.str.is_string(arg_str, str)) { if (str.length() == 0) { - // transitioning on the empty string is handled specially - TRACE("str", tout << "empty string epsilon-move " << start << " --> " << end << std::endl;); - make_epsilon_move(start, end); - } else { - TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); - /* - * For an n-character string, we make (n-1) intermediate states, - * labelled i_(0) through i_(n-2). - * Then we construct the following transitions: - * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final - */ - unsigned last = start; - for (int i = 0; i <= ((int)str.length()) - 2; ++i) { - unsigned i_state = next_id(); - make_transition(last, str[i], i_state); - TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); - last = i_state; - } - make_transition(last, str[(str.length() - 1)], end); - TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); - } - } else { // ! u.str.is_string(arg_str, str) - TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); - m_valid = false; - return; - } + // transitioning on the empty string is handled specially + TRACE("str", tout << "empty string epsilon-move " << start << " --> " << end << std::endl;); + make_epsilon_move(start, end); + } else { + TRACE("str", tout << "build NFA for '" << str << "'" << "\n";); + /* + * For an n-character string, we make (n-1) intermediate states, + * labelled i_(0) through i_(n-2). + * Then we construct the following transitions: + * start --str[0]--> i_(0) --str[1]--> i_(1) --...--> i_(n-2) --str[n-1]--> final + */ + unsigned last = start; + for (int i = 0; i <= ((int)str.length()) - 2; ++i) { + unsigned i_state = next_id(); + make_transition(last, str[i], i_state); + TRACE("str", tout << "string transition " << last << "--" << str[i] << "--> " << i_state << "\n";); + last = i_state; + } + make_transition(last, str[(str.length() - 1)], end); + TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); + } + } else { // ! u.str.is_string(arg_str, str) + TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); + m_valid = false; + return; + } } else if (u.re.is_concat(e)){ app * a = to_app(e); expr * re1 = a->get_arg(0); From b2388464e46e3e44f5448a2b285ce0b35878422d Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Wed, 9 Aug 2017 22:03:26 -0400 Subject: [PATCH 100/488] add re.all to theory_str --- src/smt/theory_str.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 2016a6501..5642339f4 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -1685,6 +1685,8 @@ namespace smt { u.str.is_string(range1, range1val); u.str.is_string(range2, range2val); return zstring("[") + range1val + zstring("-") + range2val + zstring("]"); + } else if (u.re.is_full(a_regex)) { + return zstring("(.*)"); } else { TRACE("str", tout << "BUG: unrecognized regex term " << mk_pp(regex, get_manager()) << std::endl;); UNREACHABLE(); return zstring(""); @@ -1715,6 +1717,12 @@ namespace smt { expr_ref str(ex->get_arg(0), m); app * regex = to_app(ex->get_arg(1)); + // quick reference for the following code: + // - ex: top-level regex membership term + // - str: string term appearing in ex + // - regex: regex term appearing in ex + // ex ::= (str.in.re str regex) + if (u.re.is_to_re(regex)) { expr_ref rxStr(regex->get_arg(0), m); // want to assert 'expr IFF (str == rxStr)' @@ -1794,6 +1802,9 @@ namespace smt { expr_ref finalAxiom(m.mk_iff(ex, rhs), m); SASSERT(finalAxiom); assert_axiom(finalAxiom); + } else if (u.re.is_full(regex)) { + // trivially true for any string! + assert_axiom(ex); } else { TRACE("str", tout << "ERROR: unknown regex expression " << mk_pp(regex, m) << "!" << std::endl;); NOT_IMPLEMENTED_YET(); @@ -6284,6 +6295,10 @@ namespace smt { } TRACE("str", tout << "range NFA: start = " << start << ", end = " << end << std::endl;); + } else if (u.re.is_full(e)) { + NOT_IMPLEMENTED_YET(); + m_valid = false; + return; } else { TRACE("str", tout << "invalid regular expression" << std::endl;); m_valid = false; From 7b47b0380e5d2fb403c9da0b89af498064b5e286 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 10 Aug 2017 23:43:21 +0200 Subject: [PATCH 101/488] update Ackerman reduction for division to make Andre and Nathan happy Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 4 +-- src/qe/nlqsat.cpp | 47 ++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 90792ad64..6fd492ae4 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -656,8 +656,8 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) { unsigned sz = as.size(); expr* b0 = bs[0].get(); expr* bL = bs[bs.size()-1].get(); - for (; offs < as.size() && m().are_distinct(b0, as[offs].get()); ++offs) {}; - for (; sz > offs && m().are_distinct(bL, as[sz-1].get()); --sz) {} + for (; offs < as.size() && m_util.str.is_unit(b0) && m_util.str.is_unit(as[offs].get()) && m().are_distinct(b0, as[offs].get()); ++offs) {}; + for (; sz > offs && m_util.str.is_unit(bL) && m_util.str.is_unit(as[sz-1].get()) && m().are_distinct(bL, as[sz-1].get()); --sz) {} if (offs == sz) { result = m().mk_eq(b, m_util.str.mk_empty(m().get_sort(b))); return BR_REWRITE2; diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index a10971165..4f041cc41 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -429,8 +429,9 @@ namespace qe { } struct div { - expr_ref num, den, name; - div(ast_manager& m, expr* n, expr* d, expr* nm): + expr_ref num, den; + app_ref name; + div(ast_manager& m, expr* n, expr* d, app* nm): num(n, m), den(d, m), name(nm, m) {} }; @@ -442,9 +443,9 @@ namespace qe { div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m) {} ~div_rewriter_cfg() {} br_status reduce_app(func_decl* f, unsigned sz, expr* const* args, expr_ref& result, proof_ref& pr) { - if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && !a.is_numeral(args[1]) && is_ground(args[0]) && is_ground(args[1])) { + if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && !a.is_numeral(args[1])) { result = m.mk_fresh_const("div", a.mk_real()); - m_divs.push_back(div(m, args[0], args[1], result)); + m_divs.push_back(div(m, args[0], args[1], to_app(result))); return BR_DONE; } return BR_FAILED; @@ -496,7 +497,7 @@ namespace qe { if (a.is_power(n, n1, n2) && a.is_numeral(n2, r) && r.is_unsigned()) { return; } - if (a.is_div(n, n1, n2) && is_ground(n1) && is_ground(n2) && s.m_mode == qsat_t) { + if (a.is_div(n, n1, n2) && s.m_mode == qsat_t) { m_has_divs = true; return; } @@ -508,7 +509,7 @@ namespace qe { bool has_divs() const { return m_has_divs; } }; - void purify(expr_ref& fml) { + void purify(expr_ref& fml, app_ref_vector& pvars, expr_ref_vector& paxioms) { is_pure_proc is_pure(*this); { expr_fast_mark1 visited; @@ -520,19 +521,34 @@ namespace qe { proof_ref pr(m); rw(fml, fml, pr); vector
const& divs = rw.divs(); - expr_ref_vector axioms(m); for (unsigned i = 0; i < divs.size(); ++i) { - axioms.push_back( + pvars.push_back(divs[i].name); + paxioms.push_back( m.mk_or(m.mk_eq(divs[i].den, arith.mk_numeral(rational(0), false)), m.mk_eq(divs[i].num, arith.mk_mul(divs[i].den, divs[i].name)))); for (unsigned j = i + 1; j < divs.size(); ++j) { - axioms.push_back(m.mk_or(m.mk_not(m.mk_eq(divs[i].den, divs[j].den)), - m.mk_not(m.mk_eq(divs[i].num, divs[j].num)), - m.mk_eq(divs[i].name, divs[j].name))); + paxioms.push_back(m.mk_or(m.mk_not(m.mk_eq(divs[i].den, divs[j].den)), + m.mk_not(m.mk_eq(divs[i].num, divs[j].num)), + m.mk_eq(divs[i].name, divs[j].name))); } } - axioms.push_back(fml); - fml = mk_and(axioms); + } + } + + void ackermanize_div(bool is_forall, vector& qvars, expr_ref& fml) { + app_ref_vector pvars(m); + expr_ref_vector paxioms(m); + purify(fml, pvars, paxioms); + if (pvars.empty()) { + return; + } + expr_ref ante = mk_and(paxioms); + qvars[qvars.size()-2].append(pvars); + if (!is_forall) { + fml = m.mk_implies(ante, fml); + } + else { + fml = m.mk_and(fml, ante); } } @@ -602,7 +618,6 @@ namespace qe { app_ref_vector vars(m); bool is_forall = false; pred_abs abs(m); - purify(fml); abs.get_free_vars(fml, vars); insert_set(m_free_vars, vars); qvars.push_back(vars); @@ -624,8 +639,12 @@ namespace qe { } while (!vars.empty()); SASSERT(qvars.back().empty()); + + ackermanize_div(is_forall, qvars, fml); + init_expr2var(qvars); + goal2nlsat g2s; expr_ref is_true(m), fml1(m), fml2(m); From e898f515f75f12c363099f130e46bf638d1a42f9 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sat, 12 Aug 2017 18:09:38 +0100 Subject: [PATCH 102/488] [CMake] Change how the default value of `USE_OPENMP` is set. This change means if the user explicitly passes `-DUSE_OPENMP=ON` to CMake during the first configure and the compiler does not support OpenMP the configure will fail but if the user doesn't specify it the build system will automatically enable/disable OpenMP support depending on whether it is supported by the compiler. This is an improvement on the previous behaviour because previously we would just emit a warning if `-DUSE_OPENMP=ON` was passed and the compiler didn't support OpenMP. --- CMakeLists.txt | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8845786f9..a3ed2a312 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -281,33 +281,37 @@ endif() ################################################################################ # OpenMP support ################################################################################ -option(USE_OPENMP "Use OpenMP" ON) -set(OPENMP_FOUND FALSE) -if (USE_OPENMP) - # Because this is on by default we make the configure succeed with a warning - # if OpenMP support is not detected. - find_package(OpenMP) - if (NOT OPENMP_FOUND) - message(WARNING "OpenMP support was requested but your compiler doesn't support it") - endif() -endif() - +find_package(OpenMP) if (OPENMP_FOUND) - list(APPEND Z3_COMPONENT_CXX_FLAGS ${OpenMP_CXX_FLAGS}) - # GCC and Clang need to have additional flags passed to the linker. - # We can't do ``target_link_libraries(libz3 INTERFACE ${OpenMP_CXX_FLAGS})`` - # because ``/openmp`` is interpreted as file name rather than a linker - # flag by MSVC and breaks the build - if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR - ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")) - list(APPEND Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS ${OpenMP_CXX_FLAGS}) - endif() - unset(CMAKE_REQUIRED_FLAGS) - message(STATUS "Using OpenMP") + set(USE_OPENMP_DEFAULT ON) +else() + set(USE_OPENMP_DEFAULT OFF) +endif() +# By setting `USE_OPENMP` this way configuration will fail during the first +# configure if the user explicitly passes `-DUSE_OPENMP=ON` and the compiler +# does not support OpenMP. However if the option is not set explicitly during +# the first configure OpenMP support will be automatically enabled/disabled +# depending on whether OpenMP is available. +option(USE_OPENMP "Use OpenMP" ${USE_OPENMP_DEFAULT}) + +if (USE_OPENMP) + if (NOT OPENMP_FOUND) + message(FATAL_ERROR "USE_OPENMP is ON but your compiler does not support OpenMP") + endif() + + list(APPEND Z3_COMPONENT_CXX_FLAGS ${OpenMP_CXX_FLAGS}) + # GCC and Clang need to have additional flags passed to the linker. + # We can't do ``target_link_libraries(libz3 INTERFACE ${OpenMP_CXX_FLAGS})`` + # because ``/openmp`` is interpreted as file name rather than a linker + # flag by MSVC and breaks the build + if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR + ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")) + list(APPEND Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS ${OpenMP_CXX_FLAGS}) + endif() + message(STATUS "Using OpenMP") else() list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_NO_OMP_") message(STATUS "Not using OpenMP") - set(USE_OPENMP OFF CACHE BOOL "Use OpenMP" FORCE) endif() ################################################################################ From e88f33ba949fce0c08d07c3c4c6c762bd01f1385 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sat, 12 Aug 2017 17:18:31 +0100 Subject: [PATCH 103/488] [TravisCI] Unbreak showing interactive log output for non-LTO builds. c2f69ae9fbdcad143557309dd021aa7cafb21d36 added the use of the `travis_wait` command to all builds but this stops interactive build output from showing in the TravisCI web interface. To limit the scope of this change we only use it for LTO builds now. --- .travis.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b179c5bfe..672d8ed52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,7 +65,11 @@ env: # - os: osx # osx_image: xcode 8.2 script: - # Use `travis_wait` to handle commands that don't show output for a long period of time. - # Currently this is the LTO build which can be very slow. - # Allow at most 45 minutes for the build. - - travis_wait 45 contrib/ci/scripts/travis_ci_entry_point.sh + # Use `travis_wait` when doing LTO builds because this configuration will + # have long link times during which it will not show any output which + # TravisCI might kill due to perceived inactivity. + - if [ "X${USE_LTO}" = "X1" ]; then + travis_wait 45 contrib/ci/scripts/travis_ci_entry_point.sh || exit 1; + else + contrib/ci/scripts/travis_ci_entry_point.sh || exit 1; + fi From 850c2ebc0ca1bfbe11c3fa2040a367e89cc987d2 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sat, 12 Aug 2017 13:52:30 +0100 Subject: [PATCH 104/488] [TravisCI] Add scripts to build and test Z3 on macOS (OSX) and add a single configuration to TravisCI to test. TravisCI is very slow at running macOS jobs so just have one configuration for now. --- .travis.yml | 15 +++-- contrib/ci/scripts/install_deps_osx.sh | 47 +++++++++++++ .../ci/scripts/travis_ci_osx_entry_point.sh | 66 ++++++++++++++++++- 3 files changed, 121 insertions(+), 7 deletions(-) create mode 100755 contrib/ci/scripts/install_deps_osx.sh diff --git a/.travis.yml b/.travis.yml index 672d8ed52..50d63e593 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,11 +59,16 @@ env: # 64-bit GCC 4.8 Debug - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug -# TODO: OSX support -#matrix: -# include: -# - os: osx -# osx_image: xcode 8.2 +# macOS (a.k.a OSX) support +matrix: + include: + # For now just test a single configuration. macOS builds on TravisCI are + # very slow so we should keep the number of configurations we test on this + # OS to a minimum. + - os: osx + osx_image: xcode8.3 + # Note: Apple Clang does not support OpenMP + env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0 script: # Use `travis_wait` when doing LTO builds because this configuration will # have long link times during which it will not show any output which diff --git a/contrib/ci/scripts/install_deps_osx.sh b/contrib/ci/scripts/install_deps_osx.sh new file mode 100755 index 000000000..f9eb5a844 --- /dev/null +++ b/contrib/ci/scripts/install_deps_osx.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )" +. ${SCRIPT_DIR}/run_quiet.sh + +set -x +set -e +set -o pipefail + +run_quiet brew update +export HOMEBREW_NO_AUTO_UPDATE=1 + +function brew_install_or_upgrade() { + if brew ls --versions "$1" > /dev/null 2>&1 ; then + brew upgrade "$1" + else + brew install "$1" + fi +} + +# FIXME: We should fix the versions of dependencies used +# so that we have reproducible builds. + +# HACK: Just use CMake version in TravisCI for now +if [ "X${MACOS_UPDATE_CMAKE}" = "X1" ]; then + brew_install_or_upgrade cmake +fi + +if [ "X${Z3_CMAKE_GENERATOR}" = "XNinja" ]; then + brew_install_or_upgrade ninja +fi + +if [ "X${USE_LIBGMP}" = "X1" ]; then + brew_install_or_upgrade gmp +fi + +if [ "X${BUILD_DOCS}" = "X1" ]; then + brew_install_or_upgrade doxygen +fi + +if [ "X${DOTNET_BINDINGS}" = "X1" ]; then + brew_install_or_upgrade mono +fi + +if [ "X${JAVA_BINDINGS}" = "X1" ]; then + brew cask install java +fi diff --git a/contrib/ci/scripts/travis_ci_osx_entry_point.sh b/contrib/ci/scripts/travis_ci_osx_entry_point.sh index 03be81647..c5e8b4c02 100755 --- a/contrib/ci/scripts/travis_ci_osx_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_osx_entry_point.sh @@ -6,5 +6,67 @@ set -x set -e set -o pipefail -echo "Not implemented" -exit 1 +# Set defaults +# FIXME: Refactor this so we don't need to stay in sync with +# `z3_build.Dockerfile`. +export ASAN_BUILD="${ASAN_BUILD:-0}" +export BUILD_DOCS="${BUILD_DOCS:-0}" +export C_COMPILER="${C_COMPILER:-clang}" +export CXX_COMPILER="${CXX_COMPILER:-clang++}" +export DOTNET_BINDINGS="${DOTNET_BINDINGS:-1}" +export JAVA_BINDINGS="${JAVA_BINDINGS:-1}" +export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}" +export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}" +export PYTHON_EXECUTABLE="$(which python)" +export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}" +export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}" +export TARGET_ARCH="${TARGET_ARCH:-x86_64}" +export TEST_INSTALL="${TEST_INSTALL:-1}" +export UBSAN_BUILD="${UBSAN_BUILD:-0}" +export USE_LIBGMP="${USE_LIBGMP:-0}" +export USE_LTO="${USE_LTO:-0}" +export USE_OPENMP="${USE_OPENMP:-1}" + +if [ -z "${TRAVIS_BUILD_DIR}" ]; then + echo "TRAVIS_BUILD_DIR must be set to root of Z3 repository" + exit 1 +fi + +if [ ! -d "${TRAVIS_BUILD_DIR}" ]; then + echo "TRAVIS_BUILD_DIR must be a directory" + exit 1 +fi + +export Z3_SRC_DIR="${TRAVIS_BUILD_DIR}" +export Z3_BUILD_DIR="${Z3_SRC_DIR}/build" +export Z3_BUILD_TYPE="${Z3_BUILD_TYPE:-RelWithDebInfo}" +export Z3_CMAKE_GENERATOR="${Z3_CMAKE_GENERATOR:-Ninja}" +export Z3_INSTALL_PREFIX="${Z3_INSTALL_PREFIX:-/usr/local}" +export Z3_STATIC_BUILD="${Z3_STATIC_BUILD:-0}" +export Z3_SYSTEM_TEST_DIR="${Z3_SRC_DIR}/z3_system_test" +export Z3_WARNINGS_AS_ERRORS="${Z3_WARNINGS_AS_ERRORS:-SERIOUS_ONLY}" +export Z3_VERBOSE_BUILD_OUTPUT="${Z3_VERBOSE_BUILD_OUTPUT:-0}" + +# Overwrite whatever what set in TravisCI +export CC="${C_COMPILER}" +export CXX="${CXX_COMPILER}" + +if [ "X${MACOS_SKIP_DEPS_UPDATE}" = "X1" ]; then + # This is just for local testing to avoid updating + echo "Skipping dependency update" +else + "${SCRIPT_DIR}/install_deps_osx.sh" +fi + +# Build Z3 +"${SCRIPT_DIR}/build_z3_cmake.sh" +# Test building docs +"${SCRIPT_DIR}/test_z3_docs.sh" +# Test examples +"${SCRIPT_DIR}/test_z3_examples_cmake.sh" +# Run unit tests +"${SCRIPT_DIR}/test_z3_unit_tests_cmake.sh" +# Run system tests +"${SCRIPT_DIR}/test_z3_system_tests.sh" +# Test install +"${SCRIPT_DIR}/test_z3_install_cmake.sh" From f99048f3e7b802b2cdc06dcd121827ed7725602b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 12 Aug 2017 13:24:54 -0700 Subject: [PATCH 105/488] rewrite to address some cases like #1203, updates to division handling in NRA Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/arith_rewriter.cpp | 7 ++++ src/qe/nlqsat.cpp | 42 ++++++++++++------- src/qe/qsat.cpp | 18 ++++---- src/tactic/portfolio/smt_strategic_solver.cpp | 5 ++- 4 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 6d2e9dae1..18556b71b 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -755,6 +755,13 @@ br_status arith_rewriter::mk_mod_core(expr * arg1, expr * arg2, expr_ref & resul return BR_DONE; } + if (arg1 == arg2 && !m_util.is_numeral(arg2)) { + expr_ref zero(m_util.mk_int(0), m()), abs(m()); + mk_abs_core(arg2, abs); + result = m().mk_ite(m().mk_eq(arg2, zero), m_util.mk_mod(zero, zero), abs); + return BR_DONE; + } + // mod is idempotent on non-zero modulus. expr* t1, *t2; if (m_util.is_mod(arg1, t1, t2) && t2 == arg2 && m_util.is_numeral(arg2, v2, is_int) && is_int && !v2.is_zero()) { diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index 4f041cc41..0f2437982 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -18,22 +18,22 @@ Revision History: --*/ -#include "qe/nlqsat.h" -#include "nlsat/nlsat_solver.h" -#include "nlsat/nlsat_explain.h" -#include "nlsat/nlsat_assignment.h" -#include "qe/qsat.h" -#include "ast/rewriter/quant_hoist.h" -#include "nlsat/tactic/goal2nlsat.h" -#include "ast/expr2var.h" #include "util/uint_set.h" +#include "ast/expr2var.h" #include "ast/ast_util.h" -#include "tactic/core/tseitin_cnf_tactic.h" #include "ast/rewriter/expr_safe_replace.h" #include "ast/ast_pp.h" #include "ast/for_each_expr.h" #include "ast/rewriter/rewriter.h" #include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/quant_hoist.h" +#include "qe/nlqsat.h" +#include "qe/qsat.h" +#include "nlsat/nlsat_solver.h" +#include "nlsat/nlsat_explain.h" +#include "nlsat/nlsat_assignment.h" +#include "nlsat/tactic/goal2nlsat.h" +#include "tactic/core/tseitin_cnf_tactic.h" namespace qe { @@ -292,8 +292,8 @@ namespace qe { nlsat::var_vector vs; m_solver.vars(l, vs); TRACE("qe", m_solver.display(tout, l); tout << "\n";); - for (unsigned i = 0; i < vs.size(); ++i) { - level.merge(m_rvar2level[vs[i]]); + for (unsigned v : vs) { + level.merge(m_rvar2level[v]); } set_level(l.var(), level); return level; @@ -438,9 +438,10 @@ namespace qe { class div_rewriter_cfg : public default_rewriter_cfg { ast_manager& m; arith_util a; + expr_ref m_zero; vector
m_divs; public: - div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m) {} + div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m), m_zero(a.mk_real(0), m) {} ~div_rewriter_cfg() {} br_status reduce_app(func_decl* f, unsigned sz, expr* const* args, expr_ref& result, proof_ref& pr) { if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && !a.is_numeral(args[1])) { @@ -448,6 +449,11 @@ namespace qe { m_divs.push_back(div(m, args[0], args[1], to_app(result))); return BR_DONE; } + if (is_decl_of(f, a.get_family_id(), OP_DIV_0) && sz == 1 && !a.is_numeral(args[0])) { + result = m.mk_fresh_const("div", a.mk_real()); + m_divs.push_back(div(m, args[0], m_zero, to_app(result))); + return BR_DONE; + } return BR_FAILED; } vector
const& divs() const { return m_divs; } @@ -497,7 +503,11 @@ namespace qe { if (a.is_power(n, n1, n2) && a.is_numeral(n2, r) && r.is_unsigned()) { return; } - if (a.is_div(n, n1, n2) && s.m_mode == qsat_t) { + if (a.is_div(n) && s.m_mode == qsat_t) { + m_has_divs = true; + return; + } + if (a.is_div0(n) && s.m_mode == qsat_t) { m_has_divs = true; return; } @@ -539,7 +549,7 @@ namespace qe { app_ref_vector pvars(m); expr_ref_vector paxioms(m); purify(fml, pvars, paxioms); - if (pvars.empty()) { + if (paxioms.empty()) { return; } expr_ref ante = mk_and(paxioms); @@ -552,6 +562,7 @@ namespace qe { } } + void reset() { //m_solver.reset(); m_asms.reset(); @@ -618,10 +629,12 @@ namespace qe { app_ref_vector vars(m); bool is_forall = false; pred_abs abs(m); + abs.get_free_vars(fml, vars); insert_set(m_free_vars, vars); qvars.push_back(vars); vars.reset(); + if (m_mode == elim_t) { is_forall = true; hoist.pull_quantifier(is_forall, fml, vars); @@ -638,6 +651,7 @@ namespace qe { qvars.push_back(vars); } while (!vars.empty()); + SASSERT(qvars.size() >= 2); SASSERT(qvars.back().empty()); ackermanize_div(is_forall, qvars, fml); diff --git a/src/qe/qsat.cpp b/src/qe/qsat.cpp index abd396818..713ecfe77 100644 --- a/src/qe/qsat.cpp +++ b/src/qe/qsat.cpp @@ -20,23 +20,23 @@ Notes: --*/ -#include "smt/smt_kernel.h" -#include "qe/qe_mbp.h" -#include "smt/params/smt_params.h" +#include "ast/expr_abstract.h" #include "ast/ast_util.h" #include "ast/rewriter/quant_hoist.h" #include "ast/ast_pp.h" -#include "model/model_v2_pp.h" -#include "qe/qsat.h" -#include "ast/expr_abstract.h" -#include "qe/qe.h" -#include "ast/rewriter/label_rewriter.h" -#include "ast/rewriter/expr_replacer.h" #include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/expr_replacer.h" +#include "model/model_v2_pp.h" #include "model/model_evaluator.h" +#include "smt/smt_kernel.h" +#include "smt/params/smt_params.h" #include "smt/smt_solver.h" #include "solver/solver.h" #include "solver/mus.h" +#include "qe/qsat.h" +#include "qe/qe_mbp.h" +#include "qe/qe.h" +#include "ast/rewriter/label_rewriter.h" namespace qe { diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index fe1cf5260..bde9e0e98 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -31,14 +31,15 @@ Notes: #include "tactic/smtlogics/qfaufbv_tactic.h" #include "tactic/smtlogics/qfufbv_tactic.h" #include "tactic/smtlogics/qfidl_tactic.h" +#include "tactic/smtlogics/nra_tactic.h" #include "tactic/portfolio/default_tactic.h" +#include "tactic/portfolio/fd_solver.h" #include "tactic/ufbv/ufbv_tactic.h" #include "tactic/fpa/qffp_tactic.h" #include "tactic/smtlogics/qfufnra_tactic.h" #include "muz/fp/horn_tactic.h" #include "smt/smt_solver.h" #include "sat/sat_solver/inc_sat_solver.h" -#include "tactic/portfolio/fd_solver.h" #include "ast/rewriter/bv_rewriter.h" #include "solver/solver2tactic.h" @@ -78,6 +79,8 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const return mk_uflra_tactic(m, p); else if (logic=="LRA") return mk_lra_tactic(m, p); + else if (logic=="NRA") + return mk_nra_tactic(m, p); else if (logic=="LIA") return mk_lia_tactic(m, p); else if (logic=="UFBV") From 85cdfd885f383f1464e29705c7f6410695ed6839 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 12 Aug 2017 17:41:18 -0700 Subject: [PATCH 106/488] address bug reported in #1196 and include additional ad-hoc rewrites to handle some string cases Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 6fd492ae4..10159fcda 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -608,6 +608,7 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) { m_util.str.get_concat(a, as); m_util.str.get_concat(b, bs); bool all_values = true; + TRACE("seq", tout << mk_pp(a, m()) << " contains " << mk_pp(b, m()) << "\n";); if (bs.empty()) { result = m().mk_true(); @@ -652,6 +653,15 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) { return BR_REWRITE2; } + if (bs.size() == 1 && m_util.str.is_string(bs[0].get(), c)) { + for (auto a_i : as) { + if (m_util.str.is_string(a_i, d) && d.contains(c)) { + result = m().mk_true(); + return BR_DONE; + } + } + } + unsigned offs = 0; unsigned sz = as.size(); expr* b0 = bs[0].get(); From 50e9b371d91b48169776070453deba3266918dc7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 12 Aug 2017 17:52:58 -0700 Subject: [PATCH 107/488] inc version Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 10159fcda..581abdf1f 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -1952,6 +1952,7 @@ void seq_rewriter::split_units(expr_ref_vector& lhs, expr_ref_vector& rhs) { } + bool seq_rewriter::is_epsilon(expr* e) const { expr* e1; return m_util.re.is_to_re(e, e1) && m_util.str.is_empty(e1); From c4083c367a11e555e6d7665a40c658741bf2241e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 12 Aug 2017 19:14:55 -0700 Subject: [PATCH 108/488] update handling of contains constraints taking string literals into account Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 43 +++++++++++++++++++++++++++++-- src/ast/rewriter/seq_rewriter.h | 3 +++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 581abdf1f..5f405e013 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -597,6 +597,45 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu return BR_FAILED; } +bool seq_rewriter::cannot_contain_suffix(expr* a, expr* b) { + + if (m_util.str.is_unit(a) && m_util.str.is_unit(b) && m().are_distinct(a, b)) { + return true; + } + zstring A, B; + if (m_util.str.is_string(a, A) && m_util.str.is_string(b, B)) { + // some prefix of a is a suffix of b + bool found = false; + for (unsigned i = 1; !found && i <= A.length(); ++i) { + found = A.extract(0, i).suffixof(B); + } + return !found; + } + + return false; +} + + +bool seq_rewriter::cannot_contain_prefix(expr* a, expr* b) { + + if (m_util.str.is_unit(a) && m_util.str.is_unit(b) && m().are_distinct(a, b)) { + return true; + } + zstring A, B; + if (m_util.str.is_string(a, A) && m_util.str.is_string(b, B)) { + // some suffix of a is a prefix of b + bool found = false; + for (unsigned i = 0; !found && i < A.length(); ++i) { + found = A.extract(i, A.length()-i).suffixof(B); + } + return !found; + } + + return false; +} + + + br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) { zstring c, d; if (m_util.str.is_string(a, c) && m_util.str.is_string(b, d)) { @@ -666,8 +705,8 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) { unsigned sz = as.size(); expr* b0 = bs[0].get(); expr* bL = bs[bs.size()-1].get(); - for (; offs < as.size() && m_util.str.is_unit(b0) && m_util.str.is_unit(as[offs].get()) && m().are_distinct(b0, as[offs].get()); ++offs) {}; - for (; sz > offs && m_util.str.is_unit(bL) && m_util.str.is_unit(as[sz-1].get()) && m().are_distinct(bL, as[sz-1].get()); --sz) {} + for (; offs < as.size() && cannot_contain_prefix(as[offs].get(), b0); ++offs) {} + for (; sz > offs && cannot_contain_suffix(as[sz-1].get(), bL); --sz) {} if (offs == sz) { result = m().mk_eq(b, m_util.str.mk_empty(m().get_sort(b))); return BR_REWRITE2; diff --git a/src/ast/rewriter/seq_rewriter.h b/src/ast/rewriter/seq_rewriter.h index add941ddb..69f319168 100644 --- a/src/ast/rewriter/seq_rewriter.h +++ b/src/ast/rewriter/seq_rewriter.h @@ -122,6 +122,9 @@ class seq_rewriter { br_status mk_re_loop(unsigned num_args, expr* const* args, expr_ref& result); br_status mk_re_range(expr* lo, expr* hi, expr_ref& result); + bool cannot_contain_prefix(expr* a, expr* b); + bool cannot_contain_suffix(expr* a, expr* b); + bool set_empty(unsigned sz, expr* const* es, bool all, expr_ref_vector& lhs, expr_ref_vector& rhs); bool is_subsequence(unsigned n, expr* const* l, unsigned m, expr* const* r, expr_ref_vector& lhs, expr_ref_vector& rhs, bool& is_sat); From 347ea50b93cf3e66dbc004fba8fea804f1d53067 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 09:25:46 -0700 Subject: [PATCH 109/488] fix for #1202 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_str.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 6f3dabe2e..aacf17b30 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -8420,6 +8420,7 @@ namespace smt { // Check agreement between integer and string theories for the term a = (str.to-int S). // Returns true if axioms were added, and false otherwise. bool theory_str::finalcheck_str2int(app * a) { + SASSERT(u.str.is_stoi(a)); bool axiomAdd = false; context & ctx = get_context(); ast_manager & m = get_manager(); @@ -8446,7 +8447,10 @@ namespace smt { } } else { TRACE("str", tout << "integer theory has no assignment for " << mk_pp(a, m) << std::endl;); - NOT_IMPLEMENTED_YET(); + expr_ref is_zero(ctx.mk_eq_atom(a, m_autil.mk_int(0)), m); + literal is_zero_l = mk_literal(is_zero); + axiomAdd = true; + // NOT_IMPLEMENTED_YET(); } return axiomAdd; From 19bb55e396d0414e61cdc496ec8d32d08eb9d8a3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 10:22:36 -0700 Subject: [PATCH 110/488] recognize theory_i_arith to fix #1200 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_seq.cpp | 103 ++++++++++++++++++++++++++++----------- src/util/scoped_vector.h | 4 +- 2 files changed, 76 insertions(+), 31 deletions(-) diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 14ee3b073..1d3ab47bb 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -18,6 +18,7 @@ Revision History: --*/ +#include #include "smt/proto_model/value_factory.h" #include "smt/smt_context.h" #include "smt/smt_model_generator.h" @@ -275,7 +276,22 @@ final_check_status theory_seq::final_check_eh() { TRACE("seq", tout << ">>int_string\n";); return FC_CONTINUE; } - if (reduce_length_eq() || branch_unit_variable() || branch_binary_variable() || branch_variable_mb() || branch_variable()) { + if (reduce_length_eq()) { + ++m_stats.m_branch_variable; + TRACE("seq", tout << ">>reduce length\n";); + return FC_CONTINUE; + } + if (branch_unit_variable()) { + ++m_stats.m_branch_variable; + TRACE("seq", tout << ">>branch_unit_variable\n";); + return FC_CONTINUE; + } + if (branch_binary_variable() || branch_variable_mb()) { + ++m_stats.m_branch_variable; + TRACE("seq", tout << ">>branch_variable\n";); + return FC_CONTINUE; + } + if (branch_variable()) { ++m_stats.m_branch_variable; TRACE("seq", tout << ">>branch_variable\n";); return FC_CONTINUE; @@ -318,10 +334,9 @@ bool theory_seq::reduce_length_eq() { } bool theory_seq::branch_binary_variable() { - unsigned sz = m_eqs.size(); - for (unsigned i = 0; i < sz; ++i) { - eq const& e = m_eqs[i]; + for (eq const& e : m_eqs) { if (branch_binary_variable(e)) { + TRACE("seq", display_equation(tout, e);); return true; } } @@ -399,19 +414,21 @@ bool theory_seq::branch_binary_variable(eq const& e) { } bool theory_seq::branch_unit_variable() { - unsigned sz = m_eqs.size(); - for (unsigned i = 0; i < sz; ++i) { - eq const& e = m_eqs[i]; + bool result = false; + for (eq const& e : m_eqs) { if (is_unit_eq(e.ls(), e.rs())) { branch_unit_variable(e.dep(), e.ls()[0], e.rs()); - return true; + result = true; + break; } else if (is_unit_eq(e.rs(), e.ls())) { branch_unit_variable(e.dep(), e.rs()[0], e.ls()); - return true; + result = true; + break; } } - return false; + CTRACE("seq", result, "branch unit variable";); + return result; } /** @@ -434,17 +451,20 @@ void theory_seq::branch_unit_variable(dependency* dep, expr* X, expr_ref_vector context& ctx = get_context(); rational lenX; if (!get_length(X, lenX)) { + TRACE("seq", tout << "enforce length on " << mk_pp(X, m) << "\n";); enforce_length(ensure_enode(X)); return; } if (lenX > rational(units.size())) { expr_ref le(m_autil.mk_le(m_util.str.mk_length(X), m_autil.mk_int(units.size())), m); + TRACE("seq", tout << "propagate length on " << mk_pp(X, m) << "\n";); propagate_lit(dep, 0, 0, mk_literal(le)); return; } SASSERT(lenX.is_unsigned()); unsigned lX = lenX.get_unsigned(); if (lX == 0) { + TRACE("seq", tout << "set empty length " << mk_pp(X, m) << "\n";); set_empty(X); } else { @@ -454,8 +474,10 @@ void theory_seq::branch_unit_variable(dependency* dep, expr* X, expr_ref_vector literal_vector lits; lits.push_back(lit); propagate_eq(dep, lits, X, R, true); + TRACE("seq", tout << "propagate " << mk_pp(X, m) << " " << R << "\n";); } else { + TRACE("seq", tout << "set phase " << mk_pp(X, m) << "\n";); ctx.mark_as_relevant(lit); ctx.force_phase(lit); } @@ -494,9 +516,11 @@ bool theory_seq::branch_variable_mb() { } if (split_lengths(e.dep(), e.ls(), e.rs(), len1, len2)) { TRACE("seq", tout << "split lengths\n";); - return true; + change = true; + break; } } + TRACE("seq", tout << "branch_variable_mb\n";); return change; } @@ -651,6 +675,7 @@ bool theory_seq::branch_variable() { eq const& e = m_eqs[k]; if (branch_variable(e)) { + TRACE("seq", tout << "branch variable\n";); return true; } @@ -1577,6 +1602,7 @@ bool theory_seq::reduce_length_eq(expr_ref_vector const& ls, expr_ref_vector con len2 += len; } if (len1 == len2 && 0 < j && j < rs.size() && reduce_length(1, j, true, ls, rs, deps)) { + TRACE("seq", tout << "l equal\n";); return true; } } @@ -1586,6 +1612,7 @@ bool theory_seq::reduce_length_eq(expr_ref_vector const& ls, expr_ref_vector con len2 += len; } if (len1 == len2 && 0 < j && j < ls.size() && reduce_length(j, 1, true, ls, rs, deps)) { + TRACE("seq", tout << "r equal\n";); return true; } } @@ -1595,6 +1622,7 @@ bool theory_seq::reduce_length_eq(expr_ref_vector const& ls, expr_ref_vector con len2 += len; } if (len1 == len2 && 0 < j && j < rs.size() && reduce_length(ls.size()-1, rs.size()-j, false, ls, rs, deps)) { + TRACE("seq", tout << "l suffix equal\n";); return true; } } @@ -1604,6 +1632,7 @@ bool theory_seq::reduce_length_eq(expr_ref_vector const& ls, expr_ref_vector con len2 += len; } if (len1 == len2 && 0 < j && j < ls.size() && reduce_length(ls.size()-j, rs.size()-1, false, ls, rs, deps)) { + TRACE("seq", tout << "r suffix equal\n";); return true; } } @@ -1641,6 +1670,7 @@ bool theory_seq::reduce_length(unsigned i, unsigned j, bool front, expr_ref_vect deps = mk_join(deps, lit); m_eqs.push_back(eq(m_eq_id++, lhs, rhs, deps)); propagate_eq(deps, lits, l, r, true); + TRACE("seq", tout << "propagate eq\nlhs: " << lhs << "\nrhs: " << rhs << "\n";); return true; } else { @@ -2510,8 +2540,8 @@ void theory_seq::display_nc(std::ostream& out, nc const& nc) const { } void theory_seq::display_equations(std::ostream& out) const { - for (unsigned i = 0; i < m_eqs.size(); ++i) { - display_equation(out, m_eqs[i]); + for (eq const& e : m_eqs) { + display_equation(out, e); } } @@ -2522,10 +2552,10 @@ void theory_seq::display_equation(std::ostream& out, eq const& e) const { void theory_seq::display_disequations(std::ostream& out) const { bool first = true; - for (unsigned i = 0; i < m_nqs.size(); ++i) { + for (ne const& n : m_nqs) { if (first) out << "Disequations:\n"; first = false; - display_disequation(out, m_nqs[i]); + display_disequation(out, n); } } @@ -3406,24 +3436,32 @@ enode* theory_seq::ensure_enode(expr* e) { return n; } -static theory_mi_arith* get_th_arith(context& ctx, theory_id afid, expr* e) { +template +static T* get_th_arith(context& ctx, theory_id afid, expr* e) { theory* th = ctx.get_theory(afid); if (th && ctx.e_internalized(e)) { - return dynamic_cast(th); + return dynamic_cast(th); } else { return 0; } } +static bool get_arith_value(context& ctx, theory_id afid, expr* e, expr_ref& v) { + theory_mi_arith* tha = get_th_arith(ctx, afid, e); + if (tha) return tha->get_value(ctx.get_enode(e), v); + theory_i_arith* thi = get_th_arith(ctx, afid, e); + if (thi) return thi->get_value(ctx.get_enode(e), v); + TRACE("seq", tout << "no arithmetic theory\n";); + return false; +} + bool theory_seq::get_num_value(expr* e, rational& val) const { context& ctx = get_context(); - theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e); expr_ref _val(m); - if (!tha) return false; enode* next = ctx.get_enode(e), *n = next; do { - if (tha->get_value(next, _val) && m_autil.is_numeral(_val, val) && val.is_int()) { + if (get_arith_value(ctx, m_autil.get_family_id(), next->get_owner(), _val) && m_autil.is_numeral(_val, val) && val.is_int()) { return true; } next = next->get_next(); @@ -3435,27 +3473,31 @@ bool theory_seq::get_num_value(expr* e, rational& val) const { bool theory_seq::lower_bound(expr* _e, rational& lo) const { context& ctx = get_context(); expr_ref e(m_util.str.mk_length(_e), m); - theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e); expr_ref _lo(m); - if (!tha || !tha->get_lower(ctx.get_enode(e), _lo)) return false; + theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e); + if (tha && !tha->get_lower(ctx.get_enode(e), _lo)) return false; + if (!tha) { + theory_i_arith* thi = get_th_arith(ctx, m_autil.get_family_id(), e); + if (!thi || !thi->get_lower(ctx.get_enode(e), _lo)) return false; + } return m_autil.is_numeral(_lo, lo) && lo.is_int(); } bool theory_seq::upper_bound(expr* _e, rational& hi) const { context& ctx = get_context(); expr_ref e(m_util.str.mk_length(_e), m); - theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e); + theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e); expr_ref _hi(m); - if (!tha || !tha->get_upper(ctx.get_enode(e), _hi)) return false; + if (tha && !tha->get_upper(ctx.get_enode(e), _hi)) return false; + if (!tha) { + theory_i_arith* thi = get_th_arith(ctx, m_autil.get_family_id(), e); + if (!thi || !thi->get_upper(ctx.get_enode(e), _hi)) return false; + } return m_autil.is_numeral(_hi, hi) && hi.is_int(); } bool theory_seq::get_length(expr* e, rational& val) const { context& ctx = get_context(); - theory* th = ctx.get_theory(m_autil.get_family_id()); - if (!th) return false; - theory_mi_arith* tha = dynamic_cast(th); - if (!tha) return false; rational val1; expr_ref len(m), len_val(m); expr* e1 = 0, *e2 = 0; @@ -3480,20 +3522,23 @@ bool theory_seq::get_length(expr* e, rational& val) const { val += rational(s.length()); } else if (!has_length(c)) { + TRACE("seq", tout << "literal has no length " << mk_pp(c, m) << "\n";); return false; } else { len = m_util.str.mk_length(c); if (ctx.e_internalized(len) && - tha->get_value(ctx.get_enode(len), len_val) && + get_arith_value(ctx, m_autil.get_family_id(), len, len_val) && m_autil.is_numeral(len_val, val1)) { val += val1; } else { + TRACE("seq", tout << "length has not been internalized " << mk_pp(c, m) << "\n";); return false; } } } + CTRACE("seq", !val.is_int(), "length is not an integer\n";); return val.is_int(); } diff --git a/src/util/scoped_vector.h b/src/util/scoped_vector.h index d4c5301e6..5935ab6fa 100644 --- a/src/util/scoped_vector.h +++ b/src/util/scoped_vector.h @@ -113,8 +113,8 @@ public: } }; - iterator begin() { return iterator(*this, 0); } - iterator end() { return iterator(*this, m_size); } + iterator begin() const { return iterator(*this, 0); } + iterator end() const { return iterator(*this, m_size); } void push_back(T const& t) { set_index(m_size, m_elems.size()); From 00742566fbf2eb6675241d8571283ec3b1232963 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 13:40:30 -0700 Subject: [PATCH 111/488] address inconsistent states encountered when cancelling, #1197 Signed-off-by: Nikolaj Bjorner --- src/smt/smt_context.cpp | 170 ++++++++++++++++++------------------ src/smt/smt_context.h | 10 +-- src/smt/theory_arith_aux.h | 6 +- src/smt/theory_arith_core.h | 10 ++- 4 files changed, 99 insertions(+), 97 deletions(-) diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 52b21dd80..42e382790 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -128,6 +128,10 @@ namespace smt { return literal(v, lit.sign()); } + bool context::get_cancel_flag() { + return !m_manager.limit().inc(); + } + void context::copy(context& src_ctx, context& dst_ctx) { ast_manager& dst_m = dst_ctx.get_manager(); @@ -235,10 +239,8 @@ namespace smt { } // copy theory plugins - ptr_vector::iterator it2 = src.m_theory_set.begin(); - ptr_vector::iterator end2 = src.m_theory_set.end(); - for (; it2 != end2; ++it2) { - theory * new_th = (*it2)->mk_fresh(&dst); + for (theory* old_th : src.m_theory_set) { + theory * new_th = old_th->mk_fresh(&dst); dst.register_plugin(new_th); } } @@ -248,9 +250,7 @@ namespace smt { new_ctx->set_logic(l == 0 ? m_setup.get_logic() : *l); copy_plugins(*this, *new_ctx); return new_ctx; - } - - + } void context::init() { app * t = m_manager.mk_true(); @@ -2403,81 +2403,86 @@ namespace smt { */ unsigned context::pop_scope_core(unsigned num_scopes) { - if (m_manager.has_trace_stream()) - m_manager.trace_stream() << "[pop] " << num_scopes << " " << m_scope_lvl << "\n"; - - TRACE("context", tout << "backtracking: " << num_scopes << " from " << m_scope_lvl << "\n";); - TRACE("pop_scope_detail", display(tout);); - SASSERT(num_scopes > 0); - SASSERT(num_scopes <= m_scope_lvl); - SASSERT(m_scopes.size() == m_scope_lvl); - - unsigned new_lvl = m_scope_lvl - num_scopes; - - cache_generation(new_lvl); - m_qmanager->pop(num_scopes); - m_case_split_queue->pop_scope(num_scopes); - - TRACE("pop_scope", tout << "backtracking: " << num_scopes << ", new_lvl: " << new_lvl << "\n";); - scope & s = m_scopes[new_lvl]; - TRACE("context", tout << "backtracking new_lvl: " << new_lvl << "\n";); - - unsigned units_to_reassert_lim = s.m_units_to_reassert_lim; - - if (new_lvl < m_base_lvl) { - base_scope & bs = m_base_scopes[new_lvl]; - del_clauses(m_lemmas, bs.m_lemmas_lim); - m_simp_qhead = bs.m_simp_qhead_lim; - if (!bs.m_inconsistent) { - m_conflict = null_b_justification; - m_not_l = null_literal; - m_unsat_proof = 0; + try { + if (m_manager.has_trace_stream()) + m_manager.trace_stream() << "[pop] " << num_scopes << " " << m_scope_lvl << "\n"; + + TRACE("context", tout << "backtracking: " << num_scopes << " from " << m_scope_lvl << "\n";); + TRACE("pop_scope_detail", display(tout);); + SASSERT(num_scopes > 0); + SASSERT(num_scopes <= m_scope_lvl); + SASSERT(m_scopes.size() == m_scope_lvl); + + unsigned new_lvl = m_scope_lvl - num_scopes; + + cache_generation(new_lvl); + m_qmanager->pop(num_scopes); + m_case_split_queue->pop_scope(num_scopes); + + TRACE("pop_scope", tout << "backtracking: " << num_scopes << ", new_lvl: " << new_lvl << "\n";); + scope & s = m_scopes[new_lvl]; + TRACE("context", tout << "backtracking new_lvl: " << new_lvl << "\n";); + + unsigned units_to_reassert_lim = s.m_units_to_reassert_lim; + + if (new_lvl < m_base_lvl) { + base_scope & bs = m_base_scopes[new_lvl]; + del_clauses(m_lemmas, bs.m_lemmas_lim); + m_simp_qhead = bs.m_simp_qhead_lim; + if (!bs.m_inconsistent) { + m_conflict = null_b_justification; + m_not_l = null_literal; + m_unsat_proof = 0; + } + m_base_scopes.shrink(new_lvl); } - m_base_scopes.shrink(new_lvl); - } - else { - m_conflict = null_b_justification; - m_not_l = null_literal; + else { + m_conflict = null_b_justification; + m_not_l = null_literal; + } + del_clauses(m_aux_clauses, s.m_aux_clauses_lim); + + m_relevancy_propagator->pop(num_scopes); + + m_fingerprints.pop_scope(num_scopes); + unassign_vars(s.m_assigned_literals_lim); + undo_trail_stack(s.m_trail_stack_lim); + + for (theory* th : m_theory_set) { + th->pop_scope_eh(num_scopes); + } + + del_justifications(m_justifications, s.m_justifications_lim); + + m_asserted_formulas.pop_scope(num_scopes); + + m_eq_propagation_queue.reset(); + m_th_eq_propagation_queue.reset(); + m_th_diseq_propagation_queue.reset(); + m_atom_propagation_queue.reset(); + + m_region.pop_scope(num_scopes); + m_scopes.shrink(new_lvl); + + m_scope_lvl = new_lvl; + if (new_lvl < m_base_lvl) { + m_base_lvl = new_lvl; + m_search_lvl = new_lvl; // Remark: not really necessary + } + + unsigned num_bool_vars = get_num_bool_vars(); + // any variable >= num_bool_vars was deleted during backtracking. + reinit_clauses(num_scopes, num_bool_vars); + reassert_units(units_to_reassert_lim); + TRACE("pop_scope_detail", tout << "end of pop_scope: \n"; display(tout);); + CASSERT("context", check_invariant()); + return num_bool_vars; } - del_clauses(m_aux_clauses, s.m_aux_clauses_lim); - - m_relevancy_propagator->pop(num_scopes); - - m_fingerprints.pop_scope(num_scopes); - unassign_vars(s.m_assigned_literals_lim); - undo_trail_stack(s.m_trail_stack_lim); - - ptr_vector::iterator it = m_theory_set.begin(); - ptr_vector::iterator end = m_theory_set.end(); - for (; it != end; ++it) { - (*it)->pop_scope_eh(num_scopes); + catch (...) { + // throwing inside pop is just not cool. + UNREACHABLE(); + throw; } - - del_justifications(m_justifications, s.m_justifications_lim); - - m_asserted_formulas.pop_scope(num_scopes); - - m_eq_propagation_queue.reset(); - m_th_eq_propagation_queue.reset(); - m_th_diseq_propagation_queue.reset(); - m_atom_propagation_queue.reset(); - - m_region.pop_scope(num_scopes); - m_scopes.shrink(new_lvl); - - m_scope_lvl = new_lvl; - if (new_lvl < m_base_lvl) { - m_base_lvl = new_lvl; - m_search_lvl = new_lvl; // Remark: not really necessary - } - - unsigned num_bool_vars = get_num_bool_vars(); - // any variable >= num_bool_vars was deleted during backtracking. - reinit_clauses(num_scopes, num_bool_vars); - reassert_units(units_to_reassert_lim); - TRACE("pop_scope_detail", tout << "end of pop_scope: \n"; display(tout);); - CASSERT("context", check_invariant()); - return num_bool_vars; } void context::pop_scope(unsigned num_scopes) { @@ -3418,10 +3423,9 @@ namespace smt { } void context::init_search() { - ptr_vector::iterator it = m_theory_set.begin(); - ptr_vector::iterator end = m_theory_set.end(); - for (; it != end; ++it) - (*it)->init_search_eh(); + for (theory* th : m_theory_set) { + th->init_search_eh(); + } m_qmanager->init_search_eh(); m_assumption_core.reset(); m_incomplete_theories.reset(); diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index 1aa3b385b..fecb42700 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -257,15 +257,7 @@ namespace smt { return m_params; } - bool get_cancel_flag() { - if (m_manager.limit().inc()) { - // get_simplifier().reset(); - return false; - } - else { - return true; - } - } + bool get_cancel_flag(); region & get_region() { return m_region; diff --git a/src/smt/theory_arith_aux.h b/src/smt/theory_arith_aux.h index f0f80b4ec..a1558e5e5 100644 --- a/src/smt/theory_arith_aux.h +++ b/src/smt/theory_arith_aux.h @@ -2106,6 +2106,7 @@ namespace smt { template void theory_arith::mutate_assignment() { + SASSERT(m_to_patch.empty()); remove_fixed_vars_from_base(); int num_vars = get_num_vars(); m_var_value_table.reset(); @@ -2131,12 +2132,9 @@ namespace smt { } if (candidates.empty()) return; - typename sbuffer::iterator it = candidates.begin(); - typename sbuffer::iterator end = candidates.end(); m_tmp_var_set.reset(); m_tmp_var_set2.reset(); - for (; it != end; ++it) { - theory_var v = *it; + for (theory_var v : candidates) { SASSERT(!is_fixed(v)); if (is_base(v)) { row & r = m_rows[get_var_row(v)]; diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index e10395d31..a30e51133 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -449,6 +449,7 @@ namespace smt { proof_ref pr(m); s(ante, s_ante, pr); + if (ctx.get_cancel_flag()) return; negated = m.is_not(s_ante, s_ante_n); if (negated) s_ante = s_ante_n; ctx.internalize(s_ante, false); @@ -456,6 +457,7 @@ namespace smt { if (negated) l_ante.neg(); s(conseq, s_conseq, pr); + if (ctx.get_cancel_flag()) return; negated = m.is_not(s_conseq, s_conseq_n); if (negated) s_conseq = s_conseq_n; ctx.internalize(s_conseq, false); @@ -1413,6 +1415,12 @@ namespace smt { final_check_status result = FC_DONE; final_check_status ok; do { + if (get_context().get_cancel_flag()) { + return FC_GIVEUP; + } + + SASSERT(m_to_patch.empty()); + TRACE("arith", tout << "m_final_check_idx: " << m_final_check_idx << ", result: " << result << "\n";); switch (m_final_check_idx) { case 0: @@ -2307,7 +2315,7 @@ namespace smt { return false; } TRACE("arith_make_feasible_detail", display(tout);); - if (get_context().get_cancel_flag()) { + if (get_context().get_cancel_flag()) { return true; } } From b6cc24faf3369da9927bd7f3fd857643847b7a14 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 14:24:56 -0700 Subject: [PATCH 112/488] deal with absence of integer congruence root by querying arithmetic theory directly, #1202 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_str.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index aacf17b30..5eabc5d62 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -4656,7 +4656,7 @@ namespace smt { // safety if (!ctx.e_internalized(e)) { - return false; + return false; } // if an integer constant exists in the eqc, it should be the root @@ -4667,6 +4667,10 @@ namespace smt { return true; } else { TRACE("str", tout << "root of eqc of " << mk_pp(e, m) << " is not a numeral" << std::endl;); + theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e); + if (!tha) return false; + expr_ref val_e(m); + if (tha->get_value(root_e, val_e) && m_autil.is_numeral(val_e, val) && val.is_int()) return true; return false; } } @@ -8450,6 +8454,7 @@ namespace smt { expr_ref is_zero(ctx.mk_eq_atom(a, m_autil.mk_int(0)), m); literal is_zero_l = mk_literal(is_zero); axiomAdd = true; + TRACE("str", ctx.display(tout);); // NOT_IMPLEMENTED_YET(); } From 893bcbb5852a128cf05a467c13e11a85b9cf9f5f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 14:39:37 -0700 Subject: [PATCH 113/488] revert unsound change in integer extraction from expressions Signed-off-by: Nikolaj Bjorner --- src/smt/theory_str.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 5eabc5d62..052fd705f 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -4667,6 +4667,7 @@ namespace smt { return true; } else { TRACE("str", tout << "root of eqc of " << mk_pp(e, m) << " is not a numeral" << std::endl;); + return false; theory_mi_arith* tha = get_th_arith(ctx, m_autil.get_family_id(), e); if (!tha) return false; expr_ref val_e(m); From ead704f52f9baa7ffcebed640b9b74d95a6f4eef Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 17:13:10 -0700 Subject: [PATCH 114/488] handle undefined constant cases for int.to.str Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 16 +++++++++++++--- src/smt/theory_seq.cpp | 12 ++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 5f405e013..66df08452 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -1082,9 +1082,19 @@ br_status seq_rewriter::mk_str_stoi(expr* a, expr_ref& result) { if (m_util.str.is_string(a, str)) { std::string s = str.encode(); for (unsigned i = 0; i < s.length(); ++i) { - if (s[i] == '-') { if (i != 0) return BR_FAILED; } - else if ('0' <= s[i] && s[i] <= '9') continue; - return BR_FAILED; + if (s[i] == '-') { + if (i != 0) { + result = m_autil.mk_int(-1); + return BR_DONE; + } + } + else if ('0' <= s[i] && s[i] <= '9') { + continue; + } + else { + result = m_autil.mk_int(-1); + return BR_DONE; + } } rational r(s.c_str()); result = m_autil.mk_numeral(r, true); diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 1d3ab47bb..bbd11b4bf 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -520,7 +520,7 @@ bool theory_seq::branch_variable_mb() { break; } } - TRACE("seq", tout << "branch_variable_mb\n";); + CTRACE("seq", change, tout << "branch_variable_mb\n";); return change; } @@ -2348,7 +2348,14 @@ bool theory_seq::add_stoi_axiom(expr* e) { rational val; TRACE("seq", tout << mk_pp(e, m) << "\n";); VERIFY(m_util.str.is_stoi(e, n)); - if (get_num_value(e, val) && !m_stoi_axioms.contains(val)) { + if (!get_num_value(e, val)) { + literal l = mk_literal(m_autil.mk_ge(e, arith_util(m).mk_int(-1))); + add_axiom(l); + TRACE("seq", tout << l << " " << ctx.get_assignment(l) << "\n"; + ctx.display(tout);); + return true; + } + if (!m_stoi_axioms.contains(val)) { m_stoi_axioms.insert(val); if (!val.is_minus_one()) { app_ref e1(m_util.str.mk_string(symbol(val.to_string().c_str())), m); @@ -3467,6 +3474,7 @@ bool theory_seq::get_num_value(expr* e, rational& val) const { next = next->get_next(); } while (next != n); + TRACE("seq", tout << "no value for " << mk_pp(e, m) << "\n";); return false; } From fb17362dffdfe270c9a20e0397d01357e4b394dd Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 17:21:38 -0700 Subject: [PATCH 115/488] fix string rewriting according to definition. Relates to examples in #1202 Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 66df08452..533d9f09f 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -1072,26 +1072,27 @@ br_status seq_rewriter::mk_seq_suffix(expr* a, expr* b, expr_ref& result) { br_status seq_rewriter::mk_str_itos(expr* a, expr_ref& result) { rational r; if (m_autil.is_numeral(a, r)) { - result = m_util.str.mk_string(symbol(r.to_string().c_str())); + if (r.is_int() && !r.is_neg()) { + result = m_util.str.mk_string(symbol(r.to_string().c_str())); + } + else { + result = m_util.str.mk_string(symbol("")); + } return BR_DONE; } return BR_FAILED; } + br_status seq_rewriter::mk_str_stoi(expr* a, expr_ref& result) { zstring str; if (m_util.str.is_string(a, str)) { std::string s = str.encode(); + if (s.length() == 0) { + result = m_autil.mk_int(-1); + return BR_DONE; + } for (unsigned i = 0; i < s.length(); ++i) { - if (s[i] == '-') { - if (i != 0) { - result = m_autil.mk_int(-1); - return BR_DONE; - } - } - else if ('0' <= s[i] && s[i] <= '9') { - continue; - } - else { + if (!('0' <= s[i] && s[i] <= '9')) { result = m_autil.mk_int(-1); return BR_DONE; } From a39b0b201add137f48dcd13f618e584bdbb58f1d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 13 Aug 2017 17:27:34 -0700 Subject: [PATCH 116/488] another fix to str.to.int/int.to.str semantics Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 533d9f09f..fc38f0ae4 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -1103,7 +1103,7 @@ br_status seq_rewriter::mk_str_stoi(expr* a, expr_ref& result) { } expr* b; if (m_util.str.is_itos(a, b)) { - result = b; + result = m().mk_ite(m_autil.mk_ge(b, m_autil.mk_int(0)), b, m_autil.mk_int(-1)); return BR_DONE; } return BR_FAILED; From 07bc19b489c61ac2e416ea8d0bd9d0575383500a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 14 Aug 2017 07:19:04 -0700 Subject: [PATCH 117/488] add documentation to string rewriting Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index fc38f0ae4..36a99c592 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -1083,6 +1083,16 @@ br_status seq_rewriter::mk_str_itos(expr* a, expr_ref& result) { return BR_FAILED; } +/** + \brief rewrite str.to.int according to the rules: + - if the expression is a string which is a non-empty + sequence of digits 0-9 extract the corresponding numeral. + - if the expression is a string that contains any other character + or is empty, produce -1 + - if the expression is int.to.str(x) produce + ite(x >= 0, x, -1) + +*/ br_status seq_rewriter::mk_str_stoi(expr* a, expr_ref& result) { zstring str; if (m_util.str.is_string(a, str)) { From 9dc332ae9d4e1650af47daafe9821bbd8a2edf59 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 14 Aug 2017 17:35:51 +0100 Subject: [PATCH 118/488] [TravisCI] Temporarily disable the macOS build configuration. @wintersteiger is concerned there might be legal issues using TravisCI's macOS infrastructure. For context see: https://github.com/Z3Prover/z3/pull/1207#issuecomment-322200998 --- .travis.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 50d63e593..3764f8dac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,15 +60,17 @@ env: - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug # macOS (a.k.a OSX) support -matrix: - include: - # For now just test a single configuration. macOS builds on TravisCI are - # very slow so we should keep the number of configurations we test on this - # OS to a minimum. - - os: osx - osx_image: xcode8.3 - # Note: Apple Clang does not support OpenMP - env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0 +# FIXME: macOS support is temporarily disabled due to @wintersteiger 's concerns. +# See https://github.com/Z3Prover/z3/pull/1207#issuecomment-322200998 +# matrix: +# include: +# # For now just test a single configuration. macOS builds on TravisCI are +# # very slow so we should keep the number of configurations we test on this +# # OS to a minimum. +# - os: osx +# osx_image: xcode8.3 +# # Note: Apple Clang does not support OpenMP +# env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0 script: # Use `travis_wait` when doing LTO builds because this configuration will # have long link times during which it will not show any output which From 2473c6967921ce4c22ffecc2b3d74c37f7dc0130 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 14 Aug 2017 20:09:49 +0100 Subject: [PATCH 119/488] Drop no-strict-aliasing and fix 2 places where it was violated --- CMakeLists.txt | 4 ---- scripts/mk_util.py | 8 +++---- src/ast/ast.cpp | 8 +++---- src/ast/ast.h | 24 ++++++++++----------- src/util/optional.h | 51 ++++++++++++++++++++++++--------------------- 5 files changed, 46 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3ed2a312..715679957 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,22 +234,18 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_USE_THREAD_LOCAL") endif() - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") # Does OSX really not need any special flags? message(STATUS "Platform: Darwin") elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") message(STATUS "Platform: FreeBSD") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_FREEBSD_") - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") message(STATUS "Platform: OpenBSD") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_OPENBSD_") - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif (CYGWIN) message(STATUS "Platform: Cygwin") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_CYGWIN") - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif (WIN32) message(STATUS "Platform: Windows") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_WINDOWS") diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d2e3d6b4c..24f22d8ee 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2443,26 +2443,26 @@ def mk_config(): SO_EXT = '.dylib' SLIBFLAGS = '-dynamiclib' elif sysname == 'Linux': - CXXFLAGS = '%s -fno-strict-aliasing -D_LINUX_' % CXXFLAGS + CXXFLAGS = '%s -D_LINUX_' % CXXFLAGS OS_DEFINES = '-D_LINUX_' SO_EXT = '.so' LDFLAGS = '%s -lrt' % LDFLAGS SLIBFLAGS = '-shared' SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS elif sysname == 'FreeBSD': - CXXFLAGS = '%s -fno-strict-aliasing -D_FREEBSD_' % CXXFLAGS + CXXFLAGS = '%s -D_FREEBSD_' % CXXFLAGS OS_DEFINES = '-D_FREEBSD_' SO_EXT = '.so' LDFLAGS = '%s -lrt' % LDFLAGS SLIBFLAGS = '-shared' SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS elif sysname == 'OpenBSD': - CXXFLAGS = '%s -fno-strict-aliasing -D_OPENBSD_' % CXXFLAGS + CXXFLAGS = '%s -D_OPENBSD_' % CXXFLAGS OS_DEFINES = '-D_OPENBSD_' SO_EXT = '.so' SLIBFLAGS = '-shared' elif sysname[:6] == 'CYGWIN': - CXXFLAGS = '%s -D_CYGWIN -fno-strict-aliasing' % CXXFLAGS + CXXFLAGS = '%s -D_CYGWIN' % CXXFLAGS OS_DEFINES = '-D_CYGWIN' SO_EXT = '.dll' SLIBFLAGS = '-shared' diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index a1efed19e..43748bd42 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -35,7 +35,7 @@ Revision History: parameter::~parameter() { if (m_kind == PARAM_RATIONAL) { - reinterpret_cast(m_rational)->~rational(); + m_rational.~rational(); } } @@ -50,14 +50,14 @@ parameter& parameter::operator=(parameter const& other) { return *this; } if (m_kind == PARAM_RATIONAL) { - reinterpret_cast(m_rational)->~rational(); + m_rational.~rational(); } m_kind = other.m_kind; switch(other.m_kind) { case PARAM_INT: m_int = other.get_int(); break; case PARAM_AST: m_ast = other.get_ast(); break; - case PARAM_SYMBOL: new (m_symbol) symbol(other.get_symbol()); break; - case PARAM_RATIONAL: new (m_rational) rational(other.get_rational()); break; + case PARAM_SYMBOL: m_symbol = other.get_symbol(); break; + case PARAM_RATIONAL: m_rational = other.get_rational(); break; case PARAM_DOUBLE: m_dval = other.m_dval; break; case PARAM_EXTERNAL: m_ext_id = other.m_ext_id; break; default: diff --git a/src/ast/ast.h b/src/ast/ast.h index 3a3f08df2..64122a7dc 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -100,12 +100,12 @@ private: // It is not possible to use tag pointers, since symbols are already tagged. union { - int m_int; // for PARAM_INT - ast* m_ast; // for PARAM_AST - char m_symbol[sizeof(symbol)]; // for PARAM_SYMBOL - char m_rational[sizeof(rational)]; // for PARAM_RATIONAL - double m_dval; // for PARAM_DOUBLE (remark: this is not used in float_decl_plugin) - unsigned m_ext_id; // for PARAM_EXTERNAL + int m_int; // for PARAM_INT + ast* m_ast; // for PARAM_AST + symbol m_symbol; // for PARAM_SYMBOL + rational m_rational; // for PARAM_RATIONAL + double m_dval; // for PARAM_DOUBLE (remark: this is not used in float_decl_plugin) + unsigned m_ext_id; // for PARAM_EXTERNAL }; public: @@ -114,12 +114,10 @@ public: explicit parameter(int val): m_kind(PARAM_INT), m_int(val) {} explicit parameter(unsigned val): m_kind(PARAM_INT), m_int(val) {} explicit parameter(ast * p): m_kind(PARAM_AST), m_ast(p) {} - explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL) { new (m_symbol) symbol(s); } - explicit parameter(rational const & r): m_kind(PARAM_RATIONAL) { new (m_rational) rational(r); } + explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL), m_symbol(s) {} + explicit parameter(rational const & r): m_kind(PARAM_RATIONAL), m_rational(r) {} explicit parameter(double d):m_kind(PARAM_DOUBLE), m_dval(d) {} - explicit parameter(const char *s):m_kind(PARAM_SYMBOL) { - new (m_symbol) symbol(s); - } + explicit parameter(const char *s):m_kind(PARAM_SYMBOL), m_symbol(s) {} explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {} parameter(parameter const&); @@ -156,8 +154,8 @@ public: int get_int() const { SASSERT(is_int()); return m_int; } ast * get_ast() const { SASSERT(is_ast()); return m_ast; } - symbol const & get_symbol() const { SASSERT(is_symbol()); return *(reinterpret_cast(m_symbol)); } - rational const & get_rational() const { SASSERT(is_rational()); return *(reinterpret_cast(m_rational)); } + symbol const & get_symbol() const { SASSERT(is_symbol()); return m_symbol; } + rational const & get_rational() const { SASSERT(is_rational()); return m_rational; } double get_double() const { SASSERT(is_double()); return m_dval; } unsigned get_ext_id() const { SASSERT(is_external()); return m_ext_id; } diff --git a/src/util/optional.h b/src/util/optional.h index 22757f3bd..6a00cf841 100644 --- a/src/util/optional.h +++ b/src/util/optional.h @@ -23,32 +23,35 @@ Revision History: template class optional { - char m_obj[sizeof(T)]; - char m_initialized; + union { + T m_obj; + char m_dummy; + }; + bool m_initialized; void construct(const T & val) { - m_initialized = 1; - new (reinterpret_cast(m_obj)) T(val); + m_initialized = true; + new (&m_obj) T(val); } void destroy() { - if (m_initialized == 1) { - reinterpret_cast(m_obj)->~T(); + if (m_initialized) { + m_obj.~T(); } - m_initialized = 0; + m_initialized = false; } public: optional(): - m_initialized(0) {} + m_initialized(false) {} explicit optional(const T & val) { construct(val); } optional(const optional & val): - m_initialized(0) { - if (val.m_initialized == 1) { + m_initialized(false) { + if (val.m_initialized) { construct(*val); } } @@ -59,13 +62,13 @@ public: static optional const & undef() { static optional u; return u; } - bool initialized() const { return m_initialized == 1; } - operator bool() const { return m_initialized == 1; } - bool operator!() const { return m_initialized == 0; } + bool initialized() const { return m_initialized; } + operator bool() const { return m_initialized; } + bool operator!() const { return !m_initialized; } T * get() const { - if (m_initialized == 1) { - return reinterpret_cast(m_obj); + if (m_initialized) { + return &m_obj; } else { return 0; @@ -73,29 +76,29 @@ public: } void set_invalid() { - if (m_initialized == 1) { + if (m_initialized) { destroy(); } } T * operator->() { - SASSERT(m_initialized==1); - return reinterpret_cast(m_obj); + SASSERT(m_initialized); + return &m_obj; } T const * operator->() const { - SASSERT(m_initialized==1); - return reinterpret_cast(m_obj); + SASSERT(m_initialized); + return &m_obj; } const T & operator*() const { - SASSERT(m_initialized==1); - return *reinterpret_cast(m_obj); + SASSERT(m_initialized); + return m_obj; } T & operator*() { - SASSERT(m_initialized==1); - return *reinterpret_cast(m_obj); + SASSERT(m_initialized); + return m_obj; } optional & operator=(const T & val) { From 632c2d8ebf7011ef8876f9c938ad8a296c148b57 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 14 Aug 2017 20:10:17 +0100 Subject: [PATCH 120/488] use static_assert in COMPILE_TIME_ASSERT --- src/util/debug.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/util/debug.h b/src/util/debug.h index adc9fc6b7..e0ceb9a64 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -90,14 +90,7 @@ bool is_debug_enabled(const char * tag); exit(-1); \ } -#define MAKE_NAME2(LINE) zofty_ ## LINE -#define MAKE_NAME(LINE) MAKE_NAME2(LINE) -#define DBG_UNIQUE_NAME MAKE_NAME(__LINE__) -#ifdef __GNUC__ -#define COMPILE_TIME_ASSERT(expr) extern __attribute__((unused)) char DBG_UNIQUE_NAME[expr] -#else -#define COMPILE_TIME_ASSERT(expr) extern char DBG_UNIQUE_NAME[expr] -#endif +#define COMPILE_TIME_ASSERT(expr) static_assert(expr, "") void finalize_debug(); /* From 000796c25cbc06ef008c4701305a3b1bea3bdf4b Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 14 Aug 2017 20:12:00 +0100 Subject: [PATCH 121/488] micro-optimization in tactics' cleanup(): avoid dealloc+alloc traffic --- src/tactic/bv/elim_small_bv_tactic.cpp | 5 ++--- src/tactic/core/elim_term_ite_tactic.cpp | 5 ++--- src/tactic/core/reduce_args_tactic.cpp | 7 +++---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/tactic/bv/elim_small_bv_tactic.cpp b/src/tactic/bv/elim_small_bv_tactic.cpp index d24ae4f49..c40927179 100644 --- a/src/tactic/bv/elim_small_bv_tactic.cpp +++ b/src/tactic/bv/elim_small_bv_tactic.cpp @@ -307,9 +307,8 @@ public: virtual void cleanup() { ast_manager & m = m_imp->m; - imp * d = alloc(imp, m, m_params); - std::swap(d, m_imp); - dealloc(d); + m_imp->~imp(); + m_imp = new (m_imp) imp(m, m_params); } }; diff --git a/src/tactic/core/elim_term_ite_tactic.cpp b/src/tactic/core/elim_term_ite_tactic.cpp index 91f1d9020..79526a101 100644 --- a/src/tactic/core/elim_term_ite_tactic.cpp +++ b/src/tactic/core/elim_term_ite_tactic.cpp @@ -171,9 +171,8 @@ public: virtual void cleanup() { ast_manager & m = m_imp->m; - imp * d = alloc(imp, m, m_params); - std::swap(d, m_imp); - dealloc(d); + m_imp->~imp(); + m_imp = new (m_imp) imp(m, m_params); } }; diff --git a/src/tactic/core/reduce_args_tactic.cpp b/src/tactic/core/reduce_args_tactic.cpp index a4b9825cc..476c21232 100644 --- a/src/tactic/core/reduce_args_tactic.cpp +++ b/src/tactic/core/reduce_args_tactic.cpp @@ -502,9 +502,8 @@ void reduce_args_tactic::operator()(goal_ref const & g, } void reduce_args_tactic::cleanup() { - ast_manager & m = m_imp->m(); - imp * d = alloc(imp, m); - std::swap(d, m_imp); - dealloc(d); + ast_manager & m = m_imp->m(); + m_imp->~imp(); + m_imp = new (m_imp) imp(m); } From 086ea7867ec487ba263095fc7f797ebaf530db02 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 14 Aug 2017 12:52:25 -0700 Subject: [PATCH 122/488] another stab at #989 Signed-off-by: Nikolaj Bjorner --- scripts/update_api.py | 2 +- src/smt/smt_context.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 7c9f553cb..4000b3da2 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -322,7 +322,7 @@ def mk_py_wrappers(): display_args(num) core_py.write("):\n") core_py.write(" _lib = lib()\n") - core_py.write(" if _lib.%s is None:\n" % name) + core_py.write(" if _lib is None or _lib.%s is None:\n" % name) core_py.write(" return\n") if result != VOID: core_py.write(" r = _lib.%s(" % name) diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 42e382790..daa408161 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -3290,11 +3290,11 @@ namespace smt { internalize_assertions(); lbool r = l_undef; + TRACE("before_search", display(tout);); if (m_asserted_formulas.inconsistent()) { r = l_false; } else { - TRACE("after_internalization", display(tout);); if (inconsistent()) { VERIFY(!resolve_conflict()); // build the proof r = l_false; From 197aefd111d3336edf092542c2289b8081abe480 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 14 Aug 2017 22:22:48 +0100 Subject: [PATCH 123/488] fix crash introduced in my previous commit --- src/ast/ast.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 43748bd42..38d432f33 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -57,7 +57,7 @@ parameter& parameter::operator=(parameter const& other) { case PARAM_INT: m_int = other.get_int(); break; case PARAM_AST: m_ast = other.get_ast(); break; case PARAM_SYMBOL: m_symbol = other.get_symbol(); break; - case PARAM_RATIONAL: m_rational = other.get_rational(); break; + case PARAM_RATIONAL: new (&m_rational) rational(other.get_rational()); break; case PARAM_DOUBLE: m_dval = other.m_dval; break; case PARAM_EXTERNAL: m_ext_id = other.m_ext_id; break; default: From 4b00bc636bda344ba8ae7ea28a2d5d949d4dc629 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 14 Aug 2017 23:00:59 +0100 Subject: [PATCH 124/488] revert the patch to remove no-strict-aliasing VS 2012 doesnt support C++11 unions.. --- CMakeLists.txt | 4 ++++ scripts/mk_util.py | 8 +++---- src/ast/ast.cpp | 8 +++---- src/ast/ast.h | 24 +++++++++++---------- src/util/optional.h | 51 +++++++++++++++++++++------------------------ 5 files changed, 49 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 715679957..a3ed2a312 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,18 +234,22 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_USE_THREAD_LOCAL") endif() + z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") # Does OSX really not need any special flags? message(STATUS "Platform: Darwin") elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") message(STATUS "Platform: FreeBSD") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_FREEBSD_") + z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") message(STATUS "Platform: OpenBSD") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_OPENBSD_") + z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif (CYGWIN) message(STATUS "Platform: Cygwin") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_CYGWIN") + z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif (WIN32) message(STATUS "Platform: Windows") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_WINDOWS") diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 24f22d8ee..d2e3d6b4c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2443,26 +2443,26 @@ def mk_config(): SO_EXT = '.dylib' SLIBFLAGS = '-dynamiclib' elif sysname == 'Linux': - CXXFLAGS = '%s -D_LINUX_' % CXXFLAGS + CXXFLAGS = '%s -fno-strict-aliasing -D_LINUX_' % CXXFLAGS OS_DEFINES = '-D_LINUX_' SO_EXT = '.so' LDFLAGS = '%s -lrt' % LDFLAGS SLIBFLAGS = '-shared' SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS elif sysname == 'FreeBSD': - CXXFLAGS = '%s -D_FREEBSD_' % CXXFLAGS + CXXFLAGS = '%s -fno-strict-aliasing -D_FREEBSD_' % CXXFLAGS OS_DEFINES = '-D_FREEBSD_' SO_EXT = '.so' LDFLAGS = '%s -lrt' % LDFLAGS SLIBFLAGS = '-shared' SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS elif sysname == 'OpenBSD': - CXXFLAGS = '%s -D_OPENBSD_' % CXXFLAGS + CXXFLAGS = '%s -fno-strict-aliasing -D_OPENBSD_' % CXXFLAGS OS_DEFINES = '-D_OPENBSD_' SO_EXT = '.so' SLIBFLAGS = '-shared' elif sysname[:6] == 'CYGWIN': - CXXFLAGS = '%s -D_CYGWIN' % CXXFLAGS + CXXFLAGS = '%s -D_CYGWIN -fno-strict-aliasing' % CXXFLAGS OS_DEFINES = '-D_CYGWIN' SO_EXT = '.dll' SLIBFLAGS = '-shared' diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 38d432f33..a1efed19e 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -35,7 +35,7 @@ Revision History: parameter::~parameter() { if (m_kind == PARAM_RATIONAL) { - m_rational.~rational(); + reinterpret_cast(m_rational)->~rational(); } } @@ -50,14 +50,14 @@ parameter& parameter::operator=(parameter const& other) { return *this; } if (m_kind == PARAM_RATIONAL) { - m_rational.~rational(); + reinterpret_cast(m_rational)->~rational(); } m_kind = other.m_kind; switch(other.m_kind) { case PARAM_INT: m_int = other.get_int(); break; case PARAM_AST: m_ast = other.get_ast(); break; - case PARAM_SYMBOL: m_symbol = other.get_symbol(); break; - case PARAM_RATIONAL: new (&m_rational) rational(other.get_rational()); break; + case PARAM_SYMBOL: new (m_symbol) symbol(other.get_symbol()); break; + case PARAM_RATIONAL: new (m_rational) rational(other.get_rational()); break; case PARAM_DOUBLE: m_dval = other.m_dval; break; case PARAM_EXTERNAL: m_ext_id = other.m_ext_id; break; default: diff --git a/src/ast/ast.h b/src/ast/ast.h index 64122a7dc..3a3f08df2 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -100,12 +100,12 @@ private: // It is not possible to use tag pointers, since symbols are already tagged. union { - int m_int; // for PARAM_INT - ast* m_ast; // for PARAM_AST - symbol m_symbol; // for PARAM_SYMBOL - rational m_rational; // for PARAM_RATIONAL - double m_dval; // for PARAM_DOUBLE (remark: this is not used in float_decl_plugin) - unsigned m_ext_id; // for PARAM_EXTERNAL + int m_int; // for PARAM_INT + ast* m_ast; // for PARAM_AST + char m_symbol[sizeof(symbol)]; // for PARAM_SYMBOL + char m_rational[sizeof(rational)]; // for PARAM_RATIONAL + double m_dval; // for PARAM_DOUBLE (remark: this is not used in float_decl_plugin) + unsigned m_ext_id; // for PARAM_EXTERNAL }; public: @@ -114,10 +114,12 @@ public: explicit parameter(int val): m_kind(PARAM_INT), m_int(val) {} explicit parameter(unsigned val): m_kind(PARAM_INT), m_int(val) {} explicit parameter(ast * p): m_kind(PARAM_AST), m_ast(p) {} - explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL), m_symbol(s) {} - explicit parameter(rational const & r): m_kind(PARAM_RATIONAL), m_rational(r) {} + explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL) { new (m_symbol) symbol(s); } + explicit parameter(rational const & r): m_kind(PARAM_RATIONAL) { new (m_rational) rational(r); } explicit parameter(double d):m_kind(PARAM_DOUBLE), m_dval(d) {} - explicit parameter(const char *s):m_kind(PARAM_SYMBOL), m_symbol(s) {} + explicit parameter(const char *s):m_kind(PARAM_SYMBOL) { + new (m_symbol) symbol(s); + } explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {} parameter(parameter const&); @@ -154,8 +156,8 @@ public: int get_int() const { SASSERT(is_int()); return m_int; } ast * get_ast() const { SASSERT(is_ast()); return m_ast; } - symbol const & get_symbol() const { SASSERT(is_symbol()); return m_symbol; } - rational const & get_rational() const { SASSERT(is_rational()); return m_rational; } + symbol const & get_symbol() const { SASSERT(is_symbol()); return *(reinterpret_cast(m_symbol)); } + rational const & get_rational() const { SASSERT(is_rational()); return *(reinterpret_cast(m_rational)); } double get_double() const { SASSERT(is_double()); return m_dval; } unsigned get_ext_id() const { SASSERT(is_external()); return m_ext_id; } diff --git a/src/util/optional.h b/src/util/optional.h index 6a00cf841..22757f3bd 100644 --- a/src/util/optional.h +++ b/src/util/optional.h @@ -23,35 +23,32 @@ Revision History: template class optional { - union { - T m_obj; - char m_dummy; - }; - bool m_initialized; + char m_obj[sizeof(T)]; + char m_initialized; void construct(const T & val) { - m_initialized = true; - new (&m_obj) T(val); + m_initialized = 1; + new (reinterpret_cast(m_obj)) T(val); } void destroy() { - if (m_initialized) { - m_obj.~T(); + if (m_initialized == 1) { + reinterpret_cast(m_obj)->~T(); } - m_initialized = false; + m_initialized = 0; } public: optional(): - m_initialized(false) {} + m_initialized(0) {} explicit optional(const T & val) { construct(val); } optional(const optional & val): - m_initialized(false) { - if (val.m_initialized) { + m_initialized(0) { + if (val.m_initialized == 1) { construct(*val); } } @@ -62,13 +59,13 @@ public: static optional const & undef() { static optional u; return u; } - bool initialized() const { return m_initialized; } - operator bool() const { return m_initialized; } - bool operator!() const { return !m_initialized; } + bool initialized() const { return m_initialized == 1; } + operator bool() const { return m_initialized == 1; } + bool operator!() const { return m_initialized == 0; } T * get() const { - if (m_initialized) { - return &m_obj; + if (m_initialized == 1) { + return reinterpret_cast(m_obj); } else { return 0; @@ -76,29 +73,29 @@ public: } void set_invalid() { - if (m_initialized) { + if (m_initialized == 1) { destroy(); } } T * operator->() { - SASSERT(m_initialized); - return &m_obj; + SASSERT(m_initialized==1); + return reinterpret_cast(m_obj); } T const * operator->() const { - SASSERT(m_initialized); - return &m_obj; + SASSERT(m_initialized==1); + return reinterpret_cast(m_obj); } const T & operator*() const { - SASSERT(m_initialized); - return m_obj; + SASSERT(m_initialized==1); + return *reinterpret_cast(m_obj); } T & operator*() { - SASSERT(m_initialized); - return m_obj; + SASSERT(m_initialized==1); + return *reinterpret_cast(m_obj); } optional & operator=(const T & val) { From 1690febffd05861b738700f43eb236a8f445fde9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 15 Aug 2017 00:26:05 -0700 Subject: [PATCH 125/488] enable QF_UF mode use same parameters whether with or without static featues, #1141 Signed-off-by: Nikolaj Bjorner --- src/smt/asserted_formulas.cpp | 22 +++++++++++++--------- src/smt/smt_setup.cpp | 20 +++++++++++--------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 9753adc5b..0afbeb434 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -16,31 +16,31 @@ Author: Revision History: --*/ -#include "smt/asserted_formulas.h" +#include "util/warning.h" #include "ast/ast_ll_pp.h" #include "ast/ast_pp.h" +#include "ast/for_each_expr.h" +#include "ast/well_sorted.h" #include "ast/simplifier/arith_simplifier_plugin.h" #include "ast/simplifier/array_simplifier_plugin.h" #include "ast/simplifier/datatype_simplifier_plugin.h" #include "ast/simplifier/fpa_simplifier_plugin.h" #include "ast/simplifier/seq_simplifier_plugin.h" #include "ast/simplifier/bv_simplifier_plugin.h" -#include "ast/for_each_expr.h" -#include "ast/well_sorted.h" -#include "ast/normal_forms/pull_quant.h" #include "ast/simplifier/pull_ite_tree.h" #include "ast/simplifier/push_app_ite.h" -#include "smt/elim_term_ite.h" -#include "ast/pattern/pattern_inference.h" -#include "ast/normal_forms/nnf.h" #include "ast/simplifier/bv_elim.h" #include "ast/simplifier/inj_axiom.h" -#include "ast/rewriter/der.h" #include "ast/simplifier/elim_bounds.h" -#include "util/warning.h" #include "ast/simplifier/bit2int.h" +#include "ast/normal_forms/pull_quant.h" +#include "ast/normal_forms/nnf.h" +#include "ast/pattern/pattern_inference.h" +#include "ast/rewriter/der.h" #include "ast/rewriter/distribute_forall.h" #include "ast/macros/quasi_macros.h" +#include "smt/asserted_formulas.h" +#include "smt/elim_term_ite.h" asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m(m), @@ -138,6 +138,8 @@ void asserted_formulas::set_eliminate_and(bool flag) { m_bsimp->set_eliminate_and(flag); } +#include "th_rewriter.h" + void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { if (inconsistent()) return; @@ -161,6 +163,8 @@ void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { } set_eliminate_and(false); // do not eliminate and before nnf. m_simplifier(r1, r2, pr2); + th_rewriter rw(m); + rw(r2); TRACE("assert_expr_bug", tout << "after...\n" << mk_pp(r1, m) << "\n";); if (m.proofs_enabled()) { if (e == r2) diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 392802d5d..da9285b94 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -53,7 +53,9 @@ namespace smt { // warning_msg("ignoring MODEL_COMPACT=true because it cannot be used with MBQI=true"); // m_params.m_model_compact = false; // } - TRACE("setup", tout << "configuring logical context, logic: " << m_logic << "\n";); + TRACE("setup", tout << "configuring logical context, logic: " << m_logic << " " << cm << "\n";); + + m_params.m_relevancy_lvl = 0; m_already_configured = true; switch (cm) { @@ -202,6 +204,9 @@ namespace smt { void setup::setup_QF_UF() { m_params.m_relevancy_lvl = 0; m_params.m_nnf_cnf = false; + m_params.m_restart_strategy = RS_LUBY; + m_params.m_phase_selection = PS_CACHING_CONSERVATIVE2; + m_params.m_random_initial_activity = IA_RANDOM; } void setup::setup_QF_BVRE() { @@ -210,13 +215,9 @@ namespace smt { m_context.register_plugin(alloc(theory_seq, m_manager)); } - void setup::setup_QF_UF(static_features const & st) { + void setup::setup_QF_UF(static_features const & st) { check_no_arithmetic(st, "QF_UF"); - m_params.m_relevancy_lvl = 0; - m_params.m_nnf_cnf = false; - m_params.m_restart_strategy = RS_LUBY; - m_params.m_phase_selection = PS_CACHING_CONSERVATIVE2; - m_params.m_random_initial_activity = IA_RANDOM; + setup_QF_UF(); TRACE("setup", tout << "st.m_num_theories: " << st.m_num_theories << "\n"; tout << "st.m_num_uninterpreted_functions: " << st.m_num_uninterpreted_functions << "\n";); @@ -548,6 +549,7 @@ namespace smt { } void setup::setup_QF_BV() { + TRACE("setup", tout << "qf-bv\n";); m_params.m_relevancy_lvl = 0; m_params.m_arith_reflect = false; m_params.m_bv_cc = false; @@ -877,7 +879,7 @@ namespace smt { void setup::setup_unknown() { static_features st(m_manager); st.collect(m_context.get_num_asserted_formulas(), m_context.get_asserted_formulas()); - + TRACE("setup", tout << "setup_unknown\n";); setup_arith(); setup_arrays(); setup_bv(); @@ -916,7 +918,7 @@ namespace smt { tout << "has fpa: " << st.m_has_fpa << "\n"; tout << "has arrays: " << st.m_has_arrays << "\n";); - if (st.num_non_uf_theories() == 0) { + if (st.num_non_uf_theories() == 0) { setup_QF_UF(st); return; } From 25752dc169215d37aef537c985922361874b662d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 15 Aug 2017 01:20:30 -0700 Subject: [PATCH 126/488] enable QF_UF mode use same parameters whether with or without static featues, #1141, revert some breaking changes that should not have been part of commit Signed-off-by: Nikolaj Bjorner --- src/smt/asserted_formulas.cpp | 3 --- src/smt/smt_setup.cpp | 1 - 2 files changed, 4 deletions(-) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 0afbeb434..cbbb9a6bc 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -138,7 +138,6 @@ void asserted_formulas::set_eliminate_and(bool flag) { m_bsimp->set_eliminate_and(flag); } -#include "th_rewriter.h" void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { if (inconsistent()) @@ -163,8 +162,6 @@ void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { } set_eliminate_and(false); // do not eliminate and before nnf. m_simplifier(r1, r2, pr2); - th_rewriter rw(m); - rw(r2); TRACE("assert_expr_bug", tout << "after...\n" << mk_pp(r1, m) << "\n";); if (m.proofs_enabled()) { if (e == r2) diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index da9285b94..a37668c7b 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -55,7 +55,6 @@ namespace smt { // } TRACE("setup", tout << "configuring logical context, logic: " << m_logic << " " << cm << "\n";); - m_params.m_relevancy_lvl = 0; m_already_configured = true; switch (cm) { From 97e263299d28e5ccb78ce4aef8e3133808c372a4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 15 Aug 2017 01:35:28 -0700 Subject: [PATCH 127/488] add logic 'SAT' as an alternative name to QF_FD some solverFor(SAT) works too. #1152 Signed-off-by: Nikolaj Bjorner --- src/tactic/portfolio/smt_strategic_solver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index bde9e0e98..0ad9e5f19 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -93,7 +93,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const return mk_qffpbv_tactic(m, p); else if (logic=="HORN") return mk_horn_tactic(m, p); - else if (logic == "QF_FD") + else if (logic == "QF_FD" || logic == "SAT") return mk_solver2tactic(mk_fd_solver(m, p)); //else if (logic=="QF_UFNRA") // return mk_qfufnra_tactic(m, p); @@ -102,7 +102,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const } static solver* mk_special_solver_for_logic(ast_manager & m, params_ref const & p, symbol const& logic) { - if (logic == "QF_FD") + if (logic == "QF_FD" || logic == "SAT") return mk_fd_solver(m, p); return 0; } From 370706b2b7918c7c0a6580042c4306b58c6f43e7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 16 Aug 2017 14:33:37 -0700 Subject: [PATCH 128/488] patch Signed-off-by: Nikolaj Bjorner --- src/smt/mam.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index f59a57bf3..72a6d895c 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -2086,6 +2086,7 @@ namespace smt { for (; it != end; ++it) { enode * p = *it; if (p->get_decl() == f && + p->get_num_args() > i && m_context.is_relevant(p) && p->is_cgr() && p->get_arg(i)->get_root() == n) { From 4b759fd865ab45643b404bff9270463ef1ef3d4b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 16 Aug 2017 16:18:19 -0700 Subject: [PATCH 129/488] add missing functions to serialize optimize benchmarks for Java #1215 Signed-off-by: Nikolaj Bjorner --- src/api/java/Optimize.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/api/java/Optimize.java b/src/api/java/Optimize.java index 5e4535ac4..0b0a5bdaf 100644 --- a/src/api/java/Optimize.java +++ b/src/api/java/Optimize.java @@ -298,6 +298,24 @@ public class Optimize extends Z3Object { return Native.optimizeToString(getContext().nCtx(), getNativeObject()); } + /** + * Parse an SMT-LIB2 file with optimization objectives and constraints. + * The parsed constraints and objectives are added to the optimization context. + */ + public void fromFile(string file) + { + Native.optimizeFromFile(getContext().nCtx(), getNativeObject(), file); + } + + /** + * Similar to FromFile. Instead it takes as argument a string. + */ + public void fromString(string s) + { + Native.optimizeFromString(getContext().nCtx(), getNativeObject(), s); + } + + /** * Optimize statistics. **/ From 43c2ccb29a5fc13cd7328ce54e2febdecd0901bb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 16 Aug 2017 16:38:48 -0700 Subject: [PATCH 130/488] add missing functions to serialize optimize benchmarks for Java #1215 Signed-off-by: Nikolaj Bjorner --- src/api/java/Optimize.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/java/Optimize.java b/src/api/java/Optimize.java index 0b0a5bdaf..bc2232888 100644 --- a/src/api/java/Optimize.java +++ b/src/api/java/Optimize.java @@ -302,7 +302,7 @@ public class Optimize extends Z3Object { * Parse an SMT-LIB2 file with optimization objectives and constraints. * The parsed constraints and objectives are added to the optimization context. */ - public void fromFile(string file) + public void fromFile(String file) { Native.optimizeFromFile(getContext().nCtx(), getNativeObject(), file); } @@ -310,7 +310,7 @@ public class Optimize extends Z3Object { /** * Similar to FromFile. Instead it takes as argument a string. */ - public void fromString(string s) + public void fromString(String s) { Native.optimizeFromString(getContext().nCtx(), getNativeObject(), s); } From 96d0781c9d0790a3d54ba8a4a339bc89c32f030c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Aug 2017 11:39:06 +0100 Subject: [PATCH 131/488] Whitespace --- src/smt/mam.cpp | 492 ++++++++++++++++++++++++------------------------ 1 file changed, 246 insertions(+), 246 deletions(-) diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index f59a57bf3..1fc5ed220 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -34,7 +34,7 @@ Revision History: // send profiling information to stdout #define _PROFILE_MAM_TO_STDOUT // threshold in secs for being considered expensive -#define _PROFILE_MAM_THRESHOLD 30.0 +#define _PROFILE_MAM_THRESHOLD 30.0 // dump expensive (> _PROFILE_MAM_THRESHOLD) code trees whenever execute_core is executed. #define _PROFILE_MAM_EXPENSIVE // @@ -60,7 +60,7 @@ namespace smt { // ------------------------------------ class mam_impl; - + typedef trail_stack mam_trail_stack; typedef trail mam_trail; @@ -70,8 +70,8 @@ namespace smt { public: mam_value_trail(T & value):value_trail(value) {} }; - - + + // ------------------------------------ // // Auxiliary @@ -79,7 +79,7 @@ namespace smt { // ------------------------------------ class label_hasher { svector m_lbl2hash; // cache: lbl_id -> hash - + void mk_lbl_hash(unsigned lbl_id) { unsigned a = 17; unsigned b = 3; @@ -124,19 +124,19 @@ namespace smt { typedef enum { INIT1=0, INIT2, INIT3, INIT4, INIT5, INIT6, INITN, BIND1, BIND2, BIND3, BIND4, BIND5, BIND6, BINDN, - YIELD1, YIELD2, YIELD3, YIELD4, YIELD5, YIELD6, YIELDN, + YIELD1, YIELD2, YIELD3, YIELD4, YIELD5, YIELD6, YIELDN, COMPARE, CHECK, FILTER, CFILTER, PFILTER, CHOOSE, NOOP, CONTINUE, - GET_ENODE, + GET_ENODE, GET_CGR1, GET_CGR2, GET_CGR3, GET_CGR4, GET_CGR5, GET_CGR6, GET_CGRN, IS_CGR } opcode; - + struct instruction { opcode m_opcode; instruction * m_next; #ifdef _PROFILE_MAM unsigned m_counter; // how often it was executed -#endif +#endif bool is_init() const { return m_opcode >= INIT1 && m_opcode <= INITN; } @@ -147,7 +147,7 @@ namespace smt { // operators (e.g., + and *) are represented using n-ary // applications. // We do not need the extra field for INIT1, ..., INIT6. - unsigned m_num_args; + unsigned m_num_args; }; struct compare : public instruction { @@ -162,7 +162,7 @@ namespace smt { struct filter : public instruction { unsigned m_reg; - approx_set m_lbl_set; + approx_set m_lbl_set; }; struct pcheck : public instruction { @@ -211,15 +211,15 @@ namespace smt { approx_set m_lbl_set; // singleton set containing m_label /* The following field is an array of tagged pointers. - Each positon contains: + Each positon contains: 1- null (no joint), NULL_TAG 2- a boxed integer (i.e., register that contains the variable bind) VAR_TAG 3- an enode pointer (ground term) GROUND_TERM_TAG 4- or, a joint2 pointer. NESTED_VAR_TAG - + The size of the array is m_num_args. */ - enode * m_joints[0]; + enode * m_joints[0]; }; struct bind : public instruction { @@ -294,7 +294,7 @@ namespace smt { void display_joints(std::ostream & out, unsigned num_joints, enode * const * joints) { for (unsigned i = 0; i < num_joints; i++) { - if (i > 0) + if (i > 0) out << " "; enode * bare = joints[i]; switch (GET_TAG(bare)) { @@ -307,7 +307,7 @@ namespace smt { } void display_continue(std::ostream & out, const cont & c) { - out << "(CONTINUE " << c.m_label->get_name() << " " << c.m_num_args << " " << c.m_oreg << " " + out << "(CONTINUE " << c.m_label->get_name() << " " << c.m_num_args << " " << c.m_oreg << " " << c.m_lbl_set << " ("; display_joints(out, c.m_num_args, c.m_joints); out << "))"; @@ -317,38 +317,38 @@ namespace smt { out << "(" << op << " " << instr.m_reg << " " << instr.m_lbl_set << ")"; } - + std::ostream & operator<<(std::ostream & out, const instruction & instr) { switch (instr.m_opcode) { - case INIT1: case INIT2: case INIT3: case INIT4: case INIT5: case INIT6: case INITN: + case INIT1: case INIT2: case INIT3: case INIT4: case INIT5: case INIT6: case INITN: out << "(INIT"; - if (instr.m_opcode <= INIT6) + if (instr.m_opcode <= INIT6) out << (instr.m_opcode - INIT1 + 1); else out << "N"; out << ")"; break; - case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: - display_bind(out, static_cast(instr)); + case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: + display_bind(out, static_cast(instr)); break; case GET_CGR1: case GET_CGR2: case GET_CGR3: case GET_CGR4: case GET_CGR5: case GET_CGR6: case GET_CGRN: - display_get_cgr(out, static_cast(instr)); + display_get_cgr(out, static_cast(instr)); break; case IS_CGR: display_is_cgr(out, static_cast(instr)); break; - case YIELD1: case YIELD2: case YIELD3: case YIELD4: case YIELD5: case YIELD6: case YIELDN: - display_yield(out, static_cast(instr)); + case YIELD1: case YIELD2: case YIELD3: case YIELD4: case YIELD5: case YIELD6: case YIELDN: + display_yield(out, static_cast(instr)); break; case CONTINUE: display_continue(out, static_cast(instr)); break; - case COMPARE: - out << "(COMPARE " << static_cast(instr).m_reg1 << " " + case COMPARE: + out << "(COMPARE " << static_cast(instr).m_reg1 << " " << static_cast(instr).m_reg2 << ")"; break; case CHECK: - out << "(CHECK " << static_cast(instr).m_reg + out << "(CHECK " << static_cast(instr).m_reg << " #" << static_cast(instr).m_enode->get_owner_id() << ")"; break; case FILTER: @@ -361,14 +361,14 @@ namespace smt { display_filter(out, "PFILTER", static_cast(instr)); break; case GET_ENODE: - out << "(GET_ENODE " << static_cast(instr).m_oreg << " #" << + out << "(GET_ENODE " << static_cast(instr).m_oreg << " #" << static_cast(instr).m_enode->get_owner_id() << ")"; break; - case CHOOSE: + case CHOOSE: out << "(CHOOSE)"; break; - case NOOP: - out << "(NOOP)"; + case NOOP: + out << "(NOOP)"; break; } #ifdef _PROFILE_MAM @@ -379,7 +379,7 @@ namespace smt { // ------------------------------------ // - // Code Tree + // Code Tree // // ------------------------------------ @@ -404,11 +404,11 @@ namespace smt { unsigned m_num_regs; unsigned m_num_choices; instruction * m_root; - enode_vector m_candidates; + enode_vector m_candidates; #ifdef Z3DEBUG context * m_context; ptr_vector m_patterns; -#endif +#endif #ifdef _PROFILE_MAM stopwatch m_watch; unsigned m_counter; @@ -476,7 +476,7 @@ namespace smt { } } #endif - + public: code_tree(label_hasher & h, func_decl * lbl, unsigned short num_args, bool filter_candidates): m_lbl_hasher(h), @@ -500,8 +500,8 @@ namespace smt { #endif } - stopwatch & get_watch() { - return m_watch; + stopwatch & get_watch() { + return m_watch; } void inc_counter() { @@ -512,7 +512,7 @@ namespace smt { return m_counter; } #endif - + unsigned expected_num_args() const { return m_num_args; } @@ -532,7 +532,7 @@ namespace smt { bool filter_candidates() const { return m_filter_candidates != 0; } - + const instruction * get_root() const { return m_root; } @@ -558,7 +558,7 @@ namespace smt { SASSERT(m_context == 0); m_context = ctx; } - + ptr_vector & get_patterns() { return m_patterns; } @@ -614,7 +614,7 @@ namespace smt { return r; } - instruction * mk_init(unsigned n) { + instruction * mk_init(unsigned n) { SASSERT(n >= 1); opcode op = n <= 6 ? static_cast(INIT1 + n - 1) : INITN; if (op == INITN) { @@ -637,7 +637,7 @@ namespace smt { m_trail_stack(s), m_region(s.get_region()) { } - + code_tree * mk_code_tree(func_decl * lbl, unsigned short num_args, bool filter_candidates) { code_tree * r = alloc(code_tree,m_lbl_hasher, lbl, num_args, filter_candidates); r->m_root = mk_init(num_args); @@ -648,22 +648,22 @@ namespace smt { return new (m_region) joint2(f, pos, reg); } - compare * mk_compare(unsigned reg1, unsigned reg2) { - compare * r = mk_instr(COMPARE, sizeof(compare)); + compare * mk_compare(unsigned reg1, unsigned reg2) { + compare * r = mk_instr(COMPARE, sizeof(compare)); r->m_reg1 = reg1; r->m_reg2 = reg2; return r; } - - check * mk_check(unsigned reg, enode * n) { - check * r = mk_instr(CHECK, sizeof(check)); + + check * mk_check(unsigned reg, enode * n) { + check * r = mk_instr(CHECK, sizeof(check)); r->m_reg = reg; r->m_enode = n; return r; } filter * mk_filter_core(opcode op, unsigned reg, approx_set s) { - filter * r = mk_instr(op, sizeof(filter)); + filter * r = mk_instr(op, sizeof(filter)); r->m_reg = reg; r->m_lbl_set = s; return r; @@ -744,7 +744,7 @@ namespace smt { return y; } - cont * mk_cont(func_decl * lbl, unsigned short num_args, unsigned oreg, + cont * mk_cont(func_decl * lbl, unsigned short num_args, unsigned oreg, approx_set const & s, enode * const * joints) { SASSERT(num_args >= 1); cont * r = mk_instr(CONTINUE, sizeof(cont) + num_args * sizeof(enode*)); @@ -764,11 +764,11 @@ namespace smt { void save_num_regs(code_tree * tree) { m_trail_stack.push(mam_value_trail(tree->m_num_regs)); } - + void save_num_choices(code_tree * tree) { m_trail_stack.push(mam_value_trail(tree->m_num_choices)); } - + void insert_new_lbl_hash(filter * instr, unsigned h) { m_trail_stack.push(mam_value_trail(instr->m_lbl_set)); instr->m_lbl_set.insert(h); @@ -795,18 +795,18 @@ namespace smt { app * m_mp; code_tree * m_tree; unsigned m_num_choices; - bool m_is_tmp_tree; + bool m_is_tmp_tree; svector m_mp_already_processed; obj_map m_matched_exprs; - + struct pcheck_checked { func_decl * m_label; enode * m_enode; }; - - typedef enum { NOT_CHECKED, - CHECK_SET, + + typedef enum { NOT_CHECKED, + CHECK_SET, CHECK_SINGLETON } check_mark; svector m_mark; @@ -827,7 +827,7 @@ namespace smt { void set_check_mark(unsigned reg, check_mark m) { m_mark.setx(reg, m, NOT_CHECKED); } - + void init(code_tree * t, quantifier * qa, app * mp, unsigned first_idx) { SASSERT(m_ast_manager.is_pattern(mp)); #ifdef Z3DEBUG @@ -843,7 +843,7 @@ namespace smt { m_num_choices = 0; m_todo.reset(); m_registers.fill(0); - + app * p = to_app(mp->get_arg(first_idx)); SASSERT(t->get_root_lbl() == p->get_decl()); unsigned num_args = p->get_num_args(); @@ -861,7 +861,7 @@ namespace smt { } /** - \brief Return true if all arguments of n are bound variables. + \brief Return true if all arguments of n are bound variables. That is, during execution time, the variables will be already bound */ bool all_args_are_bound_vars(app * n) { @@ -877,7 +877,7 @@ namespace smt { } /** - \see get_stats + \see get_stats */ void get_stats_core(app * n, unsigned & sz, unsigned & num_unbound_vars) { sz++; @@ -912,7 +912,7 @@ namespace smt { /** \brief Process registers in m_todo. The registers in m_todo that produce non-BIND operations are processed first. Then, - a single BIND operation b is produced. + a single BIND operation b is produced. After executing this method m_todo will contain the registers in m_todo that produce BIND operations and were @@ -942,7 +942,7 @@ namespace smt { m_vars[var_id] = reg; continue; } - + SASSERT(is_app(p)); if (to_app(p)->is_ground()) { @@ -988,7 +988,7 @@ namespace smt { // change the first_app m_aux.push_back(first_app_reg); first_app = to_app(p); - first_app_reg = reg; + first_app_reg = reg; first_app_sz = sz; first_app_num_unbound_vars = num_unbound_vars; } @@ -1000,7 +1000,7 @@ namespace smt { } else { first_app = to_app(p); - first_app_reg = reg; + first_app_reg = reg; get_stats(first_app, first_app_sz, first_app_num_unbound_vars); } } @@ -1069,7 +1069,7 @@ namespace smt { has_unbound_vars = false; return get_num_bound_vars_core(n, has_unbound_vars); } - + /** \brief Compile a pattern where all free variables are already bound. Return the register where the enode congruent to f will be stored. @@ -1141,7 +1141,7 @@ namespace smt { approx_set s; if (m_use_filters) s.insert(m_lbl_hasher(lbl)); - + if (found_bounded_mp) { gen_mp_filter(p); } @@ -1156,17 +1156,17 @@ namespace smt { SASSERT(!is_quantifier(curr)); set_register(oreg + j, curr); m_todo.push_back(oreg + j); - + if ((is_var(curr) && m_vars[to_var(curr)->get_idx()] >= 0) || (is_app(curr) && (to_app(curr)->is_ground()))) has_depth1_joint = true; } - + if (has_depth1_joint) { for (unsigned j = 0; j < num_args; j++) { expr * curr = p->get_arg(j); - + if (is_var(curr)) { unsigned var_id = to_var(curr)->get_idx(); if (m_vars[var_id] >= 0) @@ -1175,15 +1175,15 @@ namespace smt { joints.push_back(NULL_TAG); continue; } - + SASSERT(is_app(curr)); - + if (to_app(curr)->is_ground()) { enode * e = mk_enode(m_context, m_qa, to_app(curr)); joints.push_back(TAG(enode *, e, GROUND_TERM_TAG)); continue; } - + joints.push_back(0); } } @@ -1236,7 +1236,7 @@ namespace smt { m_mp_already_processed[first_idx] = true; linearise_multi_pattern(first_idx); } - + #ifdef Z3DEBUG for (unsigned i = 0; i < m_qa->get_num_decls(); i++) { CTRACE("mam_new_bug", m_vars[i] < 0, tout << mk_ismt2_pp(m_qa, m_ast_manager) << "\ni: " << i << " m_vars[i]: " << m_vars[i] << "\n"; @@ -1248,7 +1248,7 @@ namespace smt { #endif SASSERT(head->m_next == 0); m_seq.push_back(m_ct_manager.mk_yield(m_qa, m_mp, m_qa->get_num_decls(), reinterpret_cast(m_vars.begin()))); - + ptr_vector::iterator it = m_seq.begin(); ptr_vector::iterator end = m_seq.end(); for (; it != end; ++it) { @@ -1268,7 +1268,7 @@ namespace smt { /* The nodes in the bottom of the code-tree can have a lot of children in big examples. Example: - parent-node: + parent-node: (CHOOSE) (CHECK #1 10) (YIELD ...) (CHOOSE) (CHECK #2 10) (YIELD ...) (CHOOSE) (CHECK #3 10) (YIELD ...) @@ -1277,9 +1277,9 @@ namespace smt { (CHOOSE) (CHECK #6 10) (YIELD ...) (CHOOSE) (CHECK #7 10) (YIELD ...) (CHOOSE) (CHECK #8 10) (YIELD ...) - ... + ... The method find_best_child will traverse this big list, and usually will not find - a compatible child. So, I limit the number of simple code sequences that can be + a compatible child. So, I limit the number of simple code sequences that can be traversed. */ #define FIND_BEST_CHILD_THRESHOLD 64 @@ -1305,11 +1305,11 @@ namespace smt { } return best_child; } - + bool is_compatible(bind * instr) const { unsigned ireg = instr->m_ireg; expr * n = m_registers[ireg]; - return + return n != 0 && is_app(n) && // It is wasteful to use a bind of a ground term. @@ -1318,15 +1318,15 @@ namespace smt { to_app(n)->get_decl() == instr->m_label && to_app(n)->get_num_args() == instr->m_num_args; } - + bool is_compatible(compare * instr) const { unsigned reg1 = instr->m_reg1; unsigned reg2 = instr->m_reg2; - return + return m_registers[reg1] != 0 && m_registers[reg1] == m_registers[reg2]; } - + bool is_compatible(check * instr) const { unsigned reg = instr->m_reg; enode * n = instr->m_enode; @@ -1366,25 +1366,25 @@ namespace smt { } /** - \brief We say a check operation is semi compatible if + \brief We say a check operation is semi compatible if it access a register that was not yet processed, and given reg = instr->m_reg 1- is_ground(m_registers[reg]) 2- get_pat_lbl_hash(reg) == m_enode->get_lbl_hash() - + If that is the case, then a CFILTER is created */ bool is_semi_compatible(check * instr) const { unsigned reg = instr->m_reg; - return + return m_registers[reg] != 0 && // if the register was already checked by another filter, then it doesn't make sense // to check it again. - get_check_mark(reg) == NOT_CHECKED && - is_ground(m_registers[reg]) && + get_check_mark(reg) == NOT_CHECKED && + is_ground(m_registers[reg]) && get_pat_lbl_hash(reg) == instr->m_enode->get_lbl_hash(); } - + /** \brief FILTER is not compatible with ground terms anymore. See CFILTER is the filter used for ground terms. @@ -1411,20 +1411,20 @@ namespace smt { } return false; } - + /** \brief See comments at is_semi_compatible(check * instr) and is_compatible(filter * instr). Remark: FILTER is not compatible with ground terms anymore */ bool is_semi_compatible(filter * instr) const { unsigned reg = instr->m_reg; - return + return m_registers[reg] != 0 && get_check_mark(reg) == NOT_CHECKED && is_app(m_registers[reg]) && !is_ground(m_registers[reg]); } - + bool is_compatible(cont * instr) const { unsigned oreg = instr->m_oreg; for (unsigned i = 0; i < instr->m_num_args; i++) @@ -1441,7 +1441,7 @@ namespace smt { many operations in the branch starting at child are compatible with the patterns in the registers stored in m_todo. - Set simple to true, if the tree starting at child is too simple + Set simple to true, if the tree starting at child is too simple (no branching and less than SIMPLE_SEQ_THRESHOLD instructions) */ unsigned get_compatibility_measure(choose * child, bool & simple) { @@ -1453,7 +1453,7 @@ namespace smt { while (curr != 0 && curr->m_opcode != CHOOSE && curr->m_opcode != NOOP) { num_instr++; switch (curr->m_opcode) { - case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: + case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: if (is_compatible(static_cast(curr))) { weight += 4; // the weight of BIND is bigger than COMPARE and CHECK unsigned ireg = static_cast(curr)->m_ireg; @@ -1512,7 +1512,7 @@ namespace smt { while (curr != 0 && curr->m_opcode != CHOOSE && curr->m_opcode != NOOP) { TRACE("mam_compiler_detail", tout << "processing instr: " << *curr << "\n";); switch (curr->m_opcode) { - case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: + case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: if (is_compatible(static_cast(curr))) { TRACE("mam_compiler_detail", tout << "compatible\n";); unsigned ireg = static_cast(curr)->m_ireg; @@ -1613,7 +1613,7 @@ namespace smt { TRACE("mam_compiler_detail", tout << "compatible\n";); unsigned reg = static_cast(curr)->m_reg; CTRACE("mam_compiler_bug", !m_todo.contains(reg), { - for (unsigned i = 0; i < m_todo.size(); i++) { tout << m_todo[i] << " "; } + for (unsigned i = 0; i < m_todo.size(); i++) { tout << m_todo[i] << " "; } tout << "\nregisters:\n"; for (unsigned i = 0; i < m_registers.size(); i++) { if (m_registers[i]) { tout << i << ":\n" << mk_pp(m_registers[i], m_ast_manager) << "\n"; } } tout << "quantifier:\n" << mk_pp(m_qa, m_ast_manager) << "\n"; @@ -1630,7 +1630,7 @@ namespace smt { TRACE("mam_compiler_detail", tout << "semi compatible\n";); unsigned reg = static_cast(curr)->m_reg; CTRACE("mam_compiler_bug", !m_todo.contains(reg), { - for (unsigned i = 0; i < m_todo.size(); i++) { tout << m_todo[i] << " "; } + for (unsigned i = 0; i < m_todo.size(); i++) { tout << m_todo[i] << " "; } tout << "\nregisters:\n"; for (unsigned i = 0; i < m_registers.size(); i++) { if (m_registers[i]) { tout << i << ":\n" << mk_pp(m_registers[i], m_ast_manager) << "\n"; } } tout << "quantifier:\n" << mk_pp(m_qa, m_ast_manager) << "\n"; @@ -1638,7 +1638,7 @@ namespace smt { }); SASSERT(m_todo.contains(reg)); unsigned h = get_pat_lbl_hash(reg); - TRACE("mam_lbl_bug", + TRACE("mam_lbl_bug", tout << "curr_set: " << static_cast(curr)->m_lbl_set << "\n"; tout << "new hash: " << h << "\n";); set_check_mark(reg, CHECK_SET); @@ -1650,7 +1650,7 @@ namespace smt { else { SASSERT(s.size() == 1); approx_set new_s(s); - new_s.insert(h); + new_s.insert(h); filter * new_instr = m_ct_manager.mk_filter(reg, new_s); m_compatible.push_back(new_instr); m_incompatible.push_back(curr); @@ -1669,11 +1669,11 @@ namespace smt { last = curr; curr = curr->m_next; } - + TRACE("mam_compiler", tout << *head << " " << head << "\n"; tout << "m_compatible.size(): " << m_compatible.size() << "\n"; tout << "m_incompatible.size(): " << m_incompatible.size() << "\n";); - + if (m_incompatible.empty()) { // sequence starting at head is fully compatible SASSERT(curr != 0); @@ -1756,19 +1756,19 @@ namespace smt { context & get_context() { return m_context; } - + /** \brief Create a new code tree for the given quantifier. - mp: is a pattern of qa that will be used to create the code tree - + - first_idx: index of mp that will be the "head" (first to be processed) of the multi-pattern. */ code_tree * mk_tree(quantifier * qa, app * mp, unsigned first_idx, bool filter_candidates) { SASSERT(m_ast_manager.is_pattern(mp)); app * p = to_app(mp->get_arg(first_idx)); unsigned num_args = p->get_num_args(); - code_tree * r = m_ct_manager.mk_code_tree(p->get_decl(), num_args, filter_candidates); + code_tree * r = m_ct_manager.mk_code_tree(p->get_decl(), num_args, filter_candidates); init(r, qa, mp, first_idx); linearise(r->m_root, first_idx); r->m_num_choices = m_num_choices; @@ -1795,12 +1795,12 @@ namespace smt { if (!is_tmp_tree) m_ct_manager.save_num_regs(tree); init(tree, qa, mp, first_idx); - m_num_choices = tree->m_num_choices; + m_num_choices = tree->m_num_choices; insert(tree->m_root, first_idx); TRACE("mam_bug", tout << "m_num_choices: " << m_num_choices << "\n";); if (m_num_choices > tree->m_num_choices) { - if (!is_tmp_tree) + if (!is_tmp_tree) m_ct_manager.save_num_choices(tree); tree->m_num_choices = m_num_choices; } @@ -1848,7 +1848,7 @@ namespace smt { }; typedef svector backtrack_stack; - + class interpreter { context & m_context; ast_manager & m_ast_manager; @@ -1893,7 +1893,7 @@ namespace smt { if (m_ast_manager.has_trace_stream()) m_used_enodes.push_back(n); } - + // We have to provide the number of expected arguments because we have flat-assoc applications such as +. // Flat-assoc applications may have arbitrary number of arguments. enode * get_first_f_app(func_decl * lbl, unsigned num_expected_args, enode * curr) { @@ -1950,7 +1950,7 @@ namespace smt { SASSERT(n != 0); do { if (n->get_decl() == f && - n->get_arg(0)->get_root() == m_args[0] && + n->get_arg(0)->get_root() == m_args[0] && n->get_arg(1)->get_root() == m_args[1]) { update_max_generation(n); return true; @@ -2001,7 +2001,7 @@ namespace smt { interpreter(context & ctx, mam & m, bool use_filters): m_context(ctx), m_ast_manager(ctx.get_manager()), - m_mam(m), + m_mam(m), m_use_filters(use_filters) { m_args.resize(INIT_ARGS_SIZE, 0); } @@ -2016,7 +2016,7 @@ namespace smt { if (m_backtrack_stack.size() < t->get_num_choices()) m_backtrack_stack.resize(t->get_num_choices()); } - + void execute(code_tree * t) { TRACE("trigger_bug", tout << "execute for code tree:\n"; t->display(tout);); init(t); @@ -2048,7 +2048,7 @@ namespace smt { } } } - + // init(t) must be invoked before execute_core void execute_core(code_tree * t, enode * n); @@ -2085,9 +2085,9 @@ namespace smt { enode_vector::const_iterator end = n->end_parents(); for (; it != end; ++it) { enode * p = *it; - if (p->get_decl() == f && + if (p->get_decl() == f && m_context.is_relevant(p) && - p->is_cgr() && + p->is_cgr() && p->get_arg(i)->get_root() == n) { v->push_back(p); } @@ -2111,7 +2111,7 @@ namespace smt { enode * p = *it1; if (p->get_decl() == j2->m_decl && m_context.is_relevant(p) && - p->is_cgr() && + p->is_cgr() && p->get_arg(j2->m_arg_pos)->get_root() == n) { // p is in joint2 p = p->get_root(); @@ -2121,7 +2121,7 @@ namespace smt { enode * p2 = *it2; if (p2->get_decl() == f && m_context.is_relevant(p2) && - p2->is_cgr() && + p2->is_cgr() && p2->get_arg(i)->get_root() == p) { v->push_back(p2); } @@ -2153,14 +2153,14 @@ namespace smt { goto non_depth1; } r = n->get_root(); - if (m_use_filters && r->get_plbls().empty_intersection(c->m_lbl_set)) + if (m_use_filters && r->get_plbls().empty_intersection(c->m_lbl_set)) return 0; if (r->get_num_parents() == 0) return 0; non_depth1: ; } - // traverse each joint and select the best one. + // traverse each joint and select the best one. enode_vector * best_v = 0; for (unsigned i = 0; i < num_args; i++) { enode * bare = c->m_joints[i]; @@ -2238,16 +2238,16 @@ namespace smt { out << mk_pp(n->get_owner(), m_ast_manager) << "\n"; } } - + void interpreter::display_instr_input_reg(std::ostream & out, const instruction * instr) { switch (instr->m_opcode) { - case INIT1: case INIT2: case INIT3: case INIT4: case INIT5: case INIT6: case INITN: - display_reg(out, 0); + case INIT1: case INIT2: case INIT3: case INIT4: case INIT5: case INIT6: case INITN: + display_reg(out, 0); break; - case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: + case BIND1: case BIND2: case BIND3: case BIND4: case BIND5: case BIND6: case BINDN: display_reg(out, static_cast(instr)->m_ireg); break; - case COMPARE: + case COMPARE: display_reg(out, static_cast(instr)->m_reg1); display_reg(out, static_cast(instr)->m_reg2); break; @@ -2257,7 +2257,7 @@ namespace smt { case FILTER: display_reg(out, static_cast(instr)->m_reg); break; - case YIELD1: case YIELD2: case YIELD3: case YIELD4: case YIELD5: case YIELD6: case YIELDN: + case YIELD1: case YIELD2: case YIELD3: case YIELD4: case YIELD5: case YIELD6: case YIELDN: for (unsigned i = 0; i < static_cast(instr)->m_num_bindings; i++) { display_reg(out, static_cast(instr)->m_bindings[i]); } @@ -2308,7 +2308,7 @@ namespace smt { m_registers[0] = n; m_top = 0; - + main_loop: TRACE("mam_int", display_pc_info(tout);); @@ -2323,7 +2323,7 @@ namespace smt { m_registers[1] = m_app->get_arg(0); m_pc = m_pc->m_next; goto main_loop; - + case INIT2: m_app = m_registers[0]; if (m_app->get_num_args() != 2) @@ -2332,7 +2332,7 @@ namespace smt { m_registers[2] = m_app->get_arg(1); m_pc = m_pc->m_next; goto main_loop; - + case INIT3: m_app = m_registers[0]; if (m_app->get_num_args() != 3) @@ -2342,7 +2342,7 @@ namespace smt { m_registers[3] = m_app->get_arg(2); m_pc = m_pc->m_next; goto main_loop; - + case INIT4: m_app = m_registers[0]; if (m_app->get_num_args() != 4) @@ -2353,9 +2353,9 @@ namespace smt { m_registers[4] = m_app->get_arg(3); m_pc = m_pc->m_next; goto main_loop; - + case INIT5: - m_app = m_registers[0]; + m_app = m_registers[0]; if (m_app->get_num_args() != 5) goto backtrack; m_registers[1] = m_app->get_arg(0); @@ -2365,8 +2365,8 @@ namespace smt { m_registers[5] = m_app->get_arg(4); m_pc = m_pc->m_next; goto main_loop; - - case INIT6: + + case INIT6: m_app = m_registers[0]; if (m_app->get_num_args() != 6) goto backtrack; @@ -2378,7 +2378,7 @@ namespace smt { m_registers[6] = m_app->get_arg(5); m_pc = m_pc->m_next; goto main_loop; - + case INITN: m_app = m_registers[0]; m_num_args = m_app->get_num_args(); @@ -2388,7 +2388,7 @@ namespace smt { m_registers[i+1] = m_app->get_arg(i); m_pc = m_pc->m_next; goto main_loop; - + case COMPARE: m_n1 = m_registers[static_cast(m_pc)->m_reg1]; m_n2 = m_registers[static_cast(m_pc)->m_reg2]; @@ -2398,7 +2398,7 @@ namespace smt { goto backtrack; m_pc = m_pc->m_next; goto main_loop; - + case CHECK: m_n1 = m_registers[static_cast(m_pc)->m_reg]; m_n2 = static_cast(m_pc)->m_enode; @@ -2413,21 +2413,21 @@ namespace smt { The compiler will never merge two CFILTERs with different m_lbl_set fields. Essentially, CFILTER is used to combine CHECK statements, and FILTER for BIND */ - case CFILTER: + case CFILTER: case FILTER: m_n1 = m_registers[static_cast(m_pc)->m_reg]->get_root(); - if (static_cast(m_pc)->m_lbl_set.empty_intersection(m_n1->get_lbls())) + if (static_cast(m_pc)->m_lbl_set.empty_intersection(m_n1->get_lbls())) goto backtrack; m_pc = m_pc->m_next; goto main_loop; case PFILTER: m_n1 = m_registers[static_cast(m_pc)->m_reg]->get_root(); - if (static_cast(m_pc)->m_lbl_set.empty_intersection(m_n1->get_plbls())) + if (static_cast(m_pc)->m_lbl_set.empty_intersection(m_n1->get_plbls())) goto backtrack; m_pc = m_pc->m_next; goto main_loop; - + case CHOOSE: m_backtrack_stack[m_top].m_instr = m_pc; m_backtrack_stack[m_top].m_old_max_generation = m_max_generation; @@ -2439,7 +2439,7 @@ namespace smt { SASSERT(static_cast(m_pc)->m_alt == 0); m_pc = m_pc->m_next; goto main_loop; - + case BIND1: #define BIND_COMMON() \ m_n1 = m_registers[static_cast(m_pc)->m_ireg]; \ @@ -2456,19 +2456,19 @@ namespace smt { m_backtrack_stack[m_top].m_old_used_enodes_size = m_curr_used_enodes_size; \ m_backtrack_stack[m_top].m_curr = m_app; \ m_top++; - + BIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); m_pc = m_pc->m_next; goto main_loop; - + case BIND2: BIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); m_registers[m_oreg+1] = m_app->get_arg(1); m_pc = m_pc->m_next; goto main_loop; - + case BIND3: BIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2476,7 +2476,7 @@ namespace smt { m_registers[m_oreg+2] = m_app->get_arg(2); m_pc = m_pc->m_next; goto main_loop; - + case BIND4: BIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2485,7 +2485,7 @@ namespace smt { m_registers[m_oreg+3] = m_app->get_arg(3); m_pc = m_pc->m_next; goto main_loop; - + case BIND5: BIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2495,7 +2495,7 @@ namespace smt { m_registers[m_oreg+4] = m_app->get_arg(4); m_pc = m_pc->m_next; goto main_loop; - + case BIND6: BIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2506,7 +2506,7 @@ namespace smt { m_registers[m_oreg+5] = m_app->get_arg(5); m_pc = m_pc->m_next; goto main_loop; - + case BINDN: BIND_COMMON(); m_num_args = static_cast(m_pc)->m_num_args; @@ -2529,20 +2529,20 @@ namespace smt { m_max_generation, m_used_enodes) ON_MATCH(1); goto backtrack; - + case YIELD2: m_bindings[0] = m_registers[static_cast(m_pc)->m_bindings[1]]; m_bindings[1] = m_registers[static_cast(m_pc)->m_bindings[0]]; ON_MATCH(2); goto backtrack; - + case YIELD3: m_bindings[0] = m_registers[static_cast(m_pc)->m_bindings[2]]; m_bindings[1] = m_registers[static_cast(m_pc)->m_bindings[1]]; m_bindings[2] = m_registers[static_cast(m_pc)->m_bindings[0]]; ON_MATCH(3); goto backtrack; - + case YIELD4: m_bindings[0] = m_registers[static_cast(m_pc)->m_bindings[3]]; m_bindings[1] = m_registers[static_cast(m_pc)->m_bindings[2]]; @@ -2550,7 +2550,7 @@ namespace smt { m_bindings[3] = m_registers[static_cast(m_pc)->m_bindings[0]]; ON_MATCH(4); goto backtrack; - + case YIELD5: m_bindings[0] = m_registers[static_cast(m_pc)->m_bindings[4]]; m_bindings[1] = m_registers[static_cast(m_pc)->m_bindings[3]]; @@ -2559,7 +2559,7 @@ namespace smt { m_bindings[4] = m_registers[static_cast(m_pc)->m_bindings[0]]; ON_MATCH(5); goto backtrack; - + case YIELD6: m_bindings[0] = m_registers[static_cast(m_pc)->m_bindings[5]]; m_bindings[1] = m_registers[static_cast(m_pc)->m_bindings[4]]; @@ -2569,10 +2569,10 @@ namespace smt { m_bindings[5] = m_registers[static_cast(m_pc)->m_bindings[0]]; ON_MATCH(6); goto backtrack; - + case YIELDN: m_num_args = static_cast(m_pc)->m_num_bindings; - for (unsigned i = 0; i < m_num_args; i++) + for (unsigned i = 0; i < m_num_args; i++) m_bindings[i] = m_registers[static_cast(m_pc)->m_bindings[m_num_args - i - 1]]; ON_MATCH(m_num_args); goto backtrack; @@ -2590,7 +2590,7 @@ namespace smt { m_registers[static_cast(m_pc)->m_oreg] = m_n1; \ m_pc = m_pc->m_next; \ goto main_loop; - + #define SET_VAR(IDX) \ m_args[IDX] = m_registers[static_cast(m_pc)->m_iregs[IDX]]; \ if (m_use_filters && static_cast(m_pc)->m_lbl_set.empty_intersection(m_args[IDX]->get_root()->get_plbls())) { \ @@ -2599,7 +2599,7 @@ namespace smt { tout << "node set: "; m_args[IDX]->get_root()->get_plbls().display(tout); tout << "\n";); \ goto backtrack; \ } - + SET_VAR(0); GET_CGR_COMMON(); @@ -2644,11 +2644,11 @@ namespace smt { for (unsigned i = 0; i < m_num_args; i++) m_args[i] = m_registers[static_cast(m_pc)->m_iregs[i]]; GET_CGR_COMMON(); - + case IS_CGR: - if (!exec_is_cgr(static_cast(m_pc))) - goto backtrack; - m_pc = m_pc->m_next; + if (!exec_is_cgr(static_cast(m_pc))) + goto backtrack; + m_pc = m_pc->m_next; goto main_loop; case CONTINUE: @@ -2659,13 +2659,13 @@ namespace smt { goto backtrack; m_pattern_instances.push_back(m_app); TRACE("mam_int", tout << "continue candidate:\n" << mk_ll_pp(m_app->get_owner(), m_ast_manager);); - for (unsigned i = 0; i < m_num_args; i++) + for (unsigned i = 0; i < m_num_args; i++) m_registers[m_oreg+i] = m_app->get_arg(i); m_pc = m_pc->m_next; goto main_loop; } - + backtrack: TRACE("mam_int", tout << "backtracking.\n";); if (m_top == 0) { @@ -2723,19 +2723,19 @@ namespace smt { bp.m_curr = m_app; \ TRACE("mam_int", tout << "bind next candidate:\n" << mk_ll_pp(m_app->get_owner(), m_ast_manager);); \ m_oreg = m_b->m_oreg - + BBIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); m_pc = m_b->m_next; goto main_loop; - + case BIND2: BBIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); m_registers[m_oreg+1] = m_app->get_arg(1); m_pc = m_b->m_next; goto main_loop; - + case BIND3: BBIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2743,7 +2743,7 @@ namespace smt { m_registers[m_oreg+2] = m_app->get_arg(2); m_pc = m_b->m_next; goto main_loop; - + case BIND4: BBIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2752,7 +2752,7 @@ namespace smt { m_registers[m_oreg+3] = m_app->get_arg(3); m_pc = m_b->m_next; goto main_loop; - + case BIND5: BBIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2762,7 +2762,7 @@ namespace smt { m_registers[m_oreg+4] = m_app->get_arg(4); m_pc = m_b->m_next; goto main_loop; - + case BIND6: BBIND_COMMON(); m_registers[m_oreg] = m_app->get_arg(0); @@ -2773,7 +2773,7 @@ namespace smt { m_registers[m_oreg+5] = m_app->get_arg(5); m_pc = m_b->m_next; goto main_loop; - + case BINDN: BBIND_COMMON(); m_num_args = m_b->m_num_args; @@ -2781,7 +2781,7 @@ namespace smt { m_registers[m_oreg+i] = m_app->get_arg(i); m_pc = m_b->m_next; goto main_loop; - + case CONTINUE: ++bp.m_it; for (; bp.m_it != bp.m_end; ++bp.m_it) { @@ -2815,7 +2815,7 @@ namespace smt { recycle_enode_vector(bp.m_to_recycle); m_top--; goto backtrack; - + default: UNREACHABLE(); } @@ -2835,8 +2835,8 @@ namespace smt { } // ------------------------------------ - // - // A mapping from func_label -> code tree. + // + // A mapping from func_label -> code tree. // // ------------------------------------ class code_tree_map { @@ -2858,7 +2858,7 @@ namespace smt { m_trees[m_lbl_id] = 0; } }; - + public: code_tree_map(ast_manager & m, compiler & c, mam_trail_stack & s): m_ast_manager(m), @@ -2876,9 +2876,9 @@ namespace smt { /** \brief Add a pattern to the code tree map. - + - mp: is used a pattern for qa. - + - first_idx: index to be used as head of the multi-pattern mp */ void add_pattern(quantifier * qa, app * mp, unsigned first_idx) { @@ -2933,11 +2933,11 @@ namespace smt { }; // ------------------------------------ - // + // // Path trees AKA inverted path index // // ------------------------------------ - + /** \brief Temporary object used to encode a path of the form: @@ -2948,7 +2948,7 @@ namespace smt { parents p_0 of n that are f-applications, and n is the second argument, then for each such p_0, I want to follow the parents p_1 of p_0 that are g-applications, and p_0 is the third argument. Finally, I want to - follow the p_2 parents of p_1 that are h-applications and p_1 is the + follow the p_2 parents of p_1 that are h-applications and p_1 is the first argument of p_2. To improve the filtering power of the inverse path index, I'm also @@ -2961,11 +2961,11 @@ namespace smt { The idea is that I want only the f-parents s.t. the third argument is equal to t. */ struct path { - func_decl * m_label; + func_decl * m_label; unsigned short m_arg_idx; unsigned short m_ground_arg_idx; enode * m_ground_arg; - unsigned m_pattern_idx; + unsigned m_pattern_idx; path * m_child; path (func_decl * lbl, unsigned short arg_idx, unsigned short ground_arg_idx, enode * ground_arg, unsigned pat_idx, path * child): m_label(lbl), @@ -2977,7 +2977,7 @@ namespace smt { SASSERT(ground_arg != 0 || ground_arg_idx == 0); } }; - + bool is_equal(path const * p1, path const * p2) { for (;;) { if (p1->m_label != p2->m_label || @@ -2986,15 +2986,15 @@ namespace smt { (p1->m_child == 0) != (p2->m_child == 0)) { return false; } - + if (p1->m_child == 0 && p2->m_child == 0) return true; - + p1 = p1->m_child; p2 = p2->m_child; } } - + typedef ptr_vector paths; /** @@ -3009,7 +3009,7 @@ namespace smt { approx_set m_filter; path_tree * m_sibling; path_tree * m_first_child; - enode_vector * m_todo; // temporary field used to collect candidates + enode_vector * m_todo; // temporary field used to collect candidates #ifdef _PROFILE_PATH_TREE stopwatch m_watch; unsigned m_counter; @@ -3017,7 +3017,7 @@ namespace smt { unsigned m_num_neq_visited; bool m_already_displayed; //!< true if the path_tree was already displayed after reaching _PROFILE_PATH_TREE_THRESHOLD #endif - + path_tree(path * p, label_hasher & h): m_label(p->m_label), m_arg_idx(p->m_arg_idx), @@ -3047,7 +3047,7 @@ namespace smt { #ifdef _PROFILE_PATH_TREE out << ", counter: " << m_counter << ", num_eq_visited: " << m_num_eq_visited << ", num_neq_visited: " << m_num_neq_visited << ", avg. : " << static_cast(m_num_neq_visited)/static_cast(m_num_neq_visited+m_num_eq_visited); -#endif +#endif out << "\n"; curr->m_first_child->display(out, indent+1); curr = curr->m_sibling; @@ -3058,7 +3058,7 @@ namespace smt { typedef std::pair path_tree_pair; // ------------------------------------ - // + // // Matching Abstract Machine Implementation // // ------------------------------------ @@ -3071,8 +3071,8 @@ namespace smt { code_tree_manager m_ct_manager; compiler m_compiler; interpreter m_interpreter; - code_tree_map m_trees; - + code_tree_map m_trees; + ptr_vector m_tmp_trees; ptr_vector m_tmp_trees_to_delete; ptr_vector m_to_match; @@ -3088,11 +3088,11 @@ namespace smt { // auxiliary field used to update data-structures... typedef ptr_vector func_decls; - vector m_var_parent_labels; + vector m_var_parent_labels; region & m_region; region m_tmp_region; - path_tree_pair m_pp[APPROX_SET_CAPACITY][APPROX_SET_CAPACITY]; + path_tree_pair m_pp[APPROX_SET_CAPACITY][APPROX_SET_CAPACITY]; path_tree * m_pc[APPROX_SET_CAPACITY][APPROX_SET_CAPACITY]; pool m_pool; @@ -3105,7 +3105,7 @@ namespace smt { enode * m_r1; // temp field enode * m_r2; // temp field - + class add_shared_enode_trail; friend class add_shared_enode_trail; @@ -3125,7 +3125,7 @@ namespace smt { r->reset(); return r; } - + void recycle(enode_vector * v) { m_pool.recycle(v); } @@ -3133,12 +3133,12 @@ namespace smt { void add_candidate(code_tree * t, enode * app) { if (t != 0) { TRACE("mam_candidate", tout << "adding candidate:\n" << mk_ll_pp(app->get_owner(), m_ast_manager);); - if (!t->has_candidates()) + if (!t->has_candidates()) m_to_match.push_back(t); t->add_candidate(app); } } - + void add_candidate(enode * app) { func_decl * lbl = app->get_decl(); add_candidate(m_trees.get_code_tree_for(lbl), app); @@ -3152,7 +3152,7 @@ namespace smt { unsigned lbl_id = lbl->get_decl_id(); return lbl_id < m_is_clbl.size() && m_is_clbl[lbl_id]; } - + void update_lbls(enode * n, unsigned elem) { approx_set & r_lbls = n->get_root()->get_lbls(); if (!r_lbls.may_contain(elem)) { @@ -3203,14 +3203,14 @@ namespace smt { } } } - + void update_plbls(func_decl * lbl) { unsigned lbl_id = lbl->get_decl_id(); m_is_plbl.reserve(lbl_id+1, false); TRACE("trigger_bug", tout << "update_plbls: " << lbl->get_name() << " is already plbl: " << m_is_plbl[lbl_id] << ", lbl_id: " << lbl_id << "\n"; tout << "mam: " << this << "\n";); TRACE("mam_bug", tout << "update_plbls: " << lbl->get_name() << " is already plbl: " << m_is_plbl[lbl_id] << "\n";); - if (m_is_plbl[lbl_id]) + if (m_is_plbl[lbl_id]) return; m_trail_stack.push(set_bitvector_trail(m_is_plbl, lbl_id)); SASSERT(m_is_plbl[lbl_id]); @@ -3220,7 +3220,7 @@ namespace smt { enode_vector::const_iterator end = m_context.end_enodes_of(lbl); for (; it != end; ++it) { enode * app = *it; - if (m_context.is_relevant(app)) + if (m_context.is_relevant(app)) update_children_plbls(app, h); } } @@ -3234,12 +3234,12 @@ namespace smt { } } } - + code_tree * mk_code(quantifier * qa, app * mp, unsigned pat_idx) { SASSERT(m_ast_manager.is_pattern(mp)); - return m_compiler.mk_tree(qa, mp, pat_idx, true); + return m_compiler.mk_tree(qa, mp, pat_idx, true); } - + void insert_code(path_tree * t, quantifier * qa, app * mp, unsigned pat_idx) { SASSERT(m_ast_manager.is_pattern(mp)); m_compiler.insert(t->m_code, qa, mp, pat_idx, false); @@ -3254,7 +3254,7 @@ namespace smt { path_tree * prev = 0; while (p != 0) { curr = new (m_region) path_tree(p, m_lbl_hasher); - if (prev) + if (prev) prev->m_first_child = curr; if (!head) head = curr; @@ -3274,7 +3274,7 @@ namespace smt { while (t != 0) { if (t->m_label == p->m_label) { found_label = true; - if (t->m_arg_idx == p->m_arg_idx && + if (t->m_arg_idx == p->m_arg_idx && t->m_ground_arg == p->m_ground_arg && t->m_ground_arg_idx == p->m_ground_arg_idx ) { @@ -3326,7 +3326,7 @@ namespace smt { m_trail_stack.push(set_ptr_trail(m_pc[h1][h2])); m_pc[h1][h2] = mk_path_tree(p, qa, mp); } - TRACE("mam_path_tree_updt", + TRACE("mam_path_tree_updt", tout << "updated path tree:\n"; m_pc[h1][h2]->display(tout, 2);); } @@ -3343,7 +3343,7 @@ namespace smt { m_trail_stack.push(set_ptr_trail(m_pp[h1][h2].first)); m_pp[h1][h2].first = mk_path_tree(p1, qa, mp); insert(m_pp[h1][h2].first, p2, qa, mp); - } + } } else { if (h1 > h2) { @@ -3364,7 +3364,7 @@ namespace smt { m_pp[h1][h2].second = mk_path_tree(p2, qa, mp); } } - TRACE("mam_path_tree_updt", + TRACE("mam_path_tree_updt", tout << "updated path tree:\n"; SASSERT(h1 <= h2); m_pp[h1][h2].first->display(tout, 2); @@ -3418,28 +3418,28 @@ namespace smt { for (unsigned short i = 0; i < num_args; i++) { expr * child = pat->get_arg(i); path * new_path = new (m_tmp_region) path(plbl, i, ground_arg_pos, ground_arg, pat_idx, p); - + if (is_var(child)) { update_vars(to_var(child)->get_idx(), new_path, qa, mp); continue; } SASSERT(is_app(child)); - + if (to_app(child)->is_ground()) { enode * n = mk_enode(m_context, qa, to_app(child)); update_plbls(plbl); if (!n->has_lbl_hash()) n->set_lbl_hash(m_context); - TRACE("mam_bug", - tout << "updating pc labels " << plbl->get_name() << " " << + TRACE("mam_bug", + tout << "updating pc labels " << plbl->get_name() << " " << static_cast(n->get_lbl_hash()) << "\n"; tout << "#" << n->get_owner_id() << " " << n->get_root()->get_lbls() << "\n"; tout << "relevant: " << m_context.is_relevant(n) << "\n";); update_pc(m_lbl_hasher(plbl), n->get_lbl_hash(), new_path, qa, mp); continue; } - + func_decl * clbl = to_app(child)->get_decl(); TRACE("mam_bug", tout << "updating pc labels " << plbl->get_name() << " " << clbl->get_name() << "\n";); update_plbls(plbl); @@ -3468,7 +3468,7 @@ namespace smt { // (p_n, p_2, ..., p_1) unsigned num_patterns = mp->get_num_args(); for (unsigned i = 0; i < num_patterns; i++) { - app * pat = to_app(mp->get_arg(i)); + app * pat = to_app(mp->get_arg(i)); update_filters(pat, 0, qa, mp, i); } } @@ -3495,7 +3495,7 @@ namespace smt { \brief Check equality modulo the equality m_r1 = m_r2 */ bool is_eq(enode * n1, enode * n2) { - return + return n1->get_root() == n2->get_root() || (n1->get_root() == m_r1 && n2->get_root() == m_r2) || (n2->get_root() == m_r1 && n1->get_root() == m_r2); @@ -3524,7 +3524,7 @@ namespace smt { #ifdef _PROFILE_PATH_TREE t->m_counter++; #endif - TRACE("mam_path_tree", + TRACE("mam_path_tree", tout << "processing:\n"; t->display(tout, 2);); enode_vector * v = t->m_todo; @@ -3552,13 +3552,13 @@ namespace smt { // // In a previous version of Z3, the "enode mark field" was used to mark both cases. This is incorrect, // and Z3 may fail to find potential new matches. - // + // // The file regression\acu.sx exposed this problem. enode * curr_child = (*it1)->get_root(); - + if (m_use_filters && curr_child->get_plbls().empty_intersection(filter)) continue; - + #ifdef _PROFILE_PATH_TREE static unsigned counter2 = 0; static unsigned total_sz2 = 0; @@ -3571,7 +3571,7 @@ namespace smt { std::cout << "Avg2. " << static_cast(total_sz2)/static_cast(counter2) << ", Max2. " << max_sz2 << "\n"; #endif - TRACE("mam_path_tree", tout << "processing: #" << curr_child->get_owner_id() << "\n";); + TRACE("mam_path_tree", tout << "processing: #" << curr_child->get_owner_id() << "\n";); enode_vector::const_iterator it2 = curr_child->begin_parents(); enode_vector::const_iterator end2 = curr_child->end_parents(); for (; it2 != end2; ++it2) { @@ -3594,7 +3594,7 @@ namespace smt { if (filter.may_contain(m_lbl_hasher(lbl)) && !curr_parent->is_marked() && (curr_parent_cg == curr_parent || !is_eq(curr_parent_cg, curr_parent_root)) && - m_context.is_relevant(curr_parent) + m_context.is_relevant(curr_parent) ) { path_tree * curr_tree = t; while (curr_tree) { @@ -3693,14 +3693,14 @@ namespace smt { } if (n_plbl1 == n_plbl2) { SASSERT(m_pp[n_plbl1][n_plbl2].second == 0); - if (n_r1->get_num_parents() <= n_r2->get_num_parents()) + if (n_r1->get_num_parents() <= n_r2->get_num_parents()) collect_parents(n_r1, m_pp[n_plbl1][n_plbl2].first); else collect_parents(n_r2, m_pp[n_plbl1][n_plbl2].first); } else { SASSERT(n_plbl1 < n_plbl2); - if (n_r1->get_num_parents() <= n_r2->get_num_parents()) + if (n_r1->get_num_parents() <= n_r2->get_num_parents()) collect_parents(n_r1, m_pp[n_plbl1][n_plbl2].first); else collect_parents(n_r2, m_pp[n_plbl1][n_plbl2].second); @@ -3773,7 +3773,7 @@ namespace smt { enode_vector::const_iterator end3 = m_context.end_enodes_of(lbl); for (; it3 != end3; ++it3) { enode * app = *it3; - if (m_context.is_relevant(app)) + if (m_context.is_relevant(app)) m_interpreter.execute_core(tmp_tree, app); } m_tmp_trees[lbl_id] = 0; @@ -3786,7 +3786,7 @@ namespace smt { ptr_buffer todo; unsigned num_patterns = mp->get_num_args(); for (unsigned i = 0; i < num_patterns; i++) { - app * pat = to_app(mp->get_arg(i)); + app * pat = to_app(mp->get_arg(i)); TRACE("mam_pat", tout << mk_ismt2_pp(qa, m_ast_manager) << "\npat:\n" << mk_ismt2_pp(pat, m_ast_manager) << "\n";); SASSERT(!pat->is_ground()); todo.push_back(pat); @@ -3812,7 +3812,7 @@ namespace smt { public: mam_impl(context & ctx, bool use_filters): - mam(ctx), + mam(ctx), m_ast_manager(ctx.get_manager()), m_use_filters(use_filters), m_trail_stack(*this), @@ -3827,7 +3827,7 @@ namespace smt { DEBUG_CODE(m_check_missing_instances = false;); reset_pp_pc(); } - + virtual ~mam_impl() { m_trail_stack.reset(); } @@ -3854,11 +3854,11 @@ namespace smt { for (unsigned i = 0; i < num_patterns; i++) m_trees.add_pattern(qa, mp, i); } - + virtual void push_scope() { m_trail_stack.push_scope(); } - + virtual void pop_scope(unsigned num_scopes) { if (!m_to_match.empty()) { ptr_vector::iterator it = m_to_match.begin(); @@ -3894,8 +3894,8 @@ namespace smt { (*it)->display(out); } } - - virtual void match() { + + virtual void match() { TRACE("trigger_bug", tout << "match\n"; display(tout);); ptr_vector::iterator it = m_to_match.begin(); ptr_vector::iterator end = m_to_match.end(); @@ -3925,7 +3925,7 @@ namespace smt { enode_vector::const_iterator end2 = m_context.end_enodes_of(lbl); for (; it2 != end2; ++it2) { enode * curr = *it2; - if (use_irrelevant || m_context.is_relevant(curr)) + if (use_irrelevant || m_context.is_relevant(curr)) m_interpreter.execute_core(t, curr); } } @@ -3940,13 +3940,13 @@ namespace smt { return true; } #endif - + virtual void on_match(quantifier * qa, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation, ptr_vector & used_enodes) { TRACE("trigger_bug", tout << "found match " << mk_pp(qa, m_ast_manager) << "\n";); #ifdef Z3DEBUG if (m_check_missing_instances) { if (!m_context.slow_contains_instance(qa, num_bindings, bindings)) { - TRACE("missing_instance", + TRACE("missing_instance", tout << "qa:\n" << mk_ll_pp(qa, m_ast_manager) << "\npat:\n" << mk_ll_pp(pat, m_ast_manager); for (unsigned i = 0; i < num_bindings; i++) tout << "#" << bindings[i]->get_owner_id() << "\n" << mk_ll_pp(bindings[i]->get_owner(), m_ast_manager) << "\n"; @@ -3967,23 +3967,23 @@ namespace smt { virtual bool is_shared(enode * n) const { return !m_shared_enodes.empty() && m_shared_enodes.contains(n); } - + // This method is invoked when n becomes relevant. // If lazy == true, then n is not added to the list of candidate enodes for matching. That is, the method just updates the lbls. virtual void relevant_eh(enode * n, bool lazy) { TRACE("trigger_bug", tout << "relevant_eh:\n" << mk_ismt2_pp(n->get_owner(), m_ast_manager) << "\n"; tout << "mam: " << this << "\n";); TRACE("mam", tout << "relevant_eh: #" << n->get_owner_id() << "\n";); - if (n->has_lbl_hash()) + if (n->has_lbl_hash()) update_lbls(n, n->get_lbl_hash()); - + if (n->get_num_args() > 0) { func_decl * lbl = n->get_decl(); unsigned h = m_lbl_hasher(lbl); - TRACE("trigger_bug", tout << "lbl: " << lbl->get_name() << " is_clbl(lbl): " << is_clbl(lbl) + TRACE("trigger_bug", tout << "lbl: " << lbl->get_name() << " is_clbl(lbl): " << is_clbl(lbl) << ", is_plbl(lbl): " << is_plbl(lbl) << ", h: " << h << "\n"; tout << "lbl_id: " << lbl->get_decl_id() << "\n";); - if (is_clbl(lbl)) + if (is_clbl(lbl)) update_lbls(n, h); if (is_plbl(lbl)) update_children_plbls(n, h); @@ -4002,28 +4002,28 @@ namespace smt { flet l2(m_r2, r2); TRACE("mam", tout << "add_eq_eh: #" << r1->get_owner_id() << " #" << r2->get_owner_id() << "\n";); - TRACE("mam_inc_bug_detail", m_context.display(tout);); - TRACE("mam_inc_bug", + TRACE("mam_inc_bug_detail", m_context.display(tout);); + TRACE("mam_inc_bug", tout << "before:\n#" << r1->get_owner_id() << " #" << r2->get_owner_id() << "\n"; tout << "r1.lbls: " << r1->get_lbls() << "\n"; tout << "r2.lbls: " << r2->get_lbls() << "\n"; tout << "r1.plbls: " << r1->get_plbls() << "\n"; tout << "r2.plbls: " << r2->get_plbls() << "\n";); - + process_pc(r1, r2); process_pc(r2, r1); process_pp(r1, r2); - + approx_set r1_plbls = r1->get_plbls(); approx_set & r2_plbls = r2->get_plbls(); approx_set r1_lbls = r1->get_lbls(); approx_set & r2_lbls = r2->get_lbls(); - + m_trail_stack.push(mam_value_trail(r2_lbls)); m_trail_stack.push(mam_value_trail(r2_plbls)); r2_lbls |= r1_lbls; - r2_plbls |= r1_plbls; - TRACE("mam_inc_bug", + r2_plbls |= r1_plbls; + TRACE("mam_inc_bug", tout << "after:\n"; tout << "r1.lbls: " << r1->get_lbls() << "\n"; tout << "r2.lbls: " << r2->get_lbls() << "\n"; From b2d590e0c9a5a11b955a7faea461bc45b688ce58 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Aug 2017 16:00:59 +0100 Subject: [PATCH 132/488] Bugfix for MAM. Fixes #1213. Partially addresses #1212. --- src/smt/mam.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index 1fc5ed220..19ccfbe98 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -2088,6 +2088,7 @@ namespace smt { if (p->get_decl() == f && m_context.is_relevant(p) && p->is_cgr() && + i < p->get_num_args() && p->get_arg(i)->get_root() == n) { v->push_back(p); } From 4ab0ee75fa390fce965df05274ebd5a18be04ef9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Aug 2017 08:49:06 -0700 Subject: [PATCH 133/488] mam Signed-off-by: Nikolaj Bjorner --- src/smt/mam.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index 72a6d895c..b5975ac63 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -2080,13 +2080,14 @@ namespace smt { */ enode_vector * interpreter::mk_depth1_vector(enode * n, func_decl * f, unsigned i) { enode_vector * v = mk_enode_vector(); + unsigned num_args = n->get_num_args(); n = n->get_root(); enode_vector::const_iterator it = n->begin_parents(); enode_vector::const_iterator end = n->end_parents(); for (; it != end; ++it) { enode * p = *it; if (p->get_decl() == f && - p->get_num_args() > i && + p->get_num_args() == num_args && m_context.is_relevant(p) && p->is_cgr() && p->get_arg(i)->get_root() == n) { @@ -2105,6 +2106,7 @@ namespace smt { enode * n = m_registers[j2->m_reg]->get_root(); if (n->get_num_parents() == 0) return 0; + unsigned num_args = n->get_num_args(); enode_vector * v = mk_enode_vector(); enode_vector::const_iterator it1 = n->begin_parents(); enode_vector::const_iterator end1 = n->end_parents(); @@ -2121,6 +2123,7 @@ namespace smt { for (; it2 != end2; ++it2) { enode * p2 = *it2; if (p2->get_decl() == f && + num_args == n->get_num_args() && m_context.is_relevant(p2) && p2->is_cgr() && p2->get_arg(i)->get_root() == p) { From 1620796bd1dfc6876c5f096593cda32fb4400baa Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Aug 2017 17:25:04 +0100 Subject: [PATCH 134/488] Whitespace --- src/ast/pattern/pattern_inference.cpp | 71 +++++++++++++-------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index c8247e409..11268b2f3 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -54,7 +54,7 @@ bool smaller_pattern::process(expr * p1, expr * p2) { unsigned num1 = app1->get_num_args(); if (num1 != app2->get_num_args() || app1->get_decl() != app2->get_decl()) return false; - for (unsigned i = 0; i < num1; i++) + for (unsigned i = 0; i < num1; i++) save(app1->get_arg(i), app2->get_arg(i)); break; } @@ -67,7 +67,7 @@ bool smaller_pattern::process(expr * p1, expr * p2) { return false; } // it is a variable bound by an external quantifier - else if (p1 != p2) + else if (p1 != p2) return false; break; } @@ -137,7 +137,7 @@ bool pattern_inference::collect::visit_children(expr * n, unsigned delta) { bool visited = true; unsigned i; switch (n->get_kind()) { - case AST_APP: + case AST_APP: i = to_app(n)->get_num_args(); while (i > 0) { --i; @@ -187,14 +187,14 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) { save(n, delta, 0); return; } - + if (c->get_num_args() == 0) { save(n, delta, alloc(info, m, n, uint_set(), 1)); return; } ptr_buffer buffer; - bool changed = false; // false if none of the children is mapped to a node different from itself. + bool changed = false; // false if none of the children is mapped to a node different from itself. uint_set free_vars; unsigned size = 1; unsigned num = c->get_num_args(); @@ -216,7 +216,7 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) { if (child != child_info->m_node.get()) changed = true; } - + app * new_node = 0; if (changed) new_node = m.mk_app(decl, buffer.size(), buffer.c_ptr()); @@ -229,11 +229,11 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) { // // Remark: The rule above has an exception. The operators (div, idiv, mod) are allowed to be // used as patterns even when they are not nested in other terms. The motivation is that - // Z3 currently doesn't implement them (i.e., they are uninterpreted). So, some users add axioms + // Z3 currently doesn't implement them (i.e., they are uninterpreted). So, some users add axioms // stating properties about these operators. family_id fid = c->get_family_id(); decl_kind k = c->get_decl_kind(); - if (!free_vars.empty() && + if (!free_vars.empty() && (fid != m_afid || (fid == m_afid && !m_owner.m_nested_arith_only && (k == OP_DIV || k == OP_IDIV || k == OP_MOD || k == OP_REM || k == OP_MUL)))) { TRACE("pattern_inference", tout << "potential candidate: \n" << mk_pp(new_node, m) << "\n";); m_owner.add_candidate(new_node, free_vars, size); @@ -288,7 +288,7 @@ void pattern_inference::filter_looping_patterns(ptr_vector & result) { uint_set const & s2 = e2->get_data().m_value.m_free_vars; // Remark: the comparison operator only makes sense if both AST nodes // contain the same number of variables. - // Example: + // Example: // (f X Y) <: (f (g X Z W) Y) if (s1 == s2 && m_le(m_num_bindings, n1, n2) && !m_le(m_num_bindings, n2, n1)) { smaller = true; @@ -421,12 +421,12 @@ void pattern_inference::candidates2unary_patterns(ptr_vector const & candid } // TODO: this code is too inefficient when the number of candidate -// patterns is too big. +// patterns is too big. // HACK: limit the number of case-splits: #define MAX_SPLITS 32 -void pattern_inference::candidates2multi_patterns(unsigned max_num_patterns, - ptr_vector const & candidate_patterns, +void pattern_inference::candidates2multi_patterns(unsigned max_num_patterns, + ptr_vector const & candidate_patterns, app_ref_buffer & result) { SASSERT(!candidate_patterns.empty()); m_pre_patterns.push_back(alloc(pre_pattern)); @@ -464,7 +464,7 @@ void pattern_inference::candidates2multi_patterns(unsigned max_num_patterns, m_pre_patterns.push_back(curr); } } - TRACE("pattern_inference", tout << "m_pre_patterns.size(): " << m_pre_patterns.size() << + TRACE("pattern_inference", tout << "m_pre_patterns.size(): " << m_pre_patterns.size() << "\nnum_splits: " << num_splits << "\n";); } } @@ -478,7 +478,7 @@ void pattern_inference::reset_pre_patterns() { static void dump_app_vector(std::ostream & out, ptr_vector const & v, ast_manager & m) { ptr_vector::const_iterator it = v.begin(); ptr_vector::const_iterator end = v.end(); - for (; it != end; ++it) + for (; it != end; ++it) out << mk_pp(*it, m) << "\n"; } #endif @@ -487,8 +487,8 @@ bool pattern_inference::is_forbidden(app * n) const { func_decl const * decl = n->get_decl(); if (is_ground(n)) return false; - // Remark: skolem constants should not be used in patterns, since they do not - // occur outside of the quantifier. That is, Z3 will never match this kind of + // Remark: skolem constants should not be used in patterns, since they do not + // occur outside of the quantifier. That is, Z3 will never match this kind of // pattern. if (m_params.m_pi_avoid_skolems && decl->is_skolem()) { CTRACE("pattern_inference_skolem", decl->is_skolem(), tout << "ignoring: " << mk_pp(n, m) << "\n";); @@ -521,9 +521,9 @@ bool pattern_inference::has_preferred_patterns(ptr_vector & candidate_patte return found; } -void pattern_inference::mk_patterns(unsigned num_bindings, - expr * n, - unsigned num_no_patterns, +void pattern_inference::mk_patterns(unsigned num_bindings, + expr * n, + unsigned num_no_patterns, expr * const * no_patterns, app_ref_buffer & result) { m_num_bindings = num_bindings; @@ -532,7 +532,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings, m_collect(n, num_bindings); - TRACE("pattern_inference", + TRACE("pattern_inference", tout << mk_pp(n, m); tout << "\ncandidates:\n"; unsigned num = m_candidates.size(); @@ -558,7 +558,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings, m_tmp1.reset(); candidates2unary_patterns(m_tmp2, m_tmp1, result); unsigned num_extra_multi_patterns = m_params.m_pi_max_multi_patterns; - if (result.empty()) + if (result.empty()) num_extra_multi_patterns++; if (num_extra_multi_patterns > 0 && !m_tmp1.empty()) { // m_pattern_weight_lt is not a total order @@ -604,7 +604,7 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { else { quantifier_ref tmp(m); tmp = m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), q->get_expr()); - new_q = m.update_quantifier_weight(tmp, new_weight); + new_q = m.update_quantifier_weight(tmp, new_weight); TRACE("pattern_inference", tout << "found patterns in database, weight: " << new_weight << "\n" << mk_pp(new_q, m) << "\n";); } proof * pr = 0; @@ -635,15 +635,15 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { proof * new_pattern_pr; get_cached(q->get_no_pattern(i), new_pattern, new_pattern_pr); new_no_patterns.push_back(new_pattern); - } - + } + app_ref_buffer new_patterns(m); - + if (m_params.m_pi_arith == AP_CONSERVATIVE) m_forbidden.push_back(m_afid); mk_patterns(q->get_num_decls(), new_body, new_no_patterns.size(), new_no_patterns.c_ptr(), new_patterns); - + if (new_patterns.empty() && !new_no_patterns.empty()) { if (new_patterns.empty()) { mk_patterns(q->get_num_decls(), new_body, 0, 0, new_patterns); @@ -652,7 +652,7 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { } } } - + if (m_params.m_pi_arith == AP_CONSERVATIVE) { m_forbidden.pop_back(); if (new_patterns.empty()) { @@ -661,13 +661,13 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { if (!new_patterns.empty()) { weight = std::max(weight, static_cast(m_params.m_pi_arith_weight)); if (m_params.m_pi_warnings) { - warning_msg("using arith. in pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_ARITH_WEIGHT=).", + warning_msg("using arith. in pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_ARITH_WEIGHT=).", q->get_qid().str().c_str(), weight); } } } } - + if (m_params.m_pi_arith != AP_NO && new_patterns.empty()) { if (new_patterns.empty()) { flet l1(m_nested_arith_only, false); // try to find a non-nested arith pattern @@ -676,8 +676,8 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { if (!new_patterns.empty()) { weight = std::max(weight, static_cast(m_params.m_pi_non_nested_arith_weight)); if (m_params.m_pi_warnings) { - warning_msg("using non nested arith. pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_NON_NESTED_ARITH_WEIGHT=).", - q->get_qid().str().c_str(), weight); + warning_msg("using non nested arith. pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_NON_NESTED_ARITH_WEIGHT=).", + q->get_qid().str().c_str(), weight); } // verbose_stream() << mk_pp(q, m) << "\n"; } @@ -689,12 +689,12 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { if (weight != q->get_weight()) new_q = m.update_quantifier_weight(new_q, weight); proof_ref pr(m); - if (m.fine_grain_proofs()) { + if (m.fine_grain_proofs()) { if (new_body_pr == 0) new_body_pr = m.mk_reflexivity(new_body); pr = m.mk_quant_intro(q, new_q, new_body_pr); } - + if (new_patterns.empty() && m_params.m_pi_pull_quantifiers) { pull_quant pull(m); expr_ref new_expr(m); @@ -728,9 +728,8 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { cache_result(q, q, 0); return; } - - cache_result(q, new_q, pr); + cache_result(q, new_q, pr); } @@ -739,7 +738,7 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { static void dump_expr_vector(std::ostream & out, ptr_vector const & v, ast_manager & m) { ptr_vector::const_iterator it = v.begin(); ptr_vector::const_iterator end = v.end(); - for (; it != end; ++it) + for (; it != end; ++it) out << mk_pp(*it, m) << "\n"; } #endif From 3487b368d1413cdff2de9f269a76f7ab92148ec9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Aug 2017 17:27:06 +0100 Subject: [PATCH 135/488] Added diagnostic output for pattern inference. --- src/ast/pattern/pattern_inference.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index 11268b2f3..d97c2f094 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -729,6 +729,12 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { return; } + IF_IVERBOSE(10, + verbose_stream() << "(smt.inferred-patterns :qid " << q->get_qid() << "\n"; + for (unsigned i = 0; i < new_patterns.size(); i++) + verbose_stream() << " " << mk_ismt2_pp(new_patterns[i], m, 2) << "\n"; + verbose_stream() << ")\n"; ); + cache_result(q, new_q, pr); } From a2d7b43554adff1e480cf0c6a8e341d562928aa9 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Thu, 17 Aug 2017 17:47:40 +0100 Subject: [PATCH 136/488] Update header includes to be relative to `src/` directory. --- scripts/update_api.py | 12 ++++++------ src/api/api_algebraic.cpp | 2 +- src/api/api_arith.cpp | 2 +- src/api/api_array.cpp | 2 +- src/api/api_ast.cpp | 2 +- src/api/api_ast_map.cpp | 2 +- src/api/api_ast_vector.cpp | 2 +- src/api/api_bv.cpp | 2 +- src/api/api_config_params.cpp | 2 +- src/api/api_context.cpp | 4 ++-- src/api/api_datalog.cpp | 2 +- src/api/api_datatype.cpp | 2 +- src/api/api_fpa.cpp | 2 +- src/api/api_goal.cpp | 2 +- src/api/api_interp.cpp | 2 +- src/api/api_log.cpp | 4 ++-- src/api/api_model.cpp | 2 +- src/api/api_numeral.cpp | 2 +- src/api/api_opt.cpp | 2 +- src/api/api_params.cpp | 2 +- src/api/api_parsers.cpp | 2 +- src/api/api_pb.cpp | 2 +- src/api/api_polynomial.cpp | 2 +- src/api/api_qe.cpp | 2 +- src/api/api_quant.cpp | 2 +- src/api/api_rcf.cpp | 2 +- src/api/api_seq.cpp | 2 +- src/api/api_solver.cpp | 2 +- src/api/api_stats.cpp | 2 +- src/api/api_tactic.cpp | 2 +- src/cmd_context/basic_cmds.cpp | 2 +- src/duality/duality_wrapper.h | 2 +- src/shell/main.cpp | 2 +- 33 files changed, 40 insertions(+), 40 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 4000b3da2..67a1b8a33 100755 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1573,7 +1573,7 @@ def def_APIs(api_files): def write_log_h_preamble(log_h): log_h.write('// Automatically generated file\n') - log_h.write('#include\"z3.h\"\n') + log_h.write('#include\"api/z3.h\"\n') log_h.write('#ifdef __GNUC__\n') log_h.write('#define _Z3_UNUSED __attribute__((unused))\n') log_h.write('#else\n') @@ -1592,14 +1592,14 @@ def write_log_h_preamble(log_h): def write_log_c_preamble(log_c): log_c.write('// Automatically generated file\n') log_c.write('#include\n') - log_c.write('#include\"z3.h\"\n') - log_c.write('#include\"api_log_macros.h\"\n') - log_c.write('#include\"z3_logger.h\"\n') + log_c.write('#include\"api/z3.h\"\n') + log_c.write('#include\"api/api_log_macros.h\"\n') + log_c.write('#include\"api/z3_logger.h\"\n') def write_exe_c_preamble(exe_c): exe_c.write('// Automatically generated file\n') - exe_c.write('#include\"z3.h\"\n') - exe_c.write('#include\"z3_replayer.h\"\n') + exe_c.write('#include\"api/z3.h\"\n') + exe_c.write('#include\"api/z3_replayer.h\"\n') # exe_c.write('void Z3_replayer_error_handler(Z3_context ctx, Z3_error_code c) { printf("[REPLAYER ERROR HANDLER]: %s\\n", Z3_get_error_msg(ctx, c)); }\n') diff --git a/src/api/api_algebraic.cpp b/src/api/api_algebraic.cpp index 40e8c846b..96d8392ba 100644 --- a/src/api/api_algebraic.cpp +++ b/src/api/api_algebraic.cpp @@ -18,7 +18,7 @@ Notes: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_ast_vector.h" #include "math/polynomial/algebraic_numbers.h" diff --git a/src/api/api_arith.cpp b/src/api/api_arith.cpp index 80eb261ad..8fbed6f46 100644 --- a/src/api/api_arith.cpp +++ b/src/api/api_arith.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/arith_decl_plugin.h" diff --git a/src/api/api_array.cpp b/src/api/api_array.cpp index f4682ea8f..a5916e987 100644 --- a/src/api/api_array.cpp +++ b/src/api/api_array.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/array_decl_plugin.h" diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index c14a24df1..ab93c3cbd 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/well_sorted.h" diff --git a/src/api/api_ast_map.cpp b/src/api/api_ast_map.cpp index fc593c1f5..d0388b97a 100644 --- a/src/api/api_ast_map.cpp +++ b/src/api/api_ast_map.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_ast_map.h" #include "api/api_ast_vector.h" diff --git a/src/api/api_ast_vector.cpp b/src/api/api_ast_vector.cpp index 04802cba5..471a308b6 100644 --- a/src/api/api_ast_vector.cpp +++ b/src/api/api_ast_vector.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_ast_vector.h" #include "ast/ast_translation.h" diff --git a/src/api/api_bv.cpp b/src/api/api_bv.cpp index 52fcb867c..3b5d60be3 100644 --- a/src/api/api_bv.cpp +++ b/src/api/api_bv.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/bv_decl_plugin.h" diff --git a/src/api/api_config_params.cpp b/src/api/api_config_params.cpp index d35297f59..460101d34 100644 --- a/src/api/api_config_params.cpp +++ b/src/api/api_config_params.cpp @@ -18,7 +18,7 @@ Revision History: #include "api/z3.h" #include "api/api_context.h" #include "ast/pp.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_util.h" #include "cmd_context/cmd_context.h" #include "util/symbol.h" diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index 2c93ee85d..210e0a1d4 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -20,10 +20,10 @@ Revision History: #include #include "api/api_context.h" #include "parsers/smt/smtparser.h" -#include"version.h" +#include "util/version.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_util.h" #include "ast/reg_decl_plugins.h" #include "math/realclosure/realclosure.h" diff --git a/src/api/api_datalog.cpp b/src/api/api_datalog.cpp index 8f863ed42..397e2a8af 100644 --- a/src/api/api_datalog.cpp +++ b/src/api/api_datalog.cpp @@ -20,7 +20,7 @@ Revision History: #include "api/api_util.h" #include "ast/ast_pp.h" #include "api/api_ast_vector.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_stats.h" #include "muz/fp/datalog_parser.h" #include "util/cancel_eh.h" diff --git a/src/api/api_datatype.cpp b/src/api/api_datatype.cpp index 7e9758a04..851d96a4e 100644 --- a/src/api/api_datatype.cpp +++ b/src/api/api_datatype.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/datatype_decl_plugin.h" diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 8e4d13af4..484cb3d76 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -18,7 +18,7 @@ Notes: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "ast/fpa_decl_plugin.h" diff --git a/src/api/api_goal.cpp b/src/api/api_goal.cpp index 3fe23828d..0f1b9056b 100644 --- a/src/api/api_goal.cpp +++ b/src/api/api_goal.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_goal.h" #include "ast/ast_translation.h" diff --git a/src/api/api_interp.cpp b/src/api/api_interp.cpp index 276e56989..fb2699e0a 100644 --- a/src/api/api_interp.cpp +++ b/src/api/api_interp.cpp @@ -18,7 +18,7 @@ #include #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_tactic.h" #include "api/api_solver.h" diff --git a/src/api/api_log.cpp b/src/api/api_log.cpp index aa00de424..410110d9a 100644 --- a/src/api/api_log.cpp +++ b/src/api/api_log.cpp @@ -17,9 +17,9 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "util/util.h" -#include"version.h" +#include "util/version.h" std::ostream * g_z3_log = 0; bool g_z3_log_enabled = false; diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index 73428a3d7..de917650d 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_model.h" #include "api/api_ast_vector.h" diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index c3717b5d2..95bc0bef9 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/arith_decl_plugin.h" diff --git a/src/api/api_opt.cpp b/src/api/api_opt.cpp index 8c49b526e..a967dfb2b 100644 --- a/src/api/api_opt.cpp +++ b/src/api/api_opt.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_stats.h" #include "api/api_context.h" #include "api/api_util.h" diff --git a/src/api/api_params.cpp b/src/api/api_params.cpp index 86dfe9a93..3f3cbed1d 100644 --- a/src/api/api_params.cpp +++ b/src/api/api_params.cpp @@ -19,7 +19,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "util/params.h" diff --git a/src/api/api_parsers.cpp b/src/api/api_parsers.cpp index 8c2723e9a..bef31e9f1 100644 --- a/src/api/api_parsers.cpp +++ b/src/api/api_parsers.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "cmd_context/cmd_context.h" diff --git a/src/api/api_pb.cpp b/src/api/api_pb.cpp index 97e627ec0..e6f8f77b4 100644 --- a/src/api/api_pb.cpp +++ b/src/api/api_pb.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/pb_decl_plugin.h" diff --git a/src/api/api_polynomial.cpp b/src/api/api_polynomial.cpp index 398fdeb3a..9be73289f 100644 --- a/src/api/api_polynomial.cpp +++ b/src/api/api_polynomial.cpp @@ -17,7 +17,7 @@ Notes: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_polynomial.h" #include "api/api_ast_vector.h" diff --git a/src/api/api_qe.cpp b/src/api/api_qe.cpp index 0c2948ce5..34f21d64b 100644 --- a/src/api/api_qe.cpp +++ b/src/api/api_qe.cpp @@ -19,7 +19,7 @@ Notes: #include #include "api/z3.h" -#include "api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "api/api_model.h" diff --git a/src/api/api_quant.cpp b/src/api/api_quant.cpp index f7d5bf13a..d64768b3b 100644 --- a/src/api/api_quant.cpp +++ b/src/api/api_quant.cpp @@ -16,7 +16,7 @@ Revision History: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "parsers/util/pattern_validation.h" diff --git a/src/api/api_rcf.cpp b/src/api/api_rcf.cpp index 377e83a44..84c250114 100644 --- a/src/api/api_rcf.cpp +++ b/src/api/api_rcf.cpp @@ -21,7 +21,7 @@ Notes: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "math/realclosure/realclosure.h" diff --git a/src/api/api_seq.cpp b/src/api/api_seq.cpp index a652fd912..44003a5fb 100644 --- a/src/api/api_seq.cpp +++ b/src/api/api_seq.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_util.h" #include "ast/ast_pp.h" diff --git a/src/api/api_solver.cpp b/src/api/api_solver.cpp index 6435b8288..7fd6d08fe 100644 --- a/src/api/api_solver.cpp +++ b/src/api/api_solver.cpp @@ -18,7 +18,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_tactic.h" #include "api/api_solver.h" diff --git a/src/api/api_stats.cpp b/src/api/api_stats.cpp index 440aec22d..a92b908dc 100644 --- a/src/api/api_stats.cpp +++ b/src/api/api_stats.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_stats.h" diff --git a/src/api/api_tactic.cpp b/src/api/api_tactic.cpp index 661660a63..ccb1ce597 100644 --- a/src/api/api_tactic.cpp +++ b/src/api/api_tactic.cpp @@ -17,7 +17,7 @@ Revision History: --*/ #include #include "api/z3.h" -#include"api_log_macros.h" +#include "api/api_log_macros.h" #include "api/api_context.h" #include "api/api_tactic.h" #include "api/api_model.h" diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index db522b82b..c81170ba4 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -16,7 +16,7 @@ Notes: --*/ #include "cmd_context/cmd_context.h" -#include"version.h" +#include "util/version.h" #include "ast/ast_smt_pp.h" #include "ast/ast_smt2_pp.h" #include "ast/ast_pp.h" diff --git a/src/duality/duality_wrapper.h b/src/duality/duality_wrapper.h index 8e2d70ea6..8ea8017a2 100644 --- a/src/duality/duality_wrapper.h +++ b/src/duality/duality_wrapper.h @@ -27,7 +27,7 @@ #include #include #include -#include"version.h" +#include "util/version.h" #include #include "interp/iz3hash.h" diff --git a/src/shell/main.cpp b/src/shell/main.cpp index 3f3ba5182..3d2609c4f 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -26,7 +26,7 @@ Revision History: #include "shell/smtlib_frontend.h" #include "shell/z3_log_frontend.h" #include "util/warning.h" -#include"version.h" +#include "util/version.h" #include "shell/dimacs_frontend.h" #include "shell/datalog_frontend.h" #include "shell/opt_frontend.h" From 920c596c23528da5daaee7c2fdc04e78077c46dd Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Thu, 17 Aug 2017 18:14:49 +0100 Subject: [PATCH 137/488] [CMake] Clean up setting include paths. Now that all include paths are relative to the `src/` trees ( one in source tree and one in the build tree) we can simplify what the CMake build does significantly. While I'm here I also removed some dead code that wasn't doing anything useful. --- cmake/z3_add_component.cmake | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/cmake/z3_add_component.cmake b/cmake/z3_add_component.cmake index b70838750..d87ffbe61 100644 --- a/cmake/z3_add_component.cmake +++ b/cmake/z3_add_component.cmake @@ -36,15 +36,8 @@ function(z3_add_component_dependencies_to_target target_name) # Remaing args should be component names set(_expanded_deps ${ARGN}) foreach (dependency ${_expanded_deps}) - # FIXME: Adding these include paths wouldn't be necessary if the sources - # used include paths rooted in the ``src`` directory. - get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES) - foreach (inc_dir ${_dep_include_dirs}) - target_include_directories(${target_name} PRIVATE "${inc_dir}") - endforeach() - unset(_dep_include_dirs) # Ensure this component's dependencies are built before this component. - # This important because we might need the generated header files in + # This is important because we might need the generated header files in # other components. add_dependencies(${target_name} ${dependency}) endforeach() @@ -214,18 +207,14 @@ macro(z3_add_component component_name) target_compile_options(${component_name} PRIVATE ${flag}) endforeach() - # It's unfortunate that we have to manage the include directories and dependencies ourselves. + # It's unfortunate that we have to manage dependencies ourselves. # # If we weren't building "object" libraries we could use # ``` - # target_include_directories(${component_name} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") # target_link_libraries(${component_name} INTERFACE ${Z3_MOD_COMPONENT_DEPENDENCIES}) # ``` # but we can't do that with "object" libraries. - # Record this component's include directories - set_property(GLOBAL PROPERTY Z3_${component_name}_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}") - set_property(GLOBAL APPEND PROPERTY Z3_${component_name}_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}") set_property(GLOBAL PROPERTY Z3_${component_name}_DEPS "") # Record this component's dependencies foreach (dependency ${Z3_MOD_COMPONENT_DEPENDENCIES}) @@ -243,12 +232,6 @@ macro(z3_add_component component_name) endif() #message(STATUS "Component \"${component_name}\" has the following dependencies ${_expanded_deps}") - # For any generated header files for this component - target_include_directories(${component_name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") - # So that any generated header files can refer to source files in the component's - # source tree - target_include_directories(${component_name} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") - # Add any extra include directories foreach (extra_include ${Z3_COMPONENT_EXTRA_INCLUDE_DIRS}) target_include_directories(${component_name} PRIVATE "${extra_include}") @@ -283,7 +266,6 @@ macro(z3_add_install_tactic_rule) endforeach() unset(_component_tactic_header_files) - list(APPEND _search_paths "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") add_custom_command(OUTPUT "install_tactic.cpp" COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/scripts/mk_install_tactic_cpp.py" @@ -311,13 +293,6 @@ macro(z3_add_memory_initializer_rule) ) endif() z3_expand_dependencies(_expanded_components ${ARGN}) - # Get paths to search - set(_search_paths "") - foreach (dependency ${_expanded_components}) - get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES) - list(APPEND _search_paths ${_dep_include_dirs}) - endforeach() - list(APPEND _search_paths "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") # Get header files that declare initializers and finalizers set(_mem_init_finalize_headers "") From 320c81e497f3d1d1810fecda840a91265ba68b77 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Aug 2017 19:18:14 +0100 Subject: [PATCH 138/488] Whitespace --- src/smt/smt_model_checker.cpp | 46 +++++++++++++++++------------------ src/smt/smt_model_checker.h | 6 ++--- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index d5b8415c3..23e2589f9 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -53,8 +53,8 @@ namespace smt { } void model_checker::set_qm(quantifier_manager & qm) { - SASSERT(m_qm == 0); - SASSERT(m_context == 0); + SASSERT(m_qm == 0); + SASSERT(m_context == 0); m_qm = &qm; m_context = &(m_qm->get_context()); } @@ -112,7 +112,7 @@ namespace smt { if (!m_curr_model->eval(q->get_expr(), tmp, true)) { return; } - TRACE("model_checker", tout << "q after applying interpretation:\n" << mk_ismt2_pp(tmp, m) << "\n";); + TRACE("model_checker", tout << "q after applying interpretation:\n" << mk_ismt2_pp(tmp, m) << "\n";); ptr_buffer subst_args; unsigned num_decls = q->get_num_decls(); subst_args.resize(num_decls, 0); @@ -139,7 +139,7 @@ namespace smt { bool model_checker::add_instance(quantifier * q, model * cex, expr_ref_vector & sks, bool use_inv) { if (cex == 0) { TRACE("model_checker", tout << "no model is available\n";); - return false; + return false; } unsigned num_decls = q->get_num_decls(); // Remark: sks were created for the flat version of q. @@ -187,20 +187,20 @@ namespace smt { } bindings.set(num_decls - i - 1, sk_value); } - + TRACE("model_checker", tout << q->get_qid() << " found (use_inv: " << use_inv << ") new instance: "; for (unsigned i = 0; i < num_decls; i++) { tout << mk_ismt2_pp(bindings[i].get(), m) << " "; } tout << "\n";); - + max_generation = std::max(m_qm->get_generation(q), max_generation); add_instance(q, bindings, max_generation); return true; } void model_checker::add_instance(quantifier* q, expr_ref_vector const& bindings, unsigned max_generation) { - for (unsigned i = 0; i < bindings.size(); i++) + for (unsigned i = 0; i < bindings.size(); i++) m_new_instances_bindings.push_back(bindings[i]); void * mem = m_new_instances_region.allocate(instance::get_obj_size(q->get_num_decls())); instance * new_inst = new (mem) instance(q, bindings.c_ptr(), max_generation); @@ -260,39 +260,39 @@ namespace smt { bool model_checker::check(quantifier * q) { SASSERT(!m_aux_context->relevancy()); m_aux_context->push(); - + quantifier * flat_q = get_flat_quantifier(q); - TRACE("model_checker", tout << "model checking:\n" << mk_ismt2_pp(q->get_expr(), m) << "\n" << + TRACE("model_checker", tout << "model checking:\n" << mk_ismt2_pp(q->get_expr(), m) << "\n" << mk_ismt2_pp(flat_q->get_expr(), m) << "\n";); expr_ref_vector sks(m); assert_neg_q_m(flat_q, sks); - TRACE("model_checker", tout << "skolems:\n"; + TRACE("model_checker", tout << "skolems:\n"; for (unsigned i = 0; i < sks.size(); i++) { expr * sk = sks.get(i); tout << mk_ismt2_pp(sk, m) << " " << mk_pp(m.get_sort(sk), m) << "\n"; }); - + lbool r = m_aux_context->check(); TRACE("model_checker", tout << "[complete] model-checker result: " << to_sat_str(r) << "\n";); if (r != l_true) { m_aux_context->pop(1); return r == l_false; // quantifier is satisfied by m_curr_model } - + model_ref complete_cex; - m_aux_context->get_model(complete_cex); - + m_aux_context->get_model(complete_cex); + // try to find new instances using instantiation sets. m_model_finder.restrict_sks_to_inst_set(m_aux_context.get(), q, sks); - + unsigned num_new_instances = 0; while (true) { lbool r = m_aux_context->check(); - TRACE("model_checker", tout << "[restricted] model-checker (" << (num_new_instances+1) << ") result: " << to_sat_str(r) << "\n";); + TRACE("model_checker", tout << "[restricted] model-checker (" << (num_new_instances+1) << ") result: " << to_sat_str(r) << "\n";); if (r != l_true) - break; + break; model_ref cex; m_aux_context->get_model(cex); if (!add_instance(q, cex.get(), sks, true)) { @@ -302,7 +302,7 @@ namespace smt { if (num_new_instances >= m_max_cexs || !add_blocking_clause(cex.get(), sks)) { TRACE("model_checker", tout << "Add blocking clause failed new-instances: " << num_new_instances << " max-cex: " << m_max_cexs << "\n";); // add_blocking_clause failed... stop the search for new counter-examples... - break; + break; } } @@ -395,17 +395,17 @@ namespace smt { check_quantifiers(false, found_relevant, num_failures); - + if (found_relevant) m_iteration_idx++; TRACE("model_checker", tout << "model after check:\n"; model_pp(tout, *md);); - TRACE("model_checker", tout << "model checker result: " << (num_failures == 0) << "\n";); + TRACE("model_checker", tout << "model checker result: " << (num_failures == 0) << "\n";); m_max_cexs += m_params.m_mbqi_max_cexs; if (num_failures == 0 && !m_context->validate_model()) { num_failures = 1; - // this time force expanding recursive function definitions + // this time force expanding recursive function definitions // that are not forced true in the current model. check_quantifiers(true, found_relevant, num_failures); } @@ -426,7 +426,7 @@ namespace smt { for (; it != end; ++it) { quantifier * q = *it; if(!m_qm->mbqi_enabled(q)) continue; - TRACE("model_checker", + TRACE("model_checker", tout << "Check: " << mk_pp(q, m) << "\n"; tout << m_context->get_assignment(q) << "\n";); @@ -505,7 +505,7 @@ namespace smt { expr * b = inst->m_bindings[i]; tout << mk_pp(b, m) << "\n"; }); - TRACE("model_checker_instance", + TRACE("model_checker_instance", expr_ref inst_expr(m); instantiate(m, q, inst->m_bindings, inst_expr); tout << "(assert " << mk_ismt2_pp(inst_expr, m) << ")\n";); diff --git a/src/smt/smt_model_checker.h b/src/smt/smt_model_checker.h index 7f2ed8ca7..4a9c28aba 100644 --- a/src/smt/smt_model_checker.h +++ b/src/smt/smt_model_checker.h @@ -39,7 +39,7 @@ namespace smt { class model_checker { ast_manager & m; // _manager; qi_params const & m_params; - // copy of smt_params for auxiliary context. + // copy of smt_params for auxiliary context. // the idea is to use a different configuration for the aux context (e.g., disable relevancy) scoped_ptr m_fparams; quantifier_manager * m_qm; @@ -83,8 +83,8 @@ namespace smt { struct is_model_value {}; expr_mark m_visited; - bool contains_model_value(expr* e); - void add_instance(quantifier* q, expr_ref_vector const& bindings, unsigned max_generation); + bool contains_model_value(expr * e); + void add_instance(quantifier * q, expr_ref_vector const & bindings, unsigned max_generation); public: model_checker(ast_manager & m, qi_params const & p, model_finder & mf); From abd599f48ef74f2acd4324abbc2610eac9338ebc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Aug 2017 19:29:37 +0100 Subject: [PATCH 139/488] Fixed ref-counting bug in smt_model_checker. Fixes #1212. --- src/smt/smt_model_checker.cpp | 11 ++++++++--- src/smt/smt_model_checker.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index 23e2589f9..875e7adf2 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -40,7 +40,7 @@ namespace smt { m_max_cexs(1), m_iteration_idx(0), m_curr_model(0), - m_new_instances_bindings(m) { + m_pinned_exprs(m) { } model_checker::~model_checker() { @@ -200,8 +200,12 @@ namespace smt { } void model_checker::add_instance(quantifier* q, expr_ref_vector const& bindings, unsigned max_generation) { + SASSERT(q->get_num_decls() == bindings.size()); + for (unsigned i = 0; i < bindings.size(); i++) - m_new_instances_bindings.push_back(bindings[i]); + m_pinned_exprs.push_back(bindings[i]); + m_pinned_exprs.push_back(q); + void * mem = m_new_instances_region.allocate(instance::get_obj_size(q->get_num_decls())); instance * new_inst = new (mem) instance(q, bindings.c_ptr(), max_generation); m_new_instances.push_back(new_inst); @@ -469,8 +473,9 @@ namespace smt { } void model_checker::reset_new_instances() { - m_new_instances_region.reset(); + m_pinned_exprs.reset(); m_new_instances.reset(); + m_new_instances_region.reset(); } void model_checker::reset() { diff --git a/src/smt/smt_model_checker.h b/src/smt/smt_model_checker.h index 4a9c28aba..778f913c3 100644 --- a/src/smt/smt_model_checker.h +++ b/src/smt/smt_model_checker.h @@ -73,8 +73,8 @@ namespace smt { }; region m_new_instances_region; - expr_ref_vector m_new_instances_bindings; ptr_vector m_new_instances; + expr_ref_vector m_pinned_exprs; bool add_instance(quantifier * q, model * cex, expr_ref_vector & sks, bool use_inv); void reset_new_instances(); void assert_new_instances(); From ff47c8632b9a6c212f68fe3e0968eaef379d4321 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Aug 2017 20:28:49 -0700 Subject: [PATCH 140/488] remove reinterpret cast occurrences that require disabling strict alias analysis #987 #1210 Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 8 ++++---- src/ast/ast.h | 16 +++++++--------- src/muz/spacer/spacer_sym_mux.cpp | 6 ++---- src/util/array_map.h | 5 +---- src/util/optional.h | 19 ++++++++++--------- 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index a1efed19e..f347a8e49 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -35,7 +35,7 @@ Revision History: parameter::~parameter() { if (m_kind == PARAM_RATIONAL) { - reinterpret_cast(m_rational)->~rational(); + dealloc(m_rational); } } @@ -50,14 +50,14 @@ parameter& parameter::operator=(parameter const& other) { return *this; } if (m_kind == PARAM_RATIONAL) { - reinterpret_cast(m_rational)->~rational(); + dealloc(m_rational); } m_kind = other.m_kind; switch(other.m_kind) { case PARAM_INT: m_int = other.get_int(); break; case PARAM_AST: m_ast = other.get_ast(); break; - case PARAM_SYMBOL: new (m_symbol) symbol(other.get_symbol()); break; - case PARAM_RATIONAL: new (m_rational) rational(other.get_rational()); break; + case PARAM_SYMBOL: m_symbol = other.m_symbol; break; + case PARAM_RATIONAL: m_rational = alloc(rational, other.get_rational()); break; case PARAM_DOUBLE: m_dval = other.m_dval; break; case PARAM_EXTERNAL: m_ext_id = other.m_ext_id; break; default: diff --git a/src/ast/ast.h b/src/ast/ast.h index 3a3f08df2..e6beec7e6 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -102,8 +102,8 @@ private: union { int m_int; // for PARAM_INT ast* m_ast; // for PARAM_AST - char m_symbol[sizeof(symbol)]; // for PARAM_SYMBOL - char m_rational[sizeof(rational)]; // for PARAM_RATIONAL + void const* m_symbol; // for PARAM_SYMBOL + rational* m_rational; // for PARAM_RATIONAL double m_dval; // for PARAM_DOUBLE (remark: this is not used in float_decl_plugin) unsigned m_ext_id; // for PARAM_EXTERNAL }; @@ -114,12 +114,10 @@ public: explicit parameter(int val): m_kind(PARAM_INT), m_int(val) {} explicit parameter(unsigned val): m_kind(PARAM_INT), m_int(val) {} explicit parameter(ast * p): m_kind(PARAM_AST), m_ast(p) {} - explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL) { new (m_symbol) symbol(s); } - explicit parameter(rational const & r): m_kind(PARAM_RATIONAL) { new (m_rational) rational(r); } + explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL), m_symbol(s.c_ptr()) {} + explicit parameter(rational const & r): m_kind(PARAM_RATIONAL), m_rational(alloc(rational, r)) {} explicit parameter(double d):m_kind(PARAM_DOUBLE), m_dval(d) {} - explicit parameter(const char *s):m_kind(PARAM_SYMBOL) { - new (m_symbol) symbol(s); - } + explicit parameter(const char *s):m_kind(PARAM_SYMBOL), m_symbol(symbol(s).c_ptr()) {} explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {} parameter(parameter const&); @@ -156,8 +154,8 @@ public: int get_int() const { SASSERT(is_int()); return m_int; } ast * get_ast() const { SASSERT(is_ast()); return m_ast; } - symbol const & get_symbol() const { SASSERT(is_symbol()); return *(reinterpret_cast(m_symbol)); } - rational const & get_rational() const { SASSERT(is_rational()); return *(reinterpret_cast(m_rational)); } + symbol get_symbol() const { SASSERT(is_symbol()); return symbol::mk_symbol_from_c_ptr(m_symbol); } + rational const & get_rational() const { SASSERT(is_rational()); return *m_rational; } double get_double() const { SASSERT(is_double()); return m_dval; } unsigned get_ext_id() const { SASSERT(is_external()); return m_ext_id; } diff --git a/src/muz/spacer/spacer_sym_mux.cpp b/src/muz/spacer/spacer_sym_mux.cpp index da8f8eeca..c311d9990 100644 --- a/src/muz/spacer/spacer_sym_mux.cpp +++ b/src/muz/spacer/spacer_sym_mux.cpp @@ -32,10 +32,8 @@ using namespace spacer; sym_mux::sym_mux(ast_manager & m, const std::vector & suffixes) : m(m), m_ref_holder(m), m_next_sym_suffix_idx(0), m_suffixes(suffixes) { - unsigned suf_sz = m_suffixes.size(); - for (unsigned i = 0; i < suf_sz; ++i) { - symbol suff_sym = symbol(m_suffixes[i].c_str()); - m_used_suffixes.insert(suff_sym); + for (std::string const& s : m_suffixes) { + m_used_suffixes.insert(symbol(s.c_str())); } } diff --git a/src/util/array_map.h b/src/util/array_map.h index c5163715e..f3f99d015 100644 --- a/src/util/array_map.h +++ b/src/util/array_map.h @@ -63,10 +63,7 @@ class array_map { } void really_flush() { - typename vector >::iterator it = m_map.begin(); - typename vector >::iterator end = m_map.end(); - for (; it != end; ++it) { - optional & e = *it; + for (optional & e : m_map) { if (e) { m_plugin.del_eh(e->m_key, e->m_data); e.set_invalid(); diff --git a/src/util/optional.h b/src/util/optional.h index 22757f3bd..eeff35260 100644 --- a/src/util/optional.h +++ b/src/util/optional.h @@ -23,24 +23,25 @@ Revision History: template class optional { - char m_obj[sizeof(T)]; + T* m_obj; char m_initialized; void construct(const T & val) { m_initialized = 1; - new (reinterpret_cast(m_obj)) T(val); + m_obj = alloc(T, val); } void destroy() { if (m_initialized == 1) { - reinterpret_cast(m_obj)->~T(); + dealloc(m_obj); + m_obj = 0; } m_initialized = 0; } public: optional(): - m_initialized(0) {} + m_obj(0), m_initialized(0) {} explicit optional(const T & val) { construct(val); @@ -65,7 +66,7 @@ public: T * get() const { if (m_initialized == 1) { - return reinterpret_cast(m_obj); + return m_obj; } else { return 0; @@ -80,22 +81,22 @@ public: T * operator->() { SASSERT(m_initialized==1); - return reinterpret_cast(m_obj); + return m_obj; } T const * operator->() const { SASSERT(m_initialized==1); - return reinterpret_cast(m_obj); + return m_obj; } const T & operator*() const { SASSERT(m_initialized==1); - return *reinterpret_cast(m_obj); + return *m_obj; } T & operator*() { SASSERT(m_initialized==1); - return *reinterpret_cast(m_obj); + return *m_obj; } optional & operator=(const T & val) { From e1d08e95268684a0c65316906c1ad24e15d27754 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Aug 2017 20:41:29 -0700 Subject: [PATCH 141/488] remove reinterpret cast occurrences that require disabling strict alias analysis #987 #1210 Signed-off-by: Nikolaj Bjorner --- CMakeLists.txt | 4 ---- scripts/mk_util.py | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3ed2a312..715679957 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,22 +234,18 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_USE_THREAD_LOCAL") endif() - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") # Does OSX really not need any special flags? message(STATUS "Platform: Darwin") elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") message(STATUS "Platform: FreeBSD") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_FREEBSD_") - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") message(STATUS "Platform: OpenBSD") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_OPENBSD_") - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif (CYGWIN) message(STATUS "Platform: Cygwin") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_CYGWIN") - z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED) elseif (WIN32) message(STATUS "Platform: Windows") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_WINDOWS") diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d2e3d6b4c..24f22d8ee 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2443,26 +2443,26 @@ def mk_config(): SO_EXT = '.dylib' SLIBFLAGS = '-dynamiclib' elif sysname == 'Linux': - CXXFLAGS = '%s -fno-strict-aliasing -D_LINUX_' % CXXFLAGS + CXXFLAGS = '%s -D_LINUX_' % CXXFLAGS OS_DEFINES = '-D_LINUX_' SO_EXT = '.so' LDFLAGS = '%s -lrt' % LDFLAGS SLIBFLAGS = '-shared' SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS elif sysname == 'FreeBSD': - CXXFLAGS = '%s -fno-strict-aliasing -D_FREEBSD_' % CXXFLAGS + CXXFLAGS = '%s -D_FREEBSD_' % CXXFLAGS OS_DEFINES = '-D_FREEBSD_' SO_EXT = '.so' LDFLAGS = '%s -lrt' % LDFLAGS SLIBFLAGS = '-shared' SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS elif sysname == 'OpenBSD': - CXXFLAGS = '%s -fno-strict-aliasing -D_OPENBSD_' % CXXFLAGS + CXXFLAGS = '%s -D_OPENBSD_' % CXXFLAGS OS_DEFINES = '-D_OPENBSD_' SO_EXT = '.so' SLIBFLAGS = '-shared' elif sysname[:6] == 'CYGWIN': - CXXFLAGS = '%s -D_CYGWIN -fno-strict-aliasing' % CXXFLAGS + CXXFLAGS = '%s -D_CYGWIN' % CXXFLAGS OS_DEFINES = '-D_CYGWIN' SO_EXT = '.dll' SLIBFLAGS = '-shared' From 66b24a6c18b26dcbf8762c73d25908caaab04617 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Aug 2017 21:00:14 -0700 Subject: [PATCH 142/488] change typename to class in optional to deal with compilation Signed-off-by: Nikolaj Bjorner --- src/muz/rel/dl_interval_relation.cpp | 1 - src/util/optional.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/muz/rel/dl_interval_relation.cpp b/src/muz/rel/dl_interval_relation.cpp index ccb7b728b..e14d242bb 100644 --- a/src/muz/rel/dl_interval_relation.cpp +++ b/src/muz/rel/dl_interval_relation.cpp @@ -18,7 +18,6 @@ Revision History: --*/ #include "util/debug.h" -#include "util/optional.h" #include "ast/ast_pp.h" #include "muz/rel/dl_interval_relation.h" #include "muz/rel/dl_relation_manager.h" diff --git a/src/util/optional.h b/src/util/optional.h index eeff35260..5b3753ac6 100644 --- a/src/util/optional.h +++ b/src/util/optional.h @@ -21,7 +21,7 @@ Revision History: #ifndef OPTIONAL_H_ #define OPTIONAL_H_ -template +template class optional { T* m_obj; char m_initialized; From ee00852151f6e0b34f244878eaa5643a42ec3335 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 17 Aug 2017 21:09:23 -0700 Subject: [PATCH 143/488] fix compilation of tests Signed-off-by: Nikolaj Bjorner --- src/test/optional.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/optional.cpp b/src/test/optional.cpp index 46dfef82c..2ef922444 100644 --- a/src/test/optional.cpp +++ b/src/test/optional.cpp @@ -18,6 +18,7 @@ Revision History: --*/ #include "util/trace.h" #include "util/debug.h" +#include "util/memory_manager.h" #include "util/optional.h" static void tst1() { From 112fa16bc0fa516b1c6acb51db6db7fd98fbff64 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 18 Aug 2017 09:19:38 -0700 Subject: [PATCH 144/488] fix #1217 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_arith_int.h | 4 +- src/smt/theory_arith_nl.h | 84 ++++++++++++-------------------------- 2 files changed, 29 insertions(+), 59 deletions(-) diff --git a/src/smt/theory_arith_int.h b/src/smt/theory_arith_int.h index 4150ecc1c..d93e062f4 100644 --- a/src/smt/theory_arith_int.h +++ b/src/smt/theory_arith_int.h @@ -239,7 +239,7 @@ namespace smt { for (; it != end; ++it) { theory_var b = it->get_base_var(); if (b == null_theory_var) { - TRACE("theory_arith_int", display_row(tout << "null: ", *it, true); ); + TRACE("arith_int", display_row(tout << "null: ", *it, true); ); continue; } bool is_tight = false; @@ -257,7 +257,7 @@ namespace smt { const_coeff = u->get_value().get_rational(); } if (!is_tight) { - TRACE("theory_arith_int", + TRACE("arith_int", display_row(tout << "!tight: ", *it, true); display_var(tout, b); ); diff --git a/src/smt/theory_arith_nl.h b/src/smt/theory_arith_nl.h index b4d30d639..9649440d2 100644 --- a/src/smt/theory_arith_nl.h +++ b/src/smt/theory_arith_nl.h @@ -681,8 +681,7 @@ namespace smt { SASSERT(is_pure_monomial(var2expr(v))); expr * m = var2expr(v); rational val(1), v_val; - for (unsigned i = 0; i < to_app(m)->get_num_args(); i++) { - expr * arg = to_app(m)->get_arg(i); + for (expr* arg : *to_app(m)) { theory_var curr = expr2var(arg); SASSERT(curr != null_theory_var); v_val = get_value(curr, computed_epsilon); @@ -742,7 +741,6 @@ namespace smt { continue; bool computed_epsilon = false; bool r = check_monomial_assignment(v, computed_epsilon); - SASSERT(!computed_epsilon); // integer variables do not use epsilon if (!r) { expr * m = get_enode(v)->get_owner(); SASSERT(is_pure_monomial(m)); @@ -1249,11 +1247,9 @@ namespace smt { } // Update the number of occurrences in the result vector. - typename var2num_occs::iterator it2 = m_var2num_occs.begin(); - typename var2num_occs::iterator end2 = m_var2num_occs.end(); - for (; it2 != end2; ++it2) { - if ((*it2).m_value > 1) - varinfo.push_back(var_num_occs((*it2).m_key, (*it2).m_value)); + for (auto const& vn : m_var2num_occs) { + if (vn.m_value > 1) + varinfo.push_back(var_num_occs(vn.m_key, vn.m_value)); } } @@ -1265,18 +1261,16 @@ namespace smt { SASSERT(!p.empty()); TRACE("p2expr_bug", display_coeff_exprs(tout, p);); ptr_buffer args; - sbuffer::const_iterator it = p.begin(); - sbuffer::const_iterator end = p.end(); - for (; it != end; ++it) { - rational const & c = it->first; - expr * var = it->second; + for (coeff_expr const& ce : p) { + rational const & c = ce.first; + expr * var = ce.second; if (!c.is_one()) { rational c2; expr * m = 0; if (m_util.is_numeral(var, c2)) - m = m_util.mk_numeral(c*c2, m_util.is_int(var)); + m = m_util.mk_numeral(c*c2, m_util.is_int(var) && c.is_int() && c2.is_int()); else - m = m_util.mk_mul(m_util.mk_numeral(c, m_util.is_int(var)), var); + m = m_util.mk_mul(m_util.mk_numeral(c, c.is_int() && m_util.is_int(var)), var); m_nl_new_exprs.push_back(m); args.push_back(m); } @@ -1453,8 +1447,7 @@ namespace smt { SASSERT(is_pure_monomial(m)); unsigned idx = 0; ptr_buffer new_args; - for (unsigned i = 0; i < to_app(m)->get_num_args(); i++) { - expr * arg = to_app(m)->get_arg(i); + for (expr * arg : *to_app(m)) { if (arg == var) { if (idx < d) idx++; @@ -1487,17 +1480,15 @@ namespace smt { tout << "min_degree: " << d << "\n";); sbuffer e; // monomials/x^d where var occurs with degree d sbuffer r; // rest - sbuffer::const_iterator it = p.begin(); - sbuffer::const_iterator end = p.end(); - for (; it != end; ++it) { - expr * m = it->second; + for (auto const& kv : p) { + expr * m = kv.second; expr * f = factor(m, var, d); if (get_degree_of(m, var) == d) { - e.push_back(coeff_expr(it->first, f)); + e.push_back(coeff_expr(kv.first, f)); } else { SASSERT(get_degree_of(m, var) > d); - r.push_back(coeff_expr(it->first, f)); + r.push_back(coeff_expr(kv.first, f)); } } expr * s = cross_nested(e, 0); @@ -1623,16 +1614,12 @@ namespace smt { return true; std::stable_sort(varinfo.begin(), varinfo.end(), var_num_occs_lt()); TRACE("cross_nested", tout << "var num occs:\n"; - sbuffer::const_iterator it = varinfo.begin(); - sbuffer::const_iterator end = varinfo.end(); - for (; it != end ; ++it) { - tout << mk_bounded_pp(it->first, get_manager()) << " -> " << it->second << "\n"; + for (auto const& kv : varinfo) { + tout << mk_bounded_pp(kv.first, get_manager()) << " -> " << kv.second << "\n"; }); - sbuffer::const_iterator it = varinfo.begin(); - sbuffer::const_iterator end = varinfo.end(); - for (; it != end; ++it) { + for (auto const& kv : varinfo) { m_nl_new_exprs.reset(); - expr * var = it->first; + expr * var = kv.first; expr * cn = cross_nested(p, var); // Remark: cn may not be well-sorted because, since a row may contain mixed integer/real monomials. // This is not really a problem, since evaluate_as_interval will work even if cn is not well-sorted. @@ -1731,10 +1718,7 @@ namespace smt { */ template bool theory_arith::is_cross_nested_consistent(svector const & nl_cluster) { - svector::const_iterator it = nl_cluster.begin(); - svector::const_iterator end = nl_cluster.end(); - for (; it != end; ++it) { - theory_var v = *it; + for (theory_var v : nl_cluster) { if (!is_base(v)) continue; m_stats.m_nl_cross_nested++; @@ -1765,10 +1749,7 @@ namespace smt { template void theory_arith::init_grobner_var_order(svector const & nl_cluster, grobner & gb) { // Initialize variable order - svector::const_iterator it = nl_cluster.begin(); - svector::const_iterator end = nl_cluster.end(); - for (; it != end; ++it) { - theory_var v = *it; + for (theory_var v : nl_cluster) { expr * var = var2expr(v); if (is_fixed(v)) { @@ -1905,10 +1886,7 @@ namespace smt { template void theory_arith::init_grobner(svector const & nl_cluster, grobner & gb) { init_grobner_var_order(nl_cluster, gb); - svector::const_iterator it = nl_cluster.begin(); - svector::const_iterator end = nl_cluster.end(); - for (; it != end; ++it) { - theory_var v = *it; + for (theory_var v : nl_cluster) { if (is_base(v)) { row const & r = m_rows[get_var_row(v)]; add_row_to_gb(r, gb); @@ -2296,10 +2274,7 @@ namespace smt { eqs.reset(); gb.get_equations(eqs); TRACE("grobner_bug", tout << "after gb\n";); - ptr_vector::const_iterator it = eqs.begin(); - ptr_vector::const_iterator end = eqs.end(); - for (; it != end; ++it) { - grobner::equation * eq = *it; + for (grobner::equation* eq : eqs) { TRACE("grobner_bug", gb.display_equation(tout, *eq);); if (is_inconsistent(eq, gb)) return GB_PROGRESS; @@ -2310,9 +2285,7 @@ namespace smt { // then assert bounds for x, and continue gb_result result = GB_FAIL; if (m_params.m_nl_arith_gb_eqs) { - it = eqs.begin(); - for (; it != end; ++it) { - grobner::equation * eq = *it; + for (grobner::equation* eq : eqs) { if (!eq->is_linear_combination()) { TRACE("non_linear", tout << "processing new equality:\n"; gb.display_equation(tout, *eq);); TRACE("non_linear_bug", tout << "processing new equality:\n"; gb.display_equation(tout, *eq);); @@ -2331,9 +2304,8 @@ namespace smt { // I only consider linear equations... (HACK) // Moreover, I do not change the weight of a variable more than once in this loop. bool modified = false; - it = eqs.begin(); - for (; it != end; ++it) { - grobner::equation const * eq = *it; + + for (grobner::equation const* eq : eqs) { unsigned num_monomials = eq->get_num_monomials(); CTRACE("grobner_bug", num_monomials <= 0, gb.display_equation(tout, *eq);); if (num_monomials == 0) @@ -2370,13 +2342,11 @@ namespace smt { bool theory_arith::max_min_nl_vars() { var_set already_found; svector vars; - for (unsigned j = 0; j < m_nl_monomials.size(); ++j) { - theory_var v = m_nl_monomials[j]; + for (theory_var v : m_nl_monomials) { mark_var(v, vars, already_found); expr * n = var2expr(v); SASSERT(is_pure_monomial(n)); - for (unsigned i = 0; i < to_app(n)->get_num_args(); i++) { - expr * curr = to_app(n)->get_arg(i); + for (expr * curr : *to_app(n)) { theory_var v = expr2var(curr); SASSERT(v != null_theory_var); mark_var(v, vars, already_found); From 6feb7ba79599fd3155ab4d4ee213c584c609c280 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 18 Aug 2017 14:27:46 -0700 Subject: [PATCH 145/488] :q add sequences to ML API Signed-off-by: Nikolaj Bjorner --- src/api/ml/z3.ml | 38 ++++++++++++++++ src/api/ml/z3.mli | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 41d2226c5..c4a4da00c 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1215,6 +1215,44 @@ struct let mk_numeral ctx v size = Z3native.mk_numeral ctx v (mk_sort ctx size) end +module Seq = +struct + let mk_seq_sort = Z3native.mk_seq_sort + let is_seq_sort = Z3native.is_seq_sort + let mk_re_sort = Z3native.mk_re_sort + let is_re_sort = Z3native.is_re_sort + let mk_string_sort = Z3native.mk_string_sort + let is_string_sort = Z3native.is_string_sort + let mk_string = Z3native.mk_string + let is_string = Z3native.is_string + let get_string = Z3native.get_string + let mk_seq_empty = Z3native.mk_seq_empty + let mk_seq_unit = Z3native.mk_seq_unit + let mk_seq_concat ctx args = Z3native.mk_seq_concat ctx (List.length args) args + let mk_seq_prefix = Z3native.mk_seq_prefix + let mk_seq_suffix = Z3native.mk_seq_suffix + let mk_seq_contains = Z3native.mk_seq_contains + let mk_seq_extract = Z3native.mk_seq_extract + let mk_seq_replace = Z3native.mk_seq_replace + let mk_seq_at = Z3native.mk_seq_at + let mk_seq_length = Z3native.mk_seq_length + let mk_seq_index = Z3native.mk_seq_index + let mk_str_to_int = Z3native.mk_str_to_int + let mk_int_to_str = Z3native.mk_int_to_str + let mk_seq_to_re = Z3native.mk_seq_to_re + let mk_seq_in_re = Z3native.mk_seq_in_re + let mk_re_plus = Z3native.mk_re_plus + let mk_re_star = Z3native.mk_re_star + let mk_re_option = Z3native.mk_re_option + let mk_re_union ctx args = Z3native.mk_re_union ctx (List.length args) args + let mk_re_concat ctx args = Z3native.mk_re_concat ctx (List.length args) args + let mk_re_range = Z3native.mk_re_range + let mk_re_loop = Z3native.mk_re_loop + let mk_re_intersect = Z3native.mk_re_intersect + let mk_re_complement = Z3native.mk_re_complement + let mk_re_empty = Z3native.mk_re_empty + let mk_re_full = Z3native.mk_re_full +end module FloatingPoint = struct diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 818a635f7..7b561f878 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1825,6 +1825,115 @@ sig val mk_numeral : context -> string -> int -> Expr.expr end +(** Sequences, Strings and Regular Expressions **) +module Seq : +sig + val mk_seq_sort : context -> Sort.sort -> Sort.sort + + (* test if sort is a sequence sort *) + val is_seq_sort : context -> Sort.sort -> bool + + (* create regular expression sorts over sequences of the argument sort *) + val mk_re_sort : context -> Sort.sort -> Sort.sort + + (* test if sort is a regular expression sort *) + val is_re_sort : context -> Sort.sort -> bool + + (* create string sort *) + val mk_string_sort : context -> Sort.sort + + (* test if sort is a string sort (a sequence of 8-bit bit-vectors) *) + val is_string_sort : context -> Sort.sort -> bool + + (* create a string literal *) + val mk_string : context -> string -> Expr.expr + + (* test if expression is a string *) + val is_string : context -> Expr.expr -> bool + + (* retrieve string from string Expr.expr *) + val get_string : context -> Expr.expr -> string + + (* the empty sequence over base sort *) + val mk_seq_empty : context -> Sort.sort -> Expr.expr + + (* a unit sequence *) + val mk_seq_unit : context -> Expr.expr -> Expr.expr + + (* sequence concatenation *) + val mk_seq_concat : context -> Expr.expr list -> Expr.expr + + (* predicate if the first argument is a prefix of the second *) + val mk_seq_prefix : context -> Expr.expr -> Expr.expr -> Expr.expr + + (* predicate if the first argument is a suffix of the second *) + val mk_seq_suffix : context -> Expr.expr -> Expr.expr -> Expr.expr + + (* predicate if the first argument contains the second *) + val mk_seq_contains : context -> Expr.expr -> Expr.expr -> Expr.expr + + (* extract sub-sequence starting at index given by second argument and of length provided by third argument *) + val mk_seq_extract : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (* replace first occurrence of second argument by third *) + val mk_seq_replace : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (* a unit sequence at index provided by second argument *) + val mk_seq_at : context -> Expr.expr -> Expr.expr -> Expr.expr + + (* length of a sequence *) + val mk_seq_length : context -> Expr.expr -> Expr.expr + + (* index of the first occurrence of the second argument in the first *) + val mk_seq_index : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (* retrieve integer expression encoded in string *) + val mk_str_to_int : context -> Expr.expr -> Expr.expr + + (* convert an integer expression to a string *) + val mk_int_to_str : context -> Expr.expr -> Expr.expr + + (* create regular expression that accepts the argument sequence *) + val mk_seq_to_re : context -> Expr.expr -> Expr.expr + + (* regular expression membership predicate *) + val mk_seq_in_re : context -> Expr.expr -> Expr.expr -> Expr.expr + + (* regular expression plus *) + val mk_re_plus : context -> Expr.expr -> Expr.expr + + (* regular expression star *) + val mk_re_star : context -> Expr.expr -> Expr.expr + + (* optional regular expression *) + val mk_re_option : context -> Expr.expr -> Expr.expr + + (* union of regular expressions *) + val mk_re_union : context -> Expr.expr list -> Expr.expr + + (* concatenation of regular expressions* ) + val mk_re_concat : context -> Expr.expr list -> Expr.expr + + (* regular expression for the range between two characters *) + val mk_re_range : context -> Expr.expr -> Expr.expr -> Expr.expr + + (* bounded loop regular expression *) + val mk_re_loop : context -> Expr.expr -> int -> int -> Expr.expr + + (* intersection of regular expressions *) + val mk_re_intersect : context -> int -> Expr.expr list -> Expr.expr + + (* the regular expression complement *) + val mk_re_complement : context -> Expr.expr -> Expr.expr + + (* the regular expression that accepts no sequences *) + val mk_re_empty : context -> Sort.sort -> Expr.expr + + (* the regular expression that accepts all sequences *) + val mk_re_full : context -> Sort.sort -> Expr.expr + +end + (** Floating-Point Arithmetic *) module FloatingPoint : sig From aa81d58bb0fe632a8832ec8f5a9abbd86753bf07 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 18 Aug 2017 14:29:53 -0700 Subject: [PATCH 146/488] add sequences to ML API #1214 Signed-off-by: Nikolaj Bjorner --- src/api/ml/z3.mli | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 7b561f878..0207a53ed 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1828,6 +1828,7 @@ end (** Sequences, Strings and Regular Expressions **) module Seq : sig + (* create a sequence sort *) val mk_seq_sort : context -> Sort.sort -> Sort.sort (* test if sort is a sequence sort *) From 1e445a62d4d37009cdd537d22bff2d0826efcf1d Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Fri, 18 Aug 2017 17:31:40 -0400 Subject: [PATCH 147/488] improve error message in theory_str when an invalid term in str.to.re is encountered addresses #871 --- src/smt/theory_str.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 5642339f4..7fbc15e8a 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -6223,7 +6223,8 @@ namespace smt { TRACE("str", tout << "string transition " << last << "--" << str[(str.length() - 1)] << "--> " << end << "\n";); } } else { // ! u.str.is_string(arg_str, str) - TRACE("str", tout << "invalid string constant in Str2Reg" << std::endl;); + TRACE("str", tout << "WARNING: invalid string constant in str.to.re! Cancelling." << std::endl;); + u.get_manager().raise_exception("invalid term in str.to.re, argument must be a string constant"); m_valid = false; return; } From 7a977f0106fe0ae07c90d1566a8a75e2d430f2f9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 18 Aug 2017 14:54:54 -0700 Subject: [PATCH 148/488] ensure that timeouts are distinguished from other cancel events #848 Signed-off-by: Nikolaj Bjorner --- src/api/api_context.cpp | 2 +- src/api/api_solver.cpp | 8 ++++++++ src/solver/check_sat_result.cpp | 18 ++++++++++++++++++ src/solver/check_sat_result.h | 2 ++ src/solver/combined_solver.cpp | 4 ++-- src/util/cancel_eh.h | 10 +++++++--- src/util/event_handler.h | 14 +++++++++++++- src/util/scoped_ctrl_c.cpp | 2 +- src/util/scoped_timer.cpp | 2 +- src/util/timeout.cpp | 3 ++- 10 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index 210e0a1d4..c99d3f0c8 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -142,7 +142,7 @@ namespace api { #pragma omp critical (set_interruptable) { if (m_interruptable) - (*m_interruptable)(); + (*m_interruptable)(API_INTERRUPT_EH_CALLER); m_limit.cancel(); m().limit().cancel(); } diff --git a/src/api/api_solver.cpp b/src/api/api_solver.cpp index 7fd6d08fe..3a81080ed 100644 --- a/src/api/api_solver.cpp +++ b/src/api/api_solver.cpp @@ -296,10 +296,14 @@ extern "C" { result = to_solver_ref(s)->check_sat(num_assumptions, _assumptions); } catch (z3_exception & ex) { + to_solver_ref(s)->set_reason_unknown(eh); mk_c(c)->handle_exception(ex); return Z3_L_UNDEF; } } + if (result == l_undef) { + to_solver_ref(s)->set_reason_unknown(eh); + } return static_cast(result); } @@ -466,10 +470,14 @@ extern "C" { result = to_solver_ref(s)->get_consequences(_assumptions, _variables, _consequences); } catch (z3_exception & ex) { + to_solver_ref(s)->set_reason_unknown(eh); mk_c(c)->handle_exception(ex); return Z3_L_UNDEF; } } + if (result == l_undef) { + to_solver_ref(s)->set_reason_unknown(eh); + } for (unsigned i = 0; i < _consequences.size(); ++i) { to_ast_vector_ref(consequences).push_back(_consequences[i].get()); } diff --git a/src/solver/check_sat_result.cpp b/src/solver/check_sat_result.cpp index 5a7733071..f1bedfc08 100644 --- a/src/solver/check_sat_result.cpp +++ b/src/solver/check_sat_result.cpp @@ -18,6 +18,24 @@ Notes: --*/ #include "solver/check_sat_result.h" +void check_sat_result::set_reason_unknown(event_handler& eh) { + switch (eh.caller_id()) { + case UNSET_EH_CALLER: break; + case CTRL_C_EH_CALLER: + set_reason_unknown("interrupted from keyboard"); + break; + case TIMEOUT_EH_CALLER: + set_reason_unknown("timeout"); + break; + case RESLIMIT_EH_CALLER: + set_reason_unknown("max. resource limit exceeded"); + break; + case API_INTERRUPT_EH_CALLER: + set_reason_unknown("interrupted"); + break; + } +} + simple_check_sat_result::simple_check_sat_result(ast_manager & m): m_core(m), m_proof(m) { diff --git a/src/solver/check_sat_result.h b/src/solver/check_sat_result.h index 3079433b5..38720a5e9 100644 --- a/src/solver/check_sat_result.h +++ b/src/solver/check_sat_result.h @@ -22,6 +22,7 @@ Notes: #include "model/model.h" #include "util/lbool.h" #include "util/statistics.h" +#include "util/event_handler.h" /** \brief Abstract interface for the result of a (check-sat) like command. @@ -57,6 +58,7 @@ public: virtual proof * get_proof() = 0; virtual std::string reason_unknown() const = 0; virtual void set_reason_unknown(char const* msg) = 0; + void set_reason_unknown(event_handler& eh); virtual void get_labels(svector & r) = 0; virtual ast_manager& get_manager() const = 0; diff --git a/src/solver/combined_solver.cpp b/src/solver/combined_solver.cpp index 744ac494a..8f37224ad 100644 --- a/src/solver/combined_solver.cpp +++ b/src/solver/combined_solver.cpp @@ -89,8 +89,8 @@ private: m_solver->get_manager().limit().dec_cancel(); } } - virtual void operator()() { - m_canceled = true; + virtual void operator()(event_handler_caller_t caller_id) { + m_canceled = true; m_solver->get_manager().limit().inc_cancel(); } }; diff --git a/src/util/cancel_eh.h b/src/util/cancel_eh.h index 4347a5b52..59f11b3f3 100644 --- a/src/util/cancel_eh.h +++ b/src/util/cancel_eh.h @@ -31,10 +31,14 @@ class cancel_eh : public event_handler { public: cancel_eh(T & o): m_canceled(false), m_obj(o) {} ~cancel_eh() { if (m_canceled) m_obj.dec_cancel(); } - virtual void operator()() { - m_canceled = true; - m_obj.inc_cancel(); + virtual void operator()(event_handler_caller_t caller_id) { + if (!m_canceled) { + m_caller_id = caller_id; + m_canceled = true; + m_obj.inc_cancel(); + } } + bool canceled() const { return m_canceled; } }; #endif diff --git a/src/util/event_handler.h b/src/util/event_handler.h index 4b13f9c48..2a951c3ce 100644 --- a/src/util/event_handler.h +++ b/src/util/event_handler.h @@ -19,10 +19,22 @@ Revision History: #ifndef EVENT_HANDLER_H_ #define EVENT_HANDLER_H_ +enum event_handler_caller_t { + UNSET_EH_CALLER, + CTRL_C_EH_CALLER, + TIMEOUT_EH_CALLER, + RESLIMIT_EH_CALLER, + API_INTERRUPT_EH_CALLER +}; + class event_handler { +protected: + event_handler_caller_t m_caller_id; public: + event_handler(): m_caller_id(UNSET_EH_CALLER) {} virtual ~event_handler() {} - virtual void operator()() = 0; + virtual void operator()(event_handler_caller_t caller_id) = 0; + event_handler_caller_t caller_id() const { return m_caller_id; } }; #endif diff --git a/src/util/scoped_ctrl_c.cpp b/src/util/scoped_ctrl_c.cpp index 739eca295..1cb3a03c4 100644 --- a/src/util/scoped_ctrl_c.cpp +++ b/src/util/scoped_ctrl_c.cpp @@ -24,7 +24,7 @@ scoped_ctrl_c * scoped_ctrl_c::g_obj = 0; void scoped_ctrl_c::on_ctrl_c(int) { if (g_obj->m_first) { - g_obj->m_cancel_eh(); + g_obj->m_cancel_eh(CTRL_C_EH_CALLER); if (g_obj->m_once) { g_obj->m_first = false; signal(SIGINT, on_ctrl_c); // re-install the handler diff --git a/src/util/scoped_timer.cpp b/src/util/scoped_timer.cpp index 741523291..825b251c9 100644 --- a/src/util/scoped_timer.cpp +++ b/src/util/scoped_timer.cpp @@ -85,7 +85,7 @@ struct scoped_timer::imp { obj->m_first = false; } else { - obj->m_eh->operator()(); + obj->m_eh->operator()(TIMEOUT_EH_CALLER); } } #elif defined(__APPLE__) && defined(__MACH__) diff --git a/src/util/timeout.cpp b/src/util/timeout.cpp index a82d1ec25..67995c2aa 100644 --- a/src/util/timeout.cpp +++ b/src/util/timeout.cpp @@ -32,10 +32,11 @@ void (* g_on_timeout)() = 0; class g_timeout_eh : public event_handler { public: - void operator()() { + void operator()(event_handler_caller_t caller_id) { #pragma omp critical (g_timeout_cs) { std::cout << "timeout\n"; + m_caller_id = caller_id; if (g_on_timeout) g_on_timeout(); if (g_timeout) From bc8ae21ebee8a3451c9450a7add52289dc799a16 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 18 Aug 2017 15:14:47 -0700 Subject: [PATCH 149/488] missing parameters for OSX/Linus Signed-off-by: Nikolaj Bjorner --- src/util/scoped_timer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/scoped_timer.cpp b/src/util/scoped_timer.cpp index 825b251c9..3991abd36 100644 --- a/src/util/scoped_timer.cpp +++ b/src/util/scoped_timer.cpp @@ -98,7 +98,7 @@ struct scoped_timer::imp { int e = pthread_cond_timedwait(&st->m_condition_var, &st->m_mutex, &st->m_end_time); if (e != 0 && e != ETIMEDOUT) throw default_exception("failed to start timed wait"); - st->m_eh->operator()(); + st->m_eh->operator()(TIMEOUT_EH_CALLER); pthread_mutex_unlock(&st->m_mutex); @@ -133,7 +133,7 @@ struct scoped_timer::imp { pthread_mutex_unlock(&st->m_mutex); if (e == ETIMEDOUT) - st->m_eh->operator()(); + st->m_eh->operator()(TIMEOUT_EH_CALLER); return 0; } #else From adae32f7efeb5c4bcf4777792f04e53c03e1e564 Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Sat, 19 Aug 2017 23:25:34 -0400 Subject: [PATCH 150/488] add re.all to NFA in theory_str --- src/smt/theory_str.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 7fbc15e8a..127409efe 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -6297,9 +6297,18 @@ namespace smt { TRACE("str", tout << "range NFA: start = " << start << ", end = " << end << std::endl;); } else if (u.re.is_full(e)) { - NOT_IMPLEMENTED_YET(); - m_valid = false; - return; + // effectively the same as .* where . can be any single character + // start --e--> tmp + // tmp --e--> end + // tmp --C--> tmp for every character C + unsigned tmp = next_id(); + make_epsilon_move(start, tmp); + make_epsilon_move(tmp, end); + for (unsigned int i = 0; i < 256; ++i) { + char ch = (char)i; + make_transition(tmp, ch, tmp); + } + TRACE("str", tout << "re.all NFA: start = " << start << ", end = " << end << std::endl;); } else { TRACE("str", tout << "invalid regular expression" << std::endl;); m_valid = false; From 276fdd0e972d9f6c7d78b9eb093fc2b27bb212d7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 20 Aug 2017 08:51:24 -0700 Subject: [PATCH 151/488] register auxiliary constants from projection operation Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 10 +++--- src/model/model_core.cpp | 2 +- src/smt/proto_model/proto_model.cpp | 56 +++++++++++++---------------- src/smt/proto_model/proto_model.h | 1 + src/smt/smt_model_checker.cpp | 5 +-- src/smt/smt_model_finder.cpp | 21 +++++------ src/smt/theory_seq.cpp | 10 ++++-- src/smt/theory_str.cpp | 49 ++++++++++--------------- 8 files changed, 68 insertions(+), 86 deletions(-) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 36a99c592..70eddcea1 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -864,11 +864,11 @@ br_status seq_rewriter::mk_seq_prefix(expr* a, expr* b, expr_ref& result) { expr_ref_vector as(m()), bs(m()); if (a1 != b1 && isc1 && isc2) { - TRACE("seq", tout << s1 << " " << s2 << "\n";); if (s1.length() <= s2.length()) { if (s1.prefixof(s2)) { if (a == a1) { result = m().mk_true(); + TRACE("seq", tout << s1 << " " << s2 << " " << result << "\n";); return BR_DONE; } m_util.str.get_concat(a, as); @@ -878,10 +878,12 @@ br_status seq_rewriter::mk_seq_prefix(expr* a, expr* b, expr_ref& result) { bs[0] = m_util.str.mk_string(s2); result = m_util.str.mk_prefix(m_util.str.mk_concat(as.size()-1, as.c_ptr()+1), m_util.str.mk_concat(bs.size(), bs.c_ptr())); + TRACE("seq", tout << s1 << " " << s2 << " " << result << "\n";); return BR_REWRITE_FULL; } else { result = m().mk_false(); + TRACE("seq", tout << s1 << " " << s2 << " " << result << "\n";); return BR_DONE; } } @@ -889,6 +891,7 @@ br_status seq_rewriter::mk_seq_prefix(expr* a, expr* b, expr_ref& result) { if (s2.prefixof(s1)) { if (b == b1) { result = m().mk_false(); + TRACE("seq", tout << s1 << " " << s2 << " " << result << "\n";); return BR_DONE; } m_util.str.get_concat(a, as); @@ -898,10 +901,12 @@ br_status seq_rewriter::mk_seq_prefix(expr* a, expr* b, expr_ref& result) { as[0] = m_util.str.mk_string(s1); result = m_util.str.mk_prefix(m_util.str.mk_concat(as.size(), as.c_ptr()), m_util.str.mk_concat(bs.size()-1, bs.c_ptr()+1)); + TRACE("seq", tout << s1 << " " << s2 << " " << result << "\n";); return BR_REWRITE_FULL; } else { result = m().mk_false(); + TRACE("seq", tout << s1 << " " << s2 << " " << result << "\n";); return BR_DONE; } } @@ -930,9 +935,6 @@ br_status seq_rewriter::mk_seq_prefix(expr* a, expr* b, expr_ref& result) { if (i == as.size()) { result = mk_and(eqs); TRACE("seq", tout << result << "\n";); - if (m().is_true(result)) { - return BR_DONE; - } return BR_REWRITE3; } SASSERT(i < as.size()); diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 9da1e76f9..684d1b3c2 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -94,7 +94,7 @@ void model_core::unregister_decl(func_decl * d) { m_manager.dec_ref(ec->get_data().m_value); m_interp.remove(d); m_const_decls.erase(d); - return; + return; } decl2finterp::obj_map_entry * ef = m_finterp.find_core(d); diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index f14034601..1eed4d0dd 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -42,6 +42,11 @@ proto_model::proto_model(ast_manager & m, params_ref const & p): void proto_model::register_aux_decl(func_decl * d, func_interp * fi) { model_core::register_decl(d, fi); + TRACE("cleanup_bug", tout << "register " << d->get_name() << "\n";); + m_aux_decls.insert(d); +} + +void proto_model::register_aux_decl(func_decl * d) { m_aux_decls.insert(d); } @@ -220,31 +225,29 @@ void proto_model::remove_aux_decls_not_in_set(ptr_vector & decls, fun */ void proto_model::cleanup() { func_decl_set found_aux_fs; - decl2finterp::iterator it = m_finterp.begin(); - decl2finterp::iterator end = m_finterp.end(); - for (; it != end; ++it) { - func_interp * fi = (*it).m_value; + for (auto const& kv : m_finterp) { + func_interp * fi = kv.m_value; cleanup_func_interp(fi, found_aux_fs); } + TRACE("cleanup_bug", + for (func_decl* faux : m_aux_decls) { + tout << faux->get_name() << "\n"; + }); // remove auxiliary declarations that are not used. if (found_aux_fs.size() != m_aux_decls.size()) { remove_aux_decls_not_in_set(m_decls, found_aux_fs); remove_aux_decls_not_in_set(m_func_decls, found_aux_fs); - func_decl_set::iterator it2 = m_aux_decls.begin(); - func_decl_set::iterator end2 = m_aux_decls.end(); - for (; it2 != end2; ++it2) { - func_decl * faux = *it2; + for (func_decl* faux : m_aux_decls) { if (!found_aux_fs.contains(faux)) { TRACE("cleanup_bug", tout << "eliminating " << faux->get_name() << "\n";); - func_interp * fi = 0; - m_finterp.find(faux, fi); - SASSERT(fi != 0); - m_finterp.erase(faux); - m_manager.dec_ref(faux); - dealloc(fi); + unregister_decl(faux); } + else { + TRACE("cleanup_bug", tout << "not eliminating " << faux->get_name() << "\n";); + } + } m_aux_decls.swap(found_aux_fs); } @@ -270,10 +273,8 @@ ptr_vector const & proto_model::get_universe(sort * s) const { ptr_vector & tmp = const_cast(this)->m_tmp; tmp.reset(); obj_hashtable const & u = get_known_universe(s); - obj_hashtable::iterator it = u.begin(); - obj_hashtable::iterator end = u.end(); - for (; it != end; ++it) - tmp.push_back(*it); + for (expr * e : u) + tmp.push_back(e); return tmp; } @@ -356,10 +357,7 @@ bool proto_model::is_as_array(expr * v) const { } void proto_model::compress() { - ptr_vector::iterator it = m_func_decls.begin(); - ptr_vector::iterator end = m_func_decls.end(); - for (; it != end; ++it) { - func_decl * f = *it; + for (func_decl* f : m_func_decls) { func_interp * fi = get_func_interp(f); SASSERT(fi != 0); fi->compress(); @@ -412,17 +410,13 @@ model * proto_model::mk_model() { TRACE("proto_model", tout << "mk_model\n"; model_v2_pp(tout, *this);); model * m = alloc(model, m_manager); - decl2expr::iterator it1 = m_interp.begin(); - decl2expr::iterator end1 = m_interp.end(); - for (; it1 != end1; ++it1) { - m->register_decl(it1->m_key, it1->m_value); + for (auto const& kv : m_interp) { + m->register_decl(kv.m_key, kv.m_value); } - decl2finterp::iterator it2 = m_finterp.begin(); - decl2finterp::iterator end2 = m_finterp.end(); - for (; it2 != end2; ++it2) { - m->register_decl(it2->m_key, it2->m_value); - m_manager.dec_ref(it2->m_key); + for (auto const& kv : m_finterp) { + m->register_decl(kv.m_key, kv.m_value); + m_manager.dec_ref(kv.m_key); } m_finterp.reset(); // m took the ownership of the func_interp's diff --git a/src/smt/proto_model/proto_model.h b/src/smt/proto_model/proto_model.h index 1cee04650..a7ec8d3a9 100644 --- a/src/smt/proto_model/proto_model.h +++ b/src/smt/proto_model/proto_model.h @@ -84,6 +84,7 @@ public: // Primitives for building models // void register_aux_decl(func_decl * f, func_interp * fi); + void register_aux_decl(func_decl * f); void reregister_decl(func_decl * f, func_interp * new_fi, func_decl * f_aux); void compress(); void cleanup(); diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index 875e7adf2..13651a63c 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -89,10 +89,7 @@ namespace smt { void model_checker::restrict_to_universe(expr * sk, obj_hashtable const & universe) { SASSERT(!universe.empty()); ptr_buffer eqs; - obj_hashtable::iterator it = universe.begin(); - obj_hashtable::iterator end = universe.end(); - for (; it != end; ++it) { - expr * e = *it; + for (expr * e : universe) { eqs.push_back(m.mk_eq(sk, e)); } expr_ref fml(m.mk_or(eqs.size(), eqs.c_ptr()), m); diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 35a98aa01..68d56ea84 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -628,18 +628,14 @@ namespace smt { ptr_vector const & exceptions = n->get_exceptions(); ptr_vector const & avoid_set = n->get_avoid_set(); - ptr_vector::const_iterator it1 = exceptions.begin(); - ptr_vector::const_iterator end1 = exceptions.end(); - for (; it1 != end1; ++it1) { - expr * val = eval(*it1, true); + for (expr* e : exceptions) { + expr * val = eval(e, true); SASSERT(val != 0); r.push_back(val); } - ptr_vector::const_iterator it2 = avoid_set.begin(); - ptr_vector::const_iterator end2 = avoid_set.end(); - for (; it2 != end2; ++it2) { - node * n = (*it2)->get_root(); + for (node* a : avoid_set) { + node * n = a->get_root(); if (!n->is_mono_proj() && n->get_else() != 0) { expr * val = eval(n->get_else(), true); SASSERT(val != 0); @@ -661,11 +657,9 @@ namespace smt { expr * t_result = 0; unsigned gen_result = UINT_MAX; - obj_map::iterator it1 = elems.begin(); - obj_map::iterator end1 = elems.end(); - for (; it1 != end1; ++it1) { - expr * t = (*it1).m_key; - unsigned gen = (*it1).m_value; + for (auto const& kv : elems) { + expr * t = kv.m_key; + unsigned gen = kv.m_value; expr * t_val = eval(t, true); SASSERT(t_val != 0); ptr_buffer::const_iterator it2 = ex_vals.begin(); @@ -699,6 +693,7 @@ namespace smt { if (m_sort2k.find(s, r)) return r; r = m_manager.mk_fresh_const("k", s); + m_model->register_aux_decl(r->get_decl()); m_sort2k.insert(s, r); m_ks.push_back(r); return r; diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index bbd11b4bf..d988da54f 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -3224,26 +3224,32 @@ void theory_seq::add_indexof_axiom(expr* i) { /* let r = replace(a, s, t) + a = "" => s = "" or r = a + contains(a, s) or r = a + s = "" => r = t+a + tightest_prefix(s, x) (contains(a, s) -> r = xty & a = xsy) & (!contains(a, s) -> r = a) */ void theory_seq::add_replace_axiom(expr* r) { + context& ctx = get_context(); expr* a = 0, *s = 0, *t = 0; VERIFY(m_util.str.is_replace(r, a, s, t)); expr_ref x = mk_skolem(m_indexof_left, a, s); expr_ref y = mk_skolem(m_indexof_right, a, s); expr_ref xty = mk_concat(x, t, y); expr_ref xsy = mk_concat(x, s, y); + literal a_emp = mk_eq_empty(a, true); + literal s_emp = mk_eq_empty(s, true); literal cnt = mk_literal(m_util.str.mk_contains(a, s)); - literal a_emp = mk_eq_empty(a); - literal s_emp = mk_eq_empty(s); add_axiom(~a_emp, s_emp, mk_seq_eq(r, a)); add_axiom(cnt, mk_seq_eq(r, a)); add_axiom(~s_emp, mk_seq_eq(r, mk_concat(t, a))); add_axiom(~cnt, a_emp, s_emp, mk_seq_eq(a, xsy)); add_axiom(~cnt, a_emp, s_emp, mk_seq_eq(r, xty)); + ctx.force_phase(cnt); tightest_prefix(s, x); } diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 052fd705f..92ffd8222 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -166,14 +166,18 @@ namespace smt { } } - void theory_str::assert_axiom(expr * e) { + void theory_str::assert_axiom(expr * _e) { if (opt_VerifyFinalCheckProgress) { finalCheckProgressIndicator = true; } - if (get_manager().is_true(e)) return; - TRACE("str", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << std::endl;); + if (get_manager().is_true(_e)) return; context & ctx = get_context(); + ast_manager& m = get_manager(); + TRACE("str", tout << "asserting " << mk_ismt2_pp(_e, m) << std::endl;); + expr_ref e(_e, m); + th_rewriter rw(m); + rw(e); if (!ctx.b_internalized(e)) { ctx.internalize(e, false); } @@ -1419,6 +1423,9 @@ namespace smt { void theory_str::instantiate_axiom_Substr(enode * e) { context & ctx = get_context(); ast_manager & m = get_manager(); + expr* substrBase = 0; + expr* substrPos = 0; + expr* substrLen = 0; app * expr = e->get_owner(); if (axiomatized_terms.contains(expr)) { @@ -1429,12 +1436,7 @@ namespace smt { TRACE("str", tout << "instantiate Substr axiom for " << mk_pp(expr, m) << std::endl;); - expr_ref substrBase(expr->get_arg(0), m); - expr_ref substrPos(expr->get_arg(1), m); - expr_ref substrLen(expr->get_arg(2), m); - SASSERT(substrBase); - SASSERT(substrPos); - SASSERT(substrLen); + VERIFY(u.str.is_extract(expr, substrBase, substrPos, substrLen)); expr_ref zero(m_autil.mk_numeral(rational::zero(), true), m); expr_ref minusOne(m_autil.mk_numeral(rational::minus_one(), true), m); @@ -1452,28 +1454,19 @@ namespace smt { // len >= 0 argumentsValid_terms.push_back(m_autil.mk_ge(substrLen, zero)); - expr_ref argumentsValid(mk_and(argumentsValid_terms), m); - SASSERT(argumentsValid); - ctx.internalize(argumentsValid, false); // (pos+len) >= strlen(base) // --> pos + len + -1*strlen(base) >= 0 expr_ref lenOutOfBounds(m_autil.mk_ge( m_autil.mk_add(substrPos, substrLen, m_autil.mk_mul(minusOne, mk_strlen(substrBase))), zero), m); - SASSERT(lenOutOfBounds); - ctx.internalize(argumentsValid, false); + expr_ref argumentsValid = mk_and(argumentsValid_terms); // Case 1: pos < 0 or pos >= strlen(base) or len < 0 // ==> (Substr ...) = "" expr_ref case1_premise(m.mk_not(argumentsValid), m); - SASSERT(case1_premise); - ctx.internalize(case1_premise, false); expr_ref case1_conclusion(ctx.mk_eq_atom(expr, mk_string("")), m); - SASSERT(case1_conclusion); - ctx.internalize(case1_conclusion, false); - expr_ref case1(rewrite_implication(case1_premise, case1_conclusion), m); - SASSERT(case1); + expr_ref case1(m.mk_implies(case1_premise, case1_conclusion), m); // Case 2: (pos >= 0 and pos < strlen(base) and len >= 0) and (pos+len) >= strlen(base) // ==> base = t0.t1 AND len(t0) = pos AND (Substr ...) = t1 @@ -1483,8 +1476,7 @@ namespace smt { ctx.mk_eq_atom(substrBase, mk_concat(t0,t1)), ctx.mk_eq_atom(mk_strlen(t0), substrPos), ctx.mk_eq_atom(expr, t1)), m); - expr_ref case2(rewrite_implication(m.mk_and(argumentsValid, lenOutOfBounds), case2_conclusion), m); - SASSERT(case2); + expr_ref case2(m.mk_implies(m.mk_and(argumentsValid, lenOutOfBounds), case2_conclusion), m); // Case 3: (pos >= 0 and pos < strlen(base) and len >= 0) and (pos+len) < strlen(base) // ==> base = t2.t3.t4 AND len(t2) = pos AND len(t3) = len AND (Substr ...) = t3 @@ -1497,16 +1489,11 @@ namespace smt { case3_conclusion_terms.push_back(ctx.mk_eq_atom(mk_strlen(t3), substrLen)); case3_conclusion_terms.push_back(ctx.mk_eq_atom(expr, t3)); expr_ref case3_conclusion(mk_and(case3_conclusion_terms), m); - expr_ref case3(rewrite_implication(m.mk_and(argumentsValid, m.mk_not(lenOutOfBounds)), case3_conclusion), m); - SASSERT(case3); + expr_ref case3(m.mk_implies(m.mk_and(argumentsValid, m.mk_not(lenOutOfBounds)), case3_conclusion), m); - ctx.internalize(case1, false); - ctx.internalize(case2, false); - ctx.internalize(case3, false); - - expr_ref finalAxiom(m.mk_and(case1, case2, case3), m); - SASSERT(finalAxiom); - assert_axiom(finalAxiom); + assert_axiom(case1); + assert_axiom(case2); + assert_axiom(case3); } void theory_str::instantiate_axiom_Replace(enode * e) { From 9fe9587a9bef7486036d1bdafc32d1125b5f6c3e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 20 Aug 2017 09:14:08 -0700 Subject: [PATCH 152/488] revert local changes to theory_str Signed-off-by: Nikolaj Bjorner --- src/smt/theory_str.cpp | 110 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 7 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 3417fc798..0d963f8b9 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -166,18 +166,14 @@ namespace smt { } } - void theory_str::assert_axiom(expr * _e) { + void theory_str::assert_axiom(expr * e) { if (opt_VerifyFinalCheckProgress) { finalCheckProgressIndicator = true; } - if (get_manager().is_true(_e)) return; + if (get_manager().is_true(e)) return; + TRACE("str", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << std::endl;); context & ctx = get_context(); - ast_manager& m = get_manager(); - TRACE("str", tout << "asserting " << mk_ismt2_pp(_e, m) << std::endl;); - expr_ref e(_e, m); - th_rewriter rw(m); - rw(e); if (!ctx.b_internalized(e)) { ctx.internalize(e, false); } @@ -189,6 +185,7 @@ namespace smt { m_trail.push_back(e); //TRACE("str", tout << "done asserting " << mk_ismt2_pp(e, get_manager()) << std::endl;); + } expr * theory_str::rewrite_implication(expr * premise, expr * conclusion) { @@ -1420,6 +1417,104 @@ namespace smt { assert_axiom(finalAxiom); } + void theory_str::instantiate_axiom_Substr(enode * e) { + context & ctx = get_context(); + ast_manager & m = get_manager(); + + app * expr = e->get_owner(); + if (axiomatized_terms.contains(expr)) { + TRACE("str", tout << "already set up Substr axiom for " << mk_pp(expr, m) << std::endl;); + return; + } + axiomatized_terms.insert(expr); + + TRACE("str", tout << "instantiate Substr axiom for " << mk_pp(expr, m) << std::endl;); + + expr_ref substrBase(expr->get_arg(0), m); + expr_ref substrPos(expr->get_arg(1), m); + expr_ref substrLen(expr->get_arg(2), m); + SASSERT(substrBase); + SASSERT(substrPos); + SASSERT(substrLen); + + expr_ref zero(m_autil.mk_numeral(rational::zero(), true), m); + expr_ref minusOne(m_autil.mk_numeral(rational::minus_one(), true), m); + SASSERT(zero); + SASSERT(minusOne); + + expr_ref_vector argumentsValid_terms(m); + // pos >= 0 + argumentsValid_terms.push_back(m_autil.mk_ge(substrPos, zero)); + // pos < strlen(base) + // --> pos + -1*strlen(base) < 0 + argumentsValid_terms.push_back(m.mk_not(m_autil.mk_ge( + m_autil.mk_add(substrPos, m_autil.mk_mul(minusOne, substrLen)), + zero))); + + // len >= 0 + argumentsValid_terms.push_back(m_autil.mk_ge(substrLen, zero)); + + expr_ref argumentsValid(mk_and(argumentsValid_terms), m); + SASSERT(argumentsValid); + ctx.internalize(argumentsValid, false); + + // (pos+len) >= strlen(base) + // --> pos + len + -1*strlen(base) >= 0 + expr_ref lenOutOfBounds(m_autil.mk_ge( + m_autil.mk_add(substrPos, substrLen, m_autil.mk_mul(minusOne, mk_strlen(substrBase))), + zero), m); + SASSERT(lenOutOfBounds); + ctx.internalize(argumentsValid, false); + + // Case 1: pos < 0 or pos >= strlen(base) or len < 0 + // ==> (Substr ...) = "" + expr_ref case1_premise(m.mk_not(argumentsValid), m); + SASSERT(case1_premise); + ctx.internalize(case1_premise, false); + expr_ref case1_conclusion(ctx.mk_eq_atom(expr, mk_string("")), m); + SASSERT(case1_conclusion); + ctx.internalize(case1_conclusion, false); + expr_ref case1(rewrite_implication(case1_premise, case1_conclusion), m); + SASSERT(case1); + + // Case 2: (pos >= 0 and pos < strlen(base) and len >= 0) and (pos+len) >= strlen(base) + // ==> base = t0.t1 AND len(t0) = pos AND (Substr ...) = t1 + expr_ref t0(mk_str_var("t0"), m); + expr_ref t1(mk_str_var("t1"), m); + expr_ref case2_conclusion(m.mk_and( + ctx.mk_eq_atom(substrBase, mk_concat(t0,t1)), + ctx.mk_eq_atom(mk_strlen(t0), substrPos), + ctx.mk_eq_atom(expr, t1)), m); + expr_ref case2(rewrite_implication(m.mk_and(argumentsValid, lenOutOfBounds), case2_conclusion), m); + SASSERT(case2); + + // Case 3: (pos >= 0 and pos < strlen(base) and len >= 0) and (pos+len) < strlen(base) + // ==> base = t2.t3.t4 AND len(t2) = pos AND len(t3) = len AND (Substr ...) = t3 + + expr_ref t2(mk_str_var("t2"), m); + expr_ref t3(mk_str_var("t3"), m); + expr_ref t4(mk_str_var("t4"), m); + expr_ref_vector case3_conclusion_terms(m); + case3_conclusion_terms.push_back(ctx.mk_eq_atom(substrBase, mk_concat(t2, mk_concat(t3, t4)))); + case3_conclusion_terms.push_back(ctx.mk_eq_atom(mk_strlen(t2), substrPos)); + case3_conclusion_terms.push_back(ctx.mk_eq_atom(mk_strlen(t3), substrLen)); + case3_conclusion_terms.push_back(ctx.mk_eq_atom(expr, t3)); + expr_ref case3_conclusion(mk_and(case3_conclusion_terms), m); + expr_ref case3(rewrite_implication(m.mk_and(argumentsValid, m.mk_not(lenOutOfBounds)), case3_conclusion), m); + SASSERT(case3); + + ctx.internalize(case1, false); + ctx.internalize(case2, false); + ctx.internalize(case3, false); + + expr_ref finalAxiom(m.mk_and(case1, case2, case3), m); + SASSERT(finalAxiom); + assert_axiom(finalAxiom); + } + +#if 0 + // rewrite + // requires to add th_rewriter to assert_axiom to enforce normal form. void theory_str::instantiate_axiom_Substr(enode * e) { context & ctx = get_context(); ast_manager & m = get_manager(); @@ -1495,6 +1590,7 @@ namespace smt { assert_axiom(case2); assert_axiom(case3); } +#endif void theory_str::instantiate_axiom_Replace(enode * e) { context & ctx = get_context(); From 359ee818a5800e8f0fa00a6c9ee63c690fc00a1a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 20 Aug 2017 15:35:16 -0700 Subject: [PATCH 153/488] purge iterators Signed-off-by: Nikolaj Bjorner --- src/ast/array_decl_plugin.cpp | 4 +- src/ast/array_decl_plugin.h | 2 +- src/smt/proto_model/datatype_factory.cpp | 16 +- src/smt/proto_model/proto_model.cpp | 306 +-------------- src/smt/proto_model/proto_model.h | 3 - src/smt/smt_model_checker.cpp | 34 +- src/smt/smt_model_finder.cpp | 474 ++++++++--------------- 7 files changed, 180 insertions(+), 659 deletions(-) diff --git a/src/ast/array_decl_plugin.cpp b/src/ast/array_decl_plugin.cpp index efcad1d5e..6296d344a 100644 --- a/src/ast/array_decl_plugin.cpp +++ b/src/ast/array_decl_plugin.cpp @@ -556,9 +556,9 @@ bool array_decl_plugin::is_fully_interp(sort const * s) const { return m_manager->is_fully_interp(get_array_range(s)); } -func_decl * array_recognizers::get_as_array_func_decl(app * n) const { +func_decl * array_recognizers::get_as_array_func_decl(expr * n) const { SASSERT(is_as_array(n)); - return to_func_decl(n->get_decl()->get_parameter(0).get_ast()); + return to_func_decl(to_app(n)->get_decl()->get_parameter(0).get_ast()); } array_util::array_util(ast_manager& m): diff --git a/src/ast/array_decl_plugin.h b/src/ast/array_decl_plugin.h index e06cb3065..0febb82a4 100644 --- a/src/ast/array_decl_plugin.h +++ b/src/ast/array_decl_plugin.h @@ -148,7 +148,7 @@ public: bool is_const(func_decl* f) const { return is_decl_of(f, m_fid, OP_CONST_ARRAY); } bool is_map(func_decl* f) const { return is_decl_of(f, m_fid, OP_ARRAY_MAP); } bool is_as_array(func_decl* f) const { return is_decl_of(f, m_fid, OP_AS_ARRAY); } - func_decl * get_as_array_func_decl(app * n) const; + func_decl * get_as_array_func_decl(expr * n) const; }; class array_util : public array_recognizers { diff --git a/src/smt/proto_model/datatype_factory.cpp b/src/smt/proto_model/datatype_factory.cpp index f5079b0e5..d738f2cbd 100644 --- a/src/smt/proto_model/datatype_factory.cpp +++ b/src/smt/proto_model/datatype_factory.cpp @@ -19,7 +19,6 @@ Revision History: #include "smt/proto_model/datatype_factory.h" #include "smt/proto_model/proto_model.h" #include "ast/ast_pp.h" -#include "ast/ast_ll_pp.h" #include "ast/expr_functors.h" datatype_factory::datatype_factory(ast_manager & m, proto_model & md): @@ -90,10 +89,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) { // If the argumet is a sibling datatype of s, then // use get_last_fresh_value. ptr_vector const * constructors = m_util.get_datatype_constructors(s); - ptr_vector::const_iterator it = constructors->begin(); - ptr_vector::const_iterator end = constructors->end(); - for (; it != end; ++it) { - func_decl * constructor = *it; + for (func_decl * constructor : *constructors) { expr_ref_vector args(m_manager); bool found_fresh_arg = false; bool recursive = false; @@ -156,10 +152,7 @@ expr * datatype_factory::get_fresh_value(sort * s) { // arguments (if the argument is not a sibling datatype of s). // Two datatypes are siblings if they were defined together in the same mutually recursive definition. ptr_vector const * constructors = m_util.get_datatype_constructors(s); - ptr_vector::const_iterator it = constructors->begin(); - ptr_vector::const_iterator end = constructors->end(); - for (; it != end; ++it) { - func_decl * constructor = *it; + for (func_decl * constructor : *constructors) { expr_ref_vector args(m_manager); bool found_fresh_arg = false; unsigned num = constructor->get_arity(); @@ -197,10 +190,7 @@ expr * datatype_factory::get_fresh_value(sort * s) { ++num_iterations; TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";); ptr_vector const * constructors = m_util.get_datatype_constructors(s); - ptr_vector::const_iterator it = constructors->begin(); - ptr_vector::const_iterator end = constructors->end(); - for (; it != end; ++it) { - func_decl * constructor = *it; + for (func_decl * constructor : *constructors) { expr_ref_vector args(m_manager); bool found_sibling = false; unsigned num = constructor->get_arity(); diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index 1eed4d0dd..9a5f2a1ca 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -16,33 +16,27 @@ Author: Revision History: --*/ -#include "smt/proto_model/proto_model.h" -#include "model/model_params.hpp" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" #include "ast/rewriter/var_subst.h" -#include "ast/array_decl_plugin.h" #include "ast/well_sorted.h" #include "ast/used_symbols.h" +#include "model/model_params.hpp" #include "model/model_v2_pp.h" +#include "smt/proto_model/proto_model.h" proto_model::proto_model(ast_manager & m, params_ref const & p): model_core(m), - m_afid(m.mk_family_id(symbol("array"))), m_eval(*this), m_rewrite(m) { register_factory(alloc(basic_factory, m)); m_user_sort_factory = alloc(user_sort_factory, m); register_factory(m_user_sort_factory); - m_model_partial = model_params(p).partial(); } - - void proto_model::register_aux_decl(func_decl * d, func_interp * fi) { model_core::register_decl(d, fi); - TRACE("cleanup_bug", tout << "register " << d->get_name() << "\n";); m_aux_decls.insert(d); } @@ -89,21 +83,11 @@ expr * proto_model::mk_some_interp_for(func_decl * d) { } -bool proto_model::is_select_of_model_value(expr* e) const { - return - is_app_of(e, m_afid, OP_SELECT) && - is_as_array(to_app(e)->get_arg(0)) && - has_interpretation(array_util(m_manager).get_as_array_func_decl(to_app(to_app(e)->get_arg(0)))); -} - bool proto_model::eval(expr * e, expr_ref & result, bool model_completion) { m_eval.set_model_completion(model_completion); m_eval.set_expand_array_equalities(false); try { m_eval(e, result); -#if 0 - std::cout << mk_pp(e, m_manager) << "\n===>\n" << result << "\n"; -#endif return true; } catch (model_evaluator_exception & ex) { @@ -163,12 +147,11 @@ void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_au app * t = to_app(a); bool visited = true; args.reset(); - unsigned num_args = t->get_num_args(); - for (unsigned i = 0; i < num_args; ++i) { + for (expr* t_arg : *t) { expr * arg = 0; - if (!cache.find(t->get_arg(i), arg)) { + if (!cache.find(t_arg, arg)) { visited = false; - todo.push_back(t->get_arg(i)); + todo.push_back(t_arg); } else { args.push_back(arg); @@ -181,7 +164,7 @@ void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_au if (m_aux_decls.contains(f)) found_aux_fs.insert(f); expr_ref new_t(m_manager); - new_t = m_rewrite.mk_app(f, num_args, args.c_ptr()); + new_t = m_rewrite.mk_app(f, args.size(), args.c_ptr()); if (t != new_t.get()) trail.push_back(new_t); todo.pop_back(); @@ -230,10 +213,6 @@ void proto_model::cleanup() { cleanup_func_interp(fi, found_aux_fs); } - TRACE("cleanup_bug", - for (func_decl* faux : m_aux_decls) { - tout << faux->get_name() << "\n"; - }); // remove auxiliary declarations that are not used. if (found_aux_fs.size() != m_aux_decls.size()) { remove_aux_decls_not_in_set(m_decls, found_aux_fs); @@ -244,10 +223,6 @@ void proto_model::cleanup() { TRACE("cleanup_bug", tout << "eliminating " << faux->get_name() << "\n";); unregister_decl(faux); } - else { - TRACE("cleanup_bug", tout << "not eliminating " << faux->get_name() << "\n";); - } - } m_aux_decls.swap(found_aux_fs); } @@ -273,8 +248,9 @@ ptr_vector const & proto_model::get_universe(sort * s) const { ptr_vector & tmp = const_cast(this)->m_tmp; tmp.reset(); obj_hashtable const & u = get_known_universe(s); - for (expr * e : u) + for (expr * e : u) { tmp.push_back(e); + } return tmp; } @@ -352,10 +328,6 @@ void proto_model::register_value(expr * n) { } } -bool proto_model::is_as_array(expr * v) const { - return is_app_of(v, m_afid, OP_AS_ARRAY); -} - void proto_model::compress() { for (func_decl* f : m_func_decls) { func_interp * fi = get_func_interp(f); @@ -371,23 +343,9 @@ void proto_model::compress() { void proto_model::complete_partial_func(func_decl * f) { func_interp * fi = get_func_interp(f); if (fi && fi->is_partial()) { - expr * else_value = 0; -#if 0 - // For UFBV benchmarks, setting the "else" to false is not a good idea. - // TODO: find a permanent solution. A possibility is to add another option. - if (m_manager.is_bool(f->get_range())) { - else_value = m_manager.mk_false(); - } - else { - else_value = fi->get_max_occ_result(); - if (else_value == 0) - else_value = get_some_value(f->get_range()); - } -#else - else_value = fi->get_max_occ_result(); + expr * else_value = fi->get_max_occ_result(); if (else_value == 0) else_value = get_some_value(f->get_range()); -#endif fi->set_else(else_value); } } @@ -401,8 +359,8 @@ void proto_model::complete_partial_funcs() { // m_func_decls may be "expanded" when we invoke get_some_value. // So, we must not use iterators to traverse it. - for (unsigned i = 0; i < m_func_decls.size(); i++) { - complete_partial_func(m_func_decls[i]); + for (func_decl* f : m_func_decls) { + complete_partial_func(f); } } @@ -431,245 +389,3 @@ model * proto_model::mk_model() { return m; } - - -#if 0 - -#include "ast/simplifier/simplifier.h" -#include "ast/simplifier/basic_simplifier_plugin.h" - -// Auxiliary function for computing fi(args[0], ..., args[fi.get_arity() - 1]). -// The result is stored in result. -// Return true if succeeded, and false otherwise. -// It uses the simplifier s during the computation. -bool eval(func_interp & fi, simplifier & s, expr * const * args, expr_ref & result) { - bool actuals_are_values = true; - - if (fi.num_entries() != 0) { - for (unsigned i = 0; actuals_are_values && i < fi.get_arity(); i++) { - actuals_are_values = fi.m().is_value(args[i]); - } - } - - func_entry * entry = fi.get_entry(args); - if (entry != 0) { - result = entry->get_result(); - return true; - } - - TRACE("func_interp", tout << "failed to find entry for: "; - for(unsigned i = 0; i < fi.get_arity(); i++) - tout << mk_pp(args[i], fi.m()) << " "; - tout << "\nis partial: " << fi.is_partial() << "\n";); - - if (!fi.eval_else(args, result)) { - return false; - } - - if (actuals_are_values && fi.args_are_values()) { - // cheap case... we are done - return true; - } - - // build symbolic result... the actuals may be equal to the args of one of the entries. - basic_simplifier_plugin * bs = static_cast(s.get_plugin(fi.m().get_basic_family_id())); - for (unsigned k = 0; k < fi.num_entries(); k++) { - func_entry const * curr = fi.get_entry(k); - SASSERT(!curr->eq_args(fi.m(), fi.get_arity(), args)); - if (!actuals_are_values || !curr->args_are_values()) { - expr_ref_buffer eqs(fi.m()); - unsigned i = fi.get_arity(); - while (i > 0) { - --i; - expr_ref new_eq(fi.m()); - bs->mk_eq(curr->get_arg(i), args[i], new_eq); - eqs.push_back(new_eq); - } - SASSERT(eqs.size() == fi.get_arity()); - expr_ref new_cond(fi.m()); - bs->mk_and(eqs.size(), eqs.c_ptr(), new_cond); - bs->mk_ite(new_cond, curr->get_result(), result, result); - } - } - return true; -} - - -bool proto_model::eval(expr * e, expr_ref & result, bool model_completion) { - bool is_ok = true; - SASSERT(is_well_sorted(m_manager, e)); - TRACE("model_eval", tout << mk_pp(e, m_manager) << "\n"; - tout << "sort: " << mk_pp(m_manager.get_sort(e), m_manager) << "\n";); - - obj_map eval_cache; - expr_ref_vector trail(m_manager); - sbuffer, 128> todo; - ptr_buffer args; - expr * null = static_cast(0); - todo.push_back(std::make_pair(e, null)); - - simplifier m_simplifier(m_manager); - - expr * a; - expr * expanded_a; - while (!todo.empty()) { - std::pair & p = todo.back(); - a = p.first; - expanded_a = p.second; - if (expanded_a != 0) { - expr * r = 0; - eval_cache.find(expanded_a, r); - SASSERT(r != 0); - todo.pop_back(); - eval_cache.insert(a, r); - TRACE("model_eval", - tout << "orig:\n" << mk_pp(a, m_manager) << "\n"; - tout << "after beta reduction:\n" << mk_pp(expanded_a, m_manager) << "\n"; - tout << "new:\n" << mk_pp(r, m_manager) << "\n";); - } - else { - switch(a->get_kind()) { - case AST_APP: { - app * t = to_app(a); - bool visited = true; - args.reset(); - unsigned num_args = t->get_num_args(); - for (unsigned i = 0; i < num_args; ++i) { - expr * arg = 0; - if (!eval_cache.find(t->get_arg(i), arg)) { - visited = false; - todo.push_back(std::make_pair(t->get_arg(i), null)); - } - else { - args.push_back(arg); - } - } - if (!visited) { - continue; - } - SASSERT(args.size() == t->get_num_args()); - expr_ref new_t(m_manager); - func_decl * f = t->get_decl(); - - if (!has_interpretation(f)) { - // the model does not assign an interpretation to f. - SASSERT(new_t.get() == 0); - if (f->get_family_id() == null_family_id) { - if (model_completion) { - // create an interpretation for f. - new_t = mk_some_interp_for(f); - } - else { - TRACE("model_eval", tout << f->get_name() << " is uninterpreted\n";); - is_ok = false; - } - } - if (new_t.get() == 0) { - // t is interpreted or model completion is disabled. - m_simplifier.mk_app(f, num_args, args.c_ptr(), new_t); - TRACE("model_eval", tout << mk_pp(t, m_manager) << " -> " << new_t << "\n";); - trail.push_back(new_t); - if (!is_app(new_t) || to_app(new_t)->get_decl() != f || is_select_of_model_value(new_t)) { - // if the result is not of the form (f ...), then assume we must simplify it. - expr * new_new_t = 0; - if (!eval_cache.find(new_t.get(), new_new_t)) { - todo.back().second = new_t; - todo.push_back(std::make_pair(new_t, null)); - continue; - } - else { - new_t = new_new_t; - } - } - } - } - else { - // the model has an interpretaion for f. - if (num_args == 0) { - // t is a constant - new_t = get_const_interp(f); - } - else { - // t is a function application - SASSERT(new_t.get() == 0); - // try to use function graph first - func_interp * fi = get_func_interp(f); - SASSERT(fi->get_arity() == num_args); - expr_ref r1(m_manager); - // fi may be partial... - if (!::eval(*fi, m_simplifier, args.c_ptr(), r1)) { - SASSERT(fi->is_partial()); // fi->eval only fails when fi is partial. - if (model_completion) { - expr * r = get_some_value(f->get_range()); - fi->set_else(r); - SASSERT(!fi->is_partial()); - new_t = r; - } - else { - // f is an uninterpreted function, there is no need to use m_simplifier.mk_app - new_t = m_manager.mk_app(f, num_args, args.c_ptr()); - trail.push_back(new_t); - TRACE("model_eval", tout << f->get_name() << " is uninterpreted\n";); - is_ok = false; - } - } - else { - SASSERT(r1); - trail.push_back(r1); - TRACE("model_eval", tout << mk_pp(a, m_manager) << "\nevaluates to: " << r1 << "\n";); - expr * r2 = 0; - if (!eval_cache.find(r1.get(), r2)) { - todo.back().second = r1; - todo.push_back(std::make_pair(r1, null)); - continue; - } - else { - new_t = r2; - } - } - } - } - TRACE("model_eval", - tout << "orig:\n" << mk_pp(t, m_manager) << "\n"; - tout << "new:\n" << mk_pp(new_t, m_manager) << "\n";); - todo.pop_back(); - SASSERT(new_t.get() != 0); - eval_cache.insert(t, new_t); - break; - } - case AST_VAR: - SASSERT(a != 0); - eval_cache.insert(a, a); - todo.pop_back(); - break; - case AST_QUANTIFIER: - TRACE("model_eval", tout << "found quantifier\n" << mk_pp(a, m_manager) << "\n";); - is_ok = false; // evaluator does not handle quantifiers. - SASSERT(a != 0); - eval_cache.insert(a, a); - todo.pop_back(); - break; - default: - UNREACHABLE(); - break; - } - } - } - - if (!eval_cache.find(e, a)) { - TRACE("model_eval", tout << "FAILED e: " << mk_bounded_pp(e, m_manager) << "\n";); - UNREACHABLE(); - } - - result = a; - std::cout << mk_pp(e, m_manager) << "\n===>\n" << result << "\n"; - TRACE("model_eval", - ast_ll_pp(tout << "original: ", m_manager, e); - ast_ll_pp(tout << "evaluated: ", m_manager, a); - ast_ll_pp(tout << "reduced: ", m_manager, result.get()); - tout << "sort: " << mk_pp(m_manager.get_sort(e), m_manager) << "\n"; - ); - SASSERT(is_well_sorted(m_manager, result.get())); - return is_ok; -} -#endif diff --git a/src/smt/proto_model/proto_model.h b/src/smt/proto_model/proto_model.h index a7ec8d3a9..05af0091c 100644 --- a/src/smt/proto_model/proto_model.h +++ b/src/smt/proto_model/proto_model.h @@ -41,7 +41,6 @@ Revision History: class proto_model : public model_core { plugin_manager m_factories; user_sort_factory * m_user_sort_factory; - family_id m_afid; //!< array family id: hack for displaying models in V1.x style func_decl_set m_aux_decls; ptr_vector m_tmp; model_evaluator m_eval; @@ -58,7 +57,6 @@ class proto_model : public model_core { void remove_aux_decls_not_in_set(ptr_vector & decls, func_decl_set const & s); void cleanup_func_interp(func_interp * fi, func_decl_set & found_aux_fs); - bool is_select_of_model_value(expr* e) const; public: proto_model(ast_manager & m, params_ref const & p = params_ref()); @@ -68,7 +66,6 @@ public: bool eval(expr * e, expr_ref & result, bool model_completion = false); - bool is_as_array(expr * v) const; value_factory * get_factory(family_id fid); diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index 13651a63c..f72485d0e 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -17,16 +17,15 @@ Revision History: --*/ -#include "smt/smt_model_checker.h" -#include "smt/smt_context.h" -#include "smt/smt_model_finder.h" #include "ast/normal_forms/pull_quant.h" #include "ast/for_each_expr.h" #include "ast/rewriter/var_subst.h" #include "ast/ast_pp.h" -#include "ast/ast_ll_pp.h" -#include "model/model_pp.h" #include "ast/ast_smt2_pp.h" +#include "smt/smt_model_checker.h" +#include "smt/smt_context.h" +#include "smt/smt_model_finder.h" +#include "model/model_pp.h" namespace smt { @@ -65,11 +64,9 @@ namespace smt { expr * model_checker::get_term_from_ctx(expr * val) { if (m_value2expr.empty()) { // populate m_value2expr - obj_map::iterator it = m_root2value->begin(); - obj_map::iterator end = m_root2value->end(); - for (; it != end; ++it) { - enode * n = (*it).m_key; - expr * val = (*it).m_value; + for (auto const& kv : *m_root2value) { + enode * n = kv.m_key; + expr * val = kv.m_value; n = n->get_eq_enode_with_min_gen(); m_value2expr.insert(val, n->get_owner()); } @@ -198,9 +195,8 @@ namespace smt { void model_checker::add_instance(quantifier* q, expr_ref_vector const& bindings, unsigned max_generation) { SASSERT(q->get_num_decls() == bindings.size()); - - for (unsigned i = 0; i < bindings.size(); i++) - m_pinned_exprs.push_back(bindings[i]); + for (expr* b : bindings) + m_pinned_exprs.push_back(b); m_pinned_exprs.push_back(q); void * mem = m_new_instances_region.allocate(instance::get_obj_size(q->get_num_decls())); @@ -234,10 +230,8 @@ namespace smt { bool model_checker::add_blocking_clause(model * cex, expr_ref_vector & sks) { SASSERT(cex != 0); - unsigned num_sks = sks.size(); expr_ref_buffer diseqs(m); - for (unsigned i = 0; i < num_sks; i++) { - expr * sk = sks.get(i); + for (expr * sk : sks) { func_decl * sk_d = to_app(sk)->get_decl(); expr_ref sk_value(m); sk_value = cex->get_const_interp(sk_d); @@ -269,8 +263,7 @@ namespace smt { assert_neg_q_m(flat_q, sks); TRACE("model_checker", tout << "skolems:\n"; - for (unsigned i = 0; i < sks.size(); i++) { - expr * sk = sks.get(i); + for (expr* sk : sks) { tout << mk_ismt2_pp(sk, m) << " " << mk_pp(m.get_sort(sk), m) << "\n"; }); @@ -483,10 +476,7 @@ namespace smt { TRACE("model_checker_bug_detail", tout << "assert_new_instances, inconsistent: " << m_context->inconsistent() << "\n";); ptr_buffer bindings; ptr_vector dummy; - ptr_vector::iterator it = m_new_instances.begin(); - ptr_vector::iterator end = m_new_instances.end(); - for (; it != end; ++it) { - instance * inst = *it; + for (instance* inst : m_new_instances) { quantifier * q = inst->m_q; if (m_context->b_internalized(q)) { bindings.reset(); diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 68d56ea84..73d1e9f22 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#include "smt/smt_model_finder.h" -#include "smt/smt_context.h" +#include "util/cooperate.h" +#include "util/backtrackable_set.h" #include "ast/ast_util.h" #include "ast/macros/macro_util.h" #include "ast/arith_decl_plugin.h" @@ -27,14 +27,14 @@ Revision History: #include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/normal_forms/pull_quant.h" #include "ast/rewriter/var_subst.h" -#include "util/backtrackable_set.h" #include "ast/for_each_expr.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" #include "ast/well_sorted.h" -#include "model/model_pp.h" #include "ast/ast_smt2_pp.h" -#include "util/cooperate.h" +#include "model/model_pp.h" +#include "smt/smt_model_finder.h" +#include "smt/smt_context.h" #include "tactic/tactic_exception.h" namespace smt { @@ -56,11 +56,9 @@ namespace smt { v1.swap(v2); return; } - typename ptr_vector::iterator it = v2.begin(); - typename ptr_vector::iterator end = v2.end(); - for (; it != end; ++it) { - if (!v1.contains(*it)) - v1.push_back(*it); + for (T* t : v2) { + if (!v1.contains(t)) + v1.push_back(t); } v2.finalize(); } @@ -88,10 +86,8 @@ namespace smt { instantiation_set(ast_manager & m):m_manager(m) {} ~instantiation_set() { - obj_map::iterator it = m_elems.begin(); - obj_map::iterator end = m_elems.end(); - for (; it != end; ++it) { - m_manager.dec_ref((*it).m_key); + for (auto const& kv : m_elems) { + m_manager.dec_ref(kv.m_key); } m_elems.reset(); } @@ -116,16 +112,12 @@ namespace smt { } void display(std::ostream & out) const { - obj_map::iterator it = m_elems.begin(); - obj_map::iterator end = m_elems.end(); - for (; it != end; ++it) { - out << mk_bounded_pp((*it).m_key, m_manager) << " [" << (*it).m_value << "]\n"; + for (auto const& kv : m_elems) { + out << mk_bounded_pp(kv.m_key, m_manager) << " [" << kv.m_value << "]\n"; } out << "inverse:\n"; - obj_map::iterator it2 = m_inv.begin(); - obj_map::iterator end2 = m_inv.end(); - for (; it2 != end2; ++it2) { - out << mk_bounded_pp((*it2).m_key, m_manager) << " -> " << mk_bounded_pp((*it2).m_value, m_manager) << "\n"; + for (auto const& kv : m_inv) { + out << mk_bounded_pp(kv.m_key, m_manager) << " -> " << mk_bounded_pp(kv.m_value, m_manager) << "\n"; } } @@ -142,12 +134,10 @@ namespace smt { } void mk_inverse(evaluator & ev) { - obj_map::iterator it = m_elems.begin(); - obj_map::iterator end = m_elems.end(); - for (; it != end; ++it) { - expr * t = (*it).m_key; + for (auto const& kv : m_elems) { + expr * t = kv.m_key; SASSERT(!contains_model_value(t)); - unsigned gen = (*it).m_value; + unsigned gen = kv.m_value; expr * t_val = ev.eval(t, true); if (!t_val) break; TRACE("model_finder", tout << mk_pp(t, m_manager) << " " << mk_pp(t_val, m_manager) << "\n";); @@ -329,17 +319,13 @@ namespace smt { out << "root node ------\n"; out << "@" << m_id << " mono: " << m_mono_proj << " signed: " << m_signed_proj << ", sort: " << mk_pp(m_sort, m) << "\n"; out << "avoid-set: "; - ptr_vector::const_iterator it1 = m_avoid_set.begin(); - ptr_vector::const_iterator end1 = m_avoid_set.end(); - for (; it1 != end1; ++it1) { - out << "@" << (*it1)->get_root()->get_id() << " "; + for (node* n : m_avoid_set) { + out << "@" << n->get_root()->get_id() << " "; } out << "\n"; out << "exceptions: "; - ptr_vector::const_iterator it2 = m_exceptions.begin(); - ptr_vector::const_iterator end2 = m_exceptions.end(); - for (; it2 != end2; ++it2) { - out << mk_bounded_pp((*it2), m) << " "; + for (expr * e : m_exceptions) { + out << mk_bounded_pp(e, m) << " "; } out << "\n"; if (m_else) @@ -368,10 +354,8 @@ namespace smt { // return true if m_avoid_set.contains(this) bool must_avoid_itself() const { node * r = get_root(); - ptr_vector::const_iterator it = m_avoid_set.begin(); - ptr_vector::const_iterator end = m_avoid_set.end(); - for (; it != end; ++it) { - if (r == (*it)->get_root()) + for (node* n : m_avoid_set) { + if (r == n->get_root()) return true; } return false; @@ -460,23 +444,19 @@ namespace smt { } void display_key2node(std::ostream & out, key2node const & m) const { - key2node::iterator it = m.begin(); - key2node::iterator end = m.end(); - for (; it != end; ++it) { - ast * a = (*it).m_key.first; - unsigned i = (*it).m_key.second; - node * n = (*it).m_value; + for (auto const& kv : m) { + ast * a = kv.m_key.first; + unsigned i = kv.m_key.second; + node * n = kv.m_value; out << "#" << a->get_id() << ":" << i << " -> @" << n->get_id() << "\n"; } } void display_A_f_is(std::ostream & out) const { - key2node::iterator it = m_A_f_is.begin(); - key2node::iterator end = m_A_f_is.end(); - for (; it != end; ++it) { - func_decl * f = static_cast((*it).m_key.first); - unsigned i = (*it).m_key.second; - node * n = (*it).m_value; + for (auto const& kv : m_A_f_is) { + func_decl * f = static_cast(kv.m_key.first); + unsigned i = kv.m_key.second; + node * n = kv.m_value; out << f->get_name() << ":" << i << " -> @" << n->get_id() << "\n"; } } @@ -556,10 +536,7 @@ namespace smt { } void mk_instantiation_sets() { - ptr_vector::const_iterator it = m_nodes.begin(); - ptr_vector::const_iterator end = m_nodes.end(); - for (; it != end; ++it) { - node * curr = *it; + for (node* curr : m_nodes) { if (curr->is_root()) { curr->mk_instantiation_set(m_manager); } @@ -569,22 +546,19 @@ namespace smt { // For each instantiation_set, reemove entries that do not evaluate to values. void cleanup_instantiation_sets() { ptr_vector to_delete; - ptr_vector::const_iterator it = m_nodes.begin(); - ptr_vector::const_iterator end = m_nodes.end(); - for (; it != end; ++it) { - node * curr = *it; + for (node * curr : m_nodes) { if (curr->is_root()) { instantiation_set * s = curr->get_instantiation_set(); to_delete.reset(); obj_map const & elems = s->get_elems(); - for (obj_map::iterator it = elems.begin(); it != elems.end(); it++) { - expr * n = it->m_key; + for (auto const& kv : elems) { + expr * n = kv.m_key; expr * n_val = eval(n, true); if (!n_val || !m_manager.is_value(n_val)) to_delete.push_back(n); } - for (ptr_vector::iterator it = to_delete.begin(); it != to_delete.end(); it++) { - s->remove(*it); + for (expr* e : to_delete) { + s->remove(e); } } } @@ -592,11 +566,9 @@ namespace smt { void display_nodes(std::ostream & out) const { display_key2node(out, m_uvars); - display_A_f_is(out); - ptr_vector::const_iterator it = m_nodes.begin(); - ptr_vector::const_iterator end = m_nodes.end(); - for (; it != end; ++it) { - (*it)->display(out, m_manager); + display_A_f_is(out); + for (node* n : m_nodes) { + n->display(out, m_manager); } } @@ -662,13 +634,14 @@ namespace smt { unsigned gen = kv.m_value; expr * t_val = eval(t, true); SASSERT(t_val != 0); - ptr_buffer::const_iterator it2 = ex_vals.begin(); - ptr_buffer::const_iterator end2 = ex_vals.end(); - for (; it2 != end2; ++it2) { - if (!m_manager.are_distinct(t_val, *it2)) + bool found = false; + for (expr* v : ex_vals) { + if (!m_manager.are_distinct(t_val, v)) { + found = true; break; + } } - if (it2 == end2 && (t_result == 0 || gen < gen_result)) { + if (!found && (t_result == 0 || gen < gen_result)) { t_result = t; gen_result = gen; } @@ -729,14 +702,11 @@ namespace smt { */ bool assert_k_diseq_exceptions(app * k, ptr_vector const & exceptions) { TRACE("assert_k_diseq_exceptions", tout << "assert_k_diseq_exceptions, " << "k: " << mk_pp(k, m_manager) << "\nexceptions:\n"; - for (unsigned i = 0; i < exceptions.size(); i++) tout << mk_pp(exceptions[i], m_manager) << "\n";); + for (expr * e : exceptions) tout << mk_pp(e, m_manager) << "\n";); expr * k_interp = get_k_interp(k); if (k_interp == 0) return false; - ptr_vector::const_iterator it = exceptions.begin(); - ptr_vector::const_iterator end = exceptions.end(); - for (; it != end; ++it) { - expr * ex = *it; + for (expr * ex : exceptions) { expr * ex_val = eval(ex, true); if (!m_manager.are_distinct(k_interp, ex_val)) { SASSERT(m_new_constraints); @@ -801,10 +771,7 @@ namespace smt { expr_ref one(m_manager); one = ps->mk_one(); ptr_vector const & exceptions = n->get_exceptions(); - ptr_vector::const_iterator it = exceptions.begin(); - ptr_vector::const_iterator end = exceptions.end(); - for (; it != end; ++it) { - expr * e = *it; + for (expr * e : exceptions) { expr_ref e_plus_1(m_manager); expr_ref e_minus_1(m_manager); TRACE("mf_simp_bug", tout << "e:\n" << mk_ismt2_pp(e, m_manager) << "\none:\n" << mk_ismt2_pp(one, m_manager) << "\n";); @@ -820,10 +787,8 @@ namespace smt { instantiation_set const * s = n->get_instantiation_set(); obj_hashtable already_found; obj_map const & elems = s->get_elems(); - obj_map::iterator it = elems.begin(); - obj_map::iterator end = elems.end(); - for (; it != end; ++it) { - expr * t = (*it).m_key; + for (auto const& kv : elems) { + expr * t = kv.m_key; expr * t_val = eval(t, true); if (t_val && !already_found.contains(t_val)) { values.push_back(t_val); @@ -831,10 +796,7 @@ namespace smt { } } TRACE("model_finder_bug", tout << "values for the instantiation_set of @" << n->get_id() << "\n"; - ptr_buffer::const_iterator it = values.begin(); - ptr_buffer::const_iterator end = values.end(); - for (; it != end; ++it) { - expr * v = *it; + for (expr * v : values) { tout << mk_pp(v, m_manager) << "\n"; }); } @@ -936,10 +898,7 @@ namespace smt { } void mk_projections() { - ptr_vector::const_iterator it = m_root_nodes.begin(); - ptr_vector::const_iterator end = m_root_nodes.end(); - for (; it != end; ++it) { - node * n = *it; + for (node * n : m_root_nodes) { SASSERT(n->is_root()); if (n->is_mono_proj()) mk_mono_proj(n); @@ -952,10 +911,8 @@ namespace smt { \brief Store in r the partial functions that have A_f_i nodes. */ void collect_partial_funcs(func_decl_set & r) { - key2node::iterator it = m_A_f_is.begin(); - key2node::iterator end = m_A_f_is.end(); - for (; it != end; ++it) { - func_decl * f = to_func_decl((*it).m_key.first); + for (auto const& kv : m_A_f_is) { + func_decl * f = to_func_decl(kv.m_key.first); if (!r.contains(f)) { func_interp * fi = m_model->get_func_interp(f); if (fi == 0) { @@ -978,10 +935,7 @@ namespace smt { for more details. */ void mk_sorts_finite() { - ptr_vector::const_iterator it = m_root_nodes.begin(); - ptr_vector::const_iterator end = m_root_nodes.end(); - for (; it != end; ++it) { - node * n = *it; + for (node * n : m_root_nodes) { SASSERT(n->is_root()); sort * s = n->get_sort(); if (m_manager.is_uninterp(s) && @@ -993,13 +947,10 @@ namespace smt { } } - void add_elem_to_empty_inst_sets() { - ptr_vector::const_iterator it = m_root_nodes.begin(); - ptr_vector::const_iterator end = m_root_nodes.end(); + void add_elem_to_empty_inst_sets() { obj_map sort2elems; ptr_vector need_fresh; - for (; it != end; ++it) { - node * n = *it; + for (node * n : m_root_nodes) { SASSERT(n->is_root()); instantiation_set const * s = n->get_instantiation_set(); TRACE("model_finder", s->display(tout);); @@ -1042,10 +993,7 @@ namespace smt { */ void collect_root_nodes() { m_root_nodes.reset(); - ptr_vector::const_iterator it = m_nodes.begin(); - ptr_vector::const_iterator end = m_nodes.end(); - for (; it != end; ++it) { - node * n = *it; + for (node * n : m_nodes) { if (n->is_root()) m_root_nodes.push_back(n); } @@ -1080,10 +1028,7 @@ namespace smt { collected in the beginning of fix_model(). */ void complete_partial_funcs(func_decl_set const & partial_funcs) { - func_decl_set::iterator it = partial_funcs.begin(); - func_decl_set::iterator end = partial_funcs.end(); - for (; it != end; ++it) { - func_decl * f = *it; + for (func_decl * f : partial_funcs) { // Complete the current interpretation m_model->complete_partial_func(f); @@ -1124,10 +1069,7 @@ namespace smt { } void mk_inverses() { - ptr_vector::const_iterator it = m_root_nodes.begin(); - ptr_vector::const_iterator end = m_root_nodes.end(); - for (; it != end; ++it) { - node * n = *it; + for (node * n : m_root_nodes) { SASSERT(n->is_root()); mk_inverse(n); } @@ -1355,16 +1297,14 @@ namespace smt { ps = bs; instantiation_set const * from_s = from->get_instantiation_set(); obj_map const & elems_s = from_s->get_elems(); - obj_map::iterator it = elems_s.begin(); - obj_map::iterator end = elems_s.end(); - for (; it != end; ++it) { - expr * n = (*it).m_key; + for (auto const& kv : elems_s) { + expr * n = kv.m_key; expr_ref n_k(m_offset.get_manager()); if (PLUS) ps->mk_add(n, m_offset, n_k); else ps->mk_sub(n, m_offset, n_k); - to->insert(n_k, (*it).m_value); + to->insert(n_k, kv.m_value); } } @@ -1409,10 +1349,7 @@ namespace smt { app * nested_array = to_app(auf_arr->get_arg(0)); ptr_buffer nested_arrays; get_auf_arrays(nested_array, ctx, nested_arrays); - ptr_buffer::const_iterator it = nested_arrays.begin(); - ptr_buffer::const_iterator end = nested_arrays.end(); - for (; it != end; ++it) { - enode * curr = *it; + for (enode * curr : nested_arrays) { enode_vector::iterator it2 = curr->begin_parents(); enode_vector::iterator end2 = curr->end_parents(); for (; it2 != end2; ++it2) { @@ -1428,6 +1365,7 @@ namespace smt { class select_var : public qinfo { protected: ast_manager & m_manager; + array_util m_array; app * m_select; // It must satisfy is_auf_select... see bool is_auf_select(expr * t) const unsigned m_arg_i; unsigned m_var_j; @@ -1436,13 +1374,13 @@ namespace smt { func_decl * get_array_func_decl(app * ground_array, auf_solver & s) { expr * ground_array_interp = s.eval(ground_array, false); - if (ground_array_interp != 0 && s.get_model()->is_as_array(ground_array_interp)) - return to_func_decl(to_app(ground_array_interp)->get_decl()->get_parameter(0).get_ast()); + if (ground_array_interp != 0 && m_array.is_as_array(ground_array_interp)) + return m_array.get_as_array_func_decl(ground_array_interp); return 0; } public: - select_var(ast_manager & m, app * s, unsigned i, unsigned j):m_manager(m), m_select(s), m_arg_i(i), m_var_j(j) {} + select_var(ast_manager & m, app * s, unsigned i, unsigned j):m_manager(m), m_array(m), m_select(s), m_arg_i(i), m_var_j(j) {} virtual ~select_var() {} virtual char const * get_kind() const { @@ -1465,16 +1403,12 @@ namespace smt { get_auf_arrays(get_array(), ctx, arrays); TRACE("select_var", tout << "enodes matching: "; display(tout); tout << "\n"; - ptr_buffer::const_iterator it = arrays.begin(); - ptr_buffer::const_iterator end = arrays.end(); - for (; it != end; ++it) { - tout << "#" << (*it)->get_owner()->get_id() << "\n" << mk_pp((*it)->get_owner(), m_manager) << "\n"; + for (enode* n : arrays) { + tout << "#" << n->get_owner()->get_id() << "\n" << mk_pp(n->get_owner(), m_manager) << "\n"; }); node * n1 = s.get_uvar(q, m_var_j); - ptr_buffer::const_iterator it = arrays.begin(); - ptr_buffer::const_iterator end = arrays.end(); - for (; it != end; ++it) { - app * ground_array = (*it)->get_owner(); + for (enode* n : arrays) { + app * ground_array = n->get_owner(); func_decl * f = get_array_func_decl(ground_array, s); if (f) { SASSERT(m_arg_i >= 1); @@ -1487,10 +1421,7 @@ namespace smt { virtual void populate_inst_sets(quantifier * q, auf_solver & s, context * ctx) { ptr_buffer arrays; get_auf_arrays(get_array(), ctx, arrays); - ptr_buffer::const_iterator it = arrays.begin(); - ptr_buffer::const_iterator end = arrays.end(); - for (; it != end; ++it) { - enode * curr = (*it); + for (enode * curr : arrays) { app * ground_array = curr->get_owner(); func_decl * f = get_array_func_decl(ground_array, s); if (f) { @@ -1773,11 +1704,9 @@ namespace smt { void insert_qinfo(qinfo * qi) { // I'm assuming the number of qinfo's per quantifier is small. So, the linear search is not a big deal. scoped_ptr q(qi); - ptr_vector::iterator it = m_qinfo_vect.begin(); - ptr_vector::iterator end = m_qinfo_vect.end(); - for (; it != end; ++it) { + for (qinfo* qi2 : m_qinfo_vect) { checkpoint(); - if (qi->is_equal(*it)) { + if (qi->is_equal(qi2)) { return; } } @@ -1871,22 +1800,16 @@ namespace smt { out << "IS_AUF: " << m_is_auf << ", has x=y: " << m_has_x_eq_y << "\n"; out << "unary function fragment: " << unary_function_fragment() << "\n"; out << "ng decls: "; - func_decl_set::iterator it1 = m_ng_decls.begin(); - func_decl_set::iterator end1 = m_ng_decls.end(); - for (; it1 != end1; ++it1) { - out << (*it1)->get_name() << " "; + for (func_decl * f : m_ng_decls) { + out << f->get_name() << " "; } out << "\ninfo bits:\n"; - ptr_vector::const_iterator it2 = m_qinfo_vect.begin(); - ptr_vector::const_iterator end2 = m_qinfo_vect.end(); - for (; it2 != end2; ++it2) { - out << " "; (*it2)->display(out); out << "\n"; + for (qinfo* qi : m_qinfo_vect) { + out << " "; qi->display(out); out << "\n"; } out << "\nmacros:\n"; - ptr_vector::const_iterator it3 = m_cond_macros.begin(); - ptr_vector::const_iterator end3 = m_cond_macros.end(); - for (; it3 != end3; ++it3) { - out << " "; (*it3)->display(out); out << "\n"; + for (cond_macro* cm : m_cond_macros) { + out << " "; cm->display(out); out << "\n"; } } @@ -1895,23 +1818,19 @@ namespace smt { // make sure a node exists for each variable. s.get_uvar(m_flat_q, i); } - ptr_vector::const_iterator it = m_qinfo_vect.begin(); - ptr_vector::const_iterator end = m_qinfo_vect.end(); - for (; it != end; ++it) { - (*it)->process_auf(m_flat_q, s, ctx); + for (qinfo * qi : m_qinfo_vect) { + qi->process_auf(m_flat_q, s, ctx); } } void populate_inst_sets(auf_solver & s, context * ctx) { - ptr_vector::const_iterator it = m_qinfo_vect.begin(); - ptr_vector::const_iterator end = m_qinfo_vect.end(); - for (; it != end; ++it) - (*it)->populate_inst_sets(m_flat_q, s, ctx); + for (qinfo * qi : m_qinfo_vect) { + qi->populate_inst_sets(m_flat_q, s, ctx); + } // second pass - it = m_qinfo_vect.begin(); - for (; it != end; ++it) { + for (qinfo * qi : m_qinfo_vect) { checkpoint(); - (*it)->populate_inst_sets2(m_flat_q, s, ctx); + qi->populate_inst_sets2(m_flat_q, s, ctx); } } @@ -1924,14 +1843,9 @@ namespace smt { if (m_uvar_inst_sets != 0) return; m_uvar_inst_sets = alloc(ptr_vector); - ptr_vector::const_iterator it = m_qinfo_vect.begin(); - ptr_vector::const_iterator end = m_qinfo_vect.end(); - for (; it != end; ++it) - (*it)->populate_inst_sets(m_flat_q, m_the_one, *m_uvar_inst_sets, ctx); - ptr_vector::iterator it2 = m_uvar_inst_sets->begin(); - ptr_vector::iterator end2 = m_uvar_inst_sets->end(); - for (; it2 != end2; ++it2) { - instantiation_set * s = *it2; + for (qinfo* qi : m_qinfo_vect) + qi->populate_inst_sets(m_flat_q, m_the_one, *m_uvar_inst_sets, ctx); + for (instantiation_set * s : *m_uvar_inst_sets) { if (s != 0) s->mk_inverse(ev); } @@ -2225,9 +2139,7 @@ namespace smt { expr * a = to_app(t)->get_arg(0); if (!is_ground(a) && !is_auf_select(a)) return false; - unsigned num_args = to_app(t)->get_num_args(); - for (unsigned i = 1; i < num_args; i++) { - expr * arg = to_app(t)->get_arg(i); + for (expr * arg : *to_app(t)) { if (!is_ground(arg) && !is_var(arg)) return false; } @@ -2253,9 +2165,9 @@ namespace smt { } } else { - unsigned num_args = t->get_num_args(); - for (unsigned i = 0; i < num_args; i++) - visit_term(t->get_arg(i)); + for (expr * arg : *t) { + visit_term(arg); + } } } @@ -2572,10 +2484,7 @@ namespace smt { \brief Return true if \c f is in (qs\{q}) */ bool contains(func_decl * f, ptr_vector const & qs, quantifier * q) { - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - quantifier * other = *it; + for (quantifier * other : qs) { if (q == other) continue; quantifier_info * other_qi = get_qinfo(other); @@ -2614,13 +2523,11 @@ namespace smt { virtual bool process(ptr_vector const & qs, ptr_vector & new_qs, ptr_vector & residue) { bool removed = false; - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - if (process(*it, qs)) + for (quantifier* q : qs) { + if (process(q, qs)) removed = true; else - new_qs.push_back(*it); + new_qs.push_back(q); } return removed; } @@ -2769,20 +2676,15 @@ namespace smt { void register_decls_as_forbidden(quantifier * q) { quantifier_info * qi = get_qinfo(q); func_decl_set const & ng_decls = qi->get_ng_decls(); - func_decl_set::iterator it = ng_decls.begin(); - func_decl_set::iterator end = ng_decls.end(); - for (; it != end; ++it) { - m_forbidden.insert(*it); + for (func_decl* f : ng_decls) { + m_forbidden.insert(f); } } void preprocess(ptr_vector const & qs, ptr_vector & qcandidates, ptr_vector & non_qcandidates) { ptr_vector curr(qs); while (true) { - ptr_vector::iterator it = curr.begin(); - ptr_vector::iterator end = curr.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : curr) { if (is_candidate(q)) { qcandidates.push_back(q); } @@ -2800,16 +2702,10 @@ namespace smt { } void mk_q_f_defs(ptr_vector const & qs) { - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : qs) { quantifier_info * qi = get_qinfo(q); func_decl_set const & ng_decls = qi->get_ng_decls(); - func_decl_set::iterator it2 = ng_decls.begin(); - func_decl_set::iterator end2 = ng_decls.end(); - for (; it2 != end2; ++it2) { - func_decl * f = *it2; + for (func_decl* f : ng_decls) { if (!m_forbidden.contains(f)) insert_q_f(q, f); } @@ -2826,40 +2722,30 @@ namespace smt { } static void display_quantifier_set(std::ostream & out, quantifier_set const * s) { - quantifier_set::iterator it = s->begin(); - quantifier_set::iterator end = s->end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier* q : *s) { out << q->get_qid() << " "; } out << "\n"; } void display_qcandidates(std::ostream & out, ptr_vector const & qcandidates) const { - ptr_vector::const_iterator it1 = qcandidates.begin(); - ptr_vector::const_iterator end1 = qcandidates.end(); - for (; it1 != end1; ++it1) { - quantifier * q = *it1; + for (quantifier * q : qcandidates) { out << q->get_qid() << " ->\n" << mk_pp(q, m_manager) << "\n"; quantifier_info * qi = get_qinfo(q); qi->display(out); out << "------\n"; } out << "Sets Q_f\n"; - q_f::iterator it2 = m_q_f.begin(); - q_f::iterator end2 = m_q_f.end(); - for (; it2 != end2; ++it2) { - func_decl * f = (*it2).m_key; - quantifier_set * s = (*it2).m_value; + for (auto const& kv : m_q_f) { + func_decl * f = kv.m_key; + quantifier_set * s = kv.m_value; out << f->get_name() << " -> "; display_quantifier_set(out, s); } out << "Sets Q_{f = def}\n"; - q_f_def::iterator it3 = m_q_f_def.begin(); - q_f_def::iterator end3 = m_q_f_def.end(); - for (; it3 != end3; ++it3) { - func_decl * f = (*it3).get_key1(); - expr * def = (*it3).get_key2(); - quantifier_set * s = (*it3).get_value(); + for (auto const& kv : m_q_f_def) { + func_decl * f = kv.get_key1(); + expr * def = kv.get_key2(); + quantifier_set * s = kv.get_value(); out << f->get_name() << " " << mk_pp(def, m_manager) << " ->\n"; display_quantifier_set(out, s); } } @@ -2894,32 +2780,23 @@ namespace smt { void display_search_state(std::ostream & out) const { out << "fs:\n"; - f2def::iterator it3 = m_fs.begin(); - f2def::iterator end3 = m_fs.end(); - for (; it3 != end3; ++it3) { - out << (*it3).m_key->get_name() << " "; + for (auto const& kv : m_fs) { + out << kv.m_key->get_name() << " "; } out << "\nsatisfied:\n"; - qsset::iterator it = m_satisfied.begin(); - qsset::iterator end = m_satisfied.end(); - for (; it != end; ++it) { - out << (*it)->get_qid() << " "; + for (auto q : m_satisfied) { + out << q->get_qid() << " "; } out << "\nresidue:\n"; - qset::iterator it2 = m_residue.begin(); - qset::iterator end2 = m_residue.end(); - for (; it2 != end2; ++it2) { - out << (*it2)->get_qid() << " "; + for (auto q : m_residue) { + out << q->get_qid() << " "; } out << "\n"; } bool check_satisfied_residue_invariant() { DEBUG_CODE( - qsset::iterator it = m_satisfied.begin(); - qsset::iterator end = m_satisfied.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : m_satisfied) { SASSERT(!m_residue.contains(q)); quantifier_info * qi = get_qinfo(q); SASSERT(qi != 0); @@ -2934,10 +2811,7 @@ namespace smt { SASSERT(check_satisfied_residue_invariant()); quantifier_set * q_f = get_q_f(f); quantifier_set * q_f_def = get_q_f_def(f, def); - quantifier_set::iterator it = q_f_def->begin(); - quantifier_set::iterator end = q_f_def->end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : *q_f_def) { if (!m_satisfied.contains(q)) { useful = true; m_residue.erase(q); @@ -2949,10 +2823,7 @@ namespace smt { } if (!useful) return false; - it = q_f->begin(); - end = q_f->end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : *q_f) { if (!m_satisfied.contains(q)) { m_residue.insert(q); } @@ -2966,10 +2837,7 @@ namespace smt { The candidates must not be elements of m_fs. */ void get_candidates_from_residue(func_decl_set & candidates) { - qset::iterator it = m_residue.begin(); - qset::iterator end = m_residue.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : m_residue) { quantifier_info * qi = get_qinfo(q); quantifier_info::macro_iterator it2 = qi->begin_macros(); @@ -2998,10 +2866,7 @@ namespace smt { display_search_state(tout);); expr_set * s = get_f_defs(f); - expr_set::iterator it = s->begin(); - expr_set::iterator end = s->end(); - for (; it != end; ++it) { - expr * def = *it; + for (expr * def : *s) { SASSERT(!m_fs.contains(f)); @@ -3036,17 +2901,13 @@ namespace smt { get_candidates_from_residue(candidates); TRACE("model_finder_hint", tout << "candidates from residue:\n"; - func_decl_set::iterator it = candidates.begin(); - func_decl_set::iterator end = candidates.end(); - for (; it != end; ++it) { - tout << (*it)->get_name() << " "; + for (func_decl * f : candidates) { + tout << f->get_name() << " "; } tout << "\n";); - func_decl_set::iterator it = candidates.begin(); - func_decl_set::iterator end = candidates.end(); - for (; it != end; ++it) { - greedy(*it, depth); + for (func_decl* f : candidates) { + greedy(f, depth); } } @@ -3066,10 +2927,7 @@ namespace smt { \brief Copy the quantifiers from qcandidates to new_qs that are not in m_satisfied. */ void copy_non_satisfied(ptr_vector const & qcandidates, ptr_vector & new_qs) { - ptr_vector::const_iterator it = qcandidates.begin(); - ptr_vector::const_iterator end = qcandidates.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : qcandidates) { if (!m_satisfied.contains(q)) new_qs.push_back(q); } @@ -3080,11 +2938,9 @@ namespace smt { quantifiers in m_satisfied. */ void set_interp() { - f2def::iterator it = m_fs.begin(); - f2def::iterator end = m_fs.end(); - for (; it != end; ++it) { - func_decl * f = (*it).m_key; - expr * def = (*it).m_value; + for (auto const& kv : m_fs) { + func_decl * f = kv.m_key; + expr * def = kv.m_value; set_else_interp(f, def); } } @@ -3108,10 +2964,7 @@ namespace smt { } mk_q_f_defs(qcandidates); TRACE("model_finder_hint", tout << "starting hint-solver search using:\n"; display_qcandidates(tout, qcandidates);); - func_decl_set::iterator it = m_candidates.begin(); - func_decl_set::iterator end = m_candidates.end(); - for (; it != end; ++it) { - func_decl * f = *it; + for (func_decl * f : m_candidates) { try { process(f); } @@ -3190,10 +3043,7 @@ namespace smt { typedef std::pair mq_pair; void collect_candidates(ptr_vector const & qs, obj_map & full_macros, func_decl_set & cond_macros) { - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : qs) { quantifier_info * qi = get_qinfo(q); quantifier_info::macro_iterator it2 = qi->begin_macros(); quantifier_info::macro_iterator end2 = qi->end_macros(); @@ -3216,12 +3066,10 @@ namespace smt { } void process_full_macros(obj_map const & full_macros, obj_hashtable & removed) { - obj_map::iterator it = full_macros.begin(); - obj_map::iterator end = full_macros.end(); - for (; it != end; ++it) { - func_decl * f = (*it).m_key; - cond_macro * m = (*it).m_value.first; - quantifier * q = (*it).m_value.second; + for (auto const& kv : full_macros) { + func_decl * f = kv.m_key; + cond_macro * m = kv.m_value.first; + quantifier * q = kv.m_value.second; SASSERT(m->is_unconditional()); if (add_macro(f, m->get_def())) { get_qinfo(q)->set_the_one(f); @@ -3233,10 +3081,7 @@ namespace smt { void process(func_decl * f, ptr_vector const & qs, obj_hashtable & removed) { expr_ref fi_else(m_manager); ptr_buffer to_remove; - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : qs) { if (removed.contains(q)) continue; cond_macro * m = get_macro_for(f, q); @@ -3254,20 +3099,16 @@ namespace smt { } } if (fi_else.get() != 0 && add_macro(f, fi_else)) { - ptr_buffer::iterator it2 = to_remove.begin(); - ptr_buffer::iterator end2 = to_remove.end(); - for (; it2 != end2; ++it2) { - get_qinfo(*it2)->set_the_one(f); - removed.insert(*it2); + for (quantifier * q : to_remove) { + get_qinfo(q)->set_the_one(f); + removed.insert(q); } } } void process_cond_macros(func_decl_set const & cond_macros, ptr_vector const & qs, obj_hashtable & removed) { - func_decl_set::iterator it = cond_macros.begin(); - func_decl_set::iterator end = cond_macros.end(); - for (; it != end; ++it) { - process(*it, qs, removed); + for (func_decl * f : cond_macros) { + process(f, qs, removed); } } @@ -3282,10 +3123,7 @@ namespace smt { process_full_macros(full_macros, removed); process_cond_macros(cond_macros, qs, removed); - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : qs) { if (removed.contains(q)) continue; new_qs.push_back(q); @@ -3404,10 +3242,7 @@ namespace smt { } void model_finder::collect_relevant_quantifiers(ptr_vector & qs) const { - ptr_vector::const_iterator it = m_quantifiers.begin(); - ptr_vector::const_iterator end = m_quantifiers.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : m_quantifiers) { if (m_context->is_relevant(q) && m_context->get_assignment(q) == l_true) qs.push_back(q); } @@ -3417,26 +3252,19 @@ namespace smt { m_auf_solver->reset(); m_auf_solver->set_model(m); - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : qs) { quantifier_info * qi = get_quantifier_info(q); qi->process_auf(*(m_auf_solver.get()), m_context); } m_auf_solver->mk_instantiation_sets(); - it = qs.begin(); - for (; it != end; ++it) { - quantifier * q = *it; + + for (quantifier * q : qs) { quantifier_info * qi = get_quantifier_info(q); qi->populate_inst_sets(*(m_auf_solver.get()), m_context); } m_auf_solver->fix_model(m_new_constraints); TRACE("model_finder", - ptr_vector::const_iterator it = qs.begin(); - ptr_vector::const_iterator end = qs.end(); - for (; it != end; ++it) { - quantifier * q = *it; + for (quantifier * q : qs) { quantifier_info * qi = get_quantifier_info(q); quantifier * fq = qi->get_flat_q(); tout << "#" << fq->get_id() << " ->\n" << mk_pp(fq, m_manager) << "\n"; From e47cd27c8d544178d13379d19c81927d582a6eb5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 20 Aug 2017 16:18:25 -0700 Subject: [PATCH 154/488] compiler warnings Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/spacer_generalizers.cpp | 2 +- src/muz/spacer/spacer_qe_project.cpp | 2 +- src/smt/mam.cpp | 3 +-- src/smt/theory_fpa.cpp | 5 +++-- src/smt/theory_str.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/muz/spacer/spacer_generalizers.cpp b/src/muz/spacer/spacer_generalizers.cpp index f16fb10e1..94c419493 100644 --- a/src/muz/spacer/spacer_generalizers.cpp +++ b/src/muz/spacer/spacer_generalizers.cpp @@ -133,7 +133,7 @@ void unsat_core_generalizer::operator()(lemma_ref &lemma) unsigned uses_level; expr_ref_vector core(m); - VERIFY(pt.is_invariant(lemma->level(), lemma->get_expr(), uses_level, &core)); + VERIFY(pt.is_invariant(old_level, lemma->get_expr(), uses_level, &core)); CTRACE("spacer", old_sz > core.size(), tout << "unsat core reduced lemma from: " diff --git a/src/muz/spacer/spacer_qe_project.cpp b/src/muz/spacer/spacer_qe_project.cpp index c06854cb0..0eec500e9 100644 --- a/src/muz/spacer/spacer_qe_project.cpp +++ b/src/muz/spacer/spacer_qe_project.cpp @@ -98,7 +98,7 @@ peq::peq (app* p, ast_manager& m): m_eq (m), m_arr_u (m) { - SASSERT (is_partial_eq (p)); + VERIFY (is_partial_eq (p)); SASSERT (m_arr_u.is_array (m_lhs) && m_arr_u.is_array (m_rhs) && m_eq_proc (m.get_sort (m_lhs), m.get_sort (m_rhs))); diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index 73ede7319..2aa9d6095 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -2080,16 +2080,15 @@ namespace smt { */ enode_vector * interpreter::mk_depth1_vector(enode * n, func_decl * f, unsigned i) { enode_vector * v = mk_enode_vector(); - unsigned num_args = n->get_num_args(); n = n->get_root(); enode_vector::const_iterator it = n->begin_parents(); enode_vector::const_iterator end = n->end_parents(); for (; it != end; ++it) { enode * p = *it; if (p->get_decl() == f && + i < p->get_num_args() && m_context.is_relevant(p) && p->is_cgr() && - i < p->get_num_args() && p->get_arg(i)->get_root() == n) { v->push_back(p); } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 17349ead6..e8edfc7ec 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -237,8 +237,9 @@ namespace smt { if (m_fpa_util.is_fp(e)) { expr * cargs[3] = { to_app(e)->get_arg(0), to_app(e)->get_arg(1), to_app(e)->get_arg(2) }; - res = m_bv_util.mk_concat(3, cargs); - m_th_rw((expr_ref&)res); + expr_ref tmp(m_bv_util.mk_concat(3, cargs), m); + m_th_rw(tmp); + res = to_app(tmp); } else { sort * es = m.get_sort(e); diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 0d963f8b9..88b044a90 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -8567,7 +8567,7 @@ namespace smt { } else { TRACE("str", tout << "integer theory has no assignment for " << mk_pp(a, m) << std::endl;); expr_ref is_zero(ctx.mk_eq_atom(a, m_autil.mk_int(0)), m); - literal is_zero_l = mk_literal(is_zero); + /* literal is_zero_l = */ mk_literal(is_zero); axiomAdd = true; TRACE("str", ctx.display(tout);); // NOT_IMPLEMENTED_YET(); From ed5058d225f63a1f78e796d976c424f7ceee931a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 21 Aug 2017 18:21:31 +0100 Subject: [PATCH 155/488] Fixed typo in ML API. Relates to #1214. --- src/api/ml/z3.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 0207a53ed..4f10b275a 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1912,7 +1912,7 @@ sig (* union of regular expressions *) val mk_re_union : context -> Expr.expr list -> Expr.expr - (* concatenation of regular expressions* ) + (* concatenation of regular expressions *) val mk_re_concat : context -> Expr.expr list -> Expr.expr (* regular expression for the range between two characters *) From ebe9db14d58ac3fc3f15009f56becbe69b36e56e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 21 Aug 2017 14:13:43 -0700 Subject: [PATCH 156/488] fix regression exposed by segfault2.smt2 crash Signed-off-by: Nikolaj Bjorner --- src/model/model_core.cpp | 6 +++--- src/smt/proto_model/proto_model.cpp | 6 +++--- src/smt/theory_seq.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 684d1b3c2..2f6137172 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -90,18 +90,18 @@ void model_core::register_decl(func_decl * d, func_interp * fi) { void model_core::unregister_decl(func_decl * d) { decl2expr::obj_map_entry * ec = m_interp.find_core(d); if (ec && ec->get_data().m_value != 0) { - m_manager.dec_ref(ec->get_data().m_key); - m_manager.dec_ref(ec->get_data().m_value); m_interp.remove(d); m_const_decls.erase(d); + m_manager.dec_ref(ec->get_data().m_key); + m_manager.dec_ref(ec->get_data().m_value); return; } decl2finterp::obj_map_entry * ef = m_finterp.find_core(d); if (ef && ef->get_data().m_value != 0) { - m_manager.dec_ref(ef->get_data().m_key); dealloc(ef->get_data().m_value); m_finterp.remove(d); m_func_decls.erase(d); + m_manager.dec_ref(ef->get_data().m_key); } } diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index 9a5f2a1ca..9b218037e 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -10,7 +10,7 @@ Abstract: Author: - + Leonardo de Moura (leonardo) 2007-03-08. Revision History: @@ -359,8 +359,8 @@ void proto_model::complete_partial_funcs() { // m_func_decls may be "expanded" when we invoke get_some_value. // So, we must not use iterators to traverse it. - for (func_decl* f : m_func_decls) { - complete_partial_func(f); + for (unsigned i = 0; i < m_func_decls.size(); i++) { + complete_partial_func(m_func_decls[i]); } } diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index d988da54f..c91882dad 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -427,7 +427,7 @@ bool theory_seq::branch_unit_variable() { break; } } - CTRACE("seq", result, "branch unit variable";); + CTRACE("seq", result, tout << "branch unit variable";); return result; } @@ -3552,7 +3552,7 @@ bool theory_seq::get_length(expr* e, rational& val) const { } } } - CTRACE("seq", !val.is_int(), "length is not an integer\n";); + CTRACE("seq", !val.is_int(), tout << "length is not an integer\n";); return val.is_int(); } From e6145fa6df997eae552848914b9ff6f485e18fc7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 21 Aug 2017 14:53:16 -0700 Subject: [PATCH 157/488] fix crash Signed-off-by: Nikolaj Bjorner --- src/model/model_core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 2f6137172..3d9de1ba1 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -99,9 +99,9 @@ void model_core::unregister_decl(func_decl * d) { decl2finterp::obj_map_entry * ef = m_finterp.find_core(d); if (ef && ef->get_data().m_value != 0) { + m_manager.dec_ref(ef->get_data().m_key); dealloc(ef->get_data().m_value); m_finterp.remove(d); m_func_decls.erase(d); - m_manager.dec_ref(ef->get_data().m_key); } } From 2c8e9aeb9cc6ffa334e6e262c7c56d9941d3fb90 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 21 Aug 2017 15:23:52 -0700 Subject: [PATCH 158/488] another crash fix Signed-off-by: Nikolaj Bjorner --- src/model/model_core.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 3d9de1ba1..5eb1eb00d 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -90,10 +90,10 @@ void model_core::register_decl(func_decl * d, func_interp * fi) { void model_core::unregister_decl(func_decl * d) { decl2expr::obj_map_entry * ec = m_interp.find_core(d); if (ec && ec->get_data().m_value != 0) { + m_manager.dec_ref(ec->get_data().m_key); + m_manager.dec_ref(ec->get_data().m_value); m_interp.remove(d); m_const_decls.erase(d); - m_manager.dec_ref(ec->get_data().m_key); - m_manager.dec_ref(ec->get_data().m_value); return; } From cb87d47f08281f3e2cefac07d4e4ea80e97e21e9 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Tue, 22 Aug 2017 17:03:20 +0000 Subject: [PATCH 159/488] obj_hashtable: Constify --- src/util/obj_hashtable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/obj_hashtable.h b/src/util/obj_hashtable.h index 9c3473e3d..189d1e1a0 100644 --- a/src/util/obj_hashtable.h +++ b/src/util/obj_hashtable.h @@ -134,7 +134,7 @@ public: return m_table.end(); } - void insert(Key * k, Value const & v) { + void insert(Key * const k, Value const & v) { m_table.insert(key_data(k, v)); } @@ -150,7 +150,7 @@ public: return m_table.find_core(key_data(k)); } - bool find(Key * k, Value & v) const { + bool find(Key * const k, Value & v) const { obj_map_entry * e = find_core(k); if (e) { v = e->get_data().m_value; From 4cb7f72509b6a590b1f706f0f7be09e76ac6e1a5 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Thu, 17 Aug 2017 16:43:25 +0000 Subject: [PATCH 160/488] First version of the inj. tactic --- scripts/mk_project.py | 10 +- src/tactic/core/injectivity_tactic.cpp | 305 +++++++++++++++++++++++++ src/tactic/core/injectivity_tactic.h | 32 +++ 3 files changed, 342 insertions(+), 5 deletions(-) create mode 100644 src/tactic/core/injectivity_tactic.cpp create mode 100644 src/tactic/core/injectivity_tactic.h diff --git a/scripts/mk_project.py b/scripts/mk_project.py index b40205445..64dd93faa 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -23,6 +23,10 @@ def init_project_def(): add_lib('subpaving', ['interval'], 'math/subpaving') add_lib('ast', ['util', 'polynomial']) add_lib('rewriter', ['ast', 'polynomial', 'automata'], 'ast/rewriter') + # Simplifier module will be deleted in the future. + # It has been replaced with rewriter module. + add_lib('simplifier', ['rewriter'], 'ast/simplifier') + add_lib('macros', ['simplifier'], 'ast/macros') add_lib('normal_forms', ['rewriter'], 'ast/normal_forms') add_lib('model', ['rewriter']) add_lib('tactic', ['ast', 'model']) @@ -30,7 +34,7 @@ def init_project_def(): add_lib('parser_util', ['ast'], 'parsers/util') add_lib('grobner', ['ast'], 'math/grobner') add_lib('euclid', ['util'], 'math/euclid') - add_lib('core_tactics', ['tactic', 'normal_forms'], 'tactic/core') + add_lib('core_tactics', ['tactic', 'macros', 'normal_forms', 'rewriter'], 'tactic/core') add_lib('sat_tactic', ['tactic', 'sat'], 'sat/tactic') add_lib('arith_tactics', ['core_tactics', 'sat'], 'tactic/arith') add_lib('nlsat_tactic', ['nlsat', 'sat_tactic', 'arith_tactics'], 'nlsat/tactic') @@ -43,11 +47,7 @@ def init_project_def(): add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds') add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') add_lib('proof_checker', ['rewriter'], 'ast/proof_checker') - # Simplifier module will be deleted in the future. - # It has been replaced with rewriter module. - add_lib('simplifier', ['rewriter'], 'ast/simplifier') add_lib('fpa', ['ast', 'util', 'simplifier', 'model'], 'ast/fpa') - add_lib('macros', ['simplifier'], 'ast/macros') add_lib('pattern', ['normal_forms', 'smt2parser', 'simplifier'], 'ast/pattern') add_lib('bit_blaster', ['rewriter', 'simplifier'], 'ast/rewriter/bit_blaster') add_lib('smt_params', ['ast', 'simplifier', 'pattern', 'bit_blaster'], 'smt/params') diff --git a/src/tactic/core/injectivity_tactic.cpp b/src/tactic/core/injectivity_tactic.cpp new file mode 100644 index 000000000..d8b5e6acf --- /dev/null +++ b/src/tactic/core/injectivity_tactic.cpp @@ -0,0 +1,305 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + injectivity_tactic.cpp + +Abstract: + + Injectivity tactics + - Discover axioms of the form `forall x. (= (g (f x)) x` + Mark `f` as injective + - Rewrite (sub)terms of the form `(= (f x) (f y))` to `(= x y)` whenever `f` is injective. + +Author: + + Nicolas Braud-Santoni (t-nibrau) 2017-08-10 + +Notes: + +--*/ +#include +#include +#include "tactic/tactical.h" +#include "ast/rewriter/rewriter_def.h" +#include "tactic/core/injectivity_tactic.h" +#include "util/dec_ref_util.h" + + +class injectivity_tactic : public tactic { + + struct InjHelper : public obj_map*> { + ast_manager & m_manager; + + void insert(func_decl* const f, func_decl* const g) { + obj_hashtable *m; + if (! obj_map::find(f, m)) { + m_manager.inc_ref(f); + m = alloc(obj_hashtable); // TODO: Check we don't leak memory + obj_map::insert(f, m); + } + if (!m->contains(g)) { + m_manager.inc_ref(g); + m->insert(g); + } + } + + bool find(func_decl* const f, func_decl* const g) const { + obj_hashtable *m; + if(! obj_map::find(f, m)) + return false; + + return m->contains(g); + } + + InjHelper(ast_manager& m) : obj_map*>(), m_manager(m) {} + ~InjHelper() { + for(auto m : *this) { + for (func_decl* f : *m.get_value()) + m_manager.dec_ref(f); + + m_manager.dec_ref(m.m_key); + dealloc(m.m_value); + } + } + + }; + + struct finder { + ast_manager & m_manager; + InjHelper & inj_map; + + finder(ast_manager & m, InjHelper & map, params_ref const & p) : + m_manager(m), + inj_map(map) { + updt_params(p); + } + + ast_manager & m() const { return m_manager; } + + bool is_axiom(expr* n, func_decl* &f, func_decl* &g) { + if (!is_quantifier(n)) + return false; + + quantifier* const q = to_quantifier(n); + if (!q->is_forall() || q->get_num_decls() != 1) + return false; + + const expr * const body = q->get_expr(); + + // n ~= forall x. body + + if (!m().is_eq(body)) + return false; + + const app * const body_a = to_app(body); + if (body_a->get_num_args() != 2) + return false; + + const expr* a = body_a->get_arg(0); + const expr* b = body_a->get_arg(1); + + // n ~= forall x. (= a b) + + if (is_app(a) && is_var(b)) { + // Do nothing + } + else if (is_app(b) && is_var(a)) { + std::swap(a, b); + } + else + return false; + + const app* const a_app = to_app(a); + const var* const b_var = to_var(b); + + if (b_var->get_idx() != 0) // idx is the De Bruijn's index + return false; + + if (a_app->get_num_args() != 1) + return false; + + g = a_app->get_decl(); + const expr* const a_body = a_app->get_arg(0); + + // n ~= forall x. (= (g a_body) x) + + if (!is_app(a_body)) + return false; + const app* const a_body_app = to_app(a_body); + if (a_body_app->get_num_args() != 1) // Maybe TODO: support multi-argument functions + return false; + + f = a_body_app->get_decl(); + const expr* const a_body_body = a_body_app->get_arg(0); + + // n ~= forall x. (= (g (f a_body_body)) x) + if (a_body_body != b_var) + return false; + + // n ~= forall x. (= (g (f x)) x) + + return true; + } + + void operator()(goal_ref const & goal, + goal_ref_buffer & result, + model_converter_ref & mc, + proof_converter_ref & pc, + expr_dependency_ref & core) { + SASSERT(goal->is_well_sorted()); + mc = 0; pc = 0; core = 0; + tactic_report report("injectivity", *goal); + fail_if_unsat_core_generation("injectivity", goal); // TODO: Support UNSAT cores + fail_if_proof_generation("injectivity", goal); + + for (unsigned i = 0; i < goal->size(); ++i) { + func_decl *f, *g; + if (!is_axiom(goal->form(i), f, g)) continue; + TRACE("injectivity_finder", tout << "Marking " << f->get_name() << " as injective" << std::endl;); + inj_map.insert(f, g); + // TODO: Record that g is f's pseudoinverse + } + } + + void updt_params(params_ref const & p) {} + }; + + struct rewriter_eq_cfg : public default_rewriter_cfg { + ast_manager & m_manager; + InjHelper & inj_map; +// expr_ref_vector m_out; +// sort_ref_vector m_bindings; + + ast_manager & m() const { return m_manager; } + + rewriter_eq_cfg(ast_manager & m, InjHelper & map, params_ref const & p) : m_manager(m), inj_map(map) { + } + + ~rewriter_eq_cfg() { + } + + void cleanup_buffers() { +// m_out.finalize(); + } + + void reset() { + } + + br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { + if(num != 2) + return BR_FAILED; + + if (!m().is_eq(f)) + return BR_FAILED; + + // We are rewriting (= a b) + if (!is_app(args[0]) || !is_app(args[1])) + return BR_FAILED; + + const app* const a = to_app(args[0]); + const app* const b = to_app(args[1]); + + // a and b are applications of the same function + if (a->get_decl() != b->get_decl()) + return BR_FAILED; + + // Maybe TODO: Generalize to multi-parameter functions ? + if (a->get_num_args() != 1 || b->get_num_args() != 1) + return BR_FAILED; + + if (!inj_map.contains(a->get_decl())) + return BR_FAILED; + + SASSERT(m().get_sort(a->get_arg(0)) == m().get_sort(b->get_arg(0))); + TRACE("injectivity_eq", tout << "Rewriting (= " << mk_ismt2_pp(args[0], m()) << + " " << mk_ismt2_pp(args[1], m()) << ")" << std::endl;); + result = m().mk_eq(a->get_arg(0), b->get_arg(0)); + result_pr = nullptr; + return BR_DONE; + } + + }; + + struct rewriter_eq : public rewriter_tpl { + rewriter_eq_cfg m_cfg; + rewriter_eq(ast_manager & m, InjHelper & map, params_ref const & p) : + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m, map, p) { + } + }; + + struct rewriter_inverse { }; + + finder * m_finder; + rewriter_eq * m_eq; + InjHelper * m_map; +// rewriter_inverse * m_inverse; + + params_ref m_params; + ast_manager & m_manager; + +public: + injectivity_tactic(ast_manager & m, params_ref const & p): + m_params(p), + m_manager(m) { + TRACE("injectivity", tout << "constructed new tactic" << std::endl;); + m_map = alloc(InjHelper, m); + m_finder = alloc(finder, m, *m_map, p); + m_eq = alloc(rewriter_eq, m, *m_map, p); + } + + virtual tactic * translate(ast_manager & m) { + return alloc(injectivity_tactic, m, m_params); + } + + virtual ~injectivity_tactic() { + dealloc(m_finder); + dealloc(m_eq); + dealloc(m_map); + } + + virtual void updt_params(params_ref const & p) { + m_params = p; + m_finder->updt_params(p); + } + + virtual void collect_param_descrs(param_descrs & r) { + insert_max_memory(r); + insert_produce_models(r); + r.insert("elim_and", CPK_BOOL, "(default: false) eliminate conjunctions during (internal) calls to the simplifier."); + } + + virtual void operator()(goal_ref const & g, + goal_ref_buffer & result, + model_converter_ref & mc, + proof_converter_ref & pc, + expr_dependency_ref & core) { + std::cerr << "injectivity finder: " << m_finder << std::endl; + (*m_finder)(g, result, mc, pc, core); + + for (unsigned i = 0; i < g->size(); ++i) { + std::cerr << "injectivity rewrite " << i << std::endl; + expr* curr = g->form(i); + expr_ref rw(m_manager); + proof_ref pr(m_manager); + (*m_eq)(curr, rw, pr); + g->update(i, rw, pr, g->dep(i)); + } + } + + virtual void cleanup() { + InjHelper * m = alloc(InjHelper, m_manager); + finder * f = alloc(finder, m_manager, *m, m_params); + rewriter_eq * r = alloc(rewriter_eq, m_manager, *m, m_params); + std::swap(m, m_map), std::swap(f, m_finder), std::swap(r, m_eq); + dealloc(m), dealloc(f), dealloc(r); + } + + +}; + +tactic * mk_injectivity_tactic(ast_manager & m, params_ref const & p) { + return alloc(injectivity_tactic, m, p); +} diff --git a/src/tactic/core/injectivity_tactic.h b/src/tactic/core/injectivity_tactic.h new file mode 100644 index 000000000..447357912 --- /dev/null +++ b/src/tactic/core/injectivity_tactic.h @@ -0,0 +1,32 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + injectivity_tactic.h + +Abstract: + + Injectivity tactics + +Author: + + Nicolas Braud-Santoni (t-nibrau) 2017-08-10 + +Notes: + +--*/ +#ifndef INJECTIVITY_TACTIC_H_ +#define INJECTIVITY_TACTIC_H_ + +#include "util/params.h" +class ast_manager; +class tactic; + +tactic * mk_injectivity_tactic(ast_manager & m, params_ref const & p = params_ref()); + +/* + ADD_TACTIC("injectivity", "Identifies and applies injectivity axioms.", "mk_injectivity_tactic(m, p)") +*/ + +#endif From 392334f779c089deef73bec472d6eb5bca399219 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 22 Aug 2017 10:44:00 -0700 Subject: [PATCH 161/488] add ability to create and manipulate model objects Signed-off-by: Nikolaj Bjorner --- examples/c++/example.cpp | 2 +- src/api/api_model.cpp | 54 ++++++++++++++++++++++++++++++++++++++++ src/api/c++/z3++.h | 16 ++++++++++++ src/api/z3_api.h | 30 ++++++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/examples/c++/example.cpp b/examples/c++/example.cpp index 2d7d051c5..035d032bc 100644 --- a/examples/c++/example.cpp +++ b/examples/c++/example.cpp @@ -470,7 +470,7 @@ void unsat_core_example2() { // The solver s already contains p1 => F // To disable F, we add (not p1) as an additional assumption qs.push_back(!p1); - std::cout << s.check(qs.size(), &qs[0]) << "\n"; + std::cout << s.check((unsigned)qs.size(), &qs[0]) << "\n"; expr_vector core2 = s.unsat_core(); std::cout << core2 << "\n"; std::cout << "size: " << core2.size() << "\n"; diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index de917650d..1646c691f 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -30,6 +30,17 @@ Revision History: extern "C" { + Z3_model Z3_API Z3_mk_model(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_model(c); + RESET_ERROR_CODE(); + Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c)); + m_ref->m_model = alloc(model, mk_c(c)->m()); + mk_c(c)->save_object(m_ref); + RETURN_Z3(of_model(m_ref)); + Z3_CATCH_RETURN(0); + } + void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m) { Z3_TRY; LOG_Z3_model_inc_ref(c, m); @@ -224,6 +235,31 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast else_val) { + Z3_TRY; + LOG_Z3_add_func_interp(c, m, f, else_val); + RESET_ERROR_CODE(); + func_decl* d = to_func_decl(f); + model* mdl = to_model_ref(m); + Z3_func_interp_ref * f_ref = alloc(Z3_func_interp_ref, *mk_c(c), mdl); + f_ref->m_func_interp = alloc(func_interp, mk_c(c)->m(), d->get_arity()); + mk_c(c)->save_object(f_ref); + mdl->register_decl(d, f_ref->m_func_interp); + f_ref->m_func_interp->set_else(to_expr(else_val)); + RETURN_Z3(of_func_interp(f_ref)); + Z3_CATCH_RETURN(0); + } + + void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a) { + Z3_TRY; + LOG_Z3_add_const_interp(c, m, f, a); + RESET_ERROR_CODE(); + func_decl* d = to_func_decl(f); + model* mdl = to_model_ref(m); + mdl->register_decl(d, to_expr(a)); + Z3_CATCH; + } + void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f) { Z3_TRY; LOG_Z3_func_interp_inc_ref(c, f); @@ -292,6 +328,24 @@ extern "C" { Z3_CATCH_RETURN(0); } + void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value) { + Z3_TRY; + LOG_Z3_add_func_entry(c, fi, args, value); + //CHECK_NON_NULL(fi, void); + //CHECK_NON_NULL(args, void); + //CHECK_NON_NULL(value, void); + func_interp* _fi = to_func_interp_ref(fi); + expr* _value = to_expr(value); + if (to_ast_vector_ref(args).size() != _fi->get_arity()) { + SET_ERROR_CODE(Z3_IOB); + return; + } + // check sorts of value + expr* const* _args = (expr* const*) to_ast_vector_ref(args).c_ptr(); + _fi->insert_entry(_args, _value); + Z3_CATCH; + } + void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e) { Z3_TRY; LOG_Z3_func_entry_inc_ref(c, e); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 42db6f352..cf1a5070a 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1731,6 +1731,10 @@ namespace z3 { expr else_value() const { Z3_ast r = Z3_func_interp_get_else(ctx(), m_interp); check_error(); return expr(ctx(), r); } unsigned num_entries() const { unsigned r = Z3_func_interp_get_num_entries(ctx(), m_interp); check_error(); return r; } func_entry entry(unsigned i) const { Z3_func_entry e = Z3_func_interp_get_entry(ctx(), m_interp, i); check_error(); return func_entry(ctx(), e); } + void add_entry(expr_vector const& args, expr& value) { + Z3_add_func_entry(ctx(), m_interp, args, value); + check_error(); + } }; class model : public object { @@ -1740,6 +1744,7 @@ namespace z3 { Z3_model_inc_ref(ctx(), m); } public: + model(context & c):object(c) { init(Z3_mk_model(c)); } model(context & c, Z3_model m):object(c) { init(m); } model(model const & s):object(s) { init(s.m_model); } ~model() { Z3_model_dec_ref(ctx(), m_model); } @@ -1795,6 +1800,17 @@ namespace z3 { return 0 != Z3_model_has_interp(ctx(), m_model, f); } + func_interp add_func_interp(func_decl& f, expr& else_val) { + Z3_func_interp r = Z3_add_func_interp(ctx(), m_model, f, else_val); + check_error(); + return func_interp(ctx(), r); + } + + void add_const_interp(func_decl& f, expr& value) { + Z3_add_const_interp(ctx(), m_model, f, value); + check_error(); + } + friend std::ostream & operator<<(std::ostream & out, model const & m); }; inline std::ostream & operator<<(std::ostream & out, model const & m) { out << Z3_model_to_string(m.ctx(), m); return out; } diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 8d53c9255..46c8fbb30 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4680,6 +4680,14 @@ extern "C" { /** @name Models */ /*@{*/ + + /** + \brief Create a fresh model object. It has reference count 0. + + def_API('Z3_mk_model', MODEL, (_in(CONTEXT),)) + */ + Z3_model Z3_API Z3_mk_model(Z3_context c); + /** \brief Increment the reference counter of the given model. @@ -4850,6 +4858,21 @@ extern "C" { */ Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a); + /** + \brief Create a fresh func_interp object, add it to a model for a specified function. + It has reference count 0. + + def_API('Z3_add_func_interp', FUNC_INTERP, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _in(AST))) + */ + Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast else_val); + + /** + \brief Add a constant interpretation. + + def_API('Z3_add_const_interp', VOID, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _in(AST))) + */ + void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a); + /** \brief Increment the reference counter of the given Z3_func_interp object. @@ -4904,6 +4927,13 @@ extern "C" { */ unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f); + /** + \brief add a function entry to a function interpretation. + + def_API('Z3_add_func_entry', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST_VECTOR), _in(AST))) + */ + void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value); + /** \brief Increment the reference counter of the given Z3_func_entry object. From c0b6d00e8aa9a19d2cca474aaad9d0fd37af408e Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Tue, 22 Aug 2017 18:09:38 +0000 Subject: [PATCH 162/488] Update debug output --- src/tactic/core/injectivity_tactic.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tactic/core/injectivity_tactic.cpp b/src/tactic/core/injectivity_tactic.cpp index d8b5e6acf..75685c891 100644 --- a/src/tactic/core/injectivity_tactic.cpp +++ b/src/tactic/core/injectivity_tactic.cpp @@ -157,7 +157,7 @@ class injectivity_tactic : public tactic { for (unsigned i = 0; i < goal->size(); ++i) { func_decl *f, *g; if (!is_axiom(goal->form(i), f, g)) continue; - TRACE("injectivity_finder", tout << "Marking " << f->get_name() << " as injective" << std::endl;); + TRACE("injectivity", tout << "Marking " << f->get_name() << " as injective" << std::endl;); inj_map.insert(f, g); // TODO: Record that g is f's pseudoinverse } @@ -213,7 +213,7 @@ class injectivity_tactic : public tactic { return BR_FAILED; SASSERT(m().get_sort(a->get_arg(0)) == m().get_sort(b->get_arg(0))); - TRACE("injectivity_eq", tout << "Rewriting (= " << mk_ismt2_pp(args[0], m()) << + TRACE("injectivity", tout << "Rewriting (= " << mk_ismt2_pp(args[0], m()) << " " << mk_ismt2_pp(args[1], m()) << ")" << std::endl;); result = m().mk_eq(a->get_arg(0), b->get_arg(0)); result_pr = nullptr; @@ -276,11 +276,9 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - std::cerr << "injectivity finder: " << m_finder << std::endl; (*m_finder)(g, result, mc, pc, core); for (unsigned i = 0; i < g->size(); ++i) { - std::cerr << "injectivity rewrite " << i << std::endl; expr* curr = g->form(i); expr_ref rw(m_manager); proof_ref pr(m_manager); From 33dd168195cf561786163adce7e471f82f011aeb Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Tue, 22 Aug 2017 18:09:57 +0000 Subject: [PATCH 163/488] Remove unnecessary parameter --- src/tactic/core/injectivity_tactic.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tactic/core/injectivity_tactic.cpp b/src/tactic/core/injectivity_tactic.cpp index 75685c891..4dc3fe5d5 100644 --- a/src/tactic/core/injectivity_tactic.cpp +++ b/src/tactic/core/injectivity_tactic.cpp @@ -268,7 +268,6 @@ public: virtual void collect_param_descrs(param_descrs & r) { insert_max_memory(r); insert_produce_models(r); - r.insert("elim_and", CPK_BOOL, "(default: false) eliminate conjunctions during (internal) calls to the simplifier."); } virtual void operator()(goal_ref const & g, From a206362cef8a6dce748f73a14f3aaec8ec14456c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 22 Aug 2017 11:41:25 -0700 Subject: [PATCH 164/488] add comments addressing some questions #1223 Signed-off-by: Nikolaj Bjorner --- src/api/z3_api.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 46c8fbb30..bea40f30a 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4862,9 +4862,14 @@ extern "C" { \brief Create a fresh func_interp object, add it to a model for a specified function. It has reference count 0. + \param c context + \param m model + \param f function declaration + \param default_value default value for function interpretation + def_API('Z3_add_func_interp', FUNC_INTERP, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _in(AST))) */ - Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast else_val); + Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast default_value); /** \brief Add a constant interpretation. @@ -4930,6 +4935,15 @@ extern "C" { /** \brief add a function entry to a function interpretation. + \param c logical context + \param fi a function interpregation to be updated. + \param args list of arguments. They should be constant values (such as integers) and be of the same types as the domain of the function. + \param value value of the function when the parameters match args. + + It is assumed that entries added to a function cover disjoint arguments. + If an two entries are added with the same arguments, only the second insertion survives and the + first inserted entry is removed. + def_API('Z3_add_func_entry', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST_VECTOR), _in(AST))) */ void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value); From 27fd879b8ceb5aee860ae1c7ffa3e1afe2727159 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Tue, 22 Aug 2017 18:44:34 +0000 Subject: [PATCH 165/488] injectivity: Fixup rewriter --- src/tactic/core/injectivity_tactic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tactic/core/injectivity_tactic.cpp b/src/tactic/core/injectivity_tactic.cpp index 4dc3fe5d5..95e380982 100644 --- a/src/tactic/core/injectivity_tactic.cpp +++ b/src/tactic/core/injectivity_tactic.cpp @@ -284,7 +284,8 @@ public: (*m_eq)(curr, rw, pr); g->update(i, rw, pr, g->dep(i)); } - } + result.push_back(g.get()); + } virtual void cleanup() { InjHelper * m = alloc(InjHelper, m_manager); From e2b46257d699b6165c400d8707c1cd4d6d94d95f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 22 Aug 2017 15:09:34 -0700 Subject: [PATCH 166/488] reducing dependencies on simplifier Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.h | 18 +- src/ast/bv_decl_plugin.cpp | 10 +- src/ast/bv_decl_plugin.h | 7 +- src/ast/macros/macro_finder.cpp | 20 +- src/ast/macros/macro_finder.h | 3 +- src/ast/macros/macro_manager.cpp | 2 +- src/ast/macros/macro_util.cpp | 85 +++++--- src/ast/macros/macro_util.h | 21 +- src/ast/macros/quasi_macros.cpp | 10 +- src/ast/macros/quasi_macros.h | 7 +- src/ast/rewriter/arith_rewriter.h | 2 +- src/ast/rewriter/poly_rewriter.h | 4 +- src/ast/rewriter/poly_rewriter_def.h | 60 ++++++ src/smt/asserted_formulas.cpp | 2 +- src/smt/smt_model_finder.cpp | 246 ++++++++++++------------ src/smt/smt_model_finder.h | 3 +- src/smt/smt_quantifier.cpp | 2 +- src/tactic/ufbv/quasi_macros_tactic.cpp | 2 +- 18 files changed, 289 insertions(+), 215 deletions(-) diff --git a/src/ast/arith_decl_plugin.h b/src/ast/arith_decl_plugin.h index a66ddd967..6c2b1c77a 100644 --- a/src/ast/arith_decl_plugin.h +++ b/src/ast/arith_decl_plugin.h @@ -389,16 +389,16 @@ public: app * mk_lt(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_LT, arg1, arg2); } app * mk_gt(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_GT, arg1, arg2); } - app * mk_add(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_ADD, num_args, args); } - app * mk_add(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2); } - app * mk_add(expr * arg1, expr * arg2, expr* arg3) { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2, arg3); } + app * mk_add(unsigned num_args, expr * const * args) const { return m_manager.mk_app(m_afid, OP_ADD, num_args, args); } + app * mk_add(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2); } + app * mk_add(expr * arg1, expr * arg2, expr* arg3) const { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2, arg3); } - app * mk_sub(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_SUB, arg1, arg2); } - app * mk_sub(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_SUB, num_args, args); } - app * mk_mul(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2); } - app * mk_mul(expr * arg1, expr * arg2, expr* arg3) { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2, arg3); } - app * mk_mul(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_MUL, num_args, args); } - app * mk_uminus(expr * arg) { return m_manager.mk_app(m_afid, OP_UMINUS, arg); } + app * mk_sub(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_SUB, arg1, arg2); } + app * mk_sub(unsigned num_args, expr * const * args) const { return m_manager.mk_app(m_afid, OP_SUB, num_args, args); } + app * mk_mul(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2); } + app * mk_mul(expr * arg1, expr * arg2, expr* arg3) const { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2, arg3); } + app * mk_mul(unsigned num_args, expr * const * args) const { return m_manager.mk_app(m_afid, OP_MUL, num_args, args); } + app * mk_uminus(expr * arg) const { return m_manager.mk_app(m_afid, OP_UMINUS, arg); } app * mk_div(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_DIV, arg1, arg2); } app * mk_idiv(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_IDIV, arg1, arg2); } app * mk_rem(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_REM, arg1, arg2); } diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index 4632b6604..b5c79f662 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -784,6 +784,12 @@ bool bv_recognizers::is_numeral(expr const * n, rational & val, unsigned & bv_si return true; } +bool bv_recognizers::is_numeral(expr const * n, rational & val) const { + unsigned bv_size = 0; + return is_numeral(n, val, bv_size); +} + + bool bv_recognizers::is_allone(expr const * e) const { rational r; unsigned bv_size; @@ -847,7 +853,7 @@ bv_util::bv_util(ast_manager & m): m_plugin = static_cast(m.get_plugin(m.mk_family_id("bv"))); } -app * bv_util::mk_numeral(rational const & val, sort* s) { +app * bv_util::mk_numeral(rational const & val, sort* s) const { if (!is_bv_sort(s)) { return 0; } @@ -855,7 +861,7 @@ app * bv_util::mk_numeral(rational const & val, sort* s) { return mk_numeral(val, bv_size); } -app * bv_util::mk_numeral(rational const & val, unsigned bv_size) { +app * bv_util::mk_numeral(rational const & val, unsigned bv_size) const { parameter p1(val); parameter p[2] = { p1, parameter(static_cast(bv_size)) }; return m_manager.mk_app(get_fid(), OP_BV_NUM, 2, p, 0, 0); diff --git a/src/ast/bv_decl_plugin.h b/src/ast/bv_decl_plugin.h index 5e533cd98..a4ea7af80 100644 --- a/src/ast/bv_decl_plugin.h +++ b/src/ast/bv_decl_plugin.h @@ -293,6 +293,7 @@ public: family_id get_fid() const { return m_afid; } family_id get_family_id() const { return get_fid(); } + bool is_numeral(expr const * n, rational & val) const; bool is_numeral(expr const * n, rational & val, unsigned & bv_size) const; bool is_numeral(expr const * n) const { return is_app_of(n, get_fid(), OP_BV_NUM); } bool is_allone(expr const * e) const; @@ -381,9 +382,9 @@ public: ast_manager & get_manager() const { return m_manager; } - app * mk_numeral(rational const & val, sort* s); - app * mk_numeral(rational const & val, unsigned bv_size); - app * mk_numeral(uint64 u, unsigned bv_size) { return mk_numeral(rational(u, rational::ui64()), bv_size); } + app * mk_numeral(rational const & val, sort* s) const; + app * mk_numeral(rational const & val, unsigned bv_size) const; + app * mk_numeral(uint64 u, unsigned bv_size) const { return mk_numeral(rational(u, rational::ui64()), bv_size); } sort * mk_sort(unsigned bv_size); unsigned get_bv_size(sort const * s) const { diff --git a/src/ast/macros/macro_finder.cpp b/src/ast/macros/macro_finder.cpp index 285c0e5fb..1d441aee7 100644 --- a/src/ast/macros/macro_finder.cpp +++ b/src/ast/macros/macro_finder.cpp @@ -48,14 +48,12 @@ bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) { bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) return false; - arith_simplifier_plugin * as = get_arith_simp(); - arith_util & autil = as->get_arith_util(); expr * body = to_quantifier(n)->get_expr(); unsigned num_decls = to_quantifier(n)->get_num_decls(); - if (!autil.is_le(body) && !autil.is_ge(body) && !m_manager.is_eq(body)) + if (!m_autil.is_le(body) && !m_autil.is_ge(body) && !m_manager.is_eq(body)) return false; - if (!as->is_add(to_app(body)->get_arg(0))) + if (!m_autil.is_add(to_app(body)->get_arg(0))) return false; app_ref head(m_manager); expr_ref def(m_manager); @@ -66,10 +64,10 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex if (!inv || m_manager.is_eq(body)) new_body = m_manager.mk_app(to_app(body)->get_decl(), head, def); - else if (as->is_le(body)) - new_body = autil.mk_ge(head, def); + else if (m_autil.is_le(body)) + new_body = m_autil.mk_ge(head, def); else - new_body = autil.mk_le(head, def); + new_body = m_autil.mk_le(head, def); quantifier_ref new_q(m_manager); new_q = m_manager.update_quantifier(to_quantifier(n), new_body); @@ -88,10 +86,9 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex func_decl * k = m_manager.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); app * k_app = m_manager.mk_app(k, head->get_num_args(), head->get_args()); expr_ref_buffer new_rhs_args(m_manager); - expr_ref new_rhs2(m_manager); - as->mk_add(def, k_app, new_rhs2); + expr_ref new_rhs2(m_autil.mk_add(def, k_app), m_manager); expr * body1 = m_manager.mk_eq(head, new_rhs2); - expr * body2 = m_manager.mk_app(new_body->get_decl(), k_app, as->mk_numeral(rational(0))); + expr * body2 = m_manager.mk_app(new_body->get_decl(), k_app, m_autil.mk_int(0)); quantifier * q1 = m_manager.update_quantifier(new_q, body1); expr * patterns[1] = { m_manager.mk_pattern(k_app) }; quantifier * q2 = m_manager.update_quantifier(new_q, 1, patterns, body2); @@ -158,7 +155,8 @@ static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, e macro_finder::macro_finder(ast_manager & m, macro_manager & mm): m_manager(m), m_macro_manager(mm), - m_util(mm.get_util()) { + m_util(mm.get_util()), + m_autil(m) { } macro_finder::~macro_finder() { diff --git a/src/ast/macros/macro_finder.h b/src/ast/macros/macro_finder.h index 7f1b27f0e..5807573ae 100644 --- a/src/ast/macros/macro_finder.h +++ b/src/ast/macros/macro_finder.h @@ -20,7 +20,6 @@ Revision History: #define MACRO_FINDER_H_ #include "ast/macros/macro_manager.h" -#include "ast/simplifier/arith_simplifier_plugin.h" bool is_macro_head(expr * n, unsigned num_decls); @@ -37,7 +36,7 @@ class macro_finder { ast_manager & m_manager; macro_manager & m_macro_manager; macro_util & m_util; - arith_simplifier_plugin * get_arith_simp() { return m_util.get_arith_simp(); } + arith_util m_autil; bool expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); bool is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index bd330a2de..f26a87445 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -28,7 +28,7 @@ Revision History: macro_manager::macro_manager(ast_manager & m, simplifier & s): m_manager(m), m_simplifier(s), - m_util(m, s), + m_util(m), m_decls(m), m_macros(m), m_macro_prs(m), diff --git a/src/ast/macros/macro_util.cpp b/src/ast/macros/macro_util.cpp index 35f2fbcfb..b7eb9657f 100644 --- a/src/ast/macros/macro_util.cpp +++ b/src/ast/macros/macro_util.cpp @@ -29,16 +29,17 @@ Revision History: #include "ast/well_sorted.h" #include "ast/rewriter/bool_rewriter.h" -macro_util::macro_util(ast_manager & m, simplifier & s): +macro_util::macro_util(ast_manager & m): m_manager(m), m_bv(m), - m_simplifier(s), - m_arith_simp(0), - m_bv_simp(0), + m_arith(m), + m_arith_rw(m), + m_bv_rw(m), m_forbidden_set(0), m_curr_clause(0) { } +#if 0 arith_simplifier_plugin * macro_util::get_arith_simp() const { if (m_arith_simp == 0) { const_cast(this)->m_arith_simp = static_cast(m_simplifier.get_plugin(m_manager.mk_family_id("arith"))); @@ -54,7 +55,7 @@ bv_simplifier_plugin * macro_util::get_bv_simp() const { SASSERT(m_bv_simp != 0); return m_bv_simp; } - +#endif bool macro_util::is_bv(expr * n) const { return m_bv.is_bv(n); @@ -65,32 +66,41 @@ bool macro_util::is_bv_sort(sort * s) const { } bool macro_util::is_add(expr * n) const { - return get_arith_simp()->is_add(n) || m_bv.is_bv_add(n); + return m_arith.is_add(n) || m_bv.is_bv_add(n); } bool macro_util::is_times_minus_one(expr * n, expr * & arg) const { - return get_arith_simp()->is_times_minus_one(n, arg) || get_bv_simp()->is_times_minus_one(n, arg); + return m_arith_rw.is_times_minus_one(n, arg) || m_bv_rw.is_times_minus_one(n, arg); } bool macro_util::is_le(expr * n) const { - return get_arith_simp()->is_le(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); + return m_arith.is_le(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); } bool macro_util::is_le_ge(expr * n) const { - return get_arith_simp()->is_le_ge(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); + return m_arith.is_ge(n) || m_arith.is_le(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); } -poly_simplifier_plugin * macro_util::get_poly_simp_for(sort * s) const { - if (is_bv_sort(s)) - return get_bv_simp(); - else - return get_arith_simp(); +bool macro_util::is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) { + return m_arith_rw.is_var_plus_ground(n, inv, v, t) || m_bv_rw.is_var_plus_ground(n, inv, v, t); +} + +bool macro_util::is_zero_safe(expr * n) const { + if (m_bv_rw.is_bv(n)) { + return m_bv.is_zero(n); + } + else { + return m_arith_rw.is_zero(n); + } } app * macro_util::mk_zero(sort * s) const { - poly_simplifier_plugin * ps = get_poly_simp_for(s); - ps->set_curr_sort(s); - return ps->mk_zero(); + if (m_bv.is_bv_sort(s)) { + return m_bv.mk_numeral(rational(0), s); + } + else { + return m_arith.mk_numeral(rational(0), s); + } } void macro_util::mk_sub(expr * t1, expr * t2, expr_ref & r) const { @@ -98,7 +108,7 @@ void macro_util::mk_sub(expr * t1, expr * t2, expr_ref & r) const { r = m_bv.mk_bv_sub(t1, t2); } else { - get_arith_simp()->mk_sub(t1, t2, r); + r = m_arith.mk_sub(t1, t2); } } @@ -107,18 +117,32 @@ void macro_util::mk_add(expr * t1, expr * t2, expr_ref & r) const { r = m_bv.mk_bv_add(t1, t2); } else { - get_arith_simp()->mk_add(t1, t2, r); + r = m_arith.mk_add(t1, t2); } } void macro_util::mk_add(unsigned num_args, expr * const * args, sort * s, expr_ref & r) const { - if (num_args == 0) { + switch (num_args) { + case 0: r = mk_zero(s); - return; + break; + case 1: + r = args[0]; + break; + default: + if (m_bv.is_bv_sort(s)) { + r = args[0]; + while (num_args >= 2) { + --num_args; + ++args; + r = m_bv.mk_bv_add(r, args[0]); + } + } + else { + r = m_arith.mk_add(num_args, args); + } + break; } - poly_simplifier_plugin * ps = get_poly_simp_for(s); - ps->set_curr_sort(s); - ps->mk_add(num_args, args, r); } /** @@ -241,13 +265,12 @@ bool macro_util::poly_contains_head(expr * n, func_decl * f, expr * exception) c bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def, bool & inv) const { // TODO: obsolete... we should move to collect_arith_macro_candidates - arith_simplifier_plugin * as = get_arith_simp(); - if (!m_manager.is_eq(n) && !as->is_le(n) && !as->is_ge(n)) + if (!m_manager.is_eq(n) && !m_arith.is_le(n) && !m_arith.is_ge(n)) return false; expr * lhs = to_app(n)->get_arg(0); expr * rhs = to_app(n)->get_arg(1); - if (!as->is_numeral(rhs)) + if (!m_arith.is_numeral(rhs)) return false; inv = false; @@ -272,7 +295,7 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex !poly_contains_head(lhs, to_app(arg)->get_decl(), arg)) { h = arg; } - else if (h == 0 && as->is_times_minus_one(arg, neg_arg) && + else if (h == 0 && m_arith_rw.is_times_minus_one(arg, neg_arg) && is_macro_head(neg_arg, num_decls) && !is_forbidden(to_app(neg_arg)->get_decl()) && !poly_contains_head(lhs, to_app(neg_arg)->get_decl(), arg)) { @@ -287,11 +310,11 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex return false; head = to_app(h); expr_ref tmp(m_manager); - as->mk_add(args.size(), args.c_ptr(), tmp); + tmp = m_arith.mk_add(args.size(), args.c_ptr()); if (inv) - as->mk_sub(tmp, rhs, def); + def = m_arith.mk_sub(tmp, rhs); else - as->mk_sub(rhs, tmp, def); + def = m_arith.mk_sub(rhs, tmp); return true; } diff --git a/src/ast/macros/macro_util.h b/src/ast/macros/macro_util.h index d76f2f0d3..91d96cc5e 100644 --- a/src/ast/macros/macro_util.h +++ b/src/ast/macros/macro_util.h @@ -22,12 +22,8 @@ Revision History: #include "ast/ast.h" #include "util/obj_hashtable.h" -#include "ast/simplifier/simplifier.h" - -class poly_simplifier_plugin; -class arith_simplifier_plugin; -class bv_simplifier_plugin; -class basic_simplifier_plugin; +#include "ast/rewriter/arith_rewriter.h" +#include "ast/rewriter/bv_rewriter.h" class macro_util { public: @@ -63,9 +59,9 @@ public: private: ast_manager & m_manager; bv_util m_bv; - simplifier & m_simplifier; - arith_simplifier_plugin * m_arith_simp; - bv_simplifier_plugin * m_bv_simp; + arith_util m_arith; + arith_rewriter m_arith_rw; + bv_rewriter m_bv_rw; obj_hashtable * m_forbidden_set; bool is_forbidden(func_decl * f) const { return m_forbidden_set != 0 && m_forbidden_set->contains(f); } @@ -94,11 +90,9 @@ private: public: - macro_util(ast_manager & m, simplifier & s); + macro_util(ast_manager & m); void set_forbidden_set(obj_hashtable * s) { m_forbidden_set = s; } - arith_simplifier_plugin * get_arith_simp() const; - bv_simplifier_plugin * get_bv_simp() const; bool is_macro_head(expr * n, unsigned num_decls) const; bool is_left_simple_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const; @@ -113,6 +107,8 @@ public: return is_arith_macro(n, num_decls, head, def, inv); } + bool is_zero_safe(expr * n) const; + bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t); bool is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, app_ref & t); bool is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def); @@ -137,7 +133,6 @@ public: void mk_sub(expr * t1, expr * t2, expr_ref & r) const; void mk_add(expr * t1, expr * t2, expr_ref & r) const; void mk_add(unsigned num_args, expr * const * args, sort * s, expr_ref & r) const; - poly_simplifier_plugin * get_poly_simp_for(sort * s) const; }; #endif diff --git a/src/ast/macros/quasi_macros.cpp b/src/ast/macros/quasi_macros.cpp index b39adde03..822532532 100644 --- a/src/ast/macros/quasi_macros.cpp +++ b/src/ast/macros/quasi_macros.cpp @@ -22,10 +22,10 @@ Revision History: #include "util/uint_set.h" #include "ast/rewriter/var_subst.h" -quasi_macros::quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s) : - m_manager(m), +quasi_macros::quasi_macros(ast_manager & m, macro_manager & mm) : + m_manager(m), m_macro_manager(mm), - m_simplifier(s), + m_rewriter(m), m_new_vars(m), m_new_eqs(m), m_new_qsorts(m) { @@ -299,8 +299,8 @@ void quasi_macros::apply_macros(unsigned n, expr * const * exprs, proof * const proof_ref pr(m_manager), ps(m_manager); proof * p = m_manager.proofs_enabled() ? prs[i] : 0; m_macro_manager.expand_macros(exprs[i], p, r, pr); - m_simplifier(r, rs, ps); - new_exprs.push_back(rs); + m_rewriter(r); + new_exprs.push_back(r); new_prs.push_back(ps); } } diff --git a/src/ast/macros/quasi_macros.h b/src/ast/macros/quasi_macros.h index 3a9b6074e..29efe63c7 100644 --- a/src/ast/macros/quasi_macros.h +++ b/src/ast/macros/quasi_macros.h @@ -21,8 +21,7 @@ Revision History: #include #include "ast/macros/macro_manager.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/simplifier.h" +#include "ast/rewriter/th_rewriter.h" /** \brief Finds quasi macros and applies them. @@ -32,7 +31,7 @@ class quasi_macros { ast_manager & m_manager; macro_manager & m_macro_manager; - simplifier & m_simplifier; + th_rewriter m_rewriter; occurrences_map m_occurrences; ptr_vector m_todo; @@ -57,7 +56,7 @@ class quasi_macros { void apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); public: - quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s); + quasi_macros(ast_manager & m, macro_manager & mm); ~quasi_macros(); /** diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index de849dbd7..5d9fb1d66 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -35,7 +35,6 @@ protected: bool is_numeral(expr * n) const { return m_util.is_numeral(n); } bool is_numeral(expr * n, numeral & r) const { return m_util.is_numeral(n, r); } - bool is_zero(expr * n) const { return m_util.is_zero(n); } bool is_minus_one(expr * n) const { return m_util.is_minus_one(n); } void normalize(numeral & c, sort * s) {} app * mk_numeral(numeral const & r, sort * s) { return m_util.mk_numeral(r, s); } @@ -45,6 +44,7 @@ protected: decl_kind power_decl_kind() const { return OP_POWER; } public: arith_rewriter_core(ast_manager & m):m_util(m) {} + bool is_zero(expr * n) const { return m_util.is_zero(n); } }; class arith_rewriter : public poly_rewriter { diff --git a/src/ast/rewriter/poly_rewriter.h b/src/ast/rewriter/poly_rewriter.h index 5d38e4b10..5269f25a8 100644 --- a/src/ast/rewriter/poly_rewriter.h +++ b/src/ast/rewriter/poly_rewriter.h @@ -39,7 +39,6 @@ protected: bool is_numeral(expr * n) const { return Config::is_numeral(n); } bool is_numeral(expr * n, numeral & r) const { return Config::is_numeral(n, r); } - bool is_zero(expr * n) const { return Config::is_zero(n); } bool is_minus_one(expr * n) const { return Config::is_minus_one(n); } void normalize(numeral & c) { Config::normalize(c, m_curr_sort); } app * mk_numeral(numeral const & r) { return Config::mk_numeral(r, m_curr_sort); } @@ -111,6 +110,9 @@ public: bool is_mul(expr * n) const { return is_app_of(n, get_fid(), mul_decl_kind()); } bool is_add(func_decl * f) const { return is_decl_of(f, get_fid(), add_decl_kind()); } bool is_mul(func_decl * f) const { return is_decl_of(f, get_fid(), mul_decl_kind()); } + bool is_times_minus_one(expr * n, expr*& r) const; + bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t); + br_status mk_mul_core(unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(num_args > 0); diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 5e2e39722..a8d115d64 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -931,3 +931,63 @@ expr* poly_rewriter::merge_muls(expr* x, expr* y) { m1[k] = mk_add_app(2, args); return mk_mul_app(k+1, m1.c_ptr()); } + +template +bool poly_rewriter::is_times_minus_one(expr * n, expr* & r) const { + if (is_mul(n) && to_app(n)->get_num_args() == 2 && is_minus_one(to_app(n)->get_arg(0))) { + r = to_app(n)->get_arg(1); + return true; + } + return false; +} + +/** + \brief Return true if n is can be put into the form (+ v t) or (+ (- v) t) + \c inv = true will contain true if (- v) is found, and false otherwise. +*/ +template +bool poly_rewriter::is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) { + if (!is_add(n) || is_ground(n)) + return false; + + ptr_buffer args; + v = 0; + expr * curr = to_app(n); + bool stop = false; + inv = false; + while (!stop) { + expr * arg; + expr * neg_arg; + if (is_add(curr)) { + arg = to_app(curr)->get_arg(0); + curr = to_app(curr)->get_arg(1); + } + else { + arg = curr; + stop = true; + } + if (is_ground(arg)) { + TRACE("model_checker_bug", tout << "pushing:\n" << mk_pp(arg, m()) << "\n";); + args.push_back(arg); + } + else if (is_var(arg)) { + if (v != 0) + return false; // already found variable + v = to_var(arg); + } + else if (is_times_minus_one(arg, neg_arg) && is_var(neg_arg)) { + if (v != 0) + return false; // already found variable + v = to_var(neg_arg); + inv = true; + } + else { + return false; // non ground term. + } + } + if (v == 0) + return false; // did not find variable + SASSERT(!args.empty()); + mk_add(args.size(), args.c_ptr(), t); + return true; +} diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index cbbb9a6bc..2f55cd704 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -410,7 +410,7 @@ void asserted_formulas::apply_quasi_macros() { TRACE("before_quasi_macros", display(tout);); expr_ref_vector new_exprs(m); proof_ref_vector new_prs(m); - quasi_macros proc(m, m_macro_manager, m_simplifier); + quasi_macros proc(m, m_macro_manager); while (proc(m_asserted_formulas.size() - m_asserted_qhead, m_asserted_formulas.c_ptr() + m_asserted_qhead, m_asserted_formula_prs.c_ptr() + m_asserted_qhead, diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 73d1e9f22..2e6a34557 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -23,8 +23,6 @@ Revision History: #include "ast/arith_decl_plugin.h" #include "ast/bv_decl_plugin.h" #include "ast/array_decl_plugin.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/normal_forms/pull_quant.h" #include "ast/rewriter/var_subst.h" #include "ast/for_each_expr.h" @@ -392,9 +390,9 @@ namespace smt { The idea is to create node objects based on the information produced by the quantifier_analyzer. */ class auf_solver : public evaluator { - ast_manager & m_manager; - arith_simplifier_plugin * m_asimp; - bv_simplifier_plugin * m_bvsimp; + ast_manager & m; + arith_util m_arith; + bv_util m_bv; ptr_vector m_nodes; unsigned m_next_node_id; key2node m_uvars; @@ -466,16 +464,16 @@ namespace smt { } public: - auf_solver(ast_manager & m, simplifier & s): - m_manager(m), + auf_solver(ast_manager & m): + m(m), + m_arith(m), + m_bv(m), m_next_node_id(0), m_context(0), m_ks(m), m_model(0), m_eval_cache_range(m), m_new_constraints(0) { - m_asimp = static_cast(s.get_plugin(m.mk_family_id("arith"))); - m_bvsimp = static_cast(s.get_plugin(m.mk_family_id("bv"))); } virtual ~auf_solver() { @@ -488,12 +486,8 @@ namespace smt { m_context = ctx; } - ast_manager & get_manager() const { return m_manager; } - - arith_simplifier_plugin * get_arith_simp() const { return m_asimp; } - - bv_simplifier_plugin * get_bv_simp() const { return m_bvsimp; } - + ast_manager & get_manager() const { return m; } + void reset() { flush_nodes(); m_nodes.reset(); @@ -538,7 +532,7 @@ namespace smt { void mk_instantiation_sets() { for (node* curr : m_nodes) { if (curr->is_root()) { - curr->mk_instantiation_set(m_manager); + curr->mk_instantiation_set(m); } } } @@ -554,7 +548,7 @@ namespace smt { for (auto const& kv : elems) { expr * n = kv.m_key; expr * n_val = eval(n, true); - if (!n_val || !m_manager.is_value(n_val)) + if (!n_val || !m.is_value(n_val)) to_delete.push_back(n); } for (expr* e : to_delete) { @@ -568,7 +562,7 @@ namespace smt { display_key2node(out, m_uvars); display_A_f_is(out); for (node* n : m_nodes) { - n->display(out, m_manager); + n->display(out, m); } } @@ -577,14 +571,14 @@ namespace smt { if (m_eval_cache[model_completion].find(n, r)) { return r; } - expr_ref tmp(m_manager); + expr_ref tmp(m); if (!m_model->eval(n, tmp, model_completion)) { r = 0; - TRACE("model_finder", tout << "eval\n" << mk_pp(n, m_manager) << "\n-----> null\n";); + TRACE("model_finder", tout << "eval\n" << mk_pp(n, m) << "\n-----> null\n";); } else { r = tmp; - TRACE("model_finder", tout << "eval\n" << mk_pp(n, m_manager) << "\n----->\n" << mk_pp(r, m_manager) << "\n";); + TRACE("model_finder", tout << "eval\n" << mk_pp(n, m) << "\n----->\n" << mk_pp(r, m) << "\n";); } m_eval_cache[model_completion].insert(n, r); m_eval_cache_range.push_back(r); @@ -636,7 +630,7 @@ namespace smt { SASSERT(t_val != 0); bool found = false; for (expr* v : ex_vals) { - if (!m_manager.are_distinct(t_val, v)) { + if (!m.are_distinct(t_val, v)) { found = true; break; } @@ -652,7 +646,7 @@ namespace smt { bool is_infinite(sort * s) const { // we should not assume that uninterpreted sorts are infinite in benchmarks with quantifiers. return - !m_manager.is_uninterp(s) && + !m.is_uninterp(s) && s->is_infinite(); } @@ -665,7 +659,7 @@ namespace smt { app * r = 0; if (m_sort2k.find(s, r)) return r; - r = m_manager.mk_fresh_const("k", s); + r = m.mk_fresh_const("k", s); m_model->register_aux_decl(r->get_decl()); m_sort2k.insert(s, r); m_ks.push_back(r); @@ -680,7 +674,7 @@ namespace smt { Remark: this method uses get_fresh_value, so it may fail. */ expr * get_k_interp(app * k) { - sort * s = m_manager.get_sort(k); + sort * s = m.get_sort(k); SASSERT(is_infinite(s)); func_decl * k_decl = k->get_decl(); expr * r = m_model->get_const_interp(k_decl); @@ -691,7 +685,7 @@ namespace smt { return 0; m_model->register_decl(k_decl, r); SASSERT(m_model->get_const_interp(k_decl) == r); - TRACE("model_finder", tout << mk_pp(r, m_manager) << "\n";); + TRACE("model_finder", tout << mk_pp(r, m) << "\n";); return r; } @@ -701,18 +695,18 @@ namespace smt { It invokes get_k_interp that may fail. */ bool assert_k_diseq_exceptions(app * k, ptr_vector const & exceptions) { - TRACE("assert_k_diseq_exceptions", tout << "assert_k_diseq_exceptions, " << "k: " << mk_pp(k, m_manager) << "\nexceptions:\n"; - for (expr * e : exceptions) tout << mk_pp(e, m_manager) << "\n";); + TRACE("assert_k_diseq_exceptions", tout << "assert_k_diseq_exceptions, " << "k: " << mk_pp(k, m) << "\nexceptions:\n"; + for (expr * e : exceptions) tout << mk_pp(e, m) << "\n";); expr * k_interp = get_k_interp(k); if (k_interp == 0) return false; for (expr * ex : exceptions) { expr * ex_val = eval(ex, true); - if (!m_manager.are_distinct(k_interp, ex_val)) { + if (!m.are_distinct(k_interp, ex_val)) { SASSERT(m_new_constraints); // This constraint cannot be asserted into m_context during model construction. // We must save it, and assert it during a restart. - m_new_constraints->push_back(m_manager.mk_not(m_manager.mk_eq(k, ex))); + m_new_constraints->push_back(m.mk_not(m.mk_eq(k, ex))); } } return true; @@ -735,7 +729,7 @@ namespace smt { return; } sort * s = n->get_sort(); - TRACE("model_finder", tout << "trying to create k for " << mk_pp(s, m_manager) << ", is_infinite: " << is_infinite(s) << "\n";); + TRACE("model_finder", tout << "trying to create k for " << mk_pp(s, m) << ", is_infinite: " << is_infinite(s) << "\n";); if (is_infinite(s)) { app * k = get_k_for(s); if (assert_k_diseq_exceptions(k, exceptions)) { @@ -758,28 +752,33 @@ namespace smt { void add_mono_exceptions(node * n) { SASSERT(n->is_mono_proj()); sort * s = n->get_sort(); - arith_simplifier_plugin * as = get_arith_simp(); - bv_simplifier_plugin * bs = get_bv_simp(); - bool is_int = as->is_int_sort(s); - bool is_bv = bs->is_bv_sort(s); - if (!is_int && !is_bv) - return; - poly_simplifier_plugin * ps = as; - if (is_bv) - ps = bs; - ps->set_curr_sort(s); - expr_ref one(m_manager); - one = ps->mk_one(); + arith_rewriter arw(m); + bv_rewriter brw(m); ptr_vector const & exceptions = n->get_exceptions(); - for (expr * e : exceptions) { - expr_ref e_plus_1(m_manager); - expr_ref e_minus_1(m_manager); - TRACE("mf_simp_bug", tout << "e:\n" << mk_ismt2_pp(e, m_manager) << "\none:\n" << mk_ismt2_pp(one, m_manager) << "\n";); - ps->mk_add(e, one, e_plus_1); - ps->mk_sub(e, one, e_minus_1); - // Note: exceptions come from quantifiers bodies. So, they have generation 0. - n->insert(e_plus_1, 0); - n->insert(e_minus_1, 0); + if (m_arith.is_int(s)) { + expr_ref one(m_arith.mk_int(1), m); + for (expr * e : exceptions) { + expr_ref e_plus_1(m_arith.mk_add(e, one), m); + expr_ref e_minus_1(m_arith.mk_sub(e, one), m); + TRACE("mf_simp_bug", tout << "e:\n" << mk_ismt2_pp(e, m) << "\none:\n" << mk_ismt2_pp(one, m) << "\n";); + // Note: exceptions come from quantifiers bodies. So, they have generation 0. + n->insert(e_plus_1, 0); + n->insert(e_minus_1, 0); + } + } + else if (m_bv.is_bv_sort(s)) { + expr_ref one(m_bv.mk_numeral(rational(1), s), m); + for (expr * e : exceptions) { + expr_ref e_plus_1(m_bv.mk_bv_add(e, one), m); + expr_ref e_minus_1(m_bv.mk_bv_sub(e, one), m); + TRACE("mf_simp_bug", tout << "e:\n" << mk_ismt2_pp(e, m) << "\none:\n" << mk_ismt2_pp(one, m) << "\n";); + // Note: exceptions come from quantifiers bodies. So, they have generation 0. + n->insert(e_plus_1, 0); + n->insert(e_minus_1, 0); + } + } + else { + return; } } @@ -797,16 +796,17 @@ namespace smt { } TRACE("model_finder_bug", tout << "values for the instantiation_set of @" << n->get_id() << "\n"; for (expr * v : values) { - tout << mk_pp(v, m_manager) << "\n"; + tout << mk_pp(v, m) << "\n"; }); } + template struct numeral_lt { - poly_simplifier_plugin * m_p; - numeral_lt(poly_simplifier_plugin * p):m_p(p) {} - bool operator()(expr * e1, expr * e2) { + T& m_util; + numeral_lt(T& a): m_util(a) {} + bool operator()(expr* e1, expr* e2) { rational v1, v2; - if (m_p->is_numeral(e1, v1) && m_p->is_numeral(e2, v2)) { + if (m_util.is_numeral(e1, v1) && m_util.is_numeral(e2, v1)) { return v1 < v2; } else { @@ -815,15 +815,16 @@ namespace smt { } }; + struct signed_bv_lt { - bv_simplifier_plugin * m_bs; + bv_util& m_bv; unsigned m_bv_size; - signed_bv_lt(bv_simplifier_plugin * bs, unsigned sz):m_bs(bs), m_bv_size(sz) {} + signed_bv_lt(bv_util& bv, unsigned sz):m_bv(bv), m_bv_size(sz) {} bool operator()(expr * e1, expr * e2) { rational v1, v2; - if (m_bs->is_numeral(e1, v1) && m_bs->is_numeral(e2, v2)) { - v1 = m_bs->norm(v1, m_bv_size, true); - v2 = m_bs->norm(v2, m_bv_size, true); + if (m_bv.is_numeral(e1, v1) && m_bv.is_numeral(e2, v2)) { + v1 = m_bv.norm(v1, m_bv_size, true); + v2 = m_bv.norm(v2, m_bv_size, true); return v1 < v2; } else { @@ -834,15 +835,14 @@ namespace smt { void sort_values(node * n, ptr_buffer & values) { sort * s = n->get_sort(); - if (get_arith_simp()->is_arith_sort(s)) { - std::sort(values.begin(), values.end(), numeral_lt(get_arith_simp())); + if (m_arith.is_int(s) || m_arith.is_real(s)) { + std::sort(values.begin(), values.end(), numeral_lt(m_arith)); } else if (!n->is_signed_proj()) { - std::sort(values.begin(), values.end(), numeral_lt(get_bv_simp())); + std::sort(values.begin(), values.end(), numeral_lt(m_bv)); } else { - bv_simplifier_plugin * bs = get_bv_simp(); - std::sort(values.begin(), values.end(), signed_bv_lt(bs, bs->get_bv_size(s))); + std::sort(values.begin(), values.end(), signed_bv_lt(m_bv, m_bv.get_bv_size(s))); } } @@ -853,27 +853,25 @@ namespace smt { if (values.empty()) return; sort_values(n, values); sort * s = n->get_sort(); - arith_simplifier_plugin * as = get_arith_simp(); - bv_simplifier_plugin * bs = get_bv_simp(); - bool is_arith = as->is_arith_sort(s); + bool is_arith = m_arith.is_int(s) || m_arith.is_real(s); bool is_signed = n->is_signed_proj(); unsigned sz = values.size(); SASSERT(sz > 0); - func_decl * p = m_manager.mk_fresh_func_decl(1, &s, s); + func_decl * p = m.mk_fresh_func_decl(1, &s, s); expr * pi = values[sz - 1]; - expr_ref var(m_manager); - var = m_manager.mk_var(0, s); + expr_ref var(m); + var = m.mk_var(0, s); for (unsigned i = sz - 1; i >= 1; i--) { - expr_ref c(m_manager); + expr_ref c(m); if (is_arith) - as->mk_lt(var, values[i], c); + c = m_arith.mk_lt(var, values[i]); else if (!is_signed) - bs->mk_ult(var, values[i], c); + c = m.mk_not(m_bv.mk_ule(values[i], var)); else - bs->mk_slt(var, values[i], c); - pi = m_manager.mk_ite(c, values[i-1], pi); + c = m.mk_not(m_bv.mk_sle(values[i], var)); + pi = m.mk_ite(c, values[i-1], pi); } - func_interp * rpi = alloc(func_interp, m_manager, 1); + func_interp * rpi = alloc(func_interp, m, 1); rpi->set_else(pi); m_model->register_aux_decl(p, rpi); n->set_proj(p); @@ -884,8 +882,8 @@ namespace smt { ptr_buffer values; get_instantiation_set_values(n, values); sort * s = n->get_sort(); - func_decl * p = m_manager.mk_fresh_func_decl(1, &s, s); - func_interp * pi = alloc(func_interp, m_manager, 1); + func_decl * p = m.mk_fresh_func_decl(1, &s, s); + func_interp * pi = alloc(func_interp, m, 1); m_model->register_aux_decl(p, pi); if (n->get_else()) { expr * else_val = eval(n->get_else(), true); @@ -916,7 +914,7 @@ namespace smt { if (!r.contains(f)) { func_interp * fi = m_model->get_func_interp(f); if (fi == 0) { - fi = alloc(func_interp, m_manager, f->get_arity()); + fi = alloc(func_interp, m, f->get_arity()); m_model->register_decl(f, fi); SASSERT(fi->is_partial()); } @@ -938,7 +936,7 @@ namespace smt { for (node * n : m_root_nodes) { SASSERT(n->is_root()); sort * s = n->get_sort(); - if (m_manager.is_uninterp(s) && + if (m.is_uninterp(s) && // Making all uninterpreted sorts finite. // n->must_avoid_itself() && !m_model->is_finite(s)) { @@ -962,7 +960,7 @@ namespace smt { // If these module values "leak" inside the logical context, they may affect satisfiability. // sort * ns = n->get_sort(); - if (m_manager.is_fully_interp(ns)) { + if (m.is_fully_interp(ns)) { n->insert(m_model->get_some_value(ns), 0); } else { @@ -973,18 +971,18 @@ namespace smt { sort2elems.insert(n->get_sort(), elems.begin()->m_key); } } - expr_ref_vector trail(m_manager); + expr_ref_vector trail(m); for (unsigned i = 0; i < need_fresh.size(); ++i) { expr * e; node* n = need_fresh[i]; sort* s = n->get_sort(); if (!sort2elems.find(s, e)) { - e = m_manager.mk_fresh_const("elem", s); + e = m.mk_fresh_const("elem", s); trail.push_back(e); sort2elems.insert(s, e); } n->insert(e, 0); - TRACE("model_finder", tout << "fresh constant: " << mk_pp(e, m_manager) << "\n";); + TRACE("model_finder", tout << "fresh constant: " << mk_pp(e, m) << "\n";); } } @@ -1037,13 +1035,13 @@ namespace smt { if (fi->is_constant()) continue; // there is no point in using the projection for fi, since fi is the constant function. - expr_ref_vector args(m_manager); + expr_ref_vector args(m); bool has_proj = false; for (unsigned i = 0; i < arity; i++) { - var * v = m_manager.mk_var(i, f->get_domain(i)); + var * v = m.mk_var(i, f->get_domain(i)); func_decl * pi = get_f_i_proj(f, i); if (pi != 0) { - args.push_back(m_manager.mk_app(pi, v)); + args.push_back(m.mk_app(pi, v)); has_proj = true; } else { @@ -1052,11 +1050,11 @@ namespace smt { } if (has_proj) { // f_aux will be assigned to the old interpretation of f. - func_decl * f_aux = m_manager.mk_fresh_func_decl(f->get_name(), symbol::null, arity, f->get_domain(), f->get_range()); - func_interp * new_fi = alloc(func_interp, m_manager, arity); - new_fi->set_else(m_manager.mk_app(f_aux, args.size(), args.c_ptr())); + func_decl * f_aux = m.mk_fresh_func_decl(f->get_name(), symbol::null, arity, f->get_domain(), f->get_range()); + func_interp * new_fi = alloc(func_interp, m, arity); + new_fi->set_else(m.mk_app(f_aux, args.size(), args.c_ptr())); TRACE("model_finder", tout << "Setting new interpretation for " << f->get_name() << "\n" << - mk_pp(new_fi->get_else(), m_manager) << "\n";); + mk_pp(new_fi->get_else(), m) << "\n";); m_model->reregister_decl(f, new_fi, f_aux); } } @@ -1256,21 +1254,21 @@ namespace smt { if (A_f_i == S_j) { // there is no finite fixpoint... we just copy the i-th arguments of A_f_i - m_offset // hope for the best... - arith_simplifier_plugin * as = s.get_arith_simp(); - bv_simplifier_plugin * bs = s.get_bv_simp(); node * S_j = s.get_uvar(q, m_var_j); enode_vector::const_iterator it = ctx->begin_enodes_of(m_f); enode_vector::const_iterator end = ctx->end_enodes_of(m_f); for (; it != end; it++) { enode * n = *it; if (ctx->is_relevant(n)) { + arith_util arith(ctx->get_manager()); + bv_util bv(ctx->get_manager()); enode * e_arg = n->get_arg(m_arg_i); expr * arg = e_arg->get_owner(); expr_ref arg_minus_k(ctx->get_manager()); - if (bs->is_bv(arg)) - bs->mk_sub(arg, m_offset, arg_minus_k); + if (bv.is_bv(arg)) + arg_minus_k = bv.mk_bv_sub(arg, m_offset); else - as->mk_sub(arg, m_offset, arg_minus_k); + arg_minus_k = arith.mk_sub(arg, m_offset); S_j->insert(arg_minus_k, e_arg->get_generation()); } } @@ -1290,20 +1288,20 @@ namespace smt { template void copy_instances(node * from, node * to, auf_solver & s) { - arith_simplifier_plugin * as = s.get_arith_simp(); - bv_simplifier_plugin * bs = s.get_bv_simp(); - poly_simplifier_plugin * ps = as; - if (bs->is_bv_sort(from->get_sort())) - ps = bs; instantiation_set const * from_s = from->get_instantiation_set(); obj_map const & elems_s = from_s->get_elems(); + + arith_util arith(m_offset.get_manager()); + bv_util bv(m_offset.get_manager()); + bool is_bv = bv.is_bv_sort(from->get_sort()); + for (auto const& kv : elems_s) { expr * n = kv.m_key; expr_ref n_k(m_offset.get_manager()); if (PLUS) - ps->mk_add(n, m_offset, n_k); + n_k = is_bv ? bv.mk_bv_add(n, m_offset) : arith.mk_add(n, m_offset); else - ps->mk_sub(n, m_offset, n_k); + n_k = is_bv ? bv.mk_bv_sub(n, m_offset) : arith.mk_sub(n, m_offset); to->insert(n_k, kv.m_value); } } @@ -1897,11 +1895,8 @@ namespace smt { m_info->insert_qinfo(qi); } - arith_simplifier_plugin * get_arith_simp() const { return m_mutil.get_arith_simp(); } - bv_simplifier_plugin * get_bv_simp() const { return m_mutil.get_bv_simp(); } - - bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) const { - return get_arith_simp()->is_var_plus_ground(n, inv, v, t) || get_bv_simp()->is_var_plus_ground(n, inv, v, t); + bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) { + return m_mutil.is_var_plus_ground(n, inv, v, t); } bool is_var_plus_ground(expr * n, var * & v, expr_ref & t) { @@ -1917,10 +1912,7 @@ namespace smt { } bool is_zero(expr * n) const { - if (get_bv_simp()->is_bv(n)) - return get_bv_simp()->is_zero_safe(n); - else - return get_arith_simp()->is_zero_safe(n); + return m_mutil.is_zero_safe(n); } bool is_times_minus_one(expr * n, expr * & arg) const { @@ -1951,7 +1943,7 @@ namespace smt { m_mutil.mk_add(t1, t2, r); } - bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t, bool & inv) const { + bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t, bool & inv) { inv = false; // true if invert the sign TRACE("is_var_and_ground", tout << "is_var_and_ground: " << mk_ismt2_pp(lhs, m_manager) << " " << mk_ismt2_pp(rhs, m_manager) << "\n";); if (is_var(lhs) && is_ground(rhs)) { @@ -1986,12 +1978,12 @@ namespace smt { return false; } - bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t) const { + bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t) { bool inv; return is_var_and_ground(lhs, rhs, v, t, inv); } - bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) const { + bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) { if (!is_app(n)) return false; if (m_manager.is_eq(n)) @@ -1999,7 +1991,7 @@ namespace smt { return false; } - bool is_var_minus_var(expr * n, var * & v1, var * & v2) const { + bool is_var_minus_var(expr * n, var * & v1, var * & v2) { if (!is_add(n)) return false; expr * arg1 = to_app(n)->get_arg(0); @@ -2018,7 +2010,7 @@ namespace smt { return true; } - bool is_var_and_var(expr * lhs, expr * rhs, var * & v1, var * & v2) const { + bool is_var_and_var(expr * lhs, expr * rhs, var * & v1, var * & v2) { if (is_var(lhs) && is_var(rhs)) { v1 = to_var(lhs); v2 = to_var(rhs); @@ -2029,11 +2021,11 @@ namespace smt { (is_var_minus_var(rhs, v1, v2) && is_zero(lhs)); } - bool is_x_eq_y_atom(expr * n, var * & v1, var * & v2) const { + bool is_x_eq_y_atom(expr * n, var * & v1, var * & v2) { return m_manager.is_eq(n) && is_var_and_var(to_app(n)->get_arg(0), to_app(n)->get_arg(1), v1, v2); } - bool is_x_gle_y_atom(expr * n, var * & v1, var * & v2) const { + bool is_x_gle_y_atom(expr * n, var * & v1, var * & v2) { return is_le_ge(n) && is_var_and_var(to_app(n)->get_arg(0), to_app(n)->get_arg(1), v1, v2); } @@ -2379,10 +2371,10 @@ namespace smt { public: - quantifier_analyzer(model_finder& mf, ast_manager & m, simplifier & s): + quantifier_analyzer(model_finder& mf, ast_manager & m): m_mf(mf), m_manager(m), - m_mutil(m, s), + m_mutil(m), m_array_util(m), m_arith_util(m), m_bv_util(m), @@ -3152,11 +3144,11 @@ namespace smt { // // ----------------------------------- - model_finder::model_finder(ast_manager & m, simplifier & s): + model_finder::model_finder(ast_manager & m): m_manager(m), m_context(0), - m_analyzer(alloc(quantifier_analyzer, *this, m, s)), - m_auf_solver(alloc(auf_solver, m, s)), + m_analyzer(alloc(quantifier_analyzer, *this, m)), + m_auf_solver(alloc(auf_solver, m)), m_dependencies(m), m_sm_solver(alloc(simple_macro_solver, m, m_q2info)), m_hint_solver(alloc(hint_solver, m, m_q2info)), diff --git a/src/smt/smt_model_finder.h b/src/smt/smt_model_finder.h index f02640659..2b79ab265 100644 --- a/src/smt/smt_model_finder.h +++ b/src/smt/smt_model_finder.h @@ -48,7 +48,6 @@ Revision History: #include "ast/ast.h" #include "ast/func_decl_dependencies.h" -#include "ast/simplifier/simplifier.h" #include "smt/proto_model/proto_model.h" #include "util/cooperate.h" #include "tactic/tactic_exception.h" @@ -107,7 +106,7 @@ namespace smt { public: - model_finder(ast_manager & m, simplifier & s); + model_finder(ast_manager & m); ~model_finder(); void set_context(context * ctx); diff --git a/src/smt/smt_quantifier.cpp b/src/smt/smt_quantifier.cpp index 84ed7c8cd..6a2f848d9 100644 --- a/src/smt/smt_quantifier.cpp +++ b/src/smt/smt_quantifier.cpp @@ -434,7 +434,7 @@ namespace smt { m_mam = mk_mam(*m_context); m_lazy_mam = mk_mam(*m_context); - m_model_finder = alloc(model_finder, m, m_context->get_simplifier()); + m_model_finder = alloc(model_finder, m); m_model_checker = alloc(model_checker, m, *m_fparams, *(m_model_finder.get())); m_model_finder->set_context(m_context); diff --git a/src/tactic/ufbv/quasi_macros_tactic.cpp b/src/tactic/ufbv/quasi_macros_tactic.cpp index ab68a2b63..f7312fd2e 100644 --- a/src/tactic/ufbv/quasi_macros_tactic.cpp +++ b/src/tactic/ufbv/quasi_macros_tactic.cpp @@ -63,7 +63,7 @@ class quasi_macros_tactic : public tactic { simp.register_plugin(bvsimp); macro_manager mm(m_manager, simp); - quasi_macros qm(m_manager, mm, simp); + quasi_macros qm(m_manager, mm); bool more = true; expr_ref_vector forms(m_manager), new_forms(m_manager); From f7ca7409cec5ce622725a9e35eb3ff935bdc890e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 22 Aug 2017 17:05:40 -0700 Subject: [PATCH 167/488] fix regressions introduced when modifying macro_util Signed-off-by: Nikolaj Bjorner --- src/ast/macros/macro_util.cpp | 13 +++++----- src/ast/macros/macro_util.h | 4 +-- src/smt/smt_model_finder.cpp | 48 +++++++++++++++++++++++------------ 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/ast/macros/macro_util.cpp b/src/ast/macros/macro_util.cpp index b7eb9657f..6bc1ee66e 100644 --- a/src/ast/macros/macro_util.cpp +++ b/src/ast/macros/macro_util.cpp @@ -105,19 +105,19 @@ app * macro_util::mk_zero(sort * s) const { void macro_util::mk_sub(expr * t1, expr * t2, expr_ref & r) const { if (is_bv(t1)) { - r = m_bv.mk_bv_sub(t1, t2); + m_bv_rw.mk_sub(t1, t2, r); } else { - r = m_arith.mk_sub(t1, t2); + m_arith_rw.mk_sub(t1, t2, r); } } void macro_util::mk_add(expr * t1, expr * t2, expr_ref & r) const { if (is_bv(t1)) { - r = m_bv.mk_bv_add(t1, t2); + m_bv_rw.mk_add(t1, t2, r); } else { - r = m_arith.mk_add(t1, t2); + m_arith_rw.mk_add(t1, t2, r); } } @@ -312,9 +312,10 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex expr_ref tmp(m_manager); tmp = m_arith.mk_add(args.size(), args.c_ptr()); if (inv) - def = m_arith.mk_sub(tmp, rhs); + mk_sub(tmp, rhs, def); else - def = m_arith.mk_sub(rhs, tmp); + mk_sub(rhs, tmp, def); + TRACE("macro_util", tout << def << "\n";); return true; } diff --git a/src/ast/macros/macro_util.h b/src/ast/macros/macro_util.h index 91d96cc5e..3ab00df2a 100644 --- a/src/ast/macros/macro_util.h +++ b/src/ast/macros/macro_util.h @@ -60,8 +60,8 @@ private: ast_manager & m_manager; bv_util m_bv; arith_util m_arith; - arith_rewriter m_arith_rw; - bv_rewriter m_bv_rw; + mutable arith_rewriter m_arith_rw; + mutable bv_rewriter m_bv_rw; obj_hashtable * m_forbidden_set; bool is_forbidden(func_decl * f) const { return m_forbidden_set != 0 && m_forbidden_set->contains(f); } diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 2e6a34557..f678ee3e7 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -755,11 +755,13 @@ namespace smt { arith_rewriter arw(m); bv_rewriter brw(m); ptr_vector const & exceptions = n->get_exceptions(); + expr_ref e_minus_1(m), e_plus_1(m); if (m_arith.is_int(s)) { expr_ref one(m_arith.mk_int(1), m); + arith_rewriter arith_rw(m); for (expr * e : exceptions) { - expr_ref e_plus_1(m_arith.mk_add(e, one), m); - expr_ref e_minus_1(m_arith.mk_sub(e, one), m); + arith_rw.mk_sub(e, one, e_minus_1); + arith_rw.mk_add(e, one, e_plus_1); TRACE("mf_simp_bug", tout << "e:\n" << mk_ismt2_pp(e, m) << "\none:\n" << mk_ismt2_pp(one, m) << "\n";); // Note: exceptions come from quantifiers bodies. So, they have generation 0. n->insert(e_plus_1, 0); @@ -768,9 +770,10 @@ namespace smt { } else if (m_bv.is_bv_sort(s)) { expr_ref one(m_bv.mk_numeral(rational(1), s), m); + bv_rewriter bv_rw(m); for (expr * e : exceptions) { - expr_ref e_plus_1(m_bv.mk_bv_add(e, one), m); - expr_ref e_minus_1(m_bv.mk_bv_sub(e, one), m); + bv_rw.mk_add(e, one, e_plus_1); + bv_rw.mk_sub(e, one, e_minus_1); TRACE("mf_simp_bug", tout << "e:\n" << mk_ismt2_pp(e, m) << "\none:\n" << mk_ismt2_pp(one, m) << "\n";); // Note: exceptions come from quantifiers bodies. So, they have generation 0. n->insert(e_plus_1, 0); @@ -806,7 +809,7 @@ namespace smt { numeral_lt(T& a): m_util(a) {} bool operator()(expr* e1, expr* e2) { rational v1, v2; - if (m_util.is_numeral(e1, v1) && m_util.is_numeral(e2, v1)) { + if (m_util.is_numeral(e1, v1) && m_util.is_numeral(e2, v2)) { return v1 < v2; } else { @@ -1260,15 +1263,16 @@ namespace smt { for (; it != end; it++) { enode * n = *it; if (ctx->is_relevant(n)) { - arith_util arith(ctx->get_manager()); + arith_rewriter arith_rw(ctx->get_manager()); bv_util bv(ctx->get_manager()); + bv_rewriter bv_rw(ctx->get_manager()); enode * e_arg = n->get_arg(m_arg_i); expr * arg = e_arg->get_owner(); expr_ref arg_minus_k(ctx->get_manager()); - if (bv.is_bv(arg)) - arg_minus_k = bv.mk_bv_sub(arg, m_offset); + if (bv.is_bv(arg)) + bv_rw.mk_sub(arg, m_offset, arg_minus_k); else - arg_minus_k = arith.mk_sub(arg, m_offset); + arith_rw.mk_sub(arg, m_offset, arg_minus_k); S_j->insert(arg_minus_k, e_arg->get_generation()); } } @@ -1291,17 +1295,29 @@ namespace smt { instantiation_set const * from_s = from->get_instantiation_set(); obj_map const & elems_s = from_s->get_elems(); - arith_util arith(m_offset.get_manager()); - bv_util bv(m_offset.get_manager()); - bool is_bv = bv.is_bv_sort(from->get_sort()); + arith_rewriter arith_rw(m_offset.get_manager()); + bv_rewriter bv_rw(m_offset.get_manager()); + bool is_bv = bv_util(m_offset.get_manager()).is_bv_sort(from->get_sort()); for (auto const& kv : elems_s) { expr * n = kv.m_key; expr_ref n_k(m_offset.get_manager()); - if (PLUS) - n_k = is_bv ? bv.mk_bv_add(n, m_offset) : arith.mk_add(n, m_offset); - else - n_k = is_bv ? bv.mk_bv_sub(n, m_offset) : arith.mk_sub(n, m_offset); + if (PLUS) { + if (is_bv) { + bv_rw.mk_add(n, m_offset, n_k); + } + else { + arith_rw.mk_add(n, m_offset, n_k); + } + } + else { + if (is_bv) { + bv_rw.mk_sub(n, m_offset, n_k); + } + else { + arith_rw.mk_sub(n, m_offset, n_k); + } + } to->insert(n_k, kv.m_value); } } From ce04c18a7a8965ffc1642e56779e1e5db9c6d750 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 22 Aug 2017 22:14:13 -0700 Subject: [PATCH 168/488] trying to get rid of last simplifier dependency in macros Signed-off-by: Nikolaj Bjorner --- src/ast/fpa/fpa2bv_converter.h | 4 +- src/ast/macros/macro_manager.cpp | 159 ++++++++++++++++++++---- src/ast/macros/macro_manager.h | 14 ++- src/ast/rewriter/poly_rewriter_def.h | 4 + src/muz/pdr/pdr_util.h | 2 +- src/muz/rel/dl_bound_relation.cpp | 2 +- src/muz/rel/dl_bound_relation.h | 3 +- src/smt/asserted_formulas.cpp | 2 +- src/tactic/ufbv/macro_finder_tactic.cpp | 2 +- src/tactic/ufbv/quasi_macros_tactic.cpp | 2 +- 10 files changed, 158 insertions(+), 36 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 19a52dd23..1e3e5d9b3 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -29,7 +29,7 @@ Notes: #include "ast/dl_decl_plugin.h" #include "ast/pb_decl_plugin.h" #include "ast/seq_decl_plugin.h" -#include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/rewriter/bool_rewriter.h" class fpa2bv_converter { public: @@ -39,7 +39,7 @@ public: protected: ast_manager & m; - basic_simplifier_plugin m_simp; + bool_rewriter m_simp; fpa_util m_util; bv_util m_bv_util; arith_util m_arith_util; diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index f26a87445..70434435b 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -22,12 +22,14 @@ Revision History: #include "ast/macros/macro_manager.h" #include "ast/for_each_expr.h" #include "ast/rewriter/var_subst.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/rewriter_def.h" #include "ast/ast_pp.h" #include "ast/recurse_expr_def.h" -macro_manager::macro_manager(ast_manager & m, simplifier & s): - m_manager(m), - m_simplifier(s), + +macro_manager::macro_manager(ast_manager & m): + m(m), m_util(m), m_decls(m), m_macros(m), @@ -60,12 +62,12 @@ void macro_manager::restore_decls(unsigned old_sz) { for (unsigned i = old_sz; i < sz; i++) { m_decl2macro.erase(m_decls.get(i)); m_deps.erase(m_decls.get(i)); - if (m_manager.proofs_enabled()) + if (m.proofs_enabled()) m_decl2macro_pr.erase(m_decls.get(i)); } m_decls.shrink(old_sz); m_macros.shrink(old_sz); - if (m_manager.proofs_enabled()) + if (m.proofs_enabled()) m_macro_prs.shrink(old_sz); } @@ -88,8 +90,8 @@ void macro_manager::reset() { m_deps.reset(); } -bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr) { - TRACE("macro_insert", tout << "trying to create macro: " << f->get_name() << "\n" << mk_pp(m, m_manager) << "\n";); +bool macro_manager::insert(func_decl * f, quantifier * q, proof * pr) { + TRACE("macro_insert", tout << "trying to create macro: " << f->get_name() << "\n" << mk_pp(q, m) << "\n";); // if we already have a macro for f then return false; if (m_decls.contains(f)) { @@ -99,7 +101,7 @@ bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr) { app * head; expr * definition; - get_head_def(m, f, head, definition); + get_head_def(q, f, head, definition); func_decl_set * s = m_deps.mk_func_decl_set(); m_deps.collect_func_decls(definition, s); @@ -108,10 +110,10 @@ bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr) { } // add macro - m_decl2macro.insert(f, m); + m_decl2macro.insert(f, q); m_decls.push_back(f); - m_macros.push_back(m); - if (m_manager.proofs_enabled()) { + m_macros.push_back(q); + if (m.proofs_enabled()) { m_macro_prs.push_back(pr); m_decl2macro_pr.insert(f, pr); } @@ -152,7 +154,7 @@ void macro_manager::mark_forbidden(unsigned n, expr * const * exprs) { void macro_manager::get_head_def(quantifier * q, func_decl * d, app * & head, expr * & def) const { app * body = to_app(q->get_expr()); - SASSERT(m_manager.is_eq(body) || m_manager.is_iff(body)); + SASSERT(m.is_eq(body) || m.is_iff(body)); expr * lhs = to_app(body)->get_arg(0); expr * rhs = to_app(body)->get_arg(1); SASSERT(is_app_of(lhs, d) || is_app_of(rhs, d)); @@ -177,7 +179,7 @@ void macro_manager::display(std::ostream & out) { expr * def; get_head_def(q, f, head, def); SASSERT(q); - out << mk_pp(head, m_manager) << " ->\n" << mk_pp(def, m_manager) << "\n"; + out << mk_pp(head, m) << " ->\n" << mk_pp(def, m) << "\n"; } } @@ -188,12 +190,115 @@ func_decl * macro_manager::get_macro_interpretation(unsigned i, expr_ref & inter expr * def; get_head_def(q, f, head, def); TRACE("macro_bug", - tout << f->get_name() << "\n" << mk_pp(head, m_manager) << "\n" << mk_pp(q, m_manager) << "\n";); + tout << f->get_name() << "\n" << mk_pp(head, m) << "\n" << mk_pp(q, m) << "\n";); m_util.mk_macro_interpretation(head, q->get_num_decls(), def, interp); return f; } -macro_manager::macro_expander::macro_expander(ast_manager & m, macro_manager & mm, simplifier & s): +struct macro_manager::macro_expander_cfg : public default_rewriter_cfg { + ast_manager& m; + macro_manager& mm; + expr_ref_vector m_trail; + + macro_expander_cfg(ast_manager& m, macro_manager& mm): + m(m), + mm(mm), + m_trail(m) + {} + + bool rewrite_patterns() const { return false; } + bool flat_assoc(func_decl * f) const { return false; } + br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { + result_pr = 0; + return BR_FAILED; + } + + bool reduce_quantifier(quantifier * old_q, + expr * new_body, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr) { + + // If a macro was expanded in a pattern, we must erase it since it may not be a valid pattern anymore. + // The MAM assumes valid patterns, and it crashes if invalid patterns are provided. + // For example, it will crash if the pattern does not contain all variables. + // + // Alternative solution: use pattern_validation to check if the pattern is still valid. + // I'm not sure if this is a good solution, since the pattern may be meaningless after the macro expansion. + // So, I'm just erasing them. + + bool erase_patterns = false; + for (unsigned i = 0; !erase_patterns && i < old_q->get_num_patterns(); i++) { + if (old_q->get_pattern(i) != new_patterns[i]) + erase_patterns = true; + } + for (unsigned i = 0; !erase_patterns && i < old_q->get_num_no_patterns(); i++) { + if (old_q->get_no_pattern(i) != new_no_patterns[i]) + erase_patterns = true; + } + if (erase_patterns) { + result = m.update_quantifier(old_q, 0, 0, 0, 0, new_body); + } + return erase_patterns; + } + + bool get_subst(expr * _n, expr* & r, proof* & p) { + if (!is_app(_n)) + return false; + app * n = to_app(_n); + quantifier * q = 0; + func_decl * d = n->get_decl(); + TRACE("macro_manager", tout << "trying to expand:\n" << mk_pp(n, m) << "\nd:\n" << d->get_name() << "\n";); + if (mm.m_decl2macro.find(d, q)) { + TRACE("macro_manager", tout << "expanding: " << mk_pp(n, m) << "\n";); + app * head = 0; + expr * def = 0; + mm.get_head_def(q, d, head, def); + unsigned num = n->get_num_args(); + SASSERT(head && def); + ptr_buffer subst_args; + subst_args.resize(num, 0); + for (unsigned i = 0; i < num; i++) { + var * v = to_var(head->get_arg(i)); + SASSERT(v->get_idx() < num); + unsigned nidx = num - v->get_idx() - 1; + SASSERT(subst_args[nidx] == 0); + subst_args[nidx] = n->get_arg(i); + } + var_subst s(m); + expr_ref rr(m); + s(def, num, subst_args.c_ptr(), rr); + m_trail.push_back(rr); + r = rr; + if (m.proofs_enabled()) { + expr_ref instance(m); + s(q->get_expr(), num, subst_args.c_ptr(), instance); + proof * qi_pr = m.mk_quant_inst(m.mk_or(m.mk_not(q), instance), num, subst_args.c_ptr()); + proof * q_pr = 0; + mm.m_decl2macro_pr.find(d, q_pr); + SASSERT(q_pr != 0); + proof * prs[2] = { qi_pr, q_pr }; + p = m.mk_unit_resolution(2, prs); + } + else { + p = 0; + } + return true; + } + return false; + } +}; + +struct macro_manager::macro_expander_rw : public rewriter_tpl { + macro_expander_cfg m_cfg; + macro_expander_rw(ast_manager& m, macro_manager& mm): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m, mm) + {} +}; + +macro_manager::macro_expander::macro_expander(ast_manager & m, macro_manager & mm): simplifier(m), m_macro_manager(mm) { // REMARK: theory simplifier should not be used by macro_expander... @@ -295,20 +400,30 @@ bool macro_manager::macro_expander::get_subst(expr * _n, expr_ref & r, proof_ref void macro_manager::expand_macros(expr * n, proof * pr, expr_ref & r, proof_ref & new_pr) { if (has_macros()) { // Expand macros with "real" proof production support (NO rewrite*) - expr_ref old_n(m_manager); - proof_ref old_pr(m_manager); + expr_ref old_n(m); + proof_ref old_pr(m); old_n = n; old_pr = pr; + bool change = false; for (;;) { - macro_expander proc(m_manager, *this, m_simplifier); - proof_ref n_eq_r_pr(m_manager); - TRACE("macro_manager_bug", tout << "expand_macros:\n" << mk_pp(n, m_manager) << "\n";); + macro_expander_rw proc(m, *this); + proof_ref n_eq_r_pr(m); + TRACE("macro_manager_bug", tout << "expand_macros:\n" << mk_pp(n, m) << "\n";); proc(old_n, r, n_eq_r_pr); - new_pr = m_manager.mk_modus_ponens(old_pr, n_eq_r_pr); + new_pr = m.mk_modus_ponens(old_pr, n_eq_r_pr); if (r.get() == old_n.get()) - return; + break; old_n = r; old_pr = new_pr; + change = true; + } + // apply th_rewrite to the result. + if (change) { + th_rewriter rw(m); + proof_ref rw_pr(m); + expr_ref r1(r, m); + rw(r1, r, rw_pr); + new_pr = m.mk_modus_ponens(new_pr, rw_pr); } } else { diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index a0a42b790..98e242cd8 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -19,8 +19,8 @@ Revision History: #ifndef MACRO_MANAGER_H_ #define MACRO_MANAGER_H_ -#include "ast/ast_util.h" #include "util/obj_hashtable.h" +#include "ast/ast_util.h" #include "ast/simplifier/simplifier.h" #include "ast/recurse_expr.h" #include "ast/func_decl_dependencies.h" @@ -36,8 +36,7 @@ Revision History: It has support for backtracking and tagging declarations in an expression as forbidded for being macros. */ class macro_manager { - ast_manager & m_manager; - simplifier & m_simplifier; + ast_manager & m; macro_util m_util; obj_map m_decl2macro; // func-decl -> quantifier @@ -58,21 +57,24 @@ class macro_manager { void restore_decls(unsigned old_sz); void restore_forbidden(unsigned old_sz); + struct macro_expander_cfg; + struct macro_expander_rw; + class macro_expander : public simplifier { protected: macro_manager & m_macro_manager; virtual bool get_subst(expr * n, expr_ref & r, proof_ref & p); virtual void reduce1_quantifier(quantifier * q); public: - macro_expander(ast_manager & m, macro_manager & mm, simplifier & s); + macro_expander(ast_manager & m, macro_manager & mm); ~macro_expander(); }; friend class macro_expander; public: - macro_manager(ast_manager & m, simplifier & s); + macro_manager(ast_manager & m); ~macro_manager(); - ast_manager & get_manager() const { return m_manager; } + ast_manager & get_manager() const { return m; } macro_util & get_util() { return m_util; } bool insert(func_decl * f, quantifier * m, proof * pr); bool has_macros() const { return !m_macros.empty(); } diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index a8d115d64..6b747756c 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -118,6 +118,9 @@ expr * poly_rewriter::mk_mul_app(numeral const & c, expr * arg) { if (c.is_one()) { return arg; } + else if (is_zero(arg)) { + return arg; + } else { expr * new_args[2] = { mk_numeral(c), arg }; return mk_mul_app(2, new_args); @@ -654,6 +657,7 @@ br_status poly_rewriter::mk_sub(unsigned num_args, expr * const * args, ptr_buffer new_args; new_args.push_back(args[0]); for (unsigned i = 1; i < num_args; i++) { + if (is_zero(args[i])) continue; expr * aux_args[2] = { minus_one, args[i] }; new_args.push_back(mk_mul_app(2, aux_args)); } diff --git a/src/muz/pdr/pdr_util.h b/src/muz/pdr/pdr_util.h index fccb0c40f..51f6978ec 100644 --- a/src/muz/pdr/pdr_util.h +++ b/src/muz/pdr/pdr_util.h @@ -22,9 +22,9 @@ Revision History: #include "ast/ast.h" #include "ast/ast_pp.h" +#include "ast/ast_util.h" #include "util/obj_hashtable.h" #include "util/ref_vector.h" -#include "ast/simplifier/simplifier.h" #include "util/trace.h" #include "util/vector.h" #include "ast/arith_decl_plugin.h" diff --git a/src/muz/rel/dl_bound_relation.cpp b/src/muz/rel/dl_bound_relation.cpp index de6c76456..9dc0eb8d5 100644 --- a/src/muz/rel/dl_bound_relation.cpp +++ b/src/muz/rel/dl_bound_relation.cpp @@ -653,7 +653,7 @@ namespace datalog { void bound_relation::to_formula(expr_ref& fml) const { ast_manager& m = get_plugin().get_ast_manager(); arith_util& arith = get_plugin().m_arith; - basic_simplifier_plugin& bsimp = get_plugin().m_bsimp; + bool_rewriter& bsimp = get_plugin().m_bsimp; expr_ref_vector conjs(m); relation_signature const& sig = get_signature(); for (unsigned i = 0; i < sig.size(); ++i) { diff --git a/src/muz/rel/dl_bound_relation.h b/src/muz/rel/dl_bound_relation.h index 456df737b..1678e23b8 100644 --- a/src/muz/rel/dl_bound_relation.h +++ b/src/muz/rel/dl_bound_relation.h @@ -27,6 +27,7 @@ Revision History: #include "muz/rel/dl_interval_relation.h" #include "ast/arith_decl_plugin.h" #include "ast/simplifier/basic_simplifier_plugin.h" +#include "ast/rewriter/bool_rewriter.h" namespace datalog { @@ -44,7 +45,7 @@ namespace datalog { class filter_interpreted_fn; class filter_intersection_fn; arith_util m_arith; - basic_simplifier_plugin m_bsimp; + bool_rewriter m_bsimp; public: bound_relation_plugin(relation_manager& m); virtual bool can_handle_signature(const relation_signature & s); diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 2f55cd704..7eb189ebf 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -52,7 +52,7 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m_asserted_formulas(m), m_asserted_formula_prs(m), m_asserted_qhead(0), - m_macro_manager(m, m_simplifier), + m_macro_manager(m), m_bit2int(m), m_bv_sharing(m), m_inconsistent(false){ diff --git a/src/tactic/ufbv/macro_finder_tactic.cpp b/src/tactic/ufbv/macro_finder_tactic.cpp index 9b1835ff3..b3f258ba7 100644 --- a/src/tactic/ufbv/macro_finder_tactic.cpp +++ b/src/tactic/ufbv/macro_finder_tactic.cpp @@ -64,7 +64,7 @@ class macro_finder_tactic : public tactic { bv_simplifier_plugin * bvsimp = alloc(bv_simplifier_plugin, m_manager, *bsimp, bv_params); simp.register_plugin(bvsimp); - macro_manager mm(m_manager, simp); + macro_manager mm(m_manager); macro_finder mf(m_manager, mm); expr_ref_vector forms(m_manager), new_forms(m_manager); diff --git a/src/tactic/ufbv/quasi_macros_tactic.cpp b/src/tactic/ufbv/quasi_macros_tactic.cpp index f7312fd2e..8a91bde61 100644 --- a/src/tactic/ufbv/quasi_macros_tactic.cpp +++ b/src/tactic/ufbv/quasi_macros_tactic.cpp @@ -62,7 +62,7 @@ class quasi_macros_tactic : public tactic { bv_simplifier_plugin * bvsimp = alloc(bv_simplifier_plugin, m_manager, *bsimp, bv_params); simp.register_plugin(bvsimp); - macro_manager mm(m_manager, simp); + macro_manager mm(m_manager); quasi_macros qm(m_manager, mm); bool more = true; From ae9ace232143af631af831a23d48c9f7fbd471c1 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Wed, 23 Aug 2017 10:25:33 +0000 Subject: [PATCH 169/488] injectivity: Cleanup whitespace --- src/tactic/core/injectivity_tactic.cpp | 340 ++++++++++++------------- 1 file changed, 170 insertions(+), 170 deletions(-) diff --git a/src/tactic/core/injectivity_tactic.cpp b/src/tactic/core/injectivity_tactic.cpp index 95e380982..7d90a2155 100644 --- a/src/tactic/core/injectivity_tactic.cpp +++ b/src/tactic/core/injectivity_tactic.cpp @@ -29,120 +29,120 @@ Notes: class injectivity_tactic : public tactic { - struct InjHelper : public obj_map*> { - ast_manager & m_manager; + struct InjHelper : public obj_map*> { + ast_manager & m_manager; - void insert(func_decl* const f, func_decl* const g) { - obj_hashtable *m; - if (! obj_map::find(f, m)) { - m_manager.inc_ref(f); - m = alloc(obj_hashtable); // TODO: Check we don't leak memory - obj_map::insert(f, m); - } - if (!m->contains(g)) { - m_manager.inc_ref(g); - m->insert(g); - } - } + void insert(func_decl* const f, func_decl* const g) { + obj_hashtable *m; + if (! obj_map::find(f, m)) { + m_manager.inc_ref(f); + m = alloc(obj_hashtable); // TODO: Check we don't leak memory + obj_map::insert(f, m); + } + if (!m->contains(g)) { + m_manager.inc_ref(g); + m->insert(g); + } + } - bool find(func_decl* const f, func_decl* const g) const { - obj_hashtable *m; - if(! obj_map::find(f, m)) - return false; + bool find(func_decl* const f, func_decl* const g) const { + obj_hashtable *m; + if(! obj_map::find(f, m)) + return false; - return m->contains(g); - } + return m->contains(g); + } - InjHelper(ast_manager& m) : obj_map*>(), m_manager(m) {} - ~InjHelper() { - for(auto m : *this) { - for (func_decl* f : *m.get_value()) - m_manager.dec_ref(f); + InjHelper(ast_manager& m) : obj_map*>(), m_manager(m) {} + ~InjHelper() { + for(auto m : *this) { + for (func_decl* f : *m.get_value()) + m_manager.dec_ref(f); - m_manager.dec_ref(m.m_key); - dealloc(m.m_value); - } - } + m_manager.dec_ref(m.m_key); + dealloc(m.m_value); + } + } - }; + }; struct finder { ast_manager & m_manager; - InjHelper & inj_map; + InjHelper & inj_map; - finder(ast_manager & m, InjHelper & map, params_ref const & p) : + finder(ast_manager & m, InjHelper & map, params_ref const & p) : m_manager(m), - inj_map(map) { + inj_map(map) { updt_params(p); } - + ast_manager & m() const { return m_manager; } - bool is_axiom(expr* n, func_decl* &f, func_decl* &g) { - if (!is_quantifier(n)) - return false; + bool is_axiom(expr* n, func_decl* &f, func_decl* &g) { + if (!is_quantifier(n)) + return false; - quantifier* const q = to_quantifier(n); - if (!q->is_forall() || q->get_num_decls() != 1) - return false; + quantifier* const q = to_quantifier(n); + if (!q->is_forall() || q->get_num_decls() != 1) + return false; - const expr * const body = q->get_expr(); + const expr * const body = q->get_expr(); - // n ~= forall x. body + // n ~= forall x. body - if (!m().is_eq(body)) - return false; + if (!m().is_eq(body)) + return false; - const app * const body_a = to_app(body); - if (body_a->get_num_args() != 2) - return false; + const app * const body_a = to_app(body); + if (body_a->get_num_args() != 2) + return false; - const expr* a = body_a->get_arg(0); - const expr* b = body_a->get_arg(1); + const expr* a = body_a->get_arg(0); + const expr* b = body_a->get_arg(1); - // n ~= forall x. (= a b) + // n ~= forall x. (= a b) - if (is_app(a) && is_var(b)) { - // Do nothing - } - else if (is_app(b) && is_var(a)) { - std::swap(a, b); - } - else - return false; + if (is_app(a) && is_var(b)) { + // Do nothing + } + else if (is_app(b) && is_var(a)) { + std::swap(a, b); + } + else + return false; - const app* const a_app = to_app(a); - const var* const b_var = to_var(b); + const app* const a_app = to_app(a); + const var* const b_var = to_var(b); - if (b_var->get_idx() != 0) // idx is the De Bruijn's index - return false; + if (b_var->get_idx() != 0) // idx is the De Bruijn's index + return false; - if (a_app->get_num_args() != 1) - return false; + if (a_app->get_num_args() != 1) + return false; - g = a_app->get_decl(); - const expr* const a_body = a_app->get_arg(0); + g = a_app->get_decl(); + const expr* const a_body = a_app->get_arg(0); - // n ~= forall x. (= (g a_body) x) + // n ~= forall x. (= (g a_body) x) - if (!is_app(a_body)) - return false; - const app* const a_body_app = to_app(a_body); - if (a_body_app->get_num_args() != 1) // Maybe TODO: support multi-argument functions - return false; + if (!is_app(a_body)) + return false; + const app* const a_body_app = to_app(a_body); + if (a_body_app->get_num_args() != 1) // Maybe TODO: support multi-argument functions + return false; - f = a_body_app->get_decl(); - const expr* const a_body_body = a_body_app->get_arg(0); - - // n ~= forall x. (= (g (f a_body_body)) x) - if (a_body_body != b_var) - return false; + f = a_body_app->get_decl(); + const expr* const a_body_body = a_body_app->get_arg(0); - // n ~= forall x. (= (g (f x)) x) + // n ~= forall x. (= (g (f a_body_body)) x) + if (a_body_body != b_var) + return false; + + // n ~= forall x. (= (g (f x)) x) + + return true; + } - return true; - } - void operator()(goal_ref const & goal, goal_ref_buffer & result, model_converter_ref & mc, @@ -152,112 +152,112 @@ class injectivity_tactic : public tactic { mc = 0; pc = 0; core = 0; tactic_report report("injectivity", *goal); fail_if_unsat_core_generation("injectivity", goal); // TODO: Support UNSAT cores - fail_if_proof_generation("injectivity", goal); + fail_if_proof_generation("injectivity", goal); - for (unsigned i = 0; i < goal->size(); ++i) { - func_decl *f, *g; - if (!is_axiom(goal->form(i), f, g)) continue; - TRACE("injectivity", tout << "Marking " << f->get_name() << " as injective" << std::endl;); - inj_map.insert(f, g); - // TODO: Record that g is f's pseudoinverse - } + for (unsigned i = 0; i < goal->size(); ++i) { + func_decl *f, *g; + if (!is_axiom(goal->form(i), f, g)) continue; + TRACE("injectivity", tout << "Marking " << f->get_name() << " as injective" << std::endl;); + inj_map.insert(f, g); + // TODO: Record that g is f's pseudoinverse + } } void updt_params(params_ref const & p) {} }; - struct rewriter_eq_cfg : public default_rewriter_cfg { - ast_manager & m_manager; - InjHelper & inj_map; -// expr_ref_vector m_out; -// sort_ref_vector m_bindings; + struct rewriter_eq_cfg : public default_rewriter_cfg { + ast_manager & m_manager; + InjHelper & inj_map; +// expr_ref_vector m_out; +// sort_ref_vector m_bindings; - ast_manager & m() const { return m_manager; } + ast_manager & m() const { return m_manager; } - rewriter_eq_cfg(ast_manager & m, InjHelper & map, params_ref const & p) : m_manager(m), inj_map(map) { - } + rewriter_eq_cfg(ast_manager & m, InjHelper & map, params_ref const & p) : m_manager(m), inj_map(map) { + } - ~rewriter_eq_cfg() { - } + ~rewriter_eq_cfg() { + } - void cleanup_buffers() { -// m_out.finalize(); - } + void cleanup_buffers() { +// m_out.finalize(); + } - void reset() { - } + void reset() { + } - br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { - if(num != 2) - return BR_FAILED; + br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { + if(num != 2) + return BR_FAILED; - if (!m().is_eq(f)) - return BR_FAILED; + if (!m().is_eq(f)) + return BR_FAILED; - // We are rewriting (= a b) - if (!is_app(args[0]) || !is_app(args[1])) - return BR_FAILED; + // We are rewriting (= a b) + if (!is_app(args[0]) || !is_app(args[1])) + return BR_FAILED; - const app* const a = to_app(args[0]); - const app* const b = to_app(args[1]); + const app* const a = to_app(args[0]); + const app* const b = to_app(args[1]); - // a and b are applications of the same function - if (a->get_decl() != b->get_decl()) - return BR_FAILED; + // a and b are applications of the same function + if (a->get_decl() != b->get_decl()) + return BR_FAILED; - // Maybe TODO: Generalize to multi-parameter functions ? - if (a->get_num_args() != 1 || b->get_num_args() != 1) - return BR_FAILED; + // Maybe TODO: Generalize to multi-parameter functions ? + if (a->get_num_args() != 1 || b->get_num_args() != 1) + return BR_FAILED; - if (!inj_map.contains(a->get_decl())) - return BR_FAILED; + if (!inj_map.contains(a->get_decl())) + return BR_FAILED; - SASSERT(m().get_sort(a->get_arg(0)) == m().get_sort(b->get_arg(0))); - TRACE("injectivity", tout << "Rewriting (= " << mk_ismt2_pp(args[0], m()) << - " " << mk_ismt2_pp(args[1], m()) << ")" << std::endl;); - result = m().mk_eq(a->get_arg(0), b->get_arg(0)); - result_pr = nullptr; - return BR_DONE; - } + SASSERT(m().get_sort(a->get_arg(0)) == m().get_sort(b->get_arg(0))); + TRACE("injectivity", tout << "Rewriting (= " << mk_ismt2_pp(args[0], m()) << + " " << mk_ismt2_pp(args[1], m()) << ")" << std::endl;); + result = m().mk_eq(a->get_arg(0), b->get_arg(0)); + result_pr = nullptr; + return BR_DONE; + } - }; + }; - struct rewriter_eq : public rewriter_tpl { - rewriter_eq_cfg m_cfg; - rewriter_eq(ast_manager & m, InjHelper & map, params_ref const & p) : - rewriter_tpl(m, m.proofs_enabled(), m_cfg), - m_cfg(m, map, p) { - } - }; + struct rewriter_eq : public rewriter_tpl { + rewriter_eq_cfg m_cfg; + rewriter_eq(ast_manager & m, InjHelper & map, params_ref const & p) : + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m, map, p) { + } + }; - struct rewriter_inverse { }; + struct rewriter_inverse { }; finder * m_finder; - rewriter_eq * m_eq; - InjHelper * m_map; -// rewriter_inverse * m_inverse; + rewriter_eq * m_eq; + InjHelper * m_map; +// rewriter_inverse * m_inverse; params_ref m_params; - ast_manager & m_manager; + ast_manager & m_manager; public: injectivity_tactic(ast_manager & m, params_ref const & p): m_params(p), - m_manager(m) { - TRACE("injectivity", tout << "constructed new tactic" << std::endl;); - m_map = alloc(InjHelper, m); + m_manager(m) { + TRACE("injectivity", tout << "constructed new tactic" << std::endl;); + m_map = alloc(InjHelper, m); m_finder = alloc(finder, m, *m_map, p); - m_eq = alloc(rewriter_eq, m, *m_map, p); + m_eq = alloc(rewriter_eq, m, *m_map, p); } virtual tactic * translate(ast_manager & m) { return alloc(injectivity_tactic, m, m_params); } - + virtual ~injectivity_tactic() { dealloc(m_finder); - dealloc(m_eq); - dealloc(m_map); + dealloc(m_eq); + dealloc(m_map); } virtual void updt_params(params_ref const & p) { @@ -269,30 +269,30 @@ public: insert_max_memory(r); insert_produce_models(r); } - - virtual void operator()(goal_ref const & g, - goal_ref_buffer & result, - model_converter_ref & mc, + + virtual void operator()(goal_ref const & g, + goal_ref_buffer & result, + model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { (*m_finder)(g, result, mc, pc, core); - - for (unsigned i = 0; i < g->size(); ++i) { - expr* curr = g->form(i); - expr_ref rw(m_manager); - proof_ref pr(m_manager); - (*m_eq)(curr, rw, pr); - g->update(i, rw, pr, g->dep(i)); - } - result.push_back(g.get()); - } - + + for (unsigned i = 0; i < g->size(); ++i) { + expr* curr = g->form(i); + expr_ref rw(m_manager); + proof_ref pr(m_manager); + (*m_eq)(curr, rw, pr); + g->update(i, rw, pr, g->dep(i)); + } + result.push_back(g.get()); + } + virtual void cleanup() { - InjHelper * m = alloc(InjHelper, m_manager); - finder * f = alloc(finder, m_manager, *m, m_params); - rewriter_eq * r = alloc(rewriter_eq, m_manager, *m, m_params); - std::swap(m, m_map), std::swap(f, m_finder), std::swap(r, m_eq); - dealloc(m), dealloc(f), dealloc(r); + InjHelper * m = alloc(InjHelper, m_manager); + finder * f = alloc(finder, m_manager, *m, m_params); + rewriter_eq * r = alloc(rewriter_eq, m_manager, *m, m_params); + std::swap(m, m_map), std::swap(f, m_finder), std::swap(r, m_eq); + dealloc(m), dealloc(f), dealloc(r); } From b877c962caa73ae29be01a4dd28c7a82ac7600d3 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Wed, 23 Aug 2017 10:27:55 +0000 Subject: [PATCH 170/488] injectivity: Add tactic to CMake-based builds --- src/tactic/core/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tactic/core/CMakeLists.txt b/src/tactic/core/CMakeLists.txt index 1f766bd47..f192b4fa6 100644 --- a/src/tactic/core/CMakeLists.txt +++ b/src/tactic/core/CMakeLists.txt @@ -9,6 +9,7 @@ z3_add_component(core_tactics distribute_forall_tactic.cpp elim_term_ite_tactic.cpp elim_uncnstr_tactic.cpp + injectivity_tactic.cpp nnf_tactic.cpp occf_tactic.cpp pb_preprocess_tactic.cpp @@ -22,6 +23,7 @@ z3_add_component(core_tactics collect_occs.cpp COMPONENT_DEPENDENCIES normal_forms + rewriter tactic TACTIC_HEADERS blast_term_ite_tactic.h @@ -32,6 +34,7 @@ z3_add_component(core_tactics distribute_forall_tactic.h elim_term_ite_tactic.h elim_uncnstr_tactic.h + injectivity_tactic.h nnf_tactic.h occf_tactic.h pb_preprocess_tactic.h From 3e960eadd2b14f1da9b89927e6dd17cf77eea063 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Aug 2017 12:14:19 +0100 Subject: [PATCH 171/488] (Re-)added option to disable lemma deletion in the smt_context. --- src/smt/params/smt_params.h | 31 +- src/smt/smt_context.cpp | 556 ++++++++++++++++++------------------ 2 files changed, 295 insertions(+), 292 deletions(-) diff --git a/src/smt/params/smt_params.h b/src/smt/params/smt_params.h index 4539ebe58..b01499c04 100644 --- a/src/smt/params/smt_params.h +++ b/src/smt/params/smt_params.h @@ -31,7 +31,7 @@ Revision History: #include "smt/params/preprocessor_params.h" #include "cmd_context/context_params.h" -enum phase_selection { +enum phase_selection { PS_ALWAYS_FALSE, PS_ALWAYS_TRUE, PS_CACHING, @@ -52,7 +52,8 @@ enum restart_strategy { enum lemma_gc_strategy { LGC_FIXED, LGC_GEOMETRIC, - LGC_AT_RESTART + LGC_AT_RESTART, + LGC_NONE }; enum initial_activity { @@ -71,11 +72,11 @@ enum case_split_strategy { CS_ACTIVITY_THEORY_AWARE_BRANCHING // activity-based case split, but theory solvers can manipulate activity }; -struct smt_params : public preprocessor_params, - public dyn_ack_params, - public qi_params, - public theory_arith_params, - public theory_array_params, +struct smt_params : public preprocessor_params, + public dyn_ack_params, + public qi_params, + public theory_arith_params, + public theory_array_params, public theory_bv_params, public theory_str_params, public theory_pb_params, @@ -153,12 +154,12 @@ struct smt_params : public preprocessor_params, unsigned m_lemma_gc_initial; double m_lemma_gc_factor; unsigned m_new_old_ratio; //!< the ratio of new and old clauses. - unsigned m_new_clause_activity; + unsigned m_new_clause_activity; unsigned m_old_clause_activity; unsigned m_new_clause_relevancy; //!< Max. number of unassigned literals to be considered relevant. unsigned m_old_clause_relevancy; //!< Max. number of unassigned literals to be considered relevant. double m_inv_clause_decay; //!< clause activity decay - + // ----------------------------------- // // SMT-LIB (debug) pretty printer @@ -166,7 +167,7 @@ struct smt_params : public preprocessor_params, // ----------------------------------- bool m_smtlib_dump_lemmas; symbol m_logic; - + // ----------------------------------- // // Statistics for Profiling @@ -179,10 +180,10 @@ struct smt_params : public preprocessor_params, // ----------------------------------- // - // Model generation + // Model generation // // ----------------------------------- - bool m_model; + bool m_model; bool m_model_compact; bool m_model_on_timeout; bool m_model_on_final_check; @@ -213,7 +214,7 @@ struct smt_params : public preprocessor_params, unsigned m_timeout; unsigned m_rlimit; bool m_at_labels_cex; // only use labels which contains the @ symbol when building multiple counterexamples. - bool m_check_at_labels; // check that @ labels are inserted to generate unique counter-examples. + bool m_check_at_labels; // check that @ labels are inserted to generate unique counter-examples. bool m_dump_goal_as_smt; bool m_auto_config; @@ -237,7 +238,7 @@ struct smt_params : public preprocessor_params, m_display_proof(false), m_display_dot_proof(false), m_display_unsat_core(false), - m_check_proof(false), + m_check_proof(false), m_eq_propagation(true), m_binary_clause_opt(true), m_relevancy_lvl(2), @@ -279,7 +280,7 @@ struct smt_params : public preprocessor_params, m_new_old_ratio(16), m_new_clause_activity(10), m_old_clause_activity(500), - m_new_clause_relevancy(45), + m_new_clause_relevancy(45), m_old_clause_relevancy(6), m_inv_clause_decay(1), m_smtlib_dump_lemmas(false), diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index daa408161..b966b8380 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -95,7 +95,7 @@ namespace smt { if (!relevancy()) m_fparams.m_relevancy_lemma = false; - + m_model_generator->set_context(this); } @@ -106,29 +106,29 @@ namespace smt { ast_manager& src_m = src_ctx.get_manager(); expr_ref dst_f(dst_m); - SASSERT(lit != false_literal && lit != true_literal); - bool_var v = b2v.get(lit.var(), null_bool_var); - if (v == null_bool_var) { - expr* e = src_ctx.m_bool_var2expr.get(lit.var(), 0); - SASSERT(e); - dst_f = tr(e); + SASSERT(lit != false_literal && lit != true_literal); + bool_var v = b2v.get(lit.var(), null_bool_var); + if (v == null_bool_var) { + expr* e = src_ctx.m_bool_var2expr.get(lit.var(), 0); + SASSERT(e); + dst_f = tr(e); v = dst_ctx.get_bool_var_of_id_option(dst_f->get_id()); - if (v != null_bool_var) { - } + if (v != null_bool_var) { + } else if (src_m.is_not(e) || src_m.is_and(e) || src_m.is_or(e) || - src_m.is_iff(e) || src_m.is_ite(e)) { - v = dst_ctx.mk_bool_var(dst_f); - } - else { - dst_ctx.internalize_formula(dst_f, false); - v = dst_ctx.get_bool_var(dst_f); - } - b2v.setx(lit.var(), v, null_bool_var); - } - return literal(v, lit.sign()); + src_m.is_iff(e) || src_m.is_ite(e)) { + v = dst_ctx.mk_bool_var(dst_f); + } + else { + dst_ctx.internalize_formula(dst_f, false); + v = dst_ctx.get_bool_var(dst_f); + } + b2v.setx(lit.var(), v, null_bool_var); + } + return literal(v, lit.sign()); } - bool context::get_cancel_flag() { + bool context::get_cancel_flag() { return !m_manager.limit().inc(); } @@ -137,12 +137,12 @@ namespace smt { ast_manager& dst_m = dst_ctx.get_manager(); ast_manager& src_m = src_ctx.get_manager(); src_ctx.pop_to_base_lvl(); - + if (src_ctx.m_base_lvl > 0) { throw default_exception("Cloning contexts within a user-scope is not allowed"); } SASSERT(src_ctx.m_base_lvl == 0); - + ast_translation tr(src_m, dst_m, false); dst_ctx.set_logic(src_ctx.m_setup.get_logic()); @@ -151,7 +151,7 @@ namespace smt { asserted_formulas& src_af = src_ctx.m_asserted_formulas; asserted_formulas& dst_af = dst_ctx.m_asserted_formulas; - // Copy asserted formulas. + // Copy asserted formulas. for (unsigned i = 0; i < src_af.get_num_formulas(); ++i) { expr_ref fml(dst_m); proof_ref pr(dst_m); @@ -160,7 +160,7 @@ namespace smt { if (pr_src) { pr = tr(pr_src); } - dst_af.assert_expr(fml, pr); + dst_af.assert_expr(fml, pr); } if (!src_ctx.m_setup.already_configured()) { @@ -191,7 +191,7 @@ namespace smt { lits.push_back(lit); } dst_ctx.mk_clause(lits.size(), lits.c_ptr(), 0, src_cls.get_kind(), 0); - } + } vector::const_iterator it = src_ctx.m_watches.begin(); vector::const_iterator end = src_ctx.m_watches.end(); literal ls[2]; @@ -207,12 +207,12 @@ namespace smt { ls[0] = TRANSLATE(neg_l1); ls[1] = TRANSLATE(l2); dst_ctx.mk_clause(2, ls, 0, CLS_AUX, 0); - } + } } } #endif - - TRACE("smt_context", + + TRACE("smt_context", src_ctx.display(tout); dst_ctx.display(tout);); } @@ -227,7 +227,7 @@ namespace smt { // copy missing simplifier_plugins // remark: some simplifier_plugins are automatically created by the asserted_formulas class. simplifier & src_s = src.get_simplifier(); - simplifier & dst_s = dst.get_simplifier(); + simplifier & dst_s = dst.get_simplifier(); ptr_vector::const_iterator it1 = src_s.begin_plugins(); ptr_vector::const_iterator end1 = src_s.end_plugins(); for (; it1 != end1; ++it1) { @@ -248,9 +248,9 @@ namespace smt { context * context::mk_fresh(symbol const * l, smt_params * p) { context * new_ctx = alloc(context, m_manager, p == 0 ? m_fparams : *p); new_ctx->set_logic(l == 0 ? m_setup.get_logic() : *l); - copy_plugins(*this, *new_ctx); + copy_plugins(*this, *new_ctx); return new_ctx; - } + } void context::init() { app * t = m_manager.mk_true(); @@ -299,9 +299,9 @@ namespace smt { d.set_justification(j); } - + void context::assign_core(literal l, b_justification j, bool decision) { - TRACE("assign_core", tout << (decision?"decision: ":"propagating: ") << l << " "; + TRACE("assign_core", tout << (decision?"decision: ":"propagating: ") << l << " "; display_literal_verbose(tout, l); tout << " level: " << m_scope_lvl << "\n"; display(tout, j);); m_assigned_literals.push_back(l); @@ -319,7 +319,7 @@ namespace smt { d.m_phase = !l.sign(); TRACE("phase_selection", tout << "saving phase, is_pos: " << d.m_phase << " l: " << l << "\n";); - TRACE("relevancy", + TRACE("relevancy", tout << "is_atom: " << d.is_atom() << " is relevant: " << is_relevant_core(l) << "\n";); if (d.is_atom() && (m_fparams.m_relevancy_lvl == 0 || (m_fparams.m_relevancy_lvl == 1 && !d.is_quantifier()) || is_relevant_core(l))) m_atom_propagation_queue.push_back(l); @@ -331,12 +331,12 @@ namespace smt { // a unit is asserted at search level. Mark it as relevant. // this addresses bug... where a literal becomes fixed to true (false) // as a conflict gets assigned misses relevancy (and quantifier instantiation). - // + // if (false && !decision && relevancy() && at_search_level() && !is_relevant_core(l)) { mark_as_relevant(l); } } - + bool context::bcp() { SASSERT(!inconsistent()); while (m_qhead < m_assigned_literals.size()) { @@ -385,17 +385,17 @@ namespace smt { cls->set_literal(0, cls->get_literal(1)); cls->set_literal(1, not_l); } - + SASSERT(cls->get_literal(1) == not_l); - - literal first_lit = cls->get_literal(0); + + literal first_lit = cls->get_literal(0); lbool first_lit_val = get_assignment(first_lit); - - if (first_lit_val == l_true) { - *it2 = *it; // clause is already satisfied, keep it + + if (first_lit_val == l_true) { + *it2 = *it; // clause is already satisfied, keep it it2++; } - else { + else { literal * it3 = cls->begin_literals() + 2; literal * end3 = cls->end_literals(); for(; it3 != end3; ++it3) { @@ -408,7 +408,7 @@ namespace smt { goto found_watch; } } - // did not find watch... + // did not find watch... if (first_lit_val == l_false) { // CONFLICT // copy remaining watches @@ -427,8 +427,8 @@ namespace smt { // PROPAGATION SASSERT(first_lit_val == l_undef); SASSERT(get_assignment(first_lit) == l_undef); - SASSERT(is_unit_clause(cls)); - *it2 = *it; + SASSERT(is_unit_clause(cls)); + *it2 = *it; it2++; // keep clause m_stats.m_num_propagations++; // It is safe to call assign_core instead of assign because first_lit is unassigned @@ -440,13 +440,13 @@ namespace smt { //if (!(m_manager.is_eq(e) && m_manager.get_sort(to_app(e)->get_arg(0))->get_family_id() == m_manager.get_family_id("array"))) mark_as_relevant(e); } - } - found_watch:; - } + } + found_watch:; + } } - SASSERT(it2 <= end); + SASSERT(it2 <= end); w.set_end_clause(it2); - } + } return true; } @@ -473,7 +473,7 @@ namespace smt { theory * t = get_theory(th); if (t->get_enode(lhs)->is_interpreted() && t->get_enode(rhs)->is_interpreted()) return; - TRACE("add_diseq", + TRACE("add_diseq", tout << "#" << t->get_enode(lhs)->get_owner_id() << " != " << "#" << t->get_enode(rhs)->get_owner_id() << "\n";); @@ -490,7 +490,7 @@ namespace smt { m_n1(n1), m_r2_num_parents(r2_num_parents) { } - + virtual void undo(context & ctx) { ctx.undo_add_eq(m_r1, m_n1, m_r2_num_parents); } @@ -506,27 +506,27 @@ namespace smt { TRACE("add_eq", tout << "assigning: #" << n1->get_owner_id() << " = #" << n2->get_owner_id() << "\n";); TRACE("add_eq_detail", tout << "assigning\n" << mk_pp(n1->get_owner(), m_manager) << "\n" << mk_pp(n2->get_owner(), m_manager) << "\n"; tout << "kind: " << js.get_kind() << "\n";); - + m_stats.m_num_add_eq++; enode * r1 = n1->get_root(); enode * r2 = n2->get_root(); - + if (r1 == r2) { TRACE("add_eq", tout << "redundant constraint.\n";); return; } - + if (r1->is_interpreted() && r2->is_interpreted()) { TRACE("add_eq", tout << "interpreted roots conflict.\n";); set_conflict(mk_justification(eq_conflict_justification(n1, n2, js))); return; } - + // Swap r1 and r2: // 1. if the "equivalence" class of r1 is bigger than the equivalence class of r2 // OR // 2. r1 is interpreted but r2 is not. - // + // // The second condition is used to enforce the invariant that if a class contain // an interepreted enode then the root is also interpreted. if ((r1->get_class_size() > r2->get_class_size() && !r2->is_interpreted()) || r1->is_interpreted()) { @@ -534,10 +534,10 @@ namespace smt { std::swap(n1, n2); std::swap(r1, r2); } - - TRACE("add_eq", tout << "merging: #" << r1->get_owner_id() << " #" << r2->get_owner_id() << + + TRACE("add_eq", tout << "merging: #" << r1->get_owner_id() << " #" << r2->get_owner_id() << " n1: #" << n1->get_owner_id() << "\n";); - + // It is necessary to propagate relevancy to other elements of // the equivalence class. This is nessary to enforce the invariant // in the field m_parent of the enode class. @@ -554,13 +554,13 @@ namespace smt { else if (is_relevant(r2)) { // && !m_manager.is_eq(r2->get_owner())) { // !is_eq HACK mark_as_relevant(r1); } - + push_trail(add_eq_trail(r1, n1, r2->get_num_parents())); - + m_qmanager->add_eq_eh(r1, r2); - + merge_theory_vars(n2, n1, js); - + // 'Proof' tree // n1 -> ... -> r1 // n2 -> ... -> r2 @@ -571,8 +571,8 @@ namespace smt { SASSERT(r1->trans_reaches(n1)); // --------------- // r1 -> .. -> n1 -> n2 -> ... -> r2 - - + + #if 0 { static unsigned counter = 0; @@ -584,35 +584,35 @@ namespace smt { num_bad_adds++; } if (num_adds % 100000 == 0) { - verbose_stream() << "[add-eq]: " << num_bad_adds << " " << num_adds << " " + verbose_stream() << "[add-eq]: " << num_bad_adds << " " << num_adds << " " << static_cast(num_bad_adds)/static_cast(num_adds) << "\n"; } } #endif - - + + remove_parents_from_cg_table(r1); - + enode * curr = r1; do { curr->m_root = r2; curr = curr->m_next; } while(curr != r1); - + SASSERT(r1->get_root() == r2); - + reinsert_parents_into_cg_table(r1, r2, n1, n2, js); - + if (n2->is_bool()) propagate_bool_enode_assignment(r1, r2, n1, n2); - + // Merge "equivalence" classes std::swap(r1->m_next, r2->m_next); - + // Update "equivalence" class size r2->m_class_size += r1->m_class_size; - + CASSERT("add_eq", check_invariant()); } catch (...) { @@ -642,12 +642,12 @@ namespace smt { num_eqs++; num_parents++; if (num_parents % 100000 == 0) { - verbose_stream() << "[remove-cg] " << num_eqs << " " << num_parents << " " + verbose_stream() << "[remove-cg] " << num_eqs << " " << num_parents << " " << static_cast(num_eqs)/static_cast(num_parents) << "\n"; } } #endif - SASSERT(parent->is_marked() || !parent->is_cgc_enabled() || + SASSERT(parent->is_marked() || !parent->is_cgc_enabled() || (!parent->is_true_eq() && parent->is_cgr() == m_cg_table.contains_ptr(parent)) || (parent->is_true_eq() && !m_cg_table.contains_ptr(parent))); if (!parent->is_marked() && parent->is_cgr() && !parent->is_true_eq()) { @@ -667,12 +667,12 @@ namespace smt { cg_table at remove_parents_from_cg_table. Some of these parents will become congruent to other enodes, and a new equality will be propagated. Moreover, this method is also used for doing equality propagation. - + The parents of r1 that remain as congruence roots are copied to the r2->m_parents. The n1, n2, js arguments are used to implement dynamic ackermanization. - js is a justification for n1 and n2 being equal, and the equality n1 = n2 is + js is a justification for n1 and n2 being equal, and the equality n1 = n2 is the one that implied r1 = r2. */ void context::reinsert_parents_into_cg_table(enode * r1, enode * r2, enode * n1, enode * n2, eq_justification js) { @@ -737,7 +737,7 @@ namespace smt { the following sequence starting at n and ending at n->get_root. - N1 = n + N1 = n N_{i+1} = N_i->m_trans.m_target and, there is an k such that N_k = n->get_root() @@ -768,12 +768,12 @@ namespace smt { This method is used to improve the quality of the conflict clauses produced by the logical context. - + Consider the following example: - Consider the following sequence of equalities: n1 = n2 = n3 = n4 = n5 = n6 - + - Now, assume that n1 is the root of the equivalence class after each merge. So, the 'proof' branch will have the following shape: @@ -782,12 +782,12 @@ namespace smt { - Assuming that all nodes are attached to theory variable, then the following sequence of equalities is sent to the theory if the method get_closest_var is not used: - + n1 = n2, n1 = n3, n1 = n4, n1 = n5, n1 = n6 - This sequence is bad, and bad justifications may be produced by theory. For example, assume the following arithmetic constraint - + n5 < n6 For the arithmetic module, the best justification will be: @@ -798,7 +798,7 @@ namespace smt { When the method get_closest_var is used in the communication with theories, the logical context will send the natural sequence of equalities to the theories: - + n1 = n2 = n3 = n4 = n5 = n6 */ theory_var context::get_closest_var(enode * n, theory_id th_id) { @@ -816,7 +816,7 @@ namespace smt { /** \brief Merge the theory variables of n2->get_root() and n1->get_root(), the result is stored in n2->get_root(). New th_var equalities are propagated to the theories. - + \remark In most cases, an enode is attached to at most one theory var. */ void context::merge_theory_vars(enode * n2, enode * n1, eq_justification js) { @@ -826,7 +826,7 @@ namespace smt { TRACE("merge_theory_vars", tout << "Neither have theory vars #" << n1->get_owner()->get_id() << " #" << n2->get_owner()->get_id() << "\n";); return; } - + theory_id from_th = null_theory_id; if (js.get_kind() == eq_justification::JUSTIFICATION) @@ -839,8 +839,8 @@ namespace smt { // verbose_stream() << "[merge_theory_vars] t2: " << t2 << ", t1: " << t1 << "\n"; theory_var v2 = m_fparams.m_new_core2th_eq ? get_closest_var(n2, t2) : r2->m_th_var_list.get_th_var(); theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : r1->m_th_var_list.get_th_var(); - TRACE("merge_theory_vars", - tout << "v2: " << v2 << " #" << r2->get_owner_id() << ", v1: " << v1 << " #" << r1->get_owner_id() + TRACE("merge_theory_vars", + tout << "v2: " << v2 << " #" << r2->get_owner_id() << ", v1: " << v1 << " #" << r1->get_owner_id() << ", t2: " << t2 << ", t1: " << t1 << "\n";); if (v2 != null_theory_var && v1 != null_theory_var) { if (t1 == t2) { @@ -867,7 +867,7 @@ namespace smt { } else { // r1 and/or r2 have more than one theory variable. - TRACE("merge_theory_vars", + TRACE("merge_theory_vars", tout << "#" << r1->get_owner_id() << " == #" << r2->get_owner_id() << "\n";); @@ -889,7 +889,7 @@ namespace smt { } l2 = l2->get_next(); } - + theory_var_list * l1 = r1->get_th_var_list(); while (l1) { theory_id t1 = l1->get_th_id(); @@ -905,7 +905,7 @@ namespace smt { } } } - + /** \brief Propabate the boolean assignment when two equivalence classes are merged. */ @@ -959,7 +959,7 @@ namespace smt { bool_var v2 = enode2bool_var(target); lbool val2 = get_assignment(v2); if (val2 != val) { - if (val2 != l_undef && congruent(source, target) && source->get_num_args() > 0) + if (val2 != l_undef && congruent(source, target) && source->get_num_args() > 0) m_dyn_ack_manager.cg_conflict_eh(source->get_owner(), target->get_owner()); assign(literal(v2, sign), mk_justification(mp_iff_justification(source, target))); } @@ -986,7 +986,7 @@ namespace smt { enode * parent = *it; if (parent->is_cgc_enabled()) { TRACE("add_eq_parents", tout << "removing: #" << parent->get_owner_id() << "\n";); - CTRACE("add_eq", !parent->is_cgr(), + CTRACE("add_eq", !parent->is_cgr(), tout << "old num_parents: " << r2_num_parents << ", num_parents: " << r2->m_parents.size() << ", parent: #" << parent->get_owner_id() << ", parents: \n"; for (unsigned i = 0; i < r2->m_parents.size(); i++) { @@ -1017,10 +1017,10 @@ namespace smt { TRACE("add_eq_parents", tout << "visiting: #" << parent->get_owner_id() << "\n";); if (parent->is_cgc_enabled()) { enode * cg = parent->m_cg; - if (!parent->is_true_eq() && + if (!parent->is_true_eq() && (parent == cg || // parent was root of the congruence class before and after the merge !congruent(parent, cg) // parent was root of the congruence class before but not after the merge - )) { + )) { TRACE("add_eq_parents", tout << "trying to reinsert\n";); m_cg_table.insert(parent); parent->m_cg = parent; @@ -1057,17 +1057,17 @@ namespace smt { // n2 -> ... -> r2 SASSERT(n1->trans_reaches(r1)); SASSERT(r1->m_trans.m_target == 0); - + CASSERT("add_eq", check_invariant()); } /** - \brief Auxiliary method for undo_add_eq. + \brief Auxiliary method for undo_add_eq. It restores the theory variables of a given root enode. This method deletes any theory variable v2 of r2 (for a theory t2) whenever: - get_theory(t2)->get_enode(v2)->get_root() != r2 + get_theory(t2)->get_enode(v2)->get_root() != r2 That is, v2 is not equivalent to r2 anymore. */ @@ -1078,7 +1078,7 @@ namespace smt { while (l2) { theory_var v2 = l2->get_th_var(); theory_id t2 = l2->get_th_id(); - + if (get_theory(t2)->get_enode(v2)->get_root() != r2) { SASSERT(get_theory(t2)->get_enode(v2)->get_root() == r1); l2 = l2->get_next(); @@ -1122,7 +1122,7 @@ namespace smt { #ifdef Z3DEBUG push_trail(push_back_trail(m_diseq_vector)); m_diseq_vector.push_back(enode_pair(n1, n2)); -#endif +#endif if (r1 == r2) { TRACE("add_diseq_inconsistent", tout << "add_diseq #" << n1->get_owner_id() << " #" << n2->get_owner_id() << " inconsistency, scope_lvl: " << m_scope_lvl << "\n";); @@ -1166,7 +1166,7 @@ namespace smt { } return true; } - + /** \brief Return true if n1 and n2 are known to be disequal in the logical context. @@ -1215,7 +1215,7 @@ namespace smt { if (parent->is_eq() && is_relevant(parent->get_owner()) && get_assignment(enode2bool_var(parent)) == l_false && ((parent->get_arg(0)->get_root() == n1->get_root() && parent->get_arg(1)->get_root() == n2->get_root()) || (parent->get_arg(1)->get_root() == n1->get_root() && parent->get_arg(0)->get_root() == n2->get_root()))) { - TRACE("is_diseq_bug", tout << "parent: #" << parent->get_owner_id() << ", parent->root: #" << + TRACE("is_diseq_bug", tout << "parent: #" << parent->get_owner_id() << ", parent->root: #" << parent->get_root()->get_owner_id() << " assignment(parent): " << get_assignment(enode2bool_var(parent)) << " args: #" << parent->get_arg(0)->get_owner_id() << " #" << parent->get_arg(1)->get_owner_id() << "\n";); return true; @@ -1274,7 +1274,7 @@ namespace smt { enode * arg2 = p2->get_arg(j)->get_root(); if (arg1 == arg2) continue; - if ((arg1 == r1 || arg1 == r2) && + if ((arg1 == r1 || arg1 == r2) && (arg2 == r1 || arg2 == r2)) continue; break; @@ -1353,8 +1353,8 @@ namespace smt { expr * arg = r->get_owner()->get_arg(i); SASSERT(e_internalized(arg)); enode * _arg = get_enode(arg); - CTRACE("eq_to_bug", args[i]->get_root() != _arg->get_root(), - tout << "#" << args[i]->get_owner_id() << " #" << args[i]->get_root()->get_owner_id() + CTRACE("eq_to_bug", args[i]->get_root() != _arg->get_root(), + tout << "#" << args[i]->get_owner_id() << " #" << args[i]->get_root()->get_owner_id() << " #" << _arg->get_owner_id() << " #" << _arg->get_root()->get_owner_id() << "\n"; tout << "#" << r->get_owner_id() << "\n"; display(tout);); @@ -1367,8 +1367,8 @@ namespace smt { } /** - \brief Process the equality propagation queue. - + \brief Process the equality propagation queue. + \remark The method assign_eq adds a new entry on this queue. */ bool context::propagate_eqs() { @@ -1385,7 +1385,7 @@ namespace smt { std::cout << counter1 << " " << counter2 << "\n"; #endif add_eq(entry.m_lhs, entry.m_rhs, entry.m_justification); - if (inconsistent()) + if (inconsistent()) return false; } m_eq_propagation_queue.reset(); @@ -1403,7 +1403,7 @@ namespace smt { bool_var v = l.var(); bool_var_data & d = get_bdata(v); lbool val = get_assignment(v); - TRACE("propagate_atoms", tout << "propagating atom, #" << bool_var2expr(v)->get_id() << ", is_enode(): " << d.is_enode() + TRACE("propagate_atoms", tout << "propagating atom, #" << bool_var2expr(v)->get_id() << ", is_enode(): " << d.is_enode() << " tag: " << (d.is_eq()?"eq":"") << (d.is_theory_atom()?"th":"") << (d.is_quantifier()?"q":"") << " " << l << "\n";); SASSERT(val != l_undef); if (d.is_enode()) @@ -1435,7 +1435,7 @@ namespace smt { // Remark: when RELEVANCY_LEMMA is true, a quantifier can be asserted to false and marked as relevant. // This happens when a quantifier is part of a lemma (conflict-clause), and this conflict clause // becomes an unit-clause and the remaining literal is the negation of a quantifier. - CTRACE("assign_quantifier_bug", get_assignment(v) != l_true, + CTRACE("assign_quantifier_bug", get_assignment(v) != l_true, tout << "#" << bool_var2expr(v)->get_id() << " val: " << get_assignment(v) << "\n"; tout << mk_pp(bool_var2expr(v), m_manager) << "\n"; display(tout);); @@ -1562,7 +1562,7 @@ namespace smt { /** \brief Return the truth assignment for an expression that is attached to a boolean variable. - + \pre The expression must be attached to a boolean variable. */ inline lbool context::get_assignment_core(expr * n) const { @@ -1582,7 +1582,7 @@ namespace smt { lbool context::get_assignment(expr * n) const { if (m_manager.is_false(n)) return l_false; - if (m_manager.is_not(n)) + if (m_manager.is_not(n)) return ~get_assignment_core(to_app(n)->get_arg(0)); return get_assignment_core(n); } @@ -1621,14 +1621,14 @@ namespace smt { */ void context::get_assignments(expr_ref_vector& assignments) { literal_vector::const_iterator it = m_assigned_literals.begin(); - literal_vector::const_iterator end = m_assigned_literals.end(); + literal_vector::const_iterator end = m_assigned_literals.end(); for (; it != end; ++it) { expr_ref e(m_manager); literal2expr(*it, e); assignments.push_back(e); } } - + void context::relevant_eh(expr * n) { if (b_internalized(n)) { bool_var v = get_bool_var(n); @@ -1646,7 +1646,7 @@ namespace smt { #ifndef SMTCOMP m_case_split_queue->relevant_eh(n); #endif - + if (is_app(n)) { if (e_internalized(n)) { SASSERT(relevancy()); @@ -1663,15 +1663,15 @@ namespace smt { propagated_th = th; // <<< mark that relevancy_eh was already invoked for theory th. } } - + if (e_internalized(n)) { - enode * e = get_enode(n); + enode * e = get_enode(n); theory_var_list * l = e->get_th_var_list(); while (l) { theory_id th_id = l->get_th_id(); theory * th = get_theory(th_id); // I don't want to invoke relevant_eh twice for the same n. - if (th != propagated_th) + if (th != propagated_th) th->relevant_eh(to_app(n)); l = l->get_next(); } @@ -1749,7 +1749,7 @@ namespace smt { } bool context::can_propagate() const { - return + return m_qhead != m_assigned_literals.size() || m_relevancy_propagator->can_propagate() || !m_atom_propagation_queue.empty() || @@ -1776,7 +1776,7 @@ namespace smt { } SASSERT(!inconsistent()); propagate_relevancy(qhead); - if (inconsistent()) + if (inconsistent()) return false; if (!propagate_atoms()) return false; @@ -1784,7 +1784,7 @@ namespace smt { return false; propagate_th_eqs(); propagate_th_diseqs(); - if (inconsistent()) + if (inconsistent()) return false; if (!propagate_theories()) return false; @@ -1820,11 +1820,11 @@ namespace smt { return m_fingerprints.contains(q, q->get_id(), num_bindings, bindings); } - bool context::add_instance(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation, + bool context::add_instance(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation, unsigned min_top_generation, unsigned max_top_generation, ptr_vector & used_enodes) { return m_qmanager->add_instance(q, pat, num_bindings, bindings, max_generation, min_top_generation, max_top_generation, used_enodes); } - + void context::rescale_bool_var_activity() { TRACE("case_split", tout << "rescale\n";); svector::iterator it = m_activity.begin(); @@ -1851,15 +1851,15 @@ namespace smt { static unsigned counter = 0; counter++; if (counter % 100 == 0) { - TRACE("activity_profile", + TRACE("activity_profile", for (unsigned i=0; i m_lit_occs[(~l).index()].size(); + is_pos = m_lit_occs[l.index()].size() > m_lit_occs[(~l).index()].size(); break; } default: @@ -1972,7 +1972,7 @@ namespace smt { m_fingerprints.push_scope(); m_case_split_queue->push_scope(); m_asserted_formulas.push_scope(); - + ptr_vector::iterator it = m_theory_set.begin(); ptr_vector::iterator end = m_theory_set.end(); for (; it != end; ++it) @@ -1989,7 +1989,7 @@ namespace smt { /** \brief Remove watch literal idx from the given clause. - + \pre idx must be 0 or 1. */ void context::remove_watch_literal(clause * cls, unsigned idx) { @@ -2015,13 +2015,13 @@ namespace smt { } /** - \brief Delete the given clause. - + \brief Delete the given clause. + \pre Clause is not in the reinit stack. */ void context::del_clause(clause * cls) { SASSERT(m_flushing || !cls->in_reinit_stack()); - if (!cls->deleted()) + if (!cls->deleted()) remove_cls_occs(cls); cls->deallocate(m_manager); m_stats.m_num_del_clause++; @@ -2067,7 +2067,7 @@ namespace smt { d.set_null_justification(); m_case_split_queue->unassign_var_eh(v); } - + m_assigned_literals.shrink(old_lim); m_qhead = old_lim; SASSERT(m_qhead == m_assigned_literals.size()); @@ -2137,8 +2137,8 @@ namespace smt { /** \brief When a clause is reinitialized (see reinit_clauses) enodes and literals may need to be recreated. When an enode is recreated, I want to use the same generation - number it had before being deleted. Otherwise the generation will be 0, and will affect - the loop prevetion heuristics used to control quantifier instantiation. + number it had before being deleted. Otherwise the generation will be 0, and will affect + the loop prevetion heuristics used to control quantifier instantiation. Thus, I cache the generation number of enodes that will be deleted during backtracking and recreated by reinit_clauses. */ @@ -2184,11 +2184,11 @@ namespace smt { for(unsigned i = 0; i < num_lits; i++) { bool_var v = lits[i].var(); unsigned ilvl = get_intern_level(v); - if (ilvl > new_scope_lvl) + if (ilvl > new_scope_lvl) cache_generation(bool_var2expr(v), new_scope_lvl); } } - + /** \brief See cache_generation(unsigned new_scope_lvl) */ @@ -2223,7 +2223,7 @@ namespace smt { } } } - + /** \brief See cache_generation(unsigned new_scope_lvl) */ @@ -2235,7 +2235,7 @@ namespace smt { /** \brief Reinitialize learned clauses (lemmas) that contain boolean variables that were deleted during backtracking. - + \remark num_bool_vars contains the number of boolean variables alive after backtracking. So, a clause contains a dead variable if it contains a literal l where l.var() >= num_bool_vars. @@ -2290,20 +2290,20 @@ namespace smt { } } } - + unsigned ilvl = 0; (void)ilvl; for (unsigned j = 0; j < num; j++) { expr * atom = cls->get_atom(j); bool sign = cls->get_atom_sign(j); - // Atom can be (NOT foo). This can happen, for example, when + // Atom can be (NOT foo). This can happen, for example, when // the NOT-application is a child of an uninterpreted function symbol. // So, when reinternalizing the NOT-atom I should set the gate_ctx to false, // and force expression to be reinternalized. // Otherwise I set gate_ctx to true bool gate_ctx = !m_manager.is_not(atom); internalize(atom, gate_ctx); - SASSERT(b_internalized(atom)); + SASSERT(b_internalized(atom)); bool_var v = get_bool_var(atom); DEBUG_CODE({ if (get_intern_level(v) > ilvl) @@ -2322,7 +2322,7 @@ namespace smt { if (lit_occs_enabled()) add_lit_occs(cls); - + literal l1 = cls->get_literal(0); literal l2 = cls->get_literal(1); @@ -2330,9 +2330,9 @@ namespace smt { set_conflict(b_justification(cls)); else if (get_assignment(l2) == l_false) assign(l1, b_justification(cls)); - + TRACE("reinit_clauses", tout << "reinit clause:\n"; display_clause_detail(tout, cls); tout << "\n"; - tout << "activity: " << cls->get_activity() << ", num_bool_vars: " << num_bool_vars << ", scope_lvl: " + tout << "activity: " << cls->get_activity() << ", num_bool_vars: " << num_bool_vars << ", scope_lvl: " << m_scope_lvl << "\n";); keep = true; } @@ -2349,8 +2349,8 @@ namespace smt { keep = true; } } - - // SASSERT(!(cls->get_num_literals() == 3 && + + // SASSERT(!(cls->get_num_literals() == 3 && // (cls->get_literal(0).index() == 624 || cls->get_literal(0).index() == 103 || cls->get_literal(0).index() == 629) && // (cls->get_literal(1).index() == 624 || cls->get_literal(1).index() == 103 || cls->get_literal(1).index() == 629) && // (cls->get_literal(2).index() == 624 || cls->get_literal(2).index() == 103 || cls->get_literal(2).index() == 629))); @@ -2398,7 +2398,7 @@ namespace smt { of boolean variables before reinitializing clauses. This value is useful because it can be used to detect which boolean variables were deleted. - + \warning This method will not invoke reset_cache_generation. */ unsigned context::pop_scope_core(unsigned num_scopes) { @@ -2406,25 +2406,25 @@ namespace smt { try { if (m_manager.has_trace_stream()) m_manager.trace_stream() << "[pop] " << num_scopes << " " << m_scope_lvl << "\n"; - + TRACE("context", tout << "backtracking: " << num_scopes << " from " << m_scope_lvl << "\n";); TRACE("pop_scope_detail", display(tout);); SASSERT(num_scopes > 0); SASSERT(num_scopes <= m_scope_lvl); SASSERT(m_scopes.size() == m_scope_lvl); - + unsigned new_lvl = m_scope_lvl - num_scopes; - + cache_generation(new_lvl); m_qmanager->pop(num_scopes); m_case_split_queue->pop_scope(num_scopes); - + TRACE("pop_scope", tout << "backtracking: " << num_scopes << ", new_lvl: " << new_lvl << "\n";); scope & s = m_scopes[new_lvl]; TRACE("context", tout << "backtracking new_lvl: " << new_lvl << "\n";); - + unsigned units_to_reassert_lim = s.m_units_to_reassert_lim; - + if (new_lvl < m_base_lvl) { base_scope & bs = m_base_scopes[new_lvl]; del_clauses(m_lemmas, bs.m_lemmas_lim); @@ -2441,35 +2441,35 @@ namespace smt { m_not_l = null_literal; } del_clauses(m_aux_clauses, s.m_aux_clauses_lim); - + m_relevancy_propagator->pop(num_scopes); - + m_fingerprints.pop_scope(num_scopes); unassign_vars(s.m_assigned_literals_lim); undo_trail_stack(s.m_trail_stack_lim); - + for (theory* th : m_theory_set) { th->pop_scope_eh(num_scopes); } - + del_justifications(m_justifications, s.m_justifications_lim); - + m_asserted_formulas.pop_scope(num_scopes); - + m_eq_propagation_queue.reset(); m_th_eq_propagation_queue.reset(); m_th_diseq_propagation_queue.reset(); m_atom_propagation_queue.reset(); - + m_region.pop_scope(num_scopes); m_scopes.shrink(new_lvl); - + m_scope_lvl = new_lvl; if (new_lvl < m_base_lvl) { m_base_lvl = new_lvl; m_search_lvl = new_lvl; // Remark: not really necessary } - + unsigned num_bool_vars = get_num_bool_vars(); // any variable >= num_bool_vars was deleted during backtracking. reinit_clauses(num_scopes, num_bool_vars); @@ -2516,32 +2516,32 @@ namespace smt { bool context::simplify_clause(clause * cls) { SASSERT(m_scope_lvl == m_base_lvl); unsigned s = cls->get_num_literals(); - if (get_assignment(cls->get_literal(0)) == l_true || + if (get_assignment(cls->get_literal(0)) == l_true || get_assignment(cls->get_literal(1)) == l_true) { // clause is already satisfied. - return true; + return true; } - + literal_buffer simp_lits; unsigned i = 2; - unsigned j = i; - for(; i < s; i++) { + unsigned j = i; + for(; i < s; i++) { literal l = cls->get_literal(i); switch(get_assignment(l)) { - case l_false: - if (m_manager.proofs_enabled()) + case l_false: + if (m_manager.proofs_enabled()) simp_lits.push_back(~l); - if (lit_occs_enabled()) + if (lit_occs_enabled()) m_lit_occs[l.index()].erase(cls); break; - case l_undef: + case l_undef: cls->set_literal(j, l); j++; break; - case l_true: + case l_true: return true; - } + } } if (j < s) { @@ -2554,15 +2554,15 @@ namespace smt { justification * js = cls->get_justification(); justification * new_js = 0; if (js->in_region()) - new_js = mk_justification(unit_resolution_justification(m_region, - js, + new_js = mk_justification(unit_resolution_justification(m_region, + js, simp_lits.size(), simp_lits.c_ptr())); else new_js = alloc(unit_resolution_justification, js, simp_lits.size(), simp_lits.c_ptr()); cls->set_justification(new_js); } - return false; + return false; } /** @@ -2598,7 +2598,7 @@ namespace smt { SASSERT(m_search_lvl == m_base_lvl); literal_buffer simp_lits; unsigned num_lits = cls->get_num_literals(); - for(unsigned i = 0; i < num_lits; i++) { + for(unsigned i = 0; i < num_lits; i++) { if (i != idx) { literal l = cls->get_literal(i); SASSERT(l != l0); @@ -2610,13 +2610,13 @@ namespace smt { if (!cls_js || cls_js->in_region()) { // If cls_js is 0 or is allocated in a region, then // we can allocate the new justification in a region too. - js = mk_justification(unit_resolution_justification(m_region, + js = mk_justification(unit_resolution_justification(m_region, cls_js, simp_lits.size(), - simp_lits.c_ptr())); + simp_lits.c_ptr())); } else { - js = alloc(unit_resolution_justification, cls_js, simp_lits.size(), simp_lits.c_ptr()); + js = alloc(unit_resolution_justification, cls_js, simp_lits.size(), simp_lits.c_ptr()); // js took ownership of the justification object. cls->set_justification(0); m_justifications.push_back(js); @@ -2648,7 +2648,7 @@ namespace smt { // Remark: when assumptions are used m_scope_lvl >= m_search_lvl > m_base_lvl. Therefore, no simplification is performed. if (m_scope_lvl > m_base_lvl) return; - + unsigned sz = m_assigned_literals.size(); SASSERT(m_simp_qhead <= sz); @@ -2678,7 +2678,7 @@ namespace smt { // a variable during propagation. // m_simp_counter = 0; - // the field m_simp_qhead is used to check whether there are + // the field m_simp_qhead is used to check whether there are // new assigned literals at the base level. m_simp_qhead = m_assigned_literals.size(); @@ -2709,13 +2709,15 @@ namespace smt { \brief Delete low activity lemmas */ inline void context::del_inactive_lemmas() { - if (m_fparams.m_lemma_gc_half) + if (m_fparams.m_lemma_gc_strategy == LGC_NONE) + return; + else if (m_fparams.m_lemma_gc_half) del_inactive_lemmas1(); else del_inactive_lemmas2(); m_num_conflicts_since_lemma_gc = 0; - if (m_fparams.m_lemma_gc_strategy == LGC_GEOMETRIC) + if (m_fparams.m_lemma_gc_strategy == LGC_GEOMETRIC) m_lemma_gc_threshold = static_cast(m_lemma_gc_threshold * m_fparams.m_lemma_gc_factor); } @@ -2737,12 +2739,12 @@ namespace smt { unsigned i = start_del_at; unsigned j = i; unsigned num_del_cls = 0; - TRACE("del_inactive_lemmas", tout << "sz: " << sz << ", start_at: " << start_at << ", end_at: " << end_at + TRACE("del_inactive_lemmas", tout << "sz: " << sz << ", start_at: " << start_at << ", end_at: " << end_at << ", start_del_at: " << start_del_at << "\n";); for (; i < end_at; i++) { clause * cls = m_lemmas[i]; if (can_delete(cls)) { - TRACE("del_inactive_lemmas", tout << "deleting: "; display_clause(tout, cls); tout << ", activity: " << + TRACE("del_inactive_lemmas", tout << "deleting: "; display_clause(tout, cls); tout << ", activity: " << cls->get_activity() << "\n";); del_clause(cls); num_del_cls++; @@ -2763,7 +2765,7 @@ namespace smt { m_lemmas[j] = cls; j++; } - } + } m_lemmas.shrink(j); if (m_fparams.m_clause_decay > 1) { // rescale activity @@ -2805,7 +2807,7 @@ namespace smt { } // A clause is deleted if it has low activity and the number of unknowns is greater than a threshold. // The activity threshold depends on how old the clause is. - unsigned act_threshold = m_fparams.m_old_clause_activity - + unsigned act_threshold = m_fparams.m_old_clause_activity - (m_fparams.m_old_clause_activity - m_fparams.m_new_clause_activity) * ((i - start_at) / real_sz); if (cls->get_activity() < act_threshold) { unsigned rel_threshold = (i >= new_first_idx ? m_fparams.m_new_clause_relevancy : m_fparams.m_old_clause_relevancy); @@ -2843,10 +2845,10 @@ namespace smt { return false; } - void context::register_plugin(simplifier_plugin * s) { + void context::register_plugin(simplifier_plugin * s) { SASSERT(!already_internalized()); SASSERT(m_scope_lvl == 0); - m_asserted_formulas.register_simplifier_plugin(s); + m_asserted_formulas.register_simplifier_plugin(s); } #ifdef Z3DEBUG @@ -2873,7 +2875,7 @@ namespace smt { } #endif - void context::register_plugin(theory * th) { + void context::register_plugin(theory * th) { if (m_theories.get_plugin(th->get_family_id()) != 0) { dealloc(th); return; // context already has a theory for the given family id. @@ -2881,7 +2883,7 @@ namespace smt { SASSERT(std::find(m_theory_set.begin(), m_theory_set.end(), th) == m_theory_set.end()); SASSERT(!already_internalized_theory(th)); th->init(this); - m_theories.register_plugin(th); + m_theories.register_plugin(th); m_theory_set.push_back(th); { #ifdef Z3DEBUG @@ -2933,18 +2935,18 @@ namespace smt { ptr_vector::iterator it = m_theory_set.begin(); ptr_vector::iterator end = m_theory_set.end(); for (; it != end; ++it) - (*it)->flush_eh(); + (*it)->flush_eh(); undo_trail_stack(0); m_qmanager = 0; del_clauses(m_aux_clauses, 0); del_clauses(m_lemmas, 0); del_justifications(m_justifications, 0); - if (m_is_diseq_tmp) { + if (m_is_diseq_tmp) { m_is_diseq_tmp->del_eh(m_manager, false); - m_manager.dec_ref(m_is_diseq_tmp->get_owner()); + m_manager.dec_ref(m_is_diseq_tmp->get_owner()); enode::del_dummy(m_is_diseq_tmp); - m_is_diseq_tmp = 0; - } + m_is_diseq_tmp = 0; + } std::for_each(m_almost_cg_tables.begin(), m_almost_cg_tables.end(), delete_proc()); } @@ -3042,7 +3044,7 @@ namespace smt { // not counting any literals that get assigned by this method // this relies on bcp() to give us its old m_qhead and therefore // bcp() should always be called before this method - + unsigned assigned_literal_end = m_assigned_literals.size(); for (; qhead < assigned_literal_end; ++qhead) { literal l = m_assigned_literals[qhead]; @@ -3129,7 +3131,7 @@ namespace smt { return true; if (m.is_not(assumption, arg) && is_uninterp_const(arg)) return true; - if (!is_app(assumption)) + if (!is_app(assumption)) return false; if (to_app(assumption)->get_num_args() == 0) return true; @@ -3146,7 +3148,7 @@ namespace smt { SASSERT(assumptions[i]); if (!is_valid_assumption(m_manager, assumptions[i])) { warning_msg("an assumption must be a propositional variable or the negation of one"); - return false; + return false; } } return true; @@ -3158,11 +3160,11 @@ namespace smt { m_unsat_core.reset(); if (num_assumptions > 0) { // We must give a chance to the theories to propagate before we create a new scope... - propagate(); + propagate(); // Internal backtracking scopes (created with push_scope()) must only be created when we are // in a consistent context. if (inconsistent()) - return; + return; if (get_cancel_flag()) return; push_scope(); @@ -3270,9 +3272,9 @@ namespace smt { /** \brief Setup the logical context based on the current set of asserted formulas and execute the check command. - + \remark A logical context can only be configured at scope level 0, - and before internalizing any formulas. + and before internalizing any formulas. */ lbool context::setup_and_check(bool reset_cancel) { if (!check_preamble(reset_cancel)) @@ -3371,7 +3373,7 @@ namespace smt { expr_ref_vector all_assumptions(m_manager, ext_num_assumptions, ext_assumptions); if (!already_did_theory_assumptions) { - add_theory_assumptions(all_assumptions); + add_theory_assumptions(all_assumptions); } unsigned num_assumptions = all_assumptions.size(); @@ -3484,7 +3486,7 @@ namespace smt { lbool context::search() { -#ifndef _EXTERNAL_RELEASE +#ifndef _EXTERNAL_RELEASE if (m_fparams.m_abort_after_preproc) { exit(1); } @@ -3507,16 +3509,16 @@ namespace smt { status = bounded_search(); TRACE("search_bug", tout << "status: " << status << ", inconsistent: " << inconsistent() << "\n";); - TRACE("assigned_literals_per_lvl", display_num_assigned_literals_per_lvl(tout); + TRACE("assigned_literals_per_lvl", display_num_assigned_literals_per_lvl(tout); tout << ", num_assigned: " << m_assigned_literals.size() << "\n";); - + if (!restart(status, curr_lvl)) { break; } } - + TRACE("search_lite", tout << "status: " << status << "\n";); - TRACE("guessed_literals", + TRACE("guessed_literals", expr_ref_vector guessed_lits(m_manager); get_guessed_literals(guessed_lits); unsigned sz = guessed_lits.size(); @@ -3547,7 +3549,7 @@ namespace smt { // possible outcomes DONE l_true, DONE l_undef, CONTINUE quantifier_manager::check_model_result cmr = m_qmanager->check_model(m_proto_model.get(), m_model_generator->get_root2value()); if (cmr == quantifier_manager::SAT) { - // done + // done status = l_true; return false; } @@ -3562,7 +3564,7 @@ namespace smt { inc_limits(); if (status == l_true || !m_fparams.m_restart_adaptive || m_agility < m_fparams.m_restart_agility_threshold) { SASSERT(!inconsistent()); - IF_VERBOSE(2, verbose_stream() << "(smt.restarting :propagations " << m_stats.m_num_propagations + IF_VERBOSE(2, verbose_stream() << "(smt.restarting :propagations " << m_stats.m_num_propagations << " :decisions " << m_stats.m_num_decisions << " :conflicts " << m_stats.m_num_conflicts << " :restart " << m_restart_threshold; if (m_fparams.m_restart_strategy == RS_IN_OUT_GEOMETRIC) { @@ -3582,9 +3584,9 @@ namespace smt { ptr_vector::iterator end = m_theory_set.end(); for (; it != end && !inconsistent(); ++it) (*it)->restart_eh(); - TRACE("mbqi_bug_detail", tout << "before instantiating quantifiers...\n";); + TRACE("mbqi_bug_detail", tout << "before instantiating quantifiers...\n";); if (!inconsistent()) { - m_qmanager->restart_eh(); + m_qmanager->restart_eh(); } if (inconsistent()) { VERIFY(!resolve_conflict()); @@ -3600,7 +3602,7 @@ namespace smt { status = l_undef; return true; } - + void context::tick(unsigned & counter) const { counter++; if (counter > m_fparams.m_tick) { @@ -3617,7 +3619,7 @@ namespace smt { lbool context::bounded_search() { unsigned counter = 0; - + TRACE("bounded_search", tout << "starting bounded search...\n";); while (true) { @@ -3636,14 +3638,14 @@ namespace smt { return l_false; SASSERT(m_scope_lvl >= m_base_lvl); - + if (!inconsistent()) { if (resource_limits_exceeded()) return l_undef; if (get_cancel_flag()) return l_undef; - + if (m_num_conflicts_since_restart > m_restart_threshold && m_scope_lvl - m_base_lvl > 2) { TRACE("search_bug", tout << "bounded-search return undef, inconsistent: " << inconsistent() << "\n";); return l_undef; // restart @@ -3664,7 +3666,7 @@ namespace smt { m_dyn_ack_manager.propagate_eh(); CASSERT("dyn_ack", check_clauses(m_lemmas) && check_clauses(m_aux_clauses)); } - + if (resource_limits_exceeded() && !inconsistent()) { return l_undef; } @@ -3674,7 +3676,7 @@ namespace smt { if (m_base_lvl == m_scope_lvl && m_fparams.m_simplify_clauses) simplify_clauses(); - + if (!decide()) { final_check_status fcs = final_check(); TRACE("final_check_result", tout << "fcs: " << fcs << " last_search_failure: " << m_last_search_failure << "\n";); @@ -3697,11 +3699,11 @@ namespace smt { bool context::resource_limits_exceeded() { if (m_searching) { - // Some of the flags only make sense to check when searching. + // Some of the flags only make sense to check when searching. // For example, the timer is only started in init_search(). if (m_last_search_failure != OK) return true; - + if (m_timer.ms_timeout(m_fparams.m_timeout)) { m_last_search_failure = TIMEOUT; return true; @@ -3715,12 +3717,12 @@ namespace smt { } } } - + if (get_cancel_flag()) { m_last_search_failure = CANCELED; return true; } - + if (memory::above_high_watermark()) { m_last_search_failure = MEMOUT; return true; @@ -3771,15 +3773,15 @@ namespace smt { ok = m_qmanager->final_check_eh(true); TRACE("final_check_step", tout << "quantifier ok: " << ok << " " << "inconsistent " << inconsistent() << "\n";); } - + m_final_check_idx = (m_final_check_idx + 1) % range; // IF_VERBOSE(1000, verbose_stream() << "final check status: " << ok << "\n";); - + switch (ok) { - case FC_DONE: + case FC_DONE: break; case FC_GIVEUP: - result = FC_GIVEUP; + result = FC_GIVEUP; break; case FC_CONTINUE: return FC_CONTINUE; @@ -3844,23 +3846,23 @@ namespace smt { unsigned new_lvl = m_conflict_resolution->get_new_scope_lvl(); unsigned num_lits = m_conflict_resolution->get_lemma_num_literals(); literal * lits = m_conflict_resolution->get_lemma_literals(); - + SASSERT(num_lits > 0); unsigned conflict_lvl = get_assign_level(lits[0]); SASSERT(conflict_lvl <= m_scope_lvl); - // When num_lits == 1, then the default behavior is to go + // When num_lits == 1, then the default behavior is to go // to base-level. If the problem has quantifiers, it may be // too expensive to do that, since all instances will need to // be recreated. If that is the case, I store the assertions in // a special vector and keep reasserting whenever I backtrack. // Moreover, I backtrack only one level. - bool delay_forced_restart = + bool delay_forced_restart = m_fparams.m_delay_units && - internalized_quantifiers() && - num_lits == 1 && - conflict_lvl > m_search_lvl + 1 && - !m_manager.proofs_enabled() && + internalized_quantifiers() && + num_lits == 1 && + conflict_lvl > m_search_lvl + 1 && + !m_manager.proofs_enabled() && m_units_to_reassert.size() < m_fparams.m_delay_units_threshold; if (delay_forced_restart) { new_lvl = conflict_lvl - 1; @@ -3868,20 +3870,20 @@ namespace smt { // Some of the literals/enodes of the conflict clause will be destroyed during // backtracking, and will need to be recreated. However, I want to keep - // the generation number for enodes that are going to be recreated. See + // the generation number for enodes that are going to be recreated. See // comment in cache_generation(unsigned). if (m_conflict_resolution->get_lemma_intern_lvl() > new_lvl) cache_generation(num_lits, lits, new_lvl); SASSERT(new_lvl < m_scope_lvl); - TRACE("resolve_conflict_bug", + TRACE("resolve_conflict_bug", tout << "m_scope_lvl: " << m_scope_lvl << ", new_lvl: " << new_lvl << ", lemma_intern_lvl: " << m_conflict_resolution->get_lemma_intern_lvl() << "\n"; tout << "num_lits: " << num_lits << "\n"; for (unsigned i = 0; i < num_lits; i++) { literal l = lits[i]; tout << l << " "; - display_literal(tout, l); - tout << ", ilvl: " << get_intern_level(l.var()) << "\n" + display_literal(tout, l); + tout << ", ilvl: " << get_intern_level(l.var()) << "\n" << mk_pp(bool_var2expr(l.var()), m_manager) << "\n"; }); @@ -3891,7 +3893,7 @@ namespace smt { m_manager.trace_stream() << "\n"; } -#ifdef Z3DEBUG +#ifdef Z3DEBUG expr_ref_vector expr_lits(m_manager); svector expr_signs; for (unsigned i = 0; i < num_lits; i++) { @@ -3906,7 +3908,7 @@ namespace smt { pr = m_conflict_resolution->get_lemma_proof(); // check_proof(pr); TRACE("context_proof", tout << mk_ll_pp(pr, m_manager);); - TRACE("context_proof_hack", + TRACE("context_proof_hack", static ast_mark visited; ast_ll_pp(tout, m_manager, pr, visited);); } @@ -3948,15 +3950,15 @@ namespace smt { if (relevancy()) restore_relevancy(num_lits, lits); // Resetting the cache manually because I did not invoke pop_scope, but pop_scope_core reset_cache_generation(); - TRACE("resolve_conflict_bug", - tout << "AFTER m_scope_lvl: " << m_scope_lvl << ", new_lvl: " << new_lvl << ", lemma_intern_lvl: " << + TRACE("resolve_conflict_bug", + tout << "AFTER m_scope_lvl: " << m_scope_lvl << ", new_lvl: " << new_lvl << ", lemma_intern_lvl: " << m_conflict_resolution->get_lemma_intern_lvl() << "\n"; tout << "num_lits: " << num_lits << "\n"; for (unsigned i = 0; i < num_lits; i++) { literal l = lits[i]; tout << l << " "; - display_literal(tout, l); - tout << ", ilvl: " << get_intern_level(l.var()) << "\n" + display_literal(tout, l); + tout << ", ilvl: " << get_intern_level(l.var()) << "\n" << mk_pp(bool_var2expr(l.var()), m_manager) << "\n"; }); #ifdef Z3DEBUG @@ -3980,7 +3982,7 @@ namespace smt { } #if 0 { - static unsigned counter = 0; + static unsigned counter = 0; static uint64 total = 0; static unsigned max = 0; counter++; @@ -4006,13 +4008,13 @@ namespace smt { m_units_to_reassert_sign.push_back(unit_sign); TRACE("reassert_units", tout << "asserting #" << unit->get_id() << " " << unit_sign << " @ " << m_scope_lvl << "\n";); } - + m_conflict_resolution->release_lemma_atoms(); - TRACE("context_lemma", tout << "new lemma: "; + TRACE("context_lemma", tout << "new lemma: "; literal_vector v(num_lits, lits); std::sort(v.begin(), v.end()); for (unsigned i = 0; i < num_lits; i++) { - display_literal(tout, v[i]); + display_literal(tout, v[i]); tout << "\n"; v[i].display(tout, m_manager, m_bool_var2expr.c_ptr()); tout << "\n\n"; @@ -4028,7 +4030,7 @@ namespace smt { } return false; } - + /* \brief we record and restore relevancy information for literals in conflict clauses. A literal may have been marked relevant within the scope that gets popped during @@ -4064,11 +4066,11 @@ namespace smt { if (!checker.check(fml)) { warning_msg("Boogie generated formula that can require multiple '@' labels in a counter-example"); break; - } + } } } } - + SASSERT(!inconsistent()); unsigned sz = m_b_internalized_stack.size(); for (unsigned i = 0; i < sz; i++) { @@ -4079,7 +4081,7 @@ namespace smt { } } } - + /** \brief Collect relevant literals that may be used to block the current assignment. If at_lbls is true, then only labels that contains '@' are considered. (This is a hack for Boogie). @@ -4192,7 +4194,7 @@ namespace smt { } bool r = false; if (!b_internalized(eq)) { - // I do not invoke internalize(eq, true), because I want to + // I do not invoke internalize(eq, true), because I want to // mark the try_true_first flag before invoking theory::internalize_eq_eh. // Reason: Theories like arithmetic should be able to know if the try_true_first flag is // marked or not. They use this information to also mark auxiliary atoms such as: @@ -4254,13 +4256,13 @@ namespace smt { if (m_qmanager->is_shared(n)) { return true; } - - // the variabe is shared if the equivalence class of n + + // the variabe is shared if the equivalence class of n // contains a parent application. - + theory_var_list * l = n->get_th_var_list(); theory_id th_id = l->get_th_id(); - + enode_vector::const_iterator it = n->begin_parents(); enode_vector::const_iterator end = n->end_parents(); for (; it != end; ++it) { @@ -4271,12 +4273,12 @@ namespace smt { return true; } } - + // Some theories implement families of theories. Examples: // Arrays and Tuples. For example, array theory is a // parametric theory, that is, it implements several theories: // (array int int), (array int (array int int)), ... - // + // // Example: // // a : (array int int) @@ -4323,18 +4325,18 @@ namespace smt { if (fcs == FC_DONE) { mk_proto_model(l_true); m_model = m_proto_model->mk_model(); - add_rec_funs_to_model(); + add_rec_funs_to_model(); } - + return fcs == FC_DONE; } void context::mk_proto_model(lbool r) { - TRACE("get_model", - display(tout); + TRACE("get_model", + display(tout); display_normalized_enodes(tout); display_enodes_lbls(tout); - m_fingerprints.display(tout); + m_fingerprints.display(tout); ); failure fl = get_last_search_failure(); if (fl == MEMOUT || fl == CANCELED || fl == TIMEOUT || fl == NUM_CONFLICTS || fl == RESOURCE_LIMIT) { @@ -4351,7 +4353,7 @@ namespace smt { if (m_fparams.m_model_compact) m_proto_model->compress(); TRACE("mbqi_bug", tout << "after cleanup:\n"; model_pp(tout, *m_proto_model);); - } + } else { } @@ -4363,19 +4365,19 @@ namespace smt { return m_unsat_proof; } - void context::get_model(model_ref & m) const { + void context::get_model(model_ref & m) const { if (inconsistent()) m = 0; else - m = const_cast(m_model.get()); + m = const_cast(m_model.get()); } void context::get_proto_model(proto_model_ref & m) const { m = const_cast(m_proto_model.get()); } - failure context::get_last_search_failure() const { - return m_last_search_failure; + failure context::get_last_search_failure() const { + return m_last_search_failure; } void context::add_rec_funs_to_model() { @@ -4394,7 +4396,7 @@ namespace smt { func_decl* f = to_app(fn)->get_decl(); func_interp* fi = alloc(func_interp, m, f->get_arity()); fi->set_else(body); - m_model->register_decl(f, fi); + m_model->register_decl(f, fi); } } } From 6f8a9545325cb1b73fb07055755c54a8cc113e12 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Aug 2017 12:37:26 +0100 Subject: [PATCH 172/488] added missing addition to smt_params_helper.pyg --- src/smt/params/smt_params_helper.pyg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/smt/params/smt_params_helper.pyg b/src/smt/params/smt_params_helper.pyg index a501f474a..5b5c7328c 100644 --- a/src/smt/params/smt_params_helper.pyg +++ b/src/smt/params/smt_params_helper.pyg @@ -80,5 +80,6 @@ def_module_params(module_name='smt', ('core.minimize', BOOL, False, 'minimize unsat core produced by SMT context'), ('core.extend_patterns', BOOL, False, 'extend unsat core with literals that trigger (potential) quantifier instances'), ('core.extend_patterns.max_distance', UINT, UINT_MAX, 'limits the distance of a pattern-extended unsat core'), - ('core.extend_nonlocal_patterns', BOOL, False, 'extend unsat cores with literals that have quantifiers with patterns that contain symbols which are not in the quantifier\'s body') + ('core.extend_nonlocal_patterns', BOOL, False, 'extend unsat cores with literals that have quantifiers with patterns that contain symbols which are not in the quantifier\'s body'), + ('lemma_gc_strategy', UINT, 0, 'lemma garbage collection strategy: 0 - fixed, 1 - geometric, 2 - at restart, 3 - none') )) From e5826b957f97e2c43ad765ef77b127726b7255eb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Aug 2017 09:01:25 -0700 Subject: [PATCH 173/488] fix build Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/poly_rewriter.h | 1 + src/ast/rewriter/poly_rewriter_def.h | 7 +++++++ src/smt/proto_model/proto_model.cpp | 8 ++++---- src/smt/smt_model_generator.cpp | 6 +++--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/ast/rewriter/poly_rewriter.h b/src/ast/rewriter/poly_rewriter.h index 5269f25a8..8cbc7f864 100644 --- a/src/ast/rewriter/poly_rewriter.h +++ b/src/ast/rewriter/poly_rewriter.h @@ -112,6 +112,7 @@ public: bool is_mul(func_decl * f) const { return is_decl_of(f, get_fid(), mul_decl_kind()); } bool is_times_minus_one(expr * n, expr*& r) const; bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t); + bool is_zero(expr* e) const; br_status mk_mul_core(unsigned num_args, expr * const * args, expr_ref & result) { diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 6b747756c..731a0538a 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -64,6 +64,13 @@ expr * poly_rewriter::get_power_body(expr * t, rational & k) { return t; } +template +bool poly_rewriter::is_zero(expr* e) const { + rational v; + return is_numeral(e, v) && v.is_zero(); +} + + template expr * poly_rewriter::mk_mul_app(unsigned num_args, expr * const * args) { switch (num_args) { diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index 9b218037e..725c9fc51 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -161,8 +161,10 @@ void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_au continue; } func_decl * f = t->get_decl(); - if (m_aux_decls.contains(f)) + if (m_aux_decls.contains(f)) { + TRACE("model_bug", tout << f->get_name() << "\n";); found_aux_fs.insert(f); + } expr_ref new_t(m_manager); new_t = m_rewrite.mk_app(f, args.size(), args.c_ptr()); if (t != new_t.get()) @@ -180,9 +182,7 @@ void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_au } } - if (!cache.find(fi_else, a)) { - UNREACHABLE(); - } + VERIFY(cache.find(fi_else, a)); fi->set_else(a); } diff --git a/src/smt/smt_model_generator.cpp b/src/smt/smt_model_generator.cpp index 49e9083f2..953afd4b7 100644 --- a/src/smt/smt_model_generator.cpp +++ b/src/smt/smt_model_generator.cpp @@ -17,14 +17,14 @@ Revision History: --*/ -#include "smt/smt_context.h" -#include "smt/smt_model_generator.h" -#include "smt/proto_model/proto_model.h" #include "util/ref_util.h" #include "ast/for_each_expr.h" #include "ast/ast_ll_pp.h" #include "ast/ast_pp.h" #include "ast/ast_smt2_pp.h" +#include "smt/smt_context.h" +#include "smt/smt_model_generator.h" +#include "smt/proto_model/proto_model.h" namespace smt { From 58f152a92a0fa3ad6d5f0fcf64501b1108097c69 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 23 Aug 2017 19:21:32 +0100 Subject: [PATCH 174/488] [CMake] Teach CMake to support git worktrees. This fixes the bug reported by @nbraud reported in #1227. Previously the CMake build system assumed that the `.git` file must be a directory. This is not the case when the working directory is a "git worktree". In this case the `.git` file is just a plain file that points to a directory within the true `.git` directory. This commit essentially implements the logic to traverse this extra level of indirection and removes some assumptions that the `.git` file is a directory. --- cmake/git_utils.cmake | 82 ++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/cmake/git_utils.cmake b/cmake/git_utils.cmake index f98aca205..dbc95d8df 100644 --- a/cmake/git_utils.cmake +++ b/cmake/git_utils.cmake @@ -4,23 +4,55 @@ # of the git directory changes CMake will be forced to re-run. This useful # for fetching the current git hash and including it in the build. # -# `GIT_DIR` is the path to the git directory (i.e. the `.git` directory) +# `GIT_DOT_FILE` is the path to the git directory (i.e. the `.git` directory) or +# `.git` file used by a git worktree. # `SUCCESS_VAR` is the name of the variable to set. It will be set to TRUE # if the dependency was successfully added and FALSE otherwise. -function(add_git_dir_dependency GIT_DIR SUCCESS_VAR) +function(add_git_dir_dependency GIT_DOT_FILE SUCCESS_VAR) if (NOT "${ARGC}" EQUAL 2) message(FATAL_ERROR "Invalid number (${ARGC}) of arguments") endif() - if (NOT IS_ABSOLUTE "${GIT_DIR}") - message(FATAL_ERROR "GIT_DIR (\"${GIT_DIR}\") is not an absolute path") + if (NOT IS_ABSOLUTE "${GIT_DOT_FILE}") + message(FATAL_ERROR "GIT_DOT_FILE (\"${GIT_DOT_FILE}\") is not an absolute path") endif() - if (NOT IS_DIRECTORY "${GIT_DIR}") - message(FATAL_ERROR "GIT_DIR (\"${GIT_DIR}\") is not a directory") + if (NOT EXISTS "${GIT_DOT_FILE}") + message(FATAL_ERROR "GIT_DOT_FILE (\"${GIT_DOT_FILE}\") does not exist") endif() - set(GIT_HEAD_FILE "${GIT_DIR}/HEAD") + if (NOT IS_DIRECTORY "${GIT_DOT_FILE}") + # Might be a git worktree. In this case we need parse out the worktree + # git directory + file(READ "${GIT_DOT_FILE}" GIT_DOT_FILE_DATA LIMIT 512) + string(STRIP "${GIT_DOT_FILE_DATA}" GIT_DOT_FILE_DATA_STRIPPED) + if ("${GIT_DOT_FILE_DATA_STRIPPED}" MATCHES "^gitdir:[ ]*(.+)$") + # Git worktree + message(STATUS "Found git worktree") + set(GIT_WORKTREE_DIR "${CMAKE_MATCH_1}") + set(GIT_HEAD_FILE "${GIT_WORKTREE_DIR}/HEAD") + # Figure out where real git directory lives + set(GIT_COMMON_DIR_FILE "${GIT_WORKTREE_DIR}/commondir") + if (NOT EXISTS "${GIT_COMMON_DIR_FILE}") + message(FATAL_ERROR "Found git worktree dir but could not find \"${GIT_COMMON_DIR_FILE}\"") + endif() + file(READ "${GIT_COMMON_DIR_FILE}" GIT_COMMON_DIR_FILE_DATA LIMIT 512) + string(STRIP "${GIT_COMMON_DIR_FILE_DATA}" GIT_COMMON_DIR_FILE_DATA_STRIPPED) + get_filename_component(GIT_DIR "${GIT_WORKTREE_DIR}/${GIT_COMMON_DIR_FILE_DATA_STRIPPED}" ABSOLUTE) + if (NOT IS_DIRECTORY "${GIT_DIR}") + message(FATAL_ERROR "Failed to compute path to git directory from git worktree") + endif() + else() + message(FATAL_ERROR "GIT_DOT_FILE (\"${GIT_DOT_FILE}\") is not a directory or a pointer to git worktree directory") + endif() + else() + # Just a normal `.git` directory + message(STATUS "Found simple git working directory") + set(GIT_HEAD_FILE "${GIT_DOT_FILE}/HEAD") + set(GIT_DIR "${GIT_DOT_FILE}") + endif() + message(STATUS "Found git directory \"${GIT_DIR}\"") + if (NOT EXISTS "${GIT_HEAD_FILE}") message(AUTHOR_WARNING "Git head file \"${GIT_HEAD_FILE}\" cannot be found") set(${SUCCESS_VAR} FALSE PARENT_SCOPE) @@ -79,24 +111,25 @@ function(add_git_dir_dependency GIT_DIR SUCCESS_VAR) set(${SUCCESS_VAR} TRUE PARENT_SCOPE) endfunction() -# get_git_head_hash(GIT_DIR OUTPUT_VAR) +# get_git_head_hash(GIT_DOT_FILE OUTPUT_VAR) # -# Retrieve the current commit hash for a git working directory where `GIT_DIR` -# is the `.git` directory in the root of the git working directory. +# Retrieve the current commit hash for a git working directory where +# `GIT_DOT_FILE` is the `.git` directory or `.git` pointer file in a git +# worktree in the root of the git working directory. # # `OUTPUT_VAR` should be the name of the variable to put the result in. If this # function fails then either a fatal error will be raised or `OUTPUT_VAR` will # contain a string with the suffix `NOTFOUND` which can be used in CMake `if()` # commands. -function(get_git_head_hash GIT_DIR OUTPUT_VAR) +function(get_git_head_hash GIT_DOT_FILE OUTPUT_VAR) if (NOT "${ARGC}" EQUAL 2) message(FATAL_ERROR "Invalid number of arguments") endif() - if (NOT IS_DIRECTORY "${GIT_DIR}") - message(FATAL_ERROR "\"${GIT_DIR}\" is not a directory") + if (NOT EXISTS "${GIT_DOT_FILE}") + message(FATAL_ERROR "\"${GIT_DOT_FILE}\" does not exist") endif() - if (NOT IS_ABSOLUTE "${GIT_DIR}") - message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path") + if (NOT IS_ABSOLUTE "${GIT_DOT_FILE}") + message(FATAL_ERROR \""${GIT_DOT_FILE}\" is not an absolute path") endif() find_package(Git) # NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only @@ -105,7 +138,7 @@ function(get_git_head_hash GIT_DIR OUTPUT_VAR) set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE) return() endif() - get_filename_component(GIT_WORKING_DIR "${GIT_DIR}" DIRECTORY) + get_filename_component(GIT_WORKING_DIR "${GIT_DOT_FILE}" DIRECTORY) execute_process( COMMAND "${GIT_EXECUTABLE}" @@ -128,24 +161,25 @@ function(get_git_head_hash GIT_DIR OUTPUT_VAR) set(${OUTPUT_VAR} "${Z3_GIT_HASH}" PARENT_SCOPE) endfunction() -# get_git_head_describe(GIT_DIR OUTPUT_VAR) +# get_git_head_describe(GIT_DOT_FILE OUTPUT_VAR) # # Retrieve the output of `git describe` for a git working directory where -# `GIT_DIR` is the `.git` directory in the root of the git working directory. +# `GIT_DOT_FILE` is the `.git` directory or `.git` pointer file in a git +# worktree in the root of the git working directory. # # `OUTPUT_VAR` should be the name of the variable to put the result in. If this # function fails then either a fatal error will be raised or `OUTPUT_VAR` will # contain a string with the suffix `NOTFOUND` which can be used in CMake `if()` # commands. -function(get_git_head_describe GIT_DIR OUTPUT_VAR) +function(get_git_head_describe GIT_DOT_FILE OUTPUT_VAR) if (NOT "${ARGC}" EQUAL 2) message(FATAL_ERROR "Invalid number of arguments") endif() - if (NOT IS_DIRECTORY "${GIT_DIR}") - message(FATAL_ERROR "\"${GIT_DIR}\" is not a directory") + if (NOT EXISTS "${GIT_DOT_FILE}") + message(FATAL_ERROR "\"${GIT_DOT_FILE}\" does not exist") endif() - if (NOT IS_ABSOLUTE "${GIT_DIR}") - message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path") + if (NOT IS_ABSOLUTE "${GIT_DOT_FILE}") + message(FATAL_ERROR \""${GIT_DOT_FILE}\" is not an absolute path") endif() find_package(Git) # NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only @@ -154,7 +188,7 @@ function(get_git_head_describe GIT_DIR OUTPUT_VAR) set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE) return() endif() - get_filename_component(GIT_WORKING_DIR "${GIT_DIR}" DIRECTORY) + get_filename_component(GIT_WORKING_DIR "${GIT_DOT_FILE}" DIRECTORY) execute_process( COMMAND "${GIT_EXECUTABLE}" From 655b3d9c1953b5deef01bcfd9ef523b032e05bc8 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Aug 2017 12:17:30 -0700 Subject: [PATCH 175/488] removing dependency on simplifier in pattern_inference Signed-off-by: Nikolaj Bjorner --- src/ast/macros/macro_manager.cpp | 98 --- src/ast/macros/macro_manager.h | 11 - src/ast/pattern/pattern_inference.cpp | 698 ++++++++++++++++-- src/ast/pattern/pattern_inference.h | 211 +++++- .../dl_mk_quantifier_instantiation.cpp | 2 +- src/smt/asserted_formulas.cpp | 3 +- src/smt/proto_model/proto_model.cpp | 4 +- src/smt/smt_model_generator.cpp | 1 - 8 files changed, 861 insertions(+), 167 deletions(-) diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index 70434435b..bff1e7dae 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -298,104 +298,6 @@ struct macro_manager::macro_expander_rw : public rewriter_tplget_num_patterns() != new_q->get_num_patterns() || - q->get_num_no_patterns() != new_q->get_num_no_patterns()) { - erase_patterns = true; - } - else { - for (unsigned i = 0; !erase_patterns && i < q->get_num_patterns(); i++) { - if (q->get_pattern(i) != new_q->get_pattern(i)) - erase_patterns = true; - } - for (unsigned i = 0; !erase_patterns && i < q->get_num_no_patterns(); i++) { - if (q->get_no_pattern(i) != new_q->get_no_pattern(i)) - erase_patterns = true; - } - } - if (erase_patterns) { - ast_manager & m = get_manager(); - expr * new_new_q = m.update_quantifier(new_q, 0, 0, 0, 0, new_q->get_expr()); - // we can use the same proof since new_new_q and new_q are identical modulo patterns/annotations - cache_result(q, new_new_q, new_q_pr); - } -} - -bool macro_manager::macro_expander::get_subst(expr * _n, expr_ref & r, proof_ref & p) { - if (!is_app(_n)) - return false; - app * n = to_app(_n); - quantifier * q = 0; - func_decl * d = n->get_decl(); - TRACE("macro_manager_bug", tout << "trying to expand:\n" << mk_pp(n, m) << "\nd:\n" << d->get_name() << "\n";); - if (m_macro_manager.m_decl2macro.find(d, q)) { - TRACE("macro_manager", tout << "expanding: " << mk_pp(n, m) << "\n";); - app * head = 0; - expr * def = 0; - m_macro_manager.get_head_def(q, d, head, def); - unsigned num = n->get_num_args(); - SASSERT(head && def); - ptr_buffer subst_args; - subst_args.resize(num, 0); - for (unsigned i = 0; i < num; i++) { - var * v = to_var(head->get_arg(i)); - SASSERT(v->get_idx() < num); - unsigned nidx = num - v->get_idx() - 1; - SASSERT(subst_args[nidx] == 0); - subst_args[nidx] = n->get_arg(i); - } - var_subst s(m); - s(def, num, subst_args.c_ptr(), r); - if (m.proofs_enabled()) { - expr_ref instance(m); - s(q->get_expr(), num, subst_args.c_ptr(), instance); - proof * qi_pr = m.mk_quant_inst(m.mk_or(m.mk_not(q), instance), num, subst_args.c_ptr()); - proof * q_pr = 0; - m_macro_manager.m_decl2macro_pr.find(d, q_pr); - SASSERT(q_pr != 0); - proof * prs[2] = { qi_pr, q_pr }; - p = m.mk_unit_resolution(2, prs); - } - else { - p = 0; - } - return true; - } - return false; -} void macro_manager::expand_macros(expr * n, proof * pr, expr_ref & r, proof_ref & new_pr) { if (has_macros()) { diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index 98e242cd8..71864a699 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -60,17 +60,6 @@ class macro_manager { struct macro_expander_cfg; struct macro_expander_rw; - class macro_expander : public simplifier { - protected: - macro_manager & m_macro_manager; - virtual bool get_subst(expr * n, expr_ref & r, proof_ref & p); - virtual void reduce1_quantifier(quantifier * q); - public: - macro_expander(ast_manager & m, macro_manager & mm); - ~macro_expander(); - }; - friend class macro_expander; - public: macro_manager(ast_manager & m); ~macro_manager(); diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index d97c2f094..94a90d829 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -16,15 +16,17 @@ Author: Revision History: --*/ + +#include "util/warning.h" #include "ast/pattern/pattern_inference.h" #include "ast/ast_ll_pp.h" #include "ast/ast_pp.h" #include "ast/ast_util.h" -#include "util/warning.h" #include "ast/arith_decl_plugin.h" #include "ast/normal_forms/pull_quant.h" #include "ast/well_sorted.h" #include "ast/for_each_expr.h" +#include "ast/rewriter/rewriter_def.h" void smaller_pattern::save(expr * p1, expr * p2) { expr_pair e(p1, p2); @@ -87,7 +89,7 @@ bool smaller_pattern::operator()(unsigned num_bindings, expr * p1, expr * p2) { return process(p1, p2); } -pattern_inference::pattern_inference(ast_manager & m, pattern_inference_params & params): +pattern_inference_old::pattern_inference_old(ast_manager & m, pattern_inference_params & params): simplifier(m), m_params(params), m_bfid(m.get_basic_family_id()), @@ -105,7 +107,7 @@ pattern_inference::pattern_inference(ast_manager & m, pattern_inference_params & enable_ac_support(false); } -void pattern_inference::collect::operator()(expr * n, unsigned num_bindings) { +void pattern_inference_old::collect::operator()(expr * n, unsigned num_bindings) { SASSERT(m_info.empty()); SASSERT(m_todo.empty()); SASSERT(m_cache.empty()); @@ -125,7 +127,7 @@ void pattern_inference::collect::operator()(expr * n, unsigned num_bindings) { reset(); } -inline void pattern_inference::collect::visit(expr * n, unsigned delta, bool & visited) { +inline void pattern_inference_old::collect::visit(expr * n, unsigned delta, bool & visited) { entry e(n, delta); if (!m_cache.contains(e)) { m_todo.push_back(e); @@ -133,7 +135,7 @@ inline void pattern_inference::collect::visit(expr * n, unsigned delta, bool & v } } -bool pattern_inference::collect::visit_children(expr * n, unsigned delta) { +bool pattern_inference_old::collect::visit_children(expr * n, unsigned delta) { bool visited = true; unsigned i; switch (n->get_kind()) { @@ -153,13 +155,13 @@ bool pattern_inference::collect::visit_children(expr * n, unsigned delta) { return visited; } -inline void pattern_inference::collect::save(expr * n, unsigned delta, info * i) { +inline void pattern_inference_old::collect::save(expr * n, unsigned delta, info * i) { m_cache.insert(entry(n, delta), i); if (i != 0) m_info.push_back(i); } -void pattern_inference::collect::save_candidate(expr * n, unsigned delta) { +void pattern_inference_old::collect::save_candidate(expr * n, unsigned delta) { switch (n->get_kind()) { case AST_VAR: { unsigned idx = to_var(n)->get_idx(); @@ -247,14 +249,14 @@ void pattern_inference::collect::save_candidate(expr * n, unsigned delta) { } -void pattern_inference::collect::reset() { +void pattern_inference_old::collect::reset() { m_cache.reset(); std::for_each(m_info.begin(), m_info.end(), delete_proc()); m_info.reset(); SASSERT(m_todo.empty()); } -void pattern_inference::add_candidate(app * n, uint_set const & free_vars, unsigned size) { +void pattern_inference_old::add_candidate(app * n, uint_set const & free_vars, unsigned size) { for (unsigned i = 0; i < m_num_no_patterns; i++) { if (n == m_no_patterns[i]) return; @@ -271,7 +273,7 @@ void pattern_inference::add_candidate(app * n, uint_set const & free_vars, unsig \brief Copy the non-looping patterns in m_candidates to result when m_params.m_pi_block_loop_patterns = true. Otherwise, copy m_candidates to result. */ -void pattern_inference::filter_looping_patterns(ptr_vector & result) { +void pattern_inference_old::filter_looping_patterns(ptr_vector & result) { unsigned num = m_candidates.size(); for (unsigned i1 = 0; i1 < num; i1++) { app * n1 = m_candidates.get(i1); @@ -310,7 +312,7 @@ void pattern_inference::filter_looping_patterns(ptr_vector & result) { -inline void pattern_inference::contains_subpattern::save(expr * n) { +inline void pattern_inference_old::contains_subpattern::save(expr * n) { unsigned id = n->get_id(); m_already_processed.assure_domain(id); if (!m_already_processed.contains(id)) { @@ -319,7 +321,7 @@ inline void pattern_inference::contains_subpattern::save(expr * n) { } } -bool pattern_inference::contains_subpattern::operator()(expr * n) { +bool pattern_inference_old::contains_subpattern::operator()(expr * n) { m_already_processed.reset(); m_todo.reset(); expr2info::obj_map_entry * _e = m_owner.m_candidates_info.find_core(n); @@ -360,7 +362,7 @@ bool pattern_inference::contains_subpattern::operator()(expr * n) { Return true if n contains a direct/indirect child that is also a pattern, and contains the same number of free variables. */ -inline bool pattern_inference::contains_subpattern(expr * n) { +inline bool pattern_inference_old::contains_subpattern(expr * n) { return m_contains_subpattern(n); } @@ -372,18 +374,15 @@ inline bool pattern_inference::contains_subpattern(expr * n) { Remark: Every pattern p in patterns is also a member of m_pattern_map. */ -void pattern_inference::filter_bigger_patterns(ptr_vector const & patterns, ptr_vector & result) { - ptr_vector::const_iterator it = patterns.begin(); - ptr_vector::const_iterator end = patterns.end(); - for (; it != end; ++it) { - app * curr = *it; +void pattern_inference_old::filter_bigger_patterns(ptr_vector const & patterns, ptr_vector & result) { + for (app * curr : patterns) { if (!contains_subpattern(curr)) result.push_back(curr); } } -bool pattern_inference::pattern_weight_lt::operator()(expr * n1, expr * n2) const { +bool pattern_inference_old::pattern_weight_lt::operator()(expr * n1, expr * n2) const { expr2info::obj_map_entry * e1 = m_candidates_info.find_core(n1); expr2info::obj_map_entry * e2 = m_candidates_info.find_core(n2); SASSERT(e1 != 0); @@ -401,13 +400,10 @@ bool pattern_inference::pattern_weight_lt::operator()(expr * n1, expr * n2) cons variables, then it is copied to remaining_candidate_patterns. The new patterns are stored in result. */ -void pattern_inference::candidates2unary_patterns(ptr_vector const & candidate_patterns, +void pattern_inference_old::candidates2unary_patterns(ptr_vector const & candidate_patterns, ptr_vector & remaining_candidate_patterns, app_ref_buffer & result) { - ptr_vector::const_iterator it = candidate_patterns.begin(); - ptr_vector::const_iterator end = candidate_patterns.end(); - for (; it != end; ++it) { - app * candidate = *it; + for (app * candidate : candidate_patterns) { expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate); info const & i = e->get_data().m_value; if (i.m_free_vars.num_elems() == m_num_bindings) { @@ -425,7 +421,7 @@ void pattern_inference::candidates2unary_patterns(ptr_vector const & candid // HACK: limit the number of case-splits: #define MAX_SPLITS 32 -void pattern_inference::candidates2multi_patterns(unsigned max_num_patterns, +void pattern_inference_old::candidates2multi_patterns(unsigned max_num_patterns, ptr_vector const & candidate_patterns, app_ref_buffer & result) { SASSERT(!candidate_patterns.empty()); @@ -469,21 +465,19 @@ void pattern_inference::candidates2multi_patterns(unsigned max_num_patterns, } } -void pattern_inference::reset_pre_patterns() { +void pattern_inference_old::reset_pre_patterns() { std::for_each(m_pre_patterns.begin(), m_pre_patterns.end(), delete_proc()); m_pre_patterns.reset(); } #ifdef _TRACE static void dump_app_vector(std::ostream & out, ptr_vector const & v, ast_manager & m) { - ptr_vector::const_iterator it = v.begin(); - ptr_vector::const_iterator end = v.end(); - for (; it != end; ++it) - out << mk_pp(*it, m) << "\n"; + for (app * e : v) + out << mk_pp(e, m) << "\n"; } #endif -bool pattern_inference::is_forbidden(app * n) const { +bool pattern_inference_old::is_forbidden(app * n) const { func_decl const * decl = n->get_decl(); if (is_ground(n)) return false; @@ -499,14 +493,11 @@ bool pattern_inference::is_forbidden(app * n) const { return false; } -bool pattern_inference::has_preferred_patterns(ptr_vector & candidate_patterns, app_ref_buffer & result) { +bool pattern_inference_old::has_preferred_patterns(ptr_vector & candidate_patterns, app_ref_buffer & result) { if (m_preferred.empty()) return false; bool found = false; - ptr_vector::const_iterator it = candidate_patterns.begin(); - ptr_vector::const_iterator end = candidate_patterns.end(); - for (; it != end; ++it) { - app * candidate = *it; + for (app * candidate : candidate_patterns) { if (m_preferred.contains(to_app(candidate)->get_decl())) { expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate); info const & i = e->get_data().m_value; @@ -521,7 +512,7 @@ bool pattern_inference::has_preferred_patterns(ptr_vector & candidate_patte return found; } -void pattern_inference::mk_patterns(unsigned num_bindings, +void pattern_inference_old::mk_patterns(unsigned num_bindings, expr * n, unsigned num_no_patterns, expr * const * no_patterns, @@ -578,7 +569,7 @@ void pattern_inference::mk_patterns(unsigned num_bindings, #include "ast/pattern/database.h" -void pattern_inference::reduce1_quantifier(quantifier * q) { +void pattern_inference_old::reduce1_quantifier(quantifier * q) { TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";); if (!q->is_forall()) { simplifier::reduce1_quantifier(q); @@ -739,13 +730,626 @@ void pattern_inference::reduce1_quantifier(quantifier * q) { } -#if 0 -// unused -static void dump_expr_vector(std::ostream & out, ptr_vector const & v, ast_manager & m) { - ptr_vector::const_iterator it = v.begin(); - ptr_vector::const_iterator end = v.end(); - for (; it != end; ++it) - out << mk_pp(*it, m) << "\n"; -} -#endif +pattern_inference_cfg::pattern_inference_cfg(ast_manager & m, pattern_inference_params & params): + m(m), + m_params(params), + m_bfid(m.get_basic_family_id()), + m_afid(m.mk_family_id("arith")), + m_le(m), + m_nested_arith_only(true), + m_block_loop_patterns(params.m_pi_block_loop_patterns), + m_candidates(m), + m_pattern_weight_lt(m_candidates_info), + m_collect(m, *this), + m_contains_subpattern(*this), + m_database(m) { + if (params.m_pi_arith == AP_NO) + register_forbidden_family(m_afid); +} + +void pattern_inference_cfg::collect::operator()(expr * n, unsigned num_bindings) { + SASSERT(m_info.empty()); + SASSERT(m_todo.empty()); + SASSERT(m_cache.empty()); + m_num_bindings = num_bindings; + m_todo.push_back(entry(n, 0)); + while (!m_todo.empty()) { + entry & e = m_todo.back(); + n = e.m_node; + unsigned delta = e.m_delta; + TRACE("collect", tout << "processing: " << n->get_id() << " " << delta << " kind: " << n->get_kind() << "\n";); + TRACE("collect_info", tout << mk_pp(n, m) << "\n";); + if (visit_children(n, delta)) { + m_todo.pop_back(); + save_candidate(n, delta); + } + } + reset(); +} + +inline void pattern_inference_cfg::collect::visit(expr * n, unsigned delta, bool & visited) { + entry e(n, delta); + if (!m_cache.contains(e)) { + m_todo.push_back(e); + visited = false; + } +} + +bool pattern_inference_cfg::collect::visit_children(expr * n, unsigned delta) { + bool visited = true; + unsigned i; + switch (n->get_kind()) { + case AST_APP: + i = to_app(n)->get_num_args(); + while (i > 0) { + --i; + visit(to_app(n)->get_arg(i), delta, visited); + } + break; + case AST_QUANTIFIER: + visit(to_quantifier(n)->get_expr(), delta + to_quantifier(n)->get_num_decls(), visited); + break; + default: + break; + } + return visited; +} + +inline void pattern_inference_cfg::collect::save(expr * n, unsigned delta, info * i) { + m_cache.insert(entry(n, delta), i); + if (i != 0) + m_info.push_back(i); +} + +void pattern_inference_cfg::collect::save_candidate(expr * n, unsigned delta) { + switch (n->get_kind()) { + case AST_VAR: { + unsigned idx = to_var(n)->get_idx(); + if (idx >= delta) { + idx = idx - delta; + uint_set free_vars; + if (idx < m_num_bindings) + free_vars.insert(idx); + info * i = 0; + if (delta == 0) + i = alloc(info, m, n, free_vars, 1); + else + i = alloc(info, m, m.mk_var(idx, to_var(n)->get_sort()), free_vars, 1); + save(n, delta, i); + } + else { + save(n, delta, 0); + } + return; + } + case AST_APP: { + app * c = to_app(n); + func_decl * decl = c->get_decl(); + if (m_owner.is_forbidden(c)) { + save(n, delta, 0); + return; + } + + if (c->get_num_args() == 0) { + save(n, delta, alloc(info, m, n, uint_set(), 1)); + return; + } + + ptr_buffer buffer; + bool changed = false; // false if none of the children is mapped to a node different from itself. + uint_set free_vars; + unsigned size = 1; + unsigned num = c->get_num_args(); + for (unsigned i = 0; i < num; i++) { + expr * child = c->get_arg(i); + info * child_info = 0; +#ifdef Z3DEBUG + bool found = +#endif + m_cache.find(entry(child, delta), child_info); + SASSERT(found); + if (child_info == 0) { + save(n, delta, 0); + return; + } + buffer.push_back(child_info->m_node.get()); + free_vars |= child_info->m_free_vars; + size += child_info->m_size; + if (child != child_info->m_node.get()) + changed = true; + } + + app * new_node = 0; + if (changed) + new_node = m.mk_app(decl, buffer.size(), buffer.c_ptr()); + else + new_node = to_app(n); + save(n, delta, alloc(info, m, new_node, free_vars, size)); + // Remark: arithmetic patterns are only used if they are nested inside other terms. + // That is, we never consider x + 1 as pattern. On the other hand, f(x+1) can be a pattern + // if arithmetic is not in the forbidden list. + // + // Remark: The rule above has an exception. The operators (div, idiv, mod) are allowed to be + // used as patterns even when they are not nested in other terms. The motivation is that + // Z3 currently doesn't implement them (i.e., they are uninterpreted). So, some users add axioms + // stating properties about these operators. + family_id fid = c->get_family_id(); + decl_kind k = c->get_decl_kind(); + if (!free_vars.empty() && + (fid != m_afid || (fid == m_afid && !m_owner.m_nested_arith_only && (k == OP_DIV || k == OP_IDIV || k == OP_MOD || k == OP_REM || k == OP_MUL)))) { + TRACE("pattern_inference", tout << "potential candidate: \n" << mk_pp(new_node, m) << "\n";); + m_owner.add_candidate(new_node, free_vars, size); + } + return; + } + default: + save(n, delta, 0); + return; + } +} + + +void pattern_inference_cfg::collect::reset() { + m_cache.reset(); + std::for_each(m_info.begin(), m_info.end(), delete_proc()); + m_info.reset(); + SASSERT(m_todo.empty()); +} + +void pattern_inference_cfg::add_candidate(app * n, uint_set const & free_vars, unsigned size) { + for (unsigned i = 0; i < m_num_no_patterns; i++) { + if (n == m_no_patterns[i]) + return; + } + + if (!m_candidates_info.contains(n)) { + m_candidates_info.insert(n, info(free_vars, size)); + m_candidates.push_back(n); + } +} + + +/** + \brief Copy the non-looping patterns in m_candidates to result when m_params.m_pi_block_loop_patterns = true. + Otherwise, copy m_candidates to result. +*/ +void pattern_inference_cfg::filter_looping_patterns(ptr_vector & result) { + unsigned num = m_candidates.size(); + for (unsigned i1 = 0; i1 < num; i1++) { + app * n1 = m_candidates.get(i1); + expr2info::obj_map_entry * e1 = m_candidates_info.find_core(n1); + SASSERT(e1); + uint_set const & s1 = e1->get_data().m_value.m_free_vars; + if (m_block_loop_patterns) { + bool smaller = false; + for (unsigned i2 = 0; i2 < num; i2++) { + if (i1 != i2) { + app * n2 = m_candidates.get(i2); + expr2info::obj_map_entry * e2 = m_candidates_info.find_core(n2); + if (e2) { + uint_set const & s2 = e2->get_data().m_value.m_free_vars; + // Remark: the comparison operator only makes sense if both AST nodes + // contain the same number of variables. + // Example: + // (f X Y) <: (f (g X Z W) Y) + if (s1 == s2 && m_le(m_num_bindings, n1, n2) && !m_le(m_num_bindings, n2, n1)) { + smaller = true; + break; + } + } + } + } + if (!smaller) + result.push_back(n1); + else + m_candidates_info.erase(n1); + } + else { + result.push_back(n1); + } + } +} + + + +inline void pattern_inference_cfg::contains_subpattern::save(expr * n) { + unsigned id = n->get_id(); + m_already_processed.assure_domain(id); + if (!m_already_processed.contains(id)) { + m_todo.push_back(n); + m_already_processed.insert(id); + } +} + +bool pattern_inference_cfg::contains_subpattern::operator()(expr * n) { + m_already_processed.reset(); + m_todo.reset(); + expr2info::obj_map_entry * _e = m_owner.m_candidates_info.find_core(n); + SASSERT(_e); + uint_set const & s1 = _e->get_data().m_value.m_free_vars; + save(n); + unsigned num; + while (!m_todo.empty()) { + expr * curr = m_todo.back(); + m_todo.pop_back(); + switch (curr->get_kind()) { + case AST_APP: + if (curr != n) { + expr2info::obj_map_entry * e = m_owner.m_candidates_info.find_core(curr); + if (e) { + uint_set const & s2 = e->get_data().m_value.m_free_vars; + SASSERT(s2.subset_of(s1)); + if (s1 == s2) { + TRACE("pattern_inference", tout << mk_pp(n, m_owner.m) << "\nis bigger than\n" << mk_pp(to_app(curr), m_owner.m) << "\n";); + return true; + } + } + } + num = to_app(curr)->get_num_args(); + for (unsigned i = 0; i < num; i++) + save(to_app(curr)->get_arg(i)); + break; + case AST_VAR: + break; + default: + UNREACHABLE(); + } + } + return false; +} + +/** + Return true if n contains a direct/indirect child that is also a + pattern, and contains the same number of free variables. +*/ +inline bool pattern_inference_cfg::contains_subpattern(expr * n) { + return m_contains_subpattern(n); +} + +/** + \brief Copy a pattern p in patterns to result, if there is no + direct/indirect child of p in patterns which contains the same set + of variables. + + Remark: Every pattern p in patterns is also a member of + m_pattern_map. +*/ +void pattern_inference_cfg::filter_bigger_patterns(ptr_vector const & patterns, ptr_vector & result) { + for (app * curr : patterns) { + if (!contains_subpattern(curr)) + result.push_back(curr); + } +} + + +bool pattern_inference_cfg::pattern_weight_lt::operator()(expr * n1, expr * n2) const { + expr2info::obj_map_entry * e1 = m_candidates_info.find_core(n1); + expr2info::obj_map_entry * e2 = m_candidates_info.find_core(n2); + SASSERT(e1 != 0); + SASSERT(e2 != 0); + info const & i1 = e1->get_data().m_value; + info const & i2 = e2->get_data().m_value; + unsigned num_free_vars1 = i1.m_free_vars.num_elems(); + unsigned num_free_vars2 = i2.m_free_vars.num_elems(); + return num_free_vars1 > num_free_vars2 || (num_free_vars1 == num_free_vars2 && i1.m_size < i2.m_size); +} + +/** + \brief Create unary patterns (single expressions that contain all + bound variables). If a candidate does not contain all bound + variables, then it is copied to remaining_candidate_patterns. The + new patterns are stored in result. +*/ +void pattern_inference_cfg::candidates2unary_patterns(ptr_vector const & candidate_patterns, + ptr_vector & remaining_candidate_patterns, + app_ref_buffer & result) { + for (app * candidate : candidate_patterns) { + expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate); + info const & i = e->get_data().m_value; + if (i.m_free_vars.num_elems() == m_num_bindings) { + app * new_pattern = m.mk_pattern(candidate); + result.push_back(new_pattern); + } + else { + remaining_candidate_patterns.push_back(candidate); + } + } +} + +// TODO: this code is too inefficient when the number of candidate +// patterns is too big. +// HACK: limit the number of case-splits: +#define MAX_SPLITS 32 + +void pattern_inference_cfg::candidates2multi_patterns(unsigned max_num_patterns, + ptr_vector const & candidate_patterns, + app_ref_buffer & result) { + SASSERT(!candidate_patterns.empty()); + m_pre_patterns.push_back(alloc(pre_pattern)); + unsigned sz = candidate_patterns.size(); + unsigned num_splits = 0; + for (unsigned j = 0; j < m_pre_patterns.size(); j++) { + pre_pattern * curr = m_pre_patterns[j]; + if (curr->m_free_vars.num_elems() == m_num_bindings) { + app * new_pattern = m.mk_pattern(curr->m_exprs.size(), curr->m_exprs.c_ptr()); + result.push_back(new_pattern); + if (result.size() >= max_num_patterns) + return; + } + else if (curr->m_idx < sz) { + app * n = candidate_patterns[curr->m_idx]; + expr2info::obj_map_entry * e = m_candidates_info.find_core(n); + uint_set const & s = e->get_data().m_value.m_free_vars; + if (!s.subset_of(curr->m_free_vars)) { + pre_pattern * new_p = alloc(pre_pattern,*curr); + new_p->m_exprs.push_back(n); + new_p->m_free_vars |= s; + new_p->m_idx++; + m_pre_patterns.push_back(new_p); + + if (num_splits < MAX_SPLITS) { + m_pre_patterns[j] = 0; + curr->m_idx++; + m_pre_patterns.push_back(curr); + num_splits++; + } + } + else { + m_pre_patterns[j] = 0; + curr->m_idx++; + m_pre_patterns.push_back(curr); + } + } + TRACE("pattern_inference", tout << "m_pre_patterns.size(): " << m_pre_patterns.size() << + "\nnum_splits: " << num_splits << "\n";); + } +} + +void pattern_inference_cfg::reset_pre_patterns() { + std::for_each(m_pre_patterns.begin(), m_pre_patterns.end(), delete_proc()); + m_pre_patterns.reset(); +} + + +bool pattern_inference_cfg::is_forbidden(app * n) const { + func_decl const * decl = n->get_decl(); + if (is_ground(n)) + return false; + // Remark: skolem constants should not be used in patterns, since they do not + // occur outside of the quantifier. That is, Z3 will never match this kind of + // pattern. + if (m_params.m_pi_avoid_skolems && decl->is_skolem()) { + CTRACE("pattern_inference_skolem", decl->is_skolem(), tout << "ignoring: " << mk_pp(n, m) << "\n";); + return true; + } + if (is_forbidden(decl)) + return true; + return false; +} + +bool pattern_inference_cfg::has_preferred_patterns(ptr_vector & candidate_patterns, app_ref_buffer & result) { + if (m_preferred.empty()) + return false; + bool found = false; + for (app * candidate : candidate_patterns) { + if (m_preferred.contains(to_app(candidate)->get_decl())) { + expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate); + info const & i = e->get_data().m_value; + if (i.m_free_vars.num_elems() == m_num_bindings) { + TRACE("pattern_inference", tout << "found preferred pattern:\n" << mk_pp(candidate, m) << "\n";); + app * p = m.mk_pattern(candidate); + result.push_back(p); + found = true; + } + } + } + return found; +} + +void pattern_inference_cfg::mk_patterns(unsigned num_bindings, + expr * n, + unsigned num_no_patterns, + expr * const * no_patterns, + app_ref_buffer & result) { + m_num_bindings = num_bindings; + m_num_no_patterns = num_no_patterns; + m_no_patterns = no_patterns; + + m_collect(n, num_bindings); + + TRACE("pattern_inference", + tout << mk_pp(n, m); + tout << "\ncandidates:\n"; + unsigned num = m_candidates.size(); + for (unsigned i = 0; i < num; i++) { + tout << mk_pp(m_candidates.get(i), m) << "\n"; + }); + + if (!m_candidates.empty()) { + m_tmp1.reset(); + filter_looping_patterns(m_tmp1); + TRACE("pattern_inference", + tout << "candidates after removing looping-patterns:\n"; + dump_app_vector(tout, m_tmp1, m);); + SASSERT(!m_tmp1.empty()); + if (!has_preferred_patterns(m_tmp1, result)) { + // continue if there are no preferred patterns + m_tmp2.reset(); + filter_bigger_patterns(m_tmp1, m_tmp2); + SASSERT(!m_tmp2.empty()); + TRACE("pattern_inference", + tout << "candidates after removing bigger patterns:\n"; + dump_app_vector(tout, m_tmp2, m);); + m_tmp1.reset(); + candidates2unary_patterns(m_tmp2, m_tmp1, result); + unsigned num_extra_multi_patterns = m_params.m_pi_max_multi_patterns; + if (result.empty()) + num_extra_multi_patterns++; + if (num_extra_multi_patterns > 0 && !m_tmp1.empty()) { + // m_pattern_weight_lt is not a total order + std::stable_sort(m_tmp1.begin(), m_tmp1.end(), m_pattern_weight_lt); + TRACE("pattern_inference", + tout << "candidates after sorting:\n"; + dump_app_vector(tout, m_tmp1, m);); + candidates2multi_patterns(num_extra_multi_patterns, m_tmp1, result); + } + } + } + + reset_pre_patterns(); + m_candidates_info.reset(); + m_candidates.reset(); +} + + +bool pattern_inference_cfg::reduce_quantifier( + quantifier * q, + expr * new_body, + expr * const *, // new_patterns + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr) { + + TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";); + if (!q->is_forall()) { + return false; + } + + int weight = q->get_weight(); + + if (m_params.m_pi_use_database) { + app_ref_vector new_patterns(m); + m_database.initialize(g_pattern_database); + unsigned new_weight; + if (m_database.match_quantifier(q, new_patterns, new_weight)) { + DEBUG_CODE(for (unsigned i = 0; i < new_patterns.size(); i++) { SASSERT(is_well_sorted(m, new_patterns.get(i))); }); + quantifier_ref new_q(m); + if (q->get_num_patterns() > 0) { + // just update the weight... + TRACE("pattern_inference", tout << "updating weight to: " << new_weight << "\n" << mk_pp(q, m) << "\n";); + result = m.update_quantifier_weight(q, new_weight); + } + else { + quantifier_ref tmp(m); + tmp = m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), q->get_expr()); + result = m.update_quantifier_weight(tmp, new_weight); + TRACE("pattern_inference", tout << "found patterns in database, weight: " << new_weight << "\n" << mk_pp(new_q, m) << "\n";); + } + if (m.fine_grain_proofs()) + result_pr = m.mk_rewrite(q, new_q); + return true; + } + } + + if (q->get_num_patterns() > 0) { + return false; + } + + if (m_params.m_pi_nopat_weight >= 0) + weight = m_params.m_pi_nopat_weight; + + SASSERT(q->get_num_patterns() == 0); + + if (m_params.m_pi_arith == AP_CONSERVATIVE) + m_forbidden.push_back(m_afid); + + app_ref_buffer new_patterns(m); + unsigned num_no_patterns = q->get_num_no_patterns(); + mk_patterns(q->get_num_decls(), new_body, num_no_patterns, new_no_patterns, new_patterns); + + if (new_patterns.empty() && num_no_patterns > 0) { + if (new_patterns.empty()) { + mk_patterns(q->get_num_decls(), new_body, 0, 0, new_patterns); + if (m_params.m_pi_warnings && !new_patterns.empty()) { + warning_msg("ignoring nopats annotation because Z3 couldn't find any other pattern (quantifier id: %s)", q->get_qid().str().c_str()); + } + } + } + + if (m_params.m_pi_arith == AP_CONSERVATIVE) { + m_forbidden.pop_back(); + if (new_patterns.empty()) { + flet l1(m_block_loop_patterns, false); // allow looping patterns + mk_patterns(q->get_num_decls(), new_body, num_no_patterns, new_no_patterns, new_patterns); + if (!new_patterns.empty()) { + weight = std::max(weight, static_cast(m_params.m_pi_arith_weight)); + if (m_params.m_pi_warnings) { + warning_msg("using arith. in pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_ARITH_WEIGHT=).", + q->get_qid().str().c_str(), weight); + } + } + } + } + + if (m_params.m_pi_arith != AP_NO && new_patterns.empty()) { + if (new_patterns.empty()) { + flet l1(m_nested_arith_only, false); // try to find a non-nested arith pattern + flet l2(m_block_loop_patterns, false); // allow looping patterns + mk_patterns(q->get_num_decls(), new_body, num_no_patterns, new_no_patterns, new_patterns); + if (!new_patterns.empty()) { + weight = std::max(weight, static_cast(m_params.m_pi_non_nested_arith_weight)); + if (m_params.m_pi_warnings) { + warning_msg("using non nested arith. pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_NON_NESTED_ARITH_WEIGHT=).", + q->get_qid().str().c_str(), weight); + } + // verbose_stream() << mk_pp(q, m) << "\n"; + } + } + } + + quantifier_ref new_q(m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_body), m); + if (weight != q->get_weight()) + new_q = m.update_quantifier_weight(new_q, weight); + if (m.fine_grain_proofs()) { + proof* new_body_pr = m.mk_reflexivity(new_body); + result_pr = m.mk_quant_intro(q, new_q, new_body_pr); + } + + if (new_patterns.empty() && m_params.m_pi_pull_quantifiers) { + pull_quant pull(m); + expr_ref new_expr(m); + proof_ref new_pr(m); + pull(new_q, new_expr, new_pr); + quantifier * result2 = to_quantifier(new_expr); + if (result2 != new_q) { + mk_patterns(result2->get_num_decls(), result2->get_expr(), 0, 0, new_patterns); + if (!new_patterns.empty()) { + if (m_params.m_pi_warnings) { + warning_msg("pulled nested quantifier to be able to find an useable pattern (quantifier id: %s)", q->get_qid().str().c_str()); + } + new_q = m.update_quantifier(result2, new_patterns.size(), (expr**) new_patterns.c_ptr(), result2->get_expr()); + if (m.fine_grain_proofs()) { + result_pr = m.mk_transitivity(new_pr, m.mk_quant_intro(result2, new_q, m.mk_reflexivity(new_q->get_expr()))); + } + TRACE("pattern_inference", tout << "pulled quantifier:\n" << mk_pp(new_q, m) << "\n";); + } + } + } + + if (new_patterns.empty()) { + if (m_params.m_pi_warnings) { + warning_msg("failed to find a pattern for quantifier (quantifier id: %s)", q->get_qid().str().c_str()); + } + TRACE("pi_failed", tout << mk_pp(q, m) << "\n";); + } + + if (new_patterns.empty() && new_body == q->get_expr()) { + return false; + } + + result = new_q; + + IF_IVERBOSE(10, + verbose_stream() << "(smt.inferred-patterns :qid " << q->get_qid() << "\n"; + for (unsigned i = 0; i < new_patterns.size(); i++) + verbose_stream() << " " << mk_ismt2_pp(new_patterns[i], m, 2) << "\n"; + verbose_stream() << ")\n"; ); + + return true; +} + +pattern_inference_rw::pattern_inference_rw(ast_manager& m, pattern_inference_params & params): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m, params) +{} diff --git a/src/ast/pattern/pattern_inference.h b/src/ast/pattern/pattern_inference.h index a138d1033..7b0ec9cfe 100644 --- a/src/ast/pattern/pattern_inference.h +++ b/src/ast/pattern/pattern_inference.h @@ -21,6 +21,7 @@ Revision History: #include "ast/ast.h" #include "ast/simplifier/simplifier.h" +#include "ast/rewriter/rewriter.h" #include "ast/pattern/pattern_inference_params.h" #include "util/vector.h" #include "util/uint_set.h" @@ -60,7 +61,7 @@ public: bool operator()(unsigned num_bindings, expr * p1, expr * p2); }; -class pattern_inference : public simplifier { +class pattern_inference_old : public simplifier { pattern_inference_params & m_params; family_id m_bfid; family_id m_afid; @@ -88,7 +89,7 @@ class pattern_inference : public simplifier { typedef obj_map expr2info; - expr2info m_candidates_info; // candidate -> set of free vars + size + expr2info m_candidates_info; // candidate -> set of free vars + size app_ref_vector m_candidates; ptr_vector m_tmp1; @@ -136,7 +137,7 @@ class pattern_inference : public simplifier { }; ast_manager & m; - pattern_inference & m_owner; + pattern_inference_old & m_owner; family_id m_afid; unsigned m_num_bindings; typedef map, default_eq > cache; @@ -150,7 +151,7 @@ class pattern_inference : public simplifier { void save_candidate(expr * n, unsigned delta); void reset(); public: - collect(ast_manager & m, pattern_inference & o):m(m), m_owner(o), m_afid(m.mk_family_id("arith")) {} + collect(ast_manager & m, pattern_inference_old & o):m(m), m_owner(o), m_afid(m.mk_family_id("arith")) {} void operator()(expr * n, unsigned num_bindings); }; @@ -165,12 +166,12 @@ class pattern_inference : public simplifier { void filter_bigger_patterns(ptr_vector const & patterns, ptr_vector & result); class contains_subpattern { - pattern_inference & m_owner; + pattern_inference_old & m_owner; nat_set m_already_processed; ptr_vector m_todo; void save(expr * n); public: - contains_subpattern(pattern_inference & owner): + contains_subpattern(pattern_inference_old & owner): m_owner(owner) {} bool operator()(expr * n); }; @@ -217,7 +218,7 @@ class pattern_inference : public simplifier { virtual void reduce1_quantifier(quantifier * q); public: - pattern_inference(ast_manager & m, pattern_inference_params & params); + pattern_inference_old(ast_manager & m, pattern_inference_params & params); void register_forbidden_family(family_id fid) { SASSERT(fid != m_bfid); @@ -244,5 +245,201 @@ public: bool is_forbidden(app * n) const; }; +class pattern_inference_cfg : public default_rewriter_cfg { + ast_manager& m; + pattern_inference_params & m_params; + family_id m_bfid; + family_id m_afid; + svector m_forbidden; + obj_hashtable m_preferred; + smaller_pattern m_le; + unsigned m_num_bindings; + unsigned m_num_no_patterns; + expr * const * m_no_patterns; + bool m_nested_arith_only; + bool m_block_loop_patterns; + + struct info { + uint_set m_free_vars; + unsigned m_size; + info(uint_set const & vars, unsigned size): + m_free_vars(vars), + m_size(size) { + } + info(): + m_free_vars(), + m_size(0) { + } + }; + + typedef obj_map expr2info; + + expr2info m_candidates_info; // candidate -> set of free vars + size + app_ref_vector m_candidates; + + ptr_vector m_tmp1; + ptr_vector m_tmp2; + ptr_vector m_todo; + + // Compare candidates patterns based on their usefulness + // p1 < p2 if + // - p1 has more free variables than p2 + // - p1 and p2 has the same number of free variables, + // and p1 is smaller than p2. + struct pattern_weight_lt { + expr2info & m_candidates_info; + pattern_weight_lt(expr2info & i): + m_candidates_info(i) { + } + bool operator()(expr * n1, expr * n2) const; + }; + + pattern_weight_lt m_pattern_weight_lt; + + // + // Functor for collecting candidates. + // + class collect { + struct entry { + expr * m_node; + unsigned m_delta; + entry():m_node(0), m_delta(0) {} + entry(expr * n, unsigned d):m_node(n), m_delta(d) {} + unsigned hash() const { + return hash_u_u(m_node->get_id(), m_delta); + } + bool operator==(entry const & e) const { + return m_node == e.m_node && m_delta == e.m_delta; + } + }; + + struct info { + expr_ref m_node; + uint_set m_free_vars; + unsigned m_size; + info(ast_manager & m, expr * n, uint_set const & vars, unsigned sz): + m_node(n, m), m_free_vars(vars), m_size(sz) {} + }; + + ast_manager & m; + pattern_inference_cfg & m_owner; + family_id m_afid; + unsigned m_num_bindings; + typedef map, default_eq > cache; + cache m_cache; + ptr_vector m_info; + svector m_todo; + + void visit(expr * n, unsigned delta, bool & visited); + bool visit_children(expr * n, unsigned delta); + void save(expr * n, unsigned delta, info * i); + void save_candidate(expr * n, unsigned delta); + void reset(); + public: + collect(ast_manager & m, pattern_inference_cfg & o):m(m), m_owner(o), m_afid(m.mk_family_id("arith")) {} + void operator()(expr * n, unsigned num_bindings); + }; + + collect m_collect; + + void add_candidate(app * n, uint_set const & s, unsigned size); + + void filter_looping_patterns(ptr_vector & result); + + bool has_preferred_patterns(ptr_vector & candidate_patterns, app_ref_buffer & result); + + void filter_bigger_patterns(ptr_vector const & patterns, ptr_vector & result); + + class contains_subpattern { + pattern_inference_cfg & m_owner; + nat_set m_already_processed; + ptr_vector m_todo; + void save(expr * n); + public: + contains_subpattern(pattern_inference_cfg & owner): + m_owner(owner) {} + bool operator()(expr * n); + }; + + contains_subpattern m_contains_subpattern; + + bool contains_subpattern(expr * n); + + struct pre_pattern { + ptr_vector m_exprs; // elements of the pattern. + uint_set m_free_vars; // set of free variables in m_exprs + unsigned m_idx; // idx of the next candidate to process. + pre_pattern(): + m_idx(0) { + } + }; + + ptr_vector m_pre_patterns; + expr_pattern_match m_database; + + void candidates2unary_patterns(ptr_vector const & candidate_patterns, + ptr_vector & remaining_candidate_patterns, + app_ref_buffer & result); + + void candidates2multi_patterns(unsigned max_num_patterns, + ptr_vector const & candidate_patterns, + app_ref_buffer & result); + + void reset_pre_patterns(); + + /** + \brief All minimal unary patterns (i.e., expressions that + contain all bound variables) are copied to result. If there + are unary patterns, then at most num_extra_multi_patterns multi + patterns are created. If there are no unary pattern, then at + most 1 + num_extra_multi_patterns multi_patterns are created. + */ + void mk_patterns(unsigned num_bindings, // IN number of bindings. + expr * n, // IN node where the patterns are going to be extracted. + unsigned num_no_patterns, // IN num. patterns that should not be used. + expr * const * no_patterns, // IN patterns that should not be used. + app_ref_buffer & result); // OUT result + +public: + pattern_inference_cfg(ast_manager & m, pattern_inference_params & params); + + void register_forbidden_family(family_id fid) { + SASSERT(fid != m_bfid); + m_forbidden.push_back(fid); + } + + /** + \brief Register f as a preferred function symbol. The inference algorithm + gives preference to patterns rooted by this kind of function symbol. + */ + void register_preferred(func_decl * f) { + m_preferred.insert(f); + } + + bool reduce_quantifier(quantifier * old_q, + expr * new_body, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr); + + void register_preferred(unsigned num, func_decl * const * fs) { for (unsigned i = 0; i < num; i++) register_preferred(fs[i]); } + + bool is_forbidden(func_decl const * decl) const { + family_id fid = decl->get_family_id(); + if (fid == m_bfid && decl->get_decl_kind() != OP_TRUE && decl->get_decl_kind() != OP_FALSE) + return true; + return std::find(m_forbidden.begin(), m_forbidden.end(), fid) != m_forbidden.end(); + } + + bool is_forbidden(app * n) const; +}; + +class pattern_inference_rw : public rewriter_tpl { + pattern_inference_cfg m_cfg; +public: + pattern_inference_rw(ast_manager& m, pattern_inference_params & params); +}; + #endif /* PATTERN_INFERENCE_H_ */ diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp index 7eb2284c0..cfb998a32 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp @@ -70,7 +70,7 @@ namespace datalog { if (q->get_num_patterns() == 0) { proof_ref new_pr(m); pattern_inference_params params; - pattern_inference infer(m, params); + pattern_inference_old infer(m, params); infer(q, qe, new_pr); q = to_quantifier(qe); } diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 7eb189ebf..26265a6f8 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -21,6 +21,7 @@ Revision History: #include "ast/ast_pp.h" #include "ast/for_each_expr.h" #include "ast/well_sorted.h" +#include "ast/rewriter/rewriter_def.h" #include "ast/simplifier/arith_simplifier_plugin.h" #include "ast/simplifier/array_simplifier_plugin.h" #include "ast/simplifier/datatype_simplifier_plugin.h" @@ -517,7 +518,7 @@ void asserted_formulas::reduce_and_solve() { void asserted_formulas::infer_patterns() { IF_IVERBOSE(10, verbose_stream() << "(smt.pattern-inference)\n";); TRACE("before_pattern_inference", display(tout);); - pattern_inference infer(m, m_params); + pattern_inference_rw infer(m, m_params); expr_ref_vector new_exprs(m); proof_ref_vector new_prs(m); unsigned i = m_asserted_qhead; diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index 725c9fc51..0a75ff700 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -207,8 +207,10 @@ void proto_model::remove_aux_decls_not_in_set(ptr_vector & decls, fun by their interpretations. */ void proto_model::cleanup() { + TRACE("model_bug", model_v2_pp(tout, *this);); func_decl_set found_aux_fs; for (auto const& kv : m_finterp) { + TRACE("model_bug", tout << kv.m_key->get_name() << "\n";); func_interp * fi = kv.m_value; cleanup_func_interp(fi, found_aux_fs); } @@ -365,7 +367,7 @@ void proto_model::complete_partial_funcs() { } model * proto_model::mk_model() { - TRACE("proto_model", tout << "mk_model\n"; model_v2_pp(tout, *this);); + TRACE("proto_model", model_v2_pp(tout << "mk_model\n", *this);); model * m = alloc(model, m_manager); for (auto const& kv : m_interp) { diff --git a/src/smt/smt_model_generator.cpp b/src/smt/smt_model_generator.cpp index 953afd4b7..5848fac62 100644 --- a/src/smt/smt_model_generator.cpp +++ b/src/smt/smt_model_generator.cpp @@ -19,7 +19,6 @@ Revision History: #include "util/ref_util.h" #include "ast/for_each_expr.h" -#include "ast/ast_ll_pp.h" #include "ast/ast_pp.h" #include "ast/ast_smt2_pp.h" #include "smt/smt_context.h" From f062e170373b1e1c3e7344b0b2a6c0bf93c14097 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Aug 2017 12:30:33 -0700 Subject: [PATCH 176/488] remove simplifier dependencies from ufbv tactics Signed-off-by: Nikolaj Bjorner --- src/tactic/ufbv/macro_finder_tactic.cpp | 16 ---------------- src/tactic/ufbv/quasi_macros_tactic.cpp | 17 +---------------- src/tactic/ufbv/ufbv_rewriter.cpp | 13 ++++++++----- src/tactic/ufbv/ufbv_rewriter.h | 6 +++--- src/tactic/ufbv/ufbv_rewriter_tactic.cpp | 6 +----- 5 files changed, 13 insertions(+), 45 deletions(-) diff --git a/src/tactic/ufbv/macro_finder_tactic.cpp b/src/tactic/ufbv/macro_finder_tactic.cpp index b3f258ba7..3832339a8 100644 --- a/src/tactic/ufbv/macro_finder_tactic.cpp +++ b/src/tactic/ufbv/macro_finder_tactic.cpp @@ -17,10 +17,6 @@ Notes: --*/ #include "tactic/tactical.h" -#include "ast/simplifier/simplifier.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/macros/macro_manager.h" #include "ast/macros/macro_finder.h" #include "tactic/extension_model_converter.h" @@ -52,18 +48,6 @@ class macro_finder_tactic : public tactic { fail_if_unsat_core_generation("macro-finder", g); bool produce_proofs = g->proofs_enabled(); - - simplifier simp(m_manager); - basic_simplifier_plugin * bsimp = alloc(basic_simplifier_plugin, m_manager); - bsimp->set_eliminate_and(m_elim_and); - simp.register_plugin(bsimp); - arith_simplifier_params a_params; - arith_simplifier_plugin * asimp = alloc(arith_simplifier_plugin, m_manager, *bsimp, a_params); - simp.register_plugin(asimp); - bv_simplifier_params bv_params; - bv_simplifier_plugin * bvsimp = alloc(bv_simplifier_plugin, m_manager, *bsimp, bv_params); - simp.register_plugin(bvsimp); - macro_manager mm(m_manager); macro_finder mf(m_manager, mm); diff --git a/src/tactic/ufbv/quasi_macros_tactic.cpp b/src/tactic/ufbv/quasi_macros_tactic.cpp index 8a91bde61..8196dc664 100644 --- a/src/tactic/ufbv/quasi_macros_tactic.cpp +++ b/src/tactic/ufbv/quasi_macros_tactic.cpp @@ -17,10 +17,6 @@ Notes: --*/ #include "tactic/tactical.h" -#include "ast/simplifier/simplifier.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/macros/macro_manager.h" #include "ast/macros/macro_finder.h" #include "tactic/extension_model_converter.h" @@ -50,18 +46,7 @@ class quasi_macros_tactic : public tactic { fail_if_unsat_core_generation("quasi-macros", g); bool produce_proofs = g->proofs_enabled(); - - simplifier simp(m_manager); - basic_simplifier_plugin * bsimp = alloc(basic_simplifier_plugin, m_manager); - bsimp->set_eliminate_and(true); - simp.register_plugin(bsimp); - arith_simplifier_params a_params; - arith_simplifier_plugin * asimp = alloc(arith_simplifier_plugin, m_manager, *bsimp, a_params); - simp.register_plugin(asimp); - bv_simplifier_params bv_params; - bv_simplifier_plugin * bvsimp = alloc(bv_simplifier_plugin, m_manager, *bsimp, bv_params); - simp.register_plugin(bvsimp); - + macro_manager mm(m_manager); quasi_macros qm(m_manager, mm); bool more = true; diff --git a/src/tactic/ufbv/ufbv_rewriter.cpp b/src/tactic/ufbv/ufbv_rewriter.cpp index 4f0f5e548..446d1a49c 100644 --- a/src/tactic/ufbv/ufbv_rewriter.cpp +++ b/src/tactic/ufbv/ufbv_rewriter.cpp @@ -20,20 +20,23 @@ Revision History: --*/ +#include "util/uint_set.h" #include "ast/ast_pp.h" -#include "tactic/ufbv/ufbv_rewriter.h" #include "ast/for_each_expr.h" #include "ast/rewriter/var_subst.h" -#include "util/uint_set.h" +#include "tactic/ufbv/ufbv_rewriter.h" -ufbv_rewriter::ufbv_rewriter(ast_manager & m, basic_simplifier_plugin & p): +ufbv_rewriter::ufbv_rewriter(ast_manager & m): m_manager(m), m_match_subst(m), - m_bsimp(p), + m_bsimp(m), m_todo(m), m_rewrite_todo(m), m_rewrite_cache(m), m_new_exprs(m) { + params_ref p; + p.set_bool("elim_and", true); + m_bsimp.updt_params(p); } ufbv_rewriter::~ufbv_rewriter() { @@ -396,7 +399,7 @@ expr * ufbv_rewriter::rewrite(expr * n) { if (f->get_family_id() != m_manager.get_basic_family_id()) na = m_manager.mk_app(f, m_new_args.size(), m_new_args.c_ptr()); else - m_bsimp.reduce(f, m_new_args.size(), m_new_args.c_ptr(), na); + m_bsimp.mk_app(f, m_new_args.size(), m_new_args.c_ptr(), na); TRACE("demodulator_bug", tout << "e:\n" << mk_pp(e, m_manager) << "\nnew_args: \n"; for (unsigned i = 0; i < m_new_args.size(); i++) { tout << mk_pp(m_new_args[i], m_manager) << "\n"; } tout << "=====>\n"; diff --git a/src/tactic/ufbv/ufbv_rewriter.h b/src/tactic/ufbv/ufbv_rewriter.h index d11453836..1e13f4fa4 100644 --- a/src/tactic/ufbv/ufbv_rewriter.h +++ b/src/tactic/ufbv/ufbv_rewriter.h @@ -23,10 +23,10 @@ Revision History: #include "ast/ast.h" #include "ast/substitution/substitution.h" +#include "ast/rewriter/bool_rewriter.h" #include "util/obj_hashtable.h" #include "util/obj_pair_hashtable.h" #include "util/array_map.h" -#include "ast/simplifier/basic_simplifier_plugin.h" /** \brief Apply demodulators as a preprocessing technique. @@ -159,7 +159,7 @@ class ufbv_rewriter { ast_manager & m_manager; match_subst m_match_subst; - basic_simplifier_plugin & m_bsimp; + bool_rewriter m_bsimp; fwd_idx_map m_fwd_idx; back_idx_map m_back_idx; demodulator2lhs_rhs m_demodulator2lhs_rhs; @@ -194,7 +194,7 @@ protected: virtual int is_subset(expr * e1, expr * e2) const; public: - ufbv_rewriter(ast_manager & m, basic_simplifier_plugin & p); + ufbv_rewriter(ast_manager & m); virtual ~ufbv_rewriter(); void operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); diff --git a/src/tactic/ufbv/ufbv_rewriter_tactic.cpp b/src/tactic/ufbv/ufbv_rewriter_tactic.cpp index b4bfabf65..615593317 100644 --- a/src/tactic/ufbv/ufbv_rewriter_tactic.cpp +++ b/src/tactic/ufbv/ufbv_rewriter_tactic.cpp @@ -17,8 +17,6 @@ Notes: --*/ #include "tactic/tactical.h" -#include "ast/simplifier/simplifier.h" -#include "ast/simplifier/basic_simplifier_plugin.h" #include "tactic/ufbv/ufbv_rewriter.h" #include "tactic/ufbv/ufbv_rewriter_tactic.h" @@ -45,9 +43,7 @@ class ufbv_rewriter_tactic : public tactic { bool produce_proofs = g->proofs_enabled(); - basic_simplifier_plugin bsimp(m_manager); - bsimp.set_eliminate_and(true); - ufbv_rewriter dem(m_manager, bsimp); + ufbv_rewriter dem(m_manager); expr_ref_vector forms(m_manager), new_forms(m_manager); proof_ref_vector proofs(m_manager), new_proofs(m_manager); From 40f2afb5afc8a59526678337afa2d02f8a2b6e0a Mon Sep 17 00:00:00 2001 From: Dewald de Jager Date: Wed, 23 Aug 2017 23:09:47 +0200 Subject: [PATCH 177/488] [Doxygen] Fix function name in docstring Amending the changes made in https://github.com/Z3Prover/z3/commit/fe702d7782db990cb90ff2bea390b100fdd65872 --- src/api/z3_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 8d53c9255..43c175ca8 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -1530,7 +1530,7 @@ extern "C" { In contrast to #Z3_mk_context_rc, the life time of Z3_ast objects are determined by the scope level of #Z3_solver_push and #Z3_solver_pop. In other words, a Z3_ast object remains valid until there is a - call to Z3_pop that takes the current scope below the level where + call to Z3_solver_pop that takes the current scope below the level where the object was created. Note that all other reference counted objects, including Z3_model, From 7dd28781ab5f26703e8bb79ceee79e4c44bdc339 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Aug 2017 16:33:36 -0700 Subject: [PATCH 178/488] remove simplifier dependencies from cmakelist.txt files Signed-off-by: Nikolaj Bjorner --- src/ast/fpa/CMakeLists.txt | 2 +- src/ast/macros/CMakeLists.txt | 2 +- src/ast/pattern/CMakeLists.txt | 2 +- src/ast/pattern/pattern_inference.cpp | 19 ++++++++++++------- src/ast/pattern/pattern_inference.h | 2 ++ src/ast/rewriter/bit_blaster/CMakeLists.txt | 1 - src/model/model_core.cpp | 16 ++++++---------- .../dl_mk_quantifier_instantiation.cpp | 2 +- src/smt/proto_model/CMakeLists.txt | 2 +- 9 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/ast/fpa/CMakeLists.txt b/src/ast/fpa/CMakeLists.txt index 4a9506d16..2a6d0763c 100644 --- a/src/ast/fpa/CMakeLists.txt +++ b/src/ast/fpa/CMakeLists.txt @@ -5,7 +5,7 @@ z3_add_component(fpa fpa2bv_rewriter.cpp COMPONENT_DEPENDENCIES ast - simplifier + rewriter model util PYG_FILES diff --git a/src/ast/macros/CMakeLists.txt b/src/ast/macros/CMakeLists.txt index ca38b4759..ec6d7e26c 100644 --- a/src/ast/macros/CMakeLists.txt +++ b/src/ast/macros/CMakeLists.txt @@ -5,5 +5,5 @@ z3_add_component(macros macro_util.cpp quasi_macros.cpp COMPONENT_DEPENDENCIES - simplifier + rewriter ) diff --git a/src/ast/pattern/CMakeLists.txt b/src/ast/pattern/CMakeLists.txt index 6e8301afc..5531bb29b 100644 --- a/src/ast/pattern/CMakeLists.txt +++ b/src/ast/pattern/CMakeLists.txt @@ -29,7 +29,7 @@ z3_add_component(pattern ${CMAKE_CURRENT_BINARY_DIR}/database.h COMPONENT_DEPENDENCIES normal_forms - simplifier + rewriter smt2parser PYG_FILES pattern_inference_params_helper.pyg diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index 94a90d829..dfeb29ffe 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -89,6 +89,15 @@ bool smaller_pattern::operator()(unsigned num_bindings, expr * p1, expr * p2) { return process(p1, p2); } + +#ifdef _TRACE +static void dump_app_vector(std::ostream & out, ptr_vector const & v, ast_manager & m) { + for (app * e : v) + out << mk_pp(e, m) << "\n"; +} +#endif + +#if 0 pattern_inference_old::pattern_inference_old(ast_manager & m, pattern_inference_params & params): simplifier(m), m_params(params), @@ -470,12 +479,6 @@ void pattern_inference_old::reset_pre_patterns() { m_pre_patterns.reset(); } -#ifdef _TRACE -static void dump_app_vector(std::ostream & out, ptr_vector const & v, ast_manager & m) { - for (app * e : v) - out << mk_pp(e, m) << "\n"; -} -#endif bool pattern_inference_old::is_forbidden(app * n) const { func_decl const * decl = n->get_decl(); @@ -567,7 +570,6 @@ void pattern_inference_old::mk_patterns(unsigned num_bindings, m_candidates.reset(); } -#include "ast/pattern/database.h" void pattern_inference_old::reduce1_quantifier(quantifier * q) { TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";); @@ -729,6 +731,9 @@ void pattern_inference_old::reduce1_quantifier(quantifier * q) { cache_result(q, new_q, pr); } +#endif + +#include "ast/pattern/database.h" pattern_inference_cfg::pattern_inference_cfg(ast_manager & m, pattern_inference_params & params): diff --git a/src/ast/pattern/pattern_inference.h b/src/ast/pattern/pattern_inference.h index 7b0ec9cfe..281c3ff8b 100644 --- a/src/ast/pattern/pattern_inference.h +++ b/src/ast/pattern/pattern_inference.h @@ -61,6 +61,7 @@ public: bool operator()(unsigned num_bindings, expr * p1, expr * p2); }; +#if 0 class pattern_inference_old : public simplifier { pattern_inference_params & m_params; family_id m_bfid; @@ -244,6 +245,7 @@ public: bool is_forbidden(app * n) const; }; +#endif class pattern_inference_cfg : public default_rewriter_cfg { ast_manager& m; diff --git a/src/ast/rewriter/bit_blaster/CMakeLists.txt b/src/ast/rewriter/bit_blaster/CMakeLists.txt index 9eea1558e..c8985a051 100644 --- a/src/ast/rewriter/bit_blaster/CMakeLists.txt +++ b/src/ast/rewriter/bit_blaster/CMakeLists.txt @@ -4,5 +4,4 @@ z3_add_component(bit_blaster bit_blaster_rewriter.cpp COMPONENT_DEPENDENCIES rewriter - simplifier ) diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 5eb1eb00d..2fd2d8746 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -19,18 +19,14 @@ Revision History: #include "model/model_core.h" model_core::~model_core() { - decl2expr::iterator it1 = m_interp.begin(); - decl2expr::iterator end1 = m_interp.end(); - for (; it1 != end1; ++it1) { - m_manager.dec_ref(it1->m_key); - m_manager.dec_ref(it1->m_value); + for (auto & kv : m_interp) { + m_manager.dec_ref(kv.m_key); + m_manager.dec_ref(kv.m_value); } - decl2finterp::iterator it2 = m_finterp.begin(); - decl2finterp::iterator end2 = m_finterp.end(); - for (; it2 != end2; ++it2) { - m_manager.dec_ref(it2->m_key); - dealloc(it2->m_value); + for (auto & kv : m_finterp) { + m_manager.dec_ref(kv.m_key); + dealloc(kv.m_value); } } diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp index cfb998a32..f32840c49 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp @@ -70,7 +70,7 @@ namespace datalog { if (q->get_num_patterns() == 0) { proof_ref new_pr(m); pattern_inference_params params; - pattern_inference_old infer(m, params); + pattern_inference_rw infer(m, params); infer(q, qe, new_pr); q = to_quantifier(qe); } diff --git a/src/smt/proto_model/CMakeLists.txt b/src/smt/proto_model/CMakeLists.txt index 0539c0fb0..c5f6c4b18 100644 --- a/src/smt/proto_model/CMakeLists.txt +++ b/src/smt/proto_model/CMakeLists.txt @@ -8,6 +8,6 @@ z3_add_component(proto_model value_factory.cpp COMPONENT_DEPENDENCIES model - simplifier + rewriter smt_params ) From f91496f5fff77ad04647ff3c9f350a8e92a3641c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Aug 2017 16:56:55 -0700 Subject: [PATCH 179/488] pruning simplifier dependencies Signed-off-by: Nikolaj Bjorner --- src/ast/simplifier/pull_ite_tree.cpp | 10 +++++----- src/ast/simplifier/pull_ite_tree.h | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ast/simplifier/pull_ite_tree.cpp b/src/ast/simplifier/pull_ite_tree.cpp index 072bbd12c..a092f9649 100644 --- a/src/ast/simplifier/pull_ite_tree.cpp +++ b/src/ast/simplifier/pull_ite_tree.cpp @@ -21,9 +21,9 @@ Revision History: #include "ast/for_each_expr.h" #include "ast/ast_pp.h" -pull_ite_tree::pull_ite_tree(ast_manager & m, simplifier & s): +pull_ite_tree::pull_ite_tree(ast_manager & m): m_manager(m), - m_simplifier(s), + m_rewriter(m), m_cache(m) { } @@ -64,7 +64,7 @@ void pull_ite_tree::reduce(expr * n) { get_cached(e_old, e, e_pr); expr_ref r(m_manager); expr * args[3] = {c, t, e}; - m_simplifier.mk_app(to_app(n)->get_decl(), 3, args, r); + r = m_rewriter.mk_app(to_app(n)->get_decl(), 3, args); if (!m_manager.proofs_enabled()) { // expr * r = m_manager.mk_ite(c, t, e); cache_result(n, r, 0); @@ -117,7 +117,7 @@ void pull_ite_tree::reduce(expr * n) { else { expr_ref r(m_manager); m_args[m_arg_idx] = n; - m_simplifier.mk_app(m_p, m_args.size(), m_args.c_ptr(), r); + r = m_rewriter.mk_app(m_p, m_args.size(), m_args.c_ptr()); if (!m_manager.proofs_enabled()) { // expr * r = m_manager.mk_app(m_p, m_args.size(), m_args.c_ptr()); cache_result(n, r, 0); @@ -181,7 +181,7 @@ void pull_ite_tree::operator()(app * n, app_ref & r, proof_ref & pr) { pull_ite_tree_star::pull_ite_tree_star(ast_manager & m, simplifier & s): simplifier(m), - m_proc(m, s) { + m_proc(m) { borrow_plugins(s); } diff --git a/src/ast/simplifier/pull_ite_tree.h b/src/ast/simplifier/pull_ite_tree.h index bc4a0bb68..4b35c124a 100644 --- a/src/ast/simplifier/pull_ite_tree.h +++ b/src/ast/simplifier/pull_ite_tree.h @@ -20,6 +20,7 @@ Revision History: #define PULL_ITE_TREE_H_ #include "ast/ast.h" +#include "ast/rewriter/th_rewriter.h" #include "ast/simplifier/simplifier.h" #include "ast/recurse_expr.h" #include "util/obj_hashtable.h" @@ -34,7 +35,7 @@ Revision History: */ class pull_ite_tree { ast_manager & m_manager; - simplifier & m_simplifier; + th_rewriter m_rewriter; func_decl * m_p; ptr_vector m_args; unsigned m_arg_idx; //!< position of the ite argument @@ -56,7 +57,7 @@ class pull_ite_tree { return m_manager.mk_app(m_p, m_args.size(), m_args.c_ptr()); } public: - pull_ite_tree(ast_manager & m, simplifier & s); + pull_ite_tree(ast_manager & m); /** \brief Apply the transformation above if n contains an ite-expression. Store the result in r. If n does not contain an ite-expression, then From 8b2d60e3caceb6c6803d653c7e8a48b3b6e587b0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 23 Aug 2017 17:57:03 -0700 Subject: [PATCH 180/488] using rewrite in push_app_ite Signed-off-by: Nikolaj Bjorner --- src/ast/simplifier/pull_ite_tree.cpp | 36 +++++++++++++++ src/ast/simplifier/pull_ite_tree.h | 44 ++++++++++++++++++- src/ast/simplifier/push_app_ite.cpp | 65 +++++++++++++++++++++++++++- src/ast/simplifier/push_app_ite.h | 43 +++++++++++++++++- src/smt/asserted_formulas.cpp | 6 +-- 5 files changed, 187 insertions(+), 7 deletions(-) diff --git a/src/ast/simplifier/pull_ite_tree.cpp b/src/ast/simplifier/pull_ite_tree.cpp index a092f9649..c317cafd8 100644 --- a/src/ast/simplifier/pull_ite_tree.cpp +++ b/src/ast/simplifier/pull_ite_tree.cpp @@ -209,5 +209,41 @@ bool pull_cheap_ite_tree_star::is_target(app * n) const { +pull_ite_tree_cfg::pull_ite_tree_cfg(ast_manager & m): + m(m), + m_trail(m), + m_proc(m) { +} + +bool pull_ite_tree_cfg::get_subst(expr * n, expr* & r, proof* & p) { + if (is_app(n) && is_target(to_app(n))) { + app_ref tmp(m); + proof_ref pr(m); + m_proc(to_app(n), tmp, pr); + if (tmp != n) { + r = tmp; + p = pr; + m_trail.push_back(r); + m_trail.push_back(p); + return true; + } + } + return false; +} + +bool pull_cheap_ite_tree_cfg::is_target(app * n) const { + bool r = + n->get_num_args() == 2 && + n->get_family_id() != null_family_id && + m.is_bool(n) && + (m.is_value(n->get_arg(0)) || m.is_value(n->get_arg(1))) && + (m.is_term_ite(n->get_arg(0)) || m.is_term_ite(n->get_arg(1))); + TRACE("pull_ite_target", tout << mk_pp(n, m) << "\nresult: " << r << "\n";); + return r; +} + + + + diff --git a/src/ast/simplifier/pull_ite_tree.h b/src/ast/simplifier/pull_ite_tree.h index 4b35c124a..37837a3cf 100644 --- a/src/ast/simplifier/pull_ite_tree.h +++ b/src/ast/simplifier/pull_ite_tree.h @@ -20,11 +20,12 @@ Revision History: #define PULL_ITE_TREE_H_ #include "ast/ast.h" +#include "ast/rewriter/rewriter.h" #include "ast/rewriter/th_rewriter.h" #include "ast/simplifier/simplifier.h" +#include "ast/expr_map.h" #include "ast/recurse_expr.h" #include "util/obj_hashtable.h" -#include "ast/expr_map.h" /** \brief Functor for applying the following transformation @@ -98,5 +99,46 @@ public: virtual bool is_target(app * n) const; }; +/** + \brief Functor for applying the pull_ite_tree on subexpressions n that + satisfy the is_target virtual predicate. +*/ +class pull_ite_tree_cfg : public default_rewriter_cfg { +protected: + ast_manager& m; + expr_ref_vector m_trail; + pull_ite_tree m_proc; +public: + pull_ite_tree_cfg(ast_manager & m); + virtual ~pull_ite_tree_cfg() {} + virtual bool is_target(app * n) const = 0; + bool get_subst(expr * n, expr* & r, proof* & p); +}; + +/** + \brief Apply pull_ite_tree on predicates of the form + (p ite v) and (p v ite) + + where: + - p is an interpreted predicate + - ite is an ite-term expression + - v is a value +*/ +class pull_cheap_ite_tree_cfg : public pull_ite_tree_cfg { +public: + pull_cheap_ite_tree_cfg(ast_manager & m):pull_ite_tree_cfg(m) {} + virtual ~pull_cheap_ite_tree_cfg() {} + virtual bool is_target(app * n) const; +}; + +class pull_cheap_ite_tree_rw : public rewriter_tpl { + pull_cheap_ite_tree_cfg m_cfg; +public: + pull_cheap_ite_tree_rw(ast_manager& m): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m) + {} +}; + #endif /* PULL_ITE_TREE_H_ */ diff --git a/src/ast/simplifier/push_app_ite.cpp b/src/ast/simplifier/push_app_ite.cpp index 8b56dcd85..3d118e4ac 100644 --- a/src/ast/simplifier/push_app_ite.cpp +++ b/src/ast/simplifier/push_app_ite.cpp @@ -32,7 +32,7 @@ push_app_ite::~push_app_ite() { m_plugins.release(); } -int push_app_ite::has_ite_arg(unsigned num_args, expr * const * args) { +static int has_ite_arg(ast_manager& m, unsigned num_args, expr * const * args) { for (unsigned i = 0; i < num_args; i++) if (m.is_ite(args[i])) return i; @@ -41,7 +41,7 @@ int push_app_ite::has_ite_arg(unsigned num_args, expr * const * args) { void push_app_ite::apply(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & r) { TRACE("push_app_ite", tout << "pushing app...\n";); - int ite_arg_idx = has_ite_arg(num_args, args); + int ite_arg_idx = has_ite_arg(m, num_args, args); if (ite_arg_idx < 0) { mk_app(decl, num_args, args, r); return; @@ -218,3 +218,64 @@ bool ng_push_app_ite::is_target(func_decl * decl, unsigned num_args, expr * cons ng_push_app_ite::ng_push_app_ite(simplifier & s, bool conservative): push_app_ite(s, conservative) { } + + +/** + \brief Default (conservative) implementation. Return true if there one and only one ite-term argument. +*/ +bool push_app_ite_cfg::is_target(func_decl * decl, unsigned num_args, expr * const * args) { + if (m.is_ite(decl)) + return false; + bool found_ite = false; + for (unsigned i = 0; i < num_args; i++) { + if (m.is_ite(args[i]) && !m.is_bool(args[i])) { + if (found_ite) { + if (m_conservative) + return false; + } + else { + found_ite = true; + } + } + } + CTRACE("push_app_ite", found_ite, tout << "found target for push app ite:\n"; + tout << decl->get_name(); + for (unsigned i = 0; i < num_args; i++) tout << " " << mk_pp(args[i], m); + tout << "\n";); + return found_ite; +} + +br_status push_app_ite_cfg::reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { + if (!is_target(f, num, args)) { + return BR_FAILED; + } + int ite_arg_idx = has_ite_arg(m, num, args); + if (ite_arg_idx < 0) { + return BR_FAILED; + } + app * ite = to_app(args[ite_arg_idx]); + expr * c = 0, * t = 0, * e = 0; + VERIFY(m.is_ite(ite, c, t, e)); + expr ** args_prime = const_cast(args); + expr * old = args_prime[ite_arg_idx]; + args_prime[ite_arg_idx] = t; + expr_ref t_new(m.mk_app(f, num, args_prime), m); + args_prime[ite_arg_idx] = e; + expr_ref e_new(m.mk_app(f, num, args_prime), m); + args_prime[ite_arg_idx] = old; + result = m.mk_ite(c, t_new, e_new); + if (m.proofs_enabled()) { + result_pr = m.mk_rewrite(m.mk_app(f, num, args), result); + } + return BR_REWRITE2; +} + +bool ng_push_app_ite_cfg::is_target(func_decl * decl, unsigned num_args, expr * const * args) { + bool r = push_app_ite_cfg::is_target(decl, num_args, args); + if (!r) + return false; + for (unsigned i = 0; i < num_args; i++) + if (!is_ground(args[i])) + return true; + return false; +} diff --git a/src/ast/simplifier/push_app_ite.h b/src/ast/simplifier/push_app_ite.h index 96400b1af..4faf853ea 100644 --- a/src/ast/simplifier/push_app_ite.h +++ b/src/ast/simplifier/push_app_ite.h @@ -21,6 +21,7 @@ Revision History: #include "ast/ast.h" #include "ast/simplifier/simplifier.h" +#include "ast/rewriter/rewriter.h" /** \brief Functor for applying the following transformation: @@ -30,7 +31,6 @@ Revision History: class push_app_ite : public simplifier { protected: bool m_conservative; - int has_ite_arg(unsigned num_args, expr * const * args); void apply(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & result); virtual bool is_target(func_decl * decl, unsigned num_args, expr * const * args); void reduce_core(expr * n); @@ -59,5 +59,46 @@ public: virtual ~ng_push_app_ite() {} }; +struct push_app_ite_cfg : public default_rewriter_cfg { + ast_manager& m; + bool m_conservative; + virtual bool is_target(func_decl * decl, unsigned num_args, expr * const * args); + br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr); + push_app_ite_cfg(ast_manager& m, bool conservative = true): m(m), m_conservative(conservative) {} +}; + +/** + \brief Variation of push_app_ite that applies the transformation on nonground terms only. + + \remark This functor uses the app::is_ground method. This method is not + completly precise, for instance, any term containing a quantifier is marked as non ground. +*/ +class ng_push_app_ite_cfg : public push_app_ite_cfg { +protected: + virtual bool is_target(func_decl * decl, unsigned num_args, expr * const * args); +public: + ng_push_app_ite_cfg(ast_manager& m, bool conservative = true): push_app_ite_cfg(m, conservative) {} + virtual ~ng_push_app_ite_cfg() {} +}; + +struct push_app_ite_rw : public rewriter_tpl { + push_app_ite_cfg m_cfg; +public: + push_app_ite_rw(ast_manager& m, bool conservative = true): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m, conservative) + {} +}; + +struct ng_push_app_ite_rw : public rewriter_tpl { + ng_push_app_ite_cfg m_cfg; +public: + ng_push_app_ite_rw(ast_manager& m, bool conservative = true): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m, conservative) + {} +}; + + #endif /* PUSH_APP_ITE_H_ */ diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 26265a6f8..b475ee778 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -755,7 +755,7 @@ void asserted_formulas::propagate_booleans() { return changed; \ } -MK_SIMPLIFIER(pull_cheap_ite_trees, pull_cheap_ite_tree_star functor(m, m_simplifier), "pull_cheap_ite_trees", "pull-cheap-ite-trees", false); +MK_SIMPLIFIER(pull_cheap_ite_trees, pull_cheap_ite_tree_rw functor(m), "pull_cheap_ite_trees", "pull-cheap-ite-trees", false); MK_SIMPLIFIER(pull_nested_quantifiers, pull_nested_quant functor(m), "pull_nested_quantifiers", "pull-nested-quantifiers", false); @@ -830,8 +830,8 @@ MK_SIMPLIFIER(elim_bvs_from_quantifiers, bv_elim_star functor(m), "bv_elim", "el reduce_and_solve(); \ } -LIFT_ITE(lift_ite, push_app_ite functor(m_simplifier, m_params.m_lift_ite == LI_CONSERVATIVE), "lifting ite"); -LIFT_ITE(ng_lift_ite, ng_push_app_ite functor(m_simplifier, m_params.m_ng_lift_ite == LI_CONSERVATIVE), "lifting ng ite"); +LIFT_ITE(lift_ite, push_app_ite_rw functor(m, m_params.m_lift_ite == LI_CONSERVATIVE), "lifting ite"); +LIFT_ITE(ng_lift_ite, ng_push_app_ite_rw functor(m, m_params.m_ng_lift_ite == LI_CONSERVATIVE), "lifting ng ite"); unsigned asserted_formulas::get_total_size() const { expr_mark visited; From 5845958986611889fb64516c670571aed75eeb4e Mon Sep 17 00:00:00 2001 From: Sangwoo Joh Date: Thu, 24 Aug 2017 18:17:47 +0900 Subject: [PATCH 181/488] Bugfix: get_objectives in ML API --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c4a4da00c..46fe5bd6d 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1964,7 +1964,7 @@ struct let from_file (x:optimize) (s:string) = Z3native.optimize_from_file (gc x) x s let from_string (x:optimize) (s:string) = Z3native.optimize_from_string (gc x) x s let get_assertions (x:optimize) = AST.ASTVector.to_expr_list (Z3native.optimize_get_assertions (gc x) x) - let get_objectives (x:optimize) = AST.ASTVector.to_expr_list (Z3native.optimize_get_statistics (gc x) x) + let get_objectives (x:optimize) = AST.ASTVector.to_expr_list (Z3native.optimize_get_objectives (gc x) x) end From a7bb41fd499556f3d30e50f06fcf4dfb0274d177 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 24 Aug 2017 09:19:35 -0700 Subject: [PATCH 182/488] fix build issues Signed-off-by: Nikolaj Bjorner --- .../transforms/dl_mk_quantifier_instantiation.cpp | 1 + src/smt/asserted_formulas.cpp | 4 +++- src/smt/asserted_formulas.h | 13 +++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp index f32840c49..74d15bcdf 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp @@ -26,6 +26,7 @@ Revision History: #include "muz/transforms/dl_mk_quantifier_instantiation.h" #include "muz/base/dl_context.h" #include "ast/pattern/pattern_inference.h" +#include "ast/rewriter/rewriter_def.h" namespace datalog { diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index b475ee778..eac5f7c10 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -56,7 +56,8 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m_macro_manager(m), m_bit2int(m), m_bv_sharing(m), - m_inconsistent(false){ + m_inconsistent(false), + m_has_quantifiers(false) { m_bsimp = 0; m_bvsimp = 0; @@ -143,6 +144,7 @@ void asserted_formulas::set_eliminate_and(bool flag) { void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { if (inconsistent()) return; + m_has_quantifiers |= ::has_quantifiers(e); if (!m_params.m_preprocess) { push_assertion(e, _in_pr, m_asserted_formulas, m_asserted_formula_prs); return; diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h index 093680fd9..eaed4e405 100644 --- a/src/smt/asserted_formulas.h +++ b/src/smt/asserted_formulas.h @@ -19,17 +19,17 @@ Revision History: #ifndef ASSERTED_FORMULAS_H_ #define ASSERTED_FORMULAS_H_ -#include "smt/params/smt_params.h" +#include "util/statistics.h" +#include "ast/static_features.h" #include "ast/simplifier/simplifier.h" #include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/static_features.h" +#include "ast/simplifier/maximise_ac_sharing.h" +#include "ast/simplifier/bit2int.h" #include "ast/macros/macro_manager.h" #include "ast/macros/macro_finder.h" #include "ast/normal_forms/defined_names.h" -#include "ast/simplifier/maximise_ac_sharing.h" -#include "ast/simplifier/bit2int.h" -#include "util/statistics.h" #include "ast/pattern/pattern_inference.h" +#include "smt/params/smt_params.h" class arith_simplifier_plugin; class bv_simplifier_plugin; @@ -55,6 +55,7 @@ class asserted_formulas { maximise_bv_sharing m_bv_sharing; bool m_inconsistent; + bool m_has_quantifiers; struct scope { unsigned m_asserted_formulas_lim; @@ -128,7 +129,7 @@ public: void display_ll(std::ostream & out, ast_mark & pp_visited) const; void collect_statistics(statistics & st) const; // TODO: improve precision of the following method. - bool has_quantifiers() const { return m_simplifier.visited_quantifier(); /* approximation */ } + bool has_quantifiers() const { return m_has_quantifiers; } // ----------------------------------- // From ed4477c9e410b688bfc84bcb44e6f104f1add9fe Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Aug 2017 18:32:50 +0100 Subject: [PATCH 183/488] Whitespace --- src/ast/macros/macro_manager.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index a0a42b790..b72c1e6bf 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -52,12 +52,12 @@ class macro_manager { unsigned m_forbidden_lim; }; svector m_scopes; - + func_decl_dependencies m_deps; void restore_decls(unsigned old_sz); void restore_forbidden(unsigned old_sz); - + class macro_expander : public simplifier { protected: macro_manager & m_macro_manager; @@ -91,8 +91,8 @@ public: quantifier * get_macro_quantifier(func_decl * f) const { quantifier * q = 0; m_decl2macro.find(f, q); return q; } void get_head_def(quantifier * q, func_decl * d, app * & head, expr * & def) const; void expand_macros(expr * n, proof * pr, expr_ref & r, proof_ref & new_pr); - - + + }; #endif /* MACRO_MANAGER_H_ */ From 227e6801c2276929c3b3242e97d23f55b993491f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Aug 2017 18:33:21 +0100 Subject: [PATCH 184/488] Whitespace --- src/tactic/ufbv/macro_finder_tactic.cpp | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/tactic/ufbv/macro_finder_tactic.cpp b/src/tactic/ufbv/macro_finder_tactic.cpp index 9b1835ff3..e1e3b669b 100644 --- a/src/tactic/ufbv/macro_finder_tactic.cpp +++ b/src/tactic/ufbv/macro_finder_tactic.cpp @@ -26,24 +26,24 @@ Notes: #include "tactic/extension_model_converter.h" #include "tactic/ufbv/macro_finder_tactic.h" -class macro_finder_tactic : public tactic { +class macro_finder_tactic : public tactic { struct imp { ast_manager & m_manager; bool m_elim_and; - imp(ast_manager & m, params_ref const & p) : + imp(ast_manager & m, params_ref const & p) : m_manager(m), m_elim_and(false) { updt_params(p); } - + ast_manager & m() const { return m_manager; } - - - void operator()(goal_ref const & g, - goal_ref_buffer & result, - model_converter_ref & mc, + + + void operator()(goal_ref const & g, + goal_ref_buffer & result, + model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { SASSERT(g->is_well_sorted()); @@ -63,20 +63,20 @@ class macro_finder_tactic : public tactic { bv_simplifier_params bv_params; bv_simplifier_plugin * bvsimp = alloc(bv_simplifier_plugin, m_manager, *bsimp, bv_params); simp.register_plugin(bvsimp); - + macro_manager mm(m_manager, simp); macro_finder mf(m_manager, mm); - + expr_ref_vector forms(m_manager), new_forms(m_manager); - proof_ref_vector proofs(m_manager), new_proofs(m_manager); + proof_ref_vector proofs(m_manager), new_proofs(m_manager); unsigned size = g->size(); for (unsigned idx = 0; idx < size; idx++) { forms.push_back(g->form(idx)); - proofs.push_back(g->pr(idx)); + proofs.push_back(g->pr(idx)); } mf(forms.size(), forms.c_ptr(), proofs.c_ptr(), new_forms, new_proofs); - + g->reset(); for (unsigned i = 0; i < new_forms.size(); i++) g->assert_expr(new_forms.get(i), produce_proofs ? new_proofs.get(i) : 0, 0); @@ -89,7 +89,7 @@ class macro_finder_tactic : public tactic { evmc->insert(f, f_interp); } mc = evmc; - + g->inc_depth(); result.push_back(g.get()); TRACE("macro-finder", g->display(tout);); @@ -102,7 +102,7 @@ class macro_finder_tactic : public tactic { }; imp * m_imp; - params_ref m_params; + params_ref m_params; public: macro_finder_tactic(ast_manager & m, params_ref const & p): m_params(p) { @@ -112,7 +112,7 @@ public: virtual tactic * translate(ast_manager & m) { return alloc(macro_finder_tactic, m, m_params); } - + virtual ~macro_finder_tactic() { dealloc(m_imp); } @@ -128,19 +128,19 @@ public: insert_produce_proofs(r); r.insert("elim_and", CPK_BOOL, "(default: false) eliminate conjunctions during (internal) calls to the simplifier."); } - - virtual void operator()(goal_ref const & in, - goal_ref_buffer & result, - model_converter_ref & mc, + + virtual void operator()(goal_ref const & in, + goal_ref_buffer & result, + model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { (*m_imp)(in, result, mc, pc, core); } - + virtual void cleanup() { ast_manager & m = m_imp->m(); imp * d = alloc(imp, m, m_params); - std::swap(d, m_imp); + std::swap(d, m_imp); dealloc(d); } From 23d1c0a9a8a7167992e6a823ed3affd93d7f2bc1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 24 Aug 2017 11:13:01 -0700 Subject: [PATCH 185/488] move pull/push files Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/CMakeLists.txt | 2 ++ src/ast/{simplifier => rewriter}/pull_ite_tree.cpp | 2 +- src/ast/{simplifier => rewriter}/pull_ite_tree.h | 0 src/ast/{simplifier => rewriter}/push_app_ite.cpp | 2 +- src/ast/{simplifier => rewriter}/push_app_ite.h | 0 src/ast/simplifier/CMakeLists.txt | 2 -- src/smt/asserted_formulas.cpp | 4 ++-- 7 files changed, 6 insertions(+), 6 deletions(-) rename src/ast/{simplifier => rewriter}/pull_ite_tree.cpp (99%) rename src/ast/{simplifier => rewriter}/pull_ite_tree.h (100%) rename src/ast/{simplifier => rewriter}/push_app_ite.cpp (99%) rename src/ast/{simplifier => rewriter}/push_app_ite.h (100%) diff --git a/src/ast/rewriter/CMakeLists.txt b/src/ast/rewriter/CMakeLists.txt index abf09ff0c..72bca53d4 100644 --- a/src/ast/rewriter/CMakeLists.txt +++ b/src/ast/rewriter/CMakeLists.txt @@ -19,6 +19,8 @@ z3_add_component(rewriter mk_simplified_app.cpp pb_rewriter.cpp pb2bv_rewriter.cpp + push_app_ite.cpp + pull_ite_tree.cpp quant_hoist.cpp rewriter.cpp seq_rewriter.cpp diff --git a/src/ast/simplifier/pull_ite_tree.cpp b/src/ast/rewriter/pull_ite_tree.cpp similarity index 99% rename from src/ast/simplifier/pull_ite_tree.cpp rename to src/ast/rewriter/pull_ite_tree.cpp index c317cafd8..bcb672ea7 100644 --- a/src/ast/simplifier/pull_ite_tree.cpp +++ b/src/ast/rewriter/pull_ite_tree.cpp @@ -16,7 +16,7 @@ Author: Revision History: --*/ -#include "ast/simplifier/pull_ite_tree.h" +#include "ast/rewriter/pull_ite_tree.h" #include "ast/recurse_expr_def.h" #include "ast/for_each_expr.h" #include "ast/ast_pp.h" diff --git a/src/ast/simplifier/pull_ite_tree.h b/src/ast/rewriter/pull_ite_tree.h similarity index 100% rename from src/ast/simplifier/pull_ite_tree.h rename to src/ast/rewriter/pull_ite_tree.h diff --git a/src/ast/simplifier/push_app_ite.cpp b/src/ast/rewriter/push_app_ite.cpp similarity index 99% rename from src/ast/simplifier/push_app_ite.cpp rename to src/ast/rewriter/push_app_ite.cpp index 3d118e4ac..fe6f8b408 100644 --- a/src/ast/simplifier/push_app_ite.cpp +++ b/src/ast/rewriter/push_app_ite.cpp @@ -17,7 +17,7 @@ Author: Revision History: --*/ -#include "ast/simplifier/push_app_ite.h" +#include "ast/rewriter/push_app_ite.h" #include "ast/ast_pp.h" push_app_ite::push_app_ite(simplifier & s, bool conservative): diff --git a/src/ast/simplifier/push_app_ite.h b/src/ast/rewriter/push_app_ite.h similarity index 100% rename from src/ast/simplifier/push_app_ite.h rename to src/ast/rewriter/push_app_ite.h diff --git a/src/ast/simplifier/CMakeLists.txt b/src/ast/simplifier/CMakeLists.txt index 9575c5c89..c5c310c07 100644 --- a/src/ast/simplifier/CMakeLists.txt +++ b/src/ast/simplifier/CMakeLists.txt @@ -15,8 +15,6 @@ z3_add_component(simplifier inj_axiom.cpp maximise_ac_sharing.cpp poly_simplifier_plugin.cpp - pull_ite_tree.cpp - push_app_ite.cpp seq_simplifier_plugin.cpp simplifier.cpp simplifier_plugin.cpp diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index eac5f7c10..6f1c4cfcc 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -22,14 +22,14 @@ Revision History: #include "ast/for_each_expr.h" #include "ast/well_sorted.h" #include "ast/rewriter/rewriter_def.h" +#include "ast/rewriter/pull_ite_tree.h" +#include "ast/rewriter/push_app_ite.h" #include "ast/simplifier/arith_simplifier_plugin.h" #include "ast/simplifier/array_simplifier_plugin.h" #include "ast/simplifier/datatype_simplifier_plugin.h" #include "ast/simplifier/fpa_simplifier_plugin.h" #include "ast/simplifier/seq_simplifier_plugin.h" #include "ast/simplifier/bv_simplifier_plugin.h" -#include "ast/simplifier/pull_ite_tree.h" -#include "ast/simplifier/push_app_ite.h" #include "ast/simplifier/bv_elim.h" #include "ast/simplifier/inj_axiom.h" #include "ast/simplifier/elim_bounds.h" From 5141477809cd70c90fa2e33b5ccb50a57f4ea7a1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 24 Aug 2017 11:16:48 -0700 Subject: [PATCH 186/488] remove dead code Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/pull_ite_tree.cpp | 28 ----- src/ast/rewriter/pull_ite_tree.h | 31 ----- src/ast/rewriter/push_app_ite.cpp | 191 ----------------------------- src/ast/rewriter/push_app_ite.h | 31 ----- 4 files changed, 281 deletions(-) diff --git a/src/ast/rewriter/pull_ite_tree.cpp b/src/ast/rewriter/pull_ite_tree.cpp index bcb672ea7..651744bf9 100644 --- a/src/ast/rewriter/pull_ite_tree.cpp +++ b/src/ast/rewriter/pull_ite_tree.cpp @@ -179,34 +179,6 @@ void pull_ite_tree::operator()(app * n, app_ref & r, proof_ref & pr) { m_todo.reset(); } -pull_ite_tree_star::pull_ite_tree_star(ast_manager & m, simplifier & s): - simplifier(m), - m_proc(m) { - borrow_plugins(s); -} - -bool pull_ite_tree_star::get_subst(expr * n, expr_ref & r, proof_ref & p) { - if (is_app(n) && is_target(to_app(n))) { - app_ref tmp(m); - m_proc(to_app(n), tmp, p); - r = tmp; - return true; - } - return false; -} - -bool pull_cheap_ite_tree_star::is_target(app * n) const { - bool r = - n->get_num_args() == 2 && - n->get_family_id() != null_family_id && - m.is_bool(n) && - (m.is_value(n->get_arg(0)) || m.is_value(n->get_arg(1))) && - (m.is_term_ite(n->get_arg(0)) || m.is_term_ite(n->get_arg(1))); - TRACE("pull_ite_target", tout << mk_pp(n, m) << "\nresult: " << r << "\n";); - return r; -} - - pull_ite_tree_cfg::pull_ite_tree_cfg(ast_manager & m): diff --git a/src/ast/rewriter/pull_ite_tree.h b/src/ast/rewriter/pull_ite_tree.h index 37837a3cf..3ff0a716d 100644 --- a/src/ast/rewriter/pull_ite_tree.h +++ b/src/ast/rewriter/pull_ite_tree.h @@ -22,7 +22,6 @@ Revision History: #include "ast/ast.h" #include "ast/rewriter/rewriter.h" #include "ast/rewriter/th_rewriter.h" -#include "ast/simplifier/simplifier.h" #include "ast/expr_map.h" #include "ast/recurse_expr.h" #include "util/obj_hashtable.h" @@ -69,36 +68,6 @@ public: void operator()(app * n, app_ref & r, proof_ref & pr); }; -/** - \brief Functor for applying the pull_ite_tree on subexpressions n that - satisfy the is_target virtual predicate. -*/ -class pull_ite_tree_star : public simplifier { -protected: - pull_ite_tree m_proc; - virtual bool get_subst(expr * n, expr_ref & r, proof_ref & p); -public: - pull_ite_tree_star(ast_manager & m, simplifier & s); - virtual ~pull_ite_tree_star() { release_plugins(); } - virtual bool is_target(app * n) const = 0; -}; - -/** - \brief Apply pull_ite_tree on predicates of the form - (p ite v) and (p v ite) - - where: - - p is an interpreted predicate - - ite is an ite-term expression - - v is a value -*/ -class pull_cheap_ite_tree_star : public pull_ite_tree_star { -public: - pull_cheap_ite_tree_star(ast_manager & m, simplifier & s):pull_ite_tree_star(m, s) {} - virtual ~pull_cheap_ite_tree_star() {} - virtual bool is_target(app * n) const; -}; - /** \brief Functor for applying the pull_ite_tree on subexpressions n that satisfy the is_target virtual predicate. diff --git a/src/ast/rewriter/push_app_ite.cpp b/src/ast/rewriter/push_app_ite.cpp index fe6f8b408..386a4fb27 100644 --- a/src/ast/rewriter/push_app_ite.cpp +++ b/src/ast/rewriter/push_app_ite.cpp @@ -20,17 +20,6 @@ Revision History: #include "ast/rewriter/push_app_ite.h" #include "ast/ast_pp.h" -push_app_ite::push_app_ite(simplifier & s, bool conservative): - simplifier(s.get_manager()), - m_conservative(conservative) { - - borrow_plugins(s); -} - -push_app_ite::~push_app_ite() { - // the plugins were borrowed. So, release ownership. - m_plugins.release(); -} static int has_ite_arg(ast_manager& m, unsigned num_args, expr * const * args) { for (unsigned i = 0; i < num_args; i++) @@ -39,186 +28,6 @@ static int has_ite_arg(ast_manager& m, unsigned num_args, expr * const * args) { return -1; } -void push_app_ite::apply(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & r) { - TRACE("push_app_ite", tout << "pushing app...\n";); - int ite_arg_idx = has_ite_arg(m, num_args, args); - if (ite_arg_idx < 0) { - mk_app(decl, num_args, args, r); - return; - } - app * ite = to_app(args[ite_arg_idx]); - expr * c = ite->get_arg(0); - expr * t = ite->get_arg(1); - expr * e = ite->get_arg(2); - expr ** args_prime = const_cast(args); - expr * old = args_prime[ite_arg_idx]; - args_prime[ite_arg_idx] = t; - expr_ref t_new(m); - apply(decl, num_args, args_prime, t_new); - args_prime[ite_arg_idx] = e; - expr_ref e_new(m); - apply(decl, num_args, args_prime, e_new); - args_prime[ite_arg_idx] = old; - expr * new_args[3] = { c, t_new, e_new }; - mk_app(ite->get_decl(), 3, new_args, r); -} - -/** - \brief Default (conservative) implementation. Return true if there one and only one ite-term argument. -*/ -bool push_app_ite::is_target(func_decl * decl, unsigned num_args, expr * const * args) { - if (m.is_ite(decl)) - return false; - bool found_ite = false; - for (unsigned i = 0; i < num_args; i++) { - if (m.is_ite(args[i]) && !m.is_bool(args[i])) { - if (found_ite) { - if (m_conservative) - return false; - } - else { - found_ite = true; - } - } - } - CTRACE("push_app_ite", found_ite, tout << "found target for push app ite:\n"; - tout << decl->get_name(); - for (unsigned i = 0; i < num_args; i++) tout << " " << mk_pp(args[i], m); - tout << "\n";); - return found_ite; -} - -void push_app_ite::operator()(expr * s, expr_ref & r, proof_ref & p) { - expr * result; - proof * result_proof; - reduce_core(s); - get_cached(s, result, result_proof); - r = result; - switch (m.proof_mode()) { - case PGM_DISABLED: - p = m.mk_undef_proof(); - break; - case PGM_COARSE: - if (result == s) - p = m.mk_reflexivity(s); - else - p = m.mk_rewrite_star(s, result, 0, 0); - break; - case PGM_FINE: - if (result == s) - p = m.mk_reflexivity(s); - else - p = result_proof; - break; - } -} - -void push_app_ite::reduce_core(expr * n) { - if (!is_cached(n)) { - unsigned sz = m_todo.size(); - m_todo.push_back(n); - while (m_todo.size() != sz) { - expr * n = m_todo.back(); - if (is_cached(n)) - m_todo.pop_back(); - else if (visit_children(n)) { - m_todo.pop_back(); - reduce1(n); - } - } - } -} - -bool push_app_ite::visit_children(expr * n) { - bool visited = true; - unsigned j; - switch(n->get_kind()) { - case AST_VAR: - return true; - case AST_APP: - j = to_app(n)->get_num_args(); - while (j > 0) { - --j; - visit(to_app(n)->get_arg(j), visited); - } - return visited; - case AST_QUANTIFIER: - visit(to_quantifier(n)->get_expr(), visited); - return visited; - default: - UNREACHABLE(); - return true; - } -} - -void push_app_ite::reduce1(expr * n) { - switch (n->get_kind()) { - case AST_VAR: - cache_result(n, n, 0); - break; - case AST_APP: - reduce1_app(to_app(n)); - break; - case AST_QUANTIFIER: - reduce1_quantifier(to_quantifier(n)); - break; - default: - UNREACHABLE(); - } -} - -void push_app_ite::reduce1_app(app * n) { - m_args.reset(); - - func_decl * decl = n->get_decl(); - proof_ref p1(m); - get_args(n, m_args, p1); - - expr_ref r(m); - if (is_target(decl, m_args.size(), m_args.c_ptr())) - apply(decl, m_args.size(), m_args.c_ptr(), r); - else - mk_app(decl, m_args.size(), m_args.c_ptr(), r); - - if (!m.fine_grain_proofs()) - cache_result(n, r, 0); - else { - expr * s = m.mk_app(decl, m_args.size(), m_args.c_ptr()); - proof * p; - if (n == r) - p = 0; - else if (r != s) - p = m.mk_transitivity(p1, m.mk_rewrite(s, r)); - else - p = p1; - cache_result(n, r, p); - } -} - -void push_app_ite::reduce1_quantifier(quantifier * q) { - expr * new_body; - proof * new_body_pr; - get_cached(q->get_expr(), new_body, new_body_pr); - - quantifier * new_q = m.update_quantifier(q, new_body); - proof * p = q == new_q ? 0 : m.mk_quant_intro(q, new_q, new_body_pr); - cache_result(q, new_q, p); -} - -bool ng_push_app_ite::is_target(func_decl * decl, unsigned num_args, expr * const * args) { - bool r = push_app_ite::is_target(decl, num_args, args); - if (!r) - return false; - for (unsigned i = 0; i < num_args; i++) - if (!is_ground(args[i])) - return true; - return false; -} - -ng_push_app_ite::ng_push_app_ite(simplifier & s, bool conservative): - push_app_ite(s, conservative) { -} - /** \brief Default (conservative) implementation. Return true if there one and only one ite-term argument. diff --git a/src/ast/rewriter/push_app_ite.h b/src/ast/rewriter/push_app_ite.h index 4faf853ea..e6c6b6fb2 100644 --- a/src/ast/rewriter/push_app_ite.h +++ b/src/ast/rewriter/push_app_ite.h @@ -20,7 +20,6 @@ Revision History: #define PUSH_APP_ITE_H_ #include "ast/ast.h" -#include "ast/simplifier/simplifier.h" #include "ast/rewriter/rewriter.h" /** @@ -28,36 +27,6 @@ Revision History: (f s (ite c t1 t2)) ==> (ite c (f s t1) (f s t2)) */ -class push_app_ite : public simplifier { -protected: - bool m_conservative; - void apply(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & result); - virtual bool is_target(func_decl * decl, unsigned num_args, expr * const * args); - void reduce_core(expr * n); - bool visit_children(expr * n); - void reduce1(expr * n); - void reduce1_app(app * n); - void reduce1_quantifier(quantifier * q); - -public: - push_app_ite(simplifier & s, bool conservative = true); - virtual ~push_app_ite(); - void operator()(expr * s, expr_ref & r, proof_ref & p); -}; - -/** - \brief Variation of push_app_ite that applies the transformation on nonground terms only. - - \remark This functor uses the app::is_ground method. This method is not - completly precise, for instance, any term containing a quantifier is marked as non ground. -*/ -class ng_push_app_ite : public push_app_ite { -protected: - virtual bool is_target(func_decl * decl, unsigned num_args, expr * const * args); -public: - ng_push_app_ite(simplifier & s, bool conservative = true); - virtual ~ng_push_app_ite() {} -}; struct push_app_ite_cfg : public default_rewriter_cfg { ast_manager& m; From ed8c11ff76229e1bcc1987a155f8765e1e763533 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Aug 2017 19:59:38 +0100 Subject: [PATCH 187/488] Whitespace --- src/smt/smt_model_finder.cpp | 400 +++++++++++++++++------------------ 1 file changed, 200 insertions(+), 200 deletions(-) diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 73d1e9f22..94a6a7267 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -84,8 +84,8 @@ namespace smt { expr_mark m_visited; public: instantiation_set(ast_manager & m):m_manager(m) {} - - ~instantiation_set() { + + ~instantiation_set() { for (auto const& kv : m_elems) { m_manager.dec_ref(kv.m_key); } @@ -110,7 +110,7 @@ namespace smt { m_elems.erase(n); m_manager.dec_ref(n); } - + void display(std::ostream & out) const { for (auto const& kv : m_elems) { out << mk_bounded_pp(kv.m_key, m_manager) << " [" << kv.m_value << "]\n"; @@ -126,7 +126,7 @@ namespace smt { m_inv.find(v, t); return t; } - + unsigned get_generation(expr * t) const { unsigned gen = 0; m_elems.find(t, gen); @@ -187,15 +187,15 @@ namespace smt { }; /** - During model construction time, + During model construction time, we solve several constraints that impose restrictions on how the model for the ground formulas may be extended to a model to the relevant universal quantifiers. - + The class node and its subclasses are used to solve these constraints. */ - + // ----------------------------------- // // nodes @@ -209,14 +209,14 @@ namespace smt { unsigned m_id; node * m_find; unsigned m_eqc_size; - + sort * m_sort; // sort of the elements in the instantiation set. - + bool m_mono_proj; // relevant for integers & reals & bit-vectors bool m_signed_proj; // relevant for bit-vectors. ptr_vector m_avoid_set; ptr_vector m_exceptions; - + instantiation_set * m_set; expr * m_else; @@ -286,7 +286,7 @@ namespace smt { if (!ex.contains(n)) ex.push_back(n); } - + void set_mono_proj() { get_root()->m_mono_proj = true; } @@ -348,7 +348,7 @@ namespace smt { instantiation_set * get_instantiation_set() { return get_root()->m_set; } ptr_vector const & get_exceptions() const { return get_root()->m_exceptions; } - + ptr_vector const & get_avoid_set() const { return get_root()->m_avoid_set; } // return true if m_avoid_set.contains(this) @@ -366,8 +366,8 @@ namespace smt { SASSERT(get_root()->m_else == 0); get_root()->m_else = e; } - - expr * get_else() const { + + expr * get_else() const { return get_root()->m_else; } @@ -375,7 +375,7 @@ namespace smt { SASSERT(get_root()->m_proj == 0); get_root()->m_proj = f; } - + func_decl * get_proj() const { return get_root()->m_proj; } @@ -384,7 +384,7 @@ namespace smt { typedef std::pair ast_idx_pair; typedef pair_hash, unsigned_hash> ast_idx_pair_hash; typedef map > key2node; - + /** \brief Auxiliary class for processing the "Almost uninterpreted fragment" described in the paper: Complete instantiation for quantified SMT formulas @@ -402,16 +402,16 @@ namespace smt { context * m_context; - // Mapping from sort to auxiliary constant. - // This auxiliary constant is used as a "witness" that is asserted as different from a - // finite number of terms. + // Mapping from sort to auxiliary constant. + // This auxiliary constant is used as a "witness" that is asserted as different from a + // finite number of terms. // It is only safe to use this constant for infinite sorts. - obj_map m_sort2k; + obj_map m_sort2k; expr_ref_vector m_ks; // range of m_sort2k - + // Support for evaluating expressions in the current model. proto_model * m_model; - obj_map m_eval_cache[2]; + obj_map m_eval_cache[2]; expr_ref_vector m_eval_cache_range; ptr_vector m_root_nodes; @@ -428,7 +428,7 @@ namespace smt { m_eval_cache[1].reset(); m_eval_cache_range.reset(); } - + node * mk_node(key2node & m, ast * n, unsigned i, sort * s) { node * r = 0; ast_idx_pair k(n, i); @@ -482,18 +482,18 @@ namespace smt { flush_nodes(); reset_eval_cache(); } - + void set_context(context * ctx) { SASSERT(m_context==0); m_context = ctx; } - + ast_manager & get_manager() const { return m_manager; } - + arith_simplifier_plugin * get_arith_simp() const { return m_asimp; } bv_simplifier_plugin * get_bv_simp() const { return m_bvsimp; } - + void reset() { flush_nodes(); m_nodes.reset(); @@ -509,21 +509,21 @@ namespace smt { m_model = m; } - proto_model * get_model() const { + proto_model * get_model() const { SASSERT(m_model); return m_model; } - - node * get_uvar(quantifier * q, unsigned i) { + + node * get_uvar(quantifier * q, unsigned i) { SASSERT(i < q->get_num_decls()); sort * s = q->get_decl_sort(q->get_num_decls() - i - 1); - return mk_node(m_uvars, q, i, s); + return mk_node(m_uvars, q, i, s); } - node * get_A_f_i(func_decl * f, unsigned i) { + node * get_A_f_i(func_decl * f, unsigned i) { SASSERT(i < f->get_arity()); sort * s = f->get_domain(i); - return mk_node(m_A_f_is, f, i, s); + return mk_node(m_A_f_is, f, i, s); } instantiation_set const * get_uvar_inst_set(quantifier * q, unsigned i) const { @@ -534,7 +534,7 @@ namespace smt { return r->get_instantiation_set(); return 0; } - + void mk_instantiation_sets() { for (node* curr : m_nodes) { if (curr->is_root()) { @@ -566,7 +566,7 @@ namespace smt { void display_nodes(std::ostream & out) const { display_key2node(out, m_uvars); - display_A_f_is(out); + display_A_f_is(out); for (node* n : m_nodes) { n->display(out, m_manager); } @@ -599,13 +599,13 @@ namespace smt { void collect_exceptions_values(node * n, ptr_buffer & r) { ptr_vector const & exceptions = n->get_exceptions(); ptr_vector const & avoid_set = n->get_avoid_set(); - + for (expr* e : exceptions) { expr * val = eval(e, true); SASSERT(val != 0); r.push_back(val); } - + for (node* a : avoid_set) { node * n = a->get_root(); if (!n->is_mono_proj() && n->get_else() != 0) { @@ -628,7 +628,7 @@ namespace smt { obj_map const & elems = s->get_elems(); expr * t_result = 0; - unsigned gen_result = UINT_MAX; + unsigned gen_result = UINT_MAX; for (auto const& kv : elems) { expr * t = kv.m_key; unsigned gen = kv.m_value; @@ -651,13 +651,13 @@ namespace smt { bool is_infinite(sort * s) const { // we should not assume that uninterpreted sorts are infinite in benchmarks with quantifiers. - return + return !m_manager.is_uninterp(s) && s->is_infinite(); } /** - \brief Return a fresh constant k that is used as a witness for elements that must be different from + \brief Return a fresh constant k that is used as a witness for elements that must be different from a set of values. */ app * get_k_for(sort * s) { @@ -674,7 +674,7 @@ namespace smt { /** \brief Get the interpretation for k in m_model. - If m_model does not provide an interpretation for k, then + If m_model does not provide an interpretation for k, then create a fresh one. Remark: this method uses get_fresh_value, so it may fail. @@ -717,7 +717,7 @@ namespace smt { } return true; } - + void set_projection_else(node * n) { SASSERT(n->is_root()); SASSERT(!n->is_mono_proj()); @@ -744,7 +744,7 @@ namespace smt { return; } } - // TBD: add support for the else of bitvectors. + // TBD: add support for the else of bitvectors. // Idea: get the term t with the minimal interpreation and use t - 1. } n->set_else((*(elems.begin())).m_key); @@ -775,7 +775,7 @@ namespace smt { expr_ref e_plus_1(m_manager); expr_ref e_minus_1(m_manager); TRACE("mf_simp_bug", tout << "e:\n" << mk_ismt2_pp(e, m_manager) << "\none:\n" << mk_ismt2_pp(one, m_manager) << "\n";); - ps->mk_add(e, one, e_plus_1); + ps->mk_add(e, one, e_plus_1); ps->mk_sub(e, one, e_minus_1); // Note: exceptions come from quantifiers bodies. So, they have generation 0. n->insert(e_plus_1, 0); @@ -865,7 +865,7 @@ namespace smt { var = m_manager.mk_var(0, s); for (unsigned i = sz - 1; i >= 1; i--) { expr_ref c(m_manager); - if (is_arith) + if (is_arith) as->mk_lt(var, values[i], c); else if (!is_signed) bs->mk_ult(var, values[i], c); @@ -896,7 +896,7 @@ namespace smt { } n->set_proj(p); } - + void mk_projections() { for (node * n : m_root_nodes) { SASSERT(n->is_root()); @@ -906,7 +906,7 @@ namespace smt { mk_simple_proj(n); } } - + /** \brief Store in r the partial functions that have A_f_i nodes. */ @@ -926,7 +926,7 @@ namespace smt { } } } - + /** \brief Make sorts associated with nodes that must avoid themselves finite. Only uninterpreted sorts are considered. @@ -938,16 +938,16 @@ namespace smt { for (node * n : m_root_nodes) { SASSERT(n->is_root()); sort * s = n->get_sort(); - if (m_manager.is_uninterp(s) && + if (m_manager.is_uninterp(s) && // Making all uninterpreted sorts finite. - // n->must_avoid_itself() && + // n->must_avoid_itself() && !m_model->is_finite(s)) { m_model->freeze_universe(s); } } } - void add_elem_to_empty_inst_sets() { + void add_elem_to_empty_inst_sets() { obj_map sort2elems; ptr_vector need_fresh; for (node * n : m_root_nodes) { @@ -956,11 +956,11 @@ namespace smt { TRACE("model_finder", s->display(tout);); obj_map const & elems = s->get_elems(); if (elems.empty()) { - // The method get_some_value cannot be used if n->get_sort() is an uninterpreted sort or is a sort built using uninterpreted sorts + // The method get_some_value cannot be used if n->get_sort() is an uninterpreted sort or is a sort built using uninterpreted sorts // (e.g., (Array S S) where S is uninterpreted). The problem is that these sorts do not have a fixed interpretation. // Moreover, a model assigns an arbitrary intepretation to these sorts using "model_values" a model value. // If these module values "leak" inside the logical context, they may affect satisfiability. - // + // sort * ns = n->get_sort(); if (m_manager.is_fully_interp(ns)) { n->insert(m_model->get_some_value(ns), 0); @@ -998,14 +998,14 @@ namespace smt { m_root_nodes.push_back(n); } } - + /** \brief Return the projection function for f at argument i. - Return 0, if there is none. + Return 0, if there is none. \remark This method assumes that mk_projections was already invoked. - + \remark f may have a non partial interpretation on m_model. This may happen because the evaluator uses model_completion. In the beginning of fix_model() we collected all f with @@ -1022,21 +1022,21 @@ namespace smt { return 0; return r->get_proj(); } - + /** - \brief Complete the interpretation of the functions that were + \brief Complete the interpretation of the functions that were collected in the beginning of fix_model(). */ void complete_partial_funcs(func_decl_set const & partial_funcs) { for (func_decl * f : partial_funcs) { // Complete the current interpretation m_model->complete_partial_func(f); - + unsigned arity = f->get_arity(); func_interp * fi = m_model->get_func_interp(f); if (fi->is_constant()) continue; // there is no point in using the projection for fi, since fi is the constant function. - + expr_ref_vector args(m_manager); bool has_proj = false; for (unsigned i = 0; i < arity; i++) { @@ -1055,7 +1055,7 @@ namespace smt { func_decl * f_aux = m_manager.mk_fresh_func_decl(f->get_name(), symbol::null, arity, f->get_domain(), f->get_range()); func_interp * new_fi = alloc(func_interp, m_manager, arity); new_fi->set_else(m_manager.mk_app(f_aux, args.size(), args.c_ptr())); - TRACE("model_finder", tout << "Setting new interpretation for " << f->get_name() << "\n" << + TRACE("model_finder", tout << "Setting new interpretation for " << f->get_name() << "\n" << mk_pp(new_fi->get_else(), m_manager) << "\n";); m_model->reregister_decl(f, new_fi, f_aux); } @@ -1067,7 +1067,7 @@ namespace smt { instantiation_set * s = n->get_instantiation_set(); s->mk_inverse(*this); } - + void mk_inverses() { for (node * n : m_root_nodes) { SASSERT(n->is_root()); @@ -1107,7 +1107,7 @@ namespace smt { information about the quantifier structure. These bits are instances of subclasses of qinfo. */ - + /** \brief Generic bit of information collected when analyzing quantifiers. The subclasses are defined in the .cpp file. @@ -1118,7 +1118,7 @@ namespace smt { virtual char const * get_kind() const = 0; virtual bool is_equal(qinfo const * qi) const = 0; virtual void display(std::ostream & out) const { out << "[" << get_kind() << "]"; } - + // AUF fragment solver virtual void process_auf(quantifier * q, auf_solver & s, context * ctx) = 0; virtual void populate_inst_sets(quantifier * q, auf_solver & s, context * ctx) = 0; @@ -1139,17 +1139,17 @@ namespace smt { f_var(func_decl * f, unsigned i, unsigned j):m_f(f), m_arg_i(i), m_var_j(j) {} virtual ~f_var() {} - virtual char const * get_kind() const { - return "f_var"; + virtual char const * get_kind() const { + return "f_var"; } - + virtual bool is_equal(qinfo const * qi) const { if (qi->get_kind() != get_kind()) return false; f_var const * other = static_cast(qi); return m_f == other->m_f && m_arg_i == other->m_arg_i && m_var_j == other->m_var_j; } - + virtual void display(std::ostream & out) const { out << "(" << m_f->get_name() << ":" << m_arg_i << " -> v!" << m_var_j << ")"; } @@ -1169,7 +1169,7 @@ namespace smt { for (unsigned i = 0; i < m_f->get_arity(); i++) tout << mk_pp(m_f->get_domain(i), m) << " "; tout << "-> " << mk_pp(m_f->get_range(), m) << "\n"; ); - + n1->merge(n2); } @@ -1191,7 +1191,7 @@ namespace smt { // a necessary instantiation. enode * e_arg = n->get_arg(m_arg_i); expr * arg = e_arg->get_owner(); - A_f_i->insert(arg, e_arg->get_generation()); + A_f_i->insert(arg, e_arg->get_generation()); } } } @@ -1204,7 +1204,7 @@ namespace smt { uvar_inst_sets[m_var_j] = alloc(instantiation_set, ctx->get_manager()); instantiation_set * s = uvar_inst_sets[m_var_j]; SASSERT(s != 0); - + enode_vector::const_iterator it = ctx->begin_enodes_of(m_f); enode_vector::const_iterator end = ctx->end_enodes_of(m_f); for (; it != end; it++) { @@ -1212,7 +1212,7 @@ namespace smt { if (ctx->is_relevant(n)) { enode * e_arg = n->get_arg(m_arg_i); expr * arg = e_arg->get_owner(); - s->insert(arg, e_arg->get_generation()); + s->insert(arg, e_arg->get_generation()); } } } @@ -1227,19 +1227,19 @@ namespace smt { } virtual ~f_var_plus_offset() {} - virtual char const * get_kind() const { - return "f_var_plus_offset"; + virtual char const * get_kind() const { + return "f_var_plus_offset"; } - + virtual bool is_equal(qinfo const * qi) const { if (qi->get_kind() != get_kind()) return false; f_var_plus_offset const * other = static_cast(qi); return m_f == other->m_f && m_arg_i == other->m_arg_i && m_var_j == other->m_var_j && m_offset.get() == other->m_offset.get(); } - + virtual void display(std::ostream & out) const { - out << "(" << m_f->get_name() << ":" << m_arg_i << " - " << + out << "(" << m_f->get_name() << ":" << m_arg_i << " - " << mk_bounded_pp(m_offset.get(), m_offset.get_manager()) << " -> v!" << m_var_j << ")"; } @@ -1330,11 +1330,11 @@ namespace smt { /** \brief auf_arr is a term (pattern) of the form: - + FORM := GROUND-TERM | (select FORM VAR) - - Store in arrays, all enodes that match the pattern + + Store in arrays, all enodes that match the pattern */ void get_auf_arrays(app * auf_arr, context * ctx, ptr_buffer & arrays) { if (is_ground(auf_arr)) { @@ -1361,10 +1361,10 @@ namespace smt { } } } - + class select_var : public qinfo { protected: - ast_manager & m_manager; + ast_manager & m_manager; array_util m_array; app * m_select; // It must satisfy is_auf_select... see bool is_auf_select(expr * t) const unsigned m_arg_i; @@ -1384,16 +1384,16 @@ namespace smt { virtual ~select_var() {} virtual char const * get_kind() const { - return "select_var"; + return "select_var"; } - + virtual bool is_equal(qinfo const * qi) const { if (qi->get_kind() != get_kind()) return false; select_var const * other = static_cast(qi); return m_select == other->m_select && m_arg_i == other->m_arg_i && m_var_j == other->m_var_j; } - + virtual void display(std::ostream & out) const { out << "(" << mk_bounded_pp(m_select, m_manager) << ":" << m_arg_i << " -> v!" << m_var_j << ")"; } @@ -1401,12 +1401,12 @@ namespace smt { virtual void process_auf(quantifier * q, auf_solver & s, context * ctx) { ptr_buffer arrays; get_auf_arrays(get_array(), ctx, arrays); - TRACE("select_var", + TRACE("select_var", tout << "enodes matching: "; display(tout); tout << "\n"; for (enode* n : arrays) { tout << "#" << n->get_owner()->get_id() << "\n" << mk_pp(n->get_owner(), m_manager) << "\n"; }); - node * n1 = s.get_uvar(q, m_var_j); + node * n1 = s.get_uvar(q, m_var_j); for (enode* n : arrays) { app * ground_array = n->get_owner(); func_decl * f = get_array_func_decl(ground_array, s); @@ -1429,7 +1429,7 @@ namespace smt { enode_vector::iterator it2 = curr->begin_parents(); enode_vector::iterator end2 = curr->end_parents(); for (; it2 != end2; ++it2) { - enode * p = *it2; + enode * p = *it2; if (ctx->is_relevant(p) && p->get_owner()->get_decl() == m_select->get_decl()) { SASSERT(m_arg_i < p->get_owner()->get_num_args()); enode * e_arg = p->get_arg(m_arg_i); @@ -1440,7 +1440,7 @@ namespace smt { } } }; - + class var_pair : public qinfo { protected: unsigned m_var_i; @@ -1450,16 +1450,16 @@ namespace smt { if (m_var_i > m_var_j) std::swap(m_var_i, m_var_j); } - + virtual ~var_pair() {} virtual bool is_equal(qinfo const * qi) const { if (qi->get_kind() != get_kind()) return false; var_pair const * other = static_cast(qi); - return m_var_i == other->m_var_i && m_var_j == other->m_var_j; + return m_var_i == other->m_var_i && m_var_j == other->m_var_j; } - + virtual void display(std::ostream & out) const { out << "(" << get_kind() << ":v!" << m_var_i << ":v!" << m_var_j << ")"; } @@ -1494,7 +1494,7 @@ namespace smt { n1->merge(n2); } }; - + class x_leq_y : public var_pair { public: x_leq_y(unsigned i, unsigned j):var_pair(i, j) {} @@ -1513,7 +1513,7 @@ namespace smt { public: x_sleq_y(unsigned i, unsigned j):x_leq_y(i, j) {} virtual char const * get_kind() const { return "x_sleq_y"; } - + virtual void process_auf(quantifier * q, auf_solver & s, context * ctx) { node * n1 = s.get_uvar(q, m_var_i); node * n2 = s.get_uvar(q, m_var_j); @@ -1522,7 +1522,7 @@ namespace smt { n1->set_signed_proj(); } }; - + class var_expr_pair : public qinfo { protected: unsigned m_var_i; @@ -1531,19 +1531,19 @@ namespace smt { var_expr_pair(ast_manager & m, unsigned i, expr * t): m_var_i(i), m_t(t, m) {} ~var_expr_pair() {} - + virtual bool is_equal(qinfo const * qi) const { if (qi->get_kind() != get_kind()) return false; var_expr_pair const * other = static_cast(qi); return m_var_i == other->m_var_i && m_t.get() == other->m_t.get(); } - + virtual void display(std::ostream & out) const { out << "(" << get_kind() << ":v!" << m_var_i << ":" << mk_bounded_pp(m_t.get(), m_t.get_manager()) << ")"; } }; - + class x_eq_t : public var_expr_pair { public: x_eq_t(ast_manager & m, unsigned i, expr * t): @@ -1591,7 +1591,7 @@ namespace smt { S_q_i->insert(m_t, 0); } }; - + class x_gle_t : public var_expr_pair { public: x_gle_t(ast_manager & m, unsigned i, expr * t): @@ -1634,16 +1634,16 @@ namespace smt { m_manager.inc_ref(m_cond); SASSERT(!m_hint || m_cond == 0); } - + ~cond_macro() { m_manager.dec_ref(m_def); m_manager.dec_ref(m_cond); } func_decl * get_f() const { return m_f; } - + expr * get_def() const { return m_def; } - + expr * get_cond() const { return m_cond; } bool is_unconditional() const { return m_cond == 0 || m_manager.is_true(m_cond); } @@ -1660,7 +1660,7 @@ namespace smt { out << "[" << m_f->get_name() << " -> " << mk_bounded_pp(m_def, m_manager, 6); if (m_hint) out << " *hint*"; - else + else out << " when " << mk_bounded_pp(m_cond, m_manager, 6); out << "] weight: " << m_weight; } @@ -1675,7 +1675,7 @@ namespace smt { // ----------------------------------- class quantifier_analyzer; - + /** \brief Store relevant information regarding a particular universal quantifier. This information is populated by quantifier_analyzer. @@ -1749,7 +1749,7 @@ namespace smt { tout << mk_pp(q, m) << "\n" << mk_pp(m_flat_q, m) << "\n";); SASSERT(!has_quantifiers(m_flat_q->get_expr())); } - + ~quantifier_info() { std::for_each(m_qinfo_vect.begin(), m_qinfo_vect.end(), delete_proc()); std::for_each(m_cond_macros.begin(), m_cond_macros.end(), delete_proc()); @@ -1759,7 +1759,7 @@ namespace smt { bool is_auf() const { return m_is_auf; } quantifier * get_flat_q() const { return m_flat_q; } - + bool unary_function_fragment() const { unsigned sz = m_ng_decls.size(); if (sz > 1) @@ -1843,7 +1843,7 @@ namespace smt { if (m_uvar_inst_sets != 0) return; m_uvar_inst_sets = alloc(ptr_vector); - for (qinfo* qi : m_qinfo_vect) + for (qinfo* qi : m_qinfo_vect) qi->populate_inst_sets(m_flat_q, m_the_one, *m_uvar_inst_sets, ctx); for (instantiation_set * s : *m_uvar_inst_sets) { if (s != 0) @@ -1867,7 +1867,7 @@ namespace smt { } } }; - + /** \brief Functor used to traverse/analyze a quantifier and fill the structure quantifier_info. @@ -1883,9 +1883,9 @@ namespace smt { quantifier_info * m_info; typedef enum { POS, NEG } polarity; - + polarity neg(polarity p) { return p == POS ? NEG : POS; } - + obj_hashtable m_pos_cache; obj_hashtable m_neg_cache; typedef std::pair entry; @@ -1919,7 +1919,7 @@ namespace smt { bool is_zero(expr * n) const { if (get_bv_simp()->is_bv(n)) return get_bv_simp()->is_zero_safe(n); - else + else return get_arith_simp()->is_zero_safe(n); } @@ -1927,22 +1927,22 @@ namespace smt { return m_mutil.is_times_minus_one(n, arg); } - bool is_le(expr * n) const { + bool is_le(expr * n) const { return m_mutil.is_le(n); } - + bool is_le_ge(expr * n) const { return m_mutil.is_le_ge(n); } - bool is_signed_le(expr * n) const { - return m_bv_util.is_bv_sle(n); + bool is_signed_le(expr * n) const { + return m_bv_util.is_bv_sle(n); } - - expr * mk_one(sort * s) { - return m_bv_util.is_bv_sort(s) ? m_bv_util.mk_numeral(rational(1), s) : m_arith_util.mk_numeral(rational(1), s); + + expr * mk_one(sort * s) { + return m_bv_util.is_bv_sort(s) ? m_bv_util.mk_numeral(rational(1), s) : m_arith_util.mk_numeral(rational(1), s); } - + void mk_sub(expr * t1, expr * t2, expr_ref & r) const { m_mutil.mk_sub(t1, t2, r); } @@ -1990,7 +1990,7 @@ namespace smt { bool inv; return is_var_and_ground(lhs, rhs, v, t, inv); } - + bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) const { if (!is_app(n)) return false; @@ -2024,7 +2024,7 @@ namespace smt { v2 = to_var(rhs); return true; } - return + return (is_var_minus_var(lhs, v1, v2) && is_zero(rhs)) || (is_var_minus_var(rhs, v1, v2) && is_zero(lhs)); } @@ -2042,7 +2042,7 @@ namespace smt { return false; if (sign) { bool r = is_le_ge(atom) && is_var_and_ground(to_app(atom)->get_arg(0), to_app(atom)->get_arg(1), v, t); - CTRACE("is_x_gle_t", r, tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m_manager) << "\n--->\n" + CTRACE("is_x_gle_t", r, tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m_manager) << "\n--->\n" << mk_ismt2_pp(v, m_manager) << " " << mk_ismt2_pp(t, m_manager) << "\n"; tout << "sign: " << sign << "\n";); return r; @@ -2062,7 +2062,7 @@ namespace smt { mk_add(tmp, one, t); else mk_sub(tmp, one, t); - TRACE("is_x_gle_t", tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m_manager) << "\n--->\n" + TRACE("is_x_gle_t", tout << "is_x_gle_t: " << mk_ismt2_pp(atom, m_manager) << "\n--->\n" << mk_ismt2_pp(v, m_manager) << " " << mk_ismt2_pp(t, m_manager) << "\n"; tout << "sign: " << sign << "\n";); return true; @@ -2076,19 +2076,19 @@ namespace smt { m_pos_cache.reset(); m_neg_cache.reset(); } - - obj_hashtable & get_cache(polarity pol) { - return pol == POS ? m_pos_cache : m_neg_cache; + + obj_hashtable & get_cache(polarity pol) { + return pol == POS ? m_pos_cache : m_neg_cache; } void visit_formula(expr * n, polarity pol) { if (is_ground(n)) return; // ground terms do not need to be visited. obj_hashtable & c = get_cache(pol); - if (!c.contains(n)) { - m_ftodo.push_back(entry(n, pol)); + if (!c.contains(n)) { + m_ftodo.push_back(entry(n, pol)); c.insert(n); - } + } } void visit_term(expr * n) { @@ -2098,7 +2098,7 @@ namespace smt { m_pos_cache.insert(n); } } - + /** \brief Process unintrepreted applications. */ @@ -2111,14 +2111,14 @@ namespace smt { insert_qinfo(alloc(f_var, t->get_decl(), i, to_var(arg)->get_idx())); continue; } - + var * v; expr_ref k(m_manager); if (is_var_plus_ground(arg, v, k)) { insert_qinfo(alloc(f_var_plus_offset, m_manager, t->get_decl(), i, v->get_idx(), k.get())); continue; } - + visit_term(arg); } } @@ -2127,9 +2127,9 @@ namespace smt { /** \brief A term \c t is said to be a auf_select if it is of ther form - + (select a i) Where: - + where a is ground or is_auf_select(a) == true and the indices are ground terms or variables. */ @@ -2173,11 +2173,11 @@ namespace smt { void process_app(app * t) { SASSERT(!is_ground(t)); - + if (t->get_family_id() != m_manager.get_basic_family_id()) { m_info->m_ng_decls.insert(t->get_decl()); } - + if (is_uninterp(t)) { process_u_app(t); } @@ -2185,19 +2185,19 @@ namespace smt { process_i_app(t); } } - + void process_terms_on_stack() { while (!m_ttodo.empty()) { expr * curr = m_ttodo.back(); m_ttodo.pop_back(); - + if (m_manager.is_bool(curr)) { // formula nested in a term. visit_formula(curr, POS); visit_formula(curr, NEG); continue; } - + if (is_app(curr)) { process_app(to_app(curr)); } @@ -2215,7 +2215,7 @@ namespace smt { CTRACE("model_finder_bug", is_ground(atom), tout << mk_pp(atom, m_manager) << "\n";); SASSERT(!is_ground(atom)); SASSERT(m_manager.is_bool(atom)); - + if (is_var(atom)) { if (sign) { // atom (not X) can be viewed as X != true @@ -2227,7 +2227,7 @@ namespace smt { } return; } - + if (is_app(atom)) { var * v, * v1, * v2; expr_ref t(m_manager); @@ -2259,18 +2259,18 @@ namespace smt { } return; } - + SASSERT(is_quantifier(atom)); UNREACHABLE(); } - void process_literal(expr * atom, polarity pol) { - process_literal(atom, pol == NEG); + void process_literal(expr * atom, polarity pol) { + process_literal(atom, pol == NEG); } - + void process_or(app * n, polarity p) { unsigned num_args = n->get_num_args(); - for (unsigned i = 0; i < num_args; i++) + for (unsigned i = 0; i < num_args; i++) visit_formula(n->get_arg(i), p); } @@ -2291,7 +2291,7 @@ namespace smt { void checkpoint() { m_mf.checkpoint("quantifier_analyzer"); } - + void process_formulas_on_stack() { while (!m_ftodo.empty()) { checkpoint(); @@ -2351,7 +2351,7 @@ namespace smt { SASSERT(m_manager.is_bool(n)); visit_formula(n, POS); } - + void process_clause(expr * cls) { SASSERT(is_clause(m_manager, cls)); unsigned num_lits = get_clause_num_literals(m_manager, cls); @@ -2371,25 +2371,25 @@ namespace smt { m_mutil.collect_macro_candidates(q, candidates); unsigned num_candidates = candidates.size(); for (unsigned i = 0; i < num_candidates; i++) { - cond_macro * m = alloc(cond_macro, m_manager, candidates.get_f(i), candidates.get_def(i), candidates.get_cond(i), + cond_macro * m = alloc(cond_macro, m_manager, candidates.get_f(i), candidates.get_def(i), candidates.get_cond(i), candidates.ineq(i), candidates.satisfy_atom(i), candidates.hint(i), q->get_weight()); m_info->insert_macro(m); } } - - + + public: quantifier_analyzer(model_finder& mf, ast_manager & m, simplifier & s): m_mf(mf), m_manager(m), m_mutil(m, s), - m_array_util(m), + m_array_util(m), m_arith_util(m), m_bv_util(m), m_info(0) { } - - + + void operator()(quantifier_info * d) { m_info = d; quantifier * q = d->get_flat_q(); @@ -2398,7 +2398,7 @@ namespace smt { reset_cache(); SASSERT(m_ttodo.empty()); SASSERT(m_ftodo.empty()); - + if (is_clause(m_manager, e)) { process_clause(e); } @@ -2412,7 +2412,7 @@ namespace smt { } collect_macro_candidates(q); - + m_info = 0; } @@ -2452,7 +2452,7 @@ namespace smt { m_q2info(q2i), m_model(0) { } - + virtual ~base_macro_solver() {} /** @@ -2470,13 +2470,13 @@ namespace smt { } }; - + /** \brief The simple macro solver satisfies quantifiers that contain (conditional) macros for a function f that does not occur in any other quantifier. - + Since f does not occur in any other quantifier, I don't need to track the dependencies - of f. That is, recursive definition cannot be created. + of f. That is, recursive definition cannot be created. */ class simple_macro_solver : public base_macro_solver { protected: @@ -2511,7 +2511,7 @@ namespace smt { // I know the (partial) interpretation of f satisfied the ground part. // MBQI will force extra instantiations if the the (partial) interpretation of f // does not satisfy the quantifier. - // In all other cases the "else" of f will satisfy the quantifier. + // In all other cases the "else" of f will satisfy the quantifier. set_else_interp(f, f_else); TRACE("model_finder", tout << "satisfying the quantifier using simple macro:\n"; m->display(tout); tout << "\n";); @@ -2547,7 +2547,7 @@ namespace smt { Let Q_{f_i = def_i} be the set of quantifiers where f_i = def_i is a macro. Then, the set Q can be satisfied using f_1 = def_1 ... f_n = d_n when - + Q_{f_1} union ... union Q_{f_n} = Q_{f_1 = def_1} ... Q_{f_n = d_n} (*) So, given a set of macros f_1 = def_1, ..., f_n = d_n, it is very easy to check @@ -2583,8 +2583,8 @@ namespace smt { typedef obj_pair_map q_f_def; typedef obj_pair_hashtable f_def_set; typedef obj_hashtable expr_set; - typedef obj_map f2defs; - + typedef obj_map f2defs; + q_f m_q_f; q_f_def m_q_f_def; ptr_vector m_qsets; @@ -2720,14 +2720,14 @@ namespace smt { } } } - + static void display_quantifier_set(std::ostream & out, quantifier_set const * s) { for (quantifier* q : *s) { out << q->get_qid() << " "; } out << "\n"; } - + void display_qcandidates(std::ostream & out, ptr_vector const & qcandidates) const { for (quantifier * q : qcandidates) { out << q->get_qid() << " ->\n" << mk_pp(q, m_manager) << "\n"; @@ -2749,14 +2749,14 @@ namespace smt { out << f->get_name() << " " << mk_pp(def, m_manager) << " ->\n"; display_quantifier_set(out, s); } } - + // // Search: main procedures // struct ev_handler { hint_solver * m_owner; - + void operator()(quantifier * q, bool ins) { quantifier_info * qi = m_owner->get_qinfo(q); qi->set_the_one(0); @@ -2769,7 +2769,7 @@ namespace smt { typedef backtrackable_set qset; - typedef backtrackable_set qsset; + typedef backtrackable_set qsset; typedef obj_map f2def; qset m_residue; @@ -2793,7 +2793,7 @@ namespace smt { } out << "\n"; } - + bool check_satisfied_residue_invariant() { DEBUG_CODE( for (quantifier * q : m_satisfied) { @@ -2805,7 +2805,7 @@ namespace smt { return true; } - + bool update_satisfied_residue(func_decl * f, expr * def) { bool useful = false; SASSERT(check_satisfied_residue_invariant()); @@ -2831,7 +2831,7 @@ namespace smt { SASSERT(check_satisfied_residue_invariant()); return true; } - + /** \brief Extract from m_residue, func_decls that can be used as macros to satisfy it. The candidates must not be elements of m_fs. @@ -2861,13 +2861,13 @@ namespace smt { if (depth >= GREEDY_MAX_DEPTH) return; // failed - TRACE("model_finder_hint", + TRACE("model_finder_hint", tout << "greedy depth: " << depth << ", f: " << f->get_name() << "\n"; display_search_state(tout);); expr_set * s = get_f_defs(f); for (expr * def : *s) { - + SASSERT(!m_fs.contains(f)); m_satisfied.push_scope(); @@ -2879,7 +2879,7 @@ namespace smt { greedy(depth + 1); // greedy throws exception in case of success // reachable iff greedy failed. } - + m_satisfied.pop_scope(); m_residue.pop_scope(); m_fs.erase(f); @@ -2892,7 +2892,7 @@ namespace smt { */ void greedy(unsigned depth) { if (m_residue.empty()) { - TRACE("model_finder_hint", + TRACE("model_finder_hint", tout << "found subset that is satisfied by macros\n"; display_search_state(tout);); throw found_satisfied_subset(); @@ -2938,7 +2938,7 @@ namespace smt { quantifiers in m_satisfied. */ void set_interp() { - for (auto const& kv : m_fs) { + for (auto const& kv : m_fs) { func_decl * f = kv.m_key; expr * def = kv.m_value; set_else_interp(f, def); @@ -3026,7 +3026,7 @@ namespace smt { return true; return false; } - + cond_macro * get_macro_for(func_decl * f, quantifier * q) { cond_macro * r = 0; quantifier_info * qi = get_qinfo(q); @@ -3145,13 +3145,13 @@ namespace smt { } }; }; - + // ----------------------------------- // - // model finder + // model finder // // ----------------------------------- - + model_finder::model_finder(ast_manager & m, simplifier & s): m_manager(m), m_context(0), @@ -3163,11 +3163,11 @@ namespace smt { m_nm_solver(alloc(non_auf_macro_solver, m, m_q2info, m_dependencies)), m_new_constraints(m) { } - + model_finder::~model_finder() { reset(); } - + void model_finder::checkpoint() { checkpoint("model_finder"); } @@ -3184,14 +3184,14 @@ namespace smt { SASSERT(info != 0); return info; } - + void model_finder::set_context(context * ctx) { - SASSERT(m_context == 0); + SASSERT(m_context == 0); m_context = ctx; m_auf_solver->set_context(ctx); m_nm_solver->set_params(ctx->get_fparams()); } - + void model_finder::register_quantifier(quantifier * q) { TRACE("model_finder", tout << "registering:\n" << mk_pp(q, m_manager) << "\n";); quantifier_info * new_info = alloc(quantifier_info, *this, m_manager, q); @@ -3200,15 +3200,15 @@ namespace smt { m_analyzer->operator()(new_info); TRACE("model_finder", tout << "after analyzer:\n"; new_info->display(tout);); } - + void model_finder::push_scope() { m_scopes.push_back(scope()); scope & s = m_scopes.back(); s.m_quantifiers_lim = m_quantifiers.size(); } - + void model_finder::restore_quantifiers(unsigned old_size) { - unsigned curr_size = m_quantifiers.size(); + unsigned curr_size = m_quantifiers.size(); SASSERT(old_size <= curr_size); for (unsigned i = old_size; i < curr_size; i++) { quantifier * q = m_quantifiers[i]; @@ -3219,7 +3219,7 @@ namespace smt { } m_quantifiers.shrink(old_size); } - + void model_finder::pop_scope(unsigned num_scopes) { unsigned lvl = m_scopes.size(); SASSERT(num_scopes <= lvl); @@ -3228,7 +3228,7 @@ namespace smt { restore_quantifiers(s.m_quantifiers_lim); m_scopes.shrink(new_lvl); } - + void model_finder::reset() { m_scopes.reset(); m_dependencies.reset(); @@ -3236,7 +3236,7 @@ namespace smt { SASSERT(m_q2info.empty()); SASSERT(m_quantifiers.empty()); } - + void model_finder::init_search_eh() { // do nothing in the current version } @@ -3258,12 +3258,12 @@ namespace smt { } m_auf_solver->mk_instantiation_sets(); - for (quantifier * q : qs) { + for (quantifier * q : qs) { quantifier_info * qi = get_quantifier_info(q); qi->populate_inst_sets(*(m_auf_solver.get()), m_context); } m_auf_solver->fix_model(m_new_constraints); - TRACE("model_finder", + TRACE("model_finder", for (quantifier * q : qs) { quantifier_info * qi = get_quantifier_info(q); quantifier * fq = qi->get_flat_q(); @@ -3285,7 +3285,7 @@ namespace smt { qs.swap(new_qs); TRACE("model_finder", tout << "model after processing simple macros:\n"; model_pp(tout, *m);); } - + void model_finder::process_non_auf_macros(ptr_vector & qs, ptr_vector & residue, proto_model * m) { ptr_vector new_qs; m_nm_solver->operator()(m, qs, new_qs, residue); @@ -3347,12 +3347,12 @@ namespace smt { << "\ni: " << i << " " << flat_q->get_num_decls() - q->get_num_decls() + i << "\n";); if (r != 0) return r; - // quantifier was not processed by AUF solver... + // quantifier was not processed by AUF solver... // it must have been satisfied by "macro"/"hint". quantifier_info * qinfo = get_quantifier_info(q); SASSERT(qinfo); SASSERT(qinfo->get_the_one() != 0); - + return qinfo->get_macro_based_inst_set(i, m_context, *(m_auf_solver.get())); } @@ -3373,11 +3373,11 @@ namespace smt { } return t; } - + /** \brief Assert constraints restricting the possible values of the skolem constants can be assigned to. The idea is to restrict them to the values in the instantiation sets. - + \remark q is the quantifier before flattening. Return true if something was asserted. @@ -3425,7 +3425,7 @@ namespace smt { TRACE("model_finder_bug_detail", tout << "asserting new constraint: " << mk_pp(c, m_manager) << "\n";); m_context->internalize(c, true); literal l(m_context->get_literal(c)); - m_context->mark_as_relevant(l); + m_context->mark_as_relevant(l); // asserting it as an AXIOM m_context->assign(l, b_justification()); } From 8310b24c521b6dac99a97a61ab74115c377db1b2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Aug 2017 20:34:11 +0100 Subject: [PATCH 188/488] Eliminated the dependency of the macro-finder on the simplifier. --- src/ast/macros/macro_finder.cpp | 43 ++++++------ src/ast/macros/macro_finder.h | 17 ++--- src/ast/macros/macro_manager.cpp | 2 +- src/ast/macros/macro_util.cpp | 106 ++++++++++++------------------ src/ast/macros/macro_util.h | 25 ++++--- src/ast/rewriter/arith_rewriter.h | 20 +++--- src/ast/rewriter/poly_rewriter.h | 57 ++++++++++++++++ src/smt/smt_model_finder.cpp | 37 +++++------ 8 files changed, 168 insertions(+), 139 deletions(-) diff --git a/src/ast/macros/macro_finder.cpp b/src/ast/macros/macro_finder.cpp index 285c0e5fb..604d10b04 100644 --- a/src/ast/macros/macro_finder.cpp +++ b/src/ast/macros/macro_finder.cpp @@ -21,8 +21,9 @@ Revision History: #include "ast/occurs.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" +#include "ast/rewriter/arith_rewriter.h" -bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) { +bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) const { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) return false; TRACE("macro_finder", tout << "processing: " << mk_pp(n, m_manager) << "\n";); @@ -32,30 +33,30 @@ bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) { } /** - \brief Detect macros of the form + \brief Detect macros of the form 1- (forall (X) (= (+ (f X) (R X)) c)) 2- (forall (X) (<= (+ (f X) (R X)) c)) 3- (forall (X) (>= (+ (f X) (R X)) c)) The second and third cases are first converted into (forall (X) (= (f X) (+ c (* -1 (R x)) (k X)))) - and + and (forall (X) (<= (k X) 0)) when case 2 (forall (X) (>= (k X) 0)) when case 3 For case 2 & 3, the new quantifiers are stored in new_exprs and new_prs. */ -bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { +bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) const { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) return false; - arith_simplifier_plugin * as = get_arith_simp(); - arith_util & autil = as->get_arith_util(); + arith_rewriter & arw = m_util.get_arith_rw(); + arith_util & au = m_util.get_arith_util(); expr * body = to_quantifier(n)->get_expr(); unsigned num_decls = to_quantifier(n)->get_num_decls(); - - if (!autil.is_le(body) && !autil.is_ge(body) && !m_manager.is_eq(body)) + + if (!au.is_le(body) && !au.is_ge(body) && !m_manager.is_eq(body)) return false; - if (!as->is_add(to_app(body)->get_arg(0))) + if (!au.is_add(to_app(body)->get_arg(0))) return false; app_ref head(m_manager); expr_ref def(m_manager); @@ -63,15 +64,15 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex if (!m_util.is_arith_macro(body, num_decls, head, def, inv)) return false; app_ref new_body(m_manager); - + if (!inv || m_manager.is_eq(body)) new_body = m_manager.mk_app(to_app(body)->get_decl(), head, def); - else if (as->is_le(body)) - new_body = autil.mk_ge(head, def); + else if (au.is_le(body)) + new_body = au.mk_ge(head, def); else - new_body = autil.mk_le(head, def); + new_body = au.mk_le(head, def); - quantifier_ref new_q(m_manager); + quantifier_ref new_q(m_manager); new_q = m_manager.update_quantifier(to_quantifier(n), new_body); proof * new_pr = 0; if (m_manager.proofs_enabled()) { @@ -82,16 +83,16 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex return m_macro_manager.insert(head->get_decl(), new_q, new_pr); } // is ge or le - // + // TRACE("macro_finder", tout << "is_arith_macro: is_ge or is_le\n";); func_decl * f = head->get_decl(); func_decl * k = m_manager.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); app * k_app = m_manager.mk_app(k, head->get_num_args(), head->get_args()); expr_ref_buffer new_rhs_args(m_manager); expr_ref new_rhs2(m_manager); - as->mk_add(def, k_app, new_rhs2); + arw.mk_add(def, k_app, new_rhs2); expr * body1 = m_manager.mk_eq(head, new_rhs2); - expr * body2 = m_manager.mk_app(new_body->get_decl(), k_app, as->mk_numeral(rational(0))); + expr * body2 = m_manager.mk_app(new_body->get_decl(), k_app, au.mk_numeral(0, m_manager.get_sort(def))); quantifier * q1 = m_manager.update_quantifier(new_q, body1); expr * patterns[1] = { m_manager.mk_pattern(k_app) }; quantifier * q2 = m_manager.update_quantifier(new_q, 1, patterns, body2); @@ -118,7 +119,7 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex n is of the form: (forall (X) (iff (= (f X) t) def[X])) Convert it into: - + (forall (X) (= (f X) (ite def[X] t (k X)))) (forall (X) (not (= (k X) t))) @@ -126,13 +127,13 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex The new quantifiers and proofs are stored in new_exprs and new_prs */ -static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, expr * def, quantifier * q, proof * pr, +static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, expr * def, quantifier * q, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { func_decl * f = head->get_decl(); func_decl * k = m.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); app * k_app = m.mk_app(k, head->get_num_args(), head->get_args()); app * ite = m.mk_ite(def, t, k_app); - app * body_1 = m.mk_eq(head, ite); + app * body_1 = m.mk_eq(head, ite); app * body_2 = m.mk_not(m.mk_eq(k_app, t)); quantifier * q1 = m.update_quantifier(q, body_1); expr * pats[1] = { m.mk_pattern(k_app) }; @@ -183,7 +184,7 @@ bool macro_finder::expand_macros(unsigned num, expr * const * exprs, proof * con TRACE("macro_finder_found", tout << "found new arith macro:\n" << new_n << "\n";); found_new_macro = true; } - else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) { + else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) { TRACE("macro_finder_found", tout << "found new pseudo macro:\n" << head << "\n" << t << "\n" << def << "\n";); pseudo_predicate_macro2macro(m_manager, head, t, def, to_quantifier(new_n), new_pr, new_exprs, new_prs); found_new_macro = true; diff --git a/src/ast/macros/macro_finder.h b/src/ast/macros/macro_finder.h index 7f1b27f0e..0c292eab8 100644 --- a/src/ast/macros/macro_finder.h +++ b/src/ast/macros/macro_finder.h @@ -20,8 +20,7 @@ Revision History: #define MACRO_FINDER_H_ #include "ast/macros/macro_manager.h" -#include "ast/simplifier/arith_simplifier_plugin.h" - +#include "ast/macros/macro_util.h" bool is_macro_head(expr * n, unsigned num_decls); bool is_simple_macro(ast_manager & m, expr * n, unsigned num_decls, obj_hashtable const * forbidden_set, app * & head, expr * & def); @@ -34,16 +33,15 @@ inline bool is_simple_macro(ast_manager & m, expr * n, unsigned num_decls, app * as macros. */ class macro_finder { - ast_manager & m_manager; + ast_manager & m_manager; macro_manager & m_macro_manager; macro_util & m_util; - arith_simplifier_plugin * get_arith_simp() { return m_util.get_arith_simp(); } - bool expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); - bool is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); - bool is_macro(expr * n, app_ref & head, expr_ref & def); - bool is_pseudo_head(expr * n, unsigned num_decls, app * & head, app * & t); - bool is_pseudo_predicate_macro(expr * n, app * & head, app * & t, expr * & def); + bool expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + bool is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) const; + bool is_macro(expr * n, app_ref & head, expr_ref & def) const; + bool is_pseudo_head(expr * n, unsigned num_decls, app * & head, app * & t) const; + bool is_pseudo_predicate_macro(expr * n, app * & head, app * & t, expr * & def) const; public: macro_finder(ast_manager & m, macro_manager & mm); @@ -52,4 +50,3 @@ public: }; #endif /* MACRO_FINDER_H_ */ - diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index bd330a2de..f26a87445 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -28,7 +28,7 @@ Revision History: macro_manager::macro_manager(ast_manager & m, simplifier & s): m_manager(m), m_simplifier(s), - m_util(m, s), + m_util(m), m_decls(m), m_macros(m), m_macro_prs(m), diff --git a/src/ast/macros/macro_util.cpp b/src/ast/macros/macro_util.cpp index 35f2fbcfb..415e77d03 100644 --- a/src/ast/macros/macro_util.cpp +++ b/src/ast/macros/macro_util.cpp @@ -20,8 +20,8 @@ Revision History: #include "ast/macros/macro_util.h" #include "ast/occurs.h" #include "ast/ast_util.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/arith_decl_plugin.h" +#include "ast/bv_decl_plugin.h" #include "ast/rewriter/var_subst.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" @@ -29,96 +29,73 @@ Revision History: #include "ast/well_sorted.h" #include "ast/rewriter/bool_rewriter.h" -macro_util::macro_util(ast_manager & m, simplifier & s): +macro_util::macro_util(ast_manager & m): m_manager(m), - m_bv(m), - m_simplifier(s), - m_arith_simp(0), - m_bv_simp(0), + m_arith_rw(m), + m_arith_util(m_arith_rw.get_util()), + m_bv_rw(m), + m_bv_util(m_bv_rw.get_util()), m_forbidden_set(0), m_curr_clause(0) { } -arith_simplifier_plugin * macro_util::get_arith_simp() const { - if (m_arith_simp == 0) { - const_cast(this)->m_arith_simp = static_cast(m_simplifier.get_plugin(m_manager.mk_family_id("arith"))); - } - SASSERT(m_arith_simp != 0); - return m_arith_simp; -} - -bv_simplifier_plugin * macro_util::get_bv_simp() const { - if (m_bv_simp == 0) { - const_cast(this)->m_bv_simp = static_cast(m_simplifier.get_plugin(m_manager.mk_family_id("bv"))); - } - SASSERT(m_bv_simp != 0); - return m_bv_simp; -} - - bool macro_util::is_bv(expr * n) const { - return m_bv.is_bv(n); + return m_bv_util.is_bv(n); } bool macro_util::is_bv_sort(sort * s) const { - return m_bv.is_bv_sort(s); + return m_bv_util.is_bv_sort(s); } bool macro_util::is_add(expr * n) const { - return get_arith_simp()->is_add(n) || m_bv.is_bv_add(n); + return m_arith_util.is_add(n) || m_bv_util.is_bv_add(n); } bool macro_util::is_times_minus_one(expr * n, expr * & arg) const { - return get_arith_simp()->is_times_minus_one(n, arg) || get_bv_simp()->is_times_minus_one(n, arg); + return is_app(n) && to_app(n)->get_num_args() == 2 && + ((m_arith_rw.is_mul(n) && m_arith_rw.is_times_minus_one(to_app(n)->get_arg(0), arg)) || + (m_bv_rw.is_mul(n) && m_bv_rw.is_times_minus_one(to_app(n)->get_arg(0), arg))); } bool macro_util::is_le(expr * n) const { - return get_arith_simp()->is_le(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); + return m_arith_util.is_le(n) || m_bv_util.is_bv_ule(n) || m_bv_util.is_bv_sle(n); } bool macro_util::is_le_ge(expr * n) const { - return get_arith_simp()->is_le_ge(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); -} - -poly_simplifier_plugin * macro_util::get_poly_simp_for(sort * s) const { - if (is_bv_sort(s)) - return get_bv_simp(); - else - return get_arith_simp(); + return m_arith_util.is_le(n) || m_arith_util.is_ge(n) || + m_bv_util.is_bv_ule(n) || m_bv_util.is_bv_sle(n); } app * macro_util::mk_zero(sort * s) const { - poly_simplifier_plugin * ps = get_poly_simp_for(s); - ps->set_curr_sort(s); - return ps->mk_zero(); + if (is_bv_sort(s)) + return m_bv_util.mk_numeral(rational(0), s); + else + return m_arith_util.mk_numeral(0, s); } void macro_util::mk_sub(expr * t1, expr * t2, expr_ref & r) const { - if (is_bv(t1)) { - r = m_bv.mk_bv_sub(t1, t2); - } - else { - get_arith_simp()->mk_sub(t1, t2, r); - } + if (is_bv(t1)) + r = m_bv_util.mk_bv_sub(t1, t2); + else + r = m_arith_util.mk_sub(t1, t2); } void macro_util::mk_add(expr * t1, expr * t2, expr_ref & r) const { - if (is_bv(t1)) { - r = m_bv.mk_bv_add(t1, t2); - } - else { - get_arith_simp()->mk_add(t1, t2, r); - } + if (is_bv(t1)) + r = m_bv_util.mk_bv_add(t1, t2); + else + m_arith_util.mk_add(t1, t2, r); } void macro_util::mk_add(unsigned num_args, expr * const * args, sort * s, expr_ref & r) const { - if (num_args == 0) { + if (num_args == 0) r = mk_zero(s); - return; - } - poly_simplifier_plugin * ps = get_poly_simp_for(s); - ps->set_curr_sort(s); - ps->mk_add(num_args, args, r); + else if (num_args == 1) + r = args[0]; + else if (is_bv_sort(s)) + m_bv_rw.mk_add(num_args, args, r); + else + m_arith_rw.mk_add(num_args, args, r); } /** @@ -241,13 +218,12 @@ bool macro_util::poly_contains_head(expr * n, func_decl * f, expr * exception) c bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def, bool & inv) const { // TODO: obsolete... we should move to collect_arith_macro_candidates - arith_simplifier_plugin * as = get_arith_simp(); - if (!m_manager.is_eq(n) && !as->is_le(n) && !as->is_ge(n)) + if (!m_manager.is_eq(n) && !m_arith_util.is_le(n) && !m_arith_util.is_ge(n)) return false; expr * lhs = to_app(n)->get_arg(0); expr * rhs = to_app(n)->get_arg(1); - if (!as->is_numeral(rhs)) + if (!m_arith_util.is_numeral(rhs)) return false; inv = false; @@ -272,7 +248,7 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex !poly_contains_head(lhs, to_app(arg)->get_decl(), arg)) { h = arg; } - else if (h == 0 && as->is_times_minus_one(arg, neg_arg) && + else if (h == 0 && m_arith_util.is_times_minus_one(arg, neg_arg) && is_macro_head(neg_arg, num_decls) && !is_forbidden(to_app(neg_arg)->get_decl()) && !poly_contains_head(lhs, to_app(neg_arg)->get_decl(), arg)) { @@ -287,11 +263,11 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex return false; head = to_app(h); expr_ref tmp(m_manager); - as->mk_add(args.size(), args.c_ptr(), tmp); + m_arith_rw.mk_add(args.size(), args.c_ptr(), tmp); if (inv) - as->mk_sub(tmp, rhs, def); + m_arith_rw.mk_sub(tmp, rhs, def); else - as->mk_sub(rhs, tmp, def); + m_arith_rw.mk_sub(rhs, tmp, def); return true; } diff --git a/src/ast/macros/macro_util.h b/src/ast/macros/macro_util.h index d76f2f0d3..3da8accc9 100644 --- a/src/ast/macros/macro_util.h +++ b/src/ast/macros/macro_util.h @@ -22,12 +22,8 @@ Revision History: #include "ast/ast.h" #include "util/obj_hashtable.h" -#include "ast/simplifier/simplifier.h" - -class poly_simplifier_plugin; -class arith_simplifier_plugin; -class bv_simplifier_plugin; -class basic_simplifier_plugin; +#include "ast/rewriter/arith_rewriter.h" +#include "ast/rewriter/bv_rewriter.h" class macro_util { public: @@ -62,10 +58,10 @@ public: private: ast_manager & m_manager; - bv_util m_bv; - simplifier & m_simplifier; - arith_simplifier_plugin * m_arith_simp; - bv_simplifier_plugin * m_bv_simp; + mutable arith_rewriter m_arith_rw; + arith_util & m_arith_util; + mutable bv_rewriter m_bv_rw; + bv_util & m_bv_util; obj_hashtable * m_forbidden_set; bool is_forbidden(func_decl * f) const { return m_forbidden_set != 0 && m_forbidden_set->contains(f); } @@ -94,11 +90,13 @@ private: public: - macro_util(ast_manager & m, simplifier & s); + macro_util(ast_manager & m); void set_forbidden_set(obj_hashtable * s) { m_forbidden_set = s; } - arith_simplifier_plugin * get_arith_simp() const; - bv_simplifier_plugin * get_bv_simp() const; + arith_util & get_arith_util() const { return m_arith_util; } + bv_util & get_bv_util() const { return m_bv_util; } + arith_rewriter & get_arith_rw() const { return m_arith_rw; } + bv_rewriter & get_bv_rw() const { return m_bv_rw; } bool is_macro_head(expr * n, unsigned num_decls) const; bool is_left_simple_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const; @@ -137,7 +135,6 @@ public: void mk_sub(expr * t1, expr * t2, expr_ref & r) const; void mk_add(expr * t1, expr * t2, expr_ref & r) const; void mk_add(unsigned num_args, expr * const * args, sort * s, expr_ref & r) const; - poly_simplifier_plugin * get_poly_simp_for(sort * s) const; }; #endif diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index de849dbd7..2342782c1 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -29,10 +29,10 @@ protected: bool m_expand_power; bool m_mul2power; bool m_expand_tan; - + ast_manager & m() const { return m_util.get_manager(); } family_id get_fid() const { return m_util.get_family_id(); } - + bool is_numeral(expr * n) const { return m_util.is_numeral(n); } bool is_numeral(expr * n, numeral & r) const { return m_util.is_numeral(n, r); } bool is_zero(expr * n) const { return m_util.is_zero(n); } @@ -77,7 +77,7 @@ class arith_rewriter : public poly_rewriter { br_status mk_div_irrat_rat(expr * arg1, expr * arg2, expr_ref & result); br_status mk_div_rat_irrat(expr * arg1, expr * arg2, expr_ref & result); br_status mk_div_irrat_irrat(expr * arg1, expr * arg2, expr_ref & result); - + bool is_reduce_power_target(expr * arg, bool is_eq); expr * reduce_power(expr * arg, bool is_eq); br_status reduce_power(expr * arg1, expr * arg2, op_kind kind, expr_ref & result); @@ -154,16 +154,16 @@ public: if (mk_rem_core(arg1, arg2, result) == BR_FAILED) result = m().mk_app(get_fid(), OP_REM, arg1, arg2); } - + br_status mk_to_int_core(expr * arg, expr_ref & result); br_status mk_to_real_core(expr * arg, expr_ref & result); - void mk_to_int(expr * arg, expr_ref & result) { + void mk_to_int(expr * arg, expr_ref & result) { if (mk_to_int_core(arg, result) == BR_FAILED) - result = m().mk_app(get_fid(), OP_TO_INT, 1, &arg); + result = m().mk_app(get_fid(), OP_TO_INT, 1, &arg); } - void mk_to_real(expr * arg, expr_ref & result) { - if (mk_to_real_core(arg, result) == BR_FAILED) - result = m().mk_app(get_fid(), OP_TO_REAL, 1, &arg); + void mk_to_real(expr * arg, expr_ref & result) { + if (mk_to_real_core(arg, result) == BR_FAILED) + result = m().mk_app(get_fid(), OP_TO_REAL, 1, &arg); } br_status mk_is_int(expr * arg, expr_ref & result); @@ -178,6 +178,8 @@ public: br_status mk_sinh_core(expr * arg, expr_ref & result); br_status mk_cosh_core(expr * arg, expr_ref & result); br_status mk_tanh_core(expr * arg, expr_ref & result); + + arith_util & get_util() { return m_util; } }; #endif diff --git a/src/ast/rewriter/poly_rewriter.h b/src/ast/rewriter/poly_rewriter.h index 5d38e4b10..81c5ea132 100644 --- a/src/ast/rewriter/poly_rewriter.h +++ b/src/ast/rewriter/poly_rewriter.h @@ -159,6 +159,63 @@ public: expr* args[2] = { a1, a2 }; mk_sub(2, args, result); } + + bool is_times_minus_one(expr * n, expr * & r) const { + if (is_mul(n) && to_app(n)->get_num_args() == 2 && is_minus_one(to_app(n)->get_arg(0))) { + r = to_app(n)->get_arg(1); + return true; + } + return false; + } + + /** + \brief Return true if n is can be put into the form (+ v t) or (+ (- v) t) + \c inv = true will contain true if (- v) is found, and false otherwise. + */ + bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) { + if (!is_add(n) || is_ground(n)) + return false; + + ptr_buffer args; + v = 0; + expr * curr = to_app(n); + bool stop = false; + inv = false; + while (!stop) { + expr * arg; + expr * neg_arg; + if (is_add(curr)) { + arg = to_app(curr)->get_arg(0); + curr = to_app(curr)->get_arg(1); + } + else { + arg = curr; + stop = true; + } + if (is_ground(arg)) { + args.push_back(arg); + } + else if (is_var(arg)) { + if (v != 0) + return false; // already found variable + v = to_var(arg); + } + else if (is_times_minus_one(arg, neg_arg) && is_var(neg_arg)) { + if (v != 0) + return false; // already found variable + v = to_var(neg_arg); + inv = true; + } + else { + return false; // non ground term. + } + } + if (v == 0) + return false; // did not find variable + SASSERT(!args.empty()); + mk_add(args.size(), args.c_ptr(), t); + return true; + } }; diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 94a6a7267..0a80460f5 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -1873,12 +1873,12 @@ namespace smt { fill the structure quantifier_info. */ class quantifier_analyzer { - model_finder& m_mf; + model_finder & m_mf; ast_manager & m_manager; macro_util m_mutil; array_util m_array_util; - arith_util m_arith_util; - bv_util m_bv_util; + arith_util & m_arith_util; + bv_util & m_bv_util; quantifier_info * m_info; @@ -1897,14 +1897,12 @@ namespace smt { m_info->insert_qinfo(qi); } - arith_simplifier_plugin * get_arith_simp() const { return m_mutil.get_arith_simp(); } - bv_simplifier_plugin * get_bv_simp() const { return m_mutil.get_bv_simp(); } - bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) const { - return get_arith_simp()->is_var_plus_ground(n, inv, v, t) || get_bv_simp()->is_var_plus_ground(n, inv, v, t); + return m_mutil.get_arith_rw().is_var_plus_ground(n, inv, v, t) || + m_mutil.get_bv_rw().is_var_plus_ground(n, inv, v, t); } - bool is_var_plus_ground(expr * n, var * & v, expr_ref & t) { + bool is_var_plus_ground(expr * n, var * & v, expr_ref & t) const { bool inv; TRACE("is_var_plus_ground", tout << mk_pp(n, m_manager) << "\n"; tout << "is_var_plus_ground: " << is_var_plus_ground(n, inv, v, t) << "\n"; @@ -1917,10 +1915,11 @@ namespace smt { } bool is_zero(expr * n) const { - if (get_bv_simp()->is_bv(n)) - return get_bv_simp()->is_zero_safe(n); - else - return get_arith_simp()->is_zero_safe(n); + if (m_bv_util.is_bv(n)) + return m_bv_util.is_zero(n); + else { + return m_arith_util.is_zero(n); + } } bool is_times_minus_one(expr * n, expr * & arg) const { @@ -1939,7 +1938,7 @@ namespace smt { return m_bv_util.is_bv_sle(n); } - expr * mk_one(sort * s) { + expr * mk_one(sort * s) const { return m_bv_util.is_bv_sort(s) ? m_bv_util.mk_numeral(rational(1), s) : m_arith_util.mk_numeral(rational(1), s); } @@ -1951,7 +1950,7 @@ namespace smt { m_mutil.mk_add(t1, t2, r); } - bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t, bool & inv) const { + bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t, bool & inv) { inv = false; // true if invert the sign TRACE("is_var_and_ground", tout << "is_var_and_ground: " << mk_ismt2_pp(lhs, m_manager) << " " << mk_ismt2_pp(rhs, m_manager) << "\n";); if (is_var(lhs) && is_ground(rhs)) { @@ -1986,12 +1985,12 @@ namespace smt { return false; } - bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t) const { + bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t) { bool inv; return is_var_and_ground(lhs, rhs, v, t, inv); } - bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) const { + bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) { if (!is_app(n)) return false; if (m_manager.is_eq(n)) @@ -2382,10 +2381,10 @@ namespace smt { quantifier_analyzer(model_finder& mf, ast_manager & m, simplifier & s): m_mf(mf), m_manager(m), - m_mutil(m, s), + m_mutil(m), m_array_util(m), - m_arith_util(m), - m_bv_util(m), + m_arith_util(m_mutil.get_arith_util()), + m_bv_util(m_mutil.get_bv_util()), m_info(0) { } From 799fb4a0d1e9b21a8af15759ecae4353dbb5d6bd Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Aug 2017 21:26:09 +0100 Subject: [PATCH 189/488] Revert "Eliminated the dependency of the macro-finder on the simplifier." This reverts commit 8310b24c521b6dac99a97a61ab74115c377db1b2. --- src/ast/macros/macro_finder.cpp | 43 ++++++------ src/ast/macros/macro_finder.h | 17 +++-- src/ast/macros/macro_manager.cpp | 2 +- src/ast/macros/macro_util.cpp | 106 ++++++++++++++++++------------ src/ast/macros/macro_util.h | 25 +++---- src/ast/rewriter/arith_rewriter.h | 20 +++--- src/ast/rewriter/poly_rewriter.h | 57 ---------------- src/smt/smt_model_finder.cpp | 37 ++++++----- 8 files changed, 139 insertions(+), 168 deletions(-) diff --git a/src/ast/macros/macro_finder.cpp b/src/ast/macros/macro_finder.cpp index 604d10b04..285c0e5fb 100644 --- a/src/ast/macros/macro_finder.cpp +++ b/src/ast/macros/macro_finder.cpp @@ -21,9 +21,8 @@ Revision History: #include "ast/occurs.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" -#include "ast/rewriter/arith_rewriter.h" -bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) const { +bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) return false; TRACE("macro_finder", tout << "processing: " << mk_pp(n, m_manager) << "\n";); @@ -33,30 +32,30 @@ bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) const { } /** - \brief Detect macros of the form + \brief Detect macros of the form 1- (forall (X) (= (+ (f X) (R X)) c)) 2- (forall (X) (<= (+ (f X) (R X)) c)) 3- (forall (X) (>= (+ (f X) (R X)) c)) The second and third cases are first converted into (forall (X) (= (f X) (+ c (* -1 (R x)) (k X)))) - and + and (forall (X) (<= (k X) 0)) when case 2 (forall (X) (>= (k X) 0)) when case 3 For case 2 & 3, the new quantifiers are stored in new_exprs and new_prs. */ -bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) const { +bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) return false; - arith_rewriter & arw = m_util.get_arith_rw(); - arith_util & au = m_util.get_arith_util(); + arith_simplifier_plugin * as = get_arith_simp(); + arith_util & autil = as->get_arith_util(); expr * body = to_quantifier(n)->get_expr(); unsigned num_decls = to_quantifier(n)->get_num_decls(); - - if (!au.is_le(body) && !au.is_ge(body) && !m_manager.is_eq(body)) + + if (!autil.is_le(body) && !autil.is_ge(body) && !m_manager.is_eq(body)) return false; - if (!au.is_add(to_app(body)->get_arg(0))) + if (!as->is_add(to_app(body)->get_arg(0))) return false; app_ref head(m_manager); expr_ref def(m_manager); @@ -64,15 +63,15 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex if (!m_util.is_arith_macro(body, num_decls, head, def, inv)) return false; app_ref new_body(m_manager); - + if (!inv || m_manager.is_eq(body)) new_body = m_manager.mk_app(to_app(body)->get_decl(), head, def); - else if (au.is_le(body)) - new_body = au.mk_ge(head, def); + else if (as->is_le(body)) + new_body = autil.mk_ge(head, def); else - new_body = au.mk_le(head, def); + new_body = autil.mk_le(head, def); - quantifier_ref new_q(m_manager); + quantifier_ref new_q(m_manager); new_q = m_manager.update_quantifier(to_quantifier(n), new_body); proof * new_pr = 0; if (m_manager.proofs_enabled()) { @@ -83,16 +82,16 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex return m_macro_manager.insert(head->get_decl(), new_q, new_pr); } // is ge or le - // + // TRACE("macro_finder", tout << "is_arith_macro: is_ge or is_le\n";); func_decl * f = head->get_decl(); func_decl * k = m_manager.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); app * k_app = m_manager.mk_app(k, head->get_num_args(), head->get_args()); expr_ref_buffer new_rhs_args(m_manager); expr_ref new_rhs2(m_manager); - arw.mk_add(def, k_app, new_rhs2); + as->mk_add(def, k_app, new_rhs2); expr * body1 = m_manager.mk_eq(head, new_rhs2); - expr * body2 = m_manager.mk_app(new_body->get_decl(), k_app, au.mk_numeral(0, m_manager.get_sort(def))); + expr * body2 = m_manager.mk_app(new_body->get_decl(), k_app, as->mk_numeral(rational(0))); quantifier * q1 = m_manager.update_quantifier(new_q, body1); expr * patterns[1] = { m_manager.mk_pattern(k_app) }; quantifier * q2 = m_manager.update_quantifier(new_q, 1, patterns, body2); @@ -119,7 +118,7 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex n is of the form: (forall (X) (iff (= (f X) t) def[X])) Convert it into: - + (forall (X) (= (f X) (ite def[X] t (k X)))) (forall (X) (not (= (k X) t))) @@ -127,13 +126,13 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex The new quantifiers and proofs are stored in new_exprs and new_prs */ -static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, expr * def, quantifier * q, proof * pr, +static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, expr * def, quantifier * q, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { func_decl * f = head->get_decl(); func_decl * k = m.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); app * k_app = m.mk_app(k, head->get_num_args(), head->get_args()); app * ite = m.mk_ite(def, t, k_app); - app * body_1 = m.mk_eq(head, ite); + app * body_1 = m.mk_eq(head, ite); app * body_2 = m.mk_not(m.mk_eq(k_app, t)); quantifier * q1 = m.update_quantifier(q, body_1); expr * pats[1] = { m.mk_pattern(k_app) }; @@ -184,7 +183,7 @@ bool macro_finder::expand_macros(unsigned num, expr * const * exprs, proof * con TRACE("macro_finder_found", tout << "found new arith macro:\n" << new_n << "\n";); found_new_macro = true; } - else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) { + else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) { TRACE("macro_finder_found", tout << "found new pseudo macro:\n" << head << "\n" << t << "\n" << def << "\n";); pseudo_predicate_macro2macro(m_manager, head, t, def, to_quantifier(new_n), new_pr, new_exprs, new_prs); found_new_macro = true; diff --git a/src/ast/macros/macro_finder.h b/src/ast/macros/macro_finder.h index 0c292eab8..7f1b27f0e 100644 --- a/src/ast/macros/macro_finder.h +++ b/src/ast/macros/macro_finder.h @@ -20,7 +20,8 @@ Revision History: #define MACRO_FINDER_H_ #include "ast/macros/macro_manager.h" -#include "ast/macros/macro_util.h" +#include "ast/simplifier/arith_simplifier_plugin.h" + bool is_macro_head(expr * n, unsigned num_decls); bool is_simple_macro(ast_manager & m, expr * n, unsigned num_decls, obj_hashtable const * forbidden_set, app * & head, expr * & def); @@ -33,15 +34,16 @@ inline bool is_simple_macro(ast_manager & m, expr * n, unsigned num_decls, app * as macros. */ class macro_finder { - ast_manager & m_manager; + ast_manager & m_manager; macro_manager & m_macro_manager; macro_util & m_util; - + arith_simplifier_plugin * get_arith_simp() { return m_util.get_arith_simp(); } bool expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); - bool is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) const; - bool is_macro(expr * n, app_ref & head, expr_ref & def) const; - bool is_pseudo_head(expr * n, unsigned num_decls, app * & head, app * & t) const; - bool is_pseudo_predicate_macro(expr * n, app * & head, app * & t, expr * & def) const; + bool is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + + bool is_macro(expr * n, app_ref & head, expr_ref & def); + bool is_pseudo_head(expr * n, unsigned num_decls, app * & head, app * & t); + bool is_pseudo_predicate_macro(expr * n, app * & head, app * & t, expr * & def); public: macro_finder(ast_manager & m, macro_manager & mm); @@ -50,3 +52,4 @@ public: }; #endif /* MACRO_FINDER_H_ */ + diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index f26a87445..bd330a2de 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -28,7 +28,7 @@ Revision History: macro_manager::macro_manager(ast_manager & m, simplifier & s): m_manager(m), m_simplifier(s), - m_util(m), + m_util(m, s), m_decls(m), m_macros(m), m_macro_prs(m), diff --git a/src/ast/macros/macro_util.cpp b/src/ast/macros/macro_util.cpp index 415e77d03..35f2fbcfb 100644 --- a/src/ast/macros/macro_util.cpp +++ b/src/ast/macros/macro_util.cpp @@ -20,8 +20,8 @@ Revision History: #include "ast/macros/macro_util.h" #include "ast/occurs.h" #include "ast/ast_util.h" -#include "ast/arith_decl_plugin.h" -#include "ast/bv_decl_plugin.h" +#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/rewriter/var_subst.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" @@ -29,73 +29,96 @@ Revision History: #include "ast/well_sorted.h" #include "ast/rewriter/bool_rewriter.h" -macro_util::macro_util(ast_manager & m): +macro_util::macro_util(ast_manager & m, simplifier & s): m_manager(m), - m_arith_rw(m), - m_arith_util(m_arith_rw.get_util()), - m_bv_rw(m), - m_bv_util(m_bv_rw.get_util()), + m_bv(m), + m_simplifier(s), + m_arith_simp(0), + m_bv_simp(0), m_forbidden_set(0), m_curr_clause(0) { } +arith_simplifier_plugin * macro_util::get_arith_simp() const { + if (m_arith_simp == 0) { + const_cast(this)->m_arith_simp = static_cast(m_simplifier.get_plugin(m_manager.mk_family_id("arith"))); + } + SASSERT(m_arith_simp != 0); + return m_arith_simp; +} + +bv_simplifier_plugin * macro_util::get_bv_simp() const { + if (m_bv_simp == 0) { + const_cast(this)->m_bv_simp = static_cast(m_simplifier.get_plugin(m_manager.mk_family_id("bv"))); + } + SASSERT(m_bv_simp != 0); + return m_bv_simp; +} + + bool macro_util::is_bv(expr * n) const { - return m_bv_util.is_bv(n); + return m_bv.is_bv(n); } bool macro_util::is_bv_sort(sort * s) const { - return m_bv_util.is_bv_sort(s); + return m_bv.is_bv_sort(s); } bool macro_util::is_add(expr * n) const { - return m_arith_util.is_add(n) || m_bv_util.is_bv_add(n); + return get_arith_simp()->is_add(n) || m_bv.is_bv_add(n); } bool macro_util::is_times_minus_one(expr * n, expr * & arg) const { - return is_app(n) && to_app(n)->get_num_args() == 2 && - ((m_arith_rw.is_mul(n) && m_arith_rw.is_times_minus_one(to_app(n)->get_arg(0), arg)) || - (m_bv_rw.is_mul(n) && m_bv_rw.is_times_minus_one(to_app(n)->get_arg(0), arg))); + return get_arith_simp()->is_times_minus_one(n, arg) || get_bv_simp()->is_times_minus_one(n, arg); } bool macro_util::is_le(expr * n) const { - return m_arith_util.is_le(n) || m_bv_util.is_bv_ule(n) || m_bv_util.is_bv_sle(n); + return get_arith_simp()->is_le(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); } bool macro_util::is_le_ge(expr * n) const { - return m_arith_util.is_le(n) || m_arith_util.is_ge(n) || - m_bv_util.is_bv_ule(n) || m_bv_util.is_bv_sle(n); + return get_arith_simp()->is_le_ge(n) || m_bv.is_bv_ule(n) || m_bv.is_bv_sle(n); +} + +poly_simplifier_plugin * macro_util::get_poly_simp_for(sort * s) const { + if (is_bv_sort(s)) + return get_bv_simp(); + else + return get_arith_simp(); } app * macro_util::mk_zero(sort * s) const { - if (is_bv_sort(s)) - return m_bv_util.mk_numeral(rational(0), s); - else - return m_arith_util.mk_numeral(0, s); + poly_simplifier_plugin * ps = get_poly_simp_for(s); + ps->set_curr_sort(s); + return ps->mk_zero(); } void macro_util::mk_sub(expr * t1, expr * t2, expr_ref & r) const { - if (is_bv(t1)) - r = m_bv_util.mk_bv_sub(t1, t2); - else - r = m_arith_util.mk_sub(t1, t2); + if (is_bv(t1)) { + r = m_bv.mk_bv_sub(t1, t2); + } + else { + get_arith_simp()->mk_sub(t1, t2, r); + } } void macro_util::mk_add(expr * t1, expr * t2, expr_ref & r) const { - if (is_bv(t1)) - r = m_bv_util.mk_bv_add(t1, t2); - else - m_arith_util.mk_add(t1, t2, r); + if (is_bv(t1)) { + r = m_bv.mk_bv_add(t1, t2); + } + else { + get_arith_simp()->mk_add(t1, t2, r); + } } void macro_util::mk_add(unsigned num_args, expr * const * args, sort * s, expr_ref & r) const { - if (num_args == 0) + if (num_args == 0) { r = mk_zero(s); - else if (num_args == 1) - r = args[0]; - else if (is_bv_sort(s)) - m_bv_rw.mk_add(num_args, args, r); - else - m_arith_rw.mk_add(num_args, args, r); + return; + } + poly_simplifier_plugin * ps = get_poly_simp_for(s); + ps->set_curr_sort(s); + ps->mk_add(num_args, args, r); } /** @@ -218,12 +241,13 @@ bool macro_util::poly_contains_head(expr * n, func_decl * f, expr * exception) c bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def, bool & inv) const { // TODO: obsolete... we should move to collect_arith_macro_candidates - if (!m_manager.is_eq(n) && !m_arith_util.is_le(n) && !m_arith_util.is_ge(n)) + arith_simplifier_plugin * as = get_arith_simp(); + if (!m_manager.is_eq(n) && !as->is_le(n) && !as->is_ge(n)) return false; expr * lhs = to_app(n)->get_arg(0); expr * rhs = to_app(n)->get_arg(1); - if (!m_arith_util.is_numeral(rhs)) + if (!as->is_numeral(rhs)) return false; inv = false; @@ -248,7 +272,7 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex !poly_contains_head(lhs, to_app(arg)->get_decl(), arg)) { h = arg; } - else if (h == 0 && m_arith_util.is_times_minus_one(arg, neg_arg) && + else if (h == 0 && as->is_times_minus_one(arg, neg_arg) && is_macro_head(neg_arg, num_decls) && !is_forbidden(to_app(neg_arg)->get_decl()) && !poly_contains_head(lhs, to_app(neg_arg)->get_decl(), arg)) { @@ -263,11 +287,11 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex return false; head = to_app(h); expr_ref tmp(m_manager); - m_arith_rw.mk_add(args.size(), args.c_ptr(), tmp); + as->mk_add(args.size(), args.c_ptr(), tmp); if (inv) - m_arith_rw.mk_sub(tmp, rhs, def); + as->mk_sub(tmp, rhs, def); else - m_arith_rw.mk_sub(rhs, tmp, def); + as->mk_sub(rhs, tmp, def); return true; } diff --git a/src/ast/macros/macro_util.h b/src/ast/macros/macro_util.h index 3da8accc9..d76f2f0d3 100644 --- a/src/ast/macros/macro_util.h +++ b/src/ast/macros/macro_util.h @@ -22,8 +22,12 @@ Revision History: #include "ast/ast.h" #include "util/obj_hashtable.h" -#include "ast/rewriter/arith_rewriter.h" -#include "ast/rewriter/bv_rewriter.h" +#include "ast/simplifier/simplifier.h" + +class poly_simplifier_plugin; +class arith_simplifier_plugin; +class bv_simplifier_plugin; +class basic_simplifier_plugin; class macro_util { public: @@ -58,10 +62,10 @@ public: private: ast_manager & m_manager; - mutable arith_rewriter m_arith_rw; - arith_util & m_arith_util; - mutable bv_rewriter m_bv_rw; - bv_util & m_bv_util; + bv_util m_bv; + simplifier & m_simplifier; + arith_simplifier_plugin * m_arith_simp; + bv_simplifier_plugin * m_bv_simp; obj_hashtable * m_forbidden_set; bool is_forbidden(func_decl * f) const { return m_forbidden_set != 0 && m_forbidden_set->contains(f); } @@ -90,13 +94,11 @@ private: public: - macro_util(ast_manager & m); + macro_util(ast_manager & m, simplifier & s); void set_forbidden_set(obj_hashtable * s) { m_forbidden_set = s; } - arith_util & get_arith_util() const { return m_arith_util; } - bv_util & get_bv_util() const { return m_bv_util; } - arith_rewriter & get_arith_rw() const { return m_arith_rw; } - bv_rewriter & get_bv_rw() const { return m_bv_rw; } + arith_simplifier_plugin * get_arith_simp() const; + bv_simplifier_plugin * get_bv_simp() const; bool is_macro_head(expr * n, unsigned num_decls) const; bool is_left_simple_macro(expr * n, unsigned num_decls, app_ref & head, expr_ref & def) const; @@ -135,6 +137,7 @@ public: void mk_sub(expr * t1, expr * t2, expr_ref & r) const; void mk_add(expr * t1, expr * t2, expr_ref & r) const; void mk_add(unsigned num_args, expr * const * args, sort * s, expr_ref & r) const; + poly_simplifier_plugin * get_poly_simp_for(sort * s) const; }; #endif diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index 2342782c1..de849dbd7 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -29,10 +29,10 @@ protected: bool m_expand_power; bool m_mul2power; bool m_expand_tan; - + ast_manager & m() const { return m_util.get_manager(); } family_id get_fid() const { return m_util.get_family_id(); } - + bool is_numeral(expr * n) const { return m_util.is_numeral(n); } bool is_numeral(expr * n, numeral & r) const { return m_util.is_numeral(n, r); } bool is_zero(expr * n) const { return m_util.is_zero(n); } @@ -77,7 +77,7 @@ class arith_rewriter : public poly_rewriter { br_status mk_div_irrat_rat(expr * arg1, expr * arg2, expr_ref & result); br_status mk_div_rat_irrat(expr * arg1, expr * arg2, expr_ref & result); br_status mk_div_irrat_irrat(expr * arg1, expr * arg2, expr_ref & result); - + bool is_reduce_power_target(expr * arg, bool is_eq); expr * reduce_power(expr * arg, bool is_eq); br_status reduce_power(expr * arg1, expr * arg2, op_kind kind, expr_ref & result); @@ -154,16 +154,16 @@ public: if (mk_rem_core(arg1, arg2, result) == BR_FAILED) result = m().mk_app(get_fid(), OP_REM, arg1, arg2); } - + br_status mk_to_int_core(expr * arg, expr_ref & result); br_status mk_to_real_core(expr * arg, expr_ref & result); - void mk_to_int(expr * arg, expr_ref & result) { + void mk_to_int(expr * arg, expr_ref & result) { if (mk_to_int_core(arg, result) == BR_FAILED) - result = m().mk_app(get_fid(), OP_TO_INT, 1, &arg); + result = m().mk_app(get_fid(), OP_TO_INT, 1, &arg); } - void mk_to_real(expr * arg, expr_ref & result) { - if (mk_to_real_core(arg, result) == BR_FAILED) - result = m().mk_app(get_fid(), OP_TO_REAL, 1, &arg); + void mk_to_real(expr * arg, expr_ref & result) { + if (mk_to_real_core(arg, result) == BR_FAILED) + result = m().mk_app(get_fid(), OP_TO_REAL, 1, &arg); } br_status mk_is_int(expr * arg, expr_ref & result); @@ -178,8 +178,6 @@ public: br_status mk_sinh_core(expr * arg, expr_ref & result); br_status mk_cosh_core(expr * arg, expr_ref & result); br_status mk_tanh_core(expr * arg, expr_ref & result); - - arith_util & get_util() { return m_util; } }; #endif diff --git a/src/ast/rewriter/poly_rewriter.h b/src/ast/rewriter/poly_rewriter.h index 81c5ea132..5d38e4b10 100644 --- a/src/ast/rewriter/poly_rewriter.h +++ b/src/ast/rewriter/poly_rewriter.h @@ -159,63 +159,6 @@ public: expr* args[2] = { a1, a2 }; mk_sub(2, args, result); } - - bool is_times_minus_one(expr * n, expr * & r) const { - if (is_mul(n) && to_app(n)->get_num_args() == 2 && is_minus_one(to_app(n)->get_arg(0))) { - r = to_app(n)->get_arg(1); - return true; - } - return false; - } - - /** - \brief Return true if n is can be put into the form (+ v t) or (+ (- v) t) - \c inv = true will contain true if (- v) is found, and false otherwise. - */ - bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) { - if (!is_add(n) || is_ground(n)) - return false; - - ptr_buffer args; - v = 0; - expr * curr = to_app(n); - bool stop = false; - inv = false; - while (!stop) { - expr * arg; - expr * neg_arg; - if (is_add(curr)) { - arg = to_app(curr)->get_arg(0); - curr = to_app(curr)->get_arg(1); - } - else { - arg = curr; - stop = true; - } - if (is_ground(arg)) { - args.push_back(arg); - } - else if (is_var(arg)) { - if (v != 0) - return false; // already found variable - v = to_var(arg); - } - else if (is_times_minus_one(arg, neg_arg) && is_var(neg_arg)) { - if (v != 0) - return false; // already found variable - v = to_var(neg_arg); - inv = true; - } - else { - return false; // non ground term. - } - } - if (v == 0) - return false; // did not find variable - SASSERT(!args.empty()); - mk_add(args.size(), args.c_ptr(), t); - return true; - } }; diff --git a/src/smt/smt_model_finder.cpp b/src/smt/smt_model_finder.cpp index 0a80460f5..94a6a7267 100644 --- a/src/smt/smt_model_finder.cpp +++ b/src/smt/smt_model_finder.cpp @@ -1873,12 +1873,12 @@ namespace smt { fill the structure quantifier_info. */ class quantifier_analyzer { - model_finder & m_mf; + model_finder& m_mf; ast_manager & m_manager; macro_util m_mutil; array_util m_array_util; - arith_util & m_arith_util; - bv_util & m_bv_util; + arith_util m_arith_util; + bv_util m_bv_util; quantifier_info * m_info; @@ -1897,12 +1897,14 @@ namespace smt { m_info->insert_qinfo(qi); } + arith_simplifier_plugin * get_arith_simp() const { return m_mutil.get_arith_simp(); } + bv_simplifier_plugin * get_bv_simp() const { return m_mutil.get_bv_simp(); } + bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) const { - return m_mutil.get_arith_rw().is_var_plus_ground(n, inv, v, t) || - m_mutil.get_bv_rw().is_var_plus_ground(n, inv, v, t); + return get_arith_simp()->is_var_plus_ground(n, inv, v, t) || get_bv_simp()->is_var_plus_ground(n, inv, v, t); } - bool is_var_plus_ground(expr * n, var * & v, expr_ref & t) const { + bool is_var_plus_ground(expr * n, var * & v, expr_ref & t) { bool inv; TRACE("is_var_plus_ground", tout << mk_pp(n, m_manager) << "\n"; tout << "is_var_plus_ground: " << is_var_plus_ground(n, inv, v, t) << "\n"; @@ -1915,11 +1917,10 @@ namespace smt { } bool is_zero(expr * n) const { - if (m_bv_util.is_bv(n)) - return m_bv_util.is_zero(n); - else { - return m_arith_util.is_zero(n); - } + if (get_bv_simp()->is_bv(n)) + return get_bv_simp()->is_zero_safe(n); + else + return get_arith_simp()->is_zero_safe(n); } bool is_times_minus_one(expr * n, expr * & arg) const { @@ -1938,7 +1939,7 @@ namespace smt { return m_bv_util.is_bv_sle(n); } - expr * mk_one(sort * s) const { + expr * mk_one(sort * s) { return m_bv_util.is_bv_sort(s) ? m_bv_util.mk_numeral(rational(1), s) : m_arith_util.mk_numeral(rational(1), s); } @@ -1950,7 +1951,7 @@ namespace smt { m_mutil.mk_add(t1, t2, r); } - bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t, bool & inv) { + bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t, bool & inv) const { inv = false; // true if invert the sign TRACE("is_var_and_ground", tout << "is_var_and_ground: " << mk_ismt2_pp(lhs, m_manager) << " " << mk_ismt2_pp(rhs, m_manager) << "\n";); if (is_var(lhs) && is_ground(rhs)) { @@ -1985,12 +1986,12 @@ namespace smt { return false; } - bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t) { + bool is_var_and_ground(expr * lhs, expr * rhs, var * & v, expr_ref & t) const { bool inv; return is_var_and_ground(lhs, rhs, v, t, inv); } - bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) { + bool is_x_eq_t_atom(expr * n, var * & v, expr_ref & t) const { if (!is_app(n)) return false; if (m_manager.is_eq(n)) @@ -2381,10 +2382,10 @@ namespace smt { quantifier_analyzer(model_finder& mf, ast_manager & m, simplifier & s): m_mf(mf), m_manager(m), - m_mutil(m), + m_mutil(m, s), m_array_util(m), - m_arith_util(m_mutil.get_arith_util()), - m_bv_util(m_mutil.get_bv_util()), + m_arith_util(m), + m_bv_util(m), m_info(0) { } From 36dd2b653035532a253fbb85d507fac52418af3a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Aug 2017 15:01:54 +0100 Subject: [PATCH 190/488] Re-enabled macro-related options for the smt_context --- src/smt/params/preprocessor_params.cpp | 2 ++ src/smt/params/smt_params_helper.pyg | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/smt/params/preprocessor_params.cpp b/src/smt/params/preprocessor_params.cpp index 9267dbeba..679cd0f39 100644 --- a/src/smt/params/preprocessor_params.cpp +++ b/src/smt/params/preprocessor_params.cpp @@ -22,6 +22,8 @@ Revision History: void preprocessor_params::updt_local_params(params_ref const & _p) { smt_params_helper p(_p); m_macro_finder = p.macro_finder(); + m_quasi_macros = p.quasi_macros(); + m_restricted_quasi_macros = p.restricted_quasi_macros(); m_pull_nested_quantifiers = p.pull_nested_quantifiers(); m_refine_inj_axiom = p.refine_inj_axioms(); } diff --git a/src/smt/params/smt_params_helper.pyg b/src/smt/params/smt_params_helper.pyg index 5b5c7328c..d6ca8c9b2 100644 --- a/src/smt/params/smt_params_helper.pyg +++ b/src/smt/params/smt_params_helper.pyg @@ -7,6 +7,8 @@ def_module_params(module_name='smt', ('random_seed', UINT, 0, 'random seed for the smt solver'), ('relevancy', UINT, 2, 'relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant'), ('macro_finder', BOOL, False, 'try to find universally quantified formulas that can be viewed as macros'), + ('quasi_macros', BOOL, False, 'try to find universally quantified formulas that are quasi-macros'), + ('restricted_quasi_macros', BOOL, False, 'try to find universally quantified formulas that are restricted quasi-macros'), ('ematching', BOOL, True, 'E-Matching based quantifier instantiation'), ('phase_selection', UINT, 3, 'phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences'), ('restart_strategy', UINT, 1, '0 - geometric, 1 - inner-outer-geometric, 2 - luby, 3 - fixed, 4 - arithmetic'), From 3e0926fb822195f33e9b585b0aac93094b9a58b5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Aug 2017 15:23:25 +0100 Subject: [PATCH 191/488] Whitespace --- src/ast/macros/quasi_macros.cpp | 74 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/ast/macros/quasi_macros.cpp b/src/ast/macros/quasi_macros.cpp index b39adde03..97ab55bd4 100644 --- a/src/ast/macros/quasi_macros.cpp +++ b/src/ast/macros/quasi_macros.cpp @@ -31,7 +31,7 @@ quasi_macros::quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s) m_new_qsorts(m) { } -quasi_macros::~quasi_macros() { +quasi_macros::~quasi_macros() { } void quasi_macros::find_occurrences(expr * e) { @@ -41,7 +41,7 @@ void quasi_macros::find_occurrences(expr * e) { // we remember whether we have seen an expr once, or more than once; // when we see it the second time, we don't have to visit it another time, - // as we are only interested in finding unique function applications. + // as we are only interested in finding unique function applications. m_visited_once.reset(); m_visited_more.reset(); @@ -64,8 +64,8 @@ void quasi_macros::find_occurrences(expr * e) { if (is_non_ground_uninterp(cur)) { func_decl * f = to_app(cur)->get_decl(); m_occurrences.insert_if_not_there(f, 0); - occurrences_map::iterator it = m_occurrences.find_iterator(f); - it->m_value++; + occurrences_map::iterator it = m_occurrences.find_iterator(f); + it->m_value++; } j = to_app(cur)->get_num_args(); while (j) @@ -84,16 +84,16 @@ bool quasi_macros::is_unique(func_decl * f) const { return m_occurrences.find(f) == 1; } -struct var_dep_proc { +struct var_dep_proc { bit_vector m_bitset; public: var_dep_proc(quantifier * q) { m_bitset.resize(q->get_num_decls(), false); } void operator()(var * n) { m_bitset.set(n->get_idx(), true); } void operator()(quantifier * n) {} void operator()(app * n) {} - bool all_used(void) { + bool all_used(void) { for (unsigned i = 0; i < m_bitset.size() ; i++) - if (!m_bitset.get(i)) + if (!m_bitset.get(i)) return false; return true; } @@ -101,7 +101,7 @@ public: bool quasi_macros::fully_depends_on(app * a, quantifier * q) const { // CMW: This checks whether all variables in q are used _somewhere_ deep down in the children of a - + /* var_dep_proc proc(q); for_each_expr(proc, a); return proc.all_used(); */ @@ -116,14 +116,14 @@ bool quasi_macros::fully_depends_on(app * a, quantifier * q) const { } for (unsigned i = 0; i < bitset.size() ; i++) { - if (!bitset.get(i)) + if (!bitset.get(i)) return false; } return true; } -bool quasi_macros::depends_on(expr * e, func_decl * f) const { +bool quasi_macros::depends_on(expr * e, func_decl * f) const { ptr_vector todo; expr_mark visited; todo.push_back(e); @@ -133,12 +133,12 @@ bool quasi_macros::depends_on(expr * e, func_decl * f) const { if (visited.is_marked(cur)) continue; - + if (is_app(cur)) { app * a = to_app(cur); - if (a->get_decl() == f) + if (a->get_decl() == f) return true; - + unsigned j = a->get_num_args(); while (j>0) todo.push_back(a->get_arg(--j)); @@ -151,7 +151,7 @@ bool quasi_macros::depends_on(expr * e, func_decl * f) const { bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const { // Our definition of a quasi-macro: - // Forall X. f[X] = T[X], where f[X] is a term starting with symbol f, f is uninterpreted, + // Forall X. f[X] = T[X], where f[X] is a term starting with symbol f, f is uninterpreted, // f[X] contains all universally quantified variables, and f does not occur in T[X]. TRACE("quasi_macros", tout << "Checking for quasi macro: " << mk_pp(e, m_manager) << std::endl;); @@ -165,14 +165,14 @@ bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const { if (is_non_ground_uninterp(lhs) && is_unique(to_app(lhs)->get_decl()) && !depends_on(rhs, to_app(lhs)->get_decl()) && fully_depends_on(to_app(lhs), q)) { a = to_app(lhs); - t = rhs; + t = rhs; return true; } else if (is_non_ground_uninterp(rhs) && is_unique(to_app(rhs)->get_decl()) && - !depends_on(lhs, to_app(rhs)->get_decl()) && fully_depends_on(to_app(rhs), q)) { + !depends_on(lhs, to_app(rhs)->get_decl()) && fully_depends_on(to_app(rhs), q)) { a = to_app(rhs); - t = lhs; + t = lhs; return true; - } + } } else if (m_manager.is_not(qe) && is_non_ground_uninterp(to_app(qe)->get_arg(0)) && is_unique(to_app(to_app(qe)->get_arg(0))->get_decl())) { // this is like f(...) = false a = to_app(to_app(qe)->get_arg(0)); @@ -189,7 +189,7 @@ bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const { } void quasi_macros::quasi_macro_to_macro(quantifier * q, app * a, expr * t, quantifier_ref & macro) { - m_new_var_names.reset(); + m_new_var_names.reset(); m_new_vars.reset(); m_new_qsorts.reset(); m_new_eqs.reset(); @@ -197,19 +197,19 @@ void quasi_macros::quasi_macro_to_macro(quantifier * q, app * a, expr * t, quant func_decl * f = a->get_decl(); // CMW: we rely on the fact that all variables in q appear at least once as - // a direct argument of `a'. + // a direct argument of `a'. bit_vector v_seen; - v_seen.resize(q->get_num_decls(), false); + v_seen.resize(q->get_num_decls(), false); for (unsigned i = 0 ; i < a->get_num_args() ; i++) { - if (!is_var(a->get_arg(i)) || + if (!is_var(a->get_arg(i)) || v_seen.get(to_var(a->get_arg(i))->get_idx())) { unsigned inx = m_new_var_names.size(); m_new_name.str(""); m_new_name << "X" << inx; - m_new_var_names.push_back(symbol(m_new_name.str().c_str())); + m_new_var_names.push_back(symbol(m_new_name.str().c_str())); m_new_qsorts.push_back(f->get_domain()[i]); - + m_new_vars.push_back(m_manager.mk_var(inx + q->get_num_decls(), f->get_domain()[i])); m_new_eqs.push_back(m_manager.mk_eq(m_new_vars.back(), a->get_arg(i))); } else { @@ -228,13 +228,13 @@ void quasi_macros::quasi_macro_to_macro(quantifier * q, app * a, expr * t, quant new_var_names_rev.push_back(m_new_var_names.get(i)); new_qsorts_rev.push_back(m_new_qsorts.get(i)); } - + // We want to keep all the old variables [already reversed] for (unsigned i = 0 ; i < q->get_num_decls() ; i++) { new_var_names_rev.push_back(q->get_decl_name(i)); new_qsorts_rev.push_back(q->get_decl_sort(i)); } - + // Macro := Forall m_new_vars . appl = ITE( m_new_eqs, t, f_else) app_ref appl(m_manager); @@ -251,28 +251,28 @@ void quasi_macros::quasi_macro_to_macro(quantifier * q, app * a, expr * t, quant eq = m_manager.mk_eq(appl, ite); - macro = m_manager.mk_quantifier(true, new_var_names_rev.size(), + macro = m_manager.mk_quantifier(true, new_var_names_rev.size(), new_qsorts_rev.c_ptr(), new_var_names_rev.c_ptr(), eq); } bool quasi_macros::find_macros(unsigned n, expr * const * exprs) { TRACE("quasi_macros", tout << "Finding quasi-macros in: " << std::endl; - for (unsigned i = 0 ; i < n ; i++) + for (unsigned i = 0 ; i < n ; i++) tout << i << ": " << mk_pp(exprs[i], m_manager) << std::endl; ); bool res = false; m_occurrences.reset(); - - // Find out how many non-ground appearences for each uninterpreted function there are + + // Find out how many non-ground appearences for each uninterpreted function there are for ( unsigned i = 0 ; i < n ; i++ ) find_occurrences(exprs[i]); TRACE("quasi_macros", tout << "Occurrences: " << std::endl; - for (occurrences_map::iterator it = m_occurrences.begin(); - it != m_occurrences.end(); + for (occurrences_map::iterator it = m_occurrences.begin(); + it != m_occurrences.end(); it++) tout << it->m_key->get_name() << ": " << it->m_value << std::endl; ); - + // Find all macros for ( unsigned i = 0 ; i < n ; i++ ) { app_ref a(m_manager); @@ -293,7 +293,7 @@ bool quasi_macros::find_macros(unsigned n, expr * const * exprs) { return res; } -void quasi_macros::apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { +void quasi_macros::apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { for ( unsigned i = 0 ; i < n ; i++ ) { expr_ref r(m_manager), rs(m_manager); proof_ref pr(m_manager), ps(m_manager); @@ -301,7 +301,7 @@ void quasi_macros::apply_macros(unsigned n, expr * const * exprs, proof * const m_macro_manager.expand_macros(exprs[i], p, r, pr); m_simplifier(r, rs, ps); new_exprs.push_back(rs); - new_prs.push_back(ps); + new_prs.push_back(ps); } } @@ -313,9 +313,9 @@ bool quasi_macros::operator()(unsigned n, expr * const * exprs, proof * const * // just copy them over for ( unsigned i = 0 ; i < n ; i++ ) { new_exprs.push_back(exprs[i]); - if (m_manager.proofs_enabled()) + if (m_manager.proofs_enabled()) new_prs.push_back(prs[i]); } return false; - } + } } From 31496b662548844350d1468d5a7e51502131589b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Aug 2017 15:29:29 +0100 Subject: [PATCH 192/488] Whitespace --- src/ast/macros/quasi_macros.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ast/macros/quasi_macros.h b/src/ast/macros/quasi_macros.h index 3a9b6074e..849fe8bce 100644 --- a/src/ast/macros/quasi_macros.h +++ b/src/ast/macros/quasi_macros.h @@ -34,22 +34,22 @@ class quasi_macros { macro_manager & m_macro_manager; simplifier & m_simplifier; occurrences_map m_occurrences; - ptr_vector m_todo; + ptr_vector m_todo; vector m_new_var_names; expr_ref_vector m_new_vars; expr_ref_vector m_new_eqs; sort_ref_vector m_new_qsorts; - std::stringstream m_new_name; + std::stringstream m_new_name; expr_mark m_visited_once; expr_mark m_visited_more; - + bool is_unique(func_decl * f) const; bool is_non_ground_uninterp(expr const * e) const; - bool fully_depends_on(app * a, quantifier * q) const; + bool fully_depends_on(app * a, quantifier * q) const; bool depends_on(expr * e, func_decl * f) const; - bool is_quasi_macro(expr * e, app_ref & a, expr_ref &v) const; + bool is_quasi_macro(expr * e, app_ref & a, expr_ref &v) const; void quasi_macro_to_macro(quantifier * q, app * a, expr * t, quantifier_ref & macro); void find_occurrences(expr * e); @@ -59,11 +59,11 @@ class quasi_macros { public: quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s); ~quasi_macros(); - + /** \brief Find pure function macros and apply them. */ - bool operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + bool operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); }; #endif From b8a81bcb09e59890ac8ebc2a9f253cc610c97129 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Aug 2017 20:21:57 +0100 Subject: [PATCH 193/488] Added unsat core support to the macro-finder. --- src/ast/macros/macro_finder.cpp | 59 +++++++++++++-------- src/ast/macros/macro_finder.h | 17 ++---- src/ast/macros/macro_manager.cpp | 26 +++++++-- src/ast/macros/macro_manager.h | 7 ++- src/ast/macros/quasi_macros.cpp | 29 +++++----- src/ast/macros/quasi_macros.h | 4 +- src/smt/asserted_formulas.cpp | 70 ++++++++++++++----------- src/smt/asserted_formulas.h | 14 +++-- src/smt/smt_context.h | 4 +- src/tactic/ufbv/macro_finder_tactic.cpp | 12 +++-- src/tactic/ufbv/quasi_macros_tactic.cpp | 52 ++++++++++-------- 11 files changed, 169 insertions(+), 125 deletions(-) diff --git a/src/ast/macros/macro_finder.cpp b/src/ast/macros/macro_finder.cpp index 285c0e5fb..90e64fb0a 100644 --- a/src/ast/macros/macro_finder.cpp +++ b/src/ast/macros/macro_finder.cpp @@ -32,27 +32,27 @@ bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) { } /** - \brief Detect macros of the form + \brief Detect macros of the form 1- (forall (X) (= (+ (f X) (R X)) c)) 2- (forall (X) (<= (+ (f X) (R X)) c)) 3- (forall (X) (>= (+ (f X) (R X)) c)) The second and third cases are first converted into (forall (X) (= (f X) (+ c (* -1 (R x)) (k X)))) - and + and (forall (X) (<= (k X) 0)) when case 2 (forall (X) (>= (k X) 0)) when case 3 For case 2 & 3, the new quantifiers are stored in new_exprs and new_prs. */ -bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { +bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_dependency * dep, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps) { if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) return false; arith_simplifier_plugin * as = get_arith_simp(); arith_util & autil = as->get_arith_util(); expr * body = to_quantifier(n)->get_expr(); unsigned num_decls = to_quantifier(n)->get_num_decls(); - + if (!autil.is_le(body) && !autil.is_ge(body) && !m_manager.is_eq(body)) return false; if (!as->is_add(to_app(body)->get_arg(0))) @@ -63,7 +63,7 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex if (!m_util.is_arith_macro(body, num_decls, head, def, inv)) return false; app_ref new_body(m_manager); - + if (!inv || m_manager.is_eq(body)) new_body = m_manager.mk_app(to_app(body)->get_decl(), head, def); else if (as->is_le(body)) @@ -71,18 +71,19 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex else new_body = autil.mk_le(head, def); - quantifier_ref new_q(m_manager); + quantifier_ref new_q(m_manager); new_q = m_manager.update_quantifier(to_quantifier(n), new_body); proof * new_pr = 0; if (m_manager.proofs_enabled()) { proof * rw = m_manager.mk_rewrite(n, new_q); new_pr = m_manager.mk_modus_ponens(pr, rw); } + expr_dependency * new_dep = dep; if (m_manager.is_eq(body)) { - return m_macro_manager.insert(head->get_decl(), new_q, new_pr); + return m_macro_manager.insert(head->get_decl(), new_q, new_pr, new_dep); } // is ge or le - // + // TRACE("macro_finder", tout << "is_arith_macro: is_ge or is_le\n";); func_decl * f = head->get_decl(); func_decl * k = m_manager.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); @@ -111,6 +112,10 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex new_prs.push_back(pr1); new_prs.push_back(pr2); } + if (dep) { + new_deps.push_back(new_dep); + new_deps.push_back(new_dep); + } return true; } @@ -118,7 +123,7 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex n is of the form: (forall (X) (iff (= (f X) t) def[X])) Convert it into: - + (forall (X) (= (f X) (ite def[X] t (k X)))) (forall (X) (not (= (k X) t))) @@ -126,13 +131,13 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex The new quantifiers and proofs are stored in new_exprs and new_prs */ -static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, expr * def, quantifier * q, proof * pr, - expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { +static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, expr * def, quantifier * q, proof * pr, expr_dependency * dep, + expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps ) { func_decl * f = head->get_decl(); func_decl * k = m.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); app * k_app = m.mk_app(k, head->get_num_args(), head->get_args()); app * ite = m.mk_ite(def, t, k_app); - app * body_1 = m.mk_eq(head, ite); + app * body_1 = m.mk_eq(head, ite); app * body_2 = m.mk_not(m.mk_eq(k_app, t)); quantifier * q1 = m.update_quantifier(q, body_1); expr * pats[1] = { m.mk_pattern(k_app) }; @@ -153,6 +158,8 @@ static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, e new_prs.push_back(pr1); new_prs.push_back(pr2); } + new_deps.push_back(dep); + new_deps.push_back(dep); } macro_finder::macro_finder(ast_manager & m, macro_manager & mm): @@ -164,57 +171,67 @@ macro_finder::macro_finder(ast_manager & m, macro_manager & mm): macro_finder::~macro_finder() { } -bool macro_finder::expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { +bool macro_finder::expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps) { TRACE("macro_finder", tout << "starting expand_macros:\n"; m_macro_manager.display(tout);); bool found_new_macro = false; for (unsigned i = 0; i < num; i++) { expr * n = exprs[i]; proof * pr = m_manager.proofs_enabled() ? prs[i] : 0; + expr_dependency * depi = deps != 0 ? deps[i] : 0; expr_ref new_n(m_manager), def(m_manager); proof_ref new_pr(m_manager); - m_macro_manager.expand_macros(n, pr, new_n, new_pr); + expr_dependency_ref new_dep(m_manager); + m_macro_manager.expand_macros(n, pr, depi, new_n, new_pr, new_dep); app_ref head(m_manager), t(m_manager); - if (is_macro(new_n, head, def) && m_macro_manager.insert(head->get_decl(), to_quantifier(new_n.get()), new_pr)) { + if (is_macro(new_n, head, def) && m_macro_manager.insert(head->get_decl(), to_quantifier(new_n.get()), new_pr, new_dep)) { TRACE("macro_finder_found", tout << "found new macro: " << head->get_decl()->get_name() << "\n" << new_n << "\n";); found_new_macro = true; } - else if (is_arith_macro(new_n, new_pr, new_exprs, new_prs)) { + else if (is_arith_macro(new_n, new_pr, new_dep, new_exprs, new_prs, new_deps)) { TRACE("macro_finder_found", tout << "found new arith macro:\n" << new_n << "\n";); found_new_macro = true; } - else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) { + else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) { TRACE("macro_finder_found", tout << "found new pseudo macro:\n" << head << "\n" << t << "\n" << def << "\n";); - pseudo_predicate_macro2macro(m_manager, head, t, def, to_quantifier(new_n), new_pr, new_exprs, new_prs); + pseudo_predicate_macro2macro(m_manager, head, t, def, to_quantifier(new_n), new_pr, new_dep, new_exprs, new_prs, new_deps); found_new_macro = true; } else { new_exprs.push_back(new_n); if (m_manager.proofs_enabled()) new_prs.push_back(new_pr); + if (deps != 0) + new_deps.push_back(new_dep); } } return found_new_macro; } -void macro_finder::operator()(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { +void macro_finder::operator()(unsigned num, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps) { TRACE("macro_finder", tout << "processing macros...\n";); expr_ref_vector _new_exprs(m_manager); proof_ref_vector _new_prs(m_manager); - if (expand_macros(num, exprs, prs, _new_exprs, _new_prs)) { + expr_dependency_ref_vector _new_deps(m_manager); + if (expand_macros(num, exprs, prs, deps, _new_exprs, _new_prs, _new_deps)) { while (true) { expr_ref_vector old_exprs(m_manager); proof_ref_vector old_prs(m_manager); + expr_dependency_ref_vector old_deps(m_manager); _new_exprs.swap(old_exprs); _new_prs.swap(old_prs); + _new_deps.swap(old_deps); SASSERT(_new_exprs.empty()); SASSERT(_new_prs.empty()); - if (!expand_macros(old_exprs.size(), old_exprs.c_ptr(), old_prs.c_ptr(), _new_exprs, _new_prs)) + SASSERT(_new_deps.empty()); + if (!expand_macros(old_exprs.size(), old_exprs.c_ptr(), old_prs.c_ptr(), old_deps.c_ptr(), + _new_exprs, _new_prs, _new_deps)) break; } } new_exprs.append(_new_exprs); new_prs.append(_new_prs); + new_deps.append(_new_deps); } diff --git a/src/ast/macros/macro_finder.h b/src/ast/macros/macro_finder.h index 7f1b27f0e..996d613e8 100644 --- a/src/ast/macros/macro_finder.h +++ b/src/ast/macros/macro_finder.h @@ -23,32 +23,23 @@ Revision History: #include "ast/simplifier/arith_simplifier_plugin.h" -bool is_macro_head(expr * n, unsigned num_decls); -bool is_simple_macro(ast_manager & m, expr * n, unsigned num_decls, obj_hashtable const * forbidden_set, app * & head, expr * & def); -inline bool is_simple_macro(ast_manager & m, expr * n, unsigned num_decls, app * & head, expr * & def) { - return is_simple_macro(m, n, num_decls, 0, head, def); -} - /** \brief Macro finder is responsible for finding universally quantified sub-formulas that can be used as macros. */ class macro_finder { - ast_manager & m_manager; + ast_manager & m_manager; macro_manager & m_macro_manager; macro_util & m_util; arith_simplifier_plugin * get_arith_simp() { return m_util.get_arith_simp(); } - bool expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); - bool is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); - + bool expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps); + bool is_arith_macro(expr * n, proof * pr, expr_dependency * dep, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps); bool is_macro(expr * n, app_ref & head, expr_ref & def); - bool is_pseudo_head(expr * n, unsigned num_decls, app * & head, app * & t); - bool is_pseudo_predicate_macro(expr * n, app * & head, app * & t, expr * & def); public: macro_finder(ast_manager & m, macro_manager & mm); ~macro_finder(); - void operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + void operator()(unsigned num, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps); }; #endif /* MACRO_FINDER_H_ */ diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index bd330a2de..0f16545d4 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -25,13 +25,14 @@ Revision History: #include "ast/ast_pp.h" #include "ast/recurse_expr_def.h" -macro_manager::macro_manager(ast_manager & m, simplifier & s): +macro_manager::macro_manager(ast_manager & m, simplifier & s) : m_manager(m), m_simplifier(s), m_util(m, s), m_decls(m), m_macros(m), m_macro_prs(m), + m_macro_deps(m), m_forbidden(m), m_deps(m) { m_util.set_forbidden_set(&m_forbidden_set); @@ -60,13 +61,16 @@ void macro_manager::restore_decls(unsigned old_sz) { for (unsigned i = old_sz; i < sz; i++) { m_decl2macro.erase(m_decls.get(i)); m_deps.erase(m_decls.get(i)); - if (m_manager.proofs_enabled()) + if (m_manager.proofs_enabled()) { m_decl2macro_pr.erase(m_decls.get(i)); + m_decl2macro_dep.erase(m_decls.get(i)); + } } m_decls.shrink(old_sz); m_macros.shrink(old_sz); if (m_manager.proofs_enabled()) m_macro_prs.shrink(old_sz); + m_macro_deps.shrink(old_sz); } void macro_manager::restore_forbidden(unsigned old_sz) { @@ -79,16 +83,18 @@ void macro_manager::restore_forbidden(unsigned old_sz) { void macro_manager::reset() { m_decl2macro.reset(); m_decl2macro_pr.reset(); + m_decl2macro_dep.reset(); m_decls.reset(); m_macros.reset(); m_macro_prs.reset(); + m_macro_deps.reset(); m_scopes.reset(); m_forbidden_set.reset(); m_forbidden.reset(); m_deps.reset(); } -bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr) { +bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr, expr_dependency * dep) { TRACE("macro_insert", tout << "trying to create macro: " << f->get_name() << "\n" << mk_pp(m, m_manager) << "\n";); // if we already have a macro for f then return false; @@ -115,6 +121,8 @@ bool macro_manager::insert(func_decl * f, quantifier * m, proof * pr) { m_macro_prs.push_back(pr); m_decl2macro_pr.insert(f, pr); } + m_macro_deps.push_back(dep); + m_decl2macro_dep.insert(f, dep); TRACE("macro_insert", tout << "A macro was successfully created for: " << f->get_name() << "\n";); @@ -195,7 +203,8 @@ func_decl * macro_manager::get_macro_interpretation(unsigned i, expr_ref & inter macro_manager::macro_expander::macro_expander(ast_manager & m, macro_manager & mm, simplifier & s): simplifier(m), - m_macro_manager(mm) { + m_macro_manager(mm), + m_used_macro_dependencies(m) { // REMARK: theory simplifier should not be used by macro_expander... // is_arith_macro rewrites a quantifer such as: // forall (x Int) (= (+ x (+ (f x) 1)) 2) @@ -286,34 +295,41 @@ bool macro_manager::macro_expander::get_subst(expr * _n, expr_ref & r, proof_ref } else { p = 0; + expr_dependency * ed = m_macro_manager.m_decl2macro_dep.find(d); + m_used_macro_dependencies = m.mk_join(m_used_macro_dependencies, ed); } return true; } return false; } -void macro_manager::expand_macros(expr * n, proof * pr, expr_ref & r, proof_ref & new_pr) { +void macro_manager::expand_macros(expr * n, proof * pr, expr_dependency * dep, expr_ref & r, proof_ref & new_pr, expr_dependency_ref & new_dep) { if (has_macros()) { // Expand macros with "real" proof production support (NO rewrite*) expr_ref old_n(m_manager); proof_ref old_pr(m_manager); + expr_dependency_ref old_dep(m_manager); old_n = n; old_pr = pr; + old_dep = dep; for (;;) { macro_expander proc(m_manager, *this, m_simplifier); proof_ref n_eq_r_pr(m_manager); TRACE("macro_manager_bug", tout << "expand_macros:\n" << mk_pp(n, m_manager) << "\n";); proc(old_n, r, n_eq_r_pr); new_pr = m_manager.mk_modus_ponens(old_pr, n_eq_r_pr); + new_dep = m_manager.mk_join(old_dep, proc.m_used_macro_dependencies); if (r.get() == old_n.get()) return; old_n = r; old_pr = new_pr; + old_dep = new_dep; } } else { r = n; new_pr = pr; + new_dep = dep; } } diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index b72c1e6bf..111027f73 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -42,9 +42,11 @@ class macro_manager { obj_map m_decl2macro; // func-decl -> quantifier obj_map m_decl2macro_pr; // func-decl -> quantifier_proof + obj_map m_decl2macro_dep; // func-decl -> unsat core dependency func_decl_ref_vector m_decls; quantifier_ref_vector m_macros; proof_ref_vector m_macro_prs; + expr_dependency_ref_vector m_macro_deps; obj_hashtable m_forbidden_set; func_decl_ref_vector m_forbidden; struct scope { @@ -64,6 +66,7 @@ class macro_manager { virtual bool get_subst(expr * n, expr_ref & r, proof_ref & p); virtual void reduce1_quantifier(quantifier * q); public: + expr_dependency_ref m_used_macro_dependencies; macro_expander(ast_manager & m, macro_manager & mm, simplifier & s); ~macro_expander(); }; @@ -74,7 +77,7 @@ public: ~macro_manager(); ast_manager & get_manager() const { return m_manager; } macro_util & get_util() { return m_util; } - bool insert(func_decl * f, quantifier * m, proof * pr); + bool insert(func_decl * f, quantifier * m, proof * pr, expr_dependency * dep); bool has_macros() const { return !m_macros.empty(); } void push_scope(); void pop_scope(unsigned num_scopes); @@ -90,7 +93,7 @@ public: func_decl * get_macro_interpretation(unsigned i, expr_ref & interp) const; quantifier * get_macro_quantifier(func_decl * f) const { quantifier * q = 0; m_decl2macro.find(f, q); return q; } void get_head_def(quantifier * q, func_decl * d, app * & head, expr * & def) const; - void expand_macros(expr * n, proof * pr, expr_ref & r, proof_ref & new_pr); + void expand_macros(expr * n, proof * pr, expr_dependency * dep, expr_ref & r, proof_ref & new_pr, expr_dependency_ref & new_dep); }; diff --git a/src/ast/macros/quasi_macros.cpp b/src/ast/macros/quasi_macros.cpp index 97ab55bd4..6206d0311 100644 --- a/src/ast/macros/quasi_macros.cpp +++ b/src/ast/macros/quasi_macros.cpp @@ -264,17 +264,16 @@ bool quasi_macros::find_macros(unsigned n, expr * const * exprs) { // Find out how many non-ground appearences for each uninterpreted function there are - for ( unsigned i = 0 ; i < n ; i++ ) + for (unsigned i = 0 ; i < n ; i++) find_occurrences(exprs[i]); - TRACE("quasi_macros", tout << "Occurrences: " << std::endl; - for (occurrences_map::iterator it = m_occurrences.begin(); - it != m_occurrences.end(); - it++) - tout << it->m_key->get_name() << ": " << it->m_value << std::endl; ); + TRACE("quasi_macros", + tout << "Occurrences: " << std::endl; + for (auto & kd : m_occurrences) + tout << kd.m_key->get_name() << ": " << kd.m_value << std::endl; ); // Find all macros - for ( unsigned i = 0 ; i < n ; i++ ) { + for (unsigned i = 0 ; i < n ; i++) { app_ref a(m_manager); expr_ref t(m_manager); if (is_quasi_macro(exprs[i], a, t)) { @@ -285,7 +284,8 @@ bool quasi_macros::find_macros(unsigned n, expr * const * exprs) { proof * pr = 0; if (m_manager.proofs_enabled()) pr = m_manager.mk_def_axiom(macro); - if (m_macro_manager.insert(a->get_decl(), macro, pr)) + expr_dependency * dep = 0; + if (m_macro_manager.insert(a->get_decl(), macro, pr, dep)) res = true; } } @@ -293,21 +293,24 @@ bool quasi_macros::find_macros(unsigned n, expr * const * exprs) { return res; } -void quasi_macros::apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { - for ( unsigned i = 0 ; i < n ; i++ ) { +void quasi_macros::apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps) { + for (unsigned i = 0 ; i < n ; i++) { expr_ref r(m_manager), rs(m_manager); proof_ref pr(m_manager), ps(m_manager); proof * p = m_manager.proofs_enabled() ? prs[i] : 0; - m_macro_manager.expand_macros(exprs[i], p, r, pr); + expr_dependency * dep = deps[i]; + expr_dependency_ref new_dep(m_manager); + m_macro_manager.expand_macros(exprs[i], p, dep, r, pr, new_dep); m_simplifier(r, rs, ps); new_exprs.push_back(rs); new_prs.push_back(ps); + new_deps.push_back(new_dep); } } -bool quasi_macros::operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { +bool quasi_macros::operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps) { if (find_macros(n, exprs)) { - apply_macros(n, exprs, prs, new_exprs, new_prs); + apply_macros(n, exprs, prs, deps, new_exprs, new_prs, new_deps); return true; } else { // just copy them over diff --git a/src/ast/macros/quasi_macros.h b/src/ast/macros/quasi_macros.h index 849fe8bce..50fa04af4 100644 --- a/src/ast/macros/quasi_macros.h +++ b/src/ast/macros/quasi_macros.h @@ -54,7 +54,7 @@ class quasi_macros { void find_occurrences(expr * e); bool find_macros(unsigned n, expr * const * exprs); - void apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + void apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps); public: quasi_macros(ast_manager & m, macro_manager & mm, simplifier & s); @@ -63,7 +63,7 @@ public: /** \brief Find pure function macros and apply them. */ - bool operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + bool operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_dependency * const * deps, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps); }; #endif diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index cbbb9a6bc..dabae9fbd 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -75,7 +75,7 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): void asserted_formulas::setup() { switch (m_params.m_lift_ite) { case LI_FULL: - m_params.m_ng_lift_ite = LI_NONE; + m_params.m_ng_lift_ite = LI_NONE; break; case LI_CONSERVATIVE: if (m_params.m_ng_lift_ite == LI_CONSERVATIVE) @@ -84,7 +84,7 @@ void asserted_formulas::setup() { default: break; } - + if (m_params.m_relevancy_lvl == 0) m_params.m_relevancy_lemma = false; } @@ -97,7 +97,7 @@ void asserted_formulas::setup_simplifier_plugins(simplifier & s, basic_simplifie s.register_plugin(alloc(array_simplifier_plugin, m, *bsimp, s, m_params)); bvsimp = alloc(bv_simplifier_plugin, m, *bsimp, m_params); s.register_plugin(bvsimp); - s.register_plugin(alloc(datatype_simplifier_plugin, m, *bsimp)); + s.register_plugin(alloc(datatype_simplifier_plugin, m, *bsimp)); s.register_plugin(alloc(fpa_simplifier_plugin, m, *bsimp)); s.register_plugin(alloc(seq_simplifier_plugin, m, *bsimp)); } @@ -140,7 +140,7 @@ void asserted_formulas::set_eliminate_and(bool flag) { void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { - if (inconsistent()) + if (inconsistent()) return; if (!m_params.m_preprocess) { push_assertion(e, _in_pr, m_asserted_formulas, m_asserted_formula_prs); @@ -175,7 +175,7 @@ void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { } void asserted_formulas::assert_expr(expr * e) { - if (inconsistent()) + if (inconsistent()) return; assert_expr(e, m.mk_asserted(e)); } @@ -197,7 +197,7 @@ void asserted_formulas::push_scope() { m_bv_sharing.push_scope(); commit(); } - + void asserted_formulas::pop_scope(unsigned num_scopes) { TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << "\n"; display(tout);); m_bv_sharing.pop_scope(num_scopes); @@ -228,15 +228,15 @@ void asserted_formulas::reset() { #ifdef Z3DEBUG bool asserted_formulas::check_well_sorted() const { - for (unsigned i = 0; i < m_asserted_formulas.size(); i++) { - if (!is_well_sorted(m, m_asserted_formulas.get(i))) return false; + for (unsigned i = 0; i < m_asserted_formulas.size(); i++) { + if (!is_well_sorted(m, m_asserted_formulas.get(i))) return false; } return true; } #endif void asserted_formulas::reduce() { - if (inconsistent()) + if (inconsistent()) return; if (canceled()) { return; @@ -253,7 +253,7 @@ void asserted_formulas::reduce() { #define INVOKE(COND, FUNC) if (COND) { FUNC; IF_VERBOSE(10000, verbose_stream() << "total size: " << get_total_size() << "\n";); } TRACE("reduce_step_ll", ast_mark visited; display_ll(tout, visited);); TRACE("reduce_step", display(tout << #FUNC << " ");); CASSERT("well_sorted",check_well_sorted()); if (inconsistent() || canceled()) { TRACE("after_reduce", display(tout);); TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); return; } - + set_eliminate_and(false); // do not eliminate and before nnf. INVOKE(m_params.m_propagate_booleans, propagate_booleans()); INVOKE(m_params.m_propagate_values, propagate_values()); @@ -266,18 +266,18 @@ void asserted_formulas::reduce() { INVOKE(m_params.m_lift_ite != LI_NONE, lift_ite()); INVOKE(m_params.m_eliminate_term_ite && m_params.m_lift_ite != LI_FULL, eliminate_term_ite()); INVOKE(m_params.m_refine_inj_axiom && has_quantifiers(), refine_inj_axiom()); - INVOKE(m_params.m_distribute_forall && has_quantifiers(), apply_distribute_forall()); - TRACE("qbv_bug", tout << "after distribute_forall:\n"; display(tout);); + INVOKE(m_params.m_distribute_forall && has_quantifiers(), apply_distribute_forall()); + TRACE("qbv_bug", tout << "after distribute_forall:\n"; display(tout);); INVOKE(m_params.m_macro_finder && has_quantifiers(), find_macros()); - INVOKE(m_params.m_quasi_macros && has_quantifiers(), apply_quasi_macros()); + INVOKE(m_params.m_quasi_macros && has_quantifiers(), apply_quasi_macros()); INVOKE(m_params.m_simplify_bit2int, apply_bit2int()); INVOKE(m_params.m_eliminate_bounds && has_quantifiers(), cheap_quant_fourier_motzkin()); INVOKE(m_params.m_ematching && has_quantifiers(), infer_patterns()); INVOKE(m_params.m_max_bv_sharing && has_bv(), max_bv_sharing()); INVOKE(m_params.m_bb_quantifiers, elim_bvs_from_quantifiers()); - // temporary HACK: make sure that arith & bv are list-assoc + // temporary HACK: make sure that arith & bv are list-assoc // this may destroy some simplification steps such as max_bv_sharing - reduce_asserted_formulas(); + reduce_asserted_formulas(); CASSERT("well_sorted",check_well_sorted()); @@ -291,7 +291,7 @@ void asserted_formulas::reduce() { void asserted_formulas::eliminate_and() { IF_IVERBOSE(10, verbose_stream() << "(smt.eliminating-and)\n";); set_eliminate_and(true); - reduce_asserted_formulas(); + reduce_asserted_formulas(); TRACE("after_elim_and", display(tout);); } @@ -331,10 +331,10 @@ void asserted_formulas::display(std::ostream & out) const { void asserted_formulas::display_ll(std::ostream & out, ast_mark & pp_visited) const { if (!m_asserted_formulas.empty()) { unsigned sz = m_asserted_formulas.size(); - for (unsigned i = 0; i < sz; i++) + for (unsigned i = 0; i < sz; i++) ast_def_ll_pp(out, m, m_asserted_formulas.get(i), pp_visited, true, false); out << "asserted formulas:\n"; - for (unsigned i = 0; i < sz; i++) + for (unsigned i = 0; i < sz; i++) out << "#" << m_asserted_formulas[i]->get_id() << " "; out << "\n"; } @@ -387,8 +387,12 @@ void asserted_formulas::find_macros_core() { expr_ref_vector new_exprs(m); proof_ref_vector new_prs(m); unsigned sz = m_asserted_formulas.size(); - m_macro_finder->operator()(sz - m_asserted_qhead, m_asserted_formulas.c_ptr() + m_asserted_qhead, - m_asserted_formula_prs.c_ptr() + m_asserted_qhead, new_exprs, new_prs); + expr_dependency_ref_vector new_deps(m); + m_macro_finder->operator()(sz - m_asserted_qhead, + m_asserted_formulas.c_ptr() + m_asserted_qhead, + m_asserted_formula_prs.c_ptr() + m_asserted_qhead, + 0, // 0 == No dependency tracking + new_exprs, new_prs, new_deps); swap_asserted_formulas(new_exprs, new_prs); reduce_and_solve(); } @@ -409,12 +413,14 @@ void asserted_formulas::apply_quasi_macros() { IF_IVERBOSE(10, verbose_stream() << "(smt.find-quasi-macros)\n";); TRACE("before_quasi_macros", display(tout);); expr_ref_vector new_exprs(m); - proof_ref_vector new_prs(m); - quasi_macros proc(m, m_macro_manager, m_simplifier); - while (proc(m_asserted_formulas.size() - m_asserted_qhead, - m_asserted_formulas.c_ptr() + m_asserted_qhead, + proof_ref_vector new_prs(m); + quasi_macros proc(m, m_macro_manager, m_simplifier); + expr_dependency_ref_vector new_deps(m); + while (proc(m_asserted_formulas.size() - m_asserted_qhead, + m_asserted_formulas.c_ptr() + m_asserted_qhead, m_asserted_formula_prs.c_ptr() + m_asserted_qhead, - new_exprs, new_prs)) { + 0, // 0 == No dependency tracking + new_exprs, new_prs, new_deps)) { swap_asserted_formulas(new_exprs, new_prs); new_exprs.reset(); new_prs.reset(); @@ -430,7 +436,7 @@ void asserted_formulas::nnf_cnf() { proof_ref_vector new_prs(m); expr_ref_vector push_todo(m); proof_ref_vector push_todo_prs(m); - + unsigned i = m_asserted_qhead; unsigned sz = m_asserted_formulas.size(); TRACE("nnf_bug", tout << "i: " << i << " sz: " << sz << "\n";); @@ -460,8 +466,8 @@ void asserted_formulas::nnf_cnf() { CASSERT("well_sorted",is_well_sorted(m, r1)); if (canceled()) { return; - } - + } + if (m.proofs_enabled()) pr = m.mk_modus_ponens(push_todo_prs.get(k), pr1); else @@ -598,7 +604,7 @@ void asserted_formulas::propagate_values() { // C is a set which contains formulas of the form // { x = n }, where x is a variable and n a numeral. // R contains the rest. - // + // // - new_exprs1 is the set C // - new_exprs2 is the set R // @@ -663,7 +669,7 @@ void asserted_formulas::propagate_values() { // x->n will be removed from m_cache. If we don't do that, the next transformation // may simplify constraints in C using these entries, and the variables x in C // will be (silently) eliminated, and models produced by Z3 will not contain them. - flush_cache(); + flush_cache(); } TRACE("propagate_values", tout << "after:\n"; display(tout);); } @@ -786,7 +792,7 @@ void asserted_formulas::refine_inj_axiom() { TRACE("inj_axiom", tout << "simplifying...\n" << mk_pp(n, m) << "\n" << mk_pp(new_n, m) << "\n";); m_asserted_formulas.set(i, new_n); if (m.proofs_enabled()) { - proof_ref new_pr(m); + proof_ref new_pr(m); new_pr = m.mk_rewrite(n, new_n); new_pr = m.mk_modus_ponens(pr, new_pr); m_asserted_formula_prs.set(i, new_pr); @@ -860,7 +866,7 @@ void asserted_formulas::max_bv_sharing() { } reduce_asserted_formulas(); TRACE("bv_sharing", display(tout);); - + } #ifdef Z3DEBUG diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h index 093680fd9..07f56f87e 100644 --- a/src/smt/asserted_formulas.h +++ b/src/smt/asserted_formulas.h @@ -49,7 +49,7 @@ class asserted_formulas { macro_manager m_macro_manager; scoped_ptr m_macro_finder; - + bit2int m_bit2int; maximise_bv_sharing m_bv_sharing; @@ -87,7 +87,7 @@ class asserted_formulas { bool apply_bit2int(); void lift_ite(); bool elim_bvs_from_quantifiers(); - void ng_lift_ite(); + void ng_lift_ite(); #ifdef Z3DEBUG bool check_well_sorted() const; #endif @@ -112,8 +112,8 @@ public: unsigned get_num_formulas() const { return m_asserted_formulas.size(); } unsigned get_formulas_last_level() const; unsigned get_qhead() const { return m_asserted_qhead; } - void commit(); - void commit(unsigned new_qhead); + void commit(); + void commit(unsigned new_qhead); expr * get_formula(unsigned idx) const { return m_asserted_formulas.get(idx); } proof * get_formula_proof(unsigned idx) const { return m.proofs_enabled() ? m_asserted_formula_prs.get(idx) : 0; } expr * const * get_formulas() const { return m_asserted_formulas.c_ptr(); } @@ -129,7 +129,7 @@ public: void collect_statistics(statistics & st) const; // TODO: improve precision of the following method. bool has_quantifiers() const { return m_simplifier.visited_quantifier(); /* approximation */ } - + // ----------------------------------- // // Macros @@ -140,9 +140,7 @@ public: func_decl * get_macro_func_decl(unsigned i) const { return m_macro_manager.get_macro_func_decl(i); } func_decl * get_macro_interpretation(unsigned i, expr_ref & interp) const { return m_macro_manager.get_macro_interpretation(i, interp); } quantifier * get_macro_quantifier(func_decl * f) const { return m_macro_manager.get_macro_quantifier(f); } - // auxiliary function used to create a logic context based on a model. - void insert_macro(func_decl * f, quantifier * m, proof * pr) { m_macro_manager.insert(f, m, pr); } - + void insert_macro(func_decl * f, quantifier * m, proof * pr, expr_dependency * dep) { m_macro_manager.insert(f, m, pr, dep); } }; #endif /* ASSERTED_FORMULAS_H_ */ diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index fecb42700..85633b7f4 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -209,7 +209,7 @@ namespace smt { ~scoped_mk_model() { if (m_ctx.m_proto_model.get() != 0) { m_ctx.m_model = m_ctx.m_proto_model->mk_model(); - m_ctx.add_rec_funs_to_model(); + m_ctx.add_rec_funs_to_model(); m_ctx.m_proto_model = 0; // proto_model is not needed anymore. } } @@ -1568,7 +1568,7 @@ namespace smt { func_decl * get_macro_func_decl(unsigned i) const { return m_asserted_formulas.get_macro_func_decl(i); } func_decl * get_macro_interpretation(unsigned i, expr_ref & interp) const { return m_asserted_formulas.get_macro_interpretation(i, interp); } quantifier * get_macro_quantifier(func_decl * f) const { return m_asserted_formulas.get_macro_quantifier(f); } - void insert_macro(func_decl * f, quantifier * m, proof * pr) { m_asserted_formulas.insert_macro(f, m, pr); } + void insert_macro(func_decl * f, quantifier * m, proof * pr, expr_dependency * dep) { m_asserted_formulas.insert_macro(f, m, pr, dep); } }; }; diff --git a/src/tactic/ufbv/macro_finder_tactic.cpp b/src/tactic/ufbv/macro_finder_tactic.cpp index e1e3b669b..bf8e08fb7 100644 --- a/src/tactic/ufbv/macro_finder_tactic.cpp +++ b/src/tactic/ufbv/macro_finder_tactic.cpp @@ -49,9 +49,9 @@ class macro_finder_tactic : public tactic { SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; tactic_report report("macro-finder", *g); - fail_if_unsat_core_generation("macro-finder", g); bool produce_proofs = g->proofs_enabled(); + bool unsat_core_enabled = g->unsat_core_enabled(); simplifier simp(m_manager); basic_simplifier_plugin * bsimp = alloc(basic_simplifier_plugin, m_manager); @@ -69,17 +69,21 @@ class macro_finder_tactic : public tactic { expr_ref_vector forms(m_manager), new_forms(m_manager); proof_ref_vector proofs(m_manager), new_proofs(m_manager); - unsigned size = g->size(); + expr_dependency_ref_vector deps(m_manager), new_deps(m_manager); + unsigned size = g->size(); for (unsigned idx = 0; idx < size; idx++) { forms.push_back(g->form(idx)); proofs.push_back(g->pr(idx)); + deps.push_back(g->dep(idx)); } - mf(forms.size(), forms.c_ptr(), proofs.c_ptr(), new_forms, new_proofs); + mf(forms.size(), forms.c_ptr(), proofs.c_ptr(), deps.c_ptr(), new_forms, new_proofs, new_deps); g->reset(); for (unsigned i = 0; i < new_forms.size(); i++) - g->assert_expr(new_forms.get(i), produce_proofs ? new_proofs.get(i) : 0, 0); + g->assert_expr(new_forms.get(i), + produce_proofs ? new_proofs.get(i) : 0, + unsat_core_enabled ? new_deps.get(i) : 0); extension_model_converter * evmc = alloc(extension_model_converter, mm.get_manager()); unsigned num = mm.get_num_macros(); diff --git a/src/tactic/ufbv/quasi_macros_tactic.cpp b/src/tactic/ufbv/quasi_macros_tactic.cpp index ab68a2b63..c501559a5 100644 --- a/src/tactic/ufbv/quasi_macros_tactic.cpp +++ b/src/tactic/ufbv/quasi_macros_tactic.cpp @@ -35,22 +35,22 @@ class quasi_macros_tactic : public tactic { imp(ast_manager & m, params_ref const & p) : m_manager(m) { updt_params(p); } - + ast_manager & m() const { return m_manager; } - - - void operator()(goal_ref const & g, - goal_ref_buffer & result, - model_converter_ref & mc, + + + void operator()(goal_ref const & g, + goal_ref_buffer & result, + model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; tactic_report report("quasi-macros", *g); - fail_if_unsat_core_generation("quasi-macros", g); bool produce_proofs = g->proofs_enabled(); - + bool produce_unsat_cores = g->unsat_core_enabled(); + simplifier simp(m_manager); basic_simplifier_plugin * bsimp = alloc(basic_simplifier_plugin, m_manager); bsimp->set_eliminate_and(true); @@ -61,34 +61,40 @@ class quasi_macros_tactic : public tactic { bv_simplifier_params bv_params; bv_simplifier_plugin * bvsimp = alloc(bv_simplifier_plugin, m_manager, *bsimp, bv_params); simp.register_plugin(bvsimp); - + macro_manager mm(m_manager, simp); quasi_macros qm(m_manager, mm, simp); bool more = true; - + expr_ref_vector forms(m_manager), new_forms(m_manager); proof_ref_vector proofs(m_manager), new_proofs(m_manager); + expr_dependency_ref_vector deps(m_manager), new_deps(m_manager); unsigned size = g->size(); for (unsigned i = 0; i < size; i++) { forms.push_back(g->form(i)); proofs.push_back(g->pr(i)); + deps.push_back(g->dep(i)); } - + while (more) { // CMW: use repeat(...) ? if (m().canceled()) throw tactic_exception(m().limit().get_cancel_msg()); - + new_forms.reset(); new_proofs.reset(); - more = qm(forms.size(), forms.c_ptr(), proofs.c_ptr(), new_forms, new_proofs); + new_deps.reset(); + more = qm(forms.size(), forms.c_ptr(), proofs.c_ptr(), deps.c_ptr(), new_forms, new_proofs, new_deps); forms.swap(new_forms); - proofs.swap(new_proofs); + proofs.swap(new_proofs); + deps.swap(new_deps); } g->reset(); for (unsigned i = 0; i < new_forms.size(); i++) - g->assert_expr(new_forms.get(i), produce_proofs ? new_proofs.get(i) : 0, 0); + g->assert_expr(forms.get(i), + produce_proofs ? proofs.get(i) : 0, + produce_unsat_cores ? deps.get(i) : 0); extension_model_converter * evmc = alloc(extension_model_converter, mm.get_manager()); unsigned num = mm.get_num_macros(); @@ -108,7 +114,7 @@ class quasi_macros_tactic : public tactic { void updt_params(params_ref const & p) { } }; - + imp * m_imp; params_ref m_params; @@ -121,7 +127,7 @@ public: virtual tactic * translate(ast_manager & m) { return alloc(quasi_macros_tactic, m, m_params); } - + virtual ~quasi_macros_tactic() { dealloc(m_imp); } @@ -136,19 +142,19 @@ public: insert_produce_models(r); insert_produce_proofs(r); } - - virtual void operator()(goal_ref const & in, - goal_ref_buffer & result, - model_converter_ref & mc, + + virtual void operator()(goal_ref const & in, + goal_ref_buffer & result, + model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { (*m_imp)(in, result, mc, pc, core); } - + virtual void cleanup() { ast_manager & m = m_imp->m(); imp * d = alloc(imp, m, m_params); - std::swap(d, m_imp); + std::swap(d, m_imp); dealloc(d); } From ebcacaa26d0a14c6d7893a28c154c8683243882b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 25 Aug 2017 17:44:33 -0700 Subject: [PATCH 194/488] update new assertions Signed-off-by: Nikolaj Bjorner --- src/ast/ast.h | 36 ++++++++ src/ast/macros/macro_finder.cpp | 141 +++++++++++++++++++++++++++++ src/ast/macros/macro_finder.h | 3 + src/ast/macros/macro_manager.cpp | 8 ++ src/ast/macros/macro_manager.h | 1 + src/ast/macros/quasi_macros.cpp | 62 +++++++++++++ src/ast/macros/quasi_macros.h | 3 + src/ast/rewriter/CMakeLists.txt | 1 + src/ast/simplifier/CMakeLists.txt | 1 - src/ast/simplifier/bv_elim.cpp | 52 +++++------ src/ast/simplifier/bv_elim.h | 4 +- src/ast/simplifier/inj_axiom.cpp | 142 ------------------------------ src/ast/simplifier/inj_axiom.h | 27 ------ src/smt/CMakeLists.txt | 1 + src/smt/asserted_formulas.cpp | 2 +- src/smt/elim_term_ite.cpp | 18 ++++ src/smt/elim_term_ite.h | 28 ++++++ 17 files changed, 331 insertions(+), 199 deletions(-) delete mode 100644 src/ast/simplifier/inj_axiom.cpp delete mode 100644 src/ast/simplifier/inj_axiom.h diff --git a/src/ast/ast.h b/src/ast/ast.h index e6beec7e6..408ca4063 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -2470,6 +2470,42 @@ public: void operator()(AST * n) { m_manager.inc_ref(n); } }; +class justified_expr { + ast_manager& m; + expr* m_fml; + proof* m_proof; + public: + justified_expr(ast_manager& m, expr* fml, proof* p): + m(m), + m_fml(fml), + m_proof(p) { + m.inc_ref(fml); + m.inc_ref(p); + } + + justified_expr& operator=(justified_expr& other) { + SASSERT(&m == &other.m); + if (this != &other) { + m.dec_ref(m_fml); + m.dec_ref(m_proof); + m_fml = other.get_fml(); + m_proof = other.get_proof(); + m.inc_ref(m_fml); + m.inc_ref(m_proof); + } + return *this; + } + + ~justified_expr() { + m.dec_ref(m_fml); + m.dec_ref(m_proof); + } + + expr* get_fml() const { return m_fml; } + proof* get_proof() const { return m_proof; } +}; + + #endif /* AST_H_ */ diff --git a/src/ast/macros/macro_finder.cpp b/src/ast/macros/macro_finder.cpp index 1d441aee7..9a8e552fc 100644 --- a/src/ast/macros/macro_finder.cpp +++ b/src/ast/macros/macro_finder.cpp @@ -111,6 +111,71 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_ex return true; } +bool macro_finder::is_arith_macro(expr * n, proof * pr, vector& new_fmls) { + if (!is_quantifier(n) || !to_quantifier(n)->is_forall()) + return false; + expr * body = to_quantifier(n)->get_expr(); + unsigned num_decls = to_quantifier(n)->get_num_decls(); + + if (!m_autil.is_le(body) && !m_autil.is_ge(body) && !m_manager.is_eq(body)) + return false; + if (!m_autil.is_add(to_app(body)->get_arg(0))) + return false; + app_ref head(m_manager); + expr_ref def(m_manager); + bool inv = false; + if (!m_util.is_arith_macro(body, num_decls, head, def, inv)) + return false; + app_ref new_body(m_manager); + + if (!inv || m_manager.is_eq(body)) + new_body = m_manager.mk_app(to_app(body)->get_decl(), head, def); + else if (m_autil.is_le(body)) + new_body = m_autil.mk_ge(head, def); + else + new_body = m_autil.mk_le(head, def); + + quantifier_ref new_q(m_manager); + new_q = m_manager.update_quantifier(to_quantifier(n), new_body); + proof * new_pr = 0; + if (m_manager.proofs_enabled()) { + proof * rw = m_manager.mk_rewrite(n, new_q); + new_pr = m_manager.mk_modus_ponens(pr, rw); + } + if (m_manager.is_eq(body)) { + return m_macro_manager.insert(head->get_decl(), new_q, new_pr); + } + // is ge or le + // + TRACE("macro_finder", tout << "is_arith_macro: is_ge or is_le\n";); + func_decl * f = head->get_decl(); + func_decl * k = m_manager.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); + app * k_app = m_manager.mk_app(k, head->get_num_args(), head->get_args()); + expr_ref_buffer new_rhs_args(m_manager); + expr_ref new_rhs2(m_autil.mk_add(def, k_app), m_manager); + expr * body1 = m_manager.mk_eq(head, new_rhs2); + expr * body2 = m_manager.mk_app(new_body->get_decl(), k_app, m_autil.mk_int(0)); + quantifier * q1 = m_manager.update_quantifier(new_q, body1); + expr * patterns[1] = { m_manager.mk_pattern(k_app) }; + quantifier * q2 = m_manager.update_quantifier(new_q, 1, patterns, body2); + proof* pr1 = 0, *pr2 = 0; + if (m_manager.proofs_enabled()) { + // new_pr : new_q + // rw : [rewrite] new_q ~ q1 & q2 + // mp : [modus_pones new_pr rw] q1 & q2 + // pr1 : [and-elim mp] q1 + // pr2 : [and-elim mp] q2 + app * q1q2 = m_manager.mk_and(q1,q2); + proof * rw = m_manager.mk_oeq_rewrite(new_q, q1q2); + proof * mp = m_manager.mk_modus_ponens(new_pr, rw); + pr1 = m_manager.mk_and_elim(mp, 0); + pr2 = m_manager.mk_and_elim(mp, 1); + } + new_fmls.push_back(justified_expr(m_manager, q1, pr1)); + new_fmls.push_back(justified_expr(m_manager, q2, pr2)); + return true; +} + /** n is of the form: (forall (X) (iff (= (f X) t) def[X])) @@ -152,6 +217,34 @@ static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, e } } +static void pseudo_predicate_macro2macro(ast_manager & m, app * head, app * t, expr * def, quantifier * q, proof * pr, + vector& new_fmls) { + func_decl * f = head->get_decl(); + func_decl * k = m.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range()); + app * k_app = m.mk_app(k, head->get_num_args(), head->get_args()); + app * ite = m.mk_ite(def, t, k_app); + app * body_1 = m.mk_eq(head, ite); + app * body_2 = m.mk_not(m.mk_eq(k_app, t)); + quantifier * q1 = m.update_quantifier(q, body_1); + proof * pr1 = 0, *pr2 = 0; + expr * pats[1] = { m.mk_pattern(k_app) }; + quantifier * q2 = m.update_quantifier(q, 1, pats, body_2); // erase patterns + if (m.proofs_enabled()) { + // r : [rewrite] q ~ q1 & q2 + // pr : q + // mp : [modus_pones pr pr1] q1 & q2 + // pr1 : [and-elim mp] q1 + // pr2 : [and-elim mp] q2 + app * q1q2 = m.mk_and(q1,q2); + proof * r = m.mk_oeq_rewrite(q, q1q2); + proof * mp = m.mk_modus_ponens(pr, r); + pr1 = m.mk_and_elim(mp, 0); + pr2 = m.mk_and_elim(mp, 1); + } + new_fmls.push_back(justified_expr(m, q1, pr1)); + new_fmls.push_back(justified_expr(m, q2, pr2)); +} + macro_finder::macro_finder(ast_manager & m, macro_manager & mm): m_manager(m), m_macro_manager(mm), @@ -216,3 +309,51 @@ void macro_finder::operator()(unsigned num, expr * const * exprs, proof * const } + +bool macro_finder::expand_macros(unsigned num, justified_expr const * fmls, vector& new_fmls) { + TRACE("macro_finder", tout << "starting expand_macros:\n"; + m_macro_manager.display(tout);); + bool found_new_macro = false; + for (unsigned i = 0; i < num; i++) { + expr * n = fmls[i].get_fml(); + proof * pr = m_manager.proofs_enabled() ? fmls[i].get_proof() : 0; + expr_ref new_n(m_manager), def(m_manager); + proof_ref new_pr(m_manager); + m_macro_manager.expand_macros(n, pr, new_n, new_pr); + app_ref head(m_manager), t(m_manager); + if (is_macro(new_n, head, def) && m_macro_manager.insert(head->get_decl(), to_quantifier(new_n.get()), new_pr)) { + TRACE("macro_finder_found", tout << "found new macro: " << head->get_decl()->get_name() << "\n" << new_n << "\n";); + found_new_macro = true; + } + else if (is_arith_macro(new_n, new_pr, new_fmls)) { + TRACE("macro_finder_found", tout << "found new arith macro:\n" << new_n << "\n";); + found_new_macro = true; + } + else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) { + TRACE("macro_finder_found", tout << "found new pseudo macro:\n" << head << "\n" << t << "\n" << def << "\n";); + pseudo_predicate_macro2macro(m_manager, head, t, def, to_quantifier(new_n), new_pr, new_fmls); + found_new_macro = true; + } + else { + new_fmls.push_back(justified_expr(m_manager, new_n, new_pr)); + } + } + return found_new_macro; +} + +void macro_finder::operator()(unsigned n, justified_expr const* fmls, vector& new_fmls) { + TRACE("macro_finder", tout << "processing macros...\n";); + vector _new_fmls; + if (expand_macros(n, fmls, _new_fmls)) { + while (true) { + vector old_fmls; + _new_fmls.swap(old_fmls); + SASSERT(_new_fmls.empty()); + if (!expand_macros(old_fmls.size(), old_fmls.c_ptr(), _new_fmls)) + break; + } + } + new_fmls.append(_new_fmls); +} + + diff --git a/src/ast/macros/macro_finder.h b/src/ast/macros/macro_finder.h index 5807573ae..2bba07306 100644 --- a/src/ast/macros/macro_finder.h +++ b/src/ast/macros/macro_finder.h @@ -38,7 +38,9 @@ class macro_finder { macro_util & m_util; arith_util m_autil; bool expand_macros(unsigned num, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + bool expand_macros(unsigned n, justified_expr const * fmls, vector& new_fmls); bool is_arith_macro(expr * n, proof * pr, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + bool is_arith_macro(expr * n, proof * pr, vector& new_fmls); bool is_macro(expr * n, app_ref & head, expr_ref & def); bool is_pseudo_head(expr * n, unsigned num_decls, app * & head, app * & t); @@ -48,6 +50,7 @@ public: macro_finder(ast_manager & m, macro_manager & mm); ~macro_finder(); void operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + void operator()(unsigned n, justified_expr const* fmls, vector& new_fmls); }; #endif /* MACRO_FINDER_H_ */ diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index bff1e7dae..7a2642fa3 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -152,6 +152,14 @@ void macro_manager::mark_forbidden(unsigned n, expr * const * exprs) { for_each_expr(p, visited, exprs[i]); } +void macro_manager::mark_forbidden(unsigned n, justified_expr const * exprs) { + expr_mark visited; + macro_manager_ns::proc p(m_forbidden_set, m_forbidden); + for (unsigned i = 0; i < n; i++) + for_each_expr(p, visited, exprs[i].get_fml()); +} + + void macro_manager::get_head_def(quantifier * q, func_decl * d, app * & head, expr * & def) const { app * body = to_app(q->get_expr()); SASSERT(m.is_eq(body) || m.is_iff(body)); diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index 71864a699..58fedf666 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -71,6 +71,7 @@ public: void pop_scope(unsigned num_scopes); void reset(); void mark_forbidden(unsigned n, expr * const * exprs); + void mark_forbidden(unsigned n, justified_expr const * exprs); void mark_forbidden(expr * e) { mark_forbidden(1, &e); } bool is_forbidden(func_decl * d) const { return m_forbidden_set.contains(d); } obj_hashtable const & get_forbidden_set() const { return m_forbidden_set; } diff --git a/src/ast/macros/quasi_macros.cpp b/src/ast/macros/quasi_macros.cpp index 822532532..527b9656d 100644 --- a/src/ast/macros/quasi_macros.cpp +++ b/src/ast/macros/quasi_macros.cpp @@ -293,6 +293,44 @@ bool quasi_macros::find_macros(unsigned n, expr * const * exprs) { return res; } +bool quasi_macros::find_macros(unsigned n, justified_expr const * exprs) { + TRACE("quasi_macros", tout << "Finding quasi-macros in: " << std::endl; + for (unsigned i = 0 ; i < n ; i++) + tout << i << ": " << mk_pp(exprs[i].get_fml(), m_manager) << std::endl; ); + bool res = false; + m_occurrences.reset(); + + + // Find out how many non-ground appearences for each uninterpreted function there are + for ( unsigned i = 0 ; i < n ; i++ ) + find_occurrences(exprs[i].get_fml()); + + TRACE("quasi_macros", tout << "Occurrences: " << std::endl; + for (occurrences_map::iterator it = m_occurrences.begin(); + it != m_occurrences.end(); + it++) + tout << it->m_key->get_name() << ": " << it->m_value << std::endl; ); + + // Find all macros + for ( unsigned i = 0 ; i < n ; i++ ) { + app_ref a(m_manager); + expr_ref t(m_manager); + if (is_quasi_macro(exprs[i].get_fml(), a, t)) { + quantifier_ref macro(m_manager); + quasi_macro_to_macro(to_quantifier(exprs[i].get_fml()), a, t, macro); + TRACE("quasi_macros", tout << "Found quasi macro: " << mk_pp(exprs[i].get_fml(), m_manager) << std::endl; + tout << "Macro: " << mk_pp(macro, m_manager) << std::endl; ); + proof * pr = 0; + if (m_manager.proofs_enabled()) + pr = m_manager.mk_def_axiom(macro); + if (m_macro_manager.insert(a->get_decl(), macro, pr)) + res = true; + } + } + + return res; +} + void quasi_macros::apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { for ( unsigned i = 0 ; i < n ; i++ ) { expr_ref r(m_manager), rs(m_manager); @@ -319,3 +357,27 @@ bool quasi_macros::operator()(unsigned n, expr * const * exprs, proof * const * return false; } } + +void quasi_macros::apply_macros(unsigned n, justified_expr const* fmls, vector& new_fmls) { + for ( unsigned i = 0 ; i < n ; i++ ) { + expr_ref r(m_manager), rs(m_manager); + proof_ref pr(m_manager), ps(m_manager); + proof * p = m_manager.proofs_enabled() ? fmls[i].get_proof() : 0; + m_macro_manager.expand_macros(fmls[i].get_fml(), p, r, pr); + m_rewriter(r); + new_fmls.push_back(justified_expr(m_manager, r, pr)); + } +} + +bool quasi_macros::operator()(unsigned n, justified_expr const* fmls, vector& new_fmls) { + if (find_macros(n, fmls)) { + apply_macros(n, fmls, new_fmls); + return true; + } else { + // just copy them over + for ( unsigned i = 0 ; i < n ; i++ ) { + new_fmls.push_back(fmls[i]); + } + return false; + } +} diff --git a/src/ast/macros/quasi_macros.h b/src/ast/macros/quasi_macros.h index 29efe63c7..7288ac601 100644 --- a/src/ast/macros/quasi_macros.h +++ b/src/ast/macros/quasi_macros.h @@ -53,7 +53,9 @@ class quasi_macros { void find_occurrences(expr * e); bool find_macros(unsigned n, expr * const * exprs); + bool find_macros(unsigned n, justified_expr const* expr); void apply_macros(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + void apply_macros(unsigned n, justified_expr const* fmls, vector& new_fmls); public: quasi_macros(ast_manager & m, macro_manager & mm); @@ -63,6 +65,7 @@ public: \brief Find pure function macros and apply them. */ bool operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs); + bool operator()(unsigned n, justified_expr const* fmls, vector& new_fmls); }; #endif diff --git a/src/ast/rewriter/CMakeLists.txt b/src/ast/rewriter/CMakeLists.txt index 72bca53d4..c1b99bcae 100644 --- a/src/ast/rewriter/CMakeLists.txt +++ b/src/ast/rewriter/CMakeLists.txt @@ -15,6 +15,7 @@ z3_add_component(rewriter expr_safe_replace.cpp factor_rewriter.cpp fpa_rewriter.cpp + inj_axiom.cpp label_rewriter.cpp mk_simplified_app.cpp pb_rewriter.cpp diff --git a/src/ast/simplifier/CMakeLists.txt b/src/ast/simplifier/CMakeLists.txt index c5c310c07..b6fe9b1cd 100644 --- a/src/ast/simplifier/CMakeLists.txt +++ b/src/ast/simplifier/CMakeLists.txt @@ -12,7 +12,6 @@ z3_add_component(simplifier datatype_simplifier_plugin.cpp elim_bounds.cpp fpa_simplifier_plugin.cpp - inj_axiom.cpp maximise_ac_sharing.cpp poly_simplifier_plugin.cpp seq_simplifier_plugin.cpp diff --git a/src/ast/simplifier/bv_elim.cpp b/src/ast/simplifier/bv_elim.cpp index 1875e333b..1c0048a07 100644 --- a/src/ast/simplifier/bv_elim.cpp +++ b/src/ast/simplifier/bv_elim.cpp @@ -12,16 +12,16 @@ Copyright (c) 2015 Microsoft Corporation void bv_elim::elim(quantifier* q, quantifier_ref& r) { svector names, _names; - sort_ref_buffer sorts(m_manager), _sorts(m_manager); - expr_ref_buffer pats(m_manager); - expr_ref_buffer no_pats(m_manager); - expr_ref_buffer subst_map(m_manager), _subst_map(m_manager); - var_subst subst(m_manager); - bv_util bv(m_manager); - expr_ref new_body(m_manager); + sort_ref_buffer sorts(m), _sorts(m); + expr_ref_buffer pats(m); + expr_ref_buffer no_pats(m); + expr_ref_buffer subst_map(m), _subst_map(m); + var_subst subst(m); + bv_util bv(m); + expr_ref new_body(m); expr* old_body = q->get_expr(); unsigned num_decls = q->get_num_decls(); - family_id bfid = m_manager.mk_family_id("bv"); + family_id bfid = m.mk_family_id("bv"); // // Traverse sequence of bound variables to eliminate @@ -37,23 +37,23 @@ void bv_elim::elim(quantifier* q, quantifier_ref& r) { if (bv.is_bv_sort(s)) { // convert n-bit bit-vector variable into sequence of n-Booleans. unsigned num_bits = bv.get_bv_size(s); - expr_ref_buffer args(m_manager); - expr_ref bv(m_manager); + expr_ref_buffer args(m); + expr_ref bv(m); for (unsigned j = 0; j < num_bits; ++j) { std::ostringstream new_name; new_name << nm.str(); new_name << "_"; new_name << j; - var* v = m_manager.mk_var(var_idx++, m_manager.mk_bool_sort()); + var* v = m.mk_var(var_idx++, m.mk_bool_sort()); args.push_back(v); - _sorts.push_back(m_manager.mk_bool_sort()); + _sorts.push_back(m.mk_bool_sort()); _names.push_back(symbol(new_name.str().c_str())); } - bv = m_manager.mk_app(bfid, OP_MKBV, 0, 0, args.size(), args.c_ptr()); + bv = m.mk_app(bfid, OP_MKBV, 0, 0, args.size(), args.c_ptr()); _subst_map.push_back(bv.get()); } else { - _subst_map.push_back(m_manager.mk_var(var_idx++, s)); + _subst_map.push_back(m.mk_var(var_idx++, s)); _sorts.push_back(s); _names.push_back(nm); } @@ -78,26 +78,26 @@ void bv_elim::elim(quantifier* q, quantifier_ref& r) { subst(old_body, sub_size, sub, new_body); for (unsigned j = 0; j < q->get_num_patterns(); j++) { - expr_ref pat(m_manager); + expr_ref pat(m); subst(q->get_pattern(j), sub_size, sub, pat); pats.push_back(pat); } for (unsigned j = 0; j < q->get_num_no_patterns(); j++) { - expr_ref nopat(m_manager); + expr_ref nopat(m); subst(q->get_no_pattern(j), sub_size, sub, nopat); no_pats.push_back(nopat); } - r = m_manager.mk_quantifier(true, - names.size(), - sorts.c_ptr(), - names.c_ptr(), - new_body.get(), - q->get_weight(), - q->get_qid(), - q->get_skid(), - pats.size(), pats.c_ptr(), - no_pats.size(), no_pats.c_ptr()); + r = m.mk_quantifier(true, + names.size(), + sorts.c_ptr(), + names.c_ptr(), + new_body.get(), + q->get_weight(), + q->get_qid(), + q->get_skid(), + pats.size(), pats.c_ptr(), + no_pats.size(), no_pats.c_ptr()); } bool bv_elim_star::visit_quantifier(quantifier* q) { diff --git a/src/ast/simplifier/bv_elim.h b/src/ast/simplifier/bv_elim.h index 2b8a4778a..c027b1a9e 100644 --- a/src/ast/simplifier/bv_elim.h +++ b/src/ast/simplifier/bv_elim.h @@ -24,9 +24,9 @@ Revision History: #include "ast/simplifier/simplifier.h" class bv_elim { - ast_manager& m_manager; + ast_manager& m; public: - bv_elim(ast_manager& m) : m_manager(m) {}; + bv_elim(ast_manager& m) : m(m) {}; void elim(quantifier* q, quantifier_ref& r); }; diff --git a/src/ast/simplifier/inj_axiom.cpp b/src/ast/simplifier/inj_axiom.cpp deleted file mode 100644 index 2aa828ffa..000000000 --- a/src/ast/simplifier/inj_axiom.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - inj_axiom.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-23. - -Revision History: - ---*/ -#include "ast/simplifier/inj_axiom.h" -#include "ast/ast_pp.h" -#include "ast/ast_ll_pp.h" -#include "ast/has_free_vars.h" -#include "ast/well_sorted.h" - -/** - \brief Little HACK for simplifying injectivity axioms - - \remark It is not covering all possible cases. -*/ -bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) { - expr * n = q->get_expr(); - if (q->is_forall() && m.is_or(n) && to_app(n)->get_num_args() == 2) { - expr * arg1 = to_app(n)->get_arg(0); - expr * arg2 = to_app(n)->get_arg(1); - if (m.is_not(arg2)) - std::swap(arg1, arg2); - if (m.is_not(arg1) && - m.is_eq(to_app(arg1)->get_arg(0)) && - m.is_eq(arg2)) { - expr * app1 = to_app(to_app(arg1)->get_arg(0))->get_arg(0); - expr * app2 = to_app(to_app(arg1)->get_arg(0))->get_arg(1); - expr * var1 = to_app(arg2)->get_arg(0); - expr * var2 = to_app(arg2)->get_arg(1); - if (is_app(app1) && - is_app(app2) && - to_app(app1)->get_decl() == to_app(app2)->get_decl() && - to_app(app1)->get_num_args() == to_app(app2)->get_num_args() && - to_app(app1)->get_family_id() == null_family_id && - to_app(app1)->get_num_args() > 0 && - is_var(var1) && - is_var(var2) && - var1 != var2) { - app * f1 = to_app(app1); - app * f2 = to_app(app2); - bool found_vars = false; - unsigned num = f1->get_num_args(); - unsigned idx = UINT_MAX; - unsigned num_vars = 1; - for (unsigned i = 0; i < num; i++) { - expr * c1 = f1->get_arg(i); - expr * c2 = f2->get_arg(i); - if (!is_var(c1) && !is_uninterp_const(c1)) - return false; - if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) { - if (found_vars) - return false; - found_vars = true; - idx = i; - } - else if (c1 == c2 && c1 != var1 && c1 != var2) { - if (is_var(c1)) { - ++num_vars; - } - } - else { - return false; - } - } - if (found_vars && !has_free_vars(q)) { - TRACE("inj_axiom", - tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" << - mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";); - // Building new (optimized) axiom - func_decl * decl = f1->get_decl(); - unsigned var_idx = 0; - ptr_buffer f_args, inv_vars; - ptr_buffer decls; - buffer names; - - expr * var = 0; - for (unsigned i = 0; i < num; i++) { - expr * c = f1->get_arg(i); - if (is_var(c)) { - names.push_back(symbol(i)); - sort * s = decl->get_domain(i); - decls.push_back(s); - expr * new_c = m.mk_var(var_idx, s); - var_idx++; - f_args.push_back(new_c); - if (i == idx) { - var = new_c; - } - else { - inv_vars.push_back(new_c); - } - } - else { - SASSERT(is_uninterp_const(c)); - f_args.push_back(c); - } - } - SASSERT(var != 0); - app * f = m.mk_app(decl, f_args.size(), f_args.c_ptr()); - - ptr_vector domain; - inv_vars.push_back(f); - for (unsigned i = 0; i < inv_vars.size(); ++i) { - domain.push_back(m.get_sort(inv_vars[i])); - } - sort * d = decl->get_domain(idx); - func_decl * inv_decl = m.mk_fresh_func_decl("inj", domain.size(), domain.c_ptr(), d); - - expr * proj = m.mk_app(inv_decl, inv_vars.size(), inv_vars.c_ptr()); - expr * eq = m.mk_eq(proj, var); - expr * p = m.mk_pattern(f); - - // decls are in the wrong order... - // Remark: the sort of the var 0 must be in the last position. - std::reverse(decls.begin(), decls.end()); - - result = m.mk_forall(decls.size(), decls.c_ptr(), names.c_ptr(), eq, - 0, symbol(), symbol(), 1, &p); - TRACE("inj_axiom", tout << "new axiom:\n" << mk_pp(result, m) << "\n";); - SASSERT(is_well_sorted(m, result)); - return true; - } - } - } - } - return false; -} - diff --git a/src/ast/simplifier/inj_axiom.h b/src/ast/simplifier/inj_axiom.h deleted file mode 100644 index a6df16515..000000000 --- a/src/ast/simplifier/inj_axiom.h +++ /dev/null @@ -1,27 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - inj_axiom.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-23. - -Revision History: - ---*/ -#ifndef INJ_AXIOM_H_ -#define INJ_AXIOM_H_ - -#include "ast/ast.h" - -bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result); - -#endif /* INJ_AXIOM_H_ */ - diff --git a/src/smt/CMakeLists.txt b/src/smt/CMakeLists.txt index 41890dd05..b117db89b 100644 --- a/src/smt/CMakeLists.txt +++ b/src/smt/CMakeLists.txt @@ -3,6 +3,7 @@ z3_add_component(smt arith_eq_adapter.cpp arith_eq_solver.cpp asserted_formulas.cpp + asserted_formulas_new.cpp cached_var_subst.cpp cost_evaluator.cpp dyn_ack.cpp diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 6f1c4cfcc..8b25e9263 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -24,6 +24,7 @@ Revision History: #include "ast/rewriter/rewriter_def.h" #include "ast/rewriter/pull_ite_tree.h" #include "ast/rewriter/push_app_ite.h" +#include "ast/rewriter/inj_axiom.h" #include "ast/simplifier/arith_simplifier_plugin.h" #include "ast/simplifier/array_simplifier_plugin.h" #include "ast/simplifier/datatype_simplifier_plugin.h" @@ -31,7 +32,6 @@ Revision History: #include "ast/simplifier/seq_simplifier_plugin.h" #include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/simplifier/bv_elim.h" -#include "ast/simplifier/inj_axiom.h" #include "ast/simplifier/elim_bounds.h" #include "ast/simplifier/bit2int.h" #include "ast/normal_forms/pull_quant.h" diff --git a/src/smt/elim_term_ite.cpp b/src/smt/elim_term_ite.cpp index b750e6bf5..d9cfac775 100644 --- a/src/smt/elim_term_ite.cpp +++ b/src/smt/elim_term_ite.cpp @@ -157,4 +157,22 @@ void elim_term_ite::reduce1_quantifier(quantifier * q) { } +br_status elim_term_ite_cfg::reduce_app(func_decl* f, unsigned n, expr * const* args, expr_ref& result, proof_ref& result_pr) { + if (!m.is_term_ite(f)) { + return BR_FAILED; + } + + expr_ref new_def(m); + proof_ref new_def_pr(m); + app_ref r(m.mk_app(f, n, args), m); + app_ref new_r(m); + if (!m_defined_names.mk_name(r, new_def, new_def_pr, new_r, result_pr)) { + return BR_FAILED; + } + result = new_r; + + CTRACE("elim_term_ite_bug", new_def.get() == 0, tout << mk_ismt2_pp(r, m) << "\n";); + m_new_defs.push_back(justified_expr(m, new_def, new_def_pr)); + return BR_DONE; +} diff --git a/src/smt/elim_term_ite.h b/src/smt/elim_term_ite.h index 2b9c66a64..94e5e0346 100644 --- a/src/smt/elim_term_ite.h +++ b/src/smt/elim_term_ite.h @@ -21,6 +21,7 @@ Revision History: #include "ast/simplifier/simplifier.h" #include "ast/normal_forms/defined_names.h" +#include "ast/rewriter/rewriter.h" class elim_term_ite : public simplifier { defined_names & m_defined_names; @@ -46,5 +47,32 @@ public: ); }; + + +class elim_term_ite_cfg : public default_rewriter_cfg { + ast_manager& m; + defined_names & m_defined_names; + vector m_new_defs; +public: + elim_term_ite_cfg(ast_manager & m, defined_names & d): m(m), m_defined_names(d) { + // TBD enable_ac_support(false); + } + virtual ~elim_term_ite_cfg() {} + vector const& new_defs() const { return m_new_defs; } + br_status reduce_app(func_decl* f, unsigned n, expr *const* args, expr_ref& result, proof_ref& result_pr); +}; + +class elim_term_ite_rw : public rewriter_tpl { + elim_term_ite_cfg m_cfg; +public: + elim_term_ite_rw(ast_manager& m, defined_names & dn): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m, dn) + {} + vector const& new_defs() const { return m_cfg.new_defs(); } +}; + + + #endif /* ELIM_TERM_ITE_H_ */ From 9438ff848fcaa149d0b58639f75c043d2730049f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 25 Aug 2017 17:44:57 -0700 Subject: [PATCH 195/488] moved files Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/inj_axiom.cpp | 139 +++++++++++++++++++++++++++++++++ src/ast/rewriter/inj_axiom.h | 27 +++++++ 2 files changed, 166 insertions(+) create mode 100644 src/ast/rewriter/inj_axiom.cpp create mode 100644 src/ast/rewriter/inj_axiom.h diff --git a/src/ast/rewriter/inj_axiom.cpp b/src/ast/rewriter/inj_axiom.cpp new file mode 100644 index 000000000..d322f3228 --- /dev/null +++ b/src/ast/rewriter/inj_axiom.cpp @@ -0,0 +1,139 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + inj_axiom.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-23. + +Revision History: + +--*/ +#include "ast/rewriter/inj_axiom.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/has_free_vars.h" +#include "ast/well_sorted.h" + +/** + \brief Little HACK for simplifying injectivity axioms + + \remark It is not covering all possible cases. +*/ +bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) { + expr * n = q->get_expr(); + expr* arg1 = 0, * arg2 = 0, *narg = 0; + expr* app1 = 0, * app2 = 0; + expr* var1 = 0, * var2 = 0; + if (q->is_forall() && m.is_or(n, arg1, arg2)) { + if (m.is_not(arg2)) + std::swap(arg1, arg2); + if (m.is_not(arg1, narg) && + m.is_eq(narg, app1, app2) && + m.is_eq(arg2, var1, var2)) { + if (is_app(app1) && + is_app(app2) && + to_app(app1)->get_decl() == to_app(app2)->get_decl() && + to_app(app1)->get_num_args() == to_app(app2)->get_num_args() && + to_app(app1)->get_family_id() == null_family_id && + to_app(app1)->get_num_args() > 0 && + is_var(var1) && + is_var(var2) && + var1 != var2) { + app * f1 = to_app(app1); + app * f2 = to_app(app2); + bool found_vars = false; + unsigned num = f1->get_num_args(); + unsigned idx = UINT_MAX; + unsigned num_vars = 1; + for (unsigned i = 0; i < num; i++) { + expr * c1 = f1->get_arg(i); + expr * c2 = f2->get_arg(i); + if (!is_var(c1) && !is_uninterp_const(c1)) + return false; + if ((c1 == var1 && c2 == var2) || (c1 == var2 && c2 == var1)) { + if (found_vars) + return false; + found_vars = true; + idx = i; + } + else if (c1 == c2 && c1 != var1 && c1 != var2) { + if (is_var(c1)) { + ++num_vars; + } + } + else { + return false; + } + } + if (found_vars && !has_free_vars(q)) { + TRACE("inj_axiom", + tout << "Cadidate for simplification:\n" << mk_ll_pp(q, m) << mk_pp(app1, m) << "\n" << mk_pp(app2, m) << "\n" << + mk_pp(var1, m) << "\n" << mk_pp(var2, m) << "\nnum_vars: " << num_vars << "\n";); + // Building new (optimized) axiom + func_decl * decl = f1->get_decl(); + unsigned var_idx = 0; + ptr_buffer f_args, inv_vars; + ptr_buffer decls; + buffer names; + + expr * var = 0; + for (unsigned i = 0; i < num; i++) { + expr * c = f1->get_arg(i); + if (is_var(c)) { + names.push_back(symbol(i)); + sort * s = decl->get_domain(i); + decls.push_back(s); + expr * new_c = m.mk_var(var_idx, s); + var_idx++; + f_args.push_back(new_c); + if (i == idx) { + var = new_c; + } + else { + inv_vars.push_back(new_c); + } + } + else { + SASSERT(is_uninterp_const(c)); + f_args.push_back(c); + } + } + SASSERT(var != 0); + app * f = m.mk_app(decl, f_args.size(), f_args.c_ptr()); + + ptr_vector domain; + inv_vars.push_back(f); + for (unsigned i = 0; i < inv_vars.size(); ++i) { + domain.push_back(m.get_sort(inv_vars[i])); + } + sort * d = decl->get_domain(idx); + func_decl * inv_decl = m.mk_fresh_func_decl("inj", domain.size(), domain.c_ptr(), d); + + expr * proj = m.mk_app(inv_decl, inv_vars.size(), inv_vars.c_ptr()); + expr * eq = m.mk_eq(proj, var); + expr * p = m.mk_pattern(f); + + // decls are in the wrong order... + // Remark: the sort of the var 0 must be in the last position. + std::reverse(decls.begin(), decls.end()); + + result = m.mk_forall(decls.size(), decls.c_ptr(), names.c_ptr(), eq, + 0, symbol(), symbol(), 1, &p); + TRACE("inj_axiom", tout << "new axiom:\n" << mk_pp(result, m) << "\n";); + SASSERT(is_well_sorted(m, result)); + return true; + } + } + } + } + return false; +} + diff --git a/src/ast/rewriter/inj_axiom.h b/src/ast/rewriter/inj_axiom.h new file mode 100644 index 000000000..a6df16515 --- /dev/null +++ b/src/ast/rewriter/inj_axiom.h @@ -0,0 +1,27 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + inj_axiom.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-23. + +Revision History: + +--*/ +#ifndef INJ_AXIOM_H_ +#define INJ_AXIOM_H_ + +#include "ast/ast.h" + +bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result); + +#endif /* INJ_AXIOM_H_ */ + From ac0bb6a3d062095b5538a870c4e7ec26126932b7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 25 Aug 2017 23:56:09 -0700 Subject: [PATCH 196/488] remove simplify dependencies Signed-off-by: Nikolaj Bjorner --- src/ast/expr_substitution.h | 33 ++++++++++++ src/ast/rewriter/CMakeLists.txt | 4 ++ src/ast/{simplifier => rewriter}/bit2int.cpp | 55 ++++++++++---------- src/ast/{simplifier => rewriter}/bit2int.h | 7 +-- src/ast/rewriter/bv_rewriter.h | 39 ++++++++++++-- src/ast/simplifier/CMakeLists.txt | 1 - src/smt/asserted_formulas.cpp | 4 +- src/smt/asserted_formulas.h | 2 +- src/smt/elim_term_ite.h | 2 + src/smt/params/preprocessor_params.cpp | 2 +- src/smt/params/preprocessor_params.h | 4 +- 11 files changed, 108 insertions(+), 45 deletions(-) rename src/ast/{simplifier => rewriter}/bit2int.cpp (87%) rename src/ast/{simplifier => rewriter}/bit2int.h (90%) diff --git a/src/ast/expr_substitution.h b/src/ast/expr_substitution.h index d209ab6b4..924481dd8 100644 --- a/src/ast/expr_substitution.h +++ b/src/ast/expr_substitution.h @@ -52,4 +52,37 @@ public: void cleanup(); }; +class scoped_expr_substitution { + expr_substitution& m_subst; + expr_ref_vector m_trail; + unsigned_vector m_trail_lim; +public: + + scoped_expr_substitution(expr_substitution& s): m_subst(s), m_trail(s.m()) {} + ~scoped_expr_substitution() {} + + void insert(expr * s, expr * def, proof * def_pr = 0, expr_dependency * def_dep = 0) { + if (!m_subst.contains(s)) { + m_subst.insert(s, def, def_pr, def_dep); + m_trail.push_back(s); + } + } + void reset() { m_subst.reset(); m_trail.reset(); m_trail_lim.reset(); } + void push() { m_trail_lim.push_back(m_trail.size()); } + void pop(unsigned n) { + if (n > 0) { + unsigned new_sz = m_trail_lim.size() - n; + unsigned old_sz = m_trail_lim[new_sz]; + for (unsigned i = old_sz; i < m_trail.size(); ++i) m_subst.erase(m_trail[i].get()); + m_trail.resize(old_sz); + m_trail_lim.resize(new_sz); + } + } + bool empty() const { return m_subst.empty(); } + bool find(expr * s, expr * & def, proof * & def_pr) { return m_subst.find(s, def, def_pr); } + bool find(expr * s, expr * & def, proof * & def_pr, expr_dependency * & def_dep) { return m_subst.find(s, def, def_pr, def_dep); } + bool contains(expr * s) { return m_subst.contains(s); } + void cleanup() { m_subst.cleanup(); } +}; + #endif diff --git a/src/ast/rewriter/CMakeLists.txt b/src/ast/rewriter/CMakeLists.txt index c1b99bcae..804fbcbed 100644 --- a/src/ast/rewriter/CMakeLists.txt +++ b/src/ast/rewriter/CMakeLists.txt @@ -3,13 +3,16 @@ z3_add_component(rewriter arith_rewriter.cpp array_rewriter.cpp ast_counter.cpp + bit2int.cpp bool_rewriter.cpp bv_bounds.cpp + bv_elim2.cpp bv_rewriter.cpp datatype_rewriter.cpp der.cpp distribute_forall.cpp dl_rewriter.cpp + elim_bounds2.cpp enum2bv_rewriter.cpp expr_replacer.cpp expr_safe_replace.cpp @@ -17,6 +20,7 @@ z3_add_component(rewriter fpa_rewriter.cpp inj_axiom.cpp label_rewriter.cpp + maximize_ac_sharing.cpp mk_simplified_app.cpp pb_rewriter.cpp pb2bv_rewriter.cpp diff --git a/src/ast/simplifier/bit2int.cpp b/src/ast/rewriter/bit2int.cpp similarity index 87% rename from src/ast/simplifier/bit2int.cpp rename to src/ast/rewriter/bit2int.cpp index 6f7dd1cbe..257740412 100644 --- a/src/ast/simplifier/bit2int.cpp +++ b/src/ast/rewriter/bit2int.cpp @@ -19,15 +19,16 @@ Revision History: --*/ -#include "ast/simplifier/bit2int.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" #include "ast/for_each_ast.h" +#include "ast/rewriter/bit2int.h" + #define CHECK(_x_) if (!(_x_)) { UNREACHABLE(); } bit2int::bit2int(ast_manager & m) : - m_manager(m), m_bv_util(m), m_arith_util(m), m_cache(m), m_bit0(m) { + m_manager(m), m_bv_util(m), m_rewriter(m), m_arith_util(m), m_cache(m), m_bit0(m) { m_bit0 = m_bv_util.mk_numeral(0,1); } @@ -67,7 +68,7 @@ unsigned bit2int::get_numeral_bits(numeral const& k) { void bit2int::align_size(expr* e, unsigned sz, expr_ref& result) { unsigned sz1 = m_bv_util.get_bv_size(e); SASSERT(sz1 <= sz); - m_bv_simplifier->mk_zeroext(sz-sz1, e, result); + result = m_rewriter.mk_zero_extend(sz-sz1, e); } void bit2int::align_sizes(expr_ref& a, expr_ref& b) { @@ -75,11 +76,11 @@ void bit2int::align_sizes(expr_ref& a, expr_ref& b) { unsigned sz2 = m_bv_util.get_bv_size(b); expr_ref tmp(m_manager); if (sz1 > sz2) { - m_bv_simplifier->mk_zeroext(sz1-sz2, b, tmp); + tmp = m_rewriter.mk_zero_extend(sz1-sz2, b); b = tmp; } else if (sz2 > sz1) { - m_bv_simplifier->mk_zeroext(sz2-sz1, a, tmp); + tmp = m_rewriter.mk_zero_extend(sz2-sz1, a); a = tmp; } } @@ -123,11 +124,11 @@ bool bit2int::mk_add(expr* e1, expr* e2, expr_ref& result) { return true; } align_sizes(tmp1, tmp2); - m_bv_simplifier->mk_zeroext(1, tmp1, tmp1); - m_bv_simplifier->mk_zeroext(1, tmp2, tmp2); + tmp1 = m_rewriter.mk_zero_extend(1, tmp1); + tmp2 = m_rewriter.mk_zero_extend(1, tmp2); SASSERT(m_bv_util.get_bv_size(tmp1) == m_bv_util.get_bv_size(tmp2)); - m_bv_simplifier->mk_add(tmp1, tmp2, tmp3); - m_bv_simplifier->mk_bv2int(tmp3, m_arith_util.mk_int(), result); + tmp3 = m_rewriter.mk_bv_add(tmp1, tmp2); + result = m_rewriter.mk_bv2int(tmp3); return true; } return false; @@ -143,14 +144,14 @@ bool bit2int::mk_comp(eq_type ty, expr* e1, expr* e2, expr_ref& result) { SASSERT(m_bv_util.get_bv_size(tmp1) == m_bv_util.get_bv_size(tmp2)); switch(ty) { case lt: - m_bv_simplifier->mk_leq_core(false, tmp2, tmp1, tmp3); + tmp3 = m_rewriter.mk_ule(tmp2, tmp1); result = m_manager.mk_not(tmp3); break; case le: - m_bv_simplifier->mk_leq_core(false,tmp1, tmp2, result); + result = m_rewriter.mk_ule(tmp1, tmp2); break; case eq: - result = m_manager.mk_eq(tmp1,tmp2); + result = m_manager.mk_eq(tmp1, tmp2); break; } return true; @@ -167,12 +168,12 @@ bool bit2int::mk_mul(expr* e1, expr* e2, expr_ref& result) { if (extract_bv(e1, sz1, sign1, tmp1) && extract_bv(e2, sz2, sign2, tmp2)) { align_sizes(tmp1, tmp2); - m_bv_simplifier->mk_zeroext(m_bv_util.get_bv_size(tmp1), tmp1, tmp1); - m_bv_simplifier->mk_zeroext(m_bv_util.get_bv_size(tmp2), tmp2, tmp2); + tmp1 = m_rewriter.mk_zero_extend(m_bv_util.get_bv_size(tmp1), tmp1); + tmp2 = m_rewriter.mk_zero_extend(m_bv_util.get_bv_size(tmp2), tmp2); SASSERT(m_bv_util.get_bv_size(tmp1) == m_bv_util.get_bv_size(tmp2)); - m_bv_simplifier->mk_mul(tmp1, tmp2, tmp3); - m_bv_simplifier->mk_bv2int(tmp3, m_arith_util.mk_int(), result); + tmp3 = m_rewriter.mk_bv_mul(tmp1, tmp2); + result = m_rewriter.mk_bv2int(tmp3); if (sign1 != sign2) { result = m_arith_util.mk_uminus(result); } @@ -187,8 +188,7 @@ bool bit2int::is_bv_poly(expr* n, expr_ref& pos, expr_ref& neg) { numeral k; bool is_int; todo.push_back(n); - m_bv_simplifier->mk_bv2int(m_bit0, m_arith_util.mk_int(), pos); - m_bv_simplifier->mk_bv2int(m_bit0, m_arith_util.mk_int(), neg); + neg = pos = m_rewriter.mk_bv2int(m_bit0); while (!todo.empty()) { n = todo.back(); @@ -372,8 +372,8 @@ void bit2int::visit(app* n) { tmp1 = tmp_p; tmp2 = e2bv; align_sizes(tmp1, tmp2); - m_bv_simplifier->mk_bv_urem(tmp1, tmp2, tmp3); - m_bv_simplifier->mk_bv2int(tmp3, m_arith_util.mk_int(), result); + tmp3 = m_rewriter.mk_bv_urem(tmp1, tmp2); + result = m_rewriter.mk_bv2int(tmp3); cache_result(n, result); return; } @@ -382,25 +382,24 @@ void bit2int::visit(app* n) { tmp1 = tmp_n; tmp2 = e2bv; align_sizes(tmp1, tmp2); - m_bv_simplifier->mk_bv_urem(tmp1, tmp2, tmp3); + tmp3 = m_rewriter.mk_bv_urem(tmp1, tmp2); // e2 - (neg1 mod e2) tmp1 = e2bv; tmp2 = tmp3; align_sizes(tmp1, tmp2); - m_bv_simplifier->mk_sub(tmp1, tmp2, tmp3); + tmp3 = m_rewriter.mk_bv_sub(tmp1, tmp2); // pos1 + (e2 - (neg1 mod e2)) tmp1 = tmp_p; tmp2 = tmp3; align_sizes(tmp1, tmp2); - m_bv_simplifier->mk_zeroext(1, tmp1, tmp_p); - m_bv_simplifier->mk_zeroext(1, tmp2, tmp_n); - m_bv_simplifier->mk_add(tmp_p, tmp_n, tmp1); + tmp_p = m_rewriter.mk_zero_extend(1, tmp1); + tmp_n = m_rewriter.mk_zero_extend(1, tmp2); + tmp1 = m_rewriter.mk_bv_add(tmp_p, tmp_n); // (pos1 + (e2 - (neg1 mod e2))) mod e2 tmp2 = e2bv; align_sizes(tmp1, tmp2); - m_bv_simplifier->mk_bv_urem(tmp1, tmp2, tmp3); - - m_bv_simplifier->mk_bv2int(tmp3, m_arith_util.mk_int(), result); + tmp3 = m_rewriter.mk_bv_urem(tmp1, tmp2); + result = m_rewriter.mk_bv2int(tmp3); cache_result(n, result); } diff --git a/src/ast/simplifier/bit2int.h b/src/ast/rewriter/bit2int.h similarity index 90% rename from src/ast/simplifier/bit2int.h rename to src/ast/rewriter/bit2int.h index 84ae1f4a4..fe15d1ec5 100644 --- a/src/ast/simplifier/bit2int.h +++ b/src/ast/rewriter/bit2int.h @@ -22,9 +22,7 @@ Revision History: #include "ast/bv_decl_plugin.h" #include "ast/arith_decl_plugin.h" #include "ast/act_cache.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" - +#include "ast/rewriter/bv_rewriter.h" class bit2int { protected: @@ -60,8 +58,8 @@ protected: typedef act_cache expr_map; ast_manager & m_manager; bv_util m_bv_util; + bv_rewriter m_rewriter; arith_util m_arith_util; - bv_simplifier_plugin * m_bv_simplifier; expr_map m_cache; // map: ast -> ast ref. counters are incremented when inserted here. expr_ref m_bit0; @@ -88,7 +86,6 @@ protected: public: bit2int(ast_manager & m); - void set_bv_simplifier(bv_simplifier_plugin * p) { m_bv_simplifier = p; } void operator()(expr * m, expr_ref & result, proof_ref& p); }; diff --git a/src/ast/rewriter/bv_rewriter.h b/src/ast/rewriter/bv_rewriter.h index 1109251e0..45bd6c264 100644 --- a/src/ast/rewriter/bv_rewriter.h +++ b/src/ast/rewriter/bv_rewriter.h @@ -98,11 +98,10 @@ class bv_rewriter : public poly_rewriter { br_status mk_bv_rotate_right(unsigned n, expr * arg, expr_ref & result); br_status mk_bv_ext_rotate_left(expr * arg1, expr * arg2, expr_ref & result); br_status mk_bv_ext_rotate_right(expr * arg1, expr * arg2, expr_ref & result); + br_status mk_bv_add(expr* a, expr* b, expr_ref& result) { expr* args[2] = { a, b }; return mk_bv_add(2, args, result); } + br_status mk_bv_sub(expr* a, expr* b, expr_ref& result) { expr* args[2] = { a, b }; return mk_sub(2, args, result); } + br_status mk_bv_mul(expr* a, expr* b, expr_ref& result) { expr* args[2] = { a, b }; return mk_bv_mul(2, args, result); } br_status mk_bv_add(unsigned num_args, expr * const * args, expr_ref & result); - br_status mk_bv_add(expr * arg1, expr * arg2, expr_ref & result) { - expr * args[2] = { arg1, arg2 }; - return mk_bv_add(2, args, result); - } br_status mk_bv_mul(unsigned num_args, expr * const * args, expr_ref & result); br_status mk_bv_shl(expr * arg1, expr * arg2, expr_ref & result); br_status mk_bv_lshr(expr * arg1, expr * arg2, expr_ref & result); @@ -185,6 +184,38 @@ public: bool hi_div0() const { return m_hi_div0; } bv_util & get_util() { return m_util; } + +#define MK_BV_BINARY(OP) \ + expr_ref OP(expr* a, expr* b) { \ + expr_ref result(m()); \ + if (BR_FAILED == OP(a, b, result)) \ + result = m_util.OP(a, b); \ + return result; \ + } \ + + expr_ref mk_zero_extend(unsigned n, expr * arg) { + expr_ref result(m()); + if (BR_FAILED == mk_zero_extend(n, arg, result)) + result = m_util.mk_zero_extend(n, arg); + return result; + } + + MK_BV_BINARY(mk_bv_urem); + MK_BV_BINARY(mk_ule); + MK_BV_BINARY(mk_bv_add); + MK_BV_BINARY(mk_bv_mul); + MK_BV_BINARY(mk_bv_sub); + + + expr_ref mk_bv2int(expr* a) { + expr_ref result(m()); + if (BR_FAILED == mk_bv2int(a, result)) + result = m_util.mk_bv2int(a); + return result; + } + + + }; #endif diff --git a/src/ast/simplifier/CMakeLists.txt b/src/ast/simplifier/CMakeLists.txt index b6fe9b1cd..52a44595e 100644 --- a/src/ast/simplifier/CMakeLists.txt +++ b/src/ast/simplifier/CMakeLists.txt @@ -5,7 +5,6 @@ z3_add_component(simplifier array_simplifier_params.cpp array_simplifier_plugin.cpp basic_simplifier_plugin.cpp - bit2int.cpp bv_elim.cpp bv_simplifier_params.cpp bv_simplifier_plugin.cpp diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 8b25e9263..f8efcbf4b 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -33,7 +33,6 @@ Revision History: #include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/simplifier/bv_elim.h" #include "ast/simplifier/elim_bounds.h" -#include "ast/simplifier/bit2int.h" #include "ast/normal_forms/pull_quant.h" #include "ast/normal_forms/nnf.h" #include "ast/pattern/pattern_inference.h" @@ -70,7 +69,6 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): basic_simplifier_plugin * basic_simp = 0; bv_simplifier_plugin * bv_simp = 0; setup_simplifier_plugins(m_pre_simplifier, basic_simp, arith_simp, bv_simp); - m_bit2int.set_bv_simplifier(bv_simp); m_pre_simplifier.enable_presimp(); } @@ -262,7 +260,7 @@ void asserted_formulas::reduce() { INVOKE(m_params.m_propagate_values, propagate_values()); INVOKE(m_params.m_macro_finder && has_quantifiers(), find_macros()); INVOKE(m_params.m_nnf_cnf || (m_params.m_mbqi && has_quantifiers()), nnf_cnf()); - INVOKE(m_params.m_eliminate_and, eliminate_and()); + INVOKE(/*m_params.m_eliminate_and*/ true, eliminate_and()); INVOKE(m_params.m_pull_cheap_ite_trees, pull_cheap_ite_trees()); INVOKE(m_params.m_pull_nested_quantifiers && has_quantifiers(), pull_nested_quantifiers()); INVOKE(m_params.m_ng_lift_ite != LI_NONE, ng_lift_ite()); diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h index eaed4e405..fb621000c 100644 --- a/src/smt/asserted_formulas.h +++ b/src/smt/asserted_formulas.h @@ -24,7 +24,7 @@ Revision History: #include "ast/simplifier/simplifier.h" #include "ast/simplifier/basic_simplifier_plugin.h" #include "ast/simplifier/maximise_ac_sharing.h" -#include "ast/simplifier/bit2int.h" +#include "ast/rewriter/bit2int.h" #include "ast/macros/macro_manager.h" #include "ast/macros/macro_finder.h" #include "ast/normal_forms/defined_names.h" diff --git a/src/smt/elim_term_ite.h b/src/smt/elim_term_ite.h index 94e5e0346..106a9f511 100644 --- a/src/smt/elim_term_ite.h +++ b/src/smt/elim_term_ite.h @@ -59,6 +59,7 @@ public: } virtual ~elim_term_ite_cfg() {} vector const& new_defs() const { return m_new_defs; } + void reset() { m_new_defs.reset(); } br_status reduce_app(func_decl* f, unsigned n, expr *const* args, expr_ref& result, proof_ref& result_pr); }; @@ -70,6 +71,7 @@ public: m_cfg(m, dn) {} vector const& new_defs() const { return m_cfg.new_defs(); } + void reset() { m_cfg.reset(); } }; diff --git a/src/smt/params/preprocessor_params.cpp b/src/smt/params/preprocessor_params.cpp index 9267dbeba..fcdea850f 100644 --- a/src/smt/params/preprocessor_params.cpp +++ b/src/smt/params/preprocessor_params.cpp @@ -46,7 +46,7 @@ void preprocessor_params::display(std::ostream & out) const { DISPLAY_PARAM(m_pull_cheap_ite_trees); DISPLAY_PARAM(m_pull_nested_quantifiers); DISPLAY_PARAM(m_eliminate_term_ite); - DISPLAY_PARAM(m_eliminate_and); + //DISPLAY_PARAM(m_eliminate_and); DISPLAY_PARAM(m_macro_finder); DISPLAY_PARAM(m_propagate_values); DISPLAY_PARAM(m_propagate_booleans); diff --git a/src/smt/params/preprocessor_params.h b/src/smt/params/preprocessor_params.h index c343c55fa..fe759417d 100644 --- a/src/smt/params/preprocessor_params.h +++ b/src/smt/params/preprocessor_params.h @@ -39,7 +39,7 @@ struct preprocessor_params : public pattern_inference_params, bool m_pull_cheap_ite_trees; bool m_pull_nested_quantifiers; bool m_eliminate_term_ite; - bool m_eliminate_and; // represent (and a b) as (not (or (not a) (not b))) +// bool m_eliminate_and; // represent (and a b) as (not (or (not a) (not b))) bool m_macro_finder; bool m_propagate_values; bool m_propagate_booleans; @@ -62,7 +62,7 @@ public: m_pull_cheap_ite_trees(false), m_pull_nested_quantifiers(false), m_eliminate_term_ite(false), - m_eliminate_and(true), + // m_eliminate_and(true), m_macro_finder(false), m_propagate_values(true), m_propagate_booleans(false), // TODO << check peformance From d3c00181ba526f92c5120b30509839b7eeb30613 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 25 Aug 2017 23:56:31 -0700 Subject: [PATCH 197/488] remove simplify dependencies Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/bv_elim2.cpp | 115 +++++++++++++++++ src/ast/rewriter/bv_elim2.h | 50 ++++++++ src/ast/rewriter/elim_bounds2.cpp | 203 ++++++++++++++++++++++++++++++ src/ast/rewriter/elim_bounds2.h | 77 ++++++++++++ 4 files changed, 445 insertions(+) create mode 100644 src/ast/rewriter/bv_elim2.cpp create mode 100644 src/ast/rewriter/bv_elim2.h create mode 100644 src/ast/rewriter/elim_bounds2.cpp create mode 100644 src/ast/rewriter/elim_bounds2.h diff --git a/src/ast/rewriter/bv_elim2.cpp b/src/ast/rewriter/bv_elim2.cpp new file mode 100644 index 000000000..5b542e59e --- /dev/null +++ b/src/ast/rewriter/bv_elim2.cpp @@ -0,0 +1,115 @@ + +/*++ +Copyright (c) 2015 Microsoft Corporation + +--*/ + +#include "ast/rewriter/bv_elim2.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/var_subst.h" +#include "ast/rewriter/rewriter_def.h" +#include + +bool bv_elim_cfg::reduce_quantifier(quantifier * q, + expr * body, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr) { + + + svector names, _names; + sort_ref_buffer sorts(m), _sorts(m); + expr_ref_buffer pats(m); + expr_ref_buffer no_pats(m); + expr_ref_buffer subst_map(m), _subst_map(m); + var_subst subst(m); + bv_util bv(m); + expr_ref new_body(m); + expr* old_body = body; + unsigned num_decls = q->get_num_decls(); + family_id bfid = m.mk_family_id("bv"); + + // + // Traverse sequence of bound variables to eliminate + // bit-vecctor variables and replace them by + // Booleans. + // + unsigned var_idx = 0; + bool found = false; + for (unsigned i = num_decls; i > 0; ) { + --i; + sort* s = q->get_decl_sort(i); + symbol nm = q->get_decl_name(i); + + if (bv.is_bv_sort(s)) { + // convert n-bit bit-vector variable into sequence of n-Booleans. + unsigned num_bits = bv.get_bv_size(s); + expr_ref_buffer args(m); + expr_ref bv(m); + found = true; + for (unsigned j = 0; j < num_bits; ++j) { + std::ostringstream new_name; + new_name << nm.str(); + new_name << "_"; + new_name << j; + var* v = m.mk_var(var_idx++, m.mk_bool_sort()); + args.push_back(v); + _sorts.push_back(m.mk_bool_sort()); + _names.push_back(symbol(new_name.str().c_str())); + } + bv = m.mk_app(bfid, OP_MKBV, 0, 0, args.size(), args.c_ptr()); + _subst_map.push_back(bv.get()); + } + else { + _subst_map.push_back(m.mk_var(var_idx++, s)); + _sorts.push_back(s); + _names.push_back(nm); + } + } + if (!found) { + return false; + } + // + // reverse the vectors. + // + SASSERT(_names.size() == _sorts.size()); + for (unsigned i = _names.size(); i > 0; ) { + --i; + names.push_back(_names[i]); + sorts.push_back(_sorts[i]); + } + for (unsigned i = _subst_map.size(); i > 0; ) { + --i; + subst_map.push_back(_subst_map[i]); + } + + expr* const* sub = subst_map.c_ptr(); + unsigned sub_size = subst_map.size(); + + subst(old_body, sub_size, sub, new_body); + + for (unsigned j = 0; j < q->get_num_patterns(); j++) { + expr_ref pat(m); + subst(new_patterns[j], sub_size, sub, pat); + pats.push_back(pat); + } + for (unsigned j = 0; j < q->get_num_no_patterns(); j++) { + expr_ref nopat(m); + subst(new_no_patterns[j], sub_size, sub, nopat); + no_pats.push_back(nopat); + } + + result = m.mk_quantifier(true, + names.size(), + sorts.c_ptr(), + names.c_ptr(), + new_body.get(), + q->get_weight(), + q->get_qid(), + q->get_skid(), + pats.size(), pats.c_ptr(), + no_pats.size(), no_pats.c_ptr()); + result_pr = m.mk_rewrite(q, result); + return true; +} diff --git a/src/ast/rewriter/bv_elim2.h b/src/ast/rewriter/bv_elim2.h new file mode 100644 index 000000000..a4829b207 --- /dev/null +++ b/src/ast/rewriter/bv_elim2.h @@ -0,0 +1,50 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + bv_elim.h + +Abstract: + + Eliminate bit-vectors variables from clauses, by + replacing them by bound Boolean variables. + +Author: + + Nikolaj Bjorner (nbjorner) 2008-12-16. + +Revision History: + +--*/ +#ifndef BV_ELIM2_H_ +#define BV_ELIM2_H_ + +#include "ast/ast.h" +#include "ast/rewriter/rewriter.h" + +class bv_elim_cfg : public default_rewriter_cfg { + ast_manager& m; +public: + bv_elim_cfg(ast_manager& m) : m(m) {} + + bool reduce_quantifier(quantifier * old_q, + expr * new_body, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr); +}; + +class bv_elim_rw : public rewriter_tpl { +protected: + bv_elim_cfg m_cfg; +public: + bv_elim_rw(ast_manager & m): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m) + {} +}; + +#endif /* BV_ELIM_H_ */ + diff --git a/src/ast/rewriter/elim_bounds2.cpp b/src/ast/rewriter/elim_bounds2.cpp new file mode 100644 index 000000000..9691ade09 --- /dev/null +++ b/src/ast/rewriter/elim_bounds2.cpp @@ -0,0 +1,203 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + elim_bounds2.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-28. + +Revision History: + +--*/ + +#ifndef ELIM_BOUNDS_H_ +#define ELIM_BOUNDS_H_ + +#include "ast/used_vars.h" +#include "util/obj_hashtable.h" +#include "ast/rewriter/var_subst.h" +#include "ast/rewriter/elim_bounds2.h" +#include "ast/ast_pp.h" + +elim_bounds_cfg::elim_bounds_cfg(ast_manager & m): + m(m), + m_util(m) { +} + +/** + \brief Find bounds of the form + + (<= x k) + (<= (+ x (* -1 y)) k) + (<= (+ x (* -1 t)) k) + (<= (+ t (* -1 x)) k) + + x and y are a bound variables, t is a ground term and k is a numeral + + It also detects >=, and the atom can be negated. +*/ +bool elim_bounds_cfg::is_bound(expr * n, var * & lower, var * & upper) { + upper = 0; + lower = 0; + bool neg = false; + if (m.is_not(n)) { + n = to_app(n)->get_arg(0); + neg = true; + } + + expr* l = 0, *r = 0; + bool le = false; + if (m_util.is_le(n, l, r) && m_util.is_numeral(r)) { + n = l; + le = true; + } + else if (m_util.is_ge(n, l, r) && m_util.is_numeral(r)) { + n = l; + le = false; + } + else { + return false; + } + + if (neg) + le = !le; + + if (is_var(n)) { + upper = to_var(n); + } + else if (m_util.is_add(n, l, r)) { + expr * arg1 = l; + expr * arg2 = r; + if (is_var(arg1)) + upper = to_var(arg1); + else if (!is_ground(arg1)) + return false; + rational k; + bool is_int; + if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) { + arg2 = to_app(arg2)->get_arg(1); + if (is_var(arg2)) + lower = to_var(arg2); + else if (!is_ground(arg2)) + return false; // not supported + } + else { + return false; // not supported + } + } + else { + return false; + } + + if (!le) + std::swap(upper, lower); + + return true; +} + +bool elim_bounds_cfg::is_bound(expr * n) { + var * lower, * upper; + return is_bound(n, lower, upper); +} + + +bool elim_bounds_cfg::reduce_quantifier(quantifier * q, + expr * n, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr) { + if (!q->is_forall()) { + return false; + } + unsigned num_vars = q->get_num_decls(); + ptr_buffer atoms; + if (m.is_or(n)) + atoms.append(to_app(n)->get_num_args(), to_app(n)->get_args()); + else + atoms.push_back(n); + used_vars used_vars; + // collect non-candidates + for (expr * a : atoms) { + if (!is_bound(a)) + used_vars.process(a); + } + if (used_vars.uses_all_vars(q->get_num_decls())) { + return false; + } + // collect candidates + obj_hashtable lowers; + obj_hashtable uppers; + obj_hashtable candidate_set; + ptr_buffer candidates; +#define ADD_CANDIDATE(V) if (!lowers.contains(V) && !uppers.contains(V)) { candidate_set.insert(V); candidates.push_back(V); } + for (expr * a : atoms) { + var * lower = 0; + var * upper = 0; + if (is_bound(a, lower, upper)) { + if (lower != 0 && !used_vars.contains(lower->get_idx()) && lower->get_idx() < num_vars) { + ADD_CANDIDATE(lower); + lowers.insert(lower); + } + if (upper != 0 && !used_vars.contains(upper->get_idx()) && upper->get_idx() < num_vars) { + ADD_CANDIDATE(upper); + uppers.insert(upper); + } + } + } + TRACE("elim_bounds", tout << "candidates:\n"; for (unsigned i = 0; i < candidates.size(); i++) tout << mk_pp(candidates[i], m) << "\n";); + // remove candidates that have lower and upper bounds + + for (var * v : candidates) { + if (lowers.contains(v) && uppers.contains(v)) + candidate_set.erase(v); + } + TRACE("elim_bounds", tout << "candidates after filter:\n"; for (unsigned i = 0; i < candidates.size(); i++) tout << mk_pp(candidates[i], m) << "\n";); + if (candidate_set.empty()) { + return false; + } + // remove bounds that contain variables in candidate_set + unsigned j = 0; + for (unsigned i = 0; i < atoms.size(); ++i) { + expr * a = atoms[i]; + var * lower = 0; + var * upper = 0; + if (is_bound(a, lower, upper) && ((lower != 0 && candidate_set.contains(lower)) || (upper != 0 && candidate_set.contains(upper)))) + continue; + atoms[j] = a; + j++; + } + if (j == atoms.size()) { + return false; + } + atoms.resize(j); + expr * new_body = 0; + switch (atoms.size()) { + case 0: + result = m.mk_false(); + result_pr = m.mk_rewrite(q, result); + TRACE("elim_bounds", tout << mk_pp(q, m) << "\n" << result << "\n";); + return true; + case 1: + new_body = atoms[0]; + break; + default: + new_body = m.mk_or(atoms.size(), atoms.c_ptr()); + break; + } + quantifier_ref new_q(m); + new_q = m.update_quantifier(q, new_body); + elim_unused_vars(m, new_q, params_ref(), result); + result_pr = m.mk_rewrite(q, result); + TRACE("elim_bounds", tout << mk_pp(q, m) << "\n" << result << "\n";); + return true; +} + +#endif /* ELIM_BOUNDS_H_ */ diff --git a/src/ast/rewriter/elim_bounds2.h b/src/ast/rewriter/elim_bounds2.h new file mode 100644 index 000000000..0d3b026cf --- /dev/null +++ b/src/ast/rewriter/elim_bounds2.h @@ -0,0 +1,77 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + elim_bounds2.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-28. + +Revision History: + +--*/ +#ifndef ELIM_BOUNDS2_H_ +#define ELIM_BOUNDS2_H_ + +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/rewrite.h" + +/** + \brief Functor for eliminating irrelevant bounds in quantified formulas. + + Example: + (forall (x Int) (y Int) (or (not (>= y x) (not (>= x 0)) (= (select a x) 1)))) + + The bound (>= y x) is irrelevant and can be eliminated. + + This can be easily proved by using Fourier-Motzkin elimination. + + Limitations & Assumptions: + - It assumes the input formula was already simplified. + - It can only handle bounds in the diff-logic fragment. + + \remark This operation is subsumed by Fourier-Motzkin elimination. +*/ +class elim_bounds_cfg : public default_rewriter_cfg { + ast_manager & m; + arith_util m_util; + bool is_bound(expr * n, var * & lower, var * & upper); + bool is_bound(expr * n); +public: + elim_bounds_cfg(ast_manager & m); + + bool reduce_quantifier(quantifier * old_q, + expr * new_body, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr); +}; + +/** + \brief Functor for applying elim_bounds2 in all + universal quantifiers in an expression. + + Assumption: the formula was already skolemized. +*/ +class elim_bounds_rw : public rewriter_tpl { +protected: + elim_bounds_cfg m_cfg; +public: + elim_bounds_rw(ast_manager & m): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m) + {} + + virtual ~elim_bounds_rw() {} +}; + +#endif /* ELIM_BOUNDS2_H_ */ + From b16a4ac4528d4b9399b5eb7b728e22e0df86b1c0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 25 Aug 2017 23:57:10 -0700 Subject: [PATCH 198/488] remove simplify dependencies Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/elim_bounds2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/rewriter/elim_bounds2.h b/src/ast/rewriter/elim_bounds2.h index 0d3b026cf..e0bba4e60 100644 --- a/src/ast/rewriter/elim_bounds2.h +++ b/src/ast/rewriter/elim_bounds2.h @@ -21,7 +21,7 @@ Revision History: #include "ast/ast.h" #include "ast/arith_decl_plugin.h" -#include "ast/rewriter/rewrite.h" +#include "ast/rewriter/rewriter.h" /** \brief Functor for eliminating irrelevant bounds in quantified formulas. From 2897b98ed2b712d0fec4ee84b4776830efed1f7c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 00:37:22 -0700 Subject: [PATCH 199/488] remove simplify dependencies Signed-off-by: Nikolaj Bjorner --- src/muz/bmc/dl_bmc_engine.cpp | 2 +- src/muz/pdr/pdr_smt_context_manager.cpp | 2 +- src/muz/spacer/spacer_virtual_solver.cpp | 4 ++-- src/opt/opt_solver.cpp | 4 ++-- src/smt/asserted_formulas.cpp | 1 + src/smt/asserted_formulas.h | 5 ++++- src/smt/qi_queue.cpp | 2 +- src/smt/smt_context.cpp | 23 ++--------------------- src/smt/smt_context.h | 14 ++++++-------- src/smt/smt_kernel.cpp | 16 ++++++++++------ src/smt/smt_kernel.h | 7 ++++++- src/smt/smt_quick_checker.cpp | 4 ++-- src/smt/smt_quick_checker.h | 4 ++-- src/smt/smt_setup.cpp | 12 +++++++++--- src/smt/smt_solver.cpp | 2 +- src/smt/theory_arith_core.h | 2 +- src/smt/theory_arith_int.h | 3 +-- src/smt/theory_arith_nl.h | 2 +- src/smt/theory_array_full.cpp | 9 ++++----- src/smt/theory_array_full.h | 3 --- src/smt/theory_bv.cpp | 9 ++++----- src/smt/theory_bv.h | 10 ---------- src/smt/theory_fpa.cpp | 2 +- 23 files changed, 62 insertions(+), 80 deletions(-) diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index 0f7914e0c..6d2f88019 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -1139,7 +1139,7 @@ namespace datalog { md->eval(path, path); IF_VERBOSE(2, verbose_stream() << mk_pp(trace, m) << "\n"; for (unsigned i = 0; i < b.m_solver.size(); ++i) { - verbose_stream() << mk_pp(b.m_solver.get_formulas()[i], m) << "\n"; + verbose_stream() << mk_pp(b.m_solver.get_formula(i), m) << "\n"; }); scoped_proof _sp(m); proof_ref pr(m); diff --git a/src/muz/pdr/pdr_smt_context_manager.cpp b/src/muz/pdr/pdr_smt_context_manager.cpp index e912bd658..b87d1e451 100644 --- a/src/muz/pdr/pdr_smt_context_manager.cpp +++ b/src/muz/pdr/pdr_smt_context_manager.cpp @@ -83,7 +83,7 @@ namespace pdr { { ast_smt_pp pp(m); for (unsigned i = 0; i < m_context.size(); ++i) { - pp.add_assumption(m_context.get_formulas()[i]); + pp.add_assumption(m_context.get_formula(i)); } for (unsigned i = 0; i < assumptions.size(); ++i) { pp.add_assumption(assumptions[i].get()); diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp index c080fa2c4..ebaef14f0 100644 --- a/src/muz/spacer/spacer_virtual_solver.cpp +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -318,7 +318,7 @@ lbool virtual_solver::check_sat_core(unsigned num_assumptions, stopwatch sw2; smt::kernel kernel(m, p); for (unsigned i = 0, sz = m_context.size(); i < sz; ++i) - { kernel.assert_expr(m_context.get_formulas()[i]); } + { kernel.assert_expr(m_context.get_formula(i)); } sw2.start(); kernel.check(num_assumptions, assumptions); sw2.stop(); @@ -450,7 +450,7 @@ void virtual_solver::to_smt2_benchmark(std::ostream &out, for (unsigned i = 0, sz = context.size(); i < sz; ++i) { - asserts.push_back(context.get_formulas()[i]); + asserts.push_back(context.get_formula(i)); pp.collect(asserts.back()); } pp.collect(num_assumptions, assumptions); diff --git a/src/opt/opt_solver.cpp b/src/opt/opt_solver.cpp index f453d9fe2..69b62083f 100644 --- a/src/opt/opt_solver.cpp +++ b/src/opt/opt_solver.cpp @@ -161,7 +161,7 @@ namespace opt { TRACE("opt_verbose", { tout << "context size: " << m_context.size() << "\n"; for (unsigned i = 0; i < m_context.size(); ++i) { - tout << mk_pp(m_context.get_formulas()[i], m_context.m()) << "\n"; + tout << mk_pp(m_context.get_formula(i), m_context.m()) << "\n"; } }); stopwatch w; @@ -330,7 +330,7 @@ namespace opt { expr * opt_solver::get_assertion(unsigned idx) const { SASSERT(idx < get_num_assertions()); - return m_context.get_formulas()[idx]; + return m_context.get_formula(idx); } smt::theory_var opt_solver::add_objective(app* term) { diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index f8efcbf4b..3fb20d283 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -47,6 +47,7 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m_params(p), m_pre_simplifier(m), m_simplifier(m), + m_rewriter(m), m_defined_names(m), m_static_features(m), m_asserted_formulas(m), diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h index fb621000c..3c5f424fb 100644 --- a/src/smt/asserted_formulas.h +++ b/src/smt/asserted_formulas.h @@ -30,6 +30,7 @@ Revision History: #include "ast/normal_forms/defined_names.h" #include "ast/pattern/pattern_inference.h" #include "smt/params/smt_params.h" +#include "ast/rewriter/th_rewriter.h" class arith_simplifier_plugin; class bv_simplifier_plugin; @@ -39,6 +40,7 @@ class asserted_formulas { smt_params & m_params; simplifier m_pre_simplifier; simplifier m_simplifier; + th_rewriter m_rewriter; basic_simplifier_plugin * m_bsimp; bv_simplifier_plugin * m_bvsimp; defined_names m_defined_names; @@ -121,7 +123,8 @@ public: proof * const * get_formula_proofs() const { return m_asserted_formula_prs.c_ptr(); } void init(unsigned num_formulas, expr * const * formulas, proof * const * prs); void register_simplifier_plugin(simplifier_plugin * p) { m_simplifier.register_plugin(p); } - simplifier & get_simplifier() { return m_simplifier; } + // simplifier & get_simplifier() { return m_simplifier; } + th_rewriter& get_rewriter() { return m_rewriter; } void get_assertions(ptr_vector & result); bool empty() const { return m_asserted_formulas.empty(); } void collect_static_features(); diff --git a/src/smt/qi_queue.cpp b/src/smt/qi_queue.cpp index 36a2ce834..8f8e3df7b 100644 --- a/src/smt/qi_queue.cpp +++ b/src/smt/qi_queue.cpp @@ -227,7 +227,7 @@ namespace smt { TRACE("qi_queue_instance", tout << "new instance:\n" << mk_pp(instance, m_manager) << "\n";); expr_ref s_instance(m_manager); proof_ref pr(m_manager); - simplifier & simp = m_context.get_simplifier(); + th_rewriter & simp = m_context.get_rewriter(); simp(instance, s_instance, pr); TRACE("qi_queue_bug", tout << "new instance after simplification:\n" << mk_pp(s_instance, m_manager) << "\n";); if (m_manager.is_true(s_instance)) { diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index b966b8380..7b92bdd28 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -148,8 +148,8 @@ namespace smt { dst_ctx.set_logic(src_ctx.m_setup.get_logic()); dst_ctx.copy_plugins(src_ctx, dst_ctx); - asserted_formulas& src_af = src_ctx.m_asserted_formulas; - asserted_formulas& dst_af = dst_ctx.m_asserted_formulas; + asserted_formulas_new& src_af = src_ctx.m_asserted_formulas; + asserted_formulas_new& dst_af = dst_ctx.m_asserted_formulas; // Copy asserted formulas. for (unsigned i = 0; i < src_af.get_num_formulas(); ++i) { @@ -224,20 +224,6 @@ namespace smt { void context::copy_plugins(context& src, context& dst) { - // copy missing simplifier_plugins - // remark: some simplifier_plugins are automatically created by the asserted_formulas class. - simplifier & src_s = src.get_simplifier(); - simplifier & dst_s = dst.get_simplifier(); - ptr_vector::const_iterator it1 = src_s.begin_plugins(); - ptr_vector::const_iterator end1 = src_s.end_plugins(); - for (; it1 != end1; ++it1) { - simplifier_plugin * p = *it1; - if (dst_s.get_plugin(p->get_family_id()) == 0) { - dst.register_plugin(p->mk_fresh()); - } - SASSERT(dst_s.get_plugin(p->get_family_id()) != 0); - } - // copy theory plugins for (theory* old_th : src.m_theory_set) { theory * new_th = old_th->mk_fresh(&dst); @@ -2845,11 +2831,6 @@ namespace smt { return false; } - void context::register_plugin(simplifier_plugin * s) { - SASSERT(!already_internalized()); - SASSERT(m_scope_lvl == 0); - m_asserted_formulas.register_simplifier_plugin(s); - } #ifdef Z3DEBUG /** diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index fecb42700..fbf7cbca3 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -36,7 +36,7 @@ Revision History: #include "smt/smt_case_split_queue.h" #include "smt/smt_almost_cg_table.h" #include "smt/smt_failure.h" -#include "smt/asserted_formulas.h" +#include "smt/asserted_formulas_new.h" #include "smt/smt_types.h" #include "smt/dyn_ack.h" #include "ast/ast_smt_pp.h" @@ -81,7 +81,7 @@ namespace smt { params_ref m_params; setup m_setup; timer m_timer; - asserted_formulas m_asserted_formulas; + asserted_formulas_new m_asserted_formulas; scoped_ptr m_qmanager; scoped_ptr m_model_generator; scoped_ptr m_relevancy_propagator; @@ -245,8 +245,8 @@ namespace smt { return m_manager; } - simplifier & get_simplifier() { - return m_asserted_formulas.get_simplifier(); + th_rewriter & get_rewriter() { + return m_asserted_formulas.get_rewriter(); } smt_params & get_fparams() { @@ -1467,8 +1467,6 @@ namespace smt { bool set_logic(symbol const& logic) { return m_setup.set_logic(logic); } - void register_plugin(simplifier_plugin * s); - void register_plugin(theory * th); void assert_expr(expr * e); @@ -1540,9 +1538,9 @@ namespace smt { proof * get_asserted_formula_proof(unsigned idx) const { return m_asserted_formulas.get_formula_proof(idx); } - expr * const * get_asserted_formulas() const { return m_asserted_formulas.get_formulas(); } + void get_asserted_formulas(ptr_vector& r) const { m_asserted_formulas.get_assertions(r); } - proof * const * get_asserted_formula_proofs() const { return m_asserted_formulas.get_formula_proofs(); } + //proof * const * get_asserted_formula_proofs() const { return m_asserted_formulas.get_formula_proofs(); } void get_assumptions_core(ptr_vector & result); diff --git a/src/smt/smt_kernel.cpp b/src/smt/smt_kernel.cpp index e4ce30f91..a7948725c 100644 --- a/src/smt/smt_kernel.cpp +++ b/src/smt/smt_kernel.cpp @@ -60,10 +60,10 @@ namespace smt { // m_kernel.display(out); <<< for external users it is just junk // TODO: it will be replaced with assertion_stack.display unsigned num = m_kernel.get_num_asserted_formulas(); - expr * const * fms = m_kernel.get_asserted_formulas(); out << "(kernel"; for (unsigned i = 0; i < num; i++) { - out << "\n " << mk_ismt2_pp(fms[i], m(), 2); + expr* f = m_kernel.get_asserted_formula(i); + out << "\n " << mk_ismt2_pp(f, m(), 2); } out << ")"; } @@ -81,8 +81,12 @@ namespace smt { return m_kernel.get_num_asserted_formulas(); } - expr * const * get_formulas() const { - return m_kernel.get_asserted_formulas(); + void get_formulas(ptr_vector& fmls) const { + m_kernel.get_asserted_formulas(fmls); + } + + expr* get_formula(unsigned i) const { + return m_kernel.get_asserted_formula(i); } void push() { @@ -241,8 +245,8 @@ namespace smt { return m_imp->size(); } - expr * const * kernel::get_formulas() const { - return m_imp->get_formulas(); + expr* kernel::get_formula(unsigned i) const { + return m_imp->get_formula(i); } diff --git a/src/smt/smt_kernel.h b/src/smt/smt_kernel.h index 6ebb8546f..d10cab4f3 100644 --- a/src/smt/smt_kernel.h +++ b/src/smt/smt_kernel.h @@ -85,7 +85,12 @@ namespace smt { /** \brief Return the array of asserted formulas. */ - expr * const * get_formulas() const; + void get_formulas(ptr_vector& r) const; + + /** + \brief return the formula at index idx. + */ + expr* get_formula(unsigned idx) const; /** \brief Create a backtracking point (aka scope level). diff --git a/src/smt/smt_quick_checker.cpp b/src/smt/smt_quick_checker.cpp index f8744318a..773768944 100644 --- a/src/smt/smt_quick_checker.cpp +++ b/src/smt/smt_quick_checker.cpp @@ -164,7 +164,7 @@ namespace smt { quick_checker::quick_checker(context & c): m_context(c), m_manager(c.get_manager()), - m_simplifier(c.get_simplifier()), + m_simplifier(c.get_rewriter()), m_collector(c), m_new_exprs(m_manager) { } @@ -411,7 +411,7 @@ namespace smt { } } expr_ref new_expr(m_manager); - m_simplifier.mk_app(to_app(n)->get_decl(), num_args, new_args.c_ptr(), new_expr); + new_expr = m_simplifier.mk_app(to_app(n)->get_decl(), num_args, new_args.c_ptr()); m_new_exprs.push_back(new_expr); m_canonize_cache.insert(n, new_expr); return new_expr; diff --git a/src/smt/smt_quick_checker.h b/src/smt/smt_quick_checker.h index eb07880f1..d07e10921 100644 --- a/src/smt/smt_quick_checker.h +++ b/src/smt/smt_quick_checker.h @@ -20,7 +20,7 @@ Revision History: #define SMT_QUICK_CHECKER_H_ #include "ast/ast.h" -#include "ast/simplifier/simplifier.h" +#include "ast/rewriter/th_rewriter.h" #include "util/obj_hashtable.h" namespace smt { @@ -77,7 +77,7 @@ namespace smt { context & m_context; ast_manager & m_manager; - simplifier & m_simplifier; + th_rewriter & m_simplifier; collector m_collector; expr_ref_vector m_new_exprs; vector m_candidate_vectors; diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index a37668c7b..f0c44a574 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -142,7 +142,9 @@ namespace smt { } else { IF_VERBOSE(100, verbose_stream() << "(smt.collecting-features)\n";); - st.collect(m_context.get_num_asserted_formulas(), m_context.get_asserted_formulas()); + ptr_vector fmls; + m_context.get_asserted_formulas(fmls); + st.collect(fmls.size(), fmls.c_ptr()); IF_VERBOSE(1000, st.display_primitive(verbose_stream());); if (m_logic == "QF_UF") setup_QF_UF(st); @@ -742,7 +744,9 @@ namespace smt { void setup::setup_arith() { static_features st(m_manager); IF_VERBOSE(100, verbose_stream() << "(smt.collecting-features)\n";); - st.collect(m_context.get_num_asserted_formulas(), m_context.get_asserted_formulas()); + ptr_vector fmls; + m_context.get_asserted_formulas(fmls); + st.collect(fmls.size(), fmls.c_ptr()); IF_VERBOSE(1000, st.display_primitive(verbose_stream());); bool fixnum = st.arith_k_sum_is_small() && m_params.m_arith_fixnum; bool int_only = !st.m_has_rational && !st.m_has_real && m_params.m_arith_int_only; @@ -877,7 +881,9 @@ namespace smt { void setup::setup_unknown() { static_features st(m_manager); - st.collect(m_context.get_num_asserted_formulas(), m_context.get_asserted_formulas()); + ptr_vector fmls; + m_context.get_asserted_formulas(fmls); + st.collect(fmls.size(), fmls.c_ptr()); TRACE("setup", tout << "setup_unknown\n";); setup_arith(); setup_arrays(); diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index ba86f017a..9d86436d9 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -216,7 +216,7 @@ namespace smt { virtual expr * get_assertion(unsigned idx) const { SASSERT(idx < get_num_assertions()); - return m_context.get_formulas()[idx]; + return m_context.get_formula(idx); } struct collect_fds_proc { diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index a30e51133..70355502d 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -442,7 +442,7 @@ namespace smt { void theory_arith::mk_axiom(expr * ante, expr * conseq) { ast_manager & m = get_manager(); context & ctx = get_context(); - simplifier & s = ctx.get_simplifier(); + th_rewriter & s = ctx.get_rewriter(); expr_ref s_ante(m), s_conseq(m); expr* s_conseq_n, * s_ante_n; bool negated; diff --git a/src/smt/theory_arith_int.h b/src/smt/theory_arith_int.h index d93e062f4..fbcc9c11a 100644 --- a/src/smt/theory_arith_int.h +++ b/src/smt/theory_arith_int.h @@ -455,9 +455,8 @@ namespace smt { pol = m_util.mk_add(_args.size(), _args.c_ptr()); result = m_util.mk_ge(pol, m_util.mk_numeral(k, all_int)); TRACE("arith_mk_polynomial", tout << "before simplification:\n" << result << "\n";); - simplifier & s = get_context().get_simplifier(); proof_ref pr(m); - s(result, result, pr); + get_context().get_rewriter()(result, result, pr); TRACE("arith_mk_polynomial", tout << "after simplification:\n" << result << "\n";); SASSERT(is_well_sorted(get_manager(), result)); } diff --git a/src/smt/theory_arith_nl.h b/src/smt/theory_arith_nl.h index 9649440d2..a04c34706 100644 --- a/src/smt/theory_arith_nl.h +++ b/src/smt/theory_arith_nl.h @@ -2205,7 +2205,7 @@ namespace smt { args.push_back(monomial2expr(eq->get_monomial(i), is_int)); } context & ctx = get_context(); - simplifier & s = ctx.get_simplifier(); + th_rewriter& s = ctx.get_rewriter(); expr_ref pol(get_manager()); SASSERT(!args.empty()); pol = mk_nary_add(args.size(), args.c_ptr()); diff --git a/src/smt/theory_array_full.cpp b/src/smt/theory_array_full.cpp index d5660e325..c7a3d7920 100644 --- a/src/smt/theory_array_full.cpp +++ b/src/smt/theory_array_full.cpp @@ -21,6 +21,7 @@ Revision History: #include "smt/theory_array_full.h" #include "ast/ast_ll_pp.h" #include "ast/ast_pp.h" +#include "ast/ast_util.h" #include "ast/ast_smt2_pp.h" #include "util/stats.h" @@ -515,7 +516,7 @@ namespace smt { expr_ref sel1(m), sel2(m); sel1 = mk_select(args1.size(), args1.c_ptr()); - m_simp->mk_app(f, args2.size(), args2.c_ptr(), sel2); + sel2 = ctx.get_rewriter().mk_app(f, args2.size(), args2.c_ptr()); ctx.internalize(sel1, false); ctx.internalize(sel2, false); @@ -553,7 +554,7 @@ namespace smt { expr* def1 = mk_default(map); expr_ref def2(get_manager()); - m_simp->mk_app(f, args2.size(), args2.c_ptr(), def2); + def2 = ctx.get_rewriter().mk_app(f, args2.size(), args2.c_ptr()); ctx.internalize(def1, false); ctx.internalize(def2, false); return try_assign_eq(def1, def2); @@ -722,9 +723,7 @@ namespace smt { } expr_ref eq(m); - simplifier_plugin* p = m_simp->get_plugin(m.get_basic_family_id()); - basic_simplifier_plugin* bp = static_cast(p); - bp->mk_and(eqs.size(), eqs.c_ptr(), eq); + eq = mk_and(eqs); expr* defA = mk_default(store_app->get_arg(0)); def2 = m.mk_ite(eq, store_app->get_arg(num_args-1), defA); #if 0 diff --git a/src/smt/theory_array_full.h b/src/smt/theory_array_full.h index e22d1d0e2..2cad3acbd 100644 --- a/src/smt/theory_array_full.h +++ b/src/smt/theory_array_full.h @@ -20,7 +20,6 @@ Revision History: #define THEORY_ARRAY_FULL_H_ #include "smt/theory_array.h" -#include "ast/simplifier/simplifier.h" #include "ast/ast_trail.h" namespace smt { @@ -37,7 +36,6 @@ namespace smt { ptr_vector m_var_data_full; ast2ast_trailmap m_sort2epsilon; - simplifier* m_simp; obj_pair_map m_eqs; svector m_eqsv; @@ -100,7 +98,6 @@ namespace smt { // the parent class is theory_array. // theory::init(ctx); theory_array::init(ctx); - m_simp = &ctx->get_simplifier(); } }; diff --git a/src/smt/theory_bv.cpp b/src/smt/theory_bv.cpp index 0981ccdbf..ec3913415 100644 --- a/src/smt/theory_bv.cpp +++ b/src/smt/theory_bv.cpp @@ -28,7 +28,6 @@ namespace smt { void theory_bv::init(context * ctx) { theory::init(ctx); - m_simplifier = &(ctx->get_simplifier()); } theory_var theory_bv::mk_var(enode * n) { @@ -300,7 +299,7 @@ namespace smt { void theory_bv::simplify_bit(expr * s, expr_ref & r) { // proof_ref p(get_manager()); // if (get_context().at_base_level()) - // m_simplifier->operator()(s, r, p); + // ctx.get_rewriter()(s, r, p); // else r = s; } @@ -605,8 +604,9 @@ namespace smt { args.push_back(m.mk_ite(b, n, zero)); num *= numeral(2); } - expr_ref sum(m); - arith_simp().mk_add(sz, args.c_ptr(), sum); + expr_ref sum(m_autil.mk_add(sz, args.c_ptr()), m); + arith_rewriter arw(m); + ctx.get_rewriter()(sum); literal l(mk_eq(n, sum, false)); TRACE("bv", tout << mk_pp(n, m) << "\n"; @@ -1366,7 +1366,6 @@ namespace smt { m_params(params), m_util(m), m_autil(m), - m_simplifier(0), m_bb(m, bb_params), m_trail_stack(*this), m_find(*this), diff --git a/src/smt/theory_bv.h b/src/smt/theory_bv.h index 5d2ea8da5..c35078ace 100644 --- a/src/smt/theory_bv.h +++ b/src/smt/theory_bv.h @@ -24,10 +24,7 @@ Revision History: #include "ast/rewriter/bit_blaster/bit_blaster.h" #include "util/trail.h" #include "util/union_find.h" -#include "ast/simplifier/simplifier.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/arith_decl_plugin.h" -#include "ast/simplifier/arith_simplifier_plugin.h" #include "smt/proto_model/numeral_factory.h" namespace smt { @@ -112,7 +109,6 @@ namespace smt { theory_bv_params const & m_params; bv_util m_util; arith_util m_autil; - simplifier * m_simplifier; bit_blaster m_bb; th_trail_stack m_trail_stack; th_union_find m_find; @@ -218,12 +214,6 @@ namespace smt { void assign_bit(literal consequent, theory_var v1, theory_var v2, unsigned idx, literal antecedent, bool propagate_eqc); void assert_int2bv_axiom(app* n); void assert_bv2int_axiom(app* n); - arith_simplifier_plugin & arith_simp() const { - SASSERT(m_simplifier != 0); - arith_simplifier_plugin * as = static_cast(m_simplifier->get_plugin(m_autil.get_family_id())); - SASSERT(as != 0); - return *as; - } protected: virtual void init(context * ctx); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index e8edfc7ec..3f246b2c7 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -385,7 +385,7 @@ namespace smt { { ast_manager & m = get_manager(); context & ctx = get_context(); - simplifier & simp = ctx.get_simplifier(); + th_rewriter & simp = ctx.get_rewriter(); expr_ref res(m), t(m); proof_ref t_pr(m); From 881f90d17d97f0a545503fb7ed3eb763321aaa37 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 00:48:49 -0700 Subject: [PATCH 200/488] remove simplify dependencies Signed-off-by: Nikolaj Bjorner --- src/ast/macros/macro_manager.h | 1 - src/ast/pattern/pattern_inference.h | 187 ------------------ .../dl_mk_quantifier_instantiation.cpp | 1 + src/smt/elim_term_ite.h | 3 +- 4 files changed, 2 insertions(+), 190 deletions(-) diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index 58fedf666..87073004c 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -21,7 +21,6 @@ Revision History: #include "util/obj_hashtable.h" #include "ast/ast_util.h" -#include "ast/simplifier/simplifier.h" #include "ast/recurse_expr.h" #include "ast/func_decl_dependencies.h" #include "ast/macros/macro_util.h" diff --git a/src/ast/pattern/pattern_inference.h b/src/ast/pattern/pattern_inference.h index 281c3ff8b..905662477 100644 --- a/src/ast/pattern/pattern_inference.h +++ b/src/ast/pattern/pattern_inference.h @@ -20,7 +20,6 @@ Revision History: #define PATTERN_INFERENCE_H_ #include "ast/ast.h" -#include "ast/simplifier/simplifier.h" #include "ast/rewriter/rewriter.h" #include "ast/pattern/pattern_inference_params.h" #include "util/vector.h" @@ -61,192 +60,6 @@ public: bool operator()(unsigned num_bindings, expr * p1, expr * p2); }; -#if 0 -class pattern_inference_old : public simplifier { - pattern_inference_params & m_params; - family_id m_bfid; - family_id m_afid; - svector m_forbidden; - obj_hashtable m_preferred; - smaller_pattern m_le; - unsigned m_num_bindings; - unsigned m_num_no_patterns; - expr * const * m_no_patterns; - bool m_nested_arith_only; - bool m_block_loop_patterns; - - struct info { - uint_set m_free_vars; - unsigned m_size; - info(uint_set const & vars, unsigned size): - m_free_vars(vars), - m_size(size) { - } - info(): - m_free_vars(), - m_size(0) { - } - }; - - typedef obj_map expr2info; - - expr2info m_candidates_info; // candidate -> set of free vars + size - app_ref_vector m_candidates; - - ptr_vector m_tmp1; - ptr_vector m_tmp2; - ptr_vector m_todo; - - // Compare candidates patterns based on their usefulness - // p1 < p2 if - // - p1 has more free variables than p2 - // - p1 and p2 has the same number of free variables, - // and p1 is smaller than p2. - struct pattern_weight_lt { - expr2info & m_candidates_info; - pattern_weight_lt(expr2info & i): - m_candidates_info(i) { - } - bool operator()(expr * n1, expr * n2) const; - }; - - pattern_weight_lt m_pattern_weight_lt; - - // - // Functor for collecting candidates. - // - class collect { - struct entry { - expr * m_node; - unsigned m_delta; - entry():m_node(0), m_delta(0) {} - entry(expr * n, unsigned d):m_node(n), m_delta(d) {} - unsigned hash() const { - return hash_u_u(m_node->get_id(), m_delta); - } - bool operator==(entry const & e) const { - return m_node == e.m_node && m_delta == e.m_delta; - } - }; - - struct info { - expr_ref m_node; - uint_set m_free_vars; - unsigned m_size; - info(ast_manager & m, expr * n, uint_set const & vars, unsigned sz): - m_node(n, m), m_free_vars(vars), m_size(sz) {} - }; - - ast_manager & m; - pattern_inference_old & m_owner; - family_id m_afid; - unsigned m_num_bindings; - typedef map, default_eq > cache; - cache m_cache; - ptr_vector m_info; - svector m_todo; - - void visit(expr * n, unsigned delta, bool & visited); - bool visit_children(expr * n, unsigned delta); - void save(expr * n, unsigned delta, info * i); - void save_candidate(expr * n, unsigned delta); - void reset(); - public: - collect(ast_manager & m, pattern_inference_old & o):m(m), m_owner(o), m_afid(m.mk_family_id("arith")) {} - void operator()(expr * n, unsigned num_bindings); - }; - - collect m_collect; - - void add_candidate(app * n, uint_set const & s, unsigned size); - - void filter_looping_patterns(ptr_vector & result); - - bool has_preferred_patterns(ptr_vector & candidate_patterns, app_ref_buffer & result); - - void filter_bigger_patterns(ptr_vector const & patterns, ptr_vector & result); - - class contains_subpattern { - pattern_inference_old & m_owner; - nat_set m_already_processed; - ptr_vector m_todo; - void save(expr * n); - public: - contains_subpattern(pattern_inference_old & owner): - m_owner(owner) {} - bool operator()(expr * n); - }; - - contains_subpattern m_contains_subpattern; - - bool contains_subpattern(expr * n); - - struct pre_pattern { - ptr_vector m_exprs; // elements of the pattern. - uint_set m_free_vars; // set of free variables in m_exprs - unsigned m_idx; // idx of the next candidate to process. - pre_pattern(): - m_idx(0) { - } - }; - - ptr_vector m_pre_patterns; - expr_pattern_match m_database; - - void candidates2unary_patterns(ptr_vector const & candidate_patterns, - ptr_vector & remaining_candidate_patterns, - app_ref_buffer & result); - - void candidates2multi_patterns(unsigned max_num_patterns, - ptr_vector const & candidate_patterns, - app_ref_buffer & result); - - void reset_pre_patterns(); - - /** - \brief All minimal unary patterns (i.e., expressions that - contain all bound variables) are copied to result. If there - are unary patterns, then at most num_extra_multi_patterns multi - patterns are created. If there are no unary pattern, then at - most 1 + num_extra_multi_patterns multi_patterns are created. - */ - void mk_patterns(unsigned num_bindings, // IN number of bindings. - expr * n, // IN node where the patterns are going to be extracted. - unsigned num_no_patterns, // IN num. patterns that should not be used. - expr * const * no_patterns, // IN patterns that should not be used. - app_ref_buffer & result); // OUT result - - virtual void reduce1_quantifier(quantifier * q); - -public: - pattern_inference_old(ast_manager & m, pattern_inference_params & params); - - void register_forbidden_family(family_id fid) { - SASSERT(fid != m_bfid); - m_forbidden.push_back(fid); - } - - /** - \brief Register f as a preferred function symbol. The inference algorithm - gives preference to patterns rooted by this kind of function symbol. - */ - void register_preferred(func_decl * f) { - m_preferred.insert(f); - } - - void register_preferred(unsigned num, func_decl * const * fs) { for (unsigned i = 0; i < num; i++) register_preferred(fs[i]); } - - bool is_forbidden(func_decl const * decl) const { - family_id fid = decl->get_family_id(); - if (fid == m_bfid && decl->get_decl_kind() != OP_TRUE && decl->get_decl_kind() != OP_FALSE) - return true; - return std::find(m_forbidden.begin(), m_forbidden.end(), fid) != m_forbidden.end(); - } - - bool is_forbidden(app * n) const; -}; -#endif - class pattern_inference_cfg : public default_rewriter_cfg { ast_manager& m; pattern_inference_params & m_params; diff --git a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp index 74d15bcdf..8986bf506 100644 --- a/src/muz/transforms/dl_mk_quantifier_instantiation.cpp +++ b/src/muz/transforms/dl_mk_quantifier_instantiation.cpp @@ -27,6 +27,7 @@ Revision History: #include "muz/base/dl_context.h" #include "ast/pattern/pattern_inference.h" #include "ast/rewriter/rewriter_def.h" +#include "ast/ast_util.h" namespace datalog { diff --git a/src/smt/elim_term_ite.h b/src/smt/elim_term_ite.h index 106a9f511..86b9a79e2 100644 --- a/src/smt/elim_term_ite.h +++ b/src/smt/elim_term_ite.h @@ -19,9 +19,9 @@ Revision History: #ifndef ELIM_TERM_ITE_H_ #define ELIM_TERM_ITE_H_ -#include "ast/simplifier/simplifier.h" #include "ast/normal_forms/defined_names.h" #include "ast/rewriter/rewriter.h" +#include "ast/simplifier/simplifier.h" class elim_term_ite : public simplifier { defined_names & m_defined_names; @@ -48,7 +48,6 @@ public: }; - class elim_term_ite_cfg : public default_rewriter_cfg { ast_manager& m; defined_names & m_defined_names; From 5371315f4c999b3a314a0d0023c1091f51ebc9aa Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 00:57:44 -0700 Subject: [PATCH 201/488] remove simplify dependencies Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/spacer_legacy_mev.cpp | 3 --- src/muz/spacer/spacer_legacy_mev.h | 1 - src/muz/spacer/spacer_util.h | 3 ++- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/muz/spacer/spacer_legacy_mev.cpp b/src/muz/spacer/spacer_legacy_mev.cpp index 69f479836..16e2cc734 100644 --- a/src/muz/spacer/spacer_legacy_mev.cpp +++ b/src/muz/spacer/spacer_legacy_mev.cpp @@ -5,11 +5,8 @@ Copyright (c) 2017 Arie Gurfinkel */ #include -#include "ast/simplifier/arith_simplifier_plugin.h" #include "ast/array_decl_plugin.h" #include "ast/ast_pp.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/rewriter/bool_rewriter.h" #include "muz/base/dl_util.h" #include "ast/for_each_expr.h" diff --git a/src/muz/spacer/spacer_legacy_mev.h b/src/muz/spacer/spacer_legacy_mev.h index bebf1d0db..ff8f63d1f 100644 --- a/src/muz/spacer/spacer_legacy_mev.h +++ b/src/muz/spacer/spacer_legacy_mev.h @@ -10,7 +10,6 @@ Copyright (c) 2017 Arie Gurfinkel #include "ast/ast_pp.h" #include "util/obj_hashtable.h" #include "util/ref_vector.h" -#include "ast/simplifier/simplifier.h" #include "util/trace.h" #include "util/vector.h" #include "ast/arith_decl_plugin.h" diff --git a/src/muz/spacer/spacer_util.h b/src/muz/spacer/spacer_util.h index 5bbb84bfb..546b7df5b 100644 --- a/src/muz/spacer/spacer_util.h +++ b/src/muz/spacer/spacer_util.h @@ -26,12 +26,13 @@ Revision History: #include "ast/ast_pp.h" #include "util/obj_hashtable.h" #include "util/ref_vector.h" -#include "ast/simplifier/simplifier.h" #include "util/trace.h" #include "util/vector.h" #include "ast/arith_decl_plugin.h" #include "ast/array_decl_plugin.h" #include "ast/bv_decl_plugin.h" +#include "ast/ast_util.h" +#include "ast/expr_map.h" #include "model/model.h" #include "util/stopwatch.h" From 14e6b5b50008134a0d92379a69a4d537a7f2b2d0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 01:38:55 -0700 Subject: [PATCH 202/488] mising files Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/maximize_ac_sharing.cpp | 175 +++++++++++++++++++++++ src/ast/rewriter/maximize_ac_sharing.h | 125 ++++++++++++++++ 2 files changed, 300 insertions(+) create mode 100644 src/ast/rewriter/maximize_ac_sharing.cpp create mode 100644 src/ast/rewriter/maximize_ac_sharing.h diff --git a/src/ast/rewriter/maximize_ac_sharing.cpp b/src/ast/rewriter/maximize_ac_sharing.cpp new file mode 100644 index 000000000..b560132db --- /dev/null +++ b/src/ast/rewriter/maximize_ac_sharing.cpp @@ -0,0 +1,175 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + maximize_ac_sharing.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-10-22. + +Revision History: + +--*/ + +#include "ast/rewriter/maximize_ac_sharing.h" +#include "ast/ast_pp.h" + + +void maximize_ac_sharing::register_kind(decl_kind k) { + m_kinds.push_back(k); +} + + +br_status maximize_ac_sharing::reduce_app(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result, proof_ref& result_pr) { + decl_kind k = f->get_kind(); + if (!f->is_associative()) + return BR_FAILED; + if (num_args <= 2) + return BR_FAILED; + if (std::find(m_kinds.begin(), m_kinds.end(), k) == m_kinds.end()) + return BR_FAILED; + ptr_buffer _args; + expr * numeral = 0; + if (is_numeral(args[0])) { + numeral = args[0]; + for (unsigned i = 1; i < num_args; i++) + _args.push_back(args[i]); + num_args--; + } + else { + _args.append(num_args, args); + } + + TRACE("ac_sharing_detail", tout << "before-reuse: num_args: " << num_args << "\n";); + +#define MAX_NUM_ARGS_FOR_OPT 128 + + // Try to reuse already created circuits. + TRACE("ac_sharing_detail", tout << "args: "; for (unsigned i = 0; i < num_args; i++) tout << mk_pp(_args[i], m) << "\n";); + try_to_reuse: + if (num_args > 1 && num_args < MAX_NUM_ARGS_FOR_OPT) { + for (unsigned i = 0; i < num_args - 1; i++) { + for (unsigned j = i + 1; j < num_args; j++) { + if (contains(f, _args[i], _args[j])) { + TRACE("ac_sharing_detail", tout << "reusing args: " << i << " " << j << "\n";); + _args[i] = m.mk_app(f, _args[i], _args[j]); + SASSERT(num_args > 1); + for (unsigned w = j; w < num_args - 1; w++) { + _args[w] = _args[w+1]; + } + num_args--; + goto try_to_reuse; + } + } + } + } + + + // Create "tree-like circuit" + while (true) { + TRACE("ac_sharing_detail", tout << "tree-loop: num_args: " << num_args << "\n";); + unsigned j = 0; + for (unsigned i = 0; i < num_args; i += 2, j++) { + if (i == num_args - 1) { + _args[j] = _args[i]; + } + else { + insert(f, _args[i], _args[i+1]); + _args[j] = m.mk_app(f, _args[i], _args[i+1]); + } + } + num_args = j; + if (num_args == 1) { + if (numeral == 0) { + result = _args[0]; + } + else { + result = m.mk_app(f, numeral, _args[0]); + } + TRACE("ac_sharing_detail", tout << "result: " << mk_pp(result, m) << "\n";); + return BR_DONE; + } + } + + UNREACHABLE(); + return BR_FAILED; +} + +bool maximize_ac_sharing::contains(func_decl * f, expr * arg1, expr * arg2) { + entry e(f, arg1, arg2); + return m_cache.contains(&e); +} + +void maximize_ac_sharing::insert(func_decl * f, expr * arg1, expr * arg2) { + entry * e = new (m_region) entry(f, arg1, arg2); + m_entries.push_back(e); + m_cache.insert(e); + m.inc_ref(arg1); + m.inc_ref(arg2); +} + +maximize_ac_sharing::maximize_ac_sharing(ast_manager & m): + m(m), + m_init(false) { +} + +maximize_ac_sharing::~maximize_ac_sharing() { + restore_entries(0); +} + + +void maximize_ac_sharing::push_scope() { + init(); + m_scopes.push_back(m_entries.size()); + m_region.push_scope(); +} + +void maximize_ac_sharing::pop_scope(unsigned num_scopes) { + SASSERT(num_scopes <= m_scopes.size()); + unsigned new_lvl = m_scopes.size() - num_scopes; + unsigned old_lim = m_scopes[new_lvl]; + restore_entries(old_lim); + m_region.pop_scope(num_scopes); + m_scopes.shrink(new_lvl); +} + +void maximize_ac_sharing::restore_entries(unsigned old_lim) { + unsigned i = m_entries.size(); + while (i != old_lim) { + --i; + entry * e = m_entries[i]; + m.dec_ref(e->m_arg1); + m.dec_ref(e->m_arg2); + } + m_entries.shrink(old_lim); +} + +void maximize_ac_sharing::reset() { + restore_entries(0); + m_entries.reset(); + m_cache.reset(); + m_region.reset(); + m_scopes.reset(); +} + +void maximize_bv_sharing::init_core() { + register_kind(OP_BADD); + register_kind(OP_BMUL); + register_kind(OP_BOR); + register_kind(OP_BAND); +} + +bool maximize_bv_sharing::is_numeral(expr * n) const { + return m_util.is_numeral(n); +} + +maximize_bv_sharing::maximize_bv_sharing(ast_manager & m): + maximize_ac_sharing(m), + m_util(m) { +} diff --git a/src/ast/rewriter/maximize_ac_sharing.h b/src/ast/rewriter/maximize_ac_sharing.h new file mode 100644 index 000000000..c0ee0d09f --- /dev/null +++ b/src/ast/rewriter/maximize_ac_sharing.h @@ -0,0 +1,125 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + maximize_ac_sharing.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-10-22. + +Revision History: + +--*/ +#ifndef MAXIMIZE_AC_SHARING_H_ +#define MAXIMIZE_AC_SHARING_H_ + +#include "util/hashtable.h" +#include "util/region.h" +#include "ast/bv_decl_plugin.h" +#include "ast/rewriter/rewriter.h" + +/** + \brief Functor used to maximize the amount of shared terms in an expression. + The idea is to rewrite AC terms to maximize sharing. + Example: + + (f (bvadd a (bvadd b c)) (bvadd a (bvadd b d))) + + is rewritten to: + + (f (bvadd (bvadd a b) c) (bvadd (bvadd a b) d)) + + \warning This class uses an opportunistic heuristic to maximize sharing. + There is no guarantee that the optimal expression will be produced. +*/ +class maximize_ac_sharing : public default_rewriter_cfg { + + struct entry { + func_decl * m_decl; + expr * m_arg1; + expr * m_arg2; + + entry(func_decl * d = 0, expr * arg1 = 0, expr * arg2 = 0):m_decl(d), m_arg1(arg1), m_arg2(arg2) { + SASSERT((d == 0 && arg1 == 0 && arg2 == 0) || (d != 0 && arg1 != 0 && arg2 != 0)); + if (arg1->get_id() > arg2->get_id()) + std::swap(m_arg1, m_arg2); + } + + unsigned hash() const { + unsigned a = m_decl->get_id(); + unsigned b = m_arg1->get_id(); + unsigned c = m_arg2->get_id(); + mix(a,b,c); + return c; + } + + bool operator==(entry const & e) const { + return m_decl == e.m_decl && m_arg1 == e.m_arg1 && m_arg2 == e.m_arg2; + } + }; + + typedef ptr_hashtable, deref_eq > cache; + +protected: + void register_kind(decl_kind k); + +private: + ast_manager & m; + bool m_init; + region m_region; + cache m_cache; + ptr_vector m_entries; + unsigned_vector m_scopes; + svector m_kinds; //!< kinds to be processed + + bool contains(func_decl * f, expr * arg1, expr * arg2); + void insert(func_decl * f, expr * arg1, expr * arg2); + void restore_entries(unsigned old_lim); + void init() { + if (!m_init) { + init_core(); + m_init = true; + } + } +protected: + virtual void init_core() = 0; + virtual bool is_numeral(expr * n) const = 0; +public: + maximize_ac_sharing(ast_manager & m); + virtual ~maximize_ac_sharing(); + void push_scope(); + void pop_scope(unsigned num_scopes); + void reset(); + br_status reduce_app(func_decl* f, unsigned n, expr * const* args, expr_ref& result, proof_ref& result_pr); + +}; + +class maximize_bv_sharing : public maximize_ac_sharing { + bv_util m_util; +protected: + virtual void init_core(); + virtual bool is_numeral(expr * n) const; +public: + maximize_bv_sharing(ast_manager & m); +}; + +class maximize_bv_sharing_rw : public rewriter_tpl { + maximize_bv_sharing m_cfg; +public: + maximize_bv_sharing_rw(ast_manager& m): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m) + {} + void push_scope() { m_cfg.push_scope(); } + void pop_scope(unsigned n) { m_cfg.pop_scope(n); } + void reset() { m_cfg.reset(); } +}; + +#endif /* MAXIMIZE_AC_SHARING_H_ */ + From 9b53646a342dd65b5f48a45cad11da81ed5199f6 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 01:43:06 -0700 Subject: [PATCH 203/488] mising files Signed-off-by: Nikolaj Bjorner --- src/smt/asserted_formulas_new.cpp | 619 ++++++++++++++++++++++++++++++ src/smt/asserted_formulas_new.h | 269 +++++++++++++ 2 files changed, 888 insertions(+) create mode 100644 src/smt/asserted_formulas_new.cpp create mode 100644 src/smt/asserted_formulas_new.h diff --git a/src/smt/asserted_formulas_new.cpp b/src/smt/asserted_formulas_new.cpp new file mode 100644 index 000000000..51bba9f7f --- /dev/null +++ b/src/smt/asserted_formulas_new.cpp @@ -0,0 +1,619 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + asserted_formulas_new.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-11. + +Revision History: + +--*/ +#include "util/warning.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" +#include "ast/for_each_expr.h" +#include "ast/well_sorted.h" +#include "ast/rewriter/rewriter_def.h" +#include "ast/normal_forms/nnf.h" +#include "ast/pattern/pattern_inference.h" +#include "ast/macros/quasi_macros.h" +#include "smt/asserted_formulas_new.h" + +asserted_formulas_new::asserted_formulas_new(ast_manager & m, smt_params & p): + m(m), + m_params(p), + m_rewriter(m), + m_substitution(m), + m_scoped_substitution(m_substitution), + m_defined_names(m), + m_static_features(m), + m_qhead(0), + m_macro_manager(m), + m_bv_sharing(m), + m_inconsistent(false), + m_has_quantifiers(false), + m_reduce_asserted_formulas(*this), + m_distribute_forall(*this), + m_pattern_inference(*this), + m_refine_inj_axiom(*this), + m_max_bv_sharing_fn(*this), + m_elim_term_ite(*this), + m_pull_cheap_ite_trees(*this), + m_pull_nested_quantifiers(*this), + m_elim_bvs_from_quantifiers(*this), + m_cheap_quant_fourier_motzkin(*this), + m_apply_bit2int(*this), + m_lift_ite(*this), + m_ng_lift_ite(*this), + m_find_macros(*this), + m_propagate_values(*this), + m_nnf_cnf(*this), + m_apply_quasi_macros(*this) { + + m_macro_finder = alloc(macro_finder, m, m_macro_manager); +} + +void asserted_formulas_new::setup() { + switch (m_params.m_lift_ite) { + case LI_FULL: + m_params.m_ng_lift_ite = LI_NONE; + break; + case LI_CONSERVATIVE: + if (m_params.m_ng_lift_ite == LI_CONSERVATIVE) + m_params.m_ng_lift_ite = LI_NONE; + break; + default: + break; + } + + if (m_params.m_relevancy_lvl == 0) + m_params.m_relevancy_lemma = false; +} + + +asserted_formulas_new::~asserted_formulas_new() { +} + +void asserted_formulas_new::push_assertion(expr * e, proof * pr, vector& result) { + if (inconsistent()) { + SASSERT(!result.empty()); + return; + } + expr* e1 = 0; + if (m.is_false(e)) { + result.push_back(justified_expr(m, e, pr)); + m_inconsistent = true; + } + else if (m.is_true(e)) { + // skip + } + else if (m.is_and(e)) { + for (unsigned i = 0; i < to_app(e)->get_num_args(); ++i) { + expr* arg = to_app(e)->get_arg(i); + proof_ref _pr(m.mk_and_elim(pr, i), m); + push_assertion(arg, _pr, result); + } + } + else if (m.is_not(e, e1) && m.is_or(e1)) { + for (unsigned i = 0; i < to_app(e1)->get_num_args(); ++i) { + expr* arg = to_app(e1)->get_arg(i), *e2; + proof_ref _pr(m.mk_not_or_elim(pr, i), m); + if (m.is_not(arg, e2)) { + push_assertion(e2, _pr, result); + } + else { + expr_ref narg(m.mk_not(arg), m); + push_assertion(narg, _pr, result); + } + } + } + else { + result.push_back(justified_expr(m, e, pr)); + } +} + +void asserted_formulas_new::set_eliminate_and(bool flag) { + params_ref p; + p.set_bool("elim_and", true); + m_rewriter.updt_params(p); + flush_cache(); +} + + +void asserted_formulas_new::assert_expr(expr * e, proof * _in_pr) { + proof_ref in_pr(_in_pr, m), pr(_in_pr, m); + expr_ref r(e, m); + + if (inconsistent()) + return; + + m_has_quantifiers |= ::has_quantifiers(e); + + if (m_params.m_preprocess) { + TRACE("assert_expr_bug", tout << r << "\n";); + set_eliminate_and(false); // do not eliminate and before nnf. + m_rewriter(e, r, pr); + if (m.proofs_enabled()) { + if (e == r) + pr = in_pr; + else + pr = m.mk_modus_ponens(in_pr, pr); + } + TRACE("assert_expr_bug", tout << "after...\n" << r << "\n";); + } + push_assertion(r, pr, m_formulas); + TRACE("asserted_formulas_bug", tout << "after assert_expr\n"; display(tout);); +} + +void asserted_formulas_new::assert_expr(expr * e) { + if (!inconsistent()) + assert_expr(e, m.mk_asserted(e)); +} + +void asserted_formulas_new::get_assertions(ptr_vector & result) const { + for (justified_expr const& je : m_formulas) result.push_back(je.get_fml()); +} + +void asserted_formulas_new::push_scope() { + SASSERT(inconsistent() || m_qhead == m_formulas.size() || m.canceled()); + TRACE("asserted_formulas_new_scopes", tout << "push:\n"; display(tout);); + m_scoped_substitution.push(); + m_scopes.push_back(scope()); + scope & s = m_scopes.back(); + s.m_formulas_lim = m_formulas.size(); + SASSERT(inconsistent() || s.m_formulas_lim == m_qhead || m.canceled()); + s.m_inconsistent_old = m_inconsistent; + m_defined_names.push(); + m_bv_sharing.push_scope(); + m_macro_manager.push_scope(); + commit(); +} + +void asserted_formulas_new::pop_scope(unsigned num_scopes) { + TRACE("asserted_formulas_new_scopes", tout << "before pop " << num_scopes << "\n"; display(tout);); + m_bv_sharing.pop_scope(num_scopes); + m_macro_manager.pop_scope(num_scopes); + unsigned new_lvl = m_scopes.size() - num_scopes; + scope & s = m_scopes[new_lvl]; + m_inconsistent = s.m_inconsistent_old; + m_defined_names.pop(num_scopes); + m_scoped_substitution.pop(num_scopes); + m_formulas.shrink(s.m_formulas_lim); + m_qhead = s.m_formulas_lim; + m_scopes.shrink(new_lvl); + flush_cache(); + TRACE("asserted_formulas_new_scopes", tout << "after pop " << num_scopes << "\n"; display(tout);); +} + +void asserted_formulas_new::reset() { + m_defined_names.reset(); + m_qhead = 0; + m_formulas.reset(); + m_macro_manager.reset(); + m_bv_sharing.reset(); + m_rewriter.reset(); + m_inconsistent = false; +} + +bool asserted_formulas_new::check_well_sorted() const { + for (justified_expr const& je : m_formulas) { + if (!is_well_sorted(m, je.get_fml())) return false; + } + return true; +} + +void asserted_formulas_new::reduce() { + if (inconsistent()) + return; + if (canceled()) + return; + if (m_qhead == m_formulas.size()) + return; + if (!m_params.m_preprocess) + return; + if (m_macro_manager.has_macros()) + expand_macros(); + + TRACE("before_reduce", display(tout);); + CASSERT("well_sorted", check_well_sorted()); + + set_eliminate_and(false); // do not eliminate and before nnf. + if (!invoke(m_propagate_values)) return; + if (!invoke(m_find_macros)) return; + if (!invoke(m_nnf_cnf)) return; + set_eliminate_and(true); + if (!invoke(m_reduce_asserted_formulas)) return; + if (!invoke(m_pull_cheap_ite_trees)) return; + if (!invoke(m_pull_nested_quantifiers)) return; + if (!invoke(m_lift_ite)) return; + if (!invoke(m_ng_lift_ite)) return; + if (!invoke(m_elim_term_ite)) return; + if (!invoke(m_refine_inj_axiom)) return; + if (!invoke(m_distribute_forall)) return; + if (!invoke(m_find_macros)) return; + if (!invoke(m_apply_quasi_macros)) return; + if (!invoke(m_apply_bit2int)) return; + if (!invoke(m_cheap_quant_fourier_motzkin)) return; + if (!invoke(m_pattern_inference)) return; + if (!invoke(m_max_bv_sharing_fn)) return; + if (!invoke(m_elim_bvs_from_quantifiers)) return; + if (!invoke(m_reduce_asserted_formulas)) return; + + IF_VERBOSE(10, verbose_stream() << "(smt.simplifier-done)\n";); + TRACE("after_reduce", display(tout);); + TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); + TRACE("macros", m_macro_manager.display(tout);); + flush_cache(); + CASSERT("well_sorted",check_well_sorted()); +} + + +unsigned asserted_formulas_new::get_formulas_last_level() const { + if (m_scopes.empty()) { + return 0; + } + else { + return m_scopes.back().m_formulas_lim; + } +} + +bool asserted_formulas_new::invoke(simplify_fmls& s) { + if (!s.should_apply()) return true; + IF_VERBOSE(10, verbose_stream() << "(smt." << s.id() << ")\n";); + s(); + IF_VERBOSE(10000, verbose_stream() << "total size: " << get_total_size() << "\n";); + TRACE("reduce_step_ll", ast_mark visited; display_ll(tout, visited);); + CASSERT("well_sorted",check_well_sorted()); + if (inconsistent() || canceled()) { + TRACE("after_reduce", display(tout);); + TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); + return false; + } + else { + return true; + } +} + +void asserted_formulas_new::display(std::ostream & out) const { + out << "asserted formulas:\n"; + for (unsigned i = 0; i < m_formulas.size(); i++) { + if (i == m_qhead) + out << "[HEAD] ==>\n"; + out << mk_pp(m_formulas[i].get_fml(), m) << "\n"; + } + out << "inconsistent: " << inconsistent() << "\n"; +} + +void asserted_formulas_new::display_ll(std::ostream & out, ast_mark & pp_visited) const { + if (!m_formulas.empty()) { + for (justified_expr const& f : m_formulas) + ast_def_ll_pp(out, m, f.get_fml(), pp_visited, true, false); + out << "asserted formulas:\n"; + for (justified_expr const& f : m_formulas) + out << "#" << f.get_fml()->get_id() << " "; + out << "\n"; + } +} + +void asserted_formulas_new::collect_statistics(statistics & st) const { +} + + +void asserted_formulas_new::swap_asserted_formulas(vector& formulas) { + SASSERT(!inconsistent() || !formulas.empty()); + m_formulas.shrink(m_qhead); + m_formulas.append(formulas); +} + +void asserted_formulas_new::find_macros_fn::operator()() { + TRACE("before_find_macros", af.display(tout);); + af.find_macros_core(); + TRACE("after_find_macros", af.display(tout);); +} + +void asserted_formulas_new::find_macros_core() { + vector new_fmls; + unsigned sz = m_formulas.size(); + (*m_macro_finder)(sz - m_qhead, m_formulas.c_ptr() + m_qhead, new_fmls); + swap_asserted_formulas(new_fmls); + reduce_and_solve(); +} + + +void asserted_formulas_new::expand_macros() { + IF_IVERBOSE(10, verbose_stream() << "(smt.expand-macros)\n";); + find_macros_core(); +} + +void asserted_formulas_new::apply_quasi_macros() { + TRACE("before_quasi_macros", display(tout);); + vector new_fmls; + quasi_macros proc(m, m_macro_manager); + while (proc(m_formulas.size() - m_qhead, + m_formulas.c_ptr() + m_qhead, + new_fmls)) { + swap_asserted_formulas(new_fmls); + new_fmls.reset(); + } + TRACE("after_quasi_macros", display(tout);); + reduce_and_solve(); +} + +void asserted_formulas_new::nnf_cnf() { + nnf apply_nnf(m, m_defined_names); + vector new_fmls; + expr_ref_vector push_todo(m); + proof_ref_vector push_todo_prs(m); + + unsigned i = m_qhead; + unsigned sz = m_formulas.size(); + TRACE("nnf_bug", tout << "i: " << i << " sz: " << sz << "\n";); + for (; i < sz; i++) { + expr * n = m_formulas[i].get_fml(); + TRACE("nnf_bug", tout << "processing:\n" << mk_pp(n, m) << "\n";); + proof * pr = m_formulas[i].get_proof(); + expr_ref r1(m); + proof_ref pr1(m); + push_todo.reset(); + push_todo_prs.reset(); + CASSERT("well_sorted", is_well_sorted(m, n)); + apply_nnf(n, push_todo, push_todo_prs, r1, pr1); + CASSERT("well_sorted",is_well_sorted(m, r1)); + pr = m.mk_modus_ponens(pr, pr1); + push_todo.push_back(r1); + push_todo_prs.push_back(pr); + + if (canceled()) { + return; + } + unsigned sz2 = push_todo.size(); + for (unsigned k = 0; k < sz2; k++) { + expr * n = push_todo.get(k); + pr = 0; + m_rewriter(n, r1, pr1); + CASSERT("well_sorted",is_well_sorted(m, r1)); + if (canceled()) { + return; + } + if (m.proofs_enabled()) + pr = m.mk_modus_ponens(push_todo_prs.get(k), pr1); + push_assertion(r1, pr, new_fmls); + } + } + swap_asserted_formulas(new_fmls); +} + +void asserted_formulas_new::simplify_fmls::operator()() { + vector new_fmls; + unsigned sz = af.m_formulas.size(); + for (unsigned i = af.m_qhead; i < sz; i++) { + auto& j = af.m_formulas[i]; + expr_ref result(m); + proof_ref result_pr(m); + simplify(j, result, result_pr); + if (m.proofs_enabled()) { + if (!result_pr) result_pr = m.mk_rewrite(j.get_fml(), result); + result_pr = m.mk_modus_ponens(j.get_proof(), result_pr); + } + if (j.get_fml() == result) { + new_fmls.push_back(j); + } + else { + af.push_assertion(result, result_pr, new_fmls); + } + if (af.canceled()) return; + } + af.swap_asserted_formulas(new_fmls); + TRACE("asserted_formulas", af.display(tout);); + post_op(); +} + + +void asserted_formulas_new::reduce_and_solve() { + IF_IVERBOSE(10, verbose_stream() << "(smt.reducing)\n";); + flush_cache(); // collect garbage + m_reduce_asserted_formulas(); +} + + +void asserted_formulas_new::commit() { + commit(m_formulas.size()); +} + +void asserted_formulas_new::commit(unsigned new_qhead) { + m_macro_manager.mark_forbidden(new_qhead - m_qhead, m_formulas.c_ptr() + m_qhead); + m_expr2depth.reset(); + for (unsigned i = m_qhead; i < new_qhead; ++i) { + justified_expr const& j = m_formulas[i]; + update_substitution(j.get_fml(), j.get_proof()); + } + m_qhead = new_qhead; +} + +void asserted_formulas_new::propagate_values() { + TRACE("propagate_values", tout << "before:\n"; display(tout);); + flush_cache(); + + unsigned num_prop = 0; + while (true) { + m_expr2depth.reset(); + m_scoped_substitution.push(); + unsigned prop = num_prop; + TRACE("propagate_values", tout << "before:\n"; display(tout);); + IF_IVERBOSE(10, verbose_stream() << "(smt.propagate-values)\n";); + unsigned i = m_qhead; + unsigned sz = m_formulas.size(); + for (; i < sz; i++) { + prop += propagate_values(i); + } + flush_cache(); + m_scoped_substitution.pop(1); + m_expr2depth.reset(); + m_scoped_substitution.push(); + TRACE("propagate_values", tout << "middle:\n"; display(tout);); + i = sz; + while (i > m_qhead) { + --i; + prop += propagate_values(i); + } + m_scoped_substitution.pop(1); + flush_cache(); + TRACE("propagate_values", tout << "after:\n"; display(tout);); + if (num_prop == prop) { + break; + } + num_prop = prop; + } + if (num_prop > 0) + m_reduce_asserted_formulas(); +} + +unsigned asserted_formulas_new::propagate_values(unsigned i) { + expr * n = m_formulas[i].get_fml(); + expr_ref new_n(m); + proof_ref new_pr(m); + m_rewriter(n, new_n, new_pr); + if (m.proofs_enabled()) { + proof * pr = m_formulas[i].get_proof(); + new_pr = m.mk_modus_ponens(pr, new_pr); + } + m_formulas[i] = justified_expr(m, new_n, new_pr); + update_substitution(new_n, new_pr); + return n != new_n ? 1 : 0; +} + +void asserted_formulas_new::update_substitution(expr* n, proof* pr) { + expr* lhs, *rhs, *n1; + if (is_ground(n) && (m.is_eq(n, lhs, rhs) || m.is_iff(n, lhs, rhs))) { + compute_depth(lhs); + compute_depth(rhs); + if (is_gt(lhs, rhs)) { + m_scoped_substitution.insert(lhs, rhs, pr); + return; + } + if (is_gt(rhs, lhs)) { + m_scoped_substitution.insert(rhs, lhs, m.mk_symmetry(pr)); + return; + } + } + if (m.is_not(n, n1)) { + m_scoped_substitution.insert(n1, m.mk_false(), m.mk_iff_false(pr)); + } + else { + m_scoped_substitution.insert(n, m.mk_true(), m.mk_iff_true(pr)); + } +} + +/** + \brief implement a Knuth-Bendix ordering on expressions. +*/ + +bool asserted_formulas_new::is_gt(expr* lhs, expr* rhs) { + if (lhs == rhs) { + return false; + } + if (m.is_value(rhs)) { + return true; + } + SASSERT(is_ground(lhs) && is_ground(rhs)); + if (depth(lhs) > depth(rhs)) { + return true; + } + if (depth(lhs) == depth(rhs) && is_app(lhs) && is_app(rhs)) { + app* l = to_app(lhs); + app* r = to_app(rhs); + if (l->get_decl()->get_id() != r->get_decl()->get_id()) { + return l->get_decl()->get_id() > r->get_decl()->get_id(); + } + if (l->get_num_args() != r->get_num_args()) { + return l->get_num_args() > r->get_num_args(); + } + for (unsigned i = 0; i < l->get_num_args(); ++i) { + if (l->get_arg(i) != r->get_arg(i)) { + return is_gt(l->get_arg(i), r->get_arg(i)); + } + } + UNREACHABLE(); + } + + return false; +} + +void asserted_formulas_new::compute_depth(expr* e) { + ptr_vector todo; + todo.push_back(e); + while (!todo.empty()) { + e = todo.back(); + unsigned d = 0; + if (m_expr2depth.contains(e)) { + todo.pop_back(); + continue; + } + if (is_app(e)) { + app* a = to_app(e); + bool visited = true; + for (expr* arg : *a) { + unsigned d1 = 0; + if (m_expr2depth.find(arg, d1)) { + d = std::max(d, d1); + } + else { + visited = false; + todo.push_back(arg); + } + } + if (!visited) { + continue; + } + } + todo.pop_back(); + m_expr2depth.insert(e, d + 1); + } +} + +proof * asserted_formulas_new::get_inconsistency_proof() const { + if (!inconsistent()) + return 0; + if (!m.proofs_enabled()) + return 0; + for (justified_expr const& j : m_formulas) { + if (m.is_false(j.get_fml())) + return j.get_proof(); + } + UNREACHABLE(); + return 0; +} + +void asserted_formulas_new::refine_inj_axiom_fn::simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { + expr* f = j.get_fml(); + if (is_quantifier(f) && simplify_inj_axiom(m, to_quantifier(f), n)) { + TRACE("inj_axiom", tout << "simplifying...\n" << mk_pp(f, m) << "\n" << n << "\n";); + } + else { + n = j.get_fml(); + } +} + + +unsigned asserted_formulas_new::get_total_size() const { + expr_mark visited; + unsigned r = 0; + for (justified_expr const& j : m_formulas) + r += get_num_exprs(j.get_fml(), visited); + return r; +} + +#ifdef Z3DEBUG +void pp(asserted_formulas_new & f) { + f.display(std::cout); +} +#endif + diff --git a/src/smt/asserted_formulas_new.h b/src/smt/asserted_formulas_new.h new file mode 100644 index 000000000..dc51c86ae --- /dev/null +++ b/src/smt/asserted_formulas_new.h @@ -0,0 +1,269 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + asserted_formulas_new.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-11. + +Revision History: + +--*/ +#ifndef ASSERTED_FORMULAS_NEW_H_ +#define ASSERTED_FORMULAS_NEW_H_ + +#include "util/statistics.h" +#include "ast/static_features.h" +#include "ast/expr_substitution.h" +#include "ast/rewriter/th_rewriter.h" +#include "ast/rewriter/bit2int.h" +#include "ast/rewriter/maximize_ac_sharing.h" +#include "ast/rewriter/distribute_forall.h" +#include "ast/rewriter/pull_ite_tree.h" +#include "ast/rewriter/push_app_ite.h" +#include "ast/rewriter/inj_axiom.h" +#include "ast/rewriter/bv_elim2.h" +#include "ast/rewriter/der.h" +#include "ast/rewriter/elim_bounds2.h" +#include "ast/macros/macro_manager.h" +#include "ast/macros/macro_finder.h" +#include "ast/normal_forms/defined_names.h" +#include "ast/normal_forms/pull_quant.h" +#include "ast/pattern/pattern_inference.h" +#include "smt/params/smt_params.h" +#include "smt/elim_term_ite.h" + + +class asserted_formulas_new { + + ast_manager & m; + smt_params & m_params; + th_rewriter m_rewriter; + expr_substitution m_substitution; + scoped_expr_substitution m_scoped_substitution; + defined_names m_defined_names; + static_features m_static_features; + vector m_formulas; + unsigned m_qhead; + macro_manager m_macro_manager; + scoped_ptr m_macro_finder; + maximize_bv_sharing_rw m_bv_sharing; + bool m_inconsistent; + bool m_has_quantifiers; + struct scope { + unsigned m_formulas_lim; + bool m_inconsistent_old; + }; + svector m_scopes; + obj_map m_expr2depth; + + class simplify_fmls { + protected: + asserted_formulas_new& af; + ast_manager& m; + char const* m_id; + public: + simplify_fmls(asserted_formulas_new& af, char const* id): af(af), m(af.m), m_id(id) {} + char const* id() const { return m_id; } + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) = 0; + virtual bool should_apply() const { return true;} + virtual void post_op() {} + virtual void operator()(); + }; + + class reduce_asserted_formulas_fn : public simplify_fmls { + public: + reduce_asserted_formulas_fn(asserted_formulas_new& af): simplify_fmls(af, "reduce-asserted") {} + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { af.m_rewriter(j.get_fml(), n, p); } + }; + + class find_macros_fn : public simplify_fmls { + public: + find_macros_fn(asserted_formulas_new& af): simplify_fmls(af, "find-macros") {} + virtual void operator()(); + virtual bool should_apply() const { return af.m_params.m_macro_finder && af.has_quantifiers(); } + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } + }; + + class apply_quasi_macros_fn : public simplify_fmls { + public: + apply_quasi_macros_fn(asserted_formulas_new& af): simplify_fmls(af, "find-quasi-macros") {} + virtual void operator()() { af.apply_quasi_macros(); } + virtual bool should_apply() const { return af.m_params.m_quasi_macros && af.has_quantifiers(); } + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } + }; + + class nnf_cnf_fn : public simplify_fmls { + public: + nnf_cnf_fn(asserted_formulas_new& af): simplify_fmls(af, "nnf-cnf") {} + virtual void operator()() { af.nnf_cnf(); } + virtual bool should_apply() const { return af.m_params.m_nnf_cnf || (af.m_params.m_mbqi && af.has_quantifiers()); } + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } + }; + + class propagate_values_fn : public simplify_fmls { + public: + propagate_values_fn(asserted_formulas_new& af): simplify_fmls(af, "propagate-values") {} + virtual void operator()() { af.propagate_values(); } + virtual bool should_apply() const { return af.m_params.m_propagate_values; } + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } + }; + + class distribute_forall_fn : public simplify_fmls { + distribute_forall m_functor; + public: + distribute_forall_fn(asserted_formulas_new& af): simplify_fmls(af, "distribute-forall"), m_functor(af.m) {} + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { m_functor(j.get_fml(), n); } + virtual bool should_apply() const { return af.m_params.m_distribute_forall && af.has_quantifiers(); } + virtual void post_op() { af.reduce_and_solve(); TRACE("asserted_formulas", af.display(tout);); } + }; + + class pattern_inference_fn : public simplify_fmls { + pattern_inference_rw m_infer; + public: + pattern_inference_fn(asserted_formulas_new& af): simplify_fmls(af, "pattern-inference"), m_infer(af.m, af.m_params) {} + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { m_infer(j.get_fml(), n, p); } + virtual bool should_apply() const { return af.m_params.m_ematching && af.has_quantifiers(); } + }; + + class refine_inj_axiom_fn : public simplify_fmls { + public: + refine_inj_axiom_fn(asserted_formulas_new& af): simplify_fmls(af, "refine-injectivity") {} + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p); + virtual bool should_apply() const { return af.m_params.m_refine_inj_axiom && af.has_quantifiers(); } + }; + + class max_bv_sharing_fn : public simplify_fmls { + public: + max_bv_sharing_fn(asserted_formulas_new& af): simplify_fmls(af, "maximizing-bv-sharing") {} + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { af.m_bv_sharing(j.get_fml(), n, p); } + virtual bool should_apply() const { return af.m_params.m_max_bv_sharing; } + virtual void post_op() { af.m_reduce_asserted_formulas(); } + }; + + class elim_term_ite_fn : public simplify_fmls { + elim_term_ite_rw m_elim; + public: + elim_term_ite_fn(asserted_formulas_new& af): simplify_fmls(af, "elim-term-ite"), m_elim(af.m, af.m_defined_names) {} + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { m_elim(j.get_fml(), n, p); } + virtual bool should_apply() const { return af.m_params.m_eliminate_term_ite && af.m_params.m_lift_ite != LI_FULL; } + virtual void post_op() { af.m_formulas.append(m_elim.new_defs()); af.reduce_and_solve(); m_elim.reset(); } + }; + +#define MK_SIMPLIFIERA(NAME, FUNCTOR, MSG, APP, ARG, REDUCE) \ + class NAME : public simplify_fmls { \ + FUNCTOR m_functor; \ + public: \ + NAME(asserted_formulas_new& af):simplify_fmls(af, MSG), m_functor ARG {} \ + virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { \ + m_functor(j.get_fml(), n, p); \ + } \ + virtual void post_op() { if (REDUCE) af.reduce_and_solve(); } \ + virtual bool should_apply() const { return APP; } \ + }; \ + +#define MK_SIMPLIFIERF(NAME, FUNCTOR, MSG, APP, REDUCE) MK_SIMPLIFIERA(NAME, FUNCTOR, MSG, APP, (af.m), REDUCE) + + MK_SIMPLIFIERF(pull_cheap_ite_trees, pull_cheap_ite_tree_rw, "pull-cheap-ite-trees", af.m_params.m_pull_cheap_ite_trees, false); + MK_SIMPLIFIERF(pull_nested_quantifiers, pull_nested_quant, "pull-nested-quantifiers", af.m_params.m_pull_nested_quantifiers && af.has_quantifiers(), false); + MK_SIMPLIFIERF(cheap_quant_fourier_motzkin, elim_bounds_rw, "cheap-fourier-motzkin", af.m_params.m_eliminate_bounds && af.has_quantifiers(), true); + MK_SIMPLIFIERF(elim_bvs_from_quantifiers, bv_elim_rw, "eliminate-bit-vectors-from-quantifiers", af.m_params.m_bb_quantifiers, true); + MK_SIMPLIFIERF(apply_bit2int, bit2int, "propagate-bit-vector-over-integers", af.m_params.m_simplify_bit2int, true); + MK_SIMPLIFIERA(lift_ite, push_app_ite_rw, "lift-ite", af.m_params.m_lift_ite != LI_NONE, (af.m, af.m_params.m_lift_ite == LI_CONSERVATIVE), true); + MK_SIMPLIFIERA(ng_lift_ite, ng_push_app_ite_rw, "lift-ite", af.m_params.m_ng_lift_ite != LI_NONE, (af.m, af.m_params.m_ng_lift_ite == LI_CONSERVATIVE), true); + + + reduce_asserted_formulas_fn m_reduce_asserted_formulas; + distribute_forall_fn m_distribute_forall; + pattern_inference_fn m_pattern_inference; + refine_inj_axiom_fn m_refine_inj_axiom; + max_bv_sharing_fn m_max_bv_sharing_fn; + elim_term_ite_fn m_elim_term_ite; + pull_cheap_ite_trees m_pull_cheap_ite_trees; + pull_nested_quantifiers m_pull_nested_quantifiers; + elim_bvs_from_quantifiers m_elim_bvs_from_quantifiers; + cheap_quant_fourier_motzkin m_cheap_quant_fourier_motzkin; + apply_bit2int m_apply_bit2int; + lift_ite m_lift_ite; + ng_lift_ite m_ng_lift_ite; + find_macros_fn m_find_macros; + propagate_values_fn m_propagate_values; + nnf_cnf_fn m_nnf_cnf; + apply_quasi_macros_fn m_apply_quasi_macros; + + bool invoke(simplify_fmls& s); + void swap_asserted_formulas(vector& new_fmls); + void push_assertion(expr * e, proof * pr, vector& result); + bool canceled() { return m.canceled(); } + bool check_well_sorted() const; + unsigned get_total_size() const; + + void find_macros_core(); + void expand_macros(); + void apply_quasi_macros(); + void nnf_cnf(); + void reduce_and_solve(); + void flush_cache() { m_rewriter.reset(); } + void set_eliminate_and(bool flag); + void propagate_values(); + unsigned propagate_values(unsigned i); + void update_substitution(expr* n, proof* p); + bool is_gt(expr* lhs, expr* rhs); + void compute_depth(expr* e); + unsigned depth(expr* e) { return m_expr2depth[e]; } + bool pull_cheap_ite_trees(); + +public: + asserted_formulas_new(ast_manager & m, smt_params & p); + ~asserted_formulas_new(); + + bool has_quantifiers() const { return m_has_quantifiers; } + void setup(); + void assert_expr(expr * e, proof * in_pr); + void assert_expr(expr * e); + void reset(); + void push_scope(); + void pop_scope(unsigned num_scopes); + bool inconsistent() const { return m_inconsistent; } + proof * get_inconsistency_proof() const; + void reduce(); + unsigned get_num_formulas() const { return m_formulas.size(); } + unsigned get_formulas_last_level() const; + unsigned get_qhead() const { return m_qhead; } + void commit(); + void commit(unsigned new_qhead); + expr * get_formula(unsigned idx) const { return m_formulas[idx].get_fml(); } + proof * get_formula_proof(unsigned idx) const { return m_formulas[idx].get_proof(); } + + th_rewriter & get_rewriter() { return m_rewriter; } + void get_assertions(ptr_vector & result) const; + bool empty() const { return m_formulas.empty(); } + void display(std::ostream & out) const; + void display_ll(std::ostream & out, ast_mark & pp_visited) const; + void collect_statistics(statistics & st) const; + + // ----------------------------------- + // + // Macros + // + // ----------------------------------- + unsigned get_num_macros() const { return m_macro_manager.get_num_macros(); } + unsigned get_first_macro_last_level() const { return m_macro_manager.get_first_macro_last_level(); } + func_decl * get_macro_func_decl(unsigned i) const { return m_macro_manager.get_macro_func_decl(i); } + func_decl * get_macro_interpretation(unsigned i, expr_ref & interp) const { return m_macro_manager.get_macro_interpretation(i, interp); } + quantifier * get_macro_quantifier(func_decl * f) const { return m_macro_manager.get_macro_quantifier(f); } + // auxiliary function used to create a logic context based on a model. + void insert_macro(func_decl * f, quantifier * m, proof * pr) { m_macro_manager.insert(f, m, pr); } + void insert_macro(func_decl * f, quantifier * m, proof * pr, expr_dependency* dep) { m_macro_manager.insert(f, m, pr, dep); } + +}; + +#endif /* ASSERTED_FORMULAS_NEW_H_ */ + From e3e965883f562de3ecd91ecfba6dd20c88437438 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 01:55:03 -0700 Subject: [PATCH 204/488] mising files Signed-off-by: Nikolaj Bjorner --- src/smt/asserted_formulas_new.cpp | 28 +++++----------------------- src/smt/asserted_formulas_new.h | 2 +- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/smt/asserted_formulas_new.cpp b/src/smt/asserted_formulas_new.cpp index 51bba9f7f..14c8615a2 100644 --- a/src/smt/asserted_formulas_new.cpp +++ b/src/smt/asserted_formulas_new.cpp @@ -84,7 +84,6 @@ asserted_formulas_new::~asserted_formulas_new() { void asserted_formulas_new::push_assertion(expr * e, proof * pr, vector& result) { if (inconsistent()) { - SASSERT(!result.empty()); return; } expr* e1 = 0; @@ -106,13 +105,8 @@ void asserted_formulas_new::push_assertion(expr * e, proof * pr, vectorget_num_args(); ++i) { expr* arg = to_app(e1)->get_arg(i), *e2; proof_ref _pr(m.mk_not_or_elim(pr, i), m); - if (m.is_not(arg, e2)) { - push_assertion(e2, _pr, result); - } - else { - expr_ref narg(m.mk_not(arg), m); - push_assertion(narg, _pr, result); - } + expr_ref narg(mk_not(m, arg), m); + push_assertion(narg, _pr, result); } } else { @@ -154,8 +148,7 @@ void asserted_formulas_new::assert_expr(expr * e, proof * _in_pr) { } void asserted_formulas_new::assert_expr(expr * e) { - if (!inconsistent()) - assert_expr(e, m.mk_asserted(e)); + assert_expr(e, m.mk_asserted(e)); } void asserted_formulas_new::get_assertions(ptr_vector & result) const { @@ -220,8 +213,8 @@ void asserted_formulas_new::reduce() { if (!m_params.m_preprocess) return; if (m_macro_manager.has_macros()) - expand_macros(); - + invoke(m_find_macros); + TRACE("before_reduce", display(tout);); CASSERT("well_sorted", check_well_sorted()); @@ -313,11 +306,6 @@ void asserted_formulas_new::swap_asserted_formulas(vector& formu m_formulas.append(formulas); } -void asserted_formulas_new::find_macros_fn::operator()() { - TRACE("before_find_macros", af.display(tout);); - af.find_macros_core(); - TRACE("after_find_macros", af.display(tout);); -} void asserted_formulas_new::find_macros_core() { vector new_fmls; @@ -327,12 +315,6 @@ void asserted_formulas_new::find_macros_core() { reduce_and_solve(); } - -void asserted_formulas_new::expand_macros() { - IF_IVERBOSE(10, verbose_stream() << "(smt.expand-macros)\n";); - find_macros_core(); -} - void asserted_formulas_new::apply_quasi_macros() { TRACE("before_quasi_macros", display(tout);); vector new_fmls; diff --git a/src/smt/asserted_formulas_new.h b/src/smt/asserted_formulas_new.h index dc51c86ae..60af46dea 100644 --- a/src/smt/asserted_formulas_new.h +++ b/src/smt/asserted_formulas_new.h @@ -87,7 +87,7 @@ class asserted_formulas_new { class find_macros_fn : public simplify_fmls { public: find_macros_fn(asserted_formulas_new& af): simplify_fmls(af, "find-macros") {} - virtual void operator()(); + virtual void operator()() { af.find_macros_core(); } virtual bool should_apply() const { return af.m_params.m_macro_finder && af.has_quantifiers(); } virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } }; From ce3ab6b170151953dde32f3b6f365754f3feb662 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 02:04:59 -0700 Subject: [PATCH 205/488] mising files Signed-off-by: Nikolaj Bjorner --- src/ast/ast.h | 12 ++++++------ src/smt/asserted_formulas_new.cpp | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ast/ast.h b/src/ast/ast.h index 408ca4063..34ea96653 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -2474,15 +2474,15 @@ class justified_expr { ast_manager& m; expr* m_fml; proof* m_proof; - public: - justified_expr(ast_manager& m, expr* fml, proof* p): - m(m), - m_fml(fml), - m_proof(p) { +public: + justified_expr(ast_manager& m, expr* fml, proof* p): + m(m), + m_fml(fml), + m_proof(p) { m.inc_ref(fml); m.inc_ref(p); } - + justified_expr& operator=(justified_expr& other) { SASSERT(&m == &other.m); if (this != &other) { diff --git a/src/smt/asserted_formulas_new.cpp b/src/smt/asserted_formulas_new.cpp index 14c8615a2..39c432b61 100644 --- a/src/smt/asserted_formulas_new.cpp +++ b/src/smt/asserted_formulas_new.cpp @@ -467,7 +467,8 @@ unsigned asserted_formulas_new::propagate_values(unsigned i) { proof * pr = m_formulas[i].get_proof(); new_pr = m.mk_modus_ponens(pr, new_pr); } - m_formulas[i] = justified_expr(m, new_n, new_pr); + justified_expr j(m, new_n, new_pr); + m_formulas[i] = j; update_substitution(new_n, new_pr); return n != new_n ? 1 : 0; } From 2955b0c2efe27ef220e51749647fe9f7e5653836 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 03:05:34 -0700 Subject: [PATCH 206/488] removing more dependencies Signed-off-by: Nikolaj Bjorner --- src/muz/base/dl_rule.cpp | 3 +- src/muz/spacer/spacer_qe_project.cpp | 1 + src/qe/CMakeLists.txt | 2 - src/qe/nlarith_util.cpp | 11 +- src/qe/qe.cpp | 22 +++- src/qe/qe.h | 34 ++--- src/qe/qe_cmd.cpp | 3 +- src/qe/vsubst_tactic.cpp | 169 ------------------------- src/qe/vsubst_tactic.h | 33 ----- src/smt/CMakeLists.txt | 2 +- src/smt/arith_eq_adapter.cpp | 1 - src/smt/params/CMakeLists.txt | 1 - src/smt/params/preprocessor_params.cpp | 1 - src/smt/params/preprocessor_params.h | 6 +- src/tactic/bv/elim_small_bv_tactic.cpp | 14 +- 15 files changed, 38 insertions(+), 265 deletions(-) delete mode 100644 src/qe/vsubst_tactic.cpp delete mode 100644 src/qe/vsubst_tactic.h diff --git a/src/muz/base/dl_rule.cpp b/src/muz/base/dl_rule.cpp index 26a5b748e..367795c9b 100644 --- a/src/muz/base/dl_rule.cpp +++ b/src/muz/base/dl_rule.cpp @@ -44,6 +44,7 @@ Revision History: #include "tactic/filter_model_converter.h" #include "ast/scoped_proof.h" #include "ast/datatype_decl_plugin.h" +#include "ast/ast_util.h" namespace datalog { @@ -757,7 +758,7 @@ namespace datalog { ); proof_ref pr(m); - qe::expr_quant_elim_star1 simpl(m, m_ctx.get_fparams()); + qe::simplify_rewriter_star simpl(m); simpl(quant_tail, fixed_tail, pr); } else { diff --git a/src/muz/spacer/spacer_qe_project.cpp b/src/muz/spacer/spacer_qe_project.cpp index 0eec500e9..8dbf87ca5 100644 --- a/src/muz/spacer/spacer_qe_project.cpp +++ b/src/muz/spacer/spacer_qe_project.cpp @@ -25,6 +25,7 @@ Revision History: #include "ast/ast_pp.h" #include "ast/expr_functors.h" #include "ast/expr_substitution.h" +#include "ast/ast_util.h" #include "ast/rewriter/expr_replacer.h" #include "ast/rewriter/expr_safe_replace.h" diff --git a/src/qe/CMakeLists.txt b/src/qe/CMakeLists.txt index 2d2cf9579..2e6052382 100644 --- a/src/qe/CMakeLists.txt +++ b/src/qe/CMakeLists.txt @@ -18,7 +18,6 @@ z3_add_component(qe qe_sat_tactic.cpp qe_tactic.cpp qsat.cpp - vsubst_tactic.cpp COMPONENT_DEPENDENCIES nlsat_tactic nlsat @@ -31,5 +30,4 @@ z3_add_component(qe qe_sat_tactic.h qe_tactic.h qsat.h - vsubst_tactic.h ) diff --git a/src/qe/nlarith_util.cpp b/src/qe/nlarith_util.cpp index 1da5ef52a..4f07b59dd 100644 --- a/src/qe/nlarith_util.cpp +++ b/src/qe/nlarith_util.cpp @@ -11,7 +11,8 @@ Copyright (c) 2015 Microsoft Corporation #include "qe/qe.h" #include "ast/rewriter/expr_replacer.h" #include "ast/rewriter/arith_rewriter.h" -#include "ast/simplifier/arith_simplifier_plugin.h" +#include "ast/rewriter/bool_rewriter.h" +#include "ast/rewriter/th_rewriter.h" #include "ast/expr_functors.h" namespace nlarith { @@ -79,9 +80,8 @@ namespace nlarith { app_ref m_zero; app_ref m_one; smt_params m_params; - basic_simplifier_plugin m_bs; - arith_simplifier_plugin m_rw; - arith_rewriter m_rw1; + bool_rewriter m_bs; + arith_rewriter m_rw; expr_ref_vector m_trail; ast_manager& m() const { return m_manager; } @@ -105,8 +105,7 @@ namespace nlarith { m_enable_linear(false), m_zero(num(0),m), m_one(num(1),m), m_bs(m), - m_rw(m, m_bs, m_params), - m_rw1(m), m_trail(m) { + m_rw(m), m_trail(m) { } // diff --git a/src/qe/qe.cpp b/src/qe/qe.cpp index 7c7250c40..dd54f4441 100644 --- a/src/qe/qe.cpp +++ b/src/qe/qe.cpp @@ -1310,6 +1310,10 @@ namespace qe { m_s.mk_atom(e, p, result); } + void i_solver_context::collect_statistics(statistics& st) const { + // tbd + } + typedef ref_vector_ptr_hash expr_ref_vector_hash; typedef ref_vector_ptr_eq expr_ref_vector_eq; typedef hashtable clause_table; @@ -2393,6 +2397,7 @@ namespace qe { +#if 0 // ------------------------------------------------ // expr_quant_elim_star1 @@ -2433,13 +2438,7 @@ namespace qe { simplifier(m), m_quant_elim(m, p), m_assumption(m.mk_true()) { } - - void expr_quant_elim_star1::reduce_with_assumption(expr* ctx, expr* fml, expr_ref& result) { - proof_ref pr(m); - m_assumption = ctx; - (*this)(fml, result, pr); - m_assumption = m.mk_true(); - } +#endif void hoist_exists(expr_ref& fml, app_ref_vector& vars) { @@ -2488,6 +2487,7 @@ namespace qe { virtual ~simplify_solver_context() { reset(); } + void solve(expr_ref& fml, app_ref_vector& vars) { init(fml, vars); bool solved = true; @@ -2580,6 +2580,10 @@ namespace qe { m_ctx.updt_params(p); } + void collect_statistics(statistics & st) const { + m_ctx.collect_statistics(st); + } + bool reduce_quantifier( quantifier * old_q, expr * new_body, @@ -2647,6 +2651,10 @@ namespace qe { imp->updt_params(p); } + void simplify_rewriter_cfg::collect_statistics(statistics & st) const { + imp->collect_statistics(st); + } + bool simplify_rewriter_cfg::pre_visit(expr* e) { if (!is_quantifier(e)) return true; quantifier * q = to_quantifier(e); diff --git a/src/qe/qe.h b/src/qe/qe.h index 392bfb03b..b6754b384 100644 --- a/src/qe/qe.h +++ b/src/qe/qe.h @@ -26,7 +26,6 @@ Revision History: #include "util/statistics.h" #include "util/lbool.h" #include "ast/expr_functors.h" -#include "ast/simplifier/simplifier.h" #include "ast/rewriter/rewriter.h" #include "model/model.h" #include "util/params.h" @@ -106,6 +105,9 @@ namespace qe { i_expr_pred& get_is_relevant() { return m_is_relevant; } i_nnf_atom& get_mk_atom() { return m_mk_atom; } + + void collect_statistics(statistics & st) const; + }; class conj_enum { @@ -322,30 +324,6 @@ namespace qe { void init_qe(); }; - class expr_quant_elim_star1 : public simplifier { - protected: - expr_quant_elim m_quant_elim; - expr* m_assumption; - virtual bool visit_quantifier(quantifier * q); - virtual void reduce1_quantifier(quantifier * q); - virtual bool is_target(quantifier * q) const { return q->get_num_patterns() == 0 && q->get_num_no_patterns() == 0; } - public: - expr_quant_elim_star1(ast_manager & m, smt_params const& p); - virtual ~expr_quant_elim_star1() {} - - void collect_statistics(statistics & st) const { - m_quant_elim.collect_statistics(st); - } - - void reduce_with_assumption(expr* ctx, expr* fml, expr_ref& result); - - lbool first_elim(unsigned num_vars, app* const* vars, expr_ref& fml, def_vector& defs) { - return m_quant_elim.first_elim(num_vars, vars, fml, defs); - } - - - }; - void hoist_exists(expr_ref& fml, app_ref_vector& vars); void mk_exists(unsigned num_vars, app* const* vars, expr_ref& fml); @@ -372,6 +350,7 @@ namespace qe { void updt_params(params_ref const& p); + void collect_statistics(statistics & st) const; }; class simplify_rewriter_star : public rewriter_tpl { @@ -382,6 +361,11 @@ namespace qe { m_cfg(m) {} void updt_params(params_ref const& p) { m_cfg.updt_params(p); } + + void collect_statistics(statistics & st) const { + m_cfg.collect_statistics(st); + } + }; }; diff --git a/src/qe/qe_cmd.cpp b/src/qe/qe_cmd.cpp index 553cf4471..3c55c0f49 100644 --- a/src/qe/qe_cmd.cpp +++ b/src/qe/qe_cmd.cpp @@ -44,9 +44,8 @@ public: } virtual void execute(cmd_context & ctx) { - smt_params par; proof_ref pr(ctx.m()); - qe::expr_quant_elim_star1 qe(ctx.m(), par); + qe::simplify_rewriter_star qe(ctx.m()); expr_ref result(ctx.m()); qe(m_target, result, pr); diff --git a/src/qe/vsubst_tactic.cpp b/src/qe/vsubst_tactic.cpp deleted file mode 100644 index 6bd8213d6..000000000 --- a/src/qe/vsubst_tactic.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/*++ -Copyright (c) 2011 Microsoft Corporation - -Module Name: - - vsubst_tactic.cpp - -Abstract: - - Check satisfiability of QF_NRA problems using virtual subsititution quantifier-elimination. - -Author: - - Nikolaj (nbjorner) 2011-05-16 - -Notes: - Ported to tactic framework on 2012-02-28 - It was qfnra_vsubst.cpp - - This goal transformation checks satsifiability - of quantifier-free non-linear constraints using - virtual substitutions (applies to second-degree polynomials). - . identify non-linear variables - . use the identified variables as non-linear variables. - . give up if there are non-linear variables under uninterpreted scope. - give up if there are no non-linear variables. - . call quantifier elimination with - - non-linear elimination option. - - get-first-branch option. - . if the first branch is linear, then done. - if the result is unsat, then done. - if the first branch is non-linear then, - check candidate model, - perhaps iterate using rewriting or just give up. - - . helpful facilities: - . linearize_rewriter - a*a*b + a*b = 0 <=> (b+1) = 0 \/ a = 0 \/ b = 0 - . sign analysis: - a*a + b*b + c < 0 => c < 0 - ---*/ -#include "tactic/tactic.h" -#include "qe/qe.h" -#include "ast/arith_decl_plugin.h" -#include "ast/for_each_expr.h" -#include "tactic/extension_model_converter.h" -#include "ast/ast_smt2_pp.h" - -class vsubst_tactic : public tactic { - params_ref m_params; - - class get_var_proc { - arith_util m_arith; - ptr_vector& m_vars; - public: - get_var_proc(ast_manager & m, ptr_vector& vars) : m_arith(m), m_vars(vars) {} - - void operator()(expr* e) { - if (is_app(e)) { - app* a = to_app(e); - if (m_arith.is_real(e) && - a->get_num_args() == 0 && - a->get_family_id() == null_family_id) { - m_vars.push_back(a); - } - } - } - }; - - void get_vars(ast_manager & m, expr* fml, ptr_vector& vars) { - get_var_proc proc(m, vars); - for_each_expr(proc, fml); - } - - void main(goal & s, model_converter_ref & mc, params_ref const & p) { - ast_manager & m = s.m(); - - ptr_vector fs; - for (unsigned i = 0; i < s.size(); ++i) { - fs.push_back(s.form(i)); - } - app_ref f(m.mk_and(fs.size(), fs.c_ptr()), m); - TRACE("vsubst", - s.display(tout); - tout << "goal: " << mk_ismt2_pp(f.get(), m) << "\n";); - ptr_vector vars; - get_vars(m, f.get(), vars); - - if (vars.empty()) { - TRACE("vsubst", tout << "no real variables\n";); - throw tactic_exception("there are no real variables"); - } - - smt_params params; - params.updt_params(p); - params.m_model = false; - flet fl1(params.m_nlquant_elim, true); - flet fl2(params.m_nl_arith_gb, false); - TRACE("quant_elim", tout << "Produce models: " << params.m_model << "\n";); - - qe::expr_quant_elim_star1 qelim(m, params); - expr_ref g(f, m); - qe::def_vector defs(m); - lbool is_sat = qelim.first_elim(vars.size(), vars.c_ptr(), g, defs); - if (is_sat == l_undef) { - TRACE("vsubst", tout << mk_ismt2_pp(g, m) << "\n";); - throw tactic_exception("elimination was not successful"); - } - if (!defs.empty()) { - extension_model_converter * ev = alloc(extension_model_converter, m); - mc = ev; - for (unsigned i = defs.size(); i > 0; ) { - --i; - ev->insert(defs.var(i), defs.def(i)); - } - } - - s.reset(); - // TBD: wasteful as we already know it is sat or unsat. - // TBD: extract model from virtual substitution. - s.assert_expr(g); - - TRACE("qfnra_vsubst", - tout << "v-subst result:\n"; - s.display(tout);); - } - - -public: - vsubst_tactic(params_ref const & p):m_params(p) {} - - virtual tactic * translate(ast_manager & m) { - return alloc(vsubst_tactic, m_params); - } - - virtual ~vsubst_tactic() {} - - virtual void updt_params(params_ref const & p) { - m_params = p; - } - - /** - \brief Check satisfiability of an assertion set of QF_NRA - by using virtual substitutions. - */ - virtual void operator()(goal_ref const & g, - goal_ref_buffer & result, - model_converter_ref & mc, - proof_converter_ref & pc, - expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); - fail_if_proof_generation("vsubst", g); - fail_if_unsat_core_generation("vsubst", g); - fail_if_model_generation("vsubst", g); // disable for now due to problems with infinitesimals. - mc = 0; pc = 0; core = 0; result.reset(); - - main(*(g.get()), mc, m_params); - - result.push_back(g.get()); - SASSERT(g->is_well_sorted()); - } - - virtual void cleanup(void) {} -}; - -tactic * mk_vsubst_tactic(ast_manager & m, params_ref const & p) { - return alloc(vsubst_tactic, p); -} diff --git a/src/qe/vsubst_tactic.h b/src/qe/vsubst_tactic.h deleted file mode 100644 index 2f28bda71..000000000 --- a/src/qe/vsubst_tactic.h +++ /dev/null @@ -1,33 +0,0 @@ -/*++ -Copyright (c) 2011 Microsoft Corporation - -Module Name: - - vsubst_tactic.h - -Abstract: - - Check satisfiability of QF_NRA problems using virtual subsititution quantifier-elimination. - -Author: - - Nikolaj (nbjorner) 2011-05-16 - -Notes: - - ---*/ -#ifndef VSUBST_TACTIC_H_ -#define VSUBST_TACTIC_H_ - -#include "util/params.h" -class ast_manager; -class tactic; - -tactic * mk_vsubst_tactic(ast_manager & m, params_ref const & p = params_ref()); -/* - ADD_TACTIC("vsubst", "checks satsifiability of quantifier-free non-linear constraints using virtual substitution.", "mk_vsubst_tactic(m, p)") -*/ - -#endif - diff --git a/src/smt/CMakeLists.txt b/src/smt/CMakeLists.txt index b117db89b..5c4c6b0b9 100644 --- a/src/smt/CMakeLists.txt +++ b/src/smt/CMakeLists.txt @@ -2,7 +2,7 @@ z3_add_component(smt SOURCES arith_eq_adapter.cpp arith_eq_solver.cpp - asserted_formulas.cpp +## asserted_formulas.cpp asserted_formulas_new.cpp cached_var_subst.cpp cost_evaluator.cpp diff --git a/src/smt/arith_eq_adapter.cpp b/src/smt/arith_eq_adapter.cpp index 60c109cff..307bdc671 100644 --- a/src/smt/arith_eq_adapter.cpp +++ b/src/smt/arith_eq_adapter.cpp @@ -22,7 +22,6 @@ Revision History: #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" #include "util/stats.h" -#include "ast/simplifier/simplifier.h" #include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/params/CMakeLists.txt b/src/smt/params/CMakeLists.txt index 500423dcc..c965f0a62 100644 --- a/src/smt/params/CMakeLists.txt +++ b/src/smt/params/CMakeLists.txt @@ -13,7 +13,6 @@ z3_add_component(smt_params ast bit_blaster pattern - simplifier PYG_FILES smt_params_helper.pyg ) diff --git a/src/smt/params/preprocessor_params.cpp b/src/smt/params/preprocessor_params.cpp index 0b621870d..afca0196a 100644 --- a/src/smt/params/preprocessor_params.cpp +++ b/src/smt/params/preprocessor_params.cpp @@ -48,7 +48,6 @@ void preprocessor_params::display(std::ostream & out) const { DISPLAY_PARAM(m_pull_cheap_ite_trees); DISPLAY_PARAM(m_pull_nested_quantifiers); DISPLAY_PARAM(m_eliminate_term_ite); - //DISPLAY_PARAM(m_eliminate_and); DISPLAY_PARAM(m_macro_finder); DISPLAY_PARAM(m_propagate_values); DISPLAY_PARAM(m_propagate_booleans); diff --git a/src/smt/params/preprocessor_params.h b/src/smt/params/preprocessor_params.h index fe759417d..6f763c0e1 100644 --- a/src/smt/params/preprocessor_params.h +++ b/src/smt/params/preprocessor_params.h @@ -31,15 +31,14 @@ enum lift_ite_kind { }; struct preprocessor_params : public pattern_inference_params, - public bit_blaster_params, - public bv_simplifier_params, + public bit_blaster_params, + public bv_simplifier_params, public arith_simplifier_params { lift_ite_kind m_lift_ite; lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms bool m_pull_cheap_ite_trees; bool m_pull_nested_quantifiers; bool m_eliminate_term_ite; -// bool m_eliminate_and; // represent (and a b) as (not (or (not a) (not b))) bool m_macro_finder; bool m_propagate_values; bool m_propagate_booleans; @@ -62,7 +61,6 @@ public: m_pull_cheap_ite_trees(false), m_pull_nested_quantifiers(false), m_eliminate_term_ite(false), - // m_eliminate_and(true), m_macro_finder(false), m_propagate_values(true), m_propagate_booleans(false), // TODO << check peformance diff --git a/src/tactic/bv/elim_small_bv_tactic.cpp b/src/tactic/bv/elim_small_bv_tactic.cpp index c40927179..ab4b3920d 100644 --- a/src/tactic/bv/elim_small_bv_tactic.cpp +++ b/src/tactic/bv/elim_small_bv_tactic.cpp @@ -24,9 +24,7 @@ Revision History: #include "ast/used_vars.h" #include "ast/well_sorted.h" #include "ast/rewriter/var_subst.h" -#include "ast/simplifier/simplifier.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" +#include "ast/rewriter/th_rewriter.h" #include "tactic/bv/elim_small_bv_tactic.h" @@ -36,7 +34,7 @@ class elim_small_bv_tactic : public tactic { ast_manager & m; params_ref m_params; bv_util m_util; - simplifier m_simp; + th_rewriter m_simp; ref m_mc; goal * m_goal; unsigned m_max_bits; @@ -56,14 +54,6 @@ class elim_small_bv_tactic : public tactic { updt_params(p); m_goal = 0; m_max_steps = UINT_MAX; - - basic_simplifier_plugin * bsimp = alloc(basic_simplifier_plugin, m); - // bsimp->set_eliminate_and(true); - m_simp.register_plugin(bsimp); - - bv_simplifier_params bv_params; - bv_simplifier_plugin * bvsimp = alloc(bv_simplifier_plugin, m, *bsimp, bv_params); - m_simp.register_plugin(bvsimp); } bool max_steps_exceeded(unsigned long long num_steps) const { From 0d5cfe9292d9d9b60a6567c48bb48d5a2aa246a9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 09:23:15 -0700 Subject: [PATCH 207/488] separate out, add copy constructor Signed-off-by: Nikolaj Bjorner --- src/ast/ast.h | 35 ----------------------- src/ast/justified_expr.h | 52 ++++++++++++++++++++++++++++++++++ src/ast/macros/macro_manager.h | 1 + src/ast/macros/quasi_macros.h | 1 + src/smt/elim_term_ite.h | 2 ++ 5 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 src/ast/justified_expr.h diff --git a/src/ast/ast.h b/src/ast/ast.h index 34ea96653..699268bd0 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -2470,41 +2470,6 @@ public: void operator()(AST * n) { m_manager.inc_ref(n); } }; -class justified_expr { - ast_manager& m; - expr* m_fml; - proof* m_proof; -public: - justified_expr(ast_manager& m, expr* fml, proof* p): - m(m), - m_fml(fml), - m_proof(p) { - m.inc_ref(fml); - m.inc_ref(p); - } - - justified_expr& operator=(justified_expr& other) { - SASSERT(&m == &other.m); - if (this != &other) { - m.dec_ref(m_fml); - m.dec_ref(m_proof); - m_fml = other.get_fml(); - m_proof = other.get_proof(); - m.inc_ref(m_fml); - m.inc_ref(m_proof); - } - return *this; - } - - ~justified_expr() { - m.dec_ref(m_fml); - m.dec_ref(m_proof); - } - - expr* get_fml() const { return m_fml; } - proof* get_proof() const { return m_proof; } -}; - #endif /* AST_H_ */ diff --git a/src/ast/justified_expr.h b/src/ast/justified_expr.h new file mode 100644 index 000000000..49362940d --- /dev/null +++ b/src/ast/justified_expr.h @@ -0,0 +1,52 @@ + +#ifndef JUSTIFIED_EXPR_H_ +#define JUSTIFIED_EXPR_H_ + +#include "ast/ast.h" + +class justified_expr { + ast_manager& m; + expr* m_fml; + proof* m_proof; +public: + justified_expr(ast_manager& m, expr* fml, proof* p): + m(m), + m_fml(fml), + m_proof(p) { + SASSERT(fml); + m.inc_ref(fml); + m.inc_ref(p); + } + + justified_expr& operator=(justified_expr const& other) { + SASSERT(&m == &other.m); + if (this != &other) { + m.dec_ref(m_fml); + m.dec_ref(m_proof); + m_fml = other.get_fml(); + m_proof = other.get_proof(); + m.inc_ref(m_fml); + m.inc_ref(m_proof); + } + return *this; + } + + justified_expr(justified_expr const& other): + m(other.m), + m_fml(other.m_fml), + m_proof(other.m_proof) + { + m.inc_ref(m_fml); + m.inc_ref(m_proof); + } + + ~justified_expr() { + m.dec_ref(m_fml); + m.dec_ref(m_proof); + } + + expr* get_fml() const { return m_fml; } + proof* get_proof() const { return m_proof; } +}; + +#endif diff --git a/src/ast/macros/macro_manager.h b/src/ast/macros/macro_manager.h index 46dfa059d..0205fb891 100644 --- a/src/ast/macros/macro_manager.h +++ b/src/ast/macros/macro_manager.h @@ -21,6 +21,7 @@ Revision History: #include "util/obj_hashtable.h" #include "ast/ast_util.h" +#include "ast/justified_expr.h" #include "ast/recurse_expr.h" #include "ast/func_decl_dependencies.h" #include "ast/macros/macro_util.h" diff --git a/src/ast/macros/quasi_macros.h b/src/ast/macros/quasi_macros.h index fc7287554..1b1483a90 100644 --- a/src/ast/macros/quasi_macros.h +++ b/src/ast/macros/quasi_macros.h @@ -20,6 +20,7 @@ Revision History: #define QUASI_MACROS_H_ #include +#include "ast/justified_expr.h" #include "ast/macros/macro_manager.h" #include "ast/rewriter/th_rewriter.h" diff --git a/src/smt/elim_term_ite.h b/src/smt/elim_term_ite.h index 86b9a79e2..a57ea1dad 100644 --- a/src/smt/elim_term_ite.h +++ b/src/smt/elim_term_ite.h @@ -22,6 +22,8 @@ Revision History: #include "ast/normal_forms/defined_names.h" #include "ast/rewriter/rewriter.h" #include "ast/simplifier/simplifier.h" +#include "ast/justified_expr.h" + class elim_term_ite : public simplifier { defined_names & m_defined_names; From 82a937d1af25f9466556670684ac9283023ef586 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 10:41:25 -0700 Subject: [PATCH 208/488] enforce arithmetic normalization Signed-off-by: Nikolaj Bjorner --- src/api/api_context.cpp | 3 ++- src/ast/ast_smt2_pp.cpp | 8 ++++---- src/ast/rewriter/arith_rewriter.cpp | 2 +- src/ast/rewriter/poly_rewriter_def.h | 17 +++++++++++++---- src/smt/asserted_formulas_new.cpp | 9 +++++++-- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index c99d3f0c8..1e3f7a0a4 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -150,8 +150,9 @@ namespace api { void context::set_error_code(Z3_error_code err) { m_error_code = err; - if (err != Z3_OK) + if (err != Z3_OK) { invoke_error_handler(err); + } } void context::check_searching() { diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index 5c3eb93c2..51ccc1e7d 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -1222,15 +1222,15 @@ mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, unsigned indent, unsigned num std::ostream& operator<<(std::ostream& out, mk_ismt2_pp const & p) { smt2_pp_environment_dbg env(p.m_manager); - if (is_expr(p.m_ast)) { + if (p.m_ast == 0) { + out << "null"; + } + else if (is_expr(p.m_ast)) { ast_smt2_pp(out, to_expr(p.m_ast), env, p.m_params, p.m_indent, p.m_num_vars, p.m_var_prefix); } else if (is_sort(p.m_ast)) { ast_smt2_pp(out, to_sort(p.m_ast), env, p.m_params, p.m_indent); } - else if (p.m_ast == 0) { - out << "null"; - } else { SASSERT(is_func_decl(p.m_ast)); ast_smt2_pp(out, to_func_decl(p.m_ast), env, p.m_params, p.m_indent); diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 18556b71b..4b00cde45 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -371,7 +371,7 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin (is_zero(arg2) && is_reduce_power_target(arg1, kind == EQ))) return reduce_power(arg1, arg2, kind, result); br_status st = cancel_monomials(arg1, arg2, m_arith_lhs, new_arg1, new_arg2); - TRACE("mk_le_bug", tout << "st: " << st << "\n";); + TRACE("mk_le_bug", tout << "st: " << st << " " << new_arg1 << " " << new_arg2 << "\n";); if (st != BR_FAILED) { arg1 = new_arg1; arg2 = new_arg2; diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 731a0538a..2a6bd2c50 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -704,8 +704,10 @@ br_status poly_rewriter::cancel_monomials(expr * lhs, expr * rhs, bool m } } - if (move && num_coeffs == 0 && is_numeral(rhs)) + if (move && num_coeffs == 0 && is_numeral(rhs)) { + TRACE("mk_le_bug", tout << "no coeffs\n";); return BR_FAILED; + } for (unsigned i = 0; i < rhs_sz; i++) { expr * arg = rhs_monomials[i]; @@ -723,15 +725,21 @@ br_status poly_rewriter::cancel_monomials(expr * lhs, expr * rhs, bool m } normalize(c); - + + TRACE("mk_le_bug", tout << c << "\n";); + if (!has_multiple && num_coeffs <= 1) { if (move) { - if (is_numeral(rhs)) + if (is_numeral(rhs)) { + TRACE("mk_le_bug", tout << "rhs is numeral\n";); return BR_FAILED; + } } else { - if (num_coeffs == 0 || is_numeral(rhs)) + if (num_coeffs == 0 || is_numeral(rhs)) { + TRACE("mk_le_bug", tout << "rhs is numeral or no coeffs\n";); return BR_FAILED; + } } } @@ -847,6 +855,7 @@ br_status poly_rewriter::cancel_monomials(expr * lhs, expr * rhs, bool m new_lhs_monomials[0] = insert_c_lhs ? mk_numeral(c) : NULL; lhs_result = mk_add_app(new_lhs_monomials.size() - lhs_offset, new_lhs_monomials.c_ptr() + lhs_offset); rhs_result = mk_add_app(new_rhs_monomials.size() - rhs_offset, new_rhs_monomials.c_ptr() + rhs_offset); + TRACE("mk_le_bug", tout << lhs_result << " " << rhs_result << "\n";); return BR_DONE; } diff --git a/src/smt/asserted_formulas_new.cpp b/src/smt/asserted_formulas_new.cpp index 39c432b61..5d4783bf8 100644 --- a/src/smt/asserted_formulas_new.cpp +++ b/src/smt/asserted_formulas_new.cpp @@ -59,6 +59,11 @@ asserted_formulas_new::asserted_formulas_new(ast_manager & m, smt_params & p): m_apply_quasi_macros(*this) { m_macro_finder = alloc(macro_finder, m, m_macro_manager); + + params_ref pa; + pa.set_bool("arith_lhs", true); + m_rewriter.updt_params(pa); + } void asserted_formulas_new::setup() { @@ -103,7 +108,7 @@ void asserted_formulas_new::push_assertion(expr * e, proof * pr, vectorget_num_args(); ++i) { - expr* arg = to_app(e1)->get_arg(i), *e2; + expr* arg = to_app(e1)->get_arg(i); proof_ref _pr(m.mk_not_or_elim(pr, i), m); expr_ref narg(mk_not(m, arg), m); push_assertion(narg, _pr, result); @@ -117,6 +122,7 @@ void asserted_formulas_new::push_assertion(expr * e, proof * pr, vector Date: Sat, 26 Aug 2017 11:23:41 -0700 Subject: [PATCH 209/488] removing dependencies on simplifier Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/CMakeLists.txt | 4 +- .../rewriter/{bv_elim2.cpp => bv_elim.cpp} | 2 +- src/ast/rewriter/{bv_elim2.h => bv_elim.h} | 4 +- src/ast/rewriter/elim_bounds2.cpp | 203 ---- src/ast/rewriter/elim_bounds2.h | 77 -- src/ast/simplifier/CMakeLists.txt | 32 +- src/smt/CMakeLists.txt | 1 - src/smt/asserted_formulas.cpp | 879 ------------------ src/smt/asserted_formulas.h | 151 --- src/smt/asserted_formulas_new.cpp | 8 +- src/smt/asserted_formulas_new.h | 6 +- src/smt/elim_term_ite.cpp | 138 --- src/smt/elim_term_ite.h | 27 - src/smt/expr_context_simplifier.h | 4 +- src/smt/params/CMakeLists.txt | 1 + src/smt/smt_consequences.cpp | 9 +- src/smt/smt_quantifier.cpp | 3 +- src/smt/theory_array.cpp | 1 + src/smt/theory_lra.cpp | 1 + src/smt/theory_seq.cpp | 3 +- src/smt/theory_str.h | 7 +- src/test/CMakeLists.txt | 1 - src/test/bv_simplifier_plugin.cpp | 326 ------- src/test/main.cpp | 1 - src/test/quant_elim.cpp | 6 - src/test/sorting_network.cpp | 6 +- 26 files changed, 52 insertions(+), 1849 deletions(-) rename src/ast/rewriter/{bv_elim2.cpp => bv_elim.cpp} (99%) rename src/ast/rewriter/{bv_elim2.h => bv_elim.h} (96%) delete mode 100644 src/ast/rewriter/elim_bounds2.cpp delete mode 100644 src/ast/rewriter/elim_bounds2.h delete mode 100644 src/smt/asserted_formulas.cpp delete mode 100644 src/smt/asserted_formulas.h delete mode 100644 src/test/bv_simplifier_plugin.cpp diff --git a/src/ast/rewriter/CMakeLists.txt b/src/ast/rewriter/CMakeLists.txt index 804fbcbed..57924b48a 100644 --- a/src/ast/rewriter/CMakeLists.txt +++ b/src/ast/rewriter/CMakeLists.txt @@ -6,13 +6,13 @@ z3_add_component(rewriter bit2int.cpp bool_rewriter.cpp bv_bounds.cpp - bv_elim2.cpp + bv_elim.cpp bv_rewriter.cpp datatype_rewriter.cpp der.cpp distribute_forall.cpp dl_rewriter.cpp - elim_bounds2.cpp + elim_bounds.cpp enum2bv_rewriter.cpp expr_replacer.cpp expr_safe_replace.cpp diff --git a/src/ast/rewriter/bv_elim2.cpp b/src/ast/rewriter/bv_elim.cpp similarity index 99% rename from src/ast/rewriter/bv_elim2.cpp rename to src/ast/rewriter/bv_elim.cpp index 5b542e59e..270d7deb8 100644 --- a/src/ast/rewriter/bv_elim2.cpp +++ b/src/ast/rewriter/bv_elim.cpp @@ -4,7 +4,7 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ast/rewriter/bv_elim2.h" +#include "ast/rewriter/bv_elim.h" #include "ast/bv_decl_plugin.h" #include "ast/rewriter/var_subst.h" #include "ast/rewriter/rewriter_def.h" diff --git a/src/ast/rewriter/bv_elim2.h b/src/ast/rewriter/bv_elim.h similarity index 96% rename from src/ast/rewriter/bv_elim2.h rename to src/ast/rewriter/bv_elim.h index a4829b207..6468cb8b9 100644 --- a/src/ast/rewriter/bv_elim2.h +++ b/src/ast/rewriter/bv_elim.h @@ -17,8 +17,8 @@ Author: Revision History: --*/ -#ifndef BV_ELIM2_H_ -#define BV_ELIM2_H_ +#ifndef BV_ELIM_H_ +#define BV_ELIM_H_ #include "ast/ast.h" #include "ast/rewriter/rewriter.h" diff --git a/src/ast/rewriter/elim_bounds2.cpp b/src/ast/rewriter/elim_bounds2.cpp deleted file mode 100644 index 9691ade09..000000000 --- a/src/ast/rewriter/elim_bounds2.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - elim_bounds2.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-28. - -Revision History: - ---*/ - -#ifndef ELIM_BOUNDS_H_ -#define ELIM_BOUNDS_H_ - -#include "ast/used_vars.h" -#include "util/obj_hashtable.h" -#include "ast/rewriter/var_subst.h" -#include "ast/rewriter/elim_bounds2.h" -#include "ast/ast_pp.h" - -elim_bounds_cfg::elim_bounds_cfg(ast_manager & m): - m(m), - m_util(m) { -} - -/** - \brief Find bounds of the form - - (<= x k) - (<= (+ x (* -1 y)) k) - (<= (+ x (* -1 t)) k) - (<= (+ t (* -1 x)) k) - - x and y are a bound variables, t is a ground term and k is a numeral - - It also detects >=, and the atom can be negated. -*/ -bool elim_bounds_cfg::is_bound(expr * n, var * & lower, var * & upper) { - upper = 0; - lower = 0; - bool neg = false; - if (m.is_not(n)) { - n = to_app(n)->get_arg(0); - neg = true; - } - - expr* l = 0, *r = 0; - bool le = false; - if (m_util.is_le(n, l, r) && m_util.is_numeral(r)) { - n = l; - le = true; - } - else if (m_util.is_ge(n, l, r) && m_util.is_numeral(r)) { - n = l; - le = false; - } - else { - return false; - } - - if (neg) - le = !le; - - if (is_var(n)) { - upper = to_var(n); - } - else if (m_util.is_add(n, l, r)) { - expr * arg1 = l; - expr * arg2 = r; - if (is_var(arg1)) - upper = to_var(arg1); - else if (!is_ground(arg1)) - return false; - rational k; - bool is_int; - if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) { - arg2 = to_app(arg2)->get_arg(1); - if (is_var(arg2)) - lower = to_var(arg2); - else if (!is_ground(arg2)) - return false; // not supported - } - else { - return false; // not supported - } - } - else { - return false; - } - - if (!le) - std::swap(upper, lower); - - return true; -} - -bool elim_bounds_cfg::is_bound(expr * n) { - var * lower, * upper; - return is_bound(n, lower, upper); -} - - -bool elim_bounds_cfg::reduce_quantifier(quantifier * q, - expr * n, - expr * const * new_patterns, - expr * const * new_no_patterns, - expr_ref & result, - proof_ref & result_pr) { - if (!q->is_forall()) { - return false; - } - unsigned num_vars = q->get_num_decls(); - ptr_buffer atoms; - if (m.is_or(n)) - atoms.append(to_app(n)->get_num_args(), to_app(n)->get_args()); - else - atoms.push_back(n); - used_vars used_vars; - // collect non-candidates - for (expr * a : atoms) { - if (!is_bound(a)) - used_vars.process(a); - } - if (used_vars.uses_all_vars(q->get_num_decls())) { - return false; - } - // collect candidates - obj_hashtable lowers; - obj_hashtable uppers; - obj_hashtable candidate_set; - ptr_buffer candidates; -#define ADD_CANDIDATE(V) if (!lowers.contains(V) && !uppers.contains(V)) { candidate_set.insert(V); candidates.push_back(V); } - for (expr * a : atoms) { - var * lower = 0; - var * upper = 0; - if (is_bound(a, lower, upper)) { - if (lower != 0 && !used_vars.contains(lower->get_idx()) && lower->get_idx() < num_vars) { - ADD_CANDIDATE(lower); - lowers.insert(lower); - } - if (upper != 0 && !used_vars.contains(upper->get_idx()) && upper->get_idx() < num_vars) { - ADD_CANDIDATE(upper); - uppers.insert(upper); - } - } - } - TRACE("elim_bounds", tout << "candidates:\n"; for (unsigned i = 0; i < candidates.size(); i++) tout << mk_pp(candidates[i], m) << "\n";); - // remove candidates that have lower and upper bounds - - for (var * v : candidates) { - if (lowers.contains(v) && uppers.contains(v)) - candidate_set.erase(v); - } - TRACE("elim_bounds", tout << "candidates after filter:\n"; for (unsigned i = 0; i < candidates.size(); i++) tout << mk_pp(candidates[i], m) << "\n";); - if (candidate_set.empty()) { - return false; - } - // remove bounds that contain variables in candidate_set - unsigned j = 0; - for (unsigned i = 0; i < atoms.size(); ++i) { - expr * a = atoms[i]; - var * lower = 0; - var * upper = 0; - if (is_bound(a, lower, upper) && ((lower != 0 && candidate_set.contains(lower)) || (upper != 0 && candidate_set.contains(upper)))) - continue; - atoms[j] = a; - j++; - } - if (j == atoms.size()) { - return false; - } - atoms.resize(j); - expr * new_body = 0; - switch (atoms.size()) { - case 0: - result = m.mk_false(); - result_pr = m.mk_rewrite(q, result); - TRACE("elim_bounds", tout << mk_pp(q, m) << "\n" << result << "\n";); - return true; - case 1: - new_body = atoms[0]; - break; - default: - new_body = m.mk_or(atoms.size(), atoms.c_ptr()); - break; - } - quantifier_ref new_q(m); - new_q = m.update_quantifier(q, new_body); - elim_unused_vars(m, new_q, params_ref(), result); - result_pr = m.mk_rewrite(q, result); - TRACE("elim_bounds", tout << mk_pp(q, m) << "\n" << result << "\n";); - return true; -} - -#endif /* ELIM_BOUNDS_H_ */ diff --git a/src/ast/rewriter/elim_bounds2.h b/src/ast/rewriter/elim_bounds2.h deleted file mode 100644 index e0bba4e60..000000000 --- a/src/ast/rewriter/elim_bounds2.h +++ /dev/null @@ -1,77 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - elim_bounds2.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-28. - -Revision History: - ---*/ -#ifndef ELIM_BOUNDS2_H_ -#define ELIM_BOUNDS2_H_ - -#include "ast/ast.h" -#include "ast/arith_decl_plugin.h" -#include "ast/rewriter/rewriter.h" - -/** - \brief Functor for eliminating irrelevant bounds in quantified formulas. - - Example: - (forall (x Int) (y Int) (or (not (>= y x) (not (>= x 0)) (= (select a x) 1)))) - - The bound (>= y x) is irrelevant and can be eliminated. - - This can be easily proved by using Fourier-Motzkin elimination. - - Limitations & Assumptions: - - It assumes the input formula was already simplified. - - It can only handle bounds in the diff-logic fragment. - - \remark This operation is subsumed by Fourier-Motzkin elimination. -*/ -class elim_bounds_cfg : public default_rewriter_cfg { - ast_manager & m; - arith_util m_util; - bool is_bound(expr * n, var * & lower, var * & upper); - bool is_bound(expr * n); -public: - elim_bounds_cfg(ast_manager & m); - - bool reduce_quantifier(quantifier * old_q, - expr * new_body, - expr * const * new_patterns, - expr * const * new_no_patterns, - expr_ref & result, - proof_ref & result_pr); -}; - -/** - \brief Functor for applying elim_bounds2 in all - universal quantifiers in an expression. - - Assumption: the formula was already skolemized. -*/ -class elim_bounds_rw : public rewriter_tpl { -protected: - elim_bounds_cfg m_cfg; -public: - elim_bounds_rw(ast_manager & m): - rewriter_tpl(m, m.proofs_enabled(), m_cfg), - m_cfg(m) - {} - - virtual ~elim_bounds_rw() {} -}; - -#endif /* ELIM_BOUNDS2_H_ */ - diff --git a/src/ast/simplifier/CMakeLists.txt b/src/ast/simplifier/CMakeLists.txt index 52a44595e..649c0486e 100644 --- a/src/ast/simplifier/CMakeLists.txt +++ b/src/ast/simplifier/CMakeLists.txt @@ -1,21 +1,21 @@ z3_add_component(simplifier SOURCES - arith_simplifier_params.cpp - arith_simplifier_plugin.cpp - array_simplifier_params.cpp - array_simplifier_plugin.cpp - basic_simplifier_plugin.cpp - bv_elim.cpp - bv_simplifier_params.cpp - bv_simplifier_plugin.cpp - datatype_simplifier_plugin.cpp - elim_bounds.cpp - fpa_simplifier_plugin.cpp - maximise_ac_sharing.cpp - poly_simplifier_plugin.cpp - seq_simplifier_plugin.cpp - simplifier.cpp - simplifier_plugin.cpp + arith_simplifier_params.cpp +# arith_simplifier_plugin.cpp + array_simplifier_params.cpp +# array_simplifier_plugin.cpp +# basic_simplifier_plugin.cpp +# bv_elim.cpp + bv_simplifier_params.cpp +# bv_simplifier_plugin.cpp +# datatype_simplifier_plugin.cpp +# elim_bounds.cpp +# fpa_simplifier_plugin.cpp +# maximise_ac_sharing.cpp +# poly_simplifier_plugin.cpp +# seq_simplifier_plugin.cpp +# simplifier.cpp +# simplifier_plugin.cpp COMPONENT_DEPENDENCIES rewriter PYG_FILES diff --git a/src/smt/CMakeLists.txt b/src/smt/CMakeLists.txt index 5c4c6b0b9..385d1aaa0 100644 --- a/src/smt/CMakeLists.txt +++ b/src/smt/CMakeLists.txt @@ -2,7 +2,6 @@ z3_add_component(smt SOURCES arith_eq_adapter.cpp arith_eq_solver.cpp -## asserted_formulas.cpp asserted_formulas_new.cpp cached_var_subst.cpp cost_evaluator.cpp diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp deleted file mode 100644 index 44ccd0bf6..000000000 --- a/src/smt/asserted_formulas.cpp +++ /dev/null @@ -1,879 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - asserted_formulas.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-11. - -Revision History: - ---*/ -#include "util/warning.h" -#include "ast/ast_ll_pp.h" -#include "ast/ast_pp.h" -#include "ast/for_each_expr.h" -#include "ast/well_sorted.h" -#include "ast/rewriter/rewriter_def.h" -#include "ast/rewriter/pull_ite_tree.h" -#include "ast/rewriter/push_app_ite.h" -#include "ast/rewriter/inj_axiom.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/array_simplifier_plugin.h" -#include "ast/simplifier/datatype_simplifier_plugin.h" -#include "ast/simplifier/fpa_simplifier_plugin.h" -#include "ast/simplifier/seq_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" -#include "ast/simplifier/bv_elim.h" -#include "ast/simplifier/elim_bounds.h" -#include "ast/normal_forms/pull_quant.h" -#include "ast/normal_forms/nnf.h" -#include "ast/pattern/pattern_inference.h" -#include "ast/rewriter/der.h" -#include "ast/rewriter/distribute_forall.h" -#include "ast/macros/quasi_macros.h" -#include "smt/asserted_formulas.h" -#include "smt/elim_term_ite.h" - -asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): - m(m), - m_params(p), - m_pre_simplifier(m), - m_simplifier(m), - m_rewriter(m), - m_defined_names(m), - m_static_features(m), - m_asserted_formulas(m), - m_asserted_formula_prs(m), - m_asserted_qhead(0), - m_macro_manager(m), - m_bit2int(m), - m_bv_sharing(m), - m_inconsistent(false), - m_has_quantifiers(false) { - - m_bsimp = 0; - m_bvsimp = 0; - arith_simplifier_plugin * arith_simp = 0; - setup_simplifier_plugins(m_simplifier, m_bsimp, arith_simp, m_bvsimp); - SASSERT(m_bsimp != 0); - SASSERT(arith_simp != 0); - m_macro_finder = alloc(macro_finder, m, m_macro_manager); - - basic_simplifier_plugin * basic_simp = 0; - bv_simplifier_plugin * bv_simp = 0; - setup_simplifier_plugins(m_pre_simplifier, basic_simp, arith_simp, bv_simp); - m_pre_simplifier.enable_presimp(); -} - -void asserted_formulas::setup() { - switch (m_params.m_lift_ite) { - case LI_FULL: - m_params.m_ng_lift_ite = LI_NONE; - break; - case LI_CONSERVATIVE: - if (m_params.m_ng_lift_ite == LI_CONSERVATIVE) - m_params.m_ng_lift_ite = LI_NONE; - break; - default: - break; - } - - if (m_params.m_relevancy_lvl == 0) - m_params.m_relevancy_lemma = false; -} - -void asserted_formulas::setup_simplifier_plugins(simplifier & s, basic_simplifier_plugin * & bsimp, arith_simplifier_plugin * & asimp, bv_simplifier_plugin * & bvsimp) { - bsimp = alloc(basic_simplifier_plugin, m); - s.register_plugin(bsimp); - asimp = alloc(arith_simplifier_plugin, m, *bsimp, m_params); - s.register_plugin(asimp); - s.register_plugin(alloc(array_simplifier_plugin, m, *bsimp, s, m_params)); - bvsimp = alloc(bv_simplifier_plugin, m, *bsimp, m_params); - s.register_plugin(bvsimp); - s.register_plugin(alloc(datatype_simplifier_plugin, m, *bsimp)); - s.register_plugin(alloc(fpa_simplifier_plugin, m, *bsimp)); - s.register_plugin(alloc(seq_simplifier_plugin, m, *bsimp)); -} - -void asserted_formulas::init(unsigned num_formulas, expr * const * formulas, proof * const * prs) { - SASSERT(m_asserted_formulas.empty()); - SASSERT(m_asserted_formula_prs.empty()); - SASSERT(!m_inconsistent); - SASSERT(m_scopes.empty()); - m_asserted_formulas.append(num_formulas, formulas); - if (m.proofs_enabled()) - m_asserted_formula_prs.append(num_formulas, prs); -} - -bool asserted_formulas::has_bv() const { - // approaximated answer... assume the formula has bit-vectors if the bv_simplifier_plugin was invoked at least once. - return m_bvsimp->reduce_invoked(); -} - -asserted_formulas::~asserted_formulas() { -} - -void asserted_formulas::push_assertion(expr * e, proof * pr, expr_ref_vector & result, proof_ref_vector & result_prs) { - if (inconsistent()) { - SASSERT(!result.empty()); - return; - } - if (m.is_false(e)) - m_inconsistent = true; - ::push_assertion(m, e, pr, result, result_prs); -} - -void asserted_formulas::set_eliminate_and(bool flag) { - if (m_bsimp->eliminate_and() == flag) - return; - TRACE("eliminate_and", tout << "flushing cache...\n";); - flush_cache(); - m_bsimp->set_eliminate_and(flag); -} - - -void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { - if (inconsistent()) - return; - m_has_quantifiers |= ::has_quantifiers(e); - if (!m_params.m_preprocess) { - push_assertion(e, _in_pr, m_asserted_formulas, m_asserted_formula_prs); - return; - } - proof_ref in_pr(_in_pr, m); - expr_ref r1(m); - proof_ref pr1(m); - expr_ref r2(m); - proof_ref pr2(m); - TRACE("assert_expr_before_simp", tout << mk_ll_pp(e, m) << "\n";); - TRACE("assert_expr_bug", tout << mk_pp(e, m) << "\n";); - if (m_params.m_pre_simplifier) { - m_pre_simplifier(e, r1, pr1); - } - else { - r1 = e; - pr1 = 0; - } - set_eliminate_and(false); // do not eliminate and before nnf. - m_simplifier(r1, r2, pr2); - TRACE("assert_expr_bug", tout << "after...\n" << mk_pp(r1, m) << "\n";); - if (m.proofs_enabled()) { - if (e == r2) - pr2 = in_pr; - else - pr2 = m.mk_modus_ponens(in_pr, m.mk_transitivity(pr1, pr2)); - } - TRACE("assert_expr_after_simp", tout << mk_ll_pp(r1, m) << "\n";); - push_assertion(r2, pr2, m_asserted_formulas, m_asserted_formula_prs); - TRACE("asserted_formulas_bug", tout << "after assert_expr\n"; display(tout);); -} - -void asserted_formulas::assert_expr(expr * e) { - if (inconsistent()) - return; - assert_expr(e, m.mk_asserted(e)); -} - -void asserted_formulas::get_assertions(ptr_vector & result) { - result.append(m_asserted_formulas.size(), m_asserted_formulas.c_ptr()); -} - -void asserted_formulas::push_scope() { - SASSERT(inconsistent() || m_asserted_qhead == m_asserted_formulas.size() || m.canceled()); - TRACE("asserted_formulas_scopes", tout << "push:\n"; display(tout);); - m_scopes.push_back(scope()); - m_macro_manager.push_scope(); - scope & s = m_scopes.back(); - s.m_asserted_formulas_lim = m_asserted_formulas.size(); - SASSERT(inconsistent() || s.m_asserted_formulas_lim == m_asserted_qhead || m.canceled()); - s.m_inconsistent_old = m_inconsistent; - m_defined_names.push(); - m_bv_sharing.push_scope(); - commit(); -} - -void asserted_formulas::pop_scope(unsigned num_scopes) { - TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << "\n"; display(tout);); - m_bv_sharing.pop_scope(num_scopes); - m_macro_manager.pop_scope(num_scopes); - unsigned new_lvl = m_scopes.size() - num_scopes; - scope & s = m_scopes[new_lvl]; - m_inconsistent = s.m_inconsistent_old; - m_defined_names.pop(num_scopes); - m_asserted_formulas.shrink(s.m_asserted_formulas_lim); - if (m.proofs_enabled()) - m_asserted_formula_prs.shrink(s.m_asserted_formulas_lim); - m_asserted_qhead = s.m_asserted_formulas_lim; - m_scopes.shrink(new_lvl); - flush_cache(); - TRACE("asserted_formulas_scopes", tout << "after pop " << num_scopes << "\n"; display(tout);); -} - -void asserted_formulas::reset() { - m_defined_names.reset(); - m_asserted_qhead = 0; - m_asserted_formulas.reset(); - m_asserted_formula_prs.reset(); - m_macro_manager.reset(); - m_bv_sharing.reset(); - m_inconsistent = false; -} - - -#ifdef Z3DEBUG -bool asserted_formulas::check_well_sorted() const { - for (unsigned i = 0; i < m_asserted_formulas.size(); i++) { - if (!is_well_sorted(m, m_asserted_formulas.get(i))) return false; - } - return true; -} -#endif - -void asserted_formulas::reduce() { - if (inconsistent()) - return; - if (canceled()) { - return; - } - if (m_asserted_qhead == m_asserted_formulas.size()) - return; - if (!m_params.m_preprocess) - return; - - if (m_macro_manager.has_macros()) - expand_macros(); - TRACE("before_reduce", display(tout);); - CASSERT("well_sorted", check_well_sorted()); - - -#define INVOKE(COND, FUNC) if (COND) { FUNC; IF_VERBOSE(10000, verbose_stream() << "total size: " << get_total_size() << "\n";); } TRACE("reduce_step_ll", ast_mark visited; display_ll(tout, visited);); TRACE("reduce_step", display(tout << #FUNC << " ");); CASSERT("well_sorted",check_well_sorted()); if (inconsistent() || canceled()) { TRACE("after_reduce", display(tout);); TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); return; } - - set_eliminate_and(false); // do not eliminate and before nnf. - INVOKE(m_params.m_propagate_booleans, propagate_booleans()); - INVOKE(m_params.m_propagate_values, propagate_values()); - INVOKE(m_params.m_macro_finder && has_quantifiers(), find_macros()); - INVOKE(m_params.m_nnf_cnf || (m_params.m_mbqi && has_quantifiers()), nnf_cnf()); - INVOKE(/*m_params.m_eliminate_and*/ true, eliminate_and()); - INVOKE(m_params.m_pull_cheap_ite_trees, pull_cheap_ite_trees()); - INVOKE(m_params.m_pull_nested_quantifiers && has_quantifiers(), pull_nested_quantifiers()); - INVOKE(m_params.m_ng_lift_ite != LI_NONE, ng_lift_ite()); - INVOKE(m_params.m_lift_ite != LI_NONE, lift_ite()); - INVOKE(m_params.m_eliminate_term_ite && m_params.m_lift_ite != LI_FULL, eliminate_term_ite()); - INVOKE(m_params.m_refine_inj_axiom && has_quantifiers(), refine_inj_axiom()); - INVOKE(m_params.m_distribute_forall && has_quantifiers(), apply_distribute_forall()); - TRACE("qbv_bug", tout << "after distribute_forall:\n"; display(tout);); - INVOKE(m_params.m_macro_finder && has_quantifiers(), find_macros()); - INVOKE(m_params.m_quasi_macros && has_quantifiers(), apply_quasi_macros()); - INVOKE(m_params.m_simplify_bit2int, apply_bit2int()); - INVOKE(m_params.m_eliminate_bounds && has_quantifiers(), cheap_quant_fourier_motzkin()); - INVOKE(m_params.m_ematching && has_quantifiers(), infer_patterns()); - INVOKE(m_params.m_max_bv_sharing && has_bv(), max_bv_sharing()); - INVOKE(m_params.m_bb_quantifiers, elim_bvs_from_quantifiers()); - // temporary HACK: make sure that arith & bv are list-assoc - // this may destroy some simplification steps such as max_bv_sharing - reduce_asserted_formulas(); - - CASSERT("well_sorted",check_well_sorted()); - - IF_VERBOSE(10, verbose_stream() << "(smt.simplifier-done)\n";); - TRACE("after_reduce", display(tout);); - TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); - TRACE("macros", m_macro_manager.display(tout);); - flush_cache(); -} - -void asserted_formulas::eliminate_and() { - IF_IVERBOSE(10, verbose_stream() << "(smt.eliminating-and)\n";); - set_eliminate_and(true); - reduce_asserted_formulas(); - TRACE("after_elim_and", display(tout);); -} - -unsigned asserted_formulas::get_formulas_last_level() const { - if (m_scopes.empty()) { - return 0; - } - else { - return m_scopes.back().m_asserted_formulas_lim; - } -} - -void asserted_formulas::collect_static_features() { - if (m_params.m_display_features) { - unsigned sz = m_asserted_formulas.size(); - unsigned head = m_asserted_qhead; - while (head < sz) { - expr * f = m_asserted_formulas.get(head); - head++; - m_static_features.collect(f); - } - m_static_features.display_primitive(std::cout); - m_static_features.display(std::cout); - } -} - -void asserted_formulas::display(std::ostream & out) const { - out << "asserted formulas:\n"; - for (unsigned i = 0; i < m_asserted_formulas.size(); i++) { - if (i == m_asserted_qhead) - out << "[HEAD] ==>\n"; - out << mk_pp(m_asserted_formulas.get(i), m) << "\n"; - } - out << "inconsistent: " << inconsistent() << "\n"; -} - -void asserted_formulas::display_ll(std::ostream & out, ast_mark & pp_visited) const { - if (!m_asserted_formulas.empty()) { - unsigned sz = m_asserted_formulas.size(); - for (unsigned i = 0; i < sz; i++) - ast_def_ll_pp(out, m, m_asserted_formulas.get(i), pp_visited, true, false); - out << "asserted formulas:\n"; - for (unsigned i = 0; i < sz; i++) - out << "#" << m_asserted_formulas[i]->get_id() << " "; - out << "\n"; - } -} - -void asserted_formulas::collect_statistics(statistics & st) const { -} - -void asserted_formulas::reduce_asserted_formulas() { - if (inconsistent()) { - return; - } - expr_ref_vector new_exprs(m); - proof_ref_vector new_prs(m); - unsigned i = m_asserted_qhead; - unsigned sz = m_asserted_formulas.size(); - for (; i < sz && !inconsistent(); i++) { - expr * n = m_asserted_formulas.get(i); - SASSERT(n != 0); - proof * pr = m_asserted_formula_prs.get(i, 0); - expr_ref new_n(m); - proof_ref new_pr(m); - m_simplifier(n, new_n, new_pr); - TRACE("reduce_asserted_formulas", tout << mk_pp(n, m) << " -> " << mk_pp(new_n, m) << "\n";); - if (n == new_n.get()) { - push_assertion(n, pr, new_exprs, new_prs); - } - else { - new_pr = m.mk_modus_ponens(pr, new_pr); - push_assertion(new_n, new_pr, new_exprs, new_prs); - } - if (canceled()) { - return; - } - } - swap_asserted_formulas(new_exprs, new_prs); -} - -void asserted_formulas::swap_asserted_formulas(expr_ref_vector & new_exprs, proof_ref_vector & new_prs) { - SASSERT(!inconsistent() || !new_exprs.empty()); - m_asserted_formulas.shrink(m_asserted_qhead); - m_asserted_formulas.append(new_exprs); - if (m.proofs_enabled()) { - m_asserted_formula_prs.shrink(m_asserted_qhead); - m_asserted_formula_prs.append(new_prs); - } -} - -void asserted_formulas::find_macros_core() { - expr_ref_vector new_exprs(m); - proof_ref_vector new_prs(m); - unsigned sz = m_asserted_formulas.size(); - expr_dependency_ref_vector new_deps(m); - m_macro_finder->operator()(sz - m_asserted_qhead, - m_asserted_formulas.c_ptr() + m_asserted_qhead, - m_asserted_formula_prs.c_ptr() + m_asserted_qhead, - 0, // 0 == No dependency tracking - new_exprs, new_prs, new_deps); - swap_asserted_formulas(new_exprs, new_prs); - reduce_and_solve(); -} - -void asserted_formulas::find_macros() { - IF_IVERBOSE(10, verbose_stream() << "(smt.find-macros)\n";); - TRACE("before_find_macros", display(tout);); - find_macros_core(); - TRACE("after_find_macros", display(tout);); -} - -void asserted_formulas::expand_macros() { - IF_IVERBOSE(10, verbose_stream() << "(smt.expand-macros)\n";); - find_macros_core(); -} - -void asserted_formulas::apply_quasi_macros() { - IF_IVERBOSE(10, verbose_stream() << "(smt.find-quasi-macros)\n";); - TRACE("before_quasi_macros", display(tout);); - expr_ref_vector new_exprs(m); - proof_ref_vector new_prs(m); - expr_dependency_ref_vector new_deps(m); - quasi_macros proc(m, m_macro_manager); - while (proc(m_asserted_formulas.size() - m_asserted_qhead, - m_asserted_formulas.c_ptr() + m_asserted_qhead, - m_asserted_formula_prs.c_ptr() + m_asserted_qhead, - 0, // 0 == No dependency tracking - new_exprs, new_prs, new_deps)) { - swap_asserted_formulas(new_exprs, new_prs); - new_exprs.reset(); - new_prs.reset(); - new_deps.reset(); - } - TRACE("after_quasi_macros", display(tout);); - reduce_and_solve(); -} - -void asserted_formulas::nnf_cnf() { - IF_IVERBOSE(10, verbose_stream() << "(smt.nnf)\n";); - nnf apply_nnf(m, m_defined_names); - expr_ref_vector new_exprs(m); - proof_ref_vector new_prs(m); - expr_ref_vector push_todo(m); - proof_ref_vector push_todo_prs(m); - - unsigned i = m_asserted_qhead; - unsigned sz = m_asserted_formulas.size(); - TRACE("nnf_bug", tout << "i: " << i << " sz: " << sz << "\n";); - for (; i < sz; i++) { - expr * n = m_asserted_formulas.get(i); - TRACE("nnf_bug", tout << "processing:\n" << mk_pp(n, m) << "\n";); - proof * pr = m_asserted_formula_prs.get(i, 0); - expr_ref r1(m); - proof_ref pr1(m); - CASSERT("well_sorted",is_well_sorted(m, n)); - push_todo.reset(); - push_todo_prs.reset(); - apply_nnf(n, push_todo, push_todo_prs, r1, pr1); - CASSERT("well_sorted",is_well_sorted(m, r1)); - pr = m.mk_modus_ponens(pr, pr1); - push_todo.push_back(r1); - push_todo_prs.push_back(pr); - - if (canceled()) { - return; - } - unsigned sz2 = push_todo.size(); - for (unsigned k = 0; k < sz2; k++) { - expr * n = push_todo.get(k); - proof * pr = 0; - m_simplifier(n, r1, pr1); - CASSERT("well_sorted",is_well_sorted(m, r1)); - if (canceled()) { - return; - } - - if (m.proofs_enabled()) - pr = m.mk_modus_ponens(push_todo_prs.get(k), pr1); - else - pr = 0; - push_assertion(r1, pr, new_exprs, new_prs); - } - } - swap_asserted_formulas(new_exprs, new_prs); -} - -#define MK_SIMPLE_SIMPLIFIER(NAME, FUNCTOR_DEF, LABEL, MSG) \ -void asserted_formulas::NAME() { \ - IF_IVERBOSE(10, verbose_stream() << "(smt." << MSG << ")\n";); \ - TRACE(LABEL, tout << "before:\n"; display(tout);); \ - FUNCTOR_DEF; \ - expr_ref_vector new_exprs(m); \ - proof_ref_vector new_prs(m); \ - unsigned i = m_asserted_qhead; \ - unsigned sz = m_asserted_formulas.size(); \ - for (; i < sz; i++) { \ - expr * n = m_asserted_formulas.get(i); \ - proof * pr = m_asserted_formula_prs.get(i, 0); \ - expr_ref new_n(m); \ - functor(n, new_n); \ - TRACE("simplifier_simple_step", tout << mk_pp(n, m) << "\n" << mk_pp(new_n, m) << "\n";); \ - if (n == new_n.get()) { \ - push_assertion(n, pr, new_exprs, new_prs); \ - } \ - else if (m.proofs_enabled()) { \ - proof_ref new_pr(m); \ - new_pr = m.mk_rewrite_star(n, new_n, 0, 0); \ - new_pr = m.mk_modus_ponens(pr, new_pr); \ - push_assertion(new_n, new_pr, new_exprs, new_prs); \ - } \ - else { \ - push_assertion(new_n, 0, new_exprs, new_prs); \ - } \ - } \ - swap_asserted_formulas(new_exprs, new_prs); \ - TRACE(LABEL, display(tout);); \ - reduce_and_solve(); \ - TRACE(LABEL, display(tout);); \ -} - -MK_SIMPLE_SIMPLIFIER(apply_distribute_forall, distribute_forall functor(m), "distribute_forall", "distribute-forall"); - -void asserted_formulas::reduce_and_solve() { - IF_IVERBOSE(10, verbose_stream() << "(smt.reducing)\n";); - flush_cache(); // collect garbage - reduce_asserted_formulas(); -} - -void asserted_formulas::infer_patterns() { - IF_IVERBOSE(10, verbose_stream() << "(smt.pattern-inference)\n";); - TRACE("before_pattern_inference", display(tout);); - pattern_inference_rw infer(m, m_params); - expr_ref_vector new_exprs(m); - proof_ref_vector new_prs(m); - unsigned i = m_asserted_qhead; - unsigned sz = m_asserted_formulas.size(); - for (; i < sz; i++) { - expr * n = m_asserted_formulas.get(i); - proof * pr = m_asserted_formula_prs.get(i, 0); - expr_ref new_n(m); - proof_ref new_pr(m); - infer(n, new_n, new_pr); - if (n == new_n.get()) { - push_assertion(n, pr, new_exprs, new_prs); - } - else if (m.proofs_enabled()) { - new_pr = m.mk_modus_ponens(pr, new_pr); - push_assertion(new_n, new_pr, new_exprs, new_prs); - } - else { - push_assertion(new_n, 0, new_exprs, new_prs); - } - } - swap_asserted_formulas(new_exprs, new_prs); - TRACE("after_pattern_inference", display(tout);); -} - -void asserted_formulas::commit() { - commit(m_asserted_formulas.size()); -} - -void asserted_formulas::commit(unsigned new_qhead) { - m_macro_manager.mark_forbidden(new_qhead - m_asserted_qhead, m_asserted_formulas.c_ptr() + m_asserted_qhead); - m_asserted_qhead = new_qhead; -} - -void asserted_formulas::eliminate_term_ite() { - IF_IVERBOSE(10, verbose_stream() << "(smt.eliminating-ite-term)\n";); - TRACE("before_elim_term_ite", display(tout);); - elim_term_ite elim(m, m_defined_names); - expr_ref_vector new_exprs(m); - proof_ref_vector new_prs(m); - unsigned i = m_asserted_qhead; - unsigned sz = m_asserted_formulas.size(); - for (; i < sz; i++) { - expr * n = m_asserted_formulas.get(i); - proof * pr = m_asserted_formula_prs.get(i, 0); - expr_ref new_n(m); - proof_ref new_pr(m); - elim(n, new_exprs, new_prs, new_n, new_pr); - SASSERT(new_n.get() != 0); - DEBUG_CODE({ - for (unsigned i = 0; i < new_exprs.size(); i++) { - SASSERT(new_exprs.get(i) != 0); - } - }); - if (n == new_n.get()) { - push_assertion(n, pr, new_exprs, new_prs); - } - else if (m.proofs_enabled()) { - new_pr = m.mk_modus_ponens(pr, new_pr); - push_assertion(new_n, new_pr, new_exprs, new_prs); - } - else { - push_assertion(new_n, 0, new_exprs, new_prs); - } - } - swap_asserted_formulas(new_exprs, new_prs); - TRACE("after_elim_term_ite", display(tout);); - reduce_and_solve(); - TRACE("after_elim_term_ite", display(tout);); -} - -void asserted_formulas::propagate_values() { - IF_IVERBOSE(10, verbose_stream() << "(smt.constant-propagation)\n";); - TRACE("propagate_values", tout << "before:\n"; display(tout);); - flush_cache(); - bool found = false; - // Separate the formulas in two sets: C and R - // C is a set which contains formulas of the form - // { x = n }, where x is a variable and n a numeral. - // R contains the rest. - // - // - new_exprs1 is the set C - // - new_exprs2 is the set R - // - // The loop also updates the m_cache. It adds the entries x -> n to it. - expr_ref_vector new_exprs1(m); - proof_ref_vector new_prs1(m); - expr_ref_vector new_exprs2(m); - proof_ref_vector new_prs2(m); - unsigned sz = m_asserted_formulas.size(); - for (unsigned i = 0; i < sz; i++) { - expr_ref n(m_asserted_formulas.get(i), m); - proof_ref pr(m_asserted_formula_prs.get(i, 0), m); - TRACE("simplifier", tout << mk_pp(n, m) << "\n";); - expr* lhs, *rhs; - if (m.is_eq(n, lhs, rhs) && - (m.is_value(lhs) || m.is_value(rhs))) { - if (m.is_value(lhs)) { - std::swap(lhs, rhs); - n = m.mk_eq(lhs, rhs); - pr = m.mk_symmetry(pr); - } - if (!m.is_value(lhs) && !m_simplifier.is_cached(lhs)) { - if (i >= m_asserted_qhead) { - new_exprs1.push_back(n); - if (m.proofs_enabled()) - new_prs1.push_back(pr); - } - TRACE("propagate_values", tout << "found:\n" << mk_pp(lhs, m) << "\n->\n" << mk_pp(rhs, m) << "\n"; - if (pr) tout << "proof: " << mk_pp(pr, m) << "\n";); - m_simplifier.cache_result(lhs, rhs, pr); - found = true; - continue; - } - } - if (i >= m_asserted_qhead) { - new_exprs2.push_back(n); - if (m.proofs_enabled()) - new_prs2.push_back(pr); - } - } - TRACE("propagate_values", tout << "found: " << found << "\n";); - // If C is not empty, then reduce R using the updated simplifier cache with entries - // x -> n for each constraint 'x = n' in C. - if (found) { - unsigned sz = new_exprs2.size(); - for (unsigned i = 0; i < sz; i++) { - expr * n = new_exprs2.get(i); - proof * pr = new_prs2.get(i, 0); - expr_ref new_n(m); - proof_ref new_pr(m); - m_simplifier(n, new_n, new_pr); - if (n == new_n.get()) { - push_assertion(n, pr, new_exprs1, new_prs1); - } - else { - new_pr = m.mk_modus_ponens(pr, new_pr); - push_assertion(new_n, new_pr, new_exprs1, new_prs1); - } - } - swap_asserted_formulas(new_exprs1, new_prs1); - // IMPORTANT: the cache MUST be flushed. This guarantees that all entries - // x->n will be removed from m_cache. If we don't do that, the next transformation - // may simplify constraints in C using these entries, and the variables x in C - // will be (silently) eliminated, and models produced by Z3 will not contain them. - flush_cache(); - } - TRACE("propagate_values", tout << "after:\n"; display(tout);); -} - -void asserted_formulas::propagate_booleans() { - bool cont = true; - bool modified = false; - flush_cache(); - while (cont) { - TRACE("propagate_booleans", tout << "before:\n"; display(tout);); - IF_IVERBOSE(10, verbose_stream() << "(smt.propagate-booleans)\n";); - cont = false; - unsigned i = m_asserted_qhead; - unsigned sz = m_asserted_formulas.size(); -#define PROCESS() { \ - expr * n = m_asserted_formulas.get(i); \ - proof * pr = m_asserted_formula_prs.get(i, 0); \ - expr_ref new_n(m); \ - proof_ref new_pr(m); \ - m_simplifier(n, new_n, new_pr); \ - m_asserted_formulas.set(i, new_n); \ - if (m.proofs_enabled()) { \ - new_pr = m.mk_modus_ponens(pr, new_pr); \ - m_asserted_formula_prs.set(i, new_pr); \ - } \ - if (n != new_n) { \ - cont = true; \ - modified = true; \ - } \ - if (m.is_not(new_n)) \ - m_simplifier.cache_result(to_app(new_n)->get_arg(0), m.mk_false(), m.mk_iff_false(new_pr)); \ - else \ - m_simplifier.cache_result(new_n, m.mk_true(), m.mk_iff_true(new_pr)); \ - } - for (; i < sz; i++) { - PROCESS(); - } - flush_cache(); - TRACE("propagate_booleans", tout << "middle:\n"; display(tout);); - i = sz; - while (i > m_asserted_qhead) { - --i; - PROCESS(); - } - flush_cache(); - TRACE("propagate_booleans", tout << "after:\n"; display(tout);); - } - if (modified) - reduce_asserted_formulas(); -} - -#define MK_SIMPLIFIER(NAME, FUNCTOR, TAG, MSG, REDUCE) \ - bool asserted_formulas::NAME() { \ - IF_IVERBOSE(10, verbose_stream() << "(smt." << MSG << ")\n";); \ - TRACE(TAG, ast_mark visited; display_ll(tout, visited);); \ - FUNCTOR; \ - bool changed = false; \ - expr_ref_vector new_exprs(m); \ - proof_ref_vector new_prs(m); \ - unsigned i = m_asserted_qhead; \ - unsigned sz = m_asserted_formulas.size(); \ - for (; i < sz; i++) { \ - expr * n = m_asserted_formulas.get(i); \ - proof * pr = m_asserted_formula_prs.get(i, 0); \ - expr_ref new_n(m); \ - proof_ref new_pr(m); \ - functor(n, new_n, new_pr); \ - if (n == new_n.get()) { \ - push_assertion(n, pr, new_exprs, new_prs); \ - } \ - else if (m.proofs_enabled()) { \ - changed = true; \ - if (!new_pr) new_pr = m.mk_rewrite(n, new_n); \ - new_pr = m.mk_modus_ponens(pr, new_pr); \ - push_assertion(new_n, new_pr, new_exprs, new_prs); \ - } \ - else { \ - changed = true; \ - push_assertion(new_n, 0, new_exprs, new_prs); \ - } \ - } \ - swap_asserted_formulas(new_exprs, new_prs); \ - TRACE(TAG, ast_mark visited; display_ll(tout, visited);); \ - if (changed && REDUCE) { \ - reduce_and_solve(); \ - TRACE(TAG, ast_mark visited; display_ll(tout, visited);); \ - } \ - return changed; \ - } - -MK_SIMPLIFIER(pull_cheap_ite_trees, pull_cheap_ite_tree_rw functor(m), "pull_cheap_ite_trees", "pull-cheap-ite-trees", false); - -MK_SIMPLIFIER(pull_nested_quantifiers, pull_nested_quant functor(m), "pull_nested_quantifiers", "pull-nested-quantifiers", false); - -proof * asserted_formulas::get_inconsistency_proof() const { - if (!inconsistent()) - return 0; - if (!m.proofs_enabled()) - return 0; - unsigned sz = m_asserted_formulas.size(); - for (unsigned i = 0; i < sz; i++) { - expr * f = m_asserted_formulas.get(i); - if (m.is_false(f)) - return m_asserted_formula_prs.get(i); - } - UNREACHABLE(); - return 0; -} - -void asserted_formulas::refine_inj_axiom() { - IF_IVERBOSE(10, verbose_stream() << "(smt.refine-injectivity)\n";); - TRACE("inj_axiom", display(tout);); - unsigned i = m_asserted_qhead; - unsigned sz = m_asserted_formulas.size(); - for (; i < sz; i++) { - expr * n = m_asserted_formulas.get(i); - proof * pr = m_asserted_formula_prs.get(i, 0); - expr_ref new_n(m); - if (is_quantifier(n) && simplify_inj_axiom(m, to_quantifier(n), new_n)) { - TRACE("inj_axiom", tout << "simplifying...\n" << mk_pp(n, m) << "\n" << mk_pp(new_n, m) << "\n";); - m_asserted_formulas.set(i, new_n); - if (m.proofs_enabled()) { - proof_ref new_pr(m); - new_pr = m.mk_rewrite(n, new_n); - new_pr = m.mk_modus_ponens(pr, new_pr); - m_asserted_formula_prs.set(i, new_pr); - } - } - } - TRACE("inj_axiom", display(tout);); -} - -MK_SIMPLIFIER(apply_bit2int, bit2int& functor = m_bit2int, "bit2int", "propagate-bit-vector-over-integers", true); - -MK_SIMPLIFIER(cheap_quant_fourier_motzkin, elim_bounds_star functor(m), "elim_bounds", "cheap-fourier-motzkin", true); - - - -MK_SIMPLIFIER(elim_bvs_from_quantifiers, bv_elim_star functor(m), "bv_elim", "eliminate-bit-vectors-from-quantifiers", true); - -#define LIFT_ITE(NAME, FUNCTOR, MSG) \ - void asserted_formulas::NAME() { \ - IF_IVERBOSE(10, verbose_stream() << "(smt." << MSG << ")\n";); \ - TRACE("lift_ite", display(tout);); \ - FUNCTOR; \ - unsigned i = m_asserted_qhead; \ - unsigned sz = m_asserted_formulas.size(); \ - for (; i < sz; i++) { \ - expr * n = m_asserted_formulas.get(i); \ - proof * pr = m_asserted_formula_prs.get(i, 0); \ - expr_ref new_n(m); \ - proof_ref new_pr(m); \ - functor(n, new_n, new_pr); \ - TRACE("lift_ite_step", tout << mk_pp(n, m) << "\n";); \ - IF_IVERBOSE(10000, verbose_stream() << "lift before: " << get_num_exprs(n) << ", after: " << get_num_exprs(new_n) << "\n";); \ - m_asserted_formulas.set(i, new_n); \ - if (m.proofs_enabled()) { \ - new_pr = m.mk_modus_ponens(pr, new_pr); \ - m_asserted_formula_prs.set(i, new_pr); \ - } \ - } \ - TRACE("lift_ite", display(tout);); \ - reduce_and_solve(); \ - } - -LIFT_ITE(lift_ite, push_app_ite_rw functor(m, m_params.m_lift_ite == LI_CONSERVATIVE), "lifting ite"); -LIFT_ITE(ng_lift_ite, ng_push_app_ite_rw functor(m, m_params.m_ng_lift_ite == LI_CONSERVATIVE), "lifting ng ite"); - -unsigned asserted_formulas::get_total_size() const { - expr_mark visited; - unsigned r = 0; - unsigned sz = m_asserted_formulas.size(); - for (unsigned i = 0; i < sz; i++) - r += get_num_exprs(m_asserted_formulas.get(i), visited); - return r; -} - -void asserted_formulas::max_bv_sharing() { - IF_IVERBOSE(10, verbose_stream() << "(smt.maximizing-bv-sharing)\n";); - TRACE("bv_sharing", display(tout);); - unsigned i = m_asserted_qhead; - unsigned sz = m_asserted_formulas.size(); - for (; i < sz; i++) { - expr * n = m_asserted_formulas.get(i); - proof * pr = m_asserted_formula_prs.get(i, 0); - expr_ref new_n(m); - proof_ref new_pr(m); - m_bv_sharing(n, new_n, new_pr); - m_asserted_formulas.set(i, new_n); - if (m.proofs_enabled()) { - new_pr = m.mk_modus_ponens(pr, new_pr); - m_asserted_formula_prs.set(i, new_pr); - } - } - reduce_asserted_formulas(); - TRACE("bv_sharing", display(tout);); - -} - -#ifdef Z3DEBUG -void pp(asserted_formulas & f) { - f.display(std::cout); -} -#endif diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h deleted file mode 100644 index 1e15e6300..000000000 --- a/src/smt/asserted_formulas.h +++ /dev/null @@ -1,151 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - asserted_formulas.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-11. - -Revision History: - ---*/ -#ifndef ASSERTED_FORMULAS_H_ -#define ASSERTED_FORMULAS_H_ - -#include "util/statistics.h" -#include "ast/static_features.h" -#include "ast/simplifier/simplifier.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/maximise_ac_sharing.h" -#include "ast/rewriter/bit2int.h" -#include "ast/macros/macro_manager.h" -#include "ast/macros/macro_finder.h" -#include "ast/normal_forms/defined_names.h" -#include "ast/pattern/pattern_inference.h" -#include "smt/params/smt_params.h" -#include "ast/rewriter/th_rewriter.h" - -class arith_simplifier_plugin; -class bv_simplifier_plugin; - -class asserted_formulas { - ast_manager & m; - smt_params & m_params; - simplifier m_pre_simplifier; - simplifier m_simplifier; - th_rewriter m_rewriter; - basic_simplifier_plugin * m_bsimp; - bv_simplifier_plugin * m_bvsimp; - defined_names m_defined_names; - static_features m_static_features; - expr_ref_vector m_asserted_formulas; // formulas asserted by user - proof_ref_vector m_asserted_formula_prs; // proofs for the asserted formulas. - unsigned m_asserted_qhead; - - macro_manager m_macro_manager; - scoped_ptr m_macro_finder; - - bit2int m_bit2int; - - maximise_bv_sharing m_bv_sharing; - - bool m_inconsistent; - bool m_has_quantifiers; - - struct scope { - unsigned m_asserted_formulas_lim; - bool m_inconsistent_old; - }; - svector m_scopes; - - void setup_simplifier_plugins(simplifier & s, basic_simplifier_plugin * & bsimp, arith_simplifier_plugin * & asimp, bv_simplifier_plugin * & bvsimp); - void reduce_asserted_formulas(); - void swap_asserted_formulas(expr_ref_vector & new_exprs, proof_ref_vector & new_prs); - void find_macros_core(); - void find_macros(); - void expand_macros(); - void apply_quasi_macros(); - void nnf_cnf(); - void infer_patterns(); - void eliminate_term_ite(); - void reduce_and_solve(); - void flush_cache() { m_pre_simplifier.reset(); m_simplifier.reset(); } - void set_eliminate_and(bool flag); - void propagate_values(); - void propagate_booleans(); - bool pull_cheap_ite_trees(); - bool pull_nested_quantifiers(); - void push_assertion(expr * e, proof * pr, expr_ref_vector & result, proof_ref_vector & result_prs); - void eliminate_and(); - void refine_inj_axiom(); - bool cheap_quant_fourier_motzkin(); - void apply_distribute_forall(); - bool apply_bit2int(); - void lift_ite(); - bool elim_bvs_from_quantifiers(); - void ng_lift_ite(); -#ifdef Z3DEBUG - bool check_well_sorted() const; -#endif - unsigned get_total_size() const; - bool has_bv() const; - void max_bv_sharing(); - bool canceled() { return m.canceled(); } - -public: - asserted_formulas(ast_manager & m, smt_params & p); - ~asserted_formulas(); - - void setup(); - void assert_expr(expr * e, proof * in_pr); - void assert_expr(expr * e); - void reset(); - void push_scope(); - void pop_scope(unsigned num_scopes); - bool inconsistent() const { return m_inconsistent; } - proof * get_inconsistency_proof() const; - void reduce(); - unsigned get_num_formulas() const { return m_asserted_formulas.size(); } - unsigned get_formulas_last_level() const; - unsigned get_qhead() const { return m_asserted_qhead; } - void commit(); - void commit(unsigned new_qhead); - expr * get_formula(unsigned idx) const { return m_asserted_formulas.get(idx); } - proof * get_formula_proof(unsigned idx) const { return m.proofs_enabled() ? m_asserted_formula_prs.get(idx) : 0; } - expr * const * get_formulas() const { return m_asserted_formulas.c_ptr(); } - proof * const * get_formula_proofs() const { return m_asserted_formula_prs.c_ptr(); } - void init(unsigned num_formulas, expr * const * formulas, proof * const * prs); - void register_simplifier_plugin(simplifier_plugin * p) { m_simplifier.register_plugin(p); } - // simplifier & get_simplifier() { return m_simplifier; } - th_rewriter& get_rewriter() { return m_rewriter; } - void get_assertions(ptr_vector & result); - bool empty() const { return m_asserted_formulas.empty(); } - void collect_static_features(); - void display(std::ostream & out) const; - void display_ll(std::ostream & out, ast_mark & pp_visited) const; - void collect_statistics(statistics & st) const; - // TODO: improve precision of the following method. - bool has_quantifiers() const { return m_has_quantifiers; } - - // ----------------------------------- - // - // Macros - // - // ----------------------------------- - unsigned get_num_macros() const { return m_macro_manager.get_num_macros(); } - unsigned get_first_macro_last_level() const { return m_macro_manager.get_first_macro_last_level(); } - func_decl * get_macro_func_decl(unsigned i) const { return m_macro_manager.get_macro_func_decl(i); } - func_decl * get_macro_interpretation(unsigned i, expr_ref & interp) const { return m_macro_manager.get_macro_interpretation(i, interp); } - quantifier * get_macro_quantifier(func_decl * f) const { return m_macro_manager.get_macro_quantifier(f); } - void insert_macro(func_decl * f, quantifier * m, proof * pr, expr_dependency * dep) { m_macro_manager.insert(f, m, pr, dep); } -}; - -#endif /* ASSERTED_FORMULAS_H_ */ - diff --git a/src/smt/asserted_formulas_new.cpp b/src/smt/asserted_formulas_new.cpp index 5d4783bf8..8d16ef2cd 100644 --- a/src/smt/asserted_formulas_new.cpp +++ b/src/smt/asserted_formulas_new.cpp @@ -431,7 +431,7 @@ void asserted_formulas_new::propagate_values() { flush_cache(); unsigned num_prop = 0; - while (true) { + while (!inconsistent()) { m_expr2depth.reset(); m_scoped_substitution.push(); unsigned prop = num_prop; @@ -474,6 +474,9 @@ unsigned asserted_formulas_new::propagate_values(unsigned i) { } justified_expr j(m, new_n, new_pr); m_formulas[i] = j; + if (m.is_false(j.get_fml())) { + m_inconsistent = true; + } update_substitution(new_n, new_pr); return n != new_n ? 1 : 0; } @@ -484,13 +487,16 @@ void asserted_formulas_new::update_substitution(expr* n, proof* pr) { compute_depth(lhs); compute_depth(rhs); if (is_gt(lhs, rhs)) { + TRACE("propagate_values", tout << "insert " << mk_pp(lhs, m) << " -> " << mk_pp(rhs, m) << "\n";); m_scoped_substitution.insert(lhs, rhs, pr); return; } if (is_gt(rhs, lhs)) { + TRACE("propagate_values", tout << "insert " << mk_pp(rhs, m) << " -> " << mk_pp(lhs, m) << "\n";); m_scoped_substitution.insert(rhs, lhs, m.mk_symmetry(pr)); return; } + TRACE("propagate_values", tout << "incompatible " << mk_pp(n, m) << "\n";); } if (m.is_not(n, n1)) { m_scoped_substitution.insert(n1, m.mk_false(), m.mk_iff_false(pr)); diff --git a/src/smt/asserted_formulas_new.h b/src/smt/asserted_formulas_new.h index 60af46dea..82f18250d 100644 --- a/src/smt/asserted_formulas_new.h +++ b/src/smt/asserted_formulas_new.h @@ -29,9 +29,9 @@ Revision History: #include "ast/rewriter/pull_ite_tree.h" #include "ast/rewriter/push_app_ite.h" #include "ast/rewriter/inj_axiom.h" -#include "ast/rewriter/bv_elim2.h" +#include "ast/rewriter/bv_elim.h" #include "ast/rewriter/der.h" -#include "ast/rewriter/elim_bounds2.h" +#include "ast/rewriter/elim_bounds.h" #include "ast/macros/macro_manager.h" #include "ast/macros/macro_finder.h" #include "ast/normal_forms/defined_names.h" @@ -210,7 +210,7 @@ class asserted_formulas_new { void apply_quasi_macros(); void nnf_cnf(); void reduce_and_solve(); - void flush_cache() { m_rewriter.reset(); } + void flush_cache() { m_rewriter.reset(); m_rewriter.set_substitution(&m_substitution); } void set_eliminate_and(bool flag); void propagate_values(); unsigned propagate_values(unsigned i); diff --git a/src/smt/elim_term_ite.cpp b/src/smt/elim_term_ite.cpp index d9cfac775..e8b70fc59 100644 --- a/src/smt/elim_term_ite.cpp +++ b/src/smt/elim_term_ite.cpp @@ -19,144 +19,6 @@ Revision History: #include "smt/elim_term_ite.h" #include "ast/ast_smt2_pp.h" -void elim_term_ite::operator()(expr * n, - expr_ref_vector & new_defs, - proof_ref_vector & new_def_proofs, - expr_ref & r, - proof_ref & pr) { - - m_coarse_proofs.reset(); - m_new_defs = &new_defs; - m_new_def_proofs = &new_def_proofs; - reduce_core(n); - expr * r2; - proof * pr2; - get_cached(n, r2, pr2); - r = r2; - switch (m.proof_mode()) { - case PGM_DISABLED: - pr = m.mk_undef_proof(); - break; - case PGM_COARSE: - remove_duplicates(m_coarse_proofs); - pr = n == r2 ? m.mk_oeq_reflexivity(n) : m.mk_apply_defs(n, r, m_coarse_proofs.size(), m_coarse_proofs.c_ptr()); - break; - case PGM_FINE: - pr = pr2 == 0 ? m.mk_oeq_reflexivity(n) : pr2; - break; - } - m_coarse_proofs.reset(); -} - -void elim_term_ite::reduce_core(expr * n) { - m_todo.reset(); - if (!is_cached(n)) { - m_todo.push_back(n); - while (!m_todo.empty()) { - expr * n = m_todo.back(); - if (is_cached(n)) { - m_todo.pop_back(); - } - else if (visit_children(n)) { - m_todo.pop_back(); - reduce1(n); - } - } - } -} - -bool elim_term_ite::visit_children(expr * n) { - bool visited = true; - unsigned j; - switch(n->get_kind()) { - case AST_VAR: - return true; - case AST_APP: - j = to_app(n)->get_num_args(); - while (j > 0) { - --j; - visit(to_app(n)->get_arg(j), visited); - } - return visited; - case AST_QUANTIFIER: - visit(to_quantifier(n)->get_expr(), visited); - return visited; - default: - UNREACHABLE(); - return true; - } -} - -void elim_term_ite::reduce1(expr * n) { - switch (n->get_kind()) { - case AST_VAR: - cache_result(n, n, 0); - break; - case AST_APP: - reduce1_app(to_app(n)); - break; - case AST_QUANTIFIER: - reduce1_quantifier(to_quantifier(n)); - break; - default: - UNREACHABLE(); - } -} - -void elim_term_ite::reduce1_app(app * n) { - m_args.reset(); - - func_decl * decl = n->get_decl(); - proof_ref p1(m); - get_args(n, m_args, p1); - if (!m.fine_grain_proofs()) - p1 = 0; - - expr_ref r(m); - r = m.mk_app(decl, m_args.size(), m_args.c_ptr()); - if (m.is_term_ite(r)) { - expr_ref new_def(m); - proof_ref new_def_pr(m); - app_ref new_r(m); - proof_ref new_pr(m); - if (m_defined_names.mk_name(r, new_def, new_def_pr, new_r, new_pr)) { - CTRACE("elim_term_ite_bug", new_def.get() == 0, tout << mk_ismt2_pp(r, m) << "\n";); - SASSERT(new_def.get() != 0); - m_new_defs->push_back(new_def); - if (m.fine_grain_proofs()) { - m_new_def_proofs->push_back(new_def_pr); - new_pr = m.mk_transitivity(p1, new_pr); - } - else { - // [Leo] This looks fishy... why do we add 0 into m_coarse_proofs when fine_grain_proofs are disabled? - new_pr = 0; - if (m.proofs_enabled()) - m_coarse_proofs.push_back(new_pr); - } - } - else { - SASSERT(new_def.get() == 0); - if (!m.fine_grain_proofs()) - new_pr = 0; - } - cache_result(n, new_r, new_pr); - } - else { - cache_result(n, r, p1); - } -} - -void elim_term_ite::reduce1_quantifier(quantifier * q) { - expr * new_body; - proof * new_body_pr; - get_cached(q->get_expr(), new_body, new_body_pr); - - quantifier * new_q = m.update_quantifier(q, new_body); - proof * p = q == new_q ? 0 : m.mk_oeq_quant_intro(q, new_q, new_body_pr); - cache_result(q, new_q, p); -} - - br_status elim_term_ite_cfg::reduce_app(func_decl* f, unsigned n, expr * const* args, expr_ref& result, proof_ref& result_pr) { if (!m.is_term_ite(f)) { return BR_FAILED; diff --git a/src/smt/elim_term_ite.h b/src/smt/elim_term_ite.h index a57ea1dad..8e8340dc0 100644 --- a/src/smt/elim_term_ite.h +++ b/src/smt/elim_term_ite.h @@ -21,35 +21,8 @@ Revision History: #include "ast/normal_forms/defined_names.h" #include "ast/rewriter/rewriter.h" -#include "ast/simplifier/simplifier.h" #include "ast/justified_expr.h" - -class elim_term_ite : public simplifier { - defined_names & m_defined_names; - proof_ref_vector m_coarse_proofs; - expr_ref_vector * m_new_defs; - proof_ref_vector * m_new_def_proofs; - void reduce_core(expr * n); - bool visit_children(expr * n); - void reduce1(expr * n); - void reduce1_app(app * n); - void reduce1_quantifier(quantifier * q); -public: - elim_term_ite(ast_manager & m, defined_names & d):simplifier(m), m_defined_names(d), m_coarse_proofs(m) { - m_use_oeq = true; - enable_ac_support(false); - } - virtual ~elim_term_ite() {} - void operator()(expr * n, // [IN] - expr_ref_vector & new_defs, // [OUT] new definitions - proof_ref_vector & new_def_proofs, // [OUT] proofs of the new definitions - expr_ref & r, // [OUT] resultant expression - proof_ref & pr // [OUT] proof for (~ n r) - ); -}; - - class elim_term_ite_cfg : public default_rewriter_cfg { ast_manager& m; defined_names & m_defined_names; diff --git a/src/smt/expr_context_simplifier.h b/src/smt/expr_context_simplifier.h index ed15044e7..b412d8646 100644 --- a/src/smt/expr_context_simplifier.h +++ b/src/smt/expr_context_simplifier.h @@ -21,10 +21,10 @@ Revision History: #include "ast/ast.h" #include "util/obj_hashtable.h" -#include "ast/simplifier/basic_simplifier_plugin.h" #include "smt/params/smt_params.h" #include "smt/smt_kernel.h" #include "ast/arith_decl_plugin.h" +#include "ast/rewriter/bool_rewriter.h" class expr_context_simplifier { typedef obj_map context_map; @@ -33,7 +33,7 @@ class expr_context_simplifier { arith_util m_arith; context_map m_context; expr_ref_vector m_trail; - basic_simplifier_plugin m_simp; + bool_rewriter m_simp; expr_mark m_mark; bool m_forward; public: diff --git a/src/smt/params/CMakeLists.txt b/src/smt/params/CMakeLists.txt index c965f0a62..500423dcc 100644 --- a/src/smt/params/CMakeLists.txt +++ b/src/smt/params/CMakeLists.txt @@ -13,6 +13,7 @@ z3_add_component(smt_params ast bit_blaster pattern + simplifier PYG_FILES smt_params_helper.pyg ) diff --git a/src/smt/smt_consequences.cpp b/src/smt/smt_consequences.cpp index 65af3c0bd..0bf2a2939 100644 --- a/src/smt/smt_consequences.cpp +++ b/src/smt/smt_consequences.cpp @@ -16,12 +16,13 @@ Author: Revision History: --*/ -#include "smt/smt_context.h" -#include "ast/ast_util.h" -#include "ast/datatype_decl_plugin.h" -#include "model/model_pp.h" #include "util/max_cliques.h" #include "util/stopwatch.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" +#include "ast/datatype_decl_plugin.h" +#include "model/model_pp.h" +#include "smt/smt_context.h" namespace smt { diff --git a/src/smt/smt_quantifier.cpp b/src/smt/smt_quantifier.cpp index 6a2f848d9..22004ee78 100644 --- a/src/smt/smt_quantifier.cpp +++ b/src/smt/smt_quantifier.cpp @@ -16,6 +16,8 @@ Author: Revision History: --*/ +#include "ast/ast_pp.h" +#include "ast/ast_smt2_pp.h" #include "smt/smt_quantifier.h" #include "smt/smt_context.h" #include "smt/smt_quantifier_stat.h" @@ -24,7 +26,6 @@ Revision History: #include "smt/smt_quick_checker.h" #include "smt/mam.h" #include "smt/qi_queue.h" -#include "ast/ast_smt2_pp.h" namespace smt { diff --git a/src/smt/theory_array.cpp b/src/smt/theory_array.cpp index 17eefb361..18fc9f50b 100644 --- a/src/smt/theory_array.cpp +++ b/src/smt/theory_array.cpp @@ -19,6 +19,7 @@ Revision History: #include "smt/smt_context.h" #include "smt/theory_array.h" #include "ast/ast_ll_pp.h" +#include "ast/ast_pp.h" #include "util/stats.h" namespace smt { diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index 124fea910..0c09d0403 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -28,6 +28,7 @@ Revision History: #include "util/optional.h" #include "util/lp/lp_params.hpp" #include "util/inf_rational.h" +#include "ast/ast_pp.h" #include "smt/smt_theory.h" #include "smt/smt_context.h" #include "smt/theory_lra.h" diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index c91882dad..8d6d70a79 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -19,11 +19,12 @@ Revision History: --*/ #include +#include "ast/ast_pp.h" +#include "ast/ast_trail.h" #include "smt/proto_model/value_factory.h" #include "smt/smt_context.h" #include "smt/smt_model_generator.h" #include "smt/theory_seq.h" -#include "ast/ast_trail.h" #include "smt/theory_arith.h" #include "smt/smt_kernel.h" diff --git a/src/smt/theory_str.h b/src/smt/theory_str.h index 5837980df..686fcdd57 100644 --- a/src/smt/theory_str.h +++ b/src/smt/theory_str.h @@ -17,13 +17,14 @@ #ifndef _THEORY_STR_H_ #define _THEORY_STR_H_ +#include "util/trail.h" +#include "ast/ast_pp.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/th_rewriter.h" #include "smt/smt_theory.h" #include "smt/params/theory_str_params.h" -#include "util/trail.h" -#include "ast/rewriter/th_rewriter.h" #include "smt/proto_model/value_factory.h" #include "smt/smt_model_generator.h" -#include "ast/arith_decl_plugin.h" #include #include #include diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index b395c09e6..fbcaec5ef 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -20,7 +20,6 @@ add_executable(test-z3 bits.cpp bit_vector.cpp buffer.cpp - bv_simplifier_plugin.cpp chashtable.cpp check_assumptions.cpp cnf_backbones.cpp diff --git a/src/test/bv_simplifier_plugin.cpp b/src/test/bv_simplifier_plugin.cpp deleted file mode 100644 index 15ca9fac5..000000000 --- a/src/test/bv_simplifier_plugin.cpp +++ /dev/null @@ -1,326 +0,0 @@ - -/*++ -Copyright (c) 2015 Microsoft Corporation - ---*/ - -#include "ast/simplifier/bv_simplifier_plugin.h" -#include "ast/arith_decl_plugin.h" -#include "ast/ast_pp.h" -#include "ast/reg_decl_plugins.h" - -class tst_bv_simplifier_plugin_cls { - class mgr { - public: - mgr(ast_manager& m) { - reg_decl_plugins(m); - } - }; - ast_manager m_manager; - mgr m_mgr; - bv_simplifier_params m_bv_params; - basic_simplifier_plugin m_bsimp; - arith_util m_arith; - bv_simplifier_plugin m_simp; - bv_util m_bv_util; - family_id m_fid; - - void get_num(expr* e, unsigned bv_size, rational& r) { - unsigned bv_size0; - if (!m_bv_util.is_numeral(e, r, bv_size0)) { - UNREACHABLE(); - } - ENSURE(bv_size == bv_size0); - } - - unsigned u32(expr* e) { - rational r; - std::cout << mk_pp(e,m_manager) << "\n"; - get_num(e, 32, r); - return r.get_unsigned(); - } - - unsigned char u8(expr* e) { - rational r; - get_num(e, 8, r); - return static_cast(r.get_unsigned()); - } - int i32(expr* e) { - return static_cast(u32(e)); - } - - uint64 u64(expr* e) { - rational r; - get_num(e, 64, r); - return r.get_uint64(); - } - - int64 i64(expr* e) { - rational r; - get_num(e, 64, r); - if (r >= power(rational(2), 63)) { - r -= power(rational(2), 64); - } - return r.get_int64(); - } - - bool ast2bool(expr* e) { - if (m_manager.is_true(e)) { - return true; - } - if (m_manager.is_false(e)) { - return false; - } - UNREACHABLE(); - return false; - } - - bool bit2bool(expr* e) { - rational r; - get_num(e, 1, r); - return 0 != r.get_unsigned(); - } - - expr* mk_int(unsigned i) { - return m_arith.mk_numeral(rational(i), true); - } - -public: - - tst_bv_simplifier_plugin_cls() : - m_mgr(m_manager), - m_bsimp(m_manager), - m_arith(m_manager), - m_simp(m_manager, m_bsimp, m_bv_params), - m_bv_util(m_manager), - m_fid(0) { - m_fid = m_manager.mk_family_id("bv"); - } - - ~tst_bv_simplifier_plugin_cls() {} - - void test_num(unsigned a) { - expr_ref e(m_manager), e1(m_manager); - app_ref ar(m_manager); - uint64 a64 = static_cast(a); - - e1 = m_bv_util.mk_numeral(rational(a), 32); - expr* const es[1] = { e1.get() }; - - ar = m_manager.mk_app(m_fid, OP_BNEG, e1.get()); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE((0-a) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BNOT, e1.get()); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE((~a) == u32(e.get())); - - parameter params[2] = { parameter(32), parameter(32) }; - ar = m_manager.mk_app(m_fid, OP_SIGN_EXT, 1, params, 1, es); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE(((int64)(int)a) == i64(e.get())); - - ar = m_manager.mk_app(m_fid, OP_ZERO_EXT, 1, params, 1, es); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE(((uint64)a) == u64(e.get())); - - params[0] = parameter(7); - params[1] = parameter(0); - ar = m_manager.mk_app(m_fid, OP_EXTRACT, 2, params, 1, es); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE(((unsigned char)a) == u8(e.get())); - - params[0] = parameter(2); - ar = m_manager.mk_app(m_fid, OP_REPEAT, 1, params, 1, es); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY(((a64 << 32) | a64) == u64(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BREDOR, e1.get()); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE((a != 0) == bit2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BREDAND, e1.get()); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE((a == 0xFFFFFFFF) == bit2bool(e.get())); - - params[0] = parameter(8); - - ar = m_manager.mk_app(m_fid, OP_ROTATE_LEFT, 1, params, 1, es); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE(((a << 8) | (a >> 24)) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_ROTATE_RIGHT, 1, params, 1, es); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE(((a >> 8) | (a << 24)) == u32(e.get())); - - params[0] = parameter(m_manager.mk_sort(m_manager.mk_family_id("arith"), INT_SORT)); - ar = m_manager.mk_app(m_fid, OP_BV2INT, 1, params, 1, es); - expr* es2[1] = { ar.get() }; - params[0] = parameter(32); - ar = m_manager.mk_app(m_fid, OP_INT2BV, 1, params, 1, es2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - ENSURE(a == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BIT0); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY(!bit2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BIT1); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY(bit2bool(e.get())); - - } - - void test_pair(unsigned a, unsigned b) { - - expr_ref e(m_manager), e1(m_manager), e2(m_manager); - app_ref ar(m_manager); - int sa = static_cast(a); - int sb = static_cast(b); - uint64 a64 = static_cast(a); - uint64 b64 = static_cast(b); - - e1 = m_bv_util.mk_numeral(rational(a), 32); - e2 = m_bv_util.mk_numeral(rational(b), 32); - expr* const e1e2[] = { e1.get(), e2.get() }; - - - ar = m_manager.mk_app(m_fid, OP_BADD, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a + b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BSUB, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a - b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BMUL, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a * b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BAND, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a & b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BOR, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a | b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BNOR, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY(~(a | b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BXOR, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a ^ b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BXNOR, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((~(a ^ b)) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BNAND, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((~(a & b)) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_ULEQ, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a <= b) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_UGEQ, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a >= b) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_ULT, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a < b) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_UGT, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a > b) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_SLEQ, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((sa <= sb) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_SGEQ, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((sa >= sb) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_SLT, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((sa < sb) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_SGT, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((sa > sb) == ast2bool(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BSHL, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY(((b>=32)?0:(a << b)) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BLSHR, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY(((b>=32)?0:(a >> b)) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BASHR, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - - std::cout << "compare: " << sa << " >> " << b << " = " << (sa >> b) << " with " << i32(e.get()) << "\n"; - VERIFY(b >= 32 || ((sa >> b) == i32(e.get()))); - - if (b != 0) { - ar = m_manager.mk_app(m_fid, OP_BSDIV, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((sa / sb) == i32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BUDIV, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a / b) == u32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BSREM, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - //VERIFY((sa % sb) == i32(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BUREM, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a % b) == u32(e.get())); - - // TBD: BSMOD. - } - - ar = m_manager.mk_app(m_fid, OP_CONCAT, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY(((a64 << 32) | b64) == u64(e.get())); - - ar = m_manager.mk_app(m_fid, OP_BCOMP, 2, e1e2); - m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e); - VERIFY((a == b) == bit2bool(e.get())); - } - - void test() { - unsigned_vector nums; - nums.push_back(0); - nums.push_back(1); - nums.push_back(-1); - nums.push_back(2); - nums.push_back(31); - nums.push_back(32); - nums.push_back(33); - nums.push_back(435562); - nums.push_back(-43556211); - // TBD add some random numbers. - - - for (unsigned i = 0; i < nums.size(); ++i) { - test_num(nums[i]); - for (unsigned j = 0; j < nums.size(); ++j) { - test_pair(nums[i], nums[j]); - } - } - } -}; - - -void tst_bv_simplifier_plugin() { - tst_bv_simplifier_plugin_cls tst_cls; - tst_cls.test(); -} diff --git a/src/test/main.cpp b/src/test/main.cpp index 17ac720dc..2c51df601 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -166,7 +166,6 @@ int main(int argc, char ** argv) { TST(timeout); TST(proof_checker); TST(simplifier); - TST(bv_simplifier_plugin); TST(bit_blaster); TST(var_subst); TST(simple_parser); diff --git a/src/test/quant_elim.cpp b/src/test/quant_elim.cpp index fec86d164..3674e6b70 100644 --- a/src/test/quant_elim.cpp +++ b/src/test/quant_elim.cpp @@ -6,12 +6,7 @@ Copyright (c) 2015 Microsoft Corporation #include "ast/ast.h" #include "smt/params/smt_params.h" -#include "ast/simplifier/simplifier.h" #include "qe/qe.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/array_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/ast_pp.h" #include "parsers/smt/smtlib.h" #include "parsers/smt/smtparser.h" @@ -38,7 +33,6 @@ static void test_qe(ast_manager& m, lbool expected_outcome, expr* fml, char cons // enable_trace("after_search"); // enable_trace("bv_bit_prop"); - simplifier simp(m); smt_params params; // params.m_quant_elim = true; diff --git a/src/test/sorting_network.cpp b/src/test/sorting_network.cpp index 909ea594e..2984e94e2 100644 --- a/src/test/sorting_network.cpp +++ b/src/test/sorting_network.cpp @@ -220,7 +220,7 @@ static void test_sorting_eq(unsigned n, unsigned k) { TRACE("pb", unsigned sz = solver.size(); for (unsigned i = 0; i < sz; ++i) { - tout << mk_pp(solver.get_formulas()[i], m) << "\n"; + tout << mk_pp(solver.get_formula(i), m) << "\n"; }); model_ref model; solver.get_model(model); @@ -266,7 +266,7 @@ static void test_sorting_le(unsigned n, unsigned k) { TRACE("pb", unsigned sz = solver.size(); for (unsigned i = 0; i < sz; ++i) { - tout << mk_pp(solver.get_formulas()[i], m) << "\n"; + tout << mk_pp(solver.get_formula(i), m) << "\n"; }); model_ref model; solver.get_model(model); @@ -314,7 +314,7 @@ void test_sorting_ge(unsigned n, unsigned k) { TRACE("pb", unsigned sz = solver.size(); for (unsigned i = 0; i < sz; ++i) { - tout << mk_pp(solver.get_formulas()[i], m) << "\n"; + tout << mk_pp(solver.get_formula(i), m) << "\n"; }); model_ref model; solver.get_model(model); From 809a4efc6bd2f412027702994b897b96c81beb32 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 26 Aug 2017 11:24:19 -0700 Subject: [PATCH 210/488] removing dependencies on simplifier Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/elim_bounds.cpp | 203 +++++++++++++++++++++++++++++++ src/ast/rewriter/elim_bounds.h | 77 ++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 src/ast/rewriter/elim_bounds.cpp create mode 100644 src/ast/rewriter/elim_bounds.h diff --git a/src/ast/rewriter/elim_bounds.cpp b/src/ast/rewriter/elim_bounds.cpp new file mode 100644 index 000000000..d3240e511 --- /dev/null +++ b/src/ast/rewriter/elim_bounds.cpp @@ -0,0 +1,203 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + elim_bounds.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-28. + +Revision History: + +--*/ + +#ifndef ELIM_BOUNDS_H_ +#define ELIM_BOUNDS_H_ + +#include "ast/used_vars.h" +#include "util/obj_hashtable.h" +#include "ast/rewriter/var_subst.h" +#include "ast/rewriter/elim_bounds.h" +#include "ast/ast_pp.h" + +elim_bounds_cfg::elim_bounds_cfg(ast_manager & m): + m(m), + m_util(m) { +} + +/** + \brief Find bounds of the form + + (<= x k) + (<= (+ x (* -1 y)) k) + (<= (+ x (* -1 t)) k) + (<= (+ t (* -1 x)) k) + + x and y are a bound variables, t is a ground term and k is a numeral + + It also detects >=, and the atom can be negated. +*/ +bool elim_bounds_cfg::is_bound(expr * n, var * & lower, var * & upper) { + upper = 0; + lower = 0; + bool neg = false; + if (m.is_not(n)) { + n = to_app(n)->get_arg(0); + neg = true; + } + + expr* l = 0, *r = 0; + bool le = false; + if (m_util.is_le(n, l, r) && m_util.is_numeral(r)) { + n = l; + le = true; + } + else if (m_util.is_ge(n, l, r) && m_util.is_numeral(r)) { + n = l; + le = false; + } + else { + return false; + } + + if (neg) + le = !le; + + if (is_var(n)) { + upper = to_var(n); + } + else if (m_util.is_add(n, l, r)) { + expr * arg1 = l; + expr * arg2 = r; + if (is_var(arg1)) + upper = to_var(arg1); + else if (!is_ground(arg1)) + return false; + rational k; + bool is_int; + if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) { + arg2 = to_app(arg2)->get_arg(1); + if (is_var(arg2)) + lower = to_var(arg2); + else if (!is_ground(arg2)) + return false; // not supported + } + else { + return false; // not supported + } + } + else { + return false; + } + + if (!le) + std::swap(upper, lower); + + return true; +} + +bool elim_bounds_cfg::is_bound(expr * n) { + var * lower, * upper; + return is_bound(n, lower, upper); +} + + +bool elim_bounds_cfg::reduce_quantifier(quantifier * q, + expr * n, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr) { + if (!q->is_forall()) { + return false; + } + unsigned num_vars = q->get_num_decls(); + ptr_buffer atoms; + if (m.is_or(n)) + atoms.append(to_app(n)->get_num_args(), to_app(n)->get_args()); + else + atoms.push_back(n); + used_vars used_vars; + // collect non-candidates + for (expr * a : atoms) { + if (!is_bound(a)) + used_vars.process(a); + } + if (used_vars.uses_all_vars(q->get_num_decls())) { + return false; + } + // collect candidates + obj_hashtable lowers; + obj_hashtable uppers; + obj_hashtable candidate_set; + ptr_buffer candidates; +#define ADD_CANDIDATE(V) if (!lowers.contains(V) && !uppers.contains(V)) { candidate_set.insert(V); candidates.push_back(V); } + for (expr * a : atoms) { + var * lower = 0; + var * upper = 0; + if (is_bound(a, lower, upper)) { + if (lower != 0 && !used_vars.contains(lower->get_idx()) && lower->get_idx() < num_vars) { + ADD_CANDIDATE(lower); + lowers.insert(lower); + } + if (upper != 0 && !used_vars.contains(upper->get_idx()) && upper->get_idx() < num_vars) { + ADD_CANDIDATE(upper); + uppers.insert(upper); + } + } + } + TRACE("elim_bounds", tout << "candidates:\n"; for (unsigned i = 0; i < candidates.size(); i++) tout << mk_pp(candidates[i], m) << "\n";); + // remove candidates that have lower and upper bounds + + for (var * v : candidates) { + if (lowers.contains(v) && uppers.contains(v)) + candidate_set.erase(v); + } + TRACE("elim_bounds", tout << "candidates after filter:\n"; for (unsigned i = 0; i < candidates.size(); i++) tout << mk_pp(candidates[i], m) << "\n";); + if (candidate_set.empty()) { + return false; + } + // remove bounds that contain variables in candidate_set + unsigned j = 0; + for (unsigned i = 0; i < atoms.size(); ++i) { + expr * a = atoms[i]; + var * lower = 0; + var * upper = 0; + if (is_bound(a, lower, upper) && ((lower != 0 && candidate_set.contains(lower)) || (upper != 0 && candidate_set.contains(upper)))) + continue; + atoms[j] = a; + j++; + } + if (j == atoms.size()) { + return false; + } + atoms.resize(j); + expr * new_body = 0; + switch (atoms.size()) { + case 0: + result = m.mk_false(); + result_pr = m.mk_rewrite(q, result); + TRACE("elim_bounds", tout << mk_pp(q, m) << "\n" << result << "\n";); + return true; + case 1: + new_body = atoms[0]; + break; + default: + new_body = m.mk_or(atoms.size(), atoms.c_ptr()); + break; + } + quantifier_ref new_q(m); + new_q = m.update_quantifier(q, new_body); + elim_unused_vars(m, new_q, params_ref(), result); + result_pr = m.mk_rewrite(q, result); + TRACE("elim_bounds", tout << mk_pp(q, m) << "\n" << result << "\n";); + return true; +} + +#endif /* ELIM_BOUNDS_H_ */ diff --git a/src/ast/rewriter/elim_bounds.h b/src/ast/rewriter/elim_bounds.h new file mode 100644 index 000000000..e0bba4e60 --- /dev/null +++ b/src/ast/rewriter/elim_bounds.h @@ -0,0 +1,77 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + elim_bounds2.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-28. + +Revision History: + +--*/ +#ifndef ELIM_BOUNDS2_H_ +#define ELIM_BOUNDS2_H_ + +#include "ast/ast.h" +#include "ast/arith_decl_plugin.h" +#include "ast/rewriter/rewriter.h" + +/** + \brief Functor for eliminating irrelevant bounds in quantified formulas. + + Example: + (forall (x Int) (y Int) (or (not (>= y x) (not (>= x 0)) (= (select a x) 1)))) + + The bound (>= y x) is irrelevant and can be eliminated. + + This can be easily proved by using Fourier-Motzkin elimination. + + Limitations & Assumptions: + - It assumes the input formula was already simplified. + - It can only handle bounds in the diff-logic fragment. + + \remark This operation is subsumed by Fourier-Motzkin elimination. +*/ +class elim_bounds_cfg : public default_rewriter_cfg { + ast_manager & m; + arith_util m_util; + bool is_bound(expr * n, var * & lower, var * & upper); + bool is_bound(expr * n); +public: + elim_bounds_cfg(ast_manager & m); + + bool reduce_quantifier(quantifier * old_q, + expr * new_body, + expr * const * new_patterns, + expr * const * new_no_patterns, + expr_ref & result, + proof_ref & result_pr); +}; + +/** + \brief Functor for applying elim_bounds2 in all + universal quantifiers in an expression. + + Assumption: the formula was already skolemized. +*/ +class elim_bounds_rw : public rewriter_tpl { +protected: + elim_bounds_cfg m_cfg; +public: + elim_bounds_rw(ast_manager & m): + rewriter_tpl(m, m.proofs_enabled(), m_cfg), + m_cfg(m) + {} + + virtual ~elim_bounds_rw() {} +}; + +#endif /* ELIM_BOUNDS2_H_ */ + From 2ede4b2c805a97ddd63f0205d4ba5c2940295a5c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 09:31:16 -0700 Subject: [PATCH 211/488] fixes based on regression tests Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.cpp | 36 ++++---- src/ast/arith_decl_plugin.h | 34 +++---- src/ast/ast.cpp | 1 + src/ast/macros/macro_manager.cpp | 11 ++- src/ast/rewriter/arith_rewriter.cpp | 9 +- src/ast/rewriter/poly_rewriter_def.h | 23 ++--- src/ast/rewriter/push_app_ite.cpp | 1 + src/ast/rewriter/push_app_ite.h | 1 + src/ast/rewriter/rewriter_def.h | 3 +- src/ast/rewriter/rewriter_params.pyg | 1 + src/ast/rewriter/th_rewriter.cpp | 4 +- src/qe/nlqsat.cpp | 12 +-- src/smt/CMakeLists.txt | 2 +- ...formulas_new.cpp => asserted_formulas.cpp} | 88 +++++++++---------- ...ted_formulas_new.h => asserted_formulas.h} | 40 ++++----- src/smt/smt_context.cpp | 4 +- src/smt/smt_context.h | 4 +- src/smt/theory_arith_core.h | 17 ++-- src/smt/theory_array_full.cpp | 8 +- src/smt/theory_lra.cpp | 3 - src/tactic/arith/purify_arith_tactic.cpp | 8 +- 21 files changed, 159 insertions(+), 151 deletions(-) rename src/smt/{asserted_formulas_new.cpp => asserted_formulas.cpp} (86%) rename src/smt/{asserted_formulas_new.h => asserted_formulas.h} (88%) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 01b671c99..0719ebdfa 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -178,7 +178,7 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { MK_AC_OP(m_i_mul_decl, "*", OP_MUL, 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_OP(m_i_mod_decl, "mod", OP_MOD, i); MK_UNARY(m_i_uminus_decl, "-", OP_UMINUS, i); m_to_real_decl = m->mk_func_decl(symbol("to_real"), i, r, func_decl_info(id, OP_TO_REAL)); @@ -215,18 +215,18 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { m_e = m->mk_const(e_decl); m->inc_ref(m_e); - func_decl * z_pw_z_int = m->mk_const_decl(symbol("0^0-int"), i, func_decl_info(id, OP_0_PW_0_INT)); - m_0_pw_0_int = m->mk_const(z_pw_z_int); - m->inc_ref(m_0_pw_0_int); + //func_decl * z_pw_z_int = m->mk_const_decl(symbol("0^0-int"), i, func_decl_info(id, OP_0_PW_0_INT)); + //m_0_pw_0_int = m->mk_const(z_pw_z_int); + //m->inc_ref(m_0_pw_0_int); - func_decl * z_pw_z_real = m->mk_const_decl(symbol("0^0-real"), r, func_decl_info(id, OP_0_PW_0_REAL)); - m_0_pw_0_real = m->mk_const(z_pw_z_real); - m->inc_ref(m_0_pw_0_real); + //func_decl * z_pw_z_real = m->mk_const_decl(symbol("0^0-real"), r, func_decl_info(id, OP_0_PW_0_REAL)); + //m_0_pw_0_real = m->mk_const(z_pw_z_real); + //m->inc_ref(m_0_pw_0_real); MK_OP(m_neg_root_decl, "neg-root", OP_NEG_ROOT, r); - MK_UNARY(m_div_0_decl, "/0", OP_DIV_0, r); - MK_UNARY(m_idiv_0_decl, "div0", OP_IDIV_0, i); - MK_UNARY(m_mod_0_decl, "mod0", OP_MOD_0, i); + //MK_UNARY(m_div_0_decl, "/0", OP_DIV_0, r); + //MK_UNARY(m_idiv_0_decl, "div0", OP_IDIV_0, i); + //MK_UNARY(m_mod_0_decl, "mod0", OP_MOD_0, i); MK_UNARY(m_u_asin_decl, "asin-u", OP_U_ASIN, r); MK_UNARY(m_u_acos_decl, "acos-u", OP_U_ACOS, r); } @@ -392,12 +392,12 @@ inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) { case OP_ATANH: return m_atanh_decl; case OP_PI: return m_pi->get_decl(); case OP_E: return m_e->get_decl(); - case OP_0_PW_0_INT: return m_0_pw_0_int->get_decl(); - case OP_0_PW_0_REAL: return m_0_pw_0_real->get_decl(); + //case OP_0_PW_0_INT: return m_0_pw_0_int->get_decl(); + //case OP_0_PW_0_REAL: return m_0_pw_0_real->get_decl(); case OP_NEG_ROOT: return m_neg_root_decl; - case OP_DIV_0: return m_div_0_decl; - case OP_IDIV_0: return m_idiv_0_decl; - case OP_MOD_0: return m_mod_0_decl; + //case OP_DIV_0: return m_div_0_decl; + //case OP_IDIV_0: return m_idiv_0_decl; + //case OP_MOD_0: return m_mod_0_decl; case OP_U_ASIN: return m_u_asin_decl; case OP_U_ACOS: return m_u_acos_decl; default: return 0; @@ -489,9 +489,9 @@ static bool has_real_arg(ast_manager * m, unsigned num_args, expr * const * args static bool is_const_op(decl_kind k) { return k == OP_PI || - k == OP_E || - k == OP_0_PW_0_INT || - k == OP_0_PW_0_REAL; + k == OP_E; + //k == OP_0_PW_0_INT || + //k == OP_0_PW_0_REAL; } func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, diff --git a/src/ast/arith_decl_plugin.h b/src/ast/arith_decl_plugin.h index 6c2b1c77a..0238df3ae 100644 --- a/src/ast/arith_decl_plugin.h +++ b/src/ast/arith_decl_plugin.h @@ -70,12 +70,12 @@ enum arith_op_kind { OP_PI, OP_E, // under-specified symbols - OP_0_PW_0_INT, // 0^0 for integers - OP_0_PW_0_REAL, // 0^0 for reals + //OP_0_PW_0_INT, // 0^0 for integers + //OP_0_PW_0_REAL, // 0^0 for reals OP_NEG_ROOT, // x^n when n is even and x is negative - OP_DIV_0, // x/0 - OP_IDIV_0, // x div 0 - OP_MOD_0, // x mod 0 + // OP_DIV_0, // x/0 + // OP_IDIV_0, // x div 0 + // OP_MOD_0, // x mod 0 OP_U_ASIN, // asin(x) for x < -1 or x > 1 OP_U_ACOS, // acos(x) for x < -1 or x > 1 LAST_ARITH_OP @@ -218,12 +218,12 @@ public: return false; switch (f->get_decl_kind()) { - case OP_0_PW_0_INT: - case OP_0_PW_0_REAL: + //case OP_0_PW_0_INT: + //case OP_0_PW_0_REAL: case OP_NEG_ROOT: - case OP_DIV_0: - case OP_IDIV_0: - case OP_MOD_0: + //case OP_DIV_0: + //case OP_IDIV_0: + //case OP_MOD_0: case OP_U_ASIN: case OP_U_ACOS: return true; @@ -276,9 +276,9 @@ public: bool is_uminus(expr const * n) const { return is_app_of(n, m_afid, OP_UMINUS); } bool is_mul(expr const * n) const { return is_app_of(n, m_afid, OP_MUL); } bool is_div(expr const * n) const { return is_app_of(n, m_afid, OP_DIV); } - bool is_div0(expr const * n) const { return is_app_of(n, m_afid, OP_DIV_0); } + //bool is_div0(expr const * n) const { return is_app_of(n, m_afid, OP_DIV_0); } bool is_idiv(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV); } - bool is_idiv0(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV_0); } + //bool is_idiv0(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV_0); } bool is_mod(expr const * n) const { return is_app_of(n, m_afid, OP_MOD); } bool is_rem(expr const * n) const { return is_app_of(n, m_afid, OP_REM); } bool is_to_real(expr const * n) const { return is_app_of(n, m_afid, OP_TO_REAL); } @@ -425,11 +425,11 @@ public: app * mk_pi() { return plugin().mk_pi(); } app * mk_e() { return plugin().mk_e(); } - app * mk_0_pw_0_int() { return plugin().mk_0_pw_0_int(); } - app * mk_0_pw_0_real() { return plugin().mk_0_pw_0_real(); } - app * mk_div0(expr * arg) { return m_manager.mk_app(m_afid, OP_DIV_0, arg); } - app * mk_idiv0(expr * arg) { return m_manager.mk_app(m_afid, OP_IDIV_0, arg); } - app * mk_mod0(expr * arg) { return m_manager.mk_app(m_afid, OP_MOD_0, arg); } + // app * mk_0_pw_0_int() { return plugin().mk_0_pw_0_int(); } + // app * mk_0_pw_0_real() { return plugin().mk_0_pw_0_real(); } + // app * mk_div0(expr * arg) { return m_manager.mk_app(m_afid, OP_DIV_0, arg); } + // app * mk_idiv0(expr * arg) { return m_manager.mk_app(m_afid, OP_IDIV_0, arg); } + // app * mk_mod0(expr * arg) { return m_manager.mk_app(m_afid, OP_MOD_0, arg); } app * mk_neg_root(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_NEG_ROOT, arg1, arg2); } app * mk_u_asin(expr * arg) { return m_manager.mk_app(m_afid, OP_U_ASIN, arg); } app * mk_u_acos(expr * arg) { return m_manager.mk_app(m_afid, OP_U_ACOS, arg); } diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index f347a8e49..029e2d90c 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -2355,6 +2355,7 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort * SASSERT(num_decls > 0); DEBUG_CODE({ for (unsigned i = 0; i < num_patterns; ++i) { + TRACE("ast", tout << i << " " << mk_pp(patterns[i], *this) << "\n";); SASSERT(is_pattern(patterns[i])); }}); unsigned sz = quantifier::get_obj_size(num_decls, num_patterns, num_no_patterns); diff --git a/src/ast/macros/macro_manager.cpp b/src/ast/macros/macro_manager.cpp index b6ee62322..855cae107 100644 --- a/src/ast/macros/macro_manager.cpp +++ b/src/ast/macros/macro_manager.cpp @@ -213,11 +213,13 @@ func_decl * macro_manager::get_macro_interpretation(unsigned i, expr_ref & inter struct macro_manager::macro_expander_cfg : public default_rewriter_cfg { ast_manager& m; macro_manager& mm; + expr_dependency_ref m_used_macro_dependencies; expr_ref_vector m_trail; macro_expander_cfg(ast_manager& m, macro_manager& mm): m(m), mm(mm), + m_used_macro_dependencies(m), m_trail(m) {} @@ -297,8 +299,10 @@ struct macro_manager::macro_expander_cfg : public default_rewriter_cfg { p = m.mk_unit_resolution(2, prs); } else { - p = 0; + p = 0; } + expr_dependency * ed = mm.m_decl2macro_dep.find(d); + m_used_macro_dependencies = m.mk_join(m_used_macro_dependencies, ed); return true; } return false; @@ -307,6 +311,7 @@ struct macro_manager::macro_expander_cfg : public default_rewriter_cfg { struct macro_manager::macro_expander_rw : public rewriter_tpl { macro_expander_cfg m_cfg; + macro_expander_rw(ast_manager& m, macro_manager& mm): rewriter_tpl(m, m.proofs_enabled(), m_cfg), m_cfg(m, mm) @@ -319,8 +324,10 @@ void macro_manager::expand_macros(expr * n, proof * pr, expr_dependency * dep, e // Expand macros with "real" proof production support (NO rewrite*) expr_ref old_n(m); proof_ref old_pr(m); + expr_dependency_ref old_dep(m); old_n = n; old_pr = pr; + old_dep = dep; bool change = false; for (;;) { macro_expander_rw proc(m, *this); @@ -328,10 +335,12 @@ void macro_manager::expand_macros(expr * n, proof * pr, expr_dependency * dep, e TRACE("macro_manager_bug", tout << "expand_macros:\n" << mk_pp(n, m) << "\n";); proc(old_n, r, n_eq_r_pr); new_pr = m.mk_modus_ponens(old_pr, n_eq_r_pr); + new_dep = m.mk_join(old_dep, proc.m_cfg.m_used_macro_dependencies); if (r.get() == old_n.get()) break; old_n = r; old_pr = new_pr; + old_dep = new_dep; change = true; } // apply th_rewrite to the result. diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 4b00cde45..1f2e9e2e9 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -680,8 +680,9 @@ br_status arith_rewriter::mk_div_core(expr * arg1, expr * arg2, expr_ref & resul if (m_util.is_numeral(arg2, v2, is_int)) { SASSERT(!is_int); if (v2.is_zero()) { - result = m_util.mk_div0(arg1); - return BR_REWRITE1; + return BR_FAILED; + //result = m_util.mk_div0(arg1); + //return BR_REWRITE1; } else if (m_util.is_numeral(arg1, v1, is_int)) { result = m_util.mk_numeral(v1/v2, false); @@ -735,8 +736,8 @@ br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & resu return BR_DONE; } if (m_util.is_numeral(arg2, v2, is_int) && v2.is_zero()) { - result = m_util.mk_idiv0(arg1); - return BR_REWRITE1; + //result = m_util.mk_idiv0(arg1); + //return BR_REWRITE1; } return BR_FAILED; } diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 2a6bd2c50..85044af08 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -508,22 +508,22 @@ br_status poly_rewriter::mk_nflat_add_core(unsigned num_args, expr * con expr_fast_mark2 multiple; // multiple.is_marked(power_product) if power_product occurs more than once bool has_multiple = false; expr * prev = 0; - bool ordered = true; + bool ordered = true; for (unsigned i = 0; i < num_args; i++) { expr * arg = args[i]; + if (is_numeral(arg, a)) { num_coeffs++; c += a; + ordered = !m_sort_sums || i == 0; } - else { - // arg is not a numeral - if (m_sort_sums && ordered) { - if (prev != 0 && lt(arg, prev)) - ordered = false; - prev = arg; - } + else if (m_sort_sums && ordered) { + if (prev != 0 && lt(arg, prev)) + ordered = false; + prev = arg; } + arg = get_power_product(arg); if (visited.is_marked(arg)) { multiple.mark(arg); @@ -535,8 +535,8 @@ br_status poly_rewriter::mk_nflat_add_core(unsigned num_args, expr * con } normalize(c); SASSERT(m_sort_sums || ordered); - TRACE("sort_sums", - tout << "ordered: " << ordered << "\n"; + TRACE("rewriter", + tout << "ordered: " << ordered << " sort sums: " << m_sort_sums << "\n"; for (unsigned i = 0; i < num_args; i++) tout << mk_ismt2_pp(args[i], m()) << "\n";); if (has_multiple) { @@ -589,13 +589,14 @@ br_status poly_rewriter::mk_nflat_add_core(unsigned num_args, expr * con hoist_cmul(new_args); } else if (m_sort_sums) { - TRACE("sort_sums_bug", tout << "new_args.size(): " << new_args.size() << "\n";); + TRACE("rewriter_bug", tout << "new_args.size(): " << new_args.size() << "\n";); if (c.is_zero()) std::sort(new_args.c_ptr(), new_args.c_ptr() + new_args.size(), ast_to_lt()); else std::sort(new_args.c_ptr() + 1, new_args.c_ptr() + new_args.size(), ast_to_lt()); } result = mk_add_app(new_args.size(), new_args.c_ptr()); + TRACE("rewriter", tout << result << "\n";); if (hoist_multiplication(result)) { return BR_REWRITE_FULL; } diff --git a/src/ast/rewriter/push_app_ite.cpp b/src/ast/rewriter/push_app_ite.cpp index 386a4fb27..f3df4d711 100644 --- a/src/ast/rewriter/push_app_ite.cpp +++ b/src/ast/rewriter/push_app_ite.cpp @@ -73,6 +73,7 @@ br_status push_app_ite_cfg::reduce_app(func_decl * f, unsigned num, expr * const expr_ref e_new(m.mk_app(f, num, args_prime), m); args_prime[ite_arg_idx] = old; result = m.mk_ite(c, t_new, e_new); + TRACE("push_app_ite", tout << result << "\n";); if (m.proofs_enabled()) { result_pr = m.mk_rewrite(m.mk_app(f, num, args), result); } diff --git a/src/ast/rewriter/push_app_ite.h b/src/ast/rewriter/push_app_ite.h index e6c6b6fb2..ae06aad30 100644 --- a/src/ast/rewriter/push_app_ite.h +++ b/src/ast/rewriter/push_app_ite.h @@ -34,6 +34,7 @@ struct push_app_ite_cfg : public default_rewriter_cfg { virtual bool is_target(func_decl * decl, unsigned num_args, expr * const * args); br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr); push_app_ite_cfg(ast_manager& m, bool conservative = true): m(m), m_conservative(conservative) {} + bool rewrite_patterns() const { return false; } }; /** diff --git a/src/ast/rewriter/rewriter_def.h b/src/ast/rewriter/rewriter_def.h index 163118d17..c511f00d0 100644 --- a/src/ast/rewriter/rewriter_def.h +++ b/src/ast/rewriter/rewriter_def.h @@ -496,6 +496,7 @@ void rewriter_tpl::process_quantifier(quantifier * q, frame & fr) { expr * const * new_pats; expr * const * new_no_pats; if (rewrite_patterns()) { + TRACE("reduce_quantifier_bug", tout << "rewrite patterns\n";); new_pats = it + 1; new_no_pats = new_pats + q->get_num_patterns(); } @@ -518,7 +519,7 @@ void rewriter_tpl::process_quantifier(quantifier * q, frame & fr) { } else { expr_ref tmp(m()); - + TRACE("reduce_quantifier_bug", tout << mk_ismt2_pp(q, m()) << " " << mk_ismt2_pp(new_body, m()) << "\n";); if (!m_cfg.reduce_quantifier(q, new_body, new_pats, new_no_pats, m_r, m_pr)) { if (fr.m_new_child) { m_r = m().update_quantifier(q, q->get_num_patterns(), new_pats, q->get_num_no_patterns(), new_no_pats, new_body); diff --git a/src/ast/rewriter/rewriter_params.pyg b/src/ast/rewriter/rewriter_params.pyg index 06500086a..18bb29e56 100644 --- a/src/ast/rewriter/rewriter_params.pyg +++ b/src/ast/rewriter/rewriter_params.pyg @@ -9,5 +9,6 @@ def_module_params('rewriter', ("pull_cheap_ite", BOOL, False, "pull if-then-else terms when cheap."), ("bv_ineq_consistency_test_max", UINT, 0, "max size of conjunctions on which to perform consistency test based on inequalities on bitvectors."), ("cache_all", BOOL, False, "cache all intermediate results."), + ("rewrite_patterns", BOOL, False, "rewrite patterns."), ("ignore_patterns_on_ground_qbody", BOOL, True, "ignores patterns on quantifiers that don't mention their bound variables."))) diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index 764fa8eef..a2ca12b24 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -55,6 +55,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg { bool m_push_ite_arith; bool m_push_ite_bv; bool m_ignore_patterns_on_ground_qbody; + bool m_rewrite_patterns; // substitution support expr_dependency_ref m_used_dependencies; // set of dependencies of used substitutions @@ -72,6 +73,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg { m_push_ite_arith = p.push_ite_arith(); m_push_ite_bv = p.push_ite_bv(); m_ignore_patterns_on_ground_qbody = p.ignore_patterns_on_ground_qbody(); + m_rewrite_patterns = p.rewrite_patterns(); } void updt_params(params_ref const & p) { @@ -99,7 +101,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg { return false; } - bool rewrite_patterns() const { return false; } + bool rewrite_patterns() const { return m_rewrite_patterns; } bool cache_all_results() const { return m_cache_all; } diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index 0f2437982..1f9c89f89 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -444,16 +444,12 @@ namespace qe { div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m), m_zero(a.mk_real(0), m) {} ~div_rewriter_cfg() {} br_status reduce_app(func_decl* f, unsigned sz, expr* const* args, expr_ref& result, proof_ref& pr) { - if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && !a.is_numeral(args[1])) { + rational r(1); + if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && (!a.is_numeral(args[1], r) || r.is_zero())) { result = m.mk_fresh_const("div", a.mk_real()); m_divs.push_back(div(m, args[0], args[1], to_app(result))); return BR_DONE; } - if (is_decl_of(f, a.get_family_id(), OP_DIV_0) && sz == 1 && !a.is_numeral(args[0])) { - result = m.mk_fresh_const("div", a.mk_real()); - m_divs.push_back(div(m, args[0], m_zero, to_app(result))); - return BR_DONE; - } return BR_FAILED; } vector
const& divs() const { return m_divs; } @@ -507,10 +503,6 @@ namespace qe { m_has_divs = true; return; } - if (a.is_div0(n) && s.m_mode == qsat_t) { - m_has_divs = true; - return; - } TRACE("qe", tout << "not NRA: " << mk_pp(n, s.m) << "\n";); throw tactic_exception("not NRA"); } diff --git a/src/smt/CMakeLists.txt b/src/smt/CMakeLists.txt index 385d1aaa0..41890dd05 100644 --- a/src/smt/CMakeLists.txt +++ b/src/smt/CMakeLists.txt @@ -2,7 +2,7 @@ z3_add_component(smt SOURCES arith_eq_adapter.cpp arith_eq_solver.cpp - asserted_formulas_new.cpp + asserted_formulas.cpp cached_var_subst.cpp cost_evaluator.cpp dyn_ack.cpp diff --git a/src/smt/asserted_formulas_new.cpp b/src/smt/asserted_formulas.cpp similarity index 86% rename from src/smt/asserted_formulas_new.cpp rename to src/smt/asserted_formulas.cpp index 8d16ef2cd..626588ab3 100644 --- a/src/smt/asserted_formulas_new.cpp +++ b/src/smt/asserted_formulas.cpp @@ -3,7 +3,7 @@ Copyright (c) 2006 Microsoft Corporation Module Name: - asserted_formulas_new.cpp + asserted_formulas.cpp Abstract: @@ -25,9 +25,9 @@ Revision History: #include "ast/normal_forms/nnf.h" #include "ast/pattern/pattern_inference.h" #include "ast/macros/quasi_macros.h" -#include "smt/asserted_formulas_new.h" +#include "smt/asserted_formulas.h" -asserted_formulas_new::asserted_formulas_new(ast_manager & m, smt_params & p): +asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m(m), m_params(p), m_rewriter(m), @@ -60,13 +60,11 @@ asserted_formulas_new::asserted_formulas_new(ast_manager & m, smt_params & p): m_macro_finder = alloc(macro_finder, m, m_macro_manager); - params_ref pa; - pa.set_bool("arith_lhs", true); - m_rewriter.updt_params(pa); + set_eliminate_and(false); } -void asserted_formulas_new::setup() { +void asserted_formulas::setup() { switch (m_params.m_lift_ite) { case LI_FULL: m_params.m_ng_lift_ite = LI_NONE; @@ -84,10 +82,10 @@ void asserted_formulas_new::setup() { } -asserted_formulas_new::~asserted_formulas_new() { +asserted_formulas::~asserted_formulas() { } -void asserted_formulas_new::push_assertion(expr * e, proof * pr, vector& result) { +void asserted_formulas::push_assertion(expr * e, proof * pr, vector& result) { if (inconsistent()) { return; } @@ -119,16 +117,18 @@ void asserted_formulas_new::push_assertion(expr * e, proof * pr, vector & result) const { +void asserted_formulas::get_assertions(ptr_vector & result) const { for (justified_expr const& je : m_formulas) result.push_back(je.get_fml()); } -void asserted_formulas_new::push_scope() { +void asserted_formulas::push_scope() { SASSERT(inconsistent() || m_qhead == m_formulas.size() || m.canceled()); - TRACE("asserted_formulas_new_scopes", tout << "push:\n"; display(tout);); + TRACE("asserted_formulas_scopes", tout << "push:\n"; display(tout);); m_scoped_substitution.push(); m_scopes.push_back(scope()); scope & s = m_scopes.back(); @@ -176,8 +176,8 @@ void asserted_formulas_new::push_scope() { commit(); } -void asserted_formulas_new::pop_scope(unsigned num_scopes) { - TRACE("asserted_formulas_new_scopes", tout << "before pop " << num_scopes << "\n"; display(tout);); +void asserted_formulas::pop_scope(unsigned num_scopes) { + TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << "\n"; display(tout);); m_bv_sharing.pop_scope(num_scopes); m_macro_manager.pop_scope(num_scopes); unsigned new_lvl = m_scopes.size() - num_scopes; @@ -189,10 +189,10 @@ void asserted_formulas_new::pop_scope(unsigned num_scopes) { m_qhead = s.m_formulas_lim; m_scopes.shrink(new_lvl); flush_cache(); - TRACE("asserted_formulas_new_scopes", tout << "after pop " << num_scopes << "\n"; display(tout);); + TRACE("asserted_formulas_scopes", tout << "after pop " << num_scopes << "\n"; display(tout);); } -void asserted_formulas_new::reset() { +void asserted_formulas::reset() { m_defined_names.reset(); m_qhead = 0; m_formulas.reset(); @@ -202,14 +202,14 @@ void asserted_formulas_new::reset() { m_inconsistent = false; } -bool asserted_formulas_new::check_well_sorted() const { +bool asserted_formulas::check_well_sorted() const { for (justified_expr const& je : m_formulas) { if (!is_well_sorted(m, je.get_fml())) return false; } return true; } -void asserted_formulas_new::reduce() { +void asserted_formulas::reduce() { if (inconsistent()) return; if (canceled()) @@ -255,7 +255,7 @@ void asserted_formulas_new::reduce() { } -unsigned asserted_formulas_new::get_formulas_last_level() const { +unsigned asserted_formulas::get_formulas_last_level() const { if (m_scopes.empty()) { return 0; } @@ -264,7 +264,7 @@ unsigned asserted_formulas_new::get_formulas_last_level() const { } } -bool asserted_formulas_new::invoke(simplify_fmls& s) { +bool asserted_formulas::invoke(simplify_fmls& s) { if (!s.should_apply()) return true; IF_VERBOSE(10, verbose_stream() << "(smt." << s.id() << ")\n";); s(); @@ -281,7 +281,7 @@ bool asserted_formulas_new::invoke(simplify_fmls& s) { } } -void asserted_formulas_new::display(std::ostream & out) const { +void asserted_formulas::display(std::ostream & out) const { out << "asserted formulas:\n"; for (unsigned i = 0; i < m_formulas.size(); i++) { if (i == m_qhead) @@ -291,7 +291,7 @@ void asserted_formulas_new::display(std::ostream & out) const { out << "inconsistent: " << inconsistent() << "\n"; } -void asserted_formulas_new::display_ll(std::ostream & out, ast_mark & pp_visited) const { +void asserted_formulas::display_ll(std::ostream & out, ast_mark & pp_visited) const { if (!m_formulas.empty()) { for (justified_expr const& f : m_formulas) ast_def_ll_pp(out, m, f.get_fml(), pp_visited, true, false); @@ -302,18 +302,18 @@ void asserted_formulas_new::display_ll(std::ostream & out, ast_mark & pp_visited } } -void asserted_formulas_new::collect_statistics(statistics & st) const { +void asserted_formulas::collect_statistics(statistics & st) const { } -void asserted_formulas_new::swap_asserted_formulas(vector& formulas) { +void asserted_formulas::swap_asserted_formulas(vector& formulas) { SASSERT(!inconsistent() || !formulas.empty()); m_formulas.shrink(m_qhead); m_formulas.append(formulas); } -void asserted_formulas_new::find_macros_core() { +void asserted_formulas::find_macros_core() { vector new_fmls; unsigned sz = m_formulas.size(); (*m_macro_finder)(sz - m_qhead, m_formulas.c_ptr() + m_qhead, new_fmls); @@ -321,7 +321,7 @@ void asserted_formulas_new::find_macros_core() { reduce_and_solve(); } -void asserted_formulas_new::apply_quasi_macros() { +void asserted_formulas::apply_quasi_macros() { TRACE("before_quasi_macros", display(tout);); vector new_fmls; quasi_macros proc(m, m_macro_manager); @@ -335,7 +335,7 @@ void asserted_formulas_new::apply_quasi_macros() { reduce_and_solve(); } -void asserted_formulas_new::nnf_cnf() { +void asserted_formulas::nnf_cnf() { nnf apply_nnf(m, m_defined_names); vector new_fmls; expr_ref_vector push_todo(m); @@ -379,7 +379,7 @@ void asserted_formulas_new::nnf_cnf() { swap_asserted_formulas(new_fmls); } -void asserted_formulas_new::simplify_fmls::operator()() { +void asserted_formulas::simplify_fmls::operator()() { vector new_fmls; unsigned sz = af.m_formulas.size(); for (unsigned i = af.m_qhead; i < sz; i++) { @@ -405,18 +405,18 @@ void asserted_formulas_new::simplify_fmls::operator()() { } -void asserted_formulas_new::reduce_and_solve() { +void asserted_formulas::reduce_and_solve() { IF_IVERBOSE(10, verbose_stream() << "(smt.reducing)\n";); flush_cache(); // collect garbage m_reduce_asserted_formulas(); } -void asserted_formulas_new::commit() { +void asserted_formulas::commit() { commit(m_formulas.size()); } -void asserted_formulas_new::commit(unsigned new_qhead) { +void asserted_formulas::commit(unsigned new_qhead) { m_macro_manager.mark_forbidden(new_qhead - m_qhead, m_formulas.c_ptr() + m_qhead); m_expr2depth.reset(); for (unsigned i = m_qhead; i < new_qhead; ++i) { @@ -426,7 +426,7 @@ void asserted_formulas_new::commit(unsigned new_qhead) { m_qhead = new_qhead; } -void asserted_formulas_new::propagate_values() { +void asserted_formulas::propagate_values() { TRACE("propagate_values", tout << "before:\n"; display(tout);); flush_cache(); @@ -463,7 +463,7 @@ void asserted_formulas_new::propagate_values() { m_reduce_asserted_formulas(); } -unsigned asserted_formulas_new::propagate_values(unsigned i) { +unsigned asserted_formulas::propagate_values(unsigned i) { expr * n = m_formulas[i].get_fml(); expr_ref new_n(m); proof_ref new_pr(m); @@ -481,7 +481,7 @@ unsigned asserted_formulas_new::propagate_values(unsigned i) { return n != new_n ? 1 : 0; } -void asserted_formulas_new::update_substitution(expr* n, proof* pr) { +void asserted_formulas::update_substitution(expr* n, proof* pr) { expr* lhs, *rhs, *n1; if (is_ground(n) && (m.is_eq(n, lhs, rhs) || m.is_iff(n, lhs, rhs))) { compute_depth(lhs); @@ -510,7 +510,7 @@ void asserted_formulas_new::update_substitution(expr* n, proof* pr) { \brief implement a Knuth-Bendix ordering on expressions. */ -bool asserted_formulas_new::is_gt(expr* lhs, expr* rhs) { +bool asserted_formulas::is_gt(expr* lhs, expr* rhs) { if (lhs == rhs) { return false; } @@ -541,7 +541,7 @@ bool asserted_formulas_new::is_gt(expr* lhs, expr* rhs) { return false; } -void asserted_formulas_new::compute_depth(expr* e) { +void asserted_formulas::compute_depth(expr* e) { ptr_vector todo; todo.push_back(e); while (!todo.empty()) { @@ -573,7 +573,7 @@ void asserted_formulas_new::compute_depth(expr* e) { } } -proof * asserted_formulas_new::get_inconsistency_proof() const { +proof * asserted_formulas::get_inconsistency_proof() const { if (!inconsistent()) return 0; if (!m.proofs_enabled()) @@ -586,7 +586,7 @@ proof * asserted_formulas_new::get_inconsistency_proof() const { return 0; } -void asserted_formulas_new::refine_inj_axiom_fn::simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { +void asserted_formulas::refine_inj_axiom_fn::simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { expr* f = j.get_fml(); if (is_quantifier(f) && simplify_inj_axiom(m, to_quantifier(f), n)) { TRACE("inj_axiom", tout << "simplifying...\n" << mk_pp(f, m) << "\n" << n << "\n";); @@ -597,7 +597,7 @@ void asserted_formulas_new::refine_inj_axiom_fn::simplify(justified_expr const& } -unsigned asserted_formulas_new::get_total_size() const { +unsigned asserted_formulas::get_total_size() const { expr_mark visited; unsigned r = 0; for (justified_expr const& j : m_formulas) @@ -606,7 +606,7 @@ unsigned asserted_formulas_new::get_total_size() const { } #ifdef Z3DEBUG -void pp(asserted_formulas_new & f) { +void pp(asserted_formulas & f) { f.display(std::cout); } #endif diff --git a/src/smt/asserted_formulas_new.h b/src/smt/asserted_formulas.h similarity index 88% rename from src/smt/asserted_formulas_new.h rename to src/smt/asserted_formulas.h index 82f18250d..ea00cb71c 100644 --- a/src/smt/asserted_formulas_new.h +++ b/src/smt/asserted_formulas.h @@ -3,7 +3,7 @@ Copyright (c) 2006 Microsoft Corporation Module Name: - asserted_formulas_new.h + asserted_formulas.h Abstract: @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#ifndef ASSERTED_FORMULAS_NEW_H_ -#define ASSERTED_FORMULAS_NEW_H_ +#ifndef ASSERTED_FORMULAS_H_ +#define ASSERTED_FORMULAS_H_ #include "util/statistics.h" #include "ast/static_features.h" @@ -41,7 +41,7 @@ Revision History: #include "smt/elim_term_ite.h" -class asserted_formulas_new { +class asserted_formulas { ast_manager & m; smt_params & m_params; @@ -66,11 +66,11 @@ class asserted_formulas_new { class simplify_fmls { protected: - asserted_formulas_new& af; + asserted_formulas& af; ast_manager& m; char const* m_id; public: - simplify_fmls(asserted_formulas_new& af, char const* id): af(af), m(af.m), m_id(id) {} + simplify_fmls(asserted_formulas& af, char const* id): af(af), m(af.m), m_id(id) {} char const* id() const { return m_id; } virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) = 0; virtual bool should_apply() const { return true;} @@ -80,13 +80,13 @@ class asserted_formulas_new { class reduce_asserted_formulas_fn : public simplify_fmls { public: - reduce_asserted_formulas_fn(asserted_formulas_new& af): simplify_fmls(af, "reduce-asserted") {} + reduce_asserted_formulas_fn(asserted_formulas& af): simplify_fmls(af, "reduce-asserted") {} virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { af.m_rewriter(j.get_fml(), n, p); } }; class find_macros_fn : public simplify_fmls { public: - find_macros_fn(asserted_formulas_new& af): simplify_fmls(af, "find-macros") {} + find_macros_fn(asserted_formulas& af): simplify_fmls(af, "find-macros") {} virtual void operator()() { af.find_macros_core(); } virtual bool should_apply() const { return af.m_params.m_macro_finder && af.has_quantifiers(); } virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } @@ -94,7 +94,7 @@ class asserted_formulas_new { class apply_quasi_macros_fn : public simplify_fmls { public: - apply_quasi_macros_fn(asserted_formulas_new& af): simplify_fmls(af, "find-quasi-macros") {} + apply_quasi_macros_fn(asserted_formulas& af): simplify_fmls(af, "find-quasi-macros") {} virtual void operator()() { af.apply_quasi_macros(); } virtual bool should_apply() const { return af.m_params.m_quasi_macros && af.has_quantifiers(); } virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } @@ -102,7 +102,7 @@ class asserted_formulas_new { class nnf_cnf_fn : public simplify_fmls { public: - nnf_cnf_fn(asserted_formulas_new& af): simplify_fmls(af, "nnf-cnf") {} + nnf_cnf_fn(asserted_formulas& af): simplify_fmls(af, "nnf-cnf") {} virtual void operator()() { af.nnf_cnf(); } virtual bool should_apply() const { return af.m_params.m_nnf_cnf || (af.m_params.m_mbqi && af.has_quantifiers()); } virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } @@ -110,7 +110,7 @@ class asserted_formulas_new { class propagate_values_fn : public simplify_fmls { public: - propagate_values_fn(asserted_formulas_new& af): simplify_fmls(af, "propagate-values") {} + propagate_values_fn(asserted_formulas& af): simplify_fmls(af, "propagate-values") {} virtual void operator()() { af.propagate_values(); } virtual bool should_apply() const { return af.m_params.m_propagate_values; } virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { UNREACHABLE(); } @@ -119,7 +119,7 @@ class asserted_formulas_new { class distribute_forall_fn : public simplify_fmls { distribute_forall m_functor; public: - distribute_forall_fn(asserted_formulas_new& af): simplify_fmls(af, "distribute-forall"), m_functor(af.m) {} + distribute_forall_fn(asserted_formulas& af): simplify_fmls(af, "distribute-forall"), m_functor(af.m) {} virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { m_functor(j.get_fml(), n); } virtual bool should_apply() const { return af.m_params.m_distribute_forall && af.has_quantifiers(); } virtual void post_op() { af.reduce_and_solve(); TRACE("asserted_formulas", af.display(tout);); } @@ -128,21 +128,21 @@ class asserted_formulas_new { class pattern_inference_fn : public simplify_fmls { pattern_inference_rw m_infer; public: - pattern_inference_fn(asserted_formulas_new& af): simplify_fmls(af, "pattern-inference"), m_infer(af.m, af.m_params) {} + pattern_inference_fn(asserted_formulas& af): simplify_fmls(af, "pattern-inference"), m_infer(af.m, af.m_params) {} virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { m_infer(j.get_fml(), n, p); } virtual bool should_apply() const { return af.m_params.m_ematching && af.has_quantifiers(); } }; class refine_inj_axiom_fn : public simplify_fmls { public: - refine_inj_axiom_fn(asserted_formulas_new& af): simplify_fmls(af, "refine-injectivity") {} + refine_inj_axiom_fn(asserted_formulas& af): simplify_fmls(af, "refine-injectivity") {} virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p); virtual bool should_apply() const { return af.m_params.m_refine_inj_axiom && af.has_quantifiers(); } }; class max_bv_sharing_fn : public simplify_fmls { public: - max_bv_sharing_fn(asserted_formulas_new& af): simplify_fmls(af, "maximizing-bv-sharing") {} + max_bv_sharing_fn(asserted_formulas& af): simplify_fmls(af, "maximizing-bv-sharing") {} virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { af.m_bv_sharing(j.get_fml(), n, p); } virtual bool should_apply() const { return af.m_params.m_max_bv_sharing; } virtual void post_op() { af.m_reduce_asserted_formulas(); } @@ -151,7 +151,7 @@ class asserted_formulas_new { class elim_term_ite_fn : public simplify_fmls { elim_term_ite_rw m_elim; public: - elim_term_ite_fn(asserted_formulas_new& af): simplify_fmls(af, "elim-term-ite"), m_elim(af.m, af.m_defined_names) {} + elim_term_ite_fn(asserted_formulas& af): simplify_fmls(af, "elim-term-ite"), m_elim(af.m, af.m_defined_names) {} virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { m_elim(j.get_fml(), n, p); } virtual bool should_apply() const { return af.m_params.m_eliminate_term_ite && af.m_params.m_lift_ite != LI_FULL; } virtual void post_op() { af.m_formulas.append(m_elim.new_defs()); af.reduce_and_solve(); m_elim.reset(); } @@ -161,7 +161,7 @@ class asserted_formulas_new { class NAME : public simplify_fmls { \ FUNCTOR m_functor; \ public: \ - NAME(asserted_formulas_new& af):simplify_fmls(af, MSG), m_functor ARG {} \ + NAME(asserted_formulas& af):simplify_fmls(af, MSG), m_functor ARG {} \ virtual void simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { \ m_functor(j.get_fml(), n, p); \ } \ @@ -221,8 +221,8 @@ class asserted_formulas_new { bool pull_cheap_ite_trees(); public: - asserted_formulas_new(ast_manager & m, smt_params & p); - ~asserted_formulas_new(); + asserted_formulas(ast_manager & m, smt_params & p); + ~asserted_formulas(); bool has_quantifiers() const { return m_has_quantifiers; } void setup(); @@ -265,5 +265,5 @@ public: }; -#endif /* ASSERTED_FORMULAS_NEW_H_ */ +#endif /* ASSERTED_FORMULAS_H_ */ diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 7b92bdd28..eef84f773 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -148,8 +148,8 @@ namespace smt { dst_ctx.set_logic(src_ctx.m_setup.get_logic()); dst_ctx.copy_plugins(src_ctx, dst_ctx); - asserted_formulas_new& src_af = src_ctx.m_asserted_formulas; - asserted_formulas_new& dst_af = dst_ctx.m_asserted_formulas; + asserted_formulas& src_af = src_ctx.m_asserted_formulas; + asserted_formulas& dst_af = dst_ctx.m_asserted_formulas; // Copy asserted formulas. for (unsigned i = 0; i < src_af.get_num_formulas(); ++i) { diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index a6a67702a..3cc577b29 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -36,7 +36,7 @@ Revision History: #include "smt/smt_case_split_queue.h" #include "smt/smt_almost_cg_table.h" #include "smt/smt_failure.h" -#include "smt/asserted_formulas_new.h" +#include "smt/asserted_formulas.h" #include "smt/smt_types.h" #include "smt/dyn_ack.h" #include "ast/ast_smt_pp.h" @@ -81,7 +81,7 @@ namespace smt { params_ref m_params; setup m_setup; timer m_timer; - asserted_formulas_new m_asserted_formulas; + asserted_formulas m_asserted_formulas; scoped_ptr m_qmanager; scoped_ptr m_model_generator; scoped_ptr m_relevancy_propagator; diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index 70355502d..16a49961e 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -395,7 +395,8 @@ namespace smt { template theory_var theory_arith::internalize_div(app * n) { - if (!m_util.is_numeral(n->get_arg(1))) found_underspecified_op(n); + rational r(1); + if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n); found_underspecified_op(n); theory_var s = mk_binary_op(n); context & ctx = get_context(); @@ -419,7 +420,8 @@ namespace smt { template theory_var theory_arith::internalize_mod(app * n) { TRACE("arith_mod", tout << "internalizing...\n" << mk_pp(n, get_manager()) << "\n";); - if (!m_util.is_numeral(n->get_arg(1))) found_underspecified_op(n); + rational r(1); + if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n); theory_var s = mk_binary_op(n); context & ctx = get_context(); if (!ctx.relevancy()) @@ -429,7 +431,8 @@ namespace smt { template theory_var theory_arith::internalize_rem(app * n) { - if (!m_util.is_numeral(n->get_arg(1))) found_underspecified_op(n); + rational r(1); + if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n); theory_var s = mk_binary_op(n); context & ctx = get_context(); if (!ctx.relevancy()) { @@ -734,11 +737,6 @@ namespace smt { return internalize_div(n); else if (m_util.is_idiv(n)) return internalize_idiv(n); - else if (is_app_of(n, get_id(), OP_IDIV_0) || is_app_of(n, get_id(), OP_DIV_0)) { - ctx.internalize(n->get_arg(0), false); - enode * e = mk_enode(n); - return mk_var(e); - } else if (m_util.is_mod(n)) return internalize_mod(n); else if (m_util.is_rem(n)) @@ -1226,7 +1224,8 @@ namespace smt { app * rhs = to_app(n->get_arg(1)); expr * rhs2; if (m_util.is_to_real(rhs, rhs2) && is_app(rhs2)) { rhs = to_app(rhs2); } - if (!m_util.is_numeral(rhs)) { + if (!m_util.is_numeral(rhs)) { + UNREACHABLE(); throw default_exception("malformed atomic constraint"); } theory_var v = internalize_term_core(lhs); diff --git a/src/smt/theory_array_full.cpp b/src/smt/theory_array_full.cpp index c7a3d7920..274f89e8b 100644 --- a/src/smt/theory_array_full.cpp +++ b/src/smt/theory_array_full.cpp @@ -516,7 +516,8 @@ namespace smt { expr_ref sel1(m), sel2(m); sel1 = mk_select(args1.size(), args1.c_ptr()); - sel2 = ctx.get_rewriter().mk_app(f, args2.size(), args2.c_ptr()); + sel2 = m.mk_app(f, args2.size(), args2.c_ptr()); + ctx.get_rewriter()(sel2); ctx.internalize(sel1, false); ctx.internalize(sel2, false); @@ -537,6 +538,7 @@ namespace smt { SASSERT(is_map(mp)); app* map = mp->get_owner(); + ast_manager& m = get_manager(); context& ctx = get_context(); if (!ctx.add_fingerprint(this, 0, 1, &mp)) { return false; @@ -552,9 +554,9 @@ namespace smt { args2.push_back(mk_default(map->get_arg(i))); } + expr_ref def2(m.mk_app(f, args2.size(), args2.c_ptr()), m); + ctx.get_rewriter()(def2); expr* def1 = mk_default(map); - expr_ref def2(get_manager()); - def2 = ctx.get_rewriter().mk_app(f, args2.size(), args2.c_ptr()); ctx.internalize(def1, false); ctx.internalize(def2, false); return try_assign_eq(def1, def2); diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index 0c09d0403..dd044b78a 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -293,9 +293,6 @@ namespace smt { } void found_not_handled(expr* n) { - if (a.is_div0(n)) { - return; - } m_not_handled = n; if (is_app(n) && is_underspecified(to_app(n))) { m_underspecified.push_back(to_app(n)); diff --git a/src/tactic/arith/purify_arith_tactic.cpp b/src/tactic/arith/purify_arith_tactic.cpp index 0443a51ed..17a69f93e 100644 --- a/src/tactic/arith/purify_arith_tactic.cpp +++ b/src/tactic/arith/purify_arith_tactic.cpp @@ -301,7 +301,7 @@ struct purify_arith_proc { if (complete()) { // y != 0 \/ k = div-0(x) push_cnstr(OR(NOT(EQ(y, mk_real_zero())), - EQ(k, u().mk_div0(x)))); + EQ(k, u().mk_div(x, mk_real_zero())))); push_cnstr_pr(result_pr); } } @@ -349,10 +349,10 @@ struct purify_arith_proc { push_cnstr_pr(mod_pr); if (complete()) { - push_cnstr(OR(NOT(EQ(y, zero)), EQ(k1, u().mk_idiv0(x)))); + push_cnstr(OR(NOT(EQ(y, zero)), EQ(k1, u().mk_idiv(x, zero)))); push_cnstr_pr(result_pr); - push_cnstr(OR(NOT(EQ(y, zero)), EQ(k2, u().mk_mod0(x)))); + push_cnstr(OR(NOT(EQ(y, zero)), EQ(k2, u().mk_mod(x, zero)))); push_cnstr_pr(mod_pr); } } @@ -414,7 +414,7 @@ struct purify_arith_proc { // (^ x 0) --> k | x != 0 implies k = 1, x = 0 implies k = 0^0 push_cnstr(OR(EQ(x, zero), EQ(k, one))); push_cnstr_pr(result_pr); - push_cnstr(OR(NOT(EQ(x, zero)), EQ(k, is_int ? u().mk_0_pw_0_int() : u().mk_0_pw_0_real()))); + push_cnstr(OR(NOT(EQ(x, zero)), EQ(k, u().mk_power(zero, zero)))); push_cnstr_pr(result_pr); } else if (!is_int) { From d940516df3c60ca01c69e1569dcfbb3e950f52ec Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 11:01:45 -0700 Subject: [PATCH 212/488] fixes Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.cpp | 22 +--------------------- src/ast/arith_decl_plugin.h | 24 ------------------------ src/muz/spacer/spacer_sym_mux.cpp | 1 + src/smt/qi_queue.cpp | 5 ++--- src/smt/smt_quick_checker.cpp | 3 +-- src/smt/smt_quick_checker.h | 1 - src/smt/theory_arith_core.h | 5 ++--- src/smt/theory_fpa.cpp | 3 +-- src/tactic/arith/purify_arith_tactic.cpp | 7 ++++--- src/test/ext_numeral.cpp | 6 +++--- 10 files changed, 15 insertions(+), 62 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 0719ebdfa..03ee77458 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -178,7 +178,7 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { MK_AC_OP(m_i_mul_decl, "*", OP_MUL, 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_OP(m_i_mod_decl, "mod", OP_MOD, i); MK_UNARY(m_i_uminus_decl, "-", OP_UMINUS, i); m_to_real_decl = m->mk_func_decl(symbol("to_real"), i, r, func_decl_info(id, OP_TO_REAL)); @@ -215,18 +215,8 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { m_e = m->mk_const(e_decl); m->inc_ref(m_e); - //func_decl * z_pw_z_int = m->mk_const_decl(symbol("0^0-int"), i, func_decl_info(id, OP_0_PW_0_INT)); - //m_0_pw_0_int = m->mk_const(z_pw_z_int); - //m->inc_ref(m_0_pw_0_int); - - //func_decl * z_pw_z_real = m->mk_const_decl(symbol("0^0-real"), r, func_decl_info(id, OP_0_PW_0_REAL)); - //m_0_pw_0_real = m->mk_const(z_pw_z_real); - //m->inc_ref(m_0_pw_0_real); MK_OP(m_neg_root_decl, "neg-root", OP_NEG_ROOT, r); - //MK_UNARY(m_div_0_decl, "/0", OP_DIV_0, r); - //MK_UNARY(m_idiv_0_decl, "div0", OP_IDIV_0, i); - //MK_UNARY(m_mod_0_decl, "mod0", OP_MOD_0, i); MK_UNARY(m_u_asin_decl, "asin-u", OP_U_ASIN, r); MK_UNARY(m_u_acos_decl, "acos-u", OP_U_ACOS, r); } @@ -279,12 +269,7 @@ arith_decl_plugin::arith_decl_plugin(): m_atanh_decl(0), m_pi(0), m_e(0), - m_0_pw_0_int(0), - m_0_pw_0_real(0), m_neg_root_decl(0), - m_div_0_decl(0), - m_idiv_0_decl(0), - m_mod_0_decl(0), m_u_asin_decl(0), m_u_acos_decl(0), m_convert_int_numerals_to_real(false) { @@ -339,12 +324,7 @@ void arith_decl_plugin::finalize() { DEC_REF(m_atanh_decl); DEC_REF(m_pi); DEC_REF(m_e); - DEC_REF(m_0_pw_0_int); - DEC_REF(m_0_pw_0_real); DEC_REF(m_neg_root_decl); - DEC_REF(m_div_0_decl); - DEC_REF(m_idiv_0_decl); - DEC_REF(m_mod_0_decl); DEC_REF(m_u_asin_decl); DEC_REF(m_u_acos_decl); m_manager->dec_array_ref(m_small_ints.size(), m_small_ints.c_ptr()); diff --git a/src/ast/arith_decl_plugin.h b/src/ast/arith_decl_plugin.h index 0238df3ae..4b24ea5e6 100644 --- a/src/ast/arith_decl_plugin.h +++ b/src/ast/arith_decl_plugin.h @@ -70,12 +70,7 @@ enum arith_op_kind { OP_PI, OP_E, // under-specified symbols - //OP_0_PW_0_INT, // 0^0 for integers - //OP_0_PW_0_REAL, // 0^0 for reals OP_NEG_ROOT, // x^n when n is even and x is negative - // OP_DIV_0, // x/0 - // OP_IDIV_0, // x div 0 - // OP_MOD_0, // x mod 0 OP_U_ASIN, // asin(x) for x < -1 or x > 1 OP_U_ACOS, // acos(x) for x < -1 or x > 1 LAST_ARITH_OP @@ -141,12 +136,7 @@ protected: app * m_pi; app * m_e; - app * m_0_pw_0_int; - app * m_0_pw_0_real; func_decl * m_neg_root_decl; - func_decl * m_div_0_decl; - func_decl * m_idiv_0_decl; - func_decl * m_mod_0_decl; func_decl * m_u_asin_decl; func_decl * m_u_acos_decl; ptr_vector m_small_ints; @@ -207,10 +197,6 @@ public: app * mk_e() const { return m_e; } - app * mk_0_pw_0_int() const { return m_0_pw_0_int; } - - app * mk_0_pw_0_real() const { return m_0_pw_0_real; } - virtual expr * get_some_value(sort * s); virtual bool is_considered_uninterpreted(func_decl * f) { @@ -218,12 +204,7 @@ public: return false; switch (f->get_decl_kind()) { - //case OP_0_PW_0_INT: - //case OP_0_PW_0_REAL: case OP_NEG_ROOT: - //case OP_DIV_0: - //case OP_IDIV_0: - //case OP_MOD_0: case OP_U_ASIN: case OP_U_ACOS: return true; @@ -425,11 +406,6 @@ public: app * mk_pi() { return plugin().mk_pi(); } app * mk_e() { return plugin().mk_e(); } - // app * mk_0_pw_0_int() { return plugin().mk_0_pw_0_int(); } - // app * mk_0_pw_0_real() { return plugin().mk_0_pw_0_real(); } - // app * mk_div0(expr * arg) { return m_manager.mk_app(m_afid, OP_DIV_0, arg); } - // app * mk_idiv0(expr * arg) { return m_manager.mk_app(m_afid, OP_IDIV_0, arg); } - // app * mk_mod0(expr * arg) { return m_manager.mk_app(m_afid, OP_MOD_0, arg); } app * mk_neg_root(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_NEG_ROOT, arg1, arg2); } app * mk_u_asin(expr * arg) { return m_manager.mk_app(m_afid, OP_U_ASIN, arg); } app * mk_u_acos(expr * arg) { return m_manager.mk_app(m_afid, OP_U_ACOS, arg); } diff --git a/src/muz/spacer/spacer_sym_mux.cpp b/src/muz/spacer/spacer_sym_mux.cpp index c311d9990..ee1d3726d 100644 --- a/src/muz/spacer/spacer_sym_mux.cpp +++ b/src/muz/spacer/spacer_sym_mux.cpp @@ -368,6 +368,7 @@ public: app * a = to_app(s); func_decl * sym = a->get_decl(); if (!m_parent.has_index(sym, m_from_idx)) { + (void) m_homogenous; SASSERT(!m_homogenous || !m_parent.is_muxed(sym)); return false; } diff --git a/src/smt/qi_queue.cpp b/src/smt/qi_queue.cpp index 8f8e3df7b..f77fde29a 100644 --- a/src/smt/qi_queue.cpp +++ b/src/smt/qi_queue.cpp @@ -227,9 +227,8 @@ namespace smt { TRACE("qi_queue_instance", tout << "new instance:\n" << mk_pp(instance, m_manager) << "\n";); expr_ref s_instance(m_manager); proof_ref pr(m_manager); - th_rewriter & simp = m_context.get_rewriter(); - simp(instance, s_instance, pr); - TRACE("qi_queue_bug", tout << "new instance after simplification:\n" << mk_pp(s_instance, m_manager) << "\n";); + m_context.get_rewriter()(instance, s_instance, pr); + TRACE("qi_queue_bug", tout << "new instance after simplification:\n" << s_instance << "\n";); if (m_manager.is_true(s_instance)) { TRACE("checker", tout << "reduced to true, before:\n" << mk_ll_pp(instance, m_manager);); diff --git a/src/smt/smt_quick_checker.cpp b/src/smt/smt_quick_checker.cpp index 773768944..72c28fd7d 100644 --- a/src/smt/smt_quick_checker.cpp +++ b/src/smt/smt_quick_checker.cpp @@ -164,7 +164,6 @@ namespace smt { quick_checker::quick_checker(context & c): m_context(c), m_manager(c.get_manager()), - m_simplifier(c.get_rewriter()), m_collector(c), m_new_exprs(m_manager) { } @@ -411,7 +410,7 @@ namespace smt { } } expr_ref new_expr(m_manager); - new_expr = m_simplifier.mk_app(to_app(n)->get_decl(), num_args, new_args.c_ptr()); + new_expr = m_context.get_rewriter().mk_app(to_app(n)->get_decl(), num_args, new_args.c_ptr()); m_new_exprs.push_back(new_expr); m_canonize_cache.insert(n, new_expr); return new_expr; diff --git a/src/smt/smt_quick_checker.h b/src/smt/smt_quick_checker.h index d07e10921..21a570c3c 100644 --- a/src/smt/smt_quick_checker.h +++ b/src/smt/smt_quick_checker.h @@ -77,7 +77,6 @@ namespace smt { context & m_context; ast_manager & m_manager; - th_rewriter & m_simplifier; collector m_collector; expr_ref_vector m_new_exprs; vector m_candidate_vectors; diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index 16a49961e..13aba9686 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -449,9 +449,8 @@ namespace smt { expr_ref s_ante(m), s_conseq(m); expr* s_conseq_n, * s_ante_n; bool negated; - proof_ref pr(m); - s(ante, s_ante, pr); + s(ante, s_ante); if (ctx.get_cancel_flag()) return; negated = m.is_not(s_ante, s_ante_n); if (negated) s_ante = s_ante_n; @@ -459,7 +458,7 @@ namespace smt { literal l_ante = ctx.get_literal(s_ante); if (negated) l_ante.neg(); - s(conseq, s_conseq, pr); + s(conseq, s_conseq); if (ctx.get_cancel_flag()) return; negated = m.is_not(s_conseq, s_conseq_n); if (negated) s_conseq = s_conseq_n; diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 3f246b2c7..dfd295220 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -385,7 +385,6 @@ namespace smt { { ast_manager & m = get_manager(); context & ctx = get_context(); - th_rewriter & simp = ctx.get_rewriter(); expr_ref res(m), t(m); proof_ref t_pr(m); @@ -394,7 +393,7 @@ namespace smt { expr_ref_vector::iterator it = m_converter.m_extra_assertions.begin(); expr_ref_vector::iterator end = m_converter.m_extra_assertions.end(); for (; it != end; it++) { - simp(*it, t, t_pr); + ctx.get_rewriter()(*it, t, t_pr); res = m.mk_and(res, t); } m_converter.m_extra_assertions.reset(); diff --git a/src/tactic/arith/purify_arith_tactic.cpp b/src/tactic/arith/purify_arith_tactic.cpp index 17a69f93e..7e89794ce 100644 --- a/src/tactic/arith/purify_arith_tactic.cpp +++ b/src/tactic/arith/purify_arith_tactic.cpp @@ -297,8 +297,8 @@ struct purify_arith_proc { push_cnstr(OR(EQ(y, mk_real_zero()), EQ(u().mk_mul(y, k), x))); push_cnstr_pr(result_pr); - - if (complete()) { + rational r; + if (complete() && (!u().is_numeral(y, r) || r.is_zero())) { // y != 0 \/ k = div-0(x) push_cnstr(OR(NOT(EQ(y, mk_real_zero())), EQ(k, u().mk_div(x, mk_real_zero())))); @@ -348,7 +348,8 @@ struct purify_arith_proc { push_cnstr(OR(u().mk_ge(y, zero), u().mk_lt(k2, u().mk_mul(u().mk_numeral(rational(-1), true), y)))); push_cnstr_pr(mod_pr); - if (complete()) { + rational r; + if (complete() && (!u().is_numeral(y, r) || r.is_zero())) { push_cnstr(OR(NOT(EQ(y, zero)), EQ(k1, u().mk_idiv(x, zero)))); push_cnstr_pr(result_pr); diff --git a/src/test/ext_numeral.cpp b/src/test/ext_numeral.cpp index 4c82617c9..003aa272f 100644 --- a/src/test/ext_numeral.cpp +++ b/src/test/ext_numeral.cpp @@ -43,13 +43,13 @@ static void FUN_NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, int scoped_mpq _a(m), _b(m), _c(m); \ m.set(_a, a); \ m.set(_b, b); \ - ext_numeral_kind ck; \ + ext_numeral_kind ck(EN_NUMERAL); \ OP_NAME(m, _a, ak, _b, bk, _c, ck); \ - ENSURE(ck == expected_ck); \ + ENSURE(ck == expected_ck); \ if (expected_ck == EN_NUMERAL) { \ scoped_mpq _expected_c(m); \ m.set(_expected_c, expected_c); \ - ENSURE(m.eq(_c, _expected_c)); \ + ENSURE(m.eq(_c, _expected_c)); \ } \ } From 3bfc3437f188394e246eed1668fdaef1e8ad8438 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 11:57:13 -0700 Subject: [PATCH 213/488] purify Signed-off-by: Nikolaj Bjorner --- src/ast/arith_decl_plugin.cpp | 36 ++++----------- src/ast/arith_decl_plugin.h | 46 +++++-------------- src/ast/rewriter/arith_rewriter.cpp | 7 +-- .../simplifier/arith_simplifier_plugin.cpp | 2 - src/qe/nlqsat.cpp | 12 +---- src/smt/theory_arith_core.h | 17 ++++--- src/smt/theory_lra.cpp | 10 ++-- src/tactic/arith/purify_arith_tactic.cpp | 15 +++--- 8 files changed, 44 insertions(+), 101 deletions(-) diff --git a/src/ast/arith_decl_plugin.cpp b/src/ast/arith_decl_plugin.cpp index 01b671c99..03ee77458 100644 --- a/src/ast/arith_decl_plugin.cpp +++ b/src/ast/arith_decl_plugin.cpp @@ -215,18 +215,8 @@ void arith_decl_plugin::set_manager(ast_manager * m, family_id id) { m_e = m->mk_const(e_decl); m->inc_ref(m_e); - func_decl * z_pw_z_int = m->mk_const_decl(symbol("0^0-int"), i, func_decl_info(id, OP_0_PW_0_INT)); - m_0_pw_0_int = m->mk_const(z_pw_z_int); - m->inc_ref(m_0_pw_0_int); - - func_decl * z_pw_z_real = m->mk_const_decl(symbol("0^0-real"), r, func_decl_info(id, OP_0_PW_0_REAL)); - m_0_pw_0_real = m->mk_const(z_pw_z_real); - m->inc_ref(m_0_pw_0_real); MK_OP(m_neg_root_decl, "neg-root", OP_NEG_ROOT, r); - MK_UNARY(m_div_0_decl, "/0", OP_DIV_0, r); - MK_UNARY(m_idiv_0_decl, "div0", OP_IDIV_0, i); - MK_UNARY(m_mod_0_decl, "mod0", OP_MOD_0, i); MK_UNARY(m_u_asin_decl, "asin-u", OP_U_ASIN, r); MK_UNARY(m_u_acos_decl, "acos-u", OP_U_ACOS, r); } @@ -279,12 +269,7 @@ arith_decl_plugin::arith_decl_plugin(): m_atanh_decl(0), m_pi(0), m_e(0), - m_0_pw_0_int(0), - m_0_pw_0_real(0), m_neg_root_decl(0), - m_div_0_decl(0), - m_idiv_0_decl(0), - m_mod_0_decl(0), m_u_asin_decl(0), m_u_acos_decl(0), m_convert_int_numerals_to_real(false) { @@ -339,12 +324,7 @@ void arith_decl_plugin::finalize() { DEC_REF(m_atanh_decl); DEC_REF(m_pi); DEC_REF(m_e); - DEC_REF(m_0_pw_0_int); - DEC_REF(m_0_pw_0_real); DEC_REF(m_neg_root_decl); - DEC_REF(m_div_0_decl); - DEC_REF(m_idiv_0_decl); - DEC_REF(m_mod_0_decl); DEC_REF(m_u_asin_decl); DEC_REF(m_u_acos_decl); m_manager->dec_array_ref(m_small_ints.size(), m_small_ints.c_ptr()); @@ -392,12 +372,12 @@ inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) { case OP_ATANH: return m_atanh_decl; case OP_PI: return m_pi->get_decl(); case OP_E: return m_e->get_decl(); - case OP_0_PW_0_INT: return m_0_pw_0_int->get_decl(); - case OP_0_PW_0_REAL: return m_0_pw_0_real->get_decl(); + //case OP_0_PW_0_INT: return m_0_pw_0_int->get_decl(); + //case OP_0_PW_0_REAL: return m_0_pw_0_real->get_decl(); case OP_NEG_ROOT: return m_neg_root_decl; - case OP_DIV_0: return m_div_0_decl; - case OP_IDIV_0: return m_idiv_0_decl; - case OP_MOD_0: return m_mod_0_decl; + //case OP_DIV_0: return m_div_0_decl; + //case OP_IDIV_0: return m_idiv_0_decl; + //case OP_MOD_0: return m_mod_0_decl; case OP_U_ASIN: return m_u_asin_decl; case OP_U_ACOS: return m_u_acos_decl; default: return 0; @@ -489,9 +469,9 @@ static bool has_real_arg(ast_manager * m, unsigned num_args, expr * const * args static bool is_const_op(decl_kind k) { return k == OP_PI || - k == OP_E || - k == OP_0_PW_0_INT || - k == OP_0_PW_0_REAL; + k == OP_E; + //k == OP_0_PW_0_INT || + //k == OP_0_PW_0_REAL; } func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, diff --git a/src/ast/arith_decl_plugin.h b/src/ast/arith_decl_plugin.h index a66ddd967..4b24ea5e6 100644 --- a/src/ast/arith_decl_plugin.h +++ b/src/ast/arith_decl_plugin.h @@ -70,12 +70,7 @@ enum arith_op_kind { OP_PI, OP_E, // under-specified symbols - OP_0_PW_0_INT, // 0^0 for integers - OP_0_PW_0_REAL, // 0^0 for reals OP_NEG_ROOT, // x^n when n is even and x is negative - OP_DIV_0, // x/0 - OP_IDIV_0, // x div 0 - OP_MOD_0, // x mod 0 OP_U_ASIN, // asin(x) for x < -1 or x > 1 OP_U_ACOS, // acos(x) for x < -1 or x > 1 LAST_ARITH_OP @@ -141,12 +136,7 @@ protected: app * m_pi; app * m_e; - app * m_0_pw_0_int; - app * m_0_pw_0_real; func_decl * m_neg_root_decl; - func_decl * m_div_0_decl; - func_decl * m_idiv_0_decl; - func_decl * m_mod_0_decl; func_decl * m_u_asin_decl; func_decl * m_u_acos_decl; ptr_vector m_small_ints; @@ -207,10 +197,6 @@ public: app * mk_e() const { return m_e; } - app * mk_0_pw_0_int() const { return m_0_pw_0_int; } - - app * mk_0_pw_0_real() const { return m_0_pw_0_real; } - virtual expr * get_some_value(sort * s); virtual bool is_considered_uninterpreted(func_decl * f) { @@ -218,12 +204,7 @@ public: return false; switch (f->get_decl_kind()) { - case OP_0_PW_0_INT: - case OP_0_PW_0_REAL: case OP_NEG_ROOT: - case OP_DIV_0: - case OP_IDIV_0: - case OP_MOD_0: case OP_U_ASIN: case OP_U_ACOS: return true; @@ -276,9 +257,9 @@ public: bool is_uminus(expr const * n) const { return is_app_of(n, m_afid, OP_UMINUS); } bool is_mul(expr const * n) const { return is_app_of(n, m_afid, OP_MUL); } bool is_div(expr const * n) const { return is_app_of(n, m_afid, OP_DIV); } - bool is_div0(expr const * n) const { return is_app_of(n, m_afid, OP_DIV_0); } + //bool is_div0(expr const * n) const { return is_app_of(n, m_afid, OP_DIV_0); } bool is_idiv(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV); } - bool is_idiv0(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV_0); } + //bool is_idiv0(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV_0); } bool is_mod(expr const * n) const { return is_app_of(n, m_afid, OP_MOD); } bool is_rem(expr const * n) const { return is_app_of(n, m_afid, OP_REM); } bool is_to_real(expr const * n) const { return is_app_of(n, m_afid, OP_TO_REAL); } @@ -389,16 +370,16 @@ public: app * mk_lt(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_LT, arg1, arg2); } app * mk_gt(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_GT, arg1, arg2); } - app * mk_add(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_ADD, num_args, args); } - app * mk_add(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2); } - app * mk_add(expr * arg1, expr * arg2, expr* arg3) { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2, arg3); } + app * mk_add(unsigned num_args, expr * const * args) const { return m_manager.mk_app(m_afid, OP_ADD, num_args, args); } + app * mk_add(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2); } + app * mk_add(expr * arg1, expr * arg2, expr* arg3) const { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2, arg3); } - app * mk_sub(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_SUB, arg1, arg2); } - app * mk_sub(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_SUB, num_args, args); } - app * mk_mul(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2); } - app * mk_mul(expr * arg1, expr * arg2, expr* arg3) { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2, arg3); } - app * mk_mul(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_MUL, num_args, args); } - app * mk_uminus(expr * arg) { return m_manager.mk_app(m_afid, OP_UMINUS, arg); } + app * mk_sub(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_SUB, arg1, arg2); } + app * mk_sub(unsigned num_args, expr * const * args) const { return m_manager.mk_app(m_afid, OP_SUB, num_args, args); } + app * mk_mul(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2); } + app * mk_mul(expr * arg1, expr * arg2, expr* arg3) const { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2, arg3); } + app * mk_mul(unsigned num_args, expr * const * args) const { return m_manager.mk_app(m_afid, OP_MUL, num_args, args); } + app * mk_uminus(expr * arg) const { return m_manager.mk_app(m_afid, OP_UMINUS, arg); } app * mk_div(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_DIV, arg1, arg2); } app * mk_idiv(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_IDIV, arg1, arg2); } app * mk_rem(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_REM, arg1, arg2); } @@ -425,11 +406,6 @@ public: app * mk_pi() { return plugin().mk_pi(); } app * mk_e() { return plugin().mk_e(); } - app * mk_0_pw_0_int() { return plugin().mk_0_pw_0_int(); } - app * mk_0_pw_0_real() { return plugin().mk_0_pw_0_real(); } - app * mk_div0(expr * arg) { return m_manager.mk_app(m_afid, OP_DIV_0, arg); } - app * mk_idiv0(expr * arg) { return m_manager.mk_app(m_afid, OP_IDIV_0, arg); } - app * mk_mod0(expr * arg) { return m_manager.mk_app(m_afid, OP_MOD_0, arg); } app * mk_neg_root(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_NEG_ROOT, arg1, arg2); } app * mk_u_asin(expr * arg) { return m_manager.mk_app(m_afid, OP_U_ASIN, arg); } app * mk_u_acos(expr * arg) { return m_manager.mk_app(m_afid, OP_U_ACOS, arg); } diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 18556b71b..fc9b1ac1d 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -680,8 +680,7 @@ br_status arith_rewriter::mk_div_core(expr * arg1, expr * arg2, expr_ref & resul if (m_util.is_numeral(arg2, v2, is_int)) { SASSERT(!is_int); if (v2.is_zero()) { - result = m_util.mk_div0(arg1); - return BR_REWRITE1; + return BR_FAILED; } else if (m_util.is_numeral(arg1, v1, is_int)) { result = m_util.mk_numeral(v1/v2, false); @@ -734,10 +733,6 @@ br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & resu result = m_util.mk_numeral(div(v1, v2), is_int); return BR_DONE; } - if (m_util.is_numeral(arg2, v2, is_int) && v2.is_zero()) { - result = m_util.mk_idiv0(arg1); - return BR_REWRITE1; - } return BR_FAILED; } diff --git a/src/ast/simplifier/arith_simplifier_plugin.cpp b/src/ast/simplifier/arith_simplifier_plugin.cpp index 8410ce143..bfe72b232 100644 --- a/src/ast/simplifier/arith_simplifier_plugin.cpp +++ b/src/ast/simplifier/arith_simplifier_plugin.cpp @@ -405,8 +405,6 @@ bool arith_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * co 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; - case OP_DIV_0: return false; - case OP_IDIV_0: return false; default: return false; } diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index 0f2437982..3e5a9f24f 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -444,16 +444,12 @@ namespace qe { div_rewriter_cfg(nlqsat& s): m(s.m), a(s.m), m_zero(a.mk_real(0), m) {} ~div_rewriter_cfg() {} br_status reduce_app(func_decl* f, unsigned sz, expr* const* args, expr_ref& result, proof_ref& pr) { - if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && !a.is_numeral(args[1])) { + rational r; + if (is_decl_of(f, a.get_family_id(), OP_DIV) && sz == 2 && (!a.is_numeral(args[1], r) || r.is_zero())) { result = m.mk_fresh_const("div", a.mk_real()); m_divs.push_back(div(m, args[0], args[1], to_app(result))); return BR_DONE; } - if (is_decl_of(f, a.get_family_id(), OP_DIV_0) && sz == 1 && !a.is_numeral(args[0])) { - result = m.mk_fresh_const("div", a.mk_real()); - m_divs.push_back(div(m, args[0], m_zero, to_app(result))); - return BR_DONE; - } return BR_FAILED; } vector
const& divs() const { return m_divs; } @@ -507,10 +503,6 @@ namespace qe { m_has_divs = true; return; } - if (a.is_div0(n) && s.m_mode == qsat_t) { - m_has_divs = true; - return; - } TRACE("qe", tout << "not NRA: " << mk_pp(n, s.m) << "\n";); throw tactic_exception("not NRA"); } diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index a30e51133..b5e7db310 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -395,7 +395,8 @@ namespace smt { template theory_var theory_arith::internalize_div(app * n) { - if (!m_util.is_numeral(n->get_arg(1))) found_underspecified_op(n); + rational r; + if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n); found_underspecified_op(n); theory_var s = mk_binary_op(n); context & ctx = get_context(); @@ -406,7 +407,8 @@ namespace smt { template theory_var theory_arith::internalize_idiv(app * n) { - found_underspecified_op(n); + rational r; + if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n); theory_var s = mk_binary_op(n); context & ctx = get_context(); app * mod = m_util.mk_mod(n->get_arg(0), n->get_arg(1)); @@ -419,7 +421,8 @@ namespace smt { template theory_var theory_arith::internalize_mod(app * n) { TRACE("arith_mod", tout << "internalizing...\n" << mk_pp(n, get_manager()) << "\n";); - if (!m_util.is_numeral(n->get_arg(1))) found_underspecified_op(n); + rational r; + if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n); theory_var s = mk_binary_op(n); context & ctx = get_context(); if (!ctx.relevancy()) @@ -429,7 +432,8 @@ namespace smt { template theory_var theory_arith::internalize_rem(app * n) { - if (!m_util.is_numeral(n->get_arg(1))) found_underspecified_op(n); + rational r; + if (!m_util.is_numeral(n->get_arg(1), r) || r.is_zero()) found_underspecified_op(n); theory_var s = mk_binary_op(n); context & ctx = get_context(); if (!ctx.relevancy()) { @@ -734,11 +738,6 @@ namespace smt { return internalize_div(n); else if (m_util.is_idiv(n)) return internalize_idiv(n); - else if (is_app_of(n, get_id(), OP_IDIV_0) || is_app_of(n, get_id(), OP_DIV_0)) { - ctx.internalize(n->get_arg(0), false); - enode * e = mk_enode(n); - return mk_var(e); - } else if (m_util.is_mod(n)) return internalize_mod(n); else if (m_util.is_rem(n)) diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index 124fea910..c5e3ae350 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -292,9 +292,6 @@ namespace smt { } void found_not_handled(expr* n) { - if (a.is_div0(n)) { - return; - } m_not_handled = n; if (is_app(n) && is_underspecified(to_app(n))) { m_underspecified.push_back(to_app(n)); @@ -379,7 +376,12 @@ namespace smt { } else if (is_app(n) && a.get_family_id() == to_app(n)->get_family_id()) { app* t = to_app(n); - found_not_handled(n); + if (a.is_div(n, n1, n2) && is_numeral(n2, r)) { + // skip + } + else { + found_not_handled(n); + } internalize_args(t); mk_enode(t); theory_var v = mk_var(n); diff --git a/src/tactic/arith/purify_arith_tactic.cpp b/src/tactic/arith/purify_arith_tactic.cpp index 0443a51ed..7e89794ce 100644 --- a/src/tactic/arith/purify_arith_tactic.cpp +++ b/src/tactic/arith/purify_arith_tactic.cpp @@ -297,11 +297,11 @@ struct purify_arith_proc { push_cnstr(OR(EQ(y, mk_real_zero()), EQ(u().mk_mul(y, k), x))); push_cnstr_pr(result_pr); - - if (complete()) { + rational r; + if (complete() && (!u().is_numeral(y, r) || r.is_zero())) { // y != 0 \/ k = div-0(x) push_cnstr(OR(NOT(EQ(y, mk_real_zero())), - EQ(k, u().mk_div0(x)))); + EQ(k, u().mk_div(x, mk_real_zero())))); push_cnstr_pr(result_pr); } } @@ -348,11 +348,12 @@ struct purify_arith_proc { push_cnstr(OR(u().mk_ge(y, zero), u().mk_lt(k2, u().mk_mul(u().mk_numeral(rational(-1), true), y)))); push_cnstr_pr(mod_pr); - if (complete()) { - push_cnstr(OR(NOT(EQ(y, zero)), EQ(k1, u().mk_idiv0(x)))); + rational r; + if (complete() && (!u().is_numeral(y, r) || r.is_zero())) { + push_cnstr(OR(NOT(EQ(y, zero)), EQ(k1, u().mk_idiv(x, zero)))); push_cnstr_pr(result_pr); - push_cnstr(OR(NOT(EQ(y, zero)), EQ(k2, u().mk_mod0(x)))); + push_cnstr(OR(NOT(EQ(y, zero)), EQ(k2, u().mk_mod(x, zero)))); push_cnstr_pr(mod_pr); } } @@ -414,7 +415,7 @@ struct purify_arith_proc { // (^ x 0) --> k | x != 0 implies k = 1, x = 0 implies k = 0^0 push_cnstr(OR(EQ(x, zero), EQ(k, one))); push_cnstr_pr(result_pr); - push_cnstr(OR(NOT(EQ(x, zero)), EQ(k, is_int ? u().mk_0_pw_0_int() : u().mk_0_pw_0_real()))); + push_cnstr(OR(NOT(EQ(x, zero)), EQ(k, u().mk_power(zero, zero)))); push_cnstr_pr(result_pr); } else if (!is_int) { From ce8443581d31b4194f6db010d91f9dab8ee55aac Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 12:15:27 -0700 Subject: [PATCH 214/488] add API methods for creating and modifying models, #1223 Signed-off-by: Nikolaj Bjorner --- src/api/api_model.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++ src/api/c++/z3++.h | 20 ++++++++++++++ src/api/z3_api.h | 54 +++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index de917650d..66002baa0 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -30,6 +30,17 @@ Revision History: extern "C" { + Z3_model Z3_API Z3_mk_model(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_model(c); + RESET_ERROR_CODE(); + Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c)); + m_ref->m_model = alloc(model, mk_c(c)->m()); + mk_c(c)->save_object(m_ref); + RETURN_Z3(of_model(m_ref)); + Z3_CATCH_RETURN(0); + } + void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m) { Z3_TRY; LOG_Z3_model_inc_ref(c, m); @@ -224,6 +235,31 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast else_val) { + Z3_TRY; + LOG_Z3_add_func_interp(c, m, f, else_val); + RESET_ERROR_CODE(); + func_decl* d = to_func_decl(f); + model* mdl = to_model_ref(m); + Z3_func_interp_ref * f_ref = alloc(Z3_func_interp_ref, *mk_c(c), mdl); + f_ref->m_func_interp = alloc(func_interp, mk_c(c)->m(), d->get_arity()); + mk_c(c)->save_object(f_ref); + mdl->register_decl(d, f_ref->m_func_interp); + f_ref->m_func_interp->set_else(to_expr(else_val)); + RETURN_Z3(of_func_interp(f_ref)); + Z3_CATCH_RETURN(0); + } + + void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a) { + Z3_TRY; + LOG_Z3_add_const_interp(c, m, f, a); + RESET_ERROR_CODE(); + func_decl* d = to_func_decl(f); + model* mdl = to_model_ref(m); + mdl->register_decl(d, to_expr(a)); + Z3_CATCH; + } + void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f) { Z3_TRY; LOG_Z3_func_interp_inc_ref(c, f); @@ -283,6 +319,15 @@ extern "C" { Z3_CATCH_RETURN(0); } + void Z3_API Z3_func_interp_set_else(Z3_context c, Z3_func_interp f, Z3_ast else_value) { + Z3_TRY; + LOG_Z3_func_interp_set_else(c, f, else_value); + RESET_ERROR_CODE(); + // CHECK_NON_NULL(f, 0); + to_func_interp_ref(f)->set_else(to_expr(else_value)); + Z3_CATCH; + } + unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f) { Z3_TRY; LOG_Z3_func_interp_get_arity(c, f); @@ -292,6 +337,24 @@ extern "C" { Z3_CATCH_RETURN(0); } + void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value) { + Z3_TRY; + LOG_Z3_add_func_entry(c, fi, args, value); + //CHECK_NON_NULL(fi, void); + //CHECK_NON_NULL(args, void); + //CHECK_NON_NULL(value, void); + func_interp* _fi = to_func_interp_ref(fi); + expr* _value = to_expr(value); + if (to_ast_vector_ref(args).size() != _fi->get_arity()) { + SET_ERROR_CODE(Z3_IOB); + return; + } + // check sorts of value + expr* const* _args = (expr* const*) to_ast_vector_ref(args).c_ptr(); + _fi->insert_entry(_args, _value); + Z3_CATCH; + } + void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e) { Z3_TRY; LOG_Z3_func_entry_inc_ref(c, e); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 42db6f352..2f67cb72a 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1731,6 +1731,14 @@ namespace z3 { expr else_value() const { Z3_ast r = Z3_func_interp_get_else(ctx(), m_interp); check_error(); return expr(ctx(), r); } unsigned num_entries() const { unsigned r = Z3_func_interp_get_num_entries(ctx(), m_interp); check_error(); return r; } func_entry entry(unsigned i) const { Z3_func_entry e = Z3_func_interp_get_entry(ctx(), m_interp, i); check_error(); return func_entry(ctx(), e); } + void add_entry(expr_vector const& args, expr& value) { + Z3_add_func_entry(ctx(), m_interp, args, value); + check_error(); + } + void set_else(expr& value) { + Z3_func_entry_set_else(ctx(), m_interp, value); + check_error(); + } }; class model : public object { @@ -1740,6 +1748,7 @@ namespace z3 { Z3_model_inc_ref(ctx(), m); } public: + model(context & c):object(c) { init(Z3_mk_model(c)); } model(context & c, Z3_model m):object(c) { init(m); } model(model const & s):object(s) { init(s.m_model); } ~model() { Z3_model_dec_ref(ctx(), m_model); } @@ -1795,6 +1804,17 @@ namespace z3 { return 0 != Z3_model_has_interp(ctx(), m_model, f); } + func_interp add_func_interp(func_decl& f, expr& else_val) { + Z3_func_interp r = Z3_add_func_interp(ctx(), m_model, f, else_val); + check_error(); + return func_interp(ctx(), r); + } + + void add_const_interp(func_decl& f, expr& value) { + Z3_add_const_interp(ctx(), m_model, f, value); + check_error(); + } + friend std::ostream & operator<<(std::ostream & out, model const & m); }; inline std::ostream & operator<<(std::ostream & out, model const & m) { out << Z3_model_to_string(m.ctx(), m); return out; } diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 43c175ca8..045417d38 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4680,6 +4680,14 @@ extern "C" { /** @name Models */ /*@{*/ + + /** + \brief Create a fresh model object. It has reference count 0. + + def_API('Z3_mk_model', MODEL, (_in(CONTEXT),)) + */ + Z3_model Z3_API Z3_mk_model(Z3_context c); + /** \brief Increment the reference counter of the given model. @@ -4850,6 +4858,26 @@ extern "C" { */ Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a); + /** + \brief Create a fresh func_interp object, add it to a model for a specified function. + It has reference count 0. + + \param c context + \param m model + \param f function declaration + \param default_value default value for function interpretation + + def_API('Z3_add_func_interp', FUNC_INTERP, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _in(AST))) + */ + Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast default_value); + + /** + \brief Add a constant interpretation. + + def_API('Z3_add_const_interp', VOID, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _in(AST))) + */ + void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a); + /** \brief Increment the reference counter of the given Z3_func_interp object. @@ -4897,6 +4925,16 @@ extern "C" { */ Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f); + /** + \brief Return the 'else' value of the given function interpretation. + + A function interpretation is represented as a finite map and an 'else' value. + This procedure can be used to update the 'else' value. + + def_API('Z3_func_interp_set_else', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST))) + */ + void Z3_API Z3_func_interp_set_else(Z3_context c, Z3_func_interp f, Z3_ast else_value); + /** \brief Return the arity (number of arguments) of the given function interpretation. @@ -4904,6 +4942,22 @@ extern "C" { */ unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f); + /** + \brief add a function entry to a function interpretation. + + \param c logical context + \param fi a function interpregation to be updated. + \param args list of arguments. They should be constant values (such as integers) and be of the same types as the domain of the function. + \param value value of the function when the parameters match args. + + It is assumed that entries added to a function cover disjoint arguments. + If an two entries are added with the same arguments, only the second insertion survives and the + first inserted entry is removed. + + def_API('Z3_add_func_entry', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST_VECTOR), _in(AST))) + */ + void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value); + /** \brief Increment the reference counter of the given Z3_func_entry object. From f9dc6385b203621f810c1e44df5ea9facc989b41 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 12:19:24 -0700 Subject: [PATCH 215/488] n/a Signed-off-by: Nikolaj Bjorner --- src/api/api_model.cpp | 9 +++++++++ src/api/c++/z3++.h | 4 ++++ src/api/z3_api.h | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index 1646c691f..66002baa0 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -319,6 +319,15 @@ extern "C" { Z3_CATCH_RETURN(0); } + void Z3_API Z3_func_interp_set_else(Z3_context c, Z3_func_interp f, Z3_ast else_value) { + Z3_TRY; + LOG_Z3_func_interp_set_else(c, f, else_value); + RESET_ERROR_CODE(); + // CHECK_NON_NULL(f, 0); + to_func_interp_ref(f)->set_else(to_expr(else_value)); + Z3_CATCH; + } + unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f) { Z3_TRY; LOG_Z3_func_interp_get_arity(c, f); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index cf1a5070a..2f67cb72a 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1735,6 +1735,10 @@ namespace z3 { Z3_add_func_entry(ctx(), m_interp, args, value); check_error(); } + void set_else(expr& value) { + Z3_func_entry_set_else(ctx(), m_interp, value); + check_error(); + } }; class model : public object { diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 2f14c3f2e..045417d38 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4925,6 +4925,16 @@ extern "C" { */ Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f); + /** + \brief Return the 'else' value of the given function interpretation. + + A function interpretation is represented as a finite map and an 'else' value. + This procedure can be used to update the 'else' value. + + def_API('Z3_func_interp_set_else', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST))) + */ + void Z3_API Z3_func_interp_set_else(Z3_context c, Z3_func_interp f, Z3_ast else_value); + /** \brief Return the arity (number of arguments) of the given function interpretation. From 623cd5ded2bbc414faca3ca2295d62c935c026f0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 13:00:43 -0700 Subject: [PATCH 216/488] fix naming for functions #1223 Signed-off-by: Nikolaj Bjorner --- src/api/api_model.cpp | 4 ++-- src/api/c++/z3++.h | 4 ++-- src/api/z3_api.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index 66002baa0..540f014c6 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -337,9 +337,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value) { + void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value) { Z3_TRY; - LOG_Z3_add_func_entry(c, fi, args, value); + LOG_Z3_func_interp_add_entry(c, fi, args, value); //CHECK_NON_NULL(fi, void); //CHECK_NON_NULL(args, void); //CHECK_NON_NULL(value, void); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 2f67cb72a..6d8ff3b35 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1732,11 +1732,11 @@ namespace z3 { unsigned num_entries() const { unsigned r = Z3_func_interp_get_num_entries(ctx(), m_interp); check_error(); return r; } func_entry entry(unsigned i) const { Z3_func_entry e = Z3_func_interp_get_entry(ctx(), m_interp, i); check_error(); return func_entry(ctx(), e); } void add_entry(expr_vector const& args, expr& value) { - Z3_add_func_entry(ctx(), m_interp, args, value); + Z3_func_interp_add_entry(ctx(), m_interp, args, value); check_error(); } void set_else(expr& value) { - Z3_func_entry_set_else(ctx(), m_interp, value); + Z3_func_interp_set_else(ctx(), m_interp, value); check_error(); } }; diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 045417d38..bed70cb6c 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4954,9 +4954,9 @@ extern "C" { If an two entries are added with the same arguments, only the second insertion survives and the first inserted entry is removed. - def_API('Z3_add_func_entry', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST_VECTOR), _in(AST))) + def_API('Z3_func_interp_add_entry', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST_VECTOR), _in(AST))) */ - void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value); + void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value); /** \brief Increment the reference counter of the given Z3_func_entry object. From 03f263b974a8300444a956877940c9967a425b3b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 13:02:59 -0700 Subject: [PATCH 217/488] update names Signed-off-by: Nikolaj Bjorner --- src/api/api_model.cpp | 4 ++-- src/api/c++/z3++.h | 4 ++-- src/api/z3_api.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index 66002baa0..540f014c6 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -337,9 +337,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value) { + void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value) { Z3_TRY; - LOG_Z3_add_func_entry(c, fi, args, value); + LOG_Z3_func_interp_add_entry(c, fi, args, value); //CHECK_NON_NULL(fi, void); //CHECK_NON_NULL(args, void); //CHECK_NON_NULL(value, void); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 2f67cb72a..6d8ff3b35 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1732,11 +1732,11 @@ namespace z3 { unsigned num_entries() const { unsigned r = Z3_func_interp_get_num_entries(ctx(), m_interp); check_error(); return r; } func_entry entry(unsigned i) const { Z3_func_entry e = Z3_func_interp_get_entry(ctx(), m_interp, i); check_error(); return func_entry(ctx(), e); } void add_entry(expr_vector const& args, expr& value) { - Z3_add_func_entry(ctx(), m_interp, args, value); + Z3_func_interp_add_entry(ctx(), m_interp, args, value); check_error(); } void set_else(expr& value) { - Z3_func_entry_set_else(ctx(), m_interp, value); + Z3_func_interp_set_else(ctx(), m_interp, value); check_error(); } }; diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 045417d38..bed70cb6c 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4954,9 +4954,9 @@ extern "C" { If an two entries are added with the same arguments, only the second insertion survives and the first inserted entry is removed. - def_API('Z3_add_func_entry', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST_VECTOR), _in(AST))) + def_API('Z3_func_interp_add_entry', VOID, (_in(CONTEXT), _in(FUNC_INTERP), _in(AST_VECTOR), _in(AST))) */ - void Z3_API Z3_add_func_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value); + void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value); /** \brief Increment the reference counter of the given Z3_func_entry object. From 5db349f6fafc5b117dd49e11d7f2cd42531732af Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 27 Aug 2017 23:52:27 -0700 Subject: [PATCH 218/488] raise an exception if trying proof generation for the SAT solver. Stackoverflow question https://stackoverflow.com/questions/45885321/check-function-while-qf-fd-logic-is-set-throws-accessviolationexception Signed-off-by: Nikolaj Bjorner --- src/sat/sat_solver/inc_sat_solver.cpp | 3 +++ src/tactic/portfolio/smt_strategic_solver.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sat/sat_solver/inc_sat_solver.cpp b/src/sat/sat_solver/inc_sat_solver.cpp index 521aa5e71..21f9f1e8a 100644 --- a/src/sat/sat_solver/inc_sat_solver.cpp +++ b/src/sat/sat_solver/inc_sat_solver.cpp @@ -388,6 +388,9 @@ private: m_subgoals.reset(); init_preprocess(); SASSERT(g->models_enabled()); + if (g->proofs_enabled()) { + throw default_exception("generation of proof objects is not supported in this mode"); + } SASSERT(!g->proofs_enabled()); TRACE("sat", g->display(tout);); try { diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index 0ad9e5f19..3e77b7abc 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -93,7 +93,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const return mk_qffpbv_tactic(m, p); else if (logic=="HORN") return mk_horn_tactic(m, p); - else if (logic == "QF_FD" || logic == "SAT") + else if ((logic == "QF_FD" || logic == "SAT") && !m.proofs_enabled()) return mk_solver2tactic(mk_fd_solver(m, p)); //else if (logic=="QF_UFNRA") // return mk_qfufnra_tactic(m, p); @@ -102,7 +102,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const } static solver* mk_special_solver_for_logic(ast_manager & m, params_ref const & p, symbol const& logic) { - if (logic == "QF_FD" || logic == "SAT") + if ((logic == "QF_FD" || logic == "SAT") && !m.proofs_enabled()) return mk_fd_solver(m, p); return 0; } From 8542e4ae3df20070e9922b5e25e7381b6985ceb7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 00:05:53 -0700 Subject: [PATCH 219/488] add pre-processing simplificaiton of power to the legacy simplifier Fixes #1237 Signed-off-by: Nikolaj Bjorner --- .../simplifier/arith_simplifier_plugin.cpp | 21 ++++++++++++++++++- src/ast/simplifier/arith_simplifier_plugin.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/ast/simplifier/arith_simplifier_plugin.cpp b/src/ast/simplifier/arith_simplifier_plugin.cpp index bfe72b232..d604ba2ff 100644 --- a/src/ast/simplifier/arith_simplifier_plugin.cpp +++ b/src/ast/simplifier/arith_simplifier_plugin.cpp @@ -402,7 +402,7 @@ bool arith_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * co case OP_TO_REAL: SASSERT(num_args == 1); mk_to_real(args[0], result); break; 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_POWER: SASSERT(num_args == 2); mk_power(args[0], args[1], result); break; case OP_ABS: SASSERT(num_args == 1); mk_abs(args[0], result); break; case OP_IRRATIONAL_ALGEBRAIC_NUM: return false; default: @@ -412,6 +412,25 @@ bool arith_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * co return true; } +void arith_simplifier_plugin::mk_power(expr* x, expr* y, expr_ref& result) { + rational a, b; + if (is_numeral(y, b) && b.is_one()) { + result = x; + return; + } + if (is_numeral(x, a) && is_numeral(y, b) && b.is_unsigned()) { + if (b.is_zero() && !a.is_zero()) { + result = m_util.mk_numeral(rational(1), m_manager.get_sort(x)); + return; + } + if (!b.is_zero()) { + result = m_util.mk_numeral(power(a, b.get_unsigned()), m_manager.get_sort(x)); + return; + } + } + result = m_util.mk_power(x, y); +} + void arith_simplifier_plugin::mk_abs(expr * arg, expr_ref & result) { expr_ref c(m_manager); expr_ref m_arg(m_manager); diff --git a/src/ast/simplifier/arith_simplifier_plugin.h b/src/ast/simplifier/arith_simplifier_plugin.h index 21ab8f6b4..4f3a6add0 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_power(expr* x, expr* y, 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); From 974eaab01c752df9d61d53887709a5eb9a71ef1d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 01:38:23 -0700 Subject: [PATCH 220/488] complement regular expressions when used in negated membership constraints #1224 Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 1 + src/math/automata/automaton.h | 59 +++++++++++------------ src/math/automata/symbolic_automata.h | 3 +- src/math/automata/symbolic_automata_def.h | 17 +++++-- src/smt/theory_seq.cpp | 20 +++++--- 5 files changed, 58 insertions(+), 42 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index f347a8e49..4f9a88490 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1726,6 +1726,7 @@ ast * ast_manager::register_node_core(ast * n) { } n->m_id = is_decl(n) ? m_decl_id_gen.mk() : m_expr_id_gen.mk(); + static unsigned s_counter = 0; TRACE("ast", tout << "Object " << n->m_id << " was created.\n";); diff --git a/src/math/automata/automaton.h b/src/math/automata/automaton.h index cf4dcbfc6..2f55d5cc2 100644 --- a/src/math/automata/automaton.h +++ b/src/math/automata/automaton.h @@ -107,11 +107,10 @@ public: m_init = init; m_delta.push_back(moves()); m_delta_inv.push_back(moves()); - for (unsigned i = 0; i < final.size(); ++i) { - add_to_final_states(final[i]); + for (unsigned f : final) { + add_to_final_states(f); } - for (unsigned i = 0; i < mvs.size(); ++i) { - move const& mv = mvs[i]; + for (move const& mv : mvs) { unsigned n = std::max(mv.src(), mv.dst()); if (n >= m_delta.size()) { m_delta.resize(n+1, moves()); @@ -280,8 +279,8 @@ public: } else { init = a.num_states(); - for (unsigned i = 0; i < a.m_final_states.size(); ++i) { - mvs.push_back(move(m, init, a.m_final_states[i])); + for (unsigned st : a.m_final_states) { + mvs.push_back(move(m, init, st)); } } return alloc(automaton, m, init, final, mvs); @@ -471,18 +470,17 @@ public: moves const& get_moves_to(unsigned state) const { return m_delta_inv[state]; } bool initial_state_is_source() const { return m_delta_inv[m_init].empty(); } bool is_final_state(unsigned s) const { return m_final_set.contains(s); } - bool is_final_configuration(uint_set s) const { - for (uint_set::iterator it = s.begin(), end = s.end(); it != end; ++it) { - if (is_final_state(*it)) - return true; - } - return false; - } + bool is_final_configuration(uint_set s) const { + for (unsigned i : s) { + if (is_final_state(i)) + return true; + } + return false; + } bool is_epsilon_free() const { - for (unsigned i = 0; i < m_delta.size(); ++i) { - moves const& mvs = m_delta[i]; - for (unsigned j = 0; j < mvs.size(); ++j) { - if (!mvs[j].t()) return false; + for (moves const& mvs : m_delta) { + for (move const & m : mvs) { + if (!m.t()) return false; } } return true; @@ -490,8 +488,8 @@ public: bool all_epsilon_in(unsigned s) { moves const& mvs = m_delta_inv[s]; - for (unsigned j = 0; j < mvs.size(); ++j) { - if (mvs[j].t()) return false; + for (move const& m : mvs) { + if (m.t()) return false; } return true; } @@ -504,15 +502,15 @@ public: bool is_loop_state(unsigned s) const { moves mvs; get_moves_from(s, mvs); - for (unsigned i = 0; i < mvs.size(); ++i) { - if (s == mvs[i].dst()) return true; + for (move const& m : mvs) { + if (s == m.dst()) return true; } return false; } unsigned move_count() const { unsigned result = 0; - for (unsigned i = 0; i < m_delta.size(); result += m_delta[i].size(), ++i) {} + for (moves const& mvs : m_delta) result += mvs.size(); return result; } void get_epsilon_closure(unsigned state, unsigned_vector& states) { @@ -524,13 +522,13 @@ public: void get_moves_from(unsigned state, moves& mvs, bool epsilon_closure = true) const { get_moves(state, m_delta, mvs, epsilon_closure); } - void get_moves_from_states(uint_set states, moves& mvs, bool epsilon_closure = true) const { - for (uint_set::iterator it = states.begin(), end = states.end(); it != end; ++it) { - moves curr; - get_moves(*it, m_delta, curr, epsilon_closure); - mvs.append(curr); - } - } + void get_moves_from_states(uint_set states, moves& mvs, bool epsilon_closure = true) const { + for (unsigned i : states) { + moves curr; + get_moves(i, m_delta, curr, epsilon_closure); + mvs.append(curr); + } + } void get_moves_to(unsigned state, moves& mvs, bool epsilon_closure = true) { get_moves(state, m_delta_inv, mvs, epsilon_closure); } @@ -543,8 +541,7 @@ public: out << "\n"; for (unsigned i = 0; i < m_delta.size(); ++i) { moves const& mvs = m_delta[i]; - for (unsigned j = 0; j < mvs.size(); ++j) { - move const& mv = mvs[j]; + for (move const& mv : mvs) { out << i << " -> " << mv.dst() << " "; if (mv.t()) { out << "if "; diff --git a/src/math/automata/symbolic_automata.h b/src/math/automata/symbolic_automata.h index 4a8e7a74d..35545e975 100644 --- a/src/math/automata/symbolic_automata.h +++ b/src/math/automata/symbolic_automata.h @@ -136,7 +136,8 @@ private: //false case curr_bv.push_back(false); - ref_t new_pred_neg(m_ba.mk_and(curr_pred, m_ba.mk_not(constraints[i])), m); + ref_t neg(m_ba.mk_not(constraints[i]), m); + ref_t new_pred_neg(m_ba.mk_and(curr_pred, neg), m); generate_min_terms_rec(constraints, min_terms, i + 1, curr_bv, new_pred_neg); curr_bv.pop_back(); } diff --git a/src/math/automata/symbolic_automata_def.h b/src/math/automata/symbolic_automata_def.h index c1ee53214..aa8dd34fd 100644 --- a/src/math/automata/symbolic_automata_def.h +++ b/src/math/automata/symbolic_automata_def.h @@ -288,7 +288,7 @@ typename symbolic_automata::automaton_t* symbolic_automata::mk_determinstic_param(automaton_t& a, bool flip_acceptance) { vector, ref_t> > min_terms; vector predicates; - + map s2id; // set of states to unique id vector id2s; // unique id to set of b-states uint_set set; @@ -296,9 +296,19 @@ symbolic_automata::mk_determinstic_param(automaton_t& a, bool flip_accepta moves_t new_mvs; // moves in the resulting automaton unsigned_vector new_final_states; // new final states unsigned p_state_id = 0; // next state identifier - + + TRACE("seq", tout << "mk-deterministic " << flip_acceptance << " " << set << " " << a.is_final_configuration(set) << "\n";); // adds non-final states of a to final if flipping and and final otherwise - if (a.is_final_configuration(set) != flip_acceptance) { + unsigned_vector init_states; + a.get_epsilon_closure(a.init(), init_states); + bool found_final = false; + for (unsigned s : init_states) { + if (a.is_final_state(s)) { + found_final = true; + break; + } + } + if (found_final != flip_acceptance) { new_final_states.push_back(p_state_id); } @@ -342,6 +352,7 @@ symbolic_automata::mk_determinstic_param(automaton_t& a, bool flip_accepta bool is_new = !s2id.contains(set); if (is_new) { + TRACE("seq", tout << "mk-deterministic " << flip_acceptance << " " << set << " " << a.is_final_configuration(set) << "\n";); if (a.is_final_configuration(set) != flip_acceptance) { new_final_states.push_back(p_state_id); } diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index c91882dad..a32a4833a 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -3391,15 +3391,22 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) { return; } - eautomaton* a = get_automaton(e2); + expr_ref e3(e2, m); + context& ctx = get_context(); + literal lit = ctx.get_literal(n); + if (!is_true) { + e3 = m_util.re.mk_complement(e2); + is_true = true; + lit.neg(); + } + eautomaton* a = get_automaton(e3); if (!a) return; - context& ctx = get_context(); expr_ref len(m_util.str.mk_length(e1), m); for (unsigned i = 0; i < a->num_states(); ++i) { - literal acc = mk_accept(e1, len, e2, i); - literal rej = mk_reject(e1, len, e2, i); + literal acc = mk_accept(e1, len, e3, i); + literal rej = mk_reject(e1, len, e3, i); add_axiom(a->is_final_state(i)?acc:~acc); add_axiom(a->is_final_state(i)?~rej:rej); } @@ -3408,17 +3415,16 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) { unsigned_vector states; a->get_epsilon_closure(a->init(), states); literal_vector lits; - literal lit = ctx.get_literal(n); if (is_true) { lits.push_back(~lit); } for (unsigned i = 0; i < states.size(); ++i) { if (is_true) { - lits.push_back(mk_accept(e1, zero, e2, states[i])); + lits.push_back(mk_accept(e1, zero, e3, states[i])); } else { literal nlit = ~lit; - propagate_lit(0, 1, &nlit, mk_reject(e1, zero, e2, states[i])); + propagate_lit(0, 1, &nlit, mk_reject(e1, zero, e3, states[i])); } } if (is_true) { From 0ebb9172681e11b6ac0bcea6a4d69b021282a21a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 01:40:15 -0700 Subject: [PATCH 221/488] complement regular expressions when used in negated membership constraints #1224 Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 2 -- src/math/automata/symbolic_automata.h | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 4f9a88490..5c0abf6b8 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1726,8 +1726,6 @@ ast * ast_manager::register_node_core(ast * n) { } n->m_id = is_decl(n) ? m_decl_id_gen.mk() : m_expr_id_gen.mk(); - static unsigned s_counter = 0; - TRACE("ast", tout << "Object " << n->m_id << " was created.\n";); TRACE("mk_var_bug", tout << "mk_ast: " << n->m_id << "\n";); diff --git a/src/math/automata/symbolic_automata.h b/src/math/automata/symbolic_automata.h index 35545e975..4831280af 100644 --- a/src/math/automata/symbolic_automata.h +++ b/src/math/automata/symbolic_automata.h @@ -130,13 +130,13 @@ private: else { //true case curr_bv.push_back(true); - ref_t new_pred_pos(m_ba.mk_and(curr_pred, constraints[i]), m); + ref_t new_pred_pos(m_ba.mk_and(curr_pred, constraints[i]), m); generate_min_terms_rec(constraints, min_terms, i + 1, curr_bv, new_pred_pos); curr_bv.pop_back(); //false case curr_bv.push_back(false); - ref_t neg(m_ba.mk_not(constraints[i]), m); + ref_t neg(m_ba.mk_not(constraints[i]), m); ref_t new_pred_neg(m_ba.mk_and(curr_pred, neg), m); generate_min_terms_rec(constraints, min_terms, i + 1, curr_bv, new_pred_neg); curr_bv.pop_back(); From 9e4b2a67959fa09cbfb7e09abea81c0d88d255af Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 02:55:50 -0700 Subject: [PATCH 222/488] port simplifications on bv2int Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/bv_rewriter.cpp | 79 +++++++++++++++++++++++++++++++- src/ast/rewriter/bv_rewriter.h | 5 ++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index edd601c9c..75f931c1d 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -1365,13 +1365,88 @@ br_status bv_rewriter::mk_bv2int(expr * arg, expr_ref & result) { result = m_autil.mk_numeral(v, true); return BR_DONE; } - - // TODO: add other simplifications + if (m_util.is_concat(arg)) { + if (to_app(arg)->get_num_args() == 0) { + result = m_autil.mk_int(0); + return BR_DONE; + } + expr_ref_vector args(m()); + + unsigned num_args = to_app(arg)->get_num_args(); + for (expr* x : *to_app(arg)) { + args.push_back(m_util.mk_bv2int(x)); + } + unsigned sz = get_bv_size(to_app(arg)->get_arg(num_args-1)); + for (unsigned i = num_args - 1; i > 0; ) { + expr_ref tmp(m()); + --i; + tmp = args[i].get(); + tmp = m_autil.mk_mul(m_autil.mk_numeral(power(numeral(2), sz), true), tmp); + args[i] = tmp; + sz += get_bv_size(to_app(arg)->get_arg(i)); + } + result = m_autil.mk_add(args.size(), args.c_ptr()); + return BR_REWRITE2; + } + if (is_mul_no_overflow(arg)) { + expr_ref_vector args(m()); + for (expr* x : *to_app(arg)) args.push_back(m_util.mk_bv2int(x)); + result = m_autil.mk_mul(args.size(), args.c_ptr()); + return BR_REWRITE2; + } + if (is_add_no_overflow(arg)) { + expr_ref_vector args(m()); + for (expr* x : *to_app(arg)) args.push_back(m_util.mk_bv2int(x)); + result = m_autil.mk_add(args.size(), args.c_ptr()); + return BR_REWRITE2; + } return BR_FAILED; } +bool bv_rewriter::is_mul_no_overflow(expr* e) { + if (!m_util.is_bv_mul(e)) return false; + unsigned sz = get_bv_size(e); + unsigned sum = 0; + for (expr* x : *to_app(e)) sum += sz-num_leading_zero_bits(x); + return sum < sz; +} + +bool bv_rewriter::is_add_no_overflow(expr* e) { + if (!is_add(e)) return false; + for (expr* x : *to_app(e)) { + if (0 == num_leading_zero_bits(x)) return false; + } + return true; +} + +unsigned bv_rewriter::num_leading_zero_bits(expr* e) { + numeral v; + unsigned sz = get_bv_size(e); + if (m_util.is_numeral(e, v)) { + while (v.is_pos()) { + SASSERT(sz > 0); + --sz; + v = div(v, numeral(2)); + } + return sz; + } + else if (m_util.is_concat(e)) { + app* a = to_app(e); + unsigned sz1 = get_bv_size(a->get_arg(0)); + unsigned nb1 = num_leading_zero_bits(a->get_arg(0)); + if (sz1 == nb1) { + nb1 += num_leading_zero_bits(a->get_arg(1)); + } + return nb1; + } + return 0; +} + + + + br_status bv_rewriter::mk_concat(unsigned num_args, expr * const * args, expr_ref & result) { expr_ref_buffer new_args(m()); numeral v1; diff --git a/src/ast/rewriter/bv_rewriter.h b/src/ast/rewriter/bv_rewriter.h index 45bd6c264..205ebbf8e 100644 --- a/src/ast/rewriter/bv_rewriter.h +++ b/src/ast/rewriter/bv_rewriter.h @@ -42,6 +42,7 @@ protected: decl_kind mul_decl_kind() const { return OP_BMUL; } bool use_power() const { return false; } decl_kind power_decl_kind() const { UNREACHABLE(); return static_cast(UINT_MAX); } + public: bv_rewriter_core(ast_manager & m):m_util(m) {} }; @@ -108,6 +109,10 @@ class bv_rewriter : public poly_rewriter { br_status mk_bv_ashr(expr * arg1, expr * arg2, expr_ref & result); bool is_minus_one_core(expr * arg) const; bool is_x_minus_one(expr * arg, expr * & x); + bool is_add_no_overflow(expr* e); + bool is_mul_no_overflow(expr* e); + unsigned num_leading_zero_bits(expr* e); + br_status mk_bv_sdiv_core(expr * arg1, expr * arg2, bool hi_div0, expr_ref & result); br_status mk_bv_udiv_core(expr * arg1, expr * arg2, bool hi_div0, expr_ref & result); br_status mk_bv_srem_core(expr * arg1, expr * arg2, bool hi_div0, expr_ref & result); From f20e95184ee6532d7a538886c46cf6ad02ee9733 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 13:29:51 -0700 Subject: [PATCH 223/488] remove old_simplify dependencies Signed-off-by: Nikolaj Bjorner --- src/CMakeLists.txt | 3 - src/ast/simplifier/CMakeLists.txt | 9 +- src/ast/simplifier/array_simplifier_params.h | 6 +- src/ast/simplifier/bv_simplifier_params.cpp | 2 +- src/ast/simplifier/maximise_ac_sharing.cpp | 192 ------------------- src/ast/simplifier/maximise_ac_sharing.h | 124 ------------ src/smt/params/CMakeLists.txt | 1 - src/smt/params/preprocessor_params.cpp | 4 - src/smt/params/preprocessor_params.h | 6 +- src/smt/params/theory_arith_params.cpp | 2 + src/smt/params/theory_arith_params.h | 4 + src/smt/params/theory_array_params.h | 8 +- src/smt/params/theory_bv_params.cpp | 6 +- src/smt/params/theory_bv_params.h | 2 + 14 files changed, 26 insertions(+), 343 deletions(-) delete mode 100644 src/ast/simplifier/maximise_ac_sharing.cpp delete mode 100644 src/ast/simplifier/maximise_ac_sharing.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3df33aac9..277335ce9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,9 +68,6 @@ add_subdirectory(cmd_context) add_subdirectory(cmd_context/extra_cmds) add_subdirectory(parsers/smt2) add_subdirectory(ast/proof_checker) -## Simplifier module will be deleted in the future. -## It has been replaced with rewriter component. -add_subdirectory(ast/simplifier) add_subdirectory(ast/fpa) add_subdirectory(ast/macros) add_subdirectory(ast/pattern) diff --git a/src/ast/simplifier/CMakeLists.txt b/src/ast/simplifier/CMakeLists.txt index 649c0486e..37d96b1a5 100644 --- a/src/ast/simplifier/CMakeLists.txt +++ b/src/ast/simplifier/CMakeLists.txt @@ -2,11 +2,11 @@ z3_add_component(simplifier SOURCES arith_simplifier_params.cpp # arith_simplifier_plugin.cpp - array_simplifier_params.cpp +# array_simplifier_params.cpp # array_simplifier_plugin.cpp # basic_simplifier_plugin.cpp # bv_elim.cpp - bv_simplifier_params.cpp +# bv_simplifier_params.cpp # bv_simplifier_plugin.cpp # datatype_simplifier_plugin.cpp # elim_bounds.cpp @@ -18,8 +18,5 @@ z3_add_component(simplifier # simplifier_plugin.cpp COMPONENT_DEPENDENCIES rewriter - PYG_FILES - arith_simplifier_params_helper.pyg - array_simplifier_params_helper.pyg - bv_simplifier_params_helper.pyg + ) diff --git a/src/ast/simplifier/array_simplifier_params.h b/src/ast/simplifier/array_simplifier_params.h index 559e3de54..07ead5fd6 100644 --- a/src/ast/simplifier/array_simplifier_params.h +++ b/src/ast/simplifier/array_simplifier_params.h @@ -21,11 +21,9 @@ Revision History: #include "util/params.h" -struct array_simplifier_params { - bool m_array_canonize_simplify; - bool m_array_simplify; // temporary hack for disabling array simplifier plugin. +struct array_simplifier_params1 { - array_simplifier_params(params_ref const & p = params_ref()) { + array_simplifier_params1(params_ref const & p = params_ref()) { updt_params(p); } diff --git a/src/ast/simplifier/bv_simplifier_params.cpp b/src/ast/simplifier/bv_simplifier_params.cpp index 4c6b4a5fa..07f854179 100644 --- a/src/ast/simplifier/bv_simplifier_params.cpp +++ b/src/ast/simplifier/bv_simplifier_params.cpp @@ -33,4 +33,4 @@ void bv_simplifier_params::updt_params(params_ref const & _p) { void bv_simplifier_params::display(std::ostream & out) const { DISPLAY_PARAM(m_hi_div0); DISPLAY_PARAM(m_bv2int_distribute); -} \ No newline at end of file +} diff --git a/src/ast/simplifier/maximise_ac_sharing.cpp b/src/ast/simplifier/maximise_ac_sharing.cpp deleted file mode 100644 index 93e5a43f0..000000000 --- a/src/ast/simplifier/maximise_ac_sharing.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - maximise_ac_sharing.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-10-22. - -Revision History: - ---*/ - -#include "ast/simplifier/maximise_ac_sharing.h" -#include "ast/ast_pp.h" -#include "ast/simplifier/basic_simplifier_plugin.h" - -maximise_ac_sharing::ac_plugin::ac_plugin(symbol const & fname, ast_manager & m, maximise_ac_sharing & owner): - simplifier_plugin(fname, m), - m_owner(owner) { -} - -void maximise_ac_sharing::ac_plugin::register_kind(decl_kind k) { - m_kinds.push_back(k); -} - -maximise_ac_sharing::ac_plugin::~ac_plugin() { -} - -bool maximise_ac_sharing::ac_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - decl_kind k = f->get_kind(); - if (!f->is_associative()) - return false; - if (num_args <= 2) - return false; - if (std::find(m_kinds.begin(), m_kinds.end(), k) == m_kinds.end()) - return false; - ptr_buffer _args; - expr * numeral = 0; - if (m_owner.is_numeral(args[0])) { - numeral = args[0]; - for (unsigned i = 1; i < num_args; i++) - _args.push_back(args[i]); - num_args--; - } - else { - _args.append(num_args, args); - } - - TRACE("ac_sharing_detail", tout << "before-reuse: num_args: " << num_args << "\n";); - -#define MAX_NUM_ARGS_FOR_OPT 128 - - // Try to reuse already created circuits. - TRACE("ac_sharing_detail", tout << "args: "; for (unsigned i = 0; i < num_args; i++) tout << mk_pp(_args[i], m_manager) << "\n";); - try_to_reuse: - if (num_args > 1 && num_args < MAX_NUM_ARGS_FOR_OPT) { - for (unsigned i = 0; i < num_args - 1; i++) { - for (unsigned j = i + 1; j < num_args; j++) { - if (m_owner.contains(f, _args[i], _args[j])) { - TRACE("ac_sharing_detail", tout << "reusing args: " << i << " " << j << "\n";); - _args[i] = m_manager.mk_app(f, _args[i], _args[j]); - SASSERT(num_args > 1); - for (unsigned w = j; w < num_args - 1; w++) { - _args[w] = _args[w+1]; - } - num_args--; - goto try_to_reuse; - } - } - } - } - - - // Create "tree-like circuit" - while (true) { - TRACE("ac_sharing_detail", tout << "tree-loop: num_args: " << num_args << "\n";); - unsigned j = 0; - for (unsigned i = 0; i < num_args; i += 2, j++) { - if (i == num_args - 1) { - _args[j] = _args[i]; - } - else { - m_owner.insert(f, _args[i], _args[i+1]); - _args[j] = m_manager.mk_app(f, _args[i], _args[i+1]); - } - } - num_args = j; - if (num_args == 1) { - if (numeral == 0) { - result = _args[0]; - } - else { - result = m_manager.mk_app(f, numeral, _args[0]); - } - TRACE("ac_sharing_detail", tout << "result: " << mk_pp(result, m_manager) << "\n";); - return true; - } - } - - UNREACHABLE(); - return false; -} - -bool maximise_ac_sharing::contains(func_decl * f, expr * arg1, expr * arg2) { - entry e(f, arg1, arg2); - return m_cache.contains(&e); -} - -void maximise_ac_sharing::insert(func_decl * f, expr * arg1, expr * arg2) { - entry * e = new (m_region) entry(f, arg1, arg2); - m_entries.push_back(e); - m_cache.insert(e); - m_manager.inc_ref(arg1); - m_manager.inc_ref(arg2); -} - -maximise_ac_sharing::maximise_ac_sharing(ast_manager & m): - m_manager(m), - m_simplifier(m), - m_init(false) { - basic_simplifier_plugin* basic_simp = alloc(basic_simplifier_plugin,m); - m_simplifier.register_plugin(basic_simp); -} - -maximise_ac_sharing::~maximise_ac_sharing() { - restore_entries(0); -} - -void maximise_ac_sharing::operator()(expr * s, expr_ref & r, proof_ref & p) { - init(); - m_simplifier.operator()(s, r, p); -} - -void maximise_ac_sharing::push_scope() { - init(); - m_scopes.push_back(m_entries.size()); - m_region.push_scope(); -} - -void maximise_ac_sharing::pop_scope(unsigned num_scopes) { - SASSERT(num_scopes <= m_scopes.size()); - unsigned new_lvl = m_scopes.size() - num_scopes; - unsigned old_lim = m_scopes[new_lvl]; - restore_entries(old_lim); - m_region.pop_scope(num_scopes); - m_scopes.shrink(new_lvl); -} - -void maximise_ac_sharing::restore_entries(unsigned old_lim) { - unsigned i = m_entries.size(); - while (i != old_lim) { - --i; - entry * e = m_entries[i]; - m_manager.dec_ref(e->m_arg1); - m_manager.dec_ref(e->m_arg2); - } - m_entries.shrink(old_lim); -} - -void maximise_ac_sharing::reset() { - restore_entries(0); - m_entries.reset(); - m_cache.reset(); - m_simplifier.reset(); - m_region.reset(); - m_scopes.reset(); -} - -void maximise_bv_sharing::init_core() { - maximise_ac_sharing::ac_plugin * p = alloc(maximise_ac_sharing::ac_plugin, symbol("bv"), get_manager(), *this); - p->register_kind(OP_BADD); - p->register_kind(OP_BMUL); - p->register_kind(OP_BOR); - p->register_kind(OP_BAND); - register_plugin(p); -} - -bool maximise_bv_sharing::is_numeral(expr * n) const { - return m_util.is_numeral(n); -} - -maximise_bv_sharing::maximise_bv_sharing(ast_manager & m): - maximise_ac_sharing(m), - m_util(m) { -} diff --git a/src/ast/simplifier/maximise_ac_sharing.h b/src/ast/simplifier/maximise_ac_sharing.h deleted file mode 100644 index cf488e20d..000000000 --- a/src/ast/simplifier/maximise_ac_sharing.h +++ /dev/null @@ -1,124 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - maximise_ac_sharing.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-10-22. - -Revision History: - ---*/ -#ifndef MAXIMISE_AC_SHARING_H_ -#define MAXIMISE_AC_SHARING_H_ - -#include "ast/simplifier/simplifier.h" -#include "util/hashtable.h" -#include "ast/bv_decl_plugin.h" -#include "util/region.h" - -/** - \brief Functor used to maximise the amount of shared terms in an expression. - The idea is to rewrite AC terms to maximise sharing. - Example: - - (f (bvadd a (bvadd b c)) (bvadd a (bvadd b d))) - - is rewritten to: - - (f (bvadd (bvadd a b) c) (bvadd (bvadd a b) d)) - - \warning This class uses an opportunistic heuristic to maximise sharing. - There is no guarantee that the optimal expression will be produced. -*/ -class maximise_ac_sharing { - - struct entry { - func_decl * m_decl; - expr * m_arg1; - expr * m_arg2; - - entry(func_decl * d = 0, expr * arg1 = 0, expr * arg2 = 0):m_decl(d), m_arg1(arg1), m_arg2(arg2) { - SASSERT((d == 0 && arg1 == 0 && arg2 == 0) || (d != 0 && arg1 != 0 && arg2 != 0)); - if (arg1->get_id() > arg2->get_id()) - std::swap(m_arg1, m_arg2); - } - - unsigned hash() const { - unsigned a = m_decl->get_id(); - unsigned b = m_arg1->get_id(); - unsigned c = m_arg2->get_id(); - mix(a,b,c); - return c; - } - - bool operator==(entry const & e) const { - return m_decl == e.m_decl && m_arg1 == e.m_arg1 && m_arg2 == e.m_arg2; - } - }; - - typedef ptr_hashtable, deref_eq > cache; - -protected: - class ac_plugin : public simplifier_plugin { - maximise_ac_sharing & m_owner; - svector m_kinds; //!< kinds to be processed - public: - ac_plugin(symbol const & fname, ast_manager & m, maximise_ac_sharing & owner); - void register_kind(decl_kind k); - virtual ~ac_plugin(); - virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); - }; - - friend class ac_plugin; - -private: - ast_manager & m_manager; - simplifier m_simplifier; - bool m_init; - region m_region; - cache m_cache; - ptr_vector m_entries; - unsigned_vector m_scopes; - - bool contains(func_decl * f, expr * arg1, expr * arg2); - void insert(func_decl * f, expr * arg1, expr * arg2); - void restore_entries(unsigned old_lim); - void init() { - if (!m_init) { - init_core(); - m_init = true; - } - } -protected: - virtual void init_core() = 0; - virtual bool is_numeral(expr * n) const = 0; - void register_plugin(ac_plugin * p) { m_simplifier.register_plugin(p); } -public: - maximise_ac_sharing(ast_manager & m); - virtual ~maximise_ac_sharing(); - void operator()(expr * s, expr_ref & r, proof_ref & p); - void push_scope(); - void pop_scope(unsigned num_scopes); - void reset(); - ast_manager & get_manager() { return m_manager; } -}; - -class maximise_bv_sharing : public maximise_ac_sharing { - bv_util m_util; -protected: - virtual void init_core(); - virtual bool is_numeral(expr * n) const; -public: - maximise_bv_sharing(ast_manager & m); -}; - -#endif /* MAXIMISE_AC_SHARING_H_ */ - diff --git a/src/smt/params/CMakeLists.txt b/src/smt/params/CMakeLists.txt index 500423dcc..c965f0a62 100644 --- a/src/smt/params/CMakeLists.txt +++ b/src/smt/params/CMakeLists.txt @@ -13,7 +13,6 @@ z3_add_component(smt_params ast bit_blaster pattern - simplifier PYG_FILES smt_params_helper.pyg ) diff --git a/src/smt/params/preprocessor_params.cpp b/src/smt/params/preprocessor_params.cpp index afca0196a..93ea794fa 100644 --- a/src/smt/params/preprocessor_params.cpp +++ b/src/smt/params/preprocessor_params.cpp @@ -30,8 +30,6 @@ void preprocessor_params::updt_local_params(params_ref const & _p) { void preprocessor_params::updt_params(params_ref const & p) { pattern_inference_params::updt_params(p); - bv_simplifier_params::updt_params(p); - arith_simplifier_params::updt_params(p); updt_local_params(p); } @@ -40,8 +38,6 @@ void preprocessor_params::updt_params(params_ref const & p) { void preprocessor_params::display(std::ostream & out) const { pattern_inference_params::display(out); bit_blaster_params::display(out); - bv_simplifier_params::display(out); - arith_simplifier_params::display(out); DISPLAY_PARAM(m_lift_ite); DISPLAY_PARAM(m_ng_lift_ite); diff --git a/src/smt/params/preprocessor_params.h b/src/smt/params/preprocessor_params.h index 6f763c0e1..dc16d6244 100644 --- a/src/smt/params/preprocessor_params.h +++ b/src/smt/params/preprocessor_params.h @@ -21,8 +21,6 @@ Revision History: #include "ast/pattern/pattern_inference_params.h" #include "ast/rewriter/bit_blaster/bit_blaster_params.h" -#include "ast/simplifier/bv_simplifier_params.h" -#include "ast/simplifier/arith_simplifier_params.h" enum lift_ite_kind { LI_NONE, @@ -31,9 +29,7 @@ enum lift_ite_kind { }; struct preprocessor_params : public pattern_inference_params, - public bit_blaster_params, - public bv_simplifier_params, - public arith_simplifier_params { + public bit_blaster_params { lift_ite_kind m_lift_ite; lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms bool m_pull_cheap_ite_trees; diff --git a/src/smt/params/theory_arith_params.cpp b/src/smt/params/theory_arith_params.cpp index 2b5a14493..ab80f0c67 100644 --- a/src/smt/params/theory_arith_params.cpp +++ b/src/smt/params/theory_arith_params.cpp @@ -42,6 +42,8 @@ void theory_arith_params::updt_params(params_ref const & _p) { #define DISPLAY_PARAM(X) out << #X"=" << X << std::endl; void theory_arith_params::display(std::ostream & out) const { + DISPLAY_PARAM(m_arith_expand_eqs); + DISPLAY_PARAM(m_arith_process_all_eqs); DISPLAY_PARAM(m_arith_mode); DISPLAY_PARAM(m_arith_auto_config_simplex); //!< force simplex solver in auto_config DISPLAY_PARAM(m_arith_blands_rule_threshold); diff --git a/src/smt/params/theory_arith_params.h b/src/smt/params/theory_arith_params.h index d73a67985..89c4fe46c 100644 --- a/src/smt/params/theory_arith_params.h +++ b/src/smt/params/theory_arith_params.h @@ -49,6 +49,8 @@ enum arith_pivot_strategy { }; struct theory_arith_params { + bool m_arith_expand_eqs; + bool m_arith_process_all_eqs; arith_solver_id m_arith_mode; bool m_arith_auto_config_simplex; //!< force simplex solver in auto_config unsigned m_arith_blands_rule_threshold; @@ -108,6 +110,8 @@ struct theory_arith_params { theory_arith_params(params_ref const & p = params_ref()): + m_arith_expand_eqs(false), + m_arith_process_all_eqs(false), m_arith_mode(AS_ARITH), m_arith_auto_config_simplex(false), m_arith_blands_rule_threshold(1000), diff --git a/src/smt/params/theory_array_params.h b/src/smt/params/theory_array_params.h index af3fdebeb..edda4d7cf 100644 --- a/src/smt/params/theory_array_params.h +++ b/src/smt/params/theory_array_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef THEORY_ARRAY_PARAMS_H_ #define THEORY_ARRAY_PARAMS_H_ -#include "ast/simplifier/array_simplifier_params.h" +#include "util/params.h" enum array_solver_id { AR_NO_ARRAY, @@ -28,7 +28,9 @@ enum array_solver_id { AR_FULL }; -struct theory_array_params : public array_simplifier_params { +struct theory_array_params { + bool m_array_canonize_simplify; + bool m_array_simplify; // temporary hack for disabling array simplifier plugin. array_solver_id m_array_mode; bool m_array_weak; bool m_array_extensional; @@ -40,6 +42,8 @@ struct theory_array_params : public array_simplifier_params { unsigned m_array_lazy_ieq_delay; theory_array_params(): + m_array_canonize_simplify(false), + m_array_simplify(true), m_array_mode(AR_FULL), m_array_weak(false), m_array_extensional(true), diff --git a/src/smt/params/theory_bv_params.cpp b/src/smt/params/theory_bv_params.cpp index 4b4808a1f..156fda592 100644 --- a/src/smt/params/theory_bv_params.cpp +++ b/src/smt/params/theory_bv_params.cpp @@ -18,9 +18,12 @@ Revision History: --*/ #include "smt/params/theory_bv_params.h" #include "smt/params/smt_params_helper.hpp" +#include "ast/rewriter/bv_rewriter_params.hpp" void theory_bv_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); + bv_rewriter_params rp(_p); + m_hi_div0 = rp.hi_div0(); m_bv_reflect = p.bv_reflect(); m_bv_enable_int2bv2int = p.bv_enable_int2bv(); } @@ -29,9 +32,10 @@ void theory_bv_params::updt_params(params_ref const & _p) { void theory_bv_params::display(std::ostream & out) const { DISPLAY_PARAM(m_bv_mode); + DISPLAY_PARAM(m_hi_div0); DISPLAY_PARAM(m_bv_reflect); DISPLAY_PARAM(m_bv_lazy_le); DISPLAY_PARAM(m_bv_cc); DISPLAY_PARAM(m_bv_blast_max_size); DISPLAY_PARAM(m_bv_enable_int2bv2int); -} \ No newline at end of file +} diff --git a/src/smt/params/theory_bv_params.h b/src/smt/params/theory_bv_params.h index 52aaa4c9c..e0bff3f17 100644 --- a/src/smt/params/theory_bv_params.h +++ b/src/smt/params/theory_bv_params.h @@ -28,6 +28,7 @@ enum bv_solver_id { struct theory_bv_params { bv_solver_id m_bv_mode; + bool m_hi_div0; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted. bool m_bv_reflect; bool m_bv_lazy_le; bool m_bv_cc; @@ -35,6 +36,7 @@ struct theory_bv_params { bool m_bv_enable_int2bv2int; theory_bv_params(params_ref const & p = params_ref()): m_bv_mode(BS_BLASTER), + m_hi_div0(false), m_bv_reflect(true), m_bv_lazy_le(false), m_bv_cc(false), From feac705cb88bb00085e8c4313dbdc23befc7aa0c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 13:47:19 -0700 Subject: [PATCH 224/488] include epsilon closure in initial state set, streamline final configuration computation #1224 Signed-off-by: Nikolaj Bjorner --- src/math/automata/symbolic_automata_def.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/math/automata/symbolic_automata_def.h b/src/math/automata/symbolic_automata_def.h index aa8dd34fd..c89080d3d 100644 --- a/src/math/automata/symbolic_automata_def.h +++ b/src/math/automata/symbolic_automata_def.h @@ -298,21 +298,16 @@ symbolic_automata::mk_determinstic_param(automaton_t& a, bool flip_accepta unsigned p_state_id = 0; // next state identifier TRACE("seq", tout << "mk-deterministic " << flip_acceptance << " " << set << " " << a.is_final_configuration(set) << "\n";); - // adds non-final states of a to final if flipping and and final otherwise + // adds non-final states of a to final if flipping and final otherwise unsigned_vector init_states; - a.get_epsilon_closure(a.init(), init_states); - bool found_final = false; + a.get_epsilon_closure(a.init(), init_states); for (unsigned s : init_states) { - if (a.is_final_state(s)) { - found_final = true; - break; - } + set.insert(s); } - if (found_final != flip_acceptance) { + if (a.is_final_configuration(set) != flip_acceptance) { new_final_states.push_back(p_state_id); } - set.insert(a.init()); // Initial state as aset s2id.insert(set, p_state_id++); // the index to the initial state is 0 id2s.push_back(set); From 597f77cd7766a439d64cff22cc8f1950d00eb450 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 20:03:31 -0700 Subject: [PATCH 225/488] initial sketch for dominator based simplifiation Signed-off-by: Nikolaj Bjorner --- scripts/mk_project.py | 15 +- src/tactic/core/dom_simplify_tactic.cpp | 348 ++++++++++++++++++++++++ 2 files changed, 354 insertions(+), 9 deletions(-) create mode 100644 src/tactic/core/dom_simplify_tactic.cpp diff --git a/scripts/mk_project.py b/scripts/mk_project.py index 64dd93faa..923b948a6 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -23,10 +23,7 @@ def init_project_def(): add_lib('subpaving', ['interval'], 'math/subpaving') add_lib('ast', ['util', 'polynomial']) add_lib('rewriter', ['ast', 'polynomial', 'automata'], 'ast/rewriter') - # Simplifier module will be deleted in the future. - # It has been replaced with rewriter module. - add_lib('simplifier', ['rewriter'], 'ast/simplifier') - add_lib('macros', ['simplifier'], 'ast/macros') + add_lib('macros', ['rewriter'], 'ast/macros') add_lib('normal_forms', ['rewriter'], 'ast/normal_forms') add_lib('model', ['rewriter']) add_lib('tactic', ['ast', 'model']) @@ -47,11 +44,11 @@ def init_project_def(): add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds') add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') add_lib('proof_checker', ['rewriter'], 'ast/proof_checker') - add_lib('fpa', ['ast', 'util', 'simplifier', 'model'], 'ast/fpa') - add_lib('pattern', ['normal_forms', 'smt2parser', 'simplifier'], 'ast/pattern') - add_lib('bit_blaster', ['rewriter', 'simplifier'], 'ast/rewriter/bit_blaster') - add_lib('smt_params', ['ast', 'simplifier', 'pattern', 'bit_blaster'], 'smt/params') - add_lib('proto_model', ['model', 'simplifier', 'smt_params'], 'smt/proto_model') + add_lib('fpa', ['ast', 'util', 'rewriter', 'model'], 'ast/fpa') + add_lib('pattern', ['normal_forms', 'smt2parser', 'rewriter'], 'ast/pattern') + add_lib('bit_blaster', ['rewriter', 'rewriter'], 'ast/rewriter/bit_blaster') + add_lib('smt_params', ['ast', 'rewriter', 'pattern', 'bit_blaster'], 'smt/params') + add_lib('proto_model', ['model', 'rewriter', 'smt_params'], 'smt/proto_model') add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', 'proto_model', 'substitution', 'grobner', 'euclid', 'simplex', 'proof_checker', 'pattern', 'parser_util', 'fpa', 'lp']) add_lib('bv_tactics', ['tactic', 'bit_blaster', 'core_tactics'], 'tactic/bv') diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp new file mode 100644 index 000000000..b4c0b6d82 --- /dev/null +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -0,0 +1,348 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + dom_simplify_tactic.cpp + +Abstract: + + Dominator-based context simplifer. + +Author: + + Nikolaj and Nuno + +Notes: + +--*/ + +#if 0 + +#include "ast/ast.h" + +class expr_dominators { +public: + typedef obj_map> tree_t; +private: + ast_manager& m; + expr_ref m_root; + obj_map m_expr2post; // reverse post-order number + ptr_vector m_post2expr; + tree_t m_parents; + obj_map m_doms; + tree_t m_tree; + + void add_edge(tree_t& tree, expr * src, expr* dst) { + tree.insert_if_not_there(src, ptr_vector()).push_back(dst); + } + + /** + \brief compute a post-order traversal for e. + Also populate the set of parents + */ + void compute_post_order() { + unsigned post_num = 0; + SASSERT(m_post2expr.empty()); + SASSERT(m_expr2post.empty()); + ast_mark mark; + ptr_vector todo; + todo.push_back(m_root); + while (!todo.empty()) { + expr* e = todo.back(); + if (is_marked(e)) { + todo.pop_back(); + continue; + } + if (is_app(e)) { + app* a = to_app(e); + bool done = true; + for (expr* arg : *a) { + if (!is_marked(arg)) { + todo.push_back(arg); + done = false; + } + } + if (done) { + mark.mark(e); + m_expr2post.insert(e, post_num++); + m_post2expr.push_back(e); + todo.pop_back(); + for (expr* arg : *a) { + add_edge(m_parents, a, arg); + } + } + } + else { + todo.pop_back(); + } + } + } + + expr* intersect(expr* x, expr * y) { + unsigned n1 = m_expr2post[x]; + unsigned n2 = m_expr2post[y]; + while (n1 != n2) { + if (n1 < n2) + n1 = m_doms[n1]; + else if (n1 > n2) + n2 = m_doms[n2]; + } + return n1; + } + + void compute_dominators() { + expr * e = m_root; + SASSERT(m_doms.empty()); + m_doms.insert(e, e); + bool change = true; + while (change) { + change = false; + SASSERT(m_post2expr.back() == e); + for (unsigned i = 0; i < m_post2expr.size() - 1; ++i) { + expr * child = m_post2expr[i]; + ptr_vector const& p = m_parents[child]; + SASSERT(!p.empty()); + expr * new_idom = p[0], * idom2 = 0; + for (unsigned j = 1; j < p.size(); ++j) { + if (m_doms.find(p[j], idom2)) { + new_idom = intersect(new_idom, idom2); + } + } + if (!m_doms.find(child, idom2) || idom2 != new_idom) { + m_doms.insert(child, new_idom); + } + } + } + } + + void extract_tree() { + for (auto const& kv : m_doms) { + expr * child = kv.m_key; + for (expr * parent : kv.m_value) { + add_edge(m_tree, parent, child); + } + } + } + + void reset() { + m_expr2post.reset(); + m_post2expr.reset(); + m_parents.reset(); + m_doms.reset(); + m_tree.reset(); + m_root.reset(); + } + + +public: + expr_dominators(ast_manager& m): m(m), m_root(m) {} + + void compile(expr * e) { + reset(); + m_root = e; + compute_post_order(); + compute_dominators(); + extract_tree(); + } + + void compile(unsigned sz, expr * const* es) { + expr_ref e(m.mk_and(sz, es), m); + compile(e); + } + + tree_t const& get_tree() { return m_tree; } + +}; + +// goes to header file: + +class dom_simplify_tactic : public tactic { +public: + class simplifier { + public: + virtual ~simplifier() {} + /** + \brief assert_expr performs an implicit push + */ + virtual bool assert_expr(expr * t, bool sign) = 0; + + /** + \brief apply simplification. + */ + virtual void operator()(expr_ref& r) = 0; + + /** + \brief pop scopes accumulated from assertions. + */ + virtual void pop(unsigned num_scopes) = 0; + }; +private: + simplifier& m_simplifier; + params_ref m_params; + expr_ref_vector m_trail; + obj_map m_result; + expr_dominators m_dominators; + + expr_ref simplify(expr* t); + expr_ref simplify_ite(app * ite); + expr_ref simplify_and(app * ite) { return simplify_and_or(true, ite); } + expr_ref simplify_or(app * ite) { return simplify_and_or(false, ite); } + expr_ref simplify_and_or(bool is_and app * ite); + + expr_ref get_cache(expr* t) { if (!m_result.find(r, r)) r = t; return expr_ref(r, m); } + void cache(expr *t, expr* r) { m_result.insert(t, r); m_trail.push_back(r); } + + void simplify_goal(goal_ref& g); + +public: + dom_simplify_tactic(ast_manager & m, simplifier& s, params_ref const & p = params_ref()); + + virtual tactic * translate(ast_manager & m); + + virtual ~dom_simplify_tactic(); + + virtual void updt_params(params_ref const & p); + static void get_param_descrs(param_descrs & r); + virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); } + + virtual void operator()(goal_ref const & in, + goal_ref_buffer & result, + model_converter_ref & mc, + proof_converter_ref & pc, + expr_dependency_ref & core); + + virtual void cleanup(); +}; + +// implementation: + +expr_ref dom_simplifier_tactic::simplify_ite(app * ite) { + expr_ref r(m); + expr * c = 0, * t = 0, * e = 0; + VERIFY(m.is_ite(ite, c, t, e)); + unsigned old_lvl = scope_level(); + expr_ref new_c = simplify(c); + if (m.is_true(new_c)) { + r = simplify(t); + } + else if (m.is_false(new_c) || !assert_expr(new_c, false)) { + r = simplify(e); + } + else { + expr_ref t = simplify(t); + pop(scope_level() - old_lvl); + if (!assert_expr(new_c, true)) { + return new_t; + } + expr_ref new_e = simplify(e); + pop(scope_level() - old_lvl); + if (c == new_c && t == new_t && e == new_e) { + r = ite; + } + else if (new_t == new_e) { + r = new_t; + } + else { + TRACE("tactic", tout << new_c << "\n" << new_t << "\n" << new_e << "\n";); + r = m.mk_ite(new_c, new_t, new_c); + } + } + return r; +} + +expr_ref dom_simplifier_tactic::simplify(expr * e0) { + expr_ref r(m); + expr* e = 0; + if (!m_result.find(e0, e)) { + e = e0; + } + + if (m.is_ite(e)) { + r = simplify_ite(to_app(e)); + } + else if (m.is_and(e)) { + r = simplify_and(to_app(e)); + } + else if (m.is_or(e)) { + r = simplify_or(to_app(e)); + } + else { + tree_t const& t = m_dominators.get_tree(); + if (t.contains(e)) { + ptr_vector const& children = t[e]; + for (expr * child : children) { + simplify(child); + } + } + if (is_app(e)) { + m_args.reset(); + for (expr* arg : *to_app(e)) { + m_args.push_back(get_cached(arg)); + } + r = m.mk_app(to_app(e)->get_decl(), m_args.size(), m_args.c_ptr()); + } + else { + r = e; + } + } + m_simplifier(r); + cache(e0, r); + return r; +} + +expr_ref dom_simplifier_tactic::simplify_or_and(bool is_and, app * e) { + expr_ref r(m); + unsigned old_lvl = scope_level(); + m_args.reset(); + for (expr * arg : *e) { + r = simplify(arg); + if (!assert_expr(r, is_and)) { + r = is_and ? m.mk_false() : m.mk_true(); + } + m_args.push_back(r); + } + pop(scope_level() - old_lvl); + m_args.reverse(); + m_args2.reset(); + for (expr * arg : m_args) { + r = simplify(arg); + if (!assert_expr(r, is_and)) { + r = is_and ? m.mk_false() : m.mk_true(); + } + m_args2.push_back(r); + } + pop(scope_level() - old_lvl); + m_args2.reverse(); + r = is_and ? mk_and(m_args2) : mk_or(m_args2); + return r; +} + +void dom_simplifier_tactic::simplify_goal(goal& g) { + expr_ref_vector args(m); + expr_ref fml(m); + for (unsigned i = 0; i < sz; ++i) args.push_back(g.form(i)); + fml = mk_and(args); + expr_ref tmp(fml); + // TBD: deal with dependencies. + do { + m_result.reset(); + m_trail.reset(); + m_dominators.compile(fml); +#if 0 + for (unsigned i = 0; i < sz; ++i) { + r = simplify(g.form(i)); + // TBD: simplfy goal as a conjuction ? + // + } +#endif + tmp = fml; + fml = simplify(fml); + } + while (tmp != fml); + //g.reset(); + //g.add(fml); +} + + +#endif From 8d8e4cbc513dd7171fd3e1439f38d4bdeb214b63 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 28 Aug 2017 20:11:46 -0700 Subject: [PATCH 226/488] fix some basic mistakes in dominator code Signed-off-by: Nikolaj Bjorner --- src/tactic/core/dom_simplify_tactic.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index b4c0b6d82..3b444ef1a 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -69,7 +69,7 @@ private: m_post2expr.push_back(e); todo.pop_back(); for (expr* arg : *a) { - add_edge(m_parents, a, arg); + add_edge(m_parents, arg, a); } } } @@ -83,12 +83,17 @@ private: unsigned n1 = m_expr2post[x]; unsigned n2 = m_expr2post[y]; while (n1 != n2) { - if (n1 < n2) - n1 = m_doms[n1]; - else if (n1 > n2) - n2 = m_doms[n2]; + if (n1 < n2) { + x = m_doms[x]; + n1 = m_expr2post[x]; + } + else if (n1 > n2) { + y = m_doms[y]; + n2 = m_expr2post[y]; + } } - return n1; + SASSERT(x == y); + return x; } void compute_dominators() { @@ -111,6 +116,7 @@ private: } if (!m_doms.find(child, idom2) || idom2 != new_idom) { m_doms.insert(child, new_idom); + change = true; } } } @@ -118,10 +124,7 @@ private: void extract_tree() { for (auto const& kv : m_doms) { - expr * child = kv.m_key; - for (expr * parent : kv.m_value) { - add_edge(m_tree, parent, child); - } + add_edge(m_tree, kv.m_value, kv.m_key); } } From cf87b6d622d8cb71b4dff4a3cbd034dccbaddcbf Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 29 Aug 2017 09:22:27 -0700 Subject: [PATCH 227/488] remove simplifier files Signed-off-by: Nikolaj Bjorner --- src/ast/macros/macro_util.cpp | 2 - src/ast/simplifier/CMakeLists.txt | 22 - src/ast/simplifier/README | 2 - .../simplifier/arith_simplifier_params.cpp | 33 - src/ast/simplifier/arith_simplifier_params.h | 38 - .../arith_simplifier_params_helper.pyg | 7 - .../simplifier/arith_simplifier_plugin.cpp | 449 ---- src/ast/simplifier/arith_simplifier_plugin.h | 96 - .../simplifier/array_simplifier_params.cpp | 26 - src/ast/simplifier/array_simplifier_params.h | 34 - .../array_simplifier_params_helper.pyg | 6 - .../simplifier/array_simplifier_plugin.cpp | 877 ------- src/ast/simplifier/array_simplifier_plugin.h | 154 -- src/ast/simplifier/base_simplifier.h | 76 - .../simplifier/basic_simplifier_plugin.cpp | 147 -- src/ast/simplifier/basic_simplifier_plugin.h | 78 - src/ast/simplifier/bv_elim.cpp | 119 - src/ast/simplifier/bv_elim.h | 45 - src/ast/simplifier/bv_simplifier_params.cpp | 36 - src/ast/simplifier/bv_simplifier_params.h | 38 - .../bv_simplifier_params_helper.pyg | 4 - src/ast/simplifier/bv_simplifier_plugin.cpp | 2261 ----------------- src/ast/simplifier/bv_simplifier_plugin.h | 187 -- .../simplifier/datatype_simplifier_plugin.cpp | 115 - .../simplifier/datatype_simplifier_plugin.h | 42 - src/ast/simplifier/elim_bounds.cpp | 224 -- src/ast/simplifier/elim_bounds.h | 69 - src/ast/simplifier/fpa_simplifier_plugin.cpp | 39 - src/ast/simplifier/fpa_simplifier_plugin.h | 39 - src/ast/simplifier/poly_simplifier_plugin.cpp | 835 ------ src/ast/simplifier/poly_simplifier_plugin.h | 155 -- src/ast/simplifier/seq_simplifier_plugin.cpp | 39 - src/ast/simplifier/seq_simplifier_plugin.h | 39 - src/ast/simplifier/simplifier.cpp | 962 ------- src/ast/simplifier/simplifier.h | 232 -- src/ast/simplifier/simplifier_plugin.cpp | 46 - src/ast/simplifier/simplifier_plugin.h | 94 - src/muz/pdr/pdr_util.cpp | 27 +- src/muz/rel/dl_bound_relation.h | 1 - src/muz/rel/dl_interval_relation.h | 5 +- src/muz/spacer/spacer_legacy_mbp.cpp | 3 - src/smt/arith_eq_adapter.h | 1 - src/smt/theory_arith.h | 1 - src/smt/theory_arith_int.h | 7 +- 44 files changed, 17 insertions(+), 7695 deletions(-) delete mode 100644 src/ast/simplifier/CMakeLists.txt delete mode 100644 src/ast/simplifier/README delete mode 100644 src/ast/simplifier/arith_simplifier_params.cpp delete mode 100644 src/ast/simplifier/arith_simplifier_params.h delete mode 100644 src/ast/simplifier/arith_simplifier_params_helper.pyg delete mode 100644 src/ast/simplifier/arith_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/arith_simplifier_plugin.h delete mode 100644 src/ast/simplifier/array_simplifier_params.cpp delete mode 100644 src/ast/simplifier/array_simplifier_params.h delete mode 100644 src/ast/simplifier/array_simplifier_params_helper.pyg delete mode 100644 src/ast/simplifier/array_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/array_simplifier_plugin.h delete mode 100644 src/ast/simplifier/base_simplifier.h delete mode 100644 src/ast/simplifier/basic_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/basic_simplifier_plugin.h delete mode 100644 src/ast/simplifier/bv_elim.cpp delete mode 100644 src/ast/simplifier/bv_elim.h delete mode 100644 src/ast/simplifier/bv_simplifier_params.cpp delete mode 100644 src/ast/simplifier/bv_simplifier_params.h delete mode 100644 src/ast/simplifier/bv_simplifier_params_helper.pyg delete mode 100644 src/ast/simplifier/bv_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/bv_simplifier_plugin.h delete mode 100644 src/ast/simplifier/datatype_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/datatype_simplifier_plugin.h delete mode 100644 src/ast/simplifier/elim_bounds.cpp delete mode 100644 src/ast/simplifier/elim_bounds.h delete mode 100644 src/ast/simplifier/fpa_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/fpa_simplifier_plugin.h delete mode 100644 src/ast/simplifier/poly_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/poly_simplifier_plugin.h delete mode 100644 src/ast/simplifier/seq_simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/seq_simplifier_plugin.h delete mode 100644 src/ast/simplifier/simplifier.cpp delete mode 100644 src/ast/simplifier/simplifier.h delete mode 100644 src/ast/simplifier/simplifier_plugin.cpp delete mode 100644 src/ast/simplifier/simplifier_plugin.h diff --git a/src/ast/macros/macro_util.cpp b/src/ast/macros/macro_util.cpp index 6bc1ee66e..55c5436e4 100644 --- a/src/ast/macros/macro_util.cpp +++ b/src/ast/macros/macro_util.cpp @@ -20,8 +20,6 @@ Revision History: #include "ast/macros/macro_util.h" #include "ast/occurs.h" #include "ast/ast_util.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/rewriter/var_subst.h" #include "ast/ast_pp.h" #include "ast/ast_ll_pp.h" diff --git a/src/ast/simplifier/CMakeLists.txt b/src/ast/simplifier/CMakeLists.txt deleted file mode 100644 index 37d96b1a5..000000000 --- a/src/ast/simplifier/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -z3_add_component(simplifier - SOURCES - arith_simplifier_params.cpp -# arith_simplifier_plugin.cpp -# array_simplifier_params.cpp -# array_simplifier_plugin.cpp -# basic_simplifier_plugin.cpp -# bv_elim.cpp -# bv_simplifier_params.cpp -# bv_simplifier_plugin.cpp -# datatype_simplifier_plugin.cpp -# elim_bounds.cpp -# fpa_simplifier_plugin.cpp -# maximise_ac_sharing.cpp -# poly_simplifier_plugin.cpp -# seq_simplifier_plugin.cpp -# simplifier.cpp -# simplifier_plugin.cpp - COMPONENT_DEPENDENCIES - rewriter - -) diff --git a/src/ast/simplifier/README b/src/ast/simplifier/README deleted file mode 100644 index 4725d9de9..000000000 --- a/src/ast/simplifier/README +++ /dev/null @@ -1,2 +0,0 @@ -Simplifier module is now obsolete. -It is still being used in many places, but we will eventually replace all occurrences with the new rewriter module. diff --git a/src/ast/simplifier/arith_simplifier_params.cpp b/src/ast/simplifier/arith_simplifier_params.cpp deleted file mode 100644 index 73bbbaa1a..000000000 --- a/src/ast/simplifier/arith_simplifier_params.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - arith_simplifier_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2012-12-02. - -Revision History: - ---*/ -#include "ast/simplifier/arith_simplifier_params.h" -#include "ast/simplifier/arith_simplifier_params_helper.hpp" - -void arith_simplifier_params::updt_params(params_ref const & _p) { - arith_simplifier_params_helper p(_p); - m_arith_expand_eqs = p.arith_expand_eqs(); - m_arith_process_all_eqs = p.arith_process_all_eqs(); -} - -#define DISPLAY_PARAM(X) out << #X"=" << X << std::endl; - -void arith_simplifier_params::display(std::ostream & out) const { - DISPLAY_PARAM(m_arith_expand_eqs); - DISPLAY_PARAM(m_arith_process_all_eqs); -} \ No newline at end of file diff --git a/src/ast/simplifier/arith_simplifier_params.h b/src/ast/simplifier/arith_simplifier_params.h deleted file mode 100644 index 8a4150099..000000000 --- a/src/ast/simplifier/arith_simplifier_params.h +++ /dev/null @@ -1,38 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - arith_simplifier_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-05-09. - -Revision History: - ---*/ -#ifndef ARITH_SIMPLIFIER_PARAMS_H_ -#define ARITH_SIMPLIFIER_PARAMS_H_ - -#include "util/params.h" - -struct arith_simplifier_params { - bool m_arith_expand_eqs; - bool m_arith_process_all_eqs; - - arith_simplifier_params(params_ref const & p = params_ref()) { - updt_params(p); - } - - void updt_params(params_ref const & _p); - - void display(std::ostream & out) const; -}; - -#endif /* ARITH_SIMPLIFIER_PARAMS_H_ */ - diff --git a/src/ast/simplifier/arith_simplifier_params_helper.pyg b/src/ast/simplifier/arith_simplifier_params_helper.pyg deleted file mode 100644 index 49a7cf3d2..000000000 --- a/src/ast/simplifier/arith_simplifier_params_helper.pyg +++ /dev/null @@ -1,7 +0,0 @@ -def_module_params(class_name='arith_simplifier_params_helper', - module_name="old_simplify", # Parameters will be in the old_simplify module - description="old simplification (stack) still used in the smt module", - export=True, - params=( - ('arith.expand_eqs', BOOL, False, 'expand equalities into two inequalities'), - ('arith.process_all_eqs', BOOL, False, 'put all equations in the form (= t c), where c is a numeral'))) diff --git a/src/ast/simplifier/arith_simplifier_plugin.cpp b/src/ast/simplifier/arith_simplifier_plugin.cpp deleted file mode 100644 index bfe72b232..000000000 --- a/src/ast/simplifier/arith_simplifier_plugin.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - arith_simplifier_plugin.cpp - -Abstract: - - Simplifier for the arithmetic family. - -Author: - - Leonardo (leonardo) 2008-01-08 - ---*/ -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/ast_pp.h" -#include "ast/ast_ll_pp.h" -#include "ast/ast_smt2_pp.h" - -arith_simplifier_plugin::~arith_simplifier_plugin() { -} - -arith_simplifier_plugin::arith_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b, arith_simplifier_params & p): - poly_simplifier_plugin(symbol("arith"), m, OP_ADD, OP_MUL, OP_UMINUS, OP_SUB, OP_NUM), - m_params(p), - m_util(m), - m_bsimp(b), - m_int_zero(m), - m_real_zero(m) { - m_int_zero = m_util.mk_numeral(rational(0), true); - m_real_zero = m_util.mk_numeral(rational(0), false); -} - -/** - \brief Return true if the first monomial of t is negative. -*/ -bool arith_simplifier_plugin::is_neg_poly(expr * t) const { - if (m_util.is_add(t)) { - t = to_app(t)->get_arg(0); - } - if (m_util.is_mul(t)) { - t = to_app(t)->get_arg(0); - rational r; - if (is_numeral(t, r)) - return r.is_neg(); - } - return false; -} - -void arith_simplifier_plugin::get_monomial_gcd(expr_ref_vector& monomials, numeral& g) { - g = numeral::zero(); - numeral n; - for (unsigned i = 0; !g.is_one() && i < monomials.size(); ++i) { - expr* e = monomials[i].get(); - if (is_numeral(e, n)) { - g = gcd(abs(n), g); - } - else if (is_mul(e) && is_numeral(to_app(e)->get_arg(0), n)) { - g = gcd(abs(n), g); - } - else { - g = numeral::one(); - return; - } - } - if (g.is_zero()) { - g = numeral::one(); - } -} - -void arith_simplifier_plugin::div_monomial(expr_ref_vector& monomials, numeral const& g) { - numeral n; - for (unsigned i = 0; i < monomials.size(); ++i) { - expr* e = monomials[i].get(); - if (is_numeral(e, n)) { - SASSERT((n/g).is_int()); - monomials[i] = mk_numeral(n/g); - } - else if (is_mul(e) && is_numeral(to_app(e)->get_arg(0), n)) { - SASSERT((n/g).is_int()); - monomials[i] = mk_mul(n/g, to_app(e)->get_arg(1)); - } - else { - UNREACHABLE(); - } - } -} - -void arith_simplifier_plugin::gcd_reduce_monomial(expr_ref_vector& monomials, numeral& k) { - numeral g, n; - - get_monomial_gcd(monomials, g); - g = gcd(abs(k), g); - - if (g.is_one()) { - return; - } - SASSERT(g.is_pos()); - - k = k / g; - div_monomial(monomials, g); - -} - -template -void arith_simplifier_plugin::mk_le_ge_eq_core(expr * arg1, expr * arg2, expr_ref & result) { - set_curr_sort(arg1); - bool is_int = m_curr_sort->get_decl_kind() == INT_SORT; - expr_ref_vector monomials(m_manager); - rational k; - TRACE("arith_eq_bug", tout << mk_ismt2_pp(arg1, m_manager) << "\n" << mk_ismt2_pp(arg2, m_manager) << "\n";); - process_sum_of_monomials(false, arg1, monomials, k); - process_sum_of_monomials(true, arg2, monomials, k); - k.neg(); - if (is_int) { - numeral g; - get_monomial_gcd(monomials, g); - if (!g.is_one()) { - div_monomial(monomials, g); - switch(Kind) { - case LE: - // - // g*monmials' <= k - // <=> - // monomials' <= floor(k/g) - // - k = floor(k/g); - break; - case GE: - // - // g*monmials' >= k - // <=> - // monomials' >= ceil(k/g) - // - k = ceil(k/g); - break; - case EQ: - k = k/g; - if (!k.is_int()) { - result = m_manager.mk_false(); - return; - } - break; - } - } - } - expr_ref lhs(m_manager); - mk_sum_of_monomials(monomials, lhs); - if (m_util.is_numeral(lhs)) { - SASSERT(lhs == mk_zero()); - if (( Kind == LE && numeral::zero() <= k) || - ( Kind == GE && numeral::zero() >= k) || - ( Kind == EQ && numeral::zero() == k)) - result = m_manager.mk_true(); - else - result = m_manager.mk_false(); - } - else { - - if (is_neg_poly(lhs)) { - expr_ref neg_lhs(m_manager); - mk_uminus(lhs, neg_lhs); - lhs = neg_lhs; - k.neg(); - expr * rhs = m_util.mk_numeral(k, is_int); - switch (Kind) { - case LE: - result = m_util.mk_ge(lhs, rhs); - break; - case GE: - result = m_util.mk_le(lhs, rhs); - break; - case EQ: - result = m_manager.mk_eq(lhs, rhs); - break; - } - } - else { - expr * rhs = m_util.mk_numeral(k, is_int); - switch (Kind) { - case LE: - result = m_util.mk_le(lhs, rhs); - break; - case GE: - result = m_util.mk_ge(lhs, rhs); - break; - case EQ: - result = m_manager.mk_eq(lhs, rhs); - break; - } - } - } -} - -void arith_simplifier_plugin::mk_arith_eq(expr * arg1, expr * arg2, expr_ref & result) { - mk_le_ge_eq_core(arg1, arg2, result); -} - -void arith_simplifier_plugin::mk_le(expr * arg1, expr * arg2, expr_ref & result) { - mk_le_ge_eq_core(arg1, arg2, result); -} - -void arith_simplifier_plugin::mk_ge(expr * arg1, expr * arg2, expr_ref & result) { - mk_le_ge_eq_core(arg1, arg2, result); -} - -void arith_simplifier_plugin::mk_lt(expr * arg1, expr * arg2, expr_ref & result) { - expr_ref tmp(m_manager); - mk_le(arg2, arg1, tmp); - m_bsimp.mk_not(tmp, result); -} - -void arith_simplifier_plugin::mk_gt(expr * arg1, expr * arg2, expr_ref & result) { - expr_ref tmp(m_manager); - mk_le(arg1, arg2, tmp); - m_bsimp.mk_not(tmp, result); -} - -void arith_simplifier_plugin::gcd_normalize(numeral & coeff, expr_ref& term) { - if (!abs(coeff).is_one()) { - set_curr_sort(term); - SASSERT(m_curr_sort->get_decl_kind() == INT_SORT); - expr_ref_vector monomials(m_manager); - rational k; - monomials.push_back(mk_numeral(numeral(coeff), true)); - process_sum_of_monomials(false, term, monomials, k); - gcd_reduce_monomial(monomials, k); - numeral coeff1; - if (!is_numeral(monomials[0].get(), coeff1)) { - UNREACHABLE(); - } - if (coeff1 == coeff) { - return; - } - monomials[0] = mk_numeral(k, true); - coeff = coeff1; - mk_sum_of_monomials(monomials, term); - } -} - - -void arith_simplifier_plugin::mk_div(expr * arg1, expr * arg2, expr_ref & result) { - set_curr_sort(arg1); - numeral v1, v2; - bool is_int; - if (m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero()) { - SASSERT(!is_int); - if (m_util.is_numeral(arg1, v1, is_int)) - result = m_util.mk_numeral(v1/v2, false); - else { - numeral k(1); - k /= v2; - - expr_ref inv_arg2(m_util.mk_numeral(k, false), m_manager); - mk_mul(inv_arg2, arg1, result); - } - } - else - result = m_util.mk_div(arg1, arg2); -} - -void arith_simplifier_plugin::mk_idiv(expr * arg1, expr * arg2, expr_ref & result) { - set_curr_sort(arg1); - numeral v1, v2; - bool is_int; - if (m_util.is_numeral(arg1, v1, is_int) && m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero()) - result = m_util.mk_numeral(div(v1, v2), is_int); - else - result = m_util.mk_idiv(arg1, arg2); -} - -void arith_simplifier_plugin::prop_mod_const(expr * e, unsigned depth, numeral const& k, expr_ref& result) { - SASSERT(m_util.is_int(e)); - SASSERT(k.is_int() && k.is_pos()); - numeral n; - bool is_int; - - if (depth == 0) { - result = e; - } - else if (is_add(e) || is_mul(e)) { - expr_ref_vector args(m_manager); - expr_ref tmp(m_manager); - app* a = to_app(e); - for (unsigned i = 0; i < a->get_num_args(); ++i) { - prop_mod_const(a->get_arg(i), depth - 1, k, tmp); - args.push_back(tmp); - } - reduce(a->get_decl(), args.size(), args.c_ptr(), result); - } - else if (m_util.is_numeral(e, n, is_int) && is_int) { - result = mk_numeral(mod(n, k), true); - } - else { - result = e; - } -} - -void arith_simplifier_plugin::mk_mod(expr * arg1, expr * arg2, expr_ref & result) { - set_curr_sort(arg1); - numeral v1, v2; - bool is_int; - if (m_util.is_numeral(arg1, v1, is_int) && m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero()) { - result = m_util.mk_numeral(mod(v1, v2), is_int); - } - else if (m_util.is_numeral(arg2, v2, is_int) && is_int && v2.is_one()) { - result = m_util.mk_numeral(numeral(0), true); - } - else if (m_util.is_numeral(arg2, v2, is_int) && is_int && v2.is_pos()) { - expr_ref tmp(m_manager); - prop_mod_const(arg1, 5, v2, tmp); - result = m_util.mk_mod(tmp, arg2); - } - else { - result = m_util.mk_mod(arg1, arg2); - } -} - -void arith_simplifier_plugin::mk_rem(expr * arg1, expr * arg2, expr_ref & result) { - set_curr_sort(arg1); - numeral v1, v2; - bool is_int; - if (m_util.is_numeral(arg1, v1, is_int) && m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero()) { - numeral m = mod(v1, v2); - // - // rem(v1,v2) = if v2 >= 0 then mod(v1,v2) else -mod(v1,v2) - // - if (v2.is_neg()) { - m.neg(); - } - result = m_util.mk_numeral(m, is_int); - } - else if (m_util.is_numeral(arg2, v2, is_int) && is_int && v2.is_one()) { - result = m_util.mk_numeral(numeral(0), true); - } - else if (m_util.is_numeral(arg2, v2, is_int) && is_int && !v2.is_zero()) { - expr_ref tmp(m_manager); - prop_mod_const(arg1, 5, v2, tmp); - result = m_util.mk_mod(tmp, arg2); - if (v2.is_neg()) { - result = m_util.mk_uminus(result); - } - } - else { - result = m_util.mk_rem(arg1, arg2); - } -} - -void arith_simplifier_plugin::mk_to_real(expr * arg, expr_ref & result) { - numeral v; - if (m_util.is_numeral(arg, v)) - result = m_util.mk_numeral(v, false); - else - result = m_util.mk_to_real(arg); -} - -void arith_simplifier_plugin::mk_to_int(expr * arg, expr_ref & result) { - numeral v; - if (m_util.is_numeral(arg, v)) - result = m_util.mk_numeral(floor(v), true); - else if (m_util.is_to_real(arg)) - result = to_app(arg)->get_arg(0); - else - result = m_util.mk_to_int(arg); -} - -void arith_simplifier_plugin::mk_is_int(expr * arg, expr_ref & result) { - numeral v; - if (m_util.is_numeral(arg, v)) - result = v.is_int()?m_manager.mk_true():m_manager.mk_false(); - else if (m_util.is_to_real(arg)) - result = m_manager.mk_true(); - else - result = m_util.mk_is_int(arg); -} - -bool arith_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - SASSERT(f->get_family_id() == m_fid); - TRACE("arith_simplifier_plugin", tout << mk_pp(f, m_manager) << "\n"; - for (unsigned i = 0; i < num_args; i++) tout << mk_pp(args[i], m_manager) << "\n";); - arith_op_kind k = static_cast(f->get_decl_kind()); - switch (k) { - case OP_NUM: return false; - case OP_LE: if (m_presimp) return false; SASSERT(num_args == 2); mk_le(args[0], args[1], result); break; - case OP_GE: if (m_presimp) return false; SASSERT(num_args == 2); mk_ge(args[0], args[1], result); break; - case OP_LT: if (m_presimp) return false; SASSERT(num_args == 2); mk_lt(args[0], args[1], result); break; - case OP_GT: if (m_presimp) return false; SASSERT(num_args == 2); mk_gt(args[0], args[1], result); break; - case OP_ADD: mk_add(num_args, args, result); break; - case OP_SUB: mk_sub(num_args, args, result); break; - case OP_UMINUS: SASSERT(num_args == 1); mk_uminus(args[0], result); break; - case OP_MUL: - mk_mul(num_args, args, result); - TRACE("arith_simplifier_plugin", tout << mk_pp(result, m_manager) << "\n";); - break; - case OP_DIV: SASSERT(num_args == 2); mk_div(args[0], args[1], result); break; - case OP_IDIV: SASSERT(num_args == 2); mk_idiv(args[0], args[1], result); break; - case OP_REM: SASSERT(num_args == 2); mk_rem(args[0], args[1], result); break; - case OP_MOD: SASSERT(num_args == 2); mk_mod(args[0], args[1], result); break; - case OP_TO_REAL: SASSERT(num_args == 1); mk_to_real(args[0], result); break; - 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: - return false; - } - TRACE("arith_simplifier_plugin", tout << mk_pp(result.get(), m_manager) << "\n";); - 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; -} - -bool arith_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { - TRACE("reduce_eq_bug", tout << mk_ismt2_pp(lhs, m_manager) << "\n" << mk_ismt2_pp(rhs, m_manager) << "\n";); - set_reduce_invoked(); - if (m_presimp) { - return false; - } - if (m_params.m_arith_expand_eqs) { - expr_ref le(m_manager), ge(m_manager); - mk_le_ge_eq_core(lhs, rhs, le); - mk_le_ge_eq_core(lhs, rhs, ge); - m_bsimp.mk_and(le, ge, result); - return true; - } - - if (m_params.m_arith_process_all_eqs || is_arith_term(lhs) || is_arith_term(rhs)) { - mk_arith_eq(lhs, rhs, result); - return true; - } - return false; -} - - - diff --git a/src/ast/simplifier/arith_simplifier_plugin.h b/src/ast/simplifier/arith_simplifier_plugin.h deleted file mode 100644 index 21ab8f6b4..000000000 --- a/src/ast/simplifier/arith_simplifier_plugin.h +++ /dev/null @@ -1,96 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - arith_simplifier_plugin.h - -Abstract: - - Simplifier for the arithmetic family. - -Author: - - Leonardo (leonardo) 2008-01-08 - ---*/ -#ifndef ARITH_SIMPLIFIER_PLUGIN_H_ -#define ARITH_SIMPLIFIER_PLUGIN_H_ - -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/poly_simplifier_plugin.h" -#include "ast/arith_decl_plugin.h" -#include "ast/simplifier/arith_simplifier_params.h" - -/** - \brief Simplifier for the arith family. -*/ -class arith_simplifier_plugin : public poly_simplifier_plugin { -public: - enum op_kind { - LE, GE, EQ - }; -protected: - arith_simplifier_params & m_params; - arith_util m_util; - basic_simplifier_plugin & m_bsimp; - expr_ref m_int_zero; - expr_ref m_real_zero; - - bool is_neg_poly(expr * t) const; - - template - void mk_le_ge_eq_core(expr * arg1, expr * arg2, expr_ref & result); - - void prop_mod_const(expr * e, unsigned depth, numeral const& k, expr_ref& result); - - void gcd_reduce_monomial(expr_ref_vector& monomials, numeral& k); - - void div_monomial(expr_ref_vector& monomials, numeral const& g); - void get_monomial_gcd(expr_ref_vector& monomials, numeral& g); - -public: - arith_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b, arith_simplifier_params & p); - ~arith_simplifier_plugin(); - arith_util & get_arith_util() { return m_util; } - virtual numeral norm(const numeral & n) { return n; } - virtual bool is_numeral(expr * n, rational & val) const { bool f; return m_util.is_numeral(n, val, f); } - bool is_numeral(expr * n) const { return m_util.is_numeral(n); } - virtual bool is_minus_one(expr * n) const { numeral tmp; return is_numeral(n, tmp) && tmp.is_minus_one(); } - virtual expr * get_zero(sort * s) const { return m_util.is_int(s) ? m_int_zero.get() : m_real_zero.get(); } - - virtual app * mk_numeral(numeral const & n) { return m_util.mk_numeral(n, m_curr_sort->get_decl_kind() == INT_SORT); } - app * mk_numeral(numeral const & n, bool is_int) { return m_util.mk_numeral(n, is_int); } - bool is_int_sort(sort const * s) const { return m_util.is_int(s); } - bool is_real_sort(sort const * s) const { return m_util.is_real(s); } - bool is_arith_sort(sort const * s) const { return is_int_sort(s) || is_real_sort(s); } - bool is_int(expr const * n) const { return m_util.is_int(n); } - bool is_le(expr const * n) const { return m_util.is_le(n); } - bool is_ge(expr const * n) const { return m_util.is_ge(n); } - - virtual bool is_le_ge(expr * n) const { return is_le(n) || is_ge(n); } - - void mk_le(expr * arg1, expr * arg2, expr_ref & result); - void mk_ge(expr * arg1, expr * arg2, expr_ref & result); - void mk_lt(expr * arg1, expr * arg2, expr_ref & result); - void mk_gt(expr * arg1, expr * arg2, expr_ref & result); - void mk_arith_eq(expr * arg1, expr * arg2, expr_ref & result); - void mk_div(expr * arg1, expr * arg2, expr_ref & result); - void mk_idiv(expr * arg1, expr * arg2, expr_ref & result); - void mk_mod(expr * arg1, expr * arg2, expr_ref & result); - void mk_rem(expr * arg1, expr * arg2, expr_ref & result); - 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); - - bool is_arith_term(expr * n) const; - - void gcd_normalize(numeral & coeff, expr_ref& term); - -}; - -#endif /* ARITH_SIMPLIFIER_PLUGIN_H_ */ diff --git a/src/ast/simplifier/array_simplifier_params.cpp b/src/ast/simplifier/array_simplifier_params.cpp deleted file mode 100644 index ff7dba25f..000000000 --- a/src/ast/simplifier/array_simplifier_params.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/*++ -Copyright (c) 2012 Microsoft Corporation - -Module Name: - - array_simplifier_params.cpp - -Abstract: - - This file was created during code reorg. - -Author: - - Leonardo de Moura (leonardo) 2012-12-02. - -Revision History: - ---*/ -#include "ast/simplifier/array_simplifier_params.h" -#include "ast/simplifier/array_simplifier_params_helper.hpp" - -void array_simplifier_params::updt_params(params_ref const & _p) { - array_simplifier_params_helper p(_p); - m_array_canonize_simplify = p.array_canonize(); - m_array_simplify = p.array_simplify(); -} diff --git a/src/ast/simplifier/array_simplifier_params.h b/src/ast/simplifier/array_simplifier_params.h deleted file mode 100644 index 07ead5fd6..000000000 --- a/src/ast/simplifier/array_simplifier_params.h +++ /dev/null @@ -1,34 +0,0 @@ -/*++ -Copyright (c) 2012 Microsoft Corporation - -Module Name: - - array_simplifier_params.h - -Abstract: - - This file was created during code reorg. - -Author: - - Leonardo de Moura (leonardo) 2012-12-02. - -Revision History: - ---*/ -#ifndef ARRAY_SIMPLIFIER_PARAMS_H_ -#define ARRAY_SIMPLIFIER_PARAMS_H_ - -#include "util/params.h" - -struct array_simplifier_params1 { - - array_simplifier_params1(params_ref const & p = params_ref()) { - updt_params(p); - } - - void updt_params(params_ref const & _p); -}; - -#endif /* ARITH_SIMPLIFIER_PARAMS_H_ */ - diff --git a/src/ast/simplifier/array_simplifier_params_helper.pyg b/src/ast/simplifier/array_simplifier_params_helper.pyg deleted file mode 100644 index 93c184c23..000000000 --- a/src/ast/simplifier/array_simplifier_params_helper.pyg +++ /dev/null @@ -1,6 +0,0 @@ -def_module_params(class_name='array_simplifier_params_helper', - module_name="old_simplify", # Parameters will be in the old_simplify module - export=True, - params=( - ('array.canonize', BOOL, False, 'normalize array terms into normal form during simplification'), - ('array.simplify', BOOL, True, 'enable/disable array simplifications'))) diff --git a/src/ast/simplifier/array_simplifier_plugin.cpp b/src/ast/simplifier/array_simplifier_plugin.cpp deleted file mode 100644 index 754daab69..000000000 --- a/src/ast/simplifier/array_simplifier_plugin.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/*++ -Copyright (c) 2008 Microsoft Corporation - -Module Name: - - array_simplifier_plugin.cpp - -Abstract: - - - -Author: - - Nikolaj Bjorner (nbjorner) 2008-05-05 - -Revision History: - -Notes TODO: - - Examine quadratic cost of simplification vs. model-based procedure. - - Parameterize cache replacement strategy. - Some parameters are hard-wired. - ---*/ - -#include "ast/simplifier/array_simplifier_plugin.h" -#include "ast/ast_ll_pp.h" -#include "ast/ast_pp.h" - - -array_simplifier_plugin::array_simplifier_plugin( - ast_manager & m, - basic_simplifier_plugin& s, - simplifier& simp, - array_simplifier_params const& p) : - simplifier_plugin(symbol("array"),m), - m_util(m), - m_simp(s), - m_simplifier(simp), - m_params(p), - m_store_cache_size(0) -{} - - -array_simplifier_plugin::~array_simplifier_plugin() { - - select_cache::iterator it = m_select_cache.begin(); - select_cache::iterator end = m_select_cache.end(); - for ( ; it != end; ++it) { - m_manager.dec_array_ref(it->m_key->size(), it->m_key->c_ptr()); - m_manager.dec_ref(it->m_value); - dealloc(it->m_key); - } - - store_cache::iterator it2 = m_store_cache.begin(); - store_cache::iterator end2 = m_store_cache.end(); - for (; it2 != end2; ++it2) { - m_manager.dec_ref(it->m_value); - dealloc(it->m_key); - } -} - - -bool array_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - if (!m_params.m_array_simplify) - return false; - set_reduce_invoked(); - if (m_presimp) - return false; -#if Z3DEBUG - for (unsigned i = 0; i < num_args && i < f->get_arity(); ++i) { - SASSERT(m_manager.get_sort(args[i]) == f->get_domain(i)); - } -#endif - TRACE("array_simplifier", { - tout << mk_pp(f, m_manager) << " "; - for (unsigned i = 0; i < num_args; ++i) { - tout << mk_pp(args[i], m_manager) << " "; - } - tout << "\n"; - } - ); - SASSERT(f->get_family_id() == m_fid); - switch(f->get_decl_kind()) { - case OP_SELECT: - mk_select(num_args, args, result); - break; - case OP_STORE: - mk_store(f, num_args, args, result); - break; - case OP_SET_UNION: { - sort* s = f->get_range(); - expr_ref empty(m_manager); - mk_empty_set(s, empty); - switch(num_args) { - case 0: - result = empty; - break; - case 1: - result = args[0]; - break; - default: { - result = args[0]; - func_decl* f_or = m_manager.mk_or_decl(); - for (unsigned i = 1; i < num_args; ++i) { - mk_map(f_or, result, args[i], result); - } - break; - } - } - break; - } - case OP_SET_INTERSECT: { - expr_ref full(m_manager); - mk_full_set(f->get_range(), full); - switch(num_args) { - case 0: - result = full; - break; - case 1: - result = args[0]; - break; - default: { - result = args[0]; - func_decl* f_and = m_manager.mk_and_decl(); - for (unsigned i = 1; i < num_args; ++i) { - mk_map(f_and, result, args[i], result); - } - break; - } - } - TRACE("array_simplifier", tout << "sort " << mk_pp(result.get(), m_manager) << "\n";); - break; - } - case OP_SET_SUBSET: { - SASSERT(num_args == 2); - expr_ref diff(m_manager), emp(m_manager); - mk_set_difference(num_args, args, diff); - mk_empty_set(m_manager.get_sort(args[0]), emp); - m_simp.mk_eq(diff.get(), emp.get(), result); - break; - } - case OP_SET_COMPLEMENT: { - SASSERT(num_args == 1); - func_decl* f_not = m_manager.mk_not_decl(); - mk_map(f_not, args[0], result); - break; - } - case OP_SET_DIFFERENCE: { - SASSERT(num_args == 2); - expr_ref r1(m_manager); - mk_map(m_manager.mk_not_decl(), args[1], r1); - mk_map(m_manager.mk_and_decl(), args[0], r1, result); - break; - } - case OP_ARRAY_MAP: { - SASSERT(f->get_num_parameters() == 1); - SASSERT(f->get_parameter(0).is_ast()); - SASSERT(is_func_decl(f->get_parameter(0).get_ast())); - // - // map_d (store a j v) = (store (map_f a) v (d v)) - // - if (num_args == 1 && is_store(args[0])) { - app* store_expr = to_app(args[0]); - unsigned num_args = store_expr->get_num_args(); - SASSERT(num_args >= 3); - parameter p = f->get_parameter(0); - func_decl* d = to_func_decl(p.get_ast()); - expr* a = store_expr->get_arg(0); - expr* v = store_expr->get_arg(num_args-1); - // expr*const* args = store_expr->get_args()+1; - expr_ref r1(m_manager), r2(m_manager); - ptr_vector new_args; - - reduce(f, 1, &a, r1); - m_simplifier.mk_app(d, 1, &v, r2); - new_args.push_back(r1); - for (unsigned i = 1; i + 1 < num_args; ++i) { - new_args.push_back(store_expr->get_arg(i)); - } - new_args.push_back(r2); - mk_store(store_expr->get_decl(), num_args, new_args.c_ptr(), result); - break; - } - - // - // map_d (store a j v) (store b j w) = (store (map_f a b) j (d v w)) - // - if (num_args > 1 && same_store(num_args, args)) { - app* store_expr1 = to_app(args[0]); - unsigned num_indices = store_expr1->get_num_args(); - SASSERT(num_indices >= 3); - parameter p = f->get_parameter(0); - func_decl* d = to_func_decl(p.get_ast()); - ptr_vector arrays; - ptr_vector values; - for (unsigned i = 0; i < num_args; ++i) { - arrays.push_back(to_app(args[i])->get_arg(0)); - values.push_back(to_app(args[i])->get_arg(num_indices-1)); - } - - expr_ref r1(m_manager), r2(m_manager); - reduce(f, arrays.size(), arrays.c_ptr(), r1); - m_simplifier.mk_app(d, values.size(), values.c_ptr(), r2); - ptr_vector new_args; - new_args.push_back(r1); - for (unsigned i = 1; i + 1 < num_indices; ++i) { - new_args.push_back(store_expr1->get_arg(i)); - } - new_args.push_back(r2); - mk_store(store_expr1->get_decl(), new_args.size(), new_args.c_ptr(), result); - break; - } - // - // map_d (const v) = (const (d v)) - // - if (num_args == 1 && is_const_array(args[0])) { - app* const_expr = to_app(args[0]); - SASSERT(const_expr->get_num_args() == 1); - parameter p = f->get_parameter(0); - func_decl* d = to_func_decl(p.get_ast()); - expr* v = const_expr->get_arg(0); - expr_ref r1(m_manager); - - m_simplifier.mk_app(d, 1, &v, r1); - expr* arg = r1.get(); - parameter param(f->get_range()); - result = m_manager.mk_app(m_fid, OP_CONST_ARRAY, 1, ¶m, 1, &arg); - break; - } - // - // map_d (const v) (const w) = (const (d v w)) - // - if (num_args > 1 && all_const_array(num_args, args)) { - parameter p = f->get_parameter(0); - func_decl* d = to_func_decl(p.get_ast()); - ptr_vector values; - for (unsigned i = 0; i < num_args; ++i) { - values.push_back(to_app(args[i])->get_arg(0)); - } - expr_ref r1(m_manager); - - m_simplifier.mk_app(d, values.size(), values.c_ptr(), r1); - expr* arg = r1.get(); - parameter param(f->get_range()); - result = m_manager.mk_app(m_fid, OP_CONST_ARRAY, 1, ¶m, 1, &arg); - break; - } - result = m_manager.mk_app(f, num_args, args); - - break; - } - default: - result = m_manager.mk_app(f, num_args, args); - break; - } - TRACE("array_simplifier", - tout << mk_pp(result.get(), m_manager) << "\n";); - - return true; -} - -bool array_simplifier_plugin::same_store(unsigned num_args, expr* const* args) const { - if (num_args == 0) { - return true; - } - if (!is_store(args[0])) { - return false; - } - SASSERT(to_app(args[0])->get_num_args() >= 3); - unsigned num_indices = to_app(args[0])->get_num_args() - 2; - for (unsigned i = 1; i < num_args; ++i) { - if (!is_store(args[i])) { - return false; - } - for (unsigned j = 1; j < num_indices + 1; ++j) { - if (to_app(args[0])->get_arg(j) != to_app(args[i])->get_arg(j)) { - return false; - } - } - } - return true; -} - -bool array_simplifier_plugin::all_const_array(unsigned num_args, expr* const* args) const { - bool is_const = true; - for (unsigned i = 0; is_const && i < num_args; ++i) { - is_const = is_const_array(args[i]); - } - return is_const; -} - -bool array_simplifier_plugin::all_values(unsigned num_args, expr* const* args) const { - for (unsigned i = 0; i < num_args; ++i) { - if (!m_manager.is_unique_value(args[i])) { - return false; - } - } - return true; -} - -bool array_simplifier_plugin::lex_lt(unsigned num_args, expr* const* args1, expr* const* args2) { - for (unsigned i = 0; i < num_args; ++i) { - TRACE("array_simplifier", - tout << mk_pp(args1[i], m_manager) << "\n"; - tout << mk_pp(args2[i], m_manager) << "\n"; - tout << args1[i]->get_id() << " " << args2[i]->get_id() << "\n"; - ); - - if (args1[i]->get_id() < args2[i]->get_id()) return true; - if (args1[i]->get_id() > args2[i]->get_id()) return false; - } - return false; -} - - -void array_simplifier_plugin::get_stores(expr* n, unsigned& arity, expr*& m, ptr_vector& stores) { - while (is_store(n)) { - app* a = to_app(n); - SASSERT(a->get_num_args() > 2); - arity = a->get_num_args()-2; - n = a->get_arg(0); - stores.push_back(a->get_args()+1); - } - m = n; -} - -lbool array_simplifier_plugin::eq_default(expr* def, unsigned arity, unsigned num_st, expr*const* const* st) { - bool all_diseq = m_manager.is_unique_value(def) && num_st > 0; - bool all_eq = true; - for (unsigned i = 0; i < num_st; ++i) { - all_eq &= (st[i][arity] == def); - all_diseq &= m_manager.is_unique_value(st[i][arity]) && (st[i][arity] != def); - TRACE("array_simplifier", tout << m_manager.is_unique_value(st[i][arity]) << " " << mk_pp(st[i][arity], m_manager) << "\n";); - } - if (all_eq) { - return l_true; - } - if (all_diseq) { - return l_false; - } - return l_undef; -} - - -bool array_simplifier_plugin::insert_table(expr* def, unsigned arity, unsigned num_st, expr*const* const* st, arg_table& table) { - for (unsigned i = 0; i < num_st; ++i ) { - for (unsigned j = 0; j < arity; ++j) { - if (!m_manager.is_unique_value(st[i][j])) { - return false; - } - } - TRACE("array_simplifier", tout << "inserting: "; - for (unsigned j = 0; j < arity; ++j) { - tout << mk_pp(st[i][j], m_manager) << " "; - } - tout << " |-> " << mk_pp(def, m_manager) << "\n"; - ); - args_entry e(arity, st[i]); - table.insert_if_not_there(e); - } - return true; -} - - -lbool array_simplifier_plugin::eq_stores(expr* def, unsigned arity, unsigned num_st1, expr*const* const* st1, unsigned num_st2, expr*const* const* st2) { - if (num_st1 == 0) { - return eq_default(def, arity, num_st2, st2); - } - if (num_st2 == 0) { - return eq_default(def, arity, num_st1, st1); - } - arg_table table1, table2; - if (!insert_table(def, arity, num_st1, st1, table1)) { - return l_undef; - } - if (!insert_table(def, arity, num_st2, st2, table2)) { - return l_undef; - } - - arg_table::iterator it = table1.begin(); - arg_table::iterator end = table1.end(); - for (; it != end; ++it) { - args_entry const & e1 = *it; - args_entry e2; - expr* v1 = e1.m_args[arity]; - if (table2.find(e1, e2)) { - expr* v2 = e2.m_args[arity]; - if (v1 == v2) { - table2.erase(e1); - continue; - } - if (m_manager.is_unique_value(v1) && m_manager.is_unique_value(v2)) { - return l_false; - } - return l_undef; - } - else if (m_manager.is_unique_value(v1) && m_manager.is_unique_value(def) && v1 != def) { - return l_false; - } - } - it = table2.begin(); - end = table2.end(); - for (; it != end; ++it) { - args_entry const & e = *it; - expr* v = e.m_args[arity]; - if (m_manager.is_unique_value(v) && m_manager.is_unique_value(def) && v != def) { - return l_false; - } - } - if (!table2.empty() || !table1.empty()) { - return l_undef; - } - return l_true; -} - - -bool array_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { - set_reduce_invoked(); - expr* c1, *c2; - ptr_vector st1, st2; - unsigned arity1 = 0; - unsigned arity2 = 0; - get_stores(lhs, arity1, c1, st1); - get_stores(rhs, arity2, c2, st2); - if (arity1 == arity2 && is_const_array(c1) && is_const_array(c2)) { - c1 = to_app(c1)->get_arg(0); - c2 = to_app(c2)->get_arg(0); - if (c1 == c2) { - lbool eq = eq_stores(c1, arity2, st1.size(), st1.c_ptr(), st2.size(), st2.c_ptr()); - TRACE("array_simplifier", - tout << mk_pp(lhs, m_manager) << " = " - << mk_pp(rhs, m_manager) << " := " << eq << "\n"; - tout << "arity: " << arity1 << "\n";); - switch(eq) { - case l_false: - result = m_manager.mk_false(); - return true; - case l_true: - result = m_manager.mk_true(); - return true; - default: - return false; - } - } - else if (m_manager.is_unique_value(c1) && m_manager.is_unique_value(c2)) { - result = m_manager.mk_false(); - return true; - } - } - return false; -} - -bool array_simplifier_plugin::reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - return false; -} - - -array_simplifier_plugin::const_select_result -array_simplifier_plugin::mk_select_const(expr* m, app* index, expr_ref& result) { - store_info* info = 0; - expr* r = 0, *a = 0; - if (!is_store(m)) { - return NOT_CACHED; - } - if (!m_store_cache.find(m, info)) { - return NOT_CACHED; - } - if (info->m_map.find(index, r)) { - result = r; - return FOUND_VALUE; - } - a = info->m_default.get(); - - // - // Unfold and cache the store while searching for value of index. - // - while (is_store(a) && m_manager.is_unique_value(to_app(a)->get_arg(1))) { - app* b = to_app(a); - app* c = to_app(b->get_arg(1)); - - if (!info->m_map.contains(c)) { - info->m_map.insert(c, b->get_arg(2)); - m_manager.inc_ref(b->get_arg(2)); - ++m_store_cache_size; - } - a = b->get_arg(0); - info->m_default = a; - - if (c == index) { - result = b->get_arg(2); - return FOUND_VALUE; - } - } - result = info->m_default.get(); - return FOUND_DEFAULT; -} - -void array_simplifier_plugin::cache_store(unsigned num_stores, expr* store_term) -{ - if (num_stores <= m_const_store_threshold) { - return; - } - prune_store_cache(); - if (!m_store_cache.contains(store_term)) { - store_info * info = alloc(store_info, m_manager, store_term); - m_manager.inc_ref(store_term); - m_store_cache.insert(store_term, info); - TRACE("cache_store", tout << m_store_cache.size() << "\n";); - ++m_store_cache_size; - } -} - -void array_simplifier_plugin::cache_select(unsigned num_args, expr * const * args, expr * result) { - ptr_vector * entry = alloc(ptr_vector); - entry->append(num_args, const_cast(args)); - const select_cache::key_data & kd = m_select_cache.insert_if_not_there(entry, result); - if (kd.m_key != entry) { - dealloc(entry); - return; - } - m_manager.inc_array_ref(num_args, args); - m_manager.inc_ref(result); - TRACE("cache_select", tout << m_select_cache.size() << "\n";); -} - - - -void array_simplifier_plugin::prune_select_cache() { - if (m_select_cache.size() > m_select_cache_max_size) { - flush_select_cache(); - } -} - -void array_simplifier_plugin::prune_store_cache() { - if (m_store_cache_size > m_store_cache_max_size) { - flush_store_cache(); - } -} - -void array_simplifier_plugin::flush_select_cache() { - select_cache::iterator it = m_select_cache.begin(); - select_cache::iterator end = m_select_cache.end(); - for (; it != end; ++it) { - ptr_vector * e = (*it).m_key; - m_manager.dec_array_ref(e->size(), e->begin()); - m_manager.dec_ref((*it).m_value); - dealloc(e); - } - m_select_cache.reset(); -} - -void array_simplifier_plugin::flush_store_cache() { - store_cache::iterator it = m_store_cache.begin(); - store_cache::iterator end = m_store_cache.end(); - for (; it != end; ++it) { - m_manager.dec_ref((*it).m_key); - const_map::iterator mit = (*it).m_value->m_map.begin(); - const_map::iterator mend = (*it).m_value->m_map.end(); - for (; mit != mend; ++mit) { - m_manager.dec_ref((*mit).m_value); - } - dealloc((*it).m_value); - } - m_store_cache.reset(); - m_store_cache_size = 0; -} - - -void array_simplifier_plugin::flush_caches() { - flush_select_cache(); - flush_store_cache(); -} - -void array_simplifier_plugin::mk_set_difference(unsigned num_args, expr * const * args, expr_ref & result) { - SASSERT(num_args == 2); - result = m_manager.mk_app(m_fid, OP_SET_DIFFERENCE, 0, 0, num_args, args); -} - -void array_simplifier_plugin::mk_empty_set(sort* ty, expr_ref & result) { - parameter param(ty); - expr* args[1] = { m_manager.mk_false() }; - result = m_manager.mk_app(m_fid, OP_CONST_ARRAY, 1, ¶m, 1, args); -} - -void array_simplifier_plugin::mk_full_set(sort* ty, expr_ref & result) { - parameter param(ty); - expr* args[1] = { m_manager.mk_true() }; - result = m_manager.mk_app(m_fid, OP_CONST_ARRAY, 1, ¶m, 1, args); -} - - -bool array_simplifier_plugin::same_args(unsigned num_args, expr * const * args1, expr * const * args2) { - for (unsigned i = 0; i < num_args; ++i) { - if (args1[i] != args2[i]) { - return false; - } - } - return true; -} - -void array_simplifier_plugin::mk_store(func_decl* f, unsigned num_args, expr * const * args, expr_ref & result) { - - SASSERT(num_args >= 3); - - expr* arg0 = args[0]; - expr* argn = args[num_args-1]; - - // - // store(store(a,i,v),i,w) = store(a,i,w) - // - if (is_store(arg0) && - same_args(num_args-2, args+1, to_app(arg0)->get_args()+1)) { - expr_ref_buffer new_args(m_manager); - new_args.push_back(to_app(arg0)->get_arg(0)); - for (unsigned i = 1; i < num_args; ++i) { - new_args.push_back(args[i]); - } - reduce(f, num_args, new_args.c_ptr(), result); - TRACE("array_simplifier", tout << mk_pp(result.get(), m_manager) << "\n";); - return; - } - - // - // store(const(v),i,v) = const(v) - // - if (is_const_array(arg0) && - to_app(arg0)->get_arg(0) == args[num_args-1]) { - result = arg0; - TRACE("array_simplifier", tout << mk_pp(result.get(), m_manager) << "\n";); - return; - } - - // - // store(a, i, select(a, i)) = a - // - if (is_select(argn) && - (to_app(argn)->get_num_args() == num_args - 1) && - same_args(num_args-1, args, to_app(argn)->get_args())) { - TRACE("dummy_store", tout << "dummy store simplified mk_store(\n"; - for (unsigned i = 0; i < num_args; i++) ast_ll_pp(tout, m_manager, args[i]); - tout << ") =====>\n"; - ast_ll_pp(tout, m_manager, arg0);); - result = arg0; - TRACE("array_simplifier", tout << mk_pp(result.get(), m_manager) << "\n";); - return; - } - - // - // store(store(a,i,v),j,w) -> store(store(a,j,w),i,v) - // if i, j are values, i->get_id() < j->get_id() - // - if (m_params.m_array_canonize_simplify && - is_store(arg0) && - all_values(num_args-2, args+1) && - all_values(num_args-2, to_app(arg0)->get_args()+1) && - lex_lt(num_args-2, args+1, to_app(arg0)->get_args()+1)) { - expr* const* args2 = to_app(arg0)->get_args(); - expr_ref_buffer new_args(m_manager); - new_args.push_back(args2[0]); - for (unsigned i = 1; i < num_args; ++i) { - new_args.push_back(args[i]); - } - reduce(f, num_args, new_args.c_ptr(), result); - new_args.reset(); - new_args.push_back(result); - for (unsigned i = 1; i < num_args; ++i) { - new_args.push_back(args2[i]); - } - result = m_manager.mk_app(m_fid, OP_STORE, num_args, new_args.c_ptr()); - TRACE("array_simplifier", tout << mk_pp(result.get(), m_manager) << "\n";); - return; - } - - - result = m_manager.mk_app(m_fid, OP_STORE, num_args, args); - TRACE("array_simplifier", tout << "default: " << mk_pp(result.get(), m_manager) << "\n";); - -} - -void array_simplifier_plugin::mk_select_as_array(unsigned num_args, expr * const * args, expr_ref & result) { - SASSERT(is_as_array(args[0])); - func_decl * f = get_as_array_func_decl(to_app(args[0])); - result = m_manager.mk_app(f, num_args - 1, args+1); -} - -void array_simplifier_plugin::mk_select_as_array_tree(unsigned num_args, expr * const * args, expr_ref & result) { - SASSERT(is_as_array_tree(args[0])); - SASSERT(m_manager.is_ite(args[0])); - ptr_buffer todo; - obj_map cache; - app_ref_buffer trail(m_manager); - todo.push_back(to_app(args[0])); - while (!todo.empty()) { - app * curr = todo.back(); - SASSERT(m_manager.is_ite(curr)); - expr * branches[2] = {0, 0}; - bool visited = true; - for (unsigned i = 0; i < 2; i++) { - expr * arg = curr->get_arg(i+1); - if (is_as_array(arg)) { - branches[i] = m_manager.mk_app(get_as_array_func_decl(to_app(arg)), num_args - 1, args+1); - } - else { - SASSERT(m_manager.is_ite(arg)); - app * new_arg = 0; - if (!cache.find(to_app(arg), new_arg)) { - todo.push_back(to_app(arg)); - visited = false; - } - else { - branches[i] = new_arg; - } - } - } - if (visited) { - todo.pop_back(); - app * new_curr = m_manager.mk_ite(curr->get_arg(0), branches[0], branches[1]); - trail.push_back(new_curr); - cache.insert(curr, new_curr); - } - } - SASSERT(cache.contains(to_app(args[0]))); - app * r = 0; - cache.find(to_app(args[0]), r); - result = r; -} - -void array_simplifier_plugin::mk_select(unsigned num_args, expr * const * args, expr_ref & result) { - expr * r = 0; - - if (is_as_array(args[0])) { - mk_select_as_array(num_args, args, result); - return; - } - - if (is_as_array_tree(args[0])) { - mk_select_as_array_tree(num_args, args, result); - return; - } - - bool is_const_select = num_args == 2 && m_manager.is_unique_value(args[1]); - app* const_index = is_const_select?to_app(args[1]):0; - unsigned num_const_stores = 0; - expr_ref tmp(m_manager); - expr* args2[2]; - if (is_const_select) { - switch(mk_select_const(args[0], const_index, tmp)) { - case NOT_CACHED: - break; - case FOUND_VALUE: - TRACE("mk_select", tout << "found value\n"; ast_ll_pp(tout, m_manager, tmp.get()); ); - result = tmp.get(); - // value of select is stored under result. - return; - case FOUND_DEFAULT: - args2[0] = tmp.get(); - args2[1] = args[1]; - args = args2; - is_const_select = false; - break; - } - } - - SASSERT(num_args > 0); - ptr_vector & entry = m_tmp2; - entry.reset(); - entry.append(num_args, args); - expr * entry0 = entry[0]; - SASSERT(m_todo.empty()); - m_todo.push_back(entry0); - while (!m_todo.empty()) { - expr * m = m_todo.back(); - TRACE("array_simplifier", tout << mk_bounded_pp(m, m_manager) << "\n";); - if (is_store(m)) { - expr * nested_array = to_app(m)->get_arg(0); - expr * else_branch = 0; - entry[0] = nested_array; - if (is_const_select) { - if (m_manager.is_unique_value(to_app(m)->get_arg(1))) { - app* const_index2 = to_app(to_app(m)->get_arg(1)); - // - // we found the value, all other stores are different. - // there is no need to recurse. - // - if (const_index == const_index2) { - result = to_app(m)->get_arg(2); - cache_store(num_const_stores, args[0]); - m_todo.reset(); - return; - } - ++num_const_stores; - } - else { - is_const_select = false; - } - } - if (m_select_cache.find(&entry, else_branch)) { - expr_ref_buffer eqs(m_manager); - for (unsigned i = 1; i < num_args ; ++i) { - expr * a = args[i]; - expr * b = to_app(m)->get_arg(i); - expr_ref eq(m_manager); - m_simp.mk_eq(a, b, eq); - eqs.push_back(eq.get()); - } - expr_ref cond(m_manager); - m_simp.mk_and(eqs.size(), eqs.c_ptr(), cond); - expr * then_branch = to_app(m)->get_arg(num_args); - if (m_manager.is_true(cond.get())) { - result = then_branch; - } - else if (m_manager.is_false(cond.get())) { - result = else_branch; - } - else { - m_simp.mk_ite(cond.get(), then_branch, else_branch, result); - } - entry[0] = m; - cache_select(entry.size(), entry.c_ptr(), result.get()); - m_todo.pop_back(); - } - else { - m_todo.push_back(nested_array); - } - } - else if (is_const_array(m)) { - entry[0] = m; - cache_select(entry.size(), entry.c_ptr(), to_app(m)->get_arg(0)); - m_todo.pop_back(); - } - else { - entry[0] = m; - TRACE("array_simplifier", { - for (unsigned i = 0; i < entry.size(); ++i) { - tout << mk_bounded_pp(entry[i], m_manager) << ": " - << mk_bounded_pp(m_manager.get_sort(entry[i]), m_manager) << "\n"; - }} - ); - r = m_manager.mk_app(m_fid, OP_SELECT, 0, 0, entry.size(), entry.c_ptr()); - cache_select(entry.size(), entry.c_ptr(), r); - m_todo.pop_back(); - } - } - cache_store(num_const_stores, args[0]); - entry[0] = entry0; -#ifdef Z3DEBUG - bool f = -#endif - m_select_cache.find(&entry, r); - SASSERT(f); - result = r; - prune_select_cache(); - prune_store_cache(); - TRACE("mk_select", - for (unsigned i = 0; i < num_args; i++) { - ast_ll_pp(tout, m_manager, args[i]); tout << "\n"; - }; - tout << "is_store: " << is_store(args[0]) << "\n"; - ast_ll_pp(tout, m_manager, r);); -} - - -void array_simplifier_plugin::mk_map(func_decl* f, expr* a, expr* b, expr_ref& result) { - expr* exprs[2] = { a, b }; - parameter param(f); - result = m_manager.mk_app(m_fid, OP_ARRAY_MAP, 1, ¶m, 2, exprs ); -} - -void array_simplifier_plugin::mk_map(func_decl* f, expr* a, expr_ref& result) { - parameter param(f); - result = m_manager.mk_app(m_fid, OP_ARRAY_MAP, 1, ¶m, 1, &a ); -} - - diff --git a/src/ast/simplifier/array_simplifier_plugin.h b/src/ast/simplifier/array_simplifier_plugin.h deleted file mode 100644 index 62eb5e5ff..000000000 --- a/src/ast/simplifier/array_simplifier_plugin.h +++ /dev/null @@ -1,154 +0,0 @@ -/*++ -Copyright (c) 2008 Microsoft Corporation - -Module Name: - - array_simplifier_plugin.h - -Abstract: - - - -Author: - - Nikolaj Bjorner (nbjorner) 2008-05-05 - -Revision History: - ---*/ -#ifndef ARRAY_SIMPLIFIER_PLUGIN_H_ -#define ARRAY_SIMPLIFIER_PLUGIN_H_ - -#include "ast/ast.h" -#include "util/map.h" -#include "ast/array_decl_plugin.h" -#include "ast/simplifier/simplifier_plugin.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/array_simplifier_params.h" -#include "ast/simplifier/simplifier.h" -#include "util/obj_hashtable.h" -#include "util/lbool.h" - -class array_simplifier_plugin : public simplifier_plugin { - - typedef ptr_vector entry; - - struct entry_hash_proc { - unsigned operator()(ptr_vector * entry) const { - return get_exprs_hash(entry->size(), entry->begin(), 0xbeef1010); - } - }; - - struct entry_eq_proc { - bool operator()(ptr_vector * entry1, ptr_vector * entry2) const { - if (entry1->size() != entry2->size()) return false; - return compare_arrays(entry1->begin(), entry2->begin(), entry1->size()); - } - }; - - typedef map select_cache; - - struct args_entry { - unsigned m_arity; - expr* const* m_args; - args_entry(unsigned a, expr* const* args) : m_arity(a), m_args(args) {} - args_entry() : m_arity(0), m_args(0) {} - }; - - struct args_entry_hash_proc { - unsigned operator()(args_entry const& e) const { - return get_exprs_hash(e.m_arity, e.m_args, 0xbeef1010); - } - }; - struct args_entry_eq_proc { - bool operator()(args_entry const& e1, args_entry const& e2) const { - if (e1.m_arity != e2.m_arity) return false; - return compare_arrays(e1.m_args, e2.m_args, e1.m_arity); - } - }; - typedef hashtable arg_table; - - array_util m_util; - basic_simplifier_plugin& m_simp; - simplifier& m_simplifier; - array_simplifier_params const& m_params; - select_cache m_select_cache; - ptr_vector m_tmp; - ptr_vector m_tmp2; - ptr_vector m_todo; - static const unsigned m_select_cache_max_size = 100000; - typedef obj_map const_map; - class store_info { - store_info(); - store_info(store_info const&); - public: - const_map m_map; - expr_ref m_default; - store_info(ast_manager& m, expr* d): m_default(d, m) {} - }; - - typedef obj_map store_cache; - store_cache m_store_cache; - unsigned m_store_cache_size; - static const unsigned m_store_cache_max_size = 10000; - static const unsigned m_const_store_threshold = 5; - enum const_select_result { - NOT_CACHED, - FOUND_DEFAULT, - FOUND_VALUE - }; - - -public: - array_simplifier_plugin(ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, array_simplifier_params const& p); - virtual ~array_simplifier_plugin(); - - 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); - - virtual bool reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result); - - virtual void flush_caches(); - -private: - bool is_select(expr* n) const { return m_util.is_select(n); } - bool is_store(expr * n) const { return m_util.is_store(n); } - bool is_const_array(expr * n) const { return m_util.is_const(n); } - bool is_as_array(expr * n) const { return m_util.is_as_array(n); } - bool is_as_array_tree(expr * n) { return m_util.is_as_array_tree(n); } - func_decl * get_as_array_func_decl(app * n) const { return m_util.get_as_array_func_decl(n); } - void mk_select_as_array(unsigned num_args, expr * const * args, expr_ref & result); - void mk_select_as_array_tree(unsigned num_args, expr * const * args, expr_ref & result); - bool is_enumerated(expr* n, expr_ref& c, ptr_vector& keys, ptr_vector& vals); - const_select_result mk_select_const(expr* m, app* index, expr_ref& result); - void cache_store(unsigned num_stores, expr* nested_store); - void cache_select(unsigned num_args, expr * const * args, expr * result); - void prune_select_cache(); - void prune_store_cache(); - void flush_select_cache(); - void flush_store_cache(); - void mk_set_difference(unsigned num_args, expr * const * args, expr_ref & result); - void mk_empty_set(sort* ty, expr_ref & result); - void mk_full_set(sort* ty, expr_ref & result); - void mk_select(unsigned num_args, expr * const * args, expr_ref & result); - void mk_store(func_decl* f, unsigned num_args, expr * const * args, expr_ref & result); - void mk_map(func_decl* f, expr* a, expr* b, expr_ref & result); - void mk_map(func_decl* f, expr* a, expr_ref & result); - bool same_args(unsigned num_args, expr * const * args1, expr * const * args2); - - void get_stores(expr* n, unsigned& arity, expr*& m, ptr_vector& stores); - lbool eq_default(expr* def, unsigned arity, unsigned num_st, expr*const* const* st); - bool insert_table(expr* def, unsigned arity, unsigned num_st, expr*const* const* st, arg_table& table); - lbool eq_stores(expr* def, unsigned arity, unsigned num_st1, expr*const* const* st1, unsigned num_st2, expr*const* const* st2); - - bool same_store(unsigned num_args, expr* const* args) const; - bool all_const_array(unsigned num_args, expr* const* args) const; - bool all_values(unsigned num_args, expr* const* args) const; - bool lex_lt(unsigned num_args, expr* const* args1, expr* const* args2); - -}; - - -#endif /* ARRAY_SIMPLIFIER_PLUGIN_H_ */ - diff --git a/src/ast/simplifier/base_simplifier.h b/src/ast/simplifier/base_simplifier.h deleted file mode 100644 index 73a04d605..000000000 --- a/src/ast/simplifier/base_simplifier.h +++ /dev/null @@ -1,76 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - base_simplifier.h - -Abstract: - - Base class for expression simplifier functors. - -Author: - - Leonardo (leonardo) 2008-01-11 - -Notes: - ---*/ -#ifndef BASE_SIMPLIFIER_H_ -#define BASE_SIMPLIFIER_H_ - -#include "ast/expr_map.h" -#include "ast/ast_pp.h" - -/** - \brief Implements basic functionality used by expression simplifiers. -*/ -class base_simplifier { -protected: - ast_manager & m; - expr_map m_cache; - ptr_vector m_todo; - - void cache_result(expr * n, expr * r, proof * p) { - m_cache.insert(n, r, p); - CTRACE("simplifier", !is_rewrite_proof(n, r, p), - tout << mk_pp(n, m) << "\n"; - tout << mk_pp(r, m) << "\n"; - tout << mk_pp(p, m) << "\n";); - SASSERT(is_rewrite_proof(n, r, p)); - } - void reset_cache() { m_cache.reset(); } - void flush_cache() { m_cache.flush(); } - void get_cached(expr * n, expr * & r, proof * & p) const { m_cache.get(n, r, p); } - - void reinitialize() { m_cache.set_store_proofs(m.fine_grain_proofs()); } - - - void visit(expr * n, bool & visited) { - if (!is_cached(n)) { - m_todo.push_back(n); - visited = false; - } - } - -public: - base_simplifier(ast_manager & m): - m(m), - m_cache(m, m.fine_grain_proofs()) { - } - bool is_cached(expr * n) const { return m_cache.contains(n); } - ast_manager & get_manager() { return m; } - - bool is_rewrite_proof(expr* n, expr* r, proof* p) { - if (p && - !m.is_undef_proof(p) && - !(m.has_fact(p) && - (m.is_eq(m.get_fact(p)) || m.is_oeq(m.get_fact(p)) || m.is_iff(m.get_fact(p))) && - to_app(m.get_fact(p))->get_arg(0) == n && - to_app(m.get_fact(p))->get_arg(1) == r)) return false; - - return (!m.fine_grain_proofs() || p || (n == r)); - } -}; - -#endif /* BASE_SIMPLIFIER_H_ */ diff --git a/src/ast/simplifier/basic_simplifier_plugin.cpp b/src/ast/simplifier/basic_simplifier_plugin.cpp deleted file mode 100644 index be51bc291..000000000 --- a/src/ast/simplifier/basic_simplifier_plugin.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - basic_simplifier_plugin.cpp - -Abstract: - - Simplifier for the basic family. - -Author: - - Leonardo (leonardo) 2008-01-07 - ---*/ -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/ast_ll_pp.h" -#include "ast/rewriter/bool_rewriter.h" - -basic_simplifier_plugin::basic_simplifier_plugin(ast_manager & m): - simplifier_plugin(symbol("basic"), m), - m_rewriter(alloc(bool_rewriter, m)) { -} - -basic_simplifier_plugin::~basic_simplifier_plugin() { - dealloc(m_rewriter); -} - -bool basic_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - SASSERT(f->get_family_id() == m_manager.get_basic_family_id()); - basic_op_kind k = static_cast(f->get_decl_kind()); - switch (k) { - case OP_FALSE: - case OP_TRUE: - return false; - case OP_EQ: - SASSERT(num_args == 2); - mk_eq(args[0], args[1], result); - return true; - case OP_DISTINCT: - mk_distinct(num_args, args, result); - return true; - case OP_ITE: - SASSERT(num_args == 3); - mk_ite(args[0], args[1], args[2], result); - return true; - case OP_AND: - mk_and(num_args, args, result); - return true; - case OP_OR: - mk_or(num_args, args, result); - return true; - case OP_IMPLIES: - mk_implies(args[0], args[1], result); - return true; - case OP_IFF: - mk_iff(args[0], args[1], result); - return true; - case OP_XOR: - switch (num_args) { - case 0: result = m_manager.mk_true(); break; - case 1: result = args[0]; break; - case 2: mk_xor(args[0], args[1], result); break; - default: UNREACHABLE(); break; - } - return true; - case OP_NOT: - SASSERT(num_args == 1); - mk_not(args[0], result); - return true; - default: - UNREACHABLE(); - return false; - } -} - -/** - \brief Return true if \c rhs is of the form (ite c t1 t2) and are_distinct(lhs, t1) and are_distinct(lhs, t2). -*/ -static bool is_lhs_diseq_rhs_ite_branches(ast_manager & m, expr * lhs, expr * rhs) { - return m.is_ite(rhs) && m.are_distinct(lhs, to_app(rhs)->get_arg(1)) && m.are_distinct(lhs, to_app(rhs)->get_arg(2)); -} - -/** - \brief Return true if \c rhs is of the form (ite c t1 t2) and lhs = t1 && are_distinct(lhs, t2) -*/ -static bool is_lhs_eq_rhs_ite_then(ast_manager & m, expr * lhs, expr * rhs) { - return m.is_ite(rhs) && lhs == to_app(rhs)->get_arg(1) && m.are_distinct(lhs, to_app(rhs)->get_arg(2)); -} - -/** - \brief Return true if \c rhs is of the form (ite c t1 t2) and are_distinct(lhs,t1) && lhs = t2 -*/ -static bool is_lhs_eq_rhs_ite_else(ast_manager & m, expr * lhs, expr * rhs) { - return m.is_ite(rhs) && lhs == to_app(rhs)->get_arg(2) && m.are_distinct(lhs, to_app(rhs)->get_arg(1)); -} - -void basic_simplifier_plugin::mk_eq(expr * lhs, expr * rhs, expr_ref & result) { - // (= t1 (ite C t2 t3)) --> false if are_distinct(t1, t2) && are_distinct(t1, t3) - if (is_lhs_diseq_rhs_ite_branches(m_manager, lhs, rhs) || is_lhs_diseq_rhs_ite_branches(m_manager, rhs, lhs)) { - result = m_manager.mk_false(); - } - // (= t1 (ite C t2 t3)) --> C if t1 = t2 && are_distinct(t1, t3) - else if (is_lhs_eq_rhs_ite_then(m_manager, lhs, rhs)) { - result = to_app(rhs)->get_arg(0); - } - // (= t1 (ite C t2 t3)) --> C if t1 = t2 && are_distinct(t1, t3) - else if (is_lhs_eq_rhs_ite_then(m_manager, rhs, lhs)) { - result = to_app(lhs)->get_arg(0); - } - // (= t1 (ite C t2 t3)) --> (not C) if t1 = t3 && are_distinct(t1, t2) - else if (is_lhs_eq_rhs_ite_else(m_manager, lhs, rhs)) { - mk_not(to_app(rhs)->get_arg(0), result); - } - // (= t1 (ite C t2 t3)) --> (not C) if t1 = t3 && are_distinct(t1, t2) - else if (is_lhs_eq_rhs_ite_else(m_manager, rhs, lhs)) { - mk_not(to_app(lhs)->get_arg(0), result); - } - else { - m_rewriter->mk_eq(lhs, rhs, result); - } -} - -bool basic_simplifier_plugin::eliminate_and() const { return m_rewriter->elim_and(); } -void basic_simplifier_plugin::set_eliminate_and(bool f) { m_rewriter->set_elim_and(f); } -void basic_simplifier_plugin::mk_iff(expr * lhs, expr * rhs, expr_ref & result) { mk_eq(lhs, rhs, result); } -void basic_simplifier_plugin::mk_xor(expr * lhs, expr * rhs, expr_ref & result) { m_rewriter->mk_xor(lhs, rhs, result); } -void basic_simplifier_plugin::mk_implies(expr * lhs, expr * rhs, expr_ref & result) { m_rewriter->mk_implies(lhs, rhs, result); } -void basic_simplifier_plugin::mk_ite(expr * c, expr * t, expr * e, expr_ref & result) { m_rewriter->mk_ite(c, t, e, result); } -void basic_simplifier_plugin::mk_and(unsigned num_args, expr * const * args, expr_ref & result) { m_rewriter->mk_and(num_args, args, result); } -void basic_simplifier_plugin::mk_or(unsigned num_args, expr * const * args, expr_ref & result) { m_rewriter->mk_or(num_args, args, result); } -void basic_simplifier_plugin::mk_and(expr * arg1, expr * arg2, expr_ref & result) { m_rewriter->mk_and(arg1, arg2, result); } -void basic_simplifier_plugin::mk_or(expr * arg1, expr * arg2, expr_ref & result) { m_rewriter->mk_or(arg1, arg2, result); } -void basic_simplifier_plugin::mk_and(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { m_rewriter->mk_and(arg1, arg2, arg3, result); } -void basic_simplifier_plugin::mk_or(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { m_rewriter->mk_or(arg1, arg2, arg3, result); } -void basic_simplifier_plugin::mk_nand(unsigned num_args, expr * const * args, expr_ref & result) { m_rewriter->mk_nand(num_args, args, result); } -void basic_simplifier_plugin::mk_nor(unsigned num_args, expr * const * args, expr_ref & result) { m_rewriter->mk_nor(num_args, args, result); } -void basic_simplifier_plugin::mk_nand(expr * arg1, expr * arg2, expr_ref & result) { m_rewriter->mk_nand(arg1, arg2, result); } -void basic_simplifier_plugin::mk_nor(expr * arg1, expr * arg2, expr_ref & result) { m_rewriter->mk_nor(arg1, arg2, result); } -void basic_simplifier_plugin::mk_distinct(unsigned num_args, expr * const * args, expr_ref & result) { m_rewriter->mk_distinct(num_args, args, result); } -void basic_simplifier_plugin::mk_not(expr * n, expr_ref & result) { m_rewriter->mk_not(n, result); } - -void basic_simplifier_plugin::enable_ac_support(bool flag) { - m_rewriter->set_flat(flag); -} diff --git a/src/ast/simplifier/basic_simplifier_plugin.h b/src/ast/simplifier/basic_simplifier_plugin.h deleted file mode 100644 index f28a19b56..000000000 --- a/src/ast/simplifier/basic_simplifier_plugin.h +++ /dev/null @@ -1,78 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - basic_simplifier_plugin.h - -Abstract: - - Simplifier for the basic family. - -Author: - - Leonardo (leonardo) 2008-01-07 - ---*/ -#ifndef BASIC_SIMPLIFIER_PLUGIN_H_ -#define BASIC_SIMPLIFIER_PLUGIN_H_ - -#include "ast/simplifier/simplifier_plugin.h" - -class bool_rewriter; - -/** - \brief Simplifier for the basic family. -*/ -class basic_simplifier_plugin : public simplifier_plugin { - bool_rewriter * m_rewriter; -public: - basic_simplifier_plugin(ast_manager & m); - virtual ~basic_simplifier_plugin(); - bool_rewriter & get_rewriter() { return *m_rewriter; } - bool eliminate_and() const; - void set_eliminate_and(bool f); - void mk_eq(expr * lhs, expr * rhs, expr_ref & result); - void mk_iff(expr * lhs, expr * rhs, expr_ref & result); - void mk_xor(expr * lhs, expr * rhs, expr_ref & result); - void mk_implies(expr * lhs, expr * rhs, expr_ref & result); - void mk_ite(expr * c, expr * t, expr * e, expr_ref & result); - void mk_and(unsigned num_args, expr * const * args, expr_ref & result); - void mk_or(unsigned num_args, expr * const * args, expr_ref & result); - void mk_and(expr * arg1, expr * arg2, expr_ref & result); - void mk_or(expr * arg1, expr * arg2, expr_ref & result); - void mk_and(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); - void mk_or(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); - void mk_nand(unsigned num_args, expr * const * args, expr_ref & result); - void mk_nor(unsigned num_args, expr * const * args, expr_ref & result); - void mk_nand(expr * arg1, expr * arg2, expr_ref & result); - void mk_nor(expr * arg1, expr * arg2, expr_ref & result); - void mk_distinct(unsigned num_args, expr * const * args, expr_ref & result); - void mk_not(expr * n, expr_ref & result); - virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); - virtual void enable_ac_support(bool flag); -}; - -/** - \brief Functor that compares expressions, but puts the expressions e and f(e) close to each other, where - f is in family m_fid, and has kind m_dkind; -*/ -struct expr_lt_proc { - family_id m_fid; - decl_kind m_dkind; - - expr_lt_proc(family_id fid = null_family_id, decl_kind k = null_decl_kind):m_fid(fid), m_dkind(k) {} - - unsigned get_id(expr * n) const { - if (m_fid != null_family_id && is_app_of(n, m_fid, m_dkind)) - return (to_app(n)->get_arg(0)->get_id() << 1) + 1; - else - return n->get_id() << 1; - } - - bool operator()(expr * n1, expr * n2) const { - return get_id(n1) < get_id(n2); - } -}; - -#endif /* BASIC_SIMPLIFIER_PLUGIN_H_ */ diff --git a/src/ast/simplifier/bv_elim.cpp b/src/ast/simplifier/bv_elim.cpp deleted file mode 100644 index 1c0048a07..000000000 --- a/src/ast/simplifier/bv_elim.cpp +++ /dev/null @@ -1,119 +0,0 @@ - -/*++ -Copyright (c) 2015 Microsoft Corporation - ---*/ - -#include "ast/simplifier/bv_elim.h" -#include "ast/bv_decl_plugin.h" -#include "ast/rewriter/var_subst.h" -#include - -void bv_elim::elim(quantifier* q, quantifier_ref& r) { - - svector names, _names; - sort_ref_buffer sorts(m), _sorts(m); - expr_ref_buffer pats(m); - expr_ref_buffer no_pats(m); - expr_ref_buffer subst_map(m), _subst_map(m); - var_subst subst(m); - bv_util bv(m); - expr_ref new_body(m); - expr* old_body = q->get_expr(); - unsigned num_decls = q->get_num_decls(); - family_id bfid = m.mk_family_id("bv"); - - // - // Traverse sequence of bound variables to eliminate - // bit-vecctor variables and replace them by - // Booleans. - // - unsigned var_idx = 0; - for (unsigned i = num_decls; i > 0; ) { - --i; - sort* s = q->get_decl_sort(i); - symbol nm = q->get_decl_name(i); - - if (bv.is_bv_sort(s)) { - // convert n-bit bit-vector variable into sequence of n-Booleans. - unsigned num_bits = bv.get_bv_size(s); - expr_ref_buffer args(m); - expr_ref bv(m); - for (unsigned j = 0; j < num_bits; ++j) { - std::ostringstream new_name; - new_name << nm.str(); - new_name << "_"; - new_name << j; - var* v = m.mk_var(var_idx++, m.mk_bool_sort()); - args.push_back(v); - _sorts.push_back(m.mk_bool_sort()); - _names.push_back(symbol(new_name.str().c_str())); - } - bv = m.mk_app(bfid, OP_MKBV, 0, 0, args.size(), args.c_ptr()); - _subst_map.push_back(bv.get()); - } - else { - _subst_map.push_back(m.mk_var(var_idx++, s)); - _sorts.push_back(s); - _names.push_back(nm); - } - } - // - // reverse the vectors. - // - SASSERT(_names.size() == _sorts.size()); - for (unsigned i = _names.size(); i > 0; ) { - --i; - names.push_back(_names[i]); - sorts.push_back(_sorts[i]); - } - for (unsigned i = _subst_map.size(); i > 0; ) { - --i; - subst_map.push_back(_subst_map[i]); - } - - expr* const* sub = subst_map.c_ptr(); - unsigned sub_size = subst_map.size(); - - subst(old_body, sub_size, sub, new_body); - - for (unsigned j = 0; j < q->get_num_patterns(); j++) { - expr_ref pat(m); - subst(q->get_pattern(j), sub_size, sub, pat); - pats.push_back(pat); - } - for (unsigned j = 0; j < q->get_num_no_patterns(); j++) { - expr_ref nopat(m); - subst(q->get_no_pattern(j), sub_size, sub, nopat); - no_pats.push_back(nopat); - } - - r = m.mk_quantifier(true, - names.size(), - sorts.c_ptr(), - names.c_ptr(), - new_body.get(), - q->get_weight(), - q->get_qid(), - q->get_skid(), - pats.size(), pats.c_ptr(), - no_pats.size(), no_pats.c_ptr()); -} - -bool bv_elim_star::visit_quantifier(quantifier* q) { - // behave like destructive resolution, do not recurse. - return true; -} - -void bv_elim_star::reduce1_quantifier(quantifier* q) { - quantifier_ref r(m); - proof_ref pr(m); - m_bv_elim.elim(q, r); - if (m.fine_grain_proofs()) { - pr = m.mk_rewrite(q, r.get()); - } - else { - pr = 0; - } - cache_result(q, r, pr); -} diff --git a/src/ast/simplifier/bv_elim.h b/src/ast/simplifier/bv_elim.h deleted file mode 100644 index c027b1a9e..000000000 --- a/src/ast/simplifier/bv_elim.h +++ /dev/null @@ -1,45 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - bv_elim.h - -Abstract: - - Eliminate bit-vectors variables from clauses, by - replacing them by bound Boolean variables. - -Author: - - Nikolaj Bjorner (nbjorner) 2008-12-16. - -Revision History: - ---*/ -#ifndef BV_ELIM_H_ -#define BV_ELIM_H_ - -#include "ast/ast.h" -#include "ast/simplifier/simplifier.h" - -class bv_elim { - ast_manager& m; -public: - bv_elim(ast_manager& m) : m(m) {}; - - void elim(quantifier* q, quantifier_ref& r); -}; - -class bv_elim_star : public simplifier { -protected: - bv_elim m_bv_elim; - virtual bool visit_quantifier(quantifier* q); - virtual void reduce1_quantifier(quantifier* q); -public: - bv_elim_star(ast_manager& m) : simplifier(m), m_bv_elim(m) { enable_ac_support(false); } - virtual ~bv_elim_star() {} -}; - -#endif /* BV_ELIM_H_ */ - diff --git a/src/ast/simplifier/bv_simplifier_params.cpp b/src/ast/simplifier/bv_simplifier_params.cpp deleted file mode 100644 index 07f854179..000000000 --- a/src/ast/simplifier/bv_simplifier_params.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - bv_simplifier_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2012-12-02. - -Revision History: - ---*/ -#include "ast/simplifier/bv_simplifier_params.h" -#include "ast/simplifier/bv_simplifier_params_helper.hpp" -#include "ast/rewriter/bv_rewriter_params.hpp" - -void bv_simplifier_params::updt_params(params_ref const & _p) { - bv_simplifier_params_helper p(_p); - bv_rewriter_params rp(_p); - m_hi_div0 = rp.hi_div0(); - m_bv2int_distribute = p.bv_bv2int_distribute(); - -} - -#define DISPLAY_PARAM(X) out << #X"=" << X << std::endl; - -void bv_simplifier_params::display(std::ostream & out) const { - DISPLAY_PARAM(m_hi_div0); - DISPLAY_PARAM(m_bv2int_distribute); -} diff --git a/src/ast/simplifier/bv_simplifier_params.h b/src/ast/simplifier/bv_simplifier_params.h deleted file mode 100644 index 8c0792203..000000000 --- a/src/ast/simplifier/bv_simplifier_params.h +++ /dev/null @@ -1,38 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - bv_simplifier_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-10-10. - -Revision History: - ---*/ -#ifndef BV_SIMPLIFIER_PARAMS_H_ -#define BV_SIMPLIFIER_PARAMS_H_ - -#include "util/params.h" - -struct bv_simplifier_params { - bool m_hi_div0; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted. - bool m_bv2int_distribute; //!< if true allows downward propagation of bv2int. - - bv_simplifier_params(params_ref const & p = params_ref()) { - updt_params(p); - } - - void updt_params(params_ref const & _p); - - void display(std::ostream & out) const; -}; - -#endif /* BV_SIMPLIFIER_PARAMS_H_ */ - diff --git a/src/ast/simplifier/bv_simplifier_params_helper.pyg b/src/ast/simplifier/bv_simplifier_params_helper.pyg deleted file mode 100644 index 6bcf83207..000000000 --- a/src/ast/simplifier/bv_simplifier_params_helper.pyg +++ /dev/null @@ -1,4 +0,0 @@ -def_module_params(class_name='bv_simplifier_params_helper', - module_name="old_simplify", # Parameters will be in the old_simplify module - export=True, - params=(('bv.bv2int_distribute', BOOL, True, 'if true, then int2bv is distributed over arithmetical operators'),)) diff --git a/src/ast/simplifier/bv_simplifier_plugin.cpp b/src/ast/simplifier/bv_simplifier_plugin.cpp deleted file mode 100644 index c23d2e748..000000000 --- a/src/ast/simplifier/bv_simplifier_plugin.cpp +++ /dev/null @@ -1,2261 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - bv_simplifier_plugin.cpp - -Abstract: - - Simplifier for the bv family. - -Author: - - Leonardo (leonardo) 2008-01-08 - Nikolaj Bjorner (nbjorner) 2008-01-05 - ---*/ -#include "ast/simplifier/bv_simplifier_plugin.h" -#include "ast/ast_ll_pp.h" -#include "ast/ast_pp.h" -#include "ast/arith_decl_plugin.h" -#include "util/obj_hashtable.h" -#include "ast/ast_util.h" - -bv_simplifier_plugin::~bv_simplifier_plugin() { - flush_caches(); -} - -bv_simplifier_plugin::bv_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b, bv_simplifier_params & p): - poly_simplifier_plugin(symbol("bv"), m, OP_BADD, OP_BMUL, OP_BNEG, OP_BSUB, OP_BV_NUM), - m_manager(m), - m_util(m), - m_arith(m), - m_bsimp(b), - m_params(p), - m_zeros(m) { -} - -rational bv_simplifier_plugin::norm(const numeral & n) { - unsigned bv_size = get_bv_size(m_curr_sort); - return norm(n, bv_size, false); -} - - -bool bv_simplifier_plugin::is_numeral(expr * n, rational & val) const { - unsigned bv_size; - return m_util.is_numeral(n, val, bv_size); -} - -expr * bv_simplifier_plugin::get_zero(sort * s) const { - bv_simplifier_plugin * _this = const_cast(this); - unsigned bv_size = _this->get_bv_size(s); - if (bv_size >= m_zeros.size()) - _this->m_zeros.resize(bv_size+1); - if (m_zeros.get(bv_size) == 0) - _this->m_zeros.set(bv_size, _this->m_util.mk_numeral(rational(0), s)); - return m_zeros.get(bv_size); -} - -bool bv_simplifier_plugin::are_numerals(unsigned num_args, expr * const* args, unsigned& bv_size) { - numeral r; - if (num_args == 0) { - return false; - } - for (unsigned i = 0; i < num_args; ++i) { - if (!m_util.is_numeral(args[i], r, bv_size)) { - return false; - } - } - return true; -} - -app * bv_simplifier_plugin::mk_numeral(numeral const & n) { - unsigned bv_size = get_bv_size(m_curr_sort); - return mk_numeral(n, bv_size); -} - -app * bv_simplifier_plugin::mk_numeral(numeral const& n, unsigned bv_size) { - numeral r = mod(n, rational::power_of_two(bv_size)); - SASSERT(!r.is_neg()); - SASSERT(r < rational::power_of_two(bv_size)); - return m_util.mk_numeral(r, bv_size); -} - -bool bv_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - - SASSERT(f->get_family_id() == m_fid); - - bv_op_kind k = static_cast(f->get_decl_kind()); - switch (k) { - case OP_BV_NUM: SASSERT(num_args == 0); result = mk_numeral(f->get_parameter(0).get_rational(), f->get_parameter(1).get_int()); break; - case OP_BIT0: SASSERT(num_args == 0); result = mk_numeral(0, 1); break; - case OP_BIT1: SASSERT(num_args == 0); result = mk_numeral(1, 1); break; - case OP_BADD: SASSERT(num_args > 0); - mk_add(num_args, args, result); - TRACE("bv_add_bug", - for (unsigned i = 0; i < num_args; i++) tout << mk_bounded_pp(args[i], m_manager, 10) << "\n"; - tout << mk_bounded_pp(result, m_manager, 10) << "\n";); - mk_add_concat(result); - break; - case OP_BSUB: SASSERT(num_args > 0); mk_sub(num_args, args, result); break; - case OP_BNEG: SASSERT(num_args == 1); mk_uminus(args[0], result); break; - case OP_BMUL: SASSERT(num_args > 0); mk_mul(num_args, args, result); break; - case OP_ULEQ: if (m_presimp) return false; SASSERT(num_args == 2); mk_ule(args[0], args[1], result); break; - case OP_UGEQ: if (m_presimp) return false; SASSERT(num_args == 2); mk_ule(args[1], args[0], result); break; - case OP_ULT: if (m_presimp) return false; SASSERT(num_args == 2); mk_ult(args[0], args[1], result); break; - case OP_UGT: if (m_presimp) return false; SASSERT(num_args == 2); mk_ult(args[1], args[0], result); break; - case OP_SLEQ: if (m_presimp) return false; SASSERT(num_args == 2); mk_sle(args[0], args[1], result); break; - case OP_SGEQ: if (m_presimp) return false; SASSERT(num_args == 2); mk_sle(args[1], args[0], result); break; - case OP_SLT: if (m_presimp) return false; SASSERT(num_args == 2); mk_slt(args[0], args[1], result); break; - case OP_SGT: if (m_presimp) return false; SASSERT(num_args == 2); mk_slt(args[1], args[0], result); break; - case OP_BAND: SASSERT(num_args > 0); mk_bv_and(num_args, args, result); break; - case OP_BOR: SASSERT(num_args > 0); mk_bv_or(num_args, args, result); break; - case OP_BNOT: SASSERT(num_args == 1); mk_bv_not(args[0], result); break; - case OP_BXOR: SASSERT(num_args > 0); mk_bv_xor(num_args, args, result); break; - case OP_CONCAT: SASSERT(num_args > 0); mk_concat(num_args, args, result); break; - case OP_ZERO_EXT: - SASSERT(num_args == 1); SASSERT(f->get_num_parameters() == 1); - mk_zeroext(f->get_parameter(0).get_int(), args[0], result); - break; - case OP_EXTRACT: - SASSERT(num_args == 1); SASSERT(f->get_num_parameters() == 2); - mk_extract(f->get_parameter(0).get_int(), f->get_parameter(1).get_int(), args[0], result); - break; - case OP_REPEAT: - SASSERT(num_args == 1); SASSERT(f->get_num_parameters() == 1); - mk_repeat(f->get_parameter(0).get_int(), args[0], result); - break; - case OP_BUREM: - SASSERT(num_args == 2); - mk_bv_urem(args[0], args[1], result); - break; - case OP_SIGN_EXT: - SASSERT(num_args == 1); SASSERT(f->get_num_parameters() == 1); - mk_sign_extend(f->get_parameter(0).get_int(), args[0], result); - break; - case OP_BSHL: SASSERT(num_args == 2); mk_bv_shl(args[0], args[1], result); break; - case OP_BLSHR: SASSERT(num_args == 2); mk_bv_lshr(args[0], args[1], result); break; - case OP_INT2BV: SASSERT(num_args == 1); mk_int2bv(args[0], f->get_range(), result); break; - case OP_BV2INT: SASSERT(num_args == 1); mk_bv2int(args[0], f->get_range(), result); break; - case OP_BSDIV: SASSERT(num_args == 2); mk_bv_sdiv(args[0], args[1], result); break; - case OP_BUDIV: SASSERT(num_args == 2); mk_bv_udiv(args[0], args[1], result); break; - case OP_BSREM: SASSERT(num_args == 2); mk_bv_srem(args[0], args[1], result); break; - case OP_BSMOD: SASSERT(num_args == 2); mk_bv_smod(args[0], args[1], result); break; - case OP_BNAND: SASSERT(num_args > 0); mk_bv_nand(num_args, args, result); break; - case OP_BNOR: SASSERT(num_args > 0); mk_bv_nor(num_args, args, result); break; - case OP_BXNOR: SASSERT(num_args > 0); mk_bv_xnor(num_args, args, result); break; - case OP_ROTATE_LEFT: SASSERT(num_args == 1); mk_bv_rotate_left(f, args[0], result); break; - case OP_ROTATE_RIGHT: SASSERT(num_args == 1); mk_bv_rotate_right(f, args[0], result); break; - case OP_EXT_ROTATE_LEFT: SASSERT(num_args == 2); mk_bv_ext_rotate_left(args[0], args[1], result); break; - case OP_EXT_ROTATE_RIGHT: SASSERT(num_args == 2); mk_bv_ext_rotate_right(args[0], args[1], result); break; - case OP_BREDOR: SASSERT(num_args == 1); mk_bv_redor(args[0], result); break; - case OP_BREDAND: SASSERT(num_args == 1); mk_bv_redand(args[0], result); break; - case OP_BCOMP: SASSERT(num_args == 2); mk_bv_comp(args[0], args[1], result); break; - case OP_BASHR: SASSERT(num_args == 2); mk_bv_ashr(args[0], args[1], result); break; - case OP_BSDIV_I: SASSERT(num_args == 2); mk_bv_sdiv_i(args[0], args[1], result); break; - case OP_BUDIV_I: SASSERT(num_args == 2); mk_bv_udiv_i(args[0], args[1], result); break; - case OP_BSREM_I: SASSERT(num_args == 2); mk_bv_srem_i(args[0], args[1], result); break; - case OP_BUREM_I: SASSERT(num_args == 2); mk_bv_urem_i(args[0], args[1], result); break; - case OP_BSMOD_I: SASSERT(num_args == 2); mk_bv_smod_i(args[0], args[1], result); break; - case OP_BSDIV0: - case OP_BUDIV0: - case OP_BSREM0: - case OP_BUREM0: - case OP_BSMOD0: - case OP_BIT2BOOL: - case OP_CARRY: - case OP_XOR3: - case OP_MKBV: - case OP_BUMUL_NO_OVFL: - case OP_BSMUL_NO_OVFL: - case OP_BSMUL_NO_UDFL: - result = m_manager.mk_app(f, num_args, args); - break; - default: - UNREACHABLE(); - break; - } - SASSERT(result.get()); - - TRACE("bv_simplifier", - tout << mk_pp(f, m_manager) << "\n"; - for (unsigned i = 0; i < num_args; ++i) { - tout << mk_pp(args[i], m_manager) << " "; - } - tout << "\n"; - tout << mk_pp(result.get(), m_manager) << "\n"; - ); - - return true; -} - -bool bv_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { - set_reduce_invoked(); - - if (m_presimp) - return false; - expr_ref tmp(m_manager); - tmp = m_manager.mk_eq(lhs,rhs); - mk_bv_eq(lhs, rhs, result); - return result.get() != tmp.get(); -} - -bool bv_simplifier_plugin::reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - - return false; -} - -void bv_simplifier_plugin::flush_caches() { - TRACE("extract_cache", tout << "flushing extract cache...\n";); - extract_cache::iterator it = m_extract_cache.begin(); - extract_cache::iterator end = m_extract_cache.end(); - for (; it != end; ++it) { - extract_entry & e = (*it).m_key; - m_manager.dec_ref(e.m_arg); - m_manager.dec_ref((*it).m_value); - } - m_extract_cache.reset(); -} - - -inline uint64 bv_simplifier_plugin::to_uint64(const numeral & n, unsigned bv_size) { - SASSERT(bv_size <= 64); - numeral tmp = n; - if (tmp.is_neg()) { - tmp = mod(tmp, rational::power_of_two(bv_size)); - } - SASSERT(tmp.is_nonneg()); - SASSERT(tmp.is_uint64()); - return tmp.get_uint64(); -} - -#define MK_BV_OP(_oper_,_binop_) \ -rational bv_simplifier_plugin::mk_bv_ ## _oper_(numeral const& a0, numeral const& b0, unsigned sz) { \ - rational r(0), a(a0), b(b0); \ - numeral p64 = rational::power_of_two(64); \ - numeral mul(1); \ - while (sz > 0) { \ - numeral a1 = a % p64; \ - numeral b1 = b % p64; \ - uint64 u = a1.get_uint64() _binop_ b1.get_uint64(); \ - if (sz < 64) { \ - uint64 mask = shift_left(1ull,(uint64)sz) - 1ull; \ - u = mask & u; \ - } \ - r += mul*rational(u,rational::ui64()); \ - mul *= p64; \ - a = div(a, p64); \ - b = div(b, p64); \ - sz -= (sz<64)?sz:64; \ - } \ - return r; \ -} - -MK_BV_OP(and,&) -MK_BV_OP(or,|) -MK_BV_OP(xor,^) - -rational bv_simplifier_plugin::mk_bv_not(numeral const& a0, unsigned sz) { - rational r(0), a(a0), mul(1); - numeral p64 = rational::power_of_two(64); - while (sz > 0) { - numeral a1 = a % p64; - uint64 u = ~a1.get_uint64(); - if (sz < 64) { - uint64 mask = shift_left(1ull,(uint64)sz) - 1ull; - u = mask & u; - } - r += mul*rational(u,rational::ui64()); - mul *= p64; - a = div(a, p64); - sz -= (64get_num_args() == 2) { - // - // c <=_u (concat 0 a) <=> c[u:l] = 0 && c[l-1:0] <=_u a - // - app* app = to_app(arg2); - expr * arg2_1 = app->get_arg(0); - expr * arg2_2 = app->get_arg(1); - if (m_util.is_zero(arg2_1)) { - unsigned sz1 = get_bv_size(arg2_1); - unsigned sz2 = get_bv_size(arg2_2); - - expr_ref tmp1(m_manager); - expr_ref tmp2(m_manager); - mk_extract(sz2 + sz1 - 1, sz2, arg1, tmp1); - mk_extract(sz2 - 1, 0, arg1, tmp2); - - expr_ref eq(m_manager); - expr_ref zero(m_manager); - zero = mk_bv0(sz1); - mk_bv_eq(tmp1.get(), zero, eq); - - expr_ref ineq(m_manager); - ineq = m_util.mk_ule(tmp2.get(), arg2_2); - - m_bsimp.mk_and(eq.get(), ineq.get(), result); - return; - } - } - - // - // TODO: - // Others: - // - // k <=_s (concat 0 a) <=> (k[u:l] = 0 && k[l-1:0] <=_u a) || k[u:u] = bv1 - // - // (concat 0 a) <=_s k <=> k[u:u] = bv0 && (k[u:l] != 0 || a <=_u k[l-1:0]) - // - // (concat 0 a) <=_u k <=> k[u:l] != 0 || a <=_u k[l-1:0] - // - - result = m_manager.mk_app(m_fid, k, arg1, arg2); -} - -void bv_simplifier_plugin::mk_extract(unsigned high, unsigned low, expr* arg, expr_ref& result) { - - unsigned arg_sz = get_bv_size(arg); - unsigned sz = high - low + 1; - TRACE("bv_simplifier_plugin", tout << "mk_extract [" << high << ":" << low << "]\n"; - tout << "arg_sz: " << arg_sz << " sz: " << sz << "\n"; - tout << "arg:\n"; - ast_ll_pp(tout, m_manager, arg);); - - if (arg_sz == sz) { - result = arg; - } - else { - mk_extract_core(high, low, arg, result); - } - if (m_extract_cache.size() > (1 << 12)) { - flush_caches(); - } - - TRACE("bv_simplifier_plugin", tout << "mk_extract [" << high << ":" << low << "]\n"; - tout << "arg_sz: " << arg_sz << " sz: " << sz << "\n"; - tout << "arg:\n"; - ast_ll_pp(tout, m_manager, arg); - tout << "=====================>\n"; - ast_ll_pp(tout, m_manager, result.get());); -} - - -void bv_simplifier_plugin::cache_extract(unsigned h, unsigned l, expr * arg, expr * result) { - m_manager.inc_ref(arg); - m_manager.inc_ref(result); - m_extract_cache.insert(extract_entry(h, l, arg), result); -} - -expr* bv_simplifier_plugin::get_cached_extract(unsigned h, unsigned l, expr * arg) { - expr * result = 0; - if (m_extract_cache.find(extract_entry(h, l, arg), result)) { - return result; - } - return 0; -} - - -void bv_simplifier_plugin::mk_extract_core(unsigned high, unsigned low, expr * arg, expr_ref& result) { - - if (!lookup_mk_extract(high, low, arg, result)) { - while (!m_extract_args.empty()) { - unsigned low2 = m_lows.back(); - unsigned high2 = m_highs.back(); - expr* arg2 = m_extract_args.back(); - if (try_mk_extract(high2, low2, arg2, result)) { - if (!m_extract_cache.contains(extract_entry(high2, low2, arg2))) { - cache_extract(high2, low2, arg2, result.get()); - } - m_lows.pop_back(); - m_highs.pop_back(); - m_extract_args.pop_back(); - } - } - if (!lookup_mk_extract(high, low, arg, result)) { - UNREACHABLE(); - } - } -} - - -bool bv_simplifier_plugin::lookup_mk_extract(unsigned high, unsigned low, expr * arg, expr_ref& result) { - expr* cached_result = get_cached_extract(high, low, arg); - if (cached_result) { - result = cached_result; - return true; - } - - m_extract_args.push_back(arg); - m_lows.push_back(low); - m_highs.push_back(high); - return false; -} - - -bool bv_simplifier_plugin::try_mk_extract(unsigned high, unsigned low, expr * arg, expr_ref& result) { - - SASSERT(low <= high); - unsigned arg_sz = get_bv_size(arg); - unsigned sz = high - low + 1; - numeral r; - unsigned num_bits; - - if (arg_sz == sz) { - result = arg; - return true; - } - - expr* cached_result = get_cached_extract(high, low, arg); - if (cached_result) { - result = cached_result; - return true; - } - - if (!is_app(arg)) { - result = m_util.mk_extract(high, low, arg); - return true; - } - app* a = to_app(arg); - - if (m_util.is_numeral(a, r, num_bits)) { - if (r.is_neg()) { - r = mod(r, rational::power_of_two(sz)); - } - SASSERT(r.is_nonneg()); - if (r.is_uint64()) { - uint64 u = r.get_uint64(); - uint64 e = shift_right(u, low) & (shift_left(1ull, sz) - 1ull); - TRACE("mk_extract_bug", tout << u << "[" << high << ":" << low << "] " << e << " (u >> low): " << shift_right(u, low) << " (1ull << sz): " - << shift_left(1ull, sz) << " ((1ull << sz) - 1ull)" << (shift_left(1ull, sz) - 1ull) << "\n";); - result = mk_numeral(numeral(e, numeral::ui64()), sz); - return true; - } - result = mk_numeral(div(r, rational::power_of_two(low)), sz); - return true; - } - // (extract[high:low] (extract[high2:low2] x)) == (extract[high+low2 : low+low2] x) - else if (is_app_of(a, m_fid, OP_EXTRACT)) { - expr * x = a->get_arg(0); - unsigned low2 = a->get_decl()->get_parameter(1).get_int(); - return lookup_mk_extract(high + low2, low + low2, x, result); - } - // - // (extract[hi:lo] (bvXshr A c:bv[n])) -> (extract[hi+c:lo+c] A) - // if c < n, c <= lo <= hi < n - c - // - else if ((is_app_of(a, m_fid, OP_BASHR) || is_app_of(a, m_fid, OP_BLSHR)) && - is_numeral(a->get_arg(1), r) && r.is_unsigned()) { - unsigned c = r.get_unsigned(); - unsigned bv_size = get_bv_size(a); - if (c < bv_size && c <= low && high < bv_size - c) { - return lookup_mk_extract(high+c, low+c, a->get_arg(0), result); - } - } - // (concat a_0 ... a_{n-1}) - // Remark: the least significant bits are stored in a_{n-1} - else if (is_app_of(a, m_fid, OP_CONCAT)) { - expr_ref_buffer new_args(m_manager); - unsigned i = a->get_num_args(); - // look for first argument - while (i > 0) { - --i; - expr * a_i = a->get_arg(i); - unsigned a_sz = get_bv_size(a_i); - TRACE("extract_bug", tout << "FIRST a_sz: " << a_sz << " high: " << high << " low: " << low << "\n" << - mk_pp(a_i, m_manager) << "\n";); - if (a_sz <= low) { - low -= a_sz; - high -= a_sz; - } - else { - // found first argument - if (a_sz <= high) { - expr_ref new_arg(m_manager); - if (!lookup_mk_extract(a_sz - 1, low, a_i, new_arg)) { - return false; - } - new_args.push_back(new_arg.get()); - unsigned num_consumed_bytes = a_sz - low; - // I have to apply extract[sz - num_consumed_bytes - 1, 0] on the rest of concat - high = (sz - num_consumed_bytes - 1); - break; - } - else { - return lookup_mk_extract(high, low, a_i, result); - } - } - } - TRACE("extract_bug", tout << " high: " << high << " low: " << low << "\n";); - - // look for remaining arguments - while (i > 0) { - --i; - expr * a_i = a->get_arg(i); - unsigned a_sz = get_bv_size(a_i); - TRACE("extract_bug", tout << "SECOND a_sz: " << a_sz << " high: " << high << " " << - mk_pp( a_i, m_manager) << "\n";); - if (a_sz <= high) { - high -= a_sz; - new_args.push_back(a_i); - } - else { - // found last argument - expr_ref new_arg(m_manager); - if (!lookup_mk_extract(high, 0, a_i, new_arg)) { - return false; - } - new_args.push_back(new_arg.get()); - // The arguments in new_args are in reverse order. - ptr_buffer rev_new_args; - unsigned i = new_args.size(); - while (i > 0) { - --i; - rev_new_args.push_back(new_args[i]); - } - mk_concat(rev_new_args.size(), rev_new_args.c_ptr(), result); - return true; - } - } - UNREACHABLE(); - } - else if (is_app_of(a, m_fid, OP_SIGN_EXT)) { - SASSERT(a->get_num_args() == 1); - unsigned bv_size = get_bv_size(a->get_arg(0)); - if (high < bv_size) { - return lookup_mk_extract(high, low, a->get_arg(0), result); - } - } - else if (is_app_of(a, m_fid, OP_BAND) || - is_app_of(a, m_fid, OP_BOR) || - is_app_of(a, m_fid, OP_BXOR) || - is_app_of(a, m_fid, OP_BNOR) || - is_app_of(a, m_fid, OP_BNAND) || - is_app_of(a, m_fid, OP_BNOT) || - (low == 0 && is_app_of(a, m_fid, OP_BADD)) || - (low == 0 && is_app_of(a, m_fid, OP_BMUL)) || - (low == 0 && is_app_of(a, m_fid, OP_BSUB))) { - expr_ref_buffer new_args(m_manager); - bool all_found = true; - for (unsigned i = 0; i < a->get_num_args(); ++i) { - expr_ref new_arg(m_manager); - if (!lookup_mk_extract(high, low, a->get_arg(i), new_arg)) { - all_found = false; - } - new_args.push_back(new_arg.get()); - } - if (!all_found) { - return false; - } - // We should not use mk_app because it does not guarantee that the result would be in simplified form. - // result = m_manager.mk_app(m_fid, a->get_decl_kind(), new_args.size(), new_args.c_ptr()); - if (is_app_of(a, m_fid, OP_BAND)) - mk_bv_and(new_args.size(), new_args.c_ptr(), result); - else if (is_app_of(a, m_fid, OP_BOR)) - mk_bv_or(new_args.size(), new_args.c_ptr(), result); - else if (is_app_of(a, m_fid, OP_BXOR)) - mk_bv_xor(new_args.size(), new_args.c_ptr(), result); - else if (is_app_of(a, m_fid, OP_BNOR)) - mk_bv_nor(new_args.size(), new_args.c_ptr(), result); - else if (is_app_of(a, m_fid, OP_BNAND)) - mk_bv_nand(new_args.size(), new_args.c_ptr(), result); - else if (is_app_of(a, m_fid, OP_BNOT)) { - SASSERT(new_args.size() == 1); - mk_bv_not(new_args[0], result); - } - else if (is_app_of(a, m_fid, OP_BADD)) - mk_add(new_args.size(), new_args.c_ptr(), result); - else if (is_app_of(a, m_fid, OP_BMUL)) - mk_mul(new_args.size(), new_args.c_ptr(), result); - else if (is_app_of(a, m_fid, OP_BSUB)) - mk_sub(new_args.size(), new_args.c_ptr(), result); - else { - UNREACHABLE(); - } - return true; - } - else if (m_manager.is_ite(a)) { - expr_ref then_b(m_manager), else_b(m_manager); - bool ok = lookup_mk_extract(high, low, a->get_arg(1), then_b); - ok = lookup_mk_extract(high, low, a->get_arg(2), else_b) && ok; - if (ok) { - m_bsimp.mk_ite(a->get_arg(0), then_b.get(), else_b.get(), result); - } - return ok; - } - result = m_util.mk_extract(high, low, arg); - return true; -} - -/** - \brief Let f be the operator fid:k. Then, this function - store in result the flat args of n. If n is not an f application, then store n in result. - - Example: if n is (f (f a b) (f c (f d e))), then a b c d e are stored in result. -*/ -template -void get_assoc_args(family_id fid, decl_kind k, expr * n, T & result) { - ptr_buffer todo; - todo.push_back(n); - while (!todo.empty()) { - expr * n = todo.back(); - todo.pop_back(); - if (is_app_of(n, fid, k)) { - app * app = to_app(n); - unsigned i = app->get_num_args(); - while (i > 0) { - --i; - todo.push_back(app->get_arg(i)); - } - } - else { - result.push_back(n); - } - } -} - -/** - \brief Similar to get_assoc_args, but the arguments are stored in reverse - other in result. -*/ -template -void get_inv_assoc_args(family_id fid, decl_kind k, expr * n, T & result) { - ptr_buffer todo; - todo.push_back(n); - while (!todo.empty()) { - expr * n = todo.back(); - todo.pop_back(); - if (is_app_of(n, fid, k)) { - app * app = to_app(n); - unsigned num = app->get_num_args(); - for (unsigned i = 0; i < num; i++) - todo.push_back(app->get_arg(i)); - } - else { - result.push_back(n); - } - } -} - -void bv_simplifier_plugin::mk_bv_eq(expr* a1, expr* a2, expr_ref& result) { - - rational val1; - rational val2; - bool is_num1 = is_numeral(a1, val1); - bool is_num2 = is_numeral(a2, val2); - if (is_num1 && is_num2 && val1 != val2) { - result = m_manager.mk_false(); - return; - } - - if (!m_util.is_concat(a1) && !is_num1) { - mk_eq_core(a1, a2, result); - return; - } - if (!m_util.is_concat(a2) && !is_num2) { - mk_eq_core(a1, a2, result); - return; - } - - ptr_buffer args1, args2; - get_inv_assoc_args(m_fid, OP_CONCAT, a1, args1); - get_inv_assoc_args(m_fid, OP_CONCAT, a2, args2); - TRACE("mk_bv_eq_concat", tout << mk_ll_pp(a1, m_manager) << "\n" << mk_ll_pp(a2, m_manager) << "\n"; - tout << "args1:\n"; - for (unsigned i = 0; i < args1.size(); i++) tout << mk_ll_pp(args1[i], m_manager) << "\n"; - tout << "args2:\n"; - for (unsigned i = 0; i < args2.size(); i++) tout << mk_ll_pp(args2[i], m_manager) << "\n";); - - - - expr_ref lhs(m_manager), rhs(m_manager), eq(m_manager); - expr_ref_buffer eqs(m_manager); - unsigned low1 = 0, low2 = 0; - ptr_buffer::iterator it1 = args1.begin(); - ptr_buffer::iterator end1 = args1.end(); - ptr_buffer::iterator it2 = args2.begin(); - ptr_buffer::iterator end2 = args2.end(); - - while (it1 != end1 && it2 != end2) { - SASSERT(it1 != end1); - SASSERT(it2 != end2); - expr * arg1 = *it1; - expr * arg2 = *it2; - TRACE("expr_bv_util", tout << "low1: " << low1 << " low2: " << low2 << "\n"; - tout << mk_pp(arg1, m_manager) << "\n"; - tout << mk_pp(arg2, m_manager) << "\n";); - unsigned sz1 = get_bv_size(arg1); - unsigned sz2 = get_bv_size(arg2); - SASSERT(low1 < sz1 && low2 < sz2); - unsigned rsz1 = sz1 - low1; - unsigned rsz2 = sz2 - low2; - TRACE("expr_bv_util", tout << "rsz1: " << rsz1 << " rsz2: " << rsz2 << "\n"; - tout << mk_pp(arg1, m_manager) << "\n"; - tout << mk_pp(arg2, m_manager) << "\n";); - - if (rsz1 == rsz2) { - mk_extract(sz1 - 1, low1, arg1, lhs); - mk_extract(sz2 - 1, low2, arg2, rhs); - low1 = 0; - low2 = 0; - ++it1; - ++it2; - } - else if (rsz1 < rsz2) { - mk_extract(sz1 - 1, low1, arg1, lhs); - mk_extract(rsz1 + low2 - 1, low2, arg2, rhs); - low1 = 0; - low2 += rsz1; - ++it1; - } - else { - mk_extract(rsz2 + low1 - 1, low1, arg1, lhs); - mk_extract(sz2 - 1, low2, arg2, rhs); - low1 += rsz2; - low2 = 0; - ++it2; - } - mk_eq_core(lhs.get(), rhs.get(), eq); - eqs.push_back(eq.get()); - } - m_bsimp.mk_and(eqs.size(), eqs.c_ptr(), result); -} - -void bv_simplifier_plugin::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { - TRACE("mk_eq_core", ast_ll_pp(tout, m_manager, arg1 ); ast_ll_pp(tout, m_manager, arg2);); - if (arg1 == arg2) { - result = m_manager.mk_true(); - return; - } - if ((m_util.is_bv_and(arg1) && m_util.is_allone(arg2)) || (m_util.is_bv_or(arg1) && m_util.is_zero(arg2))) { - mk_args_eq_numeral(to_app(arg1), arg2, result); - return; - } - if ((m_util.is_bv_and(arg2) && m_util.is_allone(arg1)) || (m_util.is_bv_or(arg2) && m_util.is_zero(arg1))) { - mk_args_eq_numeral(to_app(arg2), arg1, result); - return; - } - -#if 1 - rational r; - unsigned num_bits = 0; - if (m_util.is_numeral(arg2, r, num_bits)) { - std::swap(arg1, arg2); - } - - if (m_util.is_numeral(arg1, r, num_bits) && - (m_util.is_bv_and(arg2) || m_util.is_bv_or(arg2) || m_util.is_bv_not(arg2))) { - rational two(2); - expr_ref tmp(m_manager); - expr_ref_vector tmps(m_manager); - for (unsigned i = 0; i < num_bits; ++i) { - bool is_neg = (r % two).is_zero(); - bit2bool_simplify(i, arg2, tmp); - if (is_neg) { - expr_ref tmp2(m_manager); - m_bsimp.mk_not(tmp, tmp2); - tmp = tmp2; - } - tmps.push_back(tmp); - r = div(r, two); - } - m_bsimp.mk_and(tmps.size(), tmps.c_ptr(), result); - TRACE("mk_eq_bb", - tout << mk_pp(arg1, m_manager) << "\n"; - tout << mk_pp(arg2, m_manager) << "\n"; - tout << mk_pp(result, m_manager) << "\n";); - return; - } -#endif - - if (!m_util.is_bv_add(arg1) && !m_util.is_bv_add(arg2) && - !m_util.is_bv_mul(arg1) && !m_util.is_bv_mul(arg2)) { - m_bsimp.mk_eq(arg1, arg2, result); - return; - } - - set_curr_sort(arg1); - expr_ref_vector args1(m_manager); - expr_ref_vector args2(m_manager); - get_assoc_args(m_fid, OP_BADD, arg1, args1); - get_assoc_args(m_fid, OP_BADD, arg2, args2); - TRACE("mk_eq_core", - tout << mk_pp(arg1, m_manager) << "\n" << mk_pp(arg2, m_manager) << "\n"; - tout << args1.size() << " " << args2.size() << "\n";); - - unsigned idx2 = 0; - while (idx2 < args2.size()) { - expr * m2 = args2.get(idx2); - unsigned sz1 = args1.size(); - unsigned idx1 = 0; - for (; idx1 < sz1; ++idx1) { - expr * m1 = args1.get(idx1); - if (eq_monomials_modulo_k(m1, m2)) { - expr_ref tmp(m_manager); - if (merge_monomials(true, m1, m2, tmp)) { - args1.set(idx1, tmp.get()); - } - else { - // the monomial cancelled each other. - args1.erase(idx1); - } - break; - } - } - if (idx1 == sz1) { - ++idx2; - } - else { - args2.erase(idx2); - } - } - - expr_ref lhs(m_manager); - expr_ref rhs(m_manager); - mk_sum_of_monomials(args1, lhs); - mk_sum_of_monomials(args2, rhs); - m_bsimp.mk_eq(lhs.get(), rhs.get(), result); -} - -void bv_simplifier_plugin::mk_args_eq_numeral(app * app, expr * n, expr_ref & result) { - expr_ref_buffer eqs(m_manager); - expr_ref eq(m_manager); - unsigned num = app->get_num_args(); - for (unsigned i = 0; i < num; i++) { - mk_bv_eq(app->get_arg(i), n, eq); - eqs.push_back(eq.get()); - } - m_bsimp.mk_and(eqs.size(), eqs.c_ptr(), result); -} - -void bv_simplifier_plugin::mk_concat(unsigned num_args, expr * const * args, expr_ref & result) { - TRACE("bv_simplifier_plugin", tout << "mk_concat:\n"; - for (unsigned i = 0; i < num_args; i++) ast_ll_pp(tout, m_manager, args[i]);); - unsigned shift = 0; - numeral val(0), arg_val; - for (unsigned i = num_args; i > 0; ) { - --i; - expr * arg = args[i]; - if (is_numeral(arg, arg_val)) { - arg_val *= rational::power_of_two(shift); - val += arg_val; - shift += get_bv_size(arg); - TRACE("bv_simplifier_plugin", - tout << "val: " << val << " arg_val: " << arg_val << " shift: " << shift << "\n";); - } - else { - // one of the arguments is not a number - result = m_manager.mk_app(m_fid, OP_CONCAT, num_args, args); - return; - } - } - - // all arguments are numerals - result = mk_numeral(val, shift); -} - -void bv_simplifier_plugin::mk_bv_and(unsigned num_args, expr * const* args, expr_ref & result) { - ptr_buffer flat_args; - for (unsigned i = 0; i < num_args; ++i) { - flat_args.push_back(args[i]); - } - // expr_lt_proc is a total order on expressions. - std::sort(flat_args.begin(), flat_args.end(), expr_lt_proc(m_fid, OP_BNOT)); - SASSERT(num_args > 0); - - unsigned bv_size = get_bv_size(args[0]); - - numeral allone = mk_allone(bv_size); - numeral val; - - uint64 unit = bv_size <= 64 ? to_uint64(numeral(-1), bv_size) : 0; - numeral n_unit(allone); - - expr * prev = 0; - ptr_buffer::iterator it = flat_args.begin(); - ptr_buffer::iterator it2 = it; - ptr_buffer::iterator end = flat_args.end(); - for (; it != end; ++it) { - expr* n = *it; - if (prev && - ((is_app_of(n, m_fid, OP_BNOT) && to_app(n)->get_arg(0) == prev) || - (is_app_of(prev, m_fid, OP_BNOT) && to_app(prev)->get_arg(0) == n))) { - result = mk_bv0(bv_size); - return; - } - else if (bv_size <= 64 && is_numeral(n, val)) { - unit &= to_uint64(val, bv_size); - if (unit == 0) { - result = mk_bv0(bv_size); - return; - } - } - else if (bv_size > 64 && is_numeral(n, val)) { - n_unit = mk_bv_and(val, n_unit, bv_size); - if (n_unit.is_zero()) { - result = mk_bv0(bv_size); - return; - } - } - else if (!prev || prev != n) { - *it2 = n; - prev = *it2; - ++it2; - } - } - - if (bv_size <= 64) { - n_unit = numeral(unit, numeral::ui64()); - } - - flat_args.set_end(it2); - if (n_unit != allone) { - flat_args.push_back(mk_numeral(n_unit, bv_size)); - } - - unsigned sz = flat_args.size(); - switch(sz) { - case 0: - result = mk_numeral(n_unit, bv_size); - break; - case 1: - result = flat_args.back(); - break; - default: - result = mk_list_assoc_app(m_manager, m_fid, OP_BAND, sz, flat_args.c_ptr()); - break; - } -} - -void bv_simplifier_plugin::mk_bv_or(unsigned num_args, expr * const* args, expr_ref & result) { -#if 0 - // Transformations for SAGE - // (bvor (concat 0 x) (concat y 0)) ==> (concat y x) - // (bvor (concat x 0) (concat 0 y)) ==> (concat x y) - if (num_args == 2 && - m_util.is_concat(args[0]) && - m_util.is_concat(args[1]) && - to_app(args[0])->get_num_args() == 2 && - to_app(args[1])->get_num_args() == 2) { - expr * x1 = to_app(args[0])->get_arg(0); - expr * x2 = to_app(args[0])->get_arg(1); - expr * y1 = to_app(args[1])->get_arg(0); - expr * y2 = to_app(args[1])->get_arg(1); - if (get_bv_size(x1) == get_bv_size(y1) && - get_bv_size(x2) == get_bv_size(y2)) { - if (m_util.is_zero(x1) && m_util.is_zero(y2)) { - // (bvor (concat 0 x) (concat y 0)) ==> (concat y x) - mk_concat(y1, x2, result); - return; - } - if (m_util.is_zero(x2) && m_util.is_zero(y1)) { - // (bvor (concat x 0) (concat 0 y)) ==> (concat x y) - mk_concat(x1, y2, result); - return; - } - } - } - // Investigate why it did not work. -#endif - - ptr_buffer flat_args; - for (unsigned i = 0; i < num_args; ++i) { - flat_args.push_back(args[i]); - } - std::sort(flat_args.begin(), flat_args.end(), expr_lt_proc(m_fid, OP_BNOT)); - SASSERT(num_args > 0); - - unsigned bv_size = get_bv_size(args[0]), sz; - numeral allone = mk_allone(bv_size); - numeral val; - - uint64 unit = 0; - numeral n_unit(0); - - expr * prev = 0; - ptr_buffer::iterator it = flat_args.begin(); - ptr_buffer::iterator it2 = it; - ptr_buffer::iterator end = flat_args.end(); - for (; it != end; ++it) { - expr* n = *it; - if (prev && - ((is_app_of(n, m_fid, OP_BNOT) && to_app(n)->get_arg(0) == prev) || - (is_app_of(prev, m_fid, OP_BNOT) && to_app(prev)->get_arg(0) == n))) { - result = mk_numeral(allone, bv_size); - return; - } - else if (bv_size <= 64 && is_numeral(n, val)) { - unit |= to_uint64(val, bv_size); - } - else if (bv_size > 64 && is_numeral(n, val)) { - n_unit = mk_bv_or(val, n_unit, bv_size); - } - else if (!prev || prev != n) { - *it2 = n; - prev = *it2; - ++it2; - } - } - - if (bv_size <= 64) { - n_unit = numeral(unit, numeral::ui64()); - } - - if (allone == n_unit) { - result = mk_numeral(allone, bv_size); - return; - } - - flat_args.set_end(it2); - if (!n_unit.is_zero()) { - flat_args.push_back(mk_numeral(n_unit, bv_size)); - } - - sz = flat_args.size(); - switch(sz) { - case 0: - result = mk_numeral(n_unit, bv_size); - break; - case 1: - result = flat_args.back(); - break; - default: - result = mk_list_assoc_app(m_manager, m_fid, OP_BOR, sz, flat_args.c_ptr()); - break; - } -} - -void bv_simplifier_plugin::mk_bv_xor(unsigned num_args, expr * const * args, expr_ref & result) { - ptr_buffer flat_args; - for (unsigned i = 0; i < num_args; ++i) { - flat_args.push_back(args[i]); - } - std::sort(flat_args.begin(), flat_args.end(), expr_lt_proc()); - SASSERT(num_args > 0); - - unsigned bv_size = get_bv_size(args[0]); - numeral val; - - uint64 unit = 0; - numeral n_unit(0); - - expr * prev = 0; - ptr_buffer::iterator it = flat_args.begin(); - ptr_buffer::iterator it2 = it; - ptr_buffer::iterator end = flat_args.end(); - for (; it != end; ++it) { - if (bv_size <= 64 && is_numeral(*it, val)) { - uint64 u = to_uint64(val, bv_size); - unit = u ^ unit; - } - else if (bv_size > 64 && is_numeral(*it, val)) { - n_unit = mk_bv_xor(n_unit, val, bv_size); - } - else if (prev != 0 && prev == *it) { - --it2; // remove prev - prev = 0; - } - else { - *it2 = *it; - prev = *it2; - ++it2; - } - } - flat_args.set_end(it2); - - if (bv_size <= 64) { - n_unit = numeral(numeral(unit,numeral::ui64())); - } - - if (!n_unit.is_zero()) { - flat_args.push_back(mk_numeral(n_unit, bv_size)); - } - - unsigned sz = flat_args.size(); - switch(sz) { - case 0: - result = mk_numeral(n_unit, bv_size); - break; - case 1: - result = flat_args.back(); - break; - default: - result = mk_list_assoc_app(m_manager, m_fid, OP_BXOR, flat_args.size(), flat_args.c_ptr()); - break; - } -} - -void bv_simplifier_plugin::mk_bv_not(expr * arg, expr_ref & result) { - numeral val; - unsigned bv_size; - if (m_util.is_numeral(arg, val, bv_size)) { - if (bv_size <= 64) { - uint64 l = bv_size; - uint64 mask = shift_left(1ull,l) - 1ull; - uint64 u = val.get_uint64(); - u = mask & (~u); - result = mk_numeral(numeral(u, numeral::ui64()), bv_size); - TRACE("bv_not_bug", - tout << l << " " << mask << " " << u << "\n"; - tout << mk_pp(arg, m_manager) << "\n" << mk_pp(result, m_manager) << "\n";); - } - else { - numeral r = mk_bv_not(val, bv_size); - result = mk_numeral(r, bv_size); - TRACE("bv_not_bug", - tout << mk_pp(arg, m_manager) << "\n" << mk_pp(result, m_manager) << "\n";); - } - } - else if (is_app_of(arg, m_fid, OP_BNOT)) { - result = to_app(arg)->get_arg(0); - } - else { - result = m_manager.mk_app(m_fid, OP_BNOT, arg); - } -} - -void bv_simplifier_plugin::mk_zeroext(unsigned n, expr * arg, expr_ref & result) { - if (n == 0) { - result = arg; - } - else { - expr_ref zero(m_manager); - zero = mk_bv0(n); - mk_concat(zero.get(), arg, result); - } -} - -void bv_simplifier_plugin::mk_repeat(unsigned n, expr * arg, expr_ref & result) { - ptr_buffer args; - for (unsigned i = 0; i < n; i++) { - args.push_back(arg); - } - mk_concat(args.size(), args.c_ptr(), result); -} - -bool bv_simplifier_plugin::is_minus_one_core(expr * arg) const { - numeral r; - unsigned bv_size; - if (m_util.is_numeral(arg, r, bv_size)) { - numeral minus_one(-1); - minus_one = mod(minus_one, rational::power_of_two(bv_size)); - return r == minus_one; - } - return false; -} - -bool bv_simplifier_plugin::is_x_minus_one(expr * arg, expr * & x) { - if (is_add(arg) && to_app(arg)->get_num_args() == 2) { - if (is_minus_one_core(to_app(arg)->get_arg(0))) { - x = to_app(arg)->get_arg(1); - return true; - } - if (is_minus_one_core(to_app(arg)->get_arg(1))) { - x = to_app(arg)->get_arg(0); - return true; - } - } - return false; -} - -void bv_simplifier_plugin::mk_bv_urem(expr * arg1, expr * arg2, expr_ref & result) { - numeral r1, r2; - unsigned bv_size; - bool is_num1 = m_util.is_numeral(arg1, r1, bv_size); - bool is_num2 = m_util.is_numeral(arg2, r2, bv_size); - bv_size = get_bv_size(arg1); - - if (is_num2 && r2.is_zero() && !m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BUREM0, arg1); - return; - } - - if (is_num1 && is_num2 && !r2.is_zero()) { - SASSERT(r1.is_nonneg() && r2.is_pos()); - r1 %= r2; - result = mk_numeral(r1, bv_size); - return; - } - - if (!m_params.m_hi_div0) { - // TODO: implement the optimization in this branch for the case the hardware interpretation is used for (x urem 0) - // urem(0, x) ==> ite(x = 0, urem0(x), 0) - if (is_num1 && r1.is_zero()) { - expr * zero = arg1; - expr_ref urem0(m_manager), eq0(m_manager); - urem0 = m_manager.mk_app(m_fid, OP_BUREM0, 1, &zero); - m_bsimp.mk_eq(arg2, zero, eq0); - m_bsimp.mk_ite(eq0.get(), urem0.get(), zero, result); - TRACE("urem", - tout << "urem:\n"; - ast_ll_pp(tout, m_manager, arg1); ast_ll_pp(tout, m_manager, arg2); - tout << "result:\n"; ast_ll_pp(tout, m_manager, result.get());); - return; - } - - // urem(x - 1, x) ==> ite(x = 0, urem0(x-1), x - 1) ==> ite(x = 0, urem0(-1), x - 1) - expr * x; - if (is_x_minus_one(arg1, x) && x == arg2) { - expr * x_minus_1 = arg1; - expr_ref zero(m_manager); - zero = mk_bv0(bv_size); - expr_ref minus_one(m_manager), urem0(m_manager), eq0(m_manager); - minus_one = mk_numeral(numeral::minus_one(), bv_size); - expr * minus_1 = minus_one.get(); - urem0 = m_manager.mk_app(m_fid, OP_BUREM0, 1, &minus_1); - m_bsimp.mk_eq(arg2, zero.get(), eq0); - m_bsimp.mk_ite(eq0.get(), urem0.get(), x_minus_1, result); - TRACE("urem", - tout << "urem:\n"; - ast_ll_pp(tout, m_manager, arg1); ast_ll_pp(tout, m_manager, arg2); - tout << "result:\n"; ast_ll_pp(tout, m_manager, result.get());); - return; - } - } - - if (is_num2 || m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BUREM_I, arg1, arg2); - } - else { - bv_size = get_bv_size(arg2); - result = m_manager.mk_ite(m_manager.mk_eq(arg2, mk_numeral(0, bv_size)), - m_manager.mk_app(m_fid, OP_BUREM0, arg1), - m_manager.mk_app(m_fid, OP_BUREM_I, arg1, arg2)); - } -} - -void bv_simplifier_plugin::mk_sign_extend(unsigned n, expr * arg, expr_ref & result) { - numeral r; - unsigned bv_size; - if (m_util.is_numeral(arg, r, bv_size)) { - unsigned result_bv_size = bv_size + n; - r = norm(r, bv_size, true); - r = mod(r, rational::power_of_two(result_bv_size)); - result = mk_numeral(r, result_bv_size); - TRACE("mk_sign_extend", tout << "n: " << n << "\n"; - ast_ll_pp(tout, m_manager, arg); tout << "====>\n"; - ast_ll_pp(tout, m_manager, result.get());); - return; - } - parameter param(n); - result = m_manager.mk_app(m_fid, OP_SIGN_EXT, 1, ¶m, 1, &arg); -} - -/** - Implement the following reductions - - (bvashr (bvashr a n1) n2) ==> (bvashr a (+ n1 n2)) - (bvlshr (bvlshr a n1) n2) ==> (bvlshr a (+ n1 n2)) - (bvshl (bvshl a n1) n2) ==> (bvshl a (+ n1 n2)) - when n1 and n2 are numerals. - Remark if (+ n1 n2) is greater than bv_size, we set (+ n1 n2) to bv_size - - Return true if the transformation was applied and the result stored in 'result'. - Return false otherwise. -*/ -bool bv_simplifier_plugin::shift_shift(bv_op_kind k, expr* arg1, expr* arg2, expr_ref& result) { - SASSERT(k == OP_BASHR || k == OP_BSHL || k == OP_BLSHR); - if (!is_app_of(arg1, m_fid, k)) - return false; - expr * a = to_app(arg1)->get_arg(0); - expr * n1 = to_app(arg1)->get_arg(1); - expr * n2 = arg2; - numeral r1, r2; - unsigned bv_size = UINT_MAX; - bool is_num1 = m_util.is_numeral(n1, r1, bv_size); - bool is_num2 = m_util.is_numeral(n2, r2, bv_size); - if (!is_num1 || !is_num2) - return false; - SASSERT(bv_size != UINT_MAX); - numeral r = r1 + r2; - if (r > numeral(bv_size)) - r = numeral(bv_size); - switch (k) { - case OP_BASHR: - mk_bv_ashr(a, m_util.mk_numeral(r, bv_size), result); - break; - case OP_BLSHR: - mk_bv_lshr(a, m_util.mk_numeral(r, bv_size), result); - break; - default: - SASSERT(k == OP_BSHL); - mk_bv_shl(a, m_util.mk_numeral(r, bv_size), result); - break; - } - return true; -} - -void bv_simplifier_plugin::mk_bv_shl(expr * arg1, expr * arg2, expr_ref & result) { - // x << 0 == x - numeral r1, r2; - unsigned bv_size = get_bv_size(arg1); - bool is_num1 = is_numeral(arg1, r1); - bool is_num2 = is_numeral(arg2, r2); - - if (is_num2 && r2.is_zero()) { - result = arg1; - } - else if (is_num2 && r2 >= rational(bv_size)) { - result = mk_numeral(0, bv_size); - } - else if (is_num2 && is_num1 && bv_size <= 64) { - SASSERT(r1.is_uint64() && r2.is_uint64()); - SASSERT(r2.get_uint64() < bv_size); - - uint64 r = shift_left(r1.get_uint64(), r2.get_uint64()); - result = mk_numeral(r, bv_size); - } - else if (is_num1 && is_num2) { - SASSERT(r2 < rational(bv_size)); - SASSERT(r2.is_unsigned()); - result = mk_numeral(r1 * rational::power_of_two(r2.get_unsigned()), bv_size); - } - - // - // (bvshl x k) -> (concat (extract [n-1-k:0] x) bv0:k) - // - else if (is_num2 && r2.is_pos() && r2 < numeral(bv_size)) { - SASSERT(r2.is_unsigned()); - unsigned r = r2.get_unsigned(); - expr_ref tmp1(m_manager); - mk_extract(bv_size - r - 1, 0, arg1, tmp1); - expr_ref zero(m_manager); - zero = mk_bv0(r); - expr* args[2] = { tmp1.get(), zero.get() }; - mk_concat(2, args, result); - } - else if (shift_shift(OP_BSHL, arg1, arg2, result)) { - // done - } - else { - result = m_manager.mk_app(m_fid, OP_BSHL, arg1, arg2); - } - TRACE("mk_bv_shl", - tout << mk_pp(arg1, m_manager) << " << " - << mk_pp(arg2, m_manager) << " = " - << mk_pp(result.get(), m_manager) << "\n";); -} - -void bv_simplifier_plugin::mk_bv_lshr(expr * arg1, expr * arg2, expr_ref & result) { - // x >> 0 == x - numeral r1, r2; - unsigned bv_size = get_bv_size(arg1); - bool is_num1 = is_numeral(arg1, r1); - bool is_num2 = is_numeral(arg2, r2); - - if (is_num2 && r2.is_zero()) { - result = arg1; - } - else if (is_num2 && r2 >= rational(bv_size)) { - result = mk_numeral(rational(0), bv_size); - } - else if (is_num1 && is_num2 && bv_size <= 64) { - SASSERT(r1.is_uint64()); - SASSERT(r2.is_uint64()); - uint64 r = shift_right(r1.get_uint64(), r2.get_uint64()); - result = mk_numeral(r, bv_size); - } - else if (is_num1 && is_num2) { - SASSERT(r2.is_unsigned()); - unsigned sh = r2.get_unsigned(); - r1 = div(r1, rational::power_of_two(sh)); - result = mk_numeral(r1, bv_size); - } - // - // (bvlshr x k) -> (concat bv0:k (extract [n-1:k] x)) - // - else if (is_num2 && r2.is_pos() && r2 < numeral(bv_size)) { - SASSERT(r2.is_unsigned()); - unsigned r = r2.get_unsigned(); - expr_ref tmp1(m_manager); - mk_extract(bv_size - 1, r, arg1, tmp1); - expr_ref zero(m_manager); - zero = mk_bv0(r); - expr* args[2] = { zero.get(), tmp1.get() }; - mk_concat(2, args, result); - } - else if (shift_shift(OP_BLSHR, arg1, arg2, result)) { - // done - } - else { - result = m_manager.mk_app(m_fid, OP_BLSHR, arg1, arg2); - } - TRACE("mk_bv_lshr", tout << mk_pp(arg1, m_manager) << " >> " << - mk_pp(arg2, m_manager) << " = " << mk_pp(result.get(), m_manager) << "\n";); - -} - - -void bv_simplifier_plugin::mk_int2bv(expr * arg, sort* range, expr_ref & result) { - numeral val; - bool is_int; - unsigned bv_size = get_bv_size(range); - - if (m_arith.is_numeral(arg, val, is_int)) { - result = mk_numeral(val, bv_size); - } - // (int2bv (bv2int x)) == x - else if (is_app_of(arg, m_fid, OP_BV2INT) && bv_size == get_bv_size(to_app(arg)->get_arg(0))) { - result = to_app(arg)->get_arg(0); - } - else { - parameter parameter(bv_size); - result = m_manager.mk_app(m_fid, OP_INT2BV, 1, ¶meter, 1, &arg); - SASSERT(result.get()); - } -} - -void bv_simplifier_plugin::mk_bv2int(expr * arg, sort* range, expr_ref & result) { - if (!m_params.m_bv2int_distribute) { - parameter parameter(range); - result = m_manager.mk_app(m_fid, OP_BV2INT, 1, ¶meter, 1, &arg); - return; - } - numeral v; - if (is_numeral(arg, v)) { - result = m_arith.mk_numeral(v, true); - } - else if (is_mul_no_overflow(arg)) { - expr_ref tmp1(m_manager), tmp2(m_manager); - mk_bv2int(to_app(arg)->get_arg(0), range, tmp1); - mk_bv2int(to_app(arg)->get_arg(1), range, tmp2); - result = m_arith.mk_mul(tmp1, tmp2); - } - else if (is_add_no_overflow(arg)) { - expr_ref tmp1(m_manager), tmp2(m_manager); - mk_bv2int(to_app(arg)->get_arg(0), range, tmp1); - mk_bv2int(to_app(arg)->get_arg(1), range, tmp2); - result = m_arith.mk_add(tmp1, tmp2); - } - // commented out to reproduce bug in reduction of int2bv/bv2int - else if (m_util.is_concat(arg) && to_app(arg)->get_num_args() > 0) { - expr_ref_vector args(m_manager); - unsigned num_args = to_app(arg)->get_num_args(); - for (unsigned i = 0; i < num_args; ++i) { - expr_ref tmp(m_manager); - mk_bv2int(to_app(arg)->get_arg(i), range, tmp); - args.push_back(tmp); - } - unsigned sz = get_bv_size(to_app(arg)->get_arg(num_args-1)); - for (unsigned i = num_args - 1; i > 0; ) { - expr_ref tmp(m_manager); - --i; - tmp = args[i].get(); - tmp = m_arith.mk_mul(m_arith.mk_numeral(power(numeral(2), sz), true), tmp); - args[i] = tmp; - sz += get_bv_size(to_app(arg)->get_arg(i)); - } - result = m_arith.mk_add(args.size(), args.c_ptr()); - } - else { - parameter parameter(range); - result = m_manager.mk_app(m_fid, OP_BV2INT, 1, ¶meter, 1, &arg); - } - SASSERT(m_arith.is_int(m_manager.get_sort(result.get()))); -} - -unsigned bv_simplifier_plugin::num_leading_zero_bits(expr* e) { - numeral v; - unsigned sz = get_bv_size(e); - if (is_numeral(e, v)) { - while (v.is_pos()) { - SASSERT(sz > 0); - --sz; - v = div(v, numeral(2)); - } - return sz; - } - else if (m_util.is_concat(e)) { - app* a = to_app(e); - unsigned sz1 = get_bv_size(a->get_arg(0)); - unsigned nb1 = num_leading_zero_bits(a->get_arg(0)); - if (sz1 == nb1) { - nb1 += num_leading_zero_bits(a->get_arg(1)); - } - return nb1; - } - return 0; -} - -bool bv_simplifier_plugin::is_mul_no_overflow(expr* e) { - if (!is_mul(e)) { - return false; - } - expr* e1 = to_app(e)->get_arg(0); - expr* e2 = to_app(e)->get_arg(1); - unsigned sz = get_bv_size(e1); - unsigned nb1 = num_leading_zero_bits(e1); - unsigned nb2 = num_leading_zero_bits(e2); - return nb1 + nb2 >= sz; -} - -bool bv_simplifier_plugin::is_add_no_overflow(expr* e) { - if (!is_add(e)) { - return false; - } - expr* e1 = to_app(e)->get_arg(0); - expr* e2 = to_app(e)->get_arg(1); - unsigned nb1 = num_leading_zero_bits(e1); - unsigned nb2 = num_leading_zero_bits(e2); - return nb1 > 0 && nb2 > 0; -} - - - -// Macro for generating mk_bv_sdiv_i, mk_bv_udiv_i, mk_bv_srem_i, mk_bv_urem_i and mk_bv_smod_i. -// These are essentially evaluators for the arg1 and arg2 are numerals. -// Q: Why do we need them? -// A: A constant may be eliminated using substitution. Its value is computed using the evaluator. -// Example: Suppose we have the top-level atom (= x (bvsrem_i a b)), and x is eliminated. -#define MK_FIXED_DIV_I(NAME, OP) \ -void bv_simplifier_plugin::NAME##_i(expr * arg1, expr * arg2, expr_ref & result) { \ - numeral r1, r2; \ - unsigned bv_size; \ - bool is_num1 = m_util.is_numeral(arg1, r1, bv_size); \ - bool is_num2 = m_util.is_numeral(arg2, r2, bv_size); \ - if (is_num1 && is_num2 && !r2.is_zero()) { \ - NAME(arg1, arg2, result); \ - } \ - else { \ - result = m_manager.mk_app(m_fid, OP, arg1, arg2); \ - } \ -} - -MK_FIXED_DIV_I(mk_bv_sdiv, OP_BSDIV_I) -MK_FIXED_DIV_I(mk_bv_udiv, OP_BUDIV_I) -MK_FIXED_DIV_I(mk_bv_srem, OP_BSREM_I) -MK_FIXED_DIV_I(mk_bv_urem, OP_BUREM_I) -MK_FIXED_DIV_I(mk_bv_smod, OP_BSMOD_I) - -void bv_simplifier_plugin::mk_bv_sdiv(expr* arg1, expr* arg2, expr_ref& result) { - numeral r1, r2; - unsigned bv_size; - bool is_num1 = m_util.is_numeral(arg1, r1, bv_size); - bool is_num2 = m_util.is_numeral(arg2, r2, bv_size); - - if (is_num2 && r2.is_zero() && !m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BSDIV0, arg1); - } - else if (is_num1 && is_num2 && !r2.is_zero()) { - r1 = norm(r1, bv_size, true); - r2 = norm(r2, bv_size, true); - result = mk_numeral(machine_div(r1, r2), bv_size); - } - else if (is_num2 || m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BSDIV_I, arg1, arg2); - } - else { - bv_size = get_bv_size(arg2); - result = m_manager.mk_ite(m_manager.mk_eq(arg2, mk_numeral(0, bv_size)), - m_manager.mk_app(m_fid, OP_BSDIV0, arg1), - m_manager.mk_app(m_fid, OP_BSDIV_I, arg1, arg2)); - } -} - -void bv_simplifier_plugin::mk_bv_udiv(expr* arg1, expr* arg2, expr_ref& result) { - numeral r1, r2; - unsigned bv_size; - bool is_num1 = m_util.is_numeral(arg1, r1, bv_size); - bool is_num2 = m_util.is_numeral(arg2, r2, bv_size); - - if (is_num2 && r2.is_zero() && !m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BUDIV0, arg1); - } - else if (is_num1 && is_num2 && !r2.is_zero()) { - SASSERT(r1.is_nonneg()); - SASSERT(r2.is_nonneg()); - result = mk_numeral(machine_div(r1, r2), bv_size); - } - else if (is_num2 || m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BUDIV_I, arg1, arg2); - } - else { - bv_size = get_bv_size(arg2); - result = m_manager.mk_ite(m_manager.mk_eq(arg2, mk_numeral(0, bv_size)), - m_manager.mk_app(m_fid, OP_BUDIV0, arg1), - m_manager.mk_app(m_fid, OP_BUDIV_I, arg1, arg2)); - } -} - -void bv_simplifier_plugin::mk_bv_srem(expr* arg1, expr* arg2, expr_ref& result) { - numeral r1, r2; - unsigned bv_size; - bool is_num1 = m_util.is_numeral(arg1, r1, bv_size); - bool is_num2 = m_util.is_numeral(arg2, r2, bv_size); - - if (is_num2 && r2.is_zero() && !m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BSREM0, arg1); - } - else if (is_num1 && is_num2 && !r2.is_zero()) { - r1 = norm(r1, bv_size, true); - r2 = norm(r2, bv_size, true); - result = mk_numeral(r1 % r2, bv_size); - } - else if (is_num2 || m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BSREM_I, arg1, arg2); - } - else { - bv_size = get_bv_size(arg2); - result = m_manager.mk_ite(m_manager.mk_eq(arg2, mk_numeral(0, bv_size)), - m_manager.mk_app(m_fid, OP_BSREM0, arg1), - m_manager.mk_app(m_fid, OP_BSREM_I, arg1, arg2)); - } -} - -void bv_simplifier_plugin::mk_bv_smod(expr* arg1, expr* arg2, expr_ref& result) { - numeral r1, r2; - unsigned bv_size; - bool is_num1 = m_util.is_numeral(arg1, r1, bv_size); - bool is_num2 = m_util.is_numeral(arg2, r2, bv_size); - - if (is_num1) - r1 = m_util.norm(r1, bv_size, true); - if (is_num2) - r2 = m_util.norm(r2, bv_size, true); - - TRACE("bv_simplifier", - tout << mk_pp(arg1, m_manager) << " smod " << mk_pp(arg2, m_manager) << "\n"; - ); - - - if (is_num2 && r2.is_zero()) { - if (!m_params.m_hi_div0) - result = m_manager.mk_app(m_fid, OP_BSMOD0, arg1); - else - result = arg1; - } - else if (is_num1 && is_num2) { - SASSERT(!r2.is_zero()); - numeral abs_r1 = m_util.norm(abs(r1), bv_size); - numeral abs_r2 = m_util.norm(abs(r2), bv_size); - numeral u = m_util.norm(abs_r1 % abs_r2, bv_size); - numeral r; - if (u.is_zero()) - r = u; - else if (r1.is_pos() && r2.is_pos()) - r = u; - else if (r1.is_neg() && r2.is_pos()) - r = m_util.norm(-u + r2, bv_size); - else if (r1.is_pos() && r2.is_neg()) - r = m_util.norm(u + r2, bv_size); - else - r = m_util.norm(-u, bv_size); - result = mk_numeral(r, bv_size); - } - else if (is_num2 || m_params.m_hi_div0) { - result = m_manager.mk_app(m_fid, OP_BSMOD_I, arg1, arg2); - } - else { - bv_size = get_bv_size(arg2); - result = m_manager.mk_ite(m_manager.mk_eq(arg2, mk_numeral(0, bv_size)), - m_manager.mk_app(m_fid, OP_BSMOD0, arg1), - m_manager.mk_app(m_fid, OP_BSMOD_I, arg1, arg2)); - } -} - -uint64 bv_simplifier_plugin::n64(expr* e) { - numeral r; - unsigned bv_size; - if (m_util.is_numeral(e, r, bv_size) && bv_size <= 64) { - return r.get_uint64(); - } - UNREACHABLE(); - return 0; -} - -rational bv_simplifier_plugin::num(expr* e) { - numeral r; - unsigned bv_size; - if (!m_util.is_numeral(e, r, bv_size)) { - UNREACHABLE(); - } - return r; - -} - -void bv_simplifier_plugin::mk_bv_nand(unsigned num_args, expr* const* args, expr_ref& result) { - unsigned bv_size; - if (are_numerals(num_args, args, bv_size)) { - if (bv_size <= 64) { - uint64 r = n64(args[0]); - for (unsigned i = 1; i < num_args; i++) { - r &= n64(args[i]); - } - result = mk_numeral(~r, bv_size); - } - else { - numeral r = num(args[0]); - for (unsigned i = 1; i < num_args; i++) { - r = mk_bv_and(r, num(args[i]), bv_size); - } - result = mk_numeral(mk_bv_not(r, bv_size), bv_size); - } - } - else { - result = m_manager.mk_app(m_fid, OP_BNAND, num_args, args); - } -} - -void bv_simplifier_plugin::mk_bv_nor(unsigned num_args, expr* const* args, expr_ref& result) { - unsigned bv_size; - if (are_numerals(num_args, args, bv_size)) { - if (bv_size <= 64) { - uint64 r = n64(args[0]); - for (unsigned i = 1; i < num_args; i++) { - r |= n64(args[i]); - } - result = mk_numeral(~r, bv_size); - } - else { - numeral r = num(args[0]); - for (unsigned i = 1; i < num_args; i++) { - r = mk_bv_or(r, num(args[i]), bv_size); - } - result = mk_numeral(mk_bv_not(r, bv_size), bv_size); - } - } - else { - result = m_manager.mk_app(m_fid, OP_BNOR, num_args, args); - } -} - -void bv_simplifier_plugin::mk_bv_xnor(unsigned num_args, expr* const* args, expr_ref& result) { - unsigned bv_size; - if (are_numerals(num_args, args, bv_size)) { - if (bv_size <= 64) { - uint64 r = n64(args[0]); - for (unsigned i = 1; i < num_args; i++) { - r ^= n64(args[i]); - } - result = mk_numeral(~r, bv_size); - } - else { - numeral r = num(args[0]); - for (unsigned i = 1; i < num_args; i++) { - r = mk_bv_xor(r, num(args[i]), bv_size); - } - result = mk_numeral(mk_bv_not(r, bv_size), bv_size); - } - } - else { - result = m_manager.mk_app(m_fid, OP_BXNOR, num_args, args); - } -} - -void bv_simplifier_plugin::mk_bv_rotate_left_core(unsigned shift, numeral r, unsigned bv_size, expr_ref& result) { - SASSERT(shift < bv_size); - if (bv_size <= 64) { - uint64 a = r.get_uint64(); - uint64 r = shift_left(a, shift) | shift_right(a, bv_size - shift); - result = mk_numeral(r, bv_size); - } - else { - rational r1 = div(r, rational::power_of_two(bv_size - shift)); // shift right - rational r2 = (r * rational::power_of_two(shift)) % rational::power_of_two(bv_size); // shift left - result = mk_numeral(r1 + r2, bv_size); - } -} - -void bv_simplifier_plugin::mk_bv_rotate_left(func_decl* f, expr* arg, expr_ref& result) { - numeral r; - unsigned bv_size; - SASSERT(f->get_decl_kind() == OP_ROTATE_LEFT); - if (m_util.is_numeral(arg, r, bv_size)) { - unsigned shift = f->get_parameter(0).get_int() % bv_size; - mk_bv_rotate_left_core(shift, r, bv_size, result); - } - else { - result = m_manager.mk_app(f, arg); - } -} - -void bv_simplifier_plugin::mk_bv_rotate_right_core(unsigned shift, numeral r, unsigned bv_size, expr_ref& result) { - SASSERT(shift < bv_size); - if (bv_size <= 64) { - uint64 a = r.get_uint64(); - uint64 r = shift_right(a, shift) | shift_left(a, bv_size - shift); - result = mk_numeral(r, bv_size); - } - else { - rational r1 = div(r, rational::power_of_two(shift)); // shift right - rational r2 = (r * rational::power_of_two(bv_size - shift)) % rational::power_of_two(bv_size); // shift left - result = mk_numeral(r1 + r2, bv_size); - } -} - -void bv_simplifier_plugin::mk_bv_rotate_right(func_decl* f, expr* arg, expr_ref& result) { - numeral r; - unsigned bv_size; - SASSERT(f->get_decl_kind() == OP_ROTATE_RIGHT); - if (m_util.is_numeral(arg, r, bv_size)) { - unsigned shift = f->get_parameter(0).get_int() % bv_size; - mk_bv_rotate_right_core(shift, r, bv_size, result); - } - else { - result = m_manager.mk_app(f, arg); - } -} - -void bv_simplifier_plugin::mk_bv_redor(expr* arg, expr_ref& result) { - if (is_numeral(arg)) { - result = m_util.is_zero(arg)?mk_numeral(0, 1):mk_numeral(1,1); - } - else { - result = m_manager.mk_app(m_fid, OP_BREDOR, arg); - } -} - -void bv_simplifier_plugin::mk_bv_redand(expr* arg, expr_ref& result) { - numeral r; - unsigned bv_size; - if (m_util.is_numeral(arg, r, bv_size)) { - numeral allone = mk_allone(bv_size); - result = mk_numeral((r == allone)?1:0, 1); - } - else { - result = m_manager.mk_app(m_fid, OP_BREDAND, arg); - } -} - -void bv_simplifier_plugin::mk_bv_comp(expr* arg1, expr* arg2, expr_ref& result) { - numeral r1, r2; - if (arg1 == arg2) { - result = mk_numeral(1,1); - } - else if (is_numeral(arg1, r1) && is_numeral(arg2, r2)) { - result = mk_numeral((r1 == r2)?1:0, 1); - } - else { - result = m_manager.mk_app(m_fid, OP_BCOMP, arg1, arg2); - } -} - -void bv_simplifier_plugin::mk_bv_ashr(expr* arg1, expr* arg2, expr_ref& result) { - numeral r1, r2; - unsigned bv_size = get_bv_size(arg1); - bool is_num1 = m_util.is_numeral(arg1, r1, bv_size); - bool is_num2 = m_util.is_numeral(arg2, r2, bv_size); - - if (bv_size == 0) { - result = mk_numeral(rational(0), bv_size); - } - else if (is_num2 && r2.is_zero()) { - result = arg1; - } - else if (bv_size <= 64 && is_num1 && is_num2) { - uint64 n1 = n64(arg1); - uint64 n2_orig = n64(arg2); - uint64 n2 = n2_orig % bv_size; - SASSERT(n2 < bv_size); - uint64 r = shift_right(n1, n2); - bool sign = (n1 & shift_left(1ull, bv_size - 1ull)) != 0; - if (n2_orig > n2) { - if (sign) { - r = shift_left(1ull, bv_size) - 1ull; - } - else { - r = 0; - } - } - else if (sign) { - uint64 allone = shift_left(1ull, bv_size) - 1ull; - uint64 mask = ~(shift_left(1ull, bv_size - n2) - 1ull); - mask &= allone; - r |= mask; - } - result = mk_numeral(r, bv_size); - TRACE("bv", tout << mk_pp(arg1, m_manager) << " >> " - << mk_pp(arg2, m_manager) << " = " - << mk_pp(result.get(), m_manager) << "\n"; - tout << n1 << " >> " << n2 << " = " << r << "\n"; - ); - } - else if (is_num1 && is_num2 && rational(bv_size) <= r2) { - if (has_sign_bit(r1, bv_size)) { - result = mk_numeral(mk_allone(bv_size), bv_size); - } - else { - result = mk_bv0(bv_size); - } - } - else if (is_num1 && is_num2) { - SASSERT(r2 < rational(bv_size)); - bool sign = has_sign_bit(r1, bv_size); - r1 = div(r1, rational::power_of_two(r2.get_unsigned())); - if (sign) { - // pad ones. - rational p(1); - for (unsigned i = 0; i < bv_size; ++i) { - if (r1 < p) { - r1 += p; - } - p *= rational(2); - } - } - result = mk_numeral(r1, bv_size); - - } - else if (shift_shift(OP_BASHR, arg1, arg2, result)) { - // done - } - else { - result = m_manager.mk_app(m_fid, OP_BASHR, arg1, arg2); - } -} - -void bv_simplifier_plugin::mk_bv_ext_rotate_right(expr* arg1, expr* arg2, expr_ref& result) { - numeral r2; - unsigned bv_size; - if (m_util.is_numeral(arg2, r2, bv_size)) { - unsigned shift = static_cast((r2 % numeral(bv_size)).get_uint64() % static_cast(bv_size)); - numeral r1; - if (is_numeral(arg1, r1)) { - mk_bv_rotate_right_core(shift, r1, bv_size, result); - } - else { - parameter p(shift); - result = m_manager.mk_app(m_fid, OP_ROTATE_RIGHT, 1, &p, 1, &arg1); - } - } - else { - result = m_manager.mk_app(m_fid, OP_EXT_ROTATE_RIGHT, arg1, arg2); - } -} - - -void bv_simplifier_plugin::mk_bv_ext_rotate_left(expr* arg1, expr* arg2, expr_ref& result) { - numeral r2; - unsigned bv_size; - if (m_util.is_numeral(arg2, r2, bv_size)) { - unsigned shift = static_cast((r2 % numeral(bv_size)).get_uint64() % static_cast(bv_size)); - numeral r1; - if (is_numeral(arg1, r1)) { - mk_bv_rotate_left_core(shift, r1, bv_size, result); - } - else { - parameter p(shift); - result = m_manager.mk_app(m_fid, OP_ROTATE_LEFT, 1, &p, 1, &arg1); - } - } - else { - result = m_manager.mk_app(m_fid, OP_EXT_ROTATE_LEFT, arg1, arg2); - } -} - -void bv_simplifier_plugin::bit2bool_simplify(unsigned idx, expr* e, expr_ref& result) { - - parameter p(idx); - - ptr_vector todo; - expr_ref_vector pinned(m_manager); - ptr_vector cache; - todo.push_back(e); - expr* e0 = e; - ptr_vector argv; - expr_ref tmp(m_manager); - while (!todo.empty()) { - e = todo.back(); - unsigned e_id = e->get_id(); - if (e_id >= cache.size()) { - cache.resize(e_id+1,0); - } - if (cache[e_id]) { - todo.pop_back(); - continue; - } - if (!m_util.is_numeral(e) && - !m_util.is_bv_and(e) && - !m_util.is_bv_or(e) && - !(is_app_of(e, m_fid, OP_BXOR) && to_app(e)->get_num_args() == 2) && - !m_manager.is_ite(e) && - !m_util.is_concat(e) && - !m_util.is_bv_not(e)) { - expr_ref extr(m_manager); - extr = m_util.mk_extract(idx, idx, e); - cache[e_id] = m_manager.mk_eq(m_util.mk_numeral(1, 1), extr); - pinned.push_back(cache[e_id]); - todo.pop_back(); - continue; - } - app* a = to_app(e); - unsigned sz = a->get_num_args(); - if (m_util.is_concat(e)) { - // look for first argument - unsigned idx1 = idx; - while (sz > 0) { - --sz; - expr * a_i = a->get_arg(sz); - unsigned a_sz = get_bv_size(a_i); - if (a_sz <= idx1) { - idx1 -= a_sz; - } - else { - // idx < a_sz; - bit2bool_simplify(idx1, a_i, tmp); - pinned.push_back(tmp); - cache[e_id] = to_app(tmp); - break; - } - } - todo.pop_back(); - continue; - } - argv.reset(); - for (unsigned i = 0; i < sz; ++i) { - expr* arg_i = a->get_arg(i); - if (i == 0 && m_manager.is_ite(e)) { - argv.push_back(arg_i); - } - else if (cache.size() > arg_i->get_id() && cache[arg_i->get_id()]) { - argv.push_back(cache[arg_i->get_id()]); - } - else { - todo.push_back(arg_i); - } - } - if (sz != argv.size()) { - continue; - } - todo.pop_back(); - rational val; - unsigned num_bits; - if (m_util.is_numeral(e, val, num_bits)) { - rational two(2); - for (unsigned i = 0; i < idx; ++i) { - val = div(val, two); - } - bool is_pos = !(val % two).is_zero(); - tmp = is_pos?m_manager.mk_true():m_manager.mk_false(); - } - else if (m_util.is_bv_and(e)) { - //tmp = m_manager.mk_and(sz, argv.c_ptr()); - m_bsimp.mk_and(sz, argv.c_ptr(), tmp); - pinned.push_back(tmp); - } - else if (m_util.is_bv_or(e)) { - //tmp = m_manager.mk_or(sz, argv.c_ptr()); - m_bsimp.mk_or(sz, argv.c_ptr(), tmp); - pinned.push_back(tmp); - } - else if (m_util.is_bv_not(e)) { - //tmp = m_manager.mk_not(argv[0]); - m_bsimp.mk_not(argv[0], tmp); - pinned.push_back(tmp); - } - else if (is_app_of(e, m_fid, OP_BXOR)) { - SASSERT(argv.size() == 2); - m_bsimp.mk_xor(argv[0], argv[1], tmp); - pinned.push_back(tmp); - } - else if (m_manager.is_ite(e)) { - //tmp = m_manager.mk_ite(argv[0], argv[1], argv[2]); - m_bsimp.mk_ite(argv[0], argv[1], argv[2], tmp); - pinned.push_back(tmp); - } - else { - UNREACHABLE(); - } - cache[e_id] = to_app(tmp); - } - result = cache[e0->get_id()]; -} - - -// replace addition by concatenation. -void bv_simplifier_plugin::mk_add_concat(expr_ref& result) { - if (!m_util.is_bv_add(result)) { - return; - } - app* a = to_app(result); - if (a->get_num_args() != 2) { - return; - } - expr* x = a->get_arg(0); - expr* y = a->get_arg(1); - if (!m_util.is_concat(x)) { - std::swap(x, y); - } - if (!m_util.is_concat(x)) { - return; - } - unsigned sz = m_util.get_bv_size(x); - -#if 0 - // optimzied version. Seems not worth it.. -#define UPDATE_CURR(_curr1, _idx1,_x,_is_num, _i) \ - if (_idx1 >= m_util.get_bv_size(_curr1)) { \ - _curr1 = _x; \ - _idx1 = _i; \ - _is_num = false; \ - } \ - while (m_util.is_concat(_curr1)) { \ - _is_num = false; \ - unsigned num_args = to_app(_curr1)->get_num_args(); \ - while (true) { \ - --num_args; \ - expr* c1 = to_app(_curr1)->get_arg(num_args); \ - unsigned sz1 = m_util.get_bv_size(c1); \ - if (sz1 < _idx1) { \ - _idx1 -= sz1; \ - } \ - else { \ - _curr1 = c1; \ - break; \ - } \ - } \ - } - - unsigned idx1 = 0, idx2 = 0; - expr* curr1 = x, *curr2 = y; - bool is_num1 = false, is_num2 = false; - rational val1, val2; - rational two(2); - for (unsigned i = 0; i < sz; ++i, ++idx1, ++idx2) { - UPDATE_CURR(curr1, idx1, x, is_num1, i); - UPDATE_CURR(curr2, idx2, y, is_num2, i); - if (idx1 == 0 && m_util.is_numeral(curr1, val1, bv_size)) { - is_num1 = true; - } - if (idx2 == 0 && m_util.is_numeral(curr2, val2, bv_size)) { - is_num2 = true; - } - if ((is_num1 && (val1 % two).is_zero()) || - (is_num2 && (val2 % two).is_zero())) { - val1 = div(val1, two); - val2 = div(val2, two); - continue; - } - return; - } - mk_bv_or(2, a->get_args(), result); -#endif - - for (unsigned i = 0; i < sz; ++i) { - if (!is_zero_bit(x,i) && !is_zero_bit(y,i)) { - return; - } - } - mk_bv_or(2, a->get_args(), result); -} - -bool bv_simplifier_plugin::is_zero_bit(expr* x, unsigned idx) { - rational val; - unsigned bv_size; - if (m_util.is_numeral(x, val, bv_size)) { - if (val.is_zero()) { - return true; - } - rational two(2); - while (idx > 0) { - val = div(val, two); - idx--; - } - return (val % two).is_zero(); - } - if (m_util.is_concat(x)) { - unsigned num_args = to_app(x)->get_num_args(); - while (num_args > 0) { - --num_args; - expr* y = to_app(x)->get_arg(num_args); - bv_size = m_util.get_bv_size(y); - if (bv_size <= idx) { - idx -= bv_size; - } - else { - return is_zero_bit(y, idx); - } - } - UNREACHABLE(); - } - - return false; -} diff --git a/src/ast/simplifier/bv_simplifier_plugin.h b/src/ast/simplifier/bv_simplifier_plugin.h deleted file mode 100644 index 7208b6dc8..000000000 --- a/src/ast/simplifier/bv_simplifier_plugin.h +++ /dev/null @@ -1,187 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - bv_simplifier_plugin.h - -Abstract: - - Simplifier for the bv family. - -Author: - - Leonardo (leonardo) 2008-01-08 - ---*/ -#ifndef BV_SIMPLIFIER_PLUGIN_H_ -#define BV_SIMPLIFIER_PLUGIN_H_ - -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/poly_simplifier_plugin.h" -#include "ast/bv_decl_plugin.h" -#include "util/map.h" -#include "ast/simplifier/bv_simplifier_params.h" -#include "ast/arith_decl_plugin.h" - -/** - \brief Simplifier for the bv family. -*/ -class bv_simplifier_plugin : public poly_simplifier_plugin { - - typedef rational numeral; - struct extract_entry { - unsigned m_high; - unsigned m_low; - expr * m_arg; - extract_entry():m_high(0), m_low(0), m_arg(0) {} - extract_entry(unsigned h, unsigned l, expr * n):m_high(h), m_low(l), m_arg(n) {} - unsigned hash() const { - unsigned a = m_high; - unsigned b = m_low; - unsigned c = m_arg->get_id(); - mix(a,b,c); - return c; - } - bool operator==(const extract_entry & e) const { - return m_high == e.m_high && m_low == e.m_low && m_arg == e.m_arg; - } - struct hash_proc { - unsigned operator()(extract_entry const& e) const { return e.hash(); } - }; - struct eq_proc { - bool operator()(extract_entry const& a, extract_entry const& b) const { return a == b; } - }; - }; - typedef map extract_cache; - -protected: - ast_manager& m_manager; - bv_util m_util; - arith_util m_arith; - basic_simplifier_plugin & m_bsimp; - bv_simplifier_params & m_params; - expr_ref_vector m_zeros; - extract_cache m_extract_cache; - - unsigned_vector m_lows, m_highs; - ptr_vector m_extract_args; - - rational mk_bv_and(numeral const& a0, numeral const& b0, unsigned sz); - rational mk_bv_or(numeral const& a0, numeral const& b0, unsigned sz); - rational mk_bv_xor(numeral const& a0, numeral const& b0, unsigned sz); - rational mk_bv_not(numeral const& a0, unsigned sz); - rational num(expr* e); - bool has_sign_bit(numeral const& n, unsigned bv_size) { return m_util.has_sign_bit(n, bv_size); } - - bool shift_shift(bv_op_kind k, expr* arg1, expr* arg2, expr_ref& result); - - void bit2bool_simplify(unsigned idx, expr* e, expr_ref& result); - - void mk_add_concat(expr_ref& result); - bool is_zero_bit(expr* x, unsigned idx); - - void mk_bv_rotate_left_core(unsigned shift, numeral r, unsigned bv_size, expr_ref& result); - void mk_bv_rotate_right_core(unsigned shift, numeral r, unsigned bv_size, expr_ref& result); - -public: - bv_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b, bv_simplifier_params & p); - virtual ~bv_simplifier_plugin(); - - - // simplifier_plugin: - 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); - virtual bool reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result); - virtual void flush_caches(); - - // poly_simplifier_plugin - virtual rational norm(const rational & n); - virtual bool is_numeral(expr * n, rational & val) const; - bool is_numeral(expr * n) const { return m_util.is_numeral(n); } - virtual bool is_minus_one(expr * n) const { return is_minus_one_core(n); } - virtual expr * get_zero(sort * s) const; - virtual app * mk_numeral(rational const & n); - - bool is_bv(expr * n) const { return m_util.is_bv(n); } - bool is_bv_sort(sort * s) const { return m_util.is_bv_sort(s); } - - bool is_le(expr * n) const { return m_util.is_bv_ule(n) || m_util.is_bv_sle(n); } - // REMARK: simplified bv expressions are never of the form a >= b. - virtual bool is_le_ge(expr * n) const { return is_le(n); } - - uint64 to_uint64(const numeral & n, unsigned bv_size); - rational norm(rational const& n, unsigned bv_size, bool is_signed) { return m_util.norm(n, bv_size, is_signed); } - unsigned get_bv_size(expr const * n) { return get_bv_size(m_manager.get_sort(n)); } - unsigned get_bv_size(sort const * s) { return m_util.get_bv_size(s); } - void mk_leq_core(bool is_signed, expr * arg1, expr * arg2, expr_ref & result); - void mk_ule(expr* a, expr* b, expr_ref& result); - void mk_ult(expr* a, expr* b, expr_ref& result); - void mk_sle(expr* a, expr* b, expr_ref& result); - void mk_slt(expr* a, expr* b, expr_ref& result); - void mk_bv_and(unsigned num_args, expr * const* args, expr_ref & result); - void mk_bv_or(unsigned num_args, expr * const* args, expr_ref & result); - void mk_bv_xor(unsigned num_args, expr * const* args, expr_ref & result); - void mk_bv_not(expr * arg, expr_ref & result); - void mk_extract(unsigned hi,unsigned lo, expr* bv, expr_ref& result); - void mk_extract_core(unsigned high, unsigned low, expr * arg, expr_ref& result); - void cache_extract(unsigned h, unsigned l, expr * arg, expr * result); - expr* get_cached_extract(unsigned h, unsigned l, expr * arg); - - bool lookup_mk_extract(unsigned high, unsigned low, expr * arg, expr_ref& result); - bool try_mk_extract(unsigned high, unsigned low, expr * arg, expr_ref& result); - - void mk_bv_eq(expr* a1, expr* a2, expr_ref& result); - void mk_eq_core(expr * arg1, expr * arg2, expr_ref & result); - void mk_args_eq_numeral(app * app, expr * n, expr_ref & result); - - void mk_concat(unsigned num_args, expr * const * args, expr_ref & result); - void mk_concat(expr * arg1, expr * arg2, expr_ref & result) { - expr * args[2] = { arg1, arg2 }; - mk_concat(2, args, result); - } - void mk_zeroext(unsigned n, expr * arg, expr_ref & result); - void mk_repeat(unsigned n, expr * arg, expr_ref & result); - void mk_sign_extend(unsigned n, expr * arg, expr_ref & result); - void mk_bv_lshr(expr * arg1, expr * arg2, expr_ref & result); - void mk_bv_shl(expr * arg1, expr * arg2, expr_ref & result); - void mk_bv_ashr(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_smod(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_urem(expr * arg1, expr * arg2, expr_ref & result); - void mk_bv_srem(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_udiv(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_sdiv(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_smod_i(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_urem_i(expr * arg1, expr * arg2, expr_ref & result); - void mk_bv_srem_i(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_udiv_i(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_sdiv_i(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_nand(unsigned num_args, expr* const* args, expr_ref& result); - void mk_bv_nor(unsigned num_args, expr* const* args, expr_ref& result); - void mk_bv_xnor(unsigned num_args, expr* const* args, expr_ref& result); - void mk_bv_rotate_right(func_decl* f, expr* arg, expr_ref& result); - void mk_bv_rotate_left(func_decl* f, expr* arg, expr_ref& result); - void mk_bv_ext_rotate_right(expr* arg1, expr* arg2, expr_ref& result); - void mk_bv_ext_rotate_left(expr* arg1, expr* arg2, expr_ref& result); - - void mk_bv_redor(expr* arg, expr_ref& result); - void mk_bv_redand(expr* arg, expr_ref& result); - void mk_bv_comp(expr* arg1, expr* arg2, expr_ref& result); - - bool are_numerals(unsigned num_args, expr * const* args, unsigned& bv_size); - app * mk_numeral(rational const & n, unsigned bv_size); - app * mk_numeral(uint64 n, unsigned bv_size) { return mk_numeral(numeral(n, numeral::ui64()), bv_size); } - app* mk_bv0(unsigned bv_size) { return m_util.mk_numeral(numeral(0), bv_size); } - rational mk_allone(unsigned bv_size) { return rational::power_of_two(bv_size) - numeral(1); } - bool is_minus_one_core(expr * arg) const; - bool is_x_minus_one(expr * arg, expr * & x); - void mk_int2bv(expr * arg, sort* range, expr_ref & result); - void mk_bv2int(expr * arg, sort* range, expr_ref & result); - uint64 n64(expr* e); - bool is_mul_no_overflow(expr* e); - bool is_add_no_overflow(expr* e); - unsigned num_leading_zero_bits(expr* e); - -}; - -#endif /* BV_SIMPLIFIER_PLUGIN_H_ */ diff --git a/src/ast/simplifier/datatype_simplifier_plugin.cpp b/src/ast/simplifier/datatype_simplifier_plugin.cpp deleted file mode 100644 index b665ed101..000000000 --- a/src/ast/simplifier/datatype_simplifier_plugin.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/*++ -Copyright (c) 2008 Microsoft Corporation - -Module Name: - - datatype_simplifier_plugin.cpp - -Abstract: - - Simplifier for algebraic datatypes. - -Author: - - nbjorner 2008-11-6 - ---*/ - -#include "ast/simplifier/datatype_simplifier_plugin.h" - -datatype_simplifier_plugin::datatype_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b): - simplifier_plugin(symbol("datatype"), m), - m_util(m), - m_bsimp(b) { -} - -datatype_simplifier_plugin::~datatype_simplifier_plugin() { -} - -bool datatype_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - - SASSERT(f->get_family_id() == get_family_id()); - switch(f->get_decl_kind()) { - case OP_DT_CONSTRUCTOR: { - return false; - } - case OP_DT_RECOGNISER: { - // - // simplify is_cons(cons(x,y)) -> true - // simplify is_cons(nil) -> false - // - SASSERT(num_args == 1); - - if (!is_app_of(args[0], get_family_id(), OP_DT_CONSTRUCTOR)) { - return false; - } - app* a = to_app(args[0]); - func_decl* f1 = a->get_decl(); - func_decl* f2 = m_util.get_recognizer_constructor(f); - if (f1 == f2) { - result = m_manager.mk_true(); - } - else { - result = m_manager.mk_false(); - } - return true; - } - case OP_DT_ACCESSOR: { - // - // simplify head(cons(x,y)) -> x - // - SASSERT(num_args == 1); - - if (!is_app_of(args[0], get_family_id(), OP_DT_CONSTRUCTOR)) { - return false; - } - app* a = to_app(args[0]); - func_decl* f1 = a->get_decl(); - func_decl* f2 = m_util.get_accessor_constructor(f); - if (f1 != f2) { - return false; - } - ptr_vector const* acc = m_util.get_constructor_accessors(f1); - SASSERT(acc && acc->size() == a->get_num_args()); - for (unsigned i = 0; i < acc->size(); ++i) { - if (f == (*acc)[i]) { - // found it. - result = a->get_arg(i); - return true; - } - } - UNREACHABLE(); - } - case OP_DT_UPDATE_FIELD: - return false; - default: - UNREACHABLE(); - } - - return false; -} - -bool datatype_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { - set_reduce_invoked(); - if (is_app_of(lhs, get_family_id(), OP_DT_CONSTRUCTOR) && - is_app_of(rhs, get_family_id(), OP_DT_CONSTRUCTOR)) { - app* a = to_app(lhs); - app* b = to_app(rhs); - if (a->get_decl() != b->get_decl()) { - result = m_manager.mk_false(); - return true; - } - expr_ref_vector eqs(m_manager); - for (unsigned i = 0; i < a->get_num_args(); ++i) { - m_bsimp.mk_eq(a->get_arg(i),b->get_arg(i), result); - eqs.push_back(result); - } - m_bsimp.mk_and(eqs.size(), eqs.c_ptr(), result); - return true; - } - // TBD: occurs check, constructor check. - - return false; -} - diff --git a/src/ast/simplifier/datatype_simplifier_plugin.h b/src/ast/simplifier/datatype_simplifier_plugin.h deleted file mode 100644 index e976beba7..000000000 --- a/src/ast/simplifier/datatype_simplifier_plugin.h +++ /dev/null @@ -1,42 +0,0 @@ -/*++ -Copyright (c) 2008 Microsoft Corporation - -Module Name: - - datatype_simplifier_plugin.h - -Abstract: - - Simplifier for algebraic datatypes. - -Author: - - nbjorner 2008-11-6 - ---*/ -#ifndef DATATYPE_SIMPLIFIER_PLUGIN_H_ -#define DATATYPE_SIMPLIFIER_PLUGIN_H_ - -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/datatype_decl_plugin.h" - -/** - \brief Simplifier for the arith family. -*/ -class datatype_simplifier_plugin : public simplifier_plugin { - datatype_util m_util; - basic_simplifier_plugin & m_bsimp; - - -public: - datatype_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b); - ~datatype_simplifier_plugin(); - - - 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); - -}; - -#endif /* DATATYPE_SIMPLIFIER_PLUGIN_H_ */ diff --git a/src/ast/simplifier/elim_bounds.cpp b/src/ast/simplifier/elim_bounds.cpp deleted file mode 100644 index 738fc3012..000000000 --- a/src/ast/simplifier/elim_bounds.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - elim_bounds.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-28. - -Revision History: - ---*/ -#include "ast/simplifier/elim_bounds.h" -#include "ast/used_vars.h" -#include "util/obj_hashtable.h" -#include "ast/rewriter/var_subst.h" -#include "ast/ast_pp.h" - -elim_bounds::elim_bounds(ast_manager & m): - m_manager(m), - m_util(m) { -} - -/** - \brief Find bounds of the form - - (<= x k) - (<= (+ x (* -1 y)) k) - (<= (+ x (* -1 t)) k) - (<= (+ t (* -1 x)) k) - - x and y are a bound variables, t is a ground term and k is a numeral - - It also detects >=, and the atom can be negated. -*/ -bool elim_bounds::is_bound(expr * n, var * & lower, var * & upper) { - upper = 0; - lower = 0; - bool neg = false; - if (m_manager.is_not(n)) { - n = to_app(n)->get_arg(0); - neg = true; - } - - bool le = false; - if (m_util.is_le(n)) { - SASSERT(m_util.is_numeral(to_app(n)->get_arg(1))); - n = to_app(n)->get_arg(0); - le = true; - } - else if (m_util.is_ge(n)) { - SASSERT(m_util.is_numeral(to_app(n)->get_arg(1))); - n = to_app(n)->get_arg(0); - le = false; - } - else { - return false; - } - - if (neg) - le = !le; - - if (is_var(n)) { - upper = to_var(n); - } - else if (m_util.is_add(n) && to_app(n)->get_num_args() == 2) { - expr * arg1 = to_app(n)->get_arg(0); - expr * arg2 = to_app(n)->get_arg(1); - if (is_var(arg1)) - upper = to_var(arg1); - else if (!is_ground(arg1)) - return false; - rational k; - bool is_int; - if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) { - arg2 = to_app(arg2)->get_arg(1); - if (is_var(arg2)) - lower = to_var(arg2); - else if (!is_ground(arg2)) - return false; // not supported - } - else { - return false; // not supported - } - } - else { - return false; - } - - if (!le) - std::swap(upper, lower); - - return true; -} - -bool elim_bounds::is_bound(expr * n) { - var * lower, * upper; - return is_bound(n, lower, upper); -} - -void elim_bounds::operator()(quantifier * q, expr_ref & r) { - if (!q->is_forall()) { - r = q; - return; - } - expr * n = q->get_expr(); - unsigned num_vars = q->get_num_decls(); - ptr_buffer atoms; - if (m_manager.is_or(n)) - atoms.append(to_app(n)->get_num_args(), to_app(n)->get_args()); - else - atoms.push_back(n); - used_vars m_used_vars; - // collect non-candidates - unsigned sz = atoms.size(); - for (unsigned i = 0; i < sz; i++) { - expr * a = atoms[i]; - if (!is_bound(a)) - m_used_vars.process(a); - } - if (m_used_vars.uses_all_vars(q->get_num_decls())) { - r = q; - return; - } - // collect candidates - obj_hashtable m_lowers; - obj_hashtable m_uppers; - obj_hashtable m_candidate_set; - ptr_buffer m_candidates; -#define ADD_CANDIDATE(V) if (!m_lowers.contains(V) && !m_uppers.contains(V)) { m_candidate_set.insert(V); m_candidates.push_back(V); } - for (unsigned i = 0; i < sz; i++) { - expr * a = atoms[i]; - var * lower = 0; - var * upper = 0; - if (is_bound(a, lower, upper)) { - if (lower != 0 && !m_used_vars.contains(lower->get_idx()) && lower->get_idx() < num_vars) { - ADD_CANDIDATE(lower); - m_lowers.insert(lower); - } - if (upper != 0 && !m_used_vars.contains(upper->get_idx()) && upper->get_idx() < num_vars) { - ADD_CANDIDATE(upper); - m_uppers.insert(upper); - } - } - } - TRACE("elim_bounds", tout << "candidates:\n"; for (unsigned i = 0; i < m_candidates.size(); i++) tout << mk_pp(m_candidates[i], m_manager) << "\n";); - // remove candidates that have lower and upper bounds - for (unsigned i = 0; i < m_candidates.size(); i++) { - var * v = m_candidates[i]; - if (m_lowers.contains(v) && m_uppers.contains(v)) - m_candidate_set.erase(v); - } - TRACE("elim_bounds", tout << "candidates after filter:\n"; for (unsigned i = 0; i < m_candidates.size(); i++) tout << mk_pp(m_candidates[i], m_manager) << "\n";); - if (m_candidate_set.empty()) { - r = q; - return; - } - // remove bounds that contain variables in m_candidate_set - unsigned j = 0; - for (unsigned i = 0; i < sz; i++) { - expr * a = atoms[i]; - var * lower = 0; - var * upper = 0; - if (is_bound(a, lower, upper) && ((lower != 0 && m_candidate_set.contains(lower)) || (upper != 0 && m_candidate_set.contains(upper)))) - continue; - atoms[j] = a; - j++; - } - atoms.resize(j); - expr * new_body = 0; - switch (atoms.size()) { - case 0: - r = m_manager.mk_false(); - TRACE("elim_bounds", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";); - return; - case 1: - new_body = atoms[0]; - break; - default: - new_body = m_manager.mk_or(atoms.size(), atoms.c_ptr()); - break; - } - quantifier_ref new_q(m_manager); - new_q = m_manager.update_quantifier(q, new_body); - elim_unused_vars(m_manager, new_q, params_ref(), r); - TRACE("elim_bounds", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";); -} - -bool elim_bounds_star::visit_quantifier(quantifier * q) { - if (!q->is_forall() || q->get_num_patterns() != 0) - return true; - bool visited = true; - visit(q->get_expr(), visited); - return visited; -} - -void elim_bounds_star::reduce1_quantifier(quantifier * q) { - if (!q->is_forall() || q->get_num_patterns() != 0) { - cache_result(q, q, 0); - return; - } - quantifier_ref new_q(m); - expr * new_body = 0; - proof * new_pr; - get_cached(q->get_expr(), new_body, new_pr); - new_q = m.update_quantifier(q, new_body); - expr_ref r(m); - m_elim(new_q, r); - if (q == r.get()) { - cache_result(q, q, 0); - return; - } - proof_ref pr(m); - if (m.fine_grain_proofs()) - pr = m.mk_rewrite(q, r); // TODO: improve justification - cache_result(q, r, pr); -} - diff --git a/src/ast/simplifier/elim_bounds.h b/src/ast/simplifier/elim_bounds.h deleted file mode 100644 index d4da953a8..000000000 --- a/src/ast/simplifier/elim_bounds.h +++ /dev/null @@ -1,69 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - elim_bounds.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-28. - -Revision History: - ---*/ -#ifndef ELIM_BOUNDS_H_ -#define ELIM_BOUNDS_H_ - -#include "ast/ast.h" -#include "ast/arith_decl_plugin.h" -#include "ast/simplifier/simplifier.h" - -/** - \brief Functor for eliminating irrelevant bounds in quantified formulas. - - Example: - (forall (x Int) (y Int) (or (not (>= y x) (not (>= x 0)) (= (select a x) 1)))) - - The bound (>= y x) is irrelevant and can be eliminated. - - This can be easily proved by using Fourier-Motzkin elimination. - - Limitations & Assumptions: - - It assumes the input formula was already simplified. - - It can only handle bounds in the diff-logic fragment. - - \remark This operation is subsumed by Fourier-Motzkin elimination. -*/ -class elim_bounds { - ast_manager & m_manager; - arith_util m_util; - bool is_bound(expr * n, var * & lower, var * & upper); - bool is_bound(expr * n); -public: - elim_bounds(ast_manager & m); - void operator()(quantifier * q, expr_ref & r); -}; - -/** - \brief Functor for applying elim_bounds in all - universal quantifiers in an expression. - - Assumption: the formula was already skolemized. -*/ -class elim_bounds_star : public simplifier { -protected: - elim_bounds m_elim; - virtual bool visit_quantifier(quantifier * q); - virtual void reduce1_quantifier(quantifier * q); -public: - elim_bounds_star(ast_manager & m):simplifier(m), m_elim(m) { enable_ac_support(false); } - virtual ~elim_bounds_star() {} -}; - -#endif /* ELIM_BOUNDS_H_ */ - diff --git a/src/ast/simplifier/fpa_simplifier_plugin.cpp b/src/ast/simplifier/fpa_simplifier_plugin.cpp deleted file mode 100644 index 2d333c872..000000000 --- a/src/ast/simplifier/fpa_simplifier_plugin.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*++ -Copyright (c) 2015 Microsoft Corporation - -Module Name: - - fpa_simplifier_plugin.cpp - -Abstract: - - Simplifier for the floating-point theory - -Author: - - Christoph (cwinter) 2015-01-14 - ---*/ -#include "ast/simplifier/fpa_simplifier_plugin.h" - -fpa_simplifier_plugin::fpa_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b) : -simplifier_plugin(symbol("fpa"), m), -m_util(m), -m_rw(m) {} - -fpa_simplifier_plugin::~fpa_simplifier_plugin() {} - -bool fpa_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - - SASSERT(f->get_family_id() == get_family_id()); - - return m_rw.mk_app_core(f, num_args, args, result) != BR_FAILED; -} - -bool fpa_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { - set_reduce_invoked(); - - return m_rw.mk_eq_core(lhs, rhs, result) != BR_FAILED; -} - diff --git a/src/ast/simplifier/fpa_simplifier_plugin.h b/src/ast/simplifier/fpa_simplifier_plugin.h deleted file mode 100644 index 8c9f8de4e..000000000 --- a/src/ast/simplifier/fpa_simplifier_plugin.h +++ /dev/null @@ -1,39 +0,0 @@ -/*++ -Copyright (c) 2015 Microsoft Corporation - -Module Name: - - fpa_simplifier_plugin.h - -Abstract: - - Simplifier for the floating-point theory - -Author: - - Christoph (cwinter) 2015-01-14 - ---*/ -#ifndef FPA_SIMPLIFIER_PLUGIN_H_ -#define FPA_SIMPLIFIER_PLUGIN_H_ - -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/fpa_decl_plugin.h" -#include "ast/rewriter/fpa_rewriter.h" - -class fpa_simplifier_plugin : public simplifier_plugin { - fpa_util m_util; - fpa_rewriter m_rw; - -public: - fpa_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b); - ~fpa_simplifier_plugin(); - - - 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); - -}; - -#endif /* FPA_SIMPLIFIER_PLUGIN_H_ */ diff --git a/src/ast/simplifier/poly_simplifier_plugin.cpp b/src/ast/simplifier/poly_simplifier_plugin.cpp deleted file mode 100644 index 88637d694..000000000 --- a/src/ast/simplifier/poly_simplifier_plugin.cpp +++ /dev/null @@ -1,835 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - poly_simplifier_plugin.cpp - -Abstract: - - Abstract class for families that have polynomials. - -Author: - - Leonardo (leonardo) 2008-01-08 - ---*/ -#include "ast/simplifier/poly_simplifier_plugin.h" -#include "ast/ast_pp.h" -#include "ast/ast_util.h" -#include "ast/ast_smt2_pp.h" -#include "ast/ast_ll_pp.h" - -poly_simplifier_plugin::poly_simplifier_plugin(symbol const & fname, ast_manager & m, decl_kind add, decl_kind mul, decl_kind uminus, decl_kind sub, - decl_kind num): - simplifier_plugin(fname, m), - m_ADD(add), - m_MUL(mul), - m_SUB(sub), - m_UMINUS(uminus), - m_NUM(num), - m_curr_sort(0), - m_curr_sort_zero(0) { -} - -expr * poly_simplifier_plugin::mk_add(unsigned num_args, expr * const * args) { - SASSERT(num_args > 0); -#ifdef Z3DEBUG - // check for incorrect use of mk_add - for (unsigned i = 0; i < num_args; i++) { - SASSERT(!is_zero(args[i])); - } -#endif - if (num_args == 1) - return args[0]; - else - return m_manager.mk_app(m_fid, m_ADD, num_args, args); -} - -expr * poly_simplifier_plugin::mk_mul(unsigned num_args, expr * const * args) { - SASSERT(num_args > 0); -#ifdef Z3DEBUG - // check for incorrect use of mk_mul - set_curr_sort(args[0]); - SASSERT(!is_zero(args[0])); - numeral k; - for (unsigned i = 0; i < num_args; i++) { - SASSERT(!is_numeral(args[i], k) || !k.is_one()); - SASSERT(i == 0 || !is_numeral(args[i])); - } -#endif - if (num_args == 1) - return args[0]; - else if (num_args == 2) - return m_manager.mk_app(m_fid, m_MUL, args[0], args[1]); - else if (is_numeral(args[0])) - return m_manager.mk_app(m_fid, m_MUL, args[0], m_manager.mk_app(m_fid, m_MUL, num_args - 1, args+1)); - else - return m_manager.mk_app(m_fid, m_MUL, num_args, args); -} - -expr * poly_simplifier_plugin::mk_mul(numeral const & c, expr * body) { - numeral c_prime, d; - c_prime = norm(c); - if (c_prime.is_zero()) - return 0; - if (body == 0) - return mk_numeral(c_prime); - if (c_prime.is_one()) - return body; - if (is_numeral(body, d)) { - c_prime = norm(c_prime*d); - if (c_prime.is_zero()) - return 0; - return mk_numeral(c_prime); - } - set_curr_sort(body); - expr * args[2] = { mk_numeral(c_prime), body }; - return mk_mul(2, args); -} - -/** - \brief Traverse args, and copy the non-numeral exprs to result, and accumulate the - value of the numerals in k. -*/ -void poly_simplifier_plugin::process_monomial(unsigned num_args, expr * const * args, numeral & k, ptr_buffer & result) { - rational v; - for (unsigned i = 0; i < num_args; i++) { - expr * arg = args[i]; - if (is_numeral(arg, v)) - k *= v; - else - result.push_back(arg); - } -} - -#ifdef Z3DEBUG -/** - \brief Return true if m is a wellformed monomial. -*/ -bool poly_simplifier_plugin::wf_monomial(expr * m) const { - SASSERT(!is_add(m)); - if (is_mul(m)) { - app * curr = to_app(m); - expr * pp = 0; - if (is_numeral(curr->get_arg(0))) - pp = curr->get_arg(1); - else - pp = curr; - if (is_mul(pp)) { - for (unsigned i = 0; i < to_app(pp)->get_num_args(); i++) { - expr * arg = to_app(pp)->get_arg(i); - CTRACE("wf_monomial_bug", is_mul(arg), - tout << "m: " << mk_ismt2_pp(m, m_manager) << "\n"; - tout << "pp: " << mk_ismt2_pp(pp, m_manager) << "\n"; - tout << "arg: " << mk_ismt2_pp(arg, m_manager) << "\n"; - tout << "i: " << i << "\n"; - ); - SASSERT(!is_mul(arg)); - SASSERT(!is_numeral(arg)); - } - } - } - return true; -} - -/** - \brief Return true if m is a wellformed polynomial. -*/ -bool poly_simplifier_plugin::wf_polynomial(expr * m) const { - if (is_add(m)) { - for (unsigned i = 0; i < to_app(m)->get_num_args(); i++) { - expr * arg = to_app(m)->get_arg(i); - SASSERT(!is_add(arg)); - SASSERT(wf_monomial(arg)); - } - } - else if (is_mul(m)) { - SASSERT(wf_monomial(m)); - } - return true; -} -#endif - -/** - \brief Functor used to sort the elements of a monomial. - Force numeric constants to be in the beginning. -*/ -struct monomial_element_lt_proc { - poly_simplifier_plugin & m_plugin; - monomial_element_lt_proc(poly_simplifier_plugin & p):m_plugin(p) {} - bool operator()(expr * m1, expr * m2) const { - SASSERT(!m_plugin.is_numeral(m1) || !m_plugin.is_numeral(m2)); - if (m_plugin.is_numeral(m1)) - return true; - if (m_plugin.is_numeral(m2)) - return false; - return m1->get_id() < m2->get_id(); - } -}; - -/** - \brief Create a monomial (* args). -*/ -void poly_simplifier_plugin::mk_monomial(unsigned num_args, expr * * args, expr_ref & result) { - switch(num_args) { - case 0: - result = mk_one(); - break; - case 1: - result = args[0]; - break; - default: - std::stable_sort(args, args + num_args, monomial_element_lt_proc(*this)); - result = mk_mul(num_args, args); - SASSERT(wf_monomial(result)); - break; - } -} - -/** - \brief Return the body of the monomial. That is, the monomial without a coefficient. - Examples: (* 2 (* x y)) ==> (* x y) - (* x x) ==> (* x x) - x ==> x - 10 ==> 10 -*/ -expr * poly_simplifier_plugin::get_monomial_body(expr * m) { - TRACE("get_monomial_body_bug", tout << mk_pp(m, m_manager) << "\n";); - SASSERT(wf_monomial(m)); - if (!is_mul(m)) - return m; - if (is_numeral(to_app(m)->get_arg(0))) - return to_app(m)->get_arg(1); - return m; -} - -inline bool is_essentially_var(expr * n, family_id fid) { - SASSERT(is_var(n) || is_app(n)); - return is_var(n) || to_app(n)->get_family_id() != fid; -} - -/** - \brief Hack for ordering monomials. - We want an order << where - - (* c1 m1) << (* c2 m2) when m1->get_id() < m2->get_id(), and c1 and c2 are numerals. - - c << m when c is a numeral, and m is not. - - So, this method returns -1 for numerals, and the id of the body of the monomial -*/ -int poly_simplifier_plugin::get_monomial_body_order(expr * m) { - if (is_essentially_var(m, m_fid)) { - return m->get_id(); - } - else if (is_mul(m)) { - if (is_numeral(to_app(m)->get_arg(0))) - return to_app(m)->get_arg(1)->get_id(); - else - return m->get_id(); - } - else if (is_numeral(m)) { - return -1; - } - else { - return m->get_id(); - } -} - -void poly_simplifier_plugin::get_monomial_coeff(expr * m, numeral & result) { - SASSERT(!is_numeral(m)); - SASSERT(wf_monomial(m)); - if (!is_mul(m)) - result = numeral::one(); - else if (is_numeral(to_app(m)->get_arg(0), result)) - return; - else - result = numeral::one(); -} - -/** - \brief Return true if n1 and n2 can be written as k1 * t and k2 * t, where k1 and - k2 are numerals, or n1 and n2 are both numerals. -*/ -bool poly_simplifier_plugin::eq_monomials_modulo_k(expr * n1, expr * n2) { - bool is_num1 = is_numeral(n1); - bool is_num2 = is_numeral(n2); - if (is_num1 != is_num2) - return false; - if (is_num1 && is_num2) - return true; - return get_monomial_body(n1) == get_monomial_body(n2); -} - -/** - \brief Return (k1 + k2) * t (or (k1 - k2) * t when inv = true), where n1 = k1 * t, and n2 = k2 * t - Return false if the monomials cancel each other. -*/ -bool poly_simplifier_plugin::merge_monomials(bool inv, expr * n1, expr * n2, expr_ref & result) { - numeral k1; - numeral k2; - bool is_num1 = is_numeral(n1, k1); - bool is_num2 = is_numeral(n2, k2); - SASSERT(is_num1 == is_num2); - if (!is_num1 && !is_num2) { - get_monomial_coeff(n1, k1); - get_monomial_coeff(n2, k2); - SASSERT(eq_monomials_modulo_k(n1, n2)); - } - if (inv) - k1 -= k2; - else - k1 += k2; - if (k1.is_zero()) - return false; - if (is_num1 && is_num2) { - result = mk_numeral(k1); - } - else { - expr * b = get_monomial_body(n1); - if (k1.is_one()) - result = b; - else - result = m_manager.mk_app(m_fid, m_MUL, mk_numeral(k1), b); - } - TRACE("merge_monomials", tout << mk_pp(n1, m_manager) << "\n" << mk_pp(n2, m_manager) << "\n" << mk_pp(result, m_manager) << "\n";); - return true; -} - -/** - \brief Return a monomial equivalent to -n. -*/ -void poly_simplifier_plugin::inv_monomial(expr * n, expr_ref & result) { - set_curr_sort(n); - SASSERT(wf_monomial(n)); - rational v; - SASSERT(n != 0); - TRACE("inv_monomial_bug", tout << "n:\n" << mk_ismt2_pp(n, m_manager) << "\n";); - if (is_numeral(n, v)) { - TRACE("inv_monomial_bug", tout << "is numeral\n";); - v.neg(); - result = mk_numeral(v); - } - else { - TRACE("inv_monomial_bug", tout << "is not numeral\n";); - numeral k; - get_monomial_coeff(n, k); - expr * b = get_monomial_body(n); - k.neg(); - if (k.is_one()) - result = b; - else - result = m_manager.mk_app(m_fid, m_MUL, mk_numeral(k), b); - } -} - -/** - \brief Add a monomial n to result. -*/ -template -void poly_simplifier_plugin::add_monomial_core(expr * n, expr_ref_vector & result) { - if (is_zero(n)) - return; - if (Inv) { - expr_ref n_prime(m_manager); - inv_monomial(n, n_prime); - result.push_back(n_prime); - } - else { - result.push_back(n); - } -} - -void poly_simplifier_plugin::add_monomial(bool inv, expr * n, expr_ref_vector & result) { - if (inv) - add_monomial_core(n, result); - else - add_monomial_core(n, result); -} - -/** - \brief Copy the monomials in n to result. The monomials are inverted if inv is true. - Equivalent monomials are merged. -*/ -template -void poly_simplifier_plugin::process_sum_of_monomials_core(expr * n, expr_ref_vector & result) { - SASSERT(wf_polynomial(n)); - if (is_add(n)) { - for (unsigned i = 0; i < to_app(n)->get_num_args(); i++) - add_monomial_core(to_app(n)->get_arg(i), result); - } - else { - add_monomial_core(n, result); - } -} - -void poly_simplifier_plugin::process_sum_of_monomials(bool inv, expr * n, expr_ref_vector & result) { - if (inv) - process_sum_of_monomials_core(n, result); - else - process_sum_of_monomials_core(n, result); -} - -/** - \brief Copy the (non-numeral) monomials in n to result. The monomials are inverted if inv is true. - Equivalent monomials are merged. The constant (numeral) monomials are accumulated in k. -*/ -void poly_simplifier_plugin::process_sum_of_monomials(bool inv, expr * n, expr_ref_vector & result, numeral & k) { - SASSERT(wf_polynomial(n)); - numeral val; - if (is_add(n)) { - for (unsigned i = 0; i < to_app(n)->get_num_args(); i++) { - expr * arg = to_app(n)->get_arg(i); - if (is_numeral(arg, val)) { - k += inv ? -val : val; - } - else { - add_monomial(inv, arg, result); - } - } - } - else if (is_numeral(n, val)) { - k += inv ? -val : val; - } - else { - add_monomial(inv, n, result); - } -} - -/** - \brief Functor used to sort monomials. - Force numeric constants to be in the beginning of a polynomial. -*/ -struct monomial_lt_proc { - poly_simplifier_plugin & m_plugin; - monomial_lt_proc(poly_simplifier_plugin & p):m_plugin(p) {} - bool operator()(expr * m1, expr * m2) const { - return m_plugin.get_monomial_body_order(m1) < m_plugin.get_monomial_body_order(m2); - } -}; - -void poly_simplifier_plugin::mk_sum_of_monomials_core(unsigned sz, expr ** ms, expr_ref & result) { - switch (sz) { - case 0: - result = mk_zero(); - break; - case 1: - result = ms[0]; - break; - default: - result = mk_add(sz, ms); - break; - } -} - -/** - \brief Return true if m is essentially a variable, or is of the form (* c x), - where c is a numeral and x is essentially a variable. - Store the "variable" in x. -*/ -bool poly_simplifier_plugin::is_simple_monomial(expr * m, expr * & x) { - if (is_essentially_var(m, m_fid)) { - x = m; - return true; - } - if (is_app(m) && to_app(m)->get_num_args() == 2) { - expr * arg1 = to_app(m)->get_arg(0); - expr * arg2 = to_app(m)->get_arg(1); - if (is_numeral(arg1) && is_essentially_var(arg2, m_fid)) { - x = arg2; - return true; - } - } - return false; -} - -/** - \brief Return true if all monomials are simple, and each "variable" occurs only once. - The method assumes the monomials were sorted using monomial_lt_proc. -*/ -bool poly_simplifier_plugin::is_simple_sum_of_monomials(expr_ref_vector & monomials) { - expr * last_var = 0; - expr * curr_var = 0; - unsigned size = monomials.size(); - for (unsigned i = 0; i < size; i++) { - expr * m = monomials.get(i); - if (!is_simple_monomial(m, curr_var)) - return false; - if (curr_var == last_var) - return false; - last_var = curr_var; - } - return true; -} - -/** - \brief Store in result the sum of the given monomials. -*/ -void poly_simplifier_plugin::mk_sum_of_monomials(expr_ref_vector & monomials, expr_ref & result) { - switch (monomials.size()) { - case 0: - result = mk_zero(); - break; - case 1: - result = monomials.get(0); - break; - default: { - TRACE("mk_sum_sort", tout << "before\n"; for (unsigned i = 0; i < monomials.size(); i++) tout << mk_ll_pp(monomials.get(i), m_manager) << "\n";); - std::stable_sort(monomials.c_ptr(), monomials.c_ptr() + monomials.size(), monomial_lt_proc(*this)); - TRACE("mk_sum_sort", tout << "after\n"; for (unsigned i = 0; i < monomials.size(); i++) tout << mk_ll_pp(monomials.get(i), m_manager) << "\n";); - if (is_simple_sum_of_monomials(monomials)) { - mk_sum_of_monomials_core(monomials.size(), monomials.c_ptr(), result); - return; - } - ptr_buffer new_monomials; - expr * last_body = 0; - numeral last_coeff; - numeral coeff; - unsigned sz = monomials.size(); - for (unsigned i = 0; i < sz; i++) { - expr * m = monomials.get(i); - expr * body = 0; - if (!is_numeral(m, coeff)) { - body = get_monomial_body(m); - get_monomial_coeff(m, coeff); - } - if (last_body == body) { - last_coeff += coeff; - continue; - } - expr * new_m = mk_mul(last_coeff, last_body); - if (new_m) - new_monomials.push_back(new_m); - last_body = body; - last_coeff = coeff; - } - expr * new_m = mk_mul(last_coeff, last_body); - if (new_m) - new_monomials.push_back(new_m); - TRACE("mk_sum", for (unsigned i = 0; i < monomials.size(); i++) tout << mk_pp(monomials.get(i), m_manager) << "\n"; - tout << "======>\n"; - for (unsigned i = 0; i < new_monomials.size(); i++) tout << mk_pp(new_monomials.get(i), m_manager) << "\n";); - mk_sum_of_monomials_core(new_monomials.size(), new_monomials.c_ptr(), result); - break; - } } -} - -/** - \brief Auxiliary template for mk_add_core -*/ -template -void poly_simplifier_plugin::mk_add_core_core(unsigned num_args, expr * const * args, expr_ref & result) { - SASSERT(num_args >= 2); - expr_ref_vector monomials(m_manager); - process_sum_of_monomials_core(args[0], monomials); - for (unsigned i = 1; i < num_args; i++) { - process_sum_of_monomials_core(args[i], monomials); - } - TRACE("mk_add_core_bug", - for (unsigned i = 0; i < monomials.size(); i++) { - SASSERT(monomials.get(i) != 0); - tout << mk_ismt2_pp(monomials.get(i), m_manager) << "\n"; - }); - mk_sum_of_monomials(monomials, result); -} - -/** - \brief Return a sum of monomials. The method assume that each arg in args is a sum of monomials. - If inv is true, then all but the first argument in args are inverted. -*/ -void poly_simplifier_plugin::mk_add_core(bool inv, unsigned num_args, expr * const * args, expr_ref & result) { - TRACE("mk_add_core_bug", - for (unsigned i = 0; i < num_args; i++) { - SASSERT(args[i] != 0); - tout << mk_ismt2_pp(args[i], m_manager) << "\n"; - }); - switch (num_args) { - case 0: - result = mk_zero(); - break; - case 1: - result = args[0]; - break; - default: - if (inv) - mk_add_core_core(num_args, args, result); - else - mk_add_core_core(num_args, args, result); - break; - } -} - -void poly_simplifier_plugin::mk_add(unsigned num_args, expr * const * args, expr_ref & result) { - SASSERT(num_args > 0); - set_curr_sort(args[0]); - mk_add_core(false, num_args, args, result); -} - -void poly_simplifier_plugin::mk_add(expr * arg1, expr * arg2, expr_ref & result) { - expr * args[2] = { arg1, arg2 }; - mk_add(2, args, result); -} - -void poly_simplifier_plugin::mk_sub(unsigned num_args, expr * const * args, expr_ref & result) { - SASSERT(num_args > 0); - set_curr_sort(args[0]); - mk_add_core(true, num_args, args, result); -} - -void poly_simplifier_plugin::mk_sub(expr * arg1, expr * arg2, expr_ref & result) { - expr * args[2] = { arg1, arg2 }; - mk_sub(2, args, result); -} - -void poly_simplifier_plugin::mk_uminus(expr * arg, expr_ref & result) { - set_curr_sort(arg); - rational v; - if (is_numeral(arg, v)) { - v.neg(); - result = mk_numeral(v); - } - else { - expr_ref zero(mk_zero(), m_manager); - mk_sub(zero.get(), arg, result); - } -} - -/** - \brief Add monomial n to result, the coeff of n is stored in k. -*/ -void poly_simplifier_plugin::append_to_monomial(expr * n, numeral & k, ptr_buffer & result) { - SASSERT(wf_monomial(n)); - rational val; - if (is_numeral(n, val)) { - k *= val; - return; - } - get_monomial_coeff(n, val); - k *= val; - n = get_monomial_body(n); - - unsigned hd = result.size(); - result.push_back(n); - while (hd < result.size()) { - n = result[hd]; - if (is_mul(n)) { - result[hd] = result.back(); - result.pop_back(); - for (unsigned i = 0; i < to_app(n)->get_num_args(); i++) { - result.push_back(to_app(n)->get_arg(i)); - } - } - else if (is_numeral(n, val)) { - k *= val; - result[hd] = result.back(); - result.pop_back(); - } - else { - ++hd; - } - } -} - -/** - \brief Return a sum of monomials that is equivalent to (* args[0] ... args[num_args-1]). - This method assumes that each arg[i] is a sum of monomials. -*/ -void poly_simplifier_plugin::mk_mul(unsigned num_args, expr * const * args, expr_ref & result) { - if (num_args == 1) { - result = args[0]; - return; - } - rational val; - if (num_args == 2 && is_numeral(args[0], val) && is_essentially_var(args[1], m_fid)) { - if (val.is_one()) - result = args[1]; - else if (val.is_zero()) - result = args[0]; - else - result = mk_mul(num_args, args); - return; - } - if (num_args == 2 && is_essentially_var(args[0], m_fid) && is_numeral(args[1], val)) { - if (val.is_one()) - result = args[0]; - else if (val.is_zero()) - result = args[1]; - else { - expr * inv_args[2] = { args[1], args[0] }; - result = mk_mul(2, inv_args); - } - return; - } - - TRACE("mk_mul_bug", - for (unsigned i = 0; i < num_args; i++) { - tout << mk_pp(args[i], m_manager) << "\n"; - }); - set_curr_sort(args[0]); - buffer szs; - buffer it; - vector > sums; - for (unsigned i = 0; i < num_args; i ++) { - it.push_back(0); - expr * arg = args[i]; - SASSERT(wf_polynomial(arg)); - sums.push_back(ptr_vector()); - ptr_vector & v = sums.back(); - if (is_add(arg)) { - v.append(to_app(arg)->get_num_args(), to_app(arg)->get_args()); - } - else { - v.push_back(arg); - } - szs.push_back(v.size()); - } - expr_ref_vector monomials(m_manager); - do { - rational k(1); - ptr_buffer m; - for (unsigned i = 0; i < num_args; i++) { - ptr_vector & v = sums[i]; - expr * arg = v[it[i]]; - TRACE("mk_mul_bug", tout << "k: " << k << " arg: " << mk_pp(arg, m_manager) << "\n";); - append_to_monomial(arg, k, m); - TRACE("mk_mul_bug", tout << "after k: " << k << "\n";); - } - expr_ref num(m_manager); - if (!k.is_zero() && !k.is_one()) { - num = mk_numeral(k); - m.push_back(num); - // bit-vectors can normalize - // to 1 during - // internalization. - if (is_numeral(num, k) && k.is_one()) { - m.pop_back(); - } - } - if (!k.is_zero()) { - expr_ref new_monomial(m_manager); - TRACE("mk_mul_bug", - for (unsigned i = 0; i < m.size(); i++) { - tout << mk_pp(m[i], m_manager) << "\n"; - }); - mk_monomial(m.size(), m.c_ptr(), new_monomial); - TRACE("mk_mul_bug", tout << "new_monomial:\n" << mk_pp(new_monomial, m_manager) << "\n";); - add_monomial_core(new_monomial, monomials); - } - } - while (product_iterator_next(szs.size(), szs.c_ptr(), it.c_ptr())); - mk_sum_of_monomials(monomials, result); -} - -void poly_simplifier_plugin::mk_mul(expr * arg1, expr * arg2, expr_ref & result) { - expr * args[2] = { arg1, arg2 }; - mk_mul(2, args, result); -} - -bool poly_simplifier_plugin::reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - unsigned i = 0; - for (; i < num_args; i++) - if (!is_numeral(args[i])) - break; - if (i == num_args) { - // all arguments are numerals - // check if arguments are different... - ptr_buffer buffer; - buffer.append(num_args, args); - std::sort(buffer.begin(), buffer.end(), ast_lt_proc()); - for (unsigned i = 0; i < num_args; i++) { - if (i > 0 && buffer[i] == buffer[i-1]) { - result = m_manager.mk_false(); - return true; - } - } - result = m_manager.mk_true(); - return true; - } - return false; -} - -bool poly_simplifier_plugin::reduce(func_decl * f, unsigned num_args, rational const * mults, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - if (is_decl_of(f, m_fid, m_ADD)) { - SASSERT(num_args > 0); - set_curr_sort(args[0]); - expr_ref_buffer args1(m_manager); - for (unsigned i = 0; i < num_args; ++i) { - expr * arg = args[i]; - rational m = norm(mults[i]); - if (m.is_zero()) { - // skip - } - else if (m.is_one()) { - args1.push_back(arg); - } - else { - expr_ref k(m_manager); - k = mk_numeral(m); - expr_ref new_arg(m_manager); - mk_mul(k, args[i], new_arg); - args1.push_back(new_arg); - } - } - if (args1.empty()) { - result = mk_zero(); - } - else { - mk_add(args1.size(), args1.c_ptr(), result); - } - return true; - } - else { - return simplifier_plugin::reduce(f, num_args, mults, args, result); - } -} - -/** - \brief Return true if n is can be put into the form (+ v t) or (+ (- v) t) - \c inv = true will contain true if (- v) is found, and false otherwise. -*/ -bool poly_simplifier_plugin::is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t) { - if (!is_add(n) || is_ground(n)) - return false; - - ptr_buffer args; - v = 0; - expr * curr = to_app(n); - bool stop = false; - inv = false; - while (!stop) { - expr * arg; - expr * neg_arg; - if (is_add(curr)) { - arg = to_app(curr)->get_arg(0); - curr = to_app(curr)->get_arg(1); - } - else { - arg = curr; - stop = true; - } - if (is_ground(arg)) { - TRACE("model_checker_bug", tout << "pushing:\n" << mk_pp(arg, m_manager) << "\n";); - args.push_back(arg); - } - else if (is_var(arg)) { - if (v != 0) - return false; // already found variable - v = to_var(arg); - } - else if (is_times_minus_one(arg, neg_arg) && is_var(neg_arg)) { - if (v != 0) - return false; // already found variable - v = to_var(neg_arg); - inv = true; - } - else { - return false; // non ground term. - } - } - if (v == 0) - return false; // did not find variable - SASSERT(!args.empty()); - mk_add(args.size(), args.c_ptr(), t); - return true; -} diff --git a/src/ast/simplifier/poly_simplifier_plugin.h b/src/ast/simplifier/poly_simplifier_plugin.h deleted file mode 100644 index fe5572b20..000000000 --- a/src/ast/simplifier/poly_simplifier_plugin.h +++ /dev/null @@ -1,155 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - poly_simplifier_plugin.h - -Abstract: - - Abstract class for families that have polynomials. - -Author: - - Leonardo (leonardo) 2008-01-08 - ---*/ -#ifndef POLY_SIMPLIFIER_PLUGIN_H_ -#define POLY_SIMPLIFIER_PLUGIN_H_ - -#include "ast/simplifier/simplifier_plugin.h" - -/** - \brief Abstract class that provides simplification functions for polynomials. -*/ -class poly_simplifier_plugin : public simplifier_plugin { -protected: - typedef rational numeral; - decl_kind m_ADD; - decl_kind m_MUL; - decl_kind m_SUB; - decl_kind m_UMINUS; - decl_kind m_NUM; - sort * m_curr_sort; - expr * m_curr_sort_zero; - - expr * mk_add(unsigned num_args, expr * const * args); - expr * mk_add(expr * arg1, expr * arg2) { expr * args[2] = { arg1, arg2 }; return mk_add(2, args); } - expr * mk_mul(unsigned num_args, expr * const * args); - expr * mk_mul(expr * arg1, expr * arg2) { expr * args[2] = { arg1, arg2 }; return mk_mul(2, args); } - // expr * mk_sub(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_fid, m_SUB, num_args, args); } - expr * mk_uminus(expr * arg) { return m_manager.mk_app(m_fid, m_UMINUS, arg); } - - void process_monomial(unsigned num_args, expr * const * args, numeral & k, ptr_buffer & result); - void mk_monomial(unsigned num_args, expr * * args, expr_ref & result); - bool eq_monomials_modulo_k(expr * n1, expr * n2); - bool merge_monomials(bool inv, expr * n1, expr * n2, expr_ref & result); - template - void add_monomial_core(expr * n, expr_ref_vector & result); - void add_monomial(bool inv, expr * n, expr_ref_vector & result); - template - void process_sum_of_monomials_core(expr * n, expr_ref_vector & result); - void process_sum_of_monomials(bool inv, expr * n, expr_ref_vector & result); - void process_sum_of_monomials(bool inv, expr * n, expr_ref_vector & result, numeral & k); - void mk_sum_of_monomials(expr_ref_vector & monomials, expr_ref & result); - template - void mk_add_core_core(unsigned num_args, expr * const * args, expr_ref & result); - void mk_add_core(bool inv, unsigned num_args, expr * const * args, expr_ref & result); - void append_to_monomial(expr * n, numeral & k, ptr_buffer & result); - expr * mk_mul(numeral const & c, expr * body); - void mk_sum_of_monomials_core(unsigned sz, expr ** ms, expr_ref & result); - bool is_simple_sum_of_monomials(expr_ref_vector & monomials); - bool is_simple_monomial(expr * m, expr * & x); - -public: - poly_simplifier_plugin(symbol const & fname, ast_manager & m, decl_kind add, decl_kind mul, decl_kind uminus, decl_kind sub, decl_kind num); - virtual ~poly_simplifier_plugin() {} - - /** - \brief Return true if the given expression is a numeral, and store its value in \c val. - */ - virtual bool is_numeral(expr * n, numeral & val) const = 0; - bool is_numeral(expr * n) const { return is_app_of(n, m_fid, m_NUM); } - bool is_zero(expr * n) const { - SASSERT(m_curr_sort_zero != 0); - SASSERT(m_manager.get_sort(n) == m_manager.get_sort(m_curr_sort_zero)); - return n == m_curr_sort_zero; - } - bool is_zero_safe(expr * n) { - set_curr_sort(m_manager.get_sort(n)); - return is_zero(n); - } - virtual bool is_minus_one(expr * n) const = 0; - virtual expr * get_zero(sort * s) const = 0; - - - /** - \brief Return true if n is of the form (* -1 r) - */ - bool is_times_minus_one(expr * n, expr * & r) const { - if (is_mul(n) && to_app(n)->get_num_args() == 2 && is_minus_one(to_app(n)->get_arg(0))) { - r = to_app(n)->get_arg(1); - return true; - } - return false; - } - - /** - \brief Return true if n is of the form: a <= b or a >= b. - */ - virtual bool is_le_ge(expr * n) const = 0; - - /** - \brief Return a constant representing the giving numeral and sort m_curr_sort. - */ - virtual app * mk_numeral(numeral const & n) = 0; - app * mk_zero() { return mk_numeral(numeral::zero()); } - app * mk_one() { return mk_numeral(numeral::one()); } - app * mk_minus_one() { return mk_numeral(numeral::minus_one()); } - - /** - \brief Normalize the given numeral with respect to m_curr_sort - */ - virtual numeral norm(numeral const & n) = 0; - - void set_curr_sort(sort * s) { - if (s != m_curr_sort) { - // avoid virtual function call - m_curr_sort = s; - m_curr_sort_zero = get_zero(m_curr_sort); - } - } - void set_curr_sort(expr * n) { set_curr_sort(m_manager.get_sort(n)); } - - bool is_add(expr const * n) const { return is_app_of(n, m_fid, m_ADD); } - bool is_mul(expr const * n) const { return is_app_of(n, m_fid, m_MUL); } - void mk_add(unsigned num_args, expr * const * args, expr_ref & result); - void mk_add(expr * arg1, expr * arg2, expr_ref & result); - void mk_sub(unsigned num_args, expr * const * args, expr_ref & result); - void mk_sub(expr * arg1, expr * arg2, expr_ref & result); - void mk_uminus(expr * arg, expr_ref & result); - void mk_mul(unsigned num_args, expr * const * args, expr_ref & result); - void mk_mul(expr * arg1, expr * arg2, expr_ref & result); - - virtual bool reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result); - - virtual bool reduce(func_decl * f, unsigned num_args, rational const * mults, expr * const * args, expr_ref & result); - virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - return simplifier_plugin::reduce(f, num_args, args, result); - } - - - expr * get_monomial_body(expr * m); - int get_monomial_body_order(expr * m); - void get_monomial_coeff(expr * m, numeral & result); - void inv_monomial(expr * n, expr_ref & result); - - bool is_var_plus_ground(expr * n, bool & inv, var * & v, expr_ref & t); - -#ifdef Z3DEBUG - bool wf_monomial(expr * m) const; - bool wf_polynomial(expr * m) const; -#endif -}; - -#endif /* POLY_SIMPLIFIER_PLUGIN_H_ */ diff --git a/src/ast/simplifier/seq_simplifier_plugin.cpp b/src/ast/simplifier/seq_simplifier_plugin.cpp deleted file mode 100644 index 2125c4f4c..000000000 --- a/src/ast/simplifier/seq_simplifier_plugin.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*++ -Copyright (c) 2016 Microsoft Corporation - -Module Name: - - seq_simplifier_plugin.cpp - -Abstract: - - Simplifier for the theory of sequences - -Author: - - Nikolaj Bjorner (nbjorner) 2016-02-05 - ---*/ -#include "ast/simplifier/seq_simplifier_plugin.h" - -seq_simplifier_plugin::seq_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b) : -simplifier_plugin(symbol("seq"), m), -m_util(m), -m_rw(m) {} - -seq_simplifier_plugin::~seq_simplifier_plugin() {} - -bool seq_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - - SASSERT(f->get_family_id() == get_family_id()); - - return m_rw.mk_app_core(f, num_args, args, result) != BR_FAILED; -} - -bool seq_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { - set_reduce_invoked(); - - return m_rw.mk_eq_core(lhs, rhs, result) != BR_FAILED; -} - diff --git a/src/ast/simplifier/seq_simplifier_plugin.h b/src/ast/simplifier/seq_simplifier_plugin.h deleted file mode 100644 index a37a2209f..000000000 --- a/src/ast/simplifier/seq_simplifier_plugin.h +++ /dev/null @@ -1,39 +0,0 @@ -/*++ -Copyright (c) 2016 Microsoft Corporation - -Module Name: - - seq_simplifier_plugin.h - -Abstract: - - Simplifier for the sequence theory - -Author: - - Nikolaj Bjorner (nbjorner) 2016-02-05 - ---*/ -#ifndef SEQ_SIMPLIFIER_PLUGIN_H_ -#define SEQ_SIMPLIFIER_PLUGIN_H_ - -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/seq_decl_plugin.h" -#include "ast/rewriter/seq_rewriter.h" - -class seq_simplifier_plugin : public simplifier_plugin { - seq_util m_util; - seq_rewriter m_rw; - -public: - seq_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b); - ~seq_simplifier_plugin(); - - - 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); - -}; - -#endif /* SEQ_SIMPLIFIER_PLUGIN_H_ */ diff --git a/src/ast/simplifier/simplifier.cpp b/src/ast/simplifier/simplifier.cpp deleted file mode 100644 index c02753440..000000000 --- a/src/ast/simplifier/simplifier.cpp +++ /dev/null @@ -1,962 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - simplifier.cpp - -Abstract: - - Expression simplifier. - -Author: - - Leonardo (leonardo) 2008-01-03 - -Notes: - ---*/ -#include "ast/simplifier/simplifier.h" -#include "ast/rewriter/var_subst.h" -#include "ast/ast_ll_pp.h" -#include "ast/ast_pp.h" -#include "ast/well_sorted.h" -#include "ast/ast_smt_pp.h" - -simplifier::simplifier(ast_manager & m): - base_simplifier(m), - m_proofs(m), - m_subst_proofs(m), - m_need_reset(false), - m_use_oeq(false), - m_visited_quantifier(false), - m_ac_support(true) { -} - -void simplifier::register_plugin(plugin * p) { - m_plugins.register_plugin(p); -} - -simplifier::~simplifier() { - flush_cache(); -} - -void simplifier::enable_ac_support(bool flag) { - m_ac_support = flag; - ptr_vector::const_iterator it = m_plugins.begin(); - ptr_vector::const_iterator end = m_plugins.end(); - for (; it != end; ++it) { - if (*it != 0) - (*it)->enable_ac_support(flag); - } -} - -/** - \brief External interface for the simplifier. - A client will invoke operator()(s, r, p) to simplify s. - The result is stored in r. - When proof generation is enabled, a proof for the equivalence (or equisatisfiability) - of s and r is stored in p. - When proof generation is disabled, this method stores the "undefined proof" object in p. -*/ -void simplifier::operator()(expr * s, expr_ref & r, proof_ref & p) { - m_need_reset = true; - reinitialize(); - expr * s_orig = s; - (void)s_orig; - expr * old_s; - expr * result; - proof * result_proof; - switch (m.proof_mode()) { - case PGM_DISABLED: // proof generation is disabled. - reduce_core(s); - // after executing reduce_core, the result of the simplification is in the cache - get_cached(s, result, result_proof); - r = result; - p = m.mk_undef_proof(); - break; - case PGM_COARSE: // coarse proofs... in this case, we do not produce a step by step (fine grain) proof to show the equivalence (or equisatisfiability) of s an r. - m_subst_proofs.reset(); // m_subst_proofs is an auxiliary vector that is used to justify substitutions. See comment on method get_subst. - reduce_core(s); - get_cached(s, result, result_proof); - r = result; - if (result == s) - p = m.mk_reflexivity(s); - else { - remove_duplicates(m_subst_proofs); - p = m.mk_rewrite_star(s, result, m_subst_proofs.size(), m_subst_proofs.c_ptr()); - } - break; - case PGM_FINE: // fine grain proofs... in this mode, every proof step (or most of them) is described. - m_proofs.reset(); - old_s = 0; - // keep simplyfing until no further simplifications are possible. - while (s != old_s) { - TRACE("simplifier", tout << "simplification pass... " << s->get_id() << "\n";); - TRACE("simplifier_loop", tout << mk_ll_pp(s, m) << "\n";); - reduce_core(s); - get_cached(s, result, result_proof); - SASSERT(is_rewrite_proof(s, result, result_proof)); - if (result_proof != 0) { - m_proofs.push_back(result_proof); - } - old_s = s; - s = result; - } - SASSERT(s != 0); - r = s; - p = m_proofs.empty() ? m.mk_reflexivity(s) : m.mk_transitivity(m_proofs.size(), m_proofs.c_ptr()); - SASSERT(is_rewrite_proof(s_orig, r, p)); - break; - default: - UNREACHABLE(); - } -} - -void simplifier::flush_cache() { - m_cache.flush(); - ptr_vector::const_iterator it = m_plugins.begin(); - ptr_vector::const_iterator end = m_plugins.end(); - for (; it != end; ++it) { - if (*it != 0) { - (*it)->flush_caches(); - } - } -} - -bool simplifier::get_subst(expr * n, expr_ref & r, proof_ref & p) { - return false; -} - -void simplifier::reduce_core(expr * n1) { - if (!is_cached(n1)) { - // We do not assume m_todo is empty... So, we store the current size of the todo-stack. - unsigned sz = m_todo.size(); - m_todo.push_back(n1); - while (m_todo.size() != sz) { - expr * n = m_todo.back(); - if (is_cached(n)) - m_todo.pop_back(); - else if (visit_children(n)) { - // if all children were already simplified, then remove n from the todo stack and apply a - // simplification step to it. - m_todo.pop_back(); - reduce1(n); - } - if (m.canceled()) { - cache_result(n1, n1, 0); - break; - } - } - } -} - -/** - \brief Return true if all children of n have been already simplified. -*/ -bool simplifier::visit_children(expr * n) { - switch(n->get_kind()) { - case AST_VAR: - return true; - case AST_APP: - // The simplifier has support for flattening AC (associative-commutative) operators. - // The method ast_manager::mk_app is used to create the flat version of an AC operator. - // In Z3 1.x, we used multi-ary operators. This creates problems for the superposition engine. - // So, starting at Z3 2.x, only boolean operators can be multi-ary. - // Example: - // (and (and a b) (and c d)) --> (and a b c d) - // (+ (+ a b) (+ c d)) --> (+ a (+ b (+ c d))) - // Remark: The flattening is only applied if m_ac_support is true. - if (m_ac_support && to_app(n)->get_decl()->is_associative() && to_app(n)->get_decl()->is_commutative()) - return visit_ac(to_app(n)); - else { - bool visited = true; - unsigned j = to_app(n)->get_num_args(); - while (j > 0) { - --j; - visit(to_app(n)->get_arg(j), visited); - } - return visited; - } - case AST_QUANTIFIER: - return visit_quantifier(to_quantifier(n)); - default: - UNREACHABLE(); - return true; - } -} - -/** - \brief Visit the children of n assuming it is an AC (associative-commutative) operator. - - For example, if n is of the form (+ (+ a b) (+ c d)), this method - will return true if the nodes a, b, c and d have been already simplified. - The nodes (+ a b) and (+ c d) are not really checked. -*/ -bool simplifier::visit_ac(app * n) { - bool visited = true; - func_decl * decl = n->get_decl(); - SASSERT(m_ac_support); - SASSERT(decl->is_associative()); - SASSERT(decl->is_commutative()); - m_ac_marked.reset(); - ptr_buffer todo; - todo.push_back(n); - while (!todo.empty()) { - app * n = todo.back(); - todo.pop_back(); - if (m_ac_mark.is_marked(n)) - continue; - m_ac_mark.mark(n, true); - m_ac_marked.push_back(n); - SASSERT(n->get_decl() == decl); - unsigned i = n->get_num_args(); - while (i > 0) { - --i; - expr * arg = n->get_arg(i); - if (is_app_of(arg, decl)) - todo.push_back(to_app(arg)); - else - visit(arg, visited); - } - } - ptr_vector::const_iterator it = m_ac_marked.begin(); - ptr_vector::const_iterator end = m_ac_marked.end(); - for (; it != end; ++it) - m_ac_mark.mark(*it, false); - return visited; -} - -bool simplifier::visit_quantifier(quantifier * n) { - m_visited_quantifier = true; - bool visited = true; - unsigned j = to_quantifier(n)->get_num_patterns(); - while (j > 0) { - --j; - visit(to_quantifier(n)->get_pattern(j), visited); - } - j = to_quantifier(n)->get_num_no_patterns(); - while (j > 0) { - --j; - visit(to_quantifier(n)->get_no_pattern(j), visited); - } - visit(to_quantifier(n)->get_expr(), visited); - return visited; -} - -/** - \brief Simplify n and store the result in the cache. -*/ -void simplifier::reduce1(expr * n) { - switch (n->get_kind()) { - case AST_VAR: - cache_result(n, n, 0); - break; - case AST_APP: - reduce1_app(to_app(n)); - break; - case AST_QUANTIFIER: - reduce1_quantifier(to_quantifier(n)); - break; - default: - UNREACHABLE(); - } -} - -/** - \brief Simplify the given application using the cached values, - associativity flattening, the given substitution, and family/theory - specific simplifications via plugins. -*/ -void simplifier::reduce1_app(app * n) { - expr_ref r(m); - proof_ref p(m); - TRACE("reduce", tout << "reducing...\n" << mk_pp(n, m) << "\n";); - if (get_subst(n, r, p)) { - TRACE("reduce", tout << "applying substitution...\n";); - cache_result(n, r, p); - return; - } - - func_decl * decl = n->get_decl(); - if (m_ac_support && decl->is_associative() && decl->is_commutative()) - reduce1_ac_app_core(n); - else - reduce1_app_core(n); -} - - -void simplifier::reduce1_app_core(app * n) { - m_args.reset(); - func_decl * decl = n->get_decl(); - proof_ref p1(m); - // Stores the new arguments of n in m_args. - // Let n be of the form - // (decl arg_0 ... arg_{n-1}) - // then - // m_args contains [arg_0', ..., arg_{n-1}'], - // where arg_i' is the simplification of arg_i - // and - // p1 is a proof for - // (decl arg_0 ... arg_{n-1}) is equivalente/equisatisfiable to (decl arg_0' ... arg_{n-1}') - // p1 is built using the congruence proof step and the proofs for arg_0' ... arg_{n-1}'. - // Of course, p1 is 0 if proofs are not enabled or coarse grain proofs are used. - bool has_new_args = get_args(n, m_args, p1); - // The following if implements a simple trick. - // If none of the arguments have been simplified, and n is not a theory symbol, - // Then no simplification is possible, and we can cache the result of the simplification of n as n. - if (has_new_args || decl->get_family_id() != null_family_id) { - expr_ref r(m); - TRACE("reduce", tout << "reduce1_app\n"; for(unsigned i = 0; i < m_args.size(); i++) tout << mk_ll_pp(m_args[i], m);); - // the method mk_app invokes get_subst and plugins to simplify - // (decl arg_0' ... arg_{n-1}') - mk_app(decl, m_args.size(), m_args.c_ptr(), r); - if (!m.fine_grain_proofs()) { - cache_result(n, r, 0); - } - else { - expr * s = m.mk_app(decl, m_args.size(), m_args.c_ptr()); - proof * p; - if (n == r) - p = 0; - else if (r != s) - // we use a "theory rewrite generic proof" to justify the step - // s = (decl arg_0' ... arg_{n-1}') --> r - p = m.mk_transitivity(p1, m.mk_rewrite(s, r)); - else - p = p1; - cache_result(n, r, p); - } - } - else { - cache_result(n, n, 0); - } -} - -bool is_ac_list(app * n, ptr_vector & args) { - args.reset(); - func_decl * f = n->get_decl(); - app * curr = n; - while (true) { - if (curr->get_num_args() != 2) - return false; - expr * arg1 = curr->get_arg(0); - if (is_app_of(arg1, f)) - return false; - args.push_back(arg1); - expr * arg2 = curr->get_arg(1); - if (!is_app_of(arg2, f)) { - args.push_back(arg2); - return true; - } - curr = to_app(arg2); - } -} - -bool is_ac_vector(app * n) { - func_decl * f = n->get_decl(); - unsigned num_args = n->get_num_args(); - for (unsigned i = 0; i < num_args; i++) { - if (is_app_of(n->get_arg(i), f)) - return false; - } - return true; -} - -void simplifier::reduce1_ac_app_core(app * n) { - app_ref n_c(m); - proof_ref p1(m); - mk_ac_congruent_term(n, n_c, p1); - TRACE("ac", tout << "expr:\n" << mk_pp(n, m) << "\ncongruent term:\n" << mk_pp(n_c, m) << "\n";); - expr_ref r(m); - func_decl * decl = n->get_decl(); - family_id fid = decl->get_family_id(); - plugin * p = get_plugin(fid); - if (is_ac_vector(n_c)) { - if (p != 0 && p->reduce(decl, n_c->get_num_args(), n_c->get_args(), r)) { - // done... - } - else { - r = n_c; - } - } - else if (is_ac_list(n_c, m_args)) { - // m_args contains the arguments... - if (p != 0 && p->reduce(decl, m_args.size(), m_args.c_ptr(), r)) { - // done... - } - else { - r = m.mk_app(decl, m_args.size(), m_args.c_ptr()); - } - } - else { - m_args.reset(); - m_mults.reset(); - get_ac_args(n_c, m_args, m_mults); - TRACE("ac", tout << "AC args:\n"; - for (unsigned i = 0; i < m_args.size(); i++) { - tout << mk_pp(m_args[i], m) << " * " << m_mults[i] << "\n"; - }); - if (p != 0 && p->reduce(decl, m_args.size(), m_mults.c_ptr(), m_args.c_ptr(), r)) { - // done... - } - else { - ptr_buffer new_args; - expand_args(m_args.size(), m_mults.c_ptr(), m_args.c_ptr(), new_args); - r = m.mk_app(decl, new_args.size(), new_args.c_ptr()); - } - } - TRACE("ac", tout << "AC result:\n" << mk_pp(r, m) << "\n";); - - if (!m.fine_grain_proofs()) { - cache_result(n, r, 0); - } - else { - proof * p; - if (n == r.get()) - p = 0; - else if (r.get() != n_c.get()) - p = m.mk_transitivity(p1, m.mk_rewrite(n_c, r)); - else - p = p1; - cache_result(n, r, p); - } -} - -static unsigned g_rewrite_lemma_id = 0; - -void simplifier::dump_rewrite_lemma(func_decl * decl, unsigned num_args, expr * const * args, expr* result) { - expr_ref arg(m); - arg = m.mk_app(decl, num_args, args); - if (arg.get() != result) { - char buffer[128]; -#ifdef _WINDOWS - sprintf_s(buffer, ARRAYSIZE(buffer), "lemma_%d.smt", g_rewrite_lemma_id); -#else - sprintf(buffer, "rewrite_lemma_%d.smt", g_rewrite_lemma_id); -#endif - ast_smt_pp pp(m); - pp.set_benchmark_name("rewrite_lemma"); - pp.set_status("unsat"); - expr_ref n(m); - n = m.mk_not(m.mk_eq(arg.get(), result)); - std::ofstream out(buffer); - pp.display(out, n); - out.close(); - ++g_rewrite_lemma_id; - } -} - -/** - \brief Return in \c result an expression \c e equivalent to (f args[0] ... args[num_args - 1]), and - store in \c pr a proof for (= (f args[0] ... args[num_args - 1]) e) - - If e is identical to (f args[0] ... args[num_args - 1]), then pr is set to 0. -*/ -void simplifier::mk_app(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & result) { - m_need_reset = true; - if (m.is_eq(decl)) { - sort * s = m.get_sort(args[0]); - plugin * p = get_plugin(s->get_family_id()); - if (p != 0 && p->reduce_eq(args[0], args[1], result)) - return; - } - else if (m.is_distinct(decl)) { - sort * s = m.get_sort(args[0]); - plugin * p = get_plugin(s->get_family_id()); - if (p != 0 && p->reduce_distinct(num_args, args, result)) - return; - } - family_id fid = decl->get_family_id(); - plugin * p = get_plugin(fid); - if (p != 0 && p->reduce(decl, num_args, args, result)) { - //uncomment this line if you want to trace rewrites as lemmas: - //dump_rewrite_lemma(decl, num_args, args, result.get()); - return; - } - - result = m.mk_app(decl, num_args, args); -} - -/** - \brief Create a term congruence to n (f a[0] ... a[num_args-1]) using the - cached values for the a[i]'s. Store the result in r, and the proof for (= n r) in p. - If n and r are identical, then set p to 0. -*/ -void simplifier::mk_congruent_term(app * n, app_ref & r, proof_ref & p) { - bool has_new_args = false; - ptr_vector args; - ptr_vector proofs; - unsigned num = n->get_num_args(); - for (unsigned j = 0; j < num; j++) { - expr * arg = n->get_arg(j); - expr * new_arg; - proof * arg_proof; - get_cached(arg, new_arg, arg_proof); - - CTRACE("simplifier_bug", (arg != new_arg) != (arg_proof != 0), - tout << mk_ll_pp(arg, m) << "\n---->\n" << mk_ll_pp(new_arg, m) << "\n"; - tout << "#" << arg->get_id() << " #" << new_arg->get_id() << "\n"; - tout << arg << " " << new_arg << "\n";); - - - if (arg != new_arg) { - has_new_args = true; - proofs.push_back(arg_proof); - SASSERT(arg_proof); - } - else { - SASSERT(arg_proof == 0); - } - args.push_back(new_arg); - } - if (has_new_args) { - r = m.mk_app(n->get_decl(), args.size(), args.c_ptr()); - if (m_use_oeq) - p = m.mk_oeq_congruence(n, r, proofs.size(), proofs.c_ptr()); - else - p = m.mk_congruence(n, r, proofs.size(), proofs.c_ptr()); - } - else { - r = n; - p = 0; - } -} - -/** - \brief Store the new arguments of \c n in result. Store in p a proof for - (= n (f result[0] ... result[num_args - 1])), where f is the function symbol of n. - - If there are no new arguments or fine grain proofs are disabled, then p is set to 0. - - Return true there are new arguments. -*/ -bool simplifier::get_args(app * n, ptr_vector & result, proof_ref & p) { - bool has_new_args = false; - unsigned num = n->get_num_args(); - if (m.fine_grain_proofs()) { - app_ref r(m); - mk_congruent_term(n, r, p); - result.append(r->get_num_args(), r->get_args()); - SASSERT(n->get_num_args() == result.size()); - has_new_args = r != n; - } - else { - p = 0; - for (unsigned j = 0; j < num; j++) { - expr * arg = n->get_arg(j); - expr * new_arg; - proof * arg_proof; - get_cached(arg, new_arg, arg_proof); - if (arg != new_arg) { - has_new_args = true; - } - result.push_back(new_arg); - } - } - return has_new_args; -} - -/** - \brief Create a term congruence to n (where n is an expression such as: (f (f a_1 a_2) (f a_3 (f a_4 a_5))) using the - cached values for the a_i's. Store the result in r, and the proof for (= n r) in p. - If n and r are identical, then set p to 0. -*/ -void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) { - SASSERT(m_ac_support); - func_decl * f = n->get_decl(); - - m_ac_cache.reset(); - m_ac_pr_cache.reset(); - - ptr_buffer todo; - ptr_buffer new_args; - ptr_buffer new_arg_prs; - todo.push_back(n); - while (!todo.empty()) { - app * curr = todo.back(); - if (m_ac_cache.contains(curr)) { - todo.pop_back(); - continue; - } - bool visited = true; - bool has_new_arg = false; - new_args.reset(); - new_arg_prs.reset(); - unsigned num_args = curr->get_num_args(); - for (unsigned j = 0; j < num_args; j ++) { - expr * arg = curr->get_arg(j); - if (is_app_of(arg, f)) { - app * new_arg = 0; - if (m_ac_cache.find(to_app(arg), new_arg)) { - SASSERT(new_arg != 0); - new_args.push_back(new_arg); - if (arg != new_arg) - has_new_arg = true; - if (m.fine_grain_proofs()) { - proof * pr = 0; - m_ac_pr_cache.find(to_app(arg), pr); - if (pr != 0) - new_arg_prs.push_back(pr); - } - } - else { - visited = false; - todo.push_back(to_app(arg)); - } - } - else { - expr * new_arg = 0; - proof * pr; - get_cached(arg, new_arg, pr); - new_args.push_back(new_arg); - if (arg != new_arg) - has_new_arg = true; - if (m.fine_grain_proofs() && pr != 0) - new_arg_prs.push_back(pr); - } - } - if (visited) { - SASSERT(new_args.size() == curr->get_num_args()); - todo.pop_back(); - if (!has_new_arg) { - m_ac_cache.insert(curr, curr); - if (m.fine_grain_proofs()) - m_ac_pr_cache.insert(curr, 0); - } - else { - app * new_curr = m.mk_app(f, new_args.size(), new_args.c_ptr()); - m_ac_cache.insert(curr, new_curr); - if (m.fine_grain_proofs()) { - proof * p = m.mk_congruence(curr, new_curr, new_arg_prs.size(), new_arg_prs.c_ptr()); - m_ac_pr_cache.insert(curr, p); - } - } - } - } - - SASSERT(m_ac_cache.contains(n)); - app * new_n = 0; - m_ac_cache.find(n, new_n); - r = new_n; - if (m.fine_grain_proofs()) { - proof * new_pr = 0; - m_ac_pr_cache.find(n, new_pr); - p = new_pr; - } -} - -#define White 0 -#define Grey 1 -#define Black 2 - -#ifdef Z3DEBUG -static int get_color(obj_map & colors, expr * n) { - obj_map::obj_map_entry * entry = colors.insert_if_not_there2(n, White); - return entry->get_data().m_value; -} -#endif - -static bool visit_ac_children(func_decl * f, expr * n, obj_map & colors, ptr_buffer & todo, ptr_buffer & result) { - if (is_app_of(n, f)) { - unsigned num_args = to_app(n)->get_num_args(); - bool visited = true; - // Put the arguments in 'result' in reverse order. - // Reason: preserve the original order of the arguments in the final result. - // Remark: get_ac_args will traverse 'result' backwards. - for (unsigned i = 0; i < num_args; i++) { - expr * arg = to_app(n)->get_arg(i); - obj_map::obj_map_entry * entry = colors.insert_if_not_there2(arg, White); - if (entry->get_data().m_value == White) { - todo.push_back(arg); - visited = false; - } - } - return visited; - } - else { - return true; - } -} - -void simplifier::ac_top_sort(app * n, ptr_buffer & result) { - ptr_buffer todo; - func_decl * f = n->get_decl(); - obj_map & colors = m_colors; - colors.reset(); - todo.push_back(n); - while (!todo.empty()) { - expr * curr = todo.back(); - int color; - obj_map::obj_map_entry * entry = colors.insert_if_not_there2(curr, White); - SASSERT(entry); - color = entry->get_data().m_value; - switch (color) { - case White: - // Remark: entry becomes invalid if an element is inserted into the hashtable. - // So, I must set Grey before executing visit_ac_children. - entry->get_data().m_value = Grey; - SASSERT(get_color(colors, curr) == Grey); - if (visit_ac_children(f, curr, colors, todo, result)) { - // If visit_ac_children succeeded, then the hashtable was not modified, - // and entry is still valid. - SASSERT(todo.back() == curr); - entry->get_data().m_value = Black; - SASSERT(get_color(colors, curr) == Black); - result.push_back(curr); - todo.pop_back(); - } - break; - case Grey: - SASSERT(visit_ac_children(f, curr, colors, todo, result)); - SASSERT(entry); - entry->get_data().m_value = Black; - SASSERT(get_color(colors, curr) == Black); - result.push_back(curr); - SASSERT(todo.back() == curr); - todo.pop_back(); - break; - case Black: - todo.pop_back(); - break; - default: - UNREACHABLE(); - } - } -} - -void simplifier::get_ac_args(app * n, ptr_vector & args, vector & mults) { - SASSERT(m_ac_support); - ptr_buffer sorted_exprs; - ac_top_sort(n, sorted_exprs); - SASSERT(!sorted_exprs.empty()); - SASSERT(sorted_exprs[sorted_exprs.size()-1] == n); - - TRACE("ac", tout << mk_ll_pp(n, m, true, false) << "#" << n->get_id() << "\nsorted expressions...\n"; - for (unsigned i = 0; i < sorted_exprs.size(); i++) { - tout << "#" << sorted_exprs[i]->get_id() << " "; - } - tout << "\n";); - - m_ac_mults.reset(); - m_ac_mults.insert(n, rational(1)); - func_decl * decl = n->get_decl(); - unsigned j = sorted_exprs.size(); - while (j > 0) { - --j; - expr * curr = sorted_exprs[j]; - rational mult; - m_ac_mults.find(curr, mult); - SASSERT(!mult.is_zero()); - if (is_app_of(curr, decl)) { - unsigned num_args = to_app(curr)->get_num_args(); - for (unsigned i = 0; i < num_args; i++) { - expr * arg = to_app(curr)->get_arg(i); - rational zero; - obj_map::obj_map_entry * entry = m_ac_mults.insert_if_not_there2(arg, zero); - entry->get_data().m_value += mult; - } - } - else { - args.push_back(curr); - mults.push_back(mult); - } - } -} - -void simplifier::reduce1_quantifier(quantifier * q) { - expr * new_body; - proof * new_body_pr; - SASSERT(is_well_sorted(m, q)); - get_cached(q->get_expr(), new_body, new_body_pr); - - quantifier_ref q1(m); - proof * p1 = 0; - - if (is_quantifier(new_body) && - to_quantifier(new_body)->is_forall() == q->is_forall() && - !to_quantifier(q)->has_patterns() && - !to_quantifier(new_body)->has_patterns()) { - - quantifier * nested_q = to_quantifier(new_body); - - ptr_buffer sorts; - buffer names; - sorts.append(q->get_num_decls(), q->get_decl_sorts()); - names.append(q->get_num_decls(), q->get_decl_names()); - sorts.append(nested_q->get_num_decls(), nested_q->get_decl_sorts()); - names.append(nested_q->get_num_decls(), nested_q->get_decl_names()); - - q1 = m.mk_quantifier(q->is_forall(), - sorts.size(), - sorts.c_ptr(), - names.c_ptr(), - nested_q->get_expr(), - std::min(q->get_weight(), nested_q->get_weight()), - q->get_qid(), - q->get_skid(), - 0, 0, 0, 0); - SASSERT(is_well_sorted(m, q1)); - - if (m.fine_grain_proofs()) { - quantifier * q0 = m.update_quantifier(q, new_body); - proof * p0 = q == q0 ? 0 : m.mk_quant_intro(q, q0, new_body_pr); - p1 = m.mk_pull_quant(q0, q1); - p1 = m.mk_transitivity(p0, p1); - } - } - else { - ptr_buffer new_patterns; - ptr_buffer new_no_patterns; - expr * new_pattern; - proof * new_pattern_pr; - - // Remark: we can ignore the proofs for the patterns. - unsigned num = q->get_num_patterns(); - for (unsigned i = 0; i < num; i++) { - get_cached(q->get_pattern(i), new_pattern, new_pattern_pr); - if (m.is_pattern(new_pattern)) { - new_patterns.push_back(new_pattern); - } - } - num = q->get_num_no_patterns(); - for (unsigned i = 0; i < num; i++) { - get_cached(q->get_no_pattern(i), new_pattern, new_pattern_pr); - new_no_patterns.push_back(new_pattern); - } - - remove_duplicates(new_patterns); - remove_duplicates(new_no_patterns); - - q1 = m.mk_quantifier(q->is_forall(), - q->get_num_decls(), - q->get_decl_sorts(), - q->get_decl_names(), - new_body, - q->get_weight(), - q->get_qid(), - q->get_skid(), - new_patterns.size(), - new_patterns.c_ptr(), - new_no_patterns.size(), - new_no_patterns.c_ptr()); - SASSERT(is_well_sorted(m, q1)); - - TRACE("simplifier", tout << mk_pp(q, m) << "\n" << mk_pp(q1, m) << "\n";); - if (m.fine_grain_proofs()) { - if (q != q1 && !new_body_pr) { - new_body_pr = m.mk_rewrite(q->get_expr(), new_body); - } - p1 = q == q1 ? 0 : m.mk_quant_intro(q, q1, new_body_pr); - } - } - - expr_ref r(m); - elim_unused_vars(m, q1, params_ref(), r); - - proof * pr = 0; - if (m.fine_grain_proofs()) { - proof * p2 = 0; - if (q1.get() != r.get()) - p2 = m.mk_elim_unused_vars(q1, r); - pr = m.mk_transitivity(p1, p2); - } - - cache_result(q, r, pr); -} - -/** - \see release_plugins -*/ -void simplifier::borrow_plugins(simplifier const & s) { - ptr_vector::const_iterator it = s.begin_plugins(); - ptr_vector::const_iterator end = s.end_plugins(); - for (; it != end; ++it) - register_plugin(*it); -} - -/** - \brief Make the simplifier behave as a pre-simplifier: No AC, and plugins are marked in pre-simplification mode. -*/ -void simplifier::enable_presimp() { - enable_ac_support(false); - ptr_vector::const_iterator it = begin_plugins(); - ptr_vector::const_iterator end = end_plugins(); - for (; it != end; ++it) - (*it)->enable_presimp(true); -} - -/** - \brief This method should be invoked if the plugins of this simplifier were borrowed from a different simplifier. -*/ -void simplifier::release_plugins() { - m_plugins.release(); -} - -void subst_simplifier::set_subst_map(expr_map * s) { - flush_cache(); - m_subst_map = s; -} - -bool subst_simplifier::get_subst(expr * n, expr_ref & r, proof_ref & p) { - if (m_subst_map && m_subst_map->contains(n)) { - expr * _r; - proof * _p = 0; - m_subst_map->get(n, _r, _p); - r = _r; - p = _p; - if (m.coarse_grain_proofs()) - m_subst_proofs.push_back(p); - return true; - } - return false; -} - -static void push_core(ast_manager & m, expr * e, proof * pr, expr_ref_vector & result, proof_ref_vector & result_prs) { - SASSERT(pr == 0 || m.is_undef_proof(pr) || e == m.get_fact(pr)); - TRACE("preprocessor", - tout << mk_pp(e, m) << "\n"; - if (pr) tout << mk_ll_pp(pr, m) << "\n\n";); - if (m.is_true(e)) - return; - result.push_back(e); - if (m.proofs_enabled()) - result_prs.push_back(pr); -} - -static void push_and(ast_manager & m, app * e, proof * pr, expr_ref_vector & result, proof_ref_vector & result_prs) { - unsigned num = e->get_num_args(); - TRACE("push_and", tout << mk_pp(e, m) << "\n";); - for (unsigned i = 0; i < num; i++) - push_assertion(m, e->get_arg(i), m.mk_and_elim(pr, i), result, result_prs); -} - -static void push_not_or(ast_manager & m, app * e, proof * pr, expr_ref_vector & result, proof_ref_vector & result_prs) { - unsigned num = e->get_num_args(); - TRACE("push_not_or", tout << mk_pp(e, m) << "\n";); - for (unsigned i = 0; i < num; i++) { - expr * child = e->get_arg(i); - if (m.is_not(child)) { - expr * not_child = to_app(child)->get_arg(0); - push_assertion(m, not_child, m.mk_not_or_elim(pr, i), result, result_prs); - } - else { - expr_ref not_child(m); - not_child = m.mk_not(child); - push_assertion(m, not_child, m.mk_not_or_elim(pr, i), result, result_prs); - } - } -} - -void push_assertion(ast_manager & m, expr * e, proof * pr, expr_ref_vector & result, proof_ref_vector & result_prs) { - CTRACE("push_assertion", !(pr == 0 || m.is_undef_proof(pr) || m.get_fact(pr) == e), - tout << mk_pp(e, m) << "\n" << mk_pp(m.get_fact(pr), m) << "\n";); - SASSERT(pr == 0 || m.is_undef_proof(pr) || m.get_fact(pr) == e); - if (m.is_and(e)) - push_and(m, to_app(e), pr, result, result_prs); - else if (m.is_not(e) && m.is_or(to_app(e)->get_arg(0))) - push_not_or(m, to_app(to_app(e)->get_arg(0)), pr, result, result_prs); - else - push_core(m, e, pr, result, result_prs); -} - diff --git a/src/ast/simplifier/simplifier.h b/src/ast/simplifier/simplifier.h deleted file mode 100644 index 5148721f1..000000000 --- a/src/ast/simplifier/simplifier.h +++ /dev/null @@ -1,232 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - simplifier.h - -Abstract: - - Generic expression simplifier with support for theory specific "plugins". - -Author: - - Leonardo (leonardo) 2008-01-03 - -Notes: - ---*/ -#ifndef SIMPLIFIER_H_ -#define SIMPLIFIER_H_ - -#include "ast/simplifier/base_simplifier.h" -#include "ast/simplifier/simplifier_plugin.h" -#include "util/plugin_manager.h" -#include "ast/ast_util.h" -#include "util/obj_hashtable.h" - -/** - \brief Local simplifier. - Proof production can be enabled/disabled. - - The simplifier can also apply substitutions during the - simplification. A substitution is a mapping from expression - to expression+proof, where for each entry e_1->(e_2,p) p is - a proof for (= e_1 e_2). - - The simplifier can also generate coarse grain proofs. In a coarse - proof, local rewrite steps are omitted, and only the substitutions - used are tracked. - - Example: - - Consider the expression (+ a b), and the substitution b->(0, p) - When fine grain proofs are enabled, the simplifier will produce the - following proof - - Assume the id of the proof object p is $0. Note that p is a proof for (= b 0). - - $1: [reflexivity] |- (= a a) - $2: [congruence] $1 $0 |- (= (+ a b) (+ a 0)) - $3: [plus-0] |- (= (+ a 0) a) - $4: [transitivity] $2 $3 |- (= (+ a b) a) - - When coarse grain proofs are enabled, the simplifier produces the following - proof: - - $1: [simplifier] $0 |- (= (+ a b) a) -*/ -class simplifier : public base_simplifier { -protected: - typedef simplifier_plugin plugin; - plugin_manager m_plugins; - ptr_vector m_args; - vector m_mults; - ptr_vector m_args2; - - proof_ref_vector m_proofs; // auxiliary vector for implementing exhaustive simplification. - proof_ref_vector m_subst_proofs; // in coarse grain proof generation mode, this vector tracks the justification for substitutions (see method get_subst). - - bool m_need_reset; - bool m_use_oeq; - - bool m_visited_quantifier; //!< true, if the simplifier found a quantifier - - bool m_ac_support; - - expr_mark m_ac_mark; - ptr_vector m_ac_marked; - obj_map m_ac_cache; // temporary cache for ac - obj_map m_ac_pr_cache; // temporary cache for ac - obj_map m_colors; // temporary cache for topological sort. - obj_map m_ac_mults; - - /* - Simplifier uses an idiom for rewriting ASTs without using recursive calls. - - - It uses a cache (field m_cache in base_simplifier) and a todo-stack (field m_todo in base_simplifier). - - - The cache is a mapping from AST to (AST + Proof). An entry [n -> (n',pr)] is used to store the fact - that n and n' are equivalent and pr is a proof for that. If proofs are disabled, then pr is 0. - We say n' is the result of the simplification of n. - Note: Some simplifications do not preserve equivalence, but equisatisfiability. - For saving space, we use pr = 0 also to represent the reflexivity proof [n -> (n, 0)]. - - - - The simplifier can be extended using plugin (subclasses of the class simplifier_plugin). - Each theory has a family ID. All operators (func_decls) and sorts from a given theory have - the same family_id. Given an application (object of the class app), we use the method - get_family_id() to obtain the family id of the operator in this application. - The simplifier uses plugin to apply theory specific simplifications. The basic idea is: - whenever an AST with family_id X is found, invoke the plugin for this family_id. - A simplifier_plugin implements the following API: - 1) bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) - This method is invoked when the simplifier is trying to reduce/simplify an application - of the form (f args[0] ... args[num_args - 1]), and f has a family_id associated with - the plugin. The plugin may return false to indicate it could not simplify this application. - If it returns true (success), the result should be stored in the argument result. - - 2) bool reduce(func_decl * f, unsigned num_args, rational const * mults, expr * const * args, expr_ref & result); - This method is a similar to the previous one, and it is used to handle associative operators. - A plugin does not need to implement this method, the default implementation will use the previous one. - The arguments mults indicates the multiplicity of every argument in args. - For example, suppose this reduce is invoked with the arguments (f, 2, [3, 2], [a, b], result). - This represents the application (f a a a b b). - Some theory simplifiers may have efficient ways to encode this multiplicity. For example, - the arithmetic solver, if f is "+", the multiplicity can be encoded using "*". - This optimization is used because some benchmarks can create term that are very huge when - flattened. One "real" example (that motivated this optimization) is: - let a1 = x1 + x1 - let a2 = a1 + a1 - ... - let an = a{n-1} + a{n-1} - an - In this example, n was 32, so after AC flattening, we had an application - (+ x1 ... x1) with 2^32 arguments. Using the simple reduce would produce a stack overflow. - - This class uses a topological sort for computing the multiplicities efficiently. - So, the field m_colors is used to implement the topological sort. - - - 3) bool reduce_eq(expr * lhs, expr * rhs, expr_ref & result) - This method is invoked when the sort of lhs and rhs has a family_id associated with the plugin. - This method allows theory specific simplifications such as: - (= (+ a b) b) --> (= a 0) - Assuming n1 is a reference to (+ a b) and n2 to b, the simplifier would invoke - reduce_eq(n1, n2, result) - Like reduce, false can be returned if a simplification could not be applied. - And if true is returned, then the result is stored in the argument result. - - 4) bool reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result) - It is similar to reduce_eq, but it used for theory specific simplifications for - (distinct args[0] ... args[num_args-1]) - Example: - (distinct 0 1 ... n) --> true - - - The idiom used in this class is implemented in the methdo reduce_core. - See reduce_core for more details. The basic idea is: - - 1) Get the next ast to be simplified from the todo-stack. - 2) If it is already cached, then do nothing. That is, this expression was already simplified. - 3) Otherwise, check whether all arguments already have been simplified (method visit_children). - 3a) The arguments that have not been simplified are added to the todo-stack by visit_children. - In this case visit_children will return false. - 3b) If all arguments have already been simplified, then invoke reduce1 to perform a reduction/simplification - step. The cache is updated with the result. - - - After invoking reduce_core(n), the cache contains an entry [n -> (n', pr)]. - - */ - - void flush_cache(); - - /** - \brief This method can be redefined in subclasses of simplifier to implement substitutions. - It returns true if n should be substituted by r, where the substitution is justified by the - proof p. The field m_subst_proofs is used to store these justifications when coarse proofs are used (PGM_COARSE). - This method is redefined in the class subst_simplifier. It is used in asserted_formulas - for implementing constant elimination. For example, if asserted_formulas contains the atoms - (= a (+ b 1)) (p a c), then the constant "a" can be eliminated. This is achieved by set (+ b 1) as - a substitution for "a". - */ - virtual bool get_subst(expr * n, expr_ref & r, proof_ref & p); - - void reduce_core(expr * n); - bool visit_children(expr * n); - bool visit_ac(app * n); - virtual bool visit_quantifier(quantifier * q); - void reduce1(expr * n); - void reduce1_app(app * n); - void reduce1_app_core(app * n); - void reduce1_ac_app_core(app * n); - void mk_congruent_term(app * n, app_ref & r, proof_ref & p); - void mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p); - bool get_args(app * n, ptr_vector & result, proof_ref & p); - void get_ac_args(app * n, ptr_vector & args, vector & mults); - virtual void reduce1_quantifier(quantifier * q); - void dump_rewrite_lemma(func_decl * decl, unsigned num_args, expr * const * args, expr* result); - void ac_top_sort(app * n, ptr_buffer & result); - -public: - simplifier(ast_manager & manager); - virtual ~simplifier(); - - void enable_ac_support(bool flag); - - /** - \brief Simplify the expression \c s. Store the result in \c r, and a proof that (= s r) in \c p. - */ - void operator()(expr * s, expr_ref & r, proof_ref & p); - void reset() { if (m_need_reset) { flush_cache(); m_need_reset = false; } } - - bool visited_quantifier() const { return m_visited_quantifier; } - - void mk_app(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & r); - void cache_result(expr * n, expr * r, proof * p) { m_need_reset = true; base_simplifier::cache_result(n, r, p); } - - void register_plugin(plugin * p); - ptr_vector::const_iterator begin_plugins() const { return m_plugins.begin(); } - ptr_vector::const_iterator end_plugins() const { return m_plugins.end(); } - - plugin * get_plugin(family_id fid) const { return m_plugins.get_plugin(fid); } - - ast_manager & get_manager() { return m; } - - void borrow_plugins(simplifier const & s); - void release_plugins(); - - void enable_presimp(); -}; - -class subst_simplifier : public simplifier { -protected: - expr_map * m_subst_map; - virtual bool get_subst(expr * n, expr_ref & r, proof_ref & p); -public: - subst_simplifier(ast_manager & manager):simplifier(manager), m_subst_map(0) {} - void set_subst_map(expr_map * s); -}; - -void push_assertion(ast_manager & m, expr * e, proof * pr, expr_ref_vector & result, proof_ref_vector & result_prs); - -#endif diff --git a/src/ast/simplifier/simplifier_plugin.cpp b/src/ast/simplifier/simplifier_plugin.cpp deleted file mode 100644 index a62b15131..000000000 --- a/src/ast/simplifier/simplifier_plugin.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - simplifier_plugin.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-12-29. - -Revision History: - ---*/ -#include "ast/simplifier/simplifier_plugin.h" - -/** - \brief Copy every args[i] mult[i] times to new_args. -*/ -void expand_args(unsigned num_args, rational const * mults, expr * const * args, ptr_buffer & new_args) { - for (unsigned i = 0; i < num_args; i++) { - rational const & c = mults[i]; - SASSERT(c.is_int()); - rational j(0); - while (j < c) { - new_args.push_back(args[i]); - j++; - } - } -} - -bool simplifier_plugin::reduce(func_decl * f, unsigned num_args, rational const * mults, expr * const * args, expr_ref & result) { - set_reduce_invoked(); - if (f->is_idempotent()) { - return reduce(f, num_args, args, result); - } - else { - ptr_buffer new_args; - expand_args(num_args, mults, args, new_args); - return reduce(f, new_args.size(), new_args.c_ptr(), result); - } -} diff --git a/src/ast/simplifier/simplifier_plugin.h b/src/ast/simplifier/simplifier_plugin.h deleted file mode 100644 index 26b5bcd59..000000000 --- a/src/ast/simplifier/simplifier_plugin.h +++ /dev/null @@ -1,94 +0,0 @@ -/*++ -Copyright (c) 2007 Microsoft Corporation - -Module Name: - - simplifier_plugin.h - -Abstract: - - Expression simplifier plugin interface. - -Author: - - Leonardo (leonardo) 2008-01-03 - ---*/ - -#ifndef SIMPLIFIER_PLUGIN_H_ -#define SIMPLIFIER_PLUGIN_H_ - -#include "ast/ast.h" - -class simplifier; - -void expand_args(unsigned num_args, rational const * mults, expr * const * args, ptr_buffer & new_args); - -/** - \brief Abstract simplifier for the operators in a given family. -*/ -class simplifier_plugin { -protected: - ast_manager & m_manager; - family_id m_fid; - bool m_presimp; // true if simplifier is performing pre-simplification... - bool m_reduce_invoked; // true if one of the reduce methods were invoked. - - void set_reduce_invoked() { m_reduce_invoked = true; } - -public: - simplifier_plugin(symbol const & fname, ast_manager & m):m_manager(m), m_fid(m.mk_family_id(fname)), m_presimp(false), m_reduce_invoked(false) {} - - bool reduce_invoked() const { return m_reduce_invoked; } - - virtual ~simplifier_plugin() {} - - virtual simplifier_plugin * mk_fresh() { - UNREACHABLE(); - return 0; - } - - /** - \brief Return in \c result an expression \c e equivalent to (f args[0] ... args[num_args - 1]). - - Return true if succeeded. - */ - virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { set_reduce_invoked(); return false; } - - /** - \brief Return in \c result an expression \c e equivalent to (f args[0] ... args[0] ... args[num_args - 1]). - Where each args[i] occurs mults[i] times. - - Return true if succeeded. - */ - virtual bool reduce(func_decl * f, unsigned num_args, rational const * mults, expr * const * args, expr_ref & result); - - /** - \brief Return in \c result an expression \c e equivalent to (= lhs rhs). - - Return true if succeeded. - */ - virtual bool reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { set_reduce_invoked(); return false; } - - /** - \brief Return in \c result an expression \c e equivalent to (distinct args[0] ... args[num_args-1]). - - Return true if succeeded. - */ - virtual bool reduce_distinct(unsigned num_args, expr * const * args, expr_ref & result) { set_reduce_invoked(); return false; } - - family_id get_family_id() const { return m_fid; } - - /** - \brief Simplifiers may maintain local caches. These caches must be flushed when this method is invoked. - */ - virtual void flush_caches() { /* do nothing */ } - - ast_manager & get_manager() { return m_manager; } - - void enable_presimp(bool flag) { m_presimp = flag; } - - virtual void enable_ac_support(bool flag) {} -}; - -#endif diff --git a/src/muz/pdr/pdr_util.cpp b/src/muz/pdr/pdr_util.cpp index 42a57214a..19ffdeeec 100644 --- a/src/muz/pdr/pdr_util.cpp +++ b/src/muz/pdr/pdr_util.cpp @@ -22,29 +22,26 @@ Notes: --*/ #include -#include "ast/simplifier/arith_simplifier_plugin.h" +#include "util/util.h" +#include "util/ref_vector.h" #include "ast/array_decl_plugin.h" #include "ast/ast_pp.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" -#include "ast/rewriter/bool_rewriter.h" -#include "muz/base/dl_util.h" #include "ast/for_each_expr.h" -#include "smt/params/smt_params.h" -#include "model/model.h" -#include "util/ref_vector.h" -#include "ast/rewriter/rewriter.h" -#include "ast/rewriter/rewriter_def.h" -#include "util/util.h" -#include "muz/pdr/pdr_manager.h" -#include "muz/pdr/pdr_util.h" +#include "ast/scoped_proof.h" #include "ast/arith_decl_plugin.h" #include "ast/rewriter/expr_replacer.h" -#include "model/model_smt2_pp.h" +#include "ast/rewriter/bool_rewriter.h" #include "ast/rewriter/poly_rewriter.h" #include "ast/rewriter/poly_rewriter_def.h" #include "ast/rewriter/arith_rewriter.h" -#include "ast/scoped_proof.h" +#include "ast/rewriter/rewriter.h" +#include "ast/rewriter/rewriter_def.h" +#include "smt/params/smt_params.h" +#include "model/model.h" +#include "muz/base/dl_util.h" +#include "muz/pdr/pdr_manager.h" +#include "muz/pdr/pdr_util.h" +#include "model/model_smt2_pp.h" diff --git a/src/muz/rel/dl_bound_relation.h b/src/muz/rel/dl_bound_relation.h index 1678e23b8..3dec9d313 100644 --- a/src/muz/rel/dl_bound_relation.h +++ b/src/muz/rel/dl_bound_relation.h @@ -26,7 +26,6 @@ Revision History: #include "muz/rel/dl_vector_relation.h" #include "muz/rel/dl_interval_relation.h" #include "ast/arith_decl_plugin.h" -#include "ast/simplifier/basic_simplifier_plugin.h" #include "ast/rewriter/bool_rewriter.h" namespace datalog { diff --git a/src/muz/rel/dl_interval_relation.h b/src/muz/rel/dl_interval_relation.h index 05334624f..a9cce9802 100644 --- a/src/muz/rel/dl_interval_relation.h +++ b/src/muz/rel/dl_interval_relation.h @@ -20,13 +20,12 @@ Revision History: #define DL_INTERVAL_RELATION_H_ +#include "ast/arith_decl_plugin.h" +#include "smt/old_interval.h" #include "muz/base/dl_context.h" #include "muz/rel/dl_relation_manager.h" #include "muz/rel/dl_base.h" -#include "smt/old_interval.h" #include "muz/rel/dl_vector_relation.h" -#include "ast/arith_decl_plugin.h" -#include "ast/simplifier/basic_simplifier_plugin.h" namespace datalog { diff --git a/src/muz/spacer/spacer_legacy_mbp.cpp b/src/muz/spacer/spacer_legacy_mbp.cpp index fc2fd1fdd..9f03e6d2f 100644 --- a/src/muz/spacer/spacer_legacy_mbp.cpp +++ b/src/muz/spacer/spacer_legacy_mbp.cpp @@ -20,9 +20,6 @@ Notes: #include "ast/array_decl_plugin.h" #include "ast/ast_pp.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/simplifier/basic_simplifier_plugin.h" -#include "ast/simplifier/bv_simplifier_plugin.h" #include "ast/rewriter/bool_rewriter.h" #include "muz/base/dl_util.h" #include "ast/for_each_expr.h" diff --git a/src/smt/arith_eq_adapter.h b/src/smt/arith_eq_adapter.h index f18b2999f..4a8a293e3 100644 --- a/src/smt/arith_eq_adapter.h +++ b/src/smt/arith_eq_adapter.h @@ -23,7 +23,6 @@ Revision History: #include "util/obj_pair_hashtable.h" #include "ast/arith_decl_plugin.h" #include "util/statistics.h" -#include "ast/simplifier/arith_simplifier_plugin.h" namespace smt { diff --git a/src/smt/theory_arith.h b/src/smt/theory_arith.h index 26b970d30..5f4e58a1b 100644 --- a/src/smt/theory_arith.h +++ b/src/smt/theory_arith.h @@ -34,7 +34,6 @@ Revision History: #include "util/obj_pair_hashtable.h" #include "smt/old_interval.h" #include "math/grobner/grobner.h" -#include "ast/simplifier/arith_simplifier_plugin.h" #include "smt/arith_eq_solver.h" #include "smt/theory_opt.h" #include "util/uint_set.h" diff --git a/src/smt/theory_arith_int.h b/src/smt/theory_arith_int.h index fbcc9c11a..4f15a6156 100644 --- a/src/smt/theory_arith_int.h +++ b/src/smt/theory_arith_int.h @@ -19,12 +19,11 @@ Revision History: #ifndef THEORY_ARITH_INT_H_ #define THEORY_ARITH_INT_H_ -#include "ast/ast_ll_pp.h" -#include "ast/simplifier/arith_simplifier_plugin.h" -#include "ast/well_sorted.h" -#include "math/euclid/euclidean_solver.h" #include "util/numeral_buffer.h" +#include "ast/ast_ll_pp.h" +#include "ast/well_sorted.h" #include "ast/ast_smt2_pp.h" +#include "math/euclid/euclidean_solver.h" namespace smt { From 4452ff9884f69e06b8a8343b20bec1dea3ebd2ee Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 29 Aug 2017 19:16:56 -0700 Subject: [PATCH 228/488] elaborate on dom simplifier Signed-off-by: Nikolaj Bjorner --- src/tactic/core/CMakeLists.txt | 1 + src/tactic/core/dom_simplify_tactic.cpp | 415 ++++++++++++------------ src/tactic/core/dom_simplify_tactic.h | 132 ++++++++ 3 files changed, 336 insertions(+), 212 deletions(-) create mode 100644 src/tactic/core/dom_simplify_tactic.h diff --git a/src/tactic/core/CMakeLists.txt b/src/tactic/core/CMakeLists.txt index f192b4fa6..006948315 100644 --- a/src/tactic/core/CMakeLists.txt +++ b/src/tactic/core/CMakeLists.txt @@ -7,6 +7,7 @@ z3_add_component(core_tactics ctx_simplify_tactic.cpp der_tactic.cpp distribute_forall_tactic.cpp + dom_simplify_tactic.cpp elim_term_ite_tactic.cpp elim_uncnstr_tactic.cpp injectivity_tactic.cpp diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 3b444ef1a..21686fe64 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -17,210 +17,165 @@ Notes: --*/ -#if 0 -#include "ast/ast.h" +#include "ast/ast_util.h" +#include "ast/ast_pp.h" +#include "tactic/core/dom_simplify_tactic.h" -class expr_dominators { -public: - typedef obj_map> tree_t; -private: - ast_manager& m; - expr_ref m_root; - obj_map m_expr2post; // reverse post-order number - ptr_vector m_post2expr; - tree_t m_parents; - obj_map m_doms; - tree_t m_tree; - void add_edge(tree_t& tree, expr * src, expr* dst) { - tree.insert_if_not_there(src, ptr_vector()).push_back(dst); - } - - /** - \brief compute a post-order traversal for e. - Also populate the set of parents - */ - void compute_post_order() { - unsigned post_num = 0; - SASSERT(m_post2expr.empty()); - SASSERT(m_expr2post.empty()); - ast_mark mark; - ptr_vector todo; - todo.push_back(m_root); - while (!todo.empty()) { - expr* e = todo.back(); - if (is_marked(e)) { - todo.pop_back(); - continue; +/** + \brief compute a post-order traversal for e. + Also populate the set of parents +*/ +void expr_dominators::compute_post_order() { + unsigned post_num = 0; + SASSERT(m_post2expr.empty()); + SASSERT(m_expr2post.empty()); + ast_mark mark; + ptr_vector todo; + todo.push_back(m_root); + while (!todo.empty()) { + expr* e = todo.back(); + if (mark.is_marked(e)) { + todo.pop_back(); + continue; + } + if (is_app(e)) { + app* a = to_app(e); + bool done = true; + for (expr* arg : *a) { + if (!mark.is_marked(arg)) { + todo.push_back(arg); + done = false; + } } - if (is_app(e)) { - app* a = to_app(e); - bool done = true; + if (done) { + mark.mark(e, true); + m_expr2post.insert(e, post_num++); + m_post2expr.push_back(e); + todo.pop_back(); for (expr* arg : *a) { - if (!is_marked(arg)) { - todo.push_back(arg); - done = false; - } - } - if (done) { - mark.mark(e); - m_expr2post.insert(e, post_num++); - m_post2expr.push_back(e); - todo.pop_back(); - for (expr* arg : *a) { - add_edge(m_parents, arg, a); - } - } - } - else { - todo.pop_back(); - } - } - } - - expr* intersect(expr* x, expr * y) { - unsigned n1 = m_expr2post[x]; - unsigned n2 = m_expr2post[y]; - while (n1 != n2) { - if (n1 < n2) { - x = m_doms[x]; - n1 = m_expr2post[x]; - } - else if (n1 > n2) { - y = m_doms[y]; - n2 = m_expr2post[y]; - } - } - SASSERT(x == y); - return x; - } - - void compute_dominators() { - expr * e = m_root; - SASSERT(m_doms.empty()); - m_doms.insert(e, e); - bool change = true; - while (change) { - change = false; - SASSERT(m_post2expr.back() == e); - for (unsigned i = 0; i < m_post2expr.size() - 1; ++i) { - expr * child = m_post2expr[i]; - ptr_vector const& p = m_parents[child]; - SASSERT(!p.empty()); - expr * new_idom = p[0], * idom2 = 0; - for (unsigned j = 1; j < p.size(); ++j) { - if (m_doms.find(p[j], idom2)) { - new_idom = intersect(new_idom, idom2); - } - } - if (!m_doms.find(child, idom2) || idom2 != new_idom) { - m_doms.insert(child, new_idom); - change = true; + add_edge(m_parents, arg, a); } } } - } - - void extract_tree() { - for (auto const& kv : m_doms) { - add_edge(m_tree, kv.m_value, kv.m_key); + else { + mark.mark(e, true); + todo.pop_back(); } - } - - void reset() { - m_expr2post.reset(); - m_post2expr.reset(); - m_parents.reset(); - m_doms.reset(); - m_tree.reset(); - m_root.reset(); } +} - -public: - expr_dominators(ast_manager& m): m(m), m_root(m) {} - - void compile(expr * e) { - reset(); - m_root = e; - compute_post_order(); - compute_dominators(); - extract_tree(); +expr* expr_dominators::intersect(expr* x, expr * y) { + unsigned n1 = m_expr2post[x]; + unsigned n2 = m_expr2post[y]; + while (n1 != n2) { + if (n1 < n2) { + x = m_doms[x]; + n1 = m_expr2post[x]; + } + else if (n1 > n2) { + y = m_doms[y]; + n2 = m_expr2post[y]; + } } + SASSERT(x == y); + return x; +} - void compile(unsigned sz, expr * const* es) { - expr_ref e(m.mk_and(sz, es), m); - compile(e); +void expr_dominators::compute_dominators() { + expr * e = m_root; + SASSERT(m_doms.empty()); + m_doms.insert(e, e); + bool change = true; + while (change) { + change = false; + SASSERT(m_post2expr.back() == e); + for (unsigned i = 0; i < m_post2expr.size() - 1; ++i) { + expr * child = m_post2expr[i]; + ptr_vector const& p = m_parents[child]; + SASSERT(!p.empty()); + expr * new_idom = p[0], * idom2 = 0; + for (unsigned j = 1; j < p.size(); ++j) { + if (m_doms.find(p[j], idom2)) { + new_idom = intersect(new_idom, idom2); + } + } + if (!m_doms.find(child, idom2) || idom2 != new_idom) { + m_doms.insert(child, new_idom); + change = true; + } + } } +} + +void expr_dominators::extract_tree() { + for (auto const& kv : m_doms) { + add_edge(m_tree, kv.m_value, kv.m_key); + } +} + + + +void expr_dominators::compile(expr * e) { + reset(); + m_root = e; + compute_post_order(); + compute_dominators(); + extract_tree(); +} + +void expr_dominators::compile(unsigned sz, expr * const* es) { + expr_ref e(m.mk_and(sz, es), m); + compile(e); +} + + +void expr_dominators::reset() { + m_expr2post.reset(); + m_post2expr.reset(); + m_parents.reset(); + m_doms.reset(); + m_tree.reset(); + m_root.reset(); +} - tree_t const& get_tree() { return m_tree; } -}; // goes to header file: -class dom_simplify_tactic : public tactic { -public: - class simplifier { - public: - virtual ~simplifier() {} - /** - \brief assert_expr performs an implicit push - */ - virtual bool assert_expr(expr * t, bool sign) = 0; - /** - \brief apply simplification. - */ - virtual void operator()(expr_ref& r) = 0; - - /** - \brief pop scopes accumulated from assertions. - */ - virtual void pop(unsigned num_scopes) = 0; - }; -private: - simplifier& m_simplifier; - params_ref m_params; - expr_ref_vector m_trail; - obj_map m_result; - expr_dominators m_dominators; - - expr_ref simplify(expr* t); - expr_ref simplify_ite(app * ite); - expr_ref simplify_and(app * ite) { return simplify_and_or(true, ite); } - expr_ref simplify_or(app * ite) { return simplify_and_or(false, ite); } - expr_ref simplify_and_or(bool is_and app * ite); - - expr_ref get_cache(expr* t) { if (!m_result.find(r, r)) r = t; return expr_ref(r, m); } - void cache(expr *t, expr* r) { m_result.insert(t, r); m_trail.push_back(r); } - - void simplify_goal(goal_ref& g); - -public: - dom_simplify_tactic(ast_manager & m, simplifier& s, params_ref const & p = params_ref()); - - virtual tactic * translate(ast_manager & m); - - virtual ~dom_simplify_tactic(); - - virtual void updt_params(params_ref const & p); - static void get_param_descrs(param_descrs & r); - virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); } - - virtual void operator()(goal_ref const & in, - goal_ref_buffer & result, - model_converter_ref & mc, - proof_converter_ref & pc, - expr_dependency_ref & core); - - virtual void cleanup(); -}; // implementation: -expr_ref dom_simplifier_tactic::simplify_ite(app * ite) { +tactic * dom_simplify_tactic::translate(ast_manager & m) { + return alloc(dom_simplify_tactic, m, m_simplifier->translate(m), m_params); +} + +void dom_simplify_tactic::operator()( + goal_ref const & in, + goal_ref_buffer & result, + model_converter_ref & mc, + proof_converter_ref & pc, + expr_dependency_ref & core) { + mc = 0; pc = 0; core = 0; + + tactic_report report("dom-simplify", *in.get()); + simplify_goal(*(in.get())); + in->inc_depth(); + result.push_back(in.get()); + +} + +void dom_simplify_tactic::cleanup() { + m_trail.reset(); + m_args.reset(); + m_args2.reset(); + m_result.reset(); + m_dominators.reset(); +} + +expr_ref dom_simplify_tactic::simplify_ite(app * ite) { expr_ref r(m); expr * c = 0, * t = 0, * e = 0; VERIFY(m.is_ite(ite, c, t, e)); @@ -233,7 +188,7 @@ expr_ref dom_simplifier_tactic::simplify_ite(app * ite) { r = simplify(e); } else { - expr_ref t = simplify(t); + expr_ref new_t = simplify(t); pop(scope_level() - old_lvl); if (!assert_expr(new_c, true)) { return new_t; @@ -254,14 +209,18 @@ expr_ref dom_simplifier_tactic::simplify_ite(app * ite) { return r; } -expr_ref dom_simplifier_tactic::simplify(expr * e0) { +expr_ref dom_simplify_tactic::simplify(expr * e0) { expr_ref r(m); expr* e = 0; if (!m_result.find(e0, e)) { e = e0; } - - if (m.is_ite(e)) { + + ++m_depth; + if (m_depth > m_max_depth) { + r = e; + } + else if (m.is_ite(e)) { r = simplify_ite(to_app(e)); } else if (m.is_and(e)) { @@ -271,7 +230,7 @@ expr_ref dom_simplifier_tactic::simplify(expr * e0) { r = simplify_or(to_app(e)); } else { - tree_t const& t = m_dominators.get_tree(); + expr_dominators::tree_t const& t = m_dominators.get_tree(); if (t.contains(e)) { ptr_vector const& children = t[e]; for (expr * child : children) { @@ -281,7 +240,7 @@ expr_ref dom_simplifier_tactic::simplify(expr * e0) { if (is_app(e)) { m_args.reset(); for (expr* arg : *to_app(e)) { - m_args.push_back(get_cached(arg)); + m_args.push_back(get_cached(arg)); // TBD is cache really applied to all sub-terms? } r = m.mk_app(to_app(e)->get_decl(), m_args.size(), m_args.c_ptr()); } @@ -289,18 +248,20 @@ expr_ref dom_simplifier_tactic::simplify(expr * e0) { r = e; } } - m_simplifier(r); + (*m_simplifier)(r); cache(e0, r); + TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e0, m) << " -> " << r << "\n";); + --m_depth; return r; } -expr_ref dom_simplifier_tactic::simplify_or_and(bool is_and, app * e) { +expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { expr_ref r(m); unsigned old_lvl = scope_level(); m_args.reset(); for (expr * arg : *e) { r = simplify(arg); - if (!assert_expr(r, is_and)) { + if (!assert_expr(r, !is_and)) { r = is_and ? m.mk_false() : m.mk_true(); } m_args.push_back(r); @@ -310,7 +271,7 @@ expr_ref dom_simplifier_tactic::simplify_or_and(bool is_and, app * e) { m_args2.reset(); for (expr * arg : m_args) { r = simplify(arg); - if (!assert_expr(r, is_and)) { + if (!assert_expr(r, !is_and)) { r = is_and ? m.mk_false() : m.mk_true(); } m_args2.push_back(r); @@ -321,31 +282,61 @@ expr_ref dom_simplifier_tactic::simplify_or_and(bool is_and, app * e) { return r; } -void dom_simplifier_tactic::simplify_goal(goal& g) { + +void dom_simplify_tactic::init(goal& g) { expr_ref_vector args(m); - expr_ref fml(m); + unsigned sz = g.size(); for (unsigned i = 0; i < sz; ++i) args.push_back(g.form(i)); - fml = mk_and(args); - expr_ref tmp(fml); - // TBD: deal with dependencies. - do { - m_result.reset(); - m_trail.reset(); - m_dominators.compile(fml); -#if 0 - for (unsigned i = 0; i < sz; ++i) { - r = simplify(g.form(i)); - // TBD: simplfy goal as a conjuction ? - // + expr_ref fml = mk_and(args); + m_result.reset(); + m_trail.reset(); + m_dominators.compile(fml); +} + +void dom_simplify_tactic::simplify_goal(goal& g) { + + SASSERT(scope_level() == 0); + bool change = true; + m_depth = 0; + while (change) { + change = false; + + // go forwards + init(g); + unsigned sz = g.size(); + for (unsigned i = 0; !g.inconsistent() && i < sz; ++i) { + expr_ref r = simplify(g.form(i)); + if (i < sz - 1 && !m.is_true(r) && !m.is_false(r) && !g.dep(i) && !g.proofs_enabled() && !assert_expr(r, false)) { + r = m.mk_false(); + } + change |= r != g.form(i); + proof* new_pr = 0; + if (g.proofs_enabled()) { + new_pr = m.mk_modus_ponens(g.pr(i), m.mk_rewrite_star(g.form(i), r, 0, 0)); + } + g.update(i, r, new_pr, g.dep(i)); } -#endif - tmp = fml; - fml = simplify(fml); + pop(scope_level()); + + // go backwards + init(g); + sz = g.size(); + for (unsigned i = sz; !g.inconsistent() && i > 0; ) { + --i; + expr_ref r = simplify(g.form(i)); + if (i > 0 && !m.is_true(r) && !m.is_false(r) && !g.dep(i) && !g.proofs_enabled() && !assert_expr(r, false)) { + r = m.mk_false(); + } + change |= r != g.form(i); + proof* new_pr = 0; + if (g.proofs_enabled()) { + new_pr = m.mk_modus_ponens(g.pr(i), m.mk_rewrite_star(g.form(i), r, 0, 0)); + } + g.update(i, r, new_pr, g.dep(i)); + } + pop(scope_level()); } - while (tmp != fml); - //g.reset(); - //g.add(fml); + SASSERT(scope_level() == 0); } -#endif diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h new file mode 100644 index 000000000..9325f95f5 --- /dev/null +++ b/src/tactic/core/dom_simplify_tactic.h @@ -0,0 +1,132 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + dom_simplify_tactic.cpp + +Abstract: + + Dominator-based context simplifer. + +Author: + + Nikolaj and Nuno + +Notes: + +--*/ + +#ifndef DOM_SIMPLIFY_TACTIC_H_ +#define DOM_SIMPLIFY_TACTIC_H_ + +#include "ast/ast.h" +#include "tactic/tactic.h" + + +class expr_dominators { +public: + typedef obj_map> tree_t; +private: + ast_manager& m; + expr_ref m_root; + obj_map m_expr2post; // reverse post-order number + ptr_vector m_post2expr; + tree_t m_parents; + obj_map m_doms; + tree_t m_tree; + + void add_edge(tree_t& tree, expr * src, expr* dst) { + tree.insert_if_not_there2(src, ptr_vector())->get_data().m_value.push_back(dst); + } + + void compute_post_order(); + expr* intersect(expr* x, expr * y); + void compute_dominators(); + void extract_tree(); + +public: + expr_dominators(ast_manager& m): m(m), m_root(m) {} + + void compile(expr * e); + void compile(unsigned sz, expr * const* es); + tree_t const& get_tree() { return m_tree; } + void reset(); + +}; + +class dom_simplify_tactic : public tactic { +public: + class simplifier { + public: + virtual ~simplifier() {} + /** + \brief assert_expr performs an implicit push + */ + virtual bool assert_expr(expr * t, bool sign) = 0; + + /** + \brief apply simplification. + */ + virtual void operator()(expr_ref& r) = 0; + + /** + \brief pop scopes accumulated from assertions. + */ + virtual void pop(unsigned num_scopes) = 0; + + virtual simplifier * translate(ast_manager & m); + + }; +private: + ast_manager& m; + simplifier* m_simplifier; + params_ref m_params; + expr_ref_vector m_trail, m_args, m_args2; + obj_map m_result; + expr_dominators m_dominators; + unsigned m_scope_level; + unsigned m_depth; + unsigned m_max_depth; + + expr_ref simplify(expr* t); + expr_ref simplify_ite(app * ite); + expr_ref simplify_and(app * ite) { return simplify_and_or(true, ite); } + expr_ref simplify_or(app * ite) { return simplify_and_or(false, ite); } + expr_ref simplify_and_or(bool is_and, app * ite); + void simplify_goal(goal& g); + + expr_ref get_cached(expr* t) { expr* r = 0; if (!m_result.find(r, r)) r = t; return expr_ref(r, m); } + void cache(expr *t, expr* r) { m_result.insert(t, r); m_trail.push_back(r); } + + unsigned scope_level() { return m_scope_level; } + void pop(unsigned n) { SASSERT(n <= m_scope_level); m_scope_level -= n; m_simplifier->pop(n); } + bool assert_expr(expr* f, bool sign) { m_scope_level++; return m_simplifier->assert_expr(f, sign); } + + void init(goal& g); + +public: + dom_simplify_tactic(ast_manager & m, simplifier* s, params_ref const & p = params_ref()): + m(m), m_simplifier(s), m_params(p), + m_trail(m), m_args(m), m_args2(m), + m_dominators(m), + m_scope_level(0), m_depth(0), m_max_depth(1024) {} + + + virtual ~dom_simplify_tactic() {} + + virtual tactic * translate(ast_manager & m); + virtual void updt_params(params_ref const & p) {} + static void get_param_descrs(param_descrs & r) {} + virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); } + + virtual void operator()(goal_ref const & in, + goal_ref_buffer & result, + model_converter_ref & mc, + proof_converter_ref & pc, + expr_dependency_ref & core); + + virtual void cleanup(); +}; + +#endif From 1a1c705376677376cc9f8e63896e136f91b6c7eb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 30 Aug 2017 19:34:31 +0100 Subject: [PATCH 229/488] Added global model completion for the SMT2 frontend. --- src/cmd_context/cmd_context.cpp | 97 +++++++++++++++++++++++++++++---- src/cmd_context/cmd_context.h | 47 ++++++++-------- src/cmd_context/pdecl.cpp | 79 ++++++++++++++------------- src/cmd_context/pdecl.h | 13 +++-- src/model/model_params.pyg | 3 +- 5 files changed, 164 insertions(+), 75 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index f172e5e93..acbdc0bcf 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -229,6 +229,28 @@ func_decl * func_decls::find(ast_manager & m, unsigned num_args, expr * const * return find(num_args, sorts.c_ptr(), range); } +unsigned func_decls::get_num_entries() const { + if (!more_than_one()) + return 1; + + func_decl_set * fs = UNTAG(func_decl_set *, m_decls); + return fs->size(); +} + +func_decl * func_decls::get_entry(unsigned inx) { + if (!more_than_one()) { + SASSERT(inx == 0); + return first(); + } + else { + func_decl_set * fs = UNTAG(func_decl_set *, m_decls); + auto b = fs->begin(); + for (unsigned i = 0; i < inx; i++) + b++; + return *b; + } +} + void macro_decls::finalize(ast_manager& m) { for (auto v : *m_decls) m.dec_ref(v.m_body); dealloc(m_decls); @@ -288,13 +310,13 @@ void cmd_context::insert_macro(symbol const& s, unsigned arity, sort*const* doma } else { VERIFY(decls.insert(m(), arity, domain, t)); - } + } } void cmd_context::erase_macro(symbol const& s) { macro_decls decls; VERIFY(m_macros.find(s, decls)); - decls.erase_last(m()); + decls.erase_last(m()); } bool cmd_context::macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const { @@ -870,11 +892,11 @@ void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, s } // - // disable warning given the current way they are used - // (Z3 will here silently assume and not check the definitions to be well founded, + // disable warning given the current way they are used + // (Z3 will here silently assume and not check the definitions to be well founded, // and please use HSF for everything else). // - if (false && !ids.empty() && !m_rec_fun_declared) { + if (false && !ids.empty() && !m_rec_fun_declared) { warning_msg("recursive function definitions are assumed well-founded"); m_rec_fun_declared = true; } @@ -953,7 +975,7 @@ func_decl * cmd_context::find_func_decl(symbol const & s, unsigned num_indices, return f; } - if (contains_macro(s, arity, domain)) + if (contains_macro(s, arity, domain)) throw cmd_exception("invalid function declaration reference, named expressions (aka macros) cannot be referenced ", s); if (num_indices > 0) @@ -1316,7 +1338,7 @@ void cmd_context::push(unsigned n) { push(); } -void cmd_context::restore_func_decls(unsigned old_sz) { +void cmd_context::restore_func_decls(unsigned old_sz) { SASSERT(old_sz <= m_func_decls_stack.size()); svector::iterator it = m_func_decls_stack.begin() + old_sz; svector::iterator end = m_func_decls_stack.end(); @@ -1418,7 +1440,7 @@ void cmd_context::pop(unsigned n) { restore_assertions(s.m_assertions_lim); restore_psort_inst(s.m_psort_inst_stack_lim); m_scopes.shrink(new_lvl); - + } void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions) { @@ -1488,6 +1510,7 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions } display_sat_result(r); if (r == l_true) { + complete_model(); validate_model(); } validate_check_sat_result(r); @@ -1548,7 +1571,7 @@ void cmd_context::reset_assertions() { if (m_solver) m_solver->push(); } } - + void cmd_context::display_model(model_ref& mdl) { if (mdl) { @@ -1632,6 +1655,60 @@ struct contains_array_op_proc { void operator()(quantifier * n) {} }; +/** + \brief Complete the model if necessary. +*/ +void cmd_context::complete_model() { + if (!is_model_available() || + gparams::get_value("model.completion") != "true") + return; + + model_ref md; + get_check_sat_result()->get_model(md); + SASSERT(md.get() != 0); + 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("completion", true); + model_evaluator evaluator(*(md.get()), p); + evaluator.set_expand_array_equalities(false); + + scoped_rlimit _rlimit(m().limit(), 0); + cancel_eh eh(m().limit()); + expr_ref r(m()); + scoped_ctrl_c ctrlc(eh); + + for (auto kd : m_psort_decls) { + symbol const & k = kd.m_key; + psort_decl * v = kd.m_value; + if (v->is_user_decl()) { + SASSERT(!v->has_var_params()); + IF_VERBOSE(12, verbose_stream() << "(model.completion " << k << ")\n"; ); + ptr_vector param_sorts(v->get_num_params(), m().mk_bool_sort()); + sort * srt = v->instantiate(*m_pmanager, param_sorts.size(), param_sorts.c_ptr()); + if (!md->has_uninterpreted_sort(srt)) { + expr * singleton = m().get_some_value(srt); + md->register_usort(srt, 1, &singleton); + } + } + } + + for (auto kd : m_func_decls) { + symbol const & k = kd.m_key; + func_decls & v = kd.m_value; + IF_VERBOSE(12, verbose_stream() << "(model.completion " << k << ")\n"; ); + for (unsigned i = 0; i < v.get_num_entries(); i++) { + func_decl * f = v.get_entry(i); + if (!md->has_interpretation(f)) { + sort * range = f->get_range(); + func_interp * fi = alloc(func_interp, m(), f->get_arity()); + fi->set_else(m().get_some_value(range)); + md->register_decl(f, fi); + } + } + } +} + /** \brief Check if the current model satisfies the quantifier free formulas. */ @@ -1918,7 +1995,7 @@ void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) { } if (m_owner.m_scopes.size() > 0) { m_owner.m_psort_inst_stack.push_back(pd); - + } } diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index 189863e58..5883a8d8e 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -8,7 +8,7 @@ Module Name: Abstract: Ultra-light command context. It provides a generic command pluging infrastructure. - A command context also provides names (aka symbols) to Z3 objects. + A command context also provides names (aka symbols) to Z3 objects. These names are used to reference Z3 objects in commands. Author: @@ -58,6 +58,8 @@ public: func_decl * first() const; func_decl * find(unsigned arity, sort * const * domain, sort * range) const; func_decl * find(ast_manager & m, unsigned num_args, expr * const * args, sort * range) const; + unsigned get_num_entries() const; + func_decl * get_entry(unsigned inx); }; struct macro_decl { @@ -66,18 +68,18 @@ struct macro_decl { macro_decl(unsigned arity, sort *const* domain, expr* body): m_domain(arity, domain), m_body(body) {} - + void dec_ref(ast_manager& m) { m.dec_ref(m_body); } - + }; class macro_decls { vector* m_decls; -public: +public: macro_decls() { m_decls = 0; } void finalize(ast_manager& m); bool insert(ast_manager& m, unsigned arity, sort *const* domain, expr* body); - expr* find(unsigned arity, sort *const* domain) const; + expr* find(unsigned arity, sort *const* domain) const; void erase_last(ast_manager& m); vector::iterator begin() const { return m_decls->begin(); } vector::iterator end() const { return m_decls->end(); } @@ -158,11 +160,11 @@ public: enum status { UNSAT, SAT, UNKNOWN }; - + enum check_sat_state { css_unsat, css_sat, css_unknown, css_clear }; - + typedef std::pair macro; struct scoped_watch { @@ -188,7 +190,7 @@ protected: bool m_ignore_check; // used by the API to disable check-sat() commands when parsing SMT 2.0 files. bool m_processing_pareto; // used when re-entering check-sat for pareto front. bool m_exit_on_error; - + static std::ostringstream g_error_stream; ast_manager * m_manager; @@ -200,7 +202,7 @@ protected: check_logic m_check_logic; stream_ref m_regular; stream_ref m_diagnostic; - dictionary m_cmds; + dictionary m_cmds; dictionary m_builtin_decls; scoped_ptr_vector m_extra_builtin_decls; // make sure that dynamically allocated builtin_decls are deleted dictionary m_object_refs; // anything that can be named. @@ -217,7 +219,7 @@ protected: svector m_macros_stack; ptr_vector m_psort_inst_stack; - // + // ptr_vector m_aux_pdecls; ptr_vector m_assertions; std::vector m_assertion_strings; @@ -236,7 +238,7 @@ protected: svector m_scopes; scoped_ptr m_solver_factory; scoped_ptr m_interpolating_solver_factory; - ref m_solver; + ref m_solver; ref m_check_sat_result; ref m_opt; @@ -296,7 +298,7 @@ protected: bool contains_macro(symbol const& s) const; bool contains_macro(symbol const& s, func_decl* f) const; - bool contains_macro(symbol const& s, unsigned arity, sort *const* domain) const; + bool contains_macro(symbol const& s, unsigned arity, sort *const* domain) const; void insert_macro(symbol const& s, unsigned arity, sort*const* domain, expr* t); void erase_macro(symbol const& s); bool macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const; @@ -304,7 +306,7 @@ protected: public: cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null); - ~cmd_context(); + ~cmd_context(); void set_cancel(bool f); context_params & params() { return m_params; } solver_factory &get_solver_factory() { return *m_solver_factory; } @@ -354,39 +356,40 @@ public: virtual ast_manager & get_ast_manager() { return m(); } pdecl_manager & pm() const { if (!m_pmanager) const_cast(this)->init_manager(); return *m_pmanager; } sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; } - + void set_solver_factory(solver_factory * s); void set_interpolating_solver_factory(solver_factory * s); void set_check_sat_result(check_sat_result * r) { m_check_sat_result = r; } check_sat_result * get_check_sat_result() const { return m_check_sat_result.get(); } check_sat_state cs_state() const; + void complete_model(); void validate_model(); void display_model(model_ref& mdl); - void register_plugin(symbol const & name, decl_plugin * p, bool install_names); + void register_plugin(symbol const & name, decl_plugin * p, bool install_names); bool is_func_decl(symbol const & s) const; bool is_sort_decl(symbol const& s) const { return m_psort_decls.contains(s); } void insert(cmd * c); - void insert(symbol const & s, func_decl * f); + void insert(symbol const & s, func_decl * f); void insert(func_decl * f) { insert(f->get_name(), f); } void insert(symbol const & s, psort_decl * p); void insert(psort_decl * p) { insert(p->get_name(), p); } void insert(symbol const & s, unsigned arity, sort *const* domain, expr * t); void insert(symbol const & s, object_ref *); void insert(tactic_cmd * c) { tactic_manager::insert(c); } - void insert(probe_info * p) { tactic_manager::insert(p); } - void insert_user_tactic(symbol const & s, sexpr * d); + void insert(probe_info * p) { tactic_manager::insert(p); } + void insert_user_tactic(symbol const & s, sexpr * d); void insert_aux_pdecl(pdecl * p); void insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector const& ids, expr* e); func_decl * find_func_decl(symbol const & s) const; - func_decl * find_func_decl(symbol const & s, unsigned num_indices, unsigned const * indices, + func_decl * find_func_decl(symbol const & s, unsigned num_indices, unsigned const * indices, unsigned arity, sort * const * domain, sort * range) const; psort_decl * find_psort_decl(symbol const & s) const; cmd * find_cmd(symbol const & s) const; sexpr * find_user_tactic(symbol const & s) const; object_ref * find_object_ref(symbol const & s) const; void mk_const(symbol const & s, expr_ref & result) const; - void mk_app(symbol const & s, unsigned num_args, expr * const * args, unsigned num_indices, parameter const * indices, sort * range, + void mk_app(symbol const & s, unsigned num_args, expr * const * args, unsigned num_indices, parameter const * indices, sort * range, expr_ref & r) const; void erase_cmd(symbol const & s); void erase_func_decl(symbol const & s); @@ -401,7 +404,7 @@ public: void reset_object_refs(); void reset_user_tactics(); void set_regular_stream(char const * name) { m_regular.set(name); } - void set_diagnostic_stream(char const * name); + void set_diagnostic_stream(char const * name); virtual std::ostream & regular_stream() { return *m_regular; } virtual std::ostream & diagnostic_stream() { return *m_diagnostic; } char const * get_regular_stream_name() const { return m_regular.name(); } @@ -429,7 +432,7 @@ public: // display the result produced by a check-sat or check-sat-using commands in the regular stream void display_sat_result(lbool r); // check if result produced by check-sat or check-sat-using matches the known status - void validate_check_sat_result(lbool r); + void validate_check_sat_result(lbool r); unsigned num_scopes() const { return m_scopes.size(); } dictionary const & get_macros() const { return m_macros; } diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 983dbbc78..f255c8353 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -25,11 +25,11 @@ class psort_inst_cache { sort * m_const; obj_map m_map; // if m_num_params == 1 value is a sort, otherwise it is a reference to another inst_cache public: - psort_inst_cache(unsigned num_params):m_num_params(num_params), m_const(0) { + psort_inst_cache(unsigned num_params):m_num_params(num_params), m_const(0) { } ~psort_inst_cache() { SASSERT(m_map.empty()); SASSERT(m_const == 0); } - + void finalize(pdecl_manager & m) { if (m_num_params == 0) { SASSERT(m_map.empty()); @@ -85,7 +85,7 @@ public: curr = static_cast(next); } } - + sort * find(sort * const * s) const { if (m_num_params == 0) return m_const; @@ -138,8 +138,8 @@ class psort_sort : public psort { friend class pdecl_manager; sort * m_sort; psort_sort(unsigned id, pdecl_manager & m, sort * s):psort(id, 0), m_sort(s) { m.m().inc_ref(m_sort); } - virtual void finalize(pdecl_manager & m) { - m.m().dec_ref(m_sort); + virtual void finalize(pdecl_manager & m) { + m.m().dec_ref(m_sort); psort::finalize(m); } virtual bool check_num_params(pdecl * other) const { return true; } @@ -152,7 +152,7 @@ public: virtual char const * hcons_kind() const { return "psort_sort"; } virtual unsigned hcons_hash() const { return m_sort->get_id(); } virtual bool hcons_eq(psort const * other) const { - if (other->hcons_kind() != hcons_kind()) + if (other->hcons_kind() != hcons_kind()) return false; return m_sort == static_cast(other)->m_sort; } @@ -172,10 +172,10 @@ public: virtual char const * hcons_kind() const { return "psort_var"; } virtual unsigned hcons_hash() const { return hash_u_u(m_num_params, m_idx); } virtual bool hcons_eq(psort const * other) const { - if (other->hcons_kind() != hcons_kind()) + if (other->hcons_kind() != hcons_kind()) return false; return get_num_params() == other->get_num_params() && m_idx == static_cast(other)->m_idx; - } + } virtual void display(std::ostream & out) const { out << "s_" << m_idx; } @@ -197,7 +197,7 @@ class psort_app : public psort { DEBUG_CODE(if (num_args == num_params) { for (unsigned i = 0; i < num_params; i++) args[i]->check_num_params(this); }); } - virtual void finalize(pdecl_manager & m) { + virtual void finalize(pdecl_manager & m) { m.lazy_dec_ref(m_decl); m.lazy_dec_ref(m_args.size(), m_args.c_ptr()); psort::finalize(m); @@ -208,14 +208,14 @@ class psort_app : public psort { struct khasher { unsigned operator()(psort_app const * d) const { return d->m_decl->hash(); } }; - + struct chasher { unsigned operator()(psort_app const * d, unsigned idx) const { return d->m_args[idx]->hash(); } }; - virtual sort * instantiate(pdecl_manager & m, sort * const * s) { + virtual sort * instantiate(pdecl_manager & m, sort * const * s) { sort * r = find(s); - if (r) + if (r) return r; sort_ref_buffer args_i(m.m()); unsigned sz = m_args.size(); @@ -231,11 +231,11 @@ class psort_app : public psort { public: virtual ~psort_app() {} virtual char const * hcons_kind() const { return "psort_app"; } - virtual unsigned hcons_hash() const { + virtual unsigned hcons_hash() const { return get_composite_hash(const_cast(this), m_args.size()); } virtual bool hcons_eq(psort const * other) const { - if (other->hcons_kind() != hcons_kind()) + if (other->hcons_kind() != hcons_kind()) return false; if (get_num_params() != other->get_num_params()) return false; @@ -268,6 +268,7 @@ public: psort_decl::psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n): pdecl(id, num_params), + m_psort_kind(PSORT_BASE), m_name(n), m_inst_cache(0) { } @@ -295,7 +296,7 @@ sort * psort_decl::find(sort * const * s) { #if 0 psort_dt_decl::psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager& m, symbol const& n): - psort_decl(id, num_params, m, n) { + psort_decl(id, num_params, m, n) { } void psort_dt_decl::finalize(pdecl_manager& m) { @@ -314,9 +315,10 @@ void psort_dt_decl::display(std::ostream & out) const { #endif -psort_user_decl::psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p): +psort_user_decl::psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p) : psort_decl(id, num_params, m, n), m_def(p) { + m_psort_kind = PSORT_USER; m.inc_ref(p); SASSERT(p == 0 || num_params == p->get_num_params()); } @@ -369,6 +371,7 @@ psort_builtin_decl::psort_builtin_decl(unsigned id, pdecl_manager & m, symbol co psort_decl(id, PSORT_DECL_VAR_PARAMS, m, n), m_fid(fid), m_kind(k) { + m_psort_kind = PSORT_BUILTIN; } sort * psort_builtin_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { @@ -417,16 +420,16 @@ void ptype::display(std::ostream & out, pdatatype_decl const * const * dts) cons paccessor_decl::paccessor_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, ptype const & r): pdecl(id, num_params), - m_name(n), + m_name(n), m_type(r) { if (m_type.kind() == PTR_PSORT) { m.inc_ref(r.get_psort()); } } -void paccessor_decl::finalize(pdecl_manager & m) { +void paccessor_decl::finalize(pdecl_manager & m) { if (m_type.kind() == PTR_PSORT) { - m.lazy_dec_ref(m_type.get_psort()); + m.lazy_dec_ref(m_type.get_psort()); } } @@ -439,7 +442,7 @@ bool paccessor_decl::has_missing_refs(symbol & missing) const { } bool paccessor_decl::fix_missing_refs(dictionary const & symbol2idx, symbol & missing) { - TRACE("fix_missing_refs", tout << "m_type.kind(): " << m_type.kind() << "\n"; + TRACE("fix_missing_refs", tout << "m_type.kind(): " << m_type.kind() << "\n"; if (m_type.kind() == PTR_MISSING_REF) tout << m_type.get_missing_ref() << "\n";); if (m_type.kind() != PTR_MISSING_REF) return true; @@ -470,7 +473,7 @@ void paccessor_decl::display(std::ostream & out, pdatatype_decl const * const * out << ")"; } -pconstructor_decl::pconstructor_decl(unsigned id, unsigned num_params, pdecl_manager & m, +pconstructor_decl::pconstructor_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, symbol const & r, unsigned num_accessors, paccessor_decl * const * accessors): pdecl(id, num_params), m_name(n), @@ -508,7 +511,7 @@ constructor_decl * pconstructor_decl::instantiate_decl(pdecl_manager & m, sort * ptr_buffer as; ptr_vector::iterator it = m_accessors.begin(); ptr_vector::iterator end = m_accessors.end(); - for (; it != end; ++it) + for (; it != end; ++it) as.push_back((*it)->instantiate_decl(m, s)); return mk_constructor_decl(m_name, m_recogniser_name, as.size(), as.c_ptr()); } @@ -524,7 +527,7 @@ void pconstructor_decl::display(std::ostream & out, pdatatype_decl const * const out << ")"; } -pdatatype_decl::pdatatype_decl(unsigned id, unsigned num_params, pdecl_manager & m, +pdatatype_decl::pdatatype_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, unsigned num_constructors, pconstructor_decl * const * constructors): psort_decl(id, num_params, m, n), m_constructors(num_constructors, constructors), @@ -641,7 +644,7 @@ void pdatatype_decl::display(std::ostream & out) const { out << ")"; } -pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m, +pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m, unsigned num_datatypes, pdatatype_decl * const * dts): pdecl(id, num_params), m_datatypes(num_datatypes, dts) { @@ -714,22 +717,22 @@ struct pdecl_manager::sort_info { struct pdecl_manager::app_sort_info : public pdecl_manager::sort_info { ptr_vector m_args; - + app_sort_info(pdecl_manager & m, psort_decl * d, unsigned n, sort * const * s): sort_info(m, d), m_args(n, s) { m.m().inc_array_ref(n, s); } - + virtual ~app_sort_info() {} - + virtual unsigned obj_size() const { return sizeof(app_sort_info); } - + virtual void finalize(pdecl_manager & m) { sort_info::finalize(m); m.m().dec_array_ref(m_args.size(), m_args.c_ptr()); } - + virtual void display(std::ostream & out, pdecl_manager const & m) const { if (m_args.empty()) { out << m_decl->get_name(); @@ -743,7 +746,7 @@ struct pdecl_manager::app_sort_info : public pdecl_manager::sort_info { out << ")"; } } - + virtual format * pp(pdecl_manager const & m) const { if (m_args.empty()) { return mk_string(m.m(), m_decl->get_name().str().c_str()); @@ -755,7 +758,7 @@ struct pdecl_manager::app_sort_info : public pdecl_manager::sort_info { return mk_seq1(m.m(), b.begin(), b.end(), f2f(), m_decl->get_name().str().c_str()); } } -}; +}; struct pdecl_manager::indexed_sort_info : public pdecl_manager::sort_info { svector m_indices; @@ -781,7 +784,7 @@ struct pdecl_manager::indexed_sort_info : public pdecl_manager::sort_info { out << ")"; } } - + virtual format * pp(pdecl_manager const & m) const { if (m_indices.empty()) { return mk_string(m.m(), m_decl->get_name().str().c_str()); @@ -801,7 +804,7 @@ void pdecl_manager::init_list() { psort * v = mk_psort_var(1, 0); ptype T(v); ptype ListT(0); - paccessor_decl * as[2] = { mk_paccessor_decl(1, symbol("head"), T), + paccessor_decl * as[2] = { mk_paccessor_decl(1, symbol("head"), T), mk_paccessor_decl(1, symbol("tail"), ListT) }; pconstructor_decl * cs[2] = { mk_pconstructor_decl(1, symbol("nil"), symbol("is-nil"), 0, 0), mk_pconstructor_decl(1, symbol("insert"), symbol("is-insert"), 2, as) }; @@ -851,8 +854,8 @@ psort * pdecl_manager::mk_psort_var(unsigned num_params, unsigned vidx) { paccessor_decl * pdecl_manager::mk_paccessor_decl(unsigned num_params, symbol const & s, ptype const & p) { return new (a().allocate(sizeof(paccessor_decl))) paccessor_decl(m_id_gen.mk(), num_params, *this, s, p); } - -pconstructor_decl * pdecl_manager::mk_pconstructor_decl(unsigned num_params, + +pconstructor_decl * pdecl_manager::mk_pconstructor_decl(unsigned num_params, symbol const & s, symbol const & r, unsigned num, paccessor_decl * const * as) { return new (a().allocate(sizeof(pconstructor_decl))) pconstructor_decl(m_id_gen.mk(), num_params, *this, s, r, num, as); @@ -901,9 +904,9 @@ sort * pdecl_manager::instantiate(psort * p, unsigned num, sort * const * args) void pdecl_manager::del_decl_core(pdecl * p) { - TRACE("pdecl_manager", + TRACE("pdecl_manager", tout << "del_decl_core:\n"; - if (p->is_psort()) static_cast(p)->display(tout); + if (p->is_psort()) static_cast(p)->display(tout); else static_cast(p)->display(tout); tout << "\n";); size_t sz = p->obj_size(); @@ -921,7 +924,7 @@ void pdecl_manager::del_decl(pdecl * p) { else m_table.erase(_p); } - del_decl_core(p); + del_decl_core(p); } void pdecl_manager::del_decls() { diff --git a/src/cmd_context/pdecl.h b/src/cmd_context/pdecl.h index 2dfbb93ae..a32a42413 100644 --- a/src/cmd_context/pdecl.h +++ b/src/cmd_context/pdecl.h @@ -86,10 +86,13 @@ typedef ptr_hashtable psort_table; #define PSORT_DECL_VAR_PARAMS UINT_MAX +typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN } psort_decl_kind; + class psort_decl : public pdecl { protected: friend class pdecl_manager; symbol m_name; + psort_decl_kind m_psort_kind; psort_inst_cache * m_inst_cache; void cache(pdecl_manager & m, sort * const * s, sort * r); sort * find(sort * const * s); @@ -105,6 +108,8 @@ public: bool has_var_params() const { return m_num_params == PSORT_DECL_VAR_PARAMS; } symbol const & get_name() const { return m_name; } virtual void reset_cache(pdecl_manager& m); + bool is_user_decl() const { return m_psort_kind == PSORT_USER; } + bool is_builtin_decl() const { return m_psort_kind == PSORT_BUILTIN; } }; class psort_user_decl : public psort_decl { @@ -209,7 +214,7 @@ class pconstructor_decl : public pdecl { symbol m_name; symbol m_recogniser_name; ptr_vector m_accessors; - pconstructor_decl(unsigned id, unsigned num_params, pdecl_manager & m, + pconstructor_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, symbol const & r, unsigned num_accessors, paccessor_decl * const * accessors); virtual void finalize(pdecl_manager & m); virtual size_t obj_size() const { return sizeof(pconstructor_decl); } @@ -229,7 +234,7 @@ class pdatatype_decl : public psort_decl { friend class pdatatypes_decl; ptr_vector m_constructors; pdatatypes_decl * m_parent; - pdatatype_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, + pdatatype_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, unsigned num_constructors, pconstructor_decl * const * constructors); virtual void finalize(pdecl_manager & m); virtual size_t obj_size() const { return sizeof(pdatatype_decl); } @@ -282,7 +287,7 @@ class pdecl_manager { struct indexed_sort_info; obj_map m_sort2info; // for pretty printing sorts - + void init_list(); void del_decl_core(pdecl * p); void del_decl(pdecl * p); @@ -296,7 +301,7 @@ public: small_object_allocator & a() const { return m_allocator; } family_id get_datatype_fid() const { return m_datatype_fid; } void set_new_datatype_eh(new_datatype_eh * eh) { m_new_dt_eh = eh; } - psort * mk_psort_cnst(sort * s); + psort * mk_psort_cnst(sort * s); psort * mk_psort_var(unsigned num_params, unsigned vidx); psort * mk_psort_app(unsigned num_params, psort_decl * d, unsigned num_args, psort * const * args); psort * mk_psort_app(psort_decl * d); diff --git a/src/model/model_params.pyg b/src/model/model_params.pyg index 14e83952c..58337e863 100644 --- a/src/model/model_params.pyg +++ b/src/model/model_params.pyg @@ -1,8 +1,9 @@ -def_module_params('model', +def_module_params('model', export=True, params=(('partial', BOOL, False, 'enable/disable partial function interpretations'), ('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, 'enable/disable model completion'), )) From d61df6b91f1679a17978eb04a0e085422448f84c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 30 Aug 2017 20:35:31 +0100 Subject: [PATCH 230/488] Model completion bug fix --- src/cmd_context/cmd_context.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index acbdc0bcf..aa2bb0554 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1701,9 +1701,14 @@ void cmd_context::complete_model() { func_decl * f = v.get_entry(i); if (!md->has_interpretation(f)) { sort * range = f->get_range(); - func_interp * fi = alloc(func_interp, m(), f->get_arity()); - fi->set_else(m().get_some_value(range)); - md->register_decl(f, fi); + expr * some_val = m().get_some_value(range); + if (f->get_arity() > 0) { + func_interp * fi = alloc(func_interp, m(), f->get_arity()); + fi->set_else(some_val); + md->register_decl(f, fi); + } + else + md->register_decl(f, some_val); } } } From 009e94d18821ed3723f1db681ca032aae086ca0d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 30 Aug 2017 14:00:01 -0700 Subject: [PATCH 231/488] update to theory_seq following examples from PJLJ Signed-off-by: Nikolaj Bjorner --- src/ast/expr_substitution.h | 1 + src/ast/pattern/pattern_inference.cpp | 637 +----------------------- src/ast/rewriter/seq_rewriter.cpp | 18 +- src/math/automata/automaton.h | 10 + src/smt/smt_quantifier.cpp | 26 +- src/smt/theory_seq.cpp | 79 ++- src/smt/theory_seq.h | 2 + src/tactic/core/dom_simplify_tactic.cpp | 116 ++++- src/tactic/core/dom_simplify_tactic.h | 31 ++ 9 files changed, 213 insertions(+), 707 deletions(-) diff --git a/src/ast/expr_substitution.h b/src/ast/expr_substitution.h index 924481dd8..d360356eb 100644 --- a/src/ast/expr_substitution.h +++ b/src/ast/expr_substitution.h @@ -79,6 +79,7 @@ public: } } bool empty() const { return m_subst.empty(); } + expr* find(expr * e) { proof* pr; expr* d = 0; if (find(e, d, pr)) return d; else return e; } bool find(expr * s, expr * & def, proof * & def_pr) { return m_subst.find(s, def, def_pr); } bool find(expr * s, expr * & def, proof * & def_pr, expr_dependency * & def_dep) { return m_subst.find(s, def, def_pr, def_dep); } bool contains(expr * s) { return m_subst.contains(s); } diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index dfeb29ffe..6a91dd85e 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -97,641 +97,6 @@ static void dump_app_vector(std::ostream & out, ptr_vector const & v, ast_m } #endif -#if 0 -pattern_inference_old::pattern_inference_old(ast_manager & m, pattern_inference_params & params): - simplifier(m), - m_params(params), - m_bfid(m.get_basic_family_id()), - m_afid(m.mk_family_id("arith")), - m_le(m), - m_nested_arith_only(true), - m_block_loop_patterns(params.m_pi_block_loop_patterns), - m_candidates(m), - m_pattern_weight_lt(m_candidates_info), - m_collect(m, *this), - m_contains_subpattern(*this), - m_database(m) { - if (params.m_pi_arith == AP_NO) - register_forbidden_family(m_afid); - enable_ac_support(false); -} - -void pattern_inference_old::collect::operator()(expr * n, unsigned num_bindings) { - SASSERT(m_info.empty()); - SASSERT(m_todo.empty()); - SASSERT(m_cache.empty()); - m_num_bindings = num_bindings; - m_todo.push_back(entry(n, 0)); - while (!m_todo.empty()) { - entry & e = m_todo.back(); - n = e.m_node; - unsigned delta = e.m_delta; - TRACE("collect", tout << "processing: " << n->get_id() << " " << delta << " kind: " << n->get_kind() << "\n";); - TRACE("collect_info", tout << mk_pp(n, m) << "\n";); - if (visit_children(n, delta)) { - m_todo.pop_back(); - save_candidate(n, delta); - } - } - reset(); -} - -inline void pattern_inference_old::collect::visit(expr * n, unsigned delta, bool & visited) { - entry e(n, delta); - if (!m_cache.contains(e)) { - m_todo.push_back(e); - visited = false; - } -} - -bool pattern_inference_old::collect::visit_children(expr * n, unsigned delta) { - bool visited = true; - unsigned i; - switch (n->get_kind()) { - case AST_APP: - i = to_app(n)->get_num_args(); - while (i > 0) { - --i; - visit(to_app(n)->get_arg(i), delta, visited); - } - break; - case AST_QUANTIFIER: - visit(to_quantifier(n)->get_expr(), delta + to_quantifier(n)->get_num_decls(), visited); - break; - default: - break; - } - return visited; -} - -inline void pattern_inference_old::collect::save(expr * n, unsigned delta, info * i) { - m_cache.insert(entry(n, delta), i); - if (i != 0) - m_info.push_back(i); -} - -void pattern_inference_old::collect::save_candidate(expr * n, unsigned delta) { - switch (n->get_kind()) { - case AST_VAR: { - unsigned idx = to_var(n)->get_idx(); - if (idx >= delta) { - idx = idx - delta; - uint_set free_vars; - if (idx < m_num_bindings) - free_vars.insert(idx); - info * i = 0; - if (delta == 0) - i = alloc(info, m, n, free_vars, 1); - else - i = alloc(info, m, m.mk_var(idx, to_var(n)->get_sort()), free_vars, 1); - save(n, delta, i); - } - else { - save(n, delta, 0); - } - return; - } - case AST_APP: { - app * c = to_app(n); - func_decl * decl = c->get_decl(); - if (m_owner.is_forbidden(c)) { - save(n, delta, 0); - return; - } - - if (c->get_num_args() == 0) { - save(n, delta, alloc(info, m, n, uint_set(), 1)); - return; - } - - ptr_buffer buffer; - bool changed = false; // false if none of the children is mapped to a node different from itself. - uint_set free_vars; - unsigned size = 1; - unsigned num = c->get_num_args(); - for (unsigned i = 0; i < num; i++) { - expr * child = c->get_arg(i); - info * child_info = 0; -#ifdef Z3DEBUG - bool found = -#endif - m_cache.find(entry(child, delta), child_info); - SASSERT(found); - if (child_info == 0) { - save(n, delta, 0); - return; - } - buffer.push_back(child_info->m_node.get()); - free_vars |= child_info->m_free_vars; - size += child_info->m_size; - if (child != child_info->m_node.get()) - changed = true; - } - - app * new_node = 0; - if (changed) - new_node = m.mk_app(decl, buffer.size(), buffer.c_ptr()); - else - new_node = to_app(n); - save(n, delta, alloc(info, m, new_node, free_vars, size)); - // Remark: arithmetic patterns are only used if they are nested inside other terms. - // That is, we never consider x + 1 as pattern. On the other hand, f(x+1) can be a pattern - // if arithmetic is not in the forbidden list. - // - // Remark: The rule above has an exception. The operators (div, idiv, mod) are allowed to be - // used as patterns even when they are not nested in other terms. The motivation is that - // Z3 currently doesn't implement them (i.e., they are uninterpreted). So, some users add axioms - // stating properties about these operators. - family_id fid = c->get_family_id(); - decl_kind k = c->get_decl_kind(); - if (!free_vars.empty() && - (fid != m_afid || (fid == m_afid && !m_owner.m_nested_arith_only && (k == OP_DIV || k == OP_IDIV || k == OP_MOD || k == OP_REM || k == OP_MUL)))) { - TRACE("pattern_inference", tout << "potential candidate: \n" << mk_pp(new_node, m) << "\n";); - m_owner.add_candidate(new_node, free_vars, size); - } - return; - } - default: - save(n, delta, 0); - return; - } -} - - -void pattern_inference_old::collect::reset() { - m_cache.reset(); - std::for_each(m_info.begin(), m_info.end(), delete_proc()); - m_info.reset(); - SASSERT(m_todo.empty()); -} - -void pattern_inference_old::add_candidate(app * n, uint_set const & free_vars, unsigned size) { - for (unsigned i = 0; i < m_num_no_patterns; i++) { - if (n == m_no_patterns[i]) - return; - } - - if (!m_candidates_info.contains(n)) { - m_candidates_info.insert(n, info(free_vars, size)); - m_candidates.push_back(n); - } -} - - -/** - \brief Copy the non-looping patterns in m_candidates to result when m_params.m_pi_block_loop_patterns = true. - Otherwise, copy m_candidates to result. -*/ -void pattern_inference_old::filter_looping_patterns(ptr_vector & result) { - unsigned num = m_candidates.size(); - for (unsigned i1 = 0; i1 < num; i1++) { - app * n1 = m_candidates.get(i1); - expr2info::obj_map_entry * e1 = m_candidates_info.find_core(n1); - SASSERT(e1); - uint_set const & s1 = e1->get_data().m_value.m_free_vars; - if (m_block_loop_patterns) { - bool smaller = false; - for (unsigned i2 = 0; i2 < num; i2++) { - if (i1 != i2) { - app * n2 = m_candidates.get(i2); - expr2info::obj_map_entry * e2 = m_candidates_info.find_core(n2); - if (e2) { - uint_set const & s2 = e2->get_data().m_value.m_free_vars; - // Remark: the comparison operator only makes sense if both AST nodes - // contain the same number of variables. - // Example: - // (f X Y) <: (f (g X Z W) Y) - if (s1 == s2 && m_le(m_num_bindings, n1, n2) && !m_le(m_num_bindings, n2, n1)) { - smaller = true; - break; - } - } - } - } - if (!smaller) - result.push_back(n1); - else - m_candidates_info.erase(n1); - } - else { - result.push_back(n1); - } - } -} - - - -inline void pattern_inference_old::contains_subpattern::save(expr * n) { - unsigned id = n->get_id(); - m_already_processed.assure_domain(id); - if (!m_already_processed.contains(id)) { - m_todo.push_back(n); - m_already_processed.insert(id); - } -} - -bool pattern_inference_old::contains_subpattern::operator()(expr * n) { - m_already_processed.reset(); - m_todo.reset(); - expr2info::obj_map_entry * _e = m_owner.m_candidates_info.find_core(n); - SASSERT(_e); - uint_set const & s1 = _e->get_data().m_value.m_free_vars; - save(n); - unsigned num; - while (!m_todo.empty()) { - expr * curr = m_todo.back(); - m_todo.pop_back(); - switch (curr->get_kind()) { - case AST_APP: - if (curr != n) { - expr2info::obj_map_entry * e = m_owner.m_candidates_info.find_core(curr); - if (e) { - uint_set const & s2 = e->get_data().m_value.m_free_vars; - SASSERT(s2.subset_of(s1)); - if (s1 == s2) { - TRACE("pattern_inference", tout << mk_pp(n, m_owner.m) << "\nis bigger than\n" << mk_pp(to_app(curr), m_owner.m) << "\n";); - return true; - } - } - } - num = to_app(curr)->get_num_args(); - for (unsigned i = 0; i < num; i++) - save(to_app(curr)->get_arg(i)); - break; - case AST_VAR: - break; - default: - UNREACHABLE(); - } - } - return false; -} - -/** - Return true if n contains a direct/indirect child that is also a - pattern, and contains the same number of free variables. -*/ -inline bool pattern_inference_old::contains_subpattern(expr * n) { - return m_contains_subpattern(n); -} - -/** - \brief Copy a pattern p in patterns to result, if there is no - direct/indirect child of p in patterns which contains the same set - of variables. - - Remark: Every pattern p in patterns is also a member of - m_pattern_map. -*/ -void pattern_inference_old::filter_bigger_patterns(ptr_vector const & patterns, ptr_vector & result) { - for (app * curr : patterns) { - if (!contains_subpattern(curr)) - result.push_back(curr); - } -} - - -bool pattern_inference_old::pattern_weight_lt::operator()(expr * n1, expr * n2) const { - expr2info::obj_map_entry * e1 = m_candidates_info.find_core(n1); - expr2info::obj_map_entry * e2 = m_candidates_info.find_core(n2); - SASSERT(e1 != 0); - SASSERT(e2 != 0); - info const & i1 = e1->get_data().m_value; - info const & i2 = e2->get_data().m_value; - unsigned num_free_vars1 = i1.m_free_vars.num_elems(); - unsigned num_free_vars2 = i2.m_free_vars.num_elems(); - return num_free_vars1 > num_free_vars2 || (num_free_vars1 == num_free_vars2 && i1.m_size < i2.m_size); -} - -/** - \brief Create unary patterns (single expressions that contain all - bound variables). If a candidate does not contain all bound - variables, then it is copied to remaining_candidate_patterns. The - new patterns are stored in result. -*/ -void pattern_inference_old::candidates2unary_patterns(ptr_vector const & candidate_patterns, - ptr_vector & remaining_candidate_patterns, - app_ref_buffer & result) { - for (app * candidate : candidate_patterns) { - expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate); - info const & i = e->get_data().m_value; - if (i.m_free_vars.num_elems() == m_num_bindings) { - app * new_pattern = m.mk_pattern(candidate); - result.push_back(new_pattern); - } - else { - remaining_candidate_patterns.push_back(candidate); - } - } -} - -// TODO: this code is too inefficient when the number of candidate -// patterns is too big. -// HACK: limit the number of case-splits: -#define MAX_SPLITS 32 - -void pattern_inference_old::candidates2multi_patterns(unsigned max_num_patterns, - ptr_vector const & candidate_patterns, - app_ref_buffer & result) { - SASSERT(!candidate_patterns.empty()); - m_pre_patterns.push_back(alloc(pre_pattern)); - unsigned sz = candidate_patterns.size(); - unsigned num_splits = 0; - for (unsigned j = 0; j < m_pre_patterns.size(); j++) { - pre_pattern * curr = m_pre_patterns[j]; - if (curr->m_free_vars.num_elems() == m_num_bindings) { - app * new_pattern = m.mk_pattern(curr->m_exprs.size(), curr->m_exprs.c_ptr()); - result.push_back(new_pattern); - if (result.size() >= max_num_patterns) - return; - } - else if (curr->m_idx < sz) { - app * n = candidate_patterns[curr->m_idx]; - expr2info::obj_map_entry * e = m_candidates_info.find_core(n); - uint_set const & s = e->get_data().m_value.m_free_vars; - if (!s.subset_of(curr->m_free_vars)) { - pre_pattern * new_p = alloc(pre_pattern,*curr); - new_p->m_exprs.push_back(n); - new_p->m_free_vars |= s; - new_p->m_idx++; - m_pre_patterns.push_back(new_p); - - if (num_splits < MAX_SPLITS) { - m_pre_patterns[j] = 0; - curr->m_idx++; - m_pre_patterns.push_back(curr); - num_splits++; - } - } - else { - m_pre_patterns[j] = 0; - curr->m_idx++; - m_pre_patterns.push_back(curr); - } - } - TRACE("pattern_inference", tout << "m_pre_patterns.size(): " << m_pre_patterns.size() << - "\nnum_splits: " << num_splits << "\n";); - } -} - -void pattern_inference_old::reset_pre_patterns() { - std::for_each(m_pre_patterns.begin(), m_pre_patterns.end(), delete_proc()); - m_pre_patterns.reset(); -} - - -bool pattern_inference_old::is_forbidden(app * n) const { - func_decl const * decl = n->get_decl(); - if (is_ground(n)) - return false; - // Remark: skolem constants should not be used in patterns, since they do not - // occur outside of the quantifier. That is, Z3 will never match this kind of - // pattern. - if (m_params.m_pi_avoid_skolems && decl->is_skolem()) { - CTRACE("pattern_inference_skolem", decl->is_skolem(), tout << "ignoring: " << mk_pp(n, m) << "\n";); - return true; - } - if (is_forbidden(decl)) - return true; - return false; -} - -bool pattern_inference_old::has_preferred_patterns(ptr_vector & candidate_patterns, app_ref_buffer & result) { - if (m_preferred.empty()) - return false; - bool found = false; - for (app * candidate : candidate_patterns) { - if (m_preferred.contains(to_app(candidate)->get_decl())) { - expr2info::obj_map_entry * e = m_candidates_info.find_core(candidate); - info const & i = e->get_data().m_value; - if (i.m_free_vars.num_elems() == m_num_bindings) { - TRACE("pattern_inference", tout << "found preferred pattern:\n" << mk_pp(candidate, m) << "\n";); - app * p = m.mk_pattern(candidate); - result.push_back(p); - found = true; - } - } - } - return found; -} - -void pattern_inference_old::mk_patterns(unsigned num_bindings, - expr * n, - unsigned num_no_patterns, - expr * const * no_patterns, - app_ref_buffer & result) { - m_num_bindings = num_bindings; - m_num_no_patterns = num_no_patterns; - m_no_patterns = no_patterns; - - m_collect(n, num_bindings); - - TRACE("pattern_inference", - tout << mk_pp(n, m); - tout << "\ncandidates:\n"; - unsigned num = m_candidates.size(); - for (unsigned i = 0; i < num; i++) { - tout << mk_pp(m_candidates.get(i), m) << "\n"; - }); - - if (!m_candidates.empty()) { - m_tmp1.reset(); - filter_looping_patterns(m_tmp1); - TRACE("pattern_inference", - tout << "candidates after removing looping-patterns:\n"; - dump_app_vector(tout, m_tmp1, m);); - SASSERT(!m_tmp1.empty()); - if (!has_preferred_patterns(m_tmp1, result)) { - // continue if there are no preferred patterns - m_tmp2.reset(); - filter_bigger_patterns(m_tmp1, m_tmp2); - SASSERT(!m_tmp2.empty()); - TRACE("pattern_inference", - tout << "candidates after removing bigger patterns:\n"; - dump_app_vector(tout, m_tmp2, m);); - m_tmp1.reset(); - candidates2unary_patterns(m_tmp2, m_tmp1, result); - unsigned num_extra_multi_patterns = m_params.m_pi_max_multi_patterns; - if (result.empty()) - num_extra_multi_patterns++; - if (num_extra_multi_patterns > 0 && !m_tmp1.empty()) { - // m_pattern_weight_lt is not a total order - std::stable_sort(m_tmp1.begin(), m_tmp1.end(), m_pattern_weight_lt); - TRACE("pattern_inference", - tout << "candidates after sorting:\n"; - dump_app_vector(tout, m_tmp1, m);); - candidates2multi_patterns(num_extra_multi_patterns, m_tmp1, result); - } - } - } - - reset_pre_patterns(); - m_candidates_info.reset(); - m_candidates.reset(); -} - - -void pattern_inference_old::reduce1_quantifier(quantifier * q) { - TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";); - if (!q->is_forall()) { - simplifier::reduce1_quantifier(q); - return; - } - - int weight = q->get_weight(); - - if (m_params.m_pi_use_database) { - m_database.initialize(g_pattern_database); - app_ref_vector new_patterns(m); - unsigned new_weight; - if (m_database.match_quantifier(q, new_patterns, new_weight)) { -#ifdef Z3DEBUG - for (unsigned i = 0; i < new_patterns.size(); i++) { SASSERT(is_well_sorted(m, new_patterns.get(i))); } -#endif - quantifier_ref new_q(m); - if (q->get_num_patterns() > 0) { - // just update the weight... - TRACE("pattern_inference", tout << "updating weight to: " << new_weight << "\n" << mk_pp(q, m) << "\n";); - new_q = m.update_quantifier_weight(q, new_weight); - } - else { - quantifier_ref tmp(m); - tmp = m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), q->get_expr()); - new_q = m.update_quantifier_weight(tmp, new_weight); - TRACE("pattern_inference", tout << "found patterns in database, weight: " << new_weight << "\n" << mk_pp(new_q, m) << "\n";); - } - proof * pr = 0; - if (m.fine_grain_proofs()) - pr = m.mk_rewrite(q, new_q); - cache_result(q, new_q, pr); - return; - } - } - - if (q->get_num_patterns() > 0) { - simplifier::reduce1_quantifier(q); - return; - } - - if (m_params.m_pi_nopat_weight >= 0) - weight = m_params.m_pi_nopat_weight; - - SASSERT(q->get_num_patterns() == 0); - expr * new_body; - proof * new_body_pr; - get_cached(q->get_expr(), new_body, new_body_pr); - - ptr_buffer new_no_patterns; - unsigned num_no_patterns = q->get_num_no_patterns(); - for (unsigned i = 0; i < num_no_patterns; i++) { - expr * new_pattern; - proof * new_pattern_pr; - get_cached(q->get_no_pattern(i), new_pattern, new_pattern_pr); - new_no_patterns.push_back(new_pattern); - } - - app_ref_buffer new_patterns(m); - - if (m_params.m_pi_arith == AP_CONSERVATIVE) - m_forbidden.push_back(m_afid); - - mk_patterns(q->get_num_decls(), new_body, new_no_patterns.size(), new_no_patterns.c_ptr(), new_patterns); - - if (new_patterns.empty() && !new_no_patterns.empty()) { - if (new_patterns.empty()) { - mk_patterns(q->get_num_decls(), new_body, 0, 0, new_patterns); - if (m_params.m_pi_warnings && !new_patterns.empty()) { - warning_msg("ignoring nopats annotation because Z3 couldn't find any other pattern (quantifier id: %s)", q->get_qid().str().c_str()); - } - } - } - - if (m_params.m_pi_arith == AP_CONSERVATIVE) { - m_forbidden.pop_back(); - if (new_patterns.empty()) { - flet l1(m_block_loop_patterns, false); // allow looping patterns - mk_patterns(q->get_num_decls(), new_body, new_no_patterns.size(), new_no_patterns.c_ptr(), new_patterns); - if (!new_patterns.empty()) { - weight = std::max(weight, static_cast(m_params.m_pi_arith_weight)); - if (m_params.m_pi_warnings) { - warning_msg("using arith. in pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_ARITH_WEIGHT=).", - q->get_qid().str().c_str(), weight); - } - } - } - } - - if (m_params.m_pi_arith != AP_NO && new_patterns.empty()) { - if (new_patterns.empty()) { - flet l1(m_nested_arith_only, false); // try to find a non-nested arith pattern - flet l2(m_block_loop_patterns, false); // allow looping patterns - mk_patterns(q->get_num_decls(), new_body, new_no_patterns.size(), new_no_patterns.c_ptr(), new_patterns); - if (!new_patterns.empty()) { - weight = std::max(weight, static_cast(m_params.m_pi_non_nested_arith_weight)); - if (m_params.m_pi_warnings) { - warning_msg("using non nested arith. pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_NON_NESTED_ARITH_WEIGHT=).", - q->get_qid().str().c_str(), weight); - } - // verbose_stream() << mk_pp(q, m) << "\n"; - } - } - } - - quantifier_ref new_q(m); - new_q = m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_body); - if (weight != q->get_weight()) - new_q = m.update_quantifier_weight(new_q, weight); - proof_ref pr(m); - if (m.fine_grain_proofs()) { - if (new_body_pr == 0) - new_body_pr = m.mk_reflexivity(new_body); - pr = m.mk_quant_intro(q, new_q, new_body_pr); - } - - if (new_patterns.empty() && m_params.m_pi_pull_quantifiers) { - pull_quant pull(m); - expr_ref new_expr(m); - proof_ref new_pr(m); - pull(new_q, new_expr, new_pr); - quantifier * new_new_q = to_quantifier(new_expr); - if (new_new_q != new_q) { - mk_patterns(new_new_q->get_num_decls(), new_new_q->get_expr(), 0, 0, new_patterns); - if (!new_patterns.empty()) { - if (m_params.m_pi_warnings) { - warning_msg("pulled nested quantifier to be able to find an useable pattern (quantifier id: %s)", q->get_qid().str().c_str()); - } - new_q = m.update_quantifier(new_new_q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_new_q->get_expr()); - if (m.fine_grain_proofs()) { - pr = m.mk_transitivity(pr, new_pr); - pr = m.mk_transitivity(pr, m.mk_quant_intro(new_new_q, new_q, m.mk_reflexivity(new_q->get_expr()))); - } - TRACE("pattern_inference", tout << "pulled quantifier:\n" << mk_pp(new_q, m) << "\n";); - } - } - } - - if (new_patterns.empty()) { - if (m_params.m_pi_warnings) { - warning_msg("failed to find a pattern for quantifier (quantifier id: %s)", q->get_qid().str().c_str()); - } - TRACE("pi_failed", tout << mk_pp(q, m) << "\n";); - } - - if (new_patterns.empty() && new_body == q->get_expr()) { - cache_result(q, q, 0); - return; - } - - IF_IVERBOSE(10, - verbose_stream() << "(smt.inferred-patterns :qid " << q->get_qid() << "\n"; - for (unsigned i = 0; i < new_patterns.size(); i++) - verbose_stream() << " " << mk_ismt2_pp(new_patterns[i], m, 2) << "\n"; - verbose_stream() << ")\n"; ); - - cache_result(q, new_q, pr); -} - -#endif #include "ast/pattern/database.h" @@ -881,7 +246,7 @@ void pattern_inference_cfg::collect::save_candidate(expr * n, unsigned delta) { // stating properties about these operators. family_id fid = c->get_family_id(); decl_kind k = c->get_decl_kind(); - if (!free_vars.empty() && + if (!free_vars.empty() && (fid != m_afid || (fid == m_afid && !m_owner.m_nested_arith_only && (k == OP_DIV || k == OP_IDIV || k == OP_MOD || k == OP_REM || k == OP_MUL)))) { TRACE("pattern_inference", tout << "potential candidate: \n" << mk_pp(new_node, m) << "\n";); m_owner.add_candidate(new_node, free_vars, size); diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 70eddcea1..997d5671e 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -26,6 +26,7 @@ Notes: #include "math/automata/automaton.h" #include "ast/well_sorted.h" #include "ast/rewriter/var_subst.h" +#include "ast/rewriter/bool_rewriter.h" #include "math/automata/symbolic_automata_def.h" @@ -102,7 +103,6 @@ public: return sym_expr::mk_pred(fml, x->get_sort()); } } - sort* s = x->get_sort(); if (m.is_bool(s)) s = y->get_sort(); var_ref v(m.mk_var(0, s), m); @@ -112,7 +112,10 @@ public: return y; } if (m.is_true(fml2)) return x; - expr_ref fml(m.mk_and(fml1, fml2), m); + if (fml1 == fml2) return x; + bool_rewriter br(m); + expr_ref fml(m); + br.mk_and(fml1, fml2, fml); return sym_expr::mk_pred(fml, x->get_sort()); } virtual T mk_or(T x, T y) { @@ -120,12 +123,15 @@ public: x->get_char() == y->get_char()) { return x; } + if (x == y) return x; var_ref v(m.mk_var(0, x->get_sort()), m); expr_ref fml1 = x->accept(v); expr_ref fml2 = y->accept(v); if (m.is_false(fml1)) return y; if (m.is_false(fml2)) return x; - expr_ref fml(m.mk_or(fml1, fml2), m); + bool_rewriter br(m); + expr_ref fml(m); + br.mk_or(fml1, fml2, fml); return sym_expr::mk_pred(fml, x->get_sort()); } @@ -197,10 +203,10 @@ void re2automaton::set_solver(expr_solver* solver) { eautomaton* re2automaton::operator()(expr* e) { eautomaton* r = re2aut(e); - if (r) { - display_expr1 disp(m); + if (r) { r->compress(); - TRACE("seq", r->display(tout, disp);); + bool_rewriter br(m); + TRACE("seq", display_expr1 disp(m); r->display(tout, disp);); } return r; } diff --git a/src/math/automata/automaton.h b/src/math/automata/automaton.h index 2f55d5cc2..12aa120b3 100644 --- a/src/math/automata/automaton.h +++ b/src/math/automata/automaton.h @@ -300,6 +300,16 @@ public: } } + bool is_sink_state(unsigned s) const { + if (is_final_state(s)) return false; + moves mvs; + get_moves_from(s, mvs); + for (move const& m : mvs) { + if (s != m.dst()) return false; + } + return true; + } + void add_init_to_final_states() { add_to_final_states(init()); } diff --git a/src/smt/smt_quantifier.cpp b/src/smt/smt_quantifier.cpp index 22004ee78..1d58e2bb3 100644 --- a/src/smt/smt_quantifier.cpp +++ b/src/smt/smt_quantifier.cpp @@ -208,10 +208,8 @@ namespace smt { IF_VERBOSE(10, verbose_stream() << "quick checking quantifiers (unsat)...\n";); quick_checker mc(m_context); bool result = true; - ptr_vector::const_iterator it = m_quantifiers.begin(); - ptr_vector::const_iterator end = m_quantifiers.end(); - for (; it != end; ++it) - if (check_quantifier(*it) && mc.instantiate_unsat(*it)) + for (quantifier* q : m_quantifiers) + if (check_quantifier(q) && mc.instantiate_unsat(q)) result = false; if (m_params.m_qi_quick_checker == MC_UNSAT || !result) { m_qi_queue.instantiate(); @@ -220,9 +218,8 @@ namespace smt { // MC_NO_SAT is too expensive (it creates too many irrelevant instances). // we should use MBQI=true instead. IF_VERBOSE(10, verbose_stream() << "quick checking quantifiers (not sat)...\n";); - it = m_quantifiers.begin(); - for (; it != end; ++it) - if (check_quantifier(*it) && mc.instantiate_not_sat(*it)) + for (quantifier* q : m_quantifiers) + if (check_quantifier(q) && mc.instantiate_not_sat(q)) result = false; m_qi_queue.instantiate(); return result; @@ -493,10 +490,11 @@ namespace smt { virtual void assign_eh(quantifier * q) { m_active = true; + ast_manager& m = m_context->get_manager(); if (!m_fparams->m_ematching) { return; } - if (false && m_context->get_manager().is_rec_fun_def(q) && mbqi_enabled(q)) { + if (false && m.is_rec_fun_def(q) && mbqi_enabled(q)) { return; } bool has_unary_pattern = false; @@ -513,16 +511,20 @@ namespace smt { num_eager_multi_patterns++; for (unsigned i = 0, j = 0; i < num_patterns; i++) { app * mp = to_app(q->get_pattern(i)); - SASSERT(m_context->get_manager().is_pattern(mp)); + SASSERT(m.is_pattern(mp)); bool unary = (mp->get_num_args() == 1); - if (!unary && j >= num_eager_multi_patterns) { - TRACE("quantifier", tout << "delaying (too many multipatterns):\n" << mk_ismt2_pp(mp, m_context->get_manager()) << "\n" + if (m.is_rec_fun_def(q) && i > 0) { + // add only the first pattern + TRACE("quantifier", tout << "skip recursive function body " << mk_ismt2_pp(mp, m) << "\n";); + } + else if (!unary && j >= num_eager_multi_patterns) { + TRACE("quantifier", tout << "delaying (too many multipatterns):\n" << mk_ismt2_pp(mp, m) << "\n" << "j: " << j << " unary: " << unary << " m_params.m_qi_max_eager_multipatterns: " << m_fparams->m_qi_max_eager_multipatterns << " num_eager_multi_patterns: " << num_eager_multi_patterns << "\n";); m_lazy_mam->add_pattern(q, mp); } else { - TRACE("quantifier", tout << "adding:\n" << mk_ismt2_pp(mp, m_context->get_manager()) << "\n";); + TRACE("quantifier", tout << "adding:\n" << mk_ismt2_pp(mp, m) << "\n";); m_mam->add_pattern(q, mp); } if (!unary) diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 461e9e8ee..44ce804e7 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -151,9 +151,8 @@ void theory_seq::solution_map::pop_scope(unsigned num_scopes) { } void theory_seq::solution_map::display(std::ostream& out) const { - eqdep_map_t::iterator it = m_map.begin(), end = m_map.end(); - for (; it != end; ++it) { - out << mk_pp(it->m_key, m) << " |-> " << mk_pp(it->m_value.first, m) << "\n"; + for (auto const& kv : m_map) { + out << mk_pp(kv.m_key, m) << " |-> " << mk_pp(kv.m_value.first, m) << "\n"; } } @@ -187,9 +186,8 @@ void theory_seq::exclusion_table::pop_scope(unsigned num_scopes) { } void theory_seq::exclusion_table::display(std::ostream& out) const { - table_t::iterator it = m_table.begin(), end = m_table.end(); - for (; it != end; ++it) { - out << mk_pp(it->first, m) << " != " << mk_pp(it->second, m) << "\n"; + for (auto const& kv : m_table) { + out << mk_pp(kv.first, m) << " != " << mk_pp(kv.second, m) << "\n"; } } @@ -214,6 +212,7 @@ theory_seq::theory_seq(ast_manager& m): m_trail_stack(*this), m_ls(m), m_rs(m), m_lhs(m), m_rhs(m), + m_res(m), m_atoms_qhead(0), m_new_solution(false), m_new_propagation(false), @@ -937,18 +936,14 @@ bool theory_seq::check_length_coherence0(expr* e) { bool theory_seq::check_length_coherence() { - obj_hashtable::iterator it = m_length.begin(), end = m_length.end(); #if 1 - for (; it != end; ++it) { - expr* e = *it; + for (expr* e : m_length) { if (check_length_coherence0(e)) { return true; } } - it = m_length.begin(); #endif - for (; it != end; ++it) { - expr* e = *it; + for (expr* e : m_length) { if (check_length_coherence(e)) { return true; } @@ -957,10 +952,9 @@ bool theory_seq::check_length_coherence() { } bool theory_seq::fixed_length() { - obj_hashtable::iterator it = m_length.begin(), end = m_length.end(); bool found = false; - for (; it != end; ++it) { - if (fixed_length(*it)) { + for (expr* e : m_length) { + if (fixed_length(e)) { found = true; } } @@ -2502,12 +2496,11 @@ void theory_seq::display(std::ostream & out) const { } if (!m_re2aut.empty()) { out << "Regex\n"; - obj_map::iterator it = m_re2aut.begin(), end = m_re2aut.end(); - for (; it != end; ++it) { - out << mk_pp(it->m_key, m) << "\n"; + for (auto const& kv : m_re2aut) { + out << mk_pp(kv.m_key, m) << "\n"; display_expr disp(m); - if (it->m_value) { - it->m_value->display(out, disp); + if (kv.m_value) { + kv.m_value->display(out, disp); } } } @@ -2521,9 +2514,7 @@ void theory_seq::display(std::ostream & out) const { } if (!m_length.empty()) { - obj_hashtable::iterator it = m_length.begin(), end = m_length.end(); - for (; it != end; ++it) { - expr* e = *it; + for (expr* e : m_length) { rational lo(-1), hi(-1); lower_bound(e, lo); upper_bound(e, hi); @@ -2636,6 +2627,12 @@ void theory_seq::collect_statistics(::statistics & st) const { st.update("seq int.to.str", m_stats.m_int_string); } +void theory_seq::init_search_eh() { + m_re2aut.reset(); + m_res.reset(); + m_automata.reset(); +} + void theory_seq::init_model(expr_ref_vector const& es) { expr_ref new_s(m); for (expr* e : es) { @@ -3397,7 +3394,6 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) { literal lit = ctx.get_literal(n); if (!is_true) { e3 = m_util.re.mk_complement(e2); - is_true = true; lit.neg(); } eautomaton* a = get_automaton(e3); @@ -3416,26 +3412,17 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) { unsigned_vector states; a->get_epsilon_closure(a->init(), states); literal_vector lits; - if (is_true) { - lits.push_back(~lit); - } + lits.push_back(~lit); + for (unsigned i = 0; i < states.size(); ++i) { - if (is_true) { - lits.push_back(mk_accept(e1, zero, e3, states[i])); - } - else { - literal nlit = ~lit; - propagate_lit(0, 1, &nlit, mk_reject(e1, zero, e3, states[i])); - } + lits.push_back(mk_accept(e1, zero, e3, states[i])); } - if (is_true) { - if (lits.size() == 2) { - propagate_lit(0, 1, &lit, lits[1]); - } - else { - TRACE("seq", ctx.display_literals_verbose(tout, lits); tout << "\n";); - ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr()); - } + if (lits.size() == 2) { + propagate_lit(0, 1, &lit, lits[1]); + } + else { + TRACE("seq", ctx.display_literals_verbose(tout, lits); tout << "\n";); + ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr()); } } @@ -4180,10 +4167,8 @@ eautomaton* theory_seq::get_automaton(expr* re) { TRACE("seq", result->display(tout, disp);); } m_automata.push_back(result); - m_trail_stack.push(push_back_vector >(m_automata)); - m_re2aut.insert(re, result); - m_trail_stack.push(insert_obj_map(m_re2aut, re)); + m_res.push_back(re); return result; } @@ -4264,6 +4249,10 @@ void theory_seq::propagate_acc_rej_length(literal lit, expr* e) { if (m_util.str.is_length(idx)) return; SASSERT(m_autil.is_numeral(idx)); SASSERT(get_context().get_assignment(lit) == l_true); + if (aut->is_sink_state(src)) { + propagate_lit(0, 1, &lit, false_literal); + return; + } bool is_final = aut->is_final_state(src); if (is_final == is_acc) { propagate_lit(0, 1, &lit, mk_literal(m_autil.mk_ge(m_util.str.mk_length(s), idx))); diff --git a/src/smt/theory_seq.h b/src/smt/theory_seq.h index b5a53e8e4..1f97697c2 100644 --- a/src/smt/theory_seq.h +++ b/src/smt/theory_seq.h @@ -328,6 +328,7 @@ namespace smt { // maintain automata with regular expressions. scoped_ptr_vector m_automata; obj_map m_re2aut; + expr_ref_vector m_res; // queue of asserted atoms ptr_vector m_atoms; @@ -361,6 +362,7 @@ namespace smt { virtual void collect_statistics(::statistics & st) const; virtual model_value_proc * mk_value(enode * n, model_generator & mg); virtual void init_model(model_generator & mg); + virtual void init_search_eh(); void init_model(expr_ref_vector const& es); // final check diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 21686fe64..595f8f7c6 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -115,8 +115,6 @@ void expr_dominators::extract_tree() { } } - - void expr_dominators::compile(expr * e) { reset(); m_root = e; @@ -130,7 +128,6 @@ void expr_dominators::compile(unsigned sz, expr * const* es) { compile(e); } - void expr_dominators::reset() { m_expr2post.reset(); m_post2expr.reset(); @@ -142,11 +139,8 @@ void expr_dominators::reset() { -// goes to header file: - - - -// implementation: +// ----------------------- +// dom_simplify_tactic tactic * dom_simplify_tactic::translate(ast_manager & m) { return alloc(dom_simplify_tactic, m, m_simplifier->translate(m), m_params); @@ -340,3 +334,109 @@ void dom_simplify_tactic::simplify_goal(goal& g) { } +// ---------------------- +// expr_substitution_simplifier + +bool expr_substitution_simplifier::assert_expr(expr * t, bool sign) { + expr* tt; + if (!sign) { + update_substitution(t, 0); + } + else if (m.is_not(t, tt)) { + update_substitution(tt, 0); + } + else { + expr_ref nt(m.mk_not(t), m); + update_substitution(nt, 0); + } + return true; +} + + +bool expr_substitution_simplifier::is_gt(expr* lhs, expr* rhs) { + if (lhs == rhs) { + return false; + } + if (m.is_value(rhs)) { + return true; + } + SASSERT(is_ground(lhs) && is_ground(rhs)); + if (depth(lhs) > depth(rhs)) { + return true; + } + if (depth(lhs) == depth(rhs) && is_app(lhs) && is_app(rhs)) { + app* l = to_app(lhs); + app* r = to_app(rhs); + if (l->get_decl()->get_id() != r->get_decl()->get_id()) { + return l->get_decl()->get_id() > r->get_decl()->get_id(); + } + if (l->get_num_args() != r->get_num_args()) { + return l->get_num_args() > r->get_num_args(); + } + for (unsigned i = 0; i < l->get_num_args(); ++i) { + if (l->get_arg(i) != r->get_arg(i)) { + return is_gt(l->get_arg(i), r->get_arg(i)); + } + } + UNREACHABLE(); + } + + return false; +} + +void expr_substitution_simplifier::update_substitution(expr* n, proof* pr) { + expr* lhs, *rhs, *n1; + if (is_ground(n) && (m.is_eq(n, lhs, rhs) || m.is_iff(n, lhs, rhs))) { + compute_depth(lhs); + compute_depth(rhs); + if (is_gt(lhs, rhs)) { + TRACE("propagate_values", tout << "insert " << mk_pp(lhs, m) << " -> " << mk_pp(rhs, m) << "\n";); + m_scoped_substitution.insert(lhs, rhs, pr); + return; + } + if (is_gt(rhs, lhs)) { + TRACE("propagate_values", tout << "insert " << mk_pp(rhs, m) << " -> " << mk_pp(lhs, m) << "\n";); + m_scoped_substitution.insert(rhs, lhs, m.mk_symmetry(pr)); + return; + } + TRACE("propagate_values", tout << "incompatible " << mk_pp(n, m) << "\n";); + } + if (m.is_not(n, n1)) { + m_scoped_substitution.insert(n1, m.mk_false(), m.mk_iff_false(pr)); + } + else { + m_scoped_substitution.insert(n, m.mk_true(), m.mk_iff_true(pr)); + } +} + +void expr_substitution_simplifier::compute_depth(expr* e) { + ptr_vector todo; + todo.push_back(e); + while (!todo.empty()) { + e = todo.back(); + unsigned d = 0; + if (m_expr2depth.contains(e)) { + todo.pop_back(); + continue; + } + if (is_app(e)) { + app* a = to_app(e); + bool visited = true; + for (expr* arg : *a) { + unsigned d1 = 0; + if (m_expr2depth.find(arg, d1)) { + d = std::max(d, d1); + } + else { + visited = false; + todo.push_back(arg); + } + } + if (!visited) { + continue; + } + } + todo.pop_back(); + m_expr2depth.insert(e, d + 1); + } +} diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 9325f95f5..2fa79dd1d 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -21,6 +21,7 @@ Notes: #define DOM_SIMPLIFY_TACTIC_H_ #include "ast/ast.h" +#include "ast/expr_substitution.h" #include "tactic/tactic.h" @@ -129,4 +130,34 @@ public: virtual void cleanup(); }; +class expr_substitution_simplifier : public dom_simplify_tactic::simplifier { + ast_manager& m; + expr_substitution m_subst; + scoped_expr_substitution m_scoped_substitution; + obj_map m_expr2depth; + + // move from asserted_formulas to here.. + void compute_depth(expr* e); + bool is_gt(expr* lhs, expr* rhs); + unsigned depth(expr* e) { return m_expr2depth[e]; } + +public: + expr_substitution_simplifier(ast_manager& m): m(m), m_subst(m), m_scoped_substitution(m_subst) {} + virtual ~expr_substitution_simplifier() {} + virtual bool assert_expr(expr * t, bool sign); + + void update_substitution(expr* n, proof* pr); + + virtual void operator()(expr_ref& r) { r = m_scoped_substitution.find(r); } + + virtual void pop(unsigned num_scopes) { m_scoped_substitution.pop(num_scopes); } + + virtual simplifier * translate(ast_manager & m) { + SASSERT(m_subst.empty()); + return alloc(expr_substitution_simplifier, m); + } + + +}; + #endif From 4d8290ebc2f5ed263b7e3499779eb32ff06f542d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 30 Aug 2017 14:04:02 -0700 Subject: [PATCH 232/488] update to theory_seq following examples from PJLJ Signed-off-by: Nikolaj Bjorner --- src/math/automata/automaton.h | 10 +++++ src/smt/theory_seq.cpp | 82 +++++++++++++++-------------------- src/smt/theory_seq.h | 2 + 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/src/math/automata/automaton.h b/src/math/automata/automaton.h index 2f55d5cc2..12aa120b3 100644 --- a/src/math/automata/automaton.h +++ b/src/math/automata/automaton.h @@ -300,6 +300,16 @@ public: } } + bool is_sink_state(unsigned s) const { + if (is_final_state(s)) return false; + moves mvs; + get_moves_from(s, mvs); + for (move const& m : mvs) { + if (s != m.dst()) return false; + } + return true; + } + void add_init_to_final_states() { add_to_final_states(init()); } diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index a32a4833a..44ce804e7 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -19,11 +19,12 @@ Revision History: --*/ #include +#include "ast/ast_pp.h" +#include "ast/ast_trail.h" #include "smt/proto_model/value_factory.h" #include "smt/smt_context.h" #include "smt/smt_model_generator.h" #include "smt/theory_seq.h" -#include "ast/ast_trail.h" #include "smt/theory_arith.h" #include "smt/smt_kernel.h" @@ -150,9 +151,8 @@ void theory_seq::solution_map::pop_scope(unsigned num_scopes) { } void theory_seq::solution_map::display(std::ostream& out) const { - eqdep_map_t::iterator it = m_map.begin(), end = m_map.end(); - for (; it != end; ++it) { - out << mk_pp(it->m_key, m) << " |-> " << mk_pp(it->m_value.first, m) << "\n"; + for (auto const& kv : m_map) { + out << mk_pp(kv.m_key, m) << " |-> " << mk_pp(kv.m_value.first, m) << "\n"; } } @@ -186,9 +186,8 @@ void theory_seq::exclusion_table::pop_scope(unsigned num_scopes) { } void theory_seq::exclusion_table::display(std::ostream& out) const { - table_t::iterator it = m_table.begin(), end = m_table.end(); - for (; it != end; ++it) { - out << mk_pp(it->first, m) << " != " << mk_pp(it->second, m) << "\n"; + for (auto const& kv : m_table) { + out << mk_pp(kv.first, m) << " != " << mk_pp(kv.second, m) << "\n"; } } @@ -213,6 +212,7 @@ theory_seq::theory_seq(ast_manager& m): m_trail_stack(*this), m_ls(m), m_rs(m), m_lhs(m), m_rhs(m), + m_res(m), m_atoms_qhead(0), m_new_solution(false), m_new_propagation(false), @@ -936,18 +936,14 @@ bool theory_seq::check_length_coherence0(expr* e) { bool theory_seq::check_length_coherence() { - obj_hashtable::iterator it = m_length.begin(), end = m_length.end(); #if 1 - for (; it != end; ++it) { - expr* e = *it; + for (expr* e : m_length) { if (check_length_coherence0(e)) { return true; } } - it = m_length.begin(); #endif - for (; it != end; ++it) { - expr* e = *it; + for (expr* e : m_length) { if (check_length_coherence(e)) { return true; } @@ -956,10 +952,9 @@ bool theory_seq::check_length_coherence() { } bool theory_seq::fixed_length() { - obj_hashtable::iterator it = m_length.begin(), end = m_length.end(); bool found = false; - for (; it != end; ++it) { - if (fixed_length(*it)) { + for (expr* e : m_length) { + if (fixed_length(e)) { found = true; } } @@ -2501,12 +2496,11 @@ void theory_seq::display(std::ostream & out) const { } if (!m_re2aut.empty()) { out << "Regex\n"; - obj_map::iterator it = m_re2aut.begin(), end = m_re2aut.end(); - for (; it != end; ++it) { - out << mk_pp(it->m_key, m) << "\n"; + for (auto const& kv : m_re2aut) { + out << mk_pp(kv.m_key, m) << "\n"; display_expr disp(m); - if (it->m_value) { - it->m_value->display(out, disp); + if (kv.m_value) { + kv.m_value->display(out, disp); } } } @@ -2520,9 +2514,7 @@ void theory_seq::display(std::ostream & out) const { } if (!m_length.empty()) { - obj_hashtable::iterator it = m_length.begin(), end = m_length.end(); - for (; it != end; ++it) { - expr* e = *it; + for (expr* e : m_length) { rational lo(-1), hi(-1); lower_bound(e, lo); upper_bound(e, hi); @@ -2635,6 +2627,12 @@ void theory_seq::collect_statistics(::statistics & st) const { st.update("seq int.to.str", m_stats.m_int_string); } +void theory_seq::init_search_eh() { + m_re2aut.reset(); + m_res.reset(); + m_automata.reset(); +} + void theory_seq::init_model(expr_ref_vector const& es) { expr_ref new_s(m); for (expr* e : es) { @@ -3396,7 +3394,6 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) { literal lit = ctx.get_literal(n); if (!is_true) { e3 = m_util.re.mk_complement(e2); - is_true = true; lit.neg(); } eautomaton* a = get_automaton(e3); @@ -3415,26 +3412,17 @@ void theory_seq::propagate_in_re(expr* n, bool is_true) { unsigned_vector states; a->get_epsilon_closure(a->init(), states); literal_vector lits; - if (is_true) { - lits.push_back(~lit); - } + lits.push_back(~lit); + for (unsigned i = 0; i < states.size(); ++i) { - if (is_true) { - lits.push_back(mk_accept(e1, zero, e3, states[i])); - } - else { - literal nlit = ~lit; - propagate_lit(0, 1, &nlit, mk_reject(e1, zero, e3, states[i])); - } + lits.push_back(mk_accept(e1, zero, e3, states[i])); } - if (is_true) { - if (lits.size() == 2) { - propagate_lit(0, 1, &lit, lits[1]); - } - else { - TRACE("seq", ctx.display_literals_verbose(tout, lits); tout << "\n";); - ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr()); - } + if (lits.size() == 2) { + propagate_lit(0, 1, &lit, lits[1]); + } + else { + TRACE("seq", ctx.display_literals_verbose(tout, lits); tout << "\n";); + ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr()); } } @@ -4179,10 +4167,8 @@ eautomaton* theory_seq::get_automaton(expr* re) { TRACE("seq", result->display(tout, disp);); } m_automata.push_back(result); - m_trail_stack.push(push_back_vector >(m_automata)); - m_re2aut.insert(re, result); - m_trail_stack.push(insert_obj_map(m_re2aut, re)); + m_res.push_back(re); return result; } @@ -4263,6 +4249,10 @@ void theory_seq::propagate_acc_rej_length(literal lit, expr* e) { if (m_util.str.is_length(idx)) return; SASSERT(m_autil.is_numeral(idx)); SASSERT(get_context().get_assignment(lit) == l_true); + if (aut->is_sink_state(src)) { + propagate_lit(0, 1, &lit, false_literal); + return; + } bool is_final = aut->is_final_state(src); if (is_final == is_acc) { propagate_lit(0, 1, &lit, mk_literal(m_autil.mk_ge(m_util.str.mk_length(s), idx))); diff --git a/src/smt/theory_seq.h b/src/smt/theory_seq.h index b5a53e8e4..1f97697c2 100644 --- a/src/smt/theory_seq.h +++ b/src/smt/theory_seq.h @@ -328,6 +328,7 @@ namespace smt { // maintain automata with regular expressions. scoped_ptr_vector m_automata; obj_map m_re2aut; + expr_ref_vector m_res; // queue of asserted atoms ptr_vector m_atoms; @@ -361,6 +362,7 @@ namespace smt { virtual void collect_statistics(::statistics & st) const; virtual model_value_proc * mk_value(enode * n, model_generator & mg); virtual void init_model(model_generator & mg); + virtual void init_search_eh(); void init_model(expr_ref_vector const& es); // final check From 62f8cc1289f925adc416bef90eab3ef3657dcf55 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 31 Aug 2017 07:33:38 -0700 Subject: [PATCH 233/488] fix ordering for value propagation to ensure values are preferred Signed-off-by: Nikolaj Bjorner --- src/smt/asserted_formulas.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 626588ab3..6ecf26bd8 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -514,9 +514,15 @@ bool asserted_formulas::is_gt(expr* lhs, expr* rhs) { if (lhs == rhs) { return false; } - if (m.is_value(rhs)) { + // values are always less in ordering than non-values. + bool v1 = m.is_value(lhs); + bool v2 = m.is_value(rhs); + if (!v1 && v2) { return true; } + if (v1 && !v2) { + return false; + } SASSERT(is_ground(lhs) && is_ground(rhs)); if (depth(lhs) > depth(rhs)) { return true; From 059bad909ad4b5f0b70378970475149822cccaa6 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 31 Aug 2017 07:33:55 -0700 Subject: [PATCH 234/488] prune dead states from automata Signed-off-by: Nikolaj Bjorner --- src/ast/simplifier/base_simplifier.h | 1 + src/ast/simplifier/simplifier.cpp | 9 +++- src/math/automata/automaton.h | 72 +++++++++++++++++++++------- src/smt/asserted_formulas.cpp | 3 +- src/smt/smt_quantifier.cpp | 7 ++- 5 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/ast/simplifier/base_simplifier.h b/src/ast/simplifier/base_simplifier.h index 73a04d605..87c372636 100644 --- a/src/ast/simplifier/base_simplifier.h +++ b/src/ast/simplifier/base_simplifier.h @@ -37,6 +37,7 @@ protected: tout << mk_pp(n, m) << "\n"; tout << mk_pp(r, m) << "\n"; tout << mk_pp(p, m) << "\n";); + TRACE("cache", tout << mk_pp(n, m) << " -> " << mk_pp(r, m) << "\n";); SASSERT(is_rewrite_proof(n, r, p)); } void reset_cache() { m_cache.reset(); } diff --git a/src/ast/simplifier/simplifier.cpp b/src/ast/simplifier/simplifier.cpp index c02753440..e7f842203 100644 --- a/src/ast/simplifier/simplifier.cpp +++ b/src/ast/simplifier/simplifier.cpp @@ -591,8 +591,10 @@ void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) { if (m_ac_cache.find(to_app(arg), new_arg)) { SASSERT(new_arg != 0); new_args.push_back(new_arg); - if (arg != new_arg) + if (arg != new_arg) { + TRACE("ac", tout << mk_pp(arg, m) << " -> " << mk_pp(new_arg, m) << "\n";); has_new_arg = true; + } if (m.fine_grain_proofs()) { proof * pr = 0; m_ac_pr_cache.find(to_app(arg), pr); @@ -610,8 +612,10 @@ void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) { proof * pr; get_cached(arg, new_arg, pr); new_args.push_back(new_arg); - if (arg != new_arg) + if (arg != new_arg) { + TRACE("ac", tout << "cached: " << mk_pp(arg, m) << " -> " << mk_pp(new_arg, m) << "\n";); has_new_arg = true; + } if (m.fine_grain_proofs() && pr != 0) new_arg_prs.push_back(pr); } @@ -627,6 +631,7 @@ void simplifier::mk_ac_congruent_term(app * n, app_ref & r, proof_ref & p) { else { app * new_curr = m.mk_app(f, new_args.size(), new_args.c_ptr()); m_ac_cache.insert(curr, new_curr); + TRACE("ac", tout << mk_pp(curr, m) << " -> " << mk_pp(new_curr, m) << "\n";); if (m.fine_grain_proofs()) { proof * p = m.mk_congruence(curr, new_curr, new_arg_prs.size(), new_arg_prs.c_ptr()); m_ac_pr_cache.insert(curr, p); diff --git a/src/math/automata/automaton.h b/src/math/automata/automaton.h index 12aa120b3..07d6d31ec 100644 --- a/src/math/automata/automaton.h +++ b/src/math/automata/automaton.h @@ -25,6 +25,7 @@ Revision History: #include "util/util.h" #include "util/vector.h" #include "util/uint_set.h" +#include "util/trace.h" template class default_value_manager { @@ -383,12 +384,12 @@ public: else if (1 == in_degree(dst) && (!is_final_state(dst) || is_final_state(src)) && init() != dst) { moves const& mvs = m_delta[dst]; moves mvs1; - for (unsigned k = 0; k < mvs.size(); ++k) { - mvs1.push_back(move(m, src, mvs[k].dst(), mvs[k].t())); + for (move const& mv : mvs) { + mvs1.push_back(move(m, src, mv.dst(), mv.t())); } - for (unsigned k = 0; k < mvs1.size(); ++k) { - remove(dst, mvs1[k].dst(), mvs1[k].t()); - add(mvs1[k]); + for (move const& mv : mvs1) { + remove(dst, mv.dst(), mv.t()); + add(mv); } } // @@ -401,13 +402,13 @@ public: unsigned_vector src0s; moves const& mvs = m_delta_inv[dst]; moves mvs1; - for (unsigned k = 0; k < mvs.size(); ++k) { - SASSERT(mvs[k].is_epsilon()); - mvs1.push_back(move(m, mvs[k].src(), dst1, t)); + for (move const& mv1 : mvs) { + SASSERT(mv1.is_epsilon()); + mvs1.push_back(move(m, mv1.src(), dst1, t)); } - for (unsigned k = 0; k < mvs1.size(); ++k) { - remove(mvs1[k].src(), dst, 0); - add(mvs1[k]); + for (move const& mv1 : mvs1) { + remove(mv1.src(), dst, 0); + add(mv1); } remove(dst, dst1, t); --j; @@ -419,12 +420,12 @@ public: else if (1 == out_degree(src) && init() != src && (!is_final_state(src) || is_final_state(dst))) { moves const& mvs = m_delta_inv[src]; moves mvs1; - for (unsigned k = 0; k < mvs.size(); ++k) { - mvs1.push_back(move(m, mvs[k].src(), dst, mvs[k].t())); + for (move const& mv : mvs) { + mvs1.push_back(move(m, mv.src(), dst, mv.t())); } - for (unsigned k = 0; k < mvs1.size(); ++k) { - remove(mvs1[k].src(), src, mvs1[k].t()); - add(mvs1[k]); + for (move const& mv : mvs1) { + remove(mv.src(), src, mv.t()); + add(mv); } } else { @@ -447,6 +448,7 @@ public: break; } } + sinkify_dead_states(); } bool is_sequence(unsigned& length) const { @@ -564,6 +566,40 @@ public: } private: + void sinkify_dead_states() { + uint_set dead_states; + for (unsigned i = 0; i < m_delta.size(); ++i) { + if (!m_final_states.contains(i)) { + dead_states.insert(i); + } + } + bool change = true; + unsigned_vector to_remove; + while (change) { + change = false; + to_remove.reset(); + for (unsigned s : dead_states) { + moves const& mvs = m_delta[s]; + for (move const& mv : mvs) { + if (!dead_states.contains(mv.dst())) { + to_remove.push_back(s); + break; + } + } + } + change = !to_remove.empty(); + for (unsigned s : to_remove) { + dead_states.remove(s); + } + to_remove.reset(); + } + TRACE("seq", tout << "remove: " << dead_states << "\n";); + for (unsigned s : dead_states) { + CTRACE("seq", !m_delta[s].empty(), tout << "live state " << s << "\n";); + m_delta[s].reset(); + } + } + void remove_dead_states() { unsigned_vector remap; for (unsigned i = 0; i < m_delta.size(); ++i) { @@ -669,8 +705,8 @@ private: } static void append_final(unsigned offset, automaton const& a, unsigned_vector& final) { - for (unsigned i = 0; i < a.m_final_states.size(); ++i) { - final.push_back(a.m_final_states[i]+offset); + for (unsigned s : a.m_final_states) { + final.push_back(s+offset); } } diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index dabae9fbd..d9630c979 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -645,7 +645,7 @@ void asserted_formulas::propagate_values() { new_prs2.push_back(pr); } } - TRACE("propagate_values", tout << "found: " << found << "\n";); + TRACE("propagate_values", tout << "found: " << found << "\n" << new_exprs2 << "\n";); // If C is not empty, then reduce R using the updated simplifier cache with entries // x -> n for each constraint 'x = n' in C. if (found) { @@ -656,6 +656,7 @@ void asserted_formulas::propagate_values() { expr_ref new_n(m); proof_ref new_pr(m); m_simplifier(n, new_n, new_pr); + TRACE("propagate_values", tout << mk_pp(n, m) << " -> " << new_n << "\n";); if (n == new_n.get()) { push_assertion(n, pr, new_exprs1, new_prs1); } diff --git a/src/smt/smt_quantifier.cpp b/src/smt/smt_quantifier.cpp index 84ed7c8cd..0492aff23 100644 --- a/src/smt/smt_quantifier.cpp +++ b/src/smt/smt_quantifier.cpp @@ -492,6 +492,7 @@ namespace smt { virtual void assign_eh(quantifier * q) { m_active = true; + ast_manager& m = m_context->get_manager(); if (!m_fparams->m_ematching) { return; } @@ -514,7 +515,11 @@ namespace smt { app * mp = to_app(q->get_pattern(i)); SASSERT(m_context->get_manager().is_pattern(mp)); bool unary = (mp->get_num_args() == 1); - if (!unary && j >= num_eager_multi_patterns) { + if (m.is_rec_fun_def(q) && i > 0) { + // add only the first pattern + TRACE("quantifier", tout << "skip recursive function body " << mk_ismt2_pp(mp, m) << "\n";); + } + else if (!unary && j >= num_eager_multi_patterns) { TRACE("quantifier", tout << "delaying (too many multipatterns):\n" << mk_ismt2_pp(mp, m_context->get_manager()) << "\n" << "j: " << j << " unary: " << unary << " m_params.m_qi_max_eager_multipatterns: " << m_fparams->m_qi_max_eager_multipatterns << " num_eager_multi_patterns: " << num_eager_multi_patterns << "\n";); From fff54d5d08e610c856ba5651ab0a1276079445aa Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 03:56:10 -0700 Subject: [PATCH 235/488] fix perf regression with negative polynomial normalization, adding new datatype plugin Signed-off-by: Nikolaj Bjorner --- src/ast/CMakeLists.txt | 1 + src/ast/ast.cpp | 43 +- src/ast/ast.h | 13 +- src/ast/datatype_decl_plugin.cpp | 2 +- src/ast/datatype_decl_plugin.h | 2 +- src/ast/datatype_decl_plugin2.cpp | 819 +++++++++++++++++++++ src/ast/datatype_decl_plugin2.h | 257 +++++++ src/ast/rewriter/arith_rewriter.cpp | 66 +- src/ast/rewriter/arith_rewriter.h | 3 + src/ast/rewriter/arith_rewriter_params.pyg | 1 + src/smt/asserted_formulas.cpp | 2 + src/smt/params/theory_arith_params.cpp | 3 + src/smt/theory_datatype.cpp | 13 +- src/util/symbol_table.h | 21 +- 14 files changed, 1207 insertions(+), 39 deletions(-) create mode 100644 src/ast/datatype_decl_plugin2.cpp create mode 100644 src/ast/datatype_decl_plugin2.h diff --git a/src/ast/CMakeLists.txt b/src/ast/CMakeLists.txt index 0a14d9473..47ed2def8 100644 --- a/src/ast/CMakeLists.txt +++ b/src/ast/CMakeLists.txt @@ -14,6 +14,7 @@ z3_add_component(ast ast_util.cpp bv_decl_plugin.cpp datatype_decl_plugin.cpp + datatype_decl_plugin2.cpp decl_collector.cpp dl_decl_plugin.cpp expr2polynomial.cpp diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index c1ff04ada..1a35e710a 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -188,18 +188,14 @@ decl_info::decl_info(decl_info const& other) : void decl_info::init_eh(ast_manager & m) { - vector::iterator it = m_parameters.begin(); - vector::iterator end = m_parameters.end(); - for (; it != end; ++it) { - it->init_eh(m); + for (parameter & p : m_parameters) { + p.init_eh(m); } } void decl_info::del_eh(ast_manager & m) { - vector::iterator it = m_parameters.begin(); - vector::iterator end = m_parameters.end(); - for (; it != end; ++it) { - it->del_eh(m, m_family_id); + for (parameter & p : m_parameters) { + p.del_eh(m, m_family_id); } } @@ -1935,6 +1931,35 @@ sort * ast_manager::mk_sort(symbol const & name, sort_info * info) { return register_node(new_node); } +sort * ast_manager::substitute(sort* s, unsigned n, sort * const * src, sort * const * dst) { + for (unsigned i = 0; i < n; ++i) { + if (s == src[i]) return dst[i]; + } + + vector ps; + bool change = false; + sort_ref_vector sorts(*this); + for (unsigned i = 0; i < s->get_num_parameters(); ++i) { + parameter const& p = s->get_parameter(i); + if (p.is_ast()) { + SASSERT(is_sort(p.get_ast())); + change = true; + sorts.push_back(substitute(to_sort(p.get_ast()), n, src, dst)); + ps.push_back(parameter(sorts.back())); + } + else { + ps.push_back(p); + } + } + if (!change) { + return s; + } + decl_info dinfo(s->get_family_id(), s->get_decl_kind(), ps.size(), ps.c_ptr(), s->private_parameters()); + sort_info sinfo(dinfo, s->get_num_elements()); + return mk_sort(s->get_name(), &sinfo); +} + + 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); @@ -2580,7 +2605,7 @@ expr * ast_manager::get_some_value(sort * s) { return mk_model_value(0, s); } -bool ast_manager::is_fully_interp(sort const * s) const { +bool ast_manager::is_fully_interp(sort * s) const { if (is_uninterp(s)) return false; family_id fid = s->get_family_id(); diff --git a/src/ast/ast.h b/src/ast/ast.h index 699268bd0..a1e31f46f 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -335,13 +335,17 @@ public: unsigned num_parameters = 0, parameter const * parameters = 0, bool private_parameters = false): decl_info(family_id, k, num_parameters, parameters, private_parameters), m_num_elements(num_elements) { } - sort_info(sort_info const& other) : decl_info(other), m_num_elements(other.m_num_elements) { + sort_info(sort_info const& other) : decl_info(other), m_num_elements(other.m_num_elements) { } + sort_info(decl_info const& di, sort_size const& num_elements) : + decl_info(di), m_num_elements(num_elements) {} + ~sort_info() {} bool is_infinite() const { return m_num_elements.is_infinite(); } bool is_very_big() const { return m_num_elements.is_very_big(); } sort_size const & get_num_elements() const { return m_num_elements; } + void set_num_elements(sort_size const& s) { m_num_elements = s; } }; std::ostream & operator<<(std::ostream & out, sort_info const & info); @@ -567,6 +571,7 @@ public: bool is_very_big() const { return get_info() == 0 || get_info()->is_very_big(); } bool is_sort_of(family_id fid, decl_kind k) const { return get_family_id() == fid && get_decl_kind() == k; } sort_size const & get_num_elements() const { return get_info()->get_num_elements(); } + void set_num_elements(sort_size const& s) { get_info()->set_num_elements(s); } unsigned get_size() const { return get_obj_size(); } }; @@ -988,7 +993,7 @@ public: // Return true if the interpreted sort s does not depend on uninterpreted sorts. // This may be the case, for example, for array and datatype sorts. - virtual bool is_fully_interp(sort const * s) const { return true; } + virtual bool is_fully_interp(sort * s) const { return true; } // Event handlers for deleting/translating PARAM_EXTERNAL virtual void del(parameter const & p) {} @@ -1655,6 +1660,8 @@ public: sort * mk_sort(family_id fid, decl_kind k, unsigned num_parameters = 0, parameter const * parameters = 0); + sort * substitute(sort* s, unsigned n, sort * const * src, sort * const * dst); + sort * mk_bool_sort() const { return m_bool_sort; } sort * mk_proof_sort() const { return m_proof_sort; } @@ -1667,7 +1674,7 @@ public: \brief A sort is "fully" interpreted if it is interpreted, and doesn't depend on other uninterpreted sorts. */ - bool is_fully_interp(sort const * s) const; + bool is_fully_interp(sort * s) const; func_decl * mk_func_decl(family_id fid, decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range = 0); diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index b4f30767f..446992105 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -675,7 +675,7 @@ expr * datatype_decl_plugin::get_some_value(sort * s) { return m_manager->mk_app(c, args.size(), args.c_ptr()); } -bool datatype_decl_plugin::is_fully_interp(sort const * s) const { +bool datatype_decl_plugin::is_fully_interp(sort * s) const { SASSERT(s->is_sort_of(m_family_id, DATATYPE_SORT)); parameter const * parameters = s->get_parameters(); unsigned num_types = parameters[0].get_int(); diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index 3d008ad9c..dcd352471 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -150,7 +150,7 @@ public: virtual expr * get_some_value(sort * s); - virtual bool is_fully_interp(sort const * s) const; + virtual bool is_fully_interp(sort * s) const; virtual bool is_value(app* e) const; diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp new file mode 100644 index 000000000..4e60abcce --- /dev/null +++ b/src/ast/datatype_decl_plugin2.cpp @@ -0,0 +1,819 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + datatype_decl_plugin.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-01-10. + +Revision History: + + // compute sort sizes and insert them. + // have a notion of pre-sort or just attach sort size after declaration. + +--*/ +#include "ast/datatype_decl_plugin2.h" +#include "util/warning.h" +#include "ast/ast_smt2_pp.h" + +namespace datatype { + + func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const { + unsigned n = ps.size(); + SASSERT(n == get_def().params().size()); + sort_ref range(m.substitute(m_range, n, get_def().params().c_ptr(), ps.c_ptr()), m); + sort_ref src(get_def().instantiate(ps)); + sort* srcs[1] = { src.get() }; + parameter pas[2] = { parameter(name()), parameter(get_constructor().name()) }; + return func_decl_ref(m.mk_func_decl(u().get_family_id(), OP_DT_ACCESSOR, 2, pas, 1, srcs, range), m); + } + + func_decl_ref accessor::instantiate(sort* dt) const { + sort_ref_vector sorts = get_def().u().datatype_params(dt); + return instantiate(sorts); + } + + def const& accessor::get_def() const { return m_constructor->get_def(); } + util& accessor::u() const { return m_constructor->u(); } + + util& constructor::u() const { return m_def->u(); } + + func_decl_ref constructor::instantiate(sort_ref_vector const& ps) const { + sort_ref_vector domain(m); + for (accessor const& a : accessors()) { + domain.push_back(a.instantiate(ps)->get_range()); + } + sort_ref range = get_def().instantiate(ps); + parameter pas[1] = { parameter(name()) }; + return func_decl_ref(m.mk_func_decl(u().get_family_id(), OP_DT_CONSTRUCTOR, 1, pas, domain.size(), domain.c_ptr(), range), m); + } + + func_decl_ref constructor::instantiate(sort* dt) const { + sort_ref_vector sorts = get_def().u().datatype_params(dt); + return instantiate(sorts); + } + + sort_ref def::instantiate(sort_ref_vector const& sorts) const { + sort_ref s(m); + if (!m_sort) { + vector ps; + for (sort * s : m_params) ps.push_back(parameter(s)); + m_sort = m.mk_sort(u().get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); + } + if (sorts.empty()) { + return m_sort; + } + return sort_ref(m.substitute(m_sort, sorts.size(), sorts.c_ptr(), m_params.c_ptr()), m); + } + + enum status { + GRAY, + BLACK + }; + + namespace decl { + + plugin::~plugin() { + finalize(); + } + + void plugin::finalize() { + for (auto& kv : m_defs) { + dealloc(kv.m_value); + } + m_defs.reset(); + m_util = 0; // force deletion + } + + util & plugin::u() const { + SASSERT(m_manager); + if (m_util.get() == 0) { + m_util = alloc(util, *m_manager); + } + return *(m_util.get()); + } + + struct invalid_datatype {}; + + sort * plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { + try { + if (k != DATATYPE_SORT) { + throw invalid_datatype(); + } + if (num_parameters < 1) { + throw invalid_datatype(); + } + parameter const & name = parameters[0]; + if (!name.is_symbol()) { + TRACE("datatype", tout << "expected symol parameter at position " << 0 << " got: " << name << "\n";); + throw invalid_datatype(); + } + for (unsigned i = 1; i < num_parameters; ++i) { + parameter const& s = parameters[i]; + if (!s.is_ast() || !is_sort(s.get_ast())) { + TRACE("datatype", tout << "expected sort parameter at position " << i << " got: " << s << "\n";); + throw invalid_datatype(); + } + } + + sort* s = m_manager->mk_sort(name.get_symbol(), + sort_info(m_family_id, k, num_parameters, parameters, true)); + // compute datatype size + sort_size ts = u().get_datatype_size(s); + s->set_num_elements(ts); + return s; + } + catch (invalid_datatype) { + m_manager->raise_exception("invalid datatype"); + return 0; + } + } + + func_decl * plugin::mk_update_field( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + decl_kind k = OP_DT_UPDATE_FIELD; + ast_manager& m = *m_manager; + + if (num_parameters != 1 || !parameters[0].is_ast()) { + m.raise_exception("invalid parameters for datatype field update"); + return 0; + } + if (arity != 2) { + m.raise_exception("invalid number of arguments for datatype field update"); + return 0; + } + func_decl* acc = 0; + if (is_func_decl(parameters[0].get_ast())) { + acc = to_func_decl(parameters[0].get_ast()); + } + if (acc && !u().is_accessor(acc)) { + acc = 0; + } + if (!acc) { + m.raise_exception("datatype field update requires a datatype accessor as the second argument"); + return 0; + } + sort* dom = acc->get_domain(0); + sort* rng = acc->get_range(); + if (dom != domain[0]) { + m.raise_exception("first argument to field update should be a data-type"); + return 0; + } + if (rng != domain[1]) { + std::ostringstream buffer; + buffer << "second argument to field update should be " << mk_ismt2_pp(rng, m) + << " instead of " << mk_ismt2_pp(domain[1], m); + m.raise_exception(buffer.str().c_str()); + return 0; + } + range = domain[0]; + func_decl_info info(m_family_id, k, num_parameters, parameters); + return m.mk_func_decl(symbol("update-field"), arity, domain, range, info); + } + + + func_decl * decl::plugin::mk_constructor(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + ast_manager& m = *m_manager; + SASSERT(num_parameters == 1 && parameters[0].is_symbol() && range && u().is_datatype(range)); + if (num_parameters != 1 || !parameters[0].is_symbol() || !range || !u().is_datatype(range)) { + m_manager->raise_exception("invalid parameters for datatype constructor"); + } + // we blindly trust other conditions are met, including domain types. + symbol name = parameters[0].get_symbol(); + func_decl_info info(m_family_id, OP_DT_CONSTRUCTOR, num_parameters, parameters); + info.m_private_parameters = true; + return m.mk_func_decl(name, arity, domain, range, info); + } + + func_decl * decl::plugin::mk_recognizer(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort *) { + ast_manager& m = *m_manager; + SASSERT(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + SASSERT(u().is_datatype(domain[0])); + // blindly trust that parameter is a constructor + sort* range = m_manager->mk_bool_sort(); + func_decl_info info(m_family_id, OP_DT_RECOGNISER, num_parameters, parameters); + info.m_private_parameters = true; + symbol name = to_func_decl(parameters[0].get_ast())->get_name(); + return m.mk_func_decl(name, arity, domain, range); + } + + func_decl * decl::plugin::mk_accessor(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) + { + ast_manager& m = *m_manager; + SASSERT(arity == 1 && num_parameters == 2 && parameters[0].is_symbol() && parameters[0].is_symbol()); + SASSERT(u().is_datatype(domain[0])); + SASSERT(range); + func_decl_info info(m_family_id, OP_DT_ACCESSOR, num_parameters, parameters); + info.m_private_parameters = true; + symbol name = parameters[0].get_symbol(); + return m.mk_func_decl(name, arity, domain, range); + } + + func_decl * decl::plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + switch (k) { + case OP_DT_CONSTRUCTOR: + return mk_constructor(num_parameters, parameters, arity, domain, range); + case OP_DT_RECOGNISER: + return mk_recognizer(num_parameters, parameters, arity, domain, range); + case OP_DT_ACCESSOR: + return mk_accessor(num_parameters, parameters, arity, domain, range); + case OP_DT_UPDATE_FIELD: + return mk_update_field(num_parameters, parameters, arity, domain, range); + default: + m_manager->raise_exception("invalid datatype operator kind"); + return 0; + } + } + + def& plugin::add(symbol const& name, unsigned n, sort * const * params) { + ast_manager& m = *m_manager; + def* d = alloc(def, m, u(), name, m_class_id, n, params); + m_defs.insert(name, d); + m_def_block.push_back(name); + return *d; + } + + void plugin::end_def_block() { + ast_manager& m = *m_manager; + sort_ref_vector sorts(m); + for (symbol const& s : m_def_block) { + def const& d = *m_defs[s]; + sort_ref_vector ps(m); + sorts.push_back(d.instantiate(ps)); + } + if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) { + m_manager->raise_exception("datatype is not well-founded"); + } + } + + void plugin::del(symbol const& s) { + def* d = 0; + if (m_defs.find(s, d)) dealloc(d); + m_defs.remove(s); + } + + bool plugin::is_value_visit(expr * arg, ptr_buffer & todo) const { + if (!is_app(arg)) + return false; + family_id fid = to_app(arg)->get_family_id(); + if (fid == m_family_id) { + if (!u().is_constructor(to_app(arg))) + return false; + if (to_app(arg)->get_num_args() == 0) + return true; + todo.push_back(to_app(arg)); + return true; + } + else { + return m_manager->is_value(arg); + } + } + + bool plugin::is_value(app * e) const { + TRACE("dt_is_value", tout << "checking\n" << mk_ismt2_pp(e, *m_manager) << "\n";); + if (!u().is_constructor(e)) + return false; + if (e->get_num_args() == 0) + return true; + // REMARK: if the following check is too expensive, we should + // cache the values in the decl::plugin. + ptr_buffer todo; + // potentially expensive check for common sub-expressions. + for (expr* arg : *e) { + if (!is_value_visit(arg, todo)) { + TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(arg, *m_manager) << "\n";); + return false; + } + } + while (!todo.empty()) { + app * curr = todo.back(); + SASSERT(u().is_constructor(curr)); + todo.pop_back(); + for (expr* arg : *curr) { + if (!is_value_visit(arg, todo)) { + TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(arg, *m_manager) << "\n";); + return false; + } + } + } + return true; + } + + void plugin::get_op_names(svector & op_names, symbol const & logic) { + if (logic == symbol::null) { + op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD)); + } + } + + expr * plugin::get_some_value(sort * s) { + SASSERT(u().is_datatype(s)); + func_decl * c = u().get_non_rec_constructor(s); + ptr_buffer args; + for (unsigned i = 0; i < c->get_arity(); i++) { + args.push_back(m_manager->get_some_value(c->get_domain(i))); + } + return m_manager->mk_app(c, args.size(), args.c_ptr()); + } + + bool plugin::is_fully_interp(sort * s) const { + return u().is_fully_interp(s); + } + } + + sort_ref_vector util::datatype_params(sort * s) const { + SASSERT(is_datatype(s)); + sort_ref_vector result(m); + for (unsigned i = 1; i < s->get_num_parameters(); ++i) { + result.push_back(to_sort(s->get_parameter(i).get_ast())); + } + return result; + } + + + bool util::is_fully_interp(sort * s) const { + SASSERT(is_datatype(s)); + bool fi = true; + return fi; + if (m_is_fully_interp.find(s, fi)) { + return fi; + } + unsigned sz = m_fully_interp_trail.size(); + m_is_fully_interp.insert(s, true); + def const& d = get_def(s); + bool is_interp = true; + m_fully_interp_trail.push_back(s); + for (constructor const& c : d) { + for (accessor const& a : c) { + func_decl_ref ac = a.instantiate(s); + sort* r = ac->get_range(); + if (!m.is_fully_interp(r)) { + is_interp = false; + break; + } + } + if (!is_interp) break; + } + for (unsigned i = sz; i < m_fully_interp_trail.size(); ++i) { + m_is_fully_interp.remove(m_fully_interp_trail[i]); + } + m_fully_interp_trail.shrink(sz); + m_is_fully_interp.insert(s, is_interp); + m_asts.push_back(s); + return true; + } + + /** + \brief Return true if the inductive datatype is recursive. + */ + bool util::is_recursive_core(sort* s) const { + obj_map already_found; + ptr_vector todo, subsorts; + todo.push_back(s); + status st; + while (!todo.empty()) { + s = todo.back(); + if (already_found.find(s, st) && st == BLACK) { + todo.pop_back(); + continue; + } + already_found.insert(s, GRAY); + def const& d = get_def(s); + bool can_process = true; + for (constructor const& c : d) { + for (accessor const& a : c) { + sort* d = a.range(); + // check if d is a datatype sort + subsorts.reset(); + get_subsorts(d, subsorts); + for (sort * s2 : subsorts) { + if (is_datatype(s2)) { + if (already_found.find(s2, st)) { + // type is recursive + if (st == GRAY) return true; + } + else { + todo.push_back(s2); + can_process = false; + } + } + } + } + } + if (can_process) { + already_found.insert(s, BLACK); + todo.pop_back(); + } + } + return false; + } + + /** + \brief Return the size of the inductive datatype. + Pre-condition: The given argument constains the parameters of an inductive datatype. + */ + sort_size util::get_datatype_size(sort* s0) { + obj_map already_found; + obj_map szs; + ptr_vector todo; + todo.push_back(s0); + status st; + while (!todo.empty()) { + sort* s = todo.back(); + if (already_found.find(s, st) && st == BLACK) { + todo.pop_back(); + continue; + } + already_found.insert(s, GRAY); + bool is_very_big = false; + bool can_process = true; + def const& d = get_def(s); + for (constructor const& c : d) { + for (accessor const& a : c) { + func_decl_ref ac = a.instantiate(s); + sort* r = ac->get_range(); + if (is_datatype(r)) { + if (already_found.find(r, st)) { + // type is infinite + if (st == GRAY) return sort_size(); + } + else { + todo.push_back(r); + can_process = false; + } + } + else if (r->is_infinite()) { + // type is infinite + return sort_size(); + } + else if (r->is_very_big()) { + is_very_big = true; + } + } + } + + if (can_process) { + todo.pop_back(); + already_found.insert(s, BLACK); + if (is_very_big) { + szs.insert(s, sort_size::mk_very_big()); + } + else { + // the type is not infinite nor the number of elements is infinite... + // computing the number of elements + rational num; + def const& d = get_def(s); + for (constructor const& c : d) { + rational c_num(1); + for (accessor const& a : c) { + func_decl_ref ac = a.instantiate(s); + sort* r = ac->get_range(); + if (szs.contains(r)) { + c_num *= rational(szs[r].size(), rational::ui64()); + } + else { + SASSERT(!r->is_infinite() && !r->is_very_big()); + c_num *= rational(r->get_num_elements().size(), rational::ui64()); + } + } + num += c_num; + } + szs.insert(s, sort_size(num)); + } + } + } + return szs[s0]; + } + + + /** + \brief Return true if the inductive datatype is well-founded. + Pre-condition: The given argument constains the parameters of an inductive datatype. + */ + bool util::is_well_founded(unsigned num_types, sort* const* sorts) { + buffer well_founded(num_types, false); + obj_map sort2id; + for (unsigned i = 0; i < num_types; ++i) { + sort2id.insert(sorts[i], i); + } + unsigned num_well_founded = 0, id = 0; + bool changed; + do { + changed = false; + for (unsigned tid = 0; tid < num_types; tid++) { + if (well_founded[tid]) { + continue; + } + sort* s = sorts[tid]; + def const& d = get_def(s); + for (constructor const& c : d) { + bool found_nonwf = false; + for (accessor const& a : c) { + if (sort2id.find(a.range(), id) && !well_founded[id]) { + found_nonwf = true; + break; + } + } + if (!found_nonwf) { + changed = true; + well_founded[tid] = true; + num_well_founded++; + break; + } + } + } + } + while(changed && num_well_founded < num_types); + return num_well_founded == num_types; + } + + def const& util::get_def(sort* s) const { + return m_plugin->get_def(s); + } + + void util::get_subsorts(sort* s, ptr_vector& sorts) const { + sorts.push_back(s); + for (unsigned i = 0; i < s->get_num_parameters(); ++i) { + parameter const& p = s->get_parameter(i); + if (p.is_ast() && is_sort(p.get_ast())) { + get_subsorts(to_sort(p.get_ast()), sorts); + } + } + } + + + util::util(ast_manager & m): + m(m), + m_family_id(m.mk_family_id("datatype")), + m_asts(m), + m_start(0) { + m_plugin = dynamic_cast(m.get_plugin(m_family_id)); + } + + util::~util() { + std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); + } + + ptr_vector const & util::get_datatype_constructors(sort * ty) { + SASSERT(is_datatype(ty)); + ptr_vector * r = 0; + if (m_datatype2constructors.find(ty, r)) + return *r; + r = alloc(ptr_vector); + m_asts.push_back(ty); + m_vectors.push_back(r); + m_datatype2constructors.insert(ty, r); + def const& d = get_def(ty); + for (constructor const& c : d) { + func_decl_ref f = c.instantiate(ty); + m_asts.push_back(f); + r->push_back(f); + } + return *r; + } + + ptr_vector const & util::get_constructor_accessors(func_decl * con) { + SASSERT(is_constructor(con)); + ptr_vector * res = 0; + if (m_constructor2accessors.find(con, res)) + return *res; + res = alloc(ptr_vector); + m_asts.push_back(con); + m_vectors.push_back(res); + m_constructor2accessors.insert(con, res); + sort * datatype = con->get_range(); + def const& d = get_def(datatype); + for (constructor const& c : d) { + if (c.name() == con->get_name()) { + for (accessor const& a : c) { + res->push_back(a.instantiate(datatype)); + } + break; + } + } + return *res; + } + + func_decl * util::get_constructor_recognizer(func_decl * constructor) { + SASSERT(is_constructor(constructor)); + func_decl * d = 0; + if (m_constructor2recognizer.find(constructor, d)) + return d; + sort * datatype = constructor->get_range(); + parameter ps[1] = { parameter(constructor) }; + d = m.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 1, ps, 1, &datatype); + SASSERT(d); + m_asts.push_back(constructor); + m_asts.push_back(d); + m_constructor2recognizer.insert(constructor, d); + return d; + } + + func_decl * util::get_recognizer_constructor(func_decl * recognizer) { + SASSERT(is_recognizer(recognizer)); + return to_func_decl(recognizer->get_parameter(0).get_ast()); + } + + bool util::is_recursive(sort * ty) { + SASSERT(is_datatype(ty)); + bool r = false; + if (!m_is_recursive.find(ty, r)) { + r = is_recursive_core(ty); + m_is_recursive.insert(ty, r); + m_asts.push_back(ty); + } + return r; + } + + bool util::is_enum_sort(sort* s) { + if (!is_datatype(s)) { + return false; + } + bool r = false; + if (m_is_enum.find(s, r)) + return r; + ptr_vector const& cnstrs = get_datatype_constructors(s); + r = true; + for (unsigned i = 0; r && i < cnstrs.size(); ++i) { + r = cnstrs[i]->get_arity() == 0; + } + m_is_enum.insert(s, r); + m_asts.push_back(s); + return r; + } + + func_decl * util::get_accessor_constructor(func_decl * accessor) { + SASSERT(is_accessor(accessor)); + func_decl * r = 0; + if (m_accessor2constructor.find(accessor, r)) + return r; + sort * datatype = accessor->get_domain(0); + symbol c_id = accessor->get_parameter(1).get_symbol(); + def const& d = get_def(datatype); + func_decl_ref fn(m); + for (constructor const& c : d) { + if (c.name() == c_id) { + fn = c.instantiate(datatype); + break; + } + } + r = fn; + m_accessor2constructor.insert(accessor, r); + m_asts.push_back(accessor); + m_asts.push_back(r); + return r; + } + + + void util::reset() { + m_datatype2constructors.reset(); + m_datatype2nonrec_constructor.reset(); + m_constructor2accessors.reset(); + m_constructor2recognizer.reset(); + m_recognizer2constructor.reset(); + m_accessor2constructor.reset(); + m_is_recursive.reset(); + m_is_enum.reset(); + std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); + m_vectors.reset(); + m_asts.reset(); + ++m_start; + } + + + /** + \brief Return a constructor mk(T_1, ... T_n) + where each T_i is not a datatype or it is a datatype that contains + a constructor that will not contain directly or indirectly an element of the given sort. + */ + func_decl * util::get_non_rec_constructor(sort * ty) { + SASSERT(is_datatype(ty)); + func_decl * r = 0; + if (m_datatype2nonrec_constructor.find(ty, r)) + return r; + r = 0; + ptr_vector forbidden_set; + forbidden_set.push_back(ty); + r = get_non_rec_constructor_core(ty, forbidden_set); + SASSERT(forbidden_set.back() == ty); + SASSERT(r); + m_asts.push_back(ty); + m_asts.push_back(r); + m_datatype2nonrec_constructor.insert(ty, r); + return r; + } + + /** + \brief Return a constructor mk(T_1, ..., T_n) where + each T_i is not a datatype or it is a datatype t not in forbidden_set, + and get_non_rec_constructor_core(T_i, forbidden_set union { T_i }) + */ + func_decl * util::get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set) { + // We must select a constructor c(T_1, ..., T_n):T such that + // 1) T_i's are not recursive + // If there is no such constructor, then we select one that + // 2) each type T_i is not recursive or contains a constructor that does not depend on T + ptr_vector const& constructors = get_datatype_constructors(ty); + // step 1) + unsigned sz = constructors.size(); + ++m_start; + for (unsigned j = 0; j < sz; ++j) { + func_decl * c = constructors[(j + m_start) % sz]; + unsigned num_args = c->get_arity(); + unsigned i = 0; + for (; i < num_args; i++) { + sort * T_i = c->get_domain(i); + if (is_datatype(T_i)) + break; + } + if (i == num_args) + return c; + } + // step 2) + for (unsigned j = 0; j < sz; ++j) { + func_decl * c = constructors[(j + m_start) % sz]; + TRACE("util_bug", tout << "non_rec_constructor c: " << c->get_name() << "\n";); + unsigned num_args = c->get_arity(); + unsigned i = 0; + for (; i < num_args; i++) { + sort * T_i = c->get_domain(i); + TRACE("util_bug", tout << "c: " << c->get_name() << " i: " << i << " T_i: " << T_i->get_name() << "\n";); + if (!is_datatype(T_i)) { + TRACE("util_bug", tout << "T_i is not a datatype\n";); + continue; + } + if (std::find(forbidden_set.begin(), forbidden_set.end(), T_i) != forbidden_set.end()) { + TRACE("util_bug", tout << "T_i is in forbidden_set\n";); + break; + } + forbidden_set.push_back(T_i); + func_decl * nested_c = get_non_rec_constructor_core(T_i, forbidden_set); + SASSERT(forbidden_set.back() == T_i); + forbidden_set.pop_back(); + TRACE("util_bug", tout << "nested_c: " << nested_c->get_name() << "\n";); + if (nested_c == 0) + break; + } + if (i == num_args) + return c; + } + return 0; + } + + + /** + \brief Two datatype sorts s1 and s2 are siblings if they were + defined together in the same mutually recursive definition. + */ + bool util::are_siblings(sort * s1, sort * s2) { + if (!is_datatype(s1) || !is_datatype(s2)) { + return s1 == s2; + } + else { + return get_def(s1).id() == get_def(s2).id(); + } + } + + void util::display_datatype(sort *s0, std::ostream& strm) { + ast_mark mark; + ptr_buffer todo; + SASSERT(is_datatype(s0)); + strm << s0->get_name() << " where\n"; + todo.push_back(s0); + mark.mark(s0, true); + while (!todo.empty()) { + sort* s = todo.back(); + todo.pop_back(); + strm << s->get_name() << " =\n"; + + ptr_vector const& cnstrs = get_datatype_constructors(s); + for (unsigned i = 0; i < cnstrs.size(); ++i) { + func_decl* cns = cnstrs[i]; + func_decl* rec = get_constructor_recognizer(cns); + strm << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; + ptr_vector const & accs = get_constructor_accessors(cns); + for (unsigned j = 0; j < accs.size(); ++j) { + func_decl* acc = accs[j]; + sort* s1 = acc->get_range(); + strm << "(" << acc->get_name() << ": " << s1->get_name() << ") "; + if (is_datatype(s1) && are_siblings(s1, s0) && !mark.is_marked(s1)) { + mark.mark(s1, true); + todo.push_back(s1); + } + } + strm << "\n"; + } + } + } +} diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h new file mode 100644 index 000000000..fad7ff174 --- /dev/null +++ b/src/ast/datatype_decl_plugin2.h @@ -0,0 +1,257 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + datatype_decl_plugin.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-01-09. + +Revision History: + +--*/ +#ifndef DATATYPE_DECL_PLUGIN2_H_ +#define DATATYPE_DECL_PLUGIN2_H_ + +#include "ast/ast.h" +#include "util/buffer.h" +#include "util/symbol_table.h" +#include "util/obj_hashtable.h" + +namespace datatype { + + class util; + class def; + class accessor; + class constructor; + + enum sort_kind { + DATATYPE_SORT + }; + + enum op_kind { + OP_DT_CONSTRUCTOR, + OP_DT_RECOGNISER, + OP_DT_ACCESSOR, + OP_DT_UPDATE_FIELD, + LAST_DT_OP + }; + + class accessor { + ast_manager& m; + symbol m_name; + sort_ref m_domain; + sort_ref m_range; + constructor* m_constructor; + public: + accessor(ast_manager& m, symbol const& n): + m(m), + m_name(n), + m_domain(m), + m_range(m) + {} + sort* range() const { return m_range; } + symbol const& name() const { return m_name; } + func_decl_ref instantiate(sort_ref_vector const& ps) const; + func_decl_ref instantiate(sort* dt) const; + void attach(constructor* d) { m_constructor = d; } + constructor const& get_constructor() const { return *m_constructor; } + def const& get_def() const; + util& u() const; + }; + + class constructor { + ast_manager& m; + symbol m_name; + vector m_accessors; + def* m_def; + public: + constructor(ast_manager& m, symbol n): m(m), m_name(n) {} + void add(accessor& a) { m_accessors.push_back(a); a.attach(this); } + symbol const& name() const { return m_name; } + vector const& accessors() const { return m_accessors; } + vector::const_iterator begin() const { return m_accessors.begin(); } + vector::const_iterator end() const { return m_accessors.end(); } + func_decl_ref instantiate(sort_ref_vector const& ps) const; + func_decl_ref instantiate(sort* dt) const; + void attach(def* d) { m_def = d; } + def const& get_def() const { return *m_def; } + util& u() const; + }; + + class def { + ast_manager& m; + util& m_util; + symbol m_name; + unsigned m_class_id; + sort_ref_vector m_params; + mutable sort_ref m_sort; + vector m_constructors; + public: + def(ast_manager& m, util& u, symbol const& n, unsigned class_id, unsigned num_params, sort * const* params): + m(m), + m_util(u), + m_name(n), + m_class_id(class_id), + m_params(m, num_params, params), + m_sort(m) + {} + void add(constructor& c) { + m_constructors.push_back(c); + c.attach(this); + } + symbol const& name() const { return m_name; } + unsigned id() const { return m_class_id; } + sort_ref instantiate(sort_ref_vector const& ps) const; + vector const& constructors() const { return m_constructors; } + vector::const_iterator begin() const { return m_constructors.begin(); } + vector::const_iterator end() const { return m_constructors.end(); } + sort_ref_vector const& params() const { return m_params; } + util& u() const { return m_util; } + }; + + namespace decl { + + class plugin : public decl_plugin { + mutable scoped_ptr m_util; + map m_defs; + svector m_def_block; + unsigned m_class_id; + util & u() const; + public: + plugin(): m_class_id(0) {} + virtual ~plugin(); + + virtual void finalize(); + + virtual decl_plugin * mk_fresh() { return alloc(plugin); } + + virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters); + + virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + virtual expr * get_some_value(sort * s); + + virtual bool is_fully_interp(sort * s) const; + + virtual bool is_value(app* e) const; + + virtual bool is_unique_value(app * e) const { return is_value(e); } + + virtual void get_op_names(svector & op_names, symbol const & logic); + + void begin_def_block() { m_class_id++; m_def_block.reset(); } + + void end_def_block(); + + def& add(symbol const& name, unsigned n, sort * const * params); + + void del(symbol const& d); + + def const& get_def(sort* s) const { def* d = 0; VERIFY(m_defs.find(datatype_name(s), d)); return *d; } + + private: + bool is_value_visit(expr * arg, ptr_buffer & todo) const; + + func_decl * mk_update_field( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + func_decl * mk_constructor( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + func_decl * mk_accessor( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + func_decl * mk_recognizer( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + symbol datatype_name(sort * s) const { + //SASSERT(u().is_datatype(s)); + return s->get_parameter(0).get_symbol(); + } + + }; + } + + class util { + ast_manager & m; + family_id m_family_id; + mutable decl::plugin* m_plugin; + + + func_decl * get_constructor(sort * ty, unsigned c_id) const; + + obj_map *> m_datatype2constructors; + obj_map m_datatype2nonrec_constructor; + obj_map *> m_constructor2accessors; + obj_map m_constructor2recognizer; + obj_map m_recognizer2constructor; + obj_map m_accessor2constructor; + obj_map m_is_recursive; + obj_map m_is_enum; + mutable obj_map m_is_fully_interp; + mutable ast_ref_vector m_asts; + ptr_vector > m_vectors; + unsigned m_start; + mutable ptr_vector m_fully_interp_trail; + + func_decl * get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set); + func_decl * get_constructor(sort * ty, unsigned c_id); + + friend class decl::plugin; + + bool is_recursive_core(sort * s) const; + sort_size get_datatype_size(sort* s0); + bool is_well_founded(unsigned num_types, sort* const* sorts); + def const& get_def(sort* s) const; + void get_subsorts(sort* s, ptr_vector& sorts) const; + + public: + util(ast_manager & m); + ~util(); + ast_manager & get_manager() const { return m; } + bool is_datatype(sort const* s) const { return is_sort_of(s, m_family_id, DATATYPE_SORT); } + bool is_enum_sort(sort* s); + bool is_recursive(sort * ty); + bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); } + bool is_recognizer(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); } + bool is_update_field(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_UPDATE_FIELD); } + bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); } + bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } + bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } + ptr_vector const & get_datatype_constructors(sort * ty); + unsigned get_datatype_num_constructors(sort * ty); + unsigned get_datatype_num_parameter_sorts(sort * ty); + sort* get_datatype_parameter_sort(sort * ty, unsigned idx); + func_decl * get_non_rec_constructor(sort * ty); + func_decl * get_constructor_recognizer(func_decl * constructor); + ptr_vector const & get_constructor_accessors(func_decl * constructor); + func_decl * get_accessor_constructor(func_decl * accessor); + func_decl * get_recognizer_constructor(func_decl * recognizer); + family_id get_family_id() const { return m_family_id; } + bool are_siblings(sort * s1, sort * s2); + bool is_func_decl(op_kind k, unsigned num_params, parameter const* params, func_decl* f); + bool is_constructor_of(unsigned num_params, parameter const* params, func_decl* f); + void reset(); + void display_datatype(sort *s, std::ostream& strm); + bool is_fully_interp(sort * s) const; + sort_ref_vector datatype_params(sort * s) const; + }; + +}; + +#endif /* DATATYPE_DECL_PLUGIN_H_ */ + diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 4dfd69ddd..c1ef61938 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -35,6 +35,7 @@ void arith_rewriter::updt_local_params(params_ref const & _p) { m_mul2power = p.mul_to_power(); m_elim_rem = p.elim_rem(); m_expand_tan = p.expand_tan(); + m_expand_eqs = p.expand_eqs(); set_sort_sums(p.sort_sums()); } @@ -454,7 +455,20 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin st = BR_DONE; } } - if (st == BR_DONE && arg1 == orig_arg1 && arg2 == orig_arg2) { + if (kind == EQ && m_expand_eqs) { + result = m().mk_and(m_util.mk_le(arg1, arg2), m_util.mk_ge(arg1, arg2)); + return BR_REWRITE2; + } + else if (is_numeral(arg2, a2) && is_neg_poly(arg1, new_arg1)) { + a2.neg(); + new_arg2 = m_util.mk_numeral(a2, m_util.is_int(new_arg1)); + switch (kind) { + case LE: result = m_util.mk_ge(new_arg1, new_arg2); return BR_DONE; + case GE: result = m_util.mk_le(new_arg1, new_arg2); return BR_DONE; + case EQ: result = m_util.mk_eq(new_arg1, new_arg2); return BR_DONE; + } + } + else if (st == BR_DONE && arg1 == orig_arg1 && arg2 == orig_arg2) { // Nothing new; return BR_FAILED to avoid rewriting loops. return BR_FAILED; } @@ -494,6 +508,56 @@ br_status arith_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result return mk_le_ge_eq_core(arg1, arg2, EQ, result); } +expr_ref arith_rewriter::neg_monomial(expr* e) const { + expr_ref_vector args(m()); + rational a1; + if (is_app(e) & m_util.is_mul(e)) { + if (is_numeral(to_app(e)->get_arg(0), a1)) { + if (!a1.is_minus_one()) { + args.push_back(m_util.mk_numeral(-a1, m_util.is_int(e))); + } + args.append(to_app(e)->get_num_args() - 1, to_app(e)->get_args() + 1); + } + else { + args.push_back(m_util.mk_numeral(rational(-1), m_util.is_int(e))); + args.append(to_app(e)->get_num_args(), to_app(e)->get_args()); + } + } + else { + args.push_back(m_util.mk_numeral(rational(-1), m_util.is_int(e))); + args.push_back(e); + } + if (args.size() == 1) { + return expr_ref(args.back(), m()); + } + else { + return expr_ref(m_util.mk_mul(args.size(), args.c_ptr()), m()); + } +} + +bool arith_rewriter::is_neg_poly(expr* t, expr_ref& neg) const { + rational r; + if (m_util.is_mul(t) && is_numeral(to_app(t)->get_arg(0), r) && r.is_neg()) { + neg = neg_monomial(t); + return true; + } + + if (!m_util.is_add(t)) { + return false; + } + expr * t2 = to_app(t)->get_arg(0); + + if (m_util.is_mul(t2) && is_numeral(to_app(t2)->get_arg(0), r) && r.is_neg()) { + expr_ref_vector args1(m()); + for (expr* e1 : *to_app(t)) { + args1.push_back(neg_monomial(e1)); + } + neg = m_util.mk_add(args1.size(), args1.c_ptr()); + return true; + } + return false; +} + bool arith_rewriter::is_anum_simp_target(unsigned num_args, expr * const * args) { if (!m_anum_simp) return false; diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index 5d9fb1d66..352cb5a6c 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -55,6 +55,7 @@ class arith_rewriter : public poly_rewriter { bool m_push_to_real; bool m_anum_simp; bool m_elim_rem; + bool m_expand_eqs; unsigned m_max_degree; void get_coeffs_gcd(expr * t, numeral & g, bool & first, unsigned & num_consts); @@ -88,6 +89,8 @@ class arith_rewriter : public poly_rewriter { bool is_2_pi_integer_offset(expr * t, expr * & m); bool is_pi_integer(expr * t); bool is_pi_integer_offset(expr * t, expr * & m); + bool is_neg_poly(expr* e, expr_ref& neg) const; + expr_ref neg_monomial(expr * e) const; expr * mk_sin_value(rational const & k); app * mk_sqrt(rational const & k); diff --git a/src/ast/rewriter/arith_rewriter_params.pyg b/src/ast/rewriter/arith_rewriter_params.pyg index 8a41d838d..94ada1b6d 100644 --- a/src/ast/rewriter/arith_rewriter_params.pyg +++ b/src/ast/rewriter/arith_rewriter_params.pyg @@ -12,4 +12,5 @@ def_module_params(module_name='rewriter', ("arith_lhs", BOOL, False, "all monomials are moved to the left-hand-side, and the right-hand-side is just a constant."), ("elim_to_real", BOOL, False, "eliminate to_real from arithmetic predicates that contain only integers."), ("push_to_real", BOOL, True, "distribute to_real over * and +."), + ("expand_eqs", BOOL, False, "expand equalities into two inequalities"), ("elim_rem", BOOL, False, "replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y)))."))) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 6ecf26bd8..fb2004c77 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -123,6 +123,8 @@ void asserted_formulas::set_eliminate_and(bool flag) { p.set_bool("arith_lhs", true); p.set_bool("sort_sums", true); p.set_bool("rewrite_patterns", true); + p.set_bool("expand_eqs", m_params.m_arith_expand_eqs); + p.set_bool("gcd_rounding", true); m_rewriter.updt_params(p); flush_cache(); } diff --git a/src/smt/params/theory_arith_params.cpp b/src/smt/params/theory_arith_params.cpp index ab80f0c67..9b8aa9b81 100644 --- a/src/smt/params/theory_arith_params.cpp +++ b/src/smt/params/theory_arith_params.cpp @@ -18,6 +18,7 @@ Revision History: --*/ #include "smt/params/theory_arith_params.h" #include "smt/params/smt_params_helper.hpp" +#include "ast/rewriter/arith_rewriter_params.hpp" void theory_arith_params::updt_params(params_ref const & _p) { smt_params_helper p(_p); @@ -36,6 +37,8 @@ void theory_arith_params::updt_params(params_ref const & _p) { m_arith_bound_prop = static_cast(p.arith_propagation_mode()); m_arith_dump_lemmas = p.arith_dump_lemmas(); m_arith_reflect = p.arith_reflect(); + arith_rewriter_params ap(_p); + m_arith_expand_eqs = ap.expand_eqs(); } diff --git a/src/smt/theory_datatype.cpp b/src/smt/theory_datatype.cpp index 806d6706b..beb1acf63 100644 --- a/src/smt/theory_datatype.cpp +++ b/src/smt/theory_datatype.cpp @@ -437,10 +437,7 @@ namespace smt { ctx.set_conflict(ctx.mk_justification(ext_theory_conflict_justification(get_id(), r, 0, 0, m_used_eqs.size(), m_used_eqs.c_ptr()))); TRACE("occurs_check", tout << "occurs_check: true\n"; - enode_pair_vector::const_iterator it = m_used_eqs.begin(); - enode_pair_vector::const_iterator end = m_used_eqs.end(); - for(; it != end; ++it) { - enode_pair const & p = *it; + for (enode_pair const& p : m_used_eqs) { tout << "eq: #" << p.first->get_owner_id() << " #" << p.second->get_owner_id() << "\n"; tout << mk_bounded_pp(p.first->get_owner(), get_manager()) << " " << mk_bounded_pp(p.second->get_owner(), get_manager()) << "\n"; }); @@ -613,11 +610,9 @@ namespace smt { d1->m_constructor = d2->m_constructor; } } - ptr_vector::iterator it = d2->m_recognizers.begin(); - ptr_vector::iterator end = d2->m_recognizers.end(); - for (; it != end; ++it) - if (*it) - add_recognizer(v1, *it); + for (enode* e : d2->m_recognizers) + if (e) + add_recognizer(v1, e); } void theory_datatype::unmerge_eh(theory_var v1, theory_var v2) { diff --git a/src/util/symbol_table.h b/src/util/symbol_table.h index ea848d991..818cb7584 100644 --- a/src/util/symbol_table.h +++ b/src/util/symbol_table.h @@ -182,29 +182,20 @@ public: } void append(symbol_table const& other) { - typename sym_table::iterator it = other.m_sym_table.begin(); - typename sym_table::iterator end = other.m_sym_table.end(); - - for (; it != end; ++it) { - insert((*it).m_key, (*it).m_data); + for (auto const& kv : other.m_sym_table) { + insert(kv.m_key, kv.m_data); } } void get_range(vector& range) const { - typename sym_table::iterator it = m_sym_table.begin(); - typename sym_table::iterator end = m_sym_table.end(); - - for (; it != end; ++it) { - range.push_back((*it).m_data); + for (auto kv : m_sym_table) { + range.push_back(kv.m_data); } } void get_dom(svector& dom) const { - typename sym_table::iterator it = m_sym_table.begin(); - typename sym_table::iterator end = m_sym_table.end(); - - for (; it != end; ++it) { - dom.push_back((*it).m_key); + for (auto kv : m_sym_table) { + dom.push_back(kv.m_key); } } }; From 7fbb93847414c166db8b4c694d98c4727382adcc Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 12:00:02 -0700 Subject: [PATCH 236/488] working on parametric datatype redo Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.cpp | 184 ++++++++++++++++++++---------- src/ast/datatype_decl_plugin2.h | 101 +++++++++++++++- src/cmd_context/pdecl.cpp | 119 +++++++------------ src/cmd_context/pdecl.h | 14 --- 4 files changed, 266 insertions(+), 152 deletions(-) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 4e60abcce..0030af609 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -15,14 +15,13 @@ Author: Revision History: - // compute sort sizes and insert them. - // have a notion of pre-sort or just attach sort size after declaration. - --*/ -#include "ast/datatype_decl_plugin2.h" #include "util/warning.h" +#include "ast/datatype_decl_plugin2.h" +#include "ast/array_decl_plugin.h" #include "ast/ast_smt2_pp.h" + namespace datatype { func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const { @@ -78,6 +77,32 @@ namespace datatype { BLACK }; + namespace param_size { + size* size::mk_offset(sort_size const& s) { return alloc(offset, s); } + size* size::mk_param(sort_ref& p) { return alloc(sparam, p); } + size* size::mk_plus(size* a1, size* a2) { return alloc(plus, a1, a2); } + size* size::mk_times(size* a1, size* a2) { return alloc(times, a1, a2); } + size* size::mk_times(ptr_vector& szs) { + if (szs.empty()) return mk_offset(sort_size(1)); + if (szs.size() == 1) return szs[0]; + size* r = szs[0]; + for (unsigned i = 1; i < szs.size(); ++i) { + r = mk_times(r, szs[i]); + } + return r; + } + size* size::mk_plus(ptr_vector& szs) { + if (szs.empty()) return mk_offset(sort_size(0)); + if (szs.size() == 1) return szs[0]; + size* r = szs[0]; + for (unsigned i = 1; i < szs.size(); ++i) { + r = mk_plus(r, szs[i]); + } + return r; + } + size* size::mk_power(size* a1, size* a2) { return alloc(power, a1, a2); } + } + namespace decl { plugin::~plugin() { @@ -125,9 +150,16 @@ namespace datatype { sort* s = m_manager->mk_sort(name.get_symbol(), sort_info(m_family_id, k, num_parameters, parameters, true)); - // compute datatype size - sort_size ts = u().get_datatype_size(s); - s->set_num_elements(ts); + def* d = 0; + if (m_defs.find(s->get_name(), d) && d->sort_size()) { + obj_map S; + for (unsigned i = 1; i < num_parameters; ++i) { + sort* r = to_sort(parameters[i].get_ast()); + S.insert(d->params()[i], r->get_num_elements()); + } + sort_size ts = d->sort_size()->fold(S); + s->set_num_elements(ts); + } return s; } catch (invalid_datatype) { @@ -256,6 +288,7 @@ namespace datatype { if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) { m_manager->raise_exception("datatype is not well-founded"); } + u().compute_datatype_size_functions(m_def_block); } void plugin::del(symbol const& s) { @@ -418,84 +451,111 @@ namespace datatype { } return false; } + + unsigned util::get_datatype_num_parameter_sorts(sort * ty) { + SASSERT(ty->get_num_parameters() >= 1); + return ty->get_num_parameters() - 1; + } + + sort* util::get_datatype_parameter_sort(sort * ty, unsigned idx) { + SASSERT(idx < get_datatype_num_parameter_sorts(ty)); + return to_sort(ty->get_parameter(idx+1).get_ast()); + } + + param_size::size* util::get_sort_size(sort_ref_vector const& params, sort* s) { + if (params.empty()) { + return param_size::size::mk_offset(s->get_num_elements()); + } + if (is_datatype(s)) { + param_size::size* sz; + obj_map S; + unsigned n = get_datatype_num_parameter_sorts(s); + for (unsigned i = 0; i < n; ++i) { + sort* ps = get_datatype_parameter_sort(s, i); + sz = get_sort_size(params, ps); + sz->inc_ref(); + S.insert(ps, sz); + } + def & d = get_def(s->get_name()); + sz = d.sort_size()->subst(S); + for (auto & kv : S) { + kv.m_value->dec_ref(); + } + return sz; + } + array_util autil(m); + if (autil.is_array(s)) { + unsigned n = get_array_arity(s); + ptr_vector szs; + for (unsigned i = 0; i < n; ++i) { + szs.push_back(get_sort_size(params, get_array_domain(s, i))); + } + param_size::size* sz1 = param_size::size::mk_times(szs); + param_size::size* sz2 = get_sort_size(params, get_array_range(s)); + return param_size::size::mk_power(sz2, sz1); + } + for (sort* p : params) { + if (s == p) return param_size::size::mk_param(sort_ref(s, m)); + } + return param_size::size::mk_offset(s->get_num_elements()); + } - /** - \brief Return the size of the inductive datatype. - Pre-condition: The given argument constains the parameters of an inductive datatype. - */ - sort_size util::get_datatype_size(sort* s0) { - obj_map already_found; - obj_map szs; - ptr_vector todo; - todo.push_back(s0); + void util::compute_datatype_size_functions(svector const& names) { + map already_found; + map szs; + + svector todo(names); status st; while (!todo.empty()) { - sort* s = todo.back(); + symbol s = todo.back(); if (already_found.find(s, st) && st == BLACK) { todo.pop_back(); continue; } already_found.insert(s, GRAY); - bool is_very_big = false; - bool can_process = true; - def const& d = get_def(s); + bool is_infinite = false; + bool can_process = true; + def& d = get_def(s); for (constructor const& c : d) { for (accessor const& a : c) { - func_decl_ref ac = a.instantiate(s); - sort* r = ac->get_range(); + sort* r = a.range(); if (is_datatype(r)) { - if (already_found.find(r, st)) { + symbol s2 = r->get_name(); + if (already_found.find(s2, st)) { // type is infinite - if (st == GRAY) return sort_size(); + if (st == GRAY) { + is_infinite = true; + } } - else { - todo.push_back(r); + else if (names.contains(s2)) { + todo.push_back(s2); can_process = false; } } - else if (r->is_infinite()) { - // type is infinite - return sort_size(); - } - else if (r->is_very_big()) { - is_very_big = true; - } } } + if (!can_process) { + continue; + } + todo.pop_back(); + already_found.insert(s, BLACK); + if (is_infinite) { + d.set_sort_size(param_size::size::mk_offset(sort_size::mk_infinite())); + continue; + } - if (can_process) { - todo.pop_back(); - already_found.insert(s, BLACK); - if (is_very_big) { - szs.insert(s, sort_size::mk_very_big()); - } - else { - // the type is not infinite nor the number of elements is infinite... - // computing the number of elements - rational num; - def const& d = get_def(s); - for (constructor const& c : d) { - rational c_num(1); - for (accessor const& a : c) { - func_decl_ref ac = a.instantiate(s); - sort* r = ac->get_range(); - if (szs.contains(r)) { - c_num *= rational(szs[r].size(), rational::ui64()); - } - else { - SASSERT(!r->is_infinite() && !r->is_very_big()); - c_num *= rational(r->get_num_elements().size(), rational::ui64()); - } - } - num += c_num; - } - szs.insert(s, sort_size(num)); + ptr_vector s_add; + for (constructor const& c : d) { + ptr_vector s_mul; + for (accessor const& a : c) { + s_mul.push_back(get_sort_size(d.params(), a.range())); } + s_add.push_back(param_size::size::mk_times(s_mul)); } + d.set_sort_size(param_size::size::mk_plus(s_add)); } - return szs[s0]; } - + /** \brief Return true if the inductive datatype is well-founded. diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index fad7ff174..a4a76f346 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -85,11 +85,100 @@ namespace datatype { util& u() const; }; + namespace param_size { + class size { + unsigned m_ref; + public: + size(): m_ref(0) {} + virtual ~size() {} + void inc_ref() { ++m_ref; } + void dec_ref() { --m_ref; if (m_ref == 0) dealloc(this); } + static size* mk_offset(sort_size const& s); + static size* mk_param(sort_ref& p); + static size* mk_plus(size* a1, size* a2); + static size* mk_times(size* a1, size* a2); + static size* mk_plus(ptr_vector& szs); + static size* mk_times(ptr_vector& szs); + static size* mk_power(size* a1, size* a2); + + virtual size* subst(obj_map& S) = 0; + virtual sort_size fold(obj_map const& S) = 0; + + }; + struct offset : public size { + sort_size m_offset; + offset(sort_size const& s): m_offset(s) {} + virtual ~offset() {} + virtual size* subst(obj_map& S) { return this; } + virtual sort_size fold(obj_map const& S) { return m_offset; } + }; + struct plus : public size { + size* m_arg1, *m_arg2; + plus(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref();} + virtual ~plus() { m_arg1->dec_ref(); m_arg2->dec_ref(); } + virtual size* subst(obj_map& S) { return mk_plus(m_arg1->subst(S), m_arg2->subst(S)); } + virtual sort_size fold(obj_map const& S) { + sort_size s1 = m_arg1->fold(S); + sort_size s2 = m_arg2->fold(S); + if (s1.is_infinite()) return s1; + if (s2.is_infinite()) return s2; + if (s1.is_very_big()) return s1; + if (s2.is_very_big()) return s2; + rational r = rational(s1.size(), rational::ui64()) + rational(s2.size(), rational::ui64()); + return sort_size(r); + } + }; + struct times : public size { + size* m_arg1, *m_arg2; + times(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } + virtual ~times() { m_arg1->dec_ref(); m_arg2->dec_ref(); } + virtual size* subst(obj_map& S) { return mk_times(m_arg1->subst(S), m_arg2->subst(S)); } + virtual sort_size fold(obj_map const& S) { + sort_size s1 = m_arg1->fold(S); + sort_size s2 = m_arg2->fold(S); + if (s1.is_infinite()) return s1; + if (s2.is_infinite()) return s2; + if (s1.is_very_big()) return s1; + if (s2.is_very_big()) return s2; + rational r = rational(s1.size(), rational::ui64()) * rational(s2.size(), rational::ui64()); + return sort_size(r); + } + }; + struct power : public size { + size* m_arg1, *m_arg2; + power(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } + virtual ~power() { m_arg1->dec_ref(); m_arg2->dec_ref(); } + virtual size* subst(obj_map& S) { return mk_power(m_arg1->subst(S), m_arg2->subst(S)); } + virtual sort_size fold(obj_map const& S) { + sort_size s1 = m_arg1->fold(S); + sort_size s2 = m_arg2->fold(S); + // s1^s2 + if (s1.is_infinite()) return s1; + if (s2.is_infinite()) return s2; + if (s1.is_very_big()) return s1; + if (s2.is_very_big()) return s2; + if (s1.size() == 1) return s1; + if (s2.size() == 1) return s1; + if (s1.size() > (2 << 20) || s2.size() > 10) return sort_size::mk_very_big(); + rational r = ::power(rational(s1.size(), rational::ui64()), static_cast(s2.size())); + return sort_size(r); + } + }; + struct sparam : public size { + sort_ref m_param; + sparam(sort_ref& p): m_param(p) {} + virtual ~sparam() {} + virtual size* subst(obj_map& S) { return S[m_param]; } + virtual sort_size fold(obj_map const& S) { return S[m_param]; } + }; + }; + class def { ast_manager& m; util& m_util; symbol m_name; unsigned m_class_id; + param_size::size* m_sort_size; sort_ref_vector m_params; mutable sort_ref m_sort; vector m_constructors; @@ -99,9 +188,13 @@ namespace datatype { m_util(u), m_name(n), m_class_id(class_id), + m_sort_size(0), m_params(m, num_params, params), m_sort(m) {} + ~def() { + if (m_sort_size) m_sort_size->dec_ref(); + } void add(constructor& c) { m_constructors.push_back(c); c.attach(this); @@ -114,6 +207,8 @@ namespace datatype { vector::const_iterator end() const { return m_constructors.end(); } sort_ref_vector const& params() const { return m_params; } util& u() const { return m_util; } + param_size::size* sort_size() { return m_sort_size; } + void set_sort_size(param_size::size* p) { m_sort_size = p; p->inc_ref(); } }; namespace decl { @@ -155,7 +250,8 @@ namespace datatype { void del(symbol const& d); - def const& get_def(sort* s) const { def* d = 0; VERIFY(m_defs.find(datatype_name(s), d)); return *d; } + def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); } + def& get_def(symbol const& s) { return *(m_defs[s]); } private: bool is_value_visit(expr * arg, ptr_buffer & todo) const; @@ -213,8 +309,11 @@ namespace datatype { bool is_recursive_core(sort * s) const; sort_size get_datatype_size(sort* s0); + void compute_datatype_size_functions(svector const& names); + param_size::size* get_sort_size(sort_ref_vector const& params, sort* s); bool is_well_founded(unsigned num_types, sort* const* sorts); def const& get_def(sort* s) const; + def& get_def(symbol const& s) { return m_plugin->get_def(s); } void get_subsorts(sort* s, ptr_vector& sorts) const; public: diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 983dbbc78..88ab9f8b8 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -39,15 +39,13 @@ public: } else { SASSERT(m_const == 0); - obj_map::iterator it = m_map.begin(); - obj_map::iterator end = m_map.end(); - for (; it != end; ++it) { - m.m().dec_ref((*it).m_key); + for (auto kv : m_map) { + m.m().dec_ref(kv.m_key); if (m_num_params == 1) { - m.m().dec_ref(static_cast((*it).m_value)); + m.m().dec_ref(static_cast(kv.m_value)); } else { - psort_inst_cache * child = static_cast((*it).m_value); + psort_inst_cache * child = static_cast(kv.m_value); child->finalize(m); child->~psort_inst_cache(); m.a().deallocate(sizeof(psort_inst_cache), child); @@ -485,20 +483,16 @@ void pconstructor_decl::finalize(pdecl_manager & m) { } bool pconstructor_decl::has_missing_refs(symbol & missing) const { - ptr_vector::const_iterator it = m_accessors.begin(); - ptr_vector::const_iterator end = m_accessors.end(); - for (; it != end; ++it) { - if ((*it)->has_missing_refs(missing)) + for (paccessor_decl* a : m_accessors) { + if (a->has_missing_refs(missing)) return true; } return false; } bool pconstructor_decl::fix_missing_refs(dictionary const & symbol2idx, symbol & missing) { - ptr_vector::iterator it = m_accessors.begin(); - ptr_vector::iterator end = m_accessors.end(); - for (; it != end; ++it) { - if (!(*it)->fix_missing_refs(symbol2idx, missing)) + for (paccessor_decl* a : m_accessors) { + if (!a->fix_missing_refs(symbol2idx, missing)) return false; } return true; @@ -506,20 +500,16 @@ bool pconstructor_decl::fix_missing_refs(dictionary const & symbol2idx, sym constructor_decl * pconstructor_decl::instantiate_decl(pdecl_manager & m, sort * const * s) { ptr_buffer as; - ptr_vector::iterator it = m_accessors.begin(); - ptr_vector::iterator end = m_accessors.end(); - for (; it != end; ++it) - as.push_back((*it)->instantiate_decl(m, s)); + for (paccessor_decl* a : m_accessors) + as.push_back(a->instantiate_decl(m, s)); return mk_constructor_decl(m_name, m_recogniser_name, as.size(), as.c_ptr()); } void pconstructor_decl::display(std::ostream & out, pdatatype_decl const * const * dts) const { out << "(" << m_name; - ptr_vector::const_iterator it = m_accessors.begin(); - ptr_vector::const_iterator end = m_accessors.end(); - for (; it != end; ++it) { + for (paccessor_decl* a : m_accessors) { out << " "; - (*it)->display(out, dts); + a->display(out, dts); } out << ")"; } @@ -538,23 +528,17 @@ void pdatatype_decl::finalize(pdecl_manager & m) { } bool pdatatype_decl::has_missing_refs(symbol & missing) const { - ptr_vector::const_iterator it = m_constructors.begin(); - ptr_vector::const_iterator end = m_constructors.end(); - for (; it != end; ++it) { - if ((*it)->has_missing_refs(missing)) + for (auto c : m_constructors) + if (c->has_missing_refs(missing)) return true; - } return false; } bool pdatatype_decl::has_duplicate_accessors(symbol & duplicated) const { hashtable names; - ptr_vector::const_iterator it = m_constructors.begin(); - ptr_vector::const_iterator end = m_constructors.end(); - for (; it != end; ++it) { - ptr_vector const& acc = (*it)->m_accessors; - for (unsigned i = 0; i < acc.size(); ++i) { - symbol const& name = acc[i]->get_name(); + for (auto c : m_constructors) { + for (auto a : c->m_accessors) { + symbol const& name = a->get_name(); if (names.contains(name)) { duplicated = name; return true; @@ -567,10 +551,8 @@ bool pdatatype_decl::has_duplicate_accessors(symbol & duplicated) const { bool pdatatype_decl::fix_missing_refs(dictionary const & symbol2idx, symbol & missing) { - ptr_vector::iterator it = m_constructors.begin(); - ptr_vector::iterator end = m_constructors.end(); - for (; it != end; ++it) { - if (!(*it)->fix_missing_refs(symbol2idx, missing)) + for (auto c : m_constructors) { + if (!c->fix_missing_refs(symbol2idx, missing)) return false; } return true; @@ -578,10 +560,8 @@ bool pdatatype_decl::fix_missing_refs(dictionary const & symbol2idx, symbol datatype_decl * pdatatype_decl::instantiate_decl(pdecl_manager & m, sort * const * s) { ptr_buffer cs; - ptr_vector::iterator it = m_constructors.begin(); - ptr_vector::iterator end = m_constructors.end(); - for (; it != end; ++it) { - cs.push_back((*it)->instantiate_decl(m, s)); + for (auto c : m_constructors) { + cs.push_back(c->instantiate_decl(m, s)); } return mk_datatype_decl(m_name, cs.size(), cs.c_ptr()); } @@ -624,17 +604,16 @@ sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * void pdatatype_decl::display(std::ostream & out) const { out << "(declare-datatype " << m_name; display_sort_args(out, m_num_params); - ptr_vector::const_iterator it = m_constructors.begin(); - ptr_vector::const_iterator end = m_constructors.end(); - for (bool first = true; it != end; ++it) { + bool first = true; + for (auto c : m_constructors) { if (!first) out << " "; if (m_parent) { - (*it)->display(out, m_parent->children()); + c->display(out, m_parent->children()); } else { pdatatype_decl const * dts[1] = { this }; - (*it)->display(out, dts); + c->display(out, dts); } first = false; } @@ -647,11 +626,9 @@ pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager m_datatypes(num_datatypes, dts) { m.inc_ref(num_datatypes, dts); - ptr_vector::iterator it = m_datatypes.begin(); - ptr_vector::iterator end = m_datatypes.end(); - for (; it != end; ++it) { - SASSERT((*it)->m_parent == 0); - (*it)->m_parent = this; + for (auto d : m_datatypes) { + SASSERT(d->m_parent == 0); + d->m_parent = this; } } @@ -662,36 +639,30 @@ void pdatatypes_decl::finalize(pdecl_manager & m) { bool pdatatypes_decl::fix_missing_refs(symbol & missing) { TRACE("fix_missing_refs", tout << "pdatatypes_decl::fix_missing_refs\n";); dictionary symbol2idx; - ptr_vector::iterator it = m_datatypes.begin(); - ptr_vector::iterator end = m_datatypes.end(); - for (unsigned idx = 0; it != end; ++it, ++idx) - symbol2idx.insert((*it)->get_name(), idx); - - it = m_datatypes.begin(); - for (unsigned idx = 0; it != end; ++it, ++idx) { - if (!(*it)->fix_missing_refs(symbol2idx, missing)) + int idx = 0; + for (pdatatype_decl* d : m_datatypes) + symbol2idx.insert(d->get_name(), idx++); + for (pdatatype_decl* d : m_datatypes) + if (!d->fix_missing_refs(symbol2idx, missing)) return false; - } return true; } bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) { datatype_decl_buffer dts; - ptr_vector::iterator it = m_datatypes.begin(); - ptr_vector::iterator end = m_datatypes.end(); - for (; it != end; ++it) { - dts.m_buffer.push_back((*it)->instantiate_decl(m, s)); + for (auto d : m_datatypes) { + dts.m_buffer.push_back(d->instantiate_decl(m, s)); } sort_ref_vector sorts(m.m()); bool is_ok = m.get_dt_plugin()->mk_datatypes(dts.m_buffer.size(), dts.m_buffer.c_ptr(), m_num_params, s, sorts); if (!is_ok) return false; - it = m_datatypes.begin(); - for (unsigned i = 0; it != end; ++it, ++i) { - sort * new_dt = sorts.get(i); - (*it)->cache(m, s, new_dt); - m.save_info(new_dt, *it, m_num_params, s); - m.notify_new_dt(new_dt, *it); + unsigned i = 0; + for (auto d : m_datatypes) { + sort * new_dt = sorts.get(i++); + d->cache(m, s, new_dt); + m.save_info(new_dt, d, m_num_params, s); + m.notify_new_dt(new_dt, d); } return true; } @@ -965,11 +936,9 @@ void pdecl_manager::save_info(sort * s, psort_decl * d, unsigned num_indices, un } void pdecl_manager::reset_sort_info() { - obj_map::iterator it = m_sort2info.begin(); - obj_map::iterator end = m_sort2info.end(); - for (; it != end; ++it) { - sort * s = (*it).m_key; - sort_info * info = (*it).m_value; + for (auto kv : m_sort2info) { + sort * s = kv.m_key; + sort_info * info = kv.m_value; m().dec_ref(s); unsigned sz = info->obj_size(); info->finalize(*this); diff --git a/src/cmd_context/pdecl.h b/src/cmd_context/pdecl.h index 2dfbb93ae..1d7203197 100644 --- a/src/cmd_context/pdecl.h +++ b/src/cmd_context/pdecl.h @@ -134,20 +134,6 @@ public: virtual void display(std::ostream & out) const; }; -#if 0 -class psort_dt_decl : public psort_decl { -protected: - friend class pdecl_manager; - psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n); - virtual size_t obj_size() const { return sizeof(psort_dt_decl); } - virtual void finalize(pdecl_manager & m); - virtual ~psort_dt_decl() {} -public: - virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s); - virtual void display(std::ostream & out) const; -}; -#endif - class datatype_decl_plugin; class datatype_decl; class constructor_decl; From c6722859c271723760b20188bf75a6201ad33af7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 14:36:03 -0700 Subject: [PATCH 237/488] update rewriting of equalities and monomials for regressions Signed-off-by: Nikolaj Bjorner --- src/ast/justified_expr.h | 4 +- src/ast/rewriter/arith_rewriter.cpp | 20 +++--- src/ast/rewriter/arith_rewriter.h | 4 +- src/ast/rewriter/arith_rewriter_params.pyg | 1 - src/ast/rewriter/bv_rewriter.cpp | 1 + src/ast/rewriter/poly_rewriter.h | 9 ++- src/ast/rewriter/poly_rewriter_def.h | 71 ++++++++++++------- src/cmd_context/cmd_context.cpp | 79 +++++++--------------- src/smt/asserted_formulas.cpp | 8 ++- 9 files changed, 102 insertions(+), 95 deletions(-) diff --git a/src/ast/justified_expr.h b/src/ast/justified_expr.h index 49362940d..8aa961686 100644 --- a/src/ast/justified_expr.h +++ b/src/ast/justified_expr.h @@ -21,12 +21,12 @@ public: justified_expr& operator=(justified_expr const& other) { SASSERT(&m == &other.m); if (this != &other) { + m.inc_ref(other.get_fml()); + m.inc_ref(other.get_proof()); m.dec_ref(m_fml); m.dec_ref(m_proof); m_fml = other.get_fml(); m_proof = other.get_proof(); - m.inc_ref(m_fml); - m.inc_ref(m_proof); } return *this; } diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index c1ef61938..b630cdff6 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -26,7 +26,6 @@ void arith_rewriter::updt_local_params(params_ref const & _p) { arith_rewriter_params p(_p); m_arith_lhs = p.arith_lhs(); m_gcd_rounding = p.gcd_rounding(); - m_eq2ineq = p.eq2ineq(); m_elim_to_real = p.elim_to_real(); m_push_to_real = p.push_to_real(); m_anum_simp = p.algebraic_number_evaluator(); @@ -371,7 +370,7 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin if ((is_zero(arg1) && is_reduce_power_target(arg2, kind == EQ)) || (is_zero(arg2) && is_reduce_power_target(arg1, kind == EQ))) return reduce_power(arg1, arg2, kind, result); - br_status st = cancel_monomials(arg1, arg2, m_arith_lhs, new_arg1, new_arg2); + br_status st = cancel_monomials(arg1, arg2, true, new_arg1, new_arg2); TRACE("mk_le_bug", tout << "st: " << st << " " << new_arg1 << " " << new_arg2 << "\n";); if (st != BR_FAILED) { arg1 = new_arg1; @@ -455,11 +454,7 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin st = BR_DONE; } } - if (kind == EQ && m_expand_eqs) { - result = m().mk_and(m_util.mk_le(arg1, arg2), m_util.mk_ge(arg1, arg2)); - return BR_REWRITE2; - } - else if (is_numeral(arg2, a2) && is_neg_poly(arg1, new_arg1)) { + if (is_numeral(arg2, a2) && is_neg_poly(arg1, new_arg1)) { a2.neg(); new_arg2 = m_util.mk_numeral(a2, m_util.is_int(new_arg1)); switch (kind) { @@ -500,12 +495,19 @@ br_status arith_rewriter::mk_gt_core(expr * arg1, expr * arg2, expr_ref & result return BR_REWRITE2; } +bool arith_rewriter::is_arith_term(expr * n) const { + return n->get_kind() == AST_APP && to_app(n)->get_family_id() == get_fid(); +} + br_status arith_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { - if (m_eq2ineq) { + if (m_expand_eqs) { result = m().mk_and(m_util.mk_le(arg1, arg2), m_util.mk_ge(arg1, arg2)); return BR_REWRITE2; } - return mk_le_ge_eq_core(arg1, arg2, EQ, result); + if (m_arith_lhs || is_arith_term(arg1) || is_arith_term(arg2)) { + return mk_le_ge_eq_core(arg1, arg2, EQ, result); + } + return BR_FAILED; } expr_ref arith_rewriter::neg_monomial(expr* e) const { diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index 352cb5a6c..f1e4c4396 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -50,12 +50,12 @@ public: class arith_rewriter : public poly_rewriter { bool m_arith_lhs; bool m_gcd_rounding; - bool m_eq2ineq; bool m_elim_to_real; bool m_push_to_real; bool m_anum_simp; bool m_elim_rem; bool m_expand_eqs; + bool m_process_all_eqs; unsigned m_max_degree; void get_coeffs_gcd(expr * t, numeral & g, bool & first, unsigned & num_consts); @@ -83,6 +83,8 @@ class arith_rewriter : public poly_rewriter { expr * reduce_power(expr * arg, bool is_eq); br_status reduce_power(expr * arg1, expr * arg2, op_kind kind, expr_ref & result); + bool is_arith_term(expr * n) const; + bool is_pi_multiple(expr * t, rational & k); bool is_pi_offset(expr * t, rational & k, expr * & m); bool is_2_pi_integer(expr * t); diff --git a/src/ast/rewriter/arith_rewriter_params.pyg b/src/ast/rewriter/arith_rewriter_params.pyg index 94ada1b6d..9a6c6c1c0 100644 --- a/src/ast/rewriter/arith_rewriter_params.pyg +++ b/src/ast/rewriter/arith_rewriter_params.pyg @@ -6,7 +6,6 @@ def_module_params(module_name='rewriter', ("expand_power", BOOL, False, "expand (^ t k) into (* t ... t) if 1 < k <= max_degree."), ("expand_tan", BOOL, False, "replace (tan x) with (/ (sin x) (cos x))."), ("max_degree", UINT, 64, "max degree of algebraic numbers (and power operators) processed by simplifier."), - ("eq2ineq", BOOL, False, "split arithmetic equalities into two inequalities."), ("sort_sums", BOOL, False, "sort the arguments of + application."), ("gcd_rounding", BOOL, False, "use gcd rounding on integer arithmetic atoms."), ("arith_lhs", BOOL, False, "all monomials are moved to the left-hand-side, and the right-hand-side is just a constant."), diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index 75f931c1d..ce35300ca 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -20,6 +20,7 @@ Notes: #include "ast/rewriter/bv_rewriter_params.hpp" #include "ast/rewriter/poly_rewriter_def.h" #include "ast/ast_smt2_pp.h" +#include "ast/ast_lt.h" void bv_rewriter::updt_local_params(params_ref const & _p) { diff --git a/src/ast/rewriter/poly_rewriter.h b/src/ast/rewriter/poly_rewriter.h index 8cbc7f864..c00464383 100644 --- a/src/ast/rewriter/poly_rewriter.h +++ b/src/ast/rewriter/poly_rewriter.h @@ -48,7 +48,6 @@ protected: decl_kind power_decl_kind() const { return Config::power_decl_kind(); } bool is_power(expr * t) const { return is_app_of(t, get_fid(), power_decl_kind()); } expr * get_power_body(expr * t, rational & k); - struct mon_pw_lt; // functor used to sort monomial elements when use_power() == true expr * mk_mul_app(unsigned num_args, expr * const * args); expr * mk_mul_app(numeral const & c, expr * arg); @@ -85,6 +84,14 @@ protected: bool is_mul(expr * t, numeral & c, expr * & pp); void hoist_cmul(expr_ref_buffer & args); + class mon_lt { + poly_rewriter& rw; + int ordinal(expr* e) const; + public: + mon_lt(poly_rewriter& rw): rw(rw) {} + bool operator()(expr* e1, expr * e2) const; + }; + public: poly_rewriter(ast_manager & m, params_ref const & p = params_ref()): Config(m), diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 85044af08..8fda040b6 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -18,7 +18,7 @@ Notes: --*/ #include "ast/rewriter/poly_rewriter.h" #include "ast/rewriter/poly_rewriter_params.hpp" -#include "ast/ast_lt.h" +// include "ast/ast_lt.h" #include "ast/ast_ll_pp.h" #include "ast/ast_smt2_pp.h" @@ -191,21 +191,9 @@ br_status poly_rewriter::mk_flat_mul_core(unsigned num_args, expr * cons } -template -struct poly_rewriter::mon_pw_lt { - poly_rewriter & m_owner; - mon_pw_lt(poly_rewriter & o):m_owner(o) {} - - bool operator()(expr * n1, expr * n2) const { - rational k; - return lt(m_owner.get_power_body(n1, k), - m_owner.get_power_body(n2, k)); - } -}; - - template br_status poly_rewriter::mk_nflat_mul_core(unsigned num_args, expr * const * args, expr_ref & result) { + mon_lt lt(*this); SASSERT(num_args >= 2); // cheap case numeral a; @@ -320,11 +308,8 @@ br_status poly_rewriter::mk_nflat_mul_core(unsigned num_args, expr * con if (ordered && num_coeffs == 0 && !use_power()) return BR_FAILED; if (!ordered) { - if (use_power()) - std::sort(new_args.begin(), new_args.end(), mon_pw_lt(*this)); - else - std::sort(new_args.begin(), new_args.end(), ast_to_lt()); - TRACE("poly_rewriter", + std::sort(new_args.begin(), new_args.end(), lt); + TRACE("poly_rewriter", tout << "after sorting:\n"; for (unsigned i = 0; i < new_args.size(); i++) { if (i > 0) @@ -498,8 +483,43 @@ void poly_rewriter::hoist_cmul(expr_ref_buffer & args) { args.resize(j); } +template +bool poly_rewriter::mon_lt::operator()(expr* e1, expr * e2) const { + return ordinal(e1) < ordinal(e2); +} + +inline bool is_essentially_var(expr * n, family_id fid) { + SASSERT(is_var(n) || is_app(n)); + return is_var(n) || to_app(n)->get_family_id() != fid; +} + +template +int poly_rewriter::mon_lt::ordinal(expr* e) const { + rational k; + if (is_essentially_var(e, rw.get_fid())) { + return e->get_id(); + } + else if (rw.is_mul(e)) { + if (rw.is_numeral(to_app(e)->get_arg(0))) + return to_app(e)->get_arg(1)->get_id(); + else + return e->get_id(); + } + else if (rw.is_numeral(e)) { + return -1; + } + else if (rw.use_power() && rw.is_power(e) && rw.is_numeral(to_app(e)->get_arg(1), k) && k > rational(1)) { + return to_app(e)->get_arg(0)->get_id(); + } + else { + return e->get_id(); + } +} + + template br_status poly_rewriter::mk_nflat_add_core(unsigned num_args, expr * const * args, expr_ref & result) { + mon_lt lt(*this); SASSERT(num_args >= 2); numeral c; unsigned num_coeffs = 0; @@ -591,9 +611,9 @@ br_status poly_rewriter::mk_nflat_add_core(unsigned num_args, expr * con else if (m_sort_sums) { TRACE("rewriter_bug", tout << "new_args.size(): " << new_args.size() << "\n";); if (c.is_zero()) - std::sort(new_args.c_ptr(), new_args.c_ptr() + new_args.size(), ast_to_lt()); + std::sort(new_args.c_ptr(), new_args.c_ptr() + new_args.size(), mon_lt(*this)); else - std::sort(new_args.c_ptr() + 1, new_args.c_ptr() + new_args.size(), ast_to_lt()); + std::sort(new_args.c_ptr() + 1, new_args.c_ptr() + new_args.size(), mon_lt(*this)); } result = mk_add_app(new_args.size(), new_args.c_ptr()); TRACE("rewriter", tout << result << "\n";); @@ -624,10 +644,10 @@ br_status poly_rewriter::mk_nflat_add_core(unsigned num_args, expr * con } else if (!ordered) { if (c.is_zero()) - std::sort(new_args.c_ptr(), new_args.c_ptr() + new_args.size(), ast_to_lt()); + std::sort(new_args.c_ptr(), new_args.c_ptr() + new_args.size(), lt); else - std::sort(new_args.c_ptr() + 1, new_args.c_ptr() + new_args.size(), ast_to_lt()); - } + std::sort(new_args.c_ptr() + 1, new_args.c_ptr() + new_args.size(), lt); + } result = mk_add_app(new_args.size(), new_args.c_ptr()); if (hoist_multiplication(result)) { return BR_REWRITE_FULL; @@ -681,6 +701,7 @@ br_status poly_rewriter::mk_sub(unsigned num_args, expr * const * args, template br_status poly_rewriter::cancel_monomials(expr * lhs, expr * rhs, bool move, expr_ref & lhs_result, expr_ref & rhs_result) { set_curr_sort(m().get_sort(lhs)); + mon_lt lt(*this); unsigned lhs_sz; expr * const * lhs_monomials = get_monomials(lhs, lhs_sz); unsigned rhs_sz; @@ -831,7 +852,7 @@ br_status poly_rewriter::cancel_monomials(expr * lhs, expr * rhs, bool m if (move) { if (m_sort_sums) { // + 1 to skip coefficient - std::sort(new_lhs_monomials.begin() + 1, new_lhs_monomials.end(), ast_to_lt()); + std::sort(new_lhs_monomials.begin() + 1, new_lhs_monomials.end(), lt); } c_at_rhs = true; } diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index f172e5e93..d1b8f7f78 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -585,10 +585,8 @@ void cmd_context::register_builtin_sorts(decl_plugin * p) { svector names; p->get_sort_names(names, m_logic); family_id fid = p->get_family_id(); - svector::const_iterator it = names.begin(); - svector::const_iterator end = names.end(); - for (; it != end; ++it) { - psort_decl * d = pm().mk_psort_builtin_decl((*it).m_name, fid, (*it).m_kind); + for (builtin_name const& n : names) { + psort_decl * d = pm().mk_psort_builtin_decl(n.m_name, fid, n.m_kind); insert(d); } } @@ -597,17 +595,15 @@ void cmd_context::register_builtin_ops(decl_plugin * p) { svector names; p->get_op_names(names, m_logic); family_id fid = p->get_family_id(); - svector::const_iterator it = names.begin(); - svector::const_iterator end = names.end(); - for (; it != end; ++it) { - if (m_builtin_decls.contains((*it).m_name)) { - builtin_decl & d = m_builtin_decls.find((*it).m_name); - builtin_decl * new_d = alloc(builtin_decl, fid, (*it).m_kind, d.m_next); + for (builtin_name const& n : names) { + if (m_builtin_decls.contains(n.m_name)) { + builtin_decl & d = m_builtin_decls.find(n.m_name); + builtin_decl * new_d = alloc(builtin_decl, fid, n.m_kind, d.m_next); d.m_next = new_d; m_extra_builtin_decls.push_back(new_d); } else { - m_builtin_decls.insert((*it).m_name, builtin_decl(fid, (*it).m_kind)); + m_builtin_decls.insert(n.m_name, builtin_decl(fid, n.m_kind)); } } } @@ -693,10 +689,8 @@ void cmd_context::init_manager_core(bool new_manager) { load_plugin(symbol("seq"), logic_has_seq(), fids); load_plugin(symbol("fpa"), logic_has_fpa(), fids); load_plugin(symbol("pb"), logic_has_pb(), fids); - svector::iterator it = fids.begin(); - svector::iterator end = fids.end(); - for (; it != end; ++it) { - decl_plugin * p = m_manager->get_plugin(*it); + for (family_id fid : fids) { + decl_plugin * p = m_manager->get_plugin(fid); if (p) { register_builtin_sorts(p); register_builtin_ops(p); @@ -1148,11 +1142,8 @@ void cmd_context::erase_object_ref(symbol const & s) { } void cmd_context::reset_func_decls() { - dictionary::iterator it = m_func_decls.begin(); - dictionary::iterator end = m_func_decls.end(); - for (; it != end; ++it) { - func_decls fs = (*it).m_value; - fs.finalize(m()); + for (auto & kv : m_func_decls) { + kv.m_value.finalize(m()); } m_func_decls.reset(); m_func_decls_stack.reset(); @@ -1160,10 +1151,8 @@ void cmd_context::reset_func_decls() { } void cmd_context::reset_psort_decls() { - dictionary::iterator it = m_psort_decls.begin(); - dictionary::iterator end = m_psort_decls.end(); - for (; it != end; ++it) { - psort_decl * p = (*it).m_value; + for (auto & kv : m_psort_decls) { + psort_decl * p = kv.m_value; pm().dec_ref(p); } m_psort_decls.reset(); @@ -1179,19 +1168,14 @@ void cmd_context::reset_macros() { } void cmd_context::reset_cmds() { - dictionary::iterator it = m_cmds.begin(); - dictionary::iterator end = m_cmds.end(); - for (; it != end; ++it) { - cmd * c = (*it).m_value; - c->reset(*this); + for (auto& kv : m_cmds) { + kv.m_value->reset(*this); } } void cmd_context::finalize_cmds() { - dictionary::iterator it = m_cmds.begin(); - dictionary::iterator end = m_cmds.end(); - for (; it != end; ++it) { - cmd * c = (*it).m_value; + for (auto& kv : m_cmds) { + cmd * c = kv.m_value; c->finalize(*this); dealloc(c); } @@ -1204,10 +1188,8 @@ void cmd_context::reset_user_tactics() { } void cmd_context::reset_object_refs() { - dictionary::iterator it = m_object_refs.begin(); - dictionary::iterator end = m_object_refs.end(); - for (; it != end; ++it) { - object_ref * r = (*it).m_value; + for (auto& kv : m_object_refs) { + object_ref * r = kv.m_value; r->dec_ref(*this); } m_object_refs.reset(); @@ -1541,10 +1523,8 @@ void cmd_context::reset_assertions() { mk_solver(); } restore_assertions(0); - svector::iterator it = m_scopes.begin(); - svector::iterator end = m_scopes.end(); - for (; it != end; ++it) { - it->m_assertions_lim = 0; + for (scope& s : m_scopes) { + s.m_assertions_lim = 0; if (m_solver) m_solver->push(); } } @@ -1717,10 +1697,7 @@ void cmd_context::set_solver_factory(solver_factory * f) { mk_solver(); // assert formulas and create scopes in the new solver. unsigned lim = 0; - svector::iterator it = m_scopes.begin(); - svector::iterator end = m_scopes.end(); - for (; it != end; ++it) { - scope & s = *it; + for (scope& s : m_scopes) { for (unsigned i = lim; i < s.m_assertions_lim; i++) { m_solver->assert_expr(m_assertions[i]); } @@ -1757,11 +1734,9 @@ void cmd_context::display_statistics(bool show_total_time, double total_time) { void cmd_context::display_assertions() { if (!m_interactive_mode) throw cmd_exception("command is only available in interactive mode, use command (set-option :interactive-mode true)"); - std::vector::const_iterator it = m_assertion_strings.begin(); - std::vector::const_iterator end = m_assertion_strings.end(); regular_stream() << "("; - for (bool first = true; it != end; ++it) { - std::string const & s = *it; + bool first = true; + for (std::string const& s : m_assertion_strings) { if (first) first = false; else @@ -1837,10 +1812,8 @@ void cmd_context::display(std::ostream & out, func_decl * d, unsigned indent) co } void cmd_context::dump_assertions(std::ostream & out) const { - ptr_vector::const_iterator it = m_assertions.begin(); - ptr_vector::const_iterator end = m_assertions.end(); - for (; it != end; ++it) { - display(out, *it); + for (expr * e : m_assertions) { + display(out, e); out << std::endl; } } diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index fb2004c77..7dca13c07 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -120,7 +120,7 @@ void asserted_formulas::push_assertion(expr * e, proof * pr, vector Date: Sun, 3 Sep 2017 15:01:54 -0700 Subject: [PATCH 238/488] remove dom-simplifier from build Signed-off-by: Nikolaj Bjorner --- src/tactic/core/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tactic/core/CMakeLists.txt b/src/tactic/core/CMakeLists.txt index 006948315..f192b4fa6 100644 --- a/src/tactic/core/CMakeLists.txt +++ b/src/tactic/core/CMakeLists.txt @@ -7,7 +7,6 @@ z3_add_component(core_tactics ctx_simplify_tactic.cpp der_tactic.cpp distribute_forall_tactic.cpp - dom_simplify_tactic.cpp elim_term_ite_tactic.cpp elim_uncnstr_tactic.cpp injectivity_tactic.cpp From ee4ae33ac444fdc7407545e06453029aeca45f56 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 15:19:55 -0700 Subject: [PATCH 239/488] build fixes Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 0030af609..44102156d 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -495,7 +495,10 @@ namespace datatype { return param_size::size::mk_power(sz2, sz1); } for (sort* p : params) { - if (s == p) return param_size::size::mk_param(sort_ref(s, m)); + if (s == p) { + sort_ref sr(s, m); + return param_size::size::mk_param(sr); + } } return param_size::size::mk_offset(s->get_num_elements()); } From 10f734357ee2e50e88d29462c857e3757a69e238 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 15:32:57 -0700 Subject: [PATCH 240/488] build fixes Signed-off-by: Nikolaj Bjorner --- src/ast/array_decl_plugin.cpp | 2 +- src/ast/array_decl_plugin.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/array_decl_plugin.cpp b/src/ast/array_decl_plugin.cpp index 6296d344a..cb016e263 100644 --- a/src/ast/array_decl_plugin.cpp +++ b/src/ast/array_decl_plugin.cpp @@ -546,7 +546,7 @@ expr * array_decl_plugin::get_some_value(sort * s) { return m_manager->mk_app(m_family_id, OP_CONST_ARRAY, 1, &p, 1, &v); } -bool array_decl_plugin::is_fully_interp(sort const * s) const { +bool array_decl_plugin::is_fully_interp(sort * s) const { SASSERT(s->is_sort_of(m_family_id, ARRAY_SORT)); unsigned sz = get_array_arity(s); for (unsigned i = 0; i < sz; i++) { diff --git a/src/ast/array_decl_plugin.h b/src/ast/array_decl_plugin.h index 0febb82a4..0704fe56a 100644 --- a/src/ast/array_decl_plugin.h +++ b/src/ast/array_decl_plugin.h @@ -127,7 +127,7 @@ class array_decl_plugin : public decl_plugin { virtual expr * get_some_value(sort * s); - virtual bool is_fully_interp(sort const * s) const; + virtual bool is_fully_interp(sort * s) const; }; class array_recognizers { From eb6b2813ff68501d308cc2696a57568aa9e6e835 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 16:14:22 -0700 Subject: [PATCH 241/488] build fixes Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.cpp | 14 ++++++++++++++ src/ast/datatype_decl_plugin2.h | 19 +++++++++++++++---- src/ast/rewriter/arith_rewriter.cpp | 3 ++- src/ast/rewriter/arith_rewriter.h | 1 + src/ast/rewriter/arith_rewriter_params.pyg | 1 + src/smt/asserted_formulas.cpp | 2 +- 6 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 44102156d..8969e02a9 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -24,6 +24,12 @@ Revision History: namespace datatype { + void accessor::fix_range(sort_ref_vector const& dts) { + if (!m_range) { + m_range = dts[m_index]; + } + } + func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const { unsigned n = ps.size(); SASSERT(n == get_def().params().size()); @@ -285,6 +291,14 @@ namespace datatype { sort_ref_vector ps(m); sorts.push_back(d.instantiate(ps)); } + for (symbol const& s : m_def_block) { + def& d = *m_defs[s]; + for (constructor& c : d) { + for (accessor& a : c) { + // a.fix_range(sorts); + } + } + } if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) { m_manager->raise_exception("datatype is not well-founded"); } diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index a4a76f346..13e85b47f 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -46,17 +46,24 @@ namespace datatype { class accessor { ast_manager& m; symbol m_name; - sort_ref m_domain; sort_ref m_range; + unsigned m_index; // reference to recursive data-type may only get resolved after all mutually recursive data-types are procssed. constructor* m_constructor; public: - accessor(ast_manager& m, symbol const& n): + accessor(ast_manager& m, symbol const& n, sort* range): m(m), m_name(n), - m_domain(m), - m_range(m) + m_range(range, m), + m_index(UINT_MAX) + {} + accessor(ast_manager& m, symbol const& n, unsigned index): + m(m), + m_name(n), + m_range(m), + m_index(index) {} sort* range() const { return m_range; } + void fix_range(sort_ref_vector const& dts); symbol const& name() const { return m_name; } func_decl_ref instantiate(sort_ref_vector const& ps) const; func_decl_ref instantiate(sort* dt) const; @@ -78,6 +85,8 @@ namespace datatype { vector const& accessors() const { return m_accessors; } vector::const_iterator begin() const { return m_accessors.begin(); } vector::const_iterator end() const { return m_accessors.end(); } + vector::iterator begin() { return m_accessors.begin(); } + vector::iterator end() { return m_accessors.end(); } func_decl_ref instantiate(sort_ref_vector const& ps) const; func_decl_ref instantiate(sort* dt) const; void attach(def* d) { m_def = d; } @@ -205,6 +214,8 @@ namespace datatype { vector const& constructors() const { return m_constructors; } vector::const_iterator begin() const { return m_constructors.begin(); } vector::const_iterator end() const { return m_constructors.end(); } + vector::iterator begin() { return m_constructors.begin(); } + vector::iterator end() { return m_constructors.end(); } sort_ref_vector const& params() const { return m_params; } util& u() const { return m_util; } param_size::size* sort_size() { return m_sort_size; } diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index b630cdff6..8b29004ab 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -25,6 +25,7 @@ Notes: void arith_rewriter::updt_local_params(params_ref const & _p) { arith_rewriter_params p(_p); m_arith_lhs = p.arith_lhs(); + m_arith_ineq_lhs = p.arith_ineq_lhs; m_gcd_rounding = p.gcd_rounding(); m_elim_to_real = p.elim_to_real(); m_push_to_real = p.push_to_real(); @@ -370,7 +371,7 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin if ((is_zero(arg1) && is_reduce_power_target(arg2, kind == EQ)) || (is_zero(arg2) && is_reduce_power_target(arg1, kind == EQ))) return reduce_power(arg1, arg2, kind, result); - br_status st = cancel_monomials(arg1, arg2, true, new_arg1, new_arg2); + br_status st = cancel_monomials(arg1, arg2, m_arith_ineq_lhs || m_arith_lhs, new_arg1, new_arg2); TRACE("mk_le_bug", tout << "st: " << st << " " << new_arg1 << " " << new_arg2 << "\n";); if (st != BR_FAILED) { arg1 = new_arg1; diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index f1e4c4396..af9d0e09d 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -49,6 +49,7 @@ public: class arith_rewriter : public poly_rewriter { bool m_arith_lhs; + bool m_arith_ineq_lhs; bool m_gcd_rounding; bool m_elim_to_real; bool m_push_to_real; diff --git a/src/ast/rewriter/arith_rewriter_params.pyg b/src/ast/rewriter/arith_rewriter_params.pyg index 9a6c6c1c0..d40f46917 100644 --- a/src/ast/rewriter/arith_rewriter_params.pyg +++ b/src/ast/rewriter/arith_rewriter_params.pyg @@ -9,6 +9,7 @@ def_module_params(module_name='rewriter', ("sort_sums", BOOL, False, "sort the arguments of + application."), ("gcd_rounding", BOOL, False, "use gcd rounding on integer arithmetic atoms."), ("arith_lhs", BOOL, False, "all monomials are moved to the left-hand-side, and the right-hand-side is just a constant."), + ("arith_ineq_lhs", BOOL, False, "rewrite inequalities so that right-hand-side is a constant."), ("elim_to_real", BOOL, False, "eliminate to_real from arithmetic predicates that contain only integers."), ("push_to_real", BOOL, True, "distribute to_real over * and +."), ("expand_eqs", BOOL, False, "expand equalities into two inequalities"), diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 7dca13c07..f37cabde8 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -120,7 +120,7 @@ void asserted_formulas::push_assertion(expr * e, proof * pr, vector Date: Sun, 3 Sep 2017 16:14:58 -0700 Subject: [PATCH 242/488] build fixes Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/arith_rewriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 8b29004ab..ff1894a18 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -25,7 +25,7 @@ Notes: void arith_rewriter::updt_local_params(params_ref const & _p) { arith_rewriter_params p(_p); m_arith_lhs = p.arith_lhs(); - m_arith_ineq_lhs = p.arith_ineq_lhs; + m_arith_ineq_lhs = p.arith_ineq_lhs(); m_gcd_rounding = p.gcd_rounding(); m_elim_to_real = p.elim_to_real(); m_push_to_real = p.push_to_real(); From 09386e43e307a95cc9f49bfe3bbdd6f57477cce1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 19:07:02 -0700 Subject: [PATCH 243/488] doctest fix Signed-off-by: Nikolaj Bjorner --- src/api/python/z3/z3.py | 4 +-- src/ast/datatype_decl_plugin2.cpp | 59 ++++++++++++++++--------------- src/ast/datatype_decl_plugin2.h | 44 +++++++++++------------ 3 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index 1452a037e..0b5f151be 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -3640,7 +3640,7 @@ def BitVecs(names, bv, ctx=None): >>> Product(x, y, z) 1*x*y*z >>> simplify(Product(x, y, z)) - x*y*z + z*x*y """ ctx = _get_ctx(ctx) if isinstance(names, str): @@ -7647,7 +7647,7 @@ def simplify(a, *arguments, **keywords): >>> simplify(x + 1 + y + x + 1) 2 + 2*x + y >>> simplify((x + 1)*(y + 1), som=True) - 1 + x + y + x*y + 1 + x + y + y*x >>> simplify(Distinct(x, y, 1), blast_distinct=True) And(Not(x == y), Not(x == 1), Not(y == 1)) >>> simplify(And(x == 0, y == 1), elim_and=True) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 8969e02a9..8233da7d9 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -31,6 +31,7 @@ namespace datatype { } func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const { + ast_manager& m = ps.get_manager(); unsigned n = ps.size(); SASSERT(n == get_def().params().size()); sort_ref range(m.substitute(m_range, n, get_def().params().c_ptr(), ps.c_ptr()), m); @@ -52,8 +53,8 @@ namespace datatype { func_decl_ref constructor::instantiate(sort_ref_vector const& ps) const { sort_ref_vector domain(m); - for (accessor const& a : accessors()) { - domain.push_back(a.instantiate(ps)->get_range()); + for (accessor const* a : accessors()) { + domain.push_back(a->instantiate(ps)->get_range()); } sort_ref range = get_def().instantiate(ps); parameter pas[1] = { parameter(name()) }; @@ -293,9 +294,9 @@ namespace datatype { } for (symbol const& s : m_def_block) { def& d = *m_defs[s]; - for (constructor& c : d) { - for (accessor& a : c) { - // a.fix_range(sorts); + for (constructor* c : d) { + for (accessor* a : *c) { + a->fix_range(sorts); } } } @@ -401,9 +402,9 @@ namespace datatype { def const& d = get_def(s); bool is_interp = true; m_fully_interp_trail.push_back(s); - for (constructor const& c : d) { - for (accessor const& a : c) { - func_decl_ref ac = a.instantiate(s); + for (constructor const* c : d) { + for (accessor const* a : *c) { + func_decl_ref ac = a->instantiate(s); sort* r = ac->get_range(); if (!m.is_fully_interp(r)) { is_interp = false; @@ -438,9 +439,9 @@ namespace datatype { already_found.insert(s, GRAY); def const& d = get_def(s); bool can_process = true; - for (constructor const& c : d) { - for (accessor const& a : c) { - sort* d = a.range(); + for (constructor const* c : d) { + for (accessor const* a : *c) { + sort* d = a->range(); // check if d is a datatype sort subsorts.reset(); get_subsorts(d, subsorts); @@ -533,9 +534,9 @@ namespace datatype { bool is_infinite = false; bool can_process = true; def& d = get_def(s); - for (constructor const& c : d) { - for (accessor const& a : c) { - sort* r = a.range(); + for (constructor const* c : d) { + for (accessor const* a : *c) { + sort* r = a->range(); if (is_datatype(r)) { symbol s2 = r->get_name(); if (already_found.find(s2, st)) { @@ -562,10 +563,10 @@ namespace datatype { } ptr_vector s_add; - for (constructor const& c : d) { + for (constructor const* c : d) { ptr_vector s_mul; - for (accessor const& a : c) { - s_mul.push_back(get_sort_size(d.params(), a.range())); + for (accessor const* a : *c) { + s_mul.push_back(get_sort_size(d.params(), a->range())); } s_add.push_back(param_size::size::mk_times(s_mul)); } @@ -594,10 +595,10 @@ namespace datatype { } sort* s = sorts[tid]; def const& d = get_def(s); - for (constructor const& c : d) { + for (constructor const* c : d) { bool found_nonwf = false; - for (accessor const& a : c) { - if (sort2id.find(a.range(), id) && !well_founded[id]) { + for (accessor const* a : *c) { + if (sort2id.find(a->range(), id) && !well_founded[id]) { found_nonwf = true; break; } @@ -652,8 +653,8 @@ namespace datatype { m_vectors.push_back(r); m_datatype2constructors.insert(ty, r); def const& d = get_def(ty); - for (constructor const& c : d) { - func_decl_ref f = c.instantiate(ty); + for (constructor const* c : d) { + func_decl_ref f = c->instantiate(ty); m_asts.push_back(f); r->push_back(f); } @@ -671,10 +672,10 @@ namespace datatype { m_constructor2accessors.insert(con, res); sort * datatype = con->get_range(); def const& d = get_def(datatype); - for (constructor const& c : d) { - if (c.name() == con->get_name()) { - for (accessor const& a : c) { - res->push_back(a.instantiate(datatype)); + for (constructor const* c : d) { + if (c->name() == con->get_name()) { + for (accessor const* a : *c) { + res->push_back(a->instantiate(datatype)); } break; } @@ -739,9 +740,9 @@ namespace datatype { symbol c_id = accessor->get_parameter(1).get_symbol(); def const& d = get_def(datatype); func_decl_ref fn(m); - for (constructor const& c : d) { - if (c.name() == c_id) { - fn = c.instantiate(datatype); + for (constructor const* c : d) { + if (c->name() == c_id) { + fn = c->instantiate(datatype); break; } } diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index 13e85b47f..c540b7c1c 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -44,22 +44,19 @@ namespace datatype { }; class accessor { - ast_manager& m; symbol m_name; - sort_ref m_range; + sort* m_range; unsigned m_index; // reference to recursive data-type may only get resolved after all mutually recursive data-types are procssed. constructor* m_constructor; public: - accessor(ast_manager& m, symbol const& n, sort* range): - m(m), + accessor(symbol const& n, sort* range): m_name(n), - m_range(range, m), + m_range(range), m_index(UINT_MAX) {} - accessor(ast_manager& m, symbol const& n, unsigned index): - m(m), + accessor(symbol const& n, unsigned index): m_name(n), - m_range(m), + m_range(0), m_index(index) {} sort* range() const { return m_range; } @@ -76,17 +73,18 @@ namespace datatype { class constructor { ast_manager& m; symbol m_name; - vector m_accessors; + ptr_vector m_accessors; def* m_def; public: constructor(ast_manager& m, symbol n): m(m), m_name(n) {} - void add(accessor& a) { m_accessors.push_back(a); a.attach(this); } + ~constructor(); + void add(accessor* a) { m_accessors.push_back(a); a->attach(this); } symbol const& name() const { return m_name; } - vector const& accessors() const { return m_accessors; } - vector::const_iterator begin() const { return m_accessors.begin(); } - vector::const_iterator end() const { return m_accessors.end(); } - vector::iterator begin() { return m_accessors.begin(); } - vector::iterator end() { return m_accessors.end(); } + ptr_vector const& accessors() const { return m_accessors; } + ptr_vector::const_iterator begin() const { return m_accessors.begin(); } + ptr_vector::const_iterator end() const { return m_accessors.end(); } + ptr_vector::iterator begin() { return m_accessors.begin(); } + ptr_vector::iterator end() { return m_accessors.end(); } func_decl_ref instantiate(sort_ref_vector const& ps) const; func_decl_ref instantiate(sort* dt) const; void attach(def* d) { m_def = d; } @@ -190,7 +188,7 @@ namespace datatype { param_size::size* m_sort_size; sort_ref_vector m_params; mutable sort_ref m_sort; - vector m_constructors; + ptr_vector m_constructors; public: def(ast_manager& m, util& u, symbol const& n, unsigned class_id, unsigned num_params, sort * const* params): m(m), @@ -204,18 +202,18 @@ namespace datatype { ~def() { if (m_sort_size) m_sort_size->dec_ref(); } - void add(constructor& c) { + void add(constructor* c) { m_constructors.push_back(c); - c.attach(this); + c->attach(this); } symbol const& name() const { return m_name; } unsigned id() const { return m_class_id; } sort_ref instantiate(sort_ref_vector const& ps) const; - vector const& constructors() const { return m_constructors; } - vector::const_iterator begin() const { return m_constructors.begin(); } - vector::const_iterator end() const { return m_constructors.end(); } - vector::iterator begin() { return m_constructors.begin(); } - vector::iterator end() { return m_constructors.end(); } + ptr_vector const& constructors() const { return m_constructors; } + ptr_vector::const_iterator begin() const { return m_constructors.begin(); } + ptr_vector::const_iterator end() const { return m_constructors.end(); } + ptr_vector::iterator begin() { return m_constructors.begin(); } + ptr_vector::iterator end() { return m_constructors.end(); } sort_ref_vector const& params() const { return m_params; } util& u() const { return m_util; } param_size::size* sort_size() { return m_sort_size; } From a3dba5b2f97341269e205dbfb18d4c127e084f56 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 3 Sep 2017 20:01:59 -0700 Subject: [PATCH 244/488] hide new datatype plugin Signed-off-by: Nikolaj Bjorner --- src/api/api_datatype.cpp | 107 +++++++++-------------- src/ast/ast_smt_pp.cpp | 17 ++-- src/ast/datatype_decl_plugin.cpp | 37 ++++---- src/ast/datatype_decl_plugin.h | 11 ++- src/ast/datatype_decl_plugin2.cpp | 12 ++- src/ast/datatype_decl_plugin2.h | 74 ++++++++++++---- src/ast/decl_collector.cpp | 4 +- src/ast/rewriter/datatype_rewriter.cpp | 16 ++-- src/ast/rewriter/enum2bv_rewriter.cpp | 2 +- src/cmd_context/cmd_context.cpp | 12 +-- src/muz/base/dl_rule.h | 2 +- src/muz/base/rule_properties.cpp | 2 +- src/muz/bmc/dl_bmc_engine.cpp | 10 +-- src/muz/pdr/pdr_prop_solver.cpp | 2 +- src/muz/spacer/spacer_util.cpp | 2 +- src/qe/qe_datatype_plugin.cpp | 12 +-- src/qe/qe_datatypes.cpp | 6 +- src/qe/qe_lite.cpp | 2 +- src/smt/proto_model/datatype_factory.cpp | 12 +-- src/smt/smt_value_sort.cpp | 2 +- src/smt/theory_datatype.cpp | 37 ++++---- src/tactic/core/elim_uncnstr_tactic.cpp | 17 ++-- src/tactic/portfolio/enum2bv_solver.cpp | 2 +- src/test/get_consequences.cpp | 2 +- 24 files changed, 211 insertions(+), 191 deletions(-) diff --git a/src/api/api_datatype.cpp b/src/api/api_datatype.cpp index 851d96a4e..39d147ed1 100644 --- a/src/api/api_datatype.cpp +++ b/src/api/api_datatype.cpp @@ -69,18 +69,13 @@ extern "C" { // create constructor SASSERT(dt_util.is_datatype(tuple)); SASSERT(!dt_util.is_recursive(tuple)); - ptr_vector const * decls = dt_util.get_datatype_constructors(tuple); - func_decl* decl = (*decls)[0]; + ptr_vector const & decls = dt_util.get_datatype_constructors(tuple); + func_decl* decl = (decls)[0]; mk_c(c)->save_multiple_ast_trail(decl); *mk_tuple_decl = of_func_decl(decl); // Create projections - ptr_vector const * accs = dt_util.get_constructor_accessors(decl); - if (!accs) { - SET_ERROR_CODE(Z3_INVALID_ARG); - RETURN_Z3(0); - } - ptr_vector const & _accs = *accs; + ptr_vector const & _accs = dt_util.get_constructor_accessors(decl); SASSERT(_accs.size() == num_fields); for (unsigned i = 0; i < _accs.size(); i++) { mk_c(c)->save_multiple_ast_trail(_accs[i]); @@ -136,10 +131,10 @@ extern "C" { // create constructor SASSERT(dt_util.is_datatype(e)); SASSERT(!dt_util.is_recursive(e)); - ptr_vector const * decls = dt_util.get_datatype_constructors(e); - SASSERT(decls && decls->size() == n); + ptr_vector const & decls = dt_util.get_datatype_constructors(e); + SASSERT(decls.size() == n); for (unsigned i = 0; i < n; ++i) { - func_decl* decl = (*decls)[i]; + func_decl* decl = (decls)[i]; mk_c(c)->save_multiple_ast_trail(decl); enum_consts[i] = of_func_decl(decl); decl = dt_util.get_constructor_recognizer(decl); @@ -191,7 +186,7 @@ extern "C" { sort * s = sorts.get(0); mk_c(c)->save_multiple_ast_trail(s); - ptr_vector const& cnstrs = *data_util.get_datatype_constructors(s); + ptr_vector const& cnstrs = data_util.get_datatype_constructors(s); SASSERT(cnstrs.size() == 2); func_decl* f; if (nil_decl) { @@ -215,18 +210,16 @@ extern "C" { *is_cons_decl = of_func_decl(f); } if (head_decl) { - ptr_vector const* acc = data_util.get_constructor_accessors(cnstrs[1]); - SASSERT(acc); - SASSERT(acc->size() == 2); - f = (*acc)[0]; + ptr_vector const& acc = data_util.get_constructor_accessors(cnstrs[1]); + SASSERT(acc.size() == 2); + f = (acc)[0]; mk_c(c)->save_multiple_ast_trail(f); *head_decl = of_func_decl(f); } if (tail_decl) { - ptr_vector const* acc = data_util.get_constructor_accessors(cnstrs[1]); - SASSERT(acc); - SASSERT(acc->size() == 2); - f = (*acc)[1]; + ptr_vector const& acc = data_util.get_constructor_accessors(cnstrs[1]); + SASSERT(acc.size() == 2); + f = (acc)[1]; mk_c(c)->save_multiple_ast_trail(f); *tail_decl = of_func_decl(f); } @@ -301,13 +294,9 @@ extern "C" { *tester = of_func_decl(f2); } - ptr_vector const* accs = data_util.get_constructor_accessors(f); - if (!accs && num_fields > 0) { - SET_ERROR_CODE(Z3_INVALID_ARG); - return; - } + ptr_vector const& accs = data_util.get_constructor_accessors(f); for (unsigned i = 0; i < num_fields; ++i) { - func_decl* f2 = (*accs)[i]; + func_decl* f2 = (accs)[i]; mk_c(c)->save_multiple_ast_trail(f2); accessors[i] = of_func_decl(f2); } @@ -368,11 +357,11 @@ extern "C" { sort * s = sorts.get(0); mk_c(c)->save_ast_trail(s); - ptr_vector const* cnstrs = data_util.get_datatype_constructors(s); + ptr_vector const& cnstrs = data_util.get_datatype_constructors(s); for (unsigned i = 0; i < num_constructors; ++i) { constructor* cn = reinterpret_cast(constructors[i]); - cn->m_constructor = (*cnstrs)[i]; + cn->m_constructor = cnstrs[i]; } RETURN_Z3_mk_datatype(of_sort(s)); Z3_CATCH_RETURN(0); @@ -434,10 +423,10 @@ extern "C" { mk_c(c)->save_multiple_ast_trail(s); sorts[i] = of_sort(s); constructor_list* cl = reinterpret_cast(constructor_lists[i]); - ptr_vector const* cnstrs = data_util.get_datatype_constructors(s); + ptr_vector const& cnstrs = data_util.get_datatype_constructors(s); for (unsigned j = 0; j < cl->size(); ++j) { constructor* cn = (*cl)[j]; - cn->m_constructor = (*cnstrs)[j]; + cn->m_constructor = cnstrs[j]; } } RETURN_Z3_mk_datatypes; @@ -456,12 +445,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - ptr_vector const * decls = dt_util.get_datatype_constructors(_t); - if (!decls) { - SET_ERROR_CODE(Z3_INVALID_ARG); - return 0; - } - return decls->size(); + return dt_util.get_datatype_constructors(_t).size(); Z3_CATCH_RETURN(0); } @@ -474,12 +458,12 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - ptr_vector const * decls = dt_util.get_datatype_constructors(_t); - if (!decls || idx >= decls->size()) { + ptr_vector const & decls = dt_util.get_datatype_constructors(_t); + if (idx >= decls.size()) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - func_decl* decl = (*decls)[idx]; + func_decl* decl = (decls)[idx]; mk_c(c)->save_ast_trail(decl); return of_func_decl(decl); } @@ -504,12 +488,12 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const * decls = dt_util.get_datatype_constructors(_t); - if (!decls || idx >= decls->size()) { + ptr_vector const & decls = dt_util.get_datatype_constructors(_t); + if (idx >= decls.size()) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - func_decl* decl = (*decls)[idx]; + func_decl* decl = (decls)[idx]; decl = dt_util.get_constructor_recognizer(decl); mk_c(c)->save_ast_trail(decl); RETURN_Z3(of_func_decl(decl)); @@ -527,23 +511,23 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const * decls = dt_util.get_datatype_constructors(_t); - if (!decls || idx_c >= decls->size()) { + ptr_vector const & decls = dt_util.get_datatype_constructors(_t); + if (idx_c >= decls.size()) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - func_decl* decl = (*decls)[idx_c]; + func_decl* decl = (decls)[idx_c]; if (decl->get_arity() <= idx_a) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const * accs = dt_util.get_constructor_accessors(decl); - SASSERT(accs && accs->size() == decl->get_arity()); - if (!accs || accs->size() <= idx_a) { + ptr_vector const & accs = dt_util.get_constructor_accessors(decl); + SASSERT(accs.size() == decl->get_arity()); + if (accs.size() <= idx_a) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - decl = (*accs)[idx_a]; + decl = (accs)[idx_a]; mk_c(c)->save_ast_trail(decl); RETURN_Z3(of_func_decl(decl)); Z3_CATCH_RETURN(0); @@ -574,16 +558,13 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - ptr_vector const * decls = dt_util.get_datatype_constructors(tuple); - if (!decls || decls->size() != 1) { + ptr_vector const & decls = dt_util.get_datatype_constructors(tuple); + if (decls.size() != 1) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - ptr_vector const * accs = dt_util.get_constructor_accessors((*decls)[0]); - if (!accs) { - return 0; - } - return accs->size(); + ptr_vector const & accs = dt_util.get_constructor_accessors(decls[0]); + return accs.size(); Z3_CATCH_RETURN(0); } @@ -597,21 +578,17 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const * decls = dt_util.get_datatype_constructors(tuple); - if (!decls || decls->size() != 1) { + ptr_vector const & decls = dt_util.get_datatype_constructors(tuple); + if (decls.size() != 1) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const * accs = dt_util.get_constructor_accessors((*decls)[0]); - if (!accs) { - SET_ERROR_CODE(Z3_INVALID_ARG); - RETURN_Z3(0); - } - if (accs->size() <= i) { + ptr_vector const & accs = dt_util.get_constructor_accessors((decls)[0]); + if (accs.size() <= i) { SET_ERROR_CODE(Z3_IOB); RETURN_Z3(0); } - func_decl* acc = (*accs)[i]; + func_decl* acc = (accs)[i]; mk_c(c)->save_ast_trail(acc); RETURN_Z3(of_func_decl(acc)); Z3_CATCH_RETURN(0); diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 9ebfdfbef..9211c5899 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -907,7 +907,6 @@ public: void pp_dt(ast_mark& mark, sort* s) { SASSERT(s->is_sort_of(m_dt_fid, DATATYPE_SORT)); datatype_util util(m_manager); - ptr_vector const* decls; ptr_vector rec_sorts; rec_sorts.push_back(s); @@ -916,10 +915,10 @@ public: // collect siblings and sorts that have not already been printed. for (unsigned h = 0; h < rec_sorts.size(); ++h) { s = rec_sorts[h]; - decls = util.get_datatype_constructors(s); + ptr_vector const& decls = util.get_datatype_constructors(s); - for (unsigned i = 0; i < decls->size(); ++i) { - func_decl* f = (*decls)[i]; + for (unsigned i = 0; i < decls.size(); ++i) { + func_decl* f = decls[i]; for (unsigned j = 0; j < f->get_arity(); ++j) { sort* s2 = f->get_domain(j); if (!mark.is_marked(s2)) { @@ -955,11 +954,11 @@ public: m_out << "("; m_out << m_renaming.get_symbol(s->get_name()); m_out << " "; - decls = util.get_datatype_constructors(s); + ptr_vector const& decls = util.get_datatype_constructors(s); - for (unsigned i = 0; i < decls->size(); ++i) { - func_decl* f = (*decls)[i]; - ptr_vector const& accs = *util.get_constructor_accessors(f); + for (unsigned i = 0; i < decls.size(); ++i) { + func_decl* f = decls[i]; + ptr_vector const& accs = util.get_constructor_accessors(f); if (m_is_smt2 || accs.size() > 0) { m_out << "("; } @@ -976,7 +975,7 @@ public: } if (m_is_smt2 || accs.size() > 0) { m_out << ")"; - if (i + 1 < decls->size()) { + if (i + 1 < decls.size()) { m_out << " "; } } diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index 446992105..e2aa54236 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -20,6 +20,7 @@ Revision History: #include "util/warning.h" #include "ast/ast_smt2_pp.h" +#ifndef DATATYPE_V2 /** \brief Auxiliary class used to declare inductive datatypes. @@ -802,11 +803,11 @@ func_decl * datatype_util::get_constructor(sort * ty, unsigned c_id) { return d; } -ptr_vector const * datatype_util::get_datatype_constructors(sort * ty) { +ptr_vector const & datatype_util::get_datatype_constructors(sort * ty) { SASSERT(is_datatype(ty)); ptr_vector * r = 0; if (m_datatype2constructors.find(ty, r)) - return r; + return *r; r = alloc(ptr_vector); m_asts.push_back(ty); m_vectors.push_back(r); @@ -819,7 +820,7 @@ ptr_vector const * datatype_util::get_datatype_constructors(sort * ty m_asts.push_back(c); r->push_back(c); } - return r; + return *r; } /** @@ -854,12 +855,12 @@ func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vector const * constructors = get_datatype_constructors(ty); + ptr_vector const & constructors = get_datatype_constructors(ty); // step 1) - unsigned sz = constructors->size(); + unsigned sz = constructors.size(); ++m_start; for (unsigned j = 0; j < sz; ++j) { - func_decl * c = (*constructors)[(j + m_start) % sz]; + func_decl * c = constructors[(j + m_start) % sz]; unsigned num_args = c->get_arity(); unsigned i = 0; for (; i < num_args; i++) { @@ -872,7 +873,7 @@ func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vectorget_name() << "\n";); unsigned num_args = c->get_arity(); unsigned i = 0; @@ -915,11 +916,11 @@ func_decl * datatype_util::get_constructor_recognizer(func_decl * constructor) { return d; } -ptr_vector const * datatype_util::get_constructor_accessors(func_decl * constructor) { +ptr_vector const & datatype_util::get_constructor_accessors(func_decl * constructor) { SASSERT(is_constructor(constructor)); ptr_vector * res = 0; if (m_constructor2accessors.find(constructor, res)) - return res; + return *res; res = alloc(ptr_vector); m_asts.push_back(constructor); m_vectors.push_back(res); @@ -938,7 +939,7 @@ ptr_vector const * datatype_util::get_constructor_accessors(func_decl m_asts.push_back(d); res->push_back(d); } - return res; + return *res; } func_decl * datatype_util::get_accessor_constructor(func_decl * accessor) { @@ -988,7 +989,7 @@ bool datatype_util::is_enum_sort(sort* s) { bool r = false; if (m_is_enum.find(s, r)) return r; - ptr_vector const& cnstrs = *get_datatype_constructors(s); + ptr_vector const& cnstrs = get_datatype_constructors(s); r = true; for (unsigned i = 0; r && i < cnstrs.size(); ++i) { r = cnstrs[i]->get_arity() == 0; @@ -1048,14 +1049,14 @@ void datatype_util::display_datatype(sort *s0, std::ostream& strm) { todo.pop_back(); strm << s->get_name() << " =\n"; - ptr_vector const * cnstrs = get_datatype_constructors(s); - for (unsigned i = 0; i < cnstrs->size(); ++i) { - func_decl* cns = (*cnstrs)[i]; + ptr_vector const & cnstrs = get_datatype_constructors(s); + for (unsigned i = 0; i < cnstrs.size(); ++i) { + func_decl* cns = cnstrs[i]; func_decl* rec = get_constructor_recognizer(cns); strm << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; - ptr_vector const * accs = get_constructor_accessors(cns); - for (unsigned j = 0; j < accs->size(); ++j) { - func_decl* acc = (*accs)[j]; + ptr_vector const & accs = get_constructor_accessors(cns); + for (unsigned j = 0; j < accs.size(); ++j) { + func_decl* acc = accs[j]; sort* s1 = acc->get_range(); strm << "(" << acc->get_name() << ": " << s1->get_name() << ") "; if (is_datatype(s1) && are_siblings(s1, s0) && !mark.is_marked(s1)) { @@ -1090,3 +1091,5 @@ bool datatype_util::is_constructor_of(unsigned num_params, parameter const* para params[1] == f->get_parameter(1); } + +#endif diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index dcd352471..b9c2602ef 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -16,9 +16,15 @@ Author: Revision History: --*/ +// define DATATYPE_V2 +#ifdef DATATYPE_V2 +#include "ast/datatype_decl_plugin2.h" +#else + #ifndef DATATYPE_DECL_PLUGIN_H_ #define DATATYPE_DECL_PLUGIN_H_ + #include "ast/ast.h" #include "util/tptr.h" #include "util/buffer.h" @@ -210,7 +216,7 @@ public: bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); } bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } - ptr_vector const * get_datatype_constructors(sort * ty); + ptr_vector const & get_datatype_constructors(sort * ty); unsigned get_datatype_num_constructors(sort * ty) { SASSERT(is_datatype(ty)); unsigned tid = ty->get_parameter(1).get_int(); @@ -230,7 +236,7 @@ public: unsigned get_recognizer_constructor_idx(func_decl * f) const { SASSERT(is_recognizer(f)); return f->get_parameter(1).get_int(); } func_decl * get_non_rec_constructor(sort * ty); func_decl * get_constructor_recognizer(func_decl * constructor); - ptr_vector const * get_constructor_accessors(func_decl * constructor); + ptr_vector const & get_constructor_accessors(func_decl * constructor); func_decl * get_accessor_constructor(func_decl * accessor); func_decl * get_recognizer_constructor(func_decl * recognizer); family_id get_family_id() const { return m_family_id; } @@ -245,3 +251,4 @@ public: #endif /* DATATYPE_DECL_PLUGIN_H_ */ +#endif /* DATATYPE_V2 */ diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 8233da7d9..2fc62af31 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -22,6 +22,7 @@ Revision History: #include "ast/ast_smt2_pp.h" +#ifdef DATATYPE_V2 namespace datatype { void accessor::fix_range(sort_ref_vector const& dts) { @@ -49,6 +50,10 @@ namespace datatype { def const& accessor::get_def() const { return m_constructor->get_def(); } util& accessor::u() const { return m_constructor->u(); } + constructor::~constructor() { + for (accessor* a : m_accessors) dealloc(a); + m_accessors.reset(); + } util& constructor::u() const { return m_def->u(); } func_decl_ref constructor::instantiate(sort_ref_vector const& ps) const { @@ -164,7 +169,7 @@ namespace datatype { sort* r = to_sort(parameters[i].get_ast()); S.insert(d->params()[i], r->get_num_elements()); } - sort_size ts = d->sort_size()->fold(S); + sort_size ts = d->sort_size()->eval(S); s->set_num_elements(ts); } return s; @@ -278,7 +283,9 @@ namespace datatype { def& plugin::add(symbol const& name, unsigned n, sort * const * params) { ast_manager& m = *m_manager; - def* d = alloc(def, m, u(), name, m_class_id, n, params); + def* d = 0; + if (m_defs.find(name, d)) dealloc(d); + d = alloc(def, m, u(), name, m_class_id, n, params); m_defs.insert(name, d); m_def_block.push_back(name); return *d; @@ -895,3 +902,4 @@ namespace datatype { } } } +#endif diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index c540b7c1c..c8aa042f1 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -24,17 +24,12 @@ Revision History: #include "util/symbol_table.h" #include "util/obj_hashtable.h" -namespace datatype { - - class util; - class def; - class accessor; - class constructor; +#ifdef DATATYPE_V2 enum sort_kind { DATATYPE_SORT }; - + enum op_kind { OP_DT_CONSTRUCTOR, OP_DT_RECOGNISER, @@ -43,6 +38,14 @@ namespace datatype { LAST_DT_OP }; +namespace datatype { + + class util; + class def; + class accessor; + class constructor; + + class accessor { symbol m_name; sort* m_range; @@ -109,7 +112,7 @@ namespace datatype { static size* mk_power(size* a1, size* a2); virtual size* subst(obj_map& S) = 0; - virtual sort_size fold(obj_map const& S) = 0; + virtual sort_size eval(obj_map const& S) = 0; }; struct offset : public size { @@ -117,16 +120,16 @@ namespace datatype { offset(sort_size const& s): m_offset(s) {} virtual ~offset() {} virtual size* subst(obj_map& S) { return this; } - virtual sort_size fold(obj_map const& S) { return m_offset; } + virtual sort_size eval(obj_map const& S) { return m_offset; } }; struct plus : public size { size* m_arg1, *m_arg2; plus(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref();} virtual ~plus() { m_arg1->dec_ref(); m_arg2->dec_ref(); } virtual size* subst(obj_map& S) { return mk_plus(m_arg1->subst(S), m_arg2->subst(S)); } - virtual sort_size fold(obj_map const& S) { - sort_size s1 = m_arg1->fold(S); - sort_size s2 = m_arg2->fold(S); + virtual sort_size eval(obj_map const& S) { + sort_size s1 = m_arg1->eval(S); + sort_size s2 = m_arg2->eval(S); if (s1.is_infinite()) return s1; if (s2.is_infinite()) return s2; if (s1.is_very_big()) return s1; @@ -140,9 +143,9 @@ namespace datatype { times(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } virtual ~times() { m_arg1->dec_ref(); m_arg2->dec_ref(); } virtual size* subst(obj_map& S) { return mk_times(m_arg1->subst(S), m_arg2->subst(S)); } - virtual sort_size fold(obj_map const& S) { - sort_size s1 = m_arg1->fold(S); - sort_size s2 = m_arg2->fold(S); + virtual sort_size eval(obj_map const& S) { + sort_size s1 = m_arg1->eval(S); + sort_size s2 = m_arg2->eval(S); if (s1.is_infinite()) return s1; if (s2.is_infinite()) return s2; if (s1.is_very_big()) return s1; @@ -156,9 +159,9 @@ namespace datatype { power(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } virtual ~power() { m_arg1->dec_ref(); m_arg2->dec_ref(); } virtual size* subst(obj_map& S) { return mk_power(m_arg1->subst(S), m_arg2->subst(S)); } - virtual sort_size fold(obj_map const& S) { - sort_size s1 = m_arg1->fold(S); - sort_size s2 = m_arg2->fold(S); + virtual sort_size eval(obj_map const& S) { + sort_size s1 = m_arg1->eval(S); + sort_size s2 = m_arg2->eval(S); // s1^s2 if (s1.is_infinite()) return s1; if (s2.is_infinite()) return s2; @@ -176,7 +179,7 @@ namespace datatype { sparam(sort_ref& p): m_param(p) {} virtual ~sparam() {} virtual size* subst(obj_map& S) { return S[m_param]; } - virtual sort_size fold(obj_map const& S) { return S[m_param]; } + virtual sort_size eval(obj_map const& S) { return S[m_param]; } }; }; @@ -201,6 +204,8 @@ namespace datatype { {} ~def() { if (m_sort_size) m_sort_size->dec_ref(); + for (constructor* c : m_constructors) dealloc(c); + m_constructors.reset(); } void add(constructor* c) { m_constructors.push_back(c); @@ -361,5 +366,36 @@ namespace datatype { }; +#ifdef DATATYPE_V2 +typedef datatype::accessor accessor_decl; +typedef datatype::constructor constructor_decl; +typedef datatype::def datatype_decl; +typedef datatype::decl::plugin datatype_decl_plugin; +typedef datatype::util datatype_util; + +class type_ref { + void * m_data; +public: + type_ref():m_data(TAG(void *, static_cast(0), 1)) {} + type_ref(int idx):m_data(BOXINT(void *, idx)) {} + type_ref(sort * s):m_data(TAG(void *, s, 1)) {} + + bool is_idx() const { return GET_TAG(m_data) == 0; } + bool is_sort() const { return GET_TAG(m_data) == 1; } + sort * get_sort() const { return UNTAG(sort *, m_data); } + int get_idx() const { return UNBOXINT(m_data); } +}; + +inline accessor_decl * mk_accessor_decl(symbol const & n, type_ref const & t) { + if (t.is_idx()) { + return alloc(accessor_decl, n, t.get_idx()); + } + else { + return alloc(accessor_decl, n, t.get_sort()); + } +} +#endif + #endif /* DATATYPE_DECL_PLUGIN_H_ */ +#endif DATATYPE_V2 diff --git a/src/ast/decl_collector.cpp b/src/ast/decl_collector.cpp index e000f43df..bf509aba5 100644 --- a/src/ast/decl_collector.cpp +++ b/src/ast/decl_collector.cpp @@ -28,9 +28,9 @@ void decl_collector::visit_sort(sort * n) { unsigned num_cnstr = m_dt_util.get_datatype_num_constructors(n); for (unsigned i = 0; i < num_cnstr; i++) { - func_decl * cnstr = m_dt_util.get_datatype_constructors(n)->get(i); + func_decl * cnstr = m_dt_util.get_datatype_constructors(n).get(i); m_decls.push_back(cnstr); - ptr_vector const & cnstr_acc = *m_dt_util.get_constructor_accessors(cnstr); + ptr_vector const & cnstr_acc = m_dt_util.get_constructor_accessors(cnstr); unsigned num_cas = cnstr_acc.size(); for (unsigned j = 0; j < num_cas; j++) { func_decl * accsr = cnstr_acc.get(j); diff --git a/src/ast/rewriter/datatype_rewriter.cpp b/src/ast/rewriter/datatype_rewriter.cpp index d38c9e476..8746fab86 100644 --- a/src/ast/rewriter/datatype_rewriter.cpp +++ b/src/ast/rewriter/datatype_rewriter.cpp @@ -47,11 +47,11 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr func_decl * c_decl = a->get_decl(); if (c_decl != m_util.get_accessor_constructor(f)) return BR_FAILED; - ptr_vector const * acc = m_util.get_constructor_accessors(c_decl); - SASSERT(acc && acc->size() == a->get_num_args()); - unsigned num = acc->size(); + ptr_vector const & acc = m_util.get_constructor_accessors(c_decl); + SASSERT(acc.size() == a->get_num_args()); + unsigned num = acc.size(); for (unsigned i = 0; i < num; ++i) { - if (f == (*acc)[i]) { + if (f == acc[i]) { // found it. result = a->get_arg(i); return BR_DONE; @@ -70,13 +70,13 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr result = a; return BR_DONE; } - ptr_vector const * acc = m_util.get_constructor_accessors(c_decl); - SASSERT(acc && acc->size() == a->get_num_args()); - unsigned num = acc->size(); + ptr_vector const & acc = m_util.get_constructor_accessors(c_decl); + SASSERT(acc.size() == a->get_num_args()); + unsigned num = acc.size(); ptr_buffer new_args; for (unsigned i = 0; i < num; ++i) { - if (f == (*acc)[i]) { + if (f == acc[i]) { new_args.push_back(args[1]); } else { diff --git a/src/ast/rewriter/enum2bv_rewriter.cpp b/src/ast/rewriter/enum2bv_rewriter.cpp index eb6b195f0..b2ecbcc24 100644 --- a/src/ast/rewriter/enum2bv_rewriter.cpp +++ b/src/ast/rewriter/enum2bv_rewriter.cpp @@ -130,7 +130,7 @@ struct enum2bv_rewriter::imp { m_imp.m_bounds.push_back(m_bv.mk_ule(result, m_bv.mk_numeral(nc-1, bv_size))); } expr_ref f_def(m); - ptr_vector const& cs = *m_dt.get_datatype_constructors(s); + ptr_vector const& cs = m_dt.get_datatype_constructors(s); f_def = m.mk_const(cs[nc-1]); for (unsigned i = nc - 1; i > 0; ) { --i; diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 8b1a89f3f..109fe1718 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1954,19 +1954,19 @@ cmd_context::dt_eh::~dt_eh() { void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) { TRACE("new_dt_eh", tout << "new datatype: "; m_owner.pm().display(tout, dt); tout << "\n";); - ptr_vector const * constructors = m_dt_util.get_datatype_constructors(dt); - unsigned num_constructors = constructors->size(); + ptr_vector const & constructors = m_dt_util.get_datatype_constructors(dt); + unsigned num_constructors = constructors.size(); for (unsigned j = 0; j < num_constructors; j++) { - func_decl * c = constructors->get(j); + func_decl * c = constructors[j]; m_owner.insert(c); TRACE("new_dt_eh", tout << "new constructor: " << c->get_name() << "\n";); func_decl * r = m_dt_util.get_constructor_recognizer(c); m_owner.insert(r); TRACE("new_dt_eh", tout << "new recognizer: " << r->get_name() << "\n";); - ptr_vector const * accessors = m_dt_util.get_constructor_accessors(c); - unsigned num_accessors = accessors->size(); + ptr_vector const & accessors = m_dt_util.get_constructor_accessors(c); + unsigned num_accessors = accessors.size(); for (unsigned k = 0; k < num_accessors; k++) { - func_decl * a = accessors->get(k); + func_decl * a = accessors[k]; m_owner.insert(a); TRACE("new_dt_eh", tout << "new accessor: " << a->get_name() << "\n";); } diff --git a/src/muz/base/dl_rule.h b/src/muz/base/dl_rule.h index ea0e64e4f..51d673ba5 100644 --- a/src/muz/base/dl_rule.h +++ b/src/muz/base/dl_rule.h @@ -65,7 +65,7 @@ namespace datalog { else if (m_dt.is_accessor(n)) { sort* s = m.get_sort(n->get_arg(0)); SASSERT(m_dt.is_datatype(s)); - if (m_dt.get_datatype_constructors(s)->size() > 1) { + if (m_dt.get_datatype_constructors(s).size() > 1) { m_found = true; m_func = n->get_decl(); } diff --git a/src/muz/base/rule_properties.cpp b/src/muz/base/rule_properties.cpp index 21317a07c..75487bbfb 100644 --- a/src/muz/base/rule_properties.cpp +++ b/src/muz/base/rule_properties.cpp @@ -191,7 +191,7 @@ void rule_properties::operator()(app* n) { else if (m_dt.is_accessor(n)) { sort* s = m.get_sort(n->get_arg(0)); SASSERT(m_dt.is_datatype(s)); - if (m_dt.get_datatype_constructors(s)->size() > 1) { + if (m_dt.get_datatype_constructors(s).size() > 1) { m_uninterp_funs.insert(n->get_decl(), m_rule); } } diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index 6d2f88019..b9dbe83ca 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -808,7 +808,7 @@ namespace datalog { datatype_util dtu(m); ptr_vector sorts; func_decl* p = r.get_decl(); - ptr_vector const& succs = *dtu.get_datatype_constructors(m.get_sort(path)); + ptr_vector const& succs = dtu.get_datatype_constructors(m.get_sort(path)); // populate substitution of bound variables. r.get_vars(m, sorts); sub.reset(); @@ -871,8 +871,8 @@ namespace datalog { path_var = m.mk_var(0, m_path_sort); trace_var = m.mk_var(1, pred_sort); // sort* sorts[2] = { pred_sort, m_path_sort }; - ptr_vector const& cnstrs = *dtu.get_datatype_constructors(pred_sort); - ptr_vector const& succs = *dtu.get_datatype_constructors(m_path_sort); + ptr_vector const& cnstrs = dtu.get_datatype_constructors(pred_sort); + ptr_vector const& succs = dtu.get_datatype_constructors(m_path_sort); SASSERT(cnstrs.size() == rls.size()); pred = m.mk_app(mk_predicate(p), trace_var.get(), path_var.get()); for (unsigned i = 0; i < rls.size(); ++i) { @@ -1039,8 +1039,8 @@ namespace datalog { sort* trace_sort = m.get_sort(trace); func_decl* p = m_sort2pred.find(trace_sort); datalog::rule_vector const& rules = b.m_rules.get_predicate_rules(p); - ptr_vector const& cnstrs = *dtu.get_datatype_constructors(trace_sort); - ptr_vector const& succs = *dtu.get_datatype_constructors(m_path_sort); + ptr_vector const& cnstrs = dtu.get_datatype_constructors(trace_sort); + ptr_vector const& succs = dtu.get_datatype_constructors(m_path_sort); for (unsigned i = 0; i < cnstrs.size(); ++i) { if (trace->get_decl() == cnstrs[i]) { svector > positions; diff --git a/src/muz/pdr/pdr_prop_solver.cpp b/src/muz/pdr/pdr_prop_solver.cpp index 3055985f4..1bca8e925 100644 --- a/src/muz/pdr/pdr_prop_solver.cpp +++ b/src/muz/pdr/pdr_prop_solver.cpp @@ -135,7 +135,7 @@ namespace pdr { func_decl* f = to_app(val)->get_decl(); func_decl* r = dt.get_constructor_recognizer(f); conjs[i] = m.mk_app(r, c); - ptr_vector const& acc = *dt.get_constructor_accessors(f); + ptr_vector const& acc = dt.get_constructor_accessors(f); for (unsigned j = 0; j < acc.size(); ++j) { conjs.push_back(m.mk_eq(apply_accessor(acc, j, f, c), to_app(val)->get_arg(j))); } diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp index a277c9ed6..14d8899c5 100644 --- a/src/muz/spacer/spacer_util.cpp +++ b/src/muz/spacer/spacer_util.cpp @@ -711,7 +711,7 @@ void expand_literals(ast_manager &m, expr_ref_vector& conjs) func_decl* f = to_app(val)->get_decl(); func_decl* r = dt.get_constructor_recognizer(f); conjs[i] = m.mk_app(r, c); - ptr_vector const& acc = *dt.get_constructor_accessors(f); + ptr_vector const& acc = dt.get_constructor_accessors(f); for (unsigned j = 0; j < acc.size(); ++j) { conjs.push_back(m.mk_eq(apply_accessor(m, acc, j, f, c), to_app(val)->get_arg(j))); } diff --git a/src/qe/qe_datatype_plugin.cpp b/src/qe/qe_datatype_plugin.cpp index 4178c3af3..eff230ffe 100644 --- a/src/qe/qe_datatype_plugin.cpp +++ b/src/qe/qe_datatype_plugin.cpp @@ -262,7 +262,7 @@ namespace qe { } func_decl* c = a->get_decl(); func_decl* r = m_util.get_constructor_recognizer(c); - ptr_vector const & acc = *m_util.get_constructor_accessors(c); + ptr_vector const & acc = m_util.get_constructor_accessors(c); SASSERT(acc.size() == a->get_num_args()); // // It suffices to solve just the first available equality. @@ -379,7 +379,7 @@ namespace qe { return false; } func_decl* c = l->get_decl(); - ptr_vector const& acc = *m_util.get_constructor_accessors(c); + ptr_vector const& acc = m_util.get_constructor_accessors(c); func_decl* rec = m_util.get_constructor_recognizer(c); expr_ref_vector conj(m); conj.push_back(m.mk_app(rec, r)); @@ -626,7 +626,7 @@ namespace qe { // If 'x' does not yet have a recognizer, then branch according to recognizers. // if (!has_recognizer(x, fml, r, c)) { - c = (*m_datatype_util.get_datatype_constructors(s))[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; r = m_datatype_util.get_constructor_recognizer(c); app* is_c = m.mk_app(r, x); // assert v => r(x) @@ -673,7 +673,7 @@ namespace qe { // Introduce auxiliary variable to eliminate. // if (!has_recognizer(x, fml, r, c)) { - c = (*m_datatype_util.get_datatype_constructors(s))[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; r = m_datatype_util.get_constructor_recognizer(c); app* is_c = m.mk_app(r, x); fml = m.mk_and(is_c, fml); @@ -774,7 +774,7 @@ namespace qe { return; } - c = (*m_datatype_util.get_datatype_constructors(s))[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; r = m_datatype_util.get_constructor_recognizer(c); app* is_c = m.mk_app(r, x); @@ -794,7 +794,7 @@ namespace qe { else { SASSERT(vl.is_unsigned()); SASSERT(vl.get_unsigned() < m_datatype_util.get_datatype_num_constructors(s)); - c = (*m_datatype_util.get_datatype_constructors(s))[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; } subst_constructor(x, c, fml, def); } diff --git a/src/qe/qe_datatypes.cpp b/src/qe/qe_datatypes.cpp index db1e6ec85..f16bdda59 100644 --- a/src/qe/qe_datatypes.cpp +++ b/src/qe/qe_datatypes.cpp @@ -75,7 +75,7 @@ namespace qe { app_ref arg(m); SASSERT(dt.is_constructor(m_val)); func_decl* f = m_val->get_decl(); - ptr_vector const& acc = *dt.get_constructor_accessors(f); + ptr_vector const& acc = dt.get_constructor_accessors(f); for (unsigned i = 0; i < acc.size(); ++i) { arg = m.mk_fresh_const(acc[i]->get_name().str().c_str(), acc[i]->get_range()); model.register_decl(arg->get_decl(), m_val->get_arg(i)); @@ -152,7 +152,7 @@ namespace qe { } func_decl* c = a->get_decl(); func_decl* rec = dt.get_constructor_recognizer(c); - ptr_vector const & acc = *dt.get_constructor_accessors(c); + ptr_vector const & acc = dt.get_constructor_accessors(c); SASSERT(acc.size() == a->get_num_args()); // // It suffices to solve just the first available equality. @@ -230,7 +230,7 @@ namespace qe { return false; } func_decl* c = to_app(l)->get_decl(); - ptr_vector const& acc = *dt.get_constructor_accessors(c); + ptr_vector const& acc = dt.get_constructor_accessors(c); if (!is_app_of(r, c)) { lits.push_back(m.mk_app(dt.get_constructor_recognizer(c), r)); } diff --git a/src/qe/qe_lite.cpp b/src/qe/qe_lite.cpp index 257331161..10af3be25 100644 --- a/src/qe/qe_lite.cpp +++ b/src/qe/qe_lite.cpp @@ -671,7 +671,7 @@ namespace eq { 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); + 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))); } diff --git a/src/smt/proto_model/datatype_factory.cpp b/src/smt/proto_model/datatype_factory.cpp index d738f2cbd..653ef034a 100644 --- a/src/smt/proto_model/datatype_factory.cpp +++ b/src/smt/proto_model/datatype_factory.cpp @@ -88,8 +88,8 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) { // Traverse constructors, and try to invoke get_fresh_value of one of the arguments (if the argument is not a sibling datatype of s). // If the argumet is a sibling datatype of s, then // use get_last_fresh_value. - ptr_vector const * constructors = m_util.get_datatype_constructors(s); - for (func_decl * constructor : *constructors) { + ptr_vector const & constructors = m_util.get_datatype_constructors(s); + for (func_decl * constructor : constructors) { expr_ref_vector args(m_manager); bool found_fresh_arg = false; bool recursive = false; @@ -151,8 +151,8 @@ expr * datatype_factory::get_fresh_value(sort * s) { // Traverse constructors, and try to invoke get_fresh_value of one of the // arguments (if the argument is not a sibling datatype of s). // Two datatypes are siblings if they were defined together in the same mutually recursive definition. - ptr_vector const * constructors = m_util.get_datatype_constructors(s); - for (func_decl * constructor : *constructors) { + ptr_vector const & constructors = m_util.get_datatype_constructors(s); + for (func_decl * constructor : constructors) { expr_ref_vector args(m_manager); bool found_fresh_arg = false; unsigned num = constructor->get_arity(); @@ -189,8 +189,8 @@ expr * datatype_factory::get_fresh_value(sort * s) { while(true) { ++num_iterations; TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";); - ptr_vector const * constructors = m_util.get_datatype_constructors(s); - for (func_decl * constructor : *constructors) { + ptr_vector const & constructors = m_util.get_datatype_constructors(s); + for (func_decl * constructor : constructors) { expr_ref_vector args(m_manager); bool found_sibling = false; unsigned num = constructor->get_arity(); diff --git a/src/smt/smt_value_sort.cpp b/src/smt/smt_value_sort.cpp index 56768b91a..3eeb3461d 100644 --- a/src/smt/smt_value_sort.cpp +++ b/src/smt/smt_value_sort.cpp @@ -52,7 +52,7 @@ namespace smt { // simple } else if (data.is_datatype(s)) { - ptr_vector const& cs = *data.get_datatype_constructors(s); + ptr_vector const& cs = data.get_datatype_constructors(s); for (unsigned i = 0; i < cs.size(); ++i) { func_decl* f = cs[i]; for (unsigned j = 0; j < f->get_arity(); ++j) { diff --git a/src/smt/theory_datatype.cpp b/src/smt/theory_datatype.cpp index beb1acf63..33b4b194d 100644 --- a/src/smt/theory_datatype.cpp +++ b/src/smt/theory_datatype.cpp @@ -97,12 +97,9 @@ namespace smt { SASSERT(m_util.is_datatype(get_manager().get_sort(n->get_owner()))); ast_manager & m = get_manager(); ptr_vector args; - ptr_vector const * accessors = m_util.get_constructor_accessors(c); - SASSERT(c->get_arity() == accessors->size()); - ptr_vector::const_iterator it = accessors->begin(); - ptr_vector::const_iterator end = accessors->end(); - for (; it != end; ++it) { - func_decl * d = *it; + ptr_vector const & accessors = m_util.get_constructor_accessors(c); + SASSERT(c->get_arity() == accessors.size()); + for (func_decl * d : accessors) { SASSERT(d->get_arity() == 1); expr * acc = m.mk_app(d, n->get_owner()); args.push_back(acc); @@ -123,15 +120,14 @@ namespace smt { SASSERT(is_constructor(n)); ast_manager & m = get_manager(); func_decl * d = n->get_decl(); - ptr_vector const * accessors = m_util.get_constructor_accessors(d); - SASSERT(n->get_num_args() == accessors->size()); - ptr_vector::const_iterator it = accessors->begin(); - ptr_vector::const_iterator end = accessors->end(); - for (unsigned i = 0; it != end; ++it, ++i) { - func_decl * acc = *it; + ptr_vector const & accessors = m_util.get_constructor_accessors(d); + SASSERT(n->get_num_args() == accessors.size()); + unsigned i = 0; + for (func_decl * acc : accessors) { app * acc_app = m.mk_app(acc, n->get_owner()); enode * arg = n->get_arg(i); assert_eq_axiom(arg, acc_app, null_literal); + ++i; } } @@ -172,15 +168,12 @@ namespace smt { func_decl * acc = to_func_decl(upd->get_parameter(0).get_ast()); func_decl * con = m_util.get_accessor_constructor(acc); func_decl * rec = m_util.get_constructor_recognizer(con); - ptr_vector const * accessors = m_util.get_constructor_accessors(con); - ptr_vector::const_iterator it = accessors->begin(); - ptr_vector::const_iterator end = accessors->end(); + ptr_vector const & accessors = m_util.get_constructor_accessors(con); app_ref rec_app(m.mk_app(rec, arg1), m); ctx.internalize(rec_app, false); literal is_con(ctx.get_bool_var(rec_app)); - for (; it != end; ++it) { + for (func_decl* acc1 : accessors) { enode* arg; - func_decl * acc1 = *it; if (acc1 == acc) { arg = n->get_arg(1); } @@ -215,7 +208,7 @@ namespace smt { ast_manager & m = get_manager(); sort * s = m.get_sort(n->get_owner()); if (m_util.get_datatype_num_constructors(s) == 1) { - func_decl * c = m_util.get_datatype_constructors(s)->get(0); + func_decl * c = m_util.get_datatype_constructors(s)[0]; assert_is_constructor_axiom(n, c, null_literal); } else { @@ -716,8 +709,8 @@ namespace smt { enode * r = d->m_recognizers[unassigned_idx]; literal consequent; if (!r) { - ptr_vector const * constructors = m_util.get_datatype_constructors(dt); - func_decl * rec = m_util.get_constructor_recognizer(constructors->get(unassigned_idx)); + ptr_vector const & constructors = m_util.get_datatype_constructors(dt); + func_decl * rec = m_util.get_constructor_recognizer(constructors[unassigned_idx]); app * rec_app = get_manager().mk_app(rec, n->get_owner()); ctx.internalize(rec_app, false); consequent = literal(ctx.get_bool_var(rec_app)); @@ -781,9 +774,9 @@ namespace smt { for (unsigned idx = 0; it != end; ++it, ++idx) { enode * curr = *it; if (curr == 0) { - ptr_vector const * constructors = m_util.get_datatype_constructors(s); + ptr_vector const & constructors = m_util.get_datatype_constructors(s); // found empty slot... - r = m_util.get_constructor_recognizer(constructors->get(idx)); + r = m_util.get_constructor_recognizer(constructors[idx]); break; } else if (!ctx.is_relevant(curr)) { diff --git a/src/tactic/core/elim_uncnstr_tactic.cpp b/src/tactic/core/elim_uncnstr_tactic.cpp index 73adabb6f..a13cd54d8 100644 --- a/src/tactic/core/elim_uncnstr_tactic.cpp +++ b/src/tactic/core/elim_uncnstr_tactic.cpp @@ -174,11 +174,8 @@ class elim_uncnstr_tactic : public tactic { if (fid == m_dt_util.get_family_id()) { // In the current implementation, I only handle the case where // the datatype has a recursive constructor. - ptr_vector const * constructors = m_dt_util.get_datatype_constructors(s); - ptr_vector::const_iterator it = constructors->begin(); - ptr_vector::const_iterator end = constructors->end(); - for (; it != end; ++it) { - func_decl * constructor = *it; + ptr_vector const & constructors = m_dt_util.get_datatype_constructors(s); + for (func_decl * constructor : constructors) { unsigned num = constructor->get_arity(); unsigned target = UINT_MAX; for (unsigned i = 0; i < num; i++) { @@ -707,10 +704,10 @@ class elim_uncnstr_tactic : public tactic { app * u; if (!mk_fresh_uncnstr_var_for(f, num, args, u)) return u; - ptr_vector const * accs = m_dt_util.get_constructor_accessors(c); + ptr_vector const & accs = m_dt_util.get_constructor_accessors(c); ptr_buffer new_args; - for (unsigned i = 0; i < accs->size(); i++) { - if (accs->get(i) == f) + for (unsigned i = 0; i < accs.size(); i++) { + if (accs[i] == f) new_args.push_back(u); else new_args.push_back(m().get_some_value(c->get_domain(i))); @@ -726,9 +723,9 @@ class elim_uncnstr_tactic : public tactic { return u; if (!m_mc) return u; - ptr_vector const * accs = m_dt_util.get_constructor_accessors(f); + ptr_vector const & accs = m_dt_util.get_constructor_accessors(f); for (unsigned i = 0; i < num; i++) { - add_def(args[i], m().mk_app(accs->get(i), u)); + add_def(args[i], m().mk_app(accs[i], u)); } return u; } diff --git a/src/tactic/portfolio/enum2bv_solver.cpp b/src/tactic/portfolio/enum2bv_solver.cpp index 36a178c41..db7cebd6e 100644 --- a/src/tactic/portfolio/enum2bv_solver.cpp +++ b/src/tactic/portfolio/enum2bv_solver.cpp @@ -136,7 +136,7 @@ public: if (m.is_eq(b, u, v) && is_uninterp_const(u) && m_rewriter.bv2enum().find(to_app(u)->get_decl(), f) && bv.is_numeral(v, num, bvsize)) { SASSERT(num.is_unsigned()); expr_ref head(m); - ptr_vector const& enums = *dt.get_datatype_constructors(f->get_range()); + ptr_vector const& enums = dt.get_datatype_constructors(f->get_range()); if (enums.size() > num.get_unsigned()) { head = m.mk_eq(m.mk_const(f), m.mk_const(enums[num.get_unsigned()])); consequences[i] = m.mk_implies(a, head); diff --git a/src/test/get_consequences.cpp b/src/test/get_consequences.cpp index 9337dcee3..e8868c661 100644 --- a/src/test/get_consequences.cpp +++ b/src/test/get_consequences.cpp @@ -71,7 +71,7 @@ void test2() { sort* rgb = new_sorts[0].get(); expr_ref x = mk_const(m, "x", rgb), y = mk_const(m, "y", rgb), z = mk_const(m, "z", rgb); - ptr_vector const& enums = *dtutil.get_datatype_constructors(rgb); + ptr_vector const& enums = dtutil.get_datatype_constructors(rgb); expr_ref r = expr_ref(m.mk_const(enums[0]), m); expr_ref g = expr_ref(m.mk_const(enums[1]), m); expr_ref b = expr_ref(m.mk_const(enums[2]), m); From f12a4f04fdf5bcd16a120ffe1c1d64a5b4f02359 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 4 Sep 2017 09:28:40 -0700 Subject: [PATCH 245/488] aligning simplifier and rewriter for regression tests Signed-off-by: Nikolaj Bjorner --- src/api/api_datatype.cpp | 10 +++-- src/ast/datatype_decl_plugin.cpp | 2 +- src/ast/datatype_decl_plugin.h | 12 +++--- src/ast/datatype_decl_plugin2.cpp | 64 ++++++++++++++++++++++++++-- src/ast/datatype_decl_plugin2.h | 45 +++++++++++++------ src/ast/rewriter/arith_rewriter.cpp | 4 +- src/ast/rewriter/poly_rewriter.h | 1 + src/ast/rewriter/poly_rewriter_def.h | 7 ++- src/cmd_context/pdecl.cpp | 7 ++- src/cmd_context/pdecl.h | 9 ++-- src/muz/bmc/dl_bmc_engine.cpp | 4 +- src/test/get_consequences.cpp | 3 +- 12 files changed, 125 insertions(+), 43 deletions(-) diff --git a/src/api/api_datatype.cpp b/src/api/api_datatype.cpp index 39d147ed1..d670888ed 100644 --- a/src/api/api_datatype.cpp +++ b/src/api/api_datatype.cpp @@ -51,7 +51,7 @@ extern "C" { constructor_decl* constrs[1] = { mk_constructor_decl(to_symbol(name), recognizer, acc.size(), acc.c_ptr()) }; { - datatype_decl * dt = mk_datatype_decl(to_symbol(name), 1, constrs); + datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), 1, constrs); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, tuples); del_datatype_decl(dt); @@ -113,7 +113,7 @@ extern "C" { { - datatype_decl * dt = mk_datatype_decl(to_symbol(name), n, constrs.c_ptr()); + datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), n, constrs.c_ptr()); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, sorts); del_datatype_decl(dt); @@ -160,6 +160,7 @@ extern "C" { LOG_Z3_mk_list_sort(c, name, elem_sort, nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl); RESET_ERROR_CODE(); ast_manager& m = mk_c(c)->m(); + datatype_util& dt_util = mk_c(c)->dtutil(); mk_c(c)->reset_last_result(); datatype_util data_util(m); accessor_decl* head_tail[2] = { @@ -174,7 +175,7 @@ extern "C" { sort_ref_vector sorts(m); { - datatype_decl * decl = mk_datatype_decl(to_symbol(name), 2, constrs); + datatype_decl * decl = mk_datatype_decl(dt_util, to_symbol(name), 2, constrs); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &decl, 0, 0, sorts); del_datatype_decl(decl); @@ -316,6 +317,7 @@ extern "C" { Z3_symbol name, unsigned num_constructors, Z3_constructor constructors[]) { + datatype_util& dt_util = mk_c(c)->dtutil(); ptr_vector constrs; for (unsigned i = 0; i < num_constructors; ++i) { constructor* cn = reinterpret_cast(constructors[i]); @@ -330,7 +332,7 @@ extern "C" { } constrs.push_back(mk_constructor_decl(cn->m_name, cn->m_tester, acc.size(), acc.c_ptr())); } - return mk_datatype_decl(to_symbol(name), num_constructors, constrs.c_ptr()); + return mk_datatype_decl(dt_util, to_symbol(name), num_constructors, constrs.c_ptr()); } Z3_sort Z3_API Z3_mk_datatype(Z3_context c, diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index e2aa54236..1c090bc33 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -95,7 +95,7 @@ public: ptr_vector const & get_constructors() const { return m_constructors; } }; -datatype_decl * mk_datatype_decl(symbol const & n, unsigned num_constructors, constructor_decl * const * cs) { +datatype_decl * mk_datatype_decl(datatype_util&, symbol const & n, unsigned num_constructors, constructor_decl * const * cs) { return alloc(datatype_decl, n, num_constructors, cs); } diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index b9c2602ef..e3e1b7b10 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -16,7 +16,7 @@ Author: Revision History: --*/ -// define DATATYPE_V2 +//define DATATYPE_V2 #ifdef DATATYPE_V2 #include "ast/datatype_decl_plugin2.h" #else @@ -79,14 +79,14 @@ class datatype_decl; class datatype_util; accessor_decl * mk_accessor_decl(symbol const & n, type_ref const & t); -void del_accessor_decl(accessor_decl * d); -void del_accessor_decls(unsigned num, accessor_decl * const * as); +//void del_accessor_decl(accessor_decl * d); +//void del_accessor_decls(unsigned num, accessor_decl * const * as); // Remark: the constructor becomes the owner of the accessor_decls constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * const * acs); -void del_constructor_decl(constructor_decl * d); -void del_constructor_decls(unsigned num, constructor_decl * const * cs); +//void del_constructor_decl(constructor_decl * d); +//void del_constructor_decls(unsigned num, constructor_decl * const * cs); // Remark: the datatype becomes the owner of the constructor_decls -datatype_decl * mk_datatype_decl(symbol const & n, unsigned num_constructors, constructor_decl * const * cs); +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_constructors, constructor_decl * const * cs); void del_datatype_decl(datatype_decl * d); void del_datatype_decls(unsigned num, datatype_decl * const * ds); diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 2fc62af31..c059907d5 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -1,5 +1,5 @@ /*++ -Copyright (c) 2006 Microsoft Corporation +Copyright (c) 2017 Microsoft Corporation Module Name: @@ -11,18 +11,21 @@ Abstract: Author: - Leonardo de Moura (leonardo) 2008-01-10. + Nikolaj Bjorner (nbjorner) 2017-9-1 Revision History: --*/ + +#include "ast/datatype_decl_plugin.h" + +#ifdef DATATYPE_V2 #include "util/warning.h" #include "ast/datatype_decl_plugin2.h" #include "ast/array_decl_plugin.h" #include "ast/ast_smt2_pp.h" -#ifdef DATATYPE_V2 namespace datatype { void accessor::fix_range(sort_ref_vector const& dts) { @@ -57,6 +60,7 @@ namespace datatype { util& constructor::u() const { return m_def->u(); } func_decl_ref constructor::instantiate(sort_ref_vector const& ps) const { + ast_manager& m = ps.get_manager(); sort_ref_vector domain(m); for (accessor const* a : accessors()) { domain.push_back(a->instantiate(ps)->get_range()); @@ -281,6 +285,11 @@ namespace datatype { } } + def* plugin::mk(symbol const& name, unsigned n, sort * const * params) { + ast_manager& m = *m_manager; + return alloc(def, m, u(), name, m_class_id, n, params); + } + def& plugin::add(symbol const& name, unsigned n, sort * const * params) { ast_manager& m = *m_manager; def* d = 0; @@ -313,6 +322,21 @@ namespace datatype { u().compute_datatype_size_functions(m_def_block); } + bool plugin::mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts) { + begin_def_block(); + for (unsigned i = 0; i < num_datatypes; ++i) { + if (m_defs.find(datatypes[i]->name(), d)) dealloc(d); + m_defs.insert(datatypes[i]->name(), datatypes[i]); + m_def_block.push_back(datatypes[i]->name()); + } + end_def_block(); + sort_ref_vector ps(*m_manager); + for (symbol const& s : m_def_block) { + new_sorts.push_back(m_defs[s]->instantiate(ps)); + } + return true; + } + void plugin::del(symbol const& s) { def* d = 0; if (m_defs.find(s, d)) dealloc(d); @@ -705,7 +729,7 @@ namespace datatype { return d; } - func_decl * util::get_recognizer_constructor(func_decl * recognizer) { + func_decl * util::get_recognizer_constructor(func_decl * recognizer) const { SASSERT(is_recognizer(recognizer)); return to_func_decl(recognizer->get_parameter(0).get_ast()); } @@ -856,6 +880,22 @@ namespace datatype { return 0; } + unsigned util::get_constructor_idx(func_decl * f) const { + unsigned idx = 0; + def const& d = get_def(f->get_range()); + for (constructor* c : d) { + if (c->name() == f->get_name()) { + return idx; + } + ++idx; + } + UNREACHABLE(); + return 0; + } + unsigned util::get_recognizer_constructor_idx(func_decl * f) const { + return get_constructor_idx(get_recognizer_constructor(f)); + } + /** \brief Two datatype sorts s1 and s2 are siblings if they were @@ -870,6 +910,12 @@ namespace datatype { } } + unsigned util::get_datatype_num_constructors(sort * ty) { + def const& d = get_def(ty->get_name()); + return d.constructors().size(); + } + + void util::display_datatype(sort *s0, std::ostream& strm) { ast_mark mark; ptr_buffer todo; @@ -902,4 +948,14 @@ namespace datatype { } } } + +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_constructors, constructor_decl * const * cs) { + datatype::decl::plugin* p = u.get_plugin(); + datatype::def( d = p->mk(n, 0, 0); + for (unsigned i = 0; i < num_constructors; ++i) { + d->add(cs[i]); + } + return d; +} + #endif diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index c8aa042f1..c79939a5b 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -1,5 +1,5 @@ /*++ -Copyright (c) 2006 Microsoft Corporation +Copyright (c) 2017 Microsoft Corporation Module Name: @@ -11,10 +11,13 @@ Abstract: Author: - Leonardo de Moura (leonardo) 2008-01-09. + Nikolaj Bjorner (nbjorner) 2017-9-1 Revision History: + rewritten to support SMTLIB-2.6 parameters from + Leonardo de Moura (leonardo) 2008-01-09. + --*/ #ifndef DATATYPE_DECL_PLUGIN2_H_ #define DATATYPE_DECL_PLUGIN2_H_ @@ -74,12 +77,11 @@ namespace datatype { }; class constructor { - ast_manager& m; symbol m_name; ptr_vector m_accessors; def* m_def; public: - constructor(ast_manager& m, symbol n): m(m), m_name(n) {} + constructor(symbol n): m_name(n) {} ~constructor(); void add(accessor* a) { m_accessors.push_back(a); a->attach(this); } symbol const& name() const { return m_name; } @@ -262,8 +264,12 @@ namespace datatype { def& add(symbol const& name, unsigned n, sort * const * params); + def* mk(symbol const& name, unsigned n, sort * const * params); + void del(symbol const& d); + bool mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts); + def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); } def& get_def(symbol const& s) { return *(m_defs[s]); } @@ -299,9 +305,7 @@ namespace datatype { family_id m_family_id; mutable decl::plugin* m_plugin; - - func_decl * get_constructor(sort * ty, unsigned c_id) const; - + obj_map *> m_datatype2constructors; obj_map m_datatype2nonrec_constructor; obj_map *> m_constructor2accessors; @@ -310,14 +314,13 @@ namespace datatype { obj_map m_accessor2constructor; obj_map m_is_recursive; obj_map m_is_enum; - mutable obj_map m_is_fully_interp; + mutable obj_map m_is_fully_interp; mutable ast_ref_vector m_asts; ptr_vector > m_vectors; unsigned m_start; - mutable ptr_vector m_fully_interp_trail; + mutable ptr_vector m_fully_interp_trail; func_decl * get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set); - func_decl * get_constructor(sort * ty, unsigned c_id); friend class decl::plugin; @@ -353,7 +356,7 @@ namespace datatype { func_decl * get_constructor_recognizer(func_decl * constructor); ptr_vector const & get_constructor_accessors(func_decl * constructor); func_decl * get_accessor_constructor(func_decl * accessor); - func_decl * get_recognizer_constructor(func_decl * recognizer); + func_decl * get_recognizer_constructor(func_decl * recognizer) const; family_id get_family_id() const { return m_family_id; } bool are_siblings(sort * s1, sort * s2); bool is_func_decl(op_kind k, unsigned num_params, parameter const* params, func_decl* f); @@ -362,11 +365,12 @@ namespace datatype { void display_datatype(sort *s, std::ostream& strm); bool is_fully_interp(sort * s) const; sort_ref_vector datatype_params(sort * s) const; + unsigned get_constructor_idx(func_decl * f) const; + unsigned get_recognizer_constructor_idx(func_decl * f) const; }; }; -#ifdef DATATYPE_V2 typedef datatype::accessor accessor_decl; typedef datatype::constructor constructor_decl; typedef datatype::def datatype_decl; @@ -394,7 +398,22 @@ inline accessor_decl * mk_accessor_decl(symbol const & n, type_ref const & t) { return alloc(accessor_decl, n, t.get_sort()); } } -#endif + +inline constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * * acs) { + constructor_decl* c = alloc(constructor_decl, n); + for (unsigned i = 0; i < num_accessors; ++i) { + c->add(acs[i]); + } + return c; +} + + + +// Remark: the datatype becomes the owner of the constructor_decls +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_constructors, constructor_decl * const * cs); +inline void del_datatype_decl(datatype_decl * d) {} +inline void del_datatype_decls(unsigned num, datatype_decl * const * ds) {} + #endif /* DATATYPE_DECL_PLUGIN_H_ */ diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index ff1894a18..fbfcabd78 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -455,7 +455,7 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin st = BR_DONE; } } - if (is_numeral(arg2, a2) && is_neg_poly(arg1, new_arg1)) { + if (m_arith_lhs && is_numeral(arg2, a2) && is_neg_poly(arg1, new_arg1)) { a2.neg(); new_arg2 = m_util.mk_numeral(a2, m_util.is_int(new_arg1)); switch (kind) { @@ -523,7 +523,7 @@ expr_ref arith_rewriter::neg_monomial(expr* e) const { } else { args.push_back(m_util.mk_numeral(rational(-1), m_util.is_int(e))); - args.append(to_app(e)->get_num_args(), to_app(e)->get_args()); + args.push_back(e); } } else { diff --git a/src/ast/rewriter/poly_rewriter.h b/src/ast/rewriter/poly_rewriter.h index c00464383..23743399e 100644 --- a/src/ast/rewriter/poly_rewriter.h +++ b/src/ast/rewriter/poly_rewriter.h @@ -36,6 +36,7 @@ protected: bool m_sort_sums; bool m_hoist_mul; bool m_hoist_cmul; + bool m_ast_order; bool is_numeral(expr * n) const { return Config::is_numeral(n); } bool is_numeral(expr * n, numeral & r) const { return Config::is_numeral(n, r); } diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 8fda040b6..b52440393 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -18,7 +18,8 @@ Notes: --*/ #include "ast/rewriter/poly_rewriter.h" #include "ast/rewriter/poly_rewriter_params.hpp" -// include "ast/ast_lt.h" +#include "ast/rewriter/arith_rewriter_params.hpp" +#include "ast/ast_lt.h" #include "ast/ast_ll_pp.h" #include "ast/ast_smt2_pp.h" @@ -33,6 +34,8 @@ void poly_rewriter::updt_params(params_ref const & _p) { m_som_blowup = p.som_blowup(); if (!m_flat) m_som = false; if (m_som) m_hoist_mul = false; + arith_rewriter_params ap(_p); + m_ast_order = !ap.arith_ineq_lhs(); } template @@ -485,6 +488,8 @@ void poly_rewriter::hoist_cmul(expr_ref_buffer & args) { template bool poly_rewriter::mon_lt::operator()(expr* e1, expr * e2) const { + if (rw.m_ast_order) + return lt(e1,e2); return ordinal(e1) < ordinal(e2); } diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 034b067c7..a9ce0b69c 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -566,7 +566,8 @@ datatype_decl * pdatatype_decl::instantiate_decl(pdecl_manager & m, sort * const for (auto c : m_constructors) { cs.push_back(c->instantiate_decl(m, s)); } - return mk_datatype_decl(m_name, cs.size(), cs.c_ptr()); + datatype_util util(m.m()); + return mk_datatype_decl(util, m_name, cs.size(), cs.c_ptr()); } struct datatype_decl_buffer { @@ -679,9 +680,7 @@ struct pdecl_manager::sort_info { } virtual ~sort_info() {} virtual unsigned obj_size() const { return sizeof(sort_info); } - virtual void finalize(pdecl_manager & m) { - m.dec_ref(m_decl); - } + virtual void finalize(pdecl_manager & m) { m.dec_ref(m_decl); } virtual void display(std::ostream & out, pdecl_manager const & m) const = 0; virtual format * pp(pdecl_manager const & m) const = 0; }; diff --git a/src/cmd_context/pdecl.h b/src/cmd_context/pdecl.h index 66e9cff53..e7fae8dd5 100644 --- a/src/cmd_context/pdecl.h +++ b/src/cmd_context/pdecl.h @@ -23,6 +23,7 @@ Revision History: #include "util/obj_hashtable.h" #include "util/dictionary.h" #include "ast/format.h" +#include "ast/datatype_decl_plugin.h" class pdecl_manager; @@ -139,10 +140,10 @@ public: virtual void display(std::ostream & out) const; }; -class datatype_decl_plugin; -class datatype_decl; -class constructor_decl; -class accessor_decl; +//class datatype_decl_plugin; +//class datatype_decl; +//class constructor_decl; +//class accessor_decl; class pdatatypes_decl; class pdatatype_decl; diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index b9dbe83ca..9109f6b3c 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -979,7 +979,7 @@ namespace datalog { symbol is_name(_name.str().c_str()); cnstrs.push_back(mk_constructor_decl(name, is_name, accs.size(), accs.c_ptr())); } - dts.push_back(mk_datatype_decl(pred->get_name(), cnstrs.size(), cnstrs.c_ptr())); + dts.push_back(mk_datatype_decl(dtu, pred->get_name(), cnstrs.size(), cnstrs.c_ptr())); } @@ -1027,7 +1027,7 @@ namespace datalog { accs.push_back(mk_accessor_decl(name, tr)); cnstrs.push_back(mk_constructor_decl(name, is_name, accs.size(), accs.c_ptr())); } - dts.push_back(mk_datatype_decl(symbol("Path"), cnstrs.size(), cnstrs.c_ptr())); + dts.push_back(mk_datatype_decl(dtu, symbol("Path"), cnstrs.size(), cnstrs.c_ptr())); VERIFY (dtp->mk_datatypes(dts.size(), dts.c_ptr(), 0, 0, new_sorts)); m_path_sort = new_sorts[0].get(); } diff --git a/src/test/get_consequences.cpp b/src/test/get_consequences.cpp index e8868c661..229cbe834 100644 --- a/src/test/get_consequences.cpp +++ b/src/test/get_consequences.cpp @@ -65,9 +65,8 @@ void test2() { constructor_decl* G = mk_constructor_decl(symbol("G"), symbol("is-G"), 0, 0); constructor_decl* B = mk_constructor_decl(symbol("B"), symbol("is-B"), 0, 0); constructor_decl* constrs[3] = { R, G, B }; - datatype_decl * enum_sort = mk_datatype_decl(symbol("RGB"), 3, constrs); + datatype_decl * enum_sort = mk_datatype_decl(dtutil, symbol("RGB"), 3, constrs); VERIFY(dt.mk_datatypes(1, &enum_sort, 0, 0, new_sorts)); - del_constructor_decls(3, constrs); sort* rgb = new_sorts[0].get(); expr_ref x = mk_const(m, "x", rgb), y = mk_const(m, "y", rgb), z = mk_const(m, "z", rgb); From 93474c0263502e9c7575d9c53ade310fccb78bba Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 4 Sep 2017 09:43:25 -0700 Subject: [PATCH 246/488] aligning simplifier and rewriter for regression tests Signed-off-by: Nikolaj Bjorner --- src/api/python/z3/z3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index 0b5f151be..1452a037e 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -3640,7 +3640,7 @@ def BitVecs(names, bv, ctx=None): >>> Product(x, y, z) 1*x*y*z >>> simplify(Product(x, y, z)) - z*x*y + x*y*z """ ctx = _get_ctx(ctx) if isinstance(names, str): @@ -7647,7 +7647,7 @@ def simplify(a, *arguments, **keywords): >>> simplify(x + 1 + y + x + 1) 2 + 2*x + y >>> simplify((x + 1)*(y + 1), som=True) - 1 + x + y + y*x + 1 + x + y + x*y >>> simplify(Distinct(x, y, 1), blast_distinct=True) And(Not(x == y), Not(x == 1), Not(y == 1)) >>> simplify(And(x == 0, y == 1), elim_and=True) From 5492d0e1355e0979eda801a3110224c6a040fdfc Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 4 Sep 2017 11:03:57 -0700 Subject: [PATCH 247/488] re-introduce eq2ineq name for rewriting parameter Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/arith_rewriter.cpp | 4 +-- src/ast/rewriter/arith_rewriter.h | 2 +- src/ast/rewriter/arith_rewriter_params.pyg | 2 +- src/cmd_context/pdecl.cpp | 25 ----------------- src/muz/pdr/pdr_context.cpp | 6 ++-- src/smt/asserted_formulas.cpp | 2 +- src/smt/params/theory_arith_params.cpp | 4 +-- src/smt/params/theory_arith_params.h | 4 +-- src/smt/smt_setup.cpp | 32 +++++++++++----------- 9 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index fbfcabd78..275290665 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -35,7 +35,7 @@ void arith_rewriter::updt_local_params(params_ref const & _p) { m_mul2power = p.mul_to_power(); m_elim_rem = p.elim_rem(); m_expand_tan = p.expand_tan(); - m_expand_eqs = p.expand_eqs(); + m_eq2ineq = p.eq2ineq(); set_sort_sums(p.sort_sums()); } @@ -501,7 +501,7 @@ bool arith_rewriter::is_arith_term(expr * n) const { } br_status arith_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { - if (m_expand_eqs) { + if (m_eq2ineq) { result = m().mk_and(m_util.mk_le(arg1, arg2), m_util.mk_ge(arg1, arg2)); return BR_REWRITE2; } diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index af9d0e09d..1bef9a964 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -55,7 +55,7 @@ class arith_rewriter : public poly_rewriter { bool m_push_to_real; bool m_anum_simp; bool m_elim_rem; - bool m_expand_eqs; + bool m_eq2ineq; bool m_process_all_eqs; unsigned m_max_degree; diff --git a/src/ast/rewriter/arith_rewriter_params.pyg b/src/ast/rewriter/arith_rewriter_params.pyg index d40f46917..c7374105a 100644 --- a/src/ast/rewriter/arith_rewriter_params.pyg +++ b/src/ast/rewriter/arith_rewriter_params.pyg @@ -12,5 +12,5 @@ def_module_params(module_name='rewriter', ("arith_ineq_lhs", BOOL, False, "rewrite inequalities so that right-hand-side is a constant."), ("elim_to_real", BOOL, False, "eliminate to_real from arithmetic predicates that contain only integers."), ("push_to_real", BOOL, True, "distribute to_real over * and +."), - ("expand_eqs", BOOL, False, "expand equalities into two inequalities"), + ("eq2ineq", BOOL, False, "expand equalities into two inequalities"), ("elim_rem", BOOL, False, "replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y)))."))) diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index a9ce0b69c..04456c076 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -292,27 +292,6 @@ sort * psort_decl::find(sort * const * s) { return m_inst_cache->find(s); } -#if 0 -psort_dt_decl::psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager& m, symbol const& n): - psort_decl(id, num_params, m, n) { -} - -void psort_dt_decl::finalize(pdecl_manager& m) { - psort_decl::finalize(m); -} - - -sort * psort_dt_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { - UNREACHABLE(); - return 0; -} - -void psort_dt_decl::display(std::ostream & out) const { - out << get_name() << " " << get_num_params(); -} -#endif - - psort_user_decl::psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p) : psort_decl(id, num_params, m, n), m_def(p) { @@ -859,10 +838,6 @@ psort_decl * pdecl_manager::mk_psort_user_decl(unsigned num_params, symbol const } -//psort_decl * pdecl_manager::mk_psort_dt_decl(unsigned num_params, symbol const & n) { -// return new (a().allocate(sizeof(psort_dt_decl))) psort_dt_decl(m_id_gen.mk(), num_params, *this, n); -//} - psort_decl * pdecl_manager::mk_psort_builtin_decl(symbol const & n, family_id fid, decl_kind k) { return new (a().allocate(sizeof(psort_builtin_decl))) psort_builtin_decl(m_id_gen.mk(), *this, n, fid, k); } diff --git a/src/muz/pdr/pdr_context.cpp b/src/muz/pdr/pdr_context.cpp index 0190044b1..fd734ea66 100644 --- a/src/muz/pdr/pdr_context.cpp +++ b/src/muz/pdr/pdr_context.cpp @@ -1835,16 +1835,16 @@ namespace pdr { !m_params.pdr_use_convex_interior_generalizer()) { if (classify.is_dl()) { m_fparams.m_arith_mode = AS_DIFF_LOGIC; - m_fparams.m_arith_expand_eqs = true; + m_fparams.m_arith_eq2ineq = true; } else if (classify.is_utvpi()) { IF_VERBOSE(1, verbose_stream() << "UTVPI\n";); m_fparams.m_arith_mode = AS_UTVPI; - m_fparams.m_arith_expand_eqs = true; + m_fparams.m_arith_eq2ineq = true; } else { m_fparams.m_arith_mode = AS_ARITH; - m_fparams.m_arith_expand_eqs = false; + m_fparams.m_arith_eq2ineq = false; } } } diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index f37cabde8..1581e70bd 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -123,7 +123,7 @@ void asserted_formulas::set_eliminate_and(bool flag) { p.set_bool("arith_ineq_lhs", true); p.set_bool("sort_sums", true); p.set_bool("rewrite_patterns", true); - p.set_bool("expand_eqs", m_params.m_arith_expand_eqs); + p.set_bool("eq2ineq", m_params.m_arith_eq2ineq); p.set_bool("gcd_rounding", true); m_rewriter.updt_params(p); flush_cache(); diff --git a/src/smt/params/theory_arith_params.cpp b/src/smt/params/theory_arith_params.cpp index 9b8aa9b81..250848db4 100644 --- a/src/smt/params/theory_arith_params.cpp +++ b/src/smt/params/theory_arith_params.cpp @@ -38,14 +38,14 @@ void theory_arith_params::updt_params(params_ref const & _p) { m_arith_dump_lemmas = p.arith_dump_lemmas(); m_arith_reflect = p.arith_reflect(); arith_rewriter_params ap(_p); - m_arith_expand_eqs = ap.expand_eqs(); + m_arith_eq2ineq = ap.eq2ineq(); } #define DISPLAY_PARAM(X) out << #X"=" << X << std::endl; void theory_arith_params::display(std::ostream & out) const { - DISPLAY_PARAM(m_arith_expand_eqs); + DISPLAY_PARAM(m_arith_eq2ineq); DISPLAY_PARAM(m_arith_process_all_eqs); DISPLAY_PARAM(m_arith_mode); DISPLAY_PARAM(m_arith_auto_config_simplex); //!< force simplex solver in auto_config diff --git a/src/smt/params/theory_arith_params.h b/src/smt/params/theory_arith_params.h index 89c4fe46c..1fe7e1163 100644 --- a/src/smt/params/theory_arith_params.h +++ b/src/smt/params/theory_arith_params.h @@ -49,7 +49,7 @@ enum arith_pivot_strategy { }; struct theory_arith_params { - bool m_arith_expand_eqs; + bool m_arith_eq2ineq; bool m_arith_process_all_eqs; arith_solver_id m_arith_mode; bool m_arith_auto_config_simplex; //!< force simplex solver in auto_config @@ -110,7 +110,7 @@ struct theory_arith_params { theory_arith_params(params_ref const & p = params_ref()): - m_arith_expand_eqs(false), + m_arith_eq2ineq(false), m_arith_process_all_eqs(false), m_arith_mode(AS_ARITH), m_arith_auto_config_simplex(false), diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index f0c44a574..50b49f3b8 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -226,7 +226,7 @@ namespace smt { void setup::setup_QF_RDL() { m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_nnf_cnf = false; @@ -266,7 +266,7 @@ namespace smt { TRACE("setup", tout << "setup_QF_RDL(st)\n";); check_no_uninterpreted_functions(st, "QF_RDL"); m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_nnf_cnf = false; @@ -318,7 +318,7 @@ namespace smt { void setup::setup_QF_IDL() { TRACE("setup", tout << "setup_QF_IDL()\n";); m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_arith_small_lemma_size = 30; @@ -336,7 +336,7 @@ namespace smt { TRACE("setup", tout << "setup_QF_IDL(st)\n";); check_no_uninterpreted_functions(st, "QF_IDL"); m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_arith_small_lemma_size = 30; @@ -390,7 +390,7 @@ namespace smt { m_params.m_arith_reflect = false; m_params.m_nnf_cnf = false; m_params.m_arith_eq_bounds = true; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_phase_selection = PS_ALWAYS_FALSE; m_params.m_restart_strategy = RS_GEOMETRIC; m_params.m_restart_factor = 1.5; @@ -406,8 +406,8 @@ namespace smt { m_params.m_arith_reflect = false; m_params.m_nnf_cnf = false; if (st.m_num_uninterpreted_functions == 0) { - m_params.m_arith_expand_eqs = true; - m_params.m_arith_propagate_eqs = false; + m_params.m_arith_eq2ineq = true; + m_params.m_arith_propagate_eqs = false; if (is_dense(st)) { m_params.m_arith_small_lemma_size = 128; m_params.m_lemma_gc_half = true; @@ -440,7 +440,7 @@ namespace smt { void setup::setup_QF_LRA() { TRACE("setup", tout << "setup_QF_LRA(st)\n";); m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_eliminate_term_ite = true; @@ -451,7 +451,7 @@ namespace smt { void setup::setup_QF_LRA(static_features const & st) { check_no_uninterpreted_functions(st, "QF_LRA"); m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_eliminate_term_ite = true; @@ -480,7 +480,7 @@ namespace smt { void setup::setup_QF_LIA() { TRACE("setup", tout << "setup_QF_LIA(st)\n";); m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_nnf_cnf = false; @@ -492,12 +492,12 @@ namespace smt { TRACE("setup", tout << "QF_LIA setup\n";); m_params.m_relevancy_lvl = 0; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_arith_reflect = false; m_params.m_arith_propagate_eqs = false; m_params.m_nnf_cnf = false; if (st.m_max_ite_tree_depth > 50) { - m_params.m_arith_expand_eqs = false; + m_params.m_arith_eq2ineq = false; m_params.m_pull_cheap_ite_trees = true; m_params.m_arith_propagate_eqs = true; m_params.m_relevancy_lvl = 2; @@ -507,7 +507,7 @@ namespace smt { m_params.m_arith_gcd_test = false; m_params.m_arith_branch_cut_ratio = 4; m_params.m_relevancy_lvl = 2; - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; m_params.m_eliminate_term_ite = true; // if (st.m_num_exprs < 5000 && st.m_num_ite_terms < 50) { // safeguard to avoid high memory consumption // TODO: implement analsysis function to decide where lift ite is too expensive. @@ -755,7 +755,7 @@ namespace smt { m_context.register_plugin(alloc(smt::theory_dummy, m_manager.mk_family_id("arith"), "no arithmetic")); break; case AS_DIFF_LOGIC: - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; if (fixnum) { if (int_only) m_context.register_plugin(alloc(smt::theory_fidl, m_manager, m_params)); @@ -770,7 +770,7 @@ namespace smt { } break; case AS_DENSE_DIFF_LOGIC: - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; if (fixnum) { if (int_only) m_context.register_plugin(alloc(smt::theory_dense_si, m_manager, m_params)); @@ -785,7 +785,7 @@ namespace smt { } break; case AS_UTVPI: - m_params.m_arith_expand_eqs = true; + m_params.m_arith_eq2ineq = true; if (int_only) m_context.register_plugin(alloc(smt::theory_iutvpi, m_manager)); else From 5d17e286672ee808702972cb6da60389bb80a720 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 4 Sep 2017 21:12:43 -0700 Subject: [PATCH 248/488] support for smtlib2.6 datatype parsing Signed-off-by: Nikolaj Bjorner --- src/api/api_datatype.cpp | 57 +++++----- src/ast/ast.cpp | 35 ++----- src/ast/ast_ll_pp.cpp | 2 +- src/ast/ast_smt2_pp.cpp | 2 +- src/ast/ast_smt_pp.cpp | 32 ++++-- src/ast/datatype_decl_plugin.cpp | 24 ++--- src/ast/datatype_decl_plugin.h | 14 +-- src/ast/datatype_decl_plugin2.cpp | 85 +++++++++------ src/ast/datatype_decl_plugin2.h | 31 +++--- src/ast/decl_collector.cpp | 4 +- src/ast/rewriter/datatype_rewriter.cpp | 4 +- src/ast/rewriter/enum2bv_rewriter.cpp | 2 +- src/cmd_context/cmd_context.cpp | 21 ++-- src/cmd_context/pdecl.cpp | 127 +++++++++++++++++++++-- src/cmd_context/pdecl.h | 29 ++++-- src/muz/base/dl_rule.h | 2 +- src/muz/base/rule_properties.cpp | 2 +- src/muz/bmc/dl_bmc_engine.cpp | 18 ++-- src/muz/pdr/pdr_prop_solver.cpp | 2 +- src/muz/spacer/spacer_util.cpp | 2 +- src/parsers/smt2/smt2parser.cpp | 27 ++++- src/qe/qe_datatype_plugin.cpp | 12 +-- src/qe/qe_datatypes.cpp | 6 +- src/qe/qe_lite.cpp | 2 +- src/smt/proto_model/datatype_factory.cpp | 6 +- src/smt/smt_value_sort.cpp | 2 +- src/smt/theory_datatype.cpp | 22 ++-- src/tactic/core/elim_uncnstr_tactic.cpp | 6 +- src/tactic/portfolio/enum2bv_solver.cpp | 2 +- 29 files changed, 374 insertions(+), 206 deletions(-) diff --git a/src/api/api_datatype.cpp b/src/api/api_datatype.cpp index d670888ed..d667a7428 100644 --- a/src/api/api_datatype.cpp +++ b/src/api/api_datatype.cpp @@ -45,13 +45,13 @@ extern "C" { ptr_vector acc; for (unsigned i = 0; i < num_fields; ++i) { - acc.push_back(mk_accessor_decl(to_symbol(field_names[i]), type_ref(to_sort(field_sorts[i])))); + acc.push_back(mk_accessor_decl(m, to_symbol(field_names[i]), type_ref(to_sort(field_sorts[i])))); } constructor_decl* constrs[1] = { mk_constructor_decl(to_symbol(name), recognizer, acc.size(), acc.c_ptr()) }; { - datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), 1, constrs); + datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), 0, nullptr, 1, constrs); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, tuples); del_datatype_decl(dt); @@ -69,13 +69,13 @@ extern "C" { // create constructor SASSERT(dt_util.is_datatype(tuple)); SASSERT(!dt_util.is_recursive(tuple)); - ptr_vector const & decls = dt_util.get_datatype_constructors(tuple); + ptr_vector const & decls = *dt_util.get_datatype_constructors(tuple); func_decl* decl = (decls)[0]; mk_c(c)->save_multiple_ast_trail(decl); *mk_tuple_decl = of_func_decl(decl); // Create projections - ptr_vector const & _accs = dt_util.get_constructor_accessors(decl); + ptr_vector const & _accs = *dt_util.get_constructor_accessors(decl); SASSERT(_accs.size() == num_fields); for (unsigned i = 0; i < _accs.size(); i++) { mk_c(c)->save_multiple_ast_trail(_accs[i]); @@ -113,7 +113,7 @@ extern "C" { { - datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), n, constrs.c_ptr()); + datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), 0, 0, n, constrs.c_ptr()); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, sorts); del_datatype_decl(dt); @@ -131,7 +131,7 @@ extern "C" { // create constructor SASSERT(dt_util.is_datatype(e)); SASSERT(!dt_util.is_recursive(e)); - ptr_vector const & decls = dt_util.get_datatype_constructors(e); + ptr_vector const & decls = *dt_util.get_datatype_constructors(e); SASSERT(decls.size() == n); for (unsigned i = 0; i < n; ++i) { func_decl* decl = (decls)[i]; @@ -164,8 +164,8 @@ extern "C" { mk_c(c)->reset_last_result(); datatype_util data_util(m); accessor_decl* head_tail[2] = { - mk_accessor_decl(symbol("head"), type_ref(to_sort(elem_sort))), - mk_accessor_decl(symbol("tail"), type_ref(0)) + mk_accessor_decl(m, symbol("head"), type_ref(to_sort(elem_sort))), + mk_accessor_decl(m, symbol("tail"), type_ref(0)) }; constructor_decl* constrs[2] = { mk_constructor_decl(symbol("nil"), symbol("is_nil"), 0, 0), @@ -175,7 +175,7 @@ extern "C" { sort_ref_vector sorts(m); { - datatype_decl * decl = mk_datatype_decl(dt_util, to_symbol(name), 2, constrs); + datatype_decl * decl = mk_datatype_decl(dt_util, to_symbol(name), 0, nullptr, 2, constrs); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &decl, 0, 0, sorts); del_datatype_decl(decl); @@ -187,7 +187,7 @@ extern "C" { sort * s = sorts.get(0); mk_c(c)->save_multiple_ast_trail(s); - ptr_vector const& cnstrs = data_util.get_datatype_constructors(s); + ptr_vector const& cnstrs = *data_util.get_datatype_constructors(s); SASSERT(cnstrs.size() == 2); func_decl* f; if (nil_decl) { @@ -211,14 +211,14 @@ extern "C" { *is_cons_decl = of_func_decl(f); } if (head_decl) { - ptr_vector const& acc = data_util.get_constructor_accessors(cnstrs[1]); + ptr_vector const& acc = *data_util.get_constructor_accessors(cnstrs[1]); SASSERT(acc.size() == 2); f = (acc)[0]; mk_c(c)->save_multiple_ast_trail(f); *head_decl = of_func_decl(f); } if (tail_decl) { - ptr_vector const& acc = data_util.get_constructor_accessors(cnstrs[1]); + ptr_vector const& acc = *data_util.get_constructor_accessors(cnstrs[1]); SASSERT(acc.size() == 2); f = (acc)[1]; mk_c(c)->save_multiple_ast_trail(f); @@ -295,7 +295,7 @@ extern "C" { *tester = of_func_decl(f2); } - ptr_vector const& accs = data_util.get_constructor_accessors(f); + ptr_vector const& accs = *data_util.get_constructor_accessors(f); for (unsigned i = 0; i < num_fields; ++i) { func_decl* f2 = (accs)[i]; mk_c(c)->save_multiple_ast_trail(f2); @@ -318,21 +318,22 @@ extern "C" { unsigned num_constructors, Z3_constructor constructors[]) { datatype_util& dt_util = mk_c(c)->dtutil(); + ast_manager& m = mk_c(c)->m(); ptr_vector constrs; for (unsigned i = 0; i < num_constructors; ++i) { constructor* cn = reinterpret_cast(constructors[i]); ptr_vector acc; for (unsigned j = 0; j < cn->m_sorts.size(); ++j) { if (cn->m_sorts[j].get()) { - acc.push_back(mk_accessor_decl(cn->m_field_names[j], type_ref(cn->m_sorts[j].get()))); + acc.push_back(mk_accessor_decl(m, cn->m_field_names[j], type_ref(cn->m_sorts[j].get()))); } else { - acc.push_back(mk_accessor_decl(cn->m_field_names[j], type_ref(cn->m_sort_refs[j]))); + acc.push_back(mk_accessor_decl(m, cn->m_field_names[j], type_ref(cn->m_sort_refs[j]))); } } constrs.push_back(mk_constructor_decl(cn->m_name, cn->m_tester, acc.size(), acc.c_ptr())); } - return mk_datatype_decl(dt_util, to_symbol(name), num_constructors, constrs.c_ptr()); + return mk_datatype_decl(dt_util, to_symbol(name), 0, nullptr, num_constructors, constrs.c_ptr()); } Z3_sort Z3_API Z3_mk_datatype(Z3_context c, @@ -359,7 +360,7 @@ extern "C" { sort * s = sorts.get(0); mk_c(c)->save_ast_trail(s); - ptr_vector const& cnstrs = data_util.get_datatype_constructors(s); + ptr_vector const& cnstrs = *data_util.get_datatype_constructors(s); for (unsigned i = 0; i < num_constructors; ++i) { constructor* cn = reinterpret_cast(constructors[i]); @@ -408,7 +409,7 @@ extern "C" { ptr_vector datas; for (unsigned i = 0; i < num_sorts; ++i) { constructor_list* cl = reinterpret_cast(constructor_lists[i]); - datas.push_back(mk_datatype_decl(c,sort_names[i], cl->size(), reinterpret_cast(cl->c_ptr()))); + datas.push_back(mk_datatype_decl(c, sort_names[i], cl->size(), reinterpret_cast(cl->c_ptr()))); } sort_ref_vector _sorts(m); bool ok = mk_c(c)->get_dt_plugin()->mk_datatypes(datas.size(), datas.c_ptr(), 0, 0, _sorts); @@ -425,7 +426,7 @@ extern "C" { mk_c(c)->save_multiple_ast_trail(s); sorts[i] = of_sort(s); constructor_list* cl = reinterpret_cast(constructor_lists[i]); - ptr_vector const& cnstrs = data_util.get_datatype_constructors(s); + ptr_vector const& cnstrs = *data_util.get_datatype_constructors(s); for (unsigned j = 0; j < cl->size(); ++j) { constructor* cn = (*cl)[j]; cn->m_constructor = cnstrs[j]; @@ -447,7 +448,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - return dt_util.get_datatype_constructors(_t).size(); + return dt_util.get_datatype_constructors(_t)->size(); Z3_CATCH_RETURN(0); } @@ -460,7 +461,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - ptr_vector const & decls = dt_util.get_datatype_constructors(_t); + ptr_vector const & decls = *dt_util.get_datatype_constructors(_t); if (idx >= decls.size()) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; @@ -490,7 +491,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const & decls = dt_util.get_datatype_constructors(_t); + ptr_vector const & decls = *dt_util.get_datatype_constructors(_t); if (idx >= decls.size()) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); @@ -513,7 +514,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const & decls = dt_util.get_datatype_constructors(_t); + ptr_vector const & decls = *dt_util.get_datatype_constructors(_t); if (idx_c >= decls.size()) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; @@ -523,7 +524,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const & accs = dt_util.get_constructor_accessors(decl); + ptr_vector const & accs = *dt_util.get_constructor_accessors(decl); SASSERT(accs.size() == decl->get_arity()); if (accs.size() <= idx_a) { SET_ERROR_CODE(Z3_INVALID_ARG); @@ -560,12 +561,12 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - ptr_vector const & decls = dt_util.get_datatype_constructors(tuple); + ptr_vector const & decls = *dt_util.get_datatype_constructors(tuple); if (decls.size() != 1) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - ptr_vector const & accs = dt_util.get_constructor_accessors(decls[0]); + ptr_vector const & accs = *dt_util.get_constructor_accessors(decls[0]); return accs.size(); Z3_CATCH_RETURN(0); } @@ -580,12 +581,12 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const & decls = dt_util.get_datatype_constructors(tuple); + ptr_vector const & decls = *dt_util.get_datatype_constructors(tuple); if (decls.size() != 1) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } - ptr_vector const & accs = dt_util.get_constructor_accessors((decls)[0]); + ptr_vector const & accs = *dt_util.get_constructor_accessors((decls)[0]); if (accs.size() <= i) { SET_ERROR_CODE(Z3_IOB); RETURN_Z3(0); diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 1a35e710a..a905efa28 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1287,10 +1287,8 @@ decl_kind user_sort_plugin::register_name(symbol s) { decl_plugin * user_sort_plugin::mk_fresh() { user_sort_plugin * p = alloc(user_sort_plugin); - svector::iterator it = m_sort_names.begin(); - svector::iterator end = m_sort_names.end(); - for (; it != end; ++it) - p->register_name(*it); + for (symbol const& s : m_sort_names) + p->register_name(s); return p; } @@ -1410,26 +1408,20 @@ ast_manager::~ast_manager() { dec_ref(m_true); dec_ref(m_false); dec_ref(m_undef_proof); - ptr_vector::iterator it = m_plugins.begin(); - ptr_vector::iterator end = m_plugins.end(); - for (; it != end; ++it) { - if (*it) - (*it)->finalize(); + for (decl_plugin* p : m_plugins) { + if (p) + p->finalize(); } - it = m_plugins.begin(); - for (; it != end; ++it) { - if (*it) - dealloc(*it); + for (decl_plugin* p : m_plugins) { + if (p) + dealloc(p); } m_plugins.reset(); while (!m_ast_table.empty()) { DEBUG_CODE(std::cout << "ast_manager LEAKED: " << m_ast_table.size() << std::endl;); ptr_vector roots; ast_mark mark; - ast_table::iterator it_a = m_ast_table.begin(); - ast_table::iterator end_a = m_ast_table.end(); - for (; it_a != end_a; ++it_a) { - ast* n = (*it_a); + for (ast * n : m_ast_table) { switch (n->get_kind()) { case AST_SORT: { sort_info* info = to_sort(n)->get_info(); @@ -1462,9 +1454,7 @@ ast_manager::~ast_manager() { break; } } - it_a = m_ast_table.begin(); - for (; it_a != end_a; ++it_a) { - ast* n = *it_a; + for (ast * n : m_ast_table) { if (!mark.is_marked(n)) { roots.push_back(n); } @@ -1659,11 +1649,8 @@ bool ast_manager::is_bool(expr const * n) const { #ifdef Z3DEBUG bool ast_manager::slow_not_contains(ast const * n) { - ast_table::iterator it = m_ast_table.begin(); - ast_table::iterator end = m_ast_table.end(); unsigned num = 0; - for (; it != end; ++it) { - ast * curr = *it; + for (ast * curr : m_ast_table) { if (compare_nodes(curr, n)) { TRACE("nondet_bug", tout << "id1: " << curr->get_id() << ", id2: " << n->get_id() << "\n"; diff --git a/src/ast/ast_ll_pp.cpp b/src/ast/ast_ll_pp.cpp index c00053780..6b14b75a8 100644 --- a/src/ast/ast_ll_pp.cpp +++ b/src/ast/ast_ll_pp.cpp @@ -284,7 +284,7 @@ public: } unsigned num_args = to_app(n)->get_num_args(); if (num_args > 0) - m_out << "("; + m_out << "(_ "; display_name(to_app(n)->get_decl()); display_params(to_app(n)->get_decl()); for (unsigned i = 0; i < num_args; i++) { diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index 51ccc1e7d..642983737 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -431,7 +431,7 @@ format_ns::format * smt2_pp_environment::pp_sort(sort * s) { fs.push_back(pp_sort(to_sort(s->get_parameter(0).get_ast()))); return mk_seq1(m, fs.begin(), fs.end(), f2f(), get_sutil().is_seq(s)?"Seq":"RegEx"); } -#if 0 +#ifdef DATATYPE_V2 if (get_dtutil().is_datatype(s)) { ptr_buffer fs; unsigned sz = get_dtutil().get_datatype_num_parameter_sorts(s); diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 9211c5899..fdac6c7be 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -21,17 +21,17 @@ Revision History: #include #include +#include "util/vector.h" +#include "util/smt2_util.h" #include "ast/ast_smt_pp.h" #include "ast/arith_decl_plugin.h" #include "ast/bv_decl_plugin.h" #include "ast/array_decl_plugin.h" #include "ast/datatype_decl_plugin.h" +#include "ast/seq_decl_plugin.h" #include "ast/fpa_decl_plugin.h" -#include "util/vector.h" #include "ast/for_each_ast.h" #include "ast/decl_collector.h" -#include "util/smt2_util.h" -#include "ast/seq_decl_plugin.h" // --------------------------------------- // smt_renaming @@ -210,7 +210,19 @@ class smt_printer { void pp_decl(func_decl* d) { symbol sym = m_renaming.get_symbol(d->get_name()); if (d->get_family_id() == m_dt_fid) { +#ifdef DATATYPE_V2 + std::cout << "printing " << sym << "\n"; + datatype_util util(m_manager); + if (util.is_recognizer(d)) { + std::cout << d->get_num_parameters() << "\n"; + visit_params(false, sym, d->get_num_parameters(), d->get_parameters()); + } + else { + m_out << sym; + } +#else m_out << sym; +#endif } else if (m_manager.is_ite(d)) { if (!m_is_smt2 && is_bool(d->get_range())) { @@ -366,14 +378,15 @@ class smt_printer { return; } else if (s->is_sort_of(m_dt_fid, DATATYPE_SORT)) { +#ifndef DATATYPE_V2 m_out << m_renaming.get_symbol(s->get_name()); -#if 0 +#else datatype_util util(m_manager); unsigned num_sorts = util.get_datatype_num_parameter_sorts(s); if (num_sorts > 0) { m_out << "("; } - + m_out << m_renaming.get_symbol(s->get_name()); if (num_sorts > 0) { for (unsigned i = 0; i < num_sorts; ++i) { m_out << " "; @@ -533,7 +546,8 @@ class smt_printer { pp_arg(curr, n); m_out << ")"; - } else if (m_manager.is_distinct(decl)) { + } + else if (m_manager.is_distinct(decl)) { ptr_vector args(num_args, n->get_args()); unsigned idx = 0; m_out << "(and"; @@ -915,7 +929,7 @@ public: // collect siblings and sorts that have not already been printed. for (unsigned h = 0; h < rec_sorts.size(); ++h) { s = rec_sorts[h]; - ptr_vector const& decls = util.get_datatype_constructors(s); + ptr_vector const& decls = *util.get_datatype_constructors(s); for (unsigned i = 0; i < decls.size(); ++i) { func_decl* f = decls[i]; @@ -954,11 +968,11 @@ public: m_out << "("; m_out << m_renaming.get_symbol(s->get_name()); m_out << " "; - ptr_vector const& decls = util.get_datatype_constructors(s); + ptr_vector const& decls = *util.get_datatype_constructors(s); for (unsigned i = 0; i < decls.size(); ++i) { func_decl* f = decls[i]; - ptr_vector const& accs = util.get_constructor_accessors(f); + ptr_vector const& accs = *util.get_constructor_accessors(f); if (m_is_smt2 || accs.size() > 0) { m_out << "("; } diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index 1c090bc33..7ad80336d 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -34,7 +34,7 @@ public: type_ref const & get_type() const { return m_type; } }; -accessor_decl * mk_accessor_decl(symbol const & n, type_ref const & t) { +accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_ref const & t) { return alloc(accessor_decl, n, t); } @@ -95,7 +95,7 @@ public: ptr_vector const & get_constructors() const { return m_constructors; } }; -datatype_decl * mk_datatype_decl(datatype_util&, symbol const & n, unsigned num_constructors, constructor_decl * const * cs) { +datatype_decl * mk_datatype_decl(datatype_util&, symbol const & n, unsigned num_params, sort * const* params, unsigned num_constructors, constructor_decl * const * cs) { return alloc(datatype_decl, n, num_constructors, cs); } @@ -803,11 +803,11 @@ func_decl * datatype_util::get_constructor(sort * ty, unsigned c_id) { return d; } -ptr_vector const & datatype_util::get_datatype_constructors(sort * ty) { +ptr_vector const * datatype_util::get_datatype_constructors(sort * ty) { SASSERT(is_datatype(ty)); ptr_vector * r = 0; if (m_datatype2constructors.find(ty, r)) - return *r; + return r; r = alloc(ptr_vector); m_asts.push_back(ty); m_vectors.push_back(r); @@ -820,7 +820,7 @@ ptr_vector const & datatype_util::get_datatype_constructors(sort * ty m_asts.push_back(c); r->push_back(c); } - return *r; + return r; } /** @@ -855,7 +855,7 @@ func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vector const & constructors = get_datatype_constructors(ty); + ptr_vector const & constructors = *get_datatype_constructors(ty); // step 1) unsigned sz = constructors.size(); ++m_start; @@ -916,11 +916,11 @@ func_decl * datatype_util::get_constructor_recognizer(func_decl * constructor) { return d; } -ptr_vector const & datatype_util::get_constructor_accessors(func_decl * constructor) { +ptr_vector const * datatype_util::get_constructor_accessors(func_decl * constructor) { SASSERT(is_constructor(constructor)); ptr_vector * res = 0; if (m_constructor2accessors.find(constructor, res)) - return *res; + return res; res = alloc(ptr_vector); m_asts.push_back(constructor); m_vectors.push_back(res); @@ -939,7 +939,7 @@ ptr_vector const & datatype_util::get_constructor_accessors(func_decl m_asts.push_back(d); res->push_back(d); } - return *res; + return res; } func_decl * datatype_util::get_accessor_constructor(func_decl * accessor) { @@ -989,7 +989,7 @@ bool datatype_util::is_enum_sort(sort* s) { bool r = false; if (m_is_enum.find(s, r)) return r; - ptr_vector const& cnstrs = get_datatype_constructors(s); + ptr_vector const& cnstrs = *get_datatype_constructors(s); r = true; for (unsigned i = 0; r && i < cnstrs.size(); ++i) { r = cnstrs[i]->get_arity() == 0; @@ -1049,12 +1049,12 @@ void datatype_util::display_datatype(sort *s0, std::ostream& strm) { todo.pop_back(); strm << s->get_name() << " =\n"; - ptr_vector const & cnstrs = get_datatype_constructors(s); + ptr_vector const & cnstrs = *get_datatype_constructors(s); for (unsigned i = 0; i < cnstrs.size(); ++i) { func_decl* cns = cnstrs[i]; func_decl* rec = get_constructor_recognizer(cns); strm << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; - ptr_vector const & accs = get_constructor_accessors(cns); + ptr_vector const & accs = *get_constructor_accessors(cns); for (unsigned j = 0; j < accs.size(); ++j) { func_decl* acc = accs[j]; sort* s1 = acc->get_range(); diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index e3e1b7b10..3b4c8dd08 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -16,7 +16,7 @@ Author: Revision History: --*/ -//define DATATYPE_V2 +// define DATATYPE_V2 #ifdef DATATYPE_V2 #include "ast/datatype_decl_plugin2.h" #else @@ -78,15 +78,11 @@ class constructor_decl; class datatype_decl; class datatype_util; -accessor_decl * mk_accessor_decl(symbol const & n, type_ref const & t); -//void del_accessor_decl(accessor_decl * d); -//void del_accessor_decls(unsigned num, accessor_decl * const * as); +accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_ref const & t); // Remark: the constructor becomes the owner of the accessor_decls constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * const * acs); -//void del_constructor_decl(constructor_decl * d); -//void del_constructor_decls(unsigned num, constructor_decl * const * cs); // Remark: the datatype becomes the owner of the constructor_decls -datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_constructors, constructor_decl * const * cs); +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort * const* params, unsigned num_constructors, constructor_decl * const * cs); void del_datatype_decl(datatype_decl * d); void del_datatype_decls(unsigned num, datatype_decl * const * ds); @@ -216,7 +212,7 @@ public: bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); } bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } - ptr_vector const & get_datatype_constructors(sort * ty); + ptr_vector const * get_datatype_constructors(sort * ty); unsigned get_datatype_num_constructors(sort * ty) { SASSERT(is_datatype(ty)); unsigned tid = ty->get_parameter(1).get_int(); @@ -236,7 +232,7 @@ public: unsigned get_recognizer_constructor_idx(func_decl * f) const { SASSERT(is_recognizer(f)); return f->get_parameter(1).get_int(); } func_decl * get_non_rec_constructor(sort * ty); func_decl * get_constructor_recognizer(func_decl * constructor); - ptr_vector const & get_constructor_accessors(func_decl * constructor); + ptr_vector const * get_constructor_accessors(func_decl * constructor); func_decl * get_accessor_constructor(func_decl * accessor); func_decl * get_recognizer_constructor(func_decl * recognizer); family_id get_family_id() const { return m_family_id; } diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index c059907d5..41ae2e839 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -37,6 +37,7 @@ namespace datatype { func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const { ast_manager& m = ps.get_manager(); unsigned n = ps.size(); + SASSERT(m_range); SASSERT(n == get_def().params().size()); sort_ref range(m.substitute(m_range, n, get_def().params().c_ptr(), ps.c_ptr()), m); sort_ref src(get_def().instantiate(ps)); @@ -79,13 +80,14 @@ namespace datatype { sort_ref s(m); if (!m_sort) { vector ps; + ps.push_back(parameter(m_name)); for (sort * s : m_params) ps.push_back(parameter(s)); m_sort = m.mk_sort(u().get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); } if (sorts.empty()) { return m_sort; } - return sort_ref(m.substitute(m_sort, sorts.size(), sorts.c_ptr(), m_params.c_ptr()), m); + return sort_ref(m.substitute(m_sort, sorts.size(), m_params.c_ptr(), sorts.c_ptr()), m); } enum status { @@ -135,6 +137,7 @@ namespace datatype { util & plugin::u() const { SASSERT(m_manager); + SASSERT(m_family_id != null_family_id); if (m_util.get() == 0) { m_util = alloc(util, *m_manager); } @@ -146,9 +149,11 @@ namespace datatype { sort * plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { try { if (k != DATATYPE_SORT) { + TRACE("datatype", tout << "invalid kind parameter to datatype\n";); throw invalid_datatype(); } if (num_parameters < 1) { + TRACE("datatype", tout << "at least one parameter expected to datatype declaration\n";); throw invalid_datatype(); } parameter const & name = parameters[0]; @@ -169,13 +174,17 @@ namespace datatype { def* d = 0; if (m_defs.find(s->get_name(), d) && d->sort_size()) { obj_map S; - for (unsigned i = 1; i < num_parameters; ++i) { - sort* r = to_sort(parameters[i].get_ast()); + for (unsigned i = 0; i + 1 < num_parameters; ++i) { + sort* r = to_sort(parameters[i + 1].get_ast()); S.insert(d->params()[i], r->get_num_elements()); } sort_size ts = d->sort_size()->eval(S); + TRACE("datatype", tout << name << " has size " << ts << "\n";); s->set_num_elements(ts); } + else { + TRACE("datatype", tout << "not setting size for " << name << "\n";); + } return s; } catch (invalid_datatype) { @@ -227,14 +236,12 @@ namespace datatype { return m.mk_func_decl(symbol("update-field"), arity, domain, range, info); } +#define VALIDATE_PARAM(_pred_) if (!(_pred_)) m_manager->raise_exception("invalid parameter to datatype function"); func_decl * decl::plugin::mk_constructor(unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { ast_manager& m = *m_manager; - SASSERT(num_parameters == 1 && parameters[0].is_symbol() && range && u().is_datatype(range)); - if (num_parameters != 1 || !parameters[0].is_symbol() || !range || !u().is_datatype(range)) { - m_manager->raise_exception("invalid parameters for datatype constructor"); - } + VALIDATE_PARAM(num_parameters == 1 && parameters[0].is_symbol() && range && u().is_datatype(range)); // we blindly trust other conditions are met, including domain types. symbol name = parameters[0].get_symbol(); func_decl_info info(m_family_id, OP_DT_CONSTRUCTOR, num_parameters, parameters); @@ -245,27 +252,27 @@ namespace datatype { func_decl * decl::plugin::mk_recognizer(unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort *) { ast_manager& m = *m_manager; - SASSERT(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); - SASSERT(u().is_datatype(domain[0])); + VALIDATE_PARAM(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + VALIDATE_PARAM(u().is_datatype(domain[0])); // blindly trust that parameter is a constructor sort* range = m_manager->mk_bool_sort(); + func_decl* f = to_func_decl(parameters[0].get_ast()); func_decl_info info(m_family_id, OP_DT_RECOGNISER, num_parameters, parameters); info.m_private_parameters = true; - symbol name = to_func_decl(parameters[0].get_ast())->get_name(); - return m.mk_func_decl(name, arity, domain, range); + return m.mk_func_decl(symbol("is"), arity, domain, range, info); } func_decl * decl::plugin::mk_accessor(unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { ast_manager& m = *m_manager; - SASSERT(arity == 1 && num_parameters == 2 && parameters[0].is_symbol() && parameters[0].is_symbol()); - SASSERT(u().is_datatype(domain[0])); + VALIDATE_PARAM(arity == 1 && num_parameters == 2 && parameters[0].is_symbol() && parameters[1].is_symbol()); + VALIDATE_PARAM(u().is_datatype(domain[0])); SASSERT(range); func_decl_info info(m_family_id, OP_DT_ACCESSOR, num_parameters, parameters); info.m_private_parameters = true; symbol name = parameters[0].get_symbol(); - return m.mk_func_decl(name, arity, domain, range); + return m.mk_func_decl(name, arity, domain, range, info); } func_decl * decl::plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -290,15 +297,20 @@ namespace datatype { return alloc(def, m, u(), name, m_class_id, n, params); } +#if 0 def& plugin::add(symbol const& name, unsigned n, sort * const * params) { ast_manager& m = *m_manager; def* d = 0; - if (m_defs.find(name, d)) dealloc(d); + if (m_defs.find(name, d)) { + TRACE("datatype", tout << "delete previous version for " << name << "\n";); + dealloc(d); + } d = alloc(def, m, u(), name, m_class_id, n, params); m_defs.insert(name, d); m_def_block.push_back(name); return *d; } +#endif void plugin::end_def_block() { ast_manager& m = *m_manager; @@ -325,7 +337,11 @@ namespace datatype { bool plugin::mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts) { begin_def_block(); for (unsigned i = 0; i < num_datatypes; ++i) { - if (m_defs.find(datatypes[i]->name(), d)) dealloc(d); + def* d = 0; + if (m_defs.find(datatypes[i]->name(), d)) { + TRACE("datatype", tout << "delete previous version for " << datatypes[i]->name() << "\n";); + dealloc(d); + } m_defs.insert(datatypes[i]->name(), datatypes[i]); m_def_block.push_back(datatypes[i]->name()); } @@ -391,6 +407,7 @@ namespace datatype { } void plugin::get_op_names(svector & op_names, symbol const & logic) { + op_names.push_back(builtin_name("is", OP_DT_RECOGNISER)); if (logic == symbol::null) { op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD)); } @@ -548,6 +565,10 @@ namespace datatype { } return param_size::size::mk_offset(s->get_num_elements()); } + + bool util::is_declared(sort* s) const { + return m_plugin->is_declared(s); + } void util::compute_datatype_size_functions(svector const& names) { map already_found; @@ -668,17 +689,18 @@ namespace datatype { m_asts(m), m_start(0) { m_plugin = dynamic_cast(m.get_plugin(m_family_id)); + SASSERT(m_plugin); } util::~util() { std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); } - ptr_vector const & util::get_datatype_constructors(sort * ty) { + ptr_vector const * util::get_datatype_constructors(sort * ty) { SASSERT(is_datatype(ty)); ptr_vector * r = 0; if (m_datatype2constructors.find(ty, r)) - return *r; + return r; r = alloc(ptr_vector); m_asts.push_back(ty); m_vectors.push_back(r); @@ -689,14 +711,15 @@ namespace datatype { m_asts.push_back(f); r->push_back(f); } - return *r; + return r; } - ptr_vector const & util::get_constructor_accessors(func_decl * con) { + ptr_vector const * util::get_constructor_accessors(func_decl * con) { SASSERT(is_constructor(con)); ptr_vector * res = 0; - if (m_constructor2accessors.find(con, res)) - return *res; + if (m_constructor2accessors.find(con, res)) { + return res; + } res = alloc(ptr_vector); m_asts.push_back(con); m_vectors.push_back(res); @@ -706,12 +729,14 @@ namespace datatype { for (constructor const* c : d) { if (c->name() == con->get_name()) { for (accessor const* a : *c) { - res->push_back(a->instantiate(datatype)); + func_decl_ref fn = a->instantiate(datatype); + res->push_back(fn); + m_asts.push_back(fn); } break; } } - return *res; + return res; } func_decl * util::get_constructor_recognizer(func_decl * constructor) { @@ -752,7 +777,7 @@ namespace datatype { bool r = false; if (m_is_enum.find(s, r)) return r; - ptr_vector const& cnstrs = get_datatype_constructors(s); + ptr_vector const& cnstrs = *get_datatype_constructors(s); r = true; for (unsigned i = 0; r && i < cnstrs.size(); ++i) { r = cnstrs[i]->get_arity() == 0; @@ -833,7 +858,7 @@ namespace datatype { // 1) T_i's are not recursive // If there is no such constructor, then we select one that // 2) each type T_i is not recursive or contains a constructor that does not depend on T - ptr_vector const& constructors = get_datatype_constructors(ty); + ptr_vector const& constructors = *get_datatype_constructors(ty); // step 1) unsigned sz = constructors.size(); ++m_start; @@ -928,12 +953,12 @@ namespace datatype { todo.pop_back(); strm << s->get_name() << " =\n"; - ptr_vector const& cnstrs = get_datatype_constructors(s); + ptr_vector const& cnstrs = *get_datatype_constructors(s); for (unsigned i = 0; i < cnstrs.size(); ++i) { func_decl* cns = cnstrs[i]; func_decl* rec = get_constructor_recognizer(cns); strm << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; - ptr_vector const & accs = get_constructor_accessors(cns); + ptr_vector const & accs = *get_constructor_accessors(cns); for (unsigned j = 0; j < accs.size(); ++j) { func_decl* acc = accs[j]; sort* s1 = acc->get_range(); @@ -949,9 +974,9 @@ namespace datatype { } } -datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_constructors, constructor_decl * const * cs) { +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort*const* params, unsigned num_constructors, constructor_decl * const * cs) { datatype::decl::plugin* p = u.get_plugin(); - datatype::def( d = p->mk(n, 0, 0); + datatype::def* d = p->mk(n, num_params, params); for (unsigned i = 0; i < num_constructors; ++i) { d->add(cs[i]); } diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index c79939a5b..d7173b24a 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -50,19 +50,19 @@ namespace datatype { class accessor { - symbol m_name; - sort* m_range; + symbol m_name; + sort_ref m_range; unsigned m_index; // reference to recursive data-type may only get resolved after all mutually recursive data-types are procssed. constructor* m_constructor; public: - accessor(symbol const& n, sort* range): + accessor(ast_manager& m, symbol const& n, sort* range): m_name(n), - m_range(range), + m_range(range, m), m_index(UINT_MAX) {} - accessor(symbol const& n, unsigned index): + accessor(ast_manager& m, symbol const& n, unsigned index): m_name(n), - m_range(0), + m_range(m), m_index(index) {} sort* range() const { return m_range; } @@ -262,8 +262,6 @@ namespace datatype { void end_def_block(); - def& add(symbol const& name, unsigned n, sort * const * params); - def* mk(symbol const& name, unsigned n, sort * const * params); void del(symbol const& d); @@ -272,7 +270,7 @@ namespace datatype { def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); } def& get_def(symbol const& s) { return *(m_defs[s]); } - + bool is_declared(sort* s) const { return m_defs.contains(datatype_name(s)); } private: bool is_value_visit(expr * arg, ptr_buffer & todo) const; @@ -337,6 +335,7 @@ namespace datatype { util(ast_manager & m); ~util(); ast_manager & get_manager() const { return m; } + // sort * mk_datatype_sort(symbol const& name, unsigned n, sort* const* params); bool is_datatype(sort const* s) const { return is_sort_of(s, m_family_id, DATATYPE_SORT); } bool is_enum_sort(sort* s); bool is_recursive(sort * ty); @@ -348,13 +347,13 @@ namespace datatype { bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); } bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } - ptr_vector const & get_datatype_constructors(sort * ty); + ptr_vector const * get_datatype_constructors(sort * ty); unsigned get_datatype_num_constructors(sort * ty); unsigned get_datatype_num_parameter_sorts(sort * ty); sort* get_datatype_parameter_sort(sort * ty, unsigned idx); func_decl * get_non_rec_constructor(sort * ty); func_decl * get_constructor_recognizer(func_decl * constructor); - ptr_vector const & get_constructor_accessors(func_decl * constructor); + ptr_vector const * get_constructor_accessors(func_decl * constructor); func_decl * get_accessor_constructor(func_decl * accessor); func_decl * get_recognizer_constructor(func_decl * recognizer) const; family_id get_family_id() const { return m_family_id; } @@ -362,11 +361,13 @@ namespace datatype { bool is_func_decl(op_kind k, unsigned num_params, parameter const* params, func_decl* f); bool is_constructor_of(unsigned num_params, parameter const* params, func_decl* f); void reset(); + bool is_declared(sort* s) const; void display_datatype(sort *s, std::ostream& strm); bool is_fully_interp(sort * s) const; sort_ref_vector datatype_params(sort * s) const; unsigned get_constructor_idx(func_decl * f) const; unsigned get_recognizer_constructor_idx(func_decl * f) const; + decl::plugin* get_plugin() { return m_plugin; } }; }; @@ -390,12 +391,12 @@ public: int get_idx() const { return UNBOXINT(m_data); } }; -inline accessor_decl * mk_accessor_decl(symbol const & n, type_ref const & t) { +inline accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_ref const & t) { if (t.is_idx()) { - return alloc(accessor_decl, n, t.get_idx()); + return alloc(accessor_decl, m, n, t.get_idx()); } else { - return alloc(accessor_decl, n, t.get_sort()); + return alloc(accessor_decl, m, n, t.get_sort()); } } @@ -410,7 +411,7 @@ inline constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r // Remark: the datatype becomes the owner of the constructor_decls -datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_constructors, constructor_decl * const * cs); +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort*const* params, unsigned num_constructors, constructor_decl * const * cs); inline void del_datatype_decl(datatype_decl * d) {} inline void del_datatype_decls(unsigned num, datatype_decl * const * ds) {} diff --git a/src/ast/decl_collector.cpp b/src/ast/decl_collector.cpp index bf509aba5..e000f43df 100644 --- a/src/ast/decl_collector.cpp +++ b/src/ast/decl_collector.cpp @@ -28,9 +28,9 @@ void decl_collector::visit_sort(sort * n) { unsigned num_cnstr = m_dt_util.get_datatype_num_constructors(n); for (unsigned i = 0; i < num_cnstr; i++) { - func_decl * cnstr = m_dt_util.get_datatype_constructors(n).get(i); + func_decl * cnstr = m_dt_util.get_datatype_constructors(n)->get(i); m_decls.push_back(cnstr); - ptr_vector const & cnstr_acc = m_dt_util.get_constructor_accessors(cnstr); + ptr_vector const & cnstr_acc = *m_dt_util.get_constructor_accessors(cnstr); unsigned num_cas = cnstr_acc.size(); for (unsigned j = 0; j < num_cas; j++) { func_decl * accsr = cnstr_acc.get(j); diff --git a/src/ast/rewriter/datatype_rewriter.cpp b/src/ast/rewriter/datatype_rewriter.cpp index 8746fab86..9efa61f70 100644 --- a/src/ast/rewriter/datatype_rewriter.cpp +++ b/src/ast/rewriter/datatype_rewriter.cpp @@ -47,7 +47,7 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr func_decl * c_decl = a->get_decl(); if (c_decl != m_util.get_accessor_constructor(f)) return BR_FAILED; - ptr_vector const & acc = m_util.get_constructor_accessors(c_decl); + ptr_vector const & acc = *m_util.get_constructor_accessors(c_decl); SASSERT(acc.size() == a->get_num_args()); unsigned num = acc.size(); for (unsigned i = 0; i < num; ++i) { @@ -70,7 +70,7 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr result = a; return BR_DONE; } - ptr_vector const & acc = m_util.get_constructor_accessors(c_decl); + ptr_vector const & acc = *m_util.get_constructor_accessors(c_decl); SASSERT(acc.size() == a->get_num_args()); unsigned num = acc.size(); ptr_buffer new_args; diff --git a/src/ast/rewriter/enum2bv_rewriter.cpp b/src/ast/rewriter/enum2bv_rewriter.cpp index b2ecbcc24..eb6b195f0 100644 --- a/src/ast/rewriter/enum2bv_rewriter.cpp +++ b/src/ast/rewriter/enum2bv_rewriter.cpp @@ -130,7 +130,7 @@ struct enum2bv_rewriter::imp { m_imp.m_bounds.push_back(m_bv.mk_ule(result, m_bv.mk_numeral(nc-1, bv_size))); } expr_ref f_def(m); - ptr_vector const& cs = m_dt.get_datatype_constructors(s); + ptr_vector const& cs = *m_dt.get_datatype_constructors(s); f_def = m.mk_const(cs[nc-1]); for (unsigned i = nc - 1; i > 0; ) { --i; diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 109fe1718..21f1cfe27 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -682,8 +682,6 @@ bool cmd_context::logic_has_datatype() const { void cmd_context::init_manager_core(bool new_manager) { SASSERT(m_manager != 0); SASSERT(m_pmanager != 0); - m_dt_eh = alloc(dt_eh, *this); - m_pmanager->set_new_datatype_eh(m_dt_eh.get()); if (new_manager) { decl_plugin * basic = m_manager->get_plugin(m_manager->get_basic_family_id()); register_builtin_sorts(basic); @@ -719,6 +717,8 @@ void cmd_context::init_manager_core(bool new_manager) { } } } + m_dt_eh = alloc(dt_eh, *this); + m_pmanager->set_new_datatype_eh(m_dt_eh.get()); if (!has_logic()) { // add list type only if the logic is not specified. // it prevents clashes with builtin types. @@ -795,6 +795,7 @@ void cmd_context::insert(symbol const & s, func_decl * f) { dictionary::entry * e = m_func_decls.insert_if_not_there2(s, func_decls()); func_decls & fs = e->get_data().m_value; if (!fs.insert(m(), f)) { + UNREACHABLE(); std::string msg = "invalid declaration, "; msg += f->get_arity() == 0 ? "constant" : "function"; msg += " '"; @@ -1954,21 +1955,17 @@ cmd_context::dt_eh::~dt_eh() { void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) { TRACE("new_dt_eh", tout << "new datatype: "; m_owner.pm().display(tout, dt); tout << "\n";); - ptr_vector const & constructors = m_dt_util.get_datatype_constructors(dt); - unsigned num_constructors = constructors.size(); - for (unsigned j = 0; j < num_constructors; j++) { - func_decl * c = constructors[j]; - m_owner.insert(c); + for (func_decl * c : *m_dt_util.get_datatype_constructors(dt)) { TRACE("new_dt_eh", tout << "new constructor: " << c->get_name() << "\n";); + m_owner.insert(c); +#ifndef DATATYPE_V2 func_decl * r = m_dt_util.get_constructor_recognizer(c); m_owner.insert(r); TRACE("new_dt_eh", tout << "new recognizer: " << r->get_name() << "\n";); - ptr_vector const & accessors = m_dt_util.get_constructor_accessors(c); - unsigned num_accessors = accessors.size(); - for (unsigned k = 0; k < num_accessors; k++) { - func_decl * a = accessors[k]; - m_owner.insert(a); +#endif + for (func_decl * a : *m_dt_util.get_constructor_accessors(c)) { TRACE("new_dt_eh", tout << "new accessor: " << a->get_name() << "\n";); + m_owner.insert(a); } } if (m_owner.m_scopes.size() > 0) { diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 04456c076..4417061ec 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -170,9 +170,10 @@ public: virtual char const * hcons_kind() const { return "psort_var"; } virtual unsigned hcons_hash() const { return hash_u_u(m_num_params, m_idx); } virtual bool hcons_eq(psort const * other) const { - if (other->hcons_kind() != hcons_kind()) - return false; - return get_num_params() == other->get_num_params() && m_idx == static_cast(other)->m_idx; + return + other->hcons_kind() == hcons_kind() && + get_num_params() == other->get_num_params() && + m_idx == static_cast(other)->m_idx; } virtual void display(std::ostream & out) const { out << "s_" << m_idx; @@ -344,6 +345,53 @@ void psort_user_decl::display(std::ostream & out) const { out << ")"; } +// ------------------- +// psort_dt_decl + +psort_dt_decl::psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n) : + psort_decl(id, num_params, m, n) { + m_psort_kind = PSORT_DT; +} + + +sort * psort_dt_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { +#ifndef DATATYPE_V2 + UNREACHABLE(); + return 0; +#else + SASSERT(n == m_num_params); + sort * r = find(s); + if (r) + return r; + buffer ps; + ps.push_back(parameter(m_name)); + for (unsigned i = 0; i < n; i++) + ps.push_back(parameter(s[i])); + datatype_util util(m.m()); + r = m.m().mk_sort(util.get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); + cache(m, s, r); + m.save_info(r, this, n, s); + if (m_num_params > 0 && util.is_declared(r)) { + bool has_typevar = false; + // crude check .. + for (unsigned i = 0; !has_typevar && i < n; ++i) { + has_typevar = s[i]->get_name().is_numerical(); + } + if (!has_typevar) { + m.notify_new_dt(r, this); + } + } + return r; +#endif +} + +void psort_dt_decl::display(std::ostream & out) const { + out << "(datatype-sort " << m_name << ")"; +} + +// ------------------- +// psort_builtin_decl + psort_builtin_decl::psort_builtin_decl(unsigned id, pdecl_manager & m, symbol const & n, family_id fid, decl_kind k): psort_decl(id, PSORT_DECL_VAR_PARAMS, m, n), m_fid(fid), @@ -435,8 +483,8 @@ bool paccessor_decl::fix_missing_refs(dictionary const & symbol2idx, symbol accessor_decl * paccessor_decl::instantiate_decl(pdecl_manager & m, sort * const * s) { switch (m_type.kind()) { - case PTR_REC_REF: return mk_accessor_decl(m_name, type_ref(m_type.get_idx())); - case PTR_PSORT: return mk_accessor_decl(m_name, type_ref(m_type.get_psort()->instantiate(m, s))); + case PTR_REC_REF: return mk_accessor_decl(m.m(), m_name, type_ref(m_type.get_idx())); + case PTR_PSORT: return mk_accessor_decl(m.m(), m_name, type_ref(m_type.get_psort()->instantiate(m, s))); default: // missing refs must have been eliminated. UNREACHABLE(); @@ -546,7 +594,7 @@ datatype_decl * pdatatype_decl::instantiate_decl(pdecl_manager & m, sort * const cs.push_back(c->instantiate_decl(m, s)); } datatype_util util(m.m()); - return mk_datatype_decl(util, m_name, cs.size(), cs.c_ptr()); + return mk_datatype_decl(util, m_name, m_num_params, s, cs.size(), cs.c_ptr()); } struct datatype_decl_buffer { @@ -554,6 +602,12 @@ struct datatype_decl_buffer { ~datatype_decl_buffer() { del_datatype_decls(m_buffer.size(), m_buffer.c_ptr()); } }; +#ifdef DATATYPE_V2 +sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { + UNREACHABLE(); + return 0; +} +#else sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { SASSERT(m_num_params == n); sort * r = find(s); @@ -583,6 +637,7 @@ sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * } return 0; } +#endif void pdatatype_decl::display(std::ostream & out) const { out << "(declare-datatype " << m_name; @@ -603,6 +658,27 @@ void pdatatype_decl::display(std::ostream & out) const { out << ")"; } +#ifdef DATATYPE_V2 +bool pdatatype_decl::commit(pdecl_manager& m) { + sort_ref_vector ps(m.m()); + for (unsigned i = 0; i < m_num_params; ++i) { + ps.push_back(m.m().mk_uninterpreted_sort(symbol(i), 0, 0)); + } + datatype_decl_buffer dts; + dts.m_buffer.push_back(instantiate_decl(m, ps.c_ptr())); + datatype_decl * d_ptr = dts.m_buffer[0]; + sort_ref_vector sorts(m.m()); + bool is_ok = m.get_dt_plugin()->mk_datatypes(1, &d_ptr, m_num_params, ps.c_ptr(), sorts); + if (is_ok) { + if (m_num_params == 0) { + m.notify_new_dt(sorts.get(0), this); + } + } + return is_ok; +} +#endif + + pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m, unsigned num_datatypes, pdatatype_decl * const * dts): pdecl(id, num_params), @@ -631,6 +707,12 @@ bool pdatatypes_decl::fix_missing_refs(symbol & missing) { return true; } +#ifdef DATATYPE_V2 +bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) { + UNREACHABLE(); + return false; +} +#else bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) { datatype_decl_buffer dts; for (auto d : m_datatypes) { @@ -649,6 +731,31 @@ bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) { } return true; } +#endif + +#ifdef DATATYPE_V2 +bool pdatatypes_decl::commit(pdecl_manager& m) { + datatype_decl_buffer dts; + for (pdatatype_decl* d : m_datatypes) { + sort_ref_vector ps(m.m()); + for (unsigned i = 0; i < d->get_num_params(); ++i) { + ps.push_back(m.m().mk_uninterpreted_sort(symbol(i), 0, 0)); + } + dts.m_buffer.push_back(d->instantiate_decl(m, ps.c_ptr())); + } + sort_ref_vector sorts(m.m()); + bool is_ok = m.get_dt_plugin()->mk_datatypes(m_datatypes.size(), dts.m_buffer.c_ptr(), 0, nullptr, sorts); + if (is_ok) { + for (unsigned i = 0; i < m_datatypes.size(); ++i) { + pdatatype_decl* d = m_datatypes[i]; + if (d->get_num_params() == 0) { + m.notify_new_dt(sorts.get(i), this); + } + } + } + return is_ok; +} +#endif struct pdecl_manager::sort_info { psort_decl * m_decl; @@ -790,9 +897,8 @@ psort * pdecl_manager::register_psort(psort * n) { psort * r = m_table.insert_if_not_there(n); if (r != n) { del_decl_core(n); - return r; } - return n; + return r; } psort * pdecl_manager::mk_psort_var(unsigned num_params, unsigned vidx) { @@ -837,6 +943,11 @@ psort_decl * pdecl_manager::mk_psort_user_decl(unsigned num_params, symbol const return new (a().allocate(sizeof(psort_user_decl))) psort_user_decl(m_id_gen.mk(), num_params, *this, n, def); } +psort_decl * pdecl_manager::mk_psort_dt_decl(unsigned num_params, symbol const & n) { + // std::cout << "insert dt-psort: " << n << " " << num_params << "\n"; + return new (a().allocate(sizeof(psort_dt_decl))) psort_dt_decl(m_id_gen.mk(), num_params, *this, n); +} + psort_decl * pdecl_manager::mk_psort_builtin_decl(symbol const & n, family_id fid, decl_kind k) { return new (a().allocate(sizeof(psort_builtin_decl))) psort_builtin_decl(m_id_gen.mk(), *this, n, fid, k); diff --git a/src/cmd_context/pdecl.h b/src/cmd_context/pdecl.h index e7fae8dd5..414415255 100644 --- a/src/cmd_context/pdecl.h +++ b/src/cmd_context/pdecl.h @@ -87,7 +87,7 @@ typedef ptr_hashtable psort_table; #define PSORT_DECL_VAR_PARAMS UINT_MAX -typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN } psort_decl_kind; +typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN, PSORT_DT } psort_decl_kind; class psort_decl : public pdecl { protected: @@ -111,6 +111,7 @@ public: virtual void reset_cache(pdecl_manager& m); bool is_user_decl() const { return m_psort_kind == PSORT_USER; } bool is_builtin_decl() const { return m_psort_kind == PSORT_BUILTIN; } + bool is_dt_decl() const { return m_psort_kind == PSORT_DT; } }; class psort_user_decl : public psort_decl { @@ -125,7 +126,7 @@ public: virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s); virtual void display(std::ostream & out) const; }; - + class psort_builtin_decl : public psort_decl { protected: friend class pdecl_manager; @@ -140,10 +141,17 @@ public: virtual void display(std::ostream & out) const; }; -//class datatype_decl_plugin; -//class datatype_decl; -//class constructor_decl; -//class accessor_decl; +class psort_dt_decl : public psort_decl { +protected: + friend class pdecl_manager; + psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n); + virtual size_t obj_size() const { return sizeof(psort_dt_decl); } + virtual ~psort_dt_decl() {} +public: + virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s); + virtual void display(std::ostream & out) const; +}; + class pdatatypes_decl; class pdatatype_decl; @@ -233,6 +241,9 @@ public: virtual void display(std::ostream & out) const; bool has_missing_refs(symbol & missing) const; bool has_duplicate_accessors(symbol & repeated) const; +#ifdef DATATYPE_V2 + bool commit(pdecl_manager& m); +#endif }; /** @@ -250,6 +261,10 @@ class pdatatypes_decl : public pdecl { virtual ~pdatatypes_decl() {} public: pdatatype_decl const * const * children() const { return m_datatypes.c_ptr(); } +#ifdef DATATYPE_V2 + // commit declaration + bool commit(pdecl_manager& m); +#endif }; class new_datatype_eh { @@ -292,7 +307,7 @@ public: psort * mk_psort_var(unsigned num_params, unsigned vidx); psort * mk_psort_app(unsigned num_params, psort_decl * d, unsigned num_args, psort * const * args); psort * mk_psort_app(psort_decl * d); - // psort_decl * mk_psort_dt_decl(unsigned num_params, symbol const & n); + psort_decl * mk_psort_dt_decl(unsigned num_params, symbol const & n); psort_decl * mk_psort_user_decl(unsigned num_params, symbol const & n, psort * def); psort_decl * mk_psort_builtin_decl(symbol const & n, family_id fid, decl_kind k); paccessor_decl * mk_paccessor_decl(unsigned num_params, symbol const & s, ptype const & p); diff --git a/src/muz/base/dl_rule.h b/src/muz/base/dl_rule.h index 51d673ba5..ea0e64e4f 100644 --- a/src/muz/base/dl_rule.h +++ b/src/muz/base/dl_rule.h @@ -65,7 +65,7 @@ namespace datalog { else if (m_dt.is_accessor(n)) { sort* s = m.get_sort(n->get_arg(0)); SASSERT(m_dt.is_datatype(s)); - if (m_dt.get_datatype_constructors(s).size() > 1) { + if (m_dt.get_datatype_constructors(s)->size() > 1) { m_found = true; m_func = n->get_decl(); } diff --git a/src/muz/base/rule_properties.cpp b/src/muz/base/rule_properties.cpp index 75487bbfb..21317a07c 100644 --- a/src/muz/base/rule_properties.cpp +++ b/src/muz/base/rule_properties.cpp @@ -191,7 +191,7 @@ void rule_properties::operator()(app* n) { else if (m_dt.is_accessor(n)) { sort* s = m.get_sort(n->get_arg(0)); SASSERT(m_dt.is_datatype(s)); - if (m_dt.get_datatype_constructors(s).size() > 1) { + if (m_dt.get_datatype_constructors(s)->size() > 1) { m_uninterp_funs.insert(n->get_decl(), m_rule); } } diff --git a/src/muz/bmc/dl_bmc_engine.cpp b/src/muz/bmc/dl_bmc_engine.cpp index 9109f6b3c..3368c7640 100644 --- a/src/muz/bmc/dl_bmc_engine.cpp +++ b/src/muz/bmc/dl_bmc_engine.cpp @@ -808,7 +808,7 @@ namespace datalog { datatype_util dtu(m); ptr_vector sorts; func_decl* p = r.get_decl(); - ptr_vector const& succs = dtu.get_datatype_constructors(m.get_sort(path)); + ptr_vector const& succs = *dtu.get_datatype_constructors(m.get_sort(path)); // populate substitution of bound variables. r.get_vars(m, sorts); sub.reset(); @@ -871,8 +871,8 @@ namespace datalog { path_var = m.mk_var(0, m_path_sort); trace_var = m.mk_var(1, pred_sort); // sort* sorts[2] = { pred_sort, m_path_sort }; - ptr_vector const& cnstrs = dtu.get_datatype_constructors(pred_sort); - ptr_vector const& succs = dtu.get_datatype_constructors(m_path_sort); + ptr_vector const& cnstrs = *dtu.get_datatype_constructors(pred_sort); + ptr_vector const& succs = *dtu.get_datatype_constructors(m_path_sort); SASSERT(cnstrs.size() == rls.size()); pred = m.mk_app(mk_predicate(p), trace_var.get(), path_var.get()); for (unsigned i = 0; i < rls.size(); ++i) { @@ -970,7 +970,7 @@ namespace datalog { _name << pred->get_name() << "_" << q->get_name() << j; symbol name(_name.str().c_str()); type_ref tr(idx); - accs.push_back(mk_accessor_decl(name, tr)); + accs.push_back(mk_accessor_decl(m, name, tr)); } std::stringstream _name; _name << pred->get_name() << "_" << i; @@ -979,7 +979,7 @@ namespace datalog { symbol is_name(_name.str().c_str()); cnstrs.push_back(mk_constructor_decl(name, is_name, accs.size(), accs.c_ptr())); } - dts.push_back(mk_datatype_decl(dtu, pred->get_name(), cnstrs.size(), cnstrs.c_ptr())); + dts.push_back(mk_datatype_decl(dtu, pred->get_name(), 0, nullptr, cnstrs.size(), cnstrs.c_ptr())); } @@ -1024,10 +1024,10 @@ namespace datalog { _name2 << "get_succ#" << i; ptr_vector accs; type_ref tr(0); - accs.push_back(mk_accessor_decl(name, tr)); + accs.push_back(mk_accessor_decl(m, name, tr)); cnstrs.push_back(mk_constructor_decl(name, is_name, accs.size(), accs.c_ptr())); } - dts.push_back(mk_datatype_decl(dtu, symbol("Path"), cnstrs.size(), cnstrs.c_ptr())); + dts.push_back(mk_datatype_decl(dtu, symbol("Path"), 0, nullptr, cnstrs.size(), cnstrs.c_ptr())); VERIFY (dtp->mk_datatypes(dts.size(), dts.c_ptr(), 0, 0, new_sorts)); m_path_sort = new_sorts[0].get(); } @@ -1039,8 +1039,8 @@ namespace datalog { sort* trace_sort = m.get_sort(trace); func_decl* p = m_sort2pred.find(trace_sort); datalog::rule_vector const& rules = b.m_rules.get_predicate_rules(p); - ptr_vector const& cnstrs = dtu.get_datatype_constructors(trace_sort); - ptr_vector const& succs = dtu.get_datatype_constructors(m_path_sort); + ptr_vector const& cnstrs = *dtu.get_datatype_constructors(trace_sort); + ptr_vector const& succs = *dtu.get_datatype_constructors(m_path_sort); for (unsigned i = 0; i < cnstrs.size(); ++i) { if (trace->get_decl() == cnstrs[i]) { svector > positions; diff --git a/src/muz/pdr/pdr_prop_solver.cpp b/src/muz/pdr/pdr_prop_solver.cpp index 1bca8e925..3055985f4 100644 --- a/src/muz/pdr/pdr_prop_solver.cpp +++ b/src/muz/pdr/pdr_prop_solver.cpp @@ -135,7 +135,7 @@ namespace pdr { func_decl* f = to_app(val)->get_decl(); func_decl* r = dt.get_constructor_recognizer(f); conjs[i] = m.mk_app(r, c); - ptr_vector const& acc = dt.get_constructor_accessors(f); + ptr_vector const& acc = *dt.get_constructor_accessors(f); for (unsigned j = 0; j < acc.size(); ++j) { conjs.push_back(m.mk_eq(apply_accessor(acc, j, f, c), to_app(val)->get_arg(j))); } diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp index 14d8899c5..a277c9ed6 100644 --- a/src/muz/spacer/spacer_util.cpp +++ b/src/muz/spacer/spacer_util.cpp @@ -711,7 +711,7 @@ void expand_literals(ast_manager &m, expr_ref_vector& conjs) func_decl* f = to_app(val)->get_decl(); func_decl* r = dt.get_constructor_recognizer(f); conjs[i] = m.mk_app(r, c); - ptr_vector const& acc = dt.get_constructor_accessors(f); + ptr_vector const& acc = *dt.get_constructor_accessors(f); for (unsigned j = 0; j < acc.size(); ++j) { conjs.push_back(m.mk_eq(apply_accessor(m, acc, j, f, c), to_app(val)->get_arg(j))); } diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 3d895668b..9526429cb 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -16,8 +16,6 @@ Author: Revision History: --*/ -#include "parsers/smt2/smt2parser.h" -#include "parsers/smt2/smt2scanner.h" #include "util/stack.h" #include "ast/datatype_decl_plugin.h" #include "ast/bv_decl_plugin.h" @@ -25,10 +23,12 @@ Revision History: #include "ast/seq_decl_plugin.h" #include "ast/ast_pp.h" #include "ast/well_sorted.h" -#include "parsers/util/pattern_validation.h" #include "ast/rewriter/rewriter.h" #include "ast/has_free_vars.h" #include "ast/ast_smt2_pp.h" +#include "parsers/smt2/smt2parser.h" +#include "parsers/smt2/smt2scanner.h" +#include "parsers/util/pattern_validation.h" #include "parsers/util/parser_params.hpp" #include @@ -885,6 +885,9 @@ namespace smt2 { } else if (sz == 1) { check_missing(new_dt_decls[0], line, pos); +#ifdef DATATYPE_V2 + new_dt_decls[0]->commit(pm()); +#endif } else { SASSERT(sz > 1); @@ -897,8 +900,13 @@ namespace smt2 { err_msg += "'"; throw parser_exception(err_msg, line, pos); } +#ifndef DATATYPE_V2 m_ctx.insert_aux_pdecl(dts.get()); +#else + dts->commit(pm()); +#endif } +#ifndef DATATYPE_V2 for (unsigned i = 0; i < sz; i++) { pdatatype_decl * d = new_dt_decls[i]; SASSERT(d != 0); @@ -911,6 +919,13 @@ namespace smt2 { s = d->instantiate(pm(), 0, 0); } } +#else + for (unsigned i = 0; i < sz; i++) { + pdatatype_decl * d = new_dt_decls[i]; + symbol duplicated; + check_duplicate(d, line, pos); + } +#endif TRACE("declare_datatypes", tout << "i: " << i << " new_dt_decls.size(): " << sz << "\n"; for (unsigned i = 0; i < sz; i++) tout << new_dt_decls[i]->get_name() << "\n";); m_ctx.print_success(); @@ -940,12 +955,16 @@ namespace smt2 { check_missing(d, line, pos); check_duplicate(d, line, pos); +#ifndef DATATYPE_V2 m_ctx.insert(d); if (d->get_num_params() == 0) { // if datatype is not parametric... then force instantiation to register accessor, recognizers and constructors... sort_ref s(m()); s = d->instantiate(pm(), 0, 0); } +#else + d->commit(pm()); +#endif check_rparen_next("invalid end of datatype declaration, ')' expected"); m_ctx.print_success(); } @@ -1909,6 +1928,8 @@ namespace smt2 { m_dt_name2idx.insert(dt_name, i); m_dt_name2arity.insert(dt_name, u); m_dt_names.push_back(dt_name); + psort_decl * decl = pm().mk_psort_dt_decl(u, dt_name); + m_ctx.insert(decl); check_rparen("invalid sort declaration, ')' expected"); } else { diff --git a/src/qe/qe_datatype_plugin.cpp b/src/qe/qe_datatype_plugin.cpp index eff230ffe..c3525aa33 100644 --- a/src/qe/qe_datatype_plugin.cpp +++ b/src/qe/qe_datatype_plugin.cpp @@ -262,7 +262,7 @@ namespace qe { } func_decl* c = a->get_decl(); func_decl* r = m_util.get_constructor_recognizer(c); - ptr_vector const & acc = m_util.get_constructor_accessors(c); + ptr_vector const & acc = *m_util.get_constructor_accessors(c); SASSERT(acc.size() == a->get_num_args()); // // It suffices to solve just the first available equality. @@ -379,7 +379,7 @@ namespace qe { return false; } func_decl* c = l->get_decl(); - ptr_vector const& acc = m_util.get_constructor_accessors(c); + ptr_vector const& acc = *m_util.get_constructor_accessors(c); func_decl* rec = m_util.get_constructor_recognizer(c); expr_ref_vector conj(m); conj.push_back(m.mk_app(rec, r)); @@ -626,7 +626,7 @@ namespace qe { // If 'x' does not yet have a recognizer, then branch according to recognizers. // if (!has_recognizer(x, fml, r, c)) { - c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)->get(vl.get_unsigned()); r = m_datatype_util.get_constructor_recognizer(c); app* is_c = m.mk_app(r, x); // assert v => r(x) @@ -673,7 +673,7 @@ namespace qe { // Introduce auxiliary variable to eliminate. // if (!has_recognizer(x, fml, r, c)) { - c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)->get(vl.get_unsigned()); r = m_datatype_util.get_constructor_recognizer(c); app* is_c = m.mk_app(r, x); fml = m.mk_and(is_c, fml); @@ -774,7 +774,7 @@ namespace qe { return; } - c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)->get(vl.get_unsigned()); r = m_datatype_util.get_constructor_recognizer(c); app* is_c = m.mk_app(r, x); @@ -794,7 +794,7 @@ namespace qe { else { SASSERT(vl.is_unsigned()); SASSERT(vl.get_unsigned() < m_datatype_util.get_datatype_num_constructors(s)); - c = m_datatype_util.get_datatype_constructors(s)[vl.get_unsigned()]; + c = m_datatype_util.get_datatype_constructors(s)->get(vl.get_unsigned()); } subst_constructor(x, c, fml, def); } diff --git a/src/qe/qe_datatypes.cpp b/src/qe/qe_datatypes.cpp index f16bdda59..db1e6ec85 100644 --- a/src/qe/qe_datatypes.cpp +++ b/src/qe/qe_datatypes.cpp @@ -75,7 +75,7 @@ namespace qe { app_ref arg(m); SASSERT(dt.is_constructor(m_val)); func_decl* f = m_val->get_decl(); - ptr_vector const& acc = dt.get_constructor_accessors(f); + ptr_vector const& acc = *dt.get_constructor_accessors(f); for (unsigned i = 0; i < acc.size(); ++i) { arg = m.mk_fresh_const(acc[i]->get_name().str().c_str(), acc[i]->get_range()); model.register_decl(arg->get_decl(), m_val->get_arg(i)); @@ -152,7 +152,7 @@ namespace qe { } func_decl* c = a->get_decl(); func_decl* rec = dt.get_constructor_recognizer(c); - ptr_vector const & acc = dt.get_constructor_accessors(c); + ptr_vector const & acc = *dt.get_constructor_accessors(c); SASSERT(acc.size() == a->get_num_args()); // // It suffices to solve just the first available equality. @@ -230,7 +230,7 @@ namespace qe { return false; } func_decl* c = to_app(l)->get_decl(); - ptr_vector const& acc = dt.get_constructor_accessors(c); + ptr_vector const& acc = *dt.get_constructor_accessors(c); if (!is_app_of(r, c)) { lits.push_back(m.mk_app(dt.get_constructor_recognizer(c), r)); } diff --git a/src/qe/qe_lite.cpp b/src/qe/qe_lite.cpp index 10af3be25..257331161 100644 --- a/src/qe/qe_lite.cpp +++ b/src/qe/qe_lite.cpp @@ -671,7 +671,7 @@ namespace eq { 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); + 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))); } diff --git a/src/smt/proto_model/datatype_factory.cpp b/src/smt/proto_model/datatype_factory.cpp index 653ef034a..03f008fe6 100644 --- a/src/smt/proto_model/datatype_factory.cpp +++ b/src/smt/proto_model/datatype_factory.cpp @@ -88,7 +88,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) { // Traverse constructors, and try to invoke get_fresh_value of one of the arguments (if the argument is not a sibling datatype of s). // If the argumet is a sibling datatype of s, then // use get_last_fresh_value. - ptr_vector const & constructors = m_util.get_datatype_constructors(s); + ptr_vector const & constructors = *m_util.get_datatype_constructors(s); for (func_decl * constructor : constructors) { expr_ref_vector args(m_manager); bool found_fresh_arg = false; @@ -151,7 +151,7 @@ expr * datatype_factory::get_fresh_value(sort * s) { // Traverse constructors, and try to invoke get_fresh_value of one of the // arguments (if the argument is not a sibling datatype of s). // Two datatypes are siblings if they were defined together in the same mutually recursive definition. - ptr_vector const & constructors = m_util.get_datatype_constructors(s); + ptr_vector const & constructors = *m_util.get_datatype_constructors(s); for (func_decl * constructor : constructors) { expr_ref_vector args(m_manager); bool found_fresh_arg = false; @@ -189,7 +189,7 @@ expr * datatype_factory::get_fresh_value(sort * s) { while(true) { ++num_iterations; TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";); - ptr_vector const & constructors = m_util.get_datatype_constructors(s); + ptr_vector const & constructors = *m_util.get_datatype_constructors(s); for (func_decl * constructor : constructors) { expr_ref_vector args(m_manager); bool found_sibling = false; diff --git a/src/smt/smt_value_sort.cpp b/src/smt/smt_value_sort.cpp index 3eeb3461d..56768b91a 100644 --- a/src/smt/smt_value_sort.cpp +++ b/src/smt/smt_value_sort.cpp @@ -52,7 +52,7 @@ namespace smt { // simple } else if (data.is_datatype(s)) { - ptr_vector const& cs = data.get_datatype_constructors(s); + ptr_vector const& cs = *data.get_datatype_constructors(s); for (unsigned i = 0; i < cs.size(); ++i) { func_decl* f = cs[i]; for (unsigned j = 0; j < f->get_arity(); ++j) { diff --git a/src/smt/theory_datatype.cpp b/src/smt/theory_datatype.cpp index 33b4b194d..616314117 100644 --- a/src/smt/theory_datatype.cpp +++ b/src/smt/theory_datatype.cpp @@ -17,13 +17,13 @@ Revision History: --*/ +#include "util/stats.h" +#include "ast/ast_pp.h" +#include "ast/ast_ll_pp.h" +#include "ast/ast_smt2_pp.h" #include "smt/smt_context.h" #include "smt/theory_datatype.h" #include "smt/smt_model_generator.h" -#include "ast/ast_pp.h" -#include "ast/ast_ll_pp.h" -#include "util/stats.h" -#include "ast/ast_smt2_pp.h" namespace smt { @@ -97,7 +97,7 @@ namespace smt { SASSERT(m_util.is_datatype(get_manager().get_sort(n->get_owner()))); ast_manager & m = get_manager(); ptr_vector args; - ptr_vector const & accessors = m_util.get_constructor_accessors(c); + ptr_vector const & accessors = *m_util.get_constructor_accessors(c); SASSERT(c->get_arity() == accessors.size()); for (func_decl * d : accessors) { SASSERT(d->get_arity() == 1); @@ -120,7 +120,7 @@ namespace smt { SASSERT(is_constructor(n)); ast_manager & m = get_manager(); func_decl * d = n->get_decl(); - ptr_vector const & accessors = m_util.get_constructor_accessors(d); + ptr_vector const & accessors = *m_util.get_constructor_accessors(d); SASSERT(n->get_num_args() == accessors.size()); unsigned i = 0; for (func_decl * acc : accessors) { @@ -168,7 +168,7 @@ namespace smt { func_decl * acc = to_func_decl(upd->get_parameter(0).get_ast()); func_decl * con = m_util.get_accessor_constructor(acc); func_decl * rec = m_util.get_constructor_recognizer(con); - ptr_vector const & accessors = m_util.get_constructor_accessors(con); + ptr_vector const & accessors = *m_util.get_constructor_accessors(con); app_ref rec_app(m.mk_app(rec, arg1), m); ctx.internalize(rec_app, false); literal is_con(ctx.get_bool_var(rec_app)); @@ -208,7 +208,7 @@ namespace smt { ast_manager & m = get_manager(); sort * s = m.get_sort(n->get_owner()); if (m_util.get_datatype_num_constructors(s) == 1) { - func_decl * c = m_util.get_datatype_constructors(s)[0]; + func_decl * c = m_util.get_datatype_constructors(s)->get(0); assert_is_constructor_axiom(n, c, null_literal); } else { @@ -709,7 +709,7 @@ namespace smt { enode * r = d->m_recognizers[unassigned_idx]; literal consequent; if (!r) { - ptr_vector const & constructors = m_util.get_datatype_constructors(dt); + ptr_vector const & constructors = *m_util.get_datatype_constructors(dt); func_decl * rec = m_util.get_constructor_recognizer(constructors[unassigned_idx]); app * rec_app = get_manager().mk_app(rec, n->get_owner()); ctx.internalize(rec_app, false); @@ -774,7 +774,7 @@ namespace smt { for (unsigned idx = 0; it != end; ++it, ++idx) { enode * curr = *it; if (curr == 0) { - ptr_vector const & constructors = m_util.get_datatype_constructors(s); + ptr_vector const & constructors = *m_util.get_datatype_constructors(s); // found empty slot... r = m_util.get_constructor_recognizer(constructors[idx]); break; @@ -793,7 +793,7 @@ namespace smt { } SASSERT(r != 0); app * r_app = m.mk_app(r, n->get_owner()); - TRACE("datatype", tout << "creating split: " << mk_bounded_pp(r_app, m) << "\n";); + TRACE("datatype", tout << "creating split: " << mk_pp(r_app, m) << "\n";); ctx.internalize(r_app, false); bool_var bv = ctx.get_bool_var(r_app); ctx.set_true_first_flag(bv); diff --git a/src/tactic/core/elim_uncnstr_tactic.cpp b/src/tactic/core/elim_uncnstr_tactic.cpp index a13cd54d8..6a38f787e 100644 --- a/src/tactic/core/elim_uncnstr_tactic.cpp +++ b/src/tactic/core/elim_uncnstr_tactic.cpp @@ -174,7 +174,7 @@ class elim_uncnstr_tactic : public tactic { if (fid == m_dt_util.get_family_id()) { // In the current implementation, I only handle the case where // the datatype has a recursive constructor. - ptr_vector const & constructors = m_dt_util.get_datatype_constructors(s); + ptr_vector const & constructors = *m_dt_util.get_datatype_constructors(s); for (func_decl * constructor : constructors) { unsigned num = constructor->get_arity(); unsigned target = UINT_MAX; @@ -704,7 +704,7 @@ class elim_uncnstr_tactic : public tactic { app * u; if (!mk_fresh_uncnstr_var_for(f, num, args, u)) return u; - ptr_vector const & accs = m_dt_util.get_constructor_accessors(c); + ptr_vector const & accs = *m_dt_util.get_constructor_accessors(c); ptr_buffer new_args; for (unsigned i = 0; i < accs.size(); i++) { if (accs[i] == f) @@ -723,7 +723,7 @@ class elim_uncnstr_tactic : public tactic { return u; if (!m_mc) return u; - ptr_vector const & accs = m_dt_util.get_constructor_accessors(f); + ptr_vector const & accs = *m_dt_util.get_constructor_accessors(f); for (unsigned i = 0; i < num; i++) { add_def(args[i], m().mk_app(accs[i], u)); } diff --git a/src/tactic/portfolio/enum2bv_solver.cpp b/src/tactic/portfolio/enum2bv_solver.cpp index db7cebd6e..36a178c41 100644 --- a/src/tactic/portfolio/enum2bv_solver.cpp +++ b/src/tactic/portfolio/enum2bv_solver.cpp @@ -136,7 +136,7 @@ public: if (m.is_eq(b, u, v) && is_uninterp_const(u) && m_rewriter.bv2enum().find(to_app(u)->get_decl(), f) && bv.is_numeral(v, num, bvsize)) { SASSERT(num.is_unsigned()); expr_ref head(m); - ptr_vector const& enums = dt.get_datatype_constructors(f->get_range()); + ptr_vector const& enums = *dt.get_datatype_constructors(f->get_range()); if (enums.size() > num.get_unsigned()) { head = m.mk_eq(m.mk_const(f), m.mk_const(enums[num.get_unsigned()])); consequences[i] = m.mk_implies(a, head); From aac7773a525b71fa6aab771163718ae9266d4835 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 4 Sep 2017 21:15:44 -0700 Subject: [PATCH 249/488] support for smtlib2.6 datatype parsing Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 21f1cfe27..e93e51186 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -795,7 +795,6 @@ void cmd_context::insert(symbol const & s, func_decl * f) { dictionary::entry * e = m_func_decls.insert_if_not_there2(s, func_decls()); func_decls & fs = e->get_data().m_value; if (!fs.insert(m(), f)) { - UNREACHABLE(); std::string msg = "invalid declaration, "; msg += f->get_arity() == 0 ? "constant" : "function"; msg += " '"; From a4cf2726fdd58324e9b65e843c3763aefb9fdaa1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 07:35:37 -0700 Subject: [PATCH 250/488] fix seg-fault from #1244 Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/seq_rewriter.cpp | 2 +- src/smt/asserted_formulas.h | 3 ++- src/smt/smt_conflict_resolution.cpp | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ast/rewriter/seq_rewriter.cpp b/src/ast/rewriter/seq_rewriter.cpp index 70eddcea1..96a98e472 100644 --- a/src/ast/rewriter/seq_rewriter.cpp +++ b/src/ast/rewriter/seq_rewriter.cpp @@ -1946,7 +1946,7 @@ bool seq_rewriter::solve_itos(unsigned szl, expr* const* ls, unsigned szr, expr* } } - if (szr == 1 && m_util.str.is_itos(rs[0], r) && !m_util.str.is_itos(ls[0])) { + if (szr == 1 && szl >= 1 && m_util.str.is_itos(rs[0], r) && !m_util.str.is_itos(ls[0])) { return solve_itos(szr, rs, szl, ls, rhs, lhs, is_sat); } diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h index 093680fd9..1f86edb75 100644 --- a/src/smt/asserted_formulas.h +++ b/src/smt/asserted_formulas.h @@ -96,6 +96,8 @@ class asserted_formulas { void max_bv_sharing(); bool canceled() { return m.canceled(); } + void init(unsigned num_formulas, expr * const * formulas, proof * const * prs); + public: asserted_formulas(ast_manager & m, smt_params & p); ~asserted_formulas(); @@ -118,7 +120,6 @@ public: proof * get_formula_proof(unsigned idx) const { return m.proofs_enabled() ? m_asserted_formula_prs.get(idx) : 0; } expr * const * get_formulas() const { return m_asserted_formulas.c_ptr(); } proof * const * get_formula_proofs() const { return m_asserted_formula_prs.c_ptr(); } - void init(unsigned num_formulas, expr * const * formulas, proof * const * prs); void register_simplifier_plugin(simplifier_plugin * p) { m_simplifier.register_plugin(p); } simplifier & get_simplifier() { return m_simplifier; } void get_assertions(ptr_vector & result); diff --git a/src/smt/smt_conflict_resolution.cpp b/src/smt/smt_conflict_resolution.cpp index 79a1f0416..cb1465d94 100644 --- a/src/smt/smt_conflict_resolution.cpp +++ b/src/smt/smt_conflict_resolution.cpp @@ -348,10 +348,8 @@ namespace smt { literal_vector & antecedents = m_tmp_literal_vector; antecedents.reset(); justification2literals_core(js, antecedents); - literal_vector::iterator it = antecedents.begin(); - literal_vector::iterator end = antecedents.end(); - for(; it != end; ++it) - process_antecedent(*it, num_marks); + for (literal l : antecedents) + process_antecedent(l, num_marks); } /** @@ -517,11 +515,13 @@ namespace smt { } TRACE("conflict", tout << "processing consequent: "; m_ctx.display_literal_verbose(tout, consequent); tout << "\n"; - tout << "num_marks: " << num_marks << ", js kind: " << js.get_kind() << "\n";); + tout << "num_marks: " << num_marks << ", js kind: " << js.get_kind() << " level: " << m_ctx.get_assign_level(consequent) << "\n"; + ); SASSERT(js != null_b_justification); switch (js.get_kind()) { case b_justification::CLAUSE: { clause * cls = js.get_clause(); + TRACE("conflict", m_ctx.display_clause_detail(tout, cls);); if (cls->is_lemma()) cls->inc_clause_activity(); unsigned num_lits = cls->get_num_literals(); @@ -566,7 +566,7 @@ namespace smt { if (m_ctx.is_marked(l.var())) break; CTRACE("conflict", m_ctx.get_assign_level(l) != m_conflict_lvl && m_ctx.get_assign_level(l) != m_ctx.get_base_level(), - tout << "assign_level(l): " << m_ctx.get_assign_level(l) << ", conflict_lvl: " << m_conflict_lvl << ", l: "; m_ctx.display_literal(tout, l); + tout << "assign_level(l): " << m_ctx.get_assign_level(l) << ", conflict_lvl: " << m_conflict_lvl << ", l: "; m_ctx.display_literal_verbose(tout, l); tout << "\n";); SASSERT(m_ctx.get_assign_level(l) == m_conflict_lvl || // it may also be an (out-of-order) asserted literal From 394d54fa8be9c89c8c35e647ab092bce2a809000 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 09:54:01 -0700 Subject: [PATCH 251/488] fix missin clause generation for ad-hoc handling of conjunction #1245 --- src/sat/tactic/goal2sat.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sat/tactic/goal2sat.cpp b/src/sat/tactic/goal2sat.cpp index 0b6ad2c82..1f9dd91d1 100644 --- a/src/sat/tactic/goal2sat.cpp +++ b/src/sat/tactic/goal2sat.cpp @@ -248,6 +248,7 @@ struct goal2sat::imp { for (unsigned i = 0; i < num; ++i) { m_result_stack[i].neg(); } + mk_clause(m_result_stack.size(), m_result_stack.c_ptr()); } else { for (unsigned i = 0; i < num; ++i) { @@ -278,6 +279,7 @@ struct goal2sat::imp { if (sign) l.neg(); m_result_stack.push_back(l); + TRACE("goal2sat", tout << m_result_stack << "\n";); } } From 06087c17be591ce889927d07397e334e07ce8d79 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 10:28:11 -0700 Subject: [PATCH 252/488] support for legacy datatype test Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin.h | 2 +- src/ast/datatype_decl_plugin2.cpp | 60 +++++++++++++++----------- src/ast/datatype_decl_plugin2.h | 21 ++++++--- src/ast/rewriter/datatype_rewriter.cpp | 1 + src/ast/rewriter/poly_rewriter_def.h | 4 -- src/ast/static_features.cpp | 13 +++--- src/cmd_context/basic_cmds.cpp | 42 ++++++++---------- src/cmd_context/cmd_context.cpp | 38 ++++++---------- src/cmd_context/pdecl.cpp | 2 +- src/cmd_context/tactic_cmds.cpp | 6 +-- src/smt/theory_dense_diff_logic_def.h | 5 ++- src/test/get_consequences.cpp | 4 +- 12 files changed, 100 insertions(+), 98 deletions(-) diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index 3b4c8dd08..840329dda 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -16,7 +16,7 @@ Author: Revision History: --*/ -// define DATATYPE_V2 +#define DATATYPE_V2 #ifdef DATATYPE_V2 #include "ast/datatype_decl_plugin2.h" #else diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 41ae2e839..fa3c73bca 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -236,7 +236,7 @@ namespace datatype { return m.mk_func_decl(symbol("update-field"), arity, domain, range, info); } -#define VALIDATE_PARAM(_pred_) if (!(_pred_)) m_manager->raise_exception("invalid parameter to datatype function"); +#define VALIDATE_PARAM(_pred_) if (!(_pred_)) m_manager->raise_exception("invalid parameter to datatype function " #_pred_); func_decl * decl::plugin::mk_constructor(unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { @@ -252,13 +252,26 @@ namespace datatype { func_decl * decl::plugin::mk_recognizer(unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort *) { ast_manager& m = *m_manager; - VALIDATE_PARAM(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + VALIDATE_PARAM(arity == 1 && num_parameters == 2 && parameters[1].is_symbol() && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); VALIDATE_PARAM(u().is_datatype(domain[0])); // blindly trust that parameter is a constructor sort* range = m_manager->mk_bool_sort(); func_decl* f = to_func_decl(parameters[0].get_ast()); func_decl_info info(m_family_id, OP_DT_RECOGNISER, num_parameters, parameters); info.m_private_parameters = true; + return m.mk_func_decl(symbol(parameters[1].get_symbol()), arity, domain, range, info); + } + + func_decl * decl::plugin::mk_is(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort *) { + ast_manager& m = *m_manager; + VALIDATE_PARAM(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + VALIDATE_PARAM(u().is_datatype(domain[0])); + // blindly trust that parameter is a constructor + sort* range = m_manager->mk_bool_sort(); + func_decl* f = to_func_decl(parameters[0].get_ast()); + func_decl_info info(m_family_id, OP_DT_IS, num_parameters, parameters); + info.m_private_parameters = true; return m.mk_func_decl(symbol("is"), arity, domain, range, info); } @@ -282,6 +295,8 @@ namespace datatype { return mk_constructor(num_parameters, parameters, arity, domain, range); case OP_DT_RECOGNISER: return mk_recognizer(num_parameters, parameters, arity, domain, range); + case OP_DT_IS: + return mk_is(num_parameters, parameters, arity, domain, range); case OP_DT_ACCESSOR: return mk_accessor(num_parameters, parameters, arity, domain, range); case OP_DT_UPDATE_FIELD: @@ -297,20 +312,6 @@ namespace datatype { return alloc(def, m, u(), name, m_class_id, n, params); } -#if 0 - def& plugin::add(symbol const& name, unsigned n, sort * const * params) { - ast_manager& m = *m_manager; - def* d = 0; - if (m_defs.find(name, d)) { - TRACE("datatype", tout << "delete previous version for " << name << "\n";); - dealloc(d); - } - d = alloc(def, m, u(), name, m_class_id, n, params); - m_defs.insert(name, d); - m_def_block.push_back(name); - return *d; - } -#endif void plugin::end_def_block() { ast_manager& m = *m_manager; @@ -407,7 +408,7 @@ namespace datatype { } void plugin::get_op_names(svector & op_names, symbol const & logic) { - op_names.push_back(builtin_name("is", OP_DT_RECOGNISER)); + op_names.push_back(builtin_name("is", OP_DT_IS)); if (logic == symbol::null) { op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD)); } @@ -739,18 +740,25 @@ namespace datatype { return res; } - func_decl * util::get_constructor_recognizer(func_decl * constructor) { - SASSERT(is_constructor(constructor)); + func_decl * util::get_constructor_recognizer(func_decl * con) { + SASSERT(is_constructor(con)); func_decl * d = 0; - if (m_constructor2recognizer.find(constructor, d)) + if (m_constructor2recognizer.find(con, d)) return d; - sort * datatype = constructor->get_range(); - parameter ps[1] = { parameter(constructor) }; - d = m.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 1, ps, 1, &datatype); + sort * datatype = con->get_range(); + def const& dd = get_def(datatype); + symbol r; + for (constructor const* c : dd) { + if (c->name() == con->get_name()) { + r = c->recognizer(); + } + } + parameter ps[2] = { parameter(con), parameter(r) }; + d = m.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 2, ps, 1, &datatype); SASSERT(d); - m_asts.push_back(constructor); + m_asts.push_back(con); m_asts.push_back(d); - m_constructor2recognizer.insert(constructor, d); + m_constructor2recognizer.insert(con, d); return d; } @@ -917,11 +925,11 @@ namespace datatype { UNREACHABLE(); return 0; } + unsigned util::get_recognizer_constructor_idx(func_decl * f) const { return get_constructor_idx(get_recognizer_constructor(f)); } - /** \brief Two datatype sorts s1 and s2 are siblings if they were defined together in the same mutually recursive definition. diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index d7173b24a..f076bb43f 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -36,7 +36,8 @@ Revision History: enum op_kind { OP_DT_CONSTRUCTOR, OP_DT_RECOGNISER, - OP_DT_ACCESSOR, + OP_DT_IS, + OP_DT_ACCESSOR, OP_DT_UPDATE_FIELD, LAST_DT_OP }; @@ -78,13 +79,15 @@ namespace datatype { class constructor { symbol m_name; + symbol m_recognizer; ptr_vector m_accessors; def* m_def; public: - constructor(symbol n): m_name(n) {} + constructor(symbol n, symbol const& r): m_name(n), m_recognizer(r) {} ~constructor(); void add(accessor* a) { m_accessors.push_back(a); a->attach(this); } symbol const& name() const { return m_name; } + symbol const& recognizer() const { return m_recognizer; } ptr_vector const& accessors() const { return m_accessors; } ptr_vector::const_iterator begin() const { return m_accessors.begin(); } ptr_vector::const_iterator end() const { return m_accessors.end(); } @@ -290,6 +293,10 @@ namespace datatype { unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); + func_decl * mk_is( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + symbol datatype_name(sort * s) const { //SASSERT(u().is_datatype(s)); return s->get_parameter(0).get_symbol(); @@ -340,11 +347,15 @@ namespace datatype { bool is_enum_sort(sort* s); bool is_recursive(sort * ty); bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_recognizer(func_decl * f) const { return is_recognizer0(f) || is_is(f); } + bool is_recognizer0(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_is(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_IS); } bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); } bool is_update_field(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_UPDATE_FIELD); } bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_recognizer0(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER);} + bool is_is(app * f) const { return is_app_of(f, m_family_id, OP_DT_IS);} + bool is_recognizer(app * f) const { return is_recognizer0(f) || is_is(f); } bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } ptr_vector const * get_datatype_constructors(sort * ty); @@ -401,7 +412,7 @@ inline accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_r } inline constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * * acs) { - constructor_decl* c = alloc(constructor_decl, n); + constructor_decl* c = alloc(constructor_decl, n, r); for (unsigned i = 0; i < num_accessors; ++i) { c->add(acs[i]); } diff --git a/src/ast/rewriter/datatype_rewriter.cpp b/src/ast/rewriter/datatype_rewriter.cpp index 9efa61f70..f0a95929b 100644 --- a/src/ast/rewriter/datatype_rewriter.cpp +++ b/src/ast/rewriter/datatype_rewriter.cpp @@ -23,6 +23,7 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr switch(f->get_decl_kind()) { case OP_DT_CONSTRUCTOR: return BR_FAILED; case OP_DT_RECOGNISER: + case OP_DT_IS: // // simplify is_cons(cons(x,y)) -> true // simplify is_cons(nil) -> false diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index b52440393..39c4a1078 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -753,18 +753,14 @@ br_status poly_rewriter::cancel_monomials(expr * lhs, expr * rhs, bool m normalize(c); - TRACE("mk_le_bug", tout << c << "\n";); - if (!has_multiple && num_coeffs <= 1) { if (move) { if (is_numeral(rhs)) { - TRACE("mk_le_bug", tout << "rhs is numeral\n";); return BR_FAILED; } } else { if (num_coeffs == 0 || is_numeral(rhs)) { - TRACE("mk_le_bug", tout << "rhs is numeral or no coeffs\n";); return BR_FAILED; } } diff --git a/src/ast/static_features.cpp b/src/ast/static_features.cpp index 3c8333d02..3db4d02a2 100644 --- a/src/ast/static_features.cpp +++ b/src/ast/static_features.cpp @@ -145,18 +145,19 @@ bool static_features::is_diff_atom(expr const * e) const { return true; if (!is_numeral(rhs)) return false; - // lhs can be 'x' or '(+ x (* -1 y))' + // lhs can be 'x' or '(+ x (* -1 y))' or '(+ (* -1 x) y)' if (!is_arith_expr(lhs)) return true; expr* arg1, *arg2; if (!m_autil.is_add(lhs, arg1, arg2)) return false; - // x - if (is_arith_expr(arg1)) - return false; - // arg2: (* -1 y) expr* m1, *m2; - return m_autil.is_mul(arg2, m1, m2) && is_minus_one(m1) && !is_arith_expr(m2); + if (!is_arith_expr(arg1) && m_autil.is_mul(arg2, m1, m2) && is_minus_one(m1) && !is_arith_expr(m2)) + return true; + if (!is_arith_expr(arg2) && m_autil.is_mul(arg1, m1, m2) && is_minus_one(m1) && !is_arith_expr(m2)) + return true; + return false; + } bool static_features::is_gate(expr const * e) const { diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index c81170ba4..21b66febd 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -15,21 +15,21 @@ Author: Notes: --*/ -#include "cmd_context/cmd_context.h" +#include "util/gparams.h" +#include "util/env_params.h" #include "util/version.h" #include "ast/ast_smt_pp.h" #include "ast/ast_smt2_pp.h" #include "ast/ast_pp.h" -#include "model/model_smt2_pp.h" #include "ast/array_decl_plugin.h" #include "ast/pp.h" +#include "ast/well_sorted.h" +#include "ast/pp_params.hpp" +#include "model/model_smt2_pp.h" +#include "cmd_context/cmd_context.h" #include "cmd_context/cmd_util.h" #include "cmd_context/simplify_cmd.h" #include "cmd_context/eval_cmd.h" -#include "util/gparams.h" -#include "util/env_params.h" -#include "ast/well_sorted.h" -#include "ast/pp_params.hpp" class help_cmd : public cmd { svector m_cmds; @@ -79,19 +79,15 @@ public: } // named_cmd_lt is not a total order for commands, but this is irrelevant for Linux x Windows behavior std::sort(cmds.begin(), cmds.end(), named_cmd_lt()); - vector::const_iterator it2 = cmds.begin(); - vector::const_iterator end2 = cmds.end(); - for (; it2 != end2; ++it2) { - display_cmd(ctx, it2->first, it2->second); + for (named_cmd const& nc : cmds) { + display_cmd(ctx, nc.first, nc.second); } } else { - svector::const_iterator it = m_cmds.begin(); - svector::const_iterator end = m_cmds.end(); - for (; it != end; ++it) { - cmd * c = ctx.find_cmd(*it); + for (symbol const& s : m_cmds) { + cmd * c = ctx.find_cmd(s); SASSERT(c); - display_cmd(ctx, *it, c); + display_cmd(ctx, s, c); } } ctx.regular_stream() << "\"\n"; @@ -136,11 +132,10 @@ ATOMIC_CMD(get_assignment_cmd, "get-assignment", "retrieve assignment", { ctx.get_check_sat_result()->get_model(m); ctx.regular_stream() << "("; dictionary const & macros = ctx.get_macros(); - dictionary::iterator it = macros.begin(); - dictionary::iterator end = macros.end(); - for (bool first = true; it != end; ++it) { - symbol const & name = (*it).m_key; - macro_decls const & _m = (*it).m_value; + bool first = true; + for (auto const& kv : macros) { + symbol const & name = kv.m_key; + macro_decls const & _m = kv.m_value; for (auto md : _m) { if (md.m_domain.size() == 0 && ctx.m().is_bool(md.m_body)) { expr_ref val(ctx.m()); @@ -211,14 +206,13 @@ static void print_core(cmd_context& ctx) { ptr_vector core; ctx.get_check_sat_result()->get_unsat_core(core); ctx.regular_stream() << "("; - ptr_vector::const_iterator it = core.begin(); - ptr_vector::const_iterator end = core.end(); - for (bool first = true; it != end; ++it) { + bool first = true; + for (expr* e : core) { if (first) first = false; else ctx.regular_stream() << " "; - ctx.regular_stream() << mk_ismt2_pp(*it, ctx.m()); + ctx.regular_stream() << mk_ismt2_pp(e, ctx.m()); } ctx.regular_stream() << ")" << std::endl; } diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index e93e51186..c0e1c9f9c 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -18,7 +18,10 @@ Notes: #include #include "util/tptr.h" -#include "cmd_context/cmd_context.h" +#include "util/cancel_eh.h" +#include "util/scoped_ctrl_c.h" +#include "util/dec_ref_util.h" +#include "util/scoped_timer.h" #include "ast/func_decl_dependencies.h" #include "ast/arith_decl_plugin.h" #include "ast/bv_decl_plugin.h" @@ -31,22 +34,19 @@ Notes: #include "ast/rewriter/var_subst.h" #include "ast/pp.h" #include "ast/ast_smt2_pp.h" -#include "cmd_context/basic_cmds.h" -#include "util/cancel_eh.h" -#include "util/scoped_ctrl_c.h" -#include "util/dec_ref_util.h" #include "ast/decl_collector.h" #include "ast/well_sorted.h" -#include "model/model_evaluator.h" #include "ast/for_each_expr.h" -#include "util/scoped_timer.h" -#include "cmd_context/interpolant_cmds.h" +#include "ast/rewriter/th_rewriter.h" +#include "model/model_evaluator.h" #include "model/model_smt2_pp.h" #include "model/model_v2_pp.h" #include "model/model_params.hpp" -#include "ast/rewriter/th_rewriter.h" #include "tactic/tactic_exception.h" #include "solver/smt_logics.h" +#include "cmd_context/basic_cmds.h" +#include "cmd_context/interpolant_cmds.h" +#include "cmd_context/cmd_context.h" func_decls::func_decls(ast_manager & m, func_decl * f): m_decls(TAG(func_decl*, f, 0)) { @@ -61,11 +61,9 @@ void func_decls::finalize(ast_manager & m) { else { TRACE("func_decls", tout << "finalize...\n";); func_decl_set * fs = UNTAG(func_decl_set *, m_decls); - func_decl_set::iterator it = fs->begin(); - func_decl_set::iterator end = fs->end(); - for (; it != end; ++it) { - TRACE("func_decls", tout << "dec_ref of " << (*it)->get_name() << " ref_count: " << (*it)->get_ref_count() << "\n";); - m.dec_ref(*it); + for (func_decl * f : *fs) { + TRACE("func_decls", tout << "dec_ref of " << f->get_name() << " ref_count: " << f->get_ref_count() << "\n";); + m.dec_ref(f); } dealloc(fs); } @@ -161,10 +159,7 @@ bool func_decls::clash(func_decl * f) const { if (GET_TAG(m_decls) == 0) return false; func_decl_set * fs = UNTAG(func_decl_set *, m_decls); - func_decl_set::iterator it = fs->begin(); - func_decl_set::iterator end = fs->end(); - for (; it != end; ++it) { - func_decl * g = *it; + for (func_decl * g : *fs) { if (g == f) continue; if (g->get_arity() != f->get_arity()) @@ -201,10 +196,7 @@ func_decl * func_decls::find(unsigned arity, sort * const * domain, sort * range if (!more_than_one()) return first(); func_decl_set * fs = UNTAG(func_decl_set *, m_decls); - func_decl_set::iterator it = fs->begin(); - func_decl_set::iterator end = fs->end(); - for (; it != end; it++) { - func_decl * f = *it; + for (func_decl * f : *fs) { if (range != 0 && f->get_range() != range) continue; if (f->get_arity() != arity) @@ -1957,11 +1949,9 @@ void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) { for (func_decl * c : *m_dt_util.get_datatype_constructors(dt)) { TRACE("new_dt_eh", tout << "new constructor: " << c->get_name() << "\n";); m_owner.insert(c); -#ifndef DATATYPE_V2 func_decl * r = m_dt_util.get_constructor_recognizer(c); m_owner.insert(r); TRACE("new_dt_eh", tout << "new recognizer: " << r->get_name() << "\n";); -#endif for (func_decl * a : *m_dt_util.get_constructor_accessors(c)) { TRACE("new_dt_eh", tout << "new accessor: " << a->get_name() << "\n";); m_owner.insert(a); diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 4417061ec..9d6c5065e 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -267,8 +267,8 @@ public: psort_decl::psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n): pdecl(id, num_params), - m_psort_kind(PSORT_BASE), m_name(n), + m_psort_kind(PSORT_BASE), m_inst_cache(0) { } diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index b5ad0707d..3eafc6bbd 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -255,11 +255,9 @@ public: result->m_core.append(core_elems.size(), core_elems.c_ptr()); if (p.get_bool("print_unsat_core", false)) { ctx.regular_stream() << "(unsat-core"; - ptr_vector::const_iterator it = core_elems.begin(); - ptr_vector::const_iterator end = core_elems.end(); - for (; it != end; ++it) { + for (expr * e : core_elems) { ctx.regular_stream() << " "; - ctx.display(ctx.regular_stream(), *it); + ctx.display(ctx.regular_stream(), e); } ctx.regular_stream() << ")" << std::endl; } diff --git a/src/smt/theory_dense_diff_logic_def.h b/src/smt/theory_dense_diff_logic_def.h index 342766c04..ad7727a89 100644 --- a/src/smt/theory_dense_diff_logic_def.h +++ b/src/smt/theory_dense_diff_logic_def.h @@ -127,7 +127,7 @@ namespace smt { if (!m_non_diff_logic_exprs) { TRACE("non_diff_logic", tout << "found non diff logic expression:\n" << mk_pp(n, get_manager()) << "\n";); get_context().push_trail(value_trail(m_non_diff_logic_exprs)); - IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, get_manager()) << ")\n";); + IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, get_manager()) << ")\n";); m_non_diff_logic_exprs = true; } } @@ -154,6 +154,9 @@ namespace smt { if (m_autil.is_add(lhs) && to_app(lhs)->get_num_args() == 2 && is_times_minus_one(to_app(lhs)->get_arg(1), s)) { t = to_app(to_app(lhs)->get_arg(0)); } + else if (m_autil.is_add(lhs) && to_app(lhs)->get_num_args() == 2 && is_times_minus_one(to_app(lhs)->get_arg(0), s)) { + t = to_app(to_app(lhs)->get_arg(1)); + } else if (m_autil.is_mul(lhs) && to_app(lhs)->get_num_args() == 2 && m_autil.is_minus_one(to_app(lhs)->get_arg(0))) { s = to_app(to_app(lhs)->get_arg(1)); t = mk_zero_for(s); diff --git a/src/test/get_consequences.cpp b/src/test/get_consequences.cpp index 229cbe834..b9a54245e 100644 --- a/src/test/get_consequences.cpp +++ b/src/test/get_consequences.cpp @@ -65,12 +65,12 @@ void test2() { constructor_decl* G = mk_constructor_decl(symbol("G"), symbol("is-G"), 0, 0); constructor_decl* B = mk_constructor_decl(symbol("B"), symbol("is-B"), 0, 0); constructor_decl* constrs[3] = { R, G, B }; - datatype_decl * enum_sort = mk_datatype_decl(dtutil, symbol("RGB"), 3, constrs); + datatype_decl * enum_sort = mk_datatype_decl(dtutil, symbol("RGB"), 0, nullptr, 3, constrs); VERIFY(dt.mk_datatypes(1, &enum_sort, 0, 0, new_sorts)); sort* rgb = new_sorts[0].get(); expr_ref x = mk_const(m, "x", rgb), y = mk_const(m, "y", rgb), z = mk_const(m, "z", rgb); - ptr_vector const& enums = dtutil.get_datatype_constructors(rgb); + ptr_vector const& enums = *dtutil.get_datatype_constructors(rgb); expr_ref r = expr_ref(m.mk_const(enums[0]), m); expr_ref g = expr_ref(m.mk_const(enums[1]), m); expr_ref b = expr_ref(m.mk_const(enums[2]), m); From a7ef33c136c003d0ba0e44ec4553982e2384656b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 11:31:50 -0700 Subject: [PATCH 253/488] fix bug in generation of non-recursive constructor, modular starting point shifts during recursive calls Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index b4f30767f..f86668ea8 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -857,9 +857,9 @@ func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vector const * constructors = get_datatype_constructors(ty); // step 1) unsigned sz = constructors->size(); - ++m_start; + unsigned start = ++m_start; for (unsigned j = 0; j < sz; ++j) { - func_decl * c = (*constructors)[(j + m_start) % sz]; + func_decl * c = (*constructors)[(j + start) % sz]; unsigned num_args = c->get_arity(); unsigned i = 0; for (; i < num_args; i++) { @@ -872,7 +872,7 @@ func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vectorget_name() << "\n";); unsigned num_args = c->get_arity(); unsigned i = 0; From 1f551f19f5ca16761d664b58d507d7776a7efaa1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 16:37:07 -0700 Subject: [PATCH 254/488] remove extra token Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index f076bb43f..d9bfea4a5 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -429,4 +429,4 @@ inline void del_datatype_decls(unsigned num, datatype_decl * const * ds) {} #endif /* DATATYPE_DECL_PLUGIN_H_ */ -#endif DATATYPE_V2 +#endif /* DATATYPE_V2 */ From c708691a506bef18db13e1963b69fccbc420387d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 17:24:29 -0700 Subject: [PATCH 255/488] merge Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.cpp | 9 +++++++++ src/ast/datatype_decl_plugin2.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index bd7b41a88..a7d41dcbd 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -78,6 +78,7 @@ namespace datatype { sort_ref def::instantiate(sort_ref_vector const& sorts) const { sort_ref s(m); + TRACE("datatype", tout << "instantiate " << m_name << "\n";); if (!m_sort) { vector ps; ps.push_back(parameter(m_name)); @@ -315,6 +316,7 @@ namespace datatype { void plugin::end_def_block() { ast_manager& m = *m_manager; + sort_ref_vector sorts(m); for (symbol const& s : m_def_block) { def const& d = *m_defs[s]; @@ -332,7 +334,12 @@ namespace datatype { if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) { m_manager->raise_exception("datatype is not well-founded"); } + u().compute_datatype_size_functions(m_def_block); + for (symbol const& s : m_def_block) { + sort_ref_vector ps(m); + m_defs[s]->instantiate(ps); + } } bool plugin::mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts) { @@ -579,6 +586,8 @@ namespace datatype { status st; while (!todo.empty()) { symbol s = todo.back(); + TRACE("datatype", tout << "Sort size for " << s << "\n";); + if (already_found.find(s, st) && st == BLACK) { todo.pop_back(); continue; diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index d9bfea4a5..a5db0dbc6 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -227,7 +227,7 @@ namespace datatype { sort_ref_vector const& params() const { return m_params; } util& u() const { return m_util; } param_size::size* sort_size() { return m_sort_size; } - void set_sort_size(param_size::size* p) { m_sort_size = p; p->inc_ref(); } + void set_sort_size(param_size::size* p) { m_sort_size = p; p->inc_ref(); m_sort = 0; } }; namespace decl { From dabf88b95d9178ffcb7d88b9e04eec700fca7d02 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 17:40:22 -0700 Subject: [PATCH 256/488] rename del to remove to avoid compiler error Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.cpp | 2 +- src/ast/datatype_decl_plugin2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index a7d41dcbd..74750d2ca 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -361,7 +361,7 @@ namespace datatype { return true; } - void plugin::del(symbol const& s) { + void plugin::remove(symbol const& s) { def* d = 0; if (m_defs.find(s, d)) dealloc(d); m_defs.remove(s); diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index a5db0dbc6..3ea2ad1da 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -267,7 +267,7 @@ namespace datatype { def* mk(symbol const& name, unsigned n, sort * const * params); - void del(symbol const& d); + void remove(symbol const& d); bool mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts); From 9f5bd2feda960dbdd10977026478f3fcae792eb9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 19:58:05 -0700 Subject: [PATCH 257/488] fix front-end for datatype Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/arith_rewriter.cpp | 2 +- src/cmd_context/pdecl.cpp | 8 ++++---- src/parsers/smt2/smt2parser.cpp | 12 +++--------- src/test/get_consequences.cpp | 2 +- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 275290665..631e1d8f3 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -455,7 +455,7 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin st = BR_DONE; } } - if (m_arith_lhs && is_numeral(arg2, a2) && is_neg_poly(arg1, new_arg1)) { + if ((m_arith_lhs || m_arith_ineq_lhs) && is_numeral(arg2, a2) && is_neg_poly(arg1, new_arg1)) { a2.neg(); new_arg2 = m_util.mk_numeral(a2, m_util.is_int(new_arg1)); switch (kind) { diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 9d6c5065e..1887d677d 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -660,6 +660,7 @@ void pdatatype_decl::display(std::ostream & out) const { #ifdef DATATYPE_V2 bool pdatatype_decl::commit(pdecl_manager& m) { + TRACE("datatype", tout << m_name << "\n";); sort_ref_vector ps(m.m()); for (unsigned i = 0; i < m_num_params; ++i) { ps.push_back(m.m().mk_uninterpreted_sort(symbol(i), 0, 0)); @@ -669,10 +670,8 @@ bool pdatatype_decl::commit(pdecl_manager& m) { datatype_decl * d_ptr = dts.m_buffer[0]; sort_ref_vector sorts(m.m()); bool is_ok = m.get_dt_plugin()->mk_datatypes(1, &d_ptr, m_num_params, ps.c_ptr(), sorts); - if (is_ok) { - if (m_num_params == 0) { - m.notify_new_dt(sorts.get(0), this); - } + if (is_ok && m_num_params == 0) { + m.notify_new_dt(sorts.get(0), this); } return is_ok; } @@ -917,6 +916,7 @@ pconstructor_decl * pdecl_manager::mk_pconstructor_decl(unsigned num_params, } pdatatype_decl * pdecl_manager::mk_pdatatype_decl(unsigned num_params, symbol const & s, unsigned num, pconstructor_decl * const * cs) { + TRACE("datatype", tout << s << " has " << num_params << " parameters\n";); return new (a().allocate(sizeof(pdatatype_decl))) pdatatype_decl(m_id_gen.mk(), num_params, *this, s, num, cs); } diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 9526429cb..8144ebc08 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -619,14 +619,7 @@ namespace smt2 { psort_decl * d = m_ctx.find_psort_decl(id); int idx = 0; if (d == 0) { - if (m_dt_name2idx.find(id, idx)) { - throw parser_exception("smtlib 2.6 parametric datatype sorts are not supported"); - // unsigned num_params = m_dt_name2arity.find(id); - // d = pm().mk_psort_dt_decl(num_params, id); - } - else { - unknown_sort(id); - } + unknown_sort(id); } next(); void * mem = m_stack.allocate(sizeof(psort_frame)); @@ -924,10 +917,11 @@ namespace smt2 { pdatatype_decl * d = new_dt_decls[i]; symbol duplicated; check_duplicate(d, line, pos); + m_ctx.insert(d); } #endif TRACE("declare_datatypes", tout << "i: " << i << " new_dt_decls.size(): " << sz << "\n"; - for (unsigned i = 0; i < sz; i++) tout << new_dt_decls[i]->get_name() << "\n";); + for (unsigned j = 0; j < new_dt_decls.size(); ++j) tout << new_dt_decls[j]->get_name() << "\n";); m_ctx.print_success(); next(); } diff --git a/src/test/get_consequences.cpp b/src/test/get_consequences.cpp index b9a54245e..6d600f594 100644 --- a/src/test/get_consequences.cpp +++ b/src/test/get_consequences.cpp @@ -66,7 +66,7 @@ void test2() { constructor_decl* B = mk_constructor_decl(symbol("B"), symbol("is-B"), 0, 0); constructor_decl* constrs[3] = { R, G, B }; datatype_decl * enum_sort = mk_datatype_decl(dtutil, symbol("RGB"), 0, nullptr, 3, constrs); - VERIFY(dt.mk_datatypes(1, &enum_sort, 0, 0, new_sorts)); + VERIFY(dt.mk_datatypes(1, &enum_sort, 0, nullptr, new_sorts)); sort* rgb = new_sorts[0].get(); expr_ref x = mk_const(m, "x", rgb), y = mk_const(m, "y", rgb), z = mk_const(m, "z", rgb); From d05d3bac4f8e57fc9168af1a80d93221cfad9bfa Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 5 Sep 2017 20:12:48 -0700 Subject: [PATCH 258/488] fix instantiations Signed-off-by: Nikolaj Bjorner --- src/cmd_context/pdecl.cpp | 26 ++++++++++++++++++++++++-- src/parsers/smt2/smt2parser.cpp | 5 ++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 1887d677d..2293072a2 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -604,8 +604,30 @@ struct datatype_decl_buffer { #ifdef DATATYPE_V2 sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { - UNREACHABLE(); - return 0; + // TBD: copied + SASSERT(n == m_num_params); + sort * r = find(s); + if (r) + return r; + buffer ps; + ps.push_back(parameter(m_name)); + for (unsigned i = 0; i < n; i++) + ps.push_back(parameter(s[i])); + datatype_util util(m.m()); + r = m.m().mk_sort(util.get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); + cache(m, s, r); + m.save_info(r, this, n, s); + if (m_num_params > 0 && util.is_declared(r)) { + bool has_typevar = false; + // crude check .. + for (unsigned i = 0; !has_typevar && i < n; ++i) { + has_typevar = s[i]->get_name().is_numerical(); + } + if (!has_typevar) { + m.notify_new_dt(r, this); + } + } + return r; } #else sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 8144ebc08..7bfc8bd99 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -917,7 +917,10 @@ namespace smt2 { pdatatype_decl * d = new_dt_decls[i]; symbol duplicated; check_duplicate(d, line, pos); - m_ctx.insert(d); + if (!is_smt2_6) { + // datatypes are inserted up front in SMT2.6 mode, so no need to re-insert them. + m_ctx.insert(d); + } } #endif TRACE("declare_datatypes", tout << "i: " << i << " new_dt_decls.size(): " << sz << "\n"; From fe02a5f87be30c3dda5c1c1dcf879081ff68602f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 6 Sep 2017 02:16:00 -0700 Subject: [PATCH 259/488] fix parse/print of ADTs Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt_pp.cpp | 369 ++++++++++-------------------- src/ast/datatype_decl_plugin2.cpp | 33 ++- src/ast/datatype_decl_plugin2.h | 1 + src/smt/asserted_formulas.cpp | 3 +- 4 files changed, 153 insertions(+), 253 deletions(-) diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index fdac6c7be..1c3b4aeb2 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -174,7 +174,6 @@ class smt_printer { symbol m_logic; symbol m_AUFLIRA; bool m_no_lets; - bool m_is_smt2; bool m_simplify_implies; expr* m_top; @@ -199,12 +198,7 @@ class smt_printer { } void pp_id(expr* n) { - if (m_is_smt2) { - m_out << (is_bool(n)?"$x":(is_proof(n)?"@x":"?x")) << n->get_id(); - } - else { - m_out << (is_bool(n)?"$x":"?x") << n->get_id(); - } + m_out << (is_bool(n)?"$x":(is_proof(n)?"@x":"?x")) << n->get_id(); } void pp_decl(func_decl* d) { @@ -225,23 +219,15 @@ class smt_printer { #endif } else if (m_manager.is_ite(d)) { - if (!m_is_smt2 && is_bool(d->get_range())) { - m_out << "if_then_else"; - } - else { - m_out << "ite"; - } + m_out << "ite"; } - else if (!m_is_smt2 && m_manager.is_implies(d)) { - m_out << "implies"; - } - else if (m_is_smt2 && m_manager.is_iff(d)) { + else if (m_manager.is_iff(d)) { m_out << "="; } - else if (m_is_smt2 && m_manager.is_implies(d)) { + else if (m_manager.is_implies(d)) { m_out << "=>"; } - else if (m_is_smt2 && is_decl_of(d, m_arith_fid, OP_UMINUS)) { + else if (is_decl_of(d, m_arith_fid, OP_UMINUS)) { m_out << "-"; } else { @@ -263,28 +249,23 @@ class smt_printer { return; } - if (m_is_smt2) { - if (is_sort_symbol && sym == symbol("String")) { - m_out << "String"; - return; - } - if (is_sort_symbol && - sym != symbol("BitVec") && - sym != symbol("FloatingPoint") && - sym != symbol("RoundingMode")) { - m_out << "(" << sym << " "; - } - else if (!is_sort_symbol && is_sort_param(num_params, params)) { - m_out << "(as " << sym << " "; - } - else { - m_out << "(_ " << sym << " "; - } + if (is_sort_symbol && sym == symbol("String")) { + m_out << "String"; + return; + } + if (is_sort_symbol && + sym != symbol("BitVec") && + sym != symbol("FloatingPoint") && + sym != symbol("RoundingMode")) { + m_out << "(" << sym << " "; + } + else if (!is_sort_symbol && is_sort_param(num_params, params)) { + m_out << "(as " << sym << " "; } else { - m_out << sym << "["; + m_out << "(_ " << sym << " "; } - + for (unsigned i = 0; i < num_params; ++i) { parameter const& p = params[i]; if (p.is_ast()) { @@ -305,20 +286,10 @@ class smt_printer { m_out << p; } if (i + 1 < num_params) { - if (m_is_smt2) { - m_out << " "; - } - else { - m_out << ": "; - } + m_out << " "; } } - if (m_is_smt2) { - m_out << ")"; - } - else { - m_out << "]"; - } + m_out << ")"; } bool is_auflira() const { @@ -327,9 +298,7 @@ class smt_printer { void visit_sort(sort* s, bool bool2int = false) { symbol sym; - if (bool2int && is_bool(s) && !m_is_smt2) { - sym = symbol("Int"); - } else if (s->is_sort_of(m_bv_fid, BV_SORT)) { + if (s->is_sort_of(m_bv_fid, BV_SORT)) { sym = symbol("BitVec"); } else if (s->is_sort_of(m_arith_fid, REAL_SORT)) { @@ -341,42 +310,9 @@ class smt_printer { else if (s->is_sort_of(m_arith_fid, INT_SORT)) { sym = s->get_name(); } - else if (s->is_sort_of(m_array_fid, ARRAY_SORT) && m_is_smt2) { + else if (s->is_sort_of(m_array_fid, ARRAY_SORT)) { sym = "Array"; } - else if (s->is_sort_of(m_array_fid, ARRAY_SORT) && !m_is_smt2) { - unsigned num_params = s->get_num_parameters(); - SASSERT(num_params >= 2); - if (is_auflira()) { - sort* rng = to_sort(s->get_parameter(1).get_ast()); - if (rng->get_family_id() == m_array_fid) { - m_out << "Array2"; - } - else { - m_out << "Array1"; - } - return; - } - sort* s1 = to_sort(s->get_parameter(0).get_ast()); - sort* s2 = to_sort(s->get_parameter(1).get_ast()); - if (num_params == 2 && - s1->is_sort_of(m_bv_fid, BV_SORT) && - s2->is_sort_of(m_bv_fid, BV_SORT)) { - m_out << "Array"; - m_out << "[" << s1->get_parameter(0).get_int(); - m_out << ":" << s2->get_parameter(0).get_int() << "]"; - return; - } - m_out << "(Array "; - for (unsigned i = 0; i < num_params; ++i) { - visit_sort(to_sort(s->get_parameter(i).get_ast())); - if (i + 1 < num_params) { - m_out << " "; - } - } - m_out << ")"; - return; - } else if (s->is_sort_of(m_dt_fid, DATATYPE_SORT)) { #ifndef DATATYPE_V2 m_out << m_renaming.get_symbol(s->get_name()); @@ -416,20 +352,7 @@ class smt_printer { void pp_arg(expr *arg, app *parent) { - if (!m_is_smt2 && is_bool(arg) && is_var(arg) && parent->get_family_id() == m_basic_fid) { - m_out << "(not (= "; - pp_marked_expr(arg); - m_out << " 0))"; - } else if (!m_is_smt2 && is_bool(arg) && !is_var(arg) && - parent->get_family_id() != m_basic_fid && - parent->get_family_id() != m_dt_fid) { - - m_out << "(ite "; - pp_marked_expr(arg); - m_out << " 1 0)"; - } else { - pp_marked_expr(arg); - } + pp_marked_expr(arg); } void visit_app(app* n) { @@ -444,12 +367,7 @@ class smt_printer { if (m_autil.is_numeral(n, val, is_int)) { if (val.is_neg()) { val.neg(); - if (m_is_smt2) { - m_out << "(- "; - } - else { - m_out << "(~ "; - } + m_out << "(- "; display_rational(val, is_int); m_out << ")"; } @@ -471,12 +389,7 @@ class smt_printer { m_out << "\""; } else if (m_bvutil.is_numeral(n, val, bv_size)) { - if (m_is_smt2) { - m_out << "(_ bv" << val << " " << bv_size << ")"; - } - else { - m_out << "bv" << val << "[" << bv_size << "]"; - } + m_out << "(_ bv" << val << " " << bv_size << ")"; } else if (m_futil.is_numeral(n, float_val)) { m_out << "((_ to_fp " << @@ -486,37 +399,17 @@ class smt_printer { } else if (m_bvutil.is_bit2bool(n)) { unsigned bit = n->get_decl()->get_parameter(0).get_int(); - if (m_is_smt2) { - m_out << "(= ((_ extract " << bit << " " << bit << ") "; - pp_marked_expr(n->get_arg(0)); - m_out << ") (_ bv1 1))"; - } - else { - m_out << "(= (extract[" << bit << ":" << bit << "] "; - pp_marked_expr(n->get_arg(0)); - m_out << ") bv1[1])"; - } + m_out << "(= ((_ extract " << bit << " " << bit << ") "; + pp_marked_expr(n->get_arg(0)); + m_out << ") (_ bv1 1))"; } else if (m_manager.is_label(n, pos, names) && names.size() >= 1) { - if (m_is_smt2) { - m_out << "(! "; - pp_marked_expr(n->get_arg(0)); - m_out << (pos?":lblpos":":lblneg") << " " << m_renaming.get_symbol(names[0]) << ")"; - } - else { - m_out << "(" << (pos?"lblpos":"lblneg") << " " << m_renaming.get_symbol(names[0]) << " "; - expr* ch = n->get_arg(0); - pp_marked_expr(ch); - m_out << ")"; - } + m_out << "(! "; + pp_marked_expr(n->get_arg(0)); + m_out << (pos?":lblpos":":lblneg") << " " << m_renaming.get_symbol(names[0]) << ")"; } else if (m_manager.is_label_lit(n, names) && names.size() >= 1) { - if (m_is_smt2) { - m_out << "(! true :lblpos " << m_renaming.get_symbol(names[0]) << ")"; - } - else { - m_out << "(lblpos " << m_renaming.get_symbol(names[0]) << " true )"; - } + m_out << "(! true :lblpos " << m_renaming.get_symbol(names[0]) << ")"; } else if (num_args == 0) { if (decl->private_parameters()) { @@ -595,14 +488,11 @@ class smt_printer { void print_no_lets(expr *e) { - smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, true, m_simplify_implies, m_is_smt2, m_indent, m_num_var_names, m_var_names); + smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, true, m_simplify_implies, true, m_indent, m_num_var_names, m_var_names); p(e); } void print_bound(symbol const& name) { - if (!m_is_smt2 && (name.is_numerical() || '?' != name.bare_str()[0])) { - m_out << "?"; - } m_out << name; } @@ -616,9 +506,7 @@ class smt_printer { else { m_out << "exists "; } - if (m_is_smt2) { - m_out << "("; - } + m_out << "("; for (unsigned i = 0; i < q->get_num_decls(); ++i) { sort* s = q->get_decl_sort(i); m_out << "("; @@ -627,15 +515,13 @@ class smt_printer { visit_sort(s, true); m_out << ") "; } - if (m_is_smt2) { - m_out << ")"; - } + m_out << ")"; - if (m_is_smt2 && (q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) { + if ((q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) { m_out << "(! "; } { - smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, false, m_is_smt2, m_simplify_implies, m_indent, m_num_var_names, m_var_names); + smt_printer p(m_out, m_manager, m_qlists, m_renaming, m_logic, false, true, m_simplify_implies, m_indent, m_num_var_names, m_var_names); p(q->get_expr()); } @@ -654,28 +540,18 @@ class smt_printer { } } - if (m_is_smt2) { - m_out << " :pattern ( "; - } - else { - m_out << " :pat { "; - } + m_out << " :pattern ( "; for (unsigned j = 0; j < pat->get_num_args(); ++j) { print_no_lets(pat->get_arg(j)); m_out << " "; } - if (m_is_smt2) { - m_out << ")"; - } - else { - m_out << "}"; - } + m_out << ")"; } if (q->get_qid() != symbol::null) m_out << " :qid " << q->get_qid(); - if (m_is_smt2 && (q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) { + if ((q->get_num_patterns() > 0 || q->get_qid() != symbol::null)) { m_out << ")"; } m_out << ")"; @@ -739,21 +615,11 @@ class smt_printer { } void visit_expr(expr* n) { - if (m_is_smt2) { - m_out << "(let (("; - } - else if (is_bool(n)) { - m_out << "(flet ("; - } - else { - m_out << "(let ("; - } + m_out << "(let (("; pp_id(n); m_out << " "; pp_expr(n); - if (m_is_smt2) { - m_out << ")"; - } + m_out << ")"; m_out << ")"; newline(); } @@ -865,7 +731,6 @@ public: m_AUFLIRA("AUFLIRA"), // It's much easier to read those testcases with that. m_no_lets(no_lets), - m_is_smt2(is_smt2), m_simplify_implies(simplify_implies) { m_basic_fid = m.get_basic_family_id(); @@ -919,8 +784,63 @@ public: } void pp_dt(ast_mark& mark, sort* s) { - SASSERT(s->is_sort_of(m_dt_fid, DATATYPE_SORT)); datatype_util util(m_manager); + SASSERT(util.is_datatype(s)); + +#ifdef DATATYPE_V2 + + sort_ref_vector ps(m_manager); + ptr_vector defs; + util.get_defs(s, defs); + + for (datatype::def* d : defs) { + sort_ref sr = d->instantiate(ps); + if (mark.is_marked(sr)) return; // already processed + mark.mark(sr, true); + } + + m_out << "(declare-datatypes ("; + bool first_def = true; + for (datatype::def* d : defs) { + if (!first_def) m_out << "\n "; else first_def = false; + m_out << "(" << d->name() << " " << d->params().size() << ")"; + } + m_out << ") ("; + bool first_sort = true; + for (datatype::def* d : defs) { + if (!first_sort) m_out << "\n "; else first_sort = false; + if (!d->params().empty()) { + m_out << "(par ("; + bool first_param = true; + for (sort* s : d->params()) { + if (!first_param) m_out << " "; else first_param = false; + visit_sort(s); + } + m_out << ")"; + } + m_out << "("; + m_out << m_renaming.get_symbol(d->name()); + m_out << " "; + bool first_constr = true; + for (datatype::constructor* f : *d) { + if (!first_constr) m_out << " "; else first_constr = false; + m_out << "("; + m_out << m_renaming.get_symbol(f->name()); + for (datatype::accessor* a : *f) { + m_out << " (" << m_renaming.get_symbol(a->name()) << " "; + visit_sort(a->range()); + m_out << ")"; + } + m_out << ")"; + } + if (!d->params().empty()) { + m_out << ")"; + } + m_out << ")"; + } + m_out << "))"; +#else + ptr_vector rec_sorts; rec_sorts.push_back(s); @@ -954,55 +874,30 @@ public: } } - if (m_is_smt2) { - // TBD: datatypes may be declared parametrically. - // get access to parametric generalization, or print - // monomorphic specialization with a tag that gets reused at use-point. - m_out << "(declare-datatypes () ("; - } - else { - m_out << ":datatypes ("; - } - for (unsigned si = 0; si < rec_sorts.size(); ++si) { - s = rec_sorts[si]; + m_out << "(declare-datatypes () ("; + bool first_sort = true; + for (sort * s : rec_sorts) { + if (!first_sort) m_out << " "; else first_sort = false; + m_out << "("; m_out << m_renaming.get_symbol(s->get_name()); m_out << " "; - ptr_vector const& decls = *util.get_datatype_constructors(s); - - for (unsigned i = 0; i < decls.size(); ++i) { - func_decl* f = decls[i]; - ptr_vector const& accs = *util.get_constructor_accessors(f); - if (m_is_smt2 || accs.size() > 0) { - m_out << "("; - } + bool first_constr = true; + for (func_decl* f : *util.get_datatype_constructors(s)) { + if (!first_constr) m_out << " "; else first_constr = false; + m_out << "("; m_out << m_renaming.get_symbol(f->get_name()); - if (!accs.empty() || !m_is_smt2) { - m_out << " "; - } - for (unsigned j = 0; j < accs.size(); ++j) { - func_decl* a = accs[j]; - m_out << "(" << m_renaming.get_symbol(a->get_name()) << " "; + for (func_decl* a : *util.get_constructor_accessors(f)) { + m_out << " (" << m_renaming.get_symbol(a->get_name()) << " "; visit_sort(a->get_range()); m_out << ")"; - if (j + 1 < accs.size()) m_out << " "; - } - if (m_is_smt2 || accs.size() > 0) { - m_out << ")"; - if (i + 1 < decls.size()) { - m_out << " "; - } } + m_out << ")"; } m_out << ")"; - if (si + 1 < rec_sorts.size()) { - m_out << " "; - } } - if (m_is_smt2) { - m_out << ")"; - } - m_out << ")"; + m_out << "))"; +#endif newline(); } @@ -1015,12 +910,7 @@ public: pp_dt(mark, s); } else { - if (m_is_smt2) { - m_out << "(declare-sort "; - } - else { - m_out << ":extrasorts ("; - } + m_out << "(declare-sort "; visit_sort(s); m_out << ")"; newline(); @@ -1034,29 +924,16 @@ public: } void operator()(func_decl* d) { - if (m_is_smt2) { - m_out << "(declare-fun "; - pp_decl(d); - m_out << "("; - for (unsigned i = 0; i < d->get_arity(); ++i) { - if (i > 0) m_out << " "; - visit_sort(d->get_domain(i), true); - } - m_out << ") "; - visit_sort(d->get_range()); - m_out << ")"; - } - else { - m_out << "("; - pp_decl(d); - for (unsigned i = 0; i < d->get_arity(); ++i) { - m_out << " "; - visit_sort(d->get_domain(i), true); - } - m_out << " "; - visit_sort(d->get_range()); - m_out << ")"; + m_out << "(declare-fun "; + pp_decl(d); + m_out << "("; + for (unsigned i = 0; i < d->get_arity(); ++i) { + if (i > 0) m_out << " "; + visit_sort(d->get_domain(i), true); } + m_out << ") "; + visit_sort(d->get_range()); + m_out << ")"; } void visit_pred(func_decl* d) { diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 74750d2ca..b53a2743f 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -965,35 +965,56 @@ namespace datatype { return d.constructors().size(); } + void util::get_defs(sort* s0, ptr_vector& defs) { + svector mark; + ptr_buffer todo; + todo.push_back(s0); + mark.push_back(s0->get_name()); + while (!todo.empty()) { + sort* s = todo.back(); + todo.pop_back(); + defs.push_back(&m_plugin->get_def(s->get_name())); + def const& d = get_def(s); + for (constructor* c : d) { + for (accessor* a : *c) { + sort* s = a->range(); + if (are_siblings(s0, s) && !mark.contains(s->get_name())) { + mark.push_back(s->get_name()); + todo.push_back(s); + } + } + } + } + } - void util::display_datatype(sort *s0, std::ostream& strm) { + void util::display_datatype(sort *s0, std::ostream& out) { ast_mark mark; ptr_buffer todo; SASSERT(is_datatype(s0)); - strm << s0->get_name() << " where\n"; + out << s0->get_name() << " where\n"; todo.push_back(s0); mark.mark(s0, true); while (!todo.empty()) { sort* s = todo.back(); todo.pop_back(); - strm << s->get_name() << " =\n"; + out << s->get_name() << " =\n"; ptr_vector const& cnstrs = *get_datatype_constructors(s); for (unsigned i = 0; i < cnstrs.size(); ++i) { func_decl* cns = cnstrs[i]; func_decl* rec = get_constructor_recognizer(cns); - strm << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; + out << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; ptr_vector const & accs = *get_constructor_accessors(cns); for (unsigned j = 0; j < accs.size(); ++j) { func_decl* acc = accs[j]; sort* s1 = acc->get_range(); - strm << "(" << acc->get_name() << ": " << s1->get_name() << ") "; + out << "(" << acc->get_name() << ": " << s1->get_name() << ") "; if (is_datatype(s1) && are_siblings(s1, s0) && !mark.is_marked(s1)) { mark.mark(s1, true); todo.push_back(s1); } } - strm << "\n"; + out << "\n"; } } } diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index 3ea2ad1da..d9a069de3 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -379,6 +379,7 @@ namespace datatype { unsigned get_constructor_idx(func_decl * f) const; unsigned get_recognizer_constructor_idx(func_decl * f) const; decl::plugin* get_plugin() { return m_plugin; } + void get_defs(sort* s, ptr_vector& defs); }; }; diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 1581e70bd..ebdda73a1 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -432,7 +432,8 @@ void asserted_formulas::propagate_values() { flush_cache(); unsigned num_prop = 0; - while (!inconsistent()) { + unsigned num_iterations = 0; + while (!inconsistent() && ++num_iterations < 2) { m_expr2depth.reset(); m_scoped_substitution.push(); unsigned prop = num_prop; From fafe15a997480e4fb7dc2ff24ec0af8b8a94669c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 6 Sep 2017 02:25:38 -0700 Subject: [PATCH 260/488] fix for #1247 Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt2_pp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index 5c3eb93c2..a38f7cd1a 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -43,6 +43,9 @@ format * smt2_pp_environment::pp_fdecl_name(symbol const & s, unsigned & len) co len = static_cast(str.length()); return mk_string(m, str.c_str()); } + else if (!s.bare_str()) { + return mk_string(m, "null"); + } else { len = static_cast(strlen(s.bare_str())); return mk_string(m, s.bare_str()); From f40a66c095b97c7b4ec607e3e1b1f8e81b277821 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 6 Sep 2017 02:26:19 -0700 Subject: [PATCH 261/488] fixes Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt2_pp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index cdc771f12..63c7de1a9 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -43,6 +43,9 @@ format * smt2_pp_environment::pp_fdecl_name(symbol const & s, unsigned & len) co len = static_cast(str.length()); return mk_string(m, str.c_str()); } + else if (!s.bare_str()) { + return mk_string(m,"null"); + } else { len = static_cast(strlen(s.bare_str())); return mk_string(m, s.bare_str()); From 7f127cdd5dfc2a21433e64e19a5e91ab344648c4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 6 Sep 2017 09:48:10 -0700 Subject: [PATCH 262/488] adding declarations for regression tests Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.cpp | 1 + src/ast/datatype_decl_plugin2.h | 2 +- src/cmd_context/pdecl.cpp | 99 +++++++++++++++++-------------- src/cmd_context/pdecl.h | 3 + src/parsers/smt2/smt2parser.cpp | 1 + 5 files changed, 62 insertions(+), 44 deletions(-) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index b53a2743f..43164a436 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -346,6 +346,7 @@ namespace datatype { begin_def_block(); for (unsigned i = 0; i < num_datatypes; ++i) { def* d = 0; + TRACE("datatype", tout << "declaring " << datatypes[i]->name() << "\n";); if (m_defs.find(datatypes[i]->name(), d)) { TRACE("datatype", tout << "delete previous version for " << datatypes[i]->name() << "\n";); dealloc(d); diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index d9a069de3..a88c7100e 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -334,7 +334,6 @@ namespace datatype { void compute_datatype_size_functions(svector const& names); param_size::size* get_sort_size(sort_ref_vector const& params, sort* s); bool is_well_founded(unsigned num_types, sort* const* sorts); - def const& get_def(sort* s) const; def& get_def(symbol const& s) { return m_plugin->get_def(s); } void get_subsorts(sort* s, ptr_vector& sorts) const; @@ -380,6 +379,7 @@ namespace datatype { unsigned get_recognizer_constructor_idx(func_decl * f) const; decl::plugin* get_plugin() { return m_plugin; } void get_defs(sort* s, ptr_vector& defs); + def const& get_def(sort* s) const; }; }; diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 2293072a2..95a6030f3 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -360,28 +360,7 @@ sort * psort_dt_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * return 0; #else SASSERT(n == m_num_params); - sort * r = find(s); - if (r) - return r; - buffer ps; - ps.push_back(parameter(m_name)); - for (unsigned i = 0; i < n; i++) - ps.push_back(parameter(s[i])); - datatype_util util(m.m()); - r = m.m().mk_sort(util.get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); - cache(m, s, r); - m.save_info(r, this, n, s); - if (m_num_params > 0 && util.is_declared(r)) { - bool has_typevar = false; - // crude check .. - for (unsigned i = 0; !has_typevar && i < n; ++i) { - has_typevar = s[i]->get_name().is_numerical(); - } - if (!has_typevar) { - m.notify_new_dt(r, this); - } - } - return r; + return m.instantiate_datatype(this, m_name, n, s); #endif } @@ -603,32 +582,39 @@ struct datatype_decl_buffer { }; #ifdef DATATYPE_V2 + sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { - // TBD: copied - SASSERT(n == m_num_params); - sort * r = find(s); - if (r) - return r; - buffer ps; - ps.push_back(parameter(m_name)); - for (unsigned i = 0; i < n; i++) - ps.push_back(parameter(s[i])); + sort * r = m.instantiate_datatype(this, m_name, n, s); datatype_util util(m.m()); - r = m.m().mk_sort(util.get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); - cache(m, s, r); - m.save_info(r, this, n, s); - if (m_num_params > 0 && util.is_declared(r)) { - bool has_typevar = false; - // crude check .. - for (unsigned i = 0; !has_typevar && i < n; ++i) { - has_typevar = s[i]->get_name().is_numerical(); - } - if (!has_typevar) { - m.notify_new_dt(r, this); + if (r && n > 0 && util.is_declared(r)) { + ast_mark mark; + datatype::def const& d = util.get_def(r); + mark.mark(r, true); + sort_ref_vector params(m.m(), n, s); + for (datatype::constructor* c : d) { + for (datatype::accessor* a : *c) { + sort* rng = a->range(); + if (util.is_datatype(rng) && !mark.is_marked(rng) && m_parent) { + mark.mark(rng, true); + // TBD: search over more than just parents + for (pdatatype_decl* p : *m_parent) { + if (p->get_name() == rng->get_name()) { + ptr_vector ps; + func_decl_ref acc = a->instantiate(params); + for (unsigned j = 0; j < util.get_datatype_num_parameter_sorts(rng); ++j) { + ps.push_back(util.get_datatype_parameter_sort(acc->get_range(), j)); + } + m.instantiate_datatype(p, p->get_name(), ps.size(), ps.c_ptr()); + break; + } + } + } + } } } return r; } + #else sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { SASSERT(m_num_params == n); @@ -729,6 +715,33 @@ bool pdatatypes_decl::fix_missing_refs(symbol & missing) { } #ifdef DATATYPE_V2 +sort* pdecl_manager::instantiate_datatype(psort_decl* p, symbol const& name, unsigned n, sort * const* s) { + TRACE("datatype", tout << name << " "; for (unsigned i = 0; i < n; ++i) tout << s[i]->get_name() << " "; tout << "\n";); + pdecl_manager& m = *this; + sort * r = p->find(s); + if (r) + return r; + buffer ps; + ps.push_back(parameter(name)); + for (unsigned i = 0; i < n; i++) + ps.push_back(parameter(s[i])); + datatype_util util(m.m()); + r = m.m().mk_sort(util.get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); + p->cache(m, s, r); + m.save_info(r, p, n, s); + if (n > 0 && util.is_declared(r)) { + bool has_typevar = false; + // crude check .. + for (unsigned i = 0; !has_typevar && i < n; ++i) { + has_typevar = s[i]->get_name().is_numerical(); + } + if (!has_typevar) { + m.notify_new_dt(r, p); + } + } + return r; +} + bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) { UNREACHABLE(); return false; @@ -887,6 +900,7 @@ void pdecl_manager::init_list() { mk_pconstructor_decl(1, symbol("insert"), symbol("is-insert"), 2, as) }; m_list = mk_pdatatype_decl(1, symbol("List"), 2, cs); inc_ref(m_list); + m_list->commit(*this); } pdecl_manager::pdecl_manager(ast_manager & m): @@ -966,7 +980,6 @@ psort_decl * pdecl_manager::mk_psort_user_decl(unsigned num_params, symbol const } psort_decl * pdecl_manager::mk_psort_dt_decl(unsigned num_params, symbol const & n) { - // std::cout << "insert dt-psort: " << n << " " << num_params << "\n"; return new (a().allocate(sizeof(psort_dt_decl))) psort_dt_decl(m_id_gen.mk(), num_params, *this, n); } diff --git a/src/cmd_context/pdecl.h b/src/cmd_context/pdecl.h index 414415255..bef723380 100644 --- a/src/cmd_context/pdecl.h +++ b/src/cmd_context/pdecl.h @@ -261,6 +261,8 @@ class pdatatypes_decl : public pdecl { virtual ~pdatatypes_decl() {} public: pdatatype_decl const * const * children() const { return m_datatypes.c_ptr(); } + pdatatype_decl * const * begin() const { return m_datatypes.begin(); } + pdatatype_decl * const * end() const { return m_datatypes.end(); } #ifdef DATATYPE_V2 // commit declaration bool commit(pdecl_manager& m); @@ -316,6 +318,7 @@ public: pdatatypes_decl * mk_pdatatypes_decl(unsigned num_params, unsigned num, pdatatype_decl * const * dts); pdatatype_decl * mk_plist_decl() { if (!m_list) init_list(); return m_list; } bool fix_missing_refs(pdatatypes_decl * s, symbol & missing) { return s->fix_missing_refs(missing); } + sort * instantiate_datatype(psort_decl* p, symbol const& name, unsigned n, sort * const* s); sort * instantiate(psort * s, unsigned num, sort * const * args); void lazy_dec_ref(pdecl * p) { p->dec_ref(); if (p->get_ref_count() == 0) m_to_delete.push_back(p); } diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 7bfc8bd99..ab2eecb36 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -897,6 +897,7 @@ namespace smt2 { m_ctx.insert_aux_pdecl(dts.get()); #else dts->commit(pm()); + m_ctx.insert_aux_pdecl(dts.get()); #endif } #ifndef DATATYPE_V2 From 2ea9bfaa41652303b50ece8afc5a7af6908ddb08 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 6 Sep 2017 13:34:41 -0700 Subject: [PATCH 263/488] remove unstable sequence interpolant from doc test Signed-off-by: Nikolaj Bjorner --- src/api/python/z3/z3.py | 6 +-- src/ast/ast_ll_pp.cpp | 2 +- src/ast/rewriter/bool_rewriter.cpp | 76 +++++++----------------------- src/ast/rewriter/rewriter_def.h | 7 +-- src/ast/rewriter/th_rewriter.cpp | 1 + src/smt/asserted_formulas.cpp | 4 ++ src/smt/asserted_formulas.h | 1 + src/smt/tactic/smt_tactic.cpp | 1 + 8 files changed, 31 insertions(+), 67 deletions(-) diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index 1452a037e..39af03190 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -8185,9 +8185,9 @@ def sequence_interpolant(v,p=None,ctx=None): If parameters p are supplied, these are used in creating the solver that determines satisfiability. - >>> x = Int('x') - >>> y = Int('y') - >>> print(sequence_interpolant([x < 0, y == x , y > 2])) + x = Int('x') + y = Int('y') + print(sequence_interpolant([x < 0, y == x , y > 2])) [Not(x >= 0), Not(y >= 0)] """ f = v[0] diff --git a/src/ast/ast_ll_pp.cpp b/src/ast/ast_ll_pp.cpp index 6b14b75a8..c00053780 100644 --- a/src/ast/ast_ll_pp.cpp +++ b/src/ast/ast_ll_pp.cpp @@ -284,7 +284,7 @@ public: } unsigned num_args = to_app(n)->get_num_args(); if (num_args > 0) - m_out << "(_ "; + m_out << "("; display_name(to_app(n)->get_decl()); display_params(to_app(n)->get_decl()); for (unsigned i = 0; i < num_args; i++) { diff --git a/src/ast/rewriter/bool_rewriter.cpp b/src/ast/rewriter/bool_rewriter.cpp index 44fccb49e..6e99cb23e 100644 --- a/src/ast/rewriter/bool_rewriter.cpp +++ b/src/ast/rewriter/bool_rewriter.cpp @@ -629,61 +629,23 @@ br_status bool_rewriter::try_ite_value(app * ite, app * val, expr_ref & result) return BR_REWRITE2; } } - expr* cond2, *t2, *e2; - if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) { - try_ite_value(to_app(t), val, result); - result = m().mk_ite(cond, result, m().mk_eq(e, val)); - return BR_REWRITE2; - } - if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) { - try_ite_value(to_app(e), val, result); - result = m().mk_ite(cond, m().mk_eq(t, val), result); - return BR_REWRITE2; + { + expr* cond2, *t2, *e2; + if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) { + try_ite_value(to_app(t), val, result); + result = m().mk_ite(cond, result, m().mk_eq(e, val)); + return BR_REWRITE2; + } + if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) { + try_ite_value(to_app(e), val, result); + result = m().mk_ite(cond, m().mk_eq(t, val), result); + return BR_REWRITE2; + } } return BR_FAILED; } -#if 0 -// Return true if ite is an if-then-else tree where the leaves are values, -// and they are all different from val -static bool is_ite_value_tree_neq_value(ast_manager & m, app * ite, app * val) { - SASSERT(m.is_ite(ite)); - SASSERT(m.is_value(val)); - - expr_fast_mark1 visited; - ptr_buffer todo; - todo.push_back(ite); - -#define VISIT(ARG) { \ - if (m.is_value(ARG)) { \ - if (ARG == val) \ - return false; \ - } \ - else if (m.is_ite(ARG)) { \ - if (!visited.is_marked(ARG)) { \ - visited.mark(ARG); \ - todo.push_back(to_app(ARG)); \ - } \ - } \ - else { \ - return false; \ - } \ - } - - while (!todo.empty()) { - app * ite = todo.back(); - todo.pop_back(); - SASSERT(m.is_ite(ite)); - expr * t = ite->get_arg(1); - expr * e = ite->get_arg(2); - VISIT(t); - VISIT(e); - } - - return true; -} -#endif br_status bool_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) { if (m().are_equal(lhs, rhs)) { @@ -697,26 +659,20 @@ br_status bool_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) { } br_status r = BR_FAILED; + if (m().is_ite(lhs) && m().is_value(rhs)) { - // if (is_ite_value_tree_neq_value(m(), to_app(lhs), to_app(rhs))) { - // result = m().mk_false(); - // return BR_DONE; - // } r = try_ite_value(to_app(lhs), to_app(rhs), result); CTRACE("try_ite_value", r != BR_FAILED, - tout << mk_ismt2_pp(lhs, m()) << "\n" << mk_ismt2_pp(rhs, m()) << "\n--->\n" << mk_ismt2_pp(result, m()) << "\n";); + tout << mk_bounded_pp(lhs, m()) << "\n" << mk_bounded_pp(rhs, m()) << "\n--->\n" << mk_bounded_pp(result, m()) << "\n";); } else if (m().is_ite(rhs) && m().is_value(lhs)) { - // if (is_ite_value_tree_neq_value(m(), to_app(rhs), to_app(lhs))) { - // result = m().mk_false(); - // return BR_DONE; - // } r = try_ite_value(to_app(rhs), to_app(lhs), result); CTRACE("try_ite_value", r != BR_FAILED, - tout << mk_ismt2_pp(lhs, m()) << "\n" << mk_ismt2_pp(rhs, m()) << "\n--->\n" << mk_ismt2_pp(result, m()) << "\n";); + tout << mk_bounded_pp(lhs, m()) << "\n" << mk_bounded_pp(rhs, m()) << "\n--->\n" << mk_bounded_pp(result, m()) << "\n";); } if (r != BR_FAILED) return r; + if (m().is_bool(lhs)) { bool unfolded = false; diff --git a/src/ast/rewriter/rewriter_def.h b/src/ast/rewriter/rewriter_def.h index c511f00d0..42f268379 100644 --- a/src/ast/rewriter/rewriter_def.h +++ b/src/ast/rewriter/rewriter_def.h @@ -18,6 +18,7 @@ Notes: --*/ #include "ast/rewriter/rewriter.h" #include "ast/ast_smt2_pp.h" +#include "ast/ast_ll_pp.h" template template @@ -259,10 +260,10 @@ void rewriter_tpl::process_app(app * t, frame & fr) { } br_status st = m_cfg.reduce_app(f, new_num_args, new_args, m_r, m_pr2); SASSERT(st != BR_DONE || m().get_sort(m_r) == m().get_sort(t)); - TRACE("reduce_app", - tout << mk_ismt2_pp(t, m()) << "\n"; + CTRACE("reduce_app", st != BR_FAILED, + tout << mk_bounded_pp(t, m()) << "\n"; tout << "st: " << st; - if (m_r) tout << " --->\n" << mk_ismt2_pp(m_r, m()); + if (m_r) tout << " --->\n" << mk_bounded_pp(m_r, m()); tout << "\n";); if (st != BR_FAILED) { result_stack().shrink(fr.m_spos); diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index a2ca12b24..dd431bf85 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -736,6 +736,7 @@ ast_manager & th_rewriter::m() const { void th_rewriter::updt_params(params_ref const & p) { m_params = p; m_imp->cfg().updt_params(p); + IF_VERBOSE(10, verbose_stream() << p << "\n";); } void th_rewriter::get_param_descrs(param_descrs & r) { diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index ebdda73a1..c8670bd36 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -60,6 +60,7 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m_macro_finder = alloc(macro_finder, m, m_macro_manager); + m_elim_and = true; set_eliminate_and(false); } @@ -118,7 +119,10 @@ void asserted_formulas::push_assertion(expr * e, proof * pr, vector m_formulas; unsigned m_qhead; + bool m_elim_and; macro_manager m_macro_manager; scoped_ptr m_macro_finder; maximize_bv_sharing_rw m_bv_sharing; diff --git a/src/smt/tactic/smt_tactic.cpp b/src/smt/tactic/smt_tactic.cpp index f2dc83cfe..57ac7b34b 100644 --- a/src/smt/tactic/smt_tactic.cpp +++ b/src/smt/tactic/smt_tactic.cpp @@ -150,6 +150,7 @@ public: proof_converter_ref & pc, expr_dependency_ref & core) { try { + IF_VERBOSE(10, verbose_stream() << "(smt.tactic start)\n";); mc = 0; pc = 0; core = 0; SASSERT(in->is_well_sorted()); ast_manager & m = in->m(); From 1d6f53c31026ea80679cccc12932f8ba986d7f7b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 7 Sep 2017 05:32:07 -0700 Subject: [PATCH 264/488] fix #1248, fix #1249 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/tactic_cmds.cpp | 3 +++ src/opt/opt_cmds.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index b5ad0707d..14c715eca 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -197,6 +197,9 @@ public: } virtual void execute(cmd_context & ctx) { + if (!m_tactic) { + throw cmd_exception("check-sat-using needs a tactic argument"); + } params_ref p = ctx.params().merge_default_params(ps()); tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p); tref->set_logic(ctx.get_logic()); diff --git a/src/opt/opt_cmds.cpp b/src/opt/opt_cmds.cpp index 7ca2be4aa..89264a9c8 100644 --- a/src/opt/opt_cmds.cpp +++ b/src/opt/opt_cmds.cpp @@ -96,6 +96,9 @@ public: } virtual void execute(cmd_context & ctx) { + if (!m_formula) { + throw cmd_exception("assert-soft requires a formulas as argument."); + } symbol w("weight"); rational weight = ps().get_rat(symbol("weight"), rational::one()); symbol id = ps().get_sym(symbol("id"), symbol::null); From 19fa5f8cb360a1aa6a80e04402eeffd00dbeb1ac Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 7 Sep 2017 06:23:01 -0700 Subject: [PATCH 265/488] expand select/store in pre-processor Signed-off-by: Nikolaj Bjorner --- src/smt/asserted_formulas.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index c8670bd36..c52ad851c 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -129,6 +129,7 @@ void asserted_formulas::set_eliminate_and(bool flag) { p.set_bool("rewrite_patterns", true); p.set_bool("eq2ineq", m_params.m_arith_eq2ineq); p.set_bool("gcd_rounding", true); + p.set_bool("expand_select_store", true); m_rewriter.updt_params(p); flush_cache(); } From 0c9711aad7550f246d9596abf628e58089efa6eb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 8 Sep 2017 21:20:54 +0300 Subject: [PATCH 266/488] copy declarations Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 6 ++++ src/ast/ast.h | 4 +++ src/ast/ast_translation.cpp | 8 ++---- src/ast/datatype_decl_plugin2.cpp | 47 +++++++++++++++++++++++++++++++ src/ast/datatype_decl_plugin2.h | 6 ++++ src/smt/smt_solver.cpp | 18 +++++------- 6 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index a905efa28..bb81c1eba 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1529,12 +1529,15 @@ void ast_manager::raise_exception(char const * msg) { throw ast_exception(msg); } +#include "ast/ast_translation.h" + void ast_manager::copy_families_plugins(ast_manager const & from) { TRACE("copy_families_plugins", tout << "target:\n"; for (family_id fid = 0; m_family_manager.has_family(fid); fid++) { tout << "fid: " << fid << " fidname: " << get_family_name(fid) << "\n"; }); + ast_translation trans(const_cast(from), *this, false); for (family_id fid = 0; from.m_family_manager.has_family(fid); fid++) { SASSERT(from.is_builtin_family_id(fid) == is_builtin_family_id(fid)); SASSERT(!from.is_builtin_family_id(fid) || m_family_manager.has_family(fid)); @@ -1555,6 +1558,9 @@ void ast_manager::copy_families_plugins(ast_manager const & from) { SASSERT(new_p->get_family_id() == fid); SASSERT(has_plugin(fid)); } + if (from.has_plugin(fid)) { + get_plugin(fid)->inherit(from.get_plugin(fid), trans); + } SASSERT(from.m_family_manager.has_family(fid) == m_family_manager.has_family(fid)); SASSERT(from.get_family_id(fid_name) == get_family_id(fid_name)); SASSERT(!from.has_plugin(fid) || has_plugin(fid)); diff --git a/src/ast/ast.h b/src/ast/ast.h index a1e31f46f..4eb43d30b 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -895,6 +895,8 @@ struct ast_eq_proc { } }; +class ast_translation; + class ast_table : public chashtable, ast_eq_proc> { public: void erase(ast * n); @@ -930,6 +932,8 @@ protected: m_family_id = id; } + virtual void inherit(decl_plugin* other_p, ast_translation& ) { } + friend class ast_manager; public: diff --git a/src/ast/ast_translation.cpp b/src/ast/ast_translation.cpp index 0c56b6de6..1bce4bcbe 100644 --- a/src/ast/ast_translation.cpp +++ b/src/ast/ast_translation.cpp @@ -37,11 +37,9 @@ void ast_translation::cleanup() { } void ast_translation::reset_cache() { - obj_map::iterator it = m_cache.begin(); - obj_map::iterator end = m_cache.end(); - for (; it != end; ++it) { - m_from_manager.dec_ref(it->m_key); - m_to_manager.dec_ref(it->m_value); + for (auto & kv : m_cache) { + m_from_manager.dec_ref(kv.m_key); + m_to_manager.dec_ref(kv.m_value); } m_cache.reset(); } diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 43164a436..0a002ed08 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -24,6 +24,7 @@ Revision History: #include "ast/datatype_decl_plugin2.h" #include "ast/array_decl_plugin.h" #include "ast/ast_smt2_pp.h" +#include "ast/ast_translation.h" namespace datatype { @@ -53,6 +54,9 @@ namespace datatype { def const& accessor::get_def() const { return m_constructor->get_def(); } util& accessor::u() const { return m_constructor->u(); } + accessor* accessor::translate(ast_translation& tr) { + return alloc(accessor, tr.to(), name(), to_sort(tr(m_range.get()))); + } constructor::~constructor() { for (accessor* a : m_accessors) dealloc(a); @@ -76,6 +80,15 @@ namespace datatype { return instantiate(sorts); } + constructor* constructor::translate(ast_translation& tr) { + constructor* result = alloc(constructor, m_name, m_recognizer); + for (accessor* a : *this) { + result->add(a->translate(tr)); + } + return result; + } + + sort_ref def::instantiate(sort_ref_vector const& sorts) const { sort_ref s(m); TRACE("datatype", tout << "instantiate " << m_name << "\n";); @@ -91,6 +104,19 @@ namespace datatype { return sort_ref(m.substitute(m_sort, sorts.size(), m_params.c_ptr(), sorts.c_ptr()), m); } + def* def::translate(ast_translation& tr, util& u) { + sort_ref_vector ps(tr.to()); + for (sort* p : m_params) { + ps.push_back(to_sort(tr(p))); + } + def* result = alloc(def, tr.to(), u, m_name, m_class_id, ps.size(), ps.c_ptr()); + for (constructor* c : *this) { + add(c->translate(tr)); + } + if (m_sort) result->m_sort = to_sort(tr(m_sort.get())); + return result; + } + enum status { GRAY, BLACK @@ -145,6 +171,27 @@ namespace datatype { return *(m_util.get()); } + static unsigned stack_depth = 0; + + void plugin::inherit(decl_plugin* other_p, ast_translation& tr) { + ++stack_depth; + SASSERT(stack_depth < 10); + plugin* p = dynamic_cast(other_p); + svector names; + SASSERT(p); + for (auto& kv : p->m_defs) { + def* d = kv.m_value; + if (!m_defs.contains(kv.m_key)) { + names.push_back(kv.m_key); + m_defs.insert(kv.m_key, d->translate(tr, u())); + } + } + m_class_id = m_defs.size(); + u().compute_datatype_size_functions(names); + --stack_depth; + } + + struct invalid_datatype {}; sort * plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index a88c7100e..364ba9350 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -75,6 +75,7 @@ namespace datatype { constructor const& get_constructor() const { return *m_constructor; } def const& get_def() const; util& u() const; + accessor* translate(ast_translation& tr); }; class constructor { @@ -98,6 +99,7 @@ namespace datatype { void attach(def* d) { m_def = d; } def const& get_def() const { return *m_def; } util& u() const; + constructor* translate(ast_translation& tr); }; namespace param_size { @@ -228,6 +230,7 @@ namespace datatype { util& u() const { return m_util; } param_size::size* sort_size() { return m_sort_size; } void set_sort_size(param_size::size* p) { m_sort_size = p; p->inc_ref(); m_sort = 0; } + def* translate(ast_translation& tr, util& u); }; namespace decl { @@ -238,6 +241,9 @@ namespace datatype { svector m_def_block; unsigned m_class_id; util & u() const; + + virtual void inherit(decl_plugin* other_p, ast_translation& tr); + public: plugin(): m_class_id(0) {} virtual ~plugin(); diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index 9d86436d9..36272a139 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -61,15 +61,14 @@ namespace smt { } virtual solver * translate(ast_manager & m, params_ref const & p) { + ast_translation translator(get_manager(), m); + solver * result = alloc(solver, m, p, m_logic); smt::kernel::copy(m_context, result->m_context); - ast_translation translator(get_manager(), m); - obj_map::iterator it = m_name2assertion.begin(); - obj_map::iterator end = m_name2assertion.end(); - for (; it != end; it++) - result->m_name2assertion.insert(translator(it->m_key), - translator(it->m_value)); + for (auto & kv : m_name2assertion) + result->m_name2assertion.insert(translator(kv.m_key), + translator(kv.m_value)); return result; } @@ -264,7 +263,7 @@ namespace smt { } void compute_assrtn_fds(ptr_vector & core, vector & assrtn_fds) { - assrtn_fds.resize(m_name2assertion.size()); + assrtn_fds.resize(m_name2assertion.size()); obj_map::iterator ait = m_name2assertion.begin(); obj_map::iterator aend = m_name2assertion.end(); for (unsigned i = 0; ait != aend; ait++, i++) { @@ -277,10 +276,7 @@ namespace smt { } bool fds_intersect(func_decl_set & pattern_fds, func_decl_set & assrtn_fds) { - func_decl_set::iterator it = pattern_fds.begin(); - func_decl_set::iterator end = pattern_fds.end(); - for (; it != end; it++) { - func_decl * fd = *it; + for (func_decl * fd : pattern_fds) { if (assrtn_fds.contains(fd)) return true; } From ed6e23f153ec3b63efc75c0ef12a89d789b100c5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 9 Sep 2017 05:40:12 +0300 Subject: [PATCH 267/488] iterator -> for Signed-off-by: Nikolaj Bjorner --- src/smt/smt_solver.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index 36272a139..65ba1ee24 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -264,14 +264,14 @@ namespace smt { void compute_assrtn_fds(ptr_vector & core, vector & assrtn_fds) { assrtn_fds.resize(m_name2assertion.size()); - obj_map::iterator ait = m_name2assertion.begin(); - obj_map::iterator aend = m_name2assertion.end(); - for (unsigned i = 0; ait != aend; ait++, i++) { - if (core.contains(ait->m_key)) - continue; - collect_fds_proc p(m, assrtn_fds[i]); - expr_fast_mark1 visited; - quick_for_each_expr(p, visited, ait->m_value); + unsigned i = 0; + for (auto & kv : m_name2assertion) { + if (!core.contains(kv.m_key)) { + collect_fds_proc p(m, assrtn_fds[i]); + expr_fast_mark1 visited; + quick_for_each_expr(p, visited, kv.m_value); + } + ++i; } } @@ -293,9 +293,8 @@ namespace smt { for (unsigned d = 0; d < m_core_extend_patterns_max_distance; d++) { new_core_literals.reset(); - unsigned sz = core.size(); - for (unsigned i = 0; i < sz; i++) { - expr_ref name(core[i], m); + for (expr* c : core) { + expr_ref name(c, m); SASSERT(m_name2assertion.contains(name)); expr_ref assrtn(m_name2assertion.find(name), m); collect_pattern_fds(assrtn, pattern_fds); @@ -305,12 +304,12 @@ namespace smt { if (assrtn_fds.empty()) compute_assrtn_fds(core, assrtn_fds); - obj_map::iterator ait = m_name2assertion.begin(); - obj_map::iterator aend = m_name2assertion.end(); - for (unsigned i = 0; ait != aend; ait++, i++) { + unsigned i = 0; + for (auto & kv : m_name2assertion) { if (!core.contains(ait->m_key) && fds_intersect(pattern_fds, assrtn_fds[i])) new_core_literals.push_back(ait->m_key); + ++i; } } From 04e57e08ba93be87633f2dbf9bfe3a500ac51081 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 9 Sep 2017 08:37:17 +0300 Subject: [PATCH 268/488] na Signed-off-by: Nikolaj Bjorner --- src/smt/smt_solver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index 65ba1ee24..e78c6388e 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -306,9 +306,9 @@ namespace smt { unsigned i = 0; for (auto & kv : m_name2assertion) { - if (!core.contains(ait->m_key) && + if (!core.contains(kv.m_key) && fds_intersect(pattern_fds, assrtn_fds[i])) - new_core_literals.push_back(ait->m_key); + new_core_literals.push_back(kv.m_key); ++i; } } From 4fe55cf8e5509f5ea409d2ef0dc3643e1db0d26c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 10 Sep 2017 14:48:57 +0300 Subject: [PATCH 269/488] fix plugin translation Signed-off-by: Nikolaj Bjorner --- src/ast/datatype_decl_plugin2.cpp | 15 ++++++--------- src/parsers/smt2/smt2parser.cpp | 1 - 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 0a002ed08..743a08e98 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -105,13 +105,14 @@ namespace datatype { } def* def::translate(ast_translation& tr, util& u) { + SASSERT(&u.get_manager() == &tr.to()); sort_ref_vector ps(tr.to()); for (sort* p : m_params) { ps.push_back(to_sort(tr(p))); } def* result = alloc(def, tr.to(), u, m_name, m_class_id, ps.size(), ps.c_ptr()); for (constructor* c : *this) { - add(c->translate(tr)); + result->add(c->translate(tr)); } if (m_sort) result->m_sort = to_sort(tr(m_sort.get())); return result; @@ -171,24 +172,22 @@ namespace datatype { return *(m_util.get()); } - static unsigned stack_depth = 0; - void plugin::inherit(decl_plugin* other_p, ast_translation& tr) { - ++stack_depth; - SASSERT(stack_depth < 10); plugin* p = dynamic_cast(other_p); svector names; + ptr_vector new_defs; SASSERT(p); for (auto& kv : p->m_defs) { def* d = kv.m_value; if (!m_defs.contains(kv.m_key)) { names.push_back(kv.m_key); - m_defs.insert(kv.m_key, d->translate(tr, u())); + new_defs.push_back(d->translate(tr, u())); } } + for (def* d : new_defs) + m_defs.insert(d->name(), d); m_class_id = m_defs.size(); u().compute_datatype_size_functions(names); - --stack_depth; } @@ -304,7 +303,6 @@ namespace datatype { VALIDATE_PARAM(u().is_datatype(domain[0])); // blindly trust that parameter is a constructor sort* range = m_manager->mk_bool_sort(); - func_decl* f = to_func_decl(parameters[0].get_ast()); func_decl_info info(m_family_id, OP_DT_RECOGNISER, num_parameters, parameters); info.m_private_parameters = true; return m.mk_func_decl(symbol(parameters[1].get_symbol()), arity, domain, range, info); @@ -317,7 +315,6 @@ namespace datatype { VALIDATE_PARAM(u().is_datatype(domain[0])); // blindly trust that parameter is a constructor sort* range = m_manager->mk_bool_sort(); - func_decl* f = to_func_decl(parameters[0].get_ast()); func_decl_info info(m_family_id, OP_DT_IS, num_parameters, parameters); info.m_private_parameters = true; return m.mk_func_decl(symbol("is"), arity, domain, range, info); diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index ab2eecb36..a1304a848 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -617,7 +617,6 @@ namespace smt2 { SASSERT(curr_is_identifier()); symbol id = curr_id(); psort_decl * d = m_ctx.find_psort_decl(id); - int idx = 0; if (d == 0) { unknown_sort(id); } From 070c699ffcfd2c1ffe10ac40825de13cdb195cd9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 10 Sep 2017 15:32:53 +0300 Subject: [PATCH 270/488] remove V2 reference Signed-off-by: Nikolaj Bjorner --- src/ast/CMakeLists.txt | 1 - src/ast/ast_smt2_pp.cpp | 2 - src/ast/ast_smt_pp.cpp | 71 - src/ast/datatype_decl_plugin.cpp | 2003 ++++++++++++++--------------- src/ast/datatype_decl_plugin.h | 582 ++++++--- src/ast/datatype_decl_plugin2.cpp | 1077 ---------------- src/ast/datatype_decl_plugin2.h | 439 ------- src/cmd_context/pdecl.cpp | 62 - src/cmd_context/pdecl.h | 4 - src/parsers/smt2/smt2parser.cpp | 32 +- 10 files changed, 1377 insertions(+), 2896 deletions(-) delete mode 100644 src/ast/datatype_decl_plugin2.cpp delete mode 100644 src/ast/datatype_decl_plugin2.h diff --git a/src/ast/CMakeLists.txt b/src/ast/CMakeLists.txt index 47ed2def8..0a14d9473 100644 --- a/src/ast/CMakeLists.txt +++ b/src/ast/CMakeLists.txt @@ -14,7 +14,6 @@ z3_add_component(ast ast_util.cpp bv_decl_plugin.cpp datatype_decl_plugin.cpp - datatype_decl_plugin2.cpp decl_collector.cpp dl_decl_plugin.cpp expr2polynomial.cpp diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index c69cafc71..abb4ae959 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -434,7 +434,6 @@ format_ns::format * smt2_pp_environment::pp_sort(sort * s) { fs.push_back(pp_sort(to_sort(s->get_parameter(0).get_ast()))); return mk_seq1(m, fs.begin(), fs.end(), f2f(), get_sutil().is_seq(s)?"Seq":"RegEx"); } -#ifdef DATATYPE_V2 if (get_dtutil().is_datatype(s)) { unsigned sz = get_dtutil().get_datatype_num_parameter_sorts(s); if (sz > 0) { @@ -445,7 +444,6 @@ format_ns::format * smt2_pp_environment::pp_sort(sort * s) { return mk_seq1(m, fs.begin(), fs.end(), f2f(), s->get_name().str().c_str()); } } -#endif return format_ns::mk_string(get_manager(), s->get_name().str().c_str()); } diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 1c3b4aeb2..906fd054b 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -204,19 +204,13 @@ class smt_printer { void pp_decl(func_decl* d) { symbol sym = m_renaming.get_symbol(d->get_name()); if (d->get_family_id() == m_dt_fid) { -#ifdef DATATYPE_V2 - std::cout << "printing " << sym << "\n"; datatype_util util(m_manager); if (util.is_recognizer(d)) { - std::cout << d->get_num_parameters() << "\n"; visit_params(false, sym, d->get_num_parameters(), d->get_parameters()); } else { m_out << sym; } -#else - m_out << sym; -#endif } else if (m_manager.is_ite(d)) { m_out << "ite"; @@ -314,9 +308,6 @@ class smt_printer { sym = "Array"; } else if (s->is_sort_of(m_dt_fid, DATATYPE_SORT)) { -#ifndef DATATYPE_V2 - m_out << m_renaming.get_symbol(s->get_name()); -#else datatype_util util(m_manager); unsigned num_sorts = util.get_datatype_num_parameter_sorts(s); if (num_sorts > 0) { @@ -330,7 +321,6 @@ class smt_printer { } m_out << ")"; } -#endif return; } else { @@ -787,8 +777,6 @@ public: datatype_util util(m_manager); SASSERT(util.is_datatype(s)); -#ifdef DATATYPE_V2 - sort_ref_vector ps(m_manager); ptr_vector defs; util.get_defs(s, defs); @@ -839,65 +827,6 @@ public: m_out << ")"; } m_out << "))"; -#else - - ptr_vector rec_sorts; - - rec_sorts.push_back(s); - mark.mark(s, true); - - // collect siblings and sorts that have not already been printed. - for (unsigned h = 0; h < rec_sorts.size(); ++h) { - s = rec_sorts[h]; - ptr_vector const& decls = *util.get_datatype_constructors(s); - - for (unsigned i = 0; i < decls.size(); ++i) { - func_decl* f = decls[i]; - for (unsigned j = 0; j < f->get_arity(); ++j) { - sort* s2 = f->get_domain(j); - if (!mark.is_marked(s2)) { - if (m_manager.is_uninterp(s2)) { - pp_sort_decl(mark, s2); - } - else if (!util.is_datatype(s2)) { - // skip - } - else if (util.are_siblings(s, s2)) { - rec_sorts.push_back(s2); - mark.mark(s2, true); - } - else { - pp_sort_decl(mark, s2); - } - } - } - } - } - - m_out << "(declare-datatypes () ("; - bool first_sort = true; - for (sort * s : rec_sorts) { - if (!first_sort) m_out << " "; else first_sort = false; - - m_out << "("; - m_out << m_renaming.get_symbol(s->get_name()); - m_out << " "; - bool first_constr = true; - for (func_decl* f : *util.get_datatype_constructors(s)) { - if (!first_constr) m_out << " "; else first_constr = false; - m_out << "("; - m_out << m_renaming.get_symbol(f->get_name()); - for (func_decl* a : *util.get_constructor_accessors(f)) { - m_out << " (" << m_renaming.get_symbol(a->get_name()) << " "; - visit_sort(a->get_range()); - m_out << ")"; - } - m_out << ")"; - } - m_out << ")"; - } - m_out << "))"; -#endif newline(); } diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index 1090b3ff1..566487e60 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -1,5 +1,5 @@ /*++ -Copyright (c) 2006 Microsoft Corporation +Copyright (c) 2017 Microsoft Corporation Module Name: @@ -11,321 +11,703 @@ Abstract: Author: - Leonardo de Moura (leonardo) 2008-01-10. + Nikolaj Bjorner (nbjorner) 2017-9-1 Revision History: --*/ -#include "ast/datatype_decl_plugin.h" + #include "util/warning.h" +#include "ast/array_decl_plugin.h" +#include "ast/datatype_decl_plugin.h" #include "ast/ast_smt2_pp.h" +#include "ast/ast_translation.h" -#ifndef DATATYPE_V2 -/** - \brief Auxiliary class used to declare inductive datatypes. -*/ -class accessor_decl { - symbol m_name; - type_ref m_type; -public: - accessor_decl(const symbol & n, type_ref r):m_name(n), m_type(r) {} - symbol const & get_name() const { return m_name; } - type_ref const & get_type() const { return m_type; } -}; +namespace datatype { -accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_ref const & t) { - return alloc(accessor_decl, n, t); -} - -void del_accessor_decl(accessor_decl * d) { - dealloc(d); -} - -void del_accessor_decls(unsigned num, accessor_decl * const * as) { - for (unsigned i = 0; i < num; i++) - del_accessor_decl(as[i]); -} - -/** - \brief Auxiliary class used to declare inductive datatypes. -*/ -class constructor_decl { - symbol m_name; - symbol m_recogniser_name; - ptr_vector m_accessors; -public: - constructor_decl(const symbol & n, const symbol & r, unsigned num_accessors, accessor_decl * const * accessors): - m_name(n), m_recogniser_name(r), m_accessors(num_accessors, accessors) {} - ~constructor_decl() { - std::for_each(m_accessors.begin(), m_accessors.end(), delete_proc()); - } - symbol const & get_name() const { return m_name; } - symbol const & get_recognizer_name() const { return m_recogniser_name; } - ptr_vector const & get_accessors() const { return m_accessors; } -}; - -constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * const * accessors) { - return alloc(constructor_decl, n, r, num_accessors, accessors); -} - -void del_constructor_decl(constructor_decl * d) { - dealloc(d); -} - -void del_constructor_decls(unsigned num, constructor_decl * const * cs) { - for (unsigned i = 0; i < num; i++) - del_constructor_decl(cs[i]); -} - -/** - \brief Auxiliary class used to declare inductive datatypes. -*/ -class datatype_decl { - symbol m_name; - ptr_vector m_constructors; -public: - datatype_decl(const symbol & n, unsigned num_constructors, constructor_decl * const * constructors): - m_name(n), m_constructors(num_constructors, constructors) { - } - ~datatype_decl() { - std::for_each(m_constructors.begin(), m_constructors.end(), delete_proc()); - } - symbol const & get_name() const { return m_name; } - ptr_vector const & get_constructors() const { return m_constructors; } -}; - -datatype_decl * mk_datatype_decl(datatype_util&, symbol const & n, unsigned num_params, sort * const* params, unsigned num_constructors, constructor_decl * const * cs) { - return alloc(datatype_decl, n, num_constructors, cs); -} - -void del_datatype_decl(datatype_decl * d) { - dealloc(d); -} - -void del_datatype_decls(unsigned num, datatype_decl * const * ds) { - for (unsigned i = 0; i < num; i++) - del_datatype_decl(ds[i]); -} - -typedef buffer bool_buffer; - -struct invalid_datatype {}; - -static parameter const & read(unsigned num_parameters, parameter const * parameters, unsigned idx, bool_buffer & read_pos) { - if (idx >= num_parameters) { - throw invalid_datatype(); - } - if (idx >= read_pos.size()) { - read_pos.resize(idx+1, false); - } - read_pos[idx] = true; - return parameters[idx]; -} - -static int read_int(unsigned num_parameters, parameter const * parameters, unsigned idx, bool_buffer & read_pos) { - const parameter & r = read(num_parameters, parameters, idx, read_pos); - if (!r.is_int()) { - TRACE("datatype", tout << "expected integer parameter at position " << idx << " got: " << r << "\n";); - throw invalid_datatype(); - } - return r.get_int(); -} - -static symbol read_symbol(unsigned num_parameters, parameter const * parameters, unsigned idx, bool_buffer & read_pos) { - parameter const & r = read(num_parameters, parameters, idx, read_pos); - if (!r.is_symbol()) { - TRACE("datatype", tout << "expected symol parameter at position " << idx << " got: " << r << "\n";); - throw invalid_datatype(); - } - return r.get_symbol(); -} - -static sort* read_sort(unsigned num_parameters, parameter const * parameters, unsigned idx, bool_buffer & read_pos) { - parameter const & r = read(num_parameters, parameters, idx, read_pos); - if (!r.is_ast()) { - TRACE("datatype", tout << "expected ast parameter at position " << idx << " got: " << r << "\n";); - throw invalid_datatype(); - } - ast* a = r.get_ast(); - if (!is_sort(a)) { - throw invalid_datatype(); - } - return to_sort(a); -} - -enum status { - WHITE, - GRAY, - BLACK -}; - -/** - \brief Return true if the inductive datatype is recursive. - Pre-condition: The given argument constains the parameters of an inductive datatype. -*/ -static bool is_recursive_datatype(parameter const * parameters) { - unsigned num_types = parameters[0].get_int(); - unsigned top_tid = parameters[1].get_int(); - buffer already_found(num_types, WHITE); - buffer todo; - todo.push_back(top_tid); - while (!todo.empty()) { - unsigned tid = todo.back(); - if (already_found[tid] == BLACK) { - todo.pop_back(); - continue; + void accessor::fix_range(sort_ref_vector const& dts) { + if (!m_range) { + m_range = dts[m_index]; } - already_found[tid] = GRAY; - unsigned o = datatype_decl_plugin::constructor_offset(parameters, tid); // constructor offset - unsigned num_constructors = parameters[o].get_int(); - bool can_process = true; - for (unsigned s = 1; s <= num_constructors; s++) { - unsigned k_i = parameters[o + s].get_int(); - unsigned num_accessors = parameters[k_i + 2].get_int(); - for (unsigned r = 0; r < num_accessors; r++) { - parameter const & a_type = parameters[k_i + 4 + 2*r]; - if (a_type.is_int()) { - unsigned tid_prime = a_type.get_int(); - switch (already_found[tid_prime]) { - case WHITE: - todo.push_back(tid_prime); - can_process = false; - break; - case GRAY: - // type is recursive - return true; - case BLACK: - break; + } + + func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const { + ast_manager& m = ps.get_manager(); + unsigned n = ps.size(); + SASSERT(m_range); + SASSERT(n == get_def().params().size()); + sort_ref range(m.substitute(m_range, n, get_def().params().c_ptr(), ps.c_ptr()), m); + sort_ref src(get_def().instantiate(ps)); + sort* srcs[1] = { src.get() }; + parameter pas[2] = { parameter(name()), parameter(get_constructor().name()) }; + return func_decl_ref(m.mk_func_decl(u().get_family_id(), OP_DT_ACCESSOR, 2, pas, 1, srcs, range), m); + } + + func_decl_ref accessor::instantiate(sort* dt) const { + sort_ref_vector sorts = get_def().u().datatype_params(dt); + return instantiate(sorts); + } + + def const& accessor::get_def() const { return m_constructor->get_def(); } + util& accessor::u() const { return m_constructor->u(); } + accessor* accessor::translate(ast_translation& tr) { + return alloc(accessor, tr.to(), name(), to_sort(tr(m_range.get()))); + } + + constructor::~constructor() { + for (accessor* a : m_accessors) dealloc(a); + m_accessors.reset(); + } + util& constructor::u() const { return m_def->u(); } + + func_decl_ref constructor::instantiate(sort_ref_vector const& ps) const { + ast_manager& m = ps.get_manager(); + sort_ref_vector domain(m); + for (accessor const* a : accessors()) { + domain.push_back(a->instantiate(ps)->get_range()); + } + sort_ref range = get_def().instantiate(ps); + parameter pas[1] = { parameter(name()) }; + return func_decl_ref(m.mk_func_decl(u().get_family_id(), OP_DT_CONSTRUCTOR, 1, pas, domain.size(), domain.c_ptr(), range), m); + } + + func_decl_ref constructor::instantiate(sort* dt) const { + sort_ref_vector sorts = get_def().u().datatype_params(dt); + return instantiate(sorts); + } + + constructor* constructor::translate(ast_translation& tr) { + constructor* result = alloc(constructor, m_name, m_recognizer); + for (accessor* a : *this) { + result->add(a->translate(tr)); + } + return result; + } + + + sort_ref def::instantiate(sort_ref_vector const& sorts) const { + sort_ref s(m); + TRACE("datatype", tout << "instantiate " << m_name << "\n";); + if (!m_sort) { + vector ps; + ps.push_back(parameter(m_name)); + for (sort * s : m_params) ps.push_back(parameter(s)); + m_sort = m.mk_sort(u().get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); + } + if (sorts.empty()) { + return m_sort; + } + return sort_ref(m.substitute(m_sort, sorts.size(), m_params.c_ptr(), sorts.c_ptr()), m); + } + + def* def::translate(ast_translation& tr, util& u) { + SASSERT(&u.get_manager() == &tr.to()); + sort_ref_vector ps(tr.to()); + for (sort* p : m_params) { + ps.push_back(to_sort(tr(p))); + } + def* result = alloc(def, tr.to(), u, m_name, m_class_id, ps.size(), ps.c_ptr()); + for (constructor* c : *this) { + result->add(c->translate(tr)); + } + if (m_sort) result->m_sort = to_sort(tr(m_sort.get())); + return result; + } + + enum status { + GRAY, + BLACK + }; + + namespace param_size { + size* size::mk_offset(sort_size const& s) { return alloc(offset, s); } + size* size::mk_param(sort_ref& p) { return alloc(sparam, p); } + size* size::mk_plus(size* a1, size* a2) { return alloc(plus, a1, a2); } + size* size::mk_times(size* a1, size* a2) { return alloc(times, a1, a2); } + size* size::mk_times(ptr_vector& szs) { + if (szs.empty()) return mk_offset(sort_size(1)); + if (szs.size() == 1) return szs[0]; + size* r = szs[0]; + for (unsigned i = 1; i < szs.size(); ++i) { + r = mk_times(r, szs[i]); + } + return r; + } + size* size::mk_plus(ptr_vector& szs) { + if (szs.empty()) return mk_offset(sort_size(0)); + if (szs.size() == 1) return szs[0]; + size* r = szs[0]; + for (unsigned i = 1; i < szs.size(); ++i) { + r = mk_plus(r, szs[i]); + } + return r; + } + size* size::mk_power(size* a1, size* a2) { return alloc(power, a1, a2); } + } + + namespace decl { + + plugin::~plugin() { + finalize(); + } + + void plugin::finalize() { + for (auto& kv : m_defs) { + dealloc(kv.m_value); + } + m_defs.reset(); + m_util = 0; // force deletion + } + + util & plugin::u() const { + SASSERT(m_manager); + SASSERT(m_family_id != null_family_id); + if (m_util.get() == 0) { + m_util = alloc(util, *m_manager); + } + return *(m_util.get()); + } + + void plugin::inherit(decl_plugin* other_p, ast_translation& tr) { + plugin* p = dynamic_cast(other_p); + svector names; + ptr_vector new_defs; + SASSERT(p); + for (auto& kv : p->m_defs) { + def* d = kv.m_value; + if (!m_defs.contains(kv.m_key)) { + names.push_back(kv.m_key); + new_defs.push_back(d->translate(tr, u())); + } + } + for (def* d : new_defs) + m_defs.insert(d->name(), d); + m_class_id = m_defs.size(); + u().compute_datatype_size_functions(names); + } + + + struct invalid_datatype {}; + + sort * plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { + try { + if (k != DATATYPE_SORT) { + TRACE("datatype", tout << "invalid kind parameter to datatype\n";); + throw invalid_datatype(); + } + if (num_parameters < 1) { + TRACE("datatype", tout << "at least one parameter expected to datatype declaration\n";); + throw invalid_datatype(); + } + parameter const & name = parameters[0]; + if (!name.is_symbol()) { + TRACE("datatype", tout << "expected symol parameter at position " << 0 << " got: " << name << "\n";); + throw invalid_datatype(); + } + for (unsigned i = 1; i < num_parameters; ++i) { + parameter const& s = parameters[i]; + if (!s.is_ast() || !is_sort(s.get_ast())) { + TRACE("datatype", tout << "expected sort parameter at position " << i << " got: " << s << "\n";); + throw invalid_datatype(); + } + } + + sort* s = m_manager->mk_sort(name.get_symbol(), + sort_info(m_family_id, k, num_parameters, parameters, true)); + def* d = 0; + if (m_defs.find(s->get_name(), d) && d->sort_size()) { + obj_map S; + for (unsigned i = 0; i + 1 < num_parameters; ++i) { + sort* r = to_sort(parameters[i + 1].get_ast()); + S.insert(d->params()[i], r->get_num_elements()); + } + sort_size ts = d->sort_size()->eval(S); + TRACE("datatype", tout << name << " has size " << ts << "\n";); + s->set_num_elements(ts); + } + else { + TRACE("datatype", tout << "not setting size for " << name << "\n";); + } + return s; + } + catch (invalid_datatype) { + m_manager->raise_exception("invalid datatype"); + return 0; + } + } + + func_decl * plugin::mk_update_field( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + decl_kind k = OP_DT_UPDATE_FIELD; + ast_manager& m = *m_manager; + + if (num_parameters != 1 || !parameters[0].is_ast()) { + m.raise_exception("invalid parameters for datatype field update"); + return 0; + } + if (arity != 2) { + m.raise_exception("invalid number of arguments for datatype field update"); + return 0; + } + func_decl* acc = 0; + if (is_func_decl(parameters[0].get_ast())) { + acc = to_func_decl(parameters[0].get_ast()); + } + if (acc && !u().is_accessor(acc)) { + acc = 0; + } + if (!acc) { + m.raise_exception("datatype field update requires a datatype accessor as the second argument"); + return 0; + } + sort* dom = acc->get_domain(0); + sort* rng = acc->get_range(); + if (dom != domain[0]) { + m.raise_exception("first argument to field update should be a data-type"); + return 0; + } + if (rng != domain[1]) { + std::ostringstream buffer; + buffer << "second argument to field update should be " << mk_ismt2_pp(rng, m) + << " instead of " << mk_ismt2_pp(domain[1], m); + m.raise_exception(buffer.str().c_str()); + return 0; + } + range = domain[0]; + func_decl_info info(m_family_id, k, num_parameters, parameters); + return m.mk_func_decl(symbol("update-field"), arity, domain, range, info); + } + +#define VALIDATE_PARAM(_pred_) if (!(_pred_)) m_manager->raise_exception("invalid parameter to datatype function " #_pred_); + + func_decl * decl::plugin::mk_constructor(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + ast_manager& m = *m_manager; + VALIDATE_PARAM(num_parameters == 1 && parameters[0].is_symbol() && range && u().is_datatype(range)); + // we blindly trust other conditions are met, including domain types. + symbol name = parameters[0].get_symbol(); + func_decl_info info(m_family_id, OP_DT_CONSTRUCTOR, num_parameters, parameters); + info.m_private_parameters = true; + return m.mk_func_decl(name, arity, domain, range, info); + } + + func_decl * decl::plugin::mk_recognizer(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort *) { + ast_manager& m = *m_manager; + VALIDATE_PARAM(arity == 1 && num_parameters == 2 && parameters[1].is_symbol() && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + VALIDATE_PARAM(u().is_datatype(domain[0])); + // blindly trust that parameter is a constructor + sort* range = m_manager->mk_bool_sort(); + func_decl_info info(m_family_id, OP_DT_RECOGNISER, num_parameters, parameters); + info.m_private_parameters = true; + return m.mk_func_decl(symbol(parameters[1].get_symbol()), arity, domain, range, info); + } + + func_decl * decl::plugin::mk_is(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort *) { + ast_manager& m = *m_manager; + VALIDATE_PARAM(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + VALIDATE_PARAM(u().is_datatype(domain[0])); + // blindly trust that parameter is a constructor + sort* range = m_manager->mk_bool_sort(); + func_decl_info info(m_family_id, OP_DT_IS, num_parameters, parameters); + info.m_private_parameters = true; + return m.mk_func_decl(symbol("is"), arity, domain, range, info); + } + + func_decl * decl::plugin::mk_accessor(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) + { + ast_manager& m = *m_manager; + VALIDATE_PARAM(arity == 1 && num_parameters == 2 && parameters[0].is_symbol() && parameters[1].is_symbol()); + VALIDATE_PARAM(u().is_datatype(domain[0])); + SASSERT(range); + func_decl_info info(m_family_id, OP_DT_ACCESSOR, num_parameters, parameters); + info.m_private_parameters = true; + symbol name = parameters[0].get_symbol(); + return m.mk_func_decl(name, arity, domain, range, info); + } + + func_decl * decl::plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + switch (k) { + case OP_DT_CONSTRUCTOR: + return mk_constructor(num_parameters, parameters, arity, domain, range); + case OP_DT_RECOGNISER: + return mk_recognizer(num_parameters, parameters, arity, domain, range); + case OP_DT_IS: + return mk_is(num_parameters, parameters, arity, domain, range); + case OP_DT_ACCESSOR: + return mk_accessor(num_parameters, parameters, arity, domain, range); + case OP_DT_UPDATE_FIELD: + return mk_update_field(num_parameters, parameters, arity, domain, range); + default: + m_manager->raise_exception("invalid datatype operator kind"); + return 0; + } + } + + def* plugin::mk(symbol const& name, unsigned n, sort * const * params) { + ast_manager& m = *m_manager; + return alloc(def, m, u(), name, m_class_id, n, params); + } + + + void plugin::end_def_block() { + ast_manager& m = *m_manager; + + sort_ref_vector sorts(m); + for (symbol const& s : m_def_block) { + def const& d = *m_defs[s]; + sort_ref_vector ps(m); + sorts.push_back(d.instantiate(ps)); + } + for (symbol const& s : m_def_block) { + def& d = *m_defs[s]; + for (constructor* c : d) { + for (accessor* a : *c) { + a->fix_range(sorts); } } } - } - if (can_process) { - already_found[tid] = BLACK; - todo.pop_back(); - } - } - return false; -} + if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) { + m_manager->raise_exception("datatype is not well-founded"); + } -/** - \brief Return the size of the inductive datatype. - Pre-condition: The given argument constains the parameters of an inductive datatype. -*/ -static sort_size get_datatype_size(parameter const * parameters) { - unsigned num_types = parameters[0].get_int(); - unsigned top_tid = parameters[1].get_int(); - buffer szs(num_types, sort_size()); - buffer already_found(num_types, WHITE); - buffer todo; - todo.push_back(top_tid); - while (!todo.empty()) { - unsigned tid = todo.back(); - if (already_found[tid] == BLACK) { - todo.pop_back(); - continue; - } - already_found[tid] = GRAY; - unsigned o = datatype_decl_plugin::constructor_offset(parameters, tid); - unsigned num_constructors = parameters[o].get_int(); - bool is_very_big = false; - bool can_process = true; - for (unsigned s = 1; s <= num_constructors; s++) { - unsigned k_i = parameters[o+s].get_int(); - unsigned num_accessors = parameters[k_i+2].get_int(); - for (unsigned r = 0; r < num_accessors; r++) { - parameter const & a_type = parameters[k_i+4 + 2*r]; - if (a_type.is_int()) { - int tid_prime = a_type.get_int(); - switch (already_found[tid_prime]) { - case WHITE: - todo.push_back(tid_prime); - can_process = false; - break; - case GRAY: - // type is recursive - return sort_size(); - case BLACK: - break; - } - } - else { - SASSERT(a_type.is_ast()); - sort * ty = to_sort(a_type.get_ast()); - if (ty->is_infinite()) { - // type is infinite - return sort_size(); - } - else if (ty->is_very_big()) { - is_very_big = true; - } - } + u().compute_datatype_size_functions(m_def_block); + for (symbol const& s : m_def_block) { + sort_ref_vector ps(m); + m_defs[s]->instantiate(ps); } } - if (can_process) { - todo.pop_back(); - already_found[tid] = BLACK; - if (is_very_big) { - szs[tid] = sort_size::mk_very_big(); + + bool plugin::mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts) { + begin_def_block(); + for (unsigned i = 0; i < num_datatypes; ++i) { + def* d = 0; + TRACE("datatype", tout << "declaring " << datatypes[i]->name() << "\n";); + if (m_defs.find(datatypes[i]->name(), d)) { + TRACE("datatype", tout << "delete previous version for " << datatypes[i]->name() << "\n";); + dealloc(d); + } + m_defs.insert(datatypes[i]->name(), datatypes[i]); + m_def_block.push_back(datatypes[i]->name()); + } + end_def_block(); + sort_ref_vector ps(*m_manager); + for (symbol const& s : m_def_block) { + new_sorts.push_back(m_defs[s]->instantiate(ps)); + } + return true; + } + + void plugin::remove(symbol const& s) { + def* d = 0; + if (m_defs.find(s, d)) dealloc(d); + m_defs.remove(s); + } + + bool plugin::is_value_visit(expr * arg, ptr_buffer & todo) const { + if (!is_app(arg)) + return false; + family_id fid = to_app(arg)->get_family_id(); + if (fid == m_family_id) { + if (!u().is_constructor(to_app(arg))) + return false; + if (to_app(arg)->get_num_args() == 0) + return true; + todo.push_back(to_app(arg)); + return true; } else { - // the type is not infinite nor the number of elements is infinite... - // computing the number of elements - rational num; - for (unsigned s = 1; s <= num_constructors; s++) { - unsigned k_i = parameters[o+s].get_int(); - unsigned num_accessors = parameters[k_i+2].get_int(); - rational c_num(1); - for (unsigned r = 0; r < num_accessors; r++) { - parameter const & a_type = parameters[k_i+4 + 2*r]; - if (a_type.is_int()) { - int tid_prime = a_type.get_int(); - SASSERT(!szs[tid_prime].is_infinite() && !szs[tid_prime].is_very_big()); - c_num *= rational(szs[tid_prime].size(),rational::ui64()); - } - else { - SASSERT(a_type.is_ast()); - sort * ty = to_sort(a_type.get_ast()); - SASSERT(!ty->is_infinite() && !ty->is_very_big()); - c_num *= rational(ty->get_num_elements().size(), rational::ui64()); - } - } - num += c_num; - } - szs[tid] = sort_size(num); + return m_manager->is_value(arg); + } + } + + bool plugin::is_value(app * e) const { + TRACE("dt_is_value", tout << "checking\n" << mk_ismt2_pp(e, *m_manager) << "\n";); + if (!u().is_constructor(e)) + return false; + if (e->get_num_args() == 0) + return true; + // REMARK: if the following check is too expensive, we should + // cache the values in the decl::plugin. + ptr_buffer todo; + // potentially expensive check for common sub-expressions. + for (expr* arg : *e) { + if (!is_value_visit(arg, todo)) { + TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(arg, *m_manager) << "\n";); + return false; + } + } + while (!todo.empty()) { + app * curr = todo.back(); + SASSERT(u().is_constructor(curr)); + todo.pop_back(); + for (expr* arg : *curr) { + if (!is_value_visit(arg, todo)) { + TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(arg, *m_manager) << "\n";); + return false; + } + } + } + return true; + } + + void plugin::get_op_names(svector & op_names, symbol const & logic) { + op_names.push_back(builtin_name("is", OP_DT_IS)); + if (logic == symbol::null) { + op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD)); } } - } - return szs[top_tid]; -} -/** - \brief Return true if the inductive datatype is well-founded. - Pre-condition: The given argument constains the parameters of an inductive datatype. -*/ -static bool is_well_founded(parameter const * parameters) { - unsigned num_types = parameters[0].get_int(); - buffer well_founded(num_types, false); - unsigned num_well_founded = 0; - bool changed; - do { - changed = false; - for (unsigned tid = 0; tid < num_types; tid++) { - if (!well_founded[tid]) { - unsigned o = datatype_decl_plugin::constructor_offset(parameters, tid); // constructor offset - unsigned num_constructors = parameters[o].get_int(); - for (unsigned s = 1; s <= num_constructors; s++) { - unsigned k_i = parameters[o + s].get_int(); - unsigned num_accessors = parameters[k_i + 2].get_int(); - unsigned r = 0; - for (; r < num_accessors; r++) { - parameter const & a_type = parameters[k_i + 4 + 2*r]; - if (a_type.is_int() && !well_founded[a_type.get_int()]) { + expr * plugin::get_some_value(sort * s) { + SASSERT(u().is_datatype(s)); + func_decl * c = u().get_non_rec_constructor(s); + ptr_buffer args; + for (unsigned i = 0; i < c->get_arity(); i++) { + args.push_back(m_manager->get_some_value(c->get_domain(i))); + } + return m_manager->mk_app(c, args.size(), args.c_ptr()); + } + + bool plugin::is_fully_interp(sort * s) const { + return u().is_fully_interp(s); + } + } + + sort_ref_vector util::datatype_params(sort * s) const { + SASSERT(is_datatype(s)); + sort_ref_vector result(m); + for (unsigned i = 1; i < s->get_num_parameters(); ++i) { + result.push_back(to_sort(s->get_parameter(i).get_ast())); + } + return result; + } + + + bool util::is_fully_interp(sort * s) const { + SASSERT(is_datatype(s)); + bool fi = true; + return fi; + if (m_is_fully_interp.find(s, fi)) { + return fi; + } + unsigned sz = m_fully_interp_trail.size(); + m_is_fully_interp.insert(s, true); + def const& d = get_def(s); + bool is_interp = true; + m_fully_interp_trail.push_back(s); + for (constructor const* c : d) { + for (accessor const* a : *c) { + func_decl_ref ac = a->instantiate(s); + sort* r = ac->get_range(); + if (!m.is_fully_interp(r)) { + is_interp = false; + break; + } + } + if (!is_interp) break; + } + for (unsigned i = sz; i < m_fully_interp_trail.size(); ++i) { + m_is_fully_interp.remove(m_fully_interp_trail[i]); + } + m_fully_interp_trail.shrink(sz); + m_is_fully_interp.insert(s, is_interp); + m_asts.push_back(s); + return true; + } + + /** + \brief Return true if the inductive datatype is recursive. + */ + bool util::is_recursive_core(sort* s) const { + obj_map already_found; + ptr_vector todo, subsorts; + todo.push_back(s); + status st; + while (!todo.empty()) { + s = todo.back(); + if (already_found.find(s, st) && st == BLACK) { + todo.pop_back(); + continue; + } + already_found.insert(s, GRAY); + def const& d = get_def(s); + bool can_process = true; + for (constructor const* c : d) { + for (accessor const* a : *c) { + sort* d = a->range(); + // check if d is a datatype sort + subsorts.reset(); + get_subsorts(d, subsorts); + for (sort * s2 : subsorts) { + if (is_datatype(s2)) { + if (already_found.find(s2, st)) { + // type is recursive + if (st == GRAY) return true; + } + else { + todo.push_back(s2); + can_process = false; + } + } + } + } + } + if (can_process) { + already_found.insert(s, BLACK); + todo.pop_back(); + } + } + return false; + } + + unsigned util::get_datatype_num_parameter_sorts(sort * ty) { + SASSERT(ty->get_num_parameters() >= 1); + return ty->get_num_parameters() - 1; + } + + sort* util::get_datatype_parameter_sort(sort * ty, unsigned idx) { + SASSERT(idx < get_datatype_num_parameter_sorts(ty)); + return to_sort(ty->get_parameter(idx+1).get_ast()); + } + + param_size::size* util::get_sort_size(sort_ref_vector const& params, sort* s) { + if (params.empty()) { + return param_size::size::mk_offset(s->get_num_elements()); + } + if (is_datatype(s)) { + param_size::size* sz; + obj_map S; + unsigned n = get_datatype_num_parameter_sorts(s); + for (unsigned i = 0; i < n; ++i) { + sort* ps = get_datatype_parameter_sort(s, i); + sz = get_sort_size(params, ps); + sz->inc_ref(); + S.insert(ps, sz); + } + def & d = get_def(s->get_name()); + sz = d.sort_size()->subst(S); + for (auto & kv : S) { + kv.m_value->dec_ref(); + } + return sz; + } + array_util autil(m); + if (autil.is_array(s)) { + unsigned n = get_array_arity(s); + ptr_vector szs; + for (unsigned i = 0; i < n; ++i) { + szs.push_back(get_sort_size(params, get_array_domain(s, i))); + } + param_size::size* sz1 = param_size::size::mk_times(szs); + param_size::size* sz2 = get_sort_size(params, get_array_range(s)); + return param_size::size::mk_power(sz2, sz1); + } + for (sort* p : params) { + if (s == p) { + sort_ref sr(s, m); + return param_size::size::mk_param(sr); + } + } + return param_size::size::mk_offset(s->get_num_elements()); + } + + bool util::is_declared(sort* s) const { + return m_plugin->is_declared(s); + } + + void util::compute_datatype_size_functions(svector const& names) { + map already_found; + map szs; + + svector todo(names); + status st; + while (!todo.empty()) { + symbol s = todo.back(); + TRACE("datatype", tout << "Sort size for " << s << "\n";); + + if (already_found.find(s, st) && st == BLACK) { + todo.pop_back(); + continue; + } + already_found.insert(s, GRAY); + bool is_infinite = false; + bool can_process = true; + def& d = get_def(s); + for (constructor const* c : d) { + for (accessor const* a : *c) { + sort* r = a->range(); + if (is_datatype(r)) { + symbol s2 = r->get_name(); + if (already_found.find(s2, st)) { + // type is infinite + if (st == GRAY) { + is_infinite = true; + } + } + else if (names.contains(s2)) { + todo.push_back(s2); + can_process = false; + } + } + } + } + if (!can_process) { + continue; + } + todo.pop_back(); + already_found.insert(s, BLACK); + if (is_infinite) { + d.set_sort_size(param_size::size::mk_offset(sort_size::mk_infinite())); + continue; + } + + ptr_vector s_add; + for (constructor const* c : d) { + ptr_vector s_mul; + for (accessor const* a : *c) { + s_mul.push_back(get_sort_size(d.params(), a->range())); + } + s_add.push_back(param_size::size::mk_times(s_mul)); + } + d.set_sort_size(param_size::size::mk_plus(s_add)); + } + } + + + /** + \brief Return true if the inductive datatype is well-founded. + Pre-condition: The given argument constains the parameters of an inductive datatype. + */ + bool util::is_well_founded(unsigned num_types, sort* const* sorts) { + buffer well_founded(num_types, false); + obj_map sort2id; + for (unsigned i = 0; i < num_types; ++i) { + sort2id.insert(sorts[i], i); + } + unsigned num_well_founded = 0, id = 0; + bool changed; + do { + changed = false; + for (unsigned tid = 0; tid < num_types; tid++) { + if (well_founded[tid]) { + continue; + } + sort* s = sorts[tid]; + def const& d = get_def(s); + for (constructor const* c : d) { + bool found_nonwf = false; + for (accessor const* a : *c) { + if (sort2id.find(a->range(), id) && !well_founded[id]) { + found_nonwf = true; break; } } - if (r == num_accessors) { + if (!found_nonwf) { changed = true; well_founded[tid] = true; num_well_founded++; @@ -333,759 +715,358 @@ static bool is_well_founded(parameter const * parameters) { } } } - } - } while(changed && num_well_founded < num_types); - unsigned tid = parameters[1].get_int(); - return well_founded[tid]; -} - -datatype_decl_plugin::~datatype_decl_plugin() { - SASSERT(m_util.get() == 0); -} - -void datatype_decl_plugin::finalize() { - m_util = 0; // force deletion -} - -datatype_util & datatype_decl_plugin::get_util() const { - SASSERT(m_manager); - if (m_util.get() == 0) { - m_util = alloc(datatype_util, *m_manager); + } + while(changed && num_well_founded < num_types); + return num_well_founded == num_types; } - return *(m_util.get()); -} - -sort * datatype_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { - try { - if (k != DATATYPE_SORT) { - throw invalid_datatype(); - } - buffer found; - unsigned num_types = read_int(num_parameters, parameters, 0, found); - if (num_types == 0) { - throw invalid_datatype(); - } - unsigned tid = read_int(num_parameters, parameters, 1, found); - unsigned num_sort_params = read_int(num_parameters, parameters, 2, found); - for (unsigned j = 0; j < num_sort_params; ++j) { - read_sort(num_parameters, parameters, 3 + j, found); - } - unsigned c_offset = constructor_offset(parameters); - for (unsigned j = 0; j < num_types; j++) { - read_symbol(num_parameters, parameters, c_offset + 2*j, found); // type name - unsigned o = read_int(num_parameters, parameters, c_offset + 2*j + 1, found); - unsigned num_constructors = read_int(num_parameters, parameters, o, found); - if (num_constructors == 0) { - throw invalid_datatype(); + def const& util::get_def(sort* s) const { + return m_plugin->get_def(s); + } + + void util::get_subsorts(sort* s, ptr_vector& sorts) const { + sorts.push_back(s); + for (unsigned i = 0; i < s->get_num_parameters(); ++i) { + parameter const& p = s->get_parameter(i); + if (p.is_ast() && is_sort(p.get_ast())) { + get_subsorts(to_sort(p.get_ast()), sorts); } - for (unsigned s = 1; s <= num_constructors; s++) { - unsigned k_i = read_int(num_parameters, parameters, o + s, found); - read_symbol(num_parameters, parameters, k_i, found); // constructor name - read_symbol(num_parameters, parameters, k_i + 1, found); // recognizer name - unsigned num_accessors = read_int(num_parameters, parameters, k_i + 2, found); - unsigned first_accessor = k_i+3; - for (unsigned r = 0; r < num_accessors; r++) { - read_symbol(num_parameters, parameters, first_accessor + 2*r, found); // accessor name - parameter const & a_type = read(num_parameters, parameters, first_accessor + 2*r + 1, found); // accessort type - if (!a_type.is_int() && !a_type.is_ast()) { - throw invalid_datatype(); - } - if (a_type.is_ast() && !is_sort(a_type.get_ast())) { - throw invalid_datatype(); - } + } + } + + + util::util(ast_manager & m): + m(m), + m_family_id(m.mk_family_id("datatype")), + m_asts(m), + m_start(0) { + m_plugin = dynamic_cast(m.get_plugin(m_family_id)); + SASSERT(m_plugin); + } + + util::~util() { + std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); + } + + ptr_vector const * util::get_datatype_constructors(sort * ty) { + SASSERT(is_datatype(ty)); + ptr_vector * r = 0; + if (m_datatype2constructors.find(ty, r)) + return r; + r = alloc(ptr_vector); + m_asts.push_back(ty); + m_vectors.push_back(r); + m_datatype2constructors.insert(ty, r); + def const& d = get_def(ty); + for (constructor const* c : d) { + func_decl_ref f = c->instantiate(ty); + m_asts.push_back(f); + r->push_back(f); + } + return r; + } + + ptr_vector const * util::get_constructor_accessors(func_decl * con) { + SASSERT(is_constructor(con)); + ptr_vector * res = 0; + if (m_constructor2accessors.find(con, res)) { + return res; + } + res = alloc(ptr_vector); + m_asts.push_back(con); + m_vectors.push_back(res); + m_constructor2accessors.insert(con, res); + sort * datatype = con->get_range(); + def const& d = get_def(datatype); + for (constructor const* c : d) { + if (c->name() == con->get_name()) { + for (accessor const* a : *c) { + func_decl_ref fn = a->instantiate(datatype); + res->push_back(fn); + m_asts.push_back(fn); } + break; } } - // check if there is no garbage - if (found.size() != num_parameters || std::find(found.begin(), found.end(), false) != found.end()) { - throw invalid_datatype(); - } + return res; + } - if (!is_well_founded(parameters)) { - m_manager->raise_exception("datatype is not well-founded"); - return 0; - } - - // compute datatype size - sort_size ts = get_datatype_size(parameters); - symbol const & tname = parameters[c_offset + 2*tid].get_symbol(); - return m_manager->mk_sort(tname, - sort_info(m_family_id, k, ts, num_parameters, parameters, true)); - } - catch (invalid_datatype) { - m_manager->raise_exception("invalid datatype"); - return 0; - } -} - -static sort * get_other_datatype(ast_manager & m, family_id datatype_fid, sort * source_datatype, unsigned tid) { - SASSERT(source_datatype->get_family_id() == datatype_fid); - SASSERT(source_datatype->get_decl_kind() == DATATYPE_SORT); - if (tid == static_cast(source_datatype->get_parameter(1).get_int())) { - return source_datatype; - } - buffer p; - unsigned n = source_datatype->get_num_parameters(); - for (unsigned i = 0; i < n; i++) { - p.push_back(source_datatype->get_parameter(i)); - } - p[1] = parameter(tid); - return m.mk_sort(datatype_fid, DATATYPE_SORT, n, p.c_ptr()); -} - -static sort * get_type(ast_manager & m, family_id datatype_fid, sort * source_datatype, parameter const & p) { - SASSERT(p.is_ast() || p.is_int()); - if (p.is_ast()) { - return to_sort(p.get_ast()); - } - else { - return get_other_datatype(m, datatype_fid, source_datatype, p.get_int()); - } -} - -func_decl * datatype_decl_plugin::mk_update_field( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - decl_kind k = OP_DT_UPDATE_FIELD; - ast_manager& m = *m_manager; - - if (num_parameters != 1 || !parameters[0].is_ast()) { - m.raise_exception("invalid parameters for datatype field update"); - return 0; - } - if (arity != 2) { - m.raise_exception("invalid number of arguments for datatype field update"); - return 0; - } - func_decl* acc = 0; - if (is_func_decl(parameters[0].get_ast())) { - acc = to_func_decl(parameters[0].get_ast()); - } - if (acc && !get_util().is_accessor(acc)) { - acc = 0; - } - if (!acc) { - m.raise_exception("datatype field update requires a datatype accessor as the second argument"); - return 0; - } - sort* dom = acc->get_domain(0); - sort* rng = acc->get_range(); - if (dom != domain[0]) { - m.raise_exception("first argument to field update should be a data-type"); - return 0; - } - if (rng != domain[1]) { - std::ostringstream buffer; - buffer << "second argument to field update should be " << mk_ismt2_pp(rng, m) - << " instead of " << mk_ismt2_pp(domain[1], m); - m.raise_exception(buffer.str().c_str()); - return 0; - } - range = domain[0]; - func_decl_info info(m_family_id, k, num_parameters, parameters); - return m.mk_func_decl(symbol("update-field"), arity, domain, range, info); -} - -func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - - if (k == OP_DT_UPDATE_FIELD) { - return mk_update_field(num_parameters, parameters, arity, domain, range); - } - if (num_parameters < 2 || !parameters[0].is_ast() || !is_sort(parameters[0].get_ast())) { - m_manager->raise_exception("invalid parameters for datatype operator"); - return 0; - } - sort * datatype = to_sort(parameters[0].get_ast()); - if (datatype->get_family_id() != m_family_id || - datatype->get_decl_kind() != DATATYPE_SORT) { - m_manager->raise_exception("invalid parameters for datatype operator"); - return 0; - } - for (unsigned i = 1; i < num_parameters; i++) { - if (!parameters[i].is_int()) { - m_manager->raise_exception("invalid parameters for datatype operator"); - return 0; - } - } - unsigned c_idx = parameters[1].get_int(); - unsigned tid = datatype->get_parameter(1).get_int(); - unsigned o = datatype_decl_plugin::constructor_offset(datatype, tid); - unsigned num_constructors = datatype->get_parameter(o).get_int(); - if (c_idx >= num_constructors) { - m_manager->raise_exception("invalid parameters for datatype operator"); - return 0; - } - unsigned k_i = datatype->get_parameter(o + 1 + c_idx).get_int(); - - switch (k) { - case OP_DT_CONSTRUCTOR: - if (num_parameters != 2) { - m_manager->raise_exception("invalid parameters for datatype constructor"); - return 0; - } - else { - symbol c_name = datatype->get_parameter(k_i).get_symbol(); - unsigned num_accessors = datatype->get_parameter(k_i + 2).get_int(); - if (num_accessors != arity) { - m_manager->raise_exception("invalid domain size for datatype constructor"); - return 0; + func_decl * util::get_constructor_recognizer(func_decl * con) { + SASSERT(is_constructor(con)); + func_decl * d = 0; + if (m_constructor2recognizer.find(con, d)) + return d; + sort * datatype = con->get_range(); + def const& dd = get_def(datatype); + symbol r; + for (constructor const* c : dd) { + if (c->name() == con->get_name()) { + r = c->recognizer(); } + } + parameter ps[2] = { parameter(con), parameter(r) }; + d = m.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 2, ps, 1, &datatype); + SASSERT(d); + m_asts.push_back(con); + m_asts.push_back(d); + m_constructor2recognizer.insert(con, d); + return d; + } - // - // the reference count to domain could be 0. - // we need to ensure that creating a temporary - // copy of the same type causes a free. - // - sort_ref_vector domain_check(*m_manager); + func_decl * util::get_recognizer_constructor(func_decl * recognizer) const { + SASSERT(is_recognizer(recognizer)); + return to_func_decl(recognizer->get_parameter(0).get_ast()); + } - for (unsigned r = 0; r < num_accessors; r++) { - sort_ref ty(*m_manager); - ty = get_type(*m_manager, m_family_id, datatype, datatype->get_parameter(k_i + 4 + 2*r)); - domain_check.push_back(ty); - if (ty != domain[r]) { - m_manager->raise_exception("invalid domain for datatype constructor"); - return 0; + bool util::is_recursive(sort * ty) { + SASSERT(is_datatype(ty)); + bool r = false; + if (!m_is_recursive.find(ty, r)) { + r = is_recursive_core(ty); + m_is_recursive.insert(ty, r); + m_asts.push_back(ty); + } + return r; + } + + bool util::is_enum_sort(sort* s) { + if (!is_datatype(s)) { + return false; + } + bool r = false; + if (m_is_enum.find(s, r)) + return r; + ptr_vector const& cnstrs = *get_datatype_constructors(s); + r = true; + for (unsigned i = 0; r && i < cnstrs.size(); ++i) { + r = cnstrs[i]->get_arity() == 0; + } + m_is_enum.insert(s, r); + m_asts.push_back(s); + return r; + } + + func_decl * util::get_accessor_constructor(func_decl * accessor) { + SASSERT(is_accessor(accessor)); + func_decl * r = 0; + if (m_accessor2constructor.find(accessor, r)) + return r; + sort * datatype = accessor->get_domain(0); + symbol c_id = accessor->get_parameter(1).get_symbol(); + def const& d = get_def(datatype); + func_decl_ref fn(m); + for (constructor const* c : d) { + if (c->name() == c_id) { + fn = c->instantiate(datatype); + break; + } + } + r = fn; + m_accessor2constructor.insert(accessor, r); + m_asts.push_back(accessor); + m_asts.push_back(r); + return r; + } + + + void util::reset() { + m_datatype2constructors.reset(); + m_datatype2nonrec_constructor.reset(); + m_constructor2accessors.reset(); + m_constructor2recognizer.reset(); + m_recognizer2constructor.reset(); + m_accessor2constructor.reset(); + m_is_recursive.reset(); + m_is_enum.reset(); + std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); + m_vectors.reset(); + m_asts.reset(); + ++m_start; + } + + + /** + \brief Return a constructor mk(T_1, ... T_n) + where each T_i is not a datatype or it is a datatype that contains + a constructor that will not contain directly or indirectly an element of the given sort. + */ + func_decl * util::get_non_rec_constructor(sort * ty) { + SASSERT(is_datatype(ty)); + func_decl * r = 0; + if (m_datatype2nonrec_constructor.find(ty, r)) + return r; + r = 0; + ptr_vector forbidden_set; + forbidden_set.push_back(ty); + TRACE("util_bug", tout << "invoke get-non-rec: " << sort_ref(ty, m) << "\n";); + r = get_non_rec_constructor_core(ty, forbidden_set); + SASSERT(forbidden_set.back() == ty); + SASSERT(r); + m_asts.push_back(ty); + m_asts.push_back(r); + m_datatype2nonrec_constructor.insert(ty, r); + return r; + } + + /** + \brief Return a constructor mk(T_1, ..., T_n) where + each T_i is not a datatype or it is a datatype t not in forbidden_set, + and get_non_rec_constructor_core(T_i, forbidden_set union { T_i }) + */ + func_decl * util::get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set) { + // We must select a constructor c(T_1, ..., T_n):T such that + // 1) T_i's are not recursive + // If there is no such constructor, then we select one that + // 2) each type T_i is not recursive or contains a constructor that does not depend on T + + ptr_vector const& constructors = *get_datatype_constructors(ty); + unsigned sz = constructors.size(); + TRACE("util_bug", tout << "get-non-rec constructor: " << sort_ref(ty, m) << "\n"; + tout << "forbidden: "; + for (sort* s : forbidden_set) tout << sort_ref(s, m) << " "; + tout << "\n"; + tout << "constructors: " << sz << "\n"; + for (func_decl* f : constructors) tout << func_decl_ref(f, m) << "\n"; + ); + // step 1) + unsigned start = ++m_start; + for (unsigned j = 0; j < sz; ++j) { + func_decl * c = constructors[(j + start) % sz]; + TRACE("util_bug", tout << "checking " << sort_ref(ty, m) << ": " << func_decl_ref(c, m) << "\n";); + unsigned num_args = c->get_arity(); + unsigned i = 0; + for (; i < num_args && !is_datatype(c->get_domain(i)); i++); + if (i == num_args) { + TRACE("util_bug", tout << "found non-rec " << func_decl_ref(c, m) << "\n";); + return c; + } + } + // step 2) + for (unsigned j = 0; j < sz; ++j) { + func_decl * c = constructors[(j + start) % sz]; + TRACE("util_bug", tout << "non_rec_constructor c: " << j << " " << func_decl_ref(c, m) << "\n";); + unsigned num_args = c->get_arity(); + unsigned i = 0; + for (; i < num_args; i++) { + sort * T_i = c->get_domain(i); + TRACE("util_bug", tout << "c: " << i << " " << sort_ref(T_i, m) << "\n";); + if (!is_datatype(T_i)) { + TRACE("util_bug", tout << sort_ref(T_i, m) << " is not a datatype\n";); + continue; } + if (std::find(forbidden_set.begin(), forbidden_set.end(), T_i) != forbidden_set.end()) { + TRACE("util_bug", tout << sort_ref(T_i, m) << " is in forbidden_set\n";); + break; + } + forbidden_set.push_back(T_i); + func_decl * nested_c = get_non_rec_constructor_core(T_i, forbidden_set); + SASSERT(forbidden_set.back() == T_i); + forbidden_set.pop_back(); + if (nested_c == 0) + break; + TRACE("util_bug", tout << "nested_c: " << nested_c->get_name() << "\n";); + } + if (i == num_args) + return c; + } + return 0; + } + unsigned util::get_constructor_idx(func_decl * f) const { + unsigned idx = 0; + def const& d = get_def(f->get_range()); + for (constructor* c : d) { + if (c->name() == f->get_name()) { + return idx; } - func_decl_info info(m_family_id, k, num_parameters, parameters); - info.m_private_parameters = true; - SASSERT(info.private_parameters()); - return m_manager->mk_func_decl(c_name, arity, domain, datatype, info); + ++idx; } - case OP_DT_RECOGNISER: - if (num_parameters != 2 || arity != 1 || domain[0] != datatype) { - m_manager->raise_exception("invalid parameters for datatype recogniser"); - return 0; - } - else { - symbol r_name = datatype->get_parameter(k_i + 1).get_symbol(); - sort * b = m_manager->mk_bool_sort(); - func_decl_info info(m_family_id, k, num_parameters, parameters); - info.m_private_parameters = true; - SASSERT(info.private_parameters()); - return m_manager->mk_func_decl(r_name, arity, domain, b, info); - } - case OP_DT_ACCESSOR: - if (num_parameters != 3 || arity != 1 || domain[0] != datatype) { - m_manager->raise_exception("invalid parameters for datatype accessor"); - return 0; - } - else { - unsigned a_idx = parameters[2].get_int(); - unsigned num_accessors = datatype->get_parameter(k_i + 2).get_int(); - if (a_idx >= num_accessors) { - m_manager->raise_exception("invalid datatype accessor"); - return 0; - } - symbol a_name = datatype->get_parameter(k_i + 3 + 2*a_idx).get_symbol(); - sort * a_type = get_type(*m_manager, m_family_id, datatype, datatype->get_parameter(k_i + 4 + 2*a_idx)); - func_decl_info info(m_family_id, k, num_parameters, parameters); - info.m_private_parameters = true; - SASSERT(info.private_parameters()); - return m_manager->mk_func_decl(a_name, arity, domain, a_type, info); - } - break; - case OP_DT_UPDATE_FIELD: UNREACHABLE(); return 0; - default: - m_manager->raise_exception("invalid datatype operator kind"); - return 0; } -} -bool datatype_decl_plugin::mk_datatypes(unsigned num_datatypes, datatype_decl * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_types) { - buffer p; - p.push_back(parameter(num_datatypes)); - p.push_back(parameter(-1)); - p.push_back(parameter(num_params)); - for (unsigned i = 0; i < num_params; ++i) { - p.push_back(parameter(sort_params[i])); + unsigned util::get_recognizer_constructor_idx(func_decl * f) const { + return get_constructor_idx(get_recognizer_constructor(f)); } - - unsigned c_offset = constructor_offset(p.c_ptr()); - for (unsigned i = 0; i < num_datatypes; i++) { - p.push_back(parameter(datatypes[i]->get_name())); - p.push_back(parameter(-1)); // offset is unknown at this point - } - for (unsigned i = 0; i < num_datatypes; i++) { - p[c_offset + 1 + 2*i] = parameter(p.size()); // save offset to constructor table - ptr_vector const & constructors = datatypes[i]->get_constructors(); - unsigned num_constructors = constructors.size(); - p.push_back(parameter(num_constructors)); - for (unsigned j = 0; j < num_constructors; j++) { - p.push_back(parameter(-1)); // offset is unknown at this point + + /** + \brief Two datatype sorts s1 and s2 are siblings if they were + defined together in the same mutually recursive definition. + */ + bool util::are_siblings(sort * s1, sort * s2) { + if (!is_datatype(s1) || !is_datatype(s2)) { + return s1 == s2; + } + else { + return get_def(s1).id() == get_def(s2).id(); } } - for (unsigned i = 0; i < num_datatypes; i++) { - unsigned o = constructor_offset(p.c_ptr(), i); - ptr_vector const & constructors = datatypes[i]->get_constructors(); - unsigned num_constructors = constructors.size(); - for (unsigned j = 0; j < num_constructors; j++) { - p[o+1+j] = parameter(p.size()); // save offset to constructor definition - constructor_decl * c = constructors[j]; - p.push_back(parameter(c->get_name())); - p.push_back(parameter(c->get_recognizer_name())); - ptr_vector const & accessors = c->get_accessors(); - unsigned num_accessors = accessors.size(); - p.push_back(parameter(num_accessors)); - for (unsigned k = 0; k < num_accessors; k++) { - accessor_decl * a = accessors[k]; - p.push_back(parameter(a->get_name())); - type_ref const & ty = a->get_type(); - if (ty.is_idx()) { - if (static_cast(ty.get_idx()) >= num_datatypes) { - TRACE("datatype", tout << "Index out of bounds: " << ty.get_idx() << "\n";); - return false; + + unsigned util::get_datatype_num_constructors(sort * ty) { + def const& d = get_def(ty->get_name()); + return d.constructors().size(); + } + + void util::get_defs(sort* s0, ptr_vector& defs) { + svector mark; + ptr_buffer todo; + todo.push_back(s0); + mark.push_back(s0->get_name()); + while (!todo.empty()) { + sort* s = todo.back(); + todo.pop_back(); + defs.push_back(&m_plugin->get_def(s->get_name())); + def const& d = get_def(s); + for (constructor* c : d) { + for (accessor* a : *c) { + sort* s = a->range(); + if (are_siblings(s0, s) && !mark.contains(s->get_name())) { + mark.push_back(s->get_name()); + todo.push_back(s); } - p.push_back(parameter(ty.get_idx())); - } - else { - p.push_back(parameter(ty.get_sort())); } } } } - for (unsigned i = 0; i < num_datatypes; i++) { - p[1] = parameter(i); - TRACE("datatype", tout << "new datatype parameters:\n"; - for (unsigned j = 0; j < p.size(); j++) { - tout << "p[" << j << "] -> " << p[j] << "\n"; - }); - sort * ty = mk_sort(DATATYPE_SORT, p.size(), p.c_ptr()); - if (ty == 0) { - TRACE("datatype", tout << "Failed to create datatype sort from parameters\n";); - return false; - } - new_types.push_back(ty); - } - return true; -} -expr * datatype_decl_plugin::get_some_value(sort * s) { - SASSERT(s->is_sort_of(m_family_id, DATATYPE_SORT)); - datatype_util & util = get_util(); - func_decl * c = util.get_non_rec_constructor(s); - ptr_buffer args; - for (unsigned i = 0; i < c->get_arity(); i++) { - args.push_back(m_manager->get_some_value(c->get_domain(i))); - } - return m_manager->mk_app(c, args.size(), args.c_ptr()); -} + void util::display_datatype(sort *s0, std::ostream& out) { + ast_mark mark; + ptr_buffer todo; + SASSERT(is_datatype(s0)); + out << s0->get_name() << " where\n"; + todo.push_back(s0); + mark.mark(s0, true); + while (!todo.empty()) { + sort* s = todo.back(); + todo.pop_back(); + out << s->get_name() << " =\n"; -bool datatype_decl_plugin::is_fully_interp(sort * s) const { - SASSERT(s->is_sort_of(m_family_id, DATATYPE_SORT)); - parameter const * parameters = s->get_parameters(); - unsigned num_types = parameters[0].get_int(); - for (unsigned tid = 0; tid < num_types; tid++) { - unsigned o = datatype_decl_plugin::constructor_offset(s, tid); - unsigned num_constructors = parameters[o].get_int(); - for (unsigned si = 1; si <= num_constructors; si++) { - unsigned k_i = parameters[o + si].get_int(); - unsigned num_accessors = parameters[k_i + 2].get_int(); - unsigned r = 0; - for (; r < num_accessors; r++) { - parameter const & a_type = parameters[k_i + 4 + 2*r]; - if (a_type.is_int()) - continue; - SASSERT(a_type.is_ast()); - sort * arg_s = to_sort(a_type.get_ast()); - if (!m_manager->is_fully_interp(arg_s)) - return false; - } - } - } - return true; -} - -bool datatype_decl_plugin::is_value_visit(expr * arg, ptr_buffer & todo) const { - if (!is_app(arg)) - return false; - family_id fid = to_app(arg)->get_family_id(); - if (fid == m_family_id) { - if (!get_util().is_constructor(to_app(arg))) - return false; - if (to_app(arg)->get_num_args() == 0) - return true; - todo.push_back(to_app(arg)); - return true; - } - else { - return m_manager->is_value(arg); - } -} - -unsigned datatype_decl_plugin::constructor_offset(sort const* s) { - return constructor_offset(s->get_parameters()); -} - -unsigned datatype_decl_plugin::constructor_offset(parameter const& p) { - return 3 + p.get_int(); -} - -unsigned datatype_decl_plugin::constructor_offset(parameter const* ps) { - return constructor_offset(ps[2]); -} - -unsigned datatype_decl_plugin::constructor_offset(sort const* s, unsigned tid) { - unsigned c_offset = constructor_offset(s->get_parameters()); - return s->get_parameter(c_offset + 1 + 2*tid).get_int(); -} - -unsigned datatype_decl_plugin::constructor_offset(parameter const* ps, unsigned tid) { - unsigned c_offset = constructor_offset(ps[2]); - return ps[c_offset + 1 + 2*tid].get_int(); -} - -bool datatype_decl_plugin::is_value(app * e) const { - TRACE("dt_is_value", tout << "checking\n" << mk_ismt2_pp(e, *m_manager) << "\n";); - if (!get_util().is_constructor(e)) - return false; - if (e->get_num_args() == 0) - return true; - // REMARK: if the following check is too expensive, we should - // cache the values in the datatype_decl_plugin. - ptr_buffer todo; - // potentially expensive check for common sub-expressions. - for (unsigned i = 0; i < e->get_num_args(); i++) { - if (!is_value_visit(e->get_arg(i), todo)) { - TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(e->get_arg(i), *m_manager) << "\n";); - return false; - } - } - while (!todo.empty()) { - app * curr = todo.back(); - SASSERT(get_util().is_constructor(curr)); - todo.pop_back(); - for (unsigned i = 0; i < curr->get_num_args(); i++) { - if (!is_value_visit(curr->get_arg(i), todo)) { - TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(curr->get_arg(i), *m_manager) << "\n";); - return false; - } - } - } - return true; -} - -void datatype_decl_plugin::get_op_names(svector & op_names, symbol const & logic) { - if (logic == symbol::null) { - op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD)); - } -} - - -datatype_util::datatype_util(ast_manager & m): - m_manager(m), - m_family_id(m.mk_family_id("datatype")), - m_asts(m), - m_start(0) { -} - -datatype_util::~datatype_util() { - std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); -} - -func_decl * datatype_util::get_constructor(sort * ty, unsigned c_id) { - unsigned tid = ty->get_parameter(1).get_int(); - unsigned o = datatype_decl_plugin::constructor_offset(ty, tid); - unsigned k_i = ty->get_parameter(o + c_id + 1).get_int(); - unsigned num_accessors = ty->get_parameter(k_i + 2).get_int(); - parameter p[2] = { parameter(ty), parameter(c_id) }; - ptr_buffer domain; - for (unsigned r = 0; r < num_accessors; r++) { - domain.push_back(get_type(m_manager, m_family_id, ty, ty->get_parameter(k_i + 4 + 2*r))); - } - func_decl * d = m_manager.mk_func_decl(m_family_id, OP_DT_CONSTRUCTOR, 2, p, domain.size(), domain.c_ptr()); - SASSERT(d); - return d; -} - -ptr_vector const * datatype_util::get_datatype_constructors(sort * ty) { - SASSERT(is_datatype(ty)); - ptr_vector * r = 0; - if (m_datatype2constructors.find(ty, r)) - return r; - r = alloc(ptr_vector); - m_asts.push_back(ty); - m_vectors.push_back(r); - m_datatype2constructors.insert(ty, r); - unsigned tid = ty->get_parameter(1).get_int(); - unsigned o = datatype_decl_plugin::constructor_offset(ty, tid); - unsigned num_constructors = ty->get_parameter(o).get_int(); - for (unsigned c_id = 0; c_id < num_constructors; c_id++) { - func_decl * c = get_constructor(ty, c_id); - m_asts.push_back(c); - r->push_back(c); - } - return r; -} - -/** - \brief Return a constructor mk(T_1, ... T_n) - where each T_i is not a datatype or it is a datatype that contains - a constructor that will not contain directly or indirectly an element of the given sort. -*/ -func_decl * datatype_util::get_non_rec_constructor(sort * ty) { - SASSERT(is_datatype(ty)); - func_decl * r = 0; - if (m_datatype2nonrec_constructor.find(ty, r)) - return r; - r = 0; - ptr_vector forbidden_set; - forbidden_set.push_back(ty); - r = get_non_rec_constructor_core(ty, forbidden_set); - SASSERT(forbidden_set.back() == ty); - SASSERT(r); - m_asts.push_back(ty); - m_asts.push_back(r); - m_datatype2nonrec_constructor.insert(ty, r); - return r; -} - -/** - \brief Return a constructor mk(T_1, ..., T_n) where - each T_i is not a datatype or it is a datatype t not in forbidden_set, - and get_non_rec_constructor_core(T_i, forbidden_set union { T_i }) -*/ -func_decl * datatype_util::get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set) { - // We must select a constructor c(T_1, ..., T_n):T such that - // 1) T_i's are not recursive - // If there is no such constructor, then we select one that - // 2) each type T_i is not recursive or contains a constructor that does not depend on T - ptr_vector const & constructors = *get_datatype_constructors(ty); - // step 1) - unsigned sz = constructors.size(); - unsigned start = ++m_start; - for (unsigned j = 0; j < sz; ++j) { - func_decl * c = constructors[(j + start) % sz]; - unsigned num_args = c->get_arity(); - unsigned i = 0; - for (; i < num_args && !is_datatype(c->get_domain(i)); i++) {}; - if (i == num_args) - return c; - } - // step 2) - for (unsigned j = 0; j < sz; ++j) { - func_decl * c = (*constructors)[(j + start) % sz]; - TRACE("datatype_util_bug", tout << "non_rec_constructor c: " << c->get_name() << "\n";); - unsigned num_args = c->get_arity(); - unsigned i = 0; - for (; i < num_args; i++) { - sort * T_i = c->get_domain(i); - TRACE("datatype_util_bug", tout << "c: " << c->get_name() << " i: " << i << " T_i: " << T_i->get_name() << "\n";); - if (!is_datatype(T_i)) { - TRACE("datatype_util_bug", tout << "T_i is not a datatype\n";); - continue; - } - if (std::find(forbidden_set.begin(), forbidden_set.end(), T_i) != forbidden_set.end()) { - TRACE("datatype_util_bug", tout << "T_i is in forbidden_set\n";); - break; - } - forbidden_set.push_back(T_i); - func_decl * nested_c = get_non_rec_constructor_core(T_i, forbidden_set); - SASSERT(forbidden_set.back() == T_i); - forbidden_set.pop_back(); - TRACE("datatype_util_bug", tout << "nested_c: " << nested_c->get_name() << "\n";); - if (nested_c == 0) - break; - } - if (i == num_args) - return c; - } - return 0; -} - -func_decl * datatype_util::get_constructor_recognizer(func_decl * constructor) { - SASSERT(is_constructor(constructor)); - func_decl * d = 0; - if (m_constructor2recognizer.find(constructor, d)) - return d; - sort * datatype = constructor->get_range(); - d = m_manager.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 2, constructor->get_parameters(), 1, &datatype); - SASSERT(d); - m_asts.push_back(constructor); - m_asts.push_back(d); - m_constructor2recognizer.insert(constructor, d); - return d; -} - -ptr_vector const * datatype_util::get_constructor_accessors(func_decl * constructor) { - SASSERT(is_constructor(constructor)); - ptr_vector * res = 0; - if (m_constructor2accessors.find(constructor, res)) - return res; - res = alloc(ptr_vector); - m_asts.push_back(constructor); - m_vectors.push_back(res); - m_constructor2accessors.insert(constructor, res); - unsigned c_id = constructor->get_parameter(1).get_int(); - sort * datatype = constructor->get_range(); - unsigned tid = datatype->get_parameter(1).get_int(); - unsigned o = datatype_decl_plugin::constructor_offset(datatype, tid); - unsigned k_i = datatype->get_parameter(o + c_id + 1).get_int(); - unsigned num_accessors = datatype->get_parameter(k_i+2).get_int(); - parameter p[3] = { parameter(datatype), parameter(c_id), parameter(-1) }; - for (unsigned r = 0; r < num_accessors; r++) { - p[2] = parameter(r); - func_decl * d = m_manager.mk_func_decl(m_family_id, OP_DT_ACCESSOR, 3, p, 1, &datatype); - SASSERT(d); - m_asts.push_back(d); - res->push_back(d); - } - return res; -} - -func_decl * datatype_util::get_accessor_constructor(func_decl * accessor) { - SASSERT(is_accessor(accessor)); - func_decl * r = 0; - if (m_accessor2constructor.find(accessor, r)) - return r; - sort * datatype = to_sort(accessor->get_parameter(0).get_ast()); - unsigned c_id = accessor->get_parameter(1).get_int(); - r = get_constructor(datatype, c_id); - m_accessor2constructor.insert(accessor, r); - m_asts.push_back(accessor); - m_asts.push_back(r); - return r; -} - -func_decl * datatype_util::get_recognizer_constructor(func_decl * recognizer) { - SASSERT(is_recognizer(recognizer)); - func_decl * r = 0; - if (m_recognizer2constructor.find(recognizer, r)) - return r; - sort * datatype = to_sort(recognizer->get_parameter(0).get_ast()); - unsigned c_id = recognizer->get_parameter(1).get_int(); - r = get_constructor(datatype, c_id); - m_recognizer2constructor.insert(recognizer, r); - m_asts.push_back(recognizer); - m_asts.push_back(r); - return r; -} - -bool datatype_util::is_recursive(sort * ty) { - SASSERT(is_datatype(ty)); - bool r = false; - if (m_is_recursive.find(ty, r)) - return r; - r = is_recursive_datatype(ty->get_parameters()); - m_is_recursive.insert(ty, r); - m_asts.push_back(ty); - return r; -} - - -bool datatype_util::is_enum_sort(sort* s) { - if (!is_datatype(s)) { - return false; - } - bool r = false; - if (m_is_enum.find(s, r)) - return r; - ptr_vector const& cnstrs = *get_datatype_constructors(s); - r = true; - for (unsigned i = 0; r && i < cnstrs.size(); ++i) { - r = cnstrs[i]->get_arity() == 0; - } - m_is_enum.insert(s, r); - m_asts.push_back(s); - return r; -} - - -void datatype_util::reset() { - m_datatype2constructors.reset(); - m_datatype2nonrec_constructor.reset(); - m_constructor2accessors.reset(); - m_constructor2recognizer.reset(); - m_recognizer2constructor.reset(); - m_accessor2constructor.reset(); - m_is_recursive.reset(); - m_is_enum.reset(); - std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); - m_vectors.reset(); - m_asts.reset(); - ++m_start; -} - -/** - \brief Two datatype sorts s1 and s2 are siblings if they were - defined together in the same mutually recursive definition. -*/ -bool datatype_util::are_siblings(sort * s1, sort * s2) { - SASSERT(is_datatype(s1)); - SASSERT(is_datatype(s2)); - if (s1 == s2) - return true; - if (s1->get_num_parameters() != s2->get_num_parameters()) - return false; - unsigned num_params = s1->get_num_parameters(); - if (s1->get_parameter(0) != s2->get_parameter(0)) - return false; - // position 1 contains the IDX of the datatype in a mutually recursive definition. - for (unsigned i = 2; i < num_params; i++) { - if (s1->get_parameter(i) != s2->get_parameter(i)) - return false; - } - return true; -} - -void datatype_util::display_datatype(sort *s0, std::ostream& strm) { - ast_mark mark; - ptr_buffer todo; - SASSERT(is_datatype(s0)); - strm << s0->get_name() << " where\n"; - todo.push_back(s0); - mark.mark(s0, true); - while (!todo.empty()) { - sort* s = todo.back(); - todo.pop_back(); - strm << s->get_name() << " =\n"; - - ptr_vector const & cnstrs = *get_datatype_constructors(s); - for (unsigned i = 0; i < cnstrs.size(); ++i) { - func_decl* cns = cnstrs[i]; - func_decl* rec = get_constructor_recognizer(cns); - strm << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; - ptr_vector const & accs = *get_constructor_accessors(cns); - for (unsigned j = 0; j < accs.size(); ++j) { - func_decl* acc = accs[j]; - sort* s1 = acc->get_range(); - strm << "(" << acc->get_name() << ": " << s1->get_name() << ") "; - if (is_datatype(s1) && are_siblings(s1, s0) && !mark.is_marked(s1)) { + ptr_vector const& cnstrs = *get_datatype_constructors(s); + for (unsigned i = 0; i < cnstrs.size(); ++i) { + func_decl* cns = cnstrs[i]; + func_decl* rec = get_constructor_recognizer(cns); + out << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; + ptr_vector const & accs = *get_constructor_accessors(cns); + for (unsigned j = 0; j < accs.size(); ++j) { + func_decl* acc = accs[j]; + sort* s1 = acc->get_range(); + out << "(" << acc->get_name() << ": " << s1->get_name() << ") "; + if (is_datatype(s1) && are_siblings(s1, s0) && !mark.is_marked(s1)) { mark.mark(s1, true); todo.push_back(s1); - } + } + } + out << "\n"; } - strm << "\n"; } } - } -bool datatype_util::is_func_decl(datatype_op_kind k, unsigned num_params, parameter const* params, func_decl* f) { - bool eq = - f->get_decl_kind() == k && - f->get_family_id() == m_family_id && - f->get_num_parameters() == num_params; - for (unsigned i = 0; eq && i < num_params; ++i) { - eq = params[i] == f->get_parameter(i); +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort*const* params, unsigned num_constructors, constructor_decl * const * cs) { + datatype::decl::plugin* p = u.get_plugin(); + datatype::def* d = p->mk(n, num_params, params); + for (unsigned i = 0; i < num_constructors; ++i) { + d->add(cs[i]); } - return eq; + return d; } - -bool datatype_util::is_constructor_of(unsigned num_params, parameter const* params, func_decl* f) { - return - num_params == 2 && - m_family_id == f->get_family_id() && - OP_DT_CONSTRUCTOR == f->get_decl_kind() && - 2 == f->get_num_parameters() && - params[0] == f->get_parameter(0) && - params[1] == f->get_parameter(1); -} - - -#endif diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index 840329dda..515ca6e20 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -1,5 +1,5 @@ /*++ -Copyright (c) 2006 Microsoft Corporation +Copyright (c) 2017 Microsoft Corporation Module Name: @@ -11,55 +11,390 @@ Abstract: Author: - Leonardo de Moura (leonardo) 2008-01-09. + Nikolaj Bjorner (nbjorner) 2017-9-1 Revision History: ---*/ -#define DATATYPE_V2 -#ifdef DATATYPE_V2 -#include "ast/datatype_decl_plugin2.h" -#else + rewritten to support SMTLIB-2.6 parameters from + Leonardo de Moura (leonardo) 2008-01-09. +--*/ #ifndef DATATYPE_DECL_PLUGIN_H_ #define DATATYPE_DECL_PLUGIN_H_ - #include "ast/ast.h" -#include "util/tptr.h" #include "util/buffer.h" +#include "util/symbol_table.h" #include "util/obj_hashtable.h" -enum datatype_sort_kind { + +enum sort_kind { DATATYPE_SORT }; -enum datatype_op_kind { +enum op_kind { OP_DT_CONSTRUCTOR, OP_DT_RECOGNISER, - OP_DT_ACCESSOR, + OP_DT_IS, + OP_DT_ACCESSOR, OP_DT_UPDATE_FIELD, LAST_DT_OP }; -/** - \brief Auxiliary class used to declare inductive datatypes. - It may be a sort or an integer. If it is an integer, - then it represents a reference to a recursive type. +namespace datatype { - For example, consider the datatypes - Datatype - Tree = tree(value:Real, children:TreeList) - TreeList = cons_t(first_t:Tree, rest_t:Tree) - | nil_t - End - - The recursive occurrences of Tree and TreeList will have idx 0 and - 1 respectively. + class util; + class def; + class accessor; + class constructor; + + + class accessor { + symbol m_name; + sort_ref m_range; + unsigned m_index; // reference to recursive data-type may only get resolved after all mutually recursive data-types are procssed. + constructor* m_constructor; + public: + accessor(ast_manager& m, symbol const& n, sort* range): + m_name(n), + m_range(range, m), + m_index(UINT_MAX) + {} + accessor(ast_manager& m, symbol const& n, unsigned index): + m_name(n), + m_range(m), + m_index(index) + {} + sort* range() const { return m_range; } + void fix_range(sort_ref_vector const& dts); + symbol const& name() const { return m_name; } + func_decl_ref instantiate(sort_ref_vector const& ps) const; + func_decl_ref instantiate(sort* dt) const; + void attach(constructor* d) { m_constructor = d; } + constructor const& get_constructor() const { return *m_constructor; } + def const& get_def() const; + util& u() const; + accessor* translate(ast_translation& tr); + }; + + class constructor { + symbol m_name; + symbol m_recognizer; + ptr_vector m_accessors; + def* m_def; + public: + constructor(symbol n, symbol const& r): m_name(n), m_recognizer(r) {} + ~constructor(); + void add(accessor* a) { m_accessors.push_back(a); a->attach(this); } + symbol const& name() const { return m_name; } + symbol const& recognizer() const { return m_recognizer; } + ptr_vector const& accessors() const { return m_accessors; } + ptr_vector::const_iterator begin() const { return m_accessors.begin(); } + ptr_vector::const_iterator end() const { return m_accessors.end(); } + ptr_vector::iterator begin() { return m_accessors.begin(); } + ptr_vector::iterator end() { return m_accessors.end(); } + func_decl_ref instantiate(sort_ref_vector const& ps) const; + func_decl_ref instantiate(sort* dt) const; + void attach(def* d) { m_def = d; } + def const& get_def() const { return *m_def; } + util& u() const; + constructor* translate(ast_translation& tr); + }; + + namespace param_size { + class size { + unsigned m_ref; + public: + size(): m_ref(0) {} + virtual ~size() {} + void inc_ref() { ++m_ref; } + void dec_ref() { --m_ref; if (m_ref == 0) dealloc(this); } + static size* mk_offset(sort_size const& s); + static size* mk_param(sort_ref& p); + static size* mk_plus(size* a1, size* a2); + static size* mk_times(size* a1, size* a2); + static size* mk_plus(ptr_vector& szs); + static size* mk_times(ptr_vector& szs); + static size* mk_power(size* a1, size* a2); + + virtual size* subst(obj_map& S) = 0; + virtual sort_size eval(obj_map const& S) = 0; + + }; + struct offset : public size { + sort_size m_offset; + offset(sort_size const& s): m_offset(s) {} + virtual ~offset() {} + virtual size* subst(obj_map& S) { return this; } + virtual sort_size eval(obj_map const& S) { return m_offset; } + }; + struct plus : public size { + size* m_arg1, *m_arg2; + plus(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref();} + virtual ~plus() { m_arg1->dec_ref(); m_arg2->dec_ref(); } + virtual size* subst(obj_map& S) { return mk_plus(m_arg1->subst(S), m_arg2->subst(S)); } + virtual sort_size eval(obj_map const& S) { + sort_size s1 = m_arg1->eval(S); + sort_size s2 = m_arg2->eval(S); + if (s1.is_infinite()) return s1; + if (s2.is_infinite()) return s2; + if (s1.is_very_big()) return s1; + if (s2.is_very_big()) return s2; + rational r = rational(s1.size(), rational::ui64()) + rational(s2.size(), rational::ui64()); + return sort_size(r); + } + }; + struct times : public size { + size* m_arg1, *m_arg2; + times(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } + virtual ~times() { m_arg1->dec_ref(); m_arg2->dec_ref(); } + virtual size* subst(obj_map& S) { return mk_times(m_arg1->subst(S), m_arg2->subst(S)); } + virtual sort_size eval(obj_map const& S) { + sort_size s1 = m_arg1->eval(S); + sort_size s2 = m_arg2->eval(S); + if (s1.is_infinite()) return s1; + if (s2.is_infinite()) return s2; + if (s1.is_very_big()) return s1; + if (s2.is_very_big()) return s2; + rational r = rational(s1.size(), rational::ui64()) * rational(s2.size(), rational::ui64()); + return sort_size(r); + } + }; + struct power : public size { + size* m_arg1, *m_arg2; + power(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } + virtual ~power() { m_arg1->dec_ref(); m_arg2->dec_ref(); } + virtual size* subst(obj_map& S) { return mk_power(m_arg1->subst(S), m_arg2->subst(S)); } + virtual sort_size eval(obj_map const& S) { + sort_size s1 = m_arg1->eval(S); + sort_size s2 = m_arg2->eval(S); + // s1^s2 + if (s1.is_infinite()) return s1; + if (s2.is_infinite()) return s2; + if (s1.is_very_big()) return s1; + if (s2.is_very_big()) return s2; + if (s1.size() == 1) return s1; + if (s2.size() == 1) return s1; + if (s1.size() > (2 << 20) || s2.size() > 10) return sort_size::mk_very_big(); + rational r = ::power(rational(s1.size(), rational::ui64()), static_cast(s2.size())); + return sort_size(r); + } + }; + struct sparam : public size { + sort_ref m_param; + sparam(sort_ref& p): m_param(p) {} + virtual ~sparam() {} + virtual size* subst(obj_map& S) { return S[m_param]; } + virtual sort_size eval(obj_map const& S) { return S[m_param]; } + }; + }; + + class def { + ast_manager& m; + util& m_util; + symbol m_name; + unsigned m_class_id; + param_size::size* m_sort_size; + sort_ref_vector m_params; + mutable sort_ref m_sort; + ptr_vector m_constructors; + public: + def(ast_manager& m, util& u, symbol const& n, unsigned class_id, unsigned num_params, sort * const* params): + m(m), + m_util(u), + m_name(n), + m_class_id(class_id), + m_sort_size(0), + m_params(m, num_params, params), + m_sort(m) + {} + ~def() { + if (m_sort_size) m_sort_size->dec_ref(); + for (constructor* c : m_constructors) dealloc(c); + m_constructors.reset(); + } + void add(constructor* c) { + m_constructors.push_back(c); + c->attach(this); + } + symbol const& name() const { return m_name; } + unsigned id() const { return m_class_id; } + sort_ref instantiate(sort_ref_vector const& ps) const; + ptr_vector const& constructors() const { return m_constructors; } + ptr_vector::const_iterator begin() const { return m_constructors.begin(); } + ptr_vector::const_iterator end() const { return m_constructors.end(); } + ptr_vector::iterator begin() { return m_constructors.begin(); } + ptr_vector::iterator end() { return m_constructors.end(); } + sort_ref_vector const& params() const { return m_params; } + util& u() const { return m_util; } + param_size::size* sort_size() { return m_sort_size; } + void set_sort_size(param_size::size* p) { m_sort_size = p; p->inc_ref(); m_sort = 0; } + def* translate(ast_translation& tr, util& u); + }; + + namespace decl { + + class plugin : public decl_plugin { + mutable scoped_ptr m_util; + map m_defs; + svector m_def_block; + unsigned m_class_id; + util & u() const; + + virtual void inherit(decl_plugin* other_p, ast_translation& tr); + + public: + plugin(): m_class_id(0) {} + virtual ~plugin(); + + virtual void finalize(); + + virtual decl_plugin * mk_fresh() { return alloc(plugin); } + + virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters); + + virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + virtual expr * get_some_value(sort * s); + + virtual bool is_fully_interp(sort * s) const; + + virtual bool is_value(app* e) const; + + virtual bool is_unique_value(app * e) const { return is_value(e); } + + virtual void get_op_names(svector & op_names, symbol const & logic); + + void begin_def_block() { m_class_id++; m_def_block.reset(); } + + void end_def_block(); + + def* mk(symbol const& name, unsigned n, sort * const * params); + + void remove(symbol const& d); + + bool mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts); + + def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); } + def& get_def(symbol const& s) { return *(m_defs[s]); } + bool is_declared(sort* s) const { return m_defs.contains(datatype_name(s)); } + private: + bool is_value_visit(expr * arg, ptr_buffer & todo) const; + + func_decl * mk_update_field( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + func_decl * mk_constructor( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + func_decl * mk_accessor( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + func_decl * mk_recognizer( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + func_decl * mk_is( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + + symbol datatype_name(sort * s) const { + //SASSERT(u().is_datatype(s)); + return s->get_parameter(0).get_symbol(); + } + + }; + } + + class util { + ast_manager & m; + family_id m_family_id; + mutable decl::plugin* m_plugin; + + + obj_map *> m_datatype2constructors; + obj_map m_datatype2nonrec_constructor; + obj_map *> m_constructor2accessors; + obj_map m_constructor2recognizer; + obj_map m_recognizer2constructor; + obj_map m_accessor2constructor; + obj_map m_is_recursive; + obj_map m_is_enum; + mutable obj_map m_is_fully_interp; + mutable ast_ref_vector m_asts; + ptr_vector > m_vectors; + unsigned m_start; + mutable ptr_vector m_fully_interp_trail; + + func_decl * get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set); + + friend class decl::plugin; + + bool is_recursive_core(sort * s) const; + sort_size get_datatype_size(sort* s0); + void compute_datatype_size_functions(svector const& names); + param_size::size* get_sort_size(sort_ref_vector const& params, sort* s); + bool is_well_founded(unsigned num_types, sort* const* sorts); + def& get_def(symbol const& s) { return m_plugin->get_def(s); } + void get_subsorts(sort* s, ptr_vector& sorts) const; + + public: + util(ast_manager & m); + ~util(); + ast_manager & get_manager() const { return m; } + // sort * mk_datatype_sort(symbol const& name, unsigned n, sort* const* params); + bool is_datatype(sort const* s) const { return is_sort_of(s, m_family_id, DATATYPE_SORT); } + bool is_enum_sort(sort* s); + bool is_recursive(sort * ty); + bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); } + bool is_recognizer(func_decl * f) const { return is_recognizer0(f) || is_is(f); } + bool is_recognizer0(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_is(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_IS); } + bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); } + bool is_update_field(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_UPDATE_FIELD); } + bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); } + bool is_recognizer0(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER);} + bool is_is(app * f) const { return is_app_of(f, m_family_id, OP_DT_IS);} + bool is_recognizer(app * f) const { return is_recognizer0(f) || is_is(f); } + bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } + bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } + ptr_vector const * get_datatype_constructors(sort * ty); + unsigned get_datatype_num_constructors(sort * ty); + unsigned get_datatype_num_parameter_sorts(sort * ty); + sort* get_datatype_parameter_sort(sort * ty, unsigned idx); + func_decl * get_non_rec_constructor(sort * ty); + func_decl * get_constructor_recognizer(func_decl * constructor); + ptr_vector const * get_constructor_accessors(func_decl * constructor); + func_decl * get_accessor_constructor(func_decl * accessor); + func_decl * get_recognizer_constructor(func_decl * recognizer) const; + family_id get_family_id() const { return m_family_id; } + bool are_siblings(sort * s1, sort * s2); + bool is_func_decl(op_kind k, unsigned num_params, parameter const* params, func_decl* f); + bool is_constructor_of(unsigned num_params, parameter const* params, func_decl* f); + void reset(); + bool is_declared(sort* s) const; + void display_datatype(sort *s, std::ostream& strm); + bool is_fully_interp(sort * s) const; + sort_ref_vector datatype_params(sort * s) const; + unsigned get_constructor_idx(func_decl * f) const; + unsigned get_recognizer_constructor_idx(func_decl * f) const; + decl::plugin* get_plugin() { return m_plugin; } + void get_defs(sort* s, ptr_vector& defs); + def const& get_def(sort* s) const; + }; + +}; + +typedef datatype::accessor accessor_decl; +typedef datatype::constructor constructor_decl; +typedef datatype::def datatype_decl; +typedef datatype::decl::plugin datatype_decl_plugin; +typedef datatype::util datatype_util; - This is a transient value, it is only used to declare a set of - recursive datatypes. -*/ class type_ref { void * m_data; public: @@ -73,178 +408,29 @@ public: int get_idx() const { return UNBOXINT(m_data); } }; -class accessor_decl; -class constructor_decl; -class datatype_decl; -class datatype_util; +inline accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_ref const & t) { + if (t.is_idx()) { + return alloc(accessor_decl, m, n, t.get_idx()); + } + else { + return alloc(accessor_decl, m, n, t.get_sort()); + } +} + +inline constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * * acs) { + constructor_decl* c = alloc(constructor_decl, n, r); + for (unsigned i = 0; i < num_accessors; ++i) { + c->add(acs[i]); + } + return c; +} + + -accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_ref const & t); -// Remark: the constructor becomes the owner of the accessor_decls -constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * const * acs); // Remark: the datatype becomes the owner of the constructor_decls -datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort * const* params, unsigned num_constructors, constructor_decl * const * cs); -void del_datatype_decl(datatype_decl * d); -void del_datatype_decls(unsigned num, datatype_decl * const * ds); +datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort*const* params, unsigned num_constructors, constructor_decl * const * cs); +inline void del_datatype_decl(datatype_decl * d) {} +inline void del_datatype_decls(unsigned num, datatype_decl * const * ds) {} -class datatype_decl_plugin : public decl_plugin { - mutable scoped_ptr m_util; - datatype_util & get_util() const; -public: - datatype_decl_plugin() {} - - virtual ~datatype_decl_plugin(); - virtual void finalize(); - - virtual decl_plugin * mk_fresh() { return alloc(datatype_decl_plugin); } - - - /** - Contract for sort: - parameters[0] - (int) n - number of recursive types. - parameters[1] - (int) i - index 0..n-1 of which type is defined. - - parameters[2] - (int) p - number of type parameters. - - for j = 0..p-1 - parameters[3 + j] - (sort) s - type parameter - - c_offset := 3 + p - for j in 0..n-1 - parameters[c_offset + 2*j] - (symbol) name of the type - parameters[c_offset + 2*j + 1] - (int) o - offset where the constructors are defined. - - for each offset o at parameters[2 + 2*j + 1] for some j in 0..n-1 - parameters[o] - (int) m - number of constructors - parameters[o+1] - (int) k_1 - offset for constructor definition - ... - parameters[o+m] - (int) k_m - offset for constructor definition - - for each offset k_i at parameters[o+s] for some s in 0..m-1 - parameters[k_i] - (symbol) name of the constructor - parameters[k_i+1] - (symbol) name of the recognizer - parameters[k_i+2] - (int) m' - number of accessors - parameters[k_i+3+2*r] - (symbol) name of the r accessor - parameters[k_i+3+2*r+1] - (int or type_ast) type of the accessor. If integer, then the value must be in [0..n-1], and it - represents an reference to the recursive type. - - The idea with the additional offsets is that - access to relevant constructors and types can be performed using - a few address calculations. - */ - virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters); - - /** - Contract for constructors - parameters[0] - (ast) datatype ast. - parmaeters[1] - (int) constructor idx. - Contract for accessors - parameters[0] - (ast) datatype ast. - parameters[1] - (int) constructor idx. - parameters[2] - (int) accessor idx. - Contract for tester - parameters[0] - (ast) datatype ast. - parameters[1] - (int) constructor idx. - */ - virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - - bool mk_datatypes(unsigned num_datatypes, datatype_decl * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts); - - virtual expr * get_some_value(sort * s); - - virtual bool is_fully_interp(sort * s) const; - - virtual bool is_value(app* e) const; - - virtual bool is_unique_value(app * e) const { return is_value(e); } - - virtual void get_op_names(svector & op_names, symbol const & logic); - - static unsigned constructor_offset(sort const* s); - static unsigned constructor_offset(parameter const& p); - static unsigned constructor_offset(parameter const* ps); - - static unsigned constructor_offset(sort const* s, unsigned tid); - static unsigned constructor_offset(parameter const* ps, unsigned tid); - -private: - bool is_value_visit(expr * arg, ptr_buffer & todo) const; - - func_decl * mk_update_field( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); -}; - -class datatype_util { - ast_manager & m_manager; - family_id m_family_id; - - func_decl * get_constructor(sort * ty, unsigned c_id) const; - - obj_map *> m_datatype2constructors; - obj_map m_datatype2nonrec_constructor; - obj_map *> m_constructor2accessors; - obj_map m_constructor2recognizer; - obj_map m_recognizer2constructor; - obj_map m_accessor2constructor; - obj_map m_is_recursive; - obj_map m_is_enum; - ast_ref_vector m_asts; - ptr_vector > m_vectors; - unsigned m_start; - - func_decl * get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set); - func_decl * get_constructor(sort * ty, unsigned c_id); - -public: - datatype_util(ast_manager & m); - ~datatype_util(); - ast_manager & get_manager() const { return m_manager; } - bool is_datatype(sort * s) const { return is_sort_of(s, m_family_id, DATATYPE_SORT); } - bool is_enum_sort(sort* s); - - bool is_recursive(sort * ty); - bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } - bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); } - bool is_update_field(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_UPDATE_FIELD); } - bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); } - bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } - bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } - ptr_vector const * get_datatype_constructors(sort * ty); - unsigned get_datatype_num_constructors(sort * ty) { - SASSERT(is_datatype(ty)); - unsigned tid = ty->get_parameter(1).get_int(); - unsigned o = datatype_decl_plugin::constructor_offset(ty, tid); - return ty->get_parameter(o).get_int(); - } - unsigned get_datatype_num_parameter_sorts(sort * ty) { - SASSERT(is_datatype(ty)); - return ty->get_parameter(2).get_int(); - } - sort* get_datatype_parameter_sort(sort * ty, unsigned idx) { - SASSERT(is_datatype(ty)); - SASSERT(idx < get_datatype_num_parameter_sorts(ty)); - return to_sort(ty->get_parameter(3 + idx).get_ast()); - } - unsigned get_constructor_idx(func_decl * f) const { SASSERT(is_constructor(f)); return f->get_parameter(1).get_int(); } - unsigned get_recognizer_constructor_idx(func_decl * f) const { SASSERT(is_recognizer(f)); return f->get_parameter(1).get_int(); } - func_decl * get_non_rec_constructor(sort * ty); - func_decl * get_constructor_recognizer(func_decl * constructor); - ptr_vector const * get_constructor_accessors(func_decl * constructor); - func_decl * get_accessor_constructor(func_decl * accessor); - func_decl * get_recognizer_constructor(func_decl * recognizer); - family_id get_family_id() const { return m_family_id; } - bool are_siblings(sort * s1, sort * s2); - bool is_func_decl(datatype_op_kind k, unsigned num_params, parameter const* params, func_decl* f); - bool is_constructor_of(unsigned num_params, parameter const* params, func_decl* f); - void reset(); - void display_datatype(sort *s, std::ostream& strm); - - -}; #endif /* DATATYPE_DECL_PLUGIN_H_ */ - -#endif /* DATATYPE_V2 */ diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp deleted file mode 100644 index 743a08e98..000000000 --- a/src/ast/datatype_decl_plugin2.cpp +++ /dev/null @@ -1,1077 +0,0 @@ -/*++ -Copyright (c) 2017 Microsoft Corporation - -Module Name: - - datatype_decl_plugin.cpp - -Abstract: - - - -Author: - - Nikolaj Bjorner (nbjorner) 2017-9-1 - -Revision History: - ---*/ - -#include "ast/datatype_decl_plugin.h" - -#ifdef DATATYPE_V2 -#include "util/warning.h" -#include "ast/datatype_decl_plugin2.h" -#include "ast/array_decl_plugin.h" -#include "ast/ast_smt2_pp.h" -#include "ast/ast_translation.h" - - -namespace datatype { - - void accessor::fix_range(sort_ref_vector const& dts) { - if (!m_range) { - m_range = dts[m_index]; - } - } - - func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const { - ast_manager& m = ps.get_manager(); - unsigned n = ps.size(); - SASSERT(m_range); - SASSERT(n == get_def().params().size()); - sort_ref range(m.substitute(m_range, n, get_def().params().c_ptr(), ps.c_ptr()), m); - sort_ref src(get_def().instantiate(ps)); - sort* srcs[1] = { src.get() }; - parameter pas[2] = { parameter(name()), parameter(get_constructor().name()) }; - return func_decl_ref(m.mk_func_decl(u().get_family_id(), OP_DT_ACCESSOR, 2, pas, 1, srcs, range), m); - } - - func_decl_ref accessor::instantiate(sort* dt) const { - sort_ref_vector sorts = get_def().u().datatype_params(dt); - return instantiate(sorts); - } - - def const& accessor::get_def() const { return m_constructor->get_def(); } - util& accessor::u() const { return m_constructor->u(); } - accessor* accessor::translate(ast_translation& tr) { - return alloc(accessor, tr.to(), name(), to_sort(tr(m_range.get()))); - } - - constructor::~constructor() { - for (accessor* a : m_accessors) dealloc(a); - m_accessors.reset(); - } - util& constructor::u() const { return m_def->u(); } - - func_decl_ref constructor::instantiate(sort_ref_vector const& ps) const { - ast_manager& m = ps.get_manager(); - sort_ref_vector domain(m); - for (accessor const* a : accessors()) { - domain.push_back(a->instantiate(ps)->get_range()); - } - sort_ref range = get_def().instantiate(ps); - parameter pas[1] = { parameter(name()) }; - return func_decl_ref(m.mk_func_decl(u().get_family_id(), OP_DT_CONSTRUCTOR, 1, pas, domain.size(), domain.c_ptr(), range), m); - } - - func_decl_ref constructor::instantiate(sort* dt) const { - sort_ref_vector sorts = get_def().u().datatype_params(dt); - return instantiate(sorts); - } - - constructor* constructor::translate(ast_translation& tr) { - constructor* result = alloc(constructor, m_name, m_recognizer); - for (accessor* a : *this) { - result->add(a->translate(tr)); - } - return result; - } - - - sort_ref def::instantiate(sort_ref_vector const& sorts) const { - sort_ref s(m); - TRACE("datatype", tout << "instantiate " << m_name << "\n";); - if (!m_sort) { - vector ps; - ps.push_back(parameter(m_name)); - for (sort * s : m_params) ps.push_back(parameter(s)); - m_sort = m.mk_sort(u().get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr()); - } - if (sorts.empty()) { - return m_sort; - } - return sort_ref(m.substitute(m_sort, sorts.size(), m_params.c_ptr(), sorts.c_ptr()), m); - } - - def* def::translate(ast_translation& tr, util& u) { - SASSERT(&u.get_manager() == &tr.to()); - sort_ref_vector ps(tr.to()); - for (sort* p : m_params) { - ps.push_back(to_sort(tr(p))); - } - def* result = alloc(def, tr.to(), u, m_name, m_class_id, ps.size(), ps.c_ptr()); - for (constructor* c : *this) { - result->add(c->translate(tr)); - } - if (m_sort) result->m_sort = to_sort(tr(m_sort.get())); - return result; - } - - enum status { - GRAY, - BLACK - }; - - namespace param_size { - size* size::mk_offset(sort_size const& s) { return alloc(offset, s); } - size* size::mk_param(sort_ref& p) { return alloc(sparam, p); } - size* size::mk_plus(size* a1, size* a2) { return alloc(plus, a1, a2); } - size* size::mk_times(size* a1, size* a2) { return alloc(times, a1, a2); } - size* size::mk_times(ptr_vector& szs) { - if (szs.empty()) return mk_offset(sort_size(1)); - if (szs.size() == 1) return szs[0]; - size* r = szs[0]; - for (unsigned i = 1; i < szs.size(); ++i) { - r = mk_times(r, szs[i]); - } - return r; - } - size* size::mk_plus(ptr_vector& szs) { - if (szs.empty()) return mk_offset(sort_size(0)); - if (szs.size() == 1) return szs[0]; - size* r = szs[0]; - for (unsigned i = 1; i < szs.size(); ++i) { - r = mk_plus(r, szs[i]); - } - return r; - } - size* size::mk_power(size* a1, size* a2) { return alloc(power, a1, a2); } - } - - namespace decl { - - plugin::~plugin() { - finalize(); - } - - void plugin::finalize() { - for (auto& kv : m_defs) { - dealloc(kv.m_value); - } - m_defs.reset(); - m_util = 0; // force deletion - } - - util & plugin::u() const { - SASSERT(m_manager); - SASSERT(m_family_id != null_family_id); - if (m_util.get() == 0) { - m_util = alloc(util, *m_manager); - } - return *(m_util.get()); - } - - void plugin::inherit(decl_plugin* other_p, ast_translation& tr) { - plugin* p = dynamic_cast(other_p); - svector names; - ptr_vector new_defs; - SASSERT(p); - for (auto& kv : p->m_defs) { - def* d = kv.m_value; - if (!m_defs.contains(kv.m_key)) { - names.push_back(kv.m_key); - new_defs.push_back(d->translate(tr, u())); - } - } - for (def* d : new_defs) - m_defs.insert(d->name(), d); - m_class_id = m_defs.size(); - u().compute_datatype_size_functions(names); - } - - - struct invalid_datatype {}; - - sort * plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { - try { - if (k != DATATYPE_SORT) { - TRACE("datatype", tout << "invalid kind parameter to datatype\n";); - throw invalid_datatype(); - } - if (num_parameters < 1) { - TRACE("datatype", tout << "at least one parameter expected to datatype declaration\n";); - throw invalid_datatype(); - } - parameter const & name = parameters[0]; - if (!name.is_symbol()) { - TRACE("datatype", tout << "expected symol parameter at position " << 0 << " got: " << name << "\n";); - throw invalid_datatype(); - } - for (unsigned i = 1; i < num_parameters; ++i) { - parameter const& s = parameters[i]; - if (!s.is_ast() || !is_sort(s.get_ast())) { - TRACE("datatype", tout << "expected sort parameter at position " << i << " got: " << s << "\n";); - throw invalid_datatype(); - } - } - - sort* s = m_manager->mk_sort(name.get_symbol(), - sort_info(m_family_id, k, num_parameters, parameters, true)); - def* d = 0; - if (m_defs.find(s->get_name(), d) && d->sort_size()) { - obj_map S; - for (unsigned i = 0; i + 1 < num_parameters; ++i) { - sort* r = to_sort(parameters[i + 1].get_ast()); - S.insert(d->params()[i], r->get_num_elements()); - } - sort_size ts = d->sort_size()->eval(S); - TRACE("datatype", tout << name << " has size " << ts << "\n";); - s->set_num_elements(ts); - } - else { - TRACE("datatype", tout << "not setting size for " << name << "\n";); - } - return s; - } - catch (invalid_datatype) { - m_manager->raise_exception("invalid datatype"); - return 0; - } - } - - func_decl * plugin::mk_update_field( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - decl_kind k = OP_DT_UPDATE_FIELD; - ast_manager& m = *m_manager; - - if (num_parameters != 1 || !parameters[0].is_ast()) { - m.raise_exception("invalid parameters for datatype field update"); - return 0; - } - if (arity != 2) { - m.raise_exception("invalid number of arguments for datatype field update"); - return 0; - } - func_decl* acc = 0; - if (is_func_decl(parameters[0].get_ast())) { - acc = to_func_decl(parameters[0].get_ast()); - } - if (acc && !u().is_accessor(acc)) { - acc = 0; - } - if (!acc) { - m.raise_exception("datatype field update requires a datatype accessor as the second argument"); - return 0; - } - sort* dom = acc->get_domain(0); - sort* rng = acc->get_range(); - if (dom != domain[0]) { - m.raise_exception("first argument to field update should be a data-type"); - return 0; - } - if (rng != domain[1]) { - std::ostringstream buffer; - buffer << "second argument to field update should be " << mk_ismt2_pp(rng, m) - << " instead of " << mk_ismt2_pp(domain[1], m); - m.raise_exception(buffer.str().c_str()); - return 0; - } - range = domain[0]; - func_decl_info info(m_family_id, k, num_parameters, parameters); - return m.mk_func_decl(symbol("update-field"), arity, domain, range, info); - } - -#define VALIDATE_PARAM(_pred_) if (!(_pred_)) m_manager->raise_exception("invalid parameter to datatype function " #_pred_); - - func_decl * decl::plugin::mk_constructor(unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - ast_manager& m = *m_manager; - VALIDATE_PARAM(num_parameters == 1 && parameters[0].is_symbol() && range && u().is_datatype(range)); - // we blindly trust other conditions are met, including domain types. - symbol name = parameters[0].get_symbol(); - func_decl_info info(m_family_id, OP_DT_CONSTRUCTOR, num_parameters, parameters); - info.m_private_parameters = true; - return m.mk_func_decl(name, arity, domain, range, info); - } - - func_decl * decl::plugin::mk_recognizer(unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort *) { - ast_manager& m = *m_manager; - VALIDATE_PARAM(arity == 1 && num_parameters == 2 && parameters[1].is_symbol() && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); - VALIDATE_PARAM(u().is_datatype(domain[0])); - // blindly trust that parameter is a constructor - sort* range = m_manager->mk_bool_sort(); - func_decl_info info(m_family_id, OP_DT_RECOGNISER, num_parameters, parameters); - info.m_private_parameters = true; - return m.mk_func_decl(symbol(parameters[1].get_symbol()), arity, domain, range, info); - } - - func_decl * decl::plugin::mk_is(unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort *) { - ast_manager& m = *m_manager; - VALIDATE_PARAM(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); - VALIDATE_PARAM(u().is_datatype(domain[0])); - // blindly trust that parameter is a constructor - sort* range = m_manager->mk_bool_sort(); - func_decl_info info(m_family_id, OP_DT_IS, num_parameters, parameters); - info.m_private_parameters = true; - return m.mk_func_decl(symbol("is"), arity, domain, range, info); - } - - func_decl * decl::plugin::mk_accessor(unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) - { - ast_manager& m = *m_manager; - VALIDATE_PARAM(arity == 1 && num_parameters == 2 && parameters[0].is_symbol() && parameters[1].is_symbol()); - VALIDATE_PARAM(u().is_datatype(domain[0])); - SASSERT(range); - func_decl_info info(m_family_id, OP_DT_ACCESSOR, num_parameters, parameters); - info.m_private_parameters = true; - symbol name = parameters[0].get_symbol(); - return m.mk_func_decl(name, arity, domain, range, info); - } - - func_decl * decl::plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - switch (k) { - case OP_DT_CONSTRUCTOR: - return mk_constructor(num_parameters, parameters, arity, domain, range); - case OP_DT_RECOGNISER: - return mk_recognizer(num_parameters, parameters, arity, domain, range); - case OP_DT_IS: - return mk_is(num_parameters, parameters, arity, domain, range); - case OP_DT_ACCESSOR: - return mk_accessor(num_parameters, parameters, arity, domain, range); - case OP_DT_UPDATE_FIELD: - return mk_update_field(num_parameters, parameters, arity, domain, range); - default: - m_manager->raise_exception("invalid datatype operator kind"); - return 0; - } - } - - def* plugin::mk(symbol const& name, unsigned n, sort * const * params) { - ast_manager& m = *m_manager; - return alloc(def, m, u(), name, m_class_id, n, params); - } - - - void plugin::end_def_block() { - ast_manager& m = *m_manager; - - sort_ref_vector sorts(m); - for (symbol const& s : m_def_block) { - def const& d = *m_defs[s]; - sort_ref_vector ps(m); - sorts.push_back(d.instantiate(ps)); - } - for (symbol const& s : m_def_block) { - def& d = *m_defs[s]; - for (constructor* c : d) { - for (accessor* a : *c) { - a->fix_range(sorts); - } - } - } - if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) { - m_manager->raise_exception("datatype is not well-founded"); - } - - u().compute_datatype_size_functions(m_def_block); - for (symbol const& s : m_def_block) { - sort_ref_vector ps(m); - m_defs[s]->instantiate(ps); - } - } - - bool plugin::mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts) { - begin_def_block(); - for (unsigned i = 0; i < num_datatypes; ++i) { - def* d = 0; - TRACE("datatype", tout << "declaring " << datatypes[i]->name() << "\n";); - if (m_defs.find(datatypes[i]->name(), d)) { - TRACE("datatype", tout << "delete previous version for " << datatypes[i]->name() << "\n";); - dealloc(d); - } - m_defs.insert(datatypes[i]->name(), datatypes[i]); - m_def_block.push_back(datatypes[i]->name()); - } - end_def_block(); - sort_ref_vector ps(*m_manager); - for (symbol const& s : m_def_block) { - new_sorts.push_back(m_defs[s]->instantiate(ps)); - } - return true; - } - - void plugin::remove(symbol const& s) { - def* d = 0; - if (m_defs.find(s, d)) dealloc(d); - m_defs.remove(s); - } - - bool plugin::is_value_visit(expr * arg, ptr_buffer & todo) const { - if (!is_app(arg)) - return false; - family_id fid = to_app(arg)->get_family_id(); - if (fid == m_family_id) { - if (!u().is_constructor(to_app(arg))) - return false; - if (to_app(arg)->get_num_args() == 0) - return true; - todo.push_back(to_app(arg)); - return true; - } - else { - return m_manager->is_value(arg); - } - } - - bool plugin::is_value(app * e) const { - TRACE("dt_is_value", tout << "checking\n" << mk_ismt2_pp(e, *m_manager) << "\n";); - if (!u().is_constructor(e)) - return false; - if (e->get_num_args() == 0) - return true; - // REMARK: if the following check is too expensive, we should - // cache the values in the decl::plugin. - ptr_buffer todo; - // potentially expensive check for common sub-expressions. - for (expr* arg : *e) { - if (!is_value_visit(arg, todo)) { - TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(arg, *m_manager) << "\n";); - return false; - } - } - while (!todo.empty()) { - app * curr = todo.back(); - SASSERT(u().is_constructor(curr)); - todo.pop_back(); - for (expr* arg : *curr) { - if (!is_value_visit(arg, todo)) { - TRACE("dt_is_value", tout << "not-value:\n" << mk_ismt2_pp(arg, *m_manager) << "\n";); - return false; - } - } - } - return true; - } - - void plugin::get_op_names(svector & op_names, symbol const & logic) { - op_names.push_back(builtin_name("is", OP_DT_IS)); - if (logic == symbol::null) { - op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD)); - } - } - - expr * plugin::get_some_value(sort * s) { - SASSERT(u().is_datatype(s)); - func_decl * c = u().get_non_rec_constructor(s); - ptr_buffer args; - for (unsigned i = 0; i < c->get_arity(); i++) { - args.push_back(m_manager->get_some_value(c->get_domain(i))); - } - return m_manager->mk_app(c, args.size(), args.c_ptr()); - } - - bool plugin::is_fully_interp(sort * s) const { - return u().is_fully_interp(s); - } - } - - sort_ref_vector util::datatype_params(sort * s) const { - SASSERT(is_datatype(s)); - sort_ref_vector result(m); - for (unsigned i = 1; i < s->get_num_parameters(); ++i) { - result.push_back(to_sort(s->get_parameter(i).get_ast())); - } - return result; - } - - - bool util::is_fully_interp(sort * s) const { - SASSERT(is_datatype(s)); - bool fi = true; - return fi; - if (m_is_fully_interp.find(s, fi)) { - return fi; - } - unsigned sz = m_fully_interp_trail.size(); - m_is_fully_interp.insert(s, true); - def const& d = get_def(s); - bool is_interp = true; - m_fully_interp_trail.push_back(s); - for (constructor const* c : d) { - for (accessor const* a : *c) { - func_decl_ref ac = a->instantiate(s); - sort* r = ac->get_range(); - if (!m.is_fully_interp(r)) { - is_interp = false; - break; - } - } - if (!is_interp) break; - } - for (unsigned i = sz; i < m_fully_interp_trail.size(); ++i) { - m_is_fully_interp.remove(m_fully_interp_trail[i]); - } - m_fully_interp_trail.shrink(sz); - m_is_fully_interp.insert(s, is_interp); - m_asts.push_back(s); - return true; - } - - /** - \brief Return true if the inductive datatype is recursive. - */ - bool util::is_recursive_core(sort* s) const { - obj_map already_found; - ptr_vector todo, subsorts; - todo.push_back(s); - status st; - while (!todo.empty()) { - s = todo.back(); - if (already_found.find(s, st) && st == BLACK) { - todo.pop_back(); - continue; - } - already_found.insert(s, GRAY); - def const& d = get_def(s); - bool can_process = true; - for (constructor const* c : d) { - for (accessor const* a : *c) { - sort* d = a->range(); - // check if d is a datatype sort - subsorts.reset(); - get_subsorts(d, subsorts); - for (sort * s2 : subsorts) { - if (is_datatype(s2)) { - if (already_found.find(s2, st)) { - // type is recursive - if (st == GRAY) return true; - } - else { - todo.push_back(s2); - can_process = false; - } - } - } - } - } - if (can_process) { - already_found.insert(s, BLACK); - todo.pop_back(); - } - } - return false; - } - - unsigned util::get_datatype_num_parameter_sorts(sort * ty) { - SASSERT(ty->get_num_parameters() >= 1); - return ty->get_num_parameters() - 1; - } - - sort* util::get_datatype_parameter_sort(sort * ty, unsigned idx) { - SASSERT(idx < get_datatype_num_parameter_sorts(ty)); - return to_sort(ty->get_parameter(idx+1).get_ast()); - } - - param_size::size* util::get_sort_size(sort_ref_vector const& params, sort* s) { - if (params.empty()) { - return param_size::size::mk_offset(s->get_num_elements()); - } - if (is_datatype(s)) { - param_size::size* sz; - obj_map S; - unsigned n = get_datatype_num_parameter_sorts(s); - for (unsigned i = 0; i < n; ++i) { - sort* ps = get_datatype_parameter_sort(s, i); - sz = get_sort_size(params, ps); - sz->inc_ref(); - S.insert(ps, sz); - } - def & d = get_def(s->get_name()); - sz = d.sort_size()->subst(S); - for (auto & kv : S) { - kv.m_value->dec_ref(); - } - return sz; - } - array_util autil(m); - if (autil.is_array(s)) { - unsigned n = get_array_arity(s); - ptr_vector szs; - for (unsigned i = 0; i < n; ++i) { - szs.push_back(get_sort_size(params, get_array_domain(s, i))); - } - param_size::size* sz1 = param_size::size::mk_times(szs); - param_size::size* sz2 = get_sort_size(params, get_array_range(s)); - return param_size::size::mk_power(sz2, sz1); - } - for (sort* p : params) { - if (s == p) { - sort_ref sr(s, m); - return param_size::size::mk_param(sr); - } - } - return param_size::size::mk_offset(s->get_num_elements()); - } - - bool util::is_declared(sort* s) const { - return m_plugin->is_declared(s); - } - - void util::compute_datatype_size_functions(svector const& names) { - map already_found; - map szs; - - svector todo(names); - status st; - while (!todo.empty()) { - symbol s = todo.back(); - TRACE("datatype", tout << "Sort size for " << s << "\n";); - - if (already_found.find(s, st) && st == BLACK) { - todo.pop_back(); - continue; - } - already_found.insert(s, GRAY); - bool is_infinite = false; - bool can_process = true; - def& d = get_def(s); - for (constructor const* c : d) { - for (accessor const* a : *c) { - sort* r = a->range(); - if (is_datatype(r)) { - symbol s2 = r->get_name(); - if (already_found.find(s2, st)) { - // type is infinite - if (st == GRAY) { - is_infinite = true; - } - } - else if (names.contains(s2)) { - todo.push_back(s2); - can_process = false; - } - } - } - } - if (!can_process) { - continue; - } - todo.pop_back(); - already_found.insert(s, BLACK); - if (is_infinite) { - d.set_sort_size(param_size::size::mk_offset(sort_size::mk_infinite())); - continue; - } - - ptr_vector s_add; - for (constructor const* c : d) { - ptr_vector s_mul; - for (accessor const* a : *c) { - s_mul.push_back(get_sort_size(d.params(), a->range())); - } - s_add.push_back(param_size::size::mk_times(s_mul)); - } - d.set_sort_size(param_size::size::mk_plus(s_add)); - } - } - - - /** - \brief Return true if the inductive datatype is well-founded. - Pre-condition: The given argument constains the parameters of an inductive datatype. - */ - bool util::is_well_founded(unsigned num_types, sort* const* sorts) { - buffer well_founded(num_types, false); - obj_map sort2id; - for (unsigned i = 0; i < num_types; ++i) { - sort2id.insert(sorts[i], i); - } - unsigned num_well_founded = 0, id = 0; - bool changed; - do { - changed = false; - for (unsigned tid = 0; tid < num_types; tid++) { - if (well_founded[tid]) { - continue; - } - sort* s = sorts[tid]; - def const& d = get_def(s); - for (constructor const* c : d) { - bool found_nonwf = false; - for (accessor const* a : *c) { - if (sort2id.find(a->range(), id) && !well_founded[id]) { - found_nonwf = true; - break; - } - } - if (!found_nonwf) { - changed = true; - well_founded[tid] = true; - num_well_founded++; - break; - } - } - } - } - while(changed && num_well_founded < num_types); - return num_well_founded == num_types; - } - - def const& util::get_def(sort* s) const { - return m_plugin->get_def(s); - } - - void util::get_subsorts(sort* s, ptr_vector& sorts) const { - sorts.push_back(s); - for (unsigned i = 0; i < s->get_num_parameters(); ++i) { - parameter const& p = s->get_parameter(i); - if (p.is_ast() && is_sort(p.get_ast())) { - get_subsorts(to_sort(p.get_ast()), sorts); - } - } - } - - - util::util(ast_manager & m): - m(m), - m_family_id(m.mk_family_id("datatype")), - m_asts(m), - m_start(0) { - m_plugin = dynamic_cast(m.get_plugin(m_family_id)); - SASSERT(m_plugin); - } - - util::~util() { - std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); - } - - ptr_vector const * util::get_datatype_constructors(sort * ty) { - SASSERT(is_datatype(ty)); - ptr_vector * r = 0; - if (m_datatype2constructors.find(ty, r)) - return r; - r = alloc(ptr_vector); - m_asts.push_back(ty); - m_vectors.push_back(r); - m_datatype2constructors.insert(ty, r); - def const& d = get_def(ty); - for (constructor const* c : d) { - func_decl_ref f = c->instantiate(ty); - m_asts.push_back(f); - r->push_back(f); - } - return r; - } - - ptr_vector const * util::get_constructor_accessors(func_decl * con) { - SASSERT(is_constructor(con)); - ptr_vector * res = 0; - if (m_constructor2accessors.find(con, res)) { - return res; - } - res = alloc(ptr_vector); - m_asts.push_back(con); - m_vectors.push_back(res); - m_constructor2accessors.insert(con, res); - sort * datatype = con->get_range(); - def const& d = get_def(datatype); - for (constructor const* c : d) { - if (c->name() == con->get_name()) { - for (accessor const* a : *c) { - func_decl_ref fn = a->instantiate(datatype); - res->push_back(fn); - m_asts.push_back(fn); - } - break; - } - } - return res; - } - - func_decl * util::get_constructor_recognizer(func_decl * con) { - SASSERT(is_constructor(con)); - func_decl * d = 0; - if (m_constructor2recognizer.find(con, d)) - return d; - sort * datatype = con->get_range(); - def const& dd = get_def(datatype); - symbol r; - for (constructor const* c : dd) { - if (c->name() == con->get_name()) { - r = c->recognizer(); - } - } - parameter ps[2] = { parameter(con), parameter(r) }; - d = m.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 2, ps, 1, &datatype); - SASSERT(d); - m_asts.push_back(con); - m_asts.push_back(d); - m_constructor2recognizer.insert(con, d); - return d; - } - - func_decl * util::get_recognizer_constructor(func_decl * recognizer) const { - SASSERT(is_recognizer(recognizer)); - return to_func_decl(recognizer->get_parameter(0).get_ast()); - } - - bool util::is_recursive(sort * ty) { - SASSERT(is_datatype(ty)); - bool r = false; - if (!m_is_recursive.find(ty, r)) { - r = is_recursive_core(ty); - m_is_recursive.insert(ty, r); - m_asts.push_back(ty); - } - return r; - } - - bool util::is_enum_sort(sort* s) { - if (!is_datatype(s)) { - return false; - } - bool r = false; - if (m_is_enum.find(s, r)) - return r; - ptr_vector const& cnstrs = *get_datatype_constructors(s); - r = true; - for (unsigned i = 0; r && i < cnstrs.size(); ++i) { - r = cnstrs[i]->get_arity() == 0; - } - m_is_enum.insert(s, r); - m_asts.push_back(s); - return r; - } - - func_decl * util::get_accessor_constructor(func_decl * accessor) { - SASSERT(is_accessor(accessor)); - func_decl * r = 0; - if (m_accessor2constructor.find(accessor, r)) - return r; - sort * datatype = accessor->get_domain(0); - symbol c_id = accessor->get_parameter(1).get_symbol(); - def const& d = get_def(datatype); - func_decl_ref fn(m); - for (constructor const* c : d) { - if (c->name() == c_id) { - fn = c->instantiate(datatype); - break; - } - } - r = fn; - m_accessor2constructor.insert(accessor, r); - m_asts.push_back(accessor); - m_asts.push_back(r); - return r; - } - - - void util::reset() { - m_datatype2constructors.reset(); - m_datatype2nonrec_constructor.reset(); - m_constructor2accessors.reset(); - m_constructor2recognizer.reset(); - m_recognizer2constructor.reset(); - m_accessor2constructor.reset(); - m_is_recursive.reset(); - m_is_enum.reset(); - std::for_each(m_vectors.begin(), m_vectors.end(), delete_proc >()); - m_vectors.reset(); - m_asts.reset(); - ++m_start; - } - - - /** - \brief Return a constructor mk(T_1, ... T_n) - where each T_i is not a datatype or it is a datatype that contains - a constructor that will not contain directly or indirectly an element of the given sort. - */ - func_decl * util::get_non_rec_constructor(sort * ty) { - SASSERT(is_datatype(ty)); - func_decl * r = 0; - if (m_datatype2nonrec_constructor.find(ty, r)) - return r; - r = 0; - ptr_vector forbidden_set; - forbidden_set.push_back(ty); - TRACE("util_bug", tout << "invoke get-non-rec: " << sort_ref(ty, m) << "\n";); - r = get_non_rec_constructor_core(ty, forbidden_set); - SASSERT(forbidden_set.back() == ty); - SASSERT(r); - m_asts.push_back(ty); - m_asts.push_back(r); - m_datatype2nonrec_constructor.insert(ty, r); - return r; - } - - /** - \brief Return a constructor mk(T_1, ..., T_n) where - each T_i is not a datatype or it is a datatype t not in forbidden_set, - and get_non_rec_constructor_core(T_i, forbidden_set union { T_i }) - */ - func_decl * util::get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set) { - // We must select a constructor c(T_1, ..., T_n):T such that - // 1) T_i's are not recursive - // If there is no such constructor, then we select one that - // 2) each type T_i is not recursive or contains a constructor that does not depend on T - - ptr_vector const& constructors = *get_datatype_constructors(ty); - unsigned sz = constructors.size(); - TRACE("util_bug", tout << "get-non-rec constructor: " << sort_ref(ty, m) << "\n"; - tout << "forbidden: "; - for (sort* s : forbidden_set) tout << sort_ref(s, m) << " "; - tout << "\n"; - tout << "constructors: " << sz << "\n"; - for (func_decl* f : constructors) tout << func_decl_ref(f, m) << "\n"; - ); - // step 1) - unsigned start = ++m_start; - for (unsigned j = 0; j < sz; ++j) { - func_decl * c = constructors[(j + start) % sz]; - TRACE("util_bug", tout << "checking " << sort_ref(ty, m) << ": " << func_decl_ref(c, m) << "\n";); - unsigned num_args = c->get_arity(); - unsigned i = 0; - for (; i < num_args && !is_datatype(c->get_domain(i)); i++); - if (i == num_args) { - TRACE("util_bug", tout << "found non-rec " << func_decl_ref(c, m) << "\n";); - return c; - } - } - // step 2) - for (unsigned j = 0; j < sz; ++j) { - func_decl * c = constructors[(j + start) % sz]; - TRACE("util_bug", tout << "non_rec_constructor c: " << j << " " << func_decl_ref(c, m) << "\n";); - unsigned num_args = c->get_arity(); - unsigned i = 0; - for (; i < num_args; i++) { - sort * T_i = c->get_domain(i); - TRACE("util_bug", tout << "c: " << i << " " << sort_ref(T_i, m) << "\n";); - if (!is_datatype(T_i)) { - TRACE("util_bug", tout << sort_ref(T_i, m) << " is not a datatype\n";); - continue; - } - if (std::find(forbidden_set.begin(), forbidden_set.end(), T_i) != forbidden_set.end()) { - TRACE("util_bug", tout << sort_ref(T_i, m) << " is in forbidden_set\n";); - break; - } - forbidden_set.push_back(T_i); - func_decl * nested_c = get_non_rec_constructor_core(T_i, forbidden_set); - SASSERT(forbidden_set.back() == T_i); - forbidden_set.pop_back(); - if (nested_c == 0) - break; - TRACE("util_bug", tout << "nested_c: " << nested_c->get_name() << "\n";); - } - if (i == num_args) - return c; - } - return 0; - } - - unsigned util::get_constructor_idx(func_decl * f) const { - unsigned idx = 0; - def const& d = get_def(f->get_range()); - for (constructor* c : d) { - if (c->name() == f->get_name()) { - return idx; - } - ++idx; - } - UNREACHABLE(); - return 0; - } - - unsigned util::get_recognizer_constructor_idx(func_decl * f) const { - return get_constructor_idx(get_recognizer_constructor(f)); - } - - /** - \brief Two datatype sorts s1 and s2 are siblings if they were - defined together in the same mutually recursive definition. - */ - bool util::are_siblings(sort * s1, sort * s2) { - if (!is_datatype(s1) || !is_datatype(s2)) { - return s1 == s2; - } - else { - return get_def(s1).id() == get_def(s2).id(); - } - } - - unsigned util::get_datatype_num_constructors(sort * ty) { - def const& d = get_def(ty->get_name()); - return d.constructors().size(); - } - - void util::get_defs(sort* s0, ptr_vector& defs) { - svector mark; - ptr_buffer todo; - todo.push_back(s0); - mark.push_back(s0->get_name()); - while (!todo.empty()) { - sort* s = todo.back(); - todo.pop_back(); - defs.push_back(&m_plugin->get_def(s->get_name())); - def const& d = get_def(s); - for (constructor* c : d) { - for (accessor* a : *c) { - sort* s = a->range(); - if (are_siblings(s0, s) && !mark.contains(s->get_name())) { - mark.push_back(s->get_name()); - todo.push_back(s); - } - } - } - } - } - - void util::display_datatype(sort *s0, std::ostream& out) { - ast_mark mark; - ptr_buffer todo; - SASSERT(is_datatype(s0)); - out << s0->get_name() << " where\n"; - todo.push_back(s0); - mark.mark(s0, true); - while (!todo.empty()) { - sort* s = todo.back(); - todo.pop_back(); - out << s->get_name() << " =\n"; - - ptr_vector const& cnstrs = *get_datatype_constructors(s); - for (unsigned i = 0; i < cnstrs.size(); ++i) { - func_decl* cns = cnstrs[i]; - func_decl* rec = get_constructor_recognizer(cns); - out << " " << cns->get_name() << " :: " << rec->get_name() << " :: "; - ptr_vector const & accs = *get_constructor_accessors(cns); - for (unsigned j = 0; j < accs.size(); ++j) { - func_decl* acc = accs[j]; - sort* s1 = acc->get_range(); - out << "(" << acc->get_name() << ": " << s1->get_name() << ") "; - if (is_datatype(s1) && are_siblings(s1, s0) && !mark.is_marked(s1)) { - mark.mark(s1, true); - todo.push_back(s1); - } - } - out << "\n"; - } - } - } -} - -datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort*const* params, unsigned num_constructors, constructor_decl * const * cs) { - datatype::decl::plugin* p = u.get_plugin(); - datatype::def* d = p->mk(n, num_params, params); - for (unsigned i = 0; i < num_constructors; ++i) { - d->add(cs[i]); - } - return d; -} - -#endif diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h deleted file mode 100644 index 364ba9350..000000000 --- a/src/ast/datatype_decl_plugin2.h +++ /dev/null @@ -1,439 +0,0 @@ -/*++ -Copyright (c) 2017 Microsoft Corporation - -Module Name: - - datatype_decl_plugin.h - -Abstract: - - - -Author: - - Nikolaj Bjorner (nbjorner) 2017-9-1 - -Revision History: - - rewritten to support SMTLIB-2.6 parameters from - Leonardo de Moura (leonardo) 2008-01-09. - ---*/ -#ifndef DATATYPE_DECL_PLUGIN2_H_ -#define DATATYPE_DECL_PLUGIN2_H_ - -#include "ast/ast.h" -#include "util/buffer.h" -#include "util/symbol_table.h" -#include "util/obj_hashtable.h" - -#ifdef DATATYPE_V2 - - enum sort_kind { - DATATYPE_SORT - }; - - enum op_kind { - OP_DT_CONSTRUCTOR, - OP_DT_RECOGNISER, - OP_DT_IS, - OP_DT_ACCESSOR, - OP_DT_UPDATE_FIELD, - LAST_DT_OP - }; - -namespace datatype { - - class util; - class def; - class accessor; - class constructor; - - - class accessor { - symbol m_name; - sort_ref m_range; - unsigned m_index; // reference to recursive data-type may only get resolved after all mutually recursive data-types are procssed. - constructor* m_constructor; - public: - accessor(ast_manager& m, symbol const& n, sort* range): - m_name(n), - m_range(range, m), - m_index(UINT_MAX) - {} - accessor(ast_manager& m, symbol const& n, unsigned index): - m_name(n), - m_range(m), - m_index(index) - {} - sort* range() const { return m_range; } - void fix_range(sort_ref_vector const& dts); - symbol const& name() const { return m_name; } - func_decl_ref instantiate(sort_ref_vector const& ps) const; - func_decl_ref instantiate(sort* dt) const; - void attach(constructor* d) { m_constructor = d; } - constructor const& get_constructor() const { return *m_constructor; } - def const& get_def() const; - util& u() const; - accessor* translate(ast_translation& tr); - }; - - class constructor { - symbol m_name; - symbol m_recognizer; - ptr_vector m_accessors; - def* m_def; - public: - constructor(symbol n, symbol const& r): m_name(n), m_recognizer(r) {} - ~constructor(); - void add(accessor* a) { m_accessors.push_back(a); a->attach(this); } - symbol const& name() const { return m_name; } - symbol const& recognizer() const { return m_recognizer; } - ptr_vector const& accessors() const { return m_accessors; } - ptr_vector::const_iterator begin() const { return m_accessors.begin(); } - ptr_vector::const_iterator end() const { return m_accessors.end(); } - ptr_vector::iterator begin() { return m_accessors.begin(); } - ptr_vector::iterator end() { return m_accessors.end(); } - func_decl_ref instantiate(sort_ref_vector const& ps) const; - func_decl_ref instantiate(sort* dt) const; - void attach(def* d) { m_def = d; } - def const& get_def() const { return *m_def; } - util& u() const; - constructor* translate(ast_translation& tr); - }; - - namespace param_size { - class size { - unsigned m_ref; - public: - size(): m_ref(0) {} - virtual ~size() {} - void inc_ref() { ++m_ref; } - void dec_ref() { --m_ref; if (m_ref == 0) dealloc(this); } - static size* mk_offset(sort_size const& s); - static size* mk_param(sort_ref& p); - static size* mk_plus(size* a1, size* a2); - static size* mk_times(size* a1, size* a2); - static size* mk_plus(ptr_vector& szs); - static size* mk_times(ptr_vector& szs); - static size* mk_power(size* a1, size* a2); - - virtual size* subst(obj_map& S) = 0; - virtual sort_size eval(obj_map const& S) = 0; - - }; - struct offset : public size { - sort_size m_offset; - offset(sort_size const& s): m_offset(s) {} - virtual ~offset() {} - virtual size* subst(obj_map& S) { return this; } - virtual sort_size eval(obj_map const& S) { return m_offset; } - }; - struct plus : public size { - size* m_arg1, *m_arg2; - plus(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref();} - virtual ~plus() { m_arg1->dec_ref(); m_arg2->dec_ref(); } - virtual size* subst(obj_map& S) { return mk_plus(m_arg1->subst(S), m_arg2->subst(S)); } - virtual sort_size eval(obj_map const& S) { - sort_size s1 = m_arg1->eval(S); - sort_size s2 = m_arg2->eval(S); - if (s1.is_infinite()) return s1; - if (s2.is_infinite()) return s2; - if (s1.is_very_big()) return s1; - if (s2.is_very_big()) return s2; - rational r = rational(s1.size(), rational::ui64()) + rational(s2.size(), rational::ui64()); - return sort_size(r); - } - }; - struct times : public size { - size* m_arg1, *m_arg2; - times(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } - virtual ~times() { m_arg1->dec_ref(); m_arg2->dec_ref(); } - virtual size* subst(obj_map& S) { return mk_times(m_arg1->subst(S), m_arg2->subst(S)); } - virtual sort_size eval(obj_map const& S) { - sort_size s1 = m_arg1->eval(S); - sort_size s2 = m_arg2->eval(S); - if (s1.is_infinite()) return s1; - if (s2.is_infinite()) return s2; - if (s1.is_very_big()) return s1; - if (s2.is_very_big()) return s2; - rational r = rational(s1.size(), rational::ui64()) * rational(s2.size(), rational::ui64()); - return sort_size(r); - } - }; - struct power : public size { - size* m_arg1, *m_arg2; - power(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); } - virtual ~power() { m_arg1->dec_ref(); m_arg2->dec_ref(); } - virtual size* subst(obj_map& S) { return mk_power(m_arg1->subst(S), m_arg2->subst(S)); } - virtual sort_size eval(obj_map const& S) { - sort_size s1 = m_arg1->eval(S); - sort_size s2 = m_arg2->eval(S); - // s1^s2 - if (s1.is_infinite()) return s1; - if (s2.is_infinite()) return s2; - if (s1.is_very_big()) return s1; - if (s2.is_very_big()) return s2; - if (s1.size() == 1) return s1; - if (s2.size() == 1) return s1; - if (s1.size() > (2 << 20) || s2.size() > 10) return sort_size::mk_very_big(); - rational r = ::power(rational(s1.size(), rational::ui64()), static_cast(s2.size())); - return sort_size(r); - } - }; - struct sparam : public size { - sort_ref m_param; - sparam(sort_ref& p): m_param(p) {} - virtual ~sparam() {} - virtual size* subst(obj_map& S) { return S[m_param]; } - virtual sort_size eval(obj_map const& S) { return S[m_param]; } - }; - }; - - class def { - ast_manager& m; - util& m_util; - symbol m_name; - unsigned m_class_id; - param_size::size* m_sort_size; - sort_ref_vector m_params; - mutable sort_ref m_sort; - ptr_vector m_constructors; - public: - def(ast_manager& m, util& u, symbol const& n, unsigned class_id, unsigned num_params, sort * const* params): - m(m), - m_util(u), - m_name(n), - m_class_id(class_id), - m_sort_size(0), - m_params(m, num_params, params), - m_sort(m) - {} - ~def() { - if (m_sort_size) m_sort_size->dec_ref(); - for (constructor* c : m_constructors) dealloc(c); - m_constructors.reset(); - } - void add(constructor* c) { - m_constructors.push_back(c); - c->attach(this); - } - symbol const& name() const { return m_name; } - unsigned id() const { return m_class_id; } - sort_ref instantiate(sort_ref_vector const& ps) const; - ptr_vector const& constructors() const { return m_constructors; } - ptr_vector::const_iterator begin() const { return m_constructors.begin(); } - ptr_vector::const_iterator end() const { return m_constructors.end(); } - ptr_vector::iterator begin() { return m_constructors.begin(); } - ptr_vector::iterator end() { return m_constructors.end(); } - sort_ref_vector const& params() const { return m_params; } - util& u() const { return m_util; } - param_size::size* sort_size() { return m_sort_size; } - void set_sort_size(param_size::size* p) { m_sort_size = p; p->inc_ref(); m_sort = 0; } - def* translate(ast_translation& tr, util& u); - }; - - namespace decl { - - class plugin : public decl_plugin { - mutable scoped_ptr m_util; - map m_defs; - svector m_def_block; - unsigned m_class_id; - util & u() const; - - virtual void inherit(decl_plugin* other_p, ast_translation& tr); - - public: - plugin(): m_class_id(0) {} - virtual ~plugin(); - - virtual void finalize(); - - virtual decl_plugin * mk_fresh() { return alloc(plugin); } - - virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters); - - virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - - virtual expr * get_some_value(sort * s); - - virtual bool is_fully_interp(sort * s) const; - - virtual bool is_value(app* e) const; - - virtual bool is_unique_value(app * e) const { return is_value(e); } - - virtual void get_op_names(svector & op_names, symbol const & logic); - - void begin_def_block() { m_class_id++; m_def_block.reset(); } - - void end_def_block(); - - def* mk(symbol const& name, unsigned n, sort * const * params); - - void remove(symbol const& d); - - bool mk_datatypes(unsigned num_datatypes, def * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts); - - def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); } - def& get_def(symbol const& s) { return *(m_defs[s]); } - bool is_declared(sort* s) const { return m_defs.contains(datatype_name(s)); } - private: - bool is_value_visit(expr * arg, ptr_buffer & todo) const; - - func_decl * mk_update_field( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - - func_decl * mk_constructor( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - - func_decl * mk_accessor( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - - func_decl * mk_recognizer( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - - func_decl * mk_is( - unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - - symbol datatype_name(sort * s) const { - //SASSERT(u().is_datatype(s)); - return s->get_parameter(0).get_symbol(); - } - - }; - } - - class util { - ast_manager & m; - family_id m_family_id; - mutable decl::plugin* m_plugin; - - - obj_map *> m_datatype2constructors; - obj_map m_datatype2nonrec_constructor; - obj_map *> m_constructor2accessors; - obj_map m_constructor2recognizer; - obj_map m_recognizer2constructor; - obj_map m_accessor2constructor; - obj_map m_is_recursive; - obj_map m_is_enum; - mutable obj_map m_is_fully_interp; - mutable ast_ref_vector m_asts; - ptr_vector > m_vectors; - unsigned m_start; - mutable ptr_vector m_fully_interp_trail; - - func_decl * get_non_rec_constructor_core(sort * ty, ptr_vector & forbidden_set); - - friend class decl::plugin; - - bool is_recursive_core(sort * s) const; - sort_size get_datatype_size(sort* s0); - void compute_datatype_size_functions(svector const& names); - param_size::size* get_sort_size(sort_ref_vector const& params, sort* s); - bool is_well_founded(unsigned num_types, sort* const* sorts); - def& get_def(symbol const& s) { return m_plugin->get_def(s); } - void get_subsorts(sort* s, ptr_vector& sorts) const; - - public: - util(ast_manager & m); - ~util(); - ast_manager & get_manager() const { return m; } - // sort * mk_datatype_sort(symbol const& name, unsigned n, sort* const* params); - bool is_datatype(sort const* s) const { return is_sort_of(s, m_family_id, DATATYPE_SORT); } - bool is_enum_sort(sort* s); - bool is_recursive(sort * ty); - bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer(func_decl * f) const { return is_recognizer0(f) || is_is(f); } - bool is_recognizer0(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } - bool is_is(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_IS); } - bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); } - bool is_update_field(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_UPDATE_FIELD); } - bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer0(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER);} - bool is_is(app * f) const { return is_app_of(f, m_family_id, OP_DT_IS);} - bool is_recognizer(app * f) const { return is_recognizer0(f) || is_is(f); } - bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } - bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } - ptr_vector const * get_datatype_constructors(sort * ty); - unsigned get_datatype_num_constructors(sort * ty); - unsigned get_datatype_num_parameter_sorts(sort * ty); - sort* get_datatype_parameter_sort(sort * ty, unsigned idx); - func_decl * get_non_rec_constructor(sort * ty); - func_decl * get_constructor_recognizer(func_decl * constructor); - ptr_vector const * get_constructor_accessors(func_decl * constructor); - func_decl * get_accessor_constructor(func_decl * accessor); - func_decl * get_recognizer_constructor(func_decl * recognizer) const; - family_id get_family_id() const { return m_family_id; } - bool are_siblings(sort * s1, sort * s2); - bool is_func_decl(op_kind k, unsigned num_params, parameter const* params, func_decl* f); - bool is_constructor_of(unsigned num_params, parameter const* params, func_decl* f); - void reset(); - bool is_declared(sort* s) const; - void display_datatype(sort *s, std::ostream& strm); - bool is_fully_interp(sort * s) const; - sort_ref_vector datatype_params(sort * s) const; - unsigned get_constructor_idx(func_decl * f) const; - unsigned get_recognizer_constructor_idx(func_decl * f) const; - decl::plugin* get_plugin() { return m_plugin; } - void get_defs(sort* s, ptr_vector& defs); - def const& get_def(sort* s) const; - }; - -}; - -typedef datatype::accessor accessor_decl; -typedef datatype::constructor constructor_decl; -typedef datatype::def datatype_decl; -typedef datatype::decl::plugin datatype_decl_plugin; -typedef datatype::util datatype_util; - -class type_ref { - void * m_data; -public: - type_ref():m_data(TAG(void *, static_cast(0), 1)) {} - type_ref(int idx):m_data(BOXINT(void *, idx)) {} - type_ref(sort * s):m_data(TAG(void *, s, 1)) {} - - bool is_idx() const { return GET_TAG(m_data) == 0; } - bool is_sort() const { return GET_TAG(m_data) == 1; } - sort * get_sort() const { return UNTAG(sort *, m_data); } - int get_idx() const { return UNBOXINT(m_data); } -}; - -inline accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_ref const & t) { - if (t.is_idx()) { - return alloc(accessor_decl, m, n, t.get_idx()); - } - else { - return alloc(accessor_decl, m, n, t.get_sort()); - } -} - -inline constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * * acs) { - constructor_decl* c = alloc(constructor_decl, n, r); - for (unsigned i = 0; i < num_accessors; ++i) { - c->add(acs[i]); - } - return c; -} - - - -// Remark: the datatype becomes the owner of the constructor_decls -datatype_decl * mk_datatype_decl(datatype_util& u, symbol const & n, unsigned num_params, sort*const* params, unsigned num_constructors, constructor_decl * const * cs); -inline void del_datatype_decl(datatype_decl * d) {} -inline void del_datatype_decls(unsigned num, datatype_decl * const * ds) {} - - -#endif /* DATATYPE_DECL_PLUGIN_H_ */ - -#endif /* DATATYPE_V2 */ diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 95a6030f3..7eac1f347 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -355,13 +355,8 @@ psort_dt_decl::psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager & m sort * psort_dt_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { -#ifndef DATATYPE_V2 - UNREACHABLE(); - return 0; -#else SASSERT(n == m_num_params); return m.instantiate_datatype(this, m_name, n, s); -#endif } void psort_dt_decl::display(std::ostream & out) const { @@ -581,7 +576,6 @@ struct datatype_decl_buffer { ~datatype_decl_buffer() { del_datatype_decls(m_buffer.size(), m_buffer.c_ptr()); } }; -#ifdef DATATYPE_V2 sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { sort * r = m.instantiate_datatype(this, m_name, n, s); @@ -615,37 +609,6 @@ sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * return r; } -#else -sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { - SASSERT(m_num_params == n); - sort * r = find(s); - if (r) - return r; - if (m_parent != 0) { - if (m_parent->instantiate(m, s)) { - r = find(s); - SASSERT(r); - return r; - } - } - else { - datatype_decl_buffer dts; - dts.m_buffer.push_back(instantiate_decl(m, s)); - datatype_decl * d_ptr = dts.m_buffer[0]; - sort_ref_vector sorts(m.m()); - bool is_ok = m.get_dt_plugin()->mk_datatypes(1, &d_ptr, m_num_params, s, sorts); - TRACE("pdatatype_decl", tout << "instantiating " << m_name << " is_ok: " << is_ok << "\n";); - if (is_ok) { - r = sorts.get(0); - cache(m, s, r); - m.save_info(r, this, n, s); - m.notify_new_dt(r, this); - return r; - } - } - return 0; -} -#endif void pdatatype_decl::display(std::ostream & out) const { out << "(declare-datatype " << m_name; @@ -666,7 +629,6 @@ void pdatatype_decl::display(std::ostream & out) const { out << ")"; } -#ifdef DATATYPE_V2 bool pdatatype_decl::commit(pdecl_manager& m) { TRACE("datatype", tout << m_name << "\n";); sort_ref_vector ps(m.m()); @@ -683,7 +645,6 @@ bool pdatatype_decl::commit(pdecl_manager& m) { } return is_ok; } -#endif pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m, @@ -714,7 +675,6 @@ bool pdatatypes_decl::fix_missing_refs(symbol & missing) { return true; } -#ifdef DATATYPE_V2 sort* pdecl_manager::instantiate_datatype(psort_decl* p, symbol const& name, unsigned n, sort * const* s) { TRACE("datatype", tout << name << " "; for (unsigned i = 0; i < n; ++i) tout << s[i]->get_name() << " "; tout << "\n";); pdecl_manager& m = *this; @@ -746,28 +706,7 @@ bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) { UNREACHABLE(); return false; } -#else -bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) { - datatype_decl_buffer dts; - for (auto d : m_datatypes) { - dts.m_buffer.push_back(d->instantiate_decl(m, s)); - } - sort_ref_vector sorts(m.m()); - bool is_ok = m.get_dt_plugin()->mk_datatypes(dts.m_buffer.size(), dts.m_buffer.c_ptr(), m_num_params, s, sorts); - if (!is_ok) - return false; - unsigned i = 0; - for (auto d : m_datatypes) { - sort * new_dt = sorts.get(i++); - d->cache(m, s, new_dt); - m.save_info(new_dt, d, m_num_params, s); - m.notify_new_dt(new_dt, d); - } - return true; -} -#endif -#ifdef DATATYPE_V2 bool pdatatypes_decl::commit(pdecl_manager& m) { datatype_decl_buffer dts; for (pdatatype_decl* d : m_datatypes) { @@ -789,7 +728,6 @@ bool pdatatypes_decl::commit(pdecl_manager& m) { } return is_ok; } -#endif struct pdecl_manager::sort_info { psort_decl * m_decl; diff --git a/src/cmd_context/pdecl.h b/src/cmd_context/pdecl.h index bef723380..c72020827 100644 --- a/src/cmd_context/pdecl.h +++ b/src/cmd_context/pdecl.h @@ -241,9 +241,7 @@ public: virtual void display(std::ostream & out) const; bool has_missing_refs(symbol & missing) const; bool has_duplicate_accessors(symbol & repeated) const; -#ifdef DATATYPE_V2 bool commit(pdecl_manager& m); -#endif }; /** @@ -263,10 +261,8 @@ public: pdatatype_decl const * const * children() const { return m_datatypes.c_ptr(); } pdatatype_decl * const * begin() const { return m_datatypes.begin(); } pdatatype_decl * const * end() const { return m_datatypes.end(); } -#ifdef DATATYPE_V2 // commit declaration bool commit(pdecl_manager& m); -#endif }; class new_datatype_eh { diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index a1304a848..681c3d597 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -877,9 +877,7 @@ namespace smt2 { } else if (sz == 1) { check_missing(new_dt_decls[0], line, pos); -#ifdef DATATYPE_V2 new_dt_decls[0]->commit(pm()); -#endif } else { SASSERT(sz > 1); @@ -892,27 +890,9 @@ namespace smt2 { err_msg += "'"; throw parser_exception(err_msg, line, pos); } -#ifndef DATATYPE_V2 - m_ctx.insert_aux_pdecl(dts.get()); -#else dts->commit(pm()); - m_ctx.insert_aux_pdecl(dts.get()); -#endif + m_ctx.insert_aux_pdecl(dts.get()); } -#ifndef DATATYPE_V2 - for (unsigned i = 0; i < sz; i++) { - pdatatype_decl * d = new_dt_decls[i]; - SASSERT(d != 0); - symbol duplicated; - check_duplicate(d, line, pos); - m_ctx.insert(d); - if (d->get_num_params() == 0) { - // if datatype is not parametric... then force instantiation to register accessor, recognizers and constructors... - sort_ref s(m()); - s = d->instantiate(pm(), 0, 0); - } - } -#else for (unsigned i = 0; i < sz; i++) { pdatatype_decl * d = new_dt_decls[i]; symbol duplicated; @@ -922,7 +902,6 @@ namespace smt2 { m_ctx.insert(d); } } -#endif TRACE("declare_datatypes", tout << "i: " << i << " new_dt_decls.size(): " << sz << "\n"; for (unsigned j = 0; j < new_dt_decls.size(); ++j) tout << new_dt_decls[j]->get_name() << "\n";); m_ctx.print_success(); @@ -952,16 +931,7 @@ namespace smt2 { check_missing(d, line, pos); check_duplicate(d, line, pos); -#ifndef DATATYPE_V2 - m_ctx.insert(d); - if (d->get_num_params() == 0) { - // if datatype is not parametric... then force instantiation to register accessor, recognizers and constructors... - sort_ref s(m()); - s = d->instantiate(pm(), 0, 0); - } -#else d->commit(pm()); -#endif check_rparen_next("invalid end of datatype declaration, ')' expected"); m_ctx.print_success(); } From 78be4719086a93c146646aec11f293e5bf40ba14 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 11 Sep 2017 00:00:40 +0200 Subject: [PATCH 271/488] fix OSX build Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/arith_rewriter.h | 1 - src/ast/rewriter/poly_rewriter_def.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/ast/rewriter/arith_rewriter.h b/src/ast/rewriter/arith_rewriter.h index 1bef9a964..95668ea44 100644 --- a/src/ast/rewriter/arith_rewriter.h +++ b/src/ast/rewriter/arith_rewriter.h @@ -56,7 +56,6 @@ class arith_rewriter : public poly_rewriter { bool m_anum_simp; bool m_elim_rem; bool m_eq2ineq; - bool m_process_all_eqs; unsigned m_max_degree; void get_coeffs_gcd(expr * t, numeral & g, bool & first, unsigned & num_consts); diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 39c4a1078..029cf231a 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -1010,7 +1010,6 @@ bool poly_rewriter::is_var_plus_ground(expr * n, bool & inv, var * & v, stop = true; } if (is_ground(arg)) { - TRACE("model_checker_bug", tout << "pushing:\n" << mk_pp(arg, m()) << "\n";); args.push_back(arg); } else if (is_var(arg)) { From d131aba8a9807b20b101cc4797302e4f58d5ab70 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 11 Sep 2017 01:07:25 +0200 Subject: [PATCH 272/488] fix exposed memory leak Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 7 +++++++ src/ast/rewriter/poly_rewriter_def.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index bb81c1eba..c98307ee0 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1714,8 +1714,15 @@ ast * ast_manager::register_node_core(ast * n) { SASSERT(m_ast_table.contains(n)); } + n->m_id = is_decl(n) ? m_decl_id_gen.mk() : m_expr_id_gen.mk(); + static unsigned count = 0; + if (n->m_id == 404) { + ++count; + //if (count == 2) SASSERT(false); + } + TRACE("ast", tout << "Object " << n->m_id << " was created.\n";); TRACE("mk_var_bug", tout << "mk_ast: " << n->m_id << "\n";); // increment reference counters diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index 029cf231a..3bb963a7f 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -686,7 +686,7 @@ br_status poly_rewriter::mk_sub(unsigned num_args, expr * const * args, return BR_DONE; } set_curr_sort(m().get_sort(args[0])); - expr * minus_one = mk_numeral(numeral(-1)); + expr_ref minus_one(mk_numeral(numeral(-1)), m()); ptr_buffer new_args; new_args.push_back(args[0]); for (unsigned i = 1; i < num_args; i++) { From e88487021afb34965bfa54f2f4a2fb3da5e03297 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 11 Sep 2017 14:36:58 +0100 Subject: [PATCH 273/488] Exposed internal FPA func_decl kinds. Added missing FPA simplifications. Fixes #1242. --- src/api/api_ast.cpp | 16 +++---- src/api/z3_api.h | 73 ++++++++++++++++++++++++++----- src/ast/fpa_decl_plugin.h | 2 - src/ast/rewriter/fpa_rewriter.cpp | 28 +++++++++++- src/ast/rewriter/fpa_rewriter.h | 2 + 5 files changed, 97 insertions(+), 24 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index ab93c3cbd..561bfa87b 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -1206,14 +1206,14 @@ extern "C" { case OP_FPA_TO_IEEE_BV: return Z3_OP_FPA_TO_IEEE_BV; case OP_FPA_INTERNAL_MIN_I: return Z3_OP_FPA_MIN_I; case OP_FPA_INTERNAL_MAX_I: return Z3_OP_FPA_MAX_I; - case OP_FPA_INTERNAL_BV2RM: - case OP_FPA_INTERNAL_BVWRAP: - case OP_FPA_INTERNAL_MIN_UNSPECIFIED: - case OP_FPA_INTERNAL_MAX_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED: + case OP_FPA_INTERNAL_BVWRAP: return Z3_OP_FPA_BVWRAP; + case OP_FPA_INTERNAL_BV2RM: return Z3_OP_FPA_BV2RM; + case OP_FPA_INTERNAL_MIN_UNSPECIFIED: return Z3_OP_FPA_MIN_UNSPECIFIED; + case OP_FPA_INTERNAL_MAX_UNSPECIFIED: return Z3_OP_FPA_MAX_UNSPECIFIED; + case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: return Z3_OP_FPA_TO_UBV_UNSPECIFIED; + case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: return Z3_OP_FPA_TO_SBV_UNSPECIFIED; + case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: return Z3_OP_FPA_TO_REAL_UNSPECIFIED; + case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED: return Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED; return Z3_OP_UNINTERPRETED; default: return Z3_OP_INTERNAL; diff --git a/src/api/z3_api.h b/src/api/z3_api.h index bed70cb6c..663a59fd9 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -397,23 +397,23 @@ typedef enum (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) - Z3_OP_BSMUL_NO_OVFL: a predicate to check that bit-wise signed multiplication does not overflow. - Signed multiplication overflows if the operands have the same sign and the result of multiplication + Signed multiplication overflows if the operands have the same sign and the result of multiplication does not fit within the available bits. \sa Z3_mk_bvmul_no_overflow. - Z3_OP_BUMUL_NO_OVFL: check that bit-wise unsigned multiplication does not overflow. Unsigned multiplication overflows if the result does not fit within the available bits. \sa Z3_mk_bvmul_no_overflow. - + - Z3_OP_BSMUL_NO_UDFL: check that bit-wise signed multiplication does not underflow. Signed multiplication underflows if the operands have opposite signs and the result of multiplication does not fit within the avaialble bits. Z3_mk_bvmul_no_underflow. - - - Z3_OP_BSDIV_I: Binary signed division. + + - Z3_OP_BSDIV_I: Binary signed division. It has the same semantics as Z3_OP_BSDIV, but created in a context where the second operand can be assumed to be non-zero. - Z3_OP_BUDIV_I: Binary unsigned division. It has the same semantics as Z3_OP_BUDIV, but created in a context where the second operand can be assumed to be non-zero. - + - Z3_OP_BSREM_I: Binary signed remainder. It has the same semantics as Z3_OP_BSREM, but created in a context where the second operand can be assumed to be non-zero. @@ -979,7 +979,47 @@ typedef enum - Z3_OP_FPA_TO_IEEE_BV: Floating-point conversion to IEEE-754 bit-vector - - Z3_OP_INTERNAL: internal (often interpreted) symbol, but no additional information is exposed. Tools may use the string representation of the function declaration to obtain more information. + - Z3_OP_FPA_BVWRAP: (Implicitly) represents the internal bitvector- + representation of a floating-point term (used for the lazy encoding + of non-relevant terms in theory_fpa) + + - Z3_OP_FPA_BV2RM: Conversion of a 3-bit bit-vector term to a + floating-point rouding-mode term + + The conversion uses the following values: + 0 = 000 = Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN, + 1 = 001 = Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY, + 2 = 010 = Z3_OP_FPA_RM_TOWARD_POSITIVE, + 3 = 011 = Z3_OP_FPA_RM_TOWARD_NEGATIVE, + 4 = 100 = Z3_OP_FPA_RM_TOWARD_ZERO. + + - Z3_OP_FPA_MIN_I: The same as Z3_OP_FPA_MIN, but the arguments are + expected not to be zeroes with different signs. + + - Z3_OP_FPA_MAX_I: The same as Z3_OP_FPA_MAX, but the arguments are + expected not to be zeroes with different signs. + + - Z3_OP_FPA_MIN_UNSPECIFIED: The same as Z3_OP_FPA_MIN, but the + arguments are expected to be zeroes with different signs. + + - Z3_OP_FPA_MAX_UNSPECIFIED: The same as Z3_OP_FPA_MAX, but the + arguments are expected to be zeroes with different signs. + + - Z3_OP_FPA_TO_UBV_UNSPECIFIED: A term representing the unspecified + results of Z3_OP_FPA_TO_UBV. + + - Z3_OP_FPA_TO_SBV_UNSPECIFIED: A term representing the unspecified + results of Z3_OP_FPA_TO_SBV. + + - Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED: A term representing the unspecified + results of Z3_OP_FPA_TO_IEEE_BV. + + - Z3_OP_FPA_TO_REAL_UNSPECIFIED: A term representing the unspecified + results of Z3_OP_FPA_TO_IEEE_BV. + + - Z3_OP_INTERNAL: internal (often interpreted) symbol, but no additional + information is exposed. Tools may use the string representation of the + function declaration to obtain more information. - Z3_OP_UNINTERPRETED: kind used for uninterpreted symbols. */ @@ -1266,6 +1306,15 @@ typedef enum { Z3_OP_FPA_MIN_I, Z3_OP_FPA_MAX_I, + Z3_OP_FPA_BVWRAP, + Z3_OP_FPA_BV2RM, + Z3_OP_FPA_MIN_UNSPECIFIED, + Z3_OP_FPA_MAX_UNSPECIFIED, + Z3_OP_FPA_TO_UBV_UNSPECIFIED, + Z3_OP_FPA_TO_SBV_UNSPECIFIED, + Z3_OP_FPA_TO_REAL_UNSPECIFIED, + Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED, + Z3_OP_INTERNAL, Z3_OP_UNINTERPRETED @@ -3361,7 +3410,7 @@ extern "C" { \brief Convert string to integer. def_API('Z3_mk_str_to_int' ,AST ,(_in(CONTEXT), _in(AST))) - */ + */ Z3_ast Z3_API Z3_mk_str_to_int(Z3_context c, Z3_ast s); @@ -3369,7 +3418,7 @@ extern "C" { \brief Integer to string conversion. def_API('Z3_mk_int_to_str' ,AST ,(_in(CONTEXT), _in(AST))) - */ + */ Z3_ast Z3_API Z3_mk_int_to_str(Z3_context c, Z3_ast s); /** @@ -4859,12 +4908,12 @@ extern "C" { Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a); /** - \brief Create a fresh func_interp object, add it to a model for a specified function. - It has reference count 0. + \brief Create a fresh func_interp object, add it to a model for a specified function. + It has reference count 0. \param c context \param m model - \param f function declaration + \param f function declaration \param default_value default value for function interpretation def_API('Z3_add_func_interp', FUNC_INTERP, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _in(AST))) @@ -4950,7 +4999,7 @@ extern "C" { \param args list of arguments. They should be constant values (such as integers) and be of the same types as the domain of the function. \param value value of the function when the parameters match args. - It is assumed that entries added to a function cover disjoint arguments. + It is assumed that entries added to a function cover disjoint arguments. If an two entries are added with the same arguments, only the second insertion survives and the first inserted entry is removed. diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 0cba3ae62..5d76345f6 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -168,8 +168,6 @@ class fpa_decl_plugin : public decl_plugin { unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_to_ubv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 563437b99..41435818b 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -94,8 +94,8 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(f, args[0], result); break; case OP_FPA_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; - case OP_FPA_INTERNAL_MIN_I: - case OP_FPA_INTERNAL_MAX_I: + case OP_FPA_INTERNAL_MIN_I:SASSERT(num_args == 2); st = mk_min_i(f, args[0], args[1], result); break; + case OP_FPA_INTERNAL_MAX_I: SASSERT(num_args == 2); st = mk_max_i(f, args[0], args[1], result); break; case OP_FPA_INTERNAL_MIN_UNSPECIFIED: case OP_FPA_INTERNAL_MAX_UNSPECIFIED: SASSERT(num_args == 2); st = BR_FAILED; break; @@ -454,6 +454,18 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { } } +br_status fpa_rewriter::mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { + scoped_mpf v1(m_fm), v2(m_fm); + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { + if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) + result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); + else + result = m_util.mk_min(arg1, arg2); + return BR_DONE; + } + return BR_FAILED; +} + br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { if (m_util.is_nan(arg1)) { result = arg2; @@ -489,6 +501,18 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { } } +br_status fpa_rewriter::mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { + scoped_mpf v1(m_fm), v2(m_fm); + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { + if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) + result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); + else + result = m_util.mk_max(arg1, arg2); + return BR_DONE; + } + return BR_FAILED; +} + br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_numeral(arg1, rm)) { diff --git a/src/ast/rewriter/fpa_rewriter.h b/src/ast/rewriter/fpa_rewriter.h index 45710122c..282cec4df 100644 --- a/src/ast/rewriter/fpa_rewriter.h +++ b/src/ast/rewriter/fpa_rewriter.h @@ -85,6 +85,8 @@ public: br_status mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ieee_bv(func_decl * f, expr * arg, expr_ref & result); br_status mk_to_real(expr * arg, expr_ref & result); + br_status mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); + br_status mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned with, expr_ref & result); br_status mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned with, expr_ref & result); From 4ceef091563ef0c5f760ee989d3a9c5cb34cd041 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 11 Sep 2017 15:03:02 +0100 Subject: [PATCH 274/488] Renamed FPA-internal functions now that they are exposed. --- src/api/api_ast.cpp | 20 +++---- src/ast/fpa/fpa2bv_converter.cpp | 16 +++--- src/ast/fpa/fpa2bv_rewriter.cpp | 20 +++---- src/ast/fpa_decl_plugin.cpp | 70 ++++++++++++------------ src/ast/fpa_decl_plugin.h | 91 +++++++++++++++---------------- src/ast/rewriter/fpa_rewriter.cpp | 46 ++++++++-------- src/smt/theory_fpa.cpp | 4 +- src/smt/theory_fpa.h | 5 +- 8 files changed, 135 insertions(+), 137 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index 561bfa87b..cfea4098f 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -1204,16 +1204,16 @@ extern "C" { case OP_FPA_TO_SBV: return Z3_OP_FPA_TO_SBV; case OP_FPA_TO_REAL: return Z3_OP_FPA_TO_REAL; case OP_FPA_TO_IEEE_BV: return Z3_OP_FPA_TO_IEEE_BV; - case OP_FPA_INTERNAL_MIN_I: return Z3_OP_FPA_MIN_I; - case OP_FPA_INTERNAL_MAX_I: return Z3_OP_FPA_MAX_I; - case OP_FPA_INTERNAL_BVWRAP: return Z3_OP_FPA_BVWRAP; - case OP_FPA_INTERNAL_BV2RM: return Z3_OP_FPA_BV2RM; - case OP_FPA_INTERNAL_MIN_UNSPECIFIED: return Z3_OP_FPA_MIN_UNSPECIFIED; - case OP_FPA_INTERNAL_MAX_UNSPECIFIED: return Z3_OP_FPA_MAX_UNSPECIFIED; - case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: return Z3_OP_FPA_TO_UBV_UNSPECIFIED; - case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: return Z3_OP_FPA_TO_SBV_UNSPECIFIED; - case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: return Z3_OP_FPA_TO_REAL_UNSPECIFIED; - case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED: return Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED; + case OP_FPA_MIN_I: return Z3_OP_FPA_MIN_I; + case OP_FPA_MAX_I: return Z3_OP_FPA_MAX_I; + case OP_FPA_BVWRAP: return Z3_OP_FPA_BVWRAP; + case OP_FPA_BV2RM: return Z3_OP_FPA_BV2RM; + case OP_FPA_MIN_UNSPECIFIED: return Z3_OP_FPA_MIN_UNSPECIFIED; + case OP_FPA_MAX_UNSPECIFIED: return Z3_OP_FPA_MAX_UNSPECIFIED; + case OP_FPA_TO_UBV_UNSPECIFIED: return Z3_OP_FPA_TO_UBV_UNSPECIFIED; + case OP_FPA_TO_SBV_UNSPECIFIED: return Z3_OP_FPA_TO_SBV_UNSPECIFIED; + case OP_FPA_TO_REAL_UNSPECIFIED: return Z3_OP_FPA_TO_REAL_UNSPECIFIED; + case OP_FPA_TO_IEEE_BV_UNSPECIFIED: return Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED; return Z3_OP_UNINTERPRETED; default: return Z3_OP_INTERNAL; diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 1a4698fa4..6f0c83df9 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1231,11 +1231,11 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref c(m), v(m); c = m.mk_and(both_are_zero, pn_or_np); - v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, x, y); + v = m.mk_app(m_util.get_family_id(), OP_FPA_MIN_UNSPECIFIED, x, y); // Note: This requires BR_REWRITE_FULL afterwards. expr_ref min_i(m); - min_i = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_I, x, y); + min_i = m.mk_app(m_util.get_family_id(), OP_FPA_MIN_I, x, y); m_simp.mk_ite(c, v, min_i, result); } @@ -1324,11 +1324,11 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref c(m), v(m); c = m.mk_and(both_are_zero, pn_or_np); - v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, x, y); + v = m.mk_app(m_util.get_family_id(), OP_FPA_MAX_UNSPECIFIED, x, y); // Note: This requires BR_REWRITE_FULL afterwards. expr_ref max_i(m); - max_i = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_I, x, y); + max_i = m.mk_app(m_util.get_family_id(), OP_FPA_MAX_I, x, y); m_simp.mk_ite(c, v, max_i, result); } @@ -3160,7 +3160,7 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * m_bv_util.mk_numeral(1, 1)))); else { app_ref unspec(m); - unspec = m_util.mk_internal_to_ieee_bv_unspecified(ebits, sbits); + unspec = m_util.mk_to_ieee_bv_unspecified(ebits, sbits); mk_to_ieee_bv_unspecified(unspec->get_decl(), 0, 0, nanv); } @@ -3402,7 +3402,7 @@ void fpa2bv_converter::mk_to_ubv_unspecified(func_decl * f, unsigned num, expr * expr_ref fpa2bv_converter::mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { expr_ref res(m); app_ref u(m); - u = m_util.mk_internal_to_ubv_unspecified(ebits, sbits, width); + u = m_util.mk_to_ubv_unspecified(ebits, sbits, width); mk_to_sbv_unspecified(u->get_decl(), 0, 0, res); return res; } @@ -3431,7 +3431,7 @@ void fpa2bv_converter::mk_to_sbv_unspecified(func_decl * f, unsigned num, expr * expr_ref fpa2bv_converter::mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { expr_ref res(m); app_ref u(m); - u = m_util.mk_internal_to_sbv_unspecified(ebits, sbits, width); + u = m_util.mk_to_sbv_unspecified(ebits, sbits, width); mk_to_sbv_unspecified(u->get_decl(), 0, 0, res); return res; } @@ -3454,7 +3454,7 @@ void fpa2bv_converter::mk_to_real_unspecified(func_decl * f, unsigned num, expr expr_ref fpa2bv_converter::mk_to_real_unspecified(unsigned ebits, unsigned sbits) { expr_ref res(m); app_ref u(m); - u = m_util.mk_internal_to_real_unspecified(ebits, sbits); + u = m_util.mk_to_real_unspecified(ebits, sbits); mk_to_real_unspecified(u->get_decl(), 0, 0, res); return res; } diff --git a/src/ast/fpa/fpa2bv_rewriter.cpp b/src/ast/fpa/fpa2bv_rewriter.cpp index 0e3899c53..28ec35536 100644 --- a/src/ast/fpa/fpa2bv_rewriter.cpp +++ b/src/ast/fpa/fpa2bv_rewriter.cpp @@ -143,24 +143,24 @@ br_status fpa2bv_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr * co case OP_FPA_TO_FP_UNSIGNED: m_conv.mk_to_fp_unsigned(f, num, args, result); return BR_DONE; case OP_FPA_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; case OP_FPA_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; - case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: m_conv.mk_to_ubv_unspecified(f, num, args, result); return BR_DONE; + case OP_FPA_TO_UBV_UNSPECIFIED: m_conv.mk_to_ubv_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; - case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: m_conv.mk_to_sbv_unspecified(f, num, args, result); return BR_DONE; + case OP_FPA_TO_SBV_UNSPECIFIED: m_conv.mk_to_sbv_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; - case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: m_conv.mk_to_real_unspecified(f, num, args, result); return BR_DONE; + case OP_FPA_TO_REAL_UNSPECIFIED: m_conv.mk_to_real_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; - case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED: m_conv.mk_to_ieee_bv_unspecified(f, num, args, result); return BR_DONE; + case OP_FPA_TO_IEEE_BV_UNSPECIFIED: m_conv.mk_to_ieee_bv_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_REWRITE_FULL; case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_REWRITE_FULL; - case OP_FPA_INTERNAL_MIN_UNSPECIFIED: - case OP_FPA_INTERNAL_MAX_UNSPECIFIED: result = m_conv.mk_min_max_unspecified(f, args[0], args[1]); return BR_DONE; - case OP_FPA_INTERNAL_MIN_I: m_conv.mk_min_i(f, num, args, result); return BR_DONE; - case OP_FPA_INTERNAL_MAX_I: m_conv.mk_max_i(f, num, args, result); return BR_DONE; + case OP_FPA_MIN_UNSPECIFIED: + case OP_FPA_MAX_UNSPECIFIED: result = m_conv.mk_min_max_unspecified(f, args[0], args[1]); return BR_DONE; + case OP_FPA_MIN_I: m_conv.mk_min_i(f, num, args, result); return BR_DONE; + case OP_FPA_MAX_I: m_conv.mk_max_i(f, num, args, result); return BR_DONE; - case OP_FPA_INTERNAL_BVWRAP: - case OP_FPA_INTERNAL_BV2RM: + case OP_FPA_BVWRAP: + case OP_FPA_BV2RM: return BR_FAILED; default: diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index fc69c5f89..c50d6b985 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -361,10 +361,10 @@ func_decl * fpa_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_parameters case OP_FPA_REM: name = "fp.rem"; break; case OP_FPA_MIN: name = "fp.min"; break; case OP_FPA_MAX: name = "fp.max"; break; - case OP_FPA_INTERNAL_MIN_I: name = "fp.min_i"; break; - case OP_FPA_INTERNAL_MAX_I: name = "fp.max_i"; break; - case OP_FPA_INTERNAL_MIN_UNSPECIFIED: name = "fp.min_unspecified"; break; - case OP_FPA_INTERNAL_MAX_UNSPECIFIED: name = "fp.max_unspecified"; break; + case OP_FPA_MIN_I: name = "fp.min_i"; break; + case OP_FPA_MAX_I: name = "fp.max_i"; break; + case OP_FPA_MIN_UNSPECIFIED: name = "fp.min_unspecified"; break; + case OP_FPA_MAX_UNSPECIFIED: name = "fp.max_unspecified"; break; default: UNREACHABLE(); break; @@ -676,10 +676,10 @@ func_decl * fpa_decl_plugin::mk_to_ieee_bv(decl_kind k, unsigned num_parameters, return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k)); } -func_decl * fpa_decl_plugin::mk_internal_bv2rm(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_bv2rm(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) - m_manager->raise_exception("invalid number of arguments to internal_rm"); + m_manager->raise_exception("invalid number of arguments to bv2rm"); if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) || domain[0]->get_parameter(0).get_int() != 3) m_manager->raise_exception("sort mismatch, expected argument of sort bitvector, size 3"); if (!is_rm_sort(range)) @@ -690,7 +690,7 @@ func_decl * fpa_decl_plugin::mk_internal_bv2rm(decl_kind k, unsigned num_paramet return m_manager->mk_func_decl(symbol("rm"), 1, &bv_srt, range, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * fpa_decl_plugin::mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to bv_wrap"); @@ -711,7 +711,7 @@ func_decl * fpa_decl_plugin::mk_internal_bv_wrap(decl_kind k, unsigned num_param } } -func_decl * fpa_decl_plugin::mk_internal_to_ubv_unspecified( +func_decl * fpa_decl_plugin::mk_to_ubv_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 0) @@ -725,7 +725,7 @@ func_decl * fpa_decl_plugin::mk_internal_to_ubv_unspecified( return m_manager->mk_func_decl(symbol("fp.to_ubv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * fpa_decl_plugin::mk_internal_to_sbv_unspecified( +func_decl * fpa_decl_plugin::mk_to_sbv_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 0) @@ -739,7 +739,7 @@ func_decl * fpa_decl_plugin::mk_internal_to_sbv_unspecified( return m_manager->mk_func_decl(symbol("fp.to_sbv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * fpa_decl_plugin::mk_internal_to_real_unspecified( +func_decl * fpa_decl_plugin::mk_to_real_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 0) @@ -754,7 +754,7 @@ func_decl * fpa_decl_plugin::mk_internal_to_real_unspecified( return m_manager->mk_func_decl(symbol("fp.to_real_unspecified"), 0, domain, m_real_sort, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * fpa_decl_plugin::mk_internal_to_ieee_bv_unspecified( +func_decl * fpa_decl_plugin::mk_to_ieee_bv_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 0) @@ -835,25 +835,25 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, case OP_FPA_TO_IEEE_BV: return mk_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_INTERNAL_BVWRAP: - return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_INTERNAL_BV2RM: - return mk_internal_bv2rm(k, num_parameters, parameters, arity, domain, range); + case OP_FPA_BVWRAP: + return mk_bv_wrap(k, num_parameters, parameters, arity, domain, range); + case OP_FPA_BV2RM: + return mk_bv2rm(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_INTERNAL_MIN_I: - case OP_FPA_INTERNAL_MAX_I: - case OP_FPA_INTERNAL_MIN_UNSPECIFIED: - case OP_FPA_INTERNAL_MAX_UNSPECIFIED: + case OP_FPA_MIN_I: + case OP_FPA_MAX_I: + case OP_FPA_MIN_UNSPECIFIED: + case OP_FPA_MAX_UNSPECIFIED: return mk_binary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: - return mk_internal_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: - return mk_internal_to_sbv_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: - return mk_internal_to_real_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED: - return mk_internal_to_ieee_bv_unspecified(k, num_parameters, parameters, arity, domain, range); + case OP_FPA_TO_UBV_UNSPECIFIED: + return mk_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range); + case OP_FPA_TO_SBV_UNSPECIFIED: + return mk_to_sbv_unspecified(k, num_parameters, parameters, arity, domain, range); + case OP_FPA_TO_REAL_UNSPECIFIED: + return mk_to_real_unspecified(k, num_parameters, parameters, arity, domain, range); + case OP_FPA_TO_IEEE_BV_UNSPECIFIED: + return mk_to_ieee_bv_unspecified(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); return 0; @@ -1054,28 +1054,28 @@ app * fpa_util::mk_nzero(unsigned ebits, unsigned sbits) { return mk_value(v); } -app * fpa_util::mk_internal_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { +app * fpa_util::mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { parameter ps[] = { parameter(ebits), parameter(sbits), parameter(width) }; sort * range = m_bv_util.mk_sort(width); - return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED, 3, ps, 0, 0, range); + return m().mk_app(get_family_id(), OP_FPA_TO_UBV_UNSPECIFIED, 3, ps, 0, 0, range); } -app * fpa_util::mk_internal_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { +app * fpa_util::mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { parameter ps[] = { parameter(ebits), parameter(sbits), parameter(width) }; sort * range = m_bv_util.mk_sort(width); - return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED, 3, ps, 0, 0, range); + return m().mk_app(get_family_id(), OP_FPA_TO_SBV_UNSPECIFIED, 3, ps, 0, 0, range); } -app * fpa_util::mk_internal_to_ieee_bv_unspecified(unsigned ebits, unsigned sbits) { +app * fpa_util::mk_to_ieee_bv_unspecified(unsigned ebits, unsigned sbits) { parameter ps[] = { parameter(ebits), parameter(sbits) }; sort * range = m_bv_util.mk_sort(ebits+sbits); - return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED, 2, ps, 0, 0, range); + return m().mk_app(get_family_id(), OP_FPA_TO_IEEE_BV_UNSPECIFIED, 2, ps, 0, 0, range); } -app * fpa_util::mk_internal_to_real_unspecified(unsigned ebits, unsigned sbits) { +app * fpa_util::mk_to_real_unspecified(unsigned ebits, unsigned sbits) { parameter ps[] = { parameter(ebits), parameter(sbits) }; sort * range = m_a_util.mk_real(); - return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED, 2, ps, 0, 0, range); + return m().mk_app(get_family_id(), OP_FPA_TO_REAL_UNSPECIFIED, 2, ps, 0, 0, range); } bool fpa_util::contains_floats(ast * a) { diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 5d76345f6..c78194b63 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -86,18 +86,17 @@ enum fpa_op_kind { /* Extensions */ OP_FPA_TO_IEEE_BV, - /* Internal use only */ - OP_FPA_INTERNAL_BVWRAP, - OP_FPA_INTERNAL_BV2RM, + OP_FPA_BVWRAP, + OP_FPA_BV2RM, - OP_FPA_INTERNAL_MIN_I, - OP_FPA_INTERNAL_MAX_I, - OP_FPA_INTERNAL_MIN_UNSPECIFIED, - OP_FPA_INTERNAL_MAX_UNSPECIFIED, - OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED, - OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED, - OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED, - OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED, + OP_FPA_MIN_I, + OP_FPA_MAX_I, + OP_FPA_MIN_UNSPECIFIED, + OP_FPA_MAX_UNSPECIFIED, + OP_FPA_TO_UBV_UNSPECIFIED, + OP_FPA_TO_SBV_UNSPECIFIED, + OP_FPA_TO_IEEE_BV_UNSPECIFIED, + OP_FPA_TO_REAL_UNSPECIFIED, LAST_FLOAT_OP }; @@ -164,17 +163,17 @@ class fpa_decl_plugin : public decl_plugin { func_decl * mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_bv2rm(decl_kind k, unsigned num_parameters, parameter const * parameters, + func_decl * mk_bv2rm(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, + func_decl * mk_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_to_ubv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, + func_decl * mk_to_ubv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, + func_decl * mk_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_to_real_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, + func_decl * mk_to_real_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_to_ieee_bv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, + func_decl * mk_to_ieee_bv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); virtual void set_manager(ast_manager * m, family_id id); @@ -186,10 +185,10 @@ class fpa_decl_plugin : public decl_plugin { return false; switch (f->get_decl_kind()) { - case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED: + case OP_FPA_TO_UBV_UNSPECIFIED: + case OP_FPA_TO_SBV_UNSPECIFIED: + case OP_FPA_TO_REAL_UNSPECIFIED: + case OP_FPA_TO_IEEE_BV_UNSPECIFIED: return true; default: return false; @@ -373,35 +372,35 @@ public: app * mk_bv2rm(expr * bv3) { SASSERT(m_bv_util.is_bv(bv3) && m_bv_util.get_bv_size(bv3) == 3); - return m().mk_app(m_fid, OP_FPA_INTERNAL_BV2RM, 0, 0, 1, &bv3, mk_rm_sort()); + return m().mk_app(m_fid, OP_FPA_BV2RM, 0, 0, 1, &bv3, mk_rm_sort()); } - app * mk_internal_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width); - app * mk_internal_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width); - app * mk_internal_to_ieee_bv_unspecified(unsigned ebits, unsigned sbits); - app * mk_internal_to_real_unspecified(unsigned ebits, unsigned sbits); + app * mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width); + app * mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width); + app * mk_to_ieee_bv_unspecified(unsigned ebits, unsigned sbits); + app * mk_to_real_unspecified(unsigned ebits, unsigned sbits); - bool is_bvwrap(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_BVWRAP); } - bool is_bvwrap(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_BVWRAP; } - bool is_bv2rm(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_BV2RM); } - bool is_bv2rm(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_BV2RM; } + bool is_bvwrap(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_BVWRAP); } + bool is_bvwrap(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_BVWRAP; } + bool is_bv2rm(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_BV2RM); } + bool is_bv2rm(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_BV2RM; } - bool is_min_interpreted(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_MIN_I); } - bool is_min_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_MIN_UNSPECIFIED); } - bool is_max_interpreted(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_MAX_I); } - bool is_max_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_MAX_UNSPECIFIED); } - bool is_to_ubv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED); } - bool is_to_sbv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED); } - bool is_to_ieee_bv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED); } - bool is_to_real_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED); } + bool is_min_interpreted(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MIN_I); } + bool is_min_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MIN_UNSPECIFIED); } + bool is_max_interpreted(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MAX_I); } + bool is_max_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MAX_UNSPECIFIED); } + bool is_to_ubv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_UBV_UNSPECIFIED); } + bool is_to_sbv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_SBV_UNSPECIFIED); } + bool is_to_ieee_bv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_IEEE_BV_UNSPECIFIED); } + bool is_to_real_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_REAL_UNSPECIFIED); } - bool is_min_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_MIN_I; } - bool is_min_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_MIN_UNSPECIFIED; } - bool is_max_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_MAX_I; } - bool is_max_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_MAX_UNSPECIFIED; } - bool is_to_ubv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED; } - bool is_to_sbv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED; } - bool is_to_ieee_bv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED; } - bool is_to_real_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED; } + bool is_min_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MIN_I; } + bool is_min_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MIN_UNSPECIFIED; } + bool is_max_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MAX_I; } + bool is_max_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MAX_UNSPECIFIED; } + bool is_to_ubv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_UBV_UNSPECIFIED; } + bool is_to_sbv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_SBV_UNSPECIFIED; } + bool is_to_ieee_bv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_IEEE_BV_UNSPECIFIED; } + bool is_to_real_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_REAL_UNSPECIFIED; } bool contains_floats(ast * a); }; diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 41435818b..b31270ce8 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -94,19 +94,19 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(f, args[0], result); break; case OP_FPA_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; - case OP_FPA_INTERNAL_MIN_I:SASSERT(num_args == 2); st = mk_min_i(f, args[0], args[1], result); break; - case OP_FPA_INTERNAL_MAX_I: SASSERT(num_args == 2); st = mk_max_i(f, args[0], args[1], result); break; - case OP_FPA_INTERNAL_MIN_UNSPECIFIED: - case OP_FPA_INTERNAL_MAX_UNSPECIFIED: + case OP_FPA_MIN_I:SASSERT(num_args == 2); st = mk_min_i(f, args[0], args[1], result); break; + case OP_FPA_MAX_I: SASSERT(num_args == 2); st = mk_max_i(f, args[0], args[1], result); break; + case OP_FPA_MIN_UNSPECIFIED: + case OP_FPA_MAX_UNSPECIFIED: SASSERT(num_args == 2); st = BR_FAILED; break; - case OP_FPA_INTERNAL_BVWRAP: SASSERT(num_args == 1); st = mk_bvwrap(args[0], result); break; - case OP_FPA_INTERNAL_BV2RM: SASSERT(num_args == 1); st = mk_bv2rm(args[0], result); break; + case OP_FPA_BVWRAP: SASSERT(num_args == 1); st = mk_bvwrap(args[0], result); break; + case OP_FPA_BV2RM: SASSERT(num_args == 1); st = mk_bv2rm(args[0], result); break; - case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: - case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED: + case OP_FPA_TO_UBV_UNSPECIFIED: + case OP_FPA_TO_SBV_UNSPECIFIED: + case OP_FPA_TO_REAL_UNSPECIFIED: + case OP_FPA_TO_IEEE_BV_UNSPECIFIED: st = BR_FAILED; break; @@ -124,7 +124,7 @@ br_status fpa_rewriter::mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, un return BR_DONE; } else { - result = m_util.mk_internal_to_ubv_unspecified(ebits, sbits, width); + result = m_util.mk_to_ubv_unspecified(ebits, sbits, width); return BR_REWRITE1; } } @@ -137,7 +137,7 @@ br_status fpa_rewriter::mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, un return BR_DONE; } else { - result = m_util.mk_internal_to_sbv_unspecified(ebits, sbits, width); + result = m_util.mk_to_sbv_unspecified(ebits, sbits, width); return BR_REWRITE1; } } @@ -149,7 +149,7 @@ br_status fpa_rewriter::mk_to_real_unspecified(unsigned ebits, unsigned sbits, e return BR_DONE; } else { - result = m_util.mk_internal_to_real_unspecified(ebits, sbits); + result = m_util.mk_to_real_unspecified(ebits, sbits); return BR_REWRITE1; } } @@ -432,7 +432,7 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_fm), v2(m_fm); if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { - result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); + result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); return BR_REWRITE1; } else { @@ -447,9 +447,9 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { c = m().mk_and(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), m().mk_or(m().mk_and(m_util.mk_is_positive(arg1), m_util.mk_is_negative(arg2)), m().mk_and(m_util.mk_is_negative(arg1), m_util.mk_is_positive(arg2)))); - v = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); + v = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); - result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_I, arg1, arg2)); + result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_MIN_I, arg1, arg2)); return BR_REWRITE_FULL; } } @@ -458,7 +458,7 @@ br_status fpa_rewriter::mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_r scoped_mpf v1(m_fm), v2(m_fm); if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) - result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); + result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); else result = m_util.mk_min(arg1, arg2); return BR_DONE; @@ -479,7 +479,7 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_fm), v2(m_fm); if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { - result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, arg1, arg2); + result = m().mk_app(get_fid(), OP_FPA_MAX_UNSPECIFIED, arg1, arg2); return BR_REWRITE1; } else { @@ -494,9 +494,9 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { c = m().mk_and(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), m().mk_or(m().mk_and(m_util.mk_is_positive(arg1), m_util.mk_is_negative(arg2)), m().mk_and(m_util.mk_is_negative(arg1), m_util.mk_is_positive(arg2)))); - v = m().mk_app(get_fid(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, arg1, arg2); + v = m().mk_app(get_fid(), OP_FPA_MAX_UNSPECIFIED, arg1, arg2); - result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_INTERNAL_MAX_I, arg1, arg2)); + result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_MAX_I, arg1, arg2)); return BR_REWRITE_FULL; } } @@ -505,7 +505,7 @@ br_status fpa_rewriter::mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_r scoped_mpf v1(m_fm), v2(m_fm); if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) - result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); + result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); else result = m_util.mk_max(arg1, arg2); return BR_DONE; @@ -881,7 +881,7 @@ br_status fpa_rewriter::mk_to_ieee_bv(func_decl * f, expr * arg, expr_ref & resu result = bu.mk_concat(4, args); } else - result = m_util.mk_internal_to_ieee_bv_unspecified(x.get_ebits(), x.get_sbits()); + result = m_util.mk_to_ieee_bv_unspecified(x.get_ebits(), x.get_sbits()); return BR_REWRITE1; } @@ -902,7 +902,7 @@ br_status fpa_rewriter::mk_to_real(expr * arg, expr_ref & result) { if (m_util.is_numeral(arg, v)) { if (m_fm.is_nan(v) || m_fm.is_inf(v)) { const mpf & x = v.get(); - result = m_util.mk_internal_to_real_unspecified(x.get_ebits(), x.get_sbits()); + result = m_util.mk_to_real_unspecified(x.get_ebits(), x.get_sbits()); } else { scoped_mpq r(m_fm.mpq_manager()); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index dfd295220..12c5fb0b1 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -237,7 +237,7 @@ namespace smt { if (m_fpa_util.is_fp(e)) { expr * cargs[3] = { to_app(e)->get_arg(0), to_app(e)->get_arg(1), to_app(e)->get_arg(2) }; - expr_ref tmp(m_bv_util.mk_concat(3, cargs), m); + expr_ref tmp(m_bv_util.mk_concat(3, cargs), m); m_th_rw(tmp); res = to_app(tmp); } @@ -255,7 +255,7 @@ namespace smt { } func_decl_ref wrap_fd(m); - wrap_fd = m.mk_func_decl(get_family_id(), OP_FPA_INTERNAL_BVWRAP, 0, 0, 1, &es, bv_srt); + wrap_fd = m.mk_func_decl(get_family_id(), OP_FPA_BVWRAP, 0, 0, 1, &es, bv_srt); res = m.mk_app(wrap_fd, e); } diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 5fcb8637c..7be82816e 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -82,7 +82,7 @@ namespace smt { m_th(*th) {} virtual ~fpa2bv_converter_wrapped() {} virtual void mk_const(func_decl * f, expr_ref & result); - virtual void mk_rm_const(func_decl * f, expr_ref & result); + virtual void mk_rm_const(func_decl * f, expr_ref & result); }; class fpa_value_proc : public model_value_proc { @@ -108,7 +108,7 @@ namespace smt { result.append(m_deps); } - virtual app * mk_value(model_generator & mg, ptr_vector & values); + virtual app * mk_value(model_generator & mg, ptr_vector & values); }; class fpa_rm_value_proc : public model_value_proc { @@ -179,7 +179,6 @@ namespace smt { expr_ref convert_atom(expr * e); expr_ref convert_term(expr * e); expr_ref convert_conversion_term(expr * e); - expr_ref convert_unwrap(expr * e); void add_trail(ast * a); From 29d06896bf24c5309391804698e4b88b08e177ad Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 11 Sep 2017 17:06:59 +0200 Subject: [PATCH 275/488] remove verbose Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/th_rewriter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index dd431bf85..a2ca12b24 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -736,7 +736,6 @@ ast_manager & th_rewriter::m() const { void th_rewriter::updt_params(params_ref const & p) { m_params = p; m_imp->cfg().updt_params(p); - IF_VERBOSE(10, verbose_stream() << p << "\n";); } void th_rewriter::get_param_descrs(param_descrs & r) { From a0d0812b0cf01889c82991e539a08ed4fc5d698a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 12 Sep 2017 13:18:52 +0200 Subject: [PATCH 276/488] add alias bv2nat for bv2int to make it easier to interoperate #1252 Signed-off-by: Nikolaj Bjorner --- src/ast/bv_decl_plugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index b5c79f662..fcf9a9f8f 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -738,6 +738,7 @@ void bv_decl_plugin::get_op_names(svector & op_names, symbol const op_names.push_back(builtin_name("ext_rotate_right",OP_EXT_ROTATE_RIGHT)); op_names.push_back(builtin_name("int2bv",OP_INT2BV)); op_names.push_back(builtin_name("bv2int",OP_BV2INT)); + op_names.push_back(builtin_name("bv2nat",OP_BV2INT)); op_names.push_back(builtin_name("mkbv",OP_MKBV)); } } From 31cfca0444d2df3f231e0a8b92e80a8fa531f7c1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 12 Sep 2017 19:43:45 +0100 Subject: [PATCH 277/488] Eliminated unspecified operators for fp.to_*bv, fp.to_real. Also fixes #1191. --- src/api/api_ast.cpp | 4 - src/api/z3_api.h | 16 --- src/ast/fpa/bv2fpa_converter.cpp | 26 ++++- src/ast/fpa/fpa2bv_converter.cpp | 183 +++++++++++++----------------- src/ast/fpa/fpa2bv_converter.h | 8 +- src/ast/fpa/fpa2bv_rewriter.cpp | 4 - src/ast/fpa_decl_plugin.cpp | 91 --------------- src/ast/fpa_decl_plugin.h | 44 +------ src/ast/rewriter/fpa_rewriter.cpp | 64 +---------- src/ast/rewriter/fpa_rewriter.h | 4 +- src/smt/theory_fpa.cpp | 11 +- 11 files changed, 118 insertions(+), 337 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index cfea4098f..491e08cf4 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -1210,10 +1210,6 @@ extern "C" { case OP_FPA_BV2RM: return Z3_OP_FPA_BV2RM; case OP_FPA_MIN_UNSPECIFIED: return Z3_OP_FPA_MIN_UNSPECIFIED; case OP_FPA_MAX_UNSPECIFIED: return Z3_OP_FPA_MAX_UNSPECIFIED; - case OP_FPA_TO_UBV_UNSPECIFIED: return Z3_OP_FPA_TO_UBV_UNSPECIFIED; - case OP_FPA_TO_SBV_UNSPECIFIED: return Z3_OP_FPA_TO_SBV_UNSPECIFIED; - case OP_FPA_TO_REAL_UNSPECIFIED: return Z3_OP_FPA_TO_REAL_UNSPECIFIED; - case OP_FPA_TO_IEEE_BV_UNSPECIFIED: return Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED; return Z3_OP_UNINTERPRETED; default: return Z3_OP_INTERNAL; diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 663a59fd9..bfc0b93a2 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -1005,18 +1005,6 @@ typedef enum - Z3_OP_FPA_MAX_UNSPECIFIED: The same as Z3_OP_FPA_MAX, but the arguments are expected to be zeroes with different signs. - - Z3_OP_FPA_TO_UBV_UNSPECIFIED: A term representing the unspecified - results of Z3_OP_FPA_TO_UBV. - - - Z3_OP_FPA_TO_SBV_UNSPECIFIED: A term representing the unspecified - results of Z3_OP_FPA_TO_SBV. - - - Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED: A term representing the unspecified - results of Z3_OP_FPA_TO_IEEE_BV. - - - Z3_OP_FPA_TO_REAL_UNSPECIFIED: A term representing the unspecified - results of Z3_OP_FPA_TO_IEEE_BV. - - Z3_OP_INTERNAL: internal (often interpreted) symbol, but no additional information is exposed. Tools may use the string representation of the function declaration to obtain more information. @@ -1310,10 +1298,6 @@ typedef enum { Z3_OP_FPA_BV2RM, Z3_OP_FPA_MIN_UNSPECIFIED, Z3_OP_FPA_MAX_UNSPECIFIED, - Z3_OP_FPA_TO_UBV_UNSPECIFIED, - Z3_OP_FPA_TO_SBV_UNSPECIFIED, - Z3_OP_FPA_TO_REAL_UNSPECIFIED, - Z3_OP_FPA_TO_IEEE_BV_UNSPECIFIED, Z3_OP_INTERNAL, diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index 7e4f2f133..59f24779e 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -291,9 +291,11 @@ func_interp * bv2fpa_converter::convert_func_interp(model_core * mc, func_decl * app_ref bv_els(m); expr_ref ft_els(m); bv_els = (app*)bv_fi->get_else(); - ft_els = rebuild_floats(mc, rng, bv_els); - m_th_rw(ft_els); - result->set_else(ft_els); + if (bv_els != 0) { + ft_els = rebuild_floats(mc, rng, bv_els); + m_th_rw(ft_els); + result->set_else(ft_els); + } } return result; @@ -447,8 +449,22 @@ void bv2fpa_converter::convert_uf2bvuf(model_core * mc, model_core * target_mode } } else { - func_interp * fmv = convert_func_interp(mc, f, it->m_value); - if (fmv) target_model->register_decl(f, fmv); + if (it->get_key().get_family_id() == m_fpa_util.get_fid()) { + // it->m_value contains the model for the unspecified cases of it->m_key. + continue; + + // Upon request, add this 'recursive' definition? + func_interp * fmv = convert_func_interp(mc, f, it->m_value); + unsigned n = fmv->get_arity(); + expr_ref_vector args(m); + for (unsigned i = 0; i < n; i++) + args.push_back(m.mk_var(i, f->get_domain()[i])); + fmv->set_else(m.mk_app(it->m_key, n, args.c_ptr())); + } + else { + func_interp * fmv = convert_func_interp(mc, f, it->m_value); + if (fmv) target_model->register_decl(f, fmv); + } } } } diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 6f0c83df9..da4052108 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2855,8 +2855,7 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;); expr_ref unspec(m); - unspec = mk_to_real_unspecified(ebits, sbits); - + mk_to_real_unspecified(f, num, args, unspec); result = m.mk_ite(x_is_zero, zero, res); result = m.mk_ite(x_is_inf, unspec, result); result = m.mk_ite(x_is_nan, unspec, result); @@ -3141,11 +3140,12 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); - expr_ref x(m), x_is_nan(m); + expr_ref x(m), x_is_nan(m), x_flat(m); expr * sgn, * s, * e; x = args[0]; split_fp(x, sgn, e, s); mk_is_nan(x, x_is_nan); + join_fp(x, x_flat); sort * fp_srt = m.get_sort(x); unsigned ebits = m_util.get_ebits(fp_srt); @@ -3159,13 +3159,12 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * m_bv_util.mk_concat(m_bv_util.mk_numeral(0, sbits - 2), m_bv_util.mk_numeral(1, 1)))); else { - app_ref unspec(m); - unspec = m_util.mk_to_ieee_bv_unspecified(ebits, sbits); - mk_to_ieee_bv_unspecified(unspec->get_decl(), 0, 0, nanv); + expr * x_flatp = x_flat.get(); + mk_to_ieee_bv_unspecified(f, 1, &x_flatp, nanv); } expr_ref sgn_e_s(m); - sgn_e_s = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s); + join_fp(x, sgn_e_s); m_simp.mk_ite(x_is_nan, nanv, sgn_e_s, result); TRACE("fpa2bv_to_ieee_bv", tout << "result=" << mk_ismt2_pp(result, m) << std::endl;); @@ -3173,7 +3172,8 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * } void fpa2bv_converter::mk_to_ieee_bv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 0); + SASSERT(num == 1); + SASSERT(m_util.is_float(args[0])); unsigned ebits = f->get_parameter(0).get_int(); unsigned sbits = f->get_parameter(1).get_int(); @@ -3184,26 +3184,30 @@ void fpa2bv_converter::mk_to_ieee_bv_unspecified(func_decl * f, unsigned num, ex m_bv_util.mk_numeral(1, sbits-1)); } else { - func_decl * fd; - if (m_uf2bvuf.find(f, fd)) - result = m.mk_const(fd); - else { - fd = m.mk_fresh_func_decl(0, 0, 0, f->get_range()); - m_uf2bvuf.insert(f, fd); + expr * n = args[0]; + expr_ref n_bv(m); + join_fp(n, n_bv); + + func_decl * f_bv; + if (!m_uf2bvuf.find(f, f_bv)) { + sort * domain[2] = { m.get_sort(n_bv) }; + f_bv = m.mk_fresh_func_decl(0, 1, domain, f->get_range()); + m_uf2bvuf.insert(f, f_bv); m.inc_ref(f); - m.inc_ref(fd); - result = m.mk_const(fd); - - expr_ref exp_bv(m), exp_all_ones(m); - exp_bv = m_bv_util.mk_extract(ebits+sbits-2, sbits-1, result); - exp_all_ones = m.mk_eq(exp_bv, m_bv_util.mk_numeral(-1, ebits)); - m_extra_assertions.push_back(exp_all_ones); - - expr_ref sig_bv(m), sig_is_non_zero(m); - sig_bv = m_bv_util.mk_extract(sbits-2, 0, result); - sig_is_non_zero = m.mk_not(m.mk_eq(sig_bv, m_bv_util.mk_numeral(0, sbits-1))); - m_extra_assertions.push_back(sig_is_non_zero); + m.inc_ref(f_bv); } + + result = m.mk_app(f_bv, n_bv); + + expr_ref exp_bv(m), exp_all_ones(m); + exp_bv = m_bv_util.mk_extract(ebits+sbits-2, sbits-1, result); + exp_all_ones = m.mk_eq(exp_bv, m_bv_util.mk_numeral(-1, ebits)); + m_extra_assertions.push_back(exp_all_ones); + + expr_ref sig_bv(m), sig_is_non_zero(m); + sig_bv = m_bv_util.mk_extract(sbits-2, 0, result); + sig_is_non_zero = m.mk_not(m.mk_eq(sig_bv, m_bv_util.mk_numeral(0, sbits-1))); + m_extra_assertions.push_back(sig_is_non_zero); } TRACE("fpa2bv_to_ieee_bv_unspecified", tout << "result=" << mk_ismt2_pp(result, m) << std::endl;); @@ -3238,15 +3242,13 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args mk_is_nzero(x, x_is_nzero); // NaN, Inf, or negative (except -0) -> unspecified - expr_ref c1(m), v1(m); - if (!is_signed) { + expr_ref c1(m), v1(m), unspec_v(m); + if (!is_signed) c1 = m.mk_or(x_is_nan, x_is_inf, m.mk_and(x_is_neg, m.mk_not(x_is_nzero))); - v1 = mk_to_ubv_unspecified(ebits, sbits, bv_sz); - } - else { + else c1 = m.mk_or(x_is_nan, x_is_inf); - v1 = mk_to_sbv_unspecified(ebits, sbits, bv_sz); - } + mk_to_bv_unspecified(f, num, args, unspec_v); + v1 = unspec_v; dbg_decouple("fpa2bv_to_bv_c1", c1); // +-Zero -> 0 @@ -3355,11 +3357,8 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args dbg_decouple("fpa2bv_to_bv_rnd", rnd); - expr_ref unspec(m); - unspec = is_signed ? mk_to_sbv_unspecified(ebits, sbits, bv_sz) : - mk_to_ubv_unspecified(ebits, sbits, bv_sz); - result = m.mk_ite(rnd_has_overflown, unspec, rnd); - result = m.mk_ite(c_in_limits, result, unspec); + result = m.mk_ite(rnd_has_overflown, unspec_v, rnd); + result = m.mk_ite(c_in_limits, result, unspec_v); result = m.mk_ite(c2, v2, result); result = m.mk_ite(c1, v1, result); @@ -3378,85 +3377,54 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg mk_to_bv(f, num, args, true, result); } -void fpa2bv_converter::mk_to_ubv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 0); - unsigned width = m_bv_util.get_bv_size(f->get_range()); +void fpa2bv_converter::mk_to_bv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + SASSERT(num == 2); + SASSERT(m_util.is_bv2rm(args[0])); + SASSERT(m_util.is_float(args[1])); if (m_hi_fp_unspecified) - result = m_bv_util.mk_numeral(0, width); + result = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(f->get_range())); else { - func_decl * fd; - if (!m_uf2bvuf.find(f, fd)) { - fd = m.mk_fresh_func_decl(0, 0, 0, f->get_range()); - m_uf2bvuf.insert(f, fd); + expr * rm_bv = to_app(args[0])->get_arg(0); + expr * n = args[1]; + expr_ref n_bv(m); + join_fp(n, n_bv); + + func_decl * f_bv; + if (!m_uf2bvuf.find(f, f_bv)) { + sort * domain[2] = { m.get_sort(rm_bv), m.get_sort(n_bv) }; + f_bv = m.mk_fresh_func_decl(0, 2, domain, f->get_range()); + m_uf2bvuf.insert(f, f_bv); m.inc_ref(f); - m.inc_ref(fd); + m.inc_ref(f_bv); } - result = m.mk_const(fd); + result = m.mk_app(f_bv, rm_bv, n_bv); } - TRACE("fpa2bv_to_ubv_unspecified", tout << "result=" << mk_ismt2_pp(result, m) << std::endl;); + TRACE("fpa2bv_to_bv_unspecified", tout << "result=" << mk_ismt2_pp(result, m) << std::endl;); SASSERT(is_well_sorted(m, result)); } -expr_ref fpa2bv_converter::mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { - expr_ref res(m); - app_ref u(m); - u = m_util.mk_to_ubv_unspecified(ebits, sbits, width); - mk_to_sbv_unspecified(u->get_decl(), 0, 0, res); - return res; -} - -void fpa2bv_converter::mk_to_sbv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 0); - unsigned width = m_bv_util.get_bv_size(f->get_range()); - - if (m_hi_fp_unspecified) - result = m_bv_util.mk_numeral(0, width); - else { - func_decl * fd; - if (!m_uf2bvuf.find(f, fd)) { - fd = m.mk_fresh_func_decl(0, 0, 0, f->get_range()); - m_uf2bvuf.insert(f, fd); - m.inc_ref(f); - m.inc_ref(fd); - } - result = m.mk_const(fd); - } - - TRACE("fpa2bv_to_sbv_unspecified", tout << "result=" << mk_ismt2_pp(result, m) << std::endl;); - SASSERT(is_well_sorted(m, result)); -} - -expr_ref fpa2bv_converter::mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { - expr_ref res(m); - app_ref u(m); - u = m_util.mk_to_sbv_unspecified(ebits, sbits, width); - mk_to_sbv_unspecified(u->get_decl(), 0, 0, res); - return res; -} - void fpa2bv_converter::mk_to_real_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + SASSERT(num == 1); + if (m_hi_fp_unspecified) result = m_arith_util.mk_numeral(rational(0), false); else { - func_decl * fd; - if (!m_uf2bvuf.find(f, fd)) { - fd = m.mk_fresh_func_decl(0, 0, 0, f->get_range()); - m_uf2bvuf.insert(f, fd); - m.inc_ref(f); - m.inc_ref(fd); - } - result = m.mk_const(fd); - } -} + expr * n = args[0]; + expr_ref n_bv(m); + join_fp(n, n_bv); -expr_ref fpa2bv_converter::mk_to_real_unspecified(unsigned ebits, unsigned sbits) { - expr_ref res(m); - app_ref u(m); - u = m_util.mk_to_real_unspecified(ebits, sbits); - mk_to_real_unspecified(u->get_decl(), 0, 0, res); - return res; + func_decl * f_bv; + if (!m_uf2bvuf.find(f, f_bv)) { + sort * domain[2] = { m.get_sort(n_bv) }; + f_bv = m.mk_fresh_func_decl(0, 1, domain, f->get_range()); + m_uf2bvuf.insert(f, f_bv); + m.inc_ref(f); + m.inc_ref(f_bv); + } + result = m.mk_app(f_bv, n_bv); + } } void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -3467,6 +3435,7 @@ void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, e result = m_util.mk_fp(args[0], args[1], args[2]); TRACE("fpa2bv_mk_fp", tout << "mk_fp result = " << mk_ismt2_pp(result, m) << std::endl;); } + void fpa2bv_converter::split_fp(expr * e, expr * & sgn, expr * & exp, expr * & sig) const { SASSERT(m_util.is_fp(e)); SASSERT(to_app(e)->get_num_args() == 3); @@ -3485,6 +3454,14 @@ void fpa2bv_converter::split_fp(expr * e, expr_ref & sgn, expr_ref & exp, expr_r sig = e_sig; } +void fpa2bv_converter::join_fp(expr * e, expr_ref & res) { + SASSERT(m_util.is_fp(e)); + SASSERT(to_app(e)->get_num_args() == 3); + expr *sgn, *exp, *sig; + split_fp(e, sgn, exp, sig); + res = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, exp), sig); +} + void fpa2bv_converter::mk_is_nan(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; split_fp(e, sgn, exp, sig); @@ -4051,7 +4028,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & // put the sticky bit into the significand. expr_ref ext_sticky(m); ext_sticky = m_bv_util.mk_zero_extend(sbits+1, sticky); - expr * tmp[] = { sig, ext_sticky }; + expr * tmp[2] = { sig, ext_sticky }; sig = m_bv_util.mk_bv_or(2, tmp); SASSERT(is_well_sorted(m, sig)); SASSERT(m_bv_util.get_bv_size(sig) == sbits+2); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 1e3e5d9b3..d54adac78 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -76,6 +76,7 @@ public: void split_fp(expr * e, expr * & sgn, expr * & exp, expr * & sig) const; void split_fp(expr * e, expr_ref & sgn, expr_ref & exp, expr_ref & sig) const; + void join_fp(expr * e, expr_ref & res); void mk_eq(expr * a, expr * b, expr_ref & result); void mk_ite(expr * c, expr * t, expr * f, expr_ref & result); @@ -138,9 +139,8 @@ public: void mk_to_fp_real_int(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_ubv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_sbv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_bv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_real_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); @@ -226,10 +226,6 @@ private: void mk_round_to_integral(sort * s, expr_ref & rm, expr_ref & x, expr_ref & result); void mk_to_fp_float(sort * s, expr * rm, expr * x, expr_ref & result); - - expr_ref mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width); - expr_ref mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width); - expr_ref mk_to_real_unspecified(unsigned ebits, unsigned sbits); }; #endif diff --git a/src/ast/fpa/fpa2bv_rewriter.cpp b/src/ast/fpa/fpa2bv_rewriter.cpp index 28ec35536..07623ec48 100644 --- a/src/ast/fpa/fpa2bv_rewriter.cpp +++ b/src/ast/fpa/fpa2bv_rewriter.cpp @@ -143,13 +143,9 @@ br_status fpa2bv_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr * co case OP_FPA_TO_FP_UNSIGNED: m_conv.mk_to_fp_unsigned(f, num, args, result); return BR_DONE; case OP_FPA_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; case OP_FPA_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; - case OP_FPA_TO_UBV_UNSPECIFIED: m_conv.mk_to_ubv_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; - case OP_FPA_TO_SBV_UNSPECIFIED: m_conv.mk_to_sbv_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; - case OP_FPA_TO_REAL_UNSPECIFIED: m_conv.mk_to_real_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; - case OP_FPA_TO_IEEE_BV_UNSPECIFIED: m_conv.mk_to_ieee_bv_unspecified(f, num, args, result); return BR_DONE; case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_REWRITE_FULL; case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_REWRITE_FULL; diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index c50d6b985..9bee51af7 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -711,65 +711,6 @@ func_decl * fpa_decl_plugin::mk_bv_wrap(decl_kind k, unsigned num_parameters, pa } } -func_decl * fpa_decl_plugin::mk_to_ubv_unspecified( - decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (arity != 0) - m_manager->raise_exception("invalid number of arguments to fp.to_ubv_unspecified"); - if (num_parameters != 3) - m_manager->raise_exception("invalid number of parameters to fp.to_ubv_unspecified; expecting 3"); - if (!parameters[0].is_int() || !parameters[1].is_int() || !parameters[2].is_int()) - m_manager->raise_exception("invalid parameters type provided to fp.to_ubv_unspecified; expecting 3 integers"); - - sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ¶meters[2]); - return m_manager->mk_func_decl(symbol("fp.to_ubv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); -} - -func_decl * fpa_decl_plugin::mk_to_sbv_unspecified( - decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (arity != 0) - m_manager->raise_exception("invalid number of arguments to fp.to_sbv_unspecified"); - if (num_parameters != 3) - m_manager->raise_exception("invalid number of parameters to fp.to_sbv_unspecified; expecting 3"); - if (!parameters[0].is_int() || !parameters[1].is_int() || !parameters[2].is_int()) - m_manager->raise_exception("invalid parameters type provided to fp.to_sbv_unspecified; expecting 3 integers"); - - sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ¶meters[2]); - return m_manager->mk_func_decl(symbol("fp.to_sbv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); -} - -func_decl * fpa_decl_plugin::mk_to_real_unspecified( - decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (arity != 0) - m_manager->raise_exception("invalid number of arguments to fp.to_real_unspecified"); - if (num_parameters != 2) - m_manager->raise_exception("invalid number of parameters to fp.to_real_unspecified; expecting 2"); - if (!parameters[0].is_int() || !parameters[1].is_int()) - m_manager->raise_exception("invalid parameters type provided to fp.to_real_unspecified; expecting 2 integers"); - if (!is_sort_of(range, m_arith_fid, REAL_SORT)) - m_manager->raise_exception("sort mismatch, expected range of Real sort"); - - return m_manager->mk_func_decl(symbol("fp.to_real_unspecified"), 0, domain, m_real_sort, func_decl_info(m_family_id, k, num_parameters, parameters)); -} - -func_decl * fpa_decl_plugin::mk_to_ieee_bv_unspecified( - decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (arity != 0) - m_manager->raise_exception("invalid number of arguments to fp.to_ieee_bv_unspecified; expecting none"); - if (num_parameters != 2) - m_manager->raise_exception("invalid number of parameters to fp.to_ieee_bv_unspecified; expecting 2"); - if (!parameters[0].is_int() || !parameters[1].is_int()) - m_manager->raise_exception("invalid parameters type provided to fp.to_ieee_bv_unspecified; expecting 2 integers"); - - parameter width_p[1] = { parameter(parameters[0].get_int() + parameters[1].get_int()) }; - sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, width_p); - return m_manager->mk_func_decl(symbol("fp.to_ieee_bv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); -} - - func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { switch (k) { @@ -846,14 +787,6 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, case OP_FPA_MAX_UNSPECIFIED: return mk_binary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_TO_UBV_UNSPECIFIED: - return mk_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_TO_SBV_UNSPECIFIED: - return mk_to_sbv_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_TO_REAL_UNSPECIFIED: - return mk_to_real_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_TO_IEEE_BV_UNSPECIFIED: - return mk_to_ieee_bv_unspecified(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); return 0; @@ -1054,30 +987,6 @@ app * fpa_util::mk_nzero(unsigned ebits, unsigned sbits) { return mk_value(v); } -app * fpa_util::mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { - parameter ps[] = { parameter(ebits), parameter(sbits), parameter(width) }; - sort * range = m_bv_util.mk_sort(width); - return m().mk_app(get_family_id(), OP_FPA_TO_UBV_UNSPECIFIED, 3, ps, 0, 0, range); -} - -app * fpa_util::mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width) { - parameter ps[] = { parameter(ebits), parameter(sbits), parameter(width) }; - sort * range = m_bv_util.mk_sort(width); - return m().mk_app(get_family_id(), OP_FPA_TO_SBV_UNSPECIFIED, 3, ps, 0, 0, range); -} - -app * fpa_util::mk_to_ieee_bv_unspecified(unsigned ebits, unsigned sbits) { - parameter ps[] = { parameter(ebits), parameter(sbits) }; - sort * range = m_bv_util.mk_sort(ebits+sbits); - return m().mk_app(get_family_id(), OP_FPA_TO_IEEE_BV_UNSPECIFIED, 2, ps, 0, 0, range); -} - -app * fpa_util::mk_to_real_unspecified(unsigned ebits, unsigned sbits) { - parameter ps[] = { parameter(ebits), parameter(sbits) }; - sort * range = m_a_util.mk_real(); - return m().mk_app(get_family_id(), OP_FPA_TO_REAL_UNSPECIFIED, 2, ps, 0, 0, range); -} - bool fpa_util::contains_floats(ast * a) { switch (a->get_kind()) { case AST_APP: { diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index c78194b63..79f44a13d 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -93,10 +93,6 @@ enum fpa_op_kind { OP_FPA_MAX_I, OP_FPA_MIN_UNSPECIFIED, OP_FPA_MAX_UNSPECIFIED, - OP_FPA_TO_UBV_UNSPECIFIED, - OP_FPA_TO_SBV_UNSPECIFIED, - OP_FPA_TO_IEEE_BV_UNSPECIFIED, - OP_FPA_TO_REAL_UNSPECIFIED, LAST_FLOAT_OP }; @@ -167,34 +163,12 @@ class fpa_decl_plugin : public decl_plugin { unsigned arity, sort * const * domain, sort * range); func_decl * mk_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_to_ubv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - func_decl * mk_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - func_decl * mk_to_real_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - func_decl * mk_to_ieee_bv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); virtual void set_manager(ast_manager * m, family_id id); unsigned mk_id(mpf const & v); void recycled_id(unsigned id); - virtual bool is_considered_uninterpreted(func_decl * f) { - if (f->get_family_id() != get_family_id()) - return false; - switch (f->get_decl_kind()) - { - case OP_FPA_TO_UBV_UNSPECIFIED: - case OP_FPA_TO_SBV_UNSPECIFIED: - case OP_FPA_TO_REAL_UNSPECIFIED: - case OP_FPA_TO_IEEE_BV_UNSPECIFIED: - return true; - default: - return false; - } - return false; - } + virtual bool is_considered_uninterpreted(func_decl * f) { return false; } public: fpa_decl_plugin(); @@ -374,10 +348,6 @@ public: SASSERT(m_bv_util.is_bv(bv3) && m_bv_util.get_bv_size(bv3) == 3); return m().mk_app(m_fid, OP_FPA_BV2RM, 0, 0, 1, &bv3, mk_rm_sort()); } - app * mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width); - app * mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width); - app * mk_to_ieee_bv_unspecified(unsigned ebits, unsigned sbits); - app * mk_to_real_unspecified(unsigned ebits, unsigned sbits); bool is_bvwrap(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_BVWRAP); } bool is_bvwrap(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_BVWRAP; } @@ -388,19 +358,15 @@ public: bool is_min_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MIN_UNSPECIFIED); } bool is_max_interpreted(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MAX_I); } bool is_max_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MAX_UNSPECIFIED); } - bool is_to_ubv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_UBV_UNSPECIFIED); } - bool is_to_sbv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_SBV_UNSPECIFIED); } - bool is_to_ieee_bv_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_IEEE_BV_UNSPECIFIED); } - bool is_to_real_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_REAL_UNSPECIFIED); } + bool is_to_ubv(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_UBV); } + bool is_to_sbv(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_SBV); } bool is_min_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MIN_I; } bool is_min_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MIN_UNSPECIFIED; } bool is_max_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MAX_I; } bool is_max_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MAX_UNSPECIFIED; } - bool is_to_ubv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_UBV_UNSPECIFIED; } - bool is_to_sbv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_SBV_UNSPECIFIED; } - bool is_to_ieee_bv_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_IEEE_BV_UNSPECIFIED; } - bool is_to_real_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_REAL_UNSPECIFIED; } + bool is_to_ubv(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_UBV; } + bool is_to_sbv(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_SBV; } bool contains_floats(ast * a); }; diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index b31270ce8..644aff630 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -103,57 +103,12 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_BVWRAP: SASSERT(num_args == 1); st = mk_bvwrap(args[0], result); break; case OP_FPA_BV2RM: SASSERT(num_args == 1); st = mk_bv2rm(args[0], result); break; - case OP_FPA_TO_UBV_UNSPECIFIED: - case OP_FPA_TO_SBV_UNSPECIFIED: - case OP_FPA_TO_REAL_UNSPECIFIED: - case OP_FPA_TO_IEEE_BV_UNSPECIFIED: - st = BR_FAILED; - break; - default: NOT_IMPLEMENTED_YET(); } return st; } -br_status fpa_rewriter::mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned width, expr_ref & result) { - bv_util bu(m()); - if (m_hi_fp_unspecified) { - // The "hardware interpretation" is 0. - result = bu.mk_numeral(0, width); - return BR_DONE; - } - else { - result = m_util.mk_to_ubv_unspecified(ebits, sbits, width); - return BR_REWRITE1; - } -} - -br_status fpa_rewriter::mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned width, expr_ref & result) { - bv_util bu(m()); - if (m_hi_fp_unspecified) { - // The "hardware interpretation" is 0. - result = bu.mk_numeral(0, width); - return BR_DONE; - } - else { - result = m_util.mk_to_sbv_unspecified(ebits, sbits, width); - return BR_REWRITE1; - } -} - -br_status fpa_rewriter::mk_to_real_unspecified(unsigned ebits, unsigned sbits, expr_ref & result) { - if (m_hi_fp_unspecified) { - // The "hardware interpretation" is 0. - result = m_util.au().mk_numeral(rational(0), false); - return BR_DONE; - } - else { - result = m_util.mk_to_real_unspecified(ebits, sbits); - return BR_REWRITE1; - } -} - br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(f->get_num_parameters() == 2); SASSERT(f->get_parameter(0).is_int()); @@ -808,7 +763,7 @@ br_status fpa_rewriter::mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ const mpf & x = v.get(); if (m_fm.is_nan(v) || m_fm.is_inf(v) || m_fm.is_neg(v)) - return mk_to_ubv_unspecified(x.get_ebits(), x.get_sbits(), bv_sz, result); + return BR_FAILED; bv_util bu(m()); scoped_mpq q(m_fm.mpq_manager()); @@ -822,9 +777,6 @@ br_status fpa_rewriter::mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ result = bu.mk_numeral(r, bv_sz); return BR_DONE; } - else - return mk_to_ubv_unspecified(x.get_ebits(), x.get_sbits(), bv_sz, result); - } return BR_FAILED; @@ -842,7 +794,7 @@ br_status fpa_rewriter::mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ const mpf & x = v.get(); if (m_fm.is_nan(v) || m_fm.is_inf(v)) - return mk_to_sbv_unspecified(x.get_ebits(), x.get_sbits(), bv_sz, result); + return BR_FAILED; bv_util bu(m()); scoped_mpq q(m_fm.mpq_manager()); @@ -856,8 +808,6 @@ br_status fpa_rewriter::mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ result = bu.mk_numeral(r, bv_sz); return BR_DONE; } - else - return mk_to_sbv_unspecified(x.get_ebits(), x.get_sbits(), bv_sz, result); } return BR_FAILED; @@ -881,7 +831,7 @@ br_status fpa_rewriter::mk_to_ieee_bv(func_decl * f, expr * arg, expr_ref & resu result = bu.mk_concat(4, args); } else - result = m_util.mk_to_ieee_bv_unspecified(x.get_ebits(), x.get_sbits()); + return BR_FAILED; return BR_REWRITE1; } @@ -900,16 +850,12 @@ br_status fpa_rewriter::mk_to_real(expr * arg, expr_ref & result) { scoped_mpf v(m_fm); if (m_util.is_numeral(arg, v)) { - if (m_fm.is_nan(v) || m_fm.is_inf(v)) { - const mpf & x = v.get(); - result = m_util.mk_to_real_unspecified(x.get_ebits(), x.get_sbits()); - } - else { + if (!m_fm.is_nan(v) && !m_fm.is_inf(v)) { scoped_mpq r(m_fm.mpq_manager()); m_fm.to_rational(v, r); result = m_util.au().mk_numeral(r.get(), false); + return BR_DONE; } - return BR_DONE; } return BR_FAILED; diff --git a/src/ast/rewriter/fpa_rewriter.h b/src/ast/rewriter/fpa_rewriter.h index 282cec4df..5d5b7e57d 100644 --- a/src/ast/rewriter/fpa_rewriter.h +++ b/src/ast/rewriter/fpa_rewriter.h @@ -88,9 +88,7 @@ public: br_status mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); - br_status mk_to_ubv_unspecified(unsigned ebits, unsigned sbits, unsigned with, expr_ref & result); - br_status mk_to_sbv_unspecified(unsigned ebits, unsigned sbits, unsigned with, expr_ref & result); - br_status mk_to_real_unspecified(unsigned ebits, unsigned sbits, expr_ref & result); + br_status mk_to_real_unspecified(unsigned ebits, unsigned sbits, expr * n, expr_ref & result); br_status mk_bvwrap(expr * arg, expr_ref & result); }; diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 12c5fb0b1..d337cc65d 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -119,6 +119,7 @@ namespace smt { SASSERT(m_conversions.empty()); SASSERT(m_is_added_to_model.empty()); } + void theory_fpa::init(context * ctx) { smt::theory::init(ctx); m_is_initialized = true; @@ -890,14 +891,10 @@ namespace smt { if (f->get_family_id() == get_family_id()) { bool include = m_fpa_util.is_min_unspecified(f) || - m_fpa_util.is_max_unspecified(f) || - m_fpa_util.is_to_ubv_unspecified(f) || - m_fpa_util.is_to_sbv_unspecified(f) || - m_fpa_util.is_to_ieee_bv_unspecified(f) || - m_fpa_util.is_to_real_unspecified(f); + m_fpa_util.is_max_unspecified(f) ; if (include && !m_is_added_to_model.contains(f)) { - m_is_added_to_model.insert(f); - get_manager().inc_ref(f); + //m_is_added_to_model.insert(f); + //get_manager().inc_ref(f); return true; } return false; From de15932f4ca7e1419c205d2816f6f8e257e55286 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 13 Sep 2017 19:47:59 +0100 Subject: [PATCH 278/488] Fixed BV encoding of fp.to_{s,u}bv. --- src/ast/fpa/fpa2bv_converter.cpp | 137 +++++++++++++++---------------- 1 file changed, 66 insertions(+), 71 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index da4052108..190e86da3 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3140,12 +3140,11 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); - expr_ref x(m), x_is_nan(m), x_flat(m); + expr_ref x(m), x_is_nan(m); expr * sgn, * s, * e; x = args[0]; split_fp(x, sgn, e, s); mk_is_nan(x, x_is_nan); - join_fp(x, x_flat); sort * fp_srt = m.get_sort(x); unsigned ebits = m_util.get_ebits(fp_srt); @@ -3158,10 +3157,8 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * m_bv_util.mk_concat(m_bv_util.mk_numeral(-1, ebits), m_bv_util.mk_concat(m_bv_util.mk_numeral(0, sbits - 2), m_bv_util.mk_numeral(1, 1)))); - else { - expr * x_flatp = x_flat.get(); - mk_to_ieee_bv_unspecified(f, 1, &x_flatp, nanv); - } + else + mk_to_ieee_bv_unspecified(f, num, args, nanv); expr_ref sgn_e_s(m); join_fp(x, sgn_e_s); @@ -3174,8 +3171,8 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * void fpa2bv_converter::mk_to_ieee_bv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); SASSERT(m_util.is_float(args[0])); - unsigned ebits = f->get_parameter(0).get_int(); - unsigned sbits = f->get_parameter(1).get_int(); + unsigned ebits = f->get_domain()[0]->get_parameter(0).get_int(); + unsigned sbits = f->get_domain()[0]->get_parameter(1).get_int(); if (m_hi_fp_unspecified) { result = m_bv_util.mk_concat(m_bv_util.mk_concat( @@ -3251,7 +3248,7 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args v1 = unspec_v; dbg_decouple("fpa2bv_to_bv_c1", c1); - // +-Zero -> 0 + // +-0 -> 0 expr_ref c2(m), v2(m); c2 = x_is_zero; v2 = m_bv_util.mk_numeral(rational(0), bv_srt); @@ -3272,60 +3269,57 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args SASSERT(m_bv_util.get_bv_size(exp) == ebits); SASSERT(m_bv_util.get_bv_size(lz) == ebits); - unsigned sig_sz = m_bv_util.get_bv_size(sig); - SASSERT(sig_sz == sbits); + unsigned sig_sz = sbits; if (sig_sz < (bv_sz + 3)) - sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, bv_sz - sig_sz + 3)); + sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, bv_sz-sig_sz+3)); sig_sz = m_bv_util.get_bv_size(sig); SASSERT(sig_sz >= (bv_sz + 3)); - expr_ref exp_m_lz(m), e_m_lz_m_bv_sz(m), shift(m), bv0_e2(m), shift_abs(m), shift_le_0(m); - exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), - m_bv_util.mk_zero_extend(2, lz)); - e_m_lz_m_bv_sz = m_bv_util.mk_bv_sub(exp_m_lz, - m_bv_util.mk_numeral(bv_sz - 1, ebits + 2)); - shift = m_bv_util.mk_bv_neg(e_m_lz_m_bv_sz); - bv0_e2 = m_bv_util.mk_numeral(0, ebits + 2); - shift_le_0 = m_bv_util.mk_sle(shift, bv0_e2); - shift_abs = m.mk_ite(shift_le_0, e_m_lz_m_bv_sz, shift); - SASSERT(m_bv_util.get_bv_size(shift) == ebits + 2); - SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2); - dbg_decouple("fpa2bv_to_bv_shift", shift); - dbg_decouple("fpa2bv_to_bv_shift_abs", shift_abs); - // x is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long - // [1][ ... sig ... ][r][g][ ... s ...] - // [ ... ubv ... ][r][g][ ... s ... ] - shift_abs = m_bv_util.mk_zero_extend(sig_sz - ebits - 2, shift_abs); - SASSERT(m_bv_util.get_bv_size(shift_abs) == sig_sz); + expr_ref exp_m_lz(m), e_m_lz_m_bv_sz(m), shift(m), is_neg_shift(m), big_sig(m); + exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), + m_bv_util.mk_zero_extend(2, lz)); - expr_ref c_in_limits(m); - if (!is_signed) - c_in_limits = m_bv_util.mk_sle(bv0_e2, shift); - else { - expr_ref one_sle_shift(m), one_eq_shift(m), p2(m), sig_is_p2(m), shift1_and_sig_p2(m); - one_sle_shift = m_bv_util.mk_sle(m_bv_util.mk_numeral(1, ebits + 2), shift); - one_eq_shift = m.mk_eq(m_bv_util.mk_numeral(0, ebits + 2), shift); - p2 = m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, sig_sz-1)); - sig_is_p2 = m.mk_eq(sig, p2); - shift1_and_sig_p2 = m.mk_and(one_eq_shift, sig_is_p2); - c_in_limits = m.mk_or(one_sle_shift, shift1_and_sig_p2); + // big_sig is +- [... bv_sz+2 bits ...].[r][g][ ... sbits-1 ... ] + big_sig = m_bv_util.mk_zero_extend(bv_sz+2, sig); + unsigned big_sig_sz = sig_sz+bv_sz+2; + SASSERT(m_bv_util.get_bv_size(big_sig) == big_sig_sz); + + is_neg_shift = m_bv_util.mk_sle(exp_m_lz, m_bv_util.mk_numeral(0, ebits+2)); + shift = m.mk_ite(is_neg_shift, m_bv_util.mk_bv_neg(exp_m_lz), exp_m_lz); + if (ebits+2 < big_sig_sz) + shift = m_bv_util.mk_zero_extend(big_sig_sz-ebits-2, shift); + else if (ebits+2 > big_sig_sz) { + expr_ref upper(m); + upper = m_bv_util.mk_extract(big_sig_sz, ebits+2, shift); + shift = m_bv_util.mk_extract(ebits+1, 0, shift); + shift = m.mk_ite(m.mk_eq(upper, m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(upper))), + shift, + m_bv_util.mk_numeral(big_sig_sz-1, ebits+2)); } - dbg_decouple("fpa2bv_to_bv_in_limits", c_in_limits); + dbg_decouple("fpa2bv_to_bv_shift_uncapped", shift); + SASSERT(m_bv_util.get_bv_size(shift) == m_bv_util.get_bv_size(big_sig)); + dbg_decouple("fpa2bv_to_bv_big_sig", big_sig); - expr_ref r_shifted_sig(m), l_shifted_sig(m); - r_shifted_sig = m_bv_util.mk_bv_lshr(sig, shift_abs); - l_shifted_sig = m_bv_util.mk_bv_shl(sig, m_bv_util.mk_bv_sub( - m_bv_util.mk_numeral(m_bv_util.get_bv_size(sig), m_bv_util.get_bv_size(sig)), - shift_abs)); - dbg_decouple("fpa2bv_to_bv_r_shifted_sig", r_shifted_sig); - dbg_decouple("fpa2bv_to_bv_l_shifted_sig", l_shifted_sig); + expr_ref shift_limit(m); + shift_limit = m_bv_util.mk_numeral(bv_sz+2, m_bv_util.get_bv_size(shift)); + shift = m.mk_ite(m_bv_util.mk_ule(shift, shift_limit), shift, shift_limit); + dbg_decouple("fpa2bv_to_bv_shift_limit", shift_limit); + dbg_decouple("fpa2bv_to_bv_is_neg_shift", is_neg_shift); + dbg_decouple("fpa2bv_to_bv_shift", shift); - expr_ref last(m), round(m), sticky(m); - last = m_bv_util.mk_extract(sig_sz - bv_sz - 0, sig_sz - bv_sz - 0, r_shifted_sig); - round = m_bv_util.mk_extract(sig_sz - bv_sz - 1, sig_sz - bv_sz - 1, r_shifted_sig); - sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, l_shifted_sig.get()); + expr_ref big_sig_shifted(m), int_part(m), last(m), round(m), stickies(m), sticky(m); + big_sig_shifted = m.mk_ite(is_neg_shift, m_bv_util.mk_bv_lshr(big_sig, shift), + m_bv_util.mk_bv_shl(big_sig, shift)); + int_part = m_bv_util.mk_extract(big_sig_sz-1, big_sig_sz-bv_sz-3, big_sig_shifted); + SASSERT(m_bv_util.get_bv_size(int_part) == bv_sz+3); + last = m_bv_util.mk_extract(big_sig_sz-bv_sz-4, big_sig_sz-bv_sz-4, big_sig_shifted); + round = m_bv_util.mk_extract(big_sig_sz-bv_sz-5, big_sig_sz-bv_sz-5, big_sig_shifted); + stickies = m_bv_util.mk_extract(big_sig_sz-bv_sz-6, 0, big_sig_shifted); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, stickies); + dbg_decouple("fpa2bv_to_bv_big_sig_shifted", big_sig_shifted); + dbg_decouple("fpa2bv_to_bv_int_part", int_part); dbg_decouple("fpa2bv_to_bv_last", last); dbg_decouple("fpa2bv_to_bv_round", round); dbg_decouple("fpa2bv_to_bv_sticky", sticky); @@ -3335,30 +3329,31 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args SASSERT(m_bv_util.get_bv_size(rounding_decision) == 1); dbg_decouple("fpa2bv_to_bv_rounding_decision", rounding_decision); - expr_ref unrounded_sig(m), pre_rounded(m), inc(m); - unrounded_sig = m_bv_util.mk_zero_extend(1, m_bv_util.mk_extract(sig_sz - 1, sig_sz - bv_sz, r_shifted_sig)); - inc = m_bv_util.mk_zero_extend(1, m_bv_util.mk_zero_extend(bv_sz - 1, rounding_decision)); - pre_rounded = m_bv_util.mk_bv_add(unrounded_sig, inc); + expr_ref inc(m), pre_rounded(m); + inc = m_bv_util.mk_zero_extend(bv_sz+2, rounding_decision); + pre_rounded = m_bv_util.mk_bv_add(int_part, inc); dbg_decouple("fpa2bv_to_bv_inc", inc); dbg_decouple("fpa2bv_to_bv_pre_rounded", pre_rounded); - expr_ref rnd_overflow(m), rnd(m), rnd_has_overflown(m); - rnd_overflow = m_bv_util.mk_extract(bv_sz, bv_sz, pre_rounded); - rnd = m_bv_util.mk_extract(bv_sz - 1, 0, pre_rounded); - rnd_has_overflown = m.mk_eq(rnd_overflow, bv1); - dbg_decouple("fpa2bv_to_bv_rnd_has_overflown", rnd_has_overflown); - - if (is_signed) { - expr_ref sgn_eq_1(m), neg_rnd(m); - sgn_eq_1 = m.mk_eq(sgn, bv1); - neg_rnd = m_bv_util.mk_bv_neg(rnd); - m_simp.mk_ite(sgn_eq_1, neg_rnd, rnd, rnd); + expr_ref out_of_range(m); + if (!is_signed) { + expr_ref ul(m); + ul = m_bv_util.mk_zero_extend(3, m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz-1))); + out_of_range = m_bv_util.mk_ule(ul, pre_rounded); } + else { + expr_ref ll(m), ul(m); + ll = m_bv_util.mk_sign_extend(3, m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz-1))); + ul = m_bv_util.mk_zero_extend(4, m_bv_util.mk_numeral(-1, bv_sz-1)); + out_of_range = m.mk_not(m.mk_and(m_bv_util.mk_sle(ll, pre_rounded), m_bv_util.mk_sle(pre_rounded, ul))); + } + dbg_decouple("fpa2bv_to_bv_out_of_range", out_of_range); - dbg_decouple("fpa2bv_to_bv_rnd", rnd); + expr_ref rounded(m); + rounded = m_bv_util.mk_extract(bv_sz-1, 0, pre_rounded); + dbg_decouple("fpa2bv_to_bv_rounded", rounded); - result = m.mk_ite(rnd_has_overflown, unspec_v, rnd); - result = m.mk_ite(c_in_limits, result, unspec_v); + result = m.mk_ite(out_of_range, unspec_v, rounded); result = m.mk_ite(c2, v2, result); result = m.mk_ite(c1, v1, result); From 2165c09defb5a989ba703e9ca05eaf8aa0a1e203 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 13 Sep 2017 19:50:51 +0100 Subject: [PATCH 279/488] Improved FPA models of partial theory functions --- src/ast/fpa/bv2fpa_converter.cpp | 52 +++++++++++++++++--------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index 59f24779e..d3eedbf54 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -120,9 +120,9 @@ expr_ref bv2fpa_converter::convert_bv2fp(sort * s, expr * sgn, expr * exp, expr res = m_fpa_util.mk_value(fp_val); TRACE("bv2fpa", tout << "[" << mk_ismt2_pp(sgn, m) << - " " << mk_ismt2_pp(exp, m) << - " " << mk_ismt2_pp(sig, m) << "] == " << - mk_ismt2_pp(res, m) << std::endl;); + " " << mk_ismt2_pp(exp, m) << + " " << mk_ismt2_pp(sig, m) << "] == " << + mk_ismt2_pp(res, m) << std::endl;); m_fpa_util.fm().del(fp_val); return res; @@ -263,7 +263,7 @@ func_interp * bv2fpa_converter::convert_func_interp(model_core * mc, func_decl * unsigned arity = bv_f->get_arity(); func_interp * bv_fi = mc->get_func_interp(bv_f); - if (bv_fi != 0) { + if (bv_fi) { fpa_rewriter rw(m); expr_ref ai(m); result = alloc(func_interp, m, arity); @@ -384,7 +384,7 @@ void bv2fpa_converter::convert_rm_consts(model_core * mc, model_core * target_mo expr * bvval = to_app(val)->get_arg(0); expr_ref fv(m); fv = convert_bv2rm(mc, to_app(bvval)); - TRACE("bv2fpa", tout << var->get_name() << " == " << mk_ismt2_pp(fv, m) << ")" << std::endl;); + TRACE("bv2fpa", tout << var->get_name() << " == " << mk_ismt2_pp(fv, m) << std::endl;); target_model->register_decl(var, fv); seen.insert(to_app(bvval)->get_decl()); } @@ -455,11 +455,14 @@ void bv2fpa_converter::convert_uf2bvuf(model_core * mc, model_core * target_mode // Upon request, add this 'recursive' definition? func_interp * fmv = convert_func_interp(mc, f, it->m_value); - unsigned n = fmv->get_arity(); - expr_ref_vector args(m); - for (unsigned i = 0; i < n; i++) - args.push_back(m.mk_var(i, f->get_domain()[i])); - fmv->set_else(m.mk_app(it->m_key, n, args.c_ptr())); + if (fmv) { + unsigned n = fmv->get_arity(); + expr_ref_vector args(m); + for (unsigned i = 0; i < n; i++) + args.push_back(m.mk_var(i, f->get_domain()[i])); + fmv->set_else(m.mk_app(it->m_key, n, args.c_ptr())); + target_model->register_decl(f, fmv); + } } else { func_interp * fmv = convert_func_interp(mc, f, it->m_value); @@ -554,21 +557,20 @@ bv2fpa_converter * bv2fpa_converter::translate(ast_translation & translator) { void bv2fpa_converter::convert(model_core * mc, model_core * float_mdl) { TRACE("bv2fpa", tout << "BV Model: " << std::endl; - for (unsigned i = 0; i < mc->get_num_constants(); i++) - tout << mc->get_constant(i)->get_name() << " --> " << - mk_ismt2_pp(mc->get_const_interp(mc->get_constant(i)), m) << std::endl; - for (unsigned i = 0; i < mc->get_num_functions(); i++) { - func_decl * f = mc->get_function(i); - tout << f->get_name() << "(...) := " << std::endl; - func_interp * fi = mc->get_func_interp(f); - for (unsigned j = 0; j < fi->num_entries(); j++) { - func_entry const * fe = fi->get_entry(j); - for (unsigned k = 0; k < f->get_arity(); k++) { - tout << mk_ismt2_pp(fe->get_arg(k), m) << " "; + for (unsigned i = 0; i < mc->get_num_constants(); i++) + tout << mc->get_constant(i)->get_name() << " --> " << + mk_ismt2_pp(mc->get_const_interp(mc->get_constant(i)), m) << std::endl; + for (unsigned i = 0; i < mc->get_num_functions(); i++) { + func_decl * f = mc->get_function(i); + tout << f->get_name() << "(...) := " << std::endl; + func_interp * fi = mc->get_func_interp(f); + for (unsigned j = 0; j < fi->num_entries(); j++) { + func_entry const * fe = fi->get_entry(j); + for (unsigned k = 0; k < f->get_arity(); k++) + tout << mk_ismt2_pp(fe->get_arg(k), m) << " "; + tout << "--> " << mk_ismt2_pp(fe->get_result(), m) << std::endl; } - tout << "--> " << mk_ismt2_pp(fe->get_result(), m) << std::endl; - } - tout << "else " << mk_ismt2_pp(fi->get_else(), m) << std::endl; - }); + tout << "else " << mk_ismt2_pp(fi->get_else(), m) << std::endl; + }); } From 2bcbc5bb2fbe8711c790a05c5431301de2179f92 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 13 Sep 2017 20:15:11 +0100 Subject: [PATCH 280/488] Revert "[TravisCI] Temporarily disable the macOS build configuration." This reverts commit 9dc332ae9d4e1650af47daafe9821bbd8a2edf59. @wintersteiger is now satisfied that using TravisCI's macOS support is legal [1]. This fixes #1211 [1] https://github.com/Z3Prover/z3/issues/1211#issuecomment-328535885 --- .travis.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3764f8dac..50d63e593 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,17 +60,15 @@ env: - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug # macOS (a.k.a OSX) support -# FIXME: macOS support is temporarily disabled due to @wintersteiger 's concerns. -# See https://github.com/Z3Prover/z3/pull/1207#issuecomment-322200998 -# matrix: -# include: -# # For now just test a single configuration. macOS builds on TravisCI are -# # very slow so we should keep the number of configurations we test on this -# # OS to a minimum. -# - os: osx -# osx_image: xcode8.3 -# # Note: Apple Clang does not support OpenMP -# env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0 +matrix: + include: + # For now just test a single configuration. macOS builds on TravisCI are + # very slow so we should keep the number of configurations we test on this + # OS to a minimum. + - os: osx + osx_image: xcode8.3 + # Note: Apple Clang does not support OpenMP + env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0 script: # Use `travis_wait` when doing LTO builds because this configuration will # have long link times during which it will not show any output which From 8b6d7c0251722ba70b406759f935b7a8ea56fa37 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 14 Sep 2017 17:34:51 +0100 Subject: [PATCH 281/488] Style, formatting --- src/ackermannization/ackr_model_converter.cpp | 61 ++++++++++--------- src/ackermannization/ackr_model_converter.h | 8 +-- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/ackermannization/ackr_model_converter.cpp b/src/ackermannization/ackr_model_converter.cpp index 0697686eb..b48ab9af4 100644 --- a/src/ackermannization/ackr_model_converter.cpp +++ b/src/ackermannization/ackr_model_converter.cpp @@ -3,13 +3,13 @@ Copyright (c) 2015 Microsoft Corporation Module Name: -ackr_model_converter.cpp + ackr_model_converter.cpp Abstract: Author: -Mikolas Janota + Mikolas Janota Revision History: --*/ @@ -22,8 +22,8 @@ Revision History: class ackr_model_converter : public model_converter { public: ackr_model_converter(ast_manager & m, - const ackr_info_ref& info, - model_ref& abstr_model) + const ackr_info_ref& info, + model_ref& abstr_model) : m(m) , info(info) , abstr_model(abstr_model) @@ -31,7 +31,7 @@ public: { } ackr_model_converter(ast_manager & m, - const ackr_info_ref& info) + const ackr_info_ref& info) : m(m) , info(info) , fixed_model(false) @@ -51,8 +51,6 @@ public: virtual void operator()(model_ref & md) { operator()(md, 0); } - //void display(std::ostream & out); - virtual model_converter * translate(ast_translation & translator) { ackr_info_ref retv_info = info->translate(translator); if (fixed_model) { @@ -63,22 +61,23 @@ public: return alloc(ackr_model_converter, translator.to(), retv_info); } } + protected: - ast_manager& m; + ast_manager & m; const ackr_info_ref info; model_ref abstr_model; bool fixed_model; void convert(model * source, model * destination); void add_entry(model_evaluator & evaluator, - app* term, expr* value, - obj_map& interpretations); + app* term, expr* value, + obj_map& interpretations); void convert_constants(model * source, model * destination); }; void ackr_model_converter::convert(model * source, model * destination) { destination->copy_func_interps(*source); destination->copy_usort_interps(*source); - convert_constants(source,destination); + convert_constants(source, destination); } void ackr_model_converter::convert_constants(model * source, model * destination) { @@ -89,16 +88,17 @@ void ackr_model_converter::convert_constants(model * source, model * destination func_decl * const c = source->get_constant(i); app * const term = info->find_term(c); expr * value = source->get_const_interp(c); - if(!term) { + if (!term) { destination->register_decl(c, value); - } else { + } + else { add_entry(evaluator, term, value, interpretations); } } obj_map::iterator e = interpretations.end(); for (obj_map::iterator i = interpretations.begin(); - i!=e; ++i) { + i != e; ++i) { func_decl* const fd = i->m_key; func_interp* const fi = i->get_value(); fi->set_else(m.get_some_value(fd->get_range())); @@ -107,34 +107,35 @@ void ackr_model_converter::convert_constants(model * source, model * destination } void ackr_model_converter::add_entry(model_evaluator & evaluator, - app* term, expr* value, - obj_map& interpretations) { + app* term, expr* value, + obj_map& interpretations) { TRACE("ackr_model", tout << "add_entry" - << mk_ismt2_pp(term, m, 2) - << "->" - << mk_ismt2_pp(value, m, 2) << "\n"; + << mk_ismt2_pp(term, m, 2) + << "->" + << mk_ismt2_pp(value, m, 2) << "\n"; ); - func_interp* fi = 0; + func_interp * fi = 0; func_decl * const declaration = term->get_decl(); const unsigned sz = declaration->get_arity(); SASSERT(sz == term->get_num_args()); - if (!interpretations.find(declaration, fi)) { - fi = alloc(func_interp,m,sz); - interpretations.insert(declaration, fi); + if (!interpretations.find(declaration, fi)) { + fi = alloc(func_interp, m, sz); + interpretations.insert(declaration, fi); } expr_ref_vector args(m); for (unsigned gi = 0; gi < sz; ++gi) { - expr * const arg = term->get_arg(gi); - expr_ref aarg(m); - info->abstract(arg, aarg); - expr_ref arg_value(m); - evaluator(aarg,arg_value); - args.push_back(arg_value); + expr * const arg = term->get_arg(gi); + expr_ref aarg(m); + info->abstract(arg, aarg); + expr_ref arg_value(m); + evaluator(aarg, arg_value); + args.push_back(arg_value); } if (fi->get_entry(args.c_ptr()) == 0) { fi->insert_new_entry(args.c_ptr(), value); - } else { + } + else { TRACE("ackr_model", tout << "entry already present\n";); } } diff --git a/src/ackermannization/ackr_model_converter.h b/src/ackermannization/ackr_model_converter.h index cee7472aa..659b45926 100644 --- a/src/ackermannization/ackr_model_converter.h +++ b/src/ackermannization/ackr_model_converter.h @@ -3,13 +3,13 @@ Copyright (c) 2015 Microsoft Corporation Module Name: -ackr_model_converter.h + ackr_model_converter.h Abstract: Author: -Mikolas Janota + Mikolas Janota Revision History: --*/ @@ -19,7 +19,7 @@ Revision History: #include "tactic/model_converter.h" #include "ackermannization/ackr_info.h" -model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model); -model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info); +model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref & info, model_ref & abstr_model); +model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref & info); #endif /* LACKR_MODEL_CONVERTER_H_ */ From 5d341814d8049102429618a3aa6beed4dea9cf18 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 14 Sep 2017 17:46:17 +0100 Subject: [PATCH 282/488] Fixed bug in ackermannization model converter --- src/ackermannization/ackr_model_converter.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ackermannization/ackr_model_converter.cpp b/src/ackermannization/ackr_model_converter.cpp index b48ab9af4..a7c021913 100644 --- a/src/ackermannization/ackr_model_converter.cpp +++ b/src/ackermannization/ackr_model_converter.cpp @@ -84,6 +84,7 @@ void ackr_model_converter::convert_constants(model * source, model * destination TRACE("ackr_model", tout << "converting constants\n";); obj_map interpretations; model_evaluator evaluator(*source); + evaluator.set_model_completion(true); for (unsigned i = 0; i < source->get_num_constants(); i++) { func_decl * const c = source->get_constant(i); app * const term = info->find_term(c); @@ -133,6 +134,11 @@ void ackr_model_converter::add_entry(model_evaluator & evaluator, args.push_back(arg_value); } if (fi->get_entry(args.c_ptr()) == 0) { + TRACE("ackr_model", + tout << mk_ismt2_pp(declaration, m) << " args: " << std::endl; + for (unsigned i = 0; i < args.size(); i++) + tout << mk_ismt2_pp(args.get(i), m) << std::endl; + tout << " -> " << mk_ismt2_pp(value, m) << "\n"; ); fi->insert_new_entry(args.c_ptr(), value); } else { From a479fa610acb201136f6c488cc604b2e460d552f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 14 Sep 2017 20:29:07 +0100 Subject: [PATCH 283/488] Refactored treatment of unspecified FPA functions. --- src/ast/fpa/bv2fpa_converter.cpp | 7 +- src/ast/fpa/fpa2bv_converter.cpp | 10 +-- src/ast/fpa_decl_plugin.h | 3 +- src/ast/rewriter/fpa_rewriter.cpp | 144 ++++++++++++++++-------------- src/ast/rewriter/fpa_rewriter.h | 11 ++- 5 files changed, 95 insertions(+), 80 deletions(-) diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index d3eedbf54..2aa4dc31a 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -451,16 +451,19 @@ void bv2fpa_converter::convert_uf2bvuf(model_core * mc, model_core * target_mode else { if (it->get_key().get_family_id() == m_fpa_util.get_fid()) { // it->m_value contains the model for the unspecified cases of it->m_key. - continue; - // Upon request, add this 'recursive' definition? func_interp * fmv = convert_func_interp(mc, f, it->m_value); if (fmv) { +#if 0 + // Upon request, add this 'recursive' definition? unsigned n = fmv->get_arity(); expr_ref_vector args(m); for (unsigned i = 0; i < n; i++) args.push_back(m.mk_var(i, f->get_domain()[i])); fmv->set_else(m.mk_app(it->m_key, n, args.c_ptr())); +#else + fmv->set_else(0); +#endif target_model->register_decl(f, fmv); } } diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 190e86da3..f0707a273 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2582,7 +2582,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); - if (m_bv_util.is_numeral(bv_rm) && m_util.au().is_numeral(x)) { + if (m_bv_util.is_numeral(bv_rm) && m_util.arith_util().is_numeral(x)) { rational tmp_rat; unsigned sz; m_bv_util.is_numeral(to_expr(bv_rm), tmp_rat, sz); SASSERT(tmp_rat.is_int32()); @@ -2600,7 +2600,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * rational q; bool is_int; - m_util.au().is_numeral(x, q, is_int); + m_util.arith_util().is_numeral(x, q, is_int); if (q.is_zero()) return mk_pzero(f, result); @@ -2617,12 +2617,12 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * result = m_util.mk_fp(sgn, exp, sig); } } - else if (m_util.au().is_numeral(x)) { + else if (m_util.arith_util().is_numeral(x)) { rational q; bool is_int; - m_util.au().is_numeral(x, q, is_int); + m_util.arith_util().is_numeral(x, q, is_int); - if (m_util.au().is_zero(x)) + if (m_util.arith_util().is_zero(x)) mk_pzero(f, result); else { expr_ref rm_nta(m), rm_nte(m), rm_tp(m), rm_tn(m), rm_tz(m); diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 79f44a13d..b4730cc75 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -221,7 +221,8 @@ public: mpf_manager & fm() const { return m_plugin->fm(); } family_id get_fid() const { return m_fid; } family_id get_family_id() const { return m_fid; } - arith_util & au() { return m_a_util; } + arith_util & arith_util() { return m_a_util; } + bv_util & bv_util() { return m_bv_util; } fpa_decl_plugin & plugin() { return *m_plugin; } sort * mk_float_sort(unsigned ebits, unsigned sbits); diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 644aff630..6c7190ebc 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -113,7 +113,6 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const SASSERT(f->get_num_parameters() == 2); SASSERT(f->get_parameter(0).is_int()); SASSERT(f->get_parameter(1).is_int()); - bv_util bu(m()); scoped_mpf v(m_fm); mpf_rounding_mode rmv; rational r1, r2, r3; @@ -122,7 +121,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const unsigned sbits = f->get_parameter(1).get_int(); if (num_args == 1) { - if (bu.is_numeral(args[0], r1, bvs1)) { + if (m_util.bv_util().is_numeral(args[0], r1, bvs1)) { // BV -> float SASSERT(bvs1 == sbits + ebits); unsynch_mpz_manager & mpzm = m_fm.mpz_manager(); @@ -163,7 +162,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const if (!m_util.is_rm_numeral(args[0], rmv)) return BR_FAILED; - if (m_util.au().is_numeral(args[1], r1)) { + if (m_util.arith_util().is_numeral(args[1], r1)) { // rm + real -> float TRACE("fp_rewriter", tout << "r: " << r1 << std::endl;); scoped_mpf v(m_fm); @@ -181,10 +180,10 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const // TRACE("fp_rewriter", tout << "result: " << result << std::endl; ); return BR_DONE; } - else if (bu.is_numeral(args[1], r1, bvs1)) { + else if (m_util.bv_util().is_numeral(args[1], r1, bvs1)) { // rm + signed bv -> float TRACE("fp_rewriter", tout << "r1: " << r1 << std::endl;); - r1 = bu.norm(r1, bvs1, true); + r1 = m_util.bv_util().norm(r1, bvs1, true); TRACE("fp_rewriter", tout << "r1 norm: " << r1 << std::endl;); m_fm.set(v, ebits, sbits, rmv, r1.to_mpq()); result = m_util.mk_value(v); @@ -193,12 +192,12 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const } else if (num_args == 3) { if (m_util.is_rm_numeral(args[0], rmv) && - m_util.au().is_real(args[1]) && - m_util.au().is_int(args[2])) { + m_util.arith_util().is_real(args[1]) && + m_util.arith_util().is_int(args[2])) { // rm + real + int -> float if (!m_util.is_rm_numeral(args[0], rmv) || - !m_util.au().is_numeral(args[1], r1) || - !m_util.au().is_numeral(args[2], r2)) + !m_util.arith_util().is_numeral(args[1], r1) || + !m_util.arith_util().is_numeral(args[2], r2)) return BR_FAILED; TRACE("fp_rewriter", tout << "r1: " << r1 << ", r2: " << r2 << "\n";); @@ -207,12 +206,12 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const return BR_DONE; } else if (m_util.is_rm_numeral(args[0], rmv) && - m_util.au().is_int(args[1]) && - m_util.au().is_real(args[2])) { + m_util.arith_util().is_int(args[1]) && + m_util.arith_util().is_real(args[2])) { // rm + int + real -> float if (!m_util.is_rm_numeral(args[0], rmv) || - !m_util.au().is_numeral(args[1], r1) || - !m_util.au().is_numeral(args[2], r2)) + !m_util.arith_util().is_numeral(args[1], r1) || + !m_util.arith_util().is_numeral(args[2], r2)) return BR_FAILED; TRACE("fp_rewriter", tout << "r1: " << r1 << ", r2: " << r2 << "\n";); @@ -220,9 +219,9 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const result = m_util.mk_value(v); return BR_DONE; } - else if (bu.is_numeral(args[0], r1, bvs1) && - bu.is_numeral(args[1], r2, bvs2) && - bu.is_numeral(args[2], r3, bvs3)) { + else if (m_util.bv_util().is_numeral(args[0], r1, bvs1) && + m_util.bv_util().is_numeral(args[1], r2, bvs2) && + m_util.bv_util().is_numeral(args[2], r3, bvs3)) { // 3 BV -> float SASSERT(m_fm.mpz_manager().is_one(r2.to_mpq().denominator())); SASSERT(m_fm.mpz_manager().is_one(r3.to_mpq().denominator())); @@ -245,7 +244,6 @@ br_status fpa_rewriter::mk_to_fp_unsigned(func_decl * f, expr * arg1, expr * arg SASSERT(f->get_num_parameters() == 2); SASSERT(f->get_parameter(0).is_int()); SASSERT(f->get_parameter(1).is_int()); - bv_util bu(m()); unsigned ebits = f->get_parameter(0).get_int(); unsigned sbits = f->get_parameter(1).get_int(); mpf_rounding_mode rmv; @@ -253,7 +251,7 @@ br_status fpa_rewriter::mk_to_fp_unsigned(func_decl * f, expr * arg1, expr * arg unsigned bvs; if (m_util.is_rm_numeral(arg1, rmv) && - bu.is_numeral(arg2, r, bvs)) { + m_util.bv_util().is_numeral(arg2, r, bvs)) { scoped_mpf v(m_fm); m_fm.set(v, ebits, sbits, rmv, r.to_mpq()); result = m_util.mk_value(v); @@ -286,6 +284,7 @@ br_status fpa_rewriter::mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref & br_status fpa_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_fm), v3(m_fm); if (m_util.is_numeral(arg2, v2) && m_util.is_numeral(arg3, v3)) { @@ -301,6 +300,7 @@ br_status fpa_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & br_status fpa_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_fm), v3(m_fm); if (m_util.is_numeral(arg2, v2) && m_util.is_numeral(arg3, v3)) { @@ -310,7 +310,6 @@ br_status fpa_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & return BR_DONE; } } - return BR_FAILED; } @@ -348,6 +347,7 @@ br_status fpa_rewriter::mk_neg(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_rem(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_fm), v2(m_fm); + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { scoped_mpf t(m_fm); m_fm.rem(v1, v2, t); @@ -411,6 +411,7 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { br_status fpa_rewriter::mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_fm), v2(m_fm); + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); @@ -418,6 +419,7 @@ br_status fpa_rewriter::mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_r result = m_util.mk_min(arg1, arg2); return BR_DONE; } + return BR_FAILED; } @@ -458,6 +460,7 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { br_status fpa_rewriter::mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_fm), v2(m_fm); + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); @@ -465,11 +468,13 @@ br_status fpa_rewriter::mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_r result = m_util.mk_max(arg1, arg2); return BR_DONE; } + return BR_FAILED; } br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { mpf_rounding_mode rm; + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_fm), v3(m_fm), v4(m_fm); if (m_util.is_numeral(arg2, v2) && m_util.is_numeral(arg3, v3) && m_util.is_numeral(arg4, v4)) { @@ -485,6 +490,7 @@ br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg br_status fpa_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { mpf_rounding_mode rm; + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_fm); if (m_util.is_numeral(arg2, v2)) { @@ -500,6 +506,7 @@ br_status fpa_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { br_status fpa_rewriter::mk_round_to_integral(expr * arg1, expr * arg2, expr_ref & result) { mpf_rounding_mode rm; + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_fm); if (m_util.is_numeral(arg2, v2)) { @@ -567,7 +574,6 @@ br_status fpa_rewriter::mk_lt(expr * arg1, expr * arg2, expr_ref & result) { return BR_DONE; } - // TODO: more simplifications return BR_FAILED; } @@ -631,6 +637,7 @@ br_status fpa_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_nan(expr * arg1, expr_ref & result) { scoped_mpf v(m_fm); + if (m_util.is_numeral(arg1, v)) { result = (m_fm.is_nan(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; @@ -641,6 +648,7 @@ br_status fpa_rewriter::mk_is_nan(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_inf(expr * arg1, expr_ref & result) { scoped_mpf v(m_fm); + if (m_util.is_numeral(arg1, v)) { result = (m_fm.is_inf(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; @@ -651,6 +659,7 @@ br_status fpa_rewriter::mk_is_inf(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_normal(expr * arg1, expr_ref & result) { scoped_mpf v(m_fm); + if (m_util.is_numeral(arg1, v)) { result = (m_fm.is_normal(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; @@ -661,6 +670,7 @@ br_status fpa_rewriter::mk_is_normal(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { scoped_mpf v(m_fm); + if (m_util.is_numeral(arg1, v)) { result = (m_fm.is_denormal(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; @@ -671,6 +681,7 @@ br_status fpa_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { scoped_mpf v(m_fm); + if (m_util.is_numeral(arg1, v)) { result = (m_fm.is_neg(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; @@ -681,6 +692,7 @@ br_status fpa_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { scoped_mpf v(m_fm); + if (m_util.is_numeral(arg1, v)) { result = (m_fm.is_neg(v) || m_fm.is_nan(v)) ? m().mk_false() : m().mk_true(); return BR_DONE; @@ -693,6 +705,7 @@ br_status fpa_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { // This the SMT = br_status fpa_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_fm), v2(m_fm); + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { // Note: == is the floats-equality, here we need normal equality. result = (m_fm.is_nan(v1) && m_fm.is_nan(v2)) ? m().mk_true() : @@ -706,10 +719,10 @@ br_status fpa_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) } br_status fpa_rewriter::mk_bv2rm(expr * arg, expr_ref & result) { - bv_util bu(m()); rational bv_val; unsigned sz = 0; - if (bu.is_numeral(arg, bv_val, sz)) { + + if (m_util.bv_util().is_numeral(arg, bv_val, sz)) { SASSERT(bv_val.is_uint64()); switch (bv_val.get_uint64()) { case BV_RM_TIES_TO_AWAY: result = m_util.mk_round_nearest_ties_to_away(); break; @@ -728,13 +741,12 @@ br_status fpa_rewriter::mk_bv2rm(expr * arg, expr_ref & result) { br_status fpa_rewriter::mk_fp(expr * sgn, expr * exp, expr * sig, expr_ref & result) { unsynch_mpz_manager & mpzm = m_fm.mpz_manager(); - bv_util bu(m()); rational rsgn, rexp, rsig; unsigned bvsz_sgn, bvsz_exp, bvsz_sig; - if (bu.is_numeral(sgn, rsgn, bvsz_sgn) && - bu.is_numeral(sig, rsig, bvsz_sig) && - bu.is_numeral(exp, rexp, bvsz_exp)) { + if (m_util.bv_util().is_numeral(sgn, rsgn, bvsz_sgn) && + m_util.bv_util().is_numeral(sig, rsig, bvsz_sig) && + m_util.bv_util().is_numeral(exp, rexp, bvsz_exp)) { SASSERT(mpzm.is_one(rexp.to_mpq().denominator())); SASSERT(mpzm.is_one(rsig.to_mpq().denominator())); scoped_mpf v(m_fm); @@ -751,38 +763,7 @@ br_status fpa_rewriter::mk_fp(expr * sgn, expr * exp, expr * sig, expr_ref & res return BR_FAILED; } -br_status fpa_rewriter::mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { - SASSERT(f->get_num_parameters() == 1); - SASSERT(f->get_parameter(0).is_int()); - int bv_sz = f->get_parameter(0).get_int(); - mpf_rounding_mode rmv; - scoped_mpf v(m_fm); - - if (m_util.is_rm_numeral(arg1, rmv) && - m_util.is_numeral(arg2, v)) { - const mpf & x = v.get(); - - if (m_fm.is_nan(v) || m_fm.is_inf(v) || m_fm.is_neg(v)) - return BR_FAILED; - - bv_util bu(m()); - scoped_mpq q(m_fm.mpq_manager()); - m_fm.to_sbv_mpq(rmv, v, q); - - rational r(q); - rational ul, ll; - ul = m_fm.m_powers2.m1(bv_sz); - ll = rational(0); - if (r >= ll && r <= ul) { - result = bu.mk_numeral(r, bv_sz); - return BR_DONE; - } - } - - return BR_FAILED; -} - -br_status fpa_rewriter::mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_to_bv(func_decl * f, expr * arg1, expr * arg2, bool is_signed, expr_ref & result) { SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_int()); int bv_sz = f->get_parameter(0).get_int(); @@ -794,7 +775,7 @@ br_status fpa_rewriter::mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ const mpf & x = v.get(); if (m_fm.is_nan(v) || m_fm.is_inf(v)) - return BR_FAILED; + return mk_to_bv_unspecified(f, result); bv_util bu(m()); scoped_mpq q(m_fm.mpq_manager()); @@ -802,17 +783,43 @@ br_status fpa_rewriter::mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ rational r(q); rational ul, ll; - ul = m_fm.m_powers2.m1(bv_sz - 1); - ll = - m_fm.m_powers2(bv_sz - 1); + if (!is_signed) { + ul = m_fm.m_powers2.m1(bv_sz); + ll = rational(0); + } + else { + ul = m_fm.m_powers2.m1(bv_sz - 1); + ll = -m_fm.m_powers2(bv_sz - 1); + } if (r >= ll && r <= ul) { result = bu.mk_numeral(r, bv_sz); return BR_DONE; } + else + return mk_to_bv_unspecified(f, result); } return BR_FAILED; } +br_status fpa_rewriter::mk_to_bv_unspecified(func_decl * f, expr_ref & result) { + if (m_hi_fp_unspecified) { + unsigned bv_sz = m_util.bv_util().get_bv_size(f->get_range()); + result = m_util.bv_util().mk_numeral(0, bv_sz); + return BR_DONE; + } + else + return BR_FAILED; +} + +br_status fpa_rewriter::mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { + return mk_to_bv(f, arg1, arg2, false, result); +} + +br_status fpa_rewriter::mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { + return mk_to_bv(f, arg1, arg2, true, result); +} + br_status fpa_rewriter::mk_to_ieee_bv(func_decl * f, expr * arg, expr_ref & result) { TRACE("fp_rewriter", tout << "to_ieee_bv of " << mk_ismt2_pp(arg, m()) << std::endl;); scoped_mpf v(m_fm); @@ -829,11 +836,8 @@ br_status fpa_rewriter::mk_to_ieee_bv(func_decl * f, expr * arg, expr_ref & resu bu.mk_numeral(0, x.get_sbits() - 2), bu.mk_numeral(1, 1) }; result = bu.mk_concat(4, args); + return BR_REWRITE1; } - else - return BR_FAILED; - - return BR_REWRITE1; } else { scoped_mpz rz(m_fm.mpq_manager()); @@ -851,9 +855,17 @@ br_status fpa_rewriter::mk_to_real(expr * arg, expr_ref & result) { if (m_util.is_numeral(arg, v)) { if (!m_fm.is_nan(v) && !m_fm.is_inf(v)) { + if (m_hi_fp_unspecified) { + result = m_util.arith_util().mk_numeral(rational(0), false); + return BR_DONE; + } + else + return BR_FAILED; + } + else { scoped_mpq r(m_fm.mpq_manager()); m_fm.to_rational(v, r); - result = m_util.au().mk_numeral(r.get(), false); + result = m_util.arith_util().mk_numeral(r.get(), false); return BR_DONE; } } diff --git a/src/ast/rewriter/fpa_rewriter.h b/src/ast/rewriter/fpa_rewriter.h index 5d5b7e57d..cfa1bea52 100644 --- a/src/ast/rewriter/fpa_rewriter.h +++ b/src/ast/rewriter/fpa_rewriter.h @@ -21,8 +21,9 @@ Notes: #include "ast/ast.h" #include "ast/rewriter/rewriter.h" -#include "util/params.h" #include "ast/fpa_decl_plugin.h" +#include "ast/expr_map.h" +#include "util/params.h" #include "util/mpf.h" class fpa_rewriter { @@ -33,6 +34,9 @@ class fpa_rewriter { app * mk_eq_nan(expr * arg); app * mk_neq_nan(expr * arg); + br_status mk_to_bv(func_decl * f, expr * arg1, expr * arg2, bool is_signed, expr_ref & result); + br_status mk_to_bv_unspecified(func_decl * f, expr_ref & result); + public: fpa_rewriter(ast_manager & m, params_ref const & p = params_ref()); ~fpa_rewriter(); @@ -73,14 +77,11 @@ public: br_status mk_is_negative(expr * arg1, expr_ref & result); br_status mk_is_positive(expr * arg1, expr_ref & result); - br_status mk_to_ieee_bv(expr * arg1, expr_ref & result); - br_status mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); br_status mk_to_fp_unsigned(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_bv2rm(expr * arg, expr_ref & result); br_status mk_fp(expr * sgn, expr * exp, expr * sig, expr_ref & result); - br_status mk_to_fp_unsigned(expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_sbv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ieee_bv(func_decl * f, expr * arg, expr_ref & result); @@ -88,8 +89,6 @@ public: br_status mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); - br_status mk_to_real_unspecified(unsigned ebits, unsigned sbits, expr * n, expr_ref & result); - br_status mk_bvwrap(expr * arg, expr_ref & result); }; From 2688fd55cf79d8dcb2a5a509cb68f60ac92ad759 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 14 Sep 2017 20:29:54 +0100 Subject: [PATCH 284/488] Taught the model_evaluator to look for definitions of partial theory functions in the model upon evaluation failure. --- src/model/model_evaluator.cpp | 127 ++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 51 deletions(-) diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp index 2b8f8abd6..32ed1e236 100644 --- a/src/model/model_evaluator.cpp +++ b/src/model/model_evaluator.cpp @@ -33,9 +33,11 @@ Revision History: #include "ast/ast_pp.h" #include "ast/ast_util.h" #include "model/model_smt2_pp.h" +#include "ast/rewriter/var_subst.h" struct evaluator_cfg : public default_rewriter_cfg { + ast_manager & m; model_core & m_model; bool_rewriter m_b_rw; arith_rewriter m_a_rw; @@ -53,6 +55,7 @@ struct evaluator_cfg : public default_rewriter_cfg { bool m_array_equalities; evaluator_cfg(ast_manager & m, model_core & md, params_ref const & p): + m(m), m_model(md), m_b_rw(m), // We must allow customers to set parameters for arithmetic rewriter/evaluator. @@ -74,6 +77,7 @@ struct evaluator_cfg : public default_rewriter_cfg { m_ar_rw.set_expand_select_store(true); m_ar_rw.set_expand_select_ite(true); updt_params(p); + //add_unspecified_function_models(md); } void updt_params(params_ref const & _p) { @@ -85,10 +89,8 @@ struct evaluator_cfg : public default_rewriter_cfg { m_array_equalities = p.array_equalities(); } - ast_manager & m() const { return m_model.get_manager(); } - - bool evaluate(func_decl* f, unsigned num, expr * const * args, expr_ref & result) { - func_interp* fi = m_model.get_func_interp(f); + bool evaluate(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + func_interp * fi = m_model.get_func_interp(f); return (fi != 0) && eval_fi(fi, num, args, result); } @@ -101,9 +103,8 @@ struct evaluator_cfg : public default_rewriter_cfg { bool actuals_are_values = true; - for (unsigned i = 0; actuals_are_values && i < num; i++) { - actuals_are_values = m().is_value(args[i]); - } + for (unsigned i = 0; actuals_are_values && i < num; i++) + actuals_are_values = m.is_value(args[i]); if (!actuals_are_values) return false; // let get_macro handle it @@ -120,7 +121,7 @@ struct evaluator_cfg : public default_rewriter_cfg { br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { result_pr = 0; family_id fid = f->get_family_id(); - bool is_uninterp = fid != null_family_id && m().get_plugin(fid)->is_considered_uninterpreted(f); + bool is_uninterp = fid != null_family_id && m.get_plugin(fid)->is_considered_uninterpreted(f); if (num == 0 && (fid == null_family_id || is_uninterp)) { expr * val = m_model.get_const_interp(f); if (val != 0) { @@ -145,7 +146,7 @@ struct evaluator_cfg : public default_rewriter_cfg { if (k == OP_EQ) { // theory dispatch for = SASSERT(num == 2); - family_id s_fid = m().get_sort(args[0])->get_family_id(); + family_id s_fid = m.get_sort(args[0])->get_family_id(); if (s_fid == m_a_rw.get_fid()) st = m_a_rw.mk_eq_core(args[0], args[1], result); else if (s_fid == m_bv_rw.get_fid()) @@ -178,16 +179,18 @@ struct evaluator_cfg : public default_rewriter_cfg { st = m_f_rw.mk_app_core(f, num, args, result); else if (fid == m_seq_rw.get_fid()) st = m_seq_rw.mk_app_core(f, num, args, result); - else if (fid == m().get_label_family_id() && num == 1) { + else if (fid == m.get_label_family_id() && num == 1) { result = args[0]; st = BR_DONE; } else if (evaluate(f, num, args, result)) { TRACE("model_evaluator", tout << "reduce_app " << f->get_name() << "\n"; - for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << "\n"; - tout << "---->\n" << mk_ismt2_pp(result, m()) << "\n";); + for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m) << "\n"; + tout << "---->\n" << mk_ismt2_pp(result, m) << "\n";); return BR_DONE; } + if (st == BR_FAILED && !m.is_builtin_family_id(fid)) + st = evaluate_partial_theory_func(f, num, args, result, result_pr); if (st == BR_DONE && is_app(result)) { app* a = to_app(result); if (evaluate(a->get_decl(), a->get_num_args(), a->get_args(), result)) { @@ -200,14 +203,14 @@ struct evaluator_cfg : public default_rewriter_cfg { void expand_value(expr_ref& val) { vector stores; - expr_ref else_case(m()); + expr_ref else_case(m); bool _unused; if (m_ar.is_array(val) && extract_array_func_interp(val, stores, else_case, _unused)) { - sort* srt = m().get_sort(val); + sort* srt = m.get_sort(val); val = m_ar.mk_const_array(srt, else_case); for (unsigned i = stores.size(); i > 0; ) { --i; - expr_ref_vector args(m()); + expr_ref_vector args(m); args.push_back(val); args.append(stores[i].size(), stores[i].c_ptr()); val = m_ar.mk_store(args.size(), args.c_ptr()); @@ -220,6 +223,7 @@ struct evaluator_cfg : public default_rewriter_cfg { #define TRACE_MACRO TRACE("model_evaluator", tout << "get_macro for " << f->get_name() << " (model completion: " << m_model_completion << ")\n";); func_interp * fi = m_model.get_func_interp(f); + if (fi != 0) { TRACE_MACRO; if (fi->is_partial()) { @@ -228,31 +232,52 @@ struct evaluator_cfg : public default_rewriter_cfg { expr * val = m_model.get_some_value(s); fi->set_else(val); } - else { + else return false; - } } - def = fi->get_interp(); + def = fi->get_interp(); SASSERT(def != 0); return true; } if (m_model_completion && (f->get_family_id() == null_family_id || - m().get_plugin(f->get_family_id())->is_considered_uninterpreted(f))) + m.get_plugin(f->get_family_id())->is_considered_uninterpreted(f))) { TRACE_MACRO; sort * s = f->get_range(); expr * val = m_model.get_some_value(s); - func_interp * new_fi = alloc(func_interp, m(), f->get_arity()); + func_interp * new_fi = alloc(func_interp, m, f->get_arity()); new_fi->set_else(val); m_model.register_decl(f, new_fi); def = val; return true; } + return false; } + br_status evaluate_partial_theory_func(func_decl * f, + unsigned num, expr * const * args, + expr_ref & result, proof_ref & result_pr) { + SASSERT(f != 0); + SASSERT(!m.is_builtin_family_id(f->get_family_id())); + result = 0; + result_pr = 0; + + func_interp * fi = m_model.get_func_interp(f); + if (fi) { + if (fi->is_partial()) + fi->set_else(m.get_some_value(f->get_range())); + + var_subst vs(m, false); + vs(fi->get_interp(), num, args, result); + return BR_REWRITE_FULL; + } + + return BR_FAILED; + } + bool max_steps_exceeded(unsigned num_steps) const { cooperate("model evaluator"); @@ -266,7 +291,7 @@ struct evaluator_cfg : public default_rewriter_cfg { br_status mk_array_eq(expr* a, expr* b, expr_ref& result) { if (a == b) { - result = m().mk_true(); + result = m.mk_true(); return BR_DONE; } if (!m_array_equalities) { @@ -275,19 +300,19 @@ struct evaluator_cfg : public default_rewriter_cfg { vector stores1, stores2; bool args_are_unique1, args_are_unique2; - expr_ref else1(m()), else2(m()); + expr_ref else1(m), else2(m); if (extract_array_func_interp(a, stores1, else1, args_are_unique1) && extract_array_func_interp(b, stores2, else2, args_are_unique2)) { - expr_ref_vector conj(m()), args1(m()), args2(m()); - if (m().are_equal(else1, else2)) { + expr_ref_vector conj(m), args1(m), args2(m); + if (m.are_equal(else1, else2)) { // no op } - else if (m().are_distinct(else1, else2) && !(m().get_sort(else1)->get_info()->get_num_elements().is_finite())) { - result = m().mk_false(); + else if (m.are_distinct(else1, else2) && !(m.get_sort(else1)->get_info()->get_num_elements().is_finite())) { + result = m.mk_false(); return BR_DONE; } else { - conj.push_back(m().mk_eq(else1, else2)); + conj.push_back(m.mk_eq(else1, else2)); } if (args_are_unique1 && args_are_unique2 && !stores1.empty()) { return mk_array_eq_core(stores1, else1, stores2, else2, conj, result); @@ -300,11 +325,11 @@ struct evaluator_cfg : public default_rewriter_cfg { for (unsigned i = 0; i < stores1.size(); ++i) { args1.resize(1); args1.append(stores1[i].size() - 1, stores1[i].c_ptr()); args2.resize(1); args2.append(stores1[i].size() - 1, stores1[i].c_ptr()); - expr_ref s1(m_ar.mk_select(args1.size(), args1.c_ptr()), m()); - expr_ref s2(m_ar.mk_select(args2.size(), args2.c_ptr()), m()); - conj.push_back(m().mk_eq(s1, s2)); + expr_ref s1(m_ar.mk_select(args1.size(), args1.c_ptr()), m); + expr_ref s2(m_ar.mk_select(args2.size(), args2.c_ptr()), m); + conj.push_back(m.mk_eq(s1, s2)); } - result = m().mk_and(conj.size(), conj.c_ptr()); + result = m.mk_and(conj.size(), conj.c_ptr()); return BR_REWRITE_FULL; } return BR_FAILED; @@ -362,15 +387,15 @@ struct evaluator_cfg : public default_rewriter_cfg { if (table1.find(stores2[i].c_ptr(), args)) { switch (compare(args[arity], val)) { case l_true: table1.remove(args); break; - case l_false: result = m().mk_false(); return BR_DONE; - default: conj.push_back(m().mk_eq(val, args[arity])); break; + case l_false: result = m.mk_false(); return BR_DONE; + default: conj.push_back(m.mk_eq(val, args[arity])); break; } } else { switch (compare(else1, val)) { case l_true: break; - case l_false: result = m().mk_false(); return BR_DONE; - default: conj.push_back(m().mk_eq(else1, val)); break; + case l_false: result = m.mk_false(); return BR_DONE; + default: conj.push_back(m.mk_eq(else1, val)); break; } } } @@ -378,8 +403,8 @@ struct evaluator_cfg : public default_rewriter_cfg { for (; it != end; ++it) { switch (compare((*it)[arity], else2)) { case l_true: break; - case l_false: result = m().mk_false(); return BR_DONE; - default: conj.push_back(m().mk_eq((*it)[arity], else2)); break; + case l_false: result = m.mk_false(); return BR_DONE; + default: conj.push_back(m.mk_eq((*it)[arity], else2)); break; } } result = mk_and(conj); @@ -387,8 +412,8 @@ struct evaluator_cfg : public default_rewriter_cfg { } lbool compare(expr* a, expr* b) { - if (m().are_equal(a, b)) return l_true; - if (m().are_distinct(a, b)) return l_false; + if (m.are_equal(a, b)) return l_true; + if (m.are_distinct(a, b)) return l_false; return l_undef; } @@ -396,8 +421,8 @@ struct evaluator_cfg : public default_rewriter_cfg { bool args_are_values(expr_ref_vector const& store, bool& are_unique) { bool are_values = true; for (unsigned j = 0; are_values && j + 1 < store.size(); ++j) { - are_values = m().is_value(store[j]); - are_unique &= m().is_unique_value(store[j]); + are_values = m.is_value(store[j]); + are_unique &= m.is_unique_value(store[j]); } SASSERT(!are_unique || are_values); return are_values; @@ -408,10 +433,10 @@ struct evaluator_cfg : public default_rewriter_cfg { SASSERT(m_ar.is_array(a)); bool are_values = true; are_unique = true; - TRACE("model_evaluator", tout << mk_pp(a, m()) << "\n";); + TRACE("model_evaluator", tout << mk_pp(a, m) << "\n";); while (m_ar.is_store(a)) { - expr_ref_vector store(m()); + expr_ref_vector store(m); store.append(to_app(a)->get_num_args()-1, to_app(a)->get_args()+1); are_values &= args_are_values(store, are_unique); stores.push_back(store); @@ -424,7 +449,7 @@ struct evaluator_cfg : public default_rewriter_cfg { } if (!m_ar.is_as_array(a)) { - TRACE("model_evaluator", tout << "no translation: " << mk_pp(a, m()) << "\n";); + TRACE("model_evaluator", tout << "no translation: " << mk_pp(a, m) << "\n";); return false; } @@ -434,13 +459,13 @@ struct evaluator_cfg : public default_rewriter_cfg { unsigned arity = f->get_arity(); unsigned base_sz = stores.size(); for (unsigned i = 0; i < sz; ++i) { - expr_ref_vector store(m()); + expr_ref_vector store(m); func_entry const* fe = g->get_entry(i); store.append(arity, fe->get_args()); store.push_back(fe->get_result()); for (unsigned j = 0; j < store.size(); ++j) { if (!is_ground(store[j].get())) { - TRACE("model_evaluator", tout << "could not extract array interpretation: " << mk_pp(a, m()) << "\n" << mk_pp(store[j].get(), m()) << "\n";); + TRACE("model_evaluator", tout << "could not extract array interpretation: " << mk_pp(a, m) << "\n" << mk_pp(store[j].get(), m) << "\n";); return false; } } @@ -448,18 +473,18 @@ struct evaluator_cfg : public default_rewriter_cfg { } else_case = g->get_else(); if (!else_case) { - TRACE("model_evaluator", tout << "no else case " << mk_pp(a, m()) << "\n"; - /*model_smt2_pp(tout, m(), m_model, 0);*/ + TRACE("model_evaluator", tout << "no else case " << mk_pp(a, m) << "\n"; + /*model_smt2_pp(tout, m, m_model, 0);*/ ); return false; } if (!is_ground(else_case)) { - TRACE("model_evaluator", tout << "non-ground else case " << mk_pp(a, m()) << "\n" << else_case << "\n";); + TRACE("model_evaluator", tout << "non-ground else case " << mk_pp(a, m) << "\n" << else_case << "\n";); return false; } for (unsigned i = stores.size(); are_values && i > base_sz; ) { --i; - if (m().are_equal(else_case, stores[i].back())) { + if (m.are_equal(else_case, stores[i].back())) { for (unsigned j = i + 1; j < stores.size(); ++j) { stores[j-1].reset(); stores[j-1].append(stores[j]); @@ -469,7 +494,7 @@ struct evaluator_cfg : public default_rewriter_cfg { } are_values &= args_are_values(stores[i], are_unique); } - TRACE("model_evaluator", tout << "else case: " << mk_pp(else_case, m()) << "\n";); + TRACE("model_evaluator", tout << "else case: " << mk_pp(else_case, m) << "\n";); return true; } From d82afcc48c9682765b9ca4a6bbe879a6a4369e9e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 15 Sep 2017 11:37:32 +0100 Subject: [PATCH 285/488] Whitespace --- src/tactic/fpa/fpa2bv_model_converter.cpp | 6 +++--- src/tactic/fpa/fpa2bv_model_converter.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 8ebb3375d..e82c06386 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -38,7 +38,7 @@ void fpa2bv_model_converter::convert(model_core * mc, model * float_mdl) { m_bv2fp->convert_rm_consts(mc, float_mdl, seen); m_bv2fp->convert_min_max_specials(mc, float_mdl, seen); m_bv2fp->convert_uf2bvuf(mc, float_mdl, seen); - + // Keep all the non-float constants. unsigned sz = mc->get_num_constants(); for (unsigned i = 0; i < sz; i++) { @@ -46,7 +46,7 @@ void fpa2bv_model_converter::convert(model_core * mc, model * float_mdl) { if (!seen.contains(c)) float_mdl->register_decl(c, mc->get_const_interp(c)); } - + // And keep everything else sz = mc->get_num_functions(); for (unsigned i = 0; i < sz; i++) { @@ -57,7 +57,7 @@ void fpa2bv_model_converter::convert(model_core * mc, model * float_mdl) { float_mdl->register_decl(f, val); } } - + sz = mc->get_num_uninterpreted_sorts(); for (unsigned i = 0; i < sz; i++) { sort * s = mc->get_uninterpreted_sort(i); diff --git a/src/tactic/fpa/fpa2bv_model_converter.h b/src/tactic/fpa/fpa2bv_model_converter.h index 465aaa1e4..989caaa58 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.h +++ b/src/tactic/fpa/fpa2bv_model_converter.h @@ -26,7 +26,7 @@ Notes: class fpa2bv_model_converter : public model_converter { ast_manager & m; bv2fpa_converter * m_bv2fp; - + public: fpa2bv_model_converter(ast_manager & m, fpa2bv_converter & conv): m(m), @@ -53,10 +53,10 @@ public: virtual model_converter * translate(ast_translation & translator); protected: - fpa2bv_model_converter(ast_manager & m) : + fpa2bv_model_converter(ast_manager & m) : m(m), m_bv2fp(0) {} - + void convert(model_core * mc, model * float_mdl); }; From ff42c44f37dae408ab9e73df650a9935ab156975 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 15 Sep 2017 11:48:25 +0100 Subject: [PATCH 286/488] Debug traces --- src/ast/fpa/bv2fpa_converter.cpp | 19 ------------------- src/tactic/fpa/fpa2bv_model_converter.cpp | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index 2aa4dc31a..ae9f321d1 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -558,22 +558,3 @@ bv2fpa_converter * bv2fpa_converter::translate(ast_translation & translator) { return res; } -void bv2fpa_converter::convert(model_core * mc, model_core * float_mdl) { - TRACE("bv2fpa", tout << "BV Model: " << std::endl; - for (unsigned i = 0; i < mc->get_num_constants(); i++) - tout << mc->get_constant(i)->get_name() << " --> " << - mk_ismt2_pp(mc->get_const_interp(mc->get_constant(i)), m) << std::endl; - for (unsigned i = 0; i < mc->get_num_functions(); i++) { - func_decl * f = mc->get_function(i); - tout << f->get_name() << "(...) := " << std::endl; - func_interp * fi = mc->get_func_interp(f); - for (unsigned j = 0; j < fi->num_entries(); j++) { - func_entry const * fe = fi->get_entry(j); - for (unsigned k = 0; k < f->get_arity(); k++) - tout << mk_ismt2_pp(fe->get_arg(k), m) << " "; - tout << "--> " << mk_ismt2_pp(fe->get_result(), m) << std::endl; - } - tout << "else " << mk_ismt2_pp(fi->get_else(), m) << std::endl; - }); - -} diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index e82c06386..5e952eb6e 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -33,6 +33,23 @@ model_converter * fpa2bv_model_converter::translate(ast_translation & translator } void fpa2bv_model_converter::convert(model_core * mc, model * float_mdl) { + TRACE("fpa2bv_mc", tout << "BV Model: " << std::endl; + for (unsigned i = 0; i < mc->get_num_constants(); i++) + tout << mc->get_constant(i)->get_name() << " --> " << + mk_ismt2_pp(mc->get_const_interp(mc->get_constant(i)), m) << std::endl; + for (unsigned i = 0; i < mc->get_num_functions(); i++) { + func_decl * f = mc->get_function(i); + tout << f->get_name() << "(...) := " << std::endl; + func_interp * fi = mc->get_func_interp(f); + for (unsigned j = 0; j < fi->num_entries(); j++) { + func_entry const * fe = fi->get_entry(j); + for (unsigned k = 0; k < f->get_arity(); k++) + tout << mk_ismt2_pp(fe->get_arg(k), m) << " "; + tout << "--> " << mk_ismt2_pp(fe->get_result(), m) << std::endl; + } + tout << "else " << mk_ismt2_pp(fi->get_else(), m) << std::endl; + }); + obj_hashtable seen; m_bv2fp->convert_consts(mc, float_mdl, seen); m_bv2fp->convert_rm_consts(mc, float_mdl, seen); From 15ccb34a8136e05f73b05ea7718b5219ef60dcf9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 15 Sep 2017 11:48:42 +0100 Subject: [PATCH 287/488] Removed unused function --- src/ast/fpa/bv2fpa_converter.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ast/fpa/bv2fpa_converter.h b/src/ast/fpa/bv2fpa_converter.h index 943f544ca..caf36c1fc 100644 --- a/src/ast/fpa/bv2fpa_converter.h +++ b/src/ast/fpa/bv2fpa_converter.h @@ -50,7 +50,6 @@ public: expr_ref convert_bv2rm(expr * eval_v); expr_ref convert_bv2rm(model_core * mc, app * val); - void convert(model_core * mc, model_core * float_mdl); void convert_consts(model_core * mc, model_core * target_model, obj_hashtable & seen); void convert_rm_consts(model_core * mc, model_core * target_model, obj_hashtable & seen); void convert_min_max_specials(model_core * mc, model_core * target_model, obj_hashtable & seen); From 4267f304a4dfa1e06aac0232ce5fe09a043e34ae Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 15 Sep 2017 12:43:16 +0100 Subject: [PATCH 288/488] Fix for model completion (via cmd_context) --- src/cmd_context/cmd_context.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index c0e1c9f9c..0a61a5ce6 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1665,6 +1665,16 @@ void cmd_context::complete_model() { } } + for (unsigned i = 0; i < md->get_num_functions(); i++) { + func_decl * f = md->get_function(i); + func_interp * fi = md->get_func_interp(f); + IF_VERBOSE(12, verbose_stream() << "(model.completion " << f->get_name() << ")\n"; ); + if (fi->is_partial()) { + sort * range = f->get_range(); + fi->set_else(m().get_some_value(range)); + } + } + for (auto kd : m_func_decls) { symbol const & k = kd.m_key; func_decls & v = kd.m_value; @@ -1948,13 +1958,13 @@ void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) { TRACE("new_dt_eh", tout << "new datatype: "; m_owner.pm().display(tout, dt); tout << "\n";); for (func_decl * c : *m_dt_util.get_datatype_constructors(dt)) { TRACE("new_dt_eh", tout << "new constructor: " << c->get_name() << "\n";); - m_owner.insert(c); + m_owner.insert(c); func_decl * r = m_dt_util.get_constructor_recognizer(c); m_owner.insert(r); TRACE("new_dt_eh", tout << "new recognizer: " << r->get_name() << "\n";); for (func_decl * a : *m_dt_util.get_constructor_accessors(c)) { TRACE("new_dt_eh", tout << "new accessor: " << a->get_name() << "\n";); - m_owner.insert(a); + m_owner.insert(a); } } if (m_owner.m_scopes.size() > 0) { From 05447d612a35af824212c696c3f899a11113093f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 15 Sep 2017 19:56:15 +0100 Subject: [PATCH 289/488] Bugfixes for fp.to_* operators --- src/ast/fpa/bv2fpa_converter.cpp | 19 ++++++++++++++++--- src/ast/fpa/fpa2bv_converter.cpp | 20 ++++++++++---------- src/ast/rewriter/fpa_rewriter.cpp | 4 +--- src/util/mpf.cpp | 8 ++++++++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index ae9f321d1..30d41bc53 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -285,7 +285,21 @@ func_interp * bv2fpa_converter::convert_func_interp(model_core * mc, func_decl * bv_fres = bv_fe->get_result(); ft_fres = rebuild_floats(mc, rng, to_app(bv_fres)); m_th_rw(ft_fres); - result->insert_new_entry(new_args.c_ptr(), ft_fres); + TRACE("bv2fpa", + for (unsigned i = 0; i < new_args.size(); i++) + tout << mk_ismt2_pp(bv_args[i], m) << " == " << + mk_ismt2_pp(new_args[i], m) << std::endl; + tout << mk_ismt2_pp(bv_fres, m) << " == " << mk_ismt2_pp(ft_fres, m) << std::endl;); + func_entry * fe = result->get_entry(new_args.c_ptr()); + if (fe == 0) + result->insert_new_entry(new_args.c_ptr(), ft_fres); + else { + // The BV model may have multiple equivalent entries using different + // representations of NaN. We can only keep one and we check that + // the results for all those entries are the same. + if (ft_fres != fe->get_result()) + throw default_exception("BUG: UF function entries disagree with each other"); + } } app_ref bv_els(m); @@ -462,6 +476,7 @@ void bv2fpa_converter::convert_uf2bvuf(model_core * mc, model_core * target_mode args.push_back(m.mk_var(i, f->get_domain()[i])); fmv->set_else(m.mk_app(it->m_key, n, args.c_ptr())); #else + fmv->set_else(0); #endif target_model->register_decl(f, fmv); @@ -476,7 +491,6 @@ void bv2fpa_converter::convert_uf2bvuf(model_core * mc, model_core * target_mode } void bv2fpa_converter::display(std::ostream & out) { - out << "(fpa2bv-model-converter"; for (obj_map::iterator it = m_const2bv.begin(); it != m_const2bv.end(); it++) { @@ -510,7 +524,6 @@ void bv2fpa_converter::display(std::ostream & out) { out << mk_ismt2_pp(it->m_value.first, m, indent) << "; " << mk_ismt2_pp(it->m_value.second, m, indent) << ")"; } - out << ")"; } bv2fpa_converter * bv2fpa_converter::translate(ast_translation & translator) { diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index f0707a273..5314bed07 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3312,11 +3312,11 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args expr_ref big_sig_shifted(m), int_part(m), last(m), round(m), stickies(m), sticky(m); big_sig_shifted = m.mk_ite(is_neg_shift, m_bv_util.mk_bv_lshr(big_sig, shift), m_bv_util.mk_bv_shl(big_sig, shift)); - int_part = m_bv_util.mk_extract(big_sig_sz-1, big_sig_sz-bv_sz-3, big_sig_shifted); + int_part = m_bv_util.mk_extract(big_sig_sz-1, big_sig_sz-(bv_sz+3), big_sig_shifted); SASSERT(m_bv_util.get_bv_size(int_part) == bv_sz+3); - last = m_bv_util.mk_extract(big_sig_sz-bv_sz-4, big_sig_sz-bv_sz-4, big_sig_shifted); - round = m_bv_util.mk_extract(big_sig_sz-bv_sz-5, big_sig_sz-bv_sz-5, big_sig_shifted); - stickies = m_bv_util.mk_extract(big_sig_sz-bv_sz-6, 0, big_sig_shifted); + last = m_bv_util.mk_extract(big_sig_sz-(bv_sz+3), big_sig_sz-(bv_sz+3), big_sig_shifted); + round = m_bv_util.mk_extract(big_sig_sz-(bv_sz+4), big_sig_sz-(bv_sz+4), big_sig_shifted); + stickies = m_bv_util.mk_extract(big_sig_sz-(bv_sz+5), 0, big_sig_shifted); sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, stickies); dbg_decouple("fpa2bv_to_bv_big_sig_shifted", big_sig_shifted); dbg_decouple("fpa2bv_to_bv_int_part", int_part); @@ -3335,25 +3335,25 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args dbg_decouple("fpa2bv_to_bv_inc", inc); dbg_decouple("fpa2bv_to_bv_pre_rounded", pre_rounded); - expr_ref out_of_range(m); + expr_ref in_range(m); if (!is_signed) { expr_ref ul(m); - ul = m_bv_util.mk_zero_extend(3, m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz-1))); - out_of_range = m_bv_util.mk_ule(ul, pre_rounded); + ul = m_bv_util.mk_zero_extend(3, m_bv_util.mk_numeral(-1, bv_sz)); + in_range = m_bv_util.mk_ule(pre_rounded, ul); } else { expr_ref ll(m), ul(m); ll = m_bv_util.mk_sign_extend(3, m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz-1))); ul = m_bv_util.mk_zero_extend(4, m_bv_util.mk_numeral(-1, bv_sz-1)); - out_of_range = m.mk_not(m.mk_and(m_bv_util.mk_sle(ll, pre_rounded), m_bv_util.mk_sle(pre_rounded, ul))); + in_range = m.mk_and(m_bv_util.mk_sle(ll, pre_rounded), m_bv_util.mk_sle(pre_rounded, ul)); } - dbg_decouple("fpa2bv_to_bv_out_of_range", out_of_range); + dbg_decouple("fpa2bv_to_bv_in_range", in_range); expr_ref rounded(m); rounded = m_bv_util.mk_extract(bv_sz-1, 0, pre_rounded); dbg_decouple("fpa2bv_to_bv_rounded", rounded); - result = m.mk_ite(out_of_range, unspec_v, rounded); + result = m.mk_ite(m.mk_not(in_range), unspec_v, rounded); result = m.mk_ite(c2, v2, result); result = m.mk_ite(c1, v1, result); diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 6c7190ebc..3e30faa6d 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -854,13 +854,11 @@ br_status fpa_rewriter::mk_to_real(expr * arg, expr_ref & result) { scoped_mpf v(m_fm); if (m_util.is_numeral(arg, v)) { - if (!m_fm.is_nan(v) && !m_fm.is_inf(v)) { + if (m_fm.is_nan(v) || m_fm.is_inf(v)) { if (m_hi_fp_unspecified) { result = m_util.arith_util().mk_numeral(rational(0), false); return BR_DONE; } - else - return BR_FAILED; } else { scoped_mpq r(m_fm.mpq_manager()); diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 7287b69cf..5e7233110 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -1217,12 +1217,18 @@ void mpf_manager::to_sbv_mpq(mpf_rounding_mode rm, const mpf & x, scoped_mpq & o default: UNREACHABLE(); } if (inc) m_mpz_manager.inc(z); + TRACE("mpf_dbg_sbv", + tout << "SBV: (" << to_string(x) << ") == " << m_mpq_manager.to_string(z) << std::endl; + tout << "sign=" << t.sign() << " last=" << last << " round=" << round << + " sticky=" << sticky << " inc=" << inc << std::endl; ); } else m_mpz_manager.mul2k(z, (unsigned) e); m_mpq_manager.set(o, z); if (x.sign) m_mpq_manager.neg(o); + + TRACE("mpf_dbg", tout << "SBV = " << m_mpq_manager.to_string(o) << std::endl;); } void mpf_manager::to_ieee_bv_mpz(const mpf & x, scoped_mpz & o) { @@ -1248,6 +1254,8 @@ void mpf_manager::to_ieee_bv_mpz(const mpf & x, scoped_mpz & o) { m_mpz_manager.mul2k(o, sbits - 1); m_mpz_manager.add(o, sig(x), o); } + + TRACE("mpf_dbg", tout << "IEEE_BV = " << m_mpz_manager.to_string(o) << std::endl;); } void mpf_manager::renormalize(unsigned ebits, unsigned sbits, mpf_exp_t & exp, mpz & sig) { From 65697eb277c457a67ea8832027acc6715d751e7a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 15 Sep 2017 21:13:47 +0100 Subject: [PATCH 290/488] Portability fixes --- src/ast/fpa/fpa2bv_converter.cpp | 12 ++++---- src/ast/fpa_decl_plugin.h | 4 +-- src/ast/rewriter/fpa_rewriter.cpp | 48 +++++++++++++++---------------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 5314bed07..cd3b0ccca 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2582,7 +2582,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); - if (m_bv_util.is_numeral(bv_rm) && m_util.arith_util().is_numeral(x)) { + if (m_bv_util.is_numeral(bv_rm) && m_util.au().is_numeral(x)) { rational tmp_rat; unsigned sz; m_bv_util.is_numeral(to_expr(bv_rm), tmp_rat, sz); SASSERT(tmp_rat.is_int32()); @@ -2600,7 +2600,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * rational q; bool is_int; - m_util.arith_util().is_numeral(x, q, is_int); + m_util.au().is_numeral(x, q, is_int); if (q.is_zero()) return mk_pzero(f, result); @@ -2617,12 +2617,12 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * result = m_util.mk_fp(sgn, exp, sig); } } - else if (m_util.arith_util().is_numeral(x)) { + else if (m_util.au().is_numeral(x)) { rational q; bool is_int; - m_util.arith_util().is_numeral(x, q, is_int); + m_util.au().is_numeral(x, q, is_int); - if (m_util.arith_util().is_zero(x)) + if (m_util.au().is_zero(x)) mk_pzero(f, result); else { expr_ref rm_nta(m), rm_nte(m), rm_tp(m), rm_tn(m), rm_tz(m); @@ -3317,7 +3317,7 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args last = m_bv_util.mk_extract(big_sig_sz-(bv_sz+3), big_sig_sz-(bv_sz+3), big_sig_shifted); round = m_bv_util.mk_extract(big_sig_sz-(bv_sz+4), big_sig_sz-(bv_sz+4), big_sig_shifted); stickies = m_bv_util.mk_extract(big_sig_sz-(bv_sz+5), 0, big_sig_shifted); - sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, stickies); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, stickies.get()); dbg_decouple("fpa2bv_to_bv_big_sig_shifted", big_sig_shifted); dbg_decouple("fpa2bv_to_bv_int_part", int_part); dbg_decouple("fpa2bv_to_bv_last", last); diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index b4730cc75..f59c8f92f 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -221,8 +221,8 @@ public: mpf_manager & fm() const { return m_plugin->fm(); } family_id get_fid() const { return m_fid; } family_id get_family_id() const { return m_fid; } - arith_util & arith_util() { return m_a_util; } - bv_util & bv_util() { return m_bv_util; } + arith_util & au() { return m_a_util; } + bv_util & bu() { return m_bv_util; } fpa_decl_plugin & plugin() { return *m_plugin; } sort * mk_float_sort(unsigned ebits, unsigned sbits); diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 3e30faa6d..09307cbf2 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -121,7 +121,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const unsigned sbits = f->get_parameter(1).get_int(); if (num_args == 1) { - if (m_util.bv_util().is_numeral(args[0], r1, bvs1)) { + if (m_util.bu().is_numeral(args[0], r1, bvs1)) { // BV -> float SASSERT(bvs1 == sbits + ebits); unsynch_mpz_manager & mpzm = m_fm.mpz_manager(); @@ -162,7 +162,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const if (!m_util.is_rm_numeral(args[0], rmv)) return BR_FAILED; - if (m_util.arith_util().is_numeral(args[1], r1)) { + if (m_util.au().is_numeral(args[1], r1)) { // rm + real -> float TRACE("fp_rewriter", tout << "r: " << r1 << std::endl;); scoped_mpf v(m_fm); @@ -180,10 +180,10 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const // TRACE("fp_rewriter", tout << "result: " << result << std::endl; ); return BR_DONE; } - else if (m_util.bv_util().is_numeral(args[1], r1, bvs1)) { + else if (m_util.bu().is_numeral(args[1], r1, bvs1)) { // rm + signed bv -> float TRACE("fp_rewriter", tout << "r1: " << r1 << std::endl;); - r1 = m_util.bv_util().norm(r1, bvs1, true); + r1 = m_util.bu().norm(r1, bvs1, true); TRACE("fp_rewriter", tout << "r1 norm: " << r1 << std::endl;); m_fm.set(v, ebits, sbits, rmv, r1.to_mpq()); result = m_util.mk_value(v); @@ -192,12 +192,12 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const } else if (num_args == 3) { if (m_util.is_rm_numeral(args[0], rmv) && - m_util.arith_util().is_real(args[1]) && - m_util.arith_util().is_int(args[2])) { + m_util.au().is_real(args[1]) && + m_util.au().is_int(args[2])) { // rm + real + int -> float if (!m_util.is_rm_numeral(args[0], rmv) || - !m_util.arith_util().is_numeral(args[1], r1) || - !m_util.arith_util().is_numeral(args[2], r2)) + !m_util.au().is_numeral(args[1], r1) || + !m_util.au().is_numeral(args[2], r2)) return BR_FAILED; TRACE("fp_rewriter", tout << "r1: " << r1 << ", r2: " << r2 << "\n";); @@ -206,12 +206,12 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const return BR_DONE; } else if (m_util.is_rm_numeral(args[0], rmv) && - m_util.arith_util().is_int(args[1]) && - m_util.arith_util().is_real(args[2])) { + m_util.au().is_int(args[1]) && + m_util.au().is_real(args[2])) { // rm + int + real -> float if (!m_util.is_rm_numeral(args[0], rmv) || - !m_util.arith_util().is_numeral(args[1], r1) || - !m_util.arith_util().is_numeral(args[2], r2)) + !m_util.au().is_numeral(args[1], r1) || + !m_util.au().is_numeral(args[2], r2)) return BR_FAILED; TRACE("fp_rewriter", tout << "r1: " << r1 << ", r2: " << r2 << "\n";); @@ -219,9 +219,9 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const result = m_util.mk_value(v); return BR_DONE; } - else if (m_util.bv_util().is_numeral(args[0], r1, bvs1) && - m_util.bv_util().is_numeral(args[1], r2, bvs2) && - m_util.bv_util().is_numeral(args[2], r3, bvs3)) { + else if (m_util.bu().is_numeral(args[0], r1, bvs1) && + m_util.bu().is_numeral(args[1], r2, bvs2) && + m_util.bu().is_numeral(args[2], r3, bvs3)) { // 3 BV -> float SASSERT(m_fm.mpz_manager().is_one(r2.to_mpq().denominator())); SASSERT(m_fm.mpz_manager().is_one(r3.to_mpq().denominator())); @@ -251,7 +251,7 @@ br_status fpa_rewriter::mk_to_fp_unsigned(func_decl * f, expr * arg1, expr * arg unsigned bvs; if (m_util.is_rm_numeral(arg1, rmv) && - m_util.bv_util().is_numeral(arg2, r, bvs)) { + m_util.bu().is_numeral(arg2, r, bvs)) { scoped_mpf v(m_fm); m_fm.set(v, ebits, sbits, rmv, r.to_mpq()); result = m_util.mk_value(v); @@ -722,7 +722,7 @@ br_status fpa_rewriter::mk_bv2rm(expr * arg, expr_ref & result) { rational bv_val; unsigned sz = 0; - if (m_util.bv_util().is_numeral(arg, bv_val, sz)) { + if (m_util.bu().is_numeral(arg, bv_val, sz)) { SASSERT(bv_val.is_uint64()); switch (bv_val.get_uint64()) { case BV_RM_TIES_TO_AWAY: result = m_util.mk_round_nearest_ties_to_away(); break; @@ -744,9 +744,9 @@ br_status fpa_rewriter::mk_fp(expr * sgn, expr * exp, expr * sig, expr_ref & res rational rsgn, rexp, rsig; unsigned bvsz_sgn, bvsz_exp, bvsz_sig; - if (m_util.bv_util().is_numeral(sgn, rsgn, bvsz_sgn) && - m_util.bv_util().is_numeral(sig, rsig, bvsz_sig) && - m_util.bv_util().is_numeral(exp, rexp, bvsz_exp)) { + if (m_util.bu().is_numeral(sgn, rsgn, bvsz_sgn) && + m_util.bu().is_numeral(sig, rsig, bvsz_sig) && + m_util.bu().is_numeral(exp, rexp, bvsz_exp)) { SASSERT(mpzm.is_one(rexp.to_mpq().denominator())); SASSERT(mpzm.is_one(rsig.to_mpq().denominator())); scoped_mpf v(m_fm); @@ -804,8 +804,8 @@ br_status fpa_rewriter::mk_to_bv(func_decl * f, expr * arg1, expr * arg2, bool i br_status fpa_rewriter::mk_to_bv_unspecified(func_decl * f, expr_ref & result) { if (m_hi_fp_unspecified) { - unsigned bv_sz = m_util.bv_util().get_bv_size(f->get_range()); - result = m_util.bv_util().mk_numeral(0, bv_sz); + unsigned bv_sz = m_util.bu().get_bv_size(f->get_range()); + result = m_util.bu().mk_numeral(0, bv_sz); return BR_DONE; } else @@ -856,14 +856,14 @@ br_status fpa_rewriter::mk_to_real(expr * arg, expr_ref & result) { if (m_util.is_numeral(arg, v)) { if (m_fm.is_nan(v) || m_fm.is_inf(v)) { if (m_hi_fp_unspecified) { - result = m_util.arith_util().mk_numeral(rational(0), false); + result = m_util.au().mk_numeral(rational(0), false); return BR_DONE; } } else { scoped_mpq r(m_fm.mpq_manager()); m_fm.to_rational(v, r); - result = m_util.arith_util().mk_numeral(r.get(), false); + result = m_util.au().mk_numeral(r.get(), false); return BR_DONE; } } From 8ff1e070bef2b69e8f8be9db7b8f2eb16d2efafa Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 17 Sep 2017 01:39:39 +0200 Subject: [PATCH 291/488] add QF_DT Signed-off-by: Nikolaj Bjorner --- src/ast/normal_forms/pull_quant.cpp | 2 +- src/cmd_context/check_logic.cpp | 9 ++++++++- src/smt/smt_setup.cpp | 8 ++++++++ src/smt/smt_setup.h | 1 + src/solver/smt_logics.cpp | 4 ++-- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/ast/normal_forms/pull_quant.cpp b/src/ast/normal_forms/pull_quant.cpp index 56bada7c1..239fd9008 100644 --- a/src/ast/normal_forms/pull_quant.cpp +++ b/src/ast/normal_forms/pull_quant.cpp @@ -244,7 +244,7 @@ struct pull_quant::imp { quantifier * q1 = m_manager.update_quantifier(to_quantifier(n), new_expr); proof * p1 = 0; if (n != q1) { - proof * p0 = m_manager.mk_pull_quant(to_quantifier(n)->get_expr(), to_quantifier(new_expr)); + proof * p0 = m_manager.mk_pull_quant(n, to_quantifier(new_expr)); p1 = m_manager.mk_quant_intro(to_quantifier(n), q1, p0); } proof * p2 = q1 == r ? 0 : m_manager.mk_pull_quant(q1, to_quantifier(r)); diff --git a/src/cmd_context/check_logic.cpp b/src/cmd_context/check_logic.cpp index 1aace7716..dd08ac9db 100644 --- a/src/cmd_context/check_logic.cpp +++ b/src/cmd_context/check_logic.cpp @@ -37,6 +37,7 @@ struct check_logic::imp { datatype_util m_dt_util; pb_util m_pb_util; bool m_uf; // true if the logic supports uninterpreted functions + bool m_dt; // true if the lgoic supports dattypes bool m_arrays; // true if the logic supports arbitrary arrays bool m_bv_arrays; // true if the logic supports only bv arrays bool m_reals; // true if the logic supports reals @@ -53,6 +54,7 @@ struct check_logic::imp { void reset() { m_uf = false; + m_dt = false; m_arrays = false; m_bv_arrays = false; m_reals = false; @@ -105,6 +107,10 @@ struct check_logic::imp { m_uf = true; m_bvs = true; } + else if (logic == "QF_DT") { + m_uf = true; + m_dt = true; + } else if (logic == "QF_AUFLIA") { m_uf = true; m_arrays = true; @@ -187,6 +193,7 @@ struct check_logic::imp { m_bvs = true; m_uf = true; m_ints = true; + m_dt = true; m_nonlinear = true; // non-linear 0-1 variables may get eliminated } else { @@ -443,7 +450,7 @@ struct check_logic::imp { else if (fid == m_seq_util.get_family_id()) { // nothing to check } - else if (fid == m_dt_util.get_family_id() && m_logic == "QF_FD") { + else if (fid == m_dt_util.get_family_id() && m_dt) { // nothing to check } else if (fid == m_pb_util.get_family_id() && m_logic == "QF_FD") { diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 50b49f3b8..56b5d541a 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -125,6 +125,8 @@ namespace smt { setup_QF_FPBV(); else if (m_logic == "QF_S") setup_QF_S(); + else if (m_logic == "QF_DT") + setup_QF_DT(); else setup_unknown(); } @@ -190,6 +192,8 @@ namespace smt { setup_AUFLIRA(); else if (m_logic == "UFNIA") setup_UFNIA(); + else if (m_logic == "QF_DT") + setup_QF_DT(); else if (m_logic == "LRA") setup_LRA(); else @@ -210,6 +214,10 @@ namespace smt { m_params.m_random_initial_activity = IA_RANDOM; } + void setup::setup_QF_DT() { + setup_QF_UF(); + } + void setup::setup_QF_BVRE() { setup_QF_BV(); setup_QF_LIA(); diff --git a/src/smt/smt_setup.h b/src/smt/smt_setup.h index a3bb29195..924c2caec 100644 --- a/src/smt/smt_setup.h +++ b/src/smt/smt_setup.h @@ -54,6 +54,7 @@ namespace smt { // setup_(static_features & st) can only be used if the logical context will perform a single // check. // + void setup_QF_DT(); void setup_QF_UF(); void setup_QF_UF(static_features const & st); void setup_QF_RDL(); diff --git a/src/solver/smt_logics.cpp b/src/solver/smt_logics.cpp index 75cd0f2bb..874f1cfcc 100644 --- a/src/solver/smt_logics.cpp +++ b/src/solver/smt_logics.cpp @@ -141,7 +141,7 @@ bool smt_logics::logic_has_fpa(symbol const & s) { } bool smt_logics::logic_has_uf(symbol const & s) { - return s == "QF_UF" || s == "UF"; + return s == "QF_UF" || s == "UF" || s == "QF_DT"; } bool smt_logics::logic_has_horn(symbol const& s) { @@ -153,5 +153,5 @@ bool smt_logics::logic_has_pb(symbol const& s) { } bool smt_logics::logic_has_datatype(symbol const& s) { - return s == "QF_FD" || s == "ALL"; + return s == "QF_FD" || s == "ALL" || s == "QF_DT"; } From 8871cb120a6bb74f40c3b1911d614cddf7e6e0ce Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 12:57:29 +0100 Subject: [PATCH 292/488] Fixed bug in fp.to_{s,u}bv --- src/ast/fpa/fpa2bv_converter.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index cd3b0ccca..cae357a32 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3240,10 +3240,7 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args // NaN, Inf, or negative (except -0) -> unspecified expr_ref c1(m), v1(m), unspec_v(m); - if (!is_signed) - c1 = m.mk_or(x_is_nan, x_is_inf, m.mk_and(x_is_neg, m.mk_not(x_is_nzero))); - else - c1 = m.mk_or(x_is_nan, x_is_inf); + c1 = m.mk_or(x_is_nan, x_is_inf); mk_to_bv_unspecified(f, num, args, unspec_v); v1 = unspec_v; dbg_decouple("fpa2bv_to_bv_c1", c1); @@ -3335,18 +3332,18 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args dbg_decouple("fpa2bv_to_bv_inc", inc); dbg_decouple("fpa2bv_to_bv_pre_rounded", pre_rounded); - expr_ref in_range(m); + pre_rounded = m.mk_ite(x_is_neg, m_bv_util.mk_bv_neg(pre_rounded), pre_rounded); + + expr_ref ll(m), ul(m), in_range(m); if (!is_signed) { - expr_ref ul(m); + ll = m_bv_util.mk_numeral(0, bv_sz+3); ul = m_bv_util.mk_zero_extend(3, m_bv_util.mk_numeral(-1, bv_sz)); - in_range = m_bv_util.mk_ule(pre_rounded, ul); } else { - expr_ref ll(m), ul(m); ll = m_bv_util.mk_sign_extend(3, m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz-1))); ul = m_bv_util.mk_zero_extend(4, m_bv_util.mk_numeral(-1, bv_sz-1)); - in_range = m.mk_and(m_bv_util.mk_sle(ll, pre_rounded), m_bv_util.mk_sle(pre_rounded, ul)); } + in_range = m.mk_and(m_bv_util.mk_sle(ll, pre_rounded), m_bv_util.mk_sle(pre_rounded, ul)); dbg_decouple("fpa2bv_to_bv_in_range", in_range); expr_ref rounded(m); From 00651f8f211dd9b71b2e5b0b828df9a3815e26ed Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 14:29:32 +0100 Subject: [PATCH 293/488] Tabs, formatting. --- src/api/dll/dll.cpp | 18 +- src/api/ml/z3native_stubs.h | 2 +- src/ast/fpa/fpa2bv_converter.cpp | 8 +- src/ast/rewriter/bit2int.h | 2 +- src/ast/rewriter/bv_bounds.h | 6 +- src/duality/duality.h | 263 ++++++------ src/duality/duality_wrapper.h | 401 +++++++++--------- src/interp/iz3base.h | 34 +- src/interp/iz3checker.h | 34 +- src/interp/iz3hash.h | 8 +- src/interp/iz3interp.h | 46 +- src/interp/iz3pp.h | 6 +- src/interp/iz3scopes.h | 4 +- src/interp/iz3translate.h | 6 +- src/math/automata/automaton.h | 2 +- src/math/automata/boolean_algebra.h | 4 +- src/math/polynomial/polynomial.h | 4 +- src/math/polynomial/upolynomial.h | 8 +- src/model/model_core.cpp | 6 +- src/muz/base/dl_context.h | 6 +- src/muz/base/dl_engine_base.h | 2 +- src/muz/duality/duality_dl_interface.h | 4 +- src/muz/pdr/pdr_generalizers.h | 2 +- src/muz/rel/dl_mk_similarity_compressor.h | 2 +- src/muz/rel/dl_mk_simple_joins.h | 2 +- src/muz/spacer/spacer_qe_project.cpp | 2 +- src/muz/transforms/dl_mk_magic_sets.h | 2 +- src/muz/transforms/dl_mk_unbound_compressor.h | 2 +- src/smt/diff_logic.h | 62 +-- src/smt/smt_enode.h | 8 +- src/smt/smt_quantifier.h | 2 +- src/smt/smt_theory.h | 2 +- src/smt/theory_seq.h | 8 +- src/smt/theory_str.cpp | 10 +- src/smt/watch_list.cpp | 8 +- src/tactic/sls/sls_tracker.h | 16 +- src/test/bit_vector.cpp | 62 +-- src/test/diff_logic.cpp | 2 +- src/test/expr_rand.cpp | 4 +- src/test/main.cpp | 98 ++--- src/test/model_based_opt.cpp | 2 +- src/test/optional.cpp | 4 +- src/util/dependency.h | 2 +- src/util/hash.h | 2 +- src/util/inf_eps_rational.h | 20 +- src/util/inf_int_rational.h | 16 +- src/util/inf_rational.h | 14 +- src/util/inf_s_integer.h | 10 +- src/util/lp/bound_analyzer_on_row.h | 38 +- src/util/lp/init_lar_solver.h | 22 +- src/util/lp/lar_core_solver.h | 2 +- src/util/lp/lar_solver.h | 30 +- src/util/lp/lp_bound_propagator.cpp | 10 +- src/util/lp/lp_settings.h | 10 +- src/util/lp/lp_utils.h | 2 +- src/util/lp/stacked_vector.h | 26 +- src/util/lp/static_matrix.h | 2 +- src/util/lp/ul_pair.h | 4 +- src/util/map.h | 2 +- src/util/max_cliques.h | 4 +- src/util/rational.h | 16 +- src/util/stopwatch.h | 6 +- src/util/util.h | 20 +- 63 files changed, 715 insertions(+), 717 deletions(-) diff --git a/src/api/dll/dll.cpp b/src/api/dll/dll.cpp index a0bd25d2e..74dc48153 100644 --- a/src/api/dll/dll.cpp +++ b/src/api/dll/dll.cpp @@ -15,16 +15,16 @@ Copyright (c) 2015 Microsoft Corporation BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved - ) + ) { - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } return TRUE; } diff --git a/src/api/ml/z3native_stubs.h b/src/api/ml/z3native_stubs.h index ef81ac239..ec498dafe 100644 --- a/src/api/ml/z3native_stubs.h +++ b/src/api/ml/z3native_stubs.h @@ -36,5 +36,5 @@ Notes: #define DLL_LOCAL #endif #endif - + #endif diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index cae357a32..bc0364994 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3332,18 +3332,18 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args dbg_decouple("fpa2bv_to_bv_inc", inc); dbg_decouple("fpa2bv_to_bv_pre_rounded", pre_rounded); - pre_rounded = m.mk_ite(x_is_neg, m_bv_util.mk_bv_neg(pre_rounded), pre_rounded); + pre_rounded = m.mk_ite(x_is_neg, m_bv_util.mk_bv_neg(pre_rounded), pre_rounded); - expr_ref ll(m), ul(m), in_range(m); + expr_ref ll(m), ul(m), in_range(m); if (!is_signed) { - ll = m_bv_util.mk_numeral(0, bv_sz+3); + ll = m_bv_util.mk_numeral(0, bv_sz+3); ul = m_bv_util.mk_zero_extend(3, m_bv_util.mk_numeral(-1, bv_sz)); } else { ll = m_bv_util.mk_sign_extend(3, m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz-1))); ul = m_bv_util.mk_zero_extend(4, m_bv_util.mk_numeral(-1, bv_sz-1)); } - in_range = m.mk_and(m_bv_util.mk_sle(ll, pre_rounded), m_bv_util.mk_sle(pre_rounded, ul)); + in_range = m.mk_and(m_bv_util.mk_sle(ll, pre_rounded), m_bv_util.mk_sle(pre_rounded, ul)); dbg_decouple("fpa2bv_to_bv_in_range", in_range); expr_ref rounded(m); diff --git a/src/ast/rewriter/bit2int.h b/src/ast/rewriter/bit2int.h index fe15d1ec5..fbbf2e6d1 100644 --- a/src/ast/rewriter/bit2int.h +++ b/src/ast/rewriter/bit2int.h @@ -75,7 +75,7 @@ protected: bool mk_mul(expr* a, expr* b, expr_ref& result); bool mk_comp(eq_type ty, expr* e1, expr* e2, expr_ref& result); bool mk_add(expr* e1, expr* e2, expr_ref& result); - + expr * get_cached(expr * n) const; bool is_cached(expr * n) const { return get_cached(n) != 0; } void cache_result(expr * n, expr * r); diff --git a/src/ast/rewriter/bv_bounds.h b/src/ast/rewriter/bv_bounds.h index 3d8ec9ebb..4a7226fa7 100644 --- a/src/ast/rewriter/bv_bounds.h +++ b/src/ast/rewriter/bv_bounds.h @@ -38,7 +38,7 @@ public: bv_bounds(ast_manager& m) : m_m(m), m_bv_util(m), m_okay(true) {}; ~bv_bounds(); public: // bounds addition methods - br_status rewrite(unsigned limit, func_decl * f, unsigned num, expr * const * args, expr_ref& result); + br_status rewrite(unsigned limit, func_decl * f, unsigned num, expr * const * args, expr_ref& result); /** \brief Add a constraint to the system. @@ -82,7 +82,7 @@ protected: bv_util m_bv_util; bool m_okay; bool is_sat(app * v); - bool is_sat_core(app * v); +bool is_sat_core(app * v); inline bool in_range(app *v, numeral l); inline bool is_constant_add(unsigned bv_sz, expr * e, app*& v, numeral& val); void record_singleton(app * v, numeral& singleton_value); @@ -94,7 +94,7 @@ protected: inline bool bv_bounds::is_okay() { return m_okay; } inline bool bv_bounds::to_bound(const expr * e) const { - return is_app(e) && m_bv_util.is_bv(e) + return is_app(e) && m_bv_util.is_bv(e) && !m_bv_util.is_bv_add(e) && !m_bv_util.is_numeral(e); } diff --git a/src/duality/duality.h b/src/duality/duality.h index 0ef6be30e..657fa18b4 100644 --- a/src/duality/duality.h +++ b/src/duality/duality.h @@ -21,6 +21,7 @@ #pragma once #include "duality/duality_wrapper.h" +#include #include #include @@ -41,9 +42,9 @@ namespace Duality { typedef expr Term; Z3User(context &_ctx) : ctx(_ctx){} - + const char *string_of_int(int n); - + Term conjoin(const std::vector &args); Term sum(const std::vector &args); @@ -130,58 +131,58 @@ namespace Duality { /** This class represents a relation post-fixed point (RPFP) problem as * a "problem graph". The graph consists of Nodes and hyper-edges. - * + * * A node consists of * - Annotation, a symbolic relation * - Bound, a symbolic relation giving an upper bound on Annotation - * + * * * A hyper-edge consists of: * - Children, a sequence of children Nodes, * - F, a symbolic relational transformer, * - Parent, a single parent Node. - * + * * The graph is "solved" when: * - For every Node n, n.Annotation subseteq n.Bound * - For every hyperedge e, e.F(e.Children.Annotation) subseteq e.Parent.Annotation - * + * * where, if x is a sequence of Nodes, x.Annotation is the sequences * of Annotations of the nodes in the sequence. - * + * * A symbolic Transformer consists of * - RelParams, a sequence of relational symbols * - IndParams, a sequence of individual symbols * - Formula, a formula over RelParams and IndParams - * + * * A Transformer t represents a function that takes sequence R of relations * and yields the relation lambda (t.Indparams). Formula(R/RelParams). - * + * * As a special case, a nullary Transformer (where RelParams is the empty sequence) * represents a fixed relation. - * + * * An RPFP consists of * - Nodes, a set of Nodes * - Edges, a set of hyper-edges * - Context, a prover context that contains formula AST's - * + * * Multiple RPFP's can use the same Context, but you should be careful - * that only one RPFP asserts constraints in the context at any time. - * + * that only one RPFP asserts constraints in the context at any time. + * * */ class RPFP : public Z3User { public: - + class Edge; class Node; bool HornClauses; - + /** Interface class for interpolating solver. */ class LogicSolver { public: - + context *ctx; /** Z3 context for formulas */ solver *slvr; /** Z3 solver */ bool need_goals; /** Can the solver use the goal tree to optimize interpolants? */ @@ -191,7 +192,7 @@ namespace Duality { "assumptions" are currently asserted in the solver. The return value indicates whether the assertions are satisfiable. In the UNSAT case, a tree interpolant is returned in "interpolants". - In the SAT case, a model is returned. + In the SAT case, a model is returned. */ virtual @@ -201,7 +202,7 @@ namespace Duality { TermTree *goals = 0, bool weak = false ) = 0; - + /** Declare a constant in the background theory. */ virtual void declare_constant(const func_decl &f) = 0; @@ -319,7 +320,7 @@ namespace Duality { virtual void declare_constant(const func_decl &f){ bckg.insert(f); } - + /** Is this a background constant? */ virtual bool is_constant(const func_decl &f){ return bckg.find(f) != bckg.end(); @@ -344,9 +345,9 @@ namespace Duality { static iZ3LogicSolver *CreateLogicSolver(config &_config){ return new iZ3LogicSolver(_config); } -#endif +#endif - /** Create a logic solver from a low-level Z3 context. + /** Create a logic solver from a low-level Z3 context. Only use this if you know what you're doing. */ static iZ3LogicSolver *CreateLogicSolver(context c){ return new iZ3LogicSolver(c); @@ -357,7 +358,7 @@ namespace Duality { protected: int nodeCount; int edgeCount; - + class stack_entry { public: @@ -365,8 +366,8 @@ namespace Duality { std::list nodes; std::list > constraints; }; - - + + public: model dualModel; protected: @@ -375,14 +376,14 @@ namespace Duality { std::vector axioms; // only saved here for printing purposes solver &aux_solver; hash_set *proof_core; - + public: /** Construct an RPFP graph with a given interpolating prover context. It is allowed to have multiple RPFP's use the same context, but you should never have teo RPFP's with the same conext asserting nodes or edges at the same time. Note, if you create axioms in one RPFP, them create a second RPFP with the same context, the second will - inherit the axioms. + inherit the axioms. */ RPFP(LogicSolver *_ls) : Z3User(*(_ls->ctx)), dualModel(*(_ls->ctx)), aux_solver(_ls->aux_solver) @@ -396,7 +397,7 @@ namespace Duality { } virtual ~RPFP(); - + /** Symbolic representation of a relational transformer */ class Transformer { @@ -406,12 +407,12 @@ namespace Duality { Term Formula; RPFP *owner; hash_map labels; - + Transformer *Clone() { return new Transformer(*this); } - + void SetEmpty(){ Formula = owner->ctx.bool_val(false); } @@ -451,7 +452,7 @@ namespace Duality { void Complement(){ Formula = !Formula; } - + void Simplify(){ Formula = Formula.simplify(); } @@ -459,7 +460,7 @@ namespace Duality { Transformer(const std::vector &_RelParams, const std::vector &_IndParams, const Term &_Formula, RPFP *_owner) : RelParams(_RelParams), IndParams(_IndParams), Formula(_Formula) {owner = _owner;} }; - + /** Create a symbolic transformer. */ Transformer CreateTransformer(const std::vector &_RelParams, const std::vector &_IndParams, const Term &_Formula) { @@ -469,13 +470,13 @@ namespace Duality { // t.labels = foo.Item2; return Transformer(_RelParams,_IndParams,_Formula,this); } - + /** Create a relation (nullary relational transformer) */ Transformer CreateRelation(const std::vector &_IndParams, const Term &_Formula) { return CreateTransformer(std::vector(), _IndParams, _Formula); } - + /** A node in the RPFP graph */ class Node { @@ -491,17 +492,17 @@ namespace Duality { Term dual; Node *map; unsigned recursion_bound; - + Node(const FuncDecl &_Name, const Transformer &_Annotation, const Transformer &_Bound, const Transformer &_Underapprox, const Term &_dual, RPFP *_owner, int _number) : Name(_Name), Annotation(_Annotation), Bound(_Bound), Underapprox(_Underapprox), dual(_dual) {owner = _owner; number = _number; Outgoing = 0; recursion_bound = UINT_MAX;} }; - + /** Create a node in the graph. The input is a term R(v_1...v_n) * where R is an arbitrary relational symbol and v_1...v_n are * arbitary distinct variables. The names are only of mnemonic value, * however, the number and type of arguments determine the type * of the relation at this node. */ - + Node *CreateNode(const Term &t) { std::vector _IndParams; @@ -517,9 +518,9 @@ namespace Duality { nodes.push_back(n); return n; } - + /** Clone a node (can be from another graph). */ - + Node *CloneNode(Node *old) { Node *n = new Node(old->Name, @@ -534,7 +535,7 @@ namespace Duality { n->map = old; return n; } - + /** Delete a node. You can only do this if not connected to any edges.*/ void DeleteNode(Node *node){ if(node->Outgoing || !node->Incoming.empty()) @@ -549,7 +550,7 @@ namespace Duality { } /** This class represents a hyper-edge in the RPFP graph */ - + class Edge { public: @@ -565,15 +566,15 @@ namespace Duality { Edge *map; Term labeled; std::vector constraints; - + Edge(Node *_Parent, const Transformer &_F, const std::vector &_Children, RPFP *_owner, int _number) : F(_F), Parent(_Parent), Children(_Children), dual(expr(_owner->ctx)) { owner = _owner; number = _number; } }; - - + + /** Create a hyper-edge. */ Edge *CreateEdge(Node *_Parent, const Transformer &_F, const std::vector &_Children) { @@ -584,8 +585,8 @@ namespace Duality { edges.push_back(e); return e; } - - + + /** Delete a hyper-edge and unlink it from any nodes. */ void DeleteEdge(Edge *edge){ if(edge->Parent) @@ -607,19 +608,19 @@ namespace Duality { } delete edge; } - + /** Create an edge that lower-bounds its parent. */ Edge *CreateLowerBoundEdge(Node *_Parent) { return CreateEdge(_Parent, _Parent->Annotation, std::vector()); } - + /** For incremental solving, asserts the constraint associated * with this edge in the SMT context. If this edge is removed, * you must pop the context accordingly. The second argument is * the number of pushes we are inside. */ - + virtual void AssertEdge(Edge *e, int persist = 0, bool with_children = false, bool underapprox = false); /* Constrain an edge by the annotation of one of its children. */ @@ -629,19 +630,19 @@ namespace Duality { /** For incremental solving, asserts the negation of the upper bound associated * with a node. * */ - + void AssertNode(Node *n); - /** Assert a constraint on an edge in the SMT context. + /** Assert a constraint on an edge in the SMT context. */ void ConstrainEdge(Edge *e, const Term &t); - + /** Fix the truth values of atomic propositions in the given edge to their values in the current assignment. */ void FixCurrentState(Edge *root); - + void FixCurrentStateFull(Edge *edge, const expr &extra); - + void FixCurrentStateFull(Edge *edge, const std::vector &assumps, const hash_map &renaming); /** Declare a constant in the background theory. */ @@ -660,78 +661,78 @@ namespace Duality { #if 0 /** Do not call this. */ - + void RemoveAxiom(const Term &t); #endif /** Solve an RPFP graph. This means either strengthen the annotation * so that the bound at the given root node is satisfied, or - * show that this cannot be done by giving a dual solution - * (i.e., a counterexample). - * + * show that this cannot be done by giving a dual solution + * (i.e., a counterexample). + * * In the current implementation, this only works for graphs that * are: * - tree-like - * + * * - closed. - * + * * In a tree-like graph, every nod has out most one incoming and one out-going edge, * and there are no cycles. In a closed graph, every node has exactly one out-going * edge. This means that the leaves of the tree are all hyper-edges with no * children. Such an edge represents a relation (nullary transformer) and thus * a lower bound on its parent. The parameter root must be the root of this tree. - * + * * If Solve returns LBool.False, this indicates success. The annotation of the tree - * has been updated to satisfy the upper bound at the root. - * + * has been updated to satisfy the upper bound at the root. + * * If Solve returns LBool.True, this indicates a counterexample. For each edge, * you can then call Eval to determine the values of symbols in the transformer formula. * You can also call Empty on a node to determine if its value in the counterexample * is the empty relation. - * + * * \param root The root of the tree - * \param persist Number of context pops through which result should persist - * - * + * \param persist Number of context pops through which result should persist + * + * */ lbool Solve(Node *root, int persist); - + /** Same as Solve, but annotates only a single node. */ lbool SolveSingleNode(Node *root, Node *node); /** Get the constraint tree (but don't solve it) */ - + TermTree *GetConstraintTree(Node *root, Node *skip_descendant = 0); - + /** Dispose of the dual model (counterexample) if there is one. */ - + void DisposeDualModel(); /** Check satisfiability of asserted edges and nodes. Same functionality as - * Solve, except no primal solution (interpolant) is generated in the unsat case. */ - - check_result Check(Node *root, std::vector underapproxes = std::vector(), + * Solve, except no primal solution (interpolant) is generated in the unsat case. */ + + check_result Check(Node *root, std::vector underapproxes = std::vector(), std::vector *underapprox_core = 0); /** Update the model, attempting to make the propositional literals in assumps true. If possible, return sat, else return unsat and keep the old model. */ - + check_result CheckUpdateModel(Node *root, std::vector assumps); /** Determines the value in the counterexample of a symbol occuring in the transformer formula of * a given edge. */ - + Term Eval(Edge *e, Term t); - + /** Return the fact derived at node p in a counterexample. */ Term EvalNode(Node *p); - + /** Returns true if the given node is empty in the primal solution. For proecudure summaries, this means that the procedure is not called in the current counter-model. */ - + bool Empty(Node *p); /** Compute an underapproximation of every node in a tree rooted at "root", @@ -747,11 +748,11 @@ namespace Duality { void InterpolateByCases(Node *root, Node *node); /** Push a scope. Assertions made after Push can be undone by Pop. */ - + void Push(); /** Exception thrown when bad clause is encountered */ - + struct bad_clause { std::string msg; int i; @@ -777,7 +778,7 @@ namespace Duality { // thrown on internal error struct Bad { }; - + // thrown on more serious internal error struct ReallyBad { }; @@ -786,56 +787,56 @@ namespace Duality { struct greedy_reduce_failed {}; /** Pop a scope (see Push). Note, you cannot pop axioms. */ - + void Pop(int num_scopes); - + /** Erase the proof by performing a Pop, Push and re-assertion of all the popped constraints */ void PopPush(); /** Return true if the given edge is used in the proof of unsat. Can be called only after Solve or Check returns an unsat result. */ - + bool EdgeUsedInProof(Edge *edge); /** Convert a collection of clauses to Nodes and Edges in the RPFP. - + Predicate unknowns are uninterpreted predicates not occurring in the background theory. - - Clauses are of the form - + + Clauses are of the form + B => P(t_1,...,t_k) - + where P is a predicate unknown and predicate unknowns occur only positivey in H and only under existential quantifiers in prenex form. - + Each predicate unknown maps to a node. Each clause maps to an edge. Let C be a clause B => P(t_1,...,t_k) where the sequence of predicate unknowns occurring in B (in order of occurrence) is P_1..P_n. The clause maps to a transformer T where: - + T.Relparams = P_1..P_n T.Indparams = x_1...x+k T.Formula = B /\ t_1 = x_1 /\ ... /\ t_k = x_k - + Throws exception bad_clause(msg,i) if a clause i is in the wrong form. - + */ - + struct label_struct { symbol name; expr value; bool pos; - label_struct(const symbol &s, const expr &e, bool b) - : name(s), value(e), pos(b) {} + label_struct(const symbol &s, const expr &e, bool b) + : name(s), value(e), pos(b) {} }; - + #ifdef _WINDOWS __declspec(dllexport) #endif @@ -847,7 +848,7 @@ namespace Duality { void WriteCounterexample(std::ostream &s, Node *node); - enum FileFormat {DualityFormat, SMT2Format, HornFormat}; + enum FileFormat {DualityFormat, SMT2Format, HornFormat}; /** Write the RPFP to a file (currently in SMTLIB 1.2 format) */ void WriteProblemToFile(std::string filename, FileFormat format = DualityFormat); @@ -870,9 +871,9 @@ namespace Duality { /** Fuse a vector of transformers. If the total number of inputs of the transformers is N, then the result is an N-ary transfomer whose output is the union of the outputs of the given transformers. The is, suppose we have a vetor of transfoermers - {T_i(r_i1,...,r_iN(i) : i=1..M}. The the result is a transformer - - F(r_11,...,r_iN(1),...,r_M1,...,r_MN(M)) = + {T_i(r_i1,...,r_iN(i) : i=1..M}. The the result is a transformer + + F(r_11,...,r_iN(1),...,r_M1,...,r_MN(M)) = T_1(r_11,...,r_iN(1)) U ... U T_M(r_M1,...,r_MN(M)) */ @@ -921,7 +922,7 @@ namespace Duality { } protected: - + void ClearProofCore(){ if(proof_core) delete proof_core; @@ -929,7 +930,7 @@ namespace Duality { } Term SuffixVariable(const Term &t, int n); - + Term HideVariable(const Term &t, int n); void RedVars(Node *node, Term &b, std::vector &v); @@ -958,16 +959,16 @@ namespace Duality { #if 0 void WriteInterps(System.IO.StreamWriter f, TermTree t); -#endif +#endif void WriteEdgeVars(Edge *e, hash_map &memo, const Term &t, std::ostream &s); void WriteEdgeAssignment(std::ostream &s, Edge *e); - + // Scan the clause body for occurrences of the predicate unknowns - - Term ScanBody(hash_map &memo, + + Term ScanBody(hash_map &memo, const Term &t, hash_map &pmap, std::vector &res, @@ -1035,7 +1036,7 @@ namespace Duality { void ConstrainEdgeLocalized(Edge *e, const Term &t); void GreedyReduce(solver &s, std::vector &conjuncts); - + void NegateLits(std::vector &lits); expr SimplifyOr(std::vector &lits); @@ -1053,7 +1054,7 @@ namespace Duality { void GetGroundLitsUnderQuants(hash_set *memo, const Term &f, std::vector &res, int under); Term StrengthenFormulaByCaseSplitting(const Term &f, std::vector &case_lits); - + expr NegateLit(const expr &f); expr GetEdgeFormula(Edge *e, int persist, bool with_children, bool underapprox); @@ -1065,7 +1066,7 @@ namespace Duality { expr UnhoistPullRec(hash_map & memo, const expr &w, hash_map & init_defs, hash_map & const_params, hash_map &const_params_inv, std::vector &new_params); void AddParamsToTransformer(Transformer &trans, const std::vector ¶ms); - + expr AddParamsToApp(const expr &app, const func_decl &new_decl, const std::vector ¶ms); expr GetRelRec(hash_set &memo, const expr &t, const func_decl &rel); @@ -1081,7 +1082,7 @@ namespace Duality { void UnhoistLoop(Edge *loop_edge, Edge *init_edge); void Unhoist(); - + Term ElimIteRec(hash_map &memo, const Term &t, std::vector &cnsts); Term ElimIte(const Term &t); @@ -1089,11 +1090,11 @@ namespace Duality { void MarkLiveNodes(hash_map > &outgoing, hash_set &live_nodes, Node *node); virtual void slvr_add(const expr &e); - + virtual void slvr_pop(int i); virtual void slvr_push(); - + virtual check_result slvr_check(unsigned n = 0, expr * const assumptions = 0, unsigned *core_size = 0, expr *core = 0); virtual lbool ls_interpolate_tree(TermTree *assumptions, @@ -1105,14 +1106,14 @@ namespace Duality { virtual bool proof_core_contains(const expr &e); }; - + /** RPFP solver base class. */ class Solver { - + public: - + class Counterexample { private: RPFP *tree; @@ -1148,18 +1149,18 @@ namespace Duality { Counterexample &operator=(const Counterexample &); Counterexample(const Counterexample &); }; - + /** Solve the problem. You can optionally give an old counterexample to use as a guide. This is chiefly useful for abstraction refinement metholdologies, and is only used as a heuristic. */ - + virtual bool Solve() = 0; - + virtual Counterexample &GetCounterexample() = 0; - + virtual bool SetOption(const std::string &option, const std::string &value) = 0; - + /** Learn heuristic information from another solver. This is chiefly useful for abstraction refinement, when we want to solve a series of similar problems. */ @@ -1184,7 +1185,7 @@ namespace Duality { /** Object thrown on cancellation */ struct Canceled {}; - + /** Object thrown on incompleteness */ struct Incompleteness {}; }; @@ -1235,16 +1236,16 @@ namespace Duality { public: /** appends assumption literals for edge to lits. if with_children is true, - includes that annotation of the edge's children. - */ + includes that annotation of the edge's children. + */ void AssertEdgeCache(Edge *e, std::vector &lits, bool with_children = false); - + /** appends assumption literals for node to lits */ void AssertNodeCache(Node *, std::vector lits); /** check assumption lits, and return core */ check_result CheckCore(const std::vector &assumps, std::vector &core); - + /** Clone another RPFP into this one, keeping a map */ void Clone(RPFP *other); @@ -1287,7 +1288,7 @@ namespace Duality { uptr slvr; }; hash_map edge_solvers; - + #ifdef LIMIT_STACK_WEIGHT struct weight_counter { int val; @@ -1296,7 +1297,7 @@ namespace Duality { std::swap(val,other.val); } }; - + struct big_stack_entry { weight_counter weight_added; std::vector new_alits; @@ -1319,11 +1320,11 @@ namespace Duality { void ConstrainEdgeLocalizedCache(Edge *e, const Term &tl, std::vector &lits); virtual void slvr_add(const expr &e); - + virtual void slvr_pop(int i); virtual void slvr_push(); - + virtual check_result slvr_check(unsigned n = 0, expr * const assumptions = 0, unsigned *core_size = 0, expr *core = 0); virtual lbool ls_interpolate_tree(TermTree *assumptions, @@ -1348,7 +1349,7 @@ namespace Duality { scoped_solver_for_edge(RPFP_caching *_rpfp, Edge *edge, bool models = false, bool axioms = false){ rpfp = _rpfp; orig_slvr = rpfp->ls->slvr; - es = &(rpfp->SolverForEdge(edge,models,axioms)); + es = &(rpfp->SolverForEdge(edge,models,axioms)); rpfp->ls->slvr = es->slvr.get(); rpfp->AssumptionLits.swap(es->AssumptionLits); } diff --git a/src/duality/duality_wrapper.h b/src/duality/duality_wrapper.h index 8ea8017a2..96c49b36b 100644 --- a/src/duality/duality_wrapper.h +++ b/src/duality/duality_wrapper.h @@ -176,7 +176,7 @@ namespace Duality { m_datalog_fid = m().mk_family_id("datalog_relation"); } ~context() { } - + ast_manager &m() const {return *(ast_manager *)&mgr;} void set(char const * param, char const * value) { m_config.set(param,value); } @@ -186,13 +186,13 @@ namespace Duality { symbol str_symbol(char const * s); symbol int_symbol(int n); - + sort bool_sort(); sort int_sort(); sort real_sort(); sort bv_sort(unsigned sz); sort array_sort(sort d, sort r); - + func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range); func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range); func_decl function(char const * name, sort const & domain, sort const & range); @@ -210,22 +210,22 @@ namespace Duality { expr int_const(char const * name); expr real_const(char const * name); expr bv_const(char const * name, unsigned sz); - + expr bool_val(bool b); - + expr int_val(int n); expr int_val(unsigned n); expr int_val(char const * n); - + expr real_val(int n, int d); expr real_val(int n); expr real_val(unsigned n); expr real_val(char const * n); - + expr bv_val(int n, unsigned sz); expr bv_val(unsigned n, unsigned sz); expr bv_val(char const * n, unsigned sz); - + expr num_val(int n, sort const & s); expr mki(family_id fid, ::decl_kind dk, int n, ::expr **args); @@ -281,17 +281,17 @@ namespace Duality { object(object const & s):m_ctx(s.m_ctx) {} context & ctx() const { return *m_ctx; } friend void check_context(object const & a, object const & b) { assert(a.m_ctx == b.m_ctx); } - ast_manager &m() const {return m_ctx->m();} + ast_manager &m() const {return m_ctx->m();} }; class symbol : public object { ::symbol m_sym; public: - symbol(context & c, ::symbol s):object(c), m_sym(s) {} - symbol(symbol const & s):object(s), m_sym(s.m_sym) {} + symbol(context & c, ::symbol s):object(c), m_sym(s) {} + symbol(symbol const & s):object(s), m_sym(s.m_sym) {} symbol & operator=(symbol const & s) { m_ctx = s.m_ctx; m_sym = s.m_sym; return *this; } - operator ::symbol() const {return m_sym;} - std::string str() const { + operator ::symbol() const {return m_sym;} + std::string str() const { if (m_sym.is_numerical()) { std::ostringstream buffer; buffer << m_sym.get_num(); @@ -300,13 +300,13 @@ namespace Duality { else { return m_sym.bare_str(); } - } - friend std::ostream & operator<<(std::ostream & out, symbol const & s){ + } + friend std::ostream & operator<<(std::ostream & out, symbol const & s) { return out << s.str(); - } - friend bool operator==(const symbol &x, const symbol &y){ + } + friend bool operator==(const symbol &x, const symbol &y) { return x.m_sym == y.m_sym; - } + } }; class params : public config {}; @@ -318,7 +318,7 @@ namespace Duality { public: ::ast * const &raw() const {return _ast;} ast_i(context & c, ::ast *a = 0) : object(c) {_ast = a;} - + ast_i(){_ast = 0;} bool eq(const ast_i &other) const { return _ast == other._ast; @@ -345,19 +345,19 @@ namespace Duality { operator ::ast*() const { return raw(); } friend bool eq(ast const & a, ast const & b) { return a.raw() == b.raw(); } - + ast(context &c, ::ast *a = 0) : ast_i(c,a) { if(_ast) m().inc_ref(a); } - + ast() {} - + ast(const ast &other) : ast_i(other) { if(_ast) m().inc_ref(_ast); } - + ast &operator=(const ast &other) { if(_ast) m().dec_ref(_ast); @@ -367,7 +367,7 @@ namespace Duality { m().inc_ref(_ast); return *this; } - + ~ast(){ if(_ast) m().dec_ref(_ast); @@ -386,15 +386,15 @@ namespace Duality { sort & operator=(sort const & s) { return static_cast(ast::operator=(s)); } bool is_bool() const { return m().is_bool(*this); } - bool is_int() const { return ctx().get_sort_kind(*this) == IntSort; } - bool is_real() const { return ctx().get_sort_kind(*this) == RealSort; } + bool is_int() const { return ctx().get_sort_kind(*this) == IntSort; } + bool is_real() const { return ctx().get_sort_kind(*this) == RealSort; } bool is_arith() const; - bool is_array() const { return ctx().get_sort_kind(*this) == ArraySort; } - bool is_datatype() const; - bool is_relation() const; - bool is_finite_domain() const; + bool is_array() const { return ctx().get_sort_kind(*this) == ArraySort; } + bool is_datatype() const; + bool is_relation() const; + bool is_finite_domain() const; + - sort array_domain() const; sort array_range() const; @@ -404,7 +404,7 @@ namespace Duality { } }; - + class func_decl : public ast { public: func_decl() : ast() {} @@ -413,7 +413,7 @@ namespace Duality { func_decl(func_decl const & s):ast(s) {} operator ::func_decl*() const { return to_func_decl(*this); } func_decl & operator=(func_decl const & s) { return static_cast(ast::operator=(s)); } - + unsigned arity() const; sort domain(unsigned i) const; sort range() const; @@ -434,9 +434,9 @@ namespace Duality { expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const; expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const; - func_decl get_func_decl_parameter(unsigned idx){ + func_decl get_func_decl_parameter(unsigned idx){ return func_decl(ctx(),to_func_decl(to_func_decl(raw())->get_parameters()[idx].get_ast())); - } + } }; @@ -447,8 +447,8 @@ namespace Duality { expr(context & c, ::ast *n):ast(c, n) {} expr(expr const & n):ast(n) {} expr & operator=(expr const & n) { return static_cast(ast::operator=(n)); } - operator ::expr*() const { return to_expr(raw()); } - unsigned get_id() const {return to_expr(raw())->get_id();} + operator ::expr*() const { return to_expr(raw()); } + unsigned get_id() const {return to_expr(raw())->get_id();} sort get_sort() const { return sort(ctx(),m().get_sort(to_expr(raw()))); } @@ -460,27 +460,27 @@ namespace Duality { bool is_datatype() const { return get_sort().is_datatype(); } bool is_relation() const { return get_sort().is_relation(); } bool is_finite_domain() const { return get_sort().is_finite_domain(); } - bool is_true() const {return is_app() && decl().get_decl_kind() == True; } + bool is_true() const {return is_app() && decl().get_decl_kind() == True; } bool is_numeral() const { return is_app() && decl().get_decl_kind() == OtherArith && m().is_unique_value(to_expr(raw())); - } - bool is_app() const {return raw()->get_kind() == AST_APP;} + } + bool is_app() const {return raw()->get_kind() == AST_APP;} bool is_quantifier() const {return raw()->get_kind() == AST_QUANTIFIER;} bool is_var() const {return raw()->get_kind() == AST_VAR;} - bool is_label (bool &pos,std::vector &names) const ; - bool is_ground() const {return to_app(raw())->is_ground();} - bool has_quantifiers() const {return to_app(raw())->has_quantifiers();} - bool has_free(int idx) const { + bool is_label (bool &pos,std::vector &names) const ; + bool is_ground() const {return to_app(raw())->is_ground();} + bool has_quantifiers() const {return to_app(raw())->has_quantifiers();} + bool has_free(int idx) const { used_vars proc; proc.process(to_expr(raw())); return proc.contains(idx); - } - unsigned get_max_var_idx_plus_1() const { + } + unsigned get_max_var_idx_plus_1() const { used_vars proc; proc.process(to_expr(raw())); return proc.get_max_found_var_idx_plus_1(); - } + } // operator Z3_app() const { assert(is_app()); return reinterpret_cast(m_ast); } func_decl decl() const {return func_decl(ctx(),to_app(raw())->get_decl());} @@ -493,11 +493,11 @@ namespace Duality { return 1; case AST_VAR: return 0; - default:; + default:; } SASSERT(0); return 0; - } + } expr arg(unsigned i) const { ast_kind dk = raw()->get_kind(); switch(dk){ @@ -509,25 +509,25 @@ namespace Duality { } assert(0); return expr(); - } + } expr body() const { return ctx().cook(to_quantifier(raw())->get_expr()); - } + } friend expr operator!(expr const & a) { // ::expr *e = a; return expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_NOT,a)); - } + } friend expr operator&&(expr const & a, expr const & b) { return expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_AND,a,b)); - } + } friend expr operator||(expr const & a, expr const & b) { return expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_OR,a,b)); } - + friend expr implies(expr const & a, expr const & b) { return expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_IMPLIES,a,b)); } @@ -546,12 +546,12 @@ namespace Duality { friend expr operator*(expr const & a, expr const & b) { return a.ctx().make(Times,a,b); // expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_MUL,a,b)); - } + } friend expr operator/(expr const & a, expr const & b) { return a.ctx().make(Div,a,b); // expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_DIV,a,b)); } - + friend expr operator-(expr const & a) { return a.ctx().make(Uminus,a); // expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_UMINUS,a)); } @@ -562,71 +562,71 @@ namespace Duality { friend expr operator<=(expr const & a, expr const & b) { return a.ctx().make(Leq,a,b); // expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_LE,a,b)); - } + } friend expr operator>=(expr const & a, expr const & b) { return a.ctx().make(Geq,a,b); //expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_GE,a,b)); } - + friend expr operator<(expr const & a, expr const & b) { return a.ctx().make(Lt,a,b); expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_LT,a,b)); } - + friend expr operator>(expr const & a, expr const & b) { return a.ctx().make(Gt,a,b); expr(a.ctx(),a.m().mk_app(a.m().get_basic_family_id(),OP_GT,a,b)); - } + } expr simplify() const; expr simplify(params const & p) const; - + expr qe_lite() const; - expr qe_lite(const std::set &idxs, bool index_of_bound) const; + expr qe_lite(const std::set &idxs, bool index_of_bound) const; - friend expr clone_quantifier(const expr &, const expr &); + friend expr clone_quantifier(const expr &, const expr &); friend expr clone_quantifier(const expr &q, const expr &b, const std::vector &patterns); - friend expr clone_quantifier(decl_kind, const expr &, const expr &); + friend expr clone_quantifier(decl_kind, const expr &, const expr &); friend std::ostream & operator<<(std::ostream & out, expr const & m){ m.ctx().print_expr(out,m); return out; - } + } - void get_patterns(std::vector &pats) const ; + void get_patterns(std::vector &pats) const ; - unsigned get_quantifier_num_bound() const { + unsigned get_quantifier_num_bound() const { return to_quantifier(raw())->get_num_decls(); - } + } - unsigned get_index_value() const { + unsigned get_index_value() const { var* va = to_var(raw()); return va->get_idx(); - } + } bool is_quantifier_forall() const { return to_quantifier(raw())->is_forall(); - } + } - sort get_quantifier_bound_sort(unsigned n) const { + sort get_quantifier_bound_sort(unsigned n) const { return sort(ctx(),to_quantifier(raw())->get_decl_sort(n)); - } + } - symbol get_quantifier_bound_name(unsigned n) const { + symbol get_quantifier_bound_name(unsigned n) const { return symbol(ctx(),to_quantifier(raw())->get_decl_names()[n]); - } + } - friend expr forall(const std::vector &quants, const expr &body); + friend expr forall(const std::vector &quants, const expr &body); - friend expr exists(const std::vector &quants, const expr &body); + friend expr exists(const std::vector &quants, const expr &body); }; - + typedef ::decl_kind pfrule; - + class proof : public ast { public: proof(context & c):ast(c) {} @@ -643,15 +643,15 @@ namespace Duality { unsigned num_prems() const { return to_app(raw())->get_num_args() - 1; } - + expr conc() const { return ctx().cook(to_app(raw())->get_arg(num_prems())); } - + proof prem(unsigned i) const { return proof(ctx(),to_app(to_app(raw())->get_arg(i))); } - + void get_assumptions(std::vector &assumps); }; @@ -675,12 +675,12 @@ namespace Duality { T back() const { return operator[](size() - 1); } void pop_back() { assert(size() > 0); resize(size() - 1); } bool empty() const { return size() == 0; } - ast_vector_tpl & operator=(ast_vector_tpl const & s) { - Z3_ast_vector_inc_ref(s.ctx(), s.m_vector); + ast_vector_tpl & operator=(ast_vector_tpl const & s) { + Z3_ast_vector_inc_ref(s.ctx(), s.m_vector); // Z3_ast_vector_dec_ref(ctx(), m_vector); - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_vector = s.m_vector; - return *this; + return *this; } friend std::ostream & operator<<(std::ostream & out, ast_vector_tpl const & v) { out << Z3_ast_vector_to_string(v.ctx(), v); return out; } }; @@ -705,9 +705,9 @@ namespace Duality { ~func_interp() { } operator ::func_interp *() const { return m_interp; } func_interp & operator=(func_interp const & s) { - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_interp = s.m_interp; - return *this; + return *this; } unsigned num_entries() const { return m_interp->num_entries(); } expr get_arg(unsigned ent, unsigned arg) const { @@ -729,32 +729,32 @@ namespace Duality { m_model = m; } public: - model(context & c, ::model * m = 0):object(c), m_model(m) { } - model(model const & s):object(s), m_model(s.m_model) { } - ~model() { } + model(context & c, ::model * m = 0):object(c), m_model(m) { } + model(model const & s):object(s), m_model(s.m_model) { } + ~model() { } operator ::model *() const { return m_model.get(); } model & operator=(model const & s) { // ::model *_inc_ref(s.ctx(), s.m_model); // ::model *_dec_ref(ctx(), m_model); - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_model = s.m_model.get(); - return *this; + return *this; } model & operator=(::model *s) { - m_model = s; - return *this; + m_model = s; + return *this; } - bool null() const {return !m_model;} - + bool null() const {return !m_model;} + expr eval(expr const & n, bool model_completion=true) const { ::model * _m = m_model.get(); expr_ref result(ctx().m()); _m->eval(n, result, model_completion); return expr(ctx(), result); } - + void show() const; - void show_hash() const; + void show_hash() const; unsigned num_consts() const {return m_model.get()->get_num_constants();} unsigned num_funcs() const {return m_model.get()->get_num_functions();} @@ -765,11 +765,11 @@ namespace Duality { expr get_const_interp(func_decl f) const { return ctx().cook(m_model->get_const_interp(to_func_decl(f.raw()))); - } + } func_interp get_func_interp(func_decl f) const { return func_interp(ctx(),m_model->get_func_interp(to_func_decl(f.raw()))); - } + } #if 0 friend std::ostream & operator<<(std::ostream & out, model const & m) { out << Z3_model_to_string(m.ctx(), m); return out; } @@ -792,9 +792,9 @@ namespace Duality { stats & operator=(stats const & s) { Z3_stats_inc_ref(s.ctx(), s.m_stats); if (m_stats) Z3_stats_dec_ref(ctx(), m_stats); - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_stats = s.m_stats; - return *this; + return *this; } unsigned size() const { return Z3_stats_size(ctx(), m_stats); } std::string key(unsigned i) const { Z3_string s = Z3_stats_get_key(ctx(), m_stats, i); check_error(); return s; } @@ -820,7 +820,7 @@ namespace Duality { void assert_cnst(const expr &cnst); }; - inline std::ostream & operator<<(std::ostream & out, check_result r) { + inline std::ostream & operator<<(std::ostream & out, check_result r) { if (r == unsat) out << "unsat"; else if (r == sat) out << "sat"; else out << "unknown"; @@ -837,54 +837,54 @@ namespace Duality { protected: ::solver *m_solver; model the_model; - bool canceled; - proof_gen_mode m_mode; - bool extensional; + bool canceled; + proof_gen_mode m_mode; + bool extensional; public: solver(context & c, bool extensional = false, bool models = true); - solver(context & c, ::solver *s):object(c),the_model(c) { m_solver = s; canceled = false;} - solver(solver const & s):object(s), the_model(s.the_model) { m_solver = s.m_solver; canceled = false;} + solver(context & c, ::solver *s):object(c),the_model(c) { m_solver = s; canceled = false;} + solver(solver const & s):object(s), the_model(s.the_model) { m_solver = s.m_solver; canceled = false;} ~solver() { if(m_solver) dealloc(m_solver); - } - operator ::solver*() const { return m_solver; } - solver & operator=(solver const & s) { - m_ctx = s.m_ctx; - m_solver = s.m_solver; - the_model = s.the_model; - m_mode = s.m_mode; - return *this; } - struct cancel_exception {}; - void checkpoint(){ + operator ::solver*() const { return m_solver; } + solver & operator=(solver const & s) { + m_ctx = s.m_ctx; + m_solver = s.m_solver; + the_model = s.the_model; + m_mode = s.m_mode; + return *this; + } + struct cancel_exception {}; + void checkpoint(){ if(canceled) throw(cancel_exception()); - } + } // void set(params const & p) { Z3_solver_set_params(ctx(), m_solver, p); check_error(); } void push() { scoped_proof_mode spm(m(),m_mode); m_solver->push(); } void pop(unsigned n = 1) { scoped_proof_mode spm(m(),m_mode); m_solver->pop(n); } // void reset() { Z3_solver_reset(ctx(), m_solver); check_error(); } void add(expr const & e) { scoped_proof_mode spm(m(),m_mode); m_solver->assert_expr(e); } - check_result check() { - scoped_proof_mode spm(m(),m_mode); + check_result check() { + scoped_proof_mode spm(m(),m_mode); checkpoint(); lbool r = m_solver->check_sat(0,0); model_ref m; m_solver->get_model(m); the_model = m.get(); return to_check_result(r); - } - check_result check_keep_model(unsigned n, expr * const assumptions, unsigned *core_size = 0, expr *core = 0) { - scoped_proof_mode spm(m(),m_mode); + } + check_result check_keep_model(unsigned n, expr * const assumptions, unsigned *core_size = 0, expr *core = 0) { + scoped_proof_mode spm(m(),m_mode); model old_model(the_model); check_result res = check(n,assumptions,core_size,core); if(the_model == 0) the_model = old_model; return res; - } + } check_result check(unsigned n, expr * const assumptions, unsigned *core_size = 0, expr *core = 0) { - scoped_proof_mode spm(m(),m_mode); + scoped_proof_mode spm(m(),m_mode); checkpoint(); std::vector< ::expr *> _assumptions(n); for (unsigned i = 0; i < n; i++) { @@ -892,7 +892,7 @@ namespace Duality { } the_model = 0; lbool r = m_solver->check_sat(n, VEC2PTR(_assumptions)); - + if(core_size && core){ ptr_vector< ::expr> _core; m_solver->get_unsat_core(_core); @@ -905,20 +905,20 @@ namespace Duality { m_solver->get_model(m); the_model = m.get(); - return to_check_result(r); + return to_check_result(r); } #if 0 - check_result check(expr_vector assumptions) { - scoped_proof_mode spm(m(),m_mode); + check_result check(expr_vector assumptions) { + scoped_proof_mode spm(m(),m_mode); unsigned n = assumptions.size(); z3array _assumptions(n); for (unsigned i = 0; i < n; i++) { check_context(*this, assumptions[i]); _assumptions[i] = assumptions[i]; } - Z3_lbool r = Z3_check_assumptions(ctx(), m_solver, n, _assumptions.ptr()); - check_error(); - return to_check_result(r); + Z3_lbool r = Z3_check_assumptions(ctx(), m_solver, n, _assumptions.ptr()); + check_error(); + return to_check_result(r); } #endif model get_model() const { return model(ctx(), the_model); } @@ -930,27 +930,26 @@ namespace Duality { #endif // expr proof() const { Z3_ast r = Z3_solver_proof(ctx(), m_solver); check_error(); return expr(ctx(), r); } // friend std::ostream & operator<<(std::ostream & out, solver const & s) { out << Z3_solver_to_string(s.ctx(), s); return out; } - - int get_num_decisions(); + int get_num_decisions(); - void cancel(){ - scoped_proof_mode spm(m(),m_mode); + void cancel(){ + scoped_proof_mode spm(m(),m_mode); canceled = true; m().limit().cancel(); - } + } - unsigned get_scope_level(){ scoped_proof_mode spm(m(),m_mode); return m_solver->get_scope_level();} + unsigned get_scope_level(){ scoped_proof_mode spm(m(),m_mode); return m_solver->get_scope_level();} - void show(); - void print(const char *filename); - void show_assertion_ids(); + void show(); + void print(const char *filename); + void show_assertion_ids(); - proof get_proof(){ - scoped_proof_mode spm(m(),m_mode); + proof get_proof(){ + scoped_proof_mode spm(m(),m_mode); return proof(ctx(),m_solver->get_proof()); - } + } - bool extensional_array_theory() {return extensional;} + bool extensional_array_theory() {return extensional;} }; #if 0 @@ -969,20 +968,20 @@ namespace Duality { goal & operator=(goal const & s) { Z3_goal_inc_ref(s.ctx(), s.m_goal); Z3_goal_dec_ref(ctx(), m_goal); - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_goal = s.m_goal; - return *this; + return *this; } void add(expr const & f) { check_context(*this, f); Z3_goal_assert(ctx(), m_goal, f); check_error(); } unsigned size() const { return Z3_goal_size(ctx(), m_goal); } expr operator[](unsigned i) const { Z3_ast r = Z3_goal_formula(ctx(), m_goal, i); check_error(); return expr(ctx(), r); } Z3_goal_prec precision() const { return Z3_goal_precision(ctx(), m_goal); } bool inconsistent() const { return Z3_goal_inconsistent(ctx(), m_goal) != 0; } - unsigned depth() const { return Z3_goal_depth(ctx(), m_goal); } + unsigned depth() const { return Z3_goal_depth(ctx(), m_goal); } void reset() { Z3_goal_reset(ctx(), m_goal); } unsigned num_exprs() const { Z3_goal_num_exprs(ctx(), m_goal); } - bool is_decided_sat() const { return Z3_goal_is_decided_sat(ctx(), m_goal) != 0; } - bool is_decided_unsat() const { return Z3_goal_is_decided_unsat(ctx(), m_goal) != 0; } + bool is_decided_sat() const { return Z3_goal_is_decided_sat(ctx(), m_goal) != 0; } + bool is_decided_unsat() const { return Z3_goal_is_decided_unsat(ctx(), m_goal) != 0; } friend std::ostream & operator<<(std::ostream & out, goal const & g) { out << Z3_goal_to_string(g.ctx(), g); return out; } }; @@ -1000,15 +999,15 @@ namespace Duality { apply_result & operator=(apply_result const & s) { Z3_apply_result_inc_ref(s.ctx(), s.m_apply_result); Z3_apply_result_dec_ref(ctx(), m_apply_result); - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_apply_result = s.m_apply_result; - return *this; + return *this; } unsigned size() const { return Z3_apply_result_get_num_subgoals(ctx(), m_apply_result); } goal operator[](unsigned i) const { Z3_goal r = Z3_apply_result_get_subgoal(ctx(), m_apply_result, i); check_error(); return goal(ctx(), r); } goal operator[](int i) const { assert(i >= 0); return this->operator[](static_cast(i)); } - model convert_model(model const & m, unsigned i = 0) const { - check_context(*this, m); + model convert_model(model const & m, unsigned i = 0) const { + check_context(*this, m); Z3_model new_m = Z3_apply_result_convert_model(ctx(), m_apply_result, i, m); check_error(); return model(ctx(), new_m); @@ -1031,16 +1030,16 @@ namespace Duality { tactic & operator=(tactic const & s) { Z3_tactic_inc_ref(s.ctx(), s.m_tactic); Z3_tactic_dec_ref(ctx(), m_tactic); - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_tactic = s.m_tactic; - return *this; + return *this; } solver mk_solver() const { Z3_solver r = Z3_mk_solver_from_tactic(ctx(), m_tactic); check_error(); return solver(ctx(), r); } - apply_result apply(goal const & g) const { + apply_result apply(goal const & g) const { check_context(*this, g); - Z3_apply_result r = Z3_tactic_apply(ctx(), m_tactic, g); - check_error(); - return apply_result(ctx(), r); + Z3_apply_result r = Z3_tactic_apply(ctx(), m_tactic, g); + check_error(); + return apply_result(ctx(), r); } apply_result operator()(goal const & g) const { return apply(g); @@ -1091,45 +1090,45 @@ namespace Duality { probe & operator=(probe const & s) { Z3_probe_inc_ref(s.ctx(), s.m_probe); Z3_probe_dec_ref(ctx(), m_probe); - m_ctx = s.m_ctx; + m_ctx = s.m_ctx; m_probe = s.m_probe; - return *this; + return *this; } double apply(goal const & g) const { double r = Z3_probe_apply(ctx(), m_probe, g); check_error(); return r; } double operator()(goal const & g) const { return apply(g); } - friend probe operator<=(probe const & p1, probe const & p2) { - check_context(p1, p2); Z3_probe r = Z3_probe_le(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + friend probe operator<=(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_le(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); } friend probe operator<=(probe const & p1, double p2) { return p1 <= probe(p1.ctx(), p2); } friend probe operator<=(double p1, probe const & p2) { return probe(p2.ctx(), p1) <= p2; } - friend probe operator>=(probe const & p1, probe const & p2) { - check_context(p1, p2); Z3_probe r = Z3_probe_ge(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + friend probe operator>=(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_ge(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); } friend probe operator>=(probe const & p1, double p2) { return p1 >= probe(p1.ctx(), p2); } friend probe operator>=(double p1, probe const & p2) { return probe(p2.ctx(), p1) >= p2; } - friend probe operator<(probe const & p1, probe const & p2) { - check_context(p1, p2); Z3_probe r = Z3_probe_lt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + friend probe operator<(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_lt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); } friend probe operator<(probe const & p1, double p2) { return p1 < probe(p1.ctx(), p2); } friend probe operator<(double p1, probe const & p2) { return probe(p2.ctx(), p1) < p2; } - friend probe operator>(probe const & p1, probe const & p2) { - check_context(p1, p2); Z3_probe r = Z3_probe_gt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + friend probe operator>(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_gt(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); } friend probe operator>(probe const & p1, double p2) { return p1 > probe(p1.ctx(), p2); } friend probe operator>(double p1, probe const & p2) { return probe(p2.ctx(), p1) > p2; } - friend probe operator==(probe const & p1, probe const & p2) { - check_context(p1, p2); Z3_probe r = Z3_probe_eq(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + friend probe operator==(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_eq(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); } friend probe operator==(probe const & p1, double p2) { return p1 == probe(p1.ctx(), p2); } friend probe operator==(double p1, probe const & p2) { return probe(p2.ctx(), p1) == p2; } - friend probe operator&&(probe const & p1, probe const & p2) { - check_context(p1, p2); Z3_probe r = Z3_probe_and(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + friend probe operator&&(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_and(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); } - friend probe operator||(probe const & p1, probe const & p2) { - check_context(p1, p2); Z3_probe r = Z3_probe_or(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); + friend probe operator||(probe const & p1, probe const & p2) { + check_context(p1, p2); Z3_probe r = Z3_probe_or(p1.ctx(), p1, p2); p1.check_error(); return probe(p1.ctx(), r); } friend probe operator!(probe const & p) { - Z3_probe r = Z3_probe_not(p.ctx(), p); p.check_error(); return probe(p.ctx(), r); + Z3_probe r = Z3_probe_not(p.ctx(), p); p.check_error(); return probe(p.ctx(), r); } }; @@ -1159,15 +1158,15 @@ namespace Duality { inline symbol context::int_symbol(int n) { ::symbol r = ::symbol(n); return symbol(*this, r); } inline sort context::bool_sort() { - ::sort *s = m().mk_sort(m_basic_fid, BOOL_SORT); + ::sort *s = m().mk_sort(m_basic_fid, BOOL_SORT); return sort(*this, s); } inline sort context::int_sort() { - ::sort *s = m().mk_sort(m_arith_fid, INT_SORT); + ::sort *s = m().mk_sort(m_arith_fid, INT_SORT); return sort(*this, s); } inline sort context::real_sort() { - ::sort *s = m().mk_sort(m_arith_fid, REAL_SORT); + ::sort *s = m().mk_sort(m_arith_fid, REAL_SORT); return sort(*this, s); } inline sort context::array_sort(sort d, sort r) { @@ -1188,7 +1187,7 @@ namespace Duality { inline func_decl context::function(char const * name, unsigned arity, sort const * domain, sort const & range) { return function(str_symbol(name), arity, domain, range); } - + inline func_decl context::function(char const * name, sort const & domain, sort const & range) { sort args[1] = { domain }; return function(name, 1, args, range); @@ -1196,7 +1195,7 @@ namespace Duality { inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & range) { sort args[2] = { d1, d2 }; - return function(name, 2, args, range); + return function(name, 2, args, range); } inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & range) { @@ -1208,7 +1207,7 @@ namespace Duality { sort args[4] = { d1, d2, d3, d4 }; return function(name, 4, args, range); } - + inline func_decl context::function(char const * name, sort const & d1, sort const & d2, sort const & d3, sort const & d4, sort const & d5, sort const & range) { sort args[5] = { d1, d2, d3, d4, d5 }; return function(name, 5, args, range); @@ -1217,7 +1216,7 @@ namespace Duality { inline expr context::constant(symbol const & name, sort const & s) { ::expr *r = m().mk_const(m().mk_const_decl(name, s)); - return expr(*this, r); + return expr(*this, r); } inline expr context::constant(char const * name, sort const & s) { return constant(str_symbol(name), s); } inline expr context::bool_const(char const * name) { return constant(name, bool_sort()); } @@ -1250,11 +1249,11 @@ namespace Duality { expr args[5] = {a1,a2,a3,a4,a5}; return operator()(5,args); } - - + + inline expr select(expr const & a, expr const & i) { return a.ctx().make(Select,a,i); } inline expr store(expr const & a, expr const & i, expr const & v) { return a.ctx().make(Store,a,i,v); } - + inline expr forall(const std::vector &quants, const expr &body){ return body.ctx().make_quant(Forall,quants,body); } @@ -1304,7 +1303,7 @@ namespace Duality { } inline void setTerm(expr t){term = t;} - + inline void addTerm(expr t){terms.push_back(t);} inline void setChildren(const std::vector & _children){ @@ -1326,7 +1325,7 @@ namespace Duality { std::vector children; int num; }; - + typedef context interpolating_context; class interpolating_solver : public solver { @@ -1336,7 +1335,7 @@ namespace Duality { { weak_mode = false; } - + public: lbool interpolate(const std::vector &assumptions, std::vector &interpolants, @@ -1344,41 +1343,41 @@ namespace Duality { literals &lits, bool incremental ); - + lbool interpolate_tree(TermTree *assumptions, TermTree *&interpolants, model &_model, literals &lits, bool incremental ); - + bool read_interpolation_problem(const std::string &file_name, std::vector &assumptions, std::vector &theory, std::string &error_message ); - + void write_interpolation_problem(const std::string &file_name, const std::vector &assumptions, const std::vector &theory ); - + void AssertInterpolationAxiom(const expr &expr); void RemoveInterpolationAxiom(const expr &expr); - + void SetWeakInterpolants(bool weak); void SetPrintToFile(const std::string &file_name); - + const std::vector &GetInterpolationAxioms() {return theory;} const char *profile(); - + private: bool weak_mode; std::string print_filename; std::vector theory; }; - - + + inline expr context::cook(::expr *a) {return expr(*this,a);} inline std::vector context::cook(ptr_vector< ::expr> v) { diff --git a/src/interp/iz3base.h b/src/interp/iz3base.h index ac171aa9e..15f613730 100755 --- a/src/interp/iz3base.h +++ b/src/interp/iz3base.h @@ -66,35 +66,35 @@ class iz3base : public iz3mgr, public scopes { /** Constructor */ - iz3base(ast_manager &_m_manager, - const std::vector &_cnsts, - const std::vector &_parents, - const std::vector &_theory) - : iz3mgr(_m_manager), scopes(_parents) { + iz3base(ast_manager &_m_manager, + const std::vector &_cnsts, + const std::vector &_parents, + const std::vector &_theory) + : iz3mgr(_m_manager), scopes(_parents) { initialize(_cnsts,_parents,_theory); weak = false; } - iz3base(const iz3mgr& other, - const std::vector &_cnsts, - const std::vector &_parents, - const std::vector &_theory) - : iz3mgr(other), scopes(_parents) { + iz3base(const iz3mgr& other, + const std::vector &_cnsts, + const std::vector &_parents, + const std::vector &_theory) + : iz3mgr(other), scopes(_parents) { initialize(_cnsts,_parents,_theory); weak = false; } - iz3base(const iz3mgr& other, - const std::vector > &_cnsts, - const std::vector &_parents, - const std::vector &_theory) - : iz3mgr(other), scopes(_parents) { + iz3base(const iz3mgr& other, + const std::vector > &_cnsts, + const std::vector &_parents, + const std::vector &_theory) + : iz3mgr(other), scopes(_parents) { initialize(_cnsts,_parents,_theory); weak = false; } - iz3base(const iz3mgr& other) - : iz3mgr(other), scopes() { + iz3base(const iz3mgr& other) + : iz3mgr(other), scopes() { weak = false; } diff --git a/src/interp/iz3checker.h b/src/interp/iz3checker.h index 175b5a43a..d89db3011 100644 --- a/src/interp/iz3checker.h +++ b/src/interp/iz3checker.h @@ -24,26 +24,26 @@ #include "solver/solver.h" bool iz3check(ast_manager &_m_manager, - solver *s, - std::ostream &err, - const ptr_vector &cnsts, - const ::vector &parents, - const ptr_vector &interps, - const ptr_vector &theory); + solver *s, + std::ostream &err, + const ptr_vector &cnsts, + const ::vector &parents, + const ptr_vector &interps, + const ptr_vector &theory); bool iz3check(ast_manager &_m_manager, - solver *s, - std::ostream &err, - const ptr_vector &cnsts, - ast *tree, - const ptr_vector &interps); + solver *s, + std::ostream &err, + const ptr_vector &cnsts, + ast *tree, + const ptr_vector &interps); bool iz3check(iz3mgr &mgr, - solver *s, - std::ostream &err, - const std::vector &cnsts, - const std::vector &parents, - const std::vector &interps, - const ptr_vector &theory); + solver *s, + std::ostream &err, + const std::vector &cnsts, + const std::vector &parents, + const std::vector &interps, + const ptr_vector &theory); #endif diff --git a/src/interp/iz3hash.h b/src/interp/iz3hash.h index 483c7ca49..c796a247b 100644 --- a/src/interp/iz3hash.h +++ b/src/interp/iz3hash.h @@ -468,10 +468,10 @@ namespace hash_space { : hashtable,Key,HashFun,proj1,EqFun>(7) {} Value &operator[](const Key& key) { - std::pair kvp(key,Value()); - return - hashtable,Key,HashFun,proj1,EqFun>:: - lookup(kvp,true)->val.second; + std::pair kvp(key,Value()); + return + hashtable,Key,HashFun,proj1,EqFun>:: + lookup(kvp,true)->val.second; } }; diff --git a/src/interp/iz3interp.h b/src/interp/iz3interp.h index 9763208f1..a4e1024a9 100644 --- a/src/interp/iz3interp.h +++ b/src/interp/iz3interp.h @@ -73,22 +73,22 @@ typedef interpolation_options_struct *interpolation_options; representation, for compatibility with the old API. */ void iz3interpolate(ast_manager &_m_manager, - ast *proof, - const ptr_vector &cnsts, - const ::vector &parents, - ptr_vector &interps, - const ptr_vector &theory, - interpolation_options_struct * options = 0); + ast *proof, + const ptr_vector &cnsts, + const ::vector &parents, + ptr_vector &interps, + const ptr_vector &theory, + interpolation_options_struct * options = 0); /* Same as above, but each constraint is a vector of formulas. */ void iz3interpolate(ast_manager &_m_manager, - ast *proof, - const vector > &cnsts, - const ::vector &parents, - ptr_vector &interps, - const ptr_vector &theory, - interpolation_options_struct * options = 0); + ast *proof, + const vector > &cnsts, + const ::vector &parents, + ptr_vector &interps, + const ptr_vector &theory, + interpolation_options_struct * options = 0); /* Compute an interpolant from a proof. This version uses the ast representation, for compatibility with the new API. Here, cnsts is @@ -98,11 +98,11 @@ void iz3interpolate(ast_manager &_m_manager, proof, so it can be considered a hint. */ void iz3interpolate(ast_manager &_m_manager, - ast *proof, - const ptr_vector &cnsts, - ast *tree, - ptr_vector &interps, - interpolation_options_struct * options); + ast *proof, + const ptr_vector &cnsts, + ast *tree, + ptr_vector &interps, + interpolation_options_struct * options); /* Compute an interpolant from an ast representing an interpolation @@ -112,12 +112,12 @@ void iz3interpolate(ast_manager &_m_manager, */ lbool iz3interpolate(ast_manager &_m_manager, - solver &s, - ast *tree, - ptr_vector &cnsts, - ptr_vector &interps, - model_ref &m, - interpolation_options_struct * options); + solver &s, + ast *tree, + ptr_vector &cnsts, + ptr_vector &interps, + model_ref &m, + interpolation_options_struct * options); #endif diff --git a/src/interp/iz3pp.h b/src/interp/iz3pp.h index eec88d35e..7b3405f9b 100644 --- a/src/interp/iz3pp.h +++ b/src/interp/iz3pp.h @@ -30,7 +30,7 @@ struct iz3pp_bad_tree: public iz3_exception { }; void iz3pp(ast_manager &m, - const ptr_vector &cnsts_vec, - expr *tree, - std::ostream& out); + const ptr_vector &cnsts_vec, + expr *tree, + std::ostream& out); #endif diff --git a/src/interp/iz3scopes.h b/src/interp/iz3scopes.h index 745256e57..ece30dc25 100755 --- a/src/interp/iz3scopes.h +++ b/src/interp/iz3scopes.h @@ -105,7 +105,7 @@ class scopes { void range_add(int i, range &n){ #if 0 - if(i < n.lo) n.lo = i; + if(i < n.lo) n.lo = i; if(i > n.hi) n.hi = i; #else range rng; rng.lo = i; rng.hi = i; @@ -119,7 +119,7 @@ class scopes { int thing = tree_lca(rng1.lo,rng2.hi); if(thing == rng1.lo) frame = rng1.lo; else frame = tree_gcd(thing,rng1.hi); - return frame; + return frame; } #else diff --git a/src/interp/iz3translate.h b/src/interp/iz3translate.h index 3430d11b3..519a252e0 100755 --- a/src/interp/iz3translate.h +++ b/src/interp/iz3translate.h @@ -47,9 +47,9 @@ class iz3translation : public iz3base { protected: iz3translation(iz3mgr &mgr, - const std::vector > &_cnsts, - const std::vector &_parents, - const std::vector &_theory) + const std::vector > &_cnsts, + const std::vector &_parents, + const std::vector &_theory) : iz3base(mgr,_cnsts,_parents,_theory) {} }; diff --git a/src/math/automata/automaton.h b/src/math/automata/automaton.h index 07d6d31ec..41fc19907 100644 --- a/src/math/automata/automaton.h +++ b/src/math/automata/automaton.h @@ -478,7 +478,7 @@ public: unsigned out_degree(unsigned state) const { return m_delta[state].size(); } move const& get_move_from(unsigned state) const { SASSERT(m_delta[state].size() == 1); return m_delta[state][0]; } move const& get_move_to(unsigned state) const { SASSERT(m_delta_inv[state].size() == 1); return m_delta_inv[state][0]; } - moves const& get_moves_from(unsigned state) const { return m_delta[state]; } + moves const& get_moves_from(unsigned state) const { return m_delta[state]; } moves const& get_moves_to(unsigned state) const { return m_delta_inv[state]; } bool initial_state_is_source() const { return m_delta_inv[m_init].empty(); } bool is_final_state(unsigned s) const { return m_final_set.contains(s); } diff --git a/src/math/automata/boolean_algebra.h b/src/math/automata/boolean_algebra.h index e49d414c4..d54ff5d1a 100644 --- a/src/math/automata/boolean_algebra.h +++ b/src/math/automata/boolean_algebra.h @@ -40,9 +40,7 @@ template class boolean_algebra : public positive_boolean_algebra { public: virtual ~boolean_algebra() {} - virtual T mk_not(T x) = 0; - //virtual lbool are_equivalent(T x, T y) = 0; - //virtual T simplify(T x) = 0; + virtual T mk_not(T x) = 0; }; #endif diff --git a/src/math/polynomial/polynomial.h b/src/math/polynomial/polynomial.h index 138331ef3..43b3c1138 100644 --- a/src/math/polynomial/polynomial.h +++ b/src/math/polynomial/polynomial.h @@ -63,8 +63,8 @@ namespace polynomial { public: void set_degree(var x, unsigned d) { m_var2degree.setx(x, d, 0); } unsigned degree(var x) const { return m_var2degree.get(x, 0); } - void display(std::ostream & out) const; - friend std::ostream & operator<<(std::ostream & out, var2degree const & ideal) { ideal.display(out); return out; } + void display(std::ostream & out) const; + friend std::ostream & operator<<(std::ostream & out, var2degree const & ideal) { ideal.display(out); return out; } }; template diff --git a/src/math/polynomial/upolynomial.h b/src/math/polynomial/upolynomial.h index e0df0dd31..f8efae465 100644 --- a/src/math/polynomial/upolynomial.h +++ b/src/math/polynomial/upolynomial.h @@ -434,11 +434,11 @@ namespace upolynomial { m().reset(r[i]); } for (unsigned i = 0; i < sz; i++) { - typename polynomial::monomial * mon = pm.get_monomial(p, i); - if (pm.size(mon) == 0) { + typename polynomial::monomial * mon = pm.get_monomial(p, i); + if (pm.size(mon) == 0) { m().set(r[0], pm.coeff(p, i)); - } else if (pm.size(mon) == 1 && pm.get_var(mon, 0) == x) { - unsigned m_deg_x = pm.degree(mon, 0); + } else if (pm.size(mon) == 1 && pm.get_var(mon, 0) == x) { + unsigned m_deg_x = pm.degree(mon, 0); m().set(r[m_deg_x], pm.coeff(p, i)); } } diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 2fd2d8746..f94558097 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -86,13 +86,13 @@ void model_core::register_decl(func_decl * d, func_interp * fi) { void model_core::unregister_decl(func_decl * d) { decl2expr::obj_map_entry * ec = m_interp.find_core(d); if (ec && ec->get_data().m_value != 0) { - m_manager.dec_ref(ec->get_data().m_key); - m_manager.dec_ref(ec->get_data().m_value); + m_manager.dec_ref(ec->get_data().m_key); + m_manager.dec_ref(ec->get_data().m_value); m_interp.remove(d); m_const_decls.erase(d); return; } - + decl2finterp::obj_map_entry * ef = m_finterp.find_core(d); if (ef && ef->get_data().m_value != 0) { m_manager.dec_ref(ef->get_data().m_key); diff --git a/src/muz/base/dl_context.h b/src/muz/base/dl_context.h index 738c2559e..129277514 100644 --- a/src/muz/base/dl_context.h +++ b/src/muz/base/dl_context.h @@ -54,7 +54,7 @@ namespace datalog { MEMOUT, INPUT_ERROR, APPROX, - BOUNDED, + BOUNDED, CANCELED }; @@ -318,7 +318,7 @@ namespace datalog { \brief Retrieve predicates */ func_decl_set const& get_predicates() const { return m_preds; } - ast_ref_vector const &get_pinned() const {return m_pinned; } + ast_ref_vector const &get_pinned() const {return m_pinned; } bool is_predicate(func_decl* pred) const { return m_preds.contains(pred); } bool is_predicate(expr * e) const { return is_app(e) && is_predicate(to_app(e)->get_decl()); } @@ -534,7 +534,7 @@ namespace datalog { \brief retrieve proof from derivation of the query. \pre engine == 'pdr' || engine == 'duality'- this option is only supported - for PDR mode and Duality mode. + for PDR mode and Duality mode. */ proof_ref get_proof(); diff --git a/src/muz/base/dl_engine_base.h b/src/muz/base/dl_engine_base.h index 9c20c712d..576ed7f6b 100644 --- a/src/muz/base/dl_engine_base.h +++ b/src/muz/base/dl_engine_base.h @@ -32,7 +32,7 @@ namespace datalog { QBMC_ENGINE, TAB_ENGINE, CLP_ENGINE, - DUALITY_ENGINE, + DUALITY_ENGINE, DDNF_ENGINE, LAST_ENGINE }; diff --git a/src/muz/duality/duality_dl_interface.h b/src/muz/duality/duality_dl_interface.h index 21291a45b..506642217 100644 --- a/src/muz/duality/duality_dl_interface.h +++ b/src/muz/duality/duality_dl_interface.h @@ -37,7 +37,7 @@ namespace Duality { class dl_interface : public datalog::engine_base { duality_data *_d; - datalog::context &m_ctx; + datalog::context &m_ctx; public: dl_interface(datalog::context& ctx); @@ -69,7 +69,7 @@ namespace Duality { proof_ref get_proof(); - duality_data *dd(){return _d;} + duality_data *dd(){return _d;} private: void display_certificate_non_const(std::ostream& out); diff --git a/src/muz/pdr/pdr_generalizers.h b/src/muz/pdr/pdr_generalizers.h index 3d0fe6ccd..e0feda310 100644 --- a/src/muz/pdr/pdr_generalizers.h +++ b/src/muz/pdr/pdr_generalizers.h @@ -88,7 +88,7 @@ namespace pdr { virtual ~core_convex_hull_generalizer() {} virtual void operator()(model_node& n, expr_ref_vector const& core, bool uses_level, cores& new_cores); virtual void operator()(model_node& n, expr_ref_vector& core, bool& uses_level); - }; + }; class core_multi_generalizer : public core_generalizer { core_bool_inductive_generalizer m_gen; diff --git a/src/muz/rel/dl_mk_similarity_compressor.h b/src/muz/rel/dl_mk_similarity_compressor.h index 68410831c..096305c59 100644 --- a/src/muz/rel/dl_mk_similarity_compressor.h +++ b/src/muz/rel/dl_mk_similarity_compressor.h @@ -53,7 +53,7 @@ namespace datalog { */ class mk_similarity_compressor : public rule_transformer::plugin { - context & m_context; + context & m_context; ast_manager & m_manager; /** number of similar rules necessary for a group to be introduced */ unsigned m_threshold_count; diff --git a/src/muz/rel/dl_mk_simple_joins.h b/src/muz/rel/dl_mk_simple_joins.h index 4d422e651..cf4522c22 100644 --- a/src/muz/rel/dl_mk_simple_joins.h +++ b/src/muz/rel/dl_mk_simple_joins.h @@ -49,7 +49,7 @@ namespace datalog { We say that a rule containing C_i's is a rule with a "big tail". */ class mk_simple_joins : public rule_transformer::plugin { - context & m_context; + context & m_context; rule_manager & rm; public: mk_simple_joins(context & ctx); diff --git a/src/muz/spacer/spacer_qe_project.cpp b/src/muz/spacer/spacer_qe_project.cpp index 8dbf87ca5..dd6472224 100644 --- a/src/muz/spacer/spacer_qe_project.cpp +++ b/src/muz/spacer/spacer_qe_project.cpp @@ -1209,7 +1209,7 @@ namespace qe { void operator()(model& mdl, app_ref_vector& vars, expr_ref& fml) { expr_map map (m); - operator()(mdl, vars, fml, map); + operator()(mdl, vars, fml, map); } void operator()(model& mdl, app_ref_vector& vars, expr_ref& fml, expr_map& map) { diff --git a/src/muz/transforms/dl_mk_magic_sets.h b/src/muz/transforms/dl_mk_magic_sets.h index eef40fd71..73b5e94f6 100644 --- a/src/muz/transforms/dl_mk_magic_sets.h +++ b/src/muz/transforms/dl_mk_magic_sets.h @@ -93,7 +93,7 @@ namespace datalog { typedef obj_map pred_adornment_map; typedef obj_map pred2pred; - context & m_context; + context & m_context; ast_manager & m; rule_manager& rm; ast_ref_vector m_pinned; diff --git a/src/muz/transforms/dl_mk_unbound_compressor.h b/src/muz/transforms/dl_mk_unbound_compressor.h index febb4bd46..6f53e0707 100644 --- a/src/muz/transforms/dl_mk_unbound_compressor.h +++ b/src/muz/transforms/dl_mk_unbound_compressor.h @@ -50,7 +50,7 @@ namespace datalog { typedef hashtable > in_progress_table; typedef svector todo_stack; - context & m_context; + context & m_context; ast_manager & m; rule_manager & rm; rule_ref_vector m_rules; diff --git a/src/smt/diff_logic.h b/src/smt/diff_logic.h index 67d1f045d..44e858219 100644 --- a/src/smt/diff_logic.h +++ b/src/smt/diff_logic.h @@ -956,8 +956,8 @@ public: } void get_neighbours_undirected(dl_var current, svector & neighbours) { - neighbours.reset(); - edge_id_vector & out_edges = m_out_edges[current]; + neighbours.reset(); + edge_id_vector & out_edges = m_out_edges[current]; typename edge_id_vector::iterator it = out_edges.begin(), end = out_edges.end(); for (; it != end; ++it) { edge_id e_id = *it; @@ -968,7 +968,7 @@ public: } edge_id_vector & in_edges = m_in_edges[current]; typename edge_id_vector::iterator it2 = in_edges.begin(), end2 = in_edges.end(); - for (; it2 != end2; ++it2) { + for (; it2 != end2; ++it2) { edge_id e_id = *it2; edge & e = m_edges[e_id]; SASSERT(e.get_target() == current); @@ -980,19 +980,19 @@ public: void dfs_undirected(dl_var start, svector & threads) { threads.reset(); threads.resize(get_num_nodes()); - uint_set discovered, explored; - svector nodes; + uint_set discovered, explored; + svector nodes; discovered.insert(start); - nodes.push_back(start); - dl_var prev = start; - while(!nodes.empty()) { - dl_var current = nodes.back(); + nodes.push_back(start); + dl_var prev = start; + while(!nodes.empty()) { + dl_var current = nodes.back(); SASSERT(discovered.contains(current) && !explored.contains(current)); - svector neighbours; - get_neighbours_undirected(current, neighbours); + svector neighbours; + get_neighbours_undirected(current, neighbours); SASSERT(!neighbours.empty()); bool found = false; - for (unsigned i = 0; i < neighbours.size(); ++i) { + for (unsigned i = 0; i < neighbours.size(); ++i) { dl_var next = neighbours[i]; DEBUG_CODE( edge_id id; @@ -1002,18 +1002,18 @@ public: threads[prev] = next; prev = next; discovered.insert(next); - nodes.push_back(next); + nodes.push_back(next); found = true; break; } - } + } SASSERT(!nodes.empty()); if (!found) { explored.insert(current); nodes.pop_back(); } - } - threads[prev] = start; + } + threads[prev] = start; } void bfs_undirected(dl_var start, svector & parents, svector & depths) { @@ -1022,31 +1022,31 @@ public: parents[start] = -1; depths.reset(); depths.resize(get_num_nodes()); - uint_set visited; - std::deque nodes; - visited.insert(start); - nodes.push_front(start); - while(!nodes.empty()) { + uint_set visited; + std::deque nodes; + visited.insert(start); + nodes.push_front(start); + while(!nodes.empty()) { dl_var current = nodes.back(); nodes.pop_back(); - SASSERT(visited.contains(current)); + SASSERT(visited.contains(current)); svector neighbours; - get_neighbours_undirected(current, neighbours); + get_neighbours_undirected(current, neighbours); SASSERT(!neighbours.empty()); - for (unsigned i = 0; i < neighbours.size(); ++i) { - dl_var next = neighbours[i]; + for (unsigned i = 0; i < neighbours.size(); ++i) { + dl_var next = neighbours[i]; DEBUG_CODE( edge_id id; SASSERT(get_edge_id(current, next, id) || get_edge_id(next, current, id));); if (!visited.contains(next)) { TRACE("diff_logic", tout << "parents[" << next << "] --> " << current << std::endl;); - parents[next] = current; - depths[next] = depths[current] + 1; - visited.insert(next); - nodes.push_front(next); + parents[next] = current; + depths[next] = depths[current] + 1; + visited.insert(next); + nodes.push_front(next); } - } - } + } + } } template diff --git a/src/smt/smt_enode.h b/src/smt/smt_enode.h index 4b3a64d90..f471314fa 100644 --- a/src/smt/smt_enode.h +++ b/src/smt/smt_enode.h @@ -40,10 +40,10 @@ namespace smt { /** \ brief Use sparse maps in SMT solver. - Define this to use hash maps rather than vectors over ast - nodes. This is useful in the case there are many solvers, each - referencing few nodes from a large ast manager. There is some - unknown performance penalty for this. */ + Define this to use hash maps rather than vectors over ast + nodes. This is useful in the case there are many solvers, each + referencing few nodes from a large ast manager. There is some + unknown performance penalty for this. */ // #define SPARSE_MAP diff --git a/src/smt/smt_quantifier.h b/src/smt/smt_quantifier.h index a55c895e6..d89f3f6a4 100644 --- a/src/smt/smt_quantifier.h +++ b/src/smt/smt_quantifier.h @@ -149,7 +149,7 @@ namespace smt { /** \brief Is "model based" instantiate allowed to instantiate this quantifier? */ - virtual bool mbqi_enabled(quantifier *q) const {return true;} + virtual bool mbqi_enabled(quantifier *q) const {return true;} /** \brief Give a change to the plugin to adjust the interpretation of unintepreted functions. diff --git a/src/smt/smt_theory.h b/src/smt/smt_theory.h index 71eedc1a7..2ee0db322 100644 --- a/src/smt/smt_theory.h +++ b/src/smt/smt_theory.h @@ -192,7 +192,7 @@ namespace smt { virtual lbool validate_unsat_core(expr_ref_vector & unsat_core) { return l_false; } - + /** \brief This method is invoked before the search starts. */ diff --git a/src/smt/theory_seq.h b/src/smt/theory_seq.h index 1f97697c2..2ad257fd7 100644 --- a/src/smt/theory_seq.h +++ b/src/smt/theory_seq.h @@ -45,7 +45,7 @@ namespace smt { typedef trail_stack th_trail_stack; typedef std::pair expr_dep; typedef obj_map eqdep_map_t; - typedef union_find th_union_find; + typedef union_find th_union_find; class seq_value_proc; @@ -298,8 +298,8 @@ namespace smt { scoped_vector m_eqs; // set of current equations. scoped_vector m_nqs; // set of current disequalities. scoped_vector m_ncs; // set of non-contains constraints. - unsigned m_eq_id; - th_union_find m_find; + unsigned m_eq_id; + th_union_find m_find; seq_factory* m_factory; // value factory exclusion_table m_exclude; // set of asserted disequalities. @@ -584,7 +584,7 @@ namespace smt { // model building app* mk_value(app* a); - th_trail_stack& get_trail_stack() { return m_trail_stack; } + th_trail_stack& get_trail_stack() { return m_trail_stack; } void merge_eh(theory_var, theory_var, theory_var v1, theory_var v2) {} void after_merge_eh(theory_var r1, theory_var r2, theory_var v1, theory_var v2) { } void unmerge_eh(theory_var v1, theory_var v2) {} diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 88b044a90..8a141665c 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -4748,11 +4748,11 @@ namespace smt { context& ctx = get_context(); ast_manager & m = get_manager(); - // safety - if (!ctx.e_internalized(e)) { + // safety + if (!ctx.e_internalized(e)) { return false; - } - + } + // if an integer constant exists in the eqc, it should be the root enode * en_e = ctx.get_enode(e); enode * root_e = en_e->get_root(); @@ -7028,7 +7028,7 @@ namespace smt { ast_manager & m = get_manager(); if (lenTester_fvar_map.contains(lenTester)) { expr * fVar = lenTester_fvar_map[lenTester]; - expr_ref toAssert(gen_len_val_options_for_free_var(fVar, lenTester, lenTesterValue), m); + expr_ref toAssert(gen_len_val_options_for_free_var(fVar, lenTester, lenTesterValue), m); TRACE("str", tout << "asserting more length tests for free variable " << mk_ismt2_pp(fVar, m) << std::endl;); if (toAssert) { assert_axiom(toAssert); diff --git a/src/smt/watch_list.cpp b/src/smt/watch_list.cpp index 2ff75c418..edd6923d7 100644 --- a/src/smt/watch_list.cpp +++ b/src/smt/watch_list.cpp @@ -36,10 +36,10 @@ namespace smt { void watch_list::expand() { if (m_data == 0) { - unsigned size = DEFAULT_WATCH_LIST_SIZE + HEADER_SIZE; + unsigned size = DEFAULT_WATCH_LIST_SIZE + HEADER_SIZE; unsigned * mem = reinterpret_cast(alloc_svect(char, size)); #ifdef _AMD64_ - ++mem; // make sure data is aligned in 64 bit machines + ++mem; // make sure data is aligned in 64 bit machines #endif *mem = 0; ++mem; @@ -62,9 +62,9 @@ namespace smt { unsigned * mem = reinterpret_cast(alloc_svect(char, new_capacity + HEADER_SIZE)); unsigned curr_end_cls = end_cls_core(); #ifdef _AMD64_ - ++mem; // make sure data is aligned in 64 bit machines + ++mem; // make sure data is aligned in 64 bit machines #endif - *mem = curr_end_cls; + *mem = curr_end_cls; ++mem; SASSERT(bin_bytes <= new_capacity); unsigned new_begin_bin = new_capacity - bin_bytes; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 651e4ef14..4ad5c65f4 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -68,7 +68,7 @@ private: typedef obj_map scores_type; typedef obj_map > uplinks_type; typedef obj_map > occ_type; - obj_hashtable m_top_expr; + obj_hashtable m_top_expr; scores_type m_scores; uplinks_type m_uplinks; entry_point_type m_entry_points; @@ -85,11 +85,11 @@ private: unsigned m_touched; double m_scale_unsat; unsigned m_paws_init; - obj_map m_where_false; - expr** m_list_false; + obj_map m_where_false; + expr** m_list_false; unsigned m_track_unsat; obj_map m_weights; - double m_top_sum; + double m_top_sum; obj_hashtable m_temp_seen; public: @@ -450,7 +450,7 @@ public: m_list_false = new expr*[sz]; for (unsigned i = 0; i < sz; i++) { - if (m_mpz_manager.eq(get_value(as[i]), m_zero)) + if (m_mpz_manager.eq(get_value(as[i]), m_zero)) break_assertion(as[i]); } } @@ -462,7 +462,7 @@ public: // initialize weights if (!m_weights.contains(e)) - m_weights.insert(e, m_paws_init); + m_weights.insert(e, m_paws_init); // positive/negative occurrences used for early pruning setup_occs(as[i]); @@ -1075,7 +1075,7 @@ public: unsigned cnt_unsat = 0; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; if (pos == static_cast(-1)) return 0; } @@ -1092,7 +1092,7 @@ public: unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if ((i != m_last_pos) && m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if ((i != m_last_pos) && m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; if (pos == static_cast(-1)) return 0; diff --git a/src/test/bit_vector.cpp b/src/test/bit_vector.cpp index e920fadee..487f6cdd0 100644 --- a/src/test/bit_vector.cpp +++ b/src/test/bit_vector.cpp @@ -27,36 +27,36 @@ static void tst1() { unsigned n = rand()%10000; for (unsigned i = 0; i < n; i++) { int op = rand()%6; - if (op <= 1) { - bool val = (rand()%2) != 0; - v1.push_back(val); - v2.push_back(val); - ENSURE(v1.size() == v2.size()); - } - else if (op <= 3) { - ENSURE(v1.size() == v2.size()); - if (v1.size() > 0) { - bool val = (rand()%2) != 0; - unsigned idx = rand()%v1.size(); - ENSURE(v1.get(idx) == v2[idx]); - v1.set(idx, val); - v2[idx] = val; - ENSURE(v1.get(idx) == v2[idx]); - } - } - else if (op <= 4) { - ENSURE(v1.size() == v2.size()); - if (v1.size() > 0) { - unsigned idx = rand()%v1.size(); - VERIFY(v1.get(idx) == v2[idx]); - } - } - else if (op <= 5) { - ENSURE(v1.size() == v2.size()); - for (unsigned j = 0; j < v1.size(); j++) { - ENSURE(v1.get(j) == v2[j]); - } - } + if (op <= 1) { + bool val = (rand()%2) != 0; + v1.push_back(val); + v2.push_back(val); + ENSURE(v1.size() == v2.size()); + } + else if (op <= 3) { + ENSURE(v1.size() == v2.size()); + if (v1.size() > 0) { + bool val = (rand()%2) != 0; + unsigned idx = rand()%v1.size(); + ENSURE(v1.get(idx) == v2[idx]); + v1.set(idx, val); + v2[idx] = val; + ENSURE(v1.get(idx) == v2[idx]); + } + } + else if (op <= 4) { + ENSURE(v1.size() == v2.size()); + if (v1.size() > 0) { + unsigned idx = rand()%v1.size(); + VERIFY(v1.get(idx) == v2[idx]); + } + } + else if (op <= 5) { + ENSURE(v1.size() == v2.size()); + for (unsigned j = 0; j < v1.size(); j++) { + ENSURE(v1.get(j) == v2[j]); + } + } } } @@ -309,6 +309,6 @@ void tst_bit_vector() { tst2(); for (unsigned i = 0; i < 20; i++) { std::cerr << i << std::endl; - tst1(); + tst1(); } } diff --git a/src/test/diff_logic.cpp b/src/test/diff_logic.cpp index e79c93cf2..0564fbfbe 100644 --- a/src/test/diff_logic.cpp +++ b/src/test/diff_logic.cpp @@ -33,7 +33,7 @@ template class dl_graph; typedef dl_graph dlg; struct tst_dl_functor { - smt::literal_vector m_literals; + smt::literal_vector m_literals; void operator()(smt::literal l) { m_literals.push_back(l); } diff --git a/src/test/expr_rand.cpp b/src/test/expr_rand.cpp index 388a178f4..f1b20ba8e 100644 --- a/src/test/expr_rand.cpp +++ b/src/test/expr_rand.cpp @@ -98,8 +98,8 @@ void tst_expr_rand(char** argv, int argc, int& i) { i += 1; if (i + 1 < argc && 0 == strncmp(argv[i+1],"/rs:",3)) { rand_seed = atol(argv[i+1]+4); - std::cout << "random seed:" << rand_seed << "\n"; - i += 1; + std::cout << "random seed:" << rand_seed << "\n"; + i += 1; } if (i + 1 < argc && 0 == strcmp(argv[i+1],"/arith")) { diff --git a/src/test/main.cpp b/src/test/main.cpp index 2c51df601..d0d0aac5b 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -16,20 +16,20 @@ // and print "PASS" to indicate success. // -#define TST(MODULE) { \ - std::string s("test "); \ - s += #MODULE; \ - void tst_##MODULE(); \ +#define TST(MODULE) { \ + std::string s("test "); \ + s += #MODULE; \ + void tst_##MODULE(); \ if (do_display_usage) \ std::cout << #MODULE << "\n"; \ - for (int i = 0; i < argc; i++) \ - if (test_all || strcmp(argv[i], #MODULE) == 0) { \ + for (int i = 0; i < argc; i++) \ + if (test_all || strcmp(argv[i], #MODULE) == 0) { \ enable_trace(#MODULE); \ - enable_debug(#MODULE); \ - timeit timeit(true, s.c_str()); \ - tst_##MODULE(); \ + enable_debug(#MODULE); \ + timeit timeit(true, s.c_str()); \ + tst_##MODULE(); \ std::cout << "PASS" << std::endl; \ - } \ + } \ } #define TST_ARGV(MODULE) { \ @@ -39,13 +39,13 @@ if (do_display_usage) \ std::cout << #MODULE << "\n"; \ for (int i = 0; i < argc; i++) \ - if (strcmp(argv[i], #MODULE) == 0) { \ + if (strcmp(argv[i], #MODULE) == 0) { \ enable_trace(#MODULE); \ - enable_debug(#MODULE); \ - timeit timeit(true, s.c_str()); \ - tst_##MODULE(argv, argc, i); \ + enable_debug(#MODULE); \ + timeit timeit(true, s.c_str()); \ + tst_##MODULE(argv, argc, i); \ std::cout << "PASS" << std::endl; \ - } \ + } \ } void error(const char * msg) { @@ -76,49 +76,49 @@ void display_usage() { void parse_cmd_line_args(int argc, char ** argv, bool& do_display_usage, bool& test_all) { int i = 1; while (i < argc) { - char * arg = argv[i], *eq_pos = 0; + char * arg = argv[i], *eq_pos = 0; - if (arg[0] == '-' || arg[0] == '/') { - char * opt_name = arg + 1; - char * opt_arg = 0; - char * colon = strchr(arg, ':'); - if (colon) { - opt_arg = colon + 1; - *colon = 0; - } - if (strcmp(opt_name, "h") == 0 || + if (arg[0] == '-' || arg[0] == '/') { + char * opt_name = arg + 1; + char * opt_arg = 0; + char * colon = strchr(arg, ':'); + if (colon) { + opt_arg = colon + 1; + *colon = 0; + } + if (strcmp(opt_name, "h") == 0 || strcmp(opt_name, "?") == 0) { - display_usage(); + display_usage(); do_display_usage = true; return; - } - else if (strcmp(opt_name, "v") == 0) { - if (!opt_arg) - error("option argument (/v:level) is missing."); - long lvl = strtol(opt_arg, 0, 10); - set_verbosity_level(lvl); - } - else if (strcmp(opt_name, "w") == 0) { + } + else if (strcmp(opt_name, "v") == 0) { + if (!opt_arg) + error("option argument (/v:level) is missing."); + long lvl = strtol(opt_arg, 0, 10); + set_verbosity_level(lvl); + } + else if (strcmp(opt_name, "w") == 0) { enable_warning_messages(true); - } - else if (strcmp(opt_name, "a") == 0) { + } + else if (strcmp(opt_name, "a") == 0) { test_all = true; - } + } #ifdef _TRACE - else if (strcmp(opt_name, "tr") == 0) { - if (!opt_arg) - error("option argument (/tr:tag) is missing."); - enable_trace(opt_arg); - } + else if (strcmp(opt_name, "tr") == 0) { + if (!opt_arg) + error("option argument (/tr:tag) is missing."); + enable_trace(opt_arg); + } #endif #ifdef Z3DEBUG - else if (strcmp(opt_name, "dbg") == 0) { - if (!opt_arg) - error("option argument (/dbg:tag) is missing."); - enable_debug(opt_arg); - } + else if (strcmp(opt_name, "dbg") == 0) { + if (!opt_arg) + error("option argument (/dbg:tag) is missing."); + enable_debug(opt_arg); + } #endif - } + } else if (arg[0] != '"' && (eq_pos = strchr(arg, '='))) { char * key = arg; *eq_pos = 0; @@ -130,7 +130,7 @@ void parse_cmd_line_args(int argc, char ** argv, bool& do_display_usage, bool& t std::cerr << ex.msg() << "\n"; } } - i++; + i++; } } diff --git a/src/test/model_based_opt.cpp b/src/test/model_based_opt.cpp index 2f8cf9941..7b3b95afd 100644 --- a/src/test/model_based_opt.cpp +++ b/src/test/model_based_opt.cpp @@ -54,7 +54,7 @@ static void add_random_ineq(opt::model_based_opt& mbo, continue; } unsigned sign = r(2); - coeff = sign == 0 ? coeff : -coeff; + coeff = sign == 0 ? coeff : -coeff; vars.push_back(var(x, rational(coeff))); value += coeff*values[x]; } diff --git a/src/test/optional.cpp b/src/test/optional.cpp index 2ef922444..d698f7289 100644 --- a/src/test/optional.cpp +++ b/src/test/optional.cpp @@ -36,11 +36,11 @@ struct OptFoo { int m_y; OptFoo(int x, int y):m_x(x), m_y(y) { - TRACE("optional", tout << "OptFoo created: " << m_x << " : " << m_y << "\n";); + TRACE("optional", tout << "OptFoo created: " << m_x << " : " << m_y << "\n";); } ~OptFoo() { - TRACE("optional", tout << "OptFoo deleted: " << m_x << " : " << m_y << "\n";); + TRACE("optional", tout << "OptFoo deleted: " << m_x << " : " << m_y << "\n";); } }; diff --git a/src/util/dependency.h b/src/util/dependency.h index d6df6d7bf..5055399bc 100644 --- a/src/util/dependency.h +++ b/src/util/dependency.h @@ -201,7 +201,7 @@ public: m_todo.push_back(d); unsigned qhead = 0; while (qhead < m_todo.size()) { - d = m_todo[qhead]; + d = m_todo[qhead]; qhead++; if (d->is_leaf()) { vs.push_back(to_leaf(d)->m_value); diff --git a/src/util/hash.h b/src/util/hash.h index 7fce04ca8..bc6117cac 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -236,7 +236,7 @@ template struct ptr_hash { typedef T * data; unsigned operator()(T * ptr) const { - return get_ptr_hash(ptr); + return get_ptr_hash(ptr); } }; diff --git a/src/util/inf_eps_rational.h b/src/util/inf_eps_rational.h index 72212d33c..c184623ca 100644 --- a/src/util/inf_eps_rational.h +++ b/src/util/inf_eps_rational.h @@ -119,12 +119,12 @@ class inf_eps_rational { bool is_rational() const { return m_infty.is_zero() && m_r.is_rational(); } int64 get_int64() const { - SASSERT(is_int64()); + SASSERT(is_int64()); return m_r.get_int64(); } uint64 get_uint64() const { - SASSERT(is_uint64()); + SASSERT(is_uint64()); return m_r.get_uint64(); } @@ -168,45 +168,45 @@ class inf_eps_rational { inf_eps_rational & operator=(const inf_eps_rational & r) { m_infty = r.m_infty; m_r = r.m_r; - return *this; + return *this; } inf_eps_rational & operator=(const Numeral & r) { m_infty.reset(); m_r = r; - return *this; + return *this; } inf_eps_rational & operator+=(const inf_eps_rational & r) { m_infty += r.m_infty; m_r += r.m_r; - return *this; + return *this; } inf_eps_rational & operator-=(const inf_eps_rational & r) { m_infty -= r.m_infty; m_r -= r.m_r; - return *this; + return *this; } inf_eps_rational & operator-=(const inf_rational & r) { m_r -= r; - return *this; + return *this; } inf_eps_rational & operator+=(const inf_rational & r) { m_r += r; - return *this; + return *this; } inf_eps_rational & operator+=(const rational & r) { m_r += r; - return *this; + return *this; } inf_eps_rational & operator-=(const rational & r) { m_r -= r; - return *this; + return *this; } inf_eps_rational & operator*=(const rational & r1) { diff --git a/src/util/inf_int_rational.h b/src/util/inf_int_rational.h index ce871b0d5..c9c82052e 100644 --- a/src/util/inf_int_rational.h +++ b/src/util/inf_int_rational.h @@ -110,12 +110,12 @@ class inf_int_rational { bool is_rational() const { return m_second == 0; } int64 get_int64() const { - SASSERT(is_int64()); + SASSERT(is_int64()); return m_first.get_int64(); } uint64 get_uint64() const { - SASSERT(is_uint64()); + SASSERT(is_uint64()); return m_first.get_uint64(); } @@ -132,7 +132,7 @@ class inf_int_rational { inf_int_rational & operator=(const inf_int_rational & r) { m_first = r.m_first; m_second = r.m_second; - return *this; + return *this; } inf_int_rational & operator=(const rational & r) { @@ -154,7 +154,7 @@ class inf_int_rational { inf_int_rational & operator+=(const inf_int_rational & r) { m_first += r.m_first; m_second += r.m_second; - return *this; + return *this; } inf_int_rational & operator*=(const rational & r) { @@ -163,7 +163,7 @@ class inf_int_rational { } m_first *= r; m_second *= r.get_int32(); - return *this; + return *this; } @@ -171,17 +171,17 @@ class inf_int_rational { inf_int_rational & operator-=(const inf_int_rational & r) { m_first -= r.m_first; m_second -= r.m_second; - return *this; + return *this; } inf_int_rational & operator+=(const rational & r) { m_first += r; - return *this; + return *this; } inf_int_rational & operator-=(const rational & r) { m_first -= r; - return *this; + return *this; } inf_int_rational & operator++() { diff --git a/src/util/inf_rational.h b/src/util/inf_rational.h index c17c4312b..d49e45f50 100644 --- a/src/util/inf_rational.h +++ b/src/util/inf_rational.h @@ -123,12 +123,12 @@ class inf_rational { bool is_rational() const { return m_second.is_zero(); } int64 get_int64() const { - SASSERT(is_int64()); + SASSERT(is_int64()); return m_first.get_int64(); } uint64 get_uint64() const { - SASSERT(is_uint64()); + SASSERT(is_uint64()); return m_first.get_uint64(); } @@ -145,7 +145,7 @@ class inf_rational { inf_rational & operator=(const inf_rational & r) { m_first = r.m_first; m_second = r.m_second; - return *this; + return *this; } inf_rational & operator=(const rational & r) { @@ -167,23 +167,23 @@ class inf_rational { inf_rational & operator+=(const inf_rational & r) { m_first += r.m_first; m_second += r.m_second; - return *this; + return *this; } inf_rational & operator-=(const inf_rational & r) { m_first -= r.m_first; m_second -= r.m_second; - return *this; + return *this; } inf_rational & operator+=(const rational & r) { m_first += r; - return *this; + return *this; } inf_rational & operator-=(const rational & r) { m_first -= r; - return *this; + return *this; } inf_rational & operator*=(const rational & r1) { diff --git a/src/util/inf_s_integer.h b/src/util/inf_s_integer.h index 6cf1d4225..067000202 100644 --- a/src/util/inf_s_integer.h +++ b/src/util/inf_s_integer.h @@ -67,7 +67,7 @@ class inf_s_integer { inf_s_integer & operator=(const inf_s_integer & r) { m_first = r.m_first; m_second = r.m_second; - return *this; + return *this; } inf_s_integer & operator=(const rational & r) { m_first = static_cast(r.get_int64()); @@ -90,20 +90,20 @@ class inf_s_integer { inf_s_integer & operator+=(const inf_s_integer & r) { m_first += r.m_first; m_second += r.m_second; - return *this; + return *this; } inf_s_integer & operator-=(const inf_s_integer & r) { m_first -= r.m_first; m_second -= r.m_second; - return *this; + return *this; } inf_s_integer & operator+=(const s_integer & r) { m_first += r.get_int(); - return *this; + return *this; } inf_s_integer & operator-=(const s_integer & r) { m_first -= r.get_int(); - return *this; + return *this; } inf_s_integer & operator*=(const s_integer & r1) { m_first *= r1.get_int(); diff --git a/src/util/lp/bound_analyzer_on_row.h b/src/util/lp/bound_analyzer_on_row.h index 4c6c43464..914835a3c 100644 --- a/src/util/lp/bound_analyzer_on_row.h +++ b/src/util/lp/bound_analyzer_on_row.h @@ -114,22 +114,22 @@ public : } return a * lb(j).x; } - mpq monoid_max(const mpq & a, unsigned j, bool & strict) const { - if (is_pos(a)) { - strict = !is_zero(ub(j).y); - return a * ub(j).x; - } - strict = !is_zero(lb(j).y); - return a * lb(j).x; - } - const mpq & monoid_min_no_mult(bool a_is_pos, unsigned j, bool & strict) const { - if (!a_is_pos) { - strict = !is_zero(ub(j).y); - return ub(j).x; - } - strict = !is_zero(lb(j).y); - return lb(j).x; - } + mpq monoid_max(const mpq & a, unsigned j, bool & strict) const { + if (is_pos(a)) { + strict = !is_zero(ub(j).y); + return a * ub(j).x; + } + strict = !is_zero(lb(j).y); + return a * lb(j).x; + } + const mpq & monoid_min_no_mult(bool a_is_pos, unsigned j, bool & strict) const { + if (!a_is_pos) { + strict = !is_zero(ub(j).y); + return ub(j).x; + } + strict = !is_zero(lb(j).y); + return lb(j).x; + } mpq monoid_min(const mpq & a, unsigned j, bool& strict) const { if (is_neg(a)) { @@ -166,7 +166,7 @@ public : m_it.reset(); while (m_it.next(a, j)) { bool str; - bool a_is_pos = is_pos(a); + bool a_is_pos = is_pos(a); mpq bound = total / a + monoid_min_no_mult(a_is_pos, j, str); if (a_is_pos) { limit_j(j, bound, true, false, strict - static_cast(str) > 0); @@ -192,8 +192,8 @@ public : m_it.reset(); while (m_it.next(a, j)) { bool str; - bool a_is_pos = is_pos(a); - mpq bound = total / a + monoid_max_no_mult(a_is_pos, j, str); + bool a_is_pos = is_pos(a); + mpq bound = total / a + monoid_max_no_mult(a_is_pos, j, str); bool astrict = strict - static_cast(str) > 0; if (a_is_pos) { limit_j(j, bound, true, true, astrict); diff --git a/src/util/lp/init_lar_solver.h b/src/util/lp/init_lar_solver.h index 3fc29f25b..db5a6ed4c 100644 --- a/src/util/lp/init_lar_solver.h +++ b/src/util/lp/init_lar_solver.h @@ -123,7 +123,7 @@ void add_row_for_term(const lar_term * term, unsigned term_ext_index) { void add_row_from_term_no_constraint(const lar_term * term, unsigned term_ext_index) { register_new_ext_var_index(term_ext_index); // j will be a new variable - unsigned j = A_r().column_count(); + unsigned j = A_r().column_count(); ul_pair ul(j); m_vars_to_ul_pairs.push_back(ul); add_basic_var_to_core_fields(); @@ -152,7 +152,7 @@ void add_basic_var_to_core_fields() { } constraint_index add_var_bound(var_index j, lconstraint_kind kind, const mpq & right_side) { - constraint_index ci = m_constraints.size(); + constraint_index ci = m_constraints.size(); if (!is_term(j)) { // j is a var auto vc = new lar_var_constraint(j, kind, right_side); m_constraints.push_back(vc); @@ -212,8 +212,8 @@ void add_constraint_from_term_and_create_new_column_row(unsigned term_j, const l } void decide_on_strategy_and_adjust_initial_state() { - lean_assert(strategy_is_undecided()); - if (m_vars_to_ul_pairs.size() > m_settings.column_number_threshold_for_using_lu_in_lar_solver) { + lean_assert(strategy_is_undecided()); + if (m_vars_to_ul_pairs.size() > m_settings.column_number_threshold_for_using_lu_in_lar_solver) { m_settings.simplex_strategy() = simplex_strategy_enum::lu; } else { m_settings.simplex_strategy() = simplex_strategy_enum::tableau_rows; // todo: when to switch to tableau_costs? @@ -239,14 +239,14 @@ void adjust_initial_state() { void adjust_initial_state_for_lu() { copy_from_mpq_matrix(A_d()); - unsigned n = A_d().column_count(); - m_mpq_lar_core_solver.m_d_x.resize(n); - m_mpq_lar_core_solver.m_d_low_bounds.resize(n); - m_mpq_lar_core_solver.m_d_upper_bounds.resize(n); - m_mpq_lar_core_solver.m_d_heading = m_mpq_lar_core_solver.m_r_heading; - m_mpq_lar_core_solver.m_d_basis = m_mpq_lar_core_solver.m_r_basis; + unsigned n = A_d().column_count(); + m_mpq_lar_core_solver.m_d_x.resize(n); + m_mpq_lar_core_solver.m_d_low_bounds.resize(n); + m_mpq_lar_core_solver.m_d_upper_bounds.resize(n); + m_mpq_lar_core_solver.m_d_heading = m_mpq_lar_core_solver.m_r_heading; + m_mpq_lar_core_solver.m_d_basis = m_mpq_lar_core_solver.m_r_basis; - /* + /* unsigned j = A_d().column_count(); A_d().add_column(); lean_assert(m_mpq_lar_core_solver.m_d_x.size() == j); diff --git a/src/util/lp/lar_core_solver.h b/src/util/lp/lar_core_solver.h index 71d69c3a4..7e402d726 100644 --- a/src/util/lp/lar_core_solver.h +++ b/src/util/lp/lar_core_solver.h @@ -550,7 +550,7 @@ public: lean_assert(m_r_solver.m_basis_heading[leaving] >= 0); m_r_solver.change_basis_unconditionally(entering, leaving); if(!m_r_solver.pivot_column_tableau(entering, m_r_solver.m_basis_heading[entering])) { - // unroll the last step + // unroll the last step m_r_solver.change_basis_unconditionally(leaving, entering); #ifdef LEAN_DEBUG bool t = diff --git a/src/util/lp/lar_solver.h b/src/util/lp/lar_solver.h index c8048a550..d4b591154 100644 --- a/src/util/lp/lar_solver.h +++ b/src/util/lp/lar_solver.h @@ -380,8 +380,8 @@ public: bool term_is_used_as_row(unsigned term) const { - lean_assert(is_term(term)); - return contains(m_ext_vars_to_columns, term); + lean_assert(is_term(term)); + return contains(m_ext_vars_to_columns, term); } void propagate_bounds_on_terms(lp_bound_propagator & bp) { @@ -484,16 +484,16 @@ public: void pop(unsigned k) { int n_was = static_cast(m_ext_vars_to_columns.size()); - m_status.pop(k); - m_infeasible_column_index.pop(k); + m_status.pop(k); + m_infeasible_column_index.pop(k); unsigned n = m_vars_to_ul_pairs.peek_size(k); - for (unsigned j = n_was; j-- > n;) - m_ext_vars_to_columns.erase(m_columns_to_ext_vars_or_term_indices[j]); - m_columns_to_ext_vars_or_term_indices.resize(n); - if (m_settings.use_tableau()) { + for (unsigned j = n_was; j-- > n;) + m_ext_vars_to_columns.erase(m_columns_to_ext_vars_or_term_indices[j]); + m_columns_to_ext_vars_or_term_indices.resize(n); + if (m_settings.use_tableau()) { pop_tableau(); } - m_vars_to_ul_pairs.pop(k); + m_vars_to_ul_pairs.pop(k); m_mpq_lar_core_solver.pop(k); clean_large_elements_after_pop(n, m_columns_with_changed_bound); @@ -501,7 +501,7 @@ public: clean_large_elements_after_pop(m, m_rows_with_changed_bounds); clean_inf_set_of_r_solver_after_pop(); lean_assert(m_settings.simplex_strategy() == simplex_strategy_enum::undecided || - (!use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); + (!use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); lean_assert(ax_is_correct()); @@ -518,9 +518,9 @@ public: } m_terms.resize(m_term_count); m_orig_terms.resize(m_term_count); - m_simplex_strategy.pop(k); - m_settings.simplex_strategy() = m_simplex_strategy; - lean_assert(sizes_are_correct()); + m_simplex_strategy.pop(k); + m_settings.simplex_strategy() = m_simplex_strategy; + lean_assert(sizes_are_correct()); lean_assert((!m_settings.use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); } @@ -967,8 +967,8 @@ public: template void copy_from_mpq_matrix(static_matrix & matr) { - matr.m_rows.resize(A_r().row_count()); - matr.m_columns.resize(A_r().column_count()); + matr.m_rows.resize(A_r().row_count()); + matr.m_columns.resize(A_r().column_count()); for (unsigned i = 0; i < matr.row_count(); i++) { for (auto & it : A_r().m_rows[i]) { matr.set(i, it.m_j, convert_struct::convert(it.get_val())); diff --git a/src/util/lp/lp_bound_propagator.cpp b/src/util/lp/lp_bound_propagator.cpp index 8b42f24a0..506ba138b 100644 --- a/src/util/lp/lp_bound_propagator.cpp +++ b/src/util/lp/lp_bound_propagator.cpp @@ -17,11 +17,11 @@ const impq & lp_bound_propagator::get_upper_bound(unsigned j) const { } void lp_bound_propagator::try_add_bound(const mpq & v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict) { unsigned term_j = m_lar_solver.adjust_column_index_to_term_index(j); - mpq w = v; - if (term_j != j) { - j = term_j; - w += m_lar_solver.get_term(term_j).m_v; // when terms are turned into the columns they "lose" the right side, at this moment they aquire it back - } + mpq w = v; + if (term_j != j) { + j = term_j; + w += m_lar_solver.get_term(term_j).m_v; // when terms are turned into the columns they "lose" the right side, at this moment they aquire it back + } lconstraint_kind kind = is_low? GE : LE; if (strict) kind = static_cast(kind / 2); diff --git a/src/util/lp/lp_settings.h b/src/util/lp/lp_settings.h index aac3692f9..ad40ad69d 100644 --- a/src/util/lp/lp_settings.h +++ b/src/util/lp/lp_settings.h @@ -278,13 +278,13 @@ public: return m_simplex_strategy; } - bool use_lu() const { - return m_simplex_strategy == simplex_strategy_enum::lu; - } + bool use_lu() const { + return m_simplex_strategy == simplex_strategy_enum::lu; + } bool use_tableau() const { - return m_simplex_strategy == simplex_strategy_enum::tableau_rows || - m_simplex_strategy == simplex_strategy_enum::tableau_costs; + return m_simplex_strategy == simplex_strategy_enum::tableau_rows || + m_simplex_strategy == simplex_strategy_enum::tableau_costs; } bool use_tableau_rows() const { diff --git a/src/util/lp/lp_utils.h b/src/util/lp/lp_utils.h index 2be15d79a..34cf4f6b9 100644 --- a/src/util/lp/lp_utils.h +++ b/src/util/lp/lp_utils.h @@ -18,7 +18,7 @@ bool try_get_val(const std::unordered_map & map, const A& key, B & val) { template bool contains(const std::unordered_map & map, const A& key) { - return map.find(key) != map.end(); + return map.find(key) != map.end(); } #ifdef lp_for_z3 diff --git a/src/util/lp/stacked_vector.h b/src/util/lp/stacked_vector.h index 3f39dd346..21202b7b8 100644 --- a/src/util/lp/stacked_vector.h +++ b/src/util/lp/stacked_vector.h @@ -51,10 +51,10 @@ public: private: void emplace_replace(unsigned i,const B & b) { - if (m_vector[i] != b) { - m_changes.push_back(std::make_pair(i, m_vector[i])); - m_vector[i] = b; - } + if (m_vector[i] != b) { + m_changes.push_back(std::make_pair(i, m_vector[i])); + m_vector[i] = b; + } } public: @@ -87,14 +87,14 @@ public: } template - void pop_tail(vector & v, unsigned k) { - lean_assert(v.size() >= k); - v.resize(v.size() - k); - } + void pop_tail(vector & v, unsigned k) { + lean_assert(v.size() >= k); + v.resize(v.size() - k); + } template void resize(vector & v, unsigned new_size) { - v.resize(new_size); + v.resize(new_size); } void pop(unsigned k) { @@ -156,10 +156,10 @@ public: m_vector.resize(m_vector.size() + 1); } - unsigned peek_size(unsigned k) const { - lean_assert(k > 0 && k <= m_stack_of_vector_sizes.size()); - return m_stack_of_vector_sizes[m_stack_of_vector_sizes.size() - k]; - } + unsigned peek_size(unsigned k) const { + lean_assert(k > 0 && k <= m_stack_of_vector_sizes.size()); + return m_stack_of_vector_sizes[m_stack_of_vector_sizes.size() - k]; + } const vector& operator()() const { return m_vector; } }; diff --git a/src/util/lp/static_matrix.h b/src/util/lp/static_matrix.h index 5ef4b449f..d027c105f 100644 --- a/src/util/lp/static_matrix.h +++ b/src/util/lp/static_matrix.h @@ -47,7 +47,7 @@ class static_matrix dim(unsigned m, unsigned n) :m_m(m), m_n(n) {} }; std::stack m_stack; - vector m_became_zeros; // the row indices that became zeroes during the pivoting + vector m_became_zeros; // the row indices that became zeroes during the pivoting public: typedef vector> row_strip; typedef vector column_strip; diff --git a/src/util/lp/ul_pair.h b/src/util/lp/ul_pair.h index 2e77a7db0..6331d17b5 100644 --- a/src/util/lp/ul_pair.h +++ b/src/util/lp/ul_pair.h @@ -49,8 +49,8 @@ public: && m_upper_bound_witness == p.m_upper_bound_witness && m_i == p.m_i; } - // empty constructor - ul_pair() : + // empty constructor + ul_pair() : m_low_bound_witness(static_cast(-1)), m_upper_bound_witness(static_cast(-1)), m_i(static_cast(-1)) diff --git a/src/util/map.h b/src/util/map.h index 0d2acf11b..3a59c8975 100644 --- a/src/util/map.h +++ b/src/util/map.h @@ -135,7 +135,7 @@ public: value const& get(key const& k, value const& default_value) const { entry* e = find_core(k); if (e) { - return e->get_data().m_value; + return e->get_data().m_value; } else { return default_value; diff --git a/src/util/max_cliques.h b/src/util/max_cliques.h index 09e40dee1..340d3fee7 100644 --- a/src/util/max_cliques.h +++ b/src/util/max_cliques.h @@ -92,7 +92,7 @@ public: m_next.reserve(std::max(src, dst) + 1); m_next.reserve(std::max(negate(src), negate(dst)) + 1); m_next[src].push_back(dst); - m_next[dst].push_back(src); + m_next[dst].push_back(src); } void cliques(unsigned_vector const& ps, vector& cliques) { @@ -104,7 +104,7 @@ public: max = std::max(max, std::max(np, p) + 1); } m_next.reserve(max); - m_tc.reserve(m_next.size()); + m_tc.reserve(m_next.size()); unsigned_vector clique; uint_set vars; for (unsigned i = 0; i < num_ps; ++i) { diff --git a/src/util/rational.h b/src/util/rational.h index ca294e234..803c562ad 100644 --- a/src/util/rational.h +++ b/src/util/rational.h @@ -422,7 +422,7 @@ inline bool operator>(rational const & r1, rational const & r2) { } inline bool operator<(rational const & r1, int r2) { - return r1 < rational(r2); + return r1 < rational(r2); } inline bool operator<=(rational const & r1, rational const & r2) { @@ -450,11 +450,11 @@ inline rational operator+(rational const & r1, rational const & r2) { } inline rational operator+(int r1, rational const & r2) { - return rational(r1) + r2; + return rational(r1) + r2; } inline rational operator+(rational const & r1, int r2) { - return r1 + rational(r2); + return r1 + rational(r2); } @@ -463,11 +463,11 @@ inline rational operator-(rational const & r1, rational const & r2) { } inline rational operator-(rational const & r1, int r2) { - return r1 - rational(r2); + return r1 - rational(r2); } inline rational operator-(int r1, rational const & r2) { - return rational(r1) - r2; + return rational(r1) - r2; } inline rational operator-(rational const & r) { @@ -492,11 +492,11 @@ inline rational operator/(rational const & r1, rational const & r2) { } inline rational operator/(rational const & r1, int r2) { - return r1 / rational(r2); + return r1 / rational(r2); } -inline rational operator/(int r1, rational const & r2) { - return rational(r1) / r2; +inline rational operator/(int r1, rational const & r2) { + return rational(r1) / r2; } inline rational power(rational const & r, unsigned p) { diff --git a/src/util/stopwatch.h b/src/util/stopwatch.h index 7a9066030..7f2ed3245 100644 --- a/src/util/stopwatch.h +++ b/src/util/stopwatch.h @@ -110,7 +110,7 @@ public: mach_timespec_t _stop; clock_get_time(m_host_clock, &_stop); m_time += (_stop.tv_sec - m_start.tv_sec) * 1000000000ull; - m_time += (_stop.tv_nsec - m_start.tv_nsec); + m_time += (_stop.tv_nsec - m_start.tv_nsec); m_running = false; } } @@ -163,8 +163,8 @@ public: struct timespec _stop; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &_stop); m_time += (_stop.tv_sec - m_start.tv_sec) * 1000000000ull; - if (m_time != 0 || _stop.tv_nsec >= m_start.tv_nsec) - m_time += (_stop.tv_nsec - m_start.tv_nsec); + if (m_time != 0 || _stop.tv_nsec >= m_start.tv_nsec) + m_time += (_stop.tv_nsec - m_start.tv_nsec); m_running = false; } } diff --git a/src/util/util.h b/src/util/util.h index 440877619..23c2c1657 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -153,13 +153,13 @@ template char (*ArraySizer(T (&)[N]))[N]; template void display(std::ostream & out, const IT & begin, const IT & end, const char * sep, bool & first) { for(IT it = begin; it != end; ++it) { - if (first) { - first = false; - } - else { - out << sep; - } - out << *it; + if (first) { + first = false; + } + else { + out << sep; + } + out << *it; } } @@ -172,9 +172,9 @@ void display(std::ostream & out, const IT & begin, const IT & end, const char * template struct delete_proc { void operator()(T * ptr) { - if (ptr) { - dealloc(ptr); - } + if (ptr) { + dealloc(ptr); + } } }; From d61b722b68e5260f5a37c5dcb788fc2abe972d74 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 16:00:06 +0100 Subject: [PATCH 294/488] Partial cleanup of util/lp/* --- src/shell/lp_frontend.cpp | 22 +- src/smt/theory_lra.cpp | 318 +++++++++--------- src/util/lp/binary_heap_priority_queue.h | 31 +- src/util/lp/binary_heap_priority_queue.hpp | 48 ++- .../binary_heap_priority_queue_instances.cpp | 29 +- src/util/lp/binary_heap_upair_queue.h | 27 +- src/util/lp/binary_heap_upair_queue.hpp | 33 +- .../lp/binary_heap_upair_queue_instances.cpp | 25 +- src/util/lp/bound_analyzer_on_row.h | 35 +- src/util/lp/breakpoint.h | 25 +- src/util/lp/column_info.h | 31 +- src/util/lp/column_namer.h | 25 +- src/util/lp/conversion_helper.h | 2 +- src/util/lp/core_solver_pretty_printer.h | 25 +- src/util/lp/core_solver_pretty_printer.hpp | 31 +- .../core_solver_pretty_printer_instances.cpp | 41 ++- src/util/lp/dense_matrix.h | 29 +- src/util/lp/dense_matrix.hpp | 29 +- src/util/lp/dense_matrix_instances.cpp | 57 ++-- src/util/lp/eta_matrix.h | 35 +- src/util/lp/eta_matrix.hpp | 47 ++- src/util/lp/eta_matrix_instances.cpp | 61 ++-- src/util/lp/hash_helper.h | 27 +- src/util/lp/implied_bound.h | 25 +- src/util/lp/indexed_value.h | 27 +- src/util/lp/indexed_vector.h | 29 +- src/util/lp/indexed_vector.hpp | 31 +- src/util/lp/indexed_vector_instances.cpp | 51 ++- src/util/lp/init_lar_solver.h | 109 +++--- src/util/lp/int_set.h | 27 +- src/util/lp/iterator_on_column.h | 25 +- src/util/lp/iterator_on_indexed_vector.h | 25 +- src/util/lp/iterator_on_pivot_row.h | 25 +- src/util/lp/iterator_on_row.h | 25 +- src/util/lp/iterator_on_term_with_basis_var.h | 25 +- src/util/lp/lar_constraints.h | 29 +- src/util/lp/lar_core_solver.h | 113 ++++--- src/util/lp/lar_core_solver.hpp | 86 +++-- src/util/lp/lar_core_solver_instances.cpp | 23 +- src/util/lp/lar_solution_signature.h | 25 +- src/util/lp/lar_solver.h | 213 ++++++------ src/util/lp/lar_term.h | 25 +- src/util/lp/linear_combination_iterator.h | 25 +- src/util/lp/lp_bound_propagator.cpp | 25 +- src/util/lp/lp_bound_propagator.h | 27 +- src/util/lp/lp_core_solver_base.h | 53 +-- src/util/lp/lp_core_solver_base.hpp | 93 ++--- src/util/lp/lp_core_solver_base_instances.cpp | 245 +++++++------- src/util/lp/lp_dual_core_solver.h | 25 +- src/util/lp/lp_dual_core_solver.hpp | 85 +++-- src/util/lp/lp_dual_core_solver_instances.cpp | 45 ++- src/util/lp/lp_dual_simplex.h | 25 +- src/util/lp/lp_dual_simplex.hpp | 53 +-- src/util/lp/lp_dual_simplex_instances.cpp | 31 +- src/util/lp/lp_primal_core_solver.h | 105 +++--- src/util/lp/lp_primal_core_solver.hpp | 157 +++++---- .../lp/lp_primal_core_solver_instances.cpp | 37 +- ...au.hpp => lp_primal_core_solver_tableau.h} | 75 +++-- src/util/lp/lp_primal_simplex.h | 25 +- src/util/lp/lp_primal_simplex.hpp | 45 ++- src/util/lp/lp_primal_simplex_instances.cpp | 43 ++- src/util/lp/lp_settings.h | 31 +- src/util/lp/lp_settings.hpp | 33 +- src/util/lp/lp_settings_instances.cpp | 27 +- src/util/lp/lp_solver.h | 25 +- src/util/lp/lp_solver.hpp | 53 +-- src/util/lp/lp_solver_instances.cpp | 91 ++--- src/util/lp/lp_utils.cpp | 29 +- src/util/lp/lp_utils.h | 99 ++---- src/util/lp/lu.h | 53 +-- src/util/lp/lu.hpp | 137 ++++---- src/util/lp/lu_instances.cpp | 123 ++++--- src/util/lp/matrix.h | 25 +- src/util/lp/matrix.hpp | 25 +- src/util/lp/matrix_instances.cpp | 37 +- src/util/lp/mps_reader.h | 41 ++- src/util/lp/numeric_pair.h | 80 ++--- src/util/lp/permutation_matrix.h | 33 +- src/util/lp/permutation_matrix.hpp | 83 +++-- src/util/lp/permutation_matrix_instances.cpp | 115 ++++--- src/util/lp/quick_xplain.cpp | 47 ++- src/util/lp/quick_xplain.h | 2 +- src/util/lp/random_updater.h | 2 +- src/util/lp/random_updater.hpp | 61 ++-- src/util/lp/random_updater_instances.cpp | 23 +- src/util/lp/row_eta_matrix.h | 35 +- src/util/lp/row_eta_matrix.hpp | 57 ++-- src/util/lp/row_eta_matrix_instances.cpp | 27 +- src/util/lp/scaler.h | 27 +- src/util/lp/scaler.hpp | 31 +- src/util/lp/scaler_instances.cpp | 27 +- src/util/lp/signature_bound_evidence.h | 25 +- src/util/lp/sparse_matrix.h | 51 ++- src/util/lp/sparse_matrix.hpp | 135 ++++---- src/util/lp/sparse_matrix_instances.cpp | 77 +++-- src/util/lp/sparse_vector.h | 29 +- src/util/lp/square_dense_submatrix.h | 45 ++- src/util/lp/square_dense_submatrix.hpp | 71 ++-- .../lp/square_dense_submatrix_instances.cpp | 71 ++-- src/util/lp/stacked_map.h | 37 +- src/util/lp/stacked_unordered_set.h | 27 +- src/util/lp/stacked_value.h | 25 +- src/util/lp/stacked_vector.h | 22 +- src/util/lp/static_matrix.h | 57 ++-- src/util/lp/static_matrix.hpp | 63 ++-- src/util/lp/static_matrix_instances.cpp | 41 ++- src/util/lp/tail_matrix.h | 27 +- src/util/lp/test_bound_analyzer.h | 29 +- src/util/lp/ul_pair.h | 25 +- 109 files changed, 3503 insertions(+), 2023 deletions(-) rename src/util/lp/{lp_primal_core_solver_tableau.hpp => lp_primal_core_solver_tableau.h} (90%) diff --git a/src/shell/lp_frontend.cpp b/src/shell/lp_frontend.cpp index 61015c860..95f9e1eb3 100644 --- a/src/shell/lp_frontend.cpp +++ b/src/shell/lp_frontend.cpp @@ -1,7 +1,7 @@ /*++ Copyright (c) 2016 Microsoft Corporation -Author: +Author: Lev Nachmanson 2016-10-27 @@ -17,7 +17,7 @@ Author: #include "util/gparams.h" #include -static lean::lp_solver* g_solver = 0; +static lp::lp_solver* g_solver = 0; static void display_statistics() { if (g_solver && g_solver->settings().print_statistics) { @@ -42,7 +42,7 @@ static void on_timeout() { } } -struct front_end_resource_limit : public lean::lp_resource_limit { +struct front_end_resource_limit : public lp::lp_resource_limit { reslimit& m_reslim; front_end_resource_limit(reslimit& lim): @@ -54,7 +54,7 @@ struct front_end_resource_limit : public lean::lp_resource_limit { void run_solver(lp_params & params, char const * mps_file_name) { - reslimit rlim; + reslimit rlim; unsigned timeout = gparams::get().get_uint("timeout", 0); unsigned rlimit = gparams::get().get_uint("rlimit", 0); front_end_resource_limit lp_limit(rlim); @@ -64,14 +64,14 @@ void run_solver(lp_params & params, char const * mps_file_name) { scoped_timer timer(timeout, &eh); std::string fn(mps_file_name); - lean::mps_reader reader(fn); + lp::mps_reader reader(fn); reader.set_message_stream(&std::cout); // can be redirected reader.read(); if (!reader.is_ok()) { std::cerr << "cannot process " << mps_file_name << std::endl; return; } - lean::lp_solver * solver = reader.create_solver(false); // false - to create the primal solver + lp::lp_solver * solver = reader.create_solver(false); // false - to create the primal solver solver->settings().set_resource_limit(lp_limit); g_solver = solver; if (params.min()) { @@ -80,20 +80,20 @@ void run_solver(lp_params & params, char const * mps_file_name) { solver->settings().set_message_ostream(&std::cout); solver->settings().report_frequency = params.rep_freq(); solver->settings().print_statistics = params.print_stats(); - solver->settings().simplex_strategy() = lean:: simplex_strategy_enum::lu; - + solver->settings().simplex_strategy() = lp:: simplex_strategy_enum::lu; + solver->find_maximal_solution(); *(solver->settings().get_message_ostream()) << "status is " << lp_status_to_string(solver->get_status()) << std::endl; - if (solver->get_status() == lean::OPTIMAL) { + if (solver->get_status() == lp::OPTIMAL) { if (params.min()) { solver->flip_costs(); } solver->print_model(std::cout); } - + // #pragma omp critical (g_display_stats) - { + { display_statistics(); register_on_timeout_proc(0); g_solver = 0; diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index a09005b7e..bd8572d73 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -38,7 +38,7 @@ Revision History: #include "util/nat_set.h" #include "tactic/filter_model_converter.h" -namespace lp { +namespace lra_lp { enum bound_kind { lower_t, upper_t }; std::ostream& operator<<(std::ostream& out, bound_kind const& k) { @@ -50,7 +50,7 @@ namespace lp { } class bound { - smt::bool_var m_bv; + smt::bool_var m_bv; smt::theory_var m_var; rational m_value; bound_kind m_bound_kind; @@ -111,7 +111,7 @@ namespace lp { namespace smt { - typedef ptr_vector lp_bounds; + typedef ptr_vector lp_bounds; class theory_lra::imp { @@ -133,7 +133,7 @@ namespace smt { delayed_atom(unsigned b, bool t): m_bv(b), m_is_true(t) {} }; - class resource_limit : public lean::lp_resource_limit { + class resource_limit : public lp::lp_resource_limit { imp& m_imp; public: resource_limit(imp& i): m_imp(i) { } @@ -198,7 +198,7 @@ namespace smt { } }; - typedef vector> var_coeffs; + typedef vector> var_coeffs; struct delayed_def { vector m_coeffs; svector m_vars; @@ -208,11 +208,11 @@ namespace smt { m_coeffs(coeffs), m_vars(vars), m_coeff(r), m_var(v) {} }; - svector m_theory_var2var_index; // translate from theory variables to lar vars + svector m_theory_var2var_index; // translate from theory variables to lar vars svector m_var_index2theory_var; // reverse map from lp_solver variables to theory variables svector m_term_index2theory_var; // reverse map from lp_solver variables to theory variables var_coeffs m_left_side; // constraint left side - mutable std::unordered_map m_variable_values; // current model + mutable std::unordered_map m_variable_values; // current model enum constraint_source { inequality_source, @@ -233,10 +233,10 @@ namespace smt { expr* m_not_handled; ptr_vector m_underspecified; unsigned_vector m_var_trail; - vector > m_use_list; // bounds where variables are used. + vector > m_use_list; // bounds where variables are used. // attributes for incremental version: - u_map m_bool_var2bound; + u_map m_bool_var2bound; vector m_bounds; unsigned_vector m_unassigned_bounds; unsigned_vector m_bounds_trail; @@ -258,15 +258,15 @@ namespace smt { struct var_value_hash { imp & m_th; var_value_hash(imp & th):m_th(th) {} - unsigned operator()(theory_var v) const { return (unsigned)std::hash()(m_th.get_ivalue(v)); } + unsigned operator()(theory_var v) const { return (unsigned)std::hash()(m_th.get_ivalue(v)); } }; int_hashtable m_model_eqs; svector m_scopes; - lp::stats m_stats; + lra_lp::stats m_stats; arith_factory* m_factory; - scoped_ptr m_solver; + scoped_ptr m_solver; resource_limit m_resource_limit; lp_bounds m_new_bounds; @@ -282,10 +282,10 @@ namespace smt { void init_solver() { if (m_solver) return; lp_params lp(ctx().get_params()); - m_solver = alloc(lean::lar_solver); + m_solver = alloc(lp::lar_solver); m_theory_var2var_index.reset(); m_solver->settings().set_resource_limit(m_resource_limit); - m_solver->settings().simplex_strategy() = static_cast(lp.simplex_strategy()); + m_solver->settings().simplex_strategy() = static_cast(lp.simplex_strategy()); reset_variable_values(); m_solver->settings().bound_propagation() = BP_NONE != propagation_mode(); m_solver->set_propagate_bounds_on_pivoted_rows_mode(lp.bprop_on_pivoted_rows()); @@ -487,8 +487,8 @@ namespace smt { return v; } - lean::var_index get_var_index(theory_var v) { - lean::var_index result = UINT_MAX; + lp::var_index get_var_index(theory_var v) { + lp::var_index result = UINT_MAX; if (m_theory_var2var_index.size() > static_cast(v)) { result = m_theory_var2var_index[v]; } @@ -537,20 +537,20 @@ namespace smt { return true; } - void add_eq_constraint(lean::constraint_index index, enode* n1, enode* n2) { + void add_eq_constraint(lp::constraint_index index, enode* n1, enode* n2) { m_constraint_sources.setx(index, equality_source, null_source); m_equalities.setx(index, enode_pair(n1, n2), enode_pair(0, 0)); ++m_stats.m_add_rows; } - void add_ineq_constraint(lean::constraint_index index, literal lit) { + void add_ineq_constraint(lp::constraint_index index, literal lit) { m_constraint_sources.setx(index, inequality_source, null_source); m_inequalities.setx(index, lit, null_literal); ++m_stats.m_add_rows; TRACE("arith", m_solver->print_constraint(index, tout); tout << "\n";); } - void add_def_constraint(lean::constraint_index index, theory_var v) { + void add_def_constraint(lp::constraint_index index, theory_var v) { m_constraint_sources.setx(index, definition_source, null_source); m_definitions.setx(index, v, null_theory_var); ++m_stats.m_add_rows; @@ -561,7 +561,7 @@ namespace smt { st.vars().append(d.m_vars); st.coeffs().append(d.m_coeffs); init_left_side(st); - add_def_constraint(m_solver->add_constraint(m_left_side, lean::EQ, -d.m_coeff), d.m_var); + add_def_constraint(m_solver->add_constraint(m_left_side, lp::EQ, -d.m_coeff), d.m_var); } void internalize_eq(theory_var v1, theory_var v2) { @@ -573,7 +573,7 @@ namespace smt { st.coeffs().push_back(rational::one()); st.coeffs().push_back(rational::minus_one()); init_left_side(st); - add_eq_constraint(m_solver->add_constraint(m_left_side, lean::EQ, rational::zero()), n1, n2); + add_eq_constraint(m_solver->add_constraint(m_left_side, lp::EQ, rational::zero()), n1, n2); TRACE("arith", tout << "v" << v1 << " = " << "v" << v2 << ": " << mk_pp(n1->get_owner(), m) << " = " << mk_pp(n2->get_owner(), m) << "\n";); @@ -583,7 +583,7 @@ namespace smt { for (unsigned i = m_bounds_trail.size(); i > old_size; ) { --i; unsigned v = m_bounds_trail[i]; - lp::bound* b = m_bounds[v].back(); + lra_lp::bound* b = m_bounds[v].back(); // del_use_lists(b); dealloc(b); m_bounds[v].pop_back(); @@ -626,7 +626,7 @@ namespace smt { else { init_left_side(st); theory_var v = mk_var(term); - lean::var_index vi = m_theory_var2var_index.get(v, UINT_MAX); + lp::var_index vi = m_theory_var2var_index.get(v, UINT_MAX); if (vi == UINT_MAX) { vi = m_solver->add_term(m_left_side, st.coeff()); m_theory_var2var_index.setx(v, vi, UINT_MAX); @@ -691,22 +691,22 @@ namespace smt { ctx().set_var_theory(bv, get_id()); expr* n1, *n2; rational r; - lp::bound_kind k; + lra_lp::bound_kind k; theory_var v = null_theory_var; if (a.is_le(atom, n1, n2) && is_numeral(n2, r) && is_app(n1)) { v = internalize_def(to_app(n1)); - k = lp::upper_t; + k = lra_lp::upper_t; } else if (a.is_ge(atom, n1, n2) && is_numeral(n2, r) && is_app(n1)) { v = internalize_def(to_app(n1)); - k = lp::lower_t; + k = lra_lp::lower_t; } else { TRACE("arith", tout << "Could not internalize " << mk_pp(atom, m) << "\n";); found_not_handled(atom); return true; } - lp::bound* b = alloc(lp::bound, bv, v, r, k); + lra_lp::bound* b = alloc(lra_lp::bound, bv, v, r, k); m_bounds[v].push_back(b); updt_unassigned_bounds(v, +1); m_bounds_trail.push_back(v); @@ -723,23 +723,23 @@ namespace smt { ctx().set_var_theory(bv, get_id()); expr* n1, *n2; rational r; - lp::bound_kind k; + lra_lp::bound_kind k; theory_var v = null_theory_var; scoped_internalize_state st(*this); if (a.is_le(atom, n1, n2) && is_numeral(n2, r) && is_app(n1)) { v = internalize_def(to_app(n1), st); - k = lp::upper_t; + k = lra_lp::upper_t; } else if (a.is_ge(atom, n1, n2) && is_numeral(n2, r) && is_app(n1)) { v = internalize_def(to_app(n1), st); - k = lp::lower_t; + k = lra_lp::lower_t; } else { TRACE("arith", tout << "Could not internalize " << mk_pp(atom, m) << "\n";); found_not_handled(atom); return true; } - lp::bound* b = alloc(lp::bound, bv, v, r, k); + lra_lp::bound* b = alloc(lra_lp::bound, bv, v, r, k); m_bounds[v].push_back(b); updt_unassigned_bounds(v, +1); m_bounds_trail.push_back(v); @@ -830,7 +830,7 @@ namespace smt { unsigned old_size = m_scopes.size() - num_scopes; del_bounds(m_scopes[old_size].m_bounds_lim); for (unsigned i = m_scopes[old_size].m_var_trail_lim; i < m_var_trail.size(); ++i) { - lean::var_index vi = m_theory_var2var_index[m_var_trail[i]]; + lp::var_index vi = m_theory_var2var_index[m_var_trail[i]]; if (m_solver->is_term(vi)) { unsigned ti = m_solver->adjust_term_index(vi); m_term_index2theory_var[ti] = UINT_MAX; @@ -1023,14 +1023,14 @@ namespace smt { return m_solver->var_is_registered(m_theory_var2var_index[v]); } - lean::impq get_ivalue(theory_var v) const { - lean_assert(can_get_ivalue(v)); - lean::var_index vi = m_theory_var2var_index[v]; + lp::impq get_ivalue(theory_var v) const { + SASSERT(can_get_ivalue(v)); + lp::var_index vi = m_theory_var2var_index[v]; if (!m_solver->is_term(vi)) return m_solver->get_value(vi); - const lean::lar_term& term = m_solver->get_term(vi); - lean::impq result(term.m_v); + const lp::lar_term& term = m_solver->get_term(vi); + lp::impq result(term.m_v); for (const auto & i: term.m_coeffs) { result += m_solver->get_value(i.first) * i.second; } @@ -1040,12 +1040,12 @@ namespace smt { rational get_value(theory_var v) const { if (!can_get_value(v)) return rational::zero(); - lean::var_index vi = m_theory_var2var_index[v]; + lp::var_index vi = m_theory_var2var_index[v]; if (m_variable_values.count(vi) > 0) { return m_variable_values[vi]; } if (m_solver->is_term(vi)) { - const lean::lar_term& term = m_solver->get_term(vi); + const lp::lar_term& term = m_solver->get_term(vi); rational result = term.m_v; for (auto i = term.m_coeffs.begin(); i != term.m_coeffs.end(); ++i) { result += m_variable_values[i->first] * i->second; @@ -1068,7 +1068,7 @@ namespace smt { } bool assume_eqs() { - svector vars; + svector vars; theory_var sz = static_cast(th.get_num_vars()); for (theory_var v = 0; v < sz; ++v) { if (th.is_relevant_and_shared(get_enode(v))) { @@ -1169,7 +1169,7 @@ namespace smt { } is_sat = make_feasible(); } - else if (m_solver->get_status() != lean::lp_status::OPTIMAL) { + else if (m_solver->get_status() != lp::lp_status::OPTIMAL) { is_sat = make_feasible(); } switch (is_sat) { @@ -1266,7 +1266,7 @@ namespace smt { propagate_bound(bv, is_true, b); #endif if (!m_delay_constraints) { - lp::bound& b = *m_bool_var2bound.find(bv); + lra_lp::bound& b = *m_bool_var2bound.find(bv); assert_bound(bv, is_true, b); } @@ -1279,7 +1279,7 @@ namespace smt { /*for (; qhead < m_asserted_atoms.size() && !ctx().inconsistent(); ++qhead) { bool_var bv = m_asserted_atoms[qhead].m_bv; bool is_true = m_asserted_atoms[qhead].m_is_true; - lp::bound& b = *m_bool_var2bound.find(bv); + lra_lp::bound& b = *m_bool_var2bound.find(bv); propagate_bound_compound(bv, is_true, b); }*/ @@ -1314,7 +1314,7 @@ namespace smt { int new_num_of_p = m_solver->settings().st().m_num_of_implied_bounds; (void)new_num_of_p; CTRACE("arith", new_num_of_p > num_of_p, tout << "found " << new_num_of_p << " implied bounds\n";); - if (m_solver->get_status() == lean::lp_status::INFEASIBLE) { + if (m_solver->get_status() == lp::lp_status::INFEASIBLE) { set_conflict(); } else { @@ -1324,7 +1324,7 @@ namespace smt { } } - bool bound_is_interesting(unsigned vi, lean::lconstraint_kind kind, const rational & bval) const { + bool bound_is_interesting(unsigned vi, lp::lconstraint_kind kind, const rational & bval) const { theory_var v; if (m_solver->is_term(vi)) { v = m_term_index2theory_var.get(m_solver->adjust_term_index(vi), null_theory_var); @@ -1341,7 +1341,7 @@ namespace smt { } lp_bounds const& bounds = m_bounds[v]; for (unsigned i = 0; i < bounds.size(); ++i) { - lp::bound* b = bounds[i]; + lra_lp::bound* b = bounds[i]; if (ctx().get_assignment(b->get_bv()) != l_undef) { continue; } @@ -1354,11 +1354,11 @@ namespace smt { return false; } - struct local_bound_propagator: public lean::lp_bound_propagator { + struct local_bound_propagator: public lp::lp_bound_propagator { imp & m_imp; local_bound_propagator(imp& i) : lp_bound_propagator(*i.m_solver), m_imp(i) {} - bool bound_is_interesting(unsigned j, lean::lconstraint_kind kind, const rational & v) { + bool bound_is_interesting(unsigned j, lp::lconstraint_kind kind, const rational & v) { return m_imp.bound_is_interesting(j, kind, v); } @@ -1368,10 +1368,10 @@ namespace smt { }; - void propagate_lp_solver_bound(lean::implied_bound& be) { + void propagate_lp_solver_bound(lp::implied_bound& be) { theory_var v; - lean::var_index vi = be.m_j; + lp::var_index vi = be.m_j; if (m_solver->is_term(vi)) { v = m_term_index2theory_var.get(m_solver->adjust_term_index(vi), null_theory_var); } @@ -1392,7 +1392,7 @@ namespace smt { lp_bounds const& bounds = m_bounds[v]; bool first = true; for (unsigned i = 0; i < bounds.size(); ++i) { - lp::bound* b = bounds[i]; + lra_lp::bound* b = bounds[i]; if (ctx().get_assignment(b->get_bv()) != l_undef) { continue; } @@ -1455,28 +1455,28 @@ namespace smt { } } - literal is_bound_implied(lean::lconstraint_kind k, rational const& value, lp::bound const& b) const { - if ((k == lean::LE || k == lean::LT) && b.get_bound_kind() == lp::upper_t && value <= b.get_value()) { + literal is_bound_implied(lp::lconstraint_kind k, rational const& value, lra_lp::bound const& b) const { + if ((k == lp::LE || k == lp::LT) && b.get_bound_kind() == lra_lp::upper_t && value <= b.get_value()) { // v <= value <= b.get_value() => v <= b.get_value() return literal(b.get_bv(), false); } - if ((k == lean::GE || k == lean::GT) && b.get_bound_kind() == lp::lower_t && b.get_value() <= value) { + if ((k == lp::GE || k == lp::GT) && b.get_bound_kind() == lra_lp::lower_t && b.get_value() <= value) { // b.get_value() <= value <= v => b.get_value() <= v return literal(b.get_bv(), false); } - if (k == lean::LE && b.get_bound_kind() == lp::lower_t && value < b.get_value()) { + if (k == lp::LE && b.get_bound_kind() == lra_lp::lower_t && value < b.get_value()) { // v <= value < b.get_value() => v < b.get_value() return literal(b.get_bv(), true); } - if (k == lean::LT && b.get_bound_kind() == lp::lower_t && value <= b.get_value()) { + if (k == lp::LT && b.get_bound_kind() == lra_lp::lower_t && value <= b.get_value()) { // v < value <= b.get_value() => v < b.get_value() return literal(b.get_bv(), true); } - if (k == lean::GE && b.get_bound_kind() == lp::upper_t && b.get_value() < value) { + if (k == lp::GE && b.get_bound_kind() == lra_lp::upper_t && b.get_value() < value) { // b.get_value() < value <= v => b.get_value() < v return literal(b.get_bv(), true); } - if (k == lean::GT && b.get_bound_kind() == lp::upper_t && b.get_value() <= value) { + if (k == lp::GT && b.get_bound_kind() == lra_lp::upper_t && b.get_value() <= value) { // b.get_value() <= value < v => b.get_value() < v return literal(b.get_bv(), true); } @@ -1484,7 +1484,7 @@ namespace smt { return null_literal; } - void mk_bound_axioms(lp::bound& b) { + void mk_bound_axioms(lra_lp::bound& b) { if (!ctx().is_searching()) { // // NB. We make an assumption that user push calls propagation @@ -1495,19 +1495,19 @@ namespace smt { return; } theory_var v = b.get_var(); - lp::bound_kind kind1 = b.get_bound_kind(); + lra_lp::bound_kind kind1 = b.get_bound_kind(); rational const& k1 = b.get_value(); lp_bounds & bounds = m_bounds[v]; - lp::bound* end = 0; - lp::bound* lo_inf = end, *lo_sup = end; - lp::bound* hi_inf = end, *hi_sup = end; + lra_lp::bound* end = 0; + lra_lp::bound* lo_inf = end, *lo_sup = end; + lra_lp::bound* hi_inf = end, *hi_sup = end; for (unsigned i = 0; i < bounds.size(); ++i) { - lp::bound& other = *bounds[i]; + lra_lp::bound& other = *bounds[i]; if (&other == &b) continue; if (b.get_bv() == other.get_bv()) continue; - lp::bound_kind kind2 = other.get_bound_kind(); + lra_lp::bound_kind kind2 = other.get_bound_kind(); rational const& k2 = other.get_value(); if (k1 == k2 && kind1 == kind2) { // the bounds are equivalent. @@ -1515,7 +1515,7 @@ namespace smt { } SASSERT(k1 != k2 || kind1 != kind2); - if (kind2 == lp::lower_t) { + if (kind2 == lra_lp::lower_t) { if (k2 < k1) { if (lo_inf == end || k2 > lo_inf->get_value()) { lo_inf = &other; @@ -1541,14 +1541,14 @@ namespace smt { } - void mk_bound_axiom(lp::bound& b1, lp::bound& b2) { + void mk_bound_axiom(lra_lp::bound& b1, lra_lp::bound& b2) { theory_var v = b1.get_var(); literal l1(b1.get_bv()); literal l2(b2.get_bv()); rational const& k1 = b1.get_value(); rational const& k2 = b2.get_value(); - lp::bound_kind kind1 = b1.get_bound_kind(); - lp::bound_kind kind2 = b2.get_bound_kind(); + lra_lp::bound_kind kind1 = b1.get_bound_kind(); + lra_lp::bound_kind kind2 = b2.get_bound_kind(); bool v_is_int = is_int(v); SASSERT(v == b2.get_var()); if (k1 == k2 && kind1 == kind2) return; @@ -1556,8 +1556,8 @@ namespace smt { parameter coeffs[3] = { parameter(symbol("farkas")), parameter(rational(1)), parameter(rational(1)) }; - if (kind1 == lp::lower_t) { - if (kind2 == lp::lower_t) { + if (kind1 == lra_lp::lower_t) { + if (kind2 == lra_lp::lower_t) { if (k2 <= k1) { mk_clause(~l1, l2, 3, coeffs); } @@ -1578,7 +1578,7 @@ namespace smt { } } } - else if (kind2 == lp::lower_t) { + else if (kind2 == lra_lp::lower_t) { if (k1 >= k2) { // k1 >= lo_inf, k1 >= x or lo_inf <= x mk_clause(l1, l2, 3, coeffs); @@ -1636,21 +1636,21 @@ namespace smt { iterator begin1 = occs.begin(); iterator begin2 = occs.begin(); iterator end = occs.end(); - begin1 = first(lp::lower_t, begin1, end); - begin2 = first(lp::upper_t, begin2, end); + begin1 = first(lra_lp::lower_t, begin1, end); + begin2 = first(lra_lp::upper_t, begin2, end); iterator lo_inf = begin1, lo_sup = begin1; iterator hi_inf = begin2, hi_sup = begin2; iterator lo_inf1 = begin1, lo_sup1 = begin1; iterator hi_inf1 = begin2, hi_sup1 = begin2; bool flo_inf, fhi_inf, flo_sup, fhi_sup; - ptr_addr_hashtable visited; + ptr_addr_hashtable visited; for (unsigned i = 0; i < atoms.size(); ++i) { - lp::bound* a1 = atoms[i]; - lo_inf1 = next_inf(a1, lp::lower_t, lo_inf, end, flo_inf); - hi_inf1 = next_inf(a1, lp::upper_t, hi_inf, end, fhi_inf); - lo_sup1 = next_sup(a1, lp::lower_t, lo_sup, end, flo_sup); - hi_sup1 = next_sup(a1, lp::upper_t, hi_sup, end, fhi_sup); + lra_lp::bound* a1 = atoms[i]; + lo_inf1 = next_inf(a1, lra_lp::lower_t, lo_inf, end, flo_inf); + hi_inf1 = next_inf(a1, lra_lp::upper_t, hi_inf, end, fhi_inf); + lo_sup1 = next_sup(a1, lra_lp::lower_t, lo_sup, end, flo_sup); + hi_sup1 = next_sup(a1, lra_lp::upper_t, hi_sup, end, fhi_sup); if (lo_inf1 != end) lo_inf = lo_inf1; if (lo_sup1 != end) lo_sup = lo_sup1; if (hi_inf1 != end) hi_inf = hi_inf1; @@ -1669,24 +1669,24 @@ namespace smt { } struct compare_bounds { - bool operator()(lp::bound* a1, lp::bound* a2) const { return a1->get_value() < a2->get_value(); } + bool operator()(lra_lp::bound* a1, lra_lp::bound* a2) const { return a1->get_value() < a2->get_value(); } }; lp_bounds::iterator first( - lp::bound_kind kind, + lra_lp::bound_kind kind, iterator it, iterator end) { for (; it != end; ++it) { - lp::bound* a = *it; + lra_lp::bound* a = *it; if (a->get_bound_kind() == kind) return it; } return end; } lp_bounds::iterator next_inf( - lp::bound* a1, - lp::bound_kind kind, + lra_lp::bound* a1, + lra_lp::bound_kind kind, iterator it, iterator end, bool& found_compatible) { @@ -1694,7 +1694,7 @@ namespace smt { iterator result = end; found_compatible = false; for (; it != end; ++it) { - lp::bound * a2 = *it; + lra_lp::bound * a2 = *it; if (a1 == a2) continue; if (a2->get_bound_kind() != kind) continue; rational const & k2(a2->get_value()); @@ -1710,15 +1710,15 @@ namespace smt { } lp_bounds::iterator next_sup( - lp::bound* a1, - lp::bound_kind kind, + lra_lp::bound* a1, + lra_lp::bound_kind kind, iterator it, iterator end, bool& found_compatible) { rational const & k1(a1->get_value()); found_compatible = false; for (; it != end; ++it) { - lp::bound * a2 = *it; + lra_lp::bound * a2 = *it; if (a1 == a2) continue; if (a2->get_bound_kind() != kind) continue; rational const & k2(a2->get_value()); @@ -1732,7 +1732,7 @@ namespace smt { void propagate_basic_bounds() { for (auto const& bv : m_to_check) { - lp::bound& b = *m_bool_var2bound.find(bv); + lra_lp::bound& b = *m_bool_var2bound.find(bv); propagate_bound(bv, ctx().get_assignment(bv) == l_true, b); if (ctx().inconsistent()) break; @@ -1747,11 +1747,11 @@ namespace smt { // x <= hi -> x <= hi' // x <= hi -> ~(x >= hi') - void propagate_bound(bool_var bv, bool is_true, lp::bound& b) { + void propagate_bound(bool_var bv, bool is_true, lra_lp::bound& b) { if (BP_NONE == propagation_mode()) { return; } - lp::bound_kind k = b.get_bound_kind(); + lra_lp::bound_kind k = b.get_bound_kind(); theory_var v = b.get_var(); inf_rational val = b.get_value(is_true); lp_bounds const& bounds = m_bounds[v]; @@ -1761,12 +1761,12 @@ namespace smt { literal lit1(bv, !is_true); literal lit2 = null_literal; - bool find_glb = (is_true == (k == lp::lower_t)); + bool find_glb = (is_true == (k == lra_lp::lower_t)); if (find_glb) { rational glb; - lp::bound* lb = 0; + lra_lp::bound* lb = 0; for (unsigned i = 0; i < bounds.size(); ++i) { - lp::bound* b2 = bounds[i]; + lra_lp::bound* b2 = bounds[i]; if (b2 == &b) continue; rational const& val2 = b2->get_value(); if ((is_true ? val2 < val : val2 <= val) && (!lb || glb < val2)) { @@ -1775,14 +1775,14 @@ namespace smt { } } if (!lb) return; - bool sign = lb->get_bound_kind() != lp::lower_t; + bool sign = lb->get_bound_kind() != lra_lp::lower_t; lit2 = literal(lb->get_bv(), sign); } else { rational lub; - lp::bound* ub = 0; + lra_lp::bound* ub = 0; for (unsigned i = 0; i < bounds.size(); ++i) { - lp::bound* b2 = bounds[i]; + lra_lp::bound* b2 = bounds[i]; if (b2 == &b) continue; rational const& val2 = b2->get_value(); if ((is_true ? val < val2 : val <= val2) && (!ub || val2 < lub)) { @@ -1791,7 +1791,7 @@ namespace smt { } } if (!ub) return; - bool sign = ub->get_bound_kind() != lp::upper_t; + bool sign = ub->get_bound_kind() != lra_lp::upper_t; lit2 = literal(ub->get_bv(), sign); } TRACE("arith", @@ -1811,27 +1811,27 @@ namespace smt { ++m_stats.m_bounds_propagations; } - void add_use_lists(lp::bound* b) { + void add_use_lists(lra_lp::bound* b) { theory_var v = b->get_var(); - lean::var_index vi = get_var_index(v); + lp::var_index vi = get_var_index(v); if (m_solver->is_term(vi)) { - lean::lar_term const& term = m_solver->get_term(vi); + lp::lar_term const& term = m_solver->get_term(vi); for (auto i = term.m_coeffs.begin(); i != term.m_coeffs.end(); ++i) { - lean::var_index wi = i->first; + lp::var_index wi = i->first; unsigned w = m_var_index2theory_var[wi]; - m_use_list.reserve(w + 1, ptr_vector()); + m_use_list.reserve(w + 1, ptr_vector()); m_use_list[w].push_back(b); } } } - void del_use_lists(lp::bound* b) { + void del_use_lists(lra_lp::bound* b) { theory_var v = b->get_var(); - lean::var_index vi = m_theory_var2var_index[v]; + lp::var_index vi = m_theory_var2var_index[v]; if (m_solver->is_term(vi)) { - lean::lar_term const& term = m_solver->get_term(vi); + lp::lar_term const& term = m_solver->get_term(vi); for (auto i = term.m_coeffs.begin(); i != term.m_coeffs.end(); ++i) { - lean::var_index wi = i->first; + lp::var_index wi = i->first; unsigned w = m_var_index2theory_var[wi]; SASSERT(m_use_list[w].back() == b); m_use_list[w].pop_back(); @@ -1845,7 +1845,7 @@ namespace smt { // have been assigned we may know the truth value of the inequality by using simple // bounds propagation. // - void propagate_bound_compound(bool_var bv, bool is_true, lp::bound& b) { + void propagate_bound_compound(bool_var bv, bool is_true, lra_lp::bound& b) { theory_var v = b.get_var(); TRACE("arith", tout << mk_pp(get_owner(v), m) << "\n";); if (static_cast(v) >= m_use_list.size()) { @@ -1861,7 +1861,7 @@ namespace smt { // x >= 0, y >= 1 -> x + y >= 1 // x <= 0, y <= 2 -> x + y <= 2 literal lit = null_literal; - if (lp::lower_t == vb->get_bound_kind()) { + if (lra_lp::lower_t == vb->get_bound_kind()) { if (get_glb(*vb, r) && r >= vb->get_value()) { // vb is assigned true lit = literal(vb->get_bv(), false); } @@ -1895,30 +1895,30 @@ namespace smt { } } - bool get_lub(lp::bound const& b, inf_rational& lub) { + bool get_lub(lra_lp::bound const& b, inf_rational& lub) { return get_bound(b, lub, true); } - bool get_glb(lp::bound const& b, inf_rational& glb) { + bool get_glb(lra_lp::bound const& b, inf_rational& glb) { return get_bound(b, glb, false); } - std::ostream& display_bound(std::ostream& out, lp::bound const& b) { + std::ostream& display_bound(std::ostream& out, lra_lp::bound const& b) { return out << mk_pp(ctx().bool_var2expr(b.get_bv()), m); } - bool get_bound(lp::bound const& b, inf_rational& r, bool is_lub) { + bool get_bound(lra_lp::bound const& b, inf_rational& r, bool is_lub) { m_core.reset(); m_eqs.reset(); m_params.reset(); r.reset(); theory_var v = b.get_var(); - lean::var_index vi = m_theory_var2var_index[v]; + lp::var_index vi = m_theory_var2var_index[v]; SASSERT(m_solver->is_term(vi)); - lean::lar_term const& term = m_solver->get_term(vi); + lp::lar_term const& term = m_solver->get_term(vi); for (auto const coeff : term.m_coeffs) { - lean::var_index wi = coeff.first; - lean::constraint_index ci; + lp::var_index wi = coeff.first; + lp::constraint_index ci; rational value; bool is_strict; if (coeff.second.is_neg() == is_lub) { @@ -1945,24 +1945,24 @@ namespace smt { return true; } - void assert_bound(bool_var bv, bool is_true, lp::bound& b) { - if (m_solver->get_status() == lean::lp_status::INFEASIBLE) { + void assert_bound(bool_var bv, bool is_true, lra_lp::bound& b) { + if (m_solver->get_status() == lp::lp_status::INFEASIBLE) { return; } scoped_internalize_state st(*this); st.vars().push_back(b.get_var()); st.coeffs().push_back(rational::one()); init_left_side(st); - lean::lconstraint_kind k = lean::EQ; + lp::lconstraint_kind k = lp::EQ; switch (b.get_bound_kind()) { - case lp::lower_t: - k = is_true ? lean::GE : lean::LT; + case lra_lp::lower_t: + k = is_true ? lp::GE : lp::LT; break; - case lp::upper_t: - k = is_true ? lean::LE : lean::GT; + case lra_lp::upper_t: + k = is_true ? lp::LE : lp::GT; break; } - if (k == lean::LT || k == lean::LE) { + if (k == lp::LT || k == lp::LE) { ++m_stats.m_assert_lower; } else { @@ -1983,7 +1983,7 @@ namespace smt { // Then the equality v1 == v2 is propagated to the core. // - typedef std::pair constraint_bound; + typedef std::pair constraint_bound; vector m_lower_terms; vector m_upper_terms; typedef std::pair value_sort_pair; @@ -1991,16 +1991,16 @@ namespace smt { typedef map > value2var; value2var m_fixed_var_table; - void propagate_eqs(lean::var_index vi, lean::constraint_index ci, lean::lconstraint_kind k, lp::bound& b) { + void propagate_eqs(lp::var_index vi, lp::constraint_index ci, lp::lconstraint_kind k, lra_lp::bound& b) { if (propagate_eqs()) { rational const& value = b.get_value(); - if (k == lean::GE) { + if (k == lp::GE) { set_lower_bound(vi, ci, value); if (has_upper_bound(vi, ci, value)) { fixed_var_eh(b.get_var(), value); } } - else if (k == lean::LE) { + else if (k == lp::LE) { set_upper_bound(vi, ci, value); if (has_lower_bound(vi, ci, value)) { fixed_var_eh(b.get_var(), value); @@ -2021,16 +2021,16 @@ namespace smt { bool use_tableau() const { return lp_params(ctx().get_params()).simplex_strategy() < 2; } - void set_upper_bound(lean::var_index vi, lean::constraint_index ci, rational const& v) { set_bound(vi, ci, v, false); } + void set_upper_bound(lp::var_index vi, lp::constraint_index ci, rational const& v) { set_bound(vi, ci, v, false); } - void set_lower_bound(lean::var_index vi, lean::constraint_index ci, rational const& v) { set_bound(vi, ci, v, true); } + void set_lower_bound(lp::var_index vi, lp::constraint_index ci, rational const& v) { set_bound(vi, ci, v, true); } - void set_bound(lean::var_index vi, lean::constraint_index ci, rational const& v, bool is_lower) { + void set_bound(lp::var_index vi, lp::constraint_index ci, rational const& v, bool is_lower) { if (!m_solver->is_term(vi)) { // m_solver already tracks bounds on proper variables, but not on terms. return; } - lean::var_index ti = m_solver->adjust_term_index(vi); + lp::var_index ti = m_solver->adjust_term_index(vi); auto& vec = is_lower ? m_lower_terms : m_upper_terms; if (vec.size() <= ti) { vec.resize(ti + 1, constraint_bound(UINT_MAX, rational())); @@ -2043,15 +2043,15 @@ namespace smt { } } - bool has_upper_bound(lean::var_index vi, lean::constraint_index& ci, rational const& bound) { return has_bound(vi, ci, bound, false); } + bool has_upper_bound(lp::var_index vi, lp::constraint_index& ci, rational const& bound) { return has_bound(vi, ci, bound, false); } - bool has_lower_bound(lean::var_index vi, lean::constraint_index& ci, rational const& bound) { return has_bound(vi, ci, bound, true); } + bool has_lower_bound(lp::var_index vi, lp::constraint_index& ci, rational const& bound) { return has_bound(vi, ci, bound, true); } - bool has_bound(lean::var_index vi, lean::constraint_index& ci, rational const& bound, bool is_lower) { + bool has_bound(lp::var_index vi, lp::constraint_index& ci, rational const& bound, bool is_lower) { if (m_solver->is_term(vi)) { - lean::var_index ti = m_solver->adjust_term_index(vi); + lp::var_index ti = m_solver->adjust_term_index(vi); theory_var v = m_term_index2theory_var.get(ti, null_theory_var); rational val; TRACE("arith", tout << vi << " " << v << "\n";); @@ -2094,7 +2094,7 @@ namespace smt { if (static_cast(v2) < th.get_num_vars() && !is_equal(v1, v2)) { auto vi1 = get_var_index(v1); auto vi2 = get_var_index(v2); - lean::constraint_index ci1, ci2, ci3, ci4; + lp::constraint_index ci1, ci2, ci3, ci4; TRACE("arith", tout << "fixed: " << mk_pp(get_owner(v1), m) << " " << mk_pp(get_owner(v2), m) << " " << bound << " " << has_lower_bound(vi2, ci3, bound) << "\n";); if (has_lower_bound(vi2, ci3, bound) && has_upper_bound(vi2, ci4, bound)) { VERIFY (has_lower_bound(vi1, ci1, bound)); @@ -2148,19 +2148,19 @@ namespace smt { if (m_solver->A_r().row_count() > m_stats.m_max_rows) m_stats.m_max_rows = m_solver->A_r().row_count(); TRACE("arith_verbose", display(tout);); - lean::lp_status status = m_solver->find_feasible_solution(); + lp::lp_status status = m_solver->find_feasible_solution(); m_stats.m_num_iterations = m_solver->settings().st().m_total_iterations; m_stats.m_num_factorizations = m_solver->settings().st().m_num_factorizations; m_stats.m_need_to_solve_inf = m_solver->settings().st().m_need_to_solve_inf; switch (status) { - case lean::lp_status::INFEASIBLE: + case lp::lp_status::INFEASIBLE: return l_false; - case lean::lp_status::FEASIBLE: - case lean::lp_status::OPTIMAL: + case lp::lp_status::FEASIBLE: + case lp::lp_status::OPTIMAL: // SASSERT(m_solver->all_constraints_hold()); return l_true; - case lean::lp_status::TIME_EXHAUSTED: + case lp::lp_status::TIME_EXHAUSTED: default: TRACE("arith", tout << "status treated as inconclusive: " << status << "\n";); @@ -2170,14 +2170,14 @@ namespace smt { } } - vector> m_explanation; + vector> m_explanation; literal_vector m_core; svector m_eqs; vector m_params; - // lean::constraint_index const null_constraint_index = UINT_MAX; // not sure what a correct fix is + // lp::constraint_index const null_constraint_index = UINT_MAX; // not sure what a correct fix is - void set_evidence(lean::constraint_index idx) { + void set_evidence(lp::constraint_index idx) { if (idx == UINT_MAX) { return; } @@ -2327,16 +2327,16 @@ namespace smt { } theory_lra::inf_eps value(theory_var v) { - lean::impq ival = get_ivalue(v); + lp::impq ival = get_ivalue(v); return inf_eps(0, inf_rational(ival.x, ival.y)); } theory_lra::inf_eps maximize(theory_var v, expr_ref& blocker, bool& has_shared) { - lean::var_index vi = m_theory_var2var_index.get(v, UINT_MAX); - vector > coeffs; + lp::var_index vi = m_theory_var2var_index.get(v, UINT_MAX); + vector > coeffs; rational coeff; if (m_solver->is_term(vi)) { - const lean::lar_term& term = m_solver->get_term(vi); + const lp::lar_term& term = m_solver->get_term(vi); for (auto & ti : term.m_coeffs) { coeffs.push_back(std::make_pair(ti.second, ti.first)); } @@ -2346,7 +2346,7 @@ namespace smt { coeffs.push_back(std::make_pair(rational::one(), vi)); coeff = rational::zero(); } - lean::impq term_max; + lp::impq term_max; if (m_solver->maximize_term(coeffs, term_max)) { blocker = mk_gt(v); inf_rational val(term_max.x + coeff, term_max.y); @@ -2361,7 +2361,7 @@ namespace smt { } expr_ref mk_gt(theory_var v) { - lean::impq val = get_ivalue(v); + lp::impq val = get_ivalue(v); expr* obj = get_enode(v)->get_owner(); rational r = val.x; expr_ref e(m); @@ -2393,11 +2393,11 @@ namespace smt { } app_ref mk_obj(theory_var v) { - lean::var_index vi = m_theory_var2var_index[v]; + lp::var_index vi = m_theory_var2var_index[v]; bool is_int = a.is_int(get_enode(v)->get_owner()); if (m_solver->is_term(vi)) { expr_ref_vector args(m); - const lean::lar_term& term = m_solver->get_term(vi); + const lp::lar_term& term = m_solver->get_term(vi); for (auto & ti : term.m_coeffs) { theory_var w = m_var_index2theory_var[ti.first]; expr* o = get_enode(w)->get_owner(); @@ -2428,9 +2428,9 @@ namespace smt { bool_var bv = ctx().mk_bool_var(b); ctx().set_var_theory(bv, get_id()); // ctx().set_enode_flag(bv, true); - lp::bound_kind bkind = lp::bound_kind::lower_t; - if (is_strict) bkind = lp::bound_kind::upper_t; - lp::bound* a = alloc(lp::bound, bv, v, r, bkind); + lra_lp::bound_kind bkind = lra_lp::bound_kind::lower_t; + if (is_strict) bkind = lra_lp::bound_kind::upper_t; + lra_lp::bound* a = alloc(lra_lp::bound, bv, v, r, bkind); mk_bound_axioms(*a); updt_unassigned_bounds(v, +1); m_bounds[v].push_back(a); @@ -2462,7 +2462,7 @@ namespace smt { } } - void display_evidence(std::ostream& out, vector> const& evidence) { + void display_evidence(std::ostream& out, vector> const& evidence) { for (auto const& ev : evidence) { expr_ref e(m); SASSERT(!ev.first.is_zero()); diff --git a/src/util/lp/binary_heap_priority_queue.h b/src/util/lp/binary_heap_priority_queue.h index a6206948c..8282ece9c 100644 --- a/src/util/lp/binary_heap_priority_queue.h +++ b/src/util/lp/binary_heap_priority_queue.h @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/debug.h" #include "util/lp/lp_utils.h" -namespace lean { +namespace lp { // the elements with the smallest priority are dequeued first template class binary_heap_priority_queue { @@ -22,7 +37,7 @@ class binary_heap_priority_queue { void put_at(unsigned i, unsigned h); void decrease_priority(unsigned o, T newPriority); public: -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG bool is_consistent() const; #endif public: @@ -60,10 +75,10 @@ public: /// return the first element of the queue and removes it from the queue unsigned dequeue(); unsigned peek() const { - lean_assert(m_heap_size > 0); + SASSERT(m_heap_size > 0); return m_heap[1]; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void print(std::ostream & out); #endif }; diff --git a/src/util/lp/binary_heap_priority_queue.hpp b/src/util/lp/binary_heap_priority_queue.hpp index 440b45b02..e7378309d 100644 --- a/src/util/lp/binary_heap_priority_queue.hpp +++ b/src/util/lp/binary_heap_priority_queue.hpp @@ -1,11 +1,26 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include "util/lp/binary_heap_priority_queue.h" -namespace lean { -// is is the child place in heap +namespace lp { +// this is the child place in the heap template void binary_heap_priority_queue::swap_with_parent(unsigned i) { unsigned parent = m_heap[i >> 1]; put_at(i >> 1, m_heap[i]); @@ -29,12 +44,12 @@ template void binary_heap_priority_queue::decrease_priority(unsi } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool binary_heap_priority_queue::is_consistent() const { for (int i = 0; i < m_heap_inverse.size(); i++) { int i_index = m_heap_inverse[i]; - lean_assert(i_index <= static_cast(m_heap_size)); - lean_assert(i_index == -1 || m_heap[i_index] == i); + SASSERT(i_index <= static_cast(m_heap_size)); + SASSERT(i_index == -1 || m_heap[i_index] == i); } for (unsigned i = 1; i < m_heap_size; i++) { unsigned ch = i << 1; @@ -49,13 +64,14 @@ template bool binary_heap_priority_queue::is_consistent() const return true; } #endif + template void binary_heap_priority_queue::remove(unsigned o) { T priority_of_o = m_priorities[o]; int o_in_heap = m_heap_inverse[o]; if (o_in_heap == -1) { return; // nothing to do } - lean_assert(static_cast(o_in_heap) <= m_heap_size); + SASSERT(static_cast(o_in_heap) <= m_heap_size); if (static_cast(o_in_heap) < m_heap_size) { put_at(o_in_heap, m_heap[m_heap_size--]); if (m_priorities[m_heap[o_in_heap]] > priority_of_o) { @@ -72,11 +88,11 @@ template void binary_heap_priority_queue::remove(unsigned o) { } } } else { - lean_assert(static_cast(o_in_heap) == m_heap_size); + SASSERT(static_cast(o_in_heap) == m_heap_size); m_heap_size--; } m_heap_inverse[o] = -1; - // lean_assert(is_consistent()); + // SASSERT(is_consistent()); } // n is the initial queue capacity. // The capacity will be enlarged two times automatically if needed @@ -102,7 +118,7 @@ template void binary_heap_priority_queue::put_to_heap(unsigned i template void binary_heap_priority_queue::enqueue_new(unsigned o, const T& priority) { m_heap_size++; int i = m_heap_size; - lean_assert(o < m_priorities.size()); + SASSERT(o < m_priorities.size()); m_priorities[o] = priority; put_at(i, o); while (i > 1 && m_priorities[m_heap[i >> 1]] > priority) { @@ -134,7 +150,7 @@ template void binary_heap_priority_queue::change_priority_for_ex /// return the first element of the queue and removes it from the queue template unsigned binary_heap_priority_queue::dequeue_and_get_priority(T & priority) { - lean_assert(m_heap_size != 0); + SASSERT(m_heap_size != 0); int ret = m_heap[1]; priority = m_priorities[ret]; put_the_last_at_the_top_and_fix_the_heap(); @@ -168,13 +184,13 @@ template void binary_heap_priority_queue::put_the_last_at_the_to } /// return the first element of the queue and removes it from the queue template unsigned binary_heap_priority_queue::dequeue() { - lean_assert(m_heap_size > 0); + SASSERT(m_heap_size > 0); int ret = m_heap[1]; put_the_last_at_the_top_and_fix_the_heap(); m_heap_inverse[ret] = -1; return ret; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template void binary_heap_priority_queue::print(std::ostream & out) { vector index; vector prs; diff --git a/src/util/lp/binary_heap_priority_queue_instances.cpp b/src/util/lp/binary_heap_priority_queue_instances.cpp index 567494d6f..fca826a6b 100644 --- a/src/util/lp/binary_heap_priority_queue_instances.cpp +++ b/src/util/lp/binary_heap_priority_queue_instances.cpp @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/numeric_pair.h" #include "util/lp/binary_heap_priority_queue.hpp" -namespace lean { +namespace lp { template binary_heap_priority_queue::binary_heap_priority_queue(unsigned int); template unsigned binary_heap_priority_queue::dequeue(); template void binary_heap_priority_queue::enqueue(unsigned int, int const&); @@ -16,11 +31,11 @@ template unsigned binary_heap_priority_queue::dequeue(); template unsigned binary_heap_priority_queue::dequeue(); template void binary_heap_priority_queue >::enqueue(unsigned int, numeric_pair const&); template void binary_heap_priority_queue >::resize(unsigned int); -template void lean::binary_heap_priority_queue::resize(unsigned int); +template void lp::binary_heap_priority_queue::resize(unsigned int); template binary_heap_priority_queue::binary_heap_priority_queue(unsigned int); template void binary_heap_priority_queue::resize(unsigned int); template unsigned binary_heap_priority_queue::dequeue(); template void binary_heap_priority_queue::enqueue(unsigned int, unsigned int const&); template void binary_heap_priority_queue::remove(unsigned int); -template void lean::binary_heap_priority_queue::resize(unsigned int); +template void lp::binary_heap_priority_queue::resize(unsigned int); } diff --git a/src/util/lp/binary_heap_upair_queue.h b/src/util/lp/binary_heap_upair_queue.h index 26cfd5532..640c4bb81 100644 --- a/src/util/lp/binary_heap_upair_queue.h +++ b/src/util/lp/binary_heap_upair_queue.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include @@ -15,7 +30,7 @@ typedef std::pair upair; -namespace lean { +namespace lp { template class binary_heap_upair_queue { binary_heap_priority_queue m_q; @@ -38,7 +53,7 @@ public: void enqueue(unsigned i, unsigned j, const T & priority); void dequeue(unsigned & i, unsigned &j); T get_priority(unsigned i, unsigned j) const; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG bool pair_to_index_is_a_bijection() const; bool available_spots_are_correct() const; bool is_correct() const { diff --git a/src/util/lp/binary_heap_upair_queue.hpp b/src/util/lp/binary_heap_upair_queue.hpp index a48bdb5b7..d12be9707 100644 --- a/src/util/lp/binary_heap_upair_queue.hpp +++ b/src/util/lp/binary_heap_upair_queue.hpp @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/lp/lp_utils.h" #include "util/lp/binary_heap_upair_queue.h" -namespace lean { +namespace lp { template binary_heap_upair_queue::binary_heap_upair_queue(unsigned size) : m_q(size), m_pairs(size) { for (unsigned i = 0; i < size; i++) m_available_spots.push_back(i); @@ -14,7 +29,7 @@ template binary_heap_upair_queue::binary_heap_upair_queue(unsign template unsigned binary_heap_upair_queue::dequeue_available_spot() { - lean_assert(m_available_spots.empty() == false); + SASSERT(m_available_spots.empty() == false); unsigned ret = m_available_spots.back(); m_available_spots.pop_back(); return ret; @@ -54,7 +69,7 @@ template void binary_heap_upair_queue::enqueue(unsigned i, unsig m_pairs.resize(new_size); } ij_index = dequeue_available_spot(); - // lean_assert(ij_index void binary_heap_upair_queue::enqueue(unsigned i, unsig } template void binary_heap_upair_queue::dequeue(unsigned & i, unsigned &j) { - lean_assert(!m_q.is_empty()); + SASSERT(!m_q.is_empty()); unsigned ij_index = m_q.dequeue(); upair & p = m_pairs[ij_index]; i = p.first; @@ -81,7 +96,7 @@ template T binary_heap_upair_queue::get_priority(unsigned i, uns return m_q.get_priority(it->second); } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool binary_heap_upair_queue::pair_to_index_is_a_bijection() const { std::set tmp; for (auto p : m_pairs_to_index) { diff --git a/src/util/lp/binary_heap_upair_queue_instances.cpp b/src/util/lp/binary_heap_upair_queue_instances.cpp index 4c4603110..6d093b175 100644 --- a/src/util/lp/binary_heap_upair_queue_instances.cpp +++ b/src/util/lp/binary_heap_upair_queue_instances.cpp @@ -1,9 +1,24 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/binary_heap_upair_queue.hpp" -namespace lean { +namespace lp { template binary_heap_upair_queue::binary_heap_upair_queue(unsigned int); template binary_heap_upair_queue::binary_heap_upair_queue(unsigned int); template unsigned binary_heap_upair_queue::dequeue_available_spot(); diff --git a/src/util/lp/bound_analyzer_on_row.h b/src/util/lp/bound_analyzer_on_row.h index 914835a3c..52b8ece64 100644 --- a/src/util/lp/bound_analyzer_on_row.h +++ b/src/util/lp/bound_analyzer_on_row.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/lp/linear_combination_iterator.h" @@ -13,7 +28,7 @@ // We try to pin a var by pushing the total by using the variable bounds // In a loop we drive the partial sum down, denoting the variables of this process by _u. // In the same loop trying to pin variables by pushing the partial sum up, denoting the variable related to it by _l -namespace lean { +namespace lp { class bound_analyzer_on_row { @@ -91,11 +106,11 @@ public : } const impq & ub(unsigned j) const { - lean_assert(upper_bound_is_available(j)); + SASSERT(upper_bound_is_available(j)); return m_bp.get_upper_bound(j); } const impq & lb(unsigned j) const { - lean_assert(low_bound_is_available(j)); + SASSERT(low_bound_is_available(j)); return m_bp.get_low_bound(j); } @@ -153,7 +168,7 @@ public : void limit_all_monoids_from_above() { int strict = 0; mpq total; - lean_assert(is_zero(total)); + SASSERT(is_zero(total)); m_it.reset(); mpq a; unsigned j; while (m_it.next(a, j)) { @@ -180,7 +195,7 @@ public : void limit_all_monoids_from_below() { int strict = 0; mpq total; - lean_assert(is_zero(total)); + SASSERT(is_zero(total)); m_it.reset(); mpq a; unsigned j; while (m_it.next(a, j)) { @@ -272,7 +287,7 @@ public : // mpq a; unsigned j; // while (it->next(a, j)) { // if (be.m_j == j) continue; - // lean_assert(bound_is_available(j, is_neg(a) ? low_bound : !low_bound)); + // SASSERT(bound_is_available(j, is_neg(a) ? low_bound : !low_bound)); // be.m_vector_of_bound_signatures.emplace_back(a, j, numeric_traits:: // is_neg(a)? low_bound: !low_bound); // } diff --git a/src/util/lp/breakpoint.h b/src/util/lp/breakpoint.h index e5454db0e..40fab293f 100644 --- a/src/util/lp/breakpoint.h +++ b/src/util/lp/breakpoint.h @@ -1,11 +1,26 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once -namespace lean { +namespace lp { enum breakpoint_type { low_break, upper_break, fixed_break }; diff --git a/src/util/lp/column_info.h b/src/util/lp/column_info.h index 56e75a1fb..e4b449bbf 100644 --- a/src/util/lp/column_info.h +++ b/src/util/lp/column_info.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -9,7 +24,7 @@ #include #include #include "util/lp/lp_settings.h" -namespace lean { +namespace lp { inline bool is_valid(unsigned j) { return static_cast(j) >= 0;} template @@ -100,11 +115,11 @@ public: } T get_low_bound() const { - lean_assert(m_low_bound_is_set); + SASSERT(m_low_bound_is_set); return m_low_bound; } T get_upper_bound() const { - lean_assert(m_upper_bound_is_set); + SASSERT(m_upper_bound_is_set); return m_upper_bound; } @@ -156,7 +171,7 @@ public: } T get_fixed_value() const { - lean_assert(m_is_fixed); + SASSERT(m_is_fixed); return m_fixed_value; } diff --git a/src/util/lp/column_namer.h b/src/util/lp/column_namer.h index a3fe05dd0..97d371f48 100644 --- a/src/util/lp/column_namer.h +++ b/src/util/lp/column_namer.h @@ -1,11 +1,26 @@ #pragma once -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/lp/linear_combination_iterator.h" -namespace lean { +namespace lp { class column_namer { public: virtual std::string get_column_name(unsigned j) const = 0; diff --git a/src/util/lp/conversion_helper.h b/src/util/lp/conversion_helper.h index bff2ad563..cd8577483 100644 --- a/src/util/lp/conversion_helper.h +++ b/src/util/lp/conversion_helper.h @@ -4,7 +4,7 @@ Author: Lev Nachmanson */ #pragma once -namespace lean { +namespace lp { template struct conversion_helper { static V get_low_bound(const column_info & ci) { diff --git a/src/util/lp/core_solver_pretty_printer.h b/src/util/lp/core_solver_pretty_printer.h index 2a3a14b31..20b2c1cbe 100644 --- a/src/util/lp/core_solver_pretty_printer.h +++ b/src/util/lp/core_solver_pretty_printer.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include #include @@ -10,7 +25,7 @@ #include #include "util/lp/lp_settings.h" #include "util/lp/indexed_vector.h" -namespace lean { +namespace lp { template class lp_core_solver_base; // forward definition template diff --git a/src/util/lp/core_solver_pretty_printer.hpp b/src/util/lp/core_solver_pretty_printer.hpp index 786b8b3a1..4ae49a550 100644 --- a/src/util/lp/core_solver_pretty_printer.hpp +++ b/src/util/lp/core_solver_pretty_printer.hpp @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include @@ -9,7 +24,7 @@ #include "util/lp/lp_core_solver_base.h" #include "util/lp/core_solver_pretty_printer.h" #include "util/lp/numeric_pair.h" -namespace lean { +namespace lp { template @@ -148,7 +163,7 @@ template void core_solver_pretty_printer::adjust_ case column_type::free_column: break; default: - lean_assert(false); + SASSERT(false); break; } } @@ -357,7 +372,7 @@ template void core_solver_pretty_printer::print_g unsigned width = m_column_widths[col]; string s = row[col]; int number_of_blanks = width - static_cast(s.size()); - lean_assert(number_of_blanks >= 0); + SASSERT(number_of_blanks >= 0); print_blanks(number_of_blanks, m_out); m_out << s << ' '; if (col < row.size() - 1) { @@ -368,7 +383,7 @@ template void core_solver_pretty_printer::print_g string rs = T_to_string(rst); int nb = m_rs_width - static_cast(rs.size()); - lean_assert(nb >= 0); + SASSERT(nb >= 0); print_blanks(nb + 1, m_out); m_out << rs << std::endl; } diff --git a/src/util/lp/core_solver_pretty_printer_instances.cpp b/src/util/lp/core_solver_pretty_printer_instances.cpp index cfa72f725..0bd7f5559 100644 --- a/src/util/lp/core_solver_pretty_printer_instances.cpp +++ b/src/util/lp/core_solver_pretty_printer_instances.cpp @@ -1,15 +1,30 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/numeric_pair.h" #include "util/lp/core_solver_pretty_printer.hpp" -template lean::core_solver_pretty_printer::core_solver_pretty_printer(lean::lp_core_solver_base &, std::ostream & out); -template void lean::core_solver_pretty_printer::print(); -template lean::core_solver_pretty_printer::~core_solver_pretty_printer(); -template lean::core_solver_pretty_printer::core_solver_pretty_printer(lean::lp_core_solver_base &, std::ostream & out); -template void lean::core_solver_pretty_printer::print(); -template lean::core_solver_pretty_printer::~core_solver_pretty_printer(); -template lean::core_solver_pretty_printer >::core_solver_pretty_printer(lean::lp_core_solver_base > &, std::ostream & out); -template lean::core_solver_pretty_printer >::~core_solver_pretty_printer(); -template void lean::core_solver_pretty_printer >::print(); +template lp::core_solver_pretty_printer::core_solver_pretty_printer(lp::lp_core_solver_base &, std::ostream & out); +template void lp::core_solver_pretty_printer::print(); +template lp::core_solver_pretty_printer::~core_solver_pretty_printer(); +template lp::core_solver_pretty_printer::core_solver_pretty_printer(lp::lp_core_solver_base &, std::ostream & out); +template void lp::core_solver_pretty_printer::print(); +template lp::core_solver_pretty_printer::~core_solver_pretty_printer(); +template lp::core_solver_pretty_printer >::core_solver_pretty_printer(lp::lp_core_solver_base > &, std::ostream & out); +template lp::core_solver_pretty_printer >::~core_solver_pretty_printer(); +template void lp::core_solver_pretty_printer >::print(); diff --git a/src/util/lp/dense_matrix.h b/src/util/lp/dense_matrix.h index 233f74016..6b157ffd4 100644 --- a/src/util/lp/dense_matrix.h +++ b/src/util/lp/dense_matrix.h @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG #include "util/vector.h" #include "util/lp/matrix.h" -namespace lean { +namespace lp { // used for debugging purposes only template class dense_matrix: public matrix { @@ -31,7 +46,7 @@ public: dense_matrix(unsigned m, unsigned n); dense_matrix operator*=(matrix const & a) { - lean_assert(column_count() == a.row_count()); + SASSERT(column_count() == a.row_count()); dense_matrix c(row_count(), a.column_count()); for (unsigned i = 0; i < row_count(); i++) { for (unsigned j = 0; j < a.column_count(); j++) { diff --git a/src/util/lp/dense_matrix.hpp b/src/util/lp/dense_matrix.hpp index e42d9e3a4..a1f815109 100644 --- a/src/util/lp/dense_matrix.hpp +++ b/src/util/lp/dense_matrix.hpp @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lp_settings.h" -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG #include "util/vector.h" #include "util/lp/numeric_pair.h" #include "util/lp/dense_matrix.h" -namespace lean { +namespace lp { template void print_vector(const vector & t, std::ostream & out); template dense_matrix::dense_matrix(unsigned m, unsigned n) : m_m(m), m_n(n), m_values(m * n, numeric_traits::zero()) { } @@ -170,7 +185,7 @@ template void dense_matrix::multiply_row_by_const template dense_matrix operator* (matrix & a, matrix & b){ - lean_assert(a.column_count() == b.row_count()); + SASSERT(a.column_count() == b.row_count()); dense_matrix ret(a.row_count(), b.column_count()); for (unsigned i = 0; i < ret.m_m; i++) for (unsigned j = 0; j< ret.m_n; j++) { diff --git a/src/util/lp/dense_matrix_instances.cpp b/src/util/lp/dense_matrix_instances.cpp index 95ba01801..54b0d15d6 100644 --- a/src/util/lp/dense_matrix_instances.cpp +++ b/src/util/lp/dense_matrix_instances.cpp @@ -1,25 +1,40 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lp_settings.h" #include "util/lp/dense_matrix.hpp" -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG #include "util/vector.h" -template lean::dense_matrix lean::operator*(lean::matrix&, lean::matrix&); -template void lean::dense_matrix::apply_from_left(vector &); -template lean::dense_matrix::dense_matrix(lean::matrix const*); -template lean::dense_matrix::dense_matrix(unsigned int, unsigned int); -template lean::dense_matrix& lean::dense_matrix::operator=(lean::dense_matrix const&); -template lean::dense_matrix::dense_matrix(unsigned int, unsigned int); -template lean::dense_matrix >::dense_matrix(lean::matrix > const*); -template void lean::dense_matrix >::apply_from_left(vector&); -template lean::dense_matrix lean::operator*(lean::matrix&, lean::matrix&); -template lean::dense_matrix & lean::dense_matrix::operator=(lean::dense_matrix const&); -template lean::dense_matrix >::dense_matrix(unsigned int, unsigned int); -template lean::dense_matrix >& lean::dense_matrix >::operator=(lean::dense_matrix > const&); -template lean::dense_matrix > lean::operator* >(lean::matrix >&, lean::matrix >&); -template void lean::dense_matrix >::apply_from_right( vector< lean::mpq> &); -template void lean::dense_matrix::apply_from_right(class vector &); -template void lean::dense_matrix::apply_from_left(vector&); +template lp::dense_matrix lp::operator*(lp::matrix&, lp::matrix&); +template void lp::dense_matrix::apply_from_left(vector &); +template lp::dense_matrix::dense_matrix(lp::matrix const*); +template lp::dense_matrix::dense_matrix(unsigned int, unsigned int); +template lp::dense_matrix& lp::dense_matrix::operator=(lp::dense_matrix const&); +template lp::dense_matrix::dense_matrix(unsigned int, unsigned int); +template lp::dense_matrix >::dense_matrix(lp::matrix > const*); +template void lp::dense_matrix >::apply_from_left(vector&); +template lp::dense_matrix lp::operator*(lp::matrix&, lp::matrix&); +template lp::dense_matrix & lp::dense_matrix::operator=(lp::dense_matrix const&); +template lp::dense_matrix >::dense_matrix(unsigned int, unsigned int); +template lp::dense_matrix >& lp::dense_matrix >::operator=(lp::dense_matrix > const&); +template lp::dense_matrix > lp::operator* >(lp::matrix >&, lp::matrix >&); +template void lp::dense_matrix >::apply_from_right( vector< lp::mpq> &); +template void lp::dense_matrix::apply_from_right(class vector &); +template void lp::dense_matrix::apply_from_left(vector&); #endif diff --git a/src/util/lp/eta_matrix.h b/src/util/lp/eta_matrix.h index 51b015066..6c30e2146 100644 --- a/src/util/lp/eta_matrix.h +++ b/src/util/lp/eta_matrix.h @@ -1,32 +1,47 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/lp/tail_matrix.h" #include "util/lp/permutation_matrix.h" -namespace lean { +namespace lp { // This is the sum of a unit matrix and a one-column matrix template class eta_matrix : public tail_matrix { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned m_length; #endif unsigned m_column_index; public: sparse_vector m_column_vector; T m_diagonal_element; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG eta_matrix(unsigned column_index, unsigned length): #else eta_matrix(unsigned column_index): #endif -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG m_length(length), #endif m_column_index(column_index) {} @@ -61,7 +76,7 @@ public: void push_back(unsigned row_index, T val ) { - lean_assert(row_index != m_column_index); + SASSERT(row_index != m_column_index); m_column_vector.push_back(row_index, val); } @@ -69,7 +84,7 @@ public: void apply_from_right(indexed_vector & w); T get_elem(unsigned i, unsigned j) const; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned row_count() const { return m_length; } unsigned column_count() const { return m_length; } void set_number_of_rows(unsigned m) { m_length = m; } diff --git a/src/util/lp/eta_matrix.hpp b/src/util/lp/eta_matrix.hpp index 142a408d1..ae4ed712e 100644 --- a/src/util/lp/eta_matrix.hpp +++ b/src/util/lp/eta_matrix.hpp @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/lp/eta_matrix.h" -namespace lean { +namespace lp { // This is the sum of a unit matrix and a one-column matrix template @@ -49,7 +64,7 @@ apply_from_left_local(indexed_vector & w, lp_settings & settings) { } template void eta_matrix::apply_from_right(vector & w) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // auto clone_w = clone_vector(w, get_number_of_rows()); // deb.apply_from_right(clone_w); @@ -59,8 +74,8 @@ void eta_matrix::apply_from_right(vector & w) { t += w[it.first] * it.second; } w[m_column_index] = t; -#ifdef LEAN_DEBUG - // lean_assert(vectors_are_equal(clone_w, w, get_number_of_rows())); +#ifdef Z3DEBUG + // SASSERT(vectors_are_equal(clone_w, w, get_number_of_rows())); // delete clone_w; #endif } @@ -68,7 +83,7 @@ template void eta_matrix::apply_from_right(indexed_vector & w) { if (w.m_index.size() == 0) return; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // vector wcopy(w.m_data); // apply_from_right(wcopy); #endif @@ -99,12 +114,12 @@ void eta_matrix::apply_from_right(indexed_vector & w) { } } -#ifdef LEAN_DEBUG - // lean_assert(w.is_OK()); - // lean_assert(vectors_are_equal(wcopy, w.m_data)); +#ifdef Z3DEBUG + // SASSERT(w.is_OK()); + // SASSERT(vectors_are_equal(wcopy, w.m_data)); #endif } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template T eta_matrix::get_elem(unsigned i, unsigned j) const { if (j == m_column_index){ @@ -120,7 +135,7 @@ T eta_matrix::get_elem(unsigned i, unsigned j) const { template void eta_matrix::conjugate_by_permutation(permutation_matrix & p) { // this = p * this * p(-1) -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // auto rev = p.get_reverse(); // auto deb = ((*this) * rev); // deb = p * deb; @@ -129,8 +144,8 @@ void eta_matrix::conjugate_by_permutation(permutation_matrix & p) { for (auto & pair : m_column_vector.m_data) { pair.first = p.get_rev(pair.first); } -#ifdef LEAN_DEBUG - // lean_assert(deb == *this); +#ifdef Z3DEBUG + // SASSERT(deb == *this); #endif } } diff --git a/src/util/lp/eta_matrix_instances.cpp b/src/util/lp/eta_matrix_instances.cpp index d57d43fed..87e12c913 100644 --- a/src/util/lp/eta_matrix_instances.cpp +++ b/src/util/lp/eta_matrix_instances.cpp @@ -1,28 +1,43 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/numeric_pair.h" #include "util/lp/eta_matrix.hpp" -#ifdef LEAN_DEBUG -template double lean::eta_matrix::get_elem(unsigned int, unsigned int) const; -template lean::mpq lean::eta_matrix::get_elem(unsigned int, unsigned int) const; -template lean::mpq lean::eta_matrix >::get_elem(unsigned int, unsigned int) const; +#ifdef Z3DEBUG +template double lp::eta_matrix::get_elem(unsigned int, unsigned int) const; +template lp::mpq lp::eta_matrix::get_elem(unsigned int, unsigned int) const; +template lp::mpq lp::eta_matrix >::get_elem(unsigned int, unsigned int) const; #endif -template void lean::eta_matrix::apply_from_left(vector&, lean::lp_settings&); -template void lean::eta_matrix::apply_from_right(vector&); -template void lean::eta_matrix::conjugate_by_permutation(lean::permutation_matrix&); -template void lean::eta_matrix::apply_from_left(vector&, lean::lp_settings&); -template void lean::eta_matrix::apply_from_right(vector&); -template void lean::eta_matrix::conjugate_by_permutation(lean::permutation_matrix&); -template void lean::eta_matrix >::apply_from_left(vector >&, lean::lp_settings&); -template void lean::eta_matrix >::apply_from_right(vector&); -template void lean::eta_matrix >::conjugate_by_permutation(lean::permutation_matrix >&); -template void lean::eta_matrix::apply_from_left_local(lean::indexed_vector&, lean::lp_settings&); -template void lean::eta_matrix::apply_from_left_local(lean::indexed_vector&, lean::lp_settings&); -template void lean::eta_matrix >::apply_from_left_local(lean::indexed_vector&, lean::lp_settings&); -template void lean::eta_matrix >::apply_from_right(lean::indexed_vector&); -template void lean::eta_matrix::apply_from_right(lean::indexed_vector&); -template void lean::eta_matrix::apply_from_right(lean::indexed_vector&); +template void lp::eta_matrix::apply_from_left(vector&, lp::lp_settings&); +template void lp::eta_matrix::apply_from_right(vector&); +template void lp::eta_matrix::conjugate_by_permutation(lp::permutation_matrix&); +template void lp::eta_matrix::apply_from_left(vector&, lp::lp_settings&); +template void lp::eta_matrix::apply_from_right(vector&); +template void lp::eta_matrix::conjugate_by_permutation(lp::permutation_matrix&); +template void lp::eta_matrix >::apply_from_left(vector >&, lp::lp_settings&); +template void lp::eta_matrix >::apply_from_right(vector&); +template void lp::eta_matrix >::conjugate_by_permutation(lp::permutation_matrix >&); +template void lp::eta_matrix::apply_from_left_local(lp::indexed_vector&, lp::lp_settings&); +template void lp::eta_matrix::apply_from_left_local(lp::indexed_vector&, lp::lp_settings&); +template void lp::eta_matrix >::apply_from_left_local(lp::indexed_vector&, lp::lp_settings&); +template void lp::eta_matrix >::apply_from_right(lp::indexed_vector&); +template void lp::eta_matrix::apply_from_right(lp::indexed_vector&); +template void lp::eta_matrix::apply_from_right(lp::indexed_vector&); diff --git a/src/util/lp/hash_helper.h b/src/util/lp/hash_helper.h index 6fe31d5cd..ab5fa844b 100644 --- a/src/util/lp/hash_helper.h +++ b/src/util/lp/hash_helper.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include #include @@ -12,8 +27,8 @@ #endif namespace std { template<> -struct hash { - inline size_t operator()(const lean::mpq & v) const { +struct hash { + inline size_t operator()(const lp::mpq & v) const { return v.hash(); } }; diff --git a/src/util/lp/implied_bound.h b/src/util/lp/implied_bound.h index 9583e3cd8..f1c711ffa 100644 --- a/src/util/lp/implied_bound.h +++ b/src/util/lp/implied_bound.h @@ -1,11 +1,26 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/lp_settings.h" #include "util/lp/lar_constraints.h" -namespace lean { +namespace lp { struct implied_bound { mpq m_bound; unsigned m_j; // the column for which the bound has been found diff --git a/src/util/lp/indexed_value.h b/src/util/lp/indexed_value.h index 7963dfdf9..216a6f953 100644 --- a/src/util/lp/indexed_value.h +++ b/src/util/lp/indexed_value.h @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once -namespace lean { +namespace lp { template class indexed_value { public: @@ -41,7 +56,7 @@ public: m_value = val; } }; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool check_vector_for_small_values(indexed_vector & w, lp_settings & settings) { for (unsigned i : w.m_index) { diff --git a/src/util/lp/indexed_vector.h b/src/util/lp/indexed_vector.h index 6e6a6009b..3b1258ed7 100644 --- a/src/util/lp/indexed_vector.h +++ b/src/util/lp/indexed_vector.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -11,7 +26,7 @@ #include "util/lp/lp_utils.h" #include "util/lp/lp_settings.h" #include -namespace lean { +namespace lp { template void print_vector(const vector & t, std::ostream & out); template void print_vector(const buffer & t, std::ostream & out); @@ -76,7 +91,7 @@ public: void set_value(const T& value, unsigned index); void set_value_as_in_dictionary(unsigned index) { - lean_assert(index < m_data.size()); + SASSERT(index < m_data.size()); T & loc = m_data[index]; if (is_zero(loc)) { m_index.push_back(index); @@ -161,7 +176,7 @@ public: } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG bool is_OK() const; void print(std::ostream & out); #endif diff --git a/src/util/lp/indexed_vector.hpp b/src/util/lp/indexed_vector.hpp index 64e329adc..73055d6da 100644 --- a/src/util/lp/indexed_vector.hpp +++ b/src/util/lp/indexed_vector.hpp @@ -1,11 +1,26 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include "util/lp/indexed_vector.h" #include "util/lp/lp_settings.h" -namespace lean { +namespace lp { template void print_vector(const vector & t, std::ostream & out) { @@ -41,13 +56,13 @@ template void indexed_vector::resize(unsigned data_size) { clear(); m_data.resize(data_size, numeric_traits::zero()); - lean_assert(is_OK()); + SASSERT(is_OK()); } template void indexed_vector::set_value(const T& value, unsigned index) { m_data[index] = value; - lean_assert(std::find(m_index.begin(), m_index.end(), index) == m_index.end()); + SASSERT(std::find(m_index.begin(), m_index.end(), index) == m_index.end()); m_index.push_back(index); } @@ -70,7 +85,7 @@ void indexed_vector::erase_from_index(unsigned j) { m_index.erase(it); } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool indexed_vector::is_OK() const { return true; diff --git a/src/util/lp/indexed_vector_instances.cpp b/src/util/lp/indexed_vector_instances.cpp index 6f17a894f..ee078f021 100644 --- a/src/util/lp/indexed_vector_instances.cpp +++ b/src/util/lp/indexed_vector_instances.cpp @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include "util/lp/indexed_vector.hpp" -namespace lean { +namespace lp { template void indexed_vector::clear(); template void indexed_vector::clear_all(); template void indexed_vector::erase_from_index(unsigned int); @@ -17,20 +32,20 @@ template void indexed_vector::resize(unsigned int); template void indexed_vector::resize(unsigned int); template void indexed_vector::set_value(const mpq&, unsigned int); template void indexed_vector::set_value(const unsigned&, unsigned int); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool indexed_vector::is_OK() const; template bool indexed_vector::is_OK() const; -template bool indexed_vector >::is_OK() const; -template void lean::indexed_vector< lean::mpq>::print(std::basic_ostream > &); -template void lean::indexed_vector::print(std::basic_ostream > &); -template void lean::indexed_vector >::print(std::ostream&); +template bool indexed_vector >::is_OK() const; +template void lp::indexed_vector< lp::mpq>::print(std::basic_ostream > &); +template void lp::indexed_vector::print(std::basic_ostream > &); +template void lp::indexed_vector >::print(std::ostream&); #endif } -template void lean::print_vector(vector const&, std::ostream&); -template void lean::print_vector(vector const&, std::ostream&); -template void lean::print_vector(vector const&, std::ostream&); -template void lean::print_vector >(vector> const&, std::ostream&); -template void lean::indexed_vector::resize(unsigned int); -template void lean::print_vector< lean::mpq>(vector< lean::mpq> const &, std::basic_ostream > &); -template void lean::print_vector >(vector> const&, std::ostream&); -template void lean::indexed_vector >::erase_from_index(unsigned int); +template void lp::print_vector(vector const&, std::ostream&); +template void lp::print_vector(vector const&, std::ostream&); +template void lp::print_vector(vector const&, std::ostream&); +template void lp::print_vector >(vector> const&, std::ostream&); +template void lp::indexed_vector::resize(unsigned int); +template void lp::print_vector< lp::mpq>(vector< lp::mpq> const &, std::basic_ostream > &); +template void lp::print_vector >(vector> const&, std::ostream&); +template void lp::indexed_vector >::erase_from_index(unsigned int); diff --git a/src/util/lp/init_lar_solver.h b/src/util/lp/init_lar_solver.h index db5a6ed4c..5d78c3ba7 100644 --- a/src/util/lp/init_lar_solver.h +++ b/src/util/lp/init_lar_solver.h @@ -1,9 +1,24 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation -// here we are inside lean::lar_solver class +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ + +// here we are inside lp::lar_solver class bool strategy_is_undecided() const { return m_settings.simplex_strategy() == simplex_strategy_enum::undecided; @@ -11,7 +26,7 @@ bool strategy_is_undecided() const { var_index add_var(unsigned ext_j) { var_index i; - lean_assert (ext_j < m_terms_start_index); + SASSERT (ext_j < m_terms_start_index); if (ext_j >= m_terms_start_index) throw 0; // todo : what is the right way to exit? @@ -19,19 +34,19 @@ var_index add_var(unsigned ext_j) { if (try_get_val(m_ext_vars_to_columns, ext_j, i)) { return i; } - lean_assert(m_vars_to_ul_pairs.size() == A_r().column_count()); + SASSERT(m_vars_to_ul_pairs.size() == A_r().column_count()); i = A_r().column_count(); m_vars_to_ul_pairs.push_back (ul_pair(static_cast(-1))); add_non_basic_var_to_core_fields(ext_j); - lean_assert(sizes_are_correct()); + SASSERT(sizes_are_correct()); return i; } void register_new_ext_var_index(unsigned ext_v) { - lean_assert(!contains(m_ext_vars_to_columns, ext_v)); + SASSERT(!contains(m_ext_vars_to_columns, ext_v)); unsigned j = static_cast(m_ext_vars_to_columns.size()); m_ext_vars_to_columns[ext_v] = j; - lean_assert(m_columns_to_ext_vars_or_term_indices.size() == j); + SASSERT(m_columns_to_ext_vars_or_term_indices.size() == j); m_columns_to_ext_vars_or_term_indices.push_back(ext_v); } @@ -47,12 +62,12 @@ void add_non_basic_var_to_core_fields(unsigned ext_j) { void add_new_var_to_core_fields_for_doubles(bool register_in_basis) { unsigned j = A_d().column_count(); A_d().add_column(); - lean_assert(m_mpq_lar_core_solver.m_d_x.size() == j); - // lean_assert(m_mpq_lar_core_solver.m_d_low_bounds.size() == j && m_mpq_lar_core_solver.m_d_upper_bounds.size() == j); // restore later + SASSERT(m_mpq_lar_core_solver.m_d_x.size() == j); + // SASSERT(m_mpq_lar_core_solver.m_d_low_bounds.size() == j && m_mpq_lar_core_solver.m_d_upper_bounds.size() == j); // restore later m_mpq_lar_core_solver.m_d_x.resize(j + 1 ); m_mpq_lar_core_solver.m_d_low_bounds.resize(j + 1); m_mpq_lar_core_solver.m_d_upper_bounds.resize(j + 1); - lean_assert(m_mpq_lar_core_solver.m_d_heading.size() == j); // as A().column_count() on the entry to the method + SASSERT(m_mpq_lar_core_solver.m_d_heading.size() == j); // as A().column_count() on the entry to the method if (register_in_basis) { A_d().add_row(); m_mpq_lar_core_solver.m_d_heading.push_back(m_mpq_lar_core_solver.m_d_basis.size()); @@ -66,15 +81,15 @@ void add_new_var_to_core_fields_for_doubles(bool register_in_basis) { void add_new_var_to_core_fields_for_mpq(bool register_in_basis) { unsigned j = A_r().column_count(); A_r().add_column(); - lean_assert(m_mpq_lar_core_solver.m_r_x.size() == j); - // lean_assert(m_mpq_lar_core_solver.m_r_low_bounds.size() == j && m_mpq_lar_core_solver.m_r_upper_bounds.size() == j); // restore later + SASSERT(m_mpq_lar_core_solver.m_r_x.size() == j); + // SASSERT(m_mpq_lar_core_solver.m_r_low_bounds.size() == j && m_mpq_lar_core_solver.m_r_upper_bounds.size() == j); // restore later m_mpq_lar_core_solver.m_r_x.resize(j + 1); m_mpq_lar_core_solver.m_r_low_bounds.increase_size_by_one(); m_mpq_lar_core_solver.m_r_upper_bounds.increase_size_by_one(); m_mpq_lar_core_solver.m_r_solver.m_inf_set.increase_size_by_one(); m_mpq_lar_core_solver.m_r_solver.m_costs.resize(j + 1); m_mpq_lar_core_solver.m_r_solver.m_d.resize(j + 1); - lean_assert(m_mpq_lar_core_solver.m_r_heading.size() == j); // as A().column_count() on the entry to the method + SASSERT(m_mpq_lar_core_solver.m_r_heading.size() == j); // as A().column_count() on the entry to the method if (register_in_basis) { A_r().add_row(); m_mpq_lar_core_solver.m_r_heading.push_back(m_mpq_lar_core_solver.m_r_basis.size()); @@ -110,14 +125,14 @@ var_index add_term(const vector> & coeffs, if (m_settings.bound_propagation()) m_rows_with_changed_bounds.insert(A_r().row_count() - 1); } - lean_assert(m_ext_vars_to_columns.size() == A_r().column_count()); + SASSERT(m_ext_vars_to_columns.size() == A_r().column_count()); return ret; } void add_row_for_term(const lar_term * term, unsigned term_ext_index) { - lean_assert(sizes_are_correct()); + SASSERT(sizes_are_correct()); add_row_from_term_no_constraint(term, term_ext_index); - lean_assert(sizes_are_correct()); + SASSERT(sizes_are_correct()); } void add_row_from_term_no_constraint(const lar_term * term, unsigned term_ext_index) { @@ -142,7 +157,7 @@ void add_row_from_term_no_constraint(const lar_term * term, unsigned term_ext_in void add_basic_var_to_core_fields() { bool use_lu = m_mpq_lar_core_solver.need_to_presolve_with_double_solver(); - lean_assert(!use_lu || A_r().column_count() == A_d().column_count()); + SASSERT(!use_lu || A_r().column_count() == A_d().column_count()); m_mpq_lar_core_solver.m_column_types.push_back(column_type::free_column); m_columns_with_changed_bound.increase_size_by_one(); m_rows_with_changed_bounds.increase_size_by_one(); @@ -160,7 +175,7 @@ constraint_index add_var_bound(var_index j, lconstraint_kind kind, const mpq & r } else { add_var_bound_on_constraint_for_term(j, kind, right_side, ci); } - lean_assert(sizes_are_correct()); + SASSERT(sizes_are_correct()); return ci; } @@ -182,12 +197,12 @@ void update_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq update_fixed_column_type_and_bound(j, kind, right_side, constr_index); break; default: - lean_assert(false); // cannot be here + SASSERT(false); // cannot be here } } void add_var_bound_on_constraint_for_term(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) { - lean_assert(is_term(j)); + SASSERT(is_term(j)); unsigned adjusted_term_index = adjust_term_index(j); unsigned term_j; if (try_get_val(m_ext_vars_to_columns, j, term_j)) { @@ -208,11 +223,11 @@ void add_constraint_from_term_and_create_new_column_row(unsigned term_j, const l unsigned j = A_r().column_count() - 1; update_column_type_and_bound(j, kind, right_side - term->m_v, m_constraints.size()); m_constraints.push_back(new lar_term_constraint(term, kind, right_side)); - lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); + SASSERT(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); } void decide_on_strategy_and_adjust_initial_state() { - lean_assert(strategy_is_undecided()); + SASSERT(strategy_is_undecided()); if (m_vars_to_ul_pairs.size() > m_settings.column_number_threshold_for_using_lu_in_lar_solver) { m_settings.simplex_strategy() = simplex_strategy_enum::lu; } else { @@ -230,7 +245,7 @@ void adjust_initial_state() { adjust_initial_state_for_tableau_rows(); break; case simplex_strategy_enum::tableau_costs: - lean_assert(false); // not implemented + SASSERT(false); // not implemented case simplex_strategy_enum::undecided: adjust_initial_state_for_tableau_rows(); break; @@ -249,12 +264,12 @@ void adjust_initial_state_for_lu() { /* unsigned j = A_d().column_count(); A_d().add_column(); - lean_assert(m_mpq_lar_core_solver.m_d_x.size() == j); - // lean_assert(m_mpq_lar_core_solver.m_d_low_bounds.size() == j && m_mpq_lar_core_solver.m_d_upper_bounds.size() == j); // restore later + SASSERT(m_mpq_lar_core_solver.m_d_x.size() == j); + // SASSERT(m_mpq_lar_core_solver.m_d_low_bounds.size() == j && m_mpq_lar_core_solver.m_d_upper_bounds.size() == j); // restore later m_mpq_lar_core_solver.m_d_x.resize(j + 1 ); m_mpq_lar_core_solver.m_d_low_bounds.resize(j + 1); m_mpq_lar_core_solver.m_d_upper_bounds.resize(j + 1); - lean_assert(m_mpq_lar_core_solver.m_d_heading.size() == j); // as A().column_count() on the entry to the method + SASSERT(m_mpq_lar_core_solver.m_d_heading.size() == j); // as A().column_count() on the entry to the method if (register_in_basis) { A_d().add_row(); m_mpq_lar_core_solver.m_d_heading.push_back(m_mpq_lar_core_solver.m_d_basis.size()); @@ -275,13 +290,13 @@ void adjust_initial_state_for_tableau_rows() { // this fills the last row of A_d and sets the basis column: -1 in the last column of the row void fill_last_row_of_A_d(static_matrix & A, const lar_term* ls) { - lean_assert(A.row_count() > 0); - lean_assert(A.column_count() > 0); + SASSERT(A.row_count() > 0); + SASSERT(A.column_count() > 0); unsigned last_row = A.row_count() - 1; - lean_assert(A.m_rows[last_row].empty()); + SASSERT(A.m_rows[last_row].empty()); for (auto & t : ls->m_coeffs) { - lean_assert(!is_zero(t.second)); + SASSERT(!is_zero(t.second)); var_index j = t.first; A.set(last_row, j, - t.second.get_double()); } @@ -297,8 +312,8 @@ void update_free_column_type_and_bound(var_index j, lconstraint_kind kind, const y_of_bound = -1; case LE: m_mpq_lar_core_solver.m_column_types[j] = column_type::upper_bound; - lean_assert(m_mpq_lar_core_solver.m_column_types()[j] == column_type::upper_bound); - lean_assert(m_mpq_lar_core_solver.m_r_upper_bounds.size() > j); + SASSERT(m_mpq_lar_core_solver.m_column_types()[j] == column_type::upper_bound); + SASSERT(m_mpq_lar_core_solver.m_r_upper_bounds.size() > j); { auto up = numeric_pair(right_side, y_of_bound); m_mpq_lar_core_solver.m_r_upper_bounds[j] = up; @@ -309,7 +324,7 @@ void update_free_column_type_and_bound(var_index j, lconstraint_kind kind, const y_of_bound = 1; case GE: m_mpq_lar_core_solver.m_column_types[j] = column_type::low_bound; - lean_assert(m_mpq_lar_core_solver.m_r_upper_bounds.size() > j); + SASSERT(m_mpq_lar_core_solver.m_r_upper_bounds.size() > j); { auto low = numeric_pair(right_side, y_of_bound); m_mpq_lar_core_solver.m_r_low_bounds[j] = low; @@ -324,14 +339,14 @@ void update_free_column_type_and_bound(var_index j, lconstraint_kind kind, const break; default: - lean_unreachable(); + SASSERT(false); } m_columns_with_changed_bound.insert(j); } void update_upper_bound_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) { - lean_assert(m_mpq_lar_core_solver.m_column_types()[j] == column_type::upper_bound); + SASSERT(m_mpq_lar_core_solver.m_column_types()[j] == column_type::upper_bound); mpq y_of_bound(0); switch (kind) { case LT: @@ -382,13 +397,13 @@ void update_upper_bound_column_type_and_bound(var_index j, lconstraint_kind kind break; default: - lean_unreachable(); + SASSERT(false); } } void update_boxed_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) { - lean_assert(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::boxed && m_mpq_lar_core_solver.m_r_low_bounds()[j] < m_mpq_lar_core_solver.m_r_upper_bounds()[j])); + SASSERT(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::boxed && m_mpq_lar_core_solver.m_r_low_bounds()[j] < m_mpq_lar_core_solver.m_r_upper_bounds()[j])); mpq y_of_bound(0); switch (kind) { case LT: @@ -404,7 +419,7 @@ void update_boxed_column_type_and_bound(var_index j, lconstraint_kind kind, cons if (up < m_mpq_lar_core_solver.m_r_low_bounds[j]) { m_status = INFEASIBLE; - lean_assert(false); + SASSERT(false); m_infeasible_column_index = j; } else { if (m_mpq_lar_core_solver.m_r_low_bounds()[j] == m_mpq_lar_core_solver.m_r_upper_bounds()[j]) @@ -453,12 +468,12 @@ void update_boxed_column_type_and_bound(var_index j, lconstraint_kind kind, cons } default: - lean_unreachable(); + SASSERT(false); } } void update_low_bound_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) { - lean_assert(m_mpq_lar_core_solver.m_column_types()[j] == column_type::low_bound); + SASSERT(m_mpq_lar_core_solver.m_column_types()[j] == column_type::low_bound); mpq y_of_bound(0); switch (kind) { case LT: @@ -508,14 +523,14 @@ void update_low_bound_column_type_and_bound(var_index j, lconstraint_kind kind, } default: - lean_unreachable(); + SASSERT(false); } } void update_fixed_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) { - lean_assert(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::fixed && m_mpq_lar_core_solver.m_r_low_bounds()[j] == m_mpq_lar_core_solver.m_r_upper_bounds()[j])); - lean_assert(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_r_low_bounds()[j].y.is_zero() && m_mpq_lar_core_solver.m_r_upper_bounds()[j].y.is_zero())); + SASSERT(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::fixed && m_mpq_lar_core_solver.m_r_low_bounds()[j] == m_mpq_lar_core_solver.m_r_upper_bounds()[j])); + SASSERT(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_r_low_bounds()[j].y.is_zero() && m_mpq_lar_core_solver.m_r_upper_bounds()[j].y.is_zero())); auto v = numeric_pair(right_side, mpq(0)); mpq y_of_bound(0); @@ -569,7 +584,7 @@ void update_fixed_column_type_and_bound(var_index j, lconstraint_kind kind, cons } default: - lean_unreachable(); + SASSERT(false); } } diff --git a/src/util/lp/int_set.h b/src/util/lp/int_set.h index 0619facd8..698b8bc49 100644 --- a/src/util/lp/int_set.h +++ b/src/util/lp/int_set.h @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/lp/indexed_vector.h" #include -namespace lean { +namespace lp { // serves at a set of non-negative integers smaller than the set size class int_set { vector m_data; @@ -20,7 +35,7 @@ public: return m_data[j] >= 0; } void insert(unsigned j) { - lean_assert(j < m_data.size()); + SASSERT(j < m_data.size()); if (contains(j)) return; m_data[j] = m_index.size(); m_index.push_back(j); diff --git a/src/util/lp/iterator_on_column.h b/src/util/lp/iterator_on_column.h index 215514b39..5bb43f4c6 100644 --- a/src/util/lp/iterator_on_column.h +++ b/src/util/lp/iterator_on_column.h @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/linear_combination_iterator.h" #include "util/lp/static_matrix.h" #include "util/lp/lar_term.h" -namespace lean { +namespace lp { template struct iterator_on_column:linear_combination_iterator { const vector& m_column; // the offset in term coeffs diff --git a/src/util/lp/iterator_on_indexed_vector.h b/src/util/lp/iterator_on_indexed_vector.h index 532b62617..2c8daf83b 100644 --- a/src/util/lp/iterator_on_indexed_vector.h +++ b/src/util/lp/iterator_on_indexed_vector.h @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/linear_combination_iterator.h" -namespace lean { +namespace lp { template struct iterator_on_indexed_vector:linear_combination_iterator { const indexed_vector & m_v; diff --git a/src/util/lp/iterator_on_pivot_row.h b/src/util/lp/iterator_on_pivot_row.h index 1a9381a70..8aa498477 100644 --- a/src/util/lp/iterator_on_pivot_row.h +++ b/src/util/lp/iterator_on_pivot_row.h @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/iterator_on_indexed_vector.h" -namespace lean { +namespace lp { template struct iterator_on_pivot_row:linear_combination_iterator { bool m_basis_returned; diff --git a/src/util/lp/iterator_on_row.h b/src/util/lp/iterator_on_row.h index 96a1a8cf3..1ac5b66bc 100644 --- a/src/util/lp/iterator_on_row.h +++ b/src/util/lp/iterator_on_row.h @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/linear_combination_iterator.h" -namespace lean { +namespace lp { template struct iterator_on_row:linear_combination_iterator { const vector> & m_row; diff --git a/src/util/lp/iterator_on_term_with_basis_var.h b/src/util/lp/iterator_on_term_with_basis_var.h index 3dd217103..e566b92b5 100644 --- a/src/util/lp/iterator_on_term_with_basis_var.h +++ b/src/util/lp/iterator_on_term_with_basis_var.h @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/linear_combination_iterator.h" #include "util/lp/numeric_pair.h" #include "util/lp/lar_term.h" -namespace lean { +namespace lp { struct iterator_on_term_with_basis_var:linear_combination_iterator { const lar_term & m_term; std::unordered_map::const_iterator m_i; // the offset in term coeffs diff --git a/src/util/lp/lar_constraints.h b/src/util/lp/lar_constraints.h index ee0864a4e..7b573bab7 100644 --- a/src/util/lp/lar_constraints.h +++ b/src/util/lp/lar_constraints.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -12,7 +27,7 @@ #include "util/lp/lp_utils.h" #include "util/lp/ul_pair.h" #include "util/lp/lar_term.h" -namespace lean { +namespace lp { inline lconstraint_kind flip_kind(lconstraint_kind t) { return static_cast( - static_cast(t)); } @@ -25,7 +40,7 @@ inline std::string lconstraint_kind_string(lconstraint_kind t) { case GT: return std::string(">"); case EQ: return std::string("="); } - lean_unreachable(); + SASSERT(false); return std::string(); // it is unreachable } @@ -74,7 +89,7 @@ public: : lar_base_constraint(kind, right_side), m_coeffs(left_side) {} lar_constraint(const lar_base_constraint & c) { - lean_assert(false); // should not be called : todo! + SASSERT(false); // should not be called : todo! } unsigned size() const { diff --git a/src/util/lp/lar_core_solver.h b/src/util/lp/lar_core_solver.h index 7e402d726..61b0d9b38 100644 --- a/src/util/lp/lar_core_solver.h +++ b/src/util/lp/lar_core_solver.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include @@ -18,7 +33,7 @@ #include "util/lp/iterator_on_column.h" #include "util/lp/iterator_on_indexed_vector.h" #include "util/lp/stacked_value.h" -namespace lean { +namespace lp { class lar_core_solver { // m_sign_of_entering is set to 1 if the entering variable needs @@ -168,9 +183,9 @@ public: } void push() { - lean_assert(m_r_solver.basis_heading_is_correct()); - lean_assert(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct()); - lean_assert(m_column_types.size() == m_r_A.column_count()); + SASSERT(m_r_solver.basis_heading_is_correct()); + SASSERT(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct()); + SASSERT(m_column_types.size() == m_r_A.column_count()); m_stacked_simplex_strategy = settings().simplex_strategy(); m_stacked_simplex_strategy.push(); m_column_types.push(); @@ -192,7 +207,7 @@ public: template void push_vector(stacked_vector & pushed_vector, const vector & vector) { - lean_assert(pushed_vector.size() <= vector.size()); + SASSERT(pushed_vector.size() <= vector.size()); for (unsigned i = 0; i < vector.size();i++) { if (i == pushed_vector.size()) { pushed_vector.push_back(vector[i]); @@ -242,8 +257,8 @@ public: pop_basis(k); m_stacked_simplex_strategy.pop(k); settings().simplex_strategy() = m_stacked_simplex_strategy; - lean_assert(m_r_solver.basis_heading_is_correct()); - lean_assert(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct()); + SASSERT(m_r_solver.basis_heading_is_correct()); + SASSERT(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct()); } bool need_to_presolve_with_double_solver() const { @@ -304,11 +319,11 @@ public: break; default: - lean_assert(false); + SASSERT(false); } break; default: - lean_unreachable(); + SASSERT(false); } m_r_solver.remove_column_from_inf_set(j); return true; @@ -317,7 +332,7 @@ public: void prepare_solver_x_with_signature_tableau(const lar_solution_signature & signature) { - lean_assert(m_r_solver.inf_set_is_correct()); + SASSERT(m_r_solver.inf_set_is_correct()); for (auto &t : signature) { unsigned j = t.first; if (m_r_heading[j] >= 0) @@ -332,9 +347,9 @@ public: m_r_solver.m_x[jb] -= delta * m_r_solver.m_A.get_val(cc); m_r_solver.update_column_in_inf_set(jb); } - lean_assert(m_r_solver.A_mult_x_is_off() == false); + SASSERT(m_r_solver.A_mult_x_is_off() == false); } - lean_assert(m_r_solver.inf_set_is_correct()); + SASSERT(m_r_solver.inf_set_is_correct()); } @@ -342,7 +357,7 @@ public: void prepare_solver_x_with_signature(const lar_solution_signature & signature, lp_primal_core_solver & s) { for (auto &t : signature) { unsigned j = t.first; - lean_assert(m_r_heading[j] < 0); + SASSERT(m_r_heading[j] < 0); auto pos_type = t.second; switch (pos_type) { case at_low_bound: @@ -359,7 +374,7 @@ public: case not_at_bound: switch (m_column_types[j]) { case column_type::free_column: - lean_assert(false); // unreachable + SASSERT(false); // unreachable case column_type::upper_bound: s.m_x[j] = s.m_upper_bounds[j]; break; @@ -377,15 +392,15 @@ public: s.m_x[j] = s.m_low_bounds[j]; break; default: - lean_assert(false); + SASSERT(false); } break; default: - lean_unreachable(); + SASSERT(false); } } - lean_assert(is_zero_vector(s.m_b)); + SASSERT(is_zero_vector(s.m_b)); s.solve_Ax_eq_b(); } @@ -418,7 +433,7 @@ public: // the queues of delayed indices std::queue entr_q, leav_q; auto * l = cs.m_factorization; - lean_assert(l->get_status() == LU_status::OK); + SASSERT(l->get_status() == LU_status::OK); for (unsigned i = 0; i < trace_of_basis_change.size(); i+= 2) { unsigned entering = trace_of_basis_change[i]; unsigned leaving = trace_of_basis_change[i+1]; @@ -446,8 +461,8 @@ public: continue; } } - lean_assert(cs.m_basis_heading[entering] < 0); - lean_assert(cs.m_basis_heading[leaving] >= 0); + SASSERT(cs.m_basis_heading[entering] < 0); + SASSERT(cs.m_basis_heading[leaving] >= 0); if (l->get_status() == LU_status::OK) { l->prepare_entering(entering, w); // to init vector w l->replace_column(zero_of_type(), w, cs.m_basis_heading[leaving]); @@ -471,7 +486,7 @@ public: void solve_on_signature_tableau(const lar_solution_signature & signature, const vector & changes_of_basis) { r_basis_is_OK(); - lean_assert(settings().use_tableau()); + SASSERT(settings().use_tableau()); bool r = catch_up_in_lu_tableau(changes_of_basis, m_d_solver.m_basis_heading); if (!r) { // it is the case where m_d_solver gives a degenerated basis @@ -490,10 +505,10 @@ public: return; m_r_solver.stop_tracing_basis_changes(); // and now catch up in the double solver - lean_assert(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2); + SASSERT(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2); catch_up_in_lu(m_r_solver.m_trace_of_basis_change_vector, m_r_solver.m_basis_heading, m_d_solver); } - lean_assert(r_basis_is_OK()); + SASSERT(r_basis_is_OK()); } bool adjust_x_of_column(unsigned j) { @@ -507,16 +522,16 @@ public: } m_r_solver.snap_column_to_bound_tableau(j); - lean_assert(m_r_solver.column_is_feasible(j)); + SASSERT(m_r_solver.column_is_feasible(j)); m_r_solver.m_inf_set.erase(j); */ - lean_assert(false); + SASSERT(false); return true; } bool catch_up_in_lu_tableau(const vector & trace_of_basis_change, const vector & basis_heading) { - lean_assert(r_basis_is_OK()); + SASSERT(r_basis_is_OK()); // the queues of delayed indices std::queue entr_q, leav_q; for (unsigned i = 0; i < trace_of_basis_change.size(); i+= 2) { @@ -546,47 +561,47 @@ public: continue; } } - lean_assert(m_r_solver.m_basis_heading[entering] < 0); - lean_assert(m_r_solver.m_basis_heading[leaving] >= 0); + SASSERT(m_r_solver.m_basis_heading[entering] < 0); + SASSERT(m_r_solver.m_basis_heading[leaving] >= 0); m_r_solver.change_basis_unconditionally(entering, leaving); if(!m_r_solver.pivot_column_tableau(entering, m_r_solver.m_basis_heading[entering])) { // unroll the last step m_r_solver.change_basis_unconditionally(leaving, entering); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG bool t = #endif m_r_solver.pivot_column_tableau(leaving, m_r_solver.m_basis_heading[leaving]); -#ifdef LEAN_DEBUG - lean_assert(t); +#ifdef Z3DEBUG + SASSERT(t); #endif return false; } } - lean_assert(r_basis_is_OK()); + SASSERT(r_basis_is_OK()); return true; } bool r_basis_is_OK() const { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG if (!m_r_solver.m_settings.use_tableau()) return true; for (unsigned j : m_r_solver.m_basis) { - lean_assert(m_r_solver.m_A.m_columns[j].size() == 1); - lean_assert(m_r_solver.m_A.get_val(m_r_solver.m_A.m_columns[j][0]) == one_of_type()); + SASSERT(m_r_solver.m_A.m_columns[j].size() == 1); + SASSERT(m_r_solver.m_A.get_val(m_r_solver.m_A.m_columns[j][0]) == one_of_type()); } for (unsigned j =0; j < m_r_solver.m_basis_heading.size(); j++) { if (m_r_solver.m_basis_heading[j] >= 0) continue; if (m_r_solver.m_column_types[j] == column_type::fixed) continue; - lean_assert(static_cast(- m_r_solver.m_basis_heading[j] - 1) < m_r_solver.m_column_types.size()); - lean_assert( m_r_solver.m_basis_heading[j] <= -1); + SASSERT(static_cast(- m_r_solver.m_basis_heading[j] - 1) < m_r_solver.m_column_types.size()); + SASSERT( m_r_solver.m_basis_heading[j] <= -1); } #endif return true; } void solve_on_signature(const lar_solution_signature & signature, const vector & changes_of_basis) { - lean_assert(!settings().use_tableau()); + SASSERT(!settings().use_tableau()); if (m_r_solver.m_factorization == nullptr) { for (unsigned j = 0; j < changes_of_basis.size(); j+=2) { unsigned entering = changes_of_basis[j]; @@ -615,7 +630,7 @@ public: return; m_r_solver.stop_tracing_basis_changes(); // and now catch up in the double solver - lean_assert(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2); + SASSERT(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2); catch_up_in_lu(m_r_solver.m_trace_of_basis_change_vector, m_r_solver.m_basis_heading, m_d_solver); } } @@ -641,7 +656,7 @@ public: template void extract_signature_from_lp_core_solver(const lp_primal_core_solver & solver, lar_solution_signature & signature) { signature.clear(); - lean_assert(signature.size() == 0); + SASSERT(signature.size() == 0); for (unsigned j = 0; j < solver.m_basis_heading.size(); j++) { if (solver.m_basis_heading[j] < 0) { signature[j] = solver.get_non_basic_column_value_position(j); @@ -664,7 +679,7 @@ public: if (upper_bound_is_set(j)) { const auto & ub = m_r_solver.m_upper_bounds[j]; m_d_upper_bounds[j] = ub.x.get_double() + delta * ub.y.get_double(); - lean_assert(!low_bound_is_set(j) || (m_d_upper_bounds[j] >= m_d_low_bounds[j])); + SASSERT(!low_bound_is_set(j) || (m_d_upper_bounds[j] >= m_d_low_bounds[j])); } } } @@ -729,7 +744,7 @@ public: case column_type::fixed: return true; default: - lean_assert(false); + SASSERT(false); } return false; } @@ -744,20 +759,20 @@ public: case column_type::fixed: return true; default: - lean_assert(false); + SASSERT(false); } return false; } void update_delta(mpq& delta, numeric_pair const& l, numeric_pair const& u) const { - lean_assert(l <= u); + SASSERT(l <= u); if (l.x < u.x && l.y > u.y) { mpq delta1 = (u.x - l.x) / (l.y - u.y); if (delta1 < delta) { delta = delta1; } } - lean_assert(l.x + delta * l.y <= u.x + delta * u.y); + SASSERT(l.x + delta * l.y <= u.x + delta * u.y); } diff --git a/src/util/lp/lar_core_solver.hpp b/src/util/lp/lar_core_solver.hpp index a6dd7e3e0..62a5c7887 100644 --- a/src/util/lp/lar_core_solver.hpp +++ b/src/util/lp/lar_core_solver.hpp @@ -1,16 +1,46 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/lar_core_solver.h" #include "util/lp/lar_solution_signature.h" -namespace lean { +namespace lp { lar_core_solver::lar_core_solver( lp_settings & settings, const column_namer & column_names @@ -42,9 +72,9 @@ lar_core_solver::lar_core_solver( column_names){} void lar_core_solver::init_costs(bool first_time) { - lean_assert(false); // should not be called - // lean_assert(this->m_x.size() >= this->m_n()); - // lean_assert(this->m_column_types.size() >= this->m_n()); + SASSERT(false); // should not be called + // SASSERT(this->m_x.size() >= this->m_n()); + // SASSERT(this->m_column_types.size() >= this->m_n()); // if (first_time) // this->m_costs.resize(this->m_n()); // X inf = this->m_infeasibility; @@ -54,7 +84,7 @@ void lar_core_solver::init_costs(bool first_time) { // if (!(first_time || inf >= this->m_infeasibility)) { // LP_OUT(this->m_settings, "iter = " << this->total_iterations() << std::endl); // LP_OUT(this->m_settings, "inf was " << T_to_string(inf) << " and now " << T_to_string(this->m_infeasibility) << std::endl); - // lean_assert(false); + // SASSERT(false); // } // if (inf == this->m_infeasibility) // this->m_iters_with_no_cost_growing++; @@ -105,7 +135,7 @@ void lar_core_solver::init_cost_for_column(unsigned j) { this->m_costs[j] = numeric_traits::zero(); break; default: - lean_assert(false); + SASSERT(false); break; }*/ } @@ -138,15 +168,15 @@ int lar_core_solver::column_is_out_of_bounds(unsigned j) { return 0; break; }*/ - lean_assert(false); + SASSERT(false); return true; } void lar_core_solver::calculate_pivot_row(unsigned i) { - lean_assert(!m_r_solver.use_tableau()); - lean_assert(m_r_solver.m_pivot_row.is_OK()); + SASSERT(!m_r_solver.use_tableau()); + SASSERT(m_r_solver.m_pivot_row.is_OK()); m_r_solver.m_pivot_row_of_B_1.clear(); m_r_solver.m_pivot_row_of_B_1.resize(m_r_solver.m_m()); m_r_solver.m_pivot_row.clear(); @@ -208,7 +238,7 @@ void lar_core_solver::calculate_pivot_row(unsigned i) { } void lar_core_solver::fill_not_improvable_zero_sum_from_inf_row() { - lean_assert(m_r_solver.A_mult_x_is_off() == false); + SASSERT(m_r_solver.A_mult_x_is_off() == false); unsigned bj = m_r_basis[m_r_solver.m_inf_row_index_for_tableau]; m_infeasible_sum_sign = m_r_solver.inf_sign_of_column(bj); m_infeasible_linear_combination.clear(); @@ -243,15 +273,15 @@ void lar_core_solver::fill_not_improvable_zero_sum() { void lar_core_solver::solve() { - lean_assert(m_r_solver.non_basic_columns_are_set_correctly()); - lean_assert(m_r_solver.inf_set_is_correct()); + SASSERT(m_r_solver.non_basic_columns_are_set_correctly()); + SASSERT(m_r_solver.inf_set_is_correct()); if (m_r_solver.current_x_is_feasible() && m_r_solver.m_look_for_feasible_solution_only) { m_r_solver.set_status(OPTIMAL); return; } ++settings().st().m_need_to_solve_inf; - lean_assert(!m_r_solver.A_mult_x_is_off()); - lean_assert((!settings().use_tableau()) || r_basis_is_OK()); + SASSERT(!m_r_solver.A_mult_x_is_off()); + SASSERT((!settings().use_tableau()) || r_basis_is_OK()); if (need_to_presolve_with_double_solver()) { prefix_d(); lar_solution_signature solution_signature; @@ -264,11 +294,11 @@ void lar_core_solver::solve() { solve_on_signature_tableau(solution_signature, changes_of_basis); else solve_on_signature(solution_signature, changes_of_basis); - lean_assert(!settings().use_tableau() || r_basis_is_OK()); + SASSERT(!settings().use_tableau() || r_basis_is_OK()); } else { if (!settings().use_tableau()) { bool snapped = m_r_solver.snap_non_basic_x_to_bound(); - lean_assert(m_r_solver.non_basic_columns_are_set_correctly()); + SASSERT(m_r_solver.non_basic_columns_are_set_correctly()); if (snapped) m_r_solver.solve_Ax_eq_b(); } @@ -276,16 +306,16 @@ void lar_core_solver::solve() { m_r_solver.find_feasible_solution(); else m_r_solver.solve(); - lean_assert(!settings().use_tableau() || r_basis_is_OK()); + SASSERT(!settings().use_tableau() || r_basis_is_OK()); } if (m_r_solver.get_status() == INFEASIBLE) { fill_not_improvable_zero_sum(); } else if (m_r_solver.get_status() != UNBOUNDED) { m_r_solver.set_status(OPTIMAL); } - lean_assert(r_basis_is_OK()); - lean_assert(m_r_solver.non_basic_columns_are_set_correctly()); - lean_assert(m_r_solver.inf_set_is_correct()); + SASSERT(r_basis_is_OK()); + SASSERT(m_r_solver.non_basic_columns_are_set_correctly()); + SASSERT(m_r_solver.inf_set_is_correct()); } diff --git a/src/util/lp/lar_core_solver_instances.cpp b/src/util/lp/lar_core_solver_instances.cpp index 432d1a939..a6a4048e5 100644 --- a/src/util/lp/lar_core_solver_instances.cpp +++ b/src/util/lp/lar_core_solver_instances.cpp @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include diff --git a/src/util/lp/lar_solution_signature.h b/src/util/lp/lar_solution_signature.h index 2c4169c81..08551a2d0 100644 --- a/src/util/lp/lar_solution_signature.h +++ b/src/util/lp/lar_solution_signature.h @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/debug.h" #include "util/lp/lp_settings.h" #include -namespace lean { +namespace lp { typedef std::unordered_map lar_solution_signature; } diff --git a/src/util/lp/lar_solver.h b/src/util/lp/lar_solver.h index d4b591154..1ed30bd70 100644 --- a/src/util/lp/lar_solver.h +++ b/src/util/lp/lar_solver.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include @@ -30,7 +45,7 @@ #include "util/lp/iterator_on_row.h" #include "util/lp/quick_xplain.h" #include "util/lp/conversion_helper.h" -namespace lean { +namespace lp { class lar_solver : public column_namer { //////////////////// fields ////////////////////////// @@ -75,7 +90,7 @@ public: lp_settings const & settings() const { return m_settings;} - void clear() {lean_assert(false); // not implemented + void clear() {SASSERT(false); // not implemented } @@ -107,7 +122,7 @@ public: } unsigned adjust_term_index(unsigned j) const { - lean_assert(is_term(j)); + SASSERT(is_term(j)); return j - m_terms_start_index; } @@ -115,10 +130,10 @@ public: bool use_lu() const { return m_settings.simplex_strategy() == simplex_strategy_enum::lu; } bool sizes_are_correct() const { - lean_assert(strategy_is_undecided() || !m_mpq_lar_core_solver.need_to_presolve_with_double_solver() || A_r().column_count() == A_d().column_count()); - lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_column_types.size()); - lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); - lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_x.size()); + SASSERT(strategy_is_undecided() || !m_mpq_lar_core_solver.need_to_presolve_with_double_solver() || A_r().column_count() == A_d().column_count()); + SASSERT(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_column_types.size()); + SASSERT(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); + SASSERT(A_r().column_count() == m_mpq_lar_core_solver.m_r_x.size()); return true; } @@ -160,7 +175,7 @@ public: else if (kind == LE || kind == LT) n_of_L++; rs_of_evidence += coeff*constr.m_right_side; } - lean_assert(n_of_G == 0 || n_of_L == 0); + SASSERT(n_of_G == 0 || n_of_L == 0); lconstraint_kind kind = n_of_G ? GE : (n_of_L ? LE : EQ); if (strict) kind = static_cast((static_cast(kind) / 2)); @@ -204,7 +219,7 @@ public: void analyze_new_bounds_on_row( unsigned row_index, lp_bound_propagator & bp) { - lean_assert(!use_tableau()); + SASSERT(!use_tableau()); iterator_on_pivot_row it(m_mpq_lar_core_solver.get_pivot_row(), m_mpq_lar_core_solver.m_r_basis[row_index]); bound_analyzer_on_row ra_pos(it, @@ -223,7 +238,7 @@ public: if (A_r().m_rows[row_index].size() > settings().max_row_length_for_bound_propagation) return; iterator_on_row it(A_r().m_rows[row_index]); - lean_assert(use_tableau()); + SASSERT(use_tableau()); bound_analyzer_on_row::analyze_row(it, zero_of_type>(), row_index, @@ -271,7 +286,7 @@ public: } void fill_bound_evidence_on_term(implied_bound & ie, implied_bound& be) { - lean_assert(false); + SASSERT(false); } void fill_implied_bound_on_row(implied_bound & ie, implied_bound& be) { iterator_on_row it(A_r().m_rows[ie.m_row_or_term_index]); @@ -285,7 +300,7 @@ public: if (is_neg(a)) { // so the monoid has a positive coeff on the right side constraint_index witness = toggle ? ul.m_low_bound_witness : ul.m_upper_bound_witness; - lean_assert(is_valid(witness)); + SASSERT(is_valid(witness)); be.m_explanation.emplace_back(a, witness); } } @@ -304,7 +319,7 @@ public: } implied_bound fill_implied_bound_for_upper_bound(implied_bound& implied_evidence) { - lean_assert(false); + SASSERT(false); be.m_j = implied_evidence.m_j; be.m_bound = implied_evidence.m_bound.x; @@ -312,7 +327,7 @@ public: for (auto t : implied_evidence.m_vector_of_bound_signatures) { const ul_pair & ul = m_vars_to_ul_pairs[t.m_column_index]; constraint_index witness = t.m_low_bound ? ul.m_low_bound_witness : ul.m_upper_bound_witness; - lean_assert(is_valid(witness)); + SASSERT(is_valid(witness)); be.m_explanation.emplace_back(t.m_coeff, witness); } @@ -338,7 +353,7 @@ public: // implied_bound * get_existing_ linear_combination_iterator * create_new_iter_from_term(unsigned term_index) const { - lean_assert(false); // not implemented + SASSERT(false); // not implemented return nullptr; // new linear_combination_iterator_on_vector(m_terms[adjust_term_index(term_index)]->coeffs_as_vector()); } @@ -349,7 +364,7 @@ public: } void propagate_bounds_on_a_term(const lar_term& t, lp_bound_propagator & bp, unsigned term_offset) { - lean_assert(false); // not implemented + SASSERT(false); // not implemented } @@ -372,15 +387,15 @@ public: int sign = j_sign * a_sign; const ul_pair & ul = m_vars_to_ul_pairs[j]; auto witness = sign > 0? ul.upper_bound_witness(): ul.low_bound_witness(); - lean_assert(is_valid(witness)); + SASSERT(is_valid(witness)); bp.consume(a, witness); } - // lean_assert(implied_bound_is_correctly_explained(ib, explanation)); + // SASSERT(implied_bound_is_correctly_explained(ib, explanation)); } bool term_is_used_as_row(unsigned term) const { - lean_assert(is_term(term)); + SASSERT(is_term(term)); return contains(m_ext_vars_to_columns, term); } @@ -500,12 +515,12 @@ public: unsigned m = A_r().row_count(); clean_large_elements_after_pop(m, m_rows_with_changed_bounds); clean_inf_set_of_r_solver_after_pop(); - lean_assert(m_settings.simplex_strategy() == simplex_strategy_enum::undecided || + SASSERT(m_settings.simplex_strategy() == simplex_strategy_enum::undecided || (!use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); - lean_assert(ax_is_correct()); - lean_assert(m_mpq_lar_core_solver.m_r_solver.inf_set_is_correct()); + SASSERT(ax_is_correct()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.inf_set_is_correct()); m_constraint_count.pop(k); for (unsigned i = m_constraint_count; i < m_constraints.size(); i++) delete m_constraints[i]; @@ -520,8 +535,8 @@ public: m_orig_terms.resize(m_term_count); m_simplex_strategy.pop(k); m_settings.simplex_strategy() = m_simplex_strategy; - lean_assert(sizes_are_correct()); - lean_assert((!m_settings.use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); + SASSERT(sizes_are_correct()); + SASSERT((!m_settings.use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); } vector get_all_constraint_indices() const { @@ -550,13 +565,13 @@ public: bool costs_are_zeros_for_r_solver() const { for (unsigned j = 0; j < m_mpq_lar_core_solver.m_r_solver.m_costs.size(); j++) { - lean_assert(is_zero(m_mpq_lar_core_solver.m_r_solver.m_costs[j])); + SASSERT(is_zero(m_mpq_lar_core_solver.m_r_solver.m_costs[j])); } return true; } bool reduced_costs_are_zeroes_for_r_solver() const { for (unsigned j = 0; j < m_mpq_lar_core_solver.m_r_solver.m_d.size(); j++) { - lean_assert(is_zero(m_mpq_lar_core_solver.m_r_solver.m_d[j])); + SASSERT(is_zero(m_mpq_lar_core_solver.m_r_solver.m_d[j])); } return true; } @@ -564,7 +579,7 @@ public: void set_costs_to_zero(const vector> & term) { auto & rslv = m_mpq_lar_core_solver.m_r_solver; auto & jset = m_mpq_lar_core_solver.m_r_solver.m_inf_set; // hijack this set that should be empty right now - lean_assert(jset.m_index.size()==0); + SASSERT(jset.m_index.size()==0); for (auto & p : term) { unsigned j = p.second; @@ -583,16 +598,16 @@ public: jset.clear(); - lean_assert(reduced_costs_are_zeroes_for_r_solver()); - lean_assert(costs_are_zeros_for_r_solver()); + SASSERT(reduced_costs_are_zeroes_for_r_solver()); + SASSERT(costs_are_zeros_for_r_solver()); } void prepare_costs_for_r_solver(const vector> & term) { auto & rslv = m_mpq_lar_core_solver.m_r_solver; rslv.m_using_infeas_costs = false; - lean_assert(costs_are_zeros_for_r_solver()); - lean_assert(reduced_costs_are_zeroes_for_r_solver()); + SASSERT(costs_are_zeros_for_r_solver()); + SASSERT(reduced_costs_are_zeroes_for_r_solver()); rslv.m_costs.resize(A_r().column_count(), zero_of_type()); for (auto & p : term) { unsigned j = p.second; @@ -602,7 +617,7 @@ public: else rslv.update_reduced_cost_for_basic_column_cost_change(- p.first, j); } - lean_assert(rslv.reduced_costs_are_correct_tableau()); + SASSERT(rslv.reduced_costs_are_correct_tableau()); } bool maximize_term_on_corrected_r_solver(const vector> & term, @@ -629,10 +644,10 @@ public: } case simplex_strategy_enum::lu: - lean_assert(false); // not implemented + SASSERT(false); // not implemented return false; default: - lean_unreachable(); // wrong mode + SASSERT(false); // wrong mode } return false; } @@ -640,7 +655,7 @@ public: // return true if found and false if unbounded bool maximize_term(const vector> & term, impq &term_max) { - lean_assert(m_mpq_lar_core_solver.m_r_solver.current_x_is_feasible()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.current_x_is_feasible()); m_mpq_lar_core_solver.m_r_solver.m_look_for_feasible_solution_only = false; return maximize_term_on_corrected_r_solver(term, term_max); } @@ -648,7 +663,7 @@ public: const lar_term & get_term(unsigned j) const { - lean_assert(j >= m_terms_start_index); + SASSERT(j >= m_terms_start_index); return *m_terms[j - m_terms_start_index]; } @@ -680,7 +695,7 @@ public: vector> &left_side, mpq & right_side) const { for (auto & t : left_side_with_terms) { if (t.second < m_terms_start_index) { - lean_assert(t.second < A_r().column_count()); + SASSERT(t.second < A_r().column_count()); left_side.push_back(std::pair(mult * t.first, t.second)); } else { const lar_term & term = * m_terms[adjust_term_index(t.second)]; @@ -696,7 +711,7 @@ public: m_column_buffer.resize(A_r().row_count()); else m_column_buffer.clear(); - lean_assert(m_column_buffer.size() == 0 && m_column_buffer.is_OK()); + SASSERT(m_column_buffer.size() == 0 && m_column_buffer.is_OK()); m_mpq_lar_core_solver.m_r_solver.solve_Bd(j, m_column_buffer); for (unsigned i : m_column_buffer.m_index) @@ -730,7 +745,7 @@ public: } void adjust_x_of_column(unsigned j) { - lean_assert(false); + SASSERT(false); } bool row_is_correct(unsigned i) const { @@ -819,14 +834,14 @@ public: } void update_x_and_inf_costs_for_columns_with_changed_bounds_tableau() { - lean_assert(ax_is_correct()); + SASSERT(ax_is_correct()); for (auto j : m_columns_with_changed_bound.m_index) update_x_and_inf_costs_for_column_with_changed_bounds(j); if (tableau_with_costs()) { for (unsigned j : m_basic_columns_with_changed_cost.m_index) m_mpq_lar_core_solver.m_r_solver.update_inf_cost_for_column_tableau(j); - lean_assert(m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); } } @@ -848,7 +863,7 @@ public: update_x_and_inf_costs_for_columns_with_changed_bounds(); m_mpq_lar_core_solver.solve(); set_status(m_mpq_lar_core_solver.m_r_solver.get_status()); - lean_assert(m_status != OPTIMAL || all_constraints_hold()); + SASSERT(m_status != OPTIMAL || all_constraints_hold()); } @@ -875,7 +890,7 @@ public: numeric_pair r = zero_of_type>(); m_mpq_lar_core_solver.calculate_pivot_row(i); for (unsigned j : m_mpq_lar_core_solver.m_r_solver.m_pivot_row.m_index) { - lean_assert(m_mpq_lar_core_solver.m_r_solver.m_basis_heading[j] < 0); + SASSERT(m_mpq_lar_core_solver.m_r_solver.m_basis_heading[j] < 0); r -= m_mpq_lar_core_solver.m_r_solver.m_pivot_row.m_data[j] * m_mpq_lar_core_solver.m_r_x[j]; } return r; @@ -939,12 +954,12 @@ public: } void fill_last_row_of_A_r(static_matrix> & A, const lar_term * ls) { - lean_assert(A.row_count() > 0); - lean_assert(A.column_count() > 0); + SASSERT(A.row_count() > 0); + SASSERT(A.column_count() > 0); unsigned last_row = A.row_count() - 1; - lean_assert(A.m_rows[last_row].size() == 0); + SASSERT(A.m_rows[last_row].size() == 0); for (auto & t : ls->m_coeffs) { - lean_assert(!is_zero(t.second)); + SASSERT(!is_zero(t.second)); var_index j = t.first; A.set(last_row, j, - t.second); } @@ -954,7 +969,7 @@ public: template void create_matrix_A(static_matrix & matr) { - lean_assert(false); // not implemented + SASSERT(false); // not implemented /* unsigned m = number_or_nontrivial_left_sides(); unsigned n = m_vec_of_canonic_left_sides.size(); @@ -1016,8 +1031,8 @@ public: mpq rs = right_side_parm; vector> left_side; substitute_terms(one_of_type(), left_side_with_terms, left_side, rs); - lean_assert(left_side.size() > 0); - lean_assert(all_constrained_variables_are_registered(left_side)); + SASSERT(left_side.size() > 0); + SASSERT(all_constrained_variables_are_registered(left_side)); lar_constraint original_constr(left_side, kind_par, rs); unsigned j; // j is the index of the basic variables corresponding to the left side canonic_left_side ls = create_or_fetch_canonic_left_side(left_side, j); @@ -1030,7 +1045,7 @@ public: update_column_type_and_bound(j, kind, rs, constr_ind); return constr_ind; */ - lean_assert(false); // not implemented + SASSERT(false); // not implemented return 0; } @@ -1058,7 +1073,7 @@ public: case GT: return left_side_val > constr.m_right_side; case EQ: return left_side_val == constr.m_right_side; default: - lean_unreachable(); + SASSERT(false); } return false; // it is unreachable } @@ -1108,7 +1123,7 @@ public: for (auto & it : evidence) { mpq coeff = it.first; constraint_index con_ind = it.second; - lean_assert(con_ind < m_constraints.size()); + SASSERT(con_ind < m_constraints.size()); register_in_map(coeff_map, *m_constraints[con_ind], coeff); } @@ -1131,7 +1146,7 @@ public: for (auto & it : evidence) { mpq coeff = it.first; constraint_index con_ind = it.second; - lean_assert(con_ind < m_constraints.size()); + SASSERT(con_ind < m_constraints.size()); const lar_constraint & constr = *m_constraints[con_ind]; ret += constr.m_right_side * coeff; } @@ -1139,24 +1154,24 @@ public: } bool explanation_is_correct(const vector>& explanation) const { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG lconstraint_kind kind; - lean_assert(the_relations_are_of_same_type(explanation, kind)); - lean_assert(the_left_sides_sum_to_zero(explanation)); + SASSERT(the_relations_are_of_same_type(explanation, kind)); + SASSERT(the_left_sides_sum_to_zero(explanation)); mpq rs = sum_of_right_sides_of_explanation(explanation); switch (kind) { - case LE: lean_assert(rs < zero_of_type()); + case LE: SASSERT(rs < zero_of_type()); break; - case LT: lean_assert(rs <= zero_of_type()); + case LT: SASSERT(rs <= zero_of_type()); break; - case GE: lean_assert(rs > zero_of_type()); + case GE: SASSERT(rs > zero_of_type()); break; - case GT: lean_assert(rs >= zero_of_type()); + case GT: SASSERT(rs >= zero_of_type()); break; - case EQ: lean_assert(rs != zero_of_type()); + case EQ: SASSERT(rs != zero_of_type()); break; default: - lean_assert(false); + SASSERT(false); return false; } #endif @@ -1164,7 +1179,7 @@ public: } bool inf_explanation_is_correct() const { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG vector> explanation; get_infeasibility_explanation(explanation); return explanation_is_correct(explanation); @@ -1177,7 +1192,7 @@ public: for (auto & it : explanation) { mpq coeff = it.first; constraint_index con_ind = it.second; - lean_assert(con_ind < m_constraints.size()); + SASSERT(con_ind < m_constraints.size()); ret += (m_constraints[con_ind]->m_right_side - m_constraints[con_ind]->get_free_coeff_of_left_side()) * coeff; } return ret; @@ -1235,7 +1250,7 @@ public: int inf_sign; auto inf_row = m_mpq_lar_core_solver.get_infeasibility_info(inf_sign); get_infeasibility_explanation_for_inf_sign(explanation, inf_row, inf_sign); - lean_assert(explanation_is_correct(explanation)); + SASSERT(explanation_is_correct(explanation)); } void get_infeasibility_explanation_for_inf_sign( @@ -1251,7 +1266,7 @@ public: const ul_pair & ul = m_vars_to_ul_pairs[j]; constraint_index bound_constr_i = adj_sign < 0 ? ul.upper_bound_witness() : ul.low_bound_witness(); - lean_assert(bound_constr_i < m_constraints.size()); + SASSERT(bound_constr_i < m_constraints.size()); explanation.push_back(std::make_pair(coeff, bound_constr_i)); } } @@ -1260,7 +1275,7 @@ public: void get_model(std::unordered_map & variable_values) const { mpq delta = m_mpq_lar_core_solver.find_delta_for_strict_bounds(mpq(1, 2)); // start from 0.5 to have less clashes - lean_assert(m_status == OPTIMAL); + SASSERT(m_status == OPTIMAL); unsigned i; do { @@ -1332,7 +1347,7 @@ public: for (auto & it : cns.get_left_side_coefficients()) { var_index j = it.second; auto vi = var_map.find(j); - lean_assert(vi != var_map.end()); + SASSERT(vi != var_map.end()); ret += it.first * vi->second; } return ret; @@ -1379,7 +1394,7 @@ public: void make_sure_that_the_bottom_right_elem_not_zero_in_tableau(unsigned i, unsigned j) { // i, j - is the indices of the bottom-right element of the tableau - lean_assert(A_r().row_count() == i + 1 && A_r().column_count() == j + 1); + SASSERT(A_r().row_count() == i + 1 && A_r().column_count() == j + 1); auto & last_column = A_r().m_columns[j]; int non_zero_column_cell_index = -1; for (unsigned k = last_column.size(); k-- > 0;){ @@ -1389,13 +1404,13 @@ public: non_zero_column_cell_index = k; } - lean_assert(non_zero_column_cell_index != -1); - lean_assert(static_cast(non_zero_column_cell_index) != i); + SASSERT(non_zero_column_cell_index != -1); + SASSERT(static_cast(non_zero_column_cell_index) != i); m_mpq_lar_core_solver.m_r_solver.transpose_rows_tableau(last_column[non_zero_column_cell_index].m_i, i); } void remove_last_row_and_column_from_tableau(unsigned j) { - lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); + SASSERT(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); auto & slv = m_mpq_lar_core_solver.m_r_solver; unsigned i = A_r().row_count() - 1; //last row index make_sure_that_the_bottom_right_elem_not_zero_in_tableau(i, j); @@ -1414,17 +1429,17 @@ public: A_r().remove_element(last_row, rc); } - lean_assert(last_row.size() == 0); - lean_assert(A_r().m_columns[j].size() == 0); + SASSERT(last_row.size() == 0); + SASSERT(A_r().m_columns[j].size() == 0); A_r().m_rows.pop_back(); A_r().m_columns.pop_back(); slv.m_b.pop_back(); } void remove_last_column_from_tableau(unsigned j) { - lean_assert(j == A_r().column_count() - 1); + SASSERT(j == A_r().column_count() - 1); // the last column has to be empty - lean_assert(A_r().m_columns[j].size() == 0); + SASSERT(A_r().m_columns[j].size() == 0); A_r().m_columns.pop_back(); } @@ -1433,7 +1448,7 @@ public: int i = rslv.m_basis_heading[j]; if (i >= 0) { // j is a basic var int last_pos = static_cast(rslv.m_basis.size()) - 1; - lean_assert(last_pos >= 0); + SASSERT(last_pos >= 0); if (i != last_pos) { unsigned j_at_last_pos = rslv.m_basis[last_pos]; rslv.m_basis[i] = j_at_last_pos; @@ -1442,7 +1457,7 @@ public: rslv.m_basis.pop_back(); // remove j from the basis } else { int last_pos = static_cast(rslv.m_nbasis.size()) - 1; - lean_assert(last_pos >= 0); + SASSERT(last_pos >= 0); i = - 1 - i; if (i != last_pos) { unsigned j_at_last_pos = rslv.m_nbasis[last_pos]; @@ -1452,14 +1467,14 @@ public: rslv.m_nbasis.pop_back(); // remove j from the basis } rslv.m_basis_heading.pop_back(); - lean_assert(rslv.m_basis.size() == A_r().row_count()); - lean_assert(rslv.basis_heading_is_correct()); + SASSERT(rslv.m_basis.size() == A_r().row_count()); + SASSERT(rslv.basis_heading_is_correct()); } void remove_column_from_tableau(unsigned j) { auto& rslv = m_mpq_lar_core_solver.m_r_solver; - lean_assert(j == A_r().column_count() - 1); - lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); + SASSERT(j == A_r().column_count() - 1); + SASSERT(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); if (column_represents_row_in_tableau(j)) { remove_last_row_and_column_from_tableau(j); if (rslv.m_basis_heading[j] < 0) @@ -1473,23 +1488,23 @@ public: rslv.m_costs.pop_back(); remove_last_column_from_basis_tableau(j); - lean_assert(m_mpq_lar_core_solver.r_basis_is_OK()); - lean_assert(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); + SASSERT(m_mpq_lar_core_solver.r_basis_is_OK()); + SASSERT(A_r().column_count() == m_mpq_lar_core_solver.m_r_solver.m_costs.size()); } void pop_tableau() { - lean_assert(m_mpq_lar_core_solver.m_r_solver.m_costs.size() == A_r().column_count()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.m_costs.size() == A_r().column_count()); - lean_assert(m_mpq_lar_core_solver.m_r_solver.m_basis.size() == A_r().row_count()); - lean_assert(m_mpq_lar_core_solver.m_r_solver.basis_heading_is_correct()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.m_basis.size() == A_r().row_count()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.basis_heading_is_correct()); // We remove last variables starting from m_column_names.size() to m_vec_of_canonic_left_sides.size(). // At this moment m_column_names is already popped for (unsigned j = A_r().column_count(); j-- > m_columns_to_ext_vars_or_term_indices.size();) remove_column_from_tableau(j); - lean_assert(m_mpq_lar_core_solver.m_r_solver.m_costs.size() == A_r().column_count()); - lean_assert(m_mpq_lar_core_solver.m_r_solver.m_basis.size() == A_r().row_count()); - lean_assert(m_mpq_lar_core_solver.m_r_solver.basis_heading_is_correct()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.m_costs.size() == A_r().column_count()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.m_basis.size() == A_r().row_count()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.basis_heading_is_correct()); } @@ -1512,14 +1527,14 @@ public: } for (unsigned j : became_feas) { - lean_assert(m_mpq_lar_core_solver.m_r_solver.m_basis_heading[j] < 0); + SASSERT(m_mpq_lar_core_solver.m_r_solver.m_basis_heading[j] < 0); m_mpq_lar_core_solver.m_r_solver.m_d[j] -= m_mpq_lar_core_solver.m_r_solver.m_costs[j]; m_mpq_lar_core_solver.m_r_solver.m_costs[j] = zero_of_type(); m_mpq_lar_core_solver.m_r_solver.m_inf_set.erase(j); } became_feas.clear(); for (unsigned j : m_mpq_lar_core_solver.m_r_solver.m_inf_set.m_index) { - lean_assert(m_mpq_lar_core_solver.m_r_heading[j] >= 0); + SASSERT(m_mpq_lar_core_solver.m_r_heading[j] >= 0); if (m_mpq_lar_core_solver.m_r_solver.column_is_feasible(j)) became_feas.push_back(j); } @@ -1532,7 +1547,7 @@ public: m_mpq_lar_core_solver.m_r_solver.update_inf_cost_for_column_tableau(j); for (unsigned j : basic_columns_with_changed_cost) m_mpq_lar_core_solver.m_r_solver.update_inf_cost_for_column_tableau(j); - lean_assert(m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); + SASSERT(m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); } } @@ -1540,7 +1555,7 @@ public: void shrink_explanation_to_minimum(vector> & explanation) const { // implementing quickXplain quick_xplain::run(explanation, *this); - lean_assert(this->explanation_is_correct(explanation)); + SASSERT(this->explanation_is_correct(explanation)); } }; } diff --git a/src/util/lp/lar_term.h b/src/util/lp/lar_term.h index 0e715ad0b..16b5a938d 100644 --- a/src/util/lp/lar_term.h +++ b/src/util/lp/lar_term.h @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/indexed_vector.h" -namespace lean { +namespace lp { struct lar_term { // the term evaluates to sum of m_coeffs + m_v std::unordered_map m_coeffs; diff --git a/src/util/lp/linear_combination_iterator.h b/src/util/lp/linear_combination_iterator.h index 634accfd4..417bdcf82 100644 --- a/src/util/lp/linear_combination_iterator.h +++ b/src/util/lp/linear_combination_iterator.h @@ -1,9 +1,24 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once -namespace lean { +namespace lp { template struct linear_combination_iterator { virtual bool next(T & a, unsigned & i) = 0; diff --git a/src/util/lp/lp_bound_propagator.cpp b/src/util/lp/lp_bound_propagator.cpp index 506ba138b..53218fced 100644 --- a/src/util/lp/lp_bound_propagator.cpp +++ b/src/util/lp/lp_bound_propagator.cpp @@ -1,9 +1,24 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lar_solver.h" -namespace lean { +namespace lp { lp_bound_propagator::lp_bound_propagator(lar_solver & ls): m_lar_solver(ls) {} column_type lp_bound_propagator::get_column_type(unsigned j) const { diff --git a/src/util/lp/lp_bound_propagator.h b/src/util/lp/lp_bound_propagator.h index f1e0d486e..76870f457 100644 --- a/src/util/lp/lp_bound_propagator.h +++ b/src/util/lp/lp_bound_propagator.h @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/lp_settings.h" -namespace lean { +namespace lp { class lar_solver; class lp_bound_propagator { std::unordered_map m_improved_low_bounds; // these maps map a column index to the corresponding index in ibounds @@ -19,7 +34,7 @@ public: const impq & get_upper_bound(unsigned) const; void try_add_bound(const mpq & v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict); virtual bool bound_is_interesting(unsigned vi, - lean::lconstraint_kind kind, + lp::lconstraint_kind kind, const rational & bval) {return true;} unsigned number_of_found_bounds() const { return m_ibounds.size(); } virtual void consume(mpq const& v, unsigned j) { std::cout << "doh\n"; } diff --git a/src/util/lp/lp_core_solver_base.h b/src/util/lp/lp_core_solver_base.h index a12b7b5d2..fd115669c 100644 --- a/src/util/lp/lp_core_solver_base.h +++ b/src/util/lp/lp_core_solver_base.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include #include "util/vector.h" @@ -13,7 +28,7 @@ #include "util/lp/lu.h" #include "util/lp/permutation_matrix.h" #include "util/lp/column_namer.h" -namespace lean { +namespace lp { template // X represents the type of the x variable and the bounds class lp_core_solver_base { @@ -182,11 +197,11 @@ public: bool need_to_pivot_to_basis_tableau() const { - lean_assert(m_A.is_correct()); + SASSERT(m_A.is_correct()); unsigned m = m_A.row_count(); for (unsigned i = 0; i < m; i++) { unsigned bj = m_basis[i]; - lean_assert(m_A.m_columns[bj].size() > 0); + SASSERT(m_A.m_columns[bj].size() > 0); if (m_A.m_columns[bj].size() > 1 || m_A.get_val(m_A.m_columns[bj][0]) != one_of_type()) return true; } return false; @@ -195,7 +210,7 @@ public: bool reduced_costs_are_correct_tableau() const { if (m_settings.simplex_strategy() == simplex_strategy_enum::tableau_rows) return true; - lean_assert(m_A.is_correct()); + SASSERT(m_A.is_correct()); if (m_using_infeas_costs) { if (infeasibility_costs_are_correct() == false) { std::cout << "infeasibility_costs_are_correct() does not hold" << std::endl; @@ -370,11 +385,11 @@ public: } bool make_column_feasible(unsigned j, numeric_pair & delta) { - lean_assert(m_basis_heading[j] < 0); + SASSERT(m_basis_heading[j] < 0); auto & x = m_x[j]; switch (m_column_types[j]) { case column_type::fixed: - lean_assert(m_low_bounds[j] == m_upper_bounds[j]); + SASSERT(m_low_bounds[j] == m_upper_bounds[j]); if (x != m_low_bounds[j]) { delta = m_low_bounds[j] - x; x = m_low_bounds[j]; @@ -410,7 +425,7 @@ public: case column_type::free_column: break; default: - lean_assert(false); + SASSERT(false); break; } return false; @@ -458,7 +473,7 @@ public: } void change_basis_unconditionally(unsigned entering, unsigned leaving) { - lean_assert(m_basis_heading[entering] < 0); + SASSERT(m_basis_heading[entering] < 0); int place_in_non_basis = -1 - m_basis_heading[entering]; if (static_cast(place_in_non_basis) >= m_nbasis.size()) { // entering variable in not in m_nbasis, we need to put it back; @@ -477,7 +492,7 @@ public: } void change_basis(unsigned entering, unsigned leaving) { - lean_assert(m_basis_heading[entering] < 0); + SASSERT(m_basis_heading[entering] < 0); int place_in_basis = m_basis_heading[leaving]; int place_in_non_basis = - m_basis_heading[entering] - 1; @@ -518,7 +533,7 @@ public: case column_type::free_column: break; default: - lean_assert(false); + SASSERT(false); break; } return true; @@ -566,7 +581,7 @@ public: case column_type::free_column: break; default: - lean_assert(false); + SASSERT(false); } std::cout << "basis heading = " << m_basis_heading[j] << std::endl; std::cout << "x = " << m_x[j] << std::endl; @@ -665,17 +680,17 @@ public: } void insert_column_into_inf_set(unsigned j) { m_inf_set.insert(j); - lean_assert(!column_is_feasible(j)); + SASSERT(!column_is_feasible(j)); } void remove_column_from_inf_set(unsigned j) { m_inf_set.erase(j); - lean_assert(column_is_feasible(j)); + SASSERT(column_is_feasible(j)); } bool costs_on_nbasis_are_zeros() const { - lean_assert(this->basis_heading_is_correct()); + SASSERT(this->basis_heading_is_correct()); for (unsigned j = 0; j < this->m_n(); j++) { if (this->m_basis_heading[j] < 0) - lean_assert(is_zero(this->m_costs[j])); + SASSERT(is_zero(this->m_costs[j])); } return true; } diff --git a/src/util/lp/lp_core_solver_base.hpp b/src/util/lp/lp_core_solver_base.hpp index a0dba9de7..fa1c95850 100644 --- a/src/util/lp/lp_core_solver_base.hpp +++ b/src/util/lp/lp_core_solver_base.hpp @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include "util/vector.h" #include "util/lp/lp_utils.h" #include "util/lp/lp_core_solver_base.h" -namespace lean { +namespace lp { template lp_core_solver_base:: lp_core_solver_base(static_matrix & A, @@ -53,7 +68,7 @@ lp_core_solver_base(static_matrix & A, m_tracing_basis_changes(false), m_pivoted_rows(nullptr), m_look_for_feasible_solution_only(false) { - lean_assert(bounds_for_boxed_are_set_correctly()); + SASSERT(bounds_for_boxed_are_set_correctly()); init(); init_basis_heading_and_non_basic_columns_vector(); } @@ -61,7 +76,7 @@ lp_core_solver_base(static_matrix & A, template void lp_core_solver_base:: allocate_basis_heading() { // the rest of initilization will be handled by the factorization class init_basis_heading_and_non_basic_columns_vector(); - lean_assert(basis_heading_is_correct()); + SASSERT(basis_heading_is_correct()); } template void lp_core_solver_base:: init() { @@ -127,7 +142,7 @@ solve_yB(vector & y) { // } // } template void lp_core_solver_base::solve_Bd(unsigned entering, indexed_vector & column) { - lean_assert(!m_settings.use_tableau()); + SASSERT(!m_settings.use_tableau()); if (m_factorization == nullptr) { init_factorization(m_factorization, m_A, m_basis, m_settings); } @@ -137,19 +152,19 @@ template void lp_core_solver_base::solve_Bd(unsig template void lp_core_solver_base:: solve_Bd(unsigned entering) { - lean_assert(m_ed.is_OK()); + SASSERT(m_ed.is_OK()); m_factorization->solve_Bd(entering, m_ed, m_w); if (this->precise()) m_columns_nz[entering] = m_ed.m_index.size(); - lean_assert(m_ed.is_OK()); - lean_assert(m_w.is_OK()); -#ifdef LEAN_DEBUG + SASSERT(m_ed.is_OK()); + SASSERT(m_w.is_OK()); +#ifdef Z3DEBUG // auto B = get_B(*m_factorization, m_basis); // vector a(m_m()); // m_A.copy_column_to_vector(entering, a); // vector cd(m_ed.m_data); // B.apply_from_left(cd, m_settings); - // lean_assert(vectors_are_equal(cd , a)); + // SASSERT(vectors_are_equal(cd , a)); #endif } @@ -208,7 +223,7 @@ restore_m_ed(T * buffer) { template bool lp_core_solver_base:: A_mult_x_is_off() const { - lean_assert(m_x.size() == m_A.column_count()); + SASSERT(m_x.size() == m_A.column_count()); if (numeric_traits::precise()) { for (unsigned i = 0; i < m_m(); i++) { X delta = m_b[i] - m_A.dot_product_with_row(i, m_x); @@ -244,7 +259,7 @@ A_mult_x_is_off() const { } template bool lp_core_solver_base:: A_mult_x_is_off_on_index(const vector & index) const { - lean_assert(m_x.size() == m_A.column_count()); + SASSERT(m_x.size() == m_A.column_count()); if (numeric_traits::precise()) return false; #if RUN_A_MULT_X_IS_OFF_FOR_PRECESE for (unsigned i : index) { @@ -284,13 +299,13 @@ A_mult_x_is_off_on_index(const vector & index) const { // from page 182 of Istvan Maros's book template void lp_core_solver_base:: calculate_pivot_row_of_B_1(unsigned pivot_row) { - lean_assert(! use_tableau()); - lean_assert(m_pivot_row_of_B_1.is_OK()); + SASSERT(! use_tableau()); + SASSERT(m_pivot_row_of_B_1.is_OK()); m_pivot_row_of_B_1.clear(); m_pivot_row_of_B_1.set_value(numeric_traits::one(), pivot_row); - lean_assert(m_pivot_row_of_B_1.is_OK()); + SASSERT(m_pivot_row_of_B_1.is_OK()); m_factorization->solve_yB_with_error_check_indexed(m_pivot_row_of_B_1, m_basis_heading, m_basis, m_settings); - lean_assert(m_pivot_row_of_B_1.is_OK()); + SASSERT(m_pivot_row_of_B_1.is_OK()); } @@ -380,11 +395,11 @@ set_non_basic_x_to_correct_bounds() { break; case column_type::low_bound: m_x[j] = m_low_bounds[j]; - lean_assert(column_is_dual_feasible(j)); + SASSERT(column_is_dual_feasible(j)); break; case column_type::upper_bound: m_x[j] = m_upper_bounds[j]; - lean_assert(column_is_dual_feasible(j)); + SASSERT(column_is_dual_feasible(j)); break; default: break; @@ -402,15 +417,15 @@ column_is_dual_feasible(unsigned j) const { return x_is_at_low_bound(j) && d_is_not_negative(j); case column_type::upper_bound: LP_OUT(m_settings, "upper_bound type should be switched to low_bound" << std::endl); - lean_assert(false); // impossible case + SASSERT(false); // impossible case case column_type::free_column: return numeric_traits::is_zero(m_d[j]); default: LP_OUT(m_settings, "column = " << j << std::endl); LP_OUT(m_settings, "unexpected column type = " << column_type_to_string(m_column_types[j]) << std::endl); - lean_unreachable(); + SASSERT(false); } - lean_unreachable(); + SASSERT(false); return false; } template bool lp_core_solver_base:: @@ -493,7 +508,7 @@ template bool lp_core_solver_base::column_is_feas return true; break; default: - lean_unreachable(); + SASSERT(false); } return false; // it is unreachable } @@ -575,7 +590,7 @@ update_basis_and_x(int entering, int leaving, X const & tt) { restore_x_and_refactor(entering, leaving, tt); if (m_status == FLOATING_POINT_ERROR) return false; - lean_assert(!A_mult_x_is_off()); + SASSERT(!A_mult_x_is_off()); m_iters_with_no_cost_growing++; // LP_OUT(m_settings, "rolled back after failing of init_factorization()" << std::endl); m_status = UNSTABLE; @@ -587,7 +602,7 @@ update_basis_and_x(int entering, int leaving, X const & tt) { template bool lp_core_solver_base:: divide_row_by_pivot(unsigned pivot_row, unsigned pivot_col) { - lean_assert(numeric_traits::precise()); + SASSERT(numeric_traits::precise()); int pivot_index = -1; auto & row = m_A.m_rows[pivot_row]; unsigned size = row.size(); @@ -628,7 +643,7 @@ pivot_column_tableau(unsigned j, unsigned piv_row_index) { return false; if (pivot_col_cell_index != 0) { - lean_assert(column.size() > 1); + SASSERT(column.size() > 1); // swap the pivot column cell with the head cell auto c = column[0]; column[0] = column[pivot_col_cell_index]; @@ -639,7 +654,7 @@ pivot_column_tableau(unsigned j, unsigned piv_row_index) { } while (column.size() > 1) { auto & c = column.back(); - lean_assert(c.m_i != piv_row_index); + SASSERT(c.m_i != piv_row_index); if(! m_A.pivot_row_to_row_given_cell(piv_row_index, c, j)) { return false; } @@ -687,7 +702,7 @@ non_basis_is_correctly_represented_in_heading() const { } for (unsigned j = 0; j < m_A.column_count(); j++) { if (m_basis_heading[j] >= 0) { - lean_assert(static_cast(m_basis_heading[j]) < m_A.row_count() && m_basis[m_basis_heading[j]] == j); + SASSERT(static_cast(m_basis_heading[j]) < m_A.row_count() && m_basis[m_basis_heading[j]] == j); } } return true; @@ -695,9 +710,9 @@ non_basis_is_correctly_represented_in_heading() const { template bool lp_core_solver_base:: basis_heading_is_correct() const { - lean_assert(m_basis_heading.size() == m_A.column_count()); - lean_assert(m_basis.size() == m_A.row_count()); - lean_assert(m_nbasis.size() <= m_A.column_count() - m_A.row_count()); // for the dual the size of non basis can be smaller + SASSERT(m_basis_heading.size() == m_A.column_count()); + SASSERT(m_basis.size() == m_A.row_count()); + SASSERT(m_nbasis.size() <= m_A.column_count() - m_A.row_count()); // for the dual the size of non basis can be smaller if (!basis_has_no_doubles()) { // std::cout << "basis_has_no_doubles" << std::endl; return false; @@ -841,7 +856,7 @@ solve_Ax_eq_b() { template void lp_core_solver_base:: snap_non_basic_x_to_bound_and_free_to_zeroes() { for (unsigned j : non_basis()) { - lean_assert(j < m_x.size()); + SASSERT(j < m_x.size()); switch (m_column_types[j]) { case column_type::fixed: case column_type::boxed: @@ -892,9 +907,9 @@ get_non_basic_column_value_position(unsigned j) const { case column_type::upper_bound: return x_is_at_upper_bound(j)? at_upper_bound : not_at_bound; default: - lean_unreachable(); + SASSERT(false); } - lean_unreachable(); + SASSERT(false); return at_low_bound; } @@ -958,7 +973,7 @@ template void lp_core_solver_base::pivot_fixed_v break; } } - lean_assert(m_factorization->get_status()== LU_status::OK); + SASSERT(m_factorization->get_status()== LU_status::OK); } } @@ -966,7 +981,7 @@ template bool lp_core_solver_base::infeasibility_costs_are_correct() const { if (! this->m_using_infeas_costs) return true; - lean_assert(costs_on_nbasis_are_zeros()); + SASSERT(costs_on_nbasis_are_zeros()); for (unsigned j :this->m_basis) { if (!infeasibility_cost_is_correct_for_column(j)) { std::cout << "infeasibility_cost_is_correct_for_column does not hold\n"; @@ -1011,7 +1026,7 @@ lp_core_solver_base::infeasibility_cost_is_correct_for_column(unsigned j) case column_type::free_column: return is_zero(this->m_costs[j]); default: - lean_assert(false); + SASSERT(false); return true; } } diff --git a/src/util/lp/lp_core_solver_base_instances.cpp b/src/util/lp/lp_core_solver_base_instances.cpp index 17dcb87db..f5853eecf 100644 --- a/src/util/lp/lp_core_solver_base_instances.cpp +++ b/src/util/lp/lp_core_solver_base_instances.cpp @@ -1,131 +1,146 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include #include "util/vector.h" #include #include "util/lp/lp_core_solver_base.hpp" -template bool lean::lp_core_solver_base::A_mult_x_is_off() const; -template bool lean::lp_core_solver_base::A_mult_x_is_off_on_index(const vector &) const; -template bool lean::lp_core_solver_base::basis_heading_is_correct() const; -template void lean::lp_core_solver_base::calculate_pivot_row_of_B_1(unsigned int); -template void lean::lp_core_solver_base::calculate_pivot_row_when_pivot_row_of_B1_is_ready(unsigned); -template bool lean::lp_core_solver_base::column_is_dual_feasible(unsigned int) const; -template void lean::lp_core_solver_base::fill_reduced_costs_from_m_y_by_rows(); -template bool lean::lp_core_solver_base::find_x_by_solving(); -template lean::non_basic_column_value_position lean::lp_core_solver_base::get_non_basic_column_value_position(unsigned int) const; -template lean::non_basic_column_value_position lean::lp_core_solver_base >::get_non_basic_column_value_position(unsigned int) const; -template lean::non_basic_column_value_position lean::lp_core_solver_base::get_non_basic_column_value_position(unsigned int) const; -template void lean::lp_core_solver_base::init_reduced_costs_for_one_iteration(); -template lean::lp_core_solver_base::lp_core_solver_base( - lean::static_matrix&, vector&, +template bool lp::lp_core_solver_base::A_mult_x_is_off() const; +template bool lp::lp_core_solver_base::A_mult_x_is_off_on_index(const vector &) const; +template bool lp::lp_core_solver_base::basis_heading_is_correct() const; +template void lp::lp_core_solver_base::calculate_pivot_row_of_B_1(unsigned int); +template void lp::lp_core_solver_base::calculate_pivot_row_when_pivot_row_of_B1_is_ready(unsigned); +template bool lp::lp_core_solver_base::column_is_dual_feasible(unsigned int) const; +template void lp::lp_core_solver_base::fill_reduced_costs_from_m_y_by_rows(); +template bool lp::lp_core_solver_base::find_x_by_solving(); +template lp::non_basic_column_value_position lp::lp_core_solver_base::get_non_basic_column_value_position(unsigned int) const; +template lp::non_basic_column_value_position lp::lp_core_solver_base >::get_non_basic_column_value_position(unsigned int) const; +template lp::non_basic_column_value_position lp::lp_core_solver_base::get_non_basic_column_value_position(unsigned int) const; +template void lp::lp_core_solver_base::init_reduced_costs_for_one_iteration(); +template lp::lp_core_solver_base::lp_core_solver_base( + lp::static_matrix&, vector&, vector&, vector &, vector &, vector&, vector&, - lean::lp_settings&, const column_namer&, const vector&, + lp::lp_settings&, const column_namer&, const vector&, const vector&, const vector&); -template bool lean::lp_core_solver_base::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &); -template bool lean::lp_core_solver_base >::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &); -template void lean::lp_core_solver_base::restore_x(unsigned int, double const&); -template void lean::lp_core_solver_base::set_non_basic_x_to_correct_bounds(); -template void lean::lp_core_solver_base::snap_xN_to_bounds_and_free_columns_to_zeroes(); -template void lean::lp_core_solver_base >::snap_xN_to_bounds_and_free_columns_to_zeroes(); -template void lean::lp_core_solver_base::solve_Ax_eq_b(); -template void lean::lp_core_solver_base::solve_Bd(unsigned int); -template void lean::lp_core_solver_base>::solve_Bd(unsigned int, indexed_vector&); -template void lean::lp_core_solver_base::solve_yB(vector&); -template bool lean::lp_core_solver_base::update_basis_and_x(int, int, double const&); -template void lean::lp_core_solver_base::update_x(unsigned int, const double&); -template bool lean::lp_core_solver_base::A_mult_x_is_off() const; -template bool lean::lp_core_solver_base::A_mult_x_is_off_on_index(const vector &) const; -template bool lean::lp_core_solver_base::basis_heading_is_correct() const ; -template void lean::lp_core_solver_base::calculate_pivot_row_of_B_1(unsigned int); -template void lean::lp_core_solver_base::calculate_pivot_row_when_pivot_row_of_B1_is_ready(unsigned); -template bool lean::lp_core_solver_base::column_is_dual_feasible(unsigned int) const; -template void lean::lp_core_solver_base::fill_reduced_costs_from_m_y_by_rows(); -template bool lean::lp_core_solver_base::find_x_by_solving(); -template void lean::lp_core_solver_base::init_reduced_costs_for_one_iteration(); -template bool lean::lp_core_solver_base::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &); -template void lean::lp_core_solver_base::restore_x(unsigned int, lean::mpq const&); -template void lean::lp_core_solver_base::set_non_basic_x_to_correct_bounds(); -template void lean::lp_core_solver_base::solve_Ax_eq_b(); -template void lean::lp_core_solver_base::solve_Bd(unsigned int); -template void lean::lp_core_solver_base::solve_yB(vector&); -template bool lean::lp_core_solver_base::update_basis_and_x(int, int, lean::mpq const&); -template void lean::lp_core_solver_base::update_x(unsigned int, const lean::mpq&); -template void lean::lp_core_solver_base >::calculate_pivot_row_of_B_1(unsigned int); -template void lean::lp_core_solver_base >::calculate_pivot_row_when_pivot_row_of_B1_is_ready(unsigned); -template void lean::lp_core_solver_base >::init(); -template void lean::lp_core_solver_base >::init_basis_heading_and_non_basic_columns_vector(); -template void lean::lp_core_solver_base >::init_reduced_costs_for_one_iteration(); -template lean::lp_core_solver_base >::lp_core_solver_base(lean::static_matrix >&, vector >&, vector&, vector &, vector &, vector >&, vector&, lean::lp_settings&, const column_namer&, const vector&, - const vector >&, - const vector >&); -template bool lean::lp_core_solver_base >::print_statistics_with_cost_and_check_that_the_time_is_over(lean::numeric_pair, std::ostream&); -template void lean::lp_core_solver_base >::snap_xN_to_bounds_and_fill_xB(); -template void lean::lp_core_solver_base >::solve_Bd(unsigned int); -template bool lean::lp_core_solver_base >::update_basis_and_x(int, int, lean::numeric_pair const&); -template void lean::lp_core_solver_base >::update_x(unsigned int, const lean::numeric_pair&); -template lean::lp_core_solver_base::lp_core_solver_base( - lean::static_matrix&, - vector&, +template bool lp::lp_core_solver_base::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &); +template bool lp::lp_core_solver_base >::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &); +template void lp::lp_core_solver_base::restore_x(unsigned int, double const&); +template void lp::lp_core_solver_base::set_non_basic_x_to_correct_bounds(); +template void lp::lp_core_solver_base::snap_xN_to_bounds_and_free_columns_to_zeroes(); +template void lp::lp_core_solver_base >::snap_xN_to_bounds_and_free_columns_to_zeroes(); +template void lp::lp_core_solver_base::solve_Ax_eq_b(); +template void lp::lp_core_solver_base::solve_Bd(unsigned int); +template void lp::lp_core_solver_base>::solve_Bd(unsigned int, indexed_vector&); +template void lp::lp_core_solver_base::solve_yB(vector&); +template bool lp::lp_core_solver_base::update_basis_and_x(int, int, double const&); +template void lp::lp_core_solver_base::update_x(unsigned int, const double&); +template bool lp::lp_core_solver_base::A_mult_x_is_off() const; +template bool lp::lp_core_solver_base::A_mult_x_is_off_on_index(const vector &) const; +template bool lp::lp_core_solver_base::basis_heading_is_correct() const ; +template void lp::lp_core_solver_base::calculate_pivot_row_of_B_1(unsigned int); +template void lp::lp_core_solver_base::calculate_pivot_row_when_pivot_row_of_B1_is_ready(unsigned); +template bool lp::lp_core_solver_base::column_is_dual_feasible(unsigned int) const; +template void lp::lp_core_solver_base::fill_reduced_costs_from_m_y_by_rows(); +template bool lp::lp_core_solver_base::find_x_by_solving(); +template void lp::lp_core_solver_base::init_reduced_costs_for_one_iteration(); +template bool lp::lp_core_solver_base::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &); +template void lp::lp_core_solver_base::restore_x(unsigned int, lp::mpq const&); +template void lp::lp_core_solver_base::set_non_basic_x_to_correct_bounds(); +template void lp::lp_core_solver_base::solve_Ax_eq_b(); +template void lp::lp_core_solver_base::solve_Bd(unsigned int); +template void lp::lp_core_solver_base::solve_yB(vector&); +template bool lp::lp_core_solver_base::update_basis_and_x(int, int, lp::mpq const&); +template void lp::lp_core_solver_base::update_x(unsigned int, const lp::mpq&); +template void lp::lp_core_solver_base >::calculate_pivot_row_of_B_1(unsigned int); +template void lp::lp_core_solver_base >::calculate_pivot_row_when_pivot_row_of_B1_is_ready(unsigned); +template void lp::lp_core_solver_base >::init(); +template void lp::lp_core_solver_base >::init_basis_heading_and_non_basic_columns_vector(); +template void lp::lp_core_solver_base >::init_reduced_costs_for_one_iteration(); +template lp::lp_core_solver_base >::lp_core_solver_base(lp::static_matrix >&, vector >&, vector&, vector &, vector &, vector >&, vector&, lp::lp_settings&, const column_namer&, const vector&, + const vector >&, + const vector >&); +template bool lp::lp_core_solver_base >::print_statistics_with_cost_and_check_that_the_time_is_over(lp::numeric_pair, std::ostream&); +template void lp::lp_core_solver_base >::snap_xN_to_bounds_and_fill_xB(); +template void lp::lp_core_solver_base >::solve_Bd(unsigned int); +template bool lp::lp_core_solver_base >::update_basis_and_x(int, int, lp::numeric_pair const&); +template void lp::lp_core_solver_base >::update_x(unsigned int, const lp::numeric_pair&); +template lp::lp_core_solver_base::lp_core_solver_base( + lp::static_matrix&, + vector&, vector&, vector &, vector &, - vector&, - vector&, - lean::lp_settings&, + vector&, + vector&, + lp::lp_settings&, const column_namer&, - const vector&, - const vector&, - const vector&); -template bool lean::lp_core_solver_base >::print_statistics_with_iterations_and_check_that_the_time_is_over(std::ostream &); -template std::string lean::lp_core_solver_base::column_name(unsigned int) const; -template void lean::lp_core_solver_base::pretty_print(std::ostream & out); -template void lean::lp_core_solver_base::restore_state(double*, double*); -template void lean::lp_core_solver_base::save_state(double*, double*); -template std::string lean::lp_core_solver_base::column_name(unsigned int) const; -template void lean::lp_core_solver_base::pretty_print(std::ostream & out); -template void lean::lp_core_solver_base::restore_state(lean::mpq*, lean::mpq*); -template void lean::lp_core_solver_base::save_state(lean::mpq*, lean::mpq*); -template std::string lean::lp_core_solver_base >::column_name(unsigned int) const; -template void lean::lp_core_solver_base >::pretty_print(std::ostream & out); -template void lean::lp_core_solver_base >::restore_state(lean::mpq*, lean::mpq*); -template void lean::lp_core_solver_base >::save_state(lean::mpq*, lean::mpq*); -template void lean::lp_core_solver_base >::solve_yB(vector&); -template void lean::lp_core_solver_base::init_lu(); -template void lean::lp_core_solver_base::init_lu(); -template int lean::lp_core_solver_base::pivots_in_column_and_row_are_different(int, int) const; -template int lean::lp_core_solver_base >::pivots_in_column_and_row_are_different(int, int) const; -template int lean::lp_core_solver_base::pivots_in_column_and_row_are_different(int, int) const; -template bool lean::lp_core_solver_base::calc_current_x_is_feasible_include_non_basis(void)const; -template bool lean::lp_core_solver_base::calc_current_x_is_feasible_include_non_basis(void)const; -template bool lean::lp_core_solver_base >::calc_current_x_is_feasible_include_non_basis() const; -template void lean::lp_core_solver_base >::pivot_fixed_vars_from_basis(); -template bool lean::lp_core_solver_base::column_is_feasible(unsigned int) const; -template bool lean::lp_core_solver_base::column_is_feasible(unsigned int) const; -// template void lean::lp_core_solver_base >::print_linear_combination_of_column_indices(vector, std::allocator > > const&, std::ostream&) const; -template bool lean::lp_core_solver_base >::column_is_feasible(unsigned int) const; -template bool lean::lp_core_solver_base >::snap_non_basic_x_to_bound(); -template void lean::lp_core_solver_base >::init_lu(); -template bool lean::lp_core_solver_base >::A_mult_x_is_off_on_index(vector const&) const; -template bool lean::lp_core_solver_base >::find_x_by_solving(); -template void lean::lp_core_solver_base >::restore_x(unsigned int, lean::numeric_pair const&); -template bool lean::lp_core_solver_base::pivot_for_tableau_on_basis(); -template bool lean::lp_core_solver_base::pivot_for_tableau_on_basis(); -template bool lean::lp_core_solver_base>::pivot_for_tableau_on_basis(); -template bool lean::lp_core_solver_base>::pivot_column_tableau(unsigned int, unsigned int); -template bool lean::lp_core_solver_base::pivot_column_tableau(unsigned int, unsigned int); -template bool lean::lp_core_solver_base::pivot_column_tableau(unsigned int, unsigned int); -template void lean::lp_core_solver_base >::transpose_rows_tableau(unsigned int, unsigned int); -template bool lean::lp_core_solver_base >::inf_set_is_correct() const; -template bool lean::lp_core_solver_base::inf_set_is_correct() const; -template bool lean::lp_core_solver_base::inf_set_is_correct() const; -template bool lean::lp_core_solver_base >::infeasibility_costs_are_correct() const; -template bool lean::lp_core_solver_base::infeasibility_costs_are_correct() const; -template bool lean::lp_core_solver_base::infeasibility_costs_are_correct() const; + const vector&, + const vector&, + const vector&); +template bool lp::lp_core_solver_base >::print_statistics_with_iterations_and_check_that_the_time_is_over(std::ostream &); +template std::string lp::lp_core_solver_base::column_name(unsigned int) const; +template void lp::lp_core_solver_base::pretty_print(std::ostream & out); +template void lp::lp_core_solver_base::restore_state(double*, double*); +template void lp::lp_core_solver_base::save_state(double*, double*); +template std::string lp::lp_core_solver_base::column_name(unsigned int) const; +template void lp::lp_core_solver_base::pretty_print(std::ostream & out); +template void lp::lp_core_solver_base::restore_state(lp::mpq*, lp::mpq*); +template void lp::lp_core_solver_base::save_state(lp::mpq*, lp::mpq*); +template std::string lp::lp_core_solver_base >::column_name(unsigned int) const; +template void lp::lp_core_solver_base >::pretty_print(std::ostream & out); +template void lp::lp_core_solver_base >::restore_state(lp::mpq*, lp::mpq*); +template void lp::lp_core_solver_base >::save_state(lp::mpq*, lp::mpq*); +template void lp::lp_core_solver_base >::solve_yB(vector&); +template void lp::lp_core_solver_base::init_lu(); +template void lp::lp_core_solver_base::init_lu(); +template int lp::lp_core_solver_base::pivots_in_column_and_row_are_different(int, int) const; +template int lp::lp_core_solver_base >::pivots_in_column_and_row_are_different(int, int) const; +template int lp::lp_core_solver_base::pivots_in_column_and_row_are_different(int, int) const; +template bool lp::lp_core_solver_base::calc_current_x_is_feasible_include_non_basis(void)const; +template bool lp::lp_core_solver_base::calc_current_x_is_feasible_include_non_basis(void)const; +template bool lp::lp_core_solver_base >::calc_current_x_is_feasible_include_non_basis() const; +template void lp::lp_core_solver_base >::pivot_fixed_vars_from_basis(); +template bool lp::lp_core_solver_base::column_is_feasible(unsigned int) const; +template bool lp::lp_core_solver_base::column_is_feasible(unsigned int) const; +// template void lp::lp_core_solver_base >::print_linear_combination_of_column_indices(vector, std::allocator > > const&, std::ostream&) const; +template bool lp::lp_core_solver_base >::column_is_feasible(unsigned int) const; +template bool lp::lp_core_solver_base >::snap_non_basic_x_to_bound(); +template void lp::lp_core_solver_base >::init_lu(); +template bool lp::lp_core_solver_base >::A_mult_x_is_off_on_index(vector const&) const; +template bool lp::lp_core_solver_base >::find_x_by_solving(); +template void lp::lp_core_solver_base >::restore_x(unsigned int, lp::numeric_pair const&); +template bool lp::lp_core_solver_base::pivot_for_tableau_on_basis(); +template bool lp::lp_core_solver_base::pivot_for_tableau_on_basis(); +template bool lp::lp_core_solver_base>::pivot_for_tableau_on_basis(); +template bool lp::lp_core_solver_base>::pivot_column_tableau(unsigned int, unsigned int); +template bool lp::lp_core_solver_base::pivot_column_tableau(unsigned int, unsigned int); +template bool lp::lp_core_solver_base::pivot_column_tableau(unsigned int, unsigned int); +template void lp::lp_core_solver_base >::transpose_rows_tableau(unsigned int, unsigned int); +template bool lp::lp_core_solver_base >::inf_set_is_correct() const; +template bool lp::lp_core_solver_base::inf_set_is_correct() const; +template bool lp::lp_core_solver_base::inf_set_is_correct() const; +template bool lp::lp_core_solver_base >::infeasibility_costs_are_correct() const; +template bool lp::lp_core_solver_base::infeasibility_costs_are_correct() const; +template bool lp::lp_core_solver_base::infeasibility_costs_are_correct() const; diff --git a/src/util/lp/lp_dual_core_solver.h b/src/util/lp/lp_dual_core_solver.h index b873cb711..ba4be494f 100644 --- a/src/util/lp/lp_dual_core_solver.h +++ b/src/util/lp/lp_dual_core_solver.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/static_matrix.h" #include "util/lp/lp_core_solver_base.h" @@ -11,7 +26,7 @@ #include #include "util/vector.h" -namespace lean { +namespace lp { template class lp_dual_core_solver:public lp_core_solver_base { public: diff --git a/src/util/lp/lp_dual_core_solver.hpp b/src/util/lp/lp_dual_core_solver.hpp index 6565331b3..5d48fe24d 100644 --- a/src/util/lp/lp_dual_core_solver.hpp +++ b/src/util/lp/lp_dual_core_solver.hpp @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include "util/vector.h" #include "util/lp/lp_dual_core_solver.h" -namespace lean { +namespace lp { template void lp_dual_core_solver::init_a_wave_by_zeros() { unsigned j = this->m_m(); @@ -23,7 +38,7 @@ template void lp_dual_core_solver::restore_non_ba while (j--) { if (this->m_basis_heading[j] >= 0 ) continue; if (m_can_enter_basis[j]) { - lean_assert(std::find(nb.begin(), nb.end(), j) == nb.end()); + SASSERT(std::find(nb.begin(), nb.end(), j) == nb.end()); nb.push_back(j); this->m_basis_heading[j] = - static_cast(nb.size()); } @@ -93,14 +108,14 @@ template bool lp_dual_core_solver::done() { } template T lp_dual_core_solver::get_edge_steepness_for_low_bound(unsigned p) { - lean_assert(this->m_basis_heading[p] >= 0 && static_cast(this->m_basis_heading[p]) < this->m_m()); + SASSERT(this->m_basis_heading[p] >= 0 && static_cast(this->m_basis_heading[p]) < this->m_m()); T del = this->m_x[p] - this->m_low_bounds[p]; del *= del; return del / this->m_betas[this->m_basis_heading[p]]; } template T lp_dual_core_solver::get_edge_steepness_for_upper_bound(unsigned p) { - lean_assert(this->m_basis_heading[p] >= 0 && static_cast(this->m_basis_heading[p]) < this->m_m()); + SASSERT(this->m_basis_heading[p] >= 0 && static_cast(this->m_basis_heading[p]) < this->m_m()); T del = this->m_x[p] - this->m_upper_bounds[p]; del *= del; return del / this->m_betas[this->m_basis_heading[p]]; @@ -135,12 +150,12 @@ template T lp_dual_core_solver::pricing_for_row(u return numeric_traits::zero(); break; case column_type::free_column: - lean_assert(numeric_traits::is_zero(this->m_d[p])); + SASSERT(numeric_traits::is_zero(this->m_d[p])); return numeric_traits::zero(); default: - lean_unreachable(); + SASSERT(false); } - lean_unreachable(); + SASSERT(false); return numeric_traits::zero(); } @@ -209,9 +224,9 @@ template bool lp_dual_core_solver::advance_on_kno int pivot_compare_result = this->pivots_in_column_and_row_are_different(m_q, m_p); if (!pivot_compare_result){;} else if (pivot_compare_result == 2) { // the sign is changed, cannot continue - lean_unreachable(); // not implemented yet + SASSERT(false); // not implemented yet } else { - lean_assert(pivot_compare_result == 1); + SASSERT(pivot_compare_result == 1); this->init_lu(); } DSE_FTran(); @@ -228,21 +243,21 @@ template int lp_dual_core_solver::define_sign_of_ if (this->x_above_upper_bound(m_p)) { return 1; } - lean_unreachable(); + SASSERT(false); case column_type::low_bound: if (this->x_below_low_bound(m_p)) { return -1; } - lean_unreachable(); + SASSERT(false); case column_type::upper_bound: if (this->x_above_upper_bound(m_p)) { return 1; } - lean_unreachable(); + SASSERT(false); default: - lean_unreachable(); + SASSERT(false); } - lean_unreachable(); + SASSERT(false); return 0; } @@ -250,10 +265,10 @@ template bool lp_dual_core_solver::can_be_breakpo if (this->pivot_row_element_is_too_small_for_ratio_test(j)) return false; switch (this->m_column_types[j]) { case column_type::low_bound: - lean_assert(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_low_bounds[j])); + SASSERT(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_low_bounds[j])); return m_sign_of_alpha_r * this->m_pivot_row[j] > 0; case column_type::upper_bound: - lean_assert(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_upper_bounds[j])); + SASSERT(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_upper_bounds[j])); return m_sign_of_alpha_r * this->m_pivot_row[j] < 0; case column_type::boxed: { @@ -292,23 +307,23 @@ template T lp_dual_core_solver::get_delta() { if (this->x_above_upper_bound(m_p)) { return this->m_x[m_p] - this->m_upper_bounds[m_p]; } - lean_unreachable(); + SASSERT(false); case column_type::low_bound: if (this->x_below_low_bound(m_p)) { return this->m_x[m_p] - this->m_low_bounds[m_p]; } - lean_unreachable(); + SASSERT(false); case column_type::upper_bound: if (this->x_above_upper_bound(m_p)) { return get_edge_steepness_for_upper_bound(m_p); } - lean_unreachable(); + SASSERT(false); case column_type::fixed: return this->m_x[m_p] - this->m_upper_bounds[m_p]; default: - lean_unreachable(); + SASSERT(false); } - lean_unreachable(); + SASSERT(false); return zero_of_type(); } @@ -355,7 +370,7 @@ template void lp_dual_core_solver::update_betas() template void lp_dual_core_solver::apply_flips() { for (unsigned j : m_flipped_boxed) { - lean_assert(this->x_is_at_bound(j)); + SASSERT(this->x_is_at_bound(j)); if (this->x_is_at_low_bound(j)) { this->m_x[j] = this->m_upper_bounds[j]; } else { @@ -385,7 +400,7 @@ template void lp_dual_core_solver::snap_xN_column case column_type::free_column: break; default: - lean_unreachable(); + SASSERT(false); } } @@ -441,7 +456,7 @@ template bool lp_dual_core_solver::basis_change_a return false; } - lean_assert(d_is_correct()); + SASSERT(d_is_correct()); return true; } @@ -457,7 +472,7 @@ template void lp_dual_core_solver::recover_leavin case free_of_bounds: this->m_x[m_q] = zero_of_type(); default: - lean_unreachable(); + SASSERT(false); } } @@ -584,7 +599,7 @@ template bool lp_dual_core_solver::tight_breakpoi template T lp_dual_core_solver::calculate_harris_delta_on_breakpoint_set() { bool first_time = true; T ret = zero_of_type(); - lean_assert(m_breakpoint_set.size() > 0); + SASSERT(m_breakpoint_set.size() > 0); for (auto j : m_breakpoint_set) { T t; if (this->x_is_at_low_bound(j)) { @@ -633,7 +648,7 @@ template void lp_dual_core_solver::find_q_on_tigh } } m_tight_set.erase(m_q); - lean_assert(m_q != -1); + SASSERT(m_q != -1); } template void lp_dual_core_solver::find_q_and_tight_set() { @@ -722,13 +737,13 @@ template void lp_dual_core_solver::one_iteration( this->set_status(FEASIBLE); } pricing_loop(number_of_rows_to_try, offset_in_rows); - lean_assert(problem_is_dual_feasible()); + SASSERT(problem_is_dual_feasible()); } template void lp_dual_core_solver::solve() { // see the page 35 - lean_assert(d_is_correct()); - lean_assert(problem_is_dual_feasible()); - lean_assert(this->basis_heading_is_correct()); + SASSERT(d_is_correct()); + SASSERT(problem_is_dual_feasible()); + SASSERT(this->basis_heading_is_correct()); this->set_total_iterations(0); this->iters_with_no_cost_growing() = 0; do { diff --git a/src/util/lp/lp_dual_core_solver_instances.cpp b/src/util/lp/lp_dual_core_solver_instances.cpp index 8016088f8..db68bda65 100644 --- a/src/util/lp/lp_dual_core_solver_instances.cpp +++ b/src/util/lp/lp_dual_core_solver_instances.cpp @@ -1,29 +1,44 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include #include "util/vector.h" #include #include "util/lp/lp_dual_core_solver.hpp" -template void lean::lp_dual_core_solver::start_with_initial_basis_and_make_it_dual_feasible(); -template void lean::lp_dual_core_solver::solve(); -template lean::lp_dual_core_solver::lp_dual_core_solver(lean::static_matrix&, vector&, +template void lp::lp_dual_core_solver::start_with_initial_basis_and_make_it_dual_feasible(); +template void lp::lp_dual_core_solver::solve(); +template lp::lp_dual_core_solver::lp_dual_core_solver(lp::static_matrix&, vector&, vector&, vector&, vector&, vector &, vector &, vector&, - vector&, + vector&, vector&, vector&, - lean::lp_settings&, const lean::column_namer&); -template void lean::lp_dual_core_solver::start_with_initial_basis_and_make_it_dual_feasible(); -template void lean::lp_dual_core_solver::solve(); -template void lean::lp_dual_core_solver::restore_non_basis(); -template void lean::lp_dual_core_solver::restore_non_basis(); -template void lean::lp_dual_core_solver::revert_to_previous_basis(); -template void lean::lp_dual_core_solver::revert_to_previous_basis(); + lp::lp_settings&, const lp::column_namer&); +template void lp::lp_dual_core_solver::start_with_initial_basis_and_make_it_dual_feasible(); +template void lp::lp_dual_core_solver::solve(); +template void lp::lp_dual_core_solver::restore_non_basis(); +template void lp::lp_dual_core_solver::restore_non_basis(); +template void lp::lp_dual_core_solver::revert_to_previous_basis(); +template void lp::lp_dual_core_solver::revert_to_previous_basis(); diff --git a/src/util/lp/lp_dual_simplex.h b/src/util/lp/lp_dual_simplex.h index 4dff2a4f1..c17a9e99e 100644 --- a/src/util/lp/lp_dual_simplex.h +++ b/src/util/lp/lp_dual_simplex.h @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/lp/lp_utils.h" #include "util/lp/lp_solver.h" #include "util/lp/lp_dual_core_solver.h" -namespace lean { +namespace lp { template class lp_dual_simplex: public lp_solver { diff --git a/src/util/lp/lp_dual_simplex.hpp b/src/util/lp/lp_dual_simplex.hpp index 5047e117f..248dff448 100644 --- a/src/util/lp/lp_dual_simplex.hpp +++ b/src/util/lp/lp_dual_simplex.hpp @@ -1,9 +1,24 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lp_dual_simplex.h" -namespace lean{ +namespace lp{ template void lp_dual_simplex::decide_on_status_after_stage1() { switch (m_core_solver->get_status()) { @@ -15,7 +30,7 @@ template void lp_dual_simplex::decide_on_status_a } break; case DUAL_UNBOUNDED: - lean_unreachable(); + SASSERT(false); case ITERATIONS_EXHAUSTED: this->m_status = ITERATIONS_EXHAUSTED; break; @@ -26,12 +41,12 @@ template void lp_dual_simplex::decide_on_status_a this->m_status = FLOATING_POINT_ERROR; break; default: - lean_unreachable(); + SASSERT(false); } } template void lp_dual_simplex::fix_logical_for_stage2(unsigned j) { - lean_assert(j >= this->number_of_core_structurals()); + SASSERT(j >= this->number_of_core_structurals()); switch (m_column_types_of_logicals[j - this->number_of_core_structurals()]) { case column_type::low_bound: m_low_bounds[j] = numeric_traits::zero(); @@ -44,7 +59,7 @@ template void lp_dual_simplex::fix_logical_for_st m_can_enter_basis[j] = false; break; default: - lean_unreachable(); + SASSERT(false); } } @@ -58,7 +73,7 @@ template void lp_dual_simplex::fix_structural_for break; case column_type::fixed: case column_type::upper_bound: - lean_unreachable(); + SASSERT(false); case column_type::boxed: this->m_upper_bounds[j] = ci->get_adjusted_upper_bound() / this->m_column_scale[j]; m_low_bounds[j] = numeric_traits::zero(); @@ -70,7 +85,7 @@ template void lp_dual_simplex::fix_structural_for m_column_types_of_core_solver[j] = column_type::free_column; break; default: - lean_unreachable(); + SASSERT(false); } // T cost_was = this->m_costs[j]; this->set_scaled_cost(j); @@ -115,7 +130,7 @@ template void lp_dual_simplex::solve_for_stage2() this->m_status = FLOATING_POINT_ERROR; break; default: - lean_unreachable(); + SASSERT(false); } this->m_second_stage_iterations = m_core_solver->total_iterations(); this->m_total_iterations = (this->m_first_stage_iterations + this->m_second_stage_iterations); @@ -129,7 +144,7 @@ template void lp_dual_simplex::fill_x_with_zeros( } template void lp_dual_simplex::stage1() { - lean_assert(m_core_solver == nullptr); + SASSERT(m_core_solver == nullptr); this->m_x.resize(this->m_A->column_count(), numeric_traits::zero()); if (this->m_settings.get_message_ostream() != nullptr) this->print_statistics_on_A(*this->m_settings.get_message_ostream()); @@ -177,7 +192,7 @@ template void lp_dual_simplex::fill_first_stage_s } template column_type lp_dual_simplex::get_column_type(unsigned j) { - lean_assert(j < this->m_A->column_count()); + SASSERT(j < this->m_A->column_count()); if (j >= this->number_of_core_structurals()) { return m_column_types_of_logicals[j - this->number_of_core_structurals()]; } @@ -186,12 +201,12 @@ template column_type lp_dual_simplex::get_column_ template void lp_dual_simplex::fill_costs_bounds_types_and_can_enter_basis_for_the_first_stage_solver_structural_column(unsigned j) { // see 4.7 in the dissertation of Achim Koberstein - lean_assert(this->m_core_solver_columns_to_external_columns.find(j) != + SASSERT(this->m_core_solver_columns_to_external_columns.find(j) != this->m_core_solver_columns_to_external_columns.end()); T free_bound = T(1e4); // see 4.8 unsigned jj = this->m_core_solver_columns_to_external_columns[j]; - lean_assert(this->m_map_from_var_index_to_column_info.find(jj) != this->m_map_from_var_index_to_column_info.end()); + SASSERT(this->m_map_from_var_index_to_column_info.find(jj) != this->m_map_from_var_index_to_column_info.end()); column_info * ci = this->m_map_from_var_index_to_column_info[jj]; switch (ci->get_column_type()) { case column_type::upper_bound: { @@ -221,14 +236,14 @@ template void lp_dual_simplex::fill_costs_bounds_ this->m_upper_bounds[j] = this->m_low_bounds[j] = numeric_traits::zero(); // is it needed? break; default: - lean_unreachable(); + SASSERT(false); } m_column_types_of_core_solver[j] = column_type::boxed; } template void lp_dual_simplex::fill_costs_bounds_types_and_can_enter_basis_for_the_first_stage_solver_logical_column(unsigned j) { this->m_costs[j] = 0; - lean_assert(get_column_type(j) != column_type::upper_bound); + SASSERT(get_column_type(j) != column_type::upper_bound); if ((m_can_enter_basis[j] = (get_column_type(j) == column_type::low_bound))) { m_column_types_of_core_solver[j] = column_type::boxed; this->m_low_bounds[j] = numeric_traits::zero(); @@ -254,7 +269,7 @@ template void lp_dual_simplex::fill_costs_and_bou template void lp_dual_simplex::fill_first_stage_solver_fields_for_row_slack_and_artificial(unsigned row, unsigned & slack_var, unsigned & artificial) { - lean_assert(row < this->row_count()); + SASSERT(row < this->row_count()); auto & constraint = this->m_constraints[this->m_core_solver_rows_to_external_rows[row]]; // we need to bring the program to the form Ax = b T rs = this->m_b[row]; diff --git a/src/util/lp/lp_dual_simplex_instances.cpp b/src/util/lp/lp_dual_simplex_instances.cpp index 6610814d8..9e45849de 100644 --- a/src/util/lp/lp_dual_simplex_instances.cpp +++ b/src/util/lp/lp_dual_simplex_instances.cpp @@ -1,9 +1,24 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lp_dual_simplex.hpp" -template lean::mpq lean::lp_dual_simplex::get_current_cost() const; -template void lean::lp_dual_simplex::find_maximal_solution(); -template double lean::lp_dual_simplex::get_current_cost() const; -template void lean::lp_dual_simplex::find_maximal_solution(); +template lp::mpq lp::lp_dual_simplex::get_current_cost() const; +template void lp::lp_dual_simplex::find_maximal_solution(); +template double lp::lp_dual_simplex::get_current_cost() const; +template void lp::lp_dual_simplex::find_maximal_solution(); diff --git a/src/util/lp/lp_primal_core_solver.h b/src/util/lp/lp_primal_core_solver.h index f77aae6eb..a7614862b 100644 --- a/src/util/lp/lp_primal_core_solver.h +++ b/src/util/lp/lp_primal_core_solver.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include @@ -23,7 +38,7 @@ #include "util/lp/binary_heap_priority_queue.h" #include "util/lp/int_set.h" #include "util/lp/iterator_on_row.h" -namespace lean { +namespace lp { // This core solver solves (Ax=b, low_bound_values \leq x \leq upper_bound_values, maximize costs*x ) // The right side b is given implicitly by x and the basis @@ -70,7 +85,7 @@ public: // unsigned len = 100000000; // for (unsigned j : this->m_inf_set.m_index) { // int i = this->m_basis_heading[j]; - // lean_assert(i >= 0); + // SASSERT(i >= 0); // unsigned row_len = this->m_A.m_rows[i].size(); // if (row_len < len) { // choices.clear(); @@ -98,8 +113,8 @@ public: bool column_is_benefitial_for_entering_basis_on_sign_row_strategy(unsigned j, int sign) const { // sign = 1 means the x of the basis column of the row has to grow to become feasible, when the coeff before j is neg, or x - has to diminish when the coeff is pos // we have xbj = -aj * xj - lean_assert(this->m_basis_heading[j] < 0); - lean_assert(this->column_is_feasible(j)); + SASSERT(this->m_basis_heading[j] < 0); + SASSERT(this->column_is_feasible(j)); switch (this->m_column_types[j]) { case column_type::free_column: return true; case column_type::fixed: return false; @@ -117,13 +132,13 @@ public: return !this->x_is_at_upper_bound(j); } - lean_assert(false); // cannot be here + SASSERT(false); // cannot be here return false; } bool needs_to_grow(unsigned bj) const { - lean_assert(!this->column_is_feasible(bj)); + SASSERT(!this->column_is_feasible(bj)); switch(this->m_column_types[bj]) { case column_type::free_column: return false; @@ -134,12 +149,12 @@ public: default: return false; } - lean_assert(false); // unreachable + SASSERT(false); // unreachable return false; } int inf_sign_of_column(unsigned bj) const { - lean_assert(!this->column_is_feasible(bj)); + SASSERT(!this->column_is_feasible(bj)); switch(this->m_column_types[bj]) { case column_type::free_column: return 0; @@ -151,7 +166,7 @@ public: default: return -1; } - lean_assert(false); // unreachable + SASSERT(false); // unreachable return 0; } @@ -159,7 +174,7 @@ public: bool monoid_can_decrease(const row_cell & rc) const { unsigned j = rc.m_j; - lean_assert(this->column_is_feasible(j)); + SASSERT(this->column_is_feasible(j)); switch (this->m_column_types[j]) { case column_type::free_column: return true; @@ -186,13 +201,13 @@ public: default: return false; } - lean_assert(false); // unreachable + SASSERT(false); // unreachable return false; } bool monoid_can_increase(const row_cell & rc) const { unsigned j = rc.m_j; - lean_assert(this->column_is_feasible(j)); + SASSERT(this->column_is_feasible(j)); switch (this->m_column_types[j]) { case column_type::free_column: return true; @@ -219,7 +234,7 @@ public: default: return false; } - lean_assert(false); // unreachable + SASSERT(false); // unreachable return false; } @@ -329,24 +344,24 @@ public: } void limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(unsigned j, const T & m, X & theta, bool & unlimited) { - lean_assert(m < 0 && this->m_column_types[j] == column_type::upper_bound); + SASSERT(m < 0 && this->m_column_types[j] == column_type::upper_bound); limit_inf_on_upper_bound_m_neg(m, this->m_x[j], this->m_upper_bounds[j], theta, unlimited); } void limit_theta_on_basis_column_for_inf_case_m_neg_low_bound(unsigned j, const T & m, X & theta, bool & unlimited) { - lean_assert(m < 0 && this->m_column_types[j] == column_type::low_bound); + SASSERT(m < 0 && this->m_column_types[j] == column_type::low_bound); limit_inf_on_bound_m_neg(m, this->m_x[j], this->m_low_bounds[j], theta, unlimited); } void limit_theta_on_basis_column_for_inf_case_m_pos_low_bound(unsigned j, const T & m, X & theta, bool & unlimited) { - lean_assert(m > 0 && this->m_column_types[j] == column_type::low_bound); + SASSERT(m > 0 && this->m_column_types[j] == column_type::low_bound); limit_inf_on_low_bound_m_pos(m, this->m_x[j], this->m_low_bounds[j], theta, unlimited); } void limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(unsigned j, const T & m, X & theta, bool & unlimited) { - lean_assert(m > 0 && this->m_column_types[j] == column_type::upper_bound); + SASSERT(m > 0 && this->m_column_types[j] == column_type::upper_bound); limit_inf_on_bound_m_pos(m, this->m_x[j], this->m_upper_bounds[j], theta, unlimited); }; @@ -359,7 +374,7 @@ public: X get_max_bound(vector & b); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void check_Ax_equal_b(); void check_the_bounds(); void check_bound(unsigned i); @@ -388,7 +403,7 @@ public: bool need_to_switch_costs() const { if (this->m_settings.simplex_strategy() == simplex_strategy_enum::tableau_rows) return false; - // lean_assert(calc_current_x_is_feasible() == current_x_is_feasible()); + // SASSERT(calc_current_x_is_feasible() == current_x_is_feasible()); return this->current_x_is_feasible() == this->m_using_infeas_costs; } @@ -443,7 +458,7 @@ public: if (j == -1) return -1; - lean_assert(!this->column_is_feasible(j)); + SASSERT(!this->column_is_feasible(j)); switch (this->m_column_types[j]) { case column_type::fixed: case column_type::upper_bound: @@ -459,7 +474,7 @@ public: new_val_for_leaving = this->m_low_bounds[j]; break; default: - lean_assert(false); + SASSERT(false); new_val_for_leaving = numeric_traits::zero(); // does not matter } return j; @@ -490,7 +505,7 @@ public: } X theta = (this->m_x[leaving] - new_val_for_leaving) / a_ent; advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta ); - lean_assert(this->m_x[leaving] == new_val_for_leaving); + SASSERT(this->m_x[leaving] == new_val_for_leaving); if (this->current_x_is_feasible()) this->set_status(OPTIMAL); } @@ -507,13 +522,13 @@ public: void update_basis_and_x_with_comparison(unsigned entering, unsigned leaving, X delta); void decide_on_status_when_cannot_find_entering() { - lean_assert(!need_to_switch_costs()); + SASSERT(!need_to_switch_costs()); this->set_status(this->current_x_is_feasible()? OPTIMAL: INFEASIBLE); } // void limit_theta_on_basis_column_for_feas_case_m_neg(unsigned j, const T & m, X & theta) { - // lean_assert(m < 0); - // lean_assert(this->m_column_type[j] == low_bound || this->m_column_type[j] == boxed); + // SASSERT(m < 0); + // SASSERT(this->m_column_type[j] == low_bound || this->m_column_type[j] == boxed); // const X & eps = harris_eps_for_bound(this->m_low_bounds[j]); // if (this->above_bound(this->m_x[j], this->m_low_bounds[j])) { // theta = std::min((this->m_low_bounds[j] -this->m_x[j] - eps) / m, theta); @@ -522,7 +537,7 @@ public: // } void limit_theta_on_basis_column_for_feas_case_m_neg_no_check(unsigned j, const T & m, X & theta, bool & unlimited) { - lean_assert(m < 0); + SASSERT(m < 0); const X& eps = harris_eps_for_bound(this->m_low_bounds[j]); limit_theta((this->m_low_bounds[j] - this->m_x[j] - eps) / m, theta, unlimited); if (theta < zero_of_type()) theta = zero_of_type(); @@ -530,7 +545,7 @@ public: bool limit_inf_on_bound_m_neg(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) { // x gets smaller - lean_assert(m < 0); + SASSERT(m < 0); if (numeric_traits::precise()) { if (this->below_bound(x, bound)) return false; if (this->above_bound(x, bound)) { @@ -554,7 +569,7 @@ public: bool limit_inf_on_bound_m_pos(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) { // x gets larger - lean_assert(m > 0); + SASSERT(m > 0); if (numeric_traits::precise()) { if (this->above_bound(x, bound)) return false; if (this->below_bound(x, bound)) { @@ -579,14 +594,14 @@ public: void limit_inf_on_low_bound_m_pos(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) { if (numeric_traits::precise()) { // x gets larger - lean_assert(m > 0); + SASSERT(m > 0); if (this->below_bound(x, bound)) { limit_theta((bound - x) / m, theta, unlimited); } } else { // x gets larger - lean_assert(m > 0); + SASSERT(m > 0); const X& eps = harris_eps_for_bound(bound); if (this->below_bound(x, bound)) { limit_theta((bound - x + eps) / m, theta, unlimited); @@ -596,7 +611,7 @@ public: void limit_inf_on_upper_bound_m_neg(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) { // x gets smaller - lean_assert(m < 0); + SASSERT(m < 0); const X& eps = harris_eps_for_bound(bound); if (this->above_bound(x, bound)) { limit_theta((bound - x - eps) / m, theta, unlimited); @@ -604,7 +619,7 @@ public: } void limit_theta_on_basis_column_for_inf_case_m_pos_boxed(unsigned j, const T & m, X & theta, bool & unlimited) { - // lean_assert(m > 0 && this->m_column_type[j] == column_type::boxed); + // SASSERT(m > 0 && this->m_column_type[j] == column_type::boxed); const X & x = this->m_x[j]; const X & lbound = this->m_low_bounds[j]; @@ -624,7 +639,7 @@ public: } void limit_theta_on_basis_column_for_inf_case_m_neg_boxed(unsigned j, const T & m, X & theta, bool & unlimited) { - // lean_assert(m < 0 && this->m_column_type[j] == column_type::boxed); + // SASSERT(m < 0 && this->m_column_type[j] == column_type::boxed); const X & x = this->m_x[j]; const X & ubound = this->m_upper_bounds[j]; if (this->above_bound(x, ubound)) { @@ -642,7 +657,7 @@ public: } } void limit_theta_on_basis_column_for_feas_case_m_pos(unsigned j, const T & m, X & theta, bool & unlimited) { - lean_assert(m > 0); + SASSERT(m > 0); const T& eps = harris_eps_for_bound(this->m_upper_bounds[j]); if (this->below_bound(this->m_x[j], this->m_upper_bounds[j])) { limit_theta((this->m_upper_bounds[j] - this->m_x[j] + eps) / m, theta, unlimited); @@ -654,7 +669,7 @@ public: } void limit_theta_on_basis_column_for_feas_case_m_pos_no_check(unsigned j, const T & m, X & theta, bool & unlimited ) { - lean_assert(m > 0); + SASSERT(m > 0); const X& eps = harris_eps_for_bound(this->m_upper_bounds[j]); limit_theta( (this->m_upper_bounds[j] - this->m_x[j] + eps) / m, theta, unlimited); if (theta < zero_of_type()) { @@ -720,7 +735,7 @@ public: break; default: - lean_unreachable(); + SASSERT(false); } if (!unlimited && theta < zero_of_type()) { theta = zero_of_type(); @@ -803,7 +818,7 @@ public: case column_type::free_column: return 0; default: - lean_assert(false); + SASSERT(false); } return 0; } @@ -838,7 +853,7 @@ public: return -1; break; default: - lean_assert(false); + SASSERT(false); } return 0; @@ -864,7 +879,7 @@ public: // the delta is between the old and the new cost (old - new) void update_reduced_cost_for_basic_column_cost_change(const T & delta, unsigned j) { - lean_assert(this->m_basis_heading[j] >= 0); + SASSERT(this->m_basis_heading[j] >= 0); unsigned i = static_cast(this->m_basis_heading[j]); for (const row_cell & rc : this->m_A.m_rows[i]) { unsigned k = rc.m_j; @@ -943,10 +958,10 @@ public: upper_bound_values), m_beta(A.row_count()), m_converted_harris_eps(convert_struct::convert(this->m_settings.harris_feasibility_tolerance)) { - lean_assert(initial_x_is_correct()); + SASSERT(initial_x_is_correct()); m_low_bounds_dummy.resize(A.column_count(), zero_of_type()); m_enter_price_eps = numeric_traits::precise() ? numeric_traits::zero() : T(1e-5); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // check_correctness(); #endif } diff --git a/src/util/lp/lp_primal_core_solver.hpp b/src/util/lp/lp_primal_core_solver.hpp index 969d56812..5f81def51 100644 --- a/src/util/lp/lp_primal_core_solver.hpp +++ b/src/util/lp/lp_primal_core_solver.hpp @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include @@ -9,13 +24,13 @@ #include #include #include "util/lp/lp_primal_core_solver.h" -namespace lean { +namespace lp { // This core solver solves (Ax=b, low_bound_values \leq x \leq upper_bound_values, maximize costs*x ) // The right side b is given implicitly by x and the basis template void lp_primal_core_solver::sort_non_basis_rational() { - lean_assert(numeric_traits::precise()); + SASSERT(numeric_traits::precise()); if (this->m_settings.use_tableau()) { std::sort(this->m_nbasis.begin(), this->m_nbasis.end(), [this](unsigned a, unsigned b) { unsigned ca = this->m_A.number_of_non_zeroes_in_column(a); @@ -70,11 +85,11 @@ bool lp_primal_core_solver::column_is_benefitial_for_entering_on_breakpoin const T & d = this->m_d[j]; switch (this->m_column_types[j]) { case column_type::low_bound: - lean_assert(this->x_is_at_low_bound(j)); + SASSERT(this->x_is_at_low_bound(j)); ret = d < -m_epsilon_of_reduced_cost; break; case column_type::upper_bound: - lean_assert(this->x_is_at_upper_bound(j)); + SASSERT(this->x_is_at_upper_bound(j)); ret = d > m_epsilon_of_reduced_cost; break; case column_type::fixed: @@ -83,7 +98,7 @@ bool lp_primal_core_solver::column_is_benefitial_for_entering_on_breakpoin case column_type::boxed: { bool low_bound = this->x_is_at_low_bound(j); - lean_assert(low_bound || this->x_is_at_upper_bound(j)); + SASSERT(low_bound || this->x_is_at_upper_bound(j)); ret = (low_bound && d < -m_epsilon_of_reduced_cost) || ((!low_bound) && d > m_epsilon_of_reduced_cost); } break; @@ -91,7 +106,7 @@ bool lp_primal_core_solver::column_is_benefitial_for_entering_on_breakpoin ret = d > m_epsilon_of_reduced_cost || d < - m_epsilon_of_reduced_cost; break; default: - lean_unreachable(); + SASSERT(false); ret = false; break; } @@ -127,14 +142,14 @@ bool lp_primal_core_solver::column_is_benefitial_for_entering_basis(unsign } break; default: - lean_unreachable(); + SASSERT(false); break; } return false; } template bool lp_primal_core_solver::column_is_benefitial_for_entering_basis_precise(unsigned j) const { - lean_assert (numeric_traits::precise()); + SASSERT (numeric_traits::precise()); if (this->m_using_infeas_costs && this->m_settings.use_breakpoints_in_feasibility_search) return column_is_benefitial_for_entering_on_breakpoints(j); const T& dj = this->m_d[j]; @@ -167,7 +182,7 @@ bool lp_primal_core_solver::column_is_benefitial_for_entering_basis_precis } break; default: - lean_unreachable(); + SASSERT(false); break; } return false; @@ -175,7 +190,7 @@ bool lp_primal_core_solver::column_is_benefitial_for_entering_basis_precis template int lp_primal_core_solver::choose_entering_column_presize(unsigned number_of_benefitial_columns_to_go_over) { // at this moment m_y = cB * B(-1) - lean_assert(numeric_traits::precise()); + SASSERT(numeric_traits::precise()); if (number_of_benefitial_columns_to_go_over == 0) return -1; if (this->m_basis_sort_counter == 0) { @@ -259,7 +274,7 @@ int lp_primal_core_solver::choose_entering_column(unsigned number_of_benef template int lp_primal_core_solver::advance_on_sorted_breakpoints(unsigned entering, X &t) { T slope_at_entering = this->m_d[entering]; breakpoint * last_bp = nullptr; - lean_assert(m_breakpoint_indices_queue.is_empty()==false); + SASSERT(m_breakpoint_indices_queue.is_empty()==false); while (m_breakpoint_indices_queue.is_empty() == false) { unsigned bi = m_breakpoint_indices_queue.dequeue(); breakpoint *b = &m_breakpoints[bi]; @@ -274,7 +289,7 @@ template int lp_primal_core_solver::advance_on_so } } } - lean_assert (last_bp != nullptr); + SASSERT (last_bp != nullptr); t = last_bp->m_delta; return last_bp->m_j; } @@ -282,13 +297,13 @@ template int lp_primal_core_solver::advance_on_so template int lp_primal_core_solver::find_leaving_and_t_with_breakpoints(unsigned entering, X & t){ - lean_assert(this->precise() == false); + SASSERT(this->precise() == false); fill_breakpoints_array(entering); return advance_on_sorted_breakpoints(entering, t); } template bool lp_primal_core_solver::get_harris_theta(X & theta) { - lean_assert(this->m_ed.is_OK()); + SASSERT(this->m_ed.is_OK()); bool unlimited = true; for (unsigned i : this->m_ed.m_index) { if (this->m_settings.abs_val_is_smaller_than_pivot_tolerance(this->m_ed[i])) continue; @@ -345,13 +360,13 @@ template bool lp_primal_core_solver::try_jump_to_ if (m_sign_of_entering_delta > 0) { t = this->m_upper_bounds[entering] - this->m_x[entering]; if (unlimited || t <= theta){ - lean_assert(t >= zero_of_type()); + SASSERT(t >= zero_of_type()); return true; } } else { // m_sign_of_entering_delta == -1 t = this->m_x[entering] - this->m_low_bounds[entering]; if (unlimited || t <= theta) { - lean_assert(t >= zero_of_type()); + SASSERT(t >= zero_of_type()); return true; } } @@ -360,7 +375,7 @@ template bool lp_primal_core_solver::try_jump_to_ if (m_sign_of_entering_delta > 0) { t = this->m_upper_bounds[entering] - this->m_x[entering]; if (unlimited || t <= theta){ - lean_assert(t >= zero_of_type()); + SASSERT(t >= zero_of_type()); return true; } } @@ -369,7 +384,7 @@ template bool lp_primal_core_solver::try_jump_to_ if (m_sign_of_entering_delta < 0) { t = this->m_x[entering] - this->m_low_bounds[entering]; if (unlimited || t <= theta) { - lean_assert(t >= zero_of_type()); + SASSERT(t >= zero_of_type()); return true; } } @@ -405,7 +420,7 @@ template int lp_primal_core_solver::find_leaving_ do { unsigned i = this->m_ed.m_index[k]; const T & ed = this->m_ed[i]; - lean_assert(!numeric_traits::is_zero(ed)); + SASSERT(!numeric_traits::is_zero(ed)); unsigned j = this->m_basis[i]; limit_theta_on_basis_column(j, - ed * m_sign_of_entering_delta, t, unlimited); if (!unlimited) { @@ -424,7 +439,7 @@ template int lp_primal_core_solver::find_leaving_ while (k != initial_k) { unsigned i = this->m_ed.m_index[k]; const T & ed = this->m_ed[i]; - lean_assert(!numeric_traits::is_zero(ed)); + SASSERT(!numeric_traits::is_zero(ed)); unsigned j = this->m_basis[i]; unlimited = true; limit_theta_on_basis_column(j, -ed * m_sign_of_entering_delta, ratio, unlimited); @@ -464,7 +479,7 @@ template int lp_primal_core_solver::find_leavi return find_leaving_and_t_with_breakpoints(entering, t); X theta; bool unlimited = get_harris_theta(theta); - lean_assert(unlimited || theta >= zero_of_type()); + SASSERT(unlimited || theta >= zero_of_type()); if (try_jump_to_another_bound_on_entering(entering, theta, t, unlimited)) return entering; if (unlimited) return -1; @@ -529,11 +544,11 @@ template X lp_primal_core_solver::get_max_boun return ret; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template void lp_primal_core_solver::check_Ax_equal_b() { dense_matrix d(this->m_A); T * ls = d.apply_from_left_with_different_dims(this->m_x); - lean_assert(vectors_are_equal(ls, this->m_b, this->m_m())); + SASSERT(vectors_are_equal(ls, this->m_b, this->m_m())); delete [] ls; } template void lp_primal_core_solver::check_the_bounds() { @@ -543,8 +558,8 @@ template void lp_primal_core_solver::check_the } template void lp_primal_core_solver::check_bound(unsigned i) { - lean_assert (!(this->column_has_low_bound(i) && (numeric_traits::zero() > this->m_x[i]))); - lean_assert (!(this->column_has_upper_bound(i) && (this->m_upper_bounds[i] < this->m_x[i]))); + SASSERT (!(this->column_has_low_bound(i) && (numeric_traits::zero() > this->m_x[i]))); + SASSERT (!(this->column_has_upper_bound(i) && (this->m_upper_bounds[i] < this->m_x[i]))); } template void lp_primal_core_solver::check_correctness() { @@ -558,10 +573,10 @@ template void lp_primal_core_solver::check_cor template void lp_primal_core_solver::update_reduced_costs_from_pivot_row(unsigned entering, unsigned leaving) { // the basis heading has changed already -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG auto & basis_heading = this->m_basis_heading; - lean_assert(basis_heading[entering] >= 0 && static_cast(basis_heading[entering]) < this->m_m()); - lean_assert(basis_heading[leaving] < 0); + SASSERT(basis_heading[entering] >= 0 && static_cast(basis_heading[entering]) < this->m_m()); + SASSERT(basis_heading[leaving] < 0); #endif T pivot = this->m_pivot_row[entering]; T dq = this->m_d[entering]/pivot; @@ -584,7 +599,7 @@ void lp_primal_core_solver::update_reduced_costs_from_pivot_row(unsigned e template int lp_primal_core_solver::refresh_reduced_cost_at_entering_and_check_that_it_is_off(unsigned entering) { if (numeric_traits::precise()) return 0; T reduced_at_entering_was = this->m_d[entering]; // can benefit from going over non-zeros of m_ed - lean_assert(abs(reduced_at_entering_was) > m_epsilon_of_reduced_cost); + SASSERT(abs(reduced_at_entering_was) > m_epsilon_of_reduced_cost); T refreshed_cost = this->m_costs[entering]; unsigned i = this->m_m(); while (i--) refreshed_cost -= this->m_costs[this->m_basis[i]] * this->m_ed[i]; @@ -619,7 +634,7 @@ template void lp_primal_core_solver::backup_an m_costs_backup = this->m_costs; } else { T cost_max = std::max(max_abs_in_vector(this->m_costs), T(1)); - lean_assert(m_costs_backup.size() == 0); + SASSERT(m_costs_backup.size() == 0); for (unsigned j = 0; j < this->m_costs.size(); j++) m_costs_backup.push_back(this->m_costs[j] /= cost_max); } @@ -649,16 +664,16 @@ template void lp_primal_core_solver::init_run( template void lp_primal_core_solver::calc_working_vector_beta_for_column_norms(){ - lean_assert(numeric_traits::precise() == false); - lean_assert(this->m_ed.is_OK()); - lean_assert(m_beta.is_OK()); + SASSERT(numeric_traits::precise() == false); + SASSERT(this->m_ed.is_OK()); + SASSERT(m_beta.is_OK()); m_beta = this->m_ed; this->m_factorization->solve_yB_with_error_check_indexed(m_beta, this->m_basis_heading, this->m_basis, this->m_settings); } template void lp_primal_core_solver::advance_on_entering_equal_leaving(int entering, X & t) { - lean_assert(!this->A_mult_x_is_off() ); + SASSERT(!this->A_mult_x_is_off() ); this->update_x(entering, t * m_sign_of_entering_delta); if (this->A_mult_x_is_off_on_index(this->m_ed.m_index) && !this->find_x_by_solving()) { this->init_lu(); @@ -670,7 +685,7 @@ void lp_primal_core_solver::advance_on_entering_equal_leaving(int entering } } if (this->m_using_infeas_costs) { - lean_assert(is_zero(this->m_costs[entering])); + SASSERT(is_zero(this->m_costs[entering])); init_infeasibility_costs_for_changed_basis_only(); } if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible()) @@ -683,10 +698,10 @@ void lp_primal_core_solver::advance_on_entering_equal_leaving(int entering } template void lp_primal_core_solver::advance_on_entering_and_leaving(int entering, int leaving, X & t) { - lean_assert(entering >= 0 && m_non_basis_list.back() == static_cast(entering)); - lean_assert(this->m_using_infeas_costs || t >= zero_of_type()); - lean_assert(leaving >= 0 && entering >= 0); - lean_assert(entering != leaving || !is_zero(t)); // otherwise nothing changes + SASSERT(entering >= 0 && m_non_basis_list.back() == static_cast(entering)); + SASSERT(this->m_using_infeas_costs || t >= zero_of_type()); + SASSERT(leaving >= 0 && entering >= 0); + SASSERT(entering != leaving || !is_zero(t)); // otherwise nothing changes if (entering == leaving) { advance_on_entering_equal_leaving(entering, t); return; @@ -702,7 +717,7 @@ template void lp_primal_core_solver::advance_on_en this->iters_with_no_cost_growing()++; return; } else { - lean_assert(pivot_compare_result == 1); + SASSERT(pivot_compare_result == 1); this->init_lu(); if (this->m_factorization == nullptr || this->m_factorization->get_status() != LU_status::OK) { this->set_status(UNSTABLE); @@ -746,7 +761,7 @@ template void lp_primal_core_solver::advance_on_en } else { update_reduced_costs_from_pivot_row(entering, leaving); } - lean_assert(!need_to_switch_costs()); + SASSERT(!need_to_switch_costs()); std::list::iterator it = m_non_basis_list.end(); it--; * it = static_cast(leaving); @@ -754,8 +769,8 @@ template void lp_primal_core_solver::advance_on_en template void lp_primal_core_solver::advance_on_entering_precise(int entering) { - lean_assert(numeric_traits::precise()); - lean_assert(entering > -1); + SASSERT(numeric_traits::precise()); + SASSERT(entering > -1); this->solve_Bd(entering); X t; int leaving = find_leaving_and_t_precise(entering, t); @@ -771,7 +786,7 @@ template void lp_primal_core_solver::advance_on_e advance_on_entering_precise(entering); return; } - lean_assert(entering > -1); + SASSERT(entering > -1); this->solve_Bd(entering); int refresh_result = refresh_reduced_cost_at_entering_and_check_that_it_is_off(entering); if (refresh_result) { @@ -791,7 +806,7 @@ template void lp_primal_core_solver::advance_on_e int leaving = find_leaving_and_t(entering, t); if (leaving == -1){ if (!this->current_x_is_feasible()) { - lean_assert(!numeric_traits::precise()); // we cannot have unbounded with inf costs + SASSERT(!numeric_traits::precise()); // we cannot have unbounded with inf costs // if (m_look_for_feasible_solution_only) { // this->m_status = INFEASIBLE; @@ -865,7 +880,7 @@ template unsigned lp_primal_core_solver::solve() return this->total_iterations(); } one_iteration(); - lean_assert(!this->m_using_infeas_costs || this->costs_on_nbasis_are_zeros()); + SASSERT(!this->m_using_infeas_costs || this->costs_on_nbasis_are_zeros()); switch (this->get_status()) { case OPTIMAL: // double check that we are at optimum case INFEASIBLE: @@ -914,7 +929,7 @@ template unsigned lp_primal_core_solver::solve() break; case UNSTABLE: - lean_assert(! (numeric_traits::precise())); + SASSERT(! (numeric_traits::precise())); this->init_lu(); if (this->m_factorization->get_status() != LU_status::OK) { this->set_status(FLOATING_POINT_ERROR); @@ -940,7 +955,7 @@ template unsigned lp_primal_core_solver::solve() && !(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only)); - lean_assert(this->get_status() == FLOATING_POINT_ERROR + SASSERT(this->get_status() == FLOATING_POINT_ERROR || this->current_x_is_feasible() == false || @@ -957,7 +972,7 @@ template void lp_primal_core_solver::delete_fa // according to Swietanowski, " A new steepest edge approximation for the simplex method for linear programming" template void lp_primal_core_solver::init_column_norms() { - lean_assert(numeric_traits::precise() == false); + SASSERT(numeric_traits::precise() == false); for (unsigned j = 0; j < this->m_n(); j++) { this->m_column_norms[j] = T(static_cast(this->m_A.m_columns[j].size() + 1)) @@ -967,7 +982,7 @@ template void lp_primal_core_solver::init_column_ // debug only template T lp_primal_core_solver::calculate_column_norm_exactly(unsigned j) { - lean_assert(numeric_traits::precise() == false); + SASSERT(numeric_traits::precise() == false); indexed_vector w(this->m_m()); this->m_A.copy_column_to_vector(j, w); vector d(this->m_m()); @@ -979,8 +994,8 @@ template T lp_primal_core_solver::calculate_colum } template void lp_primal_core_solver::update_or_init_column_norms(unsigned entering, unsigned leaving) { - lean_assert(numeric_traits::precise() == false); - lean_assert(m_column_norm_update_counter <= this->m_settings.column_norms_update_frequency); + SASSERT(numeric_traits::precise() == false); + SASSERT(m_column_norm_update_counter <= this->m_settings.column_norms_update_frequency); if (m_column_norm_update_counter == this->m_settings.column_norms_update_frequency) { m_column_norm_update_counter = 0; init_column_norms(); @@ -992,7 +1007,7 @@ template void lp_primal_core_solver::update_or // following Swietanowski - A new steepest ... template void lp_primal_core_solver::update_column_norms(unsigned entering, unsigned leaving) { - lean_assert(numeric_traits::precise() == false); + SASSERT(numeric_traits::precise() == false); T pivot = this->m_pivot_row[entering]; T g_ent = calculate_norm_of_entering_exactly() / pivot / pivot; if (!numeric_traits::precise()) { @@ -1027,7 +1042,7 @@ template T lp_primal_core_solver::calculate_no // calling it stage1 is too cryptic template void lp_primal_core_solver::find_feasible_solution() { this->m_look_for_feasible_solution_only = true; - lean_assert(this->non_basic_columns_are_set_correctly()); + SASSERT(this->non_basic_columns_are_set_correctly()); this->set_status(UNKNOWN); solve(); } @@ -1095,8 +1110,8 @@ void lp_primal_core_solver::init_infeasibility_costs_for_changed_basis_onl template void lp_primal_core_solver::init_infeasibility_costs() { - lean_assert(this->m_x.size() >= this->m_n()); - lean_assert(this->m_column_types.size() >= this->m_n()); + SASSERT(this->m_x.size() >= this->m_n()); + SASSERT(this->m_column_types.size() >= this->m_n()); for (unsigned j = this->m_n(); j--;) init_infeasibility_cost_for_column(j); this->m_using_infeas_costs = true; @@ -1138,7 +1153,7 @@ lp_primal_core_solver::get_infeasibility_cost_for_column(unsigned j) const ret = numeric_traits::zero(); break; default: - lean_assert(false); + SASSERT(false); ret = numeric_traits::zero(); // does not matter break; } @@ -1192,7 +1207,7 @@ lp_primal_core_solver::init_infeasibility_cost_for_column(unsigned j) { this->m_costs[j] = numeric_traits::zero(); break; default: - lean_assert(false); + SASSERT(false); break; } @@ -1223,7 +1238,7 @@ template void lp_primal_core_solver::print_column case column_type::free_column: out << "( _" << this->m_x[j] << "_)" << std::endl; default: - lean_unreachable(); + SASSERT(false); } } @@ -1262,7 +1277,7 @@ template std::string lp_primal_core_solver::break case upper_break: return "upper_break"; case fixed_break: return "fixed_break"; default: - lean_assert(false); + SASSERT(false); break; } return "type is not found"; @@ -1275,7 +1290,7 @@ template void lp_primal_core_solver::print_breakp template void lp_primal_core_solver::init_reduced_costs() { - lean_assert(!this->use_tableau()); + SASSERT(!this->use_tableau()); if (this->current_x_is_infeasible() && !this->m_using_infeas_costs) { init_infeasibility_costs(); } else if (this->current_x_is_feasible() && this->m_using_infeas_costs) { @@ -1290,12 +1305,12 @@ void lp_primal_core_solver::init_reduced_costs() { template void lp_primal_core_solver::change_slope_on_breakpoint(unsigned entering, breakpoint * b, T & slope_at_entering) { if (b->m_j == entering) { - lean_assert(b->m_type != fixed_break && (!is_zero(b->m_delta))); + SASSERT(b->m_type != fixed_break && (!is_zero(b->m_delta))); slope_at_entering += m_sign_of_entering_delta; return; } - lean_assert(this->m_basis_heading[b->m_j] >= 0); + SASSERT(this->m_basis_heading[b->m_j] >= 0); unsigned i_row = this->m_basis_heading[b->m_j]; const T & d = - this->m_ed[i_row]; if (numeric_traits::is_zero(d)) return; @@ -1314,13 +1329,13 @@ template void lp_primal_core_solver::change_sl slope_at_entering += delta; break; default: - lean_assert(false); + SASSERT(false); } } template void lp_primal_core_solver::try_add_breakpoint_in_row(unsigned i) { - lean_assert(i < this->m_m()); + SASSERT(i < this->m_m()); const T & d = this->m_ed[i]; // the coefficient before m_entering in the i-th row if (d == 0) return; // the change of x[m_entering] will not change the corresponding basis x unsigned j = this->m_basis[i]; @@ -1342,7 +1357,7 @@ template void lp_primal_core_solver::try_add_b case column_type::free_column: break; default: - lean_assert(false); + SASSERT(false); break; } } @@ -1366,7 +1381,7 @@ template void lp_primal_core_solver::print_bound_ out << "inf, inf" << std::endl; break; default: - lean_assert(false); + SASSERT(false); break; } } diff --git a/src/util/lp/lp_primal_core_solver_instances.cpp b/src/util/lp/lp_primal_core_solver_instances.cpp index ca231fd34..fd5f42d67 100644 --- a/src/util/lp/lp_primal_core_solver_instances.cpp +++ b/src/util/lp/lp_primal_core_solver_instances.cpp @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include @@ -9,19 +24,19 @@ #include #include "util/lp/lar_solver.h" #include "util/lp/lp_primal_core_solver.hpp" -#include "util/lp/lp_primal_core_solver_tableau.hpp" -namespace lean { +#include "util/lp/lp_primal_core_solver_tableau.h" +namespace lp { template void lp_primal_core_solver::find_feasible_solution(); -template void lean::lp_primal_core_solver >::find_feasible_solution(); +template void lp::lp_primal_core_solver >::find_feasible_solution(); template unsigned lp_primal_core_solver::solve(); template unsigned lp_primal_core_solver::solve_with_tableau(); template unsigned lp_primal_core_solver::solve(); template unsigned lp_primal_core_solver >::solve(); -template void lean::lp_primal_core_solver::clear_breakpoints(); -template bool lean::lp_primal_core_solver::update_basis_and_x_tableau(int, int, lean::mpq const&); -template bool lean::lp_primal_core_solver::update_basis_and_x_tableau(int, int, double const&); -template bool lean::lp_primal_core_solver >::update_basis_and_x_tableau(int, int, lean::numeric_pair const&); +template void lp::lp_primal_core_solver::clear_breakpoints(); +template bool lp::lp_primal_core_solver::update_basis_and_x_tableau(int, int, lp::mpq const&); +template bool lp::lp_primal_core_solver::update_basis_and_x_tableau(int, int, double const&); +template bool lp::lp_primal_core_solver >::update_basis_and_x_tableau(int, int, lp::numeric_pair const&); } diff --git a/src/util/lp/lp_primal_core_solver_tableau.hpp b/src/util/lp/lp_primal_core_solver_tableau.h similarity index 90% rename from src/util/lp/lp_primal_core_solver_tableau.hpp rename to src/util/lp/lp_primal_core_solver_tableau.h index 0c09c22c9..97fa2f9da 100644 --- a/src/util/lp/lp_primal_core_solver_tableau.hpp +++ b/src/util/lp/lp_primal_core_solver_tableau.h @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ // this is a part of lp_primal_core_solver that deals with the tableau #include "util/lp/lp_primal_core_solver.h" -namespace lean { +namespace lp { template void lp_primal_core_solver::one_iteration_tableau() { int entering = choose_entering_column_tableau(); if (entering == -1) { @@ -13,7 +28,7 @@ template void lp_primal_core_solver::one_iteratio else { advance_on_entering_tableau(entering); } - lean_assert(this->inf_set_is_correct()); + SASSERT(this->inf_set_is_correct()); } template void lp_primal_core_solver::advance_on_entering_tableau(int entering) { @@ -37,7 +52,7 @@ template int lp_primal_core_solver::choose_enteri //this moment m_y = cB * B(-1) unsigned number_of_benefitial_columns_to_go_over = get_number_of_non_basic_column_to_try_for_enter(); - lean_assert(numeric_traits::precise()); + SASSERT(numeric_traits::precise()); if (number_of_benefitial_columns_to_go_over == 0) return -1; if (this->m_basis_sort_counter == 0) { @@ -149,7 +164,7 @@ unsigned lp_primal_core_solver::solve_with_tableau() { break; case UNSTABLE: - lean_assert(! (numeric_traits::precise())); + SASSERT(! (numeric_traits::precise())); this->init_lu(); if (this->m_factorization->get_status() != LU_status::OK) { this->set_status(FLOATING_POINT_ERROR); @@ -175,7 +190,7 @@ unsigned lp_primal_core_solver::solve_with_tableau() { && !(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only)); - lean_assert(this->get_status() == FLOATING_POINT_ERROR + SASSERT(this->get_status() == FLOATING_POINT_ERROR || this->current_x_is_feasible() == false || @@ -184,13 +199,13 @@ unsigned lp_primal_core_solver::solve_with_tableau() { } template void lp_primal_core_solver::advance_on_entering_and_leaving_tableau(int entering, int leaving, X & t) { - lean_assert(this->A_mult_x_is_off() == false); - lean_assert(leaving >= 0 && entering >= 0); - lean_assert((this->m_settings.simplex_strategy() == + SASSERT(this->A_mult_x_is_off() == false); + SASSERT(leaving >= 0 && entering >= 0); + SASSERT((this->m_settings.simplex_strategy() == simplex_strategy_enum::tableau_rows) || m_non_basis_list.back() == static_cast(entering)); - lean_assert(this->m_using_infeas_costs || !is_neg(t)); - lean_assert(entering != leaving || !is_zero(t)); // otherwise nothing changes + SASSERT(this->m_using_infeas_costs || !is_neg(t)); + SASSERT(entering != leaving || !is_zero(t)); // otherwise nothing changes if (entering == leaving) { advance_on_entering_equal_leaving_tableau(entering, t); return; @@ -201,7 +216,7 @@ template void lp_primal_core_solver::advance_on_en t = -t; } this->update_basis_and_x_tableau(entering, leaving, t); - lean_assert(this->A_mult_x_is_off() == false); + SASSERT(this->A_mult_x_is_off() == false); this->iters_with_no_cost_growing() = 0; } else { this->pivot_column_tableau(entering, this->m_basis_heading[leaving]); @@ -216,7 +231,7 @@ template void lp_primal_core_solver::advance_on_en this->init_reduced_costs_tableau(); } - lean_assert(!need_to_switch_costs()); + SASSERT(!need_to_switch_costs()); std::list::iterator it = m_non_basis_list.end(); it--; * it = static_cast(leaving); @@ -225,7 +240,7 @@ template void lp_primal_core_solver::advance_on_en template void lp_primal_core_solver::advance_on_entering_equal_leaving_tableau(int entering, X & t) { - lean_assert(!this->A_mult_x_is_off() ); + SASSERT(!this->A_mult_x_is_off() ); this->update_x_tableau(entering, t * m_sign_of_entering_delta); if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible()) return; @@ -246,7 +261,7 @@ template int lp_primal_core_solver::find_leaving_ const column_cell & c = col[k]; unsigned i = c.m_i; const T & ed = this->m_A.get_val(c); - lean_assert(!numeric_traits::is_zero(ed)); + SASSERT(!numeric_traits::is_zero(ed)); unsigned j = this->m_basis[i]; limit_theta_on_basis_column(j, - ed * m_sign_of_entering_delta, t, unlimited); if (!unlimited) { @@ -265,7 +280,7 @@ template int lp_primal_core_solver::find_leaving_ const column_cell & c = col[k]; unsigned i = c.m_i; const T & ed = this->m_A.get_val(c); - lean_assert(!numeric_traits::is_zero(ed)); + SASSERT(!numeric_traits::is_zero(ed)); unsigned j = this->m_basis[i]; unlimited = true; limit_theta_on_basis_column(j, -ed * m_sign_of_entering_delta, ratio, unlimited); @@ -298,12 +313,12 @@ template int lp_primal_core_solver::find_leaving_ } template void lp_primal_core_solver::init_run_tableau() { // print_matrix(&(this->m_A), std::cout); - lean_assert(this->A_mult_x_is_off() == false); - lean_assert(basis_columns_are_set_correctly()); + SASSERT(this->A_mult_x_is_off() == false); + SASSERT(basis_columns_are_set_correctly()); this->m_basis_sort_counter = 0; // to initiate the sort of the basis this->set_total_iterations(0); this->iters_with_no_cost_growing() = 0; - lean_assert(this->inf_set_is_correct()); + SASSERT(this->inf_set_is_correct()); if (this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) return; if (this->m_settings.backup_costs) @@ -317,13 +332,13 @@ template void lp_primal_core_solver::init_run_tab } if (this->m_settings.simplex_strategy() == simplex_strategy_enum::tableau_rows) init_tableau_rows(); - lean_assert(this->reduced_costs_are_correct_tableau()); - lean_assert(!this->need_to_pivot_to_basis_tableau()); + SASSERT(this->reduced_costs_are_correct_tableau()); + SASSERT(!this->need_to_pivot_to_basis_tableau()); } template bool lp_primal_core_solver:: update_basis_and_x_tableau(int entering, int leaving, X const & tt) { - lean_assert(this->use_tableau()); + SASSERT(this->use_tableau()); update_x_tableau(entering, tt); this->pivot_column_tableau(entering, this->m_basis_heading[leaving]); this->change_basis(entering, leaving); @@ -340,8 +355,8 @@ update_x_tableau(unsigned entering, const X& delta) { } } else { // m_using_infeas_costs == true this->m_x[entering] += delta; - lean_assert(this->column_is_feasible(entering)); - lean_assert(this->m_costs[entering] == zero_of_type()); + SASSERT(this->column_is_feasible(entering)); + SASSERT(this->m_costs[entering] == zero_of_type()); // m_d[entering] can change because of the cost change for basic columns. for (const auto & c : this->m_A.m_columns[entering]) { unsigned i = c.m_i; @@ -354,13 +369,13 @@ update_x_tableau(unsigned entering, const X& delta) { this->m_inf_set.insert(j); } } - lean_assert(this->A_mult_x_is_off() == false); + SASSERT(this->A_mult_x_is_off() == false); } template void lp_primal_core_solver:: update_inf_cost_for_column_tableau(unsigned j) { - lean_assert(this->m_settings.simplex_strategy() != simplex_strategy_enum::tableau_rows); - lean_assert(this->m_using_infeas_costs); + SASSERT(this->m_settings.simplex_strategy() != simplex_strategy_enum::tableau_rows); + SASSERT(this->m_using_infeas_costs); T new_cost = get_infeasibility_cost_for_column(j); T delta = this->m_costs[j] - new_cost; if (is_zero(delta)) diff --git a/src/util/lp/lp_primal_simplex.h b/src/util/lp/lp_primal_simplex.h index 715d76408..d8fd114e4 100644 --- a/src/util/lp/lp_primal_simplex.h +++ b/src/util/lp/lp_primal_simplex.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include @@ -12,7 +27,7 @@ #include "util/lp/lp_primal_core_solver.h" #include "util/lp/lp_solver.h" #include "util/lp/iterator_on_row.h" -namespace lean { +namespace lp { template class lp_primal_simplex: public lp_solver { lp_primal_core_solver * m_core_solver; diff --git a/src/util/lp/lp_primal_simplex.hpp b/src/util/lp/lp_primal_simplex.hpp index b6b6006e5..fd717ec7f 100644 --- a/src/util/lp/lp_primal_simplex.hpp +++ b/src/util/lp/lp_primal_simplex.hpp @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/lp_primal_simplex.h" -namespace lean { +namespace lp { template void lp_primal_simplex::fill_costs_and_x_for_first_stage_solver(unsigned original_number_of_columns) { unsigned slack_var = original_number_of_columns; unsigned artificial = original_number_of_columns + this->m_slacks; @@ -61,7 +76,7 @@ template void lp_primal_simplex::fill_costs_and_x int row, unsigned & slack_var, unsigned & artificial) { - lean_assert(row >= 0 && row < this->row_count()); + SASSERT(row >= 0 && row < this->row_count()); auto & constraint = this->m_constraints[this->m_core_solver_rows_to_external_rows[row]]; // we need to bring the program to the form Ax = b T rs = this->m_b[row]; @@ -86,7 +101,7 @@ template void lp_primal_simplex::fill_costs_and_x (*this->m_A)(row, slack_var) = - numeric_traits::one(); if (rs > 0) { - lean_assert(numeric_traits::is_zero(this->m_x[slack_var])); + SASSERT(numeric_traits::is_zero(this->m_x[slack_var])); // adding one artificial this->m_column_types[artificial] = column_type::low_bound; (*this->m_A)(row, artificial) = numeric_traits::one(); @@ -108,7 +123,7 @@ template void lp_primal_simplex::fill_costs_and_x if (rs < 0) { // adding one artificial - lean_assert(numeric_traits::is_zero(this->m_x[slack_var])); + SASSERT(numeric_traits::is_zero(this->m_x[slack_var])); this->m_column_types[artificial] = column_type::low_bound; (*this->m_A)(row, artificial) = - numeric_traits::one(); this->m_costs[artificial] = artificial_cost; @@ -177,12 +192,12 @@ template void lp_primal_simplex::fill_A_x_and_bas } template void lp_primal_simplex::fill_A_x_and_basis_for_stage_one_total_inf_for_row(unsigned row) { - lean_assert(row < this->row_count()); + SASSERT(row < this->row_count()); auto ext_row_it = this->m_core_solver_rows_to_external_rows.find(row); - lean_assert(ext_row_it != this->m_core_solver_rows_to_external_rows.end()); + SASSERT(ext_row_it != this->m_core_solver_rows_to_external_rows.end()); unsigned ext_row = ext_row_it->second; auto constr_it = this->m_constraints.find(ext_row); - lean_assert(constr_it != this->m_constraints.end()); + SASSERT(constr_it != this->m_constraints.end()); auto & constraint = constr_it->second; unsigned j = this->m_A->column_count(); // j is a slack variable this->m_A->add_column(); @@ -209,7 +224,7 @@ template void lp_primal_simplex::fill_A_x_and_bas this->m_upper_bounds[j] = m_low_bounds[j] = zero_of_type(); break; default: - lean_unreachable(); + SASSERT(false); } } @@ -281,10 +296,10 @@ template T lp_primal_simplex::get_row_value(unsig T ret = numeric_traits::zero(); for (auto & pair : it->second) { auto cit = this->m_map_from_var_index_to_column_info.find(pair.first); - lean_assert(cit != this->m_map_from_var_index_to_column_info.end()); + SASSERT(cit != this->m_map_from_var_index_to_column_info.end()); column_info * ci = cit->second; auto sol_it = solution.find(ci->get_name()); - lean_assert(sol_it != solution.end()); + SASSERT(sol_it != solution.end()); T column_val = sol_it->second; if (out != nullptr) { (*out) << pair.second << "(" << ci->get_name() << "=" << column_val << ") "; @@ -329,7 +344,7 @@ template bool lp_primal_simplex::row_constraint_h } return true;; } - lean_unreachable(); + SASSERT(false); return false; // it is unreachable } diff --git a/src/util/lp/lp_primal_simplex_instances.cpp b/src/util/lp/lp_primal_simplex_instances.cpp index 37b639489..92e3a77ff 100644 --- a/src/util/lp/lp_primal_simplex_instances.cpp +++ b/src/util/lp/lp_primal_simplex_instances.cpp @@ -1,20 +1,35 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include #include "util/vector.h" #include #include "util/lp/lp_primal_simplex.hpp" -template bool lean::lp_primal_simplex::bounds_hold(std::unordered_map, std::equal_to, std::allocator > > const&); -template bool lean::lp_primal_simplex::row_constraints_hold(std::unordered_map, std::equal_to, std::allocator > > const&); -template double lean::lp_primal_simplex::get_current_cost() const; -template double lean::lp_primal_simplex::get_column_value(unsigned int) const; -template lean::lp_primal_simplex::~lp_primal_simplex(); -template lean::lp_primal_simplex::~lp_primal_simplex(); -template lean::mpq lean::lp_primal_simplex::get_current_cost() const; -template lean::mpq lean::lp_primal_simplex::get_column_value(unsigned int) const; -template void lean::lp_primal_simplex::find_maximal_solution(); -template void lean::lp_primal_simplex::find_maximal_solution(); +template bool lp::lp_primal_simplex::bounds_hold(std::unordered_map, std::equal_to, std::allocator > > const&); +template bool lp::lp_primal_simplex::row_constraints_hold(std::unordered_map, std::equal_to, std::allocator > > const&); +template double lp::lp_primal_simplex::get_current_cost() const; +template double lp::lp_primal_simplex::get_column_value(unsigned int) const; +template lp::lp_primal_simplex::~lp_primal_simplex(); +template lp::lp_primal_simplex::~lp_primal_simplex(); +template lp::mpq lp::lp_primal_simplex::get_current_cost() const; +template lp::mpq lp::lp_primal_simplex::get_column_value(unsigned int) const; +template void lp::lp_primal_simplex::find_maximal_solution(); +template void lp::lp_primal_simplex::find_maximal_solution(); diff --git a/src/util/lp/lp_settings.h b/src/util/lp/lp_settings.h index ad40ad69d..70a9f1504 100644 --- a/src/util/lp/lp_settings.h +++ b/src/util/lp/lp_settings.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -12,7 +27,7 @@ #include "util/lp/lp_utils.h" #include "util/stopwatch.h" -namespace lean { +namespace lp { typedef unsigned var_index; typedef unsigned constraint_index; typedef unsigned row_index; @@ -296,7 +311,7 @@ public: unsigned column_norms_update_frequency; bool scale_with_ratio; double density_threshold; // need to tune it up, todo -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG static unsigned ddd; // used for debugging #endif bool use_breakpoints_in_feasibility_search; @@ -366,7 +381,7 @@ inline void print_blanks(int n, std::ostream & out) { // after a push of the last element we ensure that the vector increases // we also suppose that before the last push the vector was increasing inline void ensure_increasing(vector & v) { - lean_assert(v.size() > 0); + SASSERT(v.size() > 0); unsigned j = v.size() - 1; for (; j > 0; j-- ) if (v[j] <= v[j - 1]) { @@ -381,7 +396,7 @@ inline void ensure_increasing(vector & v) { -#if LEAN_DEBUG +#if Z3DEBUG bool D(); #endif } diff --git a/src/util/lp/lp_settings.hpp b/src/util/lp/lp_settings.hpp index b27d837e0..659d47c62 100644 --- a/src/util/lp/lp_settings.hpp +++ b/src/util/lp/lp_settings.hpp @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include "util/vector.h" #include "util/lp/lp_settings.h" -namespace lean { +namespace lp { std::string column_type_to_string(column_type t) { switch (t) { case column_type::fixed: return "fixed"; @@ -14,7 +29,7 @@ std::string column_type_to_string(column_type t) { case column_type::low_bound: return "low_bound"; case column_type::upper_bound: return "upper_bound"; case column_type::free_column: return "free_column"; - default: lean_unreachable(); + default: SASSERT(false); } return "unknown"; // it is unreachable } @@ -34,7 +49,7 @@ const char* lp_status_to_string(lp_status status) { case EMPTY: return "EMPTY"; case UNSTABLE: return "UNSTABLE"; default: - lean_unreachable(); + SASSERT(false); } return "UNKNOWN"; // it is unreachable } @@ -49,7 +64,7 @@ lp_status lp_status_from_string(std::string status) { if (status == "TIME_EXHAUSTED") return lp_status::TIME_EXHAUSTED; if (status == "ITERATIONS_EXHAUSTED") return lp_status::ITERATIONS_EXHAUSTED; if (status == "EMPTY") return lp_status::EMPTY; - lean_unreachable(); + SASSERT(false); return lp_status::UNKNOWN; // it is unreachable } @@ -104,7 +119,7 @@ bool vectors_are_equal(const vector & a, const vector &b) { } return true; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned lp_settings::ddd = 0; #endif } diff --git a/src/util/lp/lp_settings_instances.cpp b/src/util/lp/lp_settings_instances.cpp index ac2ed4b51..bd5a1515f 100644 --- a/src/util/lp/lp_settings_instances.cpp +++ b/src/util/lp/lp_settings_instances.cpp @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/lp_settings.hpp" -template bool lean::vectors_are_equal(vector const&, vector const&); -template bool lean::vectors_are_equal(vector const&, vector const&); +template bool lp::vectors_are_equal(vector const&, vector const&); +template bool lp::vectors_are_equal(vector const&, vector const&); diff --git a/src/util/lp/lp_solver.h b/src/util/lp/lp_solver.h index 1bfe7dcdc..c447b1870 100644 --- a/src/util/lp/lp_solver.h +++ b/src/util/lp/lp_solver.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include @@ -15,7 +30,7 @@ #include "util/lp/scaler.h" #include "util/lp/linear_combination_iterator.h" #include "util/lp/bound_analyzer_on_row.h" -namespace lean { +namespace lp { enum lp_relation { Less_or_equal, Equal, diff --git a/src/util/lp/lp_solver.hpp b/src/util/lp/lp_solver.hpp index 135616a69..3bc83b316 100644 --- a/src/util/lp/lp_solver.hpp +++ b/src/util/lp/lp_solver.hpp @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include "util/vector.h" #include "util/lp/lp_solver.h" -namespace lean { +namespace lp { template column_info * lp_solver::get_or_create_column_info(unsigned column) { auto it = m_map_from_var_index_to_column_info.find(column); return (it == m_map_from_var_index_to_column_info.end())? (m_map_from_var_index_to_column_info[column] = new column_info(static_cast(-1))) : it->second; @@ -32,7 +47,7 @@ template T lp_solver::get_column_cost_value(unsig return ci->get_cost() * get_column_value(j); } template void lp_solver::add_constraint(lp_relation relation, T right_side, unsigned row_index) { - lean_assert(m_constraints.find(row_index) == m_constraints.end()); + SASSERT(m_constraints.find(row_index) == m_constraints.end()); lp_constraint cs(right_side, relation); m_constraints[row_index] = cs; } @@ -158,10 +173,10 @@ template void lp_solver::pin_vars_on_row_with_sig column_info * ci = m_map_from_var_index_to_column_info[j]; T a = t.second; if (a * sign > numeric_traits::zero()) { - lean_assert(ci->upper_bound_is_set()); + SASSERT(ci->upper_bound_is_set()); ci->set_fixed_value(ci->get_upper_bound()); } else { - lean_assert(ci->low_bound_is_set()); + SASSERT(ci->low_bound_is_set()); ci->set_fixed_value(ci->get_low_bound()); } } @@ -328,7 +343,7 @@ template bool lp_solver::row_is_obsolete(std:: case lp_relation::Less_or_equal: return row_le_is_obsolete(row, row_index); } - lean_unreachable(); + SASSERT(false); return false; // it is unreachable } @@ -343,7 +358,7 @@ template void lp_solver::remove_fixed_or_zero_col vector removed; for (auto & col : row) { unsigned j = col.first; - lean_assert(m_map_from_var_index_to_column_info.find(j) != m_map_from_var_index_to_column_info.end()); + SASSERT(m_map_from_var_index_to_column_info.find(j) != m_map_from_var_index_to_column_info.end()); column_info * ci = m_map_from_var_index_to_column_info[j]; if (ci->is_fixed()) { removed.push_back(j); @@ -412,7 +427,7 @@ template void lp_solver::map_external_columns_to_ } unsigned j = col.first; auto column_info_it = m_map_from_var_index_to_column_info.find(j); - lean_assert(column_info_it != m_map_from_var_index_to_column_info.end()); + SASSERT(column_info_it != m_map_from_var_index_to_column_info.end()); auto j_column = column_info_it->second->get_column_index(); if (!is_valid(j_column)) { // j is a newcomer @@ -435,14 +450,14 @@ template void lp_solver::fill_A_from_A_values() { m_A = new static_matrix(static_cast(m_A_values.size()), number_of_core_structurals()); for (auto & t : m_A_values) { auto row_it = m_external_rows_to_core_solver_rows.find(t.first); - lean_assert(row_it != m_external_rows_to_core_solver_rows.end()); + SASSERT(row_it != m_external_rows_to_core_solver_rows.end()); unsigned row = row_it->second; for (auto k : t.second) { auto column_info_it = m_map_from_var_index_to_column_info.find(k.first); - lean_assert(column_info_it != m_map_from_var_index_to_column_info.end()); + SASSERT(column_info_it != m_map_from_var_index_to_column_info.end()); column_info *ci = column_info_it->second; unsigned col = ci->get_column_index(); - lean_assert(is_valid(col)); + SASSERT(is_valid(col)); bool col_is_flipped = m_map_from_var_index_to_column_info[k.first]->is_flipped(); if (!col_is_flipped) { (*m_A)(row, col) = k.second; @@ -456,7 +471,7 @@ template void lp_solver::fill_A_from_A_values() { template void lp_solver::fill_matrix_A_and_init_right_side() { map_external_rows_to_core_solver_rows(); map_external_columns_to_core_solver_columns(); - lean_assert(m_A == nullptr); + SASSERT(m_A == nullptr); fill_A_from_A_values(); m_b.resize(m_A->row_count()); } @@ -468,7 +483,7 @@ template void lp_solver::count_slacks_and_artific } template void lp_solver::count_slacks_and_artificials_for_row(unsigned i) { - lean_assert(this->m_constraints.find(this->m_core_solver_rows_to_external_rows[i]) != this->m_constraints.end()); + SASSERT(this->m_constraints.find(this->m_core_solver_rows_to_external_rows[i]) != this->m_constraints.end()); auto & constraint = this->m_constraints[this->m_core_solver_rows_to_external_rows[i]]; switch (constraint.m_relation) { case Equal: @@ -504,7 +519,7 @@ template T lp_solver::low_bound_shift_for_row( template void lp_solver::fill_m_b() { for (int i = this->row_count() - 1; i >= 0; i--) { - lean_assert(this->m_constraints.find(this->m_core_solver_rows_to_external_rows[i]) != this->m_constraints.end()); + SASSERT(this->m_constraints.find(this->m_core_solver_rows_to_external_rows[i]) != this->m_constraints.end()); unsigned external_i = this->m_core_solver_rows_to_external_rows[i]; auto & constraint = this->m_constraints[external_i]; this->m_b[i] = constraint.m_rs - low_bound_shift_for_row(external_i); @@ -542,13 +557,13 @@ template T lp_solver::get_column_value_with_core_ template void lp_solver::set_scaled_cost(unsigned j) { // grab original costs but modify it with the column scales - lean_assert(j < this->m_column_scale.size()); + SASSERT(j < this->m_column_scale.size()); column_info * ci = this->m_map_from_var_index_to_column_info[this->m_core_solver_columns_to_external_columns[j]]; T cost = ci->get_cost(); if (ci->is_flipped()){ cost *= -1; } - lean_assert(ci->is_fixed() == false); + SASSERT(ci->is_fixed() == false); this->m_costs[j] = cost * this->m_column_scale[j]; } } diff --git a/src/util/lp/lp_solver_instances.cpp b/src/util/lp/lp_solver_instances.cpp index 5df490cae..4fe04c05f 100644 --- a/src/util/lp/lp_solver_instances.cpp +++ b/src/util/lp/lp_solver_instances.cpp @@ -1,40 +1,55 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/lp/lp_solver.hpp" -template void lean::lp_solver::add_constraint(lean::lp_relation, double, unsigned int); -template void lean::lp_solver::cleanup(); -template void lean::lp_solver::count_slacks_and_artificials(); -template void lean::lp_solver::fill_m_b(); -template void lean::lp_solver::fill_matrix_A_and_init_right_side(); -template void lean::lp_solver::flip_costs(); -template double lean::lp_solver::get_column_cost_value(unsigned int, lean::column_info*) const; -template int lean::lp_solver::get_column_index_by_name(std::string) const; -template double lean::lp_solver::get_column_value_with_core_solver(unsigned int, lean::lp_core_solver_base*) const; -template lean::column_info* lean::lp_solver::get_or_create_column_info(unsigned int); -template void lean::lp_solver::give_symbolic_name_to_column(std::string, unsigned int); -template void lean::lp_solver::print_statistics_on_A(std::ostream & out); -template bool lean::lp_solver::problem_is_empty(); -template void lean::lp_solver::scale(); -template void lean::lp_solver::set_scaled_cost(unsigned int); -template lean::lp_solver::~lp_solver(); -template void lean::lp_solver::add_constraint(lean::lp_relation, lean::mpq, unsigned int); -template void lean::lp_solver::cleanup(); -template void lean::lp_solver::count_slacks_and_artificials(); -template void lean::lp_solver::fill_m_b(); -template void lean::lp_solver::fill_matrix_A_and_init_right_side(); -template void lean::lp_solver::flip_costs(); -template lean::mpq lean::lp_solver::get_column_cost_value(unsigned int, lean::column_info*) const; -template int lean::lp_solver::get_column_index_by_name(std::string) const; -template lean::mpq lean::lp_solver::get_column_value_by_name(std::string) const; -template lean::mpq lean::lp_solver::get_column_value_with_core_solver(unsigned int, lean::lp_core_solver_base*) const; -template lean::column_info* lean::lp_solver::get_or_create_column_info(unsigned int); -template void lean::lp_solver::give_symbolic_name_to_column(std::string, unsigned int); -template void lean::lp_solver::print_statistics_on_A(std::ostream & out); -template bool lean::lp_solver::problem_is_empty(); -template void lean::lp_solver::scale(); -template void lean::lp_solver::set_scaled_cost(unsigned int); -template lean::lp_solver::~lp_solver(); -template double lean::lp_solver::get_column_value_by_name(std::string) const; +template void lp::lp_solver::add_constraint(lp::lp_relation, double, unsigned int); +template void lp::lp_solver::cleanup(); +template void lp::lp_solver::count_slacks_and_artificials(); +template void lp::lp_solver::fill_m_b(); +template void lp::lp_solver::fill_matrix_A_and_init_right_side(); +template void lp::lp_solver::flip_costs(); +template double lp::lp_solver::get_column_cost_value(unsigned int, lp::column_info*) const; +template int lp::lp_solver::get_column_index_by_name(std::string) const; +template double lp::lp_solver::get_column_value_with_core_solver(unsigned int, lp::lp_core_solver_base*) const; +template lp::column_info* lp::lp_solver::get_or_create_column_info(unsigned int); +template void lp::lp_solver::give_symbolic_name_to_column(std::string, unsigned int); +template void lp::lp_solver::print_statistics_on_A(std::ostream & out); +template bool lp::lp_solver::problem_is_empty(); +template void lp::lp_solver::scale(); +template void lp::lp_solver::set_scaled_cost(unsigned int); +template lp::lp_solver::~lp_solver(); +template void lp::lp_solver::add_constraint(lp::lp_relation, lp::mpq, unsigned int); +template void lp::lp_solver::cleanup(); +template void lp::lp_solver::count_slacks_and_artificials(); +template void lp::lp_solver::fill_m_b(); +template void lp::lp_solver::fill_matrix_A_and_init_right_side(); +template void lp::lp_solver::flip_costs(); +template lp::mpq lp::lp_solver::get_column_cost_value(unsigned int, lp::column_info*) const; +template int lp::lp_solver::get_column_index_by_name(std::string) const; +template lp::mpq lp::lp_solver::get_column_value_by_name(std::string) const; +template lp::mpq lp::lp_solver::get_column_value_with_core_solver(unsigned int, lp::lp_core_solver_base*) const; +template lp::column_info* lp::lp_solver::get_or_create_column_info(unsigned int); +template void lp::lp_solver::give_symbolic_name_to_column(std::string, unsigned int); +template void lp::lp_solver::print_statistics_on_A(std::ostream & out); +template bool lp::lp_solver::problem_is_empty(); +template void lp::lp_solver::scale(); +template void lp::lp_solver::set_scaled_cost(unsigned int); +template lp::lp_solver::~lp_solver(); +template double lp::lp_solver::get_column_value_by_name(std::string) const; diff --git a/src/util/lp/lp_utils.cpp b/src/util/lp/lp_utils.cpp index 8cb98974e..46a82e9ec 100644 --- a/src/util/lp/lp_utils.cpp +++ b/src/util/lp/lp_utils.cpp @@ -1,11 +1,26 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lp_utils.h" -#ifdef lp_for_z3 -namespace lean { + +namespace lp { double numeric_traits::g_zero = 0.0; double numeric_traits::g_one = 1.0; } -#endif + diff --git a/src/util/lp/lp_utils.h b/src/util/lp/lp_utils.h index 34cf4f6b9..fce9f4d02 100644 --- a/src/util/lp/lp_utils.h +++ b/src/util/lp/lp_utils.h @@ -1,8 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson - This file should be present in z3 and in Lean. -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include #include "util/lp/numeric_pair.h" @@ -21,20 +35,12 @@ bool contains(const std::unordered_map & map, const A& key) { return map.find(key) != map.end(); } -#ifdef lp_for_z3 - -#ifdef Z3DEBUG -#define LEAN_DEBUG 1 -#endif - -namespace lean { +namespace lp { inline void throw_exception(const std::string & str) { throw default_exception(str); } typedef z3_exception exception; -#define lean_assert(_x_) { SASSERT(_x_); } - inline void lean_unreachable() { lean_assert(false); } template inline X zero_of_type() { return numeric_traits::zero(); } template inline X one_of_type() { return numeric_traits::one(); } template inline bool is_zero(const X & v) { return numeric_traits::is_zero(v); } @@ -68,8 +74,8 @@ template struct hash> { }; template<> -struct hash> { - inline size_t operator()(const lean::numeric_pair & v) const { +struct hash> { + inline size_t operator()(const lp::numeric_pair & v) const { size_t seed = 0; hash_combine(seed, v.x); hash_combine(seed, v.y); @@ -78,64 +84,3 @@ struct hash> { }; } -#else // else of #if lp_for_z3 -#include -#include -//include "util/numerics/mpq.h" -//include "util/numerics/numeric_traits.h" -//include "util/numerics/double.h" - -#ifdef __CLANG__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmismatched-tags" -#endif -namespace std { -template<> -struct hash { - inline size_t operator()(const lean::mpq & v) const { - return v.hash(); - } -}; -} -namespace lean { -template inline bool precise() { return numeric_traits::precise();} -template inline X one_of_type() { return numeric_traits::one(); } -template inline bool is_zero(const X & v) { return numeric_traits::is_zero(v); } -template inline double get_double(const X & v) { return numeric_traits::get_double(v); } -template inline T zero_of_type() {return numeric_traits::zero();} -inline void throw_exception(std::string str) { throw exception(str); } -template inline T from_string(std::string const & ) { lean_unreachable();} -template <> double inline from_string(std::string const & str) { return atof(str.c_str());} -template <> mpq inline from_string(std::string const & str) { - return mpq(atof(str.c_str())); -} - -} // closing lean -template -inline void hash_combine(std::size_t & seed, const T & v) { - seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); -} - -namespace std { -template struct hash> { - inline size_t operator()(const pair & v) const { - size_t seed = 0; - hash_combine(seed, v.first); - hash_combine(seed, v.second); - return seed; - } -}; -template<> -struct hash> { - inline size_t operator()(const lean::numeric_pair & v) const { - size_t seed = 0; - hash_combine(seed, v.x); - hash_combine(seed, v.y); - return seed; - } -}; -} // std -#ifdef __CLANG__ -#pragma clang diagnostic pop -#endif -#endif diff --git a/src/util/lp/lu.h b/src/util/lp/lu.h index 0d8163a14..5498a1849 100644 --- a/src/util/lp/lu.h +++ b/src/util/lp/lu.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once @@ -18,8 +33,8 @@ #include "util/lp/row_eta_matrix.h" #include "util/lp/square_dense_submatrix.h" #include "util/lp/dense_matrix.h" -namespace lean { -#ifdef LEAN_DEBUG +namespace lp { +#ifdef Z3DEBUG template // print the nr x nc submatrix at the top left corner void print_submatrix(sparse_matrix & m, unsigned mr, unsigned nc); @@ -32,7 +47,7 @@ void print_matrix(sparse_matrix& m, std::ostream & out); template X dot_product(const vector & a, const vector & b) { - lean_assert(a.size() == b.size()); + SASSERT(a.size() == b.size()); auto r = zero_of_type(); for (unsigned i = 0; i < a.size(); i++) { r += a[i] * b[i]; @@ -47,7 +62,7 @@ class one_elem_on_diag: public tail_matrix { T m_val; public: one_elem_on_diag(unsigned i, T val) : m_i(i), m_val(val) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG m_one_over_val = numeric_traits::one() / m_val; #endif } @@ -56,7 +71,7 @@ public: one_elem_on_diag(const one_elem_on_diag & o); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned m_m; unsigned m_n; virtual void set_number_of_rows(unsigned m) { m_m = m; m_n = m; } @@ -91,15 +106,15 @@ public: void conjugate_by_permutation(permutation_matrix & p) { // this = p * this * p(-1) -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // auto rev = p.get_reverse(); // auto deb = ((*this) * rev); // deb = p * deb; #endif m_i = p.apply_reverse(m_i); -#ifdef LEAN_DEBUG - // lean_assert(*this == deb); +#ifdef Z3DEBUG + // SASSERT(*this == deb); #endif } }; // end of one_elem_on_diag @@ -212,7 +227,7 @@ public: // see page 407 of Chvatal unsigned transform_U_to_V_by_replacing_column(indexed_vector & w, unsigned leaving_column_of_U); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void check_vector_w(unsigned entering); void check_apply_matrix_to_vector(matrix *lp, T *w); @@ -248,7 +263,7 @@ public: bool is_correct(const vector& basis); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG dense_matrix tail_product(); dense_matrix get_left_side(const vector& basis); @@ -291,7 +306,7 @@ public: bool need_to_refactor() { return m_refactor_counter >= 200; } void adjust_dimension_with_matrix_A() { - lean_assert(m_A.row_count() >= m_dim); + SASSERT(m_A.row_count() >= m_dim); m_dim = m_A.row_count(); m_U.resize(m_dim); m_Q.resize(m_dim); @@ -305,7 +320,7 @@ public: unsigned m = m_A.row_count(); unsigned m_prev = m_U.dimension(); - lean_assert(m_A.column_count() == heading.size()); + SASSERT(m_A.column_count() == heading.size()); for (unsigned i = m_prev; i < m; i++) { for (const row_cell & c : m_A.m_rows[i]) { @@ -321,14 +336,14 @@ public: void add_last_rows_to_B(const vector & heading, const std::unordered_set & columns_to_replace) { unsigned m = m_A.row_count(); - lean_assert(m_A.column_count() == heading.size()); + SASSERT(m_A.column_count() == heading.size()); adjust_dimension_with_matrix_A(); m_w_for_extension.resize(m); // At this moment the LU is correct // for B extended by only by ones at the diagonal in the lower right corner for (unsigned j :columns_to_replace) { - lean_assert(heading[j] >= 0); + SASSERT(heading[j] >= 0); replace_column_with_only_change_at_last_rows(j, heading[j]); if (get_status() == LU_status::Degenerated) break; @@ -352,7 +367,7 @@ public: template void init_factorization(lu* & factorization, static_matrix & m_A, vector & m_basis, lp_settings &m_settings); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template dense_matrix get_B(lu& f, const vector& basis); #endif diff --git a/src/util/lp/lu.hpp b/src/util/lp/lu.hpp index 2d2c7c7c4..9d1532ac9 100644 --- a/src/util/lp/lu.hpp +++ b/src/util/lp/lu.hpp @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include @@ -9,8 +24,8 @@ #include #include "util/debug.h" #include "util/lp/lu.h" -namespace lean { -#ifdef LEAN_DEBUG +namespace lp { +#ifdef Z3DEBUG template // print the nr x nc submatrix at the top left corner void print_submatrix(sparse_matrix & m, unsigned mr, unsigned nc, std::ostream & out) { vector> A; @@ -72,13 +87,13 @@ template one_elem_on_diag::one_elem_on_diag(const one_elem_on_diag & o) { m_i = o.m_i; m_val = o.m_val; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG m_m = m_n = o.m_m; m_one_over_val = numeric_traits::one() / o.m_val; #endif } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template T one_elem_on_diag::get_elem(unsigned i, unsigned j) const { if (i == j){ @@ -122,29 +137,29 @@ lu::lu(static_matrix const & A, m_failure(false), m_row_eta_work_vector(A.row_count()), m_refactor_counter(0) { - lean_assert(!(numeric_traits::precise() && settings.use_tableau())); -#ifdef LEAN_DEBUG + SASSERT(!(numeric_traits::precise() && settings.use_tableau())); +#ifdef Z3DEBUG debug_test_of_basis(A, basis); #endif ++m_settings.st().m_num_factorizations; create_initial_factorization(); -#ifdef LEAN_DEBUG - // lean_assert(check_correctness()); +#ifdef Z3DEBUG + // SASSERT(check_correctness()); #endif } template void lu::debug_test_of_basis(static_matrix const & A, vector & basis) { std::set set; for (unsigned i = 0; i < A.row_count(); i++) { - lean_assert(basis[i]< A.column_count()); + SASSERT(basis[i]< A.column_count()); set.insert(basis[i]); } - lean_assert(set.size() == A.row_count()); + SASSERT(set.size() == A.row_count()); } template void lu::solve_By(indexed_vector & y) { - lean_assert(false); // not implemented + SASSERT(false); // not implemented // init_vector_y(y); // solve_By_when_y_is_ready(y); } @@ -268,7 +283,7 @@ void lu::solve_yB(vector& y) { m_U.solve_y_U(y); // got y*U=cb*R(-1) m_Q.apply_reverse_from_right_to_T(y); // for (auto e = m_tail.rbegin(); e != m_tail.rend(); ++e) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG (*e)->set_number_of_columns(m_dim); #endif (*e)->apply_from_right(y); @@ -277,20 +292,20 @@ void lu::solve_yB(vector& y) { template void lu::solve_yB_indexed(indexed_vector& y) { - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); // first solve yU = cb*R(-1) m_R.apply_reverse_from_right_to_T(y); // got y = cb*R(-1) - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); m_U.solve_y_U_indexed(y, m_settings); // got y*U=cb*R(-1) - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); m_Q.apply_reverse_from_right_to_T(y); - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); for (auto e = m_tail.rbegin(); e != m_tail.rend(); ++e) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG (*e)->set_number_of_columns(m_dim); #endif (*e)->apply_from_right(y); - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); } } @@ -304,8 +319,8 @@ void lu::add_delta_to_solution(const vector& yc, vector& y){ template void lu::add_delta_to_solution_indexed(indexed_vector& y) { // the delta sits in m_y_copy, put result into y - lean_assert(y.is_OK()); - lean_assert(m_y_copy.is_OK()); + SASSERT(y.is_OK()); + SASSERT(m_y_copy.is_OK()); m_ii.clear(); m_ii.resize(y.data_size()); for (unsigned i : y.m_index) @@ -315,7 +330,7 @@ void lu::add_delta_to_solution_indexed(indexed_vector& y) { if (m_ii[i] == 0) m_ii.set_value(1, i); } - lean_assert(m_ii.is_OK()); + SASSERT(m_ii.is_OK()); y.m_index.clear(); for (unsigned i : m_ii.m_index) { @@ -326,7 +341,7 @@ void lu::add_delta_to_solution_indexed(indexed_vector& y) { v = zero_of_type(); } - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); } template @@ -343,7 +358,7 @@ void lu::find_error_of_yB_indexed(const indexed_vector& y, const vector // it is a non efficient version indexed_vector yc = m_y_copy; yc.m_index.clear(); - lean_assert(!numeric_traits::precise()); + SASSERT(!numeric_traits::precise()); { vector d_basis(y.m_data.size()); @@ -364,10 +379,10 @@ void lu::find_error_of_yB_indexed(const indexed_vector& y, const vector } } #endif - lean_assert(m_ii.is_OK()); + SASSERT(m_ii.is_OK()); m_ii.clear(); m_ii.resize(y.data_size()); - lean_assert(m_y_copy.is_OK()); + SASSERT(m_y_copy.is_OK()); // put the error into m_y_copy for (auto k : y.m_index) { auto & row = m_A.m_rows[k]; @@ -399,7 +414,7 @@ void lu::find_error_of_yB_indexed(const indexed_vector& y, const vector m_y_copy.set_value(v, k); } } - lean_assert(m_y_copy.is_OK()); + SASSERT(m_y_copy.is_OK()); } @@ -419,12 +434,12 @@ void lu::solve_yB_with_error_check_indexed(indexed_vector & y, const ve } return; } - lean_assert(m_y_copy.is_OK()); - lean_assert(y.is_OK()); + SASSERT(m_y_copy.is_OK()); + SASSERT(y.is_OK()); if (y.m_index.size() * ratio_of_index_size_to_all_size() < m_A.column_count()) { m_y_copy = y; solve_yB_indexed(y); - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); if (y.m_index.size() * ratio_of_index_size_to_all_size() >= m_A.column_count()) { find_error_of_yB(m_y_copy.m_data, y.m_data, basis); solve_yB(m_y_copy.m_data); @@ -436,7 +451,7 @@ void lu::solve_yB_with_error_check_indexed(indexed_vector & y, const ve solve_yB_indexed(m_y_copy); add_delta_to_solution_indexed(y); } - lean_assert(m_y_copy.is_OK()); + SASSERT(m_y_copy.is_OK()); } else { solve_yB_with_error_check(y.m_data, basis); y.restore_index_and_clean_from_data(); @@ -489,7 +504,7 @@ template void lu::perform_transformations_on_w(indexed_vector& w) { apply_lp_list_to_w(w); m_Q.apply_reverse_from_left(w); - // TBD does not compile: lean_assert(numeric_traits::precise() || check_vector_for_small_values(w, m_settings)); + // TBD does not compile: SASSERT(numeric_traits::precise() || check_vector_for_small_values(w, m_settings)); } // see Chvatal 24.3 @@ -503,7 +518,7 @@ template void lu::apply_lp_list_to_w(indexed_vector & w) { for (unsigned i = 0; i < m_tail.size(); i++) { m_tail[i]->apply_from_left_to_T(w, m_settings); - // TBD does not compile: lean_assert(check_vector_for_small_values(w, m_settings)); + // TBD does not compile: SASSERT(check_vector_for_small_values(w, m_settings)); } } template @@ -570,7 +585,7 @@ unsigned lu::transform_U_to_V_by_replacing_column(indexed_vector & w, return column_to_replace; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template void lu::check_vector_w(unsigned entering) { T * w = new T[m_dim]; @@ -595,7 +610,7 @@ void lu::check_apply_lp_lists_to_w(T * w) { permutation_matrix qr = m_Q.get_reverse(); apply_to_vector(qr, w); for (int i = m_dim - 1; i >= 0; i--) { - lean_assert(abs(w[i] - w[i]) < 0.0000001); + SASSERT(abs(w[i] - w[i]) < 0.0000001); } } @@ -624,7 +639,7 @@ void lu::process_column(int j) { } template bool lu::is_correct(const vector& basis) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG if (get_status() != LU_status::OK) { return false; } @@ -637,10 +652,10 @@ bool lu::is_correct(const vector& basis) { } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template dense_matrix lu::tail_product() { - lean_assert(tail_size() > 0); + SASSERT(tail_size() > 0); dense_matrix left_side = permutation_matrix(m_dim); for (unsigned i = 0; i < tail_size(); i++) { matrix* lp = get_lp_matrix(i); @@ -690,8 +705,8 @@ template bool lu::all_columns_and_rows_are_active() { unsigned i = m_dim; while (i--) { - lean_assert(m_U.col_is_active(i)); - lean_assert(m_U.row_is_active(i)); + SASSERT(m_U.col_is_active(i)); + SASSERT(m_U.row_is_active(i)); } return true; } @@ -733,9 +748,9 @@ void lu::create_initial_factorization(){ } } if (j == m_dim) { - // TBD does not compile: lean_assert(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); - // lean_assert(is_correct()); - // lean_assert(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); + // TBD does not compile: SASSERT(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); + // SASSERT(is_correct()); + // SASSERT(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); return; } j++; @@ -748,12 +763,12 @@ void lu::create_initial_factorization(){ } } m_dense_LU->update_parent_matrix(m_settings); - lean_assert(m_dense_LU->is_L_matrix()); + SASSERT(m_dense_LU->is_L_matrix()); m_dense_LU->conjugate_by_permutation(m_Q); push_matrix_to_tail(m_dense_LU); m_refactor_counter = 0; - // lean_assert(is_correct()); - // lean_assert(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); + // SASSERT(is_correct()); + // SASSERT(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); } template @@ -780,7 +795,7 @@ void lu::scan_last_row_to_work_vector(unsigned lowest_row_of_the_bump) { vector> & last_row_vec = m_U.get_row_values(m_U.adjust_row(lowest_row_of_the_bump)); for (auto & iv : last_row_vec) { if (is_zero(iv.m_value)) continue; - lean_assert(!m_settings.abs_val_is_smaller_than_drop_tolerance(iv.m_value)); + SASSERT(!m_settings.abs_val_is_smaller_than_drop_tolerance(iv.m_value)); unsigned adjusted_col = m_U.adjust_column_inverse(iv.m_index); if (adjusted_col < lowest_row_of_the_bump) { m_row_eta_work_vector.set_value(-iv.m_value, adjusted_col); @@ -801,14 +816,14 @@ void lu::pivot_and_solve_the_system(unsigned replaced_column, unsigned low vector> & row = m_U.get_row_values(aj); for (auto & iv : row) { unsigned col = m_U.adjust_column_inverse(iv.m_index); - lean_assert(col >= j || numeric_traits::is_zero(iv.m_value)); + SASSERT(col >= j || numeric_traits::is_zero(iv.m_value)); if (col == j) continue; if (numeric_traits::is_zero(iv.m_value)) { continue; } // the -v is for solving the system ( to zero the last row), and +v is for pivoting T delta = col < lowest_row_of_the_bump? -v * iv.m_value: v * iv.m_value; - lean_assert(numeric_traits::is_zero(delta) == false); + SASSERT(numeric_traits::is_zero(delta) == false); @@ -845,7 +860,7 @@ row_eta_matrix *lu::get_row_eta_matrix_and_set_row_vector(unsigned r return nullptr; } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG auto ret = new row_eta_matrix(replaced_column, lowest_row_of_the_bump, m_dim); #else auto ret = new row_eta_matrix(replaced_column, lowest_row_of_the_bump); @@ -885,15 +900,15 @@ void lu::replace_column(T pivot_elem_for_checking, indexed_vector & w, push_matrix_to_tail(row_eta); } calculate_Lwave_Pwave_for_bump(replaced_column, lowest_row_of_the_bump); - // lean_assert(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); - // lean_assert(w.is_OK() && m_row_eta_work_vector.is_OK()); + // SASSERT(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); + // SASSERT(w.is_OK() && m_row_eta_work_vector.is_OK()); } template void lu::calculate_Lwave_Pwave_for_bump(unsigned replaced_column, unsigned lowest_row_of_the_bump){ T diagonal_elem; if (replaced_column < lowest_row_of_the_bump) { diagonal_elem = m_row_eta_work_vector[lowest_row_of_the_bump]; - // lean_assert(m_row_eta_work_vector.is_OK()); + // SASSERT(m_row_eta_work_vector.is_OK()); m_U.set_row_from_work_vector_and_clean_work_vector_not_adjusted(m_U.adjust_row(lowest_row_of_the_bump), m_row_eta_work_vector, m_settings); } else { diagonal_elem = m_U(lowest_row_of_the_bump, lowest_row_of_the_bump); // todo - get it more efficiently @@ -904,13 +919,13 @@ void lu::calculate_Lwave_Pwave_for_bump(unsigned replaced_column, unsigned } calculate_Lwave_Pwave_for_last_row(lowest_row_of_the_bump, diagonal_elem); - // lean_assert(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); + // SASSERT(m_U.is_upper_triangular_and_maximums_are_set_correctly_in_rows(m_settings)); } template void lu::calculate_Lwave_Pwave_for_last_row(unsigned lowest_row_of_the_bump, T diagonal_element) { auto l = new one_elem_on_diag(lowest_row_of_the_bump, diagonal_element); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG l->set_number_of_columns(m_dim); #endif push_matrix_to_tail(l); @@ -927,11 +942,11 @@ void init_factorization(lu* & factorization, static_matrix & m_A, ve // LP_OUT(m_settings, "failing in init_factorization" << std::endl); } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template dense_matrix get_B(lu& f, const vector& basis) { - lean_assert(basis.size() == f.dimension()); - lean_assert(basis.size() == f.m_U.dimension()); + SASSERT(basis.size() == f.dimension()); + SASSERT(basis.size() == f.m_U.dimension()); dense_matrix B(f.dimension(), f.dimension()); for (unsigned i = 0; i < f.dimension(); i++) for (unsigned j = 0; j < f.dimension(); j++) diff --git a/src/util/lp/lu_instances.cpp b/src/util/lp/lu_instances.cpp index c8ff7b2f4..057895068 100644 --- a/src/util/lp/lu_instances.cpp +++ b/src/util/lp/lu_instances.cpp @@ -1,63 +1,78 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include #include "util/vector.h" #include "util/debug.h" #include "util/lp/lu.hpp" -template double lean::dot_product(vector const&, vector const&); -template lean::lu::lu(lean::static_matrix const&, vector&, lean::lp_settings&); -template void lean::lu::push_matrix_to_tail(lean::tail_matrix*); -template void lean::lu::replace_column(double, lean::indexed_vector&, unsigned); -template void lean::lu::solve_Bd(unsigned int, lean::indexed_vector&, lean::indexed_vector&); -template lean::lu::~lu(); -template void lean::lu::push_matrix_to_tail(lean::tail_matrix*); -template void lean::lu::solve_Bd(unsigned int, lean::indexed_vector&, lean::indexed_vector&); -template lean::lu::~lu(); -template void lean::lu >::push_matrix_to_tail(lean::tail_matrix >*); -template void lean::lu >::solve_Bd(unsigned int, lean::indexed_vector&, lean::indexed_vector&); -template lean::lu >::~lu(); -template lean::mpq lean::dot_product(vector const&, vector const&); -template void lean::init_factorization(lean::lu*&, lean::static_matrix&, vector&, lean::lp_settings&); -template void lean::init_factorization(lean::lu*&, lean::static_matrix&, vector&, lean::lp_settings&); -template void lean::init_factorization >(lean::lu >*&, lean::static_matrix >&, vector&, lean::lp_settings&); -#ifdef LEAN_DEBUG -template void lean::print_matrix(lean::sparse_matrix&, std::ostream & out); -template void lean::print_matrix(lean::static_matrix&, std::ostream&); -template void lean::print_matrix >(lean::static_matrix >&, std::ostream&); -template void lean::print_matrix(lean::static_matrix&, std::ostream & out); -template bool lean::lu::is_correct(const vector& basis); -template bool lean::lu >::is_correct( vector const &); -template lean::dense_matrix lean::get_B(lean::lu&, const vector& basis); -template lean::dense_matrix lean::get_B(lean::lu&, vector const&); +template double lp::dot_product(vector const&, vector const&); +template lp::lu::lu(lp::static_matrix const&, vector&, lp::lp_settings&); +template void lp::lu::push_matrix_to_tail(lp::tail_matrix*); +template void lp::lu::replace_column(double, lp::indexed_vector&, unsigned); +template void lp::lu::solve_Bd(unsigned int, lp::indexed_vector&, lp::indexed_vector&); +template lp::lu::~lu(); +template void lp::lu::push_matrix_to_tail(lp::tail_matrix*); +template void lp::lu::solve_Bd(unsigned int, lp::indexed_vector&, lp::indexed_vector&); +template lp::lu::~lu(); +template void lp::lu >::push_matrix_to_tail(lp::tail_matrix >*); +template void lp::lu >::solve_Bd(unsigned int, lp::indexed_vector&, lp::indexed_vector&); +template lp::lu >::~lu(); +template lp::mpq lp::dot_product(vector const&, vector const&); +template void lp::init_factorization(lp::lu*&, lp::static_matrix&, vector&, lp::lp_settings&); +template void lp::init_factorization(lp::lu*&, lp::static_matrix&, vector&, lp::lp_settings&); +template void lp::init_factorization >(lp::lu >*&, lp::static_matrix >&, vector&, lp::lp_settings&); +#ifdef Z3DEBUG +template void lp::print_matrix(lp::sparse_matrix&, std::ostream & out); +template void lp::print_matrix(lp::static_matrix&, std::ostream&); +template void lp::print_matrix >(lp::static_matrix >&, std::ostream&); +template void lp::print_matrix(lp::static_matrix&, std::ostream & out); +template bool lp::lu::is_correct(const vector& basis); +template bool lp::lu >::is_correct( vector const &); +template lp::dense_matrix lp::get_B(lp::lu&, const vector& basis); +template lp::dense_matrix lp::get_B(lp::lu&, vector const&); #endif -template bool lean::lu::pivot_the_row(int); // NOLINT -template void lean::lu::init_vector_w(unsigned int, lean::indexed_vector&); -template void lean::lu::solve_By(vector&); -template void lean::lu::solve_By_when_y_is_ready_for_X(vector&); -template void lean::lu::solve_yB_with_error_check(vector&, const vector& basis); -template void lean::lu::solve_yB_with_error_check_indexed(lean::indexed_vector&, vector const&, const vector & basis, const lp_settings&); -template void lean::lu::replace_column(lean::mpq, lean::indexed_vector&, unsigned); -template void lean::lu::solve_By(vector&); -template void lean::lu::solve_By_when_y_is_ready_for_X(vector&); -template void lean::lu::solve_yB_with_error_check(vector&, const vector& basis); -template void lean::lu::solve_yB_with_error_check_indexed(lean::indexed_vector&, vector< int > const&, const vector & basis, const lp_settings&); -template void lean::lu >::solve_yB_with_error_check_indexed(lean::indexed_vector&, vector< int > const&, const vector & basis, const lp_settings&); -template void lean::lu >::init_vector_w(unsigned int, lean::indexed_vector&); -template void lean::lu >::replace_column(lean::mpq, lean::indexed_vector&, unsigned); -template void lean::lu >::solve_Bd_faster(unsigned int, lean::indexed_vector&); -template void lean::lu >::solve_By(vector >&); -template void lean::lu >::solve_By_when_y_is_ready_for_X(vector >&); -template void lean::lu >::solve_yB_with_error_check(vector&, const vector& basis); -template void lean::lu::solve_By(lean::indexed_vector&); -template void lean::lu::solve_By(lean::indexed_vector&); -template void lean::lu::solve_yB_indexed(lean::indexed_vector&); -template void lean::lu::solve_yB_indexed(lean::indexed_vector&); -template void lean::lu >::solve_yB_indexed(lean::indexed_vector&); -template void lean::lu::solve_By_for_T_indexed_only(lean::indexed_vector&, lean::lp_settings const&); -template void lean::lu::solve_By_for_T_indexed_only(lean::indexed_vector&, lean::lp_settings const&); +template bool lp::lu::pivot_the_row(int); // NOLINT +template void lp::lu::init_vector_w(unsigned int, lp::indexed_vector&); +template void lp::lu::solve_By(vector&); +template void lp::lu::solve_By_when_y_is_ready_for_X(vector&); +template void lp::lu::solve_yB_with_error_check(vector&, const vector& basis); +template void lp::lu::solve_yB_with_error_check_indexed(lp::indexed_vector&, vector const&, const vector & basis, const lp_settings&); +template void lp::lu::replace_column(lp::mpq, lp::indexed_vector&, unsigned); +template void lp::lu::solve_By(vector&); +template void lp::lu::solve_By_when_y_is_ready_for_X(vector&); +template void lp::lu::solve_yB_with_error_check(vector&, const vector& basis); +template void lp::lu::solve_yB_with_error_check_indexed(lp::indexed_vector&, vector< int > const&, const vector & basis, const lp_settings&); +template void lp::lu >::solve_yB_with_error_check_indexed(lp::indexed_vector&, vector< int > const&, const vector & basis, const lp_settings&); +template void lp::lu >::init_vector_w(unsigned int, lp::indexed_vector&); +template void lp::lu >::replace_column(lp::mpq, lp::indexed_vector&, unsigned); +template void lp::lu >::solve_Bd_faster(unsigned int, lp::indexed_vector&); +template void lp::lu >::solve_By(vector >&); +template void lp::lu >::solve_By_when_y_is_ready_for_X(vector >&); +template void lp::lu >::solve_yB_with_error_check(vector&, const vector& basis); +template void lp::lu::solve_By(lp::indexed_vector&); +template void lp::lu::solve_By(lp::indexed_vector&); +template void lp::lu::solve_yB_indexed(lp::indexed_vector&); +template void lp::lu::solve_yB_indexed(lp::indexed_vector&); +template void lp::lu >::solve_yB_indexed(lp::indexed_vector&); +template void lp::lu::solve_By_for_T_indexed_only(lp::indexed_vector&, lp::lp_settings const&); +template void lp::lu::solve_By_for_T_indexed_only(lp::indexed_vector&, lp::lp_settings const&); diff --git a/src/util/lp/matrix.h b/src/util/lp/matrix.h index 63fd5c01e..f6374756f 100644 --- a/src/util/lp/matrix.h +++ b/src/util/lp/matrix.h @@ -1,14 +1,29 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #ifdef Z3DEBUG #pragma once #include "util/lp/numeric_pair.h" #include "util/vector.h" #include #include "util/lp/lp_settings.h" -namespace lean { +namespace lp { // used for debugging purposes only template class matrix { diff --git a/src/util/lp/matrix.hpp b/src/util/lp/matrix.hpp index d032cab8c..6eb82a9cc 100644 --- a/src/util/lp/matrix.hpp +++ b/src/util/lp/matrix.hpp @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #ifdef Z3DEBUG #include #include #include "util/lp/matrix.h" -namespace lean { +namespace lp { template bool matrix::is_equal(const matrix& other) { if (other.row_count() != row_count() || other.column_count() != column_count()) diff --git a/src/util/lp/matrix_instances.cpp b/src/util/lp/matrix_instances.cpp index aeee62786..8271a4d8a 100644 --- a/src/util/lp/matrix_instances.cpp +++ b/src/util/lp/matrix_instances.cpp @@ -1,16 +1,31 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lp_settings.h" -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG #include "util/lp/matrix.hpp" #include "util/lp/static_matrix.h" #include -template void lean::print_matrix(lean::matrix const*, std::ostream & out); -template bool lean::matrix::is_equal(lean::matrix const&); -template void lean::print_matrix >(lean::matrix > const *, std::basic_ostream > &); -template void lean::print_matrix(lean::matrix const*, std::ostream&); -template bool lean::matrix >::is_equal(lean::matrix > const&); -template bool lean::matrix::is_equal(lean::matrix const&); +template void lp::print_matrix(lp::matrix const*, std::ostream & out); +template bool lp::matrix::is_equal(lp::matrix const&); +template void lp::print_matrix >(lp::matrix > const *, std::basic_ostream > &); +template void lp::print_matrix(lp::matrix const*, std::ostream&); +template bool lp::matrix >::is_equal(lp::matrix > const&); +template bool lp::matrix::is_equal(lp::matrix const&); #endif diff --git a/src/util/lp/mps_reader.h b/src/util/lp/mps_reader.h index 4c793d56e..1b020407d 100644 --- a/src/util/lp/mps_reader.h +++ b/src/util/lp/mps_reader.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once @@ -19,7 +34,7 @@ #include "util/lp/lar_solver.h" #include "util/lp/lp_utils.h" #include "util/lp/lp_solver.h" -namespace lean { +namespace lp { inline bool my_white_space(const char & a) { return a == ' ' || a == '\t'; } @@ -160,9 +175,9 @@ class mps_reader { if (m_line[i] == ' ') break; } - lean_assert(m_line.size() >= offset); - lean_assert(m_line.size() >> i); - lean_assert(i >= offset); + SASSERT(m_line.size() >= offset); + SASSERT(m_line.size() >> i); + SASSERT(i >= offset); return m_line.substr(offset, i - offset); } @@ -497,7 +512,7 @@ class mps_reader { void create_or_update_bound() { const unsigned name_offset = 14; - lean_assert(m_line.size() >= 14); + SASSERT(m_line.size() >= 14); vector bound_string = split_and_trim(m_line.substr(name_offset, m_line.size())); if (bound_string.size() == 0) { @@ -603,7 +618,7 @@ class mps_reader { } for (auto s : row_with_range->m_row_columns) { - lean_assert(m_columns.find(s.first) != m_columns.end()); + SASSERT(m_columns.find(s.first) != m_columns.end()); other_bound_range_row->m_row_columns[s.first] = s.second; } } @@ -679,7 +694,7 @@ class mps_reader { if (row->m_name != m_cost_row_name) { solver->add_constraint(get_relation_from_row(row->m_type), row->m_right_side, row->m_index); for (auto s : row->m_row_columns) { - lean_assert(m_columns.find(s.first) != m_columns.end()); + SASSERT(m_columns.find(s.first) != m_columns.end()); solver->set_row_column_coefficient(row->m_index, m_columns[s.first]->m_index, s.second); } } else { @@ -714,7 +729,7 @@ class mps_reader { void set_solver_cost(row * row, lp_solver *solver) { for (auto s : row->m_row_columns) { std::string name = s.first; - lean_assert(m_columns.find(name) != m_columns.end()); + SASSERT(m_columns.find(name) != m_columns.end()); mps_reader::column * col = m_columns[name]; solver->set_cost_for_column(col->m_index, s.second); } @@ -723,7 +738,7 @@ class mps_reader { public: void set_message_stream(std::ostream * o) { - lean_assert(o != nullptr); + SASSERT(o != nullptr); m_message_stream = o; } vector column_names() { diff --git a/src/util/lp/numeric_pair.h b/src/util/lp/numeric_pair.h index 84c99b3b1..4ebe63613 100644 --- a/src/util/lp/numeric_pair.h +++ b/src/util/lp/numeric_pair.h @@ -1,33 +1,38 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson - The idea is that it is only one different file in Lean and z3 source inside of LP -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once -#define lp_for_z3 + #include #include #include -#ifdef lp_for_z3 #include "../rational.h" #include "../sstream.h" #include "../z3_exception.h" -#else - // include "util/numerics/mpq.h" - // include "util/numerics/numeric_traits.h" -#endif -namespace lean { -#ifdef lp_for_z3 // rename rationals - typedef rational mpq; -#else - typedef lean::mpq mpq; -#endif +namespace lp { + typedef rational mpq; // rename rationals template std::string T_to_string(const T & t); // forward definition -#ifdef lp_for_z3 + template class numeric_traits {}; template <> class numeric_traits { @@ -67,14 +72,13 @@ template <> class numeric_traits { static bool is_pos(const rational & d) {return d.is_pos();} static bool is_neg(const rational & d) {return d.is_neg();} }; -#endif template struct convert_struct { static X convert(const Y & y){ return X(y);} static bool is_epsilon_small(const X & x, const double & y) { return std::abs(numeric_traits::get_double(x)) < y; } - static bool below_bound_numeric(const X &, const X &, const Y &) { /*lean_unreachable();*/ return false;} - static bool above_bound_numeric(const X &, const X &, const Y &) { /*lean_unreachable();*/ return false; } + static bool below_bound_numeric(const X &, const X &, const Y &) { /*SASSERT(false);*/ return false;} + static bool above_bound_numeric(const X &, const X &, const Y &) { /*SASSERT(false);*/ return false; } }; @@ -104,9 +108,9 @@ struct numeric_pair { template numeric_pair(const X & n) : x(n), y(0) { } - + numeric_pair(const numeric_pair & n) : x(n.x), y(n.y) {} - + template numeric_pair(X xp, Y yp) : x(convert_struct::convert(xp)), y(convert_struct::convert(yp)) {} @@ -144,16 +148,16 @@ struct numeric_pair { } numeric_pair operator/(const numeric_pair &) const { - // lean_unreachable(); + // SASSERT(false); } - - + + numeric_pair operator+(const numeric_pair & a) const { return numeric_pair(a.x + x, a.y + y); } numeric_pair operator*(const numeric_pair & /*a*/) const { - // lean_unreachable(); + // SASSERT(false); } numeric_pair& operator+=(const numeric_pair & a) { @@ -188,14 +192,14 @@ struct numeric_pair { return numeric_pair(-x, -y); } - static bool precize() { return lean::numeric_traits::precize();} + static bool precize() { return lp::numeric_traits::precize();} bool is_zero() const { return x.is_zero() && y.is_zero(); } bool is_pos() const { return x.is_pos() || (x.is_zero() && y.is_pos());} bool is_neg() const { return x.is_neg() || (x.is_zero() && y.is_neg());} - + std::string to_string() const { return std::string("(") + T_to_string(x) + ", " + T_to_string(y) + ")"; } @@ -225,15 +229,15 @@ numeric_pair operator/(const numeric_pair & r, const X & a) { } // template bool precise() { return numeric_traits::precise();} -template double get_double(const lean::numeric_pair & ) { /* lean_unreachable(); */ return 0;} +template double get_double(const lp::numeric_pair & ) { /* SASSERT(false); */ return 0;} template -class numeric_traits> { +class numeric_traits> { public: static bool precise() { return numeric_traits::precise();} - static lean::numeric_pair zero() { return lean::numeric_pair(numeric_traits::zero(), numeric_traits::zero()); } - static bool is_zero(const lean::numeric_pair & v) { return numeric_traits::is_zero(v.x) && numeric_traits::is_zero(v.y); } - static double get_double(const lean::numeric_pair & v){ return numeric_traits::get_double(v.x); } // just return the double of the first coordinate - static double one() { /*lean_unreachable();*/ return 0;} + static lp::numeric_pair zero() { return lp::numeric_pair(numeric_traits::zero(), numeric_traits::zero()); } + static bool is_zero(const lp::numeric_pair & v) { return numeric_traits::is_zero(v.x) && numeric_traits::is_zero(v.y); } + static double get_double(const lp::numeric_pair & v){ return numeric_traits::get_double(v.x); } // just return the double of the first coordinate + static double one() { /*SASSERT(false);*/ return 0;} static bool is_pos(const numeric_pair &p) { return numeric_traits::is_pos(p.x) || (numeric_traits::is_zero(p.x) && numeric_traits::is_pos(p.y)); @@ -242,7 +246,7 @@ class numeric_traits> { return numeric_traits::is_neg(p.x) || (numeric_traits::is_zero(p.x) && numeric_traits::is_neg(p.y)); } - + }; template <> @@ -263,11 +267,11 @@ struct convert_struct, double> { return convert_struct::is_epsilon_small(p.x, eps) && convert_struct::is_epsilon_small(p.y, eps); } static bool below_bound_numeric(const numeric_pair &, const numeric_pair &, const double &) { - // lean_unreachable(); + // SASSERT(false); return false; } static bool above_bound_numeric(const numeric_pair &, const numeric_pair &, const double &) { - // lean_unreachable(); + // SASSERT(false); return false; } }; diff --git a/src/util/lp/permutation_matrix.h b/src/util/lp/permutation_matrix.h index 4bdd57f25..7cf64a5c7 100644 --- a/src/util/lp/permutation_matrix.h +++ b/src/util/lp/permutation_matrix.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include @@ -12,8 +27,8 @@ #include "util/lp/lp_settings.h" #include "util/lp/matrix.h" #include "util/lp/tail_matrix.h" -namespace lean { -#ifdef LEAN_DEBUG +namespace lp { +#ifdef Z3DEBUG inline bool is_even(int k) { return (k/2)*2 == k; } #endif @@ -50,7 +65,7 @@ class permutation_matrix : public tail_matrix { void init(unsigned length); unsigned get_rev(unsigned i) { return m_rev[i]; } bool is_dense() const { return false; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG permutation_matrix get_inverse() const { return permutation_matrix(size(), m_rev); } @@ -86,14 +101,14 @@ class permutation_matrix : public tail_matrix { void apply_reverse_from_right_to_X(vector & w); void set_val(unsigned i, unsigned pi) { - lean_assert(i < size() && pi < size()); m_permutation[i] = pi; m_rev[pi] = i; } + SASSERT(i < size() && pi < size()); m_permutation[i] = pi; m_rev[pi] = i; } void transpose_from_left(unsigned i, unsigned j); unsigned apply_reverse(unsigned i) const { return m_rev[i]; } void transpose_from_right(unsigned i, unsigned j); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG T get_elem(unsigned i, unsigned j) const{ return m_permutation[i] == j? numeric_traits::one() : numeric_traits::zero(); } diff --git a/src/util/lp/permutation_matrix.hpp b/src/util/lp/permutation_matrix.hpp index ec9af5a50..be96ca99f 100644 --- a/src/util/lp/permutation_matrix.hpp +++ b/src/util/lp/permutation_matrix.hpp @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include "util/lp/permutation_matrix.h" -namespace lean { +namespace lp { template permutation_matrix::permutation_matrix(unsigned length): m_permutation(length), m_rev(length), m_T_buffer(length), m_X_buffer(length) { for (unsigned i = 0; i < length; i++) { // do not change the direction of the loop because of the vectorization bug in clang3.3 m_permutation[i] = m_rev[i] = i; @@ -27,7 +42,7 @@ template void permutation_matrix::init(unsigned l } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template void permutation_matrix::print(std::ostream & out) const { out << "["; for (unsigned i = 0; i < size(); i++) { @@ -44,13 +59,13 @@ template void permutation_matrix::print(std::ostr template void permutation_matrix::apply_from_left(vector & w, lp_settings & ) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // L * deb_w = clone_vector(w, row_count()); // deb.apply_from_left(deb_w); #endif // std::cout << " apply_from_left " << std::endl; - lean_assert(m_X_buffer.size() == w.size()); + SASSERT(m_X_buffer.size() == w.size()); unsigned i = size(); while (i-- > 0) { m_X_buffer[i] = w[m_permutation[i]]; @@ -59,8 +74,8 @@ void permutation_matrix::apply_from_left(vector & w, lp_settings & ) { while (i-- > 0) { w[i] = m_X_buffer[i]; } -#ifdef LEAN_DEBUG - // lean_assert(vectors_are_equal(deb_w, w, row_count())); +#ifdef Z3DEBUG + // SASSERT(vectors_are_equal(deb_w, w, row_count())); // delete [] deb_w; #endif } @@ -81,12 +96,12 @@ void permutation_matrix::apply_from_left_to_T(indexed_vector & w, lp_se } template void permutation_matrix::apply_from_right(vector & w) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // T * deb_w = clone_vector(w, row_count()); // deb.apply_from_right(deb_w); #endif - lean_assert(m_T_buffer.size() == w.size()); + SASSERT(m_T_buffer.size() == w.size()); for (unsigned i = 0; i < size(); i++) { m_T_buffer[i] = w[m_rev[i]]; } @@ -94,14 +109,14 @@ template void permutation_matrix::apply_from_righ for (unsigned i = 0; i < size(); i++) { w[i] = m_T_buffer[i]; } -#ifdef LEAN_DEBUG - // lean_assert(vectors_are_equal(deb_w, w, row_count())); +#ifdef Z3DEBUG + // SASSERT(vectors_are_equal(deb_w, w, row_count())); // delete [] deb_w; #endif } template void permutation_matrix::apply_from_right(indexed_vector & w) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG vector wcopy(w.m_data); apply_from_right(wcopy); #endif @@ -117,9 +132,9 @@ template void permutation_matrix::apply_from_righ unsigned pj = m_permutation[j]; w.set_value(buffer[i], pj); } - lean_assert(w.is_OK()); -#ifdef LEAN_DEBUG - lean_assert(vectors_are_equal(wcopy, w.m_data)); + SASSERT(w.is_OK()); +#ifdef Z3DEBUG + SASSERT(vectors_are_equal(wcopy, w.m_data)); #endif } @@ -147,7 +162,7 @@ void permutation_matrix::clear_data(indexed_vector & w) { template template void permutation_matrix::apply_reverse_from_left(indexed_vector & w) { // the result will be w = p(-1) * w -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(get_reverse()); // L * deb_w = clone_vector(w.m_data, row_count()); // deb.apply_from_left(deb_w); @@ -165,8 +180,8 @@ void permutation_matrix::apply_reverse_from_left(indexed_vector & w) { w[j] = t[i]; w.m_index[i] = j; } -#ifdef LEAN_DEBUG - // lean_assert(vectors_are_equal(deb_w, w.m_data, row_count())); +#ifdef Z3DEBUG + // SASSERT(vectors_are_equal(deb_w, w.m_data, row_count())); // delete [] deb_w; #endif } @@ -174,7 +189,7 @@ void permutation_matrix::apply_reverse_from_left(indexed_vector & w) { template void permutation_matrix::apply_reverse_from_left_to_T(vector & w) { // the result will be w = p(-1) * w - lean_assert(m_T_buffer.size() == w.size()); + SASSERT(m_T_buffer.size() == w.size()); unsigned i = size(); while (i-- > 0) { m_T_buffer[m_permutation[i]] = w[i]; @@ -187,7 +202,7 @@ void permutation_matrix::apply_reverse_from_left_to_T(vector & w) { template void permutation_matrix::apply_reverse_from_left_to_X(vector & w) { // the result will be w = p(-1) * w - lean_assert(m_X_buffer.size() == w.size()); + SASSERT(m_X_buffer.size() == w.size()); unsigned i = size(); while (i-- > 0) { m_X_buffer[m_permutation[i]] = w[i]; @@ -201,7 +216,7 @@ void permutation_matrix::apply_reverse_from_left_to_X(vector & w) { template void permutation_matrix::apply_reverse_from_right_to_T(vector & w) { // the result will be w = w * p(-1) - lean_assert(m_T_buffer.size() == w.size()); + SASSERT(m_T_buffer.size() == w.size()); unsigned i = size(); while (i-- > 0) { m_T_buffer[i] = w[m_permutation[i]]; @@ -215,11 +230,11 @@ void permutation_matrix::apply_reverse_from_right_to_T(vector & w) { template void permutation_matrix::apply_reverse_from_right_to_T(indexed_vector & w) { // the result will be w = w * p(-1) -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // vector wcopy(w.m_data); // apply_reverse_from_right_to_T(wcopy); #endif - lean_assert(w.is_OK()); + SASSERT(w.is_OK()); vector tmp; vector tmp_index(w.m_index); for (auto i : w.m_index) { @@ -232,15 +247,15 @@ void permutation_matrix::apply_reverse_from_right_to_T(indexed_vector & w.set_value(tmp[k], m_rev[j]); } - // lean_assert(w.is_OK()); - // lean_assert(vectors_are_equal(w.m_data, wcopy)); + // SASSERT(w.is_OK()); + // SASSERT(vectors_are_equal(w.m_data, wcopy)); } template void permutation_matrix::apply_reverse_from_right_to_X(vector & w) { // the result will be w = w * p(-1) - lean_assert(m_X_buffer.size() == w.size()); + SASSERT(m_X_buffer.size() == w.size()); unsigned i = size(); while (i-- > 0) { m_X_buffer[i] = w[m_permutation[i]]; @@ -253,7 +268,7 @@ void permutation_matrix::apply_reverse_from_right_to_X(vector & w) { template void permutation_matrix::transpose_from_left(unsigned i, unsigned j) { // the result will be this = (i,j)*this - lean_assert(i < size() && j < size() && i != j); + SASSERT(i < size() && j < size() && i != j); auto pi = m_rev[i]; auto pj = m_rev[j]; set_val(pi, j); @@ -262,7 +277,7 @@ template void permutation_matrix::transpose_from_ template void permutation_matrix::transpose_from_right(unsigned i, unsigned j) { // the result will be this = this * (i,j) - lean_assert(i < size() && j < size() && i != j); + SASSERT(i < size() && j < size() && i != j); auto pi = m_permutation[i]; auto pj = m_permutation[j]; set_val(i, pj); @@ -271,7 +286,7 @@ template void permutation_matrix::transpose_from_ template void permutation_matrix::multiply_by_permutation_from_left(permutation_matrix & p) { m_work_array = m_permutation; - lean_assert(p.size() == size()); + SASSERT(p.size() == size()); unsigned i = size(); while (i-- > 0) { set_val(i, m_work_array[p[i]]); // we have m(P)*m(Q) = m(QP), where m is the matrix of the permutation @@ -281,7 +296,7 @@ template void permutation_matrix::multiply_by_per // this is multiplication in the matrix sense template void permutation_matrix::multiply_by_permutation_from_right(permutation_matrix & p) { m_work_array = m_permutation; - lean_assert(p.size() == size()); + SASSERT(p.size() == size()); unsigned i = size(); while (i-- > 0) set_val(i, p[m_work_array[i]]); // we have m(P)*m(Q) = m(QP), where m is the matrix of the permutation @@ -289,7 +304,7 @@ template void permutation_matrix::multiply_by_per } template void permutation_matrix::multiply_by_reverse_from_right(permutation_matrix & q){ // todo : condensed permutations ? - lean_assert(q.size() == size()); + SASSERT(q.size() == size()); m_work_array = m_permutation; // the result is this = this*q(-1) unsigned i = size(); diff --git a/src/util/lp/permutation_matrix_instances.cpp b/src/util/lp/permutation_matrix_instances.cpp index 91473fabc..692d32337 100644 --- a/src/util/lp/permutation_matrix_instances.cpp +++ b/src/util/lp/permutation_matrix_instances.cpp @@ -1,55 +1,70 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/permutation_matrix.hpp" #include "util/lp/numeric_pair.h" -template void lean::permutation_matrix::apply_from_right(vector&); -template void lean::permutation_matrix::init(unsigned int); -template void lean::permutation_matrix::init(unsigned int); -template void lean::permutation_matrix>::init(unsigned int); -template bool lean::permutation_matrix::is_identity() const; -template void lean::permutation_matrix::multiply_by_permutation_from_left(lean::permutation_matrix&); -template void lean::permutation_matrix::multiply_by_permutation_reverse_from_left(lean::permutation_matrix&); -template void lean::permutation_matrix::multiply_by_reverse_from_right(lean::permutation_matrix&); -template lean::permutation_matrix::permutation_matrix(unsigned int, vector const&); -template void lean::permutation_matrix::transpose_from_left(unsigned int, unsigned int); +template void lp::permutation_matrix::apply_from_right(vector&); +template void lp::permutation_matrix::init(unsigned int); +template void lp::permutation_matrix::init(unsigned int); +template void lp::permutation_matrix>::init(unsigned int); +template bool lp::permutation_matrix::is_identity() const; +template void lp::permutation_matrix::multiply_by_permutation_from_left(lp::permutation_matrix&); +template void lp::permutation_matrix::multiply_by_permutation_reverse_from_left(lp::permutation_matrix&); +template void lp::permutation_matrix::multiply_by_reverse_from_right(lp::permutation_matrix&); +template lp::permutation_matrix::permutation_matrix(unsigned int, vector const&); +template void lp::permutation_matrix::transpose_from_left(unsigned int, unsigned int); -template void lean::permutation_matrix::apply_from_right(vector&); -template bool lean::permutation_matrix::is_identity() const; -template void lean::permutation_matrix::multiply_by_permutation_from_left(lean::permutation_matrix&); -template void lean::permutation_matrix::multiply_by_permutation_from_right(lean::permutation_matrix&); -template void lean::permutation_matrix::multiply_by_permutation_reverse_from_left(lean::permutation_matrix&); -template void lean::permutation_matrix::multiply_by_reverse_from_right(lean::permutation_matrix&); -template lean::permutation_matrix::permutation_matrix(unsigned int); -template void lean::permutation_matrix::transpose_from_left(unsigned int, unsigned int); -template void lean::permutation_matrix::transpose_from_right(unsigned int, unsigned int); -template void lean::permutation_matrix >::apply_from_right(vector&); -template bool lean::permutation_matrix >::is_identity() const; -template void lean::permutation_matrix >::multiply_by_permutation_from_left(lean::permutation_matrix >&); -template void lean::permutation_matrix >::multiply_by_permutation_from_right(lean::permutation_matrix >&); -template void lean::permutation_matrix >::multiply_by_permutation_reverse_from_left(lean::permutation_matrix >&); -template void lean::permutation_matrix >::multiply_by_reverse_from_right(lean::permutation_matrix >&); -template lean::permutation_matrix >::permutation_matrix(unsigned int); -template void lean::permutation_matrix >::transpose_from_left(unsigned int, unsigned int); -template void lean::permutation_matrix >::transpose_from_right(unsigned int, unsigned int); -template void lean::permutation_matrix::apply_reverse_from_left(lean::indexed_vector&); -template void lean::permutation_matrix::apply_reverse_from_left_to_T(vector&); -template void lean::permutation_matrix::apply_reverse_from_right_to_T(vector&); -template void lean::permutation_matrix::transpose_from_right(unsigned int, unsigned int); -template void lean::permutation_matrix::apply_reverse_from_left(lean::indexed_vector&); -template void lean::permutation_matrix::apply_reverse_from_left_to_T(vector&); -template void lean::permutation_matrix::apply_reverse_from_right_to_T(vector&); -template void lean::permutation_matrix >::apply_reverse_from_left(lean::indexed_vector&); -template void lean::permutation_matrix >::apply_reverse_from_left_to_T(vector&); -template void lean::permutation_matrix >::apply_reverse_from_right_to_T(vector&); -template void lean::permutation_matrix::multiply_by_permutation_from_right(lean::permutation_matrix&); -template lean::permutation_matrix::permutation_matrix(unsigned int); -template void lean::permutation_matrix::apply_reverse_from_left_to_X(vector &); -template void lean::permutation_matrix< lean::mpq, lean::mpq>::apply_reverse_from_left_to_X(vector &); -template void lean::permutation_matrix< lean::mpq, lean::numeric_pair< lean::mpq> >::apply_reverse_from_left_to_X(vector> &); -template void lean::permutation_matrix::apply_reverse_from_right_to_T(lean::indexed_vector&); -template void lean::permutation_matrix::apply_reverse_from_right_to_T(lean::indexed_vector&); -template void lean::permutation_matrix >::apply_reverse_from_right_to_T(lean::indexed_vector&); +template void lp::permutation_matrix::apply_from_right(vector&); +template bool lp::permutation_matrix::is_identity() const; +template void lp::permutation_matrix::multiply_by_permutation_from_left(lp::permutation_matrix&); +template void lp::permutation_matrix::multiply_by_permutation_from_right(lp::permutation_matrix&); +template void lp::permutation_matrix::multiply_by_permutation_reverse_from_left(lp::permutation_matrix&); +template void lp::permutation_matrix::multiply_by_reverse_from_right(lp::permutation_matrix&); +template lp::permutation_matrix::permutation_matrix(unsigned int); +template void lp::permutation_matrix::transpose_from_left(unsigned int, unsigned int); +template void lp::permutation_matrix::transpose_from_right(unsigned int, unsigned int); +template void lp::permutation_matrix >::apply_from_right(vector&); +template bool lp::permutation_matrix >::is_identity() const; +template void lp::permutation_matrix >::multiply_by_permutation_from_left(lp::permutation_matrix >&); +template void lp::permutation_matrix >::multiply_by_permutation_from_right(lp::permutation_matrix >&); +template void lp::permutation_matrix >::multiply_by_permutation_reverse_from_left(lp::permutation_matrix >&); +template void lp::permutation_matrix >::multiply_by_reverse_from_right(lp::permutation_matrix >&); +template lp::permutation_matrix >::permutation_matrix(unsigned int); +template void lp::permutation_matrix >::transpose_from_left(unsigned int, unsigned int); +template void lp::permutation_matrix >::transpose_from_right(unsigned int, unsigned int); +template void lp::permutation_matrix::apply_reverse_from_left(lp::indexed_vector&); +template void lp::permutation_matrix::apply_reverse_from_left_to_T(vector&); +template void lp::permutation_matrix::apply_reverse_from_right_to_T(vector&); +template void lp::permutation_matrix::transpose_from_right(unsigned int, unsigned int); +template void lp::permutation_matrix::apply_reverse_from_left(lp::indexed_vector&); +template void lp::permutation_matrix::apply_reverse_from_left_to_T(vector&); +template void lp::permutation_matrix::apply_reverse_from_right_to_T(vector&); +template void lp::permutation_matrix >::apply_reverse_from_left(lp::indexed_vector&); +template void lp::permutation_matrix >::apply_reverse_from_left_to_T(vector&); +template void lp::permutation_matrix >::apply_reverse_from_right_to_T(vector&); +template void lp::permutation_matrix::multiply_by_permutation_from_right(lp::permutation_matrix&); +template lp::permutation_matrix::permutation_matrix(unsigned int); +template void lp::permutation_matrix::apply_reverse_from_left_to_X(vector &); +template void lp::permutation_matrix< lp::mpq, lp::mpq>::apply_reverse_from_left_to_X(vector &); +template void lp::permutation_matrix< lp::mpq, lp::numeric_pair< lp::mpq> >::apply_reverse_from_left_to_X(vector> &); +template void lp::permutation_matrix::apply_reverse_from_right_to_T(lp::indexed_vector&); +template void lp::permutation_matrix::apply_reverse_from_right_to_T(lp::indexed_vector&); +template void lp::permutation_matrix >::apply_reverse_from_right_to_T(lp::indexed_vector&); diff --git a/src/util/lp/quick_xplain.cpp b/src/util/lp/quick_xplain.cpp index a4b6fb0e6..f9506c056 100644 --- a/src/util/lp/quick_xplain.cpp +++ b/src/util/lp/quick_xplain.cpp @@ -1,9 +1,24 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/lar_solver.h" -namespace lean { +namespace lp { quick_xplain::quick_xplain(vector> & explanation, const lar_solver & ls, lar_solver & qsol) : m_explanation(explanation), m_parent_solver(ls), @@ -15,7 +30,7 @@ void quick_xplain::add_constraint_to_qsol(unsigned j) { auto ci = m_qsol.add_constraint(ls, lar_c.m_kind, lar_c.m_right_side); m_local_ci_to_constraint_offsets[ci] = j; } - + void quick_xplain::copy_constraint_and_add_constraint_vars(const lar_constraint& lar_c) { vector < std::pair> ls; for (auto & p : lar_c.get_left_side_coefficients()) { @@ -56,9 +71,9 @@ void quick_xplain::minimize(const vector& u) { } } if (m > 0) { - lean_assert(m_qsol.constraint_stack_size() >= initial_stack_size); + SASSERT(m_qsol.constraint_stack_size() >= initial_stack_size); m_qsol.pop(m_qsol.constraint_stack_size() - initial_stack_size); - for (auto j : m_x) + for (auto j : m_x) add_constraint_to_qsol(j); if (!infeasible()) { vector un; @@ -69,11 +84,11 @@ void quick_xplain::minimize(const vector& u) { } } - + void quick_xplain::run(vector> & explanation, const lar_solver & ls){ if (explanation.size() <= 2) return; lar_solver qsol; - lean_assert(ls.explanation_is_correct(explanation)); + SASSERT(ls.explanation_is_correct(explanation)); quick_xplain q(explanation, ls, qsol); q.solve(); } @@ -109,7 +124,7 @@ bool quick_xplain::x_is_minimal() const { x.push_back(j); for (unsigned k = 0; k < x.size(); k++) { - lean_assert(is_feasible(x, x[k])); + SASSERT(is_feasible(x, x[k])); } return true; } @@ -117,8 +132,8 @@ bool quick_xplain::x_is_minimal() const { void quick_xplain::solve() { copy_constraints_to_local_constraints(); m_qsol.push(); - lean_assert(m_qsol.constraint_count() == 0) - vector u; + SASSERT(m_qsol.constraint_count() == 0); + vector u; for (unsigned k = 0; k < m_constraints_in_local_vars.size(); k++) u.push_back(k); minimize(u); @@ -127,10 +142,10 @@ void quick_xplain::solve() { for (unsigned i : m_x) add_constraint_to_qsol(i); m_qsol.solve(); - lean_assert(m_qsol.get_status() == INFEASIBLE); + SASSERT(m_qsol.get_status() == INFEASIBLE); m_qsol.get_infeasibility_explanation(m_explanation); - lean_assert(m_qsol.explanation_is_correct(m_explanation)); - lean_assert(x_is_minimal()); + SASSERT(m_qsol.explanation_is_correct(m_explanation)); + SASSERT(x_is_minimal()); for (auto & p : m_explanation) { p.second = this->m_local_constraint_offset_to_external_ci[m_local_ci_to_constraint_offsets[p.second]]; } diff --git a/src/util/lp/quick_xplain.h b/src/util/lp/quick_xplain.h index 9faa5f41c..952199f85 100644 --- a/src/util/lp/quick_xplain.h +++ b/src/util/lp/quick_xplain.h @@ -7,7 +7,7 @@ Author: Lev Nachmanson #include "util/vector.h" #include -namespace lean { +namespace lp { class lar_solver; // forward definition class quick_xplain { diff --git a/src/util/lp/random_updater.h b/src/util/lp/random_updater.h index 8cb9740ea..68b14c971 100644 --- a/src/util/lp/random_updater.h +++ b/src/util/lp/random_updater.h @@ -12,7 +12,7 @@ Author: Lev Nachmanson #include "util/lp/linear_combination_iterator.h" // see http://research.microsoft.com/projects/z3/smt07.pdf // The class searches for a feasible solution with as many different values of variables as it can find -namespace lean { +namespace lp { template struct numeric_pair; // forward definition class lar_core_solver; // forward definition class random_updater { diff --git a/src/util/lp/random_updater.hpp b/src/util/lp/random_updater.hpp index 7c6a0539f..5bbcdf27c 100644 --- a/src/util/lp/random_updater.hpp +++ b/src/util/lp/random_updater.hpp @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/random_updater.h" #include "util/lp/static_matrix.h" #include "util/lp/lar_solver.h" #include "util/vector.h" -namespace lean { +namespace lp { @@ -36,7 +51,7 @@ random_updater::interval random_updater::get_interval_of_non_basic_var(unsigned ret.set_upper_bound(m_core_solver.m_r_upper_bounds[j]); break; default: - lean_assert(false); + SASSERT(false); } return ret; } @@ -44,15 +59,15 @@ random_updater::interval random_updater::get_interval_of_non_basic_var(unsigned void random_updater::diminish_interval_for_basic_var(numeric_pair& nb_x, unsigned j, mpq & a, interval & r) { - lean_assert(m_core_solver.m_r_heading[j] >= 0); + SASSERT(m_core_solver.m_r_heading[j] >= 0); numeric_pair delta; - lean_assert(a != zero_of_type()); + SASSERT(a != zero_of_type()); switch (m_core_solver.get_column_type(j)) { case column_type::free_column: break; case column_type::low_bound: delta = m_core_solver.m_r_x[j] - m_core_solver.m_r_low_bounds[j]; - lean_assert(delta >= zero_of_type>()); + SASSERT(delta >= zero_of_type>()); if (a > 0) { r.set_upper_bound(nb_x + delta / a); } else { @@ -61,7 +76,7 @@ void random_updater::diminish_interval_for_basic_var(numeric_pair& nb_x, un break; case column_type::upper_bound: delta = m_core_solver.m_r_upper_bounds()[j] - m_core_solver.m_r_x[j]; - lean_assert(delta >= zero_of_type>()); + SASSERT(delta >= zero_of_type>()); if (a > 0) { r.set_low_bound(nb_x - delta / a); } else { @@ -71,17 +86,17 @@ void random_updater::diminish_interval_for_basic_var(numeric_pair& nb_x, un case column_type::boxed: if (a > 0) { delta = m_core_solver.m_r_x[j] - m_core_solver.m_r_low_bounds[j]; - lean_assert(delta >= zero_of_type>()); + SASSERT(delta >= zero_of_type>()); r.set_upper_bound(nb_x + delta / a); delta = m_core_solver.m_r_upper_bounds()[j] - m_core_solver.m_r_x[j]; - lean_assert(delta >= zero_of_type>()); + SASSERT(delta >= zero_of_type>()); r.set_low_bound(nb_x - delta / a); } else { // a < 0 delta = m_core_solver.m_r_upper_bounds()[j] - m_core_solver.m_r_x[j]; - lean_assert(delta >= zero_of_type>()); + SASSERT(delta >= zero_of_type>()); r.set_upper_bound(nb_x - delta / a); delta = m_core_solver.m_r_x[j] - m_core_solver.m_r_low_bounds[j]; - lean_assert(delta >= zero_of_type>()); + SASSERT(delta >= zero_of_type>()); r.set_low_bound(nb_x + delta / a); } break; @@ -90,7 +105,7 @@ void random_updater::diminish_interval_for_basic_var(numeric_pair& nb_x, un r.set_upper_bound(nb_x); break; default: - lean_assert(false); + SASSERT(false); } } @@ -113,15 +128,15 @@ random_updater::interval random_updater::find_shift_interval(unsigned j) { } void random_updater::shift_var(unsigned j, interval & r) { - lean_assert(r.contains(m_core_solver.m_r_x[j])); - lean_assert(m_core_solver.m_r_solver.column_is_feasible(j)); + SASSERT(r.contains(m_core_solver.m_r_x[j])); + SASSERT(m_core_solver.m_r_solver.column_is_feasible(j)); auto old_x = m_core_solver.m_r_x[j]; remove_value(old_x); auto new_val = m_core_solver.m_r_x[j] = get_random_from_interval(r); add_value(new_val); - lean_assert(r.contains(m_core_solver.m_r_x[j])); - lean_assert(m_core_solver.m_r_solver.column_is_feasible(j)); + SASSERT(r.contains(m_core_solver.m_r_x[j])); + SASSERT(m_core_solver.m_r_solver.column_is_feasible(j)); auto delta = m_core_solver.m_r_x[j] - old_x; unsigned i; @@ -130,9 +145,9 @@ void random_updater::shift_var(unsigned j, interval & r) { while(m_column_j->next(a, i)) { unsigned bj = m_core_solver.m_r_basis[i]; m_core_solver.m_r_x[bj] -= a * delta; - lean_assert(m_core_solver.m_r_solver.column_is_feasible(bj)); + SASSERT(m_core_solver.m_r_solver.column_is_feasible(bj)); } - lean_assert(m_core_solver.m_r_solver.A_mult_x_is_off() == false); + SASSERT(m_core_solver.m_r_solver.A_mult_x_is_off() == false); } numeric_pair random_updater::get_random_from_interval(interval & r) { @@ -143,7 +158,7 @@ numeric_pair random_updater::get_random_from_interval(interval & r) { return r.low_bound + numeric_pair(rand % range, 0); if ((!r.low_bound_is_set) && r.upper_bound_is_set) return r.upper_bound - numeric_pair(rand % range, 0); - lean_assert(r.low_bound_is_set && r.upper_bound_is_set); + SASSERT(r.low_bound_is_set && r.upper_bound_is_set); return r.low_bound + (rand % range) * (r.upper_bound - r.low_bound)/ range; } @@ -183,7 +198,7 @@ void random_updater::add_value(numeric_pair& v) { void random_updater::remove_value(numeric_pair& v) { std::unordered_map, unsigned>::iterator it = m_values.find(v); - lean_assert(it != m_values.end()); + SASSERT(it != m_values.end()); it->second--; if (it->second == 0) m_values.erase((std::unordered_map, unsigned>::const_iterator)it); diff --git a/src/util/lp/random_updater_instances.cpp b/src/util/lp/random_updater_instances.cpp index 5b4c89bd5..4f9b880c0 100644 --- a/src/util/lp/random_updater_instances.cpp +++ b/src/util/lp/random_updater_instances.cpp @@ -1,5 +1,20 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/random_updater.hpp" diff --git a/src/util/lp/row_eta_matrix.h b/src/util/lp/row_eta_matrix.h index 90acb89f3..c287e263a 100644 --- a/src/util/lp/row_eta_matrix.h +++ b/src/util/lp/row_eta_matrix.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -10,26 +25,26 @@ #include "util/lp/sparse_vector.h" #include "util/lp/indexed_vector.h" #include "util/lp/permutation_matrix.h" -namespace lean { +namespace lp { // This is the sum of a unit matrix and a lower triangular matrix // with non-zero elements only in one row template class row_eta_matrix : public tail_matrix { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned m_dimension; #endif unsigned m_row_start; unsigned m_row; sparse_vector m_row_vector; public: -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG row_eta_matrix(unsigned row_start, unsigned row, unsigned dim): #else row_eta_matrix(unsigned row_start, unsigned row): #endif -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG m_dimension(dim), #endif m_row_start(row_start), m_row(row) { @@ -55,7 +70,7 @@ public: } void push_back(unsigned row_index, T val ) { - lean_assert(row_index != m_row); + SASSERT(row_index != m_row); m_row_vector.push_back(row_index, val); } @@ -63,7 +78,7 @@ public: void apply_from_right(indexed_vector & w); void conjugate_by_permutation(permutation_matrix & p); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG T get_elem(unsigned row, unsigned col) const; unsigned row_count() const { return m_dimension; } unsigned column_count() const { return m_dimension; } diff --git a/src/util/lp/row_eta_matrix.hpp b/src/util/lp/row_eta_matrix.hpp index 5758abeb8..969b4af7d 100644 --- a/src/util/lp/row_eta_matrix.hpp +++ b/src/util/lp/row_eta_matrix.hpp @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include "util/lp/row_eta_matrix.h" -namespace lean { +namespace lp { template void row_eta_matrix::apply_from_left(vector & w, lp_settings &) { - // #ifdef LEAN_DEBUG + // #ifdef Z3DEBUG // dense_matrix deb(*this); // auto clone_w = clone_vector(w, m_dimension); // deb.apply_from_left(clone_w, settings); @@ -18,8 +33,8 @@ void row_eta_matrix::apply_from_left(vector & w, lp_settings &) { w_at_row += w[it.first] * it.second; } // w[m_row] = w_at_row; - // #ifdef LEAN_DEBUG - // lean_assert(vectors_are_equal(clone_w, w, m_dimension)); + // #ifdef Z3DEBUG + // SASSERT(vectors_are_equal(clone_w, w, m_dimension)); // delete [] clone_w; // #endif } @@ -43,7 +58,7 @@ void row_eta_matrix::apply_from_left_local_to_T(indexed_vector & w, lp_ auto it = std::find(w.m_index.begin(), w.m_index.end(), m_row); w.m_index.erase(it); } - // TBD: lean_assert(check_vector_for_small_values(w, settings)); + // TBD: SASSERT(check_vector_for_small_values(w, settings)); } template @@ -65,14 +80,14 @@ void row_eta_matrix::apply_from_left_local_to_X(indexed_vector & w, lp_ auto it = std::find(w.m_index.begin(), w.m_index.end(), m_row); w.m_index.erase(it); } - // TBD: does not compile lean_assert(check_vector_for_small_values(w, settings)); + // TBD: does not compile SASSERT(check_vector_for_small_values(w, settings)); } template void row_eta_matrix::apply_from_right(vector & w) { const T & w_row = w[m_row]; if (numeric_traits::is_zero(w_row)) return; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // auto clone_w = clone_vector(w, m_dimension); // deb.apply_from_right(clone_w); @@ -80,18 +95,18 @@ void row_eta_matrix::apply_from_right(vector & w) { for (auto & it : m_row_vector.m_data) { w[it.first] += w_row * it.second; } -#ifdef LEAN_DEBUG - // lean_assert(vectors_are_equal(clone_w, w, m_dimension)); +#ifdef Z3DEBUG + // SASSERT(vectors_are_equal(clone_w, w, m_dimension)); // delete clone_w; #endif } template void row_eta_matrix::apply_from_right(indexed_vector & w) { - lean_assert(w.is_OK()); + SASSERT(w.is_OK()); const T & w_row = w[m_row]; if (numeric_traits::is_zero(w_row)) return; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // vector wcopy(w.m_data); // apply_from_right(wcopy); #endif @@ -129,8 +144,8 @@ void row_eta_matrix::apply_from_right(indexed_vector & w) { } } } -#ifdef LEAN_DEBUG - // lean_assert(vectors_are_equal(wcopy, w.m_data)); +#ifdef Z3DEBUG + // SASSERT(vectors_are_equal(wcopy, w.m_data)); #endif } @@ -138,7 +153,7 @@ void row_eta_matrix::apply_from_right(indexed_vector & w) { template void row_eta_matrix::conjugate_by_permutation(permutation_matrix & p) { // this = p * this * p(-1) -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // auto rev = p.get_reverse(); // auto deb = ((*this) * rev); // deb = p * deb; @@ -150,11 +165,11 @@ void row_eta_matrix::conjugate_by_permutation(permutation_matrix & p columns.push_back(it.first); for (unsigned i = static_cast(columns.size()); i-- > 0;) m_row_vector.m_data[i].first = p.get_rev(columns[i]); -#ifdef LEAN_DEBUG - // lean_assert(deb == *this); +#ifdef Z3DEBUG + // SASSERT(deb == *this); #endif } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template T row_eta_matrix::get_elem(unsigned row, unsigned col) const { if (row == m_row){ diff --git a/src/util/lp/row_eta_matrix_instances.cpp b/src/util/lp/row_eta_matrix_instances.cpp index c172eda11..3c4ab9bed 100644 --- a/src/util/lp/row_eta_matrix_instances.cpp +++ b/src/util/lp/row_eta_matrix_instances.cpp @@ -1,16 +1,31 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/row_eta_matrix.hpp" #include "util/lp/lu.h" -namespace lean { +namespace lp { template void row_eta_matrix::conjugate_by_permutation(permutation_matrix&); template void row_eta_matrix >::conjugate_by_permutation(permutation_matrix >&); template void row_eta_matrix::conjugate_by_permutation(permutation_matrix&); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template mpq row_eta_matrix::get_elem(unsigned int, unsigned int) const; template mpq row_eta_matrix >::get_elem(unsigned int, unsigned int) const; template double row_eta_matrix::get_elem(unsigned int, unsigned int) const; diff --git a/src/util/lp/scaler.h b/src/util/lp/scaler.h index 33c5a6cc4..509671528 100644 --- a/src/util/lp/scaler.h +++ b/src/util/lp/scaler.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -11,7 +26,7 @@ #include /* exit, EXIT_FAILURE */ #include "util/lp/lp_utils.h" #include "util/lp/static_matrix.h" -namespace lean { +namespace lp { // for scaling an LP template class scaler { @@ -31,7 +46,7 @@ public: m_scaling_maximum(scaling_maximum), m_column_scale(column_scale), m_settings(settings) { - lean_assert(m_column_scale.size() == 0); + SASSERT(m_column_scale.size() == 0); m_column_scale.resize(m_A.column_count(), numeric_traits::one()); } diff --git a/src/util/lp/scaler.hpp b/src/util/lp/scaler.hpp index 69427eea0..ea8dc98c4 100644 --- a/src/util/lp/scaler.hpp +++ b/src/util/lp/scaler.hpp @@ -1,11 +1,26 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/lp/scaler.h" #include "util/lp/numeric_pair.h" -namespace lean { +namespace lp { // for scaling an LP template T scaler::right_side_balance() { T ret = zero_of_type(); @@ -41,7 +56,7 @@ template T scaler::A_max() const { template T scaler::get_A_ratio() const { T min = A_min(); T max = A_max(); - lean_assert(!m_settings.abs_val_is_smaller_than_zero_tolerance(min)); + SASSERT(!m_settings.abs_val_is_smaller_than_zero_tolerance(min)); T ratio = max / min; return ratio; } @@ -51,7 +66,7 @@ template T scaler::get_max_ratio_on_rows() con unsigned i = m_A.row_count(); while (i--) { T den = m_A.get_min_abs_in_row(i); - lean_assert(!m_settings.abs_val_is_smaller_than_zero_tolerance(den)); + SASSERT(!m_settings.abs_val_is_smaller_than_zero_tolerance(den)); T t = m_A.get_max_abs_in_row(i)/ den; if (t > ret) ret = t; @@ -78,7 +93,7 @@ template void scaler::scale_rows_with_geometri while (i--) { T max = m_A.get_max_abs_in_row(i); T min = m_A.get_min_abs_in_row(i); - lean_assert(max > zero_of_type() && min > zero_of_type()); + SASSERT(max > zero_of_type() && min > zero_of_type()); if (is_zero(max) || is_zero(min)) continue; T gm = T(sqrt(numeric_traits::get_double(max*min))); diff --git a/src/util/lp/scaler_instances.cpp b/src/util/lp/scaler_instances.cpp index f97e8098f..ba02321ea 100644 --- a/src/util/lp/scaler_instances.cpp +++ b/src/util/lp/scaler_instances.cpp @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/lp/scaler.hpp" -template bool lean::scaler::scale(); -template bool lean::scaler::scale(); +template bool lp::scaler::scale(); +template bool lp::scaler::scale(); diff --git a/src/util/lp/signature_bound_evidence.h b/src/util/lp/signature_bound_evidence.h index a22c188b4..e4eeb328d 100644 --- a/src/util/lp/signature_bound_evidence.h +++ b/src/util/lp/signature_bound_evidence.h @@ -1,11 +1,26 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/lp/lp_settings.h" #include "util/lp/lar_constraints.h" -namespace lean { +namespace lp { struct bound_signature { unsigned m_i; bool m_at_low; diff --git a/src/util/lp/sparse_matrix.h b/src/util/lp/sparse_matrix.h index 7256004da..400f2bfc0 100644 --- a/src/util/lp/sparse_matrix.h +++ b/src/util/lp/sparse_matrix.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -21,11 +36,11 @@ #include "util/lp/binary_heap_upair_queue.h" #include "util/lp/numeric_pair.h" #include "util/lp/int_set.h" -namespace lean { +namespace lp { // it is a square matrix template class sparse_matrix -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG : public matrix #endif { @@ -57,7 +72,7 @@ public: vector m_processed; unsigned get_n_of_active_elems() const { return m_n_of_active_elems; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix m_dense; #endif /* @@ -146,7 +161,7 @@ public: unsigned dimension() const {return static_cast(m_row_permutation.size());} -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned row_count() const {return dimension();} unsigned column_count() const {return dimension();} #endif @@ -206,19 +221,19 @@ public: void multiply_from_right(permutation_matrix& p) { // m_dense = m_dense * p; m_column_permutation.multiply_by_permutation_from_right(p); - // lean_assert(*this == m_dense); + // SASSERT(*this == m_dense); } void multiply_from_left(permutation_matrix& p) { // m_dense = p * m_dense; m_row_permutation.multiply_by_permutation_from_left(p); - // lean_assert(*this == m_dense); + // SASSERT(*this == m_dense); } void multiply_from_left_with_reverse(permutation_matrix& p) { // m_dense = p * m_dense; m_row_permutation.multiply_by_permutation_reverse_from_left(p); - // lean_assert(*this == m_dense); + // SASSERT(*this == m_dense); } // adding delta columns at the end of the matrix @@ -231,13 +246,13 @@ public: // dense_matrix d(*this); m_column_permutation.transpose_from_left(a, b); // d.swap_columns(a, b); - // lean_assert(*this == d); + // SASSERT(*this == d); } void swap_rows(unsigned a, unsigned b) { m_row_permutation.transpose_from_right(a, b); // m_dense.swap_rows(a, b); - // lean_assert(*this == m_dense); + // SASSERT(*this == m_dense); } void divide_row_by_constant(unsigned i, const T & t, lp_settings & settings); @@ -286,7 +301,7 @@ public: template void solve_U_y_indexed_only(indexed_vector & y, const lp_settings&, vector & sorted_active_rows ); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG T get_elem(unsigned i, unsigned j) const { return get(i, j); } unsigned get_number_of_rows() const { return dimension(); } unsigned get_number_of_columns() const { return dimension(); } @@ -341,7 +356,7 @@ public: bool shorten_active_matrix(unsigned row, eta_matrix *eta_matrix); unsigned pivot_score_without_shortened_counters(unsigned i, unsigned j, unsigned k); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG bool can_improve_score_for_row(unsigned row, unsigned score, T const & c_partial_pivoting, unsigned k); bool really_best_pivot(unsigned i, unsigned j, T const & c_partial_pivoting, unsigned k); void print_active_matrix(unsigned k, std::ostream & out); @@ -373,7 +388,7 @@ public: } bool fill_eta_matrix(unsigned j, eta_matrix ** eta); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG bool is_upper_triangular_and_maximums_are_set_correctly_in_rows(lp_settings & settings) const; bool is_upper_triangular_until(unsigned k) const; @@ -393,7 +408,7 @@ public: void process_index_recursively_for_y_U(unsigned j, vector & sorted_rows); void resize(unsigned new_dim) { unsigned old_dim = dimension(); - lean_assert(new_dim >= old_dim); + SASSERT(new_dim >= old_dim); for (unsigned j = old_dim; j < new_dim; j++) { m_rows.push_back(vector>()); m_columns.push_back(col_header()); @@ -407,7 +422,7 @@ public: add_new_element(j, j, numeric_traits::one()); } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG vector get_full_row(unsigned i) const; #endif unsigned pivot_queue_size() const { return m_pivot_queue.size(); } diff --git a/src/util/lp/sparse_matrix.hpp b/src/util/lp/sparse_matrix.hpp index 32bb8ed4e..d2040d313 100644 --- a/src/util/lp/sparse_matrix.hpp +++ b/src/util/lp/sparse_matrix.hpp @@ -1,13 +1,28 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include "util/lp/sparse_matrix.h" #include #include -namespace lean { +namespace lp { template void sparse_matrix::copy_column_from_static_matrix(unsigned col, static_matrix const &A, unsigned col_index_in_the_new_matrix) { vector const & A_col_vector = A.m_columns[col]; @@ -82,12 +97,12 @@ void sparse_matrix::set_with_no_adjusting(unsigned row, unsigned col, T va template void sparse_matrix::set(unsigned row, unsigned col, T val) { // should not be used in efficient code - lean_assert(row < dimension() && col < dimension()); + SASSERT(row < dimension() && col < dimension()); // m_dense.set_elem(row, col, val); row = adjust_row(row); col = adjust_column(col); set_with_no_adjusting(row, col, val); - // lean_assert(*this == m_dense); + // SASSERT(*this == m_dense); } template @@ -243,7 +258,7 @@ void sparse_matrix::scan_row_to_work_vector_and_remove_pivot_column(unsign } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template vector sparse_matrix::get_full_row(unsigned i) const { vector r; @@ -261,8 +276,8 @@ vector sparse_matrix::get_full_row(unsigned i) const { // Returns false if the resulting row is all zeroes, and true otherwise template bool sparse_matrix::pivot_row_to_row(unsigned i, const T& alpha, unsigned i0, lp_settings & settings ) { - lean_assert(i < dimension() && i0 < dimension()); - lean_assert(i != i0); + SASSERT(i < dimension() && i0 < dimension()); + SASSERT(i != i0); unsigned pivot_col = adjust_column(i); i = adjust_row(i); i0 = adjust_row(i0); @@ -327,7 +342,7 @@ bool sparse_matrix::set_row_from_work_vector_and_clean_work_vector_not_adj if (numeric_traits::is_zero(work_vec[j])) { continue; } - lean_assert(!settings.abs_val_is_smaller_than_drop_tolerance(work_vec[j])); + SASSERT(!settings.abs_val_is_smaller_than_drop_tolerance(work_vec[j])); add_new_element(i0, adjust_column(j), work_vec[j]); work_vec[j] = numeric_traits::zero(); } @@ -372,7 +387,7 @@ void sparse_matrix::remove_zero_elements_and_set_data_on_existing_elements T val = work_vec[rj]; if (settings.abs_val_is_smaller_than_drop_tolerance(val)) { remove_element(row_vals, row_el_iv); - lean_assert(numeric_traits::is_zero(val)); + SASSERT(numeric_traits::is_zero(val)); } else { m_columns[j].m_values[row_el_iv.m_other].set_value(row_el_iv.m_value = val); work_vec[rj] = numeric_traits::zero(); @@ -393,7 +408,7 @@ void sparse_matrix::add_columns_at_the_end(unsigned delta) { template void sparse_matrix::delete_column(int i) { - lean_assert(i < dimension()); + SASSERT(i < dimension()); for (auto cell = m_columns[i].m_head; cell != nullptr;) { auto next_cell = cell->m_down; kill_cell(cell); @@ -403,7 +418,7 @@ void sparse_matrix::delete_column(int i) { template void sparse_matrix::divide_row_by_constant(unsigned i, const T & t, lp_settings & settings) { - lean_assert(!settings.abs_val_is_smaller_than_zero_tolerance(t)); + SASSERT(!settings.abs_val_is_smaller_than_zero_tolerance(t)); i = adjust_row(i); for (auto & iv : m_rows[i]) { T &v = iv.m_value; @@ -420,7 +435,7 @@ void sparse_matrix::divide_row_by_constant(unsigned i, const T & t, lp_set // the matrix here has to be upper triangular template void sparse_matrix::solve_y_U(vector & y) const { // works by rows -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // T * rs = clone_vector(y, dimension()); #endif unsigned end = dimension(); @@ -436,11 +451,11 @@ void sparse_matrix::solve_y_U(vector & y) const { // works by rows } } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // T * clone_y = clone_vector(y, dimension()); // deb.apply_from_right(clone_y); - // lean_assert(vectors_are_equal(rs, clone_y, dimension())); + // SASSERT(vectors_are_equal(rs, clone_y, dimension())); // delete [] clone_y; // delete [] rs; #endif @@ -450,7 +465,7 @@ void sparse_matrix::solve_y_U(vector & y) const { // works by rows // the matrix here has to be upper triangular template void sparse_matrix::solve_y_U_indexed(indexed_vector & y, const lp_settings & settings) { -#if 0 && LEAN_DEBUG +#if 0 && Z3DEBUG vector ycopy(y.m_data); if (numeric_traits::precise() == false) solve_y_U(ycopy); @@ -474,10 +489,10 @@ void sparse_matrix::solve_y_U_indexed(indexed_vector & y, const lp_sett y.m_data[j] = zero_of_type(); } - lean_assert(y.is_OK()); -#if 0 && LEAN_DEBUG + SASSERT(y.is_OK()); +#if 0 && Z3DEBUG if (numeric_traits::precise() == false) - lean_assert(vectors_are_equal(ycopy, y.m_data)); + SASSERT(vectors_are_equal(ycopy, y.m_data)); #endif } @@ -537,8 +552,8 @@ void sparse_matrix::add_delta_to_solution(const vector& del, vector template template void sparse_matrix::add_delta_to_solution(const indexed_vector& del, indexed_vector & y) { -// lean_assert(del.is_OK()); - // lean_assert(y.is_OK()); +// SASSERT(del.is_OK()); + // SASSERT(y.is_OK()); for (auto i : del.m_index) { y.add_value_at_index(i, del[i]); } @@ -546,11 +561,11 @@ void sparse_matrix::add_delta_to_solution(const indexed_vector& del, in template template void sparse_matrix::double_solve_U_y(indexed_vector& y, const lp_settings & settings){ - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); indexed_vector y_orig(y); // copy y aside vector active_rows; solve_U_y_indexed_only(y, settings, active_rows); - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); find_error_in_solution_U_y_indexed(y_orig, y, active_rows); // y_orig contains the error now if (y_orig.m_index.size() * ratio_of_index_size_to_all_size() < 32 * dimension()) { @@ -563,7 +578,7 @@ void sparse_matrix::double_solve_U_y(indexed_vector& y, const lp_settin add_delta_to_solution(y_orig.m_data, y.m_data); y.restore_index_and_clean_from_data(); } - lean_assert(y.is_OK()); + SASSERT(y.is_OK()); } template template @@ -581,7 +596,7 @@ void sparse_matrix::double_solve_U_y(vector& y){ template template void sparse_matrix::solve_U_y(vector & y) { // it is a column wise version -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // T * rs = clone_vector(y, dimension()); #endif @@ -595,16 +610,16 @@ void sparse_matrix::solve_U_y(vector & y) { // it is a column wise vers } } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // T * clone_y = clone_vector(y, dimension()); // deb.apply_from_left(clone_y); - // lean_assert(vectors_are_equal(rs, clone_y, dimension())); + // SASSERT(vectors_are_equal(rs, clone_y, dimension())); #endif } template void sparse_matrix::process_index_recursively_for_y_U(unsigned j, vector & sorted_active_rows) { - lean_assert(m_processed[j] == false); + SASSERT(m_processed[j] == false); m_processed[j]=true; auto & row = m_rows[adjust_row(j)]; for (auto & c : row) { @@ -619,7 +634,7 @@ void sparse_matrix::process_index_recursively_for_y_U(unsigned j, vector void sparse_matrix::process_column_recursively(unsigned j, vector & sorted_active_rows) { - lean_assert(m_processed[j] == false); + SASSERT(m_processed[j] == false); auto & mc = m_columns[adjust_column(j)].m_values; for (auto & iv : mc) { unsigned i = adjust_row_inverse(iv.m_index); @@ -684,12 +699,12 @@ void sparse_matrix::solve_U_y_indexed_only(indexed_vector & y, const lp y[j] = zero_of_type(); } - lean_assert(y.is_OK()); -#ifdef LEAN_DEBUG + SASSERT(y.is_OK()); +#ifdef Z3DEBUG // dense_matrix deb(this); // vector clone_y(y.m_data); // deb.apply_from_left(clone_y); - // lean_assert(vectors_are_equal(rs, clone_y)); + // SASSERT(vectors_are_equal(rs, clone_y)); #endif } @@ -802,7 +817,7 @@ void sparse_matrix::add_new_elements_of_w_and_clear_w(unsigned column_to_r unsigned ai = adjust_row(i); add_new_element(ai, column_to_replace, w_at_i); auto & row_chunk = m_rows[ai]; - lean_assert(row_chunk.size() > 0); + SASSERT(row_chunk.size() > 0); if (abs(w_at_i) > abs(row_chunk[0].m_value)) put_max_index_to_0(row_chunk, static_cast(row_chunk.size()) - 1); } @@ -833,7 +848,7 @@ unsigned sparse_matrix::pivot_score(unsigned i, unsigned j) { template void sparse_matrix::enqueue_domain_into_pivot_queue() { - lean_assert(m_pivot_queue.size() == 0); + SASSERT(m_pivot_queue.size() == 0); for (unsigned i = 0; i < dimension(); i++) { auto & rh = m_rows[i]; unsigned rnz = static_cast(rh.size()); @@ -919,7 +934,7 @@ void sparse_matrix::update_active_pivots(unsigned row) { for (const auto & iv : m_rows[arow]) { col_header & ch = m_columns[iv.m_index]; int cols = static_cast(ch.m_values.size()) - ch.m_shortened_markovitz - 1; - lean_assert(cols >= 0); + SASSERT(cols >= 0); for (const auto &ivc : ch.m_values) { unsigned i = ivc.m_index; if (adjust_row_inverse(i) <= row) continue; // the i is not an active row @@ -945,7 +960,7 @@ bool sparse_matrix::shorten_active_matrix(unsigned row, eta_matrix * for (auto & iv : row_values) { const col_header& ch = m_columns[iv.m_index]; int cnz = static_cast(ch.m_values.size()) - ch.m_shortened_markovitz - 1; - lean_assert(cnz >= 0); + SASSERT(cnz >= 0); m_pivot_queue.enqueue(row, iv.m_index, rnz * cnz); } } @@ -961,25 +976,25 @@ unsigned sparse_matrix::pivot_score_without_shortened_counters(unsigned i, if (adjust_row_inverse(iv.m_index) < k) cnz--; } - lean_assert(cnz > 0); + SASSERT(cnz > 0); return m_rows[i].m_values.size() * (cnz - 1); } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool sparse_matrix::can_improve_score_for_row(unsigned row, unsigned score, T const & c_partial_pivoting, unsigned k) { unsigned arow = adjust_row(row); auto & row_vals = m_rows[arow].m_values; auto & begin_iv = row_vals[0]; T row_max = abs(begin_iv.m_value); - lean_assert(adjust_column_inverse(begin_iv.m_index) >= k); + SASSERT(adjust_column_inverse(begin_iv.m_index) >= k); if (pivot_score_without_shortened_counters(arow, begin_iv.m_index, k) < score) { print_active_matrix(k); return true; } for (unsigned jj = 1; jj < row_vals.size(); jj++) { auto & iv = row_vals[jj]; - lean_assert(adjust_column_inverse(iv.m_index) >= k); - lean_assert(abs(iv.m_value) <= row_max); + SASSERT(adjust_column_inverse(iv.m_index) >= k); + SASSERT(abs(iv.m_value) <= row_max); if (c_partial_pivoting * abs(iv.m_value) < row_max) continue; if (pivot_score_without_shortened_counters(arow, iv.m_index, k) < score) { print_active_matrix(k); @@ -993,7 +1008,7 @@ template bool sparse_matrix::really_best_pivot(unsigned i, unsigned j, T const & c_partial_pivoting, unsigned k) { unsigned queue_pivot_score = pivot_score_without_shortened_counters(i, j, k); for (unsigned ii = k; ii < dimension(); ii++) { - lean_assert(!can_improve_score_for_row(ii, queue_pivot_score, c_partial_pivoting, k)); + SASSERT(!can_improve_score_for_row(ii, queue_pivot_score, c_partial_pivoting, k)); } return true; } @@ -1026,7 +1041,7 @@ template bool sparse_matrix::pivot_queue_is_correct_for_row(unsigned i, unsigned k) { unsigned arow = adjust_row(i); for (auto & iv : m_rows[arow].m_values) { - lean_assert(pivot_score_without_shortened_counters(arow, iv.m_index, k + 1) == + SASSERT(pivot_score_without_shortened_counters(arow, iv.m_index, k + 1) == m_pivot_queue.get_priority(arow, iv.m_index)); } return true; @@ -1035,8 +1050,8 @@ bool sparse_matrix::pivot_queue_is_correct_for_row(unsigned i, unsigned k) template bool sparse_matrix::pivot_queue_is_correct_after_pivoting(int k) { for (unsigned i = k + 1; i < dimension(); i++ ) - lean_assert(pivot_queue_is_correct_for_row(i, k)); - lean_assert(m_pivot_queue.is_correct()); + SASSERT(pivot_queue_is_correct_for_row(i, k)); + SASSERT(m_pivot_queue.is_correct()); return true; } #endif @@ -1052,10 +1067,10 @@ bool sparse_matrix::get_pivot_for_column(unsigned &i, unsigned &j, int c_p if (j_inv < k) continue; int _small = elem_is_too_small(i, j, c_partial_pivoting); if (!_small) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // if (!really_best_pivot(i, j, c_partial_pivoting, k)) { // print_active_matrix(k); - // lean_assert(false); + // SASSERT(false); // } #endif recover_pivot_queue(pivots_candidates_that_are_too_small); @@ -1088,7 +1103,7 @@ bool sparse_matrix::shorten_columns_by_pivot_row(unsigned i, unsigned pivo for (indexed_value & iv : row_chunk) { unsigned j = iv.m_index; if (j == pivot_column) { - lean_assert(!col_is_active(j)); + SASSERT(!col_is_active(j)); continue; } m_columns[j].shorten_markovich_by_one(); @@ -1121,7 +1136,7 @@ bool sparse_matrix::fill_eta_matrix(unsigned j, eta_matrix ** eta) { return true; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG *eta = new eta_matrix(j, dimension()); #else *eta = new eta_matrix(j); @@ -1146,16 +1161,16 @@ bool sparse_matrix::fill_eta_matrix(unsigned j, eta_matrix ** eta) { (*eta)->divide_by_diagonal_element(); return true; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool sparse_matrix::is_upper_triangular_and_maximums_are_set_correctly_in_rows(lp_settings & settings) const { for (unsigned i = 0; i < dimension(); i++) { vector> const & row_chunk = get_row_values(i); - lean_assert(row_chunk.size()); + SASSERT(row_chunk.size()); T const & max = abs(row_chunk[0].m_value); unsigned ai = adjust_row_inverse(i); for (auto & iv : row_chunk) { - lean_assert(abs(iv.m_value) <= max); + SASSERT(abs(iv.m_value) <= max); unsigned aj = adjust_column_inverse(iv.m_index); if (!(ai <= aj || numeric_traits::is_zero(iv.m_value))) return false; @@ -1193,18 +1208,18 @@ void sparse_matrix::check_column_vs_rows(unsigned col) { indexed_value & row_iv = column_iv_other(column_iv); if (row_iv.m_index != col) { // std::cout << "m_other in row does not belong to column " << col << ", but to column " << row_iv.m_index << std::endl; - lean_assert(false); + SASSERT(false); } if (& row_iv_other(row_iv) != &column_iv) { // std::cout << "row and col do not point to each other" << std::endl; - lean_assert(false); + SASSERT(false); } if (row_iv.m_value != column_iv.m_value) { // std::cout << "the data from col " << col << " for row " << column_iv.m_index << " is different in the column " << std::endl; // std::cout << "in the col it is " << column_iv.m_value << ", but in the row it is " << row_iv.m_value << std::endl; - lean_assert(false); + SASSERT(false); } } } @@ -1217,18 +1232,18 @@ void sparse_matrix::check_row_vs_columns(unsigned row) { if (column_iv.m_index != row) { // std::cout << "col_iv does not point to correct row " << row << " but to " << column_iv.m_index << std::endl; - lean_assert(false); + SASSERT(false); } if (& row_iv != & column_iv_other(column_iv)) { // std::cout << "row and col do not point to each other" << std::endl; - lean_assert(false); + SASSERT(false); } if (row_iv.m_value != column_iv.m_value) { // std::cout << "the data from col " << column_iv.m_index << " for row " << row << " is different in the column " << std::endl; // std::cout << "in the col it is " << column_iv.m_value << ", but in the row it is " << row_iv.m_value << std::endl; - lean_assert(false); + SASSERT(false); } } } diff --git a/src/util/lp/sparse_matrix_instances.cpp b/src/util/lp/sparse_matrix_instances.cpp index c06fcbf05..64a555bb2 100644 --- a/src/util/lp/sparse_matrix_instances.cpp +++ b/src/util/lp/sparse_matrix_instances.cpp @@ -1,14 +1,29 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/lp_settings.h" #include "util/lp/lu.h" #include "util/lp/sparse_matrix.hpp" #include "util/lp/dense_matrix.h" -namespace lean { +namespace lp { template double sparse_matrix::dot_product_with_row(unsigned int, vector const&) const; template void sparse_matrix::add_new_element(unsigned int, unsigned int, const double&); template void sparse_matrix::divide_row_by_constant(unsigned int, const double&, lp_settings&); @@ -65,37 +80,37 @@ template void sparse_matrix::double_solve_U_y(indexed_ve template void sparse_matrix::double_solve_U_y(indexed_vector&, const lp_settings&); template void sparse_matrix>::double_solve_U_y(indexed_vector&, const lp_settings&); template void sparse_matrix >::double_solve_U_y >(indexed_vector>&, const lp_settings&); -template void lean::sparse_matrix::solve_U_y_indexed_only(lean::indexed_vector&, const lp_settings&, vector &); -template void lean::sparse_matrix::solve_U_y_indexed_only(lean::indexed_vector&, const lp_settings &, vector &); -#ifdef LEAN_DEBUG +template void lp::sparse_matrix::solve_U_y_indexed_only(lp::indexed_vector&, const lp_settings&, vector &); +template void lp::sparse_matrix::solve_U_y_indexed_only(lp::indexed_vector&, const lp_settings &, vector &); +#ifdef Z3DEBUG template bool sparse_matrix::is_upper_triangular_and_maximums_are_set_correctly_in_rows(lp_settings&) const; template bool sparse_matrix::is_upper_triangular_and_maximums_are_set_correctly_in_rows(lp_settings&) const; template bool sparse_matrix >::is_upper_triangular_and_maximums_are_set_correctly_in_rows(lp_settings&) const; #endif } -template void lean::sparse_matrix >::solve_U_y_indexed_only(lean::indexed_vector&, const lp_settings &, vector &); -template void lean::sparse_matrix::solve_U_y(vector&); -template void lean::sparse_matrix::double_solve_U_y(vector&); -template void lean::sparse_matrix::solve_U_y(vector&); -template void lean::sparse_matrix::double_solve_U_y(vector&); -template void lean::sparse_matrix >::solve_U_y >(vector >&); -template void lean::sparse_matrix >::double_solve_U_y >(vector >&); -template void lean::sparse_matrix::find_error_in_solution_U_y_indexed(lean::indexed_vector&, lean::indexed_vector&, const vector &); -template double lean::sparse_matrix::dot_product_with_row(unsigned int, lean::indexed_vector const&) const; -template void lean::sparse_matrix::find_error_in_solution_U_y_indexed(lean::indexed_vector&, lean::indexed_vector&, const vector &); -template lean::mpq lean::sparse_matrix::dot_product_with_row(unsigned int, lean::indexed_vector const&) const; -template void lean::sparse_matrix >::find_error_in_solution_U_y_indexed(lean::indexed_vector&, lean::indexed_vector&, const vector &); -template lean::mpq lean::sparse_matrix >::dot_product_with_row(unsigned int, lean::indexed_vector const&) const; -template void lean::sparse_matrix >::find_error_in_solution_U_y_indexed >(lean::indexed_vector >&, lean::indexed_vector >&, const vector &); -template lean::numeric_pair lean::sparse_matrix >::dot_product_with_row >(unsigned int, lean::indexed_vector > const&) const; -template void lean::sparse_matrix::extend_and_sort_active_rows(vector const&, vector&); +template void lp::sparse_matrix >::solve_U_y_indexed_only(lp::indexed_vector&, const lp_settings &, vector &); +template void lp::sparse_matrix::solve_U_y(vector&); +template void lp::sparse_matrix::double_solve_U_y(vector&); +template void lp::sparse_matrix::solve_U_y(vector&); +template void lp::sparse_matrix::double_solve_U_y(vector&); +template void lp::sparse_matrix >::solve_U_y >(vector >&); +template void lp::sparse_matrix >::double_solve_U_y >(vector >&); +template void lp::sparse_matrix::find_error_in_solution_U_y_indexed(lp::indexed_vector&, lp::indexed_vector&, const vector &); +template double lp::sparse_matrix::dot_product_with_row(unsigned int, lp::indexed_vector const&) const; +template void lp::sparse_matrix::find_error_in_solution_U_y_indexed(lp::indexed_vector&, lp::indexed_vector&, const vector &); +template lp::mpq lp::sparse_matrix::dot_product_with_row(unsigned int, lp::indexed_vector const&) const; +template void lp::sparse_matrix >::find_error_in_solution_U_y_indexed(lp::indexed_vector&, lp::indexed_vector&, const vector &); +template lp::mpq lp::sparse_matrix >::dot_product_with_row(unsigned int, lp::indexed_vector const&) const; +template void lp::sparse_matrix >::find_error_in_solution_U_y_indexed >(lp::indexed_vector >&, lp::indexed_vector >&, const vector &); +template lp::numeric_pair lp::sparse_matrix >::dot_product_with_row >(unsigned int, lp::indexed_vector > const&) const; +template void lp::sparse_matrix::extend_and_sort_active_rows(vector const&, vector&); -template void lean::sparse_matrix >::extend_and_sort_active_rows(vector const&, vector&); +template void lp::sparse_matrix >::extend_and_sort_active_rows(vector const&, vector&); -template void lean::sparse_matrix >::solve_U_y(vector&); -template void lean::sparse_matrix >::double_solve_U_y(vector&); -template void lean::sparse_matrix< lean::mpq,lean::numeric_pair< lean::mpq> >::set(unsigned int,unsigned int, lean::mpq); -template void lean::sparse_matrix::solve_y_U_indexed(lean::indexed_vector&, const lp_settings & ); -template void lean::sparse_matrix::solve_y_U_indexed(lean::indexed_vector&, const lp_settings &); -template void lean::sparse_matrix >::solve_y_U_indexed(lean::indexed_vector&, const lp_settings &); +template void lp::sparse_matrix >::solve_U_y(vector&); +template void lp::sparse_matrix >::double_solve_U_y(vector&); +template void lp::sparse_matrix< lp::mpq,lp::numeric_pair< lp::mpq> >::set(unsigned int,unsigned int, lp::mpq); +template void lp::sparse_matrix::solve_y_U_indexed(lp::indexed_vector&, const lp_settings & ); +template void lp::sparse_matrix::solve_y_U_indexed(lp::indexed_vector&, const lp_settings &); +template void lp::sparse_matrix >::solve_y_U_indexed(lp::indexed_vector&, const lp_settings &); diff --git a/src/util/lp/sparse_vector.h b/src/util/lp/sparse_vector.h index 975cb7f28..51639674c 100644 --- a/src/util/lp/sparse_vector.h +++ b/src/util/lp/sparse_vector.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -9,7 +24,7 @@ #include "util/debug.h" #include "util/lp/lp_utils.h" #include "util/lp/lp_settings.h" -namespace lean { +namespace lp { template class sparse_vector { @@ -18,7 +33,7 @@ public: void push_back(unsigned index, T val) { m_data.push_back(std::make_pair(index, val)); } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG T operator[] (unsigned i) const { for (auto &t : m_data) { if (t.first == i) return t.second; @@ -27,7 +42,7 @@ public: } #endif void divide(T const & a) { - lean_assert(!lp_settings::is_eps_small_general(a, 1e-12)); + SASSERT(!lp_settings::is_eps_small_general(a, 1e-12)); for (auto & t : m_data) { t.second /= a; } } diff --git a/src/util/lp/square_dense_submatrix.h b/src/util/lp/square_dense_submatrix.h index 019497aa5..3e88e8114 100644 --- a/src/util/lp/square_dense_submatrix.h +++ b/src/util/lp/square_dense_submatrix.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -20,7 +35,7 @@ #include "util/lp/eta_matrix.h" #include "util/lp/binary_heap_upair_queue.h" #include "util/lp/sparse_matrix.h" -namespace lean { +namespace lp { template class square_dense_submatrix : public tail_matrix { // the submatrix uses the permutations of the parent matrix to access the elements @@ -30,11 +45,11 @@ class square_dense_submatrix : public tail_matrix { ref(unsigned i, square_dense_submatrix & s) : m_i_offset((i - s.m_index_start) * s.m_dim), m_s(s){} T & operator[] (unsigned j) { - lean_assert(j >= m_s.m_index_start); + SASSERT(j >= m_s.m_index_start); return m_s.m_v[m_i_offset + m_s.adjust_column(j) - m_s.m_index_start]; } const T & operator[] (unsigned j) const { - lean_assert(j >= m_s.m_index_start); + SASSERT(j >= m_s.m_index_start); return m_s.m_v[m_i_offset + m_s.adjust_column(j) - m_s.m_index_start]; } }; @@ -58,8 +73,8 @@ public: bool is_dense() const { return true; } ref operator[] (unsigned i) { - lean_assert(i >= m_index_start); - lean_assert(i < m_parent->dimension()); + SASSERT(i >= m_index_start); + SASSERT(i < m_parent->dimension()); return ref(i, *this); } @@ -148,7 +163,7 @@ public: } } } - lean_assert(wcopy.is_OK()); + SASSERT(wcopy.is_OK()); apply_from_right(w.m_data); w.m_index.clear(); if (numeric_traits::precise()) { @@ -167,11 +182,11 @@ public: } } #else - lean_assert(w.is_OK()); - lean_assert(m_work_vector.is_OK()); + SASSERT(w.is_OK()); + SASSERT(m_work_vector.is_OK()); m_work_vector.resize(w.data_size()); m_work_vector.clear(); - lean_assert(m_work_vector.is_OK()); + SASSERT(m_work_vector.is_OK()); unsigned end = m_index_start + m_dim; for (unsigned k : w.m_index) { // find j such that k = adjust_row_inverse(j) @@ -188,7 +203,7 @@ public: } } m_work_vector.clean_up(); - lean_assert(m_work_vector.is_OK()); + SASSERT(m_work_vector.is_OK()); w = m_work_vector; #endif } @@ -198,7 +213,7 @@ public: void apply_from_right(vector & w); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG T get_elem (unsigned i, unsigned j) const; unsigned row_count() const { return m_parent->row_count();} unsigned column_count() const { return row_count();} diff --git a/src/util/lp/square_dense_submatrix.hpp b/src/util/lp/square_dense_submatrix.hpp index 365c9d7f0..cbf69c5dd 100644 --- a/src/util/lp/square_dense_submatrix.hpp +++ b/src/util/lp/square_dense_submatrix.hpp @@ -1,10 +1,25 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include "util/lp/square_dense_submatrix.h" -namespace lean { +namespace lp { template square_dense_submatrix::square_dense_submatrix (sparse_matrix *parent_matrix, unsigned index_start) : m_index_start(index_start), @@ -18,7 +33,7 @@ square_dense_submatrix::square_dense_submatrix (sparse_matrix *paren unsigned row = parent_matrix->adjust_row(i); for (auto & iv : parent_matrix->get_row_values(row)) { unsigned j = parent_matrix->adjust_column_inverse(iv.m_index); - lean_assert(j>= m_index_start); + SASSERT(j>= m_index_start); m_v[row_offset + j] = iv.m_value; } row_offset += m_dim; @@ -43,7 +58,7 @@ template void square_dense_submatrix::init(sparse template int square_dense_submatrix::find_pivot_column_in_row(unsigned i) const { int j = -1; T max = zero_of_type(); - lean_assert(i >= m_index_start); + SASSERT(i >= m_index_start); unsigned row_start = (i - m_index_start) * m_dim; for (unsigned k = i; k < m_parent->dimension(); k++) { unsigned col = adjust_column(k); // this is where the column is in the row @@ -64,14 +79,14 @@ template void square_dense_submatrix::pivot(un } template void square_dense_submatrix::pivot_row_to_row(unsigned i, unsigned row, lp_settings & settings) { - lean_assert(i < row); + SASSERT(i < row); unsigned pj = adjust_column(i); // the pivot column unsigned pjd = pj - m_index_start; unsigned pivot_row_offset = (i-m_index_start)*m_dim; T pivot = m_v[pivot_row_offset + pjd]; unsigned row_offset= (row-m_index_start)*m_dim; T m = m_v[row_offset + pjd]; - lean_assert(!is_zero(pivot)); + SASSERT(!is_zero(pivot)); m_v[row_offset + pjd] = -m * pivot; // creating L matrix for (unsigned j = m_index_start; j < m_parent->dimension(); j++) { if (j == pj) { @@ -94,7 +109,7 @@ template void square_dense_submatrix::divide_r unsigned pj = adjust_column(i); // the pivot column unsigned irow_offset = (i - m_index_start) * m_dim; T pivot = m_v[irow_offset + pj - m_index_start]; - lean_assert(!is_zero(pivot)); + SASSERT(!is_zero(pivot)); for (unsigned k = m_index_start; k < m_parent->dimension(); k++) { if (k == pj){ m_v[irow_offset++] = one_of_type() / pivot; // creating the L matrix diagonal @@ -158,7 +173,7 @@ template void square_dense_submatrix::push_new template template L square_dense_submatrix::row_by_vector_product(unsigned i, const vector & v) { - lean_assert(i >= m_index_start); + SASSERT(i >= m_index_start); unsigned row_in_subm = i - m_index_start; unsigned row_offset = row_in_subm * m_dim; @@ -171,7 +186,7 @@ L square_dense_submatrix::row_by_vector_product(unsigned i, const vector template L square_dense_submatrix::column_by_vector_product(unsigned j, const vector & v) { - lean_assert(j >= m_index_start); + SASSERT(j >= m_index_start); unsigned offset = j - m_index_start; L r = zero_of_type(); @@ -182,7 +197,7 @@ L square_dense_submatrix::column_by_vector_product(unsigned j, const vecto template template L square_dense_submatrix::row_by_indexed_vector_product(unsigned i, const indexed_vector & v) { - lean_assert(i >= m_index_start); + SASSERT(i >= m_index_start); unsigned row_in_subm = i - m_index_start; unsigned row_offset = row_in_subm * m_dim; @@ -194,7 +209,7 @@ L square_dense_submatrix::row_by_indexed_vector_product(unsigned i, const template template void square_dense_submatrix::apply_from_left_local(indexed_vector & w, lp_settings & settings) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // vector deb_w(w.m_data.size()); // for (unsigned i = 0; i < w.m_data.size(); i++) @@ -246,11 +261,11 @@ void square_dense_submatrix::apply_from_left_local(indexed_vector & w, w.m_data[i] = v; } #endif -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // cout << "w final" << endl; // print_vector(w.m_data); - // lean_assert(vectors_are_equal(deb_w, w.m_data)); - // lean_assert(w.is_OK()); + // SASSERT(vectors_are_equal(deb_w, w.m_data)); + // SASSERT(w.is_OK()); #endif } @@ -277,19 +292,19 @@ void square_dense_submatrix::apply_from_left_to_vector(vector & w) { for (unsigned i = 0; i < m_parent->dimension(); i++) { w[i] = t[i]; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // cout << "w final" << endl; // print_vector(w.m_data); - // lean_assert(vectors_are_equal(deb_w, w)); + // SASSERT(vectors_are_equal(deb_w, w)); #endif } template bool square_dense_submatrix::is_L_matrix() const { -#ifdef LEAN_DEBUG - lean_assert(m_row_permutation.is_identity()); +#ifdef Z3DEBUG + SASSERT(m_row_permutation.is_identity()); for (unsigned i = 0; i < m_parent->dimension(); i++) { if (i < m_index_start) { - lean_assert(m_column_permutation[i] == i); + SASSERT(m_column_permutation[i] == i); continue; } unsigned row_offs = (i-m_index_start)*m_dim; @@ -297,9 +312,9 @@ template bool square_dense_submatrix::is_L_mat unsigned j = m_index_start + k; unsigned jex = adjust_column_inverse(j); if (jex > i) { - lean_assert(is_zero(m_v[row_offs + k])); + SASSERT(is_zero(m_v[row_offs + k])); } else if (jex == i) { - lean_assert(!is_zero(m_v[row_offs + k])); + SASSERT(!is_zero(m_v[row_offs + k])); } } } @@ -308,7 +323,7 @@ template bool square_dense_submatrix::is_L_mat } template void square_dense_submatrix::apply_from_right(vector & w) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG // dense_matrix deb(*this); // vector deb_w(w); // deb.apply_from_right(deb_w); @@ -326,15 +341,15 @@ template void square_dense_submatrix::apply_from_ t[adjust_column_inverse(j)] = column_by_vector_product(j, w); } w = t; -#ifdef LEAN_DEBUG - // lean_assert(vector_are_equal(deb_w, w)); +#ifdef Z3DEBUG + // SASSERT(vector_are_equal(deb_w, w)); #endif } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template T square_dense_submatrix::get_elem (unsigned i, unsigned j) const { i = adjust_row(i); diff --git a/src/util/lp/square_dense_submatrix_instances.cpp b/src/util/lp/square_dense_submatrix_instances.cpp index 7d45aaaa1..e1df0036e 100644 --- a/src/util/lp/square_dense_submatrix_instances.cpp +++ b/src/util/lp/square_dense_submatrix_instances.cpp @@ -1,33 +1,48 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include "util/vector.h" #include "util/lp/square_dense_submatrix.hpp" -template void lean::square_dense_submatrix::init(lean::sparse_matrix*, unsigned int); -template lean::square_dense_submatrix::square_dense_submatrix(lean::sparse_matrix*, unsigned int); -template void lean::square_dense_submatrix::update_parent_matrix(lean::lp_settings&); -template bool lean::square_dense_submatrix::is_L_matrix() const; -template void lean::square_dense_submatrix::conjugate_by_permutation(lean::permutation_matrix&); -template int lean::square_dense_submatrix::find_pivot_column_in_row(unsigned int) const; -template void lean::square_dense_submatrix::pivot(unsigned int, lean::lp_settings&); -template lean::square_dense_submatrix >::square_dense_submatrix(lean::sparse_matrix >*, unsigned int); -template void lean::square_dense_submatrix >::update_parent_matrix(lean::lp_settings&); -template bool lean::square_dense_submatrix >::is_L_matrix() const; -template void lean::square_dense_submatrix >::conjugate_by_permutation(lean::permutation_matrix >&); -template int lean::square_dense_submatrix >::find_pivot_column_in_row(unsigned int) const; -template void lean::square_dense_submatrix >::pivot(unsigned int, lean::lp_settings&); -#ifdef LEAN_DEBUG -template double lean::square_dense_submatrix::get_elem(unsigned int, unsigned int) const; +template void lp::square_dense_submatrix::init(lp::sparse_matrix*, unsigned int); +template lp::square_dense_submatrix::square_dense_submatrix(lp::sparse_matrix*, unsigned int); +template void lp::square_dense_submatrix::update_parent_matrix(lp::lp_settings&); +template bool lp::square_dense_submatrix::is_L_matrix() const; +template void lp::square_dense_submatrix::conjugate_by_permutation(lp::permutation_matrix&); +template int lp::square_dense_submatrix::find_pivot_column_in_row(unsigned int) const; +template void lp::square_dense_submatrix::pivot(unsigned int, lp::lp_settings&); +template lp::square_dense_submatrix >::square_dense_submatrix(lp::sparse_matrix >*, unsigned int); +template void lp::square_dense_submatrix >::update_parent_matrix(lp::lp_settings&); +template bool lp::square_dense_submatrix >::is_L_matrix() const; +template void lp::square_dense_submatrix >::conjugate_by_permutation(lp::permutation_matrix >&); +template int lp::square_dense_submatrix >::find_pivot_column_in_row(unsigned int) const; +template void lp::square_dense_submatrix >::pivot(unsigned int, lp::lp_settings&); +#ifdef Z3DEBUG +template double lp::square_dense_submatrix::get_elem(unsigned int, unsigned int) const; #endif -template void lean::square_dense_submatrix::apply_from_right(vector&); +template void lp::square_dense_submatrix::apply_from_right(vector&); -template void lean::square_dense_submatrix::apply_from_left_local(lean::indexed_vector&, lean::lp_settings&); -template void lean::square_dense_submatrix::apply_from_left_to_vector(vector&); -template lean::square_dense_submatrix::square_dense_submatrix(lean::sparse_matrix*, unsigned int); -template void lean::square_dense_submatrix::update_parent_matrix(lean::lp_settings&); -template bool lean::square_dense_submatrix::is_L_matrix() const; -template void lean::square_dense_submatrix::conjugate_by_permutation(lean::permutation_matrix&); -template int lean::square_dense_submatrix::find_pivot_column_in_row(unsigned int) const; -template void lean::square_dense_submatrix::pivot(unsigned int, lean::lp_settings&); +template void lp::square_dense_submatrix::apply_from_left_local(lp::indexed_vector&, lp::lp_settings&); +template void lp::square_dense_submatrix::apply_from_left_to_vector(vector&); +template lp::square_dense_submatrix::square_dense_submatrix(lp::sparse_matrix*, unsigned int); +template void lp::square_dense_submatrix::update_parent_matrix(lp::lp_settings&); +template bool lp::square_dense_submatrix::is_L_matrix() const; +template void lp::square_dense_submatrix::conjugate_by_permutation(lp::permutation_matrix&); +template int lp::square_dense_submatrix::find_pivot_column_in_row(unsigned int) const; +template void lp::square_dense_submatrix::pivot(unsigned int, lp::lp_settings&); diff --git a/src/util/lp/stacked_map.h b/src/util/lp/stacked_map.h index 4692540dd..1bcad5649 100644 --- a/src/util/lp/stacked_map.h +++ b/src/util/lp/stacked_map.h @@ -1,14 +1,29 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once // this class implements a map with some stack functionality #include #include #include -namespace lean { +namespace lp { template second; } }; @@ -73,7 +88,7 @@ public: const B & operator[]( const A & a) const { auto it = m_map.find(a); if (it == m_map.end()) { - lean_assert(false); + SASSERT(false); } return it->second; @@ -128,7 +143,7 @@ public: for (auto & t: d.m_original_changed) { m_map[t.first] = t.second; } - // lean_assert(d.m_deb_copy == m_map); + // SASSERT(d.m_deb_copy == m_map); m_stack.pop(); } } @@ -142,7 +157,7 @@ public: delta & d = m_stack.top(); auto it = m_map.find(key); if (it == m_map.end()) { - lean_assert(d.m_new.find(key) == d.m_new.end()); + SASSERT(d.m_new.find(key) == d.m_new.end()); return; } auto &orig_changed = d.m_original_changed; @@ -151,7 +166,7 @@ public: if (orig_changed.find(key) == orig_changed.end()) orig_changed.emplace(it->first, it->second); // need to restore } else { // k is new - lean_assert(orig_changed.find(key) == orig_changed.end()); + SASSERT(orig_changed.find(key) == orig_changed.end()); d.m_new.erase(nit); } diff --git a/src/util/lp/stacked_unordered_set.h b/src/util/lp/stacked_unordered_set.h index 69c4cf03b..6e313e6c0 100644 --- a/src/util/lp/stacked_unordered_set.h +++ b/src/util/lp/stacked_unordered_set.h @@ -1,14 +1,29 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once // this class implements an unordered_set with some stack functionality #include #include #include -namespace lean { +namespace lp { template , @@ -81,7 +96,7 @@ public: for (auto & t : d.m_erased) { m_set.insert(t); } - lean_assert(d.m_deb_copy == m_set); + SASSERT(d.m_deb_copy == m_set); m_stack.pop(); } } diff --git a/src/util/lp/stacked_value.h b/src/util/lp/stacked_value.h index 2a1e85be7..5ef7ea0c8 100644 --- a/src/util/lp/stacked_value.h +++ b/src/util/lp/stacked_value.h @@ -1,12 +1,27 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once // add to value the stack semantics #include -namespace lean { +namespace lp { template class stacked_value { T m_value; std::stack m_stack; diff --git a/src/util/lp/stacked_vector.h b/src/util/lp/stacked_vector.h index 21202b7b8..0f66e93f3 100644 --- a/src/util/lp/stacked_vector.h +++ b/src/util/lp/stacked_vector.h @@ -7,7 +7,7 @@ Author: Lev Nachmanson #include #include #include "util/vector.h" -namespace lean { +namespace lp { template < typename B> class stacked_vector { vector m_stack_of_vector_sizes; vector m_stack_of_change_sizes; @@ -19,7 +19,7 @@ public: unsigned m_i; public: ref(stacked_vector &m, unsigned key) :m_vec(m), m_i(key) { - lean_assert(key < m.size()); + SASSERT(key < m.size()); } ref & operator=(const B & b) { m_vec.emplace_replace(m_i, b); @@ -40,7 +40,7 @@ public: unsigned m_i; public: ref_const(const stacked_vector &m, unsigned key) :m_vec(m), m_i(key) { - lean_assert(key < m.size()); + SASSERT(key < m.size()); } operator const B&() const { @@ -68,7 +68,7 @@ public: /* const B & operator[](unsigned a) const { - lean_assert(a < m_vector.size()); + SASSERT(a < m_vector.size()); return m_vector[a]; } */ @@ -88,7 +88,7 @@ public: template void pop_tail(vector & v, unsigned k) { - lean_assert(v.size() >= k); + SASSERT(v.size() >= k); v.resize(v.size() - k); } @@ -98,8 +98,8 @@ public: } void pop(unsigned k) { - lean_assert(m_stack_of_vector_sizes.size() >= k); - lean_assert(k > 0); + SASSERT(m_stack_of_vector_sizes.size() >= k); + SASSERT(k > 0); resize(m_vector, m_stack_of_vector_sizes[m_stack_of_vector_sizes.size() - k]); pop_tail(m_stack_of_vector_sizes, k); unsigned first_change = m_stack_of_change_sizes[m_stack_of_change_sizes.size() - k]; @@ -119,15 +119,15 @@ public: return; delta & d = m_stack.back(); - lean_assert(m_vector.size() >= d.m_size); + SASSERT(m_vector.size() >= d.m_size); while (m_vector.size() > d.m_size) m_vector.pop_back(); for (auto & t : d.m_original_changed) { - lean_assert(t.first < m_vector.size()); + SASSERT(t.first < m_vector.size()); m_vector[t.first] = t.second; } - // lean_assert(d.m_deb_copy == m_vector); + // SASSERT(d.m_deb_copy == m_vector); m_stack.pop_back();*/ } @@ -157,7 +157,7 @@ public: } unsigned peek_size(unsigned k) const { - lean_assert(k > 0 && k <= m_stack_of_vector_sizes.size()); + SASSERT(k > 0 && k <= m_stack_of_vector_sizes.size()); return m_stack_of_vector_sizes[m_stack_of_vector_sizes.size() - k]; } diff --git a/src/util/lp/static_matrix.h b/src/util/lp/static_matrix.h index d027c105f..29b7ed646 100644 --- a/src/util/lp/static_matrix.h +++ b/src/util/lp/static_matrix.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -13,7 +28,7 @@ #include "util/lp/permutation_matrix.h" #include "util/lp/linear_combination_iterator.h" #include -namespace lean { +namespace lp { struct column_cell { unsigned m_i; // points to the row @@ -37,7 +52,7 @@ struct row_cell { // each assignment for this matrix should be issued only once!!! template class static_matrix -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG : public matrix #endif { @@ -130,7 +145,7 @@ public: } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void regen_domain(); #endif @@ -163,7 +178,7 @@ public: T get_min_abs_in_column(unsigned column) const; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void check_consistency(); #endif @@ -196,14 +211,14 @@ public: void clean_row_work_vector(unsigned i); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned get_number_of_rows() const { return row_count(); } unsigned get_number_of_columns() const { return column_count(); } virtual void set_number_of_rows(unsigned /*m*/) { } virtual void set_number_of_columns(unsigned /*n*/) { } #endif - T get_max_val_in_row(unsigned /* i */) const { lean_unreachable(); } + T get_max_val_in_row(unsigned /* i */) const { SASSERT(false); } T get_balance() const; @@ -219,7 +234,7 @@ public: for (auto & c : row) { unsigned j = c.m_j; auto & col = m_columns[j]; - lean_assert(col[col.size() - 1].m_i == m_rows.size() -1 ); // todo : start here!!!! + SASSERT(col[col.size() - 1].m_i == m_rows.size() -1 ); // todo : start here!!!! col.pop_back(); } } @@ -227,7 +242,7 @@ public: void pop(unsigned k) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG std::set> pairs_to_remove_from_domain; #endif @@ -246,7 +261,7 @@ public: m_columns.pop_back(); // delete the last column m_stack.pop(); } - lean_assert(is_correct()); + SASSERT(is_correct()); } void multiply_row(unsigned row, T const & alpha) { @@ -262,7 +277,7 @@ public: } T dot_product_with_column(const vector & y, unsigned j) const { - lean_assert(j < column_count()); + SASSERT(j < column_count()); T ret = numeric_traits::zero(); for (auto & it : m_columns[j]) { ret += y[it.m_i] * get_val(it); // get_value_of_column_cell(it); @@ -281,20 +296,20 @@ public: // now fix the columns for (auto & rc : m_rows[i]) { column_cell & cc = m_columns[rc.m_j][rc.m_offset]; - lean_assert(cc.m_i == ii); + SASSERT(cc.m_i == ii); cc.m_i = i; } for (auto & rc : m_rows[ii]) { column_cell & cc = m_columns[rc.m_j][rc.m_offset]; - lean_assert(cc.m_i == i); + SASSERT(cc.m_i == i); cc.m_i = ii; } } void fill_last_row_with_pivoting(linear_combination_iterator & it, const vector & basis_heading) { - lean_assert(numeric_traits::precise()); - lean_assert(row_count() > 0); + SASSERT(numeric_traits::precise()); + SASSERT(row_count() > 0); m_work_vector.resize(column_count()); T a; unsigned j; @@ -332,13 +347,13 @@ public: alpha = zero_of_type(); m_work_vector.erase_from_index(j); } - lean_assert(m_work_vector.is_OK()); + SASSERT(m_work_vector.is_OK()); unsigned last_row = row_count() - 1; for (unsigned j : m_work_vector.m_index) { set (last_row, j, m_work_vector.m_data[j]); } - lean_assert(column_count() > 0); + SASSERT(column_count() > 0); set(last_row, column_count() - 1, one_of_type()); } @@ -354,7 +369,7 @@ public: template L dot_product_with_row(unsigned row, const vector & w) const { L ret = zero_of_type(); - lean_assert(row < m_rows.size()); + SASSERT(row < m_rows.size()); for (auto & it : m_rows[row]) { ret += w[it.m_j] * it.get_val(); } diff --git a/src/util/lp/static_matrix.hpp b/src/util/lp/static_matrix.hpp index fb12da8c4..d8681ff93 100644 --- a/src/util/lp/static_matrix.hpp +++ b/src/util/lp/static_matrix.hpp @@ -1,16 +1,31 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include "util/vector.h" #include #include #include "util/lp/static_matrix.h" -namespace lean { +namespace lp { // each assignment for this matrix should be issued only once!!! template void static_matrix::init_row_columns(unsigned m, unsigned n) { - lean_assert(m_rows.size() == 0 && m_columns.size() == 0); + SASSERT(m_rows.size() == 0 && m_columns.size() == 0); for (unsigned i = 0; i < m; i++){ m_rows.push_back(row_strip()); } @@ -30,23 +45,23 @@ template void static_matrix::scan_row_ii_to_offse template bool static_matrix::pivot_row_to_row_given_cell(unsigned i, column_cell & c, unsigned pivot_col) { unsigned ii = c.m_i; - lean_assert(i < row_count() && ii < column_count()); - lean_assert(i != ii); + SASSERT(i < row_count() && ii < column_count()); + SASSERT(i != ii); m_became_zeros.reset(); T alpha = -get_val(c); - lean_assert(!is_zero(alpha)); + SASSERT(!is_zero(alpha)); auto & ii_row_vals = m_rows[ii]; remove_element(ii_row_vals, ii_row_vals[c.m_offset]); scan_row_ii_to_offset_vector(ii); - lean_assert(!is_zero(alpha)); + SASSERT(!is_zero(alpha)); unsigned prev_size_ii = ii_row_vals.size(); // run over the pivot row and update row ii for (const auto & iv : m_rows[i]) { unsigned j = iv.m_j; if (j == pivot_col) continue; T alv = alpha * iv.m_value; - lean_assert(!is_zero(iv.m_value)); + SASSERT(!is_zero(iv.m_value)); int j_offs = m_vector_of_row_offsets[j]; if (j_offs == -1) { // it is a new element add_new_element(ii, j, alv); @@ -104,9 +119,9 @@ template void static_matrix::init_empty_matrix } template unsigned static_matrix::lowest_row_in_column(unsigned col) { - lean_assert(col < column_count()); + SASSERT(col < column_count()); column_strip & colstrip = m_columns[col]; - lean_assert(colstrip.size() > 0); + SASSERT(colstrip.size() > 0); unsigned ret = 0; for (auto & t : colstrip) { if (t.m_i > ret) { @@ -122,7 +137,7 @@ template void static_matrix::add_columns_at_th } template void static_matrix::forget_last_columns(unsigned how_many_to_forget) { - lean_assert(m_columns.size() >= how_many_to_forget); + SASSERT(m_columns.size() >= how_many_to_forget); unsigned j = column_count() - 1; for (; how_many_to_forget > 0; how_many_to_forget--) { remove_last_column(j --); @@ -151,7 +166,7 @@ template void static_matrix::remove_last_column(u template void static_matrix::set(unsigned row, unsigned col, T const & val) { if (numeric_traits::is_zero(val)) return; - lean_assert(row < row_count() && col < column_count()); + SASSERT(row < row_count() && col < column_count()); auto & r = m_rows[row]; unsigned offs_in_cols = static_cast(m_columns[col].size()); m_columns[col].push_back(make_column_cell(row, static_cast(r.size()))); @@ -171,7 +186,7 @@ std::set> static_matrix::get_domain() { template void static_matrix::copy_column_to_indexed_vector (unsigned j, indexed_vector & v) const { - lean_assert(j < m_columns.size()); + SASSERT(j < m_columns.size()); for (auto & it : m_columns[j]) { const T& val = get_val(it); if (!is_zero(val)) @@ -234,13 +249,13 @@ template T static_matrix::get_min_abs_in_colu return ret; } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template void static_matrix::check_consistency() { std::unordered_map, T> by_rows; for (int i = 0; i < m_rows.size(); i++){ for (auto & t : m_rows[i]) { std::pair p(i, t.m_j); - lean_assert(by_rows.find(p) == by_rows.end()); + SASSERT(by_rows.find(p) == by_rows.end()); by_rows[p] = t.get_val(); } } @@ -248,11 +263,11 @@ template void static_matrix::check_consistency for (int i = 0; i < m_columns.size(); i++){ for (auto & t : m_columns[i]) { std::pair p(t.m_i, i); - lean_assert(by_cols.find(p) == by_cols.end()); + SASSERT(by_cols.find(p) == by_cols.end()); by_cols[p] = get_val(t); } } - lean_assert(by_rows.size() == by_cols.size()); + SASSERT(by_rows.size() == by_cols.size()); for (auto & t : by_rows) { auto ic = by_cols.find(t.first); @@ -260,21 +275,21 @@ template void static_matrix::check_consistency //std::cout << "rows have pair (" << t.first.first <<"," << t.first.second // << "), but columns don't " << std::endl; } - lean_assert(ic != by_cols.end()); - lean_assert(t.second == ic->second); + SASSERT(ic != by_cols.end()); + SASSERT(t.second == ic->second); } } #endif template void static_matrix::cross_out_row(unsigned k) { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG check_consistency(); #endif cross_out_row_from_columns(k, m_rows[k]); fix_row_indices_in_each_column_for_crossed_row(k); m_rows.erase(m_rows.begin() + k); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG regen_domain(); check_consistency(); #endif diff --git a/src/util/lp/static_matrix_instances.cpp b/src/util/lp/static_matrix_instances.cpp index ef4374a50..c57f31177 100644 --- a/src/util/lp/static_matrix_instances.cpp +++ b/src/util/lp/static_matrix_instances.cpp @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include #include @@ -13,18 +28,18 @@ #include "util/lp/lp_primal_core_solver.h" #include "util/lp/scaler.h" #include "util/lp/lar_solver.h" -namespace lean { +namespace lp { template void static_matrix::add_columns_at_the_end(unsigned int); template void static_matrix::clear(); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool static_matrix::is_correct() const; #endif template void static_matrix::copy_column_to_indexed_vector(unsigned int, indexed_vector&) const; template double static_matrix::get_balance() const; template std::set> static_matrix::get_domain(); -template std::set> lean::static_matrix::get_domain(); -template std::set> lean::static_matrix >::get_domain(); +template std::set> lp::static_matrix::get_domain(); +template std::set> lp::static_matrix >::get_domain(); template double static_matrix::get_elem(unsigned int, unsigned int) const; template double static_matrix::get_max_abs_in_column(unsigned int) const; template double static_matrix::get_min_abs_in_column(unsigned int) const; @@ -51,7 +66,7 @@ template static_matrix::ref& static_matrix::ref::operator=(m template void static_matrix::set(unsigned int, unsigned int, mpq const&); template static_matrix::static_matrix(unsigned int, unsigned int); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template bool static_matrix >::is_correct() const; #endif template void static_matrix >::copy_column_to_indexed_vector(unsigned int, indexed_vector&) const; @@ -60,10 +75,10 @@ template void static_matrix >::init_empty_matrix(unsigned template void static_matrix >::set(unsigned int, unsigned int, mpq const&); -template bool lean::static_matrix::pivot_row_to_row_given_cell(unsigned int, column_cell &, unsigned int); -template bool lean::static_matrix::pivot_row_to_row_given_cell(unsigned int, column_cell& , unsigned int); -template bool lean::static_matrix >::pivot_row_to_row_given_cell(unsigned int, column_cell&, unsigned int); -template void lean::static_matrix >::remove_element(vector, true, unsigned int>&, lean::row_cell&); +template bool lp::static_matrix::pivot_row_to_row_given_cell(unsigned int, column_cell &, unsigned int); +template bool lp::static_matrix::pivot_row_to_row_given_cell(unsigned int, column_cell& , unsigned int); +template bool lp::static_matrix >::pivot_row_to_row_given_cell(unsigned int, column_cell&, unsigned int); +template void lp::static_matrix >::remove_element(vector, true, unsigned int>&, lp::row_cell&); } diff --git a/src/util/lp/tail_matrix.h b/src/util/lp/tail_matrix.h index c337b0933..37b217205 100644 --- a/src/util/lp/tail_matrix.h +++ b/src/util/lp/tail_matrix.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -10,10 +25,10 @@ #include "util/lp/lp_settings.h" // These matrices appear at the end of the list -namespace lean { +namespace lp { template class tail_matrix -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG : public matrix #endif { diff --git a/src/util/lp/test_bound_analyzer.h b/src/util/lp/test_bound_analyzer.h index 262c610c7..30f2dd16a 100644 --- a/src/util/lp/test_bound_analyzer.h +++ b/src/util/lp/test_bound_analyzer.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" #include "util/lp/linear_combination_iterator.h" @@ -16,7 +31,7 @@ // In the same loop trying to pin variables by pushing the partial sum up, denoting the variable related to it by _l // here in addition we assume that all coefficient in the row are positive -namespace lean { +namespace lp { class test_bound_analyzer { linear_combination_iterator & m_it; @@ -74,7 +89,7 @@ public : void analyze_i_for_upper(unsigned i) { mpq l; bool strict = false; - lean_assert(is_zero(l)); + SASSERT(is_zero(l)); for (unsigned k = 0; k < m_index.size(); k++) { if (k == i) continue; @@ -165,7 +180,7 @@ public : void analyze_i_for_lower(unsigned i) { mpq l; - lean_assert(is_zero(l)); + SASSERT(is_zero(l)); bool strict = false; for (unsigned k = 0; k < m_index.size(); k++) { if (k == i) diff --git a/src/util/lp/ul_pair.h b/src/util/lp/ul_pair.h index 6331d17b5..cbf511d90 100644 --- a/src/util/lp/ul_pair.h +++ b/src/util/lp/ul_pair.h @@ -1,7 +1,22 @@ -/* - Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" @@ -10,7 +25,7 @@ #include #include "util/lp/column_info.h" -namespace lean { +namespace lp { enum lconstraint_kind { LE = -2, LT = -1 , GE = 2, GT = 1, EQ = 0 From 6d51265d9de9324330a87ea5323a78e76981192b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 17:14:30 +0100 Subject: [PATCH 295/488] Cleaned up LP test code. --- src/test/argument_parser.h | 25 ++- src/test/lp.cpp | 297 +++++++++++++++++++----------------- src/test/smt_reader.h | 53 ++++--- src/test/test_file_reader.h | 26 +++- 4 files changed, 229 insertions(+), 172 deletions(-) diff --git a/src/test/argument_parser.h b/src/test/argument_parser.h index 706167f49..c8566ce34 100644 --- a/src/test/argument_parser.h +++ b/src/test/argument_parser.h @@ -1,9 +1,22 @@ -/* -Copyright (c) 2013 Microsoft Corporation. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. +/*++ +Copyright (c) 2017 Microsoft Corporation -Author: Lev Nachmanson -*/ +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #include #include @@ -11,7 +24,7 @@ Author: Lev Nachmanson #include #include -namespace lean { +namespace lp { class argument_parser { std::unordered_map m_options; std::unordered_map m_options_with_after_string; diff --git a/src/test/lp.cpp b/src/test/lp.cpp index 695a31cf4..0f4186252 100644 --- a/src/test/lp.cpp +++ b/src/test/lp.cpp @@ -1,7 +1,23 @@ -/* -Copyright (c) 2017 Microsoft Corporation. All rights reserved. -Author: Lev Nachmanson -*/ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ + #include #if _LINUX_ #include @@ -31,8 +47,9 @@ Author: Lev Nachmanson #include "util/lp/stacked_unordered_set.h" #include "util/lp/int_set.h" #include "util/stopwatch.h" -namespace lean { -unsigned seed = 1; + +namespace lp { + unsigned seed = 1; random_gen g_rand; static unsigned my_random() { @@ -78,7 +95,7 @@ void test_matrix(sparse_matrix & a) { a.set(i, j, t); - lean_assert(a.get(i, j) == t); + SASSERT(a.get(i, j) == t); unsigned j1; if (j < m - 1) { @@ -155,7 +172,7 @@ void tst1() { test_matrix(m10by9); std::cout <<"zeroing m10by9\n"; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG for (unsigned int i = 0; i < m10by9.dimension(); i++) for (unsigned int j = 0; j < m10by9.column_count(); j++) m10by9.set(i, j, 0); @@ -170,7 +187,7 @@ vector allocate_basis_heading(unsigned count) { // the rest of initilizatio void init_basic_part_of_basis_heading(vector & basis, vector & basis_heading) { - lean_assert(basis_heading.size() >= basis.size()); + SASSERT(basis_heading.size() >= basis.size()); unsigned m = basis.size(); for (unsigned i = 0; i < m; i++) { unsigned column = basis[i]; @@ -205,7 +222,7 @@ void change_basis(unsigned entering, unsigned leaving, vector& basis, } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void test_small_lu(lp_settings & settings) { std::cout << " test_small_lu" << std::endl; static_matrix m(3, 6); @@ -218,61 +235,61 @@ void test_small_lu(lp_settings & settings) { m(1, 1) = 4; m(1, 4) = 7; m(2, 0) = 1.8; m(2, 2) = 5; m(2, 4) = 2; m(2, 5) = 8; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG print_matrix(m, std::cout); #endif vector heading = allocate_basis_heading(m.column_count()); vector non_basic_columns; init_basis_heading_and_non_basic_columns_vector(basis, heading, non_basic_columns); lu l(m, basis, settings); - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); indexed_vector w(m.row_count()); std::cout << "entering 2, leaving 0" << std::endl; l.prepare_entering(2, w); // to init vector w l.replace_column(0, w, heading[0]); change_basis(2, 0, basis, non_basic_columns, heading); - // #ifdef LEAN_DEBUG + // #ifdef Z3DEBUG // std::cout << "we were factoring " << std::endl; // print_matrix(get_B(l)); // #endif - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); std::cout << "entering 4, leaving 3" << std::endl; l.prepare_entering(4, w); // to init vector w l.replace_column(0, w, heading[3]); change_basis(4, 3, basis, non_basic_columns, heading); std::cout << "we were factoring " << std::endl; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG { auto bl = get_B(l, basis); print_matrix(&bl, std::cout); } #endif - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); std::cout << "entering 5, leaving 1" << std::endl; l.prepare_entering(5, w); // to init vector w l.replace_column(0, w, heading[1]); change_basis(5, 1, basis, non_basic_columns, heading); std::cout << "we were factoring " << std::endl; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG { auto bl = get_B(l, basis); print_matrix(&bl, std::cout); } #endif - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); std::cout << "entering 3, leaving 2" << std::endl; l.prepare_entering(3, w); // to init vector w l.replace_column(0, w, heading[2]); change_basis(3, 2, basis, non_basic_columns, heading); std::cout << "we were factoring " << std::endl; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG { auto bl = get_B(l, basis); print_matrix(&bl, std::cout); } #endif - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); m.add_row(); m.add_column(); @@ -291,7 +308,7 @@ void test_small_lu(lp_settings & settings) { auto columns_to_replace = l.get_set_of_columns_to_replace_for_add_last_rows(heading); l.add_last_rows_to_B(heading, columns_to_replace); std::cout << "here" << std::endl; - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); } #endif @@ -351,7 +368,7 @@ void fill_larger_sparse_matrix(static_matrix & m){ int perm_id = 0; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void test_larger_lu_exp(lp_settings & settings) { std::cout << " test_larger_lu_exp" << std::endl; static_matrix m(6, 12); @@ -373,7 +390,7 @@ void test_larger_lu_exp(lp_settings & settings) { dense_matrix left_side = l.get_left_side(basis); dense_matrix right_side = l.get_right_side(); - lean_assert(left_side == right_side); + SASSERT(left_side == right_side); int leaving = 3; int entering = 8; for (unsigned i = 0; i < m.row_count(); i++) { @@ -385,12 +402,12 @@ void test_larger_lu_exp(lp_settings & settings) { l.prepare_entering(entering, w); l.replace_column(0, w, heading[leaving]); change_basis(entering, leaving, basis, non_basic_columns, heading); - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); l.prepare_entering(11, w); // to init vector w l.replace_column(0, w, heading[0]); change_basis(11, 0, basis, non_basic_columns, heading); - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); } void test_larger_lu_with_holes(lp_settings & settings) { @@ -432,7 +449,7 @@ void test_larger_lu_with_holes(lp_settings & settings) { l.prepare_entering(8, w); // to init vector w l.replace_column(0, w, heading[0]); change_basis(8, 0, basis, non_basic_columns, heading); - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); } @@ -479,7 +496,7 @@ void test_larger_lu(lp_settings& settings) { l.prepare_entering(9, w); // to init vector w l.replace_column(0, w, heading[0]); change_basis(9, 0, basis, non_basic_columns, heading); - lean_assert(l.is_correct(basis)); + SASSERT(l.is_correct(basis)); } @@ -550,7 +567,7 @@ void test_lp_1() { m(1, 0) = -1; m(1, 2) = 3; m(1, 4) = 1; m(2, 0) = 2; m(2, 1) = -1; m(2, 2) = 2; m(2, 5) = 1; m(3, 0) = 2; m(3, 1) = 3; m(3, 2) = -1; m(3, 6) = 1; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG print_matrix(m, std::cout); #endif vector x_star(7); @@ -604,7 +621,7 @@ void test_lp_primal_core_solver() { } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template void test_swap_rows_with_permutation(sparse_matrix& m){ std::cout << "testing swaps" << std::endl; @@ -612,7 +629,7 @@ void test_swap_rows_with_permutation(sparse_matrix& m){ dense_matrix original(&m); permutation_matrix q(dim); print_matrix(m, std::cout); - lean_assert(original == q * m); + SASSERT(original == q * m); for (int i = 0; i < 100; i++) { unsigned row1 = my_random() % dim; unsigned row2 = my_random() % dim; @@ -620,7 +637,7 @@ void test_swap_rows_with_permutation(sparse_matrix& m){ std::cout << "swap " << row1 << " " << row2 << std::endl; m.swap_rows(row1, row2); q.transpose_from_left(row1, row2); - lean_assert(original == q * m); + SASSERT(original == q * m); print_matrix(m, std::cout); std::cout << std::endl; } @@ -628,7 +645,7 @@ void test_swap_rows_with_permutation(sparse_matrix& m){ #endif template void fill_matrix(sparse_matrix& m); // forward definition -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG template void test_swap_cols_with_permutation(sparse_matrix& m){ std::cout << "testing swaps" << std::endl; @@ -636,7 +653,7 @@ void test_swap_cols_with_permutation(sparse_matrix& m){ dense_matrix original(&m); permutation_matrix q(dim); print_matrix(m, std::cout); - lean_assert(original == q * m); + SASSERT(original == q * m); for (int i = 0; i < 100; i++) { unsigned row1 = my_random() % dim; unsigned row2 = my_random() % dim; @@ -644,7 +661,7 @@ void test_swap_cols_with_permutation(sparse_matrix& m){ std::cout << "swap " << row1 << " " << row2 << std::endl; m.swap_rows(row1, row2); q.transpose_from_right(row1, row2); - lean_assert(original == q * m); + SASSERT(original == q * m); print_matrix(m, std::cout); std::cout << std::endl; } @@ -663,8 +680,8 @@ void test_swap_rows(sparse_matrix& m, unsigned i0, unsigned i1){ m.swap_rows(i0, i1); for (unsigned j = 0; j < m.dimension(); j++) { - lean_assert(mcopy(i0, j) == m(i1, j)); - lean_assert(mcopy(i1, j) == m(i0, j)); + SASSERT(mcopy(i0, j) == m(i1, j)); + SASSERT(mcopy(i1, j) == m(i0, j)); } } template @@ -678,15 +695,15 @@ void test_swap_columns(sparse_matrix& m, unsigned i0, unsigned i1){ m.swap_columns(i0, i1); for (unsigned j = 0; j < m.dimension(); j++) { - lean_assert(mcopy(j, i0) == m(j, i1)); - lean_assert(mcopy(j, i1) == m(j, i0)); + SASSERT(mcopy(j, i0) == m(j, i1)); + SASSERT(mcopy(j, i1) == m(j, i0)); } for (unsigned i = 0; i < m.dimension(); i++) { if (i == i0 || i == i1) continue; for (unsigned j = 0; j < m.dimension(); j++) { - lean_assert(mcopy(j, i)== m(j, i)); + SASSERT(mcopy(j, i)== m(j, i)); } } } @@ -731,7 +748,7 @@ void test_pivot_like_swaps_and_pivot(){ m(target_row, 3) = 0; m(target_row, 5) = 0; m(pivot_row, 6) = 0; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG print_matrix(m, std::cout); #endif @@ -748,11 +765,11 @@ void test_pivot_like_swaps_and_pivot(){ m.pivot_row_to_row(pivot_row_0, beta, target_row, settings); // print_matrix(m); for (unsigned j = 0; j < m.dimension(); j++) { - lean_assert(abs(row[j] - m(target_row, j)) < 0.00000001); + SASSERT(abs(row[j] - m(target_row, j)) < 0.00000001); } } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG void test_swap_rows() { sparse_matrix m(10); fill_matrix(m); @@ -853,57 +870,57 @@ void sparse_matrix_with_permutaions_test() { m.multiply_from_left(q0); for (unsigned i = 0; i < dim; i++) { for (unsigned j = 0; j < dim; j++) { - lean_assert(m(i, j) == dm0.get_elem(q0[i], j)); + SASSERT(m(i, j) == dm0.get_elem(q0[i], j)); } } auto q0_dm = q0 * dm; - lean_assert(m == q0_dm); + SASSERT(m == q0_dm); m.multiply_from_left(q1); for (unsigned i = 0; i < dim; i++) { for (unsigned j = 0; j < dim; j++) { - lean_assert(m(i, j) == dm0.get_elem(q0[q1[i]], j)); + SASSERT(m(i, j) == dm0.get_elem(q0[q1[i]], j)); } } auto q1_q0_dm = q1 * q0_dm; - lean_assert(m == q1_q0_dm); + SASSERT(m == q1_q0_dm); m.multiply_from_right(p0); for (unsigned i = 0; i < dim; i++) { for (unsigned j = 0; j < dim; j++) { - lean_assert(m(i, j) == dm0.get_elem(q0[q1[i]], p0[j])); + SASSERT(m(i, j) == dm0.get_elem(q0[q1[i]], p0[j])); } } auto q1_q0_dm_p0 = q1_q0_dm * p0; - lean_assert(m == q1_q0_dm_p0); + SASSERT(m == q1_q0_dm_p0); m.multiply_from_right(p1); for (unsigned i = 0; i < dim; i++) { for (unsigned j = 0; j < dim; j++) { - lean_assert(m(i, j) == dm0.get_elem(q0[q1[i]], p1[p0[j]])); + SASSERT(m(i, j) == dm0.get_elem(q0[q1[i]], p1[p0[j]])); } } auto q1_q0_dm_p0_p1 = q1_q0_dm_p0 * p1; - lean_assert(m == q1_q0_dm_p0_p1); + SASSERT(m == q1_q0_dm_p0_p1); m.multiply_from_right(p1); for (unsigned i = 0; i < dim; i++) { for (unsigned j = 0; j < dim; j++) { - lean_assert(m(i, j) == dm0.get_elem(q0[q1[i]], p1[p1[p0[j]]])); + SASSERT(m(i, j) == dm0.get_elem(q0[q1[i]], p1[p1[p0[j]]])); } } auto q1_q0_dm_p0_p1_p1 = q1_q0_dm_p0_p1 * p1; - lean_assert(m == q1_q0_dm_p0_p1_p1); + SASSERT(m == q1_q0_dm_p0_p1_p1); } void test_swap_columns() { @@ -1021,10 +1038,10 @@ void test_apply_reverse_from_right_to_perm(permutation_matrix & pclone[4] = 1; p.multiply_by_reverse_from_right(l); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG auto rev = l.get_inverse(); auto rs = pclone * rev; - lean_assert(p == rs) + SASSERT(p == rs); #endif } @@ -1051,8 +1068,8 @@ void test_permutations() { p.apply_reverse_from_right_to_T(v); p.apply_reverse_from_right_to_T(vi); - lean_assert(vectors_are_equal(v, vi.m_data)); - lean_assert(vi.is_OK()); + SASSERT(vectors_are_equal(v, vi.m_data)); + SASSERT(vi.is_OK()); } void lp_solver_test() { @@ -1200,7 +1217,7 @@ void solve_mps_double(std::string file_name, bool look_for_min, unsigned max_ite compare_solutions(reader, primal_solver, solver); print_x(reader, primal_solver); std::cout << "dual cost is " << cost << ", but primal cost is " << primal_cost << std::endl; - lean_assert(false); + SASSERT(false); } } } @@ -1210,7 +1227,7 @@ void solve_mps_double(std::string file_name, bool look_for_min, unsigned max_ite } void solve_mps_rational(std::string file_name, bool look_for_min, unsigned max_iterations, unsigned time_limit, bool dual, argument_parser & args_parser) { - mps_reader reader(file_name); + mps_reader reader(file_name); reader.read(); if (reader.is_ok()) { auto * solver = reader.create_solver(dual); @@ -1224,7 +1241,7 @@ void solve_mps_rational(std::string file_name, bool look_for_min, unsigned max_i // for (auto name: reader.column_names()) { // std::cout << name << "=" << solver->get_column_value_by_name(name) << ' '; // } - lean::mpq cost = solver->get_current_cost(); + lp::mpq cost = solver->get_current_cost(); if (look_for_min) { cost = -cost; } @@ -1262,7 +1279,7 @@ void solve_mps(std::string file_name, argument_parser & args_parser) { void solve_mps_in_rational(std::string file_name, bool dual, argument_parser & /*args_parser*/) { std::cout << "solving " << file_name << std::endl; - mps_reader reader(file_name); + mps_reader reader(file_name); reader.read(); if (reader.is_ok()) { auto * solver = reader.create_solver(dual); @@ -1274,7 +1291,7 @@ void solve_mps_in_rational(std::string file_name, bool dual, argument_parser & / std::cout << name << "=" << solver->get_column_value_by_name(name).get_double() << ' '; } } - std::cout << std::endl << "cost = " << numeric_traits::get_double(solver->get_current_cost()) << std::endl; + std::cout << std::endl << "cost = " << numeric_traits::get_double(solver->get_current_cost()) << std::endl; } delete solver; } else { @@ -1318,7 +1335,7 @@ void test_binary_priority_queue() { for (unsigned i = 0; i < 10; i++) { unsigned de = q.dequeue(); - lean_assert(i == de); + SASSERT(i == de); std::cout << de << std::endl; } q.enqueue(2, 2); @@ -1337,11 +1354,11 @@ void test_binary_priority_queue() { q.dequeue(); q.remove(33); q.enqueue(0, 0); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned t = 0; while (q.size() > 0) { unsigned d =q.dequeue(); - lean_assert(t++ == d); + SASSERT(t++ == d); std::cout << d << std::endl; } #endif @@ -1370,7 +1387,7 @@ void solve_mps_with_known_solution(std::string file_name, std::unordered_mapget_status()) << std::endl; if (status != solver->get_status()){ std::cout << "status should be " << lp_status_to_string(status) << std::endl; - lean_assert(status == solver->get_status()); + SASSERT(status == solver->get_status()); throw "status is wrong"; } if (solver->get_status() == lp_status::OPTIMAL) { @@ -1381,7 +1398,7 @@ void solve_mps_with_known_solution(std::string file_name, std::unordered_mapget_column_value_by_name(it.first) << std::endl; } - lean_assert(fabs(it.second - solver->get_column_value_by_name(it.first)) < 0.000001); + SASSERT(fabs(it.second - solver->get_column_value_by_name(it.first)) < 0.000001); } } if (reader.column_names().size() < 20) { @@ -1706,48 +1723,48 @@ void solve_some_mps(argument_parser & args_parser) { #endif void solve_rational() { - lp_primal_simplex solver; - solver.add_constraint(lp_relation::Equal, lean::mpq(7), 0); - solver.add_constraint(lp_relation::Equal, lean::mpq(-3), 1); + lp_primal_simplex solver; + solver.add_constraint(lp_relation::Equal, lp::mpq(7), 0); + solver.add_constraint(lp_relation::Equal, lp::mpq(-3), 1); // setting the cost int cost[] = {-3, -1, -1, 2, -1, 1, 1, -4}; std::string var_names[8] = {"x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8"}; for (unsigned i = 0; i < 8; i++) { - solver.set_cost_for_column(i, lean::mpq(cost[i])); + solver.set_cost_for_column(i, lp::mpq(cost[i])); solver.give_symbolic_name_to_column(var_names[i], i); } int row0[] = {1, 0, 3, 1, -5, -2 , 4, -6}; for (unsigned i = 0; i < 8; i++) { - solver.set_row_column_coefficient(0, i, lean::mpq(row0[i])); + solver.set_row_column_coefficient(0, i, lp::mpq(row0[i])); } int row1[] = {0, 1, -2, -1, 4, 1, -3, 5}; for (unsigned i = 0; i < 8; i++) { - solver.set_row_column_coefficient(1, i, lean::mpq(row1[i])); + solver.set_row_column_coefficient(1, i, lp::mpq(row1[i])); } int bounds[] = {8, 6, 4, 15, 2, 10, 10, 3}; for (unsigned i = 0; i < 8; i++) { - solver.set_low_bound(i, lean::mpq(0)); - solver.set_upper_bound(i, lean::mpq(bounds[i])); + solver.set_low_bound(i, lp::mpq(0)); + solver.set_upper_bound(i, lp::mpq(bounds[i])); } - std::unordered_map expected_sol; - expected_sol["x1"] = lean::mpq(0); - expected_sol["x2"] = lean::mpq(6); - expected_sol["x3"] = lean::mpq(0); - expected_sol["x4"] = lean::mpq(15); - expected_sol["x5"] = lean::mpq(2); - expected_sol["x6"] = lean::mpq(1); - expected_sol["x7"] = lean::mpq(1); - expected_sol["x8"] = lean::mpq(0); + std::unordered_map expected_sol; + expected_sol["x1"] = lp::mpq(0); + expected_sol["x2"] = lp::mpq(6); + expected_sol["x3"] = lp::mpq(0); + expected_sol["x4"] = lp::mpq(15); + expected_sol["x5"] = lp::mpq(2); + expected_sol["x6"] = lp::mpq(1); + expected_sol["x7"] = lp::mpq(1); + expected_sol["x8"] = lp::mpq(0); solver.find_maximal_solution(); - lean_assert(solver.get_status() == OPTIMAL); + SASSERT(solver.get_status() == OPTIMAL); for (auto it : expected_sol) { - lean_assert(it.second == solver.get_column_value_by_name(it.first)); + SASSERT(it.second == solver.get_column_value_by_name(it.first)); } } @@ -1805,7 +1822,7 @@ std::unordered_map * get_solution_from_glpsol_output(std::s return ret; } - lean_assert(split.size() > 3); + SASSERT(split.size() > 3); (*ret)[split[1]] = atof(split[3].c_str()); } while (true); } @@ -1817,7 +1834,7 @@ void test_init_U() { m(0, 0) = 10; m(0, 1) = 11; m(0, 2) = 12; m(0, 3) = 13; m(0, 4) = 14; m(1, 0) = 20; m(1, 1) = 21; m(1, 2) = 22; m(1, 3) = 23; m(1, 5) = 24; m(2, 0) = 30; m(2, 1) = 31; m(2, 2) = 32; m(2, 3) = 33; m(2, 6) = 34; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG print_matrix(m, std::cout); #endif vector basis(3); @@ -1829,7 +1846,7 @@ void test_init_U() { for (unsigned i = 0; i < 3; i++) { for (unsigned j = 0; j < 3; j ++) { - lean_assert(m(i, basis[j]) == u(i, j)); + SASSERT(m(i, basis[j]) == u(i, j)); } } @@ -1857,7 +1874,7 @@ void test_replace_column() { for (unsigned column_to_replace = 0; column_to_replace < m.dimension(); column_to_replace ++) { m.replace_column(column_to_replace, w, settings); for (unsigned i = 0; i < m.dimension(); i++) { - lean_assert(abs(w[i] - m(i, column_to_replace)) < 0.00000001); + SASSERT(abs(w[i] - m(i, column_to_replace)) < 0.00000001); } } } @@ -1961,7 +1978,7 @@ void test_stacked_unsigned() { v = 3; v = 4; v.pop(); - lean_assert(v == 2); + SASSERT(v == 2); v ++; v++; std::cout << "before push v=" << v << std::endl; @@ -1971,7 +1988,7 @@ void test_stacked_unsigned() { v+=1; std::cout << "v = " << v << std::endl; v.pop(2); - lean_assert(v == 4); + SASSERT(v == 4); const unsigned & rr = v; std::cout << rr << std:: endl; @@ -2010,7 +2027,7 @@ void test_stacked_vector() { } void test_stacked_set() { -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG std::cout << "test_stacked_set" << std::endl; stacked_unordered_set s; s.insert(1); @@ -2020,7 +2037,7 @@ void test_stacked_set() { s.push(); s.insert(4); s.pop(); - lean_assert(s() == scopy); + SASSERT(s() == scopy); s.push(); s.push(); s.insert(4); @@ -2028,7 +2045,7 @@ void test_stacked_set() { s.push(); s.insert(4); s.pop(3); - lean_assert(s() == scopy); + SASSERT(s() == scopy); #endif } @@ -2397,15 +2414,15 @@ void test_files_from_directory(std::string test_file_dir, argument_parser & args } -std::unordered_map get_solution_map(lp_solver * lps, mps_reader & reader) { - std::unordered_map ret; +std::unordered_map get_solution_map(lp_solver * lps, mps_reader & reader) { + std::unordered_map ret; for (auto it : reader.column_names()) { ret[it] = lps->get_column_value_by_name(it); } return ret; } -void run_lar_solver(argument_parser & args_parser, lar_solver * solver, mps_reader * reader) { +void run_lar_solver(argument_parser & args_parser, lar_solver * solver, mps_reader * reader) { std::string maxng = args_parser.get_option_value("--maxng"); if (maxng.size() > 0) { solver->settings().max_number_of_iterations_with_no_improvements = atoi(maxng.c_str()); @@ -2425,7 +2442,7 @@ void run_lar_solver(argument_parser & args_parser, lar_solver * solver, mps_read } auto * lps = reader->create_solver(false); lps->find_maximal_solution(); - std::unordered_map sol = get_solution_map(lps, *reader); + std::unordered_map sol = get_solution_map(lps, *reader); std::cout << "status = " << lp_status_to_string(solver->get_status()) << std::endl; return; } @@ -2434,7 +2451,7 @@ void run_lar_solver(argument_parser & args_parser, lar_solver * solver, mps_read lp_status status = solver->solve(); std::cout << "status is " << lp_status_to_string(status) << ", processed for " << sw.get_current_seconds() <<" seconds, and " << solver->get_total_iterations() << " iterations" << std::endl; if (solver->get_status() == INFEASIBLE) { - vector> evidence; + vector> evidence; solver->get_infeasibility_explanation(evidence); } if (args_parser.option_is_used("--randomize_lar")) { @@ -2467,7 +2484,7 @@ lar_solver * create_lar_solver_from_file(std::string file_name, argument_parser } return reader.create_lar_solver(); } - mps_reader reader(file_name); + mps_reader reader(file_name); reader.read(); if (!reader.is_ok()) { std::cout << "cannot process " << file_name << std::endl; @@ -2478,8 +2495,8 @@ lar_solver * create_lar_solver_from_file(std::string file_name, argument_parser void test_lar_on_file(std::string file_name, argument_parser & args_parser) { lar_solver * solver = create_lar_solver_from_file(file_name, args_parser); - mps_reader reader(file_name); - mps_reader * mps_reader = nullptr; + mps_reader reader(file_name); + mps_reader * mps_reader = nullptr; reader.read(); if (reader.is_ok()) { mps_reader = & reader; @@ -2524,28 +2541,28 @@ void test_lar_solver(argument_parser & args_parser) { } void test_numeric_pair() { - numeric_pair a; - numeric_pair b(2, lean::mpq(6, 2)); + numeric_pair a; + numeric_pair b(2, lp::mpq(6, 2)); a = b; - numeric_pair c(0.1, 0.5); + numeric_pair c(0.1, 0.5); a += 2*c; a -= c; - lean_assert (a == b + c); - numeric_pair d = a * 2; + SASSERT (a == b + c); + numeric_pair d = a * 2; std::cout << a << std::endl; - lean_assert(b == b); - lean_assert(b < a); - lean_assert(b <= a); - lean_assert(a > b); - lean_assert(a != b); - lean_assert(a >= b); - lean_assert(-a < b); - lean_assert(a < 2 * b); - lean_assert(b + b > a); - lean_assert(lean::mpq(2.1) * b + b > a); - lean_assert(-b * lean::mpq(2.1) - b < lean::mpq(0.99) * a); - std::cout << - b * lean::mpq(2.1) - b << std::endl; - lean_assert(-b *(lean::mpq(2.1) + 1) == - b * lean::mpq(2.1) - b); + SASSERT(b == b); + SASSERT(b < a); + SASSERT(b <= a); + SASSERT(a > b); + SASSERT(a != b); + SASSERT(a >= b); + SASSERT(-a < b); + SASSERT(a < 2 * b); + SASSERT(b + b > a); + SASSERT(lp::mpq(2.1) * b + b > a); + SASSERT(-b * lp::mpq(2.1) - b < lp::mpq(0.99) * a); + std::cout << - b * lp::mpq(2.1) - b << std::endl; + SASSERT(-b *(lp::mpq(2.1) + 1) == - b * lp::mpq(2.1) - b); } void get_matrix_dimensions(std::ifstream & f, unsigned & m, unsigned & n) { @@ -2566,7 +2583,7 @@ void read_row_cols(unsigned i, static_matrix& A, std::ifstream & if (line== "row_end") break; auto r = split_and_trim(line); - lean_assert(r.size() == 4); + SASSERT(r.size() == 4); unsigned j = atoi(r[1].c_str()); double v = atof(r[3].c_str()); A.set(i, j, v); @@ -2594,7 +2611,7 @@ void read_basis(vector & basis, std::ifstream & f) { std::cout << "reading basis" << std::endl; std::string line; getline(f, line); - lean_assert(line == "basis_start"); + SASSERT(line == "basis_start"); do { getline(f, line); if (line == "basis_end") @@ -2607,7 +2624,7 @@ void read_basis(vector & basis, std::ifstream & f) { void read_indexed_vector(indexed_vector & v, std::ifstream & f) { std::string line; getline(f, line); - lean_assert(line == "vector_start"); + SASSERT(line == "vector_start"); do { getline(f, line); if (line == "vector_end") break; @@ -2641,13 +2658,13 @@ void check_lu_from_file(std::string lufile_name) { indexed_vector d(A.row_count()); unsigned entering = 26; lsuhl.solve_Bd(entering, d, v); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG auto B = get_B(lsuhl, basis); vector a(m); A.copy_column_to_vector(entering, a); indexed_vector cd(d); B.apply_from_left(cd.m_data, settings); - lean_assert(vectors_are_equal(cd.m_data , a)); + SASSERT(vectors_are_equal(cd.m_data , a)); #endif } @@ -2662,7 +2679,7 @@ void test_square_dense_submatrix() { for (unsigned i = index_start; i < parent_dim; i++) for (unsigned j = index_start; j < parent_dim; j++) d[i][j] = i*3+j*2; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG unsigned dim = parent_dim - index_start; dense_matrix m(dim, dim); for (unsigned i = index_start; i < parent_dim; i++) @@ -2673,7 +2690,7 @@ void test_square_dense_submatrix() { for (unsigned i = index_start; i < parent_dim; i++) for (unsigned j = index_start; j < parent_dim; j++) d[i][j] = d[j][i]; -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG for (unsigned i = index_start; i < parent_dim; i++) for (unsigned j = index_start; j < parent_dim; j++) m[i-index_start][j-index_start] = d[i][j]; @@ -2738,7 +2755,7 @@ void test_evidence_for_total_inf_simple(argument_parser & args_parser) { auto status = solver.solve(); std::cout << lp_status_to_string(status) << std::endl; std::unordered_map model; - lean_assert(solver.get_status() == INFEASIBLE); + SASSERT(solver.get_status() == INFEASIBLE); } void test_bound_propagation_one_small_sample1() { /* @@ -2934,8 +2951,8 @@ void test_total_case_l(){ ls.solve(); lp_bound_propagator bp(ls); ls.propagate_bounds_for_touched_rows(bp); - lean_assert(ev.size() == 4); - lean_assert(contains_j_kind(x, GE, - one_of_type(), ev)); + SASSERT(ev.size() == 4); + SASSERT(contains_j_kind(x, GE, - one_of_type(), ev)); } void test_bound_propagation() { test_total_case_u(); @@ -2955,17 +2972,17 @@ void test_int_set() { s.insert(1); s.insert(2); s.print(std::cout); - lean_assert(s.contains(2)); - lean_assert(s.size() == 2); + SASSERT(s.contains(2)); + SASSERT(s.size() == 2); s.erase(2); - lean_assert(s.size() == 1); + SASSERT(s.size() == 1); s.erase(2); - lean_assert(s.size() == 1); + SASSERT(s.size() == 1); s.print(std::cout); s.insert(3); s.insert(2); s.clear(); - lean_assert(s.size() == 0); + SASSERT(s.size() == 0); } @@ -3112,7 +3129,7 @@ void test_lp_local(int argn, char**argv) { return finalize(0); } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG if (args_parser.option_is_used("--test_swaps")) { sparse_matrix m(10); fill_matrix(m); @@ -3142,7 +3159,7 @@ void test_lp_local(int argn, char**argv) { return finalize(ret); } -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG lp_settings settings; update_settings(args_parser, settings); if (args_parser.option_is_used("--test_lu")) { @@ -3219,11 +3236,11 @@ void test_lp_local(int argn, char**argv) { ret = 0; return finalize(ret); } - // lean::ccc = 0; + // lp::ccc = 0; return finalize(0); test_init_U(); test_replace_column(); -#ifdef LEAN_DEBUG +#ifdef Z3DEBUG sparse_matrix_with_permutaions_test(); test_dense_matrix(); test_swap_operations(); @@ -3236,5 +3253,5 @@ void test_lp_local(int argn, char**argv) { } } void tst_lp(char ** argv, int argc, int& i) { - lean::test_lp_local(argc - 2, argv + 2); + lp::test_lp_local(argc - 2, argv + 2); } diff --git a/src/test/smt_reader.h b/src/test/smt_reader.h index 38e3f4157..437cb7a6b 100644 --- a/src/test/smt_reader.h +++ b/src/test/smt_reader.h @@ -1,9 +1,22 @@ -/* - Copyright (c) 2013 Microsoft Corporation. All rights reserved. - Released under Apache 2.0 license as described in the file LICENSE. +/*++ +Copyright (c) 2017 Microsoft Corporation - Author: Lev Nachmanson -*/ +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once @@ -23,7 +36,7 @@ #include "util/lp/lar_constraints.h" #include #include -namespace lean { +namespace lp { template T from_string(const std::string& str) { @@ -108,13 +121,13 @@ namespace lean { void fill_simple_elem(lisp_elem & lm) { int separator = first_separator(); - lean_assert(-1 != separator && separator != 0); + SASSERT(-1 != separator && separator != 0); lm.m_head = m_line.substr(0, separator); m_line = m_line.substr(separator); } void fill_nested_elem(lisp_elem & lm) { - lean_assert(m_line[0] == '('); + SASSERT(m_line[0] == '('); m_line = m_line.substr(1); int separator = first_separator(); lm.m_head = m_line.substr(0, separator); @@ -181,11 +194,11 @@ namespace lean { } void adjust_rigth_side(formula_constraint & /* c*/, lisp_elem & /*el*/) { - // lean_assert(el.m_head == "0"); // do nothing for the time being + // SASSERT(el.m_head == "0"); // do nothing for the time being } void set_constraint_coeffs(formula_constraint & c, lisp_elem & el) { - lean_assert(el.m_elems.size() == 2); + SASSERT(el.m_elems.size() == 2); set_constraint_coeffs_on_coeff_element(c, el.m_elems[0]); adjust_rigth_side(c, el.m_elems[1]); } @@ -201,7 +214,7 @@ namespace lean { add_mult_elem(c, el.m_elems); } else if (el.m_head == "~") { lisp_elem & minel = el.m_elems[0]; - lean_assert(minel.is_simple()); + SASSERT(minel.is_simple()); c.m_right_side += mpq(str_to_int(minel.m_head)); } else { std::cout << "unexpected input " << el.m_head << std::endl; @@ -211,14 +224,14 @@ namespace lean { } std::string get_name(lisp_elem & name) { - lean_assert(name.is_simple()); - lean_assert(!is_integer(name.m_head)); + SASSERT(name.is_simple()); + SASSERT(!is_integer(name.m_head)); return name.m_head; } void add_mult_elem(formula_constraint & c, std::vector & els) { - lean_assert(els.size() == 2); + SASSERT(els.size() == 2); mpq coeff = get_coeff(els[0]); std::string col_name = get_name(els[1]); c.add_pair(coeff, col_name); @@ -228,16 +241,16 @@ namespace lean { if (le.is_simple()) { return mpq(str_to_int(le.m_head)); } else { - lean_assert(le.m_head == "~"); - lean_assert(le.size() == 1); + SASSERT(le.m_head == "~"); + SASSERT(le.size() == 1); lisp_elem & el = le.m_elems[0]; - lean_assert(el.is_simple()); + SASSERT(el.is_simple()); return -mpq(str_to_int(el.m_head)); } } int str_to_int(std::string & s) { - lean_assert(is_integer(s)); + SASSERT(is_integer(s)); return atoi(s.c_str()); } @@ -245,7 +258,7 @@ namespace lean { if (el.size()) { add_complex_sum_elem(c, el); } else { - lean_assert(is_integer(el.m_head)); + SASSERT(is_integer(el.m_head)); int v = atoi(el.m_head.c_str()); mpq vr(v); c.m_right_side -= vr; @@ -263,7 +276,7 @@ namespace lean { } else if (el.m_head == "+") { add_sum(c, el.m_elems); } else { - lean_assert(false); // unexpected input + SASSERT(false); // unexpected input } } diff --git a/src/test/test_file_reader.h b/src/test/test_file_reader.h index c7a9e3b8b..74dad419b 100644 --- a/src/test/test_file_reader.h +++ b/src/test/test_file_reader.h @@ -1,9 +1,23 @@ -/* -Copyright (c) 2013 Microsoft Corporation. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ -Author: Lev Nachmanson -*/ #pragma once // reads a text file @@ -15,7 +29,7 @@ Author: Lev Nachmanson #include "util/lp/lp_utils.h" #include "util/lp/lp_solver.h" -namespace lean { +namespace lp { template struct test_result { From 56e20da3cea4688186d94a5b6daa098afd749d08 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 17:33:42 +0100 Subject: [PATCH 296/488] Copyright messages --- src/util/lp/conversion_helper.h | 23 +++++++++++++++++++---- src/util/lp/quick_xplain.h | 21 ++++++++++++++++++--- src/util/lp/random_updater.h | 22 +++++++++++++++++++--- src/util/lp/stacked_vector.h | 22 +++++++++++++++++++--- 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/util/lp/conversion_helper.h b/src/util/lp/conversion_helper.h index cd8577483..f80b1c2c6 100644 --- a/src/util/lp/conversion_helper.h +++ b/src/util/lp/conversion_helper.h @@ -1,8 +1,23 @@ -/* - Copyright (c) 2013 Microsoft Corporation. All rights reserved. +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ - Author: Lev Nachmanson -*/ #pragma once namespace lp { template diff --git a/src/util/lp/quick_xplain.h b/src/util/lp/quick_xplain.h index 952199f85..902fa08cd 100644 --- a/src/util/lp/quick_xplain.h +++ b/src/util/lp/quick_xplain.h @@ -1,7 +1,22 @@ -/* +/*++ Copyright (c) 2017 Microsoft Corporation -Author: Lev Nachmanson -*/ + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ #pragma once #include "util/vector.h" diff --git a/src/util/lp/random_updater.h b/src/util/lp/random_updater.h index 68b14c971..6b03ad941 100644 --- a/src/util/lp/random_updater.h +++ b/src/util/lp/random_updater.h @@ -1,7 +1,23 @@ -/* +/*++ Copyright (c) 2017 Microsoft Corporation -Author: Lev Nachmanson -*/ + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ + #pragma once #include #include "util/vector.h" diff --git a/src/util/lp/stacked_vector.h b/src/util/lp/stacked_vector.h index 0f66e93f3..e8234d1e4 100644 --- a/src/util/lp/stacked_vector.h +++ b/src/util/lp/stacked_vector.h @@ -1,7 +1,23 @@ -/* +/*++ Copyright (c) 2017 Microsoft Corporation -Author: Lev Nachmanson -*/ + +Module Name: + + + +Abstract: + + + +Author: + + Lev Nachmanson (levnach) + +Revision History: + + +--*/ + #pragma once #include #include From db398eca7a45dd3f3f7cd747e83befb52a6dc68b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 17:50:05 +0100 Subject: [PATCH 297/488] Tabs, formatting. --- src/api/dotnet/CMakeLists.txt | 144 +++++++++--------- src/api/dotnet/Context.cs | 6 +- src/api/dotnet/Expr.cs | 18 +-- src/api/dotnet/Optimize.cs | 36 ++--- .../dotnet/dotnet35/Microsoft.Z3.NET35.sln | 74 ++++----- src/api/java/ASTVector.java | 2 +- src/api/java/AlgebraicNum.java | 92 +++++------ src/api/java/Context.java | 120 +++++++-------- src/api/java/EnumSort.java | 2 +- src/api/java/Expr.java | 2 +- src/api/java/Model.java | 2 +- src/api/java/Optimize.java | 9 +- src/api/java/ParamDescrs.java | 2 +- src/api/java/Solver.java | 2 +- src/api/java/Sort.java | 8 +- src/api/ml/z3native_stubs.c.pre | 38 ++--- src/ast/rewriter/array_rewriter_params.pyg | 2 +- src/ast/rewriter/fpa_rewriter_params.pyg | 2 +- src/muz/base/fixedpoint_params.pyg | 44 +++--- src/opt/opt_params.pyg | 2 +- src/tactic/sls/.#sls_params.pyg | 1 + src/tactic/sls/sls_params.pyg | 44 +++--- src/util/lp/CMakeLists.txt | 2 +- src/util/lp/lp_core_solver_base.hpp | 4 +- src/util/lp/lp_primal_core_solver_tableau.h | 2 +- src/util/lp/static_matrix.hpp | 6 +- 26 files changed, 331 insertions(+), 335 deletions(-) create mode 100644 src/tactic/sls/.#sls_params.pyg diff --git a/src/api/dotnet/CMakeLists.txt b/src/api/dotnet/CMakeLists.txt index 93f5929d9..add1b0ded 100644 --- a/src/api/dotnet/CMakeLists.txt +++ b/src/api/dotnet/CMakeLists.txt @@ -43,78 +43,78 @@ add_custom_command(OUTPUT "${Z3_DOTNET_CONST_FILE}" ) set(Z3_DOTNET_ASSEMBLY_SOURCES_IN_SRC_TREE - AlgebraicNum.cs - ApplyResult.cs - ArithExpr.cs - ArithSort.cs - ArrayExpr.cs - ArraySort.cs - AST.cs - ASTMap.cs - ASTVector.cs - BitVecExpr.cs - BitVecNum.cs - BitVecSort.cs - BoolExpr.cs - BoolSort.cs - Constructor.cs - ConstructorList.cs - Context.cs - DatatypeExpr.cs - DatatypeSort.cs - Deprecated.cs - EnumSort.cs - Expr.cs - FiniteDomainExpr.cs - FiniteDomainNum.cs - FiniteDomainSort.cs - Fixedpoint.cs - FPExpr.cs - FPNum.cs - FPRMExpr.cs - FPRMNum.cs - FPRMSort.cs - FPSort.cs - FuncDecl.cs - FuncInterp.cs - Global.cs - Goal.cs - IDecRefQueue.cs - InterpolationContext.cs - IntExpr.cs - IntNum.cs - IntSort.cs - IntSymbol.cs - ListSort.cs - Log.cs - Model.cs - Optimize.cs - ParamDescrs.cs - Params.cs - Pattern.cs - Probe.cs - Quantifier.cs - RatNum.cs - RealExpr.cs - RealSort.cs - ReExpr.cs - RelationSort.cs - ReSort.cs - SeqExpr.cs - SeqSort.cs - SetSort.cs - Solver.cs - Sort.cs - Statistics.cs - Status.cs - StringSymbol.cs - Symbol.cs - Tactic.cs - TupleSort.cs - UninterpretedSort.cs - Version.cs - Z3Exception.cs - Z3Object.cs + AlgebraicNum.cs + ApplyResult.cs + ArithExpr.cs + ArithSort.cs + ArrayExpr.cs + ArraySort.cs + AST.cs + ASTMap.cs + ASTVector.cs + BitVecExpr.cs + BitVecNum.cs + BitVecSort.cs + BoolExpr.cs + BoolSort.cs + Constructor.cs + ConstructorList.cs + Context.cs + DatatypeExpr.cs + DatatypeSort.cs + Deprecated.cs + EnumSort.cs + Expr.cs + FiniteDomainExpr.cs + FiniteDomainNum.cs + FiniteDomainSort.cs + Fixedpoint.cs + FPExpr.cs + FPNum.cs + FPRMExpr.cs + FPRMNum.cs + FPRMSort.cs + FPSort.cs + FuncDecl.cs + FuncInterp.cs + Global.cs + Goal.cs + IDecRefQueue.cs + InterpolationContext.cs + IntExpr.cs + IntNum.cs + IntSort.cs + IntSymbol.cs + ListSort.cs + Log.cs + Model.cs + Optimize.cs + ParamDescrs.cs + Params.cs + Pattern.cs + Probe.cs + Quantifier.cs + RatNum.cs + RealExpr.cs + RealSort.cs + ReExpr.cs + RelationSort.cs + ReSort.cs + SeqExpr.cs + SeqSort.cs + SetSort.cs + Solver.cs + Sort.cs + Statistics.cs + Status.cs + StringSymbol.cs + Symbol.cs + Tactic.cs + TupleSort.cs + UninterpretedSort.cs + Version.cs + Z3Exception.cs + Z3Object.cs ) set(Z3_DOTNET_ASSEMBLY_SOURCES "") diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index a656be3eb..d7699c961 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -126,7 +126,7 @@ namespace Microsoft.Z3 private BoolSort m_boolSort = null; private IntSort m_intSort = null; private RealSort m_realSort = null; - private SeqSort m_stringSort = null; + private SeqSort m_stringSort = null; /// /// Retrieves the Boolean sort of the context. @@ -2426,7 +2426,7 @@ namespace Microsoft.Z3 public SeqExpr IntToString(Expr e) { Contract.Requires(e != null); - Contract.Requires(e is ArithExpr); + Contract.Requires(e is ArithExpr); Contract.Ensures(Contract.Result() != null); return new SeqExpr(this, Native.Z3_mk_int_to_str(nCtx, e.NativeObject)); } @@ -2690,7 +2690,7 @@ namespace Microsoft.Z3 /// /// Create a range expression. /// - public ReExpr MkRange(SeqExpr lo, SeqExpr hi) + public ReExpr MkRange(SeqExpr lo, SeqExpr hi) { Contract.Requires(lo != null); Contract.Requires(hi != null); diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index 6c52b83c8..4fd306052 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -809,55 +809,55 @@ namespace Microsoft.Z3 /// Check whether expression is a concatentation. /// /// a Boolean - public bool IsConcat { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_CONCAT; } } + public bool IsConcat { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_CONCAT; } } /// /// Check whether expression is a prefix. /// /// a Boolean - public bool IsPrefix { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_PREFIX; } } + public bool IsPrefix { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_PREFIX; } } /// /// Check whether expression is a suffix. /// /// a Boolean - public bool IsSuffix { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_SUFFIX; } } + public bool IsSuffix { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_SUFFIX; } } /// /// Check whether expression is a contains. /// /// a Boolean - public bool IsContains { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_CONTAINS; } } + public bool IsContains { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_CONTAINS; } } /// /// Check whether expression is an extract. /// /// a Boolean - public bool IsExtract { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_EXTRACT; } } + public bool IsExtract { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_EXTRACT; } } /// /// Check whether expression is a replace. /// /// a Boolean - public bool IsReplace { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_REPLACE; } } + public bool IsReplace { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_REPLACE; } } /// /// Check whether expression is an at. /// /// a Boolean - public bool IsAt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_AT; } } + public bool IsAt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_AT; } } /// /// Check whether expression is a sequence length. /// /// a Boolean - public bool IsLength { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_LENGTH; } } + public bool IsLength { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_LENGTH; } } /// /// Check whether expression is a sequence index. /// /// a Boolean - public bool IsIndex { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_INDEX; } } + public bool IsIndex { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_INDEX; } } #endregion diff --git a/src/api/dotnet/Optimize.cs b/src/api/dotnet/Optimize.cs index 99dd9aac0..9d0636425 100644 --- a/src/api/dotnet/Optimize.cs +++ b/src/api/dotnet/Optimize.cs @@ -123,7 +123,7 @@ namespace Microsoft.Z3 /// /// Retrieve a lower bound for the objective handle. - /// + /// public ArithExpr Lower { get { return opt.GetLower(handle); } @@ -131,7 +131,7 @@ namespace Microsoft.Z3 /// /// Retrieve an upper bound for the objective handle. - /// + /// public ArithExpr Upper { get { return opt.GetUpper(handle); } @@ -139,7 +139,7 @@ namespace Microsoft.Z3 /// /// Retrieve the value of an objective. - /// + /// public ArithExpr Value { get { return Lower; } @@ -147,7 +147,7 @@ namespace Microsoft.Z3 /// /// Retrieve a lower bound for the objective handle. - /// + /// public ArithExpr[] LowerAsVector { get { return opt.GetLowerAsVector(handle); } @@ -155,7 +155,7 @@ namespace Microsoft.Z3 /// /// Retrieve an upper bound for the objective handle. - /// + /// public ArithExpr[] UpperAsVector { get { return opt.GetUpperAsVector(handle); } @@ -240,7 +240,7 @@ namespace Microsoft.Z3 /// Declare an arithmetical maximization objective. /// Return a handle to the objective. The handle is used as /// to retrieve the values of objectives after calling Check. - /// + /// public Handle MkMaximize(ArithExpr e) { return new Handle(this, Native.Z3_optimize_maximize(Context.nCtx, NativeObject, e.NativeObject)); @@ -249,7 +249,7 @@ namespace Microsoft.Z3 /// /// Declare an arithmetical minimization objective. /// Similar to MkMaximize. - /// + /// public Handle MkMinimize(ArithExpr e) { return new Handle(this, Native.Z3_optimize_minimize(Context.nCtx, NativeObject, e.NativeObject)); @@ -257,7 +257,7 @@ namespace Microsoft.Z3 /// /// Retrieve a lower bound for the objective handle. - /// + /// private ArithExpr GetLower(uint index) { return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_lower(Context.nCtx, NativeObject, index)); @@ -266,7 +266,7 @@ namespace Microsoft.Z3 /// /// Retrieve an upper bound for the objective handle. - /// + /// private ArithExpr GetUpper(uint index) { return (ArithExpr)Expr.Create(Context, Native.Z3_optimize_get_upper(Context.nCtx, NativeObject, index)); @@ -274,7 +274,7 @@ namespace Microsoft.Z3 /// /// Retrieve a lower bound for the objective handle. - /// + /// private ArithExpr[] GetLowerAsVector(uint index) { ASTVector v = new ASTVector(Context, Native.Z3_optimize_get_lower_as_vector(Context.nCtx, NativeObject, index)); @@ -284,29 +284,29 @@ namespace Microsoft.Z3 /// /// Retrieve an upper bound for the objective handle. - /// + /// private ArithExpr[] GetUpperAsVector(uint index) { ASTVector v = new ASTVector(Context, Native.Z3_optimize_get_upper_as_vector(Context.nCtx, NativeObject, index)); return v.ToArithExprArray(); } - /// - /// Return a string the describes why the last to check returned unknown - /// - public String ReasonUnknown - { + /// + /// Return a string the describes why the last to check returned unknown + /// + public String ReasonUnknown + { get { Contract.Ensures(Contract.Result() != null); return Native.Z3_optimize_get_reason_unknown(Context.nCtx, NativeObject); } - } + } /// /// Print the context to a string (SMT-LIB parseable benchmark). - /// + /// public override string ToString() { return Native.Z3_optimize_to_string(Context.nCtx, NativeObject); diff --git a/src/api/dotnet/dotnet35/Microsoft.Z3.NET35.sln b/src/api/dotnet/dotnet35/Microsoft.Z3.NET35.sln index b6e252684..1e33f136e 100644 --- a/src/api/dotnet/dotnet35/Microsoft.Z3.NET35.sln +++ b/src/api/dotnet/dotnet35/Microsoft.Z3.NET35.sln @@ -8,41 +8,41 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "Example\Example.csproj", "{2A8E577B-7B6D-4CA9-832A-CA2EEC314812}" EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.ActiveCfg = Debug|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.Build.0 = Debug|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x86.ActiveCfg = Debug|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x86.Build.0 = Debug|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.Build.0 = Release|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.ActiveCfg = Release|x64 - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.Build.0 = Release|x64 - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x86.ActiveCfg = Release|Any CPU - {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x86.Build.0 = Release|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x64.ActiveCfg = Debug|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x64.Build.0 = Debug|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x86.ActiveCfg = Debug|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x86.Build.0 = Debug|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|Any CPU.Build.0 = Release|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x64.ActiveCfg = Release|x64 - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x64.Build.0 = Release|x64 - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x86.ActiveCfg = Release|Any CPU - {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x64.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x86.ActiveCfg = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Debug|x86.Build.0 = Debug|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|Any CPU.Build.0 = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.ActiveCfg = Release|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x64.Build.0 = Release|x64 + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x86.ActiveCfg = Release|Any CPU + {EC3DB697-B734-42F7-9468-5B62821EEB5A}.Release|x86.Build.0 = Release|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x64.ActiveCfg = Debug|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x64.Build.0 = Debug|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x86.ActiveCfg = Debug|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Debug|x86.Build.0 = Debug|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|Any CPU.Build.0 = Release|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x64.ActiveCfg = Release|x64 + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x64.Build.0 = Release|x64 + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x86.ActiveCfg = Release|Any CPU + {2A8E577B-7B6D-4CA9-832A-CA2EEC314812}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal diff --git a/src/api/java/ASTVector.java b/src/api/java/ASTVector.java index 4d9ab291a..b78f714b2 100644 --- a/src/api/java/ASTVector.java +++ b/src/api/java/ASTVector.java @@ -131,7 +131,7 @@ public class ASTVector extends Z3Object { Expr[] res = new Expr[n]; for (int i = 0; i < n; i++) res[i] = Expr.create(getContext(), get(i).getNativeObject()); - return res; + return res; } /** diff --git a/src/api/java/AlgebraicNum.java b/src/api/java/AlgebraicNum.java index 6725d3937..7369e06e3 100644 --- a/src/api/java/AlgebraicNum.java +++ b/src/api/java/AlgebraicNum.java @@ -22,57 +22,57 @@ package com.microsoft.z3; **/ public class AlgebraicNum extends ArithExpr { - /** - * Return a upper bound for a given real algebraic number. The interval - * isolating the number is smaller than 1/10^{@code precision}. - * - * @see Expr#isAlgebraicNumber - * @param precision the precision of the result - * - * @return A numeral Expr of sort Real - * @throws Z3Exception on error - **/ - public RatNum toUpper(int precision) - { + /** + * Return a upper bound for a given real algebraic number. The interval + * isolating the number is smaller than 1/10^{@code precision}. + * + * @see Expr#isAlgebraicNumber + * @param precision the precision of the result + * + * @return A numeral Expr of sort Real + * @throws Z3Exception on error + **/ + public RatNum toUpper(int precision) + { - return new RatNum(getContext(), Native.getAlgebraicNumberUpper(getContext() - .nCtx(), getNativeObject(), precision)); - } + return new RatNum(getContext(), Native.getAlgebraicNumberUpper(getContext() + .nCtx(), getNativeObject(), precision)); + } - /** - * Return a lower bound for the given real algebraic number. The interval - * isolating the number is smaller than 1/10^{@code precision}. - * - * @see Expr#isAlgebraicNumber - * @param precision precision - * - * @return A numeral Expr of sort Real - * @throws Z3Exception on error - **/ - public RatNum toLower(int precision) - { + /** + * Return a lower bound for the given real algebraic number. The interval + * isolating the number is smaller than 1/10^{@code precision}. + * + * @see Expr#isAlgebraicNumber + * @param precision precision + * + * @return A numeral Expr of sort Real + * @throws Z3Exception on error + **/ + public RatNum toLower(int precision) + { - return new RatNum(getContext(), Native.getAlgebraicNumberLower(getContext() - .nCtx(), getNativeObject(), precision)); - } + return new RatNum(getContext(), Native.getAlgebraicNumberLower(getContext() + .nCtx(), getNativeObject(), precision)); + } - /** - * Returns a string representation in decimal notation. - * Remarks: The result has at most {@code precision} decimal places. - * @param precision precision - * @return String - * @throws Z3Exception on error - **/ - public String toDecimal(int precision) - { + /** + * Returns a string representation in decimal notation. + * Remarks: The result has at most {@code precision} decimal places. + * @param precision precision + * @return String + * @throws Z3Exception on error + **/ + public String toDecimal(int precision) + { - return Native.getNumeralDecimalString(getContext().nCtx(), getNativeObject(), - precision); - } + return Native.getNumeralDecimalString(getContext().nCtx(), getNativeObject(), + precision); + } - AlgebraicNum(Context ctx, long obj) - { - super(ctx, obj); + AlgebraicNum(Context ctx, long obj) + { + super(ctx, obj); - } + } } diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 2609dbb29..986736fb6 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -1898,8 +1898,8 @@ public class Context implements AutoCloseable { */ public SeqExpr mkEmptySeq(Sort s) { - checkContextMatch(s); - return (SeqExpr) Expr.create(this, Native.mkSeqEmpty(nCtx(), s.getNativeObject())); + checkContextMatch(s); + return (SeqExpr) Expr.create(this, Native.mkSeqEmpty(nCtx(), s.getNativeObject())); } /** @@ -1907,8 +1907,8 @@ public class Context implements AutoCloseable { */ public SeqExpr mkUnit(Expr elem) { - checkContextMatch(elem); - return (SeqExpr) Expr.create(this, Native.mkSeqUnit(nCtx(), elem.getNativeObject())); + checkContextMatch(elem); + return (SeqExpr) Expr.create(this, Native.mkSeqUnit(nCtx(), elem.getNativeObject())); } /** @@ -1916,7 +1916,7 @@ public class Context implements AutoCloseable { */ public SeqExpr mkString(String s) { - return (SeqExpr) Expr.create(this, Native.mkString(nCtx(), s)); + return (SeqExpr) Expr.create(this, Native.mkString(nCtx(), s)); } /** @@ -1924,8 +1924,8 @@ public class Context implements AutoCloseable { */ public SeqExpr mkConcat(SeqExpr... t) { - checkContextMatch(t); - return (SeqExpr) Expr.create(this, Native.mkSeqConcat(nCtx(), t.length, AST.arrayToNative(t))); + checkContextMatch(t); + return (SeqExpr) Expr.create(this, Native.mkSeqConcat(nCtx(), t.length, AST.arrayToNative(t))); } @@ -1934,8 +1934,8 @@ public class Context implements AutoCloseable { */ public IntExpr mkLength(SeqExpr s) { - checkContextMatch(s); - return (IntExpr) Expr.create(this, Native.mkSeqLength(nCtx(), s.getNativeObject())); + checkContextMatch(s); + return (IntExpr) Expr.create(this, Native.mkSeqLength(nCtx(), s.getNativeObject())); } /** @@ -1943,8 +1943,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkPrefixOf(SeqExpr s1, SeqExpr s2) { - checkContextMatch(s1, s2); - return (BoolExpr) Expr.create(this, Native.mkSeqPrefix(nCtx(), s1.getNativeObject(), s2.getNativeObject())); + checkContextMatch(s1, s2); + return (BoolExpr) Expr.create(this, Native.mkSeqPrefix(nCtx(), s1.getNativeObject(), s2.getNativeObject())); } /** @@ -1952,8 +1952,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkSuffixOf(SeqExpr s1, SeqExpr s2) { - checkContextMatch(s1, s2); - return (BoolExpr)Expr.create(this, Native.mkSeqSuffix(nCtx(), s1.getNativeObject(), s2.getNativeObject())); + checkContextMatch(s1, s2); + return (BoolExpr)Expr.create(this, Native.mkSeqSuffix(nCtx(), s1.getNativeObject(), s2.getNativeObject())); } /** @@ -1961,8 +1961,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkContains(SeqExpr s1, SeqExpr s2) { - checkContextMatch(s1, s2); - return (BoolExpr) Expr.create(this, Native.mkSeqContains(nCtx(), s1.getNativeObject(), s2.getNativeObject())); + checkContextMatch(s1, s2); + return (BoolExpr) Expr.create(this, Native.mkSeqContains(nCtx(), s1.getNativeObject(), s2.getNativeObject())); } /** @@ -1970,8 +1970,8 @@ public class Context implements AutoCloseable { */ public SeqExpr mkAt(SeqExpr s, IntExpr index) { - checkContextMatch(s, index); - return (SeqExpr) Expr.create(this, Native.mkSeqAt(nCtx(), s.getNativeObject(), index.getNativeObject())); + checkContextMatch(s, index); + return (SeqExpr) Expr.create(this, Native.mkSeqAt(nCtx(), s.getNativeObject(), index.getNativeObject())); } /** @@ -1979,8 +1979,8 @@ public class Context implements AutoCloseable { */ public SeqExpr mkExtract(SeqExpr s, IntExpr offset, IntExpr length) { - checkContextMatch(s, offset, length); - return (SeqExpr) Expr.create(this, Native.mkSeqExtract(nCtx(), s.getNativeObject(), offset.getNativeObject(), length.getNativeObject())); + checkContextMatch(s, offset, length); + return (SeqExpr) Expr.create(this, Native.mkSeqExtract(nCtx(), s.getNativeObject(), offset.getNativeObject(), length.getNativeObject())); } /** @@ -1988,8 +1988,8 @@ public class Context implements AutoCloseable { */ public IntExpr mkIndexOf(SeqExpr s, SeqExpr substr, ArithExpr offset) { - checkContextMatch(s, substr, offset); - return (IntExpr)Expr.create(this, Native.mkSeqIndex(nCtx(), s.getNativeObject(), substr.getNativeObject(), offset.getNativeObject())); + checkContextMatch(s, substr, offset); + return (IntExpr)Expr.create(this, Native.mkSeqIndex(nCtx(), s.getNativeObject(), substr.getNativeObject(), offset.getNativeObject())); } /** @@ -1997,8 +1997,8 @@ public class Context implements AutoCloseable { */ public SeqExpr mkReplace(SeqExpr s, SeqExpr src, SeqExpr dst) { - checkContextMatch(s, src, dst); - return (SeqExpr) Expr.create(this, Native.mkSeqReplace(nCtx(), s.getNativeObject(), src.getNativeObject(), dst.getNativeObject())); + checkContextMatch(s, src, dst); + return (SeqExpr) Expr.create(this, Native.mkSeqReplace(nCtx(), s.getNativeObject(), src.getNativeObject(), dst.getNativeObject())); } /** @@ -2006,8 +2006,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkToRe(SeqExpr s) { - checkContextMatch(s); - return (ReExpr) Expr.create(this, Native.mkSeqToRe(nCtx(), s.getNativeObject())); + checkContextMatch(s); + return (ReExpr) Expr.create(this, Native.mkSeqToRe(nCtx(), s.getNativeObject())); } @@ -2016,8 +2016,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkInRe(SeqExpr s, ReExpr re) { - checkContextMatch(s, re); - return (BoolExpr) Expr.create(this, Native.mkSeqInRe(nCtx(), s.getNativeObject(), re.getNativeObject())); + checkContextMatch(s, re); + return (BoolExpr) Expr.create(this, Native.mkSeqInRe(nCtx(), s.getNativeObject(), re.getNativeObject())); } /** @@ -2025,8 +2025,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkStar(ReExpr re) { - checkContextMatch(re); - return (ReExpr) Expr.create(this, Native.mkReStar(nCtx(), re.getNativeObject())); + checkContextMatch(re); + return (ReExpr) Expr.create(this, Native.mkReStar(nCtx(), re.getNativeObject())); } /** @@ -2034,7 +2034,7 @@ public class Context implements AutoCloseable { */ public ReExpr mkLoop(ReExpr re, int lo, int hi) { - return (ReExpr) Expr.create(this, Native.mkReLoop(nCtx(), re.getNativeObject(), lo, hi)); + return (ReExpr) Expr.create(this, Native.mkReLoop(nCtx(), re.getNativeObject(), lo, hi)); } /** @@ -2042,7 +2042,7 @@ public class Context implements AutoCloseable { */ public ReExpr mkLoop(ReExpr re, int lo) { - return (ReExpr) Expr.create(this, Native.mkReLoop(nCtx(), re.getNativeObject(), lo, 0)); + return (ReExpr) Expr.create(this, Native.mkReLoop(nCtx(), re.getNativeObject(), lo, 0)); } @@ -2051,8 +2051,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkPlus(ReExpr re) { - checkContextMatch(re); - return (ReExpr) Expr.create(this, Native.mkRePlus(nCtx(), re.getNativeObject())); + checkContextMatch(re); + return (ReExpr) Expr.create(this, Native.mkRePlus(nCtx(), re.getNativeObject())); } /** @@ -2060,8 +2060,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkOption(ReExpr re) { - checkContextMatch(re); - return (ReExpr) Expr.create(this, Native.mkReOption(nCtx(), re.getNativeObject())); + checkContextMatch(re); + return (ReExpr) Expr.create(this, Native.mkReOption(nCtx(), re.getNativeObject())); } @@ -2070,8 +2070,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkComplement(ReExpr re) { - checkContextMatch(re); - return (ReExpr) Expr.create(this, Native.mkReComplement(nCtx(), re.getNativeObject())); + checkContextMatchb(re); + return (ReExpr) Expr.create(this, Native.mkReComplement(nCtx(), re.getNativeObject())); } /** @@ -2079,8 +2079,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkConcat(ReExpr... t) { - checkContextMatch(t); - return (ReExpr) Expr.create(this, Native.mkReConcat(nCtx(), t.length, AST.arrayToNative(t))); + checkContextMatch(t); + return (ReExpr) Expr.create(this, Native.mkReConcat(nCtx(), t.length, AST.arrayToNative(t))); } /** @@ -2088,8 +2088,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkUnion(ReExpr... t) { - checkContextMatch(t); - return (ReExpr) Expr.create(this, Native.mkReUnion(nCtx(), t.length, AST.arrayToNative(t))); + checkContextMatch(t); + return (ReExpr) Expr.create(this, Native.mkReUnion(nCtx(), t.length, AST.arrayToNative(t))); } /** @@ -2097,8 +2097,8 @@ public class Context implements AutoCloseable { */ public ReExpr mkIntersect(ReExpr... t) { - checkContextMatch(t); - return (ReExpr) Expr.create(this, Native.mkReIntersect(nCtx(), t.length, AST.arrayToNative(t))); + checkContextMatch(t); + return (ReExpr) Expr.create(this, Native.mkReIntersect(nCtx(), t.length, AST.arrayToNative(t))); } /** @@ -2106,8 +2106,8 @@ public class Context implements AutoCloseable { */ public ReExpr MkRange(SeqExpr lo, SeqExpr hi) { - checkContextMatch(lo, hi); - return (ReExpr) Expr.create(this, Native.mkReRange(nCtx(), lo.getNativeObject(), hi.getNativeObject())); + checkContextMatch(lo, hi); + return (ReExpr) Expr.create(this, Native.mkReRange(nCtx(), lo.getNativeObject(), hi.getNativeObject())); } @@ -2116,8 +2116,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkAtMost(BoolExpr[] args, int k) { - checkContextMatch(args); - return (BoolExpr) Expr.create(this, Native.mkAtmost(nCtx(), args.length, AST.arrayToNative(args), k)); + checkContextMatch(args); + return (BoolExpr) Expr.create(this, Native.mkAtmost(nCtx(), args.length, AST.arrayToNative(args), k)); } /** @@ -2125,8 +2125,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkAtLeast(BoolExpr[] args, int k) { - checkContextMatch(args); - return (BoolExpr) Expr.create(this, Native.mkAtleast(nCtx(), args.length, AST.arrayToNative(args), k)); + checkContextMatch(args); + return (BoolExpr) Expr.create(this, Native.mkAtleast(nCtx(), args.length, AST.arrayToNative(args), k)); } /** @@ -2134,8 +2134,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkPBLe(int[] coeffs, BoolExpr[] args, int k) { - checkContextMatch(args); - return (BoolExpr) Expr.create(this, Native.mkPble(nCtx(), args.length, AST.arrayToNative(args), coeffs, k)); + checkContextMatch(args); + return (BoolExpr) Expr.create(this, Native.mkPble(nCtx(), args.length, AST.arrayToNative(args), coeffs, k)); } /** @@ -2143,8 +2143,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkPBGe(int[] coeffs, BoolExpr[] args, int k) { - checkContextMatch(args); - return (BoolExpr) Expr.create(this, Native.mkPbge(nCtx(), args.length, AST.arrayToNative(args), coeffs, k)); + checkContextMatch(args); + return (BoolExpr) Expr.create(this, Native.mkPbge(nCtx(), args.length, AST.arrayToNative(args), coeffs, k)); } /** @@ -2152,8 +2152,8 @@ public class Context implements AutoCloseable { */ public BoolExpr mkPBEq(int[] coeffs, BoolExpr[] args, int k) { - checkContextMatch(args); - return (BoolExpr) Expr.create(this, Native.mkPbeq(nCtx(), args.length, AST.arrayToNative(args), coeffs, k)); + checkContextMatch(args); + return (BoolExpr) Expr.create(this, Native.mkPbeq(nCtx(), args.length, AST.arrayToNative(args), coeffs, k)); } @@ -3988,15 +3988,15 @@ public class Context implements AutoCloseable { void checkContextMatch(Z3Object other1, Z3Object other2) { - checkContextMatch(other1); - checkContextMatch(other2); + checkContextMatch(other1); + checkContextMatch(other2); } void checkContextMatch(Z3Object other1, Z3Object other2, Z3Object other3) { - checkContextMatch(other1); - checkContextMatch(other2); - checkContextMatch(other3); + checkContextMatch(other1); + checkContextMatch(other2); + checkContextMatch(other3); } void checkContextMatch(Z3Object[] arr) diff --git a/src/api/java/EnumSort.java b/src/api/java/EnumSort.java index ce2f8d578..e0bd0f617 100644 --- a/src/api/java/EnumSort.java +++ b/src/api/java/EnumSort.java @@ -65,7 +65,7 @@ public class EnumSort extends Sort **/ public Expr getConst(int inx) { - return getContext().mkApp(getConstDecl(inx)); + return getContext().mkApp(getConstDecl(inx)); } /** diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index 6cabbb1b8..d3793a24b 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -1287,7 +1287,7 @@ public class Expr extends AST */ public String getString() { - return Native.getString(getContext().nCtx(), getNativeObject()); + return Native.getString(getContext().nCtx(), getNativeObject()); } /** diff --git a/src/api/java/Model.java b/src/api/java/Model.java index 60abb001d..9c7013aca 100644 --- a/src/api/java/Model.java +++ b/src/api/java/Model.java @@ -200,7 +200,7 @@ public class Model extends Z3Object { * Remarks: This function may fail if {@code t} contains * quantifiers, is partial (MODEL_PARTIAL enabled), or if {@code t} is not well-sorted. In this case a * {@code ModelEvaluationFailedException} is thrown. - * @param t the expression to evaluate + * @param t the expression to evaluate * @param completion An expression {@code completion} When this flag * is enabled, a model value will be assigned to any constant or function * that does not have an interpretation in the model. diff --git a/src/api/java/Optimize.java b/src/api/java/Optimize.java index bc2232888..3edbff73e 100644 --- a/src/api/java/Optimize.java +++ b/src/api/java/Optimize.java @@ -213,7 +213,7 @@ public class Optimize extends Z3Object { * Declare an arithmetical maximization objective. * Return a handle to the objective. The handle is used as * to retrieve the values of objectives after calling Check. - **/ + **/ public Handle MkMaximize(ArithExpr e) { return new Handle(this, Native.optimizeMaximize(getContext().nCtx(), getNativeObject(), e.getNativeObject())); @@ -285,8 +285,7 @@ public class Optimize extends Z3Object { **/ public String getReasonUnknown() { - return Native.optimizeGetReasonUnknown(getContext().nCtx(), - getNativeObject()); + return Native.optimizeGetReasonUnknown(getContext().nCtx(), getNativeObject()); } /** @@ -304,7 +303,7 @@ public class Optimize extends Z3Object { */ public void fromFile(String file) { - Native.optimizeFromFile(getContext().nCtx(), getNativeObject(), file); + Native.optimizeFromFile(getContext().nCtx(), getNativeObject(), file); } /** @@ -312,7 +311,7 @@ public class Optimize extends Z3Object { */ public void fromString(String s) { - Native.optimizeFromString(getContext().nCtx(), getNativeObject(), s); + Native.optimizeFromString(getContext().nCtx(), getNativeObject(), s); } diff --git a/src/api/java/ParamDescrs.java b/src/api/java/ParamDescrs.java index 0008515e3..fdaf29647 100644 --- a/src/api/java/ParamDescrs.java +++ b/src/api/java/ParamDescrs.java @@ -49,7 +49,7 @@ public class ParamDescrs extends Z3Object { public String getDocumentation(Symbol name) { - return Native.paramDescrsGetDocumentation(getContext().nCtx(), getNativeObject(), name.getNativeObject()); + return Native.paramDescrsGetDocumentation(getContext().nCtx(), getNativeObject(), name.getNativeObject()); } /** diff --git a/src/api/java/Solver.java b/src/api/java/Solver.java index a98fcbf94..19f3b01da 100644 --- a/src/api/java/Solver.java +++ b/src/api/java/Solver.java @@ -302,7 +302,7 @@ public class Solver extends Z3Object { */ public Solver translate(Context ctx) { - return new Solver(ctx, Native.solverTranslate(getContext().nCtx(), getNativeObject(), ctx.nCtx())); + return new Solver(ctx, Native.solverTranslate(getContext().nCtx(), getNativeObject(), ctx.nCtx())); } /** diff --git a/src/api/java/Sort.java b/src/api/java/Sort.java index e7a186ad2..a89417059 100644 --- a/src/api/java/Sort.java +++ b/src/api/java/Sort.java @@ -35,12 +35,8 @@ public class Sort extends AST if (!(o instanceof Sort)) return false; Sort other = (Sort) o; - return (getContext().nCtx() == other.getContext().nCtx()) && - (Native.isEqSort( - getContext().nCtx(), - getNativeObject(), - other.getNativeObject() - )); + return (getContext().nCtx() == other.getContext().nCtx()) && + (Native.isEqSort(getContext().nCtx(), getNativeObject(), other.getNativeObject())); } /** diff --git a/src/api/ml/z3native_stubs.c.pre b/src/api/ml/z3native_stubs.c.pre index 1b1ea3fde..c1c772c85 100644 --- a/src/api/ml/z3native_stubs.c.pre +++ b/src/api/ml/z3native_stubs.c.pre @@ -25,34 +25,34 @@ extern "C" { #include #define CAMLlocal6(X1,X2,X3,X4,X5,X6) \ - CAMLlocal5(X1,X2,X3,X4,X5); \ + CAMLlocal5(X1,X2,X3,X4,X5); \ CAMLlocal1(X6) -#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \ - CAMLlocal5(X1,X2,X3,X4,X5); \ +#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \ + CAMLlocal5(X1,X2,X3,X4,X5); \ CAMLlocal2(X6,X7) -#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \ - CAMLlocal5(X1,X2,X3,X4,X5); \ +#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \ + CAMLlocal5(X1,X2,X3,X4,X5); \ CAMLlocal3(X6,X7,X8) -#define CAMLparam6(X1,X2,X3,X4,X5,X6) \ - CAMLparam5(X1,X2,X3,X4,X5); \ +#define CAMLparam6(X1,X2,X3,X4,X5,X6) \ + CAMLparam5(X1,X2,X3,X4,X5); \ CAMLxparam1(X6) -#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \ - CAMLparam5(X1,X2,X3,X4,X5); \ +#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \ + CAMLparam5(X1,X2,X3,X4,X5); \ CAMLxparam2(X6,X7) -#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \ - CAMLparam5(X1,X2,X3,X4,X5); \ +#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \ + CAMLparam5(X1,X2,X3,X4,X5); \ CAMLxparam3(X6,X7,X8) -#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \ - CAMLparam5(X1,X2,X3,X4,X5); \ +#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \ + CAMLparam5(X1,X2,X3,X4,X5); \ CAMLxparam4(X6,X7,X8,X9) -#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \ - CAMLparam5(X1,X2,X3,X4,X5); \ - CAMLxparam5(X6,X7,X8,X9,X10); \ +#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \ + CAMLparam5(X1,X2,X3,X4,X5); \ + CAMLxparam5(X6,X7,X8,X9,X10); \ CAMLxparam2(X11,X12) -#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \ - CAMLparam5(X1,X2,X3,X4,X5); \ - CAMLxparam5(X6,X7,X8,X9,X10); \ +#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \ + CAMLparam5(X1,X2,X3,X4,X5); \ + CAMLxparam5(X6,X7,X8,X9,X10); \ CAMLxparam3(X11,X12,X13) diff --git a/src/ast/rewriter/array_rewriter_params.pyg b/src/ast/rewriter/array_rewriter_params.pyg index a43fadecf..3b4af7fb7 100644 --- a/src/ast/rewriter/array_rewriter_params.pyg +++ b/src/ast/rewriter/array_rewriter_params.pyg @@ -2,5 +2,5 @@ def_module_params(module_name='rewriter', class_name='array_rewriter_params', export=True, params=(("expand_select_store", BOOL, False, "replace a (select (store ...) ...) term by an if-then-else term"), - ("expand_store_eq", BOOL, False, "reduce (store ...) = (store ...) with a common base into selects"), + ("expand_store_eq", BOOL, False, "reduce (store ...) = (store ...) with a common base into selects"), ("sort_store", BOOL, False, "sort nested stores when the indices are known to be different"))) diff --git a/src/ast/rewriter/fpa_rewriter_params.pyg b/src/ast/rewriter/fpa_rewriter_params.pyg index f0cfbdf55..487c50a85 100644 --- a/src/ast/rewriter/fpa_rewriter_params.pyg +++ b/src/ast/rewriter/fpa_rewriter_params.pyg @@ -1,5 +1,5 @@ def_module_params(module_name='rewriter', class_name='fpa_rewriter_params', export=True, - params=(("hi_fp_unspecified", BOOL, False, "use the 'hardware interpretation' for unspecified values in fp.to_ubv, fp.to_sbv, fp.to_real, and fp.to_ieee_bv"), + params=(("hi_fp_unspecified", BOOL, False, "use the 'hardware interpretation' for unspecified values in fp.to_ubv, fp.to_sbv, fp.to_real, and fp.to_ieee_bv"), )) diff --git a/src/muz/base/fixedpoint_params.pyg b/src/muz/base/fixedpoint_params.pyg index 110f081b0..0c2f03460 100644 --- a/src/muz/base/fixedpoint_params.pyg +++ b/src/muz/base/fixedpoint_params.pyg @@ -4,7 +4,7 @@ def_module_params('fixedpoint', params=(('timeout', UINT, UINT_MAX, 'set timeout'), ('engine', SYMBOL, 'auto-config', 'Select: auto-config, datalog, duality, pdr, bmc, spacer'), - ('datalog.default_table', SYMBOL, 'sparse', + ('datalog.default_table', SYMBOL, 'sparse', 'default table implementation: sparse, hashtable, bitvector, interval'), ('datalog.default_relation', SYMBOL, 'pentagon', 'default relation implementation: external_relation, pentagon'), @@ -56,18 +56,18 @@ def_module_params('fixedpoint', "table columns, if it would have been empty otherwise"), ('datalog.subsumption', BOOL, True, "if true, removes/filters predicates with total transitions"), - ('duality.full_expand', BOOL, False, 'Fully expand derivation trees'), - ('duality.no_conj', BOOL, False, 'No forced covering (conjectures)'), - ('duality.feasible_edges', BOOL, True, + ('duality.full_expand', BOOL, False, 'Fully expand derivation trees'), + ('duality.no_conj', BOOL, False, 'No forced covering (conjectures)'), + ('duality.feasible_edges', BOOL, True, 'Don\'t expand definitley infeasible edges'), - ('duality.use_underapprox', BOOL, False, 'Use underapproximations'), - ('duality.stratified_inlining', BOOL, False, 'Use stratified inlining'), - ('duality.recursion_bound', UINT, UINT_MAX, + ('duality.use_underapprox', BOOL, False, 'Use underapproximations'), + ('duality.stratified_inlining', BOOL, False, 'Use stratified inlining'), + ('duality.recursion_bound', UINT, UINT_MAX, 'Recursion bound for stratified inlining'), - ('duality.profile', BOOL, False, 'profile run time'), - ('duality.mbqi', BOOL, True, 'use model-based quantifier instantiation'), - ('duality.batch_expand', BOOL, False, 'use batch expansion'), - ('duality.conjecture_file', STRING, '', 'save conjectures to file'), + ('duality.profile', BOOL, False, 'profile run time'), + ('duality.mbqi', BOOL, True, 'use model-based quantifier instantiation'), + ('duality.batch_expand', BOOL, False, 'use batch expansion'), + ('duality.conjecture_file', STRING, '', 'save conjectures to file'), ('pdr.bfs_model_search', BOOL, True, "use BFS strategy for expanding model search"), ('pdr.farkas', BOOL, True, @@ -92,9 +92,9 @@ def_module_params('fixedpoint', "generalize lemmas using induction strengthening"), ('pdr.use_arith_inductive_generalizer', BOOL, False, "generalize lemmas using arithmetic heuristics for induction strengthening"), - ('pdr.use_convex_closure_generalizer', BOOL, False, + ('pdr.use_convex_closure_generalizer', BOOL, False, "generalize using convex closures of lemmas"), - ('pdr.use_convex_interior_generalizer', BOOL, False, + ('pdr.use_convex_interior_generalizer', BOOL, False, "generalize using convex interiors of lemmas"), ('pdr.cache_mode', UINT, 0, "use no (0), symbolic (1) or explicit " + "cache (2) for model search"), @@ -104,7 +104,7 @@ def_module_params('fixedpoint', ('pdr.max_num_contexts', UINT, 500, "maximal number of contexts to create"), ('pdr.try_minimize_core', BOOL, False, "try to reduce core size (before inductive minimization)"), - ('pdr.utvpi', BOOL, True, 'Enable UTVPI strategy'), + ('pdr.utvpi', BOOL, True, 'Enable UTVPI strategy'), ('print_fixedpoint_extensions', BOOL, True, "use SMT-LIB2 fixedpoint extensions, instead of pure SMT2, " + "when printing rules"), @@ -123,7 +123,7 @@ def_module_params('fixedpoint', ('print_statistics', BOOL, False, 'print statistics'), ('print_aig', SYMBOL, '', 'Dump clauses in AIG text format (AAG) to the given file name'), - ('tab.selection', SYMBOL, 'weight', + ('tab.selection', SYMBOL, 'weight', 'selection method for tabular strategy: weight (default), first, var-use'), ('xform.bit_blast', BOOL, False, 'bit-blast bit-vectors'), @@ -140,7 +140,7 @@ def_module_params('fixedpoint', ('xform.unfold_rules', UINT, 0, "unfold rules statically using iterative squarring"), ('xform.slice', BOOL, True, "simplify clause set using slicing"), - ('xform.karr', BOOL, False, + ('xform.karr', BOOL, False, "Add linear invariants to clauses using Karr's method"), ('spacer.use_eqclass', BOOL, False, "Generalizes equalities to equivalence classes"), ('xform.transform_arrays', BOOL, False, @@ -153,24 +153,24 @@ def_module_params('fixedpoint', "Gives the number of quantifiers per array"), ('xform.instantiate_arrays.slice_technique', SYMBOL, "no-slicing", "=> GetId(i) = i, => GetId(i) = true"), - ('xform.quantify_arrays', BOOL, False, + ('xform.quantify_arrays', BOOL, False, "create quantified Horn clauses from clauses with arrays"), - ('xform.instantiate_quantifiers', BOOL, False, + ('xform.instantiate_quantifiers', BOOL, False, "instantiate quantified Horn clauses using E-matching heuristic"), ('xform.coalesce_rules', BOOL, False, "coalesce rules"), ('xform.tail_simplifier_pve', BOOL, True, "propagate_variable_equivalences"), ('xform.subsumption_checker', BOOL, True, "Enable subsumption checker (no support for model conversion)"), - ('xform.coi', BOOL, True, "use cone of influence simplificaiton"), - ('duality.enable_restarts', BOOL, False, 'DUALITY: enable restarts'), + ('xform.coi', BOOL, True, "use cone of influence simplification"), + ('duality.enable_restarts', BOOL, False, 'DUALITY: enable restarts'), ('spacer.order_children', UINT, 0, 'SPACER: order of enqueuing children in non-linear rules : 0 (original), 1 (reverse)'), ('spacer.eager_reach_check', BOOL, True, 'SPACER: eagerly check if a query is reachable using reachability facts of predecessors'), ('spacer.use_lemma_as_cti', BOOL, False, 'SPACER: use a lemma instead of a CTI in flexible_trace'), ('spacer.reset_obligation_queue', BOOL, True, 'SPACER: reset obligation queue when entering a new level'), ('spacer.init_reach_facts', BOOL, True, 'SPACER: initialize reachability facts with false'), ('spacer.use_array_eq_generalizer', BOOL, True, 'SPACER: attempt to generalize lemmas with array equalities'), - ('spacer.use_derivations', BOOL, True, 'SPACER: using derivation mechanism to cache intermediate results for non-linear rules'), + ('spacer.use_derivations', BOOL, True, 'SPACER: using derivation mechanism to cache intermediate results for non-linear rules'), ('xform.array_blast', BOOL, False, "try to eliminate local array terms using Ackermannization -- some array terms may remain"), - ('xform.array_blast_full', BOOL, False, "eliminate all local array variables by QE"), + ('xform.array_blast_full', BOOL, False, "eliminate all local array variables by QE"), ('spacer.skip_propagate', BOOL, False, "Skip propagate/pushing phase. Turns PDR into a BMC that returns either reachable or unknown"), ('spacer.max_level', UINT, UINT_MAX, "Maximum level to explore"), ('spacer.elim_aux', BOOL, True, "Eliminate auxiliary variables in reachability facts"), diff --git a/src/opt/opt_params.pyg b/src/opt/opt_params.pyg index 13bf51313..cfcc5e47e 100644 --- a/src/opt/opt_params.pyg +++ b/src/opt/opt_params.pyg @@ -2,7 +2,7 @@ def_module_params('opt', description='optimization parameters', export=True, params=(('optsmt_engine', SYMBOL, 'basic', "select optimization engine: 'basic', 'farkas', 'symba'"), - ('maxsat_engine', SYMBOL, 'maxres', "select engine for maxsat: 'core_maxsat', 'wmax', 'maxres', 'pd-maxres'"), + ('maxsat_engine', SYMBOL, 'maxres', "select engine for maxsat: 'core_maxsat', 'wmax', 'maxres', 'pd-maxres'"), ('priority', SYMBOL, 'lex', "select how to priortize objectives: 'lex' (lexicographic), 'pareto', or 'box'"), ('dump_benchmarks', BOOL, False, 'dump benchmarks for profiling'), ('timeout', UINT, UINT_MAX, 'timeout (in milliseconds) (UINT_MAX and 0 mean no timeout)'), diff --git a/src/tactic/sls/.#sls_params.pyg b/src/tactic/sls/.#sls_params.pyg new file mode 100644 index 000000000..50991f6f4 --- /dev/null +++ b/src/tactic/sls/.#sls_params.pyg @@ -0,0 +1 @@ +winte@WINTERMUTE.13536:1505663874 \ No newline at end of file diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index bf5bd181a..05405ef24 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -2,25 +2,25 @@ def_module_params('sls', export=True, description='Experimental Stochastic Local Search Solver (for QFBV only).', params=(max_memory_param(), - ('max_restarts', UINT, UINT_MAX, 'maximum number of restarts'), - ('walksat', BOOL, 1, 'use walksat assertion selection (instead of gsat)'), - ('walksat_ucb', BOOL, 1, 'use bandit heuristic for walksat assertion selection (instead of random)'), - ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), - ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), - ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), - ('walksat_ucb_noise', DOUBLE, 0.0002, 'add noise 0 <= 256 * ucb_noise to ucb score for assertion selection'), - ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), - ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), - ('paws_init', UINT, 40, 'initial/minimum assertion weights'), - ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), - ('wp', UINT, 100, 'random walk with probability wp / 1024'), - ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), - ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), - ('restart_base', UINT, 100, 'base restart interval given by moves per run'), - ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), - ('early_prune', BOOL, 1, 'use early pruning for score prediction'), - ('random_offset', BOOL, 1, 'use random offset for candidate evaluation'), - ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), - ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), - ('random_seed', UINT, 0, 'random seed') - )) + ('max_restarts', UINT, UINT_MAX, 'maximum number of restarts'), + ('walksat', BOOL, 1, 'use walksat assertion selection (instead of gsat)'), + ('walksat_ucb', BOOL, 1, 'use bandit heuristic for walksat assertion selection (instead of random)'), + ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), + ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), + ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), + ('walksat_ucb_noise', DOUBLE, 0.0002, 'add noise 0 <= 256 * ucb_noise to ucb score for assertion selection'), + ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), + ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), + ('paws_init', UINT, 40, 'initial/minimum assertion weights'), + ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), + ('wp', UINT, 100, 'random walk with probability wp / 1024'), + ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), + ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), + ('restart_base', UINT, 100, 'base restart interval given by moves per run'), + ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), + ('early_prune', BOOL, 1, 'use early pruning for score prediction'), + ('random_offset', BOOL, 1, 'use random offset for candidate evaluation'), + ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), + ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), + ('random_seed', UINT, 0, 'random seed') + )) diff --git a/src/util/lp/CMakeLists.txt b/src/util/lp/CMakeLists.txt index ca8683434..70c5f9e3b 100644 --- a/src/util/lp/CMakeLists.txt +++ b/src/util/lp/CMakeLists.txt @@ -19,7 +19,7 @@ z3_add_component(lp lu_instances.cpp matrix_instances.cpp permutation_matrix_instances.cpp - quick_xplain.cpp + quick_xplain.cpp row_eta_matrix_instances.cpp scaler_instances.cpp sparse_matrix_instances.cpp diff --git a/src/util/lp/lp_core_solver_base.hpp b/src/util/lp/lp_core_solver_base.hpp index fa1c95850..b49dd0638 100644 --- a/src/util/lp/lp_core_solver_base.hpp +++ b/src/util/lp/lp_core_solver_base.hpp @@ -98,8 +98,8 @@ pivot_for_tableau_on_basis() { // i is the pivot row, and j is the pivot column template void lp_core_solver_base:: pivot_to_reduced_costs_tableau(unsigned i, unsigned j) { - if (j >= m_d.size()) - return; + if (j >= m_d.size()) + return; T &a = m_d[j]; if (is_zero(a)) return; diff --git a/src/util/lp/lp_primal_core_solver_tableau.h b/src/util/lp/lp_primal_core_solver_tableau.h index 97fa2f9da..5c7d4d2c2 100644 --- a/src/util/lp/lp_primal_core_solver_tableau.h +++ b/src/util/lp/lp_primal_core_solver_tableau.h @@ -318,7 +318,7 @@ template void lp_primal_core_solver::init_run_tab this->m_basis_sort_counter = 0; // to initiate the sort of the basis this->set_total_iterations(0); this->iters_with_no_cost_growing() = 0; - SASSERT(this->inf_set_is_correct()); + SASSERT(this->inf_set_is_correct()); if (this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) return; if (this->m_settings.backup_costs) diff --git a/src/util/lp/static_matrix.hpp b/src/util/lp/static_matrix.hpp index d8681ff93..846c2a19f 100644 --- a/src/util/lp/static_matrix.hpp +++ b/src/util/lp/static_matrix.hpp @@ -48,9 +48,9 @@ template bool static_matrix::pivot_row_to_row_giv SASSERT(i < row_count() && ii < column_count()); SASSERT(i != ii); - m_became_zeros.reset(); + m_became_zeros.reset(); T alpha = -get_val(c); - SASSERT(!is_zero(alpha)); + SASSERT(!is_zero(alpha)); auto & ii_row_vals = m_rows[ii]; remove_element(ii_row_vals, ii_row_vals[c.m_offset]); scan_row_ii_to_offset_vector(ii); @@ -61,7 +61,7 @@ template bool static_matrix::pivot_row_to_row_giv unsigned j = iv.m_j; if (j == pivot_col) continue; T alv = alpha * iv.m_value; - SASSERT(!is_zero(iv.m_value)); + SASSERT(!is_zero(iv.m_value)); int j_offs = m_vector_of_row_offsets[j]; if (j_offs == -1) { // it is a new element add_new_element(ii, j, alv); From 085df4a0a01e5ed1ae507ea49eb9c8a8af4e2cbc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 17:52:31 +0100 Subject: [PATCH 298/488] removed temp file --- src/tactic/sls/.#sls_params.pyg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/tactic/sls/.#sls_params.pyg diff --git a/src/tactic/sls/.#sls_params.pyg b/src/tactic/sls/.#sls_params.pyg deleted file mode 100644 index 50991f6f4..000000000 --- a/src/tactic/sls/.#sls_params.pyg +++ /dev/null @@ -1 +0,0 @@ -winte@WINTERMUTE.13536:1505663874 \ No newline at end of file From 60c6249912a1fc8183a5f561f32ec455edfc2d10 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 18:09:10 +0100 Subject: [PATCH 299/488] Removed unused variable --- src/ast/rewriter/fpa_rewriter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 09307cbf2..6420dd968 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -772,7 +772,6 @@ br_status fpa_rewriter::mk_to_bv(func_decl * f, expr * arg1, expr * arg2, bool i if (m_util.is_rm_numeral(arg1, rmv) && m_util.is_numeral(arg2, v)) { - const mpf & x = v.get(); if (m_fm.is_nan(v) || m_fm.is_inf(v)) return mk_to_bv_unspecified(f, result); From b9494fe3c01f445d9523975763b1736c882c1689 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 18:09:43 +0100 Subject: [PATCH 300/488] Tabs, whitespace --- src/smt/database.smt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/smt/database.smt b/src/smt/database.smt index 2f5e5e1c9..27955badf 100644 --- a/src/smt/database.smt +++ b/src/smt/database.smt @@ -11,7 +11,7 @@ :formula (forall (a Int) (i Int) (e Int) (= (?select (?store a i e) i) e) :pats { (?store a i e) } - :weight { 0 }) + :weight { 0 }) :formula (forall (a Int) (i Int) (j Int) (e Int) (or (= i j) (= (?select (?store a i e) j) (?select a j))) From c275d4ddca7f09c78f4e6f8a55c1f03fde42c9f3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 17 Sep 2017 18:33:40 +0100 Subject: [PATCH 301/488] typo --- src/api/java/Context.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 986736fb6..72866a0ba 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -2070,7 +2070,7 @@ public class Context implements AutoCloseable { */ public ReExpr mkComplement(ReExpr re) { - checkContextMatchb(re); + checkContextMatch(re); return (ReExpr) Expr.create(this, Native.mkReComplement(nCtx(), re.getNativeObject())); } From cf86e4622946156e6fd65abeb5693088c1227cc3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 17 Sep 2017 15:10:50 -0700 Subject: [PATCH 302/488] check for datatype selectors when model validation fails Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 14 +++++++----- src/smt/proto_model/datatype_factory.cpp | 28 ++++++++++++------------ 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 0a61a5ce6..14618887a 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1609,12 +1609,16 @@ void cmd_context::set_diagnostic_stream(char const * name) { } } -struct contains_array_op_proc { +struct contains_underspecified_op_proc { struct found {}; family_id m_array_fid; - contains_array_op_proc(ast_manager & m):m_array_fid(m.mk_family_id("array")) {} + datatype_util m_dt; + + contains_underspecified_op_proc(ast_manager & m):m_array_fid(m.mk_family_id("array")), m_dt(m) {} void operator()(var * n) {} void operator()(app * n) { + if (m_dt.is_accessor(n->get_decl())) + throw found(); if (n->get_family_id() != m_array_fid) return; decl_kind k = n->get_decl_kind(); @@ -1713,7 +1717,7 @@ void cmd_context::validate_model() { p.set_bool("completion", true); model_evaluator evaluator(*(md.get()), p); evaluator.set_expand_array_equalities(false); - contains_array_op_proc contains_array(m()); + contains_underspecified_op_proc contains_underspecified(m()); { scoped_rlimit _rlimit(m().limit(), 0); cancel_eh eh(m().limit()); @@ -1739,9 +1743,9 @@ void cmd_context::validate_model() { continue; } try { - for_each_expr(contains_array, r); + for_each_expr(contains_underspecified, r); } - catch (contains_array_op_proc::found) { + catch (contains_underspecified_op_proc::found) { continue; } TRACE("model_validate", model_smt2_pp(tout, *this, *(md.get()), 0);); diff --git a/src/smt/proto_model/datatype_factory.cpp b/src/smt/proto_model/datatype_factory.cpp index 03f008fe6..550b694da 100644 --- a/src/smt/proto_model/datatype_factory.cpp +++ b/src/smt/proto_model/datatype_factory.cpp @@ -38,7 +38,7 @@ expr * datatype_factory::get_some_value(sort * s) { } expr * r = m_manager.mk_app(c, args.size(), args.c_ptr()); register_value(r); - TRACE("datatype_factory", tout << mk_pp(r, m_util.get_manager()) << "\n";); + TRACE("datatype", tout << mk_pp(r, m_util.get_manager()) << "\n";); return r; } @@ -48,7 +48,7 @@ expr * datatype_factory::get_some_value(sort * s) { expr * datatype_factory::get_last_fresh_value(sort * s) { expr * val = 0; if (m_last_fresh_value.find(s, val)) { - TRACE("datatype_factory", tout << "cached fresh value: " << mk_pp(val, m_manager) << "\n";); + TRACE("datatype", tout << "cached fresh value: " << mk_pp(val, m_manager) << "\n";); return val; } value_set * set = get_value_set(s); @@ -68,7 +68,7 @@ bool datatype_factory::is_subterm_of_last_value(app* e) { } contains_app contains(m_manager, e); bool result = contains(last); - TRACE("datatype_factory", tout << mk_pp(e, m_manager) << " in " << mk_pp(last, m_manager) << " " << result << "\n";); + TRACE("datatype", tout << mk_pp(e, m_manager) << " in " << mk_pp(last, m_manager) << " " << result << "\n";); return result; } @@ -126,7 +126,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) { m_last_fresh_value.insert(s, new_value); } } - TRACE("datatype_factory", tout << "almost fresh: " << mk_pp(new_value, m_manager) << "\n";); + TRACE("datatype", tout << "almost fresh: " << mk_pp(new_value, m_manager) << "\n";); return new_value; } } @@ -136,7 +136,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) { expr * datatype_factory::get_fresh_value(sort * s) { - TRACE("datatype_factory", tout << "generating fresh value for: " << s->get_name() << "\n";); + TRACE("datatype", tout << "generating fresh value for: " << s->get_name() << "\n";); value_set * set = get_value_set(s); // Approach 0) // if no value for s was generated so far, then used get_some_value @@ -144,7 +144,7 @@ expr * datatype_factory::get_fresh_value(sort * s) { expr * val = get_some_value(s); if (m_util.is_recursive(s)) m_last_fresh_value.insert(s, val); - TRACE("datatype_factory", tout << "0. result: " << mk_pp(val, m_manager) << "\n";); + TRACE("datatype", tout << "0. result: " << mk_pp(val, m_manager) << "\n";); return val; } // Approach 1) @@ -171,13 +171,13 @@ expr * datatype_factory::get_fresh_value(sort * s) { } expr_ref new_value(m_manager); new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr()); - CTRACE("datatype_factory", found_fresh_arg && set->contains(new_value), tout << mk_pp(new_value, m_manager) << "\n";); + CTRACE("datatype", found_fresh_arg && set->contains(new_value), tout << mk_pp(new_value, m_manager) << "\n";); SASSERT(!found_fresh_arg || !set->contains(new_value)); if (!set->contains(new_value)) { register_value(new_value); if (m_util.is_recursive(s)) m_last_fresh_value.insert(s, new_value); - TRACE("datatype_factory", tout << "1. result: " << mk_pp(new_value, m_manager) << "\n";); + TRACE("datatype", tout << "1. result: " << mk_pp(new_value, m_manager) << "\n";); return new_value; } } @@ -188,16 +188,16 @@ expr * datatype_factory::get_fresh_value(sort * s) { if (m_util.is_recursive(s)) { while(true) { ++num_iterations; - TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";); + TRACE("datatype", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";); ptr_vector const & constructors = *m_util.get_datatype_constructors(s); for (func_decl * constructor : constructors) { expr_ref_vector args(m_manager); bool found_sibling = false; unsigned num = constructor->get_arity(); - TRACE("datatype_factory", tout << "checking constructor: " << constructor->get_name() << "\n";); + TRACE("datatype", tout << "checking constructor: " << constructor->get_name() << "\n";); for (unsigned i = 0; i < num; i++) { sort * s_arg = constructor->get_domain(i); - TRACE("datatype_factory", tout << mk_pp(s, m_manager) << " " + TRACE("datatype", tout << mk_pp(s, m_manager) << " " << mk_pp(s_arg, m_manager) << " are_siblings " << m_util.are_siblings(s, s_arg) << " is_datatype " << m_util.is_datatype(s_arg) << " found_sibling " @@ -212,7 +212,7 @@ expr * datatype_factory::get_fresh_value(sort * s) { maybe_new_arg = get_fresh_value(s_arg); } if (!maybe_new_arg) { - TRACE("datatype_factory", + TRACE("datatype", tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";); maybe_new_arg = m_model.get_some_value(s_arg); found_sibling = false; @@ -229,11 +229,11 @@ expr * datatype_factory::get_fresh_value(sort * s) { if (found_sibling) { expr_ref new_value(m_manager); new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr()); - TRACE("datatype_factory", tout << "potential new value: " << mk_pp(new_value, m_manager) << "\n";); + TRACE("datatype", tout << "potential new value: " << mk_pp(new_value, m_manager) << "\n";); m_last_fresh_value.insert(s, new_value); if (!set->contains(new_value)) { register_value(new_value); - TRACE("datatype_factory", tout << "2. result: " << mk_pp(new_value, m_manager) << "\n";); + TRACE("datatype", tout << "2. result: " << mk_pp(new_value, m_manager) << "\n";); return new_value; } } From 9b01a5153eb8a09377e0d71f66094779f7119ba3 Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Mon, 18 Sep 2017 14:44:05 -0400 Subject: [PATCH 303/488] fix generation of symbolic automata with no moves but accepting initial state --- src/math/automata/symbolic_automata_def.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/math/automata/symbolic_automata_def.h b/src/math/automata/symbolic_automata_def.h index c89080d3d..3be6a1da0 100644 --- a/src/math/automata/symbolic_automata_def.h +++ b/src/math/automata/symbolic_automata_def.h @@ -451,7 +451,15 @@ typename symbolic_automata::automaton_t* symbolic_automata::mk_produ } } if (mvs1.empty()) { - return alloc(automaton_t, m); + if (a.is_final_state(a.init()) && b.is_final_state(b.init())) { + // special case: automaton has no moves, but the initial state is final on both sides + // this results in the automaton which accepts the empty sequence and nothing else + final.clear(); + final.push_back(0); + return alloc(automaton_t, m, 0, final, mvs1); + } else { + return alloc(automaton_t, m); + } } else { return alloc(automaton_t, m, 0, final, mvs1); From 6ddc5495570a15547f5f098dafd7e9de11c68ac1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 18 Sep 2017 12:21:01 -0700 Subject: [PATCH 304/488] fix #1258 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_lra.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index bd8572d73..0bb76cd90 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -2335,7 +2335,12 @@ namespace smt { lp::var_index vi = m_theory_var2var_index.get(v, UINT_MAX); vector > coeffs; rational coeff; - if (m_solver->is_term(vi)) { + if (vi == UINT_MAX) { + has_shared = false; + blocker = m.mk_false(); + return inf_eps(rational::one(), inf_rational()); + } + else if (m_solver->is_term(vi)) { const lp::lar_term& term = m_solver->get_term(vi); for (auto & ti : term.m_coeffs) { coeffs.push_back(std::make_pair(ti.second, ti.first)); From 43e47271f7e935764070db3572cd16ca590f0832 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 18 Sep 2017 15:58:09 -0700 Subject: [PATCH 305/488] have quantified tactics work with bound Boolean variables. Adding stubs for match Signed-off-by: Nikolaj Bjorner --- src/parsers/smt2/smt2parser.cpp | 58 +++++++++++++++++++++++++++++++- src/tactic/arith/probe_arith.cpp | 31 +++++++++-------- 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 681c3d597..fd32a63cc 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -108,6 +108,7 @@ namespace smt2 { symbol m_check_sat_assuming; symbol m_define_fun_rec; symbol m_define_funs_rec; + symbol m_match; symbol m_underscore; typedef std::pair named_expr; @@ -135,7 +136,7 @@ namespace smt2 { typedef psort_frame sort_frame; - enum expr_frame_kind { EF_APP, EF_LET, EF_LET_DECL, EF_QUANT, EF_ATTR_EXPR, EF_PATTERN }; + enum expr_frame_kind { EF_APP, EF_LET, EF_LET_DECL, EF_QUANT, EF_MATCH, EF_ATTR_EXPR, EF_PATTERN }; struct expr_frame { expr_frame_kind m_kind; @@ -172,6 +173,12 @@ namespace smt2 { m_expr_spos(expr_spos) {} }; + struct match_frame : public expr_frame { + match_frame(): + expr_frame(EF_MATCH) + {} + }; + struct let_frame : public expr_frame { bool m_in_decls; unsigned m_sym_spos; @@ -389,6 +396,7 @@ namespace smt2 { bool curr_id_is_underscore() const { SASSERT(curr_is_identifier()); return curr_id() == m_underscore; } bool curr_id_is_as() const { SASSERT(curr_is_identifier()); return curr_id() == m_as; } + bool curr_id_is_match() const { SASSERT(curr_is_identifier()); return curr_id() == m_match; } bool curr_id_is_forall() const { SASSERT(curr_is_identifier()); return curr_id() == m_forall; } bool curr_id_is_exists() const { SASSERT(curr_is_identifier()); return curr_id() == m_exists; } bool curr_id_is_bang() const { SASSERT(curr_is_identifier()); return curr_id() == m_bang; } @@ -1273,6 +1281,47 @@ namespace smt2 { throw parser_exception("invalid quantifier, list of sorted variables is empty"); } + /** + * SMT-LIB 2.6 pattern matches are of the form + * (match t ((p1 t1) ··· (pm+1 tm+1))) + */ + void push_match_frame() { + next(); +#if 0 + // just use the stack for parsing these for now. + void * mem = m_stack.allocate(sizeof(match_frame)); + new (mem) match_frame(); + m_num_expr_frames++; +#endif + parse_expr(); + expr_ref t(expr_stack().back(), m()); + expr_stack().pop_back(); + expr_ref_vector patterns(m()), cases(m()); + + check_lparen_next("pattern bindings should be enclosed in a parenthesis"); + while (!curr_is_rparen()) { + check_lparen_next("invalid pattern binding, '(' expected"); + parse_expr(); // TBD need to parse a pattern here. The sort of 't' provides context for how to interpret _. + patterns.push_back(expr_stack().back()); + expr_stack().pop_back(); + parse_expr(); + cases.push_back(expr_stack().back()); + expr_stack().pop_back(); + check_rparen_next("invalid pattern binding, ')' expected"); + } + next(); + expr_stack().push_back(compile_patterns(t, patterns, cases)); + } + + expr_ref compile_patterns(expr* t, expr_ref_vector const& patterns, expr_ref_vector const& cases) { + NOT_IMPLEMENTED_YET(); + return expr_ref(m()); + } + + void pop_match_frame(match_frame * fr) { + + } + symbol parse_indexed_identifier_core() { check_underscore_next("invalid indexed identifier, '_' expected"); check_identifier("invalid indexed identifier, symbol expected"); @@ -1599,6 +1648,9 @@ namespace smt2 { else if (curr_id_is_root_obj()) { parse_root_obj(); } + else if (curr_id_is_match()) { + push_match_frame(); + } else { push_app_frame(); } @@ -1776,6 +1828,9 @@ namespace smt2 { case EF_QUANT: pop_quant_frame(static_cast(fr)); break; + case EF_MATCH: + pop_match_frame(static_cast(fr)); + break; case EF_ATTR_EXPR: pop_attr_expr_frame(static_cast(fr)); break; @@ -2730,6 +2785,7 @@ namespace smt2 { m_check_sat_assuming("check-sat-assuming"), m_define_fun_rec("define-fun-rec"), m_define_funs_rec("define-funs-rec"), + m_match("match"), m_underscore("_"), m_num_open_paren(0), m_current_file(filename) { diff --git a/src/tactic/arith/probe_arith.cpp b/src/tactic/arith/probe_arith.cpp index c2de64484..edd4483e7 100644 --- a/src/tactic/arith/probe_arith.cpp +++ b/src/tactic/arith/probe_arith.cpp @@ -392,24 +392,27 @@ struct is_non_nira_functor { is_non_nira_functor(ast_manager & _m, bool _int, bool _real, bool _quant, bool linear):m(_m), u(m), m_int(_int), m_real(_real), m_quant(_quant), m_linear(linear) {} - void throw_found() { + void throw_found(expr* e) { + TRACE("probe", tout << expr_ref(e, m) << ": " << sort_ref(m.get_sort(e), m) << "\n";); throw found(); } void operator()(var * x) { if (!m_quant) - throw_found(); + throw_found(x); sort * s = x->get_sort(); if (m_int && u.is_int(s)) return; if (m_real && u.is_real(s)) return; - throw_found(); + if (m.is_bool(s)) + return; + throw_found(x); } - void operator()(quantifier *) { + void operator()(quantifier * q) { if (!m_quant) - throw_found(); + throw_found(q); } bool compatible_sort(app * n) const { @@ -424,7 +427,7 @@ struct is_non_nira_functor { void operator()(app * n) { if (!compatible_sort(n)) - throw_found(); + throw_found(n); family_id fid = n->get_family_id(); if (fid == m.get_basic_family_id()) return; @@ -437,39 +440,39 @@ struct is_non_nira_functor { case OP_MUL: if (m_linear) { if (n->get_num_args() != 2) - throw_found(); + throw_found(n); if (!u.is_numeral(n->get_arg(0))) - throw_found(); + throw_found(n); } return; case OP_IDIV: case OP_DIV: case OP_REM: case OP_MOD: if (m_linear && !u.is_numeral(n->get_arg(1))) - throw_found(); + throw_found(n); return; case OP_IS_INT: if (m_real) - throw_found(); + throw_found(n); return; case OP_TO_INT: case OP_TO_REAL: return; case OP_POWER: if (m_linear) - throw_found(); + throw_found(n); return; case OP_IRRATIONAL_ALGEBRAIC_NUM: if (m_linear || !m_real) - throw_found(); + throw_found(n); return; default: - throw_found(); + throw_found(n); } return; } if (is_uninterp_const(n)) return; - throw_found(); + throw_found(n); } }; From caa02c3c0296fb531488b8549f36424a1656cc1a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 19 Sep 2017 19:39:02 -0700 Subject: [PATCH 306/488] add match expression construct to SMT-LIB2.6 frontend Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt2_pp.cpp | 2 + src/ast/rewriter/rewriter_def.h | 4 + src/cmd_context/cmd_context.cpp | 6 +- src/model/func_interp.cpp | 1 - src/parsers/smt2/smt2parser.cpp | 216 +++++++++++++++++++++++++++----- src/smt/smt_context.cpp | 10 +- 6 files changed, 203 insertions(+), 36 deletions(-) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index abb4ae959..cad2265c8 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -584,6 +584,8 @@ class smt2_printer { string_buffer<> buf; buf.append("(:var "); buf.append(v->get_idx()); + buf.append(" "); + buf.append(v->get_sort()->get_name().str().c_str()); buf.append(")"); f = mk_string(m(), buf.c_str()); } diff --git a/src/ast/rewriter/rewriter_def.h b/src/ast/rewriter/rewriter_def.h index 42f268379..f5f72674d 100644 --- a/src/ast/rewriter/rewriter_def.h +++ b/src/ast/rewriter/rewriter_def.h @@ -42,6 +42,10 @@ void rewriter_tpl::process_var(var * v) { unsigned index = m_bindings.size() - idx - 1; var * r = (var*)(m_bindings[index]); if (r != 0) { + CTRACE("rewriter", v->get_sort() != m().get_sort(r), + tout << expr_ref(v, m()) << ":" << sort_ref(v->get_sort(), m()) << " != " << expr_ref(r, m()) << ":" << sort_ref(m().get_sort(r), m()); + tout << "index " << index << " bindings " << m_bindings.size() << "\n"; + display_bindings(tout);); SASSERT(v->get_sort() == m().get_sort(r)); if (!is_ground(r) && m_shifts[index] != m_bindings.size()) { diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 14618887a..3889d6205 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -202,7 +202,7 @@ func_decl * func_decls::find(unsigned arity, sort * const * domain, sort * range if (f->get_arity() != arity) continue; unsigned i = 0; - for (i = 0; i < arity; i++) { + for (i = 0; domain && i < arity; i++) { if (f->get_domain(i) != domain[i]) break; } @@ -937,7 +937,7 @@ static builtin_decl const & peek_builtin_decl(builtin_decl const & first, family func_decl * cmd_context::find_func_decl(symbol const & s, unsigned num_indices, unsigned const * indices, unsigned arity, sort * const * domain, sort * range) const { builtin_decl d; - if (m_builtin_decls.find(s, d)) { + if (domain && m_builtin_decls.find(s, d)) { family_id fid = d.m_fid; decl_kind k = d.m_decl; // Hack: if d.m_next != 0, we use domain[0] (if available) to decide which plugin we use. @@ -961,7 +961,7 @@ func_decl * cmd_context::find_func_decl(symbol const & s, unsigned num_indices, return f; } - if (contains_macro(s, arity, domain)) + if (domain && contains_macro(s, arity, domain)) throw cmd_exception("invalid function declaration reference, named expressions (aka macros) cannot be referenced ", s); if (num_indices > 0) diff --git a/src/model/func_interp.cpp b/src/model/func_interp.cpp index 2ead63e0a..6699ef0e2 100644 --- a/src/model/func_interp.cpp +++ b/src/model/func_interp.cpp @@ -140,7 +140,6 @@ void func_interp::set_else(expr * e) { return; reset_interp_cache(); - ptr_vector args; while (e && is_fi_entry_expr(e, args)) { TRACE("func_interp", tout << "fi entry expr: " << mk_ismt2_pp(e, m()) << std::endl;); diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index fd32a63cc..6b62edcbd 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -24,6 +24,7 @@ Revision History: #include "ast/ast_pp.h" #include "ast/well_sorted.h" #include "ast/rewriter/rewriter.h" +#include "ast/rewriter/var_subst.h" #include "ast/has_free_vars.h" #include "ast/ast_smt2_pp.h" #include "parsers/smt2/smt2parser.h" @@ -68,6 +69,7 @@ namespace smt2 { scoped_ptr m_bv_util; scoped_ptr m_arith_util; + scoped_ptr m_datatype_util; scoped_ptr m_seq_util; scoped_ptr m_pattern_validator; scoped_ptr m_var_shifter; @@ -136,7 +138,7 @@ namespace smt2 { typedef psort_frame sort_frame; - enum expr_frame_kind { EF_APP, EF_LET, EF_LET_DECL, EF_QUANT, EF_MATCH, EF_ATTR_EXPR, EF_PATTERN }; + enum expr_frame_kind { EF_APP, EF_LET, EF_LET_DECL, EF_MATCH, EF_QUANT, EF_ATTR_EXPR, EF_PATTERN }; struct expr_frame { expr_frame_kind m_kind; @@ -174,9 +176,7 @@ namespace smt2 { }; struct match_frame : public expr_frame { - match_frame(): - expr_frame(EF_MATCH) - {} + match_frame():expr_frame(EF_MATCH) {} }; struct let_frame : public expr_frame { @@ -282,6 +282,12 @@ namespace smt2 { return *(m_arith_util.get()); } + datatype_util & dtutil() { + if (m_datatype_util.get() == 0) + m_datatype_util = alloc(datatype_util, m()); + return *(m_datatype_util.get()); + } + seq_util & sutil() { if (m_seq_util.get() == 0) m_seq_util = alloc(seq_util, m()); @@ -1266,6 +1272,23 @@ namespace smt2 { return num; } + void push_let_frame() { + next(); + check_lparen_next("invalid let declaration, '(' expected"); + void * mem = m_stack.allocate(sizeof(let_frame)); + new (mem) let_frame(symbol_stack().size(), expr_stack().size()); + m_num_expr_frames++; + } + + void push_bang_frame(expr_frame * curr) { + TRACE("consume_attributes", tout << "begin bang, expr_stack.size(): " << expr_stack().size() << "\n";); + next(); + void * mem = m_stack.allocate(sizeof(attr_expr_frame)); + new (mem) attr_expr_frame(curr, symbol_stack().size(), expr_stack().size()); + m_num_expr_frames++; + } + + void push_quant_frame(bool is_forall) { SASSERT(curr_is_identifier()); SASSERT(curr_id_is_forall() || curr_id_is_exists()); @@ -1286,40 +1309,179 @@ namespace smt2 { * (match t ((p1 t1) ··· (pm+1 tm+1))) */ void push_match_frame() { + SASSERT(curr_is_identifier()); + SASSERT(curr_id() == m_match); next(); -#if 0 - // just use the stack for parsing these for now. - void * mem = m_stack.allocate(sizeof(match_frame)); + void * mem = m_stack.allocate(sizeof(match_frame)); new (mem) match_frame(); - m_num_expr_frames++; -#endif + unsigned num_frames = m_num_expr_frames; + parse_expr(); expr_ref t(expr_stack().back(), m()); expr_stack().pop_back(); expr_ref_vector patterns(m()), cases(m()); + sort* srt = m().get_sort(t); check_lparen_next("pattern bindings should be enclosed in a parenthesis"); while (!curr_is_rparen()) { + m_env.begin_scope(); + unsigned num_bindings = m_num_bindings; check_lparen_next("invalid pattern binding, '(' expected"); - parse_expr(); // TBD need to parse a pattern here. The sort of 't' provides context for how to interpret _. + parse_match_pattern(srt); patterns.push_back(expr_stack().back()); expr_stack().pop_back(); parse_expr(); cases.push_back(expr_stack().back()); expr_stack().pop_back(); + m_num_bindings = num_bindings; + m_env.end_scope(); check_rparen_next("invalid pattern binding, ')' expected"); } next(); + m_num_expr_frames = num_frames + 1; expr_stack().push_back(compile_patterns(t, patterns, cases)); } - expr_ref compile_patterns(expr* t, expr_ref_vector const& patterns, expr_ref_vector const& cases) { - NOT_IMPLEMENTED_YET(); - return expr_ref(m()); + void pop_match_frame(match_frame* fr) { + m_stack.deallocate(fr); + m_num_expr_frames--; } - void pop_match_frame(match_frame * fr) { + expr_ref compile_patterns(expr* t, expr_ref_vector const& patterns, expr_ref_vector const& cases) { + expr_ref result(m()); + var_subst sub(m(), false); + TRACE("parse_expr", tout << "term\n" << expr_ref(t, m()) << "\npatterns\n" << patterns << "\ncases\n" << cases << "\n";); + for (unsigned i = patterns.size(); i > 0; ) { + --i; + expr_ref_vector subst(m()); + expr_ref cond = bind_match(t, patterns[i], subst); + expr_ref new_case(m()); + if (subst.empty()) { + new_case = cases[i]; + } + else { + sub(cases[i], subst.size(), subst.c_ptr(), new_case); + inv_var_shifter inv(m()); + inv(new_case, subst.size(), new_case); + } + if (result) { + result = m().mk_ite(cond, new_case, result); + } + else { + // pattern match binding is ignored. + result = new_case; + } + } + TRACE("parse_expr", tout << result << "\n";); + return result; + } + // compute match condition and substitution + // t is shifted by size of subst. + expr_ref bind_match(expr* t, expr* pattern, expr_ref_vector& subst) { + expr_ref tsh(m()); + if (is_var(pattern)) { + shifter()(t, 1, tsh); + subst.push_back(tsh); + return expr_ref(m().mk_true(), m()); + } + else { + SASSERT(is_app(pattern)); + func_decl * f = to_app(pattern)->get_decl(); + func_decl * r = dtutil().get_constructor_recognizer(f); + ptr_vector const * acc = dtutil().get_constructor_accessors(f); + shifter()(t, acc->size(), tsh); + for (func_decl* a : *acc) { + subst.push_back(m().mk_app(a, tsh)); + } + return expr_ref(m().mk_app(r, t), m()); + } + } + + /** + * parse a match pattern + * (C x1 .... xn) + * C + * _ + * x + */ + + bool parse_constructor_pattern(sort * srt) { + if (!curr_is_lparen()) { + return false; + } + next(); + svector vars; + expr_ref_vector args(m()); + symbol C(check_identifier_next("constructor symbol expected")); + while (!curr_is_rparen()) { + symbol v(check_identifier_next("variable symbol expected")); + if (v != m_underscore && vars.contains(v)) { + throw parser_exception("unexpected repeated variable in pattern expression"); + } + vars.push_back(v); + } + next(); + + // now have C, vars + // look up constructor C, + // create bound variables based on constructor type. + // store expression in expr_stack(). + // ensure that bound variables are adjusted to vars + + func_decl* f = m_ctx.find_func_decl(C, 0, nullptr, vars.size(), nullptr, srt); + if (!f) { + throw parser_exception("expecting a constructor that has been declared"); + } + if (!dtutil().is_constructor(f)) { + throw parser_exception("expecting a constructor"); + } + if (f->get_arity() != vars.size()) { + throw parser_exception("mismatching number of variables supplied to constructor"); + } + m_num_bindings += vars.size(); + for (unsigned i = 0; i < vars.size(); ++i) { + var * v = m().mk_var(i, f->get_domain(i)); + args.push_back(v); + if (vars[i] != m_underscore) { + m_env.insert(vars[i], local(v, m_num_bindings)); + } + } + expr_stack().push_back(m().mk_app(f, args.size(), args.c_ptr())); + return true; + } + + void parse_match_pattern(sort* srt) { + if (parse_constructor_pattern(srt)) { + // done + } + else if (curr_id() == m_underscore) { + // we have a wild-card. + // store dummy variable in expr_stack() + next(); + var* v = m().mk_var(0, srt); + expr_stack().push_back(v); + } + else { + symbol xC(check_identifier_next("constructor symbol or variable expected")); + // check if xC is a constructor, otherwise make it a variable + // of sort srt. + try { + func_decl* f = m_ctx.find_func_decl(xC, 0, nullptr, 0, nullptr, srt); + if (!dtutil().is_constructor(f)) { + throw parser_exception("expecting a constructor, got a previously declared function"); + } + if (f->get_arity() > 0) { + throw parser_exception("constructor expects arguments, but no arguments were supplied in pattern"); + } + expr_stack().push_back(m().mk_const(f)); + } + catch (cmd_exception &) { + var* v = m().mk_var(0, srt); + expr_stack().push_back(v); + m_env.insert(xC, local(v, m_num_bindings++)); + } + } } symbol parse_indexed_identifier_core() { @@ -1613,8 +1775,7 @@ namespace smt2 { new (mem) app_frame(f, expr_spos, param_spos, has_as); m_num_expr_frames++; } - - // return true if a new frame was created. + void push_expr_frame(expr_frame * curr) { SASSERT(curr_is_lparen()); next(); @@ -1622,11 +1783,7 @@ namespace smt2 { if (curr_is_identifier()) { TRACE("push_expr_frame", tout << "push_expr_frame(), curr_id(): " << curr_id() << "\n";); if (curr_id_is_let()) { - next(); - check_lparen_next("invalid let declaration, '(' expected"); - void * mem = m_stack.allocate(sizeof(let_frame)); - new (mem) let_frame(symbol_stack().size(), expr_stack().size()); - m_num_expr_frames++; + push_let_frame(); } else if (curr_id_is_forall()) { push_quant_frame(true); @@ -1635,14 +1792,9 @@ namespace smt2 { push_quant_frame(false); } else if (curr_id_is_bang()) { - TRACE("consume_attributes", tout << "begin bang, expr_stack.size(): " << expr_stack().size() << "\n";); - next(); - void * mem = m_stack.allocate(sizeof(attr_expr_frame)); - new (mem) attr_expr_frame(curr, symbol_stack().size(), expr_stack().size()); - m_num_expr_frames++; + push_bang_frame(curr); } else if (curr_id_is_as() || curr_id_is_underscore()) { - TRACE("push_expr_frame", tout << "push_expr_frame(): parse_qualified_name\n";); parse_qualified_name(); } else if (curr_id_is_root_obj()) { @@ -1825,12 +1977,12 @@ namespace smt2 { m_stack.deallocate(static_cast(fr)); m_num_expr_frames--; break; - case EF_QUANT: - pop_quant_frame(static_cast(fr)); - break; case EF_MATCH: pop_match_frame(static_cast(fr)); break; + case EF_QUANT: + pop_quant_frame(static_cast(fr)); + break; case EF_ATTR_EXPR: pop_attr_expr_frame(static_cast(fr)); break; @@ -2287,8 +2439,10 @@ namespace smt2 { throw cmd_exception("invalid assert command, expression required as argument"); } expr * f = expr_stack().back(); - if (!m().is_bool(f)) + if (!m().is_bool(f)) { + TRACE("smt2parser", tout << expr_ref(f, m()) << "\n";); throw cmd_exception("invalid assert command, term is not Boolean"); + } if (f == m_last_named_expr.second) { m_ctx.assert_expr(m_last_named_expr.first, f); } diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index eef84f773..901f4b5ac 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -4374,9 +4374,17 @@ namespace smt { expr* fn = to_app(q->get_pattern(0))->get_arg(0); expr* body = to_app(q->get_pattern(1))->get_arg(0); SASSERT(is_app(fn)); + // reverse argument order so that variable 0 starts at the beginning. + expr_ref_vector subst(m); + for (expr* arg : *to_app(fn)) { + subst.push_back(arg); + } + expr_ref bodyr(m); + var_subst sub(m, false); + sub(body, subst.size(), subst.c_ptr(), bodyr); func_decl* f = to_app(fn)->get_decl(); func_interp* fi = alloc(func_interp, m, f->get_arity()); - fi->set_else(body); + fi->set_else(bodyr); m_model->register_decl(f, fi); } } From 93e08d9499c20dd23af35c4225b512b83abd86f2 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 19 Sep 2017 19:43:23 -0700 Subject: [PATCH 307/488] fix #1261 Signed-off-by: Nikolaj Bjorner --- src/smt/smt_solver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index e78c6388e..d624a5c9a 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -109,8 +109,10 @@ namespace smt { } virtual void assert_expr(expr * t, expr * a) { + if (m_name2assertion.contains(a)) { + throw default_exception("named assertion defined twice"); + } solver_na2as::assert_expr(t, a); - SASSERT(!m_name2assertion.contains(a)); get_manager().inc_ref(t); m_name2assertion.insert(a, t); } From cb15473d5b759b6973666f98693a5583d4f70cb1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 19 Sep 2017 20:02:41 -0700 Subject: [PATCH 308/488] remove type annotation from var printing Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt2_pp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index cad2265c8..e4a875005 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -584,8 +584,8 @@ class smt2_printer { string_buffer<> buf; buf.append("(:var "); buf.append(v->get_idx()); - buf.append(" "); - buf.append(v->get_sort()->get_name().str().c_str()); + //buf.append(" "); + //buf.append(v->get_sort()->get_name().str().c_str()); buf.append(")"); f = mk_string(m(), buf.c_str()); } From da2826b55e29317cef6db8bc07bfd0c6f0c0d788 Mon Sep 17 00:00:00 2001 From: Sebastian Buchwald Date: Wed, 20 Sep 2017 16:13:41 +0200 Subject: [PATCH 309/488] Fix warnings in C++ API When assertions are disabled, the compiler warns about unused function parameters. --- src/api/c++/z3++.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 6d8ff3b35..8938fb1b5 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -354,7 +354,7 @@ namespace z3 { Z3_error_code check_error() const { return m_ctx->check_error(); } friend void check_context(object const & a, object const & b); }; - inline void check_context(object const & a, object const & b) { assert(a.m_ctx == b.m_ctx); } + inline void check_context(object const & a, object const & b) { (void)a; (void)b; assert(a.m_ctx == b.m_ctx); } class symbol : public object { Z3_symbol m_sym; From 936c22a00b6ada5abc238d7b98fdf8b93a5aaaef Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 20 Sep 2017 09:44:38 -0700 Subject: [PATCH 310/488] add pattern match validation Signed-off-by: Nikolaj Bjorner --- src/parsers/smt2/smt2parser.cpp | 16 ++++++++++++++++ src/smt/mam.cpp | 4 ---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index 6b62edcbd..b4648f0d6 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -1351,6 +1351,7 @@ namespace smt2 { expr_ref result(m()); var_subst sub(m(), false); TRACE("parse_expr", tout << "term\n" << expr_ref(t, m()) << "\npatterns\n" << patterns << "\ncases\n" << cases << "\n";); + check_patterns(patterns, m().get_sort(t)); for (unsigned i = patterns.size(); i > 0; ) { --i; expr_ref_vector subst(m()); @@ -1376,6 +1377,21 @@ namespace smt2 { return result; } + void check_patterns(expr_ref_vector const& patterns, sort* s) { + if (!dtutil().is_datatype(s)) + throw parser_exception("pattern matching is only supported for algebraic datatypes"); + ptr_vector const& cons = *dtutil().get_datatype_constructors(s); + for (expr * arg : patterns) if (is_var(arg)) return; + if (patterns.size() < cons.size()) + throw parser_exception("non-exhaustive pattern match"); + ast_fast_mark1 marked; + for (expr * arg : patterns) + marked.mark(to_app(arg)->get_decl(), true); + for (func_decl * f : cons) + if (!marked.is_marked(f)) + throw parser_exception("a constructor is missing from pattern match"); + } + // compute match condition and substitution // t is shifted by size of subst. expr_ref bind_match(expr* t, expr* pattern, expr_ref_vector& subst) { diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index 2aa9d6095..a88ef1e0d 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -1753,10 +1753,6 @@ namespace smt { m_use_filters(use_filters) { } - context & get_context() { - return m_context; - } - /** \brief Create a new code tree for the given quantifier. From cc9f67267d30bf8909adf9894f9f0fba13f10444 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Sep 2017 20:16:09 +0100 Subject: [PATCH 311/488] Eliminated the remaining operator kinds for partially unspecified FP operators. --- src/api/z3_api.h | 17 -- src/ast/fpa/bv2fpa_converter.cpp | 4 +- src/ast/fpa/fpa2bv_converter.cpp | 288 +++++++++++------------------- src/ast/fpa/fpa2bv_converter.h | 19 +- src/ast/fpa/fpa2bv_rewriter.cpp | 12 +- src/ast/fpa_decl_plugin.cpp | 10 -- src/ast/fpa_decl_plugin.h | 18 +- src/ast/rewriter/fpa_rewriter.cpp | 76 ++------ src/smt/theory_fpa.cpp | 18 -- src/smt/theory_fpa.h | 3 - 10 files changed, 125 insertions(+), 340 deletions(-) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index bfc0b93a2..154b8eb3c 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -993,18 +993,6 @@ typedef enum 3 = 011 = Z3_OP_FPA_RM_TOWARD_NEGATIVE, 4 = 100 = Z3_OP_FPA_RM_TOWARD_ZERO. - - Z3_OP_FPA_MIN_I: The same as Z3_OP_FPA_MIN, but the arguments are - expected not to be zeroes with different signs. - - - Z3_OP_FPA_MAX_I: The same as Z3_OP_FPA_MAX, but the arguments are - expected not to be zeroes with different signs. - - - Z3_OP_FPA_MIN_UNSPECIFIED: The same as Z3_OP_FPA_MIN, but the - arguments are expected to be zeroes with different signs. - - - Z3_OP_FPA_MAX_UNSPECIFIED: The same as Z3_OP_FPA_MAX, but the - arguments are expected to be zeroes with different signs. - - Z3_OP_INTERNAL: internal (often interpreted) symbol, but no additional information is exposed. Tools may use the string representation of the function declaration to obtain more information. @@ -1291,13 +1279,8 @@ typedef enum { Z3_OP_FPA_TO_IEEE_BV, - Z3_OP_FPA_MIN_I, - Z3_OP_FPA_MAX_I, - Z3_OP_FPA_BVWRAP, Z3_OP_FPA_BV2RM, - Z3_OP_FPA_MIN_UNSPECIFIED, - Z3_OP_FPA_MAX_UNSPECIFIED, Z3_OP_INTERNAL, diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index 30d41bc53..93bd79571 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -62,8 +62,8 @@ bv2fpa_converter::bv2fpa_converter(ast_manager & m, fpa2bv_converter & conv) : m.inc_ref(it->m_key); m.inc_ref(it->m_value); } - for (obj_map >::iterator it = conv.m_min_max_specials.begin(); - it != conv.m_min_max_specials.end(); + for (obj_map >::iterator it = conv.m_min_max_ufs.begin(); + it != conv.m_min_max_ufs.end(); it++) { m_specials.insert(it->m_key, it->m_value); m.inc_ref(it->m_key); diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index bc0364994..f09ddcd42 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -230,39 +230,7 @@ void fpa2bv_converter::mk_var(unsigned base_inx, sort * srt, expr_ref & result) result = m_util.mk_fp(sgn, e, s); } -void fpa2bv_converter::mk_function_output(sort * rng, func_decl * fbv, expr * const * new_args, expr_ref & result) { - if (m_util.is_float(rng)) { - unsigned ebits = m_util.get_ebits(rng); - unsigned sbits = m_util.get_sbits(rng); - unsigned bv_sz = ebits + sbits; - - app_ref na(m); - na = m.mk_app(fbv, fbv->get_arity(), new_args); - result = m_util.mk_fp(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, na), - m_bv_util.mk_extract(bv_sz - 2, sbits - 1, na), - m_bv_util.mk_extract(sbits - 2, 0, na)); - } - else if (m_util.is_rm(rng)) { - app_ref na(m); - na = m.mk_app(fbv, fbv->get_arity(), new_args); - result = m_util.mk_bv2rm(na); - } - else - result = m.mk_app(fbv, fbv->get_arity(), new_args); -} - -func_decl * fpa2bv_converter::get_bv_uf(func_decl * f, sort * bv_rng, unsigned arity) { - func_decl * res; - if (!m_uf2bvuf.find(f, res)) { - res = m.mk_fresh_func_decl(f->get_name(), symbol("bv"), arity, f->get_domain(), bv_rng); - m_uf2bvuf.insert(f, res); - m.inc_ref(f); - m.inc_ref(res); - TRACE("fpa2bv", tout << "New UF func_decl: " << std::endl << mk_ismt2_pp(res, m) << std::endl;); - } - return res; -} -void fpa2bv_converter::mk_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result) +void fpa2bv_converter::mk_uf(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv", tout << "UF: " << mk_ismt2_pp(f, m) << std::endl; ); @@ -278,7 +246,7 @@ void fpa2bv_converter::mk_function(func_decl * f, unsigned num, expr * const * a unsigned sbits = m_util.get_sbits(rng); unsigned bv_sz = ebits+sbits; bv_rng = m_bv_util.mk_sort(bv_sz); - func_decl * bv_f = get_bv_uf(f, bv_rng, num); + func_decl * bv_f = mk_bv_uf(f, f->get_domain(), bv_rng); bv_app = m.mk_app(bv_f, num, args); flt_app = m_util.mk_fp(m_bv_util.mk_extract(bv_sz-1, bv_sz-1, bv_app), m_bv_util.mk_extract(sbits+ebits-2, sbits-1, bv_app), @@ -291,7 +259,7 @@ void fpa2bv_converter::mk_function(func_decl * f, unsigned num, expr * const * a sort_ref bv_rng(m); expr_ref new_eq(m); bv_rng = m_bv_util.mk_sort(3); - func_decl * bv_f = get_bv_uf(f, bv_rng, num); + func_decl * bv_f = mk_bv_uf(f, f->get_domain(), bv_rng); bv_app = m.mk_app(bv_f, num, args); flt_app = m_util.mk_bv2rm(bv_app); new_eq = m.mk_eq(fapp, flt_app); @@ -1211,61 +1179,89 @@ void fpa2bv_converter::mk_abs(sort * s, expr_ref & x, expr_ref & result) { } void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - expr_ref x(m), y(m); - x = args[0]; - y = args[1]; - - expr_ref x_is_zero(m), y_is_zero(m), both_are_zero(m); - x_is_zero = m_util.mk_is_zero(x); - y_is_zero = m_util.mk_is_zero(y); - both_are_zero = m.mk_and(x_is_zero, y_is_zero); - - expr_ref x_is_positive(m), x_is_negative(m), y_is_positive(m), y_is_negative(m), pn(m), np(m), pn_or_np(m); - x_is_positive = m_util.mk_is_positive(x); - x_is_negative = m_util.mk_is_negative(x); - y_is_positive = m_util.mk_is_positive(y); - y_is_negative = m_util.mk_is_negative(y); - pn = m.mk_and(x_is_positive, y_is_negative); - np = m.mk_and(x_is_negative, y_is_positive); - pn_or_np = m.mk_or(pn, np); - - expr_ref c(m), v(m); - c = m.mk_and(both_are_zero, pn_or_np); - v = m.mk_app(m_util.get_family_id(), OP_FPA_MIN_UNSPECIFIED, x, y); - - // Note: This requires BR_REWRITE_FULL afterwards. - expr_ref min_i(m); - min_i = m.mk_app(m_util.get_family_id(), OP_FPA_MIN_I, x, y); - m_simp.mk_ite(c, v, min_i, result); -} - -void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); + unsigned ebits = m_util.get_ebits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); expr * x = args[0], * y = args[1]; - expr * x_sgn, * x_sig, * x_exp; - expr * y_sgn, * y_sig, * y_exp; + expr * x_sgn, *x_sig, *x_exp; + expr * y_sgn, *y_sig, *y_exp; split_fp(x, x_sgn, x_exp, x_sig); split_fp(y, y_sgn, y_exp, y_sig); - expr_ref x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), both_zero(m), pzero(m); - mk_is_zero(x, x_is_zero); - mk_is_zero(y, y_is_zero); - m_simp.mk_and(x_is_zero, y_is_zero, both_zero); + expr_ref bv0(m), bv1(m); + bv0 = m_bv_util.mk_numeral(0, 1); + bv1 = m_bv_util.mk_numeral(1, 1); + + expr_ref x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), xy_are_zero(m); mk_is_nan(x, x_is_nan); mk_is_nan(y, y_is_nan); - mk_pzero(f, pzero); + mk_is_zero(x, x_is_zero); + mk_is_zero(y, y_is_zero); + xy_are_zero = m.mk_and(x_is_zero, y_is_zero); - expr_ref sgn_eq(m), sgn_diff(m); - sgn_eq = m.mk_eq(x_sgn, y_sgn); - sgn_diff = m.mk_not(sgn_eq); + expr_ref x_is_pos(m), x_is_neg(m); + expr_ref y_is_pos(m), y_is_neg(m); + expr_ref pn(m), np(m), pn_or_np_zeros(m); + mk_is_pos(x, x_is_pos); + mk_is_pos(y, y_is_pos); + mk_is_neg(x, x_is_neg); + mk_is_neg(y, y_is_neg); + pn_or_np_zeros = m.mk_and(xy_are_zero, m.mk_not(m.mk_eq(x_sgn, y_sgn))); - expr_ref lt(m); - mk_float_lt(f, num, args, lt); + expr_ref unspec(m); + unspec = mk_min_max_unspecified(f, x, y); - mk_ite(lt, x, y, result); - mk_ite(both_zero, y, result, result); + expr_ref x_lt_y(m); + mk_float_lt(f, num, args, x_lt_y); + + mk_ite(x_lt_y, x, y, result); + mk_ite(xy_are_zero, y, result, result); + mk_ite(pn_or_np_zeros, unspec, result, result); + mk_ite(y_is_nan, x, result, result); + mk_ite(x_is_nan, y, result, result); + + SASSERT(is_well_sorted(m, result)); +} + +void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + SASSERT(num == 2); + unsigned ebits = m_util.get_ebits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); + + expr * x = args[0], *y = args[1]; + + expr * x_sgn, *x_sig, *x_exp; + expr * y_sgn, *y_sig, *y_exp; + split_fp(x, x_sgn, x_exp, x_sig); + split_fp(y, y_sgn, y_exp, y_sig); + + expr_ref x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), xy_are_zero(m); + mk_is_nan(x, x_is_nan); + mk_is_nan(y, y_is_nan); + mk_is_zero(x, x_is_zero); + mk_is_zero(y, y_is_zero); + xy_are_zero = m.mk_and(x_is_zero, y_is_zero); + + expr_ref x_is_pos(m), x_is_neg(m); + expr_ref y_is_pos(m), y_is_neg(m); + expr_ref pn(m), np(m), pn_or_np_zeros(m); + mk_is_pos(x, x_is_pos); + mk_is_pos(y, y_is_pos); + mk_is_neg(x, x_is_neg); + mk_is_neg(y, y_is_neg); + pn_or_np_zeros = m.mk_and(xy_are_zero, m.mk_not(m.mk_eq(x_sgn, y_sgn))); + + expr_ref unspec(m); + unspec = mk_min_max_unspecified(f, x, y); + + expr_ref x_gt_y(m); + mk_float_gt(f, num, args, x_gt_y); + + mk_ite(x_gt_y, x, y, result); + mk_ite(xy_are_zero, y, result, result); + mk_ite(pn_or_np_zeros, unspec, result, result); mk_ite(y_is_nan, x, result, result); mk_ite(x_is_nan, y, result, result); @@ -1281,10 +1277,10 @@ expr_ref fpa2bv_converter::mk_min_max_unspecified(func_decl * f, expr * x, expr // There is no "hardware interpretation" for fp.min/fp.max. std::pair decls(0, 0); - if (!m_min_max_specials.find(f, decls)) { + if (!m_min_max_ufs.find(f, decls)) { decls.first = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); decls.second = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - m_min_max_specials.insert(f, decls); + m_min_max_ufs.insert(f, decls); m.inc_ref(f); m.inc_ref(decls.first); m.inc_ref(decls.second); @@ -1303,68 +1299,6 @@ expr_ref fpa2bv_converter::mk_min_max_unspecified(func_decl * f, expr * x, expr return res; } -void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - expr_ref x(m), y(m); - x = args[0]; - y = args[1]; - - expr_ref x_is_zero(m), y_is_zero(m), both_are_zero(m); - x_is_zero = m_util.mk_is_zero(x); - y_is_zero = m_util.mk_is_zero(y); - both_are_zero = m.mk_and(x_is_zero, y_is_zero); - - expr_ref x_is_positive(m), x_is_negative(m), y_is_positive(m), y_is_negative(m), pn(m), np(m), pn_or_np(m); - x_is_positive = m_util.mk_is_positive(x); - x_is_negative = m_util.mk_is_negative(x); - y_is_positive = m_util.mk_is_positive(y); - y_is_negative = m_util.mk_is_negative(y); - pn = m.mk_and(x_is_positive, y_is_negative); - np = m.mk_and(x_is_negative, y_is_positive); - pn_or_np = m.mk_or(pn, np); - - expr_ref c(m), v(m); - c = m.mk_and(both_are_zero, pn_or_np); - v = m.mk_app(m_util.get_family_id(), OP_FPA_MAX_UNSPECIFIED, x, y); - - // Note: This requires BR_REWRITE_FULL afterwards. - expr_ref max_i(m); - max_i = m.mk_app(m_util.get_family_id(), OP_FPA_MAX_I, x, y); - m_simp.mk_ite(c, v, max_i, result); -} - -void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 2); - - expr * x = args[0], *y = args[1]; - - expr * x_sgn, *x_sig, *x_exp; - expr * y_sgn, *y_sig, *y_exp; - split_fp(x, x_sgn, x_exp, x_sig); - split_fp(y, y_sgn, y_exp, y_sig); - - expr_ref x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), both_zero(m), pzero(m); - mk_is_zero(x, x_is_zero); - mk_is_zero(y, y_is_zero); - m_simp.mk_and(x_is_zero, y_is_zero, both_zero); - mk_is_nan(x, x_is_nan); - mk_is_nan(y, y_is_nan); - mk_pzero(f, pzero); - - expr_ref sgn_diff(m), sgn_eq(m); - sgn_eq = m.mk_eq(x_sgn, y_sgn); - sgn_diff = m.mk_not(sgn_eq); - - expr_ref gt(m); - mk_float_gt(f, num, args, gt); - - mk_ite(gt, x, y, result); - mk_ite(both_zero, y, result, result); - mk_ite(y_is_nan, x, result, result); - mk_ite(x_is_nan, y, result, result); - - SASSERT(is_well_sorted(m, result)); -} - void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 4); SASSERT(m_util.is_bv2rm(args[0])); @@ -3150,19 +3084,12 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * unsigned ebits = m_util.get_ebits(fp_srt); unsigned sbits = m_util.get_sbits(fp_srt); - expr_ref nanv(m); - if (m_hi_fp_unspecified) - // The "hardware interpretation" is 01...10...01. - nanv = m_bv_util.mk_concat(m_bv_util.mk_numeral(0, 1), - m_bv_util.mk_concat(m_bv_util.mk_numeral(-1, ebits), - m_bv_util.mk_concat(m_bv_util.mk_numeral(0, sbits - 2), - m_bv_util.mk_numeral(1, 1)))); - else - mk_to_ieee_bv_unspecified(f, num, args, nanv); + expr_ref unspec(m); + mk_to_ieee_bv_unspecified(f, num, args, unspec); expr_ref sgn_e_s(m); join_fp(x, sgn_e_s); - m_simp.mk_ite(x_is_nan, nanv, sgn_e_s, result); + m_simp.mk_ite(x_is_nan, unspec, sgn_e_s, result); TRACE("fpa2bv_to_ieee_bv", tout << "result=" << mk_ismt2_pp(result, m) << std::endl;); SASSERT(is_well_sorted(m, result)); @@ -3174,26 +3101,15 @@ void fpa2bv_converter::mk_to_ieee_bv_unspecified(func_decl * f, unsigned num, ex unsigned ebits = f->get_domain()[0]->get_parameter(0).get_int(); unsigned sbits = f->get_domain()[0]->get_parameter(1).get_int(); - if (m_hi_fp_unspecified) { - result = m_bv_util.mk_concat(m_bv_util.mk_concat( - m_bv_util.mk_numeral(0, 1), - m_bv_util.mk_numeral(-1, ebits)), - m_bv_util.mk_numeral(1, sbits-1)); - } + if (m_hi_fp_unspecified) + mk_nan(f->get_range(), result); else { expr * n = args[0]; expr_ref n_bv(m); join_fp(n, n_bv); - func_decl * f_bv; - if (!m_uf2bvuf.find(f, f_bv)) { - sort * domain[2] = { m.get_sort(n_bv) }; - f_bv = m.mk_fresh_func_decl(0, 1, domain, f->get_range()); - m_uf2bvuf.insert(f, f_bv); - m.inc_ref(f); - m.inc_ref(f_bv); - } - + sort * domain[1] = { m.get_sort(n_bv) }; + func_decl * f_bv = mk_bv_uf(f, domain, f->get_range()); result = m.mk_app(f_bv, n_bv); expr_ref exp_bv(m), exp_all_ones(m); @@ -3382,14 +3298,8 @@ void fpa2bv_converter::mk_to_bv_unspecified(func_decl * f, unsigned num, expr * expr_ref n_bv(m); join_fp(n, n_bv); - func_decl * f_bv; - if (!m_uf2bvuf.find(f, f_bv)) { - sort * domain[2] = { m.get_sort(rm_bv), m.get_sort(n_bv) }; - f_bv = m.mk_fresh_func_decl(0, 2, domain, f->get_range()); - m_uf2bvuf.insert(f, f_bv); - m.inc_ref(f); - m.inc_ref(f_bv); - } + sort * domain[2] = { m.get_sort(rm_bv), m.get_sort(n_bv) }; + func_decl * f_bv = mk_bv_uf(f, domain, f->get_range()); result = m.mk_app(f_bv, rm_bv, n_bv); } @@ -3407,14 +3317,8 @@ void fpa2bv_converter::mk_to_real_unspecified(func_decl * f, unsigned num, expr expr_ref n_bv(m); join_fp(n, n_bv); - func_decl * f_bv; - if (!m_uf2bvuf.find(f, f_bv)) { - sort * domain[2] = { m.get_sort(n_bv) }; - f_bv = m.mk_fresh_func_decl(0, 1, domain, f->get_range()); - m_uf2bvuf.insert(f, f_bv); - m.inc_ref(f); - m.inc_ref(f_bv); - } + sort * domain[1] = { m.get_sort(n_bv) }; + func_decl * f_bv = mk_bv_uf(f, domain, f->get_range()); result = m.mk_app(f_bv, n_bv); } } @@ -4190,13 +4094,25 @@ void fpa2bv_converter::reset(void) { dec_ref_map_key_values(m, m_const2bv); dec_ref_map_key_values(m, m_rm_const2bv); dec_ref_map_key_values(m, m_uf2bvuf); - for (obj_map >::iterator it = m_min_max_specials.begin(); - it != m_min_max_specials.end(); + for (obj_map >::iterator it = m_min_max_ufs.begin(); + it != m_min_max_ufs.end(); it++) { m.dec_ref(it->m_key); m.dec_ref(it->m_value.first); m.dec_ref(it->m_value.second); } - m_min_max_specials.reset(); + m_min_max_ufs.reset(); m_extra_assertions.reset(); } + +func_decl * fpa2bv_converter::mk_bv_uf(func_decl * f, sort * const * domain, sort * range) { + func_decl * res; + if (!m_uf2bvuf.find(f, res)) { + res = m.mk_fresh_func_decl(0, f->get_arity(), domain, range); + m_uf2bvuf.insert(f, res); + m.inc_ref(f); + m.inc_ref(res); + TRACE("fpa2bv", tout << "New UF func_decl: " << std::endl << mk_ismt2_pp(res, m) << std::endl;); + } + return res; +} diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index d54adac78..f0e50ba2d 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -53,7 +53,7 @@ protected: const2bv_t m_const2bv; const2bv_t m_rm_const2bv; uf2bvuf_t m_uf2bvuf; - special_t m_min_max_specials; + special_t m_min_max_ufs; friend class fpa2bv_model_converter; friend class bv2fpa_converter; @@ -87,7 +87,7 @@ public: void mk_numeral(sort * s, mpf const & v, expr_ref & result); virtual void mk_const(func_decl * f, expr_ref & result); virtual void mk_rm_const(func_decl * f, expr_ref & result); - virtual void mk_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + virtual void mk_uf(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_var(unsigned base_inx, sort * srt, expr_ref & result); void mk_pinf(func_decl * f, expr_ref & result); @@ -147,18 +147,15 @@ public: void set_unspecified_fp_hi(bool v) { m_hi_fp_unspecified = v; } void mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - virtual expr_ref mk_min_max_unspecified(func_decl * f, expr * x, expr * y); - void mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + expr_ref mk_min_max_unspecified(func_decl * f, expr * x, expr * y); void reset(void); void dbg_decouple(const char * prefix, expr_ref & e); expr_ref_vector m_extra_assertions; - special_t const & get_min_max_specials() const { return m_min_max_specials; }; + special_t const & get_min_max_specials() const { return m_min_max_ufs; }; const2bv_t const & get_const2bv() const { return m_const2bv; }; const2bv_t const & get_rm_const2bv() const { return m_rm_const2bv; }; uf2bvuf_t const & get_uf2bvuf() const { return m_uf2bvuf; }; @@ -202,12 +199,6 @@ protected: void mk_to_bv(func_decl * f, unsigned num, expr * const * args, bool is_signed, expr_ref & result); - sort_ref replace_float_sorts(sort * s); - func_decl_ref replace_function(func_decl * f); - expr_ref replace_float_arg(expr * a); - void mk_function_output(sort * rng, func_decl * fbv, expr * const * new_args, expr_ref & result); - func_decl * get_bv_uf(func_decl * f, sort * bv_rng, unsigned arity); - private: void mk_nan(sort * s, expr_ref & result); void mk_nzero(sort * s, expr_ref & result); @@ -226,6 +217,8 @@ private: void mk_round_to_integral(sort * s, expr_ref & rm, expr_ref & x, expr_ref & result); void mk_to_fp_float(sort * s, expr * rm, expr * x, expr_ref & result); + + func_decl * mk_bv_uf(func_decl * f, sort * const * domain, sort * range); }; #endif diff --git a/src/ast/fpa/fpa2bv_rewriter.cpp b/src/ast/fpa/fpa2bv_rewriter.cpp index 07623ec48..6c96d92c1 100644 --- a/src/ast/fpa/fpa2bv_rewriter.cpp +++ b/src/ast/fpa/fpa2bv_rewriter.cpp @@ -124,6 +124,8 @@ br_status fpa2bv_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr * co case OP_FPA_DIV: m_conv.mk_div(f, num, args, result); return BR_DONE; case OP_FPA_REM: m_conv.mk_rem(f, num, args, result); return BR_DONE; case OP_FPA_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE; + case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_DONE; + case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_DONE; case OP_FPA_FMA: m_conv.mk_fma(f, num, args, result); return BR_DONE; case OP_FPA_SQRT: m_conv.mk_sqrt(f, num, args, result); return BR_DONE; case OP_FPA_ROUND_TO_INTEGRAL: m_conv.mk_round_to_integral(f, num, args, result); return BR_DONE; @@ -147,14 +149,6 @@ br_status fpa2bv_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr * co case OP_FPA_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; case OP_FPA_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; - case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_REWRITE_FULL; - case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_REWRITE_FULL; - - case OP_FPA_MIN_UNSPECIFIED: - case OP_FPA_MAX_UNSPECIFIED: result = m_conv.mk_min_max_unspecified(f, args[0], args[1]); return BR_DONE; - case OP_FPA_MIN_I: m_conv.mk_min_i(f, num, args, result); return BR_DONE; - case OP_FPA_MAX_I: m_conv.mk_max_i(f, num, args, result); return BR_DONE; - case OP_FPA_BVWRAP: case OP_FPA_BV2RM: return BR_FAILED; @@ -169,7 +163,7 @@ br_status fpa2bv_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr * co { SASSERT(!m_conv.is_float_family(f)); if (m_conv.fu().contains_floats(f)) { - m_conv.mk_function(f, num, args, result); + m_conv.mk_uf(f, num, args, result); return BR_DONE; } } diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 9bee51af7..9d298b413 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -361,10 +361,6 @@ func_decl * fpa_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_parameters case OP_FPA_REM: name = "fp.rem"; break; case OP_FPA_MIN: name = "fp.min"; break; case OP_FPA_MAX: name = "fp.max"; break; - case OP_FPA_MIN_I: name = "fp.min_i"; break; - case OP_FPA_MAX_I: name = "fp.max_i"; break; - case OP_FPA_MIN_UNSPECIFIED: name = "fp.min_unspecified"; break; - case OP_FPA_MAX_UNSPECIFIED: name = "fp.max_unspecified"; break; default: UNREACHABLE(); break; @@ -781,12 +777,6 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, case OP_FPA_BV2RM: return mk_bv2rm(k, num_parameters, parameters, arity, domain, range); - case OP_FPA_MIN_I: - case OP_FPA_MAX_I: - case OP_FPA_MIN_UNSPECIFIED: - case OP_FPA_MAX_UNSPECIFIED: - return mk_binary_decl(k, num_parameters, parameters, arity, domain, range); - default: m_manager->raise_exception("unsupported floating point operator"); return 0; diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index f59c8f92f..4e86c9d3f 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -89,11 +89,6 @@ enum fpa_op_kind { OP_FPA_BVWRAP, OP_FPA_BV2RM, - OP_FPA_MIN_I, - OP_FPA_MAX_I, - OP_FPA_MIN_UNSPECIFIED, - OP_FPA_MAX_UNSPECIFIED, - LAST_FLOAT_OP }; @@ -351,21 +346,12 @@ public: } bool is_bvwrap(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_BVWRAP); } - bool is_bvwrap(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_BVWRAP; } bool is_bv2rm(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_BV2RM); } - bool is_bv2rm(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_BV2RM; } - - bool is_min_interpreted(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MIN_I); } - bool is_min_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MIN_UNSPECIFIED); } - bool is_max_interpreted(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MAX_I); } - bool is_max_unspecified(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_MAX_UNSPECIFIED); } bool is_to_ubv(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_UBV); } bool is_to_sbv(expr const * e) const { return is_app_of(e, get_family_id(), OP_FPA_TO_SBV); } - bool is_min_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MIN_I; } - bool is_min_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MIN_UNSPECIFIED; } - bool is_max_interpreted(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MAX_I; } - bool is_max_unspecified(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_MAX_UNSPECIFIED; } + bool is_bvwrap(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_BVWRAP; } + bool is_bv2rm(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_BV2RM; } bool is_to_ubv(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_UBV; } bool is_to_sbv(func_decl const * f) const { return f->get_family_id() == get_family_id() && f->get_decl_kind() == OP_FPA_TO_SBV; } diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 6420dd968..818336c75 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -94,12 +94,6 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(f, args[0], result); break; case OP_FPA_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; - case OP_FPA_MIN_I:SASSERT(num_args == 2); st = mk_min_i(f, args[0], args[1], result); break; - case OP_FPA_MAX_I: SASSERT(num_args == 2); st = mk_max_i(f, args[0], args[1], result); break; - case OP_FPA_MIN_UNSPECIFIED: - case OP_FPA_MAX_UNSPECIFIED: - SASSERT(num_args == 2); st = BR_FAILED; break; - case OP_FPA_BVWRAP: SASSERT(num_args == 1); st = mk_bvwrap(args[0], result); break; case OP_FPA_BV2RM: SASSERT(num_args == 1); st = mk_bv2rm(args[0], result); break; @@ -385,38 +379,13 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { } scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { - if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { - result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); - return BR_REWRITE1; - } - else { - scoped_mpf r(m_fm); - m_fm.minimum(v1, v2, r); - result = m_util.mk_value(r); - return BR_DONE; - } - } - else { - expr_ref c(m()), v(m()); - c = m().mk_and(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), - m().mk_or(m().mk_and(m_util.mk_is_positive(arg1), m_util.mk_is_negative(arg2)), - m().mk_and(m_util.mk_is_negative(arg1), m_util.mk_is_positive(arg2)))); - v = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); - - result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_MIN_I, arg1, arg2)); - return BR_REWRITE_FULL; - } -} - -br_status fpa_rewriter::mk_min_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { - scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) - result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); - else - result = m_util.mk_min(arg1, arg2); + return BR_FAILED; + + scoped_mpf r(m_fm); + m_fm.minimum(v1, v2, r); + result = m_util.mk_value(r); return BR_DONE; } @@ -434,38 +403,13 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { } scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { - if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { - result = m().mk_app(get_fid(), OP_FPA_MAX_UNSPECIFIED, arg1, arg2); - return BR_REWRITE1; - } - else { - scoped_mpf r(m_fm); - m_fm.maximum(v1, v2, r); - result = m_util.mk_value(r); - return BR_DONE; - } - } - else { - expr_ref c(m()), v(m()); - c = m().mk_and(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), - m().mk_or(m().mk_and(m_util.mk_is_positive(arg1), m_util.mk_is_negative(arg2)), - m().mk_and(m_util.mk_is_negative(arg1), m_util.mk_is_positive(arg2)))); - v = m().mk_app(get_fid(), OP_FPA_MAX_UNSPECIFIED, arg1, arg2); - - result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_MAX_I, arg1, arg2)); - return BR_REWRITE_FULL; - } -} - -br_status fpa_rewriter::mk_max_i(func_decl * f, expr * arg1, expr * arg2, expr_ref & result) { - scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) - result = m().mk_app(get_fid(), OP_FPA_MIN_UNSPECIFIED, arg1, arg2); - else - result = m_util.mk_max(arg1, arg2); + return BR_FAILED; + + scoped_mpf r(m_fm); + m_fm.maximum(v1, v2, r); + result = m_util.mk_value(r); return BR_DONE; } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index d337cc65d..cc9b0017d 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -884,22 +884,4 @@ namespace smt { out << r->get_id() << " --> " << mk_ismt2_pp(n, m) << std::endl; } } - - bool theory_fpa::include_func_interp(func_decl * f) { - TRACE("t_fpa", tout << "f = " << mk_ismt2_pp(f, get_manager()) << std::endl;); - - if (f->get_family_id() == get_family_id()) { - bool include = - m_fpa_util.is_min_unspecified(f) || - m_fpa_util.is_max_unspecified(f) ; - if (include && !m_is_added_to_model.contains(f)) { - //m_is_added_to_model.insert(f); - //get_manager().inc_ref(f); - return true; - } - return false; - } - else - return true; - } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 7be82816e..9e9801ee0 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -158,7 +158,6 @@ namespace smt { virtual char const * get_name() const { return "fpa"; } virtual model_value_proc * mk_value(enode * n, model_generator & mg); - virtual bool include_func_interp(func_decl * f); void assign_eh(bool_var v, bool is_true); virtual void relevant_eh(app * n); @@ -180,8 +179,6 @@ namespace smt { expr_ref convert_term(expr * e); expr_ref convert_conversion_term(expr * e); - void add_trail(ast * a); - void attach_new_th_var(enode * n); void assert_cnstr(expr * e); From 048ee090b02ac07709ba88979db05c3065835a95 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Sep 2017 20:19:36 +0100 Subject: [PATCH 312/488] Eliminated the remaining operator kinds for partially unspecified FP operators from the AST API. --- src/api/api_ast.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index 491e08cf4..e22603225 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -1204,12 +1204,8 @@ extern "C" { case OP_FPA_TO_SBV: return Z3_OP_FPA_TO_SBV; case OP_FPA_TO_REAL: return Z3_OP_FPA_TO_REAL; case OP_FPA_TO_IEEE_BV: return Z3_OP_FPA_TO_IEEE_BV; - case OP_FPA_MIN_I: return Z3_OP_FPA_MIN_I; - case OP_FPA_MAX_I: return Z3_OP_FPA_MAX_I; case OP_FPA_BVWRAP: return Z3_OP_FPA_BVWRAP; case OP_FPA_BV2RM: return Z3_OP_FPA_BV2RM; - case OP_FPA_MIN_UNSPECIFIED: return Z3_OP_FPA_MIN_UNSPECIFIED; - case OP_FPA_MAX_UNSPECIFIED: return Z3_OP_FPA_MAX_UNSPECIFIED; return Z3_OP_UNINTERPRETED; default: return Z3_OP_INTERNAL; From 320105c71406f557a8c7fc470054ac1af5e213db Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 20 Sep 2017 13:30:31 -0700 Subject: [PATCH 313/488] removing iterators Signed-off-by: Nikolaj Bjorner --- src/smt/mam.cpp | 18 +++++------------- src/smt/qi_queue.cpp | 5 +---- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index a88ef1e0d..497aab8db 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -2016,26 +2016,20 @@ namespace smt { void execute(code_tree * t) { TRACE("trigger_bug", tout << "execute for code tree:\n"; t->display(tout);); init(t); - enode_vector::const_iterator it = t->get_candidates().begin(); - enode_vector::const_iterator end = t->get_candidates().end(); if (t->filter_candidates()) { - for (; it != end; ++it) { - enode * app = *it; + for (enode * app : t->get_candidates()) { if (!app->is_marked() && app->is_cgr()) { execute_core(t, app); app->set_mark(); } } - it = t->get_candidates().begin(); - for (; it != end; ++it) { - enode * app = *it; + for (enode * app : t->get_candidates()) { if (app->is_marked()) app->unset_mark(); } } else { - for (; it != end; ++it) { - enode * app = *it; + for (enode * app : t->get_candidates()) { TRACE("trigger_bug", tout << "candidate\n" << mk_ismt2_pp(app->get_owner(), m_ast_manager) << "\n";); if (app->is_cgr()) { TRACE("trigger_bug", tout << "is_cgr\n";); @@ -2821,15 +2815,13 @@ namespace smt { } // end of execute_core void display_trees(std::ostream & out, const ptr_vector & trees) { - ptr_vector::const_iterator it = trees.begin(); - ptr_vector::const_iterator end = trees.end(); unsigned lbl = 0; - for (; it != end; ++it, ++lbl) { - code_tree * tree = *it; + for (code_tree* tree : trees) { if (tree) { out << "tree for f" << lbl << "\n"; out << *tree; } + ++lbl; } } diff --git a/src/smt/qi_queue.cpp b/src/smt/qi_queue.cpp index f77fde29a..2a8d9d199 100644 --- a/src/smt/qi_queue.cpp +++ b/src/smt/qi_queue.cpp @@ -148,11 +148,8 @@ namespace smt { } void qi_queue::instantiate() { - svector::iterator it = m_new_entries.begin(); - svector::iterator end = m_new_entries.end(); unsigned since_last_check = 0; - for (; it != end; ++it) { - entry & curr = *it; + for (entry & curr : m_new_entries) { fingerprint * f = curr.m_qb; quantifier * qa = static_cast(f->get_data()); From cab4e4b461efc4328a24df3fc3a446662a2fc75a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 21 Sep 2017 18:32:46 -0500 Subject: [PATCH 314/488] add feature to display benchmark in format seen by SAT solver Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 14 ++++++++++++++ src/cmd_context/cmd_context.h | 1 + src/cmd_context/extra_cmds/dbg_cmds.cpp | 15 +++++++++++---- src/sat/sat_config.cpp | 3 ++- src/sat/sat_config.h | 1 + src/sat/sat_params.pyg | 3 ++- src/sat/sat_solver.cpp | 7 +++++++ src/sat/sat_solver/inc_sat_solver.cpp | 1 - src/tactic/portfolio/enum2bv_solver.cpp | 1 - 9 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 3889d6205..fa3b06649 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1545,6 +1545,20 @@ void cmd_context::reset_assertions() { } +void cmd_context::display_dimacs() { + if (m_solver) { + try { + gparams::set("sat.dimacs.display", "true"); + m_solver->check_sat(0, nullptr); + } + catch (...) { + gparams::set("sat.dimacs.display", "false"); + throw; + } + gparams::set("sat.dimacs.display", "false"); + } +} + void cmd_context::display_model(model_ref& mdl) { if (mdl) { model_params p; diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index 5883a8d8e..b60f590a9 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -419,6 +419,7 @@ public: void display_assertions(); void display_statistics(bool show_total_time = false, double total_time = 0.0); + void display_dimacs(); void reset(bool finalize = false); void assert_expr(expr * t); void assert_expr(symbol const & name, expr * t); diff --git a/src/cmd_context/extra_cmds/dbg_cmds.cpp b/src/cmd_context/extra_cmds/dbg_cmds.cpp index 7d20685ac..dfdfa6175 100644 --- a/src/cmd_context/extra_cmds/dbg_cmds.cpp +++ b/src/cmd_context/extra_cmds/dbg_cmds.cpp @@ -31,7 +31,6 @@ Notes: #include "ast/rewriter/var_subst.h" #include "util/gparams.h" -#ifndef _EXTERNAL_RELEASE BINARY_SYM_CMD(get_quantifier_body_cmd, "dbg-get-qbody", @@ -343,10 +342,19 @@ public: } }; -#endif +class print_dimacs_cmd : public cmd { +public: + print_dimacs_cmd():cmd("display-dimacs") {} + virtual char const * get_usage() const { return ""; } + virtual char const * get_descr(cmd_context & ctx) const { return "print benchmark in DIMACS format"; } + virtual unsigned get_arity() const { return 0; } + virtual void prepare(cmd_context & ctx) {} + virtual void execute(cmd_context & ctx) { ctx.display_dimacs(); } +}; + void install_dbg_cmds(cmd_context & ctx) { -#ifndef _EXTERNAL_RELEASE + ctx.insert(alloc(print_dimacs_cmd)); ctx.insert(alloc(get_quantifier_body_cmd)); ctx.insert(alloc(set_cmd)); ctx.insert(alloc(pp_var_cmd)); @@ -369,5 +377,4 @@ void install_dbg_cmds(cmd_context & ctx) { ctx.insert(alloc(instantiate_cmd)); ctx.insert(alloc(instantiate_nested_cmd)); ctx.insert(alloc(set_next_id)); -#endif } diff --git a/src/sat/sat_config.cpp b/src/sat/sat_config.cpp index 9cd343bd3..c67511275 100644 --- a/src/sat/sat_config.cpp +++ b/src/sat/sat_config.cpp @@ -35,7 +35,7 @@ namespace sat { m_glue("glue"), m_glue_psm("glue_psm"), m_psm_glue("psm_glue") { - m_num_parallel = 1; + m_num_parallel = 1; updt_params(p); } @@ -114,6 +114,7 @@ namespace sat { m_core_minimize = p.core_minimize(); m_core_minimize_partial = p.core_minimize_partial(); m_dyn_sub_res = p.dyn_sub_res(); + m_dimacs_display = p.dimacs_display(); } void config::collect_param_descrs(param_descrs & r) { diff --git a/src/sat/sat_config.h b/src/sat/sat_config.h index edd9f0bfc..36f22e83f 100644 --- a/src/sat/sat_config.h +++ b/src/sat/sat_config.h @@ -74,6 +74,7 @@ namespace sat { bool m_core_minimize; bool m_core_minimize_partial; + bool m_dimacs_display; symbol m_always_true; symbol m_always_false; diff --git a/src/sat/sat_params.pyg b/src/sat/sat_params.pyg index 60708fd5c..2b1dc6646 100644 --- a/src/sat/sat_params.pyg +++ b/src/sat/sat_params.pyg @@ -23,4 +23,5 @@ def_module_params('sat', ('core.minimize', BOOL, False, 'minimize computed core'), ('core.minimize_partial', BOOL, False, 'apply partial (cheap) core minimization'), ('parallel_threads', UINT, 1, 'number of parallel threads to use'), - ('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks'))) + ('dimacs.core', BOOL, False, 'extract core from DIMACS benchmarks'), + ('dimacs.display', BOOL, False, 'display SAT instance in DIMACS format and return unknown instead of solving'))) diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 77bd2283d..2fa0c46f0 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -724,6 +724,13 @@ namespace sat { pop_to_base_level(); IF_VERBOSE(2, verbose_stream() << "(sat.sat-solver)\n";); SASSERT(scope_lvl() == 0); + if (m_config.m_dimacs_display) { + display_dimacs(std::cout); + for (unsigned i = 0; i < num_lits; ++lits) { + std::cout << dimacs_lit(lits[i]) << " 0\n"; + } + return l_undef; + } if (m_config.m_num_parallel > 1 && !m_par) { return check_par(num_lits, lits); } diff --git a/src/sat/sat_solver/inc_sat_solver.cpp b/src/sat/sat_solver/inc_sat_solver.cpp index 21f9f1e8a..69645d705 100644 --- a/src/sat/sat_solver/inc_sat_solver.cpp +++ b/src/sat/sat_solver/inc_sat_solver.cpp @@ -105,7 +105,6 @@ public: virtual void set_progress_callback(progress_callback * callback) {} - void display_weighted(std::ostream& out, unsigned sz, expr * const * assumptions, unsigned const* weights) { if (weights != 0) { for (unsigned i = 0; i < sz; ++i) m_weights.push_back(weights[i]); diff --git a/src/tactic/portfolio/enum2bv_solver.cpp b/src/tactic/portfolio/enum2bv_solver.cpp index 36a178c41..5880302d9 100644 --- a/src/tactic/portfolio/enum2bv_solver.cpp +++ b/src/tactic/portfolio/enum2bv_solver.cpp @@ -97,7 +97,6 @@ public: virtual void get_labels(svector & r) { m_solver->get_labels(r); } virtual ast_manager& get_manager() const { return m; } virtual lbool find_mutexes(expr_ref_vector const& vars, vector& mutexes) { return m_solver->find_mutexes(vars, mutexes); } - virtual lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) { datatype_util dt(m); bv_util bv(m); From cd24535e51263d8447efea9b917977863b97d8e5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 22 Sep 2017 09:54:56 -0500 Subject: [PATCH 315/488] add newline Signed-off-by: Nikolaj Bjorner --- src/api/z3_ast_containers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/z3_ast_containers.h b/src/api/z3_ast_containers.h index 027976c07..c423a3286 100644 --- a/src/api/z3_ast_containers.h +++ b/src/api/z3_ast_containers.h @@ -197,4 +197,4 @@ extern "C" { } #endif // __cplusplus -#endif \ No newline at end of file +#endif From 95ee4c94f1f8084374d72f0780f9d831569f1621 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 23 Sep 2017 11:37:55 -0500 Subject: [PATCH 316/488] remove utf fixes #1265 Signed-off-by: Nikolaj Bjorner --- src/parsers/smt2/smt2parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index b4648f0d6..b8ad7e610 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -1306,7 +1306,7 @@ namespace smt2 { /** * SMT-LIB 2.6 pattern matches are of the form - * (match t ((p1 t1) ··· (pm+1 tm+1))) + * (match t ((p1 t1) ... (pm+1 tm+1))) */ void push_match_frame() { SASSERT(curr_is_identifier()); From 2751cbc2703c49d9d38a624db9baf3a63a71bc6a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 23 Sep 2017 22:36:36 -0500 Subject: [PATCH 317/488] n/a Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 6 +++++ src/sat/sat_solver.cpp | 7 +++--- src/sat/sat_solver/inc_sat_solver.cpp | 13 ++++++---- src/sat/tactic/sat_tactic.cpp | 35 +++++++++++++-------------- src/smt/smt_internalizer.cpp | 12 ++------- src/smt/theory_dense_diff_logic_def.h | 14 ++++++----- src/smt/theory_diff_logic_def.h | 1 - src/test/ddnf.cpp | 16 +++++++++++- src/test/main.cpp | 1 + src/test/sorting_network.cpp | 17 +++++++------ 10 files changed, 70 insertions(+), 52 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index fa3b06649..260d49174 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1549,13 +1549,19 @@ void cmd_context::display_dimacs() { if (m_solver) { try { gparams::set("sat.dimacs.display", "true"); + params_ref p; + m_solver->updt_params(p); m_solver->check_sat(0, nullptr); } catch (...) { gparams::set("sat.dimacs.display", "false"); + params_ref p; + m_solver->updt_params(p); throw; } gparams::set("sat.dimacs.display", "false"); + params_ref p; + m_solver->updt_params(p); } } diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 2fa0c46f0..63f1badb7 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -724,6 +724,8 @@ namespace sat { pop_to_base_level(); IF_VERBOSE(2, verbose_stream() << "(sat.sat-solver)\n";); SASSERT(scope_lvl() == 0); + SASSERT(m_config.m_dimacs_display); + std::cout << "display dimacs: " << m_config.m_dimacs_display << "\n"; if (m_config.m_dimacs_display) { display_dimacs(std::cout); for (unsigned i = 0; i < num_lits; ++lits) { @@ -1249,10 +1251,7 @@ namespace sat { } void solver::sort_watch_lits() { - vector::iterator it = m_watches.begin(); - vector::iterator end = m_watches.end(); - for (; it != end; ++it) { - watch_list & wlist = *it; + for (watch_list & wlist : m_watches) { std::stable_sort(wlist.begin(), wlist.end(), watched_lt()); } } diff --git a/src/sat/sat_solver/inc_sat_solver.cpp b/src/sat/sat_solver/inc_sat_solver.cpp index 69645d705..be418cbc4 100644 --- a/src/sat/sat_solver/inc_sat_solver.cpp +++ b/src/sat/sat_solver/inc_sat_solver.cpp @@ -162,6 +162,11 @@ public: if (r != l_true) return r; r = m_solver.check(m_asms.size(), m_asms.c_ptr()); + if (r == l_undef && m_solver.get_config().m_dimacs_display) { + for (auto const& kv : m_map) { + std::cout << "c " << kv.m_value << " " << mk_pp(kv.m_key, m) << "\n"; + } + } switch (r) { case l_true: @@ -643,14 +648,12 @@ private: } sat::model const & ll_m = m_solver.get_model(); model_ref md = alloc(model, m); - atom2bool_var::iterator it = m_map.begin(); - atom2bool_var::iterator end = m_map.end(); - for (; it != end; ++it) { - expr * n = it->m_key; + for (auto const& kv : m_map) { + expr * n = kv.m_key; if (is_app(n) && to_app(n)->get_num_args() > 0) { continue; } - sat::bool_var v = it->m_value; + sat::bool_var v = kv.m_value; switch (sat::value_at(v, ll_m)) { case l_true: md->register_decl(to_app(n)->get_decl(), m.mk_true()); diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index 9b706597d..4a6171f70 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -16,11 +16,11 @@ Author: Notes: --*/ +#include "ast/ast_pp.h" #include "tactic/tactical.h" +#include "tactic/filter_model_converter.h" #include "sat/tactic/goal2sat.h" #include "sat/sat_solver.h" -#include "tactic/filter_model_converter.h" -#include "ast/ast_smt2_pp.h" #include "model/model_v2_pp.h" class sat_tactic : public tactic { @@ -56,11 +56,9 @@ class sat_tactic : public tactic { sat::literal_vector assumptions; m_goal2sat(*g, m_params, m_solver, map, dep2asm); TRACE("sat_solver_unknown", tout << "interpreted_atoms: " << map.interpreted_atoms() << "\n"; - atom2bool_var::iterator it = map.begin(); - atom2bool_var::iterator end = map.end(); - for (; it != end; ++it) { - if (!is_uninterp_const(it->m_key)) - tout << mk_ismt2_pp(it->m_key, m) << "\n"; + for (auto const& kv : map) { + if (!is_uninterp_const(kv.m_key)) + tout << mk_ismt2_pp(kv.m_key, m) << "\n"; }); g->reset(); g->m().compact_memory(); @@ -70,6 +68,11 @@ class sat_tactic : public tactic { TRACE("sat_dimacs", m_solver.display_dimacs(tout);); dep2assumptions(dep2asm, assumptions); lbool r = m_solver.check(assumptions.size(), assumptions.c_ptr()); + if (r == l_undef && m_solver.get_config().m_dimacs_display) { + for (auto const& kv : map) { + std::cout << "c " << kv.m_value << " " << mk_pp(kv.m_key, g->m()) << "\n"; + } + } if (r == l_false) { expr_dependency * lcore = 0; if (produce_core) { @@ -90,11 +93,9 @@ class sat_tactic : public tactic { model_ref md = alloc(model, m); sat::model const & ll_m = m_solver.get_model(); TRACE("sat_tactic", for (unsigned i = 0; i < ll_m.size(); i++) tout << i << ":" << ll_m[i] << " "; tout << "\n";); - atom2bool_var::iterator it = map.begin(); - atom2bool_var::iterator end = map.end(); - for (; it != end; ++it) { - expr * n = it->m_key; - sat::bool_var v = it->m_value; + for (auto const& kv : map) { + expr * n = kv.m_key; + sat::bool_var v = kv.m_value; TRACE("sat_tactic", tout << "extracting value of " << mk_ismt2_pp(n, m) << "\nvar: " << v << "\n";); switch (sat::value_at(v, ll_m)) { case l_true: @@ -126,17 +127,15 @@ class sat_tactic : public tactic { void dep2assumptions(obj_map& dep2asm, sat::literal_vector& assumptions) { - obj_map::iterator it = dep2asm.begin(), end = dep2asm.end(); - for (; it != end; ++it) { - assumptions.push_back(it->m_value); + for (auto const& kv : dep2asm) { + assumptions.push_back(kv.m_value); } } void mk_asm2dep(obj_map& dep2asm, u_map& lit2asm) { - obj_map::iterator it = dep2asm.begin(), end = dep2asm.end(); - for (; it != end; ++it) { - lit2asm.insert(it->m_value.index(), it->m_key); + for (auto const& kv : dep2asm) { + lit2asm.insert(kv.m_value.index(), kv.m_key); } } }; diff --git a/src/smt/smt_internalizer.cpp b/src/smt/smt_internalizer.cpp index 58b391ac2..5a8a313ba 100644 --- a/src/smt/smt_internalizer.cpp +++ b/src/smt/smt_internalizer.cpp @@ -201,16 +201,8 @@ namespace smt { TRACE("deep_internalize", tout << "expression is deep: #" << n->get_id() << "\n" << mk_ll_pp(n, m_manager);); svector sorted_exprs; top_sort_expr(n, sorted_exprs); - TRACE("deep_internalize", - svector::const_iterator it = sorted_exprs.begin(); - svector::const_iterator end = sorted_exprs.end(); - for (; it != end; ++it) { - tout << "#" << it->first->get_id() << " " << it->second << "\n"; - }); - svector::const_iterator it = sorted_exprs.begin(); - svector::const_iterator end = sorted_exprs.end(); - for (; it != end; ++it) - internalize(it->first, it->second); + TRACE("deep_internalize", for (auto & kv : sorted_exprs) tout << "#" << kv.first->get_id() << " " << kv.second << "\n"; ); + for (auto & kv : sorted_exprs) internalize(kv.first, kv.second); } SASSERT(m_manager.is_bool(n)); if (is_gate(m_manager, n)) { diff --git a/src/smt/theory_dense_diff_logic_def.h b/src/smt/theory_dense_diff_logic_def.h index ad7727a89..064bdd433 100644 --- a/src/smt/theory_dense_diff_logic_def.h +++ b/src/smt/theory_dense_diff_logic_def.h @@ -151,14 +151,15 @@ namespace smt { m_autil.is_numeral(rhs, _k); numeral offset(_k); app * s, * t; - if (m_autil.is_add(lhs) && to_app(lhs)->get_num_args() == 2 && is_times_minus_one(to_app(lhs)->get_arg(1), s)) { - t = to_app(to_app(lhs)->get_arg(0)); + expr *arg1, *arg2; + if (m_autil.is_add(lhs, arg1, arg2) && is_times_minus_one(arg2, s)) { + t = to_app(arg1); } - else if (m_autil.is_add(lhs) && to_app(lhs)->get_num_args() == 2 && is_times_minus_one(to_app(lhs)->get_arg(0), s)) { - t = to_app(to_app(lhs)->get_arg(1)); + else if (m_autil.is_add(lhs, arg1, arg2) && is_times_minus_one(arg1, s)) { + t = to_app(arg2); } - else if (m_autil.is_mul(lhs) && to_app(lhs)->get_num_args() == 2 && m_autil.is_minus_one(to_app(lhs)->get_arg(0))) { - s = to_app(to_app(lhs)->get_arg(1)); + else if (m_autil.is_mul(lhs, arg1, arg2) && m_autil.is_minus_one(arg1)) { + s = to_app(arg2); t = mk_zero_for(s); } else if (!m_autil.is_arith_expr(lhs)) { @@ -170,6 +171,7 @@ namespace smt { found_non_diff_logic_expr(n); return false; } + TRACE("arith", tout << expr_ref(lhs, get_manager()) << " " << expr_ref(s, get_manager()) << " " << expr_ref(t, get_manager()) << "\n";); source = internalize_term_core(s); target = internalize_term_core(t); if (source == null_theory_var || target == null_theory_var) { diff --git a/src/smt/theory_diff_logic_def.h b/src/smt/theory_diff_logic_def.h index 02cc8860f..a7153234c 100644 --- a/src/smt/theory_diff_logic_def.h +++ b/src/smt/theory_diff_logic_def.h @@ -733,7 +733,6 @@ theory_var theory_diff_logic::mk_term(app* n) { source = mk_var(a); for (unsigned i = 0; i < n->get_num_args(); ++i) { expr* arg = n->get_arg(i); - std::cout << "internalize: " << mk_pp(arg, get_manager()) << " " << ctx.e_internalized(arg) << "\n"; if (!ctx.e_internalized(arg)) { ctx.internalize(arg, false); } diff --git a/src/test/ddnf.cpp b/src/test/ddnf.cpp index 3f8e748be..09f1a4cf9 100644 --- a/src/test/ddnf.cpp +++ b/src/test/ddnf.cpp @@ -200,6 +200,20 @@ void tst_ddnf(char ** argv, int argc, int& i) { dealloc(ddnf); } - +void tst_ddnf1() { + enable_trace("ddnf"); + unsigned W = 2; + datalog::ddnf_core ddnf(W); + tbv_manager& tbvm = ddnf.get_tbv_manager(); + tbv* tXX = tbvm.allocate("xx"); + tbv* t1X = tbvm.allocate("1x"); + tbv* tX1 = tbvm.allocate("x1"); + tbv* t11 = tbvm.allocate("11"); + ddnf.insert(*tXX); + ddnf.insert(*t11); + ddnf.insert(*tX1); + ddnf.insert(*t1X); + ddnf.display(std::cout); +} diff --git a/src/test/main.cpp b/src/test/main.cpp index d0d0aac5b..03fbba1df 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -237,6 +237,7 @@ int main(int argc, char ** argv) { TST(sat_user_scope); TST(pdr); TST_ARGV(ddnf); + TST(ddnf1); TST(model_evaluator); TST_ARGV(lp); TST(get_consequences); diff --git a/src/test/sorting_network.cpp b/src/test/sorting_network.cpp index 2984e94e2..1062057f6 100644 --- a/src/test/sorting_network.cpp +++ b/src/test/sorting_network.cpp @@ -6,16 +6,14 @@ Copyright (c) 2015 Microsoft Corporation #include "util/trace.h" #include "util/vector.h" +#include "util/sorting_network.h" #include "ast/ast.h" #include "ast/ast_pp.h" #include "ast/reg_decl_plugins.h" -#include "util/sorting_network.h" -#include "smt/smt_kernel.h" -#include "model/model_smt2_pp.h" -#include "smt/params/smt_params.h" #include "ast/ast_util.h" - - +#include "model/model_smt2_pp.h" +#include "smt/smt_kernel.h" +#include "smt/params/smt_params.h" struct ast_ext { ast_manager& m; @@ -388,7 +386,6 @@ void test_at_most_1(unsigned n, bool full) { std::cout << atom << "\n"; if (is_true) ++k; } - VERIFY(l_false == solver.check()); if (k > 1) { solver.assert_expr(result1); } @@ -427,6 +424,12 @@ void tst_sorting_network() { test_at_most_1(i, true); test_at_most_1(i, false); } + + for (unsigned n = 2; n < 20; ++n) { + std::cout << "verify eq-1 out of " << n << "\n"; + test_sorting_eq(n, 1); + } + test_at_most1(); test_sorting_eq(11,7); From 7a15de374a4893de1224bc07f56b43485f464dc3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 24 Sep 2017 09:19:51 -0700 Subject: [PATCH 318/488] fix #1266 by bypassing topological ordering on theory symbols Signed-off-by: Nikolaj Bjorner --- src/smt/smt_internalizer.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/smt/smt_internalizer.cpp b/src/smt/smt_internalizer.cpp index 5a8a313ba..ffaee434f 100644 --- a/src/smt/smt_internalizer.cpp +++ b/src/smt/smt_internalizer.cpp @@ -198,11 +198,19 @@ namespace smt { if (get_depth(n) > DEEP_EXPR_THRESHOLD) { // if the expression is deep, then execute topological sort to avoid // stack overflow. + // a caveat is that theory internalizers do rely on recursive descent so + // internalization over these follows top-down TRACE("deep_internalize", tout << "expression is deep: #" << n->get_id() << "\n" << mk_ll_pp(n, m_manager);); svector sorted_exprs; top_sort_expr(n, sorted_exprs); TRACE("deep_internalize", for (auto & kv : sorted_exprs) tout << "#" << kv.first->get_id() << " " << kv.second << "\n"; ); - for (auto & kv : sorted_exprs) internalize(kv.first, kv.second); + for (auto & kv : sorted_exprs) { + expr* e = kv.first; + if (!is_app(e) || + to_app(e)->get_family_id() == null_family_id || + to_app(e)->get_family_id() == m_manager.get_basic_family_id()) + internalize(e, kv.second); + } } SASSERT(m_manager.is_bool(n)); if (is_gate(m_manager, n)) { From 9cd974e3343b83491200071442537d7765f48ad7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 24 Sep 2017 09:40:35 -0700 Subject: [PATCH 319/488] remove display Signed-off-by: Nikolaj Bjorner --- src/sat/sat_solver.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 63f1badb7..8782cb462 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -724,8 +724,6 @@ namespace sat { pop_to_base_level(); IF_VERBOSE(2, verbose_stream() << "(sat.sat-solver)\n";); SASSERT(scope_lvl() == 0); - SASSERT(m_config.m_dimacs_display); - std::cout << "display dimacs: " << m_config.m_dimacs_display << "\n"; if (m_config.m_dimacs_display) { display_dimacs(std::cout); for (unsigned i = 0; i < num_lits; ++lits) { From f179d49f4f4ac90e9515f42ee690426c5a67fa52 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 24 Sep 2017 10:58:39 -0700 Subject: [PATCH 320/488] check for eof, based on testing garbled repro from #1267 Signed-off-by: Nikolaj Bjorner --- src/parsers/smt2/smt2scanner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parsers/smt2/smt2scanner.cpp b/src/parsers/smt2/smt2scanner.cpp index c1cc40b2b..9a9e69b67 100644 --- a/src/parsers/smt2/smt2scanner.cpp +++ b/src/parsers/smt2/smt2scanner.cpp @@ -124,7 +124,7 @@ namespace smt2 { next(); bool is_float = false; - while (true) { + while (!m_at_eof) { char c = curr(); if ('0' <= c && c <= '9') { m_number = rational(10)*m_number + rational(c - '0'); From c8a67abdd70550cbab22bafd259a21f68433da7c Mon Sep 17 00:00:00 2001 From: Ken McMillan Date: Mon, 25 Sep 2017 14:33:20 -0700 Subject: [PATCH 321/488] fixing issue [1269] --- src/interp/iz3mgr.cpp | 29 +++++++++++++++++++++++++++++ src/interp/iz3mgr.h | 6 ++++++ src/interp/iz3proof_itp.cpp | 4 ++-- src/interp/iz3translate.cpp | 5 +++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/interp/iz3mgr.cpp b/src/interp/iz3mgr.cpp index 306807f1f..7314403b0 100755 --- a/src/interp/iz3mgr.cpp +++ b/src/interp/iz3mgr.cpp @@ -33,9 +33,11 @@ #include #include #include +#include #include "ast/expr_abstract.h" #include "util/params.h" +#include "ast/used_vars.h" using namespace stl_ext; @@ -938,3 +940,30 @@ void iz3mgr::get_bound_substitutes(stl_ext::hash_map &memo, const ast } #endif + +unsigned iz3mgr::num_free_variables(const ast &e){ + used_vars uv; + uv(to_expr(e.raw())); + return uv.get_num_vars(); +} + +iz3mgr::ast iz3mgr::close_universally (ast e){ + used_vars uv; + uv(to_expr(e.raw())); + std::vector bvs; + stl_ext::hash_map subst_memo; + for (unsigned i = 0; i < uv.get_max_found_var_idx_plus_1(); i++){ + if (uv.get(i)) { + std::ostringstream os; + os << "%%" << i; + ast c = make_var(os.str(),uv.get(i)); + ast v = cook(m().mk_var(i,uv.get(i))); + subst_memo[v] = c; + bvs.push_back(c); + } + } + e = subst(subst_memo,e); + for (unsigned i = 0; i < bvs.size(); i++) + e = apply_quant(Forall,bvs[i],e); + return e; +} diff --git a/src/interp/iz3mgr.h b/src/interp/iz3mgr.h index e6e08f84d..6ca8fae34 100755 --- a/src/interp/iz3mgr.h +++ b/src/interp/iz3mgr.h @@ -661,6 +661,12 @@ class iz3mgr { ast apply_quant(opr quantifier, ast var, ast e); + // Universally quantify all the free variables in a formula. + // Makes up names for the quntifiers. + + ast close_universally (ast e); + + unsigned num_free_variables(const ast &e); /** For debugging */ void show(ast); diff --git a/src/interp/iz3proof_itp.cpp b/src/interp/iz3proof_itp.cpp index eb7f8e325..fc9d0fac6 100755 --- a/src/interp/iz3proof_itp.cpp +++ b/src/interp/iz3proof_itp.cpp @@ -2968,9 +2968,9 @@ class iz3proof_itp_impl : public iz3proof_itp { ast interpolate(const node &pf){ // proof of false must be a formula, with quantified symbols #ifndef BOGUS_QUANTS - return add_quants(z3_simplify(pf)); + return close_universally(add_quants(z3_simplify(pf))); #else - return z3_simplify(pf); + return close_universally(z3_simplify(pf)); #endif } diff --git a/src/interp/iz3translate.cpp b/src/interp/iz3translate.cpp index ebbee46ca..c59dd0178 100755 --- a/src/interp/iz3translate.cpp +++ b/src/interp/iz3translate.cpp @@ -234,6 +234,11 @@ public: } } + // if(!range_is_empty(rng)){ + // if (num_free_variables(con) > 0) + // rng = range_empty(); + // } + if(res == INT_MAX){ if(range_is_empty(rng)) res = -1; From 6450ee33c58a9dc5e86b7a7b852af46277ce16d5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 26 Sep 2017 08:25:48 -0700 Subject: [PATCH 322/488] disregard model validation when source expression contains uninterpreted theory functions Signed-off-by: Nikolaj Bjorner --- 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 260d49174..3f34f3128 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1763,7 +1763,7 @@ void cmd_context::validate_model() { continue; } try { - for_each_expr(contains_underspecified, r); + for_each_expr(contains_underspecified, a); } catch (contains_underspecified_op_proc::found) { continue; From 2229a2fc1b07e733bbb69bd3f997cfd259134ca7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 26 Sep 2017 08:43:31 -0700 Subject: [PATCH 323/488] model validation update take 2 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 3f34f3128..b2a4fc47f 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1764,6 +1764,7 @@ void cmd_context::validate_model() { } try { for_each_expr(contains_underspecified, a); + for_each_expr(contains_underspecified, r); } catch (contains_underspecified_op_proc::found) { continue; From f07b89df867b29f3dc16633a94f5e204c97fae90 Mon Sep 17 00:00:00 2001 From: Max ulidtko Date: Tue, 26 Sep 2017 17:27:47 +0300 Subject: [PATCH 324/488] fix pydoc part of `make api_docs` --- doc/mk_api_doc.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/mk_api_doc.py b/doc/mk_api_doc.py index 234dd670c..d7e8e2fb1 100644 --- a/doc/mk_api_doc.py +++ b/doc/mk_api_doc.py @@ -288,8 +288,21 @@ try: # Put z3py at the beginning of the search path to try to avoid picking up # an installed copy of Z3py. sys.path.insert(0, os.path.dirname(Z3PY_PACKAGE_PATH)) - pydoc.writedoc('z3') - shutil.move('z3.html', os.path.join(OUTPUT_DIRECTORY, 'html', 'z3.html')) + for modulename in ( + 'z3', + 'z3.z3consts', + 'z3.z3core', + 'z3.z3num', + 'z3.z3poly', + 'z3.z3printer', + 'z3.z3rcf', + 'z3.z3types', + 'z3.z3util', + ): + pydoc.writedoc(modulename) + doc = modulename + '.html' + shutil.move(doc, os.path.join(OUTPUT_DIRECTORY, 'html', doc)) + print("Generated pydoc Z3Py documentation.") if ML_ENABLED: From ce6e26043af3ec3f1e857ab1cfacd6158a472589 Mon Sep 17 00:00:00 2001 From: Max ulidtko Date: Wed, 27 Sep 2017 14:03:38 +0300 Subject: [PATCH 325/488] fix Python API doxygen (`make api_docs`) --- doc/mk_api_doc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/mk_api_doc.py b/doc/mk_api_doc.py index d7e8e2fb1..ab4d32d39 100644 --- a/doc/mk_api_doc.py +++ b/doc/mk_api_doc.py @@ -188,7 +188,7 @@ try: if Z3PY_ENABLED: print("Z3Py documentation enabled") - doxygen_config_substitutions['PYTHON_API_FILES'] = 'z3.py' + doxygen_config_substitutions['PYTHON_API_FILES'] = 'z3*.py' else: print("Z3Py documentation disabled") doxygen_config_substitutions['PYTHON_API_FILES'] = '' From 9a464dded4a0208d29ff604cb91ccf0fbd9e665b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 27 Sep 2017 14:22:59 +0100 Subject: [PATCH 326/488] Removed -std=c++11 from OCaml stubs build command. Fixes #1263. --- scripts/mk_util.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 24f22d8ee..6f3052f6e 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1913,7 +1913,11 @@ class MLComponent(Component): src_dir = self.to_src_dir mk_dir(os.path.join(BUILD_DIR, self.sub_dir)) api_src = get_component(API_COMPONENT).to_src_dir - out.write('CXXFLAGS_OCAML=$(CXXFLAGS:/GL=)\n') # remove /GL; the ocaml tools don't like it. + # remove /GL and -std=c++11; the ocaml tools don't like them. + if IS_WINDOWS: + out.write('CXXFLAGS_OCAML=$(CXXFLAGS:/GL=)\n') + else: + out.write('CXXFLAGS_OCAML=$(subst -std=c++11,,$(CXXFLAGS))\n') if IS_WINDOWS: prefix_lib = '-L' + os.path.abspath(BUILD_DIR).replace('\\', '\\\\') From 8ff8c6433b9c377bae84c5c72084eefa3fbded3a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 30 Sep 2017 10:15:27 -0700 Subject: [PATCH 327/488] fix #1277 fix #1278 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 6 ++++++ src/smt/theory_arith_nl.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index b2a4fc47f..95c030687 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -870,6 +870,12 @@ void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, s lhs = m().mk_app(f, binding.size(), binding.c_ptr()); eq = m().mk_eq(lhs, e); if (!ids.empty()) { + if (is_var(e)) { + ptr_vector domain; + for (expr* b : binding) domain.push_back(m().get_sort(b)); + insert_macro(f->get_name(), domain.size(), domain.c_ptr(), e); + return; + } if (!is_app(e)) { throw cmd_exception("Z3 only supports recursive definitions that are proper terms (not binders or variables)"); } diff --git a/src/smt/theory_arith_nl.h b/src/smt/theory_arith_nl.h index a04c34706..230b6de77 100644 --- a/src/smt/theory_arith_nl.h +++ b/src/smt/theory_arith_nl.h @@ -780,7 +780,7 @@ namespace smt { of a non linear monomial that is not satisfied by the current assignment. if v >= l, then create the case split v >= l+1 else v <= u, then create the case split v <= u-1 - else do nothing and return false. + else create the bound v = 0 and case split on it. */ template bool theory_arith::branch_nl_int_var(theory_var v) { From bec60f763bbe8daf87413088f19a4b7c23ba7e5c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 30 Sep 2017 12:35:36 -0700 Subject: [PATCH 328/488] add diagnostics to DDNF and fix #1268 Signed-off-by: Nikolaj Bjorner --- src/muz/ddnf/ddnf.cpp | 21 ++++++++++++++++----- src/test/ddnf.cpp | 4 ++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/muz/ddnf/ddnf.cpp b/src/muz/ddnf/ddnf.cpp index 0e2f6b35f..da1f5392b 100644 --- a/src/muz/ddnf/ddnf.cpp +++ b/src/muz/ddnf/ddnf.cpp @@ -192,10 +192,15 @@ namespace datalog { for (unsigned i = 0; i < new_tbvs.size(); ++i) { tbv const& nt = *new_tbvs[i]; IF_VERBOSE(10, m_tbv.display(verbose_stream() << "insert: ", nt); verbose_stream() << "\n";); - if (contains(nt)) continue; - ddnf_node* n = alloc(ddnf_node, *this, m_tbv, nt, m_noderefs.size()); - m_noderefs.push_back(n); - m_nodes.insert(n); + ddnf_node* n; + if (contains(nt)) { + n = find(nt); + } + else { + n = alloc(ddnf_node, *this, m_tbv, nt, m_noderefs.size()); + m_noderefs.push_back(n); + m_nodes.insert(n); + } insert(*m_root, n, new_tbvs); } return find(t); @@ -275,13 +280,17 @@ namespace datalog { void insert(ddnf_node& root, ddnf_node* new_n, ptr_vector& new_intersections) { tbv const& new_tbv = new_n->get_tbv(); + IF_VERBOSE(10, m_tbv.display(verbose_stream() << "root: ", root.get_tbv()); + m_tbv.display(verbose_stream() << " new node ", new_tbv); verbose_stream() << "\n";); SASSERT(m_tbv.contains(root.get_tbv(), new_tbv)); - if (&root == new_n) return; + if (m_eq(&root, new_n)) return; ++m_stats.m_num_inserts; bool inserted = false; for (unsigned i = 0; i < root.num_children(); ++i) { ddnf_node& child = *(root[i]); ++m_stats.m_num_comparisons; + IF_VERBOSE(10, m_tbv.display(verbose_stream() << "child ", child.get_tbv()); + verbose_stream() << " contains: " << m_tbv.contains(child.get_tbv(), new_tbv) << "\n";); if (m_tbv.contains(child.get_tbv(), new_tbv)) { inserted = true; insert(child, new_n, new_intersections); @@ -299,11 +308,13 @@ namespace datalog { // checking for subset if (m_tbv.contains(new_tbv, child.get_tbv())) { subset_children.push_back(&child); + IF_VERBOSE(10, m_tbv.display(verbose_stream() << "contains child", child.get_tbv()); verbose_stream() << "\n";); ++m_stats.m_num_comparisons; } else if (m_tbv.intersect(child.get_tbv(), new_tbv, *intr)) { // this means there is a non-full intersection new_intersections.push_back(intr); + IF_VERBOSE(10, m_tbv.display(verbose_stream() << "intersect child ", child.get_tbv()); verbose_stream() << "\n";); intr = m_tbv.allocate(); m_stats.m_num_comparisons += 2; } diff --git a/src/test/ddnf.cpp b/src/test/ddnf.cpp index 09f1a4cf9..c9eb6aa08 100644 --- a/src/test/ddnf.cpp +++ b/src/test/ddnf.cpp @@ -214,6 +214,10 @@ void tst_ddnf1() { ddnf.insert(*tX1); ddnf.insert(*t1X); ddnf.display(std::cout); + tbvm.deallocate(tXX); + tbvm.deallocate(t1X); + tbvm.deallocate(tX1); + tbvm.deallocate(t11); } From 05428314be0a3b7bd6b682d0467efa0fe892c9d5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 1 Oct 2017 15:13:43 -0700 Subject: [PATCH 329/488] fix #1276 related crashes for re-sumption after cancellation Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/maximize_ac_sharing.cpp | 4 ---- src/smt/asserted_formulas.cpp | 7 ++++--- src/smt/smt_context.cpp | 11 ++++++++++- src/util/rlimit.cpp | 5 +++-- src/util/rlimit.h | 15 ++++++++++++++- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/ast/rewriter/maximize_ac_sharing.cpp b/src/ast/rewriter/maximize_ac_sharing.cpp index b560132db..d7e8df7a2 100644 --- a/src/ast/rewriter/maximize_ac_sharing.cpp +++ b/src/ast/rewriter/maximize_ac_sharing.cpp @@ -151,11 +151,7 @@ void maximize_ac_sharing::restore_entries(unsigned old_lim) { } void maximize_ac_sharing::reset() { - restore_entries(0); - m_entries.reset(); m_cache.reset(); - m_region.reset(); - m_scopes.reset(); } void maximize_bv_sharing::init_core() { diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index c52ad851c..11cc846b8 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -170,7 +170,7 @@ void asserted_formulas::get_assertions(ptr_vector & result) const { void asserted_formulas::push_scope() { SASSERT(inconsistent() || m_qhead == m_formulas.size() || m.canceled()); - TRACE("asserted_formulas_scopes", tout << "push:\n"; display(tout);); + TRACE("asserted_formulas_scopes", tout << "before push: " << m_scopes.size() << "\n";); m_scoped_substitution.push(); m_scopes.push_back(scope()); scope & s = m_scopes.back(); @@ -181,10 +181,11 @@ void asserted_formulas::push_scope() { m_bv_sharing.push_scope(); m_macro_manager.push_scope(); commit(); + TRACE("asserted_formulas_scopes", tout << "after push: " << m_scopes.size() << "\n";); } void asserted_formulas::pop_scope(unsigned num_scopes) { - TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << "\n"; display(tout);); + TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << " of " << m_scopes.size() << "\n";); m_bv_sharing.pop_scope(num_scopes); m_macro_manager.pop_scope(num_scopes); unsigned new_lvl = m_scopes.size() - num_scopes; @@ -196,7 +197,7 @@ void asserted_formulas::pop_scope(unsigned num_scopes) { m_qhead = s.m_formulas_lim; m_scopes.shrink(new_lvl); flush_cache(); - TRACE("asserted_formulas_scopes", tout << "after pop " << num_scopes << "\n"; display(tout);); + TRACE("asserted_formulas_scopes", tout << "after pop " << num_scopes << "\n";); } void asserted_formulas::reset() { diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 901f4b5ac..ac7b1f44b 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -487,6 +487,7 @@ namespace smt { */ void context::add_eq(enode * n1, enode * n2, eq_justification js) { unsigned old_trail_size = m_trail_stack.size(); + scoped_suspend_rlimit _suspend_cancel(m_manager.limit()); try { TRACE("add_eq", tout << "assigning: #" << n1->get_owner_id() << " = #" << n2->get_owner_id() << "\n";); @@ -541,10 +542,14 @@ namespace smt { mark_as_relevant(r1); } + TRACE("add_eq", tout << "to trail\n";); + push_trail(add_eq_trail(r1, n1, r2->get_num_parents())); + TRACE("add_eq", tout << "qmanager add_eq\n";); m_qmanager->add_eq_eh(r1, r2); + TRACE("add_eq", tout << "merge theory_vars\n";); merge_theory_vars(n2, n1, js); // 'Proof' tree @@ -577,6 +582,7 @@ namespace smt { #endif + TRACE("add_eq", tout << "remove_parents_from_cg_table\n";); remove_parents_from_cg_table(r1); enode * curr = r1; @@ -588,8 +594,10 @@ namespace smt { SASSERT(r1->get_root() == r2); + TRACE("add_eq", tout << "reinsert_parents_into_cg_table\n";); reinsert_parents_into_cg_table(r1, r2, n1, n2, js); + TRACE("add_eq", tout << "propagate_bool_enode_assignment\n";); if (n2->is_bool()) propagate_bool_enode_assignment(r1, r2, n1, n2); @@ -604,6 +612,7 @@ namespace smt { catch (...) { // Restore trail size since procedure was interrupted in the middle. // If the add_eq_trail remains on the trail stack, then Z3 may crash when the destructor is invoked. + TRACE("add_eq", tout << "add_eq interrupted. This is unsafe " << m_manager.limit().get_cancel_flag() << "\n";); m_trail_stack.shrink(old_trail_size); throw; } @@ -972,7 +981,7 @@ namespace smt { enode * parent = *it; if (parent->is_cgc_enabled()) { TRACE("add_eq_parents", tout << "removing: #" << parent->get_owner_id() << "\n";); - CTRACE("add_eq", !parent->is_cgr(), + CTRACE("add_eq", !parent->is_cgr() || !m_cg_table.contains_ptr(parent), tout << "old num_parents: " << r2_num_parents << ", num_parents: " << r2->m_parents.size() << ", parent: #" << parent->get_owner_id() << ", parents: \n"; for (unsigned i = 0; i < r2->m_parents.size(); i++) { diff --git a/src/util/rlimit.cpp b/src/util/rlimit.cpp index f3f45c654..e625cab95 100644 --- a/src/util/rlimit.cpp +++ b/src/util/rlimit.cpp @@ -21,6 +21,7 @@ Revision History: reslimit::reslimit(): m_cancel(0), + m_suspend(false), m_count(0), m_limit(0) { } @@ -31,12 +32,12 @@ uint64 reslimit::count() const { bool reslimit::inc() { ++m_count; - return m_cancel == 0 && (m_limit == 0 || m_count <= m_limit); + return (m_cancel == 0 && (m_limit == 0 || m_count <= m_limit)) || m_suspend; } bool reslimit::inc(unsigned offset) { m_count += offset; - return m_cancel == 0 && (m_limit == 0 || m_count <= m_limit); + return (m_cancel == 0 && (m_limit == 0 || m_count <= m_limit)) || m_suspend; } void reslimit::push(unsigned delta_limit) { diff --git a/src/util/rlimit.h b/src/util/rlimit.h index 3b278d132..0c81f9449 100644 --- a/src/util/rlimit.h +++ b/src/util/rlimit.h @@ -23,12 +23,14 @@ Revision History: class reslimit { volatile unsigned m_cancel; + bool m_suspend; uint64 m_count; uint64 m_limit; svector m_limits; ptr_vector m_children; void set_cancel(unsigned f); + friend class scoped_suspend_rlimit; public: reslimit(); @@ -42,7 +44,7 @@ public: uint64 count() const; - bool get_cancel_flag() const { return m_cancel > 0; } + bool get_cancel_flag() const { return m_cancel > 0 && !m_suspend; } char const* get_cancel_msg() const; void cancel(); void reset_cancel(); @@ -61,6 +63,17 @@ public: }; +class scoped_suspend_rlimit { + reslimit & m_limit; +public: + scoped_suspend_rlimit(reslimit& r): m_limit(r) { + r.m_suspend = true; + } + ~scoped_suspend_rlimit() { + m_limit.m_suspend = false; + } +}; + struct scoped_limits { reslimit& m_limit; unsigned m_sz; From e0e23975665e4344f853c8f9a51ab34ff50e5f3c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 1 Oct 2017 19:40:30 -0700 Subject: [PATCH 330/488] missing setup datatypes for QF_DT Signed-off-by: Nikolaj Bjorner --- src/smt/smt_model_generator.cpp | 18 ++++++++++-------- src/smt/smt_setup.cpp | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/smt/smt_model_generator.cpp b/src/smt/smt_model_generator.cpp index 5848fac62..df6865f1e 100644 --- a/src/smt/smt_model_generator.cpp +++ b/src/smt/smt_model_generator.cpp @@ -54,7 +54,7 @@ namespace smt { ptr_vector::const_iterator it = m_context->begin_theories(); ptr_vector::const_iterator end = m_context->end_theories(); for (; it != end; ++it) { - TRACE("model_generator_bug", tout << "init_model for theory: " << (*it)->get_name() << "\n";); + TRACE("model", tout << "init_model for theory: " << (*it)->get_name() << "\n";); (*it)->init_model(*this); } } @@ -91,7 +91,7 @@ namespace smt { sort * s = m_manager.get_sort(r->get_owner()); model_value_proc * proc = 0; if (m_manager.is_bool(s)) { - CTRACE("func_interp_bug", m_context->get_assignment(r) == l_undef, + CTRACE("model", m_context->get_assignment(r) == l_undef, tout << mk_pp(r->get_owner(), m_manager) << "\n";); SASSERT(m_context->get_assignment(r) != l_undef); if (m_context->get_assignment(r) == l_true) @@ -108,7 +108,7 @@ namespace smt { SASSERT(proc); } else { - TRACE("model_bug", tout << "creating fresh value for #" << r->get_owner_id() << "\n";); + TRACE("model", tout << "creating fresh value for #" << r->get_owner_id() << "\n";); proc = alloc(fresh_value_proc, mk_extra_fresh_value(m_manager.get_sort(r->get_owner()))); } } @@ -130,7 +130,7 @@ namespace smt { if (!m_manager.is_model_value(n)) { sort * s = m_manager.get_sort(r->get_owner()); n = m_model->get_fresh_value(s); - CTRACE("model_generator_bug", n == 0, + CTRACE("model", n == 0, tout << mk_pp(r->get_owner(), m_manager) << "\nsort:\n" << mk_pp(s, m_manager) << "\n"; tout << "is_finite: " << m_model->is_finite(s) << "\n";); } @@ -406,9 +406,11 @@ namespace smt { */ bool model_generator::include_func_interp(func_decl * f) const { family_id fid = f->get_family_id(); + TRACE("model", tout << f->get_name() << " " << fid << "\n";); if (fid == null_family_id) return !m_hidden_ufs.contains(f); if (fid == m_manager.get_basic_family_id()) return false; theory * th = m_context->get_theory(fid); + TRACE("model", tout << th << "\n";); if (!th) return true; return th->include_func_interp(f); } @@ -443,7 +445,7 @@ namespace smt { SASSERT(m_model->has_interpretation(f)); SASSERT(m_model->get_func_interp(f) == fi); // The entry must be new because n->get_cg() == n - TRACE("func_interp_bug", + TRACE("model", tout << "insert new entry for:\n" << mk_ismt2_pp(n->get_owner(), m_manager) << "\nargs: "; for (unsigned i = 0; i < num_args; i++) { tout << "#" << n->get_arg(i)->get_owner_id() << " "; @@ -507,20 +509,20 @@ namespace smt { void model_generator::register_macros() { unsigned num = m_context->get_num_macros(); - TRACE("register_macros", tout << "num. macros: " << num << "\n";); + TRACE("model", tout << "num. macros: " << num << "\n";); expr_ref v(m_manager); for (unsigned i = 0; i < num; i++) { func_decl * f = m_context->get_macro_interpretation(i, v); func_interp * fi = alloc(func_interp, m_manager, f->get_arity()); fi->set_else(v); - TRACE("register_macros", tout << f->get_name() << "\n" << mk_pp(v, m_manager) << "\n";); + TRACE("model", tout << f->get_name() << "\n" << mk_pp(v, m_manager) << "\n";); m_model->register_decl(f, fi); } } proto_model * model_generator::mk_model() { SASSERT(!m_model); - TRACE("func_interp_bug", m_context->display(tout);); + TRACE("model", m_context->display(tout);); init_model(); register_existing_model_values(); mk_bool_model(); diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 56b5d541a..631805b4d 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -216,6 +216,7 @@ namespace smt { void setup::setup_QF_DT() { setup_QF_UF(); + setup_datatypes(); } void setup::setup_QF_BVRE() { From 6c7a82edceef5e96476b2e80433d4b1a1a61b103 Mon Sep 17 00:00:00 2001 From: Miguel Angelo Da Terra Neves Date: Mon, 2 Oct 2017 09:20:59 -0700 Subject: [PATCH 331/488] update to _get_args to convert arguments from AstVector to a python list Signed-off-by: Miguel Angelo Da Terra Neves --- src/api/python/z3/z3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py index 39af03190..a521c5169 100644 --- a/src/api/python/z3/z3.py +++ b/src/api/python/z3/z3.py @@ -120,7 +120,7 @@ def _get_args(args): try: if len(args) == 1 and (isinstance(args[0], tuple) or isinstance(args[0], list)): return args[0] - elif len(args) == 1 and isinstance(args[0], set): + elif len(args) == 1 and (isinstance(args[0], set) or isinstance(args[0], AstVector)): return [arg for arg in args[0]] else: return args From 2828126b725362ee08daf0cf8a774d0b09cc3dcb Mon Sep 17 00:00:00 2001 From: Lev Nachmanson Date: Tue, 3 Oct 2017 10:20:49 -0700 Subject: [PATCH 332/488] add cancellation checks Signed-off-by: Lev Nachmanson --- src/util/lp/lar_solver.h | 2 + src/util/lp/lp_primal_core_solver_tableau.h | 45 ++++++++++++--------- src/util/lp/lp_settings.h | 3 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/util/lp/lar_solver.h b/src/util/lp/lar_solver.h index 1ed30bd70..6d2cbea7d 100644 --- a/src/util/lp/lar_solver.h +++ b/src/util/lp/lar_solver.h @@ -417,6 +417,8 @@ public: for (unsigned i : m_rows_with_changed_bounds.m_index) { calculate_implied_bounds_for_row(i, bp); + if (settings().get_cancel_flag()) + return; } m_rows_with_changed_bounds.clear(); if (!use_tableau()) { diff --git a/src/util/lp/lp_primal_core_solver_tableau.h b/src/util/lp/lp_primal_core_solver_tableau.h index 5c7d4d2c2..d2b8c1a26 100644 --- a/src/util/lp/lp_primal_core_solver_tableau.h +++ b/src/util/lp/lp_primal_core_solver_tableau.h @@ -176,25 +176,34 @@ unsigned lp_primal_core_solver::solve_with_tableau() { default: break; // do nothing } - } while (this->get_status() != FLOATING_POINT_ERROR - && - this->get_status() != UNBOUNDED - && - this->get_status() != OPTIMAL - && - this->get_status() != INFEASIBLE - && - this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements - && - this->total_iterations() <= this->m_settings.max_total_number_of_iterations - && - !(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only)); + } while (this->get_status() != FLOATING_POINT_ERROR + && + this->get_status() != UNBOUNDED + && + this->get_status() != OPTIMAL + && + this->get_status() != INFEASIBLE + && + this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements + && + this->total_iterations() <= this->m_settings.max_total_number_of_iterations + && + !(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) + && + m_settings.get_cancel_flag() == false); + + if (m_settings.get_cancel_flag()) { + this->set_status(CANCELLED); + } - SASSERT(this->get_status() == FLOATING_POINT_ERROR - || - this->current_x_is_feasible() == false - || - this->calc_current_x_is_feasible_include_non_basis()); + SASSERT( + this->get_status() == FLOATING_POINT_ERROR + || + this->get_status() == CANCELLED + || + this->current_x_is_feasible() == false + || + this->calc_current_x_is_feasible_include_non_basis()); return this->total_iterations(); } diff --git a/src/util/lp/lp_settings.h b/src/util/lp/lp_settings.h index 70a9f1504..a7e6e2665 100644 --- a/src/util/lp/lp_settings.h +++ b/src/util/lp/lp_settings.h @@ -61,7 +61,8 @@ enum lp_status { TIME_EXHAUSTED, ITERATIONS_EXHAUSTED, EMPTY, - UNSTABLE + UNSTABLE, + CANCELLED }; // when the ratio of the vector lenth to domain size to is greater than the return value we switch to solve_By_for_T_indexed_only From fd3d785a5b41715a5a1c61ea03038c550483030e Mon Sep 17 00:00:00 2001 From: Lev Nachmanson Date: Wed, 4 Oct 2017 14:49:45 -0700 Subject: [PATCH 333/488] add this-> Signed-off-by: Lev Nachmanson --- src/util/lp/lp_primal_core_solver_tableau.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util/lp/lp_primal_core_solver_tableau.h b/src/util/lp/lp_primal_core_solver_tableau.h index d2b8c1a26..0c56f0ab9 100644 --- a/src/util/lp/lp_primal_core_solver_tableau.h +++ b/src/util/lp/lp_primal_core_solver_tableau.h @@ -190,10 +190,10 @@ unsigned lp_primal_core_solver::solve_with_tableau() { && !(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) && - m_settings.get_cancel_flag() == false); + this->m_settings.get_cancel_flag() == false); - if (m_settings.get_cancel_flag()) { - this->set_status(CANCELLED); + if (this->m_settings.get_cancel_flag()) { + this->set_status(CANCELLED); } SASSERT( From 110d558ee4262721f3ab2c999d789eaf84ac15d6 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Thu, 5 Oct 2017 08:53:12 +0100 Subject: [PATCH 334/488] dom_simplify_tactic: micro opt --- src/tactic/core/dom_simplify_tactic.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 595f8f7c6..d4a3031cd 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -225,9 +225,8 @@ expr_ref dom_simplify_tactic::simplify(expr * e0) { } else { expr_dominators::tree_t const& t = m_dominators.get_tree(); - if (t.contains(e)) { - ptr_vector const& children = t[e]; - for (expr * child : children) { + if (auto children = t.find_core(e)) { + for (expr * child : children->get_data().m_value) { simplify(child); } } From 53fc6ac11b25593e3827c943f5d61ce9f28da7ca Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Thu, 5 Oct 2017 14:27:56 +0100 Subject: [PATCH 335/488] [TravisCI] Refactor as many CI default options as possible so that the Docker and "TravisCI macOS" builds share most of the same defaults by sourcing the `ci_defaults.sh` file. --- contrib/ci/Dockerfiles/z3_build.Dockerfile | 50 ++++++++--------- contrib/ci/scripts/ci_defaults.sh | 54 +++++++++++++++++++ .../ci/scripts/travis_ci_linux_entry_point.sh | 4 +- .../ci/scripts/travis_ci_osx_entry_point.sh | 30 ++--------- 4 files changed, 86 insertions(+), 52 deletions(-) create mode 100644 contrib/ci/scripts/ci_defaults.sh diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 2d16d5394..5f7608cf4 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -2,34 +2,33 @@ ARG DOCKER_IMAGE_BASE FROM ${DOCKER_IMAGE_BASE} -# Specify defaults. This can be changed when invoking +# Build arguments. This can be changed when invoking # `docker build`. -ARG ASAN_BUILD=0 -ARG BUILD_DOCS=0 -ARG CC=gcc -ARG CXX=g++ -ARG DOTNET_BINDINGS=1 -ARG JAVA_BINDINGS=1 -ARG NO_SUPPRESS_OUTPUT=0 -ARG PYTHON_BINDINGS=1 -ARG PYTHON_EXECUTABLE=/usr/bin/python2.7 -ARG RUN_SYSTEM_TESTS=1 -ARG RUN_UNIT_TESTS=1 -ARG TARGET_ARCH=x86_64 -ARG TEST_INSTALL=1 -ARG UBSAN_BUILD=0 -ARG USE_LIBGMP=0 -ARG USE_LTO=0 -ARG USE_OPENMP=1 +ARG ASAN_BUILD +ARG BUILD_DOCS +ARG CC +ARG CXX +ARG DOTNET_BINDINGS +ARG JAVA_BINDINGS +ARG NO_SUPPRESS_OUTPUT +ARG PYTHON_BINDINGS +ARG PYTHON_EXECUTABLE +ARG RUN_SYSTEM_TESTS +ARG RUN_UNIT_TESTS +ARG TARGET_ARCH +ARG TEST_INSTALL +ARG UBSAN_BUILD +ARG USE_LIBGMP +ARG USE_LTO +ARG USE_OPENMP ARG Z3_SRC_DIR=/home/user/z3_src -ARG Z3_BUILD_TYPE=RelWithDebInfo -ARG Z3_CMAKE_GENERATOR=Ninja -ARG Z3_INSTALL_PREFIX=/usr -ARG Z3_STATIC_BUILD=0 -# Blank default indicates use latest. +ARG Z3_BUILD_TYPE +ARG Z3_CMAKE_GENERATOR +ARG Z3_INSTALL_PREFIX +ARG Z3_STATIC_BUILD ARG Z3_SYSTEM_TEST_GIT_REVISION -ARG Z3_WARNINGS_AS_ERRORS=SERIOUS_ONLY -ARG Z3_VERBOSE_BUILD_OUTPUT=0 +ARG Z3_WARNINGS_AS_ERRORS +ARG Z3_VERBOSE_BUILD_OUTPUT ENV \ ASAN_BUILD=${ASAN_BUILD} \ @@ -74,6 +73,7 @@ ADD *.txt *.md RELEASE_NOTES ${Z3_SRC_DIR}/ ADD \ /contrib/ci/scripts/build_z3_cmake.sh \ + /contrib/ci/scripts/ci_defaults.sh \ /contrib/ci/scripts/set_compiler_flags.sh \ /contrib/ci/scripts/set_generator_args.sh \ ${Z3_SRC_DIR}/contrib/ci/scripts/ diff --git a/contrib/ci/scripts/ci_defaults.sh b/contrib/ci/scripts/ci_defaults.sh new file mode 100644 index 000000000..354ea95b7 --- /dev/null +++ b/contrib/ci/scripts/ci_defaults.sh @@ -0,0 +1,54 @@ +# This file should be sourced by other scripts +# and not executed directly + +# Set CI build defaults + +export ASAN_BUILD="${ASAN_BUILD:-0}" +export BUILD_DOCS="${BUILD_DOCS:-0}" +export DOTNET_BINDINGS="${DOTNET_BINDINGS:-1}" +export JAVA_BINDINGS="${JAVA_BINDINGS:-1}" +export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}" +export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}" +export PYTHON_EXECUTABLE="${PYTHON_EXECUTABLE:-$(which python)}" +export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}" +export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}" +export TARGET_ARCH="${TARGET_ARCH:-x86_64}" +export TEST_INSTALL="${TEST_INSTALL:-1}" +export UBSAN_BUILD="${UBSAN_BUILD:-0}" +export USE_LIBGMP="${USE_LIBGMP:-0}" +export USE_LTO="${USE_LTO:-0}" +export USE_OPENMP="${USE_OPENMP:-1}" + +export Z3_BUILD_TYPE="${Z3_BUILD_TYPE:-RelWithDebInfo}" +export Z3_CMAKE_GENERATOR="${Z3_CMAKE_GENERATOR:-Ninja}" +export Z3_STATIC_BUILD="${Z3_STATIC_BUILD:-0}" +# Default is blank which means get latest revision +export Z3_SYSTEM_TEST_GIT_REVISION="${Z3_SYSTEM_TEST_GIT_REVISION:-}" +export Z3_WARNINGS_AS_ERRORS="${Z3_WARNINGS_AS_ERRORS:-SERIOUS_ONLY}" +export Z3_VERBOSE_BUILD_OUTPUT="${Z3_VERBOSE_BUILD_OUTPUT:-0}" + +# Platform specific defaults +PLATFORM="$(uname -s)" +case "${PLATFORM}" in + Linux*) + export C_COMPILER="${C_COMPILER:-gcc}" + export CXX_COMPILER="${CXX_COMPILER:-g++}" + export Z3_INSTALL_PREFIX="${Z3_INSTALL_PREFIX:-/usr}" + ;; + Darwin*) + export C_COMPILER="${C_COMPILER:-clang}" + export CXX_COMPILER="${CXX_COMPILER:-clang++}" + export Z3_INSTALL_PREFIX="${Z3_INSTALL_PREFIX:-/usr/local}" + ;; + *) + echo "Unknown platform \"${PLATFORM}\"" + exit 1 + ;; +esac +unset PLATFORM + +# NOTE: The following variables are not set here because +# they are specific to the CI implementation +# Z3_SRC_DIR +# Z3_BUILD_DIR +# Z3_SYSTEM_TEST_DIR diff --git a/contrib/ci/scripts/travis_ci_linux_entry_point.sh b/contrib/ci/scripts/travis_ci_linux_entry_point.sh index 84b2dd400..c0f856faa 100755 --- a/contrib/ci/scripts/travis_ci_linux_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_linux_entry_point.sh @@ -11,13 +11,15 @@ DOCKER_FILE_DIR="$(cd ${SCRIPT_DIR}/../Dockerfiles; echo $PWD)" : ${LINUX_BASE?"LINUX_BASE must be specified"} - # Sanity check. Current working directory should be repo root if [ ! -f "./README.md" ]; then echo "Current working directory should be repo root" exit 1 fi +# Get defaults +source "${SCRIPT_DIR}/ci_defaults.sh" + BUILD_OPTS=() # Override options if they have been provided. # Otherwise the defaults in the Docker file will be used diff --git a/contrib/ci/scripts/travis_ci_osx_entry_point.sh b/contrib/ci/scripts/travis_ci_osx_entry_point.sh index c5e8b4c02..7dd566877 100755 --- a/contrib/ci/scripts/travis_ci_osx_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_osx_entry_point.sh @@ -6,26 +6,8 @@ set -x set -e set -o pipefail -# Set defaults -# FIXME: Refactor this so we don't need to stay in sync with -# `z3_build.Dockerfile`. -export ASAN_BUILD="${ASAN_BUILD:-0}" -export BUILD_DOCS="${BUILD_DOCS:-0}" -export C_COMPILER="${C_COMPILER:-clang}" -export CXX_COMPILER="${CXX_COMPILER:-clang++}" -export DOTNET_BINDINGS="${DOTNET_BINDINGS:-1}" -export JAVA_BINDINGS="${JAVA_BINDINGS:-1}" -export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}" -export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}" -export PYTHON_EXECUTABLE="$(which python)" -export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}" -export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}" -export TARGET_ARCH="${TARGET_ARCH:-x86_64}" -export TEST_INSTALL="${TEST_INSTALL:-1}" -export UBSAN_BUILD="${UBSAN_BUILD:-0}" -export USE_LIBGMP="${USE_LIBGMP:-0}" -export USE_LTO="${USE_LTO:-0}" -export USE_OPENMP="${USE_OPENMP:-1}" +# Get defaults +source "${SCRIPT_DIR}/ci_defaults.sh" if [ -z "${TRAVIS_BUILD_DIR}" ]; then echo "TRAVIS_BUILD_DIR must be set to root of Z3 repository" @@ -37,15 +19,11 @@ if [ ! -d "${TRAVIS_BUILD_DIR}" ]; then exit 1 fi +# These three variables are specific to the macOS TravisCI +# implementation and are not set in `ci_defaults.sh`. export Z3_SRC_DIR="${TRAVIS_BUILD_DIR}" export Z3_BUILD_DIR="${Z3_SRC_DIR}/build" -export Z3_BUILD_TYPE="${Z3_BUILD_TYPE:-RelWithDebInfo}" -export Z3_CMAKE_GENERATOR="${Z3_CMAKE_GENERATOR:-Ninja}" -export Z3_INSTALL_PREFIX="${Z3_INSTALL_PREFIX:-/usr/local}" -export Z3_STATIC_BUILD="${Z3_STATIC_BUILD:-0}" export Z3_SYSTEM_TEST_DIR="${Z3_SRC_DIR}/z3_system_test" -export Z3_WARNINGS_AS_ERRORS="${Z3_WARNINGS_AS_ERRORS:-SERIOUS_ONLY}" -export Z3_VERBOSE_BUILD_OUTPUT="${Z3_VERBOSE_BUILD_OUTPUT:-0}" # Overwrite whatever what set in TravisCI export CC="${C_COMPILER}" From eb975a49d606bcdb076b523d0506bf855ef8d267 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Thu, 5 Oct 2017 14:44:41 +0100 Subject: [PATCH 336/488] [TravisCI] Fix bug where `Z3_BUILD_TYPE` was not being passed as a Docker build argument. Also update an out of date comment. --- contrib/ci/scripts/travis_ci_linux_entry_point.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/contrib/ci/scripts/travis_ci_linux_entry_point.sh b/contrib/ci/scripts/travis_ci_linux_entry_point.sh index c0f856faa..bd2c9d2d1 100755 --- a/contrib/ci/scripts/travis_ci_linux_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_linux_entry_point.sh @@ -21,8 +21,11 @@ fi source "${SCRIPT_DIR}/ci_defaults.sh" BUILD_OPTS=() -# Override options if they have been provided. -# Otherwise the defaults in the Docker file will be used +# Pass Docker build arguments +if [ -n "${Z3_BUILD_TYPE}" ]; then + BUILD_OPTS+=("--build-arg" "Z3_BUILD_TYPE=${Z3_BUILD_TYPE}") +fi + if [ -n "${Z3_CMAKE_GENERATOR}" ]; then BUILD_OPTS+=("--build-arg" "Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR}") fi From 0633d5819f8b996b3300f177efe6b1406a1285a5 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Thu, 5 Oct 2017 15:09:16 +0100 Subject: [PATCH 337/488] [TravisCI] Fix bug. `PYTHON_EXECUTABLE` should not be in common defaults. The location is dependent on the implementation. This triggered a build failure on TravisCI because the location of the default Python binary is different to what is in the Docker container. --- contrib/ci/Dockerfiles/z3_build.Dockerfile | 2 +- contrib/ci/scripts/ci_defaults.sh | 2 +- contrib/ci/scripts/travis_ci_osx_entry_point.sh | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 5f7608cf4..07504e6b9 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -12,7 +12,7 @@ ARG DOTNET_BINDINGS ARG JAVA_BINDINGS ARG NO_SUPPRESS_OUTPUT ARG PYTHON_BINDINGS -ARG PYTHON_EXECUTABLE +ARG PYTHON_EXECUTABLE=/usr/bin/python2.7 ARG RUN_SYSTEM_TESTS ARG RUN_UNIT_TESTS ARG TARGET_ARCH diff --git a/contrib/ci/scripts/ci_defaults.sh b/contrib/ci/scripts/ci_defaults.sh index 354ea95b7..2fb3fa52a 100644 --- a/contrib/ci/scripts/ci_defaults.sh +++ b/contrib/ci/scripts/ci_defaults.sh @@ -9,7 +9,6 @@ export DOTNET_BINDINGS="${DOTNET_BINDINGS:-1}" export JAVA_BINDINGS="${JAVA_BINDINGS:-1}" export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}" export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}" -export PYTHON_EXECUTABLE="${PYTHON_EXECUTABLE:-$(which python)}" export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}" export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}" export TARGET_ARCH="${TARGET_ARCH:-x86_64}" @@ -49,6 +48,7 @@ unset PLATFORM # NOTE: The following variables are not set here because # they are specific to the CI implementation +# PYTHON_EXECUTABLE # Z3_SRC_DIR # Z3_BUILD_DIR # Z3_SYSTEM_TEST_DIR diff --git a/contrib/ci/scripts/travis_ci_osx_entry_point.sh b/contrib/ci/scripts/travis_ci_osx_entry_point.sh index 7dd566877..ad3b0c7ab 100755 --- a/contrib/ci/scripts/travis_ci_osx_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_osx_entry_point.sh @@ -19,8 +19,9 @@ if [ ! -d "${TRAVIS_BUILD_DIR}" ]; then exit 1 fi -# These three variables are specific to the macOS TravisCI +# These variables are specific to the macOS TravisCI # implementation and are not set in `ci_defaults.sh`. +export PYTHON_EXECUTABLE="${PYTHON_EXECUTABLE:-$(which python)}" export Z3_SRC_DIR="${TRAVIS_BUILD_DIR}" export Z3_BUILD_DIR="${Z3_SRC_DIR}/build" export Z3_SYSTEM_TEST_DIR="${Z3_SRC_DIR}/z3_system_test" From 6268ff1fa13d283c9b4b0461f2b4423509a554ee Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Thu, 5 Oct 2017 18:10:20 +0100 Subject: [PATCH 338/488] dom_simplify improvements with Nikolaj --- src/tactic/core/dom_simplify_tactic.cpp | 129 ++++++++++++++++-------- src/tactic/core/dom_simplify_tactic.h | 19 +++- 2 files changed, 102 insertions(+), 46 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index d4a3031cd..85b7fd9d6 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -95,13 +95,16 @@ void expr_dominators::compute_dominators() { expr * child = m_post2expr[i]; ptr_vector const& p = m_parents[child]; SASSERT(!p.empty()); - expr * new_idom = p[0], * idom2 = 0; - for (unsigned j = 1; j < p.size(); ++j) { - if (m_doms.find(p[j], idom2)) { + expr * new_idom = 0, *idom2 = 0; + for (unsigned j = 0; j < p.size(); ++j) { + if (!new_idom) { + m_doms.find(p[j], new_idom); + } + else if (m_doms.find(p[j], idom2)) { new_idom = intersect(new_idom, idom2); } } - if (!m_doms.find(child, idom2) || idom2 != new_idom) { + if (new_idom && (!m_doms.find(child, idom2) || idom2 != new_idom)) { m_doms.insert(child, new_idom); change = true; } @@ -113,7 +116,7 @@ void expr_dominators::extract_tree() { for (auto const& kv : m_doms) { add_edge(m_tree, kv.m_value, kv.m_key); } -} +} void expr_dominators::compile(expr * e) { reset(); @@ -147,9 +150,9 @@ tactic * dom_simplify_tactic::translate(ast_manager & m) { } void dom_simplify_tactic::operator()( - goal_ref const & in, - goal_ref_buffer & result, - model_converter_ref & mc, + goal_ref const & in, + goal_ref_buffer & result, + model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { mc = 0; pc = 0; core = 0; @@ -162,33 +165,41 @@ void dom_simplify_tactic::operator()( } void dom_simplify_tactic::cleanup() { - m_trail.reset(); - m_args.reset(); - m_args2.reset(); - m_result.reset(); - m_dominators.reset(); + m_trail.reset(); + m_args.reset(); + m_args2.reset(); + m_result.reset(); + m_dominators.reset(); } expr_ref dom_simplify_tactic::simplify_ite(app * ite) { expr_ref r(m); - expr * c = 0, * t = 0, * e = 0; + expr * c = 0, *t = 0, *e = 0; VERIFY(m.is_ite(ite, c, t, e)); unsigned old_lvl = scope_level(); expr_ref new_c = simplify(c); if (m.is_true(new_c)) { r = simplify(t); - } - else if (m.is_false(new_c) || !assert_expr(new_c, false)) { + } else if (m.is_false(new_c) || !assert_expr(new_c, false)) { r = simplify(e); - } - else { - expr_ref new_t = simplify(t); + } else { + for (expr * child : tree(ite)) { + if (is_subexpr(child, t) && !is_subexpr(child, e)) { + simplify(child); + } + } pop(scope_level() - old_lvl); + expr_ref new_t = simplify(t); if (!assert_expr(new_c, true)) { return new_t; } - expr_ref new_e = simplify(e); + for (expr * child : tree(ite)) { + if (is_subexpr(child, e) && !is_subexpr(child, t)) { + simplify(child); + } + } pop(scope_level() - old_lvl); + expr_ref new_e = simplify(e); if (c == new_c && t == new_t && e == new_e) { r = ite; } @@ -197,7 +208,7 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { } else { TRACE("tactic", tout << new_c << "\n" << new_t << "\n" << new_e << "\n";); - r = m.mk_ite(new_c, new_t, new_c); + r = m.mk_ite(new_c, new_t, new_e); } } return r; @@ -224,11 +235,8 @@ expr_ref dom_simplify_tactic::simplify(expr * e0) { r = simplify_or(to_app(e)); } else { - expr_dominators::tree_t const& t = m_dominators.get_tree(); - if (auto children = t.find_core(e)) { - for (expr * child : children->get_data().m_value) { - simplify(child); - } + for (expr * child : tree(e)) { + simplify(child); } if (is_app(e)) { m_args.reset(); @@ -251,27 +259,33 @@ expr_ref dom_simplify_tactic::simplify(expr * e0) { expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { expr_ref r(m); unsigned old_lvl = scope_level(); - m_args.reset(); + + auto is_subexpr_arg = [&](expr * child, expr * except) { + if (!is_subexpr(child, except)) + return false; + for (expr * arg : *e) { + if (arg != except && is_subexpr(child, arg)) + return false; + } + return true; + }; + + expr_ref_vector args(m); for (expr * arg : *e) { - r = simplify(arg); - if (!assert_expr(r, !is_and)) { - r = is_and ? m.mk_false() : m.mk_true(); + for (expr * child : tree(arg)) { + if (is_subexpr_arg(child, arg)) { + simplify(child); + } + } + r = simplify(arg); + args.push_back(r); + if (!assert_expr(simplify(arg), !is_and)) { + r = is_and ? m.mk_false() : m.mk_true(); + return r; } - m_args.push_back(r); } pop(scope_level() - old_lvl); - m_args.reverse(); - m_args2.reset(); - for (expr * arg : m_args) { - r = simplify(arg); - if (!assert_expr(r, !is_and)) { - r = is_and ? m.mk_false() : m.mk_true(); - } - m_args2.push_back(r); - } - pop(scope_level() - old_lvl); - m_args2.reverse(); - r = is_and ? mk_and(m_args2) : mk_or(m_args2); + r = is_and ? mk_and(args) : mk_or(args); return r; } @@ -332,11 +346,36 @@ void dom_simplify_tactic::simplify_goal(goal& g) { SASSERT(scope_level() == 0); } +bool dom_simplify_tactic::is_subexpr(expr * a, expr * b) { + if (a == b) + return true; + + bool r; + if (m_subexpr_cache.find(a, b, r)) + return r; + + for (expr * e : tree(b)) { + if (is_subexpr(a, e)) { + m_subexpr_cache.insert(a, b, true); + return true; + } + } + m_subexpr_cache.insert(a, b, false); + return false; +} + +ptr_vector const & dom_simplify_tactic::tree(expr * e) { + if (auto p = m_dominators.get_tree().find_core(e)) + return p->get_data().get_value(); + return m_empty; +} + // ---------------------- // expr_substitution_simplifier bool expr_substitution_simplifier::assert_expr(expr * t, bool sign) { + m_scoped_substitution.push(); expr* tt; if (!sign) { update_substitution(t, 0); @@ -439,3 +478,7 @@ void expr_substitution_simplifier::compute_depth(expr* e) { m_expr2depth.insert(e, d + 1); } } + +tactic * mk_dom_simplify_tactic(ast_manager & m, params_ref const & p) { + return clean(alloc(dom_simplify_tactic, m, alloc(expr_substitution_simplifier, m), p)); +} diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 2fa79dd1d..9fe59de23 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -23,6 +23,8 @@ Notes: #include "ast/ast.h" #include "ast/expr_substitution.h" #include "tactic/tactic.h" +#include "tactic/tactical.h" +#include "util/obj_pair_hashtable.h" class expr_dominators { @@ -89,6 +91,8 @@ private: unsigned m_scope_level; unsigned m_depth; unsigned m_max_depth; + ptr_vector m_empty; + obj_pair_map m_subexpr_cache; expr_ref simplify(expr* t); expr_ref simplify_ite(app * ite); @@ -97,9 +101,13 @@ private: expr_ref simplify_and_or(bool is_and, app * ite); void simplify_goal(goal& g); - expr_ref get_cached(expr* t) { expr* r = 0; if (!m_result.find(r, r)) r = t; return expr_ref(r, m); } + bool is_subexpr(expr * a, expr * b); + + expr_ref get_cached(expr* t) { expr* r = 0; if (!m_result.find(t, r)) r = t; return expr_ref(r, m); } void cache(expr *t, expr* r) { m_result.insert(t, r); m_trail.push_back(r); } + ptr_vector const & tree(expr * e); + unsigned scope_level() { return m_scope_level; } void pop(unsigned n) { SASSERT(n <= m_scope_level); m_scope_level -= n; m_simplifier->pop(n); } bool assert_expr(expr* f, bool sign) { m_scope_level++; return m_simplifier->assert_expr(f, sign); } @@ -156,8 +164,13 @@ public: SASSERT(m_subst.empty()); return alloc(expr_substitution_simplifier, m); } - - }; + +tactic * mk_dom_simplify_tactic(ast_manager & m, params_ref const & p = params_ref()); + +/* +ADD_TACTIC("dom-simplify", "apply dominator simplification rules.", "mk_dom_simplify_tactic(m, p)") +*/ + #endif From f59cf2452d9a335785bd1691dbf04b93973193d1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 5 Oct 2017 22:20:31 +0100 Subject: [PATCH 339/488] #1284 build problems Signed-off-by: Nikolaj Bjorner --- src/tactic/core/CMakeLists.txt | 2 + src/tactic/core/dom_simplify_tactic.cpp | 1 + src/tactic/core/dom_simplify_tactic.h | 53 +++++++++++++------------ 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/tactic/core/CMakeLists.txt b/src/tactic/core/CMakeLists.txt index f192b4fa6..16778d8dd 100644 --- a/src/tactic/core/CMakeLists.txt +++ b/src/tactic/core/CMakeLists.txt @@ -7,6 +7,7 @@ z3_add_component(core_tactics ctx_simplify_tactic.cpp der_tactic.cpp distribute_forall_tactic.cpp + dom_simplify_tactic.cpp elim_term_ite_tactic.cpp elim_uncnstr_tactic.cpp injectivity_tactic.cpp @@ -32,6 +33,7 @@ z3_add_component(core_tactics ctx_simplify_tactic.h der_tactic.h distribute_forall_tactic.h + dom_simplify_tactic.h elim_term_ite_tactic.h elim_uncnstr_tactic.h injectivity_tactic.h diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 85b7fd9d6..bba27cf46 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -188,6 +188,7 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { simplify(child); } } + pop(scope_level() - old_lvl); expr_ref new_t = simplify(t); if (!assert_expr(new_c, true)) { diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 9fe59de23..825a173bf 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -58,32 +58,35 @@ public: }; +class dom_simplifier { + public: + dom_simplifier() {} + + virtual ~dom_simplifier() {} + /** + \brief assert_expr performs an implicit push + */ + virtual bool assert_expr(expr * t, bool sign) = 0; + + /** + \brief apply simplification. + */ + virtual void operator()(expr_ref& r) = 0; + + /** + \brief pop scopes accumulated from assertions. + */ + virtual void pop(unsigned num_scopes) = 0; + + virtual dom_simplifier * translate(ast_manager & m) = 0; + +}; + class dom_simplify_tactic : public tactic { public: - class simplifier { - public: - virtual ~simplifier() {} - /** - \brief assert_expr performs an implicit push - */ - virtual bool assert_expr(expr * t, bool sign) = 0; - - /** - \brief apply simplification. - */ - virtual void operator()(expr_ref& r) = 0; - - /** - \brief pop scopes accumulated from assertions. - */ - virtual void pop(unsigned num_scopes) = 0; - - virtual simplifier * translate(ast_manager & m); - - }; private: ast_manager& m; - simplifier* m_simplifier; + dom_simplifier* m_simplifier; params_ref m_params; expr_ref_vector m_trail, m_args, m_args2; obj_map m_result; @@ -115,7 +118,7 @@ private: void init(goal& g); public: - dom_simplify_tactic(ast_manager & m, simplifier* s, params_ref const & p = params_ref()): + dom_simplify_tactic(ast_manager & m, dom_simplifier* s, params_ref const & p = params_ref()): m(m), m_simplifier(s), m_params(p), m_trail(m), m_args(m), m_args2(m), m_dominators(m), @@ -138,7 +141,7 @@ public: virtual void cleanup(); }; -class expr_substitution_simplifier : public dom_simplify_tactic::simplifier { +class expr_substitution_simplifier : public dom_simplifier { ast_manager& m; expr_substitution m_subst; scoped_expr_substitution m_scoped_substitution; @@ -160,7 +163,7 @@ public: virtual void pop(unsigned num_scopes) { m_scoped_substitution.pop(num_scopes); } - virtual simplifier * translate(ast_manager & m) { + virtual dom_simplifier * translate(ast_manager & m) { SASSERT(m_subst.empty()); return alloc(expr_substitution_simplifier, m); } From eac659f748fc3209fca947556d94d9b08a3c8c82 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 6 Oct 2017 11:34:14 +0100 Subject: [PATCH 340/488] deal with empty set of post-orders Signed-off-by: Nikolaj Bjorner --- src/muz/rel/karr_relation.cpp | 4 ++-- .../transforms/dl_mk_interp_tail_simplifier.cpp | 4 ++-- src/smt/theory_lra.cpp | 4 ++-- src/tactic/core/dom_simplify_tactic.cpp | 14 ++++++++------ src/tactic/core/dom_simplify_tactic.h | 4 ++-- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/muz/rel/karr_relation.cpp b/src/muz/rel/karr_relation.cpp index 572d5e8d5..c8a489d69 100644 --- a/src/muz/rel/karr_relation.cpp +++ b/src/muz/rel/karr_relation.cpp @@ -111,8 +111,8 @@ namespace datalog { void filter_interpreted(app* cond) { rational one(1), mone(-1); - expr* e1, *e2, *en; - var* v, *w; + expr* e1 = 0, *e2 = 0, *en = 0; + var* v = 0, *w = 0; rational n1, n2; expr_ref_vector conjs(m); flatten_and(cond, conjs); diff --git a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp index 30505a5e8..7bd35b4ef 100644 --- a/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp +++ b/src/muz/transforms/dl_mk_interp_tail_simplifier.cpp @@ -398,8 +398,8 @@ namespace datalog { } bool mk_interp_tail_simplifier::propagate_variable_equivalences(rule * r, rule_ref& res) { - if (!m_context.get_params ().xform_tail_simplifier_pve ()) - return false; + if (!m_context.get_params ().xform_tail_simplifier_pve ()) + return false; unsigned u_len = r->get_uninterpreted_tail_size(); unsigned len = r->get_tail_size(); if (u_len == len) { diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index 0bb76cd90..7fec6f836 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -721,7 +721,7 @@ namespace smt { SASSERT(!ctx().b_internalized(atom)); bool_var bv = ctx().mk_bool_var(atom); ctx().set_var_theory(bv, get_id()); - expr* n1, *n2; + expr* n1 = 0, *n2 = 0; rational r; lra_lp::bound_kind k; theory_var v = null_theory_var; @@ -862,7 +862,7 @@ namespace smt { void relevant_eh(app* n) { TRACE("arith", tout << mk_pp(n, m) << "\n";); - expr* n1, *n2; + expr* n1 = 0, *n2 = 0; if (a.is_mod(n, n1, n2)) mk_idiv_mod_axioms(n1, n2); else if (a.is_rem(n, n1, n2)) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index bba27cf46..17262a9d6 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -90,8 +90,8 @@ void expr_dominators::compute_dominators() { bool change = true; while (change) { change = false; - SASSERT(m_post2expr.back() == e); - for (unsigned i = 0; i < m_post2expr.size() - 1; ++i) { + SASSERT(m_post2expr.empty() || m_post2expr.back() == e); + for (unsigned i = 0; i + 1 < m_post2expr.size(); ++i) { expr * child = m_post2expr[i]; ptr_vector const& p = m_parents[child]; SASSERT(!p.empty()); @@ -167,7 +167,6 @@ void dom_simplify_tactic::operator()( void dom_simplify_tactic::cleanup() { m_trail.reset(); m_args.reset(); - m_args2.reset(); m_result.reset(); m_dominators.reset(); } @@ -180,9 +179,11 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { expr_ref new_c = simplify(c); if (m.is_true(new_c)) { r = simplify(t); - } else if (m.is_false(new_c) || !assert_expr(new_c, false)) { + } + else if (m.is_false(new_c) || !assert_expr(new_c, false)) { r = simplify(e); - } else { + } + else { for (expr * child : tree(ite)) { if (is_subexpr(child, t) && !is_subexpr(child, e)) { simplify(child); @@ -254,6 +255,7 @@ expr_ref dom_simplify_tactic::simplify(expr * e0) { cache(e0, r); TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e0, m) << " -> " << r << "\n";); --m_depth; + m_subexpr_cache.reset(); return r; } @@ -361,7 +363,7 @@ bool dom_simplify_tactic::is_subexpr(expr * a, expr * b) { return true; } } - m_subexpr_cache.insert(a, b, false); + m_subexpr_cache.insert(a, b, false); return false; } diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 825a173bf..c62651c5c 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -88,7 +88,7 @@ private: ast_manager& m; dom_simplifier* m_simplifier; params_ref m_params; - expr_ref_vector m_trail, m_args, m_args2; + expr_ref_vector m_trail, m_args; obj_map m_result; expr_dominators m_dominators; unsigned m_scope_level; @@ -120,7 +120,7 @@ private: public: dom_simplify_tactic(ast_manager & m, dom_simplifier* s, params_ref const & p = params_ref()): m(m), m_simplifier(s), m_params(p), - m_trail(m), m_args(m), m_args2(m), + m_trail(m), m_args(m), m_dominators(m), m_scope_level(0), m_depth(0), m_max_depth(1024) {} From 6df628edc7043a08dd11eae3d2ab8d44e07a172c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 6 Oct 2017 11:45:29 +0100 Subject: [PATCH 341/488] pin elements in expr2depth Signed-off-by: Nikolaj Bjorner --- src/smt/smt_implied_equalities.cpp | 2 +- src/smt/theory_lra.cpp | 2 +- src/tactic/bv/bv_bounds_tactic.cpp | 6 ++++-- src/tactic/core/dom_simplify_tactic.cpp | 2 ++ src/tactic/core/dom_simplify_tactic.h | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/smt/smt_implied_equalities.cpp b/src/smt/smt_implied_equalities.cpp index 7d54e714e..d021708fc 100644 --- a/src/smt/smt_implied_equalities.cpp +++ b/src/smt/smt_implied_equalities.cpp @@ -284,7 +284,7 @@ namespace smt { } lbool reduce_cond(model_ref& model, expr* e) { - expr* e1, *e2; + expr* e1 = 0, *e2 = 0; if (m.is_eq(e, e1, e2) && m_array_util.is_as_array(e1) && m_array_util.is_as_array(e2)) { if (e1 == e2) { return l_true; diff --git a/src/smt/theory_lra.cpp b/src/smt/theory_lra.cpp index 7fec6f836..292d2ab0d 100644 --- a/src/smt/theory_lra.cpp +++ b/src/smt/theory_lra.cpp @@ -689,7 +689,7 @@ namespace smt { SASSERT(!ctx().b_internalized(atom)); bool_var bv = ctx().mk_bool_var(atom); ctx().set_var_theory(bv, get_id()); - expr* n1, *n2; + expr* n1 = 0, *n2 = 0; rational r; lra_lp::bound_kind k; theory_var v = null_theory_var; diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp index d2cd0d66c..1f0bb8473 100644 --- a/src/tactic/bv/bv_bounds_tactic.cpp +++ b/src/tactic/bv/bv_bounds_tactic.cpp @@ -70,11 +70,13 @@ struct interval { if (is_wrapped()) { // l >= b.l >= b.h >= h return b.is_wrapped() && h <= b.h && l >= b.l; - } else if (b.is_wrapped()) { + } + else if (b.is_wrapped()) { // b.l > b.h >= h >= l // h >= l >= b.l > b.h return h <= b.h || l >= b.l; - } else { + } + else { // return l >= b.l && h <= b.h; } diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 17262a9d6..08037fe18 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -430,6 +430,8 @@ void expr_substitution_simplifier::update_substitution(expr* n, proof* pr) { if (is_ground(n) && (m.is_eq(n, lhs, rhs) || m.is_iff(n, lhs, rhs))) { compute_depth(lhs); compute_depth(rhs); + m_trail.push_back(lhs); + m_trail.push_back(rhs); if (is_gt(lhs, rhs)) { TRACE("propagate_values", tout << "insert " << mk_pp(lhs, m) << " -> " << mk_pp(rhs, m) << "\n";); m_scoped_substitution.insert(lhs, rhs, pr); diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index c62651c5c..25fb7c24f 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -146,6 +146,7 @@ class expr_substitution_simplifier : public dom_simplifier { expr_substitution m_subst; scoped_expr_substitution m_scoped_substitution; obj_map m_expr2depth; + expr_ref_vector m_trail; // move from asserted_formulas to here.. void compute_depth(expr* e); @@ -153,7 +154,7 @@ class expr_substitution_simplifier : public dom_simplifier { unsigned depth(expr* e) { return m_expr2depth[e]; } public: - expr_substitution_simplifier(ast_manager& m): m(m), m_subst(m), m_scoped_substitution(m_subst) {} + expr_substitution_simplifier(ast_manager& m): m(m), m_subst(m), m_scoped_substitution(m_subst), m_trail(m) {} virtual ~expr_substitution_simplifier() {} virtual bool assert_expr(expr * t, bool sign); From cb548404bc1ad5a55628e1dd23fc4efe69de8856 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 6 Oct 2017 12:08:37 +0100 Subject: [PATCH 342/488] bail out dominators after log number of steps Signed-off-by: Nikolaj Bjorner --- src/tactic/bv/bv_bounds_tactic.cpp | 1227 ++++++++++++++--------- src/tactic/core/dom_simplify_tactic.cpp | 25 +- src/tactic/core/dom_simplify_tactic.h | 8 +- 3 files changed, 792 insertions(+), 468 deletions(-) diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp index 1f0bb8473..2d5eb216a 100644 --- a/src/tactic/bv/bv_bounds_tactic.cpp +++ b/src/tactic/bv/bv_bounds_tactic.cpp @@ -18,6 +18,7 @@ Author: #include "tactic/bv/bv_bounds_tactic.h" #include "tactic/core/ctx_simplify_tactic.h" +#include "tactic/core/dom_simplify_tactic.h" #include "ast/bv_decl_plugin.h" #include "ast/ast_pp.h" #include @@ -29,509 +30,825 @@ static uint64 uMaxInt(unsigned sz) { namespace { -struct interval { - // l < h: [l, h] - // l > h: [0, h] U [l, UMAX_INT] - uint64 l, h; - unsigned sz; - bool tight; + struct interval { + // l < h: [l, h] + // l > h: [0, h] U [l, UMAX_INT] + uint64 l, h; + unsigned sz; + bool tight; - interval() {} - interval(uint64 l, uint64 h, unsigned sz, bool tight = false) : l(l), h(h), sz(sz), tight(tight) { - // canonicalize full set - if (is_wrapped() && l == h + 1) { - this->l = 0; - this->h = uMaxInt(sz); - } - SASSERT(invariant()); - } - - bool invariant() const { - return l <= uMaxInt(sz) && h <= uMaxInt(sz) && - (!is_wrapped() || l != h+1); - } - - bool is_full() const { return l == 0 && h == uMaxInt(sz); } - bool is_wrapped() const { return l > h; } - bool is_singleton() const { return l == h; } - - bool operator==(const interval& b) const { - SASSERT(sz == b.sz); - return l == b.l && h == b.h && tight == b.tight; - } - bool operator!=(const interval& b) const { return !(*this == b); } - - bool implies(const interval& b) const { - if (b.is_full()) - return true; - if (is_full()) - return false; - - if (is_wrapped()) { - // l >= b.l >= b.h >= h - return b.is_wrapped() && h <= b.h && l >= b.l; - } - else if (b.is_wrapped()) { - // b.l > b.h >= h >= l - // h >= l >= b.l > b.h - return h <= b.h || l >= b.l; - } - else { - // - return l >= b.l && h <= b.h; - } - } - - /// return false if intersection is unsat - bool intersect(const interval& b, interval& result) const { - if (is_full() || *this == b) { - result = b; - return true; - } - if (b.is_full()) { - result = *this; - return true; + interval() {} + interval(uint64 l, uint64 h, unsigned sz, bool tight = false) : l(l), h(h), sz(sz), tight(tight) { + // canonicalize full set + if (is_wrapped() && l == h + 1) { + this->l = 0; + this->h = uMaxInt(sz); + } + SASSERT(invariant()); } - if (is_wrapped()) { - if (b.is_wrapped()) { - if (h >= b.l) { - result = b; - } else if (b.h >= l) { - result = *this; + bool invariant() const { + return l <= uMaxInt(sz) && h <= uMaxInt(sz) && + (!is_wrapped() || l != h+1); + } + + bool is_full() const { return l == 0 && h == uMaxInt(sz); } + bool is_wrapped() const { return l > h; } + bool is_singleton() const { return l == h; } + + bool operator==(const interval& b) const { + SASSERT(sz == b.sz); + return l == b.l && h == b.h && tight == b.tight; + } + bool operator!=(const interval& b) const { return !(*this == b); } + + bool implies(const interval& b) const { + if (b.is_full()) + return true; + if (is_full()) + return false; + + if (is_wrapped()) { + // l >= b.l >= b.h >= h + return b.is_wrapped() && h <= b.h && l >= b.l; + } + else if (b.is_wrapped()) { + // b.l > b.h >= h >= l + // h >= l >= b.l > b.h + return h <= b.h || l >= b.l; + } + else { + // + return l >= b.l && h <= b.h; + } + } + + /// return false if intersection is unsat + bool intersect(const interval& b, interval& result) const { + if (is_full() || *this == b) { + result = b; + return true; + } + if (b.is_full()) { + result = *this; + return true; + } + + if (is_wrapped()) { + if (b.is_wrapped()) { + if (h >= b.l) { + result = b; + } else if (b.h >= l) { + result = *this; + } else { + result = interval(std::max(l, b.l), std::min(h, b.h), sz); + } } else { - result = interval(std::max(l, b.l), std::min(h, b.h), sz); + return b.intersect(*this, result); + } + } + else if (b.is_wrapped()) { + // ... b.h ... l ... h ... b.l .. + if (h < b.l && l > b.h) { + return false; + } + // ... l ... b.l ... h ... + if (h >= b.l && l <= b.h) { + result = b; + } else if (h >= b.l) { + result = interval(b.l, h, sz); + } else { + // ... l .. b.h .. h .. b.l ... + SASSERT(l <= b.h); + result = interval(l, std::min(h, b.h), sz); } } else { - return b.intersect(*this, result); - } - } else if (b.is_wrapped()) { - // ... b.h ... l ... h ... b.l .. - if (h < b.l && l > b.h) { - return false; - } - // ... l ... b.l ... h ... - if (h >= b.l && l <= b.h) { - result = b; - } else if (h >= b.l) { - result = interval(b.l, h, sz); - } else { - // ... l .. b.h .. h .. b.l ... - SASSERT(l <= b.h); - result = interval(l, std::min(h, b.h), sz); - } - } else { - if (l > b.h || h < b.l) - return false; + if (l > b.h || h < b.l) + return false; - // 0 .. l.. l' ... h ... h' - result = interval(std::max(l, b.l), std::min(h, b.h), sz, tight && b.tight); - } - return true; - } - - /// return false if negation is empty - bool negate(interval& result) const { - if (!tight) { - result = interval(0, uMaxInt(sz), true); + // 0 .. l.. l' ... h ... h' + result = interval(std::max(l, b.l), std::min(h, b.h), sz, tight && b.tight); + } return true; } - if (is_full()) - return false; - if (l == 0) { - result = interval(h + 1, uMaxInt(sz), sz); - } else if (uMaxInt(sz) == h) { - result = interval(0, l - 1, sz); - } else { - result = interval(h + 1, l - 1, sz); + /// return false if negation is empty + bool negate(interval& result) const { + if (!tight) { + result = interval(0, uMaxInt(sz), true); + return true; + } + + if (is_full()) + return false; + if (l == 0) { + result = interval(h + 1, uMaxInt(sz), sz); + } else if (uMaxInt(sz) == h) { + result = interval(0, l - 1, sz); + } else { + result = interval(h + 1, l - 1, sz); + } + return true; } - return true; - } -}; + }; #ifdef _TRACE -std::ostream& operator<<(std::ostream& o, const interval& I) { - o << "[" << I.l << ", " << I.h << "]"; - return o; -} -#endif - - -struct undo_bound { - expr* e; - interval b; - bool fresh; - undo_bound(expr* e, const interval& b, bool fresh) : e(e), b(b), fresh(fresh) {} -}; - -class bv_bounds_simplifier : public ctx_simplify_tactic::simplifier { - typedef obj_map map; - typedef obj_map expr_set; - typedef obj_map expr_cnt; - - ast_manager& m; - params_ref m_params; - bool m_propagate_eq; - bv_util m_bv; - vector m_scopes; - map m_bound; - svector m_expr_vars; - svector m_bound_exprs; - - bool is_number(expr *e, uint64& n, unsigned& sz) const { - rational r; - if (m_bv.is_numeral(e, r, sz) && sz <= 64) { - n = r.get_uint64(); - return true; - } - return false; - } - - bool is_bound(expr *e, expr*& v, interval& b) const { - uint64 n; - expr *lhs, *rhs; - unsigned sz; - - if (m_bv.is_bv_ule(e, lhs, rhs)) { - if (is_number(lhs, n, sz)) { // C ule x <=> x uge C - if (m_bv.is_numeral(rhs)) - return false; - b = interval(n, uMaxInt(sz), sz, true); - v = rhs; - return true; - } - if (is_number(rhs, n, sz)) { // x ule C - b = interval(0, n, sz, true); - v = lhs; - return true; - } - } else if (m_bv.is_bv_sle(e, lhs, rhs)) { - if (is_number(lhs, n, sz)) { // C sle x <=> x sge C - if (m_bv.is_numeral(rhs)) - return false; - b = interval(n, (1ull << (sz-1)) - 1, sz, true); - v = rhs; - return true; - } - if (is_number(rhs, n, sz)) { // x sle C - b = interval(1ull << (sz-1), n, sz, true); - v = lhs; - return true; - } - } else if (m.is_eq(e, lhs, rhs)) { - if (is_number(lhs, n, sz)) { - if (m_bv.is_numeral(rhs)) - return false; - b = interval(n, n, sz, true); - v = rhs; - return true; - } - if (is_number(rhs, n, sz)) { - b = interval(n, n, sz, true); - v = lhs; - return true; - } - } - return false; - } - -#if 0 - expr_set* get_expr_vars(expr* t) { - unsigned id = t->get_id(); - m_expr_vars.reserve(id + 1); - expr_set*& entry = m_expr_vars[id]; - if (entry) - return entry; - - expr_set* set = alloc(expr_set); - entry = set; - - if (!m_bv.is_numeral(t)) - set->insert(t, true); - - if (!is_app(t)) - return set; - - app* a = to_app(t); - for (unsigned i = 0; i < a->get_num_args(); ++i) { - expr_set* set_arg = get_expr_vars(a->get_arg(i)); - for (expr_set::iterator I = set_arg->begin(), E = set_arg->end(); I != E; ++I) { - set->insert(I->m_key, true); - } - } - return set; + std::ostream& operator<<(std::ostream& o, const interval& I) { + o << "[" << I.l << ", " << I.h << "]"; + return o; } #endif -#if 0 - expr_cnt* get_expr_bounds(expr* t) { - unsigned id = t->get_id(); - m_bound_exprs.reserve(id + 1); - expr_cnt*& entry = m_bound_exprs[id]; - if (entry) - return entry; - expr_cnt* set = alloc(expr_cnt); - entry = set; - - if (!is_app(t)) - return set; - - interval b; + struct undo_bound { expr* e; - if (is_bound(t, e, b)) { - set->insert_if_not_there2(e, 0)->get_data().m_value++; + interval b; + bool fresh; + undo_bound(expr* e, const interval& b, bool fresh) : e(e), b(b), fresh(fresh) {} + }; + + class bv_bounds_simplifier : public ctx_simplify_tactic::simplifier { + typedef obj_map map; + typedef obj_map expr_set; + typedef obj_map expr_cnt; + + ast_manager& m; + params_ref m_params; + bool m_propagate_eq; + bv_util m_bv; + vector m_scopes; + map m_bound; + svector m_expr_vars; + svector m_bound_exprs; + + bool is_number(expr *e, uint64& n, unsigned& sz) const { + rational r; + if (m_bv.is_numeral(e, r, sz) && sz <= 64) { + n = r.get_uint64(); + return true; + } + return false; } - app* a = to_app(t); - for (unsigned i = 0; i < a->get_num_args(); ++i) { - expr_cnt* set_arg = get_expr_bounds(a->get_arg(i)); - for (expr_cnt::iterator I = set_arg->begin(), E = set_arg->end(); I != E; ++I) { - set->insert_if_not_there2(I->m_key, 0)->get_data().m_value += I->m_value; + bool is_bound(expr *e, expr*& v, interval& b) const { + uint64 n; + expr *lhs = 0, *rhs = 0; + unsigned sz; + + if (m_bv.is_bv_ule(e, lhs, rhs)) { + if (is_number(lhs, n, sz)) { // C ule x <=> x uge C + if (m_bv.is_numeral(rhs)) + return false; + b = interval(n, uMaxInt(sz), sz, true); + v = rhs; + return true; + } + if (is_number(rhs, n, sz)) { // x ule C + b = interval(0, n, sz, true); + v = lhs; + return true; + } + } + else if (m_bv.is_bv_sle(e, lhs, rhs)) { + if (is_number(lhs, n, sz)) { // C sle x <=> x sge C + if (m_bv.is_numeral(rhs)) + return false; + b = interval(n, (1ull << (sz-1)) - 1, sz, true); + v = rhs; + return true; + } + if (is_number(rhs, n, sz)) { // x sle C + b = interval(1ull << (sz-1), n, sz, true); + v = lhs; + return true; + } + } else if (m.is_eq(e, lhs, rhs)) { + if (is_number(lhs, n, sz)) { + if (m_bv.is_numeral(rhs)) + return false; + b = interval(n, n, sz, true); + v = rhs; + return true; + } + if (is_number(rhs, n, sz)) { + b = interval(n, n, sz, true); + v = lhs; + return true; + } } + return false; + } + +#if 0 + expr_set* get_expr_vars(expr* t) { + unsigned id = t->get_id(); + m_expr_vars.reserve(id + 1); + expr_set*& entry = m_expr_vars[id]; + if (entry) + return entry; + + expr_set* set = alloc(expr_set); + entry = set; + + if (!m_bv.is_numeral(t)) + set->insert(t, true); + + if (!is_app(t)) + return set; + + app* a = to_app(t); + for (unsigned i = 0; i < a->get_num_args(); ++i) { + expr_set* set_arg = get_expr_vars(a->get_arg(i)); + for (expr_set::iterator I = set_arg->begin(), E = set_arg->end(); I != E; ++I) { + set->insert(I->m_key, true); + } + } + return set; } - return set; - } #endif -public: - bv_bounds_simplifier(ast_manager& m, params_ref const& p) : m(m), m_params(p), m_bv(m) { - updt_params(p); - } +#if 0 + expr_cnt* get_expr_bounds(expr* t) { + unsigned id = t->get_id(); + m_bound_exprs.reserve(id + 1); + expr_cnt*& entry = m_bound_exprs[id]; + if (entry) + return entry; - virtual void updt_params(params_ref const & p) { - m_propagate_eq = p.get_bool("propagate_eq", false); - } + expr_cnt* set = alloc(expr_cnt); + entry = set; - static void get_param_descrs(param_descrs& r) { - r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities"); - } + if (!is_app(t)) + return set; - virtual ~bv_bounds_simplifier() { - for (unsigned i = 0, e = m_expr_vars.size(); i < e; ++i) { - dealloc(m_expr_vars[i]); - } - for (unsigned i = 0, e = m_bound_exprs.size(); i < e; ++i) { - dealloc(m_bound_exprs[i]); - } - } - - virtual bool assert_expr(expr * t, bool sign) { - while (m.is_not(t, t)) { - sign = !sign; - } - - interval b; - expr* t1; - if (is_bound(t, t1, b)) { - SASSERT(!m_bv.is_numeral(t1)); - if (sign) - VERIFY(b.negate(b)); - - TRACE("bv", tout << (sign?"(not ":"") << mk_pp(t, m) << (sign ? ")" : "") << ": " << mk_pp(t1, m) << " in " << b << "\n";); - map::obj_map_entry* e = m_bound.find_core(t1); - if (e) { - interval& old = e->get_data().m_value; - interval intr; - if (!old.intersect(b, intr)) - return false; - if (old == intr) - return true; - m_scopes.insert(undo_bound(t1, old, false)); - old = intr; - } else { - m_bound.insert(t1, b); - m_scopes.insert(undo_bound(t1, interval(), true)); - } - } - return true; - } - - virtual bool simplify(expr* t, expr_ref& result) { - expr* t1; - interval b; - - if (m_bound.find(t, b) && b.is_singleton()) { - result = m_bv.mk_numeral(b.l, m_bv.get_bv_size(t)); - return true; - } - - if (!m.is_bool(t)) - return false; - - bool sign = false; - while (m.is_not(t, t)) { - sign = !sign; - } - - if (!is_bound(t, t1, b)) - return false; - - if (sign && b.tight) { - sign = false; - if (!b.negate(b)) { - result = m.mk_false(); - return true; - } - } - - interval ctx, intr; - result = 0; - - if (b.is_full() && b.tight) { - result = m.mk_true(); - } else if (m_bound.find(t1, ctx)) { - if (ctx.implies(b)) { - result = m.mk_true(); - } else if (!b.intersect(ctx, intr)) { - result = m.mk_false(); - } else if (m_propagate_eq && intr.is_singleton()) { - result = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()), - m.get_sort(t1))); - } - } - - CTRACE("bv", result != 0, tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << result << "\n";); - if (sign && result != 0) - result = m.mk_not(result); - return result != 0; - } - - // check if t contains v - ptr_vector todo; - bool contains(expr* t, expr* v) { - ast_fast_mark1 mark; - todo.push_back(t); - while (!todo.empty()) { - t = todo.back(); - todo.pop_back(); - if (mark.is_marked(t)) { - continue; - } - if (t == v) { - todo.reset(); - return true; - } - mark.mark(t); - - if (!is_app(t)) { - continue; - } - app* a = to_app(t); - todo.append(a->get_num_args(), a->get_args()); - } - return false; - } - - bool contains_bound(expr* t) { - ast_fast_mark1 mark1; - ast_fast_mark2 mark2; - - todo.push_back(t); - while (!todo.empty()) { - t = todo.back(); - todo.pop_back(); - if (mark1.is_marked(t)) { - continue; - } - mark1.mark(t); - - if (!is_app(t)) { - continue; - } interval b; expr* e; if (is_bound(t, e, b)) { - if (mark2.is_marked(e)) { - todo.reset(); - return true; - } - mark2.mark(e); - if (m_bound.contains(e)) { - todo.reset(); - return true; - } + set->insert_if_not_there2(e, 0)->get_data().m_value++; } app* a = to_app(t); - todo.append(a->get_num_args(), a->get_args()); - } - return false; - } - - virtual bool may_simplify(expr* t) { - if (m_bv.is_numeral(t)) - return false; - - while (m.is_not(t, t)); - - for (auto & v : m_bound) { - if (contains(t, v.m_key)) return true; - } - -#if 0 - expr_set* used_exprs = get_expr_vars(t); - for (map::iterator I = m_bound.begin(), E = m_bound.end(); I != E; ++I) { - if (contains(t, I->m_key)) return true; - if (I->m_value.is_singleton() && used_exprs->contains(I->m_key)) - return true; + for (unsigned i = 0; i < a->get_num_args(); ++i) { + expr_cnt* set_arg = get_expr_bounds(a->get_arg(i)); + for (expr_cnt::iterator I = set_arg->begin(), E = set_arg->end(); I != E; ++I) { + set->insert_if_not_there2(I->m_key, 0)->get_data().m_value += I->m_value; + } + } + return set; } #endif - expr* t1; - interval b; - // skip common case: single bound constraint without any context for simplification - if (is_bound(t, t1, b)) { - return b.is_full() || m_bound.contains(t1); + public: + bv_bounds_simplifier(ast_manager& m, params_ref const& p) : m(m), m_params(p), m_bv(m) { + updt_params(p); } - if (contains_bound(t)) { - return true; + virtual void updt_params(params_ref const & p) { + m_propagate_eq = p.get_bool("propagate_eq", false); } -#if 0 - expr_cnt* bounds = get_expr_bounds(t); - for (expr_cnt::iterator I = bounds->begin(), E = bounds->end(); I != E; ++I) { - if (I->m_value > 1 || m_bound.contains(I->m_key)) - return true; - } -#endif - return false; - } - virtual void pop(unsigned num_scopes) { - TRACE("bv", tout << "pop: " << num_scopes << "\n";); - if (m_scopes.empty()) - return; - unsigned target = m_scopes.size() - num_scopes; - if (target == 0) { - m_bound.reset(); - m_scopes.reset(); - return; + static void get_param_descrs(param_descrs& r) { + r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities"); } - for (unsigned i = m_scopes.size()-1; i >= target; --i) { - undo_bound& undo = m_scopes[i]; - SASSERT(m_bound.contains(undo.e)); - if (undo.fresh) { - m_bound.erase(undo.e); - } else { - m_bound.insert(undo.e, undo.b); + + virtual ~bv_bounds_simplifier() { + for (unsigned i = 0, e = m_expr_vars.size(); i < e; ++i) { + dealloc(m_expr_vars[i]); + } + for (unsigned i = 0, e = m_bound_exprs.size(); i < e; ++i) { + dealloc(m_bound_exprs[i]); } } - m_scopes.shrink(target); - } - virtual simplifier * translate(ast_manager & m) { - return alloc(bv_bounds_simplifier, m, m_params); - } + virtual bool assert_expr(expr * t, bool sign) { + while (m.is_not(t, t)) { + sign = !sign; + } - virtual unsigned scope_level() const { - return m_scopes.size(); - } -}; + interval b; + expr* t1; + if (is_bound(t, t1, b)) { + SASSERT(!m_bv.is_numeral(t1)); + if (sign) + VERIFY(b.negate(b)); + + TRACE("bv", tout << (sign?"(not ":"") << mk_pp(t, m) << (sign ? ")" : "") << ": " << mk_pp(t1, m) << " in " << b << "\n";); + map::obj_map_entry* e = m_bound.find_core(t1); + if (e) { + interval& old = e->get_data().m_value; + interval intr; + if (!old.intersect(b, intr)) + return false; + if (old == intr) + return true; + m_scopes.insert(undo_bound(t1, old, false)); + old = intr; + } else { + m_bound.insert(t1, b); + m_scopes.insert(undo_bound(t1, interval(), true)); + } + } + return true; + } + + virtual bool simplify(expr* t, expr_ref& result) { + expr* t1; + interval b; + + if (m_bound.find(t, b) && b.is_singleton()) { + result = m_bv.mk_numeral(b.l, m_bv.get_bv_size(t)); + return true; + } + + if (!m.is_bool(t)) + return false; + + bool sign = false; + while (m.is_not(t, t)) { + sign = !sign; + } + + if (!is_bound(t, t1, b)) + return false; + + if (sign && b.tight) { + sign = false; + if (!b.negate(b)) { + result = m.mk_false(); + return true; + } + } + + interval ctx, intr; + result = 0; + + if (b.is_full() && b.tight) { + result = m.mk_true(); + } else if (m_bound.find(t1, ctx)) { + if (ctx.implies(b)) { + result = m.mk_true(); + } else if (!b.intersect(ctx, intr)) { + result = m.mk_false(); + } else if (m_propagate_eq && intr.is_singleton()) { + result = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()), + m.get_sort(t1))); + } + } + + CTRACE("bv", result != 0, tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << result << "\n";); + if (sign && result != 0) + result = m.mk_not(result); + return result != 0; + } + + // check if t contains v + ptr_vector todo; + bool contains(expr* t, expr* v) { + ast_fast_mark1 mark; + todo.push_back(t); + while (!todo.empty()) { + t = todo.back(); + todo.pop_back(); + if (mark.is_marked(t)) { + continue; + } + if (t == v) { + todo.reset(); + return true; + } + mark.mark(t); + + if (!is_app(t)) { + continue; + } + app* a = to_app(t); + todo.append(a->get_num_args(), a->get_args()); + } + return false; + } + + bool contains_bound(expr* t) { + ast_fast_mark1 mark1; + ast_fast_mark2 mark2; + + todo.push_back(t); + while (!todo.empty()) { + t = todo.back(); + todo.pop_back(); + if (mark1.is_marked(t)) { + continue; + } + mark1.mark(t); + + if (!is_app(t)) { + continue; + } + interval b; + expr* e; + if (is_bound(t, e, b)) { + if (mark2.is_marked(e)) { + todo.reset(); + return true; + } + mark2.mark(e); + if (m_bound.contains(e)) { + todo.reset(); + return true; + } + } + + app* a = to_app(t); + todo.append(a->get_num_args(), a->get_args()); + } + return false; + } + + virtual bool may_simplify(expr* t) { + if (m_bv.is_numeral(t)) + return false; + + while (m.is_not(t, t)); + + for (auto & v : m_bound) { + if (contains(t, v.m_key)) return true; + } + +#if 0 + expr_set* used_exprs = get_expr_vars(t); + for (map::iterator I = m_bound.begin(), E = m_bound.end(); I != E; ++I) { + if (contains(t, I->m_key)) return true; + if (I->m_value.is_singleton() && used_exprs->contains(I->m_key)) + return true; + } +#endif + + expr* t1; + interval b; + // skip common case: single bound constraint without any context for simplification + if (is_bound(t, t1, b)) { + return b.is_full() || m_bound.contains(t1); + } + + if (contains_bound(t)) { + return true; + } +#if 0 + expr_cnt* bounds = get_expr_bounds(t); + for (expr_cnt::iterator I = bounds->begin(), E = bounds->end(); I != E; ++I) { + if (I->m_value > 1 || m_bound.contains(I->m_key)) + return true; + } +#endif + return false; + } + + virtual void pop(unsigned num_scopes) { + TRACE("bv", tout << "pop: " << num_scopes << "\n";); + if (m_scopes.empty()) + return; + unsigned target = m_scopes.size() - num_scopes; + if (target == 0) { + m_bound.reset(); + m_scopes.reset(); + return; + } + for (unsigned i = m_scopes.size()-1; i >= target; --i) { + undo_bound& undo = m_scopes[i]; + SASSERT(m_bound.contains(undo.e)); + if (undo.fresh) { + m_bound.erase(undo.e); + } else { + m_bound.insert(undo.e, undo.b); + } + } + m_scopes.shrink(target); + } + + virtual simplifier * translate(ast_manager & m) { + return alloc(bv_bounds_simplifier, m, m_params); + } + + virtual unsigned scope_level() const { + return m_scopes.size(); + } + }; + + + class dom_bv_bounds_simplifier : public dom_simplifier { + typedef obj_map map; + typedef obj_map expr_set; + typedef obj_map expr_cnt; + + ast_manager& m; + params_ref m_params; + bool m_propagate_eq; + bv_util m_bv; + vector m_scopes; + map m_bound; + svector m_expr_vars; + svector m_bound_exprs; + + bool is_number(expr *e, uint64& n, unsigned& sz) const { + rational r; + if (m_bv.is_numeral(e, r, sz) && sz <= 64) { + n = r.get_uint64(); + return true; + } + return false; + } + + bool is_bound(expr *e, expr*& v, interval& b) const { + uint64 n; + expr *lhs = 0, *rhs = 0; + unsigned sz; + + if (m_bv.is_bv_ule(e, lhs, rhs)) { + if (is_number(lhs, n, sz)) { // C ule x <=> x uge C + if (m_bv.is_numeral(rhs)) + return false; + b = interval(n, uMaxInt(sz), sz, true); + v = rhs; + return true; + } + if (is_number(rhs, n, sz)) { // x ule C + b = interval(0, n, sz, true); + v = lhs; + return true; + } + } + else if (m_bv.is_bv_sle(e, lhs, rhs)) { + if (is_number(lhs, n, sz)) { // C sle x <=> x sge C + if (m_bv.is_numeral(rhs)) + return false; + b = interval(n, (1ull << (sz-1)) - 1, sz, true); + v = rhs; + return true; + } + if (is_number(rhs, n, sz)) { // x sle C + b = interval(1ull << (sz-1), n, sz, true); + v = lhs; + return true; + } + } else if (m.is_eq(e, lhs, rhs)) { + if (is_number(lhs, n, sz)) { + if (m_bv.is_numeral(rhs)) + return false; + b = interval(n, n, sz, true); + v = rhs; + return true; + } + if (is_number(rhs, n, sz)) { + b = interval(n, n, sz, true); + v = lhs; + return true; + } + } + return false; + } + + + public: + dom_bv_bounds_simplifier(ast_manager& m, params_ref const& p) : m(m), m_params(p), m_bv(m) { + updt_params(p); + } + + virtual void updt_params(params_ref const & p) { + m_propagate_eq = p.get_bool("propagate_eq", false); + } + + static void get_param_descrs(param_descrs& r) { + r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities"); + } + + virtual ~dom_bv_bounds_simplifier() { + for (unsigned i = 0, e = m_expr_vars.size(); i < e; ++i) { + dealloc(m_expr_vars[i]); + } + for (unsigned i = 0, e = m_bound_exprs.size(); i < e; ++i) { + dealloc(m_bound_exprs[i]); + } + } + + virtual bool assert_expr(expr * t, bool sign) { + while (m.is_not(t, t)) { + sign = !sign; + } + + interval b; + expr* t1; + if (is_bound(t, t1, b)) { + SASSERT(!m_bv.is_numeral(t1)); + if (sign) + VERIFY(b.negate(b)); + + TRACE("bv", tout << (sign?"(not ":"") << mk_pp(t, m) << (sign ? ")" : "") << ": " << mk_pp(t1, m) << " in " << b << "\n";); + map::obj_map_entry* e = m_bound.find_core(t1); + if (e) { + interval& old = e->get_data().m_value; + interval intr; + if (!old.intersect(b, intr)) + return false; + if (old == intr) + return true; + m_scopes.insert(undo_bound(t1, old, false)); + old = intr; + } else { + m_bound.insert(t1, b); + m_scopes.insert(undo_bound(t1, interval(), true)); + } + } + return true; + } + + virtual void operator()(expr_ref& r) { + expr* t1, * t = r; + interval b; + + if (m_bound.find(t, b) && b.is_singleton()) { + r = m_bv.mk_numeral(b.l, m_bv.get_bv_size(t)); + return; + } + + if (!m.is_bool(t)) + return; + + bool sign = false; + while (m.is_not(t, t)) { + sign = !sign; + } + + if (!is_bound(t, t1, b)) + return; + + if (sign && b.tight) { + sign = false; + if (!b.negate(b)) { + r = m.mk_false(); + return; + } + } + + interval ctx, intr; + bool unchanged = false; + if (b.is_full() && b.tight) { + r = m.mk_true(); + } else if (m_bound.find(t1, ctx)) { + if (ctx.implies(b)) { + r = m.mk_true(); + } else if (!b.intersect(ctx, intr)) { + r = m.mk_false(); + } else if (m_propagate_eq && intr.is_singleton()) { + r = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()), + m.get_sort(t1))); + } + } + else { + unchanged = true; + } + + CTRACE("bv", !unchanged, tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";); + if (sign && unchanged) + r = m.mk_not(r); + } + + // check if t contains v + ptr_vector todo; + bool contains(expr* t, expr* v) { + ast_fast_mark1 mark; + todo.push_back(t); + while (!todo.empty()) { + t = todo.back(); + todo.pop_back(); + if (mark.is_marked(t)) { + continue; + } + if (t == v) { + todo.reset(); + return true; + } + mark.mark(t); + + if (!is_app(t)) { + continue; + } + app* a = to_app(t); + todo.append(a->get_num_args(), a->get_args()); + } + return false; + } + + bool contains_bound(expr* t) { + ast_fast_mark1 mark1; + ast_fast_mark2 mark2; + + todo.push_back(t); + while (!todo.empty()) { + t = todo.back(); + todo.pop_back(); + if (mark1.is_marked(t)) { + continue; + } + mark1.mark(t); + + if (!is_app(t)) { + continue; + } + interval b; + expr* e; + if (is_bound(t, e, b)) { + if (mark2.is_marked(e)) { + todo.reset(); + return true; + } + mark2.mark(e); + if (m_bound.contains(e)) { + todo.reset(); + return true; + } + } + + app* a = to_app(t); + todo.append(a->get_num_args(), a->get_args()); + } + return false; + } + + virtual bool may_simplify(expr* t) { + if (m_bv.is_numeral(t)) + return false; + + while (m.is_not(t, t)); + + for (auto & v : m_bound) { + if (contains(t, v.m_key)) return true; + } + +#if 0 + expr_set* used_exprs = get_expr_vars(t); + for (map::iterator I = m_bound.begin(), E = m_bound.end(); I != E; ++I) { + if (contains(t, I->m_key)) return true; + if (I->m_value.is_singleton() && used_exprs->contains(I->m_key)) + return true; + } +#endif + + expr* t1; + interval b; + // skip common case: single bound constraint without any context for simplification + if (is_bound(t, t1, b)) { + return b.is_full() || m_bound.contains(t1); + } + + if (contains_bound(t)) { + return true; + } +#if 0 + expr_cnt* bounds = get_expr_bounds(t); + for (expr_cnt::iterator I = bounds->begin(), E = bounds->end(); I != E; ++I) { + if (I->m_value > 1 || m_bound.contains(I->m_key)) + return true; + } +#endif + return false; + } + + virtual void pop(unsigned num_scopes) { + TRACE("bv", tout << "pop: " << num_scopes << "\n";); + if (m_scopes.empty()) + return; + unsigned target = m_scopes.size() - num_scopes; + if (target == 0) { + m_bound.reset(); + m_scopes.reset(); + return; + } + for (unsigned i = m_scopes.size()-1; i >= target; --i) { + undo_bound& undo = m_scopes[i]; + SASSERT(m_bound.contains(undo.e)); + if (undo.fresh) { + m_bound.erase(undo.e); + } else { + m_bound.insert(undo.e, undo.b); + } + } + m_scopes.shrink(target); + } + + virtual dom_simplifier * translate(ast_manager & m) { + return alloc(dom_bv_bounds_simplifier, m, m_params); + } + + virtual unsigned scope_level() const { + return m_scopes.size(); + } + }; } tactic * mk_bv_bounds_tactic(ast_manager & m, params_ref const & p) { return clean(alloc(ctx_simplify_tactic, m, alloc(bv_bounds_simplifier, m, p), p)); } + +tactic * mk_dom_bv_bounds_tactic(ast_manager & m, params_ref const & p) { + return clean(alloc(dom_simplify_tactic, m, alloc(dom_bv_bounds_simplifier, m, p), p)); +} diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 08037fe18..d38324db9 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -83,11 +83,12 @@ expr* expr_dominators::intersect(expr* x, expr * y) { return x; } -void expr_dominators::compute_dominators() { +bool expr_dominators::compute_dominators() { expr * e = m_root; SASSERT(m_doms.empty()); m_doms.insert(e, e); bool change = true; + unsigned iterations = 1; while (change) { change = false; SASSERT(m_post2expr.empty() || m_post2expr.back() == e); @@ -109,7 +110,12 @@ void expr_dominators::compute_dominators() { change = true; } } + iterations *= 2; + if (change && iterations > m_post2expr.size()) { + return false; + } } + return true; } void expr_dominators::extract_tree() { @@ -118,17 +124,18 @@ void expr_dominators::extract_tree() { } } -void expr_dominators::compile(expr * e) { +bool expr_dominators::compile(expr * e) { reset(); m_root = e; compute_post_order(); - compute_dominators(); + if (!compute_dominators()) return false; extract_tree(); + return true; } -void expr_dominators::compile(unsigned sz, expr * const* es) { +bool expr_dominators::compile(unsigned sz, expr * const* es) { expr_ref e(m.mk_and(sz, es), m); - compile(e); + return compile(e); } void expr_dominators::reset() { @@ -293,14 +300,14 @@ expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { } -void dom_simplify_tactic::init(goal& g) { +bool dom_simplify_tactic::init(goal& g) { expr_ref_vector args(m); unsigned sz = g.size(); for (unsigned i = 0; i < sz; ++i) args.push_back(g.form(i)); expr_ref fml = mk_and(args); m_result.reset(); m_trail.reset(); - m_dominators.compile(fml); + return m_dominators.compile(fml); } void dom_simplify_tactic::simplify_goal(goal& g) { @@ -312,7 +319,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { change = false; // go forwards - init(g); + if (!init(g)) return; unsigned sz = g.size(); for (unsigned i = 0; !g.inconsistent() && i < sz; ++i) { expr_ref r = simplify(g.form(i)); @@ -329,7 +336,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { pop(scope_level()); // go backwards - init(g); + if (!init(g)) return; sz = g.size(); for (unsigned i = sz; !g.inconsistent() && i > 0; ) { --i; diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 25fb7c24f..6e5833cdb 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -45,14 +45,14 @@ private: void compute_post_order(); expr* intersect(expr* x, expr * y); - void compute_dominators(); + bool compute_dominators(); void extract_tree(); public: expr_dominators(ast_manager& m): m(m), m_root(m) {} - void compile(expr * e); - void compile(unsigned sz, expr * const* es); + bool compile(expr * e); + bool compile(unsigned sz, expr * const* es); tree_t const& get_tree() { return m_tree; } void reset(); @@ -115,7 +115,7 @@ private: void pop(unsigned n) { SASSERT(n <= m_scope_level); m_scope_level -= n; m_simplifier->pop(n); } bool assert_expr(expr* f, bool sign) { m_scope_level++; return m_simplifier->assert_expr(f, sign); } - void init(goal& g); + bool init(goal& g); public: dom_simplify_tactic(ast_manager & m, dom_simplifier* s, params_ref const & p = params_ref()): From 755ca46df65209f275966886acc968ea02533992 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 6 Oct 2017 12:15:41 +0100 Subject: [PATCH 343/488] adding bv_bounds tactic dominator style Signed-off-by: Nikolaj Bjorner --- src/tactic/bv/bv_bounds_tactic.cpp | 58 +++++------------------------- 1 file changed, 9 insertions(+), 49 deletions(-) diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp index 2d5eb216a..44f920840 100644 --- a/src/tactic/bv/bv_bounds_tactic.cpp +++ b/src/tactic/bv/bv_bounds_tactic.cpp @@ -560,7 +560,7 @@ namespace { bool is_bound(expr *e, expr*& v, interval& b) const { uint64 n; expr *lhs = 0, *rhs = 0; - unsigned sz; + unsigned sz = 0; if (m_bv.is_bv_ule(e, lhs, rhs)) { if (is_number(lhs, n, sz)) { // C ule x <=> x uge C @@ -689,25 +689,27 @@ namespace { } interval ctx, intr; - bool unchanged = false; + bool was_updated = true; if (b.is_full() && b.tight) { r = m.mk_true(); } else if (m_bound.find(t1, ctx)) { if (ctx.implies(b)) { r = m.mk_true(); - } else if (!b.intersect(ctx, intr)) { + } + else if (!b.intersect(ctx, intr)) { r = m.mk_false(); - } else if (m_propagate_eq && intr.is_singleton()) { + } + else if (m_propagate_eq && intr.is_singleton()) { r = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()), m.get_sort(t1))); } } else { - unchanged = true; + was_updated = false; } - CTRACE("bv", !unchanged, tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";); - if (sign && unchanged) + CTRACE("bv", was_updated, tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";); + if (sign && was_updated) r = m.mk_not(r); } @@ -773,45 +775,6 @@ namespace { return false; } - virtual bool may_simplify(expr* t) { - if (m_bv.is_numeral(t)) - return false; - - while (m.is_not(t, t)); - - for (auto & v : m_bound) { - if (contains(t, v.m_key)) return true; - } - -#if 0 - expr_set* used_exprs = get_expr_vars(t); - for (map::iterator I = m_bound.begin(), E = m_bound.end(); I != E; ++I) { - if (contains(t, I->m_key)) return true; - if (I->m_value.is_singleton() && used_exprs->contains(I->m_key)) - return true; - } -#endif - - expr* t1; - interval b; - // skip common case: single bound constraint without any context for simplification - if (is_bound(t, t1, b)) { - return b.is_full() || m_bound.contains(t1); - } - - if (contains_bound(t)) { - return true; - } -#if 0 - expr_cnt* bounds = get_expr_bounds(t); - for (expr_cnt::iterator I = bounds->begin(), E = bounds->end(); I != E; ++I) { - if (I->m_value > 1 || m_bound.contains(I->m_key)) - return true; - } -#endif - return false; - } - virtual void pop(unsigned num_scopes) { TRACE("bv", tout << "pop: " << num_scopes << "\n";); if (m_scopes.empty()) @@ -838,9 +801,6 @@ namespace { return alloc(dom_bv_bounds_simplifier, m, m_params); } - virtual unsigned scope_level() const { - return m_scopes.size(); - } }; } From 690b17fc25d8b8bac8af63ae4788e37b29b20cee Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 6 Oct 2017 12:33:47 +0100 Subject: [PATCH 344/488] Removed Ubuntu x86 VSTS/CI build (not supported by VSTS anymore). --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 197928877..701556cc8 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ See the [release notes](RELEASE_NOTES) for notes on various stable releases of Z ## Build status -| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | Debian x64 | OSX | TravisCI | -| ----------- | ----------- | ---------- | ---------- | ---------- | --- | -------- | -[![win32-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/4/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=4) | [![win64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/7/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=7) | [![ubuntu-x64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/3/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=3) | [![ubuntu-x86-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/6/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=6) | [![debian-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/5/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=5) | [![osx-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/2/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=2) | [![Build Status](https://travis-ci.org/Z3Prover/z3.svg?branch=master)](https://travis-ci.org/Z3Prover/z3) +| Windows x86 | Windows x64 | Ubuntu x64 | Debian x64 | OSX | TravisCI | +| ----------- | ----------- | ---------- | ---------- | --- | -------- | +[![win32-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/4/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=4) | [![win64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/7/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=7) | [![ubuntu-x64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/3/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=3) | [![debian-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/5/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=5) | [![osx-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/2/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=2) | [![Build Status](https://travis-ci.org/Z3Prover/z3.svg?branch=master)](https://travis-ci.org/Z3Prover/z3) [1]: #building-z3-on-windows-using-visual-studio-command-prompt [2]: #building-z3-using-make-and-gccclang From d47aea398730634444bd31172fd2a04739a9efa7 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 11:23:44 +0100 Subject: [PATCH 345/488] [TravisCI] Workaround slow unit test execution for Debug builds. Unit tests execute very slowly in Debug (i.e. unoptimized) builds. This causes TravisCI to terminate the job due to no console output being seen. To workaround this for the debug builds the tests are just compiled but not executed. To implement this the `RUN_UNIT_TESTS` environment variable now can take on the values `BUILD_ONLY`, `BUILD_AND_RUN`, and `SKIP` rather than `0` or `1`. --- .travis.yml | 11 ++++-- contrib/ci/README.md | 2 +- contrib/ci/scripts/ci_defaults.sh | 2 +- .../ci/scripts/test_z3_unit_tests_cmake.sh | 36 ++++++++++++++----- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 50d63e593..ac00ef918 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,10 +22,17 @@ env: # 64-bit Clang 3.9 RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo + # Debug builds + # + # Note the unit tests for the debug builds are compiled but **not** + # executed. This is because the debug build of unit tests takes a large + # amount of time to execute compared to the optimized builds. The hope is + # that just running the optimized unit tests is sufficient. + # # 64-bit GCC 5.4 Debug - - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug RUN_UNIT_TESTS=BUILD_ONLY # 64-bit Clang Debug - - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug RUN_UNIT_TESTS=BUILD_ONLY # 32-bit GCC 5.4 RelWithDebInfo - LINUX_BASE=ubuntu32_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=i686 Z3_BUILD_TYPE=RelWithDebInfo diff --git a/contrib/ci/README.md b/contrib/ci/README.md index 2e117c8b1..e4c9aecfd 100644 --- a/contrib/ci/README.md +++ b/contrib/ci/README.md @@ -31,7 +31,7 @@ the future. * `NO_SUPPRESS_OUTPUT` - Don't suppress output of some commands (`0` or `1`) * `PYTHON_BINDINGS` - Build and test Python API bindings (`0` or `1`) * `RUN_SYSTEM_TESTS` - Run system tests (`0` or `1`) -* `RUN_UNIT_TESTS` - Run unit tests (`0` or `1`) +* `RUN_UNIT_TESTS` - Run unit tests (`BUILD_ONLY` or `BUILD_AND_RUN` or `SKIP`) * `TARGET_ARCH` - Target architecture (`x86_64` or `i686`) * `TEST_INSTALL` - Test running `install` target (`0` or `1`) * `UBSAN_BUILD` - Do [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) build (`0` or `1`) diff --git a/contrib/ci/scripts/ci_defaults.sh b/contrib/ci/scripts/ci_defaults.sh index 2fb3fa52a..d8e9376d8 100644 --- a/contrib/ci/scripts/ci_defaults.sh +++ b/contrib/ci/scripts/ci_defaults.sh @@ -10,7 +10,7 @@ export JAVA_BINDINGS="${JAVA_BINDINGS:-1}" export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}" export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}" export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}" -export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}" +export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-BUILD_AND_RUN}" export TARGET_ARCH="${TARGET_ARCH:-x86_64}" export TEST_INSTALL="${TEST_INSTALL:-1}" export UBSAN_BUILD="${UBSAN_BUILD:-0}" diff --git a/contrib/ci/scripts/test_z3_unit_tests_cmake.sh b/contrib/ci/scripts/test_z3_unit_tests_cmake.sh index 666673328..e1c927f58 100755 --- a/contrib/ci/scripts/test_z3_unit_tests_cmake.sh +++ b/contrib/ci/scripts/test_z3_unit_tests_cmake.sh @@ -10,17 +10,35 @@ set -o pipefail : ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"} : ${RUN_UNIT_TESTS?"RUN_UNIT_TESTS must be specified"} -if [ "X${RUN_UNIT_TESTS}" != "X1" ]; then - echo "Skipping unit tests" - exit 0 -fi - # Set CMake generator args source ${SCRIPT_DIR}/set_generator_args.sh cd "${Z3_BUILD_DIR}" -# Build and run internal tests -cmake --build $(pwd) --target test-z3 "${GENERATOR_ARGS[@]}" -# Run all tests that don't require arguments -run_quiet ./test-z3 /a +function build_unit_tests() { + # Build internal tests + cmake --build $(pwd) --target test-z3 "${GENERATOR_ARGS[@]}" +} + +function run_unit_tests() { + # Run all tests that don't require arguments + run_quiet ./test-z3 /a +} + +case "${RUN_UNIT_TESTS}" in + BUILD_AND_RUN) + build_unit_tests + run_unit_tests + ;; + BUILD_ONLY) + build_unit_tests + ;; + SKIP) + echo "RUN_UNIT_TESTS set to \"${RUN_UNIT_TESTS}\" so skipping build and run" + exit 0 + ;; + *) + echo "Error: RUN_UNIT_TESTS set to unhandled value \"${RUN_UNIT_TESTS}\"" + exit 1 + ;; +esac From 2519719d3f452eb2cbbaf0db822e58b671e4e74f Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 11:30:06 +0100 Subject: [PATCH 346/488] Fix typo --- contrib/ci/scripts/set_generator_args.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ci/scripts/set_generator_args.sh b/contrib/ci/scripts/set_generator_args.sh index 0ef7b76aa..a704c518b 100644 --- a/contrib/ci/scripts/set_generator_args.sh +++ b/contrib/ci/scripts/set_generator_args.sh @@ -1,4 +1,4 @@ -# This script should is intended to be included by other +# This script is intended to be included by other # scripts and should not be executed directly : ${Z3_CMAKE_GENERATOR?"Z3_CMAKE_GENERATOR must be specified"} From 0be28b66fe3319be01492a0391514727e099916c Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 11:48:20 +0100 Subject: [PATCH 347/488] [TravisCI] Update out of date `README.md` file. --- contrib/ci/README.md | 46 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/contrib/ci/README.md b/contrib/ci/README.md index e4c9aecfd..99bbcd7a6 100644 --- a/contrib/ci/README.md +++ b/contrib/ci/README.md @@ -58,8 +58,9 @@ The `scripts/travis_ci_linux_entry_point.sh` script variables (if set) into the build using the `--build-arg` argument of the `docker run` command. -If an environemnt variable is not set a defaults value is used which can be -found in `Dockerfiles/z3_build.Dockerfile`. +The default values of the configuration environment variables +can be found in +[`scripts/ci_defaults.sh`](scripts/ci_defaults.sh). #### Linux specific configuration variables @@ -67,8 +68,9 @@ found in `Dockerfiles/z3_build.Dockerfile`. #### Reproducing a build locally -A build can be reproduced locally by using the `scripts/travis_ci_linux_entry_point.sh` -script and setting the appropriate environment variable. +A build can be reproduced locally by using the +`scripts/travis_ci_linux_entry_point.sh` script and setting the appropriate +environment variable. For example lets say we wanted to reproduce the build below. @@ -104,11 +106,43 @@ feature might be removed in the future. It may be better to just build the base image once (outside of TravisCI), upload it to [DockerHub](https://hub.docker.com/) and have the build pull down the pre-built -image everytime. +image every time. An [organization](https://hub.docker.com/u/z3prover/) has been created on DockerHub for this. ### macOS -Not yet implemented. +For macOS we execute directly on TravisCI's macOS environment. The entry point +for the TravisCI builds is the +[`scripts/travis_ci_osx_entry_point.sh`](scripts/travis_ci_osx_entry_point.sh) +scripts. + +#### macOS specific configuration variables + +* `MACOS_SKIP_DEPS_UPDATE` - If set to `1` installing the necessary build dependencies + is skipped. This is useful for local testing if the dependencies are already installed. +* `MACOS_UPDATE_CMAKE` - If set to `1` the installed version of CMake will be upgraded. + +#### Reproducing a build locally + +To reproduce a build (e.g. like the one shown below) + +```yaml +- os: osx + osx_image: xcode8.3 + # Note: Apple Clang does not support OpenMP + env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0 +``` + +Run the following: + +```bash +TRAVIS_BUILD_DIR=$(pwd) \ +Z3_BUILD_TYPE=RelWithDebInfo \ +USE_OPEN_MP=0 \ +contrib/ci/scripts/travis_ci_osx_entry_point.sh +``` + +Note this assumes that the current working directory is the root of the Z3 +git repository. From 50042ab6388f5bd4bb7b8ba23622b96b7ef59131 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 6 Oct 2017 13:00:09 +0100 Subject: [PATCH 348/488] removed unused variables --- src/ast/fpa/fpa2bv_converter.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index f09ddcd42..13a7599a9 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1180,8 +1180,6 @@ void fpa2bv_converter::mk_abs(sort * s, expr_ref & x, expr_ref & result) { void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); - unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); expr * x = args[0], * y = args[1]; @@ -1227,8 +1225,6 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); - unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); expr * x = args[0], *y = args[1]; @@ -3081,8 +3077,6 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * mk_is_nan(x, x_is_nan); sort * fp_srt = m.get_sort(x); - unsigned ebits = m_util.get_ebits(fp_srt); - unsigned sbits = m_util.get_sbits(fp_srt); expr_ref unspec(m); mk_to_ieee_bv_unspecified(f, num, args, unspec); From 2634be01aa0c615e3b8b1362ce317f783b7109fc Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 6 Oct 2017 13:43:01 +0100 Subject: [PATCH 349/488] adding backwards pass Signed-off-by: Nikolaj Bjorner --- src/tactic/core/dom_simplify_tactic.cpp | 35 +++++++++++++++++-------- src/tactic/core/dom_simplify_tactic.h | 3 ++- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index d38324db9..da704bd0b 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -281,17 +281,28 @@ expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { }; expr_ref_vector args(m); - for (expr * arg : *e) { - for (expr * child : tree(arg)) { - if (is_subexpr_arg(child, arg)) { - simplify(child); - } - } - r = simplify(arg); - args.push_back(r); - if (!assert_expr(simplify(arg), !is_and)) { - r = is_and ? m.mk_false() : m.mk_true(); - return r; + if (m_forward) { + for (expr * arg : *e) { +#define _SIMP_ARG(arg) \ + for (expr * child : tree(arg)) { \ + if (is_subexpr_arg(child, arg)) { \ + simplify(child); \ + } \ + } \ + r = simplify(arg); \ + args.push_back(r); \ + if (!assert_expr(simplify(arg), !is_and)) { \ + r = is_and ? m.mk_false() : m.mk_true(); \ + return r; \ + } + _SIMP_ARG(arg); + } + } + else { + for (unsigned i = e->get_num_args(); i > 0; ) { + --i; + expr* arg = e->get_arg(i); + _SIMP_ARG(arg); } } pop(scope_level() - old_lvl); @@ -319,6 +330,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { change = false; // go forwards + m_forward = true; if (!init(g)) return; unsigned sz = g.size(); for (unsigned i = 0; !g.inconsistent() && i < sz; ++i) { @@ -336,6 +348,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { pop(scope_level()); // go backwards + m_forward = false; if (!init(g)) return; sz = g.size(); for (unsigned i = sz; !g.inconsistent() && i > 0; ) { diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 6e5833cdb..581d40cd0 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -96,6 +96,7 @@ private: unsigned m_max_depth; ptr_vector m_empty; obj_pair_map m_subexpr_cache; + bool m_forward; expr_ref simplify(expr* t); expr_ref simplify_ite(app * ite); @@ -122,7 +123,7 @@ public: m(m), m_simplifier(s), m_params(p), m_trail(m), m_args(m), m_dominators(m), - m_scope_level(0), m_depth(0), m_max_depth(1024) {} + m_scope_level(0), m_depth(0), m_max_depth(1024), m_forward(true) {} virtual ~dom_simplify_tactic() {} From 9aa6386be94e96651b5c12065cb95a9e4dea74b8 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Fri, 6 Oct 2017 15:27:16 +0100 Subject: [PATCH 350/488] fix debug build --- src/util/lp/indexed_vector_instances.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/lp/indexed_vector_instances.cpp b/src/util/lp/indexed_vector_instances.cpp index ee078f021..79c3ee1a1 100644 --- a/src/util/lp/indexed_vector_instances.cpp +++ b/src/util/lp/indexed_vector_instances.cpp @@ -33,6 +33,7 @@ template void indexed_vector::resize(unsigned int); template void indexed_vector::set_value(const mpq&, unsigned int); template void indexed_vector::set_value(const unsigned&, unsigned int); #ifdef Z3DEBUG +template bool indexed_vector::is_OK() const; template bool indexed_vector::is_OK() const; template bool indexed_vector::is_OK() const; template bool indexed_vector >::is_OK() const; From ba8bff76ae9a68bef78c88913cbc2c62a193b299 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 15:52:01 +0100 Subject: [PATCH 351/488] [TravisCI] Modify Debug configuration that I forgot to change with `RUN_UNIT_TESTS=BUILD_ONLY`. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ac00ef918..81ddefb8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,7 +64,7 @@ env: # 64-bit GCC 4.8 RelWithDebInfo - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo # 64-bit GCC 4.8 Debug - - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug + - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug RUN_UNIT_TESTS=BUILD_ONLY # macOS (a.k.a OSX) support matrix: From c3f615dbfcf1436a142d1112598f358ed6c27bbd Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 6 Oct 2017 16:03:43 +0100 Subject: [PATCH 352/488] reverse arguments Signed-off-by: Nikolaj Bjorner --- src/tactic/core/dom_simplify_tactic.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index da704bd0b..67b039814 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -291,7 +291,7 @@ expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { } \ r = simplify(arg); \ args.push_back(r); \ - if (!assert_expr(simplify(arg), !is_and)) { \ + if (!assert_expr(r, !is_and)) { \ r = is_and ? m.mk_false() : m.mk_true(); \ return r; \ } @@ -304,6 +304,7 @@ expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { expr* arg = e->get_arg(i); _SIMP_ARG(arg); } + args.reverse(); } pop(scope_level() - old_lvl); r = is_and ? mk_and(args) : mk_or(args); @@ -338,6 +339,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { if (i < sz - 1 && !m.is_true(r) && !m.is_false(r) && !g.dep(i) && !g.proofs_enabled() && !assert_expr(r, false)) { r = m.mk_false(); } + CTRACE("simplify", r != g.form(i), tout << r << " " << mk_pp(g.form(i), m) << "\n";); change |= r != g.form(i); proof* new_pr = 0; if (g.proofs_enabled()) { @@ -358,6 +360,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { r = m.mk_false(); } change |= r != g.form(i); + CTRACE("simplify", r != g.form(i), tout << r << " " << mk_pp(g.form(i), m) << "\n";); proof* new_pr = 0; if (g.proofs_enabled()) { new_pr = m.mk_modus_ponens(g.pr(i), m.mk_rewrite_star(g.form(i), r, 0, 0)); From 31c6b3eb5b94053c8c40f2939ad429c31471edaa Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 6 Oct 2017 16:07:25 +0100 Subject: [PATCH 353/488] fix leak Signed-off-by: Nikolaj Bjorner --- src/tactic/core/dom_simplify_tactic.cpp | 4 ++++ src/tactic/core/dom_simplify_tactic.h | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 67b039814..99f83799b 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -152,6 +152,10 @@ void expr_dominators::reset() { // ----------------------- // dom_simplify_tactic +dom_simplify_tactic::~dom_simplify_tactic() { + dealloc(m_simplifier); +} + tactic * dom_simplify_tactic::translate(ast_manager & m) { return alloc(dom_simplify_tactic, m, m_simplifier->translate(m), m_params); } diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 581d40cd0..c1660a941 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -83,8 +83,6 @@ class dom_simplifier { }; class dom_simplify_tactic : public tactic { -public: -private: ast_manager& m; dom_simplifier* m_simplifier; params_ref m_params; @@ -126,7 +124,7 @@ public: m_scope_level(0), m_depth(0), m_max_depth(1024), m_forward(true) {} - virtual ~dom_simplify_tactic() {} + virtual ~dom_simplify_tactic(); virtual tactic * translate(ast_manager & m); virtual void updt_params(params_ref const & p) {} From 1d12a9c86de07feafe1261fa52b8248fe1d494ef Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Fri, 6 Oct 2017 18:19:37 +0100 Subject: [PATCH 354/488] dom_simplifier: fix dominator computation --- src/tactic/core/dom_simplify_tactic.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 99f83799b..16d8500a4 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -95,17 +95,17 @@ bool expr_dominators::compute_dominators() { for (unsigned i = 0; i + 1 < m_post2expr.size(); ++i) { expr * child = m_post2expr[i]; ptr_vector const& p = m_parents[child]; - SASSERT(!p.empty()); expr * new_idom = 0, *idom2 = 0; - for (unsigned j = 0; j < p.size(); ++j) { - if (!new_idom) { - m_doms.find(p[j], new_idom); - } - else if (m_doms.find(p[j], idom2)) { - new_idom = intersect(new_idom, idom2); + for (auto& pred : p) { + if (m_doms.contains(pred)) { + new_idom = !new_idom ? pred : intersect(new_idom, pred); } } - if (new_idom && (!m_doms.find(child, idom2) || idom2 != new_idom)) { + if (!new_idom) { + m_doms.insert(child, p[0]); + change = true; + } + else if (!m_doms.find(child, idom2) || idom2 != new_idom) { m_doms.insert(child, new_idom); change = true; } From a18236bc7f2a9037ccd1d7d078cb54c132328474 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 7 Oct 2017 00:07:53 +0100 Subject: [PATCH 355/488] have quantifier equality take names into account Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 3 ++ src/ast/expr_abstract.cpp | 9 ++++ src/ast/expr_substitution.cpp | 7 +++ src/ast/expr_substitution.h | 3 ++ src/tactic/core/dom_simplify_tactic.cpp | 65 ++++++++++++++++++++----- src/tactic/core/dom_simplify_tactic.h | 5 +- 6 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index c98307ee0..cac12413e 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -471,6 +471,9 @@ bool compare_nodes(ast const * n1, ast const * n2) { compare_arrays(to_quantifier(n1)->get_decl_sorts(), to_quantifier(n2)->get_decl_sorts(), to_quantifier(n1)->get_num_decls()) && + compare_arrays(to_quantifier(n1)->get_decl_names(), + to_quantifier(n2)->get_decl_names(), + to_quantifier(n1)->get_num_decls()) && to_quantifier(n1)->get_expr() == to_quantifier(n2)->get_expr() && to_quantifier(n1)->get_weight() == to_quantifier(n2)->get_weight() && to_quantifier(n1)->get_num_patterns() == to_quantifier(n2)->get_num_patterns() && diff --git a/src/ast/expr_abstract.cpp b/src/ast/expr_abstract.cpp index 46682eed6..43035e203 100644 --- a/src/ast/expr_abstract.cpp +++ b/src/ast/expr_abstract.cpp @@ -19,6 +19,7 @@ Notes: #include "ast/expr_abstract.h" #include "util/map.h" +#include "ast/ast_pp.h" void expr_abstractor::operator()(unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) { @@ -109,6 +110,9 @@ void expr_abstractor::operator()(unsigned base, unsigned num_bound, expr* const* void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* const* bound, expr* n, expr_ref& result) { expr_abstractor abs(m); abs(base, num_bound, bound, n, result); + TRACE("expr_abstract", + tout << expr_ref(n, m) << "\n"; + tout << result << "\n";); } expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app* const* bound, expr* n) { @@ -123,6 +127,11 @@ expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app* } result = m.mk_quantifier(is_forall, num_bound, sorts.c_ptr(), names.c_ptr(), result); } + TRACE("expr_abstract", + tout << expr_ref(n, m) << "\n"; + for (unsigned i = 0; i < num_bound; ++i) tout << expr_ref(bound[i], m) << " "; + tout << "\n"; + tout << result << "\n";); return result; } diff --git a/src/ast/expr_substitution.cpp b/src/ast/expr_substitution.cpp index 149a59ce5..3ce038250 100644 --- a/src/ast/expr_substitution.cpp +++ b/src/ast/expr_substitution.cpp @@ -56,6 +56,13 @@ expr_substitution::~expr_substitution() { reset(); } +std::ostream& expr_substitution::display(std::ostream& out) { + for (auto & kv : m_subst) { + out << expr_ref(kv.m_key, m()) << " |-> " << expr_ref(kv.m_value, m()) << "\n"; + } + return out; +} + void expr_substitution::insert(expr * c, expr * def, proof * def_pr, expr_dependency * def_dep) { obj_map::obj_map_entry * entry = m_subst.insert_if_not_there2(c, 0); if (entry->get_data().m_value == 0) { diff --git a/src/ast/expr_substitution.h b/src/ast/expr_substitution.h index d360356eb..90154d163 100644 --- a/src/ast/expr_substitution.h +++ b/src/ast/expr_substitution.h @@ -50,6 +50,8 @@ public: bool contains(expr * s); void reset(); void cleanup(); + + std::ostream& display(std::ostream& out); }; class scoped_expr_substitution { @@ -84,6 +86,7 @@ public: bool find(expr * s, expr * & def, proof * & def_pr, expr_dependency * & def_dep) { return m_subst.find(s, def, def_pr, def_dep); } bool contains(expr * s) { return m_subst.contains(s); } void cleanup() { m_subst.cleanup(); } + std::ostream& display(std::ostream& out) { return m_subst.display(out); } }; #endif diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 99f83799b..60207e823 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -91,23 +91,42 @@ bool expr_dominators::compute_dominators() { unsigned iterations = 1; while (change) { change = false; + TRACE("simplify", + for (auto & kv : m_doms) { + tout << expr_ref(kv.m_key, m) << " |-> " << expr_ref(kv.m_value, m) << "\n"; + }); + SASSERT(m_post2expr.empty() || m_post2expr.back() == e); for (unsigned i = 0; i + 1 < m_post2expr.size(); ++i) { expr * child = m_post2expr[i]; ptr_vector const& p = m_parents[child]; SASSERT(!p.empty()); - expr * new_idom = 0, *idom2 = 0; - for (unsigned j = 0; j < p.size(); ++j) { - if (!new_idom) { - m_doms.find(p[j], new_idom); - } - else if (m_doms.find(p[j], idom2)) { - new_idom = intersect(new_idom, idom2); - } + if (p.size() == 1) { + if (!m_doms.contains(child)) { + m_doms.insert(child, p[0]); + change = true; + } } - if (new_idom && (!m_doms.find(child, idom2) || idom2 != new_idom)) { - m_doms.insert(child, new_idom); - change = true; + else { + expr * new_idom = 0, *idom2 = 0; + for (unsigned j = 0; j < p.size(); ++j) { + if (!new_idom) { + m_doms.find(p[j], new_idom); + } + else if (m_doms.find(p[j], idom2)) { + new_idom = intersect(new_idom, idom2); + } + } + if (!new_idom) { + m_doms.insert(child, p[0]); + TRACE("simplify", tout << expr_ref(child, m) << " |-> " << expr_ref(p[0], m) << "\n";); + change = true; + } + else if (!m_doms.find(child, idom2) || idom2 != new_idom) { + m_doms.insert(child, new_idom); + TRACE("simplify", tout << expr_ref(child, m) << " |-> " << expr_ref(new_idom, m) << "\n";); + change = true; + } } } iterations *= 2; @@ -130,6 +149,7 @@ bool expr_dominators::compile(expr * e) { compute_post_order(); if (!compute_dominators()) return false; extract_tree(); + TRACE("simplify", display(tout);); return true; } @@ -147,6 +167,22 @@ void expr_dominators::reset() { m_root.reset(); } +std::ostream& expr_dominators::display(std::ostream& out) { + return display(out, 0, m_root); +} + +std::ostream& expr_dominators::display(std::ostream& out, unsigned indent, expr* r) { + for (unsigned i = 0; i < indent; ++i) out << " "; + out << expr_ref(r, m); + if (m_tree.contains(r)) { + for (expr* child : m_tree[r]) { + if (child != r) + display(out, indent + 1, child); + } + } + out << "\n"; + return out; +} // ----------------------- @@ -200,7 +236,6 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { simplify(child); } } - pop(scope_level() - old_lvl); expr_ref new_t = simplify(t); if (!assert_expr(new_c, true)) { @@ -230,6 +265,8 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { expr_ref dom_simplify_tactic::simplify(expr * e0) { expr_ref r(m); expr* e = 0; + + TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e0, m) << " -> " << r << "\n";); if (!m_result.find(e0, e)) { e = e0; } @@ -254,7 +291,9 @@ expr_ref dom_simplify_tactic::simplify(expr * e0) { if (is_app(e)) { m_args.reset(); for (expr* arg : *to_app(e)) { - m_args.push_back(get_cached(arg)); // TBD is cache really applied to all sub-terms? + r = get_cached(arg); + (*m_simplifier)(r); + m_args.push_back(r); } r = m.mk_app(to_app(e)->get_decl(), m_args.size(), m_args.c_ptr()); } diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index c1660a941..d99f799b4 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -48,6 +48,8 @@ private: bool compute_dominators(); void extract_tree(); + std::ostream& display(std::ostream& out, unsigned indent, expr* r); + public: expr_dominators(ast_manager& m): m(m), m_root(m) {} @@ -55,7 +57,8 @@ public: bool compile(unsigned sz, expr * const* es); tree_t const& get_tree() { return m_tree; } void reset(); - + + std::ostream& display(std::ostream& out); }; class dom_simplifier { From 76c309a595639cbbde974f8efe2b42f24a9d7e8f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 7 Oct 2017 00:20:58 +0100 Subject: [PATCH 356/488] disable caching of simplifier when applied to direct arguments of terms. Caching is only valid when applied to dominator children Signed-off-by: Nikolaj Bjorner --- src/tactic/core/dom_simplify_tactic.cpp | 31 +++++++++++++------------ src/tactic/core/dom_simplify_tactic.h | 2 +- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 830d44c7a..1bd685bb1 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -101,7 +101,8 @@ bool expr_dominators::compute_dominators() { expr * child = m_post2expr[i]; ptr_vector const& p = m_parents[child]; expr * new_idom = 0, *idom2 = 0; - for (auto& pred : p) { + + for (expr * pred : p) { if (m_doms.contains(pred)) { new_idom = !new_idom ? pred : intersect(new_idom, pred); } @@ -209,31 +210,31 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { expr * c = 0, *t = 0, *e = 0; VERIFY(m.is_ite(ite, c, t, e)); unsigned old_lvl = scope_level(); - expr_ref new_c = simplify(c); + expr_ref new_c = simplify(c, false); if (m.is_true(new_c)) { - r = simplify(t); + r = simplify(t, false); } else if (m.is_false(new_c) || !assert_expr(new_c, false)) { - r = simplify(e); + r = simplify(e, false); } else { for (expr * child : tree(ite)) { if (is_subexpr(child, t) && !is_subexpr(child, e)) { - simplify(child); + simplify(child, true); } } pop(scope_level() - old_lvl); - expr_ref new_t = simplify(t); + expr_ref new_t = simplify(t, false); if (!assert_expr(new_c, true)) { return new_t; } for (expr * child : tree(ite)) { if (is_subexpr(child, e) && !is_subexpr(child, t)) { - simplify(child); + simplify(child, true); } } pop(scope_level() - old_lvl); - expr_ref new_e = simplify(e); + expr_ref new_e = simplify(e, false); if (c == new_c && t == new_t && e == new_e) { r = ite; } @@ -248,7 +249,7 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { return r; } -expr_ref dom_simplify_tactic::simplify(expr * e0) { +expr_ref dom_simplify_tactic::simplify(expr * e0, bool cache_result) { expr_ref r(m); expr* e = 0; @@ -272,7 +273,7 @@ expr_ref dom_simplify_tactic::simplify(expr * e0) { } else { for (expr * child : tree(e)) { - simplify(child); + simplify(child, true); } if (is_app(e)) { m_args.reset(); @@ -288,7 +289,7 @@ expr_ref dom_simplify_tactic::simplify(expr * e0) { } } (*m_simplifier)(r); - cache(e0, r); + if (cache_result) cache(e0, r); TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e0, m) << " -> " << r << "\n";); --m_depth; m_subexpr_cache.reset(); @@ -315,10 +316,10 @@ expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { #define _SIMP_ARG(arg) \ for (expr * child : tree(arg)) { \ if (is_subexpr_arg(child, arg)) { \ - simplify(child); \ + simplify(child, true); \ } \ } \ - r = simplify(arg); \ + r = simplify(arg, false); \ args.push_back(r); \ if (!assert_expr(r, !is_and)) { \ r = is_and ? m.mk_false() : m.mk_true(); \ @@ -364,7 +365,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { if (!init(g)) return; unsigned sz = g.size(); for (unsigned i = 0; !g.inconsistent() && i < sz; ++i) { - expr_ref r = simplify(g.form(i)); + expr_ref r = simplify(g.form(i), true); if (i < sz - 1 && !m.is_true(r) && !m.is_false(r) && !g.dep(i) && !g.proofs_enabled() && !assert_expr(r, false)) { r = m.mk_false(); } @@ -384,7 +385,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { sz = g.size(); for (unsigned i = sz; !g.inconsistent() && i > 0; ) { --i; - expr_ref r = simplify(g.form(i)); + expr_ref r = simplify(g.form(i), true); if (i > 0 && !m.is_true(r) && !m.is_false(r) && !g.dep(i) && !g.proofs_enabled() && !assert_expr(r, false)) { r = m.mk_false(); } diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index d99f799b4..e79777215 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -99,7 +99,7 @@ class dom_simplify_tactic : public tactic { obj_pair_map m_subexpr_cache; bool m_forward; - expr_ref simplify(expr* t); + expr_ref simplify(expr* t, bool cache); expr_ref simplify_ite(app * ite); expr_ref simplify_and(app * ite) { return simplify_and_or(true, ite); } expr_ref simplify_or(app * ite) { return simplify_and_or(false, ite); } From 7e4f5322023ddf5d1a4ae485d710c4f8c59a65f6 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 7 Oct 2017 00:37:44 +0100 Subject: [PATCH 357/488] fix build by including mk_pp Signed-off-by: Nikolaj Bjorner --- src/ast/expr_substitution.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ast/expr_substitution.cpp b/src/ast/expr_substitution.cpp index 3ce038250..f9333c443 100644 --- a/src/ast/expr_substitution.cpp +++ b/src/ast/expr_substitution.cpp @@ -16,8 +16,9 @@ Author: Notes: --*/ -#include "ast/expr_substitution.h" #include "util/ref_util.h" +#include "ast/expr_substitution.h" +#include "ast/ast_pp.h" typedef obj_map expr2proof; typedef obj_map expr2expr_dependency; @@ -58,7 +59,7 @@ expr_substitution::~expr_substitution() { std::ostream& expr_substitution::display(std::ostream& out) { for (auto & kv : m_subst) { - out << expr_ref(kv.m_key, m()) << " |-> " << expr_ref(kv.m_value, m()) << "\n"; + out << mk_pp(kv.m_key, m()) << " |-> " << mk_pp(kv.m_value, m()) << "\n"; } return out; } From b898b077953c8e4a18d9b49567af37952e889eb8 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 7 Oct 2017 11:12:09 +0100 Subject: [PATCH 358/488] distinguish simplify_rec from simplify immediate argument Signed-off-by: Nikolaj Bjorner --- src/tactic/core/dom_simplify_tactic.cpp | 40 ++++++++++++++----------- src/tactic/core/dom_simplify_tactic.h | 3 +- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 1bd685bb1..366e1edb0 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -210,31 +210,31 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { expr * c = 0, *t = 0, *e = 0; VERIFY(m.is_ite(ite, c, t, e)); unsigned old_lvl = scope_level(); - expr_ref new_c = simplify(c, false); + expr_ref new_c = simplify_arg(c); if (m.is_true(new_c)) { - r = simplify(t, false); + r = simplify_arg(t); } else if (m.is_false(new_c) || !assert_expr(new_c, false)) { - r = simplify(e, false); + r = simplify_arg(e); } else { for (expr * child : tree(ite)) { if (is_subexpr(child, t) && !is_subexpr(child, e)) { - simplify(child, true); + simplify_rec(child); } } pop(scope_level() - old_lvl); - expr_ref new_t = simplify(t, false); + expr_ref new_t = simplify_arg(t); if (!assert_expr(new_c, true)) { return new_t; } for (expr * child : tree(ite)) { if (is_subexpr(child, e) && !is_subexpr(child, t)) { - simplify(child, true); + simplify_rec(child); } } pop(scope_level() - old_lvl); - expr_ref new_e = simplify(e, false); + expr_ref new_e = simplify_arg(e); if (c == new_c && t == new_t && e == new_e) { r = ite; } @@ -249,7 +249,15 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { return r; } -expr_ref dom_simplify_tactic::simplify(expr * e0, bool cache_result) { +expr_ref dom_simplify_tactic::simplify_arg(expr * e) { + expr_ref r(m); + r = get_cached(e); + (*m_simplifier)(r); + TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e, m) << " -> " << r << "\n";); + return r; +} + +expr_ref dom_simplify_tactic::simplify_rec(expr * e0) { expr_ref r(m); expr* e = 0; @@ -273,14 +281,12 @@ expr_ref dom_simplify_tactic::simplify(expr * e0, bool cache_result) { } else { for (expr * child : tree(e)) { - simplify(child, true); + simplify_rec(child); } if (is_app(e)) { m_args.reset(); for (expr* arg : *to_app(e)) { - r = get_cached(arg); - (*m_simplifier)(r); - m_args.push_back(r); + m_args.push_back(simplify_arg(arg)); } r = m.mk_app(to_app(e)->get_decl(), m_args.size(), m_args.c_ptr()); } @@ -289,7 +295,7 @@ expr_ref dom_simplify_tactic::simplify(expr * e0, bool cache_result) { } } (*m_simplifier)(r); - if (cache_result) cache(e0, r); + cache(e0, r); TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e0, m) << " -> " << r << "\n";); --m_depth; m_subexpr_cache.reset(); @@ -316,10 +322,10 @@ expr_ref dom_simplify_tactic::simplify_and_or(bool is_and, app * e) { #define _SIMP_ARG(arg) \ for (expr * child : tree(arg)) { \ if (is_subexpr_arg(child, arg)) { \ - simplify(child, true); \ + simplify_rec(child); \ } \ } \ - r = simplify(arg, false); \ + r = simplify_arg(arg); \ args.push_back(r); \ if (!assert_expr(r, !is_and)) { \ r = is_and ? m.mk_false() : m.mk_true(); \ @@ -365,7 +371,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { if (!init(g)) return; unsigned sz = g.size(); for (unsigned i = 0; !g.inconsistent() && i < sz; ++i) { - expr_ref r = simplify(g.form(i), true); + expr_ref r = simplify_rec(g.form(i)); if (i < sz - 1 && !m.is_true(r) && !m.is_false(r) && !g.dep(i) && !g.proofs_enabled() && !assert_expr(r, false)) { r = m.mk_false(); } @@ -385,7 +391,7 @@ void dom_simplify_tactic::simplify_goal(goal& g) { sz = g.size(); for (unsigned i = sz; !g.inconsistent() && i > 0; ) { --i; - expr_ref r = simplify(g.form(i), true); + expr_ref r = simplify_rec(g.form(i)); if (i > 0 && !m.is_true(r) && !m.is_false(r) && !g.dep(i) && !g.proofs_enabled() && !assert_expr(r, false)) { r = m.mk_false(); } diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index e79777215..4f9851514 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -99,7 +99,8 @@ class dom_simplify_tactic : public tactic { obj_pair_map m_subexpr_cache; bool m_forward; - expr_ref simplify(expr* t, bool cache); + expr_ref simplify_rec(expr* t); + expr_ref simplify_arg(expr* t); expr_ref simplify_ite(app * ite); expr_ref simplify_and(app * ite) { return simplify_and_or(true, ite); } expr_ref simplify_or(app * ite) { return simplify_and_or(false, ite); } From deba7d4d6e74c2896b2f75aeeacc205618157f05 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 7 Oct 2017 14:35:44 +0100 Subject: [PATCH 359/488] use idom for checking dominator relationships Signed-off-by: Nikolaj Bjorner --- src/tactic/core/dom_simplify_tactic.cpp | 24 ++++++++++++++++-------- src/tactic/core/dom_simplify_tactic.h | 2 ++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 366e1edb0..3a6d55569 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -257,11 +257,14 @@ expr_ref dom_simplify_tactic::simplify_arg(expr * e) { return r; } +/** + \brief simplify e recursively. +*/ expr_ref dom_simplify_tactic::simplify_rec(expr * e0) { expr_ref r(m); expr* e = 0; - TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e0, m) << " -> " << r << "\n";); + TRACE("simplify", tout << "depth: " << m_depth << " " << mk_pp(e0, m) << "\n";); if (!m_result.find(e0, e)) { e = e0; } @@ -408,6 +411,12 @@ void dom_simplify_tactic::simplify_goal(goal& g) { SASSERT(scope_level() == 0); } +/** + \brief determine if a is dominated by b. + Walk the immediate dominators of a upwards until hitting b or a term that is deeper than b. + Save intermediary results in a cache to avoid recomputations. +*/ + bool dom_simplify_tactic::is_subexpr(expr * a, expr * b) { if (a == b) return true; @@ -416,14 +425,13 @@ bool dom_simplify_tactic::is_subexpr(expr * a, expr * b) { if (m_subexpr_cache.find(a, b, r)) return r; - for (expr * e : tree(b)) { - if (is_subexpr(a, e)) { - m_subexpr_cache.insert(a, b, true); - return true; - } + if (get_depth(a) >= get_depth(b)) { + return false; } - m_subexpr_cache.insert(a, b, false); - return false; + SASSERT(a != idom(a) && get_depth(idom(a)) > get_depth(a)); + r = is_subexpr(idom(a), b); + m_subexpr_cache.insert(a, b, r); + return r; } ptr_vector const & dom_simplify_tactic::tree(expr * e) { diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 4f9851514..79bc9728c 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -57,6 +57,7 @@ public: bool compile(unsigned sz, expr * const* es); tree_t const& get_tree() { return m_tree; } void reset(); + expr* idom(expr *e) const { return m_doms[e]; } std::ostream& display(std::ostream& out); }; @@ -113,6 +114,7 @@ class dom_simplify_tactic : public tactic { void cache(expr *t, expr* r) { m_result.insert(t, r); m_trail.push_back(r); } ptr_vector const & tree(expr * e); + expr* idom(expr *e) const { return m_dominators.idom(e); } unsigned scope_level() { return m_scope_level; } void pop(unsigned n) { SASSERT(n <= m_scope_level); m_scope_level -= n; m_simplifier->pop(n); } From a5ecf87ab82c86b01eef01646b70fdcbb30b1f5d Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 10:32:38 +0100 Subject: [PATCH 360/488] fix #1288 Signed-off-by: Nikolaj Bjorner --- src/muz/rel/tbv.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/muz/rel/tbv.cpp b/src/muz/rel/tbv.cpp index 7475750db..69cc4819a 100644 --- a/src/muz/rel/tbv.cpp +++ b/src/muz/rel/tbv.cpp @@ -74,8 +74,7 @@ tbv* tbv_manager::allocate(tbv const& bv) { } tbv* tbv_manager::allocate(uint64 val) { tbv* v = allocate0(); - for (unsigned bit = num_tbits(); bit > 0;) { - --bit; + for (unsigned bit = std::min(64u, num_tbits()); bit-- > 0;) { if (val & (1ULL << bit)) { set(*v, bit, BIT_1); } else { From 6f7f957a266d8a22f628aaee29303ac650529f73 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 10:38:02 +0100 Subject: [PATCH 361/488] likely fix for #1287 Signed-off-by: Nikolaj Bjorner --- src/api/c++/z3++.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 8938fb1b5..41f3f0e06 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -140,7 +140,7 @@ namespace z3 { class context { bool m_enable_exceptions; Z3_context m_ctx; - static void error_handler(Z3_context /*c*/, Z3_error_code /*e*/) { /* do nothing */ } + static void __cdecl error_handler(Z3_context /*c*/, Z3_error_code /*e*/) { /* do nothing */ } void init(config & c) { m_ctx = Z3_mk_context_rc(c); m_enable_exceptions = true; From c72b3356c16778fe21223f374f7679c1c0664e65 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 10:41:02 +0100 Subject: [PATCH 362/488] fix #1286 Signed-off-by: Nikolaj Bjorner --- src/interp/iz3mgr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interp/iz3mgr.h b/src/interp/iz3mgr.h index 6ca8fae34..e4c294059 100755 --- a/src/interp/iz3mgr.h +++ b/src/interp/iz3mgr.h @@ -96,7 +96,7 @@ class ast_r : public ast_i { ast_r(const ast_r &other) : ast_i(other) { _m = other._m; - _m->inc_ref(_ast); + if (_m) _m->inc_ref(_ast); } ast_r &operator=(const ast_r &other) { @@ -104,7 +104,7 @@ class ast_r : public ast_i { _m->dec_ref(_ast); _ast = other._ast; _m = other._m; - _m->inc_ref(_ast); + if (_m) _m->inc_ref(_ast); return *this; } From 52217f0600aaa2b2961f971d8648b8e3c7bf4f2f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 10:56:05 +0100 Subject: [PATCH 363/488] fix #1290 Signed-off-by: Nikolaj Bjorner --- src/model/model_core.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index f94558097..4290700d4 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -86,18 +86,18 @@ void model_core::register_decl(func_decl * d, func_interp * fi) { void model_core::unregister_decl(func_decl * d) { decl2expr::obj_map_entry * ec = m_interp.find_core(d); if (ec && ec->get_data().m_value != 0) { - m_manager.dec_ref(ec->get_data().m_key); - m_manager.dec_ref(ec->get_data().m_value); m_interp.remove(d); m_const_decls.erase(d); + m_manager.dec_ref(ec->get_data().m_key); + m_manager.dec_ref(ec->get_data().m_value); return; } decl2finterp::obj_map_entry * ef = m_finterp.find_core(d); if (ef && ef->get_data().m_value != 0) { - m_manager.dec_ref(ef->get_data().m_key); - dealloc(ef->get_data().m_value); m_finterp.remove(d); m_func_decls.erase(d); + m_manager.dec_ref(ef->get_data().m_key); + dealloc(ef->get_data().m_value); } } From 1371caace28097b8d86ba4cd47be22492d419784 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 11:05:57 +0100 Subject: [PATCH 364/488] fix #1287, again Signed-off-by: Nikolaj Bjorner --- src/api/c++/z3++.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 41f3f0e06..2200874d3 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -140,7 +140,7 @@ namespace z3 { class context { bool m_enable_exceptions; Z3_context m_ctx; - static void __cdecl error_handler(Z3_context /*c*/, Z3_error_code /*e*/) { /* do nothing */ } + static void Z3_API error_handler(Z3_context /*c*/, Z3_error_code /*e*/) { /* do nothing */ } void init(config & c) { m_ctx = Z3_mk_context_rc(c); m_enable_exceptions = true; From 22fa108ffd91834eb5b4a98a3e14434750b7b8f5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 11:07:22 +0100 Subject: [PATCH 365/488] fix #1288, again Signed-off-by: Nikolaj Bjorner --- src/muz/rel/tbv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muz/rel/tbv.cpp b/src/muz/rel/tbv.cpp index 69cc4819a..5ef15303e 100644 --- a/src/muz/rel/tbv.cpp +++ b/src/muz/rel/tbv.cpp @@ -74,7 +74,7 @@ tbv* tbv_manager::allocate(tbv const& bv) { } tbv* tbv_manager::allocate(uint64 val) { tbv* v = allocate0(); - for (unsigned bit = std::min(64u, num_tbits()); bit-- > 0;) { + for (unsigned bit = std::min(63u, num_tbits()); bit-- > 0;) { if (val & (1ULL << bit)) { set(*v, bit, BIT_1); } else { From 06d75a616f6246eaa717ca34bb2719726d6858d7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 11:40:17 +0100 Subject: [PATCH 366/488] fix #1288, again Signed-off-by: Nikolaj Bjorner --- src/muz/rel/tbv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muz/rel/tbv.cpp b/src/muz/rel/tbv.cpp index 5ef15303e..69cc4819a 100644 --- a/src/muz/rel/tbv.cpp +++ b/src/muz/rel/tbv.cpp @@ -74,7 +74,7 @@ tbv* tbv_manager::allocate(tbv const& bv) { } tbv* tbv_manager::allocate(uint64 val) { tbv* v = allocate0(); - for (unsigned bit = std::min(63u, num_tbits()); bit-- > 0;) { + for (unsigned bit = std::min(64u, num_tbits()); bit-- > 0;) { if (val & (1ULL << bit)) { set(*v, bit, BIT_1); } else { From d2ec927844120a4c26236e80b9bd8ae302de51f3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 12:34:08 +0100 Subject: [PATCH 367/488] fix build break Signed-off-by: Nikolaj Bjorner --- src/model/model_core.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/model/model_core.cpp b/src/model/model_core.cpp index 4290700d4..833c254c3 100644 --- a/src/model/model_core.cpp +++ b/src/model/model_core.cpp @@ -86,18 +86,22 @@ void model_core::register_decl(func_decl * d, func_interp * fi) { void model_core::unregister_decl(func_decl * d) { decl2expr::obj_map_entry * ec = m_interp.find_core(d); if (ec && ec->get_data().m_value != 0) { + auto k = ec->get_data().m_key; + auto v = ec->get_data().m_value; m_interp.remove(d); m_const_decls.erase(d); - m_manager.dec_ref(ec->get_data().m_key); - m_manager.dec_ref(ec->get_data().m_value); + m_manager.dec_ref(k); + m_manager.dec_ref(v); return; } decl2finterp::obj_map_entry * ef = m_finterp.find_core(d); if (ef && ef->get_data().m_value != 0) { + auto k = ef->get_data().m_key; + auto v = ef->get_data().m_value; m_finterp.remove(d); m_func_decls.erase(d); - m_manager.dec_ref(ef->get_data().m_key); - dealloc(ef->get_data().m_value); + m_manager.dec_ref(k); + dealloc(v); } } From f359f238851d8c1a5db11a95d4ded3639813db9a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 8 Oct 2017 15:47:06 -0700 Subject: [PATCH 368/488] another fix for #1288 Signed-off-by: Nikolaj Bjorner --- src/util/mpz.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/util/mpz.cpp b/src/util/mpz.cpp index 9569ac280..7cf87b24b 100644 --- a/src/util/mpz.cpp +++ b/src/util/mpz.cpp @@ -558,14 +558,13 @@ void mpz_manager::big_rem(mpz const & a, mpz const & b, mpz & c) { template void mpz_manager::gcd(mpz const & a, mpz const & b, mpz & c) { - if (is_small(a) && is_small(b)) { + COMPILE_TIME_ASSERT(sizeof(a.m_val) == sizeof(int)); + if (is_small(a) && is_small(b) && a.m_val != INT_MIN && b.m_val != INT_MIN) { int _a = a.m_val; int _b = b.m_val; if (_a < 0) _a = -_a; if (_b < 0) _b = -_b; unsigned r = u_gcd(_a, _b); - // Remark: r is (INT_MAX + 1) - // If a == b == INT_MIN set(c, r); } else { From 5819e386064e51037e1d748fd842ad2a656e17ff Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 9 Oct 2017 19:17:44 +0100 Subject: [PATCH 369/488] whitespace --- src/smt/asserted_formulas.cpp | 90 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 11cc846b8..2c9d1c668 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -38,7 +38,7 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m_qhead(0), m_macro_manager(m), m_bv_sharing(m), - m_inconsistent(false), + m_inconsistent(false), m_has_quantifiers(false), m_reduce_asserted_formulas(*this), m_distribute_forall(*this), @@ -54,8 +54,8 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m_lift_ite(*this), m_ng_lift_ite(*this), m_find_macros(*this), - m_propagate_values(*this), - m_nnf_cnf(*this), + m_propagate_values(*this), + m_nnf_cnf(*this), m_apply_quasi_macros(*this) { m_macro_finder = alloc(macro_finder, m, m_macro_manager); @@ -68,7 +68,7 @@ asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): void asserted_formulas::setup() { switch (m_params.m_lift_ite) { case LI_FULL: - m_params.m_ng_lift_ite = LI_NONE; + m_params.m_ng_lift_ite = LI_NONE; break; case LI_CONSERVATIVE: if (m_params.m_ng_lift_ite == LI_CONSERVATIVE) @@ -77,7 +77,7 @@ void asserted_formulas::setup() { default: break; } - + if (m_params.m_relevancy_lvl == 0) m_params.m_relevancy_lemma = false; } @@ -93,7 +93,7 @@ void asserted_formulas::push_assertion(expr * e, proof * pr, vectorget_arg(i); proof_ref _pr(m.mk_not_or_elim(pr, i), m); expr_ref narg(mk_not(m, arg), m); - push_assertion(narg, _pr, result); - } + push_assertion(narg, _pr, result); + } } else { result.push_back(justified_expr(m, e, pr)); @@ -139,7 +139,7 @@ void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { proof_ref in_pr(_in_pr, m), pr(_in_pr, m); expr_ref r(e, m); - if (inconsistent()) + if (inconsistent()) return; m_has_quantifiers |= ::has_quantifiers(e); @@ -183,7 +183,7 @@ void asserted_formulas::push_scope() { commit(); TRACE("asserted_formulas_scopes", tout << "after push: " << m_scopes.size() << "\n";); } - + void asserted_formulas::pop_scope(unsigned num_scopes) { TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << " of " << m_scopes.size() << "\n";); m_bv_sharing.pop_scope(num_scopes); @@ -212,7 +212,7 @@ void asserted_formulas::reset() { bool asserted_formulas::check_well_sorted() const { for (justified_expr const& je : m_formulas) { - if (!is_well_sorted(m, je.get_fml())) return false; + if (!is_well_sorted(m, je.get_fml())) return false; } return true; } @@ -224,20 +224,20 @@ void asserted_formulas::reduce() { return; if (m_qhead == m_formulas.size()) return; - if (!m_params.m_preprocess) - return; - if (m_macro_manager.has_macros()) + if (!m_params.m_preprocess) + return; + if (m_macro_manager.has_macros()) invoke(m_find_macros); - + TRACE("before_reduce", display(tout);); CASSERT("well_sorted", check_well_sorted()); - + set_eliminate_and(false); // do not eliminate and before nnf. if (!invoke(m_propagate_values)) return; if (!invoke(m_find_macros)) return; if (!invoke(m_nnf_cnf)) return; set_eliminate_and(true); - if (!invoke(m_reduce_asserted_formulas)) return; + if (!invoke(m_reduce_asserted_formulas)) return; if (!invoke(m_pull_cheap_ite_trees)) return; if (!invoke(m_pull_nested_quantifiers)) return; if (!invoke(m_lift_ite)) return; @@ -276,14 +276,14 @@ bool asserted_formulas::invoke(simplify_fmls& s) { if (!s.should_apply()) return true; IF_VERBOSE(10, verbose_stream() << "(smt." << s.id() << ")\n";); s(); - IF_VERBOSE(10000, verbose_stream() << "total size: " << get_total_size() << "\n";); - TRACE("reduce_step_ll", ast_mark visited; display_ll(tout, visited);); - CASSERT("well_sorted",check_well_sorted()); - if (inconsistent() || canceled()) { - TRACE("after_reduce", display(tout);); - TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); + IF_VERBOSE(10000, verbose_stream() << "total size: " << get_total_size() << "\n";); + TRACE("reduce_step_ll", ast_mark visited; display_ll(tout, visited);); + CASSERT("well_sorted",check_well_sorted()); + if (inconsistent() || canceled()) { + TRACE("after_reduce", display(tout);); + TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); return false; - } + } else { return true; } @@ -301,10 +301,10 @@ void asserted_formulas::display(std::ostream & out) const { void asserted_formulas::display_ll(std::ostream & out, ast_mark & pp_visited) const { if (!m_formulas.empty()) { - for (justified_expr const& f : m_formulas) + for (justified_expr const& f : m_formulas) ast_def_ll_pp(out, m, f.get_fml(), pp_visited, true, false); out << "asserted formulas:\n"; - for (justified_expr const& f : m_formulas) + for (justified_expr const& f : m_formulas) out << "#" << f.get_fml()->get_id() << " "; out << "\n"; } @@ -332,9 +332,9 @@ void asserted_formulas::find_macros_core() { void asserted_formulas::apply_quasi_macros() { TRACE("before_quasi_macros", display(tout);); vector new_fmls; - quasi_macros proc(m, m_macro_manager); - while (proc(m_formulas.size() - m_qhead, - m_formulas.c_ptr() + m_qhead, + quasi_macros proc(m, m_macro_manager); + while (proc(m_formulas.size() - m_qhead, + m_formulas.c_ptr() + m_qhead, new_fmls)) { swap_asserted_formulas(new_fmls); new_fmls.reset(); @@ -348,7 +348,7 @@ void asserted_formulas::nnf_cnf() { vector new_fmls; expr_ref_vector push_todo(m); proof_ref_vector push_todo_prs(m); - + unsigned i = m_qhead; unsigned sz = m_formulas.size(); TRACE("nnf_bug", tout << "i: " << i << " sz: " << sz << "\n";); @@ -378,7 +378,7 @@ void asserted_formulas::nnf_cnf() { CASSERT("well_sorted",is_well_sorted(m, r1)); if (canceled()) { return; - } + } if (m.proofs_enabled()) pr = m.mk_modus_ponens(push_todo_prs.get(k), pr1); push_assertion(r1, pr, new_fmls); @@ -389,8 +389,8 @@ void asserted_formulas::nnf_cnf() { void asserted_formulas::simplify_fmls::operator()() { vector new_fmls; - unsigned sz = af.m_formulas.size(); - for (unsigned i = af.m_qhead; i < sz; i++) { + unsigned sz = af.m_formulas.size(); + for (unsigned i = af.m_qhead; i < sz; i++) { auto& j = af.m_formulas[i]; expr_ref result(m); proof_ref result_pr(m); @@ -406,8 +406,8 @@ void asserted_formulas::simplify_fmls::operator()() { af.push_assertion(result, result_pr, new_fmls); } if (af.canceled()) return; - } - af.swap_asserted_formulas(new_fmls); + } + af.swap_asserted_formulas(new_fmls); TRACE("asserted_formulas", af.display(tout);); post_op(); } @@ -473,12 +473,12 @@ void asserted_formulas::propagate_values() { unsigned asserted_formulas::propagate_values(unsigned i) { expr_ref n(m_formulas[i].get_fml(), m); - expr_ref new_n(m); - proof_ref new_pr(m); - m_rewriter(n, new_n, new_pr); - if (m.proofs_enabled()) { + expr_ref new_n(m); + proof_ref new_pr(m); + m_rewriter(n, new_n, new_pr); + if (m.proofs_enabled()) { proof * pr = m_formulas[i].get_proof(); - new_pr = m.mk_modus_ponens(pr, new_pr); + new_pr = m.mk_modus_ponens(pr, new_pr); } justified_expr j(m, new_n, new_pr); m_formulas[i] = j; @@ -510,10 +510,10 @@ void asserted_formulas::update_substitution(expr* n, proof* pr) { TRACE("propagate_values", tout << "incompatible " << mk_pp(n, m) << "\n";); } if (m.is_not(n, n1)) { - m_scoped_substitution.insert(n1, m.mk_false(), m.mk_iff_false(pr)); + m_scoped_substitution.insert(n1, m.mk_false(), m.mk_iff_false(pr)); } else { - m_scoped_substitution.insert(n, m.mk_true(), m.mk_iff_true(pr)); + m_scoped_substitution.insert(n, m.mk_true(), m.mk_iff_true(pr)); } } @@ -554,13 +554,13 @@ bool asserted_formulas::is_gt(expr* lhs, expr* rhs) { } UNREACHABLE(); } - + return false; } void asserted_formulas::compute_depth(expr* e) { ptr_vector todo; - todo.push_back(e); + todo.push_back(e); while (!todo.empty()) { e = todo.back(); unsigned d = 0; @@ -603,7 +603,7 @@ proof * asserted_formulas::get_inconsistency_proof() const { return 0; } -void asserted_formulas::refine_inj_axiom_fn::simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { +void asserted_formulas::refine_inj_axiom_fn::simplify(justified_expr const& j, expr_ref& n, proof_ref& p) { expr* f = j.get_fml(); if (is_quantifier(f) && simplify_inj_axiom(m, to_quantifier(f), n)) { TRACE("inj_axiom", tout << "simplifying...\n" << mk_pp(f, m) << "\n" << n << "\n";); From 800fa3d246a93c0e3dba3bfe18e8ea49fce2b203 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 9 Oct 2017 19:18:41 +0100 Subject: [PATCH 370/488] Added bv_sort_ac=true to asserted_formulas::m_rewriter --- src/smt/asserted_formulas.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 2c9d1c668..1ed5f2fe1 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -130,6 +130,7 @@ void asserted_formulas::set_eliminate_and(bool flag) { p.set_bool("eq2ineq", m_params.m_arith_eq2ineq); p.set_bool("gcd_rounding", true); p.set_bool("expand_select_store", true); + p.set_bool("bv_sort_ac", true); m_rewriter.updt_params(p); flush_cache(); } @@ -142,8 +143,6 @@ void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { if (inconsistent()) return; - m_has_quantifiers |= ::has_quantifiers(e); - if (m_params.m_preprocess) { TRACE("assert_expr_bug", tout << r << "\n";); set_eliminate_and(false); // do not eliminate and before nnf. @@ -156,6 +155,9 @@ void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { } TRACE("assert_expr_bug", tout << "after...\n" << r << "\n";); } + + m_has_quantifiers |= ::has_quantifiers(e); + push_assertion(r, pr, m_formulas); TRACE("asserted_formulas_bug", tout << "after assert_expr\n"; display(tout);); } From cae414e575299d976899b764041195ff36f484e9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 9 Oct 2017 13:59:44 -0700 Subject: [PATCH 371/488] fixes for #1296, removing COMPILE_TIME_ASSERT Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/maximize_ac_sharing.cpp | 5 +++-- src/sat/sat_watched.h | 8 ++++---- src/smt/smt_theory_var_list.h | 4 ++-- src/util/approx_set.h | 4 ++-- src/util/bit_vector.h | 2 +- src/util/debug.h | 1 - src/util/double_manager.h | 2 +- src/util/mpf.cpp | 6 +++--- src/util/mpff.cpp | 4 ++-- src/util/mpn.cpp | 2 +- src/util/mpz.cpp | 10 +++++----- src/util/uint_set.h | 1 - src/util/util.h | 6 +++--- 13 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/ast/rewriter/maximize_ac_sharing.cpp b/src/ast/rewriter/maximize_ac_sharing.cpp index d7e8df7a2..a838f59fa 100644 --- a/src/ast/rewriter/maximize_ac_sharing.cpp +++ b/src/ast/rewriter/maximize_ac_sharing.cpp @@ -54,13 +54,13 @@ br_status maximize_ac_sharing::reduce_app(func_decl * f, unsigned num_args, expr TRACE("ac_sharing_detail", tout << "args: "; for (unsigned i = 0; i < num_args; i++) tout << mk_pp(_args[i], m) << "\n";); try_to_reuse: if (num_args > 1 && num_args < MAX_NUM_ARGS_FOR_OPT) { - for (unsigned i = 0; i < num_args - 1; i++) { + for (unsigned i = 0; i + 1 < num_args; i++) { for (unsigned j = i + 1; j < num_args; j++) { if (contains(f, _args[i], _args[j])) { TRACE("ac_sharing_detail", tout << "reusing args: " << i << " " << j << "\n";); _args[i] = m.mk_app(f, _args[i], _args[j]); SASSERT(num_args > 1); - for (unsigned w = j; w < num_args - 1; w++) { + for (unsigned w = j; w + 1 < num_args; w++) { _args[w] = _args[w+1]; } num_args--; @@ -144,6 +144,7 @@ void maximize_ac_sharing::restore_entries(unsigned old_lim) { while (i != old_lim) { --i; entry * e = m_entries[i]; + m_cache.remove(e); m.dec_ref(e->m_arg1); m.dec_ref(e->m_arg2); } diff --git a/src/sat/sat_watched.h b/src/sat/sat_watched.h index e5a02953b..639d3e6a8 100644 --- a/src/sat/sat_watched.h +++ b/src/sat/sat_watched.h @@ -109,10 +109,10 @@ namespace sat { bool operator!=(watched const & w) const { return !operator==(w); } }; - COMPILE_TIME_ASSERT(0 <= watched::BINARY && watched::BINARY <= 3); - COMPILE_TIME_ASSERT(0 <= watched::TERNARY && watched::TERNARY <= 3); - COMPILE_TIME_ASSERT(0 <= watched::CLAUSE && watched::CLAUSE <= 3); - COMPILE_TIME_ASSERT(0 <= watched::EXT_CONSTRAINT && watched::EXT_CONSTRAINT <= 3); + static_assert(0 <= watched::BINARY && watched::BINARY <= 3, ""); + static_assert(0 <= watched::TERNARY && watched::TERNARY <= 3, ""); + static_assert(0 <= watched::CLAUSE && watched::CLAUSE <= 3, ""); + static_assert(0 <= watched::EXT_CONSTRAINT && watched::EXT_CONSTRAINT <= 3, ""); struct watched_lt { bool operator()(watched const & w1, watched const & w2) const { diff --git a/src/smt/smt_theory_var_list.h b/src/smt/smt_theory_var_list.h index d7e246824..aa2816786 100644 --- a/src/smt/smt_theory_var_list.h +++ b/src/smt/smt_theory_var_list.h @@ -67,9 +67,9 @@ namespace smt { }; // 32 bit machine - COMPILE_TIME_ASSERT(sizeof(expr*) != 4 || sizeof(theory_var_list) == sizeof(theory_var_list *) + sizeof(int)); + static_assert(sizeof(expr*) != 4 || sizeof(theory_var_list) == sizeof(theory_var_list *) + sizeof(int), "32 bit"); // 64 bit machine - COMPILE_TIME_ASSERT(sizeof(expr*) != 8 || sizeof(theory_var_list) == sizeof(theory_var_list *) + sizeof(int) + /* a structure must be aligned */ sizeof(int)); + static_assert(sizeof(expr*) != 8 || sizeof(theory_var_list) == sizeof(theory_var_list *) + sizeof(int) + /* a structure must be aligned */ sizeof(int), "64 bit"); }; #endif /* SMT_THEORY_VAR_LIST_H_ */ diff --git a/src/util/approx_set.h b/src/util/approx_set.h index e696d52ee..1cb7ae9f2 100644 --- a/src/util/approx_set.h +++ b/src/util/approx_set.h @@ -29,7 +29,7 @@ public: static const unsigned long long zero = 0ull; static const unsigned long long one = 1ull; }; -COMPILE_TIME_ASSERT(sizeof(unsigned long long) == 8); +static_assert(sizeof(unsigned long long) == 8, ""); template <> class approx_set_traits { public: @@ -37,7 +37,7 @@ public: static const unsigned zero = 0; static const unsigned one = 1; }; -COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); +static_assert(sizeof(unsigned) == 4, "unsigned are 4 bytes"); template class approx_set_tpl : private T2U_Proc { diff --git a/src/util/bit_vector.h b/src/util/bit_vector.h index 6a254e399..2d42e35a2 100644 --- a/src/util/bit_vector.h +++ b/src/util/bit_vector.h @@ -24,7 +24,7 @@ Revision History: #include "util/vector.h" #include "util/memory_manager.h" -COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); +static_assert(sizeof(unsigned) == 4, "unsigned are 4 bytes"); #define BV_DEFAULT_CAPACITY 2 class bit_vector { diff --git a/src/util/debug.h b/src/util/debug.h index e0ceb9a64..536df4588 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -90,7 +90,6 @@ bool is_debug_enabled(const char * tag); exit(-1); \ } -#define COMPILE_TIME_ASSERT(expr) static_assert(expr, "") void finalize_debug(); /* diff --git a/src/util/double_manager.h b/src/util/double_manager.h index 33cccf2af..7532a3b8b 100644 --- a/src/util/double_manager.h +++ b/src/util/double_manager.h @@ -97,7 +97,7 @@ public: } }; -COMPILE_TIME_ASSERT(sizeof(uint64) == sizeof(double)); +static_assert(sizeof(uint64) == sizeof(double), ""); #endif /* DOUBLE_MANAGER_H_ */ diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 5e7233110..3218419a9 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -73,7 +73,7 @@ mpf_manager::~mpf_manager() { } void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, int value) { - COMPILE_TIME_ASSERT(sizeof(int) == 4); + static_assert(sizeof(int) == 4, "assume integers are 4 bytes"); o.sign = false; o.ebits = ebits; @@ -119,7 +119,7 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, double value) { // double === mpf(11, 53) - COMPILE_TIME_ASSERT(sizeof(double) == 8); + static_assert(sizeof(double) == 8, "doubles are 8 bytes"); uint64 raw; memcpy(&raw, &value, sizeof(double)); @@ -155,7 +155,7 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, double value) { void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, float value) { // single === mpf(8, 24) - COMPILE_TIME_ASSERT(sizeof(float) == 4); + static_assert(sizeof(float) == 4, "floats are 4 bytes"); unsigned int raw; memcpy(&raw, &value, sizeof(float)); diff --git a/src/util/mpff.cpp b/src/util/mpff.cpp index 459b0691c..eac9cc80c 100644 --- a/src/util/mpff.cpp +++ b/src/util/mpff.cpp @@ -27,8 +27,8 @@ Revision History: #include "util/bit_util.h" #include "util/trace.h" -COMPILE_TIME_ASSERT(sizeof(mpn_digit) == sizeof(unsigned)); -COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); +static_assert(sizeof(mpn_digit) == sizeof(unsigned), ""); +static_assert(sizeof(unsigned) == 4, "unsigned haven't changed size for a while"); // MIN_MSW is an shorthand for 0x8000..00, i.e., the minimal most significand word. #define MIN_MSW (1u << (sizeof(unsigned) * 8 - 1)) diff --git a/src/util/mpn.cpp b/src/util/mpn.cpp index 65223133f..2059ea6fd 100644 --- a/src/util/mpn.cpp +++ b/src/util/mpn.cpp @@ -24,7 +24,7 @@ Revision History: #define max(a,b) (((a) > (b)) ? (a) : (b)) typedef uint64 mpn_double_digit; -COMPILE_TIME_ASSERT(sizeof(mpn_double_digit) == 2 * sizeof(mpn_digit)); +static_assert(sizeof(mpn_double_digit) == 2 * sizeof(mpn_digit), "size alignment"); const mpn_digit mpn_manager::zero = 0; diff --git a/src/util/mpz.cpp b/src/util/mpz.cpp index 7cf87b24b..7ad472ef1 100644 --- a/src/util/mpz.cpp +++ b/src/util/mpz.cpp @@ -558,7 +558,7 @@ void mpz_manager::big_rem(mpz const & a, mpz const & b, mpz & c) { template void mpz_manager::gcd(mpz const & a, mpz const & b, mpz & c) { - COMPILE_TIME_ASSERT(sizeof(a.m_val) == sizeof(int)); + static_assert(sizeof(a.m_val) == sizeof(int), "size mismatch"); if (is_small(a) && is_small(b) && a.m_val != INT_MIN && b.m_val != INT_MIN) { int _a = a.m_val; int _b = b.m_val; @@ -724,7 +724,7 @@ void mpz_manager::gcd(mpz const & a, mpz const & b, mpz & c) { #ifdef LEHMER_GCD // For now, it only works if sizeof(digit_t) == sizeof(unsigned) - COMPILE_TIME_ASSERT(sizeof(digit_t) == sizeof(unsigned)); + static_assert(sizeof(digit_t) == sizeof(unsigned), ""); int64 a_hat, b_hat, A, B, C, D, T, q, a_sz, b_sz; mpz a1, b1, t, r, tmp; @@ -1754,7 +1754,7 @@ void mpz_manager::mul2k(mpz & a, unsigned k) { } #ifndef _MP_GMP -COMPILE_TIME_ASSERT(sizeof(digit_t) == 4 || sizeof(digit_t) == 8); +static_assert(sizeof(digit_t) == 4 || sizeof(digit_t) == 8, ""); #endif template @@ -1821,7 +1821,7 @@ unsigned mpz_manager::log2(mpz const & a) { if (is_small(a)) return ::log2((unsigned)a.m_val); #ifndef _MP_GMP - COMPILE_TIME_ASSERT(sizeof(digit_t) == 8 || sizeof(digit_t) == 4); + static_assert(sizeof(digit_t) == 8 || sizeof(digit_t) == 4, ""); mpz_cell * c = a.m_ptr; unsigned sz = c->m_size; digit_t * ds = c->m_digits; @@ -1843,7 +1843,7 @@ unsigned mpz_manager::mlog2(mpz const & a) { if (is_small(a)) return ::log2((unsigned)-a.m_val); #ifndef _MP_GMP - COMPILE_TIME_ASSERT(sizeof(digit_t) == 8 || sizeof(digit_t) == 4); + static_assert(sizeof(digit_t) == 8 || sizeof(digit_t) == 4, ""); mpz_cell * c = a.m_ptr; unsigned sz = c->m_size; digit_t * ds = c->m_digits; diff --git a/src/util/uint_set.h b/src/util/uint_set.h index 33c39eeb2..352189ef1 100644 --- a/src/util/uint_set.h +++ b/src/util/uint_set.h @@ -22,7 +22,6 @@ Revision History: #include "util/util.h" #include "util/vector.h" -COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); class uint_set : unsigned_vector { diff --git a/src/util/util.h b/src/util/util.h index 23c2c1657..1f753099c 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -33,13 +33,13 @@ Revision History: typedef unsigned long long uint64; #endif -COMPILE_TIME_ASSERT(sizeof(uint64) == 8); +static_assert(sizeof(uint64) == 8, "64 bits please"); #ifndef int64 typedef long long int64; #endif -COMPILE_TIME_ASSERT(sizeof(int64) == 8); +static_assert(sizeof(int64) == 8, "64 bits"); #ifndef INT64_MIN #define INT64_MIN static_cast(0x8000000000000000ull) @@ -111,7 +111,7 @@ inline unsigned next_power_of_two(unsigned v) { unsigned log2(unsigned v); unsigned uint64_log2(uint64 v); -COMPILE_TIME_ASSERT(sizeof(unsigned) == 4); +static_assert(sizeof(unsigned) == 4, "unsigned are 32 bits"); // Return the number of 1 bits in v. static inline unsigned get_num_1bits(unsigned v) { From 7f693186a0c0ca9cc0d15ff3fd8fbc1734e95ee1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 10 Oct 2017 07:10:04 -0700 Subject: [PATCH 372/488] trying to address leak reported in #1297 Signed-off-by: Nikolaj Bjorner --- src/api/api_parsers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/api/api_parsers.cpp b/src/api/api_parsers.cpp index bef31e9f1..7a68efbd8 100644 --- a/src/api/api_parsers.cpp +++ b/src/api/api_parsers.cpp @@ -69,6 +69,7 @@ extern "C" { ok = false; } mk_c(c)->m_smtlib_error_buffer = outs.str(); + outs.clear(); if (!ok) { mk_c(c)->reset_parser(); SET_ERROR_CODE(Z3_PARSER_ERROR); @@ -98,6 +99,7 @@ extern "C" { ok = false; } mk_c(c)->m_smtlib_error_buffer = outs.str(); + outs.clear(); if (!ok) { mk_c(c)->reset_parser(); SET_ERROR_CODE(Z3_PARSER_ERROR); From 09ea370ea33f64e54f9cd837cd4e9f66ebe933df Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 10 Oct 2017 12:06:19 -0700 Subject: [PATCH 373/488] update C-example that fails to not use longjumps. Issue #1297 Signed-off-by: Nikolaj Bjorner --- examples/c/test_capi.c | 35 ++++++++++++++++++++++++----------- src/api/api_parsers.cpp | 16 ++++++++-------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 88fdaa1cf..6327ad40f 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -65,6 +65,15 @@ void throw_z3_error(Z3_context c, Z3_error_code e) longjmp(g_catch_buffer, e); } +/** + \brief Error handling that depends on checking an error code on the context. + +*/ + +void nothrow_z3_error(Z3_context c, Z3_error_code e) { + // no-op +} + /** \brief Create a logical context. @@ -1592,18 +1601,16 @@ void error_code_example1() void error_code_example2() { Z3_config cfg; Z3_context ctx = NULL; - int r; + Z3_error_code e; printf("\nerror_code_example2\n"); LOG_MSG("error_code_example2"); - /* low tech try&catch */ - r = setjmp(g_catch_buffer); - if (r == 0) { + if (1) { Z3_ast x, y, app; cfg = Z3_mk_config(); - ctx = mk_context_custom(cfg, throw_z3_error); + ctx = mk_context_custom(cfg, nothrow_z3_error); Z3_del_config(cfg); x = mk_int_var(ctx, "x"); @@ -1611,11 +1618,14 @@ void error_code_example2() { printf("before Z3_mk_iff\n"); /* the next call will produce an error */ app = Z3_mk_iff(ctx, x, y); + e = Z3_get_error_code(ctx); + if (e != Z3_OK) goto err; unreachable(); Z3_del_context(ctx); } else { - printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, (Z3_error_code)r)); + err: + printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, e)); if (ctx != NULL) { Z3_del_context(ctx); } @@ -1781,15 +1791,14 @@ void parser_example5() { Z3_config cfg; Z3_context ctx = NULL; Z3_solver s = NULL; - int r; + Z3_error_code e; printf("\nparser_example5\n"); LOG_MSG("parser_example5"); - r = setjmp(g_catch_buffer); - if (r == 0) { + if (1) { cfg = Z3_mk_config(); - ctx = mk_context_custom(cfg, throw_z3_error); + ctx = mk_context_custom(cfg, nothrow_z3_error); s = mk_solver(ctx); Z3_del_config(cfg); @@ -1798,12 +1807,15 @@ void parser_example5() { "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))", 0, 0, 0, 0, 0, 0); + e = Z3_get_error_code(ctx); + if (e != Z3_OK) goto err; unreachable(); del_solver(ctx, s); Z3_del_context(ctx); } else { - printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, (Z3_error_code)r)); + err: + printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, e)); if (ctx != NULL) { printf("Error message: '%s'.\n",Z3_get_smtlib_error(ctx)); del_solver(ctx, s); @@ -2639,6 +2651,7 @@ void smt2parser_example() { ctx = mk_context(); fs = Z3_parse_smtlib2_string(ctx, "(declare-fun a () (_ BitVec 8)) (assert (bvuge a #x10)) (assert (bvule a #xf0))", 0, 0, 0, 0, 0, 0); printf("formulas: %s\n", Z3_ast_to_string(ctx, fs)); + Z3_del_context(ctx); } diff --git a/src/api/api_parsers.cpp b/src/api/api_parsers.cpp index 7a68efbd8..71fa945d3 100644 --- a/src/api/api_parsers.cpp +++ b/src/api/api_parsers.cpp @@ -56,20 +56,20 @@ extern "C" { Z3_func_decl const decls[]) { Z3_TRY; LOG_Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - std::ostringstream outs; + std::ostringstream* outs = alloc(std::ostringstream); bool ok = false; RESET_ERROR_CODE(); init_smtlib_parser(c, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - mk_c(c)->m_smtlib_parser->set_error_stream(outs); + mk_c(c)->m_smtlib_parser->set_error_stream(*outs); try { ok = mk_c(c)->m_smtlib_parser->parse_string(str); } catch (...) { ok = false; } - mk_c(c)->m_smtlib_error_buffer = outs.str(); - outs.clear(); + mk_c(c)->m_smtlib_error_buffer = outs->str(); + dealloc(outs); if (!ok) { mk_c(c)->reset_parser(); SET_ERROR_CODE(Z3_PARSER_ERROR); @@ -89,17 +89,17 @@ extern "C" { LOG_Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, types, num_decls, decl_names, decls); bool ok = false; RESET_ERROR_CODE(); - std::ostringstream outs; + std::ostringstream* outs = alloc(std::ostringstream); init_smtlib_parser(c, num_sorts, sort_names, types, num_decls, decl_names, decls); - mk_c(c)->m_smtlib_parser->set_error_stream(outs); + mk_c(c)->m_smtlib_parser->set_error_stream(*outs); try { ok = mk_c(c)->m_smtlib_parser->parse_file(file_name); } catch(...) { ok = false; } - mk_c(c)->m_smtlib_error_buffer = outs.str(); - outs.clear(); + mk_c(c)->m_smtlib_error_buffer = outs->str(); + dealloc(outs); if (!ok) { mk_c(c)->reset_parser(); SET_ERROR_CODE(Z3_PARSER_ERROR); From c093e6d4b9c1a9a3d97099fab492e89227fc3715 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 11 Oct 2017 09:53:02 -0700 Subject: [PATCH 374/488] harden a few API methods against longjumps in set_error. Memory leak exposed in #1297 Signed-off-by: Nikolaj Bjorner --- src/api/api_opt.cpp | 16 +++++++--------- src/api/api_parsers.cpp | 25 +++++++++++++------------ src/api/api_quant.cpp | 4 +++- src/api/api_solver.cpp | 3 +++ 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/api/api_opt.cpp b/src/api/api_opt.cpp index a967dfb2b..9f5f7dd5d 100644 --- a/src/api/api_opt.cpp +++ b/src/api/api_opt.cpp @@ -283,15 +283,16 @@ extern "C" { Z3_optimize opt, std::istream& s) { ast_manager& m = mk_c(c)->m(); - cmd_context ctx(false, &m); - install_opt_cmds(ctx, to_optimize_ptr(opt)); - ctx.set_ignore_check(true); - if (!parse_smt2_commands(ctx, s)) { + scoped_ptr ctx = alloc(cmd_context, false, &m); + install_opt_cmds(*ctx.get(), to_optimize_ptr(opt)); + ctx->set_ignore_check(true); + if (!parse_smt2_commands(*ctx.get(), s)) { + ctx = nullptr; SET_ERROR_CODE(Z3_PARSER_ERROR); return; } - ptr_vector::const_iterator it = ctx.begin_assertions(); - ptr_vector::const_iterator end = ctx.end_assertions(); + ptr_vector::const_iterator it = ctx->begin_assertions(); + ptr_vector::const_iterator end = ctx->end_assertions(); for (; it != end; ++it) { to_optimize_ptr(opt)->add_hard_constraint(*it); } @@ -320,9 +321,6 @@ extern "C" { std::ostringstream strm; strm << "Could not open file " << s; throw default_exception(strm.str()); - - SET_ERROR_CODE(Z3_PARSER_ERROR); - return; } Z3_optimize_from_stream(c, d, is); Z3_CATCH; diff --git a/src/api/api_parsers.cpp b/src/api/api_parsers.cpp index 71fa945d3..b3252281b 100644 --- a/src/api/api_parsers.cpp +++ b/src/api/api_parsers.cpp @@ -56,7 +56,7 @@ extern "C" { Z3_func_decl const decls[]) { Z3_TRY; LOG_Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - std::ostringstream* outs = alloc(std::ostringstream); + scoped_ptr outs = alloc(std::ostringstream); bool ok = false; RESET_ERROR_CODE(); @@ -69,7 +69,7 @@ extern "C" { ok = false; } mk_c(c)->m_smtlib_error_buffer = outs->str(); - dealloc(outs); + outs = nullptr; if (!ok) { mk_c(c)->reset_parser(); SET_ERROR_CODE(Z3_PARSER_ERROR); @@ -89,7 +89,7 @@ extern "C" { LOG_Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, types, num_decls, decl_names, decls); bool ok = false; RESET_ERROR_CODE(); - std::ostringstream* outs = alloc(std::ostringstream); + scoped_ptr outs = alloc(std::ostringstream); init_smtlib_parser(c, num_sorts, sort_names, types, num_decls, decl_names, decls); mk_c(c)->m_smtlib_parser->set_error_stream(*outs); try { @@ -99,7 +99,7 @@ extern "C" { ok = false; } mk_c(c)->m_smtlib_error_buffer = outs->str(); - dealloc(outs); + outs = nullptr; if (!ok) { mk_c(c)->reset_parser(); SET_ERROR_CODE(Z3_PARSER_ERROR); @@ -262,21 +262,22 @@ extern "C" { Z3_symbol const decl_names[], Z3_func_decl const decls[]) { Z3_TRY; - cmd_context ctx(false, &(mk_c(c)->m())); - ctx.set_ignore_check(true); + scoped_ptr ctx = alloc(cmd_context, false, &(mk_c(c)->m())); + ctx->set_ignore_check(true); for (unsigned i = 0; i < num_decls; ++i) { - ctx.insert(to_symbol(decl_names[i]), to_func_decl(decls[i])); + ctx->insert(to_symbol(decl_names[i]), to_func_decl(decls[i])); } for (unsigned i = 0; i < num_sorts; ++i) { - psort* ps = ctx.pm().mk_psort_cnst(to_sort(sorts[i])); - ctx.insert(ctx.pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps)); + psort* ps = ctx->pm().mk_psort_cnst(to_sort(sorts[i])); + ctx->insert(ctx->pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps)); } - if (!parse_smt2_commands(ctx, is)) { + if (!parse_smt2_commands(*ctx.get(), is)) { + ctx = nullptr; SET_ERROR_CODE(Z3_PARSER_ERROR); return of_ast(mk_c(c)->m().mk_true()); } - ptr_vector::const_iterator it = ctx.begin_assertions(); - ptr_vector::const_iterator end = ctx.end_assertions(); + ptr_vector::const_iterator it = ctx->begin_assertions(); + ptr_vector::const_iterator end = ctx->end_assertions(); unsigned size = static_cast(end - it); return of_ast(mk_c(c)->mk_and(size, it)); Z3_CATCH_RETURN(0); diff --git a/src/api/api_quant.cpp b/src/api/api_quant.cpp index d64768b3b..e56505e6d 100644 --- a/src/api/api_quant.cpp +++ b/src/api/api_quant.cpp @@ -63,9 +63,11 @@ extern "C" { RESET_ERROR_CODE(); if (!mk_c(c)->m().is_bool(to_expr(body))) { SET_ERROR_CODE(Z3_SORT_ERROR); + return nullptr; } if (num_patterns > 0 && num_no_patterns > 0) { SET_ERROR_CODE(Z3_INVALID_USAGE); + return nullptr; } expr * const* ps = reinterpret_cast(patterns); expr * const* no_ps = reinterpret_cast(no_patterns); @@ -76,7 +78,7 @@ extern "C" { for (unsigned i = 0; i < num_patterns; i++) { if (!v(num_decls, ps[i], 0, 0)) { SET_ERROR_CODE(Z3_INVALID_PATTERN); - return 0; + return nullptr; } } } diff --git a/src/api/api_solver.cpp b/src/api/api_solver.cpp index 3a81080ed..2030c5210 100644 --- a/src/api/api_solver.cpp +++ b/src/api/api_solver.cpp @@ -442,6 +442,7 @@ extern "C" { unsigned sz = __assumptions.size(); for (unsigned i = 0; i < sz; ++i) { if (!is_expr(__assumptions[i])) { + _assumptions.finalize(); _consequences.finalize(); _variables.finalize(); SET_ERROR_CODE(Z3_INVALID_USAGE); return Z3_L_UNDEF; } @@ -451,6 +452,7 @@ extern "C" { sz = __variables.size(); for (unsigned i = 0; i < sz; ++i) { if (!is_expr(__variables[i])) { + _assumptions.finalize(); _consequences.finalize(); _variables.finalize(); SET_ERROR_CODE(Z3_INVALID_USAGE); return Z3_L_UNDEF; } @@ -471,6 +473,7 @@ extern "C" { } catch (z3_exception & ex) { to_solver_ref(s)->set_reason_unknown(eh); + _assumptions.finalize(); _consequences.finalize(); _variables.finalize(); mk_c(c)->handle_exception(ex); return Z3_L_UNDEF; } From a3b109cc143356f9095640b65d1795cfe9874e1e Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 11 Oct 2017 19:37:18 +0100 Subject: [PATCH 375/488] [ASan] Fix some leaks reported in the small object allocator test. --- src/test/small_object_allocator.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/small_object_allocator.cpp b/src/test/small_object_allocator.cpp index cdac0370d..2f08d553e 100644 --- a/src/test/small_object_allocator.cpp +++ b/src/test/small_object_allocator.cpp @@ -18,8 +18,11 @@ void tst_small_object_allocator() { TRACE("small_object_allocator", tout << "p1: " << (void*)p1 << " q1: " << (void*)q1 << " p2: " << (void*)p2 << "\n";); soa.deallocate(13,p1); + soa.deallocate(14,q1); + soa.deallocate(13,p2); char * p3 = new (soa) char[13]; TRACE("small_object_allocator", tout << "p3: " << (void*)p3 << "\n";); + soa.deallocate(13,p3); char * r1 = new (soa) char[1]; char * r2 = new (soa) char[1]; @@ -36,6 +39,10 @@ void tst_small_object_allocator() { r3 = new (soa) char[1]; TRACE("small_object_allocator", tout << "r1: " << (void*)r1 << " r2: " << (void*)r2 << " r3: " << (void*)r3 << " r4: " << (void*)r4 << "\n";); + soa.deallocate(1,r1); + soa.deallocate(1,r2); + soa.deallocate(1,r3); + soa.deallocate(1,r4); (void)r1; (void)r2; (void)r3; From da2b876acb0330f0afaa15911d56fbb2d7027c7c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 12 Oct 2017 07:39:27 -0700 Subject: [PATCH 376/488] fix #1303 Signed-off-by: Nikolaj Bjorner --- src/math/polynomial/polynomial.cpp | 17 +++++++++-------- src/test/nlsat.cpp | 2 -- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/math/polynomial/polynomial.cpp b/src/math/polynomial/polynomial.cpp index 80669648e..7adaf9adb 100644 --- a/src/math/polynomial/polynomial.cpp +++ b/src/math/polynomial/polynomial.cpp @@ -3536,10 +3536,11 @@ namespace polynomial { iccp(p, max_var(p), i, c, pp); } - void pp(polynomial const * p, var x, polynomial_ref & pp) { + polynomial_ref pp(polynomial const * p, var x) { scoped_numeral i(m_manager); - polynomial_ref c(pm()); - iccp(p, x, i, c, pp); + polynomial_ref c(pm()), result(pm()); + iccp(p, x, i, c, result); + return result; } bool is_primitive(polynomial const * p, var x) { @@ -3598,7 +3599,7 @@ namespace polynomial { if (is_zero(rem)) { TRACE("polynomial", tout << "rem is zero...\npp_v: " << pp_v << "\n";); flip_sign_if_lm_neg(pp_v); - pp(pp_v, x, r); + r = pp(pp_v, x); r = mul(d_a, d_r, r); return; } @@ -3849,7 +3850,7 @@ namespace polynomial { TRACE("mgcd", tout << "new combined:\n" << C_star << "\n";); } } - pp(C_star, x, candidate); + candidate = pp(C_star, x); TRACE("mgcd", tout << "candidate:\n" << candidate << "\n";); scoped_numeral lc_candidate(m()); lc_candidate = univ_coeff(candidate, degree(candidate, x)); @@ -6619,8 +6620,8 @@ namespace polynomial { polynomial_ref cf1(pm()); m_wrapper.content(f1, x, cf1); polynomial_ref cf2(pm()); m_wrapper.content(f2, x, cf2); tout << "content(f1): " << cf1 << "\ncontent(f2): " << cf2 << "\n";); - pp(f1, x, f1); - pp(f2, x, f2); + f1 = pp(f1, x); + f2 = pp(f2, x); TRACE("factor", tout << "f1: " << f1 << "\nf2: " << f2 << "\n";); DEBUG_CODE({ polynomial_ref f1f2(pm()); @@ -7150,7 +7151,7 @@ namespace polynomial { } void manager::primitive(polynomial const * p, var x, polynomial_ref & pp) { - m_imp->pp(p, x, pp); + pp = m_imp->pp(p, x); } void manager::icpp(polynomial const * p, var x, numeral & i, polynomial_ref & c, polynomial_ref & pp) { diff --git a/src/test/nlsat.cpp b/src/test/nlsat.cpp index 4d9d4579e..ecf73843f 100644 --- a/src/test/nlsat.cpp +++ b/src/test/nlsat.cpp @@ -698,10 +698,8 @@ static void tst10() { void tst_nlsat() { tst10(); std::cout << "------------------\n"; - exit(0); tst9(); std::cout << "------------------\n"; - exit(0); tst8(); std::cout << "------------------\n"; tst7(); From 11f1a81d7b4911d969ccd354c6cff2d65fd75b1e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 12 Oct 2017 10:12:37 -0700 Subject: [PATCH 377/488] disable failing unit tests Signed-off-by: Nikolaj Bjorner --- src/test/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/main.cpp b/src/test/main.cpp index 03fbba1df..cddf97700 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -222,14 +222,14 @@ int main(int argc, char ** argv) { TST(heap_trie); TST(karr); TST(no_overflow); - TST(memory); + // TST(memory); TST(datalog_parser); TST_ARGV(datalog_parser_file); TST(dl_query); TST(quant_solve); TST(rcf); TST(polynorm); - TST(qe_arith); + // TST(qe_arith); TST(expr_substitution); TST(sorting_network); TST(theory_pb); From d338fab4f632307eff3e85786e2d44cc96dce7aa Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 12 Oct 2017 13:58:14 -0700 Subject: [PATCH 378/488] fix #1305 Signed-off-by: Nikolaj Bjorner --- src/qe/qe_arith.cpp | 59 +++++++++++++++++++++------------------------ src/test/main.cpp | 2 +- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/qe/qe_arith.cpp b/src/qe/qe_arith.cpp index 9b3033397..6b3b3a11f 100644 --- a/src/qe/qe_arith.cpp +++ b/src/qe/qe_arith.cpp @@ -105,10 +105,10 @@ namespace qe { rational r; app* alit = to_app(lit); vector > nums; - for (unsigned i = 0; i < alit->get_num_args(); ++i) { - val = eval(alit->get_arg(i)); + for (expr* arg : *alit) { + val = eval(arg); if (!a.is_numeral(val, r)) return false; - nums.push_back(std::make_pair(alit->get_arg(i), r)); + nums.push_back(std::make_pair(arg, r)); } std::sort(nums.begin(), nums.end(), compare_second()); for (unsigned i = 0; i + 1 < nums.size(); ++i) { @@ -168,8 +168,8 @@ namespace qe { } else if (a.is_add(t)) { app* ap = to_app(t); - for (unsigned i = 0; i < ap->get_num_args(); ++i) { - linearize(mbo, eval, mul, ap->get_arg(i), c, fmls, ts, tids); + for (expr* arg : *ap) { + linearize(mbo, eval, mul, arg, c, fmls, ts, tids); } } else if (a.is_sub(t, t1, t2)) { @@ -226,16 +226,16 @@ namespace qe { else if (a.is_mul(t)) { app* ap = to_app(t); r = rational(1); - for (unsigned i = 0; i < ap->get_num_args(); ++i) { - if (!is_numeral(ap->get_arg(i), r1)) return false; + for (expr * arg : *ap) { + if (!is_numeral(arg, r1)) return false; r *= r1; } } else if (a.is_add(t)) { app* ap = to_app(t); r = rational(0); - for (unsigned i = 0; i < ap->get_num_args(); ++i) { - if (!is_numeral(ap->get_arg(i), r1)) return false; + for (expr * arg : *ap) { + if (!is_numeral(arg, r1)) return false; r += r1; } } @@ -297,6 +297,7 @@ namespace qe { opt::model_based_opt mbo; obj_map tids; + expr_ref_vector pinned(m); unsigned j = 0; for (unsigned i = 0; i < fmls.size(); ++i) { expr* fml = fmls[i].get(); @@ -308,6 +309,7 @@ namespace qe { } else { TRACE("qe", tout << mk_pp(fml, m) << "\n";); + pinned.push_back(fml); } } fmls.resize(j); @@ -321,8 +323,7 @@ namespace qe { // return those to fmls. expr_mark var_mark, fmls_mark; - for (unsigned i = 0; i < vars.size(); ++i) { - app* v = vars[i].get(); + for (app * v : vars) { var_mark.mark(v); if (is_arith(v) && !tids.contains(v)) { rational r; @@ -332,17 +333,16 @@ namespace qe { tids.insert(v, mbo.add_var(r, a.is_int(v))); } } - for (unsigned i = 0; i < fmls.size(); ++i) { - fmls_mark.mark(fmls[i].get()); + for (expr* fml : fmls) { + fmls_mark.mark(fml); } - obj_map::iterator it = tids.begin(), end = tids.end(); ptr_vector index2expr; - for (; it != end; ++it) { - expr* e = it->m_key; + for (auto& kv : tids) { + expr* e = kv.m_key; if (!var_mark.is_marked(e)) { mark_rec(fmls_mark, e); } - index2expr.setx(it->m_value, e, 0); + index2expr.setx(kv.m_value, e, 0); } j = 0; unsigned_vector real_vars; @@ -360,8 +360,7 @@ namespace qe { } vars.resize(j); TRACE("qe", tout << "remaining vars: " << vars << "\n"; - for (unsigned i = 0; i < real_vars.size(); ++i) { - unsigned v = real_vars[i]; + for (unsigned v : real_vars) { tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n"; } mbo.display(tout);); @@ -449,8 +448,8 @@ namespace qe { // extract linear constraints - for (unsigned i = 0; i < fmls.size(); ++i) { - linearize(mbo, eval, fmls[i].get(), fmls, tids); + for (expr * fml : fmls) { + linearize(mbo, eval, fml, fmls, tids); } // find optimal value @@ -459,11 +458,10 @@ namespace qe { // update model to use new values that satisfy optimality ptr_vector vars; - obj_map::iterator it = tids.begin(), end = tids.end(); - for (; it != end; ++it) { - expr* e = it->m_key; + for (auto& kv : tids) { + expr* e = kv.m_key; if (is_uninterp_const(e)) { - unsigned id = it->m_value; + unsigned id = kv.m_value; func_decl* f = to_app(e)->get_decl(); expr_ref val(a.mk_numeral(mbo.get_value(id), false), m); mdl.register_decl(f, val); @@ -509,10 +507,9 @@ namespace qe { void extract_coefficients(opt::model_based_opt& mbo, model_evaluator& eval, obj_map const& ts, obj_map& tids, vars& coeffs) { coeffs.reset(); eval.set_model_completion(true); - obj_map::iterator it = ts.begin(), end = ts.end(); - for (; it != end; ++it) { + for (auto& kv : ts) { unsigned id; - expr* v = it->m_key; + expr* v = kv.m_key; if (!tids.find(v, id)) { rational r; expr_ref val = eval(v); @@ -520,9 +517,9 @@ namespace qe { id = mbo.add_var(r, a.is_int(v)); tids.insert(v, id); } - CTRACE("qe", it->m_value.is_zero(), tout << mk_pp(v, m) << " has coefficeint 0\n";); - if (!it->m_value.is_zero()) { - coeffs.push_back(var(id, it->m_value)); + CTRACE("qe", kv.m_value.is_zero(), tout << mk_pp(v, m) << " has coefficeint 0\n";); + if (!kv.m_value.is_zero()) { + coeffs.push_back(var(id, kv.m_value)); } } } diff --git a/src/test/main.cpp b/src/test/main.cpp index cddf97700..7d61f9cad 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -229,7 +229,7 @@ int main(int argc, char ** argv) { TST(quant_solve); TST(rcf); TST(polynorm); - // TST(qe_arith); + TST(qe_arith); TST(expr_substitution); TST(sorting_network); TST(theory_pb); From 355455453325fe2b677f24663414bc0900383f59 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 12 Oct 2017 14:17:52 -0700 Subject: [PATCH 379/488] command to exit tests early Signed-off-by: Nikolaj Bjorner --- src/test/main.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/test/main.cpp b/src/test/main.cpp index cddf97700..77df6c2fb 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -10,27 +10,30 @@ #include "util/memory_manager.h" #include "util/gparams.h" +static void tst_exit_all_tests() { + exit(0); +} // // Unit tests fail by asserting. // If they return, we assume the unit test succeeds // and print "PASS" to indicate success. // -#define TST(MODULE) { \ - std::string s("test "); \ - s += #MODULE; \ - void tst_##MODULE(); \ - if (do_display_usage) \ - std::cout << #MODULE << "\n"; \ - for (int i = 0; i < argc; i++) \ - if (test_all || strcmp(argv[i], #MODULE) == 0) { \ - enable_trace(#MODULE); \ - enable_debug(#MODULE); \ - timeit timeit(true, s.c_str()); \ - tst_##MODULE(); \ - std::cout << "PASS" << std::endl; \ - } \ -} +#define TST(MODULE) { \ + std::string s("test "); \ + s += #MODULE; \ + void tst_##MODULE(); \ + if (do_display_usage) \ + std::cout << #MODULE << "\n"; \ + for (int i = 0; i < argc; i++) \ + if (test_all || strcmp(argv[i], #MODULE) == 0) { \ + enable_trace(#MODULE); \ + enable_debug(#MODULE); \ + timeit timeit(true, s.c_str()); \ + tst_##MODULE(); \ + std::cout << "PASS" << std::endl; \ + } \ + } #define TST_ARGV(MODULE) { \ std::string s("test "); \ @@ -207,6 +210,7 @@ int main(int argc, char ** argv) { TST(prime_generator); TST(permutation); TST(nlsat); + TST(exit_all_tests); TST(ext_numeral); TST(interval); TST(f2n); From 8cf0c94e5ff3e2f57c250e1265a9d8c02c254092 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 12 Oct 2017 14:34:04 -0700 Subject: [PATCH 380/488] address some ASan leaks Signed-off-by: Nikolaj Bjorner --- src/math/automata/symbolic_automata_def.h | 3 ++- src/util/scoped_ptr_vector.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/math/automata/symbolic_automata_def.h b/src/math/automata/symbolic_automata_def.h index 3be6a1da0..be38a60bc 100644 --- a/src/math/automata/symbolic_automata_def.h +++ b/src/math/automata/symbolic_automata_def.h @@ -24,6 +24,7 @@ Revision History: #include "math/automata/symbolic_automata.h" #include "util/hashtable.h" +#include "util/vector.h" @@ -311,7 +312,7 @@ symbolic_automata::mk_determinstic_param(automaton_t& a, bool flip_accepta s2id.insert(set, p_state_id++); // the index to the initial state is 0 id2s.push_back(set); - svector todo; //States to visit + ::vector todo; //States to visit todo.push_back(set); uint_set state; diff --git a/src/util/scoped_ptr_vector.h b/src/util/scoped_ptr_vector.h index a9ef92766..0bd0fd47e 100644 --- a/src/util/scoped_ptr_vector.h +++ b/src/util/scoped_ptr_vector.h @@ -42,7 +42,7 @@ public: bool empty() const { return m_vector.empty(); } void resize(unsigned sz) { if (sz < m_vector.size()) { - for (unsigned i = m_vector.size(); i < sz; i++) + for (unsigned i = m_vector.size(); i-- > sz; ) dealloc(m_vector[i]); m_vector.shrink(sz); } From c12439fe1e3fb93a77e42e97780544a92206e011 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 13 Oct 2017 07:29:16 -0700 Subject: [PATCH 381/488] fix #1306 Signed-off-by: Nikolaj Bjorner --- src/sat/sat_solver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 8782cb462..03c17aaf0 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -726,7 +726,7 @@ namespace sat { SASSERT(scope_lvl() == 0); if (m_config.m_dimacs_display) { display_dimacs(std::cout); - for (unsigned i = 0; i < num_lits; ++lits) { + for (unsigned i = 0; i < num_lits; ++i) { std::cout << dimacs_lit(lits[i]) << " 0\n"; } return l_undef; From 40dfdb6606045240f519a42042bd29d6143fa6bd Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 13 Oct 2017 07:37:18 -0700 Subject: [PATCH 382/488] bypass UBSan error warnings by using nullptr as error handler. Has same no-op effect. Issue #1287 --- src/api/c++/z3++.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 2200874d3..84ddfacc6 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -140,18 +140,17 @@ namespace z3 { class context { bool m_enable_exceptions; Z3_context m_ctx; - static void Z3_API error_handler(Z3_context /*c*/, Z3_error_code /*e*/) { /* do nothing */ } void init(config & c) { m_ctx = Z3_mk_context_rc(c); m_enable_exceptions = true; - Z3_set_error_handler(m_ctx, error_handler); + Z3_set_error_handler(m_ctx, nullptr); Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT); } void init_interp(config & c) { m_ctx = Z3_mk_interpolation_context(c); m_enable_exceptions = true; - Z3_set_error_handler(m_ctx, error_handler); + Z3_set_error_handler(m_ctx, nullptr); Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT); } From 5b6472f022594dc64336da33d013d9b43e76ab0a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 13 Oct 2017 10:54:29 -0700 Subject: [PATCH 383/488] change nullptr to 0 Signed-off-by: Nikolaj Bjorner --- src/api/c++/z3++.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 84ddfacc6..f55ece034 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -143,14 +143,14 @@ namespace z3 { void init(config & c) { m_ctx = Z3_mk_context_rc(c); m_enable_exceptions = true; - Z3_set_error_handler(m_ctx, nullptr); + Z3_set_error_handler(m_ctx, 0); Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT); } void init_interp(config & c) { m_ctx = Z3_mk_interpolation_context(c); m_enable_exceptions = true; - Z3_set_error_handler(m_ctx, nullptr); + Z3_set_error_handler(m_ctx, 0); Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT); } From f79cd8f0bc58e118b1af1f7a6048d063dac97d85 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 13 Oct 2017 10:58:42 -0700 Subject: [PATCH 384/488] unused variables Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/spacer_qe_project.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/muz/spacer/spacer_qe_project.cpp b/src/muz/spacer/spacer_qe_project.cpp index dd6472224..9f4f4e4fe 100644 --- a/src/muz/spacer/spacer_qe_project.cpp +++ b/src/muz/spacer/spacer_qe_project.cpp @@ -66,7 +66,6 @@ class peq { app_ref m_peq; // partial equality application app_ref m_eq; // equivalent std equality using def. of partial eq array_util m_arr_u; - ast_eq_proc m_eq_proc; // for checking if two asts are equal public: static const char* PARTIAL_EQ; @@ -102,7 +101,7 @@ peq::peq (app* p, ast_manager& m): VERIFY (is_partial_eq (p)); SASSERT (m_arr_u.is_array (m_lhs) && m_arr_u.is_array (m_rhs) && - m_eq_proc (m.get_sort (m_lhs), m.get_sort (m_rhs))); + ast_eq_proc() (m.get_sort (m_lhs), m.get_sort (m_rhs))); for (unsigned i = 2; i < p->get_num_args (); i++) { m_diff_indices.push_back (p->get_arg (i)); } @@ -121,7 +120,7 @@ peq::peq (expr* lhs, expr* rhs, unsigned num_indices, expr * const * diff_indice { SASSERT (m_arr_u.is_array (lhs) && m_arr_u.is_array (rhs) && - m_eq_proc (m.get_sort (lhs), m.get_sort (rhs))); + ast_eq_proc() (m.get_sort (lhs), m.get_sort (rhs))); ptr_vector sorts; sorts.push_back (m.get_sort (m_lhs)); sorts.push_back (m.get_sort (m_rhs)); From 7f8a7c3d83011dd1d0571b2c4d954b3434f60901 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 14 Oct 2017 11:59:09 -0700 Subject: [PATCH 385/488] fix the fixme of #1307 Signed-off-by: Nikolaj Bjorner --- src/test/main.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/main.cpp b/src/test/main.cpp index cdc06404c..98be722e3 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -10,9 +10,7 @@ #include "util/memory_manager.h" #include "util/gparams.h" -static void tst_exit_all_tests() { - exit(0); -} + // // Unit tests fail by asserting. // If they return, we assume the unit test succeeds @@ -210,7 +208,7 @@ int main(int argc, char ** argv) { TST(prime_generator); TST(permutation); TST(nlsat); - TST(exit_all_tests); + if (test_all) return 0; TST(ext_numeral); TST(interval); TST(f2n); From 4d1acadabbe9f218681bb8c6228dc97dd337cf9b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 15 Oct 2017 09:56:21 -0700 Subject: [PATCH 386/488] fix leaks reported in #1309 Signed-off-by: Nikolaj Bjorner --- src/sat/sat_simplifier.cpp | 5 +---- src/smt/theory_str.cpp | 5 +++++ src/smt/theory_str.h | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sat/sat_simplifier.cpp b/src/sat/sat_simplifier.cpp index 67101b4d8..84534bf3f 100644 --- a/src/sat/sat_simplifier.cpp +++ b/src/sat/sat_simplifier.cpp @@ -1311,7 +1311,6 @@ namespace sat { clause_use_list & neg_occs = m_use_list.get(neg_l); unsigned num_pos = pos_occs.size() + num_bin_pos; unsigned num_neg = neg_occs.size() + num_bin_neg; - m_elim_counter -= num_pos + num_neg; TRACE("resolution", tout << v << " num_pos: " << num_pos << " neg_pos: " << num_neg << "\n";); @@ -1352,8 +1351,6 @@ namespace sat { collect_clauses(pos_l, m_pos_cls); collect_clauses(neg_l, m_neg_cls); - m_elim_counter -= num_pos * num_neg + before_lits; - TRACE("resolution_detail", tout << "collecting number of after_clauses\n";); unsigned before_clauses = num_pos + num_neg; unsigned after_clauses = 0; @@ -1376,7 +1373,7 @@ namespace sat { } } TRACE("resolution", tout << "found var to eliminate, before: " << before_clauses << " after: " << after_clauses << "\n";); - + m_elim_counter -= num_pos * num_neg + before_lits; // eliminate variable model_converter::entry & mc_entry = s.m_mc.mk(model_converter::ELIM_VAR, v); diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 8a141665c..97c8db125 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -315,6 +315,7 @@ namespace smt { m_trail.push_back(node); if (!cut_var_map.contains(baseNode)) { T_cut * varInfo = alloc(T_cut); + m_cut_allocs.push_back(varInfo); varInfo->level = slevel; varInfo->vars[node] = 1; cut_var_map.insert(baseNode, std::stack()); @@ -323,6 +324,7 @@ namespace smt { } else { if (cut_var_map[baseNode].empty()) { T_cut * varInfo = alloc(T_cut); + m_cut_allocs.push_back(varInfo); varInfo->level = slevel; varInfo->vars[node] = 1; cut_var_map[baseNode].push(varInfo); @@ -330,6 +332,7 @@ namespace smt { } else { if (cut_var_map[baseNode].top()->level < slevel) { T_cut * varInfo = alloc(T_cut); + m_cut_allocs.push_back(varInfo); varInfo->level = slevel; cut_vars_map_copy(varInfo->vars, cut_var_map[baseNode].top()->vars); varInfo->vars[node] = 1; @@ -359,6 +362,7 @@ namespace smt { if (!cut_var_map.contains(destNode)) { T_cut * varInfo = alloc(T_cut); + m_cut_allocs.push_back(varInfo); varInfo->level = slevel; cut_vars_map_copy(varInfo->vars, cut_var_map[srcNode].top()->vars); cut_var_map.insert(destNode, std::stack()); @@ -367,6 +371,7 @@ namespace smt { } else { if (cut_var_map[destNode].empty() || cut_var_map[destNode].top()->level < slevel) { T_cut * varInfo = alloc(T_cut); + m_cut_allocs.push_back(varInfo); varInfo->level = slevel; cut_vars_map_copy(varInfo->vars, cut_var_map[destNode].top()->vars); cut_vars_map_copy(varInfo->vars, cut_var_map[srcNode].top()->vars); diff --git a/src/smt/theory_str.h b/src/smt/theory_str.h index 686fcdd57..acac8cad1 100644 --- a/src/smt/theory_str.h +++ b/src/smt/theory_str.h @@ -18,9 +18,12 @@ #define _THEORY_STR_H_ #include "util/trail.h" +#include "util/union_find.h" +#include "util/scoped_ptr_vector.h" #include "ast/ast_pp.h" #include "ast/arith_decl_plugin.h" #include "ast/rewriter/th_rewriter.h" +#include "ast/seq_decl_plugin.h" #include "smt/smt_theory.h" #include "smt/params/theory_str_params.h" #include "smt/proto_model/value_factory.h" @@ -29,8 +32,6 @@ #include #include #include -#include "ast/seq_decl_plugin.h" -#include "util/union_find.h" namespace smt { @@ -292,6 +293,7 @@ protected: bool avoidLoopCut; bool loopDetected; obj_map > cut_var_map; + scoped_ptr_vector m_cut_allocs; expr_ref m_theoryStrOverlapAssumption_term; obj_hashtable variable_set; From 9b54b4e7848ff8f1df54378d5091867c37c16023 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Tue, 10 Oct 2017 17:24:22 +0100 Subject: [PATCH 387/488] fix vector<> to support non-POD types adjust code to std::move and avoid unnecessary/illegal --- src/ast/ast.cpp | 2 +- src/ast/ast.h | 14 +++ src/ast/pattern/expr_pattern_match.cpp | 6 +- .../bit_blaster/bit_blaster_tpl_def.h | 2 +- src/ast/substitution/substitution_tree.cpp | 4 +- src/ast/used_vars.cpp | 2 +- src/math/polynomial/algebraic_numbers.cpp | 12 +- src/math/polynomial/polynomial.cpp | 6 +- .../upolynomial_factorization_int.h | 2 +- src/math/simplex/sparse_matrix.h | 4 +- src/math/subpaving/subpaving_t_def.h | 2 +- src/model/func_interp.cpp | 2 +- src/muz/rel/dl_instruction.h | 2 +- src/muz/rel/dl_mk_explanations.cpp | 2 +- src/qe/qe.cpp | 2 +- src/smt/mam.cpp | 2 +- src/smt/smt_context.cpp | 2 +- src/smt/theory_array_base.cpp | 4 +- src/smt/theory_datatype.cpp | 2 +- src/smt/theory_dense_diff_logic_def.h | 9 +- src/smt/theory_diff_logic_def.h | 9 +- src/smt/theory_pb.cpp | 3 +- src/smt/theory_pb.h | 1 - src/tactic/sls/bvsls_opt_engine.cpp | 2 +- src/tactic/sls/bvsls_opt_engine.h | 2 +- src/tactic/sls/sls_tracker.h | 37 ++++--- src/util/buffer.h | 7 ++ src/util/hashtable.h | 58 ++++++++-- src/util/mpq.h | 9 +- src/util/mpz.h | 15 +++ src/util/obj_hashtable.h | 10 +- src/util/ref_vector.h | 4 +- src/util/scoped_numeral_vector.h | 3 +- src/util/util.h | 2 +- src/util/vector.h | 103 ++++++++++++++---- 35 files changed, 253 insertions(+), 95 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index cac12413e..9116c5d95 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -768,7 +768,7 @@ func_decl * basic_decl_plugin::mk_compressed_proof_decl(char const * name, basic func_decl * basic_decl_plugin::mk_proof_decl(char const * name, basic_op_kind k, unsigned num_parents, ptr_vector & cache) { if (num_parents >= cache.size()) { - cache.resize(num_parents+1, 0); + cache.resize(num_parents+1); } if (cache[num_parents] == 0) { cache[num_parents] = mk_proof_decl(name, k, num_parents); diff --git a/src/ast/ast.h b/src/ast/ast.h index 4eb43d30b..54f8f5e62 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -121,6 +121,20 @@ public: explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {} parameter(parameter const&); + parameter(parameter && other) noexcept : m_kind(other.m_kind) { + switch (other.m_kind) { + case PARAM_INT: m_int = other.get_int(); break; + case PARAM_AST: m_ast = other.get_ast(); break; + case PARAM_SYMBOL: m_symbol = other.m_symbol; break; + case PARAM_RATIONAL: m_rational = 0; std::swap(m_rational, other.m_rational); break; + case PARAM_DOUBLE: m_dval = other.m_dval; break; + case PARAM_EXTERNAL: m_ext_id = other.m_ext_id; break; + default: + UNREACHABLE(); + break; + } + } + ~parameter(); parameter& operator=(parameter const& other); diff --git a/src/ast/pattern/expr_pattern_match.cpp b/src/ast/pattern/expr_pattern_match.cpp index 770832d1f..628c777d3 100644 --- a/src/ast/pattern/expr_pattern_match.cpp +++ b/src/ast/pattern/expr_pattern_match.cpp @@ -179,11 +179,11 @@ expr_pattern_match::compile(expr* q) } if (m_regs.size() <= max_reg) { - m_regs.resize(max_reg+1, 0); + m_regs.resize(max_reg+1); } if (m_bound_dom.size() <= num_bound) { - m_bound_dom.resize(num_bound+1, 0); - m_bound_rng.resize(num_bound+1, 0); + m_bound_dom.resize(num_bound+1); + m_bound_rng.resize(num_bound+1); } instr.m_kind = YIELD; diff --git a/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h b/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h index cd66a5124..a80994f6c 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h +++ b/src/ast/rewriter/bit_blaster/bit_blaster_tpl_def.h @@ -272,7 +272,7 @@ void bit_blaster_tpl::mk_multiplier(unsigned sz, expr * const * a_bits, exp zero = m().mk_false(); vector< expr_ref_vector > pps; - pps.resize(sz, m()); + pps.resize(sz, expr_ref_vector(m())); for (unsigned i = 0; i < sz; i++) { checkpoint(); diff --git a/src/ast/substitution/substitution_tree.cpp b/src/ast/substitution/substitution_tree.cpp index 9befb582f..20d5f1590 100644 --- a/src/ast/substitution/substitution_tree.cpp +++ b/src/ast/substitution/substitution_tree.cpp @@ -256,7 +256,7 @@ void substitution_tree::insert(expr * new_expr) { sort * s = to_var(new_expr)->get_sort(); unsigned id = s->get_decl_id(); if (id >= m_vars.size()) - m_vars.resize(id+1, 0); + m_vars.resize(id+1); if (m_vars[id] == 0) m_vars[id] = alloc(var_ref_vector, m_manager); var_ref_vector * v = m_vars[id]; @@ -277,7 +277,7 @@ void substitution_tree::insert(app * new_expr) { unsigned id = d->get_decl_id(); if (id >= m_roots.size()) - m_roots.resize(id+1, 0); + m_roots.resize(id+1); if (!m_roots[id]) { // there is no tree for the function symbol heading new_expr diff --git a/src/ast/used_vars.cpp b/src/ast/used_vars.cpp index a1cd65feb..a3030f087 100644 --- a/src/ast/used_vars.cpp +++ b/src/ast/used_vars.cpp @@ -58,7 +58,7 @@ void used_vars::process(expr * n, unsigned delta) { if (idx >= delta) { idx = idx - delta; if (idx >= m_found_vars.size()) - m_found_vars.resize(idx + 1, 0); + m_found_vars.resize(idx + 1); m_found_vars[idx] = to_var(n)->get_sort(); } break; diff --git a/src/math/polynomial/algebraic_numbers.cpp b/src/math/polynomial/algebraic_numbers.cpp index 22b50326b..9484c3c83 100644 --- a/src/math/polynomial/algebraic_numbers.cpp +++ b/src/math/polynomial/algebraic_numbers.cpp @@ -2632,10 +2632,14 @@ namespace algebraic_numbers { scoped_mpz neg_n(qm()); qm().set(neg_n, v.numerator()); qm().neg(neg_n); - mpz const coeffs[2] = { neg_n.get(), v.denominator() }; + unsynch_mpz_manager zmgr; + // FIXME: remove these copies + mpz coeffs[2] = { zmgr.dup(neg_n.get()), zmgr.dup(v.denominator()) }; out << "("; upm().display(out, 2, coeffs, "#"); out << ", 1)"; // first root of the polynomial d*# - n + zmgr.del(coeffs[0]); + zmgr.del(coeffs[1]); } else { algebraic_cell * c = a.to_algebraic(); @@ -2678,10 +2682,14 @@ namespace algebraic_numbers { scoped_mpz neg_n(qm()); qm().set(neg_n, v.numerator()); qm().neg(neg_n); - mpz const coeffs[2] = { neg_n.get(), v.denominator() }; + unsynch_mpz_manager zmgr; + // FIXME: remove these copies + mpz coeffs[2] = { zmgr.dup(neg_n.get()), zmgr.dup(v.denominator()) }; out << "(root-obj "; upm().display_smt2(out, 2, coeffs, "x"); out << " 1)"; // first root of the polynomial d*# - n + zmgr.del(coeffs[0]); + zmgr.del(coeffs[1]); } else { algebraic_cell * c = a.to_algebraic(); diff --git a/src/math/polynomial/polynomial.cpp b/src/math/polynomial/polynomial.cpp index 7adaf9adb..d6d392148 100644 --- a/src/math/polynomial/polynomial.cpp +++ b/src/math/polynomial/polynomial.cpp @@ -4822,10 +4822,9 @@ namespace polynomial { polynomial * mk_x_minus_y(var x, var y) { numeral zero(0); - numeral one(1); numeral minus_one; // It is not safe to initialize with -1 when numeral_manager is GF_2 m_manager.set(minus_one, -1); - numeral as[2] = { one, minus_one }; + numeral as[2] = { numeral(1), std::move(minus_one) }; var xs[2] = { x, y }; return mk_linear(2, as, xs, zero); } @@ -4845,8 +4844,7 @@ namespace polynomial { polynomial * mk_x_plus_y(var x, var y) { numeral zero(0); - numeral one(1); - numeral as[2] = { one, one }; + numeral as[2] = { numeral(1), numeral(1) }; var xs[2] = { x, y }; return mk_linear(2, as, xs, zero); } diff --git a/src/math/polynomial/upolynomial_factorization_int.h b/src/math/polynomial/upolynomial_factorization_int.h index 640c5ad5c..ea2b51d8f 100644 --- a/src/math/polynomial/upolynomial_factorization_int.h +++ b/src/math/polynomial/upolynomial_factorization_int.h @@ -45,7 +45,7 @@ namespace upolynomial { for (unsigned i = 0; i < p.size(); ++ i) { numeral p_i; // no need to delete, we keep it pushed in zp_p zp_nm.set(p_i, p[i]); - zp_p.push_back(p_i); + zp_p.push_back(std::move(p_i)); } zp_upm.trim(zp_p); } diff --git a/src/math/simplex/sparse_matrix.h b/src/math/simplex/sparse_matrix.h index dc4ce8695..63bbe9e78 100644 --- a/src/math/simplex/sparse_matrix.h +++ b/src/math/simplex/sparse_matrix.h @@ -35,7 +35,7 @@ namespace simplex { struct row_entry { numeral m_coeff; var_t m_var; - row_entry(numeral const& c, var_t v): m_coeff(c), m_var(v) {} + row_entry(numeral && c, var_t v) noexcept : m_coeff(std::move(c)), m_var(v) {} }; private: @@ -61,7 +61,7 @@ namespace simplex { int m_col_idx; int m_next_free_row_entry_idx; }; - _row_entry(numeral const & c, var_t v): row_entry(c, v), m_col_idx(0) {} + _row_entry(numeral && c, var_t v) : row_entry(std::move(c), v), m_col_idx(0) {} _row_entry() : row_entry(numeral(), dead_id), m_col_idx(0) {} bool is_dead() const { return row_entry::m_var == dead_id; } }; diff --git a/src/math/subpaving/subpaving_t_def.h b/src/math/subpaving/subpaving_t_def.h index 108b6aac3..3574787d8 100644 --- a/src/math/subpaving/subpaving_t_def.h +++ b/src/math/subpaving/subpaving_t_def.h @@ -739,7 +739,7 @@ void context_t::del_sum(polynomial * p) { template var context_t::mk_sum(numeral const & c, unsigned sz, numeral const * as, var const * xs) { - m_num_buffer.reserve(num_vars(), numeral()); + m_num_buffer.reserve(num_vars()); for (unsigned i = 0; i < sz; i++) { SASSERT(xs[i] < num_vars()); nm().set(m_num_buffer[xs[i]], as[i]); diff --git a/src/model/func_interp.cpp b/src/model/func_interp.cpp index 6699ef0e2..e458cc4b0 100644 --- a/src/model/func_interp.cpp +++ b/src/model/func_interp.cpp @@ -117,7 +117,7 @@ bool func_interp::is_fi_entry_expr(expr * e, ptr_vector & args) { (m_arity > 1 && (!m().is_and(c) || to_app(c)->get_num_args() != m_arity))) return false; - args.resize(m_arity, 0); + args.resize(m_arity); for (unsigned i = 0; i < m_arity; i++) { expr * ci = (m_arity == 1 && i == 0) ? c : to_app(c)->get_arg(i); diff --git a/src/muz/rel/dl_instruction.h b/src/muz/rel/dl_instruction.h index c29681f37..56dd249a5 100644 --- a/src/muz/rel/dl_instruction.h +++ b/src/muz/rel/dl_instruction.h @@ -128,7 +128,7 @@ namespace datalog { void set_reg(reg_idx i, reg_type val) { if (i >= m_registers.size()) { check_overflow(i); - m_registers.resize(i+1,0); + m_registers.resize(i+1); } if (m_registers[i]) { m_registers[i]->deallocate(); diff --git a/src/muz/rel/dl_mk_explanations.cpp b/src/muz/rel/dl_mk_explanations.cpp index fd13978d2..c4fb57eeb 100644 --- a/src/muz/rel/dl_mk_explanations.cpp +++ b/src/muz/rel/dl_mk_explanations.cpp @@ -465,7 +465,7 @@ namespace datalog { unsigned sz = r.get_signature().size(); ptr_vector subst_arg; - subst_arg.resize(sz, 0); + subst_arg.resize(sz); unsigned ofs = sz-1; for (unsigned i=0; iget_family_id(); SASSERT(fid != null_family_id); if (static_cast(m_plugins.size()) <= fid) { - m_plugins.resize(fid+1,0); + m_plugins.resize(fid+1); } SASSERT(!m_plugins[fid]); m_plugins[fid] = p; diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index 497aab8db..96334e3ce 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -1999,7 +1999,7 @@ namespace smt { m_ast_manager(ctx.get_manager()), m_mam(m), m_use_filters(use_filters) { - m_args.resize(INIT_ARGS_SIZE, 0); + m_args.resize(INIT_ARGS_SIZE); } ~interpreter() { diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index ac7b1f44b..48d02da26 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -1286,7 +1286,7 @@ namespace smt { else { if (depth >= m_almost_cg_tables.size()) { unsigned old_sz = m_almost_cg_tables.size(); - m_almost_cg_tables.resize(depth+1, 0); + m_almost_cg_tables.resize(depth+1); for (unsigned i = old_sz; i < depth + 1; i++) m_almost_cg_tables[i] = alloc(almost_cg_table); } diff --git a/src/smt/theory_array_base.cpp b/src/smt/theory_array_base.cpp index 1f519dfda..21df02c76 100644 --- a/src/smt/theory_array_base.cpp +++ b/src/smt/theory_array_base.cpp @@ -617,8 +617,8 @@ namespace smt { m_else_values.reset(); m_parents.reset(); m_parents.resize(num_vars, -1); - m_defaults.resize(num_vars, 0); - m_else_values.resize(num_vars, 0); + m_defaults.resize(num_vars); + m_else_values.resize(num_vars); if (m_use_unspecified_default) return; diff --git a/src/smt/theory_datatype.cpp b/src/smt/theory_datatype.cpp index 616314117..bbed6840d 100644 --- a/src/smt/theory_datatype.cpp +++ b/src/smt/theory_datatype.cpp @@ -620,7 +620,7 @@ namespace smt { sort * s = recognizer->get_decl()->get_domain(0); if (d->m_recognizers.empty()) { SASSERT(m_util.is_datatype(s)); - d->m_recognizers.resize(m_util.get_datatype_num_constructors(s), 0); + d->m_recognizers.resize(m_util.get_datatype_num_constructors(s)); } SASSERT(d->m_recognizers.size() == m_util.get_datatype_num_constructors(s)); unsigned c_idx = m_util.get_recognizer_constructor_idx(recognizer->get_decl()); diff --git a/src/smt/theory_dense_diff_logic_def.h b/src/smt/theory_dense_diff_logic_def.h index 064bdd433..78fb4d03d 100644 --- a/src/smt/theory_dense_diff_logic_def.h +++ b/src/smt/theory_dense_diff_logic_def.h @@ -914,6 +914,8 @@ namespace smt { } verbose_stream() << " + " << m_objective_consts[v] << "\n";); + unsynch_mpq_manager mgr; + unsynch_mpq_inf_manager inf_mgr; unsigned num_nodes = get_num_vars(); unsigned num_edges = m_edges.size(); S.ensure_var(num_nodes + num_edges + m_objectives.size()); @@ -921,8 +923,9 @@ namespace smt { numeral const& a = m_assignment[i]; rational fin = a.get_rational().to_rational(); rational inf = a.get_infinitesimal().to_rational(); - mpq_inf q(fin.to_mpq(), inf.to_mpq()); + mpq_inf q(mgr.dup(fin.to_mpq()), mgr.dup(inf.to_mpq())); S.set_value(i, q); + inf_mgr.del(q); } for (unsigned i = 0; i < num_nodes; ++i) { enode * n = get_enode(i); @@ -933,7 +936,6 @@ namespace smt { } } svector vars; - unsynch_mpq_manager mgr; scoped_mpq_vector coeffs(mgr); coeffs.push_back(mpq(1)); coeffs.push_back(mpq(-1)); @@ -954,8 +956,9 @@ namespace smt { numeral const& w = e.m_offset; rational fin = w.get_rational().to_rational(); rational inf = w.get_infinitesimal().to_rational(); - mpq_inf q(fin.to_mpq(),inf.to_mpq()); + mpq_inf q(mgr.dup(fin.to_mpq()), mgr.dup(inf.to_mpq())); S.set_upper(base_var, q); + inf_mgr.del(q); } unsigned w = num_nodes + num_edges + v; diff --git a/src/smt/theory_diff_logic_def.h b/src/smt/theory_diff_logic_def.h index a7153234c..203dd24d2 100644 --- a/src/smt/theory_diff_logic_def.h +++ b/src/smt/theory_diff_logic_def.h @@ -1107,6 +1107,8 @@ unsigned theory_diff_logic::simplex2edge(unsigned e) { template void theory_diff_logic::update_simplex(Simplex& S) { + unsynch_mpq_manager mgr; + unsynch_mpq_inf_manager inf_mgr; unsigned num_nodes = m_graph.get_num_nodes(); vector > const& es = m_graph.get_all_edges(); S.ensure_var(num_simplex_vars()); @@ -1114,13 +1116,13 @@ void theory_diff_logic::update_simplex(Simplex& S) { numeral const& a = m_graph.get_assignment(i); rational fin = a.get_rational().to_rational(); rational inf = a.get_infinitesimal().to_rational(); - mpq_inf q(fin.to_mpq(), inf.to_mpq()); + mpq_inf q(mgr.dup(fin.to_mpq()), mgr.dup(inf.to_mpq())); S.set_value(node2simplex(i), q); + inf_mgr.del(q); } S.set_lower(node2simplex(get_zero()), mpq_inf(mpq(0), mpq(0))); S.set_upper(node2simplex(get_zero()), mpq_inf(mpq(0), mpq(0))); svector vars; - unsynch_mpq_manager mgr; scoped_mpq_vector coeffs(mgr); coeffs.push_back(mpq(1)); coeffs.push_back(mpq(-1)); @@ -1145,8 +1147,9 @@ void theory_diff_logic::update_simplex(Simplex& S) { numeral const& w = e.get_weight(); rational fin = w.get_rational().to_rational(); rational inf = w.get_infinitesimal().to_rational(); - mpq_inf q(fin.to_mpq(),inf.to_mpq()); + mpq_inf q(mgr.dup(fin.to_mpq()), mgr.dup(inf.to_mpq())); S.set_upper(base_var, q); + inf_mgr.del(q); } else { S.unset_upper(base_var); diff --git a/src/smt/theory_pb.cpp b/src/smt/theory_pb.cpp index 4b52d7950..9d2059f55 100644 --- a/src/smt/theory_pb.cpp +++ b/src/smt/theory_pb.cpp @@ -806,8 +806,9 @@ namespace smt { if (c != 0) { if (m_enable_simplex) { row_info const& info = m_ineq_row_info.find(v); + unsynch_mpq_manager mgr; scoped_eps_numeral coeff(m_mpq_inf_mgr); - coeff = std::make_pair(info.m_bound.to_mpq(), mpq(0)); + coeff = std::make_pair(mgr.dup(info.m_bound.to_mpq()), mpq(0)); unsigned slack = info.m_slack; if (is_true) { update_bound(slack, literal(v), true, coeff); diff --git a/src/smt/theory_pb.h b/src/smt/theory_pb.h index 7f530e5b0..662378bdf 100644 --- a/src/smt/theory_pb.h +++ b/src/smt/theory_pb.h @@ -279,7 +279,6 @@ namespace smt { // void compile_ineq(ineq& c); void inc_propagations(ineq& c); - unsigned get_compilation_threshold(ineq& c); // // Conflict resolution, cutting plane derivation. diff --git a/src/tactic/sls/bvsls_opt_engine.cpp b/src/tactic/sls/bvsls_opt_engine.cpp index e8547fdfd..502bcbde6 100644 --- a/src/tactic/sls/bvsls_opt_engine.cpp +++ b/src/tactic/sls/bvsls_opt_engine.cpp @@ -238,7 +238,7 @@ bool bvsls_opt_engine::what_if( mpz bvsls_opt_engine::find_best_move( ptr_vector & to_evaluate, - mpz score, + mpz & score, unsigned & best_const, mpz & best_value, unsigned & new_bit, diff --git a/src/tactic/sls/bvsls_opt_engine.h b/src/tactic/sls/bvsls_opt_engine.h index 67d9a5d02..9487130d3 100644 --- a/src/tactic/sls/bvsls_opt_engine.h +++ b/src/tactic/sls/bvsls_opt_engine.h @@ -61,7 +61,7 @@ protected: bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, mpz & best_score, unsigned & best_const, mpz & best_value); - mpz find_best_move(ptr_vector & to_evaluate, mpz score, + mpz find_best_move(ptr_vector & to_evaluate, mpz & score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move, mpz const & max_score, expr * objective); diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 4ad5c65f4..b4969f433 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -41,7 +41,20 @@ class sls_tracker { struct value_score { value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), score_prune(0.0), has_pos_occ(0), has_neg_occ(0), distance(0), touched(1) {}; + value_score(value_score && other) : + m(other.m), + value(std::move(other.value)), + score(other.score), + score_prune(other.score_prune), + has_pos_occ(other.has_pos_occ), + has_neg_occ(other.has_neg_occ), + distance(other.distance), + touched(other.touched) {} ~value_score() { if (m) m->del(value); } + void operator=(value_score && other) { + this->~value_score(); + new (this) value_score(std::move(other)); + } unsynch_mpz_manager * m; mpz value; double score; @@ -50,15 +63,6 @@ class sls_tracker { unsigned has_neg_occ; unsigned distance; // max distance from any root unsigned touched; - value_score & operator=(const value_score & other) { - SASSERT(m == 0 || m == other.m); - if (m) m->set(value, 0); else m = other.m; - m->set(value, other.value); - score = other.score; - distance = other.distance; - touched = other.touched; - return *this; - } }; public: @@ -294,7 +298,7 @@ public: if (!m_scores.contains(n)) { value_score vs; vs.m = & m_mpz_manager; - m_scores.insert(n, vs); + m_scores.insert(n, std::move(vs)); } // Update uplinks @@ -539,7 +543,7 @@ public: rational r_val; unsigned bv_sz; m_bv_util.is_numeral(val, r_val, bv_sz); - mpq q = r_val.to_mpq(); + const mpq& q = r_val.to_mpq(); SASSERT(m_mpz_manager.is_one(q.denominator())); set_value(fd, q.numerator()); } @@ -630,7 +634,7 @@ public: if (m_bv_util.is_bv_sort(s)) return get_random_bv(s); else if (m_manager.is_bool(s)) - return get_random_bool(); + return m_mpz_manager.dup(get_random_bool()); else NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } @@ -653,9 +657,7 @@ public: TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { - mpz temp = m_zero; - set_value(it->m_value, temp); - m_mpz_manager.del(temp); + set_value(it->m_value, m_zero); } } @@ -931,7 +933,7 @@ public: rational q; if (!m_bv_util.is_numeral(n, q, bv_sz)) NOT_IMPLEMENTED_YET(); - mpq temp = q.to_mpq(); + const mpq& temp = q.to_mpq(); SASSERT(m_mpz_manager.is_one(temp.denominator())); m_mpz_manager.set(result, temp.numerator()); } @@ -1039,7 +1041,6 @@ public: unsigned pos = -1; if (m_ucb) { - value_score vscore; double max = -1.0; // Andreas: Commented things here might be used for track_unsat data structures as done in SLS for SAT. But seems to have no benefit. /* for (unsigned i = 0; i < m_where_false.size(); i++) { @@ -1048,7 +1049,7 @@ public: expr * e = as[i]; if (m_mpz_manager.neq(get_value(e), m_one)) { - vscore = m_scores.find(e); + value_score & vscore = m_scores.find(e); // Andreas: Select the assertion with the greatest ucb score. Potentially add some noise. // double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + m_ucb_noise * get_random_uint(8); diff --git a/src/util/buffer.h b/src/util/buffer.h index 503788fa0..c64e23d8b 100644 --- a/src/util/buffer.h +++ b/src/util/buffer.h @@ -149,6 +149,13 @@ public: new (m_buffer + m_pos) T(elem); m_pos++; } + + void push_back(T && elem) { + if (m_pos >= m_capacity) + expand(); + new (m_buffer + m_pos) T(std::move(elem)); + m_pos++; + } void pop_back() { if (CallDestructors) { diff --git a/src/util/hashtable.h b/src/util/hashtable.h index 020c47b2b..fa9fef180 100644 --- a/src/util/hashtable.h +++ b/src/util/hashtable.h @@ -54,7 +54,7 @@ public: bool is_used() const { return m_state == HT_USED; } T & get_data() { return m_data; } const T & get_data() const { return m_data; } - void set_data(const T & d) { m_data = d; m_state = HT_USED; } + void set_data(T && d) { m_data = std::move(d); m_state = HT_USED; } void set_hash(unsigned h) { m_hash = h; } void mark_as_deleted() { m_state = HT_DELETED; } void mark_as_free() { m_state = HT_FREE; } @@ -187,10 +187,42 @@ protected: } } + static void move_table(entry * source, unsigned source_capacity, entry * target, unsigned target_capacity) { + SASSERT(target_capacity >= source_capacity); + unsigned target_mask = target_capacity - 1; + entry * source_end = source + source_capacity; + entry * target_end = target + target_capacity; + for (entry * source_curr = source; source_curr != source_end; ++source_curr) { + if (source_curr->is_used()) { + unsigned hash = source_curr->get_hash(); + unsigned idx = hash & target_mask; + entry * target_begin = target + idx; + entry * target_curr = target_begin; + for (; target_curr != target_end; ++target_curr) { + SASSERT(!target_curr->is_deleted()); + if (target_curr->is_free()) { + *target_curr = std::move(*source_curr); + goto end; + } + } + for (target_curr = target; target_curr != target_begin; ++target_curr) { + SASSERT(!target_curr->is_deleted()); + if (target_curr->is_free()) { + *target_curr = std::move(*source_curr); + goto end; + } + } + UNREACHABLE(); + end: + ; + } + } + } + void expand_table() { unsigned new_capacity = m_capacity << 1; entry * new_table = alloc_table(new_capacity); - copy_table(m_table, m_capacity, new_table, new_capacity); + move_table(m_table, m_capacity, new_table, new_capacity); delete_table(); m_table = new_table; m_capacity = new_capacity; @@ -202,7 +234,7 @@ protected: if (memory::is_out_of_memory()) return; entry * new_table = alloc_table(m_capacity); - copy_table(m_table, m_capacity, new_table, m_capacity); + move_table(m_table, m_capacity, new_table, m_capacity); delete_table(); m_table = new_table; m_num_deleted = 0; @@ -321,7 +353,7 @@ public: #define INSERT_LOOP_BODY() { \ if (curr->is_used()) { \ if (curr->get_hash() == hash && equals(curr->get_data(), e)) { \ - curr->set_data(e); \ + curr->set_data(std::move(e)); \ return; \ } \ HS_CODE(m_st_collision++;); \ @@ -330,7 +362,7 @@ public: entry * new_entry; \ if (del_entry) { new_entry = del_entry; m_num_deleted--; } \ else { new_entry = curr; } \ - new_entry->set_data(e); \ + new_entry->set_data(std::move(e)); \ new_entry->set_hash(hash); \ m_size++; \ return; \ @@ -342,7 +374,7 @@ public: } \ } ((void) 0) - void insert(data const & e) { + void insert(data && e) { if ((m_size + m_num_deleted) << 2 > (m_capacity * 3)) { // if ((m_size + m_num_deleted) * 2 > (m_capacity)) { expand_table(); @@ -363,6 +395,11 @@ public: UNREACHABLE(); } + void insert(const data & e) { + data tmp(e); + insert(std::move(tmp)); + } + #define INSERT_LOOP_CORE_BODY() { \ if (curr->is_used()) { \ if (curr->get_hash() == hash && equals(curr->get_data(), e)) { \ @@ -375,7 +412,7 @@ public: entry * new_entry; \ if (del_entry) { new_entry = del_entry; m_num_deleted--; } \ else { new_entry = curr; } \ - new_entry->set_data(e); \ + new_entry->set_data(std::move(e)); \ new_entry->set_hash(hash); \ m_size++; \ et = new_entry; \ @@ -393,7 +430,7 @@ public: Return true if it is a new element, and false otherwise. Store the entry/slot of the table in et. */ - bool insert_if_not_there_core(data const & e, entry * & et) { + bool insert_if_not_there_core(data && e, entry * & et) { if ((m_size + m_num_deleted) << 2 > (m_capacity * 3)) { // if ((m_size + m_num_deleted) * 2 > (m_capacity)) { expand_table(); @@ -415,6 +452,11 @@ public: return 0; } + bool insert_if_not_there_core(const data & e, entry * & et) { + data temp(e); + return insert_if_not_there_core(std::move(temp), et); + } + /** \brief Insert the element e if it is not in the table. Return a reference to e or to an object identical to e diff --git a/src/util/mpq.h b/src/util/mpq.h index 5aa3ca083..b34e9afae 100644 --- a/src/util/mpq.h +++ b/src/util/mpq.h @@ -31,11 +31,10 @@ class mpq { public: mpq(int v):m_num(v), m_den(1) {} mpq():m_den(1) {} + mpq(mpq && other) noexcept : m_num(std::move(other.m_num)), m_den(std::move(other.m_den)) {} void swap(mpq & other) { m_num.swap(other.m_num); m_den.swap(other.m_den); } mpz const & numerator() const { return m_num; } mpz const & denominator() const { return m_den; } - - double get_double() const; }; inline void swap(mpq & m1, mpq & m2) { m1.swap(m2); } @@ -745,6 +744,12 @@ public: reset_denominator(a); } + mpq dup(const mpq & source) { + mpq temp; + set(temp, source); + return temp; + } + void swap(mpz & a, mpz & b) { mpz_manager::swap(a, b); } void swap(mpq & a, mpq & b) { diff --git a/src/util/mpz.h b/src/util/mpz.h index 7001b9a42..bdfbc8061 100644 --- a/src/util/mpz.h +++ b/src/util/mpz.h @@ -94,6 +94,9 @@ class mpz { public: mpz(int v):m_val(v), m_ptr(0) {} mpz():m_val(0), m_ptr(0) {} + mpz(mpz && other) noexcept : m_val(other.m_val), m_ptr(0) { + std::swap(m_val, other.m_val); + } void swap(mpz & other) { std::swap(m_val, other.m_val); std::swap(m_ptr, other.m_ptr); @@ -668,6 +671,12 @@ public: } } + void set(mpz & target, mpz && source) { + del(target); + target.m_val = source.m_val; + std::swap(target.m_ptr, source.m_ptr); + } + void set(mpz & a, int val) { del(a); a.m_val = val; @@ -700,6 +709,12 @@ public: void set(mpz & target, unsigned sz, digit_t const * digits); + mpz dup(const mpz & source) { + mpz temp; + set(temp, source); + return temp; + } + void reset(mpz & a) { del(a); a.m_val = 0; diff --git a/src/util/obj_hashtable.h b/src/util/obj_hashtable.h index 189d1e1a0..df279383b 100644 --- a/src/util/obj_hashtable.h +++ b/src/util/obj_hashtable.h @@ -69,6 +69,10 @@ public: m_key(k), m_value(v) { } + key_data(Key * k, Value && v) : + m_key(k), + m_value(std::move(v)) { + } Value const & get_value() const { return m_value; } Key & get_key () const { return *m_key; } unsigned hash() const { return m_key->hash(); } @@ -86,7 +90,7 @@ public: bool is_used() const { return m_data.m_key != reinterpret_cast(0) && m_data.m_key != reinterpret_cast(1); } key_data const & get_data() const { return m_data; } key_data & get_data() { return m_data; } - void set_data(key_data const & d) { m_data = d; } + void set_data(key_data && d) { m_data = std::move(d); } void set_hash(unsigned h) { SASSERT(h == m_data.hash()); } void mark_as_deleted() { m_data.m_key = reinterpret_cast(1); } void mark_as_free() { m_data.m_key = 0; } @@ -137,6 +141,10 @@ public: void insert(Key * const k, Value const & v) { m_table.insert(key_data(k, v)); } + + void insert(Key * const k, Value && v) { + m_table.insert(key_data(k, std::move(v))); + } key_data const & insert_if_not_there(Key * k, Value const & v) { return m_table.insert_if_not_there(key_data(k, v)); diff --git a/src/util/ref_vector.h b/src/util/ref_vector.h index 469183b76..9b7657fb2 100644 --- a/src/util/ref_vector.h +++ b/src/util/ref_vector.h @@ -63,7 +63,7 @@ public: void resize(unsigned sz) { if (sz < m_nodes.size()) dec_range_ref(m_nodes.begin() + sz, m_nodes.end()); - m_nodes.resize(sz, 0); + m_nodes.resize(sz); } void resize(unsigned sz, T * d) { @@ -80,7 +80,7 @@ public: void reserve(unsigned sz) { if (sz <= m_nodes.size()) return; - m_nodes.resize(sz, 0); + m_nodes.resize(sz); } void shrink(unsigned sz) { diff --git a/src/util/scoped_numeral_vector.h b/src/util/scoped_numeral_vector.h index fdf63bf35..cb9a6b4fd 100644 --- a/src/util/scoped_numeral_vector.h +++ b/src/util/scoped_numeral_vector.h @@ -63,8 +63,7 @@ public: unsigned old_sz = this->size(); if (sz <= old_sz) shrink(sz); - typename Manager::numeral zero(0); - svector::resize(sz, zero); + svector::resize(sz, 0); } }; diff --git a/src/util/util.h b/src/util/util.h index 1f753099c..f8c464197 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -322,7 +322,7 @@ bool compare_arrays(const T * array1, const T * array2, unsigned size) { template void force_ptr_array_size(T & v, unsigned sz) { if (sz > v.size()) { - v.resize(sz, 0); + v.resize(sz); } } diff --git a/src/util/vector.h b/src/util/vector.h index 2d499a900..c21d33bab 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -26,6 +26,7 @@ Revision History: #include "util/debug.h" #include +#include #include #include "util/memory_manager.h" #include "util/hash.h" @@ -74,9 +75,24 @@ class vector { if (new_capacity <= old_capacity || new_capacity_T <= old_capacity_T) { throw default_exception("Overflow encountered when expanding vector"); } - SZ *mem = (SZ*)memory::reallocate(reinterpret_cast(m_data)-2, new_capacity_T); + SZ *mem, *old_mem = reinterpret_cast(m_data) - 2; + if (std::is_trivially_copyable::value) { + mem = (SZ*)memory::reallocate(old_mem, new_capacity_T); + } else { + mem = (SZ*)memory::allocate(new_capacity_T); + } + auto old_data = m_data; + auto old_size = size(); *mem = new_capacity; m_data = reinterpret_cast(mem + 2); + if (!std::is_trivially_copyable::value) { + static_assert(std::is_move_constructible::value, ""); + int i = 0; + for (auto I = old_data; I != old_data + old_size; ++I) { + new (&m_data[i++]) T(std::move(*I)); + } + memory::deallocate(old_mem); + } } } @@ -148,6 +164,10 @@ public: SASSERT(size() == source.size()); } + vector(vector&& other) noexcept : m_data(0) { + std::swap(m_data, other.m_data); + } + vector(SZ s, T const * data): m_data(0) { for (SZ i = 0; i < s; i++) { @@ -179,6 +199,16 @@ public: return *this; } + vector & operator=(vector && source) { + if (this == &source) { + return *this; + } + destroy(); + m_data = 0; + std::swap(m_data, source.m_data); + return *this; + } + void reset() { if (m_data) { if (CallDestructors) { @@ -292,6 +322,11 @@ public: m_data[idx] = val; } + void set(SZ idx, T && val) { + SASSERT(idx < size()); + m_data[idx] = std::move(val); + } + T & back() { SASSERT(!empty()); return operator[](size() - 1); @@ -318,6 +353,14 @@ public: reinterpret_cast(m_data)[SIZE_IDX]++; } + void push_back(T && elem) { + if (m_data == 0 || reinterpret_cast(m_data)[SIZE_IDX] == reinterpret_cast(m_data)[CAPACITY_IDX]) { + expand_vector(); + } + new (m_data + reinterpret_cast(m_data)[SIZE_IDX]) T(std::move(elem)); + reinterpret_cast(m_data)[SIZE_IDX]++; + } + void insert(T const & elem) { push_back(elem); } @@ -357,7 +400,8 @@ public: } } - void resize(SZ s, T const & elem=T()) { + template + void resize(SZ s, Args args...) { SZ sz = size(); if (s <= sz) { shrink(s); return; } while (s > capacity()) { @@ -367,8 +411,23 @@ public: reinterpret_cast(m_data)[SIZE_IDX] = s; iterator it = m_data + sz; iterator end = m_data + s; - for(; it != end; ++it) { - new (it) T(elem); + for (; it != end; ++it) { + new (it) T(std::forward(args)); + } + } + + void resize(SZ s) { + SZ sz = size(); + if (s <= sz) { shrink(s); return; } + while (s > capacity()) { + expand_vector(); + } + SASSERT(m_data != 0); + reinterpret_cast(m_data)[SIZE_IDX] = s; + iterator it = m_data + sz; + iterator end = m_data + s; + for (; it != end; ++it) { + new (it) T(); } } @@ -439,10 +498,15 @@ public: return m_data[idx]; } - void reserve(SZ s, T const & d = T()) { + void reserve(SZ s, T const & d) { if (s > size()) resize(s, d); } + + void reserve(SZ s) { + if (s > size()) + resize(s); + } }; template @@ -452,7 +516,12 @@ public: ptr_vector(unsigned s):vector(s) {} ptr_vector(unsigned s, T * elem):vector(s, elem) {} ptr_vector(ptr_vector const & source):vector(source) {} + ptr_vector(ptr_vector && other) noexcept : vector(std::move(other)) {} ptr_vector(unsigned s, T * const * data):vector(s, const_cast(data)) {} + ptr_vector & operator=(ptr_vector const & source) { + vector::operator=(source); + return *this; + } }; template @@ -462,7 +531,12 @@ public: svector(SZ s):vector(s) {} svector(SZ s, T const & elem):vector(s, elem) {} svector(svector const & source):vector(source) {} + svector(svector && other) noexcept : vector(std::move(other)) {} svector(SZ s, T const * data):vector(s, data) {} + svector & operator=(svector const & source) { + vector::operator=(source); + return *this; + } }; typedef svector int_vector; @@ -494,23 +568,4 @@ struct vector_hash : public vector_hash_tpl > template struct svector_hash : public vector_hash_tpl > {}; -#include -// Specialize vector to be an instance of std::vector instead. -// This will catch any regression of issue #564 and #420. - -template <> -class vector : public std::vector { -public: - vector(vector const& other): std::vector(other) {} - vector(size_t sz, char const* s): std::vector(sz, s) {} - vector() {} - - void reset() { clear(); } - - -}; - - - #endif /* VECTOR_H_ */ - From 27e84c5ffcb770374de14cb09fa08a32c4d58744 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Wed, 11 Oct 2017 00:15:04 +0100 Subject: [PATCH 388/488] mpz.h: fix typo in previous commit (found by Nikolaj) --- src/util/mpz.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/mpz.h b/src/util/mpz.h index bdfbc8061..9933e4485 100644 --- a/src/util/mpz.h +++ b/src/util/mpz.h @@ -95,7 +95,7 @@ public: mpz(int v):m_val(v), m_ptr(0) {} mpz():m_val(0), m_ptr(0) {} mpz(mpz && other) noexcept : m_val(other.m_val), m_ptr(0) { - std::swap(m_val, other.m_val); + std::swap(m_ptr, other.m_ptr); } void swap(mpz & other) { std::swap(m_val, other.m_val); From d30a099cd0f9d57b9c3a5850b541b785e205bdd4 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Wed, 11 Oct 2017 02:43:13 +0100 Subject: [PATCH 389/488] fix crash in vector::expand() --- src/util/vector.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/vector.h b/src/util/vector.h index c21d33bab..03c450660 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -87,6 +87,7 @@ class vector { m_data = reinterpret_cast(mem + 2); if (!std::is_trivially_copyable::value) { static_assert(std::is_move_constructible::value, ""); + mem[1] = old_size; int i = 0; for (auto I = old_data; I != old_data + old_size; ++I) { new (&m_data[i++]) T(std::move(*I)); From 3cc6dd1cbdc194ebbc7025f5f819b30910f1da0c Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Thu, 12 Oct 2017 21:34:21 +0100 Subject: [PATCH 390/488] bv_decl_plugin: remove mem allocation --- src/ast/bv_decl_plugin.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index fcf9a9f8f..093d0f548 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -863,8 +863,7 @@ app * bv_util::mk_numeral(rational const & val, sort* s) const { } app * bv_util::mk_numeral(rational const & val, unsigned bv_size) const { - parameter p1(val); - parameter p[2] = { p1, parameter(static_cast(bv_size)) }; + parameter p[2] = { parameter(val), parameter(static_cast(bv_size)) }; return m_manager.mk_app(get_fid(), OP_BV_NUM, 2, p, 0, 0); } From b53d69be18044ac7bf378dc1b1a61bd4266cfcd1 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Fri, 13 Oct 2017 01:00:10 +0100 Subject: [PATCH 391/488] fpa_rewriter: remove a mpq copy --- src/ast/rewriter/fpa_rewriter.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 818336c75..ce14349b2 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -125,11 +125,10 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const const mpz & sm1 = m_fm.m_powers2(sbits - 1); const mpz & em1 = m_fm.m_powers2(ebits); - scoped_mpq q(mpqm); - mpqm.set(q, r1.to_mpq()); - SASSERT(mpzm.is_one(q.get().denominator())); + const mpq & q = r1.to_mpq(); + SASSERT(mpzm.is_one(q.denominator())); scoped_mpz z(mpzm); - z = q.get().numerator(); + z = q.numerator(); mpzm.rem(z, sm1, sig); mpzm.div(z, sm1, z); From d1c13f17b0922fa53f5d42adc847877de0b48a28 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Fri, 13 Oct 2017 01:07:04 +0100 Subject: [PATCH 392/488] remove noexcept since MSVC 2012 doest support it --- src/ast/ast.h | 2 +- src/math/simplex/sparse_matrix.h | 2 +- src/util/mpq.h | 2 +- src/util/mpz.h | 2 +- src/util/vector.h | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ast/ast.h b/src/ast/ast.h index 54f8f5e62..7e1645753 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -121,7 +121,7 @@ public: explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {} parameter(parameter const&); - parameter(parameter && other) noexcept : m_kind(other.m_kind) { + parameter(parameter && other) : m_kind(other.m_kind) { switch (other.m_kind) { case PARAM_INT: m_int = other.get_int(); break; case PARAM_AST: m_ast = other.get_ast(); break; diff --git a/src/math/simplex/sparse_matrix.h b/src/math/simplex/sparse_matrix.h index 63bbe9e78..4edbb2b9d 100644 --- a/src/math/simplex/sparse_matrix.h +++ b/src/math/simplex/sparse_matrix.h @@ -35,7 +35,7 @@ namespace simplex { struct row_entry { numeral m_coeff; var_t m_var; - row_entry(numeral && c, var_t v) noexcept : m_coeff(std::move(c)), m_var(v) {} + row_entry(numeral && c, var_t v) : m_coeff(std::move(c)), m_var(v) {} }; private: diff --git a/src/util/mpq.h b/src/util/mpq.h index b34e9afae..fd0ae13d4 100644 --- a/src/util/mpq.h +++ b/src/util/mpq.h @@ -31,7 +31,7 @@ class mpq { public: mpq(int v):m_num(v), m_den(1) {} mpq():m_den(1) {} - mpq(mpq && other) noexcept : m_num(std::move(other.m_num)), m_den(std::move(other.m_den)) {} + mpq(mpq && other) : m_num(std::move(other.m_num)), m_den(std::move(other.m_den)) {} void swap(mpq & other) { m_num.swap(other.m_num); m_den.swap(other.m_den); } mpz const & numerator() const { return m_num; } mpz const & denominator() const { return m_den; } diff --git a/src/util/mpz.h b/src/util/mpz.h index 9933e4485..f04430e17 100644 --- a/src/util/mpz.h +++ b/src/util/mpz.h @@ -94,7 +94,7 @@ class mpz { public: mpz(int v):m_val(v), m_ptr(0) {} mpz():m_val(0), m_ptr(0) {} - mpz(mpz && other) noexcept : m_val(other.m_val), m_ptr(0) { + mpz(mpz && other) : m_val(other.m_val), m_ptr(0) { std::swap(m_ptr, other.m_ptr); } void swap(mpz & other) { diff --git a/src/util/vector.h b/src/util/vector.h index 03c450660..a925792eb 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -165,7 +165,7 @@ public: SASSERT(size() == source.size()); } - vector(vector&& other) noexcept : m_data(0) { + vector(vector&& other) : m_data(0) { std::swap(m_data, other.m_data); } @@ -517,7 +517,7 @@ public: ptr_vector(unsigned s):vector(s) {} ptr_vector(unsigned s, T * elem):vector(s, elem) {} ptr_vector(ptr_vector const & source):vector(source) {} - ptr_vector(ptr_vector && other) noexcept : vector(std::move(other)) {} + ptr_vector(ptr_vector && other) : vector(std::move(other)) {} ptr_vector(unsigned s, T * const * data):vector(s, const_cast(data)) {} ptr_vector & operator=(ptr_vector const & source) { vector::operator=(source); @@ -532,7 +532,7 @@ public: svector(SZ s):vector(s) {} svector(SZ s, T const & elem):vector(s, elem) {} svector(svector const & source):vector(source) {} - svector(svector && other) noexcept : vector(std::move(other)) {} + svector(svector && other) : vector(std::move(other)) {} svector(SZ s, T const * data):vector(s, data) {} svector & operator=(svector const & source) { vector::operator=(source); From 468e0207f711bf50df8909f443c64ed21ad169de Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Fri, 13 Oct 2017 18:23:30 +0100 Subject: [PATCH 393/488] add move constructor to mpf --- src/util/mpf.cpp | 6 ------ src/util/mpf.h | 7 ++++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 3218419a9..9e309a726 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -40,12 +40,6 @@ mpf::mpf(unsigned _ebits, unsigned _sbits): set(ebits, sbits); } -mpf::mpf(mpf const & other) { - // It is safe if the mpz numbers are small. - // I need it for resize method in vector. - // UNREACHABLE(); -} - mpf::~mpf() { } diff --git a/src/util/mpf.h b/src/util/mpf.h index 8070768b2..e679be558 100644 --- a/src/util/mpf.h +++ b/src/util/mpf.h @@ -50,7 +50,12 @@ class mpf { public: mpf(); mpf(unsigned ebits, unsigned sbits); - mpf(mpf const & other); + mpf(mpf && other) : + ebits(other.ebits), + sbits(other.sbits), + sign(other.sign), + significand(std::move(other.significand)), + exponent(other.exponent) {} ~mpf(); unsigned get_ebits() const { return ebits; } unsigned get_sbits() const { return sbits; } From 912a729097e778998a6d78f7cce28187dbe5dca1 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sat, 14 Oct 2017 20:41:08 +0100 Subject: [PATCH 394/488] fix build of unit tests --- src/math/interval/interval.h | 2 +- src/math/interval/interval_def.h | 2 +- src/test/im_float_config.h | 6 --- src/test/interval.cpp | 78 +++++++++++++------------------- src/test/trigo.cpp | 17 +++---- src/util/f2n.h | 3 ++ 6 files changed, 43 insertions(+), 65 deletions(-) diff --git a/src/math/interval/interval.h b/src/math/interval/interval.h index bae644fac..db3c5a850 100644 --- a/src/math/interval/interval.h +++ b/src/math/interval/interval.h @@ -162,7 +162,7 @@ private: void checkpoint(); public: - interval_manager(reslimit& lim, C const & c); + interval_manager(reslimit& lim, C && c); ~interval_manager(); numeral_manager & m() const { return m_c.m(); } diff --git a/src/math/interval/interval_def.h b/src/math/interval/interval_def.h index e18d9edda..de3a5fa19 100644 --- a/src/math/interval/interval_def.h +++ b/src/math/interval/interval_def.h @@ -31,7 +31,7 @@ Revision History: // #define TRACE_NTH_ROOT template -interval_manager::interval_manager(reslimit& lim, C const & c): m_limit(lim), m_c(c) { +interval_manager::interval_manager(reslimit& lim, C && c): m_limit(lim), m_c(std::move(c)) { m().set(m_minus_one, -1); m().set(m_one, 1); m_pi_n = 0; diff --git a/src/test/im_float_config.h b/src/test/im_float_config.h index 436d9ecaf..3905358ea 100644 --- a/src/test/im_float_config.h +++ b/src/test/im_float_config.h @@ -63,10 +63,4 @@ public: numeral_manager & m() const { return const_cast(m_manager); } }; -template -inline void del_f_interval(im_float_config & cfg, typename im_float_config::interval & a) { - cfg.m().del(a.m_lower); - cfg.m().del(a.m_upper); -} - #endif diff --git a/src/test/interval.cpp b/src/test/interval.cpp index ba218c010..21b25a9be 100644 --- a/src/test/interval.cpp +++ b/src/test/interval.cpp @@ -125,7 +125,8 @@ static bool mk_interval(im_default_config & cfg, interval & a, bool l_inf, bool } #endif -static void mk_random_interval(im_default_config & cfg, interval & a, unsigned magnitude) { +template +static void mk_random_interval(T & cfg, interval & a, unsigned magnitude) { switch (rand()%3) { case 0: // Neg, Neg @@ -195,11 +196,6 @@ static void mk_random_interval(im_default_config & cfg, interval & a, unsigned m } } -static void del_interval(im_default_config & cfg, interval & a) { - cfg.m().del(a.m_lower); - cfg.m().del(a.m_upper); -} - #define BUFFER_SZ 256 static int g_problem_id = 0; static char g_buffer[BUFFER_SZ]; @@ -238,19 +234,18 @@ static void display_lemmas(unsynch_mpq_manager & nm, char const * result_term, static void tst_ ## NAME(unsigned N, unsigned magnitude) { \ reslimit rl; \ unsynch_mpq_manager nm; \ - im_default_config imc(nm); \ - interval_manager im(rl, imc); \ + interval_manager im(rl, nm); \ interval a, b, r; \ \ for (unsigned i = 0; i < N; i++) { \ - mk_random_interval(imc, a, magnitude); \ - mk_random_interval(imc, b, magnitude); \ + mk_random_interval(im, a, magnitude); \ + mk_random_interval(im, b, magnitude); \ interval_deps deps; \ im.NAME(a, b, r, deps); \ \ display_lemmas(nm, RES_TERM, a, b, r, deps); \ } \ - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); \ + im.del(a); im.del(b); im.del(r); \ } MK_BINARY(mul, "(* a b)"); @@ -260,56 +255,52 @@ MK_BINARY(sub, "(- a b)"); static void tst_neg(unsigned N, unsigned magnitude) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval a, b, r; for (unsigned i = 0; i < N; i++) { - mk_random_interval(imc, a, magnitude); + mk_random_interval(im, a, magnitude); interval_deps deps; im.neg(a, r, deps); display_lemmas(nm, "(- a)", a, b, r, deps); } - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); + im.del(a); im.del(b); im.del(r); } static void tst_pw_2(unsigned N, unsigned magnitude) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval a, b, r; for (unsigned i = 0; i < N; i++) { - mk_random_interval(imc, a, magnitude); + mk_random_interval(im, a, magnitude); interval_deps deps; im.power(a, 2, r, deps); display_lemmas(nm, "(* a a)", a, b, r, deps); } - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); + im.del(a); im.del(b); im.del(r); } static void tst_pw_3(unsigned N, unsigned magnitude) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval a, b, r; for (unsigned i = 0; i < N; i++) { - mk_random_interval(imc, a, magnitude); + mk_random_interval(im, a, magnitude); interval_deps deps; im.power(a, 3, r, deps); display_lemmas(nm, "(* a a a)", a, b, r, deps); } - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); + im.del(a); im.del(b); im.del(r); } static void tst_root_2(unsigned N, unsigned magnitude, unsigned precision) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval a, b, r; scoped_mpq p(nm); p = precision; @@ -317,7 +308,7 @@ static void tst_root_2(unsigned N, unsigned magnitude, unsigned precision) { unsigned i = 0; while (i < N) { - mk_random_interval(imc, a, magnitude); + mk_random_interval(im, a, magnitude); if (!im.lower_is_neg(a)) { i++; interval_deps deps; @@ -325,14 +316,13 @@ static void tst_root_2(unsigned N, unsigned magnitude, unsigned precision) { display_lemmas(nm, "(^ a (/ 1.0 2.0))", a, b, r, deps); } } - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); + im.del(a); im.del(b); im.del(r); } static void tst_root_3(unsigned N, unsigned magnitude, unsigned precision) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval a, b, r; scoped_mpq p(nm); p = precision; @@ -340,25 +330,24 @@ static void tst_root_3(unsigned N, unsigned magnitude, unsigned precision) { unsigned i = 0; while (i < N) { - mk_random_interval(imc, a, magnitude); + mk_random_interval(im, a, magnitude); i++; interval_deps deps; im.nth_root(a, 3, p, r, deps); display_lemmas(nm, "(^ a (/ 1.0 3.0))", a, b, r, deps); } - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); + im.del(a); im.del(b); im.del(r); } static void tst_inv(unsigned N, unsigned magnitude) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval a, b, r; for (unsigned i = 0; i < N; i++) { while (true) { - mk_random_interval(imc, a, magnitude); + mk_random_interval(im, a, magnitude); if (!im.contains_zero(a)) break; } @@ -366,20 +355,19 @@ static void tst_inv(unsigned N, unsigned magnitude) { im.inv(a, r, deps); display_lemmas(nm, "(/ 1 a)", a, b, r, deps); } - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); + im.del(a); im.del(b); im.del(r); } static void tst_div(unsigned N, unsigned magnitude) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval a, b, r; for (unsigned i = 0; i < N; i++) { - mk_random_interval(imc, a, magnitude); + mk_random_interval(im, a, magnitude); while (true) { - mk_random_interval(imc, b, magnitude); + mk_random_interval(im, b, magnitude); if (!im.contains_zero(b)) break; } @@ -387,7 +375,7 @@ static void tst_div(unsigned N, unsigned magnitude) { im.div(a, b, r, deps); display_lemmas(nm, "(/ a b)", a, b, r, deps); } - del_interval(imc, a); del_interval(imc, b); del_interval(imc, r); + im.del(a); im.del(b); im.del(r); } #include "test/im_float_config.h" @@ -396,8 +384,7 @@ static void tst_div(unsigned N, unsigned magnitude) { static void tst_float() { unsynch_mpq_manager qm; mpf_manager fm; - im_float_config ifc(fm); - interval_manager > im(ifc); + interval_manager > im(fm); im_float_config::interval a, b, c; scoped_mpq minus_one_third(qm), one_third(qm), two_third(qm), minus_two_third(qm); qm.set(minus_one_third, -1, 3); @@ -424,15 +411,14 @@ static void tst_float() { im.display(std::cout, c); std::cout << "\n"; - del_f_interval(ifc, a); del_f_interval(ifc, b); del_f_interval(ifc, c); + im.del(a); im.del(b); im.del(r); } #endif void tst_pi() { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); interval r; for (unsigned i = 0; i < 8; i++) { im.pi(i, r); @@ -440,7 +426,7 @@ void tst_pi() { nm.display_decimal(std::cout, im.upper(r), 32); std::cout << "\n"; ENSURE(nm.lt(im.lower(r), im.upper(r))); } - del_interval(imc, r); + im.del(r); } #if 0 diff --git a/src/test/trigo.cpp b/src/test/trigo.cpp index c1b73c423..d1b75c7fb 100644 --- a/src/test/trigo.cpp +++ b/src/test/trigo.cpp @@ -39,9 +39,8 @@ static void tst_sine_core(std::ostream & out, unsynch_mpq_manager & nm, interval static void tst_sine(std::ostream & out, unsigned N, unsigned k) { unsynch_mpq_manager nm; - im_default_config imc(nm); reslimit rl; - interval_manager im(rl, imc); + interval_manager im(rl, nm); scoped_mpq a(nm); nm.set(a, 0); tst_sine_core(out, nm, im, a, 1); @@ -67,8 +66,7 @@ static void tst_cosine_core(std::ostream & out, unsynch_mpq_manager & nm, interv static void tst_cosine(std::ostream & out, unsigned N, unsigned k) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); scoped_mpq a(nm); nm.set(a, 0); tst_cosine_core(out, nm, im, a, 1); @@ -100,8 +98,7 @@ template static void tst_float_sine(std::ostream & out, unsigned N, unsigned k) { reslimit rl; fmanager fm; - im_float_config ifc(fm, EBITS, SBITS); - interval_manager > im(rl, ifc); + interval_manager > im(rl, { fm, EBITS, SBITS }); _scoped_numeral a(fm); fm.set(a, EBITS, SBITS, static_cast(0)); tst_float_sine_core(out, fm, im, a, 1); @@ -136,8 +133,7 @@ static void tst_mpf_bug() { static void tst_e(std::ostream & out) { reslimit rl; unsynch_mpq_manager nm; - im_default_config imc(nm); - interval_manager im(rl, imc); + interval_manager im(rl, nm); im_default_config::interval r; for (unsigned i = 0; i < 64; i++) { im.e(i, r); @@ -152,8 +148,7 @@ static void tst_e_float(std::ostream & out) { reslimit rl; unsynch_mpq_manager qm; mpf_manager fm; - im_float_config ifc(fm); - interval_manager > im(rl, ifc); + interval_manager > im(rl, fm); scoped_mpq q(qm); im_float_config::interval r; for (unsigned i = 0; i < 64; i++) { @@ -161,7 +156,7 @@ static void tst_e_float(std::ostream & out) { out << fm.to_rational_string(im.lower(r)) << " <= E\n"; out << "E <= " << fm.to_rational_string(im.upper(r)) << "\n"; } - del_f_interval(ifc, r); + im.del(r); } void tst_trigo() { diff --git a/src/util/f2n.h b/src/util/f2n.h index e5e84f6f0..d55b21d3d 100644 --- a/src/util/f2n.h +++ b/src/util/f2n.h @@ -46,6 +46,9 @@ public: m_manager.set(m_one, ebits, sbits, 1); } + f2n(f2n && other) : m_manager(other.m_manager), m_mode(other.m_mode), m_ebits(other.m_ebits), m_sbits(other.m_sbits), + m_tmp1(std::move(other.m_tmp1)), m_one(std::move(other.m_one)) {} + ~f2n() { m().del(m_tmp1); m().del(m_one); From 6c2d0394acc8a20fbe4f2aeb2b30b134d86a94d9 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 15 Oct 2017 00:08:50 +0100 Subject: [PATCH 395/488] add move constructor to rational --- src/util/rational.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/rational.h b/src/util/rational.h index 803c562ad..392a1982b 100644 --- a/src/util/rational.h +++ b/src/util/rational.h @@ -41,6 +41,7 @@ public: rational() {} rational(rational const & r) { m().set(m_val, r.m_val); } + rational(rational && r) : m_val(std::move(r.m_val)) {} explicit rational(int n) { m().set(m_val, n); } From 29acec672ffdf5251bd6799406c6b12fdce255a0 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 15 Oct 2017 01:41:07 +0100 Subject: [PATCH 396/488] nnf: remove ast incref --- src/ast/normal_forms/nnf.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 247e9dea1..014568812 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -207,8 +207,8 @@ struct nnf::imp { unsigned m_new_child:1; unsigned m_cache_result:1; unsigned m_spos; // top of the result stack, when the frame was created. - frame(expr_ref& n, bool pol, bool in_q, bool cache_res, unsigned spos): - m_curr(n), + frame(expr_ref&& n, bool pol, bool in_q, bool cache_res, unsigned spos): + m_curr(std::move(n)), m_i(0), m_pol(pol), m_in_q(in_q), @@ -324,8 +324,7 @@ struct nnf::imp { } void push_frame(expr * t, bool pol, bool in_q, bool cache_res) { - expr_ref tr(t, m()); - m_frame_stack.push_back(frame(tr, pol, in_q, cache_res, m_result_stack.size())); + m_frame_stack.push_back(frame({ t, m() }, pol, in_q, cache_res, m_result_stack.size())); } static unsigned get_cache_idx(bool pol, bool in_q) { From e7f0f3b834f2b71d0fd9afa3296113199193f166 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 15 Oct 2017 03:41:34 +0100 Subject: [PATCH 397/488] add move constructor to obj_ref --- src/util/obj_ref.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/obj_ref.h b/src/util/obj_ref.h index 1aa562a8f..72762ea5b 100644 --- a/src/util/obj_ref.h +++ b/src/util/obj_ref.h @@ -53,6 +53,10 @@ public: inc_ref(); } + obj_ref(obj_ref && other) : m_obj(0), m_manager(other.m_manager) { + std::swap(m_obj, other.m_obj); + } + ~obj_ref() { dec_ref(); } TManager & get_manager() const { return m_manager; } From d18e975a492cdd45ad7aad59831148b02b0c9862 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 15 Oct 2017 03:52:11 +0100 Subject: [PATCH 398/488] vector: make expand_vector() less prone to mem leaks by calling the destructors after move --- src/util/vector.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/vector.h b/src/util/vector.h index a925792eb..27de49c44 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -91,6 +91,7 @@ class vector { int i = 0; for (auto I = old_data; I != old_data + old_size; ++I) { new (&m_data[i++]) T(std::move(*I)); + I->~T(); } memory::deallocate(old_mem); } From 82b25a0608d55616c2df365b7af19f4e21a0bd9c Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 15 Oct 2017 05:31:28 +0100 Subject: [PATCH 399/488] add move constructor to watch_list --- src/smt/watch_list.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/smt/watch_list.h b/src/smt/watch_list.h index 19d3f20a8..1cc29da5a 100644 --- a/src/smt/watch_list.h +++ b/src/smt/watch_list.h @@ -85,6 +85,10 @@ namespace smt { watch_list(): m_data(0) { } + + watch_list(watch_list && other) : m_data(0) { + std::swap(m_data, other.m_data); + } ~watch_list() { destroy(); From 6cefb700ac559af28477e49f3b5a17dae0e3a602 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 15 Oct 2017 19:21:02 +0100 Subject: [PATCH 400/488] add move constructor to ref_vector --- src/util/ref_vector.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/ref_vector.h b/src/util/ref_vector.h index 9b7657fb2..f340d8886 100644 --- a/src/util/ref_vector.h +++ b/src/util/ref_vector.h @@ -45,6 +45,10 @@ public: typedef T * data; ref_vector_core(Ref const & r = Ref()):Ref(r) {} + + ref_vector_core(ref_vector_core && other) : + Ref(std::move(other)), + m_nodes(std::move(other.m_nodes)) {} ~ref_vector_core() { dec_range_ref(m_nodes.begin(), m_nodes.end()); @@ -207,6 +211,8 @@ public: this->append(other); } + ref_vector(ref_vector && other) : super(std::move(other)) {} + ref_vector(TManager & m, unsigned sz, T * const * data): super(ref_manager_wrapper(m)) { this->append(sz, data); From 2905bdebefe30112556e2f8f9cfd68d080094c48 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 15 Oct 2017 23:36:00 +0100 Subject: [PATCH 401/488] make vector friendly to gcc < 5 --- src/util/vector.h | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/util/vector.h b/src/util/vector.h index 27de49c44..f5792a5d3 100644 --- a/src/util/vector.h +++ b/src/util/vector.h @@ -76,25 +76,26 @@ class vector { throw default_exception("Overflow encountered when expanding vector"); } SZ *mem, *old_mem = reinterpret_cast(m_data) - 2; +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 + if (__has_trivial_copy(T)) { +#else if (std::is_trivially_copyable::value) { +#endif mem = (SZ*)memory::reallocate(old_mem, new_capacity_T); + m_data = reinterpret_cast(mem + 2); } else { mem = (SZ*)memory::allocate(new_capacity_T); - } - auto old_data = m_data; - auto old_size = size(); - *mem = new_capacity; - m_data = reinterpret_cast(mem + 2); - if (!std::is_trivially_copyable::value) { - static_assert(std::is_move_constructible::value, ""); + auto old_data = m_data; + auto old_size = size(); mem[1] = old_size; - int i = 0; - for (auto I = old_data; I != old_data + old_size; ++I) { - new (&m_data[i++]) T(std::move(*I)); - I->~T(); + m_data = reinterpret_cast(mem + 2); + for (unsigned i = 0; i < old_size; ++i) { + new (&m_data[i]) T(std::move(old_data[i])); + old_data[i].~T(); } memory::deallocate(old_mem); } + *mem = new_capacity; } } From b63754e3624c0978e3d8be2d500a6a1ab978e859 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 15 Oct 2017 21:16:54 -0700 Subject: [PATCH 402/488] adding explicit assignment for auto-generated function. Signed-off-by: Nikolaj Bjorner --- src/tactic/sls/sls_tracker.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index b4969f433..15f06f096 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -55,6 +55,10 @@ class sls_tracker { this->~value_score(); new (this) value_score(std::move(other)); } + value_score& operator=(value_score& other) { + UNREACHABLE(); + return *this; + } unsynch_mpz_manager * m; mpz value; double score; From 64ee9f168df650537c6264c1c4e6c16dd315966d Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 12:26:35 +0100 Subject: [PATCH 403/488] [TravisCI] Add ASan/LSan/UBSan suppression files and use them in CI. --- contrib/ci/Dockerfiles/z3_build.Dockerfile | 9 ++++++++- contrib/ci/scripts/sanitizer_env.sh | 19 +++++++++++++++++++ contrib/ci/scripts/test_z3_examples_cmake.sh | 3 +++ contrib/ci/scripts/test_z3_system_tests.sh | 3 +++ .../ci/scripts/test_z3_unit_tests_cmake.sh | 3 +++ contrib/suppressions/README.md | 7 +++++++ contrib/suppressions/maintainers.txt | 3 +++ contrib/suppressions/sanitizers/README.md | 4 ++++ contrib/suppressions/sanitizers/asan.txt | 1 + contrib/suppressions/sanitizers/lsan.txt | 1 + contrib/suppressions/sanitizers/ubsan.txt | 1 + 11 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 contrib/ci/scripts/sanitizer_env.sh create mode 100644 contrib/suppressions/README.md create mode 100644 contrib/suppressions/maintainers.txt create mode 100644 contrib/suppressions/sanitizers/README.md create mode 100644 contrib/suppressions/sanitizers/asan.txt create mode 100644 contrib/suppressions/sanitizers/lsan.txt create mode 100644 contrib/suppressions/sanitizers/ubsan.txt diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 07504e6b9..65cf08087 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -62,7 +62,8 @@ ENV \ # Build Z3 RUN mkdir -p "${Z3_SRC_DIR}" && \ - mkdir -p "${Z3_SRC_DIR}/contrib/ci/scripts" + mkdir -p "${Z3_SRC_DIR}/contrib/ci/scripts" && \ + mkdir -p "${Z3_SRC_DIR}/contrib/ci/suppressions/sanitizers" # Deliberately leave out `contrib` ADD /cmake ${Z3_SRC_DIR}/cmake/ ADD /doc ${Z3_SRC_DIR}/doc/ @@ -89,7 +90,13 @@ RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_docs.sh # Test examples ADD \ /contrib/ci/scripts/test_z3_examples_cmake.sh \ + /contrib/ci/scripts/sanitizer_env.sh \ ${Z3_SRC_DIR}/contrib/ci/scripts/ +ADD \ + /contrib/suppressions/sanitizers/asan.txt \ + /contrib/suppressions/sanitizers/lsan.txt \ + /contrib/suppressions/sanitizers/ubsan.txt \ + ${Z3_SRC_DIR}/contrib/suppressions/sanitizers/ RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_examples_cmake.sh # Run unit tests diff --git a/contrib/ci/scripts/sanitizer_env.sh b/contrib/ci/scripts/sanitizer_env.sh new file mode 100644 index 000000000..e9af255d3 --- /dev/null +++ b/contrib/ci/scripts/sanitizer_env.sh @@ -0,0 +1,19 @@ +# This script is intended to be included by other +# scripts and should not be executed directly + +: ${Z3_SRC_DIR?"Z3_SRC_DIR must be specified"} +: ${ASAN_BUILD?"ASAN_BUILD must be specified"} +: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"} + +if [ "X${ASAN_BUILD}" = "X1" ]; then + # Use suppression files + export LSAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/lsan.txt" + export ASAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt" +fi + +if [ "X${UBSAN_BUILD}" = "X1" ]; then + # `halt_on_error=1,abort_on_error=1` means that on the first UBSan error + # the program will terminate by calling `abort(). Without this UBSan will + # allow execution to continue. We also use a suppression file. + export UBSAN_OPTIONS="halt_on_error=1,abort_on_error=1,print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/ubsan.txt" +fi diff --git a/contrib/ci/scripts/test_z3_examples_cmake.sh b/contrib/ci/scripts/test_z3_examples_cmake.sh index 2eda3de7b..1b8f988a2 100755 --- a/contrib/ci/scripts/test_z3_examples_cmake.sh +++ b/contrib/ci/scripts/test_z3_examples_cmake.sh @@ -21,6 +21,9 @@ source ${SCRIPT_DIR}/set_compiler_flags.sh # Set CMake generator args source ${SCRIPT_DIR}/set_generator_args.sh +# Sanitizer environment variables +source ${SCRIPT_DIR}/sanitizer_env.sh + cd "${Z3_BUILD_DIR}" # Build and run C example diff --git a/contrib/ci/scripts/test_z3_system_tests.sh b/contrib/ci/scripts/test_z3_system_tests.sh index dfb1084a4..d61a0ef02 100755 --- a/contrib/ci/scripts/test_z3_system_tests.sh +++ b/contrib/ci/scripts/test_z3_system_tests.sh @@ -16,6 +16,9 @@ if [ "X${RUN_SYSTEM_TESTS}" != "X1" ]; then exit 0 fi +# Sanitizer environment variables +source ${SCRIPT_DIR}/sanitizer_env.sh + Z3_EXE="${Z3_BUILD_DIR}/z3" Z3_LIB_DIR="${Z3_BUILD_DIR}" diff --git a/contrib/ci/scripts/test_z3_unit_tests_cmake.sh b/contrib/ci/scripts/test_z3_unit_tests_cmake.sh index e1c927f58..60c29556b 100755 --- a/contrib/ci/scripts/test_z3_unit_tests_cmake.sh +++ b/contrib/ci/scripts/test_z3_unit_tests_cmake.sh @@ -13,6 +13,9 @@ set -o pipefail # Set CMake generator args source ${SCRIPT_DIR}/set_generator_args.sh +# Sanitizer environment variables +source ${SCRIPT_DIR}/sanitizer_env.sh + cd "${Z3_BUILD_DIR}" function build_unit_tests() { diff --git a/contrib/suppressions/README.md b/contrib/suppressions/README.md new file mode 100644 index 000000000..90df39084 --- /dev/null +++ b/contrib/suppressions/README.md @@ -0,0 +1,7 @@ +# Suppression files + +This directory contains suppression files used by various +program analysis tools. + +Suppression files tell a program analysis tool to suppress +various warnings/errors. diff --git a/contrib/suppressions/maintainers.txt b/contrib/suppressions/maintainers.txt new file mode 100644 index 000000000..caa6798c6 --- /dev/null +++ b/contrib/suppressions/maintainers.txt @@ -0,0 +1,3 @@ +# Maintainers + +- Dan Liew (@delcypher) diff --git a/contrib/suppressions/sanitizers/README.md b/contrib/suppressions/sanitizers/README.md new file mode 100644 index 000000000..f76f920b2 --- /dev/null +++ b/contrib/suppressions/sanitizers/README.md @@ -0,0 +1,4 @@ +# Sanitizer supression files + +This directory contains files used to suppress +ASan/LSan/UBSan warnings/errors. diff --git a/contrib/suppressions/sanitizers/asan.txt b/contrib/suppressions/sanitizers/asan.txt new file mode 100644 index 000000000..f058adfe2 --- /dev/null +++ b/contrib/suppressions/sanitizers/asan.txt @@ -0,0 +1 @@ +# AddressSanitizer suppression file diff --git a/contrib/suppressions/sanitizers/lsan.txt b/contrib/suppressions/sanitizers/lsan.txt new file mode 100644 index 000000000..a4ce0881a --- /dev/null +++ b/contrib/suppressions/sanitizers/lsan.txt @@ -0,0 +1 @@ +# LeakSanitizer suppression file diff --git a/contrib/suppressions/sanitizers/ubsan.txt b/contrib/suppressions/sanitizers/ubsan.txt new file mode 100644 index 000000000..8feef305f --- /dev/null +++ b/contrib/suppressions/sanitizers/ubsan.txt @@ -0,0 +1 @@ +# UndefinedBehavior sanitizer suppression file From a9fcfc531bda243b7b7cf30f2d6591d6430ac8b6 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 15:25:41 +0100 Subject: [PATCH 404/488] [TravisCI][CMake] Add `Z3_C_EXAMPLES_FORCE_CXX_LINKER` CMake option and propagate its value into the C API examples. This flag forces the C API examples to use the C++ compiler as the linker rather than the C compiler. This a workaround to avoid linking errors when building with UBSan. --- README-CMake.md | 1 + contrib/ci/scripts/build_z3_cmake.sh | 11 +++++++++++ examples/CMakeLists.txt | 21 +++++++++++++++++++-- examples/c/CMakeLists.txt | 11 +++++++++++ examples/maxsat/CMakeLists.txt | 10 ++++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/README-CMake.md b/README-CMake.md index 605c14818..0d323e08f 100644 --- a/README-CMake.md +++ b/README-CMake.md @@ -270,6 +270,7 @@ The following useful options can be passed to CMake whilst configuring. * ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature. * ``WARNINGS_AS_ERRORS`` - STRING. If set to ``TRUE`` compiler warnings will be treated as errors. If set to ``False`` compiler warnings will not be treated as errors. If set to ``SERIOUS_ONLY`` a subset of compiler warnings will be treated as errors. +* ``Z3_C_EXAMPLES_FORCE_CXX_LINKER`` - BOOL. If set to ``TRUE`` the C API examples will request that the C++ linker is used rather than the C linker. On the command line these can be passed to ``cmake`` using the ``-D`` option. In ``ccmake`` and ``cmake-gui`` these can be set in the user interface. diff --git a/contrib/ci/scripts/build_z3_cmake.sh b/contrib/ci/scripts/build_z3_cmake.sh index 76fd0fb84..c1014d5d5 100755 --- a/contrib/ci/scripts/build_z3_cmake.sh +++ b/contrib/ci/scripts/build_z3_cmake.sh @@ -22,6 +22,7 @@ set -o pipefail : ${USE_LTO?"USE_LTO must be specified"} : ${Z3_INSTALL_PREFIX?"Z3_INSTALL_PREFIX must be specified"} : ${Z3_WARNINGS_AS_ERRORS?"Z3_WARNINGS_AS_ERRORS must be specified"} +: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"} ADDITIONAL_Z3_OPTS=() @@ -105,6 +106,16 @@ fi # Set compiler flags source ${SCRIPT_DIR}/set_compiler_flags.sh +if [ "X${UBSAN_BUILD}" = "X1" ]; then + # HACK: When building with UBSan the C++ linker + # must be used to avoid the following linker errors. + # undefined reference to `__ubsan_vptr_type_cache' + # undefined reference to `__ubsan_handle_dynamic_type_cache_miss' + ADDITIONAL_Z3_OPTS+=( \ + '-DZ3_C_EXAMPLES_FORCE_CXX_LINKER=ON' \ + ) +fi + # Sanity check if [ ! -e "${Z3_SRC_DIR}/CMakeLists.txt" ]; then echo "Z3_SRC_DIR is invalid" diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ba7f6ee59..338d2e4bb 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -7,6 +7,19 @@ else() set(EXTERNAL_PROJECT_BUILD_ALWAYS_ARG "") endif() +option(Z3_C_EXAMPLES_FORCE_CXX_LINKER + "Force C++ linker when building C example projects" OFF) + +if (Z3_C_EXAMPLES_FORCE_CXX_LINKER) + # HACK: This is a workaround for UBSan. + message(STATUS "Forcing C++ linker to be used when building example C projects") + set(EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG + "-DFORCE_CXX_LINKER=ON" + ) +else() + set(EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG "") +endif() + ################################################################################ # Build example project using libz3's C API as an external project ################################################################################ @@ -14,7 +27,9 @@ ExternalProject_Add(c_example DEPENDS libz3 # Configure step SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c" - CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" + CMAKE_ARGS + "-DZ3_DIR=${CMAKE_BINARY_DIR}" + "${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}" # Build step ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_example_build_dir" @@ -30,7 +45,9 @@ ExternalProject_Add(c_maxsat_example DEPENDS libz3 # Configure step SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/maxsat" - CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" + CMAKE_ARGS + "-DZ3_DIR=${CMAKE_BINARY_DIR}" + "${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}" # Build step ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_maxsat_example_build_dir" diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index dd8fa6328..bac08e460 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -22,6 +22,17 @@ message(STATUS "Found Z3 ${Z3_VERSION_STRING}") message(STATUS "Z3_DIR: ${Z3_DIR}") add_executable(c_example test_capi.c) + +option(FORCE_CXX_LINKER "Force linker with C++ linker" OFF) +if (FORCE_CXX_LINKER) + # This is a hack for avoiding UBSan linking errors + message(STATUS "Forcing use of C++ linker") + set_target_properties(c_example + PROPERTIES + LINKER_LANGUAGE CXX + ) +endif() + target_include_directories(c_example PRIVATE ${Z3_C_INCLUDE_DIRS}) target_link_libraries(c_example PRIVATE ${Z3_LIBRARIES}) diff --git a/examples/maxsat/CMakeLists.txt b/examples/maxsat/CMakeLists.txt index b48e167ea..019243ecf 100644 --- a/examples/maxsat/CMakeLists.txt +++ b/examples/maxsat/CMakeLists.txt @@ -25,6 +25,16 @@ add_executable(c_maxsat_example maxsat.c) target_include_directories(c_maxsat_example PRIVATE ${Z3_C_INCLUDE_DIRS}) target_link_libraries(c_maxsat_example PRIVATE ${Z3_LIBRARIES}) +option(FORCE_CXX_LINKER "Force linker with C++ linker" OFF) +if (FORCE_CXX_LINKER) + # This is a hack for avoiding UBSan linking errors + message(STATUS "Forcing use of C++ linker") + set_target_properties(c_maxsat_example + PROPERTIES + LINKER_LANGUAGE CXX + ) +endif() + if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows") # On Windows we need to copy the Z3 libraries # into the same directory as the executable From f15766baee334b2d045e72b392712ef133c28c3a Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 15:56:43 +0100 Subject: [PATCH 405/488] [TravisCI] Don't run the non-native example when building with UBSan. This a workaround. Right now `libz3` gets linked against a static UBSan runtime which means none of the non-native language bindings (e.g. python) can load `libz3` due to undefined symbols. We need to link `libz3` against a shared UBSan runtime to fix this. --- contrib/ci/scripts/test_z3_examples_cmake.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contrib/ci/scripts/test_z3_examples_cmake.sh b/contrib/ci/scripts/test_z3_examples_cmake.sh index 1b8f988a2..c188dbcf4 100755 --- a/contrib/ci/scripts/test_z3_examples_cmake.sh +++ b/contrib/ci/scripts/test_z3_examples_cmake.sh @@ -14,6 +14,7 @@ set -o pipefail : ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"} : ${DOTNET_BINDINGS?"DOTNET_BINDINGS must be specified"} : ${JAVA_BINDINGS?"JAVA_BINDINGS must be specified"} +: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"} # Set compiler flags source ${SCRIPT_DIR}/set_compiler_flags.sh @@ -45,6 +46,14 @@ run_quiet \ examples/c_maxsat_example_build_dir/c_maxsat_example \ ${Z3_SRC_DIR}/examples/maxsat/ex.smt +if [ "X${UBSAN_BUILD}" = "X1" ]; then + # FIXME: We really need libz3 to link against a shared UBSan runtime. + # Right now we link against the static runtime which breaks all the + # non-native language bindings. + echo "FIXME: Can't run other examples when building with UBSan" + exit 0 +fi + if [ "X${PYTHON_BINDINGS}" = "X1" ]; then # Run python examples From fb3d4cfed9970e44712a3ee580e6152f7f17f966 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 16:13:57 +0100 Subject: [PATCH 406/488] [TravisCI] Add a UBSan configuration --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 81ddefb8b..9584d3869 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,9 @@ env: ############################################################################### # Ubuntu 16.04 LTS ############################################################################### + # 64-bit UBSan build + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo UBSAN_BUILD=1 + # 64-bit GCC 5.4 RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo # 64-bit Clang 3.9 RelWithDebInfo From f756bf6c86e6ea91aacbcc05b9cb0fa75bdcdef1 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 16:27:31 +0100 Subject: [PATCH 407/488] [TravisCI] Fix undefined SCRIPT_DIR variable --- contrib/ci/scripts/test_z3_system_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/ci/scripts/test_z3_system_tests.sh b/contrib/ci/scripts/test_z3_system_tests.sh index d61a0ef02..1b6433806 100755 --- a/contrib/ci/scripts/test_z3_system_tests.sh +++ b/contrib/ci/scripts/test_z3_system_tests.sh @@ -17,6 +17,7 @@ if [ "X${RUN_SYSTEM_TESTS}" != "X1" ]; then fi # Sanitizer environment variables +SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )" source ${SCRIPT_DIR}/sanitizer_env.sh Z3_EXE="${Z3_BUILD_DIR}/z3" From 9455391f1f60d0f4ff958dd95fb0f74cbe399ad8 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 16:46:26 +0100 Subject: [PATCH 408/488] [TravisCI] Don't run the python binding system tests when building with UBSan. This is a workaround. We can't fix this unless we build libz3 with a shared UBSan runtime. --- contrib/ci/scripts/test_z3_system_tests.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/contrib/ci/scripts/test_z3_system_tests.sh b/contrib/ci/scripts/test_z3_system_tests.sh index 1b6433806..71ecf2a1e 100755 --- a/contrib/ci/scripts/test_z3_system_tests.sh +++ b/contrib/ci/scripts/test_z3_system_tests.sh @@ -10,6 +10,7 @@ set -o pipefail : ${PYTHON_BINDINGS?"PYTHON_BINDINGS must be specified"} : ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"} : ${Z3_SYSTEM_TEST_DIR?"Z3_SYSTEM_TEST_DIR must be specified"} +: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"} if [ "X${RUN_SYSTEM_TESTS}" != "X1" ]; then echo "Skipping system tests" @@ -52,7 +53,13 @@ fi if [ "X${PYTHON_BINDINGS}" = "X1" ]; then # Run python binding tests - ${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/ + if [ "X${UBSAN_BUILD}" = "X1" ]; then + # FIXME: We need to build libz3 with a shared UBSan runtime for the bindings + # to work. + echo "FIXME: Skipping python binding tests when building with UBSan" + else + ${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/ + fi fi # FIXME: Run `scripts/test_cs.py` once it has been modified to support mono From 71dcec311349e37ef5192c331174ab4f7bcb853d Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 16:48:12 +0100 Subject: [PATCH 409/488] [UBSan] Update UBSan suppression file to suppress all undefined behaviour I have observed running in CI. --- contrib/suppressions/sanitizers/ubsan.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/contrib/suppressions/sanitizers/ubsan.txt b/contrib/suppressions/sanitizers/ubsan.txt index 8feef305f..6ceacd400 100644 --- a/contrib/suppressions/sanitizers/ubsan.txt +++ b/contrib/suppressions/sanitizers/ubsan.txt @@ -1 +1,20 @@ # UndefinedBehavior sanitizer suppression file +# FIXME: UBSan doesn't usually have false positives so we need to fix all of these! + +# Occurs when running C API example (`interpolation_example`) +# See https://github.com/Z3Prover/z3/issues/1286 +null:iz3mgr.h + +# Occurs when running C++ API example +# See https://github.com/Z3Prover/z3/issues/1287 +function:api_context.cpp + +# Occurs when running tptp example +# See https://github.com/Z3Prover/z3/issues/964 +null:rational.h +null:mpq.h + +# Occurs when running `test-z3 /a` +# See https://github.com/Z3Prover/z3/issues/1288 +shift-exponent:tbv.cpp +signed-integer-overflow:mpz.cpp From 4db5980a234802db1c379f3358230631636edf08 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 19:01:20 +0100 Subject: [PATCH 410/488] [TravisCI] Fix getting proper stack traces for ASan/LSan. The `llvm-symbolizer` tool needs to be installed and ASan/LSan needs to be told where to find it. --- contrib/ci/Dockerfiles/z3_base_ubuntu32_16.04.Dockerfile | 3 ++- contrib/ci/Dockerfiles/z3_base_ubuntu_14.04.Dockerfile | 3 ++- contrib/ci/Dockerfiles/z3_base_ubuntu_16.04.Dockerfile | 3 ++- contrib/ci/scripts/sanitizer_env.sh | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/contrib/ci/Dockerfiles/z3_base_ubuntu32_16.04.Dockerfile b/contrib/ci/Dockerfiles/z3_base_ubuntu32_16.04.Dockerfile index d8a32edea..87e3c8d67 100644 --- a/contrib/ci/Dockerfiles/z3_base_ubuntu32_16.04.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_base_ubuntu32_16.04.Dockerfile @@ -30,6 +30,7 @@ RUN apt-get update && \ libgomp1 \ libomp5 \ libomp-dev \ + llvm-3.9 \ make \ mono-devel \ ninja-build \ @@ -47,4 +48,4 @@ RUN useradd -m user && \ echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers USER user WORKDIR /home/user - +ENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.9/bin/llvm-symbolizer diff --git a/contrib/ci/Dockerfiles/z3_base_ubuntu_14.04.Dockerfile b/contrib/ci/Dockerfiles/z3_base_ubuntu_14.04.Dockerfile index c28e59e97..c963ce255 100644 --- a/contrib/ci/Dockerfiles/z3_base_ubuntu_14.04.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_base_ubuntu_14.04.Dockerfile @@ -16,6 +16,7 @@ RUN apt-get update && \ libgmp-dev \ libgomp1 \ lib32gomp1 \ + llvm-3.9 \ make \ mono-devel \ ninja-build \ @@ -32,4 +33,4 @@ RUN useradd -m user && \ echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers USER user WORKDIR /home/user - +ENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.9/bin/llvm-symbolizer diff --git a/contrib/ci/Dockerfiles/z3_base_ubuntu_16.04.Dockerfile b/contrib/ci/Dockerfiles/z3_base_ubuntu_16.04.Dockerfile index 98a5a3e09..08686e275 100644 --- a/contrib/ci/Dockerfiles/z3_base_ubuntu_16.04.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_base_ubuntu_16.04.Dockerfile @@ -18,6 +18,7 @@ RUN apt-get update && \ libgomp1 \ libomp5 \ libomp-dev \ + llvm-3.9 \ make \ mono-devel \ ninja-build \ @@ -35,4 +36,4 @@ RUN useradd -m user && \ echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers USER user WORKDIR /home/user - +ENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.9/bin/llvm-symbolizer diff --git a/contrib/ci/scripts/sanitizer_env.sh b/contrib/ci/scripts/sanitizer_env.sh index e9af255d3..3b1ff7297 100644 --- a/contrib/ci/scripts/sanitizer_env.sh +++ b/contrib/ci/scripts/sanitizer_env.sh @@ -9,6 +9,7 @@ if [ "X${ASAN_BUILD}" = "X1" ]; then # Use suppression files export LSAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/lsan.txt" export ASAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt" + : ${ASAN_SYMBOLIZER_PATH?"ASAN_SYMBOLIZER_PATH must be specified"} fi if [ "X${UBSAN_BUILD}" = "X1" ]; then From 157c8064e8f867c134c3979fd574264cf0c990aa Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 19:06:57 +0100 Subject: [PATCH 411/488] [CMake] When building C/C++ API examples use the same build type as Z3 if doing a single configuration build. --- examples/CMakeLists.txt | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 338d2e4bb..6c50320ed 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -20,6 +20,17 @@ else() set(EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG "") endif() +if (DEFINED CMAKE_CONFIGURATION_TYPES) + message(WARNING + "Cannot set built type of external project when building with a " + "multi-configuration generator") + set(EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG "") +else() + set(EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG + "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}" + ) +endif() + ################################################################################ # Build example project using libz3's C API as an external project ################################################################################ @@ -30,6 +41,7 @@ ExternalProject_Add(c_example CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" "${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}" + "${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}" # Build step ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_example_build_dir" @@ -48,6 +60,7 @@ ExternalProject_Add(c_maxsat_example CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" "${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}" + "${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}" # Build step ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_maxsat_example_build_dir" @@ -64,7 +77,9 @@ ExternalProject_Add(cpp_example DEPENDS libz3 # Configure step SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c++" - CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" + CMAKE_ARGS + "-DZ3_DIR=${CMAKE_BINARY_DIR}" + "${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}" # Build step ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpp_example_build_dir" @@ -80,7 +95,9 @@ ExternalProject_Add(z3_tptp5 DEPENDS libz3 # Configure step SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tptp" - CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" + CMAKE_ARGS + "-DZ3_DIR=${CMAKE_BINARY_DIR}" + "${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}" # Build step ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/tptp_build_dir" From 11f7298c52f2b41eb64775d419f17b4c6333bcf4 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 19:52:25 +0100 Subject: [PATCH 412/488] [TravisCI] Add ASan configuration --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9584d3869..bf69573aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,8 +17,13 @@ env: ############################################################################### # Ubuntu 16.04 LTS ############################################################################### + # FIXME: We should probably do unoptimized build to avoid the compiler's + # optimizer removing bad behaviour. However we can't run the unit tests + # if we do a Debug build because they are too slow. # 64-bit UBSan build - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo UBSAN_BUILD=1 + # 64-bit ASan build + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo ASAN_BUILD=1 # 64-bit GCC 5.4 RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo From 38d9e2df8489a16470239369cfc41f313446b755 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 20:02:25 +0100 Subject: [PATCH 413/488] [TravisCI] Make ASan/UBSan configuration a debug build. --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index bf69573aa..534aeacf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,13 +17,11 @@ env: ############################################################################### # Ubuntu 16.04 LTS ############################################################################### - # FIXME: We should probably do unoptimized build to avoid the compiler's - # optimizer removing bad behaviour. However we can't run the unit tests - # if we do a Debug build because they are too slow. - # 64-bit UBSan build - - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo UBSAN_BUILD=1 - # 64-bit ASan build - - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo ASAN_BUILD=1 + # FIXME: We should really run the unit tests too under ASan/UBSan but a debug build is too slow. + # 64-bit UBSan Debug build + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug UBSAN_BUILD=1 RUN_UNIT_TESTS=SKIP + # 64-bit ASan Debug build + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug ASAN_BUILD=1 RUN_UNIT_TESTS=SKIP # 64-bit GCC 5.4 RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo From 5bcdea1ae501d9f7c6ff3759d4a9347ea7075d70 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Fri, 6 Oct 2017 20:16:09 +0100 Subject: [PATCH 414/488] [TravisCI] For ASan/LSan use larger context so we get larger stack traces if needed. --- contrib/ci/scripts/sanitizer_env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ci/scripts/sanitizer_env.sh b/contrib/ci/scripts/sanitizer_env.sh index 3b1ff7297..30a8ce5a4 100644 --- a/contrib/ci/scripts/sanitizer_env.sh +++ b/contrib/ci/scripts/sanitizer_env.sh @@ -8,7 +8,7 @@ if [ "X${ASAN_BUILD}" = "X1" ]; then # Use suppression files export LSAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/lsan.txt" - export ASAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt" + export ASAN_OPTIONS="malloc_context_size=100,print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt" : ${ASAN_SYMBOLIZER_PATH?"ASAN_SYMBOLIZER_PATH must be specified"} fi From a991e44a2528bdee40e43c90b7902ec136968d16 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 9 Oct 2017 23:25:53 +0100 Subject: [PATCH 415/488] [TravisCI] Fix typo in created directory for suppression files --- contrib/ci/Dockerfiles/z3_build.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 65cf08087..0b6d0ac0d 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -63,7 +63,7 @@ ENV \ # Build Z3 RUN mkdir -p "${Z3_SRC_DIR}" && \ mkdir -p "${Z3_SRC_DIR}/contrib/ci/scripts" && \ - mkdir -p "${Z3_SRC_DIR}/contrib/ci/suppressions/sanitizers" + mkdir -p "${Z3_SRC_DIR}/contrib/suppressions/sanitizers" # Deliberately leave out `contrib` ADD /cmake ${Z3_SRC_DIR}/cmake/ ADD /doc ${Z3_SRC_DIR}/doc/ From bcff86a31606e0410a9295ed8ba35636d4b078a2 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 9 Oct 2017 23:29:08 +0100 Subject: [PATCH 416/488] [LSan] Add suppression for part of #1297. --- contrib/suppressions/sanitizers/lsan.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/suppressions/sanitizers/lsan.txt b/contrib/suppressions/sanitizers/lsan.txt index a4ce0881a..437358132 100644 --- a/contrib/suppressions/sanitizers/lsan.txt +++ b/contrib/suppressions/sanitizers/lsan.txt @@ -1 +1,5 @@ # LeakSanitizer suppression file + +# FIXME: This looks a bug in Clang/LSan the error reported +# doesn't make sense. See https://github.com/Z3Prover/z3/issues/1297 +leak:_fini From f90fe928af7029cb4c2179da5eca6268b1d2efe5 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 9 Oct 2017 23:42:10 +0100 Subject: [PATCH 417/488] [LSan] Suppress another leak until I can figure out what is going on. --- contrib/suppressions/sanitizers/lsan.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/suppressions/sanitizers/lsan.txt b/contrib/suppressions/sanitizers/lsan.txt index 437358132..81a3c8b85 100644 --- a/contrib/suppressions/sanitizers/lsan.txt +++ b/contrib/suppressions/sanitizers/lsan.txt @@ -3,3 +3,6 @@ # FIXME: This looks a bug in Clang/LSan the error reported # doesn't make sense. See https://github.com/Z3Prover/z3/issues/1297 leak:_fini +# FIXME: I don't understand this leak. +# See https://github.com/Z3Prover/z3/issues/1297 +leak:error_code_example2 From ff5df20deb0e49a73514906db6491a80932ca5a0 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 11 Oct 2017 08:10:13 +0100 Subject: [PATCH 418/488] [LSan] Don't run `c_maxsat_example` with LeakSanitizer because it contains leaks that the Z3 developers don't intend to fix. --- contrib/ci/scripts/sanitizer_env.sh | 13 +++++++++++++ contrib/ci/scripts/test_z3_examples_cmake.sh | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/contrib/ci/scripts/sanitizer_env.sh b/contrib/ci/scripts/sanitizer_env.sh index 30a8ce5a4..8cd646ce6 100644 --- a/contrib/ci/scripts/sanitizer_env.sh +++ b/contrib/ci/scripts/sanitizer_env.sh @@ -8,8 +8,21 @@ if [ "X${ASAN_BUILD}" = "X1" ]; then # Use suppression files export LSAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/lsan.txt" + # NOTE: If you get bad stacktraces try using `fast_unwind_on_malloc=0` + # NOTE: `malloc_context_size` controls size of recorded stacktrace for allocations. + # If the reported stacktraces appear incomplete try increasing the value. export ASAN_OPTIONS="malloc_context_size=100,print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt" : ${ASAN_SYMBOLIZER_PATH?"ASAN_SYMBOLIZER_PATH must be specified"} + + # Run command without checking for leaks + function run_no_lsan() { + ASAN_OPTIONS="${ASAN_OPTIONS},detect_leaks=0" "${@}" + } +else + # In non-ASan build just run directly + function run_no_lsan() { + "${@}" + } fi if [ "X${UBSAN_BUILD}" = "X1" ]; then diff --git a/contrib/ci/scripts/test_z3_examples_cmake.sh b/contrib/ci/scripts/test_z3_examples_cmake.sh index c188dbcf4..477f7f747 100755 --- a/contrib/ci/scripts/test_z3_examples_cmake.sh +++ b/contrib/ci/scripts/test_z3_examples_cmake.sh @@ -42,9 +42,13 @@ run_quiet examples/tptp_build_dir/z3_tptp5 -help # Build an run c_maxsat_example cmake --build $(pwd) --target c_maxsat_example "${GENERATOR_ARGS[@]}" -run_quiet \ - examples/c_maxsat_example_build_dir/c_maxsat_example \ - ${Z3_SRC_DIR}/examples/maxsat/ex.smt +# FIXME: It is known that the maxsat example leaks memory and the +# the Z3 developers have stated this is "wontfix". +# See https://github.com/Z3Prover/z3/issues/1299 +run_no_lsan \ + run_quiet \ + examples/c_maxsat_example_build_dir/c_maxsat_example \ + ${Z3_SRC_DIR}/examples/maxsat/ex.smt if [ "X${UBSAN_BUILD}" = "X1" ]; then # FIXME: We really need libz3 to link against a shared UBSan runtime. From 8d600050dbd9c73c58152259d91f999f33c19a11 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 11 Oct 2017 08:17:57 +0100 Subject: [PATCH 419/488] [LSan] Remove suppression files. The were fixed on rebase --- contrib/suppressions/sanitizers/lsan.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/contrib/suppressions/sanitizers/lsan.txt b/contrib/suppressions/sanitizers/lsan.txt index 81a3c8b85..a4ce0881a 100644 --- a/contrib/suppressions/sanitizers/lsan.txt +++ b/contrib/suppressions/sanitizers/lsan.txt @@ -1,8 +1 @@ # LeakSanitizer suppression file - -# FIXME: This looks a bug in Clang/LSan the error reported -# doesn't make sense. See https://github.com/Z3Prover/z3/issues/1297 -leak:_fini -# FIXME: I don't understand this leak. -# See https://github.com/Z3Prover/z3/issues/1297 -leak:error_code_example2 From db7b2e989db5a597812f0153827155a8b909e7c1 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 11 Oct 2017 17:27:39 +0100 Subject: [PATCH 420/488] [TravisCI] Try to run the Python and .NET examples under ASan. --- .travis.yml | 2 +- contrib/ci/Dockerfiles/z3_build.Dockerfile | 2 ++ contrib/ci/scripts/ci_defaults.sh | 1 + contrib/ci/scripts/sanitizer_env.sh | 32 ++++++++++++++++++ contrib/ci/scripts/test_z3_examples_cmake.sh | 33 +++++++++++++------ .../ci/scripts/travis_ci_linux_entry_point.sh | 4 +++ 6 files changed, 63 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 534aeacf0..940f15f98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ env: # 64-bit UBSan Debug build - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug UBSAN_BUILD=1 RUN_UNIT_TESTS=SKIP # 64-bit ASan Debug build - - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug ASAN_BUILD=1 RUN_UNIT_TESTS=SKIP + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug ASAN_BUILD=1 RUN_UNIT_TESTS=SKIP ASAN_DSO=/usr/lib/clang/3.9/lib/linux/libclang_rt.asan-x86_64.so # 64-bit GCC 5.4 RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 0b6d0ac0d..5b9ac9442 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -5,6 +5,7 @@ FROM ${DOCKER_IMAGE_BASE} # Build arguments. This can be changed when invoking # `docker build`. ARG ASAN_BUILD +ARG ASAN_DSO ARG BUILD_DOCS ARG CC ARG CXX @@ -32,6 +33,7 @@ ARG Z3_VERBOSE_BUILD_OUTPUT ENV \ ASAN_BUILD=${ASAN_BUILD} \ + ASAN_DSO=${ASAN_DSO} \ BUILD_DOCS=${BUILD_DOCS} \ CC=${CC} \ CXX=${CXX} \ diff --git a/contrib/ci/scripts/ci_defaults.sh b/contrib/ci/scripts/ci_defaults.sh index d8e9376d8..076d70180 100644 --- a/contrib/ci/scripts/ci_defaults.sh +++ b/contrib/ci/scripts/ci_defaults.sh @@ -49,6 +49,7 @@ unset PLATFORM # NOTE: The following variables are not set here because # they are specific to the CI implementation # PYTHON_EXECUTABLE +# ASAN_DSO # Z3_SRC_DIR # Z3_BUILD_DIR # Z3_SYSTEM_TEST_DIR diff --git a/contrib/ci/scripts/sanitizer_env.sh b/contrib/ci/scripts/sanitizer_env.sh index 8cd646ce6..0499eb268 100644 --- a/contrib/ci/scripts/sanitizer_env.sh +++ b/contrib/ci/scripts/sanitizer_env.sh @@ -18,11 +18,43 @@ if [ "X${ASAN_BUILD}" = "X1" ]; then function run_no_lsan() { ASAN_OPTIONS="${ASAN_OPTIONS},detect_leaks=0" "${@}" } + + # Check path to ASan DSO + : ${ASAN_DSO?"ASAN_DSO must be specified"} + if [ ! -e "${ASAN_DSO}" ]; then + echo "ASAN_DSO (${ASAN_DSO}) does not exist" + exit 1 + fi + # FIXME: We'll need to refactor this when we can do UBSan builds + # against a UBSan DSO. + function run_non_native_binding() { + # We need to preload the ASan DSO that libz3 + # will have undefined references to. + # Don't run leak checking because we get lots reported leaks + # in the language runtime (e.g. python). + PLATFORM="$(uname -s)" + case "${PLATFORM}" in + Linux*) + LD_PRELOAD="${ASAN_DSO}" run_no_lsan "${@}" + ;; + Darwin*) + DYLD_INSERT_LIBRARIES="${ASAN_DSO}" run_no_lsan "${@}" + ;; + *) + echo "Unknown platform \"${PLATFORM}\"" + exit 1 + ;; + esac + unset PLATFORM + } else # In non-ASan build just run directly function run_no_lsan() { "${@}" } + function run_non_native_binding() { + "${@}" + } fi if [ "X${UBSAN_BUILD}" = "X1" ]; then diff --git a/contrib/ci/scripts/test_z3_examples_cmake.sh b/contrib/ci/scripts/test_z3_examples_cmake.sh index 477f7f747..515027509 100755 --- a/contrib/ci/scripts/test_z3_examples_cmake.sh +++ b/contrib/ci/scripts/test_z3_examples_cmake.sh @@ -64,16 +64,21 @@ if [ "X${PYTHON_BINDINGS}" = "X1" ]; then # `all_interval_series.py` produces a lot of output so just throw # away output. # TODO: This example is slow should we remove it from testing? - run_quiet ${PYTHON_EXECUTABLE} python/all_interval_series.py - run_quiet ${PYTHON_EXECUTABLE} python/complex.py - run_quiet ${PYTHON_EXECUTABLE} python/example.py + if [ "X${ASAN_BUILD}" = "X1" -a "X${Z3_BUILD_TYPE}" = "XDebug" ]; then + # Too slow when doing ASan Debug build + echo "Skipping all_interval_series.py under ASan Debug build" + else + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/all_interval_series.py + fi + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/complex.py + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/example.py # FIXME: `hamiltonian.py` example is disabled because its too slow. #${PYTHON_EXECUTABLE} python/hamiltonian.py - run_quiet ${PYTHON_EXECUTABLE} python/marco.py - run_quiet ${PYTHON_EXECUTABLE} python/mss.py - run_quiet ${PYTHON_EXECUTABLE} python/socrates.py - run_quiet ${PYTHON_EXECUTABLE} python/visitor.py - run_quiet ${PYTHON_EXECUTABLE} python/z3test.py + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/marco.py + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/mss.py + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/socrates.py + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/visitor.py + run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/z3test.py fi if [ "X${DOTNET_BINDINGS}" = "X1" ]; then @@ -81,7 +86,7 @@ if [ "X${DOTNET_BINDINGS}" = "X1" ]; then # FIXME: Move compliation step into CMake target mcs ${Z3_SRC_DIR}/examples/dotnet/Program.cs /target:exe /out:dotnet_test.exe /reference:Microsoft.Z3.dll /r:System.Numerics.dll # Run .NET example - run_quiet mono ./dotnet_test.exe + run_non_native_binding run_quiet mono ./dotnet_test.exe fi if [ "X${JAVA_BINDINGS}" = "X1" ]; then @@ -98,6 +103,14 @@ if [ "X${JAVA_BINDINGS}" = "X1" ]; then # Assume Linux for now export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH} fi - run_quiet java -cp .:examples/java:com.microsoft.z3.jar JavaExample + if [ "X${ASAN_BUILD}" = "X1" ]; then + # The JVM seems to crash (SEGV) if we pre-load ASan + # so don't run it for now. + echo "Skipping JavaExample under ASan build" + else + run_non_native_binding \ + run_quiet \ + java -cp .:examples/java:com.microsoft.z3.jar JavaExample + fi fi diff --git a/contrib/ci/scripts/travis_ci_linux_entry_point.sh b/contrib/ci/scripts/travis_ci_linux_entry_point.sh index bd2c9d2d1..d60b06f8f 100755 --- a/contrib/ci/scripts/travis_ci_linux_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_linux_entry_point.sh @@ -84,6 +84,10 @@ if [ -n "${ASAN_BUILD}" ]; then BUILD_OPTS+=("--build-arg" "ASAN_BUILD=${ASAN_BUILD}") fi +if [ -n "${ASAN_DSO}" ]; then + BUILD_OPTS+=("--build-arg" "ASAN_DSO=${ASAN_DSO}") +fi + if [ -n "${UBSAN_BUILD}" ]; then BUILD_OPTS+=("--build-arg" "UBSAN_BUILD=${UBSAN_BUILD}") fi From 675a3ae9dd14f8dbda6d9d017566279e716b0c68 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sat, 14 Oct 2017 22:40:42 +0100 Subject: [PATCH 421/488] [UBSan] Remove a bunch of suppressions. --- contrib/suppressions/sanitizers/ubsan.txt | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/contrib/suppressions/sanitizers/ubsan.txt b/contrib/suppressions/sanitizers/ubsan.txt index 6ceacd400..4d19e40be 100644 --- a/contrib/suppressions/sanitizers/ubsan.txt +++ b/contrib/suppressions/sanitizers/ubsan.txt @@ -1,20 +1,7 @@ # UndefinedBehavior sanitizer suppression file # FIXME: UBSan doesn't usually have false positives so we need to fix all of these! -# Occurs when running C API example (`interpolation_example`) -# See https://github.com/Z3Prover/z3/issues/1286 -null:iz3mgr.h - -# Occurs when running C++ API example -# See https://github.com/Z3Prover/z3/issues/1287 -function:api_context.cpp - # Occurs when running tptp example # See https://github.com/Z3Prover/z3/issues/964 null:rational.h null:mpq.h - -# Occurs when running `test-z3 /a` -# See https://github.com/Z3Prover/z3/issues/1288 -shift-exponent:tbv.cpp -signed-integer-overflow:mpz.cpp From fd391e75a6afdc997322d87371b2228b419b2296 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 11:54:05 +0100 Subject: [PATCH 422/488] [TravisCI] Fix `Z3_BUILD_TYPE` variable that was not propagated into the Docker image as an environment variable. --- contrib/ci/Dockerfiles/z3_build.Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 5b9ac9442..562c2dfe5 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -52,6 +52,7 @@ ENV \ USE_OPENMP=${USE_OPENMP} \ Z3_SRC_DIR=${Z3_SRC_DIR} \ Z3_BUILD_DIR=/home/user/z3_build \ + Z3_BUILD_TYPE=${Z3_BUILD_TYPE} \ Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR} \ Z3_VERBOSE_BUILD_OUTPUT=${Z3_VERBOSE_BUILD_OUTPUT} \ Z3_STATIC_BUILD=${Z3_STATIC_BUILD} \ From 2dd1a4046d1579a3f953b53cb1b613c289cd51f4 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 12:02:13 +0100 Subject: [PATCH 423/488] [TravisCI] Fix typo --- contrib/ci/scripts/test_z3_system_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ci/scripts/test_z3_system_tests.sh b/contrib/ci/scripts/test_z3_system_tests.sh index 71ecf2a1e..bcffaf56e 100755 --- a/contrib/ci/scripts/test_z3_system_tests.sh +++ b/contrib/ci/scripts/test_z3_system_tests.sh @@ -28,7 +28,7 @@ Z3_LIB_DIR="${Z3_BUILD_DIR}" Z3_SYSTEM_TEST_GIT_URL="${Z3_GIT_URL:-https://github.com/Z3Prover/z3test.git}" # Clone repo to destination -mkdir -p "${Z3_SYSTEM_TEST_GIT_URL}" +mkdir -p "${Z3_SYSTEM_TEST_DIR}" git clone "${Z3_SYSTEM_TEST_GIT_URL}" "${Z3_SYSTEM_TEST_DIR}" cd "${Z3_SYSTEM_TEST_DIR}" From fd98593a5882075df3afa4c63cb47ebd7f73abee Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 12:19:16 +0100 Subject: [PATCH 424/488] [ASan] Ignore Clang OpenMP leaks for now. --- contrib/suppressions/sanitizers/lsan.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/suppressions/sanitizers/lsan.txt b/contrib/suppressions/sanitizers/lsan.txt index a4ce0881a..1480b7c09 100644 --- a/contrib/suppressions/sanitizers/lsan.txt +++ b/contrib/suppressions/sanitizers/lsan.txt @@ -1 +1,5 @@ # LeakSanitizer suppression file + +# Ignore Clang OpenMP leaks. +# See https://github.com/Z3Prover/z3/issues/1308 +leak:___kmp_allocate From 35f6746c60a40eeb3c3356e6a8652f72792a1c30 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 13:21:40 +0100 Subject: [PATCH 425/488] Workaround `regressions/smt2/error.smt2` test timing out. When ASan's LeakSanitizer is enabled leak checking is triggered when `exit()` is called and it returns so many false positives that it takes a long time to write them to the console. To workaround this we simply call `_Exit()` instead. --- src/parsers/smt2/smt2parser.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index b8ad7e610..b43ee9f6e 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -444,7 +444,10 @@ namespace smt2 { m_ctx.regular_stream()<< "line " << line << " column " << pos << ": " << escaped(msg, true) << "\")" << std::endl; } if (m_ctx.exit_on_error()) { - exit(1); + // WORKAROUND: ASan's LeakSanitizer reports many false positives when + // calling `exit()` so call `_Exit()` instead which avoids invoking leak + // checking. + _Exit(1); } } From ad2a0a0085773e1279526dce7b7bfaf167caeb40 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 15:27:10 +0100 Subject: [PATCH 426/488] [TravisCI] Don't print sanitizer suppressions by default because that breaks Z3's regression tests. --- contrib/ci/Dockerfiles/z3_build.Dockerfile | 2 ++ contrib/ci/README.md | 1 + contrib/ci/scripts/ci_defaults.sh | 4 ++++ contrib/ci/scripts/sanitizer_env.sh | 18 +++++++++++++++--- .../ci/scripts/travis_ci_linux_entry_point.sh | 4 ++++ 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 562c2dfe5..152b109d7 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -16,6 +16,7 @@ ARG PYTHON_BINDINGS ARG PYTHON_EXECUTABLE=/usr/bin/python2.7 ARG RUN_SYSTEM_TESTS ARG RUN_UNIT_TESTS +ARG SANITIZER_PRINT_SUPPRESSIONS ARG TARGET_ARCH ARG TEST_INSTALL ARG UBSAN_BUILD @@ -42,6 +43,7 @@ ENV \ NO_SUPPRESS_OUTPUT=${NO_SUPPRESS_OUTPUT} \ PYTHON_BINDINGS=${PYTHON_BINDINGS} \ PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} \ + SANITIZER_PRINT_SUPPRESSIONS=${SANITIZER_PRINT_SUPPRESSIONS} \ RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS} \ RUN_UNIT_TESTS=${RUN_UNIT_TESTS} \ TARGET_ARCH=${TARGET_ARCH} \ diff --git a/contrib/ci/README.md b/contrib/ci/README.md index 99bbcd7a6..95ed7f398 100644 --- a/contrib/ci/README.md +++ b/contrib/ci/README.md @@ -32,6 +32,7 @@ the future. * `PYTHON_BINDINGS` - Build and test Python API bindings (`0` or `1`) * `RUN_SYSTEM_TESTS` - Run system tests (`0` or `1`) * `RUN_UNIT_TESTS` - Run unit tests (`BUILD_ONLY` or `BUILD_AND_RUN` or `SKIP`) +* `SANITIZER_PRINT_SUPPRESSIONS` - Show ASan/UBSan suppressions (`0` or `1`) * `TARGET_ARCH` - Target architecture (`x86_64` or `i686`) * `TEST_INSTALL` - Test running `install` target (`0` or `1`) * `UBSAN_BUILD` - Do [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) build (`0` or `1`) diff --git a/contrib/ci/scripts/ci_defaults.sh b/contrib/ci/scripts/ci_defaults.sh index 076d70180..2029981c0 100644 --- a/contrib/ci/scripts/ci_defaults.sh +++ b/contrib/ci/scripts/ci_defaults.sh @@ -11,6 +11,10 @@ export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}" export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}" export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}" export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-BUILD_AND_RUN}" +# Don't print suppressions by default because that breaks the Z3 +# regression tests because they don't expect them to appear in Z3's +# output. +export SANITIZER_PRINT_SUPPRESSIONS="${SANITIZER_PRINT_SUPPRESSIONS:-0}" export TARGET_ARCH="${TARGET_ARCH:-x86_64}" export TEST_INSTALL="${TEST_INSTALL:-1}" export UBSAN_BUILD="${UBSAN_BUILD:-0}" diff --git a/contrib/ci/scripts/sanitizer_env.sh b/contrib/ci/scripts/sanitizer_env.sh index 0499eb268..959f136e5 100644 --- a/contrib/ci/scripts/sanitizer_env.sh +++ b/contrib/ci/scripts/sanitizer_env.sh @@ -7,11 +7,18 @@ if [ "X${ASAN_BUILD}" = "X1" ]; then # Use suppression files - export LSAN_OPTIONS="print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/lsan.txt" + export LSAN_OPTIONS="suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/lsan.txt" # NOTE: If you get bad stacktraces try using `fast_unwind_on_malloc=0` # NOTE: `malloc_context_size` controls size of recorded stacktrace for allocations. # If the reported stacktraces appear incomplete try increasing the value. - export ASAN_OPTIONS="malloc_context_size=100,print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt" + export ASAN_OPTIONS="malloc_context_size=100,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt" + + : ${SANITIZER_PRINT_SUPPRESSIONS?"SANITIZER_PRINT_SUPPRESSIONS must be specified"} + if [ "X${SANITIZER_PRINT_SUPPRESSIONS}" = "X1" ]; then + export LSAN_OPTIONS="${LSAN_OPTIONS},print_suppressions=1" + export ASAN_OPTIONS="${ASAN_OPTIONS},print_suppressions=1" + fi + : ${ASAN_SYMBOLIZER_PATH?"ASAN_SYMBOLIZER_PATH must be specified"} # Run command without checking for leaks @@ -61,5 +68,10 @@ if [ "X${UBSAN_BUILD}" = "X1" ]; then # `halt_on_error=1,abort_on_error=1` means that on the first UBSan error # the program will terminate by calling `abort(). Without this UBSan will # allow execution to continue. We also use a suppression file. - export UBSAN_OPTIONS="halt_on_error=1,abort_on_error=1,print_suppressions=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/ubsan.txt" + export UBSAN_OPTIONS="halt_on_error=1,abort_on_error=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/ubsan.txt" + + : ${SANITIZER_PRINT_SUPPRESSIONS?"SANITIZER_PRINT_SUPPRESSIONS must be specified"} + if [ "X${SANITIZER_PRINT_SUPPRESSIONS}" = "X1" ]; then + export UBSAN_OPTIONS="${UBSAN_OPTIONS},print_suppressions=1" + fi fi diff --git a/contrib/ci/scripts/travis_ci_linux_entry_point.sh b/contrib/ci/scripts/travis_ci_linux_entry_point.sh index d60b06f8f..352e13de0 100755 --- a/contrib/ci/scripts/travis_ci_linux_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_linux_entry_point.sh @@ -88,6 +88,10 @@ if [ -n "${ASAN_DSO}" ]; then BUILD_OPTS+=("--build-arg" "ASAN_DSO=${ASAN_DSO}") fi +if [ -n "${SANITIZER_PRINT_SUPPRESSIONS}" ]; then + BUILD_OPTS+=("--build-arg" "SANITIZER_PRINT_SUPPRESSIONS=${SANITIZER_PRINT_SUPPRESSIONS}") +fi + if [ -n "${UBSAN_BUILD}" ]; then BUILD_OPTS+=("--build-arg" "UBSAN_BUILD=${UBSAN_BUILD}") fi From ecadef6e48460cdbb271c13817534b357bd92341 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 17:25:12 +0100 Subject: [PATCH 427/488] [TravisCI] Try to fix case in `run_quiet` where the script would fail with. ``` -ne: unary operator expected ``` --- contrib/ci/scripts/run_quiet.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/ci/scripts/run_quiet.sh b/contrib/ci/scripts/run_quiet.sh index 5abc910e8..0f49da3be 100644 --- a/contrib/ci/scripts/run_quiet.sh +++ b/contrib/ci/scripts/run_quiet.sh @@ -34,8 +34,8 @@ function run_quiet() { fi # Clean up rm "${STDOUT}" "${STDERR}" - [ $( echo "${OLD_SETTINGS}" | grep -c 'e') -ne 0 ] && set -e - [ $( echo "${OLD_SETTINGS}" | grep -c 'x') -ne 0 ] && set -x + [ "$( echo "${OLD_SETTINGS}" | grep -c 'e')" != "0" ] && set -e + [ "$( echo "${OLD_SETTINGS}" | grep -c 'x')" != "0" ] && set -x return ${EXIT_STATUS} fi } From ead6e56d15432384ece80361dd1969c2367a0fe2 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 17:41:40 +0100 Subject: [PATCH 428/488] [TravisCI] Swap `run_quiet` and `run_non_native_binding`. In the previous order `grep` inside `run_quiet` would get ASan LD_PRELOAD'ed which would sometimes fail. --- contrib/ci/scripts/test_z3_examples_cmake.sh | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/contrib/ci/scripts/test_z3_examples_cmake.sh b/contrib/ci/scripts/test_z3_examples_cmake.sh index 515027509..9979b8773 100755 --- a/contrib/ci/scripts/test_z3_examples_cmake.sh +++ b/contrib/ci/scripts/test_z3_examples_cmake.sh @@ -68,17 +68,17 @@ if [ "X${PYTHON_BINDINGS}" = "X1" ]; then # Too slow when doing ASan Debug build echo "Skipping all_interval_series.py under ASan Debug build" else - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/all_interval_series.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/all_interval_series.py fi - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/complex.py - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/example.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/complex.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/example.py # FIXME: `hamiltonian.py` example is disabled because its too slow. #${PYTHON_EXECUTABLE} python/hamiltonian.py - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/marco.py - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/mss.py - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/socrates.py - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/visitor.py - run_non_native_binding run_quiet ${PYTHON_EXECUTABLE} python/z3test.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/marco.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/mss.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/socrates.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/visitor.py + run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/z3test.py fi if [ "X${DOTNET_BINDINGS}" = "X1" ]; then @@ -86,7 +86,7 @@ if [ "X${DOTNET_BINDINGS}" = "X1" ]; then # FIXME: Move compliation step into CMake target mcs ${Z3_SRC_DIR}/examples/dotnet/Program.cs /target:exe /out:dotnet_test.exe /reference:Microsoft.Z3.dll /r:System.Numerics.dll # Run .NET example - run_non_native_binding run_quiet mono ./dotnet_test.exe + run_quiet run_non_native_binding mono ./dotnet_test.exe fi if [ "X${JAVA_BINDINGS}" = "X1" ]; then @@ -108,8 +108,8 @@ if [ "X${JAVA_BINDINGS}" = "X1" ]; then # so don't run it for now. echo "Skipping JavaExample under ASan build" else - run_non_native_binding \ - run_quiet \ + run_quiet \ + run_non_native_binding \ java -cp .:examples/java:com.microsoft.z3.jar JavaExample fi fi From e51ce8bcafc585ee23bea555f2c91a22646445ef Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 19:54:50 +0100 Subject: [PATCH 429/488] [TravisCI] Try again to not show suppressions by default --- contrib/ci/scripts/sanitizer_env.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contrib/ci/scripts/sanitizer_env.sh b/contrib/ci/scripts/sanitizer_env.sh index 959f136e5..f1fa87442 100644 --- a/contrib/ci/scripts/sanitizer_env.sh +++ b/contrib/ci/scripts/sanitizer_env.sh @@ -17,6 +17,9 @@ if [ "X${ASAN_BUILD}" = "X1" ]; then if [ "X${SANITIZER_PRINT_SUPPRESSIONS}" = "X1" ]; then export LSAN_OPTIONS="${LSAN_OPTIONS},print_suppressions=1" export ASAN_OPTIONS="${ASAN_OPTIONS},print_suppressions=1" + else + export LSAN_OPTIONS="${LSAN_OPTIONS},print_suppressions=0" + export ASAN_OPTIONS="${ASAN_OPTIONS},print_suppressions=0" fi : ${ASAN_SYMBOLIZER_PATH?"ASAN_SYMBOLIZER_PATH must be specified"} @@ -73,5 +76,7 @@ if [ "X${UBSAN_BUILD}" = "X1" ]; then : ${SANITIZER_PRINT_SUPPRESSIONS?"SANITIZER_PRINT_SUPPRESSIONS must be specified"} if [ "X${SANITIZER_PRINT_SUPPRESSIONS}" = "X1" ]; then export UBSAN_OPTIONS="${UBSAN_OPTIONS},print_suppressions=1" + else + export UBSAN_OPTIONS="${UBSAN_OPTIONS},print_suppressions=0" fi fi From dbb7f616c157359eaaeee9b9a340217a8b522521 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Sun, 15 Oct 2017 21:36:02 +0100 Subject: [PATCH 430/488] More LSan workarounds. --- src/cmd_context/cmd_context.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 95c030687..9615e86ce 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1608,7 +1608,9 @@ void cmd_context::validate_check_sat_result(lbool r) { throw cmd_exception("check annotation that says unsat"); #else diagnostic_stream() << "BUG: incompleteness" << std::endl; - exit(ERR_INCOMPLETENESS); + // WORKAROUND: `exit()` causes LSan to be invoked and produce + // many false positives. + _Exit(ERR_INCOMPLETENESS); #endif } break; @@ -1618,7 +1620,9 @@ void cmd_context::validate_check_sat_result(lbool r) { throw cmd_exception("check annotation that says sat"); #else diagnostic_stream() << "BUG: unsoundness" << std::endl; - exit(ERR_UNSOUNDNESS); + // WORKAROUND: `exit()` causes LSan to be invoked and produce + // many false positives. + _Exit(ERR_UNSOUNDNESS); #endif } break; From 88fb31ac089a4220fc25f3d3917d88a2af746eca Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 16 Oct 2017 08:50:50 +0100 Subject: [PATCH 431/488] [TravisCI] Add `RUN_API_EXAMPLES` option so that we can disable building/running examples in some configurations. --- contrib/ci/Dockerfiles/z3_build.Dockerfile | 2 ++ contrib/ci/README.md | 1 + contrib/ci/scripts/ci_defaults.sh | 1 + contrib/ci/scripts/test_z3_examples_cmake.sh | 6 ++++++ contrib/ci/scripts/travis_ci_linux_entry_point.sh | 4 ++++ 5 files changed, 14 insertions(+) diff --git a/contrib/ci/Dockerfiles/z3_build.Dockerfile b/contrib/ci/Dockerfiles/z3_build.Dockerfile index 152b109d7..eb2e03a43 100644 --- a/contrib/ci/Dockerfiles/z3_build.Dockerfile +++ b/contrib/ci/Dockerfiles/z3_build.Dockerfile @@ -14,6 +14,7 @@ ARG JAVA_BINDINGS ARG NO_SUPPRESS_OUTPUT ARG PYTHON_BINDINGS ARG PYTHON_EXECUTABLE=/usr/bin/python2.7 +ARG RUN_API_EXAMPLES ARG RUN_SYSTEM_TESTS ARG RUN_UNIT_TESTS ARG SANITIZER_PRINT_SUPPRESSIONS @@ -44,6 +45,7 @@ ENV \ PYTHON_BINDINGS=${PYTHON_BINDINGS} \ PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} \ SANITIZER_PRINT_SUPPRESSIONS=${SANITIZER_PRINT_SUPPRESSIONS} \ + RUN_API_EXAMPLES=${RUN_API_EXAMPLES} \ RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS} \ RUN_UNIT_TESTS=${RUN_UNIT_TESTS} \ TARGET_ARCH=${TARGET_ARCH} \ diff --git a/contrib/ci/README.md b/contrib/ci/README.md index 95ed7f398..bd1c52792 100644 --- a/contrib/ci/README.md +++ b/contrib/ci/README.md @@ -30,6 +30,7 @@ the future. * `JAVA_BINDINGS` - Build and test Java API bindings (`0` or `1`) * `NO_SUPPRESS_OUTPUT` - Don't suppress output of some commands (`0` or `1`) * `PYTHON_BINDINGS` - Build and test Python API bindings (`0` or `1`) +* `RUN_API_EXAMPLES` - Build and run API examples (`0` or `1`) * `RUN_SYSTEM_TESTS` - Run system tests (`0` or `1`) * `RUN_UNIT_TESTS` - Run unit tests (`BUILD_ONLY` or `BUILD_AND_RUN` or `SKIP`) * `SANITIZER_PRINT_SUPPRESSIONS` - Show ASan/UBSan suppressions (`0` or `1`) diff --git a/contrib/ci/scripts/ci_defaults.sh b/contrib/ci/scripts/ci_defaults.sh index 2029981c0..7a4434bd5 100644 --- a/contrib/ci/scripts/ci_defaults.sh +++ b/contrib/ci/scripts/ci_defaults.sh @@ -9,6 +9,7 @@ export DOTNET_BINDINGS="${DOTNET_BINDINGS:-1}" export JAVA_BINDINGS="${JAVA_BINDINGS:-1}" export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}" export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}" +export RUN_API_EXAMPLES="${RUN_API_EXAMPLES:-1}" export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}" export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-BUILD_AND_RUN}" # Don't print suppressions by default because that breaks the Z3 diff --git a/contrib/ci/scripts/test_z3_examples_cmake.sh b/contrib/ci/scripts/test_z3_examples_cmake.sh index 9979b8773..687efebb4 100755 --- a/contrib/ci/scripts/test_z3_examples_cmake.sh +++ b/contrib/ci/scripts/test_z3_examples_cmake.sh @@ -15,6 +15,12 @@ set -o pipefail : ${DOTNET_BINDINGS?"DOTNET_BINDINGS must be specified"} : ${JAVA_BINDINGS?"JAVA_BINDINGS must be specified"} : ${UBSAN_BUILD?"UBSAN_BUILD must be specified"} +: ${RUN_API_EXAMPLES?"RUN_API_EXAMPLES must be specified"} + +if [ "X${RUN_API_EXAMPLES}" = "X0" ]; then + echo "Skipping run of API examples" + exit 0 +fi # Set compiler flags source ${SCRIPT_DIR}/set_compiler_flags.sh diff --git a/contrib/ci/scripts/travis_ci_linux_entry_point.sh b/contrib/ci/scripts/travis_ci_linux_entry_point.sh index 352e13de0..731ea9ff0 100755 --- a/contrib/ci/scripts/travis_ci_linux_entry_point.sh +++ b/contrib/ci/scripts/travis_ci_linux_entry_point.sh @@ -100,6 +100,10 @@ if [ -n "${TEST_INSTALL}" ]; then BUILD_OPTS+=("--build-arg" "TEST_INSTALL=${TEST_INSTALL}") fi +if [ -n "${RUN_API_EXAMPLES}" ]; then + BUILD_OPTS+=("--build-arg" "RUN_API_EXAMPLES=${RUN_API_EXAMPLES}") +fi + if [ -n "${RUN_SYSTEM_TESTS}" ]; then BUILD_OPTS+=("--build-arg" "RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS}") fi From 8835b54d1669d54d9595287a015acdf39e84a55c Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 16 Oct 2017 08:55:57 +0100 Subject: [PATCH 432/488] [TravisCI] Add ASan/UBSan configuration that runs unit tests. --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 940f15f98..a3ffb221e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,11 +17,14 @@ env: ############################################################################### # Ubuntu 16.04 LTS ############################################################################### - # FIXME: We should really run the unit tests too under ASan/UBSan but a debug build is too slow. # 64-bit UBSan Debug build - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug UBSAN_BUILD=1 RUN_UNIT_TESTS=SKIP # 64-bit ASan Debug build - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug ASAN_BUILD=1 RUN_UNIT_TESTS=SKIP ASAN_DSO=/usr/lib/clang/3.9/lib/linux/libclang_rt.asan-x86_64.so + # Build for running unit tests under ASan/UBSan + # FIXME: We should really be doing a debug build but the unit tests run too + # slowly when we do that. + - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo ASAN_BUILD=1 RUN_UNIT_TESTS=BUILD_AND_RUN ASAN_DSO=/usr/lib/clang/3.9/lib/linux/libclang_rt.asan-x86_64.so UBSAN_BUILD=1 RUN_API_EXAMPLES=0 RUN_SYSTEM_TESTS=0 DOTNET_BINDINGS=0 JAVA_BINDINGS=0 PYTHON_BINDINGS=0 # 64-bit GCC 5.4 RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo From a1b6316e2e3ae19e9e8f67af6e17c13771d73c81 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 16 Oct 2017 09:49:54 +0100 Subject: [PATCH 433/488] [TravisCI] Try to unbreak running Python regression tests under ASan. --- contrib/ci/scripts/test_z3_system_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ci/scripts/test_z3_system_tests.sh b/contrib/ci/scripts/test_z3_system_tests.sh index bcffaf56e..6f9901687 100755 --- a/contrib/ci/scripts/test_z3_system_tests.sh +++ b/contrib/ci/scripts/test_z3_system_tests.sh @@ -58,7 +58,7 @@ if [ "X${PYTHON_BINDINGS}" = "X1" ]; then # to work. echo "FIXME: Skipping python binding tests when building with UBSan" else - ${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/ + run_non_native_binding ${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/ fi fi From 7c99721b60e9f5a8e6a2fe502ff56380e808916b Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Mon, 16 Oct 2017 13:21:03 +0100 Subject: [PATCH 434/488] [TravisCI] Don't run Python regression tests under ASan for now. The script that runs them doesn't propagate LD_PRELOAD and so the tests fail. --- contrib/ci/scripts/test_z3_system_tests.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contrib/ci/scripts/test_z3_system_tests.sh b/contrib/ci/scripts/test_z3_system_tests.sh index 6f9901687..19c179268 100755 --- a/contrib/ci/scripts/test_z3_system_tests.sh +++ b/contrib/ci/scripts/test_z3_system_tests.sh @@ -57,6 +57,11 @@ if [ "X${PYTHON_BINDINGS}" = "X1" ]; then # FIXME: We need to build libz3 with a shared UBSan runtime for the bindings # to work. echo "FIXME: Skipping python binding tests when building with UBSan" + elif [ "X${ASAN_BUILD}" = "X1" ]; then + # FIXME: The `test_pyscripts.py` doesn't propagate LD_PRELOAD + # so under ASan the tests fail to run + # to work. + echo "FIXME: Skipping python binding tests when building with ASan" else run_non_native_binding ${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/ fi From cda03b4238852544b27a750603c4b3d4178bba8f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 16 Oct 2017 17:01:09 +0100 Subject: [PATCH 435/488] Whitespace --- src/ast/normal_forms/nnf.cpp | 94 ++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 014568812..42b4e9350 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -40,7 +40,7 @@ enum nnf_mode { transformation will be in skolem normal form. If a formula is too expensive to be put into NNF, then nested quantifiers and labels are renamed. - + This mode is sufficient when using E-matching. */ NNF_QUANT, /* A subformula is put into NNF if it contains @@ -48,7 +48,7 @@ enum nnf_mode { quantifier. The result of the transformation will be in skolem normal form, and the body of quantifiers will be in NNF. If a ground formula is too expensive to - be put into NNF, then nested quantifiers and labels + be put into NNF, then nested quantifiers and labels are renamed. This mode is sufficient when using Superposition @@ -89,7 +89,7 @@ class skolemizer { } TRACE("skolemizer", tout << "skid: " << q->get_skid() << "\n";); - + expr_ref_vector substitution(m()); unsigned num_decls = q->get_num_decls(); for (unsigned i = num_decls; i > 0; ) { @@ -111,7 +111,7 @@ class skolemizer { substitution.push_back(0); } // - // (VAR num_decls) ... (VAR num_decls+sz-1) + // (VAR num_decls) ... (VAR num_decls+sz-1) // are in positions num_decls .. num_decls+sz-1 // std::reverse(substitution.c_ptr(), substitution.c_ptr() + substitution.size()); @@ -139,7 +139,7 @@ class skolemizer { s(body, substitution.size(), substitution.c_ptr(), r); p = 0; if (m().proofs_enabled()) { - if (q->is_forall()) + if (q->is_forall()) p = m().mk_skolemization(m().mk_not(q), m().mk_not(r)); else p = m().mk_skolemization(q, r); @@ -175,7 +175,7 @@ public: m_cache_pr.insert(q, p); } } - + bool is_sk_hack(expr * p) const { SASSERT(m().is_pattern(p)); if (to_app(p)->get_num_args() != 1) @@ -204,7 +204,7 @@ struct nnf::imp { unsigned m_i:28; unsigned m_pol:1; // pos/neg polarity unsigned m_in_q:1; // true if m_curr is nested in a quantifier - unsigned m_new_child:1; + unsigned m_new_child:1; unsigned m_cache_result:1; unsigned m_spos; // top of the result stack, when the frame was created. frame(expr_ref&& n, bool pol, bool in_q, bool cache_res, unsigned spos): @@ -223,22 +223,22 @@ struct nnf::imp { #define POS_NQ_CIDX 1 // positive polarity and not nested in a quantifier #define NEG_Q_CIDX 2 // negative polarity and nested in a quantifier #define POS_Q_CIDX 3 // positive polarity and nested in a quantifier - + ast_manager & m_manager; vector m_frame_stack; expr_ref_vector m_result_stack; - + typedef act_cache cache; cache * m_cache[4]; expr_ref_vector m_todo_defs; proof_ref_vector m_todo_proofs; - + // proof generation goodness ---- proof_ref_vector m_result_pr_stack; cache * m_cache_pr[4]; // ------------------------------ - + skolemizer m_skolemizer; // configuration ---------------- @@ -249,7 +249,7 @@ struct nnf::imp { name_exprs * m_name_nested_formulas; name_exprs * m_name_quant; - + unsigned long long m_max_memory; // in bytes imp(ast_manager & m, defined_names & n, params_ref const & p): @@ -292,9 +292,9 @@ struct nnf::imp { m_mode = NNF_FULL; else if (mode_sym == "quantifiers") m_mode = NNF_QUANT; - else + else throw nnf_params_exception("invalid NNF mode"); - + TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << _p << "\n";); m_ignore_labels = p.ignore_labels(); @@ -327,8 +327,8 @@ struct nnf::imp { m_frame_stack.push_back(frame({ t, m() }, pol, in_q, cache_res, m_result_stack.size())); } - static unsigned get_cache_idx(bool pol, bool in_q) { - return static_cast(in_q) * 2 + static_cast(pol); + static unsigned get_cache_idx(bool pol, bool in_q) { + return static_cast(in_q) * 2 + static_cast(pol); } void cache_result(expr * t, bool pol, bool in_q, expr * v, proof * pr) { @@ -338,8 +338,8 @@ struct nnf::imp { m_cache_pr[idx]->insert(t, pr); } - expr * get_cached(expr * t, bool pol, bool in_q) const { - return m_cache[get_cache_idx(pol, in_q)]->find(t); + expr * get_cached(expr * t, bool pol, bool in_q) const { + return m_cache[get_cache_idx(pol, in_q)]->find(t); } proof * get_cached_pr(expr * t, bool pol, bool in_q) const { @@ -367,12 +367,12 @@ struct nnf::imp { return false; } - + void checkpoint() { cooperate("nnf"); if (memory::get_allocation_size() > m_max_memory) throw nnf_exception(Z3_MAX_MEMORY_MSG); - if (m().canceled()) + if (m().canceled()) throw nnf_exception(m().limit().get_cancel_msg()); } @@ -381,11 +381,11 @@ struct nnf::imp { m_frame_stack.back().m_new_child = true; } - void set_new_child_flag(expr * old_t, expr * new_t) { - if (old_t != new_t) - set_new_child_flag(); + void set_new_child_flag(expr * old_t, expr * new_t) { + if (old_t != new_t) + set_new_child_flag(); } - + void skip(expr * t, bool pol) { expr * r = pol ? t : m().mk_not(t); m_result_stack.push_back(r); @@ -447,10 +447,10 @@ struct nnf::imp { if (pol) { if (old_e->get_decl() == new_e->get_decl()) return m().mk_oeq_congruence(old_e, new_e, num_parents, parents); - else + else return m().mk_nnf_pos(old_e, new_e, num_parents, parents); } - else + else return m().mk_nnf_neg(old_e, new_e, num_parents, parents); } @@ -467,7 +467,7 @@ struct nnf::imp { r = m().mk_and(t->get_num_args(), m_result_stack.c_ptr() + fr.m_spos); else r = m().mk_or(t->get_num_args(), m_result_stack.c_ptr() + fr.m_spos); - + m_result_stack.shrink(fr.m_spos); m_result_stack.push_back(r); if (proofs_enabled()) { @@ -519,7 +519,7 @@ struct nnf::imp { r = m().mk_or(2, m_result_stack.c_ptr() + fr.m_spos); else r = m().mk_and(2, m_result_stack.c_ptr() + fr.m_spos); - + m_result_stack.shrink(fr.m_spos); m_result_stack.push_back(r); if (proofs_enabled()) { @@ -553,7 +553,7 @@ struct nnf::imp { default: break; } - + expr * const * rs = m_result_stack.c_ptr() + fr.m_spos; expr * _cond = rs[0]; expr * _not_cond = rs[1]; @@ -573,7 +573,7 @@ struct nnf::imp { } bool is_eq(app * t) const { return m().is_eq(t) || m().is_iff(t); } - + bool process_iff_xor(app * t, frame & fr) { SASSERT(t->get_num_args() == 2); switch (fr.m_i) { @@ -604,7 +604,7 @@ struct nnf::imp { expr * not_rhs = rs[3]; app * r; - if (is_eq(t) == fr.m_pol) + if (is_eq(t) == fr.m_pol) r = m().mk_and(m().mk_or(not_lhs, rhs), m().mk_or(lhs, not_rhs)); else r = m().mk_and(m().mk_or(lhs, rhs), m().mk_or(not_lhs, not_rhs)); @@ -625,7 +625,7 @@ struct nnf::imp { else return process_default(t, fr); } - + bool process_default(app * t, frame & fr) { SASSERT(fr.m_i == 0); if (m_mode == NNF_FULL || t->has_quantifiers() || t->has_labels()) { @@ -635,10 +635,10 @@ struct nnf::imp { m_name_nested_formulas->operator()(t, m_todo_defs, m_todo_proofs, n2, pr2); else m_name_quant->operator()(t, m_todo_defs, m_todo_proofs, n2, pr2); - + if (!fr.m_pol) n2 = m().mk_not(n2); - + m_result_stack.push_back(n2); if (proofs_enabled()) { if (!fr.m_pol) { @@ -665,10 +665,10 @@ struct nnf::imp { expr * arg = m_result_stack.back(); proof * arg_pr = proofs_enabled() ? m_result_pr_stack.back() : 0; - if (m_ignore_labels && !proofs_enabled()) + if (m_ignore_labels && !proofs_enabled()) return true; // the result is already on the stack - + buffer names; bool pos; m().is_label(t, pos, names); @@ -683,7 +683,7 @@ struct nnf::imp { pr = m().mk_transitivity(mk_proof(fr.m_pol, 1, &arg_pr, t, to_app(aux)), m().mk_iff_oeq(m().mk_rewrite(aux, r))); } - } + } else { r = arg; if (proofs_enabled()) { @@ -691,7 +691,7 @@ struct nnf::imp { pr = m().mk_transitivity(p1, arg_pr); } } - + m_result_stack.pop_back(); m_result_stack.push_back(r); if (proofs_enabled()) { @@ -728,7 +728,7 @@ struct nnf::imp { if (m().is_label(t)) { return process_label(t, fr); } - + return process_default(t, fr); } @@ -736,7 +736,7 @@ struct nnf::imp { skip(v, fr.m_pol); return true; } - + bool process_quantifier(quantifier * q, frame & fr) { expr_ref r(m()); proof_ref pr(m()); @@ -756,7 +756,7 @@ struct nnf::imp { if (q->is_forall() == fr.m_pol || !m_skolemize) { expr * new_expr = m_result_stack.back(); proof * new_expr_pr = proofs_enabled() ? m_result_pr_stack.back() : 0; - + ptr_buffer new_patterns; if (q->is_forall() == fr.m_pol) { @@ -772,7 +772,7 @@ struct nnf::imp { // New quantifier has existential force. // So, ignore patterns } - + quantifier * new_q = 0; proof * new_q_pr = 0; if (fr.m_pol) { @@ -785,7 +785,7 @@ struct nnf::imp { if (proofs_enabled()) new_q_pr = m().mk_nnf_neg(q, new_q, 1, &new_expr_pr); } - + m_result_stack.pop_back(); m_result_stack.push_back(new_q); if (proofs_enabled()) { @@ -808,7 +808,7 @@ struct nnf::imp { } return true; } - + void recover_result(expr * t, expr_ref & result, proof_ref & result_pr) { // recover result from the top of the stack. result = m_result_stack.back(); @@ -872,7 +872,7 @@ struct nnf::imp { process(n, r, pr); unsigned old_sz1 = new_defs.size(); unsigned old_sz2 = new_def_proofs.size(); - + for (unsigned i = 0; i < m_todo_defs.size(); i++) { expr_ref dr(m()); proof_ref dpr(m()); @@ -880,7 +880,7 @@ struct nnf::imp { new_defs.push_back(dr); if (proofs_enabled()) { proof * new_pr = m().mk_modus_ponens(m_todo_proofs.get(i), dpr); - new_def_proofs.push_back(new_pr); + new_def_proofs.push_back(new_pr); } } std::reverse(new_defs.c_ptr() + old_sz1, new_defs.c_ptr() + new_defs.size()); @@ -897,7 +897,7 @@ nnf::nnf(ast_manager & m, defined_names & n, params_ref const & p) { nnf::~nnf() { dealloc(m_imp); } - + void nnf::operator()(expr * n, expr_ref_vector & new_defs, proof_ref_vector & new_def_proofs, expr_ref & r, proof_ref & p) { m_imp->operator()(n, new_defs, new_def_proofs, r, p); TRACE("nnf_result", tout << mk_ismt2_pp(n, m_imp->m()) << "\nNNF result:\n" << mk_ismt2_pp(r, m_imp->m()) << "\n";); From f9adf8e62a55a4f423682ebd31d254894fe36f95 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 16 Oct 2017 17:07:03 +0100 Subject: [PATCH 436/488] Backwards compatibility --- src/ast/normal_forms/nnf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 42b4e9350..7368d7935 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -207,8 +207,8 @@ struct nnf::imp { unsigned m_new_child:1; unsigned m_cache_result:1; unsigned m_spos; // top of the result stack, when the frame was created. - frame(expr_ref&& n, bool pol, bool in_q, bool cache_res, unsigned spos): - m_curr(std::move(n)), + frame(expr_ref & n, bool pol, bool in_q, bool cache_res, unsigned spos): + m_curr(n), m_i(0), m_pol(pol), m_in_q(in_q), @@ -324,7 +324,7 @@ struct nnf::imp { } void push_frame(expr * t, bool pol, bool in_q, bool cache_res) { - m_frame_stack.push_back(frame({ t, m() }, pol, in_q, cache_res, m_result_stack.size())); + m_frame_stack.push_back(frame(expr_ref(t, m()), pol, in_q, cache_res, m_result_stack.size())); } static unsigned get_cache_idx(bool pol, bool in_q) { From 256c9d76d3fe85ac41486efd14506ff5436fc7c8 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 16 Oct 2017 09:14:10 -0700 Subject: [PATCH 437/488] add macro for _Exit under WINDOWS Signed-off-by: Nikolaj Bjorner --- src/ast/normal_forms/nnf.cpp | 2 ++ src/util/util.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 7368d7935..f625095d0 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -216,6 +216,8 @@ struct nnf::imp { m_cache_result(cache_res), m_spos(spos) { } + //frame():m_curr(*(ast_manager*)(nullptr)) { + //} }; // There are four caches: diff --git a/src/util/util.h b/src/util/util.h index f8c464197..6d38231ba 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -54,6 +54,7 @@ static_assert(sizeof(int64) == 8, "64 bits"); #ifdef _WINDOWS #define SSCANF sscanf_s #define SPRINTF sprintf_s +#define _Exit exit #else #define SSCANF sscanf #define SPRINTF sprintf From a93f1f88ccdb55f73326f087f7f34fdc70ded764 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 16 Oct 2017 09:23:50 -0700 Subject: [PATCH 438/488] trying to fix mac build Signed-off-by: Nikolaj Bjorner --- src/ast/normal_forms/nnf.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index f625095d0..6363d374a 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -216,6 +216,15 @@ struct nnf::imp { m_cache_result(cache_res), m_spos(spos) { } + frame(frame & other): + m_curr(other.m_curr), + m_i(other.m_i), + m_pol(other.m_pol), + m_in_q(other.m_in_q), + m_new_child(other.m_new_child), + m_cache_result(other.m_cache_result), + m_spos(other.m_spos) { + } //frame():m_curr(*(ast_manager*)(nullptr)) { //} }; From 5f9891c2356857998eec7cfbf8b9585571aea892 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 16 Oct 2017 09:29:26 -0700 Subject: [PATCH 439/488] moving out construction of expr_ref Signed-off-by: Nikolaj Bjorner --- src/ast/normal_forms/nnf.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 6363d374a..09fccf135 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -225,8 +225,6 @@ struct nnf::imp { m_cache_result(other.m_cache_result), m_spos(other.m_spos) { } - //frame():m_curr(*(ast_manager*)(nullptr)) { - //} }; // There are four caches: @@ -335,7 +333,8 @@ struct nnf::imp { } void push_frame(expr * t, bool pol, bool in_q, bool cache_res) { - m_frame_stack.push_back(frame(expr_ref(t, m()), pol, in_q, cache_res, m_result_stack.size())); + expr_ref tt(t, m()); + m_frame_stack.push_back(frame(tt, pol, in_q, cache_res, m_result_stack.size())); } static unsigned get_cache_idx(bool pol, bool in_q) { From 019edcb822955ec361ed4b1141eaf6c08b0068b4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 16 Oct 2017 09:35:00 -0700 Subject: [PATCH 440/488] frame, again Signed-off-by: Nikolaj Bjorner --- src/ast/normal_forms/nnf.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 09fccf135..3baf4e4ea 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -225,6 +225,16 @@ struct nnf::imp { m_cache_result(other.m_cache_result), m_spos(other.m_spos) { } + frame(frame && other): + m_curr(other.m_curr), + m_i(other.m_i), + m_pol(other.m_pol), + m_in_q(other.m_in_q), + m_new_child(other.m_new_child), + m_cache_result(other.m_cache_result), + m_spos(other.m_spos) { + } + }; // There are four caches: From 01f642a6f37e2a25cbfe45f0c48aa9341989028d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 16 Oct 2017 18:19:55 +0100 Subject: [PATCH 441/488] Backward compatibility --- src/test/trigo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/trigo.cpp b/src/test/trigo.cpp index d1b75c7fb..686800162 100644 --- a/src/test/trigo.cpp +++ b/src/test/trigo.cpp @@ -98,7 +98,7 @@ template static void tst_float_sine(std::ostream & out, unsigned N, unsigned k) { reslimit rl; fmanager fm; - interval_manager > im(rl, { fm, EBITS, SBITS }); + interval_manager > im(rl, im_float_config(fm, EBITS, SBITS)); _scoped_numeral a(fm); fm.set(a, EBITS, SBITS, static_cast(0)); tst_float_sine_core(out, fm, im, a, 1); From 4e92caa5537a139b5b8a945a0195726ded94788b Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 16 Oct 2017 22:33:23 +0100 Subject: [PATCH 442/488] nnf: let's try a different version of compatible frames wo/ copying --- src/ast/normal_forms/nnf.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 3baf4e4ea..6fc65543d 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -207,8 +207,8 @@ struct nnf::imp { unsigned m_new_child:1; unsigned m_cache_result:1; unsigned m_spos; // top of the result stack, when the frame was created. - frame(expr_ref & n, bool pol, bool in_q, bool cache_res, unsigned spos): - m_curr(n), + frame(expr_ref && n, bool pol, bool in_q, bool cache_res, unsigned spos): + m_curr(std::move(n)), m_i(0), m_pol(pol), m_in_q(in_q), @@ -216,17 +216,8 @@ struct nnf::imp { m_cache_result(cache_res), m_spos(spos) { } - frame(frame & other): - m_curr(other.m_curr), - m_i(other.m_i), - m_pol(other.m_pol), - m_in_q(other.m_in_q), - m_new_child(other.m_new_child), - m_cache_result(other.m_cache_result), - m_spos(other.m_spos) { - } frame(frame && other): - m_curr(other.m_curr), + m_curr(std::move(other.m_curr)), m_i(other.m_i), m_pol(other.m_pol), m_in_q(other.m_in_q), @@ -343,8 +334,7 @@ struct nnf::imp { } void push_frame(expr * t, bool pol, bool in_q, bool cache_res) { - expr_ref tt(t, m()); - m_frame_stack.push_back(frame(tt, pol, in_q, cache_res, m_result_stack.size())); + m_frame_stack.push_back(frame(expr_ref(t, m()), pol, in_q, cache_res, m_result_stack.size())); } static unsigned get_cache_idx(bool pol, bool in_q) { From 448cf8c31de75718b78dc7a02c313f29c1775df9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 17 Oct 2017 10:14:26 -0700 Subject: [PATCH 443/488] fix scope accounting for dom simplifier Signed-off-by: Nikolaj Bjorner --- src/ast/expr_substitution.h | 1 + src/tactic/bv/bv_bounds_tactic.cpp | 12 +++++++++--- src/tactic/bv/bv_bounds_tactic.h | 10 +++++++++- src/tactic/core/dom_simplify_tactic.h | 10 +++++++--- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/ast/expr_substitution.h b/src/ast/expr_substitution.h index 90154d163..1590f888c 100644 --- a/src/ast/expr_substitution.h +++ b/src/ast/expr_substitution.h @@ -80,6 +80,7 @@ public: m_trail_lim.resize(new_sz); } } + unsigned scope_level() const { return m_trail_lim.size(); } bool empty() const { return m_subst.empty(); } expr* find(expr * e) { proof* pr; expr* d = 0; if (find(e, d, pr)) return d; else return e; } bool find(expr * s, expr * & def, proof * & def_pr) { return m_subst.find(s, def, def_pr); } diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp index 44f920840..22b74db77 100644 --- a/src/tactic/bv/bv_bounds_tactic.cpp +++ b/src/tactic/bv/bv_bounds_tactic.cpp @@ -11,7 +11,9 @@ Abstract: Author: - Nikolaj Bjorner (nbjorner) 2016-2-12 + Nuno Lopes (nlopes) 2016-2-12 + + Nikolaj Bjorner (nbjorner) --*/ @@ -650,11 +652,11 @@ namespace { return false; if (old == intr) return true; - m_scopes.insert(undo_bound(t1, old, false)); + m_scopes.push_back(undo_bound(t1, old, false)); old = intr; } else { m_bound.insert(t1, b); - m_scopes.insert(undo_bound(t1, interval(), true)); + m_scopes.push_back(undo_bound(t1, interval(), true)); } } return true; @@ -801,6 +803,10 @@ namespace { return alloc(dom_bv_bounds_simplifier, m, m_params); } + virtual unsigned scope_level() const { + return m_scopes.size(); + } + }; } diff --git a/src/tactic/bv/bv_bounds_tactic.h b/src/tactic/bv/bv_bounds_tactic.h index 6c2ce60ed..1d6748b27 100644 --- a/src/tactic/bv/bv_bounds_tactic.h +++ b/src/tactic/bv/bv_bounds_tactic.h @@ -11,7 +11,8 @@ Abstract: Author: - Nikolaj Bjorner (nbjorner) 2016-2-12 + Nuno Lopes (nlopes) 2016-2-12 + Nikolaj Bjorner (nbjorner) --*/ @@ -21,8 +22,15 @@ Author: tactic * mk_bv_bounds_tactic(ast_manager & m, params_ref const & p = params_ref()); +tactic * mk_dom_bv_bounds_tactic(ast_manager & m, params_ref const & p = params_ref()); + /* ADD_TACTIC("propagate-bv-bounds", "propagate bit-vector bounds by simplifying implied or contradictory bounds.", "mk_bv_bounds_tactic(m, p)") + + + ADD_TACTIC("propagate-bv-bounds-new", "propagate bit-vector bounds by simplifying implied or contradictory bounds.", "mk_dom_bv_bounds_tactic(m, p)") + + */ #endif diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 79bc9728c..6cd94a3c1 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -83,6 +83,8 @@ class dom_simplifier { virtual void pop(unsigned num_scopes) = 0; virtual dom_simplifier * translate(ast_manager & m) = 0; + + virtual unsigned scope_level() const = 0; }; @@ -116,9 +118,9 @@ class dom_simplify_tactic : public tactic { ptr_vector const & tree(expr * e); expr* idom(expr *e) const { return m_dominators.idom(e); } - unsigned scope_level() { return m_scope_level; } - void pop(unsigned n) { SASSERT(n <= m_scope_level); m_scope_level -= n; m_simplifier->pop(n); } - bool assert_expr(expr* f, bool sign) { m_scope_level++; return m_simplifier->assert_expr(f, sign); } + unsigned scope_level() { return m_simplifier->scope_level(); } + void pop(unsigned n) { SASSERT(n <= m_simplifier->scope_level()); m_simplifier->pop(n); } + bool assert_expr(expr* f, bool sign) { return m_simplifier->assert_expr(f, sign); } bool init(goal& g); @@ -169,6 +171,8 @@ public: virtual void pop(unsigned num_scopes) { m_scoped_substitution.pop(num_scopes); } + virtual unsigned scope_level() const { return m_scoped_substitution.scope_level(); } + virtual dom_simplifier * translate(ast_manager & m) { SASSERT(m_subst.empty()); return alloc(expr_substitution_simplifier, m); From 7f590b5419f5dfc92a62e29db28947cb1dc73a07 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 17 Oct 2017 10:27:58 -0700 Subject: [PATCH 444/488] gift for Nuno Signed-off-by: Nikolaj Bjorner --- src/tactic/bv/bv_bounds_tactic.cpp | 8 ++++++-- src/tactic/core/dom_simplify_tactic.cpp | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tactic/bv/bv_bounds_tactic.cpp b/src/tactic/bv/bv_bounds_tactic.cpp index 22b74db77..a279e441b 100644 --- a/src/tactic/bv/bv_bounds_tactic.cpp +++ b/src/tactic/bv/bv_bounds_tactic.cpp @@ -694,7 +694,8 @@ namespace { bool was_updated = true; if (b.is_full() && b.tight) { r = m.mk_true(); - } else if (m_bound.find(t1, ctx)) { + } + else if (m_bound.find(t1, ctx)) { if (ctx.implies(b)) { r = m.mk_true(); } @@ -705,12 +706,15 @@ namespace { r = m.mk_eq(t1, m_bv.mk_numeral(rational(intr.l, rational::ui64()), m.get_sort(t1))); } + else { + was_updated = false; + } } else { was_updated = false; } - CTRACE("bv", was_updated, tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";); + TRACE("bv", tout << mk_pp(t, m) << " " << b << " (ctx: " << ctx << ") (intr: " << intr << "): " << r << "\n";); if (sign && was_updated) r = m.mk_not(r); } diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index 3a6d55569..ee94c5e57 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -242,7 +242,7 @@ expr_ref dom_simplify_tactic::simplify_ite(app * ite) { r = new_t; } else { - TRACE("tactic", tout << new_c << "\n" << new_t << "\n" << new_e << "\n";); + TRACE("simplify", tout << new_c << "\n" << new_t << "\n" << new_e << "\n";); r = m.mk_ite(new_c, new_t, new_e); } } From 45c60ed55cdcf2ed18dd4ae0ace1043bc04e40b5 Mon Sep 17 00:00:00 2001 From: Adrian Stanciu Date: Wed, 18 Oct 2017 14:50:44 +0300 Subject: [PATCH 445/488] Update README.md Corrected path to Z3 Python interface --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 701556cc8..70956d439 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ utility is used to install ``Microsoft.Z3.dll`` into the [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/) file (``Microsoft.Z3.Sharp.pc``) is also installed which allows the [MonoDevelop](http://www.monodevelop.com/) IDE to find the bindings. Running -``make uninstall`` will remove the dll from the GAC and the pkg-config file. +``make uninstall`` will remove the dll from the GAC and the ``pkg-config`` file. See [``examples/dotnet``](examples/dotnet) for examples. @@ -170,8 +170,8 @@ If you do need to install to a non standard prefix a better approach is to use a [Python virtual environment](https://virtualenv.readthedocs.org/en/latest/) and install Z3 there. Python packages also work for Python3. Under Windows, recall to build inside the Visual C++ native command build environment. -Note that the buit/python/z3 directory should be accessible from where python is used with Z3 -and it depends on libz3.dll to be in the path. +Note that the ``build/python/z3`` directory should be accessible from where python is used with Z3 +and it depends on ``libz3.dll`` to be in the path. ```bash virtualenv venv From abdb41c5df1dd7ba2209838696759d257bd0723a Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Wed, 18 Oct 2017 16:08:39 -0400 Subject: [PATCH 446/488] add special case handling for string constant backpropagation in theory_str avoid a crash when asserting that a constant string is equal to itself by not generating this assert in the first place --- src/smt/theory_str.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 97c8db125..41d42c867 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -8888,15 +8888,34 @@ namespace smt { if (concat_lhs_haseqc && concat_rhs_haseqc && !var_haseqc) { TRACE("str", tout << "backpropagate into " << mk_pp(var, m) << " = " << mk_pp(concat, m) << std::endl << "LHS ~= " << mk_pp(concat_lhs_str, m) << " RHS ~= " << mk_pp(concat_rhs_str, m) << std::endl;); + + TRACE("str_enode_bug", tout << "backpropagate into " << mk_pp(var, m) << " = " << mk_pp(concat, m) << std::endl + << "LHS ~= " << mk_pp(concat_lhs_str, m) << " RHS ~= " << mk_pp(concat_rhs_str, m) << std::endl;); zstring lhsString, rhsString; u.str.is_string(concat_lhs_str, lhsString); u.str.is_string(concat_rhs_str, rhsString); zstring concatString = lhsString + rhsString; - expr_ref lhs1(ctx.mk_eq_atom(concat_lhs, concat_lhs_str), m); - expr_ref lhs2(ctx.mk_eq_atom(concat_rhs, concat_rhs_str), m); - expr_ref lhs(m.mk_and(lhs1, lhs2), m); - expr_ref rhs(ctx.mk_eq_atom(concat, mk_string(concatString)), m); - assert_implication(lhs, rhs); + + // special handling: don't assert that string constants are equal to themselves + expr_ref_vector lhs_terms(m); + if (!u.str.is_string(concat_lhs)) { + lhs_terms.push_back(ctx.mk_eq_atom(concat_lhs, concat_lhs_str)); + } + if (!u.str.is_string(concat_rhs)) { + lhs_terms.push_back(ctx.mk_eq_atom(concat_rhs, concat_rhs_str)); + } + + if (lhs_terms.empty()) { + // no assumptions on LHS + expr_ref rhs(ctx.mk_eq_atom(concat, mk_string(concatString)), m); + assert_axiom(rhs); + } else { + expr_ref lhs(mk_and(lhs_terms), m); + expr_ref rhs(ctx.mk_eq_atom(concat, mk_string(concatString)), m); + TRACE("str_enode_bug", tout << "axiom LHS: " << mk_pp(lhs, m) << std::endl;); + TRACE("str_enode_bug", tout << "axiom RHS: " << mk_pp(rhs, m) << std::endl;); + assert_implication(lhs, rhs); + } backpropagation_occurred = true; } } From c9f540b066a33196f47b379d95327d84f55ffacf Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 19 Oct 2017 11:08:48 -0700 Subject: [PATCH 447/488] additional array functions exposed over API, ping #1223 Signed-off-by: Nikolaj Bjorner --- src/api/api_array.cpp | 88 +++++++++++++++++++++++++- src/api/c++/z3++.h | 28 +++++++++ src/api/dotnet/ArraySort.cs | 7 +++ src/api/dotnet/Context.cs | 89 ++++++++++++++++++++++++--- src/api/java/ArraySort.java | 6 ++ src/api/java/Context.java | 64 ++++++++++++++++++- src/api/z3_api.h | 38 ++++++++++++ src/ast/array_decl_plugin.cpp | 12 +++- src/ast/array_decl_plugin.h | 6 +- src/ast/fpa/bv2fpa_converter.cpp | 2 +- src/smt/theory_array.cpp | 67 +++++++------------- src/smt/theory_array_base.cpp | 5 +- src/tactic/bv/bvarray2uf_rewriter.cpp | 14 ++--- 13 files changed, 354 insertions(+), 72 deletions(-) diff --git a/src/api/api_array.cpp b/src/api/api_array.cpp index a5916e987..5e6764dff 100644 --- a/src/api/api_array.cpp +++ b/src/api/api_array.cpp @@ -34,6 +34,19 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const* domain, Z3_sort range) { + Z3_TRY; + LOG_Z3_mk_array_sort_n(c, n, domain, range); + RESET_ERROR_CODE(); + vector params; + for (unsigned i = 0; i < n; ++i) params.push_back(parameter(to_sort(domain[i]))); + params.push_back(parameter(to_sort(range))); + sort * ty = mk_c(c)->m().mk_sort(mk_c(c)->get_array_fid(), ARRAY_SORT, params.size(), params.c_ptr()); + mk_c(c)->save_ast_trail(ty); + RETURN_Z3(of_sort(ty)); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i) { Z3_TRY; LOG_Z3_mk_select(c, a, i); @@ -57,6 +70,35 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const* idxs) { + Z3_TRY; + LOG_Z3_mk_select_n(c, a, n, idxs); + RESET_ERROR_CODE(); + ast_manager & m = mk_c(c)->m(); + expr * _a = to_expr(a); + // expr * _i = to_expr(i); + sort * a_ty = m.get_sort(_a); + // sort * i_ty = m.get_sort(_i); + if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) { + SET_ERROR_CODE(Z3_SORT_ERROR); + RETURN_Z3(0); + } + ptr_vector domain; + ptr_vector args; + args.push_back(_a); + domain.push_back(a_ty); + for (unsigned i = 0; i < n; ++i) { + args.push_back(to_expr(idxs[i])); + domain.push_back(m.get_sort(to_expr(idxs[i]))); + } + func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_SELECT, 2, a_ty->get_parameters(), domain.size(), domain.c_ptr()); + app * r = m.mk_app(d, args.size(), args.c_ptr()); + mk_c(c)->save_ast_trail(r); + check_sorts(c, r); + RETURN_Z3(of_ast(r)); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v) { Z3_TRY; LOG_Z3_mk_store(c, a, i, v); @@ -82,6 +124,37 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_store_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const* idxs, Z3_ast v) { + Z3_TRY; + LOG_Z3_mk_store_n(c, a, n, idxs, v); + RESET_ERROR_CODE(); + ast_manager & m = mk_c(c)->m(); + expr * _a = to_expr(a); + expr * _v = to_expr(v); + sort * a_ty = m.get_sort(_a); + sort * v_ty = m.get_sort(_v); + if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) { + SET_ERROR_CODE(Z3_SORT_ERROR); + RETURN_Z3(0); + } + ptr_vector domain; + ptr_vector args; + args.push_back(_a); + domain.push_back(a_ty); + for (unsigned i = 0; i < n; ++i) { + args.push_back(to_expr(idxs[i])); + domain.push_back(m.get_sort(to_expr(idxs[i]))); + } + args.push_back(_v); + domain.push_back(v_ty); + func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_STORE, 2, a_ty->get_parameters(), domain.size(), domain.c_ptr()); + app * r = m.mk_app(d, args.size(), args.c_ptr()); + mk_c(c)->save_ast_trail(r); + check_sorts(c, r); + RETURN_Z3(of_ast(r)); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const* args) { Z3_TRY; LOG_Z3_mk_map(c, f, n, args); @@ -188,6 +261,18 @@ extern "C" { MK_BINARY(Z3_mk_set_subset, mk_c(c)->get_array_fid(), OP_SET_SUBSET, SKIP); MK_BINARY(Z3_mk_array_ext, mk_c(c)->get_array_fid(), OP_ARRAY_EXT, SKIP); + Z3_ast Z3_API Z3_mk_as_array(Z3_context c, Z3_func_decl f) { + Z3_TRY; + LOG_Z3_mk_as_array(c, f); + RESET_ERROR_CODE(); + ast_manager & m = mk_c(c)->m(); + array_util a(m); + app * r = a.mk_as_array(to_func_decl(f)); + mk_c(c)->save_ast_trail(r); + return of_ast(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_mk_set_member(Z3_context c, Z3_ast elem, Z3_ast set) { return Z3_mk_select(c, set, elem); } @@ -222,7 +307,8 @@ extern "C" { CHECK_VALID_AST(t, 0); if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() && to_sort(t)->get_decl_kind() == ARRAY_SORT) { - Z3_sort r = reinterpret_cast(to_sort(t)->get_parameter(1).get_ast()); + unsigned n = to_sort(t)->get_num_parameters(); + Z3_sort r = reinterpret_cast(to_sort(t)->get_parameter(n-1).get_ast()); RETURN_Z3(r); } SET_ERROR_CODE(Z3_INVALID_ARG); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index f55ece034..23a7bd22e 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -250,6 +250,8 @@ namespace z3 { Example: Given a context \c c, c.array_sort(c.int_sort(), c.bool_sort()) is an array sort from integer to Boolean. */ sort array_sort(sort d, sort r); + sort array_sort(sort_vector const& d, sort r); + /** \brief Return an enumeration sort: enum_names[0], ..., enum_names[n-1]. \c cs and \c ts are output parameters. The method stores in \c cs the constants corresponding to the enumerated elements, @@ -2327,6 +2329,11 @@ namespace z3 { inline sort context::re_sort(sort& s) { Z3_sort r = Z3_mk_re_sort(m_ctx, s); check_error(); return sort(*this, r); } inline sort context::array_sort(sort d, sort r) { Z3_sort s = Z3_mk_array_sort(m_ctx, d, r); check_error(); return sort(*this, s); } + inline sort context::array_sort(sort_vector const& d, sort r) { + array dom(d); + Z3_sort s = Z3_mk_array_sort_n(m_ctx, dom.size(), dom.ptr(), r); check_error(); return sort(*this, s); + } + inline sort context::enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts) { array _enum_names(n); for (unsigned i = 0; i < n; i++) { _enum_names[i] = Z3_mk_string_symbol(*this, enum_names[i]); } @@ -2573,11 +2580,32 @@ namespace z3 { a.check_error(); return expr(a.ctx(), r); } + inline expr select(expr const & a, expr_vector const & i) { + check_context(a, i); + array idxs(i); + Z3_ast r = Z3_mk_select_n(a.ctx(), a, idxs.size(), idxs.ptr()); + a.check_error(); + return expr(a.ctx(), r); + } + inline expr store(expr const & a, int i, expr const & v) { return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), v); } inline expr store(expr const & a, expr i, int v) { return store(a, i, a.ctx().num_val(v, a.get_sort().array_range())); } inline expr store(expr const & a, int i, int v) { return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), a.ctx().num_val(v, a.get_sort().array_range())); } + inline expr store(expr const & a, expr_vector const & i, expr const & v) { + check_context(a, i); check_context(a, v); + array idxs(i); + Z3_ast r = Z3_mk_store_n(a.ctx(), a, idxs.size(), idxs.ptr(), v); + a.check_error(); + return expr(a.ctx(), r); + } + + inline expr as_array(func_decl & f) { + Z3_ast r = Z3_mk_as_array(f.ctx(), f); + f.check_error(); + return expr(f.ctx(), r); + } #define MK_EXPR1(_fn, _arg) \ Z3_ast r = _fn(_arg.ctx(), _arg); \ diff --git a/src/api/dotnet/ArraySort.cs b/src/api/dotnet/ArraySort.cs index ddd27785c..47a73ae1f 100644 --- a/src/api/dotnet/ArraySort.cs +++ b/src/api/dotnet/ArraySort.cs @@ -63,6 +63,13 @@ namespace Microsoft.Z3 Contract.Requires(domain != null); Contract.Requires(range != null); } + internal ArraySort(Context ctx, Sort[] domain, Sort range) + : base(ctx, Native.Z3_mk_array_sort_n(ctx.nCtx, (uint)domain.Length, AST.ArrayToNative(domain), range.NativeObject)) + { + Contract.Requires(ctx != null); + Contract.Requires(domain != null); + Contract.Requires(range != null); + } #endregion }; diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index d7699c961..27711be81 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -274,6 +274,20 @@ namespace Microsoft.Z3 return new ArraySort(this, domain, range); } + /// + /// Create a new n-ary array sort. + /// + public ArraySort MkArraySort(Sort[] domain, Sort range) + { + Contract.Requires(domain != null); + Contract.Requires(range != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(domain); + CheckContextMatch(range); + return new ArraySort(this, domain, range); + } + /// /// Create a new tuple sort. /// @@ -2113,6 +2127,7 @@ namespace Microsoft.Z3 return (ArrayExpr)MkConst(MkSymbol(name), MkArraySort(domain, range)); } + /// /// Array read. /// @@ -2123,8 +2138,8 @@ namespace Microsoft.Z3 /// The node a must have an array sort [domain -> range], /// and i must have the sort domain. /// The sort of the result is range. - /// - /// + /// + /// /// public Expr MkSelect(ArrayExpr a, Expr i) { @@ -2137,6 +2152,30 @@ namespace Microsoft.Z3 return Expr.Create(this, Native.Z3_mk_select(nCtx, a.NativeObject, i.NativeObject)); } + /// + /// Array read. + /// + /// + /// The argument a is the array and args are the indices + /// of the array that gets read. + /// + /// The node a must have an array sort [domain1,..,domaink -> range], + /// and args must have the sort domain1,..,domaink. + /// The sort of the result is range. + /// + /// + /// + public Expr MkSelect(ArrayExpr a, params Expr[] args) + { + Contract.Requires(a != null); + Contract.Requires(args != null && Contract.ForAll(args, n => n != null)); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(a); + CheckContextMatch(args); + return Expr.Create(this, Native.Z3_mk_select_n(nCtx, a.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args))); + } + /// /// Array update. /// @@ -2151,8 +2190,9 @@ namespace Microsoft.Z3 /// on all indices except for i, where it maps to v /// (and the select of a with /// respect to i may be a different value). - /// - /// + /// + /// + /// /// public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) { @@ -2167,14 +2207,45 @@ namespace Microsoft.Z3 return new ArrayExpr(this, Native.Z3_mk_store(nCtx, a.NativeObject, i.NativeObject, v.NativeObject)); } + /// + /// Array update. + /// + /// + /// The node a must have an array sort [domain1,..,domaink -> range], + /// args must have sort domain1,..,domaink, + /// v must have sort range. The sort of the result is [domain -> range]. + /// The semantics of this function is given by the theory of arrays described in the SMT-LIB + /// standard. See http://smtlib.org for more details. + /// The result of this function is an array that is equal to a + /// (with respect to select) + /// on all indices except for args, where it maps to v + /// (and the select of a with + /// respect to args may be a different value). + /// + /// + /// + /// + public ArrayExpr MkStore(ArrayExpr a, Expr[] args, Expr v) + { + Contract.Requires(a != null); + Contract.Requires(args != null); + Contract.Requires(v != null); + Contract.Ensures(Contract.Result() != null); + + CheckContextMatch(args); + CheckContextMatch(a); + CheckContextMatch(v); + return new ArrayExpr(this, Native.Z3_mk_store_n(nCtx, a.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args), v.NativeObject)); + } + /// /// Create a constant array. /// /// /// The resulting term is an array, such that a selecton an arbitrary index /// produces the value v. - /// - /// + /// + /// /// public ArrayExpr MkConstArray(Sort domain, Expr v) { @@ -2194,9 +2265,9 @@ namespace Microsoft.Z3 /// Eeach element of args must be of an array sort [domain_i -> range_i]. /// The function declaration f must have type range_1 .. range_n -> range. /// v must have sort range. The sort of the result is [domain_i -> range]. - /// - /// - /// + /// + /// + /// /// public ArrayExpr MkMap(FuncDecl f, params ArrayExpr[] args) { diff --git a/src/api/java/ArraySort.java b/src/api/java/ArraySort.java index 1574823d1..db4d992ed 100644 --- a/src/api/java/ArraySort.java +++ b/src/api/java/ArraySort.java @@ -56,4 +56,10 @@ public class ArraySort extends Sort super(ctx, Native.mkArraySort(ctx.nCtx(), domain.getNativeObject(), range.getNativeObject())); } + + ArraySort(Context ctx, Sort[] domains, Sort range) + { + super(ctx, Native.mkArraySortN(ctx.nCtx(), domains.length, AST.arrayToNative(domains), + range.getNativeObject())); + } }; diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 72866a0ba..76303d670 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -224,6 +224,17 @@ public class Context implements AutoCloseable { return new ArraySort(this, domain, range); } + + /** + * Create a new array sort. + **/ + public ArraySort mkArraySort(Sort[] domains, Sort range) + { + checkContextMatch(domains); + checkContextMatch(range); + return new ArraySort(this, domains, range); + } + /** * Create a new string sort **/ @@ -414,7 +425,7 @@ public class Context implements AutoCloseable { * that is passed in as argument is updated with value v, * the remaining fields of t are unchanged. **/ - public Expr MkUpdateField(FuncDecl field, Expr t, Expr v) + public Expr mkUpdateField(FuncDecl field, Expr t, Expr v) throws Z3Exception { return Expr.create (this, @@ -706,7 +717,7 @@ public class Context implements AutoCloseable { } /** - * Mk an expression representing {@code not(a)}. + * Create an expression representing {@code not(a)}. **/ public BoolExpr mkNot(BoolExpr a) { @@ -1679,6 +1690,28 @@ public class Context implements AutoCloseable { i.getNativeObject())); } + /** + * Array read. + * Remarks: The argument {@code a} is the array and + * {@code args} are the indices of the array that gets read. + * + * The node {@code a} must have an array sort + * {@code [domains -> range]}, and {@code args} must have the sorts + * {@code domains}. The sort of the result is {@code range}. + * + * @see #mkArraySort + * @see #mkStore + + **/ + public Expr mkSelect(ArrayExpr a, Expr[] args) + { + checkContextMatch(a); + checkContextMatch(args); + return Expr.create( + this, + Native.mkSelectN(nCtx(), a.getNativeObject(), args.length, AST.arrayToNative(args))); + } + /** * Array update. * Remarks: The node {@code a} must have an array sort @@ -1704,6 +1737,31 @@ public class Context implements AutoCloseable { i.getNativeObject(), v.getNativeObject())); } + /** + * Array update. + * Remarks: The node {@code a} must have an array sort + * {@code [domains -> range]}, {@code i} must have sort + * {@code domain}, {@code v} must have sort range. The sort of the + * result is {@code [domains -> range]}. The semantics of this function + * is given by the theory of arrays described in the SMT-LIB standard. See + * http://smtlib.org for more details. The result of this function is an + * array that is equal to {@code a} (with respect to + * {@code select}) on all indices except for {@code args}, where it + * maps to {@code v} (and the {@code select} of {@code a} + * with respect to {@code args} may be a different value). + * @see #mkArraySort + * @see #mkSelect + + **/ + public ArrayExpr mkStore(ArrayExpr a, Expr[] args, Expr v) + { + checkContextMatch(a); + checkContextMatch(args); + checkContextMatch(v); + return new ArrayExpr(this, Native.mkStoreN(nCtx(), a.getNativeObject(), + args.length, AST.arrayToNative(args), v.getNativeObject())); + } + /** * Create a constant array. * Remarks: The resulting term is an array, such @@ -2104,7 +2162,7 @@ public class Context implements AutoCloseable { /** * Create a range expression. */ - public ReExpr MkRange(SeqExpr lo, SeqExpr hi) + public ReExpr mkRange(SeqExpr lo, SeqExpr hi) { checkContextMatch(lo, hi); return (ReExpr) Expr.create(this, Native.mkReRange(nCtx(), lo.getNativeObject(), hi.getNativeObject())); diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 154b8eb3c..9f155b45e 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -1881,6 +1881,17 @@ extern "C" { */ Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range); + /** + \brief Create an array type with N arguments + + \sa Z3_mk_select_n + \sa Z3_mk_store_n + + def_API('Z3_mk_array_sort_n', SORT, (_in(CONTEXT), _in(UINT), _in_array(1, SORT), _in(SORT))) + */ + Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const * domain, Z3_sort range); + + /** \brief Create a tuple type. @@ -2973,6 +2984,15 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i); + /** + \brief n-ary Array read. + The argument \c a is the array and \c idxs are the indices of the array that gets read. + + def_API('Z3_mk_select_n', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST))) + + */ + Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const* idxs); + /** \brief Array update. @@ -2991,6 +3011,14 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v); + /** + \brief n-ary Array update. + + def_API('Z3_mk_store_n', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST), _in(AST))) + + */ + Z3_ast Z3_API Z3_mk_store_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const* idxs, Z3_ast v); + /** \brief Create the constant array. @@ -3031,6 +3059,15 @@ extern "C" { def_API('Z3_mk_array_default', AST, (_in(CONTEXT), _in(AST))) */ Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array); + + /** + \brief Create array with the same interpretation as a function. + The array satisfies the property (f x) = (select (_ as-array f) x) + for every argument x. + + def_API('Z3_mk_as_array', AST, (_in(CONTEXT), _in(FUNC_DECL))) + */ + Z3_ast Z3_API Z3_mk_as_array(Z3_context c, Z3_func_decl f); /*@}*/ /** @name Sets */ @@ -3854,6 +3891,7 @@ extern "C" { /** \brief Return the domain of the given array sort. + In the case of a multi-dimensional array, this function returns the sort of the first dimension. \pre Z3_get_sort_kind(c, t) == Z3_ARRAY_SORT diff --git a/src/ast/array_decl_plugin.cpp b/src/ast/array_decl_plugin.cpp index cb016e263..0cc4f6031 100644 --- a/src/ast/array_decl_plugin.cpp +++ b/src/ast/array_decl_plugin.cpp @@ -242,7 +242,9 @@ func_decl* array_decl_plugin::mk_select(unsigned arity, sort * const * domain) { parameter const* parameters = s->get_parameters(); if (num_parameters != arity) { - m_manager->raise_exception("select requires as many arguments as the size of the domain"); + std::stringstream strm; + strm << "select requires " << num_parameters << " arguments, but was provided with " << arity << " arguments"; + m_manager->raise_exception(strm.str().c_str()); return 0; } ptr_buffer new_domain; // we need this because of coercions. @@ -314,7 +316,7 @@ func_decl * array_decl_plugin::mk_array_ext(unsigned arity, sort * const * domai return 0; } sort * r = to_sort(s->get_parameter(i).get_ast()); - parameter param(s); + parameter param(i); return m_manager->mk_func_decl(m_array_ext_sym, arity, domain, r, func_decl_info(m_family_id, OP_ARRAY_EXT, 1, ¶m)); } @@ -592,3 +594,9 @@ sort * array_util::mk_array_sort(unsigned arity, sort* const* domain, sort* rang params.push_back(parameter(range)); return m_manager.mk_sort(m_fid, ARRAY_SORT, params.size(), params.c_ptr()); } + +func_decl* array_util::mk_array_ext(sort *domain, unsigned i) { + sort * domains[2] = { domain, domain }; + parameter p(i); + return m_manager.mk_func_decl(m_fid, OP_ARRAY_EXT, 1, &p, 2, domains); +} diff --git a/src/ast/array_decl_plugin.h b/src/ast/array_decl_plugin.h index 0704fe56a..1257ab2c6 100644 --- a/src/ast/array_decl_plugin.h +++ b/src/ast/array_decl_plugin.h @@ -143,6 +143,7 @@ public: bool is_const(expr* n) const { return is_app_of(n, m_fid, OP_CONST_ARRAY); } bool is_map(expr* n) const { return is_app_of(n, m_fid, OP_ARRAY_MAP); } bool is_as_array(expr * n) const { return is_app_of(n, m_fid, OP_AS_ARRAY); } + bool is_as_array(expr * n, func_decl*& f) const { return is_as_array(n) && (f = get_as_array_func_decl(n), true); } bool is_select(func_decl* f) const { return is_decl_of(f, m_fid, OP_SELECT); } bool is_store(func_decl* f) const { return is_decl_of(f, m_fid, OP_STORE); } bool is_const(func_decl* f) const { return is_decl_of(f, m_fid, OP_CONST_ARRAY); } @@ -182,12 +183,15 @@ public: return mk_const_array(s, m_manager.mk_true()); } + func_decl * mk_array_ext(sort* domain, unsigned i); + sort * mk_array_sort(sort* dom, sort* range) { return mk_array_sort(1, &dom, range); } sort * mk_array_sort(unsigned arity, sort* const* domain, sort* range); - app * mk_as_array(sort * s, func_decl * f) { + app * mk_as_array(func_decl * f) { parameter param(f); + sort * s = f->get_range(); return m_manager.mk_app(m_fid, OP_AS_ARRAY, 1, ¶m, 0, 0, s); } }; diff --git a/src/ast/fpa/bv2fpa_converter.cpp b/src/ast/fpa/bv2fpa_converter.cpp index 93bd79571..2f5a7c3c1 100644 --- a/src/ast/fpa/bv2fpa_converter.cpp +++ b/src/ast/fpa/bv2fpa_converter.cpp @@ -250,7 +250,7 @@ bv2fpa_converter::array_model bv2fpa_converter::convert_array_func_interp(model_ am.new_float_fd = m.mk_fresh_func_decl(arity, array_domain.c_ptr(), rng); am.new_float_fi = convert_func_interp(mc, am.new_float_fd, bv_f); am.bv_fd = bv_f; - am.result = arr_util.mk_as_array(f->get_range(), am.new_float_fd); + am.result = arr_util.mk_as_array(am.new_float_fd); return am; } diff --git a/src/smt/theory_array.cpp b/src/smt/theory_array.cpp index 18fc9f50b..b8f76f9ad 100644 --- a/src/smt/theory_array.cpp +++ b/src/smt/theory_array.cpp @@ -53,18 +53,12 @@ namespace smt { var_data * d2 = m_var_data[v2]; if (!d1->m_prop_upward && d2->m_prop_upward) set_prop_upward(v1); - ptr_vector::iterator it = d2->m_stores.begin(); - ptr_vector::iterator end = d2->m_stores.end(); - for (; it != end; ++it) - add_store(v1, *it); - it = d2->m_parent_stores.begin(); - end = d2->m_parent_stores.end(); - for (; it != end; ++it) - add_parent_store(v1, *it); - it = d2->m_parent_selects.begin(); - end = d2->m_parent_selects.end(); - for (; it != end; ++it) - add_parent_select(v1, *it); + for (enode* n : d2->m_stores) + add_store(v1, n); + for (enode* n : d2->m_parent_stores) + add_parent_store(v1, n); + for (enode* n : d2->m_parent_selects) + add_parent_select(v1, n); TRACE("array", tout << "after merge\n"; display_var(tout, v1);); } @@ -103,16 +97,11 @@ namespace smt { d->m_parent_selects.push_back(s); TRACE("array", tout << mk_pp(s->get_owner(), get_manager()) << " " << mk_pp(get_enode(v)->get_owner(), get_manager()) << "\n";); m_trail_stack.push(push_back_trail(d->m_parent_selects)); - ptr_vector::iterator it = d->m_stores.begin(); - ptr_vector::iterator end = d->m_stores.end(); - for (; it != end; ++it) { - instantiate_axiom2a(s, *it); + for (enode* n : d->m_stores) { + instantiate_axiom2a(s, n); } if (!m_params.m_array_weak && !m_params.m_array_delay_exp_axiom && d->m_prop_upward) { - it = d->m_parent_stores.begin(); - end = d->m_parent_stores.end(); - for (; it != end; ++it) { - enode * store = *it; + for (enode* store : d->m_parent_stores) { SASSERT(is_store(store)); if (!m_params.m_array_cg || store->is_cgr()) { instantiate_axiom2b(s, store); @@ -129,27 +118,19 @@ namespace smt { var_data * d = m_var_data[v]; d->m_parent_stores.push_back(s); m_trail_stack.push(push_back_trail(d->m_parent_stores)); - if (!m_params.m_array_weak && !m_params.m_array_delay_exp_axiom && d->m_prop_upward) { - ptr_vector::iterator it = d->m_parent_selects.begin(); - ptr_vector::iterator end = d->m_parent_selects.end(); - for (; it != end; ++it) - if (!m_params.m_array_cg || (*it)->is_cgr()) - instantiate_axiom2b(*it, s); - } + if (!m_params.m_array_weak && !m_params.m_array_delay_exp_axiom && d->m_prop_upward) + for (enode* n : d->m_parent_selects) + if (!m_params.m_array_cg || n->is_cgr()) + instantiate_axiom2b(n, s); } bool theory_array::instantiate_axiom2b_for(theory_var v) { bool result = false; var_data * d = m_var_data[v]; - ptr_vector::iterator it = d->m_parent_stores.begin(); - ptr_vector::iterator end = d->m_parent_stores.end(); - for (; it != end; ++it) { - ptr_vector::iterator it2 = d->m_parent_selects.begin(); - ptr_vector::iterator end2 = d->m_parent_selects.end(); - for (; it2 != end2; ++it2) - if (instantiate_axiom2b(*it2, *it)) + for (enode* n1 : d->m_parent_stores) + for (enode * n2 : d->m_parent_selects) + if (instantiate_axiom2b(n2, n1)) result = true; - } return result; } @@ -167,10 +148,8 @@ namespace smt { d->m_prop_upward = true; if (!m_params.m_array_delay_exp_axiom) instantiate_axiom2b_for(v); - ptr_vector::iterator it = d->m_stores.begin(); - ptr_vector::iterator end = d->m_stores.end(); - for (; it != end; ++it) - set_prop_upward(*it); + for (enode * n : d->m_stores) + set_prop_upward(n); } } @@ -209,11 +188,9 @@ namespace smt { } d->m_stores.push_back(s); m_trail_stack.push(push_back_trail(d->m_stores)); - ptr_vector::iterator it = d->m_parent_selects.begin(); - ptr_vector::iterator end = d->m_parent_selects.end(); - for (; it != end; ++it) { - SASSERT(is_select(*it)); - instantiate_axiom2a(*it, s); + for (enode * n : d->m_parent_selects) { + SASSERT(is_select(n)); + instantiate_axiom2a(n, s); } if (m_params.m_array_always_prop_upward || lambda_equiv_class_size >= 1) set_prop_upward(s); @@ -374,7 +351,7 @@ namespace smt { final_check_status theory_array::final_check_eh() { m_final_check_idx++; - final_check_status r; + final_check_status r = FC_DONE; if (m_params.m_array_lazy_ieq) { // Delay the creation of interface equalities... The // motivation is too give other theories and quantifier diff --git a/src/smt/theory_array_base.cpp b/src/smt/theory_array_base.cpp index 21df02c76..2aaf2833f 100644 --- a/src/smt/theory_array_base.cpp +++ b/src/smt/theory_array_base.cpp @@ -210,17 +210,16 @@ namespace smt { - func_decl_ref_vector * theory_array_base::register_sort(sort * s_array) { unsigned dimension = get_dimension(s_array); func_decl_ref_vector * ext_skolems = 0; if (!m_sort2skolem.find(s_array, ext_skolems)) { + array_util util(get_manager()); ast_manager & m = get_manager(); ext_skolems = alloc(func_decl_ref_vector, m); for (unsigned i = 0; i < dimension; ++i) { sort * ext_sk_domain[2] = { s_array, s_array }; - parameter p(i); - func_decl * ext_sk_decl = m.mk_func_decl(get_id(), OP_ARRAY_EXT, 1, &p, 2, ext_sk_domain); + func_decl * ext_sk_decl = util.mk_array_ext(s_array, i); ext_skolems->push_back(ext_sk_decl); } m_sort2skolem.insert(s_array, ext_skolems); diff --git a/src/tactic/bv/bvarray2uf_rewriter.cpp b/src/tactic/bv/bvarray2uf_rewriter.cpp index 9b67e7011..b92092739 100644 --- a/src/tactic/bv/bvarray2uf_rewriter.cpp +++ b/src/tactic/bv/bvarray2uf_rewriter.cpp @@ -117,7 +117,7 @@ func_decl_ref bvarray2uf_rewriter_cfg::mk_uf_for_array(expr * e) { if (is_uninterp_const(e)) { if (m_emc) m_emc->insert(to_app(e)->get_decl(), - m_array_util.mk_as_array(m_manager.get_sort(e), bv_f)); + m_array_util.mk_as_array(bv_f)); } else if (m_fmc) m_fmc->insert(bv_f); @@ -193,7 +193,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr if (is_uninterp_const(e)) { if (m_emc) m_emc->insert(e->get_decl(), - m_array_util.mk_as_array(m_manager.get_sort(e), bv_f)); + m_array_util.mk_as_array(bv_f)); } else if (m_fmc) m_fmc->insert(bv_f); @@ -207,7 +207,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr q = m_manager.mk_forall(1, sorts, names, body); extra_assertions.push_back(q); - result = m_array_util.mk_as_array(f->get_range(), bv_f); + result = m_array_util.mk_as_array(bv_f); TRACE("bvarray2uf_rw", tout << "result: " << mk_ismt2_pp(result, m_manager) << ")" << std::endl;); res = BR_DONE; @@ -234,7 +234,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr if (is_bv_array(t)) { // From [1]: For every array term t we create a fresh uninterpreted function f_t. f_t = mk_uf_for_array(t); - result = m_array_util.mk_as_array(m_manager.get_sort(t), f_t); + result = m_array_util.mk_as_array(f_t); res = BR_DONE; } else if (has_bv_arrays) { @@ -274,7 +274,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr expr * v = args[0]; func_decl_ref f_t(mk_uf_for_array(t), m_manager); - result = m_array_util.mk_as_array(f->get_range(), f_t); + result = m_array_util.mk_as_array(f_t); res = BR_DONE; // Add \forall x . f_t(x) = v @@ -321,7 +321,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr expr_ref frllx(m_manager.mk_forall(1, sorts, names, body), m_manager); extra_assertions.push_back(frllx); - result = m_array_util.mk_as_array(f->get_range(), f_t); + result = m_array_util.mk_as_array(f_t); res = BR_DONE; } else if (m_array_util.is_store(f)) { @@ -342,7 +342,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr func_decl_ref f_s(mk_uf_for_array(s), m_manager); func_decl_ref f_t(mk_uf_for_array(t), m_manager); - result = m_array_util.mk_as_array(f->get_range(), f_t); + result = m_array_util.mk_as_array(f_t); res = BR_DONE; sort * sorts[1] = { get_index_sort(f->get_range()) }; From d2e27f6f1f33cf6e0ae05cb78976a35fd6423f5f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 19 Oct 2017 11:25:44 -0700 Subject: [PATCH 448/488] remove redundant and wrong range type, in extension to changes made for #1223 Signed-off-by: Nikolaj Bjorner --- src/ast/array_decl_plugin.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ast/array_decl_plugin.h b/src/ast/array_decl_plugin.h index 1257ab2c6..911bb3f27 100644 --- a/src/ast/array_decl_plugin.h +++ b/src/ast/array_decl_plugin.h @@ -191,8 +191,7 @@ public: app * mk_as_array(func_decl * f) { parameter param(f); - sort * s = f->get_range(); - return m_manager.mk_app(m_fid, OP_AS_ARRAY, 1, ¶m, 0, 0, s); + return m_manager.mk_app(m_fid, OP_AS_ARRAY, 1, ¶m, 0, 0, 0); } }; From ce1c8f7be29f5c9bf4f22e1c697d4032e0828ee7 Mon Sep 17 00:00:00 2001 From: Murphy Berzish Date: Thu, 19 Oct 2017 17:01:10 -0400 Subject: [PATCH 449/488] remove debug code --- src/smt/theory_str.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 41d42c867..7e5685f9c 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -8889,8 +8889,6 @@ namespace smt { TRACE("str", tout << "backpropagate into " << mk_pp(var, m) << " = " << mk_pp(concat, m) << std::endl << "LHS ~= " << mk_pp(concat_lhs_str, m) << " RHS ~= " << mk_pp(concat_rhs_str, m) << std::endl;); - TRACE("str_enode_bug", tout << "backpropagate into " << mk_pp(var, m) << " = " << mk_pp(concat, m) << std::endl - << "LHS ~= " << mk_pp(concat_lhs_str, m) << " RHS ~= " << mk_pp(concat_rhs_str, m) << std::endl;); zstring lhsString, rhsString; u.str.is_string(concat_lhs_str, lhsString); u.str.is_string(concat_rhs_str, rhsString); @@ -8912,8 +8910,6 @@ namespace smt { } else { expr_ref lhs(mk_and(lhs_terms), m); expr_ref rhs(ctx.mk_eq_atom(concat, mk_string(concatString)), m); - TRACE("str_enode_bug", tout << "axiom LHS: " << mk_pp(lhs, m) << std::endl;); - TRACE("str_enode_bug", tout << "axiom RHS: " << mk_pp(rhs, m) << std::endl;); assert_implication(lhs, rhs); } backpropagation_occurred = true; From b2191cab020718362d544bad6e7624cf30948c97 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 21 Oct 2017 18:46:35 -0400 Subject: [PATCH 450/488] disable eager clear of check-sat-result to fix #1318 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 9615e86ce..77dce80c8 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -774,7 +774,6 @@ bool cmd_context::is_func_decl(symbol const & s) const { } void cmd_context::insert(symbol const & s, func_decl * f) { - m_check_sat_result = 0; if (!m_check_logic(f)) { throw cmd_exception(m_check_logic.get_last_error()); } @@ -805,7 +804,6 @@ void cmd_context::insert(symbol const & s, func_decl * f) { } void cmd_context::insert(symbol const & s, psort_decl * p) { - m_check_sat_result = 0; if (m_psort_decls.contains(s)) { throw cmd_exception("sort already defined ", s); } @@ -819,7 +817,6 @@ void cmd_context::insert(symbol const & s, psort_decl * p) { void cmd_context::insert(symbol const & s, unsigned arity, sort *const* domain, expr * t) { expr_ref _t(t, m()); - m_check_sat_result = 0; if (m_builtin_decls.contains(s)) { throw cmd_exception("invalid macro/named expression, builtin symbol ", s); } From 42fbe19814cdb25d450b4e222252a6ded6361fa0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 21 Oct 2017 18:56:36 -0400 Subject: [PATCH 451/488] fix #1316, segmentation fault when numeric value is not internalized Signed-off-by: Nikolaj Bjorner --- src/smt/theory_seq.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 44ce804e7..d55484384 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -3466,6 +3466,8 @@ static bool get_arith_value(context& ctx, theory_id afid, expr* e, expr_ref& v) bool theory_seq::get_num_value(expr* e, rational& val) const { context& ctx = get_context(); expr_ref _val(m); + if (!ctx.e_internalized(e)) + return false; enode* next = ctx.get_enode(e), *n = next; do { if (get_arith_value(ctx, m_autil.get_family_id(), next->get_owner(), _val) && m_autil.is_numeral(_val, val) && val.is_int()) { From 77bbae65f5d602e1cf3cec81fb27720cd89a4370 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 23 Oct 2017 08:17:38 -0700 Subject: [PATCH 452/488] fix #1319, fix #1320 Signed-off-by: Nikolaj Bjorner --- src/muz/base/dl_context.cpp | 3 ++- src/muz/fp/dl_cmds.cpp | 3 ++- src/parsers/smt2/smt2parser.cpp | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 97a2c841a..6c0537936 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -453,7 +453,8 @@ namespace datalog { return new_pred; } - void context::add_rule(expr* rl, symbol const& name, unsigned bound) { + void context::add_rule(expr* rl, symbol const& name, unsigned bound) { + SASSERT(rl); m_rule_fmls.push_back(rl); m_rule_names.push_back(name); m_rule_bounds.push_back(bound); diff --git a/src/muz/fp/dl_cmds.cpp b/src/muz/fp/dl_cmds.cpp index 42c614912..2610f821c 100644 --- a/src/muz/fp/dl_cmds.cpp +++ b/src/muz/fp/dl_cmds.cpp @@ -189,11 +189,12 @@ public: m_bound = bound; m_arg_idx++; } - virtual void reset(cmd_context & ctx) { m_dl_ctx->reset(); prepare(ctx); } + virtual void reset(cmd_context & ctx) { m_dl_ctx->reset(); prepare(ctx); m_t = nullptr; } virtual void prepare(cmd_context& ctx) { m_arg_idx = 0; m_name = symbol::null; m_bound = UINT_MAX; } virtual void finalize(cmd_context & ctx) { } virtual void execute(cmd_context & ctx) { + if (!m_t) throw cmd_exception("invalid rule, expected formula"); m_dl_ctx->add_rule(m_t, m_name, m_bound); } }; diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index b43ee9f6e..fd592f7c7 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -1881,6 +1881,8 @@ namespace smt2 { // the resultant expression is on the top of the stack TRACE("let_frame", tout << "let result expr: " << mk_pp(expr_stack().back(), m()) << "\n";); expr_ref r(m()); + if (expr_stack().empty()) + throw parser_exception("invalid let expression"); r = expr_stack().back(); expr_stack().pop_back(); // remove local declarations from the stack From f63439603d3704f26b1d8e6030a7088840d0c314 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 23 Oct 2017 21:16:46 -0700 Subject: [PATCH 453/488] streamlining proof generation (initial step of removing ast-manager dependency). Detect error in model creation when declaring constant with non-zero arity. See #1223 Signed-off-by: Nikolaj Bjorner --- examples/c/test_capi.c | 2 + src/api/api_interp.cpp | 2 +- src/api/api_model.cpp | 9 +- src/ast/ast.cpp | 90 ++++++++---------- src/ast/ast.h | 8 +- src/ast/normal_forms/pull_quant.cpp | 4 +- src/ast/pattern/pattern_inference.cpp | 6 +- src/ast/scoped_proof.h | 2 +- src/cmd_context/context_params.cpp | 2 +- src/cmd_context/interpolant_cmds.cpp | 2 +- src/muz/base/dl_context.cpp | 2 +- src/muz/base/dl_rule.cpp | 4 +- src/muz/pdr/pdr_context.cpp | 2 +- src/muz/pdr/pdr_farkas_learner.cpp | 2 +- src/muz/spacer/spacer_context.cpp | 2 +- src/muz/spacer/spacer_itp_solver.h | 4 +- src/muz/spacer/spacer_util.cpp | 131 ++++++++++++-------------- src/parsers/smt/smtlib_solver.cpp | 2 +- src/smt/smt_conflict_resolution.cpp | 4 +- src/smt/smt_justification.cpp | 2 +- 20 files changed, 129 insertions(+), 153 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 6327ad40f..fa27c7887 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2843,6 +2843,8 @@ void fpa_example() { /*@}*/ /*@}*/ + + int main() { #ifdef LOG_Z3_CALLS Z3_open_log("z3.log"); diff --git a/src/api/api_interp.cpp b/src/api/api_interp.cpp index fb2699e0a..416c71adf 100644 --- a/src/api/api_interp.cpp +++ b/src/api/api_interp.cpp @@ -249,7 +249,7 @@ extern "C" { params_ref _p; _p.set_bool("proof", true); // this is currently useless - scoped_proof_mode spm(mk_c(c)->m(), PGM_FINE); + scoped_proof_mode spm(mk_c(c)->m(), PGM_ENABLED); scoped_ptr sf = mk_smt_solver_factory(); scoped_ptr m_solver((*sf)(mk_c(c)->m(), _p, true, true, true, ::symbol::null)); m_solver.get()->updt_params(_p); // why do we have to do this? diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index 540f014c6..bda33f186 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -255,8 +255,13 @@ extern "C" { LOG_Z3_add_const_interp(c, m, f, a); RESET_ERROR_CODE(); func_decl* d = to_func_decl(f); - model* mdl = to_model_ref(m); - mdl->register_decl(d, to_expr(a)); + if (d->get_arity() != 0) { + SET_ERROR_CODE(Z3_INVALID_ARG); + } + else { + model* mdl = to_model_ref(m); + mdl->register_decl(d, to_expr(a)); + } Z3_CATCH; } diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 9116c5d95..f903dc623 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -2626,7 +2626,7 @@ bool ast_manager::is_fully_interp(sort * s) const { // ----------------------------------- proof * ast_manager::mk_proof(family_id fid, decl_kind k, unsigned num_args, expr * const * args) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(fid, k, num_args, args); } @@ -2662,8 +2662,7 @@ proof * ast_manager::mk_goal(expr * f) { } proof * ast_manager::mk_modus_ponens(proof * p1, proof * p2) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; + if (!p1 || !p2) return nullptr; SASSERT(has_fact(p1)); SASSERT(has_fact(p2)); CTRACE("mk_modus_ponens", !(is_implies(get_fact(p2)) || is_iff(get_fact(p2)) || is_oeq(get_fact(p2))), @@ -2684,13 +2683,13 @@ proof * ast_manager::mk_modus_ponens(proof * p1, proof * p2) { } proof * ast_manager::mk_reflexivity(expr * e) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_REFLEXIVITY, mk_eq(e, e)); } proof * ast_manager::mk_oeq_reflexivity(expr * e) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_REFLEXIVITY, mk_oeq(e, e)); } @@ -2705,8 +2704,7 @@ proof * ast_manager::mk_commutativity(app * f) { \brief Given a proof of p, return a proof of (p <=> true) */ proof * ast_manager::mk_iff_true(proof * pr) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; + if (!pr) return pr; SASSERT(has_fact(pr)); SASSERT(is_bool(get_fact(pr))); return mk_app(m_basic_family_id, PR_IFF_TRUE, pr, mk_iff(get_fact(pr), mk_true())); @@ -2716,8 +2714,7 @@ proof * ast_manager::mk_iff_true(proof * pr) { \brief Given a proof of (not p), return a proof of (p <=> false) */ proof * ast_manager::mk_iff_false(proof * pr) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; + if (!pr) return pr; SASSERT(has_fact(pr)); SASSERT(is_not(get_fact(pr))); expr * p = to_app(get_fact(pr))->get_arg(0); @@ -2725,10 +2722,7 @@ proof * ast_manager::mk_iff_false(proof * pr) { } proof * ast_manager::mk_symmetry(proof * p) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; - if (!p) - return p; + if (!p) return p; if (is_reflexivity(p)) return p; if (is_symmetry(p)) @@ -2741,8 +2735,6 @@ proof * ast_manager::mk_symmetry(proof * p) { } proof * ast_manager::mk_transitivity(proof * p1, proof * p2) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; if (!p1) return p2; if (!p2) @@ -2787,7 +2779,7 @@ proof * ast_manager::mk_transitivity(proof * p1, proof * p2, proof * p3, proof * } proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(num_proofs > 0); proof * r = proofs[0]; @@ -2797,9 +2789,9 @@ proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs } proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs, expr * n1, expr * n2) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; - if (fine_grain_proofs()) + if (proofs_enabled()) return mk_transitivity(num_proofs, proofs); SASSERT(num_proofs > 0); if (num_proofs == 1) @@ -2817,7 +2809,7 @@ proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs } proof * ast_manager::mk_monotonicity(func_decl * R, app * f1, app * f2, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(f1->get_num_args() == f2->get_num_args()); SASSERT(f1->get_decl() == f2->get_decl()); @@ -2828,7 +2820,7 @@ proof * ast_manager::mk_monotonicity(func_decl * R, app * f1, app * f2, unsigned } proof * ast_manager::mk_congruence(app * f1, app * f2, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(get_sort(f1) == get_sort(f2)); sort * s = get_sort(f1); @@ -2837,7 +2829,7 @@ proof * ast_manager::mk_congruence(app * f1, app * f2, unsigned num_proofs, proo } proof * ast_manager::mk_oeq_congruence(app * f1, app * f2, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(get_sort(f1) == get_sort(f2)); sort * s = get_sort(f1); @@ -2846,7 +2838,7 @@ proof * ast_manager::mk_oeq_congruence(app * f1, app * f2, unsigned num_proofs, } proof * ast_manager::mk_quant_intro(quantifier * q1, quantifier * q2, proof * p) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; if (!p) { return 0; @@ -2858,7 +2850,7 @@ proof * ast_manager::mk_quant_intro(quantifier * q1, quantifier * q2, proof * p) } proof * ast_manager::mk_oeq_quant_intro(quantifier * q1, quantifier * q2, proof * p) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(q1->get_num_decls() == q2->get_num_decls()); SASSERT(has_fact(p)); @@ -2867,25 +2859,25 @@ proof * ast_manager::mk_oeq_quant_intro(quantifier * q1, quantifier * q2, proof } proof * ast_manager::mk_distributivity(expr * s, expr * r) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_DISTRIBUTIVITY, mk_eq(s, r)); } proof * ast_manager::mk_rewrite(expr * s, expr * t) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_REWRITE, mk_eq(s, t)); } proof * ast_manager::mk_oeq_rewrite(expr * s, expr * t) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_REWRITE, mk_oeq(s, t)); } proof * ast_manager::mk_rewrite_star(expr * s, expr * t, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; ptr_buffer args; args.append(num_proofs, (expr**) proofs); @@ -2894,37 +2886,37 @@ proof * ast_manager::mk_rewrite_star(expr * s, expr * t, unsigned num_proofs, pr } proof * ast_manager::mk_pull_quant(expr * e, quantifier * q) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_PULL_QUANT, mk_iff(e, q)); } proof * ast_manager::mk_pull_quant_star(expr * e, quantifier * q) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_PULL_QUANT_STAR, mk_iff(e, q)); } proof * ast_manager::mk_push_quant(quantifier * q, expr * e) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_PUSH_QUANT, mk_iff(q, e)); } proof * ast_manager::mk_elim_unused_vars(quantifier * q, expr * e) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_ELIM_UNUSED_VARS, mk_iff(q, e)); } proof * ast_manager::mk_der(quantifier * q, expr * e) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_DER, mk_iff(q, e)); } proof * ast_manager::mk_quant_inst(expr * not_q_or_i, unsigned num_bind, expr* const* binding) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; vector params; for (unsigned i = 0; i < num_bind; ++i) { @@ -2959,7 +2951,7 @@ bool ast_manager::is_rewrite(expr const* e, expr*& r1, expr*& r2) const { } proof * ast_manager::mk_def_axiom(expr * ax) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_DEF_AXIOM, ax); } @@ -3001,7 +2993,7 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro new_lits.push_back(lit); } DEBUG_CODE({ - for (unsigned i = 1; m_proof_mode == PGM_FINE && i < num_proofs; i++) { + for (unsigned i = 1; proofs_enabled() && i < num_proofs; i++) { CTRACE("mk_unit_resolution_bug", !found.get(i, false), for (unsigned j = 0; j < num_proofs; j++) { if (j == i) tout << "Index " << i << " was not found:\n"; @@ -3080,14 +3072,11 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro } proof * ast_manager::mk_hypothesis(expr * h) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; return mk_app(m_basic_family_id, PR_HYPOTHESIS, h); } proof * ast_manager::mk_lemma(proof * p, expr * lemma) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; + if (!p) return p; SASSERT(has_fact(p)); CTRACE("mk_lemma", !is_false(get_fact(p)), tout << mk_ll_pp(p, *this) << "\n";); SASSERT(is_false(get_fact(p))); @@ -3100,7 +3089,7 @@ proof * ast_manager::mk_def_intro(expr * new_def) { } proof * ast_manager::mk_apply_defs(expr * n, expr * def, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; ptr_buffer args; args.append(num_proofs, (expr**) proofs); @@ -3109,10 +3098,7 @@ proof * ast_manager::mk_apply_defs(expr * n, expr * def, unsigned num_proofs, pr } proof * ast_manager::mk_iff_oeq(proof * p) { - if (m_proof_mode == PGM_DISABLED) - return m_undef_proof; - if (!p) - return p; + if (!p) return p; SASSERT(has_fact(p)); SASSERT(is_iff(get_fact(p)) || is_oeq(get_fact(p))); @@ -3136,7 +3122,7 @@ bool ast_manager::check_nnf_proof_parents(unsigned num_proofs, proof * const * p } proof * ast_manager::mk_nnf_pos(expr * s, expr * t, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; check_nnf_proof_parents(num_proofs, proofs); ptr_buffer args; @@ -3146,7 +3132,7 @@ proof * ast_manager::mk_nnf_pos(expr * s, expr * t, unsigned num_proofs, proof * } proof * ast_manager::mk_nnf_neg(expr * s, expr * t, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; check_nnf_proof_parents(num_proofs, proofs); ptr_buffer args; @@ -3156,7 +3142,7 @@ proof * ast_manager::mk_nnf_neg(expr * s, expr * t, unsigned num_proofs, proof * } proof * ast_manager::mk_nnf_star(expr * s, expr * t, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; ptr_buffer args; args.append(num_proofs, (expr**) proofs); @@ -3165,7 +3151,7 @@ proof * ast_manager::mk_nnf_star(expr * s, expr * t, unsigned num_proofs, proof } proof * ast_manager::mk_skolemization(expr * q, expr * e) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(is_bool(q)); SASSERT(is_bool(e)); @@ -3173,7 +3159,7 @@ proof * ast_manager::mk_skolemization(expr * q, expr * e) { } proof * ast_manager::mk_cnf_star(expr * s, expr * t, unsigned num_proofs, proof * const * proofs) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; ptr_buffer args; args.append(num_proofs, (expr**) proofs); @@ -3182,7 +3168,7 @@ proof * ast_manager::mk_cnf_star(expr * s, expr * t, unsigned num_proofs, proof } proof * ast_manager::mk_and_elim(proof * p, unsigned i) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(has_fact(p)); SASSERT(is_and(get_fact(p))); @@ -3193,7 +3179,7 @@ proof * ast_manager::mk_and_elim(proof * p, unsigned i) { } proof * ast_manager::mk_not_or_elim(proof * p, unsigned i) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; SASSERT(has_fact(p)); SASSERT(is_not(get_fact(p))); @@ -3216,7 +3202,7 @@ proof * ast_manager::mk_th_lemma( unsigned num_params, parameter const* params ) { - if (m_proof_mode == PGM_DISABLED) + if (proofs_disabled()) return m_undef_proof; ptr_buffer args; diff --git a/src/ast/ast.h b/src/ast/ast.h index 7e1645753..2d06d03de 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -1396,8 +1396,7 @@ public: enum proof_gen_mode { PGM_DISABLED, - PGM_COARSE, - PGM_FINE + PGM_ENABLED }; // ----------------------------------- @@ -2088,15 +2087,14 @@ protected: proof * mk_proof(family_id fid, decl_kind k, expr * arg1, expr * arg2); proof * mk_proof(family_id fid, decl_kind k, expr * arg1, expr * arg2, expr * arg3); + proof * mk_undef_proof() const { return m_undef_proof; } + public: bool proofs_enabled() const { return m_proof_mode != PGM_DISABLED; } bool proofs_disabled() const { return m_proof_mode == PGM_DISABLED; } - bool coarse_grain_proofs() const { return m_proof_mode == PGM_COARSE; } - bool fine_grain_proofs() const { return m_proof_mode == PGM_FINE; } proof_gen_mode proof_mode() const { return m_proof_mode; } void toggle_proof_mode(proof_gen_mode m) { m_proof_mode = m; } // APIs for creating proof objects return [undef] - proof * mk_undef_proof() const { return m_undef_proof; } bool is_proof(expr const * n) const { return is_app(n) && to_app(n)->get_decl()->get_range() == m_proof_sort; } diff --git a/src/ast/normal_forms/pull_quant.cpp b/src/ast/normal_forms/pull_quant.cpp index 239fd9008..ee618c747 100644 --- a/src/ast/normal_forms/pull_quant.cpp +++ b/src/ast/normal_forms/pull_quant.cpp @@ -229,7 +229,7 @@ struct pull_quant::imp { proofs.push_back(m_manager.mk_pull_quant(arg, to_quantifier(new_arg))); } pull_quant1(to_app(n)->get_decl(), new_args.size(), new_args.c_ptr(), r); - if (m_manager.fine_grain_proofs()) { + if (m_manager.proofs_enabled()) { app * r1 = m_manager.mk_app(to_app(n)->get_decl(), new_args.size(), new_args.c_ptr()); proof * p1 = proofs.empty() ? 0 : m_manager.mk_congruence(to_app(n), r1, proofs.size(), proofs.c_ptr()); proof * p2 = r1 == r ? 0 : m_manager.mk_pull_quant(r1, to_quantifier(r)); @@ -240,7 +240,7 @@ struct pull_quant::imp { expr_ref new_expr(m_manager); pull_quant1(to_quantifier(n)->get_expr(), new_expr); pull_quant1(to_quantifier(n), new_expr, r); - if (m_manager.fine_grain_proofs()) { + if (m_manager.proofs_enabled()) { quantifier * q1 = m_manager.update_quantifier(to_quantifier(n), new_expr); proof * p1 = 0; if (n != q1) { diff --git a/src/ast/pattern/pattern_inference.cpp b/src/ast/pattern/pattern_inference.cpp index 6a91dd85e..17d8747f2 100644 --- a/src/ast/pattern/pattern_inference.cpp +++ b/src/ast/pattern/pattern_inference.cpp @@ -606,7 +606,7 @@ bool pattern_inference_cfg::reduce_quantifier( result = m.update_quantifier_weight(tmp, new_weight); TRACE("pattern_inference", tout << "found patterns in database, weight: " << new_weight << "\n" << mk_pp(new_q, m) << "\n";); } - if (m.fine_grain_proofs()) + if (m.proofs_enabled()) result_pr = m.mk_rewrite(q, new_q); return true; } @@ -671,7 +671,7 @@ bool pattern_inference_cfg::reduce_quantifier( quantifier_ref new_q(m.update_quantifier(q, new_patterns.size(), (expr**) new_patterns.c_ptr(), new_body), m); if (weight != q->get_weight()) new_q = m.update_quantifier_weight(new_q, weight); - if (m.fine_grain_proofs()) { + if (m.proofs_enabled()) { proof* new_body_pr = m.mk_reflexivity(new_body); result_pr = m.mk_quant_intro(q, new_q, new_body_pr); } @@ -689,7 +689,7 @@ bool pattern_inference_cfg::reduce_quantifier( warning_msg("pulled nested quantifier to be able to find an useable pattern (quantifier id: %s)", q->get_qid().str().c_str()); } new_q = m.update_quantifier(result2, new_patterns.size(), (expr**) new_patterns.c_ptr(), result2->get_expr()); - if (m.fine_grain_proofs()) { + if (m.proofs_enabled()) { result_pr = m.mk_transitivity(new_pr, m.mk_quant_intro(result2, new_q, m.mk_reflexivity(new_q->get_expr()))); } TRACE("pattern_inference", tout << "pulled quantifier:\n" << mk_pp(new_q, m) << "\n";); diff --git a/src/ast/scoped_proof.h b/src/ast/scoped_proof.h index 0a650ceb7..b2b3d7173 100644 --- a/src/ast/scoped_proof.h +++ b/src/ast/scoped_proof.h @@ -37,7 +37,7 @@ public: class scoped_proof : public scoped_proof_mode { public: - scoped_proof(ast_manager& m): scoped_proof_mode(m, PGM_FINE) {} + scoped_proof(ast_manager& m): scoped_proof_mode(m, PGM_ENABLED) {} }; class scoped_no_proof : public scoped_proof_mode { diff --git a/src/cmd_context/context_params.cpp b/src/cmd_context/context_params.cpp index 9a3339b84..f8646d41c 100644 --- a/src/cmd_context/context_params.cpp +++ b/src/cmd_context/context_params.cpp @@ -192,7 +192,7 @@ void context_params::get_solver_params(ast_manager const & m, params_ref & p, bo ast_manager * context_params::mk_ast_manager() { ast_manager * r = alloc(ast_manager, - m_proof ? PGM_FINE : PGM_DISABLED, + m_proof ? PGM_ENABLED : PGM_DISABLED, m_trace ? m_trace_file_name.c_str() : 0); if (m_smtlib2_compliant) r->enable_int_real_coercions(false); diff --git a/src/cmd_context/interpolant_cmds.cpp b/src/cmd_context/interpolant_cmds.cpp index b5bbea18c..8b9f0ebd8 100644 --- a/src/cmd_context/interpolant_cmds.cpp +++ b/src/cmd_context/interpolant_cmds.cpp @@ -147,7 +147,7 @@ static void compute_interpolant_and_maybe_check(cmd_context & ctx, expr * t, par ast_manager &_m = ctx.m(); // TODO: the following is a HACK to enable proofs in the old smt solver // When we stop using that solver, this hack can be removed - scoped_proof_mode spm(_m,PGM_FINE); + scoped_proof_mode spm(_m,PGM_ENABLED); ctx.params().get_solver_params(_m, p, proofs_enabled, models_enabled, unsat_core_enabled); p.set_bool("proof", true); scoped_ptr sp = (ctx.get_interpolating_solver_factory())(_m, p, true, models_enabled, false, ctx.get_logic()); diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 6c0537936..39e044ec3 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -462,7 +462,7 @@ namespace datalog { void context::flush_add_rules() { datalog::rule_manager& rm = get_rule_manager(); - scoped_proof_mode _scp(m, generate_proof_trace()?PGM_FINE:PGM_DISABLED); + scoped_proof_mode _scp(m, generate_proof_trace()?PGM_ENABLED:PGM_DISABLED); while (m_rule_fmls_head < m_rule_fmls.size()) { expr* fml = m_rule_fmls[m_rule_fmls_head].get(); proof* p = generate_proof_trace()?m.mk_asserted(fml):0; diff --git a/src/muz/base/dl_rule.cpp b/src/muz/base/dl_rule.cpp index 367795c9b..4f832c4c9 100644 --- a/src/muz/base/dl_rule.cpp +++ b/src/muz/base/dl_rule.cpp @@ -141,7 +141,7 @@ namespace datalog { void rule_manager::mk_rule(expr* fml, proof* p, rule_set& rules, symbol const& name) { - scoped_proof_mode _sc(m, m_ctx.generate_proof_trace()?PGM_FINE:PGM_DISABLED); + scoped_proof_mode _sc(m, m_ctx.generate_proof_trace()?PGM_ENABLED:PGM_DISABLED); proof_ref pr(p, m); expr_ref fml1(m); bind_variables(fml, true, fml1); @@ -343,7 +343,7 @@ namespace datalog { } TRACE("dl", tout << rule_expr << "\n";); - scoped_proof_mode _sc(m, m_ctx.generate_proof_trace()?PGM_FINE:PGM_DISABLED); + scoped_proof_mode _sc(m, m_ctx.generate_proof_trace()?PGM_ENABLED:PGM_DISABLED); proof_ref pr(m); if (m_ctx.generate_proof_trace()) { pr = m.mk_asserted(rule_expr); diff --git a/src/muz/pdr/pdr_context.cpp b/src/muz/pdr/pdr_context.cpp index fd734ea66..e6d91c87e 100644 --- a/src/muz/pdr/pdr_context.cpp +++ b/src/muz/pdr/pdr_context.cpp @@ -1825,7 +1825,7 @@ namespace pdr { m_core_generalizers.push_back(alloc(core_multi_generalizer, *this, 0)); } if (!classify.is_bool()) { - m.toggle_proof_mode(PGM_FINE); + m.toggle_proof_mode(PGM_ENABLED); m_fparams.m_arith_bound_prop = BP_NONE; m_fparams.m_arith_auto_config_simplex = true; m_fparams.m_arith_propagate_eqs = false; diff --git a/src/muz/pdr/pdr_farkas_learner.cpp b/src/muz/pdr/pdr_farkas_learner.cpp index 29037f180..4f47cb554 100644 --- a/src/muz/pdr/pdr_farkas_learner.cpp +++ b/src/muz/pdr/pdr_farkas_learner.cpp @@ -372,7 +372,7 @@ namespace pdr { farkas_learner::farkas_learner(smt_params& params, ast_manager& outer_mgr) : m_proof_params(get_proof_params(params)), - m_pr(PGM_FINE), + m_pr(PGM_ENABLED), m_constr(0), m_combine_farkas_coefficients(true), p2o(m_pr, outer_mgr), diff --git a/src/muz/spacer/spacer_context.cpp b/src/muz/spacer/spacer_context.cpp index f549205c3..7ab78d453 100644 --- a/src/muz/spacer/spacer_context.cpp +++ b/src/muz/spacer/spacer_context.cpp @@ -2139,7 +2139,7 @@ void context::reset_lemma_generalizers() void context::init_lemma_generalizers(datalog::rule_set& rules) { reset_lemma_generalizers(); - m.toggle_proof_mode(PGM_FINE); + m.toggle_proof_mode(PGM_ENABLED); smt_params &fparams = m_pm.fparams (); if (!m_params.spacer_eq_prop ()) { fparams.m_arith_bound_prop = BP_NONE; diff --git a/src/muz/spacer/spacer_itp_solver.h b/src/muz/spacer/spacer_itp_solver.h index fce2c4a9c..cab19c8ef 100644 --- a/src/muz/spacer/spacer_itp_solver.h +++ b/src/muz/spacer/spacer_itp_solver.h @@ -135,7 +135,7 @@ public: virtual expr * get_assumption(unsigned idx) const {return m_solver.get_assumption(idx);} virtual std::ostream &display(std::ostream &out) const - {m_solver.display(out); return out;} + { return m_solver.display(out); } /* check_sat_result interface */ @@ -170,7 +170,7 @@ public: public: scoped_bg(itp_solver &s) : m_s(s), m_bg_sz(m_s.get_num_bg()) {} ~scoped_bg() - {if(m_s.get_num_bg() > m_bg_sz) { m_s.pop_bg(m_s.get_num_bg() - m_bg_sz); }} + {if (m_s.get_num_bg() > m_bg_sz) { m_s.pop_bg(m_s.get_num_bg() - m_bg_sz); }} }; }; } diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp index a277c9ed6..31190a97f 100644 --- a/src/muz/spacer/spacer_util.cpp +++ b/src/muz/spacer/spacer_util.cpp @@ -72,73 +72,67 @@ namespace spacer { // model_evaluator_util::model_evaluator_util(ast_manager& m) : - m(m), m_mev(NULL) - { reset (NULL); } + m(m), m_mev(nullptr) { + reset (nullptr); + } model_evaluator_util::~model_evaluator_util() {reset (NULL);} -void model_evaluator_util::reset(model* model) -{ + void model_evaluator_util::reset(model* model) { if (m_mev) { dealloc(m_mev); m_mev = NULL; } m_model = model; - if (!m_model) { return; } + if (!m_model) { return; } m_mev = alloc(model_evaluator, *m_model); } - -bool model_evaluator_util::eval(expr *e, expr_ref &result, bool model_completion) -{ + + bool model_evaluator_util::eval(expr *e, expr_ref &result, bool model_completion) { m_mev->set_model_completion (model_completion); try { m_mev->operator() (e, result); return true; - } catch (model_evaluator_exception &ex) { + } + catch (model_evaluator_exception &ex) { (void)ex; TRACE("spacer_model_evaluator", tout << ex.msg () << "\n";); return false; } } - + bool model_evaluator_util::eval(const expr_ref_vector &v, - expr_ref& res, bool model_completion) -{ + expr_ref& res, bool model_completion) { expr_ref e(m); e = mk_and (v); return eval(e, res, model_completion); } - - -bool model_evaluator_util::is_true(const expr_ref_vector &v) -{ + + + bool model_evaluator_util::is_true(const expr_ref_vector &v) { expr_ref res(m); return eval (v, res, false) && m.is_true (res); } - -bool model_evaluator_util::is_false(expr *x) -{ + + bool model_evaluator_util::is_false(expr *x) { expr_ref res(m); return eval(x, res, false) && m.is_false (res); } -bool model_evaluator_util::is_true(expr *x) -{ + + bool model_evaluator_util::is_true(expr *x) { expr_ref res(m); return eval(x, res, false) && m.is_true (res); } - - -void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) -{ + + void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) { ast_manager& m = fml.get_manager(); expr_ref_vector conjs(m); flatten_and(fml, conjs); obj_map diseqs; expr* n, *lhs, *rhs; for (unsigned i = 0; i < conjs.size(); ++i) { - if (m.is_not(conjs[i].get(), n) && - m.is_eq(n, lhs, rhs)) { + if (m.is_not(conjs[i].get(), n) && m.is_eq(n, lhs, rhs)) { if (!m.is_value(rhs)) { std::swap(lhs, rhs); } @@ -157,12 +151,12 @@ void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) pr = m.mk_asserted(m.mk_true()); obj_map::iterator it = diseqs.begin(); obj_map::iterator end = diseqs.end(); - for (; it != end; ++it) { - if (it->m_value >= threshold) { - model.eval(it->m_key, val); - sub.insert(it->m_key, val, pr); - conjs.push_back(m.mk_eq(it->m_key, val)); - num_deleted += it->m_value; + for (auto const& kv : diseqs) { + if (kv.m_value >= threshold) { + model.eval(kv.m_key, val); + sub.insert(kv.m_key, val, pr); + conjs.push_back(m.mk_eq(kv.m_key, val)); + num_deleted += kv.m_value; } } if (orig_size < conjs.size()) { @@ -178,14 +172,17 @@ void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) SASSERT(orig_size <= 1 + conjs.size()); if (i + 1 == orig_size) { // no-op. - } else if (orig_size <= conjs.size()) { + } + else if (orig_size <= conjs.size()) { // no-op - } else { + } + else { SASSERT(orig_size == 1 + conjs.size()); --orig_size; --i; } - } else { + } + else { conjs[i] = tmp; } } @@ -202,9 +199,8 @@ void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) ast_manager& m; public: ite_hoister(ast_manager& m): m(m) {} - - br_status mk_app_core(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result) - { + + br_status mk_app_core(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result) { if (m.is_ite(f)) { return BR_FAILED; } @@ -233,13 +229,12 @@ void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) struct ite_hoister_cfg: public default_rewriter_cfg { ite_hoister m_r; bool rewrite_patterns() const { return false; } - br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) - { + br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { return m_r.mk_app_core(f, num, args, result); } ite_hoister_cfg(ast_manager & m, params_ref const & p):m_r(m) {} }; - + class ite_hoister_star : public rewriter_tpl { ite_hoister_cfg m_cfg; public: @@ -247,9 +242,8 @@ void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) rewriter_tpl(m, false, m_cfg), m_cfg(m, p) {} }; - -void hoist_non_bool_if(expr_ref& fml) -{ + + void hoist_non_bool_if(expr_ref& fml) { ast_manager& m = fml.get_manager(); scoped_no_proof _sp(m); params_ref p; @@ -266,8 +260,7 @@ void hoist_non_bool_if(expr_ref& fml) bool m_is_dl; bool m_test_for_utvpi; - bool is_numeric(expr* e) const - { + bool is_numeric(expr* e) const { if (a.is_numeral(e)) { return true; } @@ -278,13 +271,11 @@ void hoist_non_bool_if(expr_ref& fml) return false; } - bool is_arith_expr(expr *e) const - { + bool is_arith_expr(expr *e) const { return is_app(e) && a.get_family_id() == to_app(e)->get_family_id(); } - - bool is_offset(expr* e) const - { + + bool is_offset(expr* e) const { if (a.is_numeral(e)) { return true; } @@ -315,47 +306,44 @@ void hoist_non_bool_if(expr_ref& fml) return !is_arith_expr(e); } - bool is_minus_one(expr const * e) const - { - rational r; - return a.is_numeral(e, r) && r.is_minus_one(); + bool is_minus_one(expr const * e) const { + rational r; + return a.is_numeral(e, r) && r.is_minus_one(); } - bool test_ineq(expr* e) const - { + bool test_ineq(expr* e) const { SASSERT(a.is_le(e) || a.is_ge(e) || m.is_eq(e)); SASSERT(to_app(e)->get_num_args() == 2); expr * lhs = to_app(e)->get_arg(0); expr * rhs = to_app(e)->get_arg(1); if (is_offset(lhs) && is_offset(rhs)) - { return true; } + { return true; } if (!is_numeric(rhs)) - { std::swap(lhs, rhs); } + { std::swap(lhs, rhs); } if (!is_numeric(rhs)) - { return false; } + { return false; } // lhs can be 'x' or '(+ x (* -1 y))' if (is_offset(lhs)) - { return true; } + { return true; } expr* arg1, *arg2; if (!a.is_add(lhs, arg1, arg2)) - { return false; } + { return false; } // x if (m_test_for_utvpi) { return is_offset(arg1) && is_offset(arg2); } if (is_arith_expr(arg1)) - { std::swap(arg1, arg2); } + { std::swap(arg1, arg2); } if (is_arith_expr(arg1)) - { return false; } + { return false; } // arg2: (* -1 y) expr* m1, *m2; if (!a.is_mul(arg2, m1, m2)) - { return false; } + { return false; } return is_minus_one(m1) && is_offset(m2); } - bool test_eq(expr* e) const - { + bool test_eq(expr* e) const { expr* lhs, *rhs; VERIFY(m.is_eq(e, lhs, rhs)); if (!a.is_int_real(lhs)) { @@ -370,9 +358,8 @@ void hoist_non_bool_if(expr_ref& fml) !a.is_mul(lhs) && !a.is_mul(rhs); } - - bool test_term(expr* e) const - { + + bool test_term(expr* e) const { if (m.is_bool(e)) { return true; } @@ -490,7 +477,7 @@ bool is_utvpi_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) * eliminate simple equalities using qe_lite * then, MBP for Booleans (substitute), reals (based on LW), ints (based on Cooper), and arrays */ - void qe_project (ast_manager& m, app_ref_vector& vars, expr_ref& fml, +void qe_project (ast_manager& m, app_ref_vector& vars, expr_ref& fml, const model_ref& M, bool reduce_all_selects, bool use_native_mbp, bool dont_sub) { diff --git a/src/parsers/smt/smtlib_solver.cpp b/src/parsers/smt/smtlib_solver.cpp index b4487cbc5..339be2ddd 100644 --- a/src/parsers/smt/smtlib_solver.cpp +++ b/src/parsers/smt/smtlib_solver.cpp @@ -34,7 +34,7 @@ Revision History: namespace smtlib { solver::solver(): - m_ast_manager(m_params.m_proof ? PGM_FINE : PGM_DISABLED, + m_ast_manager(m_params.m_proof ? PGM_ENABLED : PGM_DISABLED, m_params.m_trace ? m_params.m_trace_file_name.c_str() : 0), m_ctx(0), m_error_code(0) { diff --git a/src/smt/smt_conflict_resolution.cpp b/src/smt/smt_conflict_resolution.cpp index cb1465d94..80168df18 100644 --- a/src/smt/smt_conflict_resolution.cpp +++ b/src/smt/smt_conflict_resolution.cpp @@ -810,8 +810,6 @@ namespace smt { m_new_proofs.push_back(pr); return pr; } - if (m_manager.coarse_grain_proofs()) - return pr; TRACE("norm_eq_proof", tout << "#" << n1->get_owner_id() << " = #" << n2->get_owner_id() << "\n"; tout << mk_ll_pp(pr, m_manager, true, false);); @@ -1217,7 +1215,7 @@ namespace smt { mk_proof(rhs, c, prs2); while (!prs2.empty()) { proof * pr = prs2.back(); - if (m_manager.fine_grain_proofs()) { + if (m_manager.proofs_enabled()) { pr = m_manager.mk_symmetry(pr); m_new_proofs.push_back(pr); prs1.push_back(pr); diff --git a/src/smt/smt_justification.cpp b/src/smt/smt_justification.cpp index c8de45644..440da7297 100644 --- a/src/smt/smt_justification.cpp +++ b/src/smt/smt_justification.cpp @@ -129,7 +129,7 @@ namespace smt { if (m_node1 != m_node1->get_root()) { proof * pr = cr.get_proof(m_node1, m_node1->get_root()); - if (pr && m.fine_grain_proofs()) + if (pr && m.proofs_enabled()) pr = m.mk_symmetry(pr); prs.push_back(pr); if (!pr) From 7f254710aadad615589ffe55537f24c100a23ef9 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Mon, 23 Oct 2017 21:38:10 -0700 Subject: [PATCH 454/488] patch build failure Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index f903dc623..040ca4078 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -2683,14 +2683,10 @@ proof * ast_manager::mk_modus_ponens(proof * p1, proof * p2) { } proof * ast_manager::mk_reflexivity(expr * e) { - if (proofs_disabled()) - return m_undef_proof; return mk_app(m_basic_family_id, PR_REFLEXIVITY, mk_eq(e, e)); } proof * ast_manager::mk_oeq_reflexivity(expr * e) { - if (proofs_disabled()) - return m_undef_proof; return mk_app(m_basic_family_id, PR_REFLEXIVITY, mk_oeq(e, e)); } @@ -2705,6 +2701,8 @@ proof * ast_manager::mk_commutativity(app * f) { */ proof * ast_manager::mk_iff_true(proof * pr) { if (!pr) return pr; + if (proofs_disabled()) + return m_undef_proof; SASSERT(has_fact(pr)); SASSERT(is_bool(get_fact(pr))); return mk_app(m_basic_family_id, PR_IFF_TRUE, pr, mk_iff(get_fact(pr), mk_true())); @@ -2779,8 +2777,6 @@ proof * ast_manager::mk_transitivity(proof * p1, proof * p2, proof * p3, proof * } proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs) { - if (proofs_disabled()) - return m_undef_proof; SASSERT(num_proofs > 0); proof * r = proofs[0]; for (unsigned i = 1; i < num_proofs; i++) @@ -2789,11 +2785,8 @@ proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs } proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs, expr * n1, expr * n2) { - if (proofs_disabled()) - return m_undef_proof; - if (proofs_enabled()) - return mk_transitivity(num_proofs, proofs); - SASSERT(num_proofs > 0); + if (num_proofs == 0) + return nullptr; if (num_proofs == 1) return proofs[0]; DEBUG_CODE({ @@ -2809,8 +2802,6 @@ proof * ast_manager::mk_transitivity(unsigned num_proofs, proof * const * proofs } proof * ast_manager::mk_monotonicity(func_decl * R, app * f1, app * f2, unsigned num_proofs, proof * const * proofs) { - if (proofs_disabled()) - return m_undef_proof; SASSERT(f1->get_num_args() == f2->get_num_args()); SASSERT(f1->get_decl() == f2->get_decl()); ptr_buffer args; @@ -2820,8 +2811,6 @@ proof * ast_manager::mk_monotonicity(func_decl * R, app * f1, app * f2, unsigned } proof * ast_manager::mk_congruence(app * f1, app * f2, unsigned num_proofs, proof * const * proofs) { - if (proofs_disabled()) - return m_undef_proof; SASSERT(get_sort(f1) == get_sort(f2)); sort * s = get_sort(f1); sort * d[2] = { s, s }; @@ -2829,8 +2818,6 @@ proof * ast_manager::mk_congruence(app * f1, app * f2, unsigned num_proofs, proo } proof * ast_manager::mk_oeq_congruence(app * f1, app * f2, unsigned num_proofs, proof * const * proofs) { - if (proofs_disabled()) - return m_undef_proof; SASSERT(get_sort(f1) == get_sort(f2)); sort * s = get_sort(f1); sort * d[2] = { s, s }; @@ -2838,11 +2825,7 @@ proof * ast_manager::mk_oeq_congruence(app * f1, app * f2, unsigned num_proofs, } proof * ast_manager::mk_quant_intro(quantifier * q1, quantifier * q2, proof * p) { - if (proofs_disabled()) - return m_undef_proof; - if (!p) { - return 0; - } + if (!p) return nullptr; SASSERT(q1->get_num_decls() == q2->get_num_decls()); SASSERT(has_fact(p)); SASSERT(is_iff(get_fact(p))); @@ -2850,8 +2833,7 @@ proof * ast_manager::mk_quant_intro(quantifier * q1, quantifier * q2, proof * p) } proof * ast_manager::mk_oeq_quant_intro(quantifier * q1, quantifier * q2, proof * p) { - if (proofs_disabled()) - return m_undef_proof; + if (!p) return nullptr; SASSERT(q1->get_num_decls() == q2->get_num_decls()); SASSERT(has_fact(p)); SASSERT(is_oeq(get_fact(p))); @@ -2859,8 +2841,6 @@ proof * ast_manager::mk_oeq_quant_intro(quantifier * q1, quantifier * q2, proof } proof * ast_manager::mk_distributivity(expr * s, expr * r) { - if (proofs_disabled()) - return m_undef_proof; return mk_app(m_basic_family_id, PR_DISTRIBUTIVITY, mk_eq(s, r)); } From d630838b38f6956aa418c81036c7b60d7d0e4163 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 24 Oct 2017 09:39:16 +0200 Subject: [PATCH 455/488] add a basic printer into graphviz (http://graphviz.org/) for proofs - proofs are output into file `proof.dot` if `(get-proof-graph)` is in the input - use `dot -Txlib proof.dot` to see the proof - use `dot -Tsvg proof.dot` to get a svg file --- src/ast/CMakeLists.txt | 1 + src/ast/ast_pp_dot.cpp | 126 +++++++++++++++++++++++++++++++++ src/ast/ast_pp_dot.h | 24 +++++++ src/cmd_context/basic_cmds.cpp | 21 ++++++ 4 files changed, 172 insertions(+) create mode 100644 src/ast/ast_pp_dot.cpp create mode 100644 src/ast/ast_pp_dot.h diff --git a/src/ast/CMakeLists.txt b/src/ast/CMakeLists.txt index 0a14d9473..4dcdd2a35 100644 --- a/src/ast/CMakeLists.txt +++ b/src/ast/CMakeLists.txt @@ -10,6 +10,7 @@ z3_add_component(ast ast_printer.cpp ast_smt2_pp.cpp ast_smt_pp.cpp + ast_pp_dot.cpp ast_translation.cpp ast_util.cpp bv_decl_plugin.cpp diff --git a/src/ast/ast_pp_dot.cpp b/src/ast/ast_pp_dot.cpp new file mode 100644 index 000000000..8e3406ccb --- /dev/null +++ b/src/ast/ast_pp_dot.cpp @@ -0,0 +1,126 @@ +/*++ + +Abstract: Pretty-printer for proofs in Graphviz format + +--*/ + +#include "util/util.h" +#include "util/map.h" +#include "ast_pp_dot.h" + +// string escaping for DOT +std::string escape_dot(std::string const & s) { + std::string res; + for (auto c : s) { + if (c == '\n') + res.append("\\l"); + else + res.push_back(c); + } + return res; +} + +// map from proofs to unique IDs +typedef map, default_eq > expr2id; +typedef map, default_eq > set_expr; + +// temporary structure for traversing the proof and printing it +struct ast_pp_dot_st { + const ast_pp_dot * m_pp; + set_expr m_printed; + expr2id m_id_map; + svector m_to_print; + std::ostream & m_out; + unsigned m_next_id; + + ast_pp_dot_st(const ast_pp_dot * pp, std::ostream & out) : + m_pp(pp), + m_out(out), + m_next_id(0), + m_id_map(), + m_to_print(), + m_printed() {} + + void push_term(const expr * a) { m_to_print.push_back(a); } + + void pp_loop() { + // DFS traversal + auto& m = get_manager(); + while (!m_to_print.empty()) { + const expr * a = m_to_print.back(); + m_to_print.pop_back(); + if (!m_printed.contains(a)) { + m_printed.insert(a, true); + if (m.is_proof(a)) + pp_step(to_app(a)); + else + pp_atomic_step(a); + } + } + } + +private: + + ast_manager & get_manager() const { return m_pp->get_manager(); } + + // label for an expression + std::string label_of_expr(const expr * e) const { + expr_ref er((expr*)e, get_manager()); + std::ostringstream out; + out << er << std::flush; + return escape_dot(out.str()); + } + + void pp_atomic_step(const expr * e) { + unsigned id = get_id(e); + m_out << "node_" << id << " [shape=box,label=\"" << label_of_expr(e) << "\"] ;" << std::endl; + } + + void pp_step(const proof * p) { + auto m = get_manager(); + unsigned num_args = p->get_num_args(); + TRACE("pp_ast_dot_step", tout << " :kind " << p->get_kind() << " :num-args " << num_args); + if (num_args > 0) { + // print result + expr* p_res = p->get_args()[num_args-1]; // result + unsigned id = get_id(p); + m_out << "node_" << id << " [shape=box,label=\"" << label_of_expr(p_res) << "\"]" << std::endl; + // now print edges to parents (except last one, which is the result) + std::string label = p->get_decl()->get_name().str(); + for (unsigned i = 0 ; i+1 < num_args; ++i) { + expr* parent = p->get_args()[i]; + // explore parent, also print a link to it + push_term(to_app(parent)); + m_out << "node_" << id << " -> " << "node_" << get_id((expr*)parent) + << "[label=\"" << label << "\"];" << std::endl;; + } + } else { + pp_atomic_step(p); + } + } + + // find a unique ID for this proof + unsigned get_id(const expr * e) { + if (m_id_map.contains(e)) { + return m_id_map[e]; + } else { + auto id = m_next_id ++; + m_id_map.insert(e, id); + return id; + } + } + +}; + +// main printer +std::ostream & ast_pp_dot::pp(std::ostream & out) const { + out << "digraph proof { " << std::endl; + ast_pp_dot_st pp_st(this, out); + pp_st.push_term(m_pr); + pp_st.pp_loop(); + out << std::endl << " } " << std::endl << std::flush; + return out; +} + +std::ostream &operator<<(std::ostream &out, const ast_pp_dot & p) { return p.pp(out); } + diff --git a/src/ast/ast_pp_dot.h b/src/ast/ast_pp_dot.h new file mode 100644 index 000000000..38c45e00b --- /dev/null +++ b/src/ast/ast_pp_dot.h @@ -0,0 +1,24 @@ +/*++ + +Abstract: Pretty-printer for proofs in Graphviz format + +--*/ + +#pragma once + +#include +#include "ast_pp.h" + +class ast_pp_dot { + ast_manager & m_manager; + proof * const m_pr; + + public: + ast_pp_dot(proof *pr, ast_manager &m) : m_manager(m), m_pr(pr) {} + ast_pp_dot(proof_ref &e) : m_manager(e.m()), m_pr(e.get()) {} + + std::ostream & pp(std::ostream & out) const; + ast_manager & get_manager() const { return m_manager; } +}; + +std::ostream &operator<<(std::ostream &out, const ast_pp_dot & p); \ No newline at end of file diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index 21b66febd..60dd09f59 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -20,6 +20,7 @@ Notes: #include "util/version.h" #include "ast/ast_smt_pp.h" #include "ast/ast_smt2_pp.h" +#include "ast/ast_pp_dot.h" #include "ast/ast_pp.h" #include "ast/array_decl_plugin.h" #include "ast/pp.h" @@ -202,6 +203,25 @@ ATOMIC_CMD(get_proof_cmd, "get-proof", "retrieve proof", { } }); +ATOMIC_CMD(get_proof_graph_cmd, "get-proof-graph", "retrieve proof and print it in graphviz", { + if (!ctx.produce_proofs()) + throw cmd_exception("proof construction is not enabled, use command (set-option :produce-proofs true)"); + if (!ctx.has_manager() || + ctx.cs_state() != cmd_context::css_unsat) + throw cmd_exception("proof is not available"); + proof_ref pr(ctx.m()); + pr = ctx.get_check_sat_result()->get_proof(); + if (pr == 0) + throw cmd_exception("proof is not available"); + if (ctx.well_sorted_check_enabled() && !is_well_sorted(ctx.m(), pr)) { + throw cmd_exception("proof is not well sorted"); + } + + // TODO: specify file into which the proof should be printed + std::ofstream out("proof.dot"); + out << ast_pp_dot(pr) << std::endl; +}); + static void print_core(cmd_context& ctx) { ptr_vector core; ctx.get_check_sat_result()->get_unsat_core(core); @@ -840,6 +860,7 @@ void install_basic_cmds(cmd_context & ctx) { ctx.insert(alloc(get_assignment_cmd)); ctx.insert(alloc(get_assertions_cmd)); ctx.insert(alloc(get_proof_cmd)); + ctx.insert(alloc(get_proof_graph_cmd)); ctx.insert(alloc(get_unsat_core_cmd)); ctx.insert(alloc(set_option_cmd)); ctx.insert(alloc(get_option_cmd)); From 24edb8fb47db0c680438c9473212160c93aac2db Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 24 Oct 2017 09:51:47 +0200 Subject: [PATCH 456/488] add some colors to the proof output --- src/ast/ast_pp_dot.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ast/ast_pp_dot.cpp b/src/ast/ast_pp_dot.cpp index 8e3406ccb..feffa71f1 100644 --- a/src/ast/ast_pp_dot.cpp +++ b/src/ast/ast_pp_dot.cpp @@ -32,6 +32,7 @@ struct ast_pp_dot_st { svector m_to_print; std::ostream & m_out; unsigned m_next_id; + bool m_first; ast_pp_dot_st(const ast_pp_dot * pp, std::ostream & out) : m_pp(pp), @@ -39,7 +40,8 @@ struct ast_pp_dot_st { m_next_id(0), m_id_map(), m_to_print(), - m_printed() {} + m_printed(), + m_first(true) {} void push_term(const expr * a) { m_to_print.push_back(a); } @@ -73,7 +75,7 @@ private: void pp_atomic_step(const expr * e) { unsigned id = get_id(e); - m_out << "node_" << id << " [shape=box,label=\"" << label_of_expr(e) << "\"] ;" << std::endl; + m_out << "node_" << id << " [shape=box,color=\"yellow\",style=\"filled\",label=\"" << label_of_expr(e) << "\"] ;" << std::endl; } void pp_step(const proof * p) { @@ -84,7 +86,11 @@ private: // print result expr* p_res = p->get_args()[num_args-1]; // result unsigned id = get_id(p); - m_out << "node_" << id << " [shape=box,label=\"" << label_of_expr(p_res) << "\"]" << std::endl; + const char* color = + m_first ? (m_first=false,"color=\"red\"") : num_args==1 ? "color=\"yellow\"": ""; + m_out << "node_" << id << + " [shape=box,style=\"filled\",label=\"" << label_of_expr(p_res) << "\"" + << color << "]" << std::endl; // now print edges to parents (except last one, which is the result) std::string label = p->get_decl()->get_name().str(); for (unsigned i = 0 ; i+1 < num_args; ++i) { From ed526b808d402e5b66bfcb8962ae58568993d00b Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 24 Oct 2017 10:16:22 +0200 Subject: [PATCH 457/488] add parameter to specify the file into which dot proofs are to be printed --- src/cmd_context/basic_cmds.cpp | 5 +++-- src/cmd_context/context_params.cpp | 5 +++++ src/cmd_context/context_params.h | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index 60dd09f59..65c8860b1 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -217,8 +217,9 @@ ATOMIC_CMD(get_proof_graph_cmd, "get-proof-graph", "retrieve proof and print it throw cmd_exception("proof is not well sorted"); } - // TODO: specify file into which the proof should be printed - std::ofstream out("proof.dot"); + context_params& params = ctx.params(); + const std::string& file = params.m_dot_proof_file; + std::ofstream out(file); out << ast_pp_dot(pr) << std::endl; }); diff --git a/src/cmd_context/context_params.cpp b/src/cmd_context/context_params.cpp index f8646d41c..78f4223fc 100644 --- a/src/cmd_context/context_params.cpp +++ b/src/cmd_context/context_params.cpp @@ -111,6 +111,9 @@ void context_params::set(char const * param, char const * value) { else if (p == "trace_file_name") { m_trace_file_name = value; } + else if (p == "dot_proof_file") { + m_dot_proof_file = value; + } else if (p == "unsat_core") { set_bool(m_unsat_core, param, value); } @@ -146,6 +149,7 @@ void context_params::updt_params(params_ref const & p) { m_dump_models = p.get_bool("dump_models", m_dump_models); m_trace = p.get_bool("trace", m_trace); m_trace_file_name = p.get_str("trace_file_name", "z3.log"); + m_dot_proof_file = p.get_str("dot_proof_file", "proof.dot"); m_unsat_core = p.get_bool("unsat_core", m_unsat_core); m_debug_ref_count = p.get_bool("debug_ref_count", m_debug_ref_count); m_smtlib2_compliant = p.get_bool("smtlib2_compliant", m_smtlib2_compliant); @@ -161,6 +165,7 @@ void context_params::collect_param_descrs(param_descrs & d) { d.insert("dump_models", CPK_BOOL, "dump models whenever check-sat returns sat", "false"); d.insert("trace", CPK_BOOL, "trace generation for VCC", "false"); d.insert("trace_file_name", CPK_STRING, "trace out file name (see option 'trace')", "z3.log"); + d.insert("dot_proof_file", CPK_STRING, "file in which to output graphical proofs", "proof.dot"); d.insert("debug_ref_count", CPK_BOOL, "debug support for AST reference counting", "false"); d.insert("smtlib2_compliant", CPK_BOOL, "enable/disable SMT-LIB 2.0 compliance", "false"); collect_solver_param_descrs(d); diff --git a/src/cmd_context/context_params.h b/src/cmd_context/context_params.h index c238af556..df62057fe 100644 --- a/src/cmd_context/context_params.h +++ b/src/cmd_context/context_params.h @@ -30,6 +30,7 @@ class context_params { public: bool m_auto_config; bool m_proof; + std::string m_dot_proof_file; bool m_interpolants; bool m_debug_ref_count; bool m_trace; From 72c9134424c973f8fae47d40806bbf8a3d43bfda Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 02:26:39 -0700 Subject: [PATCH 458/488] fixing regressions introduced when reducing astm proof dependencies Signed-off-by: Nikolaj Bjorner --- src/ast/ast.cpp | 13 ++++++++++--- src/smt/asserted_formulas.cpp | 4 ++-- src/test/proof_checker.cpp | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 040ca4078..3dbd0bc69 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -805,7 +805,6 @@ func_decl * basic_decl_plugin::mk_proof_decl(char const* name, basic_op_kind k, } func_decl * basic_decl_plugin::mk_proof_decl(basic_op_kind k, unsigned num_parents) { - SASSERT(k == PR_UNDEF || m_manager->proofs_enabled()); switch (static_cast(k)) { // // A description of the semantics of the proof @@ -2701,8 +2700,6 @@ proof * ast_manager::mk_commutativity(app * f) { */ proof * ast_manager::mk_iff_true(proof * pr) { if (!pr) return pr; - if (proofs_disabled()) - return m_undef_proof; SASSERT(has_fact(pr)); SASSERT(is_bool(get_fact(pr))); return mk_app(m_basic_family_id, PR_IFF_TRUE, pr, mk_iff(get_fact(pr), mk_true())); @@ -2845,18 +2842,21 @@ proof * ast_manager::mk_distributivity(expr * s, expr * r) { } proof * ast_manager::mk_rewrite(expr * s, expr * t) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_REWRITE, mk_eq(s, t)); } proof * ast_manager::mk_oeq_rewrite(expr * s, expr * t) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_REWRITE, mk_oeq(s, t)); } proof * ast_manager::mk_rewrite_star(expr * s, expr * t, unsigned num_proofs, proof * const * proofs) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; ptr_buffer args; @@ -2866,36 +2866,42 @@ proof * ast_manager::mk_rewrite_star(expr * s, expr * t, unsigned num_proofs, pr } proof * ast_manager::mk_pull_quant(expr * e, quantifier * q) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_PULL_QUANT, mk_iff(e, q)); } proof * ast_manager::mk_pull_quant_star(expr * e, quantifier * q) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_PULL_QUANT_STAR, mk_iff(e, q)); } proof * ast_manager::mk_push_quant(quantifier * q, expr * e) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_PUSH_QUANT, mk_iff(q, e)); } proof * ast_manager::mk_elim_unused_vars(quantifier * q, expr * e) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_ELIM_UNUSED_VARS, mk_iff(q, e)); } proof * ast_manager::mk_der(quantifier * q, expr * e) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_DER, mk_iff(q, e)); } proof * ast_manager::mk_quant_inst(expr * not_q_or_i, unsigned num_bind, expr* const* binding) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; vector params; @@ -2931,6 +2937,7 @@ bool ast_manager::is_rewrite(expr const* e, expr*& r1, expr*& r2) const { } proof * ast_manager::mk_def_axiom(expr * ax) { + SASSERT(proofs_enabled()); if (proofs_disabled()) return m_undef_proof; return mk_app(m_basic_family_id, PR_DEF_AXIOM, ax); diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 1ed5f2fe1..9f68f2412 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -101,14 +101,14 @@ void asserted_formulas::push_assertion(expr * e, proof * pr, vectorget_num_args(); ++i) { expr* arg = to_app(e)->get_arg(i); - proof_ref _pr(m.mk_and_elim(pr, i), m); + proof_ref _pr(m.proofs_enabled() ? m.mk_and_elim(pr, i) : 0, m); push_assertion(arg, _pr, result); } } else if (m.is_not(e, e1) && m.is_or(e1)) { for (unsigned i = 0; i < to_app(e1)->get_num_args(); ++i) { expr* arg = to_app(e1)->get_arg(i); - proof_ref _pr(m.mk_not_or_elim(pr, i), m); + proof_ref _pr(m.proofs_enabled() ? m.mk_not_or_elim(pr, i) : 0, m); expr_ref narg(mk_not(m, arg), m); push_assertion(narg, _pr, result); } diff --git a/src/test/proof_checker.cpp b/src/test/proof_checker.cpp index adf77e12e..33a908f24 100644 --- a/src/test/proof_checker.cpp +++ b/src/test/proof_checker.cpp @@ -8,7 +8,7 @@ Copyright (c) 2015 Microsoft Corporation #include "ast/ast_ll_pp.h" void tst_checker1() { - ast_manager m(PGM_FINE); + ast_manager m(PGM_ENABLED); expr_ref a(m); proof_ref p1(m), p2(m), p3(m), p4(m); expr_ref_vector side_conditions(m); From 607eba1720da71154f3bccf9bea20e677939327c Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 24 Oct 2017 11:44:28 +0200 Subject: [PATCH 459/488] account for review --- src/ast/ast_pp_dot.cpp | 42 ++++++++++++++++++++++-------------------- src/ast/ast_pp_dot.h | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/ast/ast_pp_dot.cpp b/src/ast/ast_pp_dot.cpp index feffa71f1..eb4ec80fe 100644 --- a/src/ast/ast_pp_dot.cpp +++ b/src/ast/ast_pp_dot.cpp @@ -11,6 +11,7 @@ Abstract: Pretty-printer for proofs in Graphviz format // string escaping for DOT std::string escape_dot(std::string const & s) { std::string res; + res.reserve(s.size()); // preallocate for (auto c : s) { if (c == '\n') res.append("\\l"); @@ -21,8 +22,8 @@ std::string escape_dot(std::string const & s) { } // map from proofs to unique IDs -typedef map, default_eq > expr2id; -typedef map, default_eq > set_expr; +typedef obj_map expr2id; +typedef obj_map set_expr; // temporary structure for traversing the proof and printing it struct ast_pp_dot_st { @@ -33,6 +34,7 @@ struct ast_pp_dot_st { std::ostream & m_out; unsigned m_next_id; bool m_first; + ast_manager & m_manager; ast_pp_dot_st(const ast_pp_dot * pp, std::ostream & out) : m_pp(pp), @@ -41,19 +43,21 @@ struct ast_pp_dot_st { m_id_map(), m_to_print(), m_printed(), - m_first(true) {} + m_first(true), + m_manager(pp->get_manager()) {} + + ~ast_pp_dot_st() = default; void push_term(const expr * a) { m_to_print.push_back(a); } void pp_loop() { // DFS traversal - auto& m = get_manager(); while (!m_to_print.empty()) { const expr * a = m_to_print.back(); m_to_print.pop_back(); if (!m_printed.contains(a)) { m_printed.insert(a, true); - if (m.is_proof(a)) + if (m().is_proof(a)) pp_step(to_app(a)); else pp_atomic_step(a); @@ -63,11 +67,11 @@ struct ast_pp_dot_st { private: - ast_manager & get_manager() const { return m_pp->get_manager(); } + inline ast_manager & m() const { return m_manager; } // label for an expression std::string label_of_expr(const expr * e) const { - expr_ref er((expr*)e, get_manager()); + expr_ref er((expr*)e, m()); std::ostringstream out; out << er << std::flush; return escape_dot(out.str()); @@ -79,22 +83,21 @@ private: } void pp_step(const proof * p) { - auto m = get_manager(); - unsigned num_args = p->get_num_args(); TRACE("pp_ast_dot_step", tout << " :kind " << p->get_kind() << " :num-args " << num_args); - if (num_args > 0) { + if (m().has_fact(p)) { // print result - expr* p_res = p->get_args()[num_args-1]; // result + expr* p_res = m().get_fact(p); // result of proof step unsigned id = get_id(p); + unsigned num_parents = m().get_num_parents(p); const char* color = - m_first ? (m_first=false,"color=\"red\"") : num_args==1 ? "color=\"yellow\"": ""; + m_first ? (m_first=false,"color=\"red\"") : num_parents==0 ? "color=\"yellow\"": ""; m_out << "node_" << id << " [shape=box,style=\"filled\",label=\"" << label_of_expr(p_res) << "\"" << color << "]" << std::endl; // now print edges to parents (except last one, which is the result) std::string label = p->get_decl()->get_name().str(); - for (unsigned i = 0 ; i+1 < num_args; ++i) { - expr* parent = p->get_args()[i]; + for (unsigned i = 0 ; i < num_parents; ++i) { + expr* parent = m().get_parent(p, i); // explore parent, also print a link to it push_term(to_app(parent)); m_out << "node_" << id << " -> " << "node_" << get_id((expr*)parent) @@ -107,13 +110,12 @@ private: // find a unique ID for this proof unsigned get_id(const expr * e) { - if (m_id_map.contains(e)) { - return m_id_map[e]; - } else { - auto id = m_next_id ++; - m_id_map.insert(e, id); - return id; + unsigned id = 0; + if (!m_id_map.find(e, id)) { + id = m_next_id++; + m_id_map.insert(e, id); } + return id; } }; diff --git a/src/ast/ast_pp_dot.h b/src/ast/ast_pp_dot.h index 38c45e00b..537754e83 100644 --- a/src/ast/ast_pp_dot.h +++ b/src/ast/ast_pp_dot.h @@ -16,7 +16,7 @@ class ast_pp_dot { public: ast_pp_dot(proof *pr, ast_manager &m) : m_manager(m), m_pr(pr) {} ast_pp_dot(proof_ref &e) : m_manager(e.m()), m_pr(e.get()) {} - + std::ostream & pp(std::ostream & out) const; ast_manager & get_manager() const { return m_manager; } }; From d67f3c14668b8f6f679f361575ad6cd3461dfa6f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 03:08:56 -0700 Subject: [PATCH 460/488] create proofs folder, move proof-post-order utility to proofs directory, fix regression with proofs Signed-off-by: Nikolaj Bjorner --- scripts/mk_project.py | 4 +- src/CMakeLists.txt | 2 +- .../{proof_checker => proofs}/CMakeLists.txt | 5 ++- .../proof_checker.cpp | 3 +- .../{proof_checker => proofs}/proof_checker.h | 0 .../proofs/proof_utils.cpp} | 37 ++++++++++--------- .../proofs/proof_utils.h} | 21 +++++------ src/muz/pdr/pdr_context.cpp | 2 +- src/muz/spacer/CMakeLists.txt | 1 - src/muz/spacer/spacer_context.cpp | 2 +- src/muz/spacer/spacer_legacy_frames.cpp | 2 +- src/muz/spacer/spacer_unsat_core_learner.cpp | 6 +-- src/muz/spacer/spacer_unsat_core_learner.h | 2 +- src/muz/spacer/spacer_unsat_core_plugin.cpp | 2 +- src/muz/spacer/spacer_virtual_solver.cpp | 2 +- src/smt/CMakeLists.txt | 2 +- src/smt/asserted_formulas.cpp | 10 ++--- src/smt/smt_context.cpp | 2 +- src/test/proof_checker.cpp | 2 +- 19 files changed, 53 insertions(+), 54 deletions(-) rename src/ast/{proof_checker => proofs}/CMakeLists.txt (60%) rename src/ast/{proof_checker => proofs}/proof_checker.cpp (99%) rename src/ast/{proof_checker => proofs}/proof_checker.h (100%) rename src/{muz/spacer/spacer_proof_utils.cpp => ast/proofs/proof_utils.cpp} (93%) rename src/{muz/spacer/spacer_proof_utils.h => ast/proofs/proof_utils.h} (58%) diff --git a/scripts/mk_project.py b/scripts/mk_project.py index 923b948a6..ddf439e10 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -43,14 +43,14 @@ def init_project_def(): add_lib('cmd_context', ['solver', 'rewriter', 'interp']) add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds') add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') - add_lib('proof_checker', ['rewriter'], 'ast/proof_checker') + add_lib('proofs', ['rewriter'], 'ast/proofs') add_lib('fpa', ['ast', 'util', 'rewriter', 'model'], 'ast/fpa') add_lib('pattern', ['normal_forms', 'smt2parser', 'rewriter'], 'ast/pattern') add_lib('bit_blaster', ['rewriter', 'rewriter'], 'ast/rewriter/bit_blaster') add_lib('smt_params', ['ast', 'rewriter', 'pattern', 'bit_blaster'], 'smt/params') add_lib('proto_model', ['model', 'rewriter', 'smt_params'], 'smt/proto_model') add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', 'proto_model', - 'substitution', 'grobner', 'euclid', 'simplex', 'proof_checker', 'pattern', 'parser_util', 'fpa', 'lp']) + 'substitution', 'grobner', 'euclid', 'simplex', 'proofs', 'pattern', 'parser_util', 'fpa', 'lp']) add_lib('bv_tactics', ['tactic', 'bit_blaster', 'core_tactics'], 'tactic/bv') add_lib('fuzzing', ['ast'], 'test/fuzzing') add_lib('smt_tactic', ['smt'], 'smt/tactic') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 277335ce9..cfe6e5265 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,7 +67,7 @@ add_subdirectory(interp) add_subdirectory(cmd_context) add_subdirectory(cmd_context/extra_cmds) add_subdirectory(parsers/smt2) -add_subdirectory(ast/proof_checker) +add_subdirectory(ast/proofs) add_subdirectory(ast/fpa) add_subdirectory(ast/macros) add_subdirectory(ast/pattern) diff --git a/src/ast/proof_checker/CMakeLists.txt b/src/ast/proofs/CMakeLists.txt similarity index 60% rename from src/ast/proof_checker/CMakeLists.txt rename to src/ast/proofs/CMakeLists.txt index 5c947adec..6eedb0fac 100644 --- a/src/ast/proof_checker/CMakeLists.txt +++ b/src/ast/proofs/CMakeLists.txt @@ -1,6 +1,7 @@ -z3_add_component(proof_checker +z3_add_component(proofs SOURCES proof_checker.cpp + proof_utils.cpp COMPONENT_DEPENDENCIES rewriter -) +) \ No newline at end of file diff --git a/src/ast/proof_checker/proof_checker.cpp b/src/ast/proofs/proof_checker.cpp similarity index 99% rename from src/ast/proof_checker/proof_checker.cpp rename to src/ast/proofs/proof_checker.cpp index afe2baeed..3f9438229 100644 --- a/src/ast/proof_checker/proof_checker.cpp +++ b/src/ast/proofs/proof_checker.cpp @@ -4,10 +4,9 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ast/proof_checker/proof_checker.h" +#include "ast/proofs/proof_checker.h" #include "ast/ast_ll_pp.h" #include "ast/ast_pp.h" -// include "spc_decl_plugin.h" #include "ast/ast_smt_pp.h" #include "ast/arith_decl_plugin.h" #include "ast/rewriter/th_rewriter.h" diff --git a/src/ast/proof_checker/proof_checker.h b/src/ast/proofs/proof_checker.h similarity index 100% rename from src/ast/proof_checker/proof_checker.h rename to src/ast/proofs/proof_checker.h diff --git a/src/muz/spacer/spacer_proof_utils.cpp b/src/ast/proofs/proof_utils.cpp similarity index 93% rename from src/muz/spacer/spacer_proof_utils.cpp rename to src/ast/proofs/proof_utils.cpp index 6edb29881..bd82696ea 100644 --- a/src/muz/spacer/spacer_proof_utils.cpp +++ b/src/ast/proofs/proof_utils.cpp @@ -3,7 +3,7 @@ Copyright (c) 2017 Arie Gurfinkel Module Name: - spacer_proof_utils.cpp + proof_utils.cpp Abstract: Utilities to traverse and manipulate proofs @@ -16,24 +16,23 @@ Revision History: --*/ -#include "muz/spacer/spacer_proof_utils.h" #include "ast/ast_util.h" #include "ast/ast_pp.h" +#include "ast/proofs/proof_utils.h" +#include "ast/proofs/proof_checker.h" -#include "ast/proof_checker/proof_checker.h" -namespace spacer { -ProofIteratorPostOrder::ProofIteratorPostOrder(proof* root, ast_manager& manager) : m(manager) +proof_post_order::proof_post_order(proof* root, ast_manager& manager) : m(manager) {m_todo.push_back(root);} -bool ProofIteratorPostOrder::hasNext() +bool proof_post_order::hasNext() {return !m_todo.empty();} /* * iterative post-order depth-first search (DFS) through the proof DAG */ -proof* ProofIteratorPostOrder::next() +proof* proof_post_order::next() { while (!m_todo.empty()) { proof* currentNode = m_todo.back(); @@ -42,7 +41,8 @@ proof* ProofIteratorPostOrder::next() if (!m_visited.is_marked(currentNode)) { bool existsUnvisitedParent = false; - // add unprocessed premises to stack for DFS. If there is at least one unprocessed premise, don't compute the result + // add unprocessed premises to stack for DFS. + // If there is at least one unprocessed premise, don't compute the result // for currentProof now, but wait until those unprocessed premises are processed. for (unsigned i = 0; i < m.get_num_parents(currentNode); ++i) { SASSERT(m.is_proof(currentNode->get_arg(i))); @@ -67,7 +67,7 @@ proof* ProofIteratorPostOrder::next() } } // we have already iterated through all inferences - return NULL; + return nullptr; } @@ -117,20 +117,21 @@ class reduce_hypotheses { return hyp_mark; } - void compute_marks(proof* pr) - { + void compute_marks(proof* pr) { proof *p; - ProofIteratorPostOrder pit(pr, m); + proof_post_order pit(pr, m); while (pit.hasNext()) { p = pit.next(); if (m.is_hypothesis(p)) { m_hypmark.mark(p, true); m_hyps.insert(m.get_fact(p)); - } else { + } + else { bool hyp_mark = compute_mark1(p); // collect units that are hyp-free and are used as hypotheses somewhere - if (!hyp_mark && m.has_fact(p) && m_hyps.contains(m.get_fact(p))) - { m_units.insert(m.get_fact(p), p); } + if (!hyp_mark && m.has_fact(p) && m_hyps.contains(m.get_fact(p))) { + m_units.insert(m.get_fact(p), p); + } } } } @@ -220,6 +221,7 @@ class reduce_hypotheses { return m_units.contains(e); } + proof *mk_lemma_core(proof *pf, expr *fact) { ptr_buffer args; @@ -319,8 +321,8 @@ public: reset(); } }; -void reduce_hypotheses(proof_ref &pr) -{ + +void reduce_hypotheses(proof_ref &pr) { ast_manager &m = pr.get_manager(); class reduce_hypotheses hypred(m); hypred(pr); @@ -329,4 +331,3 @@ void reduce_hypotheses(proof_ref &pr) SASSERT(pc.check(pr, side)); ); } -} diff --git a/src/muz/spacer/spacer_proof_utils.h b/src/ast/proofs/proof_utils.h similarity index 58% rename from src/muz/spacer/spacer_proof_utils.h rename to src/ast/proofs/proof_utils.h index f2897f7ec..7963d52de 100644 --- a/src/muz/spacer/spacer_proof_utils.h +++ b/src/ast/proofs/proof_utils.h @@ -3,7 +3,7 @@ Copyright (c) 2017 Arie Gurfinkel Module Name: - spacer_proof_utils.cpp + proof_utils.h Abstract: Utilities to traverse and manipulate proofs @@ -16,28 +16,27 @@ Revision History: --*/ -#ifndef _SPACER_PROOF_UTILS_H_ -#define _SPACER_PROOF_UTILS_H_ +#ifndef _PROOF_UTILS_H_ +#define _PROOF_UTILS_H_ #include "ast/ast.h" -namespace spacer { /* * iterator, which traverses the proof in depth-first post-order. */ -class ProofIteratorPostOrder { + +class proof_post_order { public: - ProofIteratorPostOrder(proof* refutation, ast_manager& manager); + proof_post_order(proof* refutation, ast_manager& manager); bool hasNext(); proof* next(); private: ptr_vector m_todo; - ast_mark m_visited; // the proof nodes we have already visited - - ast_manager& m; + ast_mark m_visited; // the proof nodes we have already visited + ast_manager& m; }; - void reduce_hypotheses(proof_ref &pr); -} + + #endif diff --git a/src/muz/pdr/pdr_context.cpp b/src/muz/pdr/pdr_context.cpp index e6d91c87e..a1878dc7a 100644 --- a/src/muz/pdr/pdr_context.cpp +++ b/src/muz/pdr/pdr_context.cpp @@ -41,7 +41,7 @@ Notes: #include "ast/ast_smt2_pp.h" #include "qe/qe_lite.h" #include "ast/ast_ll_pp.h" -#include "ast/proof_checker/proof_checker.h" +#include "ast/proofs/proof_checker.h" #include "smt/smt_value_sort.h" #include "muz/base/proof_utils.h" #include "muz/base/dl_boogie_proof.h" diff --git a/src/muz/spacer/CMakeLists.txt b/src/muz/spacer/CMakeLists.txt index bc2f45b43..94e429171 100644 --- a/src/muz/spacer/CMakeLists.txt +++ b/src/muz/spacer/CMakeLists.txt @@ -15,7 +15,6 @@ z3_add_component(spacer spacer_itp_solver.cpp spacer_virtual_solver.cpp spacer_legacy_mbp.cpp - spacer_proof_utils.cpp spacer_unsat_core_learner.cpp spacer_unsat_core_plugin.cpp spacer_matrix.cpp diff --git a/src/muz/spacer/spacer_context.cpp b/src/muz/spacer/spacer_context.cpp index 7ab78d453..b057730d8 100644 --- a/src/muz/spacer/spacer_context.cpp +++ b/src/muz/spacer/spacer_context.cpp @@ -40,7 +40,7 @@ Notes: #include "ast/ast_smt2_pp.h" #include "ast/ast_ll_pp.h" #include "ast/ast_util.h" -#include "ast/proof_checker/proof_checker.h" +#include "ast/proofs/proof_checker.h" #include "smt/smt_value_sort.h" #include "ast/scoped_proof.h" #include "muz/spacer/spacer_qe_project.h" diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp index 9c302e5fd..dd2a16abd 100644 --- a/src/muz/spacer/spacer_legacy_frames.cpp +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -23,7 +23,7 @@ #include "ast/ast_smt2_pp.h" #include "ast/ast_ll_pp.h" #include "ast/ast_util.h" -#include "ast/proof_checker/proof_checker.h" +#include "ast/proofs/proof_checker.h" #include "smt/smt_value_sort.h" #include "muz/base/proof_utils.h" #include "ast/scoped_proof.h" diff --git a/src/muz/spacer/spacer_unsat_core_learner.cpp b/src/muz/spacer/spacer_unsat_core_learner.cpp index 222ca146c..d478b1e8f 100644 --- a/src/muz/spacer/spacer_unsat_core_learner.cpp +++ b/src/muz/spacer/spacer_unsat_core_learner.cpp @@ -41,7 +41,7 @@ void unsat_core_learner::compute_unsat_core(proof *root, expr_set& asserted_b, e // transform proof in order to get a proof which is better suited for unsat-core-extraction proof_ref pr(root, m); - spacer::reduce_hypotheses(pr); + reduce_hypotheses(pr); STRACE("spacer.unsat_core_learner", verbose_stream() << "Reduced proof:\n" << mk_ismt2_pp(pr, m) << "\n"; ); @@ -50,7 +50,7 @@ void unsat_core_learner::compute_unsat_core(proof *root, expr_set& asserted_b, e collect_symbols_b(asserted_b); // traverse proof - ProofIteratorPostOrder it(root, m); + proof_post_order it(root, m); while (it.hasNext()) { proof* currentNode = it.next(); @@ -138,7 +138,7 @@ void unsat_core_learner::compute_unsat_core(proof *root, expr_set& asserted_b, e std::unordered_map id_to_small_id; unsigned counter = 0; - ProofIteratorPostOrder it2(root, m); + proof_post_order it2(root, m); while (it2.hasNext()) { proof* currentNode = it2.next(); diff --git a/src/muz/spacer/spacer_unsat_core_learner.h b/src/muz/spacer/spacer_unsat_core_learner.h index 6ee7c3b37..a7c9f6aa7 100644 --- a/src/muz/spacer/spacer_unsat_core_learner.h +++ b/src/muz/spacer/spacer_unsat_core_learner.h @@ -20,7 +20,7 @@ Revision History: #include "ast/ast.h" #include "muz/spacer/spacer_util.h" -#include "muz/spacer/spacer_proof_utils.h" +#include "ast/proofs/proof_utils.h" namespace spacer { diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index 0d90d2653..3f1e53778 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -20,13 +20,13 @@ Revision History: #include "ast/rewriter/bool_rewriter.h" #include "ast/arith_decl_plugin.h" +#include "ast/proofs/proof_utils.h" #include "solver/solver.h" #include "smt/smt_farkas_util.h" #include "smt/smt_solver.h" -#include "muz/spacer/spacer_proof_utils.h" #include "muz/spacer/spacer_matrix.h" #include "muz/spacer/spacer_unsat_core_plugin.h" #include "muz/spacer/spacer_unsat_core_learner.h" diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp index ebaef14f0..244a97d22 100644 --- a/src/muz/spacer/spacer_virtual_solver.cpp +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -23,7 +23,7 @@ Notes: #include "muz/spacer/spacer_util.h" #include "ast/rewriter/bool_rewriter.h" -#include "ast/proof_checker/proof_checker.h" +#include "ast/proofs/proof_checker.h" #include "ast/scoped_proof.h" diff --git a/src/smt/CMakeLists.txt b/src/smt/CMakeLists.txt index 41890dd05..e102bd28b 100644 --- a/src/smt/CMakeLists.txt +++ b/src/smt/CMakeLists.txt @@ -75,7 +75,7 @@ z3_add_component(smt normal_forms parser_util pattern - proof_checker + proofs proto_model simplex substitution diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 9f68f2412..dd92f250a 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -163,7 +163,7 @@ void asserted_formulas::assert_expr(expr * e, proof * _in_pr) { } void asserted_formulas::assert_expr(expr * e) { - assert_expr(e, m.mk_asserted(e)); + assert_expr(e, m.proofs_enabled() ? m.mk_asserted(e) : nullptr); } void asserted_formulas::get_assertions(ptr_vector & result) const { @@ -365,7 +365,7 @@ void asserted_formulas::nnf_cnf() { CASSERT("well_sorted", is_well_sorted(m, n)); apply_nnf(n, push_todo, push_todo_prs, r1, pr1); CASSERT("well_sorted",is_well_sorted(m, r1)); - pr = m.mk_modus_ponens(pr, pr1); + pr = m.proofs_enabled() ? m.mk_modus_ponens(pr, pr1) : nullptr; push_todo.push_back(r1); push_todo_prs.push_back(pr); @@ -506,16 +506,16 @@ void asserted_formulas::update_substitution(expr* n, proof* pr) { } if (is_gt(rhs, lhs)) { TRACE("propagate_values", tout << "insert " << mk_pp(rhs, m) << " -> " << mk_pp(lhs, m) << "\n";); - m_scoped_substitution.insert(rhs, lhs, m.mk_symmetry(pr)); + m_scoped_substitution.insert(rhs, lhs, m.proofs_enabled() ? m.mk_symmetry(pr) : nullptr); return; } TRACE("propagate_values", tout << "incompatible " << mk_pp(n, m) << "\n";); } if (m.is_not(n, n1)) { - m_scoped_substitution.insert(n1, m.mk_false(), m.mk_iff_false(pr)); + m_scoped_substitution.insert(n1, m.mk_false(), m.proofs_enabled() ? m.mk_iff_false(pr) : nullptr); } else { - m_scoped_substitution.insert(n, m.mk_true(), m.mk_iff_true(pr)); + m_scoped_substitution.insert(n, m.mk_true(), m.proofs_enabled() ? m.mk_iff_true(pr) : nullptr); } } diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 48d02da26..c508a65cb 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -23,7 +23,7 @@ Revision History: #include "ast/ast_ll_pp.h" #include "util/warning.h" #include "smt/smt_quick_checker.h" -#include "ast/proof_checker/proof_checker.h" +#include "ast/proofs/proof_checker.h" #include "ast/ast_util.h" #include "smt/uses_theory.h" #include "model/model.h" diff --git a/src/test/proof_checker.cpp b/src/test/proof_checker.cpp index 33a908f24..7a9b619cd 100644 --- a/src/test/proof_checker.cpp +++ b/src/test/proof_checker.cpp @@ -4,7 +4,7 @@ Copyright (c) 2015 Microsoft Corporation --*/ -#include "ast/proof_checker/proof_checker.h" +#include "ast/proofs/proof_checker.h" #include "ast/ast_ll_pp.h" void tst_checker1() { From 70f7846af5e736032daed9c6becb50257a2c98c0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 03:18:59 -0700 Subject: [PATCH 461/488] move spacer_marshal to under parsers/smt2 Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/CMakeLists.txt | 1 - src/parsers/smt2/CMakeLists.txt | 1 + .../smt2/marshal.cpp} | 22 +++++++------------ .../smt2/marshal.h} | 5 +---- 4 files changed, 10 insertions(+), 19 deletions(-) rename src/{muz/spacer/spacer_marshal.cpp => parsers/smt2/marshal.cpp} (71%) rename src/{muz/spacer/spacer_marshal.h => parsers/smt2/marshal.h} (91%) diff --git a/src/muz/spacer/CMakeLists.txt b/src/muz/spacer/CMakeLists.txt index 94e429171..97c991e2a 100644 --- a/src/muz/spacer/CMakeLists.txt +++ b/src/muz/spacer/CMakeLists.txt @@ -7,7 +7,6 @@ z3_add_component(spacer spacer_farkas_learner.cpp spacer_generalizers.cpp spacer_manager.cpp - spacer_marshal.cpp spacer_prop_solver.cpp spacer_smt_context_manager.cpp spacer_sym_mux.cpp diff --git a/src/parsers/smt2/CMakeLists.txt b/src/parsers/smt2/CMakeLists.txt index 1467d95c6..022cce2f2 100644 --- a/src/parsers/smt2/CMakeLists.txt +++ b/src/parsers/smt2/CMakeLists.txt @@ -1,5 +1,6 @@ z3_add_component(smt2parser SOURCES + marshal.cpp smt2parser.cpp smt2scanner.cpp COMPONENT_DEPENDENCIES diff --git a/src/muz/spacer/spacer_marshal.cpp b/src/parsers/smt2/marshal.cpp similarity index 71% rename from src/muz/spacer/spacer_marshal.cpp rename to src/parsers/smt2/marshal.cpp index 68c90bd33..ae144e491 100644 --- a/src/muz/spacer/spacer_marshal.cpp +++ b/src/parsers/smt2/marshal.cpp @@ -2,14 +2,14 @@ Copyright (c) 2017 Arie Gurfinkel Module Name: - spacer_marshal.cpp + marshal.cpp Abstract: marshaling and unmarshaling of expressions --*/ -#include "muz/spacer/spacer_marshal.h" +#include "parsers/smt2/marshal.h" #include @@ -18,39 +18,33 @@ Abstract: #include "util/vector.h" #include "ast/ast_smt_pp.h" #include "ast/ast_pp.h" +#include "ast/ast_util.h" -namespace spacer { -std::ostream &marshal(std::ostream &os, expr_ref e, ast_manager &m) -{ +std::ostream &marshal(std::ostream &os, expr_ref e, ast_manager &m) { ast_smt_pp pp(m); pp.display_smt2(os, e); return os; } -std::string marshal(expr_ref e, ast_manager &m) -{ +std::string marshal(expr_ref e, ast_manager &m) { std::stringstream ss; marshal(ss, e, m); return ss.str(); } -expr_ref unmarshal(std::istream &is, ast_manager &m) -{ +expr_ref unmarshal(std::istream &is, ast_manager &m) { cmd_context ctx(false, &m); ctx.set_ignore_check(true); if (!parse_smt2_commands(ctx, is)) { return expr_ref(0, m); } ptr_vector::const_iterator it = ctx.begin_assertions(); ptr_vector::const_iterator end = ctx.end_assertions(); - if (it == end) { return expr_ref(m.mk_true(), m); } unsigned size = static_cast(end - it); - return expr_ref(m.mk_and(size, it), m); + return expr_ref(mk_and(m, size, it), m); } -expr_ref unmarshal(std::string s, ast_manager &m) -{ +expr_ref unmarshal(std::string s, ast_manager &m) { std::istringstream is(s); return unmarshal(is, m); } -} diff --git a/src/muz/spacer/spacer_marshal.h b/src/parsers/smt2/marshal.h similarity index 91% rename from src/muz/spacer/spacer_marshal.h rename to src/parsers/smt2/marshal.h index 95cb8f26a..ebc2c0426 100644 --- a/src/muz/spacer/spacer_marshal.h +++ b/src/parsers/smt2/marshal.h @@ -2,7 +2,7 @@ Copyright (c) 2017 Arie Gurfinkel Module Name: - spacer_marshal.h + marshal.h Abstract: @@ -17,14 +17,11 @@ Abstract: #include "ast/ast.h" -namespace spacer { std::ostream &marshal(std::ostream &os, expr_ref e, ast_manager &m); std::string marshal(expr_ref e, ast_manager &m); expr_ref unmarshal(std::string s, ast_manager &m); expr_ref unmarshal(std::istream &is, ast_manager &m); -} - #endif From e6e1d94cf9d7a3fa2b5c60131c9e80a6e7c18384 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 03:39:00 -0700 Subject: [PATCH 462/488] fix build issues Signed-off-by: Nikolaj Bjorner --- src/ast/ast_pp_dot.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/ast/ast_pp_dot.cpp b/src/ast/ast_pp_dot.cpp index eb4ec80fe..df3de730f 100644 --- a/src/ast/ast_pp_dot.cpp +++ b/src/ast/ast_pp_dot.cpp @@ -6,7 +6,7 @@ Abstract: Pretty-printer for proofs in Graphviz format #include "util/util.h" #include "util/map.h" -#include "ast_pp_dot.h" +#include "ast/ast_pp_dot.h" // string escaping for DOT std::string escape_dot(std::string const & s) { @@ -23,28 +23,27 @@ std::string escape_dot(std::string const & s) { // map from proofs to unique IDs typedef obj_map expr2id; -typedef obj_map set_expr; // temporary structure for traversing the proof and printing it struct ast_pp_dot_st { - const ast_pp_dot * m_pp; - set_expr m_printed; - expr2id m_id_map; - svector m_to_print; - std::ostream & m_out; - unsigned m_next_id; - bool m_first; ast_manager & m_manager; + std::ostream & m_out; + const ast_pp_dot * m_pp; + unsigned m_next_id; + expr2id m_id_map; + obj_hashtable m_printed; + svector m_to_print; + bool m_first; ast_pp_dot_st(const ast_pp_dot * pp, std::ostream & out) : - m_pp(pp), + m_manager(pp->get_manager()), m_out(out), + m_pp(pp), m_next_id(0), m_id_map(), m_to_print(), m_printed(), - m_first(true), - m_manager(pp->get_manager()) {} + m_first(true) {} ~ast_pp_dot_st() = default; @@ -56,7 +55,7 @@ struct ast_pp_dot_st { const expr * a = m_to_print.back(); m_to_print.pop_back(); if (!m_printed.contains(a)) { - m_printed.insert(a, true); + m_printed.insert(a); if (m().is_proof(a)) pp_step(to_app(a)); else @@ -83,7 +82,7 @@ private: } void pp_step(const proof * p) { - TRACE("pp_ast_dot_step", tout << " :kind " << p->get_kind() << " :num-args " << num_args); + TRACE("pp_ast_dot_step", tout << " :kind " << p->get_kind() << " :num-args " << p->get_num_args() << "\n";); if (m().has_fact(p)) { // print result expr* p_res = m().get_fact(p); // result of proof step From eda3c6258b07ee9707081498557dc9ba56cb3358 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 24 Oct 2017 12:53:24 +0100 Subject: [PATCH 463/488] backward comp --- src/ast/ast_pp_dot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ast_pp_dot.cpp b/src/ast/ast_pp_dot.cpp index df3de730f..ebbf4b2b2 100644 --- a/src/ast/ast_pp_dot.cpp +++ b/src/ast/ast_pp_dot.cpp @@ -45,7 +45,7 @@ struct ast_pp_dot_st { m_printed(), m_first(true) {} - ~ast_pp_dot_st() = default; + ~ast_pp_dot_st() {}; void push_term(const expr * a) { m_to_print.push_back(a); } From 637a0fa1393dd6e7c99cf0bda15b0824a3fecb7a Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 08:49:25 -0700 Subject: [PATCH 464/488] unused warnings Signed-off-by: Nikolaj Bjorner --- src/ast/ast_pp_dot.cpp | 2 +- src/ast/fpa/fpa2bv_converter.cpp | 2 -- src/muz/spacer/spacer_util.cpp | 2 -- src/muz/spacer/spacer_virtual_solver.cpp | 4 ++++ src/muz/spacer/spacer_virtual_solver.h | 3 ++- src/smt/theory_array_base.cpp | 1 - src/tactic/core/dom_simplify_tactic.cpp | 2 +- src/tactic/core/dom_simplify_tactic.h | 4 +--- 8 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/ast/ast_pp_dot.cpp b/src/ast/ast_pp_dot.cpp index df3de730f..e3782cb21 100644 --- a/src/ast/ast_pp_dot.cpp +++ b/src/ast/ast_pp_dot.cpp @@ -41,8 +41,8 @@ struct ast_pp_dot_st { m_pp(pp), m_next_id(0), m_id_map(), - m_to_print(), m_printed(), + m_to_print(), m_first(true) {} ~ast_pp_dot_st() = default; diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 13a7599a9..220295dad 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3076,8 +3076,6 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * split_fp(x, sgn, e, s); mk_is_nan(x, x_is_nan); - sort * fp_srt = m.get_sort(x); - expr_ref unspec(m); mk_to_ieee_bv_unspecified(f, num, args, unspec); diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp index 31190a97f..83042cd6d 100644 --- a/src/muz/spacer/spacer_util.cpp +++ b/src/muz/spacer/spacer_util.cpp @@ -149,8 +149,6 @@ namespace spacer { expr_ref val(m), tmp(m); proof_ref pr(m); pr = m.mk_asserted(m.mk_true()); - obj_map::iterator it = diseqs.begin(); - obj_map::iterator end = diseqs.end(); for (auto const& kv : diseqs) { if (kv.m_value >= threshold) { model.eval(kv.m_key, val); diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp index 244a97d22..87a21336c 100644 --- a/src/muz/spacer/spacer_virtual_solver.cpp +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -81,6 +81,8 @@ static bool matches_fact(expr_ref_vector &args, expr* &match) } +// TBD: move to ast/proofs/elim_aux_assertions + class elim_aux_assertions { app_ref m_aux; public: @@ -404,6 +406,7 @@ void virtual_solver::refresh() m_head = 0; } +#ifdef NOT_USED_ANYWHERE void virtual_solver::reset() { SASSERT(!m_pushed); @@ -411,6 +414,7 @@ void virtual_solver::reset() m_assertions.reset(); m_factory.refresh(); } +#endif void virtual_solver::get_labels(svector &r) { diff --git a/src/muz/spacer/spacer_virtual_solver.h b/src/muz/spacer/spacer_virtual_solver.h index 14e05302e..3ccd89ef5 100644 --- a/src/muz/spacer/spacer_virtual_solver.h +++ b/src/muz/spacer/spacer_virtual_solver.h @@ -91,8 +91,9 @@ public: virtual void set_produce_models(bool f); virtual bool get_produce_models(); virtual smt_params &fparams(); +#ifdef NOT_USED_ANYWHERE virtual void reset(); - +#endif virtual void set_progress_callback(progress_callback *callback) {UNREACHABLE();} diff --git a/src/smt/theory_array_base.cpp b/src/smt/theory_array_base.cpp index 2aaf2833f..472053fdc 100644 --- a/src/smt/theory_array_base.cpp +++ b/src/smt/theory_array_base.cpp @@ -218,7 +218,6 @@ namespace smt { ast_manager & m = get_manager(); ext_skolems = alloc(func_decl_ref_vector, m); for (unsigned i = 0; i < dimension; ++i) { - sort * ext_sk_domain[2] = { s_array, s_array }; func_decl * ext_sk_decl = util.mk_array_ext(s_array, i); ext_skolems->push_back(ext_sk_decl); } diff --git a/src/tactic/core/dom_simplify_tactic.cpp b/src/tactic/core/dom_simplify_tactic.cpp index ee94c5e57..2099eebf0 100644 --- a/src/tactic/core/dom_simplify_tactic.cpp +++ b/src/tactic/core/dom_simplify_tactic.cpp @@ -441,7 +441,7 @@ ptr_vector const & dom_simplify_tactic::tree(expr * e) { } -// ---------------------- +// --------------------- // expr_substitution_simplifier bool expr_substitution_simplifier::assert_expr(expr * t, bool sign) { diff --git a/src/tactic/core/dom_simplify_tactic.h b/src/tactic/core/dom_simplify_tactic.h index 6cd94a3c1..56eea8d9a 100644 --- a/src/tactic/core/dom_simplify_tactic.h +++ b/src/tactic/core/dom_simplify_tactic.h @@ -95,7 +95,6 @@ class dom_simplify_tactic : public tactic { expr_ref_vector m_trail, m_args; obj_map m_result; expr_dominators m_dominators; - unsigned m_scope_level; unsigned m_depth; unsigned m_max_depth; ptr_vector m_empty; @@ -128,8 +127,7 @@ public: dom_simplify_tactic(ast_manager & m, dom_simplifier* s, params_ref const & p = params_ref()): m(m), m_simplifier(s), m_params(p), m_trail(m), m_args(m), - m_dominators(m), - m_scope_level(0), m_depth(0), m_max_depth(1024), m_forward(true) {} + m_dominators(m), m_depth(0), m_max_depth(1024), m_forward(true) {} virtual ~dom_simplify_tactic(); From 1315c8d7dea433574d28bd0e22f782ff784c68fb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 09:03:28 -0700 Subject: [PATCH 465/488] rename repeated class apart Signed-off-by: Nikolaj Bjorner --- src/muz/base/proof_utils.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/muz/base/proof_utils.cpp b/src/muz/base/proof_utils.cpp index 3b2d50fdc..87355a07b 100644 --- a/src/muz/base/proof_utils.cpp +++ b/src/muz/base/proof_utils.cpp @@ -9,7 +9,7 @@ Copyright (c) 2015 Microsoft Corporation #include "ast/ast_smt2_pp.h" #include "ast/rewriter/var_subst.h" -class reduce_hypotheses { +class reduce_hypotheses0 { typedef obj_hashtable expr_set; ast_manager& m; // reference for any expression created by the tranformation @@ -137,7 +137,7 @@ class reduce_hypotheses { } public: - reduce_hypotheses(ast_manager& m): m(m), m_refs(m) {} + reduce_hypotheses0(ast_manager& m): m(m), m_refs(m) {} void operator()(proof_ref& pr) { proof_ref tmp(m); @@ -416,7 +416,7 @@ public: void proof_utils::reduce_hypotheses(proof_ref& pr) { ast_manager& m = pr.get_manager(); - class reduce_hypotheses reduce(m); + class reduce_hypotheses0 reduce(m); reduce(pr); CTRACE("proof_utils", !is_closed(m, pr), tout << mk_pp(pr, m) << "\n";); } From f27ac24fa075279df553687d17154d391a69b1fd Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Tue, 24 Oct 2017 17:27:58 +0100 Subject: [PATCH 466/488] Add example of using Z3's new model construction C API. This API was requested in #1223. This example uses the new `Z3_mk_model()`, `Z3_add_const_interp()` , `Z3_add_func_interp()`, and `Z3_mk_as_array()` API calls. --- examples/c/test_capi.c | 171 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index fa27c7887..433c7ebcf 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2840,6 +2840,176 @@ void fpa_example() { Z3_del_context(ctx); } +/** + \brief Demonstrates some basic features of model construction +*/ + +void mk_model_example() { + printf("\nmk_model_example\n"); + LOG_MSG("mk_model_example"); + Z3_context ctx = mk_context(); + // Construct empty model + Z3_model m = Z3_mk_model(ctx); + Z3_model_inc_ref(ctx, m); + + // Create constants "a" and "b" + Z3_sort intSort = Z3_mk_int_sort(ctx); + Z3_symbol aSymbol = Z3_mk_string_symbol(ctx, "a"); + Z3_func_decl aFuncDecl = Z3_mk_func_decl(ctx, aSymbol, + /*domain_size=*/0, + /*domain=*/NULL, + /*range=*/intSort); + Z3_ast aApp = Z3_mk_app(ctx, aFuncDecl, + /*num_args=*/0, + /*args=*/NULL); + Z3_symbol bSymbol = Z3_mk_string_symbol(ctx, "b"); + Z3_func_decl bFuncDecl = Z3_mk_func_decl(ctx, bSymbol, + /*domain_size=*/0, + /*domain=*/NULL, + /*range=*/intSort); + Z3_ast bApp = Z3_mk_app(ctx, bFuncDecl, + /*num_args=*/0, + /*args=*/NULL); + + // Create array "c" that maps int to int. + Z3_symbol cSymbol = Z3_mk_string_symbol(ctx, "c"); + Z3_sort int2intArraySort = Z3_mk_array_sort(ctx, + /*domain=*/intSort, + /*range=*/intSort); + Z3_func_decl cFuncDecl = Z3_mk_func_decl(ctx, cSymbol, + /*domain_size=*/0, + /*domain=*/NULL, + /*range=*/int2intArraySort); + Z3_ast cApp = Z3_mk_app(ctx, cFuncDecl, + /*num_args=*/0, + /*args=*/NULL); + + // Create numerals to be used in model + Z3_ast zeroNumeral = Z3_mk_int(ctx, 0, intSort); + Z3_ast oneNumeral = Z3_mk_int(ctx, 1, intSort); + Z3_ast twoNumeral = Z3_mk_int(ctx, 2, intSort); + Z3_ast threeNumeral = Z3_mk_int(ctx, 3, intSort); + Z3_ast fourNumeral = Z3_mk_int(ctx, 4, intSort); + + // Add assignments to model + // a == 1 + Z3_add_const_interp(ctx, m, aFuncDecl, oneNumeral); + // b == 2 + Z3_add_const_interp(ctx, m, bFuncDecl, twoNumeral); + + // Create a fresh function that represents + // reading from array. + Z3_sort arrayDomain[] = {intSort}; + Z3_func_decl cAsFuncDecl = Z3_mk_fresh_func_decl(ctx, + /*prefix=*/"", + /*domain_size*/ 1, + /*domain=*/arrayDomain, + /*sort=*/intSort); + // Create function interpretation with default + // value of "0". + Z3_func_interp cAsFuncInterp = + Z3_add_func_interp(ctx, m, cAsFuncDecl, + /*default_value=*/zeroNumeral); + Z3_func_interp_inc_ref(ctx, cAsFuncInterp); + // Add [0] = 3 + Z3_ast_vector zeroArgs = Z3_mk_ast_vector(ctx); + Z3_ast_vector_inc_ref(ctx, zeroArgs); + Z3_ast_vector_push(ctx, zeroArgs, zeroNumeral); + Z3_func_interp_add_entry(ctx, cAsFuncInterp, zeroArgs, threeNumeral); + // Add [1] = 4 + Z3_ast_vector oneArgs = Z3_mk_ast_vector(ctx); + Z3_ast_vector_inc_ref(ctx, oneArgs); + Z3_ast_vector_push(ctx, oneArgs, oneNumeral); + Z3_func_interp_add_entry(ctx, cAsFuncInterp, oneArgs, fourNumeral); + + // Now use the `(_ as_array)` to associate + // the `cAsFuncInterp` with the `cFuncDecl` + // in the model + Z3_ast cFuncDeclAsArray = Z3_mk_as_array(ctx, cAsFuncDecl); + Z3_add_const_interp(ctx, m, cFuncDecl, cFuncDeclAsArray); + + // Print the model + Z3_string modelAsString = Z3_model_to_string(ctx, m); + printf("Model:\n%s\n", modelAsString); + + // Check the interpretations we expect to be present + // are. + Z3_func_decl expectedInterpretations[] = {aFuncDecl, bFuncDecl, cFuncDecl}; + for (int index = 0; + index < sizeof(expectedInterpretations) / sizeof(Z3_func_decl); + ++index) { + Z3_func_decl d = expectedInterpretations[index]; + if (Z3_model_has_interp(ctx, m, d)) { + printf("Found interpretation for \"%s\"\n", + Z3_ast_to_string(ctx, Z3_func_decl_to_ast(ctx, d))); + } else { + printf("Missing interpretation"); + exit(1); + } + } + + // Evaluate a + b under model + Z3_ast addArgs[] = {aApp, bApp}; + Z3_ast aPlusB = Z3_mk_add(ctx, + /*num_args=*/2, + /*args=*/addArgs); + Z3_ast aPlusBEval = NULL; + Z3_bool aPlusBEvalSuccess = + Z3_model_eval(ctx, m, aPlusB, + /*model_completion=*/Z3_FALSE, &aPlusBEval); + if (aPlusBEvalSuccess != Z3_TRUE) { + printf("Failed to evaluate model\n"); + exit(1); + } + int aPlusBValue = 0; + Z3_bool getAPlusBValueSuccess = + Z3_get_numeral_int(ctx, aPlusBEval, &aPlusBValue); + if (getAPlusBValueSuccess != Z3_TRUE) { + printf("Failed to get integer value for a+b\n"); + exit(1); + } + printf("Evaluated a + b = %d\n", aPlusBValue); + if (aPlusBValue != 3) { + printf("a+b did not evaluate to expected value\n"); + exit(1); + } + + // Evaluate c[0] + c[1] + c[2] under model + Z3_ast c0 = Z3_mk_select(ctx, cApp, zeroNumeral); + Z3_ast c1 = Z3_mk_select(ctx, cApp, oneNumeral); + Z3_ast c2 = Z3_mk_select(ctx, cApp, twoNumeral); + Z3_ast arrayAddArgs[] = {c0, c1, c2}; + Z3_ast arrayAdd = Z3_mk_add(ctx, + /*num_args=*/3, + /*args=*/arrayAddArgs); + Z3_ast arrayAddEval = NULL; + Z3_bool arrayAddEvalSuccess = + Z3_model_eval(ctx, m, arrayAdd, + /*model_completion=*/Z3_FALSE, &arrayAddEval); + if (arrayAddEvalSuccess != Z3_TRUE) { + printf("Failed to evaluate model\n"); + exit(1); + } + int arrayAddValue = 0; + Z3_bool getArrayAddValueSuccess = + Z3_get_numeral_int(ctx, arrayAddEval, &arrayAddValue); + if (getArrayAddValueSuccess != Z3_TRUE) { + printf("Failed to get integer value for c[0] + c[1] + c[2]\n"); + exit(1); + } + printf("Evaluated c[0] + c[1] + c[2] = %d\n", arrayAddValue); + if (arrayAddValue != 7) { + printf("c[0] + c[1] + c[2] did not evaluate to expected value\n"); + exit(1); + } + + Z3_ast_vector_dec_ref(ctx, oneArgs); + Z3_ast_vector_dec_ref(ctx, zeroArgs); + Z3_func_interp_dec_ref(ctx, cAsFuncInterp); + Z3_model_dec_ref(ctx, m); + Z3_del_context(ctx); +} + /*@}*/ /*@}*/ @@ -2888,5 +3058,6 @@ int main() { substitute_example(); substitute_vars_example(); fpa_example(); + mk_model_example(); return 0; } From fc822af707ebe1c80708587d524a838849743464 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 09:59:55 -0700 Subject: [PATCH 467/488] move proof utils under ast Signed-off-by: Nikolaj Bjorner --- src/ast/proofs/proof_utils.cpp | 676 ++++++++++++++++++++++ src/ast/proofs/proof_utils.h | 31 +- src/muz/base/CMakeLists.txt | 1 - src/muz/base/dl_boogie_proof.cpp | 2 +- src/muz/base/dl_util.h | 128 +---- src/muz/base/proof_utils.cpp | 680 ----------------------- src/muz/base/proof_utils.h | 48 -- src/muz/pdr/pdr_context.cpp | 1 - src/muz/pdr/pdr_farkas_learner.cpp | 8 +- src/muz/pdr/pdr_generalizers.cpp | 6 +- src/muz/spacer/spacer_farkas_learner.cpp | 8 +- src/muz/spacer/spacer_legacy_frames.cpp | 2 +- 12 files changed, 722 insertions(+), 869 deletions(-) delete mode 100644 src/muz/base/proof_utils.cpp delete mode 100644 src/muz/base/proof_utils.h diff --git a/src/ast/proofs/proof_utils.cpp b/src/ast/proofs/proof_utils.cpp index bd82696ea..b6c8b58d7 100644 --- a/src/ast/proofs/proof_utils.cpp +++ b/src/ast/proofs/proof_utils.cpp @@ -20,6 +20,7 @@ Revision History: #include "ast/ast_pp.h" #include "ast/proofs/proof_utils.h" #include "ast/proofs/proof_checker.h" +#include "util/container_util.h" @@ -331,3 +332,678 @@ void reduce_hypotheses(proof_ref &pr) { SASSERT(pc.check(pr, side)); ); } + + + +#include "ast/ast_smt2_pp.h" +#include "ast/rewriter/var_subst.h" + +class reduce_hypotheses0 { + typedef obj_hashtable expr_set; + ast_manager& m; + // reference for any expression created by the tranformation + expr_ref_vector m_refs; + // currently computed result + obj_map m_cache; + // map conclusions to closed proofs that derive them + obj_map m_units; + // currently active units + ptr_vector m_units_trail; + // size of m_units_trail at the last push + unsigned_vector m_limits; + // map from proofs to active hypotheses + obj_map m_hypmap; + // refernce train for hypotheses sets + ptr_vector m_hyprefs; + ptr_vector m_literals; + + void reset() { + m_refs.reset(); + m_cache.reset(); + m_units.reset(); + m_units_trail.reset(); + m_limits.reset(); + std::for_each(m_hyprefs.begin(), m_hyprefs.end(), delete_proc()); + m_hypmap.reset(); + m_hyprefs.reset(); + m_literals.reset(); + } + + void push() { + m_limits.push_back(m_units_trail.size()); + } + + void pop() { + unsigned sz = m_limits.back(); + while (m_units_trail.size() > sz) { + m_units.remove(m_units_trail.back()); + m_units_trail.pop_back(); + } + m_limits.pop_back(); + } + + void get_literals(expr* clause) { + m_literals.reset(); + if (m.is_or(clause)) { + m_literals.append(to_app(clause)->get_num_args(), to_app(clause)->get_args()); + } + else { + m_literals.push_back(clause); + } + } + + void add_hypotheses(proof* p) { + expr_set* hyps = 0; + bool inherited = false; + if (p->get_decl_kind() == PR_HYPOTHESIS) { + hyps = alloc(expr_set); + hyps->insert(m.get_fact(p)); + m_hyprefs.push_back(hyps); + } + else { + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + expr_set* hyps1 = m_hypmap.find(m.get_parent(p, i)); + if (hyps1) { + if (!hyps) { + hyps = hyps1; + inherited = true; + continue; + } + if (inherited) { + hyps = alloc(expr_set,*hyps); + m_hyprefs.push_back(hyps); + inherited = false; + } + set_union(*hyps, *hyps1); + } + } + } + m_hypmap.insert(p, hyps); + } + + expr_ref complement_lit(expr* e) { + expr* e1; + if (m.is_not(e, e1)) { + return expr_ref(e1, m); + } + else { + return expr_ref(m.mk_not(e), m); + } + } + + bool in_hypotheses(expr* e, expr_set* hyps) { + if (!hyps) { + return false; + } + expr_ref not_e = complement_lit(e); + return hyps->contains(not_e); + } + + bool contains_hypothesis(proof* p) { + ptr_vector todo; + ast_mark visit; + todo.push_back(p); + while (!todo.empty()) { + p = todo.back(); + todo.pop_back(); + if (visit.is_marked(p)) { + continue; + } + visit.mark(p, true); + if (PR_HYPOTHESIS == p->get_decl_kind()) { + return true; + } + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + todo.push_back(m.get_parent(p, i)); + } + } + return false; + } + + bool is_closed(proof* p) { + expr_set* hyps = m_hypmap.find(p); + return !hyps || hyps->empty(); + } + +public: + reduce_hypotheses0(ast_manager& m): m(m), m_refs(m) {} + + void operator()(proof_ref& pr) { + proof_ref tmp(m); + tmp = pr; + elim(pr); + reset(); + CTRACE("proof_utils", contains_hypothesis(pr), + tout << "Contains hypothesis:\n"; + tout << mk_ismt2_pp(tmp, m) << "\n====>\n"; + tout << mk_ismt2_pp(pr, m) << "\n";); + + } + + void elim(proof_ref& p) { + proof_ref tmp(m); + proof* result = p.get(); + if (m_cache.find(p, result)) { + p = result; + return; + } + //SASSERT (p.get () == result); + switch(p->get_decl_kind()) { + case PR_HYPOTHESIS: + // replace result by m_units[m.get_fact (p)] if defined + // AG: This is the main step. Replace a hypothesis by a derivation of its consequence + if (!m_units.find(m.get_fact(p), result)) { + // restore ther result back to p + result = p.get(); + } + // compute hypothesis of the result + // not clear what 'result' is at this point. + // probably the proof at the top of the call + // XXX not clear why this is re-computed each time + // XXX moreover, m_units are guaranteed to be closed! + // XXX so no hypotheses are needed for them + add_hypotheses(result); + break; + case PR_LEMMA: { + SASSERT(m.get_num_parents(p) == 1); + tmp = m.get_parent(p, 0); + // eliminate hypothesis recursively in the proof of the lemma + elim(tmp); + expr_set* hyps = m_hypmap.find(tmp); + expr_set* new_hyps = 0; + // XXX if the proof is correct, the hypotheses of the tmp + // XXX should be exactly those of the consequence of the lemma + // XXX but if this code actually eliminates hypotheses, the set might be a subset + if (hyps) { + new_hyps = alloc(expr_set, *hyps); + } + expr* fact = m.get_fact(p); + // when hypothesis is a single literal of the form + // (or A B), and the fact of p is (or A B). + if (hyps && hyps->size() == 1 && in_hypotheses(fact, hyps)) { + m_literals.reset(); + m_literals.push_back(fact); + } + else { + get_literals(fact); + } + + // go over all the literals in the consequence of the lemma + for (unsigned i = 0; i < m_literals.size(); ++i) { + expr* e = m_literals[i]; + // if the literal is not in hypothesis, skip it + if (!in_hypotheses(e, hyps)) { + m_literals[i] = m_literals.back(); + m_literals.pop_back(); + --i; + } + // if the literal is in hypothesis remove it because + // it is not in hypothesis set of the lemma + // XXX but we assume that lemmas have empty hypothesis set. + // XXX eventually every element of new_hyps must be removed! + else { + SASSERT(new_hyps); + expr_ref not_e = complement_lit(e); + SASSERT(new_hyps->contains(not_e)); + new_hyps->remove(not_e); + } + } + // killed all hypotheses, so can stop at the lemma since + // we have a closed pf of false + if (m_literals.empty()) { + result = tmp; + } + else { + // create a new lemma, but might be re-creating existing one + expr_ref clause(m); + if (m_literals.size() == 1) { + clause = m_literals[0]; + } + else { + clause = m.mk_or(m_literals.size(), m_literals.c_ptr()); + } + tmp = m.mk_lemma(tmp, clause); + m_refs.push_back(tmp); + result = tmp; + } + if (new_hyps && new_hyps->empty()) { + dealloc(new_hyps); + new_hyps = 0; + } + m_hypmap.insert(result, new_hyps); + // might push 0 into m_hyprefs. No reason for that + m_hyprefs.push_back(new_hyps); + TRACE("proof_utils", + tout << "New lemma: " << mk_pp(m.get_fact(p), m) + << "\n==>\n" + << mk_pp(m.get_fact(result), m) << "\n"; + if (hyps) { + expr_set::iterator it = hyps->begin(); + expr_set::iterator end = hyps->end(); + for (; it != end; ++it) { + tout << "Hypothesis: " << mk_pp(*it, m) << "\n"; + } + }); + + break; + } + case PR_UNIT_RESOLUTION: { + proof_ref_vector parents(m); + // get the clause being resolved with + parents.push_back(m.get_parent(p, 0)); + // save state + push(); + bool found_false = false; + // for every derivation of a unit literal + for (unsigned i = 1; i < m.get_num_parents(p); ++i) { + // see if it derives false + tmp = m.get_parent(p, i); + elim(tmp); + if (m.is_false(m.get_fact(tmp))) { + // if derived false, the whole pf is false and we can bail out + result = tmp; + found_false = true; + break; + } + // -- otherwise, the fact has not changed. nothing to simplify + SASSERT(m.get_fact(tmp) == m.get_fact(m.get_parent(p, i))); + parents.push_back(tmp); + // remember that we have this derivation while we have not poped the trail + // but only if the proof is closed (i.e., a real unit) + if (is_closed(tmp) && !m_units.contains(m.get_fact(tmp))) { + m_units.insert(m.get_fact(tmp), tmp); + m_units_trail.push_back(m.get_fact(tmp)); + } + } + if (found_false) { + pop(); + break; + } + // look at the clause being resolved with + tmp = m.get_parent(p, 0); + // remember its fact + expr* old_clause = m.get_fact(tmp); + // attempt to reduce its fact + elim(tmp); + // update parents + parents[0] = tmp; + // if the new fact is false, bail out + expr* clause = m.get_fact(tmp); + if (m.is_false(clause)) { + m_refs.push_back(tmp); + result = tmp; + pop(); + break; + } + // + // case where clause is a literal in the old clause. + // i.e., reduce multi-literal clause to a unit + // + if (is_literal_in_clause(clause, old_clause)) { + // if the resulting literal was resolved, get a pf of false and bail out + bool found = false; + for (unsigned i = 1; !found && i < parents.size(); ++i) { + if (m.is_complement(clause, m.get_fact(parents[i].get()))) { + parents[1] = parents[i].get(); + parents.resize(2); + result = m.mk_unit_resolution(parents.size(), parents.c_ptr()); + m_refs.push_back(result); + add_hypotheses(result); + found = true; + } + } + // else if the resulting literal is not resolved, it is the new consequence + if (!found) { + result = parents[0].get(); + } + pop(); + break; + } + // + // case where new clause is a subset of old clause. + // the literals in clause should be a subset of literals in old_clause. + // + get_literals(clause); + for (unsigned i = 1; i < parents.size(); ++i) { + bool found = false; + for (unsigned j = 0; j < m_literals.size(); ++j) { + if (m.is_complement(m_literals[j], m.get_fact(parents[i].get()))) { + found = true; + break; + } + } + if (!found) { + // literal was removed as hypothesis. + parents[i] = parents.back(); + parents.pop_back(); + --i; + } + } + if (parents.size() == 1) { + result = parents[0].get(); + } + else { + result = m.mk_unit_resolution(parents.size(), parents.c_ptr()); + m_refs.push_back(result); + add_hypotheses(result); + } + pop(); + break; + } + default: { + ptr_buffer args; + bool change = false; + bool found_false = false; + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + tmp = m.get_parent(p, i); + elim(tmp); + if (m.is_false(m.get_fact(tmp))) { + result = tmp; + found_false = true; + break; + } + // SASSERT(m.get_fact(tmp) == m.get_fact(m.get_parent(p, i))); + change = change || (tmp != m.get_parent(p, i)); + args.push_back(tmp); + } + if (found_false) { + break; + } + if (m.has_fact(p)) { + args.push_back(m.get_fact(p)); + } + if (change) { + tmp = m.mk_app(p->get_decl(), args.size(), args.c_ptr()); + m_refs.push_back(tmp); + } + else { + tmp = p; + } + result = tmp; + add_hypotheses(result); + break; + } + } + SASSERT(m_hypmap.contains(result)); + m_cache.insert(p, result); + p = result; + } + + bool is_literal_in_clause(expr* fml, expr* clause) { + if (!m.is_or(clause)) { + return false; + } + app* cl = to_app(clause); + for (unsigned i = 0; i < cl->get_num_args(); ++i) { + if (cl->get_arg(i) == fml) { + return true; + } + } + return false; + } +}; + +void proof_utils::reduce_hypotheses(proof_ref& pr) { + ast_manager& m = pr.get_manager(); + class reduce_hypotheses0 reduce(m); + reduce(pr); + CTRACE("proof_utils", !is_closed(m, pr), tout << mk_pp(pr, m) << "\n";); +} + +class proof_is_closed { + ast_manager& m; + ptr_vector m_literals; + ast_mark m_visit; + + void reset() { + m_literals.reset(); + m_visit.reset(); + } + + bool check(proof* p) { + // really just a partial check because nodes may be visited + // already under a different lemma scope. + if (m_visit.is_marked(p)) { + return true; + } + bool result = false; + m_visit.mark(p, true); + switch(p->get_decl_kind()) { + case PR_LEMMA: { + unsigned sz = m_literals.size(); + expr* cls = m.get_fact(p); + m_literals.push_back(cls); + if (m.is_or(cls)) { + m_literals.append(to_app(cls)->get_num_args(), to_app(cls)->get_args()); + } + SASSERT(m.get_num_parents(p) == 1); + result = check(m.get_parent(p, 0)); + m_literals.resize(sz); + break; + } + case PR_HYPOTHESIS: { + expr* fact = m.get_fact(p); + for (unsigned i = 0; i < m_literals.size(); ++i) { + if (m.is_complement(m_literals[i], fact)) { + result = true; + break; + } + } + break; + } + default: + result = true; + for (unsigned i = 0; i < m.get_num_parents(p); ++i) { + if (!check(m.get_parent(p, i))) { + result = false; + break; + } + } + break; + } + + return result; + } + +public: + proof_is_closed(ast_manager& m): m(m) {} + + bool operator()(proof *p) { + bool ok = check(p); + reset(); + return ok; + } +}; + +bool proof_utils::is_closed(ast_manager& m, proof* p) { + proof_is_closed checker(m); + return checker(p); +} + + +static void permute_unit_resolution(expr_ref_vector& refs, obj_map& cache, proof_ref& pr) { + ast_manager& m = pr.get_manager(); + proof* pr2 = 0; + proof_ref_vector parents(m); + proof_ref prNew(pr); + if (cache.find(pr, pr2)) { + pr = pr2; + return; + } + + for (unsigned i = 0; i < m.get_num_parents(pr); ++i) { + prNew = m.get_parent(pr, i); + permute_unit_resolution(refs, cache, prNew); + parents.push_back(prNew); + } + + prNew = pr; + if (pr->get_decl_kind() == PR_UNIT_RESOLUTION && + parents[0]->get_decl_kind() == PR_TH_LEMMA) { + /* + Unit resolution: + T1: (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') + Th lemma: + T1: (not l_1) + ... + Tn: (not l_n) + [th-lemma T1 ... Tn]: (or l_{n+1} ... l_m) + + Such that (or l_1 .. l_n l_{n+1} .. l_m) is a theory axiom. + + Implement conversion: + + T1 |- not l_1 ... Tn |- not l_n + ------------------------------- TH_LEMMA + (or k_1 .. k_m j_1 ... j_m) S1 |- not k_1 ... Sm |- not k_m + -------------------------------------------------------------- UNIT_RESOLUTION + (or j_1 .. j_m) + + + |-> + + T1 |- not l_1 ... Tn |- not l_n S1 |- not k_1 ... Sm |- not k_m + ---------------------------------------------------------------- TH_LEMMA + (or j_1 .. j_m) + + */ + proof_ref_vector premises(m); + proof* thLemma = parents[0].get(); + for (unsigned i = 0; i < m.get_num_parents(thLemma); ++i) { + premises.push_back(m.get_parent(thLemma, i)); + } + for (unsigned i = 1; i < parents.size(); ++i) { + premises.push_back(parents[i].get()); + } + parameter const* params = thLemma->get_decl()->get_parameters(); + unsigned num_params = thLemma->get_decl()->get_num_parameters(); + SASSERT(params[0].is_symbol()); + family_id tid = m.mk_family_id(params[0].get_symbol()); + SASSERT(tid != null_family_id); + // AG: This can break a theory lemma. In particular, for Farkas lemmas the coefficients + // AG: for the literals propagated from the unit resolution are missing. + // AG: Why is this a good thing to do? + // AG: This can lead to merging of the units with other terms in interpolation, + // AG: but without farkas coefficients this does not make sense + prNew = m.mk_th_lemma(tid, m.get_fact(pr), + premises.size(), premises.c_ptr(), num_params-1, params+1); + } + else { + ptr_vector args; + for (unsigned i = 0; i < parents.size(); ++i) { + args.push_back(parents[i].get()); + } + if (m.has_fact(pr)) { + args.push_back(m.get_fact(pr)); + } + prNew = m.mk_app(pr->get_decl(), args.size(), args.c_ptr()); + } + + cache.insert(pr, prNew); + refs.push_back(prNew); + pr = prNew; +} + + +// permute unit resolution over Theory lemmas to track premises. +void proof_utils::permute_unit_resolution(proof_ref& pr) { + expr_ref_vector refs(pr.get_manager()); + obj_map cache; + ::permute_unit_resolution(refs, cache, pr); +} + +class push_instantiations_up_cl { + ast_manager& m; +public: + push_instantiations_up_cl(ast_manager& m): m(m) {} + + void operator()(proof_ref& p) { + expr_ref_vector s0(m); + p = push(p, s0); + } + +private: + + proof* push(proof* p, expr_ref_vector const& sub) { + proof_ref_vector premises(m); + expr_ref conclusion(m); + svector > positions; + vector substs; + + if (m.is_hyper_resolve(p, premises, conclusion, positions, substs)) { + for (unsigned i = 0; i < premises.size(); ++i) { + compose(substs[i], sub); + premises[i] = push(premises[i].get(), substs[i]); + substs[i].reset(); + } + instantiate(sub, conclusion); + return + m.mk_hyper_resolve(premises.size(), premises.c_ptr(), conclusion, + positions, + substs); + } + if (sub.empty()) { + return p; + } + if (m.is_modus_ponens(p)) { + SASSERT(m.get_num_parents(p) == 2); + proof* p0 = m.get_parent(p, 0); + proof* p1 = m.get_parent(p, 1); + if (m.get_fact(p0) == m.get_fact(p)) { + return push(p0, sub); + } + expr* e1, *e2; + if (m.is_rewrite(p1, e1, e2) && + is_quantifier(e1) && is_quantifier(e2) && + to_quantifier(e1)->get_num_decls() == to_quantifier(e2)->get_num_decls()) { + expr_ref r1(e1,m), r2(e2,m); + instantiate(sub, r1); + instantiate(sub, r2); + p1 = m.mk_rewrite(r1, r2); + return m.mk_modus_ponens(push(p0, sub), p1); + } + } + premises.push_back(p); + substs.push_back(sub); + conclusion = m.get_fact(p); + instantiate(sub, conclusion); + return m.mk_hyper_resolve(premises.size(), premises.c_ptr(), conclusion, positions, substs); + } + + void compose(expr_ref_vector& sub, expr_ref_vector const& s0) { + for (unsigned i = 0; i < sub.size(); ++i) { + expr_ref e(m); + var_subst(m, false)(sub[i].get(), s0.size(), s0.c_ptr(), e); + sub[i] = e; + } + } + + void instantiate(expr_ref_vector const& sub, expr_ref& fml) { + if (sub.empty()) { + return; + } + if (!is_forall(fml)) { + return; + } + quantifier* q = to_quantifier(fml); + if (q->get_num_decls() != sub.size()) { + TRACE("proof_utils", tout << "quantifier has different number of variables than substitution"; + tout << mk_pp(q, m) << "\n"; + tout << sub.size() << "\n";); + return; + } + var_subst(m, false)(q->get_expr(), sub.size(), sub.c_ptr(), fml); + } + +}; + +void proof_utils::push_instantiations_up(proof_ref& pr) { + push_instantiations_up_cl push(pr.get_manager()); + push(pr); +} + + diff --git a/src/ast/proofs/proof_utils.h b/src/ast/proofs/proof_utils.h index 7963d52de..f813b96ad 100644 --- a/src/ast/proofs/proof_utils.h +++ b/src/ast/proofs/proof_utils.h @@ -16,8 +16,8 @@ Revision History: --*/ -#ifndef _PROOF_UTILS_H_ -#define _PROOF_UTILS_H_ +#ifndef PROOF_UTILS_H_ +#define PROOF_UTILS_H_ #include "ast/ast.h" /* @@ -39,4 +39,31 @@ private: void reduce_hypotheses(proof_ref &pr); +class proof_utils { +public: + /** + \brief reduce the set of hypotheses used in the proof. + */ + static void reduce_hypotheses(proof_ref& pr); + + /** + \brief Check that a proof does not contain open hypotheses. + */ + static bool is_closed(ast_manager& m, proof* p); + + /** + \brief Permute unit resolution rule with th-lemma + */ + static void permute_unit_resolution(proof_ref& pr); + + /** + \brief Push instantiations created in hyper-resolutions up to leaves. + This produces a "ground" proof where leaves are annotated by instantiations. + */ + static void push_instantiations_up(proof_ref& pr); + + +}; + + #endif diff --git a/src/muz/base/CMakeLists.txt b/src/muz/base/CMakeLists.txt index ec1ce47c3..6b0334664 100644 --- a/src/muz/base/CMakeLists.txt +++ b/src/muz/base/CMakeLists.txt @@ -10,7 +10,6 @@ z3_add_component(muz dl_rule_transformer.cpp dl_util.cpp hnf.cpp - proof_utils.cpp rule_properties.cpp COMPONENT_DEPENDENCIES aig_tactic diff --git a/src/muz/base/dl_boogie_proof.cpp b/src/muz/base/dl_boogie_proof.cpp index ec999c05e..8f4f9c02d 100644 --- a/src/muz/base/dl_boogie_proof.cpp +++ b/src/muz/base/dl_boogie_proof.cpp @@ -53,7 +53,7 @@ Example from Boogie: #include "muz/base/dl_boogie_proof.h" #include "model/model_pp.h" -#include "muz/base/proof_utils.h" +#include "ast/proofs/proof_utils.h" #include "ast/ast_pp.h" #include "ast/ast_util.h" diff --git a/src/muz/base/dl_util.h b/src/muz/base/dl_util.h index d04e4037c..c560ee28e 100644 --- a/src/muz/base/dl_util.h +++ b/src/muz/base/dl_util.h @@ -11,7 +11,7 @@ Abstract: Author: - Leonardo de Moura (leonardo) 2010-05-20. + Krystof Hoder 2010 Revision History: @@ -31,6 +31,7 @@ Revision History: #include "util/statistics.h" #include "util/stopwatch.h" #include "util/lbool.h" +#include "util/container_util.h" namespace datalog { @@ -381,129 +382,6 @@ namespace datalog { */ void apply_subst(expr_ref_vector& tgt, expr_ref_vector const& sub); - // ----------------------------------- - // - // container functions - // - // ----------------------------------- - - template - void set_intersection(Set1 & tgt, const Set2 & src) { - svector to_remove; - typename Set1::iterator vit = tgt.begin(); - typename Set1::iterator vend = tgt.end(); - for(;vit!=vend;++vit) { - typename Set1::data itm=*vit; - if(!src.contains(itm)) { - to_remove.push_back(itm); - } - } - while(!to_remove.empty()) { - tgt.remove(to_remove.back()); - to_remove.pop_back(); - } - } - - template - void set_difference(Set & tgt, const Set & to_remove) { - typename Set::iterator vit = to_remove.begin(); - typename Set::iterator vend = to_remove.end(); - for(;vit!=vend;++vit) { - typename Set::data itm=*vit; - tgt.remove(itm); - } - } - - template - void set_union(Set1 & tgt, const Set2 & to_add) { - typename Set2::iterator vit = to_add.begin(); - typename Set2::iterator vend = to_add.end(); - for(;vit!=vend;++vit) { - typename Set1::data itm=*vit; - tgt.insert(itm); - } - } - - void idx_set_union(idx_set & tgt, const idx_set & src); - - template - void unite_disjoint_maps(T & tgt, const T & src) { - typename T::iterator it = src.begin(); - typename T::iterator end = src.end(); - for(; it!=end; ++it) { - SASSERT(!tgt.contains(it->m_key)); - tgt.insert(it->m_key, it->m_value); - } - } - - template - void collect_map_range(T & acc, const U & map) { - typename U::iterator it = map.begin(); - typename U::iterator end = map.end(); - for(; it!=end; ++it) { - acc.push_back(it->m_value); - } - } - - - template - void print_container(const T & begin, const T & end, std::ostream & out) { - T it = begin; - out << "("; - bool first = true; - for(; it!=end; ++it) { - if(first) { first = false; } else { out << ","; } - out << (*it); - } - out << ")"; - } - - template - void print_container(const T & cont, std::ostream & out) { - print_container(cont.begin(), cont.end(), out); - } - - template - void print_container(const ref_vector & cont, std::ostream & out) { - print_container(cont.c_ptr(), cont.c_ptr() + cont.size(), out); - } - - template - void print_map(const T & cont, std::ostream & out) { - typename T::iterator it = cont.begin(); - typename T::iterator end = cont.end(); - out << "("; - bool first = true; - for(; it!=end; ++it) { - if(first) { first = false; } else { out << ","; } - out << it->m_key << "->" << it->m_value; - } - out << ")"; - } - - template - unsigned find_index(const It & begin, const It & end, const V & val) { - unsigned idx = 0; - It it = begin; - for(; it!=end; it++, idx++) { - if(*it==val) { - return idx; - } - } - return UINT_MAX; - } - - template - bool containers_equal(const T & begin1, const T & end1, const U & begin2, const U & end2) { - T it1 = begin1; - U it2 = begin2; - for(; it1!=end1 && it2!=end2; ++it1, ++it2) { - if(*it1!=*it2) { - return false; - } - } - return it1==end1 && it2==end2; - } template bool vectors_equal(const T & c1, const U & c2) { @@ -521,6 +399,8 @@ namespace datalog { return true; } + void idx_set_union(idx_set & tgt, const idx_set & src); + template struct default_obj_chash { unsigned operator()(T const& cont, unsigned i) const { diff --git a/src/muz/base/proof_utils.cpp b/src/muz/base/proof_utils.cpp deleted file mode 100644 index 87355a07b..000000000 --- a/src/muz/base/proof_utils.cpp +++ /dev/null @@ -1,680 +0,0 @@ - -/*++ -Copyright (c) 2015 Microsoft Corporation - ---*/ - -#include "muz/base/dl_util.h" -#include "muz/base/proof_utils.h" -#include "ast/ast_smt2_pp.h" -#include "ast/rewriter/var_subst.h" - -class reduce_hypotheses0 { - typedef obj_hashtable expr_set; - ast_manager& m; - // reference for any expression created by the tranformation - expr_ref_vector m_refs; - // currently computed result - obj_map m_cache; - // map conclusions to closed proofs that derive them - obj_map m_units; - // currently active units - ptr_vector m_units_trail; - // size of m_units_trail at the last push - unsigned_vector m_limits; - // map from proofs to active hypotheses - obj_map m_hypmap; - // refernce train for hypotheses sets - ptr_vector m_hyprefs; - ptr_vector m_literals; - - void reset() { - m_refs.reset(); - m_cache.reset(); - m_units.reset(); - m_units_trail.reset(); - m_limits.reset(); - std::for_each(m_hyprefs.begin(), m_hyprefs.end(), delete_proc()); - m_hypmap.reset(); - m_hyprefs.reset(); - m_literals.reset(); - } - - void push() { - m_limits.push_back(m_units_trail.size()); - } - - void pop() { - unsigned sz = m_limits.back(); - while (m_units_trail.size() > sz) { - m_units.remove(m_units_trail.back()); - m_units_trail.pop_back(); - } - m_limits.pop_back(); - } - - void get_literals(expr* clause) { - m_literals.reset(); - if (m.is_or(clause)) { - m_literals.append(to_app(clause)->get_num_args(), to_app(clause)->get_args()); - } - else { - m_literals.push_back(clause); - } - } - - void add_hypotheses(proof* p) { - expr_set* hyps = 0; - bool inherited = false; - if (p->get_decl_kind() == PR_HYPOTHESIS) { - hyps = alloc(expr_set); - hyps->insert(m.get_fact(p)); - m_hyprefs.push_back(hyps); - } - else { - for (unsigned i = 0; i < m.get_num_parents(p); ++i) { - expr_set* hyps1 = m_hypmap.find(m.get_parent(p, i)); - if (hyps1) { - if (!hyps) { - hyps = hyps1; - inherited = true; - continue; - } - if (inherited) { - hyps = alloc(expr_set,*hyps); - m_hyprefs.push_back(hyps); - inherited = false; - } - datalog::set_union(*hyps, *hyps1); - } - } - } - m_hypmap.insert(p, hyps); - } - - expr_ref complement_lit(expr* e) { - expr* e1; - if (m.is_not(e, e1)) { - return expr_ref(e1, m); - } - else { - return expr_ref(m.mk_not(e), m); - } - } - - bool in_hypotheses(expr* e, expr_set* hyps) { - if (!hyps) { - return false; - } - expr_ref not_e = complement_lit(e); - return hyps->contains(not_e); - } - - bool contains_hypothesis(proof* p) { - ptr_vector todo; - ast_mark visit; - todo.push_back(p); - while (!todo.empty()) { - p = todo.back(); - todo.pop_back(); - if (visit.is_marked(p)) { - continue; - } - visit.mark(p, true); - if (PR_HYPOTHESIS == p->get_decl_kind()) { - return true; - } - for (unsigned i = 0; i < m.get_num_parents(p); ++i) { - todo.push_back(m.get_parent(p, i)); - } - } - return false; - } - - bool is_closed(proof* p) { - expr_set* hyps = m_hypmap.find(p); - return !hyps || hyps->empty(); - } - -public: - reduce_hypotheses0(ast_manager& m): m(m), m_refs(m) {} - - void operator()(proof_ref& pr) { - proof_ref tmp(m); - tmp = pr; - elim(pr); - reset(); - CTRACE("proof_utils", contains_hypothesis(pr), - tout << "Contains hypothesis:\n"; - tout << mk_ismt2_pp(tmp, m) << "\n====>\n"; - tout << mk_ismt2_pp(pr, m) << "\n";); - - } - - void elim(proof_ref& p) { - proof_ref tmp(m); - proof* result = p.get(); - if (m_cache.find(p, result)) { - p = result; - return; - } - //SASSERT (p.get () == result); - switch(p->get_decl_kind()) { - case PR_HYPOTHESIS: - // replace result by m_units[m.get_fact (p)] if defined - // AG: This is the main step. Replace a hypothesis by a derivation of its consequence - if (!m_units.find(m.get_fact(p), result)) { - // restore ther result back to p - result = p.get(); - } - // compute hypothesis of the result - // not clear what 'result' is at this point. - // probably the proof at the top of the call - // XXX not clear why this is re-computed each time - // XXX moreover, m_units are guaranteed to be closed! - // XXX so no hypotheses are needed for them - add_hypotheses(result); - break; - case PR_LEMMA: { - SASSERT(m.get_num_parents(p) == 1); - tmp = m.get_parent(p, 0); - // eliminate hypothesis recursively in the proof of the lemma - elim(tmp); - expr_set* hyps = m_hypmap.find(tmp); - expr_set* new_hyps = 0; - // XXX if the proof is correct, the hypotheses of the tmp - // XXX should be exactly those of the consequence of the lemma - // XXX but if this code actually eliminates hypotheses, the set might be a subset - if (hyps) { - new_hyps = alloc(expr_set, *hyps); - } - expr* fact = m.get_fact(p); - // when hypothesis is a single literal of the form - // (or A B), and the fact of p is (or A B). - if (hyps && hyps->size() == 1 && in_hypotheses(fact, hyps)) { - m_literals.reset(); - m_literals.push_back(fact); - } - else { - get_literals(fact); - } - - // go over all the literals in the consequence of the lemma - for (unsigned i = 0; i < m_literals.size(); ++i) { - expr* e = m_literals[i]; - // if the literal is not in hypothesis, skip it - if (!in_hypotheses(e, hyps)) { - m_literals[i] = m_literals.back(); - m_literals.pop_back(); - --i; - } - // if the literal is in hypothesis remove it because - // it is not in hypothesis set of the lemma - // XXX but we assume that lemmas have empty hypothesis set. - // XXX eventually every element of new_hyps must be removed! - else { - SASSERT(new_hyps); - expr_ref not_e = complement_lit(e); - SASSERT(new_hyps->contains(not_e)); - new_hyps->remove(not_e); - } - } - // killed all hypotheses, so can stop at the lemma since - // we have a closed pf of false - if (m_literals.empty()) { - result = tmp; - } - else { - // create a new lemma, but might be re-creating existing one - expr_ref clause(m); - if (m_literals.size() == 1) { - clause = m_literals[0]; - } - else { - clause = m.mk_or(m_literals.size(), m_literals.c_ptr()); - } - tmp = m.mk_lemma(tmp, clause); - m_refs.push_back(tmp); - result = tmp; - } - if (new_hyps && new_hyps->empty()) { - dealloc(new_hyps); - new_hyps = 0; - } - m_hypmap.insert(result, new_hyps); - // might push 0 into m_hyprefs. No reason for that - m_hyprefs.push_back(new_hyps); - TRACE("proof_utils", - tout << "New lemma: " << mk_pp(m.get_fact(p), m) - << "\n==>\n" - << mk_pp(m.get_fact(result), m) << "\n"; - if (hyps) { - expr_set::iterator it = hyps->begin(); - expr_set::iterator end = hyps->end(); - for (; it != end; ++it) { - tout << "Hypothesis: " << mk_pp(*it, m) << "\n"; - } - }); - - break; - } - case PR_UNIT_RESOLUTION: { - proof_ref_vector parents(m); - // get the clause being resolved with - parents.push_back(m.get_parent(p, 0)); - // save state - push(); - bool found_false = false; - // for every derivation of a unit literal - for (unsigned i = 1; i < m.get_num_parents(p); ++i) { - // see if it derives false - tmp = m.get_parent(p, i); - elim(tmp); - if (m.is_false(m.get_fact(tmp))) { - // if derived false, the whole pf is false and we can bail out - result = tmp; - found_false = true; - break; - } - // -- otherwise, the fact has not changed. nothing to simplify - SASSERT(m.get_fact(tmp) == m.get_fact(m.get_parent(p, i))); - parents.push_back(tmp); - // remember that we have this derivation while we have not poped the trail - // but only if the proof is closed (i.e., a real unit) - if (is_closed(tmp) && !m_units.contains(m.get_fact(tmp))) { - m_units.insert(m.get_fact(tmp), tmp); - m_units_trail.push_back(m.get_fact(tmp)); - } - } - if (found_false) { - pop(); - break; - } - // look at the clause being resolved with - tmp = m.get_parent(p, 0); - // remember its fact - expr* old_clause = m.get_fact(tmp); - // attempt to reduce its fact - elim(tmp); - // update parents - parents[0] = tmp; - // if the new fact is false, bail out - expr* clause = m.get_fact(tmp); - if (m.is_false(clause)) { - m_refs.push_back(tmp); - result = tmp; - pop(); - break; - } - // - // case where clause is a literal in the old clause. - // i.e., reduce multi-literal clause to a unit - // - if (is_literal_in_clause(clause, old_clause)) { - // if the resulting literal was resolved, get a pf of false and bail out - bool found = false; - for (unsigned i = 1; !found && i < parents.size(); ++i) { - if (m.is_complement(clause, m.get_fact(parents[i].get()))) { - parents[1] = parents[i].get(); - parents.resize(2); - result = m.mk_unit_resolution(parents.size(), parents.c_ptr()); - m_refs.push_back(result); - add_hypotheses(result); - found = true; - } - } - // else if the resulting literal is not resolved, it is the new consequence - if (!found) { - result = parents[0].get(); - } - pop(); - break; - } - // - // case where new clause is a subset of old clause. - // the literals in clause should be a subset of literals in old_clause. - // - get_literals(clause); - for (unsigned i = 1; i < parents.size(); ++i) { - bool found = false; - for (unsigned j = 0; j < m_literals.size(); ++j) { - if (m.is_complement(m_literals[j], m.get_fact(parents[i].get()))) { - found = true; - break; - } - } - if (!found) { - // literal was removed as hypothesis. - parents[i] = parents.back(); - parents.pop_back(); - --i; - } - } - if (parents.size() == 1) { - result = parents[0].get(); - } - else { - result = m.mk_unit_resolution(parents.size(), parents.c_ptr()); - m_refs.push_back(result); - add_hypotheses(result); - } - pop(); - break; - } - default: { - ptr_buffer args; - bool change = false; - bool found_false = false; - for (unsigned i = 0; i < m.get_num_parents(p); ++i) { - tmp = m.get_parent(p, i); - elim(tmp); - if (m.is_false(m.get_fact(tmp))) { - result = tmp; - found_false = true; - break; - } - // SASSERT(m.get_fact(tmp) == m.get_fact(m.get_parent(p, i))); - change = change || (tmp != m.get_parent(p, i)); - args.push_back(tmp); - } - if (found_false) { - break; - } - if (m.has_fact(p)) { - args.push_back(m.get_fact(p)); - } - if (change) { - tmp = m.mk_app(p->get_decl(), args.size(), args.c_ptr()); - m_refs.push_back(tmp); - } - else { - tmp = p; - } - result = tmp; - add_hypotheses(result); - break; - } - } - SASSERT(m_hypmap.contains(result)); - m_cache.insert(p, result); - p = result; - } - - bool is_literal_in_clause(expr* fml, expr* clause) { - if (!m.is_or(clause)) { - return false; - } - app* cl = to_app(clause); - for (unsigned i = 0; i < cl->get_num_args(); ++i) { - if (cl->get_arg(i) == fml) { - return true; - } - } - return false; - } -}; - -void proof_utils::reduce_hypotheses(proof_ref& pr) { - ast_manager& m = pr.get_manager(); - class reduce_hypotheses0 reduce(m); - reduce(pr); - CTRACE("proof_utils", !is_closed(m, pr), tout << mk_pp(pr, m) << "\n";); -} - -class proof_is_closed { - ast_manager& m; - ptr_vector m_literals; - ast_mark m_visit; - - void reset() { - m_literals.reset(); - m_visit.reset(); - } - - bool check(proof* p) { - // really just a partial check because nodes may be visited - // already under a different lemma scope. - if (m_visit.is_marked(p)) { - return true; - } - bool result = false; - m_visit.mark(p, true); - switch(p->get_decl_kind()) { - case PR_LEMMA: { - unsigned sz = m_literals.size(); - expr* cls = m.get_fact(p); - m_literals.push_back(cls); - if (m.is_or(cls)) { - m_literals.append(to_app(cls)->get_num_args(), to_app(cls)->get_args()); - } - SASSERT(m.get_num_parents(p) == 1); - result = check(m.get_parent(p, 0)); - m_literals.resize(sz); - break; - } - case PR_HYPOTHESIS: { - expr* fact = m.get_fact(p); - for (unsigned i = 0; i < m_literals.size(); ++i) { - if (m.is_complement(m_literals[i], fact)) { - result = true; - break; - } - } - break; - } - default: - result = true; - for (unsigned i = 0; i < m.get_num_parents(p); ++i) { - if (!check(m.get_parent(p, i))) { - result = false; - break; - } - } - break; - } - - return result; - } - -public: - proof_is_closed(ast_manager& m): m(m) {} - - bool operator()(proof *p) { - bool ok = check(p); - reset(); - return ok; - } -}; - -bool proof_utils::is_closed(ast_manager& m, proof* p) { - proof_is_closed checker(m); - return checker(p); -} - - -static void permute_unit_resolution(expr_ref_vector& refs, obj_map& cache, proof_ref& pr) { - ast_manager& m = pr.get_manager(); - proof* pr2 = 0; - proof_ref_vector parents(m); - proof_ref prNew(pr); - if (cache.find(pr, pr2)) { - pr = pr2; - return; - } - - for (unsigned i = 0; i < m.get_num_parents(pr); ++i) { - prNew = m.get_parent(pr, i); - permute_unit_resolution(refs, cache, prNew); - parents.push_back(prNew); - } - - prNew = pr; - if (pr->get_decl_kind() == PR_UNIT_RESOLUTION && - parents[0]->get_decl_kind() == PR_TH_LEMMA) { - /* - Unit resolution: - T1: (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') - Th lemma: - T1: (not l_1) - ... - Tn: (not l_n) - [th-lemma T1 ... Tn]: (or l_{n+1} ... l_m) - - Such that (or l_1 .. l_n l_{n+1} .. l_m) is a theory axiom. - - Implement conversion: - - T1 |- not l_1 ... Tn |- not l_n - ------------------------------- TH_LEMMA - (or k_1 .. k_m j_1 ... j_m) S1 |- not k_1 ... Sm |- not k_m - -------------------------------------------------------------- UNIT_RESOLUTION - (or j_1 .. j_m) - - - |-> - - T1 |- not l_1 ... Tn |- not l_n S1 |- not k_1 ... Sm |- not k_m - ---------------------------------------------------------------- TH_LEMMA - (or j_1 .. j_m) - - */ - proof_ref_vector premises(m); - proof* thLemma = parents[0].get(); - for (unsigned i = 0; i < m.get_num_parents(thLemma); ++i) { - premises.push_back(m.get_parent(thLemma, i)); - } - for (unsigned i = 1; i < parents.size(); ++i) { - premises.push_back(parents[i].get()); - } - parameter const* params = thLemma->get_decl()->get_parameters(); - unsigned num_params = thLemma->get_decl()->get_num_parameters(); - SASSERT(params[0].is_symbol()); - family_id tid = m.mk_family_id(params[0].get_symbol()); - SASSERT(tid != null_family_id); - // AG: This can break a theory lemma. In particular, for Farkas lemmas the coefficients - // AG: for the literals propagated from the unit resolution are missing. - // AG: Why is this a good thing to do? - // AG: This can lead to merging of the units with other terms in interpolation, - // AG: but without farkas coefficients this does not make sense - prNew = m.mk_th_lemma(tid, m.get_fact(pr), - premises.size(), premises.c_ptr(), num_params-1, params+1); - } - else { - ptr_vector args; - for (unsigned i = 0; i < parents.size(); ++i) { - args.push_back(parents[i].get()); - } - if (m.has_fact(pr)) { - args.push_back(m.get_fact(pr)); - } - prNew = m.mk_app(pr->get_decl(), args.size(), args.c_ptr()); - } - - cache.insert(pr, prNew); - refs.push_back(prNew); - pr = prNew; -} - - -// permute unit resolution over Theory lemmas to track premises. -void proof_utils::permute_unit_resolution(proof_ref& pr) { - expr_ref_vector refs(pr.get_manager()); - obj_map cache; - ::permute_unit_resolution(refs, cache, pr); -} - -class push_instantiations_up_cl { - ast_manager& m; -public: - push_instantiations_up_cl(ast_manager& m): m(m) {} - - void operator()(proof_ref& p) { - expr_ref_vector s0(m); - p = push(p, s0); - } - -private: - - proof* push(proof* p, expr_ref_vector const& sub) { - proof_ref_vector premises(m); - expr_ref conclusion(m); - svector > positions; - vector substs; - - if (m.is_hyper_resolve(p, premises, conclusion, positions, substs)) { - for (unsigned i = 0; i < premises.size(); ++i) { - compose(substs[i], sub); - premises[i] = push(premises[i].get(), substs[i]); - substs[i].reset(); - } - instantiate(sub, conclusion); - return - m.mk_hyper_resolve(premises.size(), premises.c_ptr(), conclusion, - positions, - substs); - } - if (sub.empty()) { - return p; - } - if (m.is_modus_ponens(p)) { - SASSERT(m.get_num_parents(p) == 2); - proof* p0 = m.get_parent(p, 0); - proof* p1 = m.get_parent(p, 1); - if (m.get_fact(p0) == m.get_fact(p)) { - return push(p0, sub); - } - expr* e1, *e2; - if (m.is_rewrite(p1, e1, e2) && - is_quantifier(e1) && is_quantifier(e2) && - to_quantifier(e1)->get_num_decls() == to_quantifier(e2)->get_num_decls()) { - expr_ref r1(e1,m), r2(e2,m); - instantiate(sub, r1); - instantiate(sub, r2); - p1 = m.mk_rewrite(r1, r2); - return m.mk_modus_ponens(push(p0, sub), p1); - } - } - premises.push_back(p); - substs.push_back(sub); - conclusion = m.get_fact(p); - instantiate(sub, conclusion); - return m.mk_hyper_resolve(premises.size(), premises.c_ptr(), conclusion, positions, substs); - } - - void compose(expr_ref_vector& sub, expr_ref_vector const& s0) { - for (unsigned i = 0; i < sub.size(); ++i) { - expr_ref e(m); - var_subst(m, false)(sub[i].get(), s0.size(), s0.c_ptr(), e); - sub[i] = e; - } - } - - void instantiate(expr_ref_vector const& sub, expr_ref& fml) { - if (sub.empty()) { - return; - } - if (!is_forall(fml)) { - return; - } - quantifier* q = to_quantifier(fml); - if (q->get_num_decls() != sub.size()) { - TRACE("proof_utils", tout << "quantifier has different number of variables than substitution"; - tout << mk_pp(q, m) << "\n"; - tout << sub.size() << "\n";); - return; - } - var_subst(m, false)(q->get_expr(), sub.size(), sub.c_ptr(), fml); - } - -}; - -void proof_utils::push_instantiations_up(proof_ref& pr) { - push_instantiations_up_cl push(pr.get_manager()); - push(pr); -} - - diff --git a/src/muz/base/proof_utils.h b/src/muz/base/proof_utils.h deleted file mode 100644 index 0db831c4f..000000000 --- a/src/muz/base/proof_utils.h +++ /dev/null @@ -1,48 +0,0 @@ -/*++ -Copyright (c) 2012 Microsoft Corporation - -Module Name: - - proof_utils.h - -Abstract: - - Utilities for transforming proofs. - -Author: - - Nikolaj Bjorner (nbjorner) 2012-10-12. - -Revision History: - ---*/ -#ifndef PROOF_UTILS_H_ -#define PROOF_UTILS_H_ - -class proof_utils { -public: - /** - \brief reduce the set of hypotheses used in the proof. - */ - static void reduce_hypotheses(proof_ref& pr); - - /** - \brief Check that a proof does not contain open hypotheses. - */ - static bool is_closed(ast_manager& m, proof* p); - - /** - \brief Permute unit resolution rule with th-lemma - */ - static void permute_unit_resolution(proof_ref& pr); - - /** - \brief Push instantiations created in hyper-resolutions up to leaves. - This produces a "ground" proof where leaves are annotated by instantiations. - */ - static void push_instantiations_up(proof_ref& pr); - - -}; - -#endif diff --git a/src/muz/pdr/pdr_context.cpp b/src/muz/pdr/pdr_context.cpp index a1878dc7a..37d80e2d6 100644 --- a/src/muz/pdr/pdr_context.cpp +++ b/src/muz/pdr/pdr_context.cpp @@ -43,7 +43,6 @@ Notes: #include "ast/ast_ll_pp.h" #include "ast/proofs/proof_checker.h" #include "smt/smt_value_sort.h" -#include "muz/base/proof_utils.h" #include "muz/base/dl_boogie_proof.h" #include "ast/scoped_proof.h" #include "tactic/core/blast_term_ite_tactic.h" diff --git a/src/muz/pdr/pdr_farkas_learner.cpp b/src/muz/pdr/pdr_farkas_learner.cpp index 4f47cb554..4a77d2f5f 100644 --- a/src/muz/pdr/pdr_farkas_learner.cpp +++ b/src/muz/pdr/pdr_farkas_learner.cpp @@ -31,7 +31,7 @@ Revision History: #include "ast/rewriter/th_rewriter.h" #include "ast/ast_ll_pp.h" #include "tactic/arith/arith_bounds_tactic.h" -#include "muz/base/proof_utils.h" +#include "ast/proofs/proof_utils.h" #include "ast/reg_decl_plugins.h" @@ -733,8 +733,8 @@ namespace pdr { } else { expr_set* hyps3 = alloc(expr_set); - datalog::set_union(*hyps3, *hyps); - datalog::set_union(*hyps3, *hyps2); + set_union(*hyps3, *hyps); + set_union(*hyps3, *hyps2); hyps = hyps3; hyprefs.push_back(hyps); } @@ -795,7 +795,7 @@ namespace pdr { case PR_LEMMA: { expr_set* hyps2 = alloc(expr_set); hyprefs.push_back(hyps2); - datalog::set_union(*hyps2, *hyps); + set_union(*hyps2, *hyps); hyps = hyps2; expr* fml = m.get_fact(p); hyps->remove(fml); diff --git a/src/muz/pdr/pdr_generalizers.cpp b/src/muz/pdr/pdr_generalizers.cpp index b17d3f8b6..094379a0b 100644 --- a/src/muz/pdr/pdr_generalizers.cpp +++ b/src/muz/pdr/pdr_generalizers.cpp @@ -81,7 +81,7 @@ namespace pdr { m_gen(n, core0, uses_level1); new_cores.push_back(std::make_pair(core0, uses_level1)); obj_hashtable core_exprs, core1_exprs; - datalog::set_union(core_exprs, core0); + set_union(core_exprs, core0); for (unsigned i = 0; i < old_core.size(); ++i) { expr* lit = old_core[i].get(); if (core_exprs.contains(lit)) { @@ -94,8 +94,8 @@ namespace pdr { if (core1.size() < old_core.size()) { new_cores.push_back(std::make_pair(core1, uses_level1)); core1_exprs.reset(); - datalog::set_union(core1_exprs, core1); - datalog::set_intersection(core_exprs, core1_exprs); + set_union(core1_exprs, core1); + set_intersection(core_exprs, core1_exprs); } } } diff --git a/src/muz/spacer/spacer_farkas_learner.cpp b/src/muz/spacer/spacer_farkas_learner.cpp index 47bc474ef..d97bee49f 100644 --- a/src/muz/spacer/spacer_farkas_learner.cpp +++ b/src/muz/spacer/spacer_farkas_learner.cpp @@ -31,7 +31,7 @@ Revision History: #include "muz/spacer/spacer_farkas_learner.h" #include "ast/rewriter/th_rewriter.h" #include "ast/ast_ll_pp.h" -#include "muz/base/proof_utils.h" +#include "ast/proofs/proof_utils.h" #include "ast/reg_decl_plugins.h" #include "smt/smt_farkas_util.h" @@ -231,8 +231,8 @@ void farkas_learner::get_lemmas(proof* root, expr_set const& bs, expr_ref_vector hyps = hyps2; } else { expr_set* hyps3 = alloc(expr_set); - datalog::set_union(*hyps3, *hyps); - datalog::set_union(*hyps3, *hyps2); + set_union(*hyps3, *hyps); + set_union(*hyps3, *hyps2); hyps = hyps3; hyprefs.push_back(hyps); } @@ -291,7 +291,7 @@ void farkas_learner::get_lemmas(proof* root, expr_set const& bs, expr_ref_vector case PR_LEMMA: { expr_set* hyps2 = alloc(expr_set); hyprefs.push_back(hyps2); - datalog::set_union(*hyps2, *hyps); + set_union(*hyps2, *hyps); hyps = hyps2; expr* fml = m.get_fact(p); hyps->remove(fml); diff --git a/src/muz/spacer/spacer_legacy_frames.cpp b/src/muz/spacer/spacer_legacy_frames.cpp index dd2a16abd..679736add 100644 --- a/src/muz/spacer/spacer_legacy_frames.cpp +++ b/src/muz/spacer/spacer_legacy_frames.cpp @@ -25,7 +25,7 @@ #include "ast/ast_util.h" #include "ast/proofs/proof_checker.h" #include "smt/smt_value_sort.h" -#include "muz/base/proof_utils.h" +#include "ast/proofs/proof_utils.h" #include "ast/scoped_proof.h" #include "muz/spacer/spacer_qe_project.h" #include "tactic/core/blast_term_ite_tactic.h" From db65cc007ad91bccb8815d0012be00c3b061290e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 10:27:48 -0700 Subject: [PATCH 468/488] move more proof utils Signed-off-by: Nikolaj Bjorner --- scripts/mk_project.py | 2 +- src/ast/proofs/proof_utils.h | 169 ++++++++++++++++++++++- src/muz/spacer/spacer_virtual_solver.cpp | 164 +--------------------- 3 files changed, 170 insertions(+), 165 deletions(-) diff --git a/scripts/mk_project.py b/scripts/mk_project.py index ddf439e10..6e7024b3f 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -43,7 +43,7 @@ def init_project_def(): add_lib('cmd_context', ['solver', 'rewriter', 'interp']) add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds') add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') - add_lib('proofs', ['rewriter'], 'ast/proofs') + add_lib('proofs', ['rewriter', 'util'], 'ast/proofs') add_lib('fpa', ['ast', 'util', 'rewriter', 'model'], 'ast/fpa') add_lib('pattern', ['normal_forms', 'smt2parser', 'rewriter'], 'ast/pattern') add_lib('bit_blaster', ['rewriter', 'rewriter'], 'ast/rewriter/bit_blaster') diff --git a/src/ast/proofs/proof_utils.h b/src/ast/proofs/proof_utils.h index f813b96ad..4152bca92 100644 --- a/src/ast/proofs/proof_utils.h +++ b/src/ast/proofs/proof_utils.h @@ -1,5 +1,5 @@ /*++ -Copyright (c) 2017 Arie Gurfinkel +Copyright (c) 2017 Microsoft Corporation Module Name: @@ -11,6 +11,7 @@ Abstract: Author: Bernhard Gleiss Arie Gurfinkel + Nikolaj Bjorner Revision History: @@ -65,5 +66,171 @@ public: }; +#include "ast/rewriter/bool_rewriter.h" +class elim_aux_assertions { + + static bool matches_fact(expr_ref_vector &args, expr* &match) { + ast_manager &m = args.get_manager(); + expr *fact = args.back(); + for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i) { + expr *arg = args.get(i); + if (m.is_proof(arg) && + m.has_fact(to_app(arg)) && + m.get_fact(to_app(arg)) == fact) { + match = arg; + return true; + } + } + return false; + } + + app_ref m_aux; +public: + elim_aux_assertions(app_ref aux) : m_aux(aux) {} + + void mk_or_core(expr_ref_vector &args, expr_ref &res) + { + ast_manager &m = args.get_manager(); + unsigned j = 0; + for (unsigned i = 0, sz = args.size(); i < sz; ++i) { + if (m.is_false(args.get(i))) { continue; } + if (i != j) { args [j] = args.get(i); } + ++j; + } + SASSERT(j >= 1); + res = j > 1 ? m.mk_or(j, args.c_ptr()) : args.get(0); + } + + void mk_app(func_decl *decl, expr_ref_vector &args, expr_ref &res) + { + ast_manager &m = args.get_manager(); + bool_rewriter brwr(m); + + if (m.is_or(decl)) + { mk_or_core(args, res); } + else if (m.is_iff(decl) && args.size() == 2) + // avoiding simplifying equalities. In particular, + // we don't want (= (not a) (not b)) to be reduced to (= a b) + { res = m.mk_iff(args.get(0), args.get(1)); } + else + { brwr.mk_app(decl, args.size(), args.c_ptr(), res); } + } + + void operator()(ast_manager &m, proof *pr, proof_ref &res) + { + DEBUG_CODE(proof_checker pc(m); + expr_ref_vector side(m); + SASSERT(pc.check(pr, side)); + ); + obj_map cache; + bool_rewriter brwr(m); + + // for reference counting of new proofs + app_ref_vector pinned(m); + + ptr_vector todo; + todo.push_back(pr); + + expr_ref not_aux(m); + not_aux = m.mk_not(m_aux); + + expr_ref_vector args(m); + + while (!todo.empty()) { + app *p, *r; + expr *a; + + p = todo.back(); + if (cache.find(pr, r)) { + todo.pop_back(); + continue; + } + + SASSERT(!todo.empty() || pr == p); + bool dirty = false; + unsigned todo_sz = todo.size(); + args.reset(); + for (unsigned i = 0, sz = p->get_num_args(); i < sz; ++i) { + expr* arg = p->get_arg(i); + if (arg == m_aux.get()) { + dirty = true; + args.push_back(m.mk_true()); + } else if (arg == not_aux.get()) { + dirty = true; + args.push_back(m.mk_false()); + } + // skip (asserted m_aux) + else if (m.is_asserted(arg, a) && a == m_aux.get()) { + dirty = true; + } + // skip (hypothesis m_aux) + else if (m.is_hypothesis(arg, a) && a == m_aux.get()) { + dirty = true; + } else if (is_app(arg) && cache.find(to_app(arg), r)) { + dirty |= (arg != r); + args.push_back(r); + } else if (is_app(arg)) + { todo.push_back(to_app(arg)); } + else + // -- not an app + { args.push_back(arg); } + + } + if (todo_sz < todo.size()) { + // -- process parents + args.reset(); + continue; + } + + // ready to re-create + app_ref newp(m); + if (!dirty) { newp = p; } + else if (m.is_unit_resolution(p)) { + if (args.size() == 2) + // unit resolution with m_aux that got collapsed to nothing + { newp = to_app(args.get(0)); } + else { + ptr_vector parents; + for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i) + { parents.push_back(to_app(args.get(i))); } + SASSERT(parents.size() == args.size() - 1); + newp = m.mk_unit_resolution(parents.size(), parents.c_ptr()); + // XXX the old and new facts should be + // equivalent. The test here is much + // stronger. It might need to be relaxed. + SASSERT(m.get_fact(newp) == args.back()); + pinned.push_back(newp); + } + } else if (matches_fact(args, a)) { + newp = to_app(a); + } else { + expr_ref papp(m); + mk_app(p->get_decl(), args, papp); + newp = to_app(papp.get()); + pinned.push_back(newp); + } + cache.insert(p, newp); + todo.pop_back(); + CTRACE("virtual", + p->get_decl_kind() == PR_TH_LEMMA && + p->get_decl()->get_parameter(0).get_symbol() == "arith" && + p->get_decl()->get_num_parameters() > 1 && + p->get_decl()->get_parameter(1).get_symbol() == "farkas", + tout << "Old pf: " << mk_pp(p, m) << "\n" + << "New pf: " << mk_pp(newp, m) << "\n";); + } + + proof *r; + VERIFY(cache.find(pr, r)); + + DEBUG_CODE( + proof_checker pc(m); + expr_ref_vector side(m); + SASSERT(pc.check(r, side)); + ); + + res = r ; + } +}; #endif diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp index 87a21336c..891256eed 100644 --- a/src/muz/spacer/spacer_virtual_solver.cpp +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -24,6 +24,7 @@ Notes: #include "ast/rewriter/bool_rewriter.h" #include "ast/proofs/proof_checker.h" +#include "ast/proofs/proof_utils.h" #include "ast/scoped_proof.h" @@ -64,174 +65,11 @@ virtual_solver::~virtual_solver() } namespace { -static bool matches_fact(expr_ref_vector &args, expr* &match) -{ - ast_manager &m = args.get_manager(); - expr *fact = args.back(); - for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i) { - expr *arg = args.get(i); - if (m.is_proof(arg) && - m.has_fact(to_app(arg)) && - m.get_fact(to_app(arg)) == fact) { - match = arg; - return true; - } - } - return false; -} // TBD: move to ast/proofs/elim_aux_assertions -class elim_aux_assertions { - app_ref m_aux; -public: - elim_aux_assertions(app_ref aux) : m_aux(aux) {} - void mk_or_core(expr_ref_vector &args, expr_ref &res) - { - ast_manager &m = args.get_manager(); - unsigned j = 0; - for (unsigned i = 0, sz = args.size(); i < sz; ++i) { - if (m.is_false(args.get(i))) { continue; } - if (i != j) { args [j] = args.get(i); } - ++j; - } - SASSERT(j >= 1); - res = j > 1 ? m.mk_or(j, args.c_ptr()) : args.get(0); - } - - void mk_app(func_decl *decl, expr_ref_vector &args, expr_ref &res) - { - ast_manager &m = args.get_manager(); - bool_rewriter brwr(m); - - if (m.is_or(decl)) - { mk_or_core(args, res); } - else if (m.is_iff(decl) && args.size() == 2) - // avoiding simplifying equalities. In particular, - // we don't want (= (not a) (not b)) to be reduced to (= a b) - { res = m.mk_iff(args.get(0), args.get(1)); } - else - { brwr.mk_app(decl, args.size(), args.c_ptr(), res); } - } - - void operator()(ast_manager &m, proof *pr, proof_ref &res) - { - DEBUG_CODE(proof_checker pc(m); - expr_ref_vector side(m); - SASSERT(pc.check(pr, side)); - ); - obj_map cache; - bool_rewriter brwr(m); - - // for reference counting of new proofs - app_ref_vector pinned(m); - - ptr_vector todo; - todo.push_back(pr); - - expr_ref not_aux(m); - not_aux = m.mk_not(m_aux); - - expr_ref_vector args(m); - - while (!todo.empty()) { - app *p, *r; - expr *a; - - p = todo.back(); - if (cache.find(pr, r)) { - todo.pop_back(); - continue; - } - - SASSERT(!todo.empty() || pr == p); - bool dirty = false; - unsigned todo_sz = todo.size(); - args.reset(); - for (unsigned i = 0, sz = p->get_num_args(); i < sz; ++i) { - expr* arg = p->get_arg(i); - if (arg == m_aux.get()) { - dirty = true; - args.push_back(m.mk_true()); - } else if (arg == not_aux.get()) { - dirty = true; - args.push_back(m.mk_false()); - } - // skip (asserted m_aux) - else if (m.is_asserted(arg, a) && a == m_aux.get()) { - dirty = true; - } - // skip (hypothesis m_aux) - else if (m.is_hypothesis(arg, a) && a == m_aux.get()) { - dirty = true; - } else if (is_app(arg) && cache.find(to_app(arg), r)) { - dirty |= (arg != r); - args.push_back(r); - } else if (is_app(arg)) - { todo.push_back(to_app(arg)); } - else - // -- not an app - { args.push_back(arg); } - - } - if (todo_sz < todo.size()) { - // -- process parents - args.reset(); - continue; - } - - // ready to re-create - app_ref newp(m); - if (!dirty) { newp = p; } - else if (m.is_unit_resolution(p)) { - if (args.size() == 2) - // unit resolution with m_aux that got collapsed to nothing - { newp = to_app(args.get(0)); } - else { - ptr_vector parents; - for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i) - { parents.push_back(to_app(args.get(i))); } - SASSERT(parents.size() == args.size() - 1); - newp = m.mk_unit_resolution(parents.size(), parents.c_ptr()); - // XXX the old and new facts should be - // equivalent. The test here is much - // stronger. It might need to be relaxed. - SASSERT(m.get_fact(newp) == args.back()); - pinned.push_back(newp); - } - } else if (matches_fact(args, a)) { - newp = to_app(a); - } else { - expr_ref papp(m); - mk_app(p->get_decl(), args, papp); - newp = to_app(papp.get()); - pinned.push_back(newp); - } - cache.insert(p, newp); - todo.pop_back(); - CTRACE("virtual", - p->get_decl_kind() == PR_TH_LEMMA && - p->get_decl()->get_parameter(0).get_symbol() == "arith" && - p->get_decl()->get_num_parameters() > 1 && - p->get_decl()->get_parameter(1).get_symbol() == "farkas", - tout << "Old pf: " << mk_pp(p, m) << "\n" - << "New pf: " << mk_pp(newp, m) << "\n";); - } - - proof *r; - VERIFY(cache.find(pr, r)); - - DEBUG_CODE( - proof_checker pc(m); - expr_ref_vector side(m); - SASSERT(pc.check(r, side)); - ); - - res = r ; - } -}; } proof *virtual_solver::get_proof() From 48d144a6dda2d041811466694547f67b436f24c0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 12:51:47 -0700 Subject: [PATCH 469/488] missing file Signed-off-by: Nikolaj Bjorner --- src/ast/proofs/proof_utils.cpp | 3 +- src/ast/proofs/proof_utils.h | 2 +- src/muz/spacer/spacer_virtual_solver.cpp | 2 - src/muz/spacer/spacer_virtual_solver.h | 6 +- src/util/container_util.h | 121 +++++++++++++++++++++++ 5 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 src/util/container_util.h diff --git a/src/ast/proofs/proof_utils.cpp b/src/ast/proofs/proof_utils.cpp index b6c8b58d7..58500cb79 100644 --- a/src/ast/proofs/proof_utils.cpp +++ b/src/ast/proofs/proof_utils.cpp @@ -20,10 +20,10 @@ Revision History: #include "ast/ast_pp.h" #include "ast/proofs/proof_utils.h" #include "ast/proofs/proof_checker.h" +#include "ast/rewriter/var_subst.h" #include "util/container_util.h" - proof_post_order::proof_post_order(proof* root, ast_manager& manager) : m(manager) {m_todo.push_back(root);} @@ -336,7 +336,6 @@ void reduce_hypotheses(proof_ref &pr) { #include "ast/ast_smt2_pp.h" -#include "ast/rewriter/var_subst.h" class reduce_hypotheses0 { typedef obj_hashtable expr_set; diff --git a/src/ast/proofs/proof_utils.h b/src/ast/proofs/proof_utils.h index 4152bca92..9823acb92 100644 --- a/src/ast/proofs/proof_utils.h +++ b/src/ast/proofs/proof_utils.h @@ -20,6 +20,7 @@ Revision History: #ifndef PROOF_UTILS_H_ #define PROOF_UTILS_H_ #include "ast/ast.h" +#include "ast/rewriter/bool_rewriter.h" /* * iterator, which traverses the proof in depth-first post-order. @@ -66,7 +67,6 @@ public: }; -#include "ast/rewriter/bool_rewriter.h" class elim_aux_assertions { static bool matches_fact(expr_ref_vector &args, expr* &match) { diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp index 891256eed..89b9fb531 100644 --- a/src/muz/spacer/spacer_virtual_solver.cpp +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -244,7 +244,6 @@ void virtual_solver::refresh() m_head = 0; } -#ifdef NOT_USED_ANYWHERE void virtual_solver::reset() { SASSERT(!m_pushed); @@ -252,7 +251,6 @@ void virtual_solver::reset() m_assertions.reset(); m_factory.refresh(); } -#endif void virtual_solver::get_labels(svector &r) { diff --git a/src/muz/spacer/spacer_virtual_solver.h b/src/muz/spacer/spacer_virtual_solver.h index 3ccd89ef5..fed64c589 100644 --- a/src/muz/spacer/spacer_virtual_solver.h +++ b/src/muz/spacer/spacer_virtual_solver.h @@ -91,9 +91,7 @@ public: virtual void set_produce_models(bool f); virtual bool get_produce_models(); virtual smt_params &fparams(); -#ifdef NOT_USED_ANYWHERE virtual void reset(); -#endif virtual void set_progress_callback(progress_callback *callback) {UNREACHABLE();} @@ -135,6 +133,9 @@ private: void refresh(); + + smt_params &fparams() { return m_fparams; } + public: virtual_solver_factory(ast_manager &mgr, smt_params &fparams); virtual ~virtual_solver_factory(); @@ -145,7 +146,6 @@ public: void collect_param_descrs(param_descrs &r) { /* empty */ } void set_produce_models(bool f) { m_fparams.m_model = f; } bool get_produce_models() { return m_fparams.m_model; } - smt_params &fparams() { return m_fparams; } }; } diff --git a/src/util/container_util.h b/src/util/container_util.h new file mode 100644 index 000000000..7bbc3fb08 --- /dev/null +++ b/src/util/container_util.h @@ -0,0 +1,121 @@ +/*++ +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + container_util.h + +Abstract: + + Useful functions for containers + +Author: + + Krystof Hoder, Nikolaj Bjorner 2017-10-24 + +Revision History: + + Extracted from dl_util.h + +--*/ + +#ifndef CONTAINUR_UTIL_H +#define CONTAINER_UTIL_H_ + +// ----------------------------------- +// +// container functions +// +// ----------------------------------- + +template + void set_intersection(Set1 & tgt, const Set2 & src) { + svector to_remove; + for (Set1::data itm : tgt) + if (!src.contains(itm)) + to_remove.push_back(itm); + while (!to_remove.empty()) { + tgt.remove(to_remove.back()); + to_remove.pop_back(); + } +} + +template +void set_difference(Set & tgt, const Set & to_remove) { + for (auto const& itm : to_remove) + tgt.remove(itm); +} + +template +void set_union(Set1 & tgt, const Set2 & to_add) { + for (auto const& itm : to_add) + tgt.insert(itm); +} + +template +void unite_disjoint_maps(T & tgt, const T & src) { + for (auto const& kv : src) { + SASSERT(!tgt.contains(kv.m_key)); + tgt.insert(kv.m_key, kv.m_value); + } +} + +template +void collect_map_range(T & acc, const U & map) { + for (auto const& kv : map) + acc.push_back(kv.m_value); +} + + +template +void print_container(const T & begin, const T & end, std::ostream & out) { + T it = begin; + out << "("; + bool first = true; + for(; it!=end; ++it) { + if(first) { first = false; } else { out << ","; } + out << (*it); + } + out << ")"; +} + +template +void print_container(const T & cont, std::ostream & out) { + print_container(cont.begin(), cont.end(), out); +} + +template +void print_container(const ref_vector & cont, std::ostream & out) { + print_container(cont.c_ptr(), cont.c_ptr() + cont.size(), out); +} + +template +void print_map(const T & cont, std::ostream & out) { + out << "("; + bool first = true; + for (auto const& kv : cont) { + if (first) { first = false; } else { out << ","; } + out << kv.m_key << "->" << kv.m_value; + } + out << ")"; +} + +template +unsigned find_index(const It & begin, const It & end, const V & val) { + for (unsigned idx = 0, It it = begin; it != end; it++, idx++) { + if (*it == val) { + return idx; + } + } + return UINT_MAX; +} + +template +bool containers_equal(const T & begin1, const T & end1, const U & begin2, const U & end2) { + T it1 = begin1; + U it2 = begin2; + for (; it1 != end1 && it2 != end2 && *it1 == *it2; ++it1, ++it2) {}; + return it1 == end1 && it2 == end2; +} + +#endif From 6300a78b82e46e887666a2386a020acd1dfd8059 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 12:57:30 -0700 Subject: [PATCH 470/488] more build errors in debug mode Signed-off-by: Nikolaj Bjorner --- src/ast/proofs/proof_utils.h | 2 ++ src/cmd_context/cmd_context.cpp | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ast/proofs/proof_utils.h b/src/ast/proofs/proof_utils.h index 9823acb92..b953c834d 100644 --- a/src/ast/proofs/proof_utils.h +++ b/src/ast/proofs/proof_utils.h @@ -20,7 +20,9 @@ Revision History: #ifndef PROOF_UTILS_H_ #define PROOF_UTILS_H_ #include "ast/ast.h" +#include "ast/ast_pp.h" #include "ast/rewriter/bool_rewriter.h" +#include "ast/proofs/proof_checker.h" /* * iterator, which traverses the proof in depth-first post-order. diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 77dce80c8..f27d8e681 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1053,6 +1053,7 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg func_decls fs; if (!m_func_decls.find(s, fs)) { if (num_args == 0) { + //UNREACHABLE(); throw cmd_exception("unknown constant ", s); } else @@ -1063,16 +1064,20 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg if (fs.more_than_one()) throw cmd_exception("ambiguous constant reference, more than one constant with the same sort, use a qualified expression (as ) to disumbiguate ", s); func_decl * f = fs.first(); - if (f == 0) + if (f == 0) { + //UNREACHABLE(); throw cmd_exception("unknown constant ", s); + } if (f->get_arity() != 0) throw cmd_exception("invalid function application, missing arguments ", s); result = m().mk_const(f); } else { func_decl * f = fs.find(m(), num_args, args, range); - if (f == 0) + if (f == 0) { + //UNREACHABLE(); throw cmd_exception("unknown constant ", s); + } if (well_sorted_check_enabled()) m().check_sort(f, num_args, args); result = m().mk_app(f, num_args, args); From 31dfc0c610ed8a38acfde3e41c94213cddf59c21 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 13:20:19 -0700 Subject: [PATCH 471/488] fix build, fix #1322 Signed-off-by: Nikolaj Bjorner --- src/cmd_context/cmd_context.cpp | 18 ++++++++++++++---- src/util/container_util.h | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index f27d8e681..a1e7a4745 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -1053,7 +1053,6 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg func_decls fs; if (!m_func_decls.find(s, fs)) { if (num_args == 0) { - //UNREACHABLE(); throw cmd_exception("unknown constant ", s); } else @@ -1065,7 +1064,6 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg throw cmd_exception("ambiguous constant reference, more than one constant with the same sort, use a qualified expression (as ) to disumbiguate ", s); func_decl * f = fs.first(); if (f == 0) { - //UNREACHABLE(); throw cmd_exception("unknown constant ", s); } if (f->get_arity() != 0) @@ -1075,8 +1073,20 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg else { func_decl * f = fs.find(m(), num_args, args, range); if (f == 0) { - //UNREACHABLE(); - throw cmd_exception("unknown constant ", s); + std::ostringstream buffer; + buffer << "unknown constant " << s << " "; + buffer << " ("; + bool first = true; + for (unsigned i = 0; i < num_args; ++i, first = false) { + if (!first) buffer << " "; + buffer << mk_pp(m().get_sort(args[i]), m()); + } + buffer << ") "; + if (range) buffer << mk_pp(range, m()) << " "; + for (unsigned i = 0; i < fs.get_num_entries(); ++i) { + buffer << "\ndeclared: " << mk_pp(fs.get_entry(i), m()) << " "; + } + throw cmd_exception(buffer.str().c_str()); } if (well_sorted_check_enabled()) m().check_sort(f, num_args, args); diff --git a/src/util/container_util.h b/src/util/container_util.h index 7bbc3fb08..3b287ad51 100644 --- a/src/util/container_util.h +++ b/src/util/container_util.h @@ -31,7 +31,7 @@ Revision History: template void set_intersection(Set1 & tgt, const Set2 & src) { svector to_remove; - for (Set1::data itm : tgt) + for (auto const& itm : tgt) if (!src.contains(itm)) to_remove.push_back(itm); while (!to_remove.empty()) { From ee320fa0250c792a7c82baf0f50c25a2a2aa28ea Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 13:32:40 -0700 Subject: [PATCH 472/488] fix build errors Signed-off-by: Nikolaj Bjorner --- src/util/container_util.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/util/container_util.h b/src/util/container_util.h index 3b287ad51..f921b7b1d 100644 --- a/src/util/container_util.h +++ b/src/util/container_util.h @@ -19,7 +19,7 @@ Revision History: --*/ -#ifndef CONTAINUR_UTIL_H +#ifndef CONTAINUR_UTIL_H_ #define CONTAINER_UTIL_H_ // ----------------------------------- @@ -102,7 +102,8 @@ void print_map(const T & cont, std::ostream & out) { template unsigned find_index(const It & begin, const It & end, const V & val) { - for (unsigned idx = 0, It it = begin; it != end; it++, idx++) { + It it = begin; + for (unsigned idx = 0; it != end; it++, idx++) { if (*it == val) { return idx; } From 8acc924c21ee1eb65a14554636702bcad3170e81 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 24 Oct 2017 16:34:49 -0700 Subject: [PATCH 473/488] ifndef/define match Signed-off-by: Nikolaj Bjorner --- src/ast/rewriter/fpa_rewriter.cpp | 1 - src/util/container_util.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index ce14349b2..e62c9346f 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -119,7 +119,6 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const // BV -> float SASSERT(bvs1 == sbits + ebits); unsynch_mpz_manager & mpzm = m_fm.mpz_manager(); - unsynch_mpq_manager & mpqm = m_fm.mpq_manager(); scoped_mpz sig(mpzm), exp(mpzm); const mpz & sm1 = m_fm.m_powers2(sbits - 1); diff --git a/src/util/container_util.h b/src/util/container_util.h index f921b7b1d..e114c87b9 100644 --- a/src/util/container_util.h +++ b/src/util/container_util.h @@ -19,7 +19,7 @@ Revision History: --*/ -#ifndef CONTAINUR_UTIL_H_ +#ifndef CONTAINER_UTIL_H_ #define CONTAINER_UTIL_H_ // ----------------------------------- From 371f0b193c156e3221f41885a3c6ea0bfe26baeb Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 02:59:04 -0700 Subject: [PATCH 474/488] move min_cut, fix #1321 Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/CMakeLists.txt | 1 - src/muz/spacer/spacer_min_cut.cpp | 289 -------------------- src/muz/spacer/spacer_min_cut.h | 53 ---- src/muz/spacer/spacer_unsat_core_plugin.cpp | 8 +- src/muz/spacer/spacer_unsat_core_plugin.h | 4 +- src/smt/theory_str.cpp | 72 ++--- src/util/CMakeLists.txt | 1 + src/util/min_cut.cpp | 229 ++++++++++++++++ src/util/min_cut.h | 56 ++++ 9 files changed, 328 insertions(+), 385 deletions(-) delete mode 100644 src/muz/spacer/spacer_min_cut.cpp delete mode 100644 src/muz/spacer/spacer_min_cut.h create mode 100644 src/util/min_cut.cpp create mode 100644 src/util/min_cut.h diff --git a/src/muz/spacer/CMakeLists.txt b/src/muz/spacer/CMakeLists.txt index 97c991e2a..37bc7f352 100644 --- a/src/muz/spacer/CMakeLists.txt +++ b/src/muz/spacer/CMakeLists.txt @@ -17,7 +17,6 @@ z3_add_component(spacer spacer_unsat_core_learner.cpp spacer_unsat_core_plugin.cpp spacer_matrix.cpp - spacer_min_cut.cpp spacer_antiunify.cpp spacer_mev_array.cpp spacer_qe_project.cpp diff --git a/src/muz/spacer/spacer_min_cut.cpp b/src/muz/spacer/spacer_min_cut.cpp deleted file mode 100644 index 22ff81a80..000000000 --- a/src/muz/spacer/spacer_min_cut.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/*++ -Copyright (c) 2017 Arie Gurfinkel - -Module Name: - - spacer_min_cut.cpp - -Abstract: - min cut solver - -Author: - Bernhard Gleiss - -Revision History: - - ---*/ -#include "muz/spacer/spacer_min_cut.h" - -namespace spacer { - - spacer_min_cut::spacer_min_cut() - { - m_n = 2; - - // push back two empty vectors for source and sink - m_edges.push_back(vector>()); - m_edges.push_back(vector>()); - } - - unsigned spacer_min_cut::new_node() - { - return m_n++; - } - - void spacer_min_cut::add_edge(unsigned int i, unsigned int j, unsigned int capacity) - { - if (i >= m_edges.size()) - { - m_edges.resize(i + 1); - } - m_edges[i].insert(std::make_pair(j, 1)); - STRACE("spacer.mincut", - verbose_stream() << "adding edge (" << i << "," << j << ")\n"; - ); - - } - - void spacer_min_cut::compute_min_cut(vector& cut_nodes) - { - if (m_n == 2) - { - return; - } - - m_d.resize(m_n); - m_pred.resize(m_n); - - // compute initial distances and number of nodes - compute_initial_distances(); - - unsigned i = 0; - - while (m_d[0] < m_n) - { - unsigned j = get_admissible_edge(i); - - if (j < m_n) - { - // advance(i) - m_pred[j] = i; - i = j; - - // if i is the sink, augment path - if (i == 1) - { - augment_path(); - i = 0; - } - } - else - { - // retreat - compute_distance(i); - if (i != 0) - { - i = m_pred[i]; - } - } - } - - // split nodes into reachable and unreachable ones - vector reachable(m_n); - compute_reachable_nodes(reachable); - - // find all edges between reachable and unreachable nodes and for each such edge, add corresponding lemma to unsat-core - compute_cut_and_add_lemmas(reachable, cut_nodes); - } - - void spacer_min_cut::compute_initial_distances() - { - vector todo; - vector visited(m_n); - - todo.push_back(0); // start at the source, since we do postorder traversel - - while (!todo.empty()) - { - unsigned current = todo.back(); - - // if we haven't already visited current - if (!visited[current]) { - bool existsUnvisitedParent = false; - - // add unprocessed parents to stack for DFS. If there is at least one unprocessed parent, don't compute the result - // for current now, but wait until those unprocessed parents are processed. - for (unsigned i = 0, sz = m_edges[current].size(); i < sz; ++i) - { - unsigned parent = m_edges[current][i].first; - - // if we haven't visited the current parent yet - if(!visited[parent]) - { - // add it to the stack - todo.push_back(parent); - existsUnvisitedParent = true; - } - } - - // if we already visited all parents, we can visit current too - if (!existsUnvisitedParent) { - visited[current] = true; - todo.pop_back(); - - compute_distance(current); // I.H. all parent distances are already computed - } - } - else { - todo.pop_back(); - } - } - } - - unsigned spacer_min_cut::get_admissible_edge(unsigned i) - { - for (const auto& pair : m_edges[i]) - { - if (pair.second > 0 && m_d[i] == m_d[pair.first] + 1) - { - return pair.first; - } - } - return m_n; // no element found - } - - void spacer_min_cut::augment_path() - { - // find bottleneck capacity - unsigned max = std::numeric_limits::max(); - unsigned k = 1; - while (k != 0) - { - unsigned l = m_pred[k]; - for (const auto& pair : m_edges[l]) - { - if (pair.first == k) - { - if (max > pair.second) - { - max = pair.second; - } - } - } - k = l; - } - - k = 1; - while (k != 0) - { - unsigned l = m_pred[k]; - - // decrease capacity - for (auto& pair : m_edges[l]) - { - if (pair.first == k) - { - pair.second -= max; - } - } - // increase reverse flow - bool already_exists = false; - for (auto& pair : m_edges[k]) - { - if (pair.first == l) - { - already_exists = true; - pair.second += max; - } - } - if (!already_exists) - { - m_edges[k].insert(std::make_pair(l, max)); - } - k = l; - } - } - - void spacer_min_cut::compute_distance(unsigned i) - { - if (i == 1) // sink node - { - m_d[1] = 0; - } - else - { - unsigned min = std::numeric_limits::max(); - - // find edge (i,j) with positive residual capacity and smallest distance - for (const auto& pair : m_edges[i]) - { - if (pair.second > 0) - { - unsigned tmp = m_d[pair.first] + 1; - if (tmp < min) - { - min = tmp; - } - } - } - m_d[i] = min; - } - } - - void spacer_min_cut::compute_reachable_nodes(vector& reachable) - { - vector todo; - - todo.push_back(0); - while (!todo.empty()) - { - unsigned current = todo.back(); - todo.pop_back(); - - if (!reachable[current]) - { - reachable[current] = true; - - for (const auto& pair : m_edges[current]) - { - if (pair.second > 0) - { - todo.push_back(pair.first); - } - } - } - } - } - - void spacer_min_cut::compute_cut_and_add_lemmas(vector& reachable, vector& cut_nodes) - { - vector todo; - vector visited(m_n); - - todo.push_back(0); - while (!todo.empty()) - { - unsigned current = todo.back(); - todo.pop_back(); - - if (!visited[current]) - { - visited[current] = true; - - for (const auto& pair : m_edges[current]) - { - unsigned successor = pair.first; - if (reachable[successor]) - { - todo.push_back(successor); - } - else - { - cut_nodes.push_back(successor); - } - } - } - } - } -} diff --git a/src/muz/spacer/spacer_min_cut.h b/src/muz/spacer/spacer_min_cut.h deleted file mode 100644 index c73a8d3d3..000000000 --- a/src/muz/spacer/spacer_min_cut.h +++ /dev/null @@ -1,53 +0,0 @@ -/*++ -Copyright (c) 2017 Arie Gurfinkel - -Module Name: - - spacer_min_cut.h - -Abstract: - min cut solver - -Author: - Bernhard Gleiss - -Revision History: - - ---*/ - -#ifndef _SPACER_MIN_CUT_H_ -#define _SPACER_MIN_CUT_H_ - -#include "ast/ast.h" -#include "util/vector.h" - -namespace spacer { - - class spacer_min_cut { - public: - spacer_min_cut(); - - unsigned new_node(); - void add_edge(unsigned i, unsigned j, unsigned capacity); - void compute_min_cut(vector& cut_nodes); - - private: - - unsigned m_n; // number of vertices in the graph - - vector > > m_edges; // map from node to all outgoing edges together with their weights (also contains "reverse edges") - vector m_d; // approximation of distance from node to sink in residual graph - vector m_pred; // predecessor-information for reconstruction of augmenting path - vector m_node_to_formula; // maps each node to the corresponding formula in the original proof - - void compute_initial_distances(); - unsigned get_admissible_edge(unsigned i); - void augment_path(); - void compute_distance(unsigned i); - void compute_reachable_nodes(vector& reachable); - void compute_cut_and_add_lemmas(vector& reachable, vector& cut_nodes); - }; -} - -#endif diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index 3f1e53778..af9230713 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -735,7 +735,7 @@ void unsat_core_plugin_farkas_lemma::compute_linear_combination(const vector cut_nodes; + unsigned_vector cut_nodes; m_min_cut.compute_min_cut(cut_nodes); for (unsigned cut_node : cut_nodes) diff --git a/src/muz/spacer/spacer_unsat_core_plugin.h b/src/muz/spacer/spacer_unsat_core_plugin.h index 743d7af4a..96d03140c 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.h +++ b/src/muz/spacer/spacer_unsat_core_plugin.h @@ -19,7 +19,7 @@ Revision History: #define _SPACER_UNSAT_CORE_PLUGIN_H_ #include "ast/ast.h" -#include "muz/spacer/spacer_min_cut.h" +#include "util/min_cut.h" namespace spacer { @@ -109,7 +109,7 @@ private: vector m_node_to_formula; // maps each node to the corresponding formula in the original proof - spacer_min_cut m_min_cut; + min_cut m_min_cut; }; } #endif diff --git a/src/smt/theory_str.cpp b/src/smt/theory_str.cpp index 7e5685f9c..fc8122800 100644 --- a/src/smt/theory_str.cpp +++ b/src/smt/theory_str.cpp @@ -190,13 +190,13 @@ namespace smt { expr * theory_str::rewrite_implication(expr * premise, expr * conclusion) { ast_manager & m = get_manager(); - return m.mk_or(m.mk_not(premise), conclusion); + return m.mk_or(mk_not(m, premise), conclusion); } void theory_str::assert_implication(expr * premise, expr * conclusion) { ast_manager & m = get_manager(); TRACE("str", tout << "asserting implication " << mk_ismt2_pp(premise, m) << " -> " << mk_ismt2_pp(conclusion, m) << std::endl;); - expr_ref axiom(m.mk_or(m.mk_not(premise), conclusion), m); + expr_ref axiom(m.mk_or(mk_not(m, premise), conclusion), m); assert_axiom(axiom); } @@ -545,7 +545,7 @@ namespace smt { context & ctx = get_context(); ast_manager & m = get_manager(); - expr_ref ax1(m.mk_not(ctx.mk_eq_atom(s, mk_string(""))), m); + expr_ref ax1(mk_not(m, ctx.mk_eq_atom(s, mk_string(""))), m); assert_axiom(ax1); { @@ -557,7 +557,7 @@ namespace smt { SASSERT(zero); // build LHS > RHS and assert // we have to build !(LHS <= RHS) instead - expr_ref lhs_gt_rhs(m.mk_not(m_autil.mk_le(len_str, zero)), m); + expr_ref lhs_gt_rhs(mk_not(m, m_autil.mk_le(len_str, zero)), m); SASSERT(lhs_gt_rhs); assert_axiom(lhs_gt_rhs); } @@ -592,7 +592,7 @@ namespace smt { SASSERT(zero); // build LHS > RHS and assert // we have to build !(LHS <= RHS) instead - expr_ref lhs_gt_rhs(m.mk_not(m_autil.mk_le(len_str, zero)), m); + expr_ref lhs_gt_rhs(mk_not(m, m_autil.mk_le(len_str, zero)), m); SASSERT(lhs_gt_rhs); assert_axiom(lhs_gt_rhs); } @@ -1089,7 +1089,7 @@ namespace smt { m_autil.mk_ge(expr->get_arg(1), mk_int(0)), // REWRITE for arithmetic theory: // m_autil.mk_lt(expr->get_arg(1), mk_strlen(expr->get_arg(0))) - m.mk_not(m_autil.mk_ge(m_autil.mk_add(expr->get_arg(1), m_autil.mk_mul(mk_int(-1), mk_strlen(expr->get_arg(0)))), mk_int(0))) + mk_not(m, m_autil.mk_ge(m_autil.mk_add(expr->get_arg(1), m_autil.mk_mul(mk_int(-1), mk_strlen(expr->get_arg(0)))), mk_int(0))) ), m); expr_ref_vector and_item(m); @@ -1130,7 +1130,7 @@ namespace smt { expr_ref_vector innerItems(m); innerItems.push_back(ctx.mk_eq_atom(expr->get_arg(1), mk_concat(ts0, ts1))); innerItems.push_back(ctx.mk_eq_atom(mk_strlen(ts0), mk_strlen(expr->get_arg(0)))); - innerItems.push_back(m.mk_ite(ctx.mk_eq_atom(ts0, expr->get_arg(0)), expr, m.mk_not(expr))); + innerItems.push_back(m.mk_ite(ctx.mk_eq_atom(ts0, expr->get_arg(0)), expr, mk_not(m, expr))); expr_ref then1(m.mk_and(innerItems.size(), innerItems.c_ptr()), m); SASSERT(then1); @@ -1143,7 +1143,7 @@ namespace smt { , m); SASSERT(topLevelCond); - expr_ref finalAxiom(m.mk_ite(topLevelCond, then1, m.mk_not(expr)), m); + expr_ref finalAxiom(m.mk_ite(topLevelCond, then1, mk_not(m, expr)), m); SASSERT(finalAxiom); assert_axiom(finalAxiom); } @@ -1167,7 +1167,7 @@ namespace smt { expr_ref_vector innerItems(m); innerItems.push_back(ctx.mk_eq_atom(expr->get_arg(1), mk_concat(ts0, ts1))); innerItems.push_back(ctx.mk_eq_atom(mk_strlen(ts1), mk_strlen(expr->get_arg(0)))); - innerItems.push_back(m.mk_ite(ctx.mk_eq_atom(ts1, expr->get_arg(0)), expr, m.mk_not(expr))); + innerItems.push_back(m.mk_ite(ctx.mk_eq_atom(ts1, expr->get_arg(0)), expr, mk_not(m, expr))); expr_ref then1(m.mk_and(innerItems.size(), innerItems.c_ptr()), m); SASSERT(then1); @@ -1180,7 +1180,7 @@ namespace smt { , m); SASSERT(topLevelCond); - expr_ref finalAxiom(m.mk_ite(topLevelCond, then1, m.mk_not(expr)), m); + expr_ref finalAxiom(m.mk_ite(topLevelCond, then1, mk_not(m, expr)), m); SASSERT(finalAxiom); assert_axiom(finalAxiom); } @@ -1204,7 +1204,7 @@ namespace smt { if (haystackStr.contains(needleStr)) { assert_axiom(ex); } else { - assert_axiom(m.mk_not(ex)); + assert_axiom(mk_not(m, ex)); } return; } @@ -1265,7 +1265,7 @@ namespace smt { SASSERT(tmpLen); thenItems.push_back(ctx.mk_eq_atom(expr->get_arg(0), mk_concat(x3, x4))); thenItems.push_back(ctx.mk_eq_atom(mk_strlen(x3), tmpLen)); - thenItems.push_back(m.mk_not(mk_contains(x3, expr->get_arg(1)))); + thenItems.push_back(mk_not(m, mk_contains(x3, expr->get_arg(1)))); expr_ref thenBranch(m.mk_and(thenItems.size(), thenItems.c_ptr()), m); SASSERT(thenBranch); @@ -1341,7 +1341,7 @@ namespace smt { expr_ref ite1(m.mk_ite( //m_autil.mk_lt(expr->get_arg(2), zeroAst), - m.mk_not(m_autil.mk_ge(expr->get_arg(2), zeroAst)), + mk_not(m, m_autil.mk_ge(expr->get_arg(2), zeroAst)), ctx.mk_eq_atom(resAst, mk_indexof(expr->get_arg(0), expr->get_arg(1))), ite2 ), m); @@ -1384,7 +1384,7 @@ namespace smt { thenItems.push_back(m_autil.mk_ge(indexAst, mk_int(0))); // args[0] = x1 . args[1] . x2 // x1 doesn't contain args[1] - thenItems.push_back(m.mk_not(mk_contains(x2, expr->get_arg(1)))); + thenItems.push_back(mk_not(m, mk_contains(x2, expr->get_arg(1)))); thenItems.push_back(ctx.mk_eq_atom(indexAst, mk_strlen(x1))); bool canSkip = false; @@ -1402,7 +1402,7 @@ namespace smt { expr_ref tmpLen(m_autil.mk_add(indexAst, mk_int(1)), m); thenItems.push_back(ctx.mk_eq_atom(expr->get_arg(0), mk_concat(x3, x4))); thenItems.push_back(ctx.mk_eq_atom(mk_strlen(x3), tmpLen)); - thenItems.push_back(m.mk_not(mk_contains(x4, expr->get_arg(1)))); + thenItems.push_back(mk_not(m, mk_contains(x4, expr->get_arg(1)))); } //---------------------------- // else branch @@ -1452,7 +1452,7 @@ namespace smt { argumentsValid_terms.push_back(m_autil.mk_ge(substrPos, zero)); // pos < strlen(base) // --> pos + -1*strlen(base) < 0 - argumentsValid_terms.push_back(m.mk_not(m_autil.mk_ge( + argumentsValid_terms.push_back(mk_not(m, m_autil.mk_ge( m_autil.mk_add(substrPos, m_autil.mk_mul(minusOne, substrLen)), zero))); @@ -1473,7 +1473,7 @@ namespace smt { // Case 1: pos < 0 or pos >= strlen(base) or len < 0 // ==> (Substr ...) = "" - expr_ref case1_premise(m.mk_not(argumentsValid), m); + expr_ref case1_premise(mk_not(m, argumentsValid), m); SASSERT(case1_premise); ctx.internalize(case1_premise, false); expr_ref case1_conclusion(ctx.mk_eq_atom(expr, mk_string("")), m); @@ -1505,7 +1505,7 @@ namespace smt { case3_conclusion_terms.push_back(ctx.mk_eq_atom(mk_strlen(t3), substrLen)); case3_conclusion_terms.push_back(ctx.mk_eq_atom(expr, t3)); expr_ref case3_conclusion(mk_and(case3_conclusion_terms), m); - expr_ref case3(rewrite_implication(m.mk_and(argumentsValid, m.mk_not(lenOutOfBounds)), case3_conclusion), m); + expr_ref case3(rewrite_implication(m.mk_and(argumentsValid, mk_not(m, lenOutOfBounds)), case3_conclusion), m); SASSERT(case3); ctx.internalize(case1, false); @@ -1548,7 +1548,7 @@ namespace smt { argumentsValid_terms.push_back(m_autil.mk_ge(substrPos, zero)); // pos < strlen(base) // --> pos + -1*strlen(base) < 0 - argumentsValid_terms.push_back(m.mk_not(m_autil.mk_ge( + argumentsValid_terms.push_back(mk_not(m, m_autil.mk_ge( m_autil.mk_add(substrPos, m_autil.mk_mul(minusOne, substrLen)), zero))); // len >= 0 @@ -1564,7 +1564,7 @@ namespace smt { // Case 1: pos < 0 or pos >= strlen(base) or len < 0 // ==> (Substr ...) = "" - expr_ref case1_premise(m.mk_not(argumentsValid), m); + expr_ref case1_premise(mk_not(m, argumentsValid), m); expr_ref case1_conclusion(ctx.mk_eq_atom(expr, mk_string("")), m); expr_ref case1(m.mk_implies(case1_premise, case1_conclusion), m); @@ -1589,7 +1589,7 @@ namespace smt { case3_conclusion_terms.push_back(ctx.mk_eq_atom(mk_strlen(t3), substrLen)); case3_conclusion_terms.push_back(ctx.mk_eq_atom(expr, t3)); expr_ref case3_conclusion(mk_and(case3_conclusion_terms), m); - expr_ref case3(m.mk_implies(m.mk_and(argumentsValid, m.mk_not(lenOutOfBounds)), case3_conclusion), m); + expr_ref case3(m.mk_implies(m.mk_and(argumentsValid, mk_not(m, lenOutOfBounds)), case3_conclusion), m); assert_axiom(case1); assert_axiom(case2); @@ -1630,7 +1630,7 @@ namespace smt { expr_ref tmpLen(m_autil.mk_add(i1, mk_strlen(expr->get_arg(1)), mk_int(-1)), m); thenItems.push_back(ctx.mk_eq_atom(expr->get_arg(0), mk_concat(x3, x4))); thenItems.push_back(ctx.mk_eq_atom(mk_strlen(x3), tmpLen)); - thenItems.push_back(m.mk_not(mk_contains(x3, expr->get_arg(1)))); + thenItems.push_back(mk_not(m, mk_contains(x3, expr->get_arg(1)))); thenItems.push_back(ctx.mk_eq_atom(result, mk_concat(x1, mk_concat(expr->get_arg(2), x2)))); // ----------------------- // false branch @@ -1684,7 +1684,7 @@ namespace smt { expr_ref tl(mk_str_var("tl"), m); expr_ref conclusion1(ctx.mk_eq_atom(S, mk_concat(hd, tl)), m); expr_ref conclusion2(ctx.mk_eq_atom(mk_strlen(hd), m_autil.mk_numeral(rational::one(), true)), m); - expr_ref conclusion3(m.mk_not(ctx.mk_eq_atom(hd, mk_string("0"))), m); + expr_ref conclusion3(mk_not(m, ctx.mk_eq_atom(hd, mk_string("0"))), m); expr_ref conclusion(m.mk_and(conclusion1, conclusion2, conclusion3), m); SASSERT(premise); SASSERT(conclusion); @@ -1708,7 +1708,7 @@ namespace smt { // axiom 1: N < 0 <==> (str.from-int N) = "" expr * N = ex->get_arg(0); { - expr_ref axiom1_lhs(m.mk_not(m_autil.mk_ge(N, m_autil.mk_numeral(rational::zero(), true))), m); + expr_ref axiom1_lhs(mk_not(m, m_autil.mk_ge(N, m_autil.mk_numeral(rational::zero(), true))), m); expr_ref axiom1_rhs(ctx.mk_eq_atom(ex, mk_string("")), m); expr_ref axiom1(ctx.mk_eq_atom(axiom1_lhs, axiom1_rhs), m); SASSERT(axiom1); @@ -1947,7 +1947,7 @@ namespace smt { // inconsistency check: value if (!can_two_nodes_eq(eqc_nn1, eqc_nn2)) { TRACE("str", tout << "inconsistency detected: " << mk_pp(eqc_nn1, m) << " cannot be equal to " << mk_pp(eqc_nn2, m) << std::endl;); - expr_ref to_assert(m.mk_not(ctx.mk_eq_atom(eqc_nn1, eqc_nn2)), m); + expr_ref to_assert(mk_not(m, ctx.mk_eq_atom(eqc_nn1, eqc_nn2)), m); assert_axiom(to_assert); // this shouldn't use the integer theory at all, so we don't allow the option of quick-return return false; @@ -2160,7 +2160,7 @@ namespace smt { expr_ref implyR11(ctx.mk_eq_atom(mk_strlen(arg1), mk_int(makeUpLenArg1)), m); assert_implication(implyL11, implyR11); } else { - expr_ref neg(m.mk_not(implyL11), m); + expr_ref neg(mk_not(m, implyL11), m); assert_axiom(neg); } } @@ -2231,7 +2231,7 @@ namespace smt { expr_ref implyR11(ctx.mk_eq_atom(mk_strlen(arg0), mk_int(makeUpLenArg0)), m); assert_implication(implyL11, implyR11); } else { - expr_ref neg(m.mk_not(implyL11), m); + expr_ref neg(mk_not(m, implyL11), m); assert_axiom(neg); } } @@ -2762,7 +2762,7 @@ namespace smt { } if (!can_two_nodes_eq(new_nn1, new_nn2)) { - expr_ref detected(m.mk_not(ctx.mk_eq_atom(new_nn1, new_nn2)), m); + expr_ref detected(mk_not(m, ctx.mk_eq_atom(new_nn1, new_nn2)), m); TRACE("str", tout << "inconsistency detected: " << mk_ismt2_pp(detected, m) << std::endl;); assert_axiom(detected); return; @@ -5008,7 +5008,7 @@ namespace smt { implyR = boolVar; } else { //implyR = Z3_mk_eq(ctx, boolVar, Z3_mk_false(ctx)); - implyR = m.mk_not(boolVar); + implyR = mk_not(m, boolVar); } } else { // ------------------------------------------------------------------------------------------------ @@ -5037,7 +5037,7 @@ namespace smt { litems.push_back(ctx.mk_eq_atom(substrAst, aConcat)); } //implyR = Z3_mk_eq(ctx, boolVar, Z3_mk_false(ctx)); - implyR = m.mk_not(boolVar); + implyR = mk_not(m, boolVar); break; } } @@ -5076,7 +5076,7 @@ namespace smt { implyR = boolVar; } else { // implyR = Z3_mk_eq(ctx, boolVar, Z3_mk_false(ctx)); - implyR = m.mk_not(boolVar); + implyR = mk_not(m, boolVar); } } @@ -5146,7 +5146,7 @@ namespace smt { litems.push_back(ctx.mk_eq_atom(substrAst, aConcat)); } expr_ref implyLHS(mk_and(litems), m); - expr_ref implyR(m.mk_not(boolVar), m); + expr_ref implyR(mk_not(m, boolVar), m); assert_implication(implyLHS, implyR); break; } @@ -6515,7 +6515,7 @@ namespace smt { if (matchRes) { assert_implication(implyL, boolVar); } else { - assert_implication(implyL, m.mk_not(boolVar)); + assert_implication(implyL, mk_not(m, boolVar)); } } } @@ -6603,7 +6603,7 @@ namespace smt { << arg1_str << "\" + \"" << arg2_str << "\" != \"" << const_str << "\"" << "\n";); expr_ref equality(ctx.mk_eq_atom(concat, str), m); - expr_ref diseq(m.mk_not(equality), m); + expr_ref diseq(mk_not(m, equality), m); assert_axiom(diseq); return; } @@ -6621,7 +6621,7 @@ namespace smt { "\" is longer than \"" << const_str << "\"," << " so cannot be concatenated with anything to form it" << "\n";); expr_ref equality(ctx.mk_eq_atom(newConcat, str), m); - expr_ref diseq(m.mk_not(equality), m); + expr_ref diseq(mk_not(m, equality), m); assert_axiom(diseq); return; } else { @@ -6635,7 +6635,7 @@ namespace smt { << "actually \"" << arg2_str << "\"" << "\n";); expr_ref equality(ctx.mk_eq_atom(newConcat, str), m); - expr_ref diseq(m.mk_not(equality), m); + expr_ref diseq(mk_not(m, equality), m); assert_axiom(diseq); return; } else { diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 7ed68c89f..85b6f955c 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -28,6 +28,7 @@ z3_add_component(util lbool.cpp luby.cpp memory_manager.cpp + min_cut.cpp mpbq.cpp mpf.cpp mpff.cpp diff --git a/src/util/min_cut.cpp b/src/util/min_cut.cpp new file mode 100644 index 000000000..a56c5f6a0 --- /dev/null +++ b/src/util/min_cut.cpp @@ -0,0 +1,229 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + min_cut.cpp + +Abstract: + min cut solver + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ +#include "util/min_cut.h" + +min_cut::min_cut() { + // push back two empty vectors for source and sink + m_edges.push_back(edge_vector()); + m_edges.push_back(edge_vector()); +} + +unsigned min_cut::new_node() { + m_edges.push_back(edge_vector()); + return m_edges.size() - 1; +} + +void min_cut::add_edge(unsigned int i, unsigned int j) { + m_edges.reserve(i + 1); + m_edges[i].push_back(edge(j, 1)); + TRACE("spacer.mincut", tout << "adding edge (" << i << "," << j << ")\n";); +} + +void min_cut::compute_min_cut(unsigned_vector& cut_nodes) { + if (m_edges.size() == 2) { + return; + } + + m_d.resize(m_edges.size()); + m_pred.resize(m_edges.size()); + + // compute initial distances and number of nodes + compute_initial_distances(); + + unsigned i = 0; + + while (m_d[0] < m_edges.size()) { + unsigned j = get_admissible_edge(i); + + if (j < m_edges.size()) { + // advance(i) + m_pred[j] = i; + i = j; + + // if i is the sink, augment path + if (i == 1) { + augment_path(); + i = 0; + } + } + else { + // retreat + compute_distance(i); + if (i != 0) { + i = m_pred[i]; + } + } + } + + // split nodes into reachable and unreachable ones + bool_vector reachable(m_edges.size()); + compute_reachable_nodes(reachable); + + // find all edges between reachable and unreachable nodes and for each such edge, add corresponding lemma to unsat-core + compute_cut_and_add_lemmas(reachable, cut_nodes); +} + +void min_cut::compute_initial_distances() { + unsigned_vector todo; + bool_vector visited(m_edges.size()); + + todo.push_back(0); // start at the source, since we do postorder traversel + + while (!todo.empty()) { + unsigned current = todo.back(); + + // if we haven't already visited current + if (!visited[current]) { + bool exists_unvisited_parent = false; + + // add unprocessed parents to stack for DFS. If there is at least one unprocessed parent, don't compute the result + // for current now, but wait until those unprocessed parents are processed + for (auto const& edge : m_edges[current]) { + unsigned parent = edge.node; + + // if we haven't visited the current parent yet + if (!visited[parent]) { + // add it to the stack + todo.push_back(parent); + exists_unvisited_parent = true; + } + } + + // if we already visited all parents, we can visit current too + if (!exists_unvisited_parent) { + visited[current] = true; + todo.pop_back(); + + compute_distance(current); // I.H. all parent distances are already computed + } + } + else { + todo.pop_back(); + } + } +} + +unsigned min_cut::get_admissible_edge(unsigned i) { + for (const auto& edge : m_edges[i]) { + if (edge.weight > 0 && m_d[i] == m_d[edge.node] + 1) { + return edge.node; + } + } + return m_edges.size(); // no element found +} + +void min_cut::augment_path() { + // find bottleneck capacity + unsigned max = std::numeric_limits::max(); + unsigned k = 1; + while (k != 0) { + unsigned l = m_pred[k]; + for (const auto& edge : m_edges[l]) { + if (edge.node == k) { + max = std::min(max, edge.weight); + } + } + k = l; + } + + k = 1; + while (k != 0) { + unsigned l = m_pred[k]; + + // decrease capacity + for (auto& edge : m_edges[l]) { + if (edge.node == k) { + edge.weight -= max; + } + } + // increase reverse flow + bool already_exists = false; + for (auto& edge : m_edges[k]) { + if (edge.node == l) { + already_exists = true; + edge.weight += max; + } + } + if (!already_exists) { + m_edges[k].push_back(edge(1, max)); + } + k = l; + } +} + +void min_cut::compute_distance(unsigned i) { + if (i == 1) { // sink node + m_d[1] = 0; + } + else { + unsigned min = std::numeric_limits::max(); + + // find edge (i,j) with positive residual capacity and smallest distance + for (const auto& edge : m_edges[i]) { + if (edge.weight > 0) { + min = std::min(min, m_d[edge.node] + 1); + } + } + m_d[i] = min; + } +} + +void min_cut::compute_reachable_nodes(bool_vector& reachable) { + unsigned_vector todo; + + todo.push_back(0); + while (!todo.empty()) { + unsigned current = todo.back(); + todo.pop_back(); + + if (!reachable[current]) { + reachable[current] = true; + + for (const auto& edge : m_edges[current]) { + if (edge.weight > 0) { + todo.push_back(edge.node); + } + } + } + } +} + +void min_cut::compute_cut_and_add_lemmas(bool_vector& reachable, unsigned_vector& cut_nodes) { + unsigned_vector todo; + bool_vector visited(m_edges.size()); + + todo.push_back(0); + while (!todo.empty()) { + unsigned current = todo.back(); + todo.pop_back(); + + if (!visited[current]) { + visited[current] = true; + + for (const auto& edge : m_edges[current]) { + unsigned successor = edge.node; + if (reachable[successor]) { + todo.push_back(successor); + } + else { + cut_nodes.push_back(successor); + } + } + } + } +} diff --git a/src/util/min_cut.h b/src/util/min_cut.h new file mode 100644 index 000000000..246377f1f --- /dev/null +++ b/src/util/min_cut.h @@ -0,0 +1,56 @@ +/*++ +Copyright (c) 2017 Arie Gurfinkel + +Module Name: + + min_cut.h + +Abstract: + min cut solver + +Author: + Bernhard Gleiss + +Revision History: + + +--*/ + +#ifndef MIN_CUT_H_ +#define MIN_CUT_H_ + +#include "ast/ast.h" +#include "util/vector.h" + + +class min_cut { +public: + min_cut(); + + unsigned new_node(); + /* + \brief add an edge (with unit capacity) + */ + void add_edge(unsigned i, unsigned j); + + void compute_min_cut(unsigned_vector& cut_nodes); + +private: + + typedef svector bool_vector; + struct edge { unsigned node; unsigned weight; edge(unsigned n, unsigned w): node(n), weight(w) {} edge(): node(0), weight(0) {} }; + typedef svector edge_vector; + + vector m_edges; // map from node to all outgoing edges together with their weights (also contains "reverse edges") + unsigned_vector m_d; // approximation of distance from node to sink in residual graph + unsigned_vector m_pred; // predecessor-information for reconstruction of augmenting path + + void compute_initial_distances(); + unsigned get_admissible_edge(unsigned i); + void augment_path(); + void compute_distance(unsigned i); + void compute_reachable_nodes(bool_vector& reachable); + void compute_cut_and_add_lemmas(bool_vector& reachable, unsigned_vector& cut_nodes); +}; + +#endif From de3700e1fd5fc8c005fd8048e3ef979e19b2ec2e Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Wed, 25 Oct 2017 11:13:25 +0100 Subject: [PATCH 475/488] [CMake] Try to unbreak the C example build with older GCC versions by forcing the language version to be C99. --- examples/c/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index bac08e460..c47a4947a 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -7,6 +7,19 @@ # the C++ standard library in resulting in a link failure. project(Z3_C_EXAMPLE C CXX) cmake_minimum_required(VERSION 2.8.12) + +# Set C version required to C99 +if ("${CMAKE_VERSION}" VERSION_LESS "3.1") + if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR + ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 ") + endif() +else() + set(CMAKE_C_STANDARD_REQUIRED ON) + set(CMAKE_C_STANDARD 99) + set(CMAKE_C_EXTENSIONS OFF) +endif() + find_package(Z3 REQUIRED CONFIG From f5f1d019d81de5e93aa53237d31ecbfcd9dd06c0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 09:00:35 -0700 Subject: [PATCH 476/488] missing files Signed-off-by: Nikolaj Bjorner --- src/util/min_cut.cpp | 4 ++-- src/util/min_cut.h | 14 +++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/util/min_cut.cpp b/src/util/min_cut.cpp index a56c5f6a0..2f7bdb862 100644 --- a/src/util/min_cut.cpp +++ b/src/util/min_cut.cpp @@ -28,9 +28,9 @@ unsigned min_cut::new_node() { return m_edges.size() - 1; } -void min_cut::add_edge(unsigned int i, unsigned int j) { +void min_cut::add_edge(unsigned int i, unsigned int j, unsigned capacity) { m_edges.reserve(i + 1); - m_edges[i].push_back(edge(j, 1)); + m_edges[i].push_back(edge(j, capacity)); TRACE("spacer.mincut", tout << "adding edge (" << i << "," << j << ")\n";); } diff --git a/src/util/min_cut.h b/src/util/min_cut.h index 246377f1f..5a783a8d0 100644 --- a/src/util/min_cut.h +++ b/src/util/min_cut.h @@ -27,12 +27,20 @@ class min_cut { public: min_cut(); - unsigned new_node(); /* - \brief add an edge (with unit capacity) + \brief create a node */ - void add_edge(unsigned i, unsigned j); + unsigned new_node(); + /* + \brief add an i -> j edge with (unit) capacity + */ + void add_edge(unsigned i, unsigned j, unsigned capacity = 1); + + /* + \brief produce a min cut between source node = 0 and target node = 1. + NB. the function changes capacities on edges. + */ void compute_min_cut(unsigned_vector& cut_nodes); private: From 0268f2243ec8939f3e72db2761724418415818a3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 09:49:53 -0700 Subject: [PATCH 477/488] remove ast.h reference Signed-off-by: Nikolaj Bjorner --- src/util/min_cut.cpp | 7 +++++-- src/util/min_cut.h | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/util/min_cut.cpp b/src/util/min_cut.cpp index 2f7bdb862..b7c30f546 100644 --- a/src/util/min_cut.cpp +++ b/src/util/min_cut.cpp @@ -16,6 +16,7 @@ Revision History: --*/ #include "util/min_cut.h" +#include "util/trace.h" min_cut::min_cut() { // push back two empty vectors for source and sink @@ -74,7 +75,8 @@ void min_cut::compute_min_cut(unsigned_vector& cut_nodes) { bool_vector reachable(m_edges.size()); compute_reachable_nodes(reachable); - // find all edges between reachable and unreachable nodes and for each such edge, add corresponding lemma to unsat-core + // find all edges between reachable and unreachable nodes and + // for each such edge, add corresponding lemma to unsat-core compute_cut_and_add_lemmas(reachable, cut_nodes); } @@ -91,7 +93,8 @@ void min_cut::compute_initial_distances() { if (!visited[current]) { bool exists_unvisited_parent = false; - // add unprocessed parents to stack for DFS. If there is at least one unprocessed parent, don't compute the result + // add unprocessed parents to stack for DFS. If there is at least + // one unprocessed parent, don't compute the result // for current now, but wait until those unprocessed parents are processed for (auto const& edge : m_edges[current]) { unsigned parent = edge.node; diff --git a/src/util/min_cut.h b/src/util/min_cut.h index 5a783a8d0..51a330126 100644 --- a/src/util/min_cut.h +++ b/src/util/min_cut.h @@ -19,7 +19,6 @@ Revision History: #ifndef MIN_CUT_H_ #define MIN_CUT_H_ -#include "ast/ast.h" #include "util/vector.h" From 2c2705628317698709c3113bf6c11acdebc02ec7 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 10:24:49 -0700 Subject: [PATCH 478/488] disable model example pending C compliance or C99 or whatever adjustment Signed-off-by: Nikolaj Bjorner --- examples/c/test_capi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 433c7ebcf..178b77b86 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2844,9 +2844,9 @@ void fpa_example() { \brief Demonstrates some basic features of model construction */ +#if 0 void mk_model_example() { printf("\nmk_model_example\n"); - LOG_MSG("mk_model_example"); Z3_context ctx = mk_context(); // Construct empty model Z3_model m = Z3_mk_model(ctx); @@ -2973,7 +2973,7 @@ void mk_model_example() { printf("a+b did not evaluate to expected value\n"); exit(1); } - + // Evaluate c[0] + c[1] + c[2] under model Z3_ast c0 = Z3_mk_select(ctx, cApp, zeroNumeral); Z3_ast c1 = Z3_mk_select(ctx, cApp, oneNumeral); @@ -3009,6 +3009,7 @@ void mk_model_example() { Z3_model_dec_ref(ctx, m); Z3_del_context(ctx); } +#endif /*@}*/ /*@}*/ @@ -3058,6 +3059,6 @@ int main() { substitute_example(); substitute_vars_example(); fpa_example(); - mk_model_example(); +// mk_model_example(); return 0; } From 7ed32f43151816c734ddda6e56ced4e5e3b7834b Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 10:48:53 -0700 Subject: [PATCH 479/488] re-add model example Signed-off-by: Nikolaj Bjorner --- examples/c/test_capi.c | 367 ++++++++++++++++++++++------------------- 1 file changed, 194 insertions(+), 173 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 178b77b86..d9db91c66 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2769,73 +2769,73 @@ void fpa_example() { double_sort = Z3_mk_fpa_sort(ctx, 11, 53); rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx); - // Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode). - s_rm = Z3_mk_string_symbol(ctx, "rm"); - rm = Z3_mk_const(ctx, s_rm, rm_sort); - s_x = Z3_mk_string_symbol(ctx, "x"); - s_y = Z3_mk_string_symbol(ctx, "y"); - x = Z3_mk_const(ctx, s_x, double_sort); - y = Z3_mk_const(ctx, s_y, double_sort); - n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); - - s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y"); - x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort); - c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y)); - - args[0] = c1; - args[1] = Z3_mk_eq(ctx, x_plus_y, n); - c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); - - args2[0] = c2; - args2[1] = Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx))); - c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); - - and_args[0] = Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)); - and_args[1] = Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)); - and_args[2] = Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y)); - args3[0] = c3; - args3[1] = Z3_mk_and(ctx, 3, and_args); - c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); - - printf("c4: %s\n", Z3_ast_to_string(ctx, c4)); - Z3_solver_push(ctx, s); - Z3_solver_assert(ctx, s, c4); - check(ctx, s, Z3_L_TRUE); - Z3_solver_pop(ctx, s, 1); - - // Show that the following are equal: - // (fp #b0 #b10000000001 #xc000000000000) - // ((_ to_fp 11 53) #x401c000000000000)) - // ((_ to_fp 11 53) RTZ 1.75 2))) - // ((_ to_fp 11 53) RTZ 7.0))) - - Z3_solver_push(ctx, s); - c1 = Z3_mk_fpa_fp(ctx, - Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), - Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)), + // Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode). + s_rm = Z3_mk_string_symbol(ctx, "rm"); + rm = Z3_mk_const(ctx, s_rm, rm_sort); + s_x = Z3_mk_string_symbol(ctx, "x"); + s_y = Z3_mk_string_symbol(ctx, "y"); + x = Z3_mk_const(ctx, s_x, double_sort); + y = Z3_mk_const(ctx, s_y, double_sort); + n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); + + s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y"); + x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort); + c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y)); + + args[0] = c1; + args[1] = Z3_mk_eq(ctx, x_plus_y, n); + c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); + + args2[0] = c2; + args2[1] = Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx))); + c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); + + and_args[0] = Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)); + and_args[1] = Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)); + and_args[2] = Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y)); + args3[0] = c3; + args3[1] = Z3_mk_and(ctx, 3, and_args); + c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); + + printf("c4: %s\n", Z3_ast_to_string(ctx, c4)); + Z3_solver_push(ctx, s); + Z3_solver_assert(ctx, s, c4); + check(ctx, s, Z3_L_TRUE); + Z3_solver_pop(ctx, s, 1); + + // Show that the following are equal: + // (fp #b0 #b10000000001 #xc000000000000) + // ((_ to_fp 11 53) #x401c000000000000)) + // ((_ to_fp 11 53) RTZ 1.75 2))) + // ((_ to_fp 11 53) RTZ 7.0))) + + Z3_solver_push(ctx, s); + c1 = Z3_mk_fpa_fp(ctx, + Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), + Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)), Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52))); - c2 = Z3_mk_fpa_to_fp_bv(ctx, - Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), - Z3_mk_fpa_sort(ctx, 11, 53)); + c2 = Z3_mk_fpa_to_fp_bv(ctx, + Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), + Z3_mk_fpa_sort(ctx, 11, 53)); c3 = Z3_mk_fpa_to_fp_int_real(ctx, Z3_mk_fpa_rtz(ctx), - Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), /* exponent */ + Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), /* exponent */ Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), /* significand */ Z3_mk_fpa_sort(ctx, 11, 53)); c4 = Z3_mk_fpa_to_fp_real(ctx, - Z3_mk_fpa_rtz(ctx), - Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), - Z3_mk_fpa_sort(ctx, 11, 53)); - args3[0] = Z3_mk_eq(ctx, c1, c2); - args3[1] = Z3_mk_eq(ctx, c1, c3); - args3[2] = Z3_mk_eq(ctx, c1, c4); - c5 = Z3_mk_and(ctx, 3, args3); - - printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); - Z3_solver_assert(ctx, s, c5); - check(ctx, s, Z3_L_TRUE); - Z3_solver_pop(ctx, s, 1); - + Z3_mk_fpa_rtz(ctx), + Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), + Z3_mk_fpa_sort(ctx, 11, 53)); + args3[0] = Z3_mk_eq(ctx, c1, c2); + args3[1] = Z3_mk_eq(ctx, c1, c3); + args3[2] = Z3_mk_eq(ctx, c1, c4); + c5 = Z3_mk_and(ctx, 3, args3); + + printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); + Z3_solver_assert(ctx, s, c5); + check(ctx, s, Z3_L_TRUE); + Z3_solver_pop(ctx, s, 1); + del_solver(ctx, s); Z3_del_context(ctx); } @@ -2844,52 +2844,67 @@ void fpa_example() { \brief Demonstrates some basic features of model construction */ -#if 0 void mk_model_example() { + Z3_context ctx; + Z3_model m; + Z3_sort intSort; + Z3_symbol aSymbol, bSymbol, cSymbol; + Z3_func_decl aFuncDecl, bFuncDecl, cFuncDecl; + Z3_ast aApp, bApp, cApp; + Z3_sort int2intArraySort; + Z3_ast zeroNumeral, oneNumeral, twoNumeral, threeNumeral, fourNumeral; + Z3_sort arrayDomain[1]; + Z3_func_decl cAsFuncDecl; + Z3_func_interp cAsFuncInterp; + Z3_ast_vector zeroArgs; + Z3_ast_vector oneArgs; + Z3_ast cFuncDeclAsArray; + Z3_string modelAsString; + printf("\nmk_model_example\n"); - Z3_context ctx = mk_context(); + ctx = mk_context(); // Construct empty model - Z3_model m = Z3_mk_model(ctx); + m = Z3_mk_model(ctx); Z3_model_inc_ref(ctx, m); // Create constants "a" and "b" - Z3_sort intSort = Z3_mk_int_sort(ctx); - Z3_symbol aSymbol = Z3_mk_string_symbol(ctx, "a"); - Z3_func_decl aFuncDecl = Z3_mk_func_decl(ctx, aSymbol, - /*domain_size=*/0, - /*domain=*/NULL, - /*range=*/intSort); - Z3_ast aApp = Z3_mk_app(ctx, aFuncDecl, - /*num_args=*/0, - /*args=*/NULL); - Z3_symbol bSymbol = Z3_mk_string_symbol(ctx, "b"); - Z3_func_decl bFuncDecl = Z3_mk_func_decl(ctx, bSymbol, - /*domain_size=*/0, - /*domain=*/NULL, - /*range=*/intSort); - Z3_ast bApp = Z3_mk_app(ctx, bFuncDecl, - /*num_args=*/0, - /*args=*/NULL); + intSort = Z3_mk_int_sort(ctx); + aSymbol = Z3_mk_string_symbol(ctx, "a"); + aFuncDecl = Z3_mk_func_decl(ctx, aSymbol, + /*domain_size=*/0, + /*domain=*/NULL, + /*range=*/intSort); + aApp = Z3_mk_app(ctx, aFuncDecl, + /*num_args=*/0, + /*args=*/NULL); + bSymbol = Z3_mk_string_symbol(ctx, "b"); + bFuncDecl = Z3_mk_func_decl(ctx, bSymbol, + /*domain_size=*/0, + /*domain=*/NULL, + /*range=*/intSort); + bApp = Z3_mk_app(ctx, bFuncDecl, + /*num_args=*/0, + /*args=*/NULL); // Create array "c" that maps int to int. - Z3_symbol cSymbol = Z3_mk_string_symbol(ctx, "c"); - Z3_sort int2intArraySort = Z3_mk_array_sort(ctx, - /*domain=*/intSort, - /*range=*/intSort); - Z3_func_decl cFuncDecl = Z3_mk_func_decl(ctx, cSymbol, - /*domain_size=*/0, - /*domain=*/NULL, - /*range=*/int2intArraySort); - Z3_ast cApp = Z3_mk_app(ctx, cFuncDecl, - /*num_args=*/0, - /*args=*/NULL); + cSymbol = Z3_mk_string_symbol(ctx, "c"); + int2intArraySort = Z3_mk_array_sort(ctx, + /*domain=*/intSort, + /*range=*/intSort); + cFuncDecl = Z3_mk_func_decl(ctx, cSymbol, + /*domain_size=*/0, + /*domain=*/NULL, + /*range=*/int2intArraySort); + cApp = Z3_mk_app(ctx, cFuncDecl, + /*num_args=*/0, + /*args=*/NULL); // Create numerals to be used in model - Z3_ast zeroNumeral = Z3_mk_int(ctx, 0, intSort); - Z3_ast oneNumeral = Z3_mk_int(ctx, 1, intSort); - Z3_ast twoNumeral = Z3_mk_int(ctx, 2, intSort); - Z3_ast threeNumeral = Z3_mk_int(ctx, 3, intSort); - Z3_ast fourNumeral = Z3_mk_int(ctx, 4, intSort); + zeroNumeral = Z3_mk_int(ctx, 0, intSort); + oneNumeral = Z3_mk_int(ctx, 1, intSort); + twoNumeral = Z3_mk_int(ctx, 2, intSort); + threeNumeral = Z3_mk_int(ctx, 3, intSort); + fourNumeral = Z3_mk_int(ctx, 4, intSort); // Add assignments to model // a == 1 @@ -2899,25 +2914,25 @@ void mk_model_example() { // Create a fresh function that represents // reading from array. - Z3_sort arrayDomain[] = {intSort}; - Z3_func_decl cAsFuncDecl = Z3_mk_fresh_func_decl(ctx, - /*prefix=*/"", - /*domain_size*/ 1, - /*domain=*/arrayDomain, - /*sort=*/intSort); + arrayDomain[0] = intSort; + cAsFuncDecl = Z3_mk_fresh_func_decl(ctx, + /*prefix=*/"", + /*domain_size*/ 1, + /*domain=*/arrayDomain, + /*sort=*/intSort); // Create function interpretation with default // value of "0". - Z3_func_interp cAsFuncInterp = + cAsFuncInterp = Z3_add_func_interp(ctx, m, cAsFuncDecl, /*default_value=*/zeroNumeral); Z3_func_interp_inc_ref(ctx, cAsFuncInterp); // Add [0] = 3 - Z3_ast_vector zeroArgs = Z3_mk_ast_vector(ctx); + zeroArgs = Z3_mk_ast_vector(ctx); Z3_ast_vector_inc_ref(ctx, zeroArgs); Z3_ast_vector_push(ctx, zeroArgs, zeroNumeral); Z3_func_interp_add_entry(ctx, cAsFuncInterp, zeroArgs, threeNumeral); // Add [1] = 4 - Z3_ast_vector oneArgs = Z3_mk_ast_vector(ctx); + oneArgs = Z3_mk_ast_vector(ctx); Z3_ast_vector_inc_ref(ctx, oneArgs); Z3_ast_vector_push(ctx, oneArgs, oneNumeral); Z3_func_interp_add_entry(ctx, cAsFuncInterp, oneArgs, fourNumeral); @@ -2925,82 +2940,89 @@ void mk_model_example() { // Now use the `(_ as_array)` to associate // the `cAsFuncInterp` with the `cFuncDecl` // in the model - Z3_ast cFuncDeclAsArray = Z3_mk_as_array(ctx, cAsFuncDecl); + cFuncDeclAsArray = Z3_mk_as_array(ctx, cAsFuncDecl); Z3_add_const_interp(ctx, m, cFuncDecl, cFuncDeclAsArray); // Print the model - Z3_string modelAsString = Z3_model_to_string(ctx, m); + modelAsString = Z3_model_to_string(ctx, m); printf("Model:\n%s\n", modelAsString); // Check the interpretations we expect to be present // are. - Z3_func_decl expectedInterpretations[] = {aFuncDecl, bFuncDecl, cFuncDecl}; - for (int index = 0; - index < sizeof(expectedInterpretations) / sizeof(Z3_func_decl); - ++index) { - Z3_func_decl d = expectedInterpretations[index]; - if (Z3_model_has_interp(ctx, m, d)) { - printf("Found interpretation for \"%s\"\n", - Z3_ast_to_string(ctx, Z3_func_decl_to_ast(ctx, d))); - } else { - printf("Missing interpretation"); + { + Z3_func_decl expectedInterpretations[] = {aFuncDecl, bFuncDecl, cFuncDecl}; + for (int index = 0; + index < sizeof(expectedInterpretations) / sizeof(Z3_func_decl); + ++index) { + Z3_func_decl d = expectedInterpretations[index]; + if (Z3_model_has_interp(ctx, m, d)) { + printf("Found interpretation for \"%s\"\n", + Z3_ast_to_string(ctx, Z3_func_decl_to_ast(ctx, d))); + } else { + printf("Missing interpretation"); + exit(1); + } + } + } + + { + // Evaluate a + b under model + Z3_ast addArgs[] = {aApp, bApp}; + Z3_ast aPlusB = Z3_mk_add(ctx, + /*num_args=*/2, + /*args=*/addArgs); + Z3_ast aPlusBEval = NULL; + Z3_bool aPlusBEvalSuccess = + Z3_model_eval(ctx, m, aPlusB, + /*model_completion=*/Z3_FALSE, &aPlusBEval); + if (aPlusBEvalSuccess != Z3_TRUE) { + printf("Failed to evaluate model\n"); + exit(1); + } + + int aPlusBValue = 0; + Z3_bool getAPlusBValueSuccess = + Z3_get_numeral_int(ctx, aPlusBEval, &aPlusBValue); + if (getAPlusBValueSuccess != Z3_TRUE) { + printf("Failed to get integer value for a+b\n"); + exit(1); + } + printf("Evaluated a + b = %d\n", aPlusBValue); + if (aPlusBValue != 3) { + printf("a+b did not evaluate to expected value\n"); exit(1); } } - // Evaluate a + b under model - Z3_ast addArgs[] = {aApp, bApp}; - Z3_ast aPlusB = Z3_mk_add(ctx, - /*num_args=*/2, - /*args=*/addArgs); - Z3_ast aPlusBEval = NULL; - Z3_bool aPlusBEvalSuccess = - Z3_model_eval(ctx, m, aPlusB, - /*model_completion=*/Z3_FALSE, &aPlusBEval); - if (aPlusBEvalSuccess != Z3_TRUE) { - printf("Failed to evaluate model\n"); - exit(1); - } - int aPlusBValue = 0; - Z3_bool getAPlusBValueSuccess = - Z3_get_numeral_int(ctx, aPlusBEval, &aPlusBValue); - if (getAPlusBValueSuccess != Z3_TRUE) { - printf("Failed to get integer value for a+b\n"); - exit(1); - } - printf("Evaluated a + b = %d\n", aPlusBValue); - if (aPlusBValue != 3) { - printf("a+b did not evaluate to expected value\n"); - exit(1); - } - - // Evaluate c[0] + c[1] + c[2] under model - Z3_ast c0 = Z3_mk_select(ctx, cApp, zeroNumeral); - Z3_ast c1 = Z3_mk_select(ctx, cApp, oneNumeral); - Z3_ast c2 = Z3_mk_select(ctx, cApp, twoNumeral); - Z3_ast arrayAddArgs[] = {c0, c1, c2}; - Z3_ast arrayAdd = Z3_mk_add(ctx, - /*num_args=*/3, - /*args=*/arrayAddArgs); - Z3_ast arrayAddEval = NULL; - Z3_bool arrayAddEvalSuccess = - Z3_model_eval(ctx, m, arrayAdd, - /*model_completion=*/Z3_FALSE, &arrayAddEval); - if (arrayAddEvalSuccess != Z3_TRUE) { - printf("Failed to evaluate model\n"); - exit(1); - } - int arrayAddValue = 0; - Z3_bool getArrayAddValueSuccess = - Z3_get_numeral_int(ctx, arrayAddEval, &arrayAddValue); - if (getArrayAddValueSuccess != Z3_TRUE) { - printf("Failed to get integer value for c[0] + c[1] + c[2]\n"); - exit(1); - } - printf("Evaluated c[0] + c[1] + c[2] = %d\n", arrayAddValue); - if (arrayAddValue != 7) { - printf("c[0] + c[1] + c[2] did not evaluate to expected value\n"); - exit(1); + { + // Evaluate c[0] + c[1] + c[2] under model + Z3_ast c0 = Z3_mk_select(ctx, cApp, zeroNumeral); + Z3_ast c1 = Z3_mk_select(ctx, cApp, oneNumeral); + Z3_ast c2 = Z3_mk_select(ctx, cApp, twoNumeral); + Z3_ast arrayAddArgs[] = {c0, c1, c2}; + Z3_ast arrayAdd = Z3_mk_add(ctx, + /*num_args=*/3, + /*args=*/arrayAddArgs); + Z3_ast arrayAddEval = NULL; + Z3_bool arrayAddEvalSuccess = + Z3_model_eval(ctx, m, arrayAdd, + /*model_completion=*/Z3_FALSE, &arrayAddEval); + if (arrayAddEvalSuccess != Z3_TRUE) { + printf("Failed to evaluate model\n"); + exit(1); + } + int arrayAddValue = 0; + Z3_bool getArrayAddValueSuccess = + Z3_get_numeral_int(ctx, arrayAddEval, &arrayAddValue); + if (getArrayAddValueSuccess != Z3_TRUE) { + printf("Failed to get integer value for c[0] + c[1] + c[2]\n"); + exit(1); + } + printf("Evaluated c[0] + c[1] + c[2] = %d\n", arrayAddValue); + if (arrayAddValue != 7) { + printf("c[0] + c[1] + c[2] did not evaluate to expected value\n"); + exit(1); + } } Z3_ast_vector_dec_ref(ctx, oneArgs); @@ -3009,7 +3031,6 @@ void mk_model_example() { Z3_model_dec_ref(ctx, m); Z3_del_context(ctx); } -#endif /*@}*/ /*@}*/ @@ -3059,6 +3080,6 @@ int main() { substitute_example(); substitute_vars_example(); fpa_example(); -// mk_model_example(); + mk_model_example(); return 0; } From fc73271b83c7ac0d0f55249363a07cc7f15da48e Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 11:20:56 -0700 Subject: [PATCH 480/488] more C fixes to model example Signed-off-by: Nikolaj Bjorner --- examples/c/test_capi.c | 53 +++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index d9db91c66..f6d515389 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2950,8 +2950,9 @@ void mk_model_example() { // Check the interpretations we expect to be present // are. { - Z3_func_decl expectedInterpretations[] = {aFuncDecl, bFuncDecl, cFuncDecl}; - for (int index = 0; + Z3_func_decl expectedInterpretations[3] = {aFuncDecl, bFuncDecl, cFuncDecl}; + int index; + for (index = 0; index < sizeof(expectedInterpretations) / sizeof(Z3_func_decl); ++index) { Z3_func_decl d = expectedInterpretations[index]; @@ -2980,17 +2981,19 @@ void mk_model_example() { exit(1); } - int aPlusBValue = 0; - Z3_bool getAPlusBValueSuccess = - Z3_get_numeral_int(ctx, aPlusBEval, &aPlusBValue); - if (getAPlusBValueSuccess != Z3_TRUE) { - printf("Failed to get integer value for a+b\n"); - exit(1); - } - printf("Evaluated a + b = %d\n", aPlusBValue); - if (aPlusBValue != 3) { - printf("a+b did not evaluate to expected value\n"); - exit(1); + { + int aPlusBValue = 0; + Z3_bool getAPlusBValueSuccess = + Z3_get_numeral_int(ctx, aPlusBEval, &aPlusBValue); + if (getAPlusBValueSuccess != Z3_TRUE) { + printf("Failed to get integer value for a+b\n"); + exit(1); + } + printf("Evaluated a + b = %d\n", aPlusBValue); + if (aPlusBValue != 3) { + printf("a+b did not evaluate to expected value\n"); + exit(1); + } } } @@ -3011,17 +3014,19 @@ void mk_model_example() { printf("Failed to evaluate model\n"); exit(1); } - int arrayAddValue = 0; - Z3_bool getArrayAddValueSuccess = - Z3_get_numeral_int(ctx, arrayAddEval, &arrayAddValue); - if (getArrayAddValueSuccess != Z3_TRUE) { - printf("Failed to get integer value for c[0] + c[1] + c[2]\n"); - exit(1); - } - printf("Evaluated c[0] + c[1] + c[2] = %d\n", arrayAddValue); - if (arrayAddValue != 7) { - printf("c[0] + c[1] + c[2] did not evaluate to expected value\n"); - exit(1); + { + int arrayAddValue = 0; + Z3_bool getArrayAddValueSuccess = + Z3_get_numeral_int(ctx, arrayAddEval, &arrayAddValue); + if (getArrayAddValueSuccess != Z3_TRUE) { + printf("Failed to get integer value for c[0] + c[1] + c[2]\n"); + exit(1); + } + printf("Evaluated c[0] + c[1] + c[2] = %d\n", arrayAddValue); + if (arrayAddValue != 7) { + printf("c[0] + c[1] + c[2] did not evaluate to expected value\n"); + exit(1); + } } } From 0589a20b46b0edd486dbc0b4d7113d2b048598ef Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 19:24:45 -0700 Subject: [PATCH 481/488] fix #1326 Signed-off-by: Nikolaj Bjorner --- src/opt/maxres.cpp | 14 ++++++++------ src/opt/opt_context.cpp | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/opt/maxres.cpp b/src/opt/maxres.cpp index e708788f6..3707e5aeb 100644 --- a/src/opt/maxres.cpp +++ b/src/opt/maxres.cpp @@ -229,6 +229,7 @@ public: } lbool primal_dual_solver() { + std::cout << "pd\n"; if (!init()) return l_undef; lbool is_sat = init_local(); trace(); @@ -315,14 +316,13 @@ public: void found_optimum() { IF_VERBOSE(1, verbose_stream() << "found optimum\n";); - rational upper(0); + m_lower.reset(); for (unsigned i = 0; i < m_soft.size(); ++i) { m_assignment[i] = is_true(m_soft[i]); if (!m_assignment[i]) { - upper += m_weights[i]; + m_lower += m_weights[i]; } } - SASSERT(upper == m_lower); m_upper = m_lower; m_found_feasible_optimum = true; } @@ -397,10 +397,11 @@ public: void get_current_correction_set(model* mdl, exprs& cs) { cs.reset(); if (!mdl) return; - for (unsigned i = 0; i < m_asms.size(); ++i) { - if (is_false(mdl, m_asms[i].get())) { - cs.push_back(m_asms[i].get()); + for (expr* a : m_asms) { + if (is_false(mdl, a)) { + cs.push_back(a); } + TRACE("opt", expr_ref tmp(m); mdl->eval(a, tmp, true); tout << mk_pp(a, m) << ": " << tmp << "\n";); } TRACE("opt", display_vec(tout << "new correction set: ", cs);); } @@ -509,6 +510,7 @@ public: trace(); if (m_c.num_objectives() == 1 && m_pivot_on_cs && m_csmodel.get() && m_correction_set_size < core.size()) { exprs cs; + TRACE("opt", tout << "cs " << m_correction_set_size << " " << core.size() << "\n";); get_current_correction_set(m_csmodel.get(), cs); m_correction_set_size = cs.size(); if (m_correction_set_size < core.size()) { diff --git a/src/opt/opt_context.cpp b/src/opt/opt_context.cpp index 2b31e243c..8d73ea7c8 100644 --- a/src/opt/opt_context.cpp +++ b/src/opt/opt_context.cpp @@ -819,7 +819,7 @@ namespace opt { bool is_max = is_maximize(fml, term, orig_term, index); bool is_min = !is_max && is_minimize(fml, term, orig_term, index); if (is_min && get_pb_sum(term, terms, weights, offset)) { - TRACE("opt", tout << "try to convert minimization" << mk_pp(term, m) << "\n";); + TRACE("opt", tout << "try to convert minimization\n" << mk_pp(term, m) << "\n";); // minimize 2*x + 3*y // <=> // (assert-soft (not x) 2) From e7aa6455bce9ef77d6fcfcd1dcb2c31aa225e59c Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 19:25:25 -0700 Subject: [PATCH 482/488] fix #1326 Signed-off-by: Nikolaj Bjorner --- src/opt/maxres.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/opt/maxres.cpp b/src/opt/maxres.cpp index 3707e5aeb..b06773223 100644 --- a/src/opt/maxres.cpp +++ b/src/opt/maxres.cpp @@ -229,7 +229,6 @@ public: } lbool primal_dual_solver() { - std::cout << "pd\n"; if (!init()) return l_undef; lbool is_sat = init_local(); trace(); From c886b6d50033daa6a5a0c2ebe953dc56452d91cf Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 25 Oct 2017 20:53:10 -0700 Subject: [PATCH 483/488] fix #1330. Interpolation transformation needs to handle TRANSITIVITY_STAR Signed-off-by: Nikolaj Bjorner --- src/interp/iz3mgr.h | 24 ++++++++++++------------ src/interp/iz3translate.cpp | 17 +++++++++++++++++ src/interp/iz3translate.h | 2 +- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/interp/iz3mgr.h b/src/interp/iz3mgr.h index e4c294059..0ad751326 100755 --- a/src/interp/iz3mgr.h +++ b/src/interp/iz3mgr.h @@ -57,12 +57,12 @@ typedef ast raw_ast; /** Wrapper around an ast pointer */ class ast_i { - protected: +protected: raw_ast *_ast; - public: +public: raw_ast * const &raw() const {return _ast;} ast_i(raw_ast *a){_ast = a;} - + ast_i(){_ast = 0;} bool eq(const ast_i &other) const { return _ast == other._ast; @@ -86,19 +86,19 @@ class ast_i { /** Reference counting verison of above */ class ast_r : public ast_i { ast_manager *_m; - public: - ast_r(ast_manager *m, raw_ast *a) : ast_i(a) { +public: + ast_r(ast_manager *m, raw_ast *a) : ast_i(a) { _m = m; m->inc_ref(a); } - + ast_r() {_m = 0;} - - ast_r(const ast_r &other) : ast_i(other) { + + ast_r(const ast_r &other) : ast_i(other) { _m = other._m; if (_m) _m->inc_ref(_ast); } - + ast_r &operator=(const ast_r &other) { if(_ast) _m->dec_ref(_ast); @@ -107,12 +107,12 @@ class ast_r : public ast_i { if (_m) _m->inc_ref(_ast); return *this; } - - ~ast_r(){ + + ~ast_r() { if(_ast) _m->dec_ref(_ast); } - + ast_manager *mgr() const {return _m;} }; diff --git a/src/interp/iz3translate.cpp b/src/interp/iz3translate.cpp index c59dd0178..e4730ea63 100755 --- a/src/interp/iz3translate.cpp +++ b/src/interp/iz3translate.cpp @@ -29,6 +29,7 @@ #include "interp/iz3profiling.h" #include "interp/iz3interp.h" #include "interp/iz3proof_itp.h" +#include "ast/ast_pp.h" #include #include @@ -1851,6 +1852,21 @@ public: } break; } + case PR_TRANSITIVITY_STAR: { + // assume the premises are x = y, y = z, z = u, u = v, .. + + ast x = arg(conc(prem(proof,0)),0); + ast y = arg(conc(prem(proof,0)),1); + ast z = arg(conc(prem(proof,1)),1); + res = iproof->make_transitivity(x,y,z,args[0],args[1]); + + for (unsigned i = 2; i < nprems; ++i) { + y = z; + z = arg(conc(prem(proof,i)),1); + res = iproof->make_transitivity(x,y,z,res,args[i]); + } + break; + } case PR_QUANT_INTRO: case PR_MONOTONICITY: { @@ -2029,6 +2045,7 @@ public: break; } default: + IF_VERBOSE(0, verbose_stream() << "Unsupported proof rule: " << expr_ref((expr*)proof.raw(), *proof.mgr()) << "\n";); // pfgoto(proof); // SASSERT(0 && "translate_main: unsupported proof rule"); throw unsupported(); diff --git a/src/interp/iz3translate.h b/src/interp/iz3translate.h index 519a252e0..8ecafbd3a 100755 --- a/src/interp/iz3translate.h +++ b/src/interp/iz3translate.h @@ -36,7 +36,7 @@ class iz3translation : public iz3base { /** This is thrown when the proof cannot be translated. */ struct unsupported: public iz3_exception { - unsupported(): iz3_exception("unsupported") {} + unsupported(): iz3_exception("unsupported") { } }; static iz3translation *create(iz3mgr &mgr, From e4b595d490dcad056b8afe5ffaadf71eb35a4357 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 28 Oct 2017 16:10:20 -0700 Subject: [PATCH 484/488] add solver pool abstraction for Spacer Signed-off-by: Nikolaj Bjorner --- src/ast/ast_smt2_pp.cpp | 1 + src/muz/spacer/spacer_util.h | 9 - src/muz/spacer/spacer_virtual_solver.cpp | 9 +- src/opt/opt_solver.cpp | 3 +- src/sat/sat_solver/inc_sat_solver.cpp | 6 +- src/smt/smt_solver.cpp | 13 +- src/solver/CMakeLists.txt | 1 + src/solver/solver.cpp | 3 +- src/solver/solver.h | 10 +- src/solver/solver_pool.cpp | 320 ++++++++++++++++++ src/solver/solver_pool.h | 69 ++++ src/solver/tactic2solver.cpp | 7 +- .../portfolio/bounded_int2bv_solver.cpp | 5 +- src/tactic/portfolio/enum2bv_solver.cpp | 5 +- src/tactic/portfolio/pb2bv_solver.cpp | 5 +- src/util/stopwatch.h | 11 + 16 files changed, 435 insertions(+), 42 deletions(-) create mode 100644 src/solver/solver_pool.cpp create mode 100644 src/solver/solver_pool.h diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index e4a875005..0139cb0f0 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -44,6 +44,7 @@ format * smt2_pp_environment::pp_fdecl_name(symbol const & s, unsigned & len) co return mk_string(m, str.c_str()); } else if (!s.bare_str()) { + len = 4; return mk_string(m, "null"); } else { diff --git a/src/muz/spacer/spacer_util.h b/src/muz/spacer/spacer_util.h index 546b7df5b..7fb17329e 100644 --- a/src/muz/spacer/spacer_util.h +++ b/src/muz/spacer/spacer_util.h @@ -74,15 +74,6 @@ inline std::ostream& operator<<(std::ostream& out, pp_level const& p) } -struct scoped_watch { - stopwatch &m_sw; - scoped_watch (stopwatch &sw, bool reset=false): m_sw(sw) - { - if(reset) { m_sw.reset(); } - m_sw.start (); - } - ~scoped_watch () {m_sw.stop ();} -}; typedef ptr_vector app_vector; diff --git a/src/muz/spacer/spacer_virtual_solver.cpp b/src/muz/spacer/spacer_virtual_solver.cpp index 89b9fb531..938e8cb94 100644 --- a/src/muz/spacer/spacer_virtual_solver.cpp +++ b/src/muz/spacer/spacer_virtual_solver.cpp @@ -189,15 +189,16 @@ void virtual_solver::push_core() m_context.push(); } } -void virtual_solver::pop_core(unsigned n) -{ +void virtual_solver::pop_core(unsigned n) { SASSERT(!m_pushed || get_scope_level() > 0); if (m_pushed) { SASSERT(!m_in_delay_scope); m_context.pop(n); m_pushed = get_scope_level() - n > 0; - } else - { m_in_delay_scope = get_scope_level() - n > 0; } + } + else { + m_in_delay_scope = get_scope_level() - n > 0; + } } void virtual_solver::get_unsat_core(ptr_vector &r) diff --git a/src/opt/opt_solver.cpp b/src/opt/opt_solver.cpp index 69b62083f..49b48e68f 100644 --- a/src/opt/opt_solver.cpp +++ b/src/opt/opt_solver.cpp @@ -47,8 +47,9 @@ namespace opt { m_dump_benchmarks(false), m_first(true), m_was_unknown(false) { + solver::updt_params(p); m_params.updt_params(p); - if (m_params.m_case_split_strategy == CS_ACTIVITY_DELAY_NEW) { + if (m_params.m_case_split_strategy == CS_ACTIVITY_DELAY_NEW) { m_params.m_relevancy_lvl = 0; } // m_params.m_auto_config = false; diff --git a/src/sat/sat_solver/inc_sat_solver.cpp b/src/sat/sat_solver/inc_sat_solver.cpp index be418cbc4..191c49294 100644 --- a/src/sat/sat_solver/inc_sat_solver.cpp +++ b/src/sat/sat_solver/inc_sat_solver.cpp @@ -69,7 +69,7 @@ class inc_sat_solver : public solver { public: inc_sat_solver(ast_manager& m, params_ref const& p): m(m), m_solver(p, m.limit(), 0), - m_params(p), m_optimize_model(false), + m_optimize_model(false), m_fmls(m), m_asmsf(m), m_fmls_head(0), @@ -79,7 +79,7 @@ public: m_dep_core(m), m_unknown("no reason given") { m_params.set_bool("elim_vars", false); - m_solver.updt_params(m_params); + updt_params(p); init_preprocess(); } @@ -237,7 +237,7 @@ public: sat::solver::collect_param_descrs(r); } virtual void updt_params(params_ref const & p) { - m_params = p; + solver::updt_params(p); m_params.set_bool("elim_vars", false); m_solver.updt_params(m_params); m_optimize_model = m_params.get_bool("optimize_model", false); diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index d624a5c9a..539640913 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -31,7 +31,6 @@ namespace smt { class solver : public solver_na2as { smt_params m_smt_params; - params_ref m_params; smt::kernel m_context; progress_callback * m_callback; symbol m_logic; @@ -45,19 +44,15 @@ namespace smt { solver(ast_manager & m, params_ref const & p, symbol const & l) : solver_na2as(m), m_smt_params(p), - m_params(p), m_context(m, m_smt_params), m_minimizing_core(false), m_core_extend_patterns(false), m_core_extend_patterns_max_distance(UINT_MAX), - m_core_extend_nonlocal_patterns(false) { + m_core_extend_nonlocal_patterns(false) { m_logic = l; if (m_logic != symbol::null) m_context.set_logic(m_logic); - smt_params_helper smth(p); - m_core_extend_patterns = smth.core_extend_patterns(); - m_core_extend_patterns_max_distance = smth.core_extend_patterns_max_distance(); - m_core_extend_nonlocal_patterns = smth.core_extend_nonlocal_patterns(); + updt_params(p); } virtual solver * translate(ast_manager & m, params_ref const & p) { @@ -78,8 +73,8 @@ namespace smt { } virtual void updt_params(params_ref const & p) { + solver::updt_params(p); m_smt_params.updt_params(p); - m_params.copy(p); m_context.updt_params(p); smt_params_helper smth(p); m_core_extend_patterns = smth.core_extend_patterns(); @@ -165,7 +160,7 @@ namespace smt { r.push_back(m_context.get_unsat_core_expr(i)); } - if (m_minimizing_core && smt_params_helper(m_params).core_minimize()) { + if (m_minimizing_core && smt_params_helper(get_params()).core_minimize()) { scoped_minimize_core scm(*this); mus mus(*this); mus.add_soft(r.size(), r.c_ptr()); diff --git a/src/solver/CMakeLists.txt b/src/solver/CMakeLists.txt index 56864a691..1ffdc35e1 100644 --- a/src/solver/CMakeLists.txt +++ b/src/solver/CMakeLists.txt @@ -6,6 +6,7 @@ z3_add_component(solver smt_logics.cpp solver.cpp solver_na2as.cpp + solver_pool.cpp solver2tactic.cpp tactic2solver.cpp COMPONENT_DEPENDENCIES diff --git a/src/solver/solver.cpp b/src/solver/solver.cpp index cb7864268..bf53cb669 100644 --- a/src/solver/solver.cpp +++ b/src/solver/solver.cpp @@ -34,11 +34,12 @@ expr * solver::get_assertion(unsigned idx) const { return 0; } -std::ostream& solver::display(std::ostream & out) const { +std::ostream& solver::display(std::ostream & out, unsigned n, expr* const* assumptions) const { expr_ref_vector fmls(get_manager()); get_assertions(fmls); ast_pp_util visitor(get_manager()); visitor.collect(fmls); + visitor.collect(n, assumptions); visitor.display_decls(out); visitor.display_asserts(out, fmls, true); return out; diff --git a/src/solver/solver.h b/src/solver/solver.h index 00e3cf8e9..0a406455b 100644 --- a/src/solver/solver.h +++ b/src/solver/solver.h @@ -43,6 +43,7 @@ public: - results based on check_sat_result API */ class solver : public check_sat_result { + params_ref m_params; public: virtual ~solver() {} @@ -54,7 +55,12 @@ public: /** \brief Update the solver internal settings. */ - virtual void updt_params(params_ref const & p) { } + virtual void updt_params(params_ref const & p) { m_params.copy(p); } + + /** + \brief Retrieve set of parameters set on solver. + */ + virtual params_ref const& get_params() { return m_params; } /** \brief Store in \c r a description of the configuration @@ -175,7 +181,7 @@ public: /** \brief Display the content of this solver. */ - virtual std::ostream& display(std::ostream & out) const; + virtual std::ostream& display(std::ostream & out, unsigned n = 0, expr* const* assumptions = nullptr) const; class scoped_push { solver& s; diff --git a/src/solver/solver_pool.cpp b/src/solver/solver_pool.cpp new file mode 100644 index 000000000..c6c85ec29 --- /dev/null +++ b/src/solver/solver_pool.cpp @@ -0,0 +1,320 @@ +/** +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + solver_pool.cpp + +Abstract: + + Maintain a pool of solvers + +Author: + + Nikolaj Bjorner + +Notes: + +--*/ + +#include "solver/solver_pool.h" +#include "solver/solver_na2as.h" +#include "ast/proofs/proof_utils.h" +#include "ast/ast_util.h" + +class pool_solver : public solver_na2as { + solver_pool& m_pool; + app_ref m_pred; + proof_ref m_proof; + ref m_base; + expr_ref_vector m_assertions; + unsigned m_head; + expr_ref_vector m_flat; + bool m_pushed; + bool m_in_delayed_scope; + unsigned m_dump_counter; + + bool is_virtual() const { return !m.is_true(m_pred); } +public: + pool_solver(solver* b, solver_pool& pool, app_ref& pred): + solver_na2as(pred.get_manager()), + m_pool(pool), + m_pred(pred), + m_proof(m), + m_base(b), + m_assertions(m), + m_head(0), + m_flat(m), + m_pushed(false), + m_in_delayed_scope(false), + m_dump_counter(0) { + if (is_virtual()) { + solver_na2as::assert_expr(m.mk_true(), pred); + } + } + + virtual ~pool_solver() { + if (m_pushed) pop(get_scope_level()); + if (is_virtual()) { + m_pred = m.mk_not(m_pred); + m_base->assert_expr(m_pred); + } + } + + solver* base_solver() { return m_base.get(); } + + virtual solver* translate(ast_manager& m, params_ref const& p) { UNREACHABLE(); return nullptr; } + virtual void updt_params(params_ref const& p) { solver::updt_params(p); m_base->updt_params(p); } + virtual void collect_param_descrs(param_descrs & r) { m_base->collect_param_descrs(r); } + virtual void collect_statistics(statistics & st) const { m_base->collect_statistics(st); } + + virtual void get_unsat_core(ptr_vector & r) { + m_base->get_unsat_core(r); + unsigned j = 0; + for (unsigned i = 0; i < r.size(); ++i) + if (m_pred != r[i]) + r[j++] = r[i]; + r.shrink(j); + } + + virtual unsigned get_num_assumptions() const { + unsigned sz = solver_na2as::get_num_assumptions(); + return is_virtual() ? sz - 1 : sz; + } + + virtual proof * get_proof() { + scoped_watch _t_(m_pool.m_proof_watch); + if (!m_proof.get()) { + elim_aux_assertions pc(m_pred); + m_proof = m_base->get_proof(); + pc(m, m_proof, m_proof); + } + return m_proof; + } + + void internalize_assertions() { + SASSERT(!m_pushed || m_head == m_assertions.size()); + for (unsigned sz = m_assertions.size(); m_head < sz; ++m_head) { + expr_ref f(m); + f = m.mk_implies(m_pred, (m_assertions.get(m_head))); + m_base->assert_expr(f); + } + } + + virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) { + SASSERT(!m_pushed || get_scope_level() > 0); + m_proof.reset(); + scoped_watch _t_(m_pool.m_check_watch); + m_pool.m_stats.m_num_checks++; + + stopwatch sw; + sw.start(); + internalize_assertions(); + lbool res = m_base->check_sat(num_assumptions, assumptions); + sw.stop(); + switch (res) { + case l_true: + m_pool.m_check_sat_watch.add(sw); + m_pool.m_stats.m_num_sat_checks++; + break; + case l_undef: + m_pool.m_check_undef_watch.add(sw); + m_pool.m_stats.m_num_undef_checks++; + break; + default: + break; + } + set_status(res); + + if (false /*m_dump_benchmarks && sw.get_seconds() >= m_pool.fparams().m_dump_min_time*/) { + std::stringstream file_name; + file_name << "virt_solver"; + if (is_virtual()) { file_name << "_" << m_pred->get_decl()->get_name(); } + file_name << "_" << (m_dump_counter++) << ".smt2"; + + std::ofstream out(file_name.str().c_str()); + if (!out) { verbose_stream() << "could not open file " << file_name.str() << " for output\n"; } + + out << "(set-info :status "; + switch (res) { + case l_true: out << "sat"; break; + case l_false: out << "unsat"; break; + case l_undef: out << "unknown"; break; + } + out << ")\n"; + m_base->display(out, num_assumptions, assumptions); + bool first = true; + out << "(check-sat"; + for (unsigned i = 0; i < num_assumptions; ++i) { + out << " " << mk_pp(assumptions[i], m); + } + out << ")"; + out << "(exit)\n"; + ::statistics st; + m_base->collect_statistics(st); + st.update("time", sw.get_seconds()); + st.display_smt2(out); + out.close(); + } + return res; + } + + virtual void push_core() { + SASSERT(!m_pushed || get_scope_level() > 0); + if (m_in_delayed_scope) { + // second push + internalize_assertions(); + m_base->push(); + m_pushed = true; + m_in_delayed_scope = false; + } + + if (!m_pushed) { + m_in_delayed_scope = true; + } + else { + SASSERT(m_pushed); + SASSERT(!m_in_delayed_scope); + m_base->push(); + } + } + + virtual void pop_core(unsigned n) { + SASSERT(!m_pushed || get_scope_level() > 0); + if (m_pushed) { + SASSERT(!m_in_delayed_scope); + m_base->pop(n); + m_pushed = get_scope_level() - n > 0; + } + else { + m_in_delayed_scope = get_scope_level() - n > 0; + } + } + + virtual void assert_expr(expr * e) { + SASSERT(!m_pushed || get_scope_level() > 0); + if (m.is_true(e)) return; + if (m_in_delayed_scope) { + internalize_assertions(); + m_base->push(); + m_pushed = true; + m_in_delayed_scope = false; + } + + if (m_pushed) { + m_base->assert_expr(e); + } + else { + m_flat.push_back(e); + flatten_and(m_flat); + m_assertions.append(m_flat); + m_flat.reset(); + } + } + + virtual void get_model(model_ref & _m) { m_base->get_model(_m); } + + virtual expr * get_assumption(unsigned idx) const { + return solver_na2as::get_assumption(idx + is_virtual()); + } + + virtual std::string reason_unknown() const { return m_base->reason_unknown(); } + virtual void set_reason_unknown(char const* msg) { return m_base->set_reason_unknown(msg); } + virtual void get_labels(svector & r) { return m_base->get_labels(r); } + virtual void set_progress_callback(progress_callback * callback) { m_base->set_progress_callback(callback); } + + virtual ast_manager& get_manager() const { return m_base->get_manager(); } + + void refresh(solver* new_base) { + SASSERT(!m_pushed); + m_head = 0; + m_base = new_base; + } + + void reset() { + SASSERT(!m_pushed); + m_head = 0; + m_assertions.reset(); + m_pool.refresh(m_base.get()); + } +}; + +solver_pool::solver_pool(solver* base_solver, unsigned num_solvers_per_pool): + m_base_solver(base_solver), + m_num_solvers_per_pool(num_solvers_per_pool), + m_num_solvers_in_last_pool(0) +{} + + +ptr_vector solver_pool::get_base_solvers() const { + ptr_vector solvers; + for (solver* s0 : m_solvers) { + pool_solver* s = dynamic_cast(s0); + if (!solvers.contains(s->base_solver())) { + solvers.push_back(s->base_solver()); + } + } + return solvers; +} + +void solver_pool::collect_statistics(statistics &st) const { + ptr_vector solvers = get_base_solvers(); + for (solver* s : solvers) s->collect_statistics(st); + st.update("time.pool_solver.smt.total", m_check_watch.get_seconds()); + st.update("time.pool_solver.smt.total.sat", m_check_sat_watch.get_seconds()); + st.update("time.pool_solver.smt.total.undef", m_check_undef_watch.get_seconds()); + st.update("time.pool_solver.proof", m_proof_watch.get_seconds()); + st.update("pool_solver.checks", m_stats.m_num_checks); + st.update("pool_solver.checks.sat", m_stats.m_num_sat_checks); + st.update("pool_solver.checks.undef", m_stats.m_num_undef_checks); +} + +void solver_pool::reset_statistics() { +#if 0 + ptr_vector solvers = get_base_solvers(); + for (solver* s : solvers) { + s->reset_statistics(); + } +#endif + m_stats.reset(); + m_check_sat_watch.reset(); + m_check_undef_watch.reset(); + m_check_watch.reset(); + m_proof_watch.reset(); +} + +solver* solver_pool::mk_solver() { + ref base_solver; + ast_manager& m = m_base_solver->get_manager(); + if (m_solvers.empty() || m_num_solvers_in_last_pool == m_num_solvers_per_pool) { + base_solver = m_base_solver->translate(m, m_base_solver->get_params()); + m_num_solvers_in_last_pool = 0; + } + else { + base_solver = dynamic_cast(m_solvers.back())->base_solver(); + } + m_num_solvers_in_last_pool++; + std::stringstream name; + name << "vsolver#" << m_solvers.size(); + app_ref pred(m.mk_const(symbol(name.str().c_str()), m.mk_bool_sort()), m); + pool_solver* solver = alloc(pool_solver, base_solver.get(), *this, pred); + m_solvers.push_back(solver); + return solver; +} + +void solver_pool::reset_solver(solver* s) { + pool_solver* ps = dynamic_cast(s); + SASSERT(ps); + if (ps) ps->reset(); +} + +void solver_pool::refresh(solver* base_solver) { + ast_manager& m = m_base_solver->get_manager(); + ref new_base = m_base_solver->translate(m, m_base_solver->get_params()); + for (solver* s0 : m_solvers) { + pool_solver* s = dynamic_cast(s0); + if (base_solver == s->base_solver()) { + s->refresh(new_base.get()); + } + } +} diff --git a/src/solver/solver_pool.h b/src/solver/solver_pool.h new file mode 100644 index 000000000..d676ca54d --- /dev/null +++ b/src/solver/solver_pool.h @@ -0,0 +1,69 @@ +/** +Copyright (c) 2017 Microsoft Corporation + +Module Name: + + solver_pool.h + +Abstract: + + Maintain a pool of solvers + +Author: + + Nikolaj Bjorner + Arie Gurfinkel + +Notes: + + This is a revision of spacer_virtual_solver by Arie Gurfinkel + +--*/ +#ifndef SOLVER_POOL_H_ +#define SOLVER_POOL_H_ + +#include "solver/solver.h" +#include "util/stopwatch.h" + +class pool_solver; + +class solver_pool { + + friend class pool_solver; + + struct stats { + unsigned m_num_checks; + unsigned m_num_sat_checks; + unsigned m_num_undef_checks; + stats() { reset(); } + void reset() { memset(this, 0, sizeof(*this)); } + }; + + ref m_base_solver; + unsigned m_num_solvers_per_pool; + unsigned m_num_solvers_in_last_pool; + sref_vector m_solvers; + stats m_stats; + + stopwatch m_check_watch; + stopwatch m_check_sat_watch; + stopwatch m_check_undef_watch; + stopwatch m_proof_watch; + + void refresh(solver* s); + + ptr_vector get_base_solvers() const; + +public: + solver_pool(solver* base_solver, unsigned num_solvers_per_pool); + + void collect_statistics(statistics &st) const; + void reset_statistics(); + + solver* mk_solver(); + + void reset_solver(solver* s); +}; + + +#endif diff --git a/src/solver/tactic2solver.cpp b/src/solver/tactic2solver.cpp index d7e7fbb6e..a24f1d4c7 100644 --- a/src/solver/tactic2solver.cpp +++ b/src/solver/tactic2solver.cpp @@ -37,7 +37,6 @@ class tactic2solver : public solver_na2as { ref m_result; tactic_ref m_tactic; symbol m_logic; - params_ref m_params; bool m_produce_models; bool m_produce_proofs; bool m_produce_unsat_cores; @@ -85,7 +84,7 @@ tactic2solver::tactic2solver(ast_manager & m, tactic * t, params_ref const & p, m_tactic = t; m_logic = logic; - m_params = p; + solver::updt_params(p); m_produce_models = produce_models; m_produce_proofs = produce_proofs; @@ -96,7 +95,7 @@ tactic2solver::~tactic2solver() { } void tactic2solver::updt_params(params_ref const & p) { - m_params.append(p); + solver::updt_params(p); } void tactic2solver::collect_param_descrs(param_descrs & r) { @@ -129,7 +128,7 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass m_result = alloc(simple_check_sat_result, m); m_tactic->cleanup(); m_tactic->set_logic(m_logic); - m_tactic->updt_params(m_params); // parameters are allowed to overwrite logic. + m_tactic->updt_params(get_params()); // parameters are allowed to overwrite logic. goal_ref g = alloc(goal, m, m_produce_proofs, m_produce_models, m_produce_unsat_cores); unsigned sz = m_assertions.size(); diff --git a/src/tactic/portfolio/bounded_int2bv_solver.cpp b/src/tactic/portfolio/bounded_int2bv_solver.cpp index 2f66d7a53..58078e106 100644 --- a/src/tactic/portfolio/bounded_int2bv_solver.cpp +++ b/src/tactic/portfolio/bounded_int2bv_solver.cpp @@ -33,7 +33,6 @@ Notes: class bounded_int2bv_solver : public solver_na2as { ast_manager& m; - params_ref m_params; mutable bv_util m_bv; mutable arith_util m_arith; mutable expr_ref_vector m_assertions; @@ -53,7 +52,6 @@ public: bounded_int2bv_solver(ast_manager& m, params_ref const& p, solver* s): solver_na2as(m), m(m), - m_params(p), m_bv(m), m_arith(m), m_assertions(m), @@ -63,6 +61,7 @@ public: m_rewriter_ctx(m, p), m_rewriter(m, m_rewriter_ctx) { + solver::updt_params(p); m_bounds.push_back(alloc(bound_manager, m)); } @@ -131,7 +130,7 @@ public: return m_solver->check_sat(num_assumptions, assumptions); } - virtual void updt_params(params_ref const & p) { m_solver->updt_params(p); } + virtual void updt_params(params_ref const & p) { solver::updt_params(p); m_solver->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { m_solver->collect_param_descrs(r); } virtual void set_produce_models(bool f) { m_solver->set_produce_models(f); } virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); } diff --git a/src/tactic/portfolio/enum2bv_solver.cpp b/src/tactic/portfolio/enum2bv_solver.cpp index 5880302d9..dd0ee7c4b 100644 --- a/src/tactic/portfolio/enum2bv_solver.cpp +++ b/src/tactic/portfolio/enum2bv_solver.cpp @@ -33,7 +33,6 @@ Notes: class enum2bv_solver : public solver_na2as { ast_manager& m; - params_ref m_params; ref m_solver; enum2bv_rewriter m_rewriter; @@ -42,10 +41,10 @@ public: enum2bv_solver(ast_manager& m, params_ref const& p, solver* s): solver_na2as(m), m(m), - m_params(p), m_solver(s), m_rewriter(m, p) { + solver::updt_params(p); } virtual ~enum2bv_solver() {} @@ -78,7 +77,7 @@ public: return m_solver->check_sat(num_assumptions, assumptions); } - virtual void updt_params(params_ref const & p) { m_solver->updt_params(p); } + virtual void updt_params(params_ref const & p) { solver::updt_params(p); m_solver->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { m_solver->collect_param_descrs(r); } virtual void set_produce_models(bool f) { m_solver->set_produce_models(f); } virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); } diff --git a/src/tactic/portfolio/pb2bv_solver.cpp b/src/tactic/portfolio/pb2bv_solver.cpp index 81cc43685..a06ff77c0 100644 --- a/src/tactic/portfolio/pb2bv_solver.cpp +++ b/src/tactic/portfolio/pb2bv_solver.cpp @@ -26,7 +26,6 @@ Notes: class pb2bv_solver : public solver_na2as { ast_manager& m; - params_ref m_params; mutable expr_ref_vector m_assertions; mutable ref m_solver; mutable pb2bv_rewriter m_rewriter; @@ -36,11 +35,11 @@ public: pb2bv_solver(ast_manager& m, params_ref const& p, solver* s): solver_na2as(m), m(m), - m_params(p), m_assertions(m), m_solver(s), m_rewriter(m, p) { + solver::updt_params(p); } virtual ~pb2bv_solver() {} @@ -70,7 +69,7 @@ public: return m_solver->check_sat(num_assumptions, assumptions); } - virtual void updt_params(params_ref const & p) { m_solver->updt_params(p); } + virtual void updt_params(params_ref const & p) { solver::updt_params(p); m_solver->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { m_solver->collect_param_descrs(r); } virtual void set_produce_models(bool f) { m_solver->set_produce_models(f); } virtual void set_progress_callback(progress_callback * callback) { m_solver->set_progress_callback(callback); } diff --git a/src/util/stopwatch.h b/src/util/stopwatch.h index 7f2ed3245..9ba707af0 100644 --- a/src/util/stopwatch.h +++ b/src/util/stopwatch.h @@ -185,4 +185,15 @@ public: #endif +struct scoped_watch { + stopwatch &m_sw; + scoped_watch (stopwatch &sw, bool reset=false): m_sw(sw) { + if (reset) m_sw.reset(); + m_sw.start(); + } + ~scoped_watch() { + m_sw.stop (); + } +}; + #endif From 60b970b9babafae7dfdaa888709f280c1cb82b32 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 28 Oct 2017 16:23:13 -0700 Subject: [PATCH 485/488] add proofs dependency to solver Signed-off-by: Nikolaj Bjorner --- scripts/mk_project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mk_project.py b/scripts/mk_project.py index 6e7024b3f..05190f217 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -37,13 +37,13 @@ def init_project_def(): add_lib('nlsat_tactic', ['nlsat', 'sat_tactic', 'arith_tactics'], 'nlsat/tactic') add_lib('subpaving_tactic', ['core_tactics', 'subpaving'], 'math/subpaving/tactic') add_lib('aig_tactic', ['tactic'], 'tactic/aig') - add_lib('solver', ['model', 'tactic']) + add_lib('proofs', ['rewriter', 'util'], 'ast/proofs') + add_lib('solver', ['model', 'tactic', 'proofs']) add_lib('ackermannization', ['model', 'rewriter', 'ast', 'solver', 'tactic'], 'ackermannization') add_lib('interp', ['solver']) add_lib('cmd_context', ['solver', 'rewriter', 'interp']) add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds') add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') - add_lib('proofs', ['rewriter', 'util'], 'ast/proofs') add_lib('fpa', ['ast', 'util', 'rewriter', 'model'], 'ast/fpa') add_lib('pattern', ['normal_forms', 'smt2parser', 'rewriter'], 'ast/pattern') add_lib('bit_blaster', ['rewriter', 'rewriter'], 'ast/rewriter/bit_blaster') From b556f3ca42491ba2b59ca86a051de36a699064fa Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 28 Oct 2017 16:41:29 -0700 Subject: [PATCH 486/488] fix stack overflow Signed-off-by: Nikolaj Bjorner --- src/smt/smt_solver.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index 539640913..1f9ad3ef7 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -29,7 +29,7 @@ Notes: namespace smt { - class solver : public solver_na2as { + class smt_solver : public solver_na2as { smt_params m_smt_params; smt::kernel m_context; progress_callback * m_callback; @@ -41,7 +41,7 @@ namespace smt { obj_map m_name2assertion; public: - solver(ast_manager & m, params_ref const & p, symbol const & l) : + smt_solver(ast_manager & m, params_ref const & p, symbol const & l) : solver_na2as(m), m_smt_params(p), m_context(m, m_smt_params), @@ -58,7 +58,7 @@ namespace smt { virtual solver * translate(ast_manager & m, params_ref const & p) { ast_translation translator(get_manager(), m); - solver * result = alloc(solver, m, p, m_logic); + smt_solver * result = alloc(smt_solver, m, p, m_logic); smt::kernel::copy(m_context, result->m_context); for (auto & kv : m_name2assertion) @@ -68,7 +68,7 @@ namespace smt { return result; } - virtual ~solver() { + virtual ~smt_solver() { dec_ref_values(get_manager(), m_name2assertion); } @@ -141,9 +141,9 @@ namespace smt { } struct scoped_minimize_core { - solver& s; + smt_solver& s; expr_ref_vector m_assumptions; - scoped_minimize_core(solver& s) : s(s), m_assumptions(s.m_assumptions) { + scoped_minimize_core(smt_solver& s) : s(s), m_assumptions(s.m_assumptions) { s.m_minimizing_core = true; s.m_assumptions.reset(); } @@ -341,22 +341,16 @@ namespace smt { void add_nonlocal_pattern_literals_to_core(ptr_vector & core) { ast_manager & m = get_manager(); - - obj_map::iterator it = m_name2assertion.begin(); - obj_map::iterator end = m_name2assertion.end(); - for (unsigned i = 0; it != end; it++, i++) { - expr_ref name(it->m_key, m); - expr_ref assrtn(it->m_value, m); + for (auto const& kv : m_name2assertion) { + expr_ref name(kv.m_key, m); + expr_ref assrtn(kv.m_value, m); if (!core.contains(name)) { func_decl_set pattern_fds, body_fds; collect_pattern_fds(assrtn, pattern_fds); collect_body_func_decls(assrtn, body_fds); - func_decl_set::iterator pit = pattern_fds.begin(); - func_decl_set::iterator pend= pattern_fds.end(); - for (; pit != pend; pit++) { - func_decl * fd = *pit; + for (func_decl *fd : pattern_fds) { if (!body_fds.contains(fd)) { core.insert(name); break; @@ -369,7 +363,7 @@ namespace smt { }; solver * mk_smt_solver(ast_manager & m, params_ref const & p, symbol const & logic) { - return alloc(smt::solver, m, p, logic); + return alloc(smt::smt_solver, m, p, logic); } class smt_solver_factory : public solver_factory { From 2227db215ed18d524c4e8a3c0e1f0d03bc63877f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 28 Oct 2017 16:58:16 -0700 Subject: [PATCH 487/488] fix build break with virtual method override Signed-off-by: Nikolaj Bjorner --- src/solver/combined_solver.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/solver/combined_solver.cpp b/src/solver/combined_solver.cpp index 8f37224ad..81e10e443 100644 --- a/src/solver/combined_solver.cpp +++ b/src/solver/combined_solver.cpp @@ -147,6 +147,7 @@ public: } virtual void updt_params(params_ref const & p) { + solver::updt_params(p); m_solver1->updt_params(p); m_solver2->updt_params(p); updt_local_params(p); @@ -280,8 +281,8 @@ public: return m_solver2->get_assumption(idx - c1); } - virtual std::ostream& display(std::ostream & out) const { - return m_solver1->display(out); + virtual std::ostream& display(std::ostream & out, unsigned n, expr* const* es) const { + return m_solver1->display(out, n, es); } virtual void collect_statistics(statistics & st) const { From 9e20bfe7f9268eea5fec436e179a50868fb69162 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 28 Oct 2017 17:23:35 -0700 Subject: [PATCH 488/488] fix virtual method override Signed-off-by: Nikolaj Bjorner --- src/muz/spacer/spacer_itp_solver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/muz/spacer/spacer_itp_solver.h b/src/muz/spacer/spacer_itp_solver.h index cab19c8ef..8194379b8 100644 --- a/src/muz/spacer/spacer_itp_solver.h +++ b/src/muz/spacer/spacer_itp_solver.h @@ -134,8 +134,8 @@ public: {return m_solver.get_num_assumptions();} virtual expr * get_assumption(unsigned idx) const {return m_solver.get_assumption(idx);} - virtual std::ostream &display(std::ostream &out) const - { return m_solver.display(out); } + virtual std::ostream &display(std::ostream &out, unsigned n, expr* const* es) const + { return m_solver.display(out, n, es); } /* check_sat_result interface */