3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 04:43:39 +00:00

Merge branch 'opt' of https://git01.codeplex.com/z3 into opt

This commit is contained in:
Nikolaj Bjorner 2014-10-06 08:37:41 -07:00
commit e1c2049343
29 changed files with 406 additions and 140 deletions

View file

@ -6023,7 +6023,7 @@ END_MLAPI_EXCLUDE
\param a - arithmetical term \param a - arithmetical term
def_API('Z3_optimize_maximize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST))) def_API('Z3_optimize_maximize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/ */
unsigned Z3_API Z3_optimize_maximize(Z3_context, Z3_optimize o, Z3_ast t); unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t);
/** /**
\brief Add a minimization constraint. \brief Add a minimization constraint.
@ -6033,7 +6033,7 @@ END_MLAPI_EXCLUDE
def_API('Z3_optimize_minimize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST))) def_API('Z3_optimize_minimize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/ */
unsigned Z3_API Z3_optimize_minimize(Z3_context, Z3_optimize o, Z3_ast t); unsigned Z3_API Z3_optimize_minimize(Z3_context c, Z3_optimize o, Z3_ast t);
/** /**

View file

@ -4117,7 +4117,6 @@ namespace polynomial {
polynomial_ref H(m_wrapper), C(m_wrapper); polynomial_ref H(m_wrapper), C(m_wrapper);
polynomial_ref lc_H(m_wrapper); polynomial_ref lc_H(m_wrapper);
unsigned min_deg_q = UINT_MAX; unsigned min_deg_q = UINT_MAX;
var next_x = vars[idx+1];
unsigned counter = 0; unsigned counter = 0;
for (;; counter++) { for (;; counter++) {
@ -4137,7 +4136,7 @@ namespace polynomial {
var q_var = max_var(q); var q_var = max_var(q);
unsigned deg_q = q_var == null_var ? 0 : degree(q, q_var); unsigned deg_q = q_var == null_var ? 0 : degree(q, q_var);
TRACE("mgcd_detail", tout << "counter: " << counter << "\nidx: " << idx << "\nq: " << q << "\ndeg_q: " << deg_q << "\nmin_deg_q: " << TRACE("mgcd_detail", tout << "counter: " << counter << "\nidx: " << idx << "\nq: " << q << "\ndeg_q: " << deg_q << "\nmin_deg_q: " <<
min_deg_q << "\nnext_x: x" << next_x << "\nmax_var(q): " << q_var << "\n";); min_deg_q << "\nnext_x: x" << vars[idx+1] << "\nmax_var(q): " << q_var << "\n";);
if (deg_q < min_deg_q) { if (deg_q < min_deg_q) {
TRACE("mgcd_detail", tout << "reseting...\n";); TRACE("mgcd_detail", tout << "reseting...\n";);
counter = 0; counter = 0;
@ -5113,10 +5112,9 @@ namespace polynomial {
monomial const * m_r = R.m(max_R); monomial const * m_r = R.m(max_R);
numeral const & a_r = R.a(max_R); numeral const & a_r = R.a(max_R);
monomial * m_r_q = 0; monomial * m_r_q = 0;
bool q_div_r = div(m_r, m_q, m_r_q); VERIFY(div(m_r, m_q, m_r_q));
TRACE("polynomial", tout << "m_r: "; m_r->display(tout); tout << "\nm_q: "; m_q->display(tout); tout << "\n"; TRACE("polynomial", tout << "m_r: "; m_r->display(tout); tout << "\nm_q: "; m_q->display(tout); tout << "\n";
if (m_r_q) { tout << "m_r_q: "; m_r_q->display(tout); tout << "\n"; }); if (m_r_q) { tout << "m_r_q: "; m_r_q->display(tout); tout << "\n"; });
SASSERT(q_div_r);
m_r_q_ref = m_r_q; m_r_q_ref = m_r_q;
m_manager.div(a_r, a_q, a_r_q); m_manager.div(a_r, a_q, a_r_q);
C.add(a_r_q, m_r_q); // C <- C + (a_r/a_q)*(m_r/m_q) C.add(a_r_q, m_r_q); // C <- C + (a_r/a_q)*(m_r/m_q)

View file

@ -1264,6 +1264,21 @@ namespace datalog {
return check_kind(t)?alloc(filter_proj_fn, get(t), get_ast_manager(), condition, removed_col_cnt, removed_cols):0; return check_kind(t)?alloc(filter_proj_fn, get(t), get_ast_manager(), condition, removed_col_cnt, removed_cols):0;
} }
relation_join_fn * udoc_plugin::mk_join_project_fn(
relation_base const& t1, relation_base const& t2,
unsigned joined_col_cnt, const unsigned * cols1, const unsigned * cols2,
unsigned removed_col_cnt, const unsigned * removed_cols) {
if (check_kind(t1) && check_kind(t2))
return 0;
#if 0
return alloc(join_proj_fn, get(t1), ge(t2),
joined_col_cnt, cols1, cols2,
removed_col_cnt, removed_cols);
#endif
else
return 0;
}

View file

@ -81,6 +81,7 @@ namespace datalog {
class udoc_plugin : public relation_plugin { class udoc_plugin : public relation_plugin {
friend class udoc_relation; friend class udoc_relation;
class join_fn; class join_fn;
class join_project_fn;
class project_fn; class project_fn;
class union_fn; class union_fn;
class rename_fn; class rename_fn;
@ -138,6 +139,11 @@ namespace datalog {
virtual relation_transformer_fn * mk_filter_interpreted_and_project_fn( virtual relation_transformer_fn * mk_filter_interpreted_and_project_fn(
const relation_base & t, app * condition, const relation_base & t, app * condition,
unsigned removed_col_cnt, const unsigned * removed_cols); unsigned removed_col_cnt, const unsigned * removed_cols);
virtual relation_join_fn * mk_join_project_fn(
relation_base const& t1, relation_base const& t2,
unsigned joined_col_cnt, const unsigned * cols1, const unsigned * cols2,
unsigned removed_col_cnt, const unsigned * removed_cols);
void disable_fast_pass() { m_disable_fast_pass = true; } void disable_fast_pass() { m_disable_fast_pass = true; }
}; };
}; };

View file

@ -316,6 +316,7 @@ private:
for (; it != end; ++it) { for (; it != end; ++it) {
asms.push_back(it->m_value); asms.push_back(it->m_value);
} }
//IF_VERBOSE(0, verbose_stream() << asms << "\n";);
} }
void extract_core(dep2asm_t& dep2asm) { void extract_core(dep2asm_t& dep2asm) {
@ -341,7 +342,7 @@ private:
m_core.reset(); m_core.reset();
for (unsigned i = 0; i < core.size(); ++i) { for (unsigned i = 0; i < core.size(); ++i) {
expr* e; expr* e;
VERIFY (asm2dep.find(core[i].index(), e)); VERIFY(asm2dep.find(core[i].index(), e));
m_core.push_back(e); m_core.push_back(e);
} }
@ -397,6 +398,14 @@ private:
SASSERT(m_model); SASSERT(m_model);
// IF_VERBOSE(0, model_smt2_pp(verbose_stream(), m, *(m_model.get()), 0);); // IF_VERBOSE(0, model_smt2_pp(verbose_stream(), m, *(m_model.get()), 0););
DEBUG_CODE(
for (unsigned i = 0; i < m_fmls.size(); ++i) {
expr_ref tmp(m);
VERIFY(m_model->eval(m_fmls[i].get(), tmp));
CTRACE("opt", !m.is_true(tmp),
tout << "Evaluation failed: " << mk_pp(m_fmls[i].get(), m) << "\n";);
SASSERT(m.is_true(tmp));
});
} }
}; };

View file

@ -64,6 +64,7 @@ Notes:
#include "pb_decl_plugin.h" #include "pb_decl_plugin.h"
#include "opt_params.hpp" #include "opt_params.hpp"
#include "ast_util.h" #include "ast_util.h"
#include "smt_solver.h"
using namespace opt; using namespace opt;
@ -150,6 +151,7 @@ public:
} }
void new_assumption(expr* e, rational const& w) { void new_assumption(expr* e, rational const& w) {
IF_VERBOSE(3, verbose_stream() << "new assumption " << mk_pp(e, m) << " " << w << "\n";);
TRACE("opt", tout << "insert: " << mk_pp(e, m) << " : " << w << "\n";); TRACE("opt", tout << "insert: " << mk_pp(e, m) << " : " << w << "\n";);
m_asm2weight.insert(e, w); m_asm2weight.insert(e, w);
m_asms.push_back(e); m_asms.push_back(e);
@ -171,7 +173,6 @@ public:
if (m_cancel) { if (m_cancel) {
return l_undef; return l_undef;
} }
model_ref mdl;
switch (is_sat) { switch (is_sat) {
case l_true: case l_true:
found_optimum(); found_optimum();
@ -179,7 +180,6 @@ public:
case l_false: case l_false:
is_sat = process_unsat(); is_sat = process_unsat();
if (is_sat != l_true) return is_sat; if (is_sat != l_true) return is_sat;
get_mus_model(mdl);
break; break;
case l_undef: case l_undef:
return l_undef; return l_undef;
@ -187,6 +187,7 @@ public:
break; break;
} }
} }
trace_bounds("maxres");
return l_true; return l_true;
} }
@ -370,6 +371,7 @@ public:
} }
void found_optimum() { void found_optimum() {
IF_VERBOSE(1, verbose_stream() << "found optimum\n";);
s().get_model(m_model); s().get_model(m_model);
DEBUG_CODE( DEBUG_CODE(
for (unsigned i = 0; i < m_asms.size(); ++i) { for (unsigned i = 0; i < m_asms.size(); ++i) {
@ -404,6 +406,9 @@ public:
while (is_sat == l_false) { while (is_sat == l_false) {
core.reset(); core.reset();
s().get_unsat_core(core); s().get_unsat_core(core);
//verify_core(core);
model_ref mdl;
get_mus_model(mdl);
is_sat = minimize_core(core); is_sat = minimize_core(core);
if (is_sat != l_true) { if (is_sat != l_true) {
break; break;
@ -420,18 +425,12 @@ public:
break; break;
} }
remove_soft(core, asms); remove_soft(core, asms);
TRACE("opt",
display_vec(tout << "core: ", core.size(), core.c_ptr());
display_vec(tout << "assumptions: ", asms.size(), asms.c_ptr()););
is_sat = check_sat_hill_climb(asms); is_sat = check_sat_hill_climb(asms);
} }
TRACE("opt", TRACE("opt",
tout << "num cores: " << cores.size() << "\n"; tout << "num cores: " << cores.size() << "\n";
for (unsigned i = 0; i < cores.size(); ++i) { for (unsigned i = 0; i < cores.size(); ++i) {
for (unsigned j = 0; j < cores[i].size(); ++j) { display_vec(tout, cores[i].size(), cores[i].c_ptr());
tout << mk_pp(cores[i][j], m) << " ";
}
tout << "\n";
} }
tout << "num satisfying: " << asms.size() << "\n";); tout << "num satisfying: " << asms.size() << "\n";);
@ -535,6 +534,7 @@ public:
if (m_c.sat_enabled()) { if (m_c.sat_enabled()) {
// SAT solver core extracts some model // SAT solver core extracts some model
// during unsat core computation. // during unsat core computation.
mdl = 0;
s().get_model(mdl); s().get_model(mdl);
} }
else { else {
@ -601,10 +601,7 @@ public:
// find the minimal weight: // find the minimal weight:
rational w = get_weight(core[0]); rational w = get_weight(core[0]);
for (unsigned i = 1; i < core.size(); ++i) { for (unsigned i = 1; i < core.size(); ++i) {
rational w2 = get_weight(core[i]); w = std::min(w, get_weight(core[i]));
if (w2 < w) {
w = w2;
}
} }
// add fresh soft clauses for weights that are above w. // add fresh soft clauses for weights that are above w.
for (unsigned i = 0; i < core.size(); ++i) { for (unsigned i = 0; i < core.size(); ++i) {
@ -614,6 +611,7 @@ public:
new_assumption(core[i], w3); new_assumption(core[i], w3);
} }
} }
return w; return w;
} }
@ -754,6 +752,7 @@ public:
case l_false: case l_false:
core.reset(); core.reset();
s().get_unsat_core(core); s().get_unsat_core(core);
DEBUG_CODE(verify_core(core););
is_sat = minimize_core(core); is_sat = minimize_core(core);
if (is_sat != l_true) { if (is_sat != l_true) {
break; break;
@ -786,14 +785,9 @@ public:
rational upper(0); rational upper(0);
expr_ref tmp(m); expr_ref tmp(m);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
expr* n = m_soft[i]; if (!is_true(mdl, m_soft[i])) {
VERIFY(mdl->eval(n, tmp));
if (!m.is_true(tmp)) {
upper += m_weights[i]; upper += m_weights[i];
} }
TRACE("opt", tout << mk_pp(n, m) << " |-> " << mk_pp(tmp, m) << "\n";);
CTRACE("opt", !m.is_true(tmp) && !m.is_false(tmp),
tout << mk_pp(n, m) << " |-> " << mk_pp(tmp, m) << "\n";);
} }
if (upper >= m_upper) { if (upper >= m_upper) {
return; return;
@ -804,7 +798,7 @@ public:
m_assignment[i] = is_true(m_soft[i]); m_assignment[i] = is_true(m_soft[i]);
} }
m_upper = upper; m_upper = upper;
// verify_assignment(); DEBUG_CODE(verify_assignment(););
trace_bounds("maxres"); trace_bounds("maxres");
add_upper_bound_block(); add_upper_bound_block();
@ -888,6 +882,38 @@ public:
} }
} }
void verify_core(exprs const& core) {
IF_VERBOSE(3, verbose_stream() << "verify core\n";);
ref<solver> sat_solver = mk_inc_sat_solver(m, m_params);
for (unsigned i = 0; i < s().get_num_assertions(); ++i) {
sat_solver->assert_expr(s().get_assertion(i));
}
expr_ref n(m);
for (unsigned i = 0; i < core.size(); ++i) {
IF_VERBOSE(1, verbose_stream() << mk_pp(core[i],m) << " ";);
sat_solver->assert_expr(core[i]);
}
IF_VERBOSE(1, verbose_stream() << "\n";);
lbool is_sat = sat_solver->check_sat(0, 0);
if (is_sat != l_false) {
IF_VERBOSE(0, verbose_stream() << "!!!not a core\n";);
}
sat_solver = mk_smt_solver(m, m_params, symbol());
for (unsigned i = 0; i < s().get_num_assertions(); ++i) {
sat_solver->assert_expr(s().get_assertion(i));
}
for (unsigned i = 0; i < core.size(); ++i) {
sat_solver->assert_expr(core[i]);
}
is_sat = sat_solver->check_sat(0, 0);
if (is_sat == l_true) {
IF_VERBOSE(0, verbose_stream() << "not a core\n";);
}
}
void verify_assignment() { void verify_assignment() {
IF_VERBOSE(0, verbose_stream() << "verify assignment\n";); IF_VERBOSE(0, verbose_stream() << "verify assignment\n";);
ref<solver> sat_solver = mk_inc_sat_solver(m, m_params); ref<solver> sat_solver = mk_inc_sat_solver(m, m_params);

View file

@ -1449,11 +1449,19 @@ namespace qe {
m_solver.assert_expr(m_fml); m_solver.assert_expr(m_fml);
if (assumption) m_solver.assert_expr(assumption); if (assumption) m_solver.assert_expr(assumption);
bool is_sat = false; bool is_sat = false;
while (l_true == m_solver.check()) { lbool res = l_true;
is_sat = true; while (res == l_true) {
res = m_solver.check();
if (res == l_true) is_sat = true;
final_check(); final_check();
} }
if (res == l_undef) {
free_vars.append(num_vars, vars);
reset();
m_solver.pop(1);
return;
}
if (!is_sat) { if (!is_sat) {
fml = m.mk_false(); fml = m.mk_false();
@ -1484,12 +1492,13 @@ namespace qe {
); );
free_vars.append(m_free_vars); free_vars.append(m_free_vars);
SASSERT(!m_free_vars.empty() || m_solver.inconsistent()); if (!m_free_vars.empty() || m_solver.inconsistent()) {
if (m_fml.get() != m_subfml.get()) { if (m_fml.get() != m_subfml.get()) {
scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m); scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m);
rp->apply_substitution(to_app(m_subfml.get()), fml, m_fml); rp->apply_substitution(to_app(m_subfml.get()), fml, m_fml);
fml = m_fml; fml = m_fml;
}
} }
reset(); reset();
m_solver.pop(1); m_solver.pop(1);

View file

@ -22,6 +22,7 @@ Revision History:
#include"trace.h" #include"trace.h"
#include"bit_vector.h" #include"bit_vector.h"
#include"map.h" #include"map.h"
#include"sat_elim_eqs.h"
namespace sat { namespace sat {
@ -54,7 +55,7 @@ namespace sat {
} }
} }
bin_clauses bc; bin_clauses bc;
m_solver.collect_bin_clauses(bc, false); m_solver.collect_bin_clauses(bc, false); // exclude roots.
literal lits[2]; literal lits[2];
for (unsigned i = 0; i < bc.size(); ++i) { for (unsigned i = 0; i < bc.size(); ++i) {
lits[0] = bc[i].first; lits[0] = bc[i].first;
@ -215,7 +216,7 @@ namespace sat {
m_L.append(new_clauses); m_L.append(new_clauses);
m_L_blits.append(new_blits); m_L_blits.append(new_blits);
} }
std::cout << "Number left after BCE: " << clauses.size() << "\n"; if (!clauses.empty()) std::cout << "Number left after BCE: " << clauses.size() << "\n";
return clauses.empty(); return clauses.empty();
} }
@ -362,7 +363,13 @@ namespace sat {
while (v != i) { while (v != i) {
if (!m_solver.was_eliminated(v)) { if (!m_solver.was_eliminated(v)) {
if (last_v != UINT_MAX) { if (last_v != UINT_MAX) {
check_equality(v, last_v); if (check_equality(v, last_v)) {
// last_v was eliminated.
}
else {
// TBD: refine partition.
}
} }
last_v = v; last_v = v;
} }
@ -371,7 +378,7 @@ namespace sat {
} }
} }
void bceq::check_equality(unsigned v1, unsigned v2) { bool bceq::check_equality(unsigned v1, unsigned v2) {
TRACE("sat", tout << "check: " << v1 << " = " << v2 << "\n";); TRACE("sat", tout << "check: " << v1 << " = " << v2 << "\n";);
uint64 val1 = m_rbits[v1]; uint64 val1 = m_rbits[v1];
uint64 val2 = m_rbits[v2]; uint64 val2 = m_rbits[v2];
@ -381,9 +388,9 @@ namespace sat {
SASSERT(val1 == ~val2); SASSERT(val1 == ~val2);
l2.neg(); l2.neg();
} }
if (is_equiv(l1, l2)) { if (is_already_equiv(l1, l2)) {
TRACE("sat", tout << "Already equivalent: " << l1 << " " << l2 << "\n";); TRACE("sat", tout << "Already equivalent: " << l1 << " " << l2 << "\n";);
return; return false;
} }
literal lits[2]; literal lits[2];
@ -397,13 +404,16 @@ namespace sat {
} }
if (is_sat == l_false) { if (is_sat == l_false) {
TRACE("sat", tout << "Found equivalent: " << l1 << " " << l2 << "\n";); TRACE("sat", tout << "Found equivalent: " << l1 << " " << l2 << "\n";);
assert_equality(l1, l2);
} }
else { else {
TRACE("sat", tout << "Not equivalent: " << l1 << " " << l2 << "\n";); TRACE("sat", tout << "Not equivalent: " << l1 << " " << l2 << "\n";);
// TBD: if is_sat == l_true, then refine partition.
} }
return is_sat == l_false;
} }
bool bceq::is_equiv(literal l1, literal l2) { bool bceq::is_already_equiv(literal l1, literal l2) {
watch_list const& w1 = m_solver.get_wlist(l1); watch_list const& w1 = m_solver.get_wlist(l1);
bool found = false; bool found = false;
for (unsigned i = 0; !found && i < w1.size(); ++i) { for (unsigned i = 0; !found && i < w1.size(); ++i) {
@ -420,6 +430,24 @@ namespace sat {
return found; return found;
} }
void bceq::assert_equality(literal l1, literal l2) {
if (l2.sign()) {
l1.neg();
l2.neg();
}
literal_vector roots;
bool_var_vector vars;
for (unsigned i = 0; i < m_solver.num_vars(); ++i) {
roots.push_back(literal(i, false));
}
roots[l2.var()] = l1;
vars.push_back(l2.var());
elim_eqs elim(m_solver);
for (unsigned i = 0; i < vars.size(); ++i) {
std::cout << "var: " << vars[i] << " root: " << roots[vars[i]] << "\n";
}
elim(roots, vars);
}
void bceq::cleanup() { void bceq::cleanup() {
m_solver.del_clauses(m_bin_clauses.begin(), m_bin_clauses.end()); m_solver.del_clauses(m_bin_clauses.begin(), m_bin_clauses.end());
@ -430,15 +458,23 @@ namespace sat {
void bceq::operator()() { void bceq::operator()() {
if (!m_solver.m_config.m_bcd) return; if (!m_solver.m_config.m_bcd) return;
flet<bool> _disable_bcd(m_solver.m_config.m_bcd, false); flet<bool> _disable_bcd(m_solver.m_config.m_bcd, false);
flet<bool> _disable_min(m_solver.m_config.m_minimize_core, false);
flet<bool> _disable_opt(m_solver.m_config.m_optimize_model, false);
flet<unsigned> _bound_maxc(m_solver.m_config.m_max_conflicts, 1500);
use_list ul; use_list ul;
solver s(m_solver.m_params, 0); solver s(m_solver.m_params, 0);
s.m_config.m_bcd = false;
s.m_config.m_minimize_core = false;
s.m_config.m_optimize_model = false;
s.m_config.m_max_conflicts = 1500;
m_use_list = &ul; m_use_list = &ul;
m_s = &s; m_s = &s;
ul.init(m_solver.num_vars()); ul.init(m_solver.num_vars());
init(); init();
pure_decompose(); pure_decompose();
post_decompose(); post_decompose();
std::cout << "Decomposed set " << m_L.size() << "\n"; std::cout << "Decomposed set " << m_L.size() << " rest: " << m_R.size() << "\n";
TRACE("sat", TRACE("sat",
tout << "Decomposed set " << m_L.size() << "\n"; tout << "Decomposed set " << m_L.size() << "\n";

View file

@ -65,8 +65,9 @@ namespace sat {
uint64 eval_clause(clause const& cls) const; uint64 eval_clause(clause const& cls) const;
void verify_sweep(); void verify_sweep();
void extract_partition(); void extract_partition();
void check_equality(unsigned v1, unsigned v2); bool check_equality(unsigned v1, unsigned v2);
bool is_equiv(literal l1, literal l2); bool is_already_equiv(literal l1, literal l2);
void assert_equality(literal l1, literal l2);
public: public:
bceq(solver & s); bceq(solver & s);
void operator()(); void operator()();

View file

@ -68,7 +68,10 @@ namespace sat {
m_restart_factor = p.restart_factor(); m_restart_factor = p.restart_factor();
m_random_freq = p.random_freq(); m_random_freq = p.random_freq();
m_random_seed = p.random_seed();
if (m_random_seed == 0)
m_random_seed = _p.get_uint("random_seed", 0);
m_burst_search = p.burst_search(); m_burst_search = p.burst_search();
m_max_conflicts = p.max_conflicts(); m_max_conflicts = p.max_conflicts();

View file

@ -53,6 +53,7 @@ namespace sat {
unsigned m_restart_initial; unsigned m_restart_initial;
double m_restart_factor; // for geometric case double m_restart_factor; // for geometric case
double m_random_freq; double m_random_freq;
unsigned m_random_seed;
unsigned m_burst_search; unsigned m_burst_search;
unsigned m_max_conflicts; unsigned m_max_conflicts;

View file

@ -7,7 +7,7 @@ Module Name:
Abstract: Abstract:
Faster MUS extraction based on Belov et.al. HYB (Algorithm 3, 4) Faster MUS extraction
Author: Author:
@ -33,12 +33,27 @@ namespace sat {
m_mus.reset(); m_mus.reset();
m_model.reset(); m_model.reset();
m_best_value = 0; m_best_value = 0;
m_max_restarts = 10;
m_restart = s.m_stats.m_restart;
} }
void mus::set_core() { void mus::set_core() {
m_core.append(m_mus); m_mus.append(m_core);
s.m_core.reset(); s.m_core.reset();
s.m_core.append(m_core); s.m_core.append(m_mus);
}
void mus::update_model() {
double new_value = s.m_wsls.evaluate_model(s.m_model);
if (m_model.empty()) {
m_model.append(s.m_model);
m_best_value = new_value;
}
else if (m_best_value > new_value) {
m_model.reset();
m_model.append(s.m_model);
m_best_value = new_value;
}
} }
lbool mus::operator()() { lbool mus::operator()() {
@ -56,6 +71,9 @@ namespace sat {
TRACE("sat", tout << "old core: " << s.get_core() << "\n";); TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
literal_vector& core = get_core(); literal_vector& core = get_core();
literal_vector& mus = m_mus; literal_vector& mus = m_mus;
if (core.size() > 64) {
return mus2();
}
unsigned delta_time = 0; unsigned delta_time = 0;
unsigned core_miss = 0; unsigned core_miss = 0;
while (!core.empty()) { while (!core.empty()) {
@ -75,41 +93,31 @@ namespace sat {
literal lit = core.back(); literal lit = core.back();
core.pop_back(); core.pop_back();
unsigned sz = mus.size(); lbool is_sat;
mus.append(core); {
if (true || core_miss < 2) { scoped_append _sa(mus, core);
mus.push_back(~lit); // TBD: measure if (true || core_miss < 2) {
mus.push_back(~lit); // TBD: measure
}
is_sat = s.check(mus.size(), mus.c_ptr());
TRACE("sat", tout << "mus: " << mus << "\n";);
} }
lbool is_sat = s.check(mus.size(), mus.c_ptr());
TRACE("sat", tout << "mus: " << mus << "\n";);
switch (is_sat) { switch (is_sat) {
case l_undef: case l_undef:
mus.resize(sz);
core.push_back(lit); core.push_back(lit);
set_core(); set_core();
return l_undef; return l_undef;
case l_true: { case l_true: {
SASSERT(value_at(lit, s.get_model()) == l_false); SASSERT(value_at(lit, s.get_model()) == l_false);
mus.resize(sz);
mus.push_back(lit); mus.push_back(lit);
update_model();
if (!core.empty()) { if (!core.empty()) {
// mr(); // TBD: measure // mr(); // TBD: measure
} }
double new_value = s.m_wsls.evaluate_model(s.m_model);
if (m_model.empty()) {
m_model.append(s.m_model);
m_best_value = new_value;
}
else if (m_best_value > new_value) {
m_model.reset();
m_model.append(s.m_model);
m_best_value = new_value;
}
break; break;
} }
case l_false: case l_false:
literal_vector const& new_core = s.get_core(); literal_vector const& new_core = s.get_core();
mus.resize(sz);
if (new_core.contains(~lit)) { if (new_core.contains(~lit)) {
IF_VERBOSE(2, verbose_stream() << "miss core " << lit << "\n";); IF_VERBOSE(2, verbose_stream() << "miss core " << lit << "\n";);
++core_miss; ++core_miss;
@ -141,27 +149,93 @@ namespace sat {
IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << core << ")\n";); IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << core << ")\n";);
return l_true; return l_true;
} }
// bisection search. // bisection search.
lbool mus::mus2() { lbool mus::mus2() {
literal_vector& core = get_core(); literal_set core(get_core());
literal_vector& mus = m_mus; literal_set support;
while (true) { lbool is_sat = qx(core, support, false);
s.m_core.reset();
s.m_core.append(core.to_vector());
IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << s.m_core << ")\n";);
return is_sat;
}
#if 0 lbool mus::qx(literal_set& assignment, literal_set& support, bool has_support) {
unsigned start = 0; lbool is_sat = l_true;
unsigned len = core.size(); if (s.m_stats.m_restart - m_restart > m_max_restarts) {
SASSERT(start < len); IF_VERBOSE(1, verbose_stream() << "restart budget exceeded\n";);
unsigned mid = (len-start+1)/2; return l_true;
mus.append(mid, core.c_ptr() + start);
start = start + mid;
#endif
} }
return l_undef; if (has_support) {
scoped_append _sa(m_mus, support.to_vector());
is_sat = s.check(m_mus.size(), m_mus.c_ptr());
switch (is_sat) {
case l_false: {
literal_set core(s.get_core());
support &= core;
assignment.reset();
return l_true;
}
case l_undef:
return l_undef;
case l_true:
update_model();
break;
default:
break;
}
}
if (assignment.size() == 1) {
return l_true;
}
literal_set assign2;
split(assignment, assign2);
support |= assignment;
is_sat = qx(assign2, support, !assignment.empty());
unsplit(support, assignment);
if (is_sat != l_true) return is_sat;
support |= assign2;
is_sat = qx(assignment, support, !assign2.empty());
assignment |= assign2;
unsplit(support, assign2);
return is_sat;
}
void mus::unsplit(literal_set& A, literal_set& B) {
literal_set A1, B1;
literal_set::iterator it = A.begin(), end = A.end();
for (; it != end; ++it) {
if (B.contains(*it)) {
B1.insert(*it);
}
else {
A1.insert(*it);
}
}
A = A1;
B = B1;
}
void mus::split(literal_set& lits1, literal_set& lits2) {
unsigned half = lits1.size()/2;
literal_set lits3;
literal_set::iterator it = lits1.begin(), end = lits1.end();
for (unsigned i = 0; it != end; ++it, ++i) {
if (i < half) {
lits3.insert(*it);
}
else {
lits2.insert(*it);
}
}
lits1 = lits3;
} }
literal_vector& mus::get_core() { literal_vector& mus::get_core() {
m_core.reset(); m_core.reset();
m_mus.reset();
literal_vector& core = m_core; literal_vector& core = m_core;
core.append(s.get_core()); core.append(s.get_core());
for (unsigned i = 0; i < core.size(); ++i) { for (unsigned i = 0; i < core.size(); ++i) {
@ -175,6 +249,11 @@ namespace sat {
return core; return core;
} }
void mus::verify_core(literal_vector const& core) {
lbool is_sat = s.check(core.size(), core.c_ptr());
IF_VERBOSE(3, verbose_stream() << "core verification: " << is_sat << " " << core << "\n";);
}
void mus::mr() { void mus::mr() {
sls sls(s); sls sls(s);
literal_vector tabu; literal_vector tabu;

View file

@ -26,6 +26,8 @@ namespace sat {
bool m_is_active; bool m_is_active;
model m_model; // model obtained during minimal unsat core model m_model; // model obtained during minimal unsat core
double m_best_value; double m_best_value;
unsigned m_restart;
unsigned m_max_restarts;
solver& s; solver& s;
@ -38,10 +40,30 @@ namespace sat {
private: private:
lbool mus1(); lbool mus1();
lbool mus2(); lbool mus2();
lbool qx(literal_set& assignment, literal_set& support, bool has_support);
void mr(); void mr();
void reset(); void reset();
void set_core(); void set_core();
void update_model();
literal_vector & get_core(); literal_vector & get_core();
void verify_core(literal_vector const& lits);
void split(literal_set& src, literal_set& dst);
void intersect(literal_set& dst, literal_set const& src);
void unsplit(literal_set& A, literal_set& B);
class scoped_append {
unsigned m_size;
literal_vector& m_lits;
public:
scoped_append(literal_vector& lits, literal_vector const& other):
m_size(lits.size()),
m_lits(lits) {
m_lits.append(other);
}
~scoped_append() {
m_lits.resize(m_size);
}
};
}; };
}; };

View file

@ -9,6 +9,7 @@ def_module_params('sat',
('restart.initial', UINT, 100, 'initial restart (number of conflicts)'), ('restart.initial', UINT, 100, 'initial restart (number of conflicts)'),
('restart.factor', DOUBLE, 1.5, 'restart increment factor for geometric strategy'), ('restart.factor', DOUBLE, 1.5, 'restart increment factor for geometric strategy'),
('random_freq', DOUBLE, 0.01, 'frequency of random case splits'), ('random_freq', DOUBLE, 0.01, 'frequency of random case splits'),
('random_seed', UINT, 0, 'random seed'),
('burst_search', UINT, 100, 'number of conflicts before first global simplification'), ('burst_search', UINT, 100, 'number of conflicts before first global simplification'),
('max_conflicts', UINT, UINT_MAX, 'maximum number of conflicts'), ('max_conflicts', UINT, UINT_MAX, 'maximum number of conflicts'),
('gc', SYMBOL, 'glue_psm', 'garbage collection strategy: psm, glue, glue_psm, dyn_psm'), ('gc', SYMBOL, 'glue_psm', 'garbage collection strategy: psm, glue, glue_psm, dyn_psm'),

View file

@ -21,7 +21,6 @@ Revision History:
#include"sat_simplifier.h" #include"sat_simplifier.h"
#include"sat_simplifier_params.hpp" #include"sat_simplifier_params.hpp"
#include"sat_solver.h" #include"sat_solver.h"
#include"sat_bceq.h"
#include"stopwatch.h" #include"stopwatch.h"
#include"trace.h" #include"trace.h"
@ -138,8 +137,10 @@ namespace sat {
return; return;
if (!m_subsumption && !m_elim_blocked_clauses && !m_resolution) if (!m_subsumption && !m_elim_blocked_clauses && !m_resolution)
return; return;
CASSERT("sat_solver", s.check_invariant()); CASSERT("sat_solver", s.check_invariant());
TRACE("before_simplifier", s.display(tout);); TRACE("before_simplifier", s.display(tout););
s.m_cleaner(true); s.m_cleaner(true);
m_last_sub_trail_sz = s.m_trail.size(); m_last_sub_trail_sz = s.m_trail.size();
TRACE("after_cleanup", s.display(tout);); TRACE("after_cleanup", s.display(tout););
@ -157,13 +158,6 @@ namespace sat {
if (!learned && (m_elim_blocked_clauses || m_elim_blocked_clauses_at == m_num_calls)) if (!learned && (m_elim_blocked_clauses || m_elim_blocked_clauses_at == m_num_calls))
elim_blocked_clauses(); elim_blocked_clauses();
#if 1
// experiment is disabled.
if (!learned) { // && m_equality_inference
bceq bc(s);
bc();
}
#endif
if (!learned) if (!learned)
m_num_calls++; m_num_calls++;
@ -188,23 +182,21 @@ namespace sat {
bool vars_eliminated = m_num_elim_vars > old_num_elim_vars; bool vars_eliminated = m_num_elim_vars > old_num_elim_vars;
if (!m_need_cleanup) { if (m_need_cleanup) {
TRACE("after_simplifier", tout << "cleanning watches...\n";);
cleanup_watches();
cleanup_clauses(s.m_learned, true, vars_eliminated, learned_in_use_lists);
cleanup_clauses(s.m_clauses, false, vars_eliminated, true);
}
else {
TRACE("after_simplifier", tout << "skipping cleanup...\n";); TRACE("after_simplifier", tout << "skipping cleanup...\n";);
if (vars_eliminated) { if (vars_eliminated) {
// must remove learned clauses with eliminated variables // must remove learned clauses with eliminated variables
cleanup_clauses(s.m_learned, true, true, learned_in_use_lists); cleanup_clauses(s.m_learned, true, true, learned_in_use_lists);
} }
CASSERT("sat_solver", s.check_invariant());
TRACE("after_simplifier", s.display(tout); tout << "model_converter:\n"; s.m_mc.display(tout););
free_memory();
return;
} }
TRACE("after_simplifier", tout << "cleanning watches...\n";);
cleanup_watches();
cleanup_clauses(s.m_learned, true, vars_eliminated, learned_in_use_lists);
cleanup_clauses(s.m_clauses, false, vars_eliminated, true);
TRACE("after_simplifier", s.display(tout); tout << "model_converter:\n"; s.m_mc.display(tout););
CASSERT("sat_solver", s.check_invariant()); CASSERT("sat_solver", s.check_invariant());
TRACE("after_simplifier", s.display(tout); tout << "model_converter:\n"; s.m_mc.display(tout););
free_memory(); free_memory();
} }
@ -926,11 +918,11 @@ namespace sat {
void process(literal l) { void process(literal l) {
TRACE("blocked_clause", tout << "processing: " << l << "\n";); TRACE("blocked_clause", tout << "processing: " << l << "\n";);
if (s.is_external(l.var()) || s.was_eliminated(l.var())) {
return;
}
model_converter::entry * new_entry = 0; model_converter::entry * new_entry = 0;
if (s.is_external(l.var()) || s.was_eliminated(l.var()))
return;
{ {
m_to_remove.reset(); m_to_remove.reset();
{ {
clause_use_list & occs = s.m_use_list.get(l); clause_use_list & occs = s.m_use_list.get(l);
@ -1186,7 +1178,6 @@ namespace sat {
continue; continue;
m_visited[l2.index()] = false; m_visited[l2.index()] = false;
} }
return res; return res;
} }
@ -1351,6 +1342,7 @@ namespace sat {
} }
TRACE("resolution", tout << "found var to eliminate, before: " << before_clauses << " after: " << after_clauses << "\n";); TRACE("resolution", tout << "found var to eliminate, before: " << before_clauses << " after: " << after_clauses << "\n";);
// eliminate variable // eliminate variable
model_converter::entry & mc_entry = s.m_mc.mk(model_converter::ELIM_VAR, v); model_converter::entry & mc_entry = s.m_mc.mk(model_converter::ELIM_VAR, v);
save_clauses(mc_entry, m_pos_cls); save_clauses(mc_entry, m_pos_cls);

View file

@ -49,7 +49,7 @@ namespace sat {
m_qhead(0), m_qhead(0),
m_scope_lvl(0), m_scope_lvl(0),
m_params(p) { m_params(p) {
m_config.updt_params(p); updt_params(p);
m_conflicts_since_gc = 0; m_conflicts_since_gc = 0;
m_conflicts = 0; m_conflicts = 0;
m_next_simplify = 0; m_next_simplify = 0;
@ -483,7 +483,6 @@ namespace sat {
void solver::set_conflict(justification c, literal not_l) { void solver::set_conflict(justification c, literal not_l) {
if (m_inconsistent) if (m_inconsistent)
return; return;
TRACE("sat", tout << "conflict: " << not_l << "\n";);
m_inconsistent = true; m_inconsistent = true;
m_conflict = c; m_conflict = c;
m_not_l = not_l; m_not_l = not_l;
@ -960,7 +959,11 @@ namespace sat {
m_stopwatch.start(); m_stopwatch.start();
m_core.reset(); m_core.reset();
TRACE("sat", display(tout);); TRACE("sat", display(tout););
if (m_config.m_bcd) {
bceq bc(*this);
bc();
}
} }
/** /**
@ -1737,11 +1740,10 @@ namespace sat {
// TBD: // TBD:
// apply optional clause minimization by detecting subsumed literals. // apply optional clause minimization by detecting subsumed literals.
// initial experiment suggests it has no effect. // initial experiment suggests it has no effect.
m_mus(); // ignore return value on cancelation. m_mus(); // ignore return value on cancelation.
m_model.reset(); m_model.reset();
m_model.append(m_mus.get_model()); m_model.append(m_mus.get_model());
m_model_is_current = true; m_model_is_current = !m_model.empty();
} }
} }
@ -2356,7 +2358,7 @@ namespace sat {
m_asymm_branch.updt_params(p); m_asymm_branch.updt_params(p);
m_probing.updt_params(p); m_probing.updt_params(p);
m_scc.updt_params(p); m_scc.updt_params(p);
m_rand.set_seed(p.get_uint("random_seed", 0)); m_rand.set_seed(m_config.m_random_seed);
} }
void solver::collect_param_descrs(param_descrs & d) { void solver::collect_param_descrs(param_descrs & d) {

View file

@ -160,6 +160,12 @@ namespace sat {
m_in_set[v] = true; m_in_set[v] = true;
m_set.push_back(v); m_set.push_back(v);
} }
uint_set& operator=(uint_set const& other) {
m_in_set = other.m_in_set;
m_set = other.m_set;
return *this;
}
bool contains(unsigned v) const { bool contains(unsigned v) const {
return v < m_in_set.size() && m_in_set[v] != 0; return v < m_in_set.size() && m_in_set[v] != 0;
@ -177,10 +183,31 @@ namespace sat {
m_in_set[v] = false; m_in_set[v] = false;
return v; return v;
} }
unsigned size() const { return m_set.size(); }
iterator begin() const { return m_set.begin(); } iterator begin() const { return m_set.begin(); }
iterator end() const { return m_set.end(); } iterator end() const { return m_set.end(); }
void reset() { m_set.reset(); m_in_set.reset(); } void reset() { m_set.reset(); m_in_set.reset(); }
void cleanup() { m_set.finalize(); m_in_set.finalize(); } void cleanup() { m_set.finalize(); m_in_set.finalize(); }
uint_set& operator&=(uint_set const& other) {
unsigned j = 0;
for (unsigned i = 0; i < m_set.size(); ++i) {
if (other.contains(m_set[i])) {
m_set[j] = m_set[i];
++j;
}
else {
m_in_set[m_set[i]] = false;
}
}
m_set.resize(j);
return *this;
}
uint_set& operator|=(uint_set const& other) {
for (unsigned i = 0; i < other.m_set.size(); ++i) {
insert(other.m_set[i]);
}
return *this;
}
}; };
typedef uint_set bool_var_set; typedef uint_set bool_var_set;
@ -188,11 +215,44 @@ namespace sat {
class literal_set { class literal_set {
uint_set m_set; uint_set m_set;
public: public:
literal_set(literal_vector const& v) {
for (unsigned i = 0; i < v.size(); ++i) insert(v[i]);
}
literal_set() {}
literal_vector to_vector() const {
literal_vector result;
iterator it = begin(), e = end();
for (; it != e; ++it) {
result.push_back(*it);
}
return result;
}
void insert(literal l) { m_set.insert(l.index()); } void insert(literal l) { m_set.insert(l.index()); }
bool contains(literal l) const { return m_set.contains(l.index()); } bool contains(literal l) const { return m_set.contains(l.index()); }
bool empty() const { return m_set.empty(); } bool empty() const { return m_set.empty(); }
unsigned size() const { return m_set.size(); }
void reset() { m_set.reset(); } void reset() { m_set.reset(); }
void cleanup() { m_set.cleanup(); } void cleanup() { m_set.cleanup(); }
class iterator {
uint_set::iterator m_it;
public:
iterator(uint_set::iterator it):m_it(it) {}
literal operator*() const { return to_literal(*m_it); }
iterator& operator++() { ++m_it; return *this; }
iterator operator++(int) { iterator tmp = *this; ++m_it; return tmp; }
bool operator==(iterator const& it) const { return m_it == it.m_it; }
bool operator!=(iterator const& it) const { return m_it != it.m_it; }
};
iterator begin() const { return iterator(m_set.begin()); }
iterator end() const { return iterator(m_set.end()); }
literal_set& operator&=(literal_set const& other) {
m_set &= other.m_set;
return *this;
}
literal_set& operator|=(literal_set const& other) {
m_set |= other.m_set;
return *this;
}
}; };
struct mem_stat { struct mem_stat {

View file

@ -1616,6 +1616,8 @@ namespace smt {
unsigned qhead = m_qhead; unsigned qhead = m_qhead;
if (!bcp()) if (!bcp())
return false; return false;
if (m_cancel_flag)
return true;
SASSERT(!inconsistent()); SASSERT(!inconsistent());
propagate_relevancy(qhead); propagate_relevancy(qhead);
if (inconsistent()) if (inconsistent())
@ -3950,7 +3952,7 @@ namespace smt {
m_fingerprints.display(tout); m_fingerprints.display(tout);
); );
failure fl = get_last_search_failure(); failure fl = get_last_search_failure();
if (fl == TIMEOUT || fl == MEMOUT || fl == CANCELED || fl == NUM_CONFLICTS || fl == THEORY) { if (fl == TIMEOUT || fl == MEMOUT || fl == CANCELED || fl == NUM_CONFLICTS) {
// don't generate model. // don't generate model.
return; return;
} }

View file

@ -1274,8 +1274,10 @@ namespace smt {
} }
} }
while (m_final_check_idx != old_idx); while (m_final_check_idx != old_idx);
if (result == FC_DONE && m_found_unsupported_op) if (result == FC_DONE && m_found_unsupported_op) {
TRACE("arith", tout << "Found unsupported operation\n";);
result = FC_GIVEUP; result = FC_GIVEUP;
}
return result; return result;
} }

View file

@ -1299,8 +1299,10 @@ namespace smt {
} }
tout << "max: " << max << ", min: " << min << "\n";); tout << "max: " << max << ", min: " << min << "\n";);
if (m_params.m_arith_ignore_int) if (m_params.m_arith_ignore_int) {
TRACE("arith", tout << "Ignore int: give up\n";);
return FC_GIVEUP; return FC_GIVEUP;
}
if (!gcd_test()) if (!gcd_test())
return FC_CONTINUE; return FC_CONTINUE;

View file

@ -2314,13 +2314,15 @@ namespace smt {
return FC_DONE; return FC_DONE;
} }
if (!m_params.m_nl_arith) if (!m_params.m_nl_arith) {
TRACE("non_linear", tout << "Non-linear is not enabled\n";);
return FC_GIVEUP; return FC_GIVEUP;
}
TRACE("process_non_linear", display(tout);); TRACE("process_non_linear", display(tout););
if (m_nl_rounds > m_params.m_nl_arith_rounds) { if (m_nl_rounds > m_params.m_nl_arith_rounds) {
TRACE("non_linear", tout << "GIVE UP non linear problem...\n";); TRACE("non_linear", tout << "GIVEUP non linear problem...\n";);
IF_VERBOSE(3, verbose_stream() << "Max. non linear arithmetic rounds. Increase threshold using NL_ARITH_ROUNDS=<limit>\n";); IF_VERBOSE(3, verbose_stream() << "Max. non linear arithmetic rounds. Increase threshold using NL_ARITH_ROUNDS=<limit>\n";);
return FC_GIVEUP; return FC_GIVEUP;
} }

View file

@ -1066,11 +1066,8 @@ template<typename Ext>
void theory_diff_logic<Ext>::get_eq_antecedents( void theory_diff_logic<Ext>::get_eq_antecedents(
theory_var v1, theory_var v2, unsigned timestamp, conflict_resolution & cr) { theory_var v1, theory_var v2, unsigned timestamp, conflict_resolution & cr) {
imp_functor functor(cr); imp_functor functor(cr);
bool r; VERIFY(m_graph.find_shortest_zero_edge_path(v1, v2, timestamp, functor));
r = m_graph.find_shortest_zero_edge_path(v1, v2, timestamp, functor); VERIFY(m_graph.find_shortest_zero_edge_path(v2, v1, timestamp, functor));
SASSERT(r);
r = m_graph.find_shortest_zero_edge_path(v2, v1, timestamp, functor);
SASSERT(r);
} }
template<typename Ext> template<typename Ext>

View file

@ -138,9 +138,8 @@ bool bit_vector::operator==(bit_vector const & source) const {
bit_vector & bit_vector::operator|=(bit_vector const & source) { bit_vector & bit_vector::operator|=(bit_vector const & source) {
if (size() < source.size()) if (size() < source.size())
resize(source.size(), false); resize(source.size(), false);
unsigned n1 = num_words();
unsigned n2 = source.num_words(); unsigned n2 = source.num_words();
SASSERT(n2 <= n1); SASSERT(n2 <= num_words());
unsigned bit_rest = source.m_num_bits % 32; unsigned bit_rest = source.m_num_bits % 32;
if (bit_rest == 0) { if (bit_rest == 0) {
unsigned i = 0; unsigned i = 0;

View file

@ -55,12 +55,12 @@ class cmd_exception : public default_exception {
} }
public: public:
cmd_exception(char const * msg):default_exception(msg), m_line(-1), m_pos(-1) {} cmd_exception(char const * msg):default_exception(msg), m_line(-1), m_pos(-1) {}
cmd_exception(std::string const & msg):default_exception(msg.c_str()), m_line(-1), m_pos(-1) {} cmd_exception(std::string const & msg):default_exception(msg), m_line(-1), m_pos(-1) {}
cmd_exception(std::string const & msg, int line, int pos):default_exception(msg.c_str()), m_line(line), m_pos(pos) {} cmd_exception(std::string const & msg, int line, int pos):default_exception(msg), m_line(line), m_pos(pos) {}
cmd_exception(char const * msg, symbol const & s): cmd_exception(char const * msg, symbol const & s):
default_exception(compose(msg,s).c_str()),m_line(-1),m_pos(-1) {} default_exception(compose(msg,s)),m_line(-1),m_pos(-1) {}
cmd_exception(char const * msg, symbol const & s, int line, int pos): cmd_exception(char const * msg, symbol const & s, int line, int pos):
default_exception(compose(msg,s).c_str()),m_line(line),m_pos(pos) {} default_exception(compose(msg,s)),m_line(line),m_pos(pos) {}
bool has_pos() const { return m_line >= 0; } bool has_pos() const { return m_line >= 0; }
int line() const { SASSERT(has_pos()); return m_line; } int line() const { SASSERT(has_pos()); return m_line; }

View file

@ -120,7 +120,8 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, double value) {
// double === mpf(11, 53) // double === mpf(11, 53)
COMPILE_TIME_ASSERT(sizeof(double) == 8); COMPILE_TIME_ASSERT(sizeof(double) == 8);
uint64 raw = *reinterpret_cast<uint64*>(&value); uint64 raw;
memcpy(&raw, &value, sizeof(double));
bool sign = (raw >> 63) != 0; bool sign = (raw >> 63) != 0;
int64 e = ((raw & 0x7FF0000000000000ull) >> 52) - 1023; int64 e = ((raw & 0x7FF0000000000000ull) >> 52) - 1023;
uint64 s = raw & 0x000FFFFFFFFFFFFFull; uint64 s = raw & 0x000FFFFFFFFFFFFFull;
@ -155,7 +156,8 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, float value) {
// single === mpf(8, 24) // single === mpf(8, 24)
COMPILE_TIME_ASSERT(sizeof(float) == 4); COMPILE_TIME_ASSERT(sizeof(float) == 4);
unsigned int raw = *reinterpret_cast<unsigned int*>(&value); unsigned int raw;
memcpy(&raw, &value, sizeof(float));
bool sign = (raw >> 31) != 0; bool sign = (raw >> 31) != 0;
signed int e = ((raw & 0x7F800000) >> 23) - 127; signed int e = ((raw & 0x7F800000) >> 23) - 127;
unsigned int s = raw & 0x007FFFFF; unsigned int s = raw & 0x007FFFFF;
@ -1288,7 +1290,9 @@ double mpf_manager::to_double(mpf const & x) {
if (x.sign) if (x.sign)
raw = raw | 0x8000000000000000ull; raw = raw | 0x8000000000000000ull;
return *reinterpret_cast<double*>(&raw); double ret;
memcpy(&ret, &raw, sizeof(double));
return ret;
} }
float mpf_manager::to_float(mpf const & x) { float mpf_manager::to_float(mpf const & x) {
@ -1318,7 +1322,9 @@ float mpf_manager::to_float(mpf const & x) {
if (x.sign) if (x.sign)
raw = raw | 0x80000000; raw = raw | 0x80000000;
return *reinterpret_cast<float*>(&raw); float ret;
memcpy(&ret, &raw, sizeof(float));
return ret;
} }
bool mpf_manager::is_nan(mpf const & x) { bool mpf_manager::is_nan(mpf const & x) {
@ -1679,7 +1685,7 @@ void mpf_manager::round(mpf_rounding_mode rm, mpf & o) {
TRACE("mpf_dbg", tout << "OVF2 = " << OVF2 << std::endl;); TRACE("mpf_dbg", tout << "OVF2 = " << OVF2 << std::endl;);
TRACE("mpf_dbg", tout << "o_has_max_exp = " << o_has_max_exp << std::endl;); TRACE("mpf_dbg", tout << "o_has_max_exp = " << o_has_max_exp << std::endl;);
if (!OVFen && SIGovf && o_has_max_exp) if (!OVFen && OVF2)
mk_round_inf(rm, o); mk_round_inf(rm, o);
else { else {
const mpz & p = m_powers2(o.sbits-1); const mpz & p = m_powers2(o.sbits-1);

View file

@ -43,8 +43,7 @@ mpff_manager::mpff_manager(unsigned prec, unsigned initial_capacity) {
for (unsigned i = 0; i < MPFF_NUM_BUFFERS; i++) for (unsigned i = 0; i < MPFF_NUM_BUFFERS; i++)
m_buffers[i].resize(2 * prec, 0); m_buffers[i].resize(2 * prec, 0);
// Reserve space for zero // Reserve space for zero
unsigned zero_sig_idx = m_id_gen.mk(); VERIFY(m_id_gen.mk() == 0);
SASSERT(zero_sig_idx == 0);
set(m_one, 1); set(m_one, 1);
} }

View file

@ -38,8 +38,7 @@ mpfx_manager::mpfx_manager(unsigned int_sz, unsigned frac_sz, unsigned initial_c
m_buffer0.resize(2*m_total_sz, 0); m_buffer0.resize(2*m_total_sz, 0);
m_buffer1.resize(2*m_total_sz, 0); m_buffer1.resize(2*m_total_sz, 0);
m_buffer2.resize(2*m_total_sz, 0); m_buffer2.resize(2*m_total_sz, 0);
unsigned zero_sig_idx = m_id_gen.mk(); VERIFY(m_id_gen.mk() == 0);
SASSERT(zero_sig_idx == 0);
set(m_one, 1); set(m_one, 1);
} }

View file

@ -235,6 +235,9 @@ void mpq_manager<SYNCH>::set(mpq & a, char const * val) {
SASSERT(str[0] - '0' <= 9); SASSERT(str[0] - '0' <= 9);
exp = (10*exp) + (str[0] - '0'); exp = (10*exp) + (str[0] - '0');
} }
else if ('/' == str[0]) {
throw default_exception("mixing rational/scientific notation");
}
TRACE("mpq_set", tout << "[exp]: " << exp << ", str[0]: " << (str[0] - '0') << std::endl;); TRACE("mpq_set", tout << "[exp]: " << exp << ", str[0]: " << (str[0] - '0') << std::endl;);
++str; ++str;
} }

View file

@ -24,9 +24,6 @@ Revision History:
#include<iostream> #include<iostream>
#include<climits> #include<climits>
#include<limits> #include<limits>
#ifdef _MSC_VER
#include<intrin.h>
#endif
#ifndef SIZE_MAX #ifndef SIZE_MAX
#define SIZE_MAX std::numeric_limits<std::size_t>::max() #define SIZE_MAX std::numeric_limits<std::size_t>::max()
@ -99,9 +96,7 @@ COMPILE_TIME_ASSERT(sizeof(unsigned) == 4);
// Return the number of 1 bits in v. // Return the number of 1 bits in v.
static inline unsigned get_num_1bits(unsigned v) { static inline unsigned get_num_1bits(unsigned v) {
#ifdef _MSC_VER #ifdef __GNUC__
return __popcnt(v);
#elif defined(__GNUC__)
return __builtin_popcount(v); return __builtin_popcount(v);
#else #else
#ifdef Z3DEBUG #ifdef Z3DEBUG