mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 17:45:32 +00:00
enable cardinality constraints in nla2bv
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
509f80b1db
commit
caa15ea04d
4 changed files with 60 additions and 43 deletions
|
@ -21,6 +21,7 @@ Notes:
|
|||
#include "tactic/tactical.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/bv_decl_plugin.h"
|
||||
#include "ast/pb_decl_plugin.h"
|
||||
#include "ast/for_each_expr.h"
|
||||
#include "ast/rewriter/expr_replacer.h"
|
||||
#include "util/optional.h"
|
||||
|
@ -85,13 +86,18 @@ class nla2bv_tactic : public tactic {
|
|||
TRACE("nla2bv", g.display(tout);
|
||||
tout << "Muls: " << count_mul(g) << "\n";
|
||||
);
|
||||
tactic_report report("nla->bv", g);
|
||||
m_fmc = alloc(generic_model_converter, m_manager, "nla2bv");
|
||||
m_bounds(g);
|
||||
collect_power2(g);
|
||||
if(!collect_vars(g)) {
|
||||
switch (collect_vars(g)) {
|
||||
case has_num:
|
||||
break;
|
||||
case not_supported:
|
||||
throw tactic_exception("goal is not in the fragment supported by nla2bv");
|
||||
case is_bool:
|
||||
return;
|
||||
}
|
||||
tactic_report report("nla->bv", g);
|
||||
substitute_vars(g);
|
||||
TRACE("nla2bv", g.display(tout << "substitute vars\n"););
|
||||
reduce_bv2int(g);
|
||||
|
@ -308,27 +314,30 @@ class nla2bv_tactic : public tactic {
|
|||
|
||||
class get_uninterp_proc {
|
||||
imp& m_imp;
|
||||
arith_util& a;
|
||||
ast_manager& m;
|
||||
pb_util pb;
|
||||
ptr_vector<app> m_vars;
|
||||
bool m_in_supported_fragment;
|
||||
public:
|
||||
get_uninterp_proc(imp& s): m_imp(s), m_in_supported_fragment(true) {}
|
||||
get_uninterp_proc(imp& s): m_imp(s), a(s.m_arith), m(a.get_manager()), pb(m), m_in_supported_fragment(true) {}
|
||||
ptr_vector<app> const& vars() { return m_vars; }
|
||||
void operator()(var * n) {
|
||||
m_in_supported_fragment = false;
|
||||
}
|
||||
void operator()(app* n) {
|
||||
arith_util& a = m_imp.m_arith;
|
||||
ast_manager& m = a.get_manager();
|
||||
if (a.is_int(n) &&
|
||||
is_uninterp_const(n)) {
|
||||
if (a.is_int(n) && is_uninterp_const(n)) {
|
||||
TRACE("nla2bv", tout << "Not supported: " << mk_ismt2_pp(n, m) << "\n";);
|
||||
m_vars.push_back(n);
|
||||
}
|
||||
else if (a.is_real(n) &&
|
||||
is_uninterp_const(n)) {
|
||||
else if (a.is_real(n) && is_uninterp_const(n)) {
|
||||
m_vars.push_back(n);
|
||||
}
|
||||
else if (m.is_bool(n) && is_uninterp_const(n)) {
|
||||
|
||||
}
|
||||
else if (m.is_bool(n) && n->get_decl()->get_family_id() == pb.get_family_id()) {
|
||||
|
||||
}
|
||||
else if (!(a.is_mul(n) ||
|
||||
a.is_add(n) ||
|
||||
|
@ -342,7 +351,7 @@ class nla2bv_tactic : public tactic {
|
|||
m_imp.m_bv2real.is_pos_le(n) ||
|
||||
m_imp.m_bv2real.is_pos_lt(n) ||
|
||||
n->get_family_id() == a.get_manager().get_basic_family_id())) {
|
||||
TRACE("nla2bv", tout << "Not supported: " << mk_ismt2_pp(n, a.get_manager()) << "\n";);
|
||||
TRACE("nla2bv", tout << "Not supported: " << mk_ismt2_pp(n, m) << "\n";);
|
||||
m_in_supported_fragment = false;
|
||||
}
|
||||
m_imp.update_num_bits(n);
|
||||
|
@ -353,13 +362,17 @@ class nla2bv_tactic : public tactic {
|
|||
bool is_supported() const { return m_in_supported_fragment; }
|
||||
};
|
||||
|
||||
bool collect_vars(goal const & g) {
|
||||
enum collect_t { has_num, not_supported, is_bool };
|
||||
|
||||
collect_t collect_vars(goal const & g) {
|
||||
get_uninterp_proc fe_var(*this);
|
||||
for_each_expr_at(fe_var, g);
|
||||
for (unsigned i = 0; i < fe_var.vars().size(); ++i) {
|
||||
add_var(fe_var.vars()[i]);
|
||||
}
|
||||
return fe_var.is_supported() && !fe_var.vars().empty();
|
||||
if (!fe_var.is_supported()) return not_supported;
|
||||
if (!fe_var.vars().empty()) return is_bool;
|
||||
return has_num;
|
||||
}
|
||||
|
||||
class count_mul_proc {
|
||||
|
|
|
@ -27,6 +27,7 @@ Notes:
|
|||
#include "sat/tactic/sat_tactic.h"
|
||||
#include "tactic/arith/nla2bv_tactic.h"
|
||||
#include "tactic/arith/lia2card_tactic.h"
|
||||
#include "tactic/arith/card2bv_tactic.h"
|
||||
#include "tactic/core/ctx_simplify_tactic.h"
|
||||
#include "tactic/core/cofactor_term_ite_tactic.h"
|
||||
#include "nlsat/tactic/qfnra_nlsat_tactic.h"
|
||||
|
@ -73,7 +74,8 @@ static tactic * mk_qfnia_premable(ast_manager & m, params_ref const & p_ref) {
|
|||
using_params(mk_ctx_simplify_tactic(m), ctx_simp_p),
|
||||
using_params(mk_simplify_tactic(m), pull_ite_p),
|
||||
mk_elim_uncnstr_tactic(m),
|
||||
mk_lia2card_tactic(m),
|
||||
mk_lia2card_tactic(m),
|
||||
mk_card2bv_tactic(m, p_ref),
|
||||
skip_if_failed(using_params(mk_cofactor_term_ite_tactic(m), elim_p)));
|
||||
}
|
||||
|
||||
|
@ -105,7 +107,9 @@ static tactic * mk_qfnia_nlsat_solver(ast_manager & m, params_ref const & p) {
|
|||
static tactic * mk_qfnia_smt_solver(ast_manager& m, params_ref const& p) {
|
||||
params_ref simp_p = p;
|
||||
simp_p.set_bool("som", true); // expand into sums of monomials
|
||||
return and_then(using_params(mk_simplify_tactic(m), simp_p), mk_smt_tactic(m));
|
||||
return and_then(
|
||||
using_params(mk_simplify_tactic(m), simp_p),
|
||||
mk_smt_tactic(m));
|
||||
}
|
||||
|
||||
tactic * mk_qfnia_tactic(ast_manager & m, params_ref const & p) {
|
||||
|
@ -113,9 +117,11 @@ tactic * mk_qfnia_tactic(ast_manager & m, params_ref const & 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))
|
||||
mk_qfnia_sat_solver(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))
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue