3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00
This commit is contained in:
Nikolaj Bjorner 2017-10-16 09:07:44 -07:00
commit b36f512879
80 changed files with 751 additions and 310 deletions

View file

@ -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<func_decl> & 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);

View file

@ -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) : 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);

View file

@ -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<int>(bv_size)) };
parameter p[2] = { parameter(val), parameter(static_cast<int>(bv_size)) };
return m_manager.mk_app(get_fid(), OP_BV_NUM, 2, p, 0, 0);
}

View file

@ -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,10 +204,10 @@ 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):
frame(expr_ref & n, bool pol, bool in_q, bool cache_res, unsigned spos):
m_curr(n),
m_i(0),
m_pol(pol),
@ -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<frame> 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();
@ -324,12 +324,11 @@ 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(expr_ref(t, m()), pol, in_q, cache_res, m_result_stack.size()));
}
static unsigned get_cache_idx(bool pol, bool in_q) {
return static_cast<unsigned>(in_q) * 2 + static_cast<unsigned>(pol);
static unsigned get_cache_idx(bool pol, bool in_q) {
return static_cast<unsigned>(in_q) * 2 + static_cast<unsigned>(pol);
}
void cache_result(expr * t, bool pol, bool in_q, expr * v, proof * pr) {
@ -339,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 {
@ -368,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());
}
@ -382,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);
@ -448,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);
}
@ -468,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()) {
@ -520,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()) {
@ -554,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];
@ -574,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) {
@ -605,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));
@ -626,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()) {
@ -636,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) {
@ -666,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<symbol> names;
bool pos;
m().is_label(t, pos, names);
@ -684,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()) {
@ -692,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()) {
@ -729,7 +728,7 @@ struct nnf::imp {
if (m().is_label(t)) {
return process_label(t, fr);
}
return process_default(t, fr);
}
@ -737,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());
@ -757,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<expr> new_patterns;
if (q->is_forall() == fr.m_pol) {
@ -773,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) {
@ -786,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()) {
@ -809,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();
@ -873,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());
@ -881,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());
@ -898,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";);

View file

@ -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;

View file

@ -272,7 +272,7 @@ void bit_blaster_tpl<Cfg>::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();

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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(); }

View file

@ -31,7 +31,7 @@ Revision History:
// #define TRACE_NTH_ROOT
template<typename C>
interval_manager<C>::interval_manager(reslimit& lim, C const & c): m_limit(lim), m_c(c) {
interval_manager<C>::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;

View file

@ -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();

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) : 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; }
};

View file

@ -739,7 +739,7 @@ void context_t<C>::del_sum(polynomial * p) {
template<typename C>
var context_t<C>::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]);

View file

@ -117,7 +117,7 @@ bool func_interp::is_fi_entry_expr(expr * e, ptr_vector<expr> & 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);

View file

@ -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();

View file

@ -465,7 +465,7 @@ namespace datalog {
unsigned sz = r.get_signature().size();
ptr_vector<expr> subst_arg;
subst_arg.resize(sz, 0);
subst_arg.resize(sz);
unsigned ofs = sz-1;
for (unsigned i=0; i<sz; i++) {
SASSERT(!r.is_undefined(i) || !contains_var(m_new_rule, i));

View file

@ -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);
}
}

View file

@ -1272,7 +1272,7 @@ namespace qe {
family_id fid = p->get_family_id();
SASSERT(fid != null_family_id);
if (static_cast<int>(m_plugins.size()) <= fid) {
m_plugins.resize(fid+1,0);
m_plugins.resize(fid+1);
}
SASSERT(!m_plugins[fid]);
m_plugins[fid] = p;

View file

@ -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);

View file

@ -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, vector<justified_ex
expr* e1 = 0;
if (m.is_false(e)) {
result.push_back(justified_expr(m, e, pr));
m_inconsistent = true;
m_inconsistent = true;
}
else if (m.is_true(e)) {
// skip
@ -110,8 +110,8 @@ void asserted_formulas::push_assertion(expr * e, proof * pr, vector<justified_ex
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);
}
push_assertion(narg, _pr, result);
}
}
else {
result.push_back(justified_expr(m, e, pr));
@ -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();
}
@ -139,11 +140,9 @@ 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);
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););
}
@ -183,7 +185,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 +214,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 +226,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 +278,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 +303,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 +334,9 @@ void asserted_formulas::find_macros_core() {
void asserted_formulas::apply_quasi_macros() {
TRACE("before_quasi_macros", display(tout););
vector<justified_expr> 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 +350,7 @@ void asserted_formulas::nnf_cnf() {
vector<justified_expr> 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 +380,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 +391,8 @@ void asserted_formulas::nnf_cnf() {
void asserted_formulas::simplify_fmls::operator()() {
vector<justified_expr> 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 +408,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 +475,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 +512,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 +556,13 @@ bool asserted_formulas::is_gt(expr* lhs, expr* rhs) {
}
UNREACHABLE();
}
return false;
}
void asserted_formulas::compute_depth(expr* e) {
ptr_vector<expr> todo;
todo.push_back(e);
todo.push_back(e);
while (!todo.empty()) {
e = todo.back();
unsigned d = 0;
@ -603,7 +605,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";);

View file

@ -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() {

View file

@ -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);
}

View file

@ -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;

View file

@ -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());

View file

@ -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<unsigned> 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;

View file

@ -1107,6 +1107,8 @@ unsigned theory_diff_logic<Ext>::simplex2edge(unsigned e) {
template<typename Ext>
void theory_diff_logic<Ext>::update_simplex(Simplex& S) {
unsynch_mpq_manager mgr;
unsynch_mpq_inf_manager inf_mgr;
unsigned num_nodes = m_graph.get_num_nodes();
vector<dl_edge<GExt> > const& es = m_graph.get_all_edges();
S.ensure_var(num_simplex_vars());
@ -1114,13 +1116,13 @@ void theory_diff_logic<Ext>::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<unsigned> 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<Ext>::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);

View file

@ -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);

View file

@ -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.

View file

@ -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<T_cut*>());
@ -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<T_cut*>());
@ -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);

View file

@ -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<stack>
#include<vector>
#include<map>
#include "ast/seq_decl_plugin.h"
#include "util/union_find.h"
namespace smt {
@ -292,6 +293,7 @@ protected:
bool avoidLoopCut;
bool loopDetected;
obj_map<expr, std::stack<T_cut*> > cut_var_map;
scoped_ptr_vector<T_cut> m_cut_allocs;
expr_ref m_theoryStrOverlapAssumption_term;
obj_hashtable<expr> variable_set;

View file

@ -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();

View file

@ -238,7 +238,7 @@ bool bvsls_opt_engine::what_if(
mpz bvsls_opt_engine::find_best_move(
ptr_vector<func_decl> & to_evaluate,
mpz score,
mpz & score,
unsigned & best_const,
mpz & best_value,
unsigned & new_bit,

View file

@ -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<func_decl> & to_evaluate, mpz score,
mpz find_best_move(ptr_vector<func_decl> & to_evaluate, mpz & score,
unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move,
mpz const & max_score, expr * objective);

View file

@ -41,7 +41,24 @@ 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));
}
value_score& operator=(value_score& other) {
UNREACHABLE();
return *this;
}
unsynch_mpz_manager * m;
mpz value;
double score;
@ -50,15 +67,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 +302,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 +547,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 +638,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 +661,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 +937,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 +1045,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 +1053,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);

View file

@ -63,10 +63,4 @@ public:
numeral_manager & m() const { return const_cast<numeral_manager&>(m_manager); }
};
template<typename fmanager>
inline void del_f_interval(im_float_config<fmanager> & cfg, typename im_float_config<fmanager>::interval & a) {
cfg.m().del(a.m_lower);
cfg.m().del(a.m_upper);
}
#endif

View file

@ -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 <typename T>
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_default_config> im(rl, imc); \
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> 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<mpf_manager> ifc(fm);
interval_manager<im_float_config<mpf_manager> > im(ifc);
interval_manager<im_float_config<mpf_manager> > im(fm);
im_float_config<mpf_manager>::interval a, b, c;
scoped_mpq minus_one_third(qm), one_third(qm), two_third(qm), minus_two_third(qm);
qm.set(minus_one_third, -1, 3);
@ -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_default_config> im(rl, imc);
interval_manager<im_default_config> 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

View file

@ -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);

View file

@ -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_default_config> im(rl, imc);
interval_manager<im_default_config> 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_default_config> im(rl, imc);
interval_manager<im_default_config> im(rl, nm);
scoped_mpq a(nm);
nm.set(a, 0);
tst_cosine_core(out, nm, im, a, 1);
@ -100,8 +98,7 @@ template<typename fmanager>
static void tst_float_sine(std::ostream & out, unsigned N, unsigned k) {
reslimit rl;
fmanager fm;
im_float_config<fmanager> ifc(fm, EBITS, SBITS);
interval_manager<im_float_config<fmanager> > im(rl, ifc);
interval_manager<im_float_config<fmanager> > im(rl, { fm, EBITS, SBITS });
_scoped_numeral<fmanager> a(fm);
fm.set(a, EBITS, SBITS, static_cast<int>(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_default_config> im(rl, imc);
interval_manager<im_default_config> 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<mpf_manager> ifc(fm);
interval_manager<im_float_config<mpf_manager> > im(rl, ifc);
interval_manager<im_float_config<mpf_manager> > im(rl, fm);
scoped_mpq q(qm);
im_float_config<mpf_manager>::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() {

View file

@ -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) {

View file

@ -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);

View file

@ -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

View file

@ -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() {
}

View file

@ -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; }

View file

@ -31,11 +31,10 @@ class mpq {
public:
mpq(int v):m_num(v), m_den(1) {}
mpq():m_den(1) {}
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; }
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<SYNCH>::swap(a, b); }
void swap(mpq & a, mpq & b) {

View file

@ -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) : m_val(other.m_val), m_ptr(0) {
std::swap(m_ptr, other.m_ptr);
}
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;

View file

@ -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<Key *>(0) && m_data.m_key != reinterpret_cast<Key *>(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<Key *>(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));

View file

@ -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; }

View file

@ -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); }

View file

@ -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());
@ -63,7 +67,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 +84,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) {
@ -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<T, TManager>(m)) {
this->append(sz, data);

View file

@ -63,8 +63,7 @@ public:
unsigned old_sz = this->size();
if (sz <= old_sz)
shrink(sz);
typename Manager::numeral zero(0);
svector<typename Manager::numeral>::resize(sz, zero);
svector<typename Manager::numeral>::resize(sz, 0);
}
};

View file

@ -322,7 +322,7 @@ bool compare_arrays(const T * array1, const T * array2, unsigned size) {
template<typename T>
void force_ptr_array_size(T & v, unsigned sz) {
if (sz > v.size()) {
v.resize(sz, 0);
v.resize(sz);
}
}

View file

@ -26,6 +26,7 @@ Revision History:
#include "util/debug.h"
#include<algorithm>
#include<type_traits>
#include<memory.h>
#include "util/memory_manager.h"
#include "util/hash.h"
@ -74,9 +75,27 @@ 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<SZ*>(m_data)-2, new_capacity_T);
*mem = new_capacity;
m_data = reinterpret_cast<T *>(mem + 2);
SZ *mem, *old_mem = reinterpret_cast<SZ*>(m_data) - 2;
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
if (__has_trivial_copy(T)) {
#else
if (std::is_trivially_copyable<T>::value) {
#endif
mem = (SZ*)memory::reallocate(old_mem, new_capacity_T);
m_data = reinterpret_cast<T *>(mem + 2);
} else {
mem = (SZ*)memory::allocate(new_capacity_T);
auto old_data = m_data;
auto old_size = size();
mem[1] = old_size;
m_data = reinterpret_cast<T *>(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;
}
}
@ -148,6 +167,10 @@ public:
SASSERT(size() == source.size());
}
vector(vector&& other) : 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 +202,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 +325,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 +356,14 @@ public:
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]++;
}
void push_back(T && elem) {
if (m_data == 0 || reinterpret_cast<SZ *>(m_data)[SIZE_IDX] == reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX]) {
expand_vector();
}
new (m_data + reinterpret_cast<SZ *>(m_data)[SIZE_IDX]) T(std::move(elem));
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]++;
}
void insert(T const & elem) {
push_back(elem);
}
@ -357,7 +403,8 @@ public:
}
}
void resize(SZ s, T const & elem=T()) {
template<typename Args>
void resize(SZ s, Args args...) {
SZ sz = size();
if (s <= sz) { shrink(s); return; }
while (s > capacity()) {
@ -367,8 +414,23 @@ public:
reinterpret_cast<SZ *>(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>(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<SZ *>(m_data)[SIZE_IDX] = s;
iterator it = m_data + sz;
iterator end = m_data + s;
for (; it != end; ++it) {
new (it) T();
}
}
@ -439,10 +501,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<typename T>
@ -452,7 +519,12 @@ public:
ptr_vector(unsigned s):vector<T *, false>(s) {}
ptr_vector(unsigned s, T * elem):vector<T *, false>(s, elem) {}
ptr_vector(ptr_vector const & source):vector<T *, false>(source) {}
ptr_vector(ptr_vector && other) : vector<T*, false>(std::move(other)) {}
ptr_vector(unsigned s, T * const * data):vector<T *, false>(s, const_cast<T**>(data)) {}
ptr_vector & operator=(ptr_vector const & source) {
vector<T *, false>::operator=(source);
return *this;
}
};
template<typename T, typename SZ = unsigned>
@ -462,7 +534,12 @@ public:
svector(SZ s):vector<T, false, SZ>(s) {}
svector(SZ s, T const & elem):vector<T, false, SZ>(s, elem) {}
svector(svector const & source):vector<T, false, SZ>(source) {}
svector(svector && other) : vector<T, false, SZ>(std::move(other)) {}
svector(SZ s, T const * data):vector<T, false, SZ>(s, data) {}
svector & operator=(svector const & source) {
vector<T, false, SZ>::operator=(source);
return *this;
}
};
typedef svector<int> int_vector;
@ -494,23 +571,4 @@ struct vector_hash : public vector_hash_tpl<Hash, vector<typename Hash::data> >
template<typename Hash>
struct svector_hash : public vector_hash_tpl<Hash, svector<typename Hash::data> > {};
#include <vector>
// Specialize vector<std::string> to be an instance of std::vector instead.
// This will catch any regression of issue #564 and #420.
template <>
class vector<std::string, true, unsigned> : public std::vector<std::string> {
public:
vector(vector<std::string, true, unsigned> const& other): std::vector<std::string>(other) {}
vector(size_t sz, char const* s): std::vector<std::string>(sz, s) {}
vector() {}
void reset() { clear(); }
};
#endif /* VECTOR_H_ */