mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 21:38:44 +00:00
add facility to solve QF_NRA + QF_UF(and other theories) in joint solver to allow broader use of QF_NRA core
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
c807ad0927
commit
f5c048775b
|
@ -518,13 +518,19 @@ struct is_non_qfufnra_functor {
|
|||
struct found {};
|
||||
ast_manager & m;
|
||||
arith_util u;
|
||||
bool m_has_nonlinear;
|
||||
|
||||
is_non_qfufnra_functor(ast_manager & _m): m(_m), u(m) {}
|
||||
is_non_qfufnra_functor(ast_manager & _m):
|
||||
m(_m), u(m), m_has_nonlinear(false) {}
|
||||
|
||||
void throw_found() {
|
||||
throw found();
|
||||
}
|
||||
|
||||
bool has_nonlinear() const {
|
||||
return m_has_nonlinear;
|
||||
}
|
||||
|
||||
void operator()(var * x) {
|
||||
throw_found();
|
||||
}
|
||||
|
@ -539,13 +545,24 @@ struct is_non_qfufnra_functor {
|
|||
switch (n->get_decl_kind()) {
|
||||
case OP_LE: case OP_GE: case OP_LT: case OP_GT:
|
||||
case OP_ADD: case OP_UMINUS: case OP_SUB: case OP_ABS:
|
||||
case OP_NUM: case OP_MUL:
|
||||
case OP_NUM:
|
||||
case OP_IRRATIONAL_ALGEBRAIC_NUM:
|
||||
return;
|
||||
case OP_MUL:
|
||||
if (n->get_num_args() == 2 ||
|
||||
(!u.is_numeral(n->get_arg(0)) &&
|
||||
!u.is_numeral(n->get_arg(1)))) {
|
||||
m_has_nonlinear = true;
|
||||
}
|
||||
return;
|
||||
case OP_IDIV: case OP_DIV: case OP_REM: case OP_MOD:
|
||||
if (!u.is_numeral(n->get_arg(1)))
|
||||
throw_found();
|
||||
return;
|
||||
case OP_POWER:
|
||||
if (!u.is_numeral(n->get_arg(1)))
|
||||
throw_found();
|
||||
m_has_nonlinear = true;
|
||||
return;
|
||||
case OP_IS_INT:
|
||||
case OP_TO_INT:
|
||||
|
@ -618,7 +635,7 @@ public:
|
|||
|
||||
static bool is_qfufnra(goal const& g) {
|
||||
is_non_qfufnra_functor p(g.m());
|
||||
return !test(g, p);
|
||||
return !test(g, p) && p.has_nonlinear();
|
||||
}
|
||||
|
||||
class is_qfufnra_probe : public probe {
|
||||
|
|
|
@ -130,9 +130,22 @@ public:
|
|||
r = m.mk_fresh_const(0, u().mk_real());
|
||||
m_new_reals.push_back(to_app(r));
|
||||
m_interface_cache.insert(arg, r);
|
||||
expr_ref eq(m);
|
||||
eq = m.mk_eq(r, arg);
|
||||
if (is_real_expression(arg)) {
|
||||
m_nl_cnstrs.push_back(eq);
|
||||
m_nl_cnstr_prs.push_back(m.mk_oeq(r, arg));
|
||||
}
|
||||
else {
|
||||
m_owner.m_solver->assert_expr(eq);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
bool is_real_expression(expr* e) {
|
||||
return is_app(e) && (to_app(e)->get_family_id() == u().get_family_id());
|
||||
}
|
||||
|
||||
void mk_interface_bool(func_decl * f, unsigned num, expr* const* args, expr_ref& result) {
|
||||
expr_ref old_pred(m.mk_app(f, num, args), m);
|
||||
polarity_t pol;
|
||||
|
|
Loading…
Reference in a new issue