3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 21:38:44 +00:00

fix detection of bounds under conjunctions. Issue #971

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-04-11 07:40:09 +08:00
parent 80c10d5833
commit 67513a2cf5
3 changed files with 73 additions and 28 deletions

View file

@ -34,19 +34,19 @@ Notes:
class bounded_int2bv_solver : public solver_na2as { class bounded_int2bv_solver : public solver_na2as {
ast_manager& m; ast_manager& m;
params_ref m_params; params_ref m_params;
bv_util m_bv; mutable bv_util m_bv;
arith_util m_arith; mutable arith_util m_arith;
expr_ref_vector m_assertions; mutable expr_ref_vector m_assertions;
ref<solver> m_solver; ref<solver> m_solver;
ptr_vector<bound_manager> m_bounds; mutable ptr_vector<bound_manager> m_bounds;
func_decl_ref_vector m_bv_fns; mutable func_decl_ref_vector m_bv_fns;
func_decl_ref_vector m_int_fns; mutable func_decl_ref_vector m_int_fns;
unsigned_vector m_bv_fns_lim; unsigned_vector m_bv_fns_lim;
obj_map<func_decl, func_decl*> m_int2bv; mutable obj_map<func_decl, func_decl*> m_int2bv;
obj_map<func_decl, func_decl*> m_bv2int; mutable obj_map<func_decl, func_decl*> m_bv2int;
obj_map<func_decl, rational> m_bv2offset; mutable obj_map<func_decl, rational> m_bv2offset;
bv2int_rewriter_ctx m_rewriter_ctx; mutable bv2int_rewriter_ctx m_rewriter_ctx;
bv2int_rewriter_star m_rewriter; mutable bv2int_rewriter_star m_rewriter;
public: public:
@ -78,7 +78,19 @@ public:
} }
virtual void assert_expr(expr * t) { virtual void assert_expr(expr * t) {
unsigned i = m_assertions.size();
m_assertions.push_back(t); m_assertions.push_back(t);
while (i < m_assertions.size()) {
t = m_assertions[i].get();
if (m.is_and(t)) {
m_assertions.append(to_app(t)->get_num_args(), to_app(t)->get_args());
m_assertions[i] = m_assertions.back();
m_assertions.pop_back();
}
else {
++i;
}
}
} }
virtual void push_core() { virtual void push_core() {
@ -184,7 +196,7 @@ private:
} }
filter_model_converter filter(m); filter_model_converter filter(m);
for (unsigned i = 0; i < m_bv_fns.size(); ++i) { for (unsigned i = 0; i < m_bv_fns.size(); ++i) {
filter.insert(m_bv_fns[i]); filter.insert(m_bv_fns[i].get());
} }
filter(mdl, 0); filter(mdl, 0);
} }
@ -205,13 +217,13 @@ private:
ext(mdl, 0); ext(mdl, 0);
} }
void accumulate_sub(expr_safe_replace& sub) { void accumulate_sub(expr_safe_replace& sub) const {
for (unsigned i = 0; i < m_bounds.size(); ++i) { for (unsigned i = 0; i < m_bounds.size(); ++i) {
accumulate_sub(sub, *m_bounds[i]); accumulate_sub(sub, *m_bounds[i]);
} }
} }
void accumulate_sub(expr_safe_replace& sub, bound_manager& bm) { void accumulate_sub(expr_safe_replace& sub, bound_manager& bm) const {
bound_manager::iterator it = bm.begin(), end = bm.end(); bound_manager::iterator it = bm.begin(), end = bm.end();
for (; it != end; ++it) { for (; it != end; ++it) {
expr* e = *it; expr* e = *it;
@ -252,19 +264,20 @@ private:
sub.insert(e, t); sub.insert(e, t);
} }
else { else {
IF_VERBOSE(1, TRACE("pb",
verbose_stream() << "unprocessed entry: " << mk_pp(e, m) << "\n"; tout << "unprocessed entry: " << mk_pp(e, m) << "\n";
if (bm.has_lower(e, lo, s1)) { if (bm.has_lower(e, lo, s1)) {
verbose_stream() << "lower: " << lo << " " << s1 << "\n"; tout << "lower: " << lo << " " << s1 << "\n";
} }
if (bm.has_upper(e, hi, s2)) { if (bm.has_upper(e, hi, s2)) {
verbose_stream() << "upper: " << hi << " " << s2 << "\n"; tout << "upper: " << hi << " " << s2 << "\n";
}); });
} }
} }
} }
unsigned get_num_bits(rational const& k) {
unsigned get_num_bits(rational const& k) const {
SASSERT(!k.is_neg()); SASSERT(!k.is_neg());
SASSERT(k.is_int()); SASSERT(k.is_int());
rational two(2); rational two(2);
@ -277,11 +290,13 @@ private:
return num_bits; return num_bits;
} }
void flush_assertions() { void flush_assertions() const {
if (m_assertions.empty()) return;
bound_manager& bm = *m_bounds.back(); bound_manager& bm = *m_bounds.back();
for (unsigned i = 0; i < m_assertions.size(); ++i) { for (unsigned i = 0; i < m_assertions.size(); ++i) {
bm(m_assertions[i].get()); bm(m_assertions[i].get());
} }
TRACE("int2bv", bm.display(tout););
expr_safe_replace sub(m); expr_safe_replace sub(m);
accumulate_sub(sub); accumulate_sub(sub);
proof_ref proof(m); proof_ref proof(m);
@ -304,6 +319,17 @@ private:
m_assertions.reset(); m_assertions.reset();
m_rewriter.reset(); m_rewriter.reset();
} }
virtual unsigned get_num_assertions() const {
flush_assertions();
return m_solver->get_num_assertions();
}
virtual expr * get_assertion(unsigned idx) const {
flush_assertions();
return m_solver->get_assertion(idx);
}
}; };
solver * mk_bounded_int2bv_solver(ast_manager & m, params_ref const & p, solver* s) { solver * mk_bounded_int2bv_solver(ast_manager & m, params_ref const & p, solver* s) {

View file

@ -163,6 +163,14 @@ public:
ext(mdl, 0); ext(mdl, 0);
} }
virtual unsigned get_num_assertions() const {
return m_solver->get_num_assertions();
}
virtual expr * get_assertion(unsigned idx) const {
return m_solver->get_assertion(idx);
}
}; };
solver * mk_enum2bv_solver(ast_manager & m, params_ref const & p, solver* s) { solver * mk_enum2bv_solver(ast_manager & m, params_ref const & p, solver* s) {

View file

@ -27,9 +27,9 @@ Notes:
class pb2bv_solver : public solver_na2as { class pb2bv_solver : public solver_na2as {
ast_manager& m; ast_manager& m;
params_ref m_params; params_ref m_params;
expr_ref_vector m_assertions; mutable expr_ref_vector m_assertions;
ref<solver> m_solver; mutable ref<solver> m_solver;
pb2bv_rewriter m_rewriter; mutable pb2bv_rewriter m_rewriter;
public: public:
@ -107,8 +107,19 @@ public:
filter(mdl, 0); filter(mdl, 0);
} }
virtual unsigned get_num_assertions() const {
flush_assertions();
return m_solver->get_num_assertions();
}
virtual expr * get_assertion(unsigned idx) const {
flush_assertions();
return m_solver->get_assertion(idx);
}
private: private:
void flush_assertions() { void flush_assertions() const {
proof_ref proof(m); proof_ref proof(m);
expr_ref fml(m); expr_ref fml(m);
expr_ref_vector fmls(m); expr_ref_vector fmls(m);