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:
parent
2841796a92
commit
44679d8f5b
33 changed files with 3172 additions and 403 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue