3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-11-21 05:06:39 +00:00

improvements to arithmetic preprocessing simplificaiton and axiom generation for #1683

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-06-19 07:04:39 -07:00
parent 86c39c971d
commit 8a29c2803c
4 changed files with 131 additions and 63 deletions

View file

@ -865,9 +865,7 @@ namespace smt {
That is, during execution time, the variables will be already bound
*/
bool all_args_are_bound_vars(app * n) {
unsigned num_args = n->get_num_args();
for (unsigned i = 0; i < num_args; i++) {
expr * arg = n->get_arg(i);
for (expr* arg : *n) {
if (!is_var(arg))
return false;
if (m_vars[to_var(arg)->get_idx()] == -1)
@ -884,9 +882,7 @@ namespace smt {
if (n->is_ground()) {
return;
}
unsigned num_args = n->get_num_args();
for (unsigned i = 0; i < num_args; i++) {
expr * arg = n->get_arg(i);
for (expr* arg : *n) {
if (is_var(arg)) {
sz++;
unsigned var_id = to_var(arg)->get_idx();
@ -928,10 +924,7 @@ namespace smt {
unsigned first_app_sz;
unsigned first_app_num_unbound_vars;
// generate first the non-BIND operations
unsigned_vector::iterator it = m_todo.begin();
unsigned_vector::iterator end = m_todo.end();
for (; it != end; ++it) {
unsigned reg = *it;
for (unsigned reg : m_todo) {
expr * p = m_registers[reg];
SASSERT(!is_quantifier(p));
if (is_var(p)) {
@ -1249,10 +1242,7 @@ namespace smt {
SASSERT(head->m_next == 0);
m_seq.push_back(m_ct_manager.mk_yield(m_qa, m_mp, m_qa->get_num_decls(), reinterpret_cast<unsigned*>(m_vars.begin())));
ptr_vector<instruction>::iterator it = m_seq.begin();
ptr_vector<instruction>::iterator end = m_seq.end();
for (; it != end; ++it) {
instruction * curr = *it;
for (instruction * curr : m_seq) {
head->m_next = curr;
head = curr;
}
@ -1495,10 +1485,8 @@ namespace smt {
}
if (num_instr > SIMPLE_SEQ_THRESHOLD || (curr != nullptr && curr->m_opcode == CHOOSE))
simple = false;
unsigned_vector::iterator it = m_to_reset.begin();
unsigned_vector::iterator end = m_to_reset.end();
for (; it != end; ++it)
m_registers[*it] = 0;
for (unsigned reg : m_to_reset)
m_registers[reg] = 0;
return weight;
}
@ -1716,11 +1704,9 @@ namespace smt {
m_num_choices++;
// set: head -> c1 -> c2 -> c3 -> new_child_head1
curr = head;
ptr_vector<instruction>::iterator it1 = m_compatible.begin();
ptr_vector<instruction>::iterator end1 = m_compatible.end();
for (; it1 != end1; ++it1) {
set_next(curr, *it1);
curr = *it1;
for (instruction* instr : m_compatible) {
set_next(curr, instr);
curr = instr;
}
set_next(curr, new_child_head1);
// set: new_child_head1:CHOOSE(new_child_head2) -> i1 -> i2 -> first_child_head

View file

@ -508,13 +508,14 @@ namespace smt {
mk_axiom(eqz, lower, !is_numeral);
mk_axiom(eqz, upper, !is_numeral);
rational k;
context& ctx = get_context();
(void)ctx;
if (m_params.m_arith_enum_const_mod && m_util.is_numeral(divisor, k) &&
k.is_pos() && k < rational(8)) {
rational j(0);
#if 1
literal_buffer lits;
expr_ref mod_j(m);
context& ctx = get_context();
while(j < k) {
mod_j = m.mk_eq(mod, m_util.mk_numeral(j, true));
ctx.internalize(mod_j, false);
@ -542,6 +543,31 @@ namespace smt {
}
#endif
}
if (!m_util.is_numeral(divisor)) {
//
// forall x . (or (= y 0) (= (div (* x y) y) x))
// forall x . (=> (= y 0) (= (div (* x y) y) (div 0 0)))
//
sort* intS = m_util.mk_int();
var_ref v(m.mk_var(0, intS), m);
app_ref mul(m_util.mk_mul(divisor, v), m);
app_ref div(m_util.mk_idiv(mul, divisor), m);
expr_ref divp1(m.mk_pattern(div), m);
app_ref mul2(m_util.mk_mul(v, divisor), m);
app_ref div2(m_util.mk_idiv(mul2, divisor), m);
expr_ref divp2(m.mk_pattern(div2), m);
expr_ref fml1(m.mk_or(m.mk_not(eqz), m.mk_eq(div, m_util.mk_idiv(zero, zero))), m);
expr_ref fml2(m.mk_or(eqz, m.mk_eq(div, v)), m);
symbol name("?x");
expr* pats[2] = { divp1, divp2 };
expr_ref fml(m);
fml = m.mk_forall(1, &intS, &name, fml1, 0, symbol::null, symbol::null, 2, pats, 0, nullptr);
proof_ref pr(m.mk_asserted(fml), m);
ctx.internalize_assertion(fml, pr, 0);
fml = m.mk_forall(1, &intS, &name, fml2, 0, symbol::null, symbol::null, 2, pats, 0, nullptr);
pr = m.mk_asserted(fml);
ctx.internalize_assertion(fml, pr, 0);
}
}
}