3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

fix overflow and integrality bugs reported by Phan

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-12-15 16:18:09 -08:00
parent f4dfb9ac82
commit ae3d16bc50
6 changed files with 32 additions and 23 deletions

View file

@ -26,7 +26,7 @@ Notes:
using namespace datalog;
rule_properties::rule_properties(ast_manager & m, rule_manager& rm, context& ctx, i_expr_pred& p):
m(m), rm(rm), m_ctx(ctx), m_is_predicate(p), m_dt(m), m_generate_proof(false) {}
m(m), rm(rm), m_ctx(ctx), m_is_predicate(p), m_dt(m), m_dl(m), m_generate_proof(false) {}
rule_properties::~rule_properties() {}
@ -168,7 +168,7 @@ void rule_properties::operator()(app* n) {
if (m_is_predicate(n)) {
insert(m_interp_pred, m_rule);
}
else if (is_uninterp(n)) {
else if (is_uninterp(n) && !m_dl.is_rule_sort(n->get_decl()->get_range())) {
m_uninterp_funs.insert(n->get_decl(), m_rule);
}
else if (m_dt.is_accessor(n)) {

View file

@ -32,6 +32,7 @@ namespace datalog {
context& m_ctx;
i_expr_pred& m_is_predicate;
datatype_util m_dt;
dl_decl_util m_dl;
bool m_generate_proof;
rule* m_rule;
obj_map<quantifier, rule*> m_quantifiers;

View file

@ -434,6 +434,7 @@ namespace datalog {
relation_union_fn * explanation_relation_plugin::mk_union_fn(const relation_base & tgt, const relation_base & src,
const relation_base * delta) {
std::cout << "check kind: " << check_kind(tgt) << "\n";
if (!check_kind(tgt) || (delta && !check_kind(*delta))) {
return 0;
}
@ -854,7 +855,10 @@ namespace datalog {
scoped_ptr<relation_join_fn> product_fun = rmgr.mk_join_fn(orig_rel, *m_e_fact_relation, 0, 0, 0);
SASSERT(product_fun);
scoped_rel<relation_base> aux_extended_rel = (*product_fun)(orig_rel, *m_e_fact_relation);
TRACE("dl", tout << aux_extended_rel << " " << aux_extended_rel->get_plugin().get_name() << "\n";
tout << e_rel.get_plugin().get_name() << "\n";);
scoped_ptr<relation_union_fn> union_fun = rmgr.mk_union_fn(e_rel, *aux_extended_rel);
TRACE("dl", tout << union_fun << "\n";);
SASSERT(union_fun);
(*union_fun)(e_rel, *aux_extended_rel);
}

View file

@ -45,7 +45,7 @@ namespace datalog {
{}
virtual bool can_handle_signature(const relation_signature & sig) {
return true;
return get_manager().get_context().karr();
}
static symbol get_name() { return symbol("karr_relation"); }

View file

@ -115,7 +115,7 @@ namespace datalog {
rm.register_plugin(alloc(bound_relation_plugin, rm));
rm.register_plugin(alloc(interval_relation_plugin, rm));
rm.register_plugin(alloc(karr_relation_plugin, rm));
if (m_context.karr()) rm.register_plugin(alloc(karr_relation_plugin, rm));
rm.register_plugin(alloc(product_set_plugin, rm));
rm.register_plugin(alloc(udoc_plugin, rm));
rm.register_plugin(alloc(check_relation_plugin, rm));

View file

@ -1377,11 +1377,11 @@ namespace smt {
SASSERT(satisfy_bounds());
result = skipped_row?BEST_EFFORT:OPTIMIZED;
break;
}
}
if (x_i == null_theory_var) {
// can increase/decrease x_j as much as we want.
if (inc && upper(x_j)) {
if (inc && upper(x_j) && !skipped_row) {
update_value(x_j, upper_bound(x_j) - get_value(x_j));
TRACE("opt", tout << "moved v" << x_j << " to upper bound\n";);
SASSERT(valid_row_assignment());
@ -1389,7 +1389,7 @@ namespace smt {
SASSERT(satisfy_integrality());
continue;
}
if (!inc && lower(x_j)) {
if (!inc && lower(x_j) && !skipped_row) {
update_value(x_j, lower_bound(x_j) - get_value(x_j));
TRACE("opt", tout << "moved v" << x_j << " to lower bound\n";);
SASSERT(valid_row_assignment());
@ -1463,6 +1463,7 @@ namespace smt {
template<typename Ext>
bool theory_arith<Ext>::move_to_bound(theory_var x_i, bool move_to_lower) {
inf_numeral delta, delta_abs;
numeral lc(1);
if (move_to_lower) {
delta = lower_bound(x_i) - get_value(x_i);
@ -1475,7 +1476,7 @@ namespace smt {
TRACE("opt", tout << "Original delta: " << delta << "\n";);
delta_abs = abs(delta);
delta_abs = abs(delta);
//
// Decrease absolute value of delta according to bounds on rows where x_i is used.
//
@ -1483,28 +1484,31 @@ namespace smt {
typename svector<col_entry>::iterator it = c.begin_entries();
typename svector<col_entry>::iterator end = c.end_entries();
for (; it != end && delta_abs.is_pos(); ++it) {
if (!it->is_dead()) {
row & r = m_rows[it->m_row_id];
theory_var s = r.get_base_var();
if (s != null_theory_var && !is_quasi_base(s)) {
numeral const & coeff = r[it->m_row_idx].m_coeff;
SASSERT(!coeff.is_zero());
bool inc_s = coeff.is_pos() ? move_to_lower : !move_to_lower; // NSB: review this..
bound * b = get_bound(s, inc_s);
if (b) {
inf_numeral delta2 = abs((get_value(s) - b->get_value())/coeff);
if (delta2 < delta_abs) {
delta_abs = delta2;
}
if (it->is_dead()) continue;
row & r = m_rows[it->m_row_id];
theory_var s = r.get_base_var();
if (s != null_theory_var && !is_quasi_base(s)) {
numeral const & coeff = r[it->m_row_idx].m_coeff;
SASSERT(!coeff.is_zero());
bool inc_s = coeff.is_pos() ? move_to_lower : !move_to_lower; // NSB: review this..
bound * b = get_bound(s, inc_s);
if (b) {
inf_numeral delta2 = abs((get_value(s) - b->get_value())/coeff);
if (delta2 < delta_abs) {
delta_abs = delta2;
}
}
if (is_int(x_i)) {
lc = lcm(lc, denominator(abs(coeff)));
}
}
}
bool truncated = false;
if (is_int(x_i)) {
truncated = !delta_abs.is_int();
delta_abs = floor(delta_abs);
inf_numeral tmp = delta_abs/lc;
truncated = !tmp.is_int();
delta_abs = lc*floor(tmp);
}
if (move_to_lower) {