From 9b54b4e7848ff8f1df54378d5091867c37c16023 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Tue, 10 Oct 2017 17:24:22 +0100 Subject: [PATCH 01/15] 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 02/15] 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 03/15] 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 04/15] 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 05/15] 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 06/15] 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 07/15] 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 08/15] 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 09/15] 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 10/15] 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 11/15] 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 12/15] 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 13/15] 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 14/15] 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 15/15] 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; } }