3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 09:35:32 +00:00

strengthen filter for specialized tactic conditions, add flag to disable hnf to lp_params

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-07-15 22:35:47 -07:00
parent ca12a8482f
commit d00ffdda82
9 changed files with 114 additions and 43 deletions

View file

@ -127,6 +127,43 @@ public:
}
};
struct has_nlmul {
struct found {};
ast_manager& m;
arith_util a;
has_nlmul(ast_manager& m):m(m), a(m) {}
void throw_found(expr* e) {
TRACE("probe", tout << expr_ref(e, m) << ": " << sort_ref(m.get_sort(e), m) << "\n";);
SASSERT(false);
throw found();
}
void operator()(var *) { }
void operator()(quantifier *) { }
void operator()(app * n) {
family_id fid = n->get_family_id();
if (fid == a.get_family_id()) {
switch (n->get_decl_kind()) {
case OP_MUL:
if (n->get_num_args() != 2 || !a.is_numeral(n->get_arg(0)))
throw_found(n);
break;
case OP_IDIV: case OP_DIV: case OP_REM: case OP_MOD:
if (!a.is_numeral(n->get_arg(1)))
throw_found(n);
break;
case OP_POWER:
throw_found(n);
default:
break;
}
}
}
};
probe * mk_arith_avg_degree_probe() {
return alloc(arith_degree_probe, true);
}
@ -441,13 +478,13 @@ struct is_non_nira_functor {
if (m_linear) {
if (n->get_num_args() != 2)
throw_found(n);
if (!u.is_numeral(n->get_arg(0)))
if (!u.is_numeral(n->get_arg(0)) && !u.is_numeral(n->get_arg(1)))
throw_found(n);
}
return;
case OP_IDIV: case OP_DIV: case OP_REM: case OP_MOD:
if (m_linear && !u.is_numeral(n->get_arg(1)))
throw_found(n);
throw_found(n);
return;
case OP_IS_INT:
if (m_real)
@ -478,27 +515,27 @@ struct is_non_nira_functor {
static bool is_qfnia(goal const & g) {
is_non_nira_functor p(g.m(), true, false, false, false);
return !test(g, p);
return !test(g, p) && test<has_nlmul>(g);
}
static bool is_qfnra(goal const & g) {
is_non_nira_functor p(g.m(), false, true, false, false);
return !test(g, p);
return !test(g, p) && test<has_nlmul>(g);
}
static bool is_nia(goal const & g) {
is_non_nira_functor p(g.m(), true, false, true, false);
return !test(g, p);
return !test(g, p) && test<has_nlmul>(g);
}
static bool is_nra(goal const & g) {
is_non_nira_functor p(g.m(), false, true, true, false);
return !test(g, p);
return !test(g, p) && test<has_nlmul>(g);
}
static bool is_nira(goal const & g) {
is_non_nira_functor p(g.m(), true, true, true, false);
return !test(g, p);
return !test(g, p) && test<has_nlmul>(g);
}
static bool is_lra(goal const & g) {
@ -560,12 +597,16 @@ struct is_non_qfufnra_functor {
}
return;
case OP_IDIV: case OP_DIV: case OP_REM: case OP_MOD:
if (!u.is_numeral(n->get_arg(1)))
if (!u.is_numeral(n->get_arg(1))) {
TRACE("arith", tout << "non-linear " << expr_ref(n, m) << "\n";);
throw_found();
}
return;
case OP_POWER:
if (!u.is_numeral(n->get_arg(1)))
if (!u.is_numeral(n->get_arg(1))) {
TRACE("arith", tout << "non-linear " << expr_ref(n, m) << "\n";);
throw_found();
}
m_has_nonlinear = true;
return;
case OP_IS_INT:
@ -574,6 +615,7 @@ struct is_non_qfufnra_functor {
throw_found();
return;
default:
TRACE("arith", tout << "non-linear " << expr_ref(n, m) << "\n";);
throw_found();
}
}

View file

@ -26,6 +26,23 @@ tactic * mk_qffplra_tactic(ast_manager & m, params_ref const & p) {
return st;
}
struct is_fpa_function {
struct found {};
ast_manager & m;
fpa_util fu;
is_fpa_function(ast_manager & _m) : m(_m), fu(m) {}
void operator()(var *) { }
void operator()(quantifier *) { }
void operator()(app * n) {
if (n->get_family_id() == fu.get_family_id())
throw found();
}
};
struct is_non_qffplra_predicate {
struct found {};
ast_manager & m;
@ -61,7 +78,9 @@ struct is_non_qffplra_predicate {
class is_qffplra_probe : public probe {
public:
result operator()(goal const & g) override {
return !test<is_non_qffplra_predicate>(g);
return
test<is_fpa_function>(g) &&
!test<is_non_qffplra_predicate>(g);
}
~is_qffplra_probe() override {}

View file

@ -110,9 +110,11 @@ static tactic * mk_qfnia_smt_solver(ast_manager& m, params_ref const& p) {
tactic * mk_qfnia_tactic(ast_manager & m, params_ref const & p) {
return and_then(mk_qfnia_premable(m, p),
or_else(mk_qfnia_sat_solver(m, p),
try_for(mk_qfnia_smt_solver(m, p), 2000),
mk_qfnia_nlsat_solver(m, p),
mk_qfnia_smt_solver(m, p)));
return and_then(
mk_report_verbose_tactic("(qfnia-tactic)", 10),
mk_qfnia_premable(m, p),
or_else(mk_qfnia_sat_solver(m, p),
try_for(mk_qfnia_smt_solver(m, p), 2000),
mk_qfnia_nlsat_solver(m, p),
mk_qfnia_smt_solver(m, p)));
}