3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

arith_solver (#4733)

* porting arithmetic solver

* integrating arithmetic

* lp

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-10-16 10:49:46 -07:00 committed by GitHub
parent 2841796a92
commit 44679d8f5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 3172 additions and 403 deletions

View file

@ -830,6 +830,8 @@ bool arith_util::is_considered_uninterpreted(func_decl* f, unsigned n, expr* con
return plugin().is_considered_uninterpreted(f);
}
func_decl* arith_util::mk_ipower0() {
sort* s = mk_int();
sort* rs[2] = { s, s };
@ -861,3 +863,62 @@ func_decl* arith_util::mk_mod0() {
sort* rs[2] = { mk_int(), mk_int() };
return m_manager.mk_func_decl(m_afid, OP_MOD0, 0, nullptr, 2, rs, mk_int());
}
bool arith_util::is_bounded(expr* n) const {
expr* x = nullptr, * y = nullptr;
while (true) {
if (is_idiv(n, x, y) && is_numeral(y)) {
n = x;
}
else if (is_mod(n, x, y) && is_numeral(y)) {
return true;
}
else if (is_numeral(n)) {
return true;
}
else {
return false;
}
}
}
bool arith_util::is_extended_numeral(expr* term, rational& r) const {
rational mul(1);
do {
if (is_numeral(term, r)) {
r *= mul;
return true;
}
if (is_uminus(term, term)) {
mul.neg();
continue;
}
if (is_to_real(term, term)) {
continue;
}
return false;
} while (false);
return false;
}
bool arith_util::is_underspecified(expr* e) const {
if (!is_app(e))
return false;
if (to_app(e)->get_family_id() == get_family_id()) {
switch (to_app(e)->get_decl_kind()) {
case OP_DIV:
case OP_IDIV:
case OP_REM:
case OP_MOD:
case OP_DIV0:
case OP_IDIV0:
case OP_REM0:
case OP_MOD0:
return true;
default:
break;
}
}
return false;
}

View file

@ -495,6 +495,12 @@ public:
bool is_considered_uninterpreted(func_decl* f, unsigned n, expr* const* args, func_decl_ref& f_out);
bool is_underspecified(expr* e) const;
bool is_bounded(expr* e) const;
bool is_extended_numeral(expr* e, rational& r) const;
};

View file

@ -324,6 +324,7 @@ namespace euf {
void egraph::set_value(enode* n, lbool value) {
force_push();
TRACE("euf", tout << bpp(n) << "\n";);
SASSERT(n->value() == l_undef);
n->set_value(value);
m_updates.push_back(update_record(n, update_record::value_assignment()));
@ -426,12 +427,11 @@ namespace euf {
set_conflict(n1, n2, j);
return;
}
if ((r1->class_size() > r2->class_size() && !r2->interpreted()) || r1->interpreted() || r1->value() != l_undef) {
if (!r2->interpreted() &&
(r1->class_size() > r2->class_size() || r1->interpreted() || r1->value() != l_undef)) {
std::swap(r1, r2);
std::swap(n1, n2);
}
if (r1->value() != l_undef)
return;
if (j.is_congruence() && (m.is_false(r2->get_expr()) || m.is_true(r2->get_expr())))
add_literal(n1, false);
if (n1->is_equality() && n1->value() == l_false)

View file

@ -214,7 +214,7 @@ namespace euf {
public:
egraph(ast_manager& m);
~egraph();
enode* find(expr* f) { return m_expr2enode.get(f->get_id(), nullptr); }
enode* find(expr* f) const { return m_expr2enode.get(f->get_id(), nullptr); }
enode* mk(expr* f, unsigned n, enode *const* args);
enode_vector const& enodes_of(func_decl* f);
void push() { ++m_num_scopes; }

View file

@ -280,7 +280,7 @@ void static_features::update_core(expr * e) {
if (is_app(e) && to_app(e)->get_family_id() == m_srfid)
m_has_sr = true;
if (!m_has_arrays && m_arrayutil.is_array(e))
m_has_arrays = true;
check_array(m.get_sort(e));
if (!m_has_ext_arrays && m_arrayutil.is_array(e) &&
!m_arrayutil.is_select(e) && !m_arrayutil.is_store(e))
m_has_ext_arrays = true;
@ -373,6 +373,16 @@ void static_features::update_core(expr * e) {
}
}
void static_features::check_array(sort* s) {
if (m_arrayutil.is_array(s)) {
m_has_arrays = true;
update_core(get_array_range(s));
for (unsigned i = get_array_arity(s); i-- > 0; )
update_core(get_array_domain(s, i));
}
}
void static_features::update_core(sort * s) {
mark_theory(s->get_family_id());
if (!m_has_int && m_autil.is_int(s))
@ -383,8 +393,7 @@ void static_features::update_core(sort * s) {
m_has_bv = true;
if (!m_has_fpa && (m_fpautil.is_float(s) || m_fpautil.is_rm(s)))
m_has_fpa = true;
if (!m_has_arrays && m_arrayutil.is_array(s))
m_has_arrays = true;
check_array(s);
}
void static_features::process(expr * e, bool form_ctx, bool or_and_ctx, bool ite_ctx, unsigned stack_depth) {

View file

@ -134,6 +134,8 @@ struct static_features {
m_num_theories++;
}
}
void check_array(sort* s);
void acc_num(rational const & r) {
if (r.is_neg())